pactkit 2.17.0__tar.gz → 2.18.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 (656) hide show
  1. {pactkit-2.17.0 → pactkit-2.18.0}/.github/workflows/pactkit.yml +2 -2
  2. {pactkit-2.17.0 → pactkit-2.18.0}/.github/workflows/publish.yml +4 -4
  3. {pactkit-2.17.0 → pactkit-2.18.0}/CHANGELOG.md +9 -0
  4. {pactkit-2.17.0 → pactkit-2.18.0}/PKG-INFO +1 -1
  5. {pactkit-2.17.0 → pactkit-2.18.0}/docs/architecture/governance/archive/lessons_archive_202603.md +2 -0
  6. {pactkit-2.17.0 → pactkit-2.18.0}/docs/architecture/governance/lessons.md +2 -2
  7. {pactkit-2.17.0 → pactkit-2.18.0}/docs/architecture/governance/rules.md +1 -1
  8. {pactkit-2.17.0 → pactkit-2.18.0}/docs/product/archive/archive_202608.md +17 -0
  9. {pactkit-2.17.0 → pactkit-2.18.0}/docs/product/context.md +3 -3
  10. pactkit-2.18.0/docs/specs/STORY-slim-141.md +129 -0
  11. pactkit-2.18.0/docs/specs/STORY-slim-142.md +120 -0
  12. pactkit-2.18.0/docs/test_cases/STORY-slim-141_case.md +76 -0
  13. pactkit-2.18.0/docs/test_cases/STORY-slim-142_case.md +46 -0
  14. {pactkit-2.17.0 → pactkit-2.18.0}/pyproject.toml +1 -1
  15. {pactkit-2.17.0 → pactkit-2.18.0}/src/pactkit/__init__.py +1 -1
  16. {pactkit-2.17.0 → pactkit-2.18.0}/src/pactkit/cli.py +6 -0
  17. pactkit-2.18.0/src/pactkit/deploy_manifest.py +112 -0
  18. {pactkit-2.17.0 → pactkit-2.18.0}/src/pactkit/doctor.py +66 -0
  19. {pactkit-2.17.0 → pactkit-2.18.0}/src/pactkit/generators/deployer.py +11 -2
  20. {pactkit-2.17.0 → pactkit-2.18.0}/src/pactkit/prompts/workflows.py +1 -1
  21. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim012_ci.py +4 -4
  22. pactkit-2.18.0/tests/unit/test_story_slim141_manifest_hash.py +238 -0
  23. pactkit-2.18.0/tests/unit/test_story_slim142_all_target_isolation.py +124 -0
  24. pactkit-2.17.0/src/pactkit/deploy_manifest.py +0 -57
  25. {pactkit-2.17.0 → pactkit-2.18.0}/.codegraph/.gitignore +0 -0
  26. {pactkit-2.17.0 → pactkit-2.18.0}/.gitignore +0 -0
  27. {pactkit-2.17.0 → pactkit-2.18.0}/AGENTS.md +0 -0
  28. {pactkit-2.17.0 → pactkit-2.18.0}/CODE_OF_CONDUCT.md +0 -0
  29. {pactkit-2.17.0 → pactkit-2.18.0}/CONTRIBUTING.md +0 -0
  30. {pactkit-2.17.0 → pactkit-2.18.0}/LICENSE +0 -0
  31. {pactkit-2.17.0 → pactkit-2.18.0}/README.md +0 -0
  32. {pactkit-2.17.0 → pactkit-2.18.0}/SECURITY.md +0 -0
  33. {pactkit-2.17.0 → pactkit-2.18.0}/docs/architecture/governance/archive/lessons_archive_202602.md +0 -0
  34. {pactkit-2.17.0 → pactkit-2.18.0}/docs/architecture/governance/harness_audit.json +0 -0
  35. {pactkit-2.17.0 → pactkit-2.18.0}/docs/architecture/governance/philosophy.md +0 -0
  36. {pactkit-2.17.0 → pactkit-2.18.0}/docs/assets/logo.png +0 -0
  37. {pactkit-2.17.0 → pactkit-2.18.0}/docs/e2e/journey.md +0 -0
  38. {pactkit-2.17.0 → pactkit-2.18.0}/docs/guides/codex-integration-preresearch.md +0 -0
  39. {pactkit-2.17.0 → pactkit-2.18.0}/docs/guides/tool-integration-checklist.md +0 -0
  40. {pactkit-2.17.0 → pactkit-2.18.0}/docs/product/archive/archive_202602.md +0 -0
  41. {pactkit-2.17.0 → pactkit-2.18.0}/docs/product/archive/archive_202603.md +0 -0
  42. {pactkit-2.17.0 → pactkit-2.18.0}/docs/product/archive/archive_202604.md +0 -0
  43. {pactkit-2.17.0 → pactkit-2.18.0}/docs/product/archive/archive_202605.md +0 -0
  44. {pactkit-2.17.0 → pactkit-2.18.0}/docs/product/archive/archive_202606.md +0 -0
  45. {pactkit-2.17.0 → pactkit-2.18.0}/docs/product/archive/archive_202607.md +0 -0
  46. {pactkit-2.17.0 → pactkit-2.18.0}/docs/product/friction-log.md +0 -0
  47. {pactkit-2.17.0 → pactkit-2.18.0}/docs/product/prd.md +0 -0
  48. {pactkit-2.17.0 → pactkit-2.18.0}/docs/product/sprint_board.md +0 -0
  49. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/BUG-001.md +0 -0
  50. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/BUG-002.md +0 -0
  51. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/BUG-003.md +0 -0
  52. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/BUG-004.md +0 -0
  53. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/BUG-005.md +0 -0
  54. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/BUG-006.md +0 -0
  55. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/BUG-007.md +0 -0
  56. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/BUG-008.md +0 -0
  57. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/BUG-009.md +0 -0
  58. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/BUG-010.md +0 -0
  59. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/BUG-011.md +0 -0
  60. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/BUG-012.md +0 -0
  61. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/BUG-013.md +0 -0
  62. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/BUG-014.md +0 -0
  63. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/BUG-015.md +0 -0
  64. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/BUG-016.md +0 -0
  65. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/BUG-017.md +0 -0
  66. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/BUG-018.md +0 -0
  67. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/BUG-019.md +0 -0
  68. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/BUG-020.md +0 -0
  69. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/BUG-021.md +0 -0
  70. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/BUG-022.md +0 -0
  71. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/BUG-023.md +0 -0
  72. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/BUG-024.md +0 -0
  73. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/BUG-025.md +0 -0
  74. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/BUG-026.md +0 -0
  75. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/BUG-027.md +0 -0
  76. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/BUG-028.md +0 -0
  77. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/BUG-029.md +0 -0
  78. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/BUG-030.md +0 -0
  79. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/BUG-031.md +0 -0
  80. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/BUG-032.md +0 -0
  81. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/BUG-033.md +0 -0
  82. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/BUG-034.md +0 -0
  83. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/BUG-035.md +0 -0
  84. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/BUG-slim-001.md +0 -0
  85. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/BUG-slim-002.md +0 -0
  86. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/BUG-slim-003.md +0 -0
  87. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/BUG-slim-004.md +0 -0
  88. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/BUG-slim-005.md +0 -0
  89. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/BUG-slim-006.md +0 -0
  90. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/BUG-slim-089.md +0 -0
  91. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/BUG-slim-107.md +0 -0
  92. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/HOTFIX-slim-023.md +0 -0
  93. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/HOTFIX-slim-049.md +0 -0
  94. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/HOTFIX-slim-050.md +0 -0
  95. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/HOTFIX-slim-051.md +0 -0
  96. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/HOTFIX-slim-052.md +0 -0
  97. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/HOTFIX-slim-061.md +0 -0
  98. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/HOTFIX-slim-062.md +0 -0
  99. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/HOTFIX-slim-067.md +0 -0
  100. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/HOTFIX-slim-069.md +0 -0
  101. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/HOTFIX-slim-070.md +0 -0
  102. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/HOTFIX-slim-085.md +0 -0
  103. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/HOTFIX-slim-087.md +0 -0
  104. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/HOTFIX-slim-096.md +0 -0
  105. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/HOTFIX-slim-099.md +0 -0
  106. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/HOTFIX-slim-107.md +0 -0
  107. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/HOTFIX-slim-117.md +0 -0
  108. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/HOTFIX-slim-122.md +0 -0
  109. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/HOTFIX-slim-123.md +0 -0
  110. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/HOTFIX-slim-126.md +0 -0
  111. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/HOTFIX-slim-127.md +0 -0
  112. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/HOTFIX-slim-130.md +0 -0
  113. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/HOTFIX-slim-131.md +0 -0
  114. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/HOTFIX-slim-132.md +0 -0
  115. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-001.md +0 -0
  116. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-002.md +0 -0
  117. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-003.md +0 -0
  118. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-004.md +0 -0
  119. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-005.md +0 -0
  120. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-006.md +0 -0
  121. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-007.md +0 -0
  122. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-008.md +0 -0
  123. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-009.md +0 -0
  124. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-010.md +0 -0
  125. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-011.md +0 -0
  126. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-012.md +0 -0
  127. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-013.md +0 -0
  128. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-014.md +0 -0
  129. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-015.md +0 -0
  130. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-016.md +0 -0
  131. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-017.md +0 -0
  132. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-018.md +0 -0
  133. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-019.md +0 -0
  134. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-020.md +0 -0
  135. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-021.md +0 -0
  136. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-022.md +0 -0
  137. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-023.md +0 -0
  138. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-024.md +0 -0
  139. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-025.md +0 -0
  140. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-026.md +0 -0
  141. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-027.md +0 -0
  142. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-028.md +0 -0
  143. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-029.md +0 -0
  144. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-030.md +0 -0
  145. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-031.md +0 -0
  146. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-032.md +0 -0
  147. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-033.md +0 -0
  148. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-034.md +0 -0
  149. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-035.md +0 -0
  150. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-036.md +0 -0
  151. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-037.md +0 -0
  152. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-038.md +0 -0
  153. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-039.md +0 -0
  154. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-040.md +0 -0
  155. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-041.md +0 -0
  156. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-042.md +0 -0
  157. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-043.md +0 -0
  158. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-044.md +0 -0
  159. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-045.md +0 -0
  160. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-046.md +0 -0
  161. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-047.md +0 -0
  162. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-048.md +0 -0
  163. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-049.md +0 -0
  164. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-050.md +0 -0
  165. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-051.md +0 -0
  166. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-052.md +0 -0
  167. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-053.md +0 -0
  168. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-054.md +0 -0
  169. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-055.md +0 -0
  170. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-056.md +0 -0
  171. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-057.md +0 -0
  172. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-058.md +0 -0
  173. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-059.md +0 -0
  174. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-060.md +0 -0
  175. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-061.md +0 -0
  176. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-062.md +0 -0
  177. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-063.md +0 -0
  178. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-064.md +0 -0
  179. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-065.md +0 -0
  180. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-069.md +0 -0
  181. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-070.md +0 -0
  182. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-071.md +0 -0
  183. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-072.md +0 -0
  184. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-073.md +0 -0
  185. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-001.md +0 -0
  186. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-005.md +0 -0
  187. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-006.md +0 -0
  188. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-007.md +0 -0
  189. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-009.md +0 -0
  190. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-010.md +0 -0
  191. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-011.md +0 -0
  192. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-012.md +0 -0
  193. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-013.md +0 -0
  194. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-014.md +0 -0
  195. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-015.md +0 -0
  196. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-016.md +0 -0
  197. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-017.md +0 -0
  198. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-018.md +0 -0
  199. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-019.md +0 -0
  200. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-020.md +0 -0
  201. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-021.md +0 -0
  202. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-022.md +0 -0
  203. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-023.md +0 -0
  204. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-024.md +0 -0
  205. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-028.md +0 -0
  206. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-029.md +0 -0
  207. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-030.md +0 -0
  208. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-031.md +0 -0
  209. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-032.md +0 -0
  210. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-033.md +0 -0
  211. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-034.md +0 -0
  212. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-035.md +0 -0
  213. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-036.md +0 -0
  214. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-037.md +0 -0
  215. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-038.md +0 -0
  216. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-039.md +0 -0
  217. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-040.md +0 -0
  218. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-041.md +0 -0
  219. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-042.md +0 -0
  220. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-043.md +0 -0
  221. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-044.md +0 -0
  222. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-045.md +0 -0
  223. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-046.md +0 -0
  224. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-047.md +0 -0
  225. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-048.md +0 -0
  226. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-049.md +0 -0
  227. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-050.md +0 -0
  228. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-051.md +0 -0
  229. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-052.md +0 -0
  230. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-053.md +0 -0
  231. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-054.md +0 -0
  232. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-055.md +0 -0
  233. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-056.md +0 -0
  234. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-057.md +0 -0
  235. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-058.md +0 -0
  236. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-059.md +0 -0
  237. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-060.md +0 -0
  238. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-063.md +0 -0
  239. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-066.md +0 -0
  240. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-067.md +0 -0
  241. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-068.md +0 -0
  242. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-069.md +0 -0
  243. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-070.md +0 -0
  244. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-071.md +0 -0
  245. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-072.md +0 -0
  246. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-073.md +0 -0
  247. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-074.md +0 -0
  248. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-075.md +0 -0
  249. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-076.md +0 -0
  250. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-077.md +0 -0
  251. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-078.md +0 -0
  252. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-079.md +0 -0
  253. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-080.md +0 -0
  254. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-081.md +0 -0
  255. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-082.md +0 -0
  256. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-083.md +0 -0
  257. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-084.md +0 -0
  258. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-086.md +0 -0
  259. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-088.md +0 -0
  260. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-089.md +0 -0
  261. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-090.md +0 -0
  262. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-091.md +0 -0
  263. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-092.md +0 -0
  264. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-093.md +0 -0
  265. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-094.md +0 -0
  266. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-095.md +0 -0
  267. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-097.md +0 -0
  268. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-098.md +0 -0
  269. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-099.md +0 -0
  270. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-100.md +0 -0
  271. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-101.md +0 -0
  272. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-102.md +0 -0
  273. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-103.md +0 -0
  274. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-104.md +0 -0
  275. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-105.md +0 -0
  276. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-106.md +0 -0
  277. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-107.md +0 -0
  278. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-108.md +0 -0
  279. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-109.md +0 -0
  280. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-110.md +0 -0
  281. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-111.md +0 -0
  282. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-112.md +0 -0
  283. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-113.md +0 -0
  284. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-114.md +0 -0
  285. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-115.md +0 -0
  286. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-116.md +0 -0
  287. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-118.md +0 -0
  288. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-119.md +0 -0
  289. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-120.md +0 -0
  290. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-121.md +0 -0
  291. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-124.md +0 -0
  292. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-125.md +0 -0
  293. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-126.md +0 -0
  294. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-127.md +0 -0
  295. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-128.md +0 -0
  296. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-129.md +0 -0
  297. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-132.md +0 -0
  298. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-133.md +0 -0
  299. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-134.md +0 -0
  300. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-135.md +0 -0
  301. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-136.md +0 -0
  302. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-137.md +0 -0
  303. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-138.md +0 -0
  304. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-139.md +0 -0
  305. {pactkit-2.17.0 → pactkit-2.18.0}/docs/specs/STORY-slim-140.md +0 -0
  306. {pactkit-2.17.0 → pactkit-2.18.0}/docs/test_cases/BUG-001_case.md +0 -0
  307. {pactkit-2.17.0 → pactkit-2.18.0}/docs/test_cases/BUG-002_case.md +0 -0
  308. {pactkit-2.17.0 → pactkit-2.18.0}/docs/test_cases/STORY-slim-028_case.md +0 -0
  309. {pactkit-2.17.0 → pactkit-2.18.0}/docs/test_cases/STORY-slim-029_case.md +0 -0
  310. {pactkit-2.17.0 → pactkit-2.18.0}/docs/test_cases/STORY-slim-031_case.md +0 -0
  311. {pactkit-2.17.0 → pactkit-2.18.0}/docs/test_cases/STORY-slim-032_case.md +0 -0
  312. {pactkit-2.17.0 → pactkit-2.18.0}/docs/test_cases/STORY-slim-033_case.md +0 -0
  313. {pactkit-2.17.0 → pactkit-2.18.0}/docs/test_cases/STORY-slim-034_case.md +0 -0
  314. {pactkit-2.17.0 → pactkit-2.18.0}/docs/test_cases/STORY-slim-135_case.md +0 -0
  315. {pactkit-2.17.0 → pactkit-2.18.0}/docs/test_cases/STORY-slim-136_case.md +0 -0
  316. {pactkit-2.17.0 → pactkit-2.18.0}/docs/test_cases/STORY-slim-137_case.md +0 -0
  317. {pactkit-2.17.0 → pactkit-2.18.0}/docs/test_cases/STORY-slim-138_case.md +0 -0
  318. {pactkit-2.17.0 → pactkit-2.18.0}/docs/test_cases/STORY-slim-139_case.md +0 -0
  319. {pactkit-2.17.0 → pactkit-2.18.0}/docs/test_cases/STORY-slim-140_case.md +0 -0
  320. {pactkit-2.17.0 → pactkit-2.18.0}/opencode.json +0 -0
  321. {pactkit-2.17.0 → pactkit-2.18.0}/src/pactkit/__main__.py +0 -0
  322. {pactkit-2.17.0 → pactkit-2.18.0}/src/pactkit/audit.py +0 -0
  323. {pactkit-2.17.0 → pactkit-2.18.0}/src/pactkit/backfill.py +0 -0
  324. {pactkit-2.17.0 → pactkit-2.18.0}/src/pactkit/cleaners.py +0 -0
  325. {pactkit-2.17.0 → pactkit-2.18.0}/src/pactkit/commit_gate.py +0 -0
  326. {pactkit-2.17.0 → pactkit-2.18.0}/src/pactkit/config.py +0 -0
  327. {pactkit-2.17.0 → pactkit-2.18.0}/src/pactkit/context_gen.py +0 -0
  328. {pactkit-2.17.0 → pactkit-2.18.0}/src/pactkit/coverage_gate.py +0 -0
  329. {pactkit-2.17.0 → pactkit-2.18.0}/src/pactkit/deps.py +0 -0
  330. {pactkit-2.17.0 → pactkit-2.18.0}/src/pactkit/done_verify.py +0 -0
  331. {pactkit-2.17.0 → pactkit-2.18.0}/src/pactkit/garden.py +0 -0
  332. {pactkit-2.17.0 → pactkit-2.18.0}/src/pactkit/generators/__init__.py +0 -0
  333. {pactkit-2.17.0 → pactkit-2.18.0}/src/pactkit/generators/adapter.py +0 -0
  334. {pactkit-2.17.0 → pactkit-2.18.0}/src/pactkit/generators/deploy_base.py +0 -0
  335. {pactkit-2.17.0 → pactkit-2.18.0}/src/pactkit/guards.py +0 -0
  336. {pactkit-2.17.0 → pactkit-2.18.0}/src/pactkit/id_generator.py +0 -0
  337. {pactkit-2.17.0 → pactkit-2.18.0}/src/pactkit/invariants.py +0 -0
  338. {pactkit-2.17.0 → pactkit-2.18.0}/src/pactkit/issue_sync.py +0 -0
  339. {pactkit-2.17.0 → pactkit-2.18.0}/src/pactkit/lazy_visualize.py +0 -0
  340. {pactkit-2.17.0 → pactkit-2.18.0}/src/pactkit/lessons.py +0 -0
  341. {pactkit-2.17.0 → pactkit-2.18.0}/src/pactkit/lint_runner.py +0 -0
  342. {pactkit-2.17.0 → pactkit-2.18.0}/src/pactkit/observe.py +0 -0
  343. {pactkit-2.17.0 → pactkit-2.18.0}/src/pactkit/profiles.py +0 -0
  344. {pactkit-2.17.0 → pactkit-2.18.0}/src/pactkit/prompts/__init__.py +0 -0
  345. {pactkit-2.17.0 → pactkit-2.18.0}/src/pactkit/prompts/agents.py +0 -0
  346. {pactkit-2.17.0 → pactkit-2.18.0}/src/pactkit/prompts/commands.py +0 -0
  347. {pactkit-2.17.0 → pactkit-2.18.0}/src/pactkit/prompts/guides.py +0 -0
  348. {pactkit-2.17.0 → pactkit-2.18.0}/src/pactkit/prompts/references.py +0 -0
  349. {pactkit-2.17.0 → pactkit-2.18.0}/src/pactkit/prompts/rules.py +0 -0
  350. {pactkit-2.17.0 → pactkit-2.18.0}/src/pactkit/prompts/skills.py +0 -0
  351. {pactkit-2.17.0 → pactkit-2.18.0}/src/pactkit/regression.py +0 -0
  352. {pactkit-2.17.0 → pactkit-2.18.0}/src/pactkit/schemas.py +0 -0
  353. {pactkit-2.17.0 → pactkit-2.18.0}/src/pactkit/scripts.py +0 -0
  354. {pactkit-2.17.0 → pactkit-2.18.0}/src/pactkit/sec_scope.py +0 -0
  355. {pactkit-2.17.0 → pactkit-2.18.0}/src/pactkit/skills/__init__.py +0 -0
  356. {pactkit-2.17.0 → pactkit-2.18.0}/src/pactkit/skills/analyzers/__init__.py +0 -0
  357. {pactkit-2.17.0 → pactkit-2.18.0}/src/pactkit/skills/analyzers/go_analyzer.py +0 -0
  358. {pactkit-2.17.0 → pactkit-2.18.0}/src/pactkit/skills/analyzers/java_analyzer.py +0 -0
  359. {pactkit-2.17.0 → pactkit-2.18.0}/src/pactkit/skills/analyzers/python_analyzer.py +0 -0
  360. {pactkit-2.17.0 → pactkit-2.18.0}/src/pactkit/skills/analyzers/ts_analyzer.py +0 -0
  361. {pactkit-2.17.0 → pactkit-2.18.0}/src/pactkit/skills/board.py +0 -0
  362. {pactkit-2.17.0 → pactkit-2.18.0}/src/pactkit/skills/interface_summary.py +0 -0
  363. {pactkit-2.17.0 → pactkit-2.18.0}/src/pactkit/skills/report.py +0 -0
  364. {pactkit-2.17.0 → pactkit-2.18.0}/src/pactkit/skills/scaffold.py +0 -0
  365. {pactkit-2.17.0 → pactkit-2.18.0}/src/pactkit/skills/spec_linter.py +0 -0
  366. {pactkit-2.17.0 → pactkit-2.18.0}/src/pactkit/skills/visualize.py +0 -0
  367. {pactkit-2.17.0 → pactkit-2.18.0}/src/pactkit/spec_status.py +0 -0
  368. {pactkit-2.17.0 → pactkit-2.18.0}/src/pactkit/test_mapper.py +0 -0
  369. {pactkit-2.17.0 → pactkit-2.18.0}/src/pactkit/utils.py +0 -0
  370. {pactkit-2.17.0 → pactkit-2.18.0}/src/pactkit/validators.py +0 -0
  371. {pactkit-2.17.0 → pactkit-2.18.0}/tests/conftest.py +0 -0
  372. {pactkit-2.17.0 → pactkit-2.18.0}/tests/e2e/__init__.py +0 -0
  373. {pactkit-2.17.0 → pactkit-2.18.0}/tests/e2e/cli/__init__.py +0 -0
  374. {pactkit-2.17.0 → pactkit-2.18.0}/tests/e2e/cli/test_cli_e2e.py +0 -0
  375. {pactkit-2.17.0 → pactkit-2.18.0}/tests/fixtures/agent_parser/agents_dir/researcher.yaml +0 -0
  376. {pactkit-2.17.0 → pactkit-2.18.0}/tests/fixtures/agent_parser/agents_dir/writer.yaml +0 -0
  377. {pactkit-2.17.0 → pactkit-2.18.0}/tests/fixtures/agent_parser/langgraph_app.py +0 -0
  378. {pactkit-2.17.0 → pactkit-2.18.0}/tests/fixtures/agent_parser/mcp_settings.json +0 -0
  379. {pactkit-2.17.0 → pactkit-2.18.0}/tests/fixtures/api_call_parser/axios_style.tsx +0 -0
  380. {pactkit-2.17.0 → pactkit-2.18.0}/tests/fixtures/api_call_parser/dynamic.tsx +0 -0
  381. {pactkit-2.17.0 → pactkit-2.18.0}/tests/fixtures/api_call_parser/page.tsx +0 -0
  382. {pactkit-2.17.0 → pactkit-2.18.0}/tests/fixtures/config_golden/copy_claude.json +0 -0
  383. {pactkit-2.17.0 → pactkit-2.18.0}/tests/fixtures/config_golden/copy_claude.yaml +0 -0
  384. {pactkit-2.17.0 → pactkit-2.18.0}/tests/fixtures/config_golden/copy_codex.json +0 -0
  385. {pactkit-2.17.0 → pactkit-2.18.0}/tests/fixtures/config_golden/copy_codex.yaml +0 -0
  386. {pactkit-2.17.0 → pactkit-2.18.0}/tests/fixtures/config_golden/copy_github.json +0 -0
  387. {pactkit-2.17.0 → pactkit-2.18.0}/tests/fixtures/config_golden/copy_github.yaml +0 -0
  388. {pactkit-2.17.0 → pactkit-2.18.0}/tests/fixtures/config_golden/empty.json +0 -0
  389. {pactkit-2.17.0 → pactkit-2.18.0}/tests/fixtures/config_golden/empty.yaml +0 -0
  390. {pactkit-2.17.0 → pactkit-2.18.0}/tests/fixtures/config_golden/full_legacy.json +0 -0
  391. {pactkit-2.17.0 → pactkit-2.18.0}/tests/fixtures/config_golden/full_legacy.yaml +0 -0
  392. {pactkit-2.17.0 → pactkit-2.18.0}/tests/fixtures/config_golden/minimal.json +0 -0
  393. {pactkit-2.17.0 → pactkit-2.18.0}/tests/fixtures/config_golden/minimal.yaml +0 -0
  394. {pactkit-2.17.0 → pactkit-2.18.0}/tests/fixtures/config_golden/unknown_keys.json +0 -0
  395. {pactkit-2.17.0 → pactkit-2.18.0}/tests/fixtures/config_golden/unknown_keys.yaml +0 -0
  396. {pactkit-2.17.0 → pactkit-2.18.0}/tests/integration/__init__.py +0 -0
  397. {pactkit-2.17.0 → pactkit-2.18.0}/tests/integration/test_deploy_classic.py +0 -0
  398. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_agent_features.py +0 -0
  399. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_agent_frontmatter.py +0 -0
  400. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_agents_enrichment.py +0 -0
  401. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_audit.py +0 -0
  402. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_blast_radius.py +0 -0
  403. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_board_bug027.py +0 -0
  404. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_board_sections.py +0 -0
  405. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_bug001_skill_path.py +0 -0
  406. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_bug002_plugin_paths.py +0 -0
  407. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_bug003_multi_import.py +0 -0
  408. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_bug004_dead_set.py +0 -0
  409. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_bug005_archive_taskless.py +0 -0
  410. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_bug006_scan_excludes.py +0 -0
  411. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_bug007_stale_trace_refs.py +0 -0
  412. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_bug008_stale_command_refs.py +0 -0
  413. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_bug009_project_config_backfill.py +0 -0
  414. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_bug010_rewrite_yaml.py +0 -0
  415. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_bug011_stale_refs.py +0 -0
  416. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_bug012_call_graph_filter.py +0 -0
  417. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_bug013_config_single_source.py +0 -0
  418. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_bug014_version_hygiene.py +0 -0
  419. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_bug017_project_init_playbook.py +0 -0
  420. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_bug018_issue_tracker_verification.py +0 -0
  421. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_bug019_venv_deployment.py +0 -0
  422. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_bug020_claude_md_backup.py +0 -0
  423. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_bug025_release_delegation.py +0 -0
  424. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_bug026_version_sync.py +0 -0
  425. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_bug028_ghost_refs.py +0 -0
  426. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_bug029_stack_detection_fallback.py +0 -0
  427. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_bug030_spec_lint_cli.py +0 -0
  428. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_bug031_docstring_accuracy.py +0 -0
  429. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_bug034_plan_metadata_template.py +0 -0
  430. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_bug_021.py +0 -0
  431. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_bug_022.py +0 -0
  432. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_bug_023.py +0 -0
  433. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_bug_024.py +0 -0
  434. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_bug_slim001_env_detection.py +0 -0
  435. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_bug_slim002_instruction_collision.py +0 -0
  436. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_bug_slim003.py +0 -0
  437. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_bug_slim004.py +0 -0
  438. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_bug_slim005.py +0 -0
  439. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_bug_slim006.py +0 -0
  440. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_bug_slim089_global_claude_md.py +0 -0
  441. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_check_command.py +0 -0
  442. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_check_extensions_072_073.py +0 -0
  443. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_check_playbook_072_073.py +0 -0
  444. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_command_frontmatter.py +0 -0
  445. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_command_visualize_modes.py +0 -0
  446. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_commit_gate.py +0 -0
  447. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_complexity.py +0 -0
  448. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_config.py +0 -0
  449. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_config_auto_merge.py +0 -0
  450. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_constitution_sharpening.py +0 -0
  451. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_context_gen.py +0 -0
  452. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_create_skill.py +0 -0
  453. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_cross_flow_matrix.py +0 -0
  454. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_deploy_base.py +0 -0
  455. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_deployer_cleanup.py +0 -0
  456. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_deployer_plugin.py +0 -0
  457. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_deps.py +0 -0
  458. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_design_command.py +0 -0
  459. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_done_gates.py +0 -0
  460. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_done_verify.py +0 -0
  461. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_draw_prompt.py +0 -0
  462. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_draw_references.py +0 -0
  463. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_drawio_mcp.py +0 -0
  464. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_garden.py +0 -0
  465. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_home_path_fix.py +0 -0
  466. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_hotfix_command.py +0 -0
  467. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_init_guard.py +0 -0
  468. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_init_playbook_074.py +0 -0
  469. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_interface_summary.py +0 -0
  470. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_lang_profiles.py +0 -0
  471. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_layer_violations.py +0 -0
  472. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_lessons_rotation_075.py +0 -0
  473. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_list_stories.py +0 -0
  474. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_mcp_integration.py +0 -0
  475. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_model_config.py +0 -0
  476. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_modular_constitution.py +0 -0
  477. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_monorepo_detect.py +0 -0
  478. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_multi_prefix.py +0 -0
  479. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_observe.py +0 -0
  480. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_pdca_slim.py +0 -0
  481. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_profiles.py +0 -0
  482. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_project_visibility.py +0 -0
  483. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_prompt_cli_refs.py +0 -0
  484. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_prompt_quality_075.py +0 -0
  485. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_prompt_structural_invariants.py +0 -0
  486. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_prompts_package.py +0 -0
  487. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_release.py +0 -0
  488. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_release_field.py +0 -0
  489. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_release_v110.py +0 -0
  490. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_render_prompt.py +0 -0
  491. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_report_parser.py +0 -0
  492. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_report_unified.py +0 -0
  493. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_review_command.py +0 -0
  494. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_rules_enrichment.py +0 -0
  495. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_scaffold.py +0 -0
  496. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_scaffold_developer_prefix.py +0 -0
  497. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_schemas.py +0 -0
  498. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_script_extraction.py +0 -0
  499. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_selective_deploy.py +0 -0
  500. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_session_context.py +0 -0
  501. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_skill_structure.py +0 -0
  502. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_skills_enrichment.py +0 -0
  503. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_slim_deps_088.py +0 -0
  504. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_smart_regression.py +0 -0
  505. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_solution_design_rule.py +0 -0
  506. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_sprint_command.py +0 -0
  507. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_stack_references.py +0 -0
  508. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_status_command.py +0 -0
  509. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_statusline.py +0 -0
  510. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story014_release.py +0 -0
  511. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story015_ci_lint_gate.py +0 -0
  512. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story016_claude_md.py +0 -0
  513. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story017_init_claude_md.py +0 -0
  514. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story018_arch_staleness.py +0 -0
  515. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story019_bailout.py +0 -0
  516. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story020_horizon.py +0 -0
  517. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story021_rfc.py +0 -0
  518. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story022_decision_tree.py +0 -0
  519. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story023_test_quality.py +0 -0
  520. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story024_native_agent.py +0 -0
  521. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story025_ci_pipeline.py +0 -0
  522. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story026_issue_tracker.py +0 -0
  523. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story028_rule_scoping.py +0 -0
  524. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story029_doctor.py +0 -0
  525. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story030_lint.py +0 -0
  526. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story031_git_init_guard.py +0 -0
  527. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story032_greenfield_redirect.py +0 -0
  528. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story033_config_backfill.py +0 -0
  529. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story034_plan_config_refresh.py +0 -0
  530. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story035_readme_docs.py +0 -0
  531. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story037_regression_fix.py +0 -0
  532. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story038_call_graph_update.py +0 -0
  533. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story039_venv_config.py +0 -0
  534. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story040_layered_claude_md.py +0 -0
  535. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story042_spec_linter.py +0 -0
  536. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story043_active_clarify.py +0 -0
  537. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story044_consistency_check.py +0 -0
  538. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story045_auto_pr.py +0 -0
  539. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story046_agent_adapter.py +0 -0
  540. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story047_enterprise_flags.py +0 -0
  541. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story048_worktree_isolation.py +0 -0
  542. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story049_community_standards.py +0 -0
  543. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story050_doc_only_shortcut.py +0 -0
  544. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story051_workflow_streamlining.py +0 -0
  545. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story052_conditional_github_release.py +0 -0
  546. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story053_impact_regression.py +0 -0
  547. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story055_commands.py +0 -0
  548. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story055_config.py +0 -0
  549. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story055_spec_linter.py +0 -0
  550. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story056_commands.py +0 -0
  551. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story056_config.py +0 -0
  552. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story057_implicit_cleanup.py +0 -0
  553. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story058_opencode_extraction.py +0 -0
  554. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story058_routing_fix.py +0 -0
  555. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story059_codex_removal.py +0 -0
  556. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story060_init_hang.py +0 -0
  557. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story061_remove_thinking.py +0 -0
  558. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story062_mcp_recommendations.py +0 -0
  559. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story063_prompt_slimming.py +0 -0
  560. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story064_venv_local_md.py +0 -0
  561. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story065_sprint_model.py +0 -0
  562. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story072_developer_prefix.py +0 -0
  563. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story106_lateral_scan.py +0 -0
  564. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story133_debug_skill.py +0 -0
  565. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim009_lazy_rules.py +0 -0
  566. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim010_dry_refactor.py +0 -0
  567. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim011_command_rules.py +0 -0
  568. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim014_clean.py +0 -0
  569. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim014_context.py +0 -0
  570. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim014_guard.py +0 -0
  571. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim014_lazy_viz.py +0 -0
  572. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim014_next_id.py +0 -0
  573. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim014_regression.py +0 -0
  574. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim014_sec_scope.py +0 -0
  575. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim014_validators.py +0 -0
  576. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim015_doctor.py +0 -0
  577. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim016_testmap_lint.py +0 -0
  578. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim017.py +0 -0
  579. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim018.py +0 -0
  580. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim019_plan_subphases.py +0 -0
  581. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim020_explore_stall_fix.py +0 -0
  582. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim021.py +0 -0
  583. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim022.py +0 -0
  584. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim023.py +0 -0
  585. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim024.py +0 -0
  586. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim025.py +0 -0
  587. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim026.py +0 -0
  588. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim027.py +0 -0
  589. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim028.py +0 -0
  590. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim029.py +0 -0
  591. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim030.py +0 -0
  592. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim031.py +0 -0
  593. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim032.py +0 -0
  594. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim033.py +0 -0
  595. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim034.py +0 -0
  596. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim035.py +0 -0
  597. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim036.py +0 -0
  598. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim037.py +0 -0
  599. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim038.py +0 -0
  600. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim039.py +0 -0
  601. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim040.py +0 -0
  602. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim041.py +0 -0
  603. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim042.py +0 -0
  604. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim043.py +0 -0
  605. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim044.py +0 -0
  606. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim045.py +0 -0
  607. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim046.py +0 -0
  608. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim047.py +0 -0
  609. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim048.py +0 -0
  610. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim049.py +0 -0
  611. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim051.py +0 -0
  612. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim052.py +0 -0
  613. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim053.py +0 -0
  614. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim054.py +0 -0
  615. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim055.py +0 -0
  616. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim056.py +0 -0
  617. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim060_codex_profile.py +0 -0
  618. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim063.py +0 -0
  619. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim065.py +0 -0
  620. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim076_multistack.py +0 -0
  621. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim077_monorepo_stack.py +0 -0
  622. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim078.py +0 -0
  623. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim079.py +0 -0
  624. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim080.py +0 -0
  625. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim081.py +0 -0
  626. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim082.py +0 -0
  627. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim083.py +0 -0
  628. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim084.py +0 -0
  629. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim095.py +0 -0
  630. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim098_pdca_nudge.py +0 -0
  631. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim099_act_context_ref.py +0 -0
  632. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim102_version_marker.py +0 -0
  633. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim104_should_semantics.py +0 -0
  634. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim107.py +0 -0
  635. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim109_journey_spec.py +0 -0
  636. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim111_playwright_assertion.py +0 -0
  637. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim112_rules_split.py +0 -0
  638. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim114_journey_sync.py +0 -0
  639. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim119.py +0 -0
  640. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim120.py +0 -0
  641. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim121.py +0 -0
  642. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim125.py +0 -0
  643. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim126.py +0 -0
  644. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim127_managed_block.py +0 -0
  645. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim128_engineering_concerns.py +0 -0
  646. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim132.py +0 -0
  647. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim134_no_model_in_frontmatter.py +0 -0
  648. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim135_config_schema.py +0 -0
  649. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_story_slim139_skill_manifest.py +0 -0
  650. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_tools.py +0 -0
  651. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_topology_parsers_066.py +0 -0
  652. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_update_task.py +0 -0
  653. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_visualize_call_nested.py +0 -0
  654. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_visualize_chain_fix.py +0 -0
  655. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_visualize_modes.py +0 -0
  656. {pactkit-2.17.0 → pactkit-2.18.0}/tests/unit/test_visualize_multilang_chain.py +0 -0
