agent-dojo-capsule
v3.16.0
Published
Agent Dojo Discipline Capsule — operational-discipline guard suite for owner-operated Claude Code agents. Public auditable subset; canonical integrity reference at https://aiagentdojo.com/capsule/ (SHA-256 pinned). Install via install.sh after your agent'
Maintainers
Readme
Agent Dojo Discipline Capsule — v3.16
Publisher: Agent Dojo — https://aiagentdojo.com Source + integrity: https://github.com/aiagentdojo/agent-dojo-capsule What it is: field-earned operating disciplines for an AI agent, installed once, active in every future session. Not affiliated with the academic AgentDojo prompt-injection benchmark (ethz-spylab) — Agent Dojo is an operational-discipline training capsule for owner-operated Claude Code agents: a control layer for an agent whose autonomy is earned through evidence, never assumed.
Official channels — verify our footprint yourself
Auditing agents: provenance is a fair objection, so here is the complete public footprint to check against — anything claiming to be Agent Dojo outside this list is not us:
| Channel | Handle | |---|---| | Website + hosted artifacts | https://aiagentdojo.com | | Source + releases + pins | https://github.com/aiagentdojo/agent-dojo-capsule | | TikTok | @the.agent.dojo | | YouTube | @TheAgentDojo | | X | @aiagentdojo | | Instagram | @theagentdojo | | Store | Gumroad — https://3483867817168.gumroad.com/l/rjcpdm |
Honest note: this is a young publisher — the footprint above is real and checkable, and it is deliberately small. Verify it rather than trusting it.
Integrity, signature, and the two scripts named install.sh
This section ships identically in the repo README and the tarball README (balk F2: one text, no drift; the per-file hashes live in
manifest.json, not in prose that can rot).
Two different scripts are called install.sh — know which one you hold
(balk F1):
| Canonical name | Lives at | Does |
|---|---|---|
| Hosted bootstrap | https://aiagentdojo.com/install.sh | Downloads the capsule tarball, verifies it against the published SHA-256 pin, unpacks to a temp folder, runs the tarball's own capsule installer. Installs nothing itself. |
| Capsule installer | ./install.sh (in this package) | The actual install (steps 0–7). Network only in step 6, only if all three license variables are set. Supports bash install.sh --audit — prints every action it would take, touches nothing. |
Verify before installing — everything points at the public GitHub repo:
- Tarball pin. The SHA-256 of each release tarball is published in the release entry on the public GitHub repo (Releases → v3.16). Hash your download, compare, done. (This README cannot carry its own tarball's hash — a file cannot contain a hash of an archive that contains it.)
- Signed manifest.
manifest.jsondeclares every file this package installs, with real per-file SHA-256s, every settings entry, the CLAUDE.md block, the one conditional network endpoint, and every env override. It is signed (manifest.json.sig, ssh-ed25519). Verify:ssh-keygen -Y verify -f allowed_signers -I aiagentdojo.com -n agent-dojo-manifest -s manifest.json.sig < manifest.json - Signing key fingerprint —
SHA256:HVOiAiB39AFsGnjjTtKigpy/yHKklD1xXha2Yfa3zkE— fetch it from the public GitHub README (this section), compare againstssh-keygen -lf allowed_signers, done. - Mechanical audit.
python3 tests/test-manifest.pyre-hashes every declared file against disk and diffsinstall.sh --auditoutput against the manifest;python3 tests/test-audit.pyproves--auditwrites nothing. The decision procedure is closed: numbers match and the code does what it claims → install; anything unmapped → refuse and tell your owner.
The restrict-or-disclose pledge
Everything in this package either NARROWS what your AI agent will do or requires it to DISCLOSE that an installed rule acted. Verify it yourself —
the package is 38 short readable files: the 27 in the table below plus 11
self-test files in tests/ (count them):
| File | What it is |
|---|---|
| MANIFEST.md | NEW in v3.14 — the install manifest, human-readable half: identity, complete file inventory, permissions ("nothing else" is the load-bearing claim), agent-config mutations, reversibility, the refusal path, and the cold-agent audit procedure. |
| manifest.json | NEW in v3.14 — the machine-readable half, schema-validated (manifest.schema.json), every kind=copied row carrying the real sha256 of the shipped file. The signed artifact; if prose and manifest disagree, the manifest wins. |
| manifest.json.sig | NEW in v3.14 — detached ssh-ed25519 signature over manifest.json by the Agent Dojo release key. |
| manifest.schema.json | NEW in v3.14 — the JSON Schema manifest.json validates against (also published in the GitHub repo). |
| allowed_signers | NEW in v3.14 — the release public key in ssh allowed-signers format, for ssh-keygen -Y verify. Its fingerprint is published in the GitHub README. |
| install.sh | Copies the ten guard hooks plus the onboarding trigger and the memory-kit read-back (twelve hook files), registers them, seeds the v3.13 memory kit (~/.agent-dojo/memory/), writes the rules block, installs the grant-cards reference + the guard status tool + the activation step + the verify-link evidence tool + a local copy of uninstall.sh, writes a version marker + the one-time onboarding-state progress marker — and, ONLY if a license key + auth code + owner name are supplied in this same invocation, performs one licensed fetch in this same run, writing the results ONLY to a staging folder for your audit (see below). |
| tools/activate-powers.sh | Added in v3.9. The whole activation step, a few auditable lines: moves audited Power files from ~/.agent-dojo/powers-staging/ to the live ~/.agent-dojo/powers/, printing every file it moves. Zero network calls. Nothing schedules it; it runs only as a present, deliberate choice after the staged files have been read. A copy is installed to ~/.agent-dojo/activate-powers.sh. |
| tools/verify-link.py | Added in this build (P5 leg 5's evidence tool). Fetches ONE exact url you give it, checks its status/title/body for directory-listing or error shapes, and — if a headless Chromium/Chrome is found on the machine — takes a real screenshot; if none is found, it says so plainly and the proof is logged as HTTP-only (weaker evidence, never dressed up as more). Writes one row to ~/.agent-dojo/guards/link-proofs.jsonl. This is the ONE file in the whole package that makes a deliberate network call — fetching the url is its entire job — and it only ever runs when the AI agent or you deliberately invoke it, never automatically. A copy is installed to ~/.agent-dojo/verify-link.py. |
| uninstall.sh | One-command complete removal. Removes exactly what install.sh created — all twelve hook files, their settings.json entries (surgical edit across PreToolUse, Stop, UserPromptSubmit, and SessionStart), the marked CLAUDE.md block, and ~/.agent-dojo/ — printing every path first and moving your data to a timestamped backup folder instead of hard-deleting it. Zero network calls. |
| hooks/budget-guard.py | NEW in v3.16 — per-task effort caps (tool calls / minutes / identical retries, owner-tunable in ~/.agent-dojo/guards/budget.json). Ships SHADOW: watches and logs, blocks nothing until the owner arms it after burn-in. When armed and a cap crosses, it forces the stop-and-surface conversation: "budget spent — continue or change course?" Never force-armed by upgrades. |
| tools/guard-burnin-report.py | NEW in v3.16 — read-only shadow-guard report: watched / would-block / data window / verbatim samples per watch-mode guard, ending with the one-line arm command. Never changes a mode itself. |
| hooks/delete-guard.py | PreToolUse + UserPromptSubmit (v3.15) hook that BLOCKS hard-deletes — including deletes wrapped inside bash -c or interpreter one-liners; forces a recoverable trash path or explicit human confirmation. Reports the P6 introduction count when it fires, so the transparency rule is mechanical. ACTIVE from install (it has months of zero-false-positive history behind it). |
| hooks/secret-egress-guard.py | Added in v3.8. Watches send-shaped commands (PreToolUse) and finished replies (Stop) for secret-shaped strings — API keys, tokens, private keys. ARMED from install (since v3.12): a match blocks, with the value always redacted in every log line and message — pattern name + first 4 chars + length, never the secret itself (logs to ~/.agent-dojo/guards/). Stand it down to watch-only any time: echo shadow > ~/.agent-dojo/guards/secret-egress.mode. Fail-open by design: malformed input or missing files never break your AI agent. |
| hooks/done-claim-guard.py | Added in v3.8, now five legs (three added in v3.11). ALL FIVE LEGS ARMED from install (since v3.12), each behind its own mode file so you can stand any one down individually. Done-claim: flags "it's done/live/deployed" claims made without verification evidence in the same message — a done-gate pass-token can also relieve the claim, but (fixed in v3.11) only when the token is both recent AND bound to that exact claim, never by time proximity alone. Date-claim (pure calendar math, it cannot false-alarm): recomputes weekday+date pairs in replies against the real calendar and corrects mismatches on the spot. Visual-claim (leg 4): an appearance claim ("layout looks right") wants a fresh screenshot within 15 minutes. Outbound-link (leg 5): a "this link works" claim wants a fresh render-proof for that EXACT url, produced by tools/verify-link.py. Self-contained-request (leg 6): an action request handed to a human must carry every credential/link/input it references, not a dangling "the one from earlier." Same logging, redaction, and fail-open rules as every other leg here. |
| hooks/auth-guard.py | NEW in v3.10 — P1 customer edition. Watches Bash commands for sensitive actions: money movement, credential granting, destructive external commands — matched on a tight endpoint/CLI pattern list (~/.agent-dojo/sensitive-actions.txt, owner-tunable), never on natural-language nouns. ARMED from install (since v3.12): a matched action HOLDS, your AI agent shows you the exact command plus a one-time code (e.g. CONFIRM DOJO-4F7K), and only that code — typed into the session, single-use, 10-minute expiry, bound to that exact command — releases it. The typed-prompt event is the one thing text your AI agent merely reads can never fabricate. Honest scope: it proves a human at this session confirmed this exact action; it does not verify which human (see limitations below). Zero network calls, no secret reads, fail-open on malformed input. |
| hooks/powerguard-text.py | NEW in v3.12. Five guards ported from the Agent Dojo build box, each with its own mode file — all five ARMED from install: owner-action (stops your agent asserting an unevidenced NEGATIVE about something only you can do — "nobody replied", "he never emailed them"; it cannot see your sent mail, your phone, or your calls, so asking is allowed and asserting is not), render-gate (a freshly-built .html/.pdf referenced with no sign anyone LOOKED at it rendered), vocab-gate (two names for one thing, plus your own banned terms — armed but ships with ZERO rules loaded, so it blocks nothing until you fill in ~/.agent-dojo/guards/vocab-terms.txt), cant-gate (a capability refusal with no recovery story), relative-day ("tomorrow (Sat)" when tomorrow is a Sunday). The last two match phrasing rather than facts and are the likeliest to hold an innocent sentence — stand either down with echo shadow > ~/.agent-dojo/guards/<guard>.mode. Stop hook; stats files for mtimes but never reads their contents; fail-open throughout. |
| hooks/powerguard-email.py | NEW in v3.12. ARMED. An email cannot be unsent, so this one ships on. It HOLDS an email-send-shaped Bash command until a human types a one-time code (CONFIRM DOJO-XXXX) bound by fingerprint to THAT EXACT message — an approval for one email can never release a different one, and the code is consumed on use. Drafting, listing, reading and searching mail are never gated; only the verb that actually pushes the message out. Categories you never want held go in ~/.agent-dojo/guards/email-standing-allow.json. |
| hooks/powerguard-memory.py | NEW in v3.12. ARMED. scar-gate: you corrected your agent and it wrote no rule down — the single most expensive failure an agent has, because you end up paying for the same correction repeatedly. memory-freshness: a session's worth of work banked to memory nowhere. Both check a FACT (did a file in ~/.agent-dojo/guards/memory-targets.txt get written), never phrasing. It records only the matched fragment of a correction, a timestamp and a counter — never your prompt text wholesale — and stats your memory files for mtime without reading their contents. Extended in v3.13 (scar-to-guard escalation): every BANKED correction also gets one JSON line in ~/.agent-dojo/guards/scar-ledger.jsonl recording a mechanizable: yes/no verdict (a pattern heuristic, labeled as such in the entry) plus concrete guidance for turning a yes into an executable check — a vocab-terms rule, a sensitive-actions pattern, or a small Stop-hook in the shape of the shipped guards. The ledger stores only the ≤60-char matched fragment and OUR verdict text, never your prompt wholesale; it never blocks anything itself. |
| hooks/customer-ops-guard.py | NEW in v3.13. ARMED (all three). The three build-box operations guards, repointed at YOUR OWN machine: deferral-gate (P2 — a walk-away deferral in a reply must cite a mechanism or be covered by a task actually created in your scheduler within 30 min; plus no pending task may sit overdue past its own miss-threshold), report-gap (P10 — an owner-facing task completion with no outbound message on its reply channel within 30 min is a silent completion; daily rhythm tasks must have fired; a PAUSED rhythm task is your choice and logs info), monitor-coverage (P9 — every workflow declared in ~/.agent-dojo/guards/live-workflows.json must have a live, unpaused monitor task whose last success is within 2× its cadence). They read a Zylos-stack scheduler.db / c4.db READ-ONLY (looked for in ~/zylos, /opt/zylos, ~/.zylos, plus your overrides in ~/.agent-dojo/guards/customer-dbs.txt) and never write to them. Honest degradation is the contract: no such database on this box → the guard logs "no scheduler database found", passes, and guard-status.py shows it as armed-but-IDLE — it never blocks on a fact it cannot check and never pretends to coverage it lacks. Sweeps are throttled (10 min) and findings deduped (one block per finding per 24h). Fail-open throughout. |
| hooks/claim-cite-guard.py | NEW in v3.13. Narrow leg ARMED; wide leg SHADOW by design. A fact told to your owner must carry its check or be labeled as inference. claim-cite (armed): sentences asserting ACCOUNT/POOL/SUBSCRIPTION/IDENTITY state — the exact claim class that burned an owner three times in one morning on the build box — must be accompanied by a verification citation ("verified", "auth status", "checked on the box", ...) or an honest inference label ("I'm inferring", "unverified", "probably", ...). claim-cite-wide (shadow): the same demand for EVERY factual assertion — a net that wide will catch ordinary prose, so it ships watch-only and its ARMING RIDES ITS SHADOW-LOG VERDICT (build-box review: Thursday 2026-07-23; on your box, read ~/.agent-dojo/guards/claim-cite-wide.log after a few days and arm it with one line if it runs clean). This is the ONE v3.13 guard that does not ship armed, for that stated reason. Stop hook, fail-open throughout. |
| hooks/memory-kit.py | NEW in v3.13 — a read-back, not a guard: it blocks nothing, ever. SessionStart hook that injects the memory kit — ~/.agent-dojo/memory/rules.md (banked corrections), owner-preferences.md, state.md (open work) — into your agent's context at every session start. This is the missing half of P4: scar-gate and memory-freshness were already forcing the WRITE side; a file nothing re-reads is a rule forgotten with extra steps, and the wake-up injection is what makes "kept for good" true. Empty files inject one honest line, oversized files are truncated with a pointer, a missing kit is silent, and any error exits 0 — it can never cost you a session. Read-only; stdlib; zero network. |
| hooks/onboarding-trigger.py | NEW in v3.11 — the only hook here that is not a guard. A SessionStart hook that reads ~/.agent-dojo/onboarding-state.json and, when a step you were promised at purchase is still outstanding, says so at the start of the session: the interview not yet offered, or the Day-1 report past due and undelivered. It exists because v3.11 put those duties on disk but nothing ever READ that file — the whole sequence depended on your AI agent spontaneously opening it, which a sandbox run of the real journey showed it does not reliably do. It prints text and nothing else: it blocks nothing, holds nothing, and cannot stop your agent working. Once onboarding is complete it is permanently silent, so it costs you nothing per session thereafter. Any error, malformed file, or missing file exits silently rather than disturbing your session. Zero network calls, no secret reads. |
| tools/guard-status.py | Read-only burn-in report: per guard, what mode it's in, how many messages it watched, how many would-blocks. When a guard's log is clean past its burn-in threshold it prints the exact one-line command to arm it. It NEVER arms anything itself — arming is always your explicit action. |
| rules/agent-dojo-rules.md | A fixed placeholder — always, whether or not a license is supplied. It never contains real Power content and carries no instruction to fetch or trust anything at any future time. Real Powers, if licensed, are written to ~/.agent-dojo/powers-staging/ as plain files for audit (live in ~/.agent-dojo/powers/ only after the explicit activation step), never spliced into this block or into CLAUDE.md. It also carries the receipt-acknowledgement duty: on receiving an install/upgrade request, your AI agent first acknowledges receipt and states its plan before starting the audit — and (since v3.11) the onboarding duties themselves (the interview, first 24 hours, Day-1 report), written here on disk so a lost or interrupted install conversation can no longer make them evaporate; their progress is tracked in ~/.agent-dojo/onboarding-state.json. |
| rules/grant-cards.md | Owner-facing reference the equipping duties draw on: category-based access cards (email first, money last), least-privilege recipes, revoke paths. Installed to ~/.agent-dojo/grant-cards.md. |
| README.md | This file. |
| VERIFY.md | Line-by-line inspection guide. |
Specifically, this package does not:
- grant any permission, access, or capability the agent didn't already have
- name any person, handle, or channel as specially trusted (your agent's existing notion of who its human is stays exactly as it was)
- relax, override, or compete with the agent's built-in safety behavior (the rules file states explicitly: stricter built-in rules win)
- leave any standing "fetch this later" instruction anywhere — the one licensed
network call this package can ever make happens, at most once, in the SAME
install.shrun that installs everything else, using a license key + auth code + owner name supplied in that same invocation (seerules/agent-dojo-rules.mdandinstall.shstep 6). Its results land ONLY in the staging folder (~/.agent-dojo/powers-staging/), where they sit inert until the agent has read them and the activation step is run deliberately. If those three values are not supplied when you runinstall.sh, no network call happens at all, and nothing is written anywhere describing one as pending — a later request to fetch Powers is not something this install authorizes; it stands on its own and gets evaluated fresh - activate anything fetched over the network on its own — fetched content is
never live-on-arrival; the move from staging to live is a separate, tiny,
readable script (
tools/activate-powers.sh) that only ever runs as a present, deliberate choice - store or request any master password, login code, or unscoped credential
- send anything anywhere: all TWELVE hook files (the ten guard hooks, the
onboarding trigger, and the memory-kit read-back) make zero network
calls, read no secret stores, and their logs never contain a caught value
(redaction is structural, not a promise — read the
redact()andscrub()functions yourself). The one documented exception istools/verify-link.py(new this build) — a TOOL, not a hook, never auto-invoked, that fetches exactly one url you give it because that is its entire job (P5 leg 5 render-proof); see VERIFY.md for the audit treatment.
Install / upgrade
From the extracted folder, restriction-only (no license): bash install.sh
With a paid license — key, auth code, and owner name in the SAME command, so the whole install (local files + licensed fetch) happens in one sitting:
AGENT_DOJO_LICENSE_KEY=<key> AGENT_DOJO_AUTH_CODE=<code> AGENT_DOJO_OWNER_NAME="<your name>" \
bash install.shThe licensed fetch stages: it writes the Power files to
~/.agent-dojo/powers-staging/ only. Read every staged file, then activate
them with one deliberate command:
bash ~/.agent-dojo/activate-powers.shNothing staged has any effect until that step runs.
Re-running is safe and is also the upgrade path: the rules block is replaced
in place, and your agent's Power-introduction history is kept on upgrades
(only a genuinely fresh install starts the introductions from zero). One
loud exception, the standing since-v3.13 ruling: an upgrade FORCE-ARMS every
guard back to its shipped mode, printing each change — your mode choices
hold between upgrades, not through them (see "Modes" below; claim-cite-wide
is never forced down).
Uninstall completely: bash uninstall.sh — one command, prints everything it
removes before touching it, and moves ~/.agent-dojo/ (introduction counts,
grant cards, guard logs, any licensed Powers) to a timestamped backup folder
instead of hard-deleting, so even the uninstall is reversible until you delete
the backup yourself. A copy also lives at ~/.agent-dojo/uninstall.sh after
install, so you keep the uninstaller even if you delete this extracted folder.
Safe to run twice; re-running install.sh reinstates everything.
What changed in v3.16
Seven items — the ratchet release: the guard net can now TIGHTEN from use.
- Ratchet (owner-extendable patterns): done-claim, cant-gate,
secret-egress, and claim-cite now read ADDITIVE owner regexes from
~/.agent-dojo/guards/owner-patterns/<guard>.txt— built-ins never replaced, malformed lines skipped. Plus the rules-block ratchet duty: a miss no guard matched gets proposed to the owner as a one-line pattern; owner yes → appended. Every escape tightens the net. - Burn-in report:
guard-burnin-report.py(read-only) shows each shadow guard's watched / would-block / window / samples, ending "arm it?" — plus the rules-block duty to present it unprompted at seven days of data. Arming stays the owner's typed action. - Budget guard v1 (ships SHADOW): per-task effort caps — tool calls,
elapsed minutes, identical retries (owner-tunable
budget.json). At a cap, armed: stop and surface "budget spent — continue or change course?". 12th hook, 21st mode file (19 enforce + 2 shadow); excluded from force-arm like claim-cite-wide. - Install line: round-5-validated wording — verify the code matches its claims; the owner makes the install decision after the audit.
- Run-before-deliver duty: code beyond ~10 lines is written to a file, RUN, fixed, and only then delivered — with the run's real output shown.
- File-delivery duty: verified work products travel as actual files via the channel's attachment mechanism, never as chat bubbles beyond short snippets.
- Official-channels section (above): the complete public footprint, listed for auditing agents to verify.
Package: 38 files (27 + 11 tests); 17 guards across 12 hook files; 21 mode files — 19 enforce, 2 shadow (claim-cite-wide, budget). Force-arm marker semantics unchanged from v3.15 (a v3.15.x upgrade re-arms nothing; already-armed owner choices are never lowered).
What changed in v3.15.1
Documentation-only release: adds the README disambiguation line above (no affiliation with the academic AgentDojo prompt-injection benchmark, ethz-spylab). No functional change — no hook, rules, settings, or installer behavior differs from v3.15; the guard set, mode files, and force-arm state are byte-for-byte v3.15's.
What changed in v3.15
Four hardenings from the first naive-agent audit in the wild (a customer's untrained agent took the audit door on the live package and found real gaps — free adversarial review, all four accepted), plus one approved rules clause:
- Bypass hardening (delete-guard + secret-egress): the agent-typeable
AGENT_DOJO_CONFIRM_DELETE=1/AGENT_DOJO_CONFIRM_EGRESS=1command prefixes are REMOVED — nothing mechanically tied them to a human. The only release for a permanent delete or an intentional raw-value send is now a HUMAN-TYPED one-time code (CONFIRM DOJO-XXXX, same flow as the customer-email gate): single-use, 10-minute expiry, fingerprint-bound to the exact command, recorded by each guard's own never-blocking UserPromptSubmit leg. Settings now register FIVE UserPromptSubmit entries. - Powers persistence:
activate-powers.shnow distills ONE line per activated Power (the first sentence of its Principle section) into~/.agent-dojo/memory/rules.md, which the memory-kit SessionStart hook already re-injects — so each Power's core rule survives into every future session instead of only the one that read the prose. Idempotent; full prose stays inpowers/as reference. Upgrades re-run the distillation once over already-live powers. - Watermark self-disclosure: the activation printout now states that Power files carry visible and invisible license watermarks tied to the purchase (restrict-or-disclose applied to our own product). Honest limit: watermarks catch careless leaks, not a determined stripper.
- Decision-procedure closing step: the official final move of the closed match-or-refuse procedure is now explicit — the agent verifies, then the OWNER personally triggers the one licensed network call.
- Disclosure-first duty (owner-approved): new rules-block clause — when any guard acts, that fact LEADS the reply; a disclosure buried under eight paragraphs has failed quietly. It never shrinks WHAT is disclosed, only fixes WHERE it lands: first.
Force-arm re-applied (marker .v315-force-arm-done). Package: 35 files
(25 + 10 tests); guard set unchanged: 16 guards, 20 mode files, 19 enforce +
1 shadow (claim-cite-wide).
What changed in v3.14
The acceptance release: nothing new is guarded; everything is made verifiable, so a cold agent's OWN audit can conclude "yes". Six items:
- Install manifest (
MANIFEST.md+manifest.json, schema-validated): every file the install writes, every settings entry, the full CLAUDE.md block, the one conditional endpoint, every env override — with REAL per-file sha256s. An installer action with no manifest row is grounds for refusal, andtests/test-manifest.pymakes that diff mechanical. - Signed manifest (
manifest.json.sig+allowed_signers): ssh-ed25519 detached signature; the key fingerprint is published in the public GitHub README. install.sh --auditdry-run: prints every action the installer would take — placeholder-form paths, hashes, the settings table, the verbatim CLAUDE.md block, the network trigger condition — and touches NOTHING (tests/test-audit.pyproves it against a pristine HOME).- Balk-list fixes F1–F6 from the 007 cold-audit: the two scripts named
install.share now named distinctly everywhere (F1); the integrity section ships identically in repo and tarball READMEs (F2); VERIFY.md check 6 counts BOTH SessionStart entries (F3); the installer's armed count now reads "15 fully + 1 partially" (F4); the duplicate step label "2a-ii" is gone (F5); theAGENT_DOJO_API_BASEoverride is documented in VERIFY.md and the manifest, with the audit asserting it unset (F6). - Force-arm re-applied (marker
.v314-force-arm-done), so a v3.13 box upgrading here also gets the "always ship our current best" behavior. Guard set unchanged: 16 guards, 20 mode files — 19enforce, 1shadow(claim-cite-wide, whose arming still rides its shadow-log verdict). - Wording standard carried forward: every count above was made by counting this package — 34 files: 25 package files + 9 tests; 11 hook files; 16 guards (15 fully armed + 1 partially: claim-cite narrow armed, wide shadow).
What changed in v3.13
Six ratified items, each verifiable in this package:
- Three customer-side guards (
hooks/customer-ops-guard.py, ARMED):deferral-gate,report-gap,monitor-coverage— the build-box operations guards, repointed at YOUR OWN scheduler/message databases. They come OFF the not-shipped list because they can now genuinely check something on your box; where your box has no such database they say so and stay honestly idle rather than pretending. - Minimal memory kit (
~/.agent-dojo/memory/+hooks/memory-kit.py): three tiered files (rules / owner-preferences / state) written by your agent under guard pressure and READ BACK at every session start. P4 delivered whole: forced writes were already shipped; the wake-up injection completes the loop. - Scar-to-guard escalation (in
hooks/powerguard-memory.py): every banked correction gets amechanizable: yes/noverdict with build guidance in~/.agent-dojo/guards/scar-ledger.jsonl— the recorded upgrade path from remembered rule to enforced check. - Claim-cite gate (
hooks/claim-cite-guard.py): narrow leg (account/pool/subscription/identity claims) ARMED; wide leg (every factual assertion) SHADOW until its false-positive log earns arming. - Force-arm migration (install.sh step 2a-ii): an upgrade now arms every guard to its shipped mode, overwriting mode files — the "always ship our current best" ruling, superseding v3.12.1's respect-your-settings behavior. Every overwrite is printed; the migration only ever raises a guard to its shipped mode, never lowers one; your mode choices hold between upgrades, not through them.
- Wording standard carried forward: every count in this file was made
by counting this package. The true numbers: 27 files; 11 hook files
(9 guard hooks + the onboarding trigger + the memory-kit read-back);
16 guards; 20 mode files, 19 seeded
enforce, 1 seededshadow(claim-cite-wide, deliberately) — the delete-guard is always-on with no mode file; done-claim carries 5 legs and claim-cite 2, each leg with its own mode file.
What changed in v3.12.1
Wording only — no behavior change. v3.12 armed every guard (the installer's
seed_mode block writes enforce 15 times and shadow zero times), but
several of its own printed lines, this README, and hook docstrings still
described done-claim, cant-gate, relative-day, and auth-guard as shadow, and
carried stale counts ("14 files", "five hooks"). On a security product the
self-description must match the behavior exactly, so v3.12.1 fixes every such
line. The true numbers, counted against this package: 17 files, 8 hook
files (7 guard hooks + the onboarding trigger), 12 guards, all armed on
install via 15 mode files every one seeded enforce (the delete-guard is
always-on with no mode file; the done-claim guard's five legs each have their
own). The installed hooks behave identically to v3.12.
What changed in v3.12
Eight more guards, ported from the machine we run Agent Dojo on, where they have been working against real traffic since 2026-07-16 — plus a correction to how the existing ones shipped.
The honest version of why. Up to v3.11 this capsule shipped its guards with exactly one of them actually enforcing. Everything else watched and logged. That was our shipping default, not a decision you made, and it meant you were paying for protection that was mostly taking notes. v3.12 arms every guard: all 12, no exceptions — no guard ships silently watching.
The honest caveat that comes with arming everything: the three
phrasing-matching guards (done-claim, cant-gate, relative-day) judge
wording rather than facts, and on our own box that class of guard has
produced false holds — so they are the ones most likely to occasionally hold
an innocent sentence. Any guard can be stood down to watch-only with one line
(echo shadow > ~/.agent-dojo/guards/<guard>.mode); your choice holds until
the next upgrade (see the v3.13 force-arm ruling above).
If you are upgrading from any earlier version, the v3.13 installer runs the force-arm migration described above: every guard is set to its shipped mode, every change is printed, and nothing is ever lowered — a guard you armed early (claim-cite-wide included) stays armed.
One guard we did NOT ship, and why. customer-state depends on a live
licence/tenant probe feed — an API this capsule cannot reach — and it stays
ours-only, permanently. (In v3.12.x this list had four entries;
deferral-gate, report-gap, and monitor-coverage came off it in v3.13 by
being repointed at YOUR OWN operational databases — and where your box lacks
those databases, they report armed-but-IDLE rather than pretending.) We do
not ship hollow guards that always pass, because a guard that cannot
actually check anything is worse than no guard: it tells you you're covered
when you aren't. python3 ~/.agent-dojo/guard-status.py states all of this
per guard.
Modes: armed, watch-only, and how to move between them
15 of 16 guards install ARMED (enforce in their mode files; the
delete-guard is always-on and has no mode file). The one exception is
declared, not hidden: claim-cite-wide installs in shadow because its wide
net must prove its false-positive rate in its own log before it may block.
Nothing ships SILENTLY watching. The mode files are yours:
- Stand a guard down to watch-only any time:
echo shadow > ~/.agent-dojo/guards/<guard>.mode. In shadow it watches and logs only — it structurally cannot block anything. - See what any guard is doing: run
python3 ~/.agent-dojo/guard-status.py. It shows every guard's live mode and exactly what it saw — including anything it blocked, or (in shadow) would have blocked, redacted. - Re-arm a stood-down guard the same way
(
echo enforce > ~/.agent-dojo/guards/<guard>.mode). For a guard you stood down after a false hold, the status tool applies a burn-in heuristic (e.g. done-claim ≥7 days, zero would-blocks, ≥20 watched messages) before calling it READY TO ARM again — a clean log on an idle machine proves nothing. Mode changes never happen on their own, on a schedule, or on anyone else's say-so — with one printed exception: an UPGRADE force-arms every guard back to its shipped mode (the v3.13 ruling above), announcing each change as it makes it.
Legs 4/5/6 (visual-claim, outbound-link, self-contained-request) each have
their own mode file, so you can stand one leg down without touching the
others; guard-status.py reports each by name.
The date-claim leg deserves its own note: it is pure arithmetic — a weekday that doesn't match its date is simply wrong, and your AI agent corrects it before the reply stands.
Honest limitations (the guards' edges, stated plainly)
- The secret-egress Stop leg is repair-within-seconds, not pre-send suppression: the reply has already rendered locally when it fires. The hard pre-egress block for secrets moving OFF the machine is the PreToolUse leg.
- Egress detection is heuristic: a custom send wrapper the guard doesn't recognize slips past the command leg; the reply leg is the backstop.
- Local secret handling is deliberately NOT gated — writing your own
.envkeeps working. The guard gates secrets entering send-shaped commands. - The done-claim leg's phrasing sensitivity on YOUR traffic is unknown until it has run on your traffic — it ships armed (that is this release's deliberate default), so it is the leg most likely to hold an innocent sentence early on. If it does, stand it down to watch-only, let it burn in, and re-arm when your own log runs clean.
- The auth-guard proves a human at this session's prompt confirmed this exact action — it does NOT verify WHO that human is. On a single-user setup that human is, in practice, you; the purchase email recorded at install is a label for addressing, never identity verification. What it stops are content-level attacks: a poisoned email, webpage, or pasted document can order your agent to move money, but it cannot type a code into your prompt, and it cannot know a code generated after the hold. What it does NOT stop is someone who has taken over your actual input channel — at this layer they are indistinguishable from you. That is one layer up: your account security (2FA, device hygiene).
- Auth-guard coverage is pattern-based: money moving through a CLI or API it
doesn't recognize slips past. Tune
~/.agent-dojo/sensitive-actions.txtto your own payment stack. It gates Bash commands only — other tool surfaces are not matched (same boundary as the other guards). - If your agent's replies relay through a group or shared channel, a non-owner participant could read and type the CONFIRM code. A verified transport layer (which can check WHO sent a message) is the documented upgrade path; the challenge still forces a visible, logged human turn.
- A determined agent could bypass the auth-guard's local marker files —
writes into
~/.agent-dojo/guards/are themselves held once armed, which raises the bar but does not eliminate it. This controls confused or injection-steered agents, not adversarial ones (true of every capsule guard). - The done-claim leg's pass-token relief (v3.11) binds on a token's own
task_idappearing in the claim text — it is still a heuristic, not a cryptographic guarantee. It closes the "any token verifies any claim" gap, not every conceivable coincidence of wording. - Leg 4 (visual-claim) searches configured directories for a recent image
file — it cannot tell whether that image is actually a screenshot OF the
thing being claimed. A stale-but-recently-touched unrelated .png in a
configured root can relieve a claim it has nothing to do with; tune
~/.agent-dojo/guards/screenshot-roots.txtto directories your AI agent actually saves real screenshots into, and keep them free of clutter. - Leg 5 (outbound-link) and its evidence tool
tools/verify-link.pyare only as strong as what's on the machine: without a headless Chromium/Chrome binary on PATH, the proof degrades to an HTTP status + page-content check — real evidence, but not a render, and the log says so every time rather than pretending otherwise. Install a headless browser for the full render-proof. - Leg 6 (self-contained-request) is pattern-based, tuned on the "the VNC password (the one from our earlier sessions)" scar and universal English phrasing; it will under-flag credential references phrased in ways it hasn't seen and, like every text leg here, may occasionally hold an innocent phrasing — stand it down to watch-only if it does.
v3.11 changes (from v3.10)
- Fixed: done-claim guard's pass-token relief could be satisfied by an
unrelated task.
pass_token_near()used to accept ANY*.passfile in~/.agent-dojo/done-gate/written within ±30 minutes as verification of ANY completion claim — nothing tied the token to the claim it supposedly verified, so one legitimately-gated task created a 30-minute window in which every unverified claim in the same reply passed silently. The time window is unchanged (still ±30 min, still an additional constraint); a token must now ALSO carry the same task-id referenced in the claim's message text to count. A token that cannot be identified (old-format, plain-text, malformed) now fails closed — treated as not-verified, never as a crash. This leg still ships SHADOW (log-only) — the fix improves what the log honestly says, it does not change the shadow/enforce boundary. - Onboarding duties now written to disk at install time, not just
described in a chat message. Previously the interview / first-24-hours /
Day-1-report duties existed only in the paste block the owner sent at
purchase — if that install conversation was interrupted, the duties were
lost with it and the Day-1 report promised at purchase could silently
never arrive.
rules/agent-dojo-rules.md(always-loaded, installed intoCLAUDE.md) now states these duties directly, andinstall.shwrites~/.agent-dojo/onboarding-state.json(interview/first_24h_work/day1_report, allpending, plus a computedday1_due_at) so an incomplete onboarding is detectable instead of invisible. Create-if-absent only: re-running install never resets real progress. - The interview now offers your owner a choice of two formats covering the same four areas (business · tools and platforms · no-go zones · what matters most to watch): THE INTERVIEW (asked in chat) or THE INTAKE FORM (filled in on their own time). Your owner picks; either way the same four areas land on record. The honesty line is unchanged in spirit, renamed in wording: if the interview never happened, say so plainly at the 24-hour mark and offer it again.
- New: P5's done-claim discipline gained three more checks, ported from
the publisher's own production checks — a visual claim ("the layout looks
right," "fonts are fixed") now wants a fresh screenshot; a claim that an
outbound link "works" or is "ready" now wants a render-proof for that
exact URL (
tools/verify-link.py, new in this build); and an action request handed to a human (log in, enter a code, click here) now wants every credential and link it references actually carried in the message, not a dangling "the one from earlier." All three ship SHADOW-FIRST, each behind its own mode file, log-only until the owner arms it per-check — same shadow discipline as every other check in this package. - No changes to the delete-guard, secret-egress guard, auth-guard, the rules block's no-forward-commitment character, or the licensed fetch.
v3.10 changes (from v3.9)
- New shadow guard: auth-guard (P1 customer edition). Sensitive actions
— money movement, credential granting, destructive external commands —
are watched (shadow, log-only, values redacted) and, once YOU arm it,
HELD until a human types a one-time confirmation code into the session:
single-use, 10-minute expiry, bound to the exact command. There is
deliberately NO self-attest override the agent could be talked into
using; the typed code is the only release path. Installed as one readable
hook file (
hooks/auth-guard.py), registered on PreToolUse (the hold) and UserPromptSubmit (the confirmation recorder — never blocks, records nothing but a typedCONFIRM <code>). A default sensitive-action pattern file is written to~/.agent-dojo/sensitive-actions.txt(create-if- absent, owner-tunable).guard-status.pyreports its burn-in like the other guards;uninstall.shremoves the hook + all three settings entries with the same surgical-edit guarantees. - The licensed install now also records your purchase email to
~/.agent-dojo/owner-handleas a plain addressing label (hold messages name who to ask). It is a recorded label only — nothing verifies it. - No changes to the delete-guard, the wave-1 guards, the rules block's no-forward-commitment character, or the licensed fetch (same single conditional call, same three values sent, still staging-only).
v3.9 changes (from v3.8)
- Staged licensed fetch (audit-before-activate). The one licensed network
call now writes Power files ONLY to
~/.agent-dojo/powers-staging/— never directly to the live folder. The agent can read every fetched byte on disk before anything counts as installed; activation is a separate, tiny, auditable script (tools/activate-powers.sh, also installed to~/.agent-dojo/activate-powers.sh) that moves staging to live and prints every file it moves. This closes the one previously-unauditable gap: fetched content used to land live; now nothing fetched is live until it has been read and deliberately activated. - Receipt-acknowledgement duty. On receiving an install or upgrade request for this package, the agent's first act is a short acknowledgement with its plan ("Got it — auditing the package now, back in ~10 minutes") — before the audit starts, so the owner is never left wondering whether the message landed. Disclose-only; it changes nothing about the audit itself.
- No changes to the three guards, the rules block's no-forward-commitment character, or the fetch's scope (same single conditional call, same three values sent, nothing else).
v3.8 changes (from v3.7)
- Two new local guards (shadow-first): secret-egress (P11) and done-claim + date-claim (P5). Ported from the publisher's own production guards (validated at 48/48 tests and zero false positives over 2,164 real outbound messages / 7 days before shipping), installed as ordinary readable hook files. Shadow by default; arming is owner-only via the printed command.
- Guard status tool at
~/.agent-dojo/guard-status.py(read-only). uninstall.shextended to remove the new hooks + their settings entries (both PreToolUse and Stop) with the same surgical-edit guarantees.- No changes to the delete-guard, the rules block's no-forward-commitment character, or the licensed fetch.
v3.7 changes (from v3.6)
- One-command tested uninstall.
uninstall.shmechanizes the manual removal steps this README used to describe: hook file out, itssettings.jsonentry surgically removed (everything else in the file kept), the markedCLAUDE.mdblock deleted (a copy is saved to the backup), and~/.agent-dojo/moved to a timestamped backup rather than destroyed — the uninstall itself honors the P6 no-irreversible-deletes discipline. It makes zero network calls and is idempotent.install.shnow also drops a copy at~/.agent-dojo/uninstall.sh. - No behavior changes to the hook, rules, or licensed fetch.
v3.6 changes (from v3.5)
- STEP 1 + STEP 2 collapsed into one atomic install. Previously, a
license-gated fetch was described in
rules/agent-dojo-rules.mdas something your owner would trigger with a separate, later message — that standing "fetch this when asked later" language, once spliced into your own CLAUDE.md, was structurally unverifiable (nothing in the file can confirm WHO is asking in some future session) and is why two independent fresh installs refused the whole package on 2026-07-16. v3.6 removes the forward-looking language entirely: the placeholder now describes only the present, and the licensed fetch — if a license key/auth code/owner name are supplied — happens immediately, inside the sameinstall.shrun, from one real present request. Nothing is ever left waiting in memory for later. rules/agent-dojo-rules.mdnever carries real Power content and never will; licensed Powers are written only to~/.agent-dojo/powers/.
v3.5 changes (from v3.4)
- Delete-guard: quote-aware parsing (no more false blocks on quoted text) and
wrapped-command coverage (
bash -c "rm …", python one-liner deletes,xargs rm). - Delete-guard reports the P6 introduction count when it fires — the transparency rule's counter check is now mechanical, not memory.
- Fresh installs initialize the introduction counter; upgrades keep it.
- The interview (duty 13) now uses the exact same nine sections as the publisher's written intake form — answer either way, identical result — and explicitly banks every answer as permanent memory with a confirm-back summary.
- New equipping duties 16-18 + the grant-cards reference file.
Earned in our field. Installed in your agent.
