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
StateSurfacedataclass withto_dict() - ✅ T003 Populate
STATE_SURFACESregistry 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 whereauthority == LOCAL_RUNTIMEorgit_class == IGNORED.- Constitution surfaces with deferred Git policy use
git_class=INSIDE_REPO_NOT_IGNOREDwith 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_ENTRIESto derive fromstate_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_ENTRIESconstant replaced with a module-level list derived fromget_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
.gitignoreand asserts allLOCAL_RUNTIMEproject surfaces have matching patterns. - Integration test B asserts
RUNTIME_PROTECTED_ENTRIESequals the output ofget_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_contractis 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()insrc/specify_cli/state/doctor.py - ✅ T012 Create CLI command in
src/specify_cli/cli/commands/doctor.pywithstate-rootssubcommand - ✅ 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 vialocate_project_root(), global_runtime viaget_kittify_home(), global_sync viaPath.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;
--jsonflag for machine output usingStateRootsReport.to_dict(). DoctorCheckpattern fromruntime/doctor.pyis informational — this command uses its ownStateRootsReportdataclass 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-ignorenot available (not a git repo). Mitigation: Graceful fallback — warn that gitignore coverage cannot be verified; mark as "unknown". - Risk: Top-level
doctorname 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 ID | Covered By Work Package(s) |
|---|---|
| FR-001 | WP01 |
| FR-002 | WP01 |
| FR-003 | WP01 |
| FR-004 | WP01 |
| FR-005 | WP01 |
| FR-006 | WP02 |
| FR-007 | WP02 |
| FR-008 | WP03 |
| FR-009 | WP03 |
| FR-010 | WP02 |
| FR-011 | WP01 |
| NFR-001 | WP01 |
| NFR-002 | WP03 |
| NFR-003 | WP01 |
| C-001 | WP01 (classified, deferred) |
| C-002 | WP01 (classified as deprecated) |
| C-005 | WP02 |
| C-006 | WP01, WP02, WP03 |
Subtask Index (Reference)
| Subtask ID | Summary | Work Package | Priority | Parallel? |
|---|---|---|---|---|
| T001 | Create state enums | WP01 | P0 | No |
| T002 | Create StateSurface dataclass | WP01 | P0 | No |
| T003 | Populate STATE_SURFACES registry | WP01 | P0 | No |
| T004 | Implement helper functions | WP01 | P0 | No |
| T005 | Write state contract unit tests | WP01 | P0 | No |
| T006 | Derive GitignoreManager entries from contract | WP02 | P0 | No |
| T007 | Write gitignore integration tests | WP02 | P0 | Yes |
| T008 | Create state gitignore migration | WP02 | P0 | No |
| T009 | Write migration tests | WP02 | P0 | Yes |
| T010 | Create state/ package | WP03 | P0 | Yes |
| T011 | Implement check_state_roots() | WP03 | P0 | No |
| T012 | Create doctor CLI command | WP03 | P0 | Yes |
| T013 | Register doctor command | WP03 | P0 | No |
| T014 | Write doctor tests | WP03 | P0 | No |
<!-- status-model:start -->
Canonical Status (Generated)
<!-- status-model:end -->
- WP01: approved
- WP02: done
- WP03: done