-| Section-8 naming-completeness guard test: sweep the public surface (module-level functions, class `__init__`/`fit` params, results dataclass fields) for contract-rename violations and fail unless each hit is either a `docs/v4-deprecations.yaml` row or an allowlist entry carrying a stated reason (seed the allowlist with the documented domain-vocabulary exemptions: the staggered family's ATT(g,t) `group`/`groups`, `TripleDifference.fit[group]`, wrapper params dying with `M-070..M-077`, and params inherited from `DifferenceInDifferences.__init__`). Today the rules are normative prose and the ledger holds only what an audit remembered — two successive manual sweeps each found surfaces the prior one missed (`M-094`/`M-095`, then the 19-row `M-097..M-115` function sweep). Should land BEFORE Phase 2c so the rename PR works from a mechanically-verified list. Two further checks belong in the same guard, each having been missed by hand across successive review rounds: (a) **phase-table agreement** (spec amended 2026-07-31; three separate rounds caught a stale table and nothing verifies the section 9 checklist's assertion) — direction 1: every row's current `phase` appears in the matching `docs/v4-design.md` section 9 table entry; direction 2: every id cited in a cell resolves to a live ledger row whose lifecycle includes work in that phase, mechanically: a citation of row R in the cell of phase P is legitimate iff P's ship-version (phases 2/3/4 → "3.9", phase 5 → "4.0", phase 6 → "4.1") appears among R's `introduced_in`/`deprecated_in`/`removed_in` — or `decision_due` for `env-default` rows (M-008 is scheduled solely via `decision_due: "4.0"` and its phase-5 citation must pass; make it a guard fixture) — (accepts shim-phase rows re-listed in the phase-5 removal roster; rejects a row with no lifecycle work at that version, e.g. M-031 cited in phase 5). Terminal rows (`done`/`removed`) are exempt in both directions. Parsing rule: cells cite ids as single tokens (`[M-122]`), compound single brackets (`[M-030..M-047]`, comma compounds), and endpoint-bracket ranges (`[M-132]..[M-135]`) — the guard's parser expands BOTH range forms plus comma compounds when computing cell membership (single-token matching alone yields zero interior ids). Known accepted limitation: phases 2 and 3 both ship 3.9, so the predicate cannot catch a row cited in the wrong 3.9 phase; (b) **consumer coverage** (section 8 rule 11) — for each rename row, grep `diff_diff/` and `docs/methodology/` for the old name and require every hit to be either in the row's `code_refs` or allowlisted, since `getattr(obj, "old_name", default)` degrades silently rather than raising after removal. (Sequenced in v4-design §9.) | `tests/`, `docs/v4-design.md` | gating-completeness amendment | Mid | Medium |
0 commit comments