@opengsd/gsd-path 1.3.1 → 1.4.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 (434) hide show
  1. package/AGENTS.md +2 -207
  2. package/CHANGELOG.md +281 -0
  3. package/DOCS.md +13 -7
  4. package/FULL.md +9 -3
  5. package/GUIDE.md +1 -1
  6. package/HOOKS.md +9 -6
  7. package/QUICK.md +4 -1
  8. package/README.md +63 -11
  9. package/RUNTIME.md +1 -1
  10. package/UPDATE.md +57 -8
  11. package/WORKFLOW.md +22 -6
  12. package/package.json +9 -8
  13. package/scripts/_common.py +472 -19
  14. package/scripts/archive_milestone.py +146 -73
  15. package/scripts/bootstrap_repository.py +8 -5
  16. package/scripts/build_recovery.py +4 -1
  17. package/scripts/build_state.py +66 -23
  18. package/scripts/check_docs_audit.py +14 -3
  19. package/scripts/check_handoffs.py +116 -20
  20. package/scripts/check_task_briefs.py +60 -8
  21. package/scripts/check_update.py +2 -2
  22. package/scripts/core_hook_gate.py +10 -1
  23. package/scripts/core_hook_settings.py +11 -4
  24. package/scripts/detect_project.py +345 -15
  25. package/scripts/discussion_records.py +19 -13
  26. package/scripts/discussion_validate.py +66 -21
  27. package/scripts/dispatch_driver.py +111 -26
  28. package/scripts/git_guard.py +116 -29
  29. package/scripts/guard_hook.py +151 -29
  30. package/scripts/install.mjs +54 -38
  31. package/scripts/install.py +562 -41
  32. package/scripts/integration.py +434 -24
  33. package/scripts/isolation.py +1077 -28
  34. package/scripts/lean_verification.py +99 -19
  35. package/scripts/loop_run.py +20 -30
  36. package/scripts/members.py +704 -0
  37. package/scripts/migrate_core.py +2 -2
  38. package/scripts/path_config.py +2 -2
  39. package/scripts/pipeline_diagnose.py +82 -31
  40. package/scripts/pipeline_git.py +61 -22
  41. package/scripts/pipeline_state.py +176 -54
  42. package/scripts/pipeline_undo.py +117 -22
  43. package/scripts/promote_lookahead.py +1 -1
  44. package/scripts/review_panel.py +1 -1
  45. package/scripts/runtime_store.py +35 -9
  46. package/scripts/skill-resources.json +28 -3
  47. package/scripts/state_checkpoint.py +140 -31
  48. package/scripts/state_promote.py +2 -0
  49. package/scripts/status_runtime.py +36 -6
  50. package/scripts/sync_skill_resources.py +8 -7
  51. package/scripts/token_budget.py +12 -8
  52. package/scripts/workflow_run.py +103 -29
  53. package/scripts/worktree_paths.py +18 -8
  54. package/skills/gsd-path/BUILD.md +7 -1
  55. package/skills/gsd-path/DECIDE.md +11 -4
  56. package/skills/gsd-path/DEFINE.md +8 -1
  57. package/skills/gsd-path/DOCS-AUDIT.md +6 -4
  58. package/skills/gsd-path/INSPECT.md +5 -4
  59. package/skills/gsd-path/PLAN.md +7 -1
  60. package/skills/gsd-path/RESEARCH.md +2 -1
  61. package/skills/gsd-path/ROADMAP.md +2 -1
  62. package/skills/gsd-path/SHIP.md +27 -10
  63. package/skills/gsd-path/SKILL.md +45 -1
  64. package/skills/gsd-path/references/build-native.md +47 -14
  65. package/skills/gsd-path/references/codebase-mapper.md +2 -1
  66. package/skills/gsd-path/references/docs-auditor.md +2 -1
  67. package/skills/gsd-path/references/operating-rules.md +214 -0
  68. package/skills/gsd-path/references/planner.md +8 -0
  69. package/skills/gsd-path/references/reviewer-wave.md +3 -1
  70. package/skills/gsd-path/scripts/__pycache__/_common.cpython-312.pyc +0 -0
  71. package/skills/gsd-path/scripts/__pycache__/check_handoffs.cpython-312.pyc +0 -0
  72. package/skills/gsd-path/scripts/_common.py +472 -19
  73. package/skills/gsd-path/scripts/archive_milestone.py +146 -73
  74. package/skills/gsd-path/scripts/bootstrap_repository.py +8 -5
  75. package/skills/gsd-path/scripts/build_recovery.py +4 -1
  76. package/skills/gsd-path/scripts/build_state.py +66 -23
  77. package/skills/gsd-path/scripts/check_docs_audit.py +14 -3
  78. package/skills/gsd-path/scripts/check_handoffs.py +116 -20
  79. package/skills/gsd-path/scripts/check_task_briefs.py +60 -8
  80. package/skills/gsd-path/scripts/check_update.py +2 -2
  81. package/skills/gsd-path/scripts/detect_project.py +345 -15
  82. package/skills/gsd-path/scripts/discussion_records.py +19 -13
  83. package/skills/gsd-path/scripts/discussion_validate.py +66 -21
  84. package/skills/gsd-path/scripts/dispatch_driver.py +111 -26
  85. package/skills/gsd-path/scripts/git_guard.py +116 -29
  86. package/skills/gsd-path/scripts/integration.py +434 -24
  87. package/skills/gsd-path/scripts/isolation.py +1077 -28
  88. package/skills/gsd-path/scripts/lean_verification.py +99 -19
  89. package/skills/gsd-path/scripts/loop_run.py +20 -30
  90. package/skills/gsd-path/scripts/members.py +704 -0
  91. package/skills/gsd-path/scripts/path_config.py +2 -2
  92. package/skills/gsd-path/scripts/pipeline_git.py +61 -22
  93. package/skills/gsd-path/scripts/pipeline_state.py +176 -54
  94. package/skills/gsd-path/scripts/promote_lookahead.py +1 -1
  95. package/skills/gsd-path/scripts/review_panel.py +1 -1
  96. package/skills/gsd-path/scripts/state_checkpoint.py +140 -31
  97. package/skills/gsd-path/scripts/state_promote.py +2 -0
  98. package/skills/gsd-path/scripts/status_runtime.py +36 -6
  99. package/skills/gsd-path/scripts/token_budget.py +12 -8
  100. package/skills/gsd-path/scripts/workflow_run.py +103 -29
  101. package/skills/gsd-path/scripts/worktree_paths.py +18 -8
  102. package/skills/gsd-path/templates/codebase.md +1 -1
  103. package/skills/gsd-path/templates/docs-audit.md +1 -1
  104. package/skills/gsd-path/templates/final-review.md +5 -2
  105. package/skills/gsd-path/templates/gap-review.md +2 -1
  106. package/skills/gsd-path/templates/task.md +1 -0
  107. package/skills/gsd-path/templates/wave-review.md +3 -1
  108. package/skills/gsd-path-build/SKILL.md +7 -1
  109. package/skills/gsd-path-build/references/build-native.md +47 -14
  110. package/skills/gsd-path-build/references/operating-rules.md +214 -0
  111. package/skills/gsd-path-build/references/reviewer-wave.md +3 -1
  112. package/skills/gsd-path-build/scripts/__pycache__/_common.cpython-312.pyc +0 -0
  113. package/skills/gsd-path-build/scripts/__pycache__/check_handoffs.cpython-312.pyc +0 -0
  114. package/skills/gsd-path-build/scripts/_common.py +472 -19
  115. package/skills/gsd-path-build/scripts/archive_milestone.py +146 -73
  116. package/skills/gsd-path-build/scripts/build_recovery.py +4 -1
  117. package/skills/gsd-path-build/scripts/build_state.py +66 -23
  118. package/skills/gsd-path-build/scripts/check_handoffs.py +116 -20
  119. package/skills/gsd-path-build/scripts/check_task_briefs.py +60 -8
  120. package/skills/gsd-path-build/scripts/detect_project.py +345 -15
  121. package/skills/gsd-path-build/scripts/discussion_records.py +19 -13
  122. package/skills/gsd-path-build/scripts/discussion_validate.py +66 -21
  123. package/skills/gsd-path-build/scripts/dispatch_driver.py +111 -26
  124. package/skills/gsd-path-build/scripts/integration.py +434 -24
  125. package/skills/gsd-path-build/scripts/isolation.py +1077 -28
  126. package/skills/gsd-path-build/scripts/loop_run.py +20 -30
  127. package/skills/gsd-path-build/scripts/members.py +704 -0
  128. package/skills/gsd-path-build/scripts/path_config.py +2 -2
  129. package/skills/gsd-path-build/scripts/pipeline_git.py +61 -22
  130. package/skills/gsd-path-build/scripts/pipeline_state.py +176 -54
  131. package/skills/gsd-path-build/scripts/promote_lookahead.py +1 -1
  132. package/skills/gsd-path-build/scripts/review_panel.py +1 -1
  133. package/skills/gsd-path-build/scripts/state_checkpoint.py +140 -31
  134. package/skills/gsd-path-build/scripts/state_promote.py +2 -0
  135. package/skills/gsd-path-build/scripts/token_budget.py +12 -8
  136. package/skills/gsd-path-build/scripts/workflow_run.py +103 -29
  137. package/skills/gsd-path-build/scripts/worktree_paths.py +18 -8
  138. package/skills/gsd-path-build/templates/task.md +1 -0
  139. package/skills/gsd-path-build/templates/wave-review.md +3 -1
  140. package/skills/gsd-path-decide/SKILL.md +11 -4
  141. package/skills/gsd-path-decide/references/operating-rules.md +214 -0
  142. package/skills/gsd-path-decide/scripts/_common.py +472 -19
  143. package/skills/gsd-path-decide/scripts/archive_milestone.py +146 -73
  144. package/skills/gsd-path-decide/scripts/build_recovery.py +4 -1
  145. package/skills/gsd-path-decide/scripts/check_handoffs.py +116 -20
  146. package/skills/gsd-path-decide/scripts/check_task_briefs.py +60 -8
  147. package/skills/gsd-path-decide/scripts/detect_project.py +345 -15
  148. package/skills/gsd-path-decide/scripts/discussion_records.py +19 -13
  149. package/skills/gsd-path-decide/scripts/discussion_validate.py +66 -21
  150. package/skills/gsd-path-decide/scripts/integration.py +434 -24
  151. package/skills/gsd-path-decide/scripts/isolation.py +1077 -28
  152. package/skills/gsd-path-decide/scripts/loop_run.py +20 -30
  153. package/skills/gsd-path-decide/scripts/members.py +704 -0
  154. package/skills/gsd-path-decide/scripts/path_config.py +2 -2
  155. package/skills/gsd-path-decide/scripts/pipeline_git.py +61 -22
  156. package/skills/gsd-path-decide/scripts/pipeline_state.py +176 -54
  157. package/skills/gsd-path-decide/scripts/promote_lookahead.py +1 -1
  158. package/skills/gsd-path-decide/scripts/review_panel.py +1 -1
  159. package/skills/gsd-path-decide/scripts/state_checkpoint.py +140 -31
  160. package/skills/gsd-path-decide/scripts/state_promote.py +2 -0
  161. package/skills/gsd-path-decide/scripts/worktree_paths.py +18 -8
  162. package/skills/gsd-path-define/SKILL.md +8 -1
  163. package/skills/gsd-path-define/references/operating-rules.md +214 -0
  164. package/skills/gsd-path-define/scripts/_common.py +472 -19
  165. package/skills/gsd-path-define/scripts/archive_milestone.py +146 -73
  166. package/skills/gsd-path-define/scripts/build_recovery.py +4 -1
  167. package/skills/gsd-path-define/scripts/check_handoffs.py +116 -20
  168. package/skills/gsd-path-define/scripts/check_task_briefs.py +60 -8
  169. package/skills/gsd-path-define/scripts/detect_project.py +345 -15
  170. package/skills/gsd-path-define/scripts/discussion_records.py +19 -13
  171. package/skills/gsd-path-define/scripts/discussion_validate.py +66 -21
  172. package/skills/gsd-path-define/scripts/integration.py +434 -24
  173. package/skills/gsd-path-define/scripts/isolation.py +1077 -28
  174. package/skills/gsd-path-define/scripts/loop_run.py +20 -30
  175. package/skills/gsd-path-define/scripts/members.py +704 -0
  176. package/skills/gsd-path-define/scripts/path_config.py +2 -2
  177. package/skills/gsd-path-define/scripts/pipeline_git.py +61 -22
  178. package/skills/gsd-path-define/scripts/pipeline_state.py +176 -54
  179. package/skills/gsd-path-define/scripts/promote_lookahead.py +1 -1
  180. package/skills/gsd-path-define/scripts/review_panel.py +1 -1
  181. package/skills/gsd-path-define/scripts/state_checkpoint.py +140 -31
  182. package/skills/gsd-path-define/scripts/state_promote.py +2 -0
  183. package/skills/gsd-path-define/scripts/worktree_paths.py +18 -8
  184. package/skills/gsd-path-discuss/SKILL.md +2 -1
  185. package/skills/gsd-path-discuss/references/operating-rules.md +214 -0
  186. package/skills/gsd-path-discuss/scripts/_common.py +472 -19
  187. package/skills/gsd-path-discuss/scripts/discussion_records.py +19 -13
  188. package/skills/gsd-path-discuss/scripts/loop_run.py +20 -30
  189. package/skills/gsd-path-discuss/scripts/path_config.py +2 -2
  190. package/skills/gsd-path-discuss/scripts/review_panel.py +1 -1
  191. package/skills/gsd-path-discuss/scripts/worktree_paths.py +18 -8
  192. package/skills/gsd-path-docs-audit/SKILL.md +6 -4
  193. package/skills/gsd-path-docs-audit/references/docs-auditor.md +2 -1
  194. package/skills/gsd-path-docs-audit/references/operating-rules.md +214 -0
  195. package/skills/gsd-path-docs-audit/scripts/_common.py +472 -19
  196. package/skills/gsd-path-docs-audit/scripts/archive_milestone.py +146 -73
  197. package/skills/gsd-path-docs-audit/scripts/build_recovery.py +4 -1
  198. package/skills/gsd-path-docs-audit/scripts/check_docs_audit.py +14 -3
  199. package/skills/gsd-path-docs-audit/scripts/check_handoffs.py +116 -20
  200. package/skills/gsd-path-docs-audit/scripts/check_task_briefs.py +60 -8
  201. package/skills/gsd-path-docs-audit/scripts/detect_project.py +345 -15
  202. package/skills/gsd-path-docs-audit/scripts/discussion_records.py +19 -13
  203. package/skills/gsd-path-docs-audit/scripts/discussion_validate.py +66 -21
  204. package/skills/gsd-path-docs-audit/scripts/integration.py +434 -24
  205. package/skills/gsd-path-docs-audit/scripts/isolation.py +1077 -28
  206. package/skills/gsd-path-docs-audit/scripts/loop_run.py +20 -30
  207. package/skills/gsd-path-docs-audit/scripts/members.py +704 -0
  208. package/skills/gsd-path-docs-audit/scripts/path_config.py +2 -2
  209. package/skills/gsd-path-docs-audit/scripts/pipeline_git.py +61 -22
  210. package/skills/gsd-path-docs-audit/scripts/pipeline_state.py +176 -54
  211. package/skills/gsd-path-docs-audit/scripts/promote_lookahead.py +1 -1
  212. package/skills/gsd-path-docs-audit/scripts/review_panel.py +1 -1
  213. package/skills/gsd-path-docs-audit/scripts/state_checkpoint.py +140 -31
  214. package/skills/gsd-path-docs-audit/scripts/state_promote.py +2 -0
  215. package/skills/gsd-path-docs-audit/scripts/worktree_paths.py +18 -8
  216. package/skills/gsd-path-docs-audit/templates/docs-audit.md +1 -1
  217. package/skills/gsd-path-forensics/SKILL.md +2 -1
  218. package/skills/gsd-path-forensics/references/operating-rules.md +214 -0
  219. package/skills/gsd-path-forensics/scripts/_common.py +472 -19
  220. package/skills/gsd-path-forensics/scripts/discussion_records.py +19 -13
  221. package/skills/gsd-path-forensics/scripts/loop_run.py +20 -30
  222. package/skills/gsd-path-forensics/scripts/path_config.py +2 -2
  223. package/skills/gsd-path-forensics/scripts/pipeline_diagnose.py +82 -31
  224. package/skills/gsd-path-forensics/scripts/pipeline_undo.py +117 -22
  225. package/skills/gsd-path-forensics/scripts/review_panel.py +1 -1
  226. package/skills/gsd-path-forensics/scripts/worktree_paths.py +18 -8
  227. package/skills/gsd-path-inspect/SKILL.md +5 -4
  228. package/skills/gsd-path-inspect/references/codebase-mapper.md +2 -1
  229. package/skills/gsd-path-inspect/references/docs-auditor.md +2 -1
  230. package/skills/gsd-path-inspect/references/operating-rules.md +214 -0
  231. package/skills/gsd-path-inspect/scripts/__pycache__/_common.cpython-312.pyc +0 -0
  232. package/skills/gsd-path-inspect/scripts/_common.py +472 -19
  233. package/skills/gsd-path-inspect/scripts/archive_milestone.py +146 -73
  234. package/skills/gsd-path-inspect/scripts/build_recovery.py +4 -1
  235. package/skills/gsd-path-inspect/scripts/check_docs_audit.py +14 -3
  236. package/skills/gsd-path-inspect/scripts/check_handoffs.py +116 -20
  237. package/skills/gsd-path-inspect/scripts/check_task_briefs.py +60 -8
  238. package/skills/gsd-path-inspect/scripts/detect_project.py +345 -15
  239. package/skills/gsd-path-inspect/scripts/discussion_records.py +19 -13
  240. package/skills/gsd-path-inspect/scripts/discussion_validate.py +66 -21
  241. package/skills/gsd-path-inspect/scripts/integration.py +434 -24
  242. package/skills/gsd-path-inspect/scripts/isolation.py +1077 -28
  243. package/skills/gsd-path-inspect/scripts/loop_run.py +20 -30
  244. package/skills/gsd-path-inspect/scripts/members.py +704 -0
  245. package/skills/gsd-path-inspect/scripts/path_config.py +2 -2
  246. package/skills/gsd-path-inspect/scripts/pipeline_git.py +61 -22
  247. package/skills/gsd-path-inspect/scripts/pipeline_state.py +176 -54
  248. package/skills/gsd-path-inspect/scripts/promote_lookahead.py +1 -1
  249. package/skills/gsd-path-inspect/scripts/review_panel.py +1 -1
  250. package/skills/gsd-path-inspect/scripts/state_checkpoint.py +140 -31
  251. package/skills/gsd-path-inspect/scripts/state_promote.py +2 -0
  252. package/skills/gsd-path-inspect/scripts/workflow_run.py +103 -29
  253. package/skills/gsd-path-inspect/scripts/worktree_paths.py +18 -8
  254. package/skills/gsd-path-inspect/templates/codebase.md +1 -1
  255. package/skills/gsd-path-inspect/templates/docs-audit.md +1 -1
  256. package/skills/gsd-path-loop/SKILL.md +2 -1
  257. package/skills/gsd-path-loop/references/operating-rules.md +214 -0
  258. package/skills/gsd-path-loop/scripts/_common.py +472 -19
  259. package/skills/gsd-path-loop/scripts/discussion_records.py +19 -13
  260. package/skills/gsd-path-loop/scripts/loop_run.py +20 -30
  261. package/skills/gsd-path-loop/scripts/path_config.py +2 -2
  262. package/skills/gsd-path-loop/scripts/review_panel.py +1 -1
  263. package/skills/gsd-path-loop/scripts/worktree_paths.py +18 -8
  264. package/skills/gsd-path-migrate/SKILL.md +2 -1
  265. package/skills/gsd-path-migrate/references/operating-rules.md +214 -0
  266. package/skills/gsd-path-migrate/scripts/_common.py +472 -19
  267. package/skills/gsd-path-migrate/scripts/core_hook_gate.py +10 -1
  268. package/skills/gsd-path-migrate/scripts/core_hook_settings.py +11 -4
  269. package/skills/gsd-path-migrate/scripts/discussion_records.py +19 -13
  270. package/skills/gsd-path-migrate/scripts/loop_run.py +20 -30
  271. package/skills/gsd-path-migrate/scripts/migrate_core.py +2 -2
  272. package/skills/gsd-path-migrate/scripts/path_config.py +2 -2
  273. package/skills/gsd-path-migrate/scripts/review_panel.py +1 -1
  274. package/skills/gsd-path-plan/SKILL.md +7 -1
  275. package/skills/gsd-path-plan/references/operating-rules.md +214 -0
  276. package/skills/gsd-path-plan/references/planner.md +8 -0
  277. package/skills/gsd-path-plan/scripts/__pycache__/_common.cpython-312.pyc +0 -0
  278. package/skills/gsd-path-plan/scripts/_common.py +472 -19
  279. package/skills/gsd-path-plan/scripts/archive_milestone.py +146 -73
  280. package/skills/gsd-path-plan/scripts/build_recovery.py +4 -1
  281. package/skills/gsd-path-plan/scripts/check_handoffs.py +116 -20
  282. package/skills/gsd-path-plan/scripts/check_task_briefs.py +60 -8
  283. package/skills/gsd-path-plan/scripts/detect_project.py +345 -15
  284. package/skills/gsd-path-plan/scripts/discussion_records.py +19 -13
  285. package/skills/gsd-path-plan/scripts/discussion_validate.py +66 -21
  286. package/skills/gsd-path-plan/scripts/integration.py +434 -24
  287. package/skills/gsd-path-plan/scripts/isolation.py +1077 -28
  288. package/skills/gsd-path-plan/scripts/loop_run.py +20 -30
  289. package/skills/gsd-path-plan/scripts/members.py +704 -0
  290. package/skills/gsd-path-plan/scripts/path_config.py +2 -2
  291. package/skills/gsd-path-plan/scripts/pipeline_git.py +61 -22
  292. package/skills/gsd-path-plan/scripts/pipeline_state.py +176 -54
  293. package/skills/gsd-path-plan/scripts/promote_lookahead.py +1 -1
  294. package/skills/gsd-path-plan/scripts/review_panel.py +1 -1
  295. package/skills/gsd-path-plan/scripts/state_checkpoint.py +140 -31
  296. package/skills/gsd-path-plan/scripts/state_promote.py +2 -0
  297. package/skills/gsd-path-plan/scripts/workflow_run.py +103 -29
  298. package/skills/gsd-path-plan/scripts/worktree_paths.py +18 -8
  299. package/skills/gsd-path-plan/templates/task.md +1 -0
  300. package/skills/gsd-path-research/SKILL.md +2 -1
  301. package/skills/gsd-path-research/references/operating-rules.md +214 -0
  302. package/skills/gsd-path-research/scripts/_common.py +472 -19
  303. package/skills/gsd-path-research/scripts/archive_milestone.py +146 -73
  304. package/skills/gsd-path-research/scripts/build_recovery.py +4 -1
  305. package/skills/gsd-path-research/scripts/check_handoffs.py +116 -20
  306. package/skills/gsd-path-research/scripts/check_task_briefs.py +60 -8
  307. package/skills/gsd-path-research/scripts/detect_project.py +345 -15
  308. package/skills/gsd-path-research/scripts/discussion_records.py +19 -13
  309. package/skills/gsd-path-research/scripts/discussion_validate.py +66 -21
  310. package/skills/gsd-path-research/scripts/integration.py +434 -24
  311. package/skills/gsd-path-research/scripts/isolation.py +1077 -28
  312. package/skills/gsd-path-research/scripts/loop_run.py +20 -30
  313. package/skills/gsd-path-research/scripts/members.py +704 -0
  314. package/skills/gsd-path-research/scripts/path_config.py +2 -2
  315. package/skills/gsd-path-research/scripts/pipeline_git.py +61 -22
  316. package/skills/gsd-path-research/scripts/pipeline_state.py +176 -54
  317. package/skills/gsd-path-research/scripts/promote_lookahead.py +1 -1
  318. package/skills/gsd-path-research/scripts/review_panel.py +1 -1
  319. package/skills/gsd-path-research/scripts/state_checkpoint.py +140 -31
  320. package/skills/gsd-path-research/scripts/state_promote.py +2 -0
  321. package/skills/gsd-path-research/scripts/worktree_paths.py +18 -8
  322. package/skills/gsd-path-roadmap/SKILL.md +2 -1
  323. package/skills/gsd-path-roadmap/references/operating-rules.md +214 -0
  324. package/skills/gsd-path-roadmap/scripts/_common.py +472 -19
  325. package/skills/gsd-path-roadmap/scripts/archive_milestone.py +146 -73
  326. package/skills/gsd-path-roadmap/scripts/build_recovery.py +4 -1
  327. package/skills/gsd-path-roadmap/scripts/check_handoffs.py +116 -20
  328. package/skills/gsd-path-roadmap/scripts/check_task_briefs.py +60 -8
  329. package/skills/gsd-path-roadmap/scripts/detect_project.py +345 -15
  330. package/skills/gsd-path-roadmap/scripts/discussion_records.py +19 -13
  331. package/skills/gsd-path-roadmap/scripts/discussion_validate.py +66 -21
  332. package/skills/gsd-path-roadmap/scripts/integration.py +434 -24
  333. package/skills/gsd-path-roadmap/scripts/isolation.py +1077 -28
  334. package/skills/gsd-path-roadmap/scripts/loop_run.py +20 -30
  335. package/skills/gsd-path-roadmap/scripts/members.py +704 -0
  336. package/skills/gsd-path-roadmap/scripts/path_config.py +2 -2
  337. package/skills/gsd-path-roadmap/scripts/pipeline_git.py +61 -22
  338. package/skills/gsd-path-roadmap/scripts/pipeline_state.py +176 -54
  339. package/skills/gsd-path-roadmap/scripts/promote_lookahead.py +1 -1
  340. package/skills/gsd-path-roadmap/scripts/review_panel.py +1 -1
  341. package/skills/gsd-path-roadmap/scripts/state_checkpoint.py +140 -31
  342. package/skills/gsd-path-roadmap/scripts/state_promote.py +2 -0
  343. package/skills/gsd-path-roadmap/scripts/worktree_paths.py +18 -8
  344. package/skills/gsd-path-ship/SKILL.md +27 -10
  345. package/skills/gsd-path-ship/references/operating-rules.md +214 -0
  346. package/skills/gsd-path-ship/references/reviewer-wave.md +3 -1
  347. package/skills/gsd-path-ship/scripts/__pycache__/_common.cpython-312.pyc +0 -0
  348. package/skills/gsd-path-ship/scripts/_common.py +472 -19
  349. package/skills/gsd-path-ship/scripts/archive_milestone.py +146 -73
  350. package/skills/gsd-path-ship/scripts/build_recovery.py +4 -1
  351. package/skills/gsd-path-ship/scripts/build_state.py +66 -23
  352. package/skills/gsd-path-ship/scripts/check_handoffs.py +116 -20
  353. package/skills/gsd-path-ship/scripts/check_task_briefs.py +60 -8
  354. package/skills/gsd-path-ship/scripts/detect_project.py +345 -15
  355. package/skills/gsd-path-ship/scripts/discussion_records.py +19 -13
  356. package/skills/gsd-path-ship/scripts/discussion_validate.py +66 -21
  357. package/skills/gsd-path-ship/scripts/integration.py +434 -24
  358. package/skills/gsd-path-ship/scripts/isolation.py +1077 -28
  359. package/skills/gsd-path-ship/scripts/lean_verification.py +99 -19
  360. package/skills/gsd-path-ship/scripts/loop_run.py +20 -30
  361. package/skills/gsd-path-ship/scripts/members.py +704 -0
  362. package/skills/gsd-path-ship/scripts/path_config.py +2 -2
  363. package/skills/gsd-path-ship/scripts/pipeline_git.py +61 -22
  364. package/skills/gsd-path-ship/scripts/pipeline_state.py +176 -54
  365. package/skills/gsd-path-ship/scripts/promote_lookahead.py +1 -1
  366. package/skills/gsd-path-ship/scripts/review_panel.py +1 -1
  367. package/skills/gsd-path-ship/scripts/state_checkpoint.py +140 -31
  368. package/skills/gsd-path-ship/scripts/state_promote.py +2 -0
  369. package/skills/gsd-path-ship/scripts/workflow_run.py +103 -29
  370. package/skills/gsd-path-ship/scripts/worktree_paths.py +18 -8
  371. package/skills/gsd-path-ship/templates/final-review.md +5 -2
  372. package/skills/gsd-path-ship/templates/gap-review.md +2 -1
  373. package/skills/gsd-path-ship/templates/wave-review.md +3 -1
  374. package/skills/gsd-path-undo/SKILL.md +2 -1
  375. package/skills/gsd-path-undo/references/operating-rules.md +214 -0
  376. package/skills/gsd-path-undo/scripts/_common.py +472 -19
  377. package/skills/gsd-path-undo/scripts/discussion_records.py +19 -13
  378. package/skills/gsd-path-undo/scripts/loop_run.py +20 -30
  379. package/skills/gsd-path-undo/scripts/path_config.py +2 -2
  380. package/skills/gsd-path-undo/scripts/pipeline_undo.py +117 -22
  381. package/skills/gsd-path-undo/scripts/review_panel.py +1 -1
  382. package/skills/gsd-path-undo/scripts/worktree_paths.py +18 -8
  383. package/skills/path/BUILD.md +7 -1
  384. package/skills/path/DECIDE.md +11 -4
  385. package/skills/path/DEFINE.md +8 -1
  386. package/skills/path/DOCS-AUDIT.md +6 -4
  387. package/skills/path/INSPECT.md +5 -4
  388. package/skills/path/PLAN.md +7 -1
  389. package/skills/path/RESEARCH.md +2 -1
  390. package/skills/path/ROADMAP.md +2 -1
  391. package/skills/path/SHIP.md +27 -10
  392. package/skills/path/SKILL.md +45 -1
  393. package/skills/path/references/build-native.md +47 -14
  394. package/skills/path/references/codebase-mapper.md +2 -1
  395. package/skills/path/references/docs-auditor.md +2 -1
  396. package/skills/path/references/operating-rules.md +214 -0
  397. package/skills/path/references/planner.md +8 -0
  398. package/skills/path/references/reviewer-wave.md +3 -1
  399. package/skills/path/scripts/_common.py +472 -19
  400. package/skills/path/scripts/archive_milestone.py +146 -73
  401. package/skills/path/scripts/bootstrap_repository.py +8 -5
  402. package/skills/path/scripts/build_recovery.py +4 -1
  403. package/skills/path/scripts/build_state.py +66 -23
  404. package/skills/path/scripts/check_docs_audit.py +14 -3
  405. package/skills/path/scripts/check_handoffs.py +116 -20
  406. package/skills/path/scripts/check_task_briefs.py +60 -8
  407. package/skills/path/scripts/check_update.py +2 -2
  408. package/skills/path/scripts/detect_project.py +345 -15
  409. package/skills/path/scripts/discussion_records.py +19 -13
  410. package/skills/path/scripts/discussion_validate.py +66 -21
  411. package/skills/path/scripts/dispatch_driver.py +111 -26
  412. package/skills/path/scripts/git_guard.py +116 -29
  413. package/skills/path/scripts/integration.py +434 -24
  414. package/skills/path/scripts/isolation.py +1077 -28
  415. package/skills/path/scripts/lean_verification.py +99 -19
  416. package/skills/path/scripts/loop_run.py +20 -30
  417. package/skills/path/scripts/members.py +704 -0
  418. package/skills/path/scripts/path_config.py +2 -2
  419. package/skills/path/scripts/pipeline_git.py +61 -22
  420. package/skills/path/scripts/pipeline_state.py +176 -54
  421. package/skills/path/scripts/promote_lookahead.py +1 -1
  422. package/skills/path/scripts/review_panel.py +1 -1
  423. package/skills/path/scripts/state_checkpoint.py +140 -31
  424. package/skills/path/scripts/state_promote.py +2 -0
  425. package/skills/path/scripts/status_runtime.py +36 -6
  426. package/skills/path/scripts/token_budget.py +12 -8
  427. package/skills/path/scripts/workflow_run.py +103 -29
  428. package/skills/path/scripts/worktree_paths.py +18 -8
  429. package/skills/path/templates/codebase.md +1 -1
  430. package/skills/path/templates/docs-audit.md +1 -1
  431. package/skills/path/templates/final-review.md +5 -2
  432. package/skills/path/templates/gap-review.md +2 -1
  433. package/skills/path/templates/task.md +1 -0
  434. package/skills/path/templates/wave-review.md +3 -1
