pactkit 2.10.2__tar.gz → 2.10.4__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.10.2 → pactkit-2.10.4}/.opencode/pactkit.yaml +1 -1
- {pactkit-2.10.2 → pactkit-2.10.4}/CHANGELOG.md +10 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/PKG-INFO +1 -1
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/architecture/governance/archive/lessons_archive_202603.md +2 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/architecture/governance/lessons.md +2 -2
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/architecture/governance/rules.md +1 -1
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/product/archive/archive_202604.md +7 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/product/context.md +3 -3
- pactkit-2.10.4/docs/specs/STORY-slim-100.md +87 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/pyproject.toml +1 -1
- {pactkit-2.10.2 → pactkit-2.10.4}/src/pactkit/__init__.py +1 -1
- {pactkit-2.10.2 → pactkit-2.10.4}/src/pactkit/cleaners.py +25 -2
- {pactkit-2.10.2 → pactkit-2.10.4}/src/pactkit/prompts/workflows.py +10 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_hotfix_command.py +37 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story063_prompt_slimming.py +2 -1
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story_slim014_clean.py +44 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/.github/workflows/pactkit.yml +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/.github/workflows/publish.yml +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/.gitignore +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/AGENTS.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/CODE_OF_CONDUCT.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/CONTRIBUTING.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/LICENSE +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/README.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/SECURITY.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/architecture/governance/archive/lessons_archive_202602.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/architecture/governance/harness_audit.json +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/architecture/governance/philosophy.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/assets/logo.png +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/guides/codex-integration-preresearch.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/guides/tool-integration-checklist.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/product/archive/archive_202602.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/product/archive/archive_202603.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/product/friction-log.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/product/prd.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/product/sprint_board.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/BUG-001.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/BUG-002.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/BUG-003.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/BUG-004.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/BUG-005.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/BUG-006.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/BUG-007.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/BUG-008.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/BUG-009.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/BUG-010.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/BUG-011.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/BUG-012.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/BUG-013.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/BUG-014.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/BUG-015.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/BUG-016.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/BUG-017.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/BUG-018.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/BUG-019.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/BUG-020.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/BUG-021.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/BUG-022.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/BUG-023.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/BUG-024.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/BUG-025.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/BUG-026.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/BUG-027.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/BUG-028.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/BUG-029.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/BUG-030.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/BUG-031.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/BUG-032.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/BUG-033.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/BUG-034.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/BUG-035.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/BUG-slim-001.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/BUG-slim-002.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/BUG-slim-003.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/BUG-slim-004.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/BUG-slim-005.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/BUG-slim-006.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/BUG-slim-089.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/HOTFIX-slim-023.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/HOTFIX-slim-049.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/HOTFIX-slim-050.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/HOTFIX-slim-051.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/HOTFIX-slim-052.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/HOTFIX-slim-061.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/HOTFIX-slim-062.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/HOTFIX-slim-067.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/HOTFIX-slim-069.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/HOTFIX-slim-070.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/HOTFIX-slim-085.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/HOTFIX-slim-087.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/HOTFIX-slim-096.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/HOTFIX-slim-099.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-001.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-002.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-003.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-004.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-005.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-006.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-007.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-008.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-009.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-010.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-011.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-012.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-013.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-014.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-015.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-016.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-017.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-018.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-019.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-020.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-021.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-022.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-023.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-024.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-025.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-026.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-027.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-028.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-029.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-030.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-031.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-032.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-033.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-034.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-035.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-036.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-037.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-038.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-039.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-040.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-041.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-042.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-043.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-044.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-045.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-046.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-047.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-048.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-049.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-050.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-051.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-052.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-053.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-054.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-055.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-056.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-057.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-058.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-059.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-060.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-061.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-062.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-063.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-064.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-065.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-069.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-070.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-071.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-072.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-073.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-001.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-005.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-006.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-007.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-009.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-010.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-011.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-012.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-013.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-014.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-015.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-016.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-017.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-018.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-019.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-020.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-021.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-022.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-023.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-024.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-028.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-029.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-030.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-031.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-032.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-033.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-034.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-035.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-036.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-037.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-038.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-039.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-040.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-041.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-042.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-043.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-044.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-045.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-046.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-047.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-048.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-049.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-050.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-051.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-052.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-053.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-054.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-055.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-056.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-057.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-058.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-059.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-060.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-063.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-066.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-067.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-068.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-069.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-070.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-071.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-072.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-073.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-074.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-075.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-076.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-077.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-078.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-079.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-080.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-081.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-082.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-083.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-084.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-086.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-088.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-089.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-090.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-091.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-092.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-093.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-094.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-095.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-097.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-098.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/specs/STORY-slim-099.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/test_cases/BUG-001_case.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/test_cases/BUG-002_case.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/test_cases/STORY-slim-028_case.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/test_cases/STORY-slim-029_case.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/test_cases/STORY-slim-031_case.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/test_cases/STORY-slim-032_case.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/test_cases/STORY-slim-033_case.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/docs/test_cases/STORY-slim-034_case.md +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/opencode.json +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/src/pactkit/__main__.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/src/pactkit/audit.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/src/pactkit/backfill.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/src/pactkit/cli.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/src/pactkit/config.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/src/pactkit/context_gen.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/src/pactkit/coverage_gate.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/src/pactkit/doctor.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/src/pactkit/garden.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/src/pactkit/generators/__init__.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/src/pactkit/generators/adapter.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/src/pactkit/generators/deploy_base.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/src/pactkit/generators/deployer.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/src/pactkit/guards.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/src/pactkit/id_generator.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/src/pactkit/invariants.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/src/pactkit/issue_sync.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/src/pactkit/lazy_visualize.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/src/pactkit/lessons.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/src/pactkit/lint_runner.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/src/pactkit/observe.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/src/pactkit/profiles.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/src/pactkit/prompts/__init__.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/src/pactkit/prompts/agents.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/src/pactkit/prompts/commands.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/src/pactkit/prompts/references.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/src/pactkit/prompts/rules.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/src/pactkit/prompts/skills.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/src/pactkit/regression.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/src/pactkit/schemas.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/src/pactkit/scripts.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/src/pactkit/sec_scope.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/src/pactkit/skills/__init__.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/src/pactkit/skills/analyzers/__init__.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/src/pactkit/skills/analyzers/go_analyzer.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/src/pactkit/skills/analyzers/java_analyzer.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/src/pactkit/skills/analyzers/python_analyzer.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/src/pactkit/skills/analyzers/ts_analyzer.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/src/pactkit/skills/board.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/src/pactkit/skills/report.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/src/pactkit/skills/scaffold.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/src/pactkit/skills/spec_linter.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/src/pactkit/skills/visualize.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/src/pactkit/spec_status.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/src/pactkit/test_mapper.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/src/pactkit/utils.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/src/pactkit/validators.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/conftest.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/e2e/__init__.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/e2e/cli/__init__.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/e2e/cli/test_cli_e2e.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/fixtures/agent_parser/agents_dir/researcher.yaml +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/fixtures/agent_parser/agents_dir/writer.yaml +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/fixtures/agent_parser/langgraph_app.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/fixtures/agent_parser/mcp_settings.json +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/fixtures/api_call_parser/axios_style.tsx +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/fixtures/api_call_parser/dynamic.tsx +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/fixtures/api_call_parser/page.tsx +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/integration/__init__.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/integration/test_deploy_classic.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_agent_features.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_agent_frontmatter.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_agents_enrichment.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_audit.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_blast_radius.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_board_bug027.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_board_sections.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_bug001_skill_path.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_bug002_plugin_paths.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_bug003_multi_import.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_bug004_dead_set.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_bug005_archive_taskless.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_bug006_scan_excludes.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_bug007_stale_trace_refs.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_bug008_stale_command_refs.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_bug009_project_config_backfill.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_bug010_rewrite_yaml.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_bug011_stale_refs.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_bug012_call_graph_filter.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_bug013_config_single_source.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_bug014_version_hygiene.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_bug017_project_init_playbook.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_bug018_issue_tracker_verification.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_bug019_venv_deployment.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_bug020_claude_md_backup.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_bug025_release_delegation.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_bug026_version_sync.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_bug028_ghost_refs.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_bug029_stack_detection_fallback.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_bug030_spec_lint_cli.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_bug031_docstring_accuracy.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_bug034_plan_metadata_template.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_bug_021.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_bug_022.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_bug_023.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_bug_024.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_bug_slim001_env_detection.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_bug_slim002_instruction_collision.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_bug_slim003.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_bug_slim004.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_bug_slim005.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_bug_slim006.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_bug_slim089_global_claude_md.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_check_command.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_check_extensions_072_073.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_check_playbook_072_073.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_command_frontmatter.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_command_visualize_modes.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_complexity.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_config.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_config_auto_merge.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_constitution_sharpening.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_context_gen.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_create_skill.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_cross_flow_matrix.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_deploy_base.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_deployer_cleanup.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_deployer_plugin.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_design_command.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_done_gates.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_draw_prompt.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_draw_references.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_drawio_mcp.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_garden.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_home_path_fix.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_init_guard.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_init_playbook_074.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_lang_profiles.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_layer_violations.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_lessons_rotation_075.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_list_stories.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_mcp_integration.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_model_config.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_modular_constitution.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_monorepo_detect.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_multi_prefix.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_observe.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_pdca_slim.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_profiles.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_project_visibility.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_prompt_cli_refs.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_prompt_quality_075.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_prompt_structural_invariants.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_prompts_package.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_release.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_release_field.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_release_v110.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_render_prompt.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_report_parser.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_report_unified.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_review_command.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_rules_enrichment.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_scaffold.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_scaffold_developer_prefix.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_schemas.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_script_extraction.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_selective_deploy.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_session_context.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_skill_structure.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_skills_enrichment.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_slim_deps_088.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_smart_regression.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_sprint_command.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_stack_references.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_status_command.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_statusline.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story014_release.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story015_ci_lint_gate.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story016_claude_md.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story017_init_claude_md.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story018_arch_staleness.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story019_bailout.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story020_horizon.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story021_rfc.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story022_decision_tree.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story023_test_quality.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story024_native_agent.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story025_ci_pipeline.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story026_issue_tracker.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story027_hooks.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story028_rule_scoping.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story029_doctor.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story030_lint.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story031_git_init_guard.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story032_greenfield_redirect.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story033_config_backfill.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story034_plan_config_refresh.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story035_readme_docs.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story037_regression_fix.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story038_call_graph_update.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story039_venv_config.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story040_layered_claude_md.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story042_spec_linter.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story043_active_clarify.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story044_consistency_check.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story045_auto_pr.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story046_agent_adapter.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story047_enterprise_flags.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story048_worktree_isolation.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story049_community_standards.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story050_doc_only_shortcut.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story051_workflow_streamlining.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story052_conditional_github_release.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story053_impact_regression.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story055_commands.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story055_config.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story055_spec_linter.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story056_commands.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story056_config.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story057_implicit_cleanup.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story058_opencode_extraction.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story058_routing_fix.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story059_codex_removal.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story060_init_hang.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story061_remove_thinking.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story062_mcp_recommendations.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story064_venv_local_md.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story065_sprint_model.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story072_developer_prefix.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story_slim009_lazy_rules.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story_slim010_dry_refactor.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story_slim011_command_rules.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story_slim012_ci.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story_slim014_context.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story_slim014_guard.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story_slim014_lazy_viz.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story_slim014_next_id.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story_slim014_regression.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story_slim014_sec_scope.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story_slim014_validators.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story_slim015_doctor.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story_slim016_testmap_lint.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story_slim017.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story_slim018.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story_slim019_plan_subphases.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story_slim020_explore_stall_fix.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story_slim021.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story_slim022.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story_slim023.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story_slim024.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story_slim025.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story_slim026.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story_slim027.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story_slim028.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story_slim029.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story_slim030.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story_slim031.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story_slim032.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story_slim033.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story_slim034.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story_slim035.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story_slim036.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story_slim037.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story_slim038.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story_slim039.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story_slim040.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story_slim041.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story_slim042.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story_slim043.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story_slim044.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story_slim045.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story_slim046.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story_slim047.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story_slim048.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story_slim049.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story_slim051.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story_slim052.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story_slim053.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story_slim054.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story_slim055.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story_slim056.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story_slim060_codex_profile.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story_slim063.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story_slim065.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story_slim076_multistack.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story_slim077_monorepo_stack.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story_slim078.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story_slim079.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story_slim080.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story_slim081.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story_slim082.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story_slim083.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story_slim084.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story_slim095.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story_slim098_pdca_nudge.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_story_slim099_act_context_ref.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_tools.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_topology_parsers_066.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_update_task.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_visualize_call_nested.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_visualize_chain_fix.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_visualize_modes.py +0 -0
- {pactkit-2.10.2 → pactkit-2.10.4}/tests/unit/test_visualize_multilang_chain.py +0 -0
|
@@ -4,6 +4,16 @@ 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.10.4] - 2026-04-20
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
- **Hotfix Impact Check** (STORY-slim-100) — `/project-hotfix` now includes Phase 0.5 that reads existing `.mmd` call graph files before fixing. Warns when target function has 3+ callers. Advisory (L3), non-blocking, gracefully skips when no graphs exist.
|
|
11
|
+
|
|
12
|
+
## [2.10.3] - 2026-04-20
|
|
13
|
+
|
|
14
|
+
### Fixed
|
|
15
|
+
- **Protected parent dirs in `pactkit clean`** — `rglob("dist")` was matching `node_modules/*/dist`, destroying npm dependency internals. Added `_inside_protected()` guard for `node_modules/` and `.git/`; explicit path patterns (e.g., `node_modules/.cache`) now use direct matching instead of rglob.
|
|
16
|
+
|
|
7
17
|
## [2.10.2] - 2026-04-20
|
|
8
18
|
|
|
9
19
|
### Added
|
{pactkit-2.10.2 → pactkit-2.10.4}/docs/architecture/governance/archive/lessons_archive_202603.md
RENAMED
|
@@ -46,3 +46,5 @@
|
|
|
46
46
|
| 2026-03-24 | Plan Phase 3.2a scaffold-first: replaced AI freeform Write with {SCAFFOLD_CMD} create_spec + Read + Edit in src/pactkit/prompts/commands.py. Removed 3 inline format examples (~240 chars). Pre-existing tests (test_bug034, test_story055_commands, test_story_slim019) needed updates for new checkpoint wording. | src/pactkit/prompts/commands.py:Phase3.2a |
|
|
47
47
|
| 2026-03-24 | spec_linter.py _check_acceptance_criteria: per-subsection GWT check must use raw_text (with code blocks) not stripped text, because specs legitimately wrap Gherkin in fenced blocks | spec_linter.py:_check_acceptance_criteria |
|
|
48
48
|
| 2026-03-24 | Standalone scripts (visualize.py) need try/except ImportError guards for yaml.safe_load when reading pactkit.yaml — they cannot import from pactkit library | visualize.py:_load_scan_excludes |
|
|
49
|
+
| 2026-03-24 | Inline data in standalone scripts must have canonical-source comments pointing to the library module (e.g. _STACK_MARKERS → cleaners.py, _LANG_FILE_EXT → workflows.py) per Architecture Principle 1 | visualize.py:_STACK_MARKERS |
|
|
50
|
+
| 2026-03-24 | Worktree isolation diverges from working-tree: verify visualize.py _scan_files() signature is preserved across stories to avoid breaking callers | visualize.py:_scan_files |
|
|
@@ -2,8 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
| Date | Lesson | Context |
|
|
4
4
|
|------|--------|---------|
|
|
5
|
-
| 2026-03-24 | Inline data in standalone scripts must have canonical-source comments pointing to the library module (e.g. _STACK_MARKERS → cleaners.py, _LANG_FILE_EXT → workflows.py) per Architecture Principle 1 | visualize.py:_STACK_MARKERS |
|
|
6
|
-
| 2026-03-24 | Worktree isolation diverges from working-tree: verify visualize.py _scan_files() signature is preserved across stories to avoid breaking callers | visualize.py:_scan_files |
|
|
7
5
|
| 2026-03-24 | Extracting _detect_stack() from _detect_file_ext() enables both file discovery and test mapping to share stack detection — DRY refactoring | visualize.py:_detect_stack |
|
|
8
6
|
| 2026-03-24 | Standalone skill scripts using exec() require all imports in _SHARED_HEADER; new stdlib imports (dataclass) must be added to skills/__init__.py _SHARED_HEADER, not just the standalone header section | skills/__init__.py:_SHARED_HEADER |
|
|
9
7
|
| 2026-03-24 | detect_topology() must delegate to _TOPOLOGY_PARSERS parser.detect() first, not _TOPOLOGY_MARKERS alone — parsers and markers can diverge silently causing empty graphs | visualize.py:detect_topology |
|
|
@@ -53,3 +51,5 @@
|
|
|
53
51
|
| 2026-04-17 | Dual-anchor pattern: declare principle in RULES_MODULES['core'] (01-core-protocol.md), detail in dedicated module (11-pdca-nudge.md). Prevents attention dilution when rules/ has 10+ files — Core Protocol acts as behavioral constitution anchor. | src/pactkit/prompts/rules.py:RULES_MODULES |
|
|
54
52
|
| 2026-04-18 | Version comparison guards must use semantic (tuple) comparison, not string equality — string != treats 2.10.1 != 2.5.0 without direction, giving wrong upgrade advice | guards.py:check_version_mismatch |
|
|
55
53
|
| 2026-04-20 | Plugin deployer (_deploy_commands in deployer.py:952-954) uses _rewrite_skills_prefix instead of _render_prompt, keeping raw placeholders like {BOARD_CMD} — not a deploy drift bug but by-design template behavior | src/pactkit/generators/deployer.py:_deploy_commands |
|
|
54
|
+
| 2026-04-20 | pactkit clean rglob patterns must exclude protected parent dirs (node_modules, .git) — recursive pattern matching deletes dependency internals | cleaners.py:_inside_protected |
|
|
55
|
+
| 2026-04-20 | Hotfix playbook lacked data-driven impact awareness — AI-only 'no side effects' checks miss high-fan-in functions. Adding lightweight .mmd graph reads makes the advisory concrete without blocking the fast-fix path. | workflows.py:HOTFIX_PROMPT |
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
|
|
16
16
|
## Invariants
|
|
17
17
|
|
|
18
|
-
1. All
|
|
18
|
+
1. All 3762+ 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`.
|
|
@@ -205,3 +205,10 @@
|
|
|
205
205
|
- [x] Update Shared Protocols Referenced-by line
|
|
206
206
|
- [x] Redeploy via pactkit update
|
|
207
207
|
- [x] Verify deployed plugin sync
|
|
208
|
+
|
|
209
|
+
### [STORY-slim-100] Hotfix impact check via .mmd call graph
|
|
210
|
+
> Spec: docs/specs/STORY-slim-100.md
|
|
211
|
+
|
|
212
|
+
- [x] Add Phase 0.5 Impact Check to HOTFIX_PROMPT
|
|
213
|
+
- [x] Add tests for new phase
|
|
214
|
+
- [x] Deploy verification
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# Project Context (Auto-generated)
|
|
2
|
-
> Last updated: 2026-04-
|
|
2
|
+
> Last updated: 2026-04-20T17:32:07+08:00 by pactkit context
|
|
3
3
|
|
|
4
4
|
## Sprint Status
|
|
5
5
|
Backlog: 0 | In Progress: 0 | Done: 0 stories
|
|
@@ -15,11 +15,11 @@ develop
|
|
|
15
15
|
* main
|
|
16
16
|
|
|
17
17
|
## Key Decisions
|
|
18
|
-
- Weighted hotspot formula (complexity 25% + docstring 15% + smells 15% + layers 10% + test 20% + blast 15%) gives meaningful scores across different project profiles; _generate_suggested_tasks auto-scaffolds BUG/HOTFIX specs with Done-completed filter for idempotency
|
|
19
|
-
- Dual-dimension audit (config+code 50/50) gives accurate project health picture; scanning ~/.claude/ global config catches harness setup invisible at project level
|
|
20
18
|
- Dual-anchor pattern: declare principle in RULES_MODULES['core'] (01-core-protocol.md), detail in dedicated module (11-pdca-nudge.md). Prevents attention dilution when rules/ has 10+ files — Core Protocol acts as behavioral constitution anchor.
|
|
21
19
|
- Version comparison guards must use semantic (tuple) comparison, not string equality — string != treats 2.10.1 != 2.5.0 without direction, giving wrong upgrade advice
|
|
22
20
|
- Plugin deployer (_deploy_commands in deployer.py:952-954) uses _rewrite_skills_prefix instead of _render_prompt, keeping raw placeholders like {BOARD_CMD} — not a deploy drift bug but by-design template behavior
|
|
21
|
+
- pactkit clean rglob patterns must exclude protected parent dirs (node_modules, .git) — recursive pattern matching deletes dependency internals
|
|
22
|
+
- Hotfix playbook lacked data-driven impact awareness — AI-only 'no side effects' checks miss high-fan-in functions. Adding lightweight .mmd graph reads makes the advisory concrete without blocking the fast-fix path.
|
|
23
23
|
|
|
24
24
|
## Next Recommended Action
|
|
25
25
|
`/project-design`
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# STORY-slim-100: Hotfix impact check via .mmd call graph
|
|
2
|
+
|
|
3
|
+
| Field | Value |
|
|
4
|
+
|-------|-------|
|
|
5
|
+
| ID | STORY-slim-100 |
|
|
6
|
+
| Status | Done |
|
|
7
|
+
| Priority | P1 |
|
|
8
|
+
| Release | 2.10.4 |
|
|
9
|
+
|
|
10
|
+
## Background
|
|
11
|
+
|
|
12
|
+
The `/project-hotfix` playbook locates target code via `Grep`/`Glob` (Phase 0) and immediately proceeds to fix (Phase 1) without consulting the project's `.mmd` call graph files. This means "No Side Effects" (Phase 1.3) is enforced purely by AI judgment, not data. In contrast, `/project-act` uses `pactkit-trace` (Phase 1) and `code_graph.mmd` importer counts (Phase 3) to detect high-fan-in functions before modifying them. A hotfix that changes a function with 5+ callers can silently break upstream consumers.
|
|
13
|
+
|
|
14
|
+
## Requirements
|
|
15
|
+
|
|
16
|
+
### R1: Lightweight Impact Check Phase (MUST)
|
|
17
|
+
|
|
18
|
+
Insert a new **Phase 0.5: Impact Check** between Phase 0 (Locate & Register) and Phase 1 (Fix) in the `HOTFIX_PROMPT`. This phase reads existing `.mmd` call graph files (`call_graph.mmd`, `reverse_call_graph.mmd`, or `code_graph.mmd`) to identify callers of the target function/file.
|
|
19
|
+
|
|
20
|
+
### R2: High-Fan-In Warning (SHOULD)
|
|
21
|
+
|
|
22
|
+
If the target function/file has **3+ callers** in the call graph, the playbook SHOULD warn the user about potential impact scope and suggest considering `/project-act` for the full PDCA workflow.
|
|
23
|
+
|
|
24
|
+
### R3: Graceful Degradation (MUST)
|
|
25
|
+
|
|
26
|
+
If `.mmd` files do not exist in `docs/architecture/graphs/`, the impact check MUST skip silently with a log message ("No call graph available — skipping impact check"). This preserves hotfix's lightweight nature for projects without visualize data.
|
|
27
|
+
|
|
28
|
+
### R4: Non-Blocking (MUST)
|
|
29
|
+
|
|
30
|
+
The impact check MUST NOT block the hotfix workflow — it is advisory only (L3 signal). The user can acknowledge the warning and proceed.
|
|
31
|
+
|
|
32
|
+
## Acceptance Criteria
|
|
33
|
+
|
|
34
|
+
### AC1: Impact Check Phase Exists in Prompt (R1)
|
|
35
|
+
|
|
36
|
+
- **Given** the `HOTFIX_PROMPT` string in `workflows.py`
|
|
37
|
+
- **When** the prompt text is inspected
|
|
38
|
+
- **Then** it contains "Phase 0.5" and "Impact Check" and references `.mmd` call graph files
|
|
39
|
+
|
|
40
|
+
### AC2: High-Fan-In Warning Text Present (R2)
|
|
41
|
+
|
|
42
|
+
- **Given** the `HOTFIX_PROMPT` string
|
|
43
|
+
- **When** the prompt text is inspected
|
|
44
|
+
- **Then** it contains a threshold (e.g., "3+ callers") and a suggestion to consider `/project-act`
|
|
45
|
+
|
|
46
|
+
### AC3: Graceful Skip When No Graphs (R3)
|
|
47
|
+
|
|
48
|
+
- **Given** the `HOTFIX_PROMPT` string
|
|
49
|
+
- **When** the prompt text is inspected
|
|
50
|
+
- **Then** it contains instructions to skip silently if `.mmd` files do not exist
|
|
51
|
+
|
|
52
|
+
### AC4: Non-Blocking Advisory Signal (R4)
|
|
53
|
+
|
|
54
|
+
- **Given** the `HOTFIX_PROMPT` string
|
|
55
|
+
- **When** the prompt text is inspected
|
|
56
|
+
- **Then** the impact check is described as advisory (not a gate), and the phase does not use "MUST STOP" or blocking language
|
|
57
|
+
|
|
58
|
+
## Target Call Chain
|
|
59
|
+
|
|
60
|
+
`HOTFIX_PROMPT` (workflows.py:543) → imported by `commands.py:3` → registered in `COMMANDS_CONTENT["project-hotfix.md"]` (commands.py:750) → deployed by `deployer.py` via `_render_prompt()` → output to `pactkit-plugin/commands/project-hotfix.md` and `.github/prompts/project-hotfix.prompt.md`
|
|
61
|
+
|
|
62
|
+
## Implementation Steps
|
|
63
|
+
|
|
64
|
+
| Step | File | Action | Dependencies | Risk |
|
|
65
|
+
|------|------|--------|-------------|------|
|
|
66
|
+
| 1 | `src/pactkit/prompts/workflows.py` | Add Phase 0.5 Impact Check text to `HOTFIX_PROMPT` between Phase 0 and Phase 1 | None | Low |
|
|
67
|
+
| 2 | `tests/unit/test_hotfix_command.py` | Add test class verifying Phase 0.5 keywords exist in prompt | Step 1 | Low |
|
|
68
|
+
| 3 | Deploy verification | Run `pactkit deploy` and verify `pactkit-plugin/commands/project-hotfix.md` contains the new phase | Step 1 | Low |
|
|
69
|
+
|
|
70
|
+
## Security Scope
|
|
71
|
+
|
|
72
|
+
| Check | Applicable | Reason |
|
|
73
|
+
|-------|------------|--------|
|
|
74
|
+
| SEC-1 | N/A | Prompt text only, no executable injection surface |
|
|
75
|
+
| SEC-2 | N/A | No user input processing — playbook instruction text |
|
|
76
|
+
| SEC-3 | N/A | No database patterns |
|
|
77
|
+
| SEC-4 | N/A | No frontend files |
|
|
78
|
+
| SEC-5 | N/A | No auth/session handling — false positive on keyword match |
|
|
79
|
+
| SEC-6 | N/A | No API/route files |
|
|
80
|
+
| SEC-7 | N/A | No error handling patterns |
|
|
81
|
+
| SEC-8 | N/A | No dependency manifests |
|
|
82
|
+
|
|
83
|
+
## Out of Scope
|
|
84
|
+
|
|
85
|
+
- Full `pactkit-trace` integration (too heavy for hotfix; Act already handles it)
|
|
86
|
+
- Updating `code_graph.mmd` or `call_graph.mmd` during hotfix (hotfix is read-only on graphs)
|
|
87
|
+
- Blocking hotfix workflow based on impact check results
|
|
@@ -15,6 +15,9 @@ _CLEANUP_PATTERNS: dict[str, list[str]] = {
|
|
|
15
15
|
"java": ["target/", "build/", ".gradle/"],
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
+
# Directories whose contents must never be cleaned by rglob patterns
|
|
19
|
+
_PROTECTED_PARENTS = {"node_modules", ".git"}
|
|
20
|
+
|
|
18
21
|
# Stack detection markers (ordered by priority)
|
|
19
22
|
_STACK_MARKERS: list[tuple[str, str]] = [
|
|
20
23
|
("pyproject.toml", "python"),
|
|
@@ -27,6 +30,12 @@ _STACK_MARKERS: list[tuple[str, str]] = [
|
|
|
27
30
|
]
|
|
28
31
|
|
|
29
32
|
|
|
33
|
+
def _inside_protected(path: Path, project_root: Path) -> bool:
|
|
34
|
+
"""Return True if path is inside a protected parent directory."""
|
|
35
|
+
rel = path.relative_to(project_root)
|
|
36
|
+
return bool(_PROTECTED_PARENTS & set(rel.parts[:-1]))
|
|
37
|
+
|
|
38
|
+
|
|
30
39
|
def detect_stacks(project_root: Path) -> list[str]:
|
|
31
40
|
"""Detect all project stacks from marker files.
|
|
32
41
|
|
|
@@ -84,9 +93,21 @@ def clean_artifacts(
|
|
|
84
93
|
removed: list[Path] = []
|
|
85
94
|
|
|
86
95
|
for pattern in patterns:
|
|
87
|
-
if "
|
|
96
|
+
if "/" in pattern:
|
|
97
|
+
# Explicit path (e.g., "node_modules/.cache") — match directly
|
|
98
|
+
target = project_root / pattern
|
|
99
|
+
if target.exists():
|
|
100
|
+
removed.append(target)
|
|
101
|
+
if not dry_run:
|
|
102
|
+
if target.is_dir():
|
|
103
|
+
shutil.rmtree(target)
|
|
104
|
+
else:
|
|
105
|
+
target.unlink()
|
|
106
|
+
elif "*" in pattern:
|
|
88
107
|
# Glob pattern (e.g., "*.pyc")
|
|
89
108
|
for match in project_root.rglob(pattern):
|
|
109
|
+
if _inside_protected(match, project_root):
|
|
110
|
+
continue
|
|
90
111
|
removed.append(match)
|
|
91
112
|
if not dry_run:
|
|
92
113
|
if match.is_dir():
|
|
@@ -94,9 +115,11 @@ def clean_artifacts(
|
|
|
94
115
|
else:
|
|
95
116
|
match.unlink()
|
|
96
117
|
else:
|
|
97
|
-
# Directory or file name (e.g., "__pycache__", "
|
|
118
|
+
# Directory or file name (e.g., "__pycache__", "dist")
|
|
98
119
|
clean_name = pattern.rstrip("/")
|
|
99
120
|
for match in project_root.rglob(clean_name):
|
|
121
|
+
if _inside_protected(match, project_root):
|
|
122
|
+
continue
|
|
100
123
|
removed.append(match)
|
|
101
124
|
if not dry_run:
|
|
102
125
|
if match.is_dir():
|
|
@@ -573,6 +573,16 @@ allowed-tools: [Read, Write, Edit, Bash, Glob, Grep]
|
|
|
573
573
|
6. **Add Board Entry**: Add the hotfix to the Board:
|
|
574
574
|
- `{BOARD_CMD} add_story HOTFIX-{NNN} "Short title" "Fix description"`
|
|
575
575
|
|
|
576
|
+
## 🔍 Phase 0.5: Impact Check (Lightweight)
|
|
577
|
+
> **PURPOSE**: Data-driven side-effect awareness — read existing call graphs to surface upstream callers before modifying code. This is advisory (L3 SHOULD), non-blocking.
|
|
578
|
+
1. **Check Graph Availability**: Look for `docs/architecture/graphs/call_graph.mmd` or `docs/architecture/graphs/reverse_call_graph.mmd` or `docs/architecture/graphs/code_graph.mmd`.
|
|
579
|
+
- If none exist: log "No call graph available — skipping impact check" and proceed to Phase 1.
|
|
580
|
+
2. **Identify Callers**: Search the available `.mmd` file for the target function/file identified in Phase 0. Count how many other nodes reference it (callers/importers).
|
|
581
|
+
3. **High-Fan-In Warning**: If the target has **3+ callers**, SHOULD warn the user:
|
|
582
|
+
> "⚠️ Target has {N} callers in the call graph. Changes may affect upstream consumers. Consider `/project-act` for full impact analysis."
|
|
583
|
+
- This warning is advisory — the user can acknowledge and proceed.
|
|
584
|
+
4. **Proceed**: Continue to Phase 1 regardless of findings.
|
|
585
|
+
|
|
576
586
|
## 🔧 Phase 1: Fix
|
|
577
587
|
1. **Fix**: Use `Edit` or `Write` to directly fix the target code.
|
|
578
588
|
2. **Scope**: Keep the modification scope as small as possible — only change what must be changed, no extra optimization or refactoring.
|
|
@@ -138,6 +138,43 @@ class TestBackwardCompatibility:
|
|
|
138
138
|
assert agent in p.AGENTS_EXPERT, f"Missing agent {agent}"
|
|
139
139
|
|
|
140
140
|
|
|
141
|
+
class TestImpactCheckPhase:
|
|
142
|
+
"""Scenario 8: Phase 0.5 Impact Check exists (STORY-slim-100)"""
|
|
143
|
+
|
|
144
|
+
def test_has_phase_05(self):
|
|
145
|
+
p = _prompts()
|
|
146
|
+
assert 'Phase 0.5' in p.HOTFIX_PROMPT
|
|
147
|
+
|
|
148
|
+
def test_has_impact_check_title(self):
|
|
149
|
+
p = _prompts()
|
|
150
|
+
assert 'Impact Check' in p.HOTFIX_PROMPT
|
|
151
|
+
|
|
152
|
+
def test_references_mmd_files(self):
|
|
153
|
+
p = _prompts()
|
|
154
|
+
text = p.HOTFIX_PROMPT
|
|
155
|
+
assert 'call_graph.mmd' in text or 'reverse_call_graph.mmd' in text or 'code_graph.mmd' in text
|
|
156
|
+
|
|
157
|
+
def test_has_fan_in_threshold(self):
|
|
158
|
+
p = _prompts()
|
|
159
|
+
assert '3+' in p.HOTFIX_PROMPT or '3 or more' in p.HOTFIX_PROMPT
|
|
160
|
+
|
|
161
|
+
def test_suggests_project_act(self):
|
|
162
|
+
p = _prompts()
|
|
163
|
+
assert '/project-act' in p.HOTFIX_PROMPT
|
|
164
|
+
|
|
165
|
+
def test_graceful_skip_when_no_graphs(self):
|
|
166
|
+
p = _prompts()
|
|
167
|
+
text = p.HOTFIX_PROMPT.lower()
|
|
168
|
+
assert 'skip' in text and ('no call graph' in text or 'do not exist' in text or 'not exist' in text)
|
|
169
|
+
|
|
170
|
+
def test_non_blocking_advisory(self):
|
|
171
|
+
"""Impact check must not use blocking language."""
|
|
172
|
+
p = _prompts()
|
|
173
|
+
text = p.HOTFIX_PROMPT
|
|
174
|
+
assert 'MUST STOP' not in text or text.index('Phase 0.5') > text.index('MUST STOP')
|
|
175
|
+
assert 'advisory' in text.lower() or 'non-blocking' in text.lower() or 'SHOULD' in text
|
|
176
|
+
|
|
177
|
+
|
|
141
178
|
class TestDeployment:
|
|
142
179
|
"""Scenario 7: 部署后文件存在"""
|
|
143
180
|
|
|
@@ -203,7 +203,8 @@ class TestAC6DevRefGhostResolved:
|
|
|
203
203
|
# STORY-slim-072/073: bumped +2489 for Check Phase 4.5/4.7 (PactGuard + Observe)
|
|
204
204
|
# STORY-slim-091: bumped +248 for Done Phase 3.8 harness audit refresh
|
|
205
205
|
# audit --if-needed in Done playbook
|
|
206
|
-
|
|
206
|
+
# STORY-slim-100: bumped +1212 for Hotfix Phase 0.5 Impact Check
|
|
207
|
+
BASELINE_TOTAL_CHARS = 80355
|
|
207
208
|
|
|
208
209
|
|
|
209
210
|
class TestAC7PromptSizeReduced:
|
|
@@ -87,3 +87,47 @@ class TestCleanArtifacts:
|
|
|
87
87
|
|
|
88
88
|
removed = clean_artifacts(tmp_path, stack="auto")
|
|
89
89
|
assert len(removed) >= 1
|
|
90
|
+
|
|
91
|
+
def test_clean_node_skips_dist_inside_node_modules(self, tmp_path):
|
|
92
|
+
"""dist inside node_modules must NOT be deleted."""
|
|
93
|
+
(tmp_path / "package.json").write_text("{}")
|
|
94
|
+
# Create a dependency with dist/
|
|
95
|
+
dep_dist = tmp_path / "node_modules" / "some-pkg" / "dist"
|
|
96
|
+
dep_dist.mkdir(parents=True)
|
|
97
|
+
(dep_dist / "index.js").write_text("module.exports = {}")
|
|
98
|
+
# Create a project-level dist/ that SHOULD be cleaned
|
|
99
|
+
proj_dist = tmp_path / "dist"
|
|
100
|
+
proj_dist.mkdir()
|
|
101
|
+
(proj_dist / "bundle.js").write_text("")
|
|
102
|
+
|
|
103
|
+
removed = clean_artifacts(tmp_path, stack="node")
|
|
104
|
+
assert proj_dist not in list(tmp_path.iterdir())
|
|
105
|
+
assert dep_dist.exists(), "node_modules/*/dist must survive clean"
|
|
106
|
+
|
|
107
|
+
def test_clean_node_modules_cache_still_cleaned(self, tmp_path):
|
|
108
|
+
"""node_modules/.cache is explicitly targeted and should be cleaned."""
|
|
109
|
+
(tmp_path / "package.json").write_text("{}")
|
|
110
|
+
nm_cache = tmp_path / "node_modules" / ".cache"
|
|
111
|
+
nm_cache.mkdir(parents=True)
|
|
112
|
+
(nm_cache / "babel").mkdir()
|
|
113
|
+
(nm_cache / "babel" / "data.json").write_text("{}")
|
|
114
|
+
|
|
115
|
+
removed = clean_artifacts(tmp_path, stack="node")
|
|
116
|
+
assert any("node_modules/.cache" in str(p) for p in removed)
|
|
117
|
+
assert not nm_cache.exists()
|
|
118
|
+
|
|
119
|
+
def test_clean_skips_pyc_inside_node_modules(self, tmp_path):
|
|
120
|
+
"""Glob patterns (*.pyc) must not match inside node_modules."""
|
|
121
|
+
(tmp_path / "pyproject.toml").write_text("[project]")
|
|
122
|
+
# A .pyc in node_modules (unlikely but possible in hybrid projects)
|
|
123
|
+
nm_pyc = tmp_path / "node_modules" / "weird" / "file.pyc"
|
|
124
|
+
nm_pyc.parent.mkdir(parents=True)
|
|
125
|
+
nm_pyc.write_text("")
|
|
126
|
+
# A normal .pyc that should be cleaned
|
|
127
|
+
normal_pyc = tmp_path / "src" / "mod.pyc"
|
|
128
|
+
normal_pyc.parent.mkdir(parents=True)
|
|
129
|
+
normal_pyc.write_text("")
|
|
130
|
+
|
|
131
|
+
removed = clean_artifacts(tmp_path, stack="python")
|
|
132
|
+
assert not normal_pyc.exists(), "src/*.pyc should be cleaned"
|
|
133
|
+
assert nm_pyc.exists(), "node_modules/**/*.pyc must survive clean"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pactkit-2.10.2 → pactkit-2.10.4}/docs/architecture/governance/archive/lessons_archive_202602.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|