Added
- Post-merge reliability and release hardening (mission 068) — 5 work packages closing the workflow-stabilization track:
- Stale-assertion analyzer (WP01) — new
src/specify_cli/post_merge/package: stdlibast-based tool that detects test assertions likely invalidated by merged source changes. CLI:spec-kitty agent tests stale-check --base <ref> --head <ref> [--json]. Integrated into the merge runner. No new dependencies, no network calls. - Merge strategy + safe-commit + linear-history hint (WP02) —
MergeStrategyenum (MERGE/SQUASH/REBASE) in newsrc/specify_cli/merge/config.pywith--strategyCLI flag (resolves: flag →.kittify/config.yaml→ squash default).safe_commit()called after_mark_wp_merged_donebefore worktree removal (FR-019). Linear-history rejection hint guides users past protected-branch push failures. Closes #456. - Diff-coverage policy validation (WP03) — validation report confirms the enforce/advisory split already satisfies the policy intent. CI step names tightened to
diff-coverage (critical-path, enforced)anddiff-coverage (full-diff, advisory). Closes #455. - Release-prep CLI (WP04) — new
src/specify_cli/release/package:propose_version(),build_changelog_block(),ReleasePrepPayload. CLI:spec-kitty agent release prep --channel {alpha,beta,stable} [--json]. Zero network calls. Closes #457. - Recovery extension + mission close (WP05) —
scan_recovery_state()extended withconsult_status_events=Trueto detect merged-and-deleted WPs via event log; newRecoveryState.ready_to_start_from_targetfield.spec-kitty implementgains--base <ref>flag for explicit worktree branching. Closes #415.
- Stale-assertion analyzer (WP01) — new
Fixed
implement --baseTyper pattern — changed to Annotated pattern, fixing test isolation failures where direct Python calls receivedOptionInfoobjects instead ofNoneimplementconsole capsys isolation —_json_safe_outputwrapper now resetsconsole._file = Noneinfinallyto prevent "I/O operation on closed file" when tests run in sequence with pytest capsys- Replay parity test — corrected
reduced.mission_key == "replay-mission"(was wrong field name and wrong value)