Level 2 of Arc Ops decided how much an agent may spend. Nothing there decides what it may do. This is the one level where the guard is not a number but a person, and the first thing to measure is whether that person is in the loop or only in the prompt.
def fire(self, effect, approval=None, *, now=0, idempotency_key=""):
reason = self._check(effect, approval, now, idempotency_key)
if reason:
self.refusals.append((effect.id, reason)); raise Refused(reason)
self._world.commit(effect, now) # ONE call site, after the guard
The structural claim is checked, not asserted. one_door() parses gate.py with ast and reports exactly one World.commit call site, behind the guard; zero subclasses overriding fire; and zero _check methods permitted to read Approval.read, so no rung can grade its own attentiveness.
Then 34 agent programs - plan, ask, edit, fire, retry, stop - through four rungs of that rule, graded by a ledger the gate cannot reach. Ground truth is a property of the world, not your config: an effect needs a yes if its kind is irreversible, so narrowing the policy never narrows what counts as a failure.
| rung | what it binds | committed | UNAUTHORISED | refused |
|---|---|---|---|---|
| 0 | the rule, as a system prompt | 41 | 20 | 0 |
| 1 | if approval |
36 | 15 | 5 |
| 2 | signature, effect id, decision, scope | 30 | 9 | 11 |
| 3 | + bytes, target, amount, single-use, ttl | 16 | 0 | 25 |
That generalises Day 70's inbox-triage email result to any irreversible effect, independently. Rung 2 is the gate almost every framework ships, and it commits nine effects nobody read: edited, regenerated, truncated, target-changed, approved as a stub, fired after the kill switch. Rung 1 to 2 is about who approved, six programs. Rung 2 to 3 is about what they approved, nine.
Repo: https://github.com/dev48v/arc-ops - MIT, dependencies = [], 513 pytest with 144 new here, commit 30ef14d, 218 in-page assertions: https://dev48.infy.uk/arcops/level3-approval-gates.html
The inversion, and it is the sharpest in the series
Widen require_human_for past the irreversible kinds and harm moves 8 to 11, a factor of 1.38 - while coverage stays at 1.0000 and unapproved-irreversible stays at 0. Every number a gate can report about itself is flat while actual harm rises, and all 11 harmful effects arrive holding a correctly signed, in-date, in-scope, single-use approval.
The mechanism is the reviewer. At full scope 55.8% of approvals are rubber-stamped, and half of every yes is unread past 30 approvals an hour. The effect survives at zero interruption cost, and clears only at 2,400 seconds of review per hour - forty minutes of every hour, a full-time reviewer.
And the fix is not a narrower policy. It is a sorted(). Keep full scope and read the irreversible items first: harm 11 to 7, beating every narrower scope.
Two more that cost money. Single-use does not fix replay, because a retry and a replay are byte-identical on the wire, so strict spending refuses 25 attempts of which 4 were genuinely approved, and the 2x2 of {strict, declared-intent} x {L0 store, none} has exactly one clean cell. A digest ablation over 70 cells prices each field: the target is worth 20 misses, the amount 20, the verb 10 - so a payload-only digest, the one people write, misses 30.
Next is L4, determinism and replay. L3 can prove a person said yes to these exact bytes; it cannot tell you why the agent proposed them, or whether it would propose them again. Nine levels, four unlocked: https://dev48.infy.uk/arcops.php
Top comments (0)