Research — unshim-wave1-01KWKVHB (Phase 0)
All decisions derive from the pre-spec 4-lens squad (debugger-debbie, planner-priti, architect-alphonso, randy-reducer) and the post-spec 3-agent pass (reviewer-renata, paula-patterns, randy-reducer related-surfaces), all run 2026-07-03 against main @ cf2e91e17 / branch tip. Divergences were adjudicated from primary sources, not averaged.
D1 — Census authority: spec rev 2 tables override the issue bodies
#2289's body carries 4 wrong canonical-home cells (core.identity → real home specify_cli.identity.aliases; the three doc_ shims → real home specify_cli.doc_analysis.; the body's missions.documentation.* does not exist) and a ~3× re-anchor undercount ("~15" vs verified ~45–50 sites / ~19 files / 36 sites in tasks_support alone incl. 10 patch() strings — renata re-verified 35 refs + 10 patch strings exactly). Every LOC cell in the spec tables matches wc -l exactly (renata). Decision: C-005 — re-anchor targets come only from the spec table.
D2 — auth.transport: documented-DELETE, deferred to Robert (not #614/#391)
Three-way squad divergence resolved by reading the ADR: docs/adr/3.x/2026-05-18-2-delete-specify-cli-auth-transport.md is Accepted, recommends DELETE, and binds execution to Robert (HiC §5a.3; its own C-005: auth/transport.py + test_auth_transport_singleton.py MUST NOT be modified). #2292's "#614/#391 blocker" is a misattribution → corrected via issue comment (FR-007). The live from .transport import hits resolve to the different module auth/http/transport.py — a sibling-name trap recorded so nobody re-greps it wrong.
D3 — tracker_client_glue: DELETE (defer premise was stale)
randy's DEFER rested on "active mission #2124/#2131 reworking the domain" — adjudicated against the tracker: #2124 CLOSED, #2131 MERGED; the landed rework touched the file (3994e9bba) and still left it caller-less. Superseded → clean delete. This flip makes the executed-deletion count 4 (meets #2292's ≥4 AC) without sacrificing policy.audit.
D4 — policy.audit: keep, adopt-as-follow-up
The one orphan with a live future seam (append-only policy-audit.jsonl governance evidence; intended emission points: commit_guard_hook, risk override, merge gate). Wiring = design work = follow-up issue (operator default: the wave stays pure deletion/triage). Both randy (steelmanned) and alphonso (maps any transport/port adoption to epic #2173) converge.
D5 — Gate mechanics: atomic delete+drain, and the category_b −13 split
test_no_dead_modules.py:590 asserts _ALLOWLIST - actual_orphans == ∅ — deletion cannot ship without its allowlist drain in the same tip (and vice versa). Hence C-006: no standalone gate-drain WP. Arithmetic trap (renata): identity_aliases::with_tracked_mission_slug_aliases is BOTH the category_4 symbol-allowlist row AND a _CATEGORY_B member — so category_b's 237→224 = −1 (IC-01) + −12 (IC-03). An implementer draining only the 12 and writing 224 reds the count gate; the split is now stated in FR-003/FR-005.
D6 — patch() interception proofs (the silent-no-op class)
The 10 patch("specify_cli.tasks_support...") sites are bare return-value redirects — no assert_called* exists at the exact sites where the silent-no-op risk lives. AC 1.2 therefore requires per rewritten site: an added call assertion OR a red-first bogus-target flip proof. Trap recorded: the correct patch target is the consumer's lookup namespace after re-anchoring, not necessarily the definition module task_utils.support.
D7 — Scope verdict: legitimately thin; no-fold #2290/#2291; ~13 LOC doc hygiene folds
Operator flagged thin scope → dedicated related-surfaces sweep (randy) + fold adjudication (paula). Convergent verdict: do not pad. Structural proof: test_no_dead_modules is a bidirectional ratchet and passes green on main → no uncategorized dead module exists by construction. _baselines.yaml full enumeration: category_1 (87 migrations, live via pkgutil), category_2/3 (live), category_5 (0), category_6 (3 — #2291 territory per C-003), symbol categories not drainable-now beyond mission scope. #2290/#2291 are live-caller re-point migrations — categorically different risk class (paula: folding #2291 ~doubles the mission and injects delete-before-re-point ordering hazards). Folds accepted: documentation-mission.md:899-901 re-point (~3 LOC, live doc) + degod-unshim-inventory.md strike-through (~10 LOC, closeout). New untracked debt classes surfaced → FR-008 files fresh issues (pre-3.0 migration retirement; legacy-contract allowlist backfill), operator may veto.
D8 — Deletion set is closed (cascade + residue checks)
- Cascade-orphaning: deleting the 4 orphans strands no sibling (replay/glue import nothing first-party; task_profile imports only heavily-used core; lifecycle imports only the package-wide
ActorRef). - No empty packages result; no migration imports any target (zero grep hits across
upgrade/migrations/); no doctrine YAML / skills manifest / pyproject entry-point references any target; docs-freshness gates read page inventories, not in-body code paths → no LEAK risk. - Zero Design-P
resolution_gate_allowlist.yamlkeys and zero audit-inventory rows point into targets — the content-pinned gates do not engage. - ~12 string-literal
workspace_context.pypath refs in historical mission-fixtureowned_fileslists: leave as-is (disposition recorded in spec edge cases).
Pre-mission op record
#2258 (record_merge/finalize_merge prune) executed as governed op 01KWKWQC58KWSN3VDCZ3VZB2GR before planning: deadness verified (zero src callers; merge_history has no reader — TypedDict field + preservation docstring intentionally retained as legacy on-disk audit-trail compat), 2 functions + 4 test classes deleted (−248 LOC), gates green, commit c194f8d, evidence commented on #2258, closes via this mission's PR.