Implementation Plan: Implement lane-allocation integrity
Branch: fix/implement-lane-recut-and-planning-commit-integrity | Date: 2026-09-25 | Spec: spec.md Input: Feature specification from kitty-specs/implement-lane-recut-and-planning-commit-integrity-01M3CM55/spec.md
Summary
Two fail-closed / correctness fixes in the implement lane-allocation seam, folded into one mission because they share a module and call chain (allocate_lane_worktree → _merge_recorded_planning_commit):
1. #4889 (P0) — allocate_lane_worktree routes on two structural predicates (worktree_path.exists() REUSE, _branch_exists() CRASH_RECOVERY) and falls through to a FRESH route that consults no WP lane state. A lane destroyed (worktree + branch both gone) while its WP is non-terminal is indistinguishable from a never-allocated lane → silent empty re-cut, exit 0, committed work stranded. Fix: a fail-closed pre-flight inside allocate_lane_worktree (covering both callers — the CLI create_lane_workspace and the orchestrator-api _resolve_start_workspace) keyed on persisted WorkspaceContext + non-terminal canonical status + both refs gone + persisted tip not reachable on target.
2. #4905 (P1) — on coord/lanes_with_coord, the agent-verb lifecycle commit stages the PRIMARY-partition tasks/WP*.md onto the coordination branch at three sites, all through the shared sink _commit_via_coordination_transaction. The next lane's FR-009 planning merge then hits an add/add conflict. Fix: partition staged paths by artifact kind at the shared sink so a WORK_PACKAGE_TASK file routes to the PRIMARY target and never lands on coord.
Both are dogfooded on this very mission (coord topology). Fail-closed posture, smallest-viable-diff, red-first per ADR 2026-07-17-1.
Technical Context
Language/Version: Python 3.11+ Primary Dependencies: no new dependencies (stdlib + existing specify_cli, mission_runtime, kernel, spec_kitty_events surfaces); pytest for tests. This mission adds/upgrades/removes zero dependencies, so the supply-chain-install-safety gate is N/A (recorded in research.md). Storage: git (branches, worktrees, refs); .kittify/workspaces/<slug>-lane-<id>.json (persisted WorkspaceContext); status.events.jsonl (append-only canonical status log) Testing: pytest — unit + regression (@pytest.mark.regression) in tests/lanes/, tests/specify_cli/, tests/orchestrator_api/; targeted file-scoped runs, not whole-suite Target Platform: Linux/macOS/Windows dev environments (the CLI) Project Type: single (Python CLI + library) Performance Goals: N/A — correctness/reliability fix; no hot path changed. Added git ancestry probe (FR-009) runs only on the already-slow fresh-allocation path. Constraints: every added/modified function complexity ≤ 15 (Ruff C901 / Sonar S3776); no new # noqa/# type: ignore; new branches/helpers covered by focused tests in the same change; read status from the resolved coordination surface, never the sparse-excluded lane tree Scale/Scope: two write sites + a shared regression WP; ~3 source files touched (lanes/worktree_allocator.py, cli/commands/agent/workflow.py + workflow_executor.py), plus tests
Constitution Check
GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.
Charter (.kittify/charter/charter.md) governing points applied:
- Single canonical authority — #4889 reuses the existing
WorkspaceContext+ status reducer (no second lane-state authority); #4905 reuses the existingcommit_to_primary_target/is_primary_artifact_kindpartition mechanism rather than a new merge driver. ✅ - ATDD / red-first (Standing Order #4, ADR 2026-07-17-1) — each defect lands an issue-pinned
@pytest.mark.regressionrepro RED through the real entry point before the fix. ✅ - Architectural gate discipline (Standing Order #5) — the fix is placed by construction at the shared seam both callers / all three staging sites pass through, so the defect class is closed rather than patched per-caller. ✅
- Smallest-viable-diff + locality (RECONCILE_CHANGE_SCOPE_TENSIONS) — two write sites; already-polluted coord corpora and an auto-recovery subcommand are explicitly out of scope. ✅
- Terminology canon — "Mission"/"work package"/"lane"; no
feature*aliases introduced. ✅ - Model discipline — implement=sonnet, review=opus, profile-loaded delegations. ✅
No violations to justify (Complexity Tracking empty).
Project Structure
Documentation (this mission)
kitty-specs/implement-lane-recut-and-planning-commit-integrity-01M3CM55/
├── plan.md # This file
├── spec.md # Committed
├── research.md # Phase 0 output
├── data-model.md # Phase 1 output
├── quickstart.md # Phase 1 output
├── contracts/ # Phase 1 output (behavioural contracts)
├── checklists/ # requirements.md (spec quality)
├── traces/ # approach / design-decisions / tooling-friction
└── tasks/ # Phase 2 output (/spec-kitty.tasks — NOT created here)
Source Code (repository root)
src/specify_cli/
├── lanes/
│ ├── worktree_allocator.py # WP01: fail-closed destroyed-lane pre-flight before FRESH routes (covers both callers)
│ ├── implement_support.py # WP01: create_lane_workspace — call site of the allocator (CLI caller)
│ └── recovery.py # (read-only reference: WorkspaceContext helpers; not an allocator caller)
├── cli/commands/agent/
│ ├── workflow.py # WP02: _commit_via_coordination_transaction — the shared sink; partition paths by kind
│ └── workflow_executor.py # WP02: three staging sites funnel here (claim 876 / resume 1061 / review-claim 1736)
├── orchestrator_api/
│ └── commands.py # WP01: _resolve_start_workspace (second allocator caller) — covered for free by allocator-level guard
├── workspace/context.py # persisted WorkspaceContext (load/save/find_context_for_wp) — read by WP01
└── mission_runtime/… # is_primary_artifact_kind — reused by WP02
tests/
├── lanes/ # WP01 + WP03 regression (allocator routes)
├── specify_cli/ (cli/commands) # WP02 coord-staging regression
└── orchestrator_api/ # WP01 caller-independence regression
Structure Decision: single Python project; changes are localized to src/specify_cli/lanes/ (WP01) and src/specify_cli/cli/commands/agent/ (WP02), with the WP01 guard placed inside the shared allocator so the orchestrator-api caller is covered without editing orchestrator_api/commands.py.
Complexity Tracking
No Constitution Check violations — table intentionally empty.
Parallel Work Analysis
Dependency Graph
WP01 (#4889 fail-closed detector, lanes/worktree_allocator.py) ─┐
├─→ WP03 (shared regression + FR-009 resilience)
WP02 (#4905 coord-staging partition, agent/workflow*.py) ─┘
WP01 ∥ WP02 (write-scope-disjoint, no inter-gating) then WP03 depends on {WP01, WP02}
Work Distribution
- Sequential work: none up front — WP01 and WP02 have disjoint write scopes (verified by the post-spec architecture lens: the orchestrator status commit in
coordination/status_transition.pyis already partitioned and stages only status artifacts to coord, so #4905 is confined to the CLIworkflow*.pypath and does not touch WP01'sworktree_allocator.py). - Parallel streams:
- WP01 —
lanes/worktree_allocator.py(pre-flight guard), readingworkspace/context.py+ the status reducer. - WP02 —
cli/commands/agent/workflow.py+workflow_executor.py(partition staged paths by kind at the shared sink). - Convergence: WP03 lands the cross-cutting regression proof (RED-first repros for #4889 across REUSE/CRASH_RECOVERY/FRESH + both callers; #4905 across claim + review-claim) plus any FR-009
_merge_recorded_planning_commitresilience assertion. It depends on both fixes being present so its green state is meaningful.
Coordination Points
- Sync schedule:
spec-kitty mergeconsolidates the lanes into the feature branch after all WPs are approved. - Integration tests: WP03 exercises both defects end-to-end through the real
implement/agent action implemententry points on a coord mission; the review-claim assertion (SC-003) guards the multi-site #4905 fix.
Phase 0 / Phase 1 outputs
research.md— decision log (detector placement, status-key breadth, false-positive bound, #4905 shared-sink partitioning) + supply-chain N/A record + adversarial-evidence dispositions from the post-spec lens.data-model.md— the lane-allocation route state,WorkspaceContextfields, the destroyed-lane decision table, and the coord-commit path-partition rule.contracts/— behavioural contracts for the fail-closed detector and the coord-staging partition.quickstart.md— how to reproduce both defects and verify the fixes.