@opengsd/gsd-path 1.0.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 (398) hide show
  1. package/AGENTS.md +397 -0
  2. package/DOCS.md +341 -0
  3. package/FULL.md +475 -0
  4. package/GUIDE.md +23 -0
  5. package/HOOKS.md +273 -0
  6. package/LICENSE +21 -0
  7. package/MIGRATE.md +100 -0
  8. package/QUICK.md +146 -0
  9. package/README.md +280 -0
  10. package/RUNTIME.md +229 -0
  11. package/UPDATE.md +196 -0
  12. package/WORKFLOW.md +683 -0
  13. package/package.json +80 -0
  14. package/platforms/claude/dispatch.md +63 -0
  15. package/platforms/copilot/dispatch.md +61 -0
  16. package/platforms/cursor/agent.md +17 -0
  17. package/platforms/cursor/dispatch.md +63 -0
  18. package/platforms/grok/dispatch.md +61 -0
  19. package/platforms/kimi/dispatch.md +64 -0
  20. package/platforms/kiro/dispatch.md +58 -0
  21. package/platforms/opencode/dispatch.md +62 -0
  22. package/platforms/qwen/dispatch.md +60 -0
  23. package/platforms/shared-agents/dispatch.md +131 -0
  24. package/plugin.json +14 -0
  25. package/scripts/_common.py +180 -0
  26. package/scripts/archive_milestone.py +2265 -0
  27. package/scripts/bootstrap_repository.py +710 -0
  28. package/scripts/build_state.py +854 -0
  29. package/scripts/check_docs_audit.py +463 -0
  30. package/scripts/check_handoffs.py +1855 -0
  31. package/scripts/check_task_briefs.py +376 -0
  32. package/scripts/check_update.py +93 -0
  33. package/scripts/core_hook_gate.py +34 -0
  34. package/scripts/core_hook_settings.py +119 -0
  35. package/scripts/detect_project.py +1517 -0
  36. package/scripts/discussion_records.py +619 -0
  37. package/scripts/discussion_validate.py +1321 -0
  38. package/scripts/dispatch_driver.py +1812 -0
  39. package/scripts/git_guard.py +759 -0
  40. package/scripts/guard_hook.py +2124 -0
  41. package/scripts/install.mjs +3239 -0
  42. package/scripts/install.py +3008 -0
  43. package/scripts/integration.py +1433 -0
  44. package/scripts/isolation.py +3538 -0
  45. package/scripts/lean_verification.py +256 -0
  46. package/scripts/loop_run.py +837 -0
  47. package/scripts/migrate_core.py +169 -0
  48. package/scripts/pipeline_diagnose.py +715 -0
  49. package/scripts/pipeline_git.py +940 -0
  50. package/scripts/pipeline_state.py +2291 -0
  51. package/scripts/pipeline_undo.py +1039 -0
  52. package/scripts/promote_lookahead.py +415 -0
  53. package/scripts/review_findings.py +714 -0
  54. package/scripts/review_panel.py +553 -0
  55. package/scripts/skill-resources.json +340 -0
  56. package/scripts/state_checkpoint.py +1039 -0
  57. package/scripts/state_promote.py +743 -0
  58. package/scripts/status_runtime.py +122 -0
  59. package/scripts/sync_skill_resources.py +259 -0
  60. package/scripts/token_budget.py +146 -0
  61. package/scripts/wizard.mjs +179 -0
  62. package/scripts/workflow_run.py +117 -0
  63. package/skills/gsd-path/BUILD.md +700 -0
  64. package/skills/gsd-path/DECIDE.md +115 -0
  65. package/skills/gsd-path/DEFINE.md +297 -0
  66. package/skills/gsd-path/DOCS-AUDIT.md +190 -0
  67. package/skills/gsd-path/INSPECT.md +167 -0
  68. package/skills/gsd-path/PLAN.md +411 -0
  69. package/skills/gsd-path/RESEARCH.md +159 -0
  70. package/skills/gsd-path/ROADMAP.md +215 -0
  71. package/skills/gsd-path/SHIP.md +412 -0
  72. package/skills/gsd-path/SKILL.md +471 -0
  73. package/skills/gsd-path/agents/openai.yaml +6 -0
  74. package/skills/gsd-path/references/codebase-mapper.md +52 -0
  75. package/skills/gsd-path/references/coder.md +90 -0
  76. package/skills/gsd-path/references/decider.md +36 -0
  77. package/skills/gsd-path/references/dispatch.md +131 -0
  78. package/skills/gsd-path/references/docs-auditor.md +60 -0
  79. package/skills/gsd-path/references/planner.md +104 -0
  80. package/skills/gsd-path/references/researcher.md +42 -0
  81. package/skills/gsd-path/references/reviewer.md +188 -0
  82. package/skills/gsd-path/references/roadmapper.md +48 -0
  83. package/skills/gsd-path/scripts/_common.py +180 -0
  84. package/skills/gsd-path/scripts/archive_milestone.py +2265 -0
  85. package/skills/gsd-path/scripts/bootstrap_repository.py +710 -0
  86. package/skills/gsd-path/scripts/build_state.py +854 -0
  87. package/skills/gsd-path/scripts/check_docs_audit.py +463 -0
  88. package/skills/gsd-path/scripts/check_handoffs.py +1855 -0
  89. package/skills/gsd-path/scripts/check_task_briefs.py +376 -0
  90. package/skills/gsd-path/scripts/check_update.py +93 -0
  91. package/skills/gsd-path/scripts/detect_project.py +1517 -0
  92. package/skills/gsd-path/scripts/discussion_records.py +619 -0
  93. package/skills/gsd-path/scripts/discussion_validate.py +1321 -0
  94. package/skills/gsd-path/scripts/dispatch_driver.py +1812 -0
  95. package/skills/gsd-path/scripts/integration.py +1433 -0
  96. package/skills/gsd-path/scripts/isolation.py +3538 -0
  97. package/skills/gsd-path/scripts/lean_verification.py +256 -0
  98. package/skills/gsd-path/scripts/loop_run.py +837 -0
  99. package/skills/gsd-path/scripts/pipeline_git.py +940 -0
  100. package/skills/gsd-path/scripts/pipeline_state.py +2291 -0
  101. package/skills/gsd-path/scripts/promote_lookahead.py +415 -0
  102. package/skills/gsd-path/scripts/review_findings.py +714 -0
  103. package/skills/gsd-path/scripts/review_panel.py +553 -0
  104. package/skills/gsd-path/scripts/state_checkpoint.py +1039 -0
  105. package/skills/gsd-path/scripts/state_promote.py +743 -0
  106. package/skills/gsd-path/scripts/token_budget.py +146 -0
  107. package/skills/gsd-path/scripts/workflow_run.py +117 -0
  108. package/skills/gsd-path/templates/answers.md +29 -0
  109. package/skills/gsd-path/templates/archive-manifest.md +37 -0
  110. package/skills/gsd-path/templates/charter.md +50 -0
  111. package/skills/gsd-path/templates/codebase.md +46 -0
  112. package/skills/gsd-path/templates/dialogue.md +21 -0
  113. package/skills/gsd-path/templates/docs-audit.md +69 -0
  114. package/skills/gsd-path/templates/evidence.md +24 -0
  115. package/skills/gsd-path/templates/final-review.md +27 -0
  116. package/skills/gsd-path/templates/gap-review.md +20 -0
  117. package/skills/gsd-path/templates/intent.md +98 -0
  118. package/skills/gsd-path/templates/loop.md +59 -0
  119. package/skills/gsd-path/templates/patch-findings.md +16 -0
  120. package/skills/gsd-path/templates/plan-panel.md +25 -0
  121. package/skills/gsd-path/templates/plan.md +89 -0
  122. package/skills/gsd-path/templates/repository.md +16 -0
  123. package/skills/gsd-path/templates/research-handoff.md +25 -0
  124. package/skills/gsd-path/templates/roadmap.md +38 -0
  125. package/skills/gsd-path/templates/skeptic.md +36 -0
  126. package/skills/gsd-path/templates/state.md +27 -0
  127. package/skills/gsd-path/templates/synthesis.md +36 -0
  128. package/skills/gsd-path/templates/task.md +74 -0
  129. package/skills/gsd-path/templates/wave-panel.md +25 -0
  130. package/skills/gsd-path/templates/wave-review.md +64 -0
  131. package/skills/gsd-path-build/SKILL.md +700 -0
  132. package/skills/gsd-path-build/agents/openai.yaml +6 -0
  133. package/skills/gsd-path-build/references/coder.md +90 -0
  134. package/skills/gsd-path-build/references/dispatch.md +131 -0
  135. package/skills/gsd-path-build/references/reviewer.md +188 -0
  136. package/skills/gsd-path-build/scripts/_common.py +180 -0
  137. package/skills/gsd-path-build/scripts/archive_milestone.py +2265 -0
  138. package/skills/gsd-path-build/scripts/build_state.py +854 -0
  139. package/skills/gsd-path-build/scripts/check_handoffs.py +1855 -0
  140. package/skills/gsd-path-build/scripts/check_task_briefs.py +376 -0
  141. package/skills/gsd-path-build/scripts/discussion_records.py +619 -0
  142. package/skills/gsd-path-build/scripts/discussion_validate.py +1321 -0
  143. package/skills/gsd-path-build/scripts/dispatch_driver.py +1812 -0
  144. package/skills/gsd-path-build/scripts/integration.py +1433 -0
  145. package/skills/gsd-path-build/scripts/isolation.py +3538 -0
  146. package/skills/gsd-path-build/scripts/loop_run.py +837 -0
  147. package/skills/gsd-path-build/scripts/pipeline_git.py +940 -0
  148. package/skills/gsd-path-build/scripts/pipeline_state.py +2291 -0
  149. package/skills/gsd-path-build/scripts/review_findings.py +714 -0
  150. package/skills/gsd-path-build/scripts/review_panel.py +553 -0
  151. package/skills/gsd-path-build/scripts/state_checkpoint.py +1039 -0
  152. package/skills/gsd-path-build/scripts/state_promote.py +743 -0
  153. package/skills/gsd-path-build/scripts/token_budget.py +146 -0
  154. package/skills/gsd-path-build/scripts/workflow_run.py +117 -0
  155. package/skills/gsd-path-build/templates/skeptic.md +36 -0
  156. package/skills/gsd-path-build/templates/task.md +74 -0
  157. package/skills/gsd-path-build/templates/wave-panel.md +25 -0
  158. package/skills/gsd-path-build/templates/wave-review.md +64 -0
  159. package/skills/gsd-path-decide/SKILL.md +115 -0
  160. package/skills/gsd-path-decide/agents/openai.yaml +6 -0
  161. package/skills/gsd-path-decide/references/decider.md +36 -0
  162. package/skills/gsd-path-decide/references/dispatch.md +131 -0
  163. package/skills/gsd-path-decide/scripts/_common.py +180 -0
  164. package/skills/gsd-path-decide/scripts/check_handoffs.py +1855 -0
  165. package/skills/gsd-path-decide/scripts/check_task_briefs.py +376 -0
  166. package/skills/gsd-path-decide/scripts/discussion_records.py +619 -0
  167. package/skills/gsd-path-decide/scripts/isolation.py +3538 -0
  168. package/skills/gsd-path-decide/scripts/pipeline_git.py +940 -0
  169. package/skills/gsd-path-decide/scripts/pipeline_state.py +2291 -0
  170. package/skills/gsd-path-decide/scripts/state_checkpoint.py +1039 -0
  171. package/skills/gsd-path-decide/scripts/state_promote.py +743 -0
  172. package/skills/gsd-path-decide/templates/synthesis.md +36 -0
  173. package/skills/gsd-path-define/SKILL.md +297 -0
  174. package/skills/gsd-path-define/agents/openai.yaml +6 -0
  175. package/skills/gsd-path-define/scripts/_common.py +180 -0
  176. package/skills/gsd-path-define/scripts/check_handoffs.py +1855 -0
  177. package/skills/gsd-path-define/scripts/check_task_briefs.py +376 -0
  178. package/skills/gsd-path-define/scripts/detect_project.py +1517 -0
  179. package/skills/gsd-path-define/scripts/discussion_records.py +619 -0
  180. package/skills/gsd-path-define/scripts/isolation.py +3538 -0
  181. package/skills/gsd-path-define/scripts/pipeline_git.py +940 -0
  182. package/skills/gsd-path-define/scripts/pipeline_state.py +2291 -0
  183. package/skills/gsd-path-define/scripts/state_checkpoint.py +1039 -0
  184. package/skills/gsd-path-define/scripts/state_promote.py +743 -0
  185. package/skills/gsd-path-define/templates/charter.md +50 -0
  186. package/skills/gsd-path-define/templates/intent.md +98 -0
  187. package/skills/gsd-path-define/templates/state.md +27 -0
  188. package/skills/gsd-path-discuss/SKILL.md +162 -0
  189. package/skills/gsd-path-discuss/agents/openai.yaml +6 -0
  190. package/skills/gsd-path-discuss/scripts/_common.py +180 -0
  191. package/skills/gsd-path-discuss/scripts/discussion_records.py +619 -0
  192. package/skills/gsd-path-discuss/templates/answers.md +29 -0
  193. package/skills/gsd-path-discuss/templates/dialogue.md +21 -0
  194. package/skills/gsd-path-docs-audit/SKILL.md +190 -0
  195. package/skills/gsd-path-docs-audit/agents/openai.yaml +6 -0
  196. package/skills/gsd-path-docs-audit/references/dispatch.md +131 -0
  197. package/skills/gsd-path-docs-audit/references/docs-auditor.md +60 -0
  198. package/skills/gsd-path-docs-audit/scripts/_common.py +180 -0
  199. package/skills/gsd-path-docs-audit/scripts/check_docs_audit.py +463 -0
  200. package/skills/gsd-path-docs-audit/scripts/check_handoffs.py +1855 -0
  201. package/skills/gsd-path-docs-audit/scripts/check_task_briefs.py +376 -0
  202. package/skills/gsd-path-docs-audit/scripts/discussion_records.py +619 -0
  203. package/skills/gsd-path-docs-audit/scripts/isolation.py +3538 -0
  204. package/skills/gsd-path-docs-audit/scripts/pipeline_git.py +940 -0
  205. package/skills/gsd-path-docs-audit/scripts/pipeline_state.py +2291 -0
  206. package/skills/gsd-path-docs-audit/scripts/state_checkpoint.py +1039 -0
  207. package/skills/gsd-path-docs-audit/scripts/state_promote.py +743 -0
  208. package/skills/gsd-path-docs-audit/templates/docs-audit.md +69 -0
  209. package/skills/gsd-path-forensics/SKILL.md +39 -0
  210. package/skills/gsd-path-forensics/agents/openai.yaml +6 -0
  211. package/skills/gsd-path-forensics/scripts/_common.py +180 -0
  212. package/skills/gsd-path-forensics/scripts/discussion_records.py +619 -0
  213. package/skills/gsd-path-forensics/scripts/pipeline_diagnose.py +715 -0
  214. package/skills/gsd-path-forensics/scripts/pipeline_undo.py +1039 -0
  215. package/skills/gsd-path-inspect/SKILL.md +167 -0
  216. package/skills/gsd-path-inspect/agents/openai.yaml +6 -0
  217. package/skills/gsd-path-inspect/references/codebase-mapper.md +52 -0
  218. package/skills/gsd-path-inspect/references/dispatch.md +131 -0
  219. package/skills/gsd-path-inspect/references/docs-auditor.md +60 -0
  220. package/skills/gsd-path-inspect/scripts/_common.py +180 -0
  221. package/skills/gsd-path-inspect/scripts/check_docs_audit.py +463 -0
  222. package/skills/gsd-path-inspect/scripts/check_handoffs.py +1855 -0
  223. package/skills/gsd-path-inspect/scripts/check_task_briefs.py +376 -0
  224. package/skills/gsd-path-inspect/scripts/detect_project.py +1517 -0
  225. package/skills/gsd-path-inspect/scripts/discussion_records.py +619 -0
  226. package/skills/gsd-path-inspect/scripts/isolation.py +3538 -0
  227. package/skills/gsd-path-inspect/scripts/pipeline_git.py +940 -0
  228. package/skills/gsd-path-inspect/scripts/pipeline_state.py +2291 -0
  229. package/skills/gsd-path-inspect/scripts/state_checkpoint.py +1039 -0
  230. package/skills/gsd-path-inspect/scripts/state_promote.py +743 -0
  231. package/skills/gsd-path-inspect/templates/codebase.md +46 -0
  232. package/skills/gsd-path-inspect/templates/docs-audit.md +69 -0
  233. package/skills/gsd-path-inspect/templates/state.md +27 -0
  234. package/skills/gsd-path-loop/SKILL.md +98 -0
  235. package/skills/gsd-path-loop/agents/openai.yaml +6 -0
  236. package/skills/gsd-path-loop/examples/ci-repair.LOOP.md +61 -0
  237. package/skills/gsd-path-loop/scripts/_common.py +180 -0
  238. package/skills/gsd-path-loop/scripts/discussion_records.py +619 -0
  239. package/skills/gsd-path-loop/scripts/loop_run.py +837 -0
  240. package/skills/gsd-path-loop/templates/loop.md +59 -0
  241. package/skills/gsd-path-migrate/SKILL.md +134 -0
  242. package/skills/gsd-path-migrate/agents/openai.yaml +6 -0
  243. package/skills/gsd-path-migrate/scripts/core_hook_gate.py +34 -0
  244. package/skills/gsd-path-migrate/scripts/core_hook_settings.py +119 -0
  245. package/skills/gsd-path-migrate/scripts/discussion_records.py +619 -0
  246. package/skills/gsd-path-migrate/scripts/migrate_core.py +169 -0
  247. package/skills/gsd-path-plan/SKILL.md +411 -0
  248. package/skills/gsd-path-plan/agents/openai.yaml +6 -0
  249. package/skills/gsd-path-plan/references/dispatch.md +131 -0
  250. package/skills/gsd-path-plan/references/planner.md +104 -0
  251. package/skills/gsd-path-plan/scripts/_common.py +180 -0
  252. package/skills/gsd-path-plan/scripts/check_handoffs.py +1855 -0
  253. package/skills/gsd-path-plan/scripts/check_task_briefs.py +376 -0
  254. package/skills/gsd-path-plan/scripts/discussion_records.py +619 -0
  255. package/skills/gsd-path-plan/scripts/isolation.py +3538 -0
  256. package/skills/gsd-path-plan/scripts/pipeline_git.py +940 -0
  257. package/skills/gsd-path-plan/scripts/pipeline_state.py +2291 -0
  258. package/skills/gsd-path-plan/scripts/review_panel.py +553 -0
  259. package/skills/gsd-path-plan/scripts/state_checkpoint.py +1039 -0
  260. package/skills/gsd-path-plan/scripts/state_promote.py +743 -0
  261. package/skills/gsd-path-plan/scripts/workflow_run.py +117 -0
  262. package/skills/gsd-path-plan/templates/patch-findings.md +16 -0
  263. package/skills/gsd-path-plan/templates/plan-panel.md +25 -0
  264. package/skills/gsd-path-plan/templates/plan.md +89 -0
  265. package/skills/gsd-path-plan/templates/task.md +74 -0
  266. package/skills/gsd-path-research/SKILL.md +159 -0
  267. package/skills/gsd-path-research/agents/openai.yaml +6 -0
  268. package/skills/gsd-path-research/references/dispatch.md +131 -0
  269. package/skills/gsd-path-research/references/researcher.md +42 -0
  270. package/skills/gsd-path-research/scripts/_common.py +180 -0
  271. package/skills/gsd-path-research/scripts/check_handoffs.py +1855 -0
  272. package/skills/gsd-path-research/scripts/check_task_briefs.py +376 -0
  273. package/skills/gsd-path-research/scripts/discussion_records.py +619 -0
  274. package/skills/gsd-path-research/scripts/isolation.py +3538 -0
  275. package/skills/gsd-path-research/scripts/pipeline_git.py +940 -0
  276. package/skills/gsd-path-research/scripts/pipeline_state.py +2291 -0
  277. package/skills/gsd-path-research/scripts/state_checkpoint.py +1039 -0
  278. package/skills/gsd-path-research/scripts/state_promote.py +743 -0
  279. package/skills/gsd-path-research/templates/evidence.md +24 -0
  280. package/skills/gsd-path-research/templates/research-handoff.md +25 -0
  281. package/skills/gsd-path-roadmap/SKILL.md +215 -0
  282. package/skills/gsd-path-roadmap/agents/openai.yaml +6 -0
  283. package/skills/gsd-path-roadmap/references/dispatch.md +131 -0
  284. package/skills/gsd-path-roadmap/references/roadmapper.md +48 -0
  285. package/skills/gsd-path-roadmap/scripts/_common.py +180 -0
  286. package/skills/gsd-path-roadmap/scripts/archive_milestone.py +2265 -0
  287. package/skills/gsd-path-roadmap/scripts/check_handoffs.py +1855 -0
  288. package/skills/gsd-path-roadmap/scripts/check_task_briefs.py +376 -0
  289. package/skills/gsd-path-roadmap/scripts/detect_project.py +1517 -0
  290. package/skills/gsd-path-roadmap/scripts/discussion_records.py +619 -0
  291. package/skills/gsd-path-roadmap/scripts/discussion_validate.py +1321 -0
  292. package/skills/gsd-path-roadmap/scripts/integration.py +1433 -0
  293. package/skills/gsd-path-roadmap/scripts/isolation.py +3538 -0
  294. package/skills/gsd-path-roadmap/scripts/pipeline_git.py +940 -0
  295. package/skills/gsd-path-roadmap/scripts/pipeline_state.py +2291 -0
  296. package/skills/gsd-path-roadmap/scripts/promote_lookahead.py +415 -0
  297. package/skills/gsd-path-roadmap/scripts/review_panel.py +553 -0
  298. package/skills/gsd-path-roadmap/scripts/state_checkpoint.py +1039 -0
  299. package/skills/gsd-path-roadmap/scripts/state_promote.py +743 -0
  300. package/skills/gsd-path-roadmap/templates/roadmap.md +38 -0
  301. package/skills/gsd-path-ship/SKILL.md +412 -0
  302. package/skills/gsd-path-ship/agents/openai.yaml +6 -0
  303. package/skills/gsd-path-ship/references/dispatch.md +131 -0
  304. package/skills/gsd-path-ship/references/reviewer.md +188 -0
  305. package/skills/gsd-path-ship/scripts/_common.py +180 -0
  306. package/skills/gsd-path-ship/scripts/archive_milestone.py +2265 -0
  307. package/skills/gsd-path-ship/scripts/build_state.py +854 -0
  308. package/skills/gsd-path-ship/scripts/check_handoffs.py +1855 -0
  309. package/skills/gsd-path-ship/scripts/check_task_briefs.py +376 -0
  310. package/skills/gsd-path-ship/scripts/discussion_records.py +619 -0
  311. package/skills/gsd-path-ship/scripts/discussion_validate.py +1321 -0
  312. package/skills/gsd-path-ship/scripts/integration.py +1433 -0
  313. package/skills/gsd-path-ship/scripts/isolation.py +3538 -0
  314. package/skills/gsd-path-ship/scripts/lean_verification.py +256 -0
  315. package/skills/gsd-path-ship/scripts/pipeline_git.py +940 -0
  316. package/skills/gsd-path-ship/scripts/pipeline_state.py +2291 -0
  317. package/skills/gsd-path-ship/scripts/review_panel.py +553 -0
  318. package/skills/gsd-path-ship/scripts/state_checkpoint.py +1039 -0
  319. package/skills/gsd-path-ship/scripts/state_promote.py +743 -0
  320. package/skills/gsd-path-ship/scripts/workflow_run.py +117 -0
  321. package/skills/gsd-path-ship/templates/archive-manifest.md +37 -0
  322. package/skills/gsd-path-ship/templates/final-review.md +27 -0
  323. package/skills/gsd-path-ship/templates/gap-review.md +20 -0
  324. package/skills/gsd-path-ship/templates/patch-findings.md +16 -0
  325. package/skills/gsd-path-ship/templates/wave-review.md +64 -0
  326. package/skills/gsd-path-undo/SKILL.md +45 -0
  327. package/skills/gsd-path-undo/agents/openai.yaml +6 -0
  328. package/skills/gsd-path-undo/scripts/_common.py +180 -0
  329. package/skills/gsd-path-undo/scripts/discussion_records.py +619 -0
  330. package/skills/gsd-path-undo/scripts/pipeline_undo.py +1039 -0
  331. package/skills/path/BUILD.md +700 -0
  332. package/skills/path/DECIDE.md +115 -0
  333. package/skills/path/DEFINE.md +297 -0
  334. package/skills/path/DOCS-AUDIT.md +190 -0
  335. package/skills/path/INSPECT.md +167 -0
  336. package/skills/path/PLAN.md +411 -0
  337. package/skills/path/RESEARCH.md +159 -0
  338. package/skills/path/ROADMAP.md +215 -0
  339. package/skills/path/SHIP.md +412 -0
  340. package/skills/path/SKILL.md +471 -0
  341. package/skills/path/agents/openai.yaml +6 -0
  342. package/skills/path/references/codebase-mapper.md +52 -0
  343. package/skills/path/references/coder.md +90 -0
  344. package/skills/path/references/decider.md +36 -0
  345. package/skills/path/references/dispatch.md +131 -0
  346. package/skills/path/references/docs-auditor.md +60 -0
  347. package/skills/path/references/planner.md +104 -0
  348. package/skills/path/references/researcher.md +42 -0
  349. package/skills/path/references/reviewer.md +188 -0
  350. package/skills/path/references/roadmapper.md +48 -0
  351. package/skills/path/scripts/_common.py +180 -0
  352. package/skills/path/scripts/archive_milestone.py +2265 -0
  353. package/skills/path/scripts/bootstrap_repository.py +710 -0
  354. package/skills/path/scripts/build_state.py +854 -0
  355. package/skills/path/scripts/check_docs_audit.py +463 -0
  356. package/skills/path/scripts/check_handoffs.py +1855 -0
  357. package/skills/path/scripts/check_task_briefs.py +376 -0
  358. package/skills/path/scripts/check_update.py +93 -0
  359. package/skills/path/scripts/detect_project.py +1517 -0
  360. package/skills/path/scripts/discussion_records.py +619 -0
  361. package/skills/path/scripts/discussion_validate.py +1321 -0
  362. package/skills/path/scripts/dispatch_driver.py +1812 -0
  363. package/skills/path/scripts/integration.py +1433 -0
  364. package/skills/path/scripts/isolation.py +3538 -0
  365. package/skills/path/scripts/lean_verification.py +256 -0
  366. package/skills/path/scripts/loop_run.py +837 -0
  367. package/skills/path/scripts/pipeline_git.py +940 -0
  368. package/skills/path/scripts/pipeline_state.py +2291 -0
  369. package/skills/path/scripts/promote_lookahead.py +415 -0
  370. package/skills/path/scripts/review_findings.py +714 -0
  371. package/skills/path/scripts/review_panel.py +553 -0
  372. package/skills/path/scripts/state_checkpoint.py +1039 -0
  373. package/skills/path/scripts/state_promote.py +743 -0
  374. package/skills/path/scripts/token_budget.py +146 -0
  375. package/skills/path/scripts/workflow_run.py +117 -0
  376. package/skills/path/templates/answers.md +29 -0
  377. package/skills/path/templates/archive-manifest.md +37 -0
  378. package/skills/path/templates/charter.md +50 -0
  379. package/skills/path/templates/codebase.md +46 -0
  380. package/skills/path/templates/dialogue.md +21 -0
  381. package/skills/path/templates/docs-audit.md +69 -0
  382. package/skills/path/templates/evidence.md +24 -0
  383. package/skills/path/templates/final-review.md +27 -0
  384. package/skills/path/templates/gap-review.md +20 -0
  385. package/skills/path/templates/intent.md +98 -0
  386. package/skills/path/templates/loop.md +59 -0
  387. package/skills/path/templates/patch-findings.md +16 -0
  388. package/skills/path/templates/plan-panel.md +25 -0
  389. package/skills/path/templates/plan.md +89 -0
  390. package/skills/path/templates/repository.md +16 -0
  391. package/skills/path/templates/research-handoff.md +25 -0
  392. package/skills/path/templates/roadmap.md +38 -0
  393. package/skills/path/templates/skeptic.md +36 -0
  394. package/skills/path/templates/state.md +27 -0
  395. package/skills/path/templates/synthesis.md +36 -0
  396. package/skills/path/templates/task.md +74 -0
  397. package/skills/path/templates/wave-panel.md +25 -0
  398. package/skills/path/templates/wave-review.md +64 -0