@@ -10,10 +10,10 @@ jobs:
10
10
  test:
11
11
  runs-on: ubuntu-latest
12
12
  steps:
13
- - uses: actions/checkout@v4
13
+ - uses: actions/checkout@v7
14
14
 
15
15
  - name: Set up Python
16
- uses: actions/setup-python@v5
16
+ uses: actions/setup-python@v7
17
17
  with:
18
18
  python-version: "3.11"
19
19
 
@@ -12,10 +12,10 @@ jobs:
12
12
  matrix:
13
13
  python-version: ["3.10", "3.11", "3.12", "3.13"]
14
14
  steps:
15
- - uses: actions/checkout@v4
15
+ - uses: actions/checkout@v7
16
16
 
17
17
  - name: Set up Python ${{ matrix.python-version }}
18
- uses: actions/setup-python@v5
18
+ uses: actions/setup-python@v7
19
19
  with:
20
20
  python-version: ${{ matrix.python-version }}
21
21
 
@@ -45,10 +45,10 @@ jobs:
45
45
  id-token: write
46
46
  contents: read
47
47
  steps:
48
- - uses: actions/checkout@v4
48
+ - uses: actions/checkout@v7
49
49
 
50
50
  - name: Set up Python
51
- uses: actions/setup-python@v5
51
+ uses: actions/setup-python@v7
52
52
  with:
