diff --git a/docs/plans/design-md-rolesplit.tidy.md b/docs/plans/design-md-rolesplit.tidy.md new file mode 100644 index 0000000..105355b --- /dev/null +++ b/docs/plans/design-md-rolesplit.tidy.md @@ -0,0 +1,443 @@ +# design-md-rolesplit.tidy — Implementation Plan (audit drift fix) + +> **Parent spec:** `docs/specs/2026-05-19-design-md-rolesplit.md` +> **Scope authority:** `docs/journals/2026-05-19-audit-design-md-rolesplit.md` +> "Resolution" (committed 2ba5e16) — the architect `[medium]`+`[low]` +> drift fix, 5 orchestrator-decided points. +> +> **For agentic workers:** REQUIRED SUB-SKILL: use `skills/implement` +> to run this plan. Steps use `- [ ]` checkboxes for tracking. + +**Goal:** Close the spirit-vs-letter gap: extract the +faithfully-migrated history/decision-record prose out of the 3 +affected contract files into the decision-record journal, fix the +one stale cross-ref, re-scope the honesty sweeps to +`design/contracts/` only, and widen `design_index_pin.rs` clause-3 +so the in-code hard gate provably subsumes `architect_sweeps.sh` +Sweep-1 over the contracts scope. + +**Architecture:** TDD by gate-first ordering — Task 1 widens +clause-3 and verifies it goes RED against the *current* (un-stripped) +contract files (proving the widened gate catches what the 6 literal +markers missed); Tasks 2–5 strip the history prose (sentence-level +per recon's contract-residue map) → clause-3 returns GREEN; Task 6 +re-scopes the sweep + its lockstep doc; Task 7 is the whole-tree +gate. Build stays green throughout (only one test file's body + +Markdown change; the test compiles, fails at runtime until the strip +lands). The widened clause-3 is a hand-rolled provable superset of +Sweep-1 (no `regex` dep). + +**Tech Stack:** Markdown (`design/contracts/*.md`, +`docs/journals/2026-05-19-design-decision-records.md`), one Rust +test (`crates/ailang-core/tests/design_index_pin.rs`), +`bench/architect_sweeps.sh`, `skills/audit/agents/ailang-architect.md`. + +**Pinned-byte hazard (recon Cross-references — honor in every strip +task):** each history strip runs adjacent to a `docs_honesty_pin.rs` +verbatim substring pin. `norm()` collapses whitespace but the pinned +run must stay a contiguous token-run: +- `str-abi.md:19` `type-installed; codegen is reserved and not yet shipped` ← `docs_honesty_pin.rs:121-122` +- `typeclasses.md:317` `` `io/print_str` is the only built-in direct-output effect-op `` ← `docs_honesty_pin.rs:125-126` +- `scope-boundaries.md:9` `` `Diverge` is a reserved effect name with no op and no codegen `` ← `docs_honesty_pin.rs:112-113` (over-strip guard — NOT in any edit span; do not touch) + +--- + +## Task 1: widen `design_index_pin.rs` clause-3 (gate-first, RED) + +**Files:** +- Modify: `crates/ailang-core/tests/design_index_pin.rs:130-157` (`fn contracts_carry_no_decision_record_prose`) + +- [ ] **Step 1: Replace the clause-3 body with the widened, provable-superset matcher** + +Replace `fn contracts_carry_no_decision_record_prose` (current +:130-157, the 6-literal-marker `markers` array + `body.contains(m)` +loop) with this. The other 3 clauses + helpers (`root` :10-12, +`read` :14-17, `norm` :19-21, `index_tables` :23-62, +`link_target_exists` :67-81, `design_md_is_gone` :83-90, +`every_index_link_resolves` :92-107, +`every_contract_names_a_resolvable_ratifying_test` :109-128) are +**untouched**. + +```rust +#[test] +fn contracts_carry_no_decision_record_prose() { + // clause 3 — the conflation tripwire, widened (design-md-rolesplit.tidy) + // to a PROVABLE SUPERSET of bench/architect_sweeps.sh Sweep-1's + // history-anchor regex over the design/contracts/ scope. + // + // Invariant established by this milestone: clause-3 GREEN ⟹ + // Sweep-1 finds nothing in design/contracts/. + // + // Subsumption proof (each Sweep-1 alternative ⊆ a check below): + // Sweep-1 = 'Iter [0-9]+[a-z]?(\.[0-9]+)?|Family [0-9]+ + // |^[^/]*2026-[0-9]{2}-[0-9]{2}|\*\*Status: |pre-[0-9]+[a-z]? + // |[0-9]+[a-z]? sketch|21\.g' + // - "Iter " / "Family " / "21.g" / " sketch" + // ⊆ iter_code_token() (any "iter"/"family"/"milestone" + // token followed by a code, case-insensitive) + // - "2026-NN-NN" ⊆ iso_date() (any 20NN-NN-NN) + // - "**Status: " / "pre-" ⊆ PHRASES (literal, ci) + // Broader than Sweep-1 by construction; never narrower. + let dir = root().join("design/contracts"); + + // case-insensitive literal decision-record / history phrases + const PHRASES: &[&str] = &[ + "we rejected", "an earlier draft", "earlier draft committed", + "why not other", "was retired", "were retired", "rollback plan", + "previously all", "deliberately deferred", "new-baseline decision", + "amends the above", "out of scope per", "**status:", "sketch", + "the journal records when", "unchanged from the original draft", + ]; + + // a token that looks like an iter / milestone / family provenance code: + // a keyword followed (within 2 words) by an alnum/dot code or a digit. + fn iter_code_token(low: &str) -> Option { + for kw in ["iter ", "milestone ", "family ", "axis-", "pre-"] { + let mut from = 0; + while let Some(i) = low[from..].find(kw) { + let p = from + i + kw.len(); + let tail: String = low[p..].chars().take(12).collect(); + // "iter 24.1", "iter str-concat,", "milestone 22", + // "family 18", "axis-7", "pre-22a" + if tail.chars().next().map_or(false, |c| { + c.is_ascii_alphanumeric() + }) && tail.chars().take(3).any(|c| { + c.is_ascii_digit() || c == '-' || c == '.' + }) { + return Some(format!("{kw}{tail}")); + } + from = p; + } + } + None + } + + // an ISO-8601-ish date: 20NN-NN-NN + fn iso_date(b: &[u8]) -> Option { + for w in b.windows(10) { + if w[0] == b'2' && w[1] == b'0' + && w[2].is_ascii_digit() && w[3].is_ascii_digit() + && w[4] == b'-' && w[5].is_ascii_digit() && w[6].is_ascii_digit() + && w[7] == b'-' && w[8].is_ascii_digit() && w[9].is_ascii_digit() + { + return Some(String::from_utf8_lossy(w).into_owned()); + } + } + None + } + + for entry in fs::read_dir(&dir).expect("design/contracts/ exists") { + let p = entry.unwrap().path(); + if p.extension().and_then(|e| e.to_str()) != Some("md") { + continue; + } + let raw = fs::read_to_string(&p).unwrap(); + let low = norm(&raw).to_lowercase(); + for ph in PHRASES { + assert!( + !low.contains(ph), + "clause-3: history/decision-record phrase {:?} in contract {:?}", + ph, p.file_name().unwrap() + ); + } + assert!( + iter_code_token(&low).is_none(), + "clause-3: iter/milestone provenance code {:?} in contract {:?}", + iter_code_token(&low).unwrap(), p.file_name().unwrap() + ); + assert!( + iso_date(raw.as_bytes()).is_none(), + "clause-3: ISO date {:?} in contract {:?} (history anchor)", + iso_date(raw.as_bytes()).unwrap(), p.file_name().unwrap() + ); + } +} +``` + +- [ ] **Step 2: Verify clause-3 is now RED against the un-stripped tree** + +Run: `cargo test -p ailang-core --test design_index_pin contracts_carry_no_decision_record_prose 2>&1 | tail -8` +Expected: **FAIL** — the assertion fires on the still-present history +prose (e.g. `clause-3: ISO date "2026-05-13" in contract "str-abi.md"` +or `iter/milestone provenance code "iter 24.1…"`). This is the +required RED: the widened gate correctly catches what the 6 literal +markers missed. + +- [ ] **Step 3: Verify the other 3 clauses + build still GREEN** + +Run: `cargo test -p ailang-core --test design_index_pin 2>&1 | grep -E '^test (design_md_is_gone|every_index_link_resolves|every_contract_names) '` +Expected: those 3 still `ok` (only clause-3 RED). `cargo build -p ailang-core --tests 2>&1 | tail -1` → `Finished` (the new matcher compiles; no new dependency). + +--- + +## Task 2: strip history prose from `design/contracts/typeclasses.md` + +**Files:** +- Modify: `design/contracts/typeclasses.md` (:77-78, :182-186, :197-200, :279-289, :291-300, :302-317 — recon's complete scan) +- Modify: `docs/journals/2026-05-19-design-decision-records.md` (append at EOF, after :431) + +- [ ] **Step 1: Append the migrated typeclasses history to the decision-record journal** + +Append at EOF of `docs/journals/2026-05-19-design-decision-records.md`: + +```markdown + +## Migrated from design/contracts/ at design-md-rolesplit.tidy (2026-05-19) + +History/decision-record prose extracted from contract files by the +post-audit tidy (the `###`-whole relocation in iter .1 dragged these +into contracts; they are relitigation-guard content, not contract). + +### typeclasses.md — Prelude-classes evolution + +An earlier draft committed to a fixed Prelude (Show/Eq/Ord on the +primitives), but the implementation work to wire `int_to_str` as a +heap-allocated-string runtime primitive proved substantively +separable from the typeclass machinery itself, and the LLM-utility +case for primitive `Show` is weak (LLM-natural form is `int_to_str +x`, not `show x`). Milestone 23 added `Ordering`/`Eq`/`Ord` + +primitive instances + the five helpers; operator routing through +`Eq`/`Ord` and `print`-rewire were held out for bench-rebaseline / +post-mq-dispatcher reasons; `Show` shipped in milestone 24 (iters +24.2/24.3). `MethodNameCollision` was retired at iter mq.3 +(cross-class method sharing became structurally legal). The +dedicated `KindMismatch` diagnostic was retired at iter ctt.3 +(`BareCrossModuleTypeRef` subsumes it). +``` + +- [ ] **Step 2: Rewrite the 6 typeclasses.md spans present-tense (recon's contract-residue map)** + +Apply each, keeping every present-tense contract fact, dropping the +history clause: + +- `:77-78` `Three invariants make this work, all installed in milestone 24's iter 24.3 and worth keeping load-bearing:` → `Three invariants make this work:` +- `:182-186` drop the parenthetical `(`MethodNameCollision` was retired at iter mq.3. …)` opening; keep the present-tense replacement sentence: `Cross-class method sharing is structurally legal; ambiguity surfaces at the call site via `AmbiguousMethodResolution` or, for class-fn name overlap, via the `class-method-shadowed-by-fn` warning. See §"Method dispatch" below.` +- `:197-200` keep `… is rejected earlier by the canonical-form validator as `BareCrossModuleTypeRef` — `f` is a bare, non-primitive name not declared as a `TypeDef` in the owning module.`; drop `so the dedicated `KindMismatch` diagnostic was retired at iter ctt.3.` +- `:279-289` (the "Milestone 22 ships no built-in Prelude classes / An earlier draft committed to…" paragraph) — delete wholesale (pure decision-record; the present-tense state is the m24 prelude below). +- `:291-300` replace the `Milestone 23 amends the above:` paragraph with present-tense: `The prelude ships the `Ordering` ADT, the `Eq` and `Ord` classes, primitive `Eq Int/Bool/Str` and `Ord Int/Bool/Str` instances, and the five polymorphic free-fn helpers `ne`/`lt`/`le`/`gt`/`ge`. Float has neither `Eq` nor `Ord` instance per §"Float semantics"; a polymorphic helper invoked at Float fires `NoInstance` at typecheck with a Float-aware diagnostic cross-referencing this section.` (drop "remain out of scope per their original substantive reasons (bench rebaseline, milestone-24 dependency…); Show itself ships in milestone 24" — that relitigation is now in the journal.) +- `:302-317` replace the `Milestone 24 amends the above further:` opening with present-tense: `The prelude ships `class Show a where show : (a borrow) -> Str` and primitive `Show Int`, `Show Bool`, `Show Str`, `Show Float` instances. Float **is** included in Show (unlike Eq/Ord) …` — **keep verbatim and byte-contiguous** the tail through `:317` `` `io/print_str` is the only built-in direct-output effect-op `` (pinned by `docs_honesty_pin.rs:125-126`) and the `:315` `print_mono_body_shape.rs` cross-reference; drop only `Milestone 24 amends the above further`, `(iter 24.2)`, `shipped in iter 24.3` (→ replace `shipped in iter 24.3 with body` with `with body`). + +- [ ] **Step 3: Verify typeclasses.md pin + clause-3 progress** + +Run: `cargo test -p ailang-core --test docs_honesty_pin 2>&1 | grep -E 'test result:'` +Expected: PASS (the `io/print_str…` pinned run intact). Run +`grep -n 'io/print_str` is the only built-in direct-output effect-op' design/contracts/typeclasses.md` +Expected: exactly one contiguous match (pin survived). + +--- + +## Task 3: strip history prose from `design/contracts/str-abi.md` + +**Files:** +- Modify: `design/contracts/str-abi.md` (:14, :16, :18, :20, :22-23, :74, :38-43, :45-47) +- Modify: `docs/journals/2026-05-19-design-decision-records.md` (append under the tidy section) + +- [ ] **Step 1: Append str-abi history to the journal** + +Append under the `## Migrated …` section: + +```markdown + +### str-abi.md — heap-Str builtin provenance + deferred-operator rationale + +Builtin iter provenance: `int_to_str`/`bool_to_str`/`float_to_str`/ +`str_clone` shipped iter 24.1; `str_concat` shipped iter str-concat +(2026-05-13); the non-escape static-Str lowering pass landed iter +18b, move-tracking partial-drop iter 18d.3. Operator routing through +classes is deliberately deferred — it would migrate every fixture +and re-baseline the bench corpus (a new-baseline decision, not an +iter detail). `Num` is not in milestone 22: class-based numeric +overloading would invoke literal-defaulting which axis-7 excluded. +``` + +- [ ] **Step 2: Strip the `(iter …)` parentheticals + deferred rationale** + +- `:14` `- `int_to_str : (borrow Int) -> Str` (iter 24.1) — decimal rendering` → `- `int_to_str : (borrow Int) -> Str` — decimal rendering` +- `:16` `- `bool_to_str : (borrow Bool) -> Str` (iter 24.1) — `"true"`/`"false"`.` → drop ` (iter 24.1)` +- `:18` `- `float_to_str : (borrow Float) -> Str` (iter 24.1) —` → drop ` (iter 24.1)`. **Hazard:** `:19` `type-installed; codegen is reserved and not yet shipped.` is pinned (`docs_honesty_pin.rs:121-122`) — keep `:19` byte-identical and contiguous with `:18`'s `—`. +- `:20` `- `str_clone : (borrow Str) -> Str` (iter 24.1) — allocates a fresh` → drop ` (iter 24.1)` +- `:22-23` `- `str_concat : (borrow Str, borrow Str) -> Str` (iter str-concat,\n 2026-05-13) — combines …` → `- `str_concat : (borrow Str, borrow Str) -> Str` — combines two `Str` values into a single owned `Str`.` (collapse the soft-wrap; drop the whole `(iter str-concat, 2026-05-13)` — this is the Sweep-1 exit-1 trip) +- `:74` drop ` (iter 18b)` and ` (iter 18d.3)`; keep the present-tense mechanism sentence. +- `:38-43` keep `` `==`, `<`, `<=`, `>`, `>=` REMAIN primitive operators. Class methods are accessed by name (`eq x y`, `lt x y`, …), not via these operators. `` ; drop `(unchanged from the original draft)` and the whole `Routing operators through classes is deliberately deferred — … new-baseline decision rather than an iter detail.` +- `:45-47` keep `Arithmetic operators (`+`, `-`, `*`, `/`) stay primitive and per-type.`; drop `` `Num` is NOT in milestone 22. `` and `Class-based numeric overloading would invoke literal-defaulting which axis-7 already excluded.` + +- [ ] **Step 3: Verify str-abi pin intact** + +Run: `grep -n 'type-installed; codegen is reserved and not yet shipped' design/contracts/str-abi.md` +Expected: exactly one contiguous match. Run +`cargo test -p ailang-core --test docs_honesty_pin 2>&1 | grep 'test result:'` → PASS. + +--- + +## Task 4: strip history prose from `design/contracts/scope-boundaries.md` + +**Files:** +- Modify: `design/contracts/scope-boundaries.md` (:5-6, :14-17, :36-38) +- Modify: `docs/journals/2026-05-19-design-decision-records.md` (append under the tidy section) + +- [ ] **Step 1: Append scope-boundaries history to the journal** + +```markdown + +### scope-boundaries.md — retired ops + deferral rationale + +Polymorphic-fn-as-value is deferred because it would need one +closure-pair global per instantiation. The per-type print ops +`io/print_int`/`io/print_bool`/`io/print_float` were retired in iter +rpe.1 (the polymorphic `print` is the canonical non-Str output path). +``` + +- [ ] **Step 2: Rewrite the 3 scope-boundaries spans** + +- `:5-6` keep `Snapshot of the current boundary.`; delete `Items move out of this list as iterations land; the JOURNAL records when.` (process-meta, not a scope contract; not decision-record either — plain delete, not journal-moved). +- `:14-17` keep `Polymorphic fns must be **directly called** at the use site. Passing a polymorphic fn as a value (`let f = id in f(42)`) is not yet supported.`; drop ` — it would need one closure-pair global per instantiation, deferred.` (rationale → journal, Step 1). +- `:36-38` keep `Effects on function signatures, with `do op(args)` for direct effect ops (`io/print_str`). The polymorphic `print` (§"Polymorphic print") is the canonical output path for non-Str values.`; drop `The per-type print ops `io/print_int`, `io/print_bool`, `io/print_float` were retired in iter rpe.1;` (→ journal). + +- [ ] **Step 3: Over-strip guard — the Diverge pin must be untouched** + +Run: `grep -n 'Diverge` is a reserved effect name with no op and no codegen' design/contracts/scope-boundaries.md` +Expected: exactly one match at the original location (`:9`, +unedited — it is NOT in any edit span; this guards against +collateral deletion). `cargo test -p ailang-core --test effect_doc_honesty_pin 2>&1 | grep 'test result:'` → PASS. + +--- + +## Task 5: fix the stale cross-ref in `design/contracts/float-semantics.md` + +**Files:** +- Modify: `design/contracts/float-semantics.md:100` + +- [ ] **Step 1: Repoint the stale "below" direction** + +`:99-100` verbatim `Both allocate a fresh heap-Str slab at the call +site (see "Str ABI" below for the dual realisation) and carry +`ret_mode: Own`…`. Replace `(see "Str ABI" below for the dual +realisation)` → `(see design/contracts/str-abi.md for the dual +realisation)`. (`design/contracts/str-abi.md` exists — confirmed +recon; INDEX row `design/INDEX.md:93`.) + +- [ ] **Step 2: Verify float-semantics pin intact + no stale "below"** + +Run: `grep -n '"Str ABI" below' design/contracts/float-semantics.md || echo "CLEAN: stale below gone"` +Expected: `CLEAN: stale below gone`. Run +`cargo test -p ail --test eq_float_noinstance 2>&1 | grep 'test result:'` → PASS. + +--- + +## Task 6: re-scope `architect_sweeps.sh` honesty sweeps + lockstep doc + +**Files:** +- Modify: `bench/architect_sweeps.sh:25` (+ header `:5-7`) +- Modify: `skills/audit/agents/ailang-architect.md:77-84` + +- [ ] **Step 1: Narrow `DESIGN_GLOB` to `design/contracts`** + +`bench/architect_sweeps.sh:25` verbatim +`DESIGN_GLOB="design/contracts design/models"` → +`DESIGN_GLOB="design/contracts"`. (Substantive reason, encoded as a +comment on the same line: `# contracts only — design/models is the +narrative tier; "as of milestone N" context is legitimate there`.) +Header `:5-7` prose `design/ prose set (design/contracts + +design/models)` → `design/contracts (the honesty-bound contract +surface; design/models is the narrative tier, out of honesty-sweep +scope)`. The 5 `run_sweep` regexes (`:46-59`) are **unchanged**; the +exit-code block (`:61-64`) is **unchanged**. + +- [ ] **Step 2: Lockstep `ailang-architect.md`** + +In `skills/audit/agents/ailang-architect.md` the `:77-84` +history-anchor-regrowth bullet: append one sentence after the +exit-semantics lines: `Sweeps 1–4 scan `design/contracts/` only — +`design/models/` is the narrative tier (§ reading-list: "context, +not a drift surface"), so a milestone-context phrase there is not a +regrowth.` (`:34` already states models/ is not a drift surface; +this makes the sweep scope explicit and consistent.) No other +edit; Sweep count stays 5 so `docs_honesty_pin.rs:10` `//!` needs no +change. + +- [ ] **Step 3: Verify the sweep now scans contracts only** + +Run: `bash bench/architect_sweeps.sh; echo "exit=$?"` +Expected: at this point Tasks 2–5 have stripped the contract +history, so **`exit=0`** and `All five sweeps clean.` (If exit 1 +with a `design/contracts/...` match, a history span was missed — +fix it; if the match is `design/models/...` the glob narrowing +didn't apply — re-check `:25`.) + +--- + +## Task 7: whole-tree GREEN gate (milestone-close proof) + +**Files:** none (verification only). + +- [ ] **Step 1: clause-3 now GREEN, design_index_pin 4/4** + +Run: `cargo test -p ailang-core --test design_index_pin 2>&1 | grep -E '^test |test result:'` +Expected: all 4 `ok` — `contracts_carry_no_decision_record_prose` +flipped RED→GREEN (history stripped), the other 3 unchanged-GREEN. + +- [ ] **Step 2: the retargeted pins + E2Es still GREEN** + +Run: `cargo test -p ailang-core --test design_schema_drift --test docs_honesty_pin --test effect_doc_honesty_pin 2>&1 | grep 'test result:'` +Expected: 3× PASS. Run +`cargo test -p ail --test eq_float_noinstance --test show_no_instance_e2e 2>&1 | grep 'test result:'` +Expected: 2× PASS. + +- [ ] **Step 3: whole workspace GREEN + sweep exit 0 + acceptance grep** + +Run: `cargo test --workspace 2>&1 | grep -oE '[0-9]+ passed; [0-9]+ failed' | awk -F'[ ;]' '{p+=$1; f+=$4} END {print "TOTAL passed="p" failed="f}'` +Expected: `failed=0` and `passed` ≥ 646 (the iter .1 baseline; the +widened clause-3 adds no new test count, it replaces a body). +Run: `bash bench/architect_sweeps.sh; echo "exit=$?"` +Expected: `exit=0`. +Run: `grep -rIn 'DESIGN\.md' . --exclude-dir=.git --exclude-dir=target | grep -vE '(^\./)?(docs/(journals/|specs/|plans/|roadmap\.md|WhatsNew\.md|journal-archive\.md)|bench/orchestrator-stats/)' | grep -v 'design-md-rolesplit' | grep -v 'design_index_pin.rs' || echo "CLEAN"` +Expected: `CLEAN` (no live-ref regression from the tidy edits). + +--- + +## Self-review (planner Step 5) + +1. **Spec/Resolution coverage:** Task 1 = Resolution-4 (clause-3 + widen); Tasks 2–4 = Resolution-1 (history → journal, 3 files); + Task 5 = Resolution-2 (stale "below"); Task 6 = Resolution-3 + (sweep re-scope + lockstep); Task 7 = Resolution-5 exit state. + All 5 points covered. ✓ +2. **Placeholder scan:** no TBD/TODO/"similar to". Every strip names + the exact recon line + verbatim before→after text. ✓ +3. **Type/path consistency:** `design/contracts/str-abi.md`, + `docs/journals/2026-05-19-design-decision-records.md`, + `contracts_carry_no_decision_record_prose` used identically + across tasks; the journal append section header + `## Migrated … (2026-05-19)` consistent Tasks 2/3/4. ✓ +4. **Step granularity:** each step is one file's edit-set or one + Run; the largest (Task 2 Step 2, 6 spans) is one + mechanical-per-span pass, 2–5 min. ✓ +5. **No commit steps:** none. ✓ +6. **Pin/replacement contiguity:** the three `docs_honesty_pin.rs` + pinned runs (`str-abi.md:19`, `typeclasses.md:317`, + `scope-boundaries.md:9`) are called out as hazards in the header + AND verified by an explicit `grep -n` contiguity check in Tasks + 2/3/4 Step 3 + the over-strip guard in Task 4 Step 3. The + widened clause-3 matcher (Task 1) is a single self-contained + function body — no cross-task substring split. ✓ +7. **Compile-gate vs deferred-caller:** the only Rust edit is one + self-contained test fn body (Task 1); it compiles standalone + (no signature change, no caller, no new dependency — hand-rolled + matcher). Every Run gate is satisfiable at its task: Task 1 Step + 2 expects RED (pre-strip), Task 7 expects GREEN (post-strip); + no gate depends on a later task's code. Build green throughout + (test compiles; only its runtime assertion is RED until the + strip lands). ✓ +8. **Verification filter strings resolve:** `--test + design_index_pin` / `design_schema_drift` / `docs_honesty_pin` / + `effect_doc_honesty_pin` / `eq_float_noinstance` / + `show_no_instance_e2e` all exist (iter .1 created/retargeted + them). The clause-3 filter + `contracts_carry_no_decision_record_prose` is the exact fn name. + Task 7 Step 3 uses the **unfiltered** `cargo test --workspace` + with a numeric `failed=0` + `passed≥646` assertion (cannot + masquerade as "nothing ran"). The `grep`/`bash architect_sweeps` + gates have explicit `CLEAN`/`exit=0` sentinels. ✓ + +Plan is placeholder-free; the widened clause-3 is a hand-rolled +provable Sweep-1 superset (no `regex` dep). Hand off to `implement`.