Skip to content
Back to skills

Intake

ASecurity

Mine an external source - a YouTube video, a news roundup, an article, pasted notes, a repository - for what it should change in THIS registry, and in the connected projects that consume it. Ingests the source, reads its design decisions as well as its claims, maps both against existing bundles for prior art, triages with the operator, and lands what survives corroboration - amendments for boundary cases, techniques and subjects for mechanisms, forge handoffs for systems whose architecture th...

  • 2 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added October 19, 2026
researchrustgonodeexpressawsgit

Works with

  • terminal
  • cli

Security analysis

A100/100

Pro scans all 8 files and shows the line behind each finding

Scanned October 19, 2026

npx -y skills add xkazm04/ai-registry --skill intake --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Intake?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Intake
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/xkazm04-intake/badge)](https://www.skillsdirectory.com/skills/xkazm04-intake)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: intake
description: "Mine an external source - a YouTube video, a news roundup, an article, pasted notes, a repository - for what it should change in THIS registry, and in the connected projects that consume it. Ingests the source, reads its design decisions as well as its claims, maps both against existing bundles for prior art, triages with the operator, and lands what survives corroboration - amendments for boundary cases, techniques and subjects for mechanisms, forge handoffs for systems whose architecture the corpus lacks. News sources mostly yield currency signals and leads; that is a successful run. Use when someone shares a link and asks what it means for us."
category: ai-native
memory: project
version: 2.16.0
tags: research, sources, memory-lane, admission-gate, render-proof, triage, currency, cross-repo, leads, apply, ab-test, parallel, reference-index, design-read, forge-handoff, directions, fleet-map, peer-study, opus-workers, decision-gate
---

# Intake

The registry has three content engines. `/forge` creates a bundle from
a repository's ceiling. `deepen` raises one subject above any repository, outward, by
researching a topic we chose. **This one runs inward**: someone hands over a source we
did not choose - usually a mixed AI-news video - and the question is what, if anything,
it changes here.

That inversion is the whole design. `deepen` starts from a subject and goes looking for
truth. `/intake` starts from a claim of unknown quality and has to earn its way to a
subject. Most of the time it does not, and the run is still worth having, because the
thing it produces instead - a dated lead, a clock reset, a dispatch - is what keeps a
corpus from aging silently between sweeps.

Say the next sentence out loud in every session, because the failure mode for a skill
like this is a bundle quietly acquiring a YouTube channel's error rate. **A source
ORIGINATES a finding. It never AUTHORIZES one.**

## Invocation

```
/intake <url|path|->          # the full loop: ingest, map, triage, land
/intake <url> --leads-only    # stop at the vault note; change no published content
/intake <url> --spec-only     # write an XL spec but do not forge it in this session
/intake <url> --domain <d>    # constrain routing to one bundle
/intake status                # read the source ledger, touch nothing
/intake reflect               # update LESSONS.md, SCORECARD.md and this method from recent runs
/intake apply <technique> [--project <slug>] [--mode code|experiment|simulation]
                              # run Phase 7.5 alone against knowledge that already landed
/intake <url> --ask           # restore the pre-2.5 human gate: show the scored table and wait for picks
/intake <url> --no-apply      # land without applying; the reason goes in the scorecard row
/intake <url> --run <id>      # join the run board under a chosen id (default: derived)
/intake <url> --wave          # reference-index source: mine its references in waves, not its top 3
/intake <url> --no-handoff    # keep a design-deep repository in this skill instead of routing it to /forge
/intake <url> --design-only   # stop after the design read: write the design record and the source-tree applications, land no techniques
/intake <url> --delta         # re-scan a repository this registry already mined, at a newer commit; read docs/upstream-brief.md first
/intake <url> --memory        # agent-memory source: read references/memory-lane.md FIRST and triage against the measured ladder before the corpus
/intake board                 # read the run board - who else is live, and what they hold
```

**Version 2.0.0 changed what a repository run is.** Twelve consecutive runs over large
systems (a secrets manager, a dataflow runtime, an agent harness, a medical-imaging
toolkit) produced eleven amendments, six techniques, and zero subjects, specs or
forge dispatches, because every rule below was written for a news video and a
repository was bolted on at Phase 2b. The unit of extraction was a sentence, so
architecture never reached the triage table; prior-art mapping against a thousand
techniques always found a neighbour, so the impact column read `amendment`; the
unattended rule dropped every `partial` row, which is where mechanisms sit; and the
scorecard counted landings without weighing them. Six changes follow, marked **(v2)**
where they appear: route design-deep repositories to `/forge`; read a repository's
*design decisions* as candidates beside its claims; write applications against the
source tree itself; trigger an XL spec mechanically when three design candidates share
one home; execute the promoting question on every `partial` row instead of banking it;
and weigh the scorecard by depth. The old economics still hold for a video.

The pipeline this skill is trying to master, and the five stages every run is scored
on, is **research -> extract -> test -> apply -> ship**. The first two are Phases 2-6.
The last three are Phase 7.5 and Phase 8, and they are not optional: **a technique that
has never been applied to a managed project is a wiki page**, and this registry is not
a wiki. Every technique and every golden-path amendment that lands must relate to at
least one managed project and one seam in its code, and must have been A/B-tested there
- in real code where the tree allows it, as an experiment where it does not, and as a
recorded thought simulation where nothing else is reachable. The mode is graded; the
step is not skippable.

## Never count, never construct, never fetch by hand

Two instruments, both dependency-free, both asserting themselves before they report:

```sh
node scripts/research-ingest.mjs <url|path|-> --json    # source  -> deduped transcript + metadata
node scripts/research-map.mjs "<term>" "<term>" ...     # terms   -> prior art + where a new subject goes
node scripts/run-board.mjs claim|beat|check|lock|list   # this run -> visible to every sibling session
```

`research-ingest` exits **2** when the instrument failed and **3** when the source is
genuinely thin. Those lead to opposite next moves, which is why they are different
codes: a 2 is retried or routed around, a 3 is reported and the run stops.

`research-map` returns each hit's `file` from the bundle index. That string is the
subject's **address**. Bundles are nested and depth is dynamic, so a constructed path
writes a document into a folder no consumer walks - the same rule `deepen` workers and
`librarian` dispatches run on.

Neither of the first two decides anything. They put you in the neighbourhood; you still
open the file. The third decides nothing either - it makes a collision visible before
you cause it. Its exit **3** means CONTENDED, which is an answer and not a failure.

## Running beside a dozen siblings

This skill is now routinely run **a dozen at a time**, one source per terminal, against
one checkout. That is the intended mode, not an abuse of it - the front of the funnel is
the stage the scorecard keeps naming as weakest, and parallel sources are the only cheap
way to feed it. But every one of those sessions is a *writer*: it lands into shared
bundles, appends to shared ledgers, regenerates a shared index whose hash the catalog
covers, and commits on a shared branch. Run naively, twelve of those do not produce
twelve runs' worth of corpus. They produce interleaved appends that lose lines, an index
built over a neighbour's half-written subject, and commits that carry work nobody
reviewed.

Three rules make it safe, and they are worth stating as one idea: **read the board,
write only what you claimed, and take the lock for the few seconds where sharing is
unavoidable.**

**1. Announce yourself before you read anything.** The board is
`$(git rev-parse --git-common-dir)/run-board/` - inside the git common directory, so it
is shared by every worktree of this repo, can never be staged, and needs no `.gitignore`
line. Every run writes exactly one file there and reads all the others; there is no
shared document to append to, because a shared append is the race the board exists to
prevent.

```sh
node scripts/run-board.mjs claim --skill intake --source "<url>" --run <id>
node scripts/run-board.mjs list                      # who else is live, and what they hold
```

`claim` exits **3** if a live sibling is already mining the same source or already holds
a subject you named. Same source is the cheapest waste there is - two terminals paying
twice for one transcript and then racing to write one source note - and it is invisible
without the board because the ledger only learns about a source *after* it is mined.

**2. Claim a subject before you write in it, not after you decide to.** Add every
address you might land in - as soon as Phase 4 names it, not at Phase 7 - and re-check
before the write:

```sh
node scripts/run-board.mjs beat --run <id> --phase 6 --subject <domain/category/subject>
node scripts/run-board.mjs check --run <id> <path> [<path>...]   # exit 3 = a sibling holds it
```

A contended subject is **not** a stop. It is a different job: two runs adding techniques
to one golden path will collide on that file's `techniques:` list even though their
techniques are unrelated, so the second one either waits for the first to commit, or
writes its technique and takes the `content` lock for the golden-path line alone. Say in
the source note which you did.

**3. Serialize the three things that genuinely cannot be shared**, and nothing else,
with a named lock. A lock is an atomic file create with a TTL; it is breakable after 15
minutes, loudly, so a crashed session cannot deadlock the fleet.

| Lock | What it covers | Hold it for |
| --- | --- | --- |
| `index` | `build-index.mjs` + `build-catalog.mjs` + the two checkers | the regeneration, and nothing before it |
| `ledger` | appending to `librarian/sources/index.md`, `librarian/applied.md`, `SCORECARD.md`, `LESSONS.md` | one append |
| `commit` | `git add` + `git commit` + the HEAD verification | one commit |

```sh
node scripts/run-board.mjs lock index --run <id> --wait 600
node scripts/build-index.mjs && node scripts/build-catalog.mjs
node scripts/check-bundles.mjs && node scripts/check-skills.mjs
node scripts/run-board.mjs unlock index --run <id>
```

**Re-read every shared file inside the lock, immediately before appending to it.** A
ledger you read at Phase 1 is eleven runs out of date by Phase 9. This is the single
most common way parallel runs lose content, and it never fails loudly: the append
succeeds, and one line quietly ceases to exist.

Four consequences that follow from the above and are easy to get wrong:

- **Never switch the branch, ever.** A sibling did this on 2026-08-21 and every other
  session's working tree changed under it. If you need isolation, take a worktree
  (`git worktree add <short path> -b <branch>` - keep the path SHORT; the deepest bundle
  paths blow past the platform limit under a scratch prefix). The board follows you
  there for free.
- **Scratch is per run or it is a hazard.** Every clone, transcript and temp file goes
  under `<scratchpad>/<run-id>/`, and Phase 9 deletes *that* directory by name. A blind
  sweep of the scratch root deletes a neighbour's half-swept clone.
- **`git add -A` is a fleet-wide incident, not a local mistake.** With twelve live runs
  it is guaranteed to stage somebody's in-flight file. Stage new files by name, commit
  with a pathspec, verify in `HEAD`.
- **Do not regenerate to be helpful.** If the index is stale for files you do not own,
  that is the owning run's job and it holds the lock. Regenerate only after your own
  content lands, only under the lock, and only once.

Release the claim when the run ends - `release --run <id>` - or leave it to `gc`, which
reaps any record whose heartbeat is more than 45 minutes old. A run that ends without
releasing costs its siblings 45 minutes of unnecessary caution, so release it.

## The six outcomes

Rank a run by which of these it produced honestly, never by document count.

| Outcome | What it is | Where it lands |
| --- | --- | --- |
| **Applied** | Content that was A/B-tested against a managed project's seam and carries a verdict. Outranks Content: it is the only outcome that proves the corpus changes what a project does. | The project (a commit, an experiment record, or a simulation record under `.ai/`), an application document with `applied:` and `ab_verdict:`, and a row in `librarian/applied.md` |
| **Content** | A claim that survived corroboration and the strip test. | `knowledge/`, `skills/`, `practices/`, `memory/`, `scripts/`, `docs/` |
| **Currency** | The world moved under a claim we already publish. | `verified_on` / `refresh_by` on the affected application, or a scoped `/deepen` dispatch |
| **Lead** | Real, unproven, with a stated return condition. | `librarian/sources/<date>-<slug>.md` |
| **Already covered** | The corpus says it, and says it better. | The source note, as a catch |
| **Untriaged** | Extracted, reached the table, never picked. | The source note, in its own table |

**Untriaged is not declined, and the distinction is load-bearing.** A candidate the
operator never chose carries no judgment at all; filing it as a decline poisons the
decline ledger, which the next run reads as "somebody looked at this and said no" and
which Phase 11 promotes into a rule after three sightings. Record untriaged candidates
with their anchors so a later run does not re-derive them, in a table that says plainly
that nobody verified them.

A mixed-news roundup that yields nine already-covered catches, two leads and one clock
reset is a **good run**. Padding it into three half-corroborated techniques is how the
upper layers rot. Report the counts and let them be small.

## Read the source's class before its content

A source's class decides what its claims are *for*, and it is the cheapest prediction
available: it sets the expected yield, where in the source to look, and whether the
fetch budget is optional. **Read the class at Phase 2 and say the expected yield out
loud before the triage table**, so a small number reads as calibration rather than as
failure. Record the reading in the ledger; it is what makes run N+1 cheaper.

The full description of each class - what it is reliable for, where its yield hides,
and the failure it walks into - is [`references/source-classes.md`](references/source-classes.md).
**Read that file once the ingest tells you what arrived.** This table is the routing
index, not a substitute for it.

| Class | The discriminating question | Reliable for |
| --- | --- | --- |
| **second-hand survey** | is this a digest of other people's news? | *that* the world moved, nothing else |
| **first-party practitioner account** | did they build the thing they are describing? | what they did and measured (n=1) |
| ↳ *release walkthrough* | is it organised around one version's changes? | the stated failure modes - seek this out |
| ↳ *dialogue* | are two practitioners comparing their OWN systems? | their disagreements - each one is a discriminator already drawn |
| **second-hand practitioner listicle** | is it relaying vendor docs with some real pain? | where the vendor's rules moved |
| **second-hand practitioner review** | is it a demo of someone else's release? | that it shipped; the fetch carries the rest |
| **vendor release announcement** | is it the vendor's OWN post about its OWN release? | its numbers - the prose is the strip test's problem |
| ↳ *prediction report* | is it about a year that has not happened yet? | its cited measurements only - future tense is unstrippable, so the forecasts yield nothing |
| **practitioner build-walkthrough** | a personal tool they actually use daily? | the operating half only - see below |
| **paper aggregator** | a list of papers? | measurements in their protocol, not frameworks |
| **reference index** | is its VALUE the outbound links rather than its own text? | nothing itself - it is a bibliography, and the references are the source |
| **vendor repository** | a company's repo over a hosted engine? | its docs' rules page and its client's types |
| **research-model release** | open weights plus real inference code? | its prompt artifacts and its config |
| **app/tutorial aggregator** | a monorepo of example apps? | the operational periphery, not the apps |
| **operator dispatch** | no URL - a framing or a question? | whatever the sub-questions route to |

Four rules cut across every row:

- **Any row that arrives as a repository is mined from a clone, never from the ingest.**
  Five classes do - vendor repository, research-model release, app/tutorial aggregator,
  paper aggregator, and the build-walkthrough in repo form - and each states in its own
  vocabulary that the README is its least reliable surface. `research-ingest` on a repo
  URL returns exactly that surface. Clone it and sweep the tree (Phase 2b), and sweep it
  a second time for engineering worth reusing, not only for claims worth quoting.

- **A hybrid source's halves have opposite reliability, and one question separates
  them.** For the build-walkthrough: *is the creator describing what the tool does, or
  what happened to them while using it?* For any demo: **the segment it is proudest of
  is where its boundary is missing**, because relatability is uncorrelated with
  correctness. The demo half shows the solution and hides the problem; the operating
  half is a first-party account. Route per half, never per source.
- **Whether the fetch budget binds is a property of the class, not of the run.** Five
  runs disagree only because their classes did. First-party accounts, practitioner
  codebases and batches corroborate corpus-internally - three consecutive runs spent
  **zero** of three fetches and landed everything, and reaching for the web there is
  usually a sign the claim has no home yet. Reviews, listicles and papers are lossy
  pointers to a primary that states the constraints they omit: for those the fetch is
  not corroboration, **it is the extraction**. Decide which you are holding at triage.
- **Length is not yield.** A 3,000-word first-party talk has outproduced a 7,000-word
  roundup; the shortest source mined (1,565 words) produced a technique and an
  amendment. Five consecutive runs say the `--min-words` floor answers "is anything
  there at all" and nothing more. The corrective differs by class, though: a thin
  first-party account needs no help, and a thin *review* yields a lead and nothing else
  unless you spend the fetch.

**Batches are their own lane** - N sources mined as one run, with their own triage
signal (within-batch convergence, deduped by *author* not by source) and their own
economics. The lane is written up in
[`references/source-classes.md`](references/source-classes.md) § "The batch lane";
read it before ingesting more than one source.

## Route by depth: the forge handoff (v2)

This skill was designed for a source that *reports*. A repository that *is* a system
- a runtime, a harness, a control plane, a toolkit with a dozen subsystems - carries
its knowledge as design, and design does not survive being read as a list of claims.
The registry already has the engine for that shape: `/forge` scouts every context of a
repository, designs subjects from what it finds, and forges them in waves. Last week's
runs never invoked it once, and mined six forge-shaped repositories with the news
method instead.

So the design read (Phase 2d) ends with a routing decision, made against one written
count:

> **How many load-bearing design decisions does this tree carry that no subject in the
> corpus models?** A decision is load-bearing when removing it would change the shape
> of the system, not one feature. "Models" means a subject whose golden path states the
> decision's forces, not one whose technique mentions the word.

- **Three or more** -> the source is a forge job. Write the design record, write the
  source-tree applications (Phase 7, v2), claim the implicated bundle on the board, and
  hand off: dispatch `/forge`'s Phase 0 scouts over the clone with the design record as
  their brief, or bank the handoff under `librarian/handoffs/<date>-<slug>.md` if the
  operator asked for `--design-only`. Intake resumes only for the *claims* the design
  read did not absorb - currency, leads, and the one-paragraph corrections a forge wave
  would not bother with.
- **One or two** -> stay here. Each becomes a `design` candidate (Phase 3) and is
  mapped, triaged and landed as a technique or a subject - not an amendment, unless the
  decision is a boundary case of a mechanism the corpus already owns.
- **Zero** -> the news method applies unchanged; the repository is a practitioner
  account in repository form and its yield is claims.

`--no-handoff` overrides the first branch for a run the operator wants kept small; say
in the source note that the count was met and the handoff declined. A run that reaches
Phase 5 on a forge-shaped repository without having written the count has reproduced
the failure this section exists to end, and the scorecard's depth column will show it.

## The memory lane (v2.6)

One domain in this registry has a measured baseline instead of only a corpus: agent
memory. `personas/evals/memory-year/` replays a simulated year against any design that
implements four calls, and nine arms have rows on that ladder - including three built
from public memory repositories in a single session, and this fleet's own two-tier
system before and after two fixes it exposed.

That changes what a memory source is worth. Most of them report an accuracy number for
a design whose shape we have already priced, so:

> **A memory claim is triaged against the measured ladder before it is triaged against
> the corpus.** Prior art is the second question. The first is: which arm is this, and
> what does the table already say it scores?

Enter the lane when the operator passes `--memory`, or on your own judgement when a
source's subject is memory, recall, consolidation, forgetting, or their evaluation.
**Read `references/memory-lane.md` before Phase 3.** It carries the ladder, the four
claims a source does not get to make unchallenged, the measurement rules this series
paid for, and the open questions that would mark a genuinely new contribution.

Two routing consequences specific to this lane:

- **A mechanism becomes an arm before it becomes a technique.** The harness takes a new
  adapter in a few hundred lines. A mechanism that cannot be expressed on the four-call
  contract is a lead, not a candidate; one that can is tested and *then* landed with its
  row. This is the strongest form of the apply step Phase 7.5 asks for, and it outranks
  a thought simulation.
- **A published memory number is a lead, never evidence.** Of three public systems read
  in one round, one had a contaminated held-out split, one declared benchmark scripts
  that did not exist, and the third's numbers were self-against-self. Re-run the claim
  as an arm; do not cite it.

## The strip test

An upper-layer document carries no product, model, company or tool name - enforced by
`scripts/check-bundles.mjs` for the words on its denylist, and by review for the rest.
A news source is made almost entirely of those names. So there is one question that
routes most findings on its own:

> Remove every proper noun from this claim. Is anything left that a team in another
> company could act on?

- **Something is left** -> it may become a technique or a golden-path correction, once
  corroborated. The vendor was the occasion for the rule, not the rule.
- **Nothing is left** -> it is an application, or it is a lead, or it is nothing. An
  application is where product names are allowed, and it is only writable against a
  tree you actually opened (see the cross-repo lane).

Run the strip test at extraction time, not after drafting. It is cheap and it kills the
candidates that would otherwise consume the corroboration budget.

## Corroboration - what a source may authorize alone

| Target | What the source alone can do |
| --- | --- |
| `_laws.md` (a law) | Nothing. Laws are the most cross-cutting thing here; they need convergence across runs, not a video. |
| Golden path, technique | Nothing. Needs a **primary source** (vendor doc, standard, paper, spec) fetched in-run, OR **training-data convergence** (you reach the same rule without the source in front of you), OR real code you read in a connected project. |
| Application | Only with a tree you opened. `verified_on` is the date YOU resolved its citations; `verified_against` may be written only by something that read the tree. |
| Currency signal | Yes, on its own. "A vendor shipped X" is exactly the class of fact a news source is reliable for, and it is a statement about the world, not about the standard. |
| Lead | Yes, on its own. That is what a lead is. |
| Golden path, technique - *via convergence* | Two independent sources, from different runs, reaching the same rule. This is the cheapest corroboration available and it costs no fetch, but it only exists if past runs wrote down what they saw. It is the reason the untriaged table is not bookkeeping. |
| `skills/`, `practices/`, `memory/`, `scripts/`, `docs/` | Judgment, no gate. These are ours; the bar is whether it would survive `CODEOWNERS` review. |

**A source that is contradicted is the best case, not a dead candidate.** Corroboration
is not a pass/fail gate on the source's wording - it is how the finding gets written. On
2026-08-21 a roundup said "take the highest precision tier your machine allows"; the
primary literature said the compression format dominates the nominal tier and that a
lower-tier variant can beat a higher one. The gap the source pointed at was real and the
rule it gave for filling it was inverted, so the technique was written against the
literature and is stronger for it. When a pick is contradicted, do not drop it: ask
whether the source located something true while explaining it wrongly, and if so write
the finding from the source that can authorize it. Say so in the note - a corrected
premise is the most reusable thing a run produces about a source class.

Four runs now say it more strongly than that: **a source that implements a good idea
badly is worth more than one that implements it well.** A tool that counted how many
newsletters carried a story was measuring promotion rather than corroboration, because
those newsletters relay each other wholesale - and the correction (record carriers at
*publisher* granularity) was the half the technique would not otherwise have had. A
correct source hands you a catch; a wrong one hands you the boundary. When a pick is
contradicted, that is the pick to keep.

Budget corroboration like `deepen` does: at most **3** web fetches for the whole run,
spent only on picked candidates, preferring primary and vendor documents over
commentary about them. A news video reporting on a paper is not the paper.

**Two classes are exempt, and the exemption is structural rather than generous.** For a
paper aggregator and a **reference index**, the referenced documents are not
corroboration for the source - they *are* the source, and the list is a bibliography.
A run-wide budget of 3 against a 200-entry index does not enforce discipline; it
enforces a 1.5% sample and then reports the result as if it were the source's yield.
For those two, the budget is **per reference and lives with the worker that reads it**
(~2 fetches each: the document, then at most one primary it points at), and the
*run-wide* discipline moves to the number of references admitted, which the ranking in
Phase 2c decides and the operator sees before a single fetch is spent.

**Tier sources; never count them.** Convergence means *independent* sources reaching
one rule, and most sources are not independent: a relay is downstream of the primary
it relays, so three relays agreeing with each other are one observation, and three
relays disagreeing with a fresher primary are evidence of the primary's *past* state,
not a vote against its current one. Rank by tier - standard or vendor document, then
repository or paper, then first-party account, then commentary - let the highest tier
present win a conflict, and record the conflict in the note instead of resolving it by
majority. The ledger already dedupes carriers at publisher granularity; this is the
rule that granularity was serving.

## Procedure

### Phase 0 - Bootstrap (idempotent)

- `librarian/sources/index.md` exists (the source ledger). Create if missing.
- `projects.json` exists at the repo root (**committed**) and `.machine.local.json`
  beside it (gitignored). Resolve them through `loadFleet()` in
  [`scripts/lib/projects.mjs`](../../scripts/lib/projects.mjs), never by reading either
  file directly. `projects.json` maps slug -> path RELATIVE to a machine root, plus the
  machines each project is checked out on; `.machine.local.json` supplies this machine's
  name, its root and its contributor id. A relative path names no private tree until a
  root is supplied, which is why only the second one is hidden. Domains are not in
  either: each project declares its own in its `.ai/manifest.yaml`. The prose half is
  [`librarian/projects.md`](../../librarian/projects.md).
- If the bridge is missing and the run needs it, ask for paths rather than guessing.
- **Claim this run on the board before reading anything else.** It costs one command and
  it is what makes the next eleven terminals safe:

  ```sh
  node scripts/run-board.mjs claim --skill intake --source "<url>" --run <id>
  ```

  Exit 3 means a live sibling already holds this source: stop and say so, or take a
  different source. Nothing after this point is safe to write without a claim, and a run
  that skips it is invisible to everyone else for its whole life.

### Phase 1 - Prove the instruments, then load memory

1. `node scripts/check-bundles.mjs`, then `node scripts/build-index.mjs --check`. A red
   gate means you are about to map claims against a corpus that does not parse. Stop.
2. `node scripts/librarian-scan.mjs --top 15` - the standing worklist. A candidate that
   reduces a measured attention point outranks one that does not, and this is the only
   tie-breaker in the triage that a script can check.
3. Read `librarian/sources/index.md`. **If this source was already mined, say so and
   stop** unless the operator wants a re-run; then read the prior note first, because
   its declines are the answer to half of what you are about to propose.
4. `node scripts/run-board.mjs list` - the ledger answers "was this mined", the board
   answers "is this being mined **right now**", and only the second one can see the
   eleven sessions whose notes do not exist yet. Read what the live siblings hold, and
   let it steer the run: a source whose obvious home is a subject two siblings are
   already inside is a source to route elsewhere or to mine for its other half. Say in
   the source note how many siblings were live and which subjects they held - that
   line is what makes a later collision legible instead of mysterious.
5. **Read the last row and the closing paragraph of
   [`SCORECARD.md`](SCORECARD.md), and say this run's declared focus out loud
   before Phase 5.** Phase 11 writes "next run's declared focus" at the end of every
   run; until v1.4.0 nothing read it, so four consecutive runs discovered their own
   instruction at Phase 11 - after shipping the triage table it was meant to shape -
   and each diagnosed a different proximate cause for the same zero. The focus is the
   one input that makes this skill improve across runs rather than merely repeat, and
   it costs one file read. If the focus does not apply to this source, say why in the
   scorecard row; that is a result, not a miss.

### Phase 2 - Ingest

```sh
node scripts/research-ingest.mjs "<url>" --json
```

**Look at the ingest's output before naming the class.** A word count is not evidence
that anything was read, and the dangerous reader failure is not the empty one - it is
the *confidently large* one, which clears every thin-source floor. A `words:` in the
tens of thousands over a document that should be a pamphlet, or a first screen that is
not prose, means the container was decoded rather than parsed. See § "Before any class:
check what CONTAINER arrived" in the reference.

**Then name the class and read its entry in
[`references/source-classes.md`](references/source-classes.md)** before extracting
anything. The ingest metadata usually decides it - the author field, whether the source
is a repo or a talk, how many voices arrived. That entry tells you where in this source
the yield hides, what it is reliable for, and whether you must spend a fetch; all three
change what Phase 3 is looking for. For more than one source, read § "The batch lane"
in the same file.

#### Phase 2b - If the source is a repository, CLONE IT. Always. No exceptions.

`research-ingest` on a repository URL returns **the rendered landing page**, which is
the README plus site chrome. That is not the source. It is the source's advertisement,
and every repository class in this method says so in its own words - the vendor
repository's marketing surface, the research release's method ad, the build-walkthrough's
tour half. **A run that extracts from a README has mined the one file in the tree
written to be quoted, and its findings will be quotes.** That is how a corpus fills up
with restated marketing.

So the ingest is the *trigger*, never the extraction:

```sh
git clone --depth 1 <url> <scratchpad>/<run-id>
git -C <scratchpad>/<run-id> log -1 --format=%H       # pin it; the note records the commit
```

The directory is named for **this run's board id**, never for the source, and never the
scratch root itself. Twelve concurrent runs share one scratch directory, two of them may
be mining the same organisation's repos, and Phase 9's cleanup deletes by name.

Then **sweep the tree before extracting a single candidate**, in this order - it is
ordered by yield density, which is close to the inverse of how prominent each part is:

1. **The operating documents.** `docs/`, `design/`, `spec/`, `*_SPEC.md`,
   `*_CONTRACT.md`, `RUNBOOK`, `owners-manual/`, `ADR/`, `CHANGELOG`. These are
   first-party practitioner documents with paid-for failure modes recorded as
   revisions, and they are usually the densest thing in the repo by an order of
   magnitude. A README is 2,000 words; these are routinely 15,000.
2. **The instrument and its rules.** A linter, a checker, a gate, an eval harness -
   whatever file *implements* a rule the README merely names. The README says the rule
   exists; this file says what the rule actually is, in a form that cannot hedge. When
   a source claims a contract with numbered rules, the checker that enforces them is
   the contract.
3. **The measurement.** `evals/`, `benchmarks/`, `ANALYSIS.md`, results tables, the
   test fixtures. A measured result with its protocol is the strongest thing a
   repository holds, and it is the part the README compresses into one adjective.
   **Read where it was refuted**, not where it held.
4. **The types and the config schema.** What an open client renders a closed engine
   with, the config file's full key set, the enum of states. These publish the real
   data model for free and cannot lie, because something compiles against them.
5. **The tests.** A test enumerates the cases the author believed in, and a test named
   after a failure is a failure mode somebody paid for.
6. **The README last**, as an index into the above and as the source of proper nouns
   you must then strip.

Say what you swept in the source note, with the commit, and record the honest word
counts on both sides - the landing page and the in-tree documents. A note whose
`words:` is a single small number over a repository source is a run that read the ad.

The tree is deleted with the rest of this run's scratch files at Phase 9, not before -
Phase 6 verification reads it, and Phase 7.5 may need it again. **It is always deleted
(v2.1.1).** A `task` row whose first step landed on a branch of the clone does not keep
the clone alive: export the branch with `git format-patch` into `librarian/handoffs/`
beside the task's plan, point the plan at the patch, and delete the clone. A clone left
behind for "later" is dead space nobody reclaims, and the operator said so on 2026-09-02.

**Read for reusable engineering, not only for claims.** A repository is the one source
class that carries *executable* knowledge, and the intake habit of hunting quotable
assertions leaves most of it on the floor. Sweeping for excellence is a different pass
from sweeping for claims, and it produces different candidates: a dependency-free
instrument worth porting into `scripts/`, a data shape worth stealing, a test strategy
worth copying, a failure taxonomy already enumerated, a config surface that solves a
problem one of our own projects has. Those land in `scripts/`, `practices/` and
`docs/` - the lanes the corroboration table calls "judgment, no gate" - and they are
often the highest-value thing a repository run produces. Ask of the tree the question
you cannot ask of a video: **what here is good enough to reuse, and what does it do
that we do worse?**

#### Phase 2c - If the source's value IS its links, the links are the source

Some repositories carry almost no knowledge of their own. An awesome-list, a curated
bibliography, a "papers we read" vault, a links section in a handbook: what it holds is
**a filtered set of pointers somebody paid attention to build**, and its own prose is a
one-line annotation per row. Mining that source by reading its README is not merely
incomplete, the way it is for a code repository - it is reading a library's card catalog
and filing a report on the catalog.

The tell is a ratio, and it is worth computing rather than eyeballing: **outbound links
to third-party documents, over the source's own word count.** A code repository has a
handful of links across tens of thousands of words. A reference index inverts that -
hundreds of links, a few thousand words, most of them link text. When the ratio inverts,
switch lanes.

**The failure this lane exists to end.** Past runs mined these sources by picking the two
or three references that looked most promising from their titles and reading those. That
is a 1.5% sample chosen on the weakest available signal - a title - and it discarded, by
construction, everything the curator had actually done work to include. The runs then
reported their yield as the source's yield. **Titles do not rank references**; a title
tells you a paper's topic and nothing about whether it measures anything, contradicts us,
or lands anywhere. The corrective is not "read more carefully". It is to stop sampling:
**enumerate every reference, rank the whole set against the corpus, and read the maximum
the run can afford in parallel waves** - explicitly accepting that most will return
`already covered` or `nothing`, because a cheap negative on a real reference is worth
more than a confident guess about an unread one.

Full procedure, worker brief, wave sizing and the stop rule are in
[`references/reference-waves.md`](references/reference-waves.md). Read it before the
first wave. The shape in five steps:

0. **Confirm each reference resolves before a lane commits to it.** For an arXiv
   reference that means one fetch of `/abs/<id>`, not `/html/<id>`: HTML is rendered
   only for LaTeX submissions, so a PDF-only paper 404s at `/html/<id>` and at
   `/html/<id>v1` alike and a lane aimed at one can spend its entire budget on empty
   responses. The `/abs/` page also returns the **untruncated title**, which on
   2026-09-01 carried more triage signal than the curator's annotation did — twice.
1. **Enumerate exhaustively, by instrument, never by reading.** Clone the tree (Phase 2b
   still applies - the index is a repository) and extract every URL from every file, not
   just the README: sub-lists, `docs/`, per-topic pages and the git history's removed
   entries all carry references. Dedupe by normalized URL, then again by *document* - a
   paper on arXiv, a PDF mirror and a blog summary of it are one reference. Report the
   honest total. A run that says "we found 47 references" over a tree holding 213 has
   already reproduced the failure at a larger sample size.
2. **Classify each reference by its own source class** (paper, vendor doc, first-party
   account, relay) from its URL and the curator's annotation. This costs no fetch and it
   is what makes ranking possible: a relay of a primary already in the set is not a
   second reference, it is a duplicate with a different domain name.
3. **Rank the whole set against the corpus, not against your interest.** One
   `research-map` call carrying every reference's terms at once - that is what the
   instrument is for. Score each reference on: does it map to a subject that
   `librarian-scan` says has attention points; is it a class that can *authorize*
   something (primary/paper) or only originate (relay); does its annotation claim a
   measurement, a negative result or a contradiction; and is it already in the source
   ledger. Rank descending, and **keep the whole ranked list in the source note** - the
   tail is the artifact that makes the next pass over this index cheap instead of a
   re-derivation.
4. **Cut waves, not a top-N.** A wave is 5-8 references read by 5-8 parallel workers,
   one reference each, each with its own ~2-fetch budget. Run wave 1 over the top band,
   read what comes back, then decide wave 2 *from the returns* - the first wave routinely
   moves the ranking, because a reference that came back with a measurement promotes
   everything the curator grouped beside it, and a band that returns eight catches
   demotes its whole cluster. Keep going while a wave is still returning something; the
   stop rule is a yield floor, not a fixed number of waves. Two or three waves over a
   large index is normal and expected.
5. **Merge serially, exactly like a batch.** The director holds every write; workers
   return proposals and touch nothing. Within-index convergence - two independently
   curated references reaching the same rule - is the strongest triage signal this lane
   produces, and it is available *only* because the sample was broad. Dedupe it by
   author, not by reference.

**The board matters more here than anywhere else in this method**, because one reference
index can generate more landings than a dozen video runs. Claim the subjects the ranking
implicates as soon as step 3 names them, before wave 1 dispatches, and heartbeat every
wave. A wave run unclaimed against a bundle two siblings are inside is the worst
collision this skill can produce.

**A reference index also carries one finding of its own, and only one**: what the curator
chose to include and what they left out. A bibliography is a stated opinion about a
field's boundary. When it converges with ours, that is corroboration for a boundary we
drew; when it does not, the gap is a lead worth more than most of the references. Record
it, once, and do not mistake it for the source's yield.

#### Phase 2d - The design read: decisions, not claims (v2)

A sweep for claims and a sweep for excellence both leave the largest thing in a
repository on the floor: **why it is shaped the way it is.** A system's architecture is
a set of decisions, each made against forces, each buying something and rejecting
something, and the sources that record them - ADRs, design documents, the CHANGELOG's
"why" paragraphs, the module guides, the git history of a rejected approach - are the
densest first-party material a tree holds. A claim can be quoted; a decision has to be
*reconstructed*, and the reconstruction is the artifact.

After the sweep and before extraction, write the **design record** - three to seven
entries, each in this shape, into the source note under its own heading:

```
decision:   one sentence, in the tree's own terms (product names allowed here)
forces:     what made the obvious alternative wrong - scale, trust boundary, latency,
            a platform limit, an operator constraint
buys:       the property the decision secures, stated so a team elsewhere could test for it
rejects:    the alternative the tree did not take, and where it says so
where:      root-relative path:line "quote" anchors - the ADR, the module guide, the
            type that encodes it. The quote is what makes the anchor checkable:
            `node scripts/check-anchors.mjs <note> --root <clone>` verifies every
            one, and a line number without a quote is existence, not evidence (v2.11)
stage:      the point in the system's own pipeline where the decision is made
corpus:     the subject whose golden path models this decision's forces - or NONE, with
            the nearest neighbour named and why it does not model them
```

Three rules make the record worth having:

- **A decision without forces is a feature.** If you cannot say what would have made
  the alternative right, you have described what the tree does, not why, and the entry
  goes back to the claim lane.
- **Stage, not slug, decides the home.** Ask where in the corpus subject's own pipeline
  this decision is made, and whether any technique sits at that point. That is the same
  hunt Phase 6 runs on claims, moved to the front where it changes what gets extracted.
- **The `corpus:` line is the routing count, and it is counted twice (v2.2).** Group the
  entries by the SYSTEM they belong to - a repository holds several - and count NONE per
  system; a system at three or more with no home is a scoped forge, a system at three or
  more with an existing home is a technique triple inside that subject, one or two stay
  in intake. Then count the `HOME IF NEW` clause across systems: three or more entries
  sharing one home-if-new fire the XL trigger even when no single system clears alone
  (round 3: whole tree six, per system at most two, four sharing one home). Either
  clause can fire; hand off the system or the cluster, never the repository. Write both
  counts before deciding, and write the decision under the record.

The design record is also the brief a forge scout receives if the run hands off, and
it is the body of the source-tree application (Phase 7, v2) if it does not. Either way
it is written once and it outlives the run: a later pass over the same repository
diffs against it instead of re-deriving it.

#### Then read, then clean up

Read the transcript (and, for a repository, the swept tree). This run's scratch files -
the ingest's text, the metadata, and any clone - are deleted at Phase 9, scoped to this
run's id, never as a blind sweep of the work directory, which races a parallel run
sharing it.

### Phase 3 - Extract candidates (cheap: no web, no file reads, no greps)

A news roundup is **segmented**: it is ten unrelated items in a trench coat. Split on
the segment boundaries and treat each as its own candidate, because they route
differently and the operator will want to pick across them, not accept the video.

Per candidate record:

- `title` - imperative, under 60 chars
- `claim` - one sentence, in the source's own terms
- `anchor` - `[HH:MM:SS]` or a quote under 20 words
- `strip` - what survives the strip test, or `nothing`
- `lane` - `K` knowledge / `S` skills / `P` practices / `M` memory / `T` tooling+docs / `X` project
- `shape` - `law` / `golden-path` / `technique` / `application` / `correction` / `currency` / `skill` / `practice` / `memory` / `script` / `lead`
- `effort` - `S` (a frontmatter line or two) / `M` (one document) / `L` (several) / `XL` (a subject, a bundle, a lane)

Extract 5-15. Drop only what has no plausible attachment anywhere in the registry.
Do **not** open bundle files yet - that budget belongs to what the operator picks.

**A `design` candidate is a second kind of row (v2).** Every entry in the design record
whose `corpus:` line is not a clean catch becomes a candidate with `shape: design`,
carrying the record's `decision`, `forces` and `stage` in place of `claim` and `anchor`.
Two differences from a claim row govern everything downstream:

- **The strip test is deferred, not skipped.** A design candidate keeps its product
  names through triage, because the decision is only legible in the tree's terms. It is
  stripped at Phase 7, when it is written as a technique - and if nothing survives the
  strip *then*, it lands as a source-tree application instead, where names are allowed.
- **Its default landing shape is a technique or a subject, never an amendment.** A
  decision is a mechanism. An amendment is for the boundary case of a mechanism the
  corpus already models; if the design record says the corpus models it, the candidate
  is a catch, and if it says NONE, the corpus needs the mechanism, not a paragraph.

### Phase 4 - Map for prior art (one instrument call)

```sh
node scripts/research-map.mjs "<term 1>" "<term 2>" ... --top 4
```

One call, every candidate's terms at once. Add `--deep` when the first pass looks
thin - it reads each document's `use_when`, which is the field written to be matched
on and which the index does not carry. Attach to each candidate its top prior-art hit
(`domain/category/subject`, with the technique that matched) and its **registry
impact**, from a closed vocabulary that maps onto the scan's weights:

`new-subject` - `new-technique` - `corrects-claim` - `fills-stack-gap` - `dates-application` - `resets-clock` - `new-law` - `none`

**A curator's TITLE is as unreliable as the annotation, and fails differently.**
An annotation paraphrases and can be checked against the abstract; a title is
*truncated*, and what gets dropped is the qualifying clause — a scope precondition
("for discrete-choice reasoning"), or the half that carries the measurement ("and
controlled benchmarks"). Both were observed on 2026-09-01, and both decide whether a
reference is relevant at all. Recover the full title at step 0 and rank on that.

`none` is honest and common. It is also the value that should make you ask whether the
candidate belongs in `skills/` or `memory/` rather than in a bundle.

**The XL trigger is mechanical (v2).** When three or more `design` candidates carry the
same `HOME IF NEW` - or the same `corpus: NONE` neighbour - a subject exists by
construction, and the run writes the XL spec and dispatches the forge worker on it
(Phase 7) without a judgment call. Under v1 the spec was proposed only when a run
*noticed* that fragments belonged together, and in twelve runs no run noticed. The
count replaces the noticing. Two design candidates sharing a home are a technique pair
in an existing subject, or a lead for the third.

**The instrument sees one branch.** It reads the working tree, so bundles that exist on
other branches are invisible to it and it will report "no prior art" over a domain a
sibling branch covers in depth. It now prints which bundles it scanned and on which
branch; read that line. Before trusting an empty result for a domain this branch does not
carry, run `git branch -a` and check. The corpus is bigger than any one checkout.

**It also sees one moment.** The branch warning covers other branches; it cannot cover
commits that land on *this* one after you read the worklist. On 2026-08-27 a parallel
session landed a new subject in the same bundle mid-run, and Phase 4's first map would
have mis-homed two candidates. In a shared checkout, re-run the map - or at least
re-read the bundle's subject list - before Phase 6's homes are final.

**And it cannot see the future at all**, which is the failure the board exists for: a
sibling's subject is not in the index until that sibling commits, so the map reports a
hole over ground another terminal is standing on. As soon as the map names a home,
claim it and check it:

```sh
node scripts/run-board.mjs beat --run <id> --phase 4 --subject <domain/category/subject>
```

A `new-subject` impact over a domain a live sibling holds is the one to distrust hardest.
Read that sibling's claim, and prefer an amendment inside their subject over a competing
one beside it.

**An absence read off a TRUNCATED output is not evidence either, and this is the
harder one to notice** because the instrument was working. On 2026-09-01 a run
verified "nothing owns this" with a grep that returned 22 files, piped it through
`head -8`, and treated the eight it saw as the answer; the subject that refuted the
claim was in the fourteen it did not. In the same run `research-map --prose` read the
right document bodies and put the same subject at rank 7 of a default top-6. Two
different instruments, both correct, both cut off — one hidden subject. So: **never
establish an absence from a piped, capped or paginated result.** Re-run with the cap
removed (`--top 40`), or with `wc -l` first, and read the whole set before writing the
word "nothing".

**A total empty over banned vocabulary is not evidence of anything.** The upper
layers may not carry product, framework or scaffold names — `check-bundles.mjs` enforces
it — so any query built from those names returns zero by construction. It measures the
purity gate, not the corpus. On 2026-08-31 a run concluded the corpus owned no material
on agentic workflow selection from a grep for two scaffold names, re-ran the same grep as
verification, reported it as confirmed, and was refuted by two later lanes against a
subject holding 1,794 annotated trajectories. **Map on concepts; never let a proper noun
be the query that decides an absence.**

**A near-empty is more dangerous than a total empty.** The instrument matches slugs, so
it cannot see a concept that lives inside a document's prose. Zero hits usually means a
real hole. Two or three weak, semantically unrelated hits mean one of two very different
things - a hole, or a **seam**: the concern already exists inside a subject under a
different name, and what is missing is the boundary rather than the material. On
2026-08-22 a candidate mapped to three spurious matches and turned out to be a seam
inside a nine-technique subject whose golden path already produced the thing in
question. Read the top prior-art subject's golden path before believing a near-empty,
and prefer writing the boundary over writing a duplicate.

### Phase 5 - The admission gate (v2.5: scored, not asked)

```
#  Lane  Shape      Eff  Title                            Prior art (subject)        Impact           G/R/C  Decision
1  K     technique  M    Separate weights from a license  se/llm-agent/model-routing new-technique    3/0/2  accept
2  K     currency   S    Context-window claim moved       se/.../prompt-assembly     resets-clock     1/2/1  untriaged
3  X     applicat.  M    Personas already does this       -                          fills-stack-gap  2/0/2  accept
```

**Why this phase stopped asking.** Until v2.4 this gate ended with *"which should
I verify and land?"*, and the run stopped until a human answered. The ledger says
what that bought: of **149 source notes carrying a `declined` field, 134 read
`declined: 0`** - the gate changed the outcome in roughly one run in ten, by a
median of one row, and the scorecard's own prose records the modal answer as
"rows 1-6 per your recommendation". The gate was not selecting. **The run's own
`real gap` / `partial` / `likely catch` read was selecting**, and the operator was
ratifying a filter that had already run.

That is the problem worth fixing, and it is not "ask less". A filter that decides
everything while appearing to defer to someone else is a filter that never has to
justify itself. So the read becomes an explicit, veto-first, reject-biased score
that is written into the source note and can be audited after the fact - and
**stricter than the stamp it replaces**, because the stamp carried almost no
information.

**Which rule governs which shape (v2.8).** This gate does not govern every row,
and three consecutive runs filed the same diagnosis before the method said so. The
score is for rows targeting the **upper layers** - a technique, a golden-path
correction, an amendment, a subject. **A currency row and a lead are governed by the
corroboration table instead**, which says a source may authorize both alone, because
"a vendor shipped X" is a statement about the world rather than about the standard.
Run through Phase 5 they are rejected by construction: a clock reset caps at GAIN 1
and can never clear a +2 threshold, however well corroborated. So route by shape
first - score the upper-layer rows, admit currency and leads under the table - and say
in the source note which rule each admitted row ran under.

Run the three steps in order. **A score may never overturn a veto**; that ordering
is what keeps this from being a rubber stamp with arithmetic on top.

#### Step 1 - Vetoes (absolute; a vetoed row is recorded UNTRIAGED, never declined)

| | Veto | Why it is absolute |
| --- | --- | --- |
| **V1** | **Placement.** The row's home is a category already at `MAX_CHILD_DIRS` (10, `scripts/lib/taxonomy.mjs`). | `check-bundles.mjs` rejects the landing. A spec that names a full category sends a worker to build in a folder the tooling refuses - the 2026-08-22 failure, now mechanical. **Count the category before scoring, not after drafting.** |
| **V2** | **Corroboration.** Target is a golden path or technique and the row has none of: a primary fetched in-run, training-data convergence, code read in a tree. | The corroboration table already forbids it. The veto stops the score from arguing around it. |
| **V3** | **Law.** Shape is `law` without convergence across runs. | Laws need convergence, never a source. |
| **V4** | **Strip.** `strip: nothing` and the shape is not `application`, `lead` or `currency`. | An upper layer carrying a proper noun fails the gate and the review. |
| **V5** | **Contention** (defer, not reject). A live sibling holds the target file and this row would restructure rather than append. | Their write lands first; re-enter behind it. |

#### Step 2 - Escalations (the human gate, narrowed to where a human actually decides)

Four things still stop and ask, because none of them is a judgment the run owns:

- **E1 - a direction.** A new context or capability a project's `scope.does` does
  not name. Unchanged: proposed at Phase 7.6, decided at the 7.7 gate.
- **E2 - a taxonomy change.** Subdividing a category or moving a subject is a
  corpus-wide link rewrite that goes through `scripts/apply-taxonomy.mjs`.
- **E3 - a new law**, if one ever survives V3.
- **E4 - an XL row**, and any cross-repo change that is not coverage or is too
  large to read in one diff. A subject is a forge dispatch; the operator sees it.

#### Step 3 - Score the survivors

**GAIN (cap 5)** - what lands if the row is right.

- **3** - a new subject, or a new technique in a subject `librarian-scan` names in its top 15
- **2** - a new technique elsewhere; or an amendment that **inverts** a rule the target file states
- **1** - an amendment adding a boundary case; a currency signal that resets a clock
- **+1** - **convergence**: two independent readers, sources or runs reached it without seeing each other
- **+1** - the row **refutes** something the corpus asserts (a negative finding)

**RISK (cap 5)** - probability x damage of being wrong.

- **2** - the claim rests on the source's prose alone
- **1** - it rests on one worker's report the director has not re-checked
- **0** - the director opened the file or the tree and confirmed it
- **+2** - the landing **rewrites** rather than appends. The test is mechanical:
  *do the file's existing sentences stay true?* A new row beside three true rows
  is an append; a change that makes a standing sentence false is a rewrite.
- **+1** - the home is contested between two subjects
- **+1** - the source contradicts itself here and the run had to pick a side

**COST** - `S`=1, `M`=2, `L`=3.

> **Auto-accept when `GAIN - RISK >= 2` and `GAIN >= COST`. Otherwise the row is
> recorded untriaged with its anchors.**

**The threshold sits at +2 rather than 0 because the two errors are not
symmetric.** A false reject costs almost nothing - the row is banked with its
anchors, carries no judgment, and a later run picks it up for the price of a
re-read; the method already guarantees this by never filing an unpicked row as
declined. A false accept puts an unearned claim in the upper layers, which is the
one failure that damages the corpus rather than wasting a run. Bias the gate
toward the recoverable error.

**The promotion read.** When a row's *only* blocker is the `+1` for resting on an
unre-checked worker report, do not reject it - **spend one file read and re-score**.
That is the difference between a gate that punishes gaps in verification and one
that *directs* verification at the rows where it changes an outcome. It is the
same move v2 made for `partial` rows with the promoting question, applied to the
score. A row blocked by anything else as well is rejected without the read.

#### Step 4 - Record, and let the mechanism correct itself

Every row's `G/R/C` and decision go in the source note's triage table, so a wrong
call is diagnosable six weeks later instead of mysterious. The scorecard row
carries `auto=<accepted>/<rejected>/<escalated>` and `fp=<n>`.

**`fp` is the mechanism's own error rate: an auto-accepted row that dies at Phase
6 is a false positive.** Three of those across runs and the accept threshold rises
to `+3`. Three consecutive runs at `fp=0` whose rejected rows a later run had to
re-derive, and it falls to `+1`. The gate is measured by the same discipline this
skill applies to its lessons - confirmed three runs running, or it is not a rule.

**The ship authorization is standing and does not need to be asked for
(operator rule, 2026-09-04).** Where a run identifies a real seam in a managed
project, it may change that project's tree under the Phase 8 rules — the paired
proof, the pathspec commit on the active branch, and never a push. Do not ask
which trees may be touched; identify the impact and act on it. The operator's
reasoning is that the identification *is* the judgment worth having, and a
session that has the seam, the measurable and both arms loaded is the only cheap
place to spend it: three consecutive runs filed `better` apply rows against
`ship 0`, blocked on nothing but a confirmation, and in two of the three the
operator lifted it in one line after the loaded session had already ended.

Two things the standing authorization does **not** cover, and both keep their
gates: a **direction** — a new context or capability the project's scope does not
name — is still proposed and waits for the owner's ledger row (Phase 7.6/7.7),
and a change too large for a reviewer to read in one diff still takes a branch
and says why. Everything else ships on the recommendation, with the project's own
gate as the review.

**Carry an altitude on every row**, and prefer the highest altitude the corroboration
supports: `law` (a convergence across runs, provider-portable, clock-proof) /
`doctrine` (a design stance) / `technique` / `dated fact` (a number or vendor
behaviour with a shelf life). Dated facts are not lesser - they are the corroboration
the upper layers need - but a run that lands ONLY dated facts must say why nothing
higher was earned, and the cross-run convergence check is mandatory: when this run's
finding and two prior runs' findings share a root, the landing is the root, proposed
at law or golden-path level, with the numbers cited into it. The operator's standing
critique (2026-08-25): low-level numbers and per-provider practices age in months;
the synthesis step must come from the skill, not from the operator.

**Carry your own read on every row**, in its own column: `real gap` / `partial` /
`likely catch` / `thin`. It is an input the score is computed from, not decoration -
on 2026-08-22 the operator took four rows marked real and skipped three of four
marked likely-catch, and that column is what made the difference legible. Under
v2.5 the read no longer routes the row on its own: it feeds GAIN and RISK, and the
score routes it. Withholding the read to seem neutral just moves the guesswork.

Say the expected yield for the source class out loud before the table, so a small
number reads as calibration rather than as failure. Flag any candidate that matches a
prior run's decline or a banked lead as `reconsider?` with the earlier reason.

Only admitted rows go deep, and **every `partial` row gets its promoting question
executed before it is filed (v2)**: write the one question whose answer would promote
the row to `real gap`, answer it with one file read - the technique or golden path the
row's prior art names - and re-score the row if the answer promotes it. Under v1
`partial` rows were banked with their anchors, and the mechanisms sat there: a design
decision always overlaps some subject, so it always reads `partial`, and the rule that
protected the verification budget spent it on the cheapest rows instead. A `design`
row is never `likely catch`, because the design record already checked. The promoting
question and the promotion read of Step 3 are the same instrument aimed at two
different blockers, and a row may take both (operator rule, 2026-08-28; amended
2026-09-02 and 2026-09-04).

### Phase 6 - Verify the picks

1. **Read the actual file** named by `research-map`'s `file`. Slug overlap said
   "neighbourhood", not "same claim". Golden paths in this corpus routinely hedge
   better than their techniques do, and a correction written against a summary is a
   phantom fix - `deepen` names this its dominant failure mode and it is inherited here.
2. **Ask where in the subject's own pipeline the claim happens.** Most real findings in
   a mature corpus are not missing opinions, they are missing *stages*: a decision the
   documents leave to a default because no technique sits at the point where it is
   made. All four findings on 2026-08-22 had this shape - the decision to retrieve at
   all, the promotion of a memory into a capability, the step a limit counts on, what a
   provenance check settles. Walk the subject's stated pipeline, name the point the
   source's claim lands on, and check whether anything owns it. A subject that is
   thorough from stage two onward is exactly where a missing stage one hides.
3. **Hunt where a document declares its own completeness.** "The subject owns two
   flows that are mirror images of each other", "the three cases where strictness is
   still correct", "both naive policies fail" - an enumeration is a claim, it invites
   exactly one question, and asking it is cheap. Two of the strongest findings across
   four runs came from a source demonstrating a case an enumeration did not contain.
   The corpus writes these claims in golden-path openings and in technique section
   headings; they are the highest-yield thing to read once a candidate has a home.
   **A denial is an enumeration too: where a subject explicitly denies a symmetry,
   check whether it denied too much.** On 2026-08-27 a subject insisted its two
   pipelines are "not mirror images" - correct, and that framing had hidden for months
   that their *doors* do mirror and only one of the two had ever been built.
4. **Find what the subject mentions in one place and measures in another.** The third
   hunt, beside the missing stage and the enumeration, and the one that survives a
   corpus getting mature: a real finding is often not an omission but an **asymmetry**.
   On 2026-08-27 a subject named the human reviewer as its bottleneck in one technique's
   prose and modelled the machine bottleneck in another with four measures, distribution
   discipline and an ordered demand-reduction section - so it sized its first server
   against machine-paced arrival and routed the whole output into a second server whose
   rate was never written down. **Neither the slug map nor a summary can see this**: two
   files that both "cover" a concept score identically, and only opening both reveals
   that one gets a model and the other gets a sentence. When a candidate looks
   already-covered because some file says the words, ask which file *measures* it.
5. **Read the neighbours, not just the gap.** A candidate phrased as "X is missing"
   aims you at the half that is not built and away from the half that is, which is
   where a real defect is likelier to sit. Read the sibling techniques and one
   application before writing the finding up.
6. **Name the home, and expect it to be contested.** A finding whose home is obvious was
   probably already covered. The interesting ones sit between subjects, and picking
   wrong misfiles the technique where nobody looking for it will look. Read the
   candidate subjects' own boundary statements - this corpus states them explicitly, in
   the golden path's opening - and choose the subject whose stated job the finding
   answers, not the one whose slug matches. When two subjects describe the same
   boundary from opposite sides, say so in both notes rather than writing it twice.
7. **Corroborate** per the table above, inside the 3-fetch budget.
8. **Drop honestly.** A picked candidate that resolves to already-covered is a catch,
   not a failure, and it goes in the note so nobody proposes it again.

### Phase 6b - Render proof (v2.9: generative-output bundles; the operator triages)

A candidate is **render-bound** when its home produces pictures -
`media-generation/visual-generation`, `production-ops/video-assembly`,
`game-production/asset-production`, or any subject whose `use_when` generates, renders or
accepts an image, clip, sprite, texture, mesh or animation - and its shape changes what a
generator is told or how its output is prepared or accepted. **A render-bound candidate
does not land on corroboration.** Before Phase 7 writes it, render one brief through two
arms on the local pipeline: arm A compiled from the corpus as it stands at `HEAD`, arm B
compiled as the landing would leave it (or as the source instructs). One variable; same
seed, anchors, model and length; original characters and places. The operator triages a
blind sheet, the picks are revealed onto the arms, and the verdict decides what lands
and in what shape. Then every rendered artifact is deleted by run id and only the
verdict is kept.

```sh
node scripts/render-triage.mjs sheet  <run-dir>                    # blind page + sealed key
node scripts/render-triage.mjs reveal <run-dir> shot1=Y shot2=tie  # verdict.json
node scripts/render-triage.mjs clean  <run-dir> --also <ComfyUI>/output/<run-id> --also <ComfyUI>/input
```

The procedure - scope, instrument probes, arm construction, the triage questions, the
verdict-to-shape mapping, resource discipline, cleanup and the record - is
[`references/render-proof.md`](references/render-proof.md). Read it before Phase 5
scores a render-bound row, because the instruments are probed before the score, not
after the landing.

Why this is a phase and not a Phase 7.5 mode alone: until 2.9.0 these bundles changed
the instructions every consumer compiles into a generation call - restate the style,
admit the reference late, cut both anchors from one cloth - on corroboration and a
`simulation` row, **without anyone having looked at one output made under the old
instruction and the new one**. For a finding whose only observable is the output, that
is landing blind. The first run under this phase found two corpus files contradicting
each other at the still-to-motion hop, with a source siding with one of them, and no
amount of reading could settle it; rendering both arms could.

Six rules hold without exception:

- **The scenario is controlled, and it is proven legible BEFORE any pair is designed
  (v2.13; operator rule, 2026-09-20).** This is the 3D lane's clean-rig precondition,
  which the still and video lanes went without for four versions and paid for. A pair
  rendered over a brief the stack cannot compose is noise against noise: a tie, a refusal
  and a win are then indistinguishable from each other, and — the expensive part — from
  *the technique being wrong*. Two consequences:
  - **Design the proof against a scenario from the consuming project's own shot
    taxonomy**, not an invented brief. Those are the real use cases, they are already
    IP-neutral, and an envelope measured on them is the envelope that matters. Each
    scenario carries a **countable** expectation — *exactly one face, three figures
    abreast, one lit window, the upper third empty* — because a legibility bar phrased as
    "reads cinematically" is graded differently twice by the same reader.
  - **Run the scenario with NO treatment first, as a positive control**, and record which
    scenarios this stack renders legibly at which settings. That envelope is reusable, it
    makes the next render proof cheap, and it is the only thing that lets a later failure
    be attributed to the technique. A scenario that fails its own expectation is not a
    substrate for a comparison — fix it, drop it, or bank the finding as a lead about the
    pipeline rather than about the candidate.
  - **Composition and time are separate questions, measured separately.** *Can the stack
    compose this scene?* is a still control. *Can it hold the scene over time and execute
    a commanded change?* is a motion pair, run only over scenarios that passed the still.
    A run that conflates them cannot say which half failed, and the 2026-09-20 move-onset
    pair is the worked example: four incoherent clips, a discrimination ratio computed
    over them, and a number that could not distinguish an invalid technique from a
    pipeline that never rendered the brief at all.
- **A 3D subject is clean before it is compared, and it is compared in stills (v2.10).** No
  motion, rigging or posing pair is designed until the rigged subject passes
  `references/render-proof/rig_check.py` at the poses the action will reach - no unweighted
  vertices, rigid parts rigid per vertex, no torn edges. A subject that fails is repaired within
  the stage's stated budget or banked as a lead naming the clean asset it needs; it is never
  animated for triage. Each 3D arm is then shown as one pose sheet
  (`references/render-proof/pose_sheet.py`) with identical framing across arms, gated by
  `sheet_distance.py` and triaged blind like any other image, with the winner stored in
  `verdict.json`. Generated video is not a presentation; engine screenshots are opt-in. Two 3D
  runs in a row lost their pair to the subject - a proxy hand, then a fused mesh - after the
  pass that built the rig had reported it fine.
- **Arms are approaches, and their discrimination is measured before the operator looks.**
  Render the same approach at a second seed; the arms must differ from each other by at
  least 1.5x that seed noise, recorded as the pair's `discrimination`. Below that ratio the
  pair **may not author a landing** - a knob the rest of the pipeline drowns out yields two
  runs of one process and a tie that reads like evidence. The first run under this phase
  made that mistake twice before the operator named it.
- **But the gate decides the LANDING, never the look (v2.12; operator rule, 2026-09-20).**
  A refused ratio is a reason to withhold the technique, not to withhold the artifact. Every
  media-generation intake **ends in a comparison the operator can open** - before/after when
  the corpus already says something, or two variants of the path when the finding is new -
  and it is presented with its `discrimination` printed beside it rather than suppressed by
  it. The operator is the one instrument that can overrule the ratio, and they cannot
  overrule what they were never shown. A run that reports a number and deletes the frames
  has asked the operator to take its word, which is the one thing this phase exists to
  prevent. Where the gate refused, say so on the sheet and show it anyway; where the two
  seeds disagree with each other, show **both** seeds, because that disagreement is the
  finding.
- **No render host here: queue it for the media host (operator 2026-10-15).** This machine
  keeps no local models by decision, and a dedicated media host (image, video, 3D) will run
  render proofs. A render-bound candidate never lands here, and a run never downloads a model
  to render one. Write it to `librarian/harvest/backlog.jsonl` in its usual shape with
  `"status": "held"`, `"queue": "media"` and a `"render"` object naming the run id, the brief,
  where arm A's and arm B's instructions are (the corpus-before and corpus-after text, or the
  source-note section holding them), and the instrument it needs (model, node, the envelope
  if one is known). `held` rows never enter a `/harvest backlog` wave, so nothing on this
  machine picks it up; the media host claims `queue: media` rows, runs this phase there, and
  the operator's blind verdict lands or rejects them. It never becomes a technique carried by
  a `simulation` row.
- **The run does not grade its own render proof.** The director pre-reads frames to catch
  a crash, a black clip or a wrong anchor, and labels that read as opinion in the note.
  The operator's pick is the verdict: the question is whether the output is *better*, and
  every automated instrument these bundles hold is calibrated for *consistent*.
- **Clean after the OPERATOR's verdict, never after the gate's (v2.12).** Every output the
  run submits carries the run id as its `filename_prefix`, every staged input starts with
  it, and `clean` refuses without `verdict.json`. A refused discrimination ratio does not
  authorize a delete: the frames are what the operator would need in order to disagree with
  the ratio, and a run that deletes them has closed the only appeal. Keep the sheet and the
  clips until the operator has looked or has said not to; then clean by run id, and put the
  byte count in the source note.

### Phase 7 - Land what survived

Route by shape. Every content change is gate-clean before it is committed.

| Shape | Where it lands | The rule that governs it |
| --- | --- | --- |
| `technique` | `<subject>/techniques/<slug>.md` + the owning golden path's `techniques:` list | Bidirectional or it does not exist. Cite `laws:` that already have anchors; do not invent one. |
| `golden-path` correction | the subject document | Keep the file's prior voice. The corpus reads as one author. |
| `application` | `<subject>/applications/<stack>--<technique>.md` | `verified_on` is today only if you resolved its citations today. `verified_against` only if you opened the tree. **The source's own clone is an opened tree (v2):** a repository run writes applications against the source itself, one per design-record entry whose `corpus:` names a subject, with `stack:` the source's stack and the design record's `decision`/`forces`/`buys` as the body. This is where a system's architecture is recorded in the registry; under v1 applications existed only for fleet projects, so the architecture of every mined repository went nowhere. `verified_against` names the document's stack at the version the tree **witnesses** (an engines field, a CI pin, a lockfile), never the version a dispatch guessed, and the first paragraph says which witness (v2.2). |
| `currency` | the affected application's frontmatter, or a `/deepen` dispatch | A re-checked citation MUST move `verified_on`, or the corpus ages while the work says it did not. |
| `skill` | `skills/<name>/` | Bump `version` in the same change; append to `LESSONS.md` after the run. |
| `practice` / `memory` | `practices/<slug>/`, `memory/<kind>/<slug>.md` | ASCII only in these lanes. One idea per file. |
| `script` / `docs` | `scripts/`, `docs/` | Zero dependencies. Assert the instrument before the result. |
| `law` | `_laws.md` | Only on convergence across runs. Record the lead; do not write the law. |
| `amendment` | inside an existing technique | The case a well-forged technique does not cover. **Boundary or mechanism decides the shape (v2):** an amendment is right when the finding is a boundary case - a condition under which the technique's rule inverts, a lane it did not reach - and wrong when the finding is a mechanism the technique never had. A mechanism gets a technique, and three mechanisms with one home get a subject. The v1 sentence "in a mature corpus the amendment is the higher-yield move" was a bias that produced eleven amendments to six techniques over twelve runs; add the section only when the file's own rule survives the finding, keep the file's voice, do not mint a competing technique beside it. |
| `lead` | the source note | With a return condition, or it is not a lead, it is a shrug. |

**When a rule inverts across bundles, name the discriminator - do not link.** Cross-bundle
links are forbidden, and the situation is not a contradiction to resolve but a boundary to
state: the same interaction pattern can be correct in one domain and disqualifying in
another, and what the reader needs is the question that tells them which side they are on.
State it in prose on the side you are writing, and record in the subject note that the
other bundle holds the opposite technique, so a later run recognises the shape instead of
re-litigating it.

`XL` is specified, never half-built: write the spec or the handoff and link it from the
source note. Two things make the difference between a spec somebody can execute and a
note nobody acts on:

- **Fold the fragments in.** A subject-sized gap usually arrives as several small
  candidates from the same source that each looked like a standalone technique. Absorb
  them into the spec as its proposed techniques rather than banking them separately -
  four fragments in one dispatchable document beat four leads that will be re-derived
  one at a time.
- **Write it as the engine's input, not as prose.** Name the bundle, the category, the
  proposed technique slugs with the decision rule each must carry, the boundaries it
  must NOT absorb, and the open questions the drafter has to decide rather than
  discover. Point at any instance of the gap that already exists in a tree somebody can
  open - that is what makes the dispatch cheap.

Say plainly why it was proposed rather than written. A spec that does not argue its own
`XL`-ness reads as an excuse.

**Then execute it in the same session.** A spec is proposed rather than written because
one author's account is thin evidence for a whole subject - not because the work should
wait. The evidence that made it `XL` is loaded *now*: the neighbours are open, the
boundary is argued, the placement is verified. Ending the session with a banked spec
throws that context away, and the next session pays to rebuild it before it can start
(operator rule, 2026-08-28). So once the spec is written and the operator has picked
it - or, unattended, once it is the run's highest-impact row - **dispatch one forge
worker on it before Phase 9**, and stay in the director's chair:

- The worker reads `docs/forge-brief.md`, `docs/harvest-brief.md`, `docs/rkb-profile.md`,
  the spec, and every neighbour the spec names, in that order; drafts expert-first with
  the spec's listed primaries as its web budget; reconciles read-only against any
  connected tree the bridge names; runs the gate on its own subject; runs no git.
- The intake session reviews the diff, never the report: gate, purity grep against the
  source's own vocabulary, every anchor run through `scripts/check-anchors.mjs` against
  the tree it cites (one cited line opened by hand only where a report carries no
  quotes), `use_when` on every technique, the
  taxonomy entry appended not reordered. Then regenerate index and catalog, update the
  bundle tables, mark the spec `EXECUTED` with the overrides recorded, write the subject
  note, and commit with a pathspec - the forge's own Phase 4, run by this skill.
- `--spec-only` banks the spec without forging; use it when the operator says hold, or
  when the spec spans more than one subject, which is `/forge`'s job and not one
  worker's.

The forge worker is dispatched exactly once per spec, and it is the only agent this skill
dispatches **in the course of mining one document**. A reference index is not one
document - it is a bibliography, and Phase 2c dispatches a pool of reader workers across
its waves. The rule those workers inherit is the one that makes any of this safe:
**workers return proposals, the director writes.**

**Verify every structural claim in the spec against the authority, not against a count.**
A dispatch that names the wrong category sends a worker to build in a folder the tooling
rejects. On 2026-08-22 a spec asserted a category was flat and under its cap, from a
subject count; the category was already nested, and the placement rule forbids a category
holding both subjects and subcategories. Read `taxonomy.json` - it is the authority on
placement - and state the resolved path and the resulting link depth in the dispatch.

**Tell the worker to override you and say so.** Both workers dispatched on 2026-08-22
overrode their briefs, both were right, and both explained the reasoning in their report:
one rejected a placement preference because the neighbouring subjects' stated scopes
excluded the work, the other corrected the category error above. A brief that reads as
non-negotiable buys compliance with a mistake. Ask for the override and the argument.

**Review the diff, never the report.** Run the gate yourself, grep the upper layers for
purity against the source's own vocabulary (a game-design source is made of game titles;
a vendor talk is made of product names), confirm `use_when` on every new technique, and
run `node scripts/check-anchors.mjs <document> --root <clone>` over every anchor the
draft cites - open one cited line by hand only where the draft carries no quotes. The
check is the point, not the result. **"One cited line opened" was a sample, and the
first run of the instrument over the director's own applications found 39 of 39
anchors unresolvable as written (v2.11).**

**Check the board immediately before the first write, not at Phase 4.** Minutes have
passed and siblings have moved:

```sh
node scripts/run-board.mjs check --run <id> <every file you are about to touch>
```

Exit 3 on a *technique* file you are creating is nearly impossible and means somebody is
writing your document. Exit 3 on a *golden path* or a *taxonomy* entry is expected and
routine, because those are the shared spines every landing has to touch: take the
`content` lock, re-read the file, make your one-line edit, unlock. Never hold a lock
across drafting - only across the edit.

After content changes, regenerate **under the `index` lock**, in this order and never the
reverse - the catalog's hash covers the index, and a regeneration that runs while a
sibling is mid-write bakes their half-written subject into an artifact you then commit:

```sh
node scripts/run-board.mjs lock index --run <id> --wait 600
node scripts/build-index.mjs && node scripts/build-catalog.mjs
node scripts/check-bundles.mjs && node scripts/check-skills.mjs
node scripts/run-board.mjs unlock index --run <id>
```

**The lock serializes writers; it does not give you a private tree.** A regeneration
under the lock still reads every uncommitted file in the checkout, including siblings'.
On 2026-08-31 the regenerated index referenced a sibling's uncommitted technique six
times, and committing it would have baked their WIP into a hash in `HEAD` under this
run's name. So after regenerating, **check whether the artifact describes content that
is not in `HEAD`** — `git grep <their-slug> HEAD` — and if it does, commit your own
content and leave `index.json` and `catalog.json` uncommitted. A stale index in a shared
checkout is a known, self-correcting state; a committed hash over somebody's half-written
subject is not.

If the gate goes red inside that lock on a file you do not own, **unlock first, then
report it**. Holding the lock while you investigate somebody else's breakage stalls
eleven terminals; the red gate is theirs to fix and yours to name.

### Phase 7.5 - Apply and A/B test (mandatory per landed technique or amendment)

Phase 7 made the corpus say something new. This phase asks whether a project would be
better off if it did what the corpus now says - and answers by trying, not by asserting.
It runs once per landed `technique`, `golden-path` correction or `amendment`; a run
that lands N of those owes N rows in `librarian/applied.md`, each with a mode and a
verdict, or a stated reason in the scorecard for every row it does not owe.

**1. Find the seam.** Resolve the fleet with `loadFleet()` and keep the projects whose
declared domains include the finding's bundle. Prefer a project whose
`.ai/registry-map.json` already joins a context to the finding's subject (build it with
`node scripts/build-registry-map.mjs` if the project is registry-wired and the map is
missing); otherwise grep the tree for the decision the technique governs. The seam is
the `file:line` where that decision is currently made - or made by default because no
code owns it. Record it in the project's `.ai/applied.jsonl`, never in `librarian/`.
A technique with no seam in any managed project is not wrong, but it is **unapplied**,
and the row says so with the return condition "when a project grows the seam".