@@ -174,13 +174,13 @@ def set_value(repo, scope, key, value, reset=False):
174
174
  if scope == 'project':
175
175
  state, _, _ = sibling('pipeline_state').load_state(repo)
176
176
  branch = subprocess.run(['git', '-C', str(repo), 'branch', '--show-current'],
177
- capture_output=True, text=True)
177
+ capture_output=True, encoding="utf-8", errors="replace")
178
178
  if branch.returncode or not state.branch or branch.stdout.strip() != state.branch:
179
179
  raise ValueError('Run the router to bind the project branch before editing settings.')
180
180
  head = subprocess.run(['git', '-C', str(repo), 'rev-parse', '--verify', 'HEAD'], capture_output=True)
181
181
  if head.returncode == 0:
182
182
  closed = subprocess.run([sys.executable, '-B', str(Path(__file__).with_name('git_guard.py')),
183
- 'closed-milestone'], cwd=repo, capture_output=True, text=True)
183
+ 'closed-milestone'], cwd=repo, capture_output=True, encoding="utf-8", errors="replace")
184
184
  if closed.returncode:
185
185
  raise ValueError(closed.stderr.strip() or 'Cannot verify the milestone branch is open.')
186
186
  if scope == 'project' and key == 'integration':
@@ -10,6 +10,7 @@ from __future__ import annotations
10
10
 
