Sibling to #3203 (`a-falling-count-is-not-evidence`), which records that
a metric moving is not proof the system moved. **This is the positive
procedure**: how to find out whether a landed conversion is held by
anything, and how to write a test that holds it.
## The measurement it is written from
Of **64 resolved lane sets in `self-healing.ts`, 26 had no test that
could distinguish them from the literal they replaced** — including
three conversions I shipped that same day, and two halves of sweeps I
had already recorded as covered.
## The procedure
```
- const reviewColumns = await resolveProjectColumnsForRoles(this.store, REVIEW_ROLES);
+ const reviewColumns = new Set<string>(["in-review"]);
```
Suite fails → covered. Suite passes → nothing in the tree can tell the
conversion from the literal. One resolver, one 17-second run — cheaper
than writing the conversion was.
## Why the census cannot answer this
| instrument | question |
|---|---|
| census / lane-wiring ratchet | is this site written in the resolved
vocabulary? |
| blinding | does anything break if it stops being? |
Neither substitutes for the other. A conversion merged with 204 green
tests behind it and zero able to see it.
## Four rules, each paid for by a test that proved nothing
1. **Blind each resolver separately** — coverage is per-resolver, not
per-sweep. Twice a sweep recorded as done was half-done, because control
flow short-circuited before the second guard.
2. **The fixture must reach the branch the resolver gates.** A card in a
renamed *wip* lane cannot exercise a *terminal* skip — it is caught by
the wip∪review set first.
3. **Assert a path-specific side effect, never a return value.**
`outcome === "reclaimed"` is reachable without the guarded branch.
4. **A store fake must honour `options.column`.** Flat and call-order
stubs answer identically whatever column is requested — a fake that
ignores its own filter cannot see a filter bug.
## The two shapes a ratchet cannot distinguish
- **resolved gate, literal branch** — reads as *unwired*, was a live
defect (#3208: a working agent lost its task link)
- **passed-but-unread** — reads as *wired*, is dead code (#3212)
A ratchet counting call sites scores the first as debt and the second as
done. Both wrong.
## Why a doc and not more PR comments
Everything above currently lives in ~20 PR descriptions. The next person
to touch a lane conversion will not read those. `docs/solutions/` is
where this project already keeps the things it learned the expensive
way, and the frontmatter (`applies_when: deciding whether a lane
conversion is actually protected by a test`) is what makes it findable.
## Verification
`pnpm test:gate` 13 + 161 + 499 + 71 · lint · fnxc-dates (TZ=UTC) ·
`self-healing-docs` 2 passed. Docs only; no changeset, per the AGENTS.md
rule for internal docs.