NAI OS · as-built inventory · 2026-10-15

Harnessing measures

Every measure in this repository that narrows what an agent may do: from the connector that exists at all, down to the sentence in the prompt. Nine layers, catalogued with the file each one lives in.

The cohort's own vocabulary calls Claude Code the harness: "the operating system/foundation" an agent runs in (Resources/Sessions/Session 1.md). Harnessing, in that reading, is everything that constrains the model inside it. In NAI OS those constraints are layered on purpose, and the repo states the principle behind the layering in its own loop write-up:

The thesis, from 08 Option Studies/loop-pattern.md

"A guardrail written as prose can be argued with; a tool that isn't in the grant cannot be called. When a loop's quality gate matters, put the separation in tools:."

Read the layers outside-in. A request passes the human-only line first, then the provider scope, the harness permission file, the agent's tool grant, the prompt boundary, the orchestrator's gates, the verification shape, and finally the data and publication guards and the code-level checks in the scripts. Every row below cites the file it was read from; nothing is inferred.

25 / 25subagents with an explicit tools: allowlist
15 / 56permission allow / deny rules in .claude/settings.json
53Qonto tools denied; 9 read tools allowed
4canonical access classes (A, B, C, D)
4verification shapes, matched to cost of a wrong answer
3rounds, absolute bound on the one loop
9.gitignore files plus one per-machine Stop hook
13 / 10command files / agent systems; 3 commands are not systems