11
11
  import argparse
12
12
  import json
13
+ import os
13
14
  import shlex
14
15
  import sys
15
16
 
@@ -20,14 +21,14 @@ from typing import Callable, Optional, Sequence
20
21
 
21
22
 
22
23
  def _load_diagnose_modules():
23
- try:
24
- import archive_milestone
25
- import detect_project
26
- import discussion_records
27
- import integration
28
- import isolation
29
- import pipeline_git
30
- import pipeline_state
24
+ if __package__:
25
+ from . import archive_milestone
26
+ from . import detect_project
27
+ from . import discussion_records
28
+ from . import integration
29
+ from . import isolation
30
+ from . import pipeline_git
31
+ from . import pipeline_state
31
32
  return (
32
33
  archive_milestone,
33
34
  detect_project,
@@ -37,17 +38,35 @@ def _load_diagnose_modules():
37
38
  pipeline_git,
38
39
  pipeline_state,
39
40
  )
40
- except ModuleNotFoundError as error:
41
- if error.name not in {
42
- "archive_milestone",
43
- "detect_project",
44
- "discussion_records",
45
- "integration",
46
- "isolation",
47
- "pipeline_git",
48
- "pipeline_state",
49
- }:
50
- raise
41
+ else:
42
+ try:
43
+ import archive_milestone
44
+ import detect_project
45
+ import discussion_records
46
+ import integration
47
+ import isolation
48
+ import pipeline_git
49
+ import pipeline_state
50
+ return (
51
+ archive_milestone,
52
+ detect_project,
53
+ discussion_records,
54
+ integration,
55
+ isolation,
56
+ pipeline_git,
57
+ pipeline_state,
58
+ )
59
+ except ModuleNotFoundError as error:
60
+ if error.name not in {
61
+ "archive_milestone",
62
+ "detect_project",
63
+ "discussion_records",
64
+ "integration",
65
+ "isolation",
66
+ "pipeline_git",
67
+ "pipeline_state",
68
+ }:
69
+ raise
51
70
  try:
