Tasks: Event write hygiene (event-write-hygiene-01M5HS55)

Input: spec.md, plan.md, research.md, research-census.md, occurrence_map.yaml Topology: single_branch: work packages run sequentially in the write checkout on feat/event-write-hygiene. Issues: #6614 (dead write doors), #6607 (private events import + seam names). Epic context: see #6608.

Subtask Index

IDDescriptionWPParallel
T001Seeding helper tests/_support/status_seed.py + its testsWP01
T002Codemod module-level imports of store.append_event in testsWP01
T003Codemod function-local imports; delete the identity spyWP01
T004Batch multi-row seeds; run the codemodded blast radiusWP01
T005Red-first: re-pin the door gates (unsafe allowlist, writes gate, index single writer)WP02
T006Delete the store doors; shrink _unsafe; fix docstrings; drop the door's own testsWP02
T007Delete append_event_log; retarget its tests onto append_event_stream_logWP02
T008Delete append_to_index; retarget invocation testsWP02
T009Shrink the dead-symbol allowlist and _baselines.yaml; run the blast radiusWP02
T010Red-first: widen the public-imports gate (all roots, any private name)WP03
T011Delete the hosted lifecycle builder family + repo_root_for_lifecycle_log + facade exportsWP03
T012Retarget/delete the builder's tests; run the blast radiusWP03
T013Red-first: stub-handler contract test + extended timeout test (new env name)WP04
T014Rename status/adapters.py to transport-neutral names, no aliasesWP04
T015Rename emit._saas_fan_out, the lifecycle _hosted fan-out and every src/ callerWP04
T016Rename the test sink plugin (fail-loud), test files and path-keyed ledgersWP04
T017Retarget test references (patch strings, caplog text); run the blast radiusWP04
T018Update the G-11/G-16/G-18 gap-table rowsWP05[P]
T019ADR amendment notes (2026-10-13-2, 2026-10-14-1, 2026-04-25-1) + stale seam doc mentionsWP05[P]
T020Env-var reference + [Unreleased] changelog entry (breaking)WP05[P]
T021Docs freshness + terminology gatesWP05

WP01 — Test seeding helper and codemod (tidy-first)

Goal: Every test that seeds status.events.jsonl through specify_cli.status.store.append_event moves onto a test-only helper over the atomic primitive. No production change. Priority: P1 (it blocks WP02). Prompt: tasks/WP01-test-seeding-helper-and-codemod.md Independent test: after the codemod, the old name appears in no test outside the door's own tests (tests/status/test_store.py, test_store_sanitized.py), and every codemodded file passes.

T001 Seeding helper tests/_support/status_seed.py + its tests (WP01) T002 Codemod module-level imports of store.append_event in tests (WP01) T003 Codemod function-local imports; delete the identity spy (WP01) T004 Batch multi-row seeds; run the codemodded blast radius (WP01)

Dependencies: none. Risks: the durability-matrix worker blocks on os.replace (census), and the file mode becomes 0600. Neither is asserted by any test.

WP02 — Delete the dead write doors (#6614)

Goal: Remove store.append_event, append_event_verified, append_primary_checkout_event_verified, coordination.status_service.append_event_log and invocations_cmd.append_to_index. The existing gates are re-pinned red-first so the doors cannot return. A single-writer check covers ops-index.jsonl. Priority: P1. Prompt: tasks/WP02-delete-dead-write-doors.md Independent test: test_status_unsafe_allowlist.py, test_status_events_writes_gate.py and test_no_dead_symbols.py fail on the pre-change tree and pass after.

T005 Red-first: re-pin the door gates (unsafe allowlist, writes gate, index single writer) (WP02) T006 Delete the store doors; shrink _unsafe; fix docstrings; drop the door's own tests (WP02) T007 Delete append_event_log; retarget its tests onto append_event_stream_log (WP02) T008 Delete append_to_index; retarget invocation tests (WP02) T009 Shrink the dead-symbol allowlist and _baselines.yaml; run the blast radius (WP02)

Dependencies: WP01. Risks: contract-validation coverage must move, not vanish.

WP03 — Dead hosted lifecycle builder and public-imports gate (#6607, part 1)

Goal: Delete build_saas_lifecycle_queue_event, _canonical_lifecycle_payload_for_saas, _validate_lifecycle_payload and repo_root_for_lifecycle_log, which takes core's only private spec_kitty_events import with them. Widen test_events_tracker_public_imports.py to every production root and any private name. Priority: P1. Prompt: tasks/WP03-dead-hosted-builder-and-public-imports-gate.md Independent test: the widened gate is red on the pre-change tree (it reports lifecycle_events.py:368) and green after. Its planted-fault self-test stays red-capable.

T010 Red-first: widen the public-imports gate (all roots, any private name) (WP03) T011 Delete the hosted lifecycle builder family + repo_root_for_lifecycle_log + facade exports (WP03) T012 Retarget/delete the builder's tests; run the blast radius (WP03)

Dependencies: WP02 (sequential write checkout; no code coupling).

WP04 — Transport-neutral produce seam (#6607, part 2)

Goal: The seam and its residue get transport-neutral names, with no aliases (operator ruling). Behaviour is pinned by a stub-handler contract test. Priority: P2. Prompt: tasks/WP04-transport-neutral-produce-seam.md Independent test: the contract test passes. grep -ni saas src/specify_cli/status/adapters.py is empty. The old env var has no effect.

T013 Red-first: stub-handler contract test + extended timeout test (new env name) (WP04) T014 Rename status/adapters.py to transport-neutral names, no aliases (WP04) T015 Rename emit._saas_fan_out, the lifecycle _hosted fan-out and every src/ caller (WP04) T016 Rename the test sink plugin (fail-loud), test files and path-keyed ledgers (WP04) T017 Retarget test references (patch strings, caplog text); run the blast radius (WP04)

Dependencies: WP03 (shares status/__init__.py and lifecycle_events.py).

WP05 — Docs, ADR amendment notes, changelog

Goal: The documentation reflects the closure of G-11, G-16 and G-18, the renamed env var and seam API (breaking), and the public-symbols-only boundary. Priority: P3. Prompt: tasks/WP05-docs-adr-notes-changelog.md

T018 Update the G-11/G-16/G-18 gap-table rows (WP05) T019 ADR amendment notes (2026-10-13-2, 2026-10-14-1, 2026-04-25-1) + stale seam doc mentions (WP05) T020 Env-var reference + [Unreleased] changelog entry (breaking) (WP05) T021 Docs freshness + terminology gates (WP05)

Dependencies: WP02, WP03, WP04.

Parallelization

None: single_branch runs the work packages sequentially. Within WP05, T018–T020 are independent.

MVP

WP01 + WP02 close #6614. WP03 + WP04 close #6607.