Implementation Plan: Coord/primary partition-authority residuals
Branch: fix/partition-authority-residuals | Date: 2026-08-15 | Spec: spec.md Input: Feature specification from kitty-specs/partition-authority-residuals-01M021K9/spec.md
Summary
Finish the residual out-of-loop / cross-function callers that resolve the wrong partition surface under coordination topology, so read and write agree per INV-5. Every partition fix is a caller reroute to the existing mission_runtime.artifacts SSOT (no predicate fork, no membership change). Two operator-directed scope areas: Scope A — partition-authority routing folds (#2959, #3439, #2698, #2939, #2966 p2, #2937); Scope B — diagnostic output fidelity via canonical writer-schema and canonical kitty-specs/* discovery, reducer/doctor slot fidelity, and migration-repair fidelity (#2692, #2696, #2717, #2960, #3066). #2704 and #2973 were reparented out of #2720; completing Scope B plus those reparents clears #2720 for close.
Technical approach: for each caller, replace the mis-resolved dir/read with the kind-aware placement_seam(...).read_dir(<kind>) / artifact_home_for(<kind>) (Scope A) or the canonical writer-schema / discovery source (Scope B), keeping STATUS-partition reads on COORD. Each fix carries a live coord-topology e2e that is red-before/green-after (the #3437 straggler lesson).
Technical Context
Language/Version: Python 3.11+ Primary Dependencies: existing spec-kitty (typer, rich, ruamel.yaml); mission_runtime (artifacts, placement_seam, artifact_home_for, is_primary_artifact_kind); status., merge., coordination., audit.. Storage: git-committed mission artifacts partitioned across PRIMARY (target branch) and COORD (coordination branch); status.events.jsonl event log. Testing: pytest; live coord-topology e2e (test_cli_smoke-style create→finalize→implement →review→merge on a coord mission) per fix, plus targeted unit tests and tests/architectural/ guards. Run targeted only (full suite ~1h — CI is the release authority). Target Platform: Linux/macOS CLI. Project Type: single (CLI). Performance Goals: N/A — correctness/reliability mission (no perf budget). Constraints: no predicate fork / no new legacy resolver path (C-001); STATUS reads stay COORD (C-002); canonical schema/discovery sources (C-005); ruff + mypy clean, complexity ≤15 (NFR-003); second-order gates green (C-003: cutover-guard status_phase, diff-coverage critical-paths, compat-surface superset, completeness baselines). Scale/Scope: ~13 FRs across ~10 modules; coord-topology behavior is the focus (non-coord missions are the no-op control).
Charter Check
GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.
SSOT; all Scope-B fixes route through the canonical writer schema / kitty-specs/* discovery. No forked predicate, no hand-rolled key set, no ad-hoc discovery glob (C-001, C-005). ✅ by design.
insufficient. Each WP lands its failing test first. ✅ enforced via DoD.
derivation, discovery iterator) tested directly (Sonar new-code coverage). ✅
code identifiers only. Run pytest tests/architectural/test_no_legacy_terminology.py pre-push. ✅
status_phase flip may be required (cf. the write-path-integrity landing). Re-check after design.
- Single canonical authority — all Scope-A fixes route through the
mission_runtime.artifacts - ATDD-first / red-first — NFR-001 mandates a red-before coord e2e per fix; unit reads alone are
- DDD + tiered rigour — pure caller reroutes; deterministic helper extractions (schema
- Terminology adherence — canonical Mission;
feature_dir/feature branchremain as existing - Architectural gate discipline — watch the second-order gates a fix trips (C-003); a cutover-guard
Re-check after Phase 1: confirm no concern introduced a predicate fork or a second canonical copy.
Project Structure
Documentation (this mission)
kitty-specs/partition-authority-residuals-01M021K9/
├── spec.md # committed
├── plan.md # this file
├── data-model.md # Phase 1 — partition-kind ↔ surface table + affected callers
├── quickstart.md # Phase 1 — how to run a coord-topology e2e locally
├── contracts/ # Phase 1 — the seam contracts each caller must honor (INV-5)
└── tasks.md # Phase 2 (/spec-kitty.tasks)
Source Code (repository root)
Brownfield — existing single-project layout. Touched surfaces:
src/
├── mission_runtime/artifacts.py # SSOT (READ-ONLY reference; do not fork)
├── specify_cli/
│ ├── policy/merge_gates.py # IC-02 (#3439 risk/dep gates)
│ ├── coordination/commit_router.py # IC-01/IC-03 reference (partition split)
│ ├── cli/commands/
│ │ ├── merge.py # IC-01 (#2959 escape hatch)
│ │ ├── safe_commit_cmd.py # IC-05 (#2966 p2)
│ │ ├── doctor.py # IC-07 (#2696 --mission)
│ │ ├── retrospect.py # IC-07 (#2717 discovery)
│ │ └── agent/
│ │ ├── tasks_materialization.py # IC-01 (#2959 override write)
│ │ ├── tasks_verdict_persistence.py # IC-01 (#2959 caller)
│ │ ├── tasks_move_task.py # IC-03 (#2939 annotation commit)
│ │ ├── tasks_dependency_graph.py # IC-02 (#3439 C-009 lift)
│ │ ├── workflow.py # IC-02 (#3439 bulk-edit diff base)
│ │ └── mission_finalize.py # IC-06 (#2937 wps.yaml)
│ ├── status/emit.py # IC-01/IC-03 (emit_inner_state_changed:971-1041)
│ ├── merge/{preflight.py,forecast.py} # IC-01 (gate consumers)
│ ├── post_merge/review_artifact_consistency.py # IC-01 (gate read)
│ ├── core/{worktree_topology.py,worktree.py} # IC-04 (#2698), IC-07 (#2692)
│ ├── status/lane_reader.py # IC-04 (#2698)
│ ├── audit/{shape_registry.py,classifiers/meta.py} # IC-07 (#2696 schema)
│ ├── mission_metadata.py # IC-07 (#2696 canonical schema source)
│ └── retrospective/summary.py # IC-07 (#2717 discovery)
tests/
├── e2e / cli_smoke # coord-topology e2e per fix (NFR-001)
├── unit (mirrors touched modules)
└── architectural/ # guards: no predicate fork, terminology, placement-stability (#2198)
Structure Decision: No new top-level structure. src/mission_runtime/artifacts.py is the SSOT and is reference-only — fixes reroute callers to it, they do not modify membership. A small number of new shared helpers are introduced for Scope B (one canonical kitty-specs/* mission-instance iterator; one writer-schema-derived key set) — each with its own focused tests — to avoid the two-copy trap (C-005).
Complexity Tracking
No Charter Check violations. All changes are caller reroutes plus small tested helper extractions; no new project, no new pattern, no predicate fork. Nothing to justify here.
Implementation Concern Map
> Concerns are architectural areas, not work packages. /spec-kitty.tasks translates these into WPs.
IC-01 — Merge review-artifact gate: partition-correct override + escape hatch (#2959)
STATUS_STATE surface the merge gate reads, and give the gate a sanctioned override escape hatch.
reroute is caller-side: resolve placement_seam(...).read_dir(STATUS_STATE) and pass that dir in), tasks_verdict_persistence.py:547-571, cli/commands/merge.py:420-446 (new --skip-review-artifact-check/--note), gate consumers post_merge/review_artifact_consistency.py:243, merge/preflight.py:361, merge/forecast.py:203. status/emit.py:971-1041 (emit_inner_state_changed) stays GENERIC — do NOT make it topology-aware; fixing at the caller mirrors the proven tasks_dependency_graph.py:120-135 pattern and avoids blast radius on the shell_pid/note/subtask annotations that also flow through it.
common dependency with IC-03 — but the two fixes sit at different callers and are orthogonal (routing vs durability); coordinate, do NOT merge into one WP** (and do not edit the shared function for either). Shares the merge-preflight seam (not a function) with IC-02 — land coherently, one shared coord e2e (reject→override→merge).
must register the coord worktree. The escape hatch must record evidence (parity with move-task), not silently bypass.
- Purpose: Kill the coord merge deadlock — make the ReviewOverride write land on the same COORD
- Relevant requirements: FR-001, FR-002.
- Affected surfaces:
tasks_materialization.py:78-90(_persist_review_artifact_override— the - Sequencing/depends-on: none upstream. **Shares
emit_inner_state_changed(emit.py:971-1041) as a - Risks:
canonicalize_feature_dirrewrites unregistered coord paths back to PRIMARY — the e2e
IC-02 — Merge gates read real PRIMARY data on coord missions (#3439)
coord missions; lift the C-009 pin.
WORK_PACKAGE_TASK via the seam; keep the STATUS_STATE read on coord), workflow.py:202 (bulk-edit diff base), tasks_dependency_graph.py:132 (remove the C-009 deferral note).
evaluate_merge_gates orchestration pass — NOT the same module; US1's consuming gate is in post_merge/review_artifact_consistency.py). One combined coord-merge e2e can assert both a fired risk gate and an honored override.
_evaluate_risk_gate/_evaluate_dependency_gate currently take only (feature_dir, is_blocking) and have no way to build placement_seam; evaluate_merge_gates already receives repo_root (line 91), so pass it (and mission_slug) down and resolve LANE_STATE/WORK_PACKAGE_TASK per-leg there (proven pattern: tasks_dependency_graph.py:120-135). Must NOT over-correct the STATUS_STATE read to PRIMARY (C-002).
- Purpose: Stop the risk gate silently SKIPping and the dependency gate seeing an empty graph on
- Relevant requirements: FR-003, FR-004, FR-005.
- Affected surfaces:
policy/merge_gates.py:86/194/242(per-leg resolve LANE_STATE / - Sequencing/depends-on: none. Coordinate with IC-01 on the shared merge-preflight seam (the
- Risks: first-class structural task — thread
repo_root+mission_sluginto the gate helpers.
IC-03 — Status annotation durability via emit_inner_state_changed (#2939)
move-task never returns with a dirty status tree.
bookkeeping transaction or a second atomic status commit), status/emit.py:971-1041.
but the fix is caller-side in tasks_move_task.py (commit the annotation), NOT an edit to emit_inner_state_changed** — which stays generic for both concerns. Keep IC-01 and IC-03 as separate WPs; neither edits the shared function.
along — cover both in the e2e.
- Purpose: Ensure the post-transition
InnerStateChangedannotation is committed atomically so - Relevant requirements: FR-007.
- Affected surfaces:
tasks_move_task.py:2190-2318(gather the annotation into the same - Sequencing/depends-on: **Shares
emit_inner_state_changedwith IC-01 as a common dependency, - Risks: also affects the non-rejection
→for_reviewpath when a note/agent annotation rides
IC-04 — Review-handoff lane read via the coord-aware surface (#2698)
of a blanket stale planned.
coord-aware STATUS_STATE surface. Manifests only on multi-WP coord missions with stacking — the e2e must build one.
- Purpose: Make the generated review handoff show true per-WP lane state on coord missions instead
- Relevant requirements: FR-006.
- Affected surfaces:
core/worktree_topology.py:147-149/207,status/lane_reader.py:51-76. - Sequencing/depends-on: none (independent, localized).
- Risks: keep the PRIMARY dir for identity/lanes/tasks; only the per-WP lane read moves to the
IC-05 — Write-target consolidation: the 4th safe-commit sibling (#2966 part-2)
resolve_write_target_or_degrade (+ pre-gate + caught-set).
CONSOLIDATED_CONTENT_ABSENT → MissionAwareCommitRefused, and benign FileNotFoundError/ValueError → None degrade. Route through resolve_write_target_or_degrade without dropping that caught-set, or a legitimate operator commit that merely looks mission-scoped will start failing. Assert refusal-parity.
- Purpose: Align
_resolve_mission_aware_targetwith the three siblings that already route through - Relevant requirements: FR-008.
- Affected surfaces:
cli/commands/safe_commit_cmd.py:278-307. - Sequencing/depends-on: none (independent, smallest concern).
- Risks: pure consolidation — but preserve the refusal-semantics contract:
IC-06 — finalize checkpoints wps.yaml (#2937) — gated on D-001
rules it versioned).
a wps.yaml → TASKS_INDEX classifier entry in mission_runtime/artifacts.py (membership add for a currently-unclassified file — the one place a classifier change is in play; still not a predicate fork).
FR-009 becomes a documentation + files_committed reporting change instead.
- Purpose: Make the finalize checkpoint reproduce its own state by committing
wps.yaml(if D-001 - Relevant requirements: FR-009.
- Affected surfaces:
cli/commands/agent/mission_finalize.py:187-216/449-461, - Sequencing/depends-on: Decision D-001 (version vs document-as-non-versioned). If non-versioned:
- Risks:
wps.yamlis operator-authored input — confirm the lifecycle before committing it.
IC-07 — Diagnostic output fidelity: canonical schema + canonical discovery (#2692, #2696, #2717)
kitty-specs/* mission-instance discovery, eliminating false inventories / false schema findings / false missing-record counts.
metadata; fix research_dir semantics) + tests/git_ops/test_worktree.py:465,487; audit/shape_registry.py:31-47 + audit/classifiers/meta.py:110 (derive meta.json known-keys from mission_metadata.py:47-87 TypedDicts + coordination keys); cli/commands/doctor.py:1258 (--mission for coordination_health); retrospective/summary.py:296-303 + cli/commands/retrospect.py:1003-1005 (route both through one canonical kitty-specs/* iterator).
route both #2717 sites through it (avoid the two-copy trap); build the writer-schema key derivation once for #2696 (and reuse the artifacts-metadata source for #2692's inventory).
the specific keys/inventory, not just exit codes. Each canonical source needs a regression test that goes red if the writer schema/artifact set drifts again (NFR-004).
- Purpose: Source read-only diagnostics from the canonical writer schema and the canonical
- Relevant requirements: FR-010, FR-011, FR-012, FR-013.
- Affected surfaces:
core/worktree.py:661-706/718-721(inventory from missionartifacts - Sequencing/depends-on: none upstream. Internally: build the shared discovery iterator once and
- Risks: findings are INFO severity (won't fail gates unless
--fail-on info), so tests must assert
IC-08 — Reducer/doctor runtime-slot fidelity (#2960)
reporting Healthy over the corrupt state.
treat empty strings as no-op; status/models.py:460+ (WPInnerStateDelta) — normalize ""→None at the write boundary so the log never records a blanking delta; status/doctor.py — new check for empty-string runtime slots on non-terminal WPs.
site producing "" is unconfirmed); the reducer guard + doctor check are defense-in-depth. Regression test: fold agent:"" over agent:"claude" and assert survival + a non-Healthy doctor verdict.
- Purpose: Stop
agent: ""silently blanking recorded attribution, and stopstatus doctor - Relevant requirements: FR-014.
- Affected surfaces:
status/reducer.py:262-264(replace-slot fold) +:185(claim arm) — - Sequencing/depends-on: none. Scope B (C-007): must not share a WP with any Scope-A concern.
- Risks: pick the right fix altitude — write-boundary normalization is the durable net (the emit
IC-09 — Migration repair preserves legacy WPStatusChanged transitions (#3066)
transitions and regenerating a zero-WP status.json (a data-destroying repair, P1).
_is_preserved_non_lane_row). Adopt PR #3067's diff: add _is_legacy_typed_lane_transition(row) (true when event_type == "WPStatusChanged" AND wp_id/from_lane/to_lane all present) and route it via passthrough at the head of the rule, before the quarantine branches.
reroll it onto current main rather than re-implementing; keep its red-first migration test.
stay quarantined — only the canonical-writer WPStatusChanged shape passes through. The repair is mutating, so the test must assert status.json retains the WPs after --fix.
- Purpose: Stop
doctor mission-state --fixquarantining legacyWPStatusChangedlane - Relevant requirements: FR-015.
- Affected surfaces:
migration/mission_state.py:1583-1667(_rule_reject_non_status_event/ - Sequencing/depends-on: none. Scope B (C-007). Reuses the existing (stale) PR #3067 diff —
- Risks: TeamSpace envelopes (lane fields under
payload) andDecisionPointOpenedmirrors MUST
Cross-cutting notes
split this mission prescribes — read_dir(STATUS_STATE) (coord) + read_dir(WORK_PACKAGE_TASK) (primary) passed into an unchanged helper signature. Cite it as the pattern for IC-01/IC-02/IC-04; it proves no predicate fork and no shared-helper surgery is required.
partition reroute and a Scope-B schema/discovery fix in the same WP — disjoint modules, different canonical sources, different test families (NFR-001 coord-e2e vs NFR-004 schema-drift guards). IC-01… IC-06 are Scope A; IC-07/IC-08/IC-09 are Scope B and decompose into their own WP(s).
IC-03 both flow through it but fix at their own callers; neither WP edits the function. This removes the apparent shared-file conflict.
repo_root/mission_slug once and land both on a shared coord-merge e2e.
behavior (the reroutes are no-ops off coord topology).
(status_phase), diff-coverage critical-paths, the compat-surface superset, or completeness baselines.
- Reference implementation:
tasks_dependency_graph.py:120-135already performs the exact per-leg - Scope-A / Scope-B WP separability (C-007, HIGH):
/spec-kitty.tasksMUST NOT put a Scope-A emit_inner_state_changed(emit.py:971-1041) is a shared DEPENDENCY, not a shared edit: IC-01 and- Shared-seam coordination (must not diverge): the merge-preflight pass (IC-01 + IC-02) — thread
- Non-coord control: every concern's tests include a SINGLE_BRANCH/LANES control asserting identical
- Second-order gates (C-003): after design, re-check whether any concern trips cutover-guard