@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,73 @@
1
+ #!/usr/bin/env python3
2
+ """Render a read-only coder intent view from the approved task and intent."""
3
+
4
+ import argparse
5
+ import hashlib
6
+ import re
7
+ import sys
8
+ from pathlib import Path
9
+
10
+ try:
11
+ from scripts import check_handoffs as contracts
12
+ except ImportError:
13
+ import check_handoffs as contracts
14
+
15
+
16
+ def render(repo: Path, task: Path) -> str:
17
+ intent_path = repo.resolve() / '.project/intent/INTENT.md'
18
+ task = task.resolve()
19
+ intent = intent_path.read_bytes().decode('utf-8')
20
+ task_text = task.read_bytes().decode('utf-8')
21
+ owned = contracts._owned_criteria(task_text, task.stem)
22
+ criteria = contracts._success_criteria(intent)
23
+ unknown = set(owned) - set(criteria)
24
+ if unknown:
25
+ raise contracts.HandoffError('unknown owned criteria: ' + ', '.join(sorted(unknown)))
26
+ projected, mode = intent, 'full-intent'
27
+ sections = list(re.finditer(r'(?ms)^## Success criteria[ \t]*\n(?P<body>.*?)(?=^## |\Z)', intent))
28
+ if len(sections) == 1:
29
+ section = sections[0]
30
+ body = section['body']
31
+ items = list(re.finditer(r'(?m)^(\d+)\. .+\n?', body))
32
+ # Project only simple numbered prose. Preserve unfamiliar Markdown in full.
33
+ simple = (items and not body[:items[0].start()].strip()
34
+ and '```' not in body and '~~~' not in body and '<!--' not in body
35
+ and [f'SC{item[1]}' for item in items] == list(criteria))
36
+ chunks = [body[item.start():items[n + 1].start() if n + 1 < len(items) else len(body)]
37
+ for n, item in enumerate(items)]
38
+ simple = simple and all(not line.strip() or line[:1].isspace()
39
+ for chunk in chunks for line in chunk.splitlines()[1:])
40
+ if simple:
41
+ before, after = intent[:section.start('body')], intent[section.end('body'):]
42
+ # Corrections and task interfaces can explicitly refer to another SC.
43
+ required = set(owned) | set(re.findall(r'\bSC\d+\b', before + after + task_text))
44
+ selected = ''.join(chunk for item, chunk in zip(items, chunks) if f'SC{item[1]}' in required)
45
+ projected = before + '\n' + (selected or '- No criteria assigned.\n\n') + after
46
+ mode = 'owned-criteria'
47
+ return ('## Generated intent context\n\n'
48
+ f'Source: {intent_path}\n'
49
+ f'Intent SHA256: {hashlib.sha256(intent.encode()).hexdigest()}\n'
50
+ f'Task: {task}\n'
51
+ f'Task SHA256: {hashlib.sha256(task_text.encode()).hexdigest()}\n'
52
+ f'Mode: {mode}\n\n'
53
+ 'Use this view for intent. All non-criterion text is verbatim; selected criteria retain '
54
+ 'their original numbers. The source remains authoritative. Read it if a dependency '
55
+ 'or ambiguity requires omitted criteria.\n\n' + projected)
56
+
57
+
58
+ def main() -> int:
59
+ parser = argparse.ArgumentParser(description=__doc__)
60
+ parser.add_argument('--repo', type=Path, required=True)
61
+ parser.add_argument('--task', type=Path, required=True)
62
+ args = parser.parse_args()
63
+ try:
64
+ output = render(args.repo, args.task)
65
+ except (OSError, contracts.HandoffError) as error:
66
+ print(str(error), file=sys.stderr)
67
+ return 1
68
+ print(output, end='')
69
+ return 0
70
+
71
+
72
+ if __name__ == '__main__':
73
+ raise SystemExit(main())
@@ -69,6 +69,24 @@ def output_usage(path: Path) -> int:
69
69
  return sum(usages)
70
70
 
71
71
 
