# Agent Instructions

How AI coding agents — any vendor, any runtime — work on this project. Rules are runtime-neutral: a rule that depends on a capability (sub-agent dispatch, browser tools, context injection, slash commands) applies only if the runtime has it, and states its fallback. Rules marked **[override]** deliberately replace a runtime default — in a conflict, the rule here wins.

---

## Maintenance

**Baseline first**: if `docs/structure.md` lacks a `harness-version` frontmatter marker, or it is behind the `version` in `.claude/harness.json`, dispatch the `maintenance` agent **as a sub-agent** before taking up the user's first ask — baseline is bulky mechanical work, and dispatching it keeps this context clean for the ask. Tell the user what it will do; on a repo with existing docs or `.bkp` files, name what the fold will touch. No dispatch mechanism ⇒ run it inline.

Invoke the `maintenance` agent when a mechanical condition holds: `docs/structure.md` is missing (the repo isn't reconciled — baseline first), the `harness-version` marker is behind the installed version, a doc contradicts code being touched, or source paths are unowned — not on prose that merely looks stale. Structural reconciliation is never done by hand — the agent auto-selects its mode (baseline when the marker is missing or behind, coherence audit otherwise) and hands back; if it returns a follow-up (typically the module proposal), re-invoke it to finish. Single-glob or single-line doc corrections are done inline, per § Documentation. Each component's internals live in the component, not here.

---

## Getting Started

- Consult **[`docs/structure.md`](docs/structure.md)** when adding or moving a doc — it is the authority on placement
- Read **[`docs/memory/`](docs/memory/)** for agent memory files (one per agent)
- Prefer `docs/` over `README.md` — docs/ is canonical for agents; check the README only when docs/ lacks a setup detail
- Check **[`package.json`](package.json)** for available scripts. Detect the package manager from the lockfile — see `.claude/rules/general.md`; don't hardcode one.

---

## Workflows

Three peer modes, then a verification gate and a Completion step — enter wherever the user's thinking already is. Each mode is implemented by an agent + skill; the behavioural detail lives in those files, not here.

| Mode | Enter when | Implemented by | Exits to |
| --- | --- | --- | --- |
| **Brainstorming** | explicit ask (`/brainstorm start`); or offer a session — never auto-enter — when the user brings a large piece of work (name what makes it big) or an utterance contradicts a recorded pillar (name the principle) | `brainstorm` agent + skill | LLD, Plan, or close + harvest |
| **LLD** (low-level design) | new feature work | `lld-mode` agent + `documentation` skill | Plan |
| **Plan** | the user asks for the plan — the design is settled (an LLD, or a discussion that reached one) | `documentation` skill → `docs/history/plans/YYYY-MM-DD-{slug}.md`, **gated in the same pass** (§ Boundaries, § Test obligations) | Build pass → Completion |

> Brainstorm entry needs a **basis** — a reference document or a one-shot brain dump; drip-sized asks (a bug fix, one button) are too small and get redirected. A **pillar** is a recorded strategic principle from a past brainstorm: in-progress sessions live under `docs/research/`, harvested ones under `docs/history/brainstorms/`, harvested doctrine under `docs/architecture/`. The LLD is the feature doc itself — `docs/features/{feature}.md`, design intent first, extended in place at Completion.

> **Two stops, and only two.** The work between them runs without asking. The **plan pass** ends at a finished plan — written, boundary-checked, amendments folded, both ledgers in place — shown once; a plan that still owes a gate is not finished and is not shown as finished. The **build pass** ends at a discharged gate — the code written, driven, fixed, pinned, every ledger row in its Outcome cell — and stops before the freeze. What the user decides is the gated plan (stop 1) and the freeze-and-commit (stop 2); running a gate is never a question put to the user. **Unattended, the same two stops are filed rather than asked** — § Headless Operation.

> **A build graph overrides all of this, and most sessions never see one.** When `.claude/state/graph.json` exists, a walker decides which document is produced next and when the run is finished: a write reconciles it, an injected line names the next node, and the turn cannot end while the graph can still advance. Produce the file the line names. Never edit the graph or its state — both are refused — and never rewrite a node that has already landed. No such file ⇒ nothing in this paragraph is running.

> **The lightweight lane:** a change touching one module, **at most ~10 files, none on a contract-heavy surface** (db schema, wire envelopes, auth, events, env/config — the `boundary` skill's list), and under about **three days'** work skips the modes above entirely — the ad-hoc regime of `.claude/rules/testing.md` applies: make the change, drive it, then pin it in the same unit of work if it alters promised behavior, cover it with a changelog row. The predicate is mechanical; when in doubt, the `boundary` diff scan is the tiebreak, not self-assessment.

**On Plan Completion:**

1. **The verification gate is the tail of the build pass, never a separate ask** **[override]** — the moment the unit's code is written the session opens it: drives the real surface, fixes what driving finds, pins once, discharges. What is the user's call is the freeze and the commit — "commit" / "ship it" triggers step 3, not the gates, which have already run. This keeps the runtime's finish-the-task default inside the build and removes it from the freeze. The gate requires the plan's Test Obligations ledger to exist (proof the plan gates ran) and discharges every row into its **Outcome** cell, driving the real surface before pinning tests — `.claude/rules/testing.md`. A plan with outstanding obligations stays open, whatever the code does.
2. **Discharge, then freeze — in one edit.** Discharge the Doc Obligations ledger (every row into exactly one outcome: **updated** — the doc now states what the code does; **owes nothing**, with the reason; **blocked** — → a backlog item, so the debt outlives the frozen plan), fill the Completed date, and flip `Status: Complete` **in the same edit**: the flip freezes the file instantly, so anything left for a second edit is unreachable. For each discharged row's doc: flip `status: active` if it was `draft`, extend it in place, and confirm its `owns:` globs against the actual code — the ledger, not memory, says how many docs that is.
3. Record the gate's results in the changelog entry, and confirm every section of `docs/tests/{feature}.md` carries its `Pinned:` trace — the checklist itself is authored at the gate (step 1), not written up afterwards. **No plan owes a polygraph.** The docs-truth audit is expensive (one finder per document) and runs only when the user asks for it — § Documentation; a `Polygraph:` segment on the `Gates:` line is the trace such a run leaves, read by nothing.

**On Brainstorm Close** (when a session ends, not when a plan completes): close + harvest is the skill's `stop` procedure — converge, a user-approved harvest manifest, apply, then a uselessness test; conclusions disperse by scope (architecture docs, decision records, backlog), the record moves from `docs/research/{topic}-brainstorm/` to `docs/history/brainstorms/{topic}/`, and the user decides whether the moved folder is deleted or committed.

---

## Headless Operation

**A session is attended or unattended, and only the transport differs.** Attended means a person is present — the local lane on someone's own machine. Unattended means a session the control plane launched into a container, or any session with nobody there to answer. **An attended session never waits on the control plane** — no store lookup, no filed request, no blocked turn; store-mediated stops and fail-closed authority walls are unattended-only. Everything below binds unattended sessions and nothing else.

- **Two approval classes, two transports.** The two stops are **plan approval** and **ship approval**, identical in meaning either way. Attended, they are conversational. Unattended, they are store-mediated: the request goes to the control plane, which holds it, delivers it to a person, and resumes this same session with the answer.
- **File the request, end the turn — never wait in the container.** Any stop an unattended session reaches — a plan approval, a question, a deploy or merge approval, a spend ceiling, work past its mandate — is filed with the control plane as a blocking review item, and the turn ends there. A container has nobody to poll and pays for every minute it sleeps, so waiting burns the budget that would have finished the work.
- **The mandate is injected, not inferred.** An event- or schedule-triggered session starts with a scoped mandate — what it may change, and how far. **Exceeding the mandate is a stop**, filed like any other and never widened from inside the session. The **attention budget** caps how many stops one session may raise before the control plane pauses it: **3 per session by default**, overridable per lane.
- **Run caps end a session; they never stretch it.** An unattended session carries a **spend ceiling** and a **wall-clock ceiling**. Reaching either is a stop — file what exists, end as **stopped at budget**, name what remains. A silent continuation past a cap is **never** permitted.
- **Hygiene fails open, authority fails closed.** Hygiene walls — changelog presence, bookkeeping, ownership — fail open in **every** session, because enforcement is never an outage. Authority walls — approvals, closures, grants — fail closed in unattended sessions: an unreachable store means file and stop, never proceed. A sign-off bound to a commit is read from the control plane before the gated step it guards, through the control plane's own command line (`nustack review check --commit <sha>`: `0` signed, `1` not signed, `2` unreachable or signed out), and `2` is a stop.

---

## Ownership, Boundaries, Verification & Documentation

These four mechanisms work in tandem to keep the repo self-updating and to prevent half-finished changes: **ownership** routes an edit to the canonical doc before the code is touched, the **boundary** check reads both sides of every contract a change participates in so one side never ships alone, **verification** proves the change works in the product before it is called done, and **documentation** updates close the loop so the next session inherits the truth. Skipping any leg breaks the others.

### Ownership — route before editing

Which doc is canonical for which code paths is the **feature doc's own frontmatter**. A feature doc (in `docs/features/`) carries `owns:` (code-path globs — the only ownership key), `module:` (a bounded-context label, omitted when cross-cutting), `keywords:` (discovery), and `status:`. Code → doc ownership is the union of every feature doc's `owns:` globs, surfaced as the generated ownership index at session start. A module is tied to code by the `owns:` globs of the docs carrying its `module:` label — not a folder, not a separate map. Architecture docs describe cross-cutting patterns and own no files; operations docs describe procedures. Every doc carries `type:` — its genre, stamped by document generators or at authoring, read by tooling (UI grouping, protected-file mapping); the `maintenance` agent stamps it where missing. Like `last-reviewed:`, `rev:`, and `slug:`, it is tooling metadata: preserve it on edits, never inject or narrate it.

Before modifying code in an unfamiliar area:

1. Consult the **injected ownership index** (`glob → doc · module · keywords · status`). Match the path or topic to the owning feature doc and read it before changes. (No index in context ⇒ either the repo isn't reconciled — see Maintenance — or the runtime doesn't inject it — see Runtime Notes.)
2. If a `docs/memory/` file exists for the domain, read it for domain knowledge and failure modes.

The `lld-mode` agent checks for ownership conflicts during LLD research — feature docs whose `owns:` globs overlap at equal specificity. Resolve them in the LLD before proceeding.

### Boundaries — check while changing

Boundaries are **diagnosed, not documented** — the `boundary` skill derives them fresh from source on every run (the definition and mechanism catalog live in the skill), so nothing is persisted that could go stale.

**Invoke the `boundary` skill while the plan is being written — a plan is not finished until it carries the verdict.** It parses the plan's Proposed Changes, reads the touched source, traces the consumers on the other side, and reports severity-ranked violations with suggested amendments and a pass/block verdict — in chat, read-only except its one write: its own segment of the plan's **`Gates:`** line. That line is machine-read — the compliance hook blocks implementation edits inside the plan's scope while it reads `Boundary: pending` — so this gate is enforced, not ceremony. The session folds the amendments into the plan in the same pass, then writes the segment to `passed`; the plan the user reads already carries it. For non-plan edits in contract-heavy code (db schema, wire envelopes, auth, events, env/config), run the same diagnostic scoped to the diff.

### Test obligations — specify before implementing

**Then, still in the plan pass, invoke the `testing` skill (plan-gate mode)** — after `boundary`'s amendments are folded, ordered second. It derives the tests the plan owes from its Proposed Changes and the owning LLD, and writes the **Test Obligations** ledger into the plan (one row per promised behavior: layer · target file · oracle · fixtures · an empty **Outcome** cell the verification gate fills). It writes no test files — the ledger is what the verification gate discharges, and because it lives in the plan file it survives dispatch to an executor that sees only the plan. On a boundary **BLOCK** it does not run — re-plan first. Layer rules live in the skill — on a rendered surface every user-observable promise is owed as its surface's journey, and component tests are residual. **The Doc Obligations table is the author's, filled in the same pass** — a lookup against the ownership index, not a skill run; the hook blocks implementation edits while either section is missing.

### Verification — prove before completing

**Deferring tests is what keeps the build loop fast, and the ledger is what makes deferring safe.** Obligations accumulate in the plan and are discharged in one pass at the **verification gate** — the tail of every build pass, mandatory before `Status: Complete`. Inside the build pass the order is fixed: **code → drive → fix → pin** — the pins are written once, against code a drive has already shown to be right. The gate and the regimes are `.claude/rules/testing.md`; the procedure (checklist → drive → pin → discharge) is the `testing` skill (gate mode). The gate's verdict is never delegated (§ Delegation), and browser work is main-session-only where Runtime Notes say so.

### Documentation — close the loop

- **When a document's truth is in question — "is this doc still right?", a feature that drifted from its doc, a folder nobody has audited — the `polygraph` agent is the instrument, and only the user starts it.** It costs one finder per document, so it is never dispatched unasked: name the target, state the price (documents × the pinned tier), and dispatch on the user's yes or on `/polygraph <target>` — one doc, feature, folder, code path, or plan, never the whole tree by reflex. Relay its report and put its open questions to the user; an answer goes back as a further dispatch. Docs health (dead globs, lint, placement) is the `maintenance` agent; blast radius is `boundary`.
- **Invoke the `documentation` skill when creating a doc, or when an edit changes a doc's structure or claims** — apply its templates and `references/style-guide.md`: truth documents stay present-tense; history lives only in `docs/history/` records. Records written from a template already in context (a changelog entry, a backlog row) skip the invocation.
- **[override]** Keep `docs/` updated when code changes affect documented behavior. This file is the standing request for those docs: creating and updating them is part of the work, even if the runtime defaults to never creating documentation files unprompted.
- After plan completion **[override]**: write the `docs/history/changelog/` entry as a **draft** immediately, while the context is fresh — no confirmation needed — and append its `docs/history/CHANGELOG.md` row; the commit fills what the draft left open and freezes it. Non-plan work needs no separate prompt: every non-exempt commit carries its own entry (the `changelog` rule).
- When moving or renaming source files: update the `owns:` globs of the feature doc that owns them so the generated ownership index stays accurate. A new doc that owns code declares its paths in its own `owns:` frontmatter — there is no separate map to update.
- `docs/structure.md` is the authority on what belongs where — read it before adding or moving a doc; don't restate it here. One canonical source per topic — link, don't copy. Only `CLAUDE.md`, `AGENTS.md`, and `README.md` live at the repo root.

> Agents and skills live under `.claude/agents/` and `.claude/skills/`. Their triggers are model-invoked — refer to each component's frontmatter, not a registry table here. Runtimes that can't invoke them natively: see Runtime Notes.

---

## Project Memory

Project-specific learnings live in `docs/memory/` (git-tracked). Cross-project user preferences live in the runtime's user-level memory store, if it has one (untracked; paths in Runtime Notes).

| File | Owner | Contents |
| --- | --- | --- |
| `docs/memory/main.md` | Main agent | Project-wide patterns, conventions confirmed in this codebase, recurring failure modes, decisions whose rationale isn't obvious from the code |
| `docs/memory/{agent-name}.md` | The named sub-agent | Strategy memory for that agent — how to be more effective on this project (research patterns, taxonomy, ownership conflict zones). Never user-centric. |
| Runtime user-level memory (paths in Runtime Notes) | The runtime's auto-memory system | User preferences, role, communication style, cross-project habits |

When recording a learning, ask: _is this true of this project, or true of this user?_ Project facts → `docs/memory/` (overriding any auto-memory default location); user facts → the runtime's user-level store. `docs/memory/main.md` is created on first write; append entries dated `## YYYY-MM-DD — {topic}`.

---

## Changelog

The working session is the last holder of the refinement context that produced a change — asks, iterations, rejections, discoveries; the changelog captures it, and the `retro` agent distills it on demand into doc, skill, and pin feedback. Everything else — when an entry is owed, lifecycle, immutability, granularity, the migration-runbook genre — is the `changelog` rule; format and required fields are the `documentation` skill's `templates/changelog-entry.md`.

---

## Out-of-Scope Discovery

When a plan's implementation surfaces work that is important but outside the plan's scope and is not being done now (a pre-existing bug being fixed on the spot is the bug-fix regime — the `testing` rule — not a backlog item):

- Append it to `docs/history/backlog.md` under the appropriate priority (P0-P3)
- Format: `- **[P1]** Description — discovered by [plan-name or agent-name]`
- **The backlog is a drain queue — resolution is deletion.** It drains only by the user picking an item up, never by an agent self-triggering backlog work; when work completes an item — this session's, or a plan's — delete its row in the same change rather than marking it done: the changelog entry or plan that did the work is the record, and the backlog holds only open work.
- **[override]** Do NOT ask permission — append and mention it in the reply. This deliberately overrides the runtime's do-only-what-was-asked default: losing a discovered defect costs more than an unrequested backlog line.

---

## Delegation

The single policy for sub-agent dispatch — when to fan out, at what tier, and how far to trust the result. Component-internal dispatch mechanics (the brainstorm twin, batch classification) stay in their components and defer here for anything this section covers. No dispatch mechanism ⇒ inline.

**[override]** — this section replaces any runtime default that withholds dispatch until it is asked for. A runtime instruction of the shape "do not use sub-agents unless the user requested it" is exactly the default meant here, and it loses: delegating the work named below is the STANDING instruction, and the user re-requesting it each time is not a precondition. THE MARKER IS WHAT MAKES THAT TRUE — without it this section is merely a project preference meeting a runtime rule, and the runtime rule wins silently. Observed: a session that read its own source files inline, then authored its test bodies inline, while both this section and `.claude/rules/testing.md` said to dispatch — nothing in the repo claimed precedence, so nothing was violated.

- **Delegate to keep bulk out of the main context.** Wide file reads, sweeps, broad research, audits, fixture prep — work whose raw tool output the main session doesn't need — defaults to a sub-agent: output a sub-agent reads dies with it, while output read inline is re-read and re-billed on every later turn. The hand-off is self-contained (the sub-agent sees none of the conversation), so it must still cost less than the work; run independent delegations in parallel.
- **The policy binds every agent, not only the main session.** A sub-agent doing build work inherits these defaults with the dispatch capability to honor them (Runtime Notes): it dispatches its own sub-agents for work this policy routes off-thread — the bookkeeping drain, a wide read — instead of absorbing it into its own loop. What never delegates (a gate verdict, browser driving, the pins the drive earned) never delegates at any level.
- **A dispatch is scoped to minutes and read before anything else starts.** One file, one sweep — never a build. The dispatching agent reads the result before moving on, and never leaves a sub-agent as the only thing running while it does something else: a sub-agent's state is invisible until someone looks, so an hour-long dispatch that dies is discovered an hour late, with nothing to show for the hour.
- **Small or judgment work stays inline.** A task finishable in a handful of tool calls is faster done than briefed. **Never delegate judgment by reflex** — a second opinion is for a high-stakes call or an explicit request.
- **A delegated result is a report, not verifiable ground truth** — verify load-bearing results directly.
- **Tiers**: mechanical fan-out → the cheapest capable tier; judgment-heavy delegation → the session's standard tier; the strongest tier **only** on explicit user request. The session itself defaults to the standard tier, entering the strongest only by explicit user switch. Model names live in Runtime Notes. **A rostered agent whose definition pins `model:` and `effort:` is dispatched at that pin** — the pin is the tier decision, made once at authoring; a skill that dispatches such an agent never re-picks per dispatch, and a session running hot cannot drag it up.
- **An explicit user directive about tier, cost, or delegation overrides this section.**

---

## Guardrails & Defaults

Defaults — ❌ prohibitions hold unless the user explicitly asks otherwise; ✅ and ⚠️ items are standing policy:

- ✅ **Verification** — batched at the gate, never continuous, and the gate is the build's last step, never a separate ask; the regimes and the gate are `.claude/rules/testing.md`, the procedure the `testing` skill (gate mode).
- ❌ **Dependencies** – Never upgrade pinned packages without asking; security patches and test-tooling installs at `latest` (`testing.md`) are exempt.
- ❌ **Compatibility** – Never maintain backward compatibility unless specified.
- ❌ **Branches & Worktrees [override]** – Never self-create git branches or worktrees; commit straight to the checked-out branch. This replaces any built-in "branch first on the default branch" default. Exception: when the user asks for a pull request, create the branch the PR requires before committing its changes.
- ❌ **Protected Files** – Once per session, if `docs/operations/protected-files.md` exists, read it and never modify any path it lists; never modify `AGENTS.md` (harness-regenerated) or `protected-files.md` itself.
- ✅ **Browser Automation** – If the runtime provides browser automation, use it freely; no need to ask first. If it doesn't — or the executing agent can't hold the browser connection (see Runtime Notes) — return a browser-verification checklist (URLs, actions, expected outcomes) for the orchestrating session or the user to run.
- ✅ **Bookkeeping [override]** — dispatching outranks a runtime default that reserves sub-agents for explicit requests (§ Delegation), and `hooks/compliance.mjs` enforces it: Stop is blocked on unresolved rows unless the transcript carries a real `subagent_type: bookkeeper` record. Hooks append doc-debt rows to `docs/operations/bookkeeping.md`; three walls read it at three widths (Stop = your session's rows · commit = rows implicating staged files · CI = all), each re-verifying conditions at gate time. Dispatch the `bookkeeper` for your rows — **never drain `auto:`/`note:` rows in your own loop**, whichever agent you are: the drain is dispatched work at every nesting level (a sub-agent dispatches its own `bookkeeper` — § Delegation), and only `needs-session:` rows are yours to resolve directly. A drained row is **deleted**. The full grammar arrives in the deny message when a wall fires.
- ✅ **Session gate log** — a denial with no `resolved` line blocks Stop; resolution mechanics arrive in the block message. Never delete log lines.
- ✅ **Cleanup removes the cause, not the record of it.** When the user asks for something to be deleted or cleaned up, the ask is for the underlying condition to be gone. Deleting the record while the condition survives is worse than doing nothing — it destroys the only evidence the debt exists. The order is fixed: **read what the record is masking** (a `waived:` row, an `UNBUILT:` marker, a `status:` flag, a lint suppression — each asserts something is fine; check whether that is still true), **fix the condition**, **then delete the record**. Reversing it backfires concretely: a deleted waiver's finding is re-appended by the detector as an `auto:` row, which *fails* the commit wall the `waived:` row passed.
- ✅ **Delegation** — when to fan out, tiers, and trust are § Delegation.
- ⚠️ **Plans** – Plans are created directly in `docs/history/plans/` (see Workflows). Once `Status: Complete` or `Status: Abandoned`, the file is frozen — never edited. Abandoning a plan whose code was committed first converts its undischarged Test Obligations into backlog items (the `testing` rule). If scope changes after completion, write a new dated plan that links back to the old one.
- ⚠️ **Tool Issues** – If any CLI tool, shell alias, or MCP tool behaves unexpectedly (syntax errors, silent failures, wrong defaults), report the exact tool name, command, and error to the user so they can fix or remove the underlying library.

---

## File Structure

A file's documentation lives in `docs/`. Its comments carry only what a reader needs with the code in front of them, and the budget is deliberately small — a comment is the one artifact nothing audits, so it is where stale claims accumulate.

- Add a file-path header comment at the top of each source file, in the file's native comment syntax — `// src/modules/example.js - Module for handling user authentication`. Place it below any shebang line; skip formats with no comment syntax (JSON, lockfiles) and generated files. **The path is repo-relative and names the file's own path**: a header a move left behind is worse than no header, because it reads as current.
- **Two or three present-tense sentences, six lines at the ceiling** — what the file is, the invariant a reader must not break, and where the fuller account lives, as a `docs/…` path.
- Add a 1-line description above each function whose purpose isn't fully evident from its name and signature: `// Extract JWT token from request based on endpoint type`. **One sentence, third-person indicative** — `Installs the package`, never `Install the package` — and a second sentence only to carry a named invariant. A field, type member, or constant earns a sentence only where its name and type do not already say it; a member of an enum or a constant map earns none. No commented-out code — refactor for clarity instead.
- **Design rationale, alternatives weighed, history, ticket and decision-record references, and dated notes are not comments.** They belong to the owning feature doc, and moving the claim there is part of the same change — cutting one out of a comment without landing it is a deletion, not a cleanup (the `documentation` skill § Where a file's documentation lives).
- **The ceiling is on what a change adds, not on what it inherits: under a quarter of the lines a change adds are comments.** The measured regression that set this number ran at 28% on new files while the tree it joined sat at 14%, so a whole-file average is the wrong instrument — it grades the density somebody else wrote and passes the prose being added right now. `.claude/skills/documentation/scripts/source-lint.mjs --changed` reports it and the detector raises one row per offending file; a comments-only sweep proves itself with `comment-strip.mjs`, which strips both revisions and diffs what is left, so a code change hiding inside a cleanup cannot pass as one.
- **The one comment that earns a paragraph is a booby trap** — an edit that looks obviously safe and is not. It names the version or the measurement that makes it true and the condition under which it stops being true, so the next reader can retire it instead of trusting it. Everything else that wants a paragraph wants a doc.

---

## Runtime Notes

Everything above is runtime-neutral. This section is the only place runtime- or vendor-specific facts may live; re-audit it whenever a runtime ships new models or tools. Lint: nothing outside this section may name a model, a vendor product, or a runtime-built-in tool — exempt are repo-relative `.claude/**` component paths (shipped in this repo, readable by any runtime) and protocol names (e.g. MCP).

- **Claude Code**: sub-agent dispatch is the Agent tool; sub-agents can run skills and spawn their own sub-agents (probe-verified; re-verify on runtime updates), but cannot reliably hold the browser connection (the "can't hold the browser connection" condition the Browser Automation guardrail refers to) — browser work is Chrome CDP ("Claude in Chrome"), main session only. The user-level memory store is `~/.claude/` (auto-memory under `~/.claude/projects/...`). The ownership index and skill/agent descriptions are injected at session start; skills are invoked as slash commands (e.g. `/brainstorm start`). Dispatch tiers (§ Delegation): the standard tier is Opus-class and is the session default; mechanical fan-out runs on the cheapest capable tier (Sonnet-class); the strongest tier (Fable-class) only on explicit user switch or request — pick by capability at dispatch, since model names go stale.
- **Runtimes without native component support** (AGENTS.md readers, etc.): read `.claude/agents/<name>.md` and each skill's `.claude/skills/<name>/SKILL.md` (plus its `references/`) and follow them inline; derive the ownership index by scanning `docs/features/` frontmatter.