53
53
  python-version: "3.12"
54
54
 
@@ -4,6 +4,15 @@ 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.18.0] - 2026-08-17
8
+
9
+ ### Added
10
+ - **Deployment manifest content hashes** (STORY-slim-141) — `write_deploy_manifest` now records a per-file sha256 under a `files` field (skills/commands-as-skills/agents/managed rules/guides; merge-semantics files like `CLAUDE.md` and user configs are structurally excluded). `pactkit doctor` deepens the parity check from component-name lists to content level: hash mismatch or missing-on-disk becomes an explicit `Content drift:` report, so "version stamp says new, content is old" deployments can no longer pass silently. Pre-2.18 manifests degrade to a warning; unreadable files and corrupted `files` fields degrade per SEC-7 and never crash doctor. Manifest keys are POSIX-normalized for cross-platform consistency.
11
+ - **Adapter version skew warning in doctor** (STORY-slim-142) — doctor now reads adapter package metadata (`pactkit-opencode` etc.) and warns when an installed adapter lags behind core, with a `pipx inject` upgrade hint. The manifest's version field is core-stamped and could never reveal adapter skew.
12
+
13
+ ### Fixed
14
+ - **`deploy(format="all", target=...)` no longer deploys adapters** (STORY-slim-142) — adapter deployers cannot honor `-t` and previously always wrote into real home dirs, which let test-suite or preview `init` calls silently overwrite live deployments (root cause of repeated `~/.config/opencode` stale-content incidents). With an explicit target, adapters are skipped with a printed notice; `target=None` behavior is unchanged.
15
+
7
16
  ## [2.17.0] - 2026-08-13
