@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,415 @@
1
+ #!/usr/bin/env python3
2
+ # gsd-path project runtime
3
+ """Select and compare GSD Path lookahead tracks."""
4
+
5
+ from __future__ import annotations
6
+
7
+ import argparse
8
+ import hashlib
9
+ import json
10
+ import os
11
+ import re
12
+ import stat
13
+ import subprocess
14
+ import sys
15
+ from pathlib import Path
16
+ from typing import Optional, Sequence
17
+
18
+ import _common
19
+ import archive_milestone
20
+ import detect_project
21
+
22
+
23
+ PHASES = {"inspect", "define", "research", "decide", "plan"}
24
+ STATUSES = {"active", "blocked", "done"}
25
+ SHA_RE = re.compile(r"^[0-9a-f]{40}$")
26
+ ROADMAP_HEADING_RE = re.compile(r"^### (M\d{3,}) — (.+)$")
27
+ MUTABLE_ROADMAP_FIELDS_RE = re.compile(r"^(Status|Archive|Integrated):")
28
+
29
+
30
+ class LookaheadError(RuntimeError):
31
+ pass
32
+
33
+
34
+ class NoEligibleLookahead(LookaheadError):
35
+ pass
36
+
37
+
38
+ def read_text(path: Path, description: str) -> str:
39
+ try:
40
+ return path.read_text(encoding="utf-8")
41
+ except (OSError, UnicodeDecodeError) as error:
42
+ raise LookaheadError(f"cannot read {description} {path}: {error}") from error
43
+
44
+
45
+ def path_mode(path: Path) -> Optional[int]:
46
+ try:
47
+ return path.lstat().st_mode
48
+ except (FileNotFoundError, NotADirectoryError):
49
+ return None
50
+ except OSError as error:
51
+ raise LookaheadError(f"cannot inspect path {path}: {error}") from error
52
+
53
+
54
+ def require_directory(path: Path, description: str) -> None:
55
+ mode = path_mode(path)
56
+ if mode is None or not stat.S_ISDIR(mode):
57
+ raise LookaheadError(f"{description} must be a real directory: {path}")
58
+
59
+
60
+ def require_file(path: Path, description: str) -> None:
61
+ mode = path_mode(path)
62
+ if mode is None or not stat.S_ISREG(mode):
63
+ raise LookaheadError(f"{description} must be a real file: {path}")
64
+
65
+
66
+ atomic_write = _common.atomic_write
67
+
68
+
69
+ def state_fields(content: str) -> dict[str, str]:
70
+ try:
71
+ fields = detect_project.state_frontmatter(content)
72
+ except detect_project.DetectError as error:
73
+ raise LookaheadError(str(error)) from error
74
+ if fields is None:
75
+ raise LookaheadError("STATE.md is missing YAML frontmatter")
76
+ return fields
77
+
78
+
79
+ def roadmap_blocks(content: str) -> list[dict]:
80
+ lines = content.splitlines(keepends=True)
81
+ headings = []
82
+ for index, line in enumerate(lines):
83
+ match = ROADMAP_HEADING_RE.fullmatch(line.rstrip("\r\n"))
84
+ if match:
85
+ headings.append((index, match.group(1), match.group(2).strip()))
86
+ blocks = []
87
+ for position, (start, milestone_id, title) in enumerate(headings):
88
+ end = headings[position + 1][0] if position + 1 < len(headings) else len(lines)
89
+ fields = {}
90
+ for index in range(start + 1, end):
91
+ match = re.match(
92
+ r"^(Status|Archive|Integrated|Depends on):\s*([^#]*?)\s*(?:#.*)?$",
93
+ lines[index].rstrip("\r\n"),
94
+ )
95
+ if match:
96
+ if match.group(1) in fields:
97
+ raise LookaheadError(
98
+ f"roadmap milestone {milestone_id} has duplicate "
99
+ f"{match.group(1)} field"
100
+ )
101
+ fields[match.group(1)] = (index, match.group(2).strip())
102
+ blocks.append(
103
+ {
104
+ "id": milestone_id,
105
+ "title": title,
106
+ "start": start,
107
+ "end": end,
108
+ "fields": fields,
109
+ }
110
+ )
111
+ return blocks
112
+
113
+
114
+ def milestone_block(content: str, milestone: str) -> dict:
115
+ normalized = archive_milestone.normalized_slug(milestone)
116
+ matches = [
117
+ block
118
+ for block in roadmap_blocks(content)
119
+ if archive_milestone.normalized_slug(block["title"]) == normalized
120
+ ]
121
+ if len(matches) != 1:
122
+ raise LookaheadError(f"ROADMAP.md must contain exactly one entry for {milestone}")
123
+ return matches[0]
124
+
125
+
126
+ def dependency_ids(block: dict) -> list[str]:
127
+ dependencies = block["fields"].get("Depends on")
128
+ if dependencies is None:
129
+ raise LookaheadError(f"roadmap milestone {block['id']} lacks dependencies")
130
+ dependency_list = re.fullmatch(
131
+ r"\[\s*(M\d{3,}(?:\s*,\s*M\d{3,})*)?\s*\]",
132
+ dependencies[1],
133
+ )
134
+ if dependency_list is None:
135
+ raise LookaheadError(f"roadmap milestone {block['id']} has invalid dependencies")
136
+ return re.findall(r"M\d{3,}", dependency_list.group(1) or "")
137
+
138
+
139
+ def next_eligible_pending(content: str, active_milestone: Optional[str] = None) -> dict:
140
+ blocks = roadmap_blocks(content)
141
+ blocks_by_id = {block["id"]: block for block in blocks}
142
+ if len(blocks_by_id) != len(blocks):
143
+ raise LookaheadError("ROADMAP.md milestone ids must be unique")
144
+ active_id = None
145
+ if active_milestone is not None:
146
+ active = milestone_block(content, active_milestone)
147
+ if active["fields"].get("Status", (-1, ""))[1] != "active":
148
+ raise LookaheadError(f"roadmap milestone {active_milestone} is not active")
149
+ active_id = active["id"]
150
+ for block in blocks:
151
+ if block["fields"].get("Status", (-1, ""))[1] != "pending":
152
+ continue
153
+ dependencies = dependency_ids(block)
154
+ if all(
155
+ dependency in blocks_by_id
156
+ and (
157
+ blocks_by_id[dependency]["fields"].get("Status", (-1, ""))[1]
158
+ == "shipped"
159
+ or dependency == active_id
160
+ )
161
+ for dependency in dependencies
162
+ ):
163
+ return block
164
+ raise NoEligibleLookahead("ROADMAP.md has no dependency-ready pending milestone")
165
+
166
+
167
+ def selection_payload(selected: dict) -> dict:
168
+ milestone = archive_milestone.normalized_slug(selected["title"])
169
+ return {
170
+ "status": "selected",
171
+ "id": selected["id"],
172
+ "milestone": milestone,
173
+ "branch": f"gsd-path/{selected['id']}",
174
+ }
175
+
176
+
177
+ def select_lookahead(content: str, active_milestone: Optional[str] = None) -> dict:
178
+ try:
179
+ selected = next_eligible_pending(content, active_milestone)
180
+ except NoEligibleLookahead:
181
+ blocks = roadmap_blocks(content)
182
+ if blocks and all(
183
+ block["fields"].get("Status", (-1, ""))[1]
184
+ in {"shipped", "abandoned"}
185
+ for block in blocks
186
+ ):
187
+ return {"status": "complete"}
188
+ return {"status": "none"}
189
+ return selection_payload(selected)
190
+
191
+
192
+ def select_track_branch(content: str, track_state: str) -> dict:
193
+ fields = state_fields(track_state)
194
+ if fields.get("pipeline", "") != archive_milestone.PIPELINE_MARKER:
195
+ raise LookaheadError("lookahead STATE.md is not owned by gsd-path/v2")
196
+ phase = fields.get("phase", "")
197
+ status = fields.get("status", "")
198
+ milestone = fields.get("milestone", "")
199
+ if phase not in PHASES or status not in STATUSES:
200
+ raise LookaheadError(f"invalid lookahead state: {phase}/{status}")
201
+ if archive_milestone.is_unset(milestone):
202
+ raise LookaheadError("lookahead STATE.md does not name a milestone")
203
+ if not archive_milestone.is_unset(fields.get("branch")):
204
+ raise LookaheadError("lookahead STATE.md must not bind a branch")
205
+ if not archive_milestone.is_unset(fields.get("archive")):
206
+ raise LookaheadError("lookahead STATE.md must not own an archive")
207
+ selected = milestone_block(content, milestone)
208
+ if selected["fields"].get("Status", (-1, ""))[1] != "pending":
209
+ raise LookaheadError(f"lookahead milestone {milestone} is not pending")
210
+ eligible = next_eligible_pending(content)
211
+ if selected["id"] != eligible["id"]:
212
+ raise LookaheadError(
213
+ f"lookahead milestone {milestone} is not the next eligible milestone "
214
+ f"{eligible['id']}"
215
+ )
216
+ return selection_payload(selected)
217
+
218
+
219
+ def snapshot_roadmap(source: Path, destination: Path) -> dict:
220
+ require_file(source, "ROADMAP.md")
221
+ require_directory(destination.parent, "roadmap snapshot parent")
222
+ existing_mode = path_mode(destination)
223
+ if existing_mode is not None:
224
+ require_file(destination, "roadmap baseline snapshot")
225
+ content = read_text(destination, "roadmap baseline snapshot")
226
+ return {
227
+ "status": "existing",
228
+ "sha256": hashlib.sha256(content.encode("utf-8")).hexdigest(),
229
+ }
230
+ content = read_text(source, "ROADMAP.md")
231
+ temporary = destination.parent / f".{destination.name}.gsd-path-tmp"
232
+ try:
233
+ atomic_write(temporary, content)
234
+ try:
235
+ os.link(temporary, destination)
236
+ status = "created"
237
+ except FileExistsError:
238
+ require_file(destination, "roadmap baseline snapshot")
239
+ content = read_text(destination, "roadmap baseline snapshot")
240
+ status = "existing"
241
+ finally:
242
+ if path_mode(temporary) is not None:
243
+ temporary.unlink()
244
+ return {
245
+ "status": status,
246
+ "sha256": hashlib.sha256(content.encode("utf-8")).hexdigest(),
247
+ }
248
+
249
+
250
+ def roadmap_contract(content: str, milestone: str) -> tuple[str, ...]:
251
+ block = milestone_block(content, milestone)
252
+ lines = content.splitlines()
253
+ return tuple(
254
+ line.rstrip()
255
+ for line in lines[block["start"] : block["end"]]
256
+ if not MUTABLE_ROADMAP_FIELDS_RE.match(line)
257
+ )
258
+
259
+
260
+ def compare_roadmap_entry(
261
+ before: str,
262
+ after: str,
263
+ milestone: str,
264
+ active_milestone: Optional[str] = None,
265
+ ) -> dict:
266
+ before_contract = roadmap_contract(before, milestone)
267
+ try:
268
+ after_contract = roadmap_contract(after, milestone)
269
+ selected = milestone_block(after, milestone)
270
+ eligible = next_eligible_pending(after, active_milestone)
271
+ except LookaheadError:
272
+ after_contract = ()
273
+ selected = None
274
+ eligible = None
275
+ status = (
276
+ "unchanged"
277
+ if before_contract == after_contract
278
+ and selected is not None
279
+ and eligible is not None
280
+ and selected["id"] == eligible["id"]
281
+ else "changed"
282
+ )
283
+ return {"status": status, "milestone": milestone}
284
+
285
+
286
+ def git_commit_file(root: Path, commit: str, relative: str) -> str:
287
+ require_directory(root, "repository")
288
+ if not SHA_RE.fullmatch(commit):
289
+ raise LookaheadError("base must be a full lowercase commit SHA")
290
+ entry = subprocess.run(
291
+ ["git", "-C", str(root), "ls-tree", "-z", commit, "--", relative],
292
+ capture_output=True,
293
+ check=False,
294
+ )
295
+ metadata, separator, path = entry.stdout.rstrip(b"\0").partition(b"\t")
296
+ fields = metadata.split()
297
+ if (
298
+ entry.returncode != 0
299
+ or not separator
300
+ or path.decode("utf-8", "replace") != relative
301
+ or len(fields) != 3
302
+ or fields[0] not in {b"100644", b"100755"}
303
+ or fields[1] != b"blob"
304
+ ):
305
+ raise LookaheadError(f"{relative} must be a regular file at base {commit}")
306
+ result = subprocess.run(
307
+ ["git", "-C", str(root), "show", f"{commit}:{relative}"],
308
+ capture_output=True,
309
+ check=False,
310
+ )
311
+ if result.returncode != 0:
312
+ detail = result.stderr.decode("utf-8", "replace").strip()
313
+ suffix = f": {detail}" if detail else ""
314
+ raise LookaheadError(f"cannot read {relative} at base {commit}{suffix}")
315
+ try:
316
+ return result.stdout.decode("utf-8")
317
+ except UnicodeDecodeError as error:
318
+ raise LookaheadError(
319
+ f"cannot decode {relative} at base {commit}: {error}"
320
+ ) from error
321
+
322
+
323
+ def select_fetched_base(
324
+ repo: Path,
325
+ base: str,
326
+ remote_default: str,
327
+ use_lookahead: bool,
328
+ ) -> dict:
329
+ root = repo.resolve()
330
+ if not re.fullmatch(r"origin/[A-Za-z0-9][A-Za-z0-9._/-]*", remote_default):
331
+ raise LookaheadError("remote default must be an origin branch")
332
+ if ".." in remote_default or "//" in remote_default:
333
+ raise LookaheadError("remote default is invalid")
334
+ resolved = subprocess.run(
335
+ ["git", "-C", str(root), "rev-parse", "--verify", f"{remote_default}^{{commit}}"],
336
+ capture_output=True,
337
+ text=True,
338
+ check=False,
339
+ )
340
+ if resolved.returncode != 0 or resolved.stdout.strip() != base:
341
+ raise LookaheadError("base does not match the fetched remote default")
342
+ roadmap = git_commit_file(root, base, ".project/ROADMAP.md")
343
+ if use_lookahead:
344
+ track_state = git_commit_file(root, base, ".project/next/STATE.md")
345
+ result = select_track_branch(roadmap, track_state)
346
+ else:
347
+ result = select_lookahead(roadmap)
348
+ return {**result, "base": base}
349
+
350
+
351
+
352
+ def parser() -> argparse.ArgumentParser:
353
+ result = argparse.ArgumentParser(description=__doc__)
354
+ subparsers = result.add_subparsers(dest="command", required=True)
355
+ compare_parser = subparsers.add_parser("compare-entry")
356
+ compare_parser.add_argument("--before", required=True, type=Path)
357
+ compare_parser.add_argument("--after", required=True, type=Path)
358
+ compare_parser.add_argument("--milestone", required=True)
359
+ compare_parser.add_argument("--active-milestone")
360
+ select_parser = subparsers.add_parser("select-next")
361
+ select_parser.add_argument("--roadmap", required=True, type=Path)
362
+ select_parser.add_argument("--active-milestone")
363
+ branch_parser = subparsers.add_parser("select-branch")
364
+ branch_parser.add_argument("--roadmap", required=True, type=Path)
365
+ branch_parser.add_argument("--state", required=True, type=Path)
366
+ base_parser = subparsers.add_parser("select-base")
367
+ base_parser.add_argument("--repo", required=True, type=Path)
368
+ base_parser.add_argument("--base", required=True)
369
+ base_parser.add_argument("--remote-default", required=True)
370
+ base_parser.add_argument("--lookahead", action="store_true")
371
+ snapshot_parser = subparsers.add_parser("snapshot-roadmap")
372
+ snapshot_parser.add_argument("--roadmap", required=True, type=Path)
373
+ snapshot_parser.add_argument("--snapshot", required=True, type=Path)
374
+ return result
375
+
376
+
377
+ def main(argv: Optional[Sequence[str]] = None) -> int:
378
+ arguments = parser().parse_args(argv)
379
+ try:
380
+ if arguments.command == "compare-entry":
381
+ result = compare_roadmap_entry(
382
+ read_text(arguments.before, "previous ROADMAP.md"),
383
+ read_text(arguments.after, "proposed ROADMAP.md"),
384
+ arguments.milestone,
385
+ arguments.active_milestone,
386
+ )
387
+ elif arguments.command == "select-next":
388
+ result = select_lookahead(
389
+ read_text(arguments.roadmap, "ROADMAP.md"),
390
+ arguments.active_milestone,
391
+ )
392
+ elif arguments.command == "select-branch":
393
+ require_file(arguments.state, "lookahead STATE.md")
394
+ result = select_track_branch(
395
+ read_text(arguments.roadmap, "ROADMAP.md"),
396
+ read_text(arguments.state, "lookahead STATE.md"),
397
+ )
398
+ elif arguments.command == "select-base":
399
+ result = select_fetched_base(
400
+ arguments.repo,
401
+ arguments.base,
402
+ arguments.remote_default,
403
+ arguments.lookahead,
404
+ )
405
+ elif arguments.command == "snapshot-roadmap":
406
+ result = snapshot_roadmap(arguments.roadmap, arguments.snapshot)
407
+ except (LookaheadError, OSError) as error:
408
+ print(f"error: {error}", file=sys.stderr)
409
+ return 1
410
+ print(json.dumps(result, sort_keys=True))
411
+ return 0
412
+
413
+
414
+ if __name__ == "__main__":
415
+ raise SystemExit(main())