**The seam hunt is a second source (v2.8.1).** When Phase 7.5 opens a tree the corpus
already cites, diff the citations against the tree before choosing the seam, and read
the tree for where it disagrees with itself. Three consecutive runs (2026-09-08 twice,
2026-09-09) took their strongest landing from this step and not from the source: a
removed route three applications still cited, a currency row, and two keyword adapters
that defaulted the same absence to two different values. A source originates; the fleet
originates too, whenever the seam hunt opens it.

**Read the project's own EXPERIMENT ledger before designing the arm (v2.13).** Phase 4
maps a claim against the corpus for prior art and nothing, until now, mapped a proposed
*experiment* against the fleet's own measured results. Several projects keep one - a
human-gated ledger of A/B cycles with a verdict per row, a decisions log, an `.ai/`
applied ledger - and it answers a question the corpus cannot: **has this project already
tested this, and what happened?** On 2026-09-20 a run designed a render pair around the
position of a camera clause in a prompt; the consuming project's dojo ledger carried
`2026-09-02-serial-3seeds: not-better` and a runner whose own docstring said the
2026-09-02 replication *"closed text-phrasing as a lever ... the declared successor is
reference conditioning"*. The question had been asked, answered twice, and moved on
from. Find that ledger, read the rows near your question, and say in the applied row
what it said. Two specifics that make it pay:
- **A ledger dense in `not-better` is a prior, not a mood.** That one is 12 of 17. A
  candidate arriving from a source with no measurement behind it should inherit that
  base rate and be scored against it, rather than being tested as though the project had
  never looked.
- **A closed question can still be reopened - but only on a stated difference.** Name
  what is different about your arm (a different route, a different scale, a since-changed
  model), or you are paying to re-derive a `not-better` somebody already has.

**A harness-shaped finding is replayed, never simulated (v2.15).** When the finding is
a decision over tool calls, prompts, cache use or compaction, the agent harness's own
session transcripts (`~/.claude/projects/**/*.jsonl`) are an instrument with the arms
already recorded. Every tool input, tool result, usage block and compaction boundary is
there. Four runs used them (2026-09-02, 09-08, and twice on 10-02), and each returned a
measurement no simulation could have. Two rules came out of those runs:
- **Read the matched rows, never only the count.** A guard drafted from the incident
  memory was replayed over 39,940 commands before enabling. Its first draft denied
  pathspec-scoped staging, read heredoc bodies as commands and took "prints usage" for
  "handles --help"; reading the rows moved three rules by 30-40%. The same reading also
  confirmed 48 real aborts the count alone could not tell from noise.
- **A priced counterfactual measures the target, not the floor.** A replay that prices
  arm B without running it files as `unmeasurable` until the floor arm runs, however
  large the target moved.

**Where two seams are available, choose the one that could FALSIFY the finding
(v2.7).** The instinct is to pick the seam that shows the technique working, and that
seam teaches nothing the landing did not already assert. Three consecutive rounds now
say the other choice pays, and pays in a specific way - it does not merely fail to
confirm, it returns something the run was not hunting. A truncation branch chosen to
expose a missed case could not fire at the scenario's scale, and the same seam showed
a 3.5x confound sitting unnoticed in four published arms. A period-anchor seam's
control broke exactly where the technique predicted it would, which is what made the
correction worth writing. A per-capability reach test written to check a spend rule
found a live second instance in a plan nobody was looking at.