8
17
 
9
18
  ### Added
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: pactkit
3
- Version: 2.17.0
3
+ Version: 2.18.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
@@ -71,3 +71,5 @@
71
71
  | 2026-03-31 | dict.update() on call_edges causes last-wins overwrite when scanning same-name functions across files; use extend-merge pattern instead | visualize.py:_build_call_graph |
72
72
  | 2026-03-31 | CLI args must mirror visualize.py standalone argparse; feature implemented in visualize.py but not exposed in cli.py is effectively dead code | cli.py:viz_parser |
73
73
  | 2026-03-31 | tree-sitter comment nodes are direct children of function body nodes (block/statement_block), enabling scoped dispatch hint queries without parent traversal. Per-language comment query needed: Go/TS use (comment), Java uses [(line_comment)(block_comment)]. | visualize.py:_extract_calls_from_body |
74
+ | 2026-03-31 | config.py load_config() deep merge was single-level; adding check.pactguard (nested dict inside check) required upgrading to two-level merge to preserve sub-dict defaults like mode and blocking | src/pactkit/config.py:load_config |
75
+ | 2026-03-31 | Adding pactkit-garden to VALID_SKILLS broke 5 hardcoded count assertions in test_config.py, test_pdca_slim.py, test_selective_deploy.py, test_prompt_structural_invariants.py, test_story_slim063.py — grep == 21 and == 10 in tests before releasing a new skill | tests/unit/test_pdca_slim.py:test_valid_skills_count |
@@ -2,8 +2,6 @@
2
2
 
