The gate is a policy, not an if
There are two obvious ways to decide when a human is required, and both are traps: hard-code it and it rots; let the agent decide and it won't. The floor is the third way.
Somewhere in your codebase is the line that decides whether a human gets involved. Find it. It probably reads if (amount > 5000) await requireApproval(). That line is the most consequential one in your approval system, and it is in the worst possible place.
There are two obvious ways to write it. Both are traps.
Trap one: the hard-coded if#
A threshold in the middle of a function is invisible to everyone who is not reading that function. It drifts — one service gates at $5,000, another at $5,000 in cents, a third forgot. It needs a deploy to change, so the number that governs your financial risk moves on the same release train as a button color. And the person who most needs to read it — whoever actually owns the risk — cannot, because it is not written anywhere they look.
Worst of all, it cannot be audited. "Show me every rule that requires a human" has no answer when the rules are scattered across four repos as literals.
Trap two: let the agent decide#
This is the tempting, modern version. Give the model a requestApproval() tool and let it call it when it judges the action risky. It feels principled — the system that best understands the action decides whether the action needs oversight.
The problem is the incentive. An agent is optimized to complete its task, and stopping to ask a human is friction it is rewarded for avoiding. A capable model will reliably produce a reasonable-sounding account of why this particular case is fine to skip. It is not lying; it is doing exactly what you built it to do.
The model that decides whether it needs supervision is precisely the model you cannot trust to decide it. Oversight the supervised party can waive is not oversight.
The third way: a floor#
Separate the decision to require a human from both the code and the model, and make it a named, declarative rule the platform evaluates against the actual payload:
policy: payouts-over-5k
floor:
- field: amount
op: gte
value: 5000
- field: destination.country
op: not_in
value: [US, CA, GB]
Any condition that matches means a human decides. The floor is a set of tripwires, not a checklist — OR, not AND — because each condition is an independent reason the organization has already decided it wants a person in the room.
The property that makes this work is directional. AI proposes, policy bounds. The call site and the model can raise the bar — ask for a human even when the floor is silent, because the model is unsure or the customer is sensitive. Neither can lower it. The floor is the one thing in the system the model does not get a vote on, and it is evaluated by the platform against the real arguments, never by asking the model whether it thinks the rule applies.
Why a policy beats a check#
- One place. The rule that governs a $12,400 refund and the rule a regulator asks to see are the same object, not a screenshot of a code review.
- Changeable without a deploy. Risk tolerance moves on a different clock than your release pipeline. It should not need one.
- Testable. You can ask "what would this policy have done to last quarter's transactions?" You cannot ask that of an
ifyou would first have to find. - Legible. The person who owns the risk can read it, and disagree with it, without reading TypeScript.
The failure nobody expects: a floor that can't be satisfied#
There is a subtle way to make things worse. Write a floor that mandates a human on a surface where no one can actually act — a quorum of two when only one approver is verified, a channel nobody is reachable on — and the decision does not get safer. It parks. Forever.
A policy that can never reach a verdict is not strict. It is an outage with good intentions. So the floor needs a pre-flight the moment you save it: given the approvers and surfaces that actually exist, can this ever resolve? A strict rule and an unreachable rule look identical in the config and behave nothing alike in production.
When the hard if is fine#
Prototypes. Internal tools. One gate, one team, an audit trail that is a Slack thread. If there is exactly one place a human is required and exactly one person who cares about the threshold, a literal is honest and a policy engine is overhead.
It stops being fine the moment there is a second gate, a second person who cares about the rule, or a regulator who will one day ask to see it written down.
The dividing line#
A hard-coded check answers "should this pause?" at the site of the action. A policy answers "when does anything like this require a human?" at the level of the organization. The first is an implementation detail. The second is a control. They look similar in the diff and they are not the same thing.
Ratifia's approval policies are the second one: a named floor of conditions, evaluated server-side against the decision context, mandatory and un-waivable by the call site or the model, with a satisfiability check so a policy can't quietly park every decision it touches. The AI proposes. The policy bounds.