Implementation Plan: Decompose agent/tasks.py god-module
Branch: main (planning) → merges into main | Date: 2026-06-24 | Spec: spec.md Input: Feature specification from kitty-specs/decompose-agent-tasks-god-module-01KVWVAR/spec.md
Summary
Decompose src/specify_cli/cli/commands/agent/tasks.py (4633 LOC, maxCC ~178) into a thin typer command-registration shim (≤ ~1200 LOC) plus five cohesive, independently-testable seam modules, and internally decompose the six mega-functions so every function satisfies maxCC ≤ 15. The public agent tasks CLI surface stays byte-identical (golden characterization tests captured first). Separately, centralize the three planning-commit tails through the canonical commit_for_mission router and delete the now-dead bespoke is_protected pre-checks, while preserving the protected-primary error messages verbatim. Technical approach and seam boundaries are fixed by Phase 0 research (research.md).
Technical Context
Language/Version: Python 3.11+ Primary Dependencies: typer (CLI), rich (console), ruamel.yaml (frontmatter), mission_runtime / specify_cli.coordination.commit_router (commit routing) — no new runtime dependencies Storage: N/A — no runtime data-schema change; planning artifacts are files Testing: pytest. Golden CLI characterization via typer.testing.CliRunner + committed expected-output fixtures (no new snapshot dependency); per-seam unit tests; ruff + mypy --strict gates; ≥90% coverage on new/changed code Target Platform: CLI (Linux/macOS), Python package spec-kitty-cli Project Type: single (Python CLI package) Performance Goals: zero behavior/perf regression — pure structural refactor + output-preserving commit centralization Constraints: maxCC ≤ 15 for every function (ruff C901 / Sonar S3776); agent tasks command/flag/exit-code/--json contract byte-identical; one-way imports (seams never import the shim); no new # noqa/# type: ignore/per-file ignores Scale/Scope: relocate ~1800 LOC into 5 seams; decompose 6 mega-functions (move_task 778, status 483, map_requirements 382, _validate_ready_for_review 348, mark_status 265, finalize_tasks 218); ~410 LOC new tests; 3 commit tails re-routed
Charter Check
GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.
Charter present (.kittify/charter/charter.md). Policy stack: typer / rich / ruamel.yaml / pytest / mypy --strict / 90%+ new-code coverage / integration tests for CLI commands.
| Charter requirement | Status in this plan |
|---|---|
| typer / rich / ruamel.yaml | Preserved; no replacement, no new deps |
| pytest, 90%+ new-code coverage | NFR-002 + per-seam tests + golden CLI tests |
| mypy --strict, ruff clean, no suppressions | NFR-003 + C-004 |
| Integration tests for CLI commands | Golden CLI characterization tests (SC-006) |
| Complexity ceiling maxCC ≤ 15 | NFR-001 is the binding target |
| Use canonical sources, never improvise | C-002 — route via existing commit_for_mission, not a hand-rolled guard |
No charter violations. No entries in Complexity Tracking.
Project Structure
Documentation (this mission)
kitty-specs/decompose-agent-tasks-god-module-01KVWVAR/
├── plan.md # This file
├── spec.md # Mission spec
├── research.md # Phase 0 (complete)
├── data-model.md # Phase 1 — module topology + invariants
├── quickstart.md # Phase 1 — how to verify the refactor
├── contracts/
│ └── cli-surface-contract.md # Frozen `agent tasks` CLI contract (golden-test target)
└── tasks.md # Phase 2 (/spec-kitty.tasks — NOT created here)
Source Code (repository root)
src/specify_cli/cli/commands/agent/
├── tasks.py # RESIDUAL SHIM: typer `app` + 9 thinned command handlers (≤ ~1200 LOC)
├── tasks_outline.py # SEAM 1: tasks.md / manifest parsing, WP-id resolution
├── tasks_materialization.py # SEAM 2: frontmatter & file persistence, markdown-row mutation
├── tasks_finalize_validation.py # SEAM 3: dependency/cycle validation, lane metadata, bootstrap glue
├── tasks_dependency_graph.py # SEAM 4: dependency readiness / dependent-gating glue
└── tasks_parsing_validation.py # SEAM 5: readiness / verdict / issue-matrix validation
src/specify_cli/coordination/commit_router.py # EXISTING — the 3 tails route through commit_for_mission (no new module)
tests/specify_cli/cli/commands/agent/
├── test_tasks_cli_contract.py # NEW: golden CLI characterization (captured pre-refactor)
├── test_tasks_outline.py # NEW: seam 1 unit tests
├── test_tasks_materialization.py # NEW: seam 2 unit tests (+ error paths)
├── test_tasks_dependency_readiness.py # NEW: readiness gating
└── (existing test_tasks*.py suites remain green throughout)
Structure Decision: Single Python CLI package. Seams are sibling modules under src/specify_cli/cli/commands/agent/ (same package as the shim) to keep import paths short and avoid a new sub-package; one-way dependency enforced by convention + review (INV-2). Commit routing reuses the existing coordination/commit_router.py — no new module (C-002).
Complexity Tracking
No Charter Check violations — section intentionally empty.
Implementation Concern Map
> Concerns are NOT work packages. /spec-kitty.tasks translates these into executable WPs.
IC-01 — Golden CLI characterization harness (capture FIRST)
- Purpose: Pin the
agent taskscommand/flag/exit-code/--jsoncontract viaCliRunner+ committed expected-output fixtures, captured against the current code BEFORE any refactor, so contract drift is caught mechanically. - Relevant requirements: FR-001, C-005, SC-006.
- Affected surfaces:
tests/specify_cli/cli/commands/agent/test_tasks_cli_contract.py(new); fixtures dir. - Sequencing/depends-on: none — must land before all extraction concerns.
- Risks: help text contains volatile content (paths, timestamps) — normalize before snapshotting; ensure fixtures are deterministic under per-worker HOME isolation.
IC-02 — Extract tasks_outline seam (parsing / WP-id resolution)
- Purpose: Move tasks.md/manifest parsing + WP-id resolution helpers into an independently-importable module with focused tests.
- Relevant requirements: FR-003, FR-004.
- Affected surfaces: new
tasks_outline.py;tasks.py(delete moved fns, add imports); newtest_tasks_outline.py. - Sequencing/depends-on: IC-01.
- Risks: shared regex/consts (
_WP_HEADING_RE,_QUALIFIED_TASK_ID_RE) relocate cleanly; keep re-export if any external test imports by path.
IC-03 — Extract tasks_materialization seam (frontmatter/file persistence)
- Purpose: Move markdown-row mutation + file/frontmatter persistence into a seam; add error-path tests.
- Relevant requirements: FR-003, FR-004.
- Affected surfaces: new
tasks_materialization.py;tasks.py; newtest_tasks_materialization.py. - Sequencing/depends-on: IC-02 (imports outline parsers).
- Risks: fragile markdown regex; cover checkbox/pipe-table/inline cases + write-failure paths.
IC-04 — Extract tasks_finalize_validation seam (dependency/cycle/lane metadata)
- Purpose: Move cycle/dependency validation + lane-metadata + bootstrap glue (incl. the validation core extracted from
finalize_tasks). - Relevant requirements: FR-003, FR-004.
- Affected surfaces: new
tasks_finalize_validation.py;tasks.py. - Sequencing/depends-on: IC-01 (parallelizable with IC-02/03).
- Risks: preserve the "disagree-loud" conflict detection; existing finalize tests are strong — keep green.
IC-05 — Extract tasks_dependency_graph seam (readiness / dependent-gating)
- Purpose: Move
_check_dependent_warnings,_behind_commits_touch_only_planning_artifacts, and the dependent-gating extracted frommove_task; add readiness-gating tests. - Relevant requirements: FR-003, FR-004.
- Affected surfaces: new
tasks_dependency_graph.py;tasks.py; newtest_tasks_dependency_readiness.py. - Sequencing/depends-on: IC-01. (The two
core/dependency_graph.pycall sites stay in the shim — no cycle.) - Risks: subprocess git calls — keep graceful fallbacks; LOW circular-import risk per research §4.
IC-06 — Extract tasks_parsing_validation seam (readiness/verdict/issue-matrix)
- Purpose: Move issue-matrix + verdict + review-cycle validation; sub-split the 348-LOC
_validate_ready_for_reviewinto ≤15-CC helpers (research-artifacts / worktree-state / merge-ancestry / contamination). - Relevant requirements: FR-003, FR-004, NFR-001.
- Affected surfaces: new
tasks_parsing_validation.py;tasks.py. - Sequencing/depends-on: IC-02 (uses outline parsers). Largest seam.
- Risks: tightly bound to spec-md parsing + git subprocess; existing coverage is STRONG — lean on it.
IC-07 — Decompose mega-function command bodies + thin the shim
- Purpose: Internally decompose
move_task(778),status(483),map_requirements(382),mark_status(265),finalize_tasks(218) so each handler is a thin orchestrator (dispatch → seam calls → emit), achieving maxCC ≤ 15 everywhere and tasks.py ≤ ~1200 LOC. - Relevant requirements: FR-005, NFR-001, NFR-004, SC-002.
- Affected surfaces:
tasks.py(all 5 mega-handlers); helper extraction into the relevant seams. - Sequencing/depends-on: IC-02..IC-06 (seams must exist to delegate to). Coordinate with IC-08 (both touch
move_task/mark_status/map_requirements). - Risks: this is the bulk of the effort; lean entirely on IC-01 golden tests + existing suite to prove preservation.
IC-08 — Centralize commit routing (3 tails → commit_for_mission)
- Purpose: Route the 3 tails (
tasks.py:2486/3131/3947) throughcommit_for_mission; threadtarget_branch=on tail 3; delete dead pre-checks (921-932,954-971, guard conditionals2448-2470/3021-3029,_planning_commit_worktreeimport3928); map the router'sno_op_wrong_surfaceresult back to the existing protected-primary messages verbatim so output stays byte-identical. - Relevant requirements: FR-006, FR-007, FR-008, C-002, C-003, C-006.
- Affected surfaces:
tasks.py(move_task/mark_status/map_requirements); extendtests/.../test_wp03_bypass_writers_fr008.py. - Sequencing/depends-on: coordinate with IC-07 (shared functions).
mission.pyis OUT OF SCOPE (C-006). - Risks: message-preservation is the subtle part — assert byte-identical messages + exit codes in the regression test.
IC-09 — Pointer comment + final gate sweep
- Purpose: Add the top-of-file
#2058decomposition-pointer comment (matching #2056/#1623), and run the full gate sweep (ruff, mypy --strict, coverage ≥90%, maxCC ≤15, terminology guard, golden + existing suites). - Relevant requirements: FR-002, NFR-001, NFR-002, NFR-003, SC-005.
- Affected surfaces:
tasks.pyheader; CI gates. - Sequencing/depends-on: all prior ICs.
- Risks:
integration-tests-core-miscgates (terminology) run only in CI — runtests/architectural/locally before pushing.