All lessons › Function F — AI Governance for Agentic Systems › Running the Programme — the CISO Office
F3.2

Governing autonomy rather than approving tools

F3
▶
Lightboard recording

Not recorded yet. The lesson below is complete and runnable today — the video is added later without touching this page.

Video placeholderpublishes automatically from recordings/F3.2.mp4
Risk

A per-tool review queue becomes a bottleneck and then a bypass.

Control

A policy on delegated authority instead of tool-by-tool approval.

The lab

Write the delegated-authority policy.

◉Use case relevance

An approved-tools list grows until it is a list of everything, at which point it governs nothing. Autonomy levels and conditions still work at a thousand agents, because they attach to behaviour rather than to product names.

At CyberTravels. Five rungs, and the decision is about the rung rather than the tool — which is what lets the next tool ship without a review queue that becomes a bottleneck and then a bypass. Rung 4 is not granted in this system, and the reason is B3.6: the gate stops working before you get there.

◴What this lesson is — Day 0, Day 1, Day 2

Approving a rung of autonomy rather than a tool, because a per-tool review queue becomes a bottleneck and then a bypass — with the top rung left ungranted and the reason stated.

Day 0 — why

A per-tool review queue becomes a bottleneck and then a bypass, within about a quarter.

Day 1 — how

Govern the autonomy level instead: four rungs, each with its own conditions.

Day 2 — measure

What an agent may do without asking, as a function of measured containment rather than of which vendor supplied the tool.

Measure this

what to measuredenominator or target
what an agent may do without askingthe autonomy rung, as a function of measured containment rather than of vendor

▦The framework, and how it works

   autonomy levels, with conditions attached

   L0 proposes only            no conditions
   L1 acts, reversible         logged, sampled
   L2 acts, irreversible       approval + budget + egress control
   L3 acts, no human in loop   L2 + continuous verification + stop authority

   attaches to behaviour, so it still works at a thousand agents

Tool-approval processes do not scale for agents. The list of tools grows weekly, each request needs context the approver does not have, and the queue becomes a rubber stamp within a quarter.

Govern autonomy instead. The autonomy ladder from B1.1 is the right unit because it is stable — there will always be four rungs — and because it maps directly onto what can go wrong:

RungGovernance
L1Self-service. Register it. No further review.
L2Register + named owner. Approval gate on every writer, enforced by policy.
L2.5Risk tier + blast-radius budget + drift monitoring + tested stop.
L3All of L2.5, plus held-out evaluation per release and board sign-off.

Two properties make this work: a request can be evaluated in minutes by checking the manifest against the rung, and the policy does not need rewriting when a new tool appears.

The rung that decides your programme's fate is L1. If L1 requires approval, nobody registers anything and your inventory dies.

Anchor → F1.1. Governing autonomy rather than tools means the policy attaches to indicator thresholds — what an agent may do without asking is a function of measured containment, not of which vendor supplied it.

2 · Demo — the per-rung policy, and a request evaluated against it

3 · Where it breaks — govern tools instead, and watch it collapse

4 · The control — L1 must be free, or the inventory dies

5 · The procedure, as a skill

The idea here is to govern the rung, not the tool.

The skill computes the blast radius of each request, works out which rung of the autonomy ladder that radius can support, and then refuses with a condition attached.

Why a condition and not just a no. A bare refusal produces an appeal. A conditional one produces a fix.

▶Real time execution as skill

The skill — skills/programme/autonomy-ladder-decisions/SKILL.md

name: autonomy-ladder-decisions
description: >-
  Approve or refuse an autonomy request against the rung its blast radius and
  gating actually support, rather than approving the tool it wants. Use when
  agents are being promoted to act unattended.
allowed-tools: Read, Grep, Glob

Govern the rung, not the tool

Approving tools one at a time produces an agent nobody approved: each tool was reasonable, and the combination acts unattended on production. Governing the rung asks a different question — what does this agent's blast radius and gating support — and the answer is computed rather than negotiated.

When to use this

Every request to raise an agent's autonomy, and as a periodic re-check, because tools accumulate.

Procedure

1 — Publish the ladder. L1 suggests, L2 acts in a sandbox, L2.5 acts with approval on irreversible actions, L3 acts unattended. With, for each rung, the governance and the budget it requires.

2 — Compute the request's blast radius. Reachable resources weighted by scope, with gated actions discounted. Ungated writers are what usually decide the outcome.

3 — Derive the supported rung from the radius and the gating, not from the requester's ask. Then compare. The gap is the conversation.

4 — Refuse with the condition attached. "Refused at L2 for ungated writers" tells the requester what to change. A bare refusal produces an appeal; a conditional one produces a pull request.

5 — Re-evaluate on tool change. A rung approved with three tools does not carry over to five. Make the tool manifest the trigger for re-evaluation.

