Threads · 01 / 18 · Sep 7, 2026 · Apache-2.0
A cap in the wrong unit is not a cap you forgot to check
It is one you cannot compare. The action degrades to "ask a human" every single time, nothing errors, and nobody reports it — because asking a human is exactly what a careful system is supposed to do.
The test is a counter that stays at zero
A retention offer is measured in percent and in days at the same time. Somebody configures it the only way the system allowed — a ceiling in dollars — and the naive check is happy:
expect(boundedNaive(retentionOffer, { cap: "500.00" })).toBe(true); // "it has a ceiling"
Now count how many times that ceiling is ever compared against a value:
const r = runWithCounter(retentionOffer, enDolares, bounded);
expect(r.ran).toBe(false);
expect(r.comparisons).toBe(0); // ← the demonstration
Zero. A real number, configured with real intent, that was never once looked at. The action asks for permission forever, and nothing errors — no throw, no log, no red anything. That is the entire failure, and it is why it survives for months.
Why this is not "a cap you forgot to check"
A weak cap is one you can compare and set too high. This is different in kind: 500.00 and 20% for 30 days
do not live on the same axis. There is no comparison to run, so no amount of code fixes it — you have to
change the unit.
The tell is the direction of the failure. A weak cap fails open: things run that should not. This fails closed: nothing runs, which looks like caution right up until someone works out why the feature was never used and turns the guard off entirely.
Two rules that fall out of it
A half-set cap is not a cap.
bounded(retentionOffer, { named: { max_discount_pct: { enabled: true, value: 20 } } }) // → false
Bounding the discount and leaving the extension open would let an unbounded extension through because the other half happened to be bounded. All of the keys, or none.
A switch that is off bounds nothing, and a value with no switch is not a decision anyone made.
declared({ enabled: false, value: 20 }) // → false
declared({ enabled: true }) // → false
declared({ enabled: true, value: 0 }) // → true — zero IS a decision: bound it to nothing
Fail closed: what is not understood does not cap. And note the last line — zero has to count, or "bound
this to nothing" becomes unexpressible and someone works around it with a -1.
And it does not cost the ordinary case
bounded(refund, { cap: "500.00" }) // → true
An action with one unit — money, the case every ceiling was designed around — behaves exactly as before. The fix adds a path, it does not replace one, which is what makes it safe to adopt in a system that already has ceilings configured.
Where this comes from
Found in niiko, on a retention offer, and it had been silently unreachable for as long as
the feature existed. The engine that came out of it is published as
@vorluno/ratchet.
The prior question — why does autonomy attach to the capability and not to the agent? — is per-capability-autonomy.
License
Apache-2.0 — see LICENSE. This is a demonstration, not a package. Copy what you need.
Built by Vorluno — a software studio from Panamá.
// next threadA gate that answers two questions lies about both