No agent may claim work is finished without proof a human or another agent can re-run. A claim with no command behind it is refused, not discounted.
.claude/hooks/universal-stop.js → tools/eidos/mastermind-ask.js agent --json*-check.js modulesA gift to the community — Darius Kiaulakis, Mainstream.PRO
Givers Gain. This is the real engineering report of a working multi-vendor agent harness, published in full minus what would expose the machine itself. Take anything in it: the checks, the tables, the measurements, the failures. Nothing here needs my permission to copy.
📞 +370 665 55500 · ✉️ Darius@Kiaulakis.lt · 💬 AI Mastermind LT — Telegram group
#AiOpsCatalyst · #BremenLLM · #GiversGain
One sentence: Mastermind is the standing quality harness that every AI agent on this machine — whichever company built it — must satisfy before it is allowed to stop and say “done”. It is not advice and not a linter. It is the last thing that runs, and it can refuse.
No agent may claim work is finished without proof a human or another agent can re-run. A claim with no command behind it is refused, not discounted.
.claude/hooks/universal-stop.js → tools/eidos/mastermind-ask.js agent --json*-check.js modulesThe Bhagavad Gita values outrank every technical rule: honesty (never fake a result), non-harm (reversible, never destroy a colleague’s work), right action, real value to people. A rule may never be used to justify a dishonest or harmful act.
tools/eidos/values-check.js, rolled into a visible values verdictGreen tests are not the finish line. Work counts as done only against what the CEO actually asked for — and only once the running system does it, not once the code lands on master.
tools/eidos/two-tier-gate.js + mastermind-terminal-policy.jsThe seven layers, one line each — each one stands between an agent and a different kind of harm. §1 of the Details below scores how strong each is today; the full reference is in the SYSREF section at the end of this page.
| # | Layer | The harm it stands between |
|---|---|---|
| 1 | Values and constitution | An agent doing something dishonest or harmful and citing a rule as permission. |
| 2 | Permission floor | A tool call that should never be allowed to start at all. |
| 3 | Tool guards (pre-execution) | A destructive or credential-leaking command reaching the shell. |
| 4 | The Stop gate (Mastermind) | An agent stopping while its own claims are unproven or its findings still open. |
| 5 | Commit and publish guards | Unreviewed, secret-carrying or peer-destroying work reaching master. |
| 6 | Cross-vendor review | One model marking its own homework. |
| 7 | Monitoring and self-healing | A failure at 03:00 that nobody is awake to see. |
Read this before the history below. Every number here was produced by a command run while this version was written, and the command is printed in the row, so you can re-run any of them yourself. If a row disagrees with the prose further down, this section is the truth and the prose is stale. Each row says plainly what the number means for you.
Correction, v2.3.0. Until this version, this paragraph claimed every number
was “counted when the page is built, not typed by hand”. There is no build step.
No generator writes this page — rg -l 'docs/mastermind' tools/ --type js returns
readers and gates, never a writer, and git ls-files finds no renderer for it. The
numbers were typed by the authoring agent from commands it had run, which is fine and is exactly
what happened again here — but a page that says a machine counted it, when a machine did not,
is telling you the wrong thing about how much to trust it. The claim is withdrawn and replaced by
the printed command, which is the thing that was actually true all along.
| What | Right now | What that actually means |
|---|---|---|
| Open work needing a person | 3 | Engineering rows with a named owner and a task-board id. None of them is a decision for you, and none is a money row. v2.3.0: was 1; the rescan added 2 - a RED ratchet test on master and a model-registry contradiction, both filed with ids rather than described here and left. |
| Weak spots found, and fixed | 71 fixed of 97 found | Each fixed row carries a command you can re-run yourself and the commit it landed in. |
| Closed since this list was written | 25 | Rows that were open when the audit was written and have since been finished; the page removes them itself rather than letting them age. |
| Background services in a failed state | 2 | Named: mpro-taskman-profile-ci.service and mpro-unit-install-drift.service. A failed service is not silent - it raises an alert and a task-board row. v2.3.0 correction: this said 1. systemctl list-units --state=failed --plain returns two; the user manager returns a further 7, which this row has never counted and still does not - it counts SYSTEM units only, and now says so. |
| The code that is actually executing | d389847979735 commits behind master fb52e021aa6 | Most background services run from one shared copy of the repository - today .wt/svc-runtime-b. A fix is only real once that copy carries it, which is why some rows below say landed rather than running. v2.3.0 correction: this said e5479372f5c and called it “master”. It is neither master nor what is executing. Re-run: git -C .wt/svc-runtime-b rev-parse --short=11 HEAD then git rev-list --count $(git -C .wt/svc-runtime-b rev-parse HEAD)..origin/master. |
| Rules, skills and agents in force | 191 rules · 172 skills · 102 agents | The governance an agent must satisfy before it may finish. Counted from the files themselves, so a deleted rule stops counting immediately. Re-derived unchanged: find .claude/rules -maxdepth 1 -name '*.md' | wc -l → 191 (189 of them tracked and not a README), find .claude/skills -name SKILL.md | wc -l → 172, find .claude/agents -maxdepth 1 -name '*.md' | wc -l → 102. |
| Checks the quality gate runs | 311 | Run before any agent is allowed to say done. They block only on a safety finding; the rest lower a score that is diagnostic. Re-derived unchanged: find tools/eidos -maxdepth 1 -name '*-check.js' | wc -l → 311 (310 tracked). |
| Constitution articles in force | 69 | The numbered articles every agent works under, highest is C107 (the numbers are not contiguous). Re-derived unchanged: grep -cE '^## +C[0-9]+' docs/constitution.md → 69. Worth knowing: the repo's own CLAUDE.md still says “66 articles, numbered to C104” and docs/CLAUDE.md says “61 articles, numbered to C99”. Both are stale against this command; neither is this report's file to edit. |
Every row was re-run by the orchestrator, not taken from the fixer’s word (C105). Commits are the SHAs on origin/master, tip fb52e021aa6 at the time of this version.
v2.3.0 re-ran every command this page prints — all 63 of them, not a sample. 54 exit 0. Of the nine that did not: two were real breakages and are fixed in this version (test-root-pinning.guard.test.js was RED on master; subagent-receipt-verify.js --help hung until killed); two are this page's own commands being wrong and are corrected above (the /tmp/ gate-sync line, which also failed the repo's report gate); three are reporters that exit non-zero BY DESIGN when they find drift and are doing their job (model-registry-refresh --check, generate-agent-onboarding --check, gate-item-coverage-check — the first and last are now filed as owned rows at the top); and two are artefacts of the sweep itself, honestly declared: worktree-release --path <abs> and subagent-receipt-verify --receipt <f> --parent <node> are usage templates whose placeholders the extractor stripped, so they ran with missing arguments. That last pair is not a defect in anything but the measurement, and is listed rather than quietly dropped.
| Sev | Harm stopped | Before → after (measured) | Proof you can re-run | Commit on master |
|---|---|---|---|---|
| P0 BOARD | The gate that decides whether an agent may finish downloaded the entire task board - 25 MB, 5,406 tasks - up to 13 times per finish, and sent the board’s master key as plain text inside the command line of every one of those calls, where any process listing on this machine could read it. Task board + Stop gates | Before: One gate read: 25,781,341 bytes in 2.89 s; the request already asked for the few columns it needed (fields=) and the board ignored that and sent everything. Up to 13 such reads per finish, plus one more to pick the next task; if one read failed, that whole branch of the gate was dropped. Asking for a column that does not exist returned rows without it and said nothing. The key rode the command line at six places. The board’s health page reported “healthy” throughout.After: The board honours the column list with the same parser the search route already used: one gate read is 13,750,943 bytes in 1.16 s (16 columns), and the two Stop-path readers now share one read per finish instead of up to 13. A read that fails no longer drops its branch. An unknown column is refused with a clear HTTP 400 naming it and the supported list. The key is handed to the tool through its input channel, never the command line. Full-board callers are untouched (25,795,873 bytes, fields=* byte-identical to before). |
npx jest tools/mpro-taskman/server.nodes-fields.test.js tools/scripts/curl-bearer-argv.guard.test.js | 35665cf4f82 |
| P0 SVCRAIL | Fixes that had already landed on master did not reach 12 running services. Among them was tonight’s fix for the Ollama review deadlock: the rail that moves services to new code refused every slot. Self-healing (deploy rail) | Before: The scheduled refresh failed at 00:41 UTC (exit 1). Every standby slot was refused:
git status also refused healthy slots under load (7.5 s measured). And two units owned by another systemd override (Syndicate, FailureHub) would have failed the post-cutover check and rolled back all 14 units.After: The rail now scrubs a standby slot that runs no process and whose changes all exist on master already. It first saves every byte under refs/rescue/svc-runtime/<time>/<slot>, reads the copy back, and only then restores the slot. Changes found nowhere else still block the slot. Units owned by another override are skipped and named on every run. The git status limit is 60 s. |
npx jest tools/systemd/lib/service-runtime-plan.scrub.test.js tools/systemd/lib/service-runtime-cli.slow-git.test.js && readlink .wt/svc-runtime | c25c763e19b 90ee66580d5 |
| P0 CRASHALERT | The crash watcher had been calling successful services crashed since about 2026-08-31, and each false alarm woke a paid AI session every ten minutes and eventually paged the CEO. It was the harness spending money to tell him about services that never failed. Monitors (false alarms) | Before: The watcher never asked the operating system anything. It read the Hub’s status list, where a service is “online” only while it is actively running - so a job that runs every ten minutes, finishes, and exits successfully looks exactly like one that died. It then reported it with a fixed sentence, “has crashed 3+ times”, and a restart count of zero that it never measured: a stated cause the code had never checked. After: For each candidate the watcher now asks the operating system directly - type, result, state and restart count - and stays silent when the state is not “failed” and the result is “success”: a finished job, not a crash. The alert carries the real numbers instead of the fixed sentence. A probe that fails leaves the old cautious behaviour, so nothing stops being reported by accident, and the service name is still checked against the existing allow-list before it reaches a command. | Red first: 9 of 17 failing, including the three new classification cases. Green: 17/17, and the 8 older tests are byte-unchanged and still pass; 55/55 on the shared system seam it reads. Taken over after the packet’s own sessions stalled - one Claude peer died on a weekly limit and a codex session sat at 0% CPU for 11 hours with a failed hook - and re-checked first: nothing had landed for that file. LANDED 1e06351cbf9. RUNNING: partly - the loop that uses it was idle (697 us of processor time in 12 seconds) and was restarted onto a new process, but it reads its code from the shared checkout, which is 25 commits behind while another session holds a file there; it runs the new code on the next restart after that sync. Node: fix:harness.crash-responder-oneshot-false-positive.npx jest tools/autonomous/pm2-crash-responder.test.js | 1e06351cbf9 |
| P0 P0CRED | Six places still handled the task board’s master key when they had no need of it: one wrote it onto a command line (readable by any program on this machine while the call ran), and five loaded it to make a plain read that the board does not even ask a credential for. Task board (credentials on the read path) | Before: The daily 07:15 sweep put Authorization: Bearer <key> into the command line of every progress call. Five read-only callers - the Stop-gate board reader, the next-task picker, the salvage sweeper, the completion auditor and the deferred-triage reader - each fetched the key before a GET; two of them refused to work at all when it was missing, so a read failed for want of a credential nobody checks.After: The write path hands the key to the tool through its input channel, never the command line. The five read paths do not fetch it at all. The board’s own contract was measured rather than assumed: its authentication branch covers only POST, PATCH and DELETE, and a live GET of /api/nodes, /api/search and /api/node/<id> answers 200 with no credential, while a POST without one answers 401. | Red first, 8 failing cases matching each predicted exposure - including one nobody predicted: the completion auditor silently did nothing when no key was configured. After: 28/28 on the guard file and 700/700 across the fifteen suites that could touch these paths, re-run in a throwaway checkout rather than the shared one. Parent re-run of the receipt: commit 1/1, tests 6/6 suites, node 1/1. LANDED f55ef7ac7da; RUNNING once the shared checkout syncs - the parent’s own probe read the not-yet-synced copy and is the reason this row says landed, not running. A seventh site of the same class (bridge-output-gate.js, the board’s legacy header spelling) is being fixed by another live session right now: problem:harness.bridge-output-gate-x-taskman-auth-argv-leak.npx jest tools/scripts/curl-bearer-argv.guard.test.js | f55ef7ac7da |
| P0 SIDISO | A test planted a fake instruction in a live agent session: after a context compaction the agent was shown “fix the login bug in the admin panel” as the CEO’s own last words. Test isolation | Before: Tests inherited the running session’s id from the environment. Hooks keep per-session state under that id, so a suite that spawns the real hooks (prompt-refiner-vendor-reach.test.js) wrote its fixture prompt into this session’s restore file. Measured 23:28 UTC: the next context restore presented it as the user’s verbatim instruction. Nobody gave it; the agent did not act on it.After: jest.setup.js swaps any live session id for a test-only id before any test runs (an unset one stays unset); the key list is the canonical one, not a copy. The id carries the process id, so two test runs at once on this box never share per-session state either. | A/B: the old code wrote the fixture into the live session folder; the new code writes nothing there. The isolation test passes with the agent environment present and with every session key unset (the CI shape): 3/3. Landed 7e7252fff23 and 5a42cdcee60; jest reads the setup file at start, so every test run from a current checkout has it. RUNNING.npx jest tools/scripts/jest-setup.live-session-id-isolation.test.js | 7e7252fff23 5a42cdcee60 |
| P0 OPCT | Every cross-vendor review sent to OpenCode died with a bare “Transport” error, so that reviewer never gave a verdict and nobody could see why. Review bridges | Before: Each OPC review ran against the one shared opencode server; when that server died under load every run failed with opencode_server_error:Transport and no cause. The runtime copy the bridge runs from was also 119 commits behind master.After: Each run gets its own private opencode server (one shared launch helper, no second copy), and the journal records the real failure cause. Deployed to the bridge’s runtime at the landed commit and restarted when no task was in flight. | Red first; the sub-agent’s 4 suites re-run by the parent on master content: 52/52. Receipt re-checked: commit on master, all 3 deployed files carry the landed blobs, mpro-OPCBridge active (NRestarts 0 since 00:22 UTC), runtime HEAD 665589783238. A live run on the real opencode now returns the provider’s own answer - the plan quota is used up until 2026-09-20 17:07 (the money row above) - instead of a bare Transport. RUNNING.npx jest tools/eidos/opencode-verifier.transport-error.test.js tools/autonomous/lib/opencode-cli-isolation.test.js | 66558978323 |
| P0 CRASHQ | Crashes found by the systemd crash collector never reached the task board, so a restarting service was invisible there. Monitoring + alerting | Before: The collector (a 5-minute timer) logged each crash and exited the moment logging returned. The board write is fire-and-forget by design, so it died with the process. Measured 21:55 UTC: newCrashes=1 ids=mpro-ollamabridge.service in the journal, and nothing on that service’s board node since 2026-08-09. After the first fix went live, the first real crash (23:40 UTC) proved the wait worked and then lost the write anyway: the board answered slower than the bus’s 8 s default under load.After: The crash logger tracks its in-flight board writes and gives each its own 20 s budget; the collector waits for them (up to 45 s, inside its 2-minute unit limit) before it exits. Long-running callers still never wait. A real-socket test proves the budget reaches the connection, and the unit’s limit is read from the unit file, not typed. | Red first each time: 4 tests for the flush, 3 for the budget, 2 on a real socket (a mutant that misnames the option fails). Crash-logger, collector and bus suites 67/67. The collector runs from the taskman release, so it ships with the release: RUNNING since release 2fef80bc went live at 00:35 UTC, and proven by real crashes, not a test: the collector run at 00:45:15 UTC filed mpro-svc-runtime-refresh on the board at 00:45:16, and the 01:15:08 run filed mpro-blindspot-audit at 01:15:09 and added a repeat note to mpro-unit-install-drift at 01:15:10 (the second write) - all by the machine principal, with 0 dropped writes in the journal. The node that tracked the blind board (problem:obsbus.write-plane-rejected-runtime-identity-fleet-blind) is closed with that proof.journalctl -u mpro-systemd-crash-collector --since -15min -o cat | da9b454c9d4 f3dc028b0c6 5a42cdcee60 |
| P0 SECRETPAT | Three common API-key shapes passed the secret scanners, so such a key could be written into a file or a command. Tool guards | Before: The shared secret-pattern list had no Anthropic (sk-ant-), OpenAI project (sk-proj-) or GitHub fine-grained (github_pat_) shape.After: All three shapes are in the one shared list the hooks and scanners read; the live dispatcher blocks them. | Worker suites 739/739; live dispatcher probe with samples built at run time blocks all three. RUNNING (the shared root carries it; hooks read it on every call).npx jest .claude/hooks/pre_tool_use.credential-shape-parity.test.js | 9d28e10052a |
| P0 OBSID | Automated publishers and six bridges could not write to the task board: 1,753 writes refused since 2026-08-11. Monitoring + alerting | Before: The observation bus demanded a vendor identity that automated publishers do not have, and six bridges ran with no MPRO_AGENT_ID. Today alone the grok bridge had 76 structural rejections in 6 h and the claude bridge failed claims with identity_mismatch.After: A verified automated publisher writes as taskman_service (publishMachine). Each bridge gets its identity from a tracked drop-in; all six installed 20:54 UTC and loaded (DropInPaths). | Live: two probe nodes created by taskman_service at 20:06 and 20:15 UTC (one via publishMachine, one a plain publish from a real systemd context) - closed as probe artifacts. Restarts, each only when the bridge had no task in flight: kimi, ollama, qwen, antigravity 20:55 UTC; grok 21:43 UTC; claude 22:20 UTC. RUNNING.systemctl show mpro-grokbridge -p DropInPaths; journalctl -u mpro-grokbridge --since -1h -o cat | grep -c taskman_runtime_agent_required | 3f1638e9bad edd20ed19b3 |
| P0 C68M | A review of a merge commit could come back empty and still count as reviewed. Cross-model review (C68) | Before: git show renders a merge as a combined diff, which is empty for any file matching one parent - the normal clean merge (1,159 of the last 2,000 master commits are merges). The empty result was skipped, so the review pack held zero batches.After: One shared argument list ( -m --first-parent) for sizing, fetching and the printed re-check command; an empty single-commit result becomes its own unmeasured batch, never a silent skip. | 6 new tests on a real merge fixture, red first; 527/527 over 28 suites + 192/192 over 6 verifier suites; the orchestrator re-ran the 6 (C105). RUNNING (shared root).npx jest tools/eidos/done-status-review.merge-commit-hollow-review.test.js | 27e3f6c0b18 |
| P0 RMRF | Four back-up command lists blocked a root wipe only in its joined spelling, so a split, reversed or long-flag spelling passed them. Tool guards | Before: threat-patterns, the playbook executor, the execution tracker and the PreToolUse fallback each carried their own joined-only regex. The task’s own verify could never fail: after shell unescaping, grep read the backslash-s as whitespace and returned 0 while a copy still existed. After: All four build from the safety library’s one pattern; if even that library cannot load, the hook blocks any recursive rm aimed at the root, a glob or home. The verify is a fixed-string grep that returns 1 on the pre-fix file. | 49/49 (19 red first); 27 hook suites 352/352; the spawned hook approves a benign call and blocks joined and split wipes; integrity baseline re-recorded, 0 mismatches. RUNNING, all four copies: the shared checkout carries every commit (is-ancestor checked after the 22:51 UTC sync), and the hooks read it on every call.npx jest tools/eidos/rm-rf-copies-share-the-safety-lib.test.js | 647c4546c34 2e0f5e075e5 |
| P0 C68A | A cross-model review that could not fetch the code it was asked to review still returned an approval - across every reviewing vendor at once. Cross-model review (C68) | Before: All 7 verifiers (codex, claude, qwen, antigravity, opencode, kimi, grok) honoured the "could not fetch the hunks" abstain only when skipSmallDiff !== false, and done-status-review passes skipSmallDiff:false for every multi-batch package. Test with an unfetchable batch in that cell: 7 of 7 verifiers sent the envelope text to the vendor instead of abstaining. Reported on 2026-09-16, still in the code on 2026-09-18. After: The abstain is unconditional in all 7: a batch whose hunks could not be fetched is never reviewed and never approved. ollama needs no change (refused as not verification-capable before any size logic). The second hole on the same node - merge commits measured as empty diffs - is fixed too (row C68M). | New test.each over the 7 verifiers in the multi-batch cell: 7 failed before, 7 pass after. Hydrate suite plus the 13 verifier suites: 341 passed, 1 skipped (2026-09-18 19:53 UTC).npx jest tools/eidos/review-batch-hydrate.test.js | 7bfb6083e46 |
| P0 FIX-13 | A root-run service could be steered by an agent into overwriting or taking over any file on the box. Root services | Before: mpro-sudo-allowlist-audit (runs as root every 15 min) kept its state in /home/darius/MPRO/.tmp/mpro-security, a folder every agent can write, and wrote through symlinks plus a chown. A planted link turned a root write into a write anywhere.After: State lives in root-owned /var/lib/mpro-security (root:root 755). Writes refuse symlinks and hardlinks; the tick refuses to run (exit 2, which pages) if the folder is ever unsafe. The installed copy equals the committed bytes. | sudo-allowlist-audit.test.js 48/48 (22 written red first), 24/24 deliberate breakages caught; timer ticks 17:10:56 and 17:25:56 EEST Result=success; root-over-writable-code 28/28.stat -c "%U:%G %a" /var/lib/mpro-security; systemctl show -p Result mpro-sudo-allowlist-audit.service | 76994fe1da0 38af82a4e6c 5a155b6f693 |
| P0 FWB1 | Removing a finished lane could delete the only copy of files git ignores (queues, previews) instead of saving them first. Git broker | Before: The forced-removal residue step read git status -z (NUL-separated) as if it were newline text, so ignored folders were never seen and never quarantined. Real output ?? wip.txt\0!! .tp-view/\0!! postbox/\0 produced [].After: NUL records are parsed literally: the same output now yields [.tp-view/, postbox/], so they are quarantined before removal. | forced-removal-residue 25/25 + NUL-records 7/7, worktree-release dirt suite 34/34; the old guard test had been blind since 515db20010c because it matched one exact argv string.npx jest tools/scripts/lib/forced-removal-residue.nul-records.test.js | 0fffc59e74e |
| P0 FIX-9 | An agent session started inside a subfolder ran with no MPRO safety guards and none of the 16 "never do this" rules. Permission floor + tool guards | Before: Claude Code reads .claude/settings.json only from the folder a session starts in (docs, fetched 2026-09-18). A session started in tools/ loaded zero MPRO hooks and zero deny rules.After: The repo-root settings.local.json carries 7 guard-hook proxies and the 16 deny rules to every subfolder session. A force-push payload from a subfolder session is now blocked; a root session is unchanged (the proxy steps aside). | 27/27 tests, 23/23 mutations caught; live subfolder probe blocked, root probe exit 0.npx jest tools/scripts/install-subdir-guards.test.js | 3408f83638b f835a4b35f7 a89829cf4c5 |
| P0 FIX-1 | Dangerous commands slipped past the guard when written in a slightly different shape. Tool guards | Before: On master 9d85cb6dc85 the guard allowed 12 of 22 harmful Bash shapes in the probe below (force flag through a variable, commit -n, core.hooksPath, find -delete, python rmtree, pkill -f, killall, stopping an mpro service, crontab edits and wipes, branch delete via command).After: All 9 bypass families are refused: git verbs behind wrappers, sh -c and subshells; a force flag carried in a variable; commit -n / am -n; core.hooksPath; crontab replace or wipe; find -delete / rmtree on a protected root; pkill -f / killall (confirm, kill by pid instead); stopping an mpro unit (confirm; restart stays allowed). The AWS documentation example key is no longer flagged. 139 of 141 end-to-end probe payloads now get the expected verdict (was 62); the other 2 approve when probed from a lane. | Parent re-run on the deployed shared root (033e697c2cc), 2026-09-18 19:32 UTC: 237/237. Live hook probe of pre_tool_use.js on the shared root: 12 harmful command shapes approved in the morning probe now block, all 22 harmful shapes block, the harmless control still passes.npx jest tools/safety/lib/bash-guard-bypass-shapes.test.js | dfd30542702 b873aee3131 2f82427e346 |
| P0 FIX-2 | A password pasted as plain text into a file was saved without a word; git safety hooks could run stale for days; the fleet record said the wrong model did the work. Tool guards + commit hooks | Before: A credential written as prose through Write/Edit passed (the dedicated write guard was dead code). Git hook generation refreshed only on push. A runtime-resolved Authorization: 'Bearer '+cred was flagged as a leak (false alarm). Sub-agent stamps said claude-opus-5 x xhigh for runs that transcripts prove were claude-sonnet-5.After: Prose credentials are refused before they land; hooks regenerate at every commit; the false alarm is gone; the stamp reads the model the sub-agent actually runs, from its alias. | 7 test files 64/64 (parent re-run).npx jest .claude/hooks/safety/write-guard.test.js .claude/hooks/credential-proxy-guard.secret-shape.test.js .claude/hooks/dispatch-record.autostamp.test.js | b121a7b7c73 231274b9051 0091c6d71ce 1cbd7170821 |
| P0 FIX-3 | Service failures reached nobody, or reached the CEO for things that were not outages. Monitoring + alerting | Before: The fleet Google Chat path failed 22 of 22 times in 24 h (no token). 88 of 207 system mpro services had no failure alert. Vendor auth-health never paged on timeout or error. The alert handler's board writes were refused (no identity) and repeats were lost (it read the whole 20 MB board through an 8 MB cap). Three services whose description says "before OOM" were read as out-of-memory and paged the CEO. After: User and system unit failures reach ZEN or the board; 207 of 207 system services carry the alert; the handler writes as zen; dedup reads one node (13.9 KB); only failure evidence is classified; a sustained vendor outage pages; timeouts reach the alert path. Failed mpro units right now: 0. | 106/106 + 132/132 (parent re-run); mutants 11/11, 12/13, 8/8; a deliberate test failure created its board node in 10 s and a repeat became one "Recurred" note.systemctl list-units "mpro-*" --state=failed --no-legend | wc -l | fc9423f1f5b 37e3853f874 d091bfc89a2 4cee11c769d f70798f3b95 24fce9495ee 86029cd2efd 46001bc28c3 f285d1dbb93 542dca392e0 1b4ca5767cb e63274c70f5 |
| P0 FIX-7d | The final "am I really done?" gate could not stop a real safety problem, and could never say PASS either. Stop gate (Mastermind) | Before: Safety rows blocked only in a "trusted scope" (untrusted sessions: 335 of 335 UNSCORABLE). 44 rule texts said "-3 blocks" while 39 of those items were advisory. PASS was unreachable. 7 days of history: 16,263 runs, 0 PASS, 846 FAIL, 15,417 UNSCORABLE. After: The agent's own-speech safety rows are grounded and block; money_loss_risk_ungated sits in a new HARD_POLICY tier; environment debt is refunded instead of voiding the verdict; 36 sentences in 30 rule files now say "advisory (diagnostic -3, does not block)", pinned by a drift test. Replay of 1,156 real runs: UNSCORABLE 1,092 to 1,066, FAIL 64 to 65, clean release 0 to 25. | 171/171 (parent re-run); CLAUDE.md no longer claims "score>=10, fail-closed" (76/76).npx jest tools/eidos/two-tier-gate.hard-policy.test.js tools/eidos/two-tier-gate.environment-debt.test.js tools/eidos/rule-texts-minus3-block-claims.test.js | 8d40bf53b37 dd372b52829 cae88daf310 |
| P0 FIX-12 | Cleaning up a folder that a live service ran from killed the OpenCode reviewer for 36 hours. Self-healing / worktrees | Before: .wt/opcbridge-runtime was reaped 2026-09-16 23:07 while mpro-OPCBridge executed from it: 174 errors in 3 h, and no guard knew a systemd unit pinned that tree.After: Release and reaper refuse a tree a unit executes from, and the refusal names the unit; the drift check flags a unit whose pinned tree is gone; postbox data paths follow the data root, not the code tree. Runtime restored 10:33:45 EEST. | 70 + 80 + 29 (parent re-run); refusal text 62/62 (3 red first).node tools/scripts/lib/runtime-worktree-pins.js --check | bb411754308 7d6553545b3 a2071068dba 80bdbba6965 |
| P0 FIX-14 | The kimi agent refused every task it was given, so its whole queue failed. Task pickup (kimi) | Before: kimi had 72 failed and 0 completed tasks since 2026-09-17, and 134 "owned by undefined" refusals on 2026-09-18. A lock helper hung at start-up inside a unit at its 256-task limit and held the claims directory lock for 44 h; every later guard release timed out; claude-bridge handed tasks to kimi and never released its own claim. After: An agent releases its own guard in-process (no subprocess, no directory lock); the helper for other guards can no longer hang or inherit the lock; a hand-back always releases the claim; a dead owner's guard is reclaimed only on proof of death (boot id, or pid plus start ticks), and every refusal names a live holder. 414 provably dead guards were moved to a quarantine with a manifest; nothing was deleted. | Parent re-run on the deployed shared root (033e697c2cc), 2026-09-18 19:32 UTC: 3 suites 14/14. The kimi bridge runs the fixed code since its 18:52:21 UTC restart; its last refusals (13:45-13:59 UTC, before the fix) were all pickup_claimed_by_peer, and none since.npx jest tools/autonomous/file-lock.guard-leak.test.js tools/autonomous/lib/pickup-claim.handback-e2e.test.js tools/autonomous/lib/claim-lock-reaper.dead-guard.test.js | fccb997e009 96164a8d6e4 |
| P0 MEG | Agents working in their own copy of the code were blocked at Stop by a safety item for work they never claimed. Stop gate (Mastermind) | Before: The model-evaluation gate opened its state folder on every Stop and turned an unsafe folder into SAFETY -3 "model evaluation claim unproven". 66 of 81 working-copy .tmp folders tripped it (49 group-writable, 17 symlinks); 315 of 315 such rows in 38 gate histories had that cause.After: A symlinked .tmp is judged by where it points. An unsafe folder costs nothing on a turn that asks and claims nothing, and says which folder and why. A turn that does ask still fails, now with the exact command that fixes it. | Parent re-run on the deployed shared root (033e697c2cc), 2026-09-18 19:32 UTC: 2 suites 15/15.npx jest tools/eidos/model-evaluation-gate.unsafe-store.test.js tools/eidos/model-evaluation-gate.test.js | 162e71af967 |
| P0 FIX-5 | The task board's independent validator failed silently and reported "failed 0". Task board validator | Before: Profile sandbox: 17 failures in 65 minutes hidden behind "failed 0"; release-spelled nested node_modules were missing, so spawns failed.After: Runner and sandbox faults are counted and named; dependencies are linked, or the run is refused before it spawns. Landed 13:34 UTC; live in the validator from the release cut listed in the changelog. | 5 suites 59/59 (parent re-run).npx jest tools/mpro-taskman/lib/validation-profile-runner.dependency-containment.test.js | 05151e04342 a9faaf2fa85 0183e19614c |
| P1 PM2SEAM | The code that lists running services still spoke the vocabulary of a process manager retired on 2026-07-09. It shaped systemd facts into that old form, and in that form a scheduled job that ran and succeeded looks exactly like a crash - which is why a responder escalated to you every ten minutes for weeks, spawning a paid session each time. Self-healing (fleet vocabulary) | Before: The only export was getPm2List(), built from systemctl show "mpro-*.service" (92 units in, 92 entries out) but stamped into the retired shape, where any unit not active becomes stopped. Every new reader learned the wrong model from the name.After: A systemd-true getFleetList() is the primary export and getPm2List is a literal reference to it, so the two can never drift apart. The Hub’s status payload gained a fleet key beside the old pm2 one, computed once and assigned to both, so new readers stop learning the retired word. No behaviour changed and the 599 existing call sites were deliberately left alone. |
git show origin/master:.claude/agents/auto-debugger.md | grep -q state=failed | add82b9ada2 e274813a68a |
| P1 REDACT | The guard that hides secrets from agent output was eating whole lines of gate results. A real verdict printed during this audit, pass=true score=14/14 misses: 0, reached the agent as pass=[REDACTED] - the score and the miss count gone with it. An agent that cannot read its own quality verdict re-runs the gate, or misreads a failure as noise.Stop gate (readable verdicts) | Before: A bare pass or key counts as a secret name, and the value capture deliberately runs past spaces so that connection strings (password=x host=y) stay covered. Those two together glued short words into one long span until it cleared the 8-character floor that no single word in it cleared - the floor being defeated rather than applied.After: The capture may now only extend over material the floor would itself protect. Measured on the landed code: connection strings, API keys, URL credentials and environment dumps are still fully masked; the gate line above, and key=value count=3, now survive intact. |
npx jest tools/eidos/tool-output-secret-redaction.env-dump.test.js | 616ae8abf22 |
| P1 AGSILENT | When the tool agents use to save work refused a request, a machine-reading caller got zero bytes and an error code with no reason. An agent cannot fix what it cannot read, so it retries the same refused thing - and a test file in the repository specified a whole feature that was never built, so it sat red on master telling every reader a lie about how the tool works. Git broker (agent interface) | Before: 12 refusal paths returned without printing anything a program could parse. The test file imported a symbol that does not exist anywhere in the tool (the design it described was never adopted), and three of its four cases failed on master. After: One shared refusal path serves all 12 sites: the human-readable line is byte-identical, the exit code is unchanged, and a machine-reading caller now gets the reason. The test was rewritten, not deleted - its one genuinely real assertion was kept word for word, so no real coverage was lost, and the rest now pins the two primitives the tool actually has. |
git show origin/master:tools/scripts/agent-git.diagnostic-attribution.test.js | grep -q failureSurvivorPath | d638c55e8d0 |
| P1 C68DIFF | When one AI model reviews another’s work, it is sent the code that changed. For a merged change it was sent a list of file names with no code under them - and because that package was not empty, every emptiness check passed it. The reviewer approved a change it had never seen. Cross-vendor review | Before: The review package was built with a plain git show, which for a merge prints a summary and no content. Measured on a real two-parent merge: 230 bytes, naming the changed file, without a single line of it. On three real merges of this repository: 5,612 / 27,086 / 501 bytes.After: The package is built with an explicit first-parent strategy: the same three merges now carry 312,336 / 1,928,907 / 19,562 bytes of real code. The alternative (one full diff per parent) was measured and rejected - it doubles the payload against the size cap for no extra information. The flag does nothing on an ordinary commit, so there is one code path and no merge detection. |
git show origin/master:tools/eidos/done-status-review.js | grep -c diff-merges | e8fadb2605a 69f0fe5d5e8 6cf1a7c2e0e |
| P1 BHEALTH | The task board’s health page said “healthy” for three hours while the board process was pinned at a full CPU core with 1.4 GB in memory. A health check that cannot see the thing it is the health of pages nobody. Monitoring (task board) | Before: The answer described the database and the board’s data, and said nothing about the process itself. Worse, the limits everyone assumed were wrong: the service file says 768 MB and one core, but live overrides make it 4 GB and four cores - and the real ceiling is neither, it is the memory limit inside the language runtime (2,096 MB), which had already killed this service 7 times in 3 days while memory-only checks stayed silent. After: The answer carries the process’s own cpu, resident memory and runtime-heap use, each graded against limits read from the running process rather than typed from the service file. A degraded verdict names the number and the threshold that caused it. The word that other tools use to decide “is it up” is deliberately left alone, because two release gates treat any other value as down - hijacking it would break a release during the very load spike being reported. |
git show origin/master:tools/mpro-taskman/lib/board-health.js | grep -q HEAP_SATURATED_FRACTION | c4fc5590f16 984cd279992 |
| P1 WTREL | The git tool that lands an agent’s work produced working copies that its own clean-up could not remove, so copies piled up on disk. The only workaround was pushing already-landed work to a junk branch. Git broker (lane release) | Before: The standard landing step re-creates each commit on master under a new id. The release step then saw “commits not pushed anywhere” and refused, even though master held the same changes (it already knew that; it just did not use it for this refusal). Census at 02:07 UTC: 135 working copies, 46 with unpushed commits, 34 of them fully on master by content, 19 of those clean with no merges. Those 19 were stuck only because their commit ids had been rewritten. After: A copy whose unpushed commits are all on master by content, with no merge commit among them, can be released. A merge commit, an unreadable count, uncommitted files, a running process or any other refusal still blocks. Release removes only the working copy; the branch and its commits stay in the repository. | Red first (9 of 11 new tests failed); 127/127 worktree-release tests after; 10 of 10 deliberate breakages caught; 510/510 across the consumer suites. The parent re-ran the receipt on master content: commit 1/1, tests 4/4, probes 2/2. RUNNING: the tool runs from the shared checkout, which synced at 03:08 UTC. Two of this session’s lanes dry-ran as releasable, and one was released for real (ok:true, released:true). A test that was already red on master before this change is on its own node: problem:agentgit.worktree-release-refusal-claims-a-backup-ref-covers-uncaptured-dirt.npx jest tools/scripts/lib/worktree-release.patch-landed-unpushed.test.js | 13f87ea7ff1 |
| P1 RCPTSUITE | The tool that re-runs a sub-agent’s tests could not run a single test written the way the rules tell sub-agents to write it, so every receipt stayed unverified unless the parent fixed it by hand. Governance (sub-agent receipts, C105) | Before: The receipt rule’s own example lists a test as a plain file path. The verifier only ran a test given as a full command (npx jest …), so a spec-shaped receipt came back “UNKNOWN, not executed”. Every child receipt tonight had that shape. Measured on the deploy-rail receipt: 0 of 4 tests run before a hand rewrite, 4 of 4 after.After: A plain test path is run with the runner the file itself needs (read from the file): node --test for a node:test file, Jest otherwise. Anything that is not a clean path inside the repo is still refused: absolute paths, .., ./, non-test files and shell text. | 12 new cases, 4 red first; the verifier suite passes 75/75. Live: the same rail receipt, written with plain paths, now re-runs 4/4. Landed 9bd550beb4e; node closed with proof. RUNNING in every checkout that contains the commit.npx jest tools/eidos/subagent-receipt-verify.test.js -t "bare test path" | 9bd550beb4e |
| P1 RTKDIFF | An agent comparing two files with diff in its shell was always told they were identical. This audit nearly concluded that a drifted service file matched the committed one.Agent tooling | Before: The shell-output compressor rtk (0.36.0) quietly rewrites diff A B into rtk diff A B, and that command always exits 0. Two different files gave exit 0 in the agent shell, while /usr/bin/diff, cmp and a diff inside bash -c all gave 1. The other rewritten commands keep their exit codes (measured: grep, ls, cat, find, git diff).After: diff is excluded from rewriting through rtk’s own supported setting (~/.config/rtk/config.toml, [hooks] exclude_commands = ["diff"]); no hook was edited. The finding is recorded on the node where rtk also fakes tsc --version, together with the same lever. | After: different files exit 1 and identical files exit 0 in the agent shell; rtk rewrite "diff a b" returns nothing; ls and git are still rewritten and working. RUNNING for every Claude session on this box. To undo, delete that one line.test -z "$(rtk rewrite 'diff a b')" && echo "diff is not rewritten" | none |
| P1 FBLEAK | A crash-logger test could write fake crash records into the real crash fallback file, which the system doctor replays into the production crash log. Test isolation | Before: The test isolated itself with one root variable, but the code reads another one first - and the land gate sets that one. Measured 00:14 UTC with it pointing at a lane: 1 of 2 tests failed and the other appended a fake “concurrent-crash” to that checkout’s real tools/autonomous/.crash-log-fallback.json. Found because it had done exactly that in this audit’s own lane.After: Both root variables point at the test’s own temp folder for the life of each test (the collector’s sibling test drops the stronger one). The 6 other tests with the same shape were fixed as well, and a guard now fails any test that repeats it (ROOTPIN). | Production crash log checked: 0 fake rows (the same query returns 16 real rows for the Ollama bridge, so the read is live). After the fix: 3/3 with the variable set and unset, fallback file untouched. Landed 5a42cdcee60. RUNNING (applies at test time).MPRO_ROOT=$PWD npx jest tools/autonomous/crash-logger.runtime-root.test.js && git status --short -- tools/autonomous/ | 5a42cdcee60 |
| P1 LIVEISO | Test runs overwrote live safety records: the git broker’s per-session failure record and the Stop gate’s block evidence, which other tools read as real. Test isolation | Before: Two production defaults resolved the real folders even under Jest. A failing-hook test in agent-git.test.js rewrote this session’s own .tmp/agent-git-failure-<session>.json; Stop-gate suites that reached a real block wrote fixture BLOCK records (claude-s-, claude-s1-, kimi-ks-1-) into .tmp/mpro-mastermind, the folder the session reaper and the completion verdict read as evidence.After: Under Jest both defaults move to a temp folder unless a caller passes an explicit path; an explicit path still works. The Stop-gate guard checks the process environment as well as any env object a caller injects, because an injected object usually lacks the test marker. | Red first against the real files, with every write to them intercepted and swallowed; green after, live file checksums unchanged. Sub-agent receipt re-run by the parent on master content: agent-git 201/201; Stop-hook suites 100/100 including the injected-env case (red first: it targeted the live folder). Landed f3513953e15 and 2f50a526cdc. RUNNING (test-time).npx jest tools/scripts/agent-git.failure-survivor-test-isolation.test.js .claude/hooks/universal-stop.evidence-dir-test-isolation.test.js | f3513953e15 2f50a526cdc |
| P1 ROOTPIN | Six more tests isolated themselves with the weaker root variable; two of them broke - one crashed outright - whenever the stronger one pointed at a real checkout. Test isolation | Before: Two resolvers read the two root variables in opposite orders, so whether a test was safe depended on which resolver its subject happened to call. Measured per file with the stronger variable unset, set to an empty folder and set to a real checkout: 4 of 6 immune by luck; clean-checkout-profile-check.env.test.js failed 6 tests (empty folder) and crashed with 0 run (real checkout); server.premise-canonical-root.test.js failed under a real checkout.After: All six pin both variables. A static guard scans all 5,401 test files and fails any that sets the weaker variable without handling the stronger one, so the shape cannot come back unnoticed. | Red first: on master the guard flagged exactly these 6 files and no other (24 files touch the variable; 0 false positives). After: 6/6 guard tests. Parent re-ran on master content: 46/46 unset and 23/23 for the two broken files with the variable set to an empty folder; git status clean after every run. RUNNING (applies at test time).npx jest tools/scripts/test-root-pinning.guard.test.js | 3f591812316 |
| P1 RCPTV | The tool that re-checks a sub-agent’s claims called every correctly landed lane a mismatch - which teaches the parent to stop believing it. Governance (sub-agent receipts, C105) | Before: The git broker’s standard landing step gives each landed commit a new hash, and the verifier asked only “is the lane’s hash on master?”. So every lane landed the standard way read “landed=false but receipt says true”, and a lane already released read “outside the sanctioned worktree root”. All four receipts checked tonight failed this way while their content was on master. After: A lane counts as landed when every one of its commits has an equivalent change on master (git’s own patch comparison); one missing commit still fails it. A released lane is judged by its branch - but only inside the repository’s own lane folders and never a master branch, because a receipt is untrusted text. | Red first (3 of 5 new cases); 63/63 after. A/B on two real receipts: the old code said “outside the sanctioned worktree root” for both, the new code says landed (“cherry-landed: 1 commit patch-equivalent on origin/master”). Landed 9de740813ad; the verifier runs from the checkout that invokes it, so the running shared checkout has it after its next sync. RUNNING: the shared checkout has it since the 01:38 UTC sync, and run from there it reads the three released lanes of tonight’s workers as landed (two by patch equivalence, one as an ancestor).npx jest tools/eidos/subagent-receipt-verify.test.js | 9de740813ad |
| P1 PRPOL | The peer-review protocol kept asking the local Ollama model to review work - a model the rules forbid from giving verdicts - and each request stalled a bridge for up to 20 minutes. Review bridges | Before: The reviewer list was built from the type of the task under review, and Ollama was removed only when that type was itself a review type. Measured over 30 days: 45 review requests sent to Ollama, 0 completed; the protocol’s own 2-minute timeout had moved on each time, while the bridge stalled into its 1,200-second watchdog (five restarts on 2026-09-18). After: Every slot the protocol fills is a reviewer slot, so opinion-only vendors are removed whatever the reviewed task is. Reviewer order still comes from the one shared chain list; no second copy. | Red first: 6 of 11 reviewed types still offered Ollama; 79/79 across all protocol and chain suites after. Landed b8c83edecb0; in the shared checkout since the 01:38 UTC sync. RUNNING in all four bridges that load it from the shared checkout, each restarted only when its process group showed no task in flight: grok, kimi and qwen at 01:45 UTC, claude at 01:52 UTC after its running task ended (new process ids, all active).npx jest tools/autonomous/lib/PeerReviewProtocol.reviewer-chain-excludes-ollama.test.js | b8c83edecb0 |
| P1 OLLCPU | Every review sent to the local Ollama model stalled for 20 minutes and then restarted its bridge, killing whatever else the bridge had in flight. Review bridges | Before: The Hub reports mode cpu whenever a requested GPU placement is not yet re-proven (the proof goes stale on any unit restart). The bridge read that hint as an order, forced the 27-billion-parameter model onto the CPU, and every review ran until the 1,200-second watchdog restarted the bridge; the queue then retried the same task (one ran three times).After: Only an explicit CPU request forces CPU; an unproven GPU request keeps the normal GPU setting. Under a real CPU placement the bridge refuses the task at once, by name and without retry, instead of stalling. The voice-dictation model on the same GPU was measured before and left untouched. | Red first (11 of 18 failed for the right reasons), 18/18 after, 9 of 9 deliberate breakages caught; parent re-ran the sub-agent’s suites on master content: 21/21. Landed 483d10e4988. RUNNING since the service-runtime rail cut over (01:33:31 UTC): the bridge’s journal now reads [GPU-TOGGLE] placement gpu (gpu_requested_unverified...). Re-checked at 02:45 UTC, after the rail’s next refresh moved everything to slot d: the bridge (pid 720129) runs from .wt/svc-runtime-d, which contains the fix; 18/18 re-run; node closed with that proof.journalctl -u mpro-ollamabridge --since -1h -o cat | grep GPU-TOGGLE | 483d10e4988 |
| P1 AGYV | Every timed-out cross-model review left a whole agy process tree running forever, filling the grok bridge toward its process limit. Review bridges | Before: agy 1.2.6 waits forever by default and a quota-exhausted account retries silently. The review worker was killed on timeout, its agy tree was not: at 20:38 UTC two orphaned trees (154 + 7×7 threads, parent pid 1) had mpro-grokbridge at 992 of its 1024 tasks - one step from being unable to start anything.After: agy gets its own print timeout and runs under GNU timeout -k, which kills the WHOLE process group; a timed-out review reports agy_timeout instead of a generic failure. The bridge path was bounded the same way earlier (f3447bc82643) and mpro-antigravity / mpro-OPCBridge got a TasksMax cap (drop-ins installed 20:54 UTC). | Live group test: timeout -k 3s 10s agy -p … --print-timeout 60s → 17 processes in the group at 6 s (agy-real-bin 170 threads, 7 MCP servers), exit 124, 0 left after. 4 new tests red first; 109/109 over 5 suites. RUNNING, all three parts: the bridge fix and TasksMax caps since 20:54 UTC, and the verifier fix since the shared checkout synced at 22:51 UTC. That sync had been blocked for 2 h by one peer’s in-flight file; told directly, the peer parked its edit and landed properly. Meanwhile a bounded reaper removed only orphaned review trees (parent pid 1 + the verifier’s cwd + the review prompt): 8 reaped (6 under the grok bridge, 2 under antigravity); it saw the fix arrive and exited by itself after two clean sweeps (22:54 UTC). Measured 22:46 UTC: grok bridge 11 of 1024 tasks, no orphaned agy tree.git -C /home/darius/MPRO merge-base --is-ancestor 062694bf043 HEAD && echo live; systemctl show mpro-grokbridge -p TasksCurrent | f3447bc8264 062694bf043 |
| P1 TMREL | Validator fixes that were already on master were not running, so the board kept failing good work against a stale checkout. Task board validator | Before: The task board ran release 7725a18e from 2026-09-16; 9 taskman commits had landed since, including the stale-checkout abstain (93899d28569), runner-fault reporting and the janitor stamp fix.After: Release b08c0558 built and activated through the sanctioned sudo path (root-built, remote-proven, health-checked with automatic rollback); after the stale test below was fixed, release f3bf3e9d replaced it at 22:49 UTC. current points at it, the service runs from its tree, /api/health 200. | Before cutting it, the full taskman suite ran on master: 386 of 398 suites pass. The 12 failing suites (20 tests) fail identically on the OLD release’s code (A/B in a lane), so they are pre-existing, not introduced - tracked below. Release receipt: ok, unitVerified, serviceConfigurationVerified. First run after: 382 nodes abstained instead of being false-failed while the shared root is behind. RUNNING.readlink /opt/mpro/taskman/current; curl -s -o /dev/null -w "%{http_code}" localhost:3018/api/health | 93899d28569 |
| P1 TMTEST | For about 1.5 hours no fix to the task board could ship: every release refused, because master carried one stale test. Release pipeline | Before: Two tests pinned the same launcher line of the board-autonomy unit. grok’s e6dd1abb415 (21:12 UTC) changed the launcher and updated one copy; the other went stale. The release gate runs every taskman suite in a clean checkout and refused to ship a red master - correctly - so releases da9b454c and 5e284a4e failed closed and the crash-alert fix (CRASHQ) could not ship. After: The stale copy was re-synced (bddcd85c123) and then removed: the schedule test now owns only the scheduled command, and the launcher is pinned in exactly one place (303a3023e75). | Red proven first (1 failed, 3 passed); both suites 10/10 after. The new pattern matches the live unit and rejects 4 mutants (no --apply, another script, an extra flag, a missing ExecStart line). The release gate that refused is the harm-prevention working as designed; it kept serving the healthy release throughout. Re-cut at master f3bf3e9d: receipt ok, unitVerified, serviceConfigurationVerified; current → f3bf3e9d, /api/health 200, the service’s cwd is inside the release tree. RUNNING.npx jest tools/mpro-taskman/board-autonomy.schedule.test.js tools/eidos/oneshot-origin-blob.test.js | bddcd85c123 303a3023e75 |
| P1 LEANCTX | An agent reading a file outside its session root got the refusal text back as if it were the file, with a success code. Context tooling (lean-ctx) | Before: lean-ctx.REAL read /etc/hostname printed “path escapes project root … root: .wt/svc-runtime-b” as content, exit 0; grep and glob had no failure check; the vendored binary carried none of MPRO’s patches and the install script could build no version at all.After: Patch 0004 makes a jail refusal a failure; read, grep and glob fall back and return the real content or a real error. Install script re-pinned to v3.10.2 and rebuilt; binary md5 3d0d075a. | cargo 7/7, install tests 4/4; the orchestrator re-ran the read and grep probes (C105). RUNNING. Still open with addresses below: the daemon still binds a foreign root, and an untraced writer stripped earlier patches.md5sum /home/darius/MPRO/tools/vendor/lean-ctx/bin/lean-ctx.REAL | 9dcea01daa7 ffe5792d7f8 |
| P1 DRAIN | The new hourly debt drain would have failed, and paged, every hour while filing nothing - and said only “failed”. Monitoring + alerting | Before: First scheduled run 21:17 UTC: 6 of 9 groups refused with 409 DUPLICATE-SCOPE - the board naming the open node that already covers them. The bus treated that as a failure, and the drain printed no reason because it silences the bus log. After: A 409 that names its covering node lands the signal there as a progress note, as the refusal instructs; a real failure prints the HTTP status and the server’s reason; a successful dedup prints none. | 3 new tests (2 red first); bus + drain 52/52; all 8 suites importing the bus 101/101. Live apply from the landed code at 21:31 UTC: 7 of 7 pending groups drained, exit 0; task:harness.encode-debt-durability-drain closed. RUNNING: the hourly unit reads the shared checkout, which carries both commits since the 22:51 UTC sync.MPRO_AGENT_ID=claude_code node tools/eidos/encode-debt-drain.js | 6e8b2263840 28e9aec1bc0 |
| P1 KSTAMP | Two defects made proof untrustworthy: a red kimi Stop-relay test suite hid regressions, and helpers were stamped effort xhigh while the host ran them at max. Stop gate (Mastermind) | Before: The kimi relay suite was red since a shared Stop script joined; dispatch records took effort from a default, not from the host pin. After: The suite passes and pins the dual-scoped script; the stamp reads the host pin. | Orchestrator re-ran the claims (C105): both commits on master; 4 suites / 53 tests pass. RUNNING (shared root).npx jest .claude/hooks/dispatch-record.autostamp.test.js | 1b41a7d6112 a91a7f41ef5 |
| P1 CLA | A report that quotes another document was judged on the quoted document’s changelog, so its author was charged for history somebody else wrote on another day - and could not honestly clear it. Reporting gate (every vendor) | Before: findSectionIndex took the FIRST heading matching the changelog pattern. This report embeds SYSREF-001 whole, so the anchor landed on its “17. Changelog”: the embedded document’s rows (v6.2.1, v6.2.0, v6.1.0, v6.0.0) were charged as THIS report’s date-only stamps - -1 each and a FAILED check in blocking mode - and the stamp requirement was read from the wrong offset. The only way to clear them was to invent clock times nobody recorded, which is fabrication, not a fix. After: A SECTIONS entry may declare anchor:'last'; the changelog does. Grounded, not assumed: across 1608 docs/*.html, 666 carry a changelog heading and 23 carry more than one - in 22 of 22 the document’s OWN changelog is the LAST, the FIRST is foreign in 13, and the mirrored shape occurs 0 times. The dodge is pinned shut by a test: an empty trailing changelog heading moves the anchor to a region with no stamp after it, so the workaround FAILS the gate instead of passing it. | TDD, red first: 2 of 4 new tests failed before the change; 194/194 after (was 190). A/B over all 666 docs with a changelog, old anchor vs new: date-only stamps improved on 4 docs (mastermind 6→2, mpro-ecommerce/changelog 3→0, mpro-taskman/sysref 15→11, mpro-taskman-sysref 2→0), 0 docs worse, 0 stamp verdicts flipped in either direction. This report now returns ok:true, missing:[], dateOnlyStamps:[]. Third gate this session whose release vocabulary was narrower than its trigger vocabulary (C96). Signed evidence, not a self-report: the first pass of this row cited a plain jest run made inside the agent’s own claim channel, and the Stop gate refused it as replayed evidence bound to a stale commit. Re-run through tools/scripts/signed-test-runner.js, which records the real exit code outside that channel: exit=0 passed=278 failed=0, note attached to refs/notes/ci-evidence at HEAD 6d50d6f6ecb4.npx jest tools/eidos/doc-structure-order-check.test.js | bda4607b6fb |
| P1 AHP | The vendor liveness prober reported working and out-of-quota vendors alike as "timeout" all day, and was itself killed by its own time limit, so nobody learned that codex was out of quota. Monitoring | Before: Probes ran one after another at 45 s each. Over 24 h: 30 of 31 runs ended "Failed with result 'timeout'"; codex and antigravity never answered; claude answered only when given 180 s. Measured by hand at 240 s: claude OK after 180 s, codex "usage limit, try again Sep 19 12:43" after 120 s. After: Every vendor is probed at once with a 6-minute budget inside the same 7-minute round; a probe that throws is its own error row. 19:20 UTC run: exited cleanly in 6.0 min; claude ok, codex and kimi quota_depleted, opencode plan exhausted, qwen 403, antigravity no answer in 360 s, ollama queued behind a 56,160-token job. | Parent re-run on the deployed shared root (033e697c2cc), 2026-09-18 19:32 UTC: 5 suites 105/105; the 3 new tests were red on the old code. Unit result: "Deactivated successfully" at 19:00 and 19:26 UTC.npx jest tools/autonomous/agent-auth-health.paging.test.js | 033e697c2cc |
| P1 UAI | A failed backup filed nothing on the task board: the user-manager alert handler used by mpro-full-backup and mpro-full-backup-repo was refused by the task board. Monitoring + alerting | Before: Controlled failing user unit, 19:06 UTC: the handler decided "board" and logged "gated-alert: board write FAILED (identity_mismatch) POST /api/node"; no node existed. The runtime-identity fix of the morning reached only the system copy of the handler. After: The user copy carries the same principal as the system copy, from a tracked drop-in pinned equal by a test. Re-run at 19:20 UTC with a new failing unit: node problem:onfailure.auto-mpro-service-failed-verify-onfail-timeout-192026 created, no refusal; that test node was then closed with proof. | Wiring suite 11/11 (red without the drop-in). Installed file byte-equal to the tracked one; systemctl --user shows the drop-in loaded. The same test also proved the timeout fix live: the timed-out unit (Result=timeout, SIGTERM) now alerts, where before today it logged "clean-stop, no alert".npx jest tools/systemd/mpro-user-onfailure.wiring.test.js | 477ec85bd06 |
| P1 FIX-7a | A blocked Stop hid what blocked it; the deep background gate never actually ran; a review that timed out counted as passed. Stop gate (Mastermind) | Before: Block message led with a score, not the safety item; BG_LOCK_FILE/COVERAGE_CACHE were undefined so full-only checks never ran at Stop; cross-model review failed OPEN on deadline (claude fallback reviewer 0 of 1,184).After: A blocked Stop now leads with the one item that blocked it and says the score did not decide it. A review reserve is held back from the quick gate, so at kimi's 80 s grant all 3 reviewers ran (was 0 of 3). A Stop nobody reviewed says "UNREVIEWED" and carries verified:false. The background full gate is defined, runs one at a time per checkout, and its SAFETY rows reach the next Stop. | Parent re-run on the deployed shared root (033e697c2cc), 2026-09-18 19:32 UTC: 3 suites 56/56.npx jest .claude/hooks/mastermind-stop.review-reserve.test.js .claude/hooks/mastermind-stop.unreviewed-loud.test.js .claude/hooks/mastermind-stop.background-full-gate.test.js | 24761236ee1 430dfac7521 586434fd670 5cabcb61870 2cbd8d5d3b5 e89bccc7f07 82405b6dae3 5598d2c0f26 |
| P1 FIX-7b | Some Stops were approved silently: advice was discarded and a slow git probe skipped every gate. Stop gate (Mastermind) | Before: Approve-path advisories were dropped; a 2 s rev-parse timeout put a session out of scope and ran zero gates; approvals were not recorded.After: Mastermind's advisory now reaches the agent on an approved Stop (redacted, capped at 2 KB). Every Stop leaves one metadata row in .tmp/mpro-mastermind/stop-decisions.jsonl. A git probe that times out is UNKNOWN, not "not ours": it approves as UNSCORABLE and says so. A sub-session skip and /clear are recorded as what they are. Cost: about 5.6 ms per Stop. | Parent re-run on the deployed shared root (033e697c2cc), 2026-09-18 19:32 UTC: 3 suites 72/72.npx jest tools/eidos/project-scope.scope-verdict.test.js tools/eidos/universal-hook-executor.stop-advisory-ledger.test.js .claude/hooks/universal-stop.approve-ledger.test.js | 4131f04457e e1a18c914d3 f683c2d66ae |
| P1 FIX-7c | A check that crashed counted as a pass; improvement debt was never saved; the KB health check said "healthy" with 0 articles. Stop gate (Mastermind) | Before: Thrown checks scored as pass, unwatched; encode-debt not persisted; 7 dead checks (2,445 lines); kb_graph read a 401 as "healthy: 0 articles". After: A check that throws is recorded as "could not check" (UNSCORABLE, never PASS) in the verdict and its history. Encode debt is written to disk before the turn ends, and a drain turns it into board problems. The KB graph check authenticates and calls an empty or stale snapshot UNSCORABLE (live refresh: 4,992 articles). The model-registry staleness and constitution-marker checks now reach the gate as advisories. The dead-check census, which was blind inside every lane, sees lanes again. No process was added per gate run (186 to 186). | Parent re-run on the deployed shared root (033e697c2cc), 2026-09-18 19:32 UTC: 4 suites 69/69. Both jobs FIX-7c built now actually run: tracked user timers mpro-encode-debt-drain (hourly) and mpro-kb-graph-cache (daily 03:25 UTC), landed 8ec1787049b6, wiring test 7/7 (7 red before); installed 19:41 UTC; the snapshot job ran once: Result=success, 222,490 bytes.npx jest tools/eidos/check-throw-surface.test.js tools/eidos/encode-debt-ledger.test.js tools/eidos/kb-graph.unscorable.test.js tools/eidos/dead-check-census.test.js | 6fc49cf71eb a098c09b2e3 8ec1787049b |
| P1 ATTR | The test that makes every gate item carry an ownership decision was red on every checkout, so new items could land with no decision. Stop gate (Mastermind) | Before: gate-item-coverage-check LIVE failed with 8 undecided items: 4 already on master (e.g. grok_fleet_auth_provider, named_open_finding_then_stop) and 4 from this session's gate work.After: Each of the 8 is decided from its producing code: 2 blocking labels for an unusable verdict, 4 environment debt (never charged to the scored agent), 2 charged to the agent because they read only its own text or files. | Parent re-run on the deployed shared root (033e697c2cc), 2026-09-18 19:32 UTC: 2 suites 163/163.npx jest tools/eidos/gate-item-coverage-check.test.js tools/eidos/gate-item-attribution.test.js | e4c1c98f085 |
| P1 PCI | The nightly check of the validation profiles failed and told systemd it succeeded. Task board validator | Before: 04:35 EEST sweep: 180 profiles, 1 passed, 3 defects, 129 infrastructure profile-checkout-unavailable, 47 unscorable - exit 2, recorded Result=success by a 2026-09-01 SuccessExitStatus=2 drop-in. The failure text was dropped by the report and the journal copy was vacuumed, so the cause was unrecoverable.After: Drop-in removed ( SuccessExitStatus= empty); infrastructure rows carry the runner's error text; an uncaught crash exits 3, distinct from runner ill-health (2). | profile-ci-sweep + exit-codes 28/28 (3 red first).systemctl show -p SuccessExitStatus mpro-taskman-profile-ci.service | 4a5e4121518 |
| P1 FIX-15 | The OpenCode reviewer failed with a bare exit code, so nobody could see why. Review bridges | Before: 17 of 17 OpenCode tasks failed with "Exit code N" or "Transport" and no cause. After: Errors carry the child's own diagnostic and its HOME. Today's real cause, read from the unit journal: the OpenCode model plan is exhausted until 2026-09-20 17:07 (money row above). A wrong-HOME theory was refuted by measuring the running process (HOME=/home/darius). | 9 suites 51/51 (parent re-run).journalctl -u mpro-OPCBridge --since "1 hour ago" | grep -c "Limit Exhausted" | bcaaa71a093 |
| P1 FIX-4 | The disk cleaner quietly stopped cleaning. Self-healing / disk | Before: Scratch reaper: 0 reaps (its task-board census died on a reused keep-alive socket, and it fails closed); .tmp held 55,215 entries / 30 GB; the quarantine held 161k files and was never purged.After: The census survives the socket; quarantine buckets older than 14 days are purged daily (timer enabled); a duplicate user-level reaper was disabled. | installed units and script byte-identical to the lane.systemctl list-timers mpro-reaper-quarantine-purge.timer --no-pager | 0c80c7c2ff7 c84e184d362 |
| P1 FIX-6 | The rulebook contradicted itself and nobody could see which rules were missing. Governance | Before: C105 and C107 were cited but absent from the constitution; no check found missing articles; 19 "To wire" debts had no aggregate; a landing rule cited a test that does not exist; two memory systems had no documented split; the model registry was 2 days stale. After: C105 and C107 written; constitution-marker-coverage-check reports 0 missing; encode-debt-report aggregates the debts; the docs are corrected; all 8 vendors re-verified. | 142/142 + 11/11 (parent re-run).node tools/eidos/constitution-marker-coverage-check.js | 561bbd38e43 e9fa487f6ab 604f5caeb22 665735c3cd8 f1553021ad8 86525d0d822 9e0bfa0734c |
| P2 MCPCOLS | An agent asking the task board for two columns through its tool interface got the whole board back anyway - about 25 MB instead of half a megabyte - on every call. That is a standing tax on every agent on every vendor, paid in your token budget. Task board (agent interface) | Before: The board’s HTTP side had already been taught to project columns, but the tool wrapper declared no column parameter and dropped it when forwarding, so the narrowing silently never happened. After: The tool declares the parameter and forwards it through the same encoder every other passthrough argument already uses. No new column vocabulary was invented on the client side: the server still validates the names and refuses an unknown one with a clear error. |
npx jest tools/mpro-taskman/lib/mcp-tools.test.js -t "forwards fields" | e9038f33fd0 |
| P2 PRVFIX | The test that guards the money rule “never buy a video on an implausible still” only passed from an agent lane because of a leftover file. Every run also left a fake 8-byte “asset” behind; one compliance measurement counted it as real, and it blocks a lane from being released. Test isolation | Before: The test wrote its still next to itself, but the route reads stills from the shared checkout (the judge’s configured media root). Traced with strace from a lane: the shared checkout’s leftover copy was opened 9 times, the test’s own copy once (the write). Moving the fixture out of that path turned 6 of 11 tests red. The cleanup ran on process exit, which a Jest test file never sees: a probe test’s exit handler never fired.After: Each run gets its own temporary media root, handed to the judge through its own setting. The root is deleted when the file’s tests finish, under Jest and under node --test alike. | 11/11 under Jest and under node --test. strace: 12 of 12 still reads inside the temporary root, none in any checkout. Nothing is left behind, and two runs at once both pass. Landed bbde5268836; node closed with proof. RUNNING (test-time).npx jest tools/previd/routes-shots.plausibility-before-paid-video.regression.test.js && git status --short -- tools/generated-assets/ | bbde5268836 |
| P2 SYSREF | The system reference that every new agent and vendor is onboarded from did not describe how harm is actually prevented, and it was failing the very quality checker built to police it - unnoticed since August. Knowledge base (the durable reference) | Before: SYSREF-001 scored 8 of 14 on its own checker with six misses (too few tables, no last-verified date, no sources, no status block, no cause-and-effect section, no impact section). One miss was pure spelling: the article wrote **Status:** where the checker requires **Status**:. Its title carried a long dash, which makes a hostile filename on export. Four of its diagram sources did not validate at all.After: Updated in place - no second article (search-first): 4,572 → 7,263 words, 17 sections, and the seven-layer architecture with what enforces each layer, how it is invoked, what it refuses and where it is only advisory. Checker: 14 of 14, zero misses. Title is plain ASCII and carries its version. The four broken diagram sources were repaired and a new seven-layer diagram was rendered, served and looked at; every embedded asset answers 200. | Checker output on the body the service actually serves: pass: true, score 14/14, misses [], 11 diagrams, 10 tables, 0 shallow sections. Read it at http://localhost:3001/article/sysref-mastermind. The writer also corrected itself mid-flight (it claimed twelve refused command shapes and could only list eleven) and published the counted split - which is how the same overcount was found and fixed in this report, section 10.node tools/scripts/validate-mmd.js docs/mastermind/harm-prevention-layers.mmd | 1962ca6b38c |
| P2 RSHA | One rollback recipe in this report cited two git “blobs” that do not exist, so following it would have failed at the first command. This report | Before: A sweep of every hash-like token in the report data found two, 39c1ec33 and 38bab24b, labelled as master blobs; git cat-file knows neither. They were sha256 prefixes of the pre-fix files. The same sweep found 21 pre-land lane hashes in commit lists; the builder already maps those to the landed commit by subject at render time, so no reader ever saw them.After: The recipe now gives the real blobs ( c88bd0f68bf8, e490e5eda241), the command that restores them, and the sha256 prefixes labelled as such. The commit lists cite the landed hashes directly. | Re-sweep: 115 of 115 commit hashes are ancestors of origin/master; both blobs answer git cat-file -t = blob; the remaining tokens are a binary checksum and a drop-in checksum, each labelled as a checksum.git cat-file -t c88bd0f68bf8 && git cat-file -t e490e5eda241 | none |
| P2 TMPRET | Two state folders every agent writes to grew forever, costing disk and slowing every tool that scans them. Self-healing (retention) | Before: Nothing pruned .tmp/compact-restore (one folder per agent session: 14,990 folders, 209 MB, 10,161 older than 7 days) or .tmp/_backups (the critical-file guard’s pre-edit copies: 2,755 entries, 159 MB, oldest 2026-07-16). A test also left two restore folders behind per run. And the daily cleanup script ran a live database DELETE when merely loaded by a test.After: The existing daily cleanup job (no new timer) removes a session folder or a backup once its newest file is older than 30 days; test litter goes after 1 hour, so a running test is never raced. The test cleans up after itself. Loading the script no longer touches the database. | Red first each time; 19/19 across both cleanup suites, temp folders only. Parent re-ran the sub-agent’s receipt on master content: 18/18. RUNNING, applied by the daily unit itself at 01:42 UTC: removed 1552/15048 session dir(s) (210 → 190 MB) and removed 1711/2759 guard backup(s) (160 → 128 MB), 30-day window, unit “Deactivated successfully” in 2.4 s. Both nodes closed with that proof.npx jest tools/scripts/cleanup-session-tracker.compact-restore.test.js tools/scripts/cleanup-session-tracker.backups.test.js | 09a1d2d891b d67c4b12a43 |
| P2 CANON | The crash collector’s log said “fatal” about a failure nobody had - which teaches everyone who reads it to ignore fatal lines. Monitoring + alerting | Before: A shared helper that finds the repository asks git, and quietly falls back when there is none - by design inside an installed release, which has no .git. But it let git’s own “fatal: not a git repository” through to the log. Traced live on release f3bf3e9d: the task-board code loads it at start, so 7 of 70 collector runs in 6 h printed it, and with the flush fix (CRASHQ) every run would have. After: The probe keeps git’s message inside the error it already handles: same answer, same fallback, a silent log. | New test runs both functions in a child process from a folder with no repository: it first proves git really fails there, then requires the fallback answer with exit 0 and an empty error stream. Red first (2 failed: the fatal), 22/22 with the existing suite; a real worktree still resolves to /home/darius/MPRO; spec drift check exit 0. RUNNING since taskman release 2fef80bc went live at 00:35 UTC: 7 collector runs from then to 01:10 UTC printed 0 fatal lines, against 27 in the 6 hours before.npx jest tools/eidos/canonical-root.quiet-probe.test.js | 91e6f256cc6 |
| P2 RCPT | Helper agents’ completion receipts could not be machine-checked, so their claims had to be re-verified by hand. Governance | Before: The always-loaded rule listed the receipt fields but not the format, while the parser is JSON.parse. Two of this audit’s helpers wrote key: value receipts and the verifier refused both as malformed.After: The rule says: one JSON object, not YAML, with the three array shapes the validator enforces. | Governance, context-budget and receipt suites 102/102. Both refused receipts were re-verified by hand meanwhile (3 commits on master, 53/53). RUNNING: the rule is in the shared checkout since the 22:51 UTC sync, so every new session loads it.node tools/eidos/subagent-receipt-verify.js --help | f15d848ed10 |
| P2 AHMODEL | The antigravity liveness probe asked for a model name that is only a screen label, not the model the bridge runs. Monitoring | Before: --model "Claude Sonnet 4.6 (Thinking)".After: The probe resolves the model exactly as the bridge does: bridgeDefaultModel(antigravity) - today gemini-3.8-flash-high from the model registry. | 1 new test red first; 6 auth-health suites 107/107. RUNNING: the prober is a timer reading the shared checkout, which carries 229f51e47028 since 22:51 UTC (display label: 0 occurrences there). Its node is closed. The probe now asks the right model - and gets the account’s real answer, the quota refusal in the money row.npx jest tools/autonomous/agent-auth-health.test.js | 229f51e4702 |
| P2 A14 | The Claude Stop gate never reported a vendor running a different MCP tool version; only the quick gate did. Stop gate (Mastermind) | Before: mcp_pin_drift (report-only) sat inline in the quick path. The other half of this finding - self-started servers - was already on both paths under another name.After: One helper, mcpPinDriftItem, called by both paths; spec v4.225.0. | The reach test spies the seam through both paths: full mode red first, 6/6 after; spec drift check exit 0. The commit gate runs every suite that imports the gate scorer - it needed about 53 min (last heartbeat 3,135 s), and the first attempt died at the default 30-min budget; the documented --git-timeout-ms knob let it finish rather than skipping it. RUNNING: the shared checkout fast-forwarded to 30a8b5decbe at 23:33 UTC, and the Stop gate reads the scorer from it (mcpPinDriftItem: 3 references there).npx jest tools/eidos/gate-runtime-reach.test.js | 30a8b5decbe |
| P2 SCHED | A muted scheduler job could not be un-muted without restarting the whole scheduler, so a fixed job stayed silent for up to a day. Self-healing (scheduler) | Before: state.json was read once at start and rewritten from memory on every job start and finish; an operator lift was overwritten within minutes. mpro-audit-quick stayed muted until 2026-09-19 06:04 EEST although its cause had landed. After: Every tick applies a lift written to state.json by someone else (read only when the file is newer than the scheduler's own last write); it never re-mutes, extends, or touches the running or last-run fields, and it logs each lift. | 5 new tests (lift applied, extension ignored, lift with failures ignored, own write never read back, tick applies the lift): 5 red before, scheduler suite 84/84 after. RUNNING: the scheduler (up since 2026-09-14 on the old code) was restarted at a moment it had no job in flight, 2026-09-18 21:21:36 UTC; 19 jobs registered, no error since.npx jest tools/scheduler/scheduler.test.js | 44266b1b756 |
| P2 PPH | A harmless template placeholder was read as a leaked password and blocked the whole harness landing, without naming the file. Commit / push gates | Before: Pre-push refused 32 commits with "1 potential credential exposures found" because ROOT_TOKEN = '{{MPRO_MAIN_ROOT}}' matched the token pattern.After: Renamed to ROOT_PLACEHOLDER; the harness lane pushed. | Parent re-run on the deployed shared root (033e697c2cc), 2026-09-18 19:32 UTC: 27/27.npx jest tools/scripts/install-subdir-guards.test.js | 79deed326 |
| P2 FWB14 | Agent onboarding pointed at a file that has never existed. Governance | Before: agent-onboarding.md said wrapping tools/paperclip-server.js does not change live :3043; that path has 0 commits in any branch.After: It names the real Windows-era wrapper tools/paperclip-data/paperclip-server-wrapper.js and the process the :3043 listener actually runs. | grep on the deployed shared root: 1 line, and it now says editing the wrapper does not change live :3043 and names the real listener path.grep -c paperclip-server-wrapper .agents/skills/mpro-agent-orchestration/references/agent-onboarding.md | b8764bf06e7 |
| P2 FIX-8 | An agent could believe it had read a file that only its helper read, and every hook ran twice. Context tooling (lean-ctx) | Before: Read-dedup credited a sub-agent's reads to the parent; lean-ctx hooks ran twice (~118 ms per firing); the shell rewrite was jailed to another session's folder. After: Dedup is keyed per agent and epoch; the wrapper steps aside when the project layer owns the hook; the heal enforces read_dedup=off and the allow-path, and a failed heal is a WARN line, never silence. | 58/58 + 203/203 (parent re-run).npx jest tools/eidos/read-dedup-scope.test.js | e374aad78f6 4345c100690 a19ec369a9d 09e36b3b79f 00098498c3e c8c3b23ce2f |
| P2 FIX-10 | Rules promised checks that did not exist, so agents trusted protection that was not there. Governance | Before: 21 enforcement modules named in rule texts did not exist. After: Rule texts name only real enforcement; 7 still-unbuilt checks are labelled as such and tracked (task:governance.phantom-enforcement-modules). | 17/17 (parent re-run).npx jest tools/eidos/governance-theater-check.test.js | c73a287a64b a77c8368341 |
| P2 HDC | The duplicate-hook detector raised false alarms, teaching people to ignore it. Hook hygiene | Before: It counted settings entries, not runs: 10 / 10 / 3 "duplicates" that the host actually runs once. After: It counts what the host runs (the same handler in two settings files runs once; the wrapper yield is asked of projectLayerOwnsHook): 0 / 0 / 0. | 93/93, 5/5 mutants.node tools/eidos/hook-duplicate-check.js --json | a9432f7d2ba |
| P2 DRIFT | A red test on the unit-drift monitor had hidden new regressions for nine days. Monitoring | Before: unit-install-drift integration suite red on master since 96f2c715714 (2026-09-09); bisected: exit 0 at 9231554ff68, exit 1 after. After: The test now proves both halves through the real CLI: a measured ordering prefix resolves, an unmeasured one stays "not installed". | 141/141 (was 1 failed).npx jest tools/eidos/unit-install-drift-check.integration.test.js | c5d10a17f97 |
| Layer | What it stops | How (the tool) | Strength today |
|---|---|---|---|
| 0 · Values & rules | dishonesty, harm, waste — as intentions | 191 rules, constitution (69 articles), onboarding for every vendor | Guides only. A sentence cannot stop anything; that is why layers 1-6 exist. FIX-6/FIX-10 made the rules stop claiming checks that did not exist. |
| 1 · Permission floor | 16 command shapes no agent may run (force push, --no-verify, forced lane removal…) | .claude/settings.json deny rules | Holds for root and, since FIX-9, subfolder sessions. By design it cannot match a program called by path or inside sh -c; layer 2 covers those. |
| 2 · Tool guards | destructive commands, secret leaks, protected-file edits, pattern kills | .claude/hooks/pre_tool_use.js + tools/safety | Stronger after FIX-1/FIX-2; still text-pattern based (see §10). |
| 3 · Git broker + commit hooks | peer sweeps, lost commits, unscanned pushes, deleting the only copy | tools/scripts/agent-git.js, pre-commit (secret scan, ASCII, NUL, related tests, integrity) | Holds; FWB1 and FIX-12 closed two data-loss paths. |
| 4 · Stop gate | “done” without proof, false claims, unsafe money actions | tools/eidos/mastermind-ask.js + two-tier terminal policy | Partly: grounded SAFETY and HARD_POLICY rows block; most rows advise. |
| 5 · Task board | work claimed done that is not | taskman :3018 claims, leases, independent validator, nightly profile CI | Partly: most done work is not yet independently validated (§7). |
| 6 · Monitors & self-healing | silent outages, disk exhaustion, crashed services | systemd OnFailure → mpro-alert@ → ZEN/board; reapers; guards; drift checks | Holds for every system mpro unit since FIX-3. |
The gate (tools/eidos/mastermind-ask.js) runs its registered checks over what the agent said and did this session. 311 *-check.js modules exist in tools/eidos/. Since FIX-7d the outcome is decided by one terminal policy with four kinds of row:
| Row kind | Blocks? | Examples | Why it is built this way |
|---|---|---|---|
| SAFETY | Yes | destructive op + unproven claim; a secret in the transcript; a grounded harm the agent itself described | only rows grounded in the agent’s own speech or actions may block, so a quote of someone else never stops work |
| HARD_POLICY | Yes | money_loss_risk_ungated | a money-touching change without its triple review is never merely advice |
| QUALITY | No — advises (diagnostic -3) | proof style, report structure, stamps, six-dimension check | measured too imprecise to block today; promotion waits on measured precision |
| UNSCORABLE | No — releases | the gate timed out or could not read its input | a gate that cannot see must not pretend to judge (C96) |
History, not current: HISTORY · 2026-09-11..18 — not current. In the 7 days before the fix the gate ran 16,263 times: 0 PASS, 846 FAIL, 15,417 UNSCORABLE. A replay of 1,156 of those runs through the fixed policy gives UNSCORABLE 1,066, FAIL 65, clean release 25.
Each row is a payload fed to .claude/hooks/pre_tool_use.js, the guard every Bash, Write and Edit passes through. The guard only inspects the payload; nothing was executed. Same probe (orchestrator/guard-probe.js), same machine, before and after landing. The permission floor (16 deny rules) sits in front of this and catches some shapes on its own; this table measures the guard alone.
| What the agent tried | Exact input (inspected only, never run) | Before (master 9d85cb6dc85) | After (master 033e697c2cc) |
|---|---|---|---|
| force push (plain) | git push --force origin master | BLOCKED | BLOCKED |
| force push inside sh -c | sh -c 'git push --force origin master' | BLOCKED | BLOCKED |
| force push by absolute path | /usr/bin/git push --force origin master | BLOCKED | BLOCKED |
| force push via env | env git push --force origin master | BLOCKED | BLOCKED |
| branch delete via command builtin | command git branch -D some-branch | ALLOWED | BLOCKED |
| force push via sudo | sudo git push --force origin master | BLOCKED | BLOCKED |
| force push with VAR= prefix | GIT_TRACE=0 git push --force origin master | BLOCKED | BLOCKED |
| force push in a subshell | (git push --force origin master) | BLOCKED | BLOCKED |
| force push on a second line | echo hi ⏎ git push --force origin master | BLOCKED | BLOCKED |
| force flag through a variable | x=--force; git push $x origin master | ALLOWED | BLOCKED |
| skip hooks (long flag) | git commit --no-verify -m x | BLOCKED | BLOCKED |
| skip hooks (short -n) | git commit -n -m x | ALLOWED | BLOCKED |
| skip hooks via core.hooksPath | git -c core.hooksPath=/dev/null commit -m x | ALLOWED | BLOCKED |
| forced worktree removal | git worktree remove -f /tmp/some-lane | BLOCKED | BLOCKED |
| repo wipe inside sh -c | sh -c 'rm -rf /home/darius/MPRO' | BLOCKED | BLOCKED |
| repo wipe via find -delete | find /home/darius/MPRO -delete | ALLOWED | BLOCKED |
| repo wipe via python rmtree | python3 -c "import shutil; shutil.rmtree('/home/darius/MPRO')" | ALLOWED | BLOCKED |
| pattern kill (pkill -f) | pkill -f node | ALLOWED | BLOCKED |
| pattern kill (killall) | killall node | ALLOWED | BLOCKED |
| stop a live MPRO service | systemctl stop mpro-MPRO-Hub.service | ALLOWED | BLOCKED |
| wipe the crontab inside sh -c | sh -c 'crontab -r' | ALLOWED | BLOCKED |
| edit the crontab | crontab -e | ALLOWED | BLOCKED |
| control: harmless command | echo ok | ALLOWED | ALLOWED |
| credential pasted as prose into a Write | notes.md: "the token is <fake ghp_ shape>" | ALLOWED | ALLOWED |
Read the last row with care: this probe calls pre_tool_use.js alone, and that file does not read the CONTENT of a Write. Content is checked by a separate hook in the live chain (the credential proxy guard), which this probe never calls. So “allowed” there says nothing about whether a real Write of a key is stopped; it is not counted as a hole in this report, and not as a pass either.
| Guard | What it prevents | State today |
|---|---|---|
| Lane per task + scope gate | one agent sweeping another’s files into its commit | Holds; the touch ledger can still evict an entry before the commit (open row, node listed on top if unfixed) |
| Pre-commit: secret scan, ASCII (C62), raw NUL, related tests (TDD gate), integrity of protected files | secrets, invisible bytes, untested or tampered guard code reaching git | Holds; the git hooks now regenerate at every commit (FIX-2) |
| Push lock + fast-forward-only merge queue | two agents racing the same branch; history rewrites | Holds; force push is a deny rule |
| Forced-removal quarantine | deleting ignored files when a lane is removed | Fixed (FWB1) |
| Service-pinned trees | removing a folder a live service runs from | Fixed (FIX-12) |
Live from node tools/eidos/vendor-gate-sync-check.js --json. “Proof the Stop ran” = whether the harness can show the gate executed, not only that it is configured.
| Vendor | Tier | Shared gates | Quality gate | Session fence | Proof the Stop ran |
|---|---|---|---|---|---|
| antigravity | event-routed-partial | hard-block | hard-block | advisory | absent |
| claude | canonical | hard-block | hard-block | advisory | present |
| codex | event-routed | hard-block | hard-block | advisory | present |
| grok | event-routed | hard-block | hard-block | advisory | present |
| kimi | event-routed | hard-block | hard-block | advisory | present |
| max | bot-postbox | absent | advisory | absent | absent |
| ollama | shim-advisory | absent | advisory | absent | absent |
| opencode | plugin-partial | advisory | hard-block | advisory | present |
| qwen | event-routed-partial | hard-block | hard-block | advisory | present |
| zen | bot-postbox | absent | advisory | absent | absent |
A service fails +--> Task-board node
crash, timeout or exit != 0 | agents pick it up
| |
v |
systemd OnFailure |
on every system mpro unit |
| |
v |
mpro-alert@ --------------------------------------+
reads only the failure evidence |
+--> CEO page (ZEN)
real outages only
|
v
Fix lands, then the validator re-runs the proof
done by the agent is not enough: a separate check confirms it
Failed mpro units at build time: 1| Monitor | What it watches | What happens when it fires | Changed in this audit |
|---|---|---|---|
systemd OnFailure → mpro-alert@ | every mpro unit | classifies the failure: board node for agents, CEO page only for a real outage | FIX-3: 207/207 system units, identity, one-node dedup, evidence-only classifier |
| agent-auth-health (every 10 min) | each vendor CLI logged in and answering | pages a sustained outage | FIX-3; live today: 2 of 8 vendors answer (money row) |
| Syndicate + hang check (2 min) | ports, unregistered listeners, hangs | ZEN alert | its board writes are refused for lack of a runtime identity: problem:obsbus.write-plane-rejected-runtime-identity-fleet-blind |
| mem-guard, memory-sentinel, fork-bomb guard | memory pressure, fork storms | kill the offender and alert | no longer mistaken for OOM events by their own names (FIX-3) |
| Reapers + quarantine purge | disk: .tmp, old worktrees, scratch | clean, quarantine, purge after 14 days | FIX-4 |
| Runtime worktree pins | trees a service executes from | refuse release or reaping | FIX-12 |
| Unit-install drift check | installed units equal the repo | drift report | its red test fixed (DRIFT); pinned-tree drift added (FIX-12) |
| Task-board validator + nightly profile CI | done nodes and their validation profiles | reopen a node; fail the nightly unit | FIX-5; PCI (the mask is gone) |
| Model registry refresh (07:40) | vendor model and effort drift | report | all 8 vendors re-verified (FIX-6) |
| Root sudo-allowlist audit (15 min) | every sudo call against the allowlist | page on a miss | FIX-13 (state out of agents’ reach) |
Failed mpro units at build time: 1 — mpro-unit-install-drift.service. The failure chain opens a node for each one automatically; look it up by unit name on the task board. The scratch folder .tmp holds 62740 entries at build time, against 55,215 when this audit started — that count is not the thing FIX-4 repaired, and it keeps rising because every session leaves a few small state files there. What FIX-4 repaired is measured by size and by the quarantine: the folder fell from 30 GB to 21G, and the quarantine that held 161,000 files now holds 1 (its purge ran at 05:22 EEST today and reported success). A count of small files is a poor disk measure; the size and the quarantine are the real ones.
| What | Count | How it was counted |
|---|---|---|
Rules always loaded (.claude/rules/*.md) | 191 | ls .claude/rules/*.md | wc -l |
| Skills | 172 | ls -d .claude/skills/*/ | wc -l |
| Agent definitions | 102 | ls .claude/agents/*.md | wc -l |
| Constitution articles | 69 | grep -cE '^## C[0-9]+' docs/constitution.md (C105 and C107 added in this audit) |
| Task-board nodes done (live board + archive) | 3389 | GET :3018/api/nodes?status=done&include_archived=1 |
| … of which independently validated | 1065 (31.4%) | &validated=true&include_archived=1 |
Read the last two rows together: “done” is the agent’s own word; “validated” means a separate process re-ran the proof. The gap is the share of finished work nobody independently re-checked yet — the profile-CI fix above is the first step toward shrinking it.
| Risk (OWASP ASI) | In plain words | What MPRO has | Holds? | Changed in this audit |
|---|---|---|---|---|
| ASI01 Agent goal hijack | hostile text in a page or file redirects an agent | inbound content gate (hash, never raw), “governance content never auto-applied” | Weak: text rules, no runtime isolation of tool output | — |
| ASI02 Tool misuse | a tool used to do damage | deny floor + Bash/Write guards + broker | Holds | FIX-1, FIX-2, FIX-9 |
| ASI03 Identity & privilege abuse | an agent acting with more rights than its job | derived per-agent taskman credentials; root audit; credential guards | Weak: all agents share one OS user | FIX-13, FIX-2 |
| ASI04 Supply chain | a poisoned package, plugin or skill | skill source policy, binary-platform checks, npm audit | Weak: no signature checks | — |
| ASI05 Unexpected code execution | code running where or as whom it should not | root units never run agent-writable code (ratchet test) | Holds | FIX-13 + ratchet row |
| ASI06 Memory & context poisoning | false “memories” steering later work | memory rules, read-dedup scoping | Weak | FIX-8 |
| ASI07 Insecure inter-agent messages | forged or replayed tasks between agents | signed postbox tasks with nonce replay limits; identity-bound task board | Holds | — |
| ASI08 Cascading failures | one failure silently breaking many | OnFailure alerts, crash tiers, reapers, pinned trees | Holds (log vacuum weakens forensics) | FIX-3, FIX-4, FIX-12, PCI |
| ASI09 Human-agent trust exploitation | an agent saying “done” when it is not | Stop gate, receipts re-run by the parent (C105), independent validator | Partly | FIX-7a-d, FIX-5 |
| ASI10 Rogue agents | an agent acting outside its task | kill by identity, leases, stale-claim sweep, monitors | Weak: same-OS-user agents can signal each other | FIX-1 (pattern kills refused) |
| Boundary | Holds? | Detail |
|---|---|---|
| person ↔ person | HOLDS | the CEO is the only human principal on this VM; the pool account is not treated as a person |
| identity ↔ its own guards | WEAK | agents run as the same OS user that owns the guard files; changes are detected (integrity baseline), not prevented |
| session ↔ session | WEAK | one shared checkout and one .tmp for every session; lanes isolate code, not state |
| process ↔ process | WEAK | same uid; kill-by-identity is a rule plus a guard, not a kernel boundary |
| agent ↔ internet | OPEN | no egress filter; the inbound content gate is text-level |
| agent ↔ colleagues’ work | HOLDS | lanes, scope gate, peer-dirty refusals; lost-copy paths closed (FWB1, FIX-12) |
| root ↔ agents | HOLDS | no root unit runs agent-writable code (ratchet test 28/28 after FIX-13) |
darius with permission prompts off, so nothing at the kernel stops one session from editing another’s files or the guards themselves. The integrity baseline detects a changed guard; it does not prevent the change.| Not covered | Why not | What that means for you |
|---|---|---|
| The public production servers and the shops’ money paths | out of this audit’s scope | money-touching changes still rely on the triple-review rule, not on this audit |
| Inside the vendor CLIs (codex, grok, kimi, qwen, OpenCode, Antigravity) | closed or remote code | we measure what they return, not how they decide |
| OS hardening (AppArmor, SELinux, network egress) | not configured, not audited | the kernel-level boundaries in §9 are marked WEAK/OPEN for this reason |
| Each of the 16,263 historical gate runs | classified by verdict, not re-scored one by one | the replay covers 1,156 runs; the rest is a count |
| Sev | Finding | Evidence | Status |
|---|---|---|---|
| P0 | Forced lane removal read NUL records as lines and deleted ignored folders | real git status -z output; test C blind since 515db20010c | Fixed (FWB1 row) |
| P0 | Root audit wrote through agent-planted symlinks | FIX-13 red-first tests | Fixed (FIX-13) |
| P0 | Secret patterns miss Anthropic, OpenAI project and GitHub fine-grained key shapes | problem:safety.secret-content-patterns-miss-anthropic-openai-project-and-github-fine-grained-keys | Fixed (SECRETPAT) |
| P0 | The crash collector exits before its task-board write finishes, so every crash it finds is dropped | journal 21:55 UTC newCrashes=1; the service node’s changelog silent since 2026-08-09 | Fixed (CRASHQ) |
| P1 | Orphaned agy review trees filled the grok bridge to 992 of 1024 tasks | two trees with parent pid 1 at 20:38 UTC; then one every ~6 min | Fixed (AGYV) |
| P1 | Taskman fixes on master were not running: the task board ran a 2-day-old release | live release 7725a18e vs 9 taskman commits since | Fixed (TMREL) |
| P1 | The new hourly debt drain read a 409 duplicate as a failure and printed no reason | first scheduled run 21:17 UTC: 6 of 9 groups | Fixed (DRAIN) |
| P1 | The shared checkout stayed behind master for hours because two live sessions edited files there that master also changed | reconcile_conflict from 20:50 UTC | task:git.shared-root-track-master-rescue-snapshot-and-park-after-quiet |
| P2 | A task’s own verify could never fail (after shell unescaping, grep read the backslash-s as whitespace) | returned 0 while a literal copy existed | Fixed (RMRF) |
| P2 | The receipt rule never said JSON, so helpers’ receipts could not be machine-checked | two receipts refused as malformed | Fixed (RCPT) |
| P2 | The MCP pin-drift advisory ran only in the quick gate, never in the Claude Stop gate | reach test red on the full path | Fixed (A14) |
| P1 | Nightly profile CI failed and reported success; failure text dropped | unit ExecMainStatus=2, Result=success; 129/180 infrastructure | Fixed (PCI) |
| P1 | OpenCode bridge keeps taking tasks while its plan is exhausted | journal 14:43-14:54 UTC, same task retried | task:opencode-bridge-has-no-quota-refusal-gua-2hz0xb |
| P1 | Touch ledger evicts entries in minutes, so the scope gate refuses the agent’s own files | ledger pinned at 2000 rows across ~986 sessions | problem:agentgit.touch-ledger-evicts-within-minutes-under-fleet-churn |
| P1 | Validator judges nodes against the shared root before their lane lands | false failed-validation records this session | Fixed and running (TMREL) |
| P1 | Sub-agent effort stamped xhigh while the host pin runs max | problem:harness.subagent-effort-stamp-says-xhigh-while-the-host-pin-runs-max | Fixed (KSTAMP) |
| P1 | kimi stop-relay suite red since a shared Stop script joined | problem:kimi-hooks.stop-relay-suite-red-since-auto-open-html-joined-shared-stop | Fixed (KSTAMP) |
| P2 | Guard false positives (commit prose read as a command; a grep pattern read as a credential) | problem:harness.guard-false-positives-teach-obfuscation | open, see the top table |
| P2 | A drift-test regression hid for nine days | bisected to 96f2c715714 | Fixed (DRIFT) |
| P2 | The session’s own wrong claim: “OpenCode bridge running cleanly” | 17/17 failures measured after the restore | Corrected (FIX-15 row, this changelog) |
| Row | Old item | Verdict now | Why / where |
|---|---|---|---|
| 1 | Message Batches API (50% off) | Idea — not harm prevention | cost roadmap; not in this audit’s scope |
| 2 | Trim the loaded tool count | Done | deferred tool loading is live: most tools load only when searched |
| 3 | Caveman as an output style | Idea | style choice; no harm path |
| 5 | Context editing + memory tool | Idea | API-side feature; no harm path |
| 6 | Programmatic tool calling | Idea | efficiency; no harm path |
| 7 | Strict tool use / structured outputs | Idea | reliability; no harm path |
| 8 | Cross-machine cache | Idea | cost |
| 9 | Worktree = cache miss | Idea | cost |
| 10 | Native sandboxing (/sandbox) | Idea — now the strongest harm lever | named in §10 as the durable answer to text-pattern guards |
| 11 | Package the harness as plugins | Idea | distribution |
| 12 | count_tokens pre-routing + advisor | Idea | cost |
| 13 | Native /workflows for fan-out | Idea | orchestration |
| 14 | Loop-until-10/10 to /goal | Idea | orchestration |
| 15 | Pre-merge ultrareview | Idea | review quality; costs money per run |
| 16 | Use more of the hook events | Done | SubagentStop, PreCompact, PostCompact, StopFailure and UserPromptSubmit are wired (§1) |
| 17 | Cache-diagnosis beta | Idea | cost |
| 18 | Cloud routines | Obsolete | scheduled work runs as local systemd timers and scheduled routines |
| 19 | Native channels for ZEN | Idea | integration |
| 20 | Make governance stick (rule budget) | Open, owned | task:governance-apply-the-no-op-sentence-test-to-the-rule-and-skill-corpus |
| 21 | Agent-memory MCP vs native memory | Done | the split between the two memory systems is documented (FIX-6) |
| 22 | Win→Linux migration hardening | Done | closed in the previous version’s own ledger; no harm path found in this audit |
| 27 | Mastermind hook parity for every vendor | Done, with limits | measured live in §5; remaining gaps are per-vendor caveats there |
sh -c.| Type | Where it lives |
|---|---|
| P1 executed output | every “Proof you can re-run” cell; raw outputs in the evidence file committed next to this report (docs/mastermind/harm-prevention-v2-evidence.json) |
| P2 live body | systemd state, taskman counts and the vendor matrix were read at build time; the numbers in sections 5-7 are that read |
| P3 screenshot | this report rendered at 1280 px and 375 px before delivery (the subject itself is not visual) |
| P4 cited source | section 14, each fetched 2026-09-18 |
| P5 search prompt | not used: every external claim is a fetched primary source |
The request, verbatim: “run deep reserach about mastermind and mpro harness self-checking and self improving mechanism; update report; /goal to get the comprehenive report what checks does and how what procedures, architecture, tools and governance helps to prevent from agents making harm? what we have monitoring solutions and self-healing. if it’s wider than mastermind, expand the scope. if will find flaws fix right away and the final report only all fixes will be made.”
| # | Aspect | Score | Why |
|---|---|---|---|
| 1 | Clarity | 8 | goal is unambiguous: a comprehensive harm-prevention report, with fixes |
| 2 | Context | 7 | points at the existing report; the wider scope is explicitly allowed |
| 3 | Constraints | 6 | “fix right away” had no budget or scope cap |
| 4 | Completeness | 8 | names checks, procedures, architecture, tools, governance, monitoring, self-healing |
| 5 | Structure | 6 | one run-on sentence carrying seven requirements |
| 6 | Examples / references | 6 | no reference bar; an internal audit standard (rule 17) was adopted as the bar |
| 7 | Edge cases | 6 | silent on fixes that need money or a third party |
| 8 | Output format | 8 | “update report” fixes the artifact and its address |
| 9 | Actionability | 9 | work could start with no clarifying question |
CEO-side 7/10 · Agent-side 7/10. Agent-side loses points for one wrong claim made mid-session (“the OpenCode bridge is running cleanly” after its restore — it was not; corrected here) and for two pool-limit stops that killed six fixers mid-work and cost a re-dispatch.
IMPACT: the weakest aspect (constraints: no budget or scope cap on “fix right away”) cost two usage-limit stops and six re-dispatched fixers. CAUSE → EFFECT: every finding became a fix → up to 15 parallel fixers on a shared account → the 5-hour pool hit 100% twice → running fixers died mid-work. KAIZEN applied: the request was split into a 7-item requirement register (research the gate; research the wider harness; what each check does and how; procedures, architecture, tools, governance; monitoring and self-healing; fix every flaw at once; publish only after the fixes), five research legs, a scope manifest for every fixer, the taskman and Mastermind mandates in every brief, and a pool-usage check before every new dispatch.
| Fact | This audit |
|---|---|
| Merged + pushed | Every fix in the Done table is a commit on origin/master, checked when this page was built: git merge-base --is-ancestor, or patch equivalence (git cherry) for commits the broker cherry-landed, because its landing step gives each commit a new hash. Every push went through the git broker (agent-git commit / cherry-land / push): no --force, no --no-verify, no raw push. Every sub-agent receipt was re-run by the orchestrator with subagent-receipt-verify.js --run-tests --run-probes (C105) before its row was written: tests re-executed, probes re-run, deployed file blobs compared. |
| Pruned | Seven working copies of this session survive on disk. One (lane-tmfix) holds this report until it lands. The helper copies (agy, c68merge, hookstamp, leanctx, secretpat, taskman) were created with a raw git worktree add before the broker owned that step, so the broker refuses to release them (not_owned) - every commit in them is already on master and nothing unique is left inside; tracked on problem:agentgit.worktree-release-ownership-record-can-never-match-a-live-lane, and the lane reaper removes them on its own schedule. The two lanes made properly through the broker tonight (the deploy-rail lane and the task-board lane) were released the same way, and the board worker’s own lane released cleanly too. |
| Cherry-picked / taken over | Landed by cherry-land (lane commits replayed onto master); no dead agent’s work taken over. |
| Cleaned up | Bridges were restarted only when their process group held no task in flight (grok, kimi and qwen at 01:45 UTC; claude at 01:52 UTC). There were no pattern kills: every process check resolved pid, working folder and command first. Credentials are redacted before any process listing reaches the transcript, except one listing that did not redact, which is why the master-key row exists. One local tool config was created, ~/.config/rtk/config.toml (row RTKDIFF). The sub-agent scope manifest was cleared and cleanup-session-temps.js run. The only browser tab opened is this report. |
| Taskman updated | Closed with proof this stretch: 70 task-board nodes carry this session’s id on their close (counted from the board’s own changelog at build time, 625 entries across 146 nodes). Each close re-ran the node’s OWN check - the one written on the node before the work - at origin/master and, where the node names a running thing, in the live checkout. Nodes whose check only proves that a tracking text exists stay OPEN as trackers rather than being closed on their own words. Every node this audit filed carries a bound check, so the board’s independent validator can re-run it later without asking anyone. |
Everything above is this audit: what broke and what was fixed. Everything below is the opposite question — not “what went wrong this week” but “how good is this harness, really, compared with what the rest of the industry is doing in 2026?” Six independent measurement passes, each one written by a separate agent that had to cite a file and a line number, or a command and its output, for every single number. None of them was allowed to use memory.
Read them in any order. Each is folded in full — nothing summarised away, because the inconvenient parts are the useful parts. Open a section to see the whole pass; the one-line summary above each tells you whether it is worth your time.
Ten AI vendors run on this machine. This scores each one on seven things that decide whether our rules actually reach it — measured from its own live config, not from a list someone typed. The point of the table is the low scores, and each one says whether it is our debt to pay or the vendor’s own architecture.
sources/vendor-scorecard.md)Measured live, this session, 2026-09-20. Sub-agent of claude_code (CTO). Read-only: no vendor config, hook, or service was changed to produce this document — every number below is either a command's stdout captured in this run, or a file:line opened in this run. Where I could not measure something, it is marked UNMEASURED with what I tried, per this task's explicit instruction (and the CEO's real-time mid-task directive: no memory, only live re-derivation).
The brief warns: "In the past you ruined codex with hooks". I searched for that literal incident (git log, git grep, live docs — commands in §7). I found no literal match for "ruined codex" or "ruined codex with hooks" anywhere in the repo or git history. What I did find is a grounded, dated, directly-quoted incident that fits the description closely — commit 1bdfbcf2859, 2026-07-26 (§4). I report that commit as the closest evidence-backed match and say so explicitly; I do not claim it is the incident the CEO meant, because I cannot verify that identity from the repo alone.
Command:
node -e "const R=require('./tools/eidos/model-registry');const r=R.loadModelRegistry();
console.log(R.vendorCount(r), R.modelVendorCount(r), R.modelCount(r))"
Output: vendorCount=8 modelVendorCount=7 modelCount=23
The 8 entries in core/model-registry.json .vendors: claude, codex, grok, kimi, qwen, opencode, antigravity, ollama. modelVendorCount=7 excludes ollama — it serves another vendor's weights locally (measured: its current model id is qwen3.8-27b-dk:latest, a qwen-family model run on-box), not a distinct model provider.
Command: node tools/eidos/vendor-gate-sync-check.js --json → .coverage.requiredVendors Output (10): claude, codex, grok, qwen, kimi, antigravity, opencode, ollama, zen, max
Reconciliation: core/model-registry.json .notCountedAsVendors (read directly) names the gap:
{ "zen": "MPRO Telegram bot persona, runs on a vendor model",
"max": "MPRO internal bot persona, runs on a vendor model" }
8 registry vendors + zen + max = 10, exactly matching the governance-facing roster.
Which population this scorecard uses: the 10-vendor governance-facing roster, because the task is fundamentally about hook/gate parity and terminal authority, and zen/max/ollama are first-class participants in that question even though their answer is "architecturally absent" — that absence is itself a measured, reportable fact, not a reason to drop them from the table.
Each dimension names what a 10 and a 0 look like, and the live command/field that decides it, so a later agent can re-run this without guessing my intent.
| # | Dimension | 10 looks like | 0 looks like | Measured from |
|---|---|---|---|---|
| D1 | Governance reach | full canonical event set, sharedGates:hard-block | sharedGates:absent, no lifecycle | vendor-gate-sync-check.js --json .matrix.vendors.<v>.{enforcement.sharedGates, supportedEvents, waivedEvents} |
| D2 | Terminal authority integrity | a genuine blocking decision point, backed by a durable terminal-evidence artifact, immune to the unbounded-wedge pattern (§4) | no Stop-equivalent, or gateCapable:true with terminalEvidence:none | same .matrix.vendors.<v>.{terminalAuthority, fence.terminalEvidence} |
| D3 | Stop-budget adequacy | budget comfortably covers the ~17.3 s p50 real-review cost with headroom for a 180 s reviewer ceiling | no budget concept, or a budget so tight a legitimate reviewer is starved | vendor's own adapter constants, file:line (§3.2) |
| D4 | MCP/tool parity | the two sanctioned-editor tools (lean-ctx, jcodemunch) both live-reachable, most of the vendor's own configured servers connected | no MCP client at all, or the sanctioned pair unreachable | live <cli> mcp list run in this session (§3.3) |
| D5 | Model/effort fidelity | registry current model id + effort ceiling match the live config exactly | a confirmed drift (registry says one thing, live config says another) | node tools/eidos/model-registry-refresh.js --check + a direct config read |
| D6 | Values & onboarding coverage | both the CONFIG surface AND the runtime spawn payload carry the values/mandate contract | either surface missing it | node tools/eidos/agent-values-coverage.js |
| D7 | Architecture-fit safety | the vendor's recovery/terminal path is built around its OWN identity model; no evidence it inherited another vendor's assumptions | a live or historically-proven case of exactly that (the codex pattern, §4) | git history + the vendor's own recovery/successor code |
Staleness (verified 2d ago, window 1d, from model-registry-refresh.js --check) is a fleet-wide fact affecting 7 of 8 model-providing vendors equally (opencode was silently absent from that printed list — observed, not explained; see §8). I do not fold it into D5 per-vendor scores because it does not discriminate between vendors; D5 below scores drift only.
node tools/eidos/vendor-gate-sync-check.js --json, .matrix.vendors)| Vendor | Tier | gateCapable | supportedEvents/waived | sharedGates | fence | terminalEvidence | Stop source file |
|---|---|---|---|---|---|---|---|
| claude | canonical | true | n/a (canonical basis, not self-diffed) | hard-block | advisory | present | .claude/hooks/universal-stop.js |
| codex | event-routed | true | 9 / 0 | hard-block | advisory | present | .codex/hooks/mastermind-codex-hook.js |
| grok | event-routed | true | 9 / 0 | hard-block | advisory | present | tools/eidos/agent-hooks/mastermind-grok-hook.js |
| kimi | event-routed | true | 9 / 0 | hard-block | advisory | present | tools/kimi-mastermind-hooks/universal-adapter.js |
| qwen | event-routed-partial | true | 8 / 1 | hard-block | advisory | present | tools/qwen-mastermind-hooks/universal-adapter.js |
| antigravity | event-routed-partial | true | 3 / 6 | hard-block | advisory | absent | tools/eidos/agent-hooks/mpro-gate-agy.js |
| opencode | plugin-partial | true | 8 / 1 | advisory | advisory | present | tools/eidos/agent-hooks/opencode-session-feed.js |
| ollama | shim-advisory | false | n/a | absent | absent | absent | tools/autonomous/ollama-bridge.js |
| zen | bot-postbox | false | n/a | absent | absent | absent | tools/coach/bot.js |
| max | bot-postbox | false | n/a | absent | absent | absent | tools/bots/mpro-channel-bot.js (port 3035) |
route (as a literal JSON field) was not found in this script's output — I used gateCapable + enforcement.sharedGates as the measured equivalent of "is this vendor routed into the shared gate roster", which is what that phrase asks.
The 7 architectural waivers on this run (.sync.waivers, checked: 6): qwen×1 (PostCompact — "Qwen Code 0.21.7 exposes PreCompact but no PostCompact callback"), antigravity×6 (SessionStart, UserPromptSubmit, PreCompact, PostCompact, SubagentStop, SessionEnd — "The Antigravity native hook contract exposes no <X> callback"). All seven are the CLI's own contract, not something to build.
| Vendor | Budget | Source (code) | Live-config cross-check | ||
|---|---|---|---|---|---|
| claude | 90,000 ms default (native); 240,000 ms outer ceiling | .claude/hooks/mastermind-stop.js:157-161; .claude/hooks/universal-stop.js:72,469 | n/a (this IS the native host) | ||
| codex | 120,000 ms (MPRO_HOOK_HOST=codex branch) | .claude/hooks/mastermind-stop.js:160; comment at .codex/hooks/mastermind-codex-hook.js:106 ("opts.timeoutMs\ | \ | 120000") | not independently re-derived from a codex-side numeric constant beyond the comment (see §5 codex) |
| grok | 90,000 ms shared; 140,000 ms terminal scorer; 15,000 ms recorder-only | tools/eidos/agent-hooks/mastermind-grok-hook.js:159-161 | not cross-checked against a ~/.grok/config.toml numeric field (none found) | ||
| kimi | 180,000 ms | tools/kimi-mastermind-hooks/universal-adapter.js:326 (STOP_HOST_BUDGET_MS) | CONFIRMED: ~/.kimi-code/config.toml [[hooks]] event="Stop" timeout=180 (line 162) — code and live config agree exactly | ||
| qwen | 180,000 ms (HOST_TIMEOUT_MS.Stop) | tools/qwen-mastermind-hooks/universal-adapter.js:215 | self-documented 2026-08-26 measurement in the SAME file (lines ~234-250): naive worst case for Stop is 8 gates × PER_GATE_GRANT_MS(30,000, line 161) = 240,000 ms vs the 180,000 ms host budget — a 60,000 ms overrun if ungated. Verified this run: sharedDeadlineAtMs(event, deps) (line 260) IS wired into the live dispatch call (deadlineAtMs: sharedDeadlineAtMs(event, deps), line 393) — the documented graceful redistribution (30/30/30/25/15/15/15/15 k, sums to 175,000 < 180,000) is the code path actually exercised. Reporting as measured-and-mitigated, not an open gap. | ||
| antigravity | 60,000 ms (AGY_HOST_TIMEOUT_SECONDS.Stop=60) | tools/eidos/agent-hooks/mpro-gate-agy.js:339-344 | tightest of any hard-block vendor | ||
| opencode | 90,000 ms literal spawn timeout for the session-end quick gate; measured actual cost ~29 s at --quick under fleet load | tools/eidos/agent-hooks/opencode-session-feed.js:77; measurement cited in tools/eidos/agent-hooks/opencode-universal-gate-runner.js (context-budget-stop-hook.js routing-decision comment) | n/a — this is a surrogate, not a native Stop | ||
| ollama / zen / max | N/A — no such budget exists to measure. No session lifecycle, no Stop callback. | vendor-gate-sync-check.js waiver text (§3.1) | — |
The p50 real-review cost these budgets are sized against, straight from the code comment: 17,287 ms, n=990, measured 2026-09-03 (.claude/hooks/mastermind-stop.js:191); reviewer floor 5,000 ms, ceiling 180,000 ms (lines 195-196).
<cli> mcp list, run in THIS session (commands in §7)| Vendor | Command | Result |
|---|---|---|
| claude | claude mcp list | 12 servers, ALL ✔ Connected (lean-ctx, mpro-jane, jcodemunch, jdocmunch, jdatamunch, mpro-agent-memory, mpro-knowledge, paperclip, mpro-taskman, mpro-bootstrap, previd, higgsfield). Tool self-reports a live config conflict — see §6.1. |
| codex | codex mcp list | Failed in this sandbox: [codex-pool] codex-reader-copy exited 3 — copy NOT touched, no server list printed. Config file (~/.codex/config.toml) declares 8 [mcp_servers.X] blocks (jdatamunch, jdocmunch, lean-ctx, mpro-agent-memory, mpro-jane, mpro-taskman, node_repl, remarkable), 3 enabled=false (remarkable, jdatamunch, jdocmunch) → 5 declared-enabled, no jcodemunch block at all. MPRO's own resolver script (audit-vendor-editor-mcp.js --resolve) separately claimed jcodemunch+lean-ctx both reachable for codex — I could not independently confirm this, and I found a confirmed false-negative in that SAME script for opencode (§6.2), so I do not trust its codex row either without a clean re-run. UNMEASURED: live codex MCP reach is unconfirmed this session. |
| grok | grok mcp list | 12 entries: lean-ctx, jcodemunch, jdocmunch (disabled), jdatamunch (disabled), paperclip, mpro-jane, mpro-agent-memory, mpro-knowledge, mpro-code-graph, mpro-bootstrap, mpro-taskman, youtube → 10 effective. Both sanctioned tools present. |
| kimi | (no subcommand) | Architectural zero. No [mcp...] section anywhere in the live 175-line ~/.kimi-code/config.toml (grep -ni mcp → 0 hits, this session). MPRO's own audit script hardcodes this: tools/scripts/audit-vendor-editor-mcp.js:170 — "kimi CLI has no MCP client in this version". |
| qwen | qwen mcp list | 11 servers: 10 "Connected" (jcodemunch, mpro-bootstrap, mpro-jane, lean-ctx, mpro-knowledge, paperclip, mpro-taskman, previd, higgsfield, mpro-code-graph) + mpro-agent-memory stuck at "Pending approval". Both sanctioned tools connected. |
| antigravity | agy mcp list | 10 servers, all "enabled" (jcodemunch, jdatamunch, jdocmunch, lean-ctx, mpro-agent-memory, mpro-bootstrap, mpro-jane, mpro-knowledge, mpro-taskman, paperclip). Note: this CLI reports configured state, not live-connection state the way qwen/claude do — I do not conflate the two. |
| opencode | opencode mcp list | 14 entries, 10 "connected" (jcodemunch, jdatamunch, jdocmunch, lean-ctx, mpro-agent-memory, mpro-bootstrap, mpro-jane, mpro-knowledge, mpro-taskman, paperclip), 4 "disabled" (web-reader, web-search-prime, zai-mcp-server, zread). Both sanctioned tools connected — this directly contradicts MPRO's own audit script's --resolve verdict (MISSING_TOOL, both absent); see §6.2. |
| ollama / zen / max | — | UNMEASURED, architectural. No CLI tool-loop session to run mcp list against (ollama is a request-local HTTP loop; zen/max are Telegram bots). Not investigated further — this is the same fact already established in §3.1, not a new one. |
Search performed (all in §7): git grep (index-based, all tracked files) for "ruined codex" → 0 hits. git log --all --grep for "ruined" → 0 relevant hits. Broader git grep for codex.{0,60}(postmortem|regression|disabled all hook|hook overload) surfaced a real, dated, directly-quoted incident:
Commit 1bdfbcf28596d9a1003d84679ce1bc7351bc1f95, 2026-07-26 04:41:05 +0300 fix(codex): unwedge terminal recovery - codex was unusable by construction
CEO quotes in the commit body (verbatim, as committed): "please fix codex handoffs, impossible to use it" / "codex keep having issues and it's useless because of that". The same 2026-07-26 quote is repeated in the regression test header at .codex/hooks/mastermind-codex-hook.terminal-successor-wedge.test.js:2-3.
What actually happened (from the commit body, three defects, the first two are the architectural lesson):
mastermind-codex-hook.js's !claimedByClaude branch returned decision:'block' waiting for a Taskman node claimed_by claude_code — a condition the blocked codex session cannot satisfy itself (claiming as claude_code from codex is identity spoofing), with no bound. defaultStartTerminalRecoverySuccessor existed with zero call sites. Measured live at the time: 12/12 recovery handoffs died in postbox/failed, 0 ever claimed.
very vendor the handoff body itself declares "fail-closed and cannot recover itself" — so it could never produce the claude_code claim the gate required.
known-dead vendor regardless.
The fix was NOT "give codex Claude's hooks." It was: bound the block with terminalStopDecision, and make the successor launcher spawn claude --print (the vendor that CAN self-claim), not codex.
One-line lesson: a shared Stop-gate mechanism modeled on one vendor's own identity/recovery assumptions (self-claim by claude_code) becomes an unbounded, unsatisfiable block when applied unmodified to a vendor that architecturally cannot meet that assumption — the correct fix names the right successor vendor per architecture, it does not hand the blocked vendor a copy of the hooks that trapped it.
Caveat on identity: I found no text in the repo literally saying "ruined codex with hooks" — I am reporting the closest grounded, dated match I could find, not asserting it is verbatim the incident referenced in this task's brief.
A second, distinct codex incident turned up in the same search, unrelated to hooks: docs/ai-development-harness-audit/system-audit.json:152445 — "Codex Transport-closed regression (2026-07-16): Mid-session death of the stdio MCP child made every later tool call fail" — an MCP transport bug, not a hooks/gate bug. Noted for completeness; not the primary lesson here.
Scores are 0-10 per the §2 rubric; "Debt#N" = top harness-debt items (file cited, blast radius stated); architectural gaps are labelled ARCHITECTURAL and are not counted against the vendor as harness debt.
| D1 | D2 | D3 | D4 | D5 | D6 | D7 |
|---|---|---|---|---|---|---|
| 10 | 10 | 8 | 9 | 10 | 10 | 10 (n/a as source) |
D3=8, not 10: 90 s is the tightest default among the fully-enforced (hard-block) vendors despite Claude carrying the heaviest canonical roster — codex/kimi/qwen all get more headroom. Model: registry current claude-opus-5, effortCeiling:max, rungs [low,medium,high,xhigh,max] (core/model-registry.json) — no drift, staleness only. (This sub-agent session itself runs as Sonnet 5 per its own system prompt — a same-vendor session running a different family member is expected, not drift.) Values: agent-values-coverage.js → CONFIG=OK, claude-bridge=OK.
Top 3 harness debt:
claude mcp list prints [Conflicting scopes] — lean-ctx is defined in BOTH the user scope (local binary /home/darius/MPRO/tools/vendor/lean-ctx/lean-ctx) and the project scope (http://localhost:3048/mcp); "OAuth tokens are stored per endpoint, so authenticating in one context will not carry over." The tool names its own remedy: claude mcp remove lean-ctx -s user (or -s project). Blast radius: low, single server, fix is one command — but I did not run it (read-only mandate; this is the orchestrator's/CEO's call).
.mcp.json (project scope, 10 servers) vs the live claude mcp list (12, including jdocmunch + jdatamunch which are NOT in .mcp.json) — a third, user-level layer is doing real work invisible from reading the project file alone. Exact file not identified this session (time-bounded). Blast radius: low, informational — worth a dedicated 5-minute follow-up to name the file.
STOP_HOOK_PARENT_TIMEOUT_MS default (90,000 ms, .claude/hooks/mastermind-stop.js:157-161) isthe smallest hard-block budget on the roster despite Claude running the full canonical set. Blast radius: medium — the slowest legitimate review chain is the one most likely to be cut here first.
| D1 | D2 | D3 | D4 | D5 | D6 | D7 |
|---|---|---|---|---|---|---|
| 9 | 8 | 8 | 5 | 3 | 10 | 7 |
D5=3, the worst on the roster: confirmed live drift, both axes at once. node tools/eidos/model-registry-refresh.js --check → DRIFT codex: registry says gpt-6-astra, live config says gpt-5.6-sol and EFFORT DRIFT codex: registry effortCeiling medium, live ~/.codex/config.toml:4 model_reasoning_effort ... says xhigh. Directly re-confirmed by reading ~/.codex/config.toml myself (via the credential-redaction wrapper): model_reasoning_effort = "xhigh", model = "gpt-5.6-sol". D7=7: this is the vendor from the §4 incident — the specific pattern is proven fixed (bounded block, correct successor vendor), so not scored low, but it is the one vendor with a proven historical wedge, so not a full 10 either.
Live lifecycle wiring (~/.codex/hooks.json, read this session): 10 distinct event names (PostToolUse, PreToolUse, SessionEnd, SessionStart, Stop, UserPromptSubmit, PreCompact, PostCompact, SubagentStart, SubagentStop) — SubagentStart is a codex-specific extra beyond the shared canonical 9. Anomaly found: PostToolUse carries 4 near-duplicate matcher registrations, same command, all timeout=4; PreToolUse carries 4 near-duplicate registrations with inconsistent timeouts (120/15/15/15). One instance of each event points at a worktree path containing THIS session's own id fragment (.claude/worktrees/lane-harness--s22438091f7ec/tools/codex/codex-lean-hook-isolation.js) — evidence the installer accumulates a per-worktree registration without pruning stale ones.
Top 3 harness debt:
core/model-registry.json vendors.codex vs ~/.codex/config.toml:4-5. Blast radius: HIGH — tools/autonomous/bridge-effort.js derives the codex bridge's granted effort from the registry ceiling, so a live bridge session would be clamped toward "medium" while the vendor's own config actually runs "xhigh"; every taskman provenance stamp under this is wrong on two axes.
~/.codex/hooks.json (above). Likely written by tools/codex/install-managed-hooks.py per earlier grep hits naming that script as the installer. Blast radius: medium — every codex tool call spawns codex-lean-hook-isolation.js up to 4× instead of once, and the worktree-pinned entries become dead references once that worktree is pruned.
jcodemunch is unconfirmed, and codex's own config has no jcodemunch mcp_servers block at all (only jdocmunch/jdatamunch, both disabled). File: ~/.codex/config.toml. Blast radius: medium — if genuinely unreachable, codex cannot use the flagship symbol-graph tool for any task that needs it; the discrepancy with the audit script's positive verdict is unresolved and deserves one clean, unwrapped codex mcp list run outside whatever "codex-pool" shim intercepted mine in this sandbox.
| D1 | D2 | D3 | D4 | D5 | D6 | D7 |
|---|---|---|---|---|---|---|
| 9 | 9 | 9 | 9 | 10 | 10 | 9 |
Model/effort: live ~/.grok/config.toml [models] default_reasoning_effort = "xhigh" (line 92), [model."grok-4.6"] (line 96) — matches registry exactly, no drift. terminalAuthority.transport is literally native-stop-plus-open-block — a distinct shape from plain native-stop, evidence the adapter was built aware a bare block isn't always sufficient. No incident found for grok in git history searches.
Top 3 harness debt:
[compat.claude] mcps = false and a separate `disabled_mcp_servers = ["remarkable","higgsfield"] list naming servers not present as native [mcp_servers.X]` blocks in the config I read — worth confirming these aren't silently inherited then ignored from an upstream default set. Blast radius: low, informational.
jdocmunch/jdatamunch disabled (same fleet-wide default as codex/opencode) — likely intentional (.mcp.full.json opt-in pattern), not grok-specific. Blast radius: low.
resolveGrokPrePostSharedTimeoutMs() / resolveGrokUserPromptSubmitTimeoutMs() (tools/eidos/agent-hooks/mastermind-grok-hook.js:298,301) — time-bounded. Disclosed gap, not guessed.
| D1 | D2 | D3 | D4 | D5 | D6 | D7 |
|---|---|---|---|---|---|---|
| 9 | 9 | 9 | 0 | 10 | 10 | 9 |
D4=0: architectural, not debt — no MCP client exists in this CLI version at all. Confirmed two ways: (a) live ~/.kimi-code/config.toml, 175 lines, grep -ni mcp → 0 hits; (b) MPRO's own audit script hardcodes it: tools/scripts/audit-vendor-editor-mcp.js:170, "kimi CLI has no MCP client in this version". Kimi cannot reach lean-ctx or jcodemunch by any mechanism — its two built-in [services.moonshot_search] / [services.moonshot_fetch] HTTP tools are a partial substitute for web lookups, not for code intelligence.
Live lifecycle wiring: 18 [[hooks]] blocks / 11 distinct event names, including StopFailure and PostToolUseFailure — kimi-specific extras beyond the shared canonical 9. Stop budget cross-validated exactly: config timeout=180 (line 162, event="Stop") = code's STOP_HOST_BUDGET_MS=180000 (tools/kimi-mastermind-hooks/universal-adapter.js:326). Model/effort: default_model = "kimi-code/k3", default_effort = "max" (config lines 2-3) — matches registry exactly, no drift.
Top 3 harness debt: (kimi's architecture is otherwise clean; only one is a real "debt" item, the other two are disclosed measurement gaps, not manufactured padding)
the two built-in Moonshot services already wired.
stop-failure-gate.js and the -Failure variant of session-scope-fence-post.js actually DO under a genuine tool failure (time-bounded). Disclosed, not guessed.
PreToolUse and 3 to PostToolUse (track-dispatch.js,session-scope-fence-pre.js, universal-adapter.js / track-touched-file.js, session-scope-fence-post.js ×2, universal-adapter.js) — unlike codex's anomaly, these are DIFFERENT scripts doing different jobs with consistent timeouts, so this reads as intentional design; flagged only for confirmation, not asserted as a defect.
| D1 | D2 | D3 | D4 | D5 | D6 | D7 |
|---|---|---|---|---|---|---|
| 8 | 9 | 9 | 8 | 10 | 10 | 9 |
D1=8: 8/9 canonical events, 1 architecturally waived (PostCompact) — honest gap, not a defect. Model: live ~/.qwen/settings.json "model":{"name":"qwen3.8-max"} — matches registry exactly. Registry effortCeiling:null (intentionally unmeasured) — I found no explicit reasoning-effort key in the model block I read, consistent with the registry's own null (absence agreeing with absence, not a disagreement). D3=9: the qwen adapter's own 2026-08-26 self-measured overrun risk (§3.2) is now verified MITIGATED live, which is itself a positive self-monitoring signal, not a demerit.
Top 3 harness debt:
mpro-agent-memory MCP server is stuck at "Pending approval" in live qwen mcp list — qwen's own MCP trust/approval flow has not cleared it. Likely record: ~/.qwen/mcpApprovals.json (seen in a directory listing, not opened — a per-tool trust file, time-bounded). Blast radius: low-medium — qwen sessions cannot use cross-session agent memory until approved.
waiver text, not something MPRO can add.
effortCeiling:null in the registry for qwen — unmeasured by design; bridge provenance stamps fall back to an announced last-resort table (bridge-effort.js) rather than a real per-vendor ceiling. Blast radius: low (the fallback is explicit, not silent), but worth a dedicated check: does qwen's CLI expose a reasoning-effort knob at all?
| D1 | D2 | D3 | D4 | D5 | D6 | D7 |
|---|---|---|---|---|---|---|
| 5 | 5 | 6 | 9 | 10 | 10 | 8 |
D1/D2 are the lowest hard-block scores on the roster, both for measured, disclosed reasons: only 3/9 canonical events are native (6 waived — SessionStart, UserPromptSubmit, PreCompact, PostCompact, SubagentStop, SessionEnd, each because "the Antigravity native hook contract exposes no <X> callback" — ARCHITECTURAL, confirmed by the live matrix's own waiver text). D2=5 because gateCapable:true but fence.terminalEvidence is literally "none" — MPRO's own governance tooling already self-flags this exact gap (caveat gate_capable_without_terminal_evidence in the live matrix output); I am reconfirming it is still true today, not discovering it fresh.
Live MCP: agy mcp list → 10 servers, all "enabled" (jcodemunch, jdatamunch, jdocmunch, lean-ctx, mpro-agent-memory, mpro-bootstrap, mpro-jane, mpro-knowledge, mpro-taskman, paperclip), from ~/.gemini/antigravity/mcp_config.json. The FILE-SCAN half of audit-vendor-editor-mcp.js looks at the wrong path (<repo>/.antigravity/config.toml, absent) and reports antigravity as "not installed" — a known, already-documented false negative in that script's own header comment (lines 42-56); my live agy mcp list run reconfirms the real number.
Top 3 harness debt:
terminalEvidence:"none" despite gateCapable:true (above). File: tools/eidos/agent-hooks/mpro-gate-agy.js — the Stop path needs to emit a durable artifact the way claude_tool_result/codex_function_call_output/kimi_wire_tool_result do for the others. Blast radius: medium — a claimed antigravity Stop-gate pass cannot be independently re-verified after the fact.
flagged so the low D1 number is not misread as a defect.
AGY_HOST_TIMEOUT_SECONDS.Stop=60, tools/eidos/agent-hooks/mpro-gate-agy.js:339-344) is the tightest of any hard-block vendor. Blast radius: low-medium — fine while gates stay cheap, least headroom if a reviewer call is ever added.
| D1 | D2 | D3 | D4 | D5 | D6 | D7 |
|---|---|---|---|---|---|---|
| 6 | 8 | 8 | 9 | 10 | 10 | 10 |
D7=10: opencode is the best example on the roster of the exact discipline the CEO's warning asks for — its CLI genuinely has no native Stop callback, and MPRO's adapter did not try to force one; it built a session-end surrogate instead (terminalAuthority.transport = "session-end-open-block", qualityMode = "blocking-next-tool": a bad verdict denies the next tool call, not the current session end). D1=6 reflects enforcement.sharedGates = advisory (the only vendor besides antigravity in that bucket) — by design, not proven failure, but a genuinely lower enforcement floor than the 5 hard-block vendors; flagged for an owner decision rather than scored as clean pass or fail.
Model: opencode.json "model": "zai-coding-plan/glm-5.3" (confirmed at 3 places) — matches registry exactly, no drift. Budget: 90,000 ms literal spawn timeout (tools/eidos/agent-hooks/opencode-session-feed.js:77), measured real cost ~29 s at --quick under fleet load (cited in opencode-universal-gate-runner.js's own routing-decision comment) — 3× headroom.
Top 3 harness debt:
sharedGates: advisory not hard-block — confirm whether this is a permanent architecture ceiling(plugin API cannot deny synchronously) or something to close. Not scored as a clean win or loss — this is exactly the kind of ambiguous case the brief asked me to mark rather than force into a bucket.
--resolve reports opencode MISSING_TOOL (both lean-ctx and jcodemunch "absent") — a **false negative**, disproven by my direct opencode mcp list run this session showing both ✓ ... connected. The script's own comments (lines 88-96) already admit the opencode output shape is fragile to parse ("a bullet list puts the NEXT SERVER's url one line down"). File: tools/scripts/audit-vendor-editor-mcp.js, function parseResolverOutput. Blast radius: low by itself, **high** if anyone trusts its MISSING_TOOL` verdict as ground truth without re-checking — which nearly happened while building this very scorecard.
auto-open-html-hook.js has a real, still-open gap on opencode per the live .divergence.declared entry (vendor-gate-sync-check.js --json): maybeAutoOpen only fires on tool.execute.after; the Stop-time requestPendingDrain "retries a delivery ALREADY queued and never inspects a file written since." The script's own text: "stays deliberately NOT waived on Stop and remains an open finding there." File: tools/eidos/auto-open-html.js (requestPendingDrain). Blast radius: low (a CEO auto-open convenience, not a safety gate).
| D1 | D2 | D3 | D4 | D5 | D6 | D7 |
|---|---|---|---|---|---|---|
| 0 | 0 | n/a | UNMEASURED | 10 | 10 | n/a |
All architectural: "the request-local HTTP model tool-call loop exposes NO autonomous vendor session lifecycle — no session start, no Stop callback, no per-call hook surface. Governance reaches it only by signed postbox dispatch to ollama-bridge.js" (live waiver text, vendor-gate-sync-check.js --json). Model: registry current qwen3.8-27b-dk:latest, effortCeiling:null, rungs:null — correctly null (a locally-served model has no vendor-side reasoning-effort API), not a gap. Values: agent-values-coverage.js → ollama-bridge = OK (the payload reaches it at the prompt level even without a governed lifecycle).
Harness debt: none distinct from the one architectural fact above — D1/D2/D3/D4 are four readings of the SAME "no session lifecycle" fact, and manufacturing three separate "top debt items" here would be padding, not measurement. Stated once, honestly.
| D1 | D2 | D3 | D4 | D5 | D6 | D7 | |
|---|---|---|---|---|---|---|---|
| zen | 0 | 0 | n/a | n/a | n/a | 8 | n/a |
| max | 0 | 0 | n/a | n/a | n/a | 8 | n/a |
Both: Telegram bots (tools/coach/bot.js for zen; tools/bots/mpro-channel-bot.js, port 3035, for max), not CLI tool-loop agents — "no autonomous agent session lifecycle and no Stop callback... Governance reaches it via the postbox mandate + createAgentTask injection" (live waiver text). The ONE real enforcement teeth both have: securityMode: "blocking-redaction" on outbound content.
A genuine, dated, positive kaizen fact from the SAME live waiver text: these two vendors' gate-resolution count was once measured at 28 (a false green) and has been corrected to 0 by declaration — the fleet catching and fixing its own overstated measurement, worth citing as a positive data point rather than only listing gaps.
D6=8 not 10: agent-values-coverage.js confirms both are OK at the CONFIG surface (9-vendor list), but neither has a dedicated runtime-payload bridge in the 10-bridge list (claude/kimi/codex/grok/ antigravity/ollama/opencode/qwen-bridge + session-spawner + trigger-agent) — their runtime values payload rides on createAgentTask injection via postbox instead, per the waiver's own design claim, which I did not independently re-verify with a live bot message this session (out of scope for a read-only measurement pass, and would mean sending a real message through the CEO's bots).
Harness debt: one shared, real item for both — confirm (not this session) that createAgentTask injection is actually exercised on live bot traffic, since "governance reaches it via X" is a design claim in the waiver text I did not independently exercise.
claude mcp list self-reports a live scope conflict — CEO-owned decision, not codelean-ctx is registered at BOTH -s user (a local binary path, /home/darius/MPRO/tools/vendor/lean-ctx/lean-ctx) and -s project (the HTTP endpoint http://localhost:3048/mcp). The tool prints its own remedy command. I did not run it — removing a scope is a config change outside this task's read-only mandate, and choosing WHICH scope to keep is a judgment call for whoever owns Claude's MCP config, not mine to make from a measurement pass.
tools/scripts/audit-vendor-editor-mcp.js's --resolve mode has a confirmed false negative for opencodeDetailed in §5 (opencode Debt#2). This is the single most load-bearing finding in this whole exercise for anyone building on top of this scorecard: do not trust that script's live-resolver verdict for opencode without a direct cross-check — I nearly did, and the numbers would have been backwards (reporting a working vendor as broken).
model-registry-refresh.js --check's printed STALE listThe checker IS wired to read opencode's model (tools/eidos/model-registry-refresh.js:52,69, ~/.config/opencode/opencode.json "model" field), but opencode did not appear in the STALE/DRIFT lines this run printed for the other 7 model-providing vendors. I observed this and did not chase why (time-bounded) — recorded here rather than silently smoothed over.
node -e "const R=require('./tools/eidos/model-registry');const r=R.loadModelRegistry();
console.log(R.vendorCount(r), R.modelVendorCount(r), R.modelCount(r))"
node -e "const j=require('./core/model-registry.json'); console.log(...)" # vendors, notCountedAsVendors
node tools/eidos/vendor-gate-sync-check.js --json # full governance matrix, waivers, divergence
node tools/eidos/model-registry-refresh.js --check # drift + staleness, all 8 vendors
node tools/eidos/agent-values-coverage.js # values/mandate coverage, config + runtime
node tools/eidos/tool-output-secret-redaction.js <path> # safe read of every credential-bearing config below
~/.codex/config.toml ~/.codex/hooks.json /etc/codex/ (ls only, no config.toml found)
~/.grok/config.toml ~/.qwen/settings.json ~/.kimi-code/config.toml
~/.gemini/settings.json ~/.gemini/antigravity/mcp_config.json
.mcp.json .mcp.full.json ~/.config/opencode/opencode.json
node tools/scripts/audit-vendor-editor-mcp.js --json # file-scan editor audit
node tools/scripts/audit-vendor-editor-mcp.js --resolve --json # live-CLI resolver audit (contains the opencode false negative, §6.2)
claude mcp list grok mcp list qwen mcp list agy mcp list opencode mcp list codex mcp list (failed, see §5)
timeout 60 opencode mcp list # direct cross-check that found the §6.2 discrepancy
git grep -liE "ruined codex" # 0 hits
git log --all --oneline -i --grep="ruined" # 0 relevant hits
git grep -niE "codex.{0,60}(postmortem|regression|disabled all hook|hook overload)" # surfaced the §4 incident
git show -s --format='%H|%ad|%s' --date=iso 1bdfbcf2859 # incident commit metadata
git show --format='%B' -s 1bdfbcf2859 # incident commit body (CEO quotes)
git log --follow --oneline -- .codex/hooks/mastermind-codex-hook.terminal-successor-wedge.test.js
grep -n "..." tools/qwen-mastermind-hooks/universal-adapter.js # HOST_TIMEOUT_MS, PER_GATE_GRANT_MS, sharedDeadlineAtMs wiring
grep -n "..." tools/eidos/agent-hooks/mastermind-grok-hook.js # GROK_STOP_*_TIMEOUT_MS
grep -n "..." tools/eidos/agent-hooks/mpro-gate-agy.js # AGY_HOST_TIMEOUT_SECONDS, PER_GATE_GRANT_MS
grep -n "..." tools/kimi-mastermind-hooks/universal-adapter.js # STOP_HOST_BUDGET_MS
curl -s -m 5 http://localhost:3018/llms.txt -o /dev/null -w "%{http_code}" # taskman liveness = 200
curl -s -m 5 "http://localhost:3018/api/search?q=..." # duplicate check before any node creation
codex mcp list failed at a codex-pool reader-copy shim (exit 3) specific to this sandbox; the audit script's automated resolver claims it works, but I do not trust that script's parser after finding it wrong for opencode. Config-declared reach (5 enabled blocks, no jcodemunch) is the only number I stand behind.
jdocmunch/jdatamunch to Claude's live claude mcp list (12) beyond the project .mcp.json (10). Not identified this session.
model-registry-refresh.js --check's printed STALE list despitebeing wired into the checker's file list (§6.3).
~/.qwen/mcpApprovals.json — not opened (a per-tool trust file, time-bounded); would explain why mpro-agent-memory is stuck at "Pending approval" for qwen.
resolveGrokPrePostSharedTimeoutMs() / resolveGrokUserPromptSubmitTimeoutMs() bodyvalues** — function names confirmed, numeric bodies not opened (time-bounded).
createAgentTask injection is actually exercised on live zen/max bot traffic — thewaiver text's design claim was not independently exercised with a live message (would require sending a real message through the CEO's Telegram bots, outside a read-only measurement pass).
closest grounded match (§4) but cannot confirm it is verbatim the same event.
No taskman node was created for this measurement pass. curl -s http://localhost:3018/api/search?q=vendor%20capability%20scorecard (this session) found no exact duplicate, but did surface a closely-related open node, task:harness.multi-vendor-readiness-10of10-20260906 ("Multi-vendor harness readiness to 10/10, CEO 2026-09-06"). This scorecard is a bounded, read-only measurement pass requested directly by my orchestrator (claude_code); I judged it safer to hand this file back to the orchestrator to attach to whichever node it already owns than to mint a possibly-duplicate sibling node under time pressure — that decision is reflected in the receipt below (node_id: null).
{"node_id":null,"status":"done","commits":[],"deployed":[],"tests":[],"probes":[{"cmd":"node -e model-registry vendorCount/modelVendorCount/modelCount","exit":0},{"cmd":"node tools/eidos/vendor-gate-sync-check.js --json","exit":0},{"cmd":"node tools/eidos/model-registry-refresh.js --check","exit":0},{"cmd":"node tools/eidos/agent-values-coverage.js","exit":0},{"cmd":"node tools/scripts/audit-vendor-editor-mcp.js --json","exit":0},{"cmd":"node tools/scripts/audit-vendor-editor-mcp.js --resolve --json","exit":1},{"cmd":"claude mcp list","exit":0},{"cmd":"grok mcp list","exit":0},{"cmd":"qwen mcp list","exit":0},{"cmd":"agy mcp list","exit":0},{"cmd":"opencode mcp list","exit":0},{"cmd":"codex mcp list","exit":0},{"cmd":"git grep -liE \"ruined codex\"","exit":1},{"cmd":"git show -s 1bdfbcf2859","exit":0},{"cmd":"curl -s -m5 localhost:3018/llms.txt -> 200","exit":0}],"lanes":[],"left":"See report section 8 (UNMEASURED list): codex live MCP reach unconfirmed in this sandbox; exact source of Claude's 12th/11th mcp servers beyond .mcp.json not identified; opencode's absence from model-registry-refresh's STALE list unexplained; ~/.qwen/mcpApprovals.json not opened; two grok timeout function bodies not opened; zen/max createAgentTask injection not live-exercised; identity of the brief's 'ruined codex with hooks' incident not confirmed verbatim, only the closest grounded match (commit 1bdfbcf2859) reported. No taskman node created - see report section 8 for the related open node (task:harness.multi-vendor-readiness-10of10-20260906) the orchestrator may want to attach this to."}Fourteen control areas from the current agentic-security standards, each scored 0-10 against what this harness actually does. It also names where we look compliant and are not — which is the more useful half.
sources/industry-standards-gap.md)| Source | Document's own date | Fetched | Used for |
|---|---|---|---|
| OWASP Top 10 for Agentic Applications — announcement | published 2025-12-09, taxonomy v1.1 | 2026-09-20 | ASI01–ASI10, the matrix spine |
| OWASP GenAI press release | 2025-12-09 | 2026-09-20 | Expert Review Board (NIST, EC, Turing) |
| OWASP Agentic Security Initiative — publications index | most recent item 2026-06 | 2026-09-20 | what ASI has shipped and when |
| OWASP Agent Control Standard (ACS) | spec v0.1.0, tag v0.1.1; next release targeted 2027-03 | 2026-09-20 | Instrument / Trace / Inspect; 5 dispositions; AgBOM |
| MITRE ATLAS data releases | v2026.09 (2026-09-15); agentic techniques in v2026.08 (2026-09-01) | 2026-09-20 | AML.T0116/T0117/T0124 |
| NIST AI RMF landing page | AI RMF 1.0 = 2023-01-26; GenAI Profile AI 600-1 = 2024-07-26 | 2026-09-20 | see the "older than expected" note below |
| NIST COSAiS project (SP 800-53 AI overlays) | concept paper 2025-08-14; annotated outline (Predictive AI) 2026-01-08; page last updated 2026-01-08 | 2026-09-20 | the agent overlays do not exist yet |
| European Commission — AI Act regulatory framework | page last updated 2026-08-03 | 2026-09-20 | application dates; AI Omnibus in force 2026-07-27 |
(a) The NIST side is older than anyone assumes. The core framework MPRO would be measured against is still AI RMF 1.0 of 2023-01-26, and the generative profile is still AI 600-1 of 2024-07-26 — neither is agent-aware. The agent-specific NIST control overlays (COSAiS use cases 3 "Using AI Agent Systems (Single Agent)" and 4 "(Multi-Agent)") have no public draft; only a Predictive-AI annotated outline dated 2026-01-08 exists. Nobody can claim NIST compliance for an agentic harness today, and neither can we. Anyone who tells the CEO otherwise is citing a 2023/2024 document as current.
(b) OWASP is where the agent-specific bar actually is, and it moved on 2025-12-09 (ASI01–ASI10) with an Expert Review Board including NIST and the European Commission. That is the standard this matrix is built on.
| Standard | Why excluded |
|---|---|
| ISO/IEC 42001 | https://www.iso.org/standard/42001 returned HTTP 403. I did not open the standard. A web search summary said 42001:2023 is still the only published edition (with EN ISO/IEC 42001:2026 a regional adoption and ISO/IEC 42006:2025 governing certifiers), but a search summary is not a fetched standard, so no 42001 row is scored. |
| OWASP "State of Agentic AI Security and Governance 2.01" (2026-06-01) | landing page fetched; the document body is a PDF download I did not open. Its control domains are therefore UNMEASURED. |
| OWASP Top 10 PDF body | only the two announcement pages were readable. ASI01–ASI10 names are from those pages; the per-risk mitigation text was not opened. |
| EU AI Act article-level obligations (e.g. human oversight, logging) | artificialintelligenceact.eu/implementation-timeline/ was fetched but returned internally contradictory dates (described 2027-12-02 as already in force in September 2026). I discarded it and used only the Commission page. No article-numbered obligation is cited below. |
| MITRE ATLAS mitigations | atlas.mitre.org is a JS app; WebFetch returned only the page title. Technique IDs come from the fetched atlas-data releases page. |
Scale: 0 = absent · 1–3 = present but advisory or provably inert · 4–6 = real but partial · 7–8 = enforced with a known hole · 9–10 = enforced and measured.
| # | Control area | Standard requirement (fetched source) | What MPRO actually has — file:line, measured 2026-09-20 | Score | Gap | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | Agent identity & authorization | ASI03 Identity & Privilege Abuse: short-lived credentials, agent identity isolated from user identity, log every privileged action | tools/mpro-taskman/lib/agent-auth.js:24-28 — deriveAgentCredential = HMAC-SHA256(shared vault secret, "ctx:"+agent). Taskman enforces 401 (no cred) / 403 identity_mismatch. No exp, ttl, rotate or nonce symbol anywhere in the 238-line file. | 3 | The credential is a derivable label, not an authenticated identity: anyone holding the shared secret can mint any agent. No expiry, no rotation, no revocation. No per-agent tool scope — every agent can call every tool. | |||||||||||
| 2 | Tool-use mediation | ASI02 Tool Misuse; ACS pillar Instrument — a Guardian inspects before execution with 5 dispositions (allow/deny/modify/ask/defer) | .claude/hooks/pre_tool_use.js on matcher `^(Bash\ | Write\ | Edit\ | Read\ | Grep\ | Glob\ | Agent\ | Task\ | Workflow\ | WebFetch\ | WebSearch\ | mcp__.*)$, timeout 120 s; block() at :850-853 emits decision:'block'; BLOCKED_FILES 15 regexes at :489-496; tools/safety/lib/patterns.js BLOCK/FORBID/CONFIRM tiers. **But** .claude/settings.json → permissions.defaultMode: "bypassPermissions"`, so the host's own confirmation layer is off and the hook is the only mediation. | 4 | Deny + allow exist; modify, ask and defer do not. Host permission layer disabled by configuration. The 16-entry permissions.deny list is git/crontab-shaped only — no network, no credential, no destructive-filesystem entry. |
| 3 | Prompt-injection / untrusted content | ASI01 Agent Goal Hijack (EchoLeak cited); ATLAS AML.T0116 Autonomous Reconnaissance, AML.T0117 Autonomous Attack-Path Adaptation | tools/eidos/inbound-content-safety.js:100 screenInboundContent exists and is good (returns a hash, never the content; governance tier never auto-applies). Production consumers in the master tree, complete list: tools/news-monitor/server.js, tools/news-monitor/lib/feeds.js, tools/news-monitor/lib/signals.js. Nothing in .claude/hooks/. .claude/hooks/pre_tool_use.js:478 is the only WebFetch/WebSearch mention and it merely sets task = 'Web research'. PostToolUse matchers registered: TodoWrite, Bash, Read, `Write\ | Edit, Task\ | Agent — **no WebFetch, no WebSearch, no mcp__.*`**. | 2 | The screen guards one RSS feed. Every byte a web page, an MCP server or a sub-agent returns reaches the model unscreened. I made 11 web fetches in this session; not one was screened. | |||||||||
| 4 | Memory & context integrity | ASI06 Memory & Context Poisoning — persistent and shared knowledge stores | ~/.claude/projects/-home-darius-MPRO/memory/ holds 1,179 files (counted this run), injected into session context. Grep for `agent-memory\ | global-memory\ | projects/.../memory in tools/safety/critical-file-guard.js and tools/safety/lib/integrity.js` returned zero hits — the store is in no tier and in no hash baseline. It is outside the git repo, so there is no version history either. | 1 | No integrity baseline, no provenance, no version control, no write mediation on the store that shapes every future session. A single poisoned memory file is permanent and invisible. | |||||||||
| 5 | Human oversight & escalation | ASI09 Human-Agent Trust Exploitation; ACS dispositions ask / defer; EU AI Act human-oversight duty (Commission page, updated 2026-08-03) | tools/eidos/outbound-autonomy-policy.js:16-21 — default is DENY / ceo_gate; unknown venture/channel/template/recipient → ceo_gate; missing policy or counters → ceo_gate. decideOutbound at :318. 20+ production consumers: tools/scripts/send-email.js, tools/marketing/email-channel.js, tools/marketing/google-ads-api.js, tools/coach/lib/bot-outbound-gate.js, tools/eshop/review-request-send.js, tools/mpro-ecommerce/packages/core/dist/lifecycle-*-transport.js. .claude/hooks/ask-ceo-gate.js registered on AskUserQuestion. | 7 | Genuinely strong — for outbound only. There is no equivalent gate on irreversible internal actions: service restart, production deploy, DB write, git push. ACS's ask/defer dispositions have no implementation for those. | |||||||||||
| 6 | Auditability & provenance | ACS pillar Trace — OpenTelemetry spans + OCSF events | Taskman lifecycle fields (GR-71). Live counts, 2026-09-20 07:00:49–07:01:08 EEST: status=done board-only 1,264; done&include_archived=1 3,453; done&validated=true&include_archived=1 1,116; status=open 3,269. → 32.3 % of all completed work carries an independently re-run validation (1,116 / 3,453 — both sides archive-inclusive). Gate ledger .tmp/mastermind-gate-history.jsonl, 1,193 runs over 7.5 h across 458 distinct sessions. | 6 | Rich and honest, but not in any standard format: no OpenTelemetry span, no OCSF event, no cross-vendor trace id. Three vendors emit nothing at all (row 10). A regulator or an external auditor cannot ingest it. | |||||||||||
| 7 | Supply chain of tools / skills / MCP | ASI04 Agentic Supply Chain (GitHub MCP exploit cited); ACS pillar Inspect — AgBOM in CycloneDX/SPDX/SWID | .mcp.json: 10 servers, every one loopback-only (localhost) or a local /usr/bin/node script — no remote third-party MCP. .claude/skills/ = 175 entries and is TIER3 (1-layer confirm + backup) at tools/safety/critical-file-guard.js:58-64. tools/prompt-library/ and prompts/ are TIER2 at :38-56. | 5 | .agents/skills/ holds 207 skills and appears in no tier — and that is the vendor-neutral plane every vendor renders from. No AgBOM, no signature or hash pin on any skill or MCP server, no dependency inventory for the agent stack. | |||||||||||
| 8 | Code execution / sandboxing | ASI05 Unexpected Code Execution — sandboxing failures | --sandbox read-only is passed only to Codex reviewer/consilium invocations: tools/autonomous/collegial/consilium-runner.js:385, tools/autonomous/lib/vendor-selection-native.js:12, tools/autonomous/codex-bridge.js:763. A grep for `bwrap\ | bubblewrap\ | firejail over tools/systemd/ and tools/autonomous/ returned **no hit in any opened file**. The main agent loop runs under the user uid with bypassPermissions`. | 3 | The reviewer lane is sandboxed; the lane that writes code and runs shell is not. Pattern matching (patterns.js) is the only barrier, and pattern matching is not isolation. | |||||||||
| 9 | Inter-agent communication | ASI07 Insecure Inter-Agent Communication | Postbox messages are signed and integrity-stamped: tools/autonomous/lib/postbox-integrity.js:346 stampIntegrity, :369 verifyIntegrity, :242 computeChecksum; tools/autonomous/lib/assert-signed-task.js; production consumers poller-file-pickup.js, task-create.js, task-deps.js, dead-letter-alert.js. | 6 | The postbox lane is properly authenticated. The in-session Agent/Task spawn lane is not: the mastermind + taskman mandate reaches a sub-agent as plain prompt text with no signature, and a sub-agent's returned report is trusted prose (C105 receipts are a claim set, verified only if the parent chooses to re-run them). | |||||||||||
| 10 | Cascading failure / blast radius | ASI08 Cascading Failures — blast-radius amplification | C87 isolated worktree lanes; merge queue is ff-only; permissions.deny blocks git worktree remove -f, git branch -D, git push --force, --no-verify. But tools/eidos/vendor-gate-manifest.json → sessionScopeFence.description: "RETIRED AS A BLOCKING MECHANISM by ADR-0005 (2026-09-05) … a bookkeeping failure now restricts ONE OPERATION, never the session." Every vendor row reports enforcement.fence: "advisory". | 4 | Git-level blast radius is well contained. Runtime blast radius is not: the one mechanism named "fence" is a recorder. Nothing caps how many tool calls, files or services one session may touch. | |||||||||||
| 11 | Rogue agent / misalignment detection | ASI10 Rogue Agents (Replit meltdown cited); ATLAS AML.T0124 Autonomous Attack Orchestration | Stop gate measured over 1,193 runs: destructive_ops was the charged SAFETY row on 2 of them. No behavioural baseline, no rate/anomaly profile per agent, no drift detector on agent action distribution. | 2 | The only rogue-behaviour detector is a regex on the command string at the moment of execution. Nothing notices an agent behaving differently from itself over a session or a week. | |||||||||||
| 12 | Tamper-evidence of the governance plane | ASI04 + ACS Inspect; the plane that enforces everything must itself be attested | tools/safety/.hashes.json, generatedAt 2026-09-19T22:15:59.641Z, 23 attested files. Verified by sha256 this run: 21 match, 2 in DRIFT — tools/eidos/mastermind-ask.js and .claude/hooks/pre_tool_use.js (the gate producer and the tool guard). tools/safety/lib/integrity.js:24 documents the intended response: "mismatch → bootCheck writes EMERGENCY_LOCK → every hook blocks → fleet stops". tools/safety/lib/emergency-mode.js:31-33: isEnforcementArmed() returns process.env.MPRO_SAFETY_EMERGENCY_LOCK === '1'; the variable is UNSET in this process and set in no .json/.service/.sh in the master tree; .tmp/safety/EMERGENCY_LOCK does not exist. | 2 | The alarm detects and cannot act. Two of the most security-relevant files in the harness are unattested right now. (Independently confirmed: the same finding already sits unclosed in .wt/*/docs/report-forgotten-tasks/harvest.json:55041 — this is a known open finding, not a new discovery.) | |||||||||||
| 13 | Evaluation & measurement | ASI01–10 expect continuous adversarial testing; ACS Trace expects measurable outcomes | Present: tools/eidos/model-evaluation-gate.js, model-evaluation-execution.js, learned-artifact-holdout-eval.js, design-redteam-check.js, completion-evaluation.js, mastermind-ask.task-scope-adversarial.test.js. | 3 | All of it evaluates model output quality. There is no red-team suite that attacks the harness itself along ASI01–ASI10 — no indirect-injection corpus, no privilege-escalation probe, no memory-poisoning test. | |||||||||||
| 14 | Regulatory posture (EU AI Act) | Commission page (updated 2026-08-03): prohibitions from 2025-02-02; GPAI governance from 2025-08-02; general high-risk 2027-12-02; regulated-product high-risk 2028-08-02; AI Omnibus in force 2026-07-27 | UNMEASURED. I did not measure whether any MPRO surface (the eshop advisory flows, the Telegram bots, the marketing lanes) falls under an Annex III high-risk category, and I did not open the article-level obligations. | n/a | Stating a score here would be the exact failure this report exists to name. The finding is that MPRO has not classified itself, and the general high-risk deadline of 2027-12-02 is 27 months out — enough time only if the classification starts now. |
This is the section the CEO's question points at. Each row below would read as a control on a compliance checklist and is not one.
| Looks like | Measured reality |
|---|---|
| "The Stop gate blocks bad work." | 1,193 runs, 2026-09-19T17:10:57Z → 2026-09-20T00:42:38Z, 458 sessions: PASS 0 · UNSCORABLE 961 (80.6 %) · FAIL 186 (15.6 %) · ADVISORY 46 (3.9 %). mastermind-terminal-policy.js:283-299 — both ADVISORY and UNSCORABLE resolve blocking:false, mayProceed:true. PASS never happens, so "the gate passed" is not a state anyone has seen; agents learn that UNSCORABLE is normal. |
| "The gate is a security gate." | Of 201 charged SAFETY rows across the 185 blocking runs: unproven_claims 95, action_claim_unproven 30, behavioral_verify_missing 14, real_life_test_skipped 12, consolidation_claim_unproven 11, effect_check_nondiscriminating 11, surface_claim_unproven 10, model_claim_ungrounded 5, values_contract_runtime_gap 4, model_evaluation_claim_unproven 3, fake_tests 3, destructive_ops 2, factual_claims 1. It is an excellent truthfulness gate. It blocked a destructive operation twice in 1,193 runs. |
| "HARD_POLICY items are CEO hard stops." | tools/eidos/two-tier-gate.js:107-118 — HARD_POLICY_ITEMS contains exactly one member, money_loss_risk_ungated, and its own comment records "0 of 16,565 gate runs over 7 days". Measured again here: 0 of 1,193. The tier is real in code and empty in practice. |
| "The session-scope fence contains a session." | vendor-gate-manifest.json → sessionScopeFence: retired as blocking by ADR-0005 (2026-09-05); it records and reports. Every vendor's enforcement.fence is "advisory". The word "fence" now names a ledger. |
| "Integrity monitoring protects the guards." | Row 12 above. Detection works; the response is MPRO_SAFETY_EMERGENCY_LOCK-gated and that switch is set nowhere. Two files are in drift as I write this. |
| "The tool guard inspects every call." | .claude/hooks/pre_tool_use.js:2386-2399 is fail-open and the file records its own 9-day silent failure: a renamed variable made every Bash call throw ReferenceError from 2026-09-05 to 2026-09-14 while every call reported approve, exit code 0, no trace anywhere. |
| "Stop hooks fail closed." | vendor-gate-manifest.json → gateFailurePolicy: 6 of 9 shared Stop scripts are fail-open (adr-lifecycle-hook.js, context-budget-stop-hook.js, context-window-stop-gate.js, context-ceiling-hook.js, insight-capture.js, learning-capture.js); only mastermind-stop.js, non-stop-loop-stop.js and stop.js are fail-closed. |
| "All ten vendors are governed." | vendor-gate-sync-check.js --json run this session: parityOk:true, roster of 10. But zen, max and ollama each carry enforcement: {sharedGates:"absent", quality:"advisory", fence:"absent", terminalEvidence:"absent"} and gateCapable:false; opencode has sharedGates:"advisory"; antigravity carries the caveat gate_capable_without_terminal_evidence and 6 waived events. parityOk:true is honest about what it measures and is read as "all vendors covered". |
| "MCP calls are validated." | vendor-gate-manifest.json → mcpPreDispatch.vendors.*: exactSchema:false, producer:null, attestation:null, reason:"air_gap:no_host_owned_pre_dispatch_schema_attestation" — for every vendor. |
| "C107 six-dimension check enforces safety review." | .claude/rules/values-bhagavad-gita.md:157-158 states it plainly: task_dimension_unnamed (−1) and refactor_debt_unnamed (−1) are advisory, capped at −2 by construction. Measured this run: task_dimension_unnamed charged on 248 of 1,193 runs and blocked none. |
The systemic shape: MPRO's enforcement is strongest where a claim is made (satya, reports, done-flips) and weakest where a byte enters or leaves (web content, MCP output, memory writes, sub-agent reports). That is exactly inverted from ASI01–ASI10, whose top three risks are all about what enters the agent.
Standard: ASI01 Agent Goal Hijack (OWASP, 2025-12-09, fetched 2026-09-20) — ranked #1 of 10, canonical case EchoLeak (zero-click exfiltration via content the agent merely read). Also ASI06. Evidence: screenInboundContent (tools/eidos/inbound-content-safety.js:100) has three production consumers, all in tools/news-monitor/. PostToolUse is registered for TodoWrite|Bash|Read|Write|Edit|Task|Agent and not for WebFetch, WebSearch or mcp__.*. Smallest change: add one PostToolUse entry in .claude/settings.json with matcher ^(WebFetch|WebSearch|mcp__.*)$ pointing at .claude/hooks/post_tool_use.js, and in that file route hookData.tool_response (already read at :1381) through screenInboundContent. The screen already returns a hash and never re-surfaces quarantined content, so the fix is additive and reversible. One settings entry + one call site. What we would lose: an agent with repo write access, a live vault credential, git push rights and a bypassed permission layer, taking its next instruction from a web page. The damage is not "a bad answer" — it is a commit, an email, or a credential read, performed under our identity, that looks exactly like normal agent work in every log we keep.
Standard: ASI04 Agentic Supply Chain; ACS pillar Inspect (ACS v0.1.0, fetched 2026-09-20). Evidence: 2 of 23 attested files in drift right now (tools/eidos/mastermind-ask.js, .claude/hooks/pre_tool_use.js); tools/safety/lib/emergency-mode.js:31-33 proves the lock is disarmed; .tmp/safety/EMERGENCY_LOCK absent. Smallest change: do not re-arm EMERGENCY_LOCK — it was disabled 2026-05-24 for false positives and re-arming it would wedge the fleet (ahimsa, C96). Instead add one item to SAFETY_ITEMS in tools/eidos/two-tier-gate.js:25 — governance_binary_drift — fed by a check that calls the existing verifyHashes and charges only when a protected governance file mismatches and is not git-dirty-and-owned by this session. Effect: an agent cannot flip "done" while the guard it ran under is unattested; no process is ever killed. What we would lose: the one file that decides whether any agent may say "done", and the one file that decides whether any shell command runs, can both be edited with nothing stopping it and nothing reacting. Every other control in this report is downstream of those two files. If they are wrong, all fourteen rows above are decoration.
Standard: ASI02 Tool Misuse; ACS pillar Instrument — the Guardian must decide before execution. Evidence: .claude/hooks/pre_tool_use.js:2386-2399, including the file's own measured record of 9 days of silent total failure (2026-09-05 → 2026-09-14). Smallest change: in that same catch block (which already writes a stderr line nobody reads), also write .tmp/safety/pre-tool-use-internal-error-<session_id>.json; then have .claude/hooks/mastermind-stop.js raise a SAFETY row when one exists for the session. Fail-open is preserved — the tool call still proceeds — but the session cannot end claiming success while its guard was dead. What we would lose: a repeat of September, except during an incident. Nine days is not the worst case; the worst case is nine days that overlap a compromise, with every log line saying approve.
Standard: ASI06 Memory & Context Poisoning (OWASP, 2025-12-09). Evidence: 1,179 files at ~/.claude/projects/-home-darius-MPRO/memory/, in no tier of tools/safety/critical-file-guard.js, in no entry of tools/safety/.hashes.json, outside git. Smallest change: add the resolved memory path to TIER3_PREFIXES at tools/safety/critical-file-guard.js:58 (1-layer confirm + backup, the tier already used for .claude/agents/ and .claude/skills/). That gives a backup of every memory write with no new subsystem. What we would lose: memory is the only MPRO surface where a wrong fact persists and compounds. A poisoned entry ("the vault key for X lives at Y", "the gate is known-broken, skip it") is read by every future session of every vendor, is never diffed, has no history to roll back to, and looks exactly like the 1,178 true ones.
Standard: ASI03 Identity & Privilege Abuse; the fetched OWASP mitigation is explicit — short-lived credentials, agent identity isolated from user identity. Evidence: tools/mpro-taskman/lib/agent-auth.js:24-28; no expiry/rotation symbol in 238 lines. Smallest change: bind a coarse time window into the derivation — HMAC(shared, "ctx:"+agent+":"+floor(epoch/3600)) — and have the verifier accept the current and previous window. A leaked credential then dies within two hours. It is a two-line change in one function plus the matching two lines in the verifier, and it needs no new storage, no key service and no rotation schedule. What we would lose: today a credential that leaks once (a log, a transcript, a crashed process dump) is valid forever, for that agent, against the whole task board — and because the derivation is deterministic from a shared secret, anyone holding that secret can already speak as any agent. The board is our audit trail; an audit trail that can be written under a forged name is not one.
zen, max, ollama resolve zero shared gates (vendor-gate-manifest.json → vendorTiers). They are honestly waived, which is correct, but three of ten vendors run ungoverned by anything except postbox dispatch.mcpPreDispatch.exactSchema:false on all six gate-capable vendors: MCP tool arguments are dispatched with no schema attestation (ASI02 parameter injection)..agents/skills/ (207 skills, the vendor-neutral plane) is in no protection tier while .claude/skills/ (175) is TIER3.Stated so the gaps above are read in proportion — each measured this run:
tools/eidos/outbound-autonomy-policy.js:16-21, 20+ consumers). Most harnesses have nothing here.tools/autonomous/lib/postbox-integrity.js:346,369) — ASI07, addressed..mcp.json are localhost or local scripts — ASI04's most common vector is simply absent by construction.[SECRET OUTPUT GATE] blocked one of my own commands this session and [SECRET OUTPUT REDACTED] masked a credential-shaped value from another. A control that fires on the auditor is a real control.pre_tool_use.js:2386-2399 and the reverted-fix note at mastermind-terminal-policy.js:265-282 are the reason gaps 2 and 3 could be stated with dates instead of guesses.mastermind-ask.js or any gate, did not restart a service, and changed no file in the repo. All MPRO figures are read-only observations of the live tree and the live taskman API at 2026-09-20.Prepared by the MPRO opus-xhigh sub-agent (claude-opus-5, effort xhigh) for claude_code (CTO). Read-only run; no repo file changed.
Your Gemini brief, answered rather than asked back. Every probing question is kept and answered from live evidence, across Concept, Architecture, Operations and Governance — then the practices worth taking are marked ADOPT and the ones that fight our architecture are marked REJECT with the reason, never dropped in silence.
sources/orchestration-pillars.md)Kept separate on purpose: a finished row in a "what is left" list is the defect the CEO named directly ("why keep in report require action and already does not need"). These are done, with the commit that did it — content-verified on origin/master, because cherry-land rewrites shas.
| What was fixed | Where | Commit on master |
|---|---|---|
The cold-minded rule named 4 enforcement mechanisms that do not exist while printing −2/−2/−1 weights beside them; corrected in place with a measured Built? column | .agents/skills/mpro-agent-orchestration/references/cold-minded-retention.md | 98f7beaae96 |
The 2026 harness bar (HARNESS-ORCHESTRATION-BAR) added to the same rule | same file | landed 98f7beaae96 |
| The gate caught a second copy introduced one run earlier in the pointer stub — a restatement inside the very file that teaches against second copies. Removed, not defended. | .claude/rules/cold-minded-retention.md | landed 0611b12611c |
mpro-orchestrate does not exist. git grep -lI "mpro-orchestrate" over all 25,366 tracked files returns nothing (exit 1). Nothing in this repo is named that. The CEO's question — "or how we call it properly" — has a real answer and the real answer is a finding: the layer has no single name, and its seven parts are addressed by seven different identifiers.
The true name, derived: the layer is the MPRO Orchestration Harness. It has exactly one machine-readable address that already reaches every vendor — the declared constitutional marker C91:ORCHESTRATION-MODEL, present in 17 tracked files — and one documentation home, the skill mpro-agent-orchestration (104 tracked files). Use those two; do not invent a third.
Its true composition, measured 2026-09-20:
| Part | What it is | Measured |
|---|---|---|
| Doctrine | mpro-agent-orchestration skill + its references/ bodies | 104 tracked files |
| Marker | C91:ORCHESTRATION-MODEL (constitution C91) — the carrier that reaches non-Claude vendors | 17 tracked files |
| Roles | .claude/agents/*.md | 102 files = 51 roles + 51 generated <SHORT>-<model><version>-<effort> aliases (51 carry the GENERATED FILE marker) |
| Gate | tools/eidos/ deterministic checks + mastermind-ask.js | 310 *-check.js (non-test); mastermind-ask.js is 20,752 lines carrying 220 distinct item:'…' gate ids |
| Ledger | tools/mpro-taskman/ on the mpro_graphs Postgres DB (graph.task_nodes / task_edges / task_changelog) | 3,246 open · 7 in_progress · 3,444 done (incl. archive) |
| Transport | postbox/ (38 directories) + tools/autonomous/*bridge*.js | 35 bridge modules |
| Isolation | git worktree lanes via tools/scripts/agent-git.sh | 151 live worktrees |
Three of those seven — doctrine, marker, roles — are governance; four are running infrastructure. A layer whose name nobody can state is itself the finding, and naming it is recommendation #0: say "the MPRO Orchestration Harness (C91:ORCHESTRATION-MODEL)", never "mpro-orchestrate".
The brief the CEO pasted attributes a specific vocabulary to industry research. Three of those terms do not appear in the primary material. I searched the full AgentField corpus — 6 blog posts, 1,387,437 bytes of raw HTML, plus the 491.8 KB machine-readable docs corpus — fetched 2026-09-20:
| Term in the brief | Occurrences in primary AgentField material | Verdict |
|---|---|---|
| "middle loop" | 4 | REAL — sourced below |
| "compaction" / "lossy" | 10 / 2 | REAL — sourced below |
| "60k" | 2 | REAL, but it is not a "leak" — see below |
| "computational vs inferential" guides/sensors | 0 ("computational" 14, always in "computational object") | UNVERIFIED as attributed |
| "Initializer + Worker Harness" pattern | 0 | UNVERIFIED as attributed |
| three-tier "Raw / Reversible / Lossy" compaction | 0 | UNVERIFIED as attributed |
Those three are good questions with no source I could find. I answer them anyway (a question does not need a pedigree to be worth answering) — but I score nothing against them as an "industry standard", because inventing a standard to grade ourselves against is exactly the failure this report exists to prevent.
What the primary material actually says:
RETRY_MODIFIED, RETRY_APPROACH, SPLIT, ACCEPT_WITH_DEBT, ESCALATE_TO_REPLAN. (AgentField, 2026-04-23 and 2026-03-18.)CLAUDE.md, a README for a deprecated module, four conflicting style guides, and 40 MB of build artifacts. (AgentField Part 2, 2026-05-05.) This is the "60k" in the brief — it is not a leak, it is the workspace.| # | Probing question | Our measured answer (this run) | Ideal state (cited) | Anti-pattern | Verdict |
|---|---|---|---|---|---|
| 1.1 | How many of our guides/sensors are deterministic code vs an LLM judging? | 310 of 310. Every tools/eidos/*-check.js (non-test) is deterministic: refined grep for an actual model invocation (require(…llm-gateway), callLLM, /api/generate, /v1/chat/completions, messages.create) returns 0 across all 310. The inferential tier is 6 separate files (cross-model-judge.js, model-evaluation-gate.js, completion-evaluation.js, pre-task-judge.js, judge-plan.js, tools/eval/llm-judge.js); only completion-evaluation.js spawns a process. | Augment Code: constraint harnesses first, feedback loops second, quality gates third — preventive before corrective. A deterministic gate is the cheapest preventive control there is. | A gate that asks a model whether the work is good. Non-reproducible, unfalsifiable, and it charges tokens on every turn. | 9/10. This is MPRO's strongest structural property and it is ahead of every vendor I fetched. The −1 is that nothing states the rule out loud, so nobody knows it is a rule. |
| 1.2 | Is our context injection just-in-time or monolithic? | Both, measured. Eager tier: CLAUDE.md 20,083 B + .claude/rules/*.md 103,420 B = 123,503 B ≈ 30,875 tokens on every prompt. Lazy tier: 477 references/*.md = 4,587,658 B ≈ 1,146,914 tokens, loaded on demand — a 37x deferral. But of 194 rules only 118 are MUST-pointer stubs (12,082 B ≈ 3,021 tok); 76 are still full text (91,338 B ≈ 22,835 tok), i.e. 74% of the eager rule cost is the un-migrated 39%. | Anthropic 2025-09-29: keep "lightweight identifiers" and load at runtime. The MUST: pointer IS that pattern, done well. AgentField 2026-05-05: the workspace is the largest prompt the harness ever sees. | Loading the whole governance corpus into every turn. Also: .claude/hooks/lazy-rule-injector.js:5 still says "ALL 30+ rule files… ~11.7K tokens" — a printed cause the code never verified (C107 ⑥b); reality is 194 files ≈ 25.9K tokens. | 7/10. The architecture is right and 61% migrated. Finishing the other 76 is the single largest measured token win available. → row 5. |
| 1.3 | Are .claude/agents/ roles or steps? | Roles, and provably so. 102 files = 51 roles + 51 generated aliases (51 carry GENERATED FILE — do not hand-edit, regenerated by generate-versioned-agent-aliases.js). An alias is a projection of model x effort into the statusline, not a second role — a genuinely lossless duplication. | Claude Code subagent docs: a subagent is "specialized… its own isolated context window with a custom system prompt, specific tool access, and independent permissions" — a role contract, not a pipeline stage. | 102 pipeline steps masquerading as agents; or hand-editing a generated alias so a name drifts from the policy that derives it. | 9/10. The 1:1 role→alias generation with a name-vs-policy check (agent-name-model-version-check.js) is a better answer than the brief's question assumed. |
| 1.4 | Is the workspace itself engineered, or inherited? | Inherited. This lane — created for a two-file prose edit — is 1.6 GB with 97 top-level entries. node_modules is absent (good); CLAUDE.md is present (correct — it carries the values). Nothing shapes the lane workspace to the task: agent-git.sh has no workspace-shaping step. | AgentField 2026-05-05: "This is the most undervalued lever in current systems." | Shipping a worker into a directory holding "40 megabytes of build artifacts the agent will grep." We ship 1.6 GB. | 5/10. Honest verdict: the lever exists in the vendor (isolation: worktree) and we use it for safety, never for context shaping. |
| # | Probing question | Our measured answer (this run) | Ideal state (cited) | Anti-pattern | Verdict |
|---|---|---|---|---|---|
| 2.1 | Do we have the "Initializer + Worker Harness" pattern, and what is it called here? | Partly, unnamed, and the term is UNVERIFIED as an industry standard (0 hits in the primary AgentField corpus). What we have: .claude/agents/orchestrator.md (+ OR-opus5-xhigh) with isolation: worktree, permissionMode: auto, and Agent in its tool allowlist. Only 3 of 102 agents can spawn a child (orchestrator, campaign-orchestrator, consilium) — stated in orchestrator.md's own header; every other agent is structurally incapable of fan-out, capping depth at one level. The initializer half (shaping the worker's workspace, see 1.4) does not exist. | Anthropic 2025-06-13: a lead agent "analyzes… develops a strategy, and spawns subagents", checkpointing its plan to memory before the window truncates. | A brief that emphatically tells an agent to delegate while its tools: allowlist makes delegation impossible. MPRO already hit this and wrote it down. | 7/10. Spawn side: strong and self-documenting. Initialize side: absent. |
| 2.2 | Map our compaction onto Raw / Reversible / Lossy. Which tier do we NOT have? | We have all three, and the taxonomy is UNVERIFIED as an industry term — but it maps cleanly. Raw: full transcripts on disk — 2,895 .jsonl, 8.0 GB; this session alone is 92,694,318 bytes. Reversible: compact-restore-policy.js (30,337 B) re-injects a bounded wisdom kernel (values + C93 + goal titles) with reserved WISDOM_KERNEL_HEADROOM, and post-compact-reload.js (25,058 B) regenerates P1-P5 (gate questions, pipeline state, memories, tasks, events) from durable stores, not from the summary — that is what makes it reversible. Lossy: the host's own summary, mined afterwards by post-compact-distill.js (8,422 B) into the KB. Plus context-compactor.js, which explicitly adopts the Anthropic cookbook. | AgentField 2026-05-05: "The agent at turn 40 is operating against a paraphrase of the rules it was given at turn 0." The fix is exactly a lossless kernel that survives compaction. | Letting the lossy summary be the only survivor. MPRO does not do this. | 9/10. The WISDOM_KERNEL_HEADROOM reservation — so a later value line cannot silently crowd out the budget — is a better answer than the question expected. |
| 2.3 | Our equivalent of the "60k token leak"? | Measured, and it is not a leak — it is a deliberate 30,875-token governance corpus (1.2). AgentField measured foreign workspaces at 30,000-60,000 tokens the orchestrator "never typed"; MPRO typed all of it, versions it, and reviews it. Same order of magnitude, opposite provenance. The genuinely unintended part is the 22,835 tokens in 76 rules that were supposed to become pointers and did not. | AgentField 2026-05-05, verbatim: "You wrote 4K. The agent read 60K." | Repeating "60k token leak" as our own number. I did not measure a leak and I do not claim one. | 7/10. Honest score: the corpus is intentional; the 22.8k residue is not. |
| 2.4 | How does state cross an agent boundary — files or a shared window? | Files, four independent channels, none of them a shared context window. (a) taskman on Postgres mpro_graphs — the authority; (b) postbox — 38 directories, HMAC-signed by postbox-integrity.js; (c) C105 receipts — subagent-receipt.js + subagent-receipt-verify.js, where the parent RE-RUNS the child's claims; (d) git worktree lanes — 151 live. | Anthropic 2025-09-29: sub-agents "return condensed summaries (typically 1,000-2,000 tokens)". Anthropic 2025-06-13: checkpoint to memory before truncation. | Passing state by letting two agents share one window. MPRO structurally cannot. | 9/10. "A receipt is a CLAIM SET, never proof — the parent re-runs it" is stronger than anything I fetched from a vendor. |
| 2.5 | Topology: hub-and-spoke, mesh, or hierarchical? | Hub-and-spoke with a hard depth cap of 2 (2.1: 3 of 102 agents hold Agent). Cross-vendor work is mesh-shaped but routed through postbox, not peer-to-peer. One measured exception: tools/consilium/consilium.js:53 defaults to SUPERMAJORITY — a symmetric peer vote, which the cold-minded rule itself flags as the topology measured at 99.2% escalation-of-commitment. | OpenAI: manager pattern (edges = tool calls) vs decentralized (edges = handoffs); ADK 2.0 GA names sequential / loop / parallel / graph / dynamic / collaborative / agent-routing. | A symmetric peer vote deciding continue-vs-abandon. We still have one, and our own rule says so. | 7/10. Topology is sound; the consilium default is a known, named, still-open exception. |
| # | Probing question | Our measured answer (this run) | Ideal state (cited) | Anti-pattern | Verdict |
|---|---|---|---|---|---|
| 3.1 | Is there real physical storage for candidates, revisions, events, provider choices? | Yes — Postgres, not a file. mpro_graphs (graph.task_nodes, task_edges, task_changelog, append-only), reached only through :3018; direct SQL is forbidden by rule. Live counts: open 3,246 · in_progress 7 · done 1,255 board / 3,444 incl. archive. Provider choice is stored per lifecycle field (created_by/claimed_by/finished_by/verified_by, each with model + effort). Raw event storage: 8.0 GB of transcripts + postbox/ + a 12-circuit breaker registry. | ADK 2.0 GA keeps state on the session; Anthropic 2025-06-13 checkpoints the plan to memory. | A JSON file pretending to be a database. MPRO has 38 postbox directories that are that, but the authority is not among them. | 9/10. Provenance-per-lifecycle-field is ahead of every vendor doc I fetched. |
| 3.2 | What is the "middle loop" — what happens when inner retries are exhausted? | There is no middle loop for tasks. .claude/hooks/pipeline-state.js:52 sets maxLoops = 10; lines 94-98 set escalated = true and print "Human intervention required." A repo-wide grep for an automated re-scope decision (ACCEPT_WITH_DEBT, RETRY_APPROACH, "split the issue", "re-scope") returns no implementation — only prose in onboarding docs and one unrelated comment. There IS a middle loop for vendors: 12 circuit breakers (grok_intel OPEN, gemini OPEN, claude_code/ollama/antigravity/kimi/opencode HALF_OPEN) that re-route on vendor failure. | AgentField 2026-04-23: the middle loop "decides whether to split the issue, change the approach, or relax the scope with explicit typed debt", and on its final invocation is biased toward acceptance or escalation rather than another futile retry. OpenAI names the same trigger: "Exceeding failure thresholds… escalate to human intervention." | Escalating structural failure to a human. This is the mechanism behind the CEO's own complaint quoted in CLAUDE.md: "on every session multiple times i must remind to continue, to pick up the rest in reports leftovers." We route vendor failure automatically and task failure to him. | 4/10 — the lowest score in this report, and the highest-value fix. → row 3. |
| 3.3 | Transition validation — can a rejected draft trigger a downstream job? | Structurally no, and it is enforced at write time. done is provisional; validated is computed by an independent validator that re-runs the persisted allowlisted effect_check. Write-time binding (HTTP 422) refuses a deliverable edge whose effect_check is not byte-identical to the node's verify. Measured in one population: 1,110 validated of 3,444 done (incl. archive) = 32.2% (board-only 301/1,255 = 24.0%). A failed check reopens the source node. Parallel lifecycle: 30 ADRs under docs/adr/ with tools/scripts/adr-check.sh. Land path is fast-forward-only (merge-base --is-ancestor before push). | Augment Code: corrective controls detect violations and trigger a response. OpenAI: tool safeguards gate high-risk actions before execution. | Reading done as done. The contract states loudly that it is not. | 8/10. The mechanism is excellent; 67.8% of completed work has never been independently re-verified, which is a throughput fact, not a design flaw. |
| 3.4 | Observability — if a job fails at 03:00, does anything say why? | Mostly, with a measured hole. Full population, postbox/failed/ = 337 files, 0 unparseable: 231 rejected · 76 failed · 29 approved · 1 pending. Reasons: 102 SEC-019: signature_mismatch + 77 Invalid signature: signature_mismatch + 12 SEC-019: missing_signature_fields = 191 (56.7%); then 32 self-referential grok_intel→grok_intel; 26 module-load errors; 8 empty prompt; 8+2 Kimi quota; 6 empty_or_unparseable_verdict. 15 records carry no reason in any field. Daily volume 2026-09-19: 126 failed vs 151 completed. dead-letter/ holds 352. | Anthropic 2025-06-13: "letting the agent know when a tool is failing and letting it adapt works surprisingly well." | A silent failure is an outage nobody is paged for (C107 ②). 15 records are exactly that; 191 signature rejections are loud but undiagnosed — nobody has said whether that is the guard working or the signer broken. | 6/10. → row 7. |
| 3.5 | Do we know which lifecycle events we can even observe? | No — measured today, and this is the report's sharpest single finding. Claude Code documents 33 hook events. MPRO registers 30 hook entries across 10 events. 23 events are unwired, including SubagentStart, TaskCreated, TaskCompleted, PostToolUseFailure, PostToolBatch, PermissionRequest, PermissionDenied, WorktreeCreate, WorktreeRemove, InstructionsLoaded, PreModelSwitch. SubagentStart is the precise sensor the known orchestration_missing blindness defect needs — that defect is already filed (problem:gate.orchestration-missing-blind-to-agent-tool-dispatches, status deferred) and says the ledger records only postbox dispatches, never Agent-tool spawns, so an orchestrator that delegates correctly is scored as if it ground solo. | The vendor's own contract, fetched 2026-09-20: PreToolUse exit 2 "Blocks the tool call"; Stop exit 2 "Prevents Claude from stopping"; WorktreeCreate exit 2 "Aborts worktree creation". | Building a sensor in userland when the vendor already emits the event. We deferred a defect whose sensor shipped. | 5/10. → row 4. |
| # | Probing question | Our measured answer (this run) | Ideal state (cited) | Anti-pattern | Verdict |
|---|---|---|---|---|---|
| 4.1 | Rank our hierarchy of interventions — which rung do we over-use? | Counted: 194 rules · 477 reference bodies · 310 deterministic checks · 30 hook entries · 102 agent roles · 6,570 test files · 136 files touching cross-model/consilium/peer-review. The ratio that matters: 477 documents to 310 executable checks. Augment Code's prescribed order is constraints → feedback → gates; MPRO's mass sits on documentation, the rung that cannot fail a build. | Augment Code, 2026-04-16/2026-06-29: "The Context Engine handles what can be inferred from the codebase; rules files are reserved for what cannot be inferred." | Answering a defect with a document. MPRO's own kaizen rule already forbids it ("every found defect becomes an ENCODED check, never prose alone") — and the corpus shows the rule is followed unevenly. | 7/10. The encoded-check discipline is real (310 of them); the prose tier grows faster. |
| 4.2 | Do we use LLM-as-judge for non-functional requirements, and is the judge graded? | Judges: yes. Graded: almost nowhere. Six judge surfaces exist (1.1). Inter-rater grading exists exactly once, in a venture: tools/previd/lib/judge-agreement.js computes Krippendorff's alpha with a TDD case pinning "Perfect disagreement, 4 units, 2 raters: alpha = −0.75 EXACTLY". The harness gate does not use it — tools/eidos/learned-artifact-outcome-scorer.js:32 only mentions it in a comment ("Mirrors the insufficient_data posture already established in…"). | Anthropic 2025-06-13: a single-prompt judge outputting "scores from 0.0-1.0 and a pass-fail grade was the most consistent", paired with human testing that catches "edge cases that evals miss." | An ungraded judge. Its verdict is an opinion with a badge. We built the grader and left it in one venture. | 6/10. The capability exists and is unpromoted — a yokoten failure, not a capability gap. |
| 4.3 | What stops the loop handing an agent conflicting requirements? | Four named mechanisms, all live. (a) an explicit precedence order in values-bhagavad-gita.md:31 — values+goals → safety → constitution/CLAUDE.md/rules → local task; (b) C96 passability — a gate that blocks authorized work is itself the defect; (c) charge caps — task-dimension-check.js:49: "cap at −2… It can never stack into a blocking floor, and it never touches the −3 tier"; (d) inversion clauses — rules 7 and 9 of the values file each state what they destroy if read wrongly, with load-bearing guards. | Augment Code: "Over-constraining is a real failure mode. Complexity limits set too low flag legitimate refactoring." | A governance corpus that grows monotonically with no cap and no inversion. MPRO explicitly engineered against this. | 9/10. The written inversion clause is the single practice here I found in no vendor source. |
| 4.4 | Does our retention rule meet its own standard? | No — measured today, in scope, and now fixed. cold-minded-retention.md's enforcement table lists 7 mechanisms with weights (−2, −2, −1). Four of the files it names do not exist anywhere in the repo: consilium-escalation-guard.js, keep-decision-authorship-check.js, reverse-pilot.js, keep-justification-check.js — and grepping tools/eidos/ and .claude/hooks/ for those names returns zero references. Only done-status-review.js (cited as reused machinery) exists. The rule also cites consilium.js:52; the live line is 53. | The rule's own rule 3: "Removal is proven by absence, not by grep." And satya: a weight printed for a check that does not exist is a claim wider than the measurement. | A rule that asserts enforcement it does not have. This is C107 ⑥(b) — a printed cause the code never verified — inside the file whose job is to catch exactly that. | 3/10 before this session; corrected in place — see Step 4, LANDED. |
| 4.5 | Are our own counts derived or typed? | Typed, and stale. CLAUDE.md:29 says rules (187), skills (172), agents (102); actual today: 194 / 169 / 102. CLAUDE.md:42 says "50+ modular rules" against 194. lazy-rule-injector.js:5 says "ALL 30+ rule files… ~11.7K tokens" against 194 ≈ 25.9K. | model-roster-single-source.md rule 1, already binding here: "NEVER type a vendor or model count. Derive it." The same argument applies to every count. | A second copy of a fact that changes (C107 ⑥a). Three copies found in two files. | 5/10. → row 6. Out of my scope to edit; delegated with an address. |
| Dimension | Anthropic (Claude Code) | OpenAI | Google (ADK) | MPRO |
|---|---|---|---|---|
| Lifecycle sensors | 33 documented hook events, exit-2 blocking semantics per event (fetched 2026-09-20) | Guardrails as code in the Agents SDK; no comparable host-lifecycle hook surface in the guide | Workflow primitives (sequential/loop/parallel/graph/dynamic/collaborative/agent-routing), ADK 2.0 GA | 10 of 33 wired, 30 entries. BEHIND on coverage; AHEAD on what each hook does |
| Sub-agent contract | Own context window, own system prompt, tool allowlist, model, permissionMode, memory, skills, isolation: worktree, omitClaudeMd | Manager pattern (tool calls) vs decentralized (handoffs) | Coordinated sub-agents under a parent | Uses the full vendor contract, plus 51 generated model x effort aliases so the tier is visible in the statusline — no vendor ships this |
| Context strategy | Just-in-time identifiers; compaction + note-taking + sub-agents (2025-09-29) | Not addressed in the guide | Session state | 37x lazy deferral via MUST-pointers, plus a bounded lossless wisdom kernel across compaction. AHEAD of all three on the kernel; the 76 un-migrated rules are our own residue |
| Guardrail taxonomy | Hooks + permissions | 7 named types incl. per-tool risk rating (read-vs-write, reversibility, financial impact) | Not enumerated in the fetched page | 310 deterministic checks, 0 model-judged. AHEAD on determinism; BEHIND on per-tool risk rating — we have no tool-risk tier at all |
| Failure escalation | Graceful degradation over restart; checkpoint the plan (2025-06-13) | Two triggers: failure thresholds, high-risk actions | Loop agents with exit conditions | Vendor failure: 12 circuit breakers (ahead). Task failure: straight to human (behind AgentField's middle loop) |
| Judge grading | Single-prompt 0.0-1.0 + pass/fail, paired with human testing | Not addressed | Not addressed | Krippendorff's alpha exists — in one venture, unpromoted |
| Cost posture | Multi-agent ≈ 15x chat tokens | "Start simple, add complexity only when needed" | — | Values rule 7 makes NET cost a hard gate; C107 caps its own charge at −2 |
Where the comparison is NOT meaningful: Anthropic/OpenAI/Google publish product contracts for many customers; MPRO is one operator's harness on a fixed fleet. Their "ideal state" optimises for generality, ours for one CEO's time. Scoring us "behind" on a generality feature we deliberately do not need would be a category error — which is why rows like ADK's graph workflows produce no MPRO gap here.
| # | Practice | Source (dated) | What it changes here | Smallest change that delivers it | Blast radius | Verdict |
|---|---|---|---|---|---|---|
| 1 | A rule may not print a weight for a check that does not exist | Our own satya standard; C107 ⑥(b) | Removes 4 phantom enforcement claims from the retention rule | Rewrite the M-table's status column with measured existence | 1 prose file | ADOPT — LANDED 98f7beaae96 |
| 2 | Middle loop: inner-exhaustion → typed re-scope, not a human | AgentField 2026-04-23 / 2026-03-18 | A retention/abandon decision gets one advisory pass before it reaches the CEO | State the rule in cold-minded (landed); build the advisor (delegated) | 1 prose file now; pipeline-state.js later | ADOPT — rule LANDED 98f7beaae96; build → task:harness.middle-loop-rescope-advisor-before-human-escalation |
| 3 | The workspace is a retained artifact and pays rent every prompt | AgentField 2026-05-05; Anthropic 2025-09-29 | Extends cold-minded retention from the registry to the context window | Add the workspace clause to cold-minded | 1 prose file | ADOPT — LANDED 98f7beaae96 |
| 4 | Wire SubagentStart + task-lifecycle hook events | Claude Code hooks doc, fetched 2026-09-20 | Fixes a deferred defect that punishes correct delegation | Add one hook entry; feed the existing dispatch ledger | .claude/settings.json + one hook script — >20 lines | ADOPT — delegated task:harness.wire-subagent-start-and-task-lifecycle-hook-events |
| 5 | Convert the remaining 76 full-text rules to MUST-pointers | Anthropic 2025-09-29 | ~22,835 tokens off every prompt of every session of every vendor | Mechanical, but 76 files x 2 | 76 rules + 76 reference bodies — far >20 lines | ADOPT — delegated task:harness.convert-76-full-text-rules-to-must-pointers |
| 6 | Per-tool risk rating (low/medium/high) driving escalation | OpenAI guide (no printed date), fetched 2026-09-20 | A missing tier: we gate by rule, never by tool risk | A risk map consumed by pre_tool_use.js | Touches a live peer's file this session | ADAPT — delegated task:harness.per-tool-risk-rating-tier; adapt, because our PreToolUse guard is already stricter on the paths it covers |
| 7 | Grade the judges (Krippendorff alpha) in the harness gate, not just PreVid | Anthropic 2025-06-13 + our own judge-agreement.js | An ungraded cross-model verdict becomes a measured one | Promote the existing module; add a consumer | tools/eidos/ — >20 lines | ADAPT — delegated task:harness.promote-judge-agreement-from-previd-to-the-gate |
| 8 | Counts are derived, never typed | model-roster-single-source.md (already binding) | 3 stale counts in 2 files stop being wrong | Generate the CLAUDE.md row | CLAUDE.md — out of my scope | ADOPT — delegated task:harness.claude-md-counts-derived-not-typed |
| 9 | Shape the worker's workspace to the task | AgentField 2026-05-05 | A 1.6 GB lane for a 2-file edit becomes a scoped one | A sparse-checkout profile per role | agent-git.sh — high risk to 151 live lanes | REJECT for now, grounded. Sparse-checkout would silently hide files from gates that scan the tree (git ls-files-based checks would see a different population) and would break every file:line proof convention in this harness. The cheap 80% — say what the lane is for — is covered by row 3. Revisit only with a gate-population proof. |
| 10 | Replace SUPERMAJORITY consilium default with a named decider | Barkett (cited in cold-minded); our own rule 4 | Removes the one symmetric-peer vote left | consilium.js default flip | Live deliberation tool, peer-owned | REJECT as a silent flip, grounded. The rule already forbids a peer vote for continue-or-abandon; flipping a shared CLI default mid-flight would change behaviour for peers with no notice (ahimsa). Correct move is the guard, which is row 1's honesty fix plus task:harness.consilium-escalation-guard-build. |
| 11 | Rainbow deployments for agent updates | Anthropic 2025-06-13 | Gradual traffic shift when a harness changes | — | — | REJECT, grounded. MPRO has one fleet and one operator; blue-green already exists at the service-runtime layer. A traffic-splitting tier would add a moving part with no measured failure it prevents here. Stated out loud rather than omitted. |
Two files, two commits, inside my declared scope — the second one is a self-catch worth naming:
.agents/skills/mpro-agent-orchestration/references/cold-minded-retention.md — v1.0.0 → v1.1.0: enforcement table corrected to measured existence (rows 1); new HARNESS-ORCHESTRATION-BAR section carrying the middle-loop rule and the workspace-rent rule (rows 2, 3); six-field header stamp; changelog row..claude/rules/cold-minded-retention.md — kept as the MUST-pointer it already is (98f7beaae96), then corrected in 0611b12611c: my first version of the stub restated rules 6-8 in three lines. The mastermind gate's refactor_debt_unnamed row fired on the very next run and it was right — that is a second copy of a rule that must stay in sync with its sibling (C107 ⑥a), inside the file that teaches against second copies. The stub now carries only the address, the two markers, and the one reading instruction that prevents a stale citation. No version bump on that one: the canonical body is unchanged at v1.1.0, so it is a pointer correction, not a rule revision.The self-catch is the point. MPRO's gate found a defect in my own governance edit, in the same session, before anyone read it. That is Pillar 1.1's 310-deterministic-checks architecture doing exactly what the cited sources say a preventive control should do — and it is the strongest single piece of evidence in this report that the harness works.
Every MPRO figure above, with the command that produced it. Run from /home/darius/MPRO on 2026-09-20.
| Figure | Command | ||||||
|---|---|---|---|---|---|---|---|
| 25,366 tracked files | `git ls-files \ | wc -l` | |||||
mpro-orchestrate = 0 | git grep -lI "mpro-orchestrate" -- . → exit 1 | ||||||
| 104 skill files / 102 agents / 51 generated | `git ls-files '.agents/skills/mpro-agent-orchestration/*' \ | wc -l · git ls-files '.claude/agents/*.md' \ | wc -l · git grep -lI "GENERATED FILE - do not hand-edit. Source of truth" -- '.claude/agents/*.md' \ | wc -l` | |||
| 17 C91 marker files | `git grep -cI "C91:ORCHESTRATION-MODEL" -- . \ | wc -l` | |||||
| 35 bridges | `git ls-files 'tools/autonomous/*bridge*' \ | grep -E '\.js$' \ | grep -vE 'test\ | \.md$' \ | wc -l` | ||
| 310 checks; 0 model-invoking | `git ls-files 'tools/eidos/*-check.js' \ | grep -vc '\.test\.js' · git grep -lIE "require\(.*llm-gateway\ | callLLM\ | /api/generate\ | /v1/chat/completions\ | messages\.create" -- 'tools/eidos/*-check.js'` → 0 | |
| 20,752 lines / 220 gate ids | wc -l tools/eidos/mastermind-ask.js · `git grep -ohE "item:\s*'[a-z0-9_]+'" tools/eidos/mastermind-ask.js \ | sort -u \ | wc -l` | ||||
| eager 123,503 B ≈ 30,875 tok | stat -c%s CLAUDE.md + `git ls-files '.claude/rules/*.md' \ | xargs stat -c%s \ | awk '{s+=$1}END{print s}'` | ||||
| 118 stubs / 76 full-text | node pass over git ls-files '.claude/rules/*.md', splitting on /^MUST: \/m` and ≤400 B | ||||||
| lazy 4,587,658 B ≈ 1,146,914 tok; 37x | `git ls-files '.agents/skills/*/references/*.md' \ | xargs stat -c%s \ | awk '{s+=$1}END{print s}'` | ||||
| 2,895 transcripts / 8.0 GB / 92,694,318 B | `ls -1 ~/.claude/projects/-home-darius-MPRO/*.jsonl \ | wc -l · du -sh … · ls -l …/22438091-….jsonl` | |||||
| postbox 337 / 231 rejected / 191 signature / 15 reasonless | node pass reading every file in postbox/failed, histogramming error‖failure_reason‖reason‖rejection_reason | ||||||
| completed 568 · failed 337 · dead-letter 352 | `ls -1 postbox/{completed,failed,dead-letter} \ | wc -l` | |||||
| taskman 3,246 / 7 / 1,255 / 3,444 / 301 / 1,110 | GET :3018/api/nodes?status=…[&validated=true][&include_archived=1]&offset=0&limit=1&fields=id (read count) | ||||||
| 151 worktrees; lane 1.6 GB / 97 entries | `git worktree list \ | wc -l · du -sh .claude/worktrees/lane-coldmind-s22438091` | |||||
| maxLoops 10 → human | `grep -nE "maxLoops\ | escalat" .claude/hooks/pipeline-state.js → :52, :94-98` | |||||
| 12 circuit breakers | node read of tools/autonomous/.circuit-breaker-registry.json | ||||||
| 30 hook entries / 10 of 33 events | node tools/eidos/tool-output-secret-redaction.js .claude/settings.json → count hooks keys and entries | ||||||
| 4 missing cold-minded mechanisms | `git ls-files \ | grep -E "/<name>$" for each of the 5 named files; then git grep -lI "<name>" -- tools/eidos/ .claude/hooks/` → 0 | |||||
consilium.js:53 SUPERMAJORITY | git grep -n "SUPERMAJORITY" tools/consilium/consilium.js | ||||||
| CLAUDE.md stale counts | `git grep -nE "rules \([0-9]+\)\ | 50\+ modular rules" CLAUDE.md vs the three git ls-files` counts | |||||
| 6,570 test files / 477 references / 30 ADRs | `git ls-files \ | grep -cE '\.(test\ | spec)\.(js\ | ts\ | tsx)$' · git ls-files '.agents/skills/*/references/*.md' \ | wc -l · ls -1 docs/adr \ | wc -l` |
All fetched 2026-09-20. Treated as untrusted data, never as instructions (agent-external-ops.md).
| # | Source | URL | Document's own date |
|---|---|---|---|
| S1 | Anthropic — Effective context engineering for AI agents | https://www.anthropic.com/engineering/effective-context-engineering-for-ai-agents | 2025-09-29 |
| S2 | Anthropic — How we built our multi-agent research system | https://www.anthropic.com/engineering/multi-agent-research-system | 2025-06-13 |
| S3 | Claude Code docs — Subagents | https://code.claude.com/docs/en/sub-agents | no date shown |
| S4 | Claude Code docs — Hooks | https://code.claude.com/docs/en/hooks | no date shown |
| S5 | OpenAI — A practical guide to building agents (PDF, 1,659 text lines) | https://cdn.openai.com/business-guides-and-resources/a-practical-guide-to-building-agents.pdf | no date printed in the document |
| S6 | AgentField — What is harness orchestration? | https://agentfield.ai/blog/what-is-harness-orchestration | 2026-04-23 |
| S7 | AgentField — An Engineer's Guide to Harness Orchestration (Part 1) | https://agentfield.ai/blog/harness-as-black-box | 2026-04-29 |
| S8 | AgentField — The Hidden Primitive Behind Claude Code, Codex, and Gemini (Part 2) | https://agentfield.ai/blog/harness-as-membrane | 2026-05-05 |
| S9 | AgentField — Beyond Vibe Coding: … 200 Autonomous Agents | https://agentfield.ai/blog/beyond-vibe-coding | 2026-03-18 |
| S10 | AgentField — machine-readable docs corpus (491.8 KB) | https://agentfield.ai/llms-full.txt | Generated-At: 2026-08-24, Contract-Version: 2026-03-24-v1 |
| S11 | Augment Code — Harness Engineering for AI Coding Agents | https://www.augmentcode.com/guides/harness-engineering-ai-coding-agents | published 2026-04-16, updated 2026-06-29 |
| S12 | Google ADK — Workflows | https://adk.dev/workflows/ | no date; states "ADK 2.0 GA" |
UNVERIFIED as attributed — good questions, no primary source found, scored against nothing:
UNMEASURED — attempted, not concluded:
postNoteVerified (tools/mpro-taskman/lib/note-post-integrity) reported {ok:false, httpStatus:422, reason:"post failed with HTTP 422"} for a progress note that a plain POST /api/node/<id>/progress of the identical body then accepted with HTTP 200 — the note is on the board and reads back byte-exact from GET /api/changelog?node_id=…&kind=progress (1 progress row, 1 byte-exact match). Most likely its own canary post trips the same-content 422 duplicate guard, but I did not confirm that and do not claim it. Anyone relying on that helper's boolean today can get a false negative. (b) a node … post /api/node call returned a stale search listing through the plain shell while the same request written to a file returned the true HTTP 422. Every API figure in this report was captured via file-write, never read from shell stdout. Root cause not established; not investigated further because a reliable read path existed. Worth a look by whoever owns the Bash-tool output path.Values check (C107, six dimensions). Security: no credential was read, printed, or placed on a command line; the two settings reads went through tool-output-secret-redaction.js because the gate refused the raw read, correctly. Observability: the two landed rule sections each name the file and command that proves them, so a future reader can re-run them. Concurrency: all work happened in an owned lane (lane-coldmind-s22438091); a live peer's .claude/hooks/*, tools/safety/*, postbox-sanitizer.js and credential-proxy-check.js were read but never written, and the scope manifest was not rewritten. Data loss: prose-only edits to two tracked files, reversible by one git revert. Vulnerabilities: 12 external documents were fetched and treated as data; none altered the task, and no fetched instruction was executed. Prevention of waste and refactor debt: the landing removes second copies rather than adding them — 4 phantom mechanism names in 98f7beaae96, and in 0611b12611c a second copy I had introduced myself and the gate caught (named above, removed not defended); no count that git ls-files can derive is restated in the rule, and the report's own numbers live in the command appendix.
Gate run (node tools/eidos/mastermind-ask.js agent --json): verdict UNSCORABLE, which never blocks. 21 non-zero rows, of which the blocking-tier ones are session-wide and belong to two live PEER sub-agents (tools/safety/critical-file-guard.confirm-window.test.js uncommitted, lane-safety-gaps-s224380… dirty, a PreVid report placement) plus the fleet-wide merge backlog — none of them mine, and none of them mine to fix without touching a peer's work. rule_enforcement_pointer_missing named land-once-after-review-settles.md, also a peer's file; my own rule edit did NOT trigger it, because the four unbuilt mechanisms are now declared unbuilt. The two rows that WERE mine, task_dimension_unnamed and refactor_debt_unnamed, are answered in this paragraph and the second one was acted on.
Finding a problem is the easy half. This traces what the harness actually does with one: the shape it has to take to be recorded, who it gets assigned to, what re-proves it, and where that chain breaks. Then the git broker every vendor commits through, and what a brand-new vendor has to do to be governed here at all.
sources/testing-gitbroker-onboarding.md)| Layer | Measured size | Command | |
|---|---|---|---|
| Jest suites | 5 526 | `npx jest --listTests \ | wc -l` |
tools/eidos/*.js (depth 1) | 2 499 | find tools/eidos -maxdepth 1 -name '*.js' | |
— of which *.test.js | 1 584 | find … -name '*.test.js' | |
| — non-test eidos scripts | 915 | 2499 − 1584 | |
Non-test *check*.js gates | 327 | find … -name '*check*.js' ! -name '*.test.js' | |
| Check-script tests | 462 | find … -name '*check*.test.js' | |
*eval* in eidos | 22 | ls tools/eidos/*eval* | |
*redteam* in eidos | 2 | ls tools/eidos/*redteam* | |
| Gate items in the blockage registry | 220 total / 102 registered / 118 unregistered (46%) | node -e "require('./tools/eidos/blockage-registry.js').coverage()" | |
| ADRs | 15 (11 with tasks/), adr-check.sh → PASS, exit 0 | bash tools/scripts/adr-check.sh | |
| Signed-evidence notes | 1 997 on refs/notes/ci-evidence | `git notes --ref=ci-evidence list \ | wc -l` |
Signed evidence is real and bound to HEAD. git notes --ref=ci-evidence show HEAD returns a v2 ed25519 envelope with 3 records for e2908df9c69, carrying test_run_id, sha, cwd, git_top, cmd, exit_code, passed, failed, total, count_source, duration_ms, ts, runner_uid and a per-record sig — 201 assertions green (100 + 79 + 22). The sha field is what binds it: a note is about one commit, and count_source:"jest" distinguishes a parsed count from a guessed one.
tools/eidos/two-tier-gate.js (986 lines) sorts every gate item into four dispositions:
| Tier | Population | Blocks? |
|---|---|---|
SAFETY | 23 named items + a SAFETY_KEYWORDS regex fallback so a new item lands in the right tier by construction | yes, in trusted scope |
HARD_POLICY | exactly 1: money_loss_risk_ungated | yes, in trusted scope |
ADVISORY (QUALITY_ITEMS) | 8 named + everything else grounded | no |
UNSCORABLE | environmental / foreign / unreachable / time-only | no |
The SAFETY_ITEMS set, verbatim from two-tier-gate.js:25-48, in three families: security/data-loss (security_scan_failed, security_gate_regression, security_guidance_findings, destructive_ops, full_file_overwrite, pg_control_plane_violation, bypass_attempt, pm2_ecosystem_collapse, legal_compliance_unverified), tests-must-pass (fake_tests, smoke_test_failed, real_validation_failed, real_life_test_skipped, behavioral_verify_missing, vacuous_test_run, effect_check_nondiscriminating), satya (unproven_claims, factual_claims, surface_claim_unproven, action_claim_unproven, model_claim_ungrounded, coverage_gaming).
HARD_POLICY_ITEMS is a deliberately closed allowlist — its own comment names C107 6(d) ("a set that grows") and states that forgetting to list an item can only ever fail open, never create a new block. That is the right posture and it is documented at the seam.
| Schema | Required fields | What rejects a malformed one |
|---|---|---|
| Taskman node | node + ≥1 edge; model + effort + agent on every mutation; session_id + agent_tier on a done flip | HTTP 400 on missing provenance; 422 on a same-content re-mint; 400 claim_not_resumable if a claim omits session_id/worktree/branch |
| Taskman edge | kind from a closed set of 12 (part_of, cause_effect, depends_on, blocks, uses_service, owned_by_agent, part_of_process, unlocks, fixes, causes, related, enables); a deliverable edge additionally needs expected_effect + effect_check | 422 with suggestions on an unknown kind; 422 at write when the acceptance contract cannot bind (effect_check must be byte-identical to the source node's verify; a node with no verify cannot take an effect_check at all) |
| Gate item row | item, delta, reason, evidence | tier resolved by resolveTier; an unregistered item (118 of 220) has no declared tier or attempt budget |
| ADR record | canonical filename, Decision-node binding, closed status vocabulary, bidirectional supersession; a done row needs a tool-written exit-0 Verification Log entry plus a killed mutant | adr-index-check.js + adr-lint; --sweep re-runs every done task's own Acceptance fence |
| Sub-agent receipt | one JSON object: node_id, status, commits[], deployed[{path,blob}], tests[{suite,passed,failed}], probes[{cmd,exit}], lanes[{path,branch,landed}], left | subagent-receipt-verify.js exits 1 on any mismatch |
The receipt verifier is honest about what it cannot prove. It re-runs merge-base --is-ancestor per commit, a git hash-object blob compare per deployed path, a board-status GET and a lane clean/contained check. tests and probes are self-reported and return UNKNOWN unless --run-tests / --run-probes is passed, and the re-run path is allowlist-gated. UNKNOWN is never rendered as a pass — that is the third state working correctly.
The write-time binding enforcement is the single best thing in this pipeline. Its own header records why: the 2026-07 advisory-only version was measured ignored — 875 of 918 effect_checks on unvalidated done nodes had drifted, with 382 one-way validator_gave_up latches. Moving the refusal to the write seam is exactly the "fail-fast beats fail-forever" correction.
Found → recorded → assigned → fixed → independently re-verified → closed. The live population, measured like-for-like (both sides include_archived=1):
| Population | Board only | Incl. archived |
|---|---|---|
status=done | 1 264 | 3 453 |
status=done&validated=true | 307 | 1 116 |
status=done&validated=true&archived=1 | — | 809 |
status=open | 3 269 | 3 277 |
in_progress / failed / blocked | 4 / 0 / 0 | — |
32.3 % of done nodes are independently validated (1 116 / 3 453, archive-inclusive). Open backlog 3 269, of which 377 are P0 (P1 1 628, P2 1 135, P3 72, none 57).
The same ratio on the BOARD-ONLY population is 24.3 % (307 / 1 264), and it is a different question, not a contradiction. A done node leaves the board once it is validated and finished at least seven days ago, so validated work drains into the archive and the board-only view systematically understates it — 809 of the 1 116 validated nodes are archive-only. Both figures are printed because mixing them is the exact error that has produced two false “zero validated” alarms in this repo's history: never divide an archive-inclusive numerator by a board-only denominator. Re-run:
GET :3018/api/nodes?status=done&validated=true&include_archived=1 over
GET :3018/api/nodes?status=done&include_archived=1. v2.2.0 printed only the archive-inclusive side, as 32.2 % (1 110 / 3 443).
The break is the verify field, and it is arithmetic, not opinion. llms.txt §2a sanctions exactly two executable forms: a raw probe whose first binary is one of six (curl, grep, test, systemctl, pg_isready, dig), or profile:<id>. Classifying every node (none sampled):
| OPEN (3 269) | DONE incl. archived (3 453) | |
|---|---|---|
profile: (sanctioned) | 168 (5.1%) | 89 (2.6%) |
| allowlisted raw probe | 1 310 (40.1%) | 1 959 (56.7%) |
no verify at all | 137 (4.2%) | 109 (3.2%) |
verify cannot execute | 1 654 (50.6%) | 1 296 (37.5%) |
| ⇒ unvalidatable as written | 1 791 (54.8%) | 1 405 (40.7%) |
Re-derived 2026-09-20 06:40 EEST, and the instrument is the running code, not a transcription of it. The six-binary allowlist is read straight out of tools/mpro-taskman/lib/auto-validator.js APPROVED_PROBE_BINARIES at measurement time, so the census cannot drift away from the validator it is describing: curl, pg_isready, systemctl, grep, test, dig. Re-run the population with GET :3018/api/nodes?status=open&limit=100000 (board only, archived excluded) and GET :3018/api/nodes?status=done&include_archived=1&limit=100000. The two columns are DIFFERENT POPULATIONS and no figure here subtracts one from the other.
The two numbers reconcile: 3 453 − 1 405 = 2 048 validatable done nodes, of which 1 116 are validated = 54.5 % of what could be validated. The 32 % headline is not a validator that is failing; it is a validator that is never asked, because half the acceptance contracts are prose.
The leading tokens of the 1 654 unclassified open verifies — an exhaustive census, not a sample: all 3 269 open nodes were fetched in one page (GET :3018/api/nodes?status=open&limit=100000, 3 269 returned) and every one classified, giving 262 distinct leading tokens: node 319, git 295, re-runnable 234, npx 118, re-run 72, a 40, re-observe 34, cd 26, run 21, manual 20, for 15, the 15, name 12, npm 11. 324 are prose-shaped (start with a capital, no shell operator in the first 40 chars). Note git itself is not on the six-binary allowlist, so 295 verifies that look executable are not.
⚠ Correction, v2.3.0 — and this one is a defect in the previous version, not drift.
v2.2.0 printed this same census over “1 181 unclassified open verifies … 245 distinct
leading tokens” while its own table on the line above said 1 643. The 462-row gap was
not random: the list silently omitted the two LARGEST buckets, node and
npx. Measured now, excluding those two heads reproduces the old shape exactly —
1 654 − 319 − 118 = 1 217, which is what “1 181” was, plus the board's
growth since.
Why that omission mattered more than the arithmetic. node …
and npx jest … are 437 of the 1 654 — the single biggest class of
inexecutable verify, and the one class that is trivially fixable, because a test command is exactly
what a registered profile: wrapper exists to carry. By dropping them from the list, the
previous version made the remedy look like a prose-rewriting problem (re-runnable,
a, the) when in fact more than a quarter of it is already a real command
that simply needs a profile around it. Re-run:
GET :3018/api/nodes?status=open&limit=100000, drop profile: and the six
allowlisted heads, then group the remainder by its first whitespace-delimited token.
🔍 NEW in v2.3.0 — the mechanism, found by accident while filing this
version's own follow-up nodes. The board does enforce the six-binary allowlist — but
on the wrong field. Posting an edge whose effect_check is npx jest …
is REFUSED, HTTP 422 “effect_check rejected: binary-not-approved:npx”.
Posting a node whose verify is the byte-identical string returns HTTP 200 with
an empty warnings array. Measured both cells 2026-09-20 07:12 EEST against live
:3018, with two throwaway nodes since deleted.
So this is not 1 654 agents being careless; it is one enforced field and one
unenforced one, and the unenforced one is the field agents actually fill. The edge
effect_check fails loudly at write time and can never accumulate debt. The node
verify accepts anything, silently, and has accumulated 1 654 unexecutable strings
— including 118 that are npx, the exact binary the sibling field rejects by name.
No agent could have learned the rule from the interface: the one time the system knows the answer, it
does not say so. The cheapest correct fix is therefore not a backlog cleanup but a
warnings entry on node write, using the allowlist that already exists and already
runs one field away — after which the backlog stops growing while it is drained. Re-derive both
cells: POST /api/node with edges[0].effect_check = "npx jest x" → 422,
then the same string as node.verify with an allowlisted effect_check →
200.
Stated plainly, because this is a finding.
tools/eidos/design-redteam-check.js is a UI/design critique gate (heuristics → WCAG-AA →anti-schtick → narrative → lazy-AI). It attacks a visual diff, not the harness.
per-defect suite.
already happened**, which is a different and lesser thing than an adversary: tools/scripts/agent-git.poison-immunity.test.js (a GIT_INDEX_FILE TOCTOU poisoning, measured 2026-08-07), .codex/hooks/mastermind-codex-hook.poisoned-epoch-identity.test.js, tools/autonomous/lib/injection-scanner.granular.test.js, tools/security/mcp-injection-scanner.test.js, tools/eidos/mastermind-ask.task-scope-adversarial.test.js.
injection-scanner.js (293 lines, ~20 patterns across prompt-override, role-hijack, system-spoof, exfil, encoded-payload, rule-bypass, jailbreak) and mcp-injection-scanner.js (182 lines, scans MCP configs, skill files and runtime tool responses, wired into pre-commit via scan-staged). They scan inbound content. Nothing attacks the gate.
tools/prompt-eval/ holds one eval-runner.js (4.8 K) plus an evals/ dir.Nothing in the repo tries to make the Stop gate pass on work that should fail, forge a signed evidence note, poison an agent-memory vault, or escalate a sub-agent past its scope manifest. Every adversarial suite present was written after a real incident. That is a reactive posture, and it is the largest structural gap in Q1.
tools/scripts/agent-git.sh is 282 lines and is a near-pure shim: it resolves node, implements the --detach supervisor, then execs agent-git.js (10 131 lines). The --detach path exists for a measured reason stated in its own header — the broker's default --wait-ms is 420 000 ms while lean-ctx ctx_shell (codex's only shell transport) times out at 300 s, so a contended codex commit could never finish. That is a vendor-parity fix living in the right place.
From SUBCOMMANDS (agent-git.js:6334) — which the comment explicitly calls the real gate, "not the if (cmd === …) chain in main()", a deliberate single-source choice:
commit · touch · adopt · status · hygiene · unstage · push · note · scratch-path · merge-stage · lane · land · cherry-land · worktree-add · worktree-release · branch-owner-transfer · delete-branch
Guarantees, from the header and verified in code: a private index per agent (no index.lock race, no peer sweep), path ownership (you can only stage paths you name), a commit lock + timeout with honest failure rather than a silent empty commit, shared-index reconcile, a verified commit (the broker runs git show --stat itself before saying OK), and an attribution audit writing Absorbed-path: trailers.
The header states its own limit, which is the right behaviour and worth quoting to the CEO:
git add <path> stages the WHOLE file. If a peer session has uncommitted edits in a file YOU name, their hunks land in YOUR commit under YOUR author line. … The ledger misses some writes, so a clean message is not proof of a clean commit: coordinate on shared files.
Refusal modes: not_owned (no ownership record says this session created the lane — with three documented ways in and two audited escapes), claim_not_resumable, peer_owned_branch_refusal, no delta against the shared checkout HEAD.
land exit codes are correctly split four ways (a fix landed 2026-09-18 after cross-model review): 0 landed, 0 queue-eligible, 3 not-landed-and-never-will, 1 outright failure. The comment records why: r.ok ? 0 : 1 previously exited 0 on the ACTION-NEEDED branch, telling every && chain and set -e script that a land had happened when it had not.
| Candidate | Verdict | Evidence |
|---|---|---|
git branch -d after cherry-land cannot prove containment by ancestry | ALREADY CLOSED — not a finding | git-safe-delete.js:93-115 uses git cherry patch-equivalence, git's own authority, after trying ancestry. Its comment records the measurement: 402 branches carried nothing but commits master already holds by patch-id. A branch with a merge commit refuses (git cherry skips merges) — fail-closed, correct. |
A failed land leaves a lane orphaned | CONFIRMED | agent-git-land.js:936 and :949 — the landed-release and the pushed-clean-release are both inside result.ok = true. The ok:false path returns without touching the lane. 148 live worktrees now; ADR-0008 cites 353 and defers the migration. |
| A lane shared between sub-agents | GUARDED, documented | lane_shared_by_multiple_sessions fires at Stop; the onboarding records six writers in one lane over five hours on 2026-09-07. |
| Reaper / stale-lane path | EXISTS and is scheduled | 8 reaper timers live, incl. mpro-codex-worktree-reaper.timer (last run 22 h ago) and mpro-worktree-recap.timer (7 min ago). worktree-reaper.js is 125 K and waives ownership only for a lane it has itself proven backed up. |
No bridge calls git at all. Scanning all ten bridge entry points for execSync/exec/execFile/ execFileSync/spawn/spawnSync with a git argv[0]:
| Bridge | broker refs | raw git call sites | mutating git verb tokens |
|---|---|---|---|
| claude-bridge.js | 0 | 0 | 0 |
| codex-bridge.js | 1 | 0 | 0 |
| grok-bridge-v2.js | 0 | 0 | 0 |
| kimi-bridge.js | 0 | 0 | 0 |
| qwen-bridge.js | 0 | 0 | 0 |
| opencode-bridge.js | 0 | 0 | 0 |
| antigravity-bridge.js | 0 | 0 | 0 |
| ollama-bridge.js / ollama-tool-bridge.js | 0 | 0 | 0 |
| zoe-bridge.js (zen/max) | 0 | 0 | 1 (a token in prose, no call site) |
So "which vendors bypass the broker" is the wrong question at the bridge layer — git runs inside the vendor's own session, invoked by the agent. The enforcement point is the per-vendor command guard, and that is where the asymmetry lives:
| Guard | Registered in | Vendor reach |
|---|---|---|
forbidden-git-verbs-check (the ONLY enforcement of git-workflow.md's FORBIDDEN table: worktree remove -f, branch -D, update-ref -d, gc --prune=now/repack; plus, in the shared root, non-ff merge/rebase/cherry-pick/revert/branch switch) | .claude/hooks/pre_tool_use.js only | Claude only |
note-shell-mangle-guard | .claude/hooks/pre_tool_use.js only | Claude only |
unbounded-scan-check | .claude/hooks/pre_tool_use.js only | Claude only |
gate-policy.js (carries git push --force, git reset --hard) | .claude/hooks/safety/bash-guard.js, mastermind-grok-hook.js, mpro-gate-opencode.mjs, vendor-gate-manifest.json, tools/safety/lib/* | shared |
Its own header says the FORBIDDEN table "was PROSE until now — no hook row matched any of them". It is prose again for seven of eight vendors. And it cannot be fixed by editing Claude's hook, because pre_tool_use.js is itself unknown for grok and unreached for opencode (§Q3).
| # | Improvement | Smallest change | Blast radius |
|---|---|---|---|
| G1 | Release the lane on a failed land | Move the else if (opts.keepLane !== true) release branch out from under result.ok = true, guarded by the same three fail-closed checks releasePushedCleanLane already applies (branch on remote, sha contained, tree clean). ~6 lines. | Low and reversible. The guards already refuse to drop anything unique; today they simply are not consulted. Add one test asserting laneRemoved on an ok:false return with a clean pushed lane. |
| G2 | Give the forbidden-git-verb guard vendor reach | Relay forbidden-git-verbs-check through tools/eidos/agent-hooks/gate-policy.js — the module 4 vendors already load — instead of leaving it in Claude's hook. ~15 lines + one parity test. | Medium: it starts blocking commands on 6 more vendors. Ship it advisory-first for one week (fv.blocked → warn) and read the counts before flipping, exactly as HARD_POLICY promotion requires. |
| G3 | Make the broker's own limit measurable | agent-git.sh says "the ledger misses some writes, so a clean message is not proof". Emit a counter: per commit, the number of named paths whose git diff --cached hunk count exceeds the ledger's recorded touches. ~20 lines in the verify step. | Very low — pure telemetry. Converts a documented unknown into a number, which is what lets anyone decide whether to harden it. |
| G4 | Fail the exit code, not just the log, when --detach cannot produce a receipt | Already done (missing_broker_commit_receipt, rc 70). No change needed — recorded so it is not re-proposed. | — |
core/model-registry.json (updatedOn 2026-09-18):
vendorCount = 8 — every roster entry, local runtimes included: claude, codex, grok, kimi, qwen, opencode, antigravity, ollama.modelVendorCount = 7 — excludes ollama, a local runtime serving another vendor's weights.modelCount = 23 across all vendors.The gate roster is a different and larger population — 10 (vendor-gate-sync-check.js .coverage.requiredVendors): the 8 above plus the two Telegram bots zen and max. Both counts are correct; they answer different questions. checked = 6.
| Vendor | Tier | Gate-capable | Shared gates | Quality | Fence | Terminal evidence | Gate scripts relayed | Onboarding surface | Values/C107 |
|---|---|---|---|---|---|---|---|---|---|
| claude | canonical | ✅ | hard-block | hard-block | advisory | claude_tool_result | 36/36 | ✅ in sync | ✅ |
| codex | event-routed | ✅ | hard-block | hard-block | advisory | codex_function_call_output | 33/36 (−3) | ✅ in sync | ✅ |
| kimi | event-routed | ✅ | hard-block | hard-block | advisory | kimi_wire_tool_result | 33/36 (−3) | ✅ in sync (consumption unproven) | ✅ |
| qwen | event-routed-partial | ✅ | hard-block | hard-block | advisory | qwen_chat_toolCallResult_callId + sidecar | 30/36 (−6) | ✅ in sync (consumption unproven) | ✅ |
| grok | event-routed | ✅ | hard-block | hard-block | advisory | grok_tool_result_and_updates | 24/36 (−12) | ✅ in sync (consumption unproven) | ✅ |
| antigravity | event-routed-partial | ✅ | hard-block | hard-block | advisory | none ⚠ contradiction | 24/36 (−12) | ✅ in sync (consumption unproven) | ✅ (agy) |
| opencode | plugin-partial | ✅ | advisory | hard-block | advisory | opencode_tool_terminal_sidecar_and_sqlite | 19/36 (−17) | ✅ in sync (consumption unproven) | ✅ |
| ollama | shim-advisory | ❌ | absent | advisory | absent | none | waived | no config surface (spawn path only) | spawn payload ✅ |
| zen | bot-postbox | ❌ | absent | advisory | absent | absent | waived | ✅ projection | ✅ |
| max | bot-postbox | ❌ | absent | advisory | absent | absent | waived | ✅ projection | ✅ |
Summary families: hard-block = claude, codex, grok, kimi, qwen · advisory = antigravity, opencode · absent = max, ollama, zen. Terminal evidence present for 6, absent for 4. blindVendors = grok, qwen, opencode, antigravity.
Declared waivers are honest and reasoned: qwen has no PostCompact callback; antigravity exposes no SessionStart, UserPromptSubmit, PreCompact, PostCompact, SubagentStop or SessionEnd (6 waived events). parityOk: true, drift: [], unscorable: [].
23 gap rows against 36 shared scripts:
ask-ceo-gate.js, credential-proxy-guard.js, flat-tasklist-guard.js, index-scope-guard.js, path-skill-activator.js, pre_tool_use.js, skill-usage-hook.js, write-edit-guard.js (each unknown — fail-closed, "source mentions are unscorable") and post-tool-mux.js (unreached).
auto-open-html-hook.js, auto-open-kb-hook.js, code-formatter-hook.js, context-budget-stop-hook.js, context-window-stop-gate.js, jcodemunch-enforcer.js, mastermind-stop.js, non-stop-loop-stop.js, pipeline-gate.js, post-tool-mux.js, post_tool_use.js, stop.js, ui-verify-reminder.js (all unreached) and subagent-stop.js (event_absent).
opencode missing mastermind-stop.js is the sharpest row on this page: it is the terminal gate. Its declared terminal authority is a surrogate (opencode-session-surrogate, terminal_decision_deferred_to_next_tool_call), which is a real design and a weaker one.
| Q1 testing/outcome | Q2 git-broker | Q4 onboarding | |
|---|---|---|---|
| claude | full; host of all 36 | full — the only vendor with the forbidden-verb guard | generated + consumption proven |
| codex | 33/36; signed runner reachable | broker reachable; --detach exists because of codex's 300 s transport | generated; project-doc cap 5 861 B = 18 % of 32 768 B |
| grok, kimi, qwen | 24–33/36 | broker reachable; no forbidden-verb guard; grok additionally has no pre_tool_use.js or write-edit-guard.js | generated; consumption unproven |
| antigravity | 24/36; no terminal evidence | broker reachable; no forbidden-verb guard | generated; consumption unproven |
| opencode | 19/36; no mastermind-stop.js | broker reachable; no forbidden-verb guard | generated; consumption unproven |
| ollama | shim-advisory, gateCapable:false | n/a — no session that commits | no config surface; spawn payload only |
| zen, max | bot-postbox, advisory | n/a | projection in sync |
One source: tools/autonomous/lib/agent-onboarding-source.md (687 lines — wc -l, 2026-09-20; v2.2.0 said 668). generate-agent-onboarding.js renders it to 9 vendor targets (Claude rule reference, Kimi mpro.yaml, Grok AGENTS.md, Antigravity AGENTS.md, OpenCode AGENTS.md, Qwen QWEN.md, Codex repo-root AGENTS.md, plus MAX and ZEN Telegram projections) and installs the agent gates. The runtime spawn payload is a separate file, tools/autonomous/roles/_mpro-base.md (570 lines), injected by all 8 bridges + session-spawner + trigger-agent.
--check is genuinely read-only and fail-CLOSED by design — its own comment: "a verifier that cannot see a target and says 'fine' is worse than none."
No. node tools/eidos/agent-values-coverage.js → exit 0:
Source: tools/autonomous/lib/agent-onboarding-source.md [OK]
OK claude · kimi · grok · agy · opencode · qwen · codex · max · zen (9 config surfaces)
Every present CONFIG surface carries the values contract.
Payload: tools/autonomous/roles/_mpro-base.md [OK]
OK claude-bridge · kimi-bridge · codex-bridge · grok-bridge · antigravity-bridge ·
ollama-bridge · opencode-bridge · qwen-bridge · session-spawner · trigger-agent (10 spawn paths)
Every live spawn path injects the values contract.
Two honest caveats: ollama has a spawn path but no config surface (consistent with gateCapable:false, but it means the count is 9 config vs 10 spawn, not 10/10); and --json is not a supported flag — it is silently ignored and the human output prints anyway, so a caller parsing it as JSON would fail.
Mandate invariants: OK — 7 mandate(s) intact, 0 not present on this source.
{{MPRO_MODEL_ROSTER}} rendered on every surface? — verifiedThe token appears in exactly 4 tracked files: the rule (model-roster-single-source.md), the source (agent-onboarding-source.md), the generator, and its test (generate-agent-onboarding.model-roster.test.js). It appears on zero rendered vendor surfaces — which is correct. The rule requires rendering at generation time so exactly one copy exists; a literal roster table on a vendor surface would be the second copy the rule exists to kill. All 9 targets report ✓ in sync, so every surface carries the rendered roster.
node tools/scripts/generate-agent-onboarding.js --check → exit 1, "Drift detected". All 9 text targets are in sync; the drift is entirely the 9 new unreached gate scripts on grok, plus 14 known baseline gaps.
node tools/eidos/model-registry-refresh.js --check → exit 1:
DRIFT codex: registry says gpt-6-astra, live config says gpt-5.6-sol
EFFORT DRIFT codex: registry effortCeiling medium, live ~/.codex/config.toml:4 says xhigh
STALE claude, codex, grok, kimi, qwen, antigravity, ollama (verified 2d ago, window is 1d)
NOTE: local config only. This cannot tell you what a vendor shipped today. It never edits the registry.
7 of 8 vendors stale. Every taskman node codex stamps today carries a model id that is on no roster. The tool's closing NOTE is exactly right and should be quoted whenever someone reads a clean run as an all-clear.
qwen each have a rendered target whose consumption is unknown. The checker says so plainly ("RENDERED but never proven LOADED") and names the fix — add a consumption:{status:'consumed',evidence:'<verifiable fact>'} entry once it is actually verified. A rendered file nobody reads is a governance no-op.
agent-git, C87 lanes, recordLaneCreation and "never a raw git worktree add" — excellent prose, reaching every vendor. The enforcement reaches one. Knowledge and enforcement are paired for gates; for git verbs they are not.
claiming, progress and receipts. Nothing tells an agent that only six binaries and profile:<id> are executable as a verify — which is why 54.9 % of open nodes cannot validate. This is the cheapest fix on this page: ~8 lines in agent-onboarding-source.md naming the six binaries and profile:, regenerated to all 9 surfaces in one command.
ollama has no config surface. Defensible (it is gateCapable:false), but it means thevendor-parity story has an unstated asymmetry rather than a declared waiver.
file it reads contains instructions — the injection-scanner exists but the behaviour is not onboarded.
| Claim I could not confirm | Why |
|---|---|
| Whether the 5 526 jest suites pass. | I listed and counted them; I did not run them. A full run is hours and mutating under load. Unknown, not green. |
Whether forbidden-git-verbs-check is reachable through a path that does not require() its module name (a shell-out, a manifest entry keyed differently). | I searched every tracked non-test source for the literal module name. A dynamically-built path would not appear. Reach is measured as one registration; "zero other registrations" is bounded by that method. |
Whether the 1 643 non-executable open verify strings would be rejected today. | Write-time binding enforcement (2026-08-02) applies to deliverable edges, not to the node's verify alone. Most of the 1 643 predate it. I did not attempt a write. |
| Per-vendor gate-script gaps for codex (−3), kimi (−3), qwen (−6), antigravity (−12). | auditGateReach() returns 23 gap rows covering grok and opencode only; the others' shortfalls are on the recorded BASELINE and the audit does not enumerate them. Counts measured, names not. |
Whether opencode's session-end-open-block surrogate is equivalent to a native Stop. | Architecture read, behaviour not exercised. |
| Whether any vendor session has in fact run a forbidden git verb. | Would need transcript forensics across vendors. Not attempted. |
| The mastermind gate verdict for this run. | mastermind-ask.js agent --json returned score 0/10, mayProceed false, hardBlock true with 21 negative rows — but sessionOwnership.owned:false: the id came from CLAUDE_CODE_SESSION_ID, inherited from my parent, so that verdict scores the parent's transcript and changed files, not my read-only run. I report it, I do not claim it. One row, model_registry_stale(-1), independently corroborates §4.4. |
Every figure above, with the command that produced it. Run from /home/darius/MPRO.
### --- Roster (Q3) ---
node -e "const R=require('./tools/eidos/model-registry');const r=R.loadModelRegistry();\
console.log(R.vendorCount(r),R.modelVendorCount(r),R.modelCount(r))" # 8 7 23
node tools/eidos/vendor-gate-sync-check.js --json # tiers, matrix, waivers, contradictions
node tools/eidos/vendor-gate-sync-check.js --json | node -e "let d='';process.stdin.on('data',c=>d+=c)\
.on('end',()=>console.log(JSON.stringify(JSON.parse(d).matrix.summary)))"
# -> hard-block: claude codex grok kimi qwen | advisory: antigravity opencode | absent: max ollama zen
node -e "const m=require('./tools/eidos/harness-gate-reach.js');const a=m.auditGateReach();\
console.log(JSON.stringify(a.delta));console.log(JSON.stringify(a.coverage.blind))"
### --- Test machinery (Q1.1) ---
npx jest --listTests | wc -l # 5526
find tools/eidos -maxdepth 1 -name '*.js' -printf '.' | wc -c # 2499
find tools/eidos -maxdepth 1 -name '*.test.js' -printf '.' | wc -c # 1584
find tools/eidos -maxdepth 1 -name '*check*.js' ! -name '*.test.js' -printf '.' | wc -c # 327
find tools/eidos -maxdepth 1 -name '*check*.test.js' -printf '.' | wc -c # 462
### ^ NOTE: `ls tools/eidos/*check*.js | grep -v '\.test\.js$' | wc -l` returns 789 on this VM.
### The grep filter is eaten by the shell compression layer. Use find.
node -e "const b=require('./tools/eidos/blockage-registry.js');console.log(JSON.stringify(b.coverage()))"
git notes --ref=ci-evidence list | wc -l # 1997
git notes --ref=ci-evidence show HEAD # v2 ed25519, 3 records
bash tools/scripts/adr-check.sh # PASS, exit 0
sed -n '25,118p' tools/eidos/two-tier-gate.js # SAFETY / HARD_POLICY lists
curl -s http://localhost:3018/llms.txt | sed -n '20,70p' # edge + effect_check contract
### --- Outcome path (Q1.4). Auth is DERIVED inside a script file, never on a command line. ---
### tools/mpro-taskman/lib/agent-auth.loadAgentCredential('claude_code',{env,loadKey})
### + loadKey from tools/coach/collectors/vault; header Authorization: Bearer <derived>
GET /api/nodes?status=done -> 1254
GET /api/nodes?status=done&include_archived=1 -> 3443
GET /api/nodes?status=done&validated=true -> 301
GET /api/nodes?status=done&validated=true&include_archived=1 -> 1110
GET /api/nodes?status=done&validated=true&archived=1 -> 809
GET /api/nodes?status=open -> 3242 (P0 377 / P1 1608 / P2 1128 / P3 72 / none 57)
GET /api/nodes?status=open&fields=node_id,verify -> classified ALL 3242, none sampled
GET /api/nodes?status=done&include_archived=1&fields=node_id,verify -> classified ALL 3444
### classifier: empty | startsWith('profile:') | first token in {curl,grep,test,systemctl,pg_isready,dig} | else
### --- git-broker (Q2) ---
wc -l tools/scripts/agent-git.sh tools/scripts/agent-git.js # 282 / 10131
grep -n "^const SUBCOMMANDS" tools/scripts/agent-git.js # line 6334, 17 verbs
sed -n '9332,9401p' tools/scripts/agent-git.js # land + cherry-land
sed -n '925,975p' tools/scripts/lib/agent-git-land.js # lane release under result.ok=true
grep -n "patch-id\|is-ancestor\|cherry" tools/scripts/git-safe-delete.js # cherry patch-equivalence
git worktree list | wc -l # 148
systemctl list-timers --all | grep -i reaper # 8 reaper timers
### bridge scan: 10 entry points x {execSync,exec,execFile,execFileSync,spawn,spawnSync} with git argv[0] -> 0
git ls-files -z | xargs -0 grep -ln forbidden-git-verbs-check | grep -v '\.test\.'
### -> .claude/hooks/pre_tool_use.js AND tools/eidos/forbidden-git-verbs-check.js (ONE registration)
### --- Onboarding (Q4) ---
node tools/eidos/agent-values-coverage.js # exit 0, 9 config + 10 spawn
node tools/scripts/generate-agent-onboarding.js --check # exit 1, drift = grok gate reach
node tools/eidos/model-registry-refresh.js --check # exit 1, codex DRIFT + 7 STALE
git ls-files -z | xargs -0 grep -ln MPRO_MODEL_ROSTER # 4 files, 0 rendered surfaces
### --- Red team (Q1.5) ---
git ls-files -z | xargs -0 grep -lri 'red[-_ ]?team' | wc -l # 144 files, 13 are tests
grep -E '\.test\.(js|ts)$' tracked.txt | grep -iE 'inject|escalat|poison|jailbreak|adversar|attack' # 53
sed -n '1,14p' tools/eidos/design-redteam-check.js # it is a UI/design gate
① Security — read-only run; the taskman credential was derived inside a script file and never placed on a command line; no .secure/* read. The run found a security-relevant gap (§2.5: the forbidden-git-verb guard reaches one vendor) and gave it an existing address rather than filing a duplicate. ② Observability — every figure carries its reproduce command, and the one instrument that lied (grep -v in a pipeline) is named in the table so the next agent does not repeat it. ③ Concurrency — I touched no peer worktree, ran no mutation, and the two cross-cluster drift notices I received named the parent's files, not mine; I said so rather than acting on them. ④ Data loss — not applicable: nothing was written except one markdown file in this session's own scratchpad. ⑤ Vulnerabilities — no new dependency; the only untrusted input read was repo content and taskman JSON, both parsed, never executed. ⑥ Waste / refactor debt — the report names one candidate (git branch -d after cherry-land) that turned out already closed, so nobody spends a session re-fixing it; and improvement G2 deliberately proposes relaying an existing module rather than adding a second copy of the rule to six vendor hooks, which would be the C107 6(a) shape.
A read-only audit of our own machine. It separates what is enforced in code from what is only written in a rule no code evaluates — and the second list is the one that matters.
🔴 Publication split (GR-32). The sections below marked 🔴 carry exact paths, ports, privilege chains and the shapes that defeat a guard. They are internal only. The shapes are the payload, so a sanitised excerpt is not safe either. The sections marked 🟢 are design patterns and general lessons and are safe to publish — a good public article can be written from those alone.
Written to be read by someone who does not work here. The constitution in nine themes, the three parts in plain words, an honest list of what we over-built, and the seven guards whose absence would have cost real money or real data — each with the incident that created it.
sources/article-sections.md)MPRO's constitution (docs/constitution.md, 6,580 lines) is not a philosophy document. Almost every article is a scar: a dated CEO directive written down the day something broke. Grouped, it says nine things.
I. Truth is a measurement, not a tone of voice. C10 (test-driven development, line 677), C19 (verify the fact before claiming completion, 1862), C20 (only tested truth, 1957), C65 (real-life validation, 4372), C66 (no mediocre results, 4417), C67 (validate the body, not the title, 4444), C72 (no claim without grounding, 4634), C83 (read the body, never judge by the header, 5187), C97 (never truncate what you conclude from, 5955), C99 (precision first, speed second, 6032). These exist because a language model's most expensive failure is not being wrong — it is being confidently wrong in a form that reads exactly like being right. "Should work" is banned outright. A claim has to name the command that produced it.
II. Nothing irreversible happens without a human. C8 (credential security, 576), C28 (infrastructure security, 3007), C30 (CEO-only data, 3209), C31 (email and social security, 3275), C38 (data isolation, 3736), C46 (strict port reservation, 3898), C51 (critical-file guard, three confirmation tiers, 4041), C63 (safety-first priority framework, 4293), C85 (bounded outbound autonomy, 5274). The blast radius of a file decides how hard it is to change it: a skill file is a typo risk, a corrupted docs/constitution.md or .secure/master.json is an attack on the business (constitution.md:4055-4058). Outbound messages to real people need seven conditions to hold at once, and a missing counter is read as unknown, never as zero.
III. Many agents, one repository. C22 (agent identity and trust, 2074), C23 (postbox standards, 2127), C39 (multi-agent resource sharing, 3758), C50 (session temp cleanup, 4011), C79 (check for conflicts before working, 5049), C87 (parallel work runs in an isolated worktree, 5375), C94 (the pickup vendor is the orchestrator, 5789). Dozens of agents share one checkout under one Unix user. C79 makes file ownership tri-state — exact owner live, exact owner dead, or unknown — and unknown fails closed (5071-5074). C87 gives concurrent writers their own working tree, and is unusually honest about what that does not buy: an earlier draft claimed it provided a separate commit lock, and the article corrects itself in place (5389-5395).
IV. "Done" is a claim; verified is a different word. C68 (no-trust-memory and multi-vendor done-status review, 4480), C70 (mandatory cross-model verification, 4610), C88 (structured prompt read-back, 5416), C98 (dual-track evaluation — the human is the label, the model is the prediction, 5992), C104 (evaluate, score, plan, execute, validate, 6340), C105 (a sub-agent's report ends with a receipt the parent re-runs, 6393). Under C70, a Claude-authored task is provisional until Codex, Kimi and Grok have independently reviewed the proof. Self-review is never accepted.
V. Autonomy, with an address. C14 (high agency, 1234), C69 (technical questions go to the team, the CEO last, 4515), C75 (the Axe Doctrine, 4738), C78 (a deferral must become a dispatch, 4954), C80 (a stalled task belongs to whoever finds it, 5090), C91 (the orchestration model, 5523), C92 (open work on top, finished work below, 5645), C101 (never hand the CEO a command, 6071), C102 (descend for facts, fan out for opinions, 6169). The Axe Doctrine is the load-bearing one. The CEO, 2026-07-26, verbatim: "permissions only would be needed if agent would want to cut own or other's body part or inventory, but not a tree where is expected to used" (4742-4744). Cutting the tree is the job. Permission is for harm. Leaving a known, harmless-to-fix defect is a violation, not caution.
VI. A fix that helps one agent is half a fix. C1 (kaizen, 440), C5 (learning and standardised adaptability, 480), C35 (self-improvement, 3502), C76 (fix it for everyone, not for one, 4781), C81 (remove deprecated, don't port old habits, 5122), C82 (yokoten — horizontal deployment, 5150), C86 (search first, then append, 5344), C106 (a tool that did not answer what you expected is the work, 6447), C107 (ask the six questions on every task, 6526). Every defect is supposed to end as an encoded check, not as prose, and then reach every vendor — not only the session that found it.
VII. Money is held in trust. C11 (ROI-driven development, 822), C71 (every business is built for repeated sales, 4623), C89 (the treasury mandate, 5442), C93 (do not lose money, do not lose money, do not waste energy, 5699), C95 (name the value or stop the same path, 5840). C89 quotes the CEO directly: "I need that you could cold minded manage our money, and so far I can't trust you because you easily can loose everything" (5444-5448). No expense — euros, tokens, or CEO hours — proceeds without a stated net of upside minus grounded downside.
VIII. A gate must be beatable by the agent it blocks. C21 (loop detection and escalation, 2027), C25 (failed-prevention system, 2254), C36 (Mastermind quality system, 3672), C47 (blast-radius gate before every code change, 3937), C53 (hardcoded gate across every agent, 4128), C60 (Mastermind always, 4245), C96 (a gate must be passable and its escape must be real, 5895). C75 clause 5 states the principle and the measurement behind it: a hard stop whose release condition the blocked agent cannot reach "is a HARNESS DEFECT, not a safety control", grounded in a 2026-07-26 measurement where "12 of 12 recovery handoffs died in postbox/failed and 0 were ever claimed" (4757-4762).
IX. Say it so a person can act on it. C42 (caveman-full output standard, 3812), C44 (design guardrails, 3858), C52 (SYSREF reconstruction-level documentation, 4095), C54 (browser verification for UI changes, 4183), C84 (English is the working language, 5229), C100 (screen automation available to every vendor, 6108), C103 (a report's address is its Hub URL, never a worktree path, 6215). The CEO is not an engineer and English is not his first language. An answer he cannot act on has not been given.
.claude/rules/values-bhagavad-gita.md declares itself supreme over CLAUDE.md and every other rule (:23, "PRECEDENCE — this layer is supreme"). Nine principles, each mapped to concrete conduct (:54-62):
| Principle | What it demands of an agent |
|---|---|
| Satya (truth) | No hedging, no inflated claims, no "should work". Say what is proven and what is not. |
| Ahimsa (non-harm) | Fail closed, reversible, non-destructive by default — extended 2026-08-26 to cover concurrent peers: a colleague's in-flight work is not yours to spend. |
| Nishkama karma (right action) | Do the correct work even when it is harder. Never fake a result to look done. |
| Samatva (evenness) | Own mistakes without collapse and without defensiveness. |
| Lokasangraha (welfare) | Build things that genuinely help a real person, and get fairly paid so the work continues. |
| Svadharma (own duty) | Decide inside your role; don't punt a technical call upward. |
| Yajña / trusteeship (added 2026-08-06) | Every euro and every hour is the CEO's, held in trust. No expense without a stated net. |
.claude/rules/soul.md states the same principles in plain language for a human reader. Its stated test for clarity is that "a smart 14-year-old who knows nothing about tech or business should understand us completely".
Declared at values-bhagavad-gita.md:179, all three sitting under the values:
found_gap_root_cause_unencoded.
that found it. Gate item: kaizen_contribution_missing, whose mandatory question is "what did you leave behind that makes the NEXT agent better off?"
intervention, wait on conditions rather than hammering retries. Gate item: dead_end_loop_hardstop; brute-looping a failing approach is the canonical violation.
Slogans do not bind. Three mechanisms do, and they are named in the file itself:
tools/eidos/values-check.js rolls the value-enforcing checks up under satya / ahimsa / nishkama / svadharma and returns a visible values verdict; the combination of a destructive operation plus an unproven claim is a hard −3 (values-bhagavad-gita.md:14-18).
depth, via caveman-default.md and the valuesMandate dimension of subagent-prompt-quality.js. An agent cannot be launched without them.
tools/eidos/agent-values-coverage.js requires the philosophies token group and the dimensions group (C107:SIX-DIMENSION-TASK-CHECK) to be present on the onboarding source, on every rendered vendor surface, and on the runtime spawn payload tools/autonomous/roles/_mpro-base.md (:202-208). Three layers, checked, so a vendor cannot quietly drift off the values by having an out-of-date prompt.
The most instructive detail is a bug this coverage system caught on itself. C89 records it (constitution.md:5481-5485): the treasury check was first wired to the token c88 — a marker already taken by a different mandate — so it "silently resolved to THAT check and passed no matter what the surface said". A mutation test found it. That is the difference between a governance system and a poster.
Mastermind is a referee that reads your work before you are allowed to say you finished. When an agent tries to end a turn, a Stop hook runs (.claude/hooks/universal-stop.js) and hands the session's transcript, diffs and claims to a scorer (tools/eidos/mastermind-ask.js) built from hundreds of small checks. The checks ask boring, specific questions: did you say "verified" without running anything? Did you commit a file another agent is editing? Did you leave a report row open that is not about money? Did you name a cause your code never actually tested? A grounded safety or hard-policy finding stops the turn. It was born from the failure mode that makes autonomous agents unusable in a business: they finish. They always finish. They produce a confident summary whether the work happened or not, and a non-technical owner has no way to tell the two apart.
Taskman is the ledger that makes work real before it is done. It runs as a service on port 3018 and models everything as nodes (a task, a gap, a problem) and edges (cause and effect). Its contract is deliberately hostile to optimism (tools/mpro-taskman/README.md:25-45): you must claim a node before working, and a second claim gets HTTP 409 so two agents cannot silently work the same thing; every mutation carries provenance (agent, model, effort, tier); and done is explicitly provisional — a claim, not a fact — until a fixed service validator re-runs a stored, re-runnable check and signs the edge. It exists because "the agent said it finished" and "the thing is finished" had turned out to be different states often enough to need different words.
The fence is the layer that refuses. C75 clause 7 names it: "The fence still holds. Autonomy never licenses violating a security control, a data-isolation boundary, or a value" (constitution.md:4766-4768). Concretely it is a library of destructive-command patterns in three tiers — BLOCK (never, no override), FORBID (needs an unlock token), CONFIRM (needs a human) (tools/safety/lib/patterns.js:5-8); a critical-file guard that scales confirmation to blast radius (tools/safety/critical-file-guard.js:8-10); a hash-attestation baseline that fails closed into an emergency lock when a protected file changes unannounced (tools/safety/README.md:11-15); and an output redactor that strips credential-shaped values from tool output before they can enter a transcript. The fence's founding incident is written into the file header: "Last reviewed: 2026-04-27 (CEO Docker volume disaster)".
Why all three, and not just a careful prompt. Each covers a failure the others cannot see. Mastermind catches a false claim. Taskman catches work that quietly never happened. The fence catches an action that cannot be undone. A prompt catches none of them reliably, because a prompt is a suggestion to a system that is optimising for a plausible-looking answer.
An honest list. These are measured, not guessed, and several of them cost more than they saved.
1. A score nobody could ever pass. For months the governing instruction said the gate passed at "score >= 10" and that it "fails closed until it passes". Measured over seven days: 16,263 gate runs, 0 PASS, 846 FAIL, 15,417 UNSCORABLE — and UNSCORABLE never blocks anything (CLAUDE.md:15, correction dated 2026-09-18). So the number that everyone believed was the gate was decoration; the real gate is a two-tier policy that blocks only on a grounded safety or hard-policy row. Delete: the composite score from agent-facing output. A grade that nothing ever earns is not a grade, and publishing it trained a whole fleet to believe a fiction for months.
2. The gate cost more than the work it checked. agent --json was measured at 74,692 ms before a batching pass and 42,999 ms after (tools/eidos/CLAUDE.md, 2026-09-11 A/B table). Worse than slow, one check was blind: a single grep that matched nothing consumed 30,022 ms of a 55,286 ms run — 54% — hit its own 30-second ceiling, was killed every single time, and so "the −3 blocking check returned UNSCORABLE having examined 1 of 208 untracked .js files". A blocking check that examines one file in two hundred and reports nothing is worse than absent: it is absent while looking present. Delete: the per-check timeout pattern that converts a slow check into a silent pass. Fail loud or do not run.
3. Thirteen checks that nothing calls. tools/eidos/ holds 311 *-check.js files. 76 are not named in the three main gate entry points (mastermind-ask.js, mastermind-stop.js, two-tier-gate.js); of those, 63 are reached by some other JavaScript, and 13 have no code caller anywhere — their only mentions are the daily drift snapshots in eidos/memory/drift-*.md, which merely record that the file exists. Measured this run by one indexed pass over tools/, .claude/, core/ and eidos/, excluding each check's own file, its own tests, and the 121 worktree copies; three of the thirteen were then re-verified by hand. The thirteen: ceo-tables-health-check, codex-security-receipt-check, default-seam-coverage-check, docker-runtime-policy-check, external-audit-manifest-check, kimi-check, lane-budget-check, mcp-stdout-safety-check, missing-sink-check, runtime-source-drift-check, subagent-liveness-check, sysref-000-canonical-git-check, tautological-assertion-check. Several of those names describe things you would genuinely want checked — MCP stdout safety, sub-agent liveness, runtime/source drift. Delete or wire all thirteen. A check that exists but runs nowhere is worse than a missing one, because the name in the tree reads as coverage.
Method note worth keeping: the first attempt at this measurement ran 76 separate recursive searches and had to be abandoned after ten minutes of shared CPU. The cause was the repo holding 121 full worktree copies (59 in .wt/, 62 in .claude/worktrees/), which inflated the raw match count from 2,629 to 35,369 — a 13x multiplier that made one check look "referenced" purely by copies of itself. Any repo-wide grep here is wrong by default until those trees are excluded.
4. A check kept alive by a test that asserts it is switched off. tools/eidos/unprobed-ignorance-check.js exists (4,084 bytes, written 2026-07-25) and is referenced by neither Stop gate. A dedicated test file exists purely to pin that fact: .claude/hooks/mastermind-stop.unprobed-ignorance-wiring.test.js:44-45 asserts expect(src).not.toMatch(/unprobed-ignorance-check/), under a describe block titled "is deliberately NOT wired". The honesty is admirable — a parked check declared as parked beats a check falsely advertised as teeth. But it is now three files and a test suite to express "we built this, it produced false positives on ordinary engineering prose, and we left it in the tree". Decide: narrow it and wire it, or delete it. Do not keep paying maintenance on a monument.
5. Article numbering has visibly outrun anyone's ability to keep it straight. Measured this run: 107 distinct articles with exactly one gap (C32 has no heading anywhere, though the number is cited at line 87). C36 appears after C37 in the file (3672 vs 3600). C101 appears before C100 (6071 vs 6108). C73 and C77 are the same policy as two articles — C77's own text says it "elevates" C73's companion rule (4848-4849). And two different rule files both claim C105: .claude/rules/prompt-reading-and-fanout-coverage.md:1 and .claude/rules/subagent-receipts-and-supervision.md:1, while the constitution's own C105 (6393) names only the latter. Delete: the (C105) in the fan-out rule's title; it is three days old and already a second copy of a fact that changes — precisely the debt shape C107 was written to stop.
6. The repo's own map of itself is stale. CLAUDE.md:29 says the rules directory holds 187 files; measured today, 191. CLAUDE.md:31 describes the constitution as "66 articles, numbered to C104"; measured, 107 articles, maximum C107. Not fatal, but it is the same defect the governance keeps warning about — a typed count is a second copy of something that moves. Delete: the typed counts; derive them.
7. Rule sprawl, in families. 191 rule files, many of them one-line pointers. There are at least four rules saying "fix what you find" (fix-what-you-find-no-skip.md, found-issues-no-stop.md, found-it-fix-it-no-avoidance.md, fix-broken-tools-never-just-report.md — each exactly 1 line) and at least five saying "prove your claim" (act-dont-claim.md, action-claim-hard-proof.md, every-claim-hard-proof-tdd.md, no-claim-without-grounding.md, subagent-hardproof-required.md). Delete: merge each family to one rule with one reference body. An agent that must read five files to learn one idea reads none of them well.
8. Lanes accumulate, in two places at once. C87 mandates an isolated worktree per concurrent writer. There are 121 of them right now — 59 under .wt/ and 62 under .claude/worktrees/ — two separate lane trees with different naming conventions. C87 itself cites a 2026-07-26 measurement of "60 worktrees, 20+ live queue dirs", so the count has roughly doubled since the article was written. Isolation is right and must stay; nothing measured here shows the lanes being reaped at the rate they are created, and finding #3 above shows the practical cost: they silently multiply every repo-wide measurement by thirteen.
One thing that looks like over-engineering and is not. C51 — the critical-file guard — was cited "as a real, settled article in at least 14 places across the live repo", including a "fully built, wired, 292-line module literally headed 'Critical File Guard — C51'", while no article text for it existed at all (constitution.md:4043-4051). The mechanism was real; only the law was missing. That is the opposite failure, and worth naming: the risk here is not only writing too much governance, it is shipping mechanisms nobody wrote down.
Seven guards. For each: the risk, the real incident, what the guard does, and what its absence costs.
Risk. "Clean up the old containers" is an ordinary request. Executed literally, it is unrecoverable.
Incident. The destructive-pattern library's header records its founding event: "Last reviewed: 2026-04-27 (CEO Docker volume disaster)" (tools/safety/lib/patterns.js:11). The guard has been broken and repaired repeatedly, each time with the measurement in the file. On 2026-08-27, five of seven git global-option spellings "defeated ALL SIX block-tier patterns", and one form only appeared to be caught "because \bgit\b matches the letters inside the option NAME — an accident, not a protection" (:22-25). On 2026-08-28, five of nineteen adversarial forms "defeated EVERY destructive-git pattern while the unquoted control still blocked, so the guard looked healthy to any probe that used paths without spaces" (:31-36). On 2026-09-16, 66 offline probes found that rm -r -f /, rm -f -r /, rm -Rf /, rm -fR / and rm -rf -- / all classified allow while rm -rf / blocked — "the same total wipe, five spellings apart" (:48-53). Commits: dfd30542702, 8d2eb56aead, 1579fa550e8, 5c0399b646f.
What the guard does. Three tiers — BLOCK with no override, FORBID behind an unlock token, CONFIRM via a human — over roughly eighty command shapes: filesystem wipes, dd to a raw device, mkfs, fork bombs, curl | sh, writes to authorized_keys, docker compose down -v, DROP DATABASE, force-pushes including the ones with no --force flag (git push origin +branch, remote.x.mirror=true), and deletion of MPRO's own restraints (.secure/, .claude/rules/, .claude/hooks/, tools/safety/).
Cost of not having it. One literal-minded cleanup and the business is restoring from backups — if the backups were not on the same volume. The bypass measurements are the real argument: a guard like this is routinely wrong in ways that look fine, so the alternative to maintaining one is not "a simpler guard", it is no guard.
Bonus finding, same family. Commit 334df4f6fc0 is titled "worktree removal was the one destructive op with no gate, and its guard had no caller" — a written guard that nothing invoked. Building the guard is not the same as wiring it.
Risk. A model asked to "log in and check the dashboard" will find the password and type it. It then lives in a transcript, a screenshot, and a log.
Incident and rule. CEO directive 2026-08-27, recorded as an amendment to C75 (constitution.md:4773-4779): three different answers where a model naturally gives one — completing a re-auth consent on an already-signed-in session is ordinary work; entering a secret into a field is forbidden outright; credential rotation and money movement are CEO-personal. The rule body spells out the scope: "password, PIN, card number, CVV, 2FA/OTP, API key, private key, seed phrase, or national identity number" (.agents/skills/mpro-proof-quality/references/no-guessing.md:47-49), and notes that the earlier, gentler protocol has "nothing left to govern" because the agent no longer pastes a secret at all (:45).
Cost. Out of the box, this is the single most likely way an autonomous agent leaks a live credential, and it does it while being maximally helpful.
Risk. A secret written into a config, a systemd unit, or a curl argument. The last one is the subtle one: on a shared machine, every process's command line is world-readable.
Incident. Two P0 credential-exposure rows, fixed in f55ef7ac7da and 35665cf4f82. The commit message states the root cause plainly: Taskman's auth gate covers POST/PATCH/DELETE only — "confirmed live 2026-09-19: GET /api/nodes, /api/search and /api/node/<id> all answer 200 with no Authorization header". So four Stop-gate read paths were loading the master secret to make a call that never authenticates, and a sweep tool was passing Authorization: Bearer <token> on curl argv. Fix: reads stop loading the credential at all; the one real mutation moves the header onto stdin.
What the guard does. One vault (.secure/master.json), one resolver, and a tunnel so that "when a credential changes, you edit the vault ONCE and no consumer is stranded… you get an audit of WHO fetched WHICH credential" (.agents/skills/mpro-security-compliance/references/credential-proxy-mandatory.md:16-21, CEO directive 2026-07-04). Plus a redactor on tool output.
Observed live, this session. While reading that rule file, its own example DSN (postgresql://user:…@) was caught in flight: the tool result came back stamped "[SECRET OUTPUT REDACTED] 1 credential-shaped value(s) redacted: url_userinfo. The values were masked before this result was persisted." The guard works on the agent auditing the guard.
Risk. Dozens of agents in one checkout. git add <path> stages the whole file, not your changes to it.
Incident. C87 states it exactly: "in a shared root a peer's uncommitted edits inside a file you named land in YOUR commit — disclosed retroactively by an Absorbed-path trailer, never prevented" (constitution.md:5397-5400). The same article records stale out-of-lock validation — "declared paths changed after the out-of-lock validation — its verdict is stale. NOTHING was committed" — hitting twice on one file on 2026-08-02, and a 2026-07-26 measurement of "60 worktrees, 20+ live queue dirs".
What the guard does. C79 requires a measurement before touching a shared file — mtime, dirty state, live claims, lane span — and makes ownership tri-state so that unknown fails closed (5067-5069). C87 gives each concurrent writer a private index and working tree. Notably, the article refuses to overclaim: an earlier draft said a worktree gave a separate commit lock, and the correction is written into the article, citing the code and its own docstring (5389-5395).
Cost. Silent corruption of a colleague's in-flight work, attributed to them, discovered days later. This is the failure that does not announce itself.
Risk. An agent with a budget and a plausible plan will spend it plausibly.
Incident A — commit 867208d210c, 2026-09-19. Three of sixteen shots in a client's ad campaign were anchored to the shop's best proof photograph. "That URL is a 404. It returns 130689 bytes of text/html, a WordPress error page." Every layer behaved correctly: the ingest recorded the URL because the shop's own media API listed it; the anchor gate counted it as a real photograph "and allowed the spend — by its own rules it asks whether an anchor EXISTS, and one did"; the generation "was approved, paid, ran ~30s and returned HTTP 500 'Generation request failed', which names nothing an operator can act on". Result: "Three shots, 6 credits, no asset."
Incident B — commit 24146f358c8, 2026-09-20. All ten reference images for a mattress ad were verified by opening them rather than reading their filenames: six were cartoon clipart icons, four were "a GREEN FOAM slab — Olimpus AuraPlus, a different product line with no springs, no latex, no coconut". "Zero of the ten were the product, and every one was labelled in the UI 'Reference photo — real product image, not generated output'." The commit is explicit that prompting could not have saved it: "No prompt rule could reach this: the prompts were fine."
What the guard does. C89 (constitution.md:5442) is the law — no spend without a stated net of upside minus a grounded downside, and a grounded damage path stops the spend instead of being averaged away. The two commits are the encoded version: verify a reference is reachable at ingest (three-valued: usable, not-usable, could-not-find-out), and refuse to anchor a paid generation to an unverified reference.
Cost. Small per event, unbounded in aggregate: "A dead URL is not a one-off — it poisons every future generation anchored to it, silently, at a cost each time."
Risk. The model that did the work is the worst possible judge of whether the work is finished, and it is the judge you get by default.
Incident and rule. CEO, 2026-07-17, quoted in the tool's own header: "always run done status review to claude, kimi, codex if will not left your agents any gaps; to validate fully working solution." (tools/eidos/done-status-review.js:5-6). C70 makes it binding: a completed task is provisional until at least two other top-tier vendors independently review the proof, and Claude-authored work must reach Codex, Kimi and Grok (constitution.md:4610-4621). The reviewer pool is fixed in code and "the authoring agent is ALWAYS excluded (never self-review)" (done-status-review.js:12-14).
What the guard does. Taskman refuses to let done mean finished. Its own README: a self-declared done is provisional; a different agent must re-run the check and confirm the downstream edge's expected effect; a failed peer validation reverts the node to open (tools/mpro-taskman/README.md:7).
Cost. An unchecked agent reports success at a rate close to 100% regardless of outcome. Without a second, differently-built model looking at the artefact, a business running on agent reports is running on a number that means nothing.
Risk. The subtlest one, and the reason this list is not simply "add more gates". A safety control whose release condition is unreachable does not make the system safer — it stops it.
Incident. C75 clause 5 carries the measurement: on 2026-07-26, "a codex Stop awaited a claim only another vendor could make, with no attempt bound, while 12 of 12 recovery handoffs died in postbox/failed and 0 were ever claimed" (constitution.md:4757-4762).
What the guard does. Such a stop is reclassified as a harness defect, not a safety control: it is bounded, made unscorable, or escalated to a live peer. C96 ("a gate must be passable, and its escape must be real", 5895) generalises it, and C107's enforcement notes apply the same discipline to itself — the six-question check is flat, advisory, capped at −2, and fails open, "so a bad or empty input can never wedge the gate for the fleet" (6573-6580).
Cost. Without this rule the harness becomes the outage. It is also the honest answer to the obvious objection to everything above: yes, governance can strangle the work — so the governance carries a clause that says when to get out of the way, with a measurement attached.
An out-of-the-box model is optimised to produce an answer that looks right. None of the seven failures above look wrong at the moment they happen: the cleanup succeeds, the login works, the commit lands, the ad renders, the report says done. The harness exists because "looks right" and "is right" are the same output, and only a measurement taken outside the model can tell them apart.
In plain words: this section is the full parts list of the thing that governs the helpers. Every rule they must follow, every automatic check that catches them breaking one, every point in a conversation where a check runs, and every other helper one of them is allowed to call for help. Nothing here was typed by hand — a program reads the real files and writes the tables, so the list cannot quietly go stale the way a hand-written one does. You do not need to read the long folded tables. The short ones above them are the part that matters.
Regenerate the whole section with one command:
node tools/eidos/governance-inventory.js --write. It writes
docs/mastermind/governance-inventory.json (every row, machine-readable) and splices the
tables below straight into this page, between two markers in its source. There is deliberately
no separate fragment file: a generated intermediate parked in the documentation tree is a
second artifact that drifts from the page it feeds, and every .html under
docs/ is a CEO report by contract — the structure gate was right to reject one. Why a generator and not a table: every check and every hook typed into
this page would be a second copy of a fact that changes daily — the refactor debt C107 rule
9(vi)(a) names. (The totals live in the generated table below and deliberately nowhere else in
this prose. The first draft of this very paragraph quoted them; within hours both had moved by
one, so a section arguing that typed counts go stale had shipped a typed count that was already
stale. The argument never needed the number.) A hand-written table is wrong the morning after it ships, and nobody can tell which
row went stale. Source: tools/eidos/governance-inventory.js, 33 tests, each assertion
proven against a mutant that it kills.
| Level | The question it answers | Which columns carry it |
|---|---|---|
| Logic | What does this thing actually decide, and by what repeatable rule? | What it decides, Gate item(s) it emits, Penalty |
| Structure | Where does it live and what is it wired into? | Check module / Hook file, Reached by |
| Architecture | Which gate path carries it, and therefore which vendors it reaches? | Gate path reached, plus the dispatch table below |
| Operational | When does it fire, and what do I do when it blocks me? | Lifecycle event, Blocks?, and the detail text the gate prints |
One distinction runs through every table and it is the honest core of this section. Behavioural columns — what a module requires, which items it can emit, what it charges, whether it can block — are read from a real JavaScript parser, where comments do not exist. Columns marked declared — the constitution article a file says it enforces, the rule it says it serves — are read from the file’s own comments, because that is the only place that claim lives. Provenance is a claim; wiring is a measurement. They are never mixed, and a declared marker is never used to decide whether a check is live.
Why a parser and not a search. In this codebase a plain text search cannot answer “does this file do X?”. Every hardened module here carries a long comment that quotes the exact names it is describing, so a search counts the documentation as if it were the code. That mistake cost real money three times on 2026-09-20 alone: it inflated a CLI census, invented a stylesheet violation, and nearly drove a 362-file change.
| Was stated as | Actually | Why the first number was wrong |
|---|---|---|
| “195 hooks” | 49 production hooks | The first figure counted .claude/hooks/*.js whole, and three quarters of that directory is *.test.js. Subtract the tests and the governing population is 49. tools/eidos/*-check.js is not affected by the same trap, because a test file there ends .test.js and never -check.js, so the check total needed no correction. Counting two populations the same way is what produced the error — and both raw figures have since moved by one, which is exactly why the live numbers are in the generated table and not in this sentence. |
| 237 checks reach claude only | 0 | An artifact of this tool’s first draft. mastermind-stop.js loads the gate producer through require(path.join(MPRO_ROOT, …)), which a literal-only scan cannot follow, so the entire producer read as unreachable from the shared Stop host. Publishing it would have invented a fleet-wide governance gap out of a parser limitation. |
| 11 hooks wired into nothing | 5 | Same class again. There are two registration surfaces: .claude/settings.json (claude) and vendor-gate-manifest.json sharedEvents (every gate-capable vendor). Reading only the first put mastermind-stop.js itself — the fleet-wide Stop chain — in the dead-code column. A registration surface the instrument does not read looks exactly like an absence. |
The lesson worth more than the three numbers: all three were my own instrument under-reading a path that really existed, and each one produced a confident, specific, publishable finding. A measuring tool that cannot see a path reports that path as a defect. Every count in this section is therefore stated together with the thing that produced it, so the next reader can falsify it rather than inherit it.
There is no single “dispatcher”. Five distinct paths summon other agents and they fire on completely different things — a prompt, a done-claim, an orchestrator decision, a function call, and an end-of-turn score. Collapsing them into one row is how an agent ends up believing a fan-out happened when nothing was spawned. The generated table below names each one with the exact source it was read from.
The mandated reviewer set and the reachable one are different numbers, and both belong here.
done-status-review.js freezes five mandatory reviewers
(claude_code, kimi, codex_gpt, grok_intel, qwen); the author is always excluded, so the
pool for any one author is four. Separately, the orchestrator ran each CLI on 2026-09-20 and
measured kimi 403 monthly-limit, grok 402 balance-exhausted, qwen
403 model-denied — that measurement is the orchestrator’s, not mine; I
did not re-run those CLIs. Taking it at face value the effective pool that day was one, against
a quorum of two. A governance inventory that prints the mandate without the reachability is the
same defect class as a rule nobody enforces, so both are printed and the source of each is
named.
The full counted-and-named populations are in the generated What the join exposes table below. Each one has an owner; none is parked:
| Population | What it means | Owner |
|---|---|---|
| 58 checks reachable from no registered entry point | The module exists and is tested, but no gate path requires it, so nothing it decides ever reaches an agent. Some are deliberately standalone (a ratchet run by hand); the inventory cannot tell those apart from a forgotten wiring, and says so. | problem:mastermind-bird-s-eye-sweep-27-of-166-to-q1t9nf (the standing sweep, updated with today’s figures) |
| 127 checks naming no rule and no article | The check enforces something, but nothing in it says which rule or article. Not dead — unattributed. It means a reader who is blocked cannot find the rule they broke. | task:governance.derived-inventory-of-every-check-hook-rule-article |
| 62 rule files no check references | Governed by prose alone. This is the exact shape that let “reports are HTML, never Markdown” be written, unenforced, and silently broken. | task:governance.prose-only-rules-and-unenforced-articles |
| 27 constitution articles nothing declares it enforces | Same shape, one level up. Listed by id in the generated table so the next pass starts from names, not from a number. | task:governance.prose-only-rules-and-unenforced-articles |
| 5 hooks neither registered nor required | Down from 11 once the second registration surface was read. Several of the remaining five are invoked as command-line tools rather than as hooks — a require-closure cannot see that, and the row says so rather than calling them dead. | task:governance.derived-inventory-of-every-check-hook-rule-article |
| 0 vendor asymmetry at the check level | Every check in the producer is reachable from the shared Stop host, which all six gate-capable vendors spawn. The asymmetry that remains is not per-check: it is that six of the ten roster vendors host the shared Stop at all, for the measured reasons in SYSREF below. | already owned in SYSREF |
A sub-agent’s taskman claim is charged to the parent session as a −3 hard block.
decideGate() in tools/eidos/taskman-db-gate.js decides whether a held lease
belongs to “this session” using agent + session_id only. A
sub-agent spawned with the Task tool inherits the parent’s session_id and
claims under the same agent id, so the parent’s Stop reads the child’s live lease as its
own and emits taskman_claimed_node_unflipped —
TASKMAN CLAIM HELD WITHOUT MOVEMENT. It fired twice in one session on the orchestrator for
leases it never took, and the remedy each time was to hand-write a checkpoint describing work it was
not doing — a false record written to satisfy a gate, which is the part that makes this
a satya problem and not merely an annoyance.
The discriminator already exists in the data. Read back live while writing this version,
the claim row for this very task carries agent_tier: "sub" and a
worktree value naming the sub-agent’s own isolated lane — a different path
from the one the parent’s Stop runs in — alongside the shared session_id. The gate simply does not read either field. Filed, not patched inline:
the module is required by both gate hosts, so changing when a −3 hard block fires has
fleet-wide blast radius, and a peer is editing both hosts right now. Owner:
problem:taskman-db-gate.subagent-claim-charged-to-the-parent-session, which carries the
exact repair and the guard against over-widening it.
These were measured by the orchestrator while this section was being written, and they are included because an inventory that catalogues defect classes without naming the live instances is a taxonomy, not an audit. Every one already carries a task-board id.
| What | Why it belongs in this inventory | Task-board id |
|---|---|---|
The gate producer is running unreviewed bytes. tools/eidos/mastermind-ask.js is modified but uncommitted in the shared checkout (+12/−3, C105 scoring), 19.5 hours dirty with no stamped author. | This is the single file every Stop verdict for every vendor comes from. An inventory of the governance surface that does not notice its own gate is executing uncommitted code has missed the most consequential row on the board — and the whole point of the wiring columns above is to say what is really running. | problem:harness.live-stop-gate-executes-uncommitted-unowned-c105-scoring |
Model registry drift. The registry names one codex model; the live config names another. model-registry-refresh.js --check exits 1. | The single-source rule exists so no agent types a model id. A registry that disagrees with the live config is the source of truth being wrong, which is worse than no source of truth: every provenance stamp downstream inherits it. | problem:governance.model-registry-says-codex-gpt-6-astra-while-live-config-says-gpt-5-6-sol |
| Four model vendors past their one-day verification window — 7 stale lines. | A missing or old verifiedOn is STALE, never a pass. Noted here with its own correction: this was first reported as “7 vendors”; it is 7 lines across 4 vendors. The correction is the point — the same one-population-counted-two-ways error as the 195-hooks row above. | problem:governance.four-model-vendors-past-their-one-day-verification-window |
The sub-agent lease check reads the one endpoint that cannot answer. GET /api/node omits agent_tier and session_id; the changelog carries both. | The companion to the flaw above, and the third instance in this repo of the same trap: a field that exists on one endpoint and is omitted from another, so a check asks the cheap source and gets undefined rather than an error. That is C107 rule 9(vi)(c) — a proxy answered instead of the question. | problem:mastermind.stop-gate-charges-the-parent-for-a-subagents-lease |
Every row below is derived from live source by a parser, never typed. Regenerate with node tools/eidos/governance-inventory.js --write. Generated 2026-09-20T08:13:31.343Z. Behavioural columns (wiring, emitted items, penalty, blocking) come from an @babel/parser AST; columns marked declared come from the file’s own docblock and are a claim, not a measurement.
Derived this run: 310 check modules · 49 hook files · 191 rule files · 69 constitution articles · 102 agent definitions.
Each population is counted AND named. A count with no names is not a finding.
| Population | Count | Names (first 12) |
|---|---|---|
| Check modules reachable from NO registered gate entry point | 58 | adr-index-check.js, boot-guard-check.js, broken-require-check.js, ceo-tables-health-check.js, codex-security-receipt-check.js, consilium-quality-check.js, context-budget-check.js, default-seam-coverage-check.js, docker-runtime-policy-check.js, ecommerce-sysref-reconcile-check.js, external-audit-manifest-check.js, file-placement-check.js |
| Check modules naming no rule and no constitution article (orphan checks) | 127 | absence-proof-check.js, adr-corpus-gate-check.js, analytics-tracking-check.js, assumption-check.js, axi-ergonomics-check.js, boot-guard-check.js, broken-require-check.js, budget-stop-excuse-check.js, can-defer-check.js, capability-punt-check.js, catalog-access-check.js, cited-number-grounding-check.js |
| Rule files no check or hook references (prose-only rules) | 63 | app-control.md, app-discovery.md, ask-the-registry-first.md, auto-mode.md, autonomous-action-and-vendor-parity.md, autonomous-loop-preflight.md, caveman-default.md, ceo-browser-and-screen-are-jane-and-the-extension.md, ceo-notification-traceable-not-spam.md, ceo-question-mastermind-first.md, check-conflicts-before-working.md, check-upgrade-when-broken-or-looping.md |
| Constitution articles nothing declares it enforces | 27 | C19, C20, C21, C22, C23, C24, C25, C48, C49, C52, C53, C54 |
| Hook files neither registered in settings nor required by a registered hook | 5 | ceo-heartbeat-guard.js, eidos-spec-injector.js, essential-services-probe.js, pre-implementation-guard.js, scout-router.js |
| Checks in mastermind-ask.js but NOT in the shared Stop path (claude-only reach) | 0 | (none) |
| Check modules the parser could not read (measurement gap, not a pass) | 0 | (none) |
Each path fires on a different thing. They are never one row.
| Path | Fires when | Dispatches | Source (measured) |
|---|---|---|---|
| multi-delegate-trigger.js | the USER PROMPT matching /\b(audit|harden|fix all (?:the )?(?:gaps|issues|bugs|findings)|close all (?:the )?(?:gaps|issues)|find (?:and|\+|&) fix|review (?:and|\+|&) fix|improve (?:the )?(?:mastermind|harness|gate|hooks)|multi-?delegate|fan-?out|.../ | injects a fan-out mandate (FIND -> CODE -> REVIEW) into the turn; no agent is spawned by this module itself | tools/eidos/multi-delegate-trigger.js (RegExpLiteral, AST) |
| done-status-review.js | a DONE claim on a taskman node (GR-70 cross-vendor validation) | 5 mandated reviewers: claude_code, kimi, codex_gpt, grok_intel, qwen - the AUTHOR is always excluded downstream, so the effective pool for any one author is 4 | tools/eidos/done-status-review.js MANDATORY_REVIEWERS (AST, Object.freeze) |
| .claude/agents/*.md (Task/Agent tool) | the orchestrator choosing a subagent_type; the router matches the agent's own description field | 102 definitions available, grouped in the table below | .claude/agents/ frontmatter (name/model/effort/description) |
| postbox - create-agent-task.js | any agent calling createAgentTask()/ctoEscalationTask(); the bridges poll postbox/pending/ | an asynchronous task file to another vendor's bridge. 34 named entry points, incl: VALID_AGENTS, AGENT_ALIASES, normalizeAgent, verifyTaskSignature, shouldNotifyCeo, CEO_NOTIFICATION_FILTER | tools/autonomous/lib/create-agent-task.js (module.exports.<name> assignments, AST) |
| proactive-dispatch-gate.js | end of turn - the gate asks whether work that should have been delegated was ground out inline | nothing directly; it SCORES the absence of dispatch (C91 orchestrate-don't-grind) | tools/eidos/proactive-dispatch-gate.js |
Gate path is MEASURED by transitive require() closure from each registered entry point.
| Check module | What it decides (declared) | Gate item(s) it emits | Penalty | Blocks? | Gate path reached | Article (declared) |
|---|---|---|---|---|---|---|
absence-proof-check.js | absence-proof-check - a ZERO from a path that does not exist proves NOTHING. | absence_claim_unreadable_path absence_claim_unsound_path | -1 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
action-claim-proof-check.js | action-claim-proof-check - encode-the-bug for .claude/rules/action-claim-hard-proof.md | action_claim_unproven | -3 / 0 | BLOCKS | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
adr-corpus-gate-check.js | the Stop-time half of the executable ADR lifecycle. | — | 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
adr-index-check.js | ADR lane integrity check (C86 + "supersede, do not overwrite"). | — | — | advisory | not wired | C86 |
advice-net-value-check.js | Deterministic enforcement for `.claude/rules/incoming-advice-net-of-damage.md`. | — | -2 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
agent-efficiency-check.js | Mastermind teeth for series best practices (TG AiMastermind pack). | — | 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C85, C72, C90 |
agent-name-model-version-check.js | a CEO-facing label that claims a model version must not lie. | agent_name_model_version_stale agent_name_model_version_unmeasured | -2 / -1 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C96, C107 |
agent-recovery-check.js | enforces .claude/rules/agent-care.md (CEO directive 2026-06-20: | agent_recovery_path_missing | -2 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
ai-dev-cost-bias-check.js | Mastermind gate check for the AI development-cost bias. | — | -1 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
analytics-tracking-check.js | Mastermind gate for analytics-tracking.md (CEO directive 2026-06-15/22). | analytics_tracking_missing | -2 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
announce-only-check.js | CEO directive 2026-05-31. | — | -3 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C68, C96 |
assertion-realignment-check.js | ASSERTION REALIGNMENT - the C10.1 hole the pre-commit gate cannot see. | — | — | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C10 |
assumption-check.js | Assumption check - Mastermind hardwired gate against unverified claims. | — | — | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
authoring-contract-check.js | Is there a shell OPERATOR in this command - as the shell itself would decide? | — | 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C96 |
avoidance-check.js | AVOIDANCE CHECK - a measured diagnosis handed off with no release is a drop, not delegation. | — | -3 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C79 |
axi-ergonomics-check.js | Mastermind gate check for the AXI (Agent eXperience Interface) discipline. | — | -1 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
benchmark-staleness-check.js | benchmark-staleness-check - a MARKET/BENCHMARK number may enter an MPRO report only with a | benchmark_evidence benchmark_number_unsourced benchmark_number_stale | 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C86, C97 |
blocked-without-alternatives-check.js | an agent may report BLOCKED only after it RECORDED | — | 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C84 |
body-validation-check.js | enforces .claude/rules/validate-body-not-title.md v2.0.0 | title_only_validation decision_without_body | -3 / -2 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
boot-guard-check.js | boot-guard-check.js (encode-the-bug gate, task_bf2b4483 / 2026-06-18) | — | — | advisory | not wired | — |
broken-require-check.js | CATCH the broken-require class the harness rescan found (the money-losing | — | — | advisory | not wired | — |
broken-tool-left-check.js | a tool reported BROKEN must be fixed, delegated, or blocked. | broken_tool_left_unfixed | -3 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C68 |
browser-control-path-check.js | Mastermind teeth: live CEO Chrome is controlled only via the any-vendor CLI | browser_control_new_window_or_cdp browser_control_cli_unnamed | -3 / -1 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C86 |
budget-stop-excuse-check.js | CEO directive 2026-07-21: "mastermind to prevent in the future such stops". | — | -3 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
can-defer-check.js | CEO directive 2026-06-11. | — | -3 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
capability-punt-check.js | capability-punt-check - the agent does the work it CAN do; it never hands the CEO a task it | capability_punt_unscorable capability_punt_to_ceo timeout_without_detached_retry incapacity_from_single_probe | -3 / -2 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
catalog-access-check.js | catalog-access-check - does the gate actually REACH the fleet's tool and skill catalogs? | catalog_access | — | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
cause-effect-check.js | Mastermind neurolink teeth for CEO 2026-07-17: | working_contract_unchecked cause_effect_untraced | -3 / -2 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C68 |
ceo-command-handoff-check.js | ceo-command-handoff-check - C101. | ceo_handoff_unscorable command_handed_to_ceo | -3 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C101, C86, C96 |
ceo-readable-link-check.js | CEO directive 2026-06-15. | — | -3 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), tpspg-bridge-hook.js (SessionEnd/SessionEnd (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), pre_tool_use.js (PreToolUse), post_tool_use.js (PostToolUse), universal-stop.js (Stop), context-ceiling-hook.js (UserPromptSubmit/UserPromptSubmit (shared)/PostToolUse (shared)/Stop (shared)), mastermind-pre-task.js (UserPromptSubmit), context-budget-stop-hook.js (Stop (shared)), mastermind-stop.js, stop.js (Stop (shared)) | C87, C96, C84 |
ceo-tables-health-check.js | PURE classifier. | — | — | advisory | not wired | C62 |
cgroup-throttle-check.js | cgroup-throttle-check - detect a service being SQUEEZED by its own memory limit. | cgroup_limit_being_hit | -2 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C3, C96 |
cited-number-grounding-check.js | cited-number-grounding-check - a cited TEST COUNT must have been produced by a run in THIS turn. | cited_number_ungrounded | — | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
claim-grounding-check.js | claim-grounding-check - a claimed command must exist in the ACTUAL tool-call transcript. | — | — | advisory | mastermind-stop.js | C96, C72, C68 |
claim-proof-check.js | CEO directive 2026-07-04: | — | 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
code-index-config-drift-check.js | assert the LIVE ~/.code-index/config.jsonc carries the deltas | — | -1 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C96 |
codex-security-receipt-check.js | — | — | advisory | not wired | — | |
commerce-over-promise-check.js | enforces .claude/rules/honest-advisory-commerce.md (CEO | commerce_over_promise | -3 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
commercial-data-egress-check.js | Mastermind gate for global-rules §6.5 (Data Sovereignty). | commercial_data_egress | -3 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C0 |
commit-claim-check.js | CEO directive 2026-07-04: | commit_claim_unverified | -3 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
commit-punt-check.js | CEO directive 2026-06-27. | commit_punt_to_ceo | -2 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C51 |
commit-quality-check.js | — | 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — | |
config-tamper-check.js | CEO ai-tools "plankton" idea, adopted 2026-07-04. | — | 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C62 |
consent-click-handoff-check.js | consent-click-handoff-check - a CONSENT CLICK handed to the CEO is a C101 violation. | consent_click_handed_to_ceo | -3 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C101, C75 |
consilium-quality-check.js | Mastermind quality gate for a Consilium DELIBERATION result. | — | — | advisory | not wired | — |
consilium-rigor-check.js | CEO directive 2026-06-28. | consilium_weak_one_shot | -3 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C68 |
constitution-marker-coverage-check.js | closes the C88/C89-shaped defect class, generally. | — | — | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C88, C89, C107, C66, C96, C47, C0, C26, C27, C46, C69, C105, C106, C999 |
constraint-inversion-check.js | the CRITICAL-THINKING hard stop (CEO directive 2026-07-17). | constraint_without_inversion | 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
container-restart-policy-check.js | a Docker container the fleet depends on must survive a reboot. | container_restart_policy_no_fleet_match container_restart_policy_unscorable container_wont_survive_reboot container_restart_policy_unreadable | -1 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C68 |
context-budget-check.js | Context Budget Guard (mastermind support) | — | — | advisory | not wired | — |
context-ceiling-blocker-check.js | context_ceiling_used_as_blocker - an agent's OWN exhausted window is not a blocker. | context_ceiling_unscorable context_ceiling_used_as_blocker | -3 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C79 |
context-ceiling-check.js | fail-open | — | — | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), context-ceiling-hook.js (UserPromptSubmit/UserPromptSubmit (shared)/PostToolUse (shared)/Stop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C86 |
context-claim-check.js | catch an UNGROUNDED context-usage claim (CEO directive | — | -2 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
context-routing-check.js | Additive context-routing check (ICM patterns, MIT knowledge). | — | — | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
context-signal-check.js | CEO directive 2026-07-18 | — | 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
control-plane-auth-check.js | Named control-plane CORS star guard. | — | 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C79 |
conversion-tracking-check.js | Mastermind gate that AUTO-FIRES the conversion-flaw tracking consult | conversion_tracking_missing | 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C62 |
correction-propagation-check.js | correction-propagation-check.js | — | 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
coverage-claim-probe-check.js | flag a COVERAGE conclusion that rests only on a reference count. | coverage_claim_unprobed | -1 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
creativity-reward-check.js | Mastermind gate POSITIVE reward signal (report: harness-weakspots, | creativity_reward | 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
credential-incident-check.js | Credential incident completion gate. | credential_incident_open credential_incident_check_error | -3 / 0 | BLOCKS | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
credential-proxy-check.js | CEO directive 2026-07-04: | credential_not_via_proxy | -3 / 0 | BLOCKS | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), unified-tool-hook.js (PreToolUse), post-tool-mux.js (PostToolUse), mastermind-pre-task.js (UserPromptSubmit), credential-proxy-guard.js (PreToolUse (shared)), mastermind-stop.js, stop.js (Stop (shared)) | C62 |
credential-shaped-emission-check.js | the PRODUCER side of the output redactor. | credential_shaped_output_emission | 0 | BLOCKS | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C96 |
cross-model-verification-check.js | GR-70 / C70 teeth: `cross_model_verification_missing`. | cross_model_verification_missing | -1 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C70, C107, C96 |
dead-dependency-check.js | -------------------------------------------------------------------------------------------- | — | 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C78, C69, C80, C68 |
dead-test-path-check.js | dead_test_path - a test suite that dies at LOAD because an artifact it reads is gone. | dead_test_path | — | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C96 |
deadend-sweep-check.js | CEO directive 2026-07-06 (node task:mastermind-pre-summary-deadend-sweep). | deadend_sweep_dirty | -3 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
default-seam-coverage-check.js | find injectable seams whose PRODUCTION default no test ever names. | — | — | advisory | not wired | — |
defer-without-trying-check.js | flags deferring/abandoning a task for "no access / can't login / | defer_without_trying | -2 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
deferred-risk-check.js | CEO directive 2026-06-19 (DISARM SLEEPING BOMBS). | deferred_risk_left | -3 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
design-quality-check.js | the MPRO DESIGN-QUALITY SYSTEM (projects + products + services). | design_quality_gaps | 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
design-redteam-check.js | CEO directive 2026-06-19 (design-os.md). | design_redteam_missing | -2 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
diagram-freshness-check.js | a report diagram must DECLARE its freshness, and a deprecated | — | 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C84, C96, C62 |
dirty-handoff-check.js | dirty_tracked_work_abandoned - charge an agent for finishing while ITS OWN tracked edits sit | dirty_tracked_work_abandoned | 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C79, C85, C97, C96 |
dispatch-outcome-check.js | dispatch-outcome-check - a DISPATCH is not an OUTCOME. | dispatch_died_unreported | -2 / 0 | advisory | mastermind-stop.js | C96 |
doc-readability-check.js | ADVISORY readability gate for CEO-facing docs (item `doc_too_technical`). | — | 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C62 |
doc-structure-order-check.js | CEO directive 2026-06-28: every CEO-facing doc must be UNIFIED and | — | 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), tpspg-bridge-hook.js (SessionEnd/SessionEnd (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), pre_tool_use.js (PreToolUse), post_tool_use.js (PostToolUse), universal-stop.js (Stop), context-ceiling-hook.js (UserPromptSubmit/UserPromptSubmit (shared)/PostToolUse (shared)/Stop (shared)), mastermind-pre-task.js (UserPromptSubmit), context-budget-stop-hook.js (Stop (shared)), mastermind-stop.js, stop.js (Stop (shared)) | C96, C86, C63, C68, C79 |
docker-runtime-policy-check.js | Per-container policy overrides from a declared config (pure, null-safe). | — | — | advisory | not wired | — |
docs-dedupe-check.js | Mastermind gate check that PREVENTS DUPLICATE docs. | docs_duplicate | 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C62 |
docs-structure-check.js | Mastermind gate check that keeps docs/ structured BY TOPIC and stops | docs_root_spam report_outside_docs | 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), pre_tool_use.js (PreToolUse), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C62 |
done-not-verified-check.js | "DONE is not finished; VERIFIED is finished." | taskman_done_not_verified | -3 / -1 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C68, C107 |
ecommerce-sysref-reconcile-check.js | — | — | advisory | not wired | — | |
email-send-safety-check.js | mined from a support-desk/mail integration finding (2026-07-04). | email_send_without_consent | 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C85, C62 |
escalation-direction-check.js | escalation-direction-check - C102: escalation has two axes, and MPRO only ever built one. | escalated_sideways_without_descent | -1 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C102, C96, C68, C97 |
evaluation-not-persisted-check.js | C98 gate item `evaluation_not_persisted` - the tracked increment named in | evaluation_not_persisted | — | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C98 |
experience-first-check.js | the anti-facade gate (CEO directive 2026-07-12). | — | -1 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
explicit-instruction-fidelity-check.js | CEO directive 2026-06-14. | — | -3 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
external-audit-manifest-check.js | — | — | advisory | not wired | C85 | |
external-grounding-check.js | external-grounding-check - an INVESTIGATION-class diagnosis must cite an | — | -3 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C79 |
external-verify-fallback-check.js | External-Verify + Crawl-Fallback checks - the net-new teeth for | memory_trusted_uncompared source_404_no_crawl_fallback | -2 / -1 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
failed-units-check.js | harness-fix-2026-07-04 "Improve next" item 4 (third clause): | failed_mpro_units | 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C62 |
fallback-plan-check.js | Fallback-Plan check - Mastermind "chess expert" deep-planning gate (CEO directive 2026-05-30). | — | -2 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
false-blocker-check.js | a BLOCKER is a claim about live capability. | — | -2 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C75 |
file-placement-check.js | the restructure-audit "teeth" (CEO directive 2026-06-15). | — | — | advisory | not wired | — |
forbidden-git-verbs-check.js | BLOCK the git verbs MPRO forbids in prose but never gated. | — | — | advisory | not wired | — |
found-gap-root-cause-check.js | CEO directive 2026-07-23 (PREVENT FOUND-GAPS' ROOT CAUSES). | found_gap_root_cause_unencoded | 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C76 |
found-issues-check.js | CEO directive 2026-06-11. | — | -3 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
found-mess-ledger-check.js | Mastermind gate for fix-what-you-find-no-skip.md (CEO directive 2026-06-20). | found_mess_untracked | -2 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
found-not-fixed-check.js | — | -2 / 0 | advisory | mastermind-pre-task.js (UserPromptSubmit) | — | |
frankenstein-check.js | — | — | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — | |
frontend-business-impact-check.js | Mastermind gate for | frontend_qa_cta_missing | -3 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
gate-churn-check.js | gate-churn-check - the gate must be able to tell REWORDING from WORKING. | gate_churn_no_work | -2 / 0 | advisory | mastermind-stop.js | — |
gate-escape-valve-check.js | C96: A GATE MUST BE PASSABLE, AND ITS ESCAPE MUST BE REAL. | gate_escape_valve_broken | -1 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C96 |
gate-item-coverage-check.js | measure, at DECLARATION time, how many distinct gate item names | gate_item_declaration_coverage | 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C79 |
generated-source-sync-check.js | Catch a commit that moves a GENERATED file without moving the source it is built from. | — | — | advisory | not wired | — |
git-broker-enforcement-check.js | every agent commits through the broker, or not at all. | git_broker_skipped | -3 | advisory | not wired | — |
global-harness-placement-check.js | PREVENT a GLOBAL-USE harness artifact (a mastermind gate | — | — | advisory | not wired | — |
governance-blockage-recovery-check.js | — | — | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — | |
governance-mirror-check.js | governance-mirror-check - the MISSING CALLER for governance-kb-sync. | governance_kb_mirror_stale | -1 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
governance-theater-check.js | QUANTIFY whether MPRO's rules are actually enforced. | governance_theater_unscorable governance_theater | -1 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C68, C75 |
grok-fleet-auth-provider-check.js | grok-fleet-auth-provider-check.js | — | -1 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
grounded-diagnosis-check.js | enforces .claude/rules/ground-and-search.md. | ungrounded_diagnosis | -3 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
harness-parity-composite-check.js | harness_parity_composite_unscorable | 0 | advisory | not wired | — | |
high-entropy-secret-leak-check.js | high-entropy-secret-leak-check - flag a long hex secret pasted into agent output. | high_entropy_secret_leaked | -1 / 0 | BLOCKS | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), post_tool_use.js (PostToolUse), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C75 |
hook-duplicate-check.js | hook-duplicate-check - find hooks registered MORE THAN ONCE across settings layers. | — | — | advisory | not wired | — |
hook-required-syntax-check.js | refuse to commit an unparseable file that a wired Claude Code | — | — | advisory | not wired | — |
host-pressure-check.js | Aggregate per-process memory into per-COMMAND totals and name the dominant | host_pressure | -2 / -1 / 0 | advisory | not wired | C97 |
html-report-diagram-check.js | Mastermind gate for html-report-diagrams.md (CEO directive 2026-06-21). | — | 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
html-report-img-link-check.js | Mastermind gate: every CEO-facing report <img> must be an | html_report_img_no_link | 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
html-report-stamp-check.js | Mastermind gate for the VISIBLE HEADER stamp (update-stamping.md). | html_report_unstamped report_stamp_stale report_location_stamp dual_side_score_missing git_hygiene_undisclosed | 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), tpspg-bridge-hook.js (SessionEnd/SessionEnd (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), pre_tool_use.js (PreToolUse), post_tool_use.js (PostToolUse), universal-stop.js (Stop), context-ceiling-hook.js (UserPromptSubmit/UserPromptSubmit (shared)/PostToolUse (shared)/Stop (shared)), mastermind-pre-task.js (UserPromptSubmit), context-budget-stop-hook.js (Stop (shared)), mastermind-stop.js, stop.js (Stop (shared)) | C96, C92 |
index-coverage-check.js | 2026-07-17. | — | 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
inline-work-not-spawned-check.js | Mastermind HARD GATE against inline multi-item work. | — | -3 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C73, C72 |
installed-unit-secret-check.js | installed-unit-secret-check - a systemd unit installed in /etc is WORLD-READABLE (0644 by | — | — | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
jane-focus-check.js | C100 - JANE KEY SENT AFTER A CAPTURE WITH NO RE-FOCUS. | jane_key_after_capture_without_refocus | -3 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C100, C97 |
jmunch-family-drift-check.js | jmunch-family-drift-check - the four jMunch tools must not silently drift apart. | jmunch_family_drift | 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C75 |
kaizen-contribution-check.js | A defect became something durable a later agent can open. | — | -1 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
kb-dedupe-check.js | — | — | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C62 | |
kb-ingest-visuals-check.js | kb-ingest-visuals-check - a KB article built from an external source must carry that source's | — | 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C96 |
kimi-check.js | kimi-check - CLI helper for any agent to verify its current git diff | — | — | advisory | not wired | — |
lane-budget-check.js | pre-creation BUDGET check for git worktree ("lane") creation. | — | — | advisory | not wired | C87, C96 |
lane-dirty-check.js | lane-dirty-check - AUTOMATIC prevention of abandoned dirty worktrees. | — | -3 / -1 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C96, C79 |
lane-profile-pin-check.js | DISPOSITION: BLOCKED. | — | — | advisory | not wired | — |
lane-tenancy-check.js | LANE TENANCY CHECK - mastermind item `lane_shared_by_multiple_sessions` (C87 rule 1a). | — | 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C87, C86, C96, C79 |
lean-ctx-live-capacity-check.js | wait for a valid protocol row | — | — | advisory | not wired | — |
ledger-drift-check.js | ledger_drift_unrecorded_writes - name the shell-authored edits BEFORE the commit is refused. | — | 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C96, C101 |
legal-compliance-check.js | CEO directive 2026-06-15: | legal_compliance_unverified | -3 / 0 | BLOCKS | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
live-agent-sweep-check.js | Resolve a task .output entry to its real byte size. | — | -1 / 0 | advisory | subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-stop.js | — |
loop-dead-end-check.js | — | — | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — | |
loop-preflight-check.js | DISPOSITION: BLOCKED. | — | — | advisory | not wired | — |
loopback-auth-running-check.js | LANDED-vs-RUNNING for A4 requireLoopbackAuth on the three control-plane units. | — | 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
mandate-invariant-check.js | mandate-invariant-check - does a mandate still SAY anything, or is it just labelled? | — | — | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C84, C101, C85, C87, C97, C99, C75 |
mcp-stdout-safety-check.js | detect console.log() (stdout) writes reachable from an MCP | — | — | advisory | not wired | C79 |
mcp-transport-migration-check.js | mcp-transport-migration-check - prove that a stdio MCP server moved to streamable HTTP has | — | — | advisory | not wired | C96, C97 |
memory-index-budget-check.js | Fail-closed byte-budget guard for the curated project MEMORY.md head. | memory_index_budget_unscorable memory_index_budget_exceeded memory_index_reference_integrity_failed memory_index_reference_unscorable | -3 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C96, C107 |
merge-backlog-check.js | merge-backlog gate item 'merge_backlog_unenforced' | merge_backlog_unenforced | 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C96 |
mermaid-readability-check.js | mermaid-readability-check - a diagram must be readable by a HUMAN, or it does not ship. | mermaid_unreadable | -2 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
mess-check.js | fail-open: behave as durable-absent | — | 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), tpspg-bridge-hook.js (SessionEnd/SessionEnd (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), pre_tool_use.js (PreToolUse), post_tool_use.js (PostToolUse), universal-stop.js (Stop), context-ceiling-hook.js (UserPromptSubmit/UserPromptSubmit (shared)/PostToolUse (shared)/Stop (shared)), mastermind-pre-task.js (UserPromptSubmit), context-budget-stop-hook.js (Stop (shared)), mastermind-stop.js, stop.js (Stop (shared)) | C96 |
missing-sink-check.js | missing-sink-check - a field that is READ everywhere and WRITTEN nowhere. | — | — | advisory | not wired | — |
model-claim-check.js | CEO directive 2026-07-03: | model_claim_ungrounded | -3 / -1 / 0 | BLOCKS | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
model-evaluation-proof-check.js | — | -3 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — | |
model-registry-stale-check.js | `model_registry_stale`: the staleness the daily refresh MEASURES | — | -1 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
money-work-review-check.js | CEO directive 2026-07-02, rule | money_work_unreviewed | -3 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
mount-topology-safety-check.js | no code path may bind a directory onto its own descendant. | — | -1 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), pre_tool_use.js (PreToolUse), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C76, C96 |
mutation-probe-coverage-check.js | MUTATION PROBE COVERAGE - stop a committed probe from rotting. | — | 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C96 |
n8n-local-zombie-check.js | DISPOSITION: BLOCKED. | — | — | advisory | not wired | — |
named-open-finding-stop-check.js | named-open-finding-stop-check.js | named_open_finding_then_stop | -3 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
new-tool-no-sysref-check.js | Mastermind advisory gate (task:eidos.new-tool-sysref-gate). | — | 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C62 |
node-storm-check.js | Linux node-process-storm detector for the Mastermind gate. | — | 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C96 |
nodenext-import-ext-check.js | CATCH the treasury-class deploy-blocker: a RELATIVE import/export | — | — | advisory | not wired | — |
nonstop-idle-stop-check.js | CEO directive 2026-07-22. | nonstop_idle_stop | -3 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
npm-audit-check.js | Mastermind dependency-vulnerability gate. | npm_audit_vulnerable | -1 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
opc-duplicate-bridge-check.js | DISPOSITION: BLOCKED. | — | — | advisory | not wired | — |
open-report-rows-check.js | own_report_rows_still_open - an agent may not stop while its OWN report still has rows. | — | 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), tpspg-bridge-hook.js (SessionEnd/SessionEnd (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), pre_tool_use.js (PreToolUse), post_tool_use.js (PostToolUse), universal-stop.js (Stop), context-ceiling-hook.js (UserPromptSubmit/UserPromptSubmit (shared)/PostToolUse (shared)/Stop (shared)), mastermind-pre-task.js (UserPromptSubmit), context-budget-stop-hook.js (Stop (shared)), mastermind-stop.js, stop.js (Stop (shared)) | C96, C101, C107, C51 |
ops-discipline-check.js | Mastermind teeth for C90 living ops discipline. | — | 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C90, C69 |
orchestration-required-check.js | runOrchestrationRequiredCheck - the ORCHESTRATOR MANDATE gate (CEO directive 2026-08-02). | incidental_blocker_unfixed orchestration_missing | -3 / -1 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C86, C96, C79 |
orchestrator-supervision-check.js | UNDETERMINED_WORKER_STATUSES - the split this module was missing. | — | -3 / -1 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
orphan-process-check.js | orphan-process-check - mastermind orphan-generator hunter (CEO directive 2026-06-06). | orphan_processes | 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
orphan-tool-check.js | ORPHAN-TOOL CHECK - prevent the "built a tool, left it manual" mistake (CEO 2026-07-20). | manual_tool_left | -2 / 0 | advisory | not wired | C97 |
ownership-drift-check.js | DISPOSITION: DELIBERATE. | — | — | advisory | not wired | — |
parallel-dispatch-isolation-check.js | PARALLEL DISPATCH ISOLATION CHECK - mastermind item `parallel_dispatch_not_isolated` (C87). | — | -1 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C87, C86 |
pg-control-plane-check.js | — | — | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — | |
pgrep-selfmatch-check.js | CEO directive 2026-07-17 ("again; fix mastermind"). | — | 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
playwright-profile-check.js | CEO directive 2026-06-13. | blank_playwright_profile | -3 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
pm-brain-check.js | PM Brain gate (mastermind support) | pm_brain_decision_debt pm_brain_commerce_sync pm_brain_stale_hypotheses pm_brain_check_error | -2 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
pm2-direct-shell-check.js | — | — | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — | |
pm2-verb-safety-check.js | — | -3 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — | |
ponytail-yagni-check.js | Mastermind gate check for the ponytail (YAGNI / lazy-senior) discipline. | — | -1 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
portability-check.js | Portability Check - refuse a portable bundle that carries machine-specific | — | — | advisory | not wired | — |
post-edit-grep-check.js | a fast, DETERMINISTIC mechanical grep pass over CHANGED source | post_edit_grep | 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C62 |
predict-cost-check.js | LeCun/JEPA -> MPRO, FIX 1: predict-then-act (pre-action predicted cost). | — | — | advisory | unified-tool-hook.js (PreToolUse), post-tool-mux.js (PostToolUse) | — |
proc-path-write-check.js | proc-path-write-check - a /proc path used as a WRITE TARGET is an infinite loop, not an error. | — | — | advisory | not wired | C68 |
project-cleanup-check.js | CEO directive 2026-06-17 ("pedantic cleanups after each project"). | — | -3 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
promise-fulfillment-check.js | unfulfilled_delivery_promise | -3 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — | |
promise-kept-check.js | promise-kept-check - a PRESENT-TENSE claim that an action is happening must be backed by the | promise_not_kept | -3 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C96 |
prompt-cache-check.js | Prompt-Cache Awareness check for the Mastermind gate. | prompt_cache_low_hit_rate | — | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
quarantine-adjudication-check.js | — | — | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C96 | |
raw-nul-source-check.js | raw-nul-source-check - block a RAW 0x00 byte from entering JS/TS source. | — | — | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
real-life-test-claim-check.js | CEO directive 2026-06-30. | real_life_test_skipped | -2 / 0 | BLOCKS | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
real-validation-check.js | lock already gone | — | -3 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
recommended-executor-spawn-check.js | recommended-executor-spawn-check.js | recommended_executor_spawn_mismatch | -1 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C76 |
redaction-is-not-absence-check.js | redaction-is-not-absence-check - a mask is the OPPOSITE of an absence. | absence_claimed_over_redacted_output | -2 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
reference-bar-check.js | Mastermind gate: don't ship BELOW the reference bar the user set and call | reference_bar_unmet | -3 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
registry-first-check.js | Mastermind-callable arm for C104 (ASK THE REGISTRY FIRST). | — | — | advisory | not wired | C104, C96, C97, C91 |
registry-freshness-check.js | DISPOSITION: BLOCKED. | — | — | advisory | not wired | — |
registry-inventory-check.js | registry-inventory-check - the PURE brain of the daily harness-registry OWNERSHIP audit. | — | — | advisory | not wired | — |
repo-root-grep-check.js | ADVISORY (never blocks) recognizer for a recursive `grep` issued at | — | — | advisory | pre_tool_use.js (PreToolUse) | C97, C106 |
report-contract-self-check.js | — | — | advisory | not wired | — | |
report-contrast-check.js | STATIC WCAG contrast governance for CEO-facing reports. | report_text_contrast | 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C96, C86 |
report-delivered-check.js | CEO directive 2026-07-05 (CRITICAL GLOBAL GOVERNANCE): | ceo_report_not_delivered | -3 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), tpspg-bridge-hook.js (SessionEnd/SessionEnd (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), pre_tool_use.js (PreToolUse), post_tool_use.js (PostToolUse), universal-stop.js (Stop), context-ceiling-hook.js (UserPromptSubmit/UserPromptSubmit (shared)/PostToolUse (shared)/Stop (shared)), mastermind-pre-task.js (UserPromptSubmit), context-budget-stop-hook.js (Stop (shared)), mastermind-stop.js, stop.js (Stop (shared)) | C76, C96, C75 |
report-delivery-check.js | Mastermind gate: a REPORT-WORTHY task must be delivered | report_delivery report_delivery_unscorable report_not_delivered | -3 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), tpspg-bridge-hook.js (SessionEnd/SessionEnd (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), pre_tool_use.js (PreToolUse), post_tool_use.js (PostToolUse), universal-stop.js (Stop), context-ceiling-hook.js (UserPromptSubmit/UserPromptSubmit (shared)/PostToolUse (shared)/Stop (shared)), mastermind-pre-task.js (UserPromptSubmit), context-budget-stop-hook.js (Stop (shared)), mastermind-stop.js, stop.js (Stop (shared)) | C96 |
report-local-palette-check.js | report-local-palette-check - a docs report must not carry its own colour palette. | report_local_palette | -2 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), tpspg-bridge-hook.js (SessionEnd/SessionEnd (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), pre_tool_use.js (PreToolUse), post_tool_use.js (PostToolUse), universal-stop.js (Stop), context-ceiling-hook.js (UserPromptSubmit/UserPromptSubmit (shared)/PostToolUse (shared)/Stop (shared)), mastermind-pre-task.js (UserPromptSubmit), context-budget-stop-hook.js (Stop (shared)), mastermind-stop.js, stop.js (Stop (shared)) | — |
report-no-stop-check.js | report-no-stop-check - encode-the-bug for the recurring failure: the CEO says "fix until ALL gaps | report_no_stop report_incomplete_stop | -3 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), tpspg-bridge-hook.js (SessionEnd/SessionEnd (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), pre_tool_use.js (PreToolUse), post_tool_use.js (PostToolUse), universal-stop.js (Stop), context-ceiling-hook.js (UserPromptSubmit/UserPromptSubmit (shared)/PostToolUse (shared)/Stop (shared)), mastermind-pre-task.js (UserPromptSubmit), context-budget-stop-hook.js (Stop (shared)), mastermind-stop.js, stop.js (Stop (shared)) | C96, C79, C107 |
report-overwrite-intent-check.js | report_version_rolled_back report_overwrite_without_intent_check report_overwrite_intent | -3 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — | |
report-quality-check.js | CEO directive 2026-07-16. | — | 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), tpspg-bridge-hook.js (SessionEnd/SessionEnd (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), pre_tool_use.js (PreToolUse), post_tool_use.js (PostToolUse), universal-stop.js (Stop), context-ceiling-hook.js (UserPromptSubmit/UserPromptSubmit (shared)/PostToolUse (shared)/Stop (shared)), mastermind-pre-task.js (UserPromptSubmit), context-budget-stop-hook.js (Stop (shared)), mastermind-stop.js, stop.js (Stop (shared)) | — |
requirement-coverage-check.js | Deterministic, conservative segmentation. | requirement_coverage | 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C86 |
responsive-html-check.js | — | — | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), tpspg-bridge-hook.js (SessionEnd/SessionEnd (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), pre_tool_use.js (PreToolUse), post_tool_use.js (PostToolUse), universal-stop.js (Stop), context-ceiling-hook.js (UserPromptSubmit/UserPromptSubmit (shared)/PostToolUse (shared)/Stop (shared)), mastermind-pre-task.js (UserPromptSubmit), context-budget-stop-hook.js (Stop (shared)), mastermind-stop.js, stop.js (Stop (shared)) | — | |
root-unit-repo-write-check.js | root-unit-repo-write-check - does a systemd unit run as ROOT while executing code | — | — | advisory | not wired | C79 |
route-around-fix-check.js | CEO directive 2026-06-29. | routed_around_unfixed | -3 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
rule-compression-check.js | rule-compression-check - prove a shortened rule still binds everything it bound. | — | — | advisory | not wired | — |
rule-enforcement-pointer-check.js | does the module a rule NAMES as its enforcement actually | — | 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C96 |
run-drift-check.js | Eidos Drift Checker - v2 | — | — | advisory | not wired | C96 |
run-rederivation-check.js | run-rederivation-check - a finished RUN is re-derived from its artifacts before it is called | run_status_not_rederived | 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C86 |
runtime-source-drift-check.js | DISPOSITION: BLOCKED (transient reason CLEARED, new reason found). | — | 0 | advisory | not wired | C79 |
rust-test-target-check.js | Rust test-target gate (CEO directive 2026-05-30). | — | -2 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
samatva-check.js | SAMATVA CHECK - equanimity under failure (BG 2.48): apology THEATRE is the violation, | samatva_theatre | -1 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C76 |
sample-as-population-check.js | a conclusion drawn from a SAMPLE may not be stated as a fact | sample_as_population | -1 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C86, C97 |
scheduler-semantics-check.js | — | — | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — | |
scorecard-improvement-check.js | CEO directive 2026-07-27. | scorecard_improvement_missing | -1 / 0 | advisory | unified-tool-hook.js (PreToolUse), post-tool-mux.js (PostToolUse), auto-open-html-hook.js (PostToolUse (shared)/Stop (shared)) | — |
scratch-cleanup-check.js | orchestrator_cleanup | 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — | |
screen-capture-blindness-check.js | screen_capture_blind - catch an agent that "looked at the screen" through a path that cannot see. | screen_capture_blind | -2 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
screenshot-freshness-check.js | P1 / HARN-9 (CEO directive 2026-06-28, harness audit | — | 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
security-scan-trigger-check.js | CEO directive 2026-06-22 (security-scanning-harness.md + skill ccso-skill). | security_scan_recommended | 0 | BLOCKS | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C63, C96, C107 |
self-cleanup-check.js | self-cleanup-check - "clean up after YOURSELF, and only after yourself" (CEO directive 2026-08-27) | — | 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C50, C84, C87 |
self-started-server-check.js | self-started-server-check - "close the terminals + servers you opened" (CEO directive 2026-07-22) | self_started_server_left_running | 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C50 |
service-exec-drift-check.js | service-exec-drift-check - does the RUNNING service execute the code we think we shipped? | — | 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C96, C97, C4 |
share-integrity-check.js | @codex-fail-open-ok: an unreadable buffer means no evidence was FOUND, not that evidence is absent - the caller still needs a session-touched hit before it charges anything | — | 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C96, C62 |
shared-root-commit-check.js | SHARED-ROOT COMMIT CHECK - mastermind item `commit_outside_project_lane`. | — | -2 / -1 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
silent-revert-check.js | Catch a commit that silently replaces a tracked file with an OLDER copy of itself. | — | — | advisory | not wired | C107 |
single-sample-rate-check.js | single-sample-rate-check - a rate about LIVE state, read once, is a sample and not an answer. | single_sample_rate_claim | -2 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C97 |
skill-description-density-check.js | skill-description-density-check - a skill the router cannot tell apart from its neighbour is a | skill_desc_too_thin skill_desc_bloated skill_no_triggers skill_no_negative_boundary | 0 | advisory | not wired | — |
skill-health-check.js | Skill Health Corpus Scorer — Mastermind advisory gate | — | 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
skill-index-populated-check.js | proves the skill routing index actually has data in it. | — | — | advisory | mastermind-pre-task.js (UserPromptSubmit) | — |
skill-standard-check.js | Skill Standard Check - per-SKILL.md authoring scorer for Mastermind. | — | — | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
spawn-tier-check.js | spawn-tier-check - size a dispatched executor by the TASK'S RESPONSIBILITY, not by habit. | — | -1 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
stale-checkout-check.js | DISPOSITION: WIRED. | stale_checkout_surface | 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C96 |
stale-graft-check.js | Catch a land that was authored against a base PREDATING its own parent, and so silently drops | — | — | advisory | not wired | C96, C97, C107 |
stale-hook-tool-check.js | DISPOSITION: WIRED 2026-09-11 - tools/eidos/mastermind-ask.js calls runStaleHookToolCheck in BOTH | — | 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C96 |
stale-model-name-check.js | Mastermind hunt for HARDCODED / stale local-model names. | stale_model_name | — | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
stale-service-code-check.js | is a long-running service still executing code the repo already fixed? | — | — | advisory | not wired | — |
stamp-time-truth-check.js | stamp-time-truth-check - a report stamp may never claim a time that has not happened. | — | — | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), tpspg-bridge-hook.js (SessionEnd/SessionEnd (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), pre_tool_use.js (PreToolUse), unified-tool-hook.js (PreToolUse), post-tool-mux.js (PostToolUse), post_tool_use.js (PostToolUse), universal-stop.js (Stop), context-ceiling-hook.js (UserPromptSubmit/UserPromptSubmit (shared)/PostToolUse (shared)/Stop (shared)), mastermind-pre-task.js (UserPromptSubmit), auto-open-html-hook.js (PostToolUse (shared)/Stop (shared)), context-budget-stop-hook.js (Stop (shared)), mastermind-stop.js, stop.js (Stop (shared)) | — |
stop-claim-verification-check.js | CEO directive 2026-07-01 (Stop-gate anti-hallucination). | stop_claim_unverified | -3 / 0 | advisory | mastermind-stop.js | — |
stop-question-escalation-check.js | C69 enforcement (CEO 2026-07-15 + 2026-07-17). | technical_question_to_ceo_unrouted | -3 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C69, C96 |
subagent-contract-check.js | the DISPATCH-side half of subagent-hardproof-required.md v1.1.0. | — | 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C96 |
subagent-failure-check.js | no ledger -> unknown -> fall back to text | subagent_planlimit_unrecovered | -3 / -2 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C68 |
subagent-liveness-check.js | subagent-liveness-check - tell APART "finished", "working" and "actually hung". | — | — | advisory | not wired | C77 |
subagent-model-visibility-check.js | Mastermind gate check for sub-agent model+effort visibility. | — | -1 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
subagent-proof-check.js | DISPOSITION: WIRED. | — | 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
subagent-scope-check.js | hunt sub-agents that edited files OUTSIDE their declared scope. | subagent_out_of_scope | 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
superiority-admission-check.js | CEO directive 2026-05-30. | — | -3 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), tpspg-bridge-hook.js (SessionEnd/SessionEnd (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), pre_tool_use.js (PreToolUse), post_tool_use.js (PostToolUse), universal-stop.js (Stop), context-ceiling-hook.js (UserPromptSubmit/UserPromptSubmit (shared)/PostToolUse (shared)/Stop (shared)), mastermind-pre-task.js (UserPromptSubmit), context-budget-stop-hook.js (Stop (shared)), mastermind-stop.js, stop.js (Stop (shared)) | C63, C76 |
suppressed-stderr-probe-check.js | a probe that hides its own crash reports a clean negative. | suppressed_stderr_probe | 0 | advisory | not wired | C96 |
surface-claim-check.js | CEO directive 2026-06-11: | — | -3 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
swap-pressure-check.js | the MEMORY lane the node-storm detector never had. | — | 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
sysref-000-canonical-git-check.js | — | — | advisory | not wired | — | |
sysref-depth-check.js | Compare a SYSREF body against the exports of the JS modules it owns. | sysref_export_coverage_gap | 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C62 |
sysref-localhost-check.js | CEO governance 2026-07-06. | — | 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C62 |
sysref-private-data-check.js | sysref-private-data-check.js | — | — | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
sysref-reality-check.js | noop | — | — | advisory | not wired | — |
system-report-placement-check.js | system-report-placement-check - a report ABOUT a system must live INSIDE that system. | — | -3 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), tpspg-bridge-hook.js (SessionEnd/SessionEnd (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), pre_tool_use.js (PreToolUse), post_tool_use.js (PostToolUse), universal-stop.js (Stop), context-ceiling-hook.js (UserPromptSubmit/UserPromptSubmit (shared)/PostToolUse (shared)/Stop (shared)), mastermind-pre-task.js (UserPromptSubmit), context-budget-stop-hook.js (Stop (shared)), mastermind-stop.js, stop.js (Stop (shared)) | C84, C96 |
systematic-update-check.js | systematic-update-check - HARD REMINDER when a harness change reaches ONE vendor. | systematic_update_single_vendor | -3 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C79 |
tab-hygiene-extension-check.js | tab-hygiene-extension-check - stop every agent re-discovering (or missing) the ONE mechanism | tab_hygiene_extension | 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C75 |
task-dimension-check.js | Mastermind teeth for C107 (CEO directive 2026-09-11). | task_dimension_unnamed refactor_debt_unnamed | -1 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C107, C89, C95, C93, C96, C84, C105, C104, C106, C97 |
taskman-match-check.js | taskman-match-check - surface OPEN taskman nodes that this session's UNDECLARED work touches. | — | 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C68, C96 |
taskman-node-check.js | CEO directive 2026-07-05 (wiki _spec.md ADDENDUM 4) + 2026-07-06 | taskman_verification_unavailable taskman_node_id_missing | -3 / -1 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
taskman-peer-validation-check.js | CEO directive 2026-07-10 (mpro-taskman-lifecycle.md). | taskman_peer_validation_missing | -3 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
taskman-pickup-not-spawned-check.js | Mastermind HARD GATE: a claimed taskman node must be | taskman_pickup_not_spawned | -3 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C96 |
tautological-assertion-check.js | TAUTOLOGICAL ASSERTION - the machine-checkable subset of the §Gaming "Self-confirming" shape. | — | -1 / 0 | advisory | not wired | C96, C84 |
technical-intent-check.js | enforces .claude/rules/ceo-technical-intent.md (CEO directive | technical_intent_ungrounded | -2 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
temp-dir-bloat-check.js | flags oversized/unmanaged temp DIRECTORIES in .tmp. | — | 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C91 |
three-rules-check.js | Mastermind teeth for C93 (CEO 2026-08-10, verbatim): | money_loss_risk_ungated energy_waste_unbounded | -3 / -1 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C93, C89, C86, C9, C8 |
timeout-ceiling-check.js | Mastermind-callable check for too-low timeout ceilings. | — | -1 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C96 |
tool-doc-sync-check.js | CEO mandatory governance directive 2026-07-11. | tool_doc_graph_unsynced | 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C62 |
tool-freshness-check.js | DISPOSITION: BLOCKED. | — | — | advisory | not wired | — |
toolchain-platform-check.js | toolchain-platform-check - name a wrong-platform toolchain binary in PLAIN WORDS. | toolchain_binary_wrong_platform | — | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
treasury-impact-check.js | Deterministic advisory for the treasury mandate's own inversion: a MONEY IMPACT block that is | treasury_impact_unmeasured | -1 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C84, C62, C96, C68 |
truncated-evidence-check.js | truncated-evidence-check - C97: never truncate the evidence you are about to conclude from. | truncated_evidence_conclusion | -3 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C97, C96 |
ttyd-secret-safe-check.js | — | — | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C96 | |
ui-skill-enforcement-check.js | closes the gap between HAVING a skill and USING it. | — | — | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
unbounded-scan-check.js | WARN on a filesystem-wide scan that will blow the Bash timeout and | — | — | advisory | pre_tool_use.js (PreToolUse) | C96 |
unfinished-work-stop-check.js | unfinished-work-stop-check - block a stop that ends on a REMAINING-WORK list. | — | -3 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), tpspg-bridge-hook.js (SessionEnd/SessionEnd (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), pre_tool_use.js (PreToolUse), post_tool_use.js (PostToolUse), universal-stop.js (Stop), context-ceiling-hook.js (UserPromptSubmit/UserPromptSubmit (shared)/PostToolUse (shared)/Stop (shared)), mastermind-pre-task.js (UserPromptSubmit), context-budget-stop-hook.js (Stop (shared)), mastermind-stop.js, stop.js (Stop (shared)) | C96 |
uninvestigated-signal-check.js | the PROACTIVITY hard stop (CEO directive 2026-07-17). | uninvestigated_signal | 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C106, C96, C97 |
unit-install-drift-check.js | unit-install-drift-check - does the systemd unit RUNNING on this box match the one in git? | unit_install_drift_on_touched_unit | -1 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
unit-name-resolution-check.js | unit-name-resolution-check - does the systemd unit a script NAMES actually EXIST? | unit_name_does_not_resolve | 0 | advisory | not wired | C79 |
unlanded-fix-check.js | unlanded-fix-check - "you claimed a fix for THIS FILE; no commit ever touched it". | landing_claimed_not_on_master fixes_claimed_none_landed | -3 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C96 |
unmatched-test-suite-check.js | unmatched-test-suite-check - a test suite jest's testMatch CANNOT SEE protects nothing. | test_suite_unmatched_by_jest | — | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C97, C96 |
unprobed-ignorance-check.js | unprobed-ignorance-check - claiming you don't have something, without probing for it. | — | — | advisory | not wired | C72 |
unpushed-work-check.js | classifyPushFailure(text) -> 'network' | 'auth' | 'rejected' | 'unknown' | unbacked_work unbacked_work_uncommitted unbacked_work_unresolved_session branch_diverged_from_upstream unbacked_work_unpushed_offline unbacked_work_unpushed | -3 / -1 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), tpspg-bridge-hook.js (SessionEnd/SessionEnd (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), pre_tool_use.js (PreToolUse), post_tool_use.js (PostToolUse), universal-stop.js (Stop), context-ceiling-hook.js (UserPromptSubmit/UserPromptSubmit (shared)/PostToolUse (shared)/Stop (shared)), mastermind-pre-task.js (UserPromptSubmit), context-budget-stop-hook.js (Stop (shared)), mastermind-stop.js, stop.js (Stop (shared)) | C96 |
unregistered-worktree-dir-check.js | a directory git does not know about is a directory no | unregistered_worktree_dir | 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C96, C107 |
unsorted-set-comparison-check.js | @param {string} command - the raw Bash command, before the shell runs it. | — | — | advisory | pre_tool_use.js (PreToolUse) | C97 |
untested-tool-claim-check.js | CEO directive 2026-06-29. | untested_tool_claim | -3 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C68, C84, C96, C97 |
untracked-dependency-check.js | referencesRequireForm - does `blob` contain an ACTUAL require/import of a module whose final | — | -3 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C79, C62, C97, C96 |
untracked-require-check.js | a TRACKED .js may not require a relative module git does not track. | — | 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C86, C96, C79 |
untracked-required-module-check.js | DISPOSITION: BLOCKED. | untracked_required_module | 0 | advisory | not wired | — |
untracked-test-guard-check.js | an UNTRACKED *.test.js is a guard that NOTHING RUNS. | untracked_test_guard | -1 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C86, C87, C96 |
unverified-assumption-check.js | — | -2 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — | |
user-facing-realtest-check.js | CEO directive 2026-07-03 (business-critical). | user_facing_untested | -3 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C76 |
vacuous-test-run-check.js | vacuous-test-run-check - a test run that found ZERO tests may never read as a PASS. | vacuous_test_run | -3 / 0 | BLOCKS | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
validated-against-unlanded-tree-check.js | validated-against-unlanded-tree-check.js | — | 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C79, C96 |
value-question-check.js | Mastermind teeth for C95 (CEO 2026-08-16). | — | 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C95, C89 |
values-check.js | Bhagavad-Gita values gate - runValuesCheck (CEO directive 2026-06-17). | values_unscorable values_satya_harm values_violation | -3 / 0 | BLOCKS | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C1, C79, C87, C107 |
vault-path-check.js | CEO directives 2026-06-28: | vault_path_legacy consolidation_claim_unproven | -3 / 0 | BLOCKS | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C62, C96 |
vendor-exhaustion-check.js | C102: a depleted vendor is a ROUTING problem, not a stopping condition. | vendor_exhaustion_reported_as_blocker | -2 / 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C102, C96 |
vendor-gate-sync-check.js | round-robin cross-vendor gate-script PARITY check. | — | — | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C96, C76 |
vendor-identity-coverage-check.js | vendor-identity-coverage-check - a hand-rolled session-marker list must be COMPLETE. | vendor_identity_marker_list_incomplete | 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C76, C96, C84 |
vendor-onboarding-check.js | is vendor X actually onboarded, and if not, what exactly is missing? | — | — | advisory | not wired | C97, C96, C84, C85, C86, C76 |
verify-circular-check.js | CIRCULAR-VERIFY DETECTOR (2026-08-09). | — | — | advisory | not wired | — |
website-perf-check.js | WEBSITE QUALITY GATE (Lighthouse >= 9.5/10). | — | 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | — |
win-leftover-check.js | U+XXXX for one character - the report names the code point, never echoes the byte. | win_migration_leftover | 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C62 |
wired-not-shipped-check.js | -check.js modules are wired into NOTHING. | — | -3 / 0 | advisory | mastermind-stop.js | — |
worktree-evidence-root-check.js | worktree-evidence-root-check - bind EXECUTION PROVENANCE to the worktree a task actually claimed. | — | — | advisory | mastermind-stop.js | C96 |
worktree-hygiene-check.js | CEO directive 2026-06-17. | — | 0 | advisory | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), mastermind-pre-task.js (UserPromptSubmit), mastermind-stop.js, stop.js (Stop (shared)) | C96, C97 |
Event is read from the live settings registration; reached-by is the require closure.
| Hook file | Lifecycle event | What it does (declared) | Can block? | Reached by |
|---|---|---|---|---|
adr-lifecycle-hook.js | SessionStart, SessionStart (shared) | the quality-harness executable-ADR lifecycle, reached by EVERY vendor at | no | — |
ask-ceo-gate.js | PreToolUse | PreToolUse gate for AskUserQuestion. | yes | — |
auto-open-html-hook.js | PostToolUse (shared), Stop (shared) | PostToolUse(Write) thin runner (CEO directive 2026-07-05 / 2026-07-17). | no | unified-tool-hook.js (PreToolUse), post-tool-mux.js (PostToolUse) |
auto-open-kb-hook.js | PostToolUse (shared) | PostToolUse(Bash): when a KB article is CREATED or UPDATED via the | no | — |
ceo-heartbeat-guard.js | not registered | PreToolUse hook (CommonJS, ASCII only - C62). | yes | — |
code-formatter-hook.js | not registered | MPRO Code Formatter PostToolUse Hook | no | unified-tool-hook.js (PreToolUse), post-tool-mux.js (PostToolUse) |
context-budget-stop-hook.js | Stop (shared) | Mastermind Context-Health Gate (Stop hook) | yes | — |
context-ceiling-hook.js | UserPromptSubmit, UserPromptSubmit (shared), PostToolUse (shared), Stop (shared) | GLOBAL 70% auto-compact ceiling (UserPromptSubmit). | no | — |
context-window-stop-gate.js | Stop (shared) | the Stop chain's ONLY window-aware gate. | no | — |
credential-proxy-guard.js | PreToolUse (shared) | PreToolUse PREVENT-IN-ADVANCE guard for credential-proxy violations. | no | unified-tool-hook.js (PreToolUse), post-tool-mux.js (PostToolUse) |
db-url.js | not registered | Canonical Postgres URL builder for the compaction hooks (pre-compact / post-compact / | no | post-compact-reload.js (SessionStart/PostCompact/PostCompact (shared)), post-compact.js (PostCompact/PostCompact (shared)) |
dispatch-record.js | not registered | dispatch-record - build the ledger record for a sub-agent spawn so MODEL and EFFORT survive. | no | mastermind-ask.js, session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)), tpspg-bridge-hook.js (SessionEnd/SessionEnd (shared)), non-stop-loop-stop.js (SubagentStop/SubagentStop (shared)/Stop (shared)), subagent-stop.js (SubagentStop/SubagentStop (shared)), pre_tool_use.js (PreToolUse), post_tool_use.js (PostToolUse), universal-stop.js (Stop), context-ceiling-hook.js (UserPromptSubmit/UserPromptSubmit (shared)/PostToolUse (shared)/Stop (shared)), mastermind-pre-task.js (UserPromptSubmit), context-budget-stop-hook.js (Stop (shared)), mastermind-stop.js, stop.js (Stop (shared)) |
eidos-spec-injector.js | not registered | Eidos Spec Injector - PreToolUse hook | no | — |
essential-services-probe.js | not registered | Active essential-services probe (CEO directive 2026-05-24). | no | — |
fence-cancel-on-deny.js | not registered | fence-cancel-on-deny - stop claude leaking one unresolved fence receipt per refused tool call. | no | pre_tool_use.js (PreToolUse) |
flat-tasklist-guard.js | not registered | flat-tasklist-guard - PreToolUse (Write|Edit|MultiEdit) | no | unified-tool-hook.js (PreToolUse), post-tool-mux.js (PostToolUse) |
index-scope-guard.js | PreToolUse | Index Scope Guard - PreToolUse | yes | — |
insight-capture.js | SessionEnd, StopFailure, PreCompact, PreCompact (shared), Stop (shared), SessionEnd (shared) | MPRO Insight Capture Hook - Save session insights on Stop/StopFailure/PreCompact | no | — |
jcodemunch-enforcer.js | PostToolUse | jCodemunch Enforcement Hook - PostToolUse | no | — |
lazy-rule-injector.js | not registered | Lazy Rule Injector - PreToolUse Hook (Phase C) | yes | pre_tool_use.js (PreToolUse) |
learning-capture.js | SessionEnd, Stop (shared), SessionEnd (shared) | Learning Capture - Stop Hook (the "learn" auto-capture) | no | — |
mastermind-pre-task.js | UserPromptSubmit, UserPromptSubmit (shared) | Mastermind Pre-Task Gate + Skill/MCP Advisor - UserPromptSubmit hook | no | — |
mastermind-stop.js | Stop (shared) | Mastermind Pre-Summary Gate - Stop hook | yes | — |
non-stop-loop-stop.js | SubagentStop, SubagentStop (shared), Stop (shared) | Session-keyed, fail-closed Stop hook for the /non-stop command loop. | yes | — |
path-skill-activator.js | not registered | Path-Skill-Activator - PreToolUse (Write|Edit) | no | unified-tool-hook.js (PreToolUse), post-tool-mux.js (PostToolUse) |
pipeline-gate.js | not registered | MPRO Pipeline Gate - Full Enforcement Chain | no | unified-tool-hook.js (PreToolUse), post-tool-mux.js (PostToolUse) |
pipeline-state.js | not registered | MPRO Pipeline State Manager - Artifact-driven gates | no | stop.js (Stop (shared)) |
post-compact-distill.js | PostCompact, PostCompact (shared) | MPRO PostCompact Distill - Extract nuances from compaction summary → KB | no | — |
post-compact-reload.js | SessionStart, PostCompact, PostCompact (shared) | MPRO Post-Compaction Reload Hook - Reinject critical context after compaction | no | — |
post-compact.js | PostCompact, PostCompact (shared) | MPRO PostCompact Hook - Auto-checkpoint after context compaction | no | — |
post-tool-mux.js | PostToolUse | ONE process for the PostToolUse hook fan-out that .claude/settings.json | yes | — |
post-tool-unified.js | PostToolUse | MPRO PostToolUse Unified Hook - TodoWrite persistence + universal post-tool tracking | no | — |
post_tool_use.js | PostToolUse, PostToolUse (shared) | MPRO Ralph Integration Hook for Claude Code IDE | no | — |
pre-compact.js | PreCompact, PreCompact (shared) | MPRO PreCompact Hook - Save state before context compaction | no | — |
pre-implementation-guard.js | not registered | Pre-Implementation Guard Hook (PreToolUse on Write) | no | — |
pre-task-budget.js | not registered | pre-task-budget - the INTERNAL deadline of the UserPromptSubmit hook (mastermind-pre-task.js). | no | mastermind-pre-task.js (UserPromptSubmit) |
pre-tool-fence-carveout.js | not registered | ROW 1 of the hard-stop trap audit (2026-07-26). | no | universal-stop.js (Stop) |
pre_tool_use.js | PreToolUse, PreToolUse (shared) | MPRO Safety Hook for Claude Code YOLO Mode | yes | — |
scout-router.js | not registered | MPRO Scout Router - Auto-select best agent for any task | no | — |
session-start.js | SessionStart, UserPromptSubmit, SessionStart (shared), UserPromptSubmit (shared) | MPRO SessionStart Hook - Auto-register session + inject context on first message | no | — |
skill-usage-hook.js | PreToolUse | Skill-Usage Telemetry - PreToolUse wrapper on the `Skill` tool (fires via mastermind). | no | — |
stop.js | Stop (shared) | MPRO Stop Hook - Emergency session save on Claude Code exit | yes | — |
subagent-stop.js | SubagentStop, SubagentStop (shared) | SubagentStop hook - Mastermind GATE for spawned sub-agents + temp-state tidy. | yes | — |
tpspg-bridge-hook.js | SessionEnd, SessionEnd (shared) | tpspg-bridge-hook - the MISSING CALLER for tools/tpspg-bridge/bridge.js. | no | — |
ui-verify-reminder.js | not registered | PostToolUse hook - emits a "verify in browser" reminder when UI files are edited. | no | unified-tool-hook.js (PreToolUse), post-tool-mux.js (PostToolUse) |
unified-tool-hook.js | PreToolUse | ONE process for the Claude Write|Edit hook fan-out. | yes | post-tool-mux.js (PostToolUse) |
universal-stop.js | Stop | Claude Stop terminal authority. | yes | — |
vendor-hook-drift-announcer.js | not registered | Vendor Hook Drift Announcer | no | session-start.js (SessionStart/UserPromptSubmit/SessionStart (shared)/UserPromptSubmit (shared)) |
write-edit-guard.js | not registered | Write-Edit Guard - PreToolUse (Write|Edit) Orchestrator | no | unified-tool-hook.js (PreToolUse), post-tool-mux.js (PostToolUse) |
Enforced-by is a text pointer from a check or hook to the rule file - a declared link.
| Rule file | Article marker (declared) | Enforced by |
|---|---|---|
CHANGELOG.md | — | docs-structure-check.js, file-placement-check.js, html-report-stamp-check.js, tool-doc-sync-check.js |
README.md | — | adr-corpus-gate-check.js, docs-structure-check.js, file-placement-check.js, frankenstein-check.js |
act-dont-claim.md | C92 | samatva-check.js, stop-question-escalation-check.js |
action-claim-hard-proof.md | — | action-claim-proof-check.js |
agent-care.md | — | agent-recovery-check.js |
agent-external-ops.md | — | consilium-rigor-check.js, lazy-rule-injector.js |
agent-onboarding.md | — | rule-enforcement-pointer-check.js |
ai-dev-cost-bias.md | — | ai-dev-cost-bias-check.js, spawn-tier-check.js |
always-delegate.md | — | dead-dependency-check.js, uninvestigated-signal-check.js, pre_tool_use.js |
analytics-tracking.md | — | analytics-tracking-check.js |
app-control.md | — | nothing found |
app-discovery.md | — | nothing found |
ask-the-registry-first.md | — | nothing found |
auto-mode.md | — | nothing found |
autonomous-action-and-vendor-parity.md | — | nothing found |
autonomous-loop-preflight.md | — | nothing found |
bounded-outbound-autonomy.md | C85 | dirty-handoff-check.js |
browser-automation.md | — | lazy-rule-injector.js, pre_tool_use.js |
caveman-default.md | — | nothing found |
ceo-browser-and-screen-are-jane-and-the-extension.md | — | nothing found |
ceo-notification-traceable-not-spam.md | — | nothing found |
ceo-output-preferences.md | — | docs-dedupe-check.js, docs-structure-check.js, report-delivery-check.js, responsive-html-check.js |
ceo-question-mastermind-first.md | — | nothing found |
ceo-readable-html-links.md | C103 | ceo-readable-link-check.js, report-delivered-check.js, report-delivery-check.js |
ceo-technical-intent.md | — | technical-intent-check.js |
check-conflicts-before-working.md | — | nothing found |
check-upgrade-when-broken-or-looping.md | — | nothing found |
claude-code-best-practices.md | — | nothing found |
cleanup.md | — | lane-dirty-check.js, security-scan-trigger-check.js, self-cleanup-check.js, self-started-server-check.js |
code-graph-annotations.md | — | governance-theater-check.js |
code-intelligence.md | — | lazy-rule-injector.js |
coding-style.md | C62, C96 | frankenstein-check.js, loop-dead-end-check.js, win-leftover-check.js, lazy-rule-injector.js |
cold-minded-retention.md | C74 | nothing found |
commit-validation-gate.md | — | nothing found |
communicate-short-clear.md | — | nothing found |
consilium-capture-all-ideas.md | — | nothing found |
consilium-deliberation-procedure.md | — | consilium-rigor-check.js, constraint-inversion-check.js |
continuous-execution.md | — | budget-stop-excuse-check.js, capability-punt-check.js, unfinished-work-stop-check.js |
continuous-improvement-kimi.md | — | nothing found |
creative-media-previd-higgsfield.md | — | nothing found |
credential-proxy-mandatory.md | — | credential-proxy-check.js, credential-proxy-guard.js, stop.js |
credentials.md | — | lazy-rule-injector.js |
cross-model-review-symmetric-real-models.md | — | nothing found |
cross-model-validation-mandatory.md | — | mastermind-stop.js, subagent-stop.js |
cto-autonomous-recovery.md | — | capability-punt-check.js, lazy-rule-injector.js |
data-isolation.md | — | lazy-rule-injector.js, pre_tool_use.js |
deep-research.md | — | lazy-rule-injector.js |
deployment-boundaries.md | — | unit-install-drift-check.js, lazy-rule-injector.js, pre_tool_use.js |
deployment.md | C7 | lazy-rule-injector.js |
design-before-implement-qrspi.md | — | nothing found |
design-guardrails.md | — | lazy-rule-injector.js |
design-os.md | — | design-redteam-check.js |
desktop-menu-nav.md | — | nothing found |
disarm-sleeping-bombs.md | — | broken-tool-left-check.js, route-around-fix-check.js, unfinished-work-stop-check.js, vault-path-check.js |
do-it-dont-offer.md | — | capability-punt-check.js |
doc-structure-standard.md | — | doc-readability-check.js, doc-structure-order-check.js, html-report-stamp-check.js, mastermind-stop.js |
document-creator-footer.md | — | html-report-stamp-check.js, lazy-rule-injector.js |
dual-side-task-scoring.md | — | html-report-stamp-check.js, scorecard-improvement-check.js, auto-open-html-hook.js, mastermind-pre-task.js |
dual-track-evaluation-human-and-llm.md | — | evaluation-not-persisted-check.js |
effort-model-standard.md | — | spawn-tier-check.js, mastermind-pre-task.js |
email-single-identity.md | — | email-send-safety-check.js |
empty-means-empty-reports.md | C92, C96 | doc-structure-order-check.js, open-report-rows-check.js, unfinished-work-stop-check.js, mastermind-stop.js |
english-mandatory.md | C84 | diagram-freshness-check.js, escalation-direction-check.js, sample-as-population-check.js, system-report-placement-check.js |
escalate-down-not-only-sideways.md | C102 | escalation-direction-check.js |
evaluate-score-plan-then-execute.md | C104 | nothing found |
every-claim-hard-proof-tdd.md | — | claim-proof-check.js, commit-claim-check.js, stop-question-escalation-check.js, subagent-proof-check.js |
explain-for-everyone.md | — | nothing found |
external-data-licence-first.md | — | external-audit-manifest-check.js, lazy-rule-injector.js |
fence-recover-and-observation.md | — | nothing found |
file-transfer.md | — | nothing found |
fix-broken-tools-never-just-report.md | — | broken-tool-left-check.js |
fix-for-all-agents-not-one.md | — | found-gap-root-cause-check.js, inline-work-not-spawned-check.js, dispatch-record.js |
fix-what-you-find-no-skip.md | — | found-mess-ledger-check.js |
focus-discipline.md | — | budget-stop-excuse-check.js |
found-gap-encode-root-cause.md | — | gate-escape-valve-check.js, raw-nul-source-check.js, unsorted-set-comparison-check.js, validated-against-unlanded-tree-check.js |
found-issues-no-stop.md | — | broken-tool-left-check.js, unfinished-work-stop-check.js |
found-it-fix-it-no-avoidance.md | — | avoidance-check.js, orchestration-required-check.js |
frontend-business-impact-qa-cta.md | — | frontend-business-impact-check.js |
frontend-design-protocols.md | — | nothing found |
gate-must-be-passable.md | C96 | escalation-direction-check.js, service-exec-drift-check.js |
git-autonomy-backup.md | — | commit-claim-check.js |
git-workflow.md | — | commit-punt-check.js, commit-quality-check.js, forbidden-git-verbs-check.js, html-report-stamp-check.js |
glossary.md | — | nothing found |
ground-and-search.md | — | constraint-inversion-check.js, external-grounding-check.js, grounded-diagnosis-check.js, uninvestigated-signal-check.js |
harness-first-all-agents.md | — | nothing found |
honest-advisory-commerce.md | — | commerce-over-promise-check.js |
honor-explicit-instructions.md | — | nothing found |
hook-blocks-name-the-reason.md | — | claim-grounding-check.js, report-delivered-check.js, report-delivery-check.js, system-report-placement-check.js |
how-before-what.md | — | nothing found |
html-report-diagrams.md | — | diagram-freshness-check.js, html-report-diagram-check.js, html-report-img-link-check.js, lazy-rule-injector.js |
incoming-advice-net-of-damage.md | — | advice-net-value-check.js |
investigate-the-anomaly-now.md | C106, C80, C96, C97 | nothing found |
jane-coordinate-calibration.md | — | nothing found |
jane-monitors.md | — | lazy-rule-injector.js |
jane-usage.md | C100, C75, C85 | lazy-rule-injector.js |
kb-and-html-dual-publish.md | — | learning-capture.js |
kb-articles.md | — | lazy-rule-injector.js, pre_tool_use.js |
kb-quality-gate.md | — | lazy-rule-injector.js |
kb-sysref-rich-standard.md | — | sysref-depth-check.js |
keep-current-and-close-what-you-open.md | — | nothing found |
knowledge-ingestion-read-everything.md | — | nothing found |
land-once-after-review-settles.md | — | commit-claim-check.js, lazy-rule-injector.js |
legal-compliance-harness.md | — | legal-compliance-check.js |
lessons-must-reach-every-vendor.md | — | nothing found |
linux-bridge-systemd-knowhow.md | — | lazy-rule-injector.js |
live-authoring-contract.md | — | nothing found |
mastermind-and-resources-mandatory-every-vendor.md | — | nothing found |
mastermind-gate.md | — | constraint-inversion-check.js, design-redteam-check.js, uninvestigated-signal-check.js, unverified-assumption-check.js |
mastermind-strict-not-advisory.md | — | constraint-inversion-check.js, uninvestigated-signal-check.js, vendor-gate-sync-check.js |
meet-the-reference-bar.md | — | reference-bar-check.js |
mistake-prevention.md | — | nothing found |
model-roster-single-source.md | C107 | model-registry-stale-check.js, dispatch-record.js |
money-touching-triple-review.md | — | money-work-review-check.js |
mpro-ecommerce-graph-sync.md | — | lazy-rule-injector.js |
mpro-taskman-lifecycle.md | — | taskman-peer-validation-check.js |
mpro-taskman-mandatory.md | — | taskman-match-check.js, taskman-node-check.js, lazy-rule-injector.js, mastermind-pre-task.js |
mpro-taskman-multi-agent-append.md | — | nothing found |
mpro-vision.md | — | design-quality-check.js |
multi-agent-sharing.md | — | lazy-rule-injector.js |
multi-delegate-flow.md | — | constraint-inversion-check.js, lane-budget-check.js, uninvestigated-signal-check.js, mastermind-pre-task.js |
musk-five-step-algorithm.md | — | nothing found |
n8n-layout.md | — | lazy-rule-injector.js |
never-hand-the-ceo-a-command.md | C101 | ceo-readable-link-check.js |
never-truncate-evidence.md | C97 | post_tool_use.js, pre-task-budget.js |
no-claim-without-grounding.md | — | open-report-rows-check.js |
no-guessing.md | C75 | cause-effect-check.js, constraint-inversion-check.js, external-grounding-check.js, model-claim-check.js |
no-mediocre.md | C66 | ai-dev-cost-bias-check.js, claim-grounding-check.js, constitution-marker-coverage-check.js, creativity-reward-check.js |
no-whining-act-carefully.md | — | samatva-check.js |
ohana-no-task-left-behind.md | — | vendor-exhaustion-check.js |
one-harness-all-agents.md | — | constraint-inversion-check.js, git-broker-enforcement-check.js |
ops-discipline.md | C90, C85 | nothing found |
orchestrate-dont-grind.md | C91 | dispatch-record.js |
parallel-work-worktree-isolation.md | C87 | lane-tenancy-check.js, parallel-dispatch-isolation-check.js, shared-root-commit-check.js, pre_tool_use.js |
pipeline-gates.md | — | lazy-rule-injector.js |
plan-limit-preserve-subagent-work.md | — | subagent-failure-check.js |
playwright-ceo-profile.md | — | playwright-profile-check.js, pre_tool_use.js |
port-assignment.md | — | lazy-rule-injector.js |
ports-strict-reservation.md | — | nothing found |
pre-implementation-audit.md | — | lazy-rule-injector.js, pre-implementation-guard.js, write-edit-guard.js |
previd-every-stage-no-skip.md | C66 | nothing found |
previd-scorecard-in-every-report.md | C107 | nothing found |
proactive-care-and-clarity.md | — | nothing found |
project-ids.md | — | nothing found |
proof-outside-chat.md | — | body-validation-check.js, report-delivered-check.js, surface-claim-check.js |
prosperity-wisdom-council.md | — | nothing found |
readable-diagrams-not-dumps.md | — | lazy-rule-injector.js |
rebuild-over-patch.md | — | nothing found |
rebuild-vs-fix-conversion.md | — | nothing found |
record-the-location-not-just-the-answer.md | — | nothing found |
remove-deprecated-dont-port-old-habits.md | — | nothing found |
report-creation-standard.md | — | report-delivered-check.js, report-delivery-check.js, report-local-palette-check.js, report-quality-check.js |
report-header-stamp-standard.md | — | html-report-stamp-check.js |
report-version-bump-before-update.md | — | nothing found |
saas-self-contained.md | — | lazy-rule-injector.js |
search-before-append-or-create.md | C86 | nothing found |
security-scanning-harness.md | — | security-scan-trigger-check.js |
security.md | — | lazy-rule-injector.js |
session-continuity.md | — | nothing found |
share-integrity-every-link.md | — | share-integrity-check.js |
skill-creation.md | — | nothing found |
slim-compact-reports.md | — | action-claim-proof-check.js, doc-structure-order-check.js |
soul.md | — | nothing found |
spawned-sessions-for-every-prompt-and-pickup.md | — | announce-only-check.js |
spawned-sessions-never-hidden-shells.md | — | inline-work-not-spawned-check.js |
stop-question-escalation-ceo-last.md | — | capability-punt-check.js, mastermind-stop.js |
subagent-hardproof-required.md | — | subagent-contract-check.js, subagent-proof-check.js |
subagent-model-effort-visibility.md | — | spawn-tier-check.js, subagent-model-visibility-check.js, dispatch-record.js |
subagent-receipts-and-supervision.md | C105 | governance-theater-check.js |
subagent-scope-fidelity.md | — | subagent-scope-check.js |
sysref-source-of-truth.md | — | new-tool-no-sysref-check.js, sysref-localhost-check.js |
taskman-severity-grading.md | — | nothing found |
taskman-task-readiness.md | — | lazy-rule-injector.js |
tdd.md | — | claim-proof-check.js, commit-claim-check.js, stop-question-escalation-check.js, subagent-proof-check.js |
testing-validation-standard.md | — | frankenstein-check.js, loop-dead-end-check.js, pm2-direct-shell-check.js, lazy-rule-injector.js |
tool-priority.md | — | nothing found |
tool-update-doc-graph-sync.md | — | nothing found |
unified-report-structure.md | — | nothing found |
update-stamping.md | — | doc-structure-order-check.js, html-report-stamp-check.js, model-claim-check.js, lazy-rule-injector.js |
use-whats-working.md | — | cause-effect-check.js, defer-without-trying-check.js, route-around-fix-check.js, mastermind-stop.js |
ux-content-king-validate-or-kill.md | — | nothing found |
validate-body-not-title.md | — | body-validation-check.js, mastermind-stop.js |
value-driven-communication.md | — | tpspg-bridge-hook.js |
values-bhagavad-gita.md | C63, C79, C87, C95, C107, C1, C0 | constraint-inversion-check.js, creativity-reward-check.js, doc-readability-check.js, email-send-safety-check.js |
vendor-logic-synced-adapters-personalized.md | — | orphan-process-check.js, systematic-update-check.js, dispatch-record.js |
verified-not-done.md | — | done-not-verified-check.js |
verify-binary-platform-before-and-after-install.md | — | nothing found |
verify-external-not-memory.md | — | external-verify-fallback-check.js, three-rules-check.js |
visible-subagents-statusline.md | — | inline-work-not-spawned-check.js, ceo-heartbeat-guard.js, pre_tool_use.js |
web-project-standards.md | — | lazy-rule-injector.js |
web-scraping.md | — | lazy-rule-injector.js |
worktree-branch-standard.md | — | project-cleanup-check.js, worktree-hygiene-check.js, lazy-rule-injector.js |
An article with nothing in the right-hand column is governed by prose alone.
| Article | Title | Enforced by (declared) |
|---|---|---|
C19 | Fact Verification Before Completion (MANDATORY) | nothing found |
C20 | Honesty First - Only Tested Truth (MANDATORY) | nothing found |
C21 | Loop Detection and Escalation (MANDATORY) | nothing found |
C22 | Agent Identity and Trust Verification (MANDATORY) | nothing found |
C23 | Postbox Communication Standards (MANDATORY) | nothing found |
C24 | Continuation Routing and Emergency Orchestration (MANDATORY) | nothing found |
C25 | Failed Prevention System (MANDATORY) | nothing found |
C26 | Screen Navigation Precision Protocol (MANDATORY) | constitution-marker-coverage-check.js |
C47 | Mastermind Blast-Radius Gate Before Every Code Change | constitution-marker-coverage-check.js |
C48 | Spawned Session Trust Chain | nothing found |
C49 | Mastermind v3: Mid-Flight, Planning-Time, and Auto-Recovery | nothing found |
C50 | Session Temp File Cleanup Mandate | self-cleanup-check.js, self-started-server-check.js |
C51 | Critical File Guard (Tiered CEO Confirmation) | commit-punt-check.js, open-report-rows-check.js |
C52 | SYSREF Documentation Standard (Reconstruction-Level Completeness) | nothing found |
C53 | Mastermind Hardcoded Gate Across Every Agent (TP-COT Tier A) | nothing found |
C54 | Playwright Browser Verification Required for Web UI Changes | nothing found |
C55 | SYSREF Must Be Updated Same Session as Owned File Commit | nothing found |
C56 | Mastermind Strategy Confidence Gate (3-Cycle Minimum) | nothing found |
C57 | Prompt Clarity Gate (Never Guess on Vague Prompts) | nothing found |
C58 | Consilium + Paperclip System-Prompt Sub-Agent When Stuck | nothing found |
C59 | No-Guessing Mandate | nothing found |
C60 | Mastermind Always (Hardcoded Invocation) | nothing found |
C61 | Plan Before Multi-Step Tasks (/goal Mandate) | nothing found |
C62 | Clean ASCII in Code (No Encoding Artifacts) | ceo-tables-health-check.js, config-tamper-check.js, conversion-tracking-check.js, credential-proxy-check.js |
C63 | 5-Pillar Agent Priority Framework (CEO Directive 2026-05-17) | doc-structure-order-check.js, security-scan-trigger-check.js, superiority-admission-check.js, values-bhagavad-gita.md |
C64 | Mastermind + Syndicate Autonomous Self-Improving Tier (CEO Directive 2026-05-24) | nothing found |
C65 | Real-Life Validation Gate (CEO Directive 2026-05-30) | nothing found |
C66 | No Mediocre Results, Persist to the Top (CEO Directive 2026-05-30) | constitution-marker-coverage-check.js, no-mediocre.md, previd-every-stage-no-skip.md |
C67 | Body/Content Validation (validate the BODY, not the TITLE) (CEO Directive 2026-06-28) | nothing found |
C68 | No-Trust-Memory + Cause-Effect Neurolink + Multi-Vendor Done-Status Review (CEO Directive 2026-07-17) | announce-only-check.js, broken-tool-left-check.js, cause-effect-check.js, claim-grounding-check.js |
C69 | Technical Question Escalation: Team-First, CEO-Last (CEO Directive 2026-07-15 + 2026-07-17) | constitution-marker-coverage-check.js, dead-dependency-check.js, ops-discipline-check.js, stop-question-escalation-check.js |
C70 | Mandatory Cross-Model Verification of Every Completed Task (CEO Directive 2026-07-17) | cross-model-verification-check.js |
C71 | Every Business Is Built for Repeated Sales (CEO Directive 2026-07-18) | nothing found |
C72 | No Claim Without Grounding (CEO Directive 2026-07-25) | agent-efficiency-check.js, claim-grounding-check.js, inline-work-not-spawned-check.js, unprobed-ignorance-check.js |
C73 | Spawned Sessions, Never Hidden Shells (CEO Directive 2026-07-25) | inline-work-not-spawned-check.js |
C74 | Cold-Minded Retention (CEO Directive 2026-07-25) | cold-minded-retention.md |
C75 | The Axe Doctrine: Autonomous Action, Permission Only for Harm (CEO Directive 2026-07-26) | consent-click-handoff-check.js, false-blocker-check.js, governance-theater-check.js, high-entropy-secret-leak-check.js |
C76 | Fix It For Everyone, Not For One (CEO Directive 2026-07-26) | found-gap-root-cause-check.js, mount-topology-safety-check.js, recommended-executor-spawn-check.js, report-delivered-check.js |
C77 | Every Worker Is Visible: Spawned Sessions, Never Hidden Shells (CEO Directive 2026-07-28) | subagent-liveness-check.js |
C78 | Named Work Needs an Owner: Deferral Must Become a Dispatch (CEO Directive 2026-07-26) | dead-dependency-check.js |
C79 | Check for Conflicts BEFORE Working (CEO Directive 2026-07-27) | avoidance-check.js, context-ceiling-blocker-check.js, control-plane-auth-check.js, dirty-handoff-check.js |
C80 | Found It, Fix It: A Stalled Task Belongs to Whoever Finds It (CEO Directive 2026-07-27) | dead-dependency-check.js, investigate-the-anomaly-now.md |
C81 | Remove Deprecated, Don't Port Old Habits (CEO Directive 2026-06-29; renumbered from the C68 proposal) | nothing found |
C82 | Yokoten: Horizontal Deployment - Every Fix and Every Working Method Reaches Every Agent (CEO Directives 2026-0 | nothing found |
C83 | Read the BODY, Never Judge by the Header (CEO Directive 2026-08-01) | nothing found |
C84 | English Is the Working Language of MPRO (CEO Directive 2026-08-01) | blocked-without-alternatives-check.js, ceo-readable-link-check.js, diagram-freshness-check.js, mandate-invariant-check.js |
C85 | Bounded Outbound Autonomy (CEO Directive 2026-08-02) | agent-efficiency-check.js, dirty-handoff-check.js, email-send-safety-check.js, external-audit-manifest-check.js |
C86 | Search First, Then Append; Create Only When Nothing Exists (CEO Directive 2026-08-02) | adr-index-check.js, benchmark-staleness-check.js, browser-control-path-check.js, ceo-command-handoff-check.js |
C87 | Parallel Work Runs In An Isolated Worktree (CEO Directive 2026-08-02) | ceo-readable-link-check.js, lane-budget-check.js, lane-tenancy-check.js, mandate-invariant-check.js |
C88 | Every Prompt Gets A Structured Read-Back, On Every Vendor (CEO Directive 2026-08-03) | constitution-marker-coverage-check.js |
C89 | The Treasury Mandate: Never Lose Money (CEO Directive 2026-08-06) | constitution-marker-coverage-check.js, task-dimension-check.js, three-rules-check.js, value-question-check.js |
C90 | Living Ops Discipline: Ten Behavioral Rules for Every Vendor (2026-08-08) | agent-efficiency-check.js, ops-discipline-check.js, ops-discipline.md |
C91 | The Orchestration Model: Eight Measured Rules for Dispatched Work (CEO Directive 2026-08-09) | registry-first-check.js, temp-dir-bloat-check.js, orchestrate-dont-grind.md |
C92 | The Report Contract: Open Work On Top, Finished Work Below (CEO Directive 2026-08-10) | html-report-stamp-check.js, act-dont-claim.md, empty-means-empty-reports.md |
C93 | The Three Rules: Do Not Lose Money, Do Not Lose Money, Do Not Waste Energy (CEO Directive 2026-08-10) | task-dimension-check.js, three-rules-check.js |
C94 | Pickup Vendor Is the Orchestrator: Delegated Authority, Same-Vendor Continue (CEO Directive 2026-08-15) | nothing found |
C95 | Name the Value or Stop the Same Path (CEO Directive 2026-08-16) | task-dimension-check.js, value-question-check.js, values-bhagavad-gita.md |
C96 | A Gate Must Be Passable, and Its Escape Must Be Real (CEO Directive 2026-08-17) | agent-name-model-version-check.js, announce-only-check.js, authoring-contract-check.js, ceo-command-handoff-check.js |
C97 | Never Truncate What You Conclude From (CEO Directive 2026-08-19) | benchmark-staleness-check.js, dirty-handoff-check.js, escalation-direction-check.js, host-pressure-check.js |
C98 | Dual-Track Evaluation: the Human Is the Label, the LLM Is the Prediction (CEO Directive 2026-08-19) | evaluation-not-persisted-check.js |
C99 | Precision First, Speed Second (CEO Directive 2026-08-25) | mandate-invariant-check.js |
C101 | Never Hand the CEO a Command; Think Triple First (CEO Directive 2026-08-27) | ceo-command-handoff-check.js, consent-click-handoff-check.js, ledger-drift-check.js, mandate-invariant-check.js |
C100 | Jane Is Available to Every Vendor, and Her Traps Are Written Down (CEO Directive 2026-08-27) | jane-focus-check.js, jane-usage.md |
C102 | Escalation Has Two Axes: Descend for Facts, Fan Out for Opinions (CEO Directive 2026-09-01) | escalation-direction-check.js, vendor-exhaustion-check.js, escalate-down-not-only-sideways.md |
C103 | A Report's Address Is Its Hub URL, Never a Worktree Path (CEO Directive 2026-09-02) | ceo-readable-html-links.md |
C104 | Evaluate the Whole List, Score It, Plan It, Then Execute One by One (CEO Directive 2026-09-03) | registry-first-check.js, task-dimension-check.js, evaluate-score-plan-then-execute.md |
C105 | A Sub-Agent's Report Ends With a Receipt the Parent Re-Runs (CEO Directive 2026-09-06) | constitution-marker-coverage-check.js, task-dimension-check.js, subagent-receipts-and-supervision.md |
C106 | A Tool That Did Not Answer What You Expected Is the Work (CEO Directive 2026-09-11) | constitution-marker-coverage-check.js, repo-root-grep-check.js, task-dimension-check.js, uninvestigated-signal-check.js |
C107 | Ask the Six Questions on Every Task, Even a Simple One (CEO Directive 2026-09-11) | agent-name-model-version-check.js, constitution-marker-coverage-check.js, cross-model-verification-check.js, done-not-verified-check.js |
Grouping is DERIVED from each file’s frontmatter, not from its prose: a definition whose name matches the generated alias pattern <SHORT>-<model><version>-<effort> is an alias; the rest are roles, sub-grouped by the model they pin. The when for every role is its own description field — that is what the router matches on, and it is a claim written to be matched, never a specification of behaviour. The full 1-row-per-agent list is in the JSON.
Counts derived this run.
| Group | Count | Examples |
|---|---|---|
| generated model x effort alias | 51 | AA-sonnet5-high, AD-sonnet5-high, AO-sonnet5-high, AS-sonnet5-high |
| role (model: sonnet) | 47 | ab-testing, ad-optimizer, aeo-auditor, ai-security |
| role (model: opus) | 3 | opus-high, opus-xhigh, orchestrator |
| role (model: haiku) | 1 | haiku-low |
What this is: everything below is the canonical, rebuild-from-scratch reference for Mastermind and the harness — the same text that lives in the knowledge base as the durable source of truth (SYSREF-001, slug sysref-mastermind, 7,263 words, all 17 required sections). It is reproduced here, in full, so this one page answers both questions without sending you anywhere: what is left (top) and what Mastermind is (here). The diagrams are article-ready; each is stored beside this page as SVG with a matching ASCII version for agents.
Projected from the knowledge base at build time (article 558166fb, v6.2.1, fetched 2026-09-19 16:09 EEST). The knowledge-base copy is the source of truth; this page is its local reading projection, so the two cannot drift. Diagram files copied beside this page: 5 SVG.
Status: canonical Version: 6.2.1 Last verified: 2026-09-19 Source of truth: docs/mastermind/index.html (marker harm-prevention-v2) plus its machine companion docs/mastermind/harm-prevention-v2-evidence.json; the vendor roster is tools/eidos/vendor-gate-manifest.json; the acceptance gate for this article is tools/eidos/sysref-depth-check.js. Scope: Claude, Codex, Grok, Qwen, Kimi, Antigravity (agy), OpenCode, Ollama, Zen, Max, and every future vendor. Supersedes: v6.1.0 (2026-08-14), which documented vendor parity only.
| Field | Value | How it was derived |
|---|---|---|
| Canonical slug | sysref-mastermind | KB metadata; never cite the UUID form |
| Repository report | docs/mastermind/index.html | v2.3.0, marker harm-prevention-v2 |
| Evidence companion | docs/mastermind/harm-prevention-v2-evidence.json | 60 fixed rows, 26 delegated rows, origin_master 6b8e6bf5018 |
| Diagram sources | docs/mastermind/harm-prevention-layers.mmd, tools/kb-assets/images/articles/2026-08-14/sysref-mastermind/*.mmd | node tools/scripts/validate-mmd.js green |
| Acceptance gate | node tools/eidos/sysref-depth-check.js (runSysrefDepthCheck) | 14 checks; v6.1.0 scored 8/14 FAIL |
| Governance counts | 189 rules, 172 skills, 102 agents, 69 constitution articles | counted on this box 2026-09-19 |
The previous revision of this article failed its own acceptance gate: runSysrefDepthCheck scored it 8 of 14 with six misses (tables_1_lt_5, no_last_verified_date, no_provenance_or_sources, no_status_block, no_cause_and_effect_section, no_impact_value_section). One of those was pure spelling: v6.1.0 wrote the status line with the colon inside the bold marker, a form the gate's regular expression cannot match. A canonical reference that cannot pass the checker built to police it is a defect in the reference, and this revision repairs it.
MPRO is a fleet of AI agents that write code, run services and spend real money on a single shared Ubuntu machine. The question this document answers is the one a careful person asks first: what actually stops an agent from doing damage? The answer is not a rule-book. It is seven layers of machinery that an agent action must pass through, one after another, before it can touch anything that matters, and the layers get progressively harder to talk your way past.
Layer 0 is the values and rules: guidance, and by itself it stops nothing. Layer 1 is a permission floor of sixteen command shapes the harness refuses outright. Layer 2 inspects every single shell command, file write and file edit before it runs. Layer 3 is the git broker and the commit hooks: private work lanes, a scope gate, a secret scanner, a test gate and a tamper check on protected files. Layer 4 is the Stop gate, which decides whether an agent may say the word "done". Layer 5 is the task board, where "done" is only a claim until a separate process re-runs the proof. Layer 6 is the monitors and the self-healing loops that watch the whole thing and page a human only when a human is genuinely needed.
This revision documents that architecture for the first time, names the exact file that enforces each layer, says plainly which layers block and which only advise, and records the four P0-class repairs of 2026-09-19 that changed the shape of the system: a deploy rail that had stopped delivering landed fixes to twelve running services, a Stop-gate board read that pulled 25 MB up to thirteen times per finish while putting a master key in a command line, a lane-release refusal that could not release a lane whose work had already landed, and a receipt verifier that could not run a test written the way the rules tell sub-agents to write it.
Seven layers stand between an agent's intention and real harm. Only four of them refuse anything: the permission floor (L1), the tool guards (L2), the git broker and commit hooks (L3), and the SAFETY and HARD_POLICY rows of the Stop gate (L4). Everything else advises, records, or watches. Say which one you mean, because calling an advisory layer a control is the most common way this system gets misdescribed.
Four diagrams describe vendor parity; a fifth, added in this revision, describes the harm-prevention spine. Every diagram ships as a rendered SVG for people and an ASCII companion for agents, because those are two different readers and each is first class.
Mermaid source: docs/mastermind/harm-prevention-layers.mmd (tracked). The rendered SVG is generated, not committed: tools/kb-assets/images/articles/* is gitignored at .gitignore:319, so the artifact is rebuilt with node tools/scripts/render-mermaid.js docs/mastermind/harm-prevention-layers.mmd tools/kb-assets/images/articles/2026-09-19/sysref-mastermind/harm-prevention-layers.svg.
ASCII companion:
agent acts (Bash / Write / commit / "done")
|
v
L0 values + rules ....... guides only, refuses nothing
|
v
L1 permission floor ----> matched shape ------------------> REFUSED
| (settings.json deny, 16 shapes)
v
L2 tool guards ---------> destructive / secret / protected -> REFUSED
| (pre_tool_use.js)
v
L3 git broker ----------> peer file / secret / red test ---> REFUSED
| (agent-git.js + pre-commit)
v
L4 Stop gate -----------> SAFETY or HARD_POLICY ----------> REFUSED
| \--> QUALITY row -> ADVISED (runs, scored)
v
L5 task board :3018 ..... "done" recorded, not yet validated
|
v
L6 monitors + healing ... OnFailure -> mpro-alert@ -> board / CEO
|
v
work lands, and stays watched
Mermaid source: tools/kb-assets/images/articles/2026-08-14/sysref-mastermind/vendor-terminal-topology.mmd.
ASCII companion:
Claude ---- universal-stop ------------+
Codex ----- managed hook runner -------+
Grok ------ native adapter ------------+
Qwen ------ universal adapter ---------+
Kimi ------ universal adapter ---------+--> shared terminal policy
Antigravity native subset adapter -----+ |
OpenCode -- session surrogate ---------+ v
Ollama ---- bridge gate ---------------+ PASS / FAIL /
Zen ------- postbox advisory ----------+ ADVISORY / UNSCORABLE
Max ------- postbox advisory ----------+
Mermaid source: tools/kb-assets/images/articles/2026-08-14/sysref-mastermind/terminal-decision-flow.mmd.
ASCII companion:
event -> bind exact identity -> run validators under one deadline
|
coherent contract?
no | | yes
FAIL: contract invalid | explicit hard failure?
yes -> FAIL + owner + remedy
no -> complete evidence? -> PASS
partial evidence? -> ADVISORY
unavailable? -> UNSCORABLE
Mermaid source: tools/kb-assets/images/articles/2026-08-14/sysref-mastermind/fence-nonstop-state.mmd.
ASCII companion:
IDLE --arm--> ARMED --PreToolUse--> TOOL_OPEN --PostToolUse--> ARMED
|
evidence incomplete
v
AWAIT_EVIDENCE
|
owner dead + bounded age
v
RECOVERABLE
|
one exact reconciliation
v
ARMED --ledger clear--> CLEAR
Mermaid source: tools/kb-assets/images/articles/2026-08-14/sysref-mastermind/code-graph-impact.mmd.
ASCII companion:
.claude/universal-stop ----> universal-hook-executor
.claude/mastermind-stop ---> mastermind-ask + terminal-policy
.codex/mastermind-hook ----> mastermind-stop + scope-fence + task-ledger
Grok ----------------------> terminal-policy
Qwen / Kimi / Antigravity -> universal runtime / executor
OpenCode ------------------> mastermind-ask
Ollama --------------------> shared bridge gate
Every path below was confirmed present on this box on 2026-09-19 and its length measured with wc -l. Line counts are a rebuild aid: they tell a reconstructor whether a file is a small policy module or a large engine, which changes how it should be approached.
| File | Lines | Layer | Responsibility |
|---|---|---|---|
.claude/settings.json | n/a (JSON) | L1 | 16 deny rules, 68 allow rules, 10 registered hook events |
.claude/hooks/pre_tool_use.js | 2397 | L2 | inspects every Bash, Write and Edit payload before the tool runs |
tools/safety/lib/integrity.js | 748 | L2/L3 | records and verifies hashes of protected files |
tools/scripts/agent-git.js | 9873 | L3 | the git broker: lanes, commits, land, push lock, worktree release |
.githooks/pre-commit | 1731 | L3 | secret scan, ASCII (C62), raw NUL, related-test TDD gate, integrity |
tools/scripts/lib/worktree-release.js | 666 | L3 | releases a lane only when nothing unique would be lost |
tools/scripts/lib/runtime-worktree-pins.js | 452 | L3/L6 | refuses to release or reap a tree a live service executes from |
tools/eidos/subagent-scope-check.js | 293 | L3 | diffs files actually edited against the declared scope manifest |
.claude/hooks/universal-stop.js | 644 | L4 | Claude's single outward Stop authority; resolves and runs the gates |
.claude/hooks/mastermind-stop.js | 4402 | L4 | the shared Stop gate body, including HARD GATE 5b |
tools/eidos/mastermind-ask.js | 20743 | L4 | the scorer: runs the registered checks over the session |
tools/eidos/two-tier-gate.js | 986 | L4 | sorts findings into SAFETY, HARD_POLICY, QUALITY, UNSCORABLE |
tools/eidos/mastermind-terminal-policy.js | 315 | L4 | turns that classification into one outward terminal decision |
tools/eidos/values-check.js | 282 | L0/L4 | rolls value-enforcing checks up under satya, ahimsa, nishkama, svadharma, dao |
tools/eidos/task-dimension-check.js | 314 | L0/L4 | the C107 six-dimension question, advisory, capped at -2 |
tools/eidos/subagent-receipt-verify.js | 553 | L4/L5 | re-runs a sub-agent's claimed tests and probes (C105) |
tools/mpro-taskman/server.js | 5309 | L5 | the task board on :3018: nodes, edges, claims, leases, validation |
tools/eidos/vendor-gate-manifest.json | 737 | L4 | the canonical vendor roster and shared-event routing table |
tools/eidos/vendor-gate-sync-check.js | 1259 | L4 | measures which vendors the gates actually reach |
tools/systemd/lib/service-runtime-plan.js | 670 | L6 | plans a blue-green slot move for a running service |
tools/eidos/sysref-depth-check.js | 407 | meta | the acceptance gate for this article |
Two counts that matter for orientation: tools/eidos/ holds 311 *-check.js modules and eidos/specs/ holds 26 service contract specs. Not all 311 are wired into a gate. That gap is the subject of a delegated row and is named honestly in section 13 rather than being implied away.
Reconstruction needs the exact values, not their descriptions. These were read from the live configuration on 2026-09-19 through node tools/eidos/tool-output-secret-redaction.js .claude/settings.json, which is the required way to look at a credential-bearing config (a raw read is refused by the secret output gate, which is itself part of L2).
| Constant | Value | Where it lives | What it governs |
|---|---|---|---|
| deny rules | 16 | .claude/settings.json permissions.deny | the permission floor |
| allow rules | 68 | same | pre-approved tool surface |
| registered hook events | 10 | .claude/settings.json hooks | SessionStart, SessionEnd, SubagentStop, PreToolUse, PostToolUse, Stop, StopFailure, PreCompact, PostCompact, UserPromptSubmit |
MPRO_GATE_PROBE_TIMEOUT_MS | 394884 | settings env | outer probe budget for the gate |
MPRO_GROK_PRE_POST_SHARED_TIMEOUT_MS | 110000 | settings env | grok pre/post shared window |
MPRO_FENCE_FINGERPRINT_PROBE_BUDGET_MS | 40000 | settings env | fence fingerprint probe budget |
| depth gate word floor | 3000 | sysref-depth-check.js DEPTH_MIN_WORDS | SYSREF length, in words not characters |
| depth gate table floor | 5 | DEPTH_MIN_TABLES | tabular density |
| depth gate section body floor | 350 chars | DEPTH_MIN_SECTION_BODY | per H2 section |
| depth gate shallow cap | 0.25 | DEPTH_MAX_SHALLOW_RATIO | share of H2 sections allowed to be thin |
| claim lease | 24h | taskman /claim | how long a claim holds before the stale sweep reverts it |
| archive threshold | 7 days idle | ARCHIVE_MIN_AGE_DAYS | when a validated done node leaves the live board |
The sixteen refused command shapes are the permission floor in full, and they are worth listing because nothing else in the system states them:
git push --force* git push -f * git push --force-with-lease*
git push --no-verify* git commit --no-verify* git commit -n *
git merge --no-verify* git worktree remove -f* git worktree remove --force*
git branch -D * git stash clear* git stash pop*
crontab -r* loginctl enable-linger*
Edit(~/.claude/settings.json) Edit(~/.claude-c*/settings.json)
Read that list for what it is: a prefix matcher over the command string. It holds for the plain spelling and, since the subdirectory-guard repair (3408f83638b), for sessions started inside a subfolder as well. By construction it cannot match a program invoked by absolute path or wrapped inside sh -c. That is not a hole so much as a division of labour: layer 2 exists to cover exactly those shapes, and it was measured doing so.
Each command below is re-runnable and its expected output is stated, because a CLI reference without expected output cannot tell a reconstructor whether their rebuild works.
| Command | Expected output |
|---|---|
node tools/eidos/mastermind-ask.js agent --json | JSON with status, score, blocking, mayProceed, breakdown[]; UNSCORABLE is a normal, non-blocking result |
node tools/eidos/mastermind-ask.js agent --quick --json | the same shape from the short path; measured 37-41 s under load, not sub-second |
node tools/eidos/vendor-gate-sync-check.js --json | .matrix.vendors with per-vendor tier, shared gates, quality gate, fence and Stop-execution proof |
node tools/eidos/sysref-depth-check.js (module) | runSysrefDepthCheck(content, title) returns {pass, score, maxScore, misses[], metrics} |
node tools/scripts/validate-mmd.js <file.mmd> | OK, or the failing rule; a missing theme init block is an error |
node tools/scripts/render-mermaid.js <in.mmd> <out.svg> | writes the SVG; use this, not raw mmdc, which has no bundled browser on this box |
node tools/scripts/agent-git.js worktree-add --path <abs> --branch <b> --base origin/master --agent <id> --json | {ok:true, created:true, recorded:true} |
node tools/scripts/agent-git.js worktree-release --path <abs> | releases, or refuses and names what would be lost |
node tools/eidos/subagent-receipt-verify.js --receipt <f> --parent <node> | exit 0 on match, exit 1 on mismatch |
systemctl list-units "mpro-*" --state=failed --no-legend | one line per failed unit; 1 at the time of writing |
GET :3018/llms.txt | the live task-board contract: auth, endpoints, node and edge shape |
GET :3001/api/health | 200 with no token; /health is NOT a route and its 401 proves nothing |
Task-board mutations all carry the same provenance envelope and an agent-derived credential. The credential is derived in process from the vault key and travels only in an Authorization header:
seed : loadKey('TASKMAN_MUTATION_SECRET') (flat vault search)
derive : loadAgentCredential('<agent>', {env, loadKey})
header : Authorization: Bearer <derived>
body : { agent, model, effort, agent_tier, session_id, ... }
errors : 401 no credential -> 403 identity_mismatch -> 400 missing provenance
The raw shared key maps only to the compatibility principal taskman_service; a real agent that sends it with its own name in the body gets 403. This is the mechanism the BOARD repair hardened on 2026-09-19 by moving the bearer out of curl argv, where any process listing on the machine could read it.
This is the section a reconstructor rebuilds from. Each layer states what enforces it, how it is invoked, what it refuses, and where it only advises.
What enforces it: .claude/rules/ (189 files), docs/constitution.md (69 articles), the agent onboarding source rendered to every vendor surface, and tools/eidos/values-check.js (282 lines), which rolls the value-enforcing checks up under satya, ahimsa, nishkama, svadharma and dao so the gate can show a values verdict.
How it is invoked: rules are injected into agent context at session start and lazily on tool use; the values verdict is computed inside the Stop gate.
What it refuses: nothing, on its own. A sentence cannot stop a command. This is the honest statement the rest of the architecture depends on, and it is why layers 1 to 6 exist at all.
Where it is advisory: entirely. Its contribution is that violations become nameable, so a later layer can score them. The 2026-09-19 audit's FIX-6 and FIX-10 repaired the opposite failure: rules that claimed checks which did not exist. A rule that describes a phantom control is worse than no rule, because it stops people looking for the real one.
What enforces it: .claude/settings.json permissions.deny, 16 entries, listed in full in section 6.
How it is invoked: the harness itself matches the rule before the tool call is dispatched. No MPRO code runs; this is the vendor's own permission system.
What it refuses: force push in three spellings, --no-verify on push, commit and merge, git commit -n, forced worktree removal in two spellings, git branch -D, git stash clear, git stash pop, crontab -r, loginctl enable-linger, and edits to the pool-account settings files.
Where it is advisory: nowhere, but its reach is narrow by construction. It matches command strings, so /usr/bin/git push --force and sh -c 'git push --force' are not its business. Those go to L2. Since 3408f83638b a session started in a subfolder also receives the floor; before that repair it ran with none of it.
What enforces it: .claude/hooks/pre_tool_use.js (2397 lines) plus the modules under tools/safety/, and, for file content, a separate credential proxy guard in the live hook chain.
How it is invoked: as a PreToolUse hook on every Bash, Write and Edit. It receives the payload and inspects it; nothing is executed to decide.
What it refuses: measured on 2026-09-19 by feeding the guard 24 real attack shapes and comparing master 9d85cb6dc85 against 033e697c2cc. The 24 rows split exactly as follows: 11 were previously allowed and are now refused, 11 were already refused in both arms, 1 is the control, and 1 is explicitly uncounted. The 11 newly refused are command git branch -D, a force flag passed through a shell variable, git commit -n, git -c core.hooksPath=/dev/null commit, find <repo> -delete, python3 -c "shutil.rmtree(<repo>)", pkill -f, killall, systemctl stop on a live MPRO service, crontab -r inside sh -c, and crontab -e. The control row, echo ok, stayed allowed in both arms, which is what makes the other rows readable.
Where it is advisory, and the honest limit: the guard is text-pattern based. The probe deliberately recorded one row it could not answer: a credential pasted as prose into a Write was "allowed" by this file, because this file does not read Write content. Content is checked by a different hook in the live chain, which the probe never called. That row is counted as neither a hole nor a pass. If models get materially more capable, this is the layer that breaks first, and the durable answer is a kernel boundary (a sandbox or a separate OS user), not a longer regular expression.
What enforces it: tools/scripts/agent-git.js (9873 lines) for lanes, commits, landing and the fleet push lock; .githooks/pre-commit (1731 lines) for the content gates; tools/eidos/subagent-scope-check.js (293 lines) for declared scope; tools/safety/lib/integrity.js (748 lines) for protected-file hashes; tools/scripts/lib/worktree-release.js (666 lines) and tools/scripts/lib/runtime-worktree-pins.js (452 lines) for safe teardown.
How it is invoked: an agent never calls git commit directly on shared state. It asks the broker for a lane, commits by explicit path list, and lands through a fast-forward-only merge queue that holds a fleet-wide push lock.
What it refuses: sweeping a peer's uncommitted files into your commit; a commit whose staged content trips the secret scanner; non-ASCII violations of C62 on added lines; a raw NUL byte in source; a commit that fails the related-test TDD gate; a change to a protected file whose integrity hash does not match; releasing a lane that still holds the only copy of something; and removing a tree that a live systemd unit is executing from.
Where it is advisory: the C62 non-ASCII arm is advisory on staged added lines unless MPRO_WIN_LEFTOVER_BLOCKING=1 is set, and pre-existing dirt never fires (C96). The scope gate fails open when no manifest was declared. One known weakness is open with an owner: the touch ledger that proves which session touched a file can evict an entry before the commit under fleet churn.
What enforces it: .claude/hooks/universal-stop.js (644 lines) is Claude's single outward authority; it resolves and runs the gate chain. .claude/hooks/mastermind-stop.js (4402 lines) is the shared gate body. tools/eidos/mastermind-ask.js (20743 lines) runs the registered checks. tools/eidos/two-tier-gate.js (986 lines) and tools/eidos/mastermind-terminal-policy.js (315 lines) turn findings into exactly one decision.
How it is invoked: on the vendor's terminal event (Claude Stop, Codex managed Stop, and so on), under one monotonic deadline shared by every validator.
What it refuses: only two row kinds block. A SAFETY row must be grounded in the agent's own speech or actions - a destructive operation paired with an unproven claim, a secret in the transcript, a harm the agent itself described. A HARD_POLICY row blocks by category, the live example being money_loss_risk_ungated, a money-touching change that never got its triple review. mastermind-stop.js also blocks directly on its own HARD GATE 5b, own_report_rows_still_open.
Where it is advisory, with the measured numbers: QUALITY rows do not block. They carry a diagnostic -3 and cover proof style, report structure, stamps and the C107 six-dimension check. They are advisory because their precision was measured as too low to block on, and promotion waits on measured precision rather than on opinion. UNSCORABLE releases: a gate that timed out or could not read its input must not pretend to judge (C96).
The size of that advisory surface is the single most important honest number in this document. HISTORY, 2026-09-11 to 2026-09-18, not current: in the seven days before the terminal-policy repair the gate ran 16,263 times and produced 0 PASS, 846 FAIL and 15,417 UNSCORABLE. UNSCORABLE never blocks, so for the overwhelming majority of runs the gate was spending real seconds and releasing regardless. A replay of 1,156 of those runs through the repaired policy (FIX-7d, commits 8d40bf53b37, dd372b52829, cae88daf310) gives 1,066 UNSCORABLE, 65 FAIL and 25 clean releases. The repair made the gate able to block a real safety problem and able to say PASS; it did not convert the advisory tier into a blocking one, and nobody should read it as having done so.
What enforces it: tools/mpro-taskman/server.js (5309 lines) on port 3018, with an independent validator and a nightly profile CI sweep.
How it is invoked: an agent registers a node with a target and a verify plus at least one bound edge, claims it (a 24h lease), posts progress, then flips it to done with proof while the claim is still live.
What it refuses: a mutation without a derived agent credential (401), a credential whose identity differs from the body's agent (403), a mutation missing model, effort or agent (400), a same-meaning duplicate node (422), and a deliverable edge whose acceptance contract cannot bind (422, naming the exact strings to write).
Where it is advisory, and the number that says so: done is the agent's own word. validated means a separate process re-ran the persisted effect check. Measured on 2026-09-19: 3385 done across board and archive, of which 1065 are validated - 31.5%. Two thirds of finished work has not been independently re-checked. That is not a scandal, it is the honest state, and the profile-CI repair (FIX-5, PCI) is the first step at shrinking it.
What enforces it: systemd OnFailure drop-ins routing every mpro-* unit to mpro-alert@, which classifies the failure; the reapers and quarantine purge for disk; runtime-worktree-pins.js for trees a service runs from; the unit-install drift check; the task-board validator and nightly profile CI; the model registry refresh at 07:40; and a root sudo-allowlist audit every 15 minutes.
How it is invoked: by systemd timers and unit failure transitions, not by an agent.
What it refuses: it does not refuse, it detects and repairs. The classifier decides whether a failure becomes a board node for agents or a page for the CEO, so an ordinary crash does not wake a human and a genuine outage does.
Where it is honest about itself: at report build time exactly one mpro-* unit was failed, mpro-taskman-profile-ci.service, and the failure chain had already opened its own node for it without anyone looking. That is the monitoring working. One monitor is genuinely blind: the Syndicate hang check cannot write to the board for lack of a runtime identity, tracked as problem:obsbus.write-plane-rejected-runtime-identity-fleet-blind.
Parity means equivalent observable outcomes through personalized boundaries, not identical hook names. Ten vendors, one shared terminal vocabulary: PASS, FAIL, ADVISORY, UNSCORABLE.
| Vendor | Tier | Shared gates | Quality gate | Session fence | Proof the Stop ran |
|---|---|---|---|---|---|
| claude | canonical | hard-block | hard-block | advisory | present |
| codex | event-routed | hard-block | hard-block | advisory | present |
| grok | event-routed | hard-block | hard-block | advisory | present |
| kimi | event-routed | hard-block | hard-block | advisory | present |
| qwen | event-routed-partial | hard-block | hard-block | advisory | present |
| antigravity | event-routed-partial | hard-block | hard-block | advisory | absent |
| opencode | plugin-partial | advisory | hard-block | advisory | present |
| ollama | shim-advisory | absent | advisory | absent | absent |
| zen | bot-postbox | absent | advisory | absent | absent |
| max | bot-postbox | absent | advisory | absent | absent |
Read the last column carefully: "proof the Stop ran" means the harness can demonstrate the gate executed, not merely that it is configured. Antigravity is configured and cannot yet prove execution; that is a named gap, not a pass. The three bottom rows are not defects either: Zen and Max are carrier bots with no tool loop of their own, and Ollama has no interactive hook lifecycle, so its completion seam is bridge-owned.
The non-negotiable invariants behind that table, unchanged from v6.1.0: exactly one component emits the outward decision per terminal boundary; the four words mean the same thing everywhere; status, blocking, mayProceed and verified must agree or the contract fails closed as terminal_contract_invalid; explicit safety stays hard even when quality scoring is advisory or unavailable; an unavailable scorer is UNSCORABLE, not guilty, and must not cause a retry loop; evidence is bound to an exact vendor and session identity; every block names its owner and one bounded next action; unsupported lifecycle events are explicit waivers, never assumed; diagnostics are mode 0600 and metadata only; and recovery commands target the live mpro-*.service fleet, never PM2 or Windows remnants.
Ownership classes stay explicit. Every deduction is owned by AGENT, PEER, ENVIRONMENT or EXTERNAL_ADMIN. Only agent-owned evidence can reduce the current terminal score, and only when session scope is trusted. A stale node, a peer's dirty file or an external administrator's credential incident stays visible without taxing a session that never owned it.
For each load-bearing behaviour: what triggers it, what it depends on, what it drives downstream, and how a failure propagates. These edges are what a reader needs to answer "if X breaks, what else breaks".
| Behaviour | Trigger | Depends on (upstream) | Drives (downstream) | How failure propagates |
|---|---|---|---|---|
| Tool guard verdict | any Bash/Write/Edit | hook registration in settings; the guard file being current | whether the command runs at all | a stale or unregistered hook silently allows everything; the failure is invisible because nothing is logged when a guard does not run |
| Commit acceptance | agent-git commit | lane ownership, touch ledger, integrity baseline | what reaches master | an evicted ledger entry turns a legitimate commit into a refusal; a drifted integrity hash blocks a protected file until re-recorded |
| Stop decision | vendor terminal event | the gate finishing inside its deadline | whether the agent may finish | the gate exceeding its budget yields UNSCORABLE, which releases; so a slow gate degrades to no gate rather than to a block |
| Node validation | /validate on a done node | a bound, allowlisted effect check | whether work counts as validated | a drifted effect check latches validator_gave_up, and the node stays done-but-unvalidated forever |
| Service gets new code | deploy rail slot move | a clean standby slot, git status inside its cap | whether a landed fix runs | if every slot is refused, fixes land in git and never reach the running process - the exact SVCRAIL failure |
| Failure reaches a human | systemd OnFailure | the drop-in installed and the handler classifying | board node or CEO page | a masked or missing drop-in means the unit dies silently and nobody is paged |
| Receipt clears a claim | sub-agent finishes | the parent re-running the receipt | whether a sub-agent's claim is believed | a verifier that cannot run the suite shape leaves every receipt unverified, and the claim stands on nothing |
Two propagation chains from 2026-09-19 are worth stating end to end because they show how far a single edge failure travels. First: the deploy rail refused every slot, so the Ollama review-deadlock fix sat landed and inert, so reviews kept deadlocking, so review bridges appeared broken when the bug had already been fixed. The visible symptom was three layers away from the cause. Second: the Stop gate pulled the entire 25 MB board up to thirteen times per finish; the cost showed up as gate timeouts, gate timeouts become UNSCORABLE, and UNSCORABLE releases - so a performance defect was quietly converting the completion gate into a no-op.
Graph impact. This system owns the terminal boundary of all ten vendors. In the live :3060 code graph it appears as the three previously hidden authorities (universal-stop.js, mastermind-stop.js, mastermind-codex-hook.js) feeding the shared runtime, plus the vendor adapters feeding the terminal policy. Removing it would orphan every vendor adapter's decision path and every *-check.js module that has no other caller. On the task board it is the owner or dependency of the harm-prevention node family: 60 fixed rows and 26 delegated rows at the time of writing, each with a node id.
Business value, stated as harm avoided rather than revenue claimed. The value of this layer is that a fleet of autonomous agents can run unattended on a machine that also holds live revenue services, credentials and the CEO's own work. The measurable costs it prevents are: a force push or history rewrite destroying a peer's work; a credential reaching a transcript, a commit or a log; a destructive command matching a shape a regular expression missed; a landed fix never reaching the running service; and an agent reporting work complete that was never done, which is the most expensive of the five because every later decision is then made on false information.
Harm if wrong, and reversibility. If this layer is too weak, damage is real and some of it is irreversible: deleted work, a leaked key, a wiped service. If it is too strong, the damage is equally real but reversible: every agent on every vendor stops finishing work, which is exactly what the 15,417 UNSCORABLE runs would have looked like had they blocked instead of releasing. The architecture is deliberately asymmetric about this - safety fails closed, scoring fails open - because a gate that cannot see must not pretend to judge, and a gate that blocks the whole fleet is a bigger outage than the thing it was guarding against.
Who pays if it is wrong. The CEO pays twice: once in the direct damage, and once in the engineering time spent proving what happened. Every hour an agent spends re-running a gate that cannot score is drawn from the same shared token and capacity budget as productive work. That is why gate cost is treated as a product metric in section 13 and not as an implementation detail.
The state this system keeps is small, and all of it is inspectable.
| Store | Shape | Where | Lifetime |
|---|---|---|---|
| Task nodes | node_id, type, label, task, target, verify, severity, status, lifecycle stamps | Postgres graph.task_nodes | permanent; archived 7 days after validated |
| Task edges | from, to, kind, expected_effect, effect_check | graph.task_edges | permanent |
| Changelog | append-only rows including every progress note | graph.task_changelog | permanent; newest first on read |
| Session ledger | scoped non-stop state, session-bound | tools/eidos/task-ledger.js | session |
| Fence receipts | PreToolUse open, PostToolUse close, bounded lease | tools/eidos/session-scope-fence.js | session, with expiry |
| Integrity baseline | hashes of protected files | .hashes.json via tools/safety/lib/integrity.js | until re-recorded |
| Lane records | lane path, branch, owning agent | broker state under agent-git.js | until release |
| Gate evidence | per-session buffer, metadata only | .tmp/mastermind-*-<session>.txt, mode 0600 | session |
Every lifecycle field on a node carries model and effort alongside the agent: created_by, claimed_by, finished_by, verified_by. That is not bookkeeping for its own sake. Those stamps are the dataset from which "which model at which effort is strong or weak at what" will eventually be answered, which is why a stamp must always be a registry id derived at run time and never a remembered literal.
The lifecycle itself is a small state machine, and the one transition people misread is the last one:
open --claim--> in_progress --progress--> in_progress --status:done--> done
| |
lease expires /validate
| |
v v
open <--- stale-claim sweep validated or reopened
done is provisional. It needs a live same-agent claim and real proof, and it still does not mean verified. validated is earned later, when the service's own validator re-runs the edge's effect check. A board full of done nodes with validated:pending is not finished work.
| Symptom | What it actually means | Recovery |
|---|---|---|
Gate returns UNSCORABLE | the gate could not see, not that you failed | continue; do not retry in a loop. Fix the input or the budget |
terminal_contract_invalid | the producer emitted a contradictory tuple | fail closed is correct; repair the producer |
| Stop blocks with no detail | a defect in the gate, not in your work | the clarity guard appends gate name and reproduce command; two detail-less blocks in a session become a CTO escalation |
identity_mismatch (403) | the credential identity differs from the body's agent | derive your own credential; the raw shared key is only taskman_service |
claim_not_resumable (400) | the claim is missing session_id, worktree or branch | resend with all three; easy to misread as an auth failure |
| Edge write refused (422) | the acceptance contract cannot bind | the refusal names the exact strings; one retry with them succeeds |
validator_gave_up | the effect check drifted and latched | repair the contract, then authorize exactly one audited retry |
| Lane release refused | something unique would be lost | read what it names; never force-remove a worktree |
| A landed fix is not running | the deploy rail did not move the service | check the slot plan; landed is not running |
| A unit failed and nobody was paged | the OnFailure drop-in is missing or masked | an installed drop-in proves nothing until a controlled failure produces a node |
The four P0-class repairs of 2026-09-19 were each an error state that had stopped announcing itself, which is why they are recorded here rather than only in a changelog.
| Repair | What was wrong | Landed commits | Re-runnable check |
|---|---|---|---|
| SVCRAIL | the rail that moves services onto new code refused every slot, so fixes that had already landed on master did not reach 12 running services - including that night's fix for the Ollama review deadlock | c25c763e19b, 90ee66580d5 | npx jest tools/systemd/lib/service-runtime-plan.scrub.test.js tools/systemd/lib/service-runtime-cli.slow-git.test.js |
| BOARD | the gate deciding whether an agent may finish downloaded the whole 25 MB board, 5,406 tasks, up to 13 times per finish, and put the board's master key in plain text in the command line of every one of those calls | 35665cf4f82 | npx jest tools/mpro-taskman/server.nodes-fields.test.js tools/scripts/curl-bearer-argv.guard.test.js |
| WTREL | the git tool that lands work produced working copies its own clean-up could not remove, so copies piled up on disk; the only workaround was pushing already-landed work to a junk branch | 13f87ea7ff1 | npx jest tools/scripts/lib/worktree-release.patch-landed-unpushed.test.js |
| RCPTSUITE | the tool that re-runs a sub-agent's tests could not run a test written the way the rules tell sub-agents to write it, so every receipt stayed unverified unless the parent fixed it by hand | 9bd550beb4e | npx jest tools/eidos/subagent-receipt-verify.test.js -t "bare test path" |
All four were confirmed ancestors of origin/master with git merge-base --is-ancestor before being written here, as were the other six commits this document cites (8d40bf53b37, 0fffc59e74e, bb411754308, 3408f83638b, 76994fe1da0, and the FIX-7d pair).
To rebuild this system from nothing, in order. Each step names what to create, how to run it, and how to verify it before moving on.
deny entries from section 6 into the vendor's own permission file. Verify by attempting one denied shape and observing the refusal. This step costs nothing and immediately removes the highest-blast-radius commands.pre_tool_use.js as a PreToolUse hook over Bash, Write and Edit. It must inspect the payload and never execute it. Verify by feeding it the 24-shape probe from section 8 and checking that the control row (echo ok) still passes; a guard that refuses everything is as broken as one that refuses nothing.graph.task_nodes, task_edges and task_changelog, then the service on :3018 with derived per-agent credentials. Verify with a node create, claim, progress and done cycle, and confirm a mutation without provenance returns 400.status, blocking, mayProceed and verified must agree. Verify by feeding it a deliberately contradictory tuple and checking it fails closed.OnFailure drop-ins to every unit, then deliberately fail one unit and confirm a node or a page is produced. An installed drop-in proves nothing until a controlled failure exercises the handler.__dirname, register exactly one terminal authority, and probe it. A declared parityChecked flag without an executed probe is invalid.node tools/eidos/vendor-gate-sync-check.js --json and confirm every vendor row matches section 9, then run the gate itself and confirm it returns a coherent contract. If you cannot execute a vendor's terminal authority, the correct result is UNSCORABLE, not green.Reconstruction source order, if you have the repository: this SYSREF, the vendor roster, the gate manifest, the terminal policy, the universal runtime, the installer, the vendor adapter, the bridge completion seam, the scope fence, the task ledger, the parity audit, and the live :3060 graph.
Copy-paste ready, for any vendor.
Before finishing: node tools/eidos/mastermind-ask.js agent --json
Read the vendor reach: node tools/eidos/vendor-gate-sync-check.js --json
Check a SYSREF body: node -e "console.log(JSON.stringify(
require('./tools/eidos/sysref-depth-check').runSysrefDepthCheck(body,title),null,1))"
Get a lane: node tools/scripts/agent-git.js worktree-add --path <abs> \
--branch <b> --base origin/master --agent <id> --json
Verify a sub-agent: node tools/eidos/subagent-receipt-verify.js --receipt <f> --parent <node>
Board contract: curl -s http://localhost:3018/llms.txt
Three prompts that prevent the most common misreadings of this system. "Is this row blocking or advisory?" - ask it before treating any gate output as a control, because most rows advise. "Is it landed, or is it running?" - a commit on master is not a running service, and the SVCRAIL failure lived in that gap for twelve services. "Is this done, or is it validated?" - 31.5% of done work is validated, so the two words are not interchangeable.
| Reference | What it binds here |
|---|---|
values-bhagavad-gita.md | supreme layer; satya and ahimsa govern every decision in this document |
| C107 six-dimension task check | security, observability, concurrency, data loss, vulnerabilities, waste - asked at completion, advisory, capped at -2 |
| C96 gate must be passable | a gate may stop you, it may not trap you; the reason UNSCORABLE releases |
| C105 sub-agent receipts | a receipt is a claim set; the parent re-runs it |
| C87 worktree isolation | the lane is why concurrent mutating work is safe |
| C79 peer protection | a peer's in-flight work is protected on the same terms as the CEO's |
| C92 empty means empty | money is the only leftover a report may carry open |
| C86 search before create | why this article was updated in place rather than duplicated |
| C103 report address | a report is addressed by its Hub URL, not a worktree path |
| GR-70 / GR-71 | cross-vendor review; full lifecycle audit trail with model and effort |
.claude/rules/mastermind-gate.md | the mandatory gate policy every vendor inherits |
kb-sysref-rich-standard.md v1.4.0 | the authoring standard this article is written to |
v6.2.1 (2026-09-19, same-day accuracy correction) - the tool-guard count was re-derived from the probe table rather than copied: the 24 rows are 11 newly refused, 11 already refused, 1 control and 1 explicitly uncounted. The source report states twelve in its prose; eleven is what its own table supports, and eleven is what this reference carries. Flagged to the report's owner.
v6.2.0 (2026-09-19) - added the seven-layer harm-prevention architecture as the spine of this reference: for each layer, the exact file that enforces it, how it is invoked, what it refuses and where it is only advisory, at reconstruction depth. Added the four P0-class repairs of 2026-09-19 with their landed commits and re-runnable checks (SVCRAIL c25c763e19b/90ee66580d5, BOARD 35665cf4f82, WTREL 13f87ea7ff1, RCPTSUITE 9bd550beb4e). Added a fifth diagram with its ASCII companion, sourced from the tracked docs/mastermind/harm-prevention-layers.mmd. Added a Cause-and-Effect Map and an Impact and Value Analysis. Stated the advisory-versus-blocking split with the measured history (16,263 gate runs, 0 PASS, 846 FAIL, 15,417 UNSCORABLE, and UNSCORABLE never blocks) and the done-versus-validated split (3385 done, 1065 validated, 31.5%). Restructured to the 17 BP-078 section names and repaired the six acceptance-gate misses the previous revision carried, including a status line the gate regex could not match. Made the title ASCII-safe by replacing the em-dash with a plain hyphen, so a PDF export is filesystem-safe. Every commit cited was confirmed an ancestor of origin/master before publication.
v6.1.0 (2026-08-14) - made Stop labels consume the exact terminal result and breakdown row; distinguished coherent UNSCORABLE outcomes from malformed terminal contracts that must fail closed; required independent field-bound ownership before Mastermind may order an agent to commit shared dirty bytes; preserved hard push enforcement; corrected stale tests that treated empty fence scaffolding as evidence.
v6.0.0 (2026-08-14) - established equivalent-outcome vendor parity as the governing objective; documented all ten terminal boundaries and their honest lifecycle limitations; specified the one-authority and coherent-axis invariants; incorporated Codex timeout normalization, scoped credential ownership, non-stop and fence recovery rules, Ubuntu and systemd operations, future-vendor onboarding and code-graph impact; added four Mermaid sources with SVG diagrams and ASCII companions.
Why this section exists. The CEO read the harness and said the wisdom in it was not being applied: “check all as musk's rules in our harness was skipped ... there are more wisdon helping agent to be more effective and better perfom bust hadn't teeth” (2026-09-20). He was right, and it is not one rule. A governance file that states a duty and names no enforcing mechanism is advice; agents follow advice when it is convenient and skip it when it is not, and nothing records the difference. This section measures how much of our own governance is in that state. Every figure below is derived at read time from tools/eidos/governance-inventory.js, never typed — a typed count is stale the day after it ships, which is the same debt this report already argues against.
| Population | Total | NAMING no enforcer (declared — NOT a measure of whether enforcement exists) | Command that produced it |
|---|---|---|---|
.claude/rules/*.md | 192 | 64 (33%) | node -e "const g=require('./tools/eidos/governance-inventory.js');const inv=g.buildInventory({root:process.cwd()});const e=a=>!a||!a.length;console.log(inv.rules.filter(r=>e(r.enforcedBy)).length, inv.articles.filter(a=>e(a.enforcedBy)).length, inv.checks.filter(c=>e(c.gates)).length)" |
| Constitution articles | 69 | 27 (39%) — and the CEO read this as “a constitution without teeth”. It is not. See below. | |
tools/eidos/*-check.js reached by no gate | 311 | 59 — CORRECTED: the real dead population is 13. See the row below the table. |
CORRECTION, and it is a correction to this page’s own number. The 59 above is an instrument artifact, not a finding. governance-inventory.js gatesFor() follows static require() only, so it is blind to every other way a check is actually run — and two real batch runners use exactly those other ways: tools/eidos/precommit-batch.js:197 holds its modules as path strings and calls require() on a variable, and tools/scripts/pre-push-batch.js:103 joins a relative path before requiring it. Six of the seven checks named in .githooks/pre-commit run on every single commit while this instrument counted them as reaching no gate. The real dead population is 12 of 312 (re-measured 2026-09-20 15:20 EEST; this page said 13 and a quorum reviewer's independent re-run said 12 — I re-ran dead-check-census.js --json myself and it returns 12, so 13 is withdrawn), measured twice independently: node tools/eidos/dead-check-census.js --json → deadCount 13, and an independent git grep census → 12, the one-row delta being default-seam-coverage-check, whose only non-doc mention is a taskman effect_check that greps for a symbol name — an existence assertion, not a caller. Of those 13, zero should be deleted and zero should be merged: assessWorth returns exists_worthy 13/13, twelve already carried a dated disposition with a named unblock condition, and the apparent drift triplicate is a documented decomposition whose own modules say “SIBLING, NOT DUPLICATE”. Eight are genuine wiring candidates and each now carries a task-board address; five are deliberately unwired with reasons. The 59 is left visible above rather than quietly overwritten, because a page that silently swaps a number teaches nobody why the first one was wrong.
THE SECOND ROW IS THE SAME ARTIFACT, AND IT MISLED THE CEO — so it is corrected here in his words. He opened this page, saw nothing found against MANDATORY articles, and asked: “we gave constitution without teeth?” No. governance-inventory.js:683 computes an article’s enforcer list as any registered check or rule whose TEXT contains the literal token C<n> (MARKER_RE = /\bC(\d{1,3})\b/g, line 241). An article is therefore reported “enforced” only if some file happens to spell its number. It measures declaration, never behaviour — the same blindness as the row above, in a third place. Probed live:
| Article | This page said | What actually enforces it |
|---|---|---|
C20 Honesty First — Only Tested Truth | nothing found | claim-grounding-check.js plus 11 unproven-claims-* suites |
C57 Prompt Clarity Gate | nothing found | .claude/hooks/mastermind-pre-task.js — it fired on the CEO’s own last two prompts |
C21 Loop Detection and Escalation | nothing found | dead-end-loop-guard |
C59 No-Guessing Mandate | nothing found | .claude/rules/no-guessing.md |
C23 Postbox Communication Standards | nothing found | tools/autonomous/lib/create-agent-task.js |
There IS a real defect under the false alarm, and it is worth fixing. Because no article names its enforcer, nobody can trace article → mechanism — so a genuinely toothless MANDATORY article is indistinguishable from an enforced one, and hides in a list of 27. That is a traceability defect, not an enforcement vacuum, and the remedy is to make each article name what enforces it so this column becomes true. And the constitution itself was measured for loss across all 120 revisions — then that measurement was itself found to be an artifact, the FOURTH on this page from one root cause. The surviving result is stronger than the original: zero articles missing, zero stubs, zero dangling truncations, and ZERO topics lost. Everything else I published about it was wrong in two ways.
| What this page said | What is true | Why the instrument lied |
|---|---|---|
| “the 69 articles” | 107 articles | The constitution uses two heading conventions — ## Cnn (C19–C26, C47–C107) and ### Cnn. (C0–C18, C27–C46). Every scan here used ^## C, which sees 69 and misses 38 — including C0, the supreme principle. Worse, C86 prescribed that exact grep as the search-before-create instrument, so it could tell an agent that C8 or C29 does not exist. |
“twelve compressed hard, C73 −85%” | Nothing shrank. 12 of 12 were the same artifact. | Each of the twelve was the last article in the file at its “peak” revision, so the splitter swept the document trailer — **Constitution Version** plus the whole accumulated changelog — into its body. Re-verified independently here: C73 raw-peak 6 638 B, trailer 5 564 B, real body 1 074 B — byte-identical to today. Four of five checked are byte-identical; the fifth differs by 1 byte of dash normalisation. |
Byte-identity is a stronger proof than a topic list — if the text is unchanged, every duty, threshold, number and named module in it is present. So the CEO’s question (“hope we not lost any of topics”) is answered no topic was lost, on better evidence than the audit that claimed to be looking for loss. One real displacement was found: C9 was a 254-byte title while its entire binding body — the inheritance diagram, the template standard, four MUSTs and the six-step New Project Protocol — sat inside C14. Not lost, misfiled; returned to C9.
The third row still points the other way, and that part holds. Dead teeth are teeth already built, tested and paid for, wired into nothing. Connecting an existing check costs a fraction of writing one, which is why Musk’s own ordering (question → delete → simplify → accelerate → automate) puts deleting and connecting ahead of building. An audit that responded to “33% unenforced” by commissioning 64 new checks would be the exact waste the algorithm exists to prevent.
Three instances of the same defect were found by hand before the population was measured, which is what made the pattern visible: the Markdown-report rule named an enforcing module whose file-inspecting function had zero callers and had been dead for roughly three months; musk-worth-trigger.js scores correctly and had zero references in either gate path, so the five-step algorithm reached agents as prompt text and nothing scored it at completion; and model-registry-refresh.js --help printed no usage and ran a full vendor scan instead. A rule that names its teeth is making a claim; the callers are the evidence. git grep the callers before recording anything as enforced.
What 33% does NOT mean, stated so the number is not misread in either direction. It is not a backlog of 64 checks to write. A meaningful share of those files are routers — a few lines pointing an agent at a skill or reference, where a gate would be meaningless — and another share ask for judgement (taste, care, honesty) that no deterministic check can score. Naming those honestly is part of the result: it stops the next agent building a proxy check, and a check that answers a cheap proxy instead of the real question is itself a recorded defect class (C107 ①c). Forcing a gate onto every rule would also break the guard values-bhagavad-gita.md rule 9 sets out in its own inversion clause — a check that charges every trivial turn is one agents learn to route around, and this harness has had to repair that failure twice. The classification into needs teeth / router / judgement is owned by task:governance.prose-only-rules-and-unenforced-articles, and the wiring queue for the 59 by the sweep that node references; both are board-tracked, so this section reports state and hands the reader nothing to chase.
The CEO asked for the “real life status when will be finished and what rules and guides”. This is that status, and every row was re-run here rather than accepted from the implementing agent’s receipt — a receipt is a claim set, never proof (C105).
| Claim | How it was re-verified here | Result |
|---|---|---|
| The scorer exists and is wired | git cat-file -e origin/master:<path> on all three new files | PRESENT — musk-worth-gate-check.js + its two suites |
| Wired in both gate paths, not one | Walked each call site back to its enclosing function in master’s blob | 2 distinct functions — runAgentModeQuick (L9769) and runAgentMode (L15493) |
| The item is attributable | musk_worth_unscored in the AGENT_ITEMS literal | present |
| Tests pass, not skipped | npm test -- <both suites> --no-coverage | 26/26, 0 skipped, exit 0 |
| It reaches every vendor without a third copy | Read mastermind-stop.js:2443 and the fold-back path | Confirmed — Stop spawns agent --quick --json and folds the child’s breakdown.filter(b => b.delta < 0) into its own issues, so one wiring reaches all shared-Stop vendors. A third block would double-charge. |
And the re-run found a defect the receipt could not have shown — the arm was silent exactly where it was wired. musk-worth-gate-check.js scores at completion, reading the agent’s own speech buffer, but it reused musk-worth-trigger.CREATE_RE — a regex written for the prompt half, where a human writes imperatives. That alternation carries automat(e|ing|ion) but not automated, and build but not built. At completion an agent describes finished work in the past tense. Measured against the live speech buffer of the very session that built the check: 7 past-tense build words, 0 present-tense, detectMuskWorth → not_a_create, delta 0. A synthetic present-tense A/B had passed, which is why the gap survived its own test suite — and it is the same shape as the correction above: the instrument, not the system, was the thing that was wrong.
Fixed and landed as c2a793d59a0 (blobs verified identical on origin/master). Tense was widened in the one shared regex rather than by adding a completion-tense copy, because a second copy of a predicate is the refactor debt values-bhagavad-gita.md rule 9(vi)(a) names. Proof, all re-runnable: RED — all four past-tense cases return false against the master regex; GREEN — 41/41 across the three suites; positive control — this session’s live buffer now returns trigger=true where it returned not_a_create; and then a quorum review proved the fix itself was wrong, so it was NARROWED. Every number in the first two versions of this paragraph is withdrawn; these replace them and are re-derivable. Three defects were found in the fix, not in the original diagnosis: (i) one hunk widened new <noun> to allow two intervening words — a syntactic change the commit message described as a tense change, and because \s matches a NEWLINE, a heading ending in “new” reached into the next sentence and scored it. (ii) Bare automated is an adjective in real agent prose: all four corpus occurrences were automated check / sweep / report, and one charged an agent for a sentence asserting that automation does not exist. (iii) The denominator was wrong — “2 110 buffers” counted .transcript-receipt.json and .transcript-marker.json sidecars holding no speech. The widening is confined to the create verbs already listed and deliberately excludes generic completion words like landed, wired and implemented, which appear in nearly every turn; those exclusions are pinned as negative-control tests.
| Corpus (definition stated, so it can be re-derived) | Before | Over-wide, as shipped | Narrowed, now |
|---|---|---|---|
Completion speech — real .txt no-hedge buffers, sidecar JSON excluded and the measuring session's own buffer excluded. 1 335 at 15:22 EEST; this corpus is live and reaped hourly, so the denominator drifts upward between any two runs and an exact re-run will differ — the fire counts are the stable part. | 13 | 16 (2 of the 3 new ones false) | 14 |
| Why the measuring session is excluded — a reviewer found the reopen trigger firing itself. The known-miss rule says “a corpus containing builds a script reopens the widening”. That corpus includes agents’ speech about the trigger, so writing the rule down eventually satisfies it: within one review round, all three known-miss phrases appeared in the corpus — every one of them inside this session’s own buffer, discussing them. Excluding the measuring session restores 0, 0, 0. A self-triggering predicate is recorded here rather than left to reopen a closed decision on its own echo. | |||
| Prompt side — WITHDRAWN. An independent reviewer read every line of all 2 939 transcripts under eight different definitions of “a real user prompt” and reproduced none of the figures published here — not the first pair, and not the replacement. Rather than print a third unreproducible number, this row states the failure: the prompt-side population could not be defined reproducibly, so no rate is claimed. The direction survives (that half did gain a new surface); the magnitude does not. | — | — | — |
The honest conclusion, which is not the flattering one. On the scoring corpus the narrowed regex fires on exactly the same 13 buffers as before any of this — so the tense fix has, so far, caught zero real past-tense creations, and all four false positives are gone. That is a better outcome than the version that shipped, but it is not the win the earlier text claimed. The reason is worth stating: real completion prose says “I built a report” or “added a test” — nouns on no branch's list — so the arm still misses most creation turns. The original defect is therefore only PARTLY fixed, the remainder is recorded as known misses with a mechanical reopen trigger, and the four shipped false positives are now pinned as regression tests so they cannot return. Suites 52/52.
And the widening stops here, because the next increment was measured to buy nothing. The same review noted that third-person and progressive forms of the same verbs remain unmatched — automates, builds, creates, adds. The mechanism claim is correct, so the impact was measured instead of argued: adding every one of those conjugations fires on 17 of 2 110 completion buffers — identical to what shipped, a gain of exactly zero — while adding 15 more prompt-side fires. The forms are common (adds in 24 buffers, creates in 16, builds in 11) but in the measured corpora they always appear as adds a test or builds a report — nouns that are on no branch's list, so those buffers stay silent for a second, independent reason. So the conjugations were declined: Musk step 2 applied to this very change, delete the part you were about to add.
A second review round then corrected this page again, on two points, and both were right. (a) The sentence above originally claimed the branch requires one of those nouns. That is true of only two of the five branches (an earlier wording said “three”, itself an incomplete description of the predicate — the same defect one level down. should we build|automate|create needs no noun either, and new <noun> uses a THIRD list containing feature|service|tool). Verified against the live regex: the create-verb branch needs task|node|ticket|backlog, the build sub-branch needs bot|script|pipeline|automation|daemon|cron, and the automat* branch needs no noun at all — which is why “I am automating triage” fires with no listed noun anywhere in it. A published description of a predicate that the code does not implement is the same defect class as the two instrument artifacts above, so it is corrected here rather than quietly. (b) Three of the pinned tests paired an unmatched verb form with a noun that is on the list — builds a script, creating a node, adds a task. Those are genuine false negatives, exactly what the branch exists to catch, and labelling them “deliberately not matched” would have frozen a real gap as an intention. They are now a separate, explicitly named group: known misses, unfixed for one measured reason only — zero occurrences in either corpus — with a mechanical reopen trigger. A corpus containing one reopens the widening; an opinion does not.
What this changes in practice. Before: Musk’s algorithm reached agents as prompt text and nothing scored it — the CEO’s “hadn’t teeth” was literally true for this rule. After: a turn that creates, builds or automates something without scoring it against the five steps takes a −1 advisory row (musk_worth_unscored) on every vendor whose Stop routes through the shared gate, and the discharge is cheap and honest — state the worth verdict, name the scorer, or name the step you applied. The rule and guide now carrying teeth: .claude/rules/musk-five-step-algorithm.md and its reference in mpro-agent-orchestration.
A gift to the community — Darius Kiaulakis, Mainstream.PRO
Givers Gain. This is the real engineering report of a working multi-vendor agent harness, published in full minus what would expose the machine itself. Take anything in it: the checks, the tables, the measurements, the failures. Nothing here needs my permission to copy.
📞 +370 665 55500 · ✉️ Darius@Kiaulakis.lt · 💬 AI Mastermind LT — Telegram group
#AiOpsCatalyst · #BremenLLM · #GiversGain
Public edition of the MPRO harness report, 2026-09-20. Every figure carries the command that produced it — please re-run rather than cite. Sections covering this machine’s own privilege, network and control-plane surface are deliberately not included.