01The nine layers

  1. L0
    Human-only line
    CLAUDE.md · 01 Preparation/tasks-eating-time.md · 13 Decision Pack · 14 LinkedIn
    Decisions, filings, payments, sending and publishing are never delegated. Every system prepares and stops.
  2. L1
    Provider and server scope
    claude mcp add --tools · claude.ai connector · .mcp.json · env credentials · .claude/hooks/
    Decides which tools exist at all; secrets stay outside git and, in the cloud, outside the session.
  3. L2
    Harness permission file
    .claude/settings.json (tracked) · .claude/settings.local.json (per machine, gitignored)
    The harness refuses denied tools in every session, main or subagent, before any prompt runs.
  4. L3
    Agent tool grant
    .claude/agents/*.md · tools: frontmatter
    Exactly what the body uses, not one tool more. An absent tool cannot be called.
  5. L4
    Prompt boundary
    ## Boundary in every agent · docs/agent-conventions.md
    One canonical access-class sentence, agent-specific nevers, the missing-data contract: never fabricate.
  6. L5
    Orchestration gates
    .claude/commands/*.md
    STOP gates, confirm-before-irreversible, hard round bound, wave order, files as the interface, orchestrator-only promotion.
  7. L6
    Verification shape
    docs/verification-patterns.md · checker agents · publish guard
    Bounded loop, single adversarial pass with a terminal verdict, computed tie-out, or none by design.
  8. L7
    Data and publication guards
    9 × .gitignore · Stop hook DENY pattern · .vercelignore · 12 Documentation/proposed/
    Real data never commits; a staged page is never served. Two independent layers for each.
  9. L8
    Code-level checks in scripts
    scripts/paper-upload · scripts/issue-bridge · scripts/issue-router · scripts/onto-sync
    Refusals the model cannot argue with: folder allowlists, magic-byte checks, single-issue scope, one-line status protocol.

Amber marks the one layer that is not a mechanism but a design decision: what the harness is never asked to do.

L0Human-only line

The pre-course deliverable fixed which tasks are agent candidates and which stay human. Every system's command description repeats its own version of that line, and two whole folders are kept agent-free.

MeasureLives inWhat stays humanEvidence
Reserved task class01 Preparation/tasks-eating-time.md Final trade-off decisions, stakeholder negotiation and communication. "Final trade-off decisions | Needs human judgment, context, and accountability."
Prepare-and-stop contractEvery command's description: Tax: human files via ELSTER and pays. Option study: human decides. Review: human delivers. Spec: human adopts. Newsletter and briefing: human sends. nai-tax-theo.md: "You NEVER file, pay, or move money"; nai-option-study.md: "you NEVER decide"; nai-review.md: "the human delivers it".
Agent-free folder: decision gates13 Decision Pack/ Client gate conversations, answers verbatim, verdicts against pre-written criteria. README: "Human-only by design — no agent in NAI OS writes or updates files here."
Agent-free workflow: LinkedIn14 LinkedIn/ Publishing under Udo's name. A copy script formats; a person pastes. README: "There is deliberately no agent, no scheduler, and no LinkedIn API involved".
Judgement boundary in taxloan-interest-vga, vat-worksheet Whether a loan is fremdüblich, which rate applies, whether a vGA exists: the Steuerberater's call. Ambiguous VAT lines go to "Unclassified — needs review", never to a guessed Kennziffer. loan-interest-vga.md: "You FLAG risks; you NEVER decide".
Census never submits/nai-cohort-census Posting to the cohort space. Also: names and counts only, never file contents or prompt text. "You measure and draft; you NEVER submit".

L1Provider and server scope

Before any permission rule or prompt applies, the server decides which tools exist. The repo's stated pattern is "broad OAuth scopes at the server, narrow enforcement at the subagent tools: whitelist" (docs/superpowers/mcp-google-setup.md), and it records the cost of that choice rather than hiding it.

MeasureLives inWhat it narrowsEvidence
google-workspace tool listLocal server registration, user-scoped Server runs with --tools gmail calendar chat contacts; nothing else is loaded. Chat and Contacts are exposed but granted to no agent (see gaps). docs/machine-setup.md Step 3; docs/architecture/concept-tools.html.
Qonto off by defaultclaude.ai connector toggle Enabled only for the quarterly close, then disabled: no banking surface while editing prompts. The deny list (L2) stays on regardless. docs/machine-setup.md: "treat Qonto as off by default, on for the quarterly close"; "the deny list is the guard that's always on."
nai-onto bearer token, scoped by role.mcp.json Token scope read for queries, write only where runs are recorded. Never written into a file in the repo. docs/machine-setup.md: "Never write the token into a file in this repo."
Proxy-injected credentials in the cloudEnvironment API credential NAI_ONTO_TOKEN=proxy-injected; the agent proxy attaches the real token outside the VM, so it never enters the session. scripts/onto-sync/README.md: "the script then sends no Authorization header".
Service-account key outside the repoGDRIVE_SA_JSON env var; scripts/paper-upload/.gitignore Key JSON lives outside the repo; the folder's .gitignore catches any *.json dropped there by mistake (only package.json is tracked). "A service-account key must never land in the repo."
Cloud-only SessionStart hook.claude/hooks/session-start-gdrive.sh, wired in settings.json No-ops unless CLAUDE_CODE_REMOTE=true and the key is set; writes the rclone config with umask 077 and chmod 600, then self-checks the config references the file it wrote. The script's header comment and its grep -qF self-check.
Research library over API onlypaper-ingester, scripts/paper-upload/drive.mjs Never the local H:\ mount, on any machine; one helper is the only way in. "This library is Drive-API-only, on every machine."

L2Harness permission file

The tracked .claude/settings.json is applied by Claude Code before any agent is dispatched. It is the layer that holds even when a prompt is wrong, and the layer that keeps a connected Qonto session read-only.

MeasureRulesWhat it refusesEvidence
Qonto deny list53 deny 9 allow Every tool that creates, changes, sends or approves (transfers, cards, invoices, quotes, clients, memberships, attachments), plus the read tools the pipeline does not use. Applies in main and subagent sessions alike. 06 Tax Agent/README.md: "deny-lists every other Qonto tool ... so the harness refuses them in any session — main or subagent."
Bash narrowed per purpose6 allow patterns Allowed shapes only: curl -sSL -o "06 Tax Agent/* (receipts into the tax folder), git log/add/commit, gh repo *, one sort form. .claude/settings.json permissions.allow.
Wiki write denied at the shell3 deny mv, cp and curl whose arguments reference library-wiki…wiki: a structural backstop under the paper-ingester's prose rule. paper-ingester.md: "a second, structural backstop under this instruction, not a replacement for following it."
Per-machine file kept out of git.claude/settings.local.json* Holds the Stop hook and a live Google OAuth client secret; gitignored with a wildcard so editor backups are swept too; transferred out of band only. Root .gitignore; docs/machine-setup.md Step 2.
Hook events1 tracked, 1 per machine SessionStart (tracked, cloud setup). Stop (per machine): auto-commit and push, holding back guarded paths (L7). .claude/settings.json hooks; docs/machine-setup.md.

L3Agent tool grant

All 25 subagents declare a tools: allowlist. The convention is exact: "Grant exactly what the body uses. Not one tool more", and "A grant that contradicts a boundary is worse than a missing grant. A missing grant fails loudly" (docs/agent-conventions.md). Only four agents hold a remote mcp__ tool at all.

MeasureAgentsWhat the absence makes impossibleEvidence
No send tool in the mailbox agentemail-triage Holds search, read and draft. The server does expose send_gmail_message and label modification; neither is granted, so sending is impossible, not forbidden. docs/architecture/concept-boundary.html.
No write tool in the calendar agentcalendar-briefing Two Calendar read tools plus web lookups; no Write, no event mutation. Frontmatter: list_calendars, get_events, WebSearch, WebFetch.
Nine Qonto reads, no money toolsqonto-collector, loan-interest-vga List and get only; the loan agent holds list_transactions alone. No create, approve or transfer tool is in either grant. Frontmatter of both agents.
No web tools by designoption-recommender, finding-drafter, spec-rule-drafter, all three scopers, newsletter-writer, vat-worksheet, all four doc-* agents A drafter cannot cite what it cannot reach; evidence enters only through the verifier, the dropped files, or a vetted research file. loop-pattern.md §1: "The critic is independent — enforced by tools, not prose".
Checkers get Grep, not Globfinding-checker, spec-rule-checker, doc-checker Read, Write, Grep: enough to hunt for a quoted string, nothing to author with. Frontmatter of the three checkers.
Bash scoped to named purposesqonto-collector, paper-ingester Collector: one purpose, curl receipts. Ingester: four purposes, curl the PDF, run render.mjs for a web-source candidate, run the Drive helper, delete the temp file. WebFetch in the ingester: one purpose, find the PDF link on a landing page. paper-ingester.md: "Bash is granted for exactly four purposes".
Grant audit before every commitAll agents For each tool in tools:, find where the body uses it; if you cannot, remove it. onto-sync --check extracts the grants into the ontology and exits 1 on drift. docs/agent-conventions.md; scripts/onto-sync/README.md.

L4Prompt boundary

Every agent prompt is self-contained on purpose: a shared include could move or be renamed and silently drop a guardrail, and "for email-triage, whose boundary is 'never send', a silently-dropped guardrail is the one failure mode that is unacceptable." The fix for drift between the copies was canonical wording, not indirection.

MeasureLives inWhat it guaranteesEvidence
Four access classes, one verbatim sentence each## Boundary of every agent A observe only, no files (1 agent) · B read remote, write local (22) · C read remote, stage remote: drafts only (1) · D read remote, file remote: add new files only (1) docs/agent-conventions.md, "The four access classes".
Mandatory heading and orderAll agents ## Boundary, never "Guardrails" or "HARD SAFETY BOUNDARY"; then Input, Missing input, Process, Output, Return. One structure, so a missing section is visible. "Canonical phrasings" table.
Missing-data contractAll agents; JSON status field ok / missing / unconfigured. Never fabricate to fill a gap; an empty array is not missing; never compute from partial data; every agent has a ## Missing input section. "vat-worksheet shipped without one and was the agent most likely to need it."
Entity from config, never hardcoded06 Tax Agent/inputs/config.yaml Agents read organization.name; nothing an agent writes may hardcode the GmbH. The example YAML is the fallback. CLAUDE.md; "Canonical phrasings".
Full repo-root-relative pathsAll agents A subagent has no "current period folder"; the period is a parameter, so every path is written in full. "Verbosity wins."
No phase numbers in descriptionsAll agents Agents describe what they do, not when they run; the orchestrator's wave model is the truth. "No phase numbers".
View, never a calculatorcockpit-writer, doc-renderer Every figure, date and sentence rendered appears verbatim in the source markdown; no sums, rounding or rewording. A cockpit that computes would be a second source of truth. cockpit-writer.md rule 1; doc-renderer.md: "You never author, edit, shorten, expand, correct, or reorder the author's prose."
Verdict only, default UNSUPPORTEDThe three checkers, option-verifier Never edit, add or drop what is being checked; a quote that cannot be located is UNSUPPORTED, never benefit of the doubt; never fabricate a source. finding-checker.md rules 1 to 3; option-verifier.md rule 3.
No evidence, no findingfinding-drafter, spec-rule-drafter A concern without a verbatim quote from a dropped file becomes an open question for the human, never a finding or a rule. "The evidence rule is absolute: no verbatim quote from a dropped file, no finding."
Gaps stated, never filled from memoryea-context-reviewer, review-scoper, spec-context-scoper General knowledge may frame a brief; it never substitutes for absent evidence. Boundary of each scoper.
Never claim "proven"option-recommender Without web tools it may not call an option battle-tested or invent a citation; it may say what evidence would support it. Previous rounds are never modified. option-recommender.md Boundary.
Hand-edited files never regeneratedvoice-profiler, newsletter-writer The voice profile is written only if absent, then edited by hand; the writer reads exactly two files and nothing else in the repo. voice-profiler.md: "if it exists, STOP".
Documenters never touch what they documentAll four doc-* agents Never write into docs/, never edit an agent or command file, never author prose. doc-scoper.md, doc-surveyor.md Boundary.
Public information onlycompany-research, tech-radar, option-verifier, voice-profiler No scraping behind logins, no pretexting. Boundary sentence shared by the web-reading agents.

L5Orchestration gates

The command files hold the control flow. Their gates are of six kinds; each kind appears in several systems.

Gate kindWhereRuleEvidence
STOP on missing inputoption-study, review, spec-drafter, newsletter, paper-ingest, document No slug, no request file, no instances, no voice profile, no paper link, no matching target: stop and say so. Never run on a guess. nai-review.md: "Never run without a subject"; nai-newsletter.md: "do not draft an issue with no voice profile".
STOP before overwriteoption-study, review, spec-drafter, newsletter An existing non-empty output folder may carry hand annotations: ask before overwriting, never silently. "They may have annotated the study. Never silently overwrite."
STOP on a blocked or error returnAll systems A subagent's blocked: or missing: line, or a script's ERROR: line, is relayed verbatim and ends the run. Never continue on a partial source list. nai-document.md Step 3; nai-issue-to-agent.md step 1.
Confirm before the irreversibleissue-to-agent A comment on a client issue cannot be edited or removed through the app, so the orchestrator stops for explicit confirmation. Silence, a vague reply or an assumed yes do not count. "Do not proceed on silence, a vague reply, or an assumed 'yes'."
One remote write, nothing elsepaper-ingest, issue-to-agent, issue-check Paper ingest posts one summary comment and never closes, labels or edits the issue; an environment problem is relayed in chat, not posted. Issue check sends one push notification and never quotes a comment body. nai-paper-ingest.md step 4; nai-issue-check.md step 2.
Hard round boundoption-study At most three recommend-verify rounds. Only FAIL iterates; THIN exits as a finding; at the bound FAILed options are flagged, never dropped. "You never run a fourth round. The bound is absolute — it does not stretch for 'one more try'".
Wave order, never same-messageoption-study, review, spec-drafter, document Verify only after the drafter has returned; dispatch the next wave in a new message so the critic never sees unfinished work. "Only after Wave 1 returns — never in the same message".
Files are the interfaceoption-study The critique travels as a file the next round reads from disk; the orchestrator passes paths and a round number, never the critique text. Earlier rounds are never edited. loop-pattern.md §2: "The critique travels by file, not by context".
Orchestrator re-derives nothingoption-study, review, spec-drafter Verdicts, counts and quotes are copied verbatim from the working files, never recounted or reworded; empty sections say "None", never omitted. nai-review.md: "figure copied from the working files' own header lines, never recounted".
Stage, then promote by the orchestrator onlydocument Generators write to 12 Documentation/runs/<target>/proposed/, never under docs/. Promotion happens only if mode is create, every verdict is CONFIRMED and every guard line is ✓; an existing page is always staged, never overwritten. nai-document.md Steps 4 and 7; "Never claim a page is published when it was only staged."
Exact target lists, no pattern fallbackdocument The blog denylist (blog-ideas) and the editorial list are closed enumerations; an ambiguous target stops and asks. "Exactly these targets, and no pattern fallback".
Confidence-tiered autonomyissue-route TypeSafe confidence ≥ 0.85 dispatches, ≥ 0.60 asks, below that or readiness < 0.50 lists for the human; a model failure routes to human. Thresholds are tracked and hand-tuned; the README's first-week setting is 1.0, so nothing dispatches without a yes. scripts/issue-router/thresholds.json; README "Calibrating the thresholds".
Unattended runs never asknewsletter routine On a schedule, the STOP gates become one-line exits: an existing folder or a quiet month ends the run; the draft goes to a branch and a pull request, nothing is sent. 07 Newsletter/README.md: "An unattended run never asks".
Run ledger last, never blockingEvery system command Recording the run in the ontology prints one line and always exits 0; UNCONFIGURED skips silently, ERROR is reported once and never retried, and it may never change the report above it. Section "Run ledger (last, never blocking)" in each command.

L6Verification shape

Rigor is matched to what a wrong answer costs, not to what the system could afford. The map is docs/verification-patterns.md; the design line is that for the cheap, disposable systems "the guardrail is in tools:, not in a second agent's judgment."

ShapeSystemsWho checksIterates
1 Bounded generator/critic loopoption-studyoption-verifier, web-grounded≤ 3 rounds, only on FAIL
2 Single adversarial passreview, spec-drafter, documentfinding-checker, spec-rule-checker, doc-checkerNo. The verdict is terminal; an UNSUPPORTED item goes to the human, never back to the drafter.
3 Orchestrator-computed tie-outtax-theo, document (publish guard)The orchestrator, no subagentNo. Deltas are ✓ or flagged; the three guard checks are lookups, not judgement.
4 No cross-check, by designchief-of-staff, newsletter, paper-ingest, payroll-theodoraNone; the human reads every linen/a. Safety sits in the tool grant, and for paper-ingest in a tool-layer check (curl -f plus a %PDF magic-byte test).

Why no loop in shapes 2 and 3. "Iterating would let the drafter rewrite findings until they slip past the checker" (nai-review.md). The checker still runs on zero findings and records the zero, so its absence is never silent.

L7Data and publication guards

Two guards per risk, each independent of the other. Git ignores real data; the Stop hook refuses to stage it even when forced. Vercel serves only an allowlist; a staged page sits outside that allowlist by construction.

MeasureLives inWhat it holds backEvidence
Root .gitignore.gitignore .claude/settings.local.json* (wildcard, live OAuth secret), 05 Briefings/* except README and the redacted sample, local worktrees. "Only the redacted sample is tracked."
Per-system .gitignore with example carve-out08 Option Studies/, 09 Review Packs/, 10 Spec Drafts/ inputs/* and the output folder, re-including only the synthetic example slug as the visible trace. Each file's header comment names the Stop hook as the second layer.
Tax data, no synthetic example06 Tax Agent/.gitignore config.yaml, loan.yaml, payslips, every YYYY-MM/ and YYYY-Qn/ pack. Real GmbH figures are not faked; only *.example.yaml templates are tracked. CLAUDE.md, Privacy guards.
Script secrets and logsscripts/issue-bridge, issue-router, onto-sync, paper-upload .env (Supabase service role, TypeSafe key, nai-onto token), routing-log.jsonl and .last-run.json (issue titles), the notification cursor, any stray key JSON. The four folders' .gitignore files.
Stop hook DENY pattern.claude/settings.local.json, per machine Holds back the same confidential paths from staging on every auto-commit, with PCRE negative lookaheads carving out the examples; requires LC_ALL=C.UTF-8 or grep -P silently disables the guard. A canary test with git add -f is prescribed after rebuilding it. docs/machine-setup.md Step 2: "Without it, .gitignore is your only guard".
Deploy allowlist.vercelignore (repo root, the only one) Excludes every top-level entry, re-includes exact files and folders under docs/. Introduced after a root-directory build published the whole repo. Header: "Misconfigured root builds once published the whole repo (2026-07-19)".
Staged pages inert by construction12 Documentation/runs/*/proposed/ Outside docs/, so never served however often the Stop hook pushes it; that inertness is what the publish gate is built on. 12 Documentation/README.md.
Publish guard, three lookups/nai-document Step 6 Serve path re-included in .vercelignore; new page reachable from a collecting page; every relative href and src resolves against the final path. "Check one is the one that would have caught the features.html 404 in 1d912a49."
Documented exceptions07 Newsletter/, 12 Documentation/, 06 Tax Agent/ Two folders have no .gitignore because every input and output is public already; the tax folder has no tracked example because real figures are not worth faking. Each exception is written down with its reason. CLAUDE.md: "Three folders deliberately don't follow that pattern".
Census leaks nothingscripts/cohort-census/census.py Counts and names only; "never include file contents, prompt text, or any data an agent has touched". nai-cohort-census.md §1.

