pactkit 2.18.0__tar.gz → 2.20.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pactkit-2.20.0/.coverage +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/.gitignore +1 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/CHANGELOG.md +17 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/PKG-INFO +5 -4
- {pactkit-2.18.0 → pactkit-2.20.0}/README.md +4 -3
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/architecture/governance/archive/lessons_archive_202603.md +1 -0
- pactkit-2.20.0/docs/architecture/governance/archive/lessons_archive_202604.md +6 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/architecture/governance/lessons.md +3 -3
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/architecture/governance/rules.md +1 -1
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/product/archive/archive_202608.md +28 -0
- pactkit-2.20.0/docs/product/context.md +29 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/product/sprint_board.md +9 -1
- pactkit-2.20.0/docs/specs/STORY-slim-143.md +178 -0
- pactkit-2.20.0/docs/specs/STORY-slim-144.md +169 -0
- pactkit-2.20.0/docs/specs/STORY-slim-145.md +289 -0
- pactkit-2.20.0/docs/specs/STORY-slim-146.md +228 -0
- pactkit-2.20.0/docs/test_cases/STORY-slim-143_case.md +43 -0
- pactkit-2.20.0/docs/test_cases/STORY-slim-144_case.md +37 -0
- pactkit-2.20.0/docs/test_cases/STORY-slim-146_case.md +69 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/pyproject.toml +1 -1
- {pactkit-2.18.0 → pactkit-2.20.0}/src/pactkit/__init__.py +1 -1
- {pactkit-2.18.0 → pactkit-2.20.0}/src/pactkit/cli.py +141 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/src/pactkit/context_gen.py +53 -2
- pactkit-2.20.0/src/pactkit/continuation.py +539 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/src/pactkit/doctor.py +66 -7
- {pactkit-2.18.0 → pactkit-2.20.0}/src/pactkit/garden.py +14 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/src/pactkit/generators/deploy_base.py +48 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/src/pactkit/generators/deployer.py +113 -10
- {pactkit-2.18.0 → pactkit-2.20.0}/src/pactkit/profiles.py +38 -8
- {pactkit-2.18.0 → pactkit-2.20.0}/src/pactkit/prompts/commands.py +6 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/src/pactkit/prompts/skills.py +46 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/src/pactkit/prompts/workflows.py +13 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/src/pactkit/schemas.py +26 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/src/pactkit/skills/scaffold.py +9 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/src/pactkit/skills/spec_linter.py +57 -0
- pactkit-2.20.0/src/pactkit/spec_graph.py +296 -0
- pactkit-2.20.0/tests/e2e/cli/test_story_slim146_cli.py +126 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_context_gen.py +62 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_sprint_command.py +3 -2
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story042_spec_linter.py +9 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story059_codex_removal.py +4 -2
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story063_prompt_slimming.py +9 -3
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim026.py +1 -1
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim084.py +6 -3
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim142_all_target_isolation.py +4 -0
- pactkit-2.20.0/tests/unit/test_story_slim143_spec_graph.py +273 -0
- pactkit-2.20.0/tests/unit/test_story_slim144_wave_mode.py +147 -0
- pactkit-2.20.0/tests/unit/test_story_slim145.py +340 -0
- pactkit-2.20.0/tests/unit/test_story_slim146.py +744 -0
- pactkit-2.18.0/docs/product/context.md +0 -29
- {pactkit-2.18.0 → pactkit-2.20.0}/.codegraph/.gitignore +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/.github/workflows/pactkit.yml +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/.github/workflows/publish.yml +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/AGENTS.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/CODE_OF_CONDUCT.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/CONTRIBUTING.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/LICENSE +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/SECURITY.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/architecture/governance/archive/lessons_archive_202602.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/architecture/governance/harness_audit.json +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/architecture/governance/philosophy.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/assets/logo.png +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/e2e/journey.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/guides/codex-integration-preresearch.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/guides/tool-integration-checklist.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/product/archive/archive_202602.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/product/archive/archive_202603.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/product/archive/archive_202604.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/product/archive/archive_202605.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/product/archive/archive_202606.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/product/archive/archive_202607.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/product/friction-log.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/product/prd.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/BUG-001.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/BUG-002.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/BUG-003.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/BUG-004.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/BUG-005.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/BUG-006.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/BUG-007.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/BUG-008.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/BUG-009.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/BUG-010.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/BUG-011.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/BUG-012.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/BUG-013.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/BUG-014.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/BUG-015.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/BUG-016.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/BUG-017.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/BUG-018.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/BUG-019.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/BUG-020.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/BUG-021.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/BUG-022.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/BUG-023.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/BUG-024.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/BUG-025.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/BUG-026.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/BUG-027.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/BUG-028.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/BUG-029.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/BUG-030.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/BUG-031.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/BUG-032.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/BUG-033.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/BUG-034.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/BUG-035.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/BUG-slim-001.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/BUG-slim-002.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/BUG-slim-003.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/BUG-slim-004.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/BUG-slim-005.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/BUG-slim-006.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/BUG-slim-089.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/BUG-slim-107.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/HOTFIX-slim-023.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/HOTFIX-slim-049.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/HOTFIX-slim-050.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/HOTFIX-slim-051.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/HOTFIX-slim-052.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/HOTFIX-slim-061.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/HOTFIX-slim-062.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/HOTFIX-slim-067.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/HOTFIX-slim-069.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/HOTFIX-slim-070.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/HOTFIX-slim-085.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/HOTFIX-slim-087.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/HOTFIX-slim-096.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/HOTFIX-slim-099.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/HOTFIX-slim-107.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/HOTFIX-slim-117.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/HOTFIX-slim-122.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/HOTFIX-slim-123.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/HOTFIX-slim-126.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/HOTFIX-slim-127.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/HOTFIX-slim-130.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/HOTFIX-slim-131.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/HOTFIX-slim-132.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-001.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-002.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-003.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-004.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-005.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-006.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-007.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-008.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-009.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-010.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-011.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-012.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-013.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-014.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-015.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-016.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-017.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-018.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-019.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-020.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-021.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-022.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-023.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-024.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-025.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-026.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-027.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-028.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-029.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-030.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-031.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-032.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-033.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-034.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-035.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-036.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-037.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-038.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-039.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-040.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-041.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-042.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-043.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-044.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-045.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-046.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-047.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-048.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-049.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-050.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-051.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-052.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-053.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-054.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-055.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-056.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-057.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-058.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-059.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-060.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-061.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-062.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-063.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-064.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-065.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-069.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-070.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-071.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-072.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-073.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-001.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-005.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-006.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-007.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-009.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-010.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-011.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-012.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-013.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-014.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-015.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-016.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-017.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-018.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-019.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-020.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-021.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-022.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-023.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-024.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-028.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-029.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-030.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-031.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-032.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-033.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-034.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-035.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-036.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-037.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-038.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-039.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-040.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-041.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-042.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-043.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-044.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-045.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-046.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-047.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-048.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-049.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-050.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-051.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-052.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-053.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-054.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-055.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-056.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-057.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-058.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-059.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-060.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-063.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-066.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-067.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-068.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-069.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-070.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-071.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-072.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-073.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-074.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-075.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-076.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-077.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-078.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-079.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-080.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-081.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-082.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-083.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-084.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-086.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-088.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-089.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-090.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-091.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-092.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-093.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-094.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-095.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-097.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-098.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-099.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-100.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-101.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-102.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-103.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-104.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-105.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-106.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-107.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-108.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-109.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-110.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-111.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-112.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-113.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-114.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-115.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-116.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-118.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-119.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-120.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-121.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-124.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-125.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-126.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-127.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-128.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-129.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-132.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-133.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-134.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-135.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-136.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-137.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-138.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-139.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-140.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-141.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/specs/STORY-slim-142.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/test_cases/BUG-001_case.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/test_cases/BUG-002_case.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/test_cases/STORY-slim-028_case.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/test_cases/STORY-slim-029_case.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/test_cases/STORY-slim-031_case.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/test_cases/STORY-slim-032_case.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/test_cases/STORY-slim-033_case.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/test_cases/STORY-slim-034_case.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/test_cases/STORY-slim-135_case.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/test_cases/STORY-slim-136_case.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/test_cases/STORY-slim-137_case.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/test_cases/STORY-slim-138_case.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/test_cases/STORY-slim-139_case.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/test_cases/STORY-slim-140_case.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/test_cases/STORY-slim-141_case.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/docs/test_cases/STORY-slim-142_case.md +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/opencode.json +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/src/pactkit/__main__.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/src/pactkit/audit.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/src/pactkit/backfill.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/src/pactkit/cleaners.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/src/pactkit/commit_gate.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/src/pactkit/config.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/src/pactkit/coverage_gate.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/src/pactkit/deploy_manifest.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/src/pactkit/deps.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/src/pactkit/done_verify.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/src/pactkit/generators/__init__.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/src/pactkit/generators/adapter.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/src/pactkit/guards.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/src/pactkit/id_generator.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/src/pactkit/invariants.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/src/pactkit/issue_sync.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/src/pactkit/lazy_visualize.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/src/pactkit/lessons.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/src/pactkit/lint_runner.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/src/pactkit/observe.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/src/pactkit/prompts/__init__.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/src/pactkit/prompts/agents.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/src/pactkit/prompts/guides.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/src/pactkit/prompts/references.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/src/pactkit/prompts/rules.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/src/pactkit/regression.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/src/pactkit/scripts.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/src/pactkit/sec_scope.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/src/pactkit/skills/__init__.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/src/pactkit/skills/analyzers/__init__.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/src/pactkit/skills/analyzers/go_analyzer.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/src/pactkit/skills/analyzers/java_analyzer.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/src/pactkit/skills/analyzers/python_analyzer.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/src/pactkit/skills/analyzers/ts_analyzer.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/src/pactkit/skills/board.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/src/pactkit/skills/interface_summary.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/src/pactkit/skills/report.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/src/pactkit/skills/visualize.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/src/pactkit/spec_status.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/src/pactkit/test_mapper.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/src/pactkit/utils.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/src/pactkit/validators.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/conftest.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/e2e/__init__.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/e2e/cli/__init__.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/e2e/cli/test_cli_e2e.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/fixtures/agent_parser/agents_dir/researcher.yaml +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/fixtures/agent_parser/agents_dir/writer.yaml +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/fixtures/agent_parser/langgraph_app.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/fixtures/agent_parser/mcp_settings.json +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/fixtures/api_call_parser/axios_style.tsx +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/fixtures/api_call_parser/dynamic.tsx +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/fixtures/api_call_parser/page.tsx +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/fixtures/config_golden/copy_claude.json +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/fixtures/config_golden/copy_claude.yaml +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/fixtures/config_golden/copy_codex.json +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/fixtures/config_golden/copy_codex.yaml +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/fixtures/config_golden/copy_github.json +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/fixtures/config_golden/copy_github.yaml +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/fixtures/config_golden/empty.json +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/fixtures/config_golden/empty.yaml +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/fixtures/config_golden/full_legacy.json +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/fixtures/config_golden/full_legacy.yaml +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/fixtures/config_golden/minimal.json +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/fixtures/config_golden/minimal.yaml +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/fixtures/config_golden/unknown_keys.json +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/fixtures/config_golden/unknown_keys.yaml +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/integration/__init__.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/integration/test_deploy_classic.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_agent_features.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_agent_frontmatter.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_agents_enrichment.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_audit.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_blast_radius.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_board_bug027.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_board_sections.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_bug001_skill_path.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_bug002_plugin_paths.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_bug003_multi_import.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_bug004_dead_set.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_bug005_archive_taskless.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_bug006_scan_excludes.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_bug007_stale_trace_refs.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_bug008_stale_command_refs.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_bug009_project_config_backfill.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_bug010_rewrite_yaml.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_bug011_stale_refs.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_bug012_call_graph_filter.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_bug013_config_single_source.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_bug014_version_hygiene.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_bug017_project_init_playbook.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_bug018_issue_tracker_verification.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_bug019_venv_deployment.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_bug020_claude_md_backup.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_bug025_release_delegation.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_bug026_version_sync.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_bug028_ghost_refs.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_bug029_stack_detection_fallback.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_bug030_spec_lint_cli.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_bug031_docstring_accuracy.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_bug034_plan_metadata_template.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_bug_021.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_bug_022.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_bug_023.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_bug_024.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_bug_slim001_env_detection.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_bug_slim002_instruction_collision.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_bug_slim003.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_bug_slim004.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_bug_slim005.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_bug_slim006.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_bug_slim089_global_claude_md.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_check_command.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_check_extensions_072_073.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_check_playbook_072_073.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_command_frontmatter.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_command_visualize_modes.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_commit_gate.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_complexity.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_config.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_config_auto_merge.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_constitution_sharpening.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_create_skill.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_cross_flow_matrix.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_deploy_base.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_deployer_cleanup.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_deployer_plugin.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_deps.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_design_command.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_done_gates.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_done_verify.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_draw_prompt.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_draw_references.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_drawio_mcp.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_garden.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_home_path_fix.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_hotfix_command.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_init_guard.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_init_playbook_074.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_interface_summary.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_lang_profiles.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_layer_violations.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_lessons_rotation_075.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_list_stories.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_mcp_integration.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_model_config.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_modular_constitution.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_monorepo_detect.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_multi_prefix.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_observe.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_pdca_slim.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_profiles.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_project_visibility.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_prompt_cli_refs.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_prompt_quality_075.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_prompt_structural_invariants.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_prompts_package.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_release.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_release_field.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_release_v110.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_render_prompt.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_report_parser.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_report_unified.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_review_command.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_rules_enrichment.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_scaffold.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_scaffold_developer_prefix.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_schemas.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_script_extraction.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_selective_deploy.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_session_context.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_skill_structure.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_skills_enrichment.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_slim_deps_088.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_smart_regression.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_solution_design_rule.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_stack_references.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_status_command.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_statusline.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story014_release.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story015_ci_lint_gate.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story016_claude_md.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story017_init_claude_md.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story018_arch_staleness.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story019_bailout.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story020_horizon.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story021_rfc.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story022_decision_tree.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story023_test_quality.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story024_native_agent.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story025_ci_pipeline.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story026_issue_tracker.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story028_rule_scoping.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story029_doctor.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story030_lint.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story031_git_init_guard.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story032_greenfield_redirect.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story033_config_backfill.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story034_plan_config_refresh.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story035_readme_docs.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story037_regression_fix.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story038_call_graph_update.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story039_venv_config.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story040_layered_claude_md.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story043_active_clarify.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story044_consistency_check.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story045_auto_pr.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story046_agent_adapter.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story047_enterprise_flags.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story048_worktree_isolation.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story049_community_standards.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story050_doc_only_shortcut.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story051_workflow_streamlining.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story052_conditional_github_release.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story053_impact_regression.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story055_commands.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story055_config.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story055_spec_linter.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story056_commands.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story056_config.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story057_implicit_cleanup.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story058_opencode_extraction.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story058_routing_fix.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story060_init_hang.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story061_remove_thinking.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story062_mcp_recommendations.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story064_venv_local_md.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story065_sprint_model.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story072_developer_prefix.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story106_lateral_scan.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story133_debug_skill.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim009_lazy_rules.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim010_dry_refactor.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim011_command_rules.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim012_ci.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim014_clean.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim014_context.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim014_guard.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim014_lazy_viz.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim014_next_id.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim014_regression.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim014_sec_scope.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim014_validators.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim015_doctor.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim016_testmap_lint.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim017.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim018.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim019_plan_subphases.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim020_explore_stall_fix.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim021.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim022.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim023.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim024.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim025.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim027.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim028.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim029.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim030.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim031.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim032.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim033.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim034.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim035.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim036.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim037.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim038.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim039.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim040.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim041.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim042.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim043.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim044.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim045.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim046.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim047.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim048.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim049.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim051.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim052.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim053.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim054.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim055.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim056.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim060_codex_profile.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim063.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim065.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim076_multistack.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim077_monorepo_stack.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim078.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim079.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim080.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim081.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim082.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim083.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim095.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim098_pdca_nudge.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim099_act_context_ref.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim102_version_marker.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim104_should_semantics.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim107.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim109_journey_spec.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim111_playwright_assertion.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim112_rules_split.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim114_journey_sync.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim119.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim120.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim121.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim125.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim126.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim127_managed_block.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim128_engineering_concerns.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim132.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim134_no_model_in_frontmatter.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim135_config_schema.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim139_skill_manifest.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_story_slim141_manifest_hash.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_tools.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_topology_parsers_066.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_update_task.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_visualize_call_nested.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_visualize_chain_fix.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_visualize_modes.py +0 -0
- {pactkit-2.18.0 → pactkit-2.20.0}/tests/unit/test_visualize_multilang_chain.py +0 -0
pactkit-2.20.0/.coverage
ADDED
|
Binary file
|
|
@@ -4,6 +4,23 @@ All notable changes to PactKit will be documented in this file.
|
|
|
4
4
|
|
|
5
5
|
Format follows [Keep a Changelog](https://keepachangelog.com/).
|
|
6
6
|
|
|
7
|
+
## [2.20.0] - 2026-08-22
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
- **Verified resumable Act checkpoints** (STORY-slim-146) — PactKit now persists Story-scoped continuation state with validated Spec, Board, test, regression, and lint evidence. `pactkit continuation status/verify/resume/checkpoint` supports safe cross-process recovery, stale-state detection, terminal completion, fresh-cycle archival, secret/path sanitization, and Story-level locking. All 13 runtime skills and the Classic, OpenCode, Codex, and Copilot deployments share the recovery contract.
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
- **Adapter-safe command rendering and deployment gates** (STORY-slim-145) — operation-aware prompt rendering preserves PactKit CLI semantics across adapters, rejects lossy command transformations, checks generated prompt integrity before writing, and blocks incompatible Core/adapter versions unless skew is explicitly acknowledged.
|
|
14
|
+
|
|
15
|
+
## [2.19.0] - 2026-08-17
|
|
16
|
+
|
|
17
|
+
### Added
|
|
18
|
+
- **Spec Dependency Surface** (STORY-slim-143) — every scaffolded Spec now carries a machine-readable `## Dependency Surface` table (`Depends on` / `Provides` / `Touches` / `Conflict risk`). Story dependencies and file-level conflict surface are no longer implicit in the architect's head — they're data.
|
|
19
|
+
- **`pactkit spec-graph`** (STORY-slim-143) — deterministic story dependency DAG from all Specs: topological **execution waves** (wave N depends only on waves < N; same-wave stories are parallelizable), a **file-overlap conflict matrix** (same-wave overlaps flagged unsafe-parallel), cycle detection with non-zero exit, and Mermaid output to `docs/architecture/graphs/story_graph.mmd`. Stdlib only (`graphlib`, `fnmatch`), zero new dependencies.
|
|
20
|
+
- **Spec linter rules E010/W011** (STORY-slim-143) — dangling `Depends on` references (story ID with no Spec file) are now an Act-blocking ERROR; missing Dependency Surface is a WARNING. Reuses spec_linter's section-parsing helpers (newly public: `strip_code_blocks` / `section_text`).
|
|
21
|
+
- **Sprint Wave Mode** (STORY-slim-144) — `/project-sprint` with empty arguments scans the backlog, consumes `pactkit spec-graph --json` (new flag), and runs conflict-free same-wave stories as parallel worktree subagents (cap `sprint.max_parallel`, default 3). Stories with same-wave conflicts or undeclared Touches are serialized safe-by-default. Wave gate: wave N+1 starts only after wave N is fully merged green; fail-fast with no auto-retry; resume by re-running (idempotent). Single-story mode with arguments is byte-for-byte unchanged.
|
|
22
|
+
- **Plan playbook Dependency Surface step** (STORY-slim-143) — `/project-plan` Phase 3.2a now fills the table from Phase 1 trace findings, so every new Spec ships scheduling data.
|
|
23
|
+
|
|
7
24
|
## [2.18.0] - 2026-08-17
|
|
8
25
|
|
|
9
26
|
### Added
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: pactkit
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.20.0
|
|
4
4
|
Summary: Spec-driven agentic DevOps toolkit for AI coding assistants
|
|
5
5
|
Project-URL: Homepage, https://pactkit.dev
|
|
6
6
|
Project-URL: Repository, https://github.com/pactkit/pactkit-public
|
|
@@ -194,7 +194,7 @@ Or run the full cycle in one command:
|
|
|
194
194
|
| **Done** | `/project-done` | Repo Maintainer | Regression gate -> Archive -> Conventional commit |
|
|
195
195
|
| **Release** | `/project-release` | Repo Maintainer | Version bump -> Snapshot -> Git tag -> GitHub Release |
|
|
196
196
|
| **PR** | `/project-pr` | Repo Maintainer | Push branch -> Create pull request via gh CLI |
|
|
197
|
-
| **Sprint** | `/project-sprint` | Team Lead | One-command automated PDCA orchestration |
|
|
197
|
+
| **Sprint** | `/project-sprint` | Team Lead | One-command automated PDCA orchestration; empty args = Wave Mode (parallel backlog stories via `spec-graph` waves + conflict matrix) |
|
|
198
198
|
| **Hotfix** | `/project-hotfix` | Senior Developer | Fast-track fix bypassing PDCA (with traceability) |
|
|
199
199
|
| **Init** | `/project-init` | System Architect | Bootstrap project structure and governance |
|
|
200
200
|
| **Design** | `/project-design` | Product Designer | PRD generation -> Story decomposition -> Board setup |
|
|
@@ -289,8 +289,9 @@ PactKit ships 36 deterministic CLI subcommands — operations that were previous
|
|
|
289
289
|
| `pactkit upgrade` | Upgrade with format selection |
|
|
290
290
|
| `pactkit version` | Show installed version |
|
|
291
291
|
| `pactkit schema` | Print document schemas |
|
|
292
|
-
| `pactkit doctor` | Diagnose project health (HLD drift, board, config) |
|
|
293
|
-
| `pactkit spec-lint` | Validate spec structure (
|
|
292
|
+
| `pactkit doctor` | Diagnose project health (HLD drift, board, config, deployment content parity, adapter skew) |
|
|
293
|
+
| `pactkit spec-lint` | Validate spec structure (E001-E010, W001-W011; incl. dependency surface checks) |
|
|
294
|
+
| `pactkit spec-graph` | Story dependency DAG: topological execution waves + file-conflict matrix (`--json` for orchestrators, `--write-graph` for Mermaid) |
|
|
294
295
|
| `pactkit spec-status` | Update spec Status field (Draft/In Progress/Done) |
|
|
295
296
|
| `pactkit guard` | Check project init markers |
|
|
296
297
|
| `pactkit next-id` | Generate next Story/Bug ID |
|
|
@@ -149,7 +149,7 @@ Or run the full cycle in one command:
|
|
|
149
149
|
| **Done** | `/project-done` | Repo Maintainer | Regression gate -> Archive -> Conventional commit |
|
|
150
150
|
| **Release** | `/project-release` | Repo Maintainer | Version bump -> Snapshot -> Git tag -> GitHub Release |
|
|
151
151
|
| **PR** | `/project-pr` | Repo Maintainer | Push branch -> Create pull request via gh CLI |
|
|
152
|
-
| **Sprint** | `/project-sprint` | Team Lead | One-command automated PDCA orchestration |
|
|
152
|
+
| **Sprint** | `/project-sprint` | Team Lead | One-command automated PDCA orchestration; empty args = Wave Mode (parallel backlog stories via `spec-graph` waves + conflict matrix) |
|
|
153
153
|
| **Hotfix** | `/project-hotfix` | Senior Developer | Fast-track fix bypassing PDCA (with traceability) |
|
|
154
154
|
| **Init** | `/project-init` | System Architect | Bootstrap project structure and governance |
|
|
155
155
|
| **Design** | `/project-design` | Product Designer | PRD generation -> Story decomposition -> Board setup |
|
|
@@ -244,8 +244,9 @@ PactKit ships 36 deterministic CLI subcommands — operations that were previous
|
|
|
244
244
|
| `pactkit upgrade` | Upgrade with format selection |
|
|
245
245
|
| `pactkit version` | Show installed version |
|
|
246
246
|
| `pactkit schema` | Print document schemas |
|
|
247
|
-
| `pactkit doctor` | Diagnose project health (HLD drift, board, config) |
|
|
248
|
-
| `pactkit spec-lint` | Validate spec structure (
|
|
247
|
+
| `pactkit doctor` | Diagnose project health (HLD drift, board, config, deployment content parity, adapter skew) |
|
|
248
|
+
| `pactkit spec-lint` | Validate spec structure (E001-E010, W001-W011; incl. dependency surface checks) |
|
|
249
|
+
| `pactkit spec-graph` | Story dependency DAG: topological execution waves + file-conflict matrix (`--json` for orchestrators, `--write-graph` for Mermaid) |
|
|
249
250
|
| `pactkit spec-status` | Update spec Status field (Draft/In Progress/Done) |
|
|
250
251
|
| `pactkit guard` | Check project init markers |
|
|
251
252
|
| `pactkit next-id` | Generate next Story/Bug ID |
|
{pactkit-2.18.0 → pactkit-2.20.0}/docs/architecture/governance/archive/lessons_archive_202603.md
RENAMED
|
@@ -73,3 +73,4 @@
|
|
|
73
73
|
| 2026-03-31 | tree-sitter comment nodes are direct children of function body nodes (block/statement_block), enabling scoped dispatch hint queries without parent traversal. Per-language comment query needed: Go/TS use (comment), Java uses [(line_comment)(block_comment)]. | visualize.py:_extract_calls_from_body |
|
|
74
74
|
| 2026-03-31 | config.py load_config() deep merge was single-level; adding check.pactguard (nested dict inside check) required upgrading to two-level merge to preserve sub-dict defaults like mode and blocking | src/pactkit/config.py:load_config |
|
|
75
75
|
| 2026-03-31 | Adding pactkit-garden to VALID_SKILLS broke 5 hardcoded count assertions in test_config.py, test_pdca_slim.py, test_selective_deploy.py, test_prompt_structural_invariants.py, test_story_slim063.py — grep == 21 and == 10 in tests before releasing a new skill | tests/unit/test_pdca_slim.py:test_valid_skills_count |
|
|
76
|
+
| 2026-03-31 | DETECTED_ENV in commands.py init playbook was unnecessary — _render_prompt(template, profile) already resolves per-format at deploy time. Added FORMAT_NAME to deployer.py var_map to enable pactkit init --format {FORMAT_NAME}. | deployer.py:_render_prompt |
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
# Lessons Archive (2026-04)
|
|
2
|
+
|
|
3
|
+
| Date | Lesson | Context |
|
|
4
|
+
|------|--------|---------|
|
|
5
|
+
| 2026-04-01 | Graduated safety language: retire MANDATORY keyword across prompts/commands.py, workflows.py, skills.py — use CRITICAL for safety gates (T1) and MUST for required steps (T2). Consistency prevents AI from treating all-caps keywords as equally urgent. | prompts/commands.py:MANDATORY→MUST/CRITICAL |
|
|
6
|
+
| 2026-04-01 | Multi-stack visualize: _detect_stack() returning single str masks Go/TS/Java files in mixed projects; _build_class_graph hardcoded ast.parse() silently skips non-Python via except. Fix: _detect_stacks() returns list, extract_classes() ABC on all 4 analyzers. | visualize.py:_detect_stacks,_build_class_graph |
|
|
@@ -2,9 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
| Date | Lesson | Context |
|
|
4
4
|
|------|--------|---------|
|
|
5
|
-
| 2026-03-31 | DETECTED_ENV in commands.py init playbook was unnecessary — _render_prompt(template, profile) already resolves per-format at deploy time. Added FORMAT_NAME to deployer.py var_map to enable pactkit init --format {FORMAT_NAME}. | deployer.py:_render_prompt |
|
|
6
|
-
| 2026-04-01 | Graduated safety language: retire MANDATORY keyword across prompts/commands.py, workflows.py, skills.py — use CRITICAL for safety gates (T1) and MUST for required steps (T2). Consistency prevents AI from treating all-caps keywords as equally urgent. | prompts/commands.py:MANDATORY→MUST/CRITICAL |
|
|
7
|
-
| 2026-04-01 | Multi-stack visualize: _detect_stack() returning single str masks Go/TS/Java files in mixed projects; _build_class_graph hardcoded ast.parse() silently skips non-Python via except. Fix: _detect_stacks() returns list, extract_classes() ABC on all 4 analyzers. | visualize.py:_detect_stacks,_build_class_graph |
|
|
8
5
|
| 2026-04-01 | Monorepo stack detection requires depth-1 subdir scan; cleaners.py and visualize.py _STACK_MARKERS must scan root/* not just root | cleaners.py:detect_stacks |
|
|
9
6
|
| 2026-04-01 | When splitting a monolithic file into submodules with deploy-time inlining via load_script(), relative imports (from .foo) in exec() context raise KeyError not ImportError — guard with except (ImportError, KeyError) | skills/__init__.py:load_script |
|
|
10
7
|
| 2026-04-01 | TSAnalyzer._load_tsconfig_paths must search depth-1 subdirs like _detect_stacks does because visualize.py always passes monorepo root as root param, not stack subdir — tsconfig in frontend/ is invisible if only root is searched | src/pactkit/skills/analyzers/ts_analyzer.py:_load_tsconfig_paths |
|
|
@@ -53,3 +50,6 @@
|
|
|
53
50
|
| 2026-08-13 | 门禁词表扫描须先剥离 code fence/inline code span(done_verify.py:_strip_code_spans),否则词表元讨论自身误报 | done_verify.py:_strip_code_spans |
|
|
54
51
|
| 2026-08-17 | check_deploy_parity 新增 hash 路径漏了 SEC-7 降级守卫(PermissionError/AttributeError 穿透 doctor)——Spec Security Scope 逐条自查 + 独立评审实重现能抓作者盲区 | doctor.py:check_deploy_parity |
|
|
55
52
|
| 2026-08-17 | deploy(format=all) 的 adapter 分支无视 target 直写真实 home——跨环境副作用必须显式审查 target/HOME 语义;测试通过 subprocess 调 CLI 时 HOME 未隔离即真实机器 | deployer.py:deploy |
|
|
53
|
+
| 2026-08-17 | Baseline budget tests (test_story063_prompt_slimming.py BASELINE_TOTAL_CHARS) leave <100 chars headroom — new playbook instructions must compress hard or bump baseline with justification comment | pactkit/prompts/commands.py |
|
|
54
|
+
| 2026-08-17 | pactkit update only deploys to ~/.claude — in-repo pactkit-plugin/commands copies need manual sync from prompts/ source (verified by normalized diff) | pactkit/prompts/workflows.py:SPRINT_PROMPT |
|
|
55
|
+
| 2026-08-22 | Continuation completion must validate real Spec/Board/test evidence and keep read-validate-write under a Story-level process lock; prompt-only evidence is insufficient. | src/pactkit/continuation.py:ContinuationStore |
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
|
|
16
16
|
## Invariants
|
|
17
17
|
|
|
18
|
-
1. All
|
|
18
|
+
1. All 4271+ tests must pass before any commit to `main`.
|
|
19
19
|
2. Specs (`docs/specs/`) are the source of truth — code conforms to specs, not the reverse.
|
|
20
20
|
3. CLI entry point is `pactkit` via `src/pactkit/cli.py:main`.
|
|
21
21
|
4. No runtime dependencies beyond `pyyaml`.
|
|
@@ -65,3 +65,31 @@
|
|
|
65
65
|
- [x] doctor.py: adapter 版本偏斜 warning
|
|
66
66
|
- [x] 运维: 本机 adapter 升级 2.17.0
|
|
67
67
|
- [x] AC3 双跑全量套件验证
|
|
68
|
+
|
|
69
|
+
### [STORY-slim-143] Spec Dependency Surface & Story DAG (spec-graph)
|
|
70
|
+
> Spec: docs/specs/STORY-slim-143.md
|
|
71
|
+
|
|
72
|
+
- [x] schemas.py Dependency Surface constants+template
|
|
73
|
+
- [x] spec_linter dangling-ref/missing-section rules
|
|
74
|
+
- [x] spec_graph.py DAG+waves+conflict matrix
|
|
75
|
+
- [x] cli.py spec-graph subcommand
|
|
76
|
+
- [x] TDD tests AC1-AC7
|
|
77
|
+
- [x] plan playbook Phase 3.2 step
|
|
78
|
+
|
|
79
|
+
### [STORY-slim-144] Sprint Wave Mode: conflict-aware parallel orchestration
|
|
80
|
+
> Spec: docs/specs/STORY-slim-144.md
|
|
81
|
+
|
|
82
|
+
- [x] spec-graph --json serializer
|
|
83
|
+
- [x] TDD json tests AC1-AC2
|
|
84
|
+
- [x] SPRINT_PROMPT wave mode section R2-R5
|
|
85
|
+
- [x] regenerate deployed sprint playbook
|
|
86
|
+
- [x] prompt content tests AC3-AC6
|
|
87
|
+
|
|
88
|
+
### [STORY-slim-146] 全 Skill 可恢复执行契约与 Act 断点续作
|
|
89
|
+
> Spec: docs/specs/STORY-slim-146.md
|
|
90
|
+
|
|
91
|
+
- [x] 建立 13 个 runtime skill 的恢复契约与完整性校验
|
|
92
|
+
- [x] 实现原子 continuation checkpoint、验证与安全 resume CLI
|
|
93
|
+
- [x] 为 project-act 加入逐步 checkpoint 与完成覆盖门禁
|
|
94
|
+
- [x] 接入 doctor/garden/status 诊断并验证 legacy 兼容
|
|
95
|
+
- [x] 验证四种 format 与外部 adapter 的真实 project-act 部署 parity
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Project Context (Auto-generated)
|
|
2
|
+
> Last updated: 2026-08-22T08:48:25+08:00 by pactkit context
|
|
3
|
+
|
|
4
|
+
## Sprint Status
|
|
5
|
+
Backlog: 5 | In Progress: 1 | Done: 0 stories
|
|
6
|
+
|
|
7
|
+
## Current Stories
|
|
8
|
+
- STORY-slim-145: Codex 部署命令语义完整性与 Adapter 兼容门禁
|
|
9
|
+
|
|
10
|
+
## Recent Completions
|
|
11
|
+
None
|
|
12
|
+
|
|
13
|
+
## Active Branches
|
|
14
|
+
+ claude/naughty-euclid-e6a787
|
|
15
|
+
develop
|
|
16
|
+
* main
|
|
17
|
+
|
|
18
|
+
## Key Decisions
|
|
19
|
+
- check_deploy_parity 新增 hash 路径漏了 SEC-7 降级守卫(PermissionError/AttributeError 穿透 doctor)——Spec Security Scope 逐条自查 + 独立评审实重现能抓作者盲区
|
|
20
|
+
- deploy(format=all) 的 adapter 分支无视 target 直写真实 home——跨环境副作用必须显式审查 target/HOME 语义;测试通过 subprocess 调 CLI 时 HOME 未隔离即真实机器
|
|
21
|
+
- Baseline budget tests (test_story063_prompt_slimming.py BASELINE_TOTAL_CHARS) leave <100 chars headroom — new playbook instructions must compress hard or bump baseline with justification comment
|
|
22
|
+
- pactkit update only deploys to ~/.claude — in-repo pactkit-plugin/commands copies need manual sync from prompts/ source (verified by normalized diff)
|
|
23
|
+
- Continuation completion must validate real Spec/Board/test evidence and keep read-validate-write under a Story-level process lock; prompt-only evidence is insufficient.
|
|
24
|
+
|
|
25
|
+
## Next Recommended Action
|
|
26
|
+
`/project-act` (stories in progress)
|
|
27
|
+
|
|
28
|
+
## Agent Continuation
|
|
29
|
+
No active work session.
|
|
@@ -38,5 +38,13 @@
|
|
|
38
38
|
|
|
39
39
|
## 🔄 In Progress
|
|
40
40
|
|
|
41
|
-
|
|
41
|
+
### [STORY-slim-145] Codex 部署命令语义完整性与 Adapter 兼容门禁
|
|
42
|
+
> Spec: docs/specs/STORY-slim-145.md
|
|
43
|
+
|
|
44
|
+
- [x] 建立 CLI policy 与结构化操作渲染契约
|
|
45
|
+
- [x] 移除 pactkit-codex 有损命令前缀替换
|
|
46
|
+
- [x] 增加 prompt 完整性与 Classic/Codex parity 门禁
|
|
47
|
+
- [x] 阻止不兼容 Core/adapter 组合静默部署
|
|
48
|
+
- [ ] 完成隔离迁移、双仓回归与同版本发布验证
|
|
42
49
|
|
|
50
|
+
## ✅ Done
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
# STORY-slim-143: Spec Dependency Surface & Story DAG (spec-graph)
|
|
2
|
+
|
|
3
|
+
| Field | Value |
|
|
4
|
+
|-------|-------|
|
|
5
|
+
| ID | STORY-slim-143 |
|
|
6
|
+
| Status | Done |
|
|
7
|
+
| Priority | P1 |
|
|
8
|
+
| Release | 2.19.0 |
|
|
9
|
+
|
|
10
|
+
## Background
|
|
11
|
+
|
|
12
|
+
/project-plan currently writes each Spec in isolation — there is no structured record of *what a story depends on*, *what public surface it provides*, or *which files it will touch*. Plan Phase 3.3 only suggests "record story dependencies if applicable" via Memory MCP (optional, unstructured). Consequences:
|
|
13
|
+
|
|
14
|
+
1. When multiple stories are implemented in parallel (multiple agents / worktrees), file-level conflicts are only discovered at merge time.
|
|
15
|
+
2. Story execution order (先后顺序) is implicit in the architect's head, not computable — nothing can topologically sort the board.
|
|
16
|
+
3. `/project-sprint` today runs strictly one story at a time; safe parallel scheduling requires machine-readable dependency data.
|
|
17
|
+
|
|
18
|
+
This story adds a **Dependency Surface** section to the Spec schema, lints it, and introduces `pactkit spec-graph` — a deterministic CLI that parses all Specs and emits a story dependency DAG, topological execution waves, and a file-overlap conflict matrix. Downstream stories (sprint wave orchestration, interface-first contract staging, merge-preflight) consume this data but are out of scope here.
|
|
19
|
+
|
|
20
|
+
## Requirements
|
|
21
|
+
|
|
22
|
+
### R1: Dependency Surface Schema (MUST)
|
|
23
|
+
|
|
24
|
+
`schemas.py` MUST define a new optional Spec section `## Dependency Surface` (added to `SPEC_TEMPLATE` and `SPEC_OPTIONAL_SECTIONS`, registered in `SCHEMA_REGISTRY`) with exactly four pipe-table fields:
|
|
25
|
+
|
|
26
|
+
| Field | Value |
|
|
27
|
+
|-------|-------|
|
|
28
|
+
| Depends on | comma-separated story IDs this story consumes, each with a `needs:` note (e.g. `STORY-143 (needs: spec-graph CLI)`), or `None` |
|
|
29
|
+
| Provides | public surface this story adds (CLI commands, exported functions, schema constants), or `None` |
|
|
30
|
+
| Touches | glob-level file paths this story expects to modify (e.g. `src/pactkit/cli.py`, `src/pactkit/skills/*.py`) |
|
|
31
|
+
| Conflict risk | `LOW` / `MEDIUM` / `HIGH` + free-text reason |
|
|
32
|
+
|
|
33
|
+
Schema constants (section name, field names, risk levels) MUST live in `schemas.py` as named constants — no magic strings in parser/linter/CLI.
|
|
34
|
+
|
|
35
|
+
### R2: Linter Rules for Dependency Surface (MUST)
|
|
36
|
+
|
|
37
|
+
`spec_linter.py` MUST add checks, invoked from `validate_spec()` following the existing `_check_*` call-sequence pattern:
|
|
38
|
+
|
|
39
|
+
- **New ERROR rule**: a `Depends on` entry references a story ID that has no corresponding file in the specs dir (dangling dependency) — typo protection, since ordering decisions rely on these edges.
|
|
40
|
+
- **New WARNING rule**: `## Dependency Surface` section is missing or its table lacks any of the four required fields.
|
|
41
|
+
|
|
42
|
+
Both rules MUST reuse the existing `_find_section` / `_section_text` parsing helpers — no fourth copy of section-parsing regexes.
|
|
43
|
+
|
|
44
|
+
### R3: `pactkit spec-graph` CLI (MUST)
|
|
45
|
+
|
|
46
|
+
New module `src/pactkit/spec_graph.py` + `spec-graph` subcommand in `cli.py` (argparse subparser + dispatch chain, same pattern as `spec-lint`). Given `--specs-dir docs/specs` (default), it MUST:
|
|
47
|
+
|
|
48
|
+
1. Parse every Spec's Dependency Surface table (reusing spec_linter parsing helpers).
|
|
49
|
+
2. Build the story DAG from `Depends on` edges (excluding edges to stories already `Status | Done`, which are satisfied).
|
|
50
|
+
3. Topologically sort into **execution waves**: wave N contains all stories whose remaining dependencies are all in waves < N. Stories in the same wave are parallelizable.
|
|
51
|
+
4. Compute a **conflict matrix**: pairs of stories whose `Touches` globs overlap (same literal path or glob intersection) are flagged; pairs in the same wave with overlap MUST be highlighted as unsafe-parallel.
|
|
52
|
+
5. Detect dependency cycles and MUST report them as an error (non-zero exit) with the cycle path — a cycle means the Specs themselves are contradictory.
|
|
53
|
+
6. Emit a Mermaid graph to `docs/architecture/graphs/story_graph.mmd` (`--write-graph` flag) and print the wave list + conflict matrix to stdout.
|
|
54
|
+
|
|
55
|
+
### R4: Deterministic Scheduling Semantics (MUST)
|
|
56
|
+
|
|
57
|
+
Wave assignment, overlap detection, and cycle detection MUST be computed entirely in code (LLM ≠ Calculator). The CLI output MUST be stable for identical Spec inputs — same input, same waves, same matrix ordering (sorted output, no dict-iteration nondeterminism).
|
|
58
|
+
|
|
59
|
+
### R5: Plan Playbook Integration (SHOULD)
|
|
60
|
+
|
|
61
|
+
`pactkit-plugin/commands/project-plan.md` Phase 3.2 SHOULD gain a step instructing the architect to fill the Dependency Surface from Phase 1 trace findings (touches = traced files; depends-on = stories whose Provides it consumes). Sprint parallel orchestration itself is explicitly NOT changed by this story.
|
|
62
|
+
|
|
63
|
+
## Technical Design
|
|
64
|
+
|
|
65
|
+
### Lateral Scan Results
|
|
66
|
+
|
|
67
|
+
- Operation: parse Spec metadata/section structure
|
|
68
|
+
- Existing implementations: 3 (`spec_linter.py` `_find_section`/`_section_text`, `done_verify.py` requirement parsing, `audit.py` status check)
|
|
69
|
+
- Assessment: **Reuse existing** — `spec_graph.py` and the new lint rules import spec_linter's helpers; no new regex parser is written.
|
|
70
|
+
|
|
71
|
+
### Capability Assessment
|
|
72
|
+
|
|
73
|
+
| Need | Source | Decision |
|
|
74
|
+
|------|--------|----------|
|
|
75
|
+
| Spec section/metadata parsing | `pactkit.skills.spec_linter` (project) | Reuse |
|
|
76
|
+
| Topological sort / cycle detection | stdlib (`graphlib.TopologicalSorter`, Python ≥ 3.9) | Enable — no new dependency |
|
|
77
|
+
| Glob overlap check | stdlib `fnmatch` + path normalization | Enable |
|
|
78
|
+
| CLI registration | `cli.py` subparser chain (project) | Reuse |
|
|
79
|
+
|
|
80
|
+
### New Implementation Required
|
|
81
|
+
|
|
82
|
+
- `pactkit/spec_graph.py`: Dependency Surface parsing → DAG → waves → conflict matrix → Mermaid emit. Single responsibility, pure functions over parsed data (testable without filesystem fixtures beyond temp specs).
|
|
83
|
+
|
|
84
|
+
### Concurrency Decision (Engineering Concern: concurrency)
|
|
85
|
+
|
|
86
|
+
No runtime concurrency in this story. The *scheduling* semantics are deterministic data: waves are computed by `graphlib`, and any future parallel executor (sprint story) consumes the wave list rather than re-deriving it. This keeps the "can these two stories run in parallel?" judgment in code, not in an LLM prompt.
|
|
87
|
+
|
|
88
|
+
## Acceptance Criteria
|
|
89
|
+
|
|
90
|
+
### AC1: Scaffolded Spec carries Dependency Surface (R1)
|
|
91
|
+
|
|
92
|
+
- **Given** a project with pactkit initialized and the new schema deployed
|
|
93
|
+
- **When** `scaffold.py create_spec "STORY-x-999" "demo"` is run
|
|
94
|
+
- **Then** the generated Spec contains `## Dependency Surface` with all four fields (Depends on / Provides / Touches / Conflict risk) and `pactkit spec-lint` on it reports 0 errors and 0 warnings for the new rules.
|
|
95
|
+
|
|
96
|
+
### AC2: Dangling dependency is rejected (R2)
|
|
97
|
+
|
|
98
|
+
- **Given** a Spec whose `Depends on` includes `STORY-slim-999` and no such file exists in the specs dir
|
|
99
|
+
- **When** `pactkit spec-lint` runs on that Spec
|
|
100
|
+
- **Then** it reports the new ERROR rule naming the dangling ID, and exits non-zero.
|
|
101
|
+
|
|
102
|
+
### AC3: Missing section is a warning (R2)
|
|
103
|
+
|
|
104
|
+
- **Given** an otherwise-valid Spec with no `## Dependency Surface` section (e.g. all pre-2.19 Specs)
|
|
105
|
+
- **When** `pactkit spec-lint` runs on it
|
|
106
|
+
- **Then** the new WARNING fires but existing rules are unaffected.
|
|
107
|
+
|
|
108
|
+
### AC4: Waves and conflict matrix from real Specs (R3, R4)
|
|
109
|
+
|
|
110
|
+
- **Given** three Specs: A (Depends on: None, Touches: `a.py`), B (Depends on: A, Touches: `b.py`), C (Depends on: None, Touches: `a.py`)
|
|
111
|
+
- **When** `pactkit spec-graph` runs
|
|
112
|
+
- **Then** output shows wave 1 = {A, C}, wave 2 = {B}, and flags A↔C as a same-wave file conflict on `a.py` (unsafe-parallel).
|
|
113
|
+
|
|
114
|
+
### AC5: Cycle detection (R3, R4)
|
|
115
|
+
|
|
116
|
+
- **Given** two Specs that depend on each other
|
|
117
|
+
- **When** `pactkit spec-graph` runs
|
|
118
|
+
- **Then** it exits non-zero and prints the cycle path (e.g. `A -> B -> A`).
|
|
119
|
+
|
|
120
|
+
### AC6: Deterministic output (R4)
|
|
121
|
+
|
|
122
|
+
- **Given** any fixed set of Specs
|
|
123
|
+
- **When** `pactkit spec-graph` runs twice
|
|
124
|
+
- **Then** wave lists and conflict matrix are byte-identical (sorted, stable ordering).
|
|
125
|
+
|
|
126
|
+
### AC7: Plan playbook documents the step (R5)
|
|
127
|
+
|
|
128
|
+
- **Given** the updated `project-plan.md` playbook
|
|
129
|
+
- **When** reading Phase 3.2
|
|
130
|
+
- **Then** it contains a step instructing the architect to fill the Dependency Surface (touches from Phase 1 trace, depends-on from consumed Provides), with a pointer to the field semantics in R1.
|
|
131
|
+
|
|
132
|
+
## Target Call Chain
|
|
133
|
+
|
|
134
|
+
- CLI: `pactkit spec-graph` → `cli.py` (subparser + dispatch) → `pactkit.spec_graph.main(argv)`
|
|
135
|
+
- Core: `spec_graph.main` → `parse_dependency_surfaces(specs_dir)` (reuses `spec_linter._find_section` / `_section_text`) → `build_dag()` → `graphlib.TopologicalSorter` (waves) → `conflict_matrix()` (fnmatch overlap) → stdout / `story_graph.mmd`
|
|
136
|
+
- Lint: `pactkit spec-lint` → `spec_linter.validate_spec()` → new `_check_dependency_surface()` (dangling-ref ERROR, missing-section WARNING)
|
|
137
|
+
- Scaffold: `scaffold.py create_spec` → `schemas.SPEC_TEMPLATE` (now includes Dependency Surface)
|
|
138
|
+
|
|
139
|
+
## Dependency Surface
|
|
140
|
+
|
|
141
|
+
| Field | Value |
|
|
142
|
+
|-------|-------|
|
|
143
|
+
| Depends on | None |
|
|
144
|
+
| Provides | `pactkit spec-graph` CLI; `pactkit.spec_graph` module; `DEP_SURFACE_*` schema constants; 2 new spec-lint rules |
|
|
145
|
+
| Touches | `src/pactkit/schemas.py`, `src/pactkit/skills/spec_linter.py`, `src/pactkit/spec_graph.py` (new), `src/pactkit/cli.py`, `pactkit-plugin/commands/project-plan.md`, `tests/unit/test_story_slim143_spec_graph.py` (new), `tests/unit/test_story042_spec_linter.py` |
|
|
146
|
+
| Conflict risk | LOW — schemas.py and cli.py are frequently touched, but changes are append-only (new section constant, new subparser), minimal overlap with typical feature stories |
|
|
147
|
+
|
|
148
|
+
## Implementation Steps
|
|
149
|
+
|
|
150
|
+
| Step | File | Action | Dependencies | Risk |
|
|
151
|
+
|------|------|--------|-------------|------|
|
|
152
|
+
| 1 | `src/pactkit/schemas.py` | Add `DEP_SURFACE_*` constants + section in SPEC_TEMPLATE + SCHEMA_REGISTRY | None | Low |
|
|
153
|
+
| 2 | `src/pactkit/skills/spec_linter.py` | Add `_check_dependency_surface` (dangling-ref ERROR, missing-section WARNING) | Step 1 | Low |
|
|
154
|
+
| 3 | `src/pactkit/spec_graph.py` | New module: parse → DAG → waves (graphlib) → conflict matrix → Mermaid | Step 1 | Medium (glob-overlap edge cases) |
|
|
155
|
+
| 4 | `src/pactkit/cli.py` | Register `spec-graph` subparser + dispatch | Step 3 | Low |
|
|
156
|
+
| 5 | `tests/unit/` | TDD tests for AC1–AC6 | Steps 1–4 | Low |
|
|
157
|
+
| 6 | `pactkit-plugin/commands/project-plan.md` | Phase 3.2 step: fill Dependency Surface from trace findings | Step 1 | Low |
|
|
158
|
+
|
|
159
|
+
## Security Scope
|
|
160
|
+
|
|
161
|
+
| Check | Applicable | Reason |
|
|
162
|
+
|-------|------------|--------|
|
|
163
|
+
| SEC-1 | Yes | new source module spec_graph.py — code quality standards apply |
|
|
164
|
+
| SEC-2 | Yes | parses user-authored Spec markdown + glob paths — must tolerate malformed tables/globs without crashing |
|
|
165
|
+
| SEC-3 | N/A | no database/ORM (auto-detect false positive: no SQL involved) |
|
|
166
|
+
| SEC-4 | N/A | no frontend files |
|
|
167
|
+
| SEC-5 | N/A | no auth patterns |
|
|
168
|
+
| SEC-6 | N/A | no API/route files |
|
|
169
|
+
| SEC-7 | Yes | cycle detection and dangling refs must fail with clear errors, non-zero exit, no stack traces |
|
|
170
|
+
| SEC-8 | N/A | no new dependencies — stdlib only (graphlib, fnmatch) |
|
|
171
|
+
|
|
172
|
+
## Out of Scope
|
|
173
|
+
|
|
174
|
+
- `/project-sprint` wave-based parallel orchestration (depends on this story's Provides; separate story)
|
|
175
|
+
- Interface-first contract staging for depended-upon stories
|
|
176
|
+
- Merge-preflight conflict check (`--check-conflicts`) at agent completion time
|
|
177
|
+
- Auto-fixing file conflicts (spec-graph only *reports* them)
|
|
178
|
+
- Board format changes (board.py untouched)
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
# STORY-slim-144: Sprint Wave Mode: conflict-aware parallel orchestration
|
|
2
|
+
|
|
3
|
+
| Field | Value |
|
|
4
|
+
|-------|-------|
|
|
5
|
+
| ID | STORY-slim-144 |
|
|
6
|
+
| Status | Done |
|
|
7
|
+
| Priority | P1 |
|
|
8
|
+
| Release | 2.19.0 |
|
|
9
|
+
|
|
10
|
+
## Background
|
|
11
|
+
|
|
12
|
+
`/project-sprint` (v1.5.0) orchestrates exactly ONE story per invocation: Plan → Act → Check → Close, strictly sequential in worktrees. STORY-slim-143 delivered the missing data layer — every Spec now declares a Dependency Surface, and `pactkit spec-graph` computes execution waves (topological layers) and a file-overlap conflict matrix. What remains is the **consumer**: a wave mode in sprint that runs multiple backlog stories concurrently when the data proves it safe.
|
|
13
|
+
|
|
14
|
+
Design constraints from the existing architecture:
|
|
15
|
+
- Backward compatible: `$ARGUMENTS` present → current single-story mode, unchanged.
|
|
16
|
+
- LLM ≠ Calculator: wave membership, parallel/serialize decisions, and conflict checks come from `spec-graph` output, never from orchestrator judgment.
|
|
17
|
+
- Safe by default: stories without a declared `Touches` (legacy/placeholder) MUST NOT be parallelized — unknown conflict surface means serialize.
|
|
18
|
+
|
|
19
|
+
## Requirements
|
|
20
|
+
|
|
21
|
+
### R1: `spec-graph --json` Machine-Readable Output (MUST)
|
|
22
|
+
|
|
23
|
+
`pactkit spec-graph` MUST accept a `--json` flag emitting `{waves: [[ids]], conflicts: [{story_a, story_b, shared, same_wave}]}` with sorted, deterministic ordering. The sprint orchestrator consumes this instead of parsing human output. Cycle errors MUST still exit non-zero (JSON or not).
|
|
24
|
+
|
|
25
|
+
### R2: Wave Mode Entry (MUST)
|
|
26
|
+
|
|
27
|
+
`commands/project-sprint.md` (source: `src/pactkit/prompts/workflows.py` SPRINT_PROMPT) MUST gain a wave mode with this entry rule:
|
|
28
|
+
|
|
29
|
+
- `$ARGUMENTS` non-empty → existing single-story mode, byte-for-byte behavior preserved.
|
|
30
|
+
- `$ARGUMENTS` empty → wave mode:
|
|
31
|
+
1. `board.py list_stories` → BACKLOG story IDs.
|
|
32
|
+
2. `pactkit spec-graph --json` → waves + conflicts, filtered to backlog IDs with existing Specs.
|
|
33
|
+
3. If no parallelizable stories exist (all serialized), log and fall back to single-story suggestion.
|
|
34
|
+
|
|
35
|
+
### R3: Conflict-Aware Scheduling Policy (MUST)
|
|
36
|
+
|
|
37
|
+
Within each wave, the orchestrator MUST partition stories into:
|
|
38
|
+
|
|
39
|
+
- **Parallel batch**: stories whose Touches are all declared (no placeholder/missing) AND pairwise non-conflicting per the matrix. Batch size MUST NOT exceed `sprint.max_parallel` from pactkit.yaml (default 3, named constant — no magic value); excess stories spill to a following sub-batch.
|
|
40
|
+
- **Serialized tail**: stories flagged same-wave-conflict, or with undeclared Touches, run one-at-a-time after the parallel batch.
|
|
41
|
+
|
|
42
|
+
Each story (parallel or serialized) runs the EXISTING per-story PDCA chain (Plan→Act→Check→Close) in its own worktree, reusing current Stage A/B/C dispatch logic — no duplicated stage definitions (DRY).
|
|
43
|
+
|
|
44
|
+
### R4: Wave Gate & Failure Policy (MUST)
|
|
45
|
+
|
|
46
|
+
- Wave N+1 MUST NOT start until every wave-N story is merged green (worktree merged, tests passing per each story's Close stage).
|
|
47
|
+
- Any story failure → STOP the wave immediately (fail-fast, consistent with current single-story semantics), report which stories completed/merged vs pending, and leave remaining stories on the board. NEVER auto-retry a failed story in the same run.
|
|
48
|
+
- Merge conflict on worktree merge → STOP + suggest `git merge --abort` (existing error contract preserved).
|
|
49
|
+
|
|
50
|
+
### R5: Observability (SHOULD)
|
|
51
|
+
|
|
52
|
+
The orchestrator SHOULD print a wave plan before dispatching (wave N: parallel=[...], serialized=[...], skipped=[...] with reasons) so the user can abort before any subagent spawns.
|
|
53
|
+
|
|
54
|
+
## Technical Design
|
|
55
|
+
|
|
56
|
+
### Lateral Scan Results
|
|
57
|
+
|
|
58
|
+
- Operation: subagent orchestration with dependency ordering
|
|
59
|
+
- Existing implementations: 1 (`SPRINT_PROMPT` single-story chain) — no existing parallel scheduler
|
|
60
|
+
- Assessment: **New is justified** — wave mode extends the single existing orchestrator; per-story chain is reused verbatim, not copied.
|
|
61
|
+
|
|
62
|
+
### Capability Assessment
|
|
63
|
+
|
|
64
|
+
| Need | Source | Decision |
|
|
65
|
+
|------|--------|----------|
|
|
66
|
+
| Waves + conflict matrix | `pactkit spec-graph` (STORY-slim-143) | Reuse — add `--json` consumer interface |
|
|
67
|
+
| Backlog enumeration | `board.py list_stories` | Reuse |
|
|
68
|
+
| Worktree isolation | existing sprint Stage A/B/C pattern | Reuse |
|
|
69
|
+
| Parallel cap config | pactkit.yaml `sprint.max_parallel` (new optional key, default 3) | New config key |
|
|
70
|
+
|
|
71
|
+
### New Implementation Required
|
|
72
|
+
|
|
73
|
+
- `spec_graph.py`: `--json` flag + `to_json()` serializer (~30 lines).
|
|
74
|
+
- `SPRINT_PROMPT`: Wave Mode section (Phase 0.5: Mode Detection; Phase 1W: Wave loop). Deployed copy `pactkit-plugin/commands/project-sprint.md` regenerated via `pactkit update`.
|
|
75
|
+
|
|
76
|
+
### Concurrency Decision (Engineering Concern: concurrency)
|
|
77
|
+
|
|
78
|
+
Parallelism is at the **subagent/team level** (Claude Code Task agents with worktree isolation), not threads/processes in pactkit code — pactkit itself stays single-threaded. The cap (`sprint.max_parallel`, default 3) bounds concurrent worktrees. Merging is always sequential (one worktree at a time), which is the serialization point that keeps git state sane. Conflict avoidance is precomputed by `spec-graph`, not detected at merge time.
|
|
79
|
+
|
|
80
|
+
### Error-Recovery Decision (Engineering Concern: error-recovery)
|
|
81
|
+
|
|
82
|
+
Fail-fast per wave; no auto-retry; partial progress is always safe because every completed story merged through its own green PDCA chain. Resume = re-run `/project-sprint` — remaining backlog stories re-enter wave computation (idempotent, since completed stories are Done and excluded by spec-graph).
|
|
83
|
+
|
|
84
|
+
### Backwards-Compatibility Decision (Engineering Concern: backwards-compatibility)
|
|
85
|
+
|
|
86
|
+
Single-story mode is the default when args are present — zero behavior change for existing users. Wave mode is opt-in via empty args. `sprint.max_parallel` absent from pactkit.yaml → default 3, no config migration needed.
|
|
87
|
+
|
|
88
|
+
## Acceptance Criteria
|
|
89
|
+
|
|
90
|
+
### AC1: JSON output shape (R1)
|
|
91
|
+
|
|
92
|
+
- **Given** specs forming 2 waves with one same-wave conflict
|
|
93
|
+
- **When** `pactkit spec-graph --json` runs
|
|
94
|
+
- **Then** stdout parses as JSON with `waves` (list of sorted ID lists) and `conflicts` (list of objects with story_a/story_b/shared/same_wave), and two runs are byte-identical.
|
|
95
|
+
|
|
96
|
+
### AC2: Cycle still errors under --json (R1)
|
|
97
|
+
|
|
98
|
+
- **Given** two mutually dependent specs
|
|
99
|
+
- **When** `pactkit spec-graph --json` runs
|
|
100
|
+
- **Then** exit code is non-zero and stderr names the cycle.
|
|
101
|
+
|
|
102
|
+
### AC3: Mode detection (R2)
|
|
103
|
+
|
|
104
|
+
- **Given** the updated SPRINT_PROMPT / project-sprint.md
|
|
105
|
+
- **When** reading the entry phase
|
|
106
|
+
- **Then** it specifies: non-empty `$ARGUMENTS` → single-story mode (unchanged path); empty → wave mode with board scan + `spec-graph --json` + fallback when nothing is parallelizable.
|
|
107
|
+
|
|
108
|
+
### AC4: Scheduling policy documented and deterministic (R3)
|
|
109
|
+
|
|
110
|
+
- **Given** the updated playbook
|
|
111
|
+
- **When** reading the wave-mode section
|
|
112
|
+
- **Then** it encodes all of: parallel batch requires declared Touches AND pairwise non-conflict; `sprint.max_parallel` cap with default 3; serialized tail for conflicted/undeclared stories; per-story worktree PDCA chain reuse (reference, not copy).
|
|
113
|
+
|
|
114
|
+
### AC5: Wave gate & failure policy (R4, R5)
|
|
115
|
+
|
|
116
|
+
- **Given** the updated playbook
|
|
117
|
+
- **When** reading the wave-mode section
|
|
118
|
+
- **Then** it states: wave N+1 blocked until wave N fully merged; fail-fast STOP with completed/pending report; no auto-retry; merge-conflict → STOP + `git merge --abort` suggestion; wave plan printed before dispatch.
|
|
119
|
+
|
|
120
|
+
### AC6: Prompt hygiene (R2-R5)
|
|
121
|
+
|
|
122
|
+
- **Given** the implemented changes
|
|
123
|
+
- **When** running `pytest tests/unit/test_prompt_cli_refs.py tests/unit/test_story063_prompt_slimming.py` and full suite
|
|
124
|
+
- **Then** all pass (prompt baselines bumped per project convention if needed, with justification comments).
|
|
125
|
+
|
|
126
|
+
## Target Call Chain
|
|
127
|
+
|
|
128
|
+
- Wave mode: `/project-sprint` (empty args) → SPRINT_PROMPT Mode Detection → `board.py list_stories` + `pactkit spec-graph --json` → wave plan → per-story existing Stage A/B/C dispatch (worktree) → sequential merges → wave gate → next wave
|
|
129
|
+
- JSON: `cli.py spec-graph` → `spec_graph.main(["--json"])` → `to_json(graph)` (waves via `compute_waves`, conflicts via `compute_conflicts`)
|
|
130
|
+
|
|
131
|
+
## Dependency Surface
|
|
132
|
+
|
|
133
|
+
| Field | Value |
|
|
134
|
+
|-------|-------|
|
|
135
|
+
| Depends on | STORY-slim-143 (needs: `pactkit spec-graph` waves + conflict matrix, `spec_graph.compute_waves`/`compute_conflicts`) |
|
|
136
|
+
| Provides | `pactkit spec-graph --json`; sprint wave mode; `sprint.max_parallel` config key |
|
|
137
|
+
| Touches | `src/pactkit/spec_graph.py`, `src/pactkit/prompts/workflows.py`, `pactkit-plugin/commands/project-sprint.md`, `tests/unit/test_story_slim144_wave_mode.py` (new) |
|
|
138
|
+
| Conflict risk | LOW — workflows.py SPRINT_PROMPT and spec_graph.py append-only changes; no overlap with typical feature stories |
|
|
139
|
+
|
|
140
|
+
## Implementation Steps
|
|
141
|
+
|
|
142
|
+
| Step | File | Action | Dependencies | Risk |
|
|
143
|
+
|------|------|--------|-------------|------|
|
|
144
|
+
| 1 | `src/pactkit/spec_graph.py` | Add `--json` + `to_json()` | None | Low |
|
|
145
|
+
| 2 | `tests/unit/test_story_slim144_wave_mode.py` | TDD tests for AC1/AC2 | Step 1 | Low |
|
|
146
|
+
| 3 | `src/pactkit/prompts/workflows.py` | SPRINT_PROMPT wave mode section (R2-R5) | Step 1 | Medium (prompt size budget) |
|
|
147
|
+
| 4 | `pactkit-plugin/commands/project-sprint.md` | Regenerate via `pactkit update` | Step 3 | Low |
|
|
148
|
+
| 5 | `tests/unit/` | Prompt content assertions for AC3-AC5 | Step 3 | Low |
|
|
149
|
+
|
|
150
|
+
## Security Scope
|
|
151
|
+
|
|
152
|
+
| Check | Applicable | Reason |
|
|
153
|
+
|-------|------------|--------|
|
|
154
|
+
| SEC-1 | Yes | spec_graph.py source change — code quality standards apply |
|
|
155
|
+
| SEC-2 | Yes | --json serializer consumes spec-derived data — output must be valid JSON for any malformed surface input |
|
|
156
|
+
| SEC-3 | N/A | no database |
|
|
157
|
+
| SEC-4 | N/A | no frontend |
|
|
158
|
+
| SEC-5 | N/A | auto-detect false positive: no auth/session code touched (prompt text only) |
|
|
159
|
+
| SEC-6 | N/A | no API endpoints |
|
|
160
|
+
| SEC-7 | Yes | cycle error under --json must stay a clean single-line stderr + non-zero exit |
|
|
161
|
+
| SEC-8 | N/A | no new dependencies (stdlib json) |
|
|
162
|
+
|
|
163
|
+
## Out of Scope
|
|
164
|
+
|
|
165
|
+
- Interface-first contract staging (separate downstream story)
|
|
166
|
+
- Merge-preflight conflict check at agent completion time
|
|
167
|
+
- Auto-retry / self-healing of failed stories
|
|
168
|
+
- Parallelism inside pactkit code itself (threads/async) — orchestration-level only
|
|
169
|
+
- Changing single-story mode behavior in any way
|