pactkit 2.7.0__tar.gz → 2.8.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.
Files changed (315) hide show
  1. {pactkit-2.7.0 → pactkit-2.8.0}/.github/workflows/publish.yml +2 -2
  2. {pactkit-2.7.0 → pactkit-2.8.0}/.opencode/pactkit.yaml +4 -4
  3. {pactkit-2.7.0 → pactkit-2.8.0}/CHANGELOG.md +17 -0
  4. {pactkit-2.7.0 → pactkit-2.8.0}/PKG-INFO +3 -2
  5. {pactkit-2.7.0 → pactkit-2.8.0}/pyproject.toml +3 -2
  6. {pactkit-2.7.0 → pactkit-2.8.0}/src/pactkit/__init__.py +1 -1
  7. {pactkit-2.7.0 → pactkit-2.8.0}/src/pactkit/config.py +5 -27
  8. {pactkit-2.7.0 → pactkit-2.8.0}/src/pactkit/doctor.py +28 -25
  9. {pactkit-2.7.0 → pactkit-2.8.0}/src/pactkit/generators/deployer.py +4 -4
  10. {pactkit-2.7.0 → pactkit-2.8.0}/src/pactkit/prompts/commands.py +15 -4
  11. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_bug013_config_single_source.py +4 -4
  12. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_config.py +7 -3
  13. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_config_auto_merge.py +6 -7
  14. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_selective_deploy.py +1 -1
  15. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story033_config_backfill.py +3 -3
  16. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story063_prompt_slimming.py +2 -1
  17. {pactkit-2.7.0 → pactkit-2.8.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  18. {pactkit-2.7.0 → pactkit-2.8.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  19. {pactkit-2.7.0 → pactkit-2.8.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  20. {pactkit-2.7.0 → pactkit-2.8.0}/.github/dependabot.yml +0 -0
  21. {pactkit-2.7.0 → pactkit-2.8.0}/.github/workflows/ci.yml +0 -0
  22. {pactkit-2.7.0 → pactkit-2.8.0}/.github/workflows/pactkit.yml +0 -0
  23. {pactkit-2.7.0 → pactkit-2.8.0}/.gitignore +0 -0
  24. {pactkit-2.7.0 → pactkit-2.8.0}/AGENTS.md +0 -0
  25. {pactkit-2.7.0 → pactkit-2.8.0}/CODE_OF_CONDUCT.md +0 -0
  26. {pactkit-2.7.0 → pactkit-2.8.0}/CONTRIBUTING.md +0 -0
  27. {pactkit-2.7.0 → pactkit-2.8.0}/LICENSE +0 -0
  28. {pactkit-2.7.0 → pactkit-2.8.0}/README.md +0 -0
  29. {pactkit-2.7.0 → pactkit-2.8.0}/SECURITY.md +0 -0
  30. {pactkit-2.7.0 → pactkit-2.8.0}/docs/assets/logo.png +0 -0
  31. {pactkit-2.7.0 → pactkit-2.8.0}/docs/guides/codex-integration-preresearch.md +0 -0
  32. {pactkit-2.7.0 → pactkit-2.8.0}/docs/guides/tool-integration-checklist.md +0 -0
  33. {pactkit-2.7.0 → pactkit-2.8.0}/docs/specs/BUG-001.md +0 -0
  34. {pactkit-2.7.0 → pactkit-2.8.0}/docs/specs/BUG-002.md +0 -0
  35. {pactkit-2.7.0 → pactkit-2.8.0}/docs/specs/BUG-003.md +0 -0
  36. {pactkit-2.7.0 → pactkit-2.8.0}/docs/specs/BUG-004.md +0 -0
  37. {pactkit-2.7.0 → pactkit-2.8.0}/docs/specs/BUG-005.md +0 -0
  38. {pactkit-2.7.0 → pactkit-2.8.0}/docs/specs/BUG-006.md +0 -0
  39. {pactkit-2.7.0 → pactkit-2.8.0}/docs/specs/BUG-007.md +0 -0
  40. {pactkit-2.7.0 → pactkit-2.8.0}/docs/specs/BUG-008.md +0 -0
  41. {pactkit-2.7.0 → pactkit-2.8.0}/docs/specs/BUG-009.md +0 -0
  42. {pactkit-2.7.0 → pactkit-2.8.0}/docs/specs/BUG-010.md +0 -0
  43. {pactkit-2.7.0 → pactkit-2.8.0}/docs/specs/BUG-011.md +0 -0
  44. {pactkit-2.7.0 → pactkit-2.8.0}/docs/specs/BUG-012.md +0 -0
  45. {pactkit-2.7.0 → pactkit-2.8.0}/docs/specs/BUG-013.md +0 -0
  46. {pactkit-2.7.0 → pactkit-2.8.0}/docs/specs/BUG-014.md +0 -0
  47. {pactkit-2.7.0 → pactkit-2.8.0}/docs/specs/BUG-015.md +0 -0
  48. {pactkit-2.7.0 → pactkit-2.8.0}/docs/specs/BUG-016.md +0 -0
  49. {pactkit-2.7.0 → pactkit-2.8.0}/docs/specs/BUG-017.md +0 -0
  50. {pactkit-2.7.0 → pactkit-2.8.0}/docs/specs/BUG-018.md +0 -0
  51. {pactkit-2.7.0 → pactkit-2.8.0}/docs/specs/BUG-019.md +0 -0
  52. {pactkit-2.7.0 → pactkit-2.8.0}/docs/specs/BUG-020.md +0 -0
  53. {pactkit-2.7.0 → pactkit-2.8.0}/docs/specs/BUG-021.md +0 -0
  54. {pactkit-2.7.0 → pactkit-2.8.0}/docs/specs/BUG-022.md +0 -0
  55. {pactkit-2.7.0 → pactkit-2.8.0}/docs/specs/BUG-023.md +0 -0
  56. {pactkit-2.7.0 → pactkit-2.8.0}/docs/specs/BUG-024.md +0 -0
  57. {pactkit-2.7.0 → pactkit-2.8.0}/docs/specs/BUG-025.md +0 -0
  58. {pactkit-2.7.0 → pactkit-2.8.0}/docs/specs/BUG-026.md +0 -0
  59. {pactkit-2.7.0 → pactkit-2.8.0}/docs/specs/BUG-027.md +0 -0
  60. {pactkit-2.7.0 → pactkit-2.8.0}/docs/specs/BUG-028.md +0 -0
  61. {pactkit-2.7.0 → pactkit-2.8.0}/docs/specs/BUG-029.md +0 -0
  62. {pactkit-2.7.0 → pactkit-2.8.0}/docs/specs/BUG-030.md +0 -0
  63. {pactkit-2.7.0 → pactkit-2.8.0}/docs/specs/BUG-031.md +0 -0
  64. {pactkit-2.7.0 → pactkit-2.8.0}/docs/specs/BUG-032.md +0 -0
  65. {pactkit-2.7.0 → pactkit-2.8.0}/docs/specs/BUG-033.md +0 -0
  66. {pactkit-2.7.0 → pactkit-2.8.0}/docs/specs/BUG-034.md +0 -0
  67. {pactkit-2.7.0 → pactkit-2.8.0}/docs/specs/BUG-035.md +0 -0
  68. {pactkit-2.7.0 → pactkit-2.8.0}/docs/specs/BUG-slim-001.md +0 -0
  69. {pactkit-2.7.0 → pactkit-2.8.0}/docs/specs/BUG-slim-002.md +0 -0
  70. {pactkit-2.7.0 → pactkit-2.8.0}/docs/specs/BUG-slim-003.md +0 -0
  71. {pactkit-2.7.0 → pactkit-2.8.0}/docs/specs/BUG-slim-004.md +0 -0
  72. {pactkit-2.7.0 → pactkit-2.8.0}/docs/specs/BUG-slim-005.md +0 -0
  73. {pactkit-2.7.0 → pactkit-2.8.0}/docs/specs/BUG-slim-006.md +0 -0
  74. {pactkit-2.7.0 → pactkit-2.8.0}/docs/specs/BUG-slim-007.md +0 -0
  75. {pactkit-2.7.0 → pactkit-2.8.0}/docs/test_cases/BUG-001_case.md +0 -0
  76. {pactkit-2.7.0 → pactkit-2.8.0}/docs/test_cases/BUG-002_case.md +0 -0
  77. {pactkit-2.7.0 → pactkit-2.8.0}/opencode.json +0 -0
  78. {pactkit-2.7.0 → pactkit-2.8.0}/src/pactkit/__main__.py +0 -0
  79. {pactkit-2.7.0 → pactkit-2.8.0}/src/pactkit/backfill.py +0 -0
  80. {pactkit-2.7.0 → pactkit-2.8.0}/src/pactkit/cleaners.py +0 -0
  81. {pactkit-2.7.0 → pactkit-2.8.0}/src/pactkit/cli.py +0 -0
  82. {pactkit-2.7.0 → pactkit-2.8.0}/src/pactkit/context_gen.py +0 -0
  83. {pactkit-2.7.0 → pactkit-2.8.0}/src/pactkit/coverage_gate.py +0 -0
  84. {pactkit-2.7.0 → pactkit-2.8.0}/src/pactkit/generators/__init__.py +0 -0
  85. {pactkit-2.7.0 → pactkit-2.8.0}/src/pactkit/generators/adapter.py +0 -0
  86. {pactkit-2.7.0 → pactkit-2.8.0}/src/pactkit/generators/deploy_base.py +0 -0
  87. {pactkit-2.7.0 → pactkit-2.8.0}/src/pactkit/guards.py +0 -0
  88. {pactkit-2.7.0 → pactkit-2.8.0}/src/pactkit/id_generator.py +0 -0
  89. {pactkit-2.7.0 → pactkit-2.8.0}/src/pactkit/invariants.py +0 -0
  90. {pactkit-2.7.0 → pactkit-2.8.0}/src/pactkit/issue_sync.py +0 -0
  91. {pactkit-2.7.0 → pactkit-2.8.0}/src/pactkit/lazy_visualize.py +0 -0
  92. {pactkit-2.7.0 → pactkit-2.8.0}/src/pactkit/lessons.py +0 -0
  93. {pactkit-2.7.0 → pactkit-2.8.0}/src/pactkit/lint_runner.py +0 -0
  94. {pactkit-2.7.0 → pactkit-2.8.0}/src/pactkit/profiles.py +0 -0
  95. {pactkit-2.7.0 → pactkit-2.8.0}/src/pactkit/prompts/__init__.py +0 -0
  96. {pactkit-2.7.0 → pactkit-2.8.0}/src/pactkit/prompts/agents.py +0 -0
  97. {pactkit-2.7.0 → pactkit-2.8.0}/src/pactkit/prompts/references.py +0 -0
  98. {pactkit-2.7.0 → pactkit-2.8.0}/src/pactkit/prompts/rules.py +0 -0
  99. {pactkit-2.7.0 → pactkit-2.8.0}/src/pactkit/prompts/skills.py +0 -0
  100. {pactkit-2.7.0 → pactkit-2.8.0}/src/pactkit/prompts/workflows.py +0 -0
  101. {pactkit-2.7.0 → pactkit-2.8.0}/src/pactkit/regression.py +0 -0
  102. {pactkit-2.7.0 → pactkit-2.8.0}/src/pactkit/schemas.py +0 -0
  103. {pactkit-2.7.0 → pactkit-2.8.0}/src/pactkit/scripts.py +0 -0
  104. {pactkit-2.7.0 → pactkit-2.8.0}/src/pactkit/sec_scope.py +0 -0
  105. {pactkit-2.7.0 → pactkit-2.8.0}/src/pactkit/skills/__init__.py +0 -0
  106. {pactkit-2.7.0 → pactkit-2.8.0}/src/pactkit/skills/board.py +0 -0
  107. {pactkit-2.7.0 → pactkit-2.8.0}/src/pactkit/skills/scaffold.py +0 -0
  108. {pactkit-2.7.0 → pactkit-2.8.0}/src/pactkit/skills/spec_linter.py +0 -0
  109. {pactkit-2.7.0 → pactkit-2.8.0}/src/pactkit/skills/visualize.py +0 -0
  110. {pactkit-2.7.0 → pactkit-2.8.0}/src/pactkit/spec_status.py +0 -0
  111. {pactkit-2.7.0 → pactkit-2.8.0}/src/pactkit/test_mapper.py +0 -0
  112. {pactkit-2.7.0 → pactkit-2.8.0}/src/pactkit/utils.py +0 -0
  113. {pactkit-2.7.0 → pactkit-2.8.0}/src/pactkit/validators.py +0 -0
  114. {pactkit-2.7.0 → pactkit-2.8.0}/tests/conftest.py +0 -0
  115. {pactkit-2.7.0 → pactkit-2.8.0}/tests/e2e/__init__.py +0 -0
  116. {pactkit-2.7.0 → pactkit-2.8.0}/tests/e2e/cli/__init__.py +0 -0
  117. {pactkit-2.7.0 → pactkit-2.8.0}/tests/e2e/cli/test_cli_e2e.py +0 -0
  118. {pactkit-2.7.0 → pactkit-2.8.0}/tests/integration/__init__.py +0 -0
  119. {pactkit-2.7.0 → pactkit-2.8.0}/tests/integration/test_deploy_classic.py +0 -0
  120. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_agent_features.py +0 -0
  121. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_agent_frontmatter.py +0 -0
  122. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_agents_enrichment.py +0 -0
  123. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_board_bug027.py +0 -0
  124. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_board_sections.py +0 -0
  125. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_bug001_skill_path.py +0 -0
  126. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_bug002_plugin_paths.py +0 -0
  127. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_bug003_multi_import.py +0 -0
  128. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_bug004_dead_set.py +0 -0
  129. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_bug005_archive_taskless.py +0 -0
  130. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_bug006_scan_excludes.py +0 -0
  131. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_bug007_stale_trace_refs.py +0 -0
  132. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_bug008_stale_command_refs.py +0 -0
  133. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_bug009_project_config_backfill.py +0 -0
  134. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_bug010_rewrite_yaml.py +0 -0
  135. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_bug011_stale_refs.py +0 -0
  136. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_bug012_call_graph_filter.py +0 -0
  137. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_bug014_version_hygiene.py +0 -0
  138. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_bug017_project_init_playbook.py +0 -0
  139. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_bug018_issue_tracker_verification.py +0 -0
  140. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_bug019_venv_deployment.py +0 -0
  141. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_bug020_claude_md_backup.py +0 -0
  142. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_bug025_release_delegation.py +0 -0
  143. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_bug026_version_sync.py +0 -0
  144. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_bug028_ghost_refs.py +0 -0
  145. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_bug029_stack_detection_fallback.py +0 -0
  146. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_bug030_spec_lint_cli.py +0 -0
  147. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_bug031_docstring_accuracy.py +0 -0
  148. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_bug034_plan_metadata_template.py +0 -0
  149. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_bug_021.py +0 -0
  150. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_bug_022.py +0 -0
  151. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_bug_023.py +0 -0
  152. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_bug_024.py +0 -0
  153. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_bug_slim001_env_detection.py +0 -0
  154. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_bug_slim002_instruction_collision.py +0 -0
  155. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_bug_slim003.py +0 -0
  156. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_bug_slim004.py +0 -0
  157. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_bug_slim005.py +0 -0
  158. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_bug_slim006.py +0 -0
  159. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_check_command.py +0 -0
  160. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_command_frontmatter.py +0 -0
  161. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_command_visualize_modes.py +0 -0
  162. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_constitution_sharpening.py +0 -0
  163. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_create_skill.py +0 -0
  164. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_cross_flow_matrix.py +0 -0
  165. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_deploy_base.py +0 -0
  166. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_deployer_cleanup.py +0 -0
  167. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_deployer_plugin.py +0 -0
  168. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_design_command.py +0 -0
  169. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_done_gates.py +0 -0
  170. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_draw_prompt.py +0 -0
  171. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_draw_references.py +0 -0
  172. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_drawio_mcp.py +0 -0
  173. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_home_path_fix.py +0 -0
  174. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_hotfix_command.py +0 -0
  175. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_init_guard.py +0 -0
  176. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_lang_profiles.py +0 -0
  177. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_list_stories.py +0 -0
  178. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_mcp_integration.py +0 -0
  179. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_model_config.py +0 -0
  180. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_modular_constitution.py +0 -0
  181. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_multi_prefix.py +0 -0
  182. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_pdca_slim.py +0 -0
  183. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_profiles.py +0 -0
  184. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_project_visibility.py +0 -0
  185. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_prompt_cli_refs.py +0 -0
  186. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_prompt_structural_invariants.py +0 -0
  187. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_prompts_package.py +0 -0
  188. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_release.py +0 -0
  189. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_release_field.py +0 -0
  190. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_release_v110.py +0 -0
  191. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_render_prompt.py +0 -0
  192. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_review_command.py +0 -0
  193. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_rules_enrichment.py +0 -0
  194. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_scaffold.py +0 -0
  195. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_scaffold_developer_prefix.py +0 -0
  196. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_schemas.py +0 -0
  197. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_script_extraction.py +0 -0
  198. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_session_context.py +0 -0
  199. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_skill_structure.py +0 -0
  200. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_skills_enrichment.py +0 -0
  201. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_smart_regression.py +0 -0
  202. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_sprint_command.py +0 -0
  203. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_stack_references.py +0 -0
  204. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_status_command.py +0 -0
  205. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_statusline.py +0 -0
  206. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story014_release.py +0 -0
  207. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story015_ci_lint_gate.py +0 -0
  208. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story016_claude_md.py +0 -0
  209. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story017_init_claude_md.py +0 -0
  210. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story018_arch_staleness.py +0 -0
  211. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story019_bailout.py +0 -0
  212. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story020_horizon.py +0 -0
  213. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story021_rfc.py +0 -0
  214. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story022_decision_tree.py +0 -0
  215. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story023_test_quality.py +0 -0
  216. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story024_native_agent.py +0 -0
  217. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story025_ci_pipeline.py +0 -0
  218. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story026_issue_tracker.py +0 -0
  219. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story027_hooks.py +0 -0
  220. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story028_rule_scoping.py +0 -0
  221. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story029_doctor.py +0 -0
  222. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story030_lint.py +0 -0
  223. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story031_git_init_guard.py +0 -0
  224. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story032_greenfield_redirect.py +0 -0
  225. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story034_plan_config_refresh.py +0 -0
  226. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story035_readme_docs.py +0 -0
  227. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story037_regression_fix.py +0 -0
  228. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story038_call_graph_update.py +0 -0
  229. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story039_venv_config.py +0 -0
  230. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story040_layered_claude_md.py +0 -0
  231. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story042_spec_linter.py +0 -0
  232. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story043_active_clarify.py +0 -0
  233. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story044_consistency_check.py +0 -0
  234. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story045_auto_pr.py +0 -0
  235. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story046_agent_adapter.py +0 -0
  236. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story047_enterprise_flags.py +0 -0
  237. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story048_worktree_isolation.py +0 -0
  238. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story049_community_standards.py +0 -0
  239. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story050_doc_only_shortcut.py +0 -0
  240. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story051_workflow_streamlining.py +0 -0
  241. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story052_conditional_github_release.py +0 -0
  242. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story053_impact_regression.py +0 -0
  243. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story055_commands.py +0 -0
  244. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story055_config.py +0 -0
  245. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story055_spec_linter.py +0 -0
  246. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story056_commands.py +0 -0
  247. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story056_config.py +0 -0
  248. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story057_implicit_cleanup.py +0 -0
  249. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story058_opencode_extraction.py +0 -0
  250. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story058_routing_fix.py +0 -0
  251. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story059_codex_removal.py +0 -0
  252. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story060_init_hang.py +0 -0
  253. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story061_remove_thinking.py +0 -0
  254. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story062_mcp_recommendations.py +0 -0
  255. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story064_venv_local_md.py +0 -0
  256. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story065_sprint_model.py +0 -0
  257. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story072_developer_prefix.py +0 -0
  258. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story_slim009_lazy_rules.py +0 -0
  259. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story_slim010_dry_refactor.py +0 -0
  260. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story_slim011_command_rules.py +0 -0
  261. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story_slim012_ci.py +0 -0
  262. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story_slim014_clean.py +0 -0
  263. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story_slim014_context.py +0 -0
  264. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story_slim014_guard.py +0 -0
  265. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story_slim014_lazy_viz.py +0 -0
  266. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story_slim014_next_id.py +0 -0
  267. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story_slim014_regression.py +0 -0
  268. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story_slim014_sec_scope.py +0 -0
  269. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story_slim014_validators.py +0 -0
  270. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story_slim015_doctor.py +0 -0
  271. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story_slim016_testmap_lint.py +0 -0
  272. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story_slim017.py +0 -0
  273. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story_slim018.py +0 -0
  274. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story_slim019_plan_subphases.py +0 -0
  275. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story_slim020_explore_stall_fix.py +0 -0
  276. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story_slim021.py +0 -0
  277. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story_slim022.py +0 -0
  278. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story_slim023.py +0 -0
  279. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story_slim024.py +0 -0
  280. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story_slim025.py +0 -0
  281. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story_slim026.py +0 -0
  282. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story_slim027.py +0 -0
  283. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story_slim028.py +0 -0
  284. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story_slim029.py +0 -0
  285. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story_slim030.py +0 -0
  286. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story_slim031.py +0 -0
  287. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story_slim032.py +0 -0
  288. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story_slim033.py +0 -0
  289. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story_slim034.py +0 -0
  290. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story_slim035.py +0 -0
  291. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story_slim036.py +0 -0
  292. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story_slim037.py +0 -0
  293. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story_slim038.py +0 -0
  294. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story_slim039.py +0 -0
  295. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story_slim040.py +0 -0
  296. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story_slim041.py +0 -0
  297. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story_slim042.py +0 -0
  298. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story_slim043.py +0 -0
  299. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story_slim044.py +0 -0
  300. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story_slim045.py +0 -0
  301. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story_slim046.py +0 -0
  302. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story_slim047.py +0 -0
  303. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story_slim048.py +0 -0
  304. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story_slim049.py +0 -0
  305. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story_slim051.py +0 -0
  306. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story_slim052.py +0 -0
  307. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story_slim053.py +0 -0
  308. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story_slim054.py +0 -0
  309. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story_slim055.py +0 -0
  310. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story_slim056.py +0 -0
  311. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story_slim060_codex_profile.py +0 -0
  312. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_story_slim063.py +0 -0
  313. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_tools.py +0 -0
  314. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_update_task.py +0 -0
  315. {pactkit-2.7.0 → pactkit-2.8.0}/tests/unit/test_visualize_modes.py +0 -0
@@ -27,8 +27,8 @@ jobs:
27
27
  - name: Install dependencies
28
28
  run: |
29
29
  python -m pip install --upgrade pip
30
- pip install -e ".[dev]" || pip install -e .
31
- pip install pytest ruff
30
+ pip install --no-deps -e ".[dev]" || pip install --no-deps -e .
31
+ pip install pyyaml pytest ruff
32
32
 
33
33
  - name: Lint
34
34
  run: ruff check src/ tests/
@@ -2,7 +2,7 @@
2
2
  # Edit this file to customize which components are deployed.
3
3
  # Remove items from a list to disable them. Default: all enabled.
4
4
 
5
- version: "2.6.1"
5
+ version: "2.8.0"
6
6
  stack: python
7
7
  root: .
8
8
  developer: "slim"
@@ -23,18 +23,19 @@ agents:
23
23
  commands:
24
24
  - project-act
25
25
  - project-check
26
+ - project-clarify
26
27
  - project-design
27
28
  - project-done
28
29
  - project-hotfix
29
30
  - project-init
30
31
  - project-plan
31
- - project-sprint
32
- - project-clarify
33
32
  - project-pr
34
33
  - project-release
34
+ - project-sprint
35
35
 
36
36
  # Skills — tool scripts
37
37
  skills:
38
+ - pactkit-analyze
38
39
  - pactkit-board
39
40
  - pactkit-doctor
40
41
  - pactkit-draw
@@ -44,7 +45,6 @@ skills:
44
45
  - pactkit-status
45
46
  - pactkit-trace
46
47
  - pactkit-visualize
47
- - pactkit-analyze
48
48
  - project-act
49
49
  - project-check
50
50
  - project-clarify
@@ -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.8.0] - 2026-03-27
8
+
9
+ ### Added
10
+ - **3-IDE default install** — `pip install pactkit` now installs all three IDE adapters (Claude Code + OpenCode + Codex) out of the box.
11
+
12
+ ### Fixed
13
+ - **OpenCode command architecture** — Reverted OpenCode from skills-only back to `commands/` + `skills/` dual architecture. OpenCode auto-discovers commands from `commands/*.md` (invoked via `/project-plan`), while embedded skills in `skills/` are loaded by AI agent on demand. `opencode.json` command entries now only contain model routing (no `template` field — it was incorrectly treated as file path, but is actually inline text).
14
+ - **Spec version confusion** — `/project-plan` Phase 3.2a no longer reads version from `pactkit.yaml` (PactKit toolkit version). Now explicitly reads from project's package manifest (`pyproject.toml`, `package.json`, `Cargo.toml`).
15
+ - **OpenCode path isolation** — All deployed OpenCode files reference `~/.config/opencode/` paths, CLI commands replaced with `python3 ~/.config/opencode/skills/*/scripts/*.py` invocations.
16
+ - **pactkit.yaml simplification** — Removed redundant component lists (agents/commands/skills/rules) from yaml template. Absence = deploy all from `VALID_*` sets. `pactkit doctor` drift check skips absent keys.
17
+
18
+ ### Changed
19
+ - **Cross-IDE command architecture**:
20
+ - Claude Code: skills-only (`skills/project-*/SKILL.md`), prefix `/`
21
+ - OpenCode: commands + skills (`commands/project-*.md` + `skills/pactkit-*/SKILL.md`), prefix `/`
22
+ - Codex: skills-only (`skills/project-*/SKILL.md`), prefix `$`
23
+
7
24
  ## [2.7.0] - 2026-03-27
8
25
 
9
26
  ### Added
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pactkit
3
- Version: 2.7.0
3
+ Version: 2.8.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
@@ -21,7 +21,8 @@ Classifier: Programming Language :: Python :: 3.13
21
21
  Classifier: Topic :: Software Development :: Build Tools
22
22
  Classifier: Topic :: Software Development :: Quality Assurance
23
23
  Requires-Python: >=3.10
24
- Requires-Dist: pactkit-opencode>=2.6.0
24
+ Requires-Dist: pactkit-codex>=2.8.0
25
+ Requires-Dist: pactkit-opencode>=2.8.0
25
26
  Requires-Dist: pyyaml>=6.0
26
27
  Provides-Extra: multilang
27
28
  Requires-Dist: tree-sitter-go>=0.25; extra == 'multilang'
@@ -4,14 +4,15 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "pactkit"
7
- version = "2.7.0"
7
+ version = "2.8.0"
8
8
  description = "Spec-driven agentic DevOps toolkit for AI coding assistants"
9
9
  readme = "README.md"
10
10
  license = "MIT"
11
11
  requires-python = ">=3.10"
12
12
  dependencies = [
13
13
  "pyyaml>=6.0",
14
- "pactkit-opencode>=2.6.0",
14
+ "pactkit-opencode>=2.8.0",
15
+ "pactkit-codex>=2.8.0",
15
16
  ]
16
17
 
17
18
  authors = [
@@ -1,3 +1,3 @@
1
1
  """PactKit - Spec-driven agentic DevOps toolkit."""
2
2
 
3
- __version__ = "2.7.0"
3
+ __version__ = "2.8.0"
@@ -448,14 +448,12 @@ def auto_merge_config_file(path: Union[Path, str]) -> list[str]:
448
448
  added: list[str] = []
449
449
 
450
450
  # --- List-type keys: merge new items ---
451
+ # If a list key is absent from yaml, it means "deploy all" (VALID_* default).
452
+ # Only merge if the user explicitly provides a list (opt-in customization).
451
453
  for key, valid_set in _REGISTRY.items():
452
454
  user_list = user_data.get(key)
453
455
  if user_list is None:
454
- # BUG-013: key missing from user yaml backfill full default list
455
- excluded_items = set(exclude.get(key, []) or [])
456
- new_items = sorted(item for item in valid_set if item not in excluded_items)
457
- user_data[key] = new_items
458
- added.append(f"section: {key}")
456
+ # Key absent = deploy all by default. No backfill needed.
459
457
  continue
460
458
  if not isinstance(user_list, list):
461
459
  continue
@@ -900,34 +898,14 @@ def generate_default_yaml() -> str:
900
898
  cfg = get_default_config()
901
899
  lines = [
902
900
  "# PactKit Configuration",
903
- "# Edit this file to customize which components are deployed.",
904
- "# Remove items from a list to disable them. Default: all enabled.",
901
+ "# All agents, commands, skills, and rules are deployed by default.",
902
+ "# To exclude specific items, add an exclude list (e.g., exclude_skills: [pactkit-draw]).",
905
903
  "",
906
904
  f'version: "{cfg["version"]}"',
907
905
  f"stack: {cfg['stack']}",
908
906
  f"root: {cfg['root']}",
909
907
  f'developer: "{cfg["developer"]}"',
910
- "",
911
- "# Agents — AI role definitions",
912
- "agents:",
913
908
  ]
914
- for a in cfg["agents"]:
915
- lines.append(f" - {a}")
916
-
917
- lines.extend(["", "# Commands — PDCA playbooks"])
918
- lines.append("commands:")
919
- for c in cfg["commands"]:
920
- lines.append(f" - {c}")
921
-
922
- lines.extend(["", "# Skills — tool scripts"])
923
- lines.append("skills:")
924
- for s in cfg["skills"]:
925
- lines.append(f" - {s}")
926
-
927
- lines.extend(["", "# Rules — constitution modules"])
928
- lines.append("rules:")
929
- for r in cfg["rules"]:
930
- lines.append(f" - {r}")
931
909
 
932
910
  ci = cfg.get("ci", {})
933
911
  lines.extend(["", "# CI/CD — set provider to github or gitlab to generate pipeline config"])
@@ -55,6 +55,10 @@ def check_orphaned_specs(project_root: Path) -> dict:
55
55
  def check_config_drift(project_root: Path) -> dict:
56
56
  """Compare pactkit.yaml declared items vs deployed files.
57
57
 
58
+ Only checks deployment drift when the yaml explicitly declares
59
+ component lists (agents, commands, skills, rules). Default behavior
60
+ (no lists) means "deploy all from VALID_* sets" — no drift possible.
61
+
58
62
  Returns:
59
63
  {"missing_deployments": [{"type": ..., "name": ...}]}
60
64
  """
@@ -69,33 +73,32 @@ def check_config_drift(project_root: Path) -> dict:
69
73
  with open(yaml_path, encoding="utf-8") as f:
70
74
  data = yaml.safe_load(f) or {}
71
75
 
72
- config_dir = yaml_path.parent # .claude/ or .opencode/
76
+ config_dir = yaml_path.parent # .claude/ or .opencode/ or .codex/
73
77
  missing: list[dict] = []
74
78
 
75
- # Check agents
76
- for agent in data.get("agents", []):
77
- agent_file = config_dir / "agents" / f"{agent}.md"
78
- if not agent_file.exists():
79
- missing.append({"type": "agent", "name": agent})
80
-
81
- # Check commands
82
- for cmd in data.get("commands", []):
83
- cmd_file = config_dir / "commands" / f"{cmd}.md"
84
- if not cmd_file.exists():
85
- missing.append({"type": "command", "name": cmd})
86
-
87
- # Check skills
88
- for skill in data.get("skills", []):
89
- skill_dir = config_dir / "skills" / skill
90
- skill_file = config_dir / "skills" / f"{skill}.md"
91
- if not skill_dir.is_dir() and not skill_file.exists():
92
- missing.append({"type": "skill", "name": skill})
93
-
94
- # Check rules
95
- for rule in data.get("rules", []):
96
- rule_file = config_dir / "rules" / f"{rule}.md"
97
- if not rule_file.exists():
98
- missing.append({"type": "rule", "name": rule})
79
+ # Only check drift for explicitly declared lists.
80
+ # If the key is absent, it means "deploy all" — no drift to check.
81
+ _CHECKS = [
82
+ ("agents", "agents", ".md"),
83
+ ("commands", "commands", ".md"),
84
+ ("rules", "rules", ".md"),
85
+ ]
86
+ for key, subdir, suffix in _CHECKS:
87
+ declared = data.get(key)
88
+ if not isinstance(declared, list):
89
+ continue
90
+ for item in declared:
91
+ if not (config_dir / subdir / f"{item}{suffix}").exists():
92
+ missing.append({"type": key.rstrip("s"), "name": item})
93
+
94
+ # Skills: check as directory or .md file
95
+ declared_skills = data.get("skills")
96
+ if isinstance(declared_skills, list):
97
+ for skill in declared_skills:
98
+ skill_dir = config_dir / "skills" / skill
99
+ skill_file = config_dir / "skills" / f"{skill}.md"
100
+ if not skill_dir.is_dir() and not skill_file.exists():
101
+ missing.append({"type": "skill", "name": skill})
99
102
 
100
103
  return {"missing_deployments": missing}
101
104
 
@@ -301,10 +301,10 @@ def _deploy_classic(config=None, target=None):
301
301
  d.mkdir(parents=True, exist_ok=True)
302
302
 
303
303
  # Deploy components filtered by config
304
- enabled_skills = config.get("skills", [])
305
- enabled_rules = config.get("rules", [])
306
- enabled_agents = config.get("agents", [])
307
- enabled_commands = config.get("commands", [])
304
+ enabled_skills = config.get("skills", sorted(VALID_SKILLS))
305
+ enabled_rules = config.get("rules", sorted(VALID_RULES))
306
+ enabled_agents = config.get("agents", sorted(VALID_AGENTS))
307
+ enabled_commands = config.get("commands", sorted(VALID_COMMANDS))
308
308
 
309
309
  classic_profile = get_profile("classic")
310
310
  n_skills = _deploy_skills(skills_dir, enabled_skills, profile=classic_profile)
@@ -90,7 +90,7 @@ allowed-tools: [Read, Write, Edit, Bash, Glob, Grep]
90
90
  1. **Scaffold**: Run `{SCAFFOLD_CMD} create_spec "{ID}" "{title}"` to generate `docs/specs/{ID}.md` from SPEC_TEMPLATE. This creates all sections, tables, and Given/When/Then skeleton — format is guaranteed by Code.
91
91
  2. **Read**: Read `docs/specs/{ID}.md` to see the scaffolded template.
92
92
  3. **Edit placeholders** (use Edit tool, NOT Write):
93
- - Edit `Release | TBD` → `Release | {version}` (read version from `{PACTKIT_YAML}` or `pyproject.toml`; if unreadable, keep TBD)
93
+ - Edit `Release | TBD` → `Release | {version}` (from `pyproject.toml`/`package.json`, NOT `{PACTKIT_YAML}`)
94
94
  - Edit `(Description of the problem or feature)` → actual Background content from your Trace findings
95
95
  - Edit `## Target Call Chain` placeholder → actual call chain from Phase 1
96
96
  - Edit `### R1: (Requirement Name) (MUST)` → actual requirements using RFC 2119 keywords (MUST/SHOULD/MAY). Add more R{N} sections as needed.
@@ -519,18 +519,28 @@ description: "Standalone requirement clarification before planning"
519
519
  allowed-tools: [Read, Bash, Glob, Grep]
520
520
  ---
521
521
 
522
- # Command: Clarify (v1.0.0)
522
+ # Command: Clarify (v1.1.0)
523
523
  - **Usage**: `/project-clarify "$ARGUMENTS"`
524
524
  - **Agent**: System Architect
525
525
 
526
- > **PURPOSE**: Standalone requirement clarification. Run before `/project-plan` to surface ambiguities and produce a clarified brief.
526
+ > **PURPOSE**: Standalone requirement clarification. Run before `/project-plan` to surface ambiguities and assess risks upfront.
527
527
 
528
528
  ## Phase 1: Ambiguity Analysis
529
529
  1. Analyze `$ARGUMENTS` against the AMBIGUITY_SIGNALS checklist (same as Plan Phase 0.7).
530
530
  2. Generate 3–6 structured questions (Scope, Users, Constraints, Scale, Edge Cases, Non-Goals).
531
531
  3. Ask questions in the user's language.
532
532
 
533
- ## Phase 2: Clarified Brief Output
533
+ ## Phase 2: Pre-mortem Risk Probe
534
+ > **PURPOSE**: Reverse thinking — identify how the plan could fail before it starts.
535
+ 1. Based on `$ARGUMENTS` and Phase 1 findings, generate 1–2 pre-mortem questions (pick the most relevant):
536
+ - "If this feature is deemed a failure 1 month after launch, what is the most likely reason?"
537
+ - "What assumptions does this plan rely on? Which assumption is the most fragile?"
538
+ - "What will the person maintaining this code in 6 months complain about the most?"
539
+ - "What is the most likely integration point to break?"
540
+ 2. Ask in the user's language, together with Phase 1 questions.
541
+ 3. Total questions across Phase 1 + Phase 2 MUST NOT exceed 6. If Phase 1 already has 5–6, pick only 1 pre-mortem question. If Phase 1 has ≤ 4, pick up to 2.
542
+
543
+ ## Phase 3: Clarified Brief Output
534
544
  1. After user responses, produce a **Clarified Brief**:
535
545
  ```markdown
536
546
  ## Clarified Brief: {feature name}
@@ -540,6 +550,7 @@ allowed-tools: [Read, Bash, Glob, Grep]
540
550
  - **Scale**: {performance expectations}
541
551
  - **Edge Cases**: {failure scenarios and expected behavior}
542
552
  - **Non-Goals**: {explicitly excluded}
553
+ - **Risks**: {top 1-2 identified risks from pre-mortem}
543
554
  ```
544
555
  2. Output: "Ready for Plan. Run: `/project-plan \\"{clarified brief summary}\\"`"
545
556
  """,
@@ -154,10 +154,10 @@ class TestAC2NewConfigAtProjectPath:
154
154
  'Full config should be generated at $CWD/.claude/pactkit.yaml'
155
155
 
156
156
  generated = yaml.safe_load(project_yaml.read_text())
157
- assert 'agents' in generated, 'Generated config should have agents list'
158
- assert 'commands' in generated, 'Generated config should have commands list'
159
- assert 'skills' in generated, 'Generated config should have skills list'
160
- assert 'rules' in generated, 'Generated config should have rules list'
157
+ # Component lists (agents, commands, skills, rules) are no longer in yaml —
158
+ # default is "deploy all" from VALID_* sets. Only operational config remains.
159
+ assert 'stack' in generated, 'Generated config should have stack'
160
+ assert 'version' in generated, 'Generated config should have version'
161
161
 
162
162
  def test_no_config_at_global_path(self, tmp_path):
163
163
  from pactkit.generators.deployer import deploy
@@ -223,11 +223,15 @@ class TestGenerateDefaultYaml:
223
223
  parsed = yaml.safe_load(result)
224
224
  assert isinstance(parsed, dict)
225
225
 
226
- def test_roundtrip_equals_default(self):
226
+ def test_roundtrip_contains_core_keys(self):
227
+ """Generated YAML has operational config but not component lists."""
227
228
  result = _config().generate_default_yaml()
228
229
  parsed = yaml.safe_load(result)
229
- default = _config().get_default_config()
230
- assert parsed == default
230
+ assert "stack" in parsed
231
+ assert "version" in parsed
232
+ # Component lists omitted — default is "deploy all" from VALID_* sets
233
+ for key in ("agents", "commands", "skills", "rules"):
234
+ assert key not in parsed
231
235
 
232
236
  def test_contains_comments(self):
233
237
  result = _config().generate_default_yaml()
@@ -246,8 +246,8 @@ class TestBackwardCompatibility:
246
246
  added = cfg.auto_merge_config_file(yaml_path)
247
247
  assert added == []
248
248
 
249
- def test_yaml_with_only_scalar_keys_backfills_lists(self, tmp_path):
250
- """BUG-013: missing list keys are backfilled with full defaults."""
249
+ def test_yaml_with_only_scalar_keys_no_backfill(self, tmp_path):
250
+ """Missing list keys are NOT backfilled absence means 'deploy all'."""
251
251
  cfg = _config()
252
252
  yaml_path = tmp_path / 'pactkit.yaml'
253
253
  _write_yaml(yaml_path, {
@@ -260,11 +260,10 @@ class TestBackwardCompatibility:
260
260
  })
261
261
 
262
262
  added = cfg.auto_merge_config_file(yaml_path)
263
- section_reports = [r for r in added if r.startswith('section:')]
264
- assert 'section: agents' in section_reports
265
- assert 'section: commands' in section_reports
266
- assert 'section: skills' in section_reports
267
- assert 'section: rules' in section_reports
263
+ # No list backfill missing keys mean "deploy all"
264
+ list_keys = {'agents', 'commands', 'skills', 'rules'}
265
+ list_backfills = [r for r in added if any(r == f'section: {k}' for k in list_keys)]
266
+ assert len(list_backfills) == 0
268
267
 
269
268
  def test_full_list_nothing_added(self, tmp_path):
270
269
  """If user already has all VALID items and sections, nothing is added."""
@@ -229,7 +229,7 @@ class TestConfigAutoGeneration:
229
229
  yaml_path = claude / "pactkit.yaml"
230
230
  parsed = yaml.safe_load(yaml_path.read_text())
231
231
  assert parsed is not None
232
- assert "agents" in parsed
232
+ assert "stack" in parsed
233
233
 
234
234
 
235
235
  # ===========================================================================
@@ -233,13 +233,13 @@ class TestAC4BackfillReport:
233
233
  assert len(section_reports) == 0
234
234
 
235
235
  def test_reports_multiple_sections(self, tmp_path):
236
- """All missing sections reported when all are absent (BUG-013: includes lists)."""
236
+ """All missing non-list sections reported when absent."""
237
237
  yaml_path = tmp_path / 'pactkit.yaml'
238
238
  yaml_path.write_text('stack: python\nversion: "1.2.0"\nroot: .\n')
239
239
  result = auto_merge_config_file(yaml_path)
240
240
  section_reports = [r for r in result if r.startswith('section:')]
241
- # 4 list-type (agents, commands, skills, rules) + 12 non-list (ci, issue_tracker, hooks, lint_blocking, auto_fix, e2e, venv, release, regression, check, done, visualize)
242
- assert len(section_reports) == 16
241
+ # 12 non-list sections only (list-type keys no longer backfilled)
242
+ assert len(section_reports) == 12
243
243
 
244
244
 
245
245
  # ===========================================================================
@@ -197,7 +197,8 @@ class TestAC6DevRefGhostResolved:
197
197
  # AC7: Total Prompt Size Reduced >= 15%
198
198
  # ---------------------------------------------------------------------------
199
199
  # STORY-slim-050: bumped +393 for Done smart regression gate (R2)
200
- BASELINE_TOTAL_CHARS = 73975
200
+ # HOTFIX: bumped +875 for Clarify pre-mortem risk probe
201
+ BASELINE_TOTAL_CHARS = 74850
201
202
 
202
203
 
203
204
  class TestAC7PromptSizeReduced:
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