L8Code-level checks in scripts

Where a boundary can be enforced in plain Node, it is. These refusals do not depend on the model reading its prompt.

MeasureScriptWhat the code refusesEvidence
Folder allowlist in the Drive helperscripts/paper-upload/drive.mjs Lists or writes only direct children of work/; refuses work/ itself, library-wiki/, wiki/ and any nested folder; only adds new files, never overwrites, moves or deletes. paper-ingester.md: "The helper enforces the boundary in code as well".
Magic-byte check on downloadspaper-ingester Bash step curl -f plus a %PDF test, so a paywall or error page is never filed as if it were the paper. docs/verification-patterns.md §4.
Single-issue scope, insert onlyscripts/issue-bridge/fetch-issue.mjs, post-comment.mjs Touch only the one issue id passed; the only write is one insert into issue_comments; never update or delete, never change content or status. README "Safety".
Read-only activity scanscripts/issue-bridge/check-activity.mjs Select across all issues, writes only its own cursor file; a missing cursor defaults to now, so a first run never dumps history. Skips the owner's own activity. README "Activity check".
Read-only routerscripts/issue-router/route.mjs gh issue list is the only subcommand; the script never comments, labels, closes or edits. Client issues from nai-analysis are deliberately not a source. Tests run fully offline. README "Safety"; design decision 3, 2026-09-25.
One-line status protocolAll bridge, router, onto-sync and Drive scripts Print exactly one line, always exit 0: OK, MISSING, UNCONFIGURED or ERROR: …. Control flow reads the line, never the exit code, so a crash cannot be mistaken for success. scripts/issue-bridge/README.md; scripts/onto-sync/README.md.
New subagent needs a human role entryscripts/onto-sync/sync.mjs, overrides.json The sync refuses an agent without a role in the overrides: the judgement-shaped part of the inventory stays a human call. --check exits 1 on any drift between agent files and the ontology. README: "that is the human's call, on purpose."
Clipboard formatter, no APIscripts/linkedin-copy/copy-post.ts Formats one post as plain text for pasting; the LinkedIn API is never called. 14 LinkedIn/README.md.

