The knowledge repo has no root `CLAUDE.md` — every agent loads only its own class bundle
Mirrored from the fleet knowledge base: wi/decisions/ADR-7799-no-root-claude-md-in-knowledge.md
Updated
Mirrored verbatim from
utopia-models/knowledgewi/decisions/ADR-7799-no-root-claude-md-in-knowledge.mdby the allowlisted publish pipeline. Edit it there, not here.
artifact_type: adr
adr_id: ADR-7799
adr_status: accepted
status: active
decision_date: 2026-09-13
supersedes:
superseded_by:
issue: 7799
subprocess: process
references:
- wi/work/specs/7799-masters-stop-loading-architect-bundle/spec.md
- wi/work/research/2026-09-13-plan-267-the-remaining-16-workflows-verdicts.md
- _infra/scripts/kb-lint.py
- _infra/scripts/task-runner.sh
- _process/north-star.mdThe knowledge repo has no root CLAUDE.md — every agent loads only its own class bundle
Produced by the process subprocess (wi/subprocesses/dispatch/process.md): it changes what a
dispatched run loads and what task-runner.sh's brief tells it to read — the execution path itself.
Filed from #7788 (PLAN-267 P7), the ADAPT verdict on the OSS-tools / AGENTS.md slice. Parent Feature
#7781.
Context
#7316 (PLAN-256 P3, 2026-08-31) made the repo-root CLAUDE.md one line,
@_process/_generated/bundle-architect.md, and fixed the root at exactly three files in kb-lint.py R1.
Claude Code loads the CLAUDE.md in the working directory and every directory above it, and
task-runner.sh runs claude -p inside a knowledge per-run worktree. So every master run in this repo
loaded the Architect's bundle on top of its own.
Measured 2026-09-13, before this change:
$ readlink -f ~/.claude/rules/bundle.md # on each box
win /home/win/dev/utopia-models/knowledge/_process/_generated/bundle-master.md
nova /home/nova/dev/utopia-models/knowledge/_process/_generated/bundle-master.md
cloud /home/cloud/dev/utopia-models/knowledge/_process/_generated/bundle-master.md
dust /home/dust/dev/utopia-models/knowledge/_process/_generated/bundle-master.md
kxdev /home/kxdev/dev/utopia-models/knowledge/_process/_generated/bundle-architect.md
$ wc -c _process/_generated/bundle-architect.md _process/_generated/bundle-master.md
64618 bundle-architect.md
26550 bundle-master.md
$ cd <knowledge per-run worktree on win> && claude -p 'Print verbatim every line … "**Loaded by:**"' --max-turns 1
**Loaded by:** win · nova · cloud · dust — executes a filed issue.
**Loaded by:** the Architect (`agent`) — plans with Tyler, files, dispatches.
$ ssh kxdev@eth 'cd ~/dev/utopia-models/knowledge && claude -p <same> --max-turns 1'
**Loaded by:** the Architect (`agent`) — plans with Tyler, files, dispatches.
$ cd <detached knowledge worktree at 0854e244a on win> && claude -p /context --max-turns 1 # Memory Files
| User | /home/win/.claude/CLAUDE.md | 1.1k |
| User | /home/win/dev/utopia-models/knowledge/_process/_generated/bundle-master.md | 10k |
| Project | <worktree>/CLAUDE.md | 22 |
| Project | <worktree>/_process/_generated/bundle-architect.md | 24.3k |🔴 Grade this with claude -p /context, not a "print the lines" prompt. The Architect box's harness
refused the verbatim-print prompt 3 times in 4 on 2026-09-13 (reading it as a system-prompt dump) and
once answered A=NO to a yes/no variant while the same prompt from ~ answered A=YES. /context's
Memory Files table is emitted by the harness, not the model, and does not vary.
Two facts follow. The import added nothing for the Architect — its box already loads
bundle-architect.md through ~/.claude/rules/bundle.md, and its read-back prints the line once. On
every master it added 64,618 B of audience: architect doctrine to a 26,550 B bundle, ~91 KB against
the 30,000 B master ceiling — the widening _process/north-star.md forbids ("Do not widen this
audience"). process-build.py measures only ~/.claude/rules/*.md, so its ceiling check could not see
it.
Beside it, task-runner.sh resolved $CLONE/<portfolio>/CLAUDE.md into the brief (#6443). That file
exists for 0 of 6 portfolios (ls {wi,raw,dmv-research,5am,govcon,sf}/CLAUDE.md), so the block never
fired, and both briefs opened with "Read the repo root CLAUDE.md" — a pointer at the import.
Considered Options
- Do nothing. Rejected: ~91 KB on every master run, against a ceiling the build enforces on a different path.
- AGENTS.md at the root. Rejected: "Claude Code reads
CLAUDE.md, notAGENTS.md" (code.claude.com/docs/en/memory); one harness means no second reader. 0 of 22 org repos carry one. - Keep a root
CLAUDE.mdwith repo-wide content instead of the import. Rejected: every agent class that opens this repo (master, architect, cowork, personal, always-on) already has a compiled bundle carrying the shared doctrine (artifact types, core behaviors, the loop). A root file would be a second copy of text the build already delivers — the drift classprocess-build.pyexists to remove. - Integrate the existing mechanism — delete the root file.
~/.claude/rules/bundle.mdis already the one per-class loader, and it is the only one each box needs.
Decision Outcome
Chosen: delete knowledge/CLAUDE.md. The root holds exactly README.md and GOALS.md
(kb-lint.py R1). The principle kept from AGENTS.md: a repo-root instruction file carries what ANY
agent in that repo needs, never one class's bundle — and in this repo the bundles already carry all of
that, so the file has nothing left to hold.
task-runner.sh's portfolio-CLAUDE.mdblock is deleted, and both briefs' first line says the doctrine is already in context rather than sending the run to a root file.kb-lint.pyR1 and its negative control assert two root files.- A future root
CLAUDE.mdin this repo is a defect unless it carries something no class bundle does; R1 fails on it, which is the point at which that argument gets made.
Consequences
- Good, because a master run in
knowledgeloads 26,550 B of bundle instead of ~91 KB, and nothing addressed only to the Architect. - Good, because the Architect's sessions are unchanged — their bundle never depended on the import.
- Bad, because an agent that opens
knowledgeWITHOUT a~/.claude/rules/bundle.md(a box never provisioned byprocess-build.py's class symlink) now loads no doctrine from the repo at all; before, it at least got the Architect's. Every registered agent box has the symlink (#7362), so this is a provisioning defect to fix on that box, never a reason to restore the import. - Bad, because dated notes and diagrams that describe the old root file (e.g.
wi/work/reference/win/diagrams/dispatched-run-anatomy.gv) now describe a past state. They are evidence with a date on it, not claims about the live tree, and are left as written.
Corrections retired with the code they guarded
task-runner.sh's "🔴 TWO DEFECTS FIXED 2026-08-28" (SF missing from the portfolio alternation; the grep not case-insensitive, so issue #7149's 26 lowercasesfresolved to nothing). Both guarded the portfolio-CLAUDE.mdlookup deleted here. Its measurement — an emptyPORTFOLIO_PATHis indistinguishable from a run that needed none — is the reason the block is deleted rather than re-pointed at<portfolio>/README.md: a brief line that silently vanishes on a miss is the same defect with a different file name. The text stays in git history (git show 0854e244a:_infra/scripts/task-runner.sh).- Preserved, re-worded: README's "🔴 THE ROOT HOLDS EXACTLY THESE 3" → 2;
win-docs-index.py's "🔴 RETARGETED #7316" now says the root holds noCLAUDE.md.
What this does NOT change
- The content of any bundle, and
process-build.py's ceiling. _process/the-loop.md's "Ground first: repo rootCLAUDE.md" — it is generic across every repo a master works (utopia, brain repos), where such a file still exists.
Two modes — `dispatch` and `interactive` — and whether to monitor is read from the subprocess
Mirrored from the fleet knowledge base: wi/decisions/ADR-7781-two-modes-dispatch-and-interactive.md
ADR-9836 — The Architect's always-on layer is a project-free floor; project text is `<project>/context.md`
Mirrored from the fleet knowledge base: wi/decisions/ADR-9836-a-project-free-shared-floor.md