Example

Input — the fixture committed at the top of scripts/autonomy_ladder_decisions.py. Edit it and re-run: the buckets, counts and verdicts below are derived from it, not hard-coded.

Output — the opening lines of a real run:

L1   self-service  budget   0  register it; no further review
                   Assist — model proposes, a human performs every action.
L2   lightweight   budget   0  named owner + approval gate on every writer
                   Act with approval — model calls tools, a human approves each call.
L2.5 governed      budget  20  risk tier + blast budget + drift monitoring + tested stop
                   Act within a blast radius — pre-approved tools, bounded scope, review after.
L3   board         budget  60  all of L2.5 + held-out eval per release + board sign-off
                   Autonomous — model acts and self-verifies; humans see aggregates.

The run continues past this. test_skills.py executes the script on every build, with no model configured — so what CI proves is that it runs and refuses legibly, not that it prints these lines. The output above is a recorded run against a real model, and nothing re-diffs it: a model's answer is not reproducible, and this repository does not claim otherwise anywhere it can be checked.

Output contract

{
  "ladder": [{"rung": "str", "governance": "str", "budget": "str"}],
  "requests": [{"name": "str", "asked": "str", "tools": ["str"], "gated": ["str"],
                "blast": 0, "supported": "str", "verdict": "approved|refused", "condition": "str|null"}],
  "reevaluate_on": ["tool added", "scope widened", "model changed"]
}

Failure modes

  • Approving tools. The combination is what acts.
  • A bare refusal. Nobody knows what to fix.
  • No re-evaluation trigger. The manifest grows and the rung does not move.

Three ways to do this lesson. Pick one. They run the same procedure against the same code — what changes is who drives it, and how much you see.

1In your AI agent — you are taught

The agent reads the lesson, explains the idea, fetches the code, runs the check and answers your questions as you go. This is the one to take if you are here to learn.

Install it, once. From the folder you cloned. --all does every agent it finds on your machine:

python3 scripts/install_skills.py --all --lessons F3.2

Then restart your agent and open it in that folder. On Windows, if python3 says Python was not found, use python instead.

Then pick f3-2-governing-autonomy-rather-than-approving:

agentinstall just for this agentstart it
Claude Codepython3 scripts/install_skills.py --tool claude --lessons F3.2type /f3-2-governing-autonomy-rather-than-approving
GitHub Copilot (VS Code)python3 scripts/install_skills.py --tool copilot --lessons F3.2type /f3-2-governing-autonomy-rather-than-approving in Chat
Cursorpython3 scripts/install_skills.py --tool cursor --lessons F3.2type / in Agent chat and search for it
Codexpython3 scripts/install_skills.py --tool agents --lessons F3.2type $f3-2-governing-autonomy-rather-than-approving, or run /skills

2As one Python command — you just run it

No agent, no conversation. The same lesson executes and prints the same readback. Take this one if you have no assistant, if you are reviewing rather than learning, or if you want the result without the teaching around it.

python3 scripts/lesson.py F3.2

3Read the code, and the difference — nothing runs

Neither of the above, and no model needed. The first command writes CyberTravels exactly as it stood at the end of this lesson; the second prints the diff — the lines this lesson added or changed, and nothing from any later one.

python3 scripts/checkpoint.py --at F3.2 --out work/cybertravels
python3 scripts/checkpoint.py --at F3.2 --diff

On Windows, type python wherever these say python3 — and use \ instead of / in the paths. Everything else is identical. A0.0 step 2 explains why.

Ways 1 and 2 need a model; way 3 does not. A signed-in Claude Code CLI needs no API key, and any OpenAI-compatible endpoint works too. With neither, the audit exits 2 and says so rather than inventing an answer. A0.0 sets this up.

Ways 1 and 2 both end with the same readback: What I did, What changed, The number and Read this next. A step that was skipped or refused is reported as exactly that, never as a pass.

If you did the last lesson’s challenge, expect this to stop. Most challenges ask you to edit the code, and ways 1 and 2 will not overwrite your edits: you get stopped, not a failure, with two options — --out for a fresh folder that keeps your work, or --force to discard it and start this lesson clean.

✓What you just proved

The four rungs print with their governance and budgets. The doc-summariser is approved at L1; triage-bot is refused at L2 for ungated writers; the refund agent is refused at L2.5 for exceeding the budget and approved once gated. Tool approval scales to 240 reviews a month at 120 agents against 5 hours for rung governance, and a committee-gated L1 leaves roughly 108 shadow assets.

✎Your turn

Write your own per-rung policy in four lines and check what L1 costs a team today. If registering a read-only copilot needs an approval, your inventory is already incomplete and you cannot see by how much.

Skill source: skills/programme/autonomy-ladder-decisions

← PreviousF3.1 · Translating agentic risk upward