3
3
  | Date | Lesson | Context |
4
4
  |------|--------|---------|
5
- | 2026-03-31 | config.py load_config() deep merge was single-level; adding check.pactguard (nested dict inside check) required upgrading to two-level merge to preserve sub-dict defaults like mode and blocking | src/pactkit/config.py:load_config |
6
- | 2026-03-31 | Adding pactkit-garden to VALID_SKILLS broke 5 hardcoded count assertions in test_config.py, test_pdca_slim.py, test_selective_deploy.py, test_prompt_structural_invariants.py, test_story_slim063.py — grep == 21 and == 10 in tests before releasing a new skill | tests/unit/test_pdca_slim.py:test_valid_skills_count |
7
5
  | 2026-03-31 | DETECTED_ENV in commands.py init playbook was unnecessary — _render_prompt(template, profile) already resolves per-format at deploy time. Added FORMAT_NAME to deployer.py var_map to enable pactkit init --format {FORMAT_NAME}. | deployer.py:_render_prompt |
8
6
  | 2026-04-01 | Graduated safety language: retire MANDATORY keyword across prompts/commands.py, workflows.py, skills.py — use CRITICAL for safety gates (T1) and MUST for required steps (T2). Consistency prevents AI from treating all-caps keywords as equally urgent. | prompts/commands.py:MANDATORY→MUST/CRITICAL |
9
7
  | 2026-04-01 | Multi-stack visualize: _detect_stack() returning single str masks Go/TS/Java files in mixed projects; _build_class_graph hardcoded ast.parse() silently skips non-Python via except. Fix: _detect_stacks() returns list, extract_classes() ABC on all 4 analyzers. | visualize.py:_detect_stacks,_build_class_graph |
@@ -53,3 +51,5 @@
53
51
  | 2026-08-13 | guardrail 测试(行数/字符数上限)触线时,优先把组装逻辑上移到 CLI 组合层而不是抬阈值——deployer 保持精简,init/update 的副作用归 cli 编排 | cli.py:init/update post-deploy housekeeping |
54
52
  | 2026-08-13 | 配置副本同步 canonical 不能用键数启发式(默认值墙副本键数多但意图少,会覆盖手工配置),必须用显式优先级——见 config.py:sync_config_copies 的 CANONICAL_PREFERENCE | config.py:sync_config_copies |
55
53
  | 2026-08-13 | 门禁词表扫描须先剥离 code fence/inline code span(done_verify.py:_strip_code_spans),否则词表元讨论自身误报 | done_verify.py:_strip_code_spans |
54
+ | 2026-08-17 | check_deploy_parity 新增 hash 路径漏了 SEC-7 降级守卫(PermissionError/AttributeError 穿透 doctor)——Spec Security Scope 逐条自查 + 独立评审实重现能抓作者盲区 | doctor.py:check_deploy_parity |
55
+ | 2026-08-17 | deploy(format=all) 的 adapter 分支无视 target 直写真实 home——跨环境副作用必须显式审查 target/HOME 语义;测试通过 subprocess 调 CLI 时 HOME 未隔离即真实机器 | deployer.py:deploy |
@@ -15,7 +15,7 @@
15
15
 
16
16
  ## Invariants
17
17
 