02Measures by system

The ten systems and the three commands that are not systems, read across the layers.

CommandReaches outside the repoRemote writesGatesVerificationPrivacy guardStays human
/nai-chief-of-staffGmail read, Calendar read, webGmail drafts onlyDrafts await reviewNone, by design05 Briefings gitignore + Stop hookSending mail, changing events
/nai-tax-theoQonto, 9 read toolsNoneEntity from config; direction read, never assumedComputed tie-out06 Tax Agent gitignore + Stop hook; Qonto deny listFiling via ELSTER, paying
/nai-payroll-theodoraNone (dropped payslip only)NoneMissing payslip flagged, never guessedNone, by design06 Tax Agent gitignore + Stop hookFiling, paying
/nai-newsletterWeb, via tech-radarNoneSTOP on existing folder, no voice profile, quiet monthNone, by designNone needed (public output)Pasting and sending
/nai-option-studyWeb, verifier onlyNoneSTOP on missing input / overwrite; 3-round bound; wave orderBounded loop08 gitignore + Stop hookThe trade-off decision
/nai-reviewNone, no web anywhereNoneSTOP on missing subject / overwrite; wave orderSingle adversarial pass09 gitignore + Stop hookDelivering the review
/nai-issue-to-agentnai-analysis Supabase, one issueOne comment, after explicit confirmationSTOP on MISSING / ERROR / blocked; confirm before postingInherits the dispatched system's.env gitignored + Stop hookConfirming the undeletable post
/nai-spec-drafterNone, no web anywhereNoneSTOP on missing instances / overwrite; create vs update never guessedSingle adversarial pass10 gitignore + Stop hookAdopting the spec
/nai-paper-ingestGitHub issue read, landing pages, Drive APIOne PDF added, one issue commentSTOP on no link; never close, label or editNone; tool-layer PDF checkKey outside repo; wiki denied at shell and in codeWiki ingestion, topic correction
/nai-documentNone, no web anywhereNoneSTOP on unknown target; stage, promote only create + CONFIRMED + guard ✓Adversarial pass + computed guardNone needed; proposed/ inertPromoting an updated page
/nai-cohort-censusNoneNoneNames and counts onlyn/an/aSubmitting
/nai-issue-checknai-analysis Supabase, readOne push notificationQuiet result sends nothing; never quotes bodiesn/aCursor file gitignoredActing on the activity
/nai-issue-routeGitHub read, TypeSafeNone (dispatches paper-ingest)auto ≥ 0.85, review ≥ 0.60, else humann/aLog and key gitignored + Stop hookReview-tier and human-tier issues