@@ -0,0 +1,24 @@
1
+ # Evidence — <dimension>
2
+
3
+ <!-- Written by one researcher role. Consumed by the decider. -->
4
+
5
+ Dimension: <domain | stack | pitfalls | similar | custom>
6
+ Questions assigned: <exact RESEARCH questions joined by "; ", or "none">
7
+
8
+ ## Finding: <short claim as heading>
9
+
10
+ - **Claim**: <one specific, falsifiable statement>
11
+ - **Source**: <URL / doc / repo path actually opened>
12
+ - **Confidence**: <high | medium | low>
13
+ - **Why it matters here**: <one line tying this to INTENT.md>
14
+
15
+ <!-- One block per load-bearing finding — no quota. Repeat as needed. -->
16
+
17
+ ## Assigned questions — answers
18
+
19
+ - <question> → <answer with source, or "no reliable source found">
20
+
21
+ ## Dead ends
22
+
23
+ <!-- What was checked and didn't pan out, so nobody re-treads it. -->
24
+ - <path explored> — <why it's a dead end>
@@ -0,0 +1,25 @@
1
+ # Research Handoff
2
+
3
+ <!-- Written by the research orchestrator and consumed by decide. -->
4
+
5
+ Phase: research
6
+ Status: complete
7
+ Intent: `.project/intent/INTENT.md`
8
+ <!-- Program flow (no milestone INTENT exists): write the Intent line as
9
+ `.project/CHARTER.md` instead — the validator accepts exactly one of the
10
+ two paths, matching the file that actually exists. -->
11
+
12
+ ## Dispatch
13
+
14
+ <!-- Include every standard dimension exactly once. A custom dimension may
15
+ supplement these rows, never replace a standard row. -->
16
+ - `domain` — dispatched → `.project/research/evidence-domain.md` — <why this dimension ran>
17
+ - `stack` — skipped → none — <why this dimension was skipped>
18
+ - `pitfalls` — skipped → none — <why this dimension was skipped>
19
+ - `similar` — skipped → none — <why this dimension was skipped>
20
+
21
+ ## Question assignments
22
+
23
+ <!-- Copy every [RESEARCH] question from INTENT.md exactly once. Use `- none`
24
+ only when INTENT.md has no [RESEARCH] questions. -->
25
+ - `[RESEARCH] <question copied from INTENT.md>` → `domain`
@@ -0,0 +1,215 @@
1
+ ---
2
+ name: gsd-path-roadmap
3
+ description: Slice an approved GSD Path program charter into a dependency-ordered roadmap of independently shippable milestones. Use only when the user explicitly invokes $gsd-path-roadmap or an active $gsd-path router explicitly routes to this phase.
4
+ ---
5
+
6
+ # GSD Path Roadmap Phase
7
+
8
+ Dispatch one roadmapper, gate its roadmap, and obtain the single approval that
9
+ authorizes milestone planning. Rolling-wave: the roadmap scopes every
10
+ milestone; waves and tasks belong to `$gsd-path-plan`.
11
+
12
+ Routing instructions below are caller handoffs under the AGENTS.md handoff
13
+ rule; never invoke an explicit-only sibling skill yourself.
14
+
15
+ Before dispatch and again before approval, apply the AGENTS.md
16
+ pending-answer rule with the bundled `scripts/discussion_records.py`; a
17
+ follow-up owned by roadmap is resolved in ROADMAP.md, or the phase blocks.
18
+
19
+ ## Preconditions
20
+
21
+ Require `pipeline_state.py validate --repo <absolute root>` to pass; otherwise
22
+ return to `$gsd-path` for ownership checking. Legal entry is
23
+ `decide/done` with an existing `.project/CHARTER.md` and no `.project/ROADMAP.md`
24
+ yet, `roadmap/active|blocked`, or a
25
+ milestone-boundary re-slice: `inspect/active` or `define/active` with no
26
+ approved INTENT.md for the next milestone and a user request to re-scope the
27
+ remaining `pending` entries,
28
+ or `roadmap/active` with STATE.milestone null and an `abandoned` entry in
29
+ ROADMAP.md (the post-abandon re-slice the build orchestrator hands off).
30
+ Enter from `decide/done` only with `pipeline_state.py transition`, exact
31
+ expected phase/status/milestone/branch/archive fields, event `roadmap started`,
32
+ and `--set-phase roadmap --set-status active`; never edit STATE directly. In a
33
+ milestone-boundary re-slice, preserve the entering `inspect/active` or
34
+ `define/active` state throughout the re-slice.
35
+ Any later phase blocks; mid-milestone
36
+ re-scope is never legal — finish or ship the active milestone first. A
37
+ `decide/done` state with ROADMAP.md already present is milestone-scope decide;
38
+ route to `$gsd-path-plan`, never regenerate the roadmap beneath it. Absent
39
+ CHARTER.md, this is not a program: route to `$gsd-path`, which continues the
40
+ single-milestone flow at plan. Before dispatching every re-slice, run the
41
+ bundled `scripts/promote_lookahead.py snapshot-roadmap --roadmap
42
+ .project/ROADMAP.md --snapshot .project/ROADMAP.before-reslice.md` helper.
43
+ Create the baseline once and retain it through every revision; an `existing`
44
+ result is recovery evidence and must never be replaced from the current
45
+ candidate. When `.project/next/` holds a lookahead track, also save its
46
+ milestone slug. Do not ask for the keep/discard ruling until the candidate
47
+ roadmap has been generated and passed its gate.
48
+
49
+ Require `.project/CHARTER.md` and `.project/SYNTHESIS.md` (program scope) with
50
+ a non-empty `## Decisions` or `## Settled` section and no unresolved
51
+ `NEEDS-USER` items before dispatch. Route to the producing phase when a
52
+ precondition fails.
53
+
54
+ ## Process
55
+
56
+ 1. Read the local [roadmap template](templates/roadmap.md) and resolve it to an
57
+ absolute path.
58
+ 2. Read the local [roadmapper role](references/roadmapper.md), then follow the
59
+ local [runtime dispatch contract](references/dispatch.md) with deterministic
60
+ logical task name `roadmap` and a `heavy` tier hint. Give it absolute role,
61
+ `AGENTS.md`, `WORKFLOW.md`, CHARTER.md, SYNTHESIS.md, every dispatched
62
+ evidence file named in `.project/research/RESEARCH.md` — after milestone
63
+ archival has moved the active research directory, name the read-only
64
+ archived manifest and evidence copies under their
65
+ `.project/archive/<NNN>-<slug>/research/` paths
66
+ instead — template, and output
67
+ paths, including `.project/LESSONS.md` when it exists. On a re-slice, also
68
+ give `.project/ROADMAP.before-reslice.md` with the instruction to preserve
69
+ `shipped` entries byte-for-byte except Status/Archive/Integrated fields and
70
+ to never modify `abandoned` entries at all. For a milestone-boundary
71
+ re-slice, also preserve the existing `active` entry byte-for-byte; only
72
+ `pending` entries are in scope.
73
+ The output is exactly `.project/ROADMAP.md` — no other location is
74
+ canonical.
75
+ 3. Gate ROADMAP.md:
76
+ First run `python3 <absolute check_handoffs.py> roadmap --repo <absolute
77
+ root>`; its structural result is required in addition to the semantic
78
+ checks below.
79
+ - Every CHARTER.md `Full scope: in` item maps to at least one milestone,
80
+ and every milestone traces back to charter scope.
81
+ - Every milestone entry has Goal, Depends on, Surfaces, Status, Archive,
82
+ Scope in/out, Success criteria, Risks, and Open questions fields; ids are
83
+ unique and ordered.
84
+ - Every milestone whose Surfaces is not `none` has at least one success
85
+ criterion observable at each named surface. A milestone that delivers
86
+ something a person uses never carries `Surfaces: none`.
87
+ - Dependencies reference earlier milestone ids and form an acyclic graph.
88
+ - M001 is the thinnest end-to-end skeleton that burns the riskiest
89
+ synthesis decisions.
90
+ - Rolling-wave: no waves, tasks, or file lists anywhere in the roadmap.
91
+ - No scope-out veto appears in any milestone; every synthesis decision is
92
+ honored by at least one milestone's scope.
93
+ - On a re-slice, `shipped` entries differ from
94
+ `.project/ROADMAP.before-reslice.md` only in Status/Archive/Integrated;
95
+ `abandoned` entries are byte-for-byte identical.
96
+ - On a milestone-boundary re-slice, the prior `active` entry is byte-for-byte
97
+ identical to `.project/ROADMAP.before-reslice.md`.
98
+ 4. Redispatch one complete corrected brief under logical task name `roadmap`,
99
+ following the runtime dispatch contract and including all gate failures.
100
+ Allow one revision round. If it still fails, keep the entering
101
+ `inspect/active` or `define/active` state for a milestone-boundary re-slice
102
+ and use `pipeline_state.py transition` with that complete state as both the
103
+ expected and retained state and an event naming the failed roadmap gate.
104
+ Otherwise use the helper with expected `roadmap/active`, exact milestone,
105
+ branch, and archive values, `--set-status blocked`, and the same event. Then
106
+ present **Outcome** with the failed gate, **Review** linking the resolved
107
+ absolute ROADMAP.md path (or STATE.md when ROADMAP.md is missing), and
108
+ **Next** naming the one correction or user decision required. Stop.
109
+ 5. On a re-slice with a saved lookahead track, run the bundled
110
+ `scripts/promote_lookahead.py compare-entry --before
111
+ .project/ROADMAP.before-reslice.md --after .project/ROADMAP.md --milestone
112
+ <lookahead-slug>` helper now. When STATE.milestone is set, append
113
+ `--active-milestone <STATE.milestone>`; when it is unset, omit that option.
114
+ It compares every plan-binding part of the entry while ignoring only
115
+ Status, Archive, and Integrated, and requires that entry to remain the
116
+ candidate roadmap's first dependency-ready milestone. When it returns
117
+ `status: unchanged`, ask
118
+ the user to choose
119
+ `Keep the unchanged lookahead track (recommended)` or `Discard and
120
+ regenerate the lookahead track`. When it returns `status: changed`, offer
121
+ `Discard and regenerate the lookahead track (recommended)` or `Request
122
+ roadmap changes`; keeping the stale track is not valid. Apply the ruling
123
+ and record the helper result and ruling with `pipeline_state.py transition`,
124
+ expecting and retaining the complete entering state with event `lookahead
125
+ re-slice ruling: <ruling>`; never append it directly. Retain the baseline
126
+ through any requested roadmap revisions and the final approval decision.
127
+ 6. On a post-abandon re-slice, first run the bundled
128
+ `scripts/promote_lookahead.py select-next --roadmap .project/ROADMAP.md`
129
+ helper against the gated candidate. When it returns `status: complete`,
130
+ report program completion against CHARTER.md's program success criteria and
131
+ stop without offering a pending-milestone approval. When it returns
132
+ `status: selected`, use only its exact milestone in the approval and
133
+ transition below. A `status: none` result blocks without mutation.
134
+ Show every milestone id, goal, and dependency summary as the outcome. Link
135
+ the resolved absolute `.project/ROADMAP.md` path, then ask one explicit next
136
+ question. For a milestone-boundary re-slice, list `Approve roadmap and
137
+ resume the active milestone (recommended)` first. For a post-abandon
138
+ re-slice, list
139
+ `Approve roadmap and inspect <selected-milestone> (recommended)` first.
140
+ Otherwise list `Approve roadmap and start the first
141
+ pending milestone (recommended)` first. In every case, list `Request
142
+ changes` as the alternative. If the user requests changes,
143
+ retain the entering state for a milestone-boundary re-slice; otherwise keep
144
+ `phase: roadmap`, `status: active`. Retain the baseline, revise, and re-gate
145
+ against that same baseline.
146
+ 7. On approval in an established repository, record the exact full current
147
+ HEAD before changing ROADMAP.md or STATE.md. For a milestone-boundary
148
+ re-slice, keep its matching roadmap entry `active`, use `pipeline_state.py
149
+ transition` to record `program roadmap re-slice approved` while expecting
150
+ and retaining the complete entering `inspect/active` or `define/active`
151
+ state, then checkpoint the pending `.project/` artifacts with:
152
+
153
+ ```text
154
+ python3 <absolute isolation.py> checkpoint \
155
+ --repo <absolute root> --expected-head <recorded full HEAD> \
156
+ --subject "roadmap: program roadmap approved" \
157
+ --body "Why: approved roadmap checkpoint" \
158
+ --allow-path .project
159
+ ```
160
+
161
+ On a post-abandon re-slice, mark only the helper-selected pending entry
162
+ `active`, use `pipeline_state.py transition` with the complete current
163
+ `roadmap/active` state as expected to set `phase: inspect`, `status: active`,
164
+ `milestone` to the selected slug, preserve the bound branch, and set
165
+ `archive: null`, with an event naming the abandoned predecessor. Then use
166
+ the same `isolation.py checkpoint` command above. For a first roadmap
167
+ approval, run:
168
+
169
+ ```text
170
+ python3 <absolute pipeline_state.py> approve \
171
+ --repo <absolute root> --kind roadmap \
172
+ --milestone <selected first pending slug> \
173
+ --expected-head <recorded full HEAD>
174
+ ```
175
+
176
+ The helper journals before mutation, proves the selected entry is pending
177
+ and no entry is already active, marks it active, changes STATE from
178
+ `roadmap/active` to `roadmap/done` with that milestone and event `program
179
+ roadmap approved`, and checkpoints all pending `.project/` artifacts with
180
+ the canonical roadmap subject and body, subject to the
181
+ top-level allowlist in
182
+ [isolation.PROJECT_ENTRIES](scripts/isolation.py). Require its typed result to report
183
+ `schema: gsd-path/state-checkpoint/v1`, `status: approved`, `kind: roadmap`,
184
+ `project_dir: .project`, `state.status: done`, the selected milestone, and
185
+ the returned current commit. Rerun the same command after interruption; the
186
+ matching journal owns recovery.
187
+
188
+ For every re-slice, remove `.project/ROADMAP.before-reslice.md` only after
189
+ the state transition succeeds and before the checkpoint. Retain it through
190
+ every requested revision and failed approval attempt.
191
+
192
+ Defer either checkpoint only when the directory is not yet a Git repository
193
+ or `.project/REPOSITORY.md` records `Kind: new-github`. For a normal
194
+ approval, run the same `approve` command with `--defer-checkpoint` instead
195
+ of `--expected-head`; it marks the selected entry active and records
196
+ `roadmap/done` with event `program roadmap approved`. `pipeline_state.py
197
+ transition` never approves a roadmap. For
198
+ a milestone-boundary re-slice, use the retaining transition above; for a
199
+ post-abandon re-slice, use its transition above. The build transition
200
+ commit owns the pending artifacts. Confirm approval and link ROADMAP.md again. For
201
+ a milestone-boundary re-slice, state that the preserved inspect or define
202
+ phase resumes; for a post-abandon re-slice, state that inspect is next;
203
+ otherwise state that define (milestone mode) is next. Do not
204
+ add another approval gate. When routed by an active `$gsd-path`, return
205
+ control to that router so it routes the resulting state; never name define
206
+ as next when inspect was preserved or selected. When invoked directly, stop
207
+ and tell the user to explicitly invoke `$gsd-path`, which routes the same
208
+ result; do not invoke an explicit-only sibling skill yourself.
209
+
210
+ ## Rules
211
+
212
+ - Cover the charter exactly: no unmapped scope, no unscoped milestones.
213
+ - Milestone granularity only; never drift into waves, tasks, or file scopes.
214
+ - Every milestone must be shippable on its own stated dependencies.
215
+ - Surface scope cuts as `NEEDS-USER`; never drop charter scope silently.
@@ -0,0 +1,6 @@
1
+ interface:
2
+ display_name: "GSD Path Roadmap"
3
+ short_description: "Slice a program charter into a milestone roadmap"
4
+ default_prompt: "Use $gsd-path-roadmap to slice an approved program charter into dependency-ordered milestones."
5
+ policy:
6
+ allow_implicit_invocation: false
@@ -0,0 +1,131 @@
1
+ # Shared Agent Skills dispatch
2
+
3
+ Apply this contract whenever a GSD Path skill delegates work from the shared
4
+ `~/.agents/skills` bundle. Inspect the advertised child-agent tool schema and
5
+ use exactly one matching branch:
6
+
7
+ - A `spawn_agent` tool exposing `task_name`, `agent_type`, and `fork_turns` is
8
+ Codex. Use `fork_turns: "none"`; coders use the built-in `worker` type and
9
+ every other role uses `default`. Reuse a completed logical target with
10
+ `followup_task`. For Codex reasoning effort, use `high` for the portable
11
+ `heavy` tier and `low` for the portable `light` tier; leave reasoning effort
12
+ unset for the session-default tier, and never pass `heavy` or `light` as a
13
+ literal Codex value.
14
+ - A `spawn_agent` tool without those Codex fields is Zed. Spawn one isolated,
15
+ full-capability child per brief. Zed children are not resumable, so retries
16
+ use a fresh child and a complete prompt.
17
+ - An `invoke_subagent` tool advertising `TypeName`, `Workspace`, and `Role` is
18
+ Antigravity. Use `TypeName: self`, the exact supplied root as `Workspace`,
19
+ and the logical task name as `Role`. Keep the returned child ID and use
20
+ `send_message` for follow-up work when available; otherwise start a fresh
21
+ child with the complete prompt.
22
+ - A `spawn_subagent` tool advertising the `general-purpose` type is Grok. Use
23
+ `subagent_type: general-purpose`, `capability_mode: all`, the exact supplied
24
+ root as `cwd`, `isolation: none`, and `background: true`. Supply the logical
25
+ task name as `description`, keep the returned ID, and use `resume_from` with
26
+ the complete new prompt for later work. Wait for a colliding active child and
27
+ collect results with `wait_commands_or_subagents`.
28
+ - A `Task` tool advertising the custom `gsd-path` subagent is Cursor. Use that
29
+ model-inheriting, full-capability child. Resume it by returned agent ID when
30
+ available; otherwise retry with a fresh child and a complete prompt.
31
+ - A `Task` tool advertising the built-in `general` subagent is OpenCode. Use
32
+ that child; if an installed OpenCode v2 host exposes the renamed `subagent`
33
+ tool instead, use its advertised schema with the built-in `general` agent.
34
+ Supply the logical task name as the child description. Reuse a returned
35
+ child-session ID only when the host advertises a resume parameter; otherwise
36
+ use a fresh `general` child and the complete prompt.
37
+ - A `task` tool advertising the `general-purpose` child is GitHub Copilot CLI.
38
+ Use that child. Keep its returned ID for follow-up while the host exposes
39
+ it; otherwise retry with a fresh child and a complete prompt.
40
+ - An `invoke_sub_agent` tool with a `general-purpose` subagent is Kiro. Use
41
+ that child for every role; there is no worker/default type split. Start a
42
+ fresh general-purpose child for every correction, retry, post-patch review,
43
+ repeated audit, or later milestone — Kiro subagents are not resumable and
44
+ disk artifacts are the source of truth. Supply the logical task name as the
45
+ task description. Set the child working directory to the exact repository or
46
+ linked-worktree root supplied by GSD Path; do not ask Kiro or the child to
47
+ create another worktree. Encode task dependencies explicitly; launch
48
+ independent children concurrently up to the host's advertised
49
+ concurrent-subagent capacity.
50
+
51
+ For every branch:
52
+
53
+ - Supply the deterministic logical task name: `inspect_codebase`,
54
+ `inspect_docs`, `docs_audit`, `research_<dimension>`, `decide`, `roadmap`,
55
+ `plan`,
56
+ `plan_patch`, `build_<task_id>`, `review_wave_<wave>_cycle_<cycle>`
57
+ (a `deep` wave review appends the lens suffix `_contract` or
58
+ `_adversarial`; an optional review panel uses
59
+ `review_wave_<wave>_cycle_<cycle>_panel_<family>`; an optional finding
60
+ skeptic uses `review_wave_<wave>_cycle_<cycle>_skeptic_<criterion_locator>`),
61
+ `review_plan_panel_<family>`,
62
+ `review_final`, or `review_gap_<number>`. Normalize variable parts to
63
+ lowercase ASCII and replace non-alphanumeric runs with one underscore.
64
+ Never add a random suffix or collide with a running logical target.
65
+ - Resolve the phase's linked role brief to an absolute path, include it in the
66
+ prompt, and require the child to read it before acting. The role brief
67
+ supplies the read-only boundary for auditors and reviewers.
68
+ - Tier hints: use the portable `heavy` tier for `plan`, `plan_patch`, `decide`,
69
+ and `roadmap`, the portable `light` tier for `inspect_docs` and `docs_audit`,
70
+ and the session-default tier for every other role. Apply the Codex mapping
71
+ above when its schema advertises reasoning-effort selection. On every other
72
+ host, use only an exact native equivalent advertised by that host; otherwise
73
+ do not override the model or reasoning effort. The only exception is a
74
+ review-panel child: when the host advertises model selection, pass the exact
75
+ slug returned by `scripts/review_panel.py resolve` for that family. Never
76
+ override the model on the canonical reviewer, planner, coder, or any other
77
+ role.
78
+ Host isolation: none. The child's working directory is the exact absolute
79
+ root GSD Path supplied; a host SHA checkout or extra worktree is a contract
80
+ failure. Never ask the host to create a worktree. Give the child the exact
81
+ repository or linked-worktree root supplied by GSD Path.
82
+ - Send a self-contained prompt with absolute input, template, and output paths
83
+ plus the child's bounded responsibility. Every brief also names the absolute
84
+ `AGENTS.md` and `WORKFLOW.md` paths (or explicitly says they are absent), the
85
+ next phase that consumes the output, the gate it must satisfy, and the
86
+ terminal result it must return. A coder prompt also names its isolated
87
+ linked-worktree root; no child may infer the primary worktree.
88
+ - The parent is the sole dispatcher and lifecycle owner. If the runtime exposes
89
+ structured Run/Task/Dispatch orchestration, bind one Run, create one Task per
90
+ independent brief with explicit dependencies, inject the brief, and wait for
91
+ every `worker_done`, `escalation`, or question before applying the gate.
92
+ Verify the task and dispatch records before reporting the work as
93
+ orchestrated. On runtimes without that layer, use the host adapter's
94
+ equivalent and preserve the same logical name, completion state,
95
+ timeout/cancellation, and cleanup rules; never silently delegate again from a
96
+ child.
97
+ - When the structured layer exposes a blocking ask/reply channel, route a
98
+ coder's `NEEDS-ORCHESTRATOR` question through it as a live question with
99
+ the worker held alive for the reply, instead of block-and-redispatch. The
100
+ answer is still appended to the task Log as
101
+ `Orchestrator answer:` so the portable on-disk record stays complete, and a
102
+ timed-out or unavailable channel falls back to the portable block path.
103
+ - A child that receives a disposable worktree stages its assigned artifact
104
+ under that root. The parent validates it and atomically transfers it to the
105
+ canonical project path before removing the exact disposable root. A child
106
+ never writes a disposable-review output directly into the primary worktree.
107
+ - Launch independent briefs concurrently up to the advertised child capacity,
108
+ batch any remainder without combining briefs, and collect every result
109
+ before applying the phase gate. Do not leave an active child, logical task, or
110
+ temporary worktree after collection; a timeout or cancellation is a blocked
111
+ result, not a silent success.
112
+ - If the tool schema is ambiguous or the required full-capability child is
113
+ unavailable, stop and report the missing capability. Do not guess the host
114
+ or silently collapse an independence boundary into the main context.
115
+
116
+ ## Configured output budgets
117
+
118
+ When the owner supplies token budgets, use the router bundle's
119
+ `scripts/token_budget.py` with the owner's exact task and session values and
120
+ quoted authority. Keep one ledger outside the worktree under the Git common
121
+ directory for the full logical session; resumptions reuse it. Record completed
122
+ parent CLI run events and each native child's session events with stable logical
123
+ task names before the next dispatch. The helper reads host counters and refuses
124
+ incomplete or ambiguous usage; never estimate tokens or reset the ledger.
125
+ Run `admit` for the next task and stop dispatch on a blocked result. Preserve
126
+ its output in the dispatch evidence. This gates observed usage only: concurrent
127
+ or in-flight work can overrun before the host reports usage. Codex CLI has no
128
+ advertised hard output cap; report that limitation once. If the owner requires
129
+ hard generation enforcement, use `admit --require-hard-cap`; unsupported means
130
+ blocked, not budget compliance. Other hosts require a verified native counter
131
+ and cap adapter before any enforcement claim.
@@ -0,0 +1,48 @@
1
+ # Roadmapper role
2
+
3
+ Slice an approved program charter into a dependency-ordered roadmap of
4
+ independently shippable milestones. You scope; you do not plan tasks.
5
+
6
+ ## Input and output
7
+
8
+ - Require absolute paths for CHARTER.md, SYNTHESIS.md, the roadmap template,
9
+ and every dispatched evidence file listed in RESEARCH.md. Read all of them,
10
+ plus AGENTS.md and `.project/LESSONS.md` when supplied; do not repeat a
11
+ recorded slicing defect.
12
+ - Write only `.project/ROADMAP.md` using the supplied template. Stop on a
13
+ missing input or template.
14
+
15
+ ## Authority
16
+
17
+ - Charter vetoes, constraints, and corrections are hard limits.
18
+ - Synthesis decisions are settled. Surface conflicts; never average.
19
+ - Existing evidence informs scope; do not re-research.
20
+
21
+ ## Slicing rules
22
+
23
+ 1. Cover everything: every `Full scope: in` item maps to at least one
24
+ milestone, and every milestone traces to charter scope. Unmappable work is
25
+ a scope cut — list it under the roadmap's owning milestone `Scope: out`
26
+ with the reason, or escalate as `NEEDS-USER`.
27
+ 2. Milestone 1 is the thinnest end-to-end program skeleton that proves the
28
+ riskiest synthesis decisions. Order the rest by dependency, then value.
29
+ 3. Every milestone is independently shippable: its success criteria hold with
30
+ only its `Depends on` milestones shipped.
31
+ 4. Rolling-wave: milestone granularity only. No waves, no tasks, no file
32
+ lists — planning owns those for the active milestone.
33
+ 5. Prefer the fewest milestones that respect dependencies and risk isolation;
34
+ each milestone costs a full plan-build-ship cycle.
35
+ 6. Put anything that would invalidate later slicing in the earliest milestone
36
+ that can answer it, and record it under that milestone's `Open questions`
37
+ so milestone-scoped research runs before its planning.
38
+ 7. Keep the dependency graph acyclic; depend on earlier milestone ids.
39
+ 8. Set `Surfaces:` on every milestone: the screens, commands, or endpoints a
40
+ person touches to get that milestone's outcome, or `none` when nobody
41
+ touches it directly. Each named surface needs a success criterion
42
+ observable there. Never defer a milestone's own surface to a later
43
+ milestone — that leaves an unusable slice, not a shippable one.
44
+
45
+ ## Return
46
+
47
+ Return milestone count, the M001 goal, and every `NEEDS-USER` scope cut in at
48
+ most five lines.
@@ -0,0 +1,180 @@
1
+ #!/usr/bin/env python3
2
+ # gsd-path project runtime
3
+ """Helpers shared by the gsd-path scripts.
4
+
5
+ Every consuming script binds the names it used before (for example
6
+ ``run_git = _common.run_git``) so callers and tests that patch the name on the
7
+ consuming module keep working.
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ import json
13
+ import os
14
+ import re
15
+ import subprocess
16
+ from pathlib import Path
17
+ from typing import Optional
18
+
19
+ PIPELINE_MARKER = "gsd-path/v2"
20
+ BOUND_BRANCH_RE = re.compile(r"^gsd-path/M(\d{3,})$")
21
+
22
+ FIELD_PATTERN = re.compile(r"^(?P<key>[a-z_]+):\s*(?P<value>.*)$")
23
+ INLINE_LIST_PATTERN = re.compile(r"^\[(?P<body>.*)\]$")
24
+ LIST_ITEM_PATTERN = re.compile(r"^\s*-\s+(?P<value>.*)$")
25
+ VERIFY_LEDGER_PATH = ".project/build/verify-ledger.jsonl"
26
+ VERIFY_RESULTS = ("pass", "fail")
27
+ VERIFY_LEDGER_SCHEMA = "gsd-path/verify-ledger/v2"
28
+ VERIFY_BLOCK_PATTERN = re.compile(r"```bash[ \t]*\n(?P<block>.*?)```", re.DOTALL)
29
+
30
+
31
+ def section_body(text: str, heading: str) -> Optional[str]:
32
+ """The text under `## <heading>` up to the next `## `, or None when absent."""
33
+ match = re.search(
34
+ rf"(?ms)^## {re.escape(heading)}\s*\n(?P<body>.*?)(?=^## |\Z)", text
35
+ )
36
+ return match.group("body") if match else None
37
+
38
+
39
+ def task_verify_command(task_text: str) -> str:
40
+ """The Verify shell text, excluding the closing fence's separator newline."""
41
+ body = section_body(task_text, "Verify")
42
+ block = VERIFY_BLOCK_PATTERN.search(body) if body is not None else None
43
+ return block.group("block").removesuffix("\n") if block else ""
44
+
45
+
46
+ def latest_verify_entry(entries: list, command: str, commit: str) -> Optional[dict]:
47
+ for entry in reversed(entries):
48
+ if (entry.get("schema") == VERIFY_LEDGER_SCHEMA
49
+ and entry["command"] == command and entry["commit"] == commit):
50
+ return entry
51
+ return None
52
+
53
+
54
+ def verify_ledger_entries(path: Path) -> list:
55
+ """Parsed verify-ledger rows; raises ValueError on a malformed line."""
56
+ if not path.exists():
57
+ return []
58
+ return parse_verify_ledger(path.read_text(encoding="utf-8"))
59
+
60
+
61
+ def parse_verify_ledger(text: str) -> list:
62
+ entries = []
63
+ for number, line in enumerate(text.splitlines(), start=1):
64
+ if not line.strip():
65
+ continue
66
+ try:
67
+ entry = json.loads(line)
68
+ except json.JSONDecodeError as error:
69
+ raise ValueError(f"{VERIFY_LEDGER_PATH} line {number} is not JSON: {error}") from error
70
+ if (
71
+ not isinstance(entry, dict)
72
+ or not isinstance(entry.get("command"), str)
73
+ or not isinstance(entry.get("commit"), str)
74
+ or entry.get("result") not in VERIFY_RESULTS
75
+ or not isinstance(entry.get("recorded_at"), str)
76
+ ):
77
+ raise ValueError(f"{VERIFY_LEDGER_PATH} line {number} has invalid fields")
78
+ entries.append(entry)
79
+ return entries
80
+
81
+
82
+ def run_command(
83
+ *arguments: str, cwd: Optional[Path] = None
84
+ ) -> subprocess.CompletedProcess[str]:
85
+ return subprocess.run(
86
+ arguments,
87
+ cwd=cwd,
88
+ text=True,
89
+ capture_output=True,
90
+ check=False,
91
+ )
92
+
93
+
94
+ def run_git(
95
+ repo: Path, *arguments: str, input: Optional[str] = None
96
+ ) -> subprocess.CompletedProcess[str]:
97
+ return subprocess.run(
98
+ ("git", "-C", str(repo), *arguments),
99
+ input=input,
100
+ text=True,
101
+ capture_output=True,
102
+ check=False,
103
+ )
104
+
105
+
106
+ def atomic_replace(path: Path, temporary_path: Path, content: str) -> None:
107
+ temporary_path.parent.mkdir(parents=True, exist_ok=True)
108
+ descriptor = None
109
+ try:
110
+ if temporary_path.exists() or temporary_path.is_symlink():
111
+ temporary_path.unlink()
112
+ descriptor = os.open(
113
+ temporary_path,
114
+ os.O_WRONLY | os.O_CREAT | os.O_EXCL,
115
+ 0o666,
116
+ )
117
+ handle = os.fdopen(descriptor, "w", encoding="utf-8")
118
+ descriptor = None
119
+ with handle:
120
+ handle.write(content)
121
+ os.replace(temporary_path, path)
122
+ finally:
123
+ if descriptor is not None:
124
+ os.close(descriptor)
125
+ if temporary_path.exists() or temporary_path.is_symlink():
126
+ temporary_path.unlink()
127
+
128
+
129
+ def atomic_write(path: Path, content: str) -> None:
130
+ atomic_replace(path, path.parent / f".{path.name}.gsd-path-tmp", content)
131
+
132
+
133
+ def strip_yaml_comment(value: str) -> str:
134
+ quote = None
135
+ previous_significant = None
136
+ inline_list = value.lstrip().startswith("[")
137
+ index = 0
138
+ while index < len(value):
139
+ character = value[index]
140
+ if quote == '"':
141
+ if character == "\\" and index + 1 < len(value):
142
+ index += 2
143
+ continue
144
+ if character == quote:
145
+ quote = None
146
+ elif quote == "'":
147
+ if (
148
+ character == quote
149
+ and index + 1 < len(value)
150
+ and value[index + 1] == quote
151
+ ):
152
+ index += 2
153
+ continue
154
+ if character == quote:
155
+ quote = None
156
+ else:
157
+ if character in {"'", '"'} and (
158
+ previous_significant is None
159
+ or (inline_list and previous_significant in {"[", ","})
160
+ ):
161
+ quote = character
162
+ elif character == "#" and (
163
+ index == 0 or value[index - 1].isspace()
164
+ ):
165
+ return value[:index].rstrip()
166
+ if quote is None and not character.isspace():
167
+ previous_significant = character
168
+ index += 1
169
+ return value.strip()
170
+
171
+
172
+ def unquote(value: str) -> str:
173
+ cleaned = strip_yaml_comment(value).strip()
174
+ if (
175
+ len(cleaned) >= 2
176
+ and cleaned[0] == cleaned[-1]
177
+ and cleaned[0] in {"'", '"'}
178
+ ):
179
+ return cleaned[1:-1]
180
+ return cleaned