@opengsd/gsd-path 1.0.0 → 1.1.0

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 (395) hide show
  1. package/AGENTS.md +28 -11
  2. package/DOCS.md +6 -5
  3. package/FULL.md +9 -13
  4. package/QUICK.md +3 -3
  5. package/README.md +151 -14
  6. package/RUNTIME.md +7 -1
  7. package/WORKFLOW.md +30 -14
  8. package/package.json +15 -1
  9. package/platforms/shared-agents/dispatch.md +6 -0
  10. package/scripts/archive_milestone.py +10 -118
  11. package/scripts/bootstrap_repository.py +25 -3
  12. package/scripts/build_recovery.py +287 -0
  13. package/scripts/check_docs_audit.py +5 -3
  14. package/scripts/check_handoffs.py +1 -1
  15. package/scripts/detect_project.py +11 -2
  16. package/scripts/dispatch_driver.py +4 -2
  17. package/scripts/git_guard.py +2 -1
  18. package/scripts/install.mjs +2 -0
  19. package/scripts/install.py +2 -0
  20. package/scripts/integration.py +28 -22
  21. package/scripts/isolation.py +9 -1
  22. package/scripts/lean_verification.py +1 -1
  23. package/scripts/pipeline_diagnose.py +12 -3
  24. package/scripts/pipeline_state.py +114 -186
  25. package/scripts/pipeline_undo.py +11 -7
  26. package/scripts/promote_lookahead.py +30 -162
  27. package/scripts/roadmap.py +321 -0
  28. package/scripts/skill-resources.json +79 -1
  29. package/scripts/state_checkpoint.py +109 -72
  30. package/scripts/state_promote.py +42 -44
  31. package/scripts/task_context.py +73 -0
  32. package/scripts/token_budget.py +40 -1
  33. package/scripts/workflow_run.py +116 -7
  34. package/skills/gsd-path/BUILD.md +47 -575
  35. package/skills/gsd-path/DECIDE.md +2 -6
  36. package/skills/gsd-path/DEFINE.md +10 -14
  37. package/skills/gsd-path/INSPECT.md +30 -8
  38. package/skills/gsd-path/PLAN.md +25 -17
  39. package/skills/gsd-path/RESEARCH.md +3 -6
  40. package/skills/gsd-path/ROADMAP.md +22 -58
  41. package/skills/gsd-path/SHIP.md +5 -4
  42. package/skills/gsd-path/SKILL.md +24 -14
  43. package/skills/gsd-path/references/build-abandon.md +33 -0
  44. package/skills/gsd-path/references/build-native.md +494 -0
  45. package/skills/gsd-path/references/build-recovery.md +78 -0
  46. package/skills/gsd-path/references/coder.md +8 -3
  47. package/skills/gsd-path/references/dispatch.md +6 -0
  48. package/skills/gsd-path/references/docs-auditor.md +14 -0
  49. package/skills/gsd-path/references/reviewer-final.md +21 -0
  50. package/skills/gsd-path/references/reviewer-panel.md +17 -0
  51. package/skills/gsd-path/references/reviewer-skeptic.md +20 -0
  52. package/skills/gsd-path/references/reviewer-wave.md +89 -0
  53. package/skills/gsd-path/references/reviewer.md +12 -150
  54. package/skills/gsd-path/scripts/__pycache__/_common.cpython-312.pyc +0 -0
  55. package/skills/gsd-path/scripts/__pycache__/archive_milestone.cpython-312.pyc +0 -0
  56. package/skills/gsd-path/scripts/__pycache__/build_recovery.cpython-312.pyc +0 -0
  57. package/skills/gsd-path/scripts/__pycache__/build_state.cpython-312.pyc +0 -0
  58. package/skills/gsd-path/scripts/__pycache__/check_handoffs.cpython-312.pyc +0 -0
  59. package/skills/gsd-path/scripts/__pycache__/check_task_briefs.cpython-312.pyc +0 -0
  60. package/skills/gsd-path/scripts/__pycache__/detect_project.cpython-312.pyc +0 -0
  61. package/skills/gsd-path/scripts/__pycache__/discussion_records.cpython-312.pyc +0 -0
  62. package/skills/gsd-path/scripts/__pycache__/discussion_validate.cpython-312.pyc +0 -0
  63. package/skills/gsd-path/scripts/__pycache__/integration.cpython-312.pyc +0 -0
  64. package/skills/gsd-path/scripts/__pycache__/isolation.cpython-312.pyc +0 -0
  65. package/skills/gsd-path/scripts/__pycache__/loop_run.cpython-312.pyc +0 -0
  66. package/skills/gsd-path/scripts/__pycache__/pipeline_git.cpython-312.pyc +0 -0
  67. package/skills/gsd-path/scripts/__pycache__/pipeline_state.cpython-312.pyc +0 -0
  68. package/skills/gsd-path/scripts/__pycache__/review_findings.cpython-312.pyc +0 -0
  69. package/skills/gsd-path/scripts/__pycache__/review_panel.cpython-312.pyc +0 -0
  70. package/skills/gsd-path/scripts/__pycache__/roadmap.cpython-312.pyc +0 -0
  71. package/skills/gsd-path/scripts/__pycache__/state_checkpoint.cpython-312.pyc +0 -0
  72. package/skills/gsd-path/scripts/__pycache__/task_context.cpython-312.pyc +0 -0
  73. package/skills/gsd-path/scripts/__pycache__/workflow_run.cpython-312.pyc +0 -0
  74. package/skills/gsd-path/scripts/archive_milestone.py +10 -118
  75. package/skills/gsd-path/scripts/bootstrap_repository.py +25 -3
  76. package/skills/gsd-path/scripts/build_recovery.py +287 -0
  77. package/skills/gsd-path/scripts/check_docs_audit.py +5 -3
  78. package/skills/gsd-path/scripts/check_handoffs.py +1 -1
  79. package/skills/gsd-path/scripts/detect_project.py +11 -2
  80. package/skills/gsd-path/scripts/dispatch_driver.py +4 -2
  81. package/skills/gsd-path/scripts/integration.py +28 -22
  82. package/skills/gsd-path/scripts/isolation.py +9 -1
  83. package/skills/gsd-path/scripts/lean_verification.py +1 -1
  84. package/skills/gsd-path/scripts/pipeline_state.py +114 -186
  85. package/skills/gsd-path/scripts/promote_lookahead.py +30 -162
  86. package/skills/gsd-path/scripts/roadmap.py +321 -0
  87. package/skills/gsd-path/scripts/state_checkpoint.py +109 -72
  88. package/skills/gsd-path/scripts/state_promote.py +42 -44
  89. package/skills/gsd-path/scripts/task_context.py +73 -0
  90. package/skills/gsd-path/scripts/token_budget.py +40 -1
  91. package/skills/gsd-path/scripts/workflow_run.py +116 -7
  92. package/skills/gsd-path/templates/wave-review.md +1 -1
  93. package/skills/gsd-path-build/SKILL.md +47 -575
  94. package/skills/gsd-path-build/references/build-abandon.md +33 -0
  95. package/skills/gsd-path-build/references/build-native.md +494 -0
  96. package/skills/gsd-path-build/references/build-recovery.md +78 -0
  97. package/skills/gsd-path-build/references/coder.md +8 -3
  98. package/skills/gsd-path-build/references/dispatch.md +6 -0
  99. package/skills/gsd-path-build/references/reviewer-final.md +21 -0
  100. package/skills/gsd-path-build/references/reviewer-panel.md +17 -0
  101. package/skills/gsd-path-build/references/reviewer-skeptic.md +20 -0
  102. package/skills/gsd-path-build/references/reviewer-wave.md +89 -0
  103. package/skills/gsd-path-build/references/reviewer.md +12 -150
  104. package/skills/gsd-path-build/scripts/__pycache__/_common.cpython-312.pyc +0 -0
  105. package/skills/gsd-path-build/scripts/__pycache__/archive_milestone.cpython-312.pyc +0 -0
  106. package/skills/gsd-path-build/scripts/__pycache__/build_recovery.cpython-312.pyc +0 -0
  107. package/skills/gsd-path-build/scripts/__pycache__/build_state.cpython-312.pyc +0 -0
  108. package/skills/gsd-path-build/scripts/__pycache__/check_handoffs.cpython-312.pyc +0 -0
  109. package/skills/gsd-path-build/scripts/__pycache__/check_task_briefs.cpython-312.pyc +0 -0
  110. package/skills/gsd-path-build/scripts/__pycache__/detect_project.cpython-312.pyc +0 -0
  111. package/skills/gsd-path-build/scripts/__pycache__/discussion_validate.cpython-312.pyc +0 -0
  112. package/skills/gsd-path-build/scripts/__pycache__/isolation.cpython-312.pyc +0 -0
  113. package/skills/gsd-path-build/scripts/__pycache__/loop_run.cpython-312.pyc +0 -0
  114. package/skills/gsd-path-build/scripts/__pycache__/pipeline_git.cpython-312.pyc +0 -0
  115. package/skills/gsd-path-build/scripts/__pycache__/pipeline_state.cpython-312.pyc +0 -0
  116. package/skills/gsd-path-build/scripts/__pycache__/review_findings.cpython-312.pyc +0 -0
  117. package/skills/gsd-path-build/scripts/__pycache__/review_panel.cpython-312.pyc +0 -0
  118. package/skills/gsd-path-build/scripts/__pycache__/roadmap.cpython-312.pyc +0 -0
  119. package/skills/gsd-path-build/scripts/__pycache__/state_checkpoint.cpython-312.pyc +0 -0
  120. package/skills/gsd-path-build/scripts/__pycache__/task_context.cpython-312.pyc +0 -0
  121. package/skills/gsd-path-build/scripts/__pycache__/workflow_run.cpython-312.pyc +0 -0
  122. package/skills/gsd-path-build/scripts/archive_milestone.py +10 -118
  123. package/skills/gsd-path-build/scripts/build_recovery.py +287 -0
  124. package/skills/gsd-path-build/scripts/check_handoffs.py +1 -1
  125. package/skills/gsd-path-build/scripts/detect_project.py +1526 -0
  126. package/skills/gsd-path-build/scripts/dispatch_driver.py +4 -2
  127. package/skills/gsd-path-build/scripts/integration.py +28 -22
  128. package/skills/gsd-path-build/scripts/isolation.py +9 -1
  129. package/skills/gsd-path-build/scripts/pipeline_state.py +114 -186
  130. package/skills/gsd-path-build/scripts/promote_lookahead.py +283 -0
  131. package/skills/gsd-path-build/scripts/roadmap.py +321 -0
  132. package/skills/gsd-path-build/scripts/state_checkpoint.py +109 -72
  133. package/skills/gsd-path-build/scripts/state_promote.py +42 -44
  134. package/skills/gsd-path-build/scripts/task_context.py +73 -0
  135. package/skills/gsd-path-build/scripts/token_budget.py +40 -1
  136. package/skills/gsd-path-build/scripts/workflow_run.py +116 -7
  137. package/skills/gsd-path-build/templates/wave-review.md +1 -1
  138. package/skills/gsd-path-decide/SKILL.md +2 -6
  139. package/skills/gsd-path-decide/references/dispatch.md +6 -0
  140. package/skills/gsd-path-decide/scripts/__pycache__/_common.cpython-312.pyc +0 -0
  141. package/skills/gsd-path-decide/scripts/__pycache__/archive_milestone.cpython-312.pyc +0 -0
  142. package/skills/gsd-path-decide/scripts/__pycache__/detect_project.cpython-312.pyc +0 -0
  143. package/skills/gsd-path-decide/scripts/__pycache__/discussion_validate.cpython-312.pyc +0 -0
  144. package/skills/gsd-path-decide/scripts/__pycache__/isolation.cpython-312.pyc +0 -0
  145. package/skills/gsd-path-decide/scripts/__pycache__/pipeline_git.cpython-312.pyc +0 -0
  146. package/skills/gsd-path-decide/scripts/__pycache__/pipeline_state.cpython-312.pyc +0 -0
  147. package/skills/gsd-path-decide/scripts/__pycache__/review_panel.cpython-312.pyc +0 -0
  148. package/skills/gsd-path-decide/scripts/__pycache__/roadmap.cpython-312.pyc +0 -0
  149. package/skills/gsd-path-decide/scripts/__pycache__/state_checkpoint.cpython-312.pyc +0 -0
  150. package/skills/gsd-path-decide/scripts/archive_milestone.py +2157 -0
  151. package/skills/gsd-path-decide/scripts/build_recovery.py +287 -0
  152. package/skills/gsd-path-decide/scripts/check_handoffs.py +1 -1
  153. package/skills/gsd-path-decide/scripts/detect_project.py +1526 -0
  154. package/skills/gsd-path-decide/scripts/discussion_validate.py +1321 -0
  155. package/skills/gsd-path-decide/scripts/integration.py +1439 -0
  156. package/skills/gsd-path-decide/scripts/isolation.py +9 -1
  157. package/skills/gsd-path-decide/scripts/pipeline_state.py +114 -186
  158. package/skills/gsd-path-decide/scripts/promote_lookahead.py +283 -0
  159. package/skills/gsd-path-decide/scripts/review_panel.py +553 -0
  160. package/skills/gsd-path-decide/scripts/roadmap.py +321 -0
  161. package/skills/gsd-path-decide/scripts/state_checkpoint.py +109 -72
  162. package/skills/gsd-path-decide/scripts/state_promote.py +42 -44
  163. package/skills/gsd-path-define/SKILL.md +10 -14
  164. package/skills/gsd-path-define/references/build-recovery.md +78 -0
  165. package/skills/gsd-path-define/scripts/__pycache__/_common.cpython-312.pyc +0 -0
  166. package/skills/gsd-path-define/scripts/__pycache__/archive_milestone.cpython-312.pyc +0 -0
  167. package/skills/gsd-path-define/scripts/__pycache__/detect_project.cpython-312.pyc +0 -0
  168. package/skills/gsd-path-define/scripts/__pycache__/discussion_validate.cpython-312.pyc +0 -0
  169. package/skills/gsd-path-define/scripts/__pycache__/isolation.cpython-312.pyc +0 -0
  170. package/skills/gsd-path-define/scripts/__pycache__/pipeline_git.cpython-312.pyc +0 -0
  171. package/skills/gsd-path-define/scripts/__pycache__/pipeline_state.cpython-312.pyc +0 -0
  172. package/skills/gsd-path-define/scripts/__pycache__/review_panel.cpython-312.pyc +0 -0
  173. package/skills/gsd-path-define/scripts/__pycache__/roadmap.cpython-312.pyc +0 -0
  174. package/skills/gsd-path-define/scripts/__pycache__/state_checkpoint.cpython-312.pyc +0 -0
  175. package/skills/gsd-path-define/scripts/archive_milestone.py +2157 -0
  176. package/skills/gsd-path-define/scripts/build_recovery.py +287 -0
  177. package/skills/gsd-path-define/scripts/check_handoffs.py +1 -1
  178. package/skills/gsd-path-define/scripts/detect_project.py +11 -2
  179. package/skills/gsd-path-define/scripts/discussion_validate.py +1321 -0
  180. package/skills/gsd-path-define/scripts/integration.py +1439 -0
  181. package/skills/gsd-path-define/scripts/isolation.py +9 -1
  182. package/skills/gsd-path-define/scripts/pipeline_state.py +114 -186
  183. package/skills/gsd-path-define/scripts/promote_lookahead.py +283 -0
  184. package/skills/gsd-path-define/scripts/review_panel.py +553 -0
  185. package/skills/gsd-path-define/scripts/roadmap.py +321 -0
  186. package/skills/gsd-path-define/scripts/state_checkpoint.py +109 -72
  187. package/skills/gsd-path-define/scripts/state_promote.py +42 -44
  188. package/skills/gsd-path-docs-audit/references/dispatch.md +6 -0
  189. package/skills/gsd-path-docs-audit/references/docs-auditor.md +14 -0
  190. package/skills/gsd-path-docs-audit/scripts/__pycache__/_common.cpython-312.pyc +0 -0
  191. package/skills/gsd-path-docs-audit/scripts/__pycache__/archive_milestone.cpython-312.pyc +0 -0
  192. package/skills/gsd-path-docs-audit/scripts/__pycache__/build_recovery.cpython-312.pyc +0 -0
  193. package/skills/gsd-path-docs-audit/scripts/__pycache__/detect_project.cpython-312.pyc +0 -0
  194. package/skills/gsd-path-docs-audit/scripts/__pycache__/discussion_validate.cpython-312.pyc +0 -0
  195. package/skills/gsd-path-docs-audit/scripts/__pycache__/isolation.cpython-312.pyc +0 -0
  196. package/skills/gsd-path-docs-audit/scripts/__pycache__/pipeline_git.cpython-312.pyc +0 -0
  197. package/skills/gsd-path-docs-audit/scripts/__pycache__/pipeline_state.cpython-312.pyc +0 -0
  198. package/skills/gsd-path-docs-audit/scripts/__pycache__/review_panel.cpython-312.pyc +0 -0
  199. package/skills/gsd-path-docs-audit/scripts/__pycache__/roadmap.cpython-312.pyc +0 -0
  200. package/skills/gsd-path-docs-audit/scripts/__pycache__/state_checkpoint.cpython-312.pyc +0 -0
  201. package/skills/gsd-path-docs-audit/scripts/archive_milestone.py +2157 -0
  202. package/skills/gsd-path-docs-audit/scripts/build_recovery.py +287 -0
  203. package/skills/gsd-path-docs-audit/scripts/check_docs_audit.py +5 -3
  204. package/skills/gsd-path-docs-audit/scripts/check_handoffs.py +1 -1
  205. package/skills/gsd-path-docs-audit/scripts/detect_project.py +1526 -0
  206. package/skills/gsd-path-docs-audit/scripts/discussion_validate.py +1321 -0
  207. package/skills/gsd-path-docs-audit/scripts/integration.py +1439 -0
  208. package/skills/gsd-path-docs-audit/scripts/isolation.py +9 -1
  209. package/skills/gsd-path-docs-audit/scripts/pipeline_state.py +114 -186
  210. package/skills/gsd-path-docs-audit/scripts/promote_lookahead.py +283 -0
  211. package/skills/gsd-path-docs-audit/scripts/review_panel.py +553 -0
  212. package/skills/gsd-path-docs-audit/scripts/roadmap.py +321 -0
  213. package/skills/gsd-path-docs-audit/scripts/state_checkpoint.py +109 -72
  214. package/skills/gsd-path-docs-audit/scripts/state_promote.py +42 -44
  215. package/skills/gsd-path-forensics/scripts/__pycache__/pipeline_undo.cpython-312.pyc +0 -0
  216. package/skills/gsd-path-forensics/scripts/pipeline_diagnose.py +12 -3
  217. package/skills/gsd-path-forensics/scripts/pipeline_undo.py +11 -7
  218. package/skills/gsd-path-inspect/SKILL.md +30 -8
  219. package/skills/gsd-path-inspect/references/dispatch.md +6 -0
  220. package/skills/gsd-path-inspect/references/docs-auditor.md +14 -0
  221. package/skills/gsd-path-inspect/scripts/__pycache__/_common.cpython-312.pyc +0 -0
  222. package/skills/gsd-path-inspect/scripts/__pycache__/archive_milestone.cpython-312.pyc +0 -0
  223. package/skills/gsd-path-inspect/scripts/__pycache__/build_recovery.cpython-312.pyc +0 -0
  224. package/skills/gsd-path-inspect/scripts/__pycache__/detect_project.cpython-312.pyc +0 -0
  225. package/skills/gsd-path-inspect/scripts/__pycache__/discussion_validate.cpython-312.pyc +0 -0
  226. package/skills/gsd-path-inspect/scripts/__pycache__/isolation.cpython-312.pyc +0 -0
  227. package/skills/gsd-path-inspect/scripts/__pycache__/pipeline_git.cpython-312.pyc +0 -0
  228. package/skills/gsd-path-inspect/scripts/__pycache__/pipeline_state.cpython-312.pyc +0 -0
  229. package/skills/gsd-path-inspect/scripts/__pycache__/review_panel.cpython-312.pyc +0 -0
  230. package/skills/gsd-path-inspect/scripts/__pycache__/roadmap.cpython-312.pyc +0 -0
  231. package/skills/gsd-path-inspect/scripts/__pycache__/state_checkpoint.cpython-312.pyc +0 -0
  232. package/skills/gsd-path-inspect/scripts/archive_milestone.py +2157 -0
  233. package/skills/gsd-path-inspect/scripts/build_recovery.py +287 -0
  234. package/skills/gsd-path-inspect/scripts/check_docs_audit.py +5 -3
  235. package/skills/gsd-path-inspect/scripts/check_handoffs.py +1 -1
  236. package/skills/gsd-path-inspect/scripts/detect_project.py +11 -2
  237. package/skills/gsd-path-inspect/scripts/discussion_validate.py +1321 -0
  238. package/skills/gsd-path-inspect/scripts/integration.py +1439 -0
  239. package/skills/gsd-path-inspect/scripts/isolation.py +9 -1
  240. package/skills/gsd-path-inspect/scripts/pipeline_state.py +114 -186
  241. package/skills/gsd-path-inspect/scripts/promote_lookahead.py +283 -0
  242. package/skills/gsd-path-inspect/scripts/review_panel.py +553 -0
  243. package/skills/gsd-path-inspect/scripts/roadmap.py +321 -0
  244. package/skills/gsd-path-inspect/scripts/state_checkpoint.py +109 -72
  245. package/skills/gsd-path-inspect/scripts/state_promote.py +42 -44
  246. package/skills/gsd-path-inspect/scripts/workflow_run.py +226 -0
  247. package/skills/gsd-path-plan/SKILL.md +25 -17
  248. package/skills/gsd-path-plan/references/build-recovery.md +78 -0
  249. package/skills/gsd-path-plan/references/dispatch.md +6 -0
  250. package/skills/gsd-path-plan/scripts/__pycache__/_common.cpython-312.pyc +0 -0
  251. package/skills/gsd-path-plan/scripts/__pycache__/archive_milestone.cpython-312.pyc +0 -0
  252. package/skills/gsd-path-plan/scripts/__pycache__/detect_project.cpython-312.pyc +0 -0
  253. package/skills/gsd-path-plan/scripts/__pycache__/discussion_validate.cpython-312.pyc +0 -0
  254. package/skills/gsd-path-plan/scripts/__pycache__/isolation.cpython-312.pyc +0 -0
  255. package/skills/gsd-path-plan/scripts/__pycache__/pipeline_git.cpython-312.pyc +0 -0
  256. package/skills/gsd-path-plan/scripts/__pycache__/pipeline_state.cpython-312.pyc +0 -0
  257. package/skills/gsd-path-plan/scripts/__pycache__/review_panel.cpython-312.pyc +0 -0
  258. package/skills/gsd-path-plan/scripts/__pycache__/roadmap.cpython-312.pyc +0 -0
  259. package/skills/gsd-path-plan/scripts/__pycache__/state_checkpoint.cpython-312.pyc +0 -0
  260. package/skills/gsd-path-plan/scripts/archive_milestone.py +2157 -0
  261. package/skills/gsd-path-plan/scripts/build_recovery.py +287 -0
  262. package/skills/gsd-path-plan/scripts/check_handoffs.py +1 -1
  263. package/skills/gsd-path-plan/scripts/detect_project.py +1526 -0
  264. package/skills/gsd-path-plan/scripts/discussion_validate.py +1321 -0
  265. package/skills/gsd-path-plan/scripts/integration.py +1439 -0
  266. package/skills/gsd-path-plan/scripts/isolation.py +9 -1
  267. package/skills/gsd-path-plan/scripts/pipeline_state.py +114 -186
  268. package/skills/gsd-path-plan/scripts/promote_lookahead.py +283 -0
  269. package/skills/gsd-path-plan/scripts/roadmap.py +321 -0
  270. package/skills/gsd-path-plan/scripts/state_checkpoint.py +109 -72
  271. package/skills/gsd-path-plan/scripts/state_promote.py +42 -44
  272. package/skills/gsd-path-plan/scripts/workflow_run.py +116 -7
  273. package/skills/gsd-path-research/SKILL.md +3 -6
  274. package/skills/gsd-path-research/references/dispatch.md +6 -0
  275. package/skills/gsd-path-research/scripts/__pycache__/_common.cpython-312.pyc +0 -0
  276. package/skills/gsd-path-research/scripts/__pycache__/archive_milestone.cpython-312.pyc +0 -0
  277. package/skills/gsd-path-research/scripts/__pycache__/detect_project.cpython-312.pyc +0 -0
  278. package/skills/gsd-path-research/scripts/__pycache__/discussion_validate.cpython-312.pyc +0 -0
  279. package/skills/gsd-path-research/scripts/__pycache__/isolation.cpython-312.pyc +0 -0
  280. package/skills/gsd-path-research/scripts/__pycache__/pipeline_git.cpython-312.pyc +0 -0
  281. package/skills/gsd-path-research/scripts/__pycache__/pipeline_state.cpython-312.pyc +0 -0
  282. package/skills/gsd-path-research/scripts/__pycache__/review_panel.cpython-312.pyc +0 -0
  283. package/skills/gsd-path-research/scripts/__pycache__/roadmap.cpython-312.pyc +0 -0
  284. package/skills/gsd-path-research/scripts/__pycache__/state_checkpoint.cpython-312.pyc +0 -0
  285. package/skills/gsd-path-research/scripts/archive_milestone.py +2157 -0
  286. package/skills/gsd-path-research/scripts/build_recovery.py +287 -0
  287. package/skills/gsd-path-research/scripts/check_handoffs.py +1 -1
  288. package/skills/gsd-path-research/scripts/detect_project.py +1526 -0
  289. package/skills/gsd-path-research/scripts/discussion_validate.py +1321 -0
  290. package/skills/gsd-path-research/scripts/integration.py +1439 -0
  291. package/skills/gsd-path-research/scripts/isolation.py +9 -1
  292. package/skills/gsd-path-research/scripts/pipeline_state.py +114 -186
  293. package/skills/gsd-path-research/scripts/promote_lookahead.py +283 -0
  294. package/skills/gsd-path-research/scripts/review_panel.py +553 -0
  295. package/skills/gsd-path-research/scripts/roadmap.py +321 -0
  296. package/skills/gsd-path-research/scripts/state_checkpoint.py +109 -72
  297. package/skills/gsd-path-research/scripts/state_promote.py +42 -44
  298. package/skills/gsd-path-roadmap/SKILL.md +22 -58
  299. package/skills/gsd-path-roadmap/references/dispatch.md +6 -0
  300. package/skills/gsd-path-roadmap/scripts/__pycache__/_common.cpython-312.pyc +0 -0
  301. package/skills/gsd-path-roadmap/scripts/__pycache__/archive_milestone.cpython-312.pyc +0 -0
  302. package/skills/gsd-path-roadmap/scripts/__pycache__/detect_project.cpython-312.pyc +0 -0
  303. package/skills/gsd-path-roadmap/scripts/__pycache__/discussion_validate.cpython-312.pyc +0 -0
  304. package/skills/gsd-path-roadmap/scripts/__pycache__/isolation.cpython-312.pyc +0 -0
  305. package/skills/gsd-path-roadmap/scripts/__pycache__/pipeline_git.cpython-312.pyc +0 -0
  306. package/skills/gsd-path-roadmap/scripts/__pycache__/pipeline_state.cpython-312.pyc +0 -0
  307. package/skills/gsd-path-roadmap/scripts/__pycache__/review_panel.cpython-312.pyc +0 -0
  308. package/skills/gsd-path-roadmap/scripts/__pycache__/roadmap.cpython-312.pyc +0 -0
  309. package/skills/gsd-path-roadmap/scripts/__pycache__/state_checkpoint.cpython-312.pyc +0 -0
  310. package/skills/gsd-path-roadmap/scripts/archive_milestone.py +10 -118
  311. package/skills/gsd-path-roadmap/scripts/build_recovery.py +287 -0
  312. package/skills/gsd-path-roadmap/scripts/check_handoffs.py +1 -1
  313. package/skills/gsd-path-roadmap/scripts/detect_project.py +11 -2
  314. package/skills/gsd-path-roadmap/scripts/integration.py +28 -22
  315. package/skills/gsd-path-roadmap/scripts/isolation.py +9 -1
  316. package/skills/gsd-path-roadmap/scripts/pipeline_state.py +114 -186
  317. package/skills/gsd-path-roadmap/scripts/promote_lookahead.py +30 -162
  318. package/skills/gsd-path-roadmap/scripts/roadmap.py +321 -0
  319. package/skills/gsd-path-roadmap/scripts/state_checkpoint.py +109 -72
  320. package/skills/gsd-path-roadmap/scripts/state_promote.py +42 -44
  321. package/skills/gsd-path-ship/SKILL.md +5 -4
  322. package/skills/gsd-path-ship/references/dispatch.md +6 -0
  323. package/skills/gsd-path-ship/references/reviewer-final.md +21 -0
  324. package/skills/gsd-path-ship/references/reviewer-panel.md +17 -0
  325. package/skills/gsd-path-ship/references/reviewer-skeptic.md +20 -0
  326. package/skills/gsd-path-ship/references/reviewer-wave.md +89 -0
  327. package/skills/gsd-path-ship/references/reviewer.md +12 -150
  328. package/skills/gsd-path-ship/scripts/__pycache__/_common.cpython-312.pyc +0 -0
  329. package/skills/gsd-path-ship/scripts/__pycache__/archive_milestone.cpython-312.pyc +0 -0
  330. package/skills/gsd-path-ship/scripts/__pycache__/build_recovery.cpython-312.pyc +0 -0
  331. package/skills/gsd-path-ship/scripts/__pycache__/build_state.cpython-312.pyc +0 -0
  332. package/skills/gsd-path-ship/scripts/__pycache__/check_handoffs.cpython-312.pyc +0 -0
  333. package/skills/gsd-path-ship/scripts/__pycache__/check_task_briefs.cpython-312.pyc +0 -0
  334. package/skills/gsd-path-ship/scripts/__pycache__/detect_project.cpython-312.pyc +0 -0
  335. package/skills/gsd-path-ship/scripts/__pycache__/discussion_validate.cpython-312.pyc +0 -0
  336. package/skills/gsd-path-ship/scripts/__pycache__/isolation.cpython-312.pyc +0 -0
  337. package/skills/gsd-path-ship/scripts/__pycache__/pipeline_git.cpython-312.pyc +0 -0
  338. package/skills/gsd-path-ship/scripts/__pycache__/pipeline_state.cpython-312.pyc +0 -0
  339. package/skills/gsd-path-ship/scripts/__pycache__/review_panel.cpython-312.pyc +0 -0
  340. package/skills/gsd-path-ship/scripts/__pycache__/roadmap.cpython-312.pyc +0 -0
  341. package/skills/gsd-path-ship/scripts/__pycache__/state_checkpoint.cpython-312.pyc +0 -0
  342. package/skills/gsd-path-ship/scripts/archive_milestone.py +10 -118
  343. package/skills/gsd-path-ship/scripts/build_recovery.py +287 -0
  344. package/skills/gsd-path-ship/scripts/check_handoffs.py +1 -1
  345. package/skills/gsd-path-ship/scripts/detect_project.py +1526 -0
  346. package/skills/gsd-path-ship/scripts/integration.py +28 -22
  347. package/skills/gsd-path-ship/scripts/isolation.py +9 -1
  348. package/skills/gsd-path-ship/scripts/lean_verification.py +1 -1
  349. package/skills/gsd-path-ship/scripts/pipeline_state.py +114 -186
  350. package/skills/gsd-path-ship/scripts/promote_lookahead.py +283 -0
  351. package/skills/gsd-path-ship/scripts/roadmap.py +321 -0
  352. package/skills/gsd-path-ship/scripts/state_checkpoint.py +109 -72
  353. package/skills/gsd-path-ship/scripts/state_promote.py +42 -44
  354. package/skills/gsd-path-ship/scripts/workflow_run.py +116 -7
  355. package/skills/gsd-path-ship/templates/wave-review.md +1 -1
  356. package/skills/gsd-path-undo/scripts/pipeline_undo.py +11 -7
  357. package/skills/path/BUILD.md +47 -575
  358. package/skills/path/DECIDE.md +2 -6
  359. package/skills/path/DEFINE.md +10 -14
  360. package/skills/path/INSPECT.md +30 -8
  361. package/skills/path/PLAN.md +25 -17
  362. package/skills/path/RESEARCH.md +3 -6
  363. package/skills/path/ROADMAP.md +22 -58
  364. package/skills/path/SHIP.md +5 -4
  365. package/skills/path/SKILL.md +24 -14
  366. package/skills/path/references/build-abandon.md +33 -0
  367. package/skills/path/references/build-native.md +494 -0
  368. package/skills/path/references/build-recovery.md +78 -0
  369. package/skills/path/references/coder.md +8 -3
  370. package/skills/path/references/dispatch.md +6 -0
  371. package/skills/path/references/docs-auditor.md +14 -0
  372. package/skills/path/references/reviewer-final.md +21 -0
  373. package/skills/path/references/reviewer-panel.md +17 -0
  374. package/skills/path/references/reviewer-skeptic.md +20 -0
  375. package/skills/path/references/reviewer-wave.md +89 -0
  376. package/skills/path/references/reviewer.md +12 -150
  377. package/skills/path/scripts/archive_milestone.py +10 -118
  378. package/skills/path/scripts/bootstrap_repository.py +25 -3
  379. package/skills/path/scripts/build_recovery.py +287 -0
  380. package/skills/path/scripts/check_docs_audit.py +5 -3
  381. package/skills/path/scripts/check_handoffs.py +1 -1
  382. package/skills/path/scripts/detect_project.py +11 -2
  383. package/skills/path/scripts/dispatch_driver.py +4 -2
  384. package/skills/path/scripts/integration.py +28 -22
  385. package/skills/path/scripts/isolation.py +9 -1
  386. package/skills/path/scripts/lean_verification.py +1 -1
  387. package/skills/path/scripts/pipeline_state.py +114 -186
  388. package/skills/path/scripts/promote_lookahead.py +30 -162
  389. package/skills/path/scripts/roadmap.py +321 -0
  390. package/skills/path/scripts/state_checkpoint.py +109 -72
  391. package/skills/path/scripts/state_promote.py +42 -44
  392. package/skills/path/scripts/task_context.py +73 -0
  393. package/skills/path/scripts/token_budget.py +40 -1
  394. package/skills/path/scripts/workflow_run.py +116 -7
  395. package/skills/path/templates/wave-review.md +1 -1
