Work Packages: State Model Cleanup Foundations

Inputs: Design documents from kitty-specs/050-state-model-cleanup-foundations/ Prerequisites: plan.md (required), spec.md (user stories), research.md, data-model.md, quickstart.md

Tests: Tests are included in each WP as they are integral to the contract-driven approach.

Organization: Fine-grained subtasks (Txxx) roll up into work packages (WPxx). Each work package must be independently deliverable and testable.

Prompt Files: Each work package references a matching prompt file in tasks/ generated by /spec-kitty.tasks.


Work Package WP01: State Contract Module (Priority: P0)

Goal: Create src/specify_cli/state_contract.py with typed enums, frozen StateSurface dataclass, complete registry of all audit surfaces, helper functions, and unit tests. Independent Test: pytest tests/specify_cli/test_state_contract.py passes — all surfaces present, enums consistent, helpers return correct subsets. Prompt: tasks/WP01-state-contract-module.md Requirement Refs: FR-001, FR-002, FR-003, FR-004, FR-005, FR-011, NFR-001, NFR-003

Included Subtasks

  • ✅ T001 Create enums: StateRoot, AuthorityClass, GitClass, StateFormat
  • ✅ T002 Create frozen StateSurface dataclass with to_dict()
  • ✅ T003 Populate STATE_SURFACES registry with all surfaces from audit sections A–G
  • ✅ T004 Implement helper functions: get_surfaces_by_root(), get_surfaces_by_git_class(), get_surfaces_by_authority(), get_runtime_gitignore_entries()
  • ✅ T005 Write unit tests in tests/specify_cli/test_state_contract.py

Implementation Notes

  • Module is data-first: enums at top, dataclass definition, then registry tuple, then helpers.
  • Registry must cover all surfaces from audit sections A (project), B (constitution), C (feature), D (git-internal), E (user-home sync), F (global runtime), G (legacy).
  • get_runtime_gitignore_entries() returns path patterns for project-root surfaces where authority == LOCAL_RUNTIME or git_class == IGNORED.
  • Constitution surfaces with deferred Git policy use git_class=INSIDE_REPO_NOT_IGNORED with notes.
  • Zero external dependencies — stdlib only.

Parallel Opportunities

  • None within WP01 (sequential: enums → dataclass → registry → helpers → tests).

Dependencies

  • None (foundation package).

Risks & Mitigations

  • Risk: Registry becomes stale if new surfaces are added later. Mitigation: Test asserts known minimum surface count and validates name uniqueness.

Work Package WP02: Git Boundary Alignment (Priority: P0)

Goal: Align GitignoreManager with the state contract, add missing runtime entries to .gitignore via migration, and write integration tests that prevent drift. Independent Test: pytest tests/specify_cli/test_gitignore_contract.py tests/specify_cli/test_state_gitignore_migration.py passes — manager entries match contract, repo .gitignore covers all runtime surfaces, migration is idempotent. Prompt: tasks/WP02-git-boundary-alignment.md Requirement Refs: FR-006, FR-007, FR-010, C-005

Included Subtasks

  • ✅ T006 Update GitignoreManager.RUNTIME_PROTECTED_ENTRIES to derive from state_contract.get_runtime_gitignore_entries()
  • ✅ T007 [P] Write integration tests in tests/specify_cli/test_gitignore_contract.py (both contract↔manager and contract↔repo .gitignore)
  • ✅ T008 Create migration src/specify_cli/upgrade/migrations/m_2_0_9_state_gitignore.py
  • ✅ T009 [P] Write migration tests in tests/specify_cli/test_state_gitignore_migration.py

Implementation Notes

  • RUNTIME_PROTECTED_ENTRIES constant replaced with a module-level list derived from get_runtime_gitignore_entries() at import time.
  • Migration calls GitignoreManager(project_path).ensure_entries(get_runtime_gitignore_entries()) — idempotent by design.
  • Integration test A reads the actual repo .gitignore and asserts all LOCAL_RUNTIME project surfaces have matching patterns.
  • Integration test B asserts RUNTIME_PROTECTED_ENTRIES equals the output of get_runtime_gitignore_entries().
  • Migration must be registered in the migrations registry.

Parallel Opportunities

  • T007 and T009 (tests) can be written in parallel.

