Fixed — CI recovery & release readiness
release-readinessworkflow now filterswindows_citests on the Linux runner. The job was running the full suite with no marker filter, failing 10 Windows-only tests (auth file-fallback, kernel paths, sync daemon paths, tracker credentials, migrate messaging, keyring packaging, lock contention, Windows home path). Those tests continue to run on the nativeci-windows.ymljob.- Kiro agent registration completed: added
.kiro/togitignore_manager.AGENT_DIRECTORIES, regenerated 11 canonical command baselines undertests/specify_cli/regression/_twelve_agent_baseline/kiro/, and updated the four count constants that had drifted after PR #626 (13 slash-command agents, 15AGENT_DIRECTORIESentries). - Auth test fixtures aligned with the hardened HTTP transport introduced in
Harden SaaS auth and restore build sync emission. Tests forAuthorizationCodeFlow,TokenRefreshFlow,WebSocketTokenProvisioner, and the browser-login/refresh-transport integration paths now patchPublicHttpClientin each flow module's own namespace (matching the production call graph) instead of rawhttpx.AsyncClient. Network-error paths raiseNetworkErrorfrom the client mock rather thanhttpx.ConnectErrorto match the newexcept NetworkErrorcontract. ResolutionTierunified acrossdoctrine.resolverandspecify_cli.runtime.resolver.specify_cli.runtime.resolveris now a thin re-export shim, as its own docstring had claimed. Tests assert tier equivalence via.nameto stay robust againstpytestarch's filesystem-walk loader, which can load the same source file under alternate module names duringpytest --import-mode=importlib.- Post-
unified-charter-bundle-chokepointtest fixture hardening: three pre-existing tests (test_local_support_declarations_end_to_end,test_template_prompt_bootstrap_context_first_load,test_all_pass_with_healthy_setup) nowgit inittheir tmp directories to satisfy the newresolve_canonical_repo_rootprecondition that callsgit rev-parse --git-common-dir. - Codex / Vibe Agent Skills migration test alignment: five tests that pre-dated mission 083 were updated to assert the new
.agents/skills/spec-kitty.<cmd>/SKILL.mdlayout rather than the retired.codex/prompts/layout. Invariants preserved (directspec-kitty agent actionCLI calls, per-agent argument handling, agent assets generation); only the probe path changed to match the post-083 architecture. - Contract handoff fixture updated to include
BuildRegisteredandBuildHeartbeatevent types added on the emitter side by the SaaS-auth hardening. - Miscellaneous tails: redacted a dev-machine path literal in an architecture review doc (caught by
test_command_template_cleanliness); fixedtest_rewrite_shims.py::test_result_countsto use two slash-command agents since codex is no longer one; markedtest_home_unit.py::TestGetKittifyHomeWindows::test_windows_default_pathwindows_cisince DRIFT-3 of the Windows Compatibility Hardening mission madeget_kittify_home()delegate tospecify_cli.paths.get_runtime_root().base, which the monkeypatch-based simulation no longer drives reliably on non-Windows runners. - Kiro regenerated baselines for all 12 canonical commands, closing the
tests/specify_cli/regression/test_twelve_agent_parity.pybaseline-missing cluster introduced by PR #626.
Added
- Unified charter bundle manifest v1.0.0 at
src/charter/bundle.pydeclaring the threesync()-produced derivatives (governance.yaml,directives.yaml,metadata.yaml) as the authoritative bundle contract.references.yamlandcontext-state.jsonare explicitly out of v1.0.0 scope; they are produced by other pipelines. - Canonical-root resolver at
src/charter/resolution.py(resolve_canonical_repo_root()). Readers running inside a git worktree now transparently observe the main-checkout charter bundle without per-worktree materialisation. Closes #339. spec-kitty charter bundle validate [--json]CLI surface for operator and CI bundle-health checks.- Migration
m_3_2_3_unified_bundleadvances 3.x projects to the unified bundle layout. On a populated project it validates the bundle against the v1.0.0 manifest, invokesensure_charter_bundle_fresh()to regenerate any missing derivatives, and emits a structured JSON report (seekitty-specs/unified-charter-bundle-chokepoint-01KP5Q2G/contracts/migration-report.schema.json). Idempotent — the second apply against an already-upgraded project is a clean no-op. Refs #464, #479.
Changed
SyncResultextended withcanonical_root: Path—files_writtenremains a list of file names relative tocanonical_root / .kittify/charter/. Existing readers were rewired in lockstep; no compatibility shim.ensure_charter_bundle_fresh()is now the sole chokepoint for readers ofgovernance.yaml,directives.yaml, andmetadata.yaml. Direct reads of those files are forbidden and are enforced by an AST-walk coverage test (tests/charter/test_chokepoint_coverage.py). Refs #461, #464.
Unchanged (explicitly)
.kittify/memory/and.kittify/AGENTS.mdsymlinks in worktrees remain as-is — they provide project-memory and agent-instructions sharing, documented-intentional persrc/specify_cli/templates/AGENTS.md:168-179. They are NOT part of the charter bundle; the canonical-root resolver fixes the worktree charter-visibility story without touchingsrc/specify_cli/core/worktree.py(C-011).- Files under
.kittify/charter/that are not v1.0.0 manifest files (references.yaml,context-state.json,interview/answers.yaml,library/*.md) are unchanged. The migration lists them underbundle_validation.unexpectedfor operator visibility but does not delete, move, or rewrite them (C-012). - Project
.gitignoreis not reconciled by the migration. The v1.0.0 manifest's required entries already match the repository.gitignoreverbatim; the migration performs no read or write against.gitignore(D-12).
Refs
- EPIC: #461 (Charter as Synthesis & Doctrine Reference Graph).
- Phase 2 tracking: #464.
- Closes on merge: #339, #451.
Fixed
mission mergeno longer silently loses content when the repository carries legacy sparse-checkout state — the stash/merge/stash-pop cascade used by the merge driver previously recorded phantom deletions for paths filtered out by a sparse-checkout pattern, and the subsequent housekeeping commit silently reverted content the preceding merge had introduced. Merge andagent action implementnow run a sparse-checkout preflight and fail closed unless the operator passes--allow-sparse-checkout,safe_commitnow aborts commits whose staging area contains paths outside the intended scope, andmission mergeperforms a post-merge refresh and invariant check before leaving the integration branch. Closes #588.move-task --to approvedand--to plannedon a lane-worktree review no longer require--forcewhen the only untracked content is.spec-kitty/— the review-lock uncommitted-changes guard now treats the execution lane's own.spec-kitty/scratch directory as expected content rather than an unexplained untracked path, so operators stop being trained to pass--forcereflexively. Closes #589.- Retry guidance emitted by the uncommitted-changes guard now names the actual target lane rather than hardcoded
for_review, so operators see the transition they were attempting instead of a misleading default.
Added
spec-kitty doctor sparse-checkout --fix— detection and one-command migration for repositories upgraded from pre-3.0 spec-kitty that still carrycore.sparseCheckout=trueand a.git/info/sparse-checkoutpattern file. The fix removes the git-config entry, clears the pattern file, and verifies post-fix state.--allow-sparse-checkoutflag onmission mergeandagent action implement— explicit escape hatch for users with intentional sparse configurations. Use of the flag emits aWARNING-level structured log record (spec_kitty.override.sparse_checkout) at the CLI layer. Durable cross-repo audit event support is tracked as #617.- Commit-time backstop inside
safe_commit— fail-closed check that aborts commits whose staging area contains paths outside the intended scope, independent of the preflight. This is the universal defence that catches sparse-stash-pop phantom-deletion cascades regardless of which command initiated them. - Per-worktree
.spec-kitty/exclude entry — every lane worktree now receives a local git exclude entry for.spec-kitty/at worktree creation, so lane scratch content stays invisible to the working-tree guard even in worktrees initialised before the fix. - Session-scoped sparse-checkout warning at review-lock and task-command entry points — surfaces detected legacy sparse-checkout state once per process before an operator wastes a commit cycle, without blocking.
- ADR
2026-04-14-1-sparse-checkout-defense-in-depth— documents the four-layer hybrid defence (merge/implement preflight,safe_commitbackstop, session warning,doctor --fix) and the alternatives considered.
Recovery for users already affected
If a prior mission merge landed on your target branch with a silent content
reversion (symptoms: a follow-up chore: record done transitions commit that
deleted content merged in the preceding commit), restore the content from the
merge commit that introduced it:
# Identify the merge commit
git log --merges --oneline -- <affected-file>
# Restore content from that merge
git checkout <merge-sha> -- <affected-file> [...]
# Commit the restoration
git add <affected-file> [...]
git commit -m "fix: restore content reverted by phantom-deletion bug"Then run the migration to prevent recurrence:
spec-kitty doctor sparse-checkout --fixRoot-cause diagnostic trail: Priivacy-ai/spec-kitty#588 (comment).