The design that failed
Our first approval gate guarded an entire workflow: if a workflow was marked as requiring approval, every run stopped and waited. It was simple to explain and simple to implement, and within a month of watching real usage it was clearly wrong.
Teams put approval on the workflows that mattered, which meant the ones that ran most often. Reviewers faced hundreds of near-identical items a day, nearly all of which were routine. They did what anyone would do: approved in bulk, glancing at the count rather than the contents. We had built a control that produced a signature without producing a decision.
The volume was the bug
The tempting fix is better tooling for bulk review — sorting, filtering, keyboard shortcuts. We tried some of that and it made the throughput worse in a specific way: faster approval of things still not being read.
The actual problem was that we were asking for judgement on items where no judgement was required. A ₹300 refund on a delivered order with a first-time customer does not need a human; it needs a rule. Sending it to a person is not caution, it is noise, and the noise is what destroys attention for the ₹40,000 case three rows down.
Bands, not gates
Approval moved from the workflow to the step, with an explicit band. Inside the band, the run proceeds and is logged. Outside it — higher value, an unusual pattern, a missing verification, a mismatch between what was claimed and what was detected — it stops and waits for a named person.
The reviewer's queue shrank by roughly the amount you would expect, and the items in it became genuinely different from one another. That is the signal we now watch: if every item in an approval queue looks the same, the band is set wrong, not the reviewer.
The corollary is that defining the band is real work and cannot be defaulted. We ship no default thresholds for money movement, and we are frequently asked to. Declining that request is deliberate: a threshold we picked would be adopted unread, and it would be wrong for almost everyone.
More from the blog
- Engineering
Idempotency is a security control, not a reliability nicety
We shipped a retry that could refund the same order twice. The fix was one line; understanding why it was a security bug rather than a reliability bug changed how we review every payout path.
Read - AI safety
Redact before the model call, not after
Filtering a model's response is not privacy engineering. If the prompt contained a customer's access token, the token has already left your tenancy.
Read - Compliance
What an auditor actually asks for
Not a dashboard. A specific record, for a specific action, on a specific date, with the person who authorised it — and a reason to believe the record was not written afterwards.
Read