Research: Runtime-State Birth-Cutover (All Landing Paths)

Synthesis of the pre-planning grounding squad (reuse/related-issues lens + adversarial lens; brownfield lens partial — its ground was covered by the reuse lens). Decisions here are inputs the plan/tasks must honor.

Settled context (do not re-litigate)

authority path; a second stamp that resolves paths differently is a regression.

writer cutover → delete fallbacks contract and made the snapshot reader unconditional. status_phase's only remaining live effect is gating the legacy lane mirror (emit.py:401`), a no-op for new missions — the drift is real but runtime-inert; it is a latent invariant violation, not a runtime break.

(retire frontmatter authoring — already done by #2684/#2816 — then stamp at birth and re-key the guard to an event-log birth invariant). Newest diagnosis: the #2920 seam fires only in merge/executor.py (the spec-kitty merge path); GitHub squash/rebase landings never trigger it → recurrence.

(1) the flip was moved post-target with idempotent resume-heal because canonicalize_feature_dir → resolve_canonical_root redirects a worktree's .git to the main repo root and a pre-merge flip writes a stale meta.json; (2) the seed-event commit must target the coord ref (committing a COORD artifact through the PRIMARY bookkeeping seam raised SafeCommitHeadMismatch). Deferred follow-up #2923: route _flip_phase through the placement port.

the WP1 front-load; the backlog is cleared, so this mission focuses on the structural fix + guard.

  • #2160 — single artifact authority thesis. There is one canonical
  • #2816 — established the `backfill → verify(fail-closed) → reader cutover →
  • #2917 (reopened) — root cause: no birth-time cutover seam; Option-C chosen
  • #2920 — birth-cutover-at-merge. Two load-bearing engineering calls:
  • #2968 — mechanical whole-corpus re-green (data-only), Refs #2917. This is

Reuse map (extend, do not duplicate)

orchestrated seed → fail-closed verify → atomic flip, topology-aware via the status_feature_dir (COORD) kwarg; _flip_phase (:186) is the sole status_phase writer; cutover_repo(dry_run=True) (:315) backs the audit.

accept-time stamp mirrors this shape so the two callers share one function.

_mission_carries_event_log_runtime (:142) + _assert_birth_invariant_holds (:242), NOT bare verify_backfill.

(per-subcommand-module doctor convention).

release-readiness.yml), with kitty-specs/** added to its trigger paths.

  • Single stamp authority: runtime_state_cutover.cutover_mission (:234) — the
  • Reference wiring: merge/executor.py::_run_birth_cutover (:939) — the
  • Guard predicate: reuse test_dogfood_corpus_backfilled.py's
  • Audit host: spec-kitty doctor cutover subcommand shell → _cutover_doctor.py
  • Guard CI host: a pull_request-scoped, fail-closed job (candidate

Decisions & rejected alternatives

DecisionRationale
Stamp at terminal accept, not create/finalizeRuntime state must be final (dual-write trap); accept runs on-branch, pre-PR, already commits residual artifacts.
Guard keys on event-log evidence, not verify_backfill.okverify_backfill is vacuously green for natively-born missions (no frontmatter to seed → wp_count=0, ok=True).
Guard is the binding backstop; stamp is best-effortSeam-bypass paths (direct-authored, cancelled, mid-flight, later-mission edits) never hit the terminal stamp.
Pin claim-anchor to one canonical legPrevents flipped-but-unverifiable corpus from divergent seed payloads (R5).
Fail closed on absent mission_idSlug-namespaced seeds change identity when mission_id is later minted → duplicate/divergent events (R6).
No further one-time backfill#2968 already re-greened whole-corpus; stamp + diff-guard hold the line.
Rejected: relax the acceptance predicateGreen-washing a valid lock; rejected twice on #2917.
Rejected: post-merge reconcile pushing to mainViolates no-direct-push (C-001).

Open verification items for implementation

kitty-specs/** and confirm the guard job appears, executes, and can fail. A required check that is if:-skipped passes silently.

assert byte-identical status.events.jsonl.

  • Live path-filter check (R1): open a scratch PR touching only
  • 30s bound (NFR-002): measure the diff-scoped guard on the real corpus.
  • Payload determinism (R5): run the stamp twice from different leg contexts;