Doctrine · Policy & rules
Rules you can predict
A rule is a conditional override of configuration, plus a proposal of actions. It is deliberately not an inference engine.

Five guarantees
A general rules engine buys inference and costs predictability: firing order is emergent, the fixpoint may not terminate, and why did this fire needs a debugger. For a system that commits effectors, that is disqualifying. So the authoring feel is kept and the engine is not.
- No chaining. A rule reads facts, never another rule's conclusion. One pass, no fixpoint, so termination is free.
- Total order. Rules evaluate in stored order. No salience arithmetic.
- Pure. No input except facts. Enforced by the grammar rather than by convention: there is no fact for the current time of day, so no rule can read a wall clock.
- Bounded. Every derived value is clamped by a doctrine bound, and a clamp is recorded.
- Total attribution. Every firing names its rule and its subject.
The cost is real and worth stating: a rule cannot react to another rule's conclusion. That is paid deliberately, because the conditions worth chaining are all expressible as facts.
Order does not decide everything
One resolution policy for all effects is unsafe, so there are four.
| Effect | Resolved by |
|---|---|
| Derive, Prioritise | Rule order. A tuning wants a visible precedence. |
| Designate | The lattice friend > unknown > suspect > hostile. Most careful wins, regardless of order. |
| Emit | No conflict. Both fire, deduplicated by verb and target. |
| Deny | Union. Narrowing composes; there is no "last denial wins". |
The designation row is the one that matters. Last-writer-wins on designation is a fratricide path: a later rule marking a friendly aircraft hostile would win purely by sitting lower in the list. The lattice removes that without an operator having to configure anything correctly.
Self-defence is locked
Exactly one shipped rule is locked. It is not editable, not reorderable and not deletable, because no rules of engagement remove the right of a unit under attack to defend itself.
It renders with a lock rather than being hidden, because a commander needs to see that it is there.
Authoring
Settings → Decision support → Add. The picker asks one question at a time, along the graduated-response ladder, which is the order an ROE card reads in.

Then the editor, which is three parts: the sentence with its numbers as inline inputs, the WHEN and THEN rows as typed fields, and what the rule would actually do.

Every rule is editable, template or not. The template decides which form you are offered, never whether the row can be changed.
Writing one with the Copilot
The case a template cannot cover is the one a commander actually hits. Describe it instead:
Designate any contact SUSPECT if it enters the outer keep-out zone below 120 m and its affiliation is not friend.
The Copilot drafts it into the editor. Three properties of that flow:
- The agent never saves. It produces a proposal; the page renders it; you decide.
- It is validated on screen first, before it can be saved at all.
- A rule cannot widen authority. Only a grant can, and never for self-defence.
What a rule can test
Facts are a closed set of typed predicates rather than arbitrary expressions. That is what keeps the purity guarantee enforceable.
A rule can read a track's affiliation, confidence, range, closure, time to impact, altitude, speed, spoof risk, cooperative ID, dwell, whether it is inside a kind of zone, and whether it is inside one named zone.
One fact deserves a note. Visual ID is true only when an imager has produced a picture of the contact and the fused class is in the UAS family. Either half alone is what the affiliation ceiling exists to refuse: a camera that saw a bird, or a radar that guessed a multirotor.
Where to go next
- Constants for the values rules read.
- Decision support for the gates that decide whether a proposal runs.