An agent chains five actions in a row without ever asking permission. Four of them are utterly routine. One of them, buried in the middle, refunds $10,000 to a customer's account. Where do you put the tripwire that catches the one and lets the other four run themselves?
Drag the threshold up from zero. At 0, every action — even listing files in /tmp — gets flagged for a
human, which defeats the point of having an autonomous agent at all. Somewhere in the middle, the flags
thin out to exactly the one action that actually deserves attention.
Each action in a trajectory carries a fixed risk score. A gate flags an action for approval exactly when its risk clears a chosen threshold — everything else runs on its own, no human involved.
- — one action in the agent's trajectory.
- risk() — a fixed 0–10 score for that action (here: 1, 2, 3, 9, 1 across the 5 steps).
- — the approval threshold: the one knob a human operator actually sets.
- needsApproval — 1 (flagged, wait for a human) or 0 (safe, runs immediately).
- τ too low floods every action to a human
At , risk holds for all five actions — even "list files in /tmp" waits on approval. Autonomy is gone.
- τ too high lets the dangerous action through unreviewed
At , nothing clears the bar — not even the risk-9 refund. The gate exists and catches nothing.
- The four safe actions top out at risk 3
Steps 1, 2, 3, 5 have risk 1, 2, 3, 1. The highest of those four is 3 — that's the ceiling any correct threshold has to clear.
- Any τ strictly above 3 and at most 9 isolates exactly step 4
flags risk only for the refund's risk of 9, and nothing with risk .
flagged steps = [4] — correctly isolates the risky step
Watch the flagged-steps readout as you drag up from 0. It starts at "[1, 2, 3, 4, 5]", thins through intermediate mixes, locks onto "[4]" alone for a wide band of thresholds, then finally empties out to "[]" once passes 9.
Walk five threshold choices against the fixed trajectory:
- τ = 0 flags everything
All five risks (1, 2, 3, 9, 1) are . Flagged = [1, 2, 3, 4, 5]. Not a clean split.
- τ = 3 still catches an innocent action
Risk 3 (step 3, "post a status update") is , so it gets flagged right alongside step 4. Flagged = [3, 4]. Still not clean — the threshold sits exactly on a safe action's own score, not above it.
- τ = 4 is the smallest threshold that isolates step 4
Now only risk qualifies, and only step 4's risk of 9 clears it. Flagged = [4]. Clean.
- τ = 9 is the largest threshold that still catches it
Risk still includes step 4, exactly at its own score. Flagged = [4]. Still clean.
- τ = 10 misses it entirely
No action has risk . Flagged = []. The refund now runs with no human in the loop at all.
Drag the threshold until it flags only step 4 for approval — every safe action (risk ≤ 3) should auto-run.
flagged steps = [1, 2, 3, 4, 5]
The usable range for here is — six integer thresholds that all thread the needle between the highest safe score and the one truly risky one. In a real system, assigning the risk scores themselves is the hard part; this chapter fixed them by hand to isolate just the threshold decision. Misjudge the refund's risk as a 2 instead of a 9, and no choice of saves you — the gate is only as good as the score it's gating on. The next chapter puts the pieces from this part together into one working tool-using agent, sandboxed and gated exactly the way these last few chapters described.