Todo-Check
Forward-looking preflight against the planned change. Item definitions live in quality-list; this skill is the runner. Update quality-list, not this file, when adding or modifying items.
done-check asks: "Did the diff satisfy item N?" todo-check asks: "What does item N require us to set up so the diff will satisfy it?" On quality-list the two apply the same mechanical / contextual lane split (its Item lanes section): mechanical-lane items go to a fresh-context subagent (Step 2), contextual-lane items stay in main context (Step 3). The duality stops at that rule set — done-check also applies authoritative-text-rules when the diff calls for it, and this preflight does not, so a clean preflight does not by itself predict a clean audit.
Procedure
Resolve the active rule set. Resolve two absolute paths first, and use them everywhere below: <SKILLS_DIR>, the directory holding this skill's own directory, and <TARGET_ROOT>, the project this preflight is for (cwd). Every read of a rule file — main context's as much as the subagent's — resolves against <SKILLS_DIR>, so both paths are resolved here and carried, never re-derived downstream.
<SKILLS_DIR> is ${CLAUDE_SKILL_DIR}/...
Base items live in <SKILLS_DIR>/quality-list/SKILL.md; language-specific addenda at <SKILLS_DIR>/quality-list/lang-<language>.md realize them concretely. Verify <SKILLS_DIR>/quality-list/SKILL.md is present here, before anything reads it. A rule set that is not there halts, reporting the file looked for and the directory looked in, so that whoever reads the halt can tell a wrong <SKILLS_DIR> from a rule set that is not installed.
Detect language from <TARGET_ROOT>/CLAUDE.md's Language: declaration — the target's, never one found beside the rule files; otherwise auto-detect from the extensions of the files the work will likely touch — taken from the plan or task description, since Step 0 runs before Step 1 formalizes the scope (.rs → rust, .cpp/.cc/.cxx/.h/.hpp → cpp, .py → python, .ts/.tsx → typescript, .go → go, etc.). Multi-language projects detect every present language; each matching addendum applies. Missing addendum → base rules only for that language (not a concern). Step 0 only detects the language(s); it routes nothing. Each consumer — the Step 2 mechanical subagent and the Step 3 contextual pass — loads every matching addendum file itself.
Describe the planned change. State in plain terms what the change will do: the files / modules it will touch, the behavior it will change, the public symbols / schemas / contracts it will move, and the invariants it introduces or modifies. Capture what is already decided; leave the rest unstated — an unsettled fact surfaces as a ? unknown row below, not a guess. State the language(s) Step 0 detected here too, so the subagent applies the same addenda the contextual lane does rather than re-deriving them from a scope description that may name modules without file extensions. Do not pre-classify the change against individual items — the subagent (Step 2) and the contextual pass (Step 3) read each item's body and decide applicability themselves; the scope description is a plain account of the change, not a per-item trigger checklist.
todo-check also runs mid-implementation. When earlier units are already materialized on disk, name their inspectable revision range in the scope description too, so the subagent reads the real code instead of treating the tree as unwritten. Name a committed range only when earlier units are already committed; it takes a root on diff-root's consumer contract, halt included, and that skill's per-command conversion. A run with no committed units names no such range and so needs no root — a preflight runs against work that does not exist yet, and its scope description, not the repository, is what says how much of it is written. done-check has no equivalent case: it audits work that exists, and whether that work includes commits is what a root decides rather than something the audit may assume. The working-tree commands below still apply in that case.
git log --oneline <root-rev>..HEAD # committed units
git diff <root-rev>...HEAD # committed content
git diff --cached # staged
git diff # unstaged
git ls-files --others --exclude-standard # untracked paths
State that this range is part of the change under preflight, not pre-existing baseline to reuse from — a helper just added there is a candidate for duplication-extraction's search, not an existing helper the search should call.
Spawn a fresh-context preflight subagent for the mechanical items. A fresh context removes the author's blindspot for what the planned scope actually implies, and keeps the item-body rule text out of main context.
Main context MUST NOT load a purely-mechanical item's body (the dual-lane ported-code-attribution body is the one exception, read in Step 3 for its contextual half). The subagent reads the index and those bodies in its own fresh context — it derives the mechanical-lane item set from the index itself; main only composes the prompt (scope description + the resolved paths) and dispatches.
The prompt carries the two absolute paths Step 0 resolved; the subagent needs both.
Use the Agent tool with subagent_type: "general-purpose" and a prompt of the following shape:
You are running a PREFLIGHT (not an audit) against a planned change,
under the `quality-list` quality rules. You have NO access to the
conversation history that produced this scope and MUST NOT speculate
about author intent beyond the scope description below. Judge from:
- the literal scope description (provided below)
- if the scope description names an already-materialized revision
range, the code in that range — treat it as part of the change
under preflight, not as pre-existing baseline
- the literal text of the relevant `quality-list` item files (read
them yourself from the paths below)
- the literal text of the codebase at <TARGET_ROOT> you can read with
your tools (existing helpers, current callers, paired-artifact
surfaces)
The scope description's characterizations of EXISTING code ("no
helper for this exists yet", "sibling X already exposes a symmetric
surface") are the author's working hypothesis — sanity-check them
against what you can read in the codebase, and flag any discrepancy
in your report. A characterization of the not-yet-written change
itself has nothing to check against — take it as given.
First read <SKILLS_DIR>/quality-list/SKILL.md and
consult its Items index. Select every item whose lane is
`mechanical`, including the mechanical half of any dual-lane item (an
entry tagged `mechanical (+ contextual half)`, e.g.
ported-code-attribution — handle only its declared-port signal; the
undeclared-port signal is main context's job, but still return a row
for the item even when its declared half is ⊘ N/A, so the coverage
check sees it). Read each selected item's
<SKILLS_DIR>/quality-list/items/<slug>.md in full.
Where an item body or addendum spells a detection command
containing `<root-rev>`, substitute the revision form
`diff-root` derives from the root given below, not the root
itself. When no root is given, that command does not run —
follow the rule in <SKILLS_DIR>/quality-list/SKILL.md.
The language(s) Step 0 detected are stated below; load each
corresponding addendum at
<SKILLS_DIR>/quality-list/lang-<lang>.md that exists,
loading them all when more than one applies. If none are stated, fall
back to the `Language:` line of <TARGET_ROOT>/CLAUDE.md — that file
and no other CLAUDE.md, whatever its location — then to the file
extensions in the scope description. No language found, or a
detected language with no addendum file, is not a concern —
proceed on base rules.
For each selected item return one of:
- △ active — this item will apply to the finished diff; state the
concrete preflight setup action (test fixture variants, guard
locations, paired-artifact surfaces to sweep, existing-helper
search results, etc.), grounded in the scope description and the
codebase.
- ⊘ N/A — using only the item's own N/A criterion as stated.
- ? unknown — the body is read, but applicability turns on a scope
fact not given; state the scope check that would decide it AND the
resulting verdict for each possible answer, so it can be resolved
later without re-reading the body.
Report concisely: one row per item with Status + Setup action / N/A
reason / scope check; then a final list of any discrepancies between
the scope description and what you read in the codebase.
Embed the scope description (Step 1), the language(s) Step 0 detected, the root when Step 1 named a range, and the two resolved paths. The root is what an item body's or addendum's detection command needs to name a range. Do not embed item body text — the subagent reads the item files itself.
Start Step 3 immediately rather than waiting; the two run in parallel. Block on the subagent's return once you reach Step 4.
Process the contextual items in main context. Read <SKILLS_DIR>/quality-list/SKILL.md's Items index and select every item whose lane is contextual, including the contextual half of dual-lane items — ported-code-attribution's undeclared-port signal is main's job because it needs the conversation / research history the subagent lacks. These need plan / intent / review history, or command-execution planning against the working tree.
For each selected contextual item, Read its <SKILLS_DIR>/quality-list/items/<slug>.md body — plus every lang-<lang>.md addendum section for a language Step 0 detected, self-loaded here — before deciding its status. Read only the contextual-lane bodies — plus ported-code-attribution's own body, which the undeclared-port half is decided from even though the item is index-tagged mechanical (+ contextual half) — not a purely mechanical-lane item's body. For each, determine one of:
- △ active — this item will apply to the finished diff; record the concrete setup action to do now (fixture variants, guard locations, paired-artifact surfaces, probes to thread through).
- ⊘ N/A — the item's own N/A criterion excludes the scope. State why.
- ? unknown — the body is read, but applicability turns on a scope fact not yet settled; record the scope check that would decide it.
Merge results. Integrate the mechanical-lane rows the subagent returned with the contextual-lane rows (Step 3) into a single table.
domain: every item in the `<SKILLS_DIR>/quality-list/SKILL.md` Items index
coverage — the subagent's returned mechanical rows against the
mechanical-lane slug set the index predicts. This applies to a
full-set dispatch; a narrowed single-item return (Step 5) is exempt:
exactly one row per predicted slug,
and no others → proceed
any other return (a slug missing,
duplicated, or outside the predicted
set), first occurrence → re-dispatch Step 2 with the
prompt unchanged; re-check
any other return, after that
re-dispatch → surface to the user; do not
proceed with the mechanical
lane incomplete, and do not
emit the table
row rendering — one row per item, in index order:
single-lane item → that lane's verdict
dual-lane, either half △ → △ active; name which half
dual-lane, both halves ⊘ → ⊘ N/A
dual-lane, otherwise → ?
A half left ? at merge time carries its scope check forward to Step 5, so the half's own setup action is not lost behind an active status.
If the subagent returned a discrepancy list, adjudicate each: correct the affected row's setup action to match what the subagent found, or — if the scope description was right and the subagent's codebase read was the mistaken side — note that resolution instead rather than rewriting the row.
Resolve every ? before declaring preflight done.
domain: every unsettled scope check — the one behind a single-lane `?`
row, and one per unsettled half of any dual-lane row,
which can therefore carry two. Each check belongs to exactly
one lane; settle them one at a time.
pass 1 — settle the scope fact, by the lane of the check being settled:
mechanical lane, and the subagent
stated a verdict per answer to its
scope check → settle the fact; read the
matching verdict off. If the
settled answer is not one it
enumerated, take the arm below
mechanical lane, otherwise → narrowed re-dispatch (below)
contextual lane → settle the scope check Step 3
recorded, in main context
pass 2 — record the outcome:
settled, single-lane `?` row → △ with a concrete setup action
| ⊘ with a reason
settled, a half of a dual-lane row → add that half's own setup action
to the row's Setup action cell,
or note the half N/A there with
its reason, alongside whatever
the other half already put there.
The row's status is then Step 4's
row-rendering rule over its two
half-statuses, so a row already
rendered △ stays △
could not be settled at preflight
time → surface to the user, naming what
the row already carries; do not
declare preflight done, and do not
emit the table
always: never read a purely-mechanical item's body in main context.
always: a setup action that names a command to run (e.g.
`public-api-surface`'s `cargo public-api` baseline) is still a
planning action — state that the command runs before
implementation, don't run it now.
Narrowed re-dispatch. Re-dispatch the subagent with the Step 2 prompt narrowed to that one item — replace its "Select every item whose lane is mechanical…" sentence with "Process only <slug>", or for ported-code-attribution with "Process only ported-code-attribution's declared-port signal (the undeclared-port signal stays main context's job)", keeping the sentence after it that tells the subagent to read the selected item's body in full. Its single-item return is exempt from Step 4's whole-set coverage check.
Report the preflight table. Hand the △ rows to the implementation step as setup actions.
Preflight framing per item (quick reference)
These are how each quality-list item reads in preflight mode — a compressed mnemonic of the lens-shift from the item's audit question to a preflight setup action. A row is not the applicability authority and decides nothing: Step 3 reads each contextual item's body (<SKILLS_DIR>/quality-list/items/<slug>.md) plus any applicable addendum, and that — with the index as the item set — decides whether it applies. Consult a row for its setup framing once the body has marked the item active.
This list covers only the contextual-lane items (and the contextual half of the dual-lane item) that Step 3 processes. Mechanical-lane items have no row in this quick reference (they still get a row in the final preflight table, per Step 4): the subagent never reads this file, so a mnemonic for it would have no consumer.
invariant-derivation — Before patching, derive the full necessary-and-sufficient condition from first principles. List it in the plan.
purpose-verification — Identify the input that exposes the purpose end-to-end. Plan to exercise it before declaring done.
pattern-audit — Plan to re-derive any reused sibling pattern's correctness in the current context before relying on it.
scope-discipline — Resolve to evaluate findings on their merits, not narrowed to the originating task.
test-execution — Plan which test commands will be run, and capture the pre-existing failure baseline before any edit.
completion-hygiene — Plan which lint / format / type-check / build commands will be run. Note any debug artifacts to strip.
escape-hatch-necessity — Plan to derive any workaround's necessity before using it, treating it as a last resort rather than a default.
docstring-drift — List the docstring / comment / README surfaces describing any behavior the change alters, and plan a cold-read re-verification of each against the new behavior, with an execution probe where the behavior becomes library-owned.
discovery-surfacing — Extract any research plan's Inconclusive items into a watch list for the implementation phase.
ported-code-attribution (undeclared-port half) — If research surfaced an external implementation this scope structurally follows but hasn't named, plan the attribution surface now even though no comment names it yet.
Output format
preflight: <task / unit description>
| Item | Status | Setup action / N/A reason |
|-------------------------------|----------|--------------------------------------------------------|
| invariant-derivation | △ active | derive condition for <invariant> from <constraint> |
| scope-discipline | ⊘ N/A | no findings raised yet |
| behavior-coverage | △ active | fixtures: 3-site MPS bulk variant, non-square 2×3 ... |
| implementation-guards | △ active | assert! at <site>; review siblings <a>, <b> |
| architectural-boundary | ⊘ N/A | no new imports / dep edges / pub widening |
| paired-artifact-drift | △ active | sweep: examples/foo.rs, README.md, doctests in <mod> |
| discovery-surfacing | △ active | watch: inconclusive[1] probe at <site>; branches X/Y |
Emit one row per item in the <SKILLS_DIR>/quality-list/SKILL.md Items index, in index order — the rows above illustrate the format and the status vocabulary (△ active / ⊘ N/A), not the full set. ? unknown is a working state that Step 5 resolves, so it never appears in the final table. Only a preflight that reaches Step 6 emits a table at all; every halt above ends it without one, however many such halts the steps above come to hold. The table merges the mechanical-lane rows (Step 2's subagent) with Step 3's contextual-lane rows, per Step 4. Hand the △ rows forward as the implementation setup.
1---2name: todo-check3description: Preflight sweep of quality-list items before or during implementation, framed as 'what to set up so done-check's quality-list rows pass at the end'. Dual of done-check on that rule set.4---56# Todo-Check78Forward-looking preflight against the planned change. Item definitions live in `quality-list`; this skill is the **runner**. Update `quality-list`, not this file, when adding or modifying items.910`done-check` asks: "Did the diff satisfy item N?" `todo-check` asks: "What does item N require us to set up so the diff will satisfy it?" On `quality-list` the two apply the same mechanical / contextual lane split (its Item lanes section): mechanical-lane items go to a fresh-context subagent (Step 2), contextual-lane items stay in main context (Step 3). The duality stops at that rule set — `done-check` also applies `authoritative-text-rules` when the diff calls for it, and this preflight does not, so a clean preflight does not by itself predict a clean audit.1112## Procedure13140. **Resolve the active rule set.** Resolve two absolute paths first, and use them everywhere below: `<SKILLS_DIR>`, the directory holding this skill's own directory, and `<TARGET_ROOT>`, the project this preflight is for (cwd). Every read of a rule file — main context's as much as the subagent's — resolves against `<SKILLS_DIR>`, so both paths are resolved here and carried, never re-derived downstream.1516 `<SKILLS_DIR>` is `${CLAUDE_SKILL_DIR}/..`.1718 Base items live in `<SKILLS_DIR>/quality-list/SKILL.md`; language-specific addenda at `<SKILLS_DIR>/quality-list/lang-<language>.md` realize them concretely. Verify `<SKILLS_DIR>/quality-list/SKILL.md` is present here, before anything reads it. A rule set that is not there halts, reporting the file looked for and the directory looked in, so that whoever reads the halt can tell a wrong `<SKILLS_DIR>` from a rule set that is not installed.1920 Detect language from `<TARGET_ROOT>/CLAUDE.md`'s `Language:` declaration — the target's, never one found beside the rule files; otherwise auto-detect from the extensions of the files the work will likely touch — taken from the plan or task description, since Step 0 runs before Step 1 formalizes the scope (`.rs` → rust, `.cpp`/`.cc`/`.cxx`/`.h`/`.hpp` → cpp, `.py` → python, `.ts`/`.tsx` → typescript, `.go` → go, etc.). Multi-language projects detect every present language; each matching addendum applies. Missing addendum → base rules only for that language (not a concern). Step 0 only **detects** the language(s); it routes nothing. Each consumer — the Step 2 mechanical subagent and the Step 3 contextual pass — loads every matching addendum file itself.21221. **Describe the planned change.** State in plain terms what the change will do: the files / modules it will touch, the behavior it will change, the public symbols / schemas / contracts it will move, and the invariants it introduces or modifies. Capture what is already decided; leave the rest unstated — an unsettled fact surfaces as a `? unknown` row below, not a guess. State the language(s) Step 0 detected here too, so the subagent applies the same addenda the contextual lane does rather than re-deriving them from a scope description that may name modules without file extensions. **Do not pre-classify the change against individual items** — the subagent (Step 2) and the contextual pass (Step 3) read each item's body and decide applicability themselves; the scope description is a plain account of the change, not a per-item trigger checklist.2324 `todo-check` also runs mid-implementation. When earlier units are already materialized on disk, name their inspectable revision range in the scope description too, so the subagent reads the real code instead of treating the tree as unwritten. Name a **committed** range only when earlier units are already committed; it takes a **root** on `diff-root`'s consumer contract, halt included, and that skill's per-command conversion. A run with no committed units names no such range and so needs no root — a preflight runs against work that does not exist yet, and its scope description, not the repository, is what says how much of it is written. `done-check` has no equivalent case: it audits work that exists, and whether that work includes commits is what a root decides rather than something the audit may assume. The working-tree commands below still apply in that case.2526 ```bash27 git log --oneline <root-rev>..HEAD # committed units28 git diff <root-rev>...HEAD # committed content29 git diff --cached # staged30 git diff # unstaged31 git ls-files --others --exclude-standard # untracked paths32 ```3334 State that this range is **part of the change under preflight**, not pre-existing baseline to reuse from — a helper just added there is a candidate for `duplication-extraction`'s search, not an existing helper the search should call.35362. **Spawn a fresh-context preflight subagent for the mechanical items.** A fresh context removes the author's blindspot for what the planned scope actually implies, and keeps the item-body rule text out of main context.3738 **Main context MUST NOT load a purely-mechanical item's body** (the dual-lane `ported-code-attribution` body is the one exception, read in Step 3 for its contextual half). The subagent reads the index and those bodies in its own fresh context — it derives the mechanical-lane item set from the index itself; main only composes the prompt (scope description + the resolved paths) and dispatches.3940 The prompt carries the two absolute paths Step 0 resolved; the subagent needs both.4142 Use the `Agent` tool with `subagent_type: "general-purpose"` and a prompt of the following shape:4344 ```45 You are running a PREFLIGHT (not an audit) against a planned change,46 under the `quality-list` quality rules. You have NO access to the47 conversation history that produced this scope and MUST NOT speculate48 about author intent beyond the scope description below. Judge from:4950 - the literal scope description (provided below)51 - if the scope description names an already-materialized revision52 range, the code in that range — treat it as part of the change53 under preflight, not as pre-existing baseline54 - the literal text of the relevant `quality-list` item files (read55 them yourself from the paths below)56 - the literal text of the codebase at <TARGET_ROOT> you can read with57 your tools (existing helpers, current callers, paired-artifact58 surfaces)5960 The scope description's characterizations of EXISTING code ("no61 helper for this exists yet", "sibling X already exposes a symmetric62 surface") are the author's working hypothesis — sanity-check them63 against what you can read in the codebase, and flag any discrepancy64 in your report. A characterization of the not-yet-written change65 itself has nothing to check against — take it as given.6667 First read <SKILLS_DIR>/quality-list/SKILL.md and68 consult its Items index. Select every item whose lane is69 `mechanical`, including the mechanical half of any dual-lane item (an70 entry tagged `mechanical (+ contextual half)`, e.g.71 ported-code-attribution — handle only its declared-port signal; the72 undeclared-port signal is main context's job, but still return a row73 for the item even when its declared half is ⊘ N/A, so the coverage74 check sees it). Read each selected item's75 <SKILLS_DIR>/quality-list/items/<slug>.md in full.7677 Where an item body or addendum spells a detection command78 containing `<root-rev>`, substitute the revision form79 `diff-root` derives from the root given below, not the root80 itself. When no root is given, that command does not run —81 follow the rule in <SKILLS_DIR>/quality-list/SKILL.md.8283 The language(s) Step 0 detected are stated below; load each84 corresponding addendum at85 <SKILLS_DIR>/quality-list/lang-<lang>.md that exists,86 loading them all when more than one applies. If none are stated, fall87 back to the `Language:` line of <TARGET_ROOT>/CLAUDE.md — that file88 and no other CLAUDE.md, whatever its location — then to the file89 extensions in the scope description. No language found, or a90 detected language with no addendum file, is not a concern —91 proceed on base rules.9293 For each selected item return one of:9495 - △ active — this item will apply to the finished diff; state the96 concrete preflight setup action (test fixture variants, guard97 locations, paired-artifact surfaces to sweep, existing-helper98 search results, etc.), grounded in the scope description and the99 codebase.100 - ⊘ N/A — using only the item's own N/A criterion as stated.101 - ? unknown — the body is read, but applicability turns on a scope102 fact not given; state the scope check that would decide it AND the103 resulting verdict for each possible answer, so it can be resolved104 later without re-reading the body.105106 Report concisely: one row per item with Status + Setup action / N/A107 reason / scope check; then a final list of any discrepancies between108 the scope description and what you read in the codebase.109 ```110111 Embed the scope description (Step 1), the language(s) Step 0 detected, the root when Step 1 named a range, and the two resolved paths. The root is what an item body's or addendum's detection command needs to name a range. **Do not embed item body text** — the subagent reads the item files itself.112113 Start Step 3 immediately rather than waiting; the two run in parallel. Block on the subagent's return once you reach Step 4.1141153. **Process the contextual items in main context.** Read `<SKILLS_DIR>/quality-list/SKILL.md`'s Items index and select every item whose lane is `contextual`, including the contextual half of dual-lane items — `ported-code-attribution`'s undeclared-port signal is main's job because it needs the conversation / research history the subagent lacks. These need plan / intent / review history, or command-execution planning against the working tree.116117 For each selected contextual item, `Read` its `<SKILLS_DIR>/quality-list/items/<slug>.md` body — plus every `lang-<lang>.md` addendum section for a language Step 0 detected, self-loaded here — before deciding its status. Read only the contextual-lane bodies — plus `ported-code-attribution`'s own body, which the undeclared-port half is decided from even though the item is index-tagged `mechanical (+ contextual half)` — not a purely mechanical-lane item's body. For each, determine one of:118119 - **△ active** — this item will apply to the finished diff; record the concrete setup action to do *now* (fixture variants, guard locations, paired-artifact surfaces, probes to thread through).120 - **⊘ N/A** — the item's own N/A criterion excludes the scope. State why.121 - **? unknown** — the body is read, but applicability turns on a scope fact not yet settled; record the scope check that would decide it.1221234. **Merge results.** Integrate the mechanical-lane rows the subagent returned with the contextual-lane rows (Step 3) into a single table.124125 ```126 domain: every item in the `<SKILLS_DIR>/quality-list/SKILL.md` Items index127128 coverage — the subagent's returned mechanical rows against the129 mechanical-lane slug set the index predicts. This applies to a130 full-set dispatch; a narrowed single-item return (Step 5) is exempt:131 exactly one row per predicted slug,132 and no others → proceed133 any other return (a slug missing,134 duplicated, or outside the predicted135 set), first occurrence → re-dispatch Step 2 with the136 prompt unchanged; re-check137 any other return, after that138 re-dispatch → surface to the user; do not139 proceed with the mechanical140 lane incomplete, and do not141 emit the table142143 row rendering — one row per item, in index order:144 single-lane item → that lane's verdict145 dual-lane, either half △ → △ active; name which half146 dual-lane, both halves ⊘ → ⊘ N/A147 dual-lane, otherwise → ?148 ```149150 A half left `?` at merge time carries its scope check forward to Step 5, so the half's own setup action is not lost behind an active status.151152 If the subagent returned a discrepancy list, adjudicate each: correct the affected row's setup action to match what the subagent found, or — if the scope description was right and the subagent's codebase read was the mistaken side — note that resolution instead rather than rewriting the row.1531545. **Resolve every `?` before declaring preflight done.**155156 ```157 domain: every unsettled scope check — the one behind a single-lane `?`158 row, and one per unsettled half of any dual-lane row,159 which can therefore carry two. Each check belongs to exactly160 one lane; settle them one at a time.161162 pass 1 — settle the scope fact, by the lane of the check being settled:163 mechanical lane, and the subagent164 stated a verdict per answer to its165 scope check → settle the fact; read the166 matching verdict off. If the167 settled answer is not one it168 enumerated, take the arm below169 mechanical lane, otherwise → narrowed re-dispatch (below)170 contextual lane → settle the scope check Step 3171 recorded, in main context172173 pass 2 — record the outcome:174 settled, single-lane `?` row → △ with a concrete setup action175 | ⊘ with a reason176 settled, a half of a dual-lane row → add that half's own setup action177 to the row's Setup action cell,178 or note the half N/A there with179 its reason, alongside whatever180 the other half already put there.181 The row's status is then Step 4's182 row-rendering rule over its two183 half-statuses, so a row already184 rendered △ stays △185 could not be settled at preflight186 time → surface to the user, naming what187 the row already carries; do not188 declare preflight done, and do not189 emit the table190191 always: never read a purely-mechanical item's body in main context.192 always: a setup action that names a command to run (e.g.193 `public-api-surface`'s `cargo public-api` baseline) is still a194 planning action — state that the command runs before195 implementation, don't run it now.196 ```197198 **Narrowed re-dispatch.** Re-dispatch the subagent with the Step 2 prompt narrowed to that one item — replace its "Select every item whose lane is `mechanical`…" sentence with "Process only `<slug>`", or for `ported-code-attribution` with "Process only `ported-code-attribution`'s declared-port signal (the undeclared-port signal stays main context's job)", keeping the sentence after it that tells the subagent to read the selected item's body in full. Its single-item return is exempt from Step 4's whole-set coverage check.1992006. **Report the preflight table.** Hand the △ rows to the implementation step as setup actions.201202## Preflight framing per item (quick reference)203204These are how each `quality-list` item reads in preflight mode — a compressed mnemonic of the lens-shift from the item's audit question to a preflight setup action. A row is **not** the applicability authority and decides nothing: Step 3 reads each contextual item's body (`<SKILLS_DIR>/quality-list/items/<slug>.md`) plus any applicable addendum, and that — with the index as the item set — decides whether it applies. Consult a row for its setup framing once the body has marked the item active.205206This list covers only the contextual-lane items (and the contextual half of the dual-lane item) that Step 3 processes. Mechanical-lane items have no row *in this quick reference* (they still get a row in the final preflight table, per Step 4): the subagent never reads this file, so a mnemonic for it would have no consumer.207208- **`invariant-derivation`** — Before patching, derive the full necessary-and-sufficient condition from first principles. List it in the plan.209- **`purpose-verification`** — Identify the input that exposes the purpose end-to-end. Plan to exercise it before declaring done.210- **`pattern-audit`** — Plan to re-derive any reused sibling pattern's correctness in the current context before relying on it.211- **`scope-discipline`** — Resolve to evaluate findings on their merits, not narrowed to the originating task.212- **`test-execution`** — Plan which test commands will be run, and capture the pre-existing failure baseline before any edit.213- **`completion-hygiene`** — Plan which lint / format / type-check / build commands will be run. Note any debug artifacts to strip.214- **`escape-hatch-necessity`** — Plan to derive any workaround's necessity before using it, treating it as a last resort rather than a default.215- **`docstring-drift`** — List the docstring / comment / README surfaces describing any behavior the change alters, and plan a cold-read re-verification of each against the new behavior, with an execution probe where the behavior becomes library-owned.216- **`discovery-surfacing`** — Extract any research plan's `Inconclusive` items into a watch list for the implementation phase.217- **`ported-code-attribution`** (undeclared-port half) — If research surfaced an external implementation this scope structurally follows but hasn't named, plan the attribution surface now even though no comment names it yet.218219## Output format220221```222preflight: <task / unit description>223224| Item | Status | Setup action / N/A reason |225|-------------------------------|----------|--------------------------------------------------------|226| invariant-derivation | △ active | derive condition for <invariant> from <constraint> |227| scope-discipline | ⊘ N/A | no findings raised yet |228| behavior-coverage | △ active | fixtures: 3-site MPS bulk variant, non-square 2×3 ... |229| implementation-guards | △ active | assert! at <site>; review siblings <a>, <b> |230| architectural-boundary | ⊘ N/A | no new imports / dep edges / pub widening |231| paired-artifact-drift | △ active | sweep: examples/foo.rs, README.md, doctests in <mod> |232| discovery-surfacing | △ active | watch: inconclusive[1] probe at <site>; branches X/Y |233```234235Emit one row per item in the `<SKILLS_DIR>/quality-list/SKILL.md` Items index, in index order — the rows above illustrate the format and the status vocabulary (△ active / ⊘ N/A), not the full set. `? unknown` is a working state that Step 5 resolves, so it never appears in the final table. Only a preflight that reaches Step 6 emits a table at all; every halt above ends it without one, however many such halts the steps above come to hold. The table merges the mechanical-lane rows (Step 2's subagent) with Step 3's contextual-lane rows, per Step 4. Hand the △ rows forward as the implementation setup.