What kind of engine this is
The engine works with facts, goals and rules. It runs on an ordinary processor, uses no neural networks or language models, and computes in exact arithmetic — there is no floating point anywhere in it.
That design choice gives three properties a business can rely on: the answer is the same every time, it can be explained step by step, and your data never has to leave your servers.
What it does
Plans towards a goal
Given a goal, the engine builds a multi-step path to it and keeps a journal of every action it takes.
Explains — including «why not»
Each decision is explained by the goal it served and the facts it rested on. Ask why another option was not chosen and you get an answer; ask where a number came from and you see the steps that produced it.
Behaves the same every time
Two identical setups think and act identically, and any run can be replayed to check what happened.
Notices surprises and learns the real law
When an expectation breaks, the engine flags it and derives the true relationship exactly, in rational numbers. A wrong rule that someone told it loses its weight once the data contradicts it.
Rehearses before acting
A rule change can be replayed over the historical log first. The engine shows which decisions would change and why.
Takes new rules and goals while running
Rules and goals can be changed on a running instance. Changes of any other kind are refused rather than applied half-way.
Asking it a question
Take a small shop: coffee, pastry and gift cards, with a loyalty plan. Its package already says how a day goes — demand by weekday, what a promotion adds, and that gift cards are never promoted:
/// Demand of the day by kind: weekdays and weekends.
/// example: base(Kind.Coffee, 0) == 30
/// example: base(Kind.Pastry, 6) == 20
pub fn base(k: Kind, week_day: u32) -> ratio = match k {
Coffee => if week_day >= 5 { 40 } else { 30 },
Pastry => if week_day >= 5 { 20 } else { 10 },
GiftCard => 5,
};
/// Extra sales from a running promotion and from the loyalty plan.
config {
promo_lift: ratio { default: 4 },
plan_reach: ratio { default: 40 },
}
/// No promotions for gift cards.
policy item.promote(i: Item, actor: Actor) {
i.kind is not GiftCard
}
/// The law of the day: every item sells its demand, then the day turns.
rule sales every day for i in Item {
when true => sell(i.id, Shop(1).day);
}
rule day every day {
when true => next_day(Shop(1).day);
}The manager has one question: should pastry go on promotion this week? To make it a question the engine can take, the package adds a few lines — what goes in, what comes back, and which actions the engine may use to get there:
struct PromoAsk { item: Id<Item> }
struct RateAsk { rate: ratio }
struct Done { ok: bool }
/// "Put this item on promotion": the engine may act only through `promote`.
extend mind::GoalKind promote_item {
inputs: PromoAsk,
output: Done,
bounds: { organs: [shop::promote] },
}
/// "Change the loyalty rate": a heavy action, it waits for the owner's word.
extend mind::GoalKind change_rate {
inputs: RateAsk,
output: Done,
bounds: { organs: [shop::set_bonus_rate], heavy: [shop::set_bonus_rate] },
}The bounds are the safety catch. For a promotion the engine may act only through the promote action. The loyalty rate is marked heavy: the engine may propose a new rate, but nothing changes until the owner approves it.
Asking takes one line, and the answer comes back with its reasons:
/// The manager's button: ask, and keep the reasons next to the answer.
pub cmd ask_promote(i: Id<Item>) -> Result<bool,
mind::err.unavailable | mind::err.goal_unknown | mind::err.inputs_incomplete
| mind::err.out_of_limits | mind::err.timeout
> permission see idempotent by i {
let v = mind::ask::<promote_item, Done>(PromoAsk { item: i })?;
emit advice.given { item: i, trace: v.why.trace };
Ok(v.answer.ok)
}What comes back
- The answer itself, in the type the package asked for: here, whether the promotion is on
- The reasons: the rules and settings the answer rests on — for pastry, the day's rules sales and day and the settings promo_lift and plan_reach
- A trace of every step: replayed on the same facts it gives the same answer, and it reads out in plain words in the reader's language
- A refusal that names its cause: ask to promote gift cards and the answer is no, with the policy that forbids it
- A held proposal for heavy actions: a new loyalty rate waits for the owner's approval
Why this beats asking a chatbot
The engine is not a language model: it does not guess. It reasons over the shop's own records and the rules the business wrote, so the same question gives the same answer every time, every answer points at the lines behind it, and the engine can do only what its bounds allow. When an input is missing, it says which one instead of making an answer up.
The engine reasons over the same exact data as the rest of the platform, so its explanations point at real records, not at a summary of them.