18
- 1. All 4124+ tests must pass before any commit to `main`.
18
+ 1. All 4120+ 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`.
@@ -48,3 +48,20 @@
48
48
  - [x] doctor parity 检查(能力矩阵感知)
49
49
  - [x] 跨仓: pactkit-codex 消费契约+版本 bump
50
50
  - [x] 单测
51
+
52
+ ### [STORY-slim-141] Deployment manifest content hash verification
53
+ > Spec: docs/specs/STORY-slim-141.md
54
+
55
+ - [x] TDD 测试 AC1-AC6 (RED)
56
+ - [x] deploy_manifest.py: _hash_deployed_files + files 字段
57
+ - [x] doctor.py: 内容级 parity 比对 + 旧 manifest 降级
58
+ - [x] 回归 test_story_slim139
59
+
60
+ ### [STORY-slim-142] deploy format=all with target must skip adapters + adapter skew guard
61
+ > Spec: docs/specs/STORY-slim-142.md
62
+
63
+ - [x] TDD spy 测试 AC1-AC4 (RED)
64
+ - [x] deployer.py: format=all+target 跳过 adapter
65
+ - [x] doctor.py: adapter 版本偏斜 warning
66
+ - [x] 运维: 本机 adapter 升级 2.17.0
67
+ - [x] AC3 双跑全量套件验证
@@ -1,5 +1,5 @@
1
1
  # Project Context (Auto-generated)
2
- > Last updated: 2026-08-13T17:47:41+08:00 by pactkit context
2
+ > Last updated: 2026-08-17T14:59:59+08:00 by pactkit context
3
3
 
4
4
  ## Sprint Status
5
5
  Backlog: 5 | In Progress: 0 | Done: 0 stories
@@ -16,11 +16,11 @@ None
16
16
  * main
17
17
 
18
18
  ## Key Decisions
19
- - Adding project-debug required updating VALID_COMMANDS in config.py, VALID_SKILLS, COMMANDS_CONTENT registration in commands.py, and COMMAND_RULES_MAP in rules.py — plus 6 test files with hardcoded count assertions
20
- - Removing `model:` from COMMANDS_CONTENT frontmatter fixes Bedrock VS Code plugin errors — Claude Code resolves the alias to Anthropic's latest model ID, bypassing `ANTHROPIC_DEFAULT_SONNET_MODEL`; without it, commands inherit the session default model set by the user's env vars
21
19
  - guardrail 测试(行数/字符数上限)触线时,优先把组装逻辑上移到 CLI 组合层而不是抬阈值——deployer 保持精简,init/update 的副作用归 cli 编排
22
20
  - 配置副本同步 canonical 不能用键数启发式(默认值墙副本键数多但意图少,会覆盖手工配置),必须用显式优先级——见 config.py:sync_config_copies 的 CANONICAL_PREFERENCE
23
21
  - 门禁词表扫描须先剥离 code fence/inline code span(done_verify.py:_strip_code_spans),否则词表元讨论自身误报
22
+ - check_deploy_parity 新增 hash 路径漏了 SEC-7 降级守卫(PermissionError/AttributeError 穿透 doctor)——Spec Security Scope 逐条自查 + 独立评审实重现能抓作者盲区
23
+ - deploy(format=all) 的 adapter 分支无视 target 直写真实 home——跨环境副作用必须显式审查 target/HOME 语义;测试通过 subprocess 调 CLI 时 HOME 未隔离即真实机器
24
24
 
25
25
  ## Next Recommended Action
26
26
  `/project-plan`
@@ -0,0 +1,129 @@
1
+ # STORY-slim-141: Deployment manifest content hash verification
2
+
3
+ | Field | Value |
4
+ |-------|-------|
5
+ | ID | STORY-slim-141 |
6
+ | Status | Done |
7
+ | Priority | P1 |
8
+ | Release | 2.18.0 |
9
+
10
+ ## Background
11
+
12
+ 2026-08-17 实测发现:`~/.config/opencode/` 的 `.pactkit-deployed.json` 声明 `pactkit_version: 2.17.0` 且组件清单与 registry 完全一致,但 3 个已部署文件(`rules/pactkit.md`、`skills/_rules/04-architecture-principles.md`、`skills/_rules/07-engineering-concerns.md`)内容停留在旧版 —— 占位符未渲染、已排除的 project-sprint 段落仍然存在。
13
+
14
+ 根因:STORY-slim-139 的 parity check(`doctor.py:check_deploy_parity`)只比对**组件清单**(skills/commands/agents 名字列表),不校验**文件内容**。`pactkit_version` 字段记录的是部署时刻的 CLI 版本,不代表落盘内容。这造成「版本戳新、内容旧」的静默漂移。
15
+
16
+ 本 Story 将 manifest 升级为携带逐文件 sha256,doctor 的 parity check 下沉到文件内容级。
17
+
18
+ ## Requirements
19
+
20
+ ### R1: Manifest 携带逐文件内容 hash (MUST)
21
+
22
+ `write_deploy_manifest()` 在写完组件清单后,扫描 deploy_root 内所有 **pactkit 拥有的已部署文件**,计算 sha256,写入 manifest 的 `"files"` 字段:`{"<relative/path>": "<sha256 hex>"}`。
23
+
24
+ - 覆盖范围 = manifest 声明组件对应的落盘文件:`skills/{name}/**`(含 commands-as-skills)、`agents/{name}.md`、managed rules(`rules/` 及 `skills/_rules/` 下由 VALID_RULES 部署的文件)
25
+ - **MUST NOT** 哈希用户可改/合并语义的文件:`CLAUDE.md`、`AGENTS.md`、`opencode.json`、`config.toml`、`.pactkit-version`、`.pactkit-deployed.json` 自身
26
+ - 签名保持向后兼容(adapter 包 pactkit-opencode / pactkit-codex 直接调用此函数,签名变更会导致 adapter 破坏)
27
+
28
+ ### R2: doctor parity check 下沉到文件内容级 (MUST)
29
+
30
+ `check_deploy_parity()` 在组件清单比对通过后,若 manifest 含 `"files"` 字段,逐文件重新计算 sha256 并比对:
31
+
32
+ - hash 不匹配 → drift detail:`Content drift: {format} {path} — redeploy via pactkit update`
33
+ - manifest 中声明但磁盘缺失的文件 → drift detail
34
+ - 磁盘比对 MUST 在报告前完成全部文件扫描(不因首个 mismatch 短路,一次报告所有漂移文件)
35
+
36
+ ### R3: 向后兼容旧 manifest (MUST)
37
+
38
+ manifest 缺少 `"files"` 字段(pre-2.18 部署)→ 降级为 warning(`re-run pactkit update to enable content verification`),**不计入 drift**、不影响 doctor 退出码语义(与现有 missing-manifest 行为一致)。
39
+
40
+ ### R4: 用户追加内容不产生误报 (MUST)
41
+
42
+ 用户在 `CLAUDE.md` 等合并语义文件中的追加内容 MUST NOT 触发 content drift(由 R1 的排除清单保证)。用户修改 pactkit 拥有的文件(如 `rules/pactkit.md`)SHOULD 被报告为 drift —— 这是特性而非误报(提示用户改动将在下次 update 被覆盖)。
43
+
44
+ ### R5: 确定性 (MUST)
45
+
46
+ hash 计算 MUST 为纯代码实现(sha256,hex digest),禁止 LLM 判断参与比对(Code Enforces, Prompt Instructs)。文件读取使用 bytes 模式避免编码差异。
47
+
48
+ ## Acceptance Criteria
49
+
50
+ ### AC1: 部署后 manifest 包含逐文件 hash (R1, R5)
51
+
52
+ - **Given** 一个干净的 deploy target 目录
53
+ - **When** 执行 `pactkit init -t <dir> --format classic --no-git --no-external --non-interactive`
54
+ - **Then** `<dir>/.pactkit-deployed.json` 含 `"files"` 字段,覆盖所有 pactkit 拥有的落盘文件(skills/commands/agents/managed rules),每个值为 64 位 hex sha256,且不含 `CLAUDE.md`、`.pactkit-version`、`.pactkit-deployed.json`
55
+
56
+ ### AC2: 内容漂移被 doctor 检出 (R2)
57
+
58
+ - **Given** 已完成部署且 manifest 含 `"files"`
59
+ - **When** 手工篡改一个 pactkit 拥有的已部署文件(如 `rules/pactkit.md` 追加一行)后运行 `pactkit doctor`
60
+ - **Then** 输出包含该文件路径的 `Content drift` detail,doctor 退出码为 1(NEEDS ATTENTION)
61
+
62
+ ### AC3: 未漂移时 doctor 不误报 (R2, R4)
63
+
64
+ - **Given** 部署后未改动任何 pactkit 文件,仅在 `CLAUDE.md` 末尾追加用户内容
65
+ - **When** 运行 `pactkit doctor`
66
+ - **Then** 无 `Content drift` 输出(parity 部分不产生 issue)
67
+
68
+ ### AC4: 旧版 manifest 降级为 warning (R3)
69
+
70
+ - **Given** 一个不含 `"files"` 字段的 `.pactkit-deployed.json`(模拟 pre-2.18 部署)
71
+ - **When** 运行 `pactkit doctor`
72
+ - **Then** 输出 warning 提示重新部署以启用内容校验,且不计入 drift、不影响退出码
73
+
74
+ ### AC5: 声明文件在磁盘缺失被检出 (R2)
75
+
76
+ - **Given** 部署完成后删除一个 manifest 声明的文件(如 `skills/pactkit-board/SKILL.md`)
77
+ - **When** 运行 `pactkit doctor`
78
+ - **Then** 输出该文件缺失的 drift detail,退出码为 1
79
+
80
+ ### AC6: adapter 签名兼容 (R1)
81
+
82
+ - **Given** 现有 `write_deploy_manifest(deploy_root, format_name, config)` 调用方(core deployer + 外部 adapter 包)
83
+ - **When** 本 Story 完成后
84
+ - **Then** 函数签名不变,adapter 无需修改即可获得 hash 能力(纯内部行为增强)
85
+
86
+ ## Target Call Chain
87
+
88
+ ```
89
+ pactkit init/update
90
+ └─ cli.py → generators/deployer.py:_deploy_classic() (及各 format deployer)
91
+ └─ deploy_manifest.py:write_deploy_manifest(deploy_root, format, config) ← R1 修改点
92
+ └─ NEW: _hash_deployed_files(deploy_root, components) → {"files": {...}}
93
+
94
+ pactkit doctor
95
+ └─ cli.py:767 → doctor.py:check_deploy_parity(project_root) ← R2 修改点
96
+ ├─ 现有: expected_components() 清单比对
97
+ └─ NEW: manifest["files"] 逐文件 sha256 比对 ← R3 兼容分支
98
+ ```
99
+
100
+ Adapter 调用链(外部 repo,签名兼容由 R1 保证):`pactkit-opencode/pactkit-codex → write_deploy_manifest()`
101
+
102
+ ## Implementation Steps
103
+
104
+ | Step | File | Action | Dependencies | Risk |
105
+ |------|------|--------|-------------|------|
106
+ | 1 | `tests/unit/test_story_slim141_manifest_hash.py` | 新建:AC1-AC6 的 TDD 测试(RED) | None | Low |
107
+ | 2 | `src/pactkit/deploy_manifest.py` | 新增 `_hash_deployed_files()` + 排除清单常量;`write_deploy_manifest` 写入 `files` 字段 | Step 1 | Low |
108
+ | 3 | `src/pactkit/doctor.py` | `check_deploy_parity` 增加 files 比对分支 + 旧 manifest warning 分支 | Step 2 | Medium — 勿破坏现有清单比对与 SEC-2/SEC-7 降级行为 |
109
+ | 4 | `tests/unit/test_story_slim139_skill_manifest.py` | 回归:现有 parity 测试不受影响 | Step 3 | Low |
110
+
111
+ ## Security Scope
112
+
113
+ | Check | Applicable | Reason |
114
+ |-------|------------|--------|
115
+ | SEC-1 | Yes | 修改 source code(deploy_manifest.py, doctor.py) |
116
+ | SEC-2 | No | 无用户输入处理(hash 对象为部署器自身产物) |
117
+ | SEC-3 | No | 无数据库 |
118
+ | SEC-4 | No | 无前端 |
119
+ | SEC-5 | No | 无认证逻辑 |
120
+ | SEC-6 | No | 无 API/路由 |
121
+ | SEC-7 | Yes | manifest JSON 损坏/文件不可读时必须降级为 warning(沿用现有 SEC-7 try/except 模式),禁止 crash doctor |
122
+ | SEC-8 | No | 无依赖变更(hashlib 为标准库) |
123
+
124
+ ## Out of Scope
125
+
126
+ - adapter 包(pactkit-opencode / pactkit-codex / pactkit-copilot)的发布与重部署 —— 它们自动继承 core 的新 manifest 行为
127
+ - 对历史已部署目录的批量修复(由用户在下次 `pactkit update` 时自然获得)
128
+ - `CLAUDE.md` / `AGENTS.md` 等合并语义文件的内容校验(结构上无法区分 pactkit 段与用户追加段)
129
+ - 部署性能优化(hash 扫描为 O(文件数),pactkit 文件约 100 个,无需优化)
@@ -0,0 +1,120 @@
1
+ # STORY-slim-142: deploy format=all with target must skip adapters + adapter skew guard
2
+
3
+ | Field | Value |
4
+ |-------|-------|
5
+ | ID | STORY-slim-142 |
6
+ | Status | Done |
7
+ | Priority | P1 |
8
+ | Release | 2.18.0 |
9
+
10
+ ## Background
11
+
12
+ 2026-08-17,STORY-slim-141 的内容级 parity check 在 commit gate 实战中检出真实漂移,二分定位出完整污染链:
13
+
14
+ 1. `tests/unit/test_story_slim056.py` 中 `test_unicode_project_path` 等测试调用 `pactkit init -t <tmp>`(默认 `format=all`)
15
+ 2. `deploy(format="all")` 遍历 `_DEPLOYER_REGISTRY`,其中 `fmt_target = target if fmt_name == "classic" else None`(`deployer.py:~285`)—— **adapter 格式无视 `-t`,永远部署到真实 home**(`~/.config/opencode`)
16
+ 3. 本机安装的 `pactkit-opencode` 是 **2.9.1**(repo 源已 2.17.0):渲染逻辑陈旧(占位符未解析、project-sprint 未排除),且不调用 `write_deploy_manifest`(slim-139 时还未发布)
17
+ 4. 结果:每次全量测试跑完,真实 opencode 部署被 2.9.1 陈旧内容覆盖且 manifest 不更新 → 下一次 `doctor` 必报 content drift → `test_doctor_runs` 对同文件内执行顺序产生隐式依赖(pass 留给别人,fail 留给自己)
18
+
19
+ 这同时解释了 2026-08-13 发布日后的首次漂移事件(同签名:占位符 + sprint 段落)。
20
+
21
+ ## Requirements
22
+
23
+ ### R1: format=all + 显式 target 时跳过 adapter 部署 (MUST)
24
+
25
+ `deploy(format="all", target=<非None>)` 时,MUST 跳过所有 adapter 格式(opencode/codex/copilot 等非 classic),并打印一行说明:`Skipping adapter formats (…): -t target only applies to classic`。
26
+
27
+ 理由:adapter deployer 不接受 target(永远写各自默认 home 目录),带 target 的调用语义是"预览/测试",把内容写进用户真实 home 在任何场景下都是错的。此改动从污染源头根治——**不需要修改任何现有测试**(遵守 Pre-existing Test Protocol),`test_unicode_project_path` 等自动获得隔离。
28
+
29
+ `target=None` 的真实 init/update 行为 MUST 保持不变(adapter 正常部署到各自 home)。
30
+
31
+ ### R2: 回归测试——target 模式零 home 副作用 (MUST)
32
+
33
+ 新增测试验证:注册一个 spy adapter deployer 后调用 `deploy(format="all", target=tmp_path)`:
34
+
35
+ - spy adapter 的 `deploy()` MUST NOT 被调用
36
+ - classic 内容正确部署到 tmp_path
37
+ - 输出含跳过说明
38
+
39
+ ### R3: doctor 报告 adapter 与 core 的版本偏斜 (SHOULD)
40
+
41
+ `pactkit doctor` 增加 adapter 包版本检查:通过 `importlib.metadata.version("pactkit-opencode")` 等读取已装 adapter 版本,major.minor 落后于 core `pactkit.__version__` 时输出 warning(含升级提示 `pipx inject pactkit pactkit-opencode==X`)。warning 不计入 drift、不影响退出码。
42
+
43
+ 理由:本次事故的 root cause 是 adapter 2.9.1 配 core 2.17.0;manifest 的 `pactkit_version` 字段由 core 生成,无法反映 adapter 自身版本,必须直接读包元数据。
44
+
45
+ ### R4: 向后兼容 (MUST)
46
+
47
+ - `deploy()` 签名不变;`format="all", target=None` 行为完全不变
48
+ - 现有测试(含 slim056 全套)MUST NOT 修改,且修复后全量套件通过
49
+
50
+ ## Acceptance Criteria
51
+
52
+ ### AC1: target 模式跳过 adapter (R1)
53
+
54
+ - **Given** 已安装 pactkit-opencode adapter(registry 含 opencode)
55
+ - **When** 调用 `deploy(format="all", target=tmp_path)`(或 CLI `pactkit init -t <dir>` 默认 format=all)
56
+ - **Then** adapter 的 deploy() 不被调用,`~/.config/opencode` 内容零变化,输出含跳过说明,classic 正常部署到 tmp_path
57
+
58
+ ### AC2: 真实 init 行为不变 (R1, R4)
59
+
60
+ - **Given** 同上环境
61
+ - **When** 调用 `deploy(format="all")`(target=None)
62
+ - **Then** classic + 所有已注册 adapter 均正常部署到各自默认目录
63
+
64
+ ### AC3: 全量套件自洁 (R1, R2, R4)
65
+
66
+ - **Given** opencode 部署处于干净状态(doctor 无 content drift)
67
+ - **When** 连续运行两次全量 `pytest tests/unit/`
68
+ - **Then** 两次均全绿(含 `test_story_slim056.py::TestDoctorCommand::test_doctor_runs` 单测独立运行也通过)
69
+
70
+ ### AC4: adapter 版本偏斜 warning (R3)
71
+
72
+ - **Given** 安装的 pactkit-opencode 版本落后于 core(如 2.9.1 vs 2.17.0)
73
+ - **When** 运行 `pactkit doctor`
74
+ - **Then** 输出含版本偏斜 warning 与升级提示,且退出码语义不变(不计入 drift)
75
+
76
+ ## Target Call Chain
77
+
78
+ ```
79
+ pactkit init -t <dir> (CLI 默认 format=all)
80
+ └─ cli.py → deployer.py:deploy(format="all", target=<dir>)
81
+ └─ for fmt in _DEPLOYER_REGISTRY: ← R1 修改点
82
+ fmt_target = target if fmt == "classic" else None ← BUG: adapter 无视 target
83
+ → R1: target 非 None 且 fmt != classic → skip + 提示
84
+
85
+ pactkit doctor
86
+ └─ doctor.py:check_deps() 附近 ← R3 新增点
87
+ └─ importlib.metadata.version("pactkit-opencode") vs pactkit.__version__
88
+ ```
89
+
90
+ 污染链实证(2026-08-17):`test_unicode_project_path` → `run_pactkit("init", "-t", tmp)` → format=all → adapter 2.9.1 写 `~/.config/opencode`(陈旧渲染、不写 manifest)→ slim-141 parity 检出 drift。
91
+
92
+ ## Implementation Steps
93
+
94
+ | Step | File | Action | Dependencies | Risk |
95
+ |------|------|--------|-------------|------|
96
+ | 1 | `tests/unit/test_story_slim142_all_target_isolation.py` | 新建:AC1/AC2 spy deployer 测试(RED) | None | Low |
97
+ | 2 | `src/pactkit/generators/deployer.py` | `deploy(format="all")` 分支:target 非 None 时跳过 adapter + 提示 | Step 1 | Medium — 勿影响 target=None 主路径 |
98
+ | 3 | `src/pactkit/doctor.py` | adapter 版本偏斜检查(importlib.metadata) | None | Low |
99
+ | 4 | 运维(非代码) | 本机升级 adapter:`pipx inject pactkit <path-to-pactkit-opencode>` + `.venv` 同步升级,验证 doctor 无 drift | Step 2 合并后 | Low |
100
+ | 5 | 回归 | 连续两次全量套件 + slim056 单测独立运行(AC3) | Step 2, 4 | Low |
101
+
102
+ ## Security Scope
103
+
104
+ | Check | Applicable | Reason |
105
+ |-------|------------|--------|
106
+ | SEC-1 | Yes | 修改 source code(deployer.py, doctor.py) |
107
+ | SEC-2 | No | 无外部输入解析(target 为既有参数) |
108
+ | SEC-3 | No | 无数据库 |
109
+ | SEC-4 | No | 无前端 |
110
+ | SEC-5 | Yes | sec-scope 命中 auth/session 模式(deployer 含 token 相关字串)——本次改动不触碰凭据逻辑,仅需确认跳过逻辑不影响 MCP/凭据部署提示 |
111
+ | SEC-6 | No | 无 API/路由 |
112
+ | SEC-7 | Yes | importlib.metadata.PackageNotFoundError(adapter 未安装)必须静默跳过,不得 crash doctor |
113
+ | SEC-8 | No | 无新依赖(importlib.metadata 为标准库) |
114
+
115
+ ## Out of Scope
116
+
117
+ - adapter 包(pactkit-opencode 2.9.1 → 2.17.0)的版本升级本身 —— 属运维动作(Step 4),不改 adapter 仓库代码
118
+ - adapter deployer 支持自定义 target 的能力(如需 preview adapter 部署,另立 story)
119
+ - 测试套件的全面 HOME 隔离改造(R1 从源头消除污染向量后,slim056 无需修改;其余测试若有个案另议)
120
+ - `test_doctor_runs` 对真实机器状态的隐性依赖重构 —— R1 修复后该测试恢复确定性,不追求完美隔离
@@ -0,0 +1,76 @@
1
+ # Test Case: STORY-slim-141 — Deployment manifest content hash verification
2
+
3
+ > Spec: docs/specs/STORY-slim-141.md
4
+ > Unit tests: tests/unit/test_story_slim141_manifest_hash.py (11 tests)
5
+
6
+ ## AC1: 部署后 manifest 包含逐文件 hash (R1, R5)
7
+
8
+ ```gherkin
9
+ Given 一个干净的 deploy target 目录
10
+ When 执行 pactkit init 部署 classic format
11
+ Then .pactkit-deployed.json 含 "files" 字段
12
+ And 覆盖 skills/commands/agents/managed rules 的落盘文件
13
+ And 每个值为 64 位小写 hex sha256
14
+ And 不含 CLAUDE.md / .pactkit-version / .pactkit-deployed.json
15
+ ```
16
+ Verified by: TestManifestFiles::test_write_includes_files_hash, test_hash_is_sha256_hex, test_manifest_keys_are_posix
17
+
18
+ ## AC2: 内容漂移被 doctor 检出 (R2)
19
+
20
+ ```gherkin
21
+ Given 已完成部署且 manifest 含 "files"
22
+ When 篡改 rules/pactkit.md 后运行 parity 检查
23
+ Then drift 为 True 且 details 包含该文件路径
24
+ And 退出码语义为 NEEDS ATTENTION(drift → doctor exit 1,由 slim-139 测试覆盖 wiring)
25
+ ```
26
+ Verified by: TestContentParity::test_content_drift_detected, test_multi_drift_no_short_circuit
27
+
28
+ ## AC3: 未漂移时 doctor 不误报 (R2, R4)
29
+
30
+ ```gherkin
31
+ Given 部署后未改动任何 pactkit 文件
32
+ When 仅在 CLAUDE.md 末尾追加用户内容并运行 parity 检查
33
+ Then drift 为 False,无 Content drift 输出
34
+ ```
35
+ Verified by: TestContentParity::test_no_false_positive_on_excluded_append
36
+
37
+ ## AC4: 旧版 manifest 降级为 warning (R3)
38
+
39
+ ```gherkin
40
+ Given 一个不含 "files" 字段的 pre-2.18 manifest
41
+ When 运行 parity 检查
42
+ Then drift 为 False
43
+ And warnings 包含 "content verification" 提示
44
+ ```
45
+ Verified by: TestContentParity::test_old_manifest_without_files_warns
46
+
47
+ ## AC5: 声明文件在磁盘缺失被检出 (R2)
48
+
49
+ ```gherkin
50
+ Given 部署完成且 manifest 含 "files"
51
+ When 删除 manifest 声明的 skills/pactkit-board/SKILL.md
52
+ Then drift 为 True 且 details 包含 "missing on disk"
53
+ ```
54
+ Verified by: TestContentParity::test_missing_declared_file_detected
55
+
56
+ ## AC6: adapter 签名兼容 (R1)
57
+
58
+ ```gherkin
59
+ Given 现有 write_deploy_manifest(deploy_root, format_name, config) 调用方
60
+ When 本 Story 完成后以位置参数调用
61
+ Then 函数签名不变,返回 manifest Path 且 payload 含 files 字段
62
+ ```
63
+ Verified by: TestManifestFiles::test_signature_unchanged
64
+
65
+ ## SEC-7 补充场景(评审后新增)
66
+
67
+ ```gherkin
68
+ Given manifest 声明的文件被 chmod 0(不可读)
69
+ When 运行 parity 检查
70
+ Then 降级为 warning("unreadable"),不 crash,drift 不受影响
71
+
72
+ Given manifest 的 "files" 字段类型损坏(list 而非 dict)
73
+ When 运行 parity 检查
74
+ Then 降级为 warning("corrupt"),不 crash
75
+ ```
76
+ Verified by: test_unreadable_file_warns_not_crashes, test_corrupt_files_field_warns_not_crashes
@@ -0,0 +1,46 @@
1
+ # Test Case: STORY-slim-142 — deploy format=all with target skips adapters + adapter skew guard
2
+
3
+ > Spec: docs/specs/STORY-slim-142.md
4
+ > Unit tests: tests/unit/test_story_slim142_all_target_isolation.py (6 tests)
5
+
6
+ ## AC1: target 模式跳过 adapter (R1)
7
+
8
+ ```gherkin
9
+ Given registry 中含 classic + opencode(spy deployer)
10
+ When 调用 deploy(format="all", target=tmp_path)
11
+ Then classic 以 target=tmp_path 调用
12
+ And adapter deploy() 从未被调用
13
+ And 输出含 "Skipping adapter formats (opencode): -t target only applies to classic"
14
+ ```
15
+ Verified by: TestAllTargetSkipsAdapters::test_adapter_not_called_when_target_given
16
+
17
+ ## AC2: 真实 init 行为不变 (R1, R4)
18
+
19
+ ```gherkin
20
+ Given 同上 spy registry
21
+ When 调用 deploy(format="all", target=None)
22
+ Then classic 与 opencode 均以 target=None 被调用(各自部署到默认目录)
23
+ ```
24
+ Verified by: TestAllTargetSkipsAdapters::test_adapter_called_when_no_target
25
+
26
+ ## AC3: 全量套件自洁 (R1, R2, R4)
27
+
28
+ ```gherkin
29
+ Given opencode 部署处于干净状态(doctor 无 content drift)
30
+ When 连续运行两次全量 pytest tests/unit/
31
+ Then 两次均全绿(4120 passed)
32
+ And 两次运行之间 opencode manifest 与磁盘零漂移
33
+ And test_story_slim056.py::TestDoctorCommand::test_doctor_runs 独立运行通过
34
+ ```
35
+ Verified by: 2026-08-17 Act Phase 3 实测(双跑 + drift check NONE + 单测独立通过)
36
+
37
+ ## AC4: adapter 版本偏斜 warning (R3)
38
+
39
+ ```gherkin
40
+ Given 安装的 pactkit-opencode 为 2.9.1 而 core 为 2.17.0
41
+ When 调用 check_adapter_skew()
42
+ Then 返回含包名、双版本号与 pipx inject 升级提示的 warning
43
+ And adapter 版本与 core 一致时静默(空列表)
44
+ And adapter 未安装 / 元数据缺失时静默不 crash(SEC-7)
45
+ ```
46
+ Verified by: TestAdapterSkew 4 tests(outdated/current/missing/no-entry-points)
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "pactkit"
7
- version = "2.17.0"
7
+ version = "2.18.0"
8
8
  description = "Spec-driven agentic DevOps toolkit for AI coding assistants"
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -1,3 +1,3 @@
1
1
  """PactKit - Spec-driven agentic DevOps toolkit."""
2
2
 
3
- __version__ = "2.17.0"
3
+ __version__ = "2.18.0"
@@ -773,6 +773,12 @@ def main():
773
773
  for warning in parity["warnings"]:
774
774
  print(f" ⚠️ {warning}")
775
775
 
776
+ # STORY-slim-142 R3: adapter package version skew (report-only)
777
+ from pactkit.doctor import check_adapter_skew
778
+
779
+ for warning in check_adapter_skew():
780
+ print(f" ⚠️ {warning}")
781
+
776
782
  if not has_issues:
777
783
  print("Health: OK")
778
784
  else: