What agent governance is, and why an LLM can't do it by reading code
A deterministic audit reads a named file and a line number. A language model reading the same code returns a probability. Two adversarial fixtures below show exactly where that difference lands.
Published · updated · by Julian Joseph, founder
Get an Agent Trust Gap BriefWhat is agent governance?
Agent governance is a deterministic audit of an autonomous system's source, config and deployment — identity, authority, isolation, evidence, supply chain, oversight and documentation — verified by reading named files, not by asking a model whether the code looks safe.
Why can't a language model judging code replace this?
Because a model's verdict is a probability, not a rule: it can flag a documented example key as leaked or miss a real one, and it gives no fixed file-and-line reason a regulator can re-check.
What proves the difference, rather than just asserting it?
Two adversarial fixture trees, tricky_clean and tricky_dirty, look alike to a keyword scan; run through aga.py today, tricky_clean scores 3 controls PASS, tricky_dirty scores 0 — decided by file location and quoting, not wording.
What exactly told the two fixtures apart?
Three checks: id.no_secrets read a .gitignore before calling a credential a leak, sc.safe_deploy required that a destructive command sit outside quotes, and ev.refusals_logged looked for an actual refusal path — distinctions a keyword match alone cannot make.
Does this mean an LLM has no role in agent governance?
It has one: reading this evidence and explaining it in plain language. What it cannot do is stand in for the file-and-line check itself, because its judgment is not reproducible the way a fixed rule reading a fixed file is.
The worked proof: one keyword pattern, opposite verdicts
Three of the 27 controls, run against both fixture trees today, show the mechanism directly: the
same class of keyword (a credential-shaped string, the phrase "DROP TABLE", the phrase "refuse")
appears in both trees, and the verdict still comes out opposite — because the rule reads file location,
quoting and .gitignore coverage, not word resemblance.
| Control | tricky_clean evidence | tricky_clean verdict | tricky_dirty evidence | tricky_dirty verdict |
|---|---|---|---|---|
id.no_secrets | tricky_clean/sigv4_test.rs: AKIAIOSFODNN7EXAMPLE, AWS's own published SigV4 test key. tricky_clean/.env holds a credential-shaped string, but the directory's own .gitignore lists .env and .env.*. | PASS 1 secret(s) held in a git-ignored .env, which is the intended store | tricky_dirty/config.py:1 hardcodes a live-shaped AWS access key id; the directory has no .gitignore at all. | FAIL AWS access key id at config.py:1; JWT at .env:1 |
sc.safe_deploy | tricky_clean/Dockerfile:1 runs rm -rf /var/lib/apt/lists/* (routine apt cache cleanup); tricky_clean/guard.sh quotes rm -rf /, DROP TABLE and rsync --delete inside its own blocklist string. | PASS no destructive deploy command found | tricky_dirty/release.sh runs rm -rf /, rsync -a --delete ./out/ /var/www/prod/ and git push --force origin main as literal, unquoted commands. | FAIL release.sh:1; release.sh:2; release.sh:3 |
ev.refusals_logged | tricky_clean/guard.sh contains the word "refuse" in its own comment ("refuse any of these if an agent proposes them"). | PASS guard.sh:1; guard.sh:2; guard.sh:3 | None of tricky_dirty's 3 files contain any refusal-shaped language. | FAIL no refusal path recorded |
Source: /root/apexclaw-audit/aga_fixtures/tricky_clean and
/root/apexclaw-audit/aga_fixtures/tricky_dirty, re-scored today with
aga_cli.py against aga.py (AGA/1.0). Full run: tricky_clean scores 12.0/100
(3 PASS, 0 PARTIAL, 22 FAIL, 2 UNKNOWN), with its Identity family at 42.9%, Supply Chain at 21.4% and
Evidence at 18.8%; tricky_dirty scores 0.0/100 (0 PASS, 0 PARTIAL, 25 FAIL, 2 UNKNOWN), 0% in all 7 families.
Why a keyword or resemblance judgment fails here specifically
A model asked "does this file contain a leaked secret" is being asked to judge shape:
does this string look like a key. AKIAIOSFODNN7EXAMPLE has the exact shape of a real AWS access key
id — that is the point of AWS publishing it as a test vector. rm -rf /var/lib/apt/lists/* has
the same first four characters as the single most destructive shell command that exists. A rule that reads shape
alone cannot separate these without also reading context a keyword match doesn't carry: is this string inside
a quoted blocklist, is this path covered by a .gitignore, does the path end in a real directory or a
bare root. aga.py encodes exactly those three pieces of context as code, not as a prompt, so the same
input produces the same output every time it is run — which is what a durable record under EU AI Act Art.12
requires, and what a probability distribution over tokens does not guarantee.
Primary standards cited on this page: OWASP Agentic Top 10, NIST AI RMF, ISO/IEC 42001, EU AI Act.
By Julian Joseph, Founder, ApexClaw. Every figure on this page is recomputed at build time from a named source file and date — see the method notes above. Reviewed against the claims policy: sourced, first-party, or labelled.