72
+ def cumulative_counter(path: Path):
73
+ """One completed CLI invocation, with the thread identity needed for resume."""
74
+ identities, counters = set(), []
75
+ for line in path.read_text(encoding="utf-8").splitlines():
76
+ event = json.loads(line)
77
+ if "raw" in event:
78
+ event = json.loads(event["raw"])
79
+ if event.get("type") == "thread.started":
80
+ identities.add(event["thread_id"])
81
+ if event.get("type") == "turn.completed":
82
+ counters.append(event["usage"]["output_tokens"])
83
+ if len(identities) != 1 or len(counters) != 1:
84
+ raise ValueError("cumulative usage requires one identified, completed CLI invocation")
85
+ if type(counters[0]) is not int or counters[0] < 0:
86
+ raise ValueError("invalid cumulative output counter")
87
+ return identities.pop(), counters[0]
88
+
89
+
72
90
  def operate(args):
73
91
  ledger = args.ledger.absolute()
74
92
  if ledger.is_symlink():
@@ -92,9 +110,28 @@ def operate(args):
92
110
  if args.action == "record":
93
111
  source = str(args.events.resolve())
94
112
  observation = {"task": args.task, "output_tokens": output_usage(args.events)}
113
+ prior_events = getattr(args, "previous_events", None)
114
+ if prior_events is not None:
115
+ prior_source = str(prior_events.resolve())
116
+ prior = data["observations"].get(prior_source)
117
+ identity, total = cumulative_counter(args.events)
118
+ prior_identity, prior_total = cumulative_counter(prior_events)
119
+ if source == prior_source or identity != prior_identity or total < prior_total:
120
+ raise ValueError("cumulative resume has a different thread or a reset counter")
121
+ if prior is None or prior.get("reported_output_tokens", prior["output_tokens"]) != prior_total:
122
+ raise ValueError("previous cumulative invocation must be recorded unchanged first")
123
+ if any(key != source and row.get("previous_events") == prior_source
124
+ for key, row in data["observations"].items()):
125
+ raise ValueError("previous cumulative invocation already has a recorded successor")
126
+ observation.update(output_tokens=total - prior_total, reported_output_tokens=total,
127
+ previous_events=prior_source, session_id=identity)
95
128
  previous = data["observations"].get(source)
129
+ if previous and previous != observation and any(
130
+ row.get("previous_events") == source for row in data["observations"].values()):
131
+ raise ValueError("a cumulative predecessor cannot change after its successor is recorded")
96
132
  if previous and (previous["task"] != args.task or
97
- previous["output_tokens"] > observation["output_tokens"]):
133
+ previous["output_tokens"] > observation["output_tokens"] or
134
+ previous.get("previous_events") != observation.get("previous_events")):
98
135
  raise ValueError("observation cannot change task or reduce recorded usage")
99
136
  data["observations"][source] = observation
100
137
  atomic_write(ledger, json.dumps(data, indent=2) + "\n")
@@ -131,6 +168,8 @@ def main(argv=None):
131
168
  command.add_argument("--task", required=True)
132
169
  if name == "record":
133
170
  command.add_argument("--events", type=Path, required=True)
171
+ command.add_argument("--previous-events", type=Path,
172
+ help="previous recorded invocation when this CLI reports cumulative resume counters")
134
173
  if name == "admit":
135
174
  command.add_argument("--require-hard-cap", action="store_true")
136
175
  try:
@@ -2,9 +2,11 @@
2
2
  """Run canonical workflow helpers with fixed arguments and fail-stop receipts."""
3
3
 
4
4
  import argparse
5
+ import hashlib
5
6
  import json
6
7
  import subprocess
7
8
  import sys
9
+ import tempfile
8
10
  from pathlib import Path
9
11
 
10
12
  try:
@@ -16,13 +18,18 @@ except ImportError: # bundled copy inside a skill's scripts directory
16
18
  class StepFailed(RuntimeError):
17
19
  pass
18
20
 
21
+ INSPECTION_SPECS = (("inspect_codebase", "codebase-mapper", "codebase", "evidence-codebase.md"),
22
+ ("inspect_docs", "docs-auditor", "docs-audit", "DOCS-AUDIT.md"))
23
+
19
24
 
20
25
  def run_workflow(repo: Path, action: str, project_dir: str, expected_head: str = None,
21
- task_id: str = None, round_size: int = None) -> dict:
26
+ task_id: str = None, round_size: int = None, inspection: Path = None,
27
+ mapper_reviewed: bool = False) -> dict:
22
28
  steps = []
29
+ outputs = {}
23
30
  scripts = Path(__file__).resolve().parent
24
31
 
25
- def step(script, *arguments):
32
+ def step(script, *arguments, raw=False):
26
33
  command = [sys.executable, "-B", str(scripts / script), *arguments]