Dependencies

  • Depends on WP01 (needs state_contract.get_runtime_gitignore_entries()).

Risks & Mitigations

  • Risk: Migration version collision if another migration uses m_2_0_9. Mitigation: Check existing migration names before implementation.
  • Risk: Derivation changes import order. Mitigation: Use lazy import or module-level assignment that runs after state_contract is importable.

Work Package WP03: Doctor State-Roots Command (Priority: P0)

Goal: Create a new top-level spec-kitty doctor command group with a state-roots subcommand that displays root paths, surface classification, on-disk presence, and safety warnings. Support --json output. Independent Test: pytest tests/specify_cli/test_state_doctor.py passes — doctor output correct for various filesystem states; spec-kitty doctor state-roots runs without error. Prompt: tasks/WP03-doctor-state-roots-command.md Requirement Refs: FR-008, FR-009, NFR-002

Included Subtasks

  • ✅ T010 Create src/specify_cli/state/ package with __init__.py
  • ✅ T011 Implement check_state_roots() in src/specify_cli/state/doctor.py
  • ✅ T012 Create CLI command in src/specify_cli/cli/commands/doctor.py with state-roots subcommand
  • ✅ T013 Register doctor command group in src/specify_cli/cli/commands/__init__.py
  • ✅ T014 Write tests in tests/specify_cli/test_state_doctor.py

Implementation Notes

  • check_state_roots() resolves three roots (project via locate_project_root(), global_runtime via get_kittify_home(), global_sync via Path.home() / '.spec-kitty').
  • For each registered surface, check on-disk presence and gitignore coverage (via git check-ignore -q).
  • Rich table output for human consumption; --json flag for machine output using StateRootsReport.to_dict().
  • DoctorCheck pattern from runtime/doctor.py is informational — this command uses its own StateRootsReport dataclass since the output structure differs.
  • Registration: app.add_typer(doctor_module.app, name="doctor") in __init__.py.

Parallel Opportunities

  • T010 and T012 can be started in parallel (package skeleton vs CLI skeleton).

Dependencies

  • Depends on WP01 (needs STATE_SURFACES, StateRoot, helpers).

Risks & Mitigations

  • Risk: git check-ignore not available (not a git repo). Mitigation: Graceful fallback — warn that gitignore coverage cannot be verified; mark as "unknown".
  • Risk: Top-level doctor name conflicts with existing commands. Mitigation: Verified no conflict exists.

Dependency & Execution Summary

WP01 (State Contract)
├── WP02 (Git Boundary Alignment)  ← can parallelize
└── WP03 (Doctor Command)          ← can parallelize
  • Sequence: WP01 first (foundation) → WP02 and WP03 in parallel.
  • Parallelization: WP02 and WP03 are independent of each other; both depend only on WP01.
  • MVP Scope: All three WPs are required for the sprint. WP01 alone has no user-visible output.

Requirements Coverage Summary

Requirement IDCovered By Work Package(s)
FR-001WP01
FR-002WP01
FR-003WP01
FR-004WP01
FR-005WP01
FR-006WP02
FR-007WP02
FR-008WP03
FR-009WP03
FR-010WP02
FR-011WP01
NFR-001WP01
NFR-002WP03
NFR-003WP01
C-001WP01 (classified, deferred)
C-002WP01 (classified as deprecated)
C-005WP02
C-006WP01, WP02, WP03

Subtask Index (Reference)

Subtask IDSummaryWork PackagePriorityParallel?
T001Create state enumsWP01P0No
T002Create StateSurface dataclassWP01P0No
T003Populate STATE_SURFACES registryWP01P0No
T004Implement helper functionsWP01P0No
T005Write state contract unit testsWP01P0No
T006Derive GitignoreManager entries from contractWP02P0No
T007Write gitignore integration testsWP02P0Yes
T008Create state gitignore migrationWP02P0No
T009Write migration testsWP02P0Yes
T010Create state/ packageWP03P0Yes
T011Implement check_state_roots()WP03P0No
T012Create doctor CLI commandWP03P0Yes
T013Register doctor commandWP03P0No
T014Write doctor testsWP03P0No

<!-- status-model:start -->

Canonical Status (Generated)

<!-- status-model:end -->

  • WP01: approved
  • WP02: done
  • WP03: done