@@ -11,6 +11,31 @@ from pathlib import Path, PurePosixPath
11
11
  from typing import Mapping, Optional
12
12
 
13
13
 
14
+ if __package__: # imported as scripts.state_promote
15
+ from . import pipeline_state, state_checkpoint
16
+ from .pipeline_state import (
17
+ NULL,
18
+ PROMOTION_RESIDUAL,
19
+ PROMOTION_SCHEMA,
20
+ PROMOTION_TRACKS,
21
+ SLUG_RE,
22
+ PipelineState,
23
+ PipelineStateError,
24
+ )
25
+ else: # standalone script or sibling import
26
+ import pipeline_state
27
+ import state_checkpoint
28
+ from pipeline_state import (
29
+ NULL,
30
+ PROMOTION_RESIDUAL,
31
+ PROMOTION_SCHEMA,
32
+ PROMOTION_TRACKS,
33
+ SLUG_RE,
34
+ PipelineState,
35
+ PipelineStateError,
36
+ )
37
+
38
+
14
39
  def _render_roadmap(
15
40
  text: str,
16
41
  previous_milestone: str,
@@ -243,9 +268,9 @@ def _completed_promotion(
243
268
  if _head_with_exact_message(repo, subject, fields) != head:
244
269
  raise PipelineStateError("completed promotion has the wrong commit message")
245
270
 
246
- active_text = pipeline_state._git_text_at(repo, base, ".project/STATE.md")
247
- next_text = pipeline_state._git_text_at(repo, base, ".project/next/STATE.md")
248
- roadmap_text = pipeline_state._git_text_at(repo, base, ".project/ROADMAP.md")
271
+ active_text = state_checkpoint._git_text_at(repo, base, ".project/STATE.md")
272
+ next_text = state_checkpoint._git_text_at(repo, base, ".project/next/STATE.md")
273
+ roadmap_text = state_checkpoint._git_text_at(repo, base, ".project/ROADMAP.md")
249
274
  if active_text is None or next_text is None or roadmap_text is None:
250
275
  raise PipelineStateError("promotion parent is missing required metadata")
251
276
  active_state = pipeline_state._state_from_text(active_text, "promotion parent STATE.md")
@@ -265,7 +290,7 @@ def _completed_promotion(
265
290
  )
266
291
 
267
292
  _promotion_tree_mapping(repo, base, head)
268
- drift = pipeline_state._classify_plan_drift(repo, next_state, base, landing)
293
+ drift = state_checkpoint._classify_plan_drift(repo, next_state, base, landing)
269
294
  expected_roadmap = _render_roadmap(
270
295
  roadmap_text,
271
296
  active_state.milestone,
@@ -273,11 +298,11 @@ def _completed_promotion(
273
298
  branch,
274
299
  landing,
275
300
  )
276
- current_roadmap = pipeline_state._git_text_at(repo, head, ".project/ROADMAP.md")
301
+ current_roadmap = state_checkpoint._git_text_at(repo, head, ".project/ROADMAP.md")
277
302
  if current_roadmap != expected_roadmap:
278
303
  raise PipelineStateError("completed promotion has invalid ROADMAP.md")
279
304
 
280
- current_state = pipeline_state._git_text_at(repo, head, ".project/STATE.md")
305
+ current_state = state_checkpoint._git_text_at(repo, head, ".project/STATE.md")
281
306
  if current_state is None:
282
307
  raise PipelineStateError("completed promotion has no STATE.md")
283
308
  event = re.escape(_promotion_event(drift, branch, landing, base))
@@ -438,10 +463,10 @@ def _prepare_promotion(
438
463
  if source.exists() or source.is_symlink():
439
464
  if destination.exists() or destination.is_symlink():
440
465
  raise PipelineStateError(f"promotion destination already exists: {destination}")
441
- tracks[name] = pipeline_state._tree_digest(source)
466
+ tracks[name] = state_checkpoint._tree_digest(source)
442
467
  if not tracks:
443
468
  raise PipelineStateError("lookahead track has no promotable artifacts")
444
- drift = pipeline_state._classify_plan_drift(repo, next_state, base, landing)
469
+ drift = state_checkpoint._classify_plan_drift(repo, next_state, base, landing)
445
470
  roadmap_path = project / "ROADMAP.md"
446
471
  roadmap_text = pipeline_state._read_real_file(roadmap_path, "ROADMAP.md")
447
472
  target_state = _promotion_state(
@@ -464,10 +489,10 @@ def _prepare_promotion(
464
489
  "landing": landing,
465
490
  "base": base,
466
491
  "tracks": tracks,
467
- "residual_sha256": pipeline_state._tree_digest(next_root, tuple(tracks)),
468
- "next_state_sha256": pipeline_state._sha256(next_text),
469
- "active_state_sha256": pipeline_state._sha256(active_text),
470
- "roadmap_sha256": pipeline_state._sha256(roadmap_text),
492
+ "residual_sha256": state_checkpoint._tree_digest(next_root, tuple(tracks)),
493
+ "next_state_sha256": state_checkpoint._sha256(next_text),
494
+ "active_state_sha256": state_checkpoint._sha256(active_text),
495
+ "roadmap_sha256": state_checkpoint._sha256(roadmap_text),
471
496
  "target_state": target_state,
472
497
  "target_roadmap": target_roadmap,
473
498
  "drift": drift,
@@ -521,7 +546,7 @@ def _resume_track_moves(project: Path, journal: dict[str, object], path: Path) -
521
546
  if not source_exists and not destination_exists:
522
547
  raise PipelineStateError(f"promotion lost both source and destination: {name}")
523
548
  candidate = source if source_exists else destination
524
- if pipeline_state._tree_digest(candidate) != expected_digest:
549
+ if state_checkpoint._tree_digest(candidate) != expected_digest:
525
550
  raise PipelineStateError(f"promotion track drifted: {name}")
526
551
  if source_exists:
527
552
  source.rename(destination)
@@ -542,7 +567,7 @@ def _resume_metadata(project: Path, journal: dict[str, object], path: Path) -> N
542
567
  raise PipelineStateError("promotion journal has invalid metadata")
543
568
  if current == desired:
544
569
  continue
545
- if pipeline_state._sha256(current) != expected_original:
570
+ if state_checkpoint._sha256(current) != expected_original:
546
571
  raise PipelineStateError(f"promotion metadata drifted: {target}")
547
572
  pipeline_state._atomic_write(target, desired)
548
573
  journal["stage"] = f"updated:{target.name}"
@@ -560,9 +585,9 @@ def _resume_next_removal(
560
585
  if residual.exists() or residual.is_symlink():
561
586
  raise PipelineStateError("promotion has both next track and residual staging")
562
587
  next_text = pipeline_state._read_real_file(next_root / "STATE.md", "next/STATE.md")
563
- if pipeline_state._sha256(next_text) != journal.get("next_state_sha256"):
588
+ if state_checkpoint._sha256(next_text) != journal.get("next_state_sha256"):
564
589
  raise PipelineStateError("lookahead STATE drifted during promotion")
565
- if pipeline_state._tree_digest(next_root) != journal.get("residual_sha256"):
590
+ if state_checkpoint._tree_digest(next_root) != journal.get("residual_sha256"):
566
591
  raise PipelineStateError("lookahead residual drifted during promotion")
567
592
  next_root.rename(residual)
568
593
  journal["stage"] = "next-staged"
@@ -574,7 +599,7 @@ def _resume_next_removal(
574
599
  raise PipelineStateError("promotion lost next track and residual staging")
575
600
  if residual.is_symlink() or not residual.is_dir():
576
601
  raise PipelineStateError(f"promotion residual must be a real directory: {residual}")
577
- if pipeline_state._tree_digest(residual) != journal.get("residual_sha256"):
602
+ if state_checkpoint._tree_digest(residual) != journal.get("residual_sha256"):
578
603
  raise PipelineStateError("staged lookahead residual drifted during promotion")
579
604
 
580
605
 
@@ -714,30 +739,3 @@ def promote_next(
714
739
  "commit": commit,
715
740
  "drift": journal["drift"],
716
741
  }
717
-
718
-
719
- # pipeline_state imports this module, so the parent is resolved after the
720
- # definitions above. Parent functions are looked up on the module at call time
721
- # so patches applied to pipeline_state stay visible here.
722
- if __package__: # imported as scripts.state_promote
723
- from . import pipeline_state
724
- from .pipeline_state import (
725
- NULL,
726
- PROMOTION_RESIDUAL,
727
- PROMOTION_SCHEMA,
728
- PROMOTION_TRACKS,
729
- SLUG_RE,
730
- PipelineState,
731
- PipelineStateError,
732
- )
733
- else: # standalone script or sibling import
734
- import pipeline_state
735
- from pipeline_state import (
736
- NULL,
737
- PROMOTION_RESIDUAL,
738
- PROMOTION_SCHEMA,
739
- PROMOTION_TRACKS,
740
- SLUG_RE,
741
- PipelineState,
742
- PipelineStateError,
743
- )
@@ -0,0 +1,226 @@
1
+ #!/usr/bin/env python3
2
+ """Run canonical workflow helpers with fixed arguments and fail-stop receipts."""
3
+
4
+ import argparse
5
+ import hashlib
6
+ import json
7
+ import subprocess
8
+ import sys
9
+ import tempfile
10
+ from pathlib import Path
11
+
12
+ try:
13
+ from scripts import _common
14
+ except ImportError: # bundled copy inside a skill's scripts directory
15
+ import _common
16
+
17
+
18
+ class StepFailed(RuntimeError):
19
+ pass
20
+
21
+ INSPECTION_SPECS = (("inspect_codebase", "codebase-mapper", "codebase", "evidence-codebase.md"),
22
+ ("inspect_docs", "docs-auditor", "docs-audit", "DOCS-AUDIT.md"))
23
+
24
+
25
+ def run_workflow(repo: Path, action: str, project_dir: str, expected_head: str = None,
26
+ task_id: str = None, round_size: int = None, inspection: Path = None,
27
+ mapper_reviewed: bool = False) -> dict:
28
+ steps = []
29
+ outputs = {}
30
+ scripts = Path(__file__).resolve().parent
31
+
32
+ def step(script, *arguments, raw=False):
33
+ command = [sys.executable, "-B", str(scripts / script), *arguments]
34
+ completed = subprocess.run(command, cwd=repo, capture_output=True, text=True)
35
+ receipt = {"script": script, "command": command, "exit_code": completed.returncode,
36
+ "stdout": completed.stdout, "stderr": completed.stderr}
37
+ steps.append(receipt)
38
+ if completed.stderr:
39
+ sys.stderr.write(completed.stderr)
40
+ if completed.returncode:
41
+ raise StepFailed(script)
42
+ if raw:
43
+ return completed.stdout
44
+ try:
45
+ receipt["result"] = json.loads(completed.stdout)
46
+ except json.JSONDecodeError as error:
47
+ raise StepFailed(f"{script} did not return JSON") from error
48
+ return receipt["result"]
49
+
50
+ common = ["--repo", str(repo), "--project-dir", project_dir]
51
+ try:
52
+ if action == "route":
53
+ step("pipeline_state.py", "route", *common)
54
+ elif action == "prepare-inspect":
55
+ state = step("pipeline_state.py", "validate", *common)["state"]
56
+ if project_dir != ".project" or state["phase"] != "inspect" or state["status"] != "active":
57
+ raise StepFailed("initial inspection requires the active inspect track")
58
+ specs = INSPECTION_SPECS
59
+ if any((repo / project_dir / "research" / spec[3]).exists() or
60
+ (repo / project_dir / "research" / spec[3]).is_symlink() for spec in specs):
61
+ raise StepFailed("prior inspection evidence requires the re-inspection contract")
62
+ branch = subprocess.run(["git", "branch", "--show-current"], cwd=repo,
63
+ capture_output=True, text=True, check=True).stdout.strip()
64
+ if branch != state["branch"]:
65
+ raise StepFailed("current branch differs from the recorded inspection branch")
66
+ pending = step("discussion_records.py", "pending", "--repo", str(repo))
67
+ if pending["pending"]:
68
+ raise StepFailed("pending discussion requires its owner disposition")
69
+ inventory = step("check_docs_audit.py", "--repo", str(repo), "--emit-inventory", raw=True)
70
+ resources = scripts.parent
71
+ if not (resources / "references").is_dir():
72
+ resources = resources / "skills/gsd-path"
73
+ for _, role, template, _ in specs:
74
+ for path in (resources / "references" / f"{role}.md", resources / "templates" / f"{template}.md"):
75
+ if not path.is_file():
76
+ raise StepFailed(f"missing inspection resource: {path}")
77
+ staging = Path(tempfile.mkdtemp(prefix="gsd-path-inspect-"))
78
+ inventory_file = staging / "inventory.txt"
79
+ inventory_file.write_text(inventory, encoding="utf-8")
80
+ assignments = []
81
+ for task_name, role, template, filename in specs:
82
+ isolated = step("isolation.py", "isolate-verify", "--repo", str(repo),
83
+ "--base", expected_head, "--name", task_name.replace("_", "-"))
84
+ role_path = resources / "references" / f"{role}.md"
85
+ template_path = resources / "templates" / f"{template}.md"
86
+ output = f"{project_dir}/research/{filename}"
87
+ brief_file = staging / f"{task_name}.md"
88
+ brief = (f"Logical task: {task_name}\nRead and follow role: {role_path}\n"
89
+ f"Template: {template_path}\nRepository and command cwd: {isolated['worktree']}\n"
90
+ f"Recorded baseline and Audited HEAD: {isolated['base']}\n"
91
+ f"Write only: {Path(isolated['worktree']) / output}\n"
92
+ "Use only this supplied sidecar for project commands; do not create worktrees.\n"
93
+ "The parent owns gates, collection, retirement, and phase state.\n"
94
+ "Exclude .git, node_modules, .project/archive, and installed GSD Path and path skill bundles.\n")
95
+ if task_name == "inspect_docs":
96
+ brief += ("Alignment mode: false. No prior audit or changed set.\n"
97
+ "Frozen inventory follows; use it exactly, without rediscovery:\n" + inventory)
98
+ brief_file.write_text(brief, encoding="utf-8")
99
+ assignments.append({**isolated, "task_name": task_name, "role": str(role_path),
100
+ "template": str(template_path), "output": output,
101
+ "brief_file": str(brief_file)})
102
+ receipt_file = staging / "inspection.json"
103
+ outputs["inspection"] = {"repo": str(repo), "base": expected_head,
104
+ "inventory_file": str(inventory_file),
105
+ "inventory_sha256": hashlib.sha256(inventory_file.read_bytes()).hexdigest(),
106
+ "assignments": assignments, "receipt_file": str(receipt_file)}
107
+ _common.atomic_write(receipt_file, json.dumps(outputs["inspection"], sort_keys=True) + "\n")
108
+ elif action == "finish-inspect":
109
+ if not mapper_reviewed or inspection is None or project_dir != ".project":
110
+ raise StepFailed("finish-inspect requires the prepared active track and mapper review")
111
+ prepared = json.loads(inspection.read_text(encoding="utf-8"))
112
+ if prepared["repo"] != str(repo) or prepared["base"] != expected_head:
113
+ raise StepFailed("inspection receipt does not match repository and expected HEAD")
114
+ assignments = {a["task_name"]: a for a in prepared["assignments"]}
115
+ if len(prepared["assignments"]) != len(INSPECTION_SPECS) or set(assignments) != {s[0] for s in INSPECTION_SPECS}:
116
+ raise StepFailed("inspection receipt must name both original assignments")
117
+ for task_name, _, _, filename in INSPECTION_SPECS:
118
+ assignment = assignments[task_name]
119
+ if assignment["base"] != expected_head or assignment["output"] != f".project/research/{filename}":
120
+ raise StepFailed("inspection assignment changed its baseline or output")
121
+ inventory_file = Path(prepared["inventory_file"])
122
+ if hashlib.sha256(inventory_file.read_bytes()).hexdigest() != prepared["inventory_sha256"]:
123
+ raise StepFailed("frozen inspection inventory changed")
124
+ state = step("pipeline_state.py", "validate", *common)["state"]
125
+ if state["phase"] != "inspect" or state["status"] != "active":
126
+ raise StepFailed("inspection completion requires inspect/active")
127
+ branch = subprocess.run(["git", "branch", "--show-current"], cwd=repo,
128
+ capture_output=True, text=True, check=True).stdout.strip()
129
+ if state["branch"] != branch:
130
+ raise StepFailed("current branch differs from the recorded inspection branch")
131
+ pending = step("discussion_records.py", "pending", "--repo", str(repo))
132
+ if pending["pending"]:
133
+ raise StepFailed("pending discussion requires its owner disposition")
134
+ docs = assignments["inspect_docs"]
135
+ step("check_docs_audit.py", "--repo", docs["worktree"], "--audit", docs["output"],
136
+ "--inventory", str(inventory_file))
137
+ if f"Audited HEAD: {expected_head}" not in (Path(docs["worktree"]) / docs["output"]).read_text().splitlines():
138
+ raise StepFailed("audit does not name the supplied inspection baseline")
139
+ for task_name, _, _, _ in INSPECTION_SPECS:
140
+ assignment = assignments[task_name]
141
+ step("isolation.py", "collect-artifact", "--repo", str(repo),
142
+ "--source", assignment["worktree"], "--base", expected_head,
143
+ "--branch", assignment["branch"], "--source-path", assignment["output"],
144
+ "--destination-path", assignment["output"])
145
+ step("isolation.py", "retire", "--repo", str(repo), "--worktree", assignment["worktree"],
146
+ "--branch", assignment["branch"])
147
+ expected = [part for key, value in state.items()
148
+ for part in (f"--expect-{key}", "null" if value is None else str(value))]
149
+ step("pipeline_state.py", "transition", *common, *expected,
150
+ "--set-phase", "inspect", "--set-status", "done", "--event", "inspection artifacts passed")
151
+ elif action == "lint-round":
152
+ head = subprocess.run(["git", "rev-parse", "--verify", "HEAD"],
153
+ cwd=repo, capture_output=True, text=True, check=True).stdout.strip()
154
+ step("check_task_briefs.py", "--repo", str(repo), "--base", head,
155
+ "--tasks-dir", f"{project_dir}/tasks")
156
+ step("check_handoffs.py", "plan", *common)
157
+ elif action == "prepare-task":
158
+ task = step("isolation.py", "isolate-task", "--repo", str(repo),
159
+ "--base", expected_head, "--task-id", task_id,
160
+ "--round-size", str(round_size))
161
+ if task["mode"] == "serial":
162
+ step("isolation.py", "isolate-verify", "--repo", str(repo),
163
+ "--base", expected_head, "--name", f"task-{task_id.lower()}-verify")
164
+ elif action == "build-evidence":
165
+ proof = step("build_state.py", "verify-landed", *common, "--head", expected_head)
166
+ # The landing proof has one canonical home; lean final-review reuse allows only this path.
167
+ evidence = repo / project_dir / "build" / "evidence.json"
168
+ _common.atomic_write(evidence, json.dumps(proof, indent=2, sort_keys=True) + "\n")
169
+ steps.append({"script": "workflow_run.py", "evidence": str(evidence)})
170
+ elif action == "prepare-final":
171
+ if project_dir != ".project":
172
+ raise StepFailed("final review requires the active milestone")
173
+ pending = step("discussion_records.py", "pending", "--repo", str(repo))
174
+ if pending["pending"]:
175
+ raise StepFailed("pending discussion requires its owner disposition")
176
+ step("build_state.py", "verify-landed", *common, "--head", expected_head)
177
+ step("lean_verification.py", "--repo", str(repo), "--expected-head", expected_head)
178
+ else:
179
+ pending = step("discussion_records.py", "pending", "--repo", str(repo))
180
+ if pending["pending"]:
181
+ raise StepFailed("pending discussion requires its owner disposition")
182
+ step("check_handoffs.py", "plan", *common)
183
+ head = subprocess.run(["git", "rev-parse", "--verify", "HEAD"],
184
+ cwd=repo, capture_output=True, text=True, check=True).stdout.strip()
185
+ step("check_task_briefs.py", "--repo", str(repo), "--base", head,
186
+ "--tasks-dir", f"{project_dir}/tasks")
187
+ panel = ["validate-plan", "--plan", str(repo / project_dir / "plan/PLAN.md"),
188
+ "--intent", str(repo / project_dir / "intent/INTENT.md")]
189
+ charter = repo / ".project/CHARTER.md"
190
+ if charter.exists():
191
+ panel += ["--charter", str(charter)]
192
+ step("review_panel.py", *panel)
193
+ if action == "approve-plan":
194
+ step("pipeline_state.py", "approve", *common, "--kind", "plan",
195
+ "--expected-head", expected_head)
196
+ except (StepFailed, OSError, subprocess.CalledProcessError, ValueError, KeyError, TypeError) as error:
197
+ return {"status": "blocked", "reason": str(error), "steps": steps,
198
+ "next": "$gsd-path-forensics"}
199
+ return {"status": "complete", "steps": steps, **outputs}
200
+
201
+
202
+ def main(argv=None):
203
+ parser = argparse.ArgumentParser(description=__doc__)
204
+ parser.add_argument("action", choices=("route", "gate-plan", "approve-plan", "build-evidence", "lint-round", "prepare-task", "prepare-final", "prepare-inspect", "finish-inspect"))
205
+ parser.add_argument("--repo", type=Path, required=True)
206
+ parser.add_argument("--project-dir", choices=(".project", ".project/next"), default=".project")
207
+ parser.add_argument("--expected-head")
208
+ parser.add_argument("--task-id")
209
+ parser.add_argument("--round-size", type=int)
210
+ parser.add_argument("--inspection", type=Path)
211
+ parser.add_argument("--mapper-reviewed", action="store_true")
212
+ arguments = parser.parse_args(argv)
213
+ if arguments.action in {"approve-plan", "build-evidence", "prepare-task", "prepare-final", "prepare-inspect", "finish-inspect"} and not arguments.expected_head:
214
+ parser.error(f"{arguments.action} requires --expected-head")
215
+ if arguments.action == "prepare-task" and (not arguments.task_id or arguments.round_size is None):
216
+ parser.error("prepare-task requires --task-id and --round-size")
217
+ result = run_workflow(arguments.repo.resolve(), arguments.action,
218
+ arguments.project_dir, arguments.expected_head,
219
+ arguments.task_id, arguments.round_size, arguments.inspection,
220
+ arguments.mapper_reviewed)
221
+ print(json.dumps(result, sort_keys=True))
222
+ return 0 if result["status"] == "complete" else 1
223
+
224
+
225
+ if __name__ == "__main__":
226
+ raise SystemExit(main())
@@ -29,8 +29,11 @@ Before dispatch, enter from `decide/done` or `define/done` with
29
29
  `--set-phase plan --set-status active`, and event `planning started`. Resume
30
30
  `plan/blocked` through the same helper with event `planning resumed`. Require
31
31
  the returned track state to be `plan/active`; never edit STATE directly.
32
- Any later phase blocks instead of replacing an approved plan. Patch mode is
33
- the only reopen exception: require an approved plan, no in-progress task, and
32
+ For a blocked build, use the [build recovery contract](references/build-recovery.md).
33
+ The runtime's `build-repair` mode owns structural changes to the remaining task
34
+ inventory and the normal approval checkpoint; it is distinct from append-only
35
+ patch mode. Otherwise later phases block instead of replacing an approved plan.
36
+ Patch mode requires an approved plan, no in-progress task, and
34
37
  state `plan/done` or `ship/blocked`; any other state blocks. `build/done` is
35
38
  reserved exclusively for the build orchestrator's transition recovery and
36
39
  must return there instead of reopening planning. When an active router
@@ -74,10 +77,17 @@ router supplied lookahead mode. Every per-milestone path below, including
74
77
  review-panel evidence, is rooted there. Program inputs remain at `.project/`
75
78
  as stated in Lookahead mode.
76
79
 
77
- 1. Read the local [plan template](templates/plan.md), [task template](templates/task.md),
78
- [plan-panel template](templates/plan-panel.md), `scripts/check_handoffs.py`,
79
- and `scripts/review_panel.py`; resolve them to absolute paths.
80
- 2. Read the local [planner role](references/planner.md), then follow the
80
+ 1. Resolve the local [plan template](templates/plan.md), [task template](templates/task.md),
81
+ `scripts/check_handoffs.py`, and `scripts/review_panel.py` to absolute paths.
82
+ Quick mode reads the plan and task templates because the parent writes
83
+ those artifacts. Other modes pass their paths to the planner. Execute the
84
+ helpers through the commands below and consume their results; their Python
85
+ source is not planning input. Read helper source only when diagnosing a
86
+ concrete failure that the returned error and documented recovery cannot
87
+ explain.
88
+ 2. In quick mode, skip planner dispatch and follow Quick mode below; do not
89
+ load the planner role or dispatch contract. In other modes, resolve the
90
+ local [planner role](references/planner.md) for the child, then follow the
81
91
  local [runtime dispatch contract](references/dispatch.md) with deterministic
82
92
  logical task name `plan`. Give it absolute role, `AGENTS.md`, `WORKFLOW.md`,
83
93
  input, template, and output paths, including `.project/LESSONS.md` when it
@@ -133,7 +143,7 @@ as stated in Lookahead mode.
133
143
  - Require a `Review depth` value (`full`, `deep`, or `verify-only`) on
134
144
  every wave. Wave 1 and any wave touching authentication, authorization,
135
145
  payments, data migration, or concurrency requires `full` or `deep`;
136
- quick-lane single waves may use `verify-only`. The planner assigns `deep`
146
+ this includes quick-lane single waves. The planner assigns `deep`
137
147
  sparingly to waves where a wrong merge is irreversible or
138
148
  security-critical.
139
149
  - When INTENT.md `Surfaces:` is not `none`, require a PLAN.md
@@ -199,7 +209,9 @@ as stated in Lookahead mode.
199
209
  - `status: error` or exit 2 — use the same guarded transition to set
200
210
  `plan/blocked` with an event naming the helper error, link PLAN.md, and stop.
201
211
  A named family that is not advertised is an assertion failure.
202
- - `status: ready` — for each selected family, spawn one independent child
212
+ - `status: ready` — resolve the local
213
+ [plan-panel template](templates/plan-panel.md) for the reviewers; other
214
+ statuses do not load this template. For each selected family, spawn one independent child
203
215
  with logical task name `review_plan_panel_<family>`, the reviewer role
204
216
  in plan-panel mode, the plan-panel template, and the exact helper-returned
205
217
  model slug when the host advertises model selection. Never override the
@@ -257,12 +269,8 @@ as stated in Lookahead mode.
257
269
  (event `patch plan approved`) without a plan checkpoint because build's
258
270
  patch re-entry commits the artifacts with its `build/active` transition.
259
271
  `pipeline_state.py transition` never approves a plan. Confirm approval,
260
- link PLAN.md again, and state that
261
- build starts next. Do not add another approval gate. When routed by an
262
- active `$gsd-path`, return control to that router so its bundled build
263
- contract starts. When invoked directly, stop and tell the user to explicitly
264
- invoke `$gsd-path`, which routes to build; do not invoke an explicit-only
265
- sibling skill yourself.
272
+ link PLAN.md again, and use the executable phase handoff in AGENTS.md.
273
+ The plan approval also authorizes build; do not add another approval gate.
266
274
 
267
275
  ## Ordering rules
268
276
 
@@ -273,8 +281,8 @@ as stated in Lookahead mode.
273
281
  ## Quick mode
274
282
 
275
283
  Legal entry: `define/done` where INTENT.md records `Lane: quick` (transition
276
- to `plan/active`, logging that research and decide were skipped for the
277
- quick lane). Quick mode dispatches no planner agent — the orchestrator writes
284
+ to `plan/active` using exactly the Preconditions event `planning started`;
285
+ record the skipped research and decide phases in the synthesis). Quick mode dispatches no planner agent — the orchestrator writes
278
286
  the artifacts directly:
279
287
 
280
288
  1. Write `.project/research/SYNTHESIS.md` containing only `## Settled` lines
@@ -282,7 +290,7 @@ the artifacts directly:
282
290
  plus a minimal `## For the planner` naming the walking skeleton. No
283
291
  invented decisions or runner-ups.
284
292
  2. Write `.project/plan/PLAN.md` with exactly one wave — `Review depth:
285
- verify-only` permitted — and at most two deliverable-sized task files
293
+ full` or `deep` — and at most two deliverable-sized task files
286
294
  (project policy),
287
295
  honoring every task-contract rule above and `.project/LESSONS.md` when it
288
296
  exists. Write `review_panel: off` and `finding_skeptics: off` regardless
@@ -0,0 +1,78 @@
1
+ # Return a blocked build to its contract owner
2
+
3
+ Use this contract only for an active milestone at `build/blocked`: a documented
4
+ structural plan defect, or an explicit user ruling that changes approved intent.
5
+ It does not reopen ship, archived milestones, or lookahead. Build owns entry;
6
+ Define owns intent corrections; Plan owns the replacement task inventory and
7
+ approval. Routing remains a caller handoff under AGENTS.md.
8
+
9
+ ## Build: checkpoint and enter
10
+
11
+ 1. Record the finding or verbatim user ruling in STATE through its helper.
12
+ Stop dispatch. Use the normal recovery and retirement procedures until
13
+ every task is either unstarted `pending` with null dispatch metadata or
14
+ proven `done`. Preserve owned uncommitted work before any retirement.
15
+ Settle reviewers and their sidecars too. Dispatch records must have no pending
16
+ cleanup; records with reviewer `worktree` and `branch` ownership must also
17
+ record `cleanup_complete`. A `blocked` or `collected` outcome alone does not
18
+ prove retirement. Records that never owned a reviewer sidecar do not require
19
+ that retirement receipt. Use the existing dispatch retirement procedures;
20
+ recovery does not retire sidecars itself. Never infer that a timed-out child
21
+ stopped. Checkpoint the blocked state and artifacts using the Build
22
+ bookkeeping contract; the primary must be clean.
23
+ 2. Run `pipeline_state.py transition` with the complete current state expected,
24
+ `--set-status active`, and the matching target and event:
25
+
26
+ | Cause | Target | Exact event |
27
+ | --- | --- | --- |
28
+ | User changes a criterion, constraint, or veto | `--set-phase define` | `build intent corrections requested` |
29
+ | Task inventory, dependency, or wave repair | `--set-phase plan` | `build plan repair requested` |
30
+
31
+ The helper records the committed recovery base in STATE atomically. Do not
32
+ author or edit that record. Milestone, branch, integration settings, and
33
+ landed task contracts remain fixed throughout recovery.
34
+ 3. Return to the router or name the selected explicit skill. The route names
35
+ `corrections` for Define and `build-repair` for Plan. Other blocked-build
36
+ failures continue through ordinary Build recovery.
37
+
38
+ ## Define and Plan: prepare before editing
39
+
40
+ Run the bundled `pipeline_state.py prepare-build-recovery --repo <absolute-root>`
41
+ before changing any recovery artifact. This repeatable operation preserves the
42
+ old review directory under `plan/build-recovery-<base>/review` and starts a fresh
43
+ active review directory. STATE's recorded base owns an interrupted move; rerun
44
+ this command to finish it. The helper validates the preserved bytes against Git.
45
+ Do not remove, rewrite, or use the preserved reviews as current approval.
46
+
47
+ **Define corrections.** Read the existing intent and governing program artifacts.
48
+ Interview only the requested change; append the user's words under
49
+ `## Corrections`, revise the affected intent, and present the delta for approval.
50
+ Keep the milestone identity. Reclassify the lane using the normal lane rules.
51
+ After approval, use the normal `define/active → define/done` transition and route
52
+ from the approved lane. Standard intent goes through Research and Decide again;
53
+ quick and milestone intent use their existing evidence gates. A program charter
54
+ or roadmap conflict still requires its legal owner gate; this path cannot waive it.
55
+
56
+ **Plan build-repair.** Read the corrected intent, current synthesis, existing plan,
57
+ task files, and recovery base. Use the normal planner, lint, panel, and approval
58
+ gates. Repair the remaining task inventory as needed, including split, rename,
59
+ dependency, or wave changes. Keep IDs ordered and contiguous. Preserve every
60
+ landed task file byte-for-byte, including its recorded base and proof. Any new
61
+ work to satisfy a corrected criterion belongs in new pending tasks, not rewritten
62
+ landed contracts. A plan-only recovery must not change approved intent.
63
+
64
+ ## Approve and return to Build
65
+
66
+ Use normal `pipeline_state.py approve --kind plan --expected-head <HEAD>`.
67
+ Neither `--patch` nor `--defer-checkpoint` is legal for recovery. The helper
68
+ checks landed-task preservation and restored intent ownership, restores review
69
+ evidence only for unchanged contracts, and creates the normal journaled plan
70
+ checkpoint. A failed approval leaves recovery open.
71
+
72
+ Return through `plan/done → build/active` with event `build started`. The dispatch
73
+ driver uses a separate record directory for this recovery base, while retaining
74
+ the milestone budget ledger. Resume only from the new approved task inventory.
75
+ Unchanged wave evidence remains usable; changed waves need review in the new
76
+ record directory. Retained task Verify receipts remain historical evidence for
77
+ their original task and base, never proof for a changed task. Final review still
78
+ requires current-HEAD evidence before shipment.
@@ -122,6 +122,12 @@ directory for the full logical session; resumptions reuse it. Record completed
122
122
  parent CLI run events and each native child's session events with stable logical
123
123
  task names before the next dispatch. The helper reads host counters and refuses
124
124
  incomplete or ambiguous usage; never estimate tokens or reset the ledger.
125
+ When the verified CLI adapter reports cumulative counters across `resume`, record
126
+ each later invocation with `--previous-events <previous recorded CLI events>`.
127
+ The helper checks thread identity and records only the new output, preserving the
128
+ raw total and predecessor. Keep that chain in order; never sum cumulative totals.
129
+ Use ordinary `record` for per-invocation counters. An unknown counter convention
130
+ is unproven usage, not permission to guess.
125
131
  Run `admit` for the next task and stop dispatch on a blocked result. Preserve
126
132
  its output in the dispatch evidence. This gates observed usage only: concurrent
127
133
  or in-flight work can overrun before the host reports usage. Codex CLI has no