--- name: docs-refresh-scout-summaries description: "Refresh a stale documentation cluster without delegating the writing: scout subagents produce per-line verdict tables (holder verified by comma-insensitive grep), the parent makes every edit, and a port-before-cut census proves nothing was lost. Use for dedupe-our-docs, fix-the-stale-runbooks, pointers-instead-of-copied-numbers jobs." --- # Refresh stale docs with scout summaries, parent-side writes Use when a cluster of documentation pages is stale and/or restates facts another page owns, and the fix touches many files. **Scouts read and classify; the parent writes.** Sibling skill `vault-one-fact-one-owner-dedupe` covers collapsing era pages into owner pages - its section 3 (orphan census), section 7 (edit-tool hazard) and section 9 (verify/PR) apply unchanged. ## Why not writer subagents (measured cost) Writer agents produce plausible output and cannot be trusted on the one claim that matters - the owner page already holds this fact. In one run they asserted every cut was grep-confirmed while FOUR cuts left pointers to pages that did not contain the fact (118->238 GiB, 16,095 tokens, 0.739/0.554/0.427/0.340, PR #23897). Each became a broken promise the next reader trusts. Classification is the only part that parallelizes; writing is where taste (ownership, era naming, what counts as a law) lives. So fan out read-only scouts and keep the pen. If writer agents were already spawned and are no longer wanted: `write agent://all` to stop them, then `git status` the target tree - `proc://` does not list agent jobs, and a finished worker may already have edited files. ## Pipeline 1. **Cluster** targets into groups of 3-4 pages sharing subject matter (one cluster per scout). Know the owner map first (endpoint/service/host pages, plus the repo documentation law). 2. **Wave of 2 scouts** (harness cap is `task.maxConcurrency`, usually 2). Scout contract: > READ-ONLY, no writes of any kind. Per file, one table row per candidate fact: > `| lines | verbatim figure + 6 words | holder elsewhere (file:line) or none | VERDICT |` > Verdicts: `CUT -> [[Owner]]` (holder verified), `KEEP(owned here)` (no holder, this page is > the record), `PORT(parent)` (rightful owner lacks it - name page and section), `STALE` > (contradicted by current state; quote the contradicting line), `INDEX` (locator page). > Verify every holder claim with a COMMA-INSENSITIVE grep: a holder writing 1,350,182 > satisfies a page writing 1350182 and vice versa; 16,095 does NOT satisfy a check for 16095 > unless commas are stripped. Never name a holder line you have not read. > End with a per-file tally: kept / cut / port / stale. Put the law, the owner map and the verification rule in the batch-level `context`, never per task. 3. **Write while the next wave runs**: edit cluster N from wave N, launch wave N+1 in the same turn. Never launch a wave you have nothing to write. 4. **Verify each CUT yourself** before cutting - read the holder line. A scout row is a hypothesis, not evidence. 5. **PORT items are your edits**: add the fact to the owner page section (Eras row / Laws / spec table), then cut it from the technique page in the same commit. 6. **STALE items: check live state**, not another document - `ssh systemctl is-active `, the endpoint `/health`, the env file. Then rewrite with a date, or drop transient live state an owner page already records. ## The ownership test that stops wasted ports Two pages carrying one figure is the defect - a figure with exactly one holder is fine wherever it lives. A technique page that is the sole record of a campaign owns that campaign's arm tables; do not port such ledgers into an endpoint Eras table. Write the clause into the repo documentation law so the next pass stops porting single-owner facts. Corollary: a worked example may repeat a live number if it declares itself dated and names the owner (a snapshot, not fleet state - recompute from the live files). ## Census after each cluster (catches your own slips too) Run the sibling skill's section 3 census over `git diff -U0` for the cluster (deleted lines x distinctive numeric keys vs the whole vault **plus AGENTS.md**), comma-insensitively; drive the count to zero or list each accepted loss in the commit message. ```python flat = corpus.replace(',', '') pres = lambda n: n in corpus or n.replace(',', '') in flat toks = lambda l: [n for n in re.findall(r'\d[\d,]*(?:\.\d+)?', l) if len(n.replace(',', '').split('.')[0]) >= 4 or (len(n.split('.')[-1]) >= 2 and len(n.replace(',', '')) >= 5)] orphan = [l for l in deleted if toks(l) and not any(pres(n) for n in toks(l))] ``` ## Verify and land - Vault link seam must print `0 unresolved links`; hard-wrapped `[[Two Word Page]]` links split across lines are the usual cause - unwrap them. - Full suite once at the end, not per cluster; a docs seam running while scouts are live may read half-written files, so re-run after the last edit. - Commit per cluster (docs-only means **no deploy**); push, open the PR through the API with a 600-perm curl config, `xdg-open` the PR URL immediately.