What surrounds a window
A window starts out knowing nothing. Then four different places each push something into it — rules, skills, tools, helpers. Every confusing thing here is one of two questions being mixed up.
Two questions, two different switches
Supply — does this thing exist in the window at all? Decided by where it lives and what scope it's switched on for.
Reach — is this particular window allowed to use it? Decided by the helper's own file. Keep them apart and everything else follows.
The four placements — and how far each one reaches
The third question — WHEN it arrives
Instructions, tools, an identity, walls, checks, meters, a way to move it all. Nine jobs — the page The Nine Jobs.
Four sources. Vendor terms first: user scope (~/.claude/) · the working directory and its parents · the agent file · the launch flags. here: floor · folder · file · flags
Five moments: launch · turn · dispatch · compaction · stop. A path-scoped rule is instructions (what), from the project folder (where), at the first matching read (when). One thing, three coordinates — the page When Things Arrive.
The seven direction rules — each mechanism has one home and reaches one way
These seven answer the folder-above-your-projects question in one line: a folder above contributes exactly one thing to the projects beneath it — its CLAUDE.md (rule 1). Its settings stay home (2), its agents are scanned only inside the same repo (3), and memory ignores it unless that folder is the git repository (5).
The launch line, as you'd actually type it
~/Projects/strategy-seat $ claude a launch with empty hands: floor + folder + memory + every tool ~/Projects/strategy-seat $ claude --agent gap-checker Layer 3 applied: skills listed, no Write, no roster, no outside tools ~/Projects/strategy-seat $ claude --plugin-dir ~/Projects/strategy-seat/tools/lab/example-marketplace/real-estate --agent real-estate:listing-analyst Layer 4 supplies the helper, Layer 3 fences it: Read, Write, Bash — nothing else (tested) ~/Projects/strategy-seat $ claude --settings ~/ring-rules.json --mcp-config ~/one-server.json --append-system-prompt "House rule for this run only." three things handed in, none of them known to the folder. all three arrived (tested)
Typing claude is a launch with empty hands. Every flag is more words on that same line — and they stack: --agent gap-checker --plugin-dir … took effect together, each layer still doing its own job in order.
Equipment is assembled at Enter. The CLI's own words for a dropped-in plugin: "auto-loads next session." To change what a window is, close it and launch its successor — nothing durable lives in the window.
--bare skips hooks, plugins, memory and rulebook discovery in one word — every layer on this page, disabled at once. The only way to see a truly naked window.
Move the levers.
Watch what lands.
Four levers on the left; the window on the right shows exactly what arrived, from which layer, and what exists but cannot be reached. Every line has a WHERE FROM button naming the file it came from.
Installing writes one on/off line (enabledPlugins) into one of three files. The scope buttons pick which file — the line under them names it, and who that file reaches.
No file at all: the launch line itself carries the thing in, for one run. If the same plugin is also installed, nothing loads twice — the handed-in copy replaces the installed one for that run (measured 28 Aug, two distinguishable copies).
Where the numbers come from
The 28 skills (5,304 tokens always-on), the helper roster (~10,600, from measured sizes), the strategy seat rulebook (~18,500) and memory (~6,250), the outside-tool list (~3,075), the real-estate plugin's four slots (~630: agents 267, skills ~230, MCP tool 131 deferred — /context, 30 Aug).
The monolith and real-estate folder rulebook sizes, the floor briefing, and the house rules. Real folders, plausible sizes. The meter is about the relative size of layers, not exact figures.
Some fences cut
one at a time.
Some cut everything.
A helper's file is the only layer that takes things away — but it doesn't fence every kind of thing the same way. That difference is the one you need to design around.
| What | How the helper file fences it | Verified on this machine |
|---|---|---|
| Built-in tools | per item Read, Write, Bash… each named individually on the tools line | home-lead holds Read and Write only — no Bash |
| Outside-service tools (MCP) | per item each tool named individually — a helper can hold a server's read tools and not its send tool | inbox-digest: the Gmail read tools, never send. The connection runs; the tool is simply absent |
| The helper roster | per item Agent(gap-checker, general-purpose) names exactly who may be dispatched; no Agent tool at all means no roster arrives | gm names two; a one-worker seat carries 812 B of roster instead of 42,473 |
| Skills | all or nothing for the listing: the Skill tool is present or absent. But a helper file can ADD: a skills: list preloads those skills' full bodies into a dispatched child | gap-checker sees 28; home-lead sees none at all. Preload measured today: the skill's marker arrived in a dispatched child's first turn — and did nothing on a --agent launch |
| Rulebooks (CLAUDE.md) | not fenceable no key in the helper format excludes a rulebook | every helper reads its launch folder's rulebook in full |
| Memory | not fenceable no memory key in the format | measured across all 34 helper files |
| Hooks | not fenceable — only addable a helper file can carry its own Stop check; it cannot remove a floor hook | 32 of 34 carry the produce-then-verify check |
A fenced helper walks into the strategy seat folder — what it gets, item by item
Where a helper
comes from — and what it arrives with
A helper is a file: a name, a description, a tools line, a model, its instructions. That file is its identity. Where the file sits decides who can see it. Where it is launched decides what it knows. Those are three different things, and every confusion about helpers is two of them being read as one.
The four places a helper's file can come from — every row tested
| Home | Who can see it | On this machine | Evidence |
|---|---|---|---|
| ~/.claude/agents/ | every seat, launched anywhere — and every window pays ~1,250 B of roster for each | 34 helpers — your entire roster | a /tmp window and a brand-new folder both listed all of them |
| <project>/.claude/agents/ | only seats launched in that folder; subfolders don't inherit | unused — absent in strategy seat, monolith, message courier | a probe helper planted there was found by name from that folder and not found from strategy seat, both as a dispatch and as a launch |
| inside a plugin | wherever the plugin's scope reaches; prefixed real-estate:listing-analyst | monolith carries none; the prototype carries two | roster 35 → 37 with the plugin, 35 → 41 with a 6-helper plugin |
| handed in at launch — --agents '{json}' | that one window, and the children it dispatches | never used here | tested today: an inline helper joined the roster, was dispatched (returned its marker, held exactly Read), and a window was launched as it |
~/Projects/strategy-seat $ claude --agents '{"probe-json": {"description": "A probe helper defined inline, for one run.", "prompt": "You are a probe. Your marker is PROBE-JSON-5150.", "tools": ["Read"]}}' --agent probe-json (1) marker: PROBE-JSON-5150 ← the identity came from the JSON (2) tools: Read only ← its fence held (3) sees the strategy seat rulebook: yes ← the equipment came from the FOLDER (4) sees the strategy seat memory: yes
Two verbs, one rule
claude --agent gap-checker. You talk to it. It gets the launch folder's rulebook, memory drawer and hooks, then its own file subtracts.
The Agent tool, subagent_type: gap-checker. The child is born fresh and loads nothing of its own — it inherits the block the parent rendered at boot, then its own file subtracts.
Universal identity is not universal knowledge
The roster makes the WHO universal. The folder still decides the WHAT.
A floor helper is the same identity everywhere — same tools, same model, same instructions. But gap-checker launched in strategy seat reads the strategy seat's rulebook and memory; launched in monolith it reads monolith's. The inline JSON helper above proved the split in one cell: identity from the launch line, equipment from the folder. Floor = everyone knows, everyone pays · project = only here · plugin = wherever you switch it on · launch = this run.
A skill is a file.
The magic is the listing.
Every skill has two required pieces: a name and a one-line description. Everything under that is ordinary written instructions. What the system adds is the listing at boot and a tidy way to load it — nothing else.
--- name: corpus description: "Use whenever you need information from the operator's knowledge home (~/Projects/knowledge-base) — business frameworks, venture facts, the operator profile…" --- # Corpus — using the knowledge home 1. **Route** — read ~/Projects/knowledge-base/index.md … 2. **Pull** — read wiki/<slug>.md … 3. **Needle** — grep across wiki/ AND raw/ …
Two front-matter lines, then ordinary instructions. The description is the only part a window sees before it decides to load the skill — which makes it the entire routing mechanism.
The four homes — and what each holds on this machine, today
The journey from your folder to a window — and the three places it breaks
Turn the breaks on and off. The first is on because it is true on this machine right now.
The costs, measured
A folder you
switch on as one unit
Think of it as an app. It has a name and a version so the system can refer to it, and room for five kinds of thing — skills are only one of them.
Not in the format: permissions and rulebooks. The CLI's component vocabulary is exactly agents · commands · hooks · lspServers · mcpServers · skills; 0 of 39 official plugins ship settings.
It's an address book for finding plugins to install. A folder in ~/.claude/skills/<name>/ auto-loads on its own, and --plugin-dir carries one in for a single run with no install at all.
Install copies the plugin into ~/.claude/plugins/cache/. Windows load the copy. Your copy is 0.4.0 with 11 skills; your source is 0.5.6 with 28 — 17 skills authored, never published, for 35 days, with no error anywhere.
What the files look like — the prototype's, verbatim
{
"name": "real-estate",
"version": "0.1.0",
"description": "A brokerage's listing and transaction craft…",
"author": { "name": "Harborline Realty (illustrative example)" }
}{
"hooks": {
"PostToolUse": [
{ "matcher": "Read|Write|Edit",
"hooks": [ { "type": "command",
"command": "python3 \"${CLAUDE_PLUGIN_ROOT}/hooks/stamp.py\"",
"timeout": 10 } ] }
]
}
}The folder layout is the whole format: .claude-plugin/plugin.json · skills/<name>/SKILL.md · agents/<name>.md · hooks/hooks.json · .mcp.json. Seven files made the prototype.
A second real plugin, installed today — and the scoping rule shown on it
| Window opened in | superpowers: skills seen |
|---|---|
| ~/Projects/strategy-seat | 14 |
| ~/Projects/strategy-seat/reference | 0 — a subfolder does not inherit the switch |
| /tmp | 0 |
| a child dispatched FROM an strategy seat window | lists them (10 counted by the probe) — it inherits the parent's render |
| a child dispatched from strategy seat/reference | 0 — the parent had none to render |
So "scope" does two jobs. For a window it means which launch folder switches the plugin on. For a child it means nothing directly — a child sees whatever its parent had rendered at boot, plugin skills included. Measured, both rows.
The switch is one line in ~/Projects/strategy-seat/.claude/settings.json; the files sit in ~/.claude/plugins/cache/. Nothing else on the machine pays for it. That is the difference between this and monolith's user-scope switch, on two real plugins side by side.
Scope — who pays, and the surprise
| Switched on at | Who sees it | Evidence |
|---|---|---|
| user (the default) | every folder on the machine | a window in /tmp sees all 28 |
| project | windows launched in that folder — and only that folder | one settings line turned monolith OFF for a folder: 28 → 0 |
| local | same, just you | recorded in settings.local.json |
| a subfolder of that project | reverts to the machine default | launched in the subfolder: back to 28 — retested with a git root, same. "Project scope" means launch-folder scope |
| the launch | this run only | --plugin-dir — helpers, skills, a working hook and (measured 28 Aug) its MCP server arrived; gone at close. Same plugin also installed? One copy loads — the handed-in one |
The switch and the files — click through the four measured positions
A plugin is two things that are easy to conflate: where its files live and where its switch is. Pick one of each and watch what a window opened in the case folder actually loads — and what goes stale when you edit the source. Every position below was measured with the sample plugin on 30 Aug.
Rules that run,
not rules that are read
A hook is a small program that fires by itself at a fixed moment. It doesn't ask. That makes it the strongest rule you have — and it still obeys the reach rules of wherever it lives.
The moments — and which can say no
| Moment | When | Can it stop things? |
|---|---|---|
| PreToolUse | before a tool call | prevents the only one that stops an action before it happens |
| PostToolUse | after a tool call | can block usually just records; blocking is a choice, not a limit |
| Stop | a window tries to finish | can block refuses the exit, sends the window back to work |
| UserPromptSubmit | you press Enter | can block |
| SubagentStop | a dispatched helper finishes | best-effort on leaf helpers — not guaranteed |
| InstructionsLoaded | each instruction file as it loads | observes the instrument for this whole manual — tested today: it logged every rulebook with a load_reason (session_start · include · path_glob_match), the importing parent, and the glob that triggered a path-scoped rule. Two limits, measured: it does not log auto memory (MEMORY.md never appeared, even for a window whose memory clearly loaded), and it fires zero times for a dispatched child — because a child loads nothing; it inherits the parent's rendered block (confirmed by a timed test with a rule file written after the parent booted) |
| SessionStart | a window boots | observes / injects can ADD text — your floor briefing arrives this way |
| Notification · PostCompact | events | observe only |
The useful subset, not the inventory — the registry holds 31 moments. And a hook isn't only a script: command, prompt and agent kinds exist; the last two let a rule think before deciding.
Where a hook lives decides who it governs — try it
Pick a home. fires never sees it untested
---
name: gm
model: opus
tools: Read, Write, Edit, Bash, Agent(gap-checker, general-purpose), ListAgents, SendMessage, Skill
hooks:
Stop:
- hooks:
- type: command
command: "~/.claude/hooks/stop-hook.sh"
- type: command
command: "~/.claude/hooks/capture-hook.sh"
---Two things in one frontmatter: the tools line that fences (note Agent(gap-checker, general-purpose) — a roster of exactly two) and the hooks block that travels with the helper into any folder. 27 of your 34 helper files carry a Stop block like this.
Wired on this machine, today
A cabinet on the floor,
one drawer per folder
The right words: each fact is a memory file, they sit in a memory directory, and MEMORY.md is the index. Only the index loads at start; a memory file is opened when its line looks relevant. Cabinet and catalog.
The cabinet stands on the machine floor — that is where the bytes are. But it has one drawer per git repository (outside a repo: per folder), and opening any folder of that repo hands you that drawer and no other. A drawer directory is created at every launch, so most of them are empty scratch folders. ~/.claude/memory does not exist — there is no global memory.
- [strategy seat CLI port](strategy-seat-cli-port.md) — what the strategy seat is; phase-1 (Notion dead, knowledge read-only) - [System roadmap](system-roadmap.md) — LIVING roadmap at reference/roadmap.md; read on strategy/sequencing - [Title X vs Title Co](title-x-vs-title-co-distinction.md) — "Title X" (#146) = friend PM favor; NEVER his own Title Co … 127 lines · 24,864 bytes · one line per memory file · the ONLY part loaded at start
The cabinet and the catalog — the strategy seat store, measured
The wall the index stands against
What memory costs — try it
161 slim files and 161 heavy files cost exactly the same at boot, because only the index loads. Weight is paid per open, by the session that opens it.
Who writes it, and the rules
One window,
one drawer
The rulebook stacks — global, category and project all load. Memory never stacks: a window is handed exactly one memory directory. "User scope" is not a second layer on top of a project drawer; it is the same single slot, filled from a different settings file.
Exactly one drawer — verified four ways tonight
Vendor doc: "Claude Code uses the value from the highest level that sets it." · The schema: the key is one string, not a list. · The code: falls back to the user setting only when nothing higher sets it. · The probe: a scratch repo whose project settings said drawer X, launched with the command line saying drawer Y — the window named Y only, and X was never even created.
What decides the drawer — highest wins, nothing adds
Read top-down. The first level that names a drawer wins; every level below it is ignored for that window. Only when no level names one does the default apply.
Try the setups — three of your projects, one slot each
Each switch is one real mechanism. Watch which drawer each project is handed, and who decided it. The paths under the switches are example values.
The five channels — the only ways memory crosses a project line
| Channel | What it is | Who shares the drawer | On this Mac |
|---|---|---|---|
| 1 · Same repository | The default. Every subfolder and worktree of one git repo is handed the repo's drawer. | All windows opened anywhere inside that repo. | Probed: a window opened in strategy seat/reference/ was handed the strategy seat drawer. All seven folders under ~/Projects are their own repos; ~/Projects itself is not. |
| 2 · autoMemoryDirectory | A settings key that points a window at any folder. Set in one project = that project's own drawer wherever it sits. Set at user scope = one drawer for every window on the Mac. | Whoever shares the setting — one project, or the whole machine. | Probed: a window launched with it named the new path and the folder was created at launch. Not set anywhere today. |
| 3 · A second machine floor | CLAUDE_CONFIG_DIR runs Claude Code on a separate floor — its own settings, plugins, memory, transcripts — like a second account. CLAUDE_CODE_PROJECT_DIR_NAME beside it lands every launch on that floor in one named drawer (v2.1.234+). | Every launch under that floor, whatever repo it starts in. | Not used. A fleet tool — a way to give headless seats (keepers, message courier, the box) a floor of their own with one shared memory. |
| 4 · A helper's own notebook | memory: user | project | local in a helper file. The helper is born with its own index (same 200-line / 25 KB rule) and gets Read/Write/Edit for it. user → ~/.claude/agent-memory/<name>/ across all projects; project → inside the repo, committed; local → inside the repo, not committed. | That helper only. Window and helper never see each other's drawer. | One helper declares it (domain-researcher, memory: user); its directory has never been created — never used. |
| 5 · What does not cross | Additional directories bring no memory (this window edits four other folders; its drawer is still the strategy seat's). A dispatched helper is born without the parent's memory — a fork is the exception, it copies the parent. The memory files themselves never load at start — only the index, 200 lines / 25 KB. | Nobody. | Measured this week: a child inherited the parent's rendered rulebook block, not its drawer. |
The rulebook,
split into files
A rule is not a new kind of thing. It is a page of the rulebook kept as its own file — .claude/rules/<topic>.md, one topic per file — and loaded exactly like .claude/CLAUDE.md. None existed on this Mac when this page was first written. ⭐ That changed 2026-09-01: ~/Projects/study-project/.claude/rules/claude-code.md is a live always-on rule file. And it carries a measured finding of its own — an HTML comment inside a rule file does not reach the session it governs (19 lines on disk, 16 injected; the missing 3 were a comment block).
Two kinds of rule, two homes
A rule file with no paths: line is always-on: it loads at launch with the same priority as the project rulebook. A rule file that opens with paths: is path-scoped: it stays out of the window until Claude reads a file that matches, then arrives. Both were tested here this week with planted markers. The home decides who gets it: the machine floor reaches every project; a project folder reaches that launch folder.
Four things that look alike — told apart
Loads: every launch, in full (up to 4 MiB).
Reach: the folder you open plus every folder above it — stacks.
For: standing instructions.
Loads: every launch — or only when a matching file is read.
Reach: machine floor or launch folder. Same layer as CLAUDE.md, one topic per file.
For: a big rulebook kept in pages; rules that should cost nothing until they apply.
Loads: the listing at launch; the body only when invoked or judged relevant.
Reach: per its home; fenced all-or-nothing by the Skill tool.
For: a procedure, run on demand.
Loads: the index only (200 lines / 25 KB); a memory file on demand.
Reach: one drawer per git repository — never stacks.
For: what Claude learned from you.
What one would look like — an example, not on disk
--- paths: - "reference/records/**" --- # Records - Every record carries its date in the filename and a `class:` line at the top. - A count stated in a record is produced by a command, never recalled. - A record that names a live artifact's version is updated in the same act as the artifact.
Because of the paths: line this would cost the window nothing at launch and arrive only when a record is opened. The same three lines without paths: would load every time, like a page of CLAUDE.md.
A path-scoped rule — where it takes effect, step by step
The rule does not follow the file around. It belongs to a launch folder, watches for a pattern, and lands in the window that reads a matching file — from that moment, for that session.
Sharp edges the vendor documents (added 8/28)
How it could be used on your floor — five candidates, not decisions
Each row is a real folder on this Mac and a rule the floor already carries somewhere always-on. Behind a paths: line it would cost nothing until that kind of file is touched.
| Pattern | What the rule would say | Trips when | Today it lives |
|---|---|---|---|
| reference/records/** | A record carries its date in the filename and a class: line; a count in a record is produced by a command; a record naming a live artifact's version is updated in the same act. | Any record is read. | Always-on, in strategy seat/CLAUDE.md's reliability pass. |
| reference/decisions-ledger.md | The ledger is provenance, not governance: a STANDING row names its standing home or is marked provenance only; file in the same act the ruling lands. | The ledger is opened. | Always-on, in strategy seat/CLAUDE.md (the ⭐⭐ standing-home rule). |
| tools/launch/** | A standing seat rotates by pointer, never a composed boot; the launcher carries the rotation gate; a launcher is not charter-class and is not graded. | A launcher is read or written. | A memory card plus the roadmap's class row. |
| .claude/agents/** | A YAML comment containing --- before hooks: ends the front matter and kills the helper's hooks; verify a helper's hooks by the fire log, never by reading the file. | A helper file is touched. | A memory card (the 8/26 scar). |
| clients/<name>/** | That engagement's privacy dial — the one place HIPAA-class or "never store" material would be walled, per client, as you ruled 8/26. Every other engagement stays default-open. | That client's files are touched. | Nowhere yet — the per-engagement dial has no home. |
Where does a rule go — the decision, in order
Three verbs that get mixed up — and the instrument for each
Every part,
every place
Rows are kinds of moving part. Columns are places. Click any cell for its evidence. Solid green was verified on this machine this week; outlined green is a standard mechanism not exercised here; amber is untested or inconclusive. Five cells that were amber yesterday were tested today.
The scaffolding — click any file to see what it is and what's in it
The real folders on this Mac, with the real contents of the files that matter (structure only where a file holds secrets). Each node names which layer it belongs to.
The matrix — every part, every place
The direction rules — same tree, different answers
Flip one thing.
See what it moves.
Four control panels, one per layer, in layer order — floor, folder, helper, launch. The window below them is reassembled every time you click. The strip under its title says exactly what your last click added and removed. Locked controls tell you which layer actually holds that lever.
Every mechanism,
by purpose
The pages before this one mapped what a window knows and can do. This page adds the layer you named as missing — evaluation, guardrails, verification, observation — and puts every mechanism in one table by the job it does, where it lives, what it costs, and whether it is a request or an enforcement. Sources: the vendor's own pages, read today, plus this manual's measurements.
The nine jobs — vendor names first, one card each, click to see a real example
Everything that shapes a window does one of nine jobs. Each card says what the job is in the vendor's words, where it lives, when it fires, and whether this floor uses it today. The one-word nicknames are ours — memory aids, marked as such.
| Category | Tokens | Percentage | | System prompt | 4.4k | 0.4% | | System tools | 1.7k | 0.2% | | MCP tools (deferred) | 115.5k | 11.6% | ← names only; schemas load on search | System tools (deferred) | 13.3k | 1.3% | | Custom agents | 16k | 1.6% | | Memory files | 44k | 4.4% | ← CLAUDE.md stack + MEMORY.md | Skills | 8k | 0.8% | | Messages | 4.9k | 0.5% | Tokens: 79k / 1m (8%)
claude_ai_Notion 37 tools 42.4k claude_ai_Gmail 29 tools 21.0k github 45 tools 19.2k brave-search 8 tools 13.1k workspace-mcp 22 tools 13.0k playwright 24 tools 6.5k TOTAL 165 tools 115.3k — all deferred; loaded only when searched
--- name: home-lead model: sonnet tools: Read, Write ← no Skill (no listing), no Agent (no roster), no MCP tool hooks: Stop: [ stop-hook.sh ] ← travels with it ---
PreToolUse hook knowledge-home-guard.py → DENIES any write into ~/Projects/knowledge-base (exercised at every boot) permissions.deny one rule in ~/.claude/settings.json sandbox.enabled false (the strongest wall, unused)
/goal all tests in test/auth pass and the lint step is clean — or stop after 20 turns
"Stop": [ { "hooks": [ { "type": "prompt",
"prompt": "Check if all tasks are complete. If not, respond with {\"ok\": false, \"reason\": \"what remains\"}." } ] } ]
"Stop": [ { "hooks": [ { "type": "command", "command": "~/.claude/hooks/stop-hook.sh" } ] } ] ← yours todayexport CLAUDE_CODE_ENABLE_TELEMETRY=1
export OTEL_METRICS_EXPORTER=console # or otlp / prometheus
export OTEL_LOGS_EXPORTER=console
claude
# → claude_code.token.usage{type=input|output|cacheRead…} claude_code.cost.usage claude_code.tool_decision{decision=accept|reject}dispatch Agent(subagent_type: gap-checker, prompt: "grade this artifact…") ← fresh context, returns a file
fork /subtask "verify the three numbers above" ← copies the conversation
workflow parallel(findings.map(f => agent("verify " + f.title))) ← many children, fixed pattern
schedule /loop 20m /check-deploy · /schedule "every weekday 6am, run the brief"~/Projects/strategy-seat/tools/lab/example-marketplace/ ← a marketplace (address book)
.claude-plugin/marketplace.json name: re-lab · plugins: [ real-estate ]
real-estate/ ← the plugin
.claude-plugin/plugin.json skills/ (2) agents/ (2) hooks/hooks.json .mcp.json (comps-db)
$ claude plugin marketplace add ~/Projects/strategy-seat/tools/lab/example-marketplace
$ claude plugin install real-estate@re-lab --scope local → .claude/settings.local.json: enabledPluginsAll nine, as a reference table — knowledge split into its four homes
| Purpose | Mechanism | Where · when | Request or enforcement |
|---|---|---|---|
| Knowledge · always | CLAUDE.md — managed, user, project, local | the floor, the folder and its ancestors · at launch; a subfolder's own CLAUDE.md only when files there are read | request |
| Knowledge · by topic | .claude/rules/*.md (and ~/.claude/rules/) | project / user · unscoped: at launch · with paths: — on the first matching read | request |
| Knowledge · on demand | Skills | floor · project · plugin · bundled · one line each at launch; the body when used; disable-model-invocation = nothing until you type it | request |
| Knowledge · remembered | Auto memory; a helper's own memory: directory | the cabinet, one drawer per git repo; agent-memory/<name>/ at user, project or local scope · the index at launch (200 lines / 25 KB); files on demand | request |
| Capability | Built-in tools · MCP servers · code intelligence (LSP) | tools: the harness · MCP: ~/.claude.json machine-wide or per-folder, .mcp.json, a helper's mcpServers:, --mcp-config · names at launch, schemas deferred | fenced per item by the helper's tools line |
| Identity | Helper files — tools, model, effort, permissionMode, maxTurns, skills, mcpServers, hooks, memory, isolation, background | managed › --agents › project › floor › plugin (that is the order on a name clash) · launched or dispatched | the tools line enforces; the rest adds |
| Enforcement | Hooks (five kinds: command · prompt · agent · HTTP · MCP call) · permission rules and modes · the Bash sandbox (the OS fences files and network for every command and its children) | settings at any scope, a helper file, --settings, a plugin · on the event / on the call / on every Bash | enforcement — the vendor: "a request, not a guarantee" vs "a PreToolUse hook that blocks the edit is enforcement" |
| Verification | A check Claude runs itself → an automatic judge at the exit — a model that reads the transcript (/goal, a prompt Stop hook) or a script that inspects the work (a command Stop hook) → a fresh-context reviewer | the prompt · settings (/goal is a session-scoped prompt Stop hook) · a helper file · a subagent · per turn · at Stop · on demand | three rungs, cut by WHO judges — your floor's seat Stop check is the script type of rung two; the gap-checker is rung three |
| Evaluation | claude plugin eval: cases in evals/, graders, a no-plugin baseline arm and the score delta; the skill-creator's trigger eval | beside the thing it measures — <plugin>/evals/, <skill>/evals/ · on demand, by command | measurement — the numbers, the costs and the defect live in Evals, section 13 |
| Observation | OpenTelemetry (CLAUDE_CODE_ENABLE_TELEMETRY=1): tokens, cost, sessions, tool decisions, API calls — attributed by agent, skill, plugin and server; content redacted by default · in-session /context /usage /insights /doctor · the InstructionsLoaded hook | environment / managed settings; hooks · continuous once on | measurement — not enabled here |
| Orchestration | Subagents (a fork inherits the conversation) · dynamic workflows · agent teams (off) · cross-session messages · /loop and scheduled tasks · /batch · worktrees · headless -p | the Agent tool, skills, launch flags · on demand | — |
| Packaging | Plugins — manifest fields skills · commands · agents · hooks · mcpServers · lspServers · outputStyles · userConfig — and marketplaces | the cache + a switch at user / project / local scope; or carried in at launch · at launch, per scope | packaging |
The vendor's own build order — quoted, not invented
What this research corrected on the pages before it
A driving test
for a tool
An eval grades the tool, never a piece of work — that is a different machine, and you already own it. This page is the whole eval side: what exists, what it costs, and what happened when a session stopped believing the question was closed. Measured 31 Aug – 1 Sep 2026, CLI 2.1.251.
Start here — two questions, one word
Asked once, about one thing just produced. Answered by a judge at the exit, or by a fresh reader who did not do the work. You are fully built here: the seat Stop check is the judge, gap-checker is the fresh reader.
Asked about the tool itself, with fixed cases, run repeatedly. Answered by a score — or better, by the difference between two scores. Neither of your existing machines has an opinion about whether a skill is worth having.
That gap is what evals fill. Keeping the two apart is most of the topic.
The three machines — the whole inventory, there is no fourth
Why a delta, not a score
A score alone cannot tell you the tool did anything
A skill that scores 8 out of 10 tells you nothing on its own, because you do not know what the same ten cases score with the skill switched off. If the answer is also 8, the skill is decoration. That is what the baseline arm is for — the same cases, run twice, once without. It is the write-vs-grade instinct pointed at a tool instead of a document.
⛔ The defect — the open machine under-reports, and it looks like a bad description
What was run: the same rigged-to-pass control twice in one fresh folder, changing only how many test runs go at once.
| Positive control — two queries that name the skill outright | Workers | Timeout | Result |
|---|---|---|---|
| Control, serialized | 1 | 180s | 2 / 2 triggered |
| Identical control | 4 | 90s | 0 / 2 |
| Identical control | 4 | 300s | 0 / 2 — so: not the clock |
| Six-query set, 3 runs each not part of the contrast | 12 | — | 0 / 18 fires — ⚠️ no serial control was run: different queries, different worker count, nothing rigged-to-pass in the same configuration. The evidence file excludes it; it sits here only as the observation that produced the scoreboard lesson above. |
t+2s command files present: 4
net-sheet-skill-259a47e4.md
net-sheet-skill-b95fcf52.md
net-sheet-skill-c3666a31.md
net-sheet-skill-d748d95b.md
↑ same description · four names · each worker counts only its own
illustrative names. the SCHEME is read from the script's source; these four
strings are not a captured poll. real, and a genuine hazard — but NOT what
caused the zeros.$ bash reference/claude-code/repro-eval-worker-defect.sh Both queries name the skill outright. Every run SHOULD trigger. WARNING: this contrast has been observed to INVERT (serial fail / parallel pass) on an instrumented copy, 2026-09-01. Treat a single result as provisional. The published cause is THREE compounding bugs -- see section 8 of evals-measured-2026-08-31.md. --- serialized (--num-workers 1) --- Results: 2/2 passed --- parallel (--num-workers 4) --- Results: 0/2 passed
Running a real one — and what it costs
The tool writes your first case for you and refuses to do it outside a plugin folder — a guardrail, not an obstacle. Cases live beside the plugin at evals/<case>/prompt.md with graders/*.md; results and an HTML report land under evals/results/<timestamp>/. The no-plugin arm runs by default whenever a plugin resolves — --ablation none turns it off. Six grader kinds ship: regex (match the text) · tool_used · file_exists · tool_order · llm (a model's verdict) · baseline. One case was run both ways, three times each:
| Grader | With plugin | Without | Did it measure anything? |
|---|---|---|---|
| Model judge | passed 1 of 3 | passed 0 of 3 | Yes — the entire delta, and a weak one |
| Text match | 3 of 3 | 3 of 3 | No — matched in all six runs |
| Did the skill fire | 3 of 3 | — | Indicator, not points |
$0.06 for a trivial case with a mechanical grader. $0.61 for a realistic one run both ways at the default three runs. ⇒ a twenty-case suite is on the order of $12 per full pass (arithmetic from measured points, not itself measured — an earlier version got this multiplication wrong by 4×).
The four settings a working suite needs — and what each one silently does when it is missing
Everything above this line was measured on a suite that had a bug in it. A later session built a suite from nothing — a skill, a case that should fire, a case that should not — and found that three graders out of three were faulty, each in a different way. None of them announced it. Each one reported a number. The four settings below are the difference between a suite that measures something and a suite that reports confidently on nothing.
| Setting | What it does | What happens without it |
|---|---|---|
| arm: both | Runs the grader in the without-tool arm as well as the with-tool arm. | The grader scores nothing. A grader on Skill defaults to with-only, because a skill cannot fire in an arm where it does not exist. It is not silent — the tool prints [with-only, not scored] — but it is easy to read past, and the suite still shows a healthy number beside it. |
| min: 0, max: 0 | Scores a grader as correct when the thing did not happen. | You cannot express "this must not fire". Every grader reads bigger-is-better, so the case that proves your tool stays quiet has no way to pass. |
| timeout_seconds | How long a run may take before it is cut off. | ⛔ An under-set timeout reads as a score of 0, not as a timeout. The tool's own guide warns about this. A whole class of false failure that looks exactly like a bad answer. |
| the negative case | A case the tool should not change, run alongside the ones it should. | Nothing tells you the tool is over-firing. A suite of only positive cases can only ever deliver good news. |
How much the number wobbles — measured on purpose, and it is worse than it looks
The page above retires +0.17 because of this measurement. Here is the measurement itself: three identical batches — same case, same graders, same settings, nothing changed between them — scored +0.67 / +1.00 / +1.00. A spread of 0.33, a third of the whole scale, and the entire spread traces to two grader outcomes out of thirty-six.
How the finding was reached — two of these steps were being wrong
Order matters: each step only makes sense after the one before it. The wrongness is the instructive part.
What is yours to decide — nothing here needs an answer today
The gate is a per-organization rollout flag with an environment-variable override. Setting it for a single command opens it — no restart, nothing persisted:
$ CLAUDE_CODE_WALNUT_SPIRE=1 claude plugin eval --help
⚠️ Where that name comes from matters: it was read out of a compiled-in string in the CLI binary, not from published documentation — slightly less than a documented feature. A real case then ran clean for six cents. To set it permanently there is reference/claude-code/enable-plugin-eval.sh — ⚠️ that settings route is BINARY-sourced and was never RUN; only the per-command form above is measured. What none of this does is write your cases — that thinking is the actual work either way.
This is the part that runs today, and the floor has a standing complaint it fits exactly: skills that under-trigger. A trigger eval turns "it doesn't seem to fire" into a number you can move — provided it runs serialized.
When claude plugin eval does open, its HTML report publishes to claude.ai automatically wherever the account supports it. --no-publish is the opt-out. An eval report is an outward-facing artifact unless you say otherwise.
Sourcing — and one correction about method
⭐ Where the vendor's own words are — and the retrieval trap on this exact subject
Lookup
| Term | What it means here |
|---|---|
| delta | The difference between the with-tool score and the without-tool score. The whole point of an eval: a bare score cannot tell you the tool did anything, because you do not know what the same cases score without it. |
| eval | A driving test for a tool. Fixed cases, run with and without the thing, scored on the difference. Grades the tool, never a single piece of work. |
| case | One test prompt, plus what a good answer has to contain. |
| grader | The thing that scores one case. Six kinds ship: text match, which tool got used, whether a file appeared, a model's judgement, the order tools ran in, and the baseline. |
| baseline arm · ablation | The same cases run again with the tool switched off, so the result is a difference rather than a bare score. |
| trigger eval | The narrow test: does the skill fire on the right prompts and stay quiet on the wrong ones. Tests the description. |
| positive control | A case rigged so it cannot fail. When it fails anyway, the result you were about to report is void — either the equipment is broken or a setting is wrong. Run it in the same configuration you intend to report from, or it proves nothing. |
| false negative | A test reporting failure for something that actually worked. The defect on this page produces these — which is what makes it dangerous: it looks like ordinary bad news. |
| arm | One side of the comparison — with the tool, or without it. A grader set to both is scored on each side; left alone, some graders only run on the with-side and quietly contribute nothing to the difference. |
| negative case | A test the tool should not change. Success is a delta of zero. It is the half of a suite that can deliver bad news. |
| repeatability | How much the same test moves when you run it again with nothing changed. Measured here at 0.33 on a 0–1 scale. Any finding smaller than the wobble is not a finding. |
| leave-one-out | The check that costs no arithmetic: drop each run in turn and see whether the answer survives. If it moves, you measured noise. |
| worker | One of several copies of a test running at once to finish sooner. The count is a flag; here it changes the answer. |
What stops an act —
as opposed to what asks
Instructions ask. Three mechanisms stop: a hook, a permission rule, and the sandbox. They sit in that order, each stronger than the last, and a fenced tools line sits in front of all three. here: sign on the door · doorman · locked door · wall
Three arrays in any settings file: allow, ask, deny. Each entry is a tool pattern: Bash(git *), Edit(src/**), Read(~/.env), WebFetch(domain:example.com), mcp__workspace-mcp__send_gmail_message. Precedence: deny > ask > allow — a deny anywhere blocks regardless. Lists merge across scopes (user + project + local + --settings); a single-valued setting does not.
"permissions": {
"allow": [ "Bash(git status *)", "Read(**)" ],
"ask": [ "Bash(git push *)" ],
"deny": [ "Edit(~/Projects/knowledge-base/**)", "mcp__workspace-mcp__send_gmail_message" ],
"defaultMode": "acceptEdits"
}Set with --permission-mode <mode>, defaultMode in settings, or cycle live with Shift+Tab. Six modes; claude --help on this Mac (30 Aug, CLI 2.1.251) lists them as acceptEdits · auto · bypassPermissions · manual · dontAsk · plan — default and manual are the same mode. Definitions from the vendor's permission-modes page.
The operating system itself fencing what a command may touch: which files, which network. Every Bash call and its children run inside it. sandbox.enabled: true in settings, or /sandbox to toggle; macOS, Linux, WSL. Off on this Mac. The vendor's own line: hooks are deterministic where CLAUDE.md is advisory; the sandbox lets the OS enforce which files and domains a command may touch.
Hooks as walls: several moments can refuse, each its own thing — only PreToolUse can stop a tool call before it runs (permissionDecision: deny); Stop refuses an exit; PreCompact refuses a compaction (the vendor's can-block table, and the binary carries the string). When several hooks match, the most restrictive answer wins — deny, defer, ask, allow. And a hook does not bypass the rules: deny and ask rules are evaluated whatever a PreToolUse hook returns, while a blocking hook beats an allow rule (vendor doc).
Try it — pick an act, set the walls, watch which one catches it
The order is real: the agent's tools line first (if the tool is not held, nothing else is consulted), then any PreToolUse hook, then the permission rules and mode, then the sandbox under every command.
Five moments.
Launch · turn · dispatch · compaction · stop
The third question. Everything on the earlier pages enters a window at one of five moments — and some things leave at one of them. Click a moment.
Why the moment matters more than the place
The window squeezes itself.
What survives is decided by files.
A window's context fills — every message, every file read, every tool result. When it nears the limit, Claude Code compacts: it folds the conversation into a summary and continues from that. Auto-compact is on by default and needs nobody present. The whole question is what comes back after the cut, and the answer is: whatever a file re-supplies.
Try it — fill a window, watch it cut
- L1·L2The root CLAUDE.md stack and unscoped rules — re-read from disk
- L2Auto memory — the index, first 200 lines / 25 KB
- L2The plan written in plan mode — re-injected from disk (vendor doc)
- L1The system prompt — untouched
- turnFiles recently read or edited — up to 5 re-read, most recent first (vendor doc)
- turnInvoked skill bodies — re-injected, capped ~5k each / 25k total (vendor doc)
- L3Hooks, tools, the agent's identity — never in the conversation, so never cut
- goneThe conversation itself — folded into the summary; older tool outputs are cleared first, summarization only if that is not enough
- gonePath-scoped rules and nested CLAUDE.md — until a matching file is read again; the rules matching the up-to-five re-read files reload on their own (vendor doc)
- goneAnything a hook injected (a SessionStart briefing) — unless a SessionStart hook also matches compact
- goneInstructions given only in conversation — the ones that "die"
The levers — vendor names, this Mac's values (30 Aug)
| Lever | What it does | Here |
|---|---|---|
| autoCompactEnabled | the on/off switch (settings); DISABLE_AUTO_COMPACT=1 overrides it; /compact always stays available | on (default) |
| /autocompact <n> | sets the window size — how full it gets before the cut — and saves it as autoCompactWindow; range 100k–1M; forms 500k, 200000 | not set → the model's limit |
| --autocompact <auto|tokens> | the same, for one launch | — |
| CLAUDE_CODE_AUTO_COMPACT_WINDOW | env var; takes precedence over all three; plain integer only — 500k reads as 500 and clamps to the 100K minimum (vendor doc) | not set |
| CLAUDE_AUTOCOMPACT_PCT_OVERRIDE | percentage (1–100) of the window at which the cut fires; only lowers the trigger; applies to subagents too. "Come back at 400k, but 10% before" = window 400k + override 90 | not set |
| /compact [focus] | cut now; the focus text steers what the summary keeps. A # Compact instructions section in CLAUDE.md does the same standing | used — this window compacted on 28 Aug with a focus on your learning goal |
| PreCompact · PostCompact hooks | matcher manual | auto. PreCompact fires knowing the cut is coming and can refuse it (the binary carries "Compaction blocked by PreCompact hook"); PostCompact receives the summary | the floor's precompact-snapshot.sh records machine truth at the cut |
Three things measured on 27 Aug that the docs only imply
A chat is a file.
The window is what you do to it.
Everything the earlier pages assemble lands in one running session. This page is the part that happens inside it — what a session is, where it is stored, how to find it again, the commands you type at the prompt, and how to get out of a screen you did not mean to open. Folded from Part I (the chats manual) plus the vendor's interactive-mode and commands pages, 30 Aug.
What a session is — four facts
The launch and resume commands — click one to see what it does
Find an old chat in three steps: cd into the folder it happened in, then claude --resume · don't know the folder? ls -lt ~/.claude/projects/*/ lists every session across every folder, newest first · once you have the id, claude --resume <id> works from anywhere. Name a session as you start it (claude -n "fridge inventory") or later (/rename) and resume it by name.
Getting out — the keys that close things
The /memory trap of 28 Aug: you opened a CLAUDE.md in the viewer, pressed Ctrl-C, and stayed stuck. The vendor's interactive-mode page settles it:
The commands you will actually type — the vendor's table, curated
| Command | What it does | Page here |
|---|---|---|
| /context [all] | what loaded, by category — CLAUDE.md stack, memory, skills, agents, MCP tools — as a grid with token counts. The one instrument that answers "why is this window heavy" | The Nine Jobs |
| /compact [focus] | fold the conversation into a summary now; the focus text steers what is kept | Compaction |
| /autocompact [auto|tokens] | set how full the window gets before an automatic cut | Compaction |
| /clear [name] | start a new conversation with empty context — the files, memory and tools reload; the chat does not. Stop hooks fire on it | When Things Arrive |
| /memory | open the CLAUDE.md files and auto memory in a viewer; toggle auto memory on or off. Esc closes it | Memory |
| /rewind | rewind the conversation and/or the code to an earlier checkpoint (also Esc Esc on an empty prompt) | — |
| /resume [id|name] · /rename · /clear name | the session picker from inside a session; name the current one; start a named one | this page |
| /model · /effort · /fast | switch the model, the effort level, fast mode | — |
| /goal [condition|clear] | keep working until a condition the transcript can show is met | The Nine Jobs · Verification |
| /permissions · /sandbox · /hooks | manage allow/ask/deny rules · toggle the sandbox · view hook configuration | Walls · Hooks |
| /plugin · /reload-plugins · /skills · /agents · /mcp | the plugin manager (Discover / Installed / Marketplaces / Errors) · apply plugin changes without restart · list skills · agents reminder · MCP connections and OAuth | Plugins · Skills · Subagents |
| /usage (/cost, /stats) · /insights · /doctor | session cost and plan limits · an HTML report over recent sessions · a setup checkup (unused plugins, CLAUDE.md trims, slow hooks) | The Nine Jobs · Observability |
| /background · /tasks · /fork · /subtask · /loop · /schedule | detach this session · see background work · copy the conversation into a child · run a prompt on an interval · routines on a schedule | The Nine Jobs · Orchestration |
| /add-dir · /cd | give this session another folder (direction rule 7) · move the session to a different working directory, conversation intact | Core Idea |
| /desktop · /remote-control · /export · /exit | continue in the Desktop app · share with the phone · export the conversation as text · leave | this page |
Headless, and the flags that change a launch
Accounts — the reason this page has a new address
The folder holds the knowledge.
The plugin does the work.
Your own picture, in the vendor's words: a project (CLAUDE.md, rules, auto memory, the case files) with a plugin switched on for it (subagents, skills, hooks, MCP servers), the plugin sourced from one versioned folder you can switch on in any other project. This page is your architecture-in-progress — the distinction, the avenues, and what the machine measured about each. These measurements change the weight of three of the objections; the choice is still yours — no recommendation is drawn.
The case is unique and accumulates. The procedure is stable and repeats.
The case: one listing, one buyer, one refrigerator — an address or a name; correspondence, documents, decisions, history. It never repeats. The procedure: the work performed on a case — run the comps, build the net sheet, take the inventory. Templated, reused, maintained once. Your instinct: they must not live in the same place. The manual's one sentence agrees with you: the folder decides what a window knows; the agent — here, the plugin's agent — decides what it can do.
The picture, with the four measured facts drawn onto it
What the machine said about your hypothesis — measured 30 Aug
The four avenues — named, with the honest case for and against each
| Avenue | For | Against — and what changed on 30 Aug |
|---|---|---|
| everything at user scope | one place to maintain; nothing to dispatch; results land where the state already lives | every window pays the kit's cost — about 500 tokens at launch for the sample kit, MCP schemas deferred (measured 30 Aug); whether that is small is yours to weigh. |
| dedicated workflow folders | clean separation; each procedure's environment is exactly what it needs | the sprawl you rejected: N folders to keep in sync, case state serialized across, and the folder's CLAUDE.md does not load just because it was pointed at (direction rule 7 needs the opt-in variable). |
| plugins installed at user or project scope | one versioned folder per procedure; the MCP server ships inside; switch on per project with one line — your fridge picture | the refine loop needs a version bump + update, not a save; the kit carries no memory; per-project scope binds the launch folder only (a subfolder launch does not inherit). |
| plugins carried per run with --plugin-dir | case windows stay bare; the kit arrives only where launched and dies at close; loads from the folder you name, so edits are live | nothing is installed, so nothing is "always on" in the case folder; the launch line must carry the flag every time (a launcher script solves that); same memory gap. |
| the coordinator pattern — across all four | the case window dispatches several procedures at once and pulls the results back; parallelism is where the modularity earns out, since each dispatched session burns its own context | nothing arbitrates concurrent writes back into the case folder — the open question below |
Still open — yours to answer, in the order the briefing put them
Our pictures,
the vendor's words
Every nickname this manual uses, mapped to the term you will meet in the documentation and everywhere else. When you read outside, translate left-to-right; when you read here, the nickname is only a picture.
| Said here | The vendor's term | What it is, in one line |
|---|---|---|
| a window · a seat | a session (interactive, or headless with -p) | one running Claude Code conversation; a file on disk |
| the machine floor | user scope — ~/.claude/ | settings, agents, memory cabinet and CLAUDE.md that reach every session on this Mac |
| the folder you open | the working directory (project scope, plus its parent directories) | where a session is launched; supplies CLAUDE.md, rules, settings, the memory drawer |
| the rulebook | CLAUDE.md (user · project · .claude/CLAUDE.md · CLAUDE.local.md · managed) | instructions read automatically at launch because of the filename |
| a rule · a page of the rulebook | a rules file — .claude/rules/*.md, optionally with paths: | a CLAUDE.md page kept as its own file; path-scoped ones load on a matching read |
| a helper | an agent / subagent (.claude/agents/*.md, --agent, the Agent tool) | an identity file: tools, model, instructions, and what it carries |
| the roster | the available subagents listed to a session | each agent's name + description, fenced per item by Agent(a, b) |
| recipe vs cook | skill vs subagent | text the window follows itself vs a fresh window born with the instructions |
| outside-service tools · connections | MCP servers and their tools (mcp__server__tool) | declared in ~/.claude.json, .mcp.json, a plugin, or --mcp-config |
| the cabinet · a drawer · a card · the index | auto memory: ~/.claude/projects/<slug>/memory/ · a memory file · MEMORY.md | one directory per git repo; only the index loads at start (200 lines / 25 KB) |
| the switch | enabledPlugins in a settings file (user · project · local) | one true/false line per plugin per scope |
| the kit · the box | a plugin (manifest + skills · agents · hooks · mcpServers · lspServers), found through a marketplace | a versioned folder, installed to a cache or carried with --plugin-dir |
| handed in at launch · the flags | CLI flags: --settings --plugin-dir --mcp-config --append-system-prompt --agents --add-dir | supplied for one run, gone at close |
| an automatic rule · the doorman | a hook (command · prompt · agent · http · mcp_tool types, on ~30 events) | a program at a fixed moment; only PreToolUse can prevent an act |
| a locked door | permission rules (allow · ask · deny) and permission modes | per tool pattern, per scope; deny wins |
| the wall | the sandbox (sandbox.enabled, /sandbox) | the OS fencing files and network under every command |
| a fence · fenced per item / all-or-nothing | the agent's tools: line | tools and MCP tools removed one at a time; the Skill listing present or absent as a set |
| the squeeze · the cut | compaction (auto-compact, /compact) | the conversation folded into a summary; files re-injected |
| a judge at the exit | a Stop hook — /goal is a prompt-based one | runs when a turn ends; can refuse the exit |
| a stranger's eyes · fresh context | a subagent dispatched to review (here: gap-checker) | a different session that did not build the thing grades it |
| told · held · worn · walled · checked · scored · watched · directed · shipped | instructions · tools · agents · enforcement · verification · evaluation · observability · orchestration · packaging | the nine jobs — our one-word memory aids, never the vendor's names |
| a sign on the door | instructions — CLAUDE.md, rules, skills: advisory context | read and followed; nothing enforced |
| a ring · a keeper · the conductor · "this floor" | this firm's names for headless sessions run on a schedule or by an engine — and "this floor" means this whole operation, distinct from the machine floor (user scope) | firm vocabulary, not the vendor's |
Used and unused on this Mac — the takeaway
Agents (34 files at user scope, ✓cmd 30 Aug) · hooks on six events · one deny rule · the script judge at the exit (the seat Stop hook in 32 of 34 agent files) · fresh reviewers · dispatch and workflows · two plugins (monolith, superpowers) · auto memory · a very large CLAUDE.md stack. Added 2026-09-01: /goal (the model judge at the exit) and claude plugin eval — both exercised for the first time, both with their costs measured.
the sandbox · OpenTelemetry · path-scoped rule files · an agent's own memory drawer · defaultEnabled: false · the InstructionsLoaded hook · /autocompact and the PreCompact/SessionStart(compact) pair · project-scope agents and skills.