Implementation Plan: Merge Preflight Remote-State Boundary Separation
Branch: main | Date: 2026-06-05 | Spec: spec.md Mission ID: 01KTBE5MPD24VTVFHXKCF8MGHN Input: kitty-specs/merge-preflight-remote-state-boundary-separation-01KTBE5M/spec.md
Branch contract (confirmed twice per policy):
- Current branch at plan start:
main - Intended planning/base branch:
main - Final merge target for completed changes:
main branch_matches_target: true ✓
Summary
The merge command currently performs a live network fetch against origin and blocks local branch integration if the local target is not in sync with the remote. This is architecturally inverted: local merge is a domain-layer operation with no dependency on remote state; the remote-sync check is a publish-layer concern. The fix moves the remote-state fetch and push-safety check to a dedicated push-preflight module, corrects the TargetBranchSyncStatus safety predicate, gates the check on push intent at the call site, and adds a push_requested field to MergeState for correct resume semantics.
Research findings (Phase 0) confirm the exact change surface. Design artifacts (Phase 1) specify the updated value objects and new module interface.
Technical Context
Language/Version: Python 3.11+ Primary Dependencies: typer (CLI framework), pytest (testing), mypy (strict mode) Storage: JSON state files at .kittify/runtime/merge/<mission_id>/state.json Testing: pytest with ≥90% coverage for modified modules; mypy --strict must pass with zero new type errors; integration tests for CLI merge command Target Platform: Linux, macOS, Windows (cross-platform per project policy) Project Type: Single Python package (src/specify_cli/) Performance Goals: Merge invocations without --push must perform no network I/O; push-gated fetch must add ≤3 seconds latency on a standard connection Constraints: MergeState JSON schema change must be backwards-compatible (absent push_requested field → default False); no changes to WP-level run_preflight(); no changes to forecast.py, status_resolver.py, or lane resolution
Charter Check
Policy summary (from .kittify/charter/charter.md):
- mypy --strict passes (no type errors)
- pytest 90%+ coverage for new code
- Integration tests for CLI commands
- Breaking changes documented in CHANGELOG.md
Gate assessment:
- ✅ New
push_preflight.pymodule requires full type annotation coverage - ✅
MergeState.push_requestedfield is backwards-compatible; not a breaking change - ✅ Removing the "focused PR path" guidance from
AGENTS.mdis a documentation correction, not a user-visible breaking change - ✅ CHANGELOG.md entry required for the behaviour change (local merge no longer blocked by origin sync state)
- ✅ Integration test required:
spec-kitty mergemust complete in an offline or diverged-state git fixture
No charter violations. All gates pass.
Project Structure
Documentation (this mission)
kitty-specs/merge-preflight-remote-state-boundary-separation-01KTBE5M/
├── plan.md # This file
├── research.md # Phase 0 output
├── data-model.md # Phase 1 output
└── tasks.md # Phase 2 output (via /spec-kitty.tasks — not created here)
Source Code (affected paths)
src/specify_cli/merge/
├── preflight.py # MODIFY: split is_safe predicate; scope docstring
├── push_preflight.py # NEW: push-layer remote-state fetch + push-safety check
├── state.py # MODIFY: add push_requested field to MergeState
└── [all other files unchanged]
src/specify_cli/cli/commands/
└── merge.py # MODIFY: gate _enforce_target_branch_sync_preflight on push
tests/merge/
└── test_target_branch_preflight.py # MODIFY: invert ahead-blocked tests; add regression tests
architecture/3.x/adr/
└── 2026-06-05-1-merge-publish-layer-boundary.md # NEW: ADR documenting the boundary decision
AGENTS.md # MODIFY: remove focused-PR-path workaround guidance
CHANGELOG.md # MODIFY: document behaviour change
Structure Decision: Single project layout. All changes are within the existing package. One new file (push_preflight.py) in the existing merge/ package. One new ADR in architecture/3.x/adr/.
Complexity Tracking
No charter violations. No complexity justification required.