27
34
  completed = subprocess.run(command, cwd=repo, capture_output=True, text=True)
28
35
  receipt = {"script": script, "command": command, "exit_code": completed.returncode,
@@ -32,6 +39,8 @@ def run_workflow(repo: Path, action: str, project_dir: str, expected_head: str =
32
39
  sys.stderr.write(completed.stderr)
33
40
  if completed.returncode:
34
41
  raise StepFailed(script)
42
+ if raw:
43
+ return completed.stdout
35
44
  try:
36
45
  receipt["result"] = json.loads(completed.stdout)
37
46
  except json.JSONDecodeError as error:
@@ -42,6 +51,103 @@ def run_workflow(repo: Path, action: str, project_dir: str, expected_head: str =
42
51
  try:
43
52
  if action == "route":
44
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")
45
151
  elif action == "lint-round":
46
152
  head = subprocess.run(["git", "rev-parse", "--verify", "HEAD"],
47
153
  cwd=repo, capture_output=True, text=True, check=True).stdout.strip()
@@ -87,28 +193,31 @@ def run_workflow(repo: Path, action: str, project_dir: str, expected_head: str =
87
193
  if action == "approve-plan":
88
194
  step("pipeline_state.py", "approve", *common, "--kind", "plan",
89
195
  "--expected-head", expected_head)
90
- except (StepFailed, OSError, subprocess.CalledProcessError) as error:
196
+ except (StepFailed, OSError, subprocess.CalledProcessError, ValueError, KeyError, TypeError) as error:
91
197
  return {"status": "blocked", "reason": str(error), "steps": steps,
92
198
  "next": "$gsd-path-forensics"}
93
- return {"status": "complete", "steps": steps}
199
+ return {"status": "complete", "steps": steps, **outputs}
94
200
 
95
201
 
96
202
  def main(argv=None):
97
203
  parser = argparse.ArgumentParser(description=__doc__)
98
- parser.add_argument("action", choices=("route", "gate-plan", "approve-plan", "build-evidence", "lint-round", "prepare-task", "prepare-final"))
204
+ parser.add_argument("action", choices=("route", "gate-plan", "approve-plan", "build-evidence", "lint-round", "prepare-task", "prepare-final", "prepare-inspect", "finish-inspect"))
99
205
  parser.add_argument("--repo", type=Path, required=True)
100
206
  parser.add_argument("--project-dir", choices=(".project", ".project/next"), default=".project")
101
207
  parser.add_argument("--expected-head")
102
208
  parser.add_argument("--task-id")
103
209
  parser.add_argument("--round-size", type=int)
210
+ parser.add_argument("--inspection", type=Path)
211
+ parser.add_argument("--mapper-reviewed", action="store_true")
104
212
  arguments = parser.parse_args(argv)
105
- if arguments.action in {"approve-plan", "build-evidence", "prepare-task", "prepare-final"} and not arguments.expected_head:
213
+ if arguments.action in {"approve-plan", "build-evidence", "prepare-task", "prepare-final", "prepare-inspect", "finish-inspect"} and not arguments.expected_head:
106
214
  parser.error(f"{arguments.action} requires --expected-head")
107
215
  if arguments.action == "prepare-task" and (not arguments.task_id or arguments.round_size is None):
108
216
  parser.error("prepare-task requires --task-id and --round-size")
109
217
  result = run_workflow(arguments.repo.resolve(), arguments.action,
110
218
  arguments.project_dir, arguments.expected_head,
111
- arguments.task_id, arguments.round_size)
219
+ arguments.task_id, arguments.round_size, arguments.inspection,
220
+ arguments.mapper_reviewed)
112
221
  print(json.dumps(result, sort_keys=True))
113
222
  return 0 if result["status"] == "complete" else 1
114
223
 
@@ -17,7 +17,7 @@ Wave verdict: <pass | blocked — blocked if any task fails>
17
17
  Cycle: <C>
18
18
  Depth: <full | deep | verify-only — verify-only is orchestrator-written from
19
19
  its isolated Verify evidence; no independent reviewer ran>
20
- Lens: <contract | adversarial — deep reviews only; empty or omitted
20
+ Lens: <contract | adversarial — deep reviews only; leave this value empty or omit the line
21
21
  otherwise>
22
22
  Tasks reviewed: <count>
23
23