52
71
  from scripts import (
53
72
  archive_milestone,
@@ -116,21 +135,25 @@ _worktree_report = isolation._worktree_report
116
135
  PipelineStateError = pipeline_state.PipelineStateError
117
136
  status_state = pipeline_state.status_state
118
137
  validate_state = pipeline_state.validate_state
138
+ _run_git = pipeline_state._run_git
119
139
 
120
- try:
121
- import pipeline_undo
122
- except ModuleNotFoundError as error:
123
- if error.name != "pipeline_undo":
124
- raise
140
+ if __package__:
141
+ from . import pipeline_undo
142
+ else:
125
143
  try:
126
- from scripts import pipeline_undo
144
+ import pipeline_undo
127
145
  except ModuleNotFoundError as error:
128
- if error.name not in {"scripts", "scripts.pipeline_undo"}:
146
+ if error.name != "pipeline_undo":
129
147
  raise
130
- shared = Path(__file__).resolve().parents[2] / "gsd-path" / "scripts"
131
- if str(shared) not in sys.path:
132
- sys.path.insert(0, str(shared))
133
- import pipeline_undo
148
+ try:
149
+ from scripts import pipeline_undo
150
+ except ModuleNotFoundError as error:
151
+ if error.name not in {"scripts", "scripts.pipeline_undo"}:
152
+ raise
153
+ shared = Path(__file__).resolve().parents[2] / "gsd-path" / "scripts"
154
+ if str(shared) not in sys.path:
155
+ sys.path.insert(0, str(shared))
156
+ import pipeline_undo
134
157
 
135
158
  UndoError = pipeline_undo.UndoError
136
159
  undo_preview = pipeline_undo.preview
@@ -194,7 +217,12 @@ def _state_template() -> Path:
194
217
 
195
218
  def _command(module: object, *arguments: object) -> str:
196
219
  script = Path(str(getattr(module, "__file__"))).resolve()
197
- return shlex.join([sys.executable, str(script), *map(str, arguments)])
220
+ def text(value: object) -> str:
221
+ # Agents paste this into Git Bash on Windows, where unquoted
222
+ # backslashes are escapes; forward slashes need no quoting.
223
+ return value.as_posix() if isinstance(value, Path) and os.name == "nt" else str(value)
224
+
225
+ return shlex.join([text(Path(sys.executable)), text(script), *map(text, arguments)])
198
226
 
199
227
 
200
228
  def _route_retry(
@@ -391,6 +419,29 @@ def diagnose(repo: Path) -> dict[str, object]:
391
419
  for key, path in (status.get("journals") or {}).items()
392
420
  if path
393
421
  }
422
+ pending_members = [row["name"] for row in status.get("members") or [] if row["close"] == "pending"]
423
+ if pending_members:
424
+ findings.append(
425
+ _finding(
426
+ "member-close",
427
+ "stuck",
428
+ "member close is pending for: " + ", ".join(pending_members),
429
+ _command(archive_milestone, "close-members", "--repo", resolved),
430
+ )
431
+ )
432
+ common = _run_git(resolved, "rev-parse", "--path-format=absolute", "--git-common-dir", check=False)
433
+ landings = sorted(
434
+ (Path(common.stdout.strip()) / "gsd-path" / "member-landings").glob("*.json")
435
+ ) if common.returncode == 0 else []
436
+ if landings:
437
+ findings.append(
438
+ _finding(
439
+ "member-landing",
440
+ "stuck",
441
+ "member landing journal is pending: " + ", ".join(path.stem for path in landings),
442
+ "resume build; the dispatch driver finishes pending member landings before new work",
443
+ )
444
+ )
394
445
  undo_probe = by_name["undo-preview"]
395
446
  undo_result = undo_probe["result"] if undo_probe["ok"] else None
396
447
  route_retry = _route_retry(resolved, route, undo_result)
@@ -25,22 +25,30 @@ from pathlib import Path, PurePosixPath
25
25
  from typing import Optional, Sequence
26
26
 
27
27
  def _load_pipeline_modules():
28
- try:
29
- import archive_milestone
30
- import isolation
31
- import pipeline_git
32
- import pipeline_state
33
- import state_checkpoint
28
+ if __package__:
29
+ from . import archive_milestone
30
+ from . import isolation
31
+ from . import pipeline_git
32
+ from . import pipeline_state
33
+ from . import state_checkpoint
34
34
  return archive_milestone, isolation, pipeline_git, pipeline_state, state_checkpoint
35
- except ModuleNotFoundError as error:
36
- if error.name not in {
37
- "archive_milestone",
38
- "isolation",
39
- "pipeline_git",
40
- "pipeline_state",
41
- "state_checkpoint",
42
- }:
43
- raise
35
+ else:
36
+ try:
37
+ import archive_milestone
38
+ import isolation
39
+ import pipeline_git
40
+ import pipeline_state
41
+ import state_checkpoint
42
+ return archive_milestone, isolation, pipeline_git, pipeline_state, state_checkpoint
43
+ except ModuleNotFoundError as error:
44
+ if error.name not in {
45
+ "archive_milestone",
46
+ "isolation",
47
+ "pipeline_git",
48
+ "pipeline_state",
49
+ "state_checkpoint",
50
+ }:
51
+ raise
44
52
  try:
45
53
  from scripts import archive_milestone, isolation, pipeline_git, pipeline_state, state_checkpoint
46
54
  return archive_milestone, isolation, pipeline_git, pipeline_state, state_checkpoint
@@ -94,7 +102,7 @@ UNDO_TRANSACTION_SCHEMA = pipeline_state.UNDO_TRANSACTION_SCHEMA
94
102
  UNDO_TRANSACTION_NAME = pipeline_state.UNDO_TRANSACTION_NAME
95
103
  ROADMAP_APPROVAL_SUBJECT = "roadmap: program roadmap approved"
96
104
  TASK_SUBJECT_RE = re.compile(r"^(T\d{3,}): .+")
97
- KINDS = ("checkpoint", "task", "uncommitted-archive", "lookahead")
105
+ KINDS = ("checkpoint", "task", "member-task", "uncommitted-archive", "lookahead")
98
106
  PROMOTION_PREFIX = "router: promote lookahead milestone "
99
107
  ABANDON_PREFIX = "build: abandon milestone "
100
108
  INTEGRATE_PREFIX = "integrate: "
@@ -528,6 +536,7 @@ def _prepare_transaction(
528
536
  branch: str,
529
537
  archive: Optional[str],
530
538
  discussion: Optional[dict[str, bytes]],
539
+ member_fields: Optional[dict[str, str]] = None,
531
540
  ) -> dict[str, object]:
532
541
  transaction = {
533
542
  "schema": UNDO_TRANSACTION_SCHEMA,
@@ -545,6 +554,8 @@ def _prepare_transaction(
545
554
  ),
546
555
  "discussion": _encode_discussion(discussion),
547
556
  }
557
+ if member_fields is not None:
558
+ transaction.update(member_fields)
548
559
  _write_json(_git_path(repo, UNDO_TRANSACTION_NAME), transaction)
549
560
  return transaction
550
561
 
@@ -641,7 +652,7 @@ def _transaction_recovery_stage(
641
652
  expected_head = str(transaction["expected_head"])
642
653
  parent = str(transaction["parent"])
643
654
  current = _optional_rev(repo, "HEAD")
644
- if transaction["kind"] == "checkpoint":
655
+ if transaction["kind"] in {"checkpoint", "member-task"}:
645
656
  allowed = {expected_head, parent}
646
657
  else:
647
658
  allowed = {expected_head}
@@ -662,8 +673,60 @@ def _transaction_recovery_stage(
662
673
  return "reset"
663
674
 
664
675
 
676
+ def _member_undo_parent(repo: Path, member: str, landing: str) -> str:
677
+ """The member landing's parent, while that landing is the unpublished bound tip."""
678
+ checkout, _, entry = isolation._member_context(repo, member)
679
+ bound = entry["branch"]
680
+ if _run_git(checkout, "rev-parse", f"refs/heads/{bound}").stdout.strip() != landing:
681
+ raise UndoError(f"member {member} {bound} moved past this landing")
682
+ _require_member_unpublished(checkout, member, landing, bound)
683
+ return _run_git(checkout, "rev-parse", f"{landing}^").stdout.strip()
684
+
685
+
686
+ def _require_member_unpublished(checkout: Path, member: str, landing: str, bound: str) -> None:
687
+ for ref, where in (("refs/remotes/origin/main", "origin/main"), (f"refs/remotes/origin/{bound}", f"origin/{bound}")):
688
+ if _run_git(checkout, "merge-base", "--is-ancestor", landing, ref, check=False).returncode == 0:
689
+ raise UndoError(f"member {member} landing is already on {where}")
690
+
691
+
692
+ def _require_no_member_landing_journal(repo: Path) -> None:
693
+ directory = isolation.common_git_dir(repo).joinpath(*isolation.MEMBER_LANDING_DIR)
694
+ if any(directory.glob("*.json")):
695
+ raise UndoError("member landing journal is pending; recover member landing first")
696
+
697
+
698
+ def _undo_member_landing(repo: Path, transaction: dict[str, object]) -> None:
699
+ """Reset the member bound branch first; a resumed undo finds it already reset."""
700
+ member = str(transaction["member"])
701
+ checkout, _, entry = isolation._member_context(repo, member)
702
+ tip = _run_git(checkout, "rev-parse", f"refs/heads/{entry['branch']}").stdout.strip()
703
+ if tip == transaction["member_parent"]:
704
+ _require_member_unpublished(checkout, member, str(transaction["landing"]), entry["branch"])
705
+ return
706
+ if tip != transaction["landing"]:
707
+ raise UndoError(f"member {member} bound branch moved during undo")
708
+ if _member_undo_parent(repo, member, str(transaction["landing"])) != transaction["member_parent"]:
709
+ raise UndoError(f"member {member} landing parent changed during undo")
710
+ bound = Path(isolation.member_bound_checkout(repo, member)["checkout"])
711
+ if _run_git(bound, "status", "--porcelain", "--untracked-files=all").stdout:
712
+ raise UndoError(f"member {member} bound checkout is dirty")
713
+ _run_git(bound, "reset", "--hard", str(transaction["member_parent"]))
714
+
715
+
665
716
  def _finish_transaction(repo: Path, transaction: dict[str, object]) -> None:
717
+ if transaction["kind"] == "member-task":
718
+ with isolation._member_landing_lock(repo):
719
+ _finish_transaction_locked(repo, transaction)
720
+ return
721
+ _finish_transaction_locked(repo, transaction)
722
+
723
+
724
+ def _finish_transaction_locked(repo: Path, transaction: dict[str, object]) -> None:
725
+ if transaction["kind"] == "member-task":
726
+ _require_no_member_landing_journal(repo)
666
727
  stage = _transaction_recovery_stage(repo, transaction)
728
+ if transaction["kind"] == "member-task":
729
+ _undo_member_landing(repo, transaction)
667
730
  if stage == "prepared":
668
731
  _require_unpublished_reset(repo, str(transaction["branch"]))
669
732
  _reset_to(repo, str(transaction["parent"]))
@@ -675,11 +738,7 @@ def _finish_transaction(repo: Path, transaction: dict[str, object]) -> None:
675
738
  _remove_untracked_tree(repo, archive)
676
739
  path = _git_path(repo, UNDO_TRANSACTION_NAME)
677
740
  path.unlink()
678
- descriptor = os.open(path.parent, os.O_RDONLY)
679
- try:
680
- os.fsync(descriptor)
681
- finally:
682
- os.close(descriptor)
741
+ pipeline_state._common.fsync_directory(path.parent)
683
742
 
684
743
 
685
744
  def classify_undo(repo: Path) -> dict[str, object]:
@@ -821,6 +880,28 @@ def classify_undo(repo: Path) -> dict[str, object]:
821
880
  proof_error = _task_proof_error(resolved, head)
822
881
  if proof_error:
823
882
  return _blocked([f"task landing ownership is unproven: {proof_error}"])
883
+ record = isolation.MEMBER_RECORD_RE.search(body)
884
+ if record is not None:
885
+ try:
886
+ _require_no_member_landing_journal(resolved)
887
+ member_parent = _member_undo_parent(resolved, record["member"], record["landing"])
888
+ except (IsolationError, UndoError, PipelineStateError) as error:
889
+ return _blocked([f"member landing undo is unsafe: {error}"])
890
+ return {
891
+ "kind": "member-task",
892
+ "branch": recorded_branch,
893
+ "head": head,
894
+ "parent": parent,
895
+ "subject": subject,
896
+ "member": record["member"],
897
+ "landing": record["landing"],
898
+ "member_parent": member_parent,
899
+ "effects": [
900
+ f"reset member {record['member']} bound branch to {member_parent}",
901
+ f"reset {recorded_branch} to {parent}",
902
+ ],
903
+ "blocked": [],
904
+ }
824
905
  return {
825
906
  "kind": "task",
826
907
  "branch": recorded_branch,
@@ -978,6 +1059,20 @@ def apply_undo(repo: Path, kind: str, expected_head: str) -> dict[str, object]:
978
1059
  discussion,
979
1060
  )
980
1061
  _finish_transaction(resolved, transaction)
1062
+ elif kind == "member-task":
1063
+ with isolation._member_landing_lock(resolved):
1064
+ _require_no_member_landing_journal(resolved)
1065
+ if preview(resolved)["target"] != target:
1066
+ raise UndoError("member task undo target changed after preview")
1067
+ if _worktree_changes(resolved):
1068
+ raise UndoError("worktree changed after member task undo preview")
1069
+ _require_unpublished_reset(resolved, str(target["branch"]))
1070
+ transaction = _prepare_transaction(
1071
+ resolved, kind, expected_head, str(target["parent"]), str(target["branch"]), None, None,
1072
+ {"member": str(target["member"]), "landing": str(target["landing"]),
1073
+ "member_parent": str(target["member_parent"])},
1074
+ )
1075
+ _finish_transaction_locked(resolved, transaction)
981
1076
  elif kind == "task":
982
1077
  parent = target["parent"]
983
1078
  if not parent:
@@ -470,7 +470,7 @@ def merge_artifacts(
470
470
  lines.append(artifact["text"].rstrip())
471
471
  lines.append("")
472
472
  output.parent.mkdir(parents=True, exist_ok=True)
473
- output.write_text("\n".join(lines).rstrip() + "\n", encoding="utf-8")
473
+ output.write_bytes(("\n".join(lines).rstrip() + "\n").encode("utf-8"))
474
474
  return {
475
475
  "output": str(output.resolve()),
476
476
  "families": families,
@@ -13,10 +13,13 @@ import os
13
13
  import tempfile
14
14
  from pathlib import Path
15
15
 
16
- try:
17
- import _common
18
- except ImportError:
19
- from scripts import _common
16
+ if __package__:
17
+ from . import _common
18
+ else:
19
+ try:
20
+ import _common
21
+ except ImportError:
22
+ from scripts import _common
20
23
 
21
24
 
22
25
  def _git(primary: Path, *args: str) -> str:
@@ -27,7 +30,10 @@ def _git(primary: Path, *args: str) -> str:
27
30
 
28
31
 
29
32
  def _identity(path: Path) -> str:
30
- return hashlib.sha256(os.fsencode(path)).hexdigest()
33
+ digest = hashlib.sha256(os.fsencode(path)).hexdigest()
34
+ # Two identities nest in every managed path; full digests would use about
35
+ # 130 of Windows' 260-character MAX_PATH before any repository content.
36
+ return digest[:16] if os.name == "nt" else digest
31
37
 
32
38
 
33
39
  def _workspace(primary: Path, pin: bool) -> Path:
@@ -65,7 +71,7 @@ def _workspace(primary: Path, pin: bool) -> Path:
65
71
  receipt.parent.mkdir(parents=True, exist_ok=True)
66
72
  fd, temporary = tempfile.mkstemp(dir=receipt.parent)
67
73
  try:
68
- with os.fdopen(fd, "w", encoding="utf-8") as handle:
74
+ with os.fdopen(fd, "w", encoding="utf-8", newline="\n") as handle:
69
75
  json.dump({"primary": str(primary), "root": str(workspace)}, handle)
70
76
  try:
71
77
  os.link(temporary, receipt)
@@ -78,15 +84,19 @@ def _workspace(primary: Path, pin: bool) -> Path:
78
84
 
79
85
  def worktree_path(primary: Path, kind: str, name: str, *, pin: bool = False) -> Path:
80
86
  primary = primary.resolve()
81
- if kind not in {"task", "verify", "integrate"} or not name or Path(name).name != name or name in {".", ".."}:
87
+ if kind not in {"task", "verify", "integrate", "bound"} or not name or Path(name).name != name or name in {".", ".."}:
82
88
  raise ValueError("invalid managed worktree kind or name")
89
+ if kind == "bound":
90
+ return _workspace(primary, pin) / kind / name
83
91
  legacy = (primary.parent / f".{primary.name}-gsd-path-integrate-{name}"
84
92
  if kind == "integrate" else primary.parent / f"{primary.name}.gsd-path" / kind / name)
85
93
  branch = f"refs/heads/gsd-path-{kind}/{name}"
86
94
  records = _git(primary, "worktree", "list", "--porcelain", "-z").split("\0\0")
87
95
  for record in records:
88
96
  fields = record.split("\0")
89
- if f"worktree {legacy}" in fields and f"branch {branch}" in fields:
97
+ # Compare as paths: git prints forward slashes on Windows.
98
+ worktrees = [Path(field[len("worktree "):]) for field in fields if field.startswith("worktree ")]
99
+ if legacy in worktrees and f"branch {branch}" in fields:
90
100
  return legacy
91
101
  # Keep collision checks and missing-directory recovery at the old location.
92
102
  if os.path.lexists(legacy):
@@ -3,7 +3,8 @@ name: gsd-path-inspect
3
3
  description: Inspect an existing codebase and its documentation to establish brownfield ground truth before intent is defined. Use only when the user explicitly invokes $gsd-path-inspect or an active $gsd-path router explicitly routes to this phase.
4
4
  ---
5
5
 
6
- Before executing project helpers, read [runtime selection](references/runtime-selection.md).
6
+ Before executing project helpers, read [runtime selection](references/runtime-selection.md)
7
+ and [operating rules](references/operating-rules.md).
7
8
 
8
9
  # GSD Path Inspect Phase
9
10
 
@@ -112,15 +113,15 @@ Preparation never changes phase state; neither command dispatches agents.
112
113
  includes its path and revision for project commands; expected new pipeline
113
114
  artifacts do not make product code dirty. Each agent writes only its
114
115
  assigned output under that sidecar and keeps it there for the gates in step
115
- 3. Otherwise no
116
+ 3; its `Repo root` header still names the absolute primary. Otherwise no
116
117
  project command may run. The docs-auditor brief carries current HEAD as the
117
118
  audit baseline only when its verify sidecar was created at HEAD; otherwise
118
119
  it carries `none`. The auditor writes that baseline as `Audited HEAD`.
119
120
  3. Gate both artifacts against their templates: the codebase evidence needs
120
121
  a filled `## Map` plus findings as observed — no quota, but an empty
121
122
  findings section must say why; the docs audit must pass the bundled
122
- `python3 <absolute check_docs_audit.py> --repo <docs sidecar> --audit
123
- <track-relative DOCS-AUDIT.md> --inventory <frozen inventory file>`, where
123
+ `python3 <absolute check_docs_audit.py> --repo <docs sidecar> --primary
124
+ <absolute primary> --audit <track-relative DOCS-AUDIT.md> --inventory <frozen inventory file>`, where
124
125
  the audit path is `.project/research/DOCS-AUDIT.md` normally and
125
126
  `.project/next/research/DOCS-AUDIT.md` in Lookahead mode; add
126
127
  `--prior-audit <temporary prior-audit file>` when one was preserved and
@@ -10,7 +10,8 @@ change nothing outside your single output file.
10
10
  - Read AGENTS.md and the template before scanning. Stop on a missing path.
11
11
  - Write only the assigned output using the template. When the brief supplies a
12
12
  disposable root, write the output under that root at the relative handoff
13
- path; the orchestrator transfers it after validation. Do not ask the user
13
+ path; the orchestrator transfers it after validation. `Repo root` still names
14
+ the primary repo root, never the disposable root. Do not ask the user
14
15
  questions.
15
16
 
16
17
  ## What to establish
@@ -11,7 +11,8 @@ actually does. Read-only: change nothing outside your single output file.
11
11
  - Read AGENTS.md and the template before auditing. Stop on a missing path.
12
12
  - Write only the assigned output using the template. When the brief supplies a
13
13
  disposable root, write the output under that root at the relative handoff
14
- path; the orchestrator transfers it after validation. Do not ask the user
14
+ path; the orchestrator transfers it after validation. `Repo root` still names
15
+ the primary repo root, never the disposable root. Do not ask the user
15
16
  questions.
16
17
 
17
18
  ## Method