**Before committing to a falsifying seam, say what a CAUGHT outcome would teach. If the
answer is "nothing", the arm is a confirmation wearing a falsifier's name** - the seam
has to be able to return a result that changes what the landing says, or picking it is
theatre. Then **say in the applied row that the seam was chosen to falsify, and say what
it refuted** - including when the answer is "the finding held": a seam that could have
killed the technique and did not is stronger corroboration than a seam that was never at
risk. (Converged on independently by two runs on 2026-09-07, from different sources,
within one hour; the pre-check is the sibling's half.)

**2. Choose the highest reachable mode, and say why not the one above it.**

| Mode | What A and B are | What the verdict is read from | Reachable when |
| --- | --- | --- | --- |
| `code` | the seam as it is (A) vs the seam with the technique applied (B), behind a flag, a branch, or a worktree | the project's own gate, a metric the project already emits, or a before/after run of the same inputs | the change is a few readable lines, the project has a gate or a metric that can see the difference, and the tree has no foreign WIP in the files touched |
| `experiment` | the same inputs run twice through a harness that does not change product code - a script, an eval slice, a replayed session, a dry-run of the hook against recorded actions | the harness's output, counted with its predicate | the technique's effect is observable without shipping it: hooks, gates, prompts, thresholds, routing rules |
| `simulation` | three concrete cases pulled from the tree or its history - a real incident, a real PR, a real failing run - walked under policy A and policy B, one paragraph each, with the predicted outcome and **what would falsify the prediction** | your own reasoning, labelled as such | nothing above is reachable in this run: no gate can see the effect, the seam is in a tree you may not edit, or the cost of the experiment exceeds the run |
| `task` **(v2)** | the seam as it is (A) vs a **scoped work item** the project would execute to adopt the mechanism (B): a plan in the project's own `.ai/` with the files it touches, the size in files and lines, the measurable it moves, the gate that will see it, and the first step already taken on a branch | the plan's measurable, read from the project's gate once the branch runs; until then the size estimate and the first step's own result | the finding is a design decision or a subject-level mechanism whose adoption is larger than a few readable lines - the case the three modes above cannot express, and the case every design candidate produces |
| `render` **(v2.9)** | one brief rendered through the corpus-before instruction (A) and the corpus-after instruction (B): one variable, same seed, anchors, model and length | the operator's blind pick from `render-triage.mjs sheet`, revealed onto the arms; the director's frame pre-read is recorded as opinion, never as the verdict | the finding is render-bound (Phase 6b). **Mandatory there, and it outranks every other mode** - a render-bound finding may not substitute `simulation`, and it runs before Phase 7 lands, not after |

A simulation with three cases from a real tree beats a code A/B against a toy. A
simulation with invented cases is an opinion and does not count as applied.

**3. Record the verdict in a closed vocabulary**, inherited from the sweep lane's
measured Before/After rule: `better` / `not-better` / `unmeasurable`.

**A verdict is read against two declared numbers, not one (v2.11).** Name the
**target** - the number the technique says will move - and the **floor** - the
number that must not move by more than a stated tolerance, usually the outcome the
project exists to produce: tasks solved, tests green, verdicts unchanged. `better`
means the target moved *and* the floor held; a target that moved while the floor
fell is `not-better`, whatever the target says. The rule comes from a harness
optimization loop that accepted a mechanism only when every capability metric
stayed inside its predeclared tolerance and at least one efficiency metric improved,
and whose own release table shows why the floor has to be declared beforehand: one
configuration cut cost by a quarter and solved three fewer of sixty-three tasks. A
row with no floor declared says so in its return condition.

- `better` -> Phase 8 ships it (code) or files it as the project's next change
  (experiment, simulation), and the application document carries `applied: <mode>`
  and `ab_verdict: better`.
- `not-better` -> **a rejection, and the most valuable row in the ledger.** The
  technique is not deleted; it gains an amendment stating the condition under which
  it did not hold, written from what the seam showed, and the row names the seam class
  so the next run does not re-run the same test. Two `not-better` rows on one technique
  from different projects demote it to a lead.
- `unmeasurable` -> stays applied at the mode reached, with a return condition naming
  the instrument that would make it measurable. A run may not report `unmeasurable`
  without naming that instrument.

**4. Write the application document** the way Phase 8 already requires - you opened
a tree, so `verified_on` and `verified_against` are facts - and add two frontmatter
lines: `applied: code|experiment|simulation|task|render` and `ab_verdict: better|not-better|unmeasurable`
(a `render` row adds `grader: operator`).
The body carries what A and B were and what was read; the seam's `file:line` only if
the project has made that code public, per Phase 8 step 7.

**5. Append the row** to `librarian/applied.md`: date, technique slug, project slug,
mode, verdict, return condition. Slugs and dates only. This ledger is what `/intake
apply` reads to find techniques that have never been applied, oldest first, which is
the backlog the wiki has been quietly accumulating.

**Budget.** One project per finding per run; the highest mode reachable; at most the
effort of the landing itself **for a claim**. A finding whose apply step would cost
more than its landing is still owed a `simulation` row - three real cases take twenty
minutes and that is the floor, not an excuse. **A design candidate is budgeted the
other way round (v2):** its apply step is a `task`, sized against the project and not
against the landing, and a repository run carries three times a video run's budget for
this phase. The v1 budget was written for a source that reports; applied to a source
that is a system, it guaranteed that no project ever changed by more than a few lines,
and eight of twelve apply rows were simulations or structural-only reads.

### Phase 7.6 - The direction pass (v2.1: new capabilities, human-gated)

Phase 7.5 asks whether a project would be better off doing what the corpus now says at a
seam it already has. This phase asks the question 7.5 cannot: **which project has no
seam at all for a capability this source shows matters** - and proposes one, never
builds one. It runs once per design-record entry (Phase 2d) whose `corpus:` line names a
subject, and it reads one instrument:

```sh
node scripts/build-fleet-map.mjs --check || node scripts/build-fleet-map.mjs
```

`librarian/fleet-map.json` is the map of context maps and its inverse
([`docs/fleet-map.md`](../../../docs/fleet-map.md)): for every subject, the projects
that have a context it governs and the projects that do not, each absence classified
against the project's manifest `scope:` block and its directions ledger. Only an absence
classified `candidate` is eligible. For each one, the judgment step - and it is a
judgment, stated so it can be reviewed - is:

> Does this project's `scope.does` admit the decision's **forces**? Not its feature: the
> forces. A project that never faces the trust boundary, the scale, or the operator
> constraint the decision answered has no direction here, whatever its domain says.

Where the answer is yes, write a **direction proposal** into the project's own tree,
`.ai/directions/<date>-<subject>.md`, in the fixed shape the doc gives: why the scope
implies it, what the first context would contain and must not absorb, the measurable,
the falsifier, a size. Commit it with a pathspec on the project's active branch. **Do not
build it, do not open a task row for it, do not add it to the registry map.** The owner's
decision arrives as a row in `.ai/directions/ledger.jsonl`, and the next fleet-map run
reads it: `accepted` becomes a `task` row for the next intake, `declined` is never
re-proposed, `deferred` carries its return condition.

Three rules keep this lane from becoming a feature-request generator:

- **At most three proposals per run**, ranked by how many of the design record's
  entries the same project is a candidate for - a project absent from four decisions of
  one system is the one with the direction, not four projects absent from one each.
- **A proposal cites the source's forces, never its features.** "The source has a plugin
  system" is not a reason; "this project loads operator-supplied code at the same trust
  boundary and isolates nothing" is.
- **Record the ones you did not write.** Candidates that read as admitted but were
  cut by the cap go in the source note under "Directions not proposed", with the project
  and the reason, so the fleet map's next sweep can pick them up without re-deriving.

A run over a source with no design record (a video, a listicle) skips this phase and
says so in the scorecard's depth cell (`directions=n/a`).

**The peer shape (v2.2).** When a fleet project's `scope.does` names the same class of
system the source *is* - an agent runtime and an agent runtime, a provider gateway and an
observability service that ingests what the gateway emits, an engine multiplexer and an
engine multiplexer - three proposals is the wrong cap, and the operator will say so
mid-run if the method does not. For a peer, the pass writes a **comparison study** in
the project's own `.ai/directions/` (`<date>-<source>-comparison.md`): 25-45 points
grouped by area, each with file:line on both sides and a verdict from the closed set
`adopt` / `adapt` / `keep ours` / `different forces` - with the reason on every verdict,
because `keep ours` is expected to be the largest class and is worthless without it. The
study closes with the tests to initiate (paired, instrument named, the number that would
move), the features ranked with why the scope admits each, and the inverse list of what
the project does better. The three-proposal cap then applies to the study's ranked
features, not to the pass. The front-half worker runs the peer check and seeds 8-12
points; the study worker expands them against the project's own tree and is expected to
correct seeded points against it. Three rounds established this shape (2026-09-02:
personas, tracklight, pumper); a study is dispatched, never written by the director.

### Phase 7.7 - The decision gate (v2.3: the operator decides in one screen, execution follows in the session)

A proposal nobody reads is a wiki page with a schema. Under 2.1 and 2.2 the direction
pass wrote twelve proposals across five projects in twenty-four hours and zero ledger
rows were written, because the decision lived in a file the operator had to go and
find. The gate moves the decision into the run.

**When.** After Phase 7.6 has written this run's proposals, and before Phase 9. If the
run is unattended, skip the gate and say so in the depth cell (`gate=skipped`); never
decide on the operator's behalf.

**What is shown.** Every proposal with `status: proposed` across the fleet - this run's
and every earlier run's still waiting - grouped by project, as a **multi-select**: one
question per project (up to four projects per screen; a fifth waits for the next run),
each option one proposal with its slug as the label and one line of description carrying
the registry subject, the mechanism, and the size from the proposal's frontmatter.
Selected means **accepted**; unselected means **declined**. There is no third state on
the screen - a proposal the operator wants to think about is declined now and may be
re-raised by a later run, because "deferred" is how the twelve accumulated.

**What is written.** One ledger row per proposal in the project's
`.ai/directions/ledger.jsonl` (`accepted` or `declined`, reason
`operator multi-select review <date>`), the proposal's `status:` line updated, committed
in the project with a pathspec. The fleet map reads the rows on its next regeneration, so
a declined direction is never re-proposed and an accepted one leaves the candidate list.

**What executes.** Every accepted proposal is dispatched to its own worker **in the same
session** - one worker per proposal, in an isolated worktree of the project
(`git worktree add C:/t/w-<project>-<slug> -b direction/<slug>`, short path, per the
long-path rule) so nine workers can run against five checkouts without sharing one.
**When two accepted proposals in one project name the same files** (the seam line in
their `stage:`), they go to ONE worker on ONE branch (`direction/<run>-round<n>`),
executed in order with one commit and one applied row each - parallel branches over
one file only move the merge conflict to the director (v2.3.2, learned when eleven
proposals across four projects shared a chart checker, a claim statement and an error
enum). The
worker reads the proposal as its spec, the project's own account of itself, and the
registry subject it implements; builds the proposal's "first context" within the stated
size; writes the tests the proposal's measurable implies; runs the cheapest gate that
sees the change; appends one `task` row to the project's `.ai/applied.jsonl` with the
verdict read from the gate; commits on the worktree branch with a pathspec and the
project's own commit convention, never bypassing a hook, never pushing. The director
reviews each report against the diff (the gate ran, the row's verdict matches what the
gate said, the size did not creep), records the branches in `librarian/applied.md`, and
removes the worktrees. **Then the director merges (v2.3.1).** The operator's acceptance
at the gate was the human decision; a second one at merge time is a gate nobody asked
for, and the branches it produced sat unmerged until the operator said so. The rule:

- a branch whose gate ran **green** is merged into the project's active branch with
  `--no-ff` and a message naming the gate date, in the session, right after the review;
- a branch whose gate is **red, or could not run** (a missing toolchain, a test binary
  that will not launch) stays a branch, with the reason in its applied row and in the
  report - the operator merges that one by hand or asks for a second pass;
- `.ai/applied.jsonl` conflicts between sibling branches are append-only ledgers and are
  resolved by **union** (ours, then every line of theirs not already present), never by
  choosing a side; a concurrent session's uncommitted rows in the main checkout are
  committed first as their own change, never stashed or overwritten;
- **never push.** The operator pushes after reading the log, as for every other commit
  this method makes.

Workers are the default model for this phase, as for every phase but the director's
review.

**Budget.** The gate costs one screen. The execution costs one worker per accepted
proposal, and the operator chose the count. A run that lands in the registry and then
executes the fleet's accepted directions has closed the loop this whole method exists
for: research → extract → test → apply → ship, with the ship decided by the person who
owns the tree.

### Phase 8 - The cross-repo lane (default for `code` and `better`; confirm before editing)

**Two lanes (v2.1).** A *coverage* change - a `code`, `experiment` or `task` row against
a seam the project already has - ships on the recommendation under the rules below; the
project's own gate is the review. A *direction* - a new context, a new capability - never
ships from a run: it is proposed in Phase 7.6 and waits for the owner's ledger row. The
two are not a matter of size. A one-line change that creates a capability the scope
does not name is a direction; a two-hundred-line refactor inside a governed context is
coverage. When a `task` row's plan would create a context the registry map does not
have, split it: the proposal goes to `.ai/directions/`, the rest stays a task.

A finding can land in the registry AND in a project that consumes it. That second half
is a different repository with its own review, so it is gated separately and never
assumed. Phase 7.5 decides *whether* a project change is warranted; this phase governs
*how* it is made.

1. Resolve the project with `loadFleet()` from `scripts/lib/projects.mjs`. Do not guess a path.
2. **No confirmation is needed for a coverage change where the run has identified
   the impact** (standing operator rule, 2026-09-04; see Phase 5). Identify the
   seam, prove it per step 3, and commit per step 4. The gates that remain are the
   proof and the project's own test suite, not a question. A *direction* still waits
   for its ledger row, and a diff too large to read in one sitting still takes a
   branch - those two are the whole of what is still gated.
3. **Pair the proof before the commit - at any scale, but never at none.** A registry
   technique is a claim about a standard; a change to a connected project is a claim
   that the technique *improves that project*, and the second claim is not evidence
   for itself. Before any cross-repo commit, run a **paired comparison** on the tree
   and record it in the application document under a `proof:` field.
   - **Name the measurable first, and the floor beside it** - the number the
     technique says will move: a split, a rate, a latency, a count of violations, a
     token cost; and the number that must hold within a stated tolerance while it
     moves (Phase 7.5 step 3, v2.11). No measurable, no commit; a change whose effect
     cannot be named is a lead, not a landing. A target that moved over a floor that
     fell is `not-better`.
   - **Prefer A/B: the same input through both arms**, with and without the change,
     on the same instrument. Any scale is admissible - one prompt, one fixture, one
     session - as long as both arms exist and the arm count travels with the number
     (the `count-carries-predicate` law). The 2026-08-27 playground that measured a
     channel split 67/33 was an in-run A/B at n=1, and it decided the landing.
   - **Fall back to before/after only when a control is impossible**, and then under
     the rules the corpus already holds for that shape
     (`adoption-measurement/before-after-outcome-pairing`): the same instrument on
     both sides, the change instant fixed, and **never invent the missing half** - a
     missing baseline is a `no-before` status, not a cohort average.
   - **Write the status from a closed set**: `ab-paired`, `before-after`,
     `structural-only` (step 6 found the structural fact and no behavioural arm was
     runnable), `unproven`. `unproven` does not commit: the diff stays uncommitted
     or goes to a branch, and the note says what proof would take.
   - **A negative proof is a landing too.** Two arms that measure no difference are
     the application's most useful sentence - the reader is deciding whether to copy
     the technique, and "it did not move X here" is worth more than a bookmark.
   The proof measures the *impact* on this tree; the structural fact in step 6
   measures whether the tree *confirms the standard*. They are different claims, and
   an application may carry either without the other - but a cross-repo commit needs
   the first.
4. Commit atomically **with a pathspec** on the project's default branch - the fleet
   has one owner and one machine, so a branch-and-PR round trip protects nobody (see
   the single-owner doctrine in memory). The two exceptions: the tree has another
   session's uncommitted work in files you touch, or the change is larger than a few
   lines a reviewer can read in the diff - then a branch, and say why. **A `task` row
   always takes the second exception (v2):** its first step lands on a branch named
   for the run, the plan is committed beside it in the project's `.ai/`, and the row
   in `librarian/applied.md` names the branch so the next run - or `/intake apply` -
   can continue it. **Never push** from a run; the operator pushes when they have read
   the diff.
5. The registry-side artifact of a project change is an **application document**: you
   opened a real tree, so you are one of the few things allowed to write `verified_on`
   and `verified_against` truthfully. Write them, and write the `proof:` status from
   step 3 beside them.
6. **Look for the structural fact that confirms or refutes the technique, not just for a
   place to point at.** An application whose content is "here is where this happens" is
   a bookmark. The valuable one reports something the tree's *shape* says about the
   standard - and the strongest form is negative. On 2026-08-22 a technique claimed one
   term of a four-term model is the one nobody can set; the tree turned out to carry a
   module context for every other term and none for that one, because nothing in a
   codebase can own it. Nobody designed that; it fell out of the structure, and it is
   better evidence than the code the run had just added. Ask what the tree could not
   have been built to prove, and whether it proves it anyway.
   **The verdict being "no" does not cancel this step - it is often what creates the
   fact.** On 2026-08-27 the consumer assessment came back do-not-adopt, and the tree
   turned out to hold exactly two destinations for the input in question, both
   disqualified by the technique's central rule, which nobody had designed. A negative
   application built from that is better evidence than an adopting tree would have
   given. Write it.
   When the technique is a *contract*, the structural check has a specific shape:
   **enumerate the CALLERS of the optional half.** A compiler no call can skip proves
   only the mandatory half - on 2026-08-27 the text half of a two-channel contract was
   enforced that way while the image half rode an optional field, so production had run
   text-only for weeks beside a playground that measured the split 67/33.
7. **Write what the realization CANNOT do.** A stack that judges rather than measures
   should say so in the application, because the reader is deciding whether to copy it.
8. Never copy a project's paths, repo names or internals into a published registry
   file. The application layer may cite code the project has chosen to make public;
   `librarian/` and the upper layers may not cite it at all.

### Phase 9 - Persist

Everything in this phase except the source note and the subject notes is an **append to
a file every sibling also appends to**. Take the `ledger` lock once, re-read each file
inside it, append, unlock - all of it in one short hold. A ledger read at Phase 1 is
stale by now, and appending from that stale read silently deletes whatever landed in
between.

```sh
node scripts/run-board.mjs lock ledger --run <id> --wait 600
#   re-read, append: librarian/sources/index.md, librarian/applied.md, SCORECARD.md
node scripts/run-board.mjs unlock ledger --run <id>
```

The source note and the subject notes are yours alone (`<date>-<slug>.md`,
`<domain>/<subject>.md`), so they need no lock - except a subject note a sibling also
touched this session, which is an append like any other. Delete this run's scratch
directory **by its run id**, never by sweeping the scratch root.

- **Source note** `librarian/sources/<YYYY-MM-DD>-<slug>.md`: frontmatter (`source`,
  `kind`, `url`, `title`, `author`, `words`, `extracted`, `accepted`, `declined`,
  `leads`, `already_covered`, `untriaged`, `dispatched`, `run_id`, `siblings`), then one
  block per candidate with its outcome and, for declines, the reason. `siblings` is how
  many runs were live on the board when this one started, and it is the field that
  explains, six weeks later, why two notes from one afternoon disagree about what the
  corpus contained. A decline nobody wrote down gets re-proposed
  every run forever.

  **A run that lands a candidate from an EARLIER note edits that note too**, in the
  same commit: strike the row from its untriaged table and decrement its
  `untriaged` counter. This is not bookkeeping. The harvest backlog is enumerated
  from those tables, so a table left standing after its candidates were forged
  turns landed claims into backlog rows, and a worker is spent re-deriving
  something the corpus already says. Measured 2026-09-17: one note's twelve
  candidates were forged in a single run, the note kept `untriaged: 12`, and all
  twelve became backlog rows - `node scripts/backlog-phantom-screen.mjs` reports
  the notes this has already happened to. A `--delta` re-scan of the same source
  updates the original note rather than opening a second one.
- **Source ledger** `librarian/sources/index.md`: one line per mined source. This is
  what makes "already mined" a one-second check next time. The source note's
  frontmatter also carries `applied: <n>` and `shipped: <n>` beside `accepted`.
- **Applied ledger** `librarian/applied.md`: one row per Phase 7.5 test (technique,
  project slug, mode, verdict, return condition). The unapplied backlog is every
  technique in the index with no row here.
- **Scorecard** `.claude/skills/intake/SCORECARD.md`: one row per run with the five
  stage counts - research (sources), extract (candidates), test (picks verified),
  apply (rows, by mode), ship (project commits) - the reason for any zero in the
  last two, the admission cell (v2.5: `auto=<accepted>/<rejected>/<escalated>` and
  `fp=<n>`, the count of auto-accepted rows that died at Phase 6), **and the depth
  cell (v2)**: `subjects/techniques/amendments/apps-vs-source/
  task-lines`, plus the routing count from Phase 2d and whether the run handed off.
  Five one-paragraph amendments and one subject no longer score the same.
- **Run result** `librarian/runs/<run-id>/result.json` - the same run, for a program.
  Everything above is written for a reader, and a dispatcher can read none of it: a
  landing, a leads-only pass and a refusal are indistinguishable from outside. Write it
  through the helper that owns the rules (public-safe paths, a decline with its reason,
  unknown fields rejected, atomic placement), using this run's board id:

  ```sh
  node scripts/lib/run-result.mjs write <draft.json>   # -> librarian/runs/<run-id>/result.json
  ```

  This skill fills it from figures it already has: the five `counts` from the triage
  table (`contended` is the Phase 0 exit-3 case), `declined[]` from the decline ledger -
  **`untriaged` is not `declined`**, here exactly as everywhere else in this file - one
  `subjects[]` row per landing, and `verdicts[]` straight from Phase 7.5's
  `better` / `not-better` / `unmeasurable` / `COVERED` at the mode it was measured at
  (`code` / `experiment` / `blind-ab` / `simulation` / `render`). **A subject row's
  `outcome` is the counts vocabulary, not this skill's five outcomes** - `landed` /
  `declined` / `idled` / `contended` / `dispatched`, so a currency reset and a technique
  are both `landed` here and the triage table stays the place that tells them apart. `pr` is **null**: Phase 10 commits
  direct to `main`. List the commits made so far and let Phase 10 carry this file in its
  pathspec; the commit that carries it cannot name itself. `files[]` and
  `commits[].pathspec` stay the **registry's** own paths - a Phase 8 landing in a project
  tree is a `subjects[]` row, never that repo's file list, because this lane is public.
- **Subject notes** `librarian/subjects/<domain>/<subject>.md` for every subject
  touched, same shape `librarian` writes.
- **Leads** carry a return condition. "When the model is actually released", "when a
  connected project adopts it", "when a second independent source says it".
- **`rescan_when:` is MANDATORY on a repository-class source note**, and it is the fuel
  of the upstream lane rather than a note to yourself. `/librarian` reads these on every
  sweep (`scripts/upstream-check.mjs`); nothing runs that check on a clock yet - the weekly
  CI cron does not call it - so a condition fires only when someone runs a sweep. A
  repository mined without one can only ever come back on its tier's floor. Name an upstream event where you can - a PR landing, a
  flag leaving a debug gate, a changelog section appearing - and add a date fallback in
  the readable form `; or 8 weeks elapse (YYYY-MM-DD)`. The instrument decides exactly
  two clauses mechanically, a release landing after the mine and a deadline date passing;
  every other clause it reports as `undecidable` for a human, and it will never claim
  your prose fired. A delta re-scan owes the next condition the same way.
- Public-safe, like every note in that vault: slugs, scores and dates. Never a
  consumer's paths.

### Phase 10 - Commit

- **Direct to `main`, with a pathspec.** Since the 2026-08-23 single-owner redesign
  the registry commits routine work straight to `main`; the gates (`check-bundles`,
  `check-skills`, `build-index --check`) are the review, and the operator pushes after
  reading the log. A branch is for a run whose diff is too large to read in one
  sitting or that the operator asked to hold back - not the default.
- **Take the `commit` lock, and hold it for the commit only.**

  ```sh
  node scripts/run-board.mjs lock commit --run <id> --wait 600
  git add <your new files by name>
  git commit -m "..." -- <your paths>
  git grep <slug> HEAD -- <path>                  # verify inside the lock
  node scripts/run-board.mjs unlock commit --run <id>
  ```

  Git's own index (`.git/index`) is a single shared file: two concurrent `git add`s
  produce `index.lock` errors at best and a commit carrying a sibling's staged work at
  worst. The lock costs seconds and removes the whole class.
- **Check for parallel sessions before touching the tree** - `run-board.mjs list`, plus
  `git status --short` for anything the board does not know about (an operator editing
  by hand is not on the board). This checkout is routinely shared: on 2026-08-21 another
  session switched the branch out from under this one mid-run, and on 2026-08-23 a
  directory-wide `git add` swept a sibling's in-flight instrument into a commit. Never
  switch the branch. If a branch is needed after all, take it as
  `git worktree add <short path> -b <branch>` - keep the path SHORT, the deepest bundle
  paths blow past the platform limit under a scratch-directory prefix, and the board
  follows you into the worktree because it lives in the git common directory.
- **Commit with a pathspec**: `git commit -m "..." -- <your paths>`. A worktree isolates
  the checkout but shares the object store and the branch namespace, and a pathspec-less
  commit still takes whatever is staged.
- **`git add` your NEW files first, by name.** A pathspec commit only sees paths git
  already knows, so every new document - the technique, the application, the source
  note, the subject note - fails the commit with `did not match any file(s) known to
  git` until it is staged. Stage them explicitly, never with `-A`, then commit with the
  pathspec. This bites once per run and the error is easy to misread as a bad path.
- Treat any modified file you did not touch as live WIP. Never `git add -A`.
- Close by verifying each shipped artifact is in `HEAD` (`git grep <slug> HEAD -- <path>`),
  **inside the lock**, not by trusting that the commit command succeeded. A parallel
  session can rewrite history and drop your content back into the working tree, where the
  gates still pass. Verifying after the unlock re-opens exactly that window.
- **Release the claim when the run ends**: `node scripts/run-board.mjs release --run <id>`.
  A record left behind makes every sibling cautious about subjects nobody is holding for
  the next 45 minutes.

### Phase 11 - Skill Reflection

After the run's real work is done, reflect - autonomously, without asking the operator.
The shape is the one every shared skill under `skills/` runs (the `skill-reflection`
clause); this file is not stamped by that machinery because it lives under
`.claude/skills/`, so the clause is restated here and kept in step with
`docs/skill-clauses/skill-reflection.md` by hand. Be honest about volume: most runs
produce nothing beyond lane 0. An empty reflection is a valid result; a forced lesson
is pollution. Calibration: nothing (common) / one line (sometimes) / a lesson entry
(occasionally) / a redesign proposal (rare).

`SCORECARD.md` and `LESSONS.md` are shared append targets like any ledger: take the
`ledger` lock, **re-read the file inside it**, append, unlock. Twelve runs reflecting at
once onto one scorecard is where the funnel measurement quietly loses rows, and a lost
row is worse than no row - it makes the weakest-stage reading wrong rather than absent.

**Lane 0 - the scorecard, every run, no exceptions.** Append one row to
`SCORECARD.md`: version used, date, source slug, and the five stage counts -
`research` (sources ingested), `extract` (candidates), `test` (picks verified),
`apply` (rows by mode, e.g. `1c/0e/2s/1t/0r`), `ship` (project commits), and `depth`
(v2: `S/T/A/Asrc/task-lines` with the Phase 2d routing count and the handoff
decision; v2.1 adds `directions=<proposed>/<not-proposed>` or `n/a`). A zero in `apply` or `ship` carries its reason in the row. Then read the
last ten rows and name, in one line under the table, **the stage the funnel is losing
most at** - that stage is the next run's declared focus, and the next run's row says
whether it moved. Read the depth column across the same ten rows and say whether the
run's shape matched its source's: a system that yielded only amendments is a routing
miss, and it is named as one. This is the
mechanism by which the pipeline is mastered rather than merely repeated: the funnel
is measured, the weakest stage is named, and the method edits (lane 2) are aimed at
it instead of at whatever the last run happened to notice.

**Lane 1 - PROJECT learnings** (what the next session in a managed repo needs).
Anything Phase 7.5 or 8 learned about one project - where its seam is, which gate can
see which effect, what it has no instrument for - goes to that project's
`.ai/applied.jsonl` and its own overlay, never into this file or into `librarian/`. A
project's bytes in a shared method are what made the fleet's skill copies diverge.

**Lane 2 - METHOD learnings** (what would improve this skill for every source and
every project):
1. If nothing generalizes beyond this run, stop here.
2. Append to `LESSONS.md`: `## <version used> - <YYYY-MM-DD> - <source slug>` followed
   by `- ` bullets. Record the version the run **used**, never a bump target. Wrap a
   bullet in a `### Redesign proposal` sub-block when it argues for a redesign you are
   not applying now. A lesson alone needs no version bump.
3. Edit `SKILL.md` only together with a version bump, and bump only with an applied
   edit: patch for wording, minor for a step or a prompt refinement, major for a
   methodic redesign. A lesson that the scorecard has confirmed three runs running is
   a rule this file carries; until then it stays a lesson.
4. Ask the operator once, batched, why declined picks were declined. A decline reason
   seen three times is a rule this file should carry.
5. Commit the skill's files in their own commit with a pathspec, after
   `node scripts/check-skills.mjs` passes and under the `commit` lock.
6. **A method edit is the one change a parallel fleet cannot absorb quietly.** Eleven
   sessions are reading this file right now, from the version they loaded at their own
   Phase 0. Bump the version, say in `LESSONS.md` what a mid-flight run should do about
   it (usually: nothing, finish on the version you loaded), and never edit `SKILL.md`
   from two runs in the same afternoon without one of them reading the other's diff
   first - the board makes that visible if you claim
   `--path .claude/skills/intake/SKILL.md`.

**Lane 3 - DOMAIN knowledge** is a different artifact from a lesson: a lesson improves
this method, a lead proposes knowledge for a bundle. Intake IS the lane that turns leads
into knowledge, so a domain observation from reflection is filed as a lead in the source
note with a return condition - not landed from the reflection step, which has no
corroboration behind it.

## Anti-patterns

- **Letting a video author an upper layer.** The one failure that damages the corpus
  rather than just wasting a run.
- **Mining a system with the news method.** Twelve runs, six systems, zero subjects.
  A repository whose routing count is three or more is a forge job; read its design,
  write the record and the source-tree applications, and hand off.
- **Reading a repository for sentences.** A design decision is reconstructed from
  forces and alternatives, not quoted; if the design record is empty over a tree with
  an ADR directory, the sweep read the ad.
- **Landing a mechanism as a paragraph.** An amendment is for a boundary case. A
  mechanism the corpus lacks gets a technique, and three with one home get a subject.
- **Mining a repository at its README.** The ingest returns the landing page; the
  landing page is the one file in the tree written to be quoted. Clone it (Phase 2b),
  sweep the operating documents, the instrument, the measurement and the types, and
  read the README last. A repository note whose `words:` is one small number and whose
  body cites no file from the source's tree is this anti-pattern with a frontmatter.
- **Reading a tree only for claims.** The instrument, the schema, the test strategy and
  the failure taxonomy are the half that a quote-hunting pass never sees, and they are
  the half that lands in `scripts/`, `practices/` and `docs/`.
- **Landing a technique and walking away.** A technique with no `librarian/applied.md`
  row is a wiki page; a run that lands three and applies none has enriched a wiki.
  The scorecard row makes this visible; do not make it normal.
- **Simulating with invented cases.** Three cases from a real tree or its history, or
  it is an opinion with a table around it.
- **Landing a generation instruction nobody rendered.** In a render-bound bundle the
  output is the only instrument. A technique that changes what a generator is told, and
  was never rendered through both arms and triaged by the operator, is a guess with a
  citation. Render, triage blind, record the verdict, then delete the renders.
- **Animating a subject nobody checked.** A torn or half-weighted rig is inherited by every
  arm; the pair then tests the rig. Run `rig_check.py` at the action's extreme poses first, and
  never take a rig's rigidity from the report of the pass that built it.
- **Grading your own render proof, or deleting renders before the verdict.** The first
  launders the director's preference into the corpus; the second throws away the only
  thing the render was for.
- **Letting the discrimination gate end the run (v2.12).** A refused ratio withholds the
  landing, not the artifact. A media-generation intake that reports a number and shows the
  operator nothing has asked them to take its word for the one judgment the method reserves
  for them - and where the ratio was refused *because* the seeds disagree, that
  disagreement is exactly what they should be looking at.
- **Choosing the seam that flatters the finding.** Where two seams exist, the one that
  could falsify it is the one that returns something the landing did not already say.
- **Reporting `unmeasurable` without naming the instrument** that would have measured
  it. That word is a return condition, not a shrug.
- **Padding the findings list.** Nine catches and one lead is a result. Report it.
- **Proposing what the bundle already says.** Phase 4 exists to prevent this; skipping
  it to save a second costs a whole verification round.
- **Scoring a row into a category that is full.** V1 is the first veto for a reason:
  the count is free before drafting and a whole forge dispatch after it.
- **Letting the score overturn a veto**, or auto-accepting an `XL`. The vetoes and the
  escalations run first and are absolute; the arithmetic only ranks what survives them.
- **Reporting `auto=` without `fp=`.** A gate that never counts its own false positives
  drifts toward accepting everything, which is the failure the human gate was there to
  prevent and the reason it was replaced by a measured one rather than by nothing.
- **Constructing a subject path** instead of using the index's `file`.
- **Writing `verified_on` for a tree nobody opened.** That is the one field whose only
  value is that it is a fact.
- **Treating a currency signal as a content gap.** "The world moved" is a clock reset
  or a dispatch, not a new technique.
- **Pushing a connected project's branch**, or shipping a *direction* into one
  without its ledger row. Editing a tree where the run identified the impact is
  authorized standing (Phase 5) and is no longer an anti-pattern; asking again
  for permission the operator has already given is.
- **Banking an XL spec and ending the session.** The context that argued the spec is
  the cheapest forge input the registry will ever have for it; dispatch before Phase 9
  unless `--spec-only` was asked for.
- **Committing to a connected project on an unpaired claim.** A technique landing in
  a tree is a measurement with two arms, or it is a branch.
- **Committing without a pathspec in a shared checkout.**
- **Running without a board claim.** An unclaimed run is invisible to eleven siblings
  and sees none of them; every collision rule in this method degrades to hope.
- **Appending to a ledger from a read taken before the lock.** The append succeeds and a
  line ceases to exist. This is the parallel failure that never announces itself.
- **Regenerating the index outside the `index` lock**, or regenerating "to be helpful"
  over files you do not own. The catalog's hash covers the index; a regeneration over a
  sibling's half-written subject bakes their WIP into an artifact you then commit under
  your name.
- **Switching the branch.** Not once, not briefly. Take a worktree.
- **Sweeping the scratch root at cleanup** instead of deleting this run's own directory
  by its run id.
- **Holding a lock across thinking.** Locks cover an edit, an append, a commit - seconds,
  never a drafting pass. A lock held across a verification round stalls the whole fleet
  and gets broken at its TTL anyway.
- **Mining a reference index at its top three links.** The list IS the source; three of
  its two hundred pointers is a sample, not an extraction. Enumerate all of them, rank
  them, and run waves.
- **Letting a wave worker write.** Workers return proposals. The director writes, holds
  the locks, and owns the diff.

Files in this skill

  • references/memory-lane.md11.1 KB
  • references/reference-waves.md12 KB
  • references/render-proof.md18.3 KB
  • references/render-proof/pose_sheet.py11.2 KB
  • references/render-proof/rig_check.py15.8 KB
  • references/render-proof/sheet_distance.py4.3 KB
  • references/source-classes.md27.8 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.