Software is very good at making a calculation look authoritative. Give a rule engine enough inputs and it can return a crisp result in milliseconds. In a consequential workflow, that neatness is dangerous: a computed recommendation can quietly become a decision without anyone deliberately granting it that authority.
A better design treats computation and authority as different responsibilities. The software may evaluate evidence, explain what it found, and suggest an outcome. A person still records the actual decision. The data model preserves both.
That separation is more than a user-interface disclaimer. It has to reach the evaluator, persistence model, activation workflow, and tests.
Keep the evaluator pure
Start with an evaluator that has no write path. It accepts a versioned rule and a set of observations, then returns an explanation:
- which inputs contributed;
- which requirements passed or failed;
- what evidence was missing;
- which rule version was used; and
- what outcome, if any, is suggested.
The return value should say “suggested,” not “decided.” Naming is not sufficient, but it makes accidental authority harder to hide.
Purity matters here. A preview operation should be safe to run repeatedly without creating decisions, sending notifications, or mutating state. That keeps calculation testable and prevents a read-like action from acquiring an unexpected side effect.
When essential evidence is missing, the evaluator should return an advisory state with no suggestion. A nullable recommendation can be a feature: it says the software cannot justify a conclusion. Returning the most likely answer would make uncertainty easy to rubber-stamp.
Make rules prove their intended behaviour
Syntactically valid configuration is not the same as reviewed policy. A collection of thresholds can pass field validation and still express something the author did not mean.
Before a configurable rule becomes active, require named worked examples. Each example contains representative inputs and the outcome the author expects. Activation replays every example through the same evaluator used by real records. If one disagrees, activation stops.
Using the same evaluator is important. A second “fixture evaluator” would only prove that two implementations can disagree in production.
Malformed examples should fail before replay. If a parser silently misreads an input and the example happens to reach the expected result, the gate gives false confidence. An explicit failure is safer than a coincidental pass.
These examples act as executable policy conversations. They let reviewers ask, “What should happen in this borderline case?” before the rule affects a real decision.
Persist recommendation and decision separately
The final record should not overwrite the computed recommendation. Store both:
- the recommendation available at decision time;
- the outcome the person recorded;
- the exact rule version that informed it;
- the actor and timestamp; and
- a reason when the decision departs from the recommendation.
This turns disagreement into useful data instead of treating it as an error to conceal. A departure may reveal legitimate context that the model deliberately does not represent. It may also reveal a weak rule. Either way, preserving both facts makes later review possible.
The same principle applies to overrides. Do not edit the old outcome in place. Append a new version, mark it as current, retain the previous value, and require a reason. Historical records should describe what was known and decided then—not what today’s configuration would calculate now.
Pinning the rule version is crucial. If a rule changes next month, an old decision must still point to the version that produced its original recommendation. Otherwise, history becomes a moving target.
Formula tests are necessary, but the more revealing tests are often about authority and time.
Useful cases include:
- previewing produces an explanation and writes nothing;
- missing essential evidence produces no recommendation;
- a rule without worked examples cannot be activated;
- an example that disagrees with the rule blocks activation;
- departing from a recommendation without a reason is refused;
- an override appends a version instead of editing history; and
- changing a rule later does not alter an already recorded decision.
These tests express the operating model. They protect not only mathematical correctness, but also who is allowed to decide and whether past context remains trustworthy.
Accept the deliberate friction
This approach costs more than returning an enum and saving it. It introduces draft and active rule states, advisory outcomes, versioned decisions, reasons, worked examples, and review steps. Operators need to understand the distinction. Developers have more invariants to maintain.
That friction should be proportional to consequence. A low-stakes recommendation may not need an append-only ledger. A decision affecting access, eligibility, money, safety, or a person’s future probably deserves more than an opaque calculation.
Worked examples also have limits. They prove that the authored rule behaves as expected on selected cases. They do not prove that the policy is fair, lawful, complete, or statistically sound. Human approval can still be mistaken. Permissions, peer review, monitoring, and periodic policy review remain necessary.
A practical design question
When reviewing a rule-driven workflow, ask one question first: is this output evidence for a decision, or is the system silently making the decision itself?
If the answer matters, create a visible boundary. Keep evaluation pure. Refuse to guess when evidence is insufficient. Gate activation with executable examples. Record human choices separately. Preserve departures and history.
The goal is not to weaken automation. It is to make its authority honest.