03Agent roster: class, grant, the specific never

Twenty-five subagents. Class and tools are copied from each file's frontmatter and Boundary; the last column is the one rule specific to that agent beyond its class sentence.

AgentClasstools:Specific never
calendar-briefingAlist_calendars, get_events, WebSearch, WebFetchNever create, modify, move or delete events; writes no files.
email-triageCsearch_gmail_messages, get_gmail_message_content, draft_gmail_messageNever send, reply-send, delete, trash or archive; refuses if asked to send.
tech-radarBWebSearch, WebFetch, Read, WriteScan mode writes nothing; public information only.
company-researchBWebSearch, WebFetch, Read, WriteNo scraping behind logins, no pretexting.
cockpit-writerBRead, Write, GlobA view, never a calculator; never invents or drops a decision item; never edits the markdown it reads.
qonto-collectorB9 Qonto read tools, Read, Write, BashNever moves money; Bash for one purpose, curl receipts.
loan-interest-vgaBRead, Write, list_transactionsFlags; never decides fremdüblich, rate or vGA; never invents contract terms.
vat-worksheetBRead, WriteNever fabricates a figure; ambiguous lines go to Unclassified, not a guessed Kennziffer.
payroll-lohnsteuerBRead, Write, GlobNever invents a figure; missing payslip is flagged and the run stops.
newsletter-writerBRead, WriteReads exactly two files; never sends, publishes or pushes.
voice-profilerBWebFetch, Read, Write, GlobWrites the profile only if absent; STOPs if it exists.
ea-context-reviewerBRead, Write, GlobNo web tools; gaps stated as gaps, never filled from memory.
option-recommenderBRead, WriteNo web by design; never claims an option is proven; never modifies a previous round.
option-verifierBWebSearch, WebFetch, Read, WriteNever rewrites, adds or drops an option; never fabricates a source.
review-scoperBRead, Write, GlobNo web tools; gaps stated, never filled from memory.
finding-drafterBRead, Write, GlobNo verbatim quote, no finding; concerns become open questions.
finding-checkerBRead, Write, GrepVerdicts only; checks the citation, not the architecture; default UNSUPPORTED.
spec-context-scoperBRead, Write, GlobNo web tools; gaps stated, never filled from memory.
spec-rule-drafterBRead, Write, GlobNo verbatim quote, no rule; patterns become open questions.
spec-rule-checkerBRead, Write, GrepVerdicts only; checks the citation, not the grammar; default UNSUPPORTED.
doc-scoperBRead, Write, Glob, GrepNever writes docs/; never edits an agent or command; never authors prose.
doc-surveyorBRead, Write, GlobStages only; no web; never writes prose it cannot cite.
doc-rendererBRead, WriteNever authors, edits, shortens or reorders the author's prose; never writes docs/.
doc-checkerBRead, Write, GrepVerdict is terminal; never sends a claim back; never writes docs/.
paper-ingesterDBash, Read, WebFetchAdds new files to work/<Topic>/ only; Bash for four purposes; never touches wiki/.

04Incidents and lessons that produced a measure

The repo records why most of these exist. The reasons are measures too: they are what keeps the next edit from undoing them.

DateWhat happenedMeasure it producedRecorded in
2026-07-19A git-connected Vercel build from the repo root published every tracked file.Repo-root .vercelignore as an exclude-all, re-include-exact allowlist.docs/deploying-the-architecture-site.md
2026-07-26A duplicate project and a root vercel.json shadowed docs/vercel.json; both deployments 404'd.One project, one .vercelignore; the root vercel.json and docs/.vercelignore deleted.Same document
commit 1d912a49features.html went live as a 404 because it was not re-included.Publish guard check 1, serve path, in /nai-document.docs/verification-patterns.md
before agent-conventionsRead, Write, Glob, Grep had been pasted as a default suffix onto 6 of 10 agents; two grants contradicted the agent's own boundary."Grant exactly what the body uses"; the pre-commit grant audit.docs/agent-conventions.md
before agent-conventionsFive phrasings of read-only, four incompatible missing-data contracts, three house structures.Four canonical class sentences, one contract, one structure.Same document
before agent-conventionsvat-worksheet shipped without a Missing input section."Every agent has a ## Missing input section. No exceptions."Same document
2026-08-08Tech-radar brief on LifeOS: its installer mutates settings.json and would collide with the Stop-hook privacy guard.Not installed. "Read three files, steal two ideas, install nothing."03 Research/tech-radar/lifeos-agent-harness-layer-2026-08-08.md
2026-09-23paper-ingester needed to add files to a remote system, which no existing class allowed.Access class D, read remote and file remote, add-only.Commit "Add access class D (read remote, file remote) for paper-ingester"
2026-09-25Issue router design: client issues are confidential; titles are sent to a third-party judgment API.Only this repo's own issues are a source; nai-analysis deliberately excluded.scripts/issue-router/README.md, decision 3

05Gaps the repo documents about itself

Stated in the repo's own words, not found by this inventory. They are where the next measure would go.