@opengsd/gsd-path 1.5.0 → 1.6.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 (352) hide show
  1. package/CHANGELOG.md +138 -0
  2. package/DOCS.md +4 -3
  3. package/FULL.md +64 -4
  4. package/HOOKS.md +63 -2
  5. package/MIGRATE.md +12 -0
  6. package/QUICK.md +4 -2
  7. package/README.md +67 -15
  8. package/RUNTIME.md +23 -5
  9. package/UPDATE.md +35 -0
  10. package/WORKFLOW.md +58 -3
  11. package/package.json +1 -1
  12. package/scripts/_common.py +107 -1
  13. package/scripts/build_recovery.py +62 -30
  14. package/scripts/build_state.py +195 -5
  15. package/scripts/check_handoffs.py +92 -30
  16. package/scripts/check_task_briefs.py +19 -14
  17. package/scripts/detect_project.py +17 -2
  18. package/scripts/discussion_records.py +9 -1
  19. package/scripts/discussion_validate.py +7 -6
  20. package/scripts/dispatch_driver.py +157 -31
  21. package/scripts/git_guard.py +24 -5
  22. package/scripts/guard_hook.py +1216 -47
  23. package/scripts/install.mjs +76 -3
  24. package/scripts/install.py +182 -37
  25. package/scripts/integration.py +98 -64
  26. package/scripts/isolation.py +148 -11
  27. package/scripts/members.py +68 -25
  28. package/scripts/migrate_core.py +2 -0
  29. package/scripts/model_policy.py +5 -1
  30. package/scripts/pipeline_diagnose.py +17 -2
  31. package/scripts/pipeline_git.py +68 -30
  32. package/scripts/pipeline_state.py +28 -6
  33. package/scripts/pipeline_undo.py +17 -8
  34. package/scripts/promote_lookahead.py +3 -3
  35. package/scripts/review_findings.py +180 -44
  36. package/scripts/roadmap.py +9 -1
  37. package/scripts/runtime_store.py +1 -0
  38. package/scripts/state_checkpoint.py +30 -9
  39. package/scripts/state_promote.py +15 -4
  40. package/scripts/task_context.py +2 -0
  41. package/scripts/workflow_run.py +9 -2
  42. package/skills/gsd-path/DEFINE.md +6 -2
  43. package/skills/gsd-path/PLAN.md +3 -0
  44. package/skills/gsd-path/ROADMAP.md +16 -6
  45. package/skills/gsd-path/SHIP.md +26 -4
  46. package/skills/gsd-path/SKILL.md +52 -24
  47. package/skills/gsd-path/references/build-native.md +96 -9
  48. package/skills/gsd-path/references/build-recovery.md +13 -0
  49. package/skills/gsd-path/references/coder.md +7 -3
  50. package/skills/gsd-path/references/operating-rules.md +11 -3
  51. package/skills/gsd-path/references/planner.md +13 -1
  52. package/skills/gsd-path/references/reviewer-final.md +5 -5
  53. package/skills/gsd-path/references/reviewer-wave.md +46 -13
  54. package/skills/gsd-path/references/runtime-selection.md +9 -0
  55. package/skills/gsd-path/scripts/_common.py +107 -1
  56. package/skills/gsd-path/scripts/build_recovery.py +62 -30
  57. package/skills/gsd-path/scripts/build_state.py +195 -5
  58. package/skills/gsd-path/scripts/check_handoffs.py +92 -30
  59. package/skills/gsd-path/scripts/check_task_briefs.py +19 -14
  60. package/skills/gsd-path/scripts/detect_project.py +17 -2
  61. package/skills/gsd-path/scripts/discussion_records.py +9 -1
  62. package/skills/gsd-path/scripts/discussion_validate.py +7 -6
  63. package/skills/gsd-path/scripts/dispatch_driver.py +157 -31
  64. package/skills/gsd-path/scripts/git_guard.py +24 -5
  65. package/skills/gsd-path/scripts/integration.py +98 -64
  66. package/skills/gsd-path/scripts/isolation.py +148 -11
  67. package/skills/gsd-path/scripts/members.py +68 -25
  68. package/skills/gsd-path/scripts/model_policy.py +5 -1
  69. package/skills/gsd-path/scripts/pipeline_git.py +68 -30
  70. package/skills/gsd-path/scripts/pipeline_state.py +28 -6
  71. package/skills/gsd-path/scripts/promote_lookahead.py +3 -3
  72. package/skills/gsd-path/scripts/review_findings.py +180 -44
  73. package/skills/gsd-path/scripts/roadmap.py +9 -1
  74. package/skills/gsd-path/scripts/state_checkpoint.py +30 -9
  75. package/skills/gsd-path/scripts/state_promote.py +15 -4
  76. package/skills/gsd-path/scripts/task_context.py +2 -0
  77. package/skills/gsd-path/scripts/workflow_run.py +9 -2
  78. package/skills/gsd-path/templates/final-review.md +5 -5
  79. package/skills/gsd-path/templates/state.md +1 -0
  80. package/skills/gsd-path/templates/task.md +1 -0
  81. package/skills/gsd-path/templates/wave-review.md +18 -9
  82. package/skills/gsd-path-build/references/build-native.md +96 -9
  83. package/skills/gsd-path-build/references/build-recovery.md +13 -0
  84. package/skills/gsd-path-build/references/coder.md +7 -3
  85. package/skills/gsd-path-build/references/operating-rules.md +11 -3
  86. package/skills/gsd-path-build/references/reviewer-final.md +5 -5
  87. package/skills/gsd-path-build/references/reviewer-wave.md +46 -13
  88. package/skills/gsd-path-build/references/runtime-selection.md +9 -0
  89. package/skills/gsd-path-build/scripts/_common.py +107 -1
  90. package/skills/gsd-path-build/scripts/build_recovery.py +62 -30
  91. package/skills/gsd-path-build/scripts/build_state.py +195 -5
  92. package/skills/gsd-path-build/scripts/check_handoffs.py +92 -30
  93. package/skills/gsd-path-build/scripts/check_task_briefs.py +19 -14
  94. package/skills/gsd-path-build/scripts/detect_project.py +17 -2
  95. package/skills/gsd-path-build/scripts/discussion_records.py +9 -1
  96. package/skills/gsd-path-build/scripts/discussion_validate.py +7 -6
  97. package/skills/gsd-path-build/scripts/dispatch_driver.py +157 -31
  98. package/skills/gsd-path-build/scripts/integration.py +98 -64
  99. package/skills/gsd-path-build/scripts/isolation.py +148 -11
  100. package/skills/gsd-path-build/scripts/members.py +68 -25
  101. package/skills/gsd-path-build/scripts/model_policy.py +5 -1
  102. package/skills/gsd-path-build/scripts/pipeline_git.py +68 -30
  103. package/skills/gsd-path-build/scripts/pipeline_state.py +28 -6
  104. package/skills/gsd-path-build/scripts/promote_lookahead.py +3 -3
  105. package/skills/gsd-path-build/scripts/review_findings.py +180 -44
  106. package/skills/gsd-path-build/scripts/roadmap.py +9 -1
  107. package/skills/gsd-path-build/scripts/state_checkpoint.py +30 -9
  108. package/skills/gsd-path-build/scripts/state_promote.py +15 -4
  109. package/skills/gsd-path-build/scripts/task_context.py +2 -0
  110. package/skills/gsd-path-build/scripts/workflow_run.py +9 -2
  111. package/skills/gsd-path-build/templates/task.md +1 -0
  112. package/skills/gsd-path-build/templates/wave-review.md +18 -9
  113. package/skills/gsd-path-decide/references/operating-rules.md +11 -3
  114. package/skills/gsd-path-decide/references/runtime-selection.md +9 -0
  115. package/skills/gsd-path-decide/scripts/_common.py +107 -1
  116. package/skills/gsd-path-decide/scripts/build_recovery.py +62 -30
  117. package/skills/gsd-path-decide/scripts/check_handoffs.py +92 -30
  118. package/skills/gsd-path-decide/scripts/check_task_briefs.py +19 -14
  119. package/skills/gsd-path-decide/scripts/detect_project.py +17 -2
  120. package/skills/gsd-path-decide/scripts/discussion_records.py +9 -1
  121. package/skills/gsd-path-decide/scripts/discussion_validate.py +7 -6
  122. package/skills/gsd-path-decide/scripts/integration.py +98 -64
  123. package/skills/gsd-path-decide/scripts/isolation.py +148 -11
  124. package/skills/gsd-path-decide/scripts/members.py +68 -25
  125. package/skills/gsd-path-decide/scripts/model_policy.py +5 -1
  126. package/skills/gsd-path-decide/scripts/pipeline_git.py +68 -30
  127. package/skills/gsd-path-decide/scripts/pipeline_state.py +28 -6
  128. package/skills/gsd-path-decide/scripts/promote_lookahead.py +3 -3
  129. package/skills/gsd-path-decide/scripts/roadmap.py +9 -1
  130. package/skills/gsd-path-decide/scripts/state_checkpoint.py +30 -9
  131. package/skills/gsd-path-decide/scripts/state_promote.py +15 -4
  132. package/skills/gsd-path-define/SKILL.md +6 -2
  133. package/skills/gsd-path-define/references/build-recovery.md +13 -0
  134. package/skills/gsd-path-define/references/operating-rules.md +11 -3
  135. package/skills/gsd-path-define/references/runtime-selection.md +9 -0
  136. package/skills/gsd-path-define/scripts/_common.py +107 -1
  137. package/skills/gsd-path-define/scripts/build_recovery.py +62 -30
  138. package/skills/gsd-path-define/scripts/check_handoffs.py +92 -30
  139. package/skills/gsd-path-define/scripts/check_task_briefs.py +19 -14
  140. package/skills/gsd-path-define/scripts/detect_project.py +17 -2
  141. package/skills/gsd-path-define/scripts/discussion_records.py +9 -1
  142. package/skills/gsd-path-define/scripts/discussion_validate.py +7 -6
  143. package/skills/gsd-path-define/scripts/integration.py +98 -64
  144. package/skills/gsd-path-define/scripts/isolation.py +148 -11
  145. package/skills/gsd-path-define/scripts/members.py +68 -25
  146. package/skills/gsd-path-define/scripts/model_policy.py +5 -1
  147. package/skills/gsd-path-define/scripts/pipeline_git.py +68 -30
  148. package/skills/gsd-path-define/scripts/pipeline_state.py +28 -6
  149. package/skills/gsd-path-define/scripts/promote_lookahead.py +3 -3
  150. package/skills/gsd-path-define/scripts/roadmap.py +9 -1
  151. package/skills/gsd-path-define/scripts/state_checkpoint.py +30 -9
  152. package/skills/gsd-path-define/scripts/state_promote.py +15 -4
  153. package/skills/gsd-path-define/templates/state.md +1 -0
  154. package/skills/gsd-path-discuss/references/operating-rules.md +11 -3
  155. package/skills/gsd-path-discuss/references/runtime-selection.md +9 -0
  156. package/skills/gsd-path-discuss/scripts/_common.py +107 -1
  157. package/skills/gsd-path-discuss/scripts/discussion_records.py +9 -1
  158. package/skills/gsd-path-discuss/scripts/model_policy.py +5 -1
  159. package/skills/gsd-path-docs-audit/references/operating-rules.md +11 -3
  160. package/skills/gsd-path-docs-audit/references/runtime-selection.md +9 -0
  161. package/skills/gsd-path-docs-audit/scripts/_common.py +107 -1
  162. package/skills/gsd-path-docs-audit/scripts/build_recovery.py +62 -30
  163. package/skills/gsd-path-docs-audit/scripts/check_handoffs.py +92 -30
  164. package/skills/gsd-path-docs-audit/scripts/check_task_briefs.py +19 -14
  165. package/skills/gsd-path-docs-audit/scripts/detect_project.py +17 -2
  166. package/skills/gsd-path-docs-audit/scripts/discussion_records.py +9 -1
  167. package/skills/gsd-path-docs-audit/scripts/discussion_validate.py +7 -6
  168. package/skills/gsd-path-docs-audit/scripts/integration.py +98 -64
  169. package/skills/gsd-path-docs-audit/scripts/isolation.py +148 -11
  170. package/skills/gsd-path-docs-audit/scripts/members.py +68 -25
  171. package/skills/gsd-path-docs-audit/scripts/model_policy.py +5 -1
  172. package/skills/gsd-path-docs-audit/scripts/pipeline_git.py +68 -30
  173. package/skills/gsd-path-docs-audit/scripts/pipeline_state.py +28 -6
  174. package/skills/gsd-path-docs-audit/scripts/promote_lookahead.py +3 -3
  175. package/skills/gsd-path-docs-audit/scripts/roadmap.py +9 -1
  176. package/skills/gsd-path-docs-audit/scripts/state_checkpoint.py +30 -9
  177. package/skills/gsd-path-docs-audit/scripts/state_promote.py +15 -4
  178. package/skills/gsd-path-forensics/references/operating-rules.md +11 -3
  179. package/skills/gsd-path-forensics/references/runtime-selection.md +9 -0
  180. package/skills/gsd-path-forensics/scripts/_common.py +107 -1
  181. package/skills/gsd-path-forensics/scripts/discussion_records.py +9 -1
  182. package/skills/gsd-path-forensics/scripts/model_policy.py +5 -1
  183. package/skills/gsd-path-forensics/scripts/pipeline_diagnose.py +17 -2
  184. package/skills/gsd-path-forensics/scripts/pipeline_undo.py +17 -8
  185. package/skills/gsd-path-inspect/references/operating-rules.md +11 -3
  186. package/skills/gsd-path-inspect/references/runtime-selection.md +9 -0
  187. package/skills/gsd-path-inspect/scripts/_common.py +107 -1
  188. package/skills/gsd-path-inspect/scripts/build_recovery.py +62 -30
  189. package/skills/gsd-path-inspect/scripts/check_handoffs.py +92 -30
  190. package/skills/gsd-path-inspect/scripts/check_task_briefs.py +19 -14
  191. package/skills/gsd-path-inspect/scripts/detect_project.py +17 -2
  192. package/skills/gsd-path-inspect/scripts/discussion_records.py +9 -1
  193. package/skills/gsd-path-inspect/scripts/discussion_validate.py +7 -6
  194. package/skills/gsd-path-inspect/scripts/integration.py +98 -64
  195. package/skills/gsd-path-inspect/scripts/isolation.py +148 -11
  196. package/skills/gsd-path-inspect/scripts/members.py +68 -25
  197. package/skills/gsd-path-inspect/scripts/model_policy.py +5 -1
  198. package/skills/gsd-path-inspect/scripts/pipeline_git.py +68 -30
  199. package/skills/gsd-path-inspect/scripts/pipeline_state.py +28 -6
  200. package/skills/gsd-path-inspect/scripts/promote_lookahead.py +3 -3
  201. package/skills/gsd-path-inspect/scripts/roadmap.py +9 -1
  202. package/skills/gsd-path-inspect/scripts/state_checkpoint.py +30 -9
  203. package/skills/gsd-path-inspect/scripts/state_promote.py +15 -4
  204. package/skills/gsd-path-inspect/scripts/workflow_run.py +9 -2
  205. package/skills/gsd-path-inspect/templates/state.md +1 -0
  206. package/skills/gsd-path-loop/references/operating-rules.md +11 -3
  207. package/skills/gsd-path-loop/references/runtime-selection.md +9 -0
  208. package/skills/gsd-path-loop/scripts/_common.py +107 -1
  209. package/skills/gsd-path-loop/scripts/discussion_records.py +9 -1
  210. package/skills/gsd-path-loop/scripts/model_policy.py +5 -1
  211. package/skills/gsd-path-migrate/SKILL.md +8 -0
  212. package/skills/gsd-path-migrate/references/operating-rules.md +11 -3
  213. package/skills/gsd-path-migrate/references/runtime-selection.md +9 -0
  214. package/skills/gsd-path-migrate/scripts/_common.py +107 -1
  215. package/skills/gsd-path-migrate/scripts/discussion_records.py +9 -1
  216. package/skills/gsd-path-migrate/scripts/migrate_core.py +2 -0
  217. package/skills/gsd-path-migrate/scripts/model_policy.py +5 -1
  218. package/skills/gsd-path-plan/SKILL.md +3 -0
  219. package/skills/gsd-path-plan/references/build-recovery.md +13 -0
  220. package/skills/gsd-path-plan/references/operating-rules.md +11 -3
  221. package/skills/gsd-path-plan/references/planner.md +13 -1
  222. package/skills/gsd-path-plan/references/runtime-selection.md +9 -0
  223. package/skills/gsd-path-plan/scripts/_common.py +107 -1
  224. package/skills/gsd-path-plan/scripts/build_recovery.py +62 -30
  225. package/skills/gsd-path-plan/scripts/check_handoffs.py +92 -30
  226. package/skills/gsd-path-plan/scripts/check_task_briefs.py +19 -14
  227. package/skills/gsd-path-plan/scripts/detect_project.py +17 -2
  228. package/skills/gsd-path-plan/scripts/discussion_records.py +9 -1
  229. package/skills/gsd-path-plan/scripts/discussion_validate.py +7 -6
  230. package/skills/gsd-path-plan/scripts/integration.py +98 -64
  231. package/skills/gsd-path-plan/scripts/isolation.py +148 -11
  232. package/skills/gsd-path-plan/scripts/members.py +68 -25
  233. package/skills/gsd-path-plan/scripts/model_policy.py +5 -1
  234. package/skills/gsd-path-plan/scripts/pipeline_git.py +68 -30
  235. package/skills/gsd-path-plan/scripts/pipeline_state.py +28 -6
  236. package/skills/gsd-path-plan/scripts/promote_lookahead.py +3 -3
  237. package/skills/gsd-path-plan/scripts/roadmap.py +9 -1
  238. package/skills/gsd-path-plan/scripts/state_checkpoint.py +30 -9
  239. package/skills/gsd-path-plan/scripts/state_promote.py +15 -4
  240. package/skills/gsd-path-plan/scripts/workflow_run.py +9 -2
  241. package/skills/gsd-path-plan/templates/task.md +1 -0
  242. package/skills/gsd-path-research/references/operating-rules.md +11 -3
  243. package/skills/gsd-path-research/references/runtime-selection.md +9 -0
  244. package/skills/gsd-path-research/scripts/_common.py +107 -1
  245. package/skills/gsd-path-research/scripts/build_recovery.py +62 -30
  246. package/skills/gsd-path-research/scripts/check_handoffs.py +92 -30
  247. package/skills/gsd-path-research/scripts/check_task_briefs.py +19 -14
  248. package/skills/gsd-path-research/scripts/detect_project.py +17 -2
  249. package/skills/gsd-path-research/scripts/discussion_records.py +9 -1
  250. package/skills/gsd-path-research/scripts/discussion_validate.py +7 -6
  251. package/skills/gsd-path-research/scripts/integration.py +98 -64
  252. package/skills/gsd-path-research/scripts/isolation.py +148 -11
  253. package/skills/gsd-path-research/scripts/members.py +68 -25
  254. package/skills/gsd-path-research/scripts/model_policy.py +5 -1
  255. package/skills/gsd-path-research/scripts/pipeline_git.py +68 -30
  256. package/skills/gsd-path-research/scripts/pipeline_state.py +28 -6
  257. package/skills/gsd-path-research/scripts/promote_lookahead.py +3 -3
  258. package/skills/gsd-path-research/scripts/roadmap.py +9 -1
  259. package/skills/gsd-path-research/scripts/state_checkpoint.py +30 -9
  260. package/skills/gsd-path-research/scripts/state_promote.py +15 -4
  261. package/skills/gsd-path-roadmap/SKILL.md +16 -6
  262. package/skills/gsd-path-roadmap/references/operating-rules.md +11 -3
  263. package/skills/gsd-path-roadmap/references/runtime-selection.md +9 -0
  264. package/skills/gsd-path-roadmap/scripts/_common.py +107 -1
  265. package/skills/gsd-path-roadmap/scripts/build_recovery.py +62 -30
  266. package/skills/gsd-path-roadmap/scripts/check_handoffs.py +92 -30
  267. package/skills/gsd-path-roadmap/scripts/check_task_briefs.py +19 -14
  268. package/skills/gsd-path-roadmap/scripts/detect_project.py +17 -2
  269. package/skills/gsd-path-roadmap/scripts/discussion_records.py +9 -1
  270. package/skills/gsd-path-roadmap/scripts/discussion_validate.py +7 -6
  271. package/skills/gsd-path-roadmap/scripts/integration.py +98 -64
  272. package/skills/gsd-path-roadmap/scripts/isolation.py +148 -11
  273. package/skills/gsd-path-roadmap/scripts/members.py +68 -25
  274. package/skills/gsd-path-roadmap/scripts/model_policy.py +5 -1
  275. package/skills/gsd-path-roadmap/scripts/pipeline_git.py +68 -30
  276. package/skills/gsd-path-roadmap/scripts/pipeline_state.py +28 -6
  277. package/skills/gsd-path-roadmap/scripts/promote_lookahead.py +3 -3
  278. package/skills/gsd-path-roadmap/scripts/roadmap.py +9 -1
  279. package/skills/gsd-path-roadmap/scripts/state_checkpoint.py +30 -9
  280. package/skills/gsd-path-roadmap/scripts/state_promote.py +15 -4
  281. package/skills/gsd-path-ship/SKILL.md +26 -4
  282. package/skills/gsd-path-ship/references/operating-rules.md +11 -3
  283. package/skills/gsd-path-ship/references/reviewer-final.md +5 -5
  284. package/skills/gsd-path-ship/references/reviewer-wave.md +46 -13
  285. package/skills/gsd-path-ship/references/runtime-selection.md +9 -0
  286. package/skills/gsd-path-ship/scripts/_common.py +107 -1
  287. package/skills/gsd-path-ship/scripts/build_recovery.py +62 -30
  288. package/skills/gsd-path-ship/scripts/build_state.py +195 -5
  289. package/skills/gsd-path-ship/scripts/check_handoffs.py +92 -30
  290. package/skills/gsd-path-ship/scripts/check_task_briefs.py +19 -14
  291. package/skills/gsd-path-ship/scripts/detect_project.py +17 -2
  292. package/skills/gsd-path-ship/scripts/discussion_records.py +9 -1
  293. package/skills/gsd-path-ship/scripts/discussion_validate.py +7 -6
  294. package/skills/gsd-path-ship/scripts/integration.py +98 -64
  295. package/skills/gsd-path-ship/scripts/isolation.py +148 -11
  296. package/skills/gsd-path-ship/scripts/members.py +68 -25
  297. package/skills/gsd-path-ship/scripts/model_policy.py +5 -1
  298. package/skills/gsd-path-ship/scripts/pipeline_git.py +68 -30
  299. package/skills/gsd-path-ship/scripts/pipeline_state.py +28 -6
  300. package/skills/gsd-path-ship/scripts/promote_lookahead.py +3 -3
  301. package/skills/gsd-path-ship/scripts/roadmap.py +9 -1
  302. package/skills/gsd-path-ship/scripts/state_checkpoint.py +30 -9
  303. package/skills/gsd-path-ship/scripts/state_promote.py +15 -4
  304. package/skills/gsd-path-ship/scripts/workflow_run.py +9 -2
  305. package/skills/gsd-path-ship/templates/final-review.md +5 -5
  306. package/skills/gsd-path-ship/templates/wave-review.md +18 -9
  307. package/skills/gsd-path-undo/references/operating-rules.md +11 -3
  308. package/skills/gsd-path-undo/references/runtime-selection.md +9 -0
  309. package/skills/gsd-path-undo/scripts/_common.py +107 -1
  310. package/skills/gsd-path-undo/scripts/discussion_records.py +9 -1
  311. package/skills/gsd-path-undo/scripts/model_policy.py +5 -1
  312. package/skills/gsd-path-undo/scripts/pipeline_undo.py +17 -8
  313. package/skills/path/DEFINE.md +6 -2
  314. package/skills/path/PLAN.md +3 -0
  315. package/skills/path/ROADMAP.md +16 -6
  316. package/skills/path/SHIP.md +26 -4
  317. package/skills/path/SKILL.md +52 -24
  318. package/skills/path/references/build-native.md +96 -9
  319. package/skills/path/references/build-recovery.md +13 -0
  320. package/skills/path/references/coder.md +7 -3
  321. package/skills/path/references/operating-rules.md +11 -3
  322. package/skills/path/references/planner.md +13 -1
  323. package/skills/path/references/reviewer-final.md +5 -5
  324. package/skills/path/references/reviewer-wave.md +46 -13
  325. package/skills/path/references/runtime-selection.md +9 -0
  326. package/skills/path/scripts/_common.py +107 -1
  327. package/skills/path/scripts/build_recovery.py +62 -30
  328. package/skills/path/scripts/build_state.py +195 -5
  329. package/skills/path/scripts/check_handoffs.py +92 -30
  330. package/skills/path/scripts/check_task_briefs.py +19 -14
  331. package/skills/path/scripts/detect_project.py +17 -2
  332. package/skills/path/scripts/discussion_records.py +9 -1
  333. package/skills/path/scripts/discussion_validate.py +7 -6
  334. package/skills/path/scripts/dispatch_driver.py +157 -31
  335. package/skills/path/scripts/git_guard.py +24 -5
  336. package/skills/path/scripts/integration.py +98 -64
  337. package/skills/path/scripts/isolation.py +148 -11
  338. package/skills/path/scripts/members.py +68 -25
  339. package/skills/path/scripts/model_policy.py +5 -1
  340. package/skills/path/scripts/pipeline_git.py +68 -30
  341. package/skills/path/scripts/pipeline_state.py +28 -6
  342. package/skills/path/scripts/promote_lookahead.py +3 -3
  343. package/skills/path/scripts/review_findings.py +180 -44
  344. package/skills/path/scripts/roadmap.py +9 -1
  345. package/skills/path/scripts/state_checkpoint.py +30 -9
  346. package/skills/path/scripts/state_promote.py +15 -4
  347. package/skills/path/scripts/task_context.py +2 -0
  348. package/skills/path/scripts/workflow_run.py +9 -2
  349. package/skills/path/templates/final-review.md +5 -5
  350. package/skills/path/templates/state.md +1 -0
  351. package/skills/path/templates/task.md +1 -0
  352. package/skills/path/templates/wave-review.md +18 -9
@@ -7,6 +7,7 @@ import json
7
7
  import os
8
8
  import shutil
9
9
  import sys
10
+ import traceback
10
11
 
11
12
  # Runtime helpers must not modify their immutable installation.
12
13
  sys.dont_write_bytecode = True
@@ -33,7 +34,7 @@ def _load_pipeline_modules():
33
34
  try:
34
35
  from scripts import archive_milestone, pipeline_state, _common
35
36
  return _common, archive_milestone, pipeline_state
36
- except ModuleNotFoundError as error:
37
+ except ImportError as error: # a foreign `scripts` package
37
38
  if error.name not in {
38
39
  "scripts",
39
40
  "scripts.archive_milestone",
@@ -41,6 +42,13 @@ def _load_pipeline_modules():
41
42
  "scripts._common",
42
43
  }:
43
44
  raise
45
+ # A plain ImportError raised while a `scripts` module loaded is not a
46
+ # foreign package. A missing module falls back, as before.
47
+ if not isinstance(error, ModuleNotFoundError) and any(
48
+ frame.f_globals.get("__name__", "").startswith("scripts.")
49
+ for frame, _ in traceback.walk_tb(error.__traceback__)
50
+ ):
51
+ raise
44
52
  shared_scripts = Path(__file__).resolve().parents[2] / "gsd-path" / "scripts"
45
53
  sys.path.insert(0, str(shared_scripts))
46
54
  import archive_milestone
@@ -507,7 +507,8 @@ def archived_intent_criteria(archive: Path) -> dict[int, str]:
507
507
  criteria = check_handoffs._success_criteria(text)
508
508
  except check_handoffs.HandoffError as error:
509
509
  raise ArchiveError(str(error)) from error
510
- return {int(key[2:]): " ".join(value.split()) for key, value in criteria.items()}
510
+ # Each value keeps the form without sub-bullet markers that quotes_criterion reads.
511
+ return {int(key[2:]): value for key, value in criteria.items()}
511
512
 
512
513
 
513
514
  def parse_final_review(archive: Path) -> tuple:
@@ -563,7 +564,7 @@ def _final_review(archive: Path) -> tuple:
563
564
  if len(headings) != len(intent_criteria):
564
565
  raise ArchiveError("FINAL.md success criteria do not exactly cover INTENT.md")
565
566
  for _, number, criterion in headings:
566
- if " ".join(criterion.split()) != intent_criteria[number]:
567
+ if not _common.quotes_criterion(criterion, intent_criteria[number]):
567
568
  raise ArchiveError(
568
569
  f"FINAL.md SC{number} heading text differs from archived INTENT.md"
569
570
  )
@@ -951,10 +952,10 @@ def validate_wave_review(
951
952
  (index, match.group(1), " ".join(match.group(2).split()), match.group(3))
952
953
  )
953
954
  actual = [(sc_id, text) for _, sc_id, text, _ in criterion_headings]
954
- normalized_expected_criteria = [
955
- (sc_id, " ".join(text.split())) for sc_id, text in expected_criteria
956
- ]
957
- if actual != normalized_expected_criteria:
955
+ if len(actual) != len(expected_criteria) or any(
956
+ sc_id != expected_id or not _common.quotes_criterion(text, expected)
957
+ for (sc_id, text), (expected_id, expected) in zip(actual, expected_criteria)
958
+ ):
958
959
  raise ArchiveError(
959
960
  f"{path.name} Intent coverage does not match its owned success criteria"
960
961
  )
@@ -301,7 +301,9 @@ def discard_unpublished_stale_integration(
301
301
  project, "merge-base", "--is-ancestor", merge_commit, remote_default_sha
302
302
  )
303
303
  if published.returncode == 0:
304
- raise ArchiveError("stale integration merge is already published on origin/main")
304
+ raise ArchiveError(
305
+ f"stale integration merge is already published on origin/{default_name}"
306
+ )
305
307
  if published.returncode != 1:
306
308
  archive_milestone.require_git_success(published, "inspect stale integration publication")
307
309
 
@@ -659,9 +661,10 @@ def require_pull_request_identity(
659
661
  pull: dict,
660
662
  branch: str,
661
663
  ship_commit: str,
664
+ base: str = "main",
662
665
  ) -> None:
663
- if pull["base"].get("ref") != "main":
664
- raise ArchiveError("GitHub pull request base is not main")
666
+ if pull["base"].get("ref") != base:
667
+ raise ArchiveError(f"GitHub pull request base is not {base}")
665
668
  if pull["head"].get("ref") != branch:
666
669
  raise ArchiveError("GitHub pull request head is not the bound branch")
667
670
  if pull["head"].get("sha") != ship_commit:
@@ -670,7 +673,9 @@ def require_pull_request_identity(
670
673
  raise ArchiveError("GitHub pull request head repository is not origin")
671
674
 
672
675
 
673
- def find_pull_request(repository: str, branch: str, ship_commit: str) -> Optional[dict]:
676
+ def find_pull_request(
677
+ repository: str, branch: str, ship_commit: str, base: str = "main"
678
+ ) -> Optional[dict]:
674
679
  pulls = require_pull_request_pages(
675
680
  github_api_json(
676
681
  f"repos/{repository}/pulls",
@@ -679,7 +684,7 @@ def find_pull_request(repository: str, branch: str, ship_commit: str) -> Optiona
679
684
  "-f",
680
685
  "state=all",
681
686
  "-f",
682
- "base=main",
687
+ f"base={base}",
683
688
  "--paginate",
684
689
  "--slurp",
685
690
  )
@@ -687,7 +692,7 @@ def find_pull_request(repository: str, branch: str, ship_commit: str) -> Optiona
687
692
  pulls = [
688
693
  pull
689
694
  for pull in pulls
690
- if pull["base"].get("ref") == "main"
695
+ if pull["base"].get("ref") == base
691
696
  and (
692
697
  pull["head"].get("sha") == ship_commit
693
698
  or (
@@ -697,17 +702,19 @@ def find_pull_request(repository: str, branch: str, ship_commit: str) -> Optiona
697
702
  )
698
703
  ]
699
704
  if len(pulls) > 1:
700
- raise ArchiveError("multiple pull requests target main from the ship commit")
705
+ raise ArchiveError(f"multiple pull requests target {base} from the ship commit")
701
706
  if not pulls:
702
707
  return None
703
708
  pull = pulls[0]
704
- require_pull_request_identity(repository, pull, branch, ship_commit)
709
+ require_pull_request_identity(repository, pull, branch, ship_commit, base)
705
710
  return pull
706
711
 
707
712
 
708
- def pull_request_body(archive_path: str, ship_commit: str, branch: str) -> str:
713
+ def pull_request_body(
714
+ archive_path: str, ship_commit: str, branch: str, base: str = "main"
715
+ ) -> str:
709
716
  return (
710
- f"{integrate_commit_body(archive_path, ship_commit, 'main', branch)}"
717
+ f"{integrate_commit_body(archive_path, ship_commit, base, branch)}"
711
718
  f"\n\n---\n{PR_CREDIT_LINE}"
712
719
  )
713
720
 
@@ -719,8 +726,12 @@ def update_pull_request_body(
719
726
  ship_commit: str,
720
727
  branch: str,
721
728
  expected_body: Optional[str] = None,
729
+ base: str = "main",
722
730
  ) -> dict:
723
- expected = expected_body if expected_body is not None else pull_request_body(archive_path, ship_commit, branch)
731
+ expected = (
732
+ expected_body if expected_body is not None
733
+ else pull_request_body(archive_path, ship_commit, branch, base)
734
+ )
724
735
  current = pull.get("body")
725
736
  if isinstance(current, str) and current.rstrip().endswith(PR_CREDIT_LINE):
726
737
  return pull
@@ -732,7 +743,7 @@ def update_pull_request_body(
732
743
  f"body={expected}",
733
744
  )
734
745
  updated = require_pull_request_shape(response)
735
- require_pull_request_identity(repository, updated, branch, ship_commit)
746
+ require_pull_request_identity(repository, updated, branch, ship_commit, base)
736
747
  if updated.get("body") != expected:
737
748
  raise ArchiveError("updated GitHub pull request is missing the credit footer")
738
749
  return updated
@@ -744,23 +755,24 @@ def create_pull_request(
744
755
  archive_path: str,
745
756
  archive_name: str,
746
757
  ship_commit: str,
758
+ base: str = "main",
747
759
  ) -> dict:
748
- body = pull_request_body(archive_path, ship_commit, branch)
760
+ body = pull_request_body(archive_path, ship_commit, branch, base)
749
761
  response = github_api_json(
750
762
  f"repos/{repository}/pulls",
751
763
  "--method",
752
764
  "POST",
753
765
  "-f",
754
- f"title={integrate_subject(archive_name, 'main')}",
766
+ f"title={integrate_subject(archive_name, base)}",
755
767
  "-f",
756
768
  f"head={branch}",
757
769
  "-f",
758
- "base=main",
770
+ f"base={base}",
759
771
  "-f",
760
772
  f"body={body}",
761
773
  )
762
774
  pull = require_pull_request_shape(response)
763
- require_pull_request_identity(repository, pull, branch, ship_commit)
775
+ require_pull_request_identity(repository, pull, branch, ship_commit, base)
764
776
  return pull
765
777
 
766
778
 
@@ -850,7 +862,9 @@ def require_pull_request_merge(
850
862
  "inspect remote-default first-parent history",
851
863
  ).splitlines()
852
864
  if merge_commit not in first_parent:
853
- raise ArchiveError("pull-request merge is not on origin/main first-parent history")
865
+ raise ArchiveError(
866
+ f"pull-request merge is not on {remote_default} first-parent history"
867
+ )
854
868
 
855
869
 
856
870
  def require_pull_request_merge_provenance(
@@ -967,7 +981,8 @@ def integrate_pull_request(
967
981
  raise ArchiveError("pull-request integration requires a bound branch")
968
982
  require_github_authentication()
969
983
  repository = github_repository(project)
970
- pull = find_pull_request(repository, branch, ship_commit)
984
+ base = state.default_branch
985
+ pull = find_pull_request(repository, branch, ship_commit, base)
971
986
  if pull is None:
972
987
  publish_bound_branch(project, branch, ship_commit)
973
988
  pull = create_pull_request(
@@ -976,6 +991,7 @@ def integrate_pull_request(
976
991
  archive_path,
977
992
  archive_name,
978
993
  ship_commit,
994
+ base,
979
995
  )
980
996
  elif pull["merged_at"] is None:
981
997
  if pull["state"] != "open":
@@ -986,6 +1002,7 @@ def integrate_pull_request(
986
1002
  archive_path,
987
1003
  ship_commit,
988
1004
  branch,
1005
+ base=base,
989
1006
  )
990
1007
  if pull["merged_at"] is None:
991
1008
  if pull["state"] != "open":
@@ -1016,6 +1033,7 @@ def integrate_pull_request(
1016
1033
  archive_path,
1017
1034
  ship_commit,
1018
1035
  branch,
1036
+ base=base,
1019
1037
  )
1020
1038
  tag_name = f"milestone/{archive_name}"
1021
1039
  message = pull_request_tag_message(
@@ -1075,6 +1093,11 @@ def integrate_external_landing(
1075
1093
  "mode": "external-landing",
1076
1094
  "archive": archive_path,
1077
1095
  "commit": ship_commit,
1096
+ "branch": bound_branch,
1097
+ "merge_subject": integrate_subject(archive_name, default_name),
1098
+ "merge_body": integrate_commit_body(
1099
+ archive_path, ship_commit, default_name, bound_branch
1100
+ ),
1078
1101
  }
1079
1102
  if contains_ship.returncode != 0:
1080
1103
  archive_milestone.require_git_success(
@@ -1158,8 +1181,10 @@ def integrate(repo: Path, slug: str) -> dict:
1158
1181
 
1159
1182
  remote_default = refresh_origin(project)["remote_default"]
1160
1183
  default_name = default_branch_name(remote_default)
1161
- if default_name != "main":
1162
- raise ArchiveError(f"remote default must be main, got {default_name!r}")
1184
+ if default_name != state.default_branch:
1185
+ raise ArchiveError(
1186
+ f"remote default must be {state.default_branch}, got {default_name!r}"
1187
+ )
1163
1188
  if bound_branch == default_name:
1164
1189
  raise ArchiveError("bound branch must not be the remote default")
1165
1190
  remote_default_sha = archive_milestone.require_git_success(
@@ -1266,7 +1291,7 @@ def integrate(repo: Path, slug: str) -> dict:
1266
1291
  "origin",
1267
1292
  f"{merge_commit}:refs/heads/{default_name}",
1268
1293
  ),
1269
- "push integration merge to main",
1294
+ f"push integration merge to {default_name}",
1270
1295
  )
1271
1296
  archive_milestone.require_git_success(
1272
1297
  run_git(project, "update-ref", f"refs/remotes/{remote_default}", merge_commit),
@@ -1411,10 +1436,12 @@ def validate_integrated(
1411
1436
  if bound_branch == default_name:
1412
1437
  raise ArchiveError(
1413
1438
  f"bound branch {bound_branch!r} is the remote default; "
1414
- "ship merges onto main, never onto the work branch"
1439
+ "ship merges onto the default branch, never onto the work branch"
1440
+ )
1441
+ if default_name != state.default_branch:
1442
+ raise ArchiveError(
1443
+ f"remote default must be {state.default_branch}, got {default_name!r}"
1415
1444
  )
1416
- if default_name != "main":
1417
- raise ArchiveError(f"remote default must be main, got {default_name!r}")
1418
1445
 
1419
1446
  # (b) Resolve the integration proof selected before build.
1420
1447
  tag_name = f"milestone/{archive_name}"
@@ -1430,7 +1457,7 @@ def validate_integrated(
1430
1457
  pull_request = metadata["Pull-Request"]
1431
1458
  require_github_authentication()
1432
1459
  repository = github_repository(project)
1433
- pull = find_pull_request(repository, bound_branch, ship_commit)
1460
+ pull = find_pull_request(repository, bound_branch, ship_commit, default_name)
1434
1461
  if pull is None:
1435
1462
  raise ArchiveError("GitHub pull request for the ship commit is missing")
1436
1463
  if pull["html_url"] != pull_request:
@@ -1623,21 +1650,23 @@ def require_published_integration(
1623
1650
  )
1624
1651
 
1625
1652
 
1626
- def _member_names(coordinator: Path, member: str, archive_path: str) -> tuple[Path, str, str, str, str]:
1627
- """A member's checkout, coordinator project, bound branch, merge subject, and tag."""
1653
+ def _member_names(coordinator: Path, member: str, archive_path: str) -> tuple[Path, str, str, str, str, str]:
1654
+ """A member's checkout, coordinator project, bound branch, merge subject, tag,
1655
+ and the default branch that MEMBERS.md records for it."""
1628
1656
  try:
1629
1657
  import isolation
1630
1658
  except ImportError: # pragma: no cover - package import used by tests
1631
1659
  from scripts import isolation
1632
1660
  try:
1633
1661
  checkout, project = isolation.member_checkout(coordinator.resolve(), member)
1662
+ default = isolation.member_default_branch(coordinator.resolve(), member)
1634
1663
  except isolation.IsolationError as error:
1635
1664
  raise ArchiveError(str(error)) from error
1636
1665
  archive_name = PurePosixPath(archive_path).name
1637
1666
  identifier = milestone_id(milestone_number(archive_name))
1638
1667
  bound = f"gsd-path/{project}-{identifier}"
1639
- subject = f"integrate: {project} {identifier} — merge {bound} into main"
1640
- return checkout, project, bound, subject, f"milestone/{project}-{archive_name}"
1668
+ subject = f"integrate: {project} {identifier} — merge {bound} into {default}"
1669
+ return checkout, project, bound, subject, f"milestone/{project}-{archive_name}", default
1641
1670
 
1642
1671
 
1643
1672
  def _member_merge_body(archive_path: str, member: str, reviewed_head: str) -> str:
@@ -1664,16 +1693,16 @@ def member_pull_request_tag_metadata(contents: str) -> dict[str, str]:
1664
1693
  return fields
1665
1694
 
1666
1695
 
1667
- def _find_member_merge(checkout: Path, subject: str, body: str, reviewed_head: str) -> Optional[str]:
1668
- """The member merge in origin/main's first-parent history, if published."""
1696
+ def _find_member_merge(checkout: Path, subject: str, body: str, reviewed_head: str, default: str) -> Optional[str]:
1697
+ """The member merge in the first-parent history of origin/<default>, if published."""
1669
1698
  log = archive_milestone.require_git_success(
1670
- run_git(checkout, "log", "--first-parent", "--format=%H%x00%s", "origin/main"),
1671
- "inspect member origin/main first-parent history",
1699
+ run_git(checkout, "log", "--first-parent", "--format=%H%x00%s", f"origin/{default}"),
1700
+ f"inspect member origin/{default} first-parent history",
1672
1701
  )
1673
1702
  matches = [commit for commit, _, text in (line.partition("\x00") for line in log.splitlines())
1674
1703
  if text == subject]
1675
1704
  if len(matches) > 1:
1676
- raise ArchiveError(f"multiple member merges named {subject!r} on origin/main")
1705
+ raise ArchiveError(f"multiple member merges named {subject!r} on origin/{default}")
1677
1706
  if not matches:
1678
1707
  return None
1679
1708
  _require_member_merge(checkout, matches[0], subject, body, reviewed_head)
@@ -1728,7 +1757,7 @@ def _create_member_merge(checkout: Path, project: str, archive_path: str, subjec
1728
1757
  + (", ".join(conflicts) or (merged.stderr or merged.stdout).strip()))
1729
1758
  merge = archive_milestone.require_git_success(run_git(worktree, "rev-parse", "HEAD"), "resolve member merge")
1730
1759
  if _require_member_merge(worktree, merge, subject, body, reviewed_head) != origin_main:
1731
- raise ArchiveError("member merge first parent is not origin/main")
1760
+ raise ArchiveError("member merge first parent is not the origin default branch")
1732
1761
  remove_registered_worktree(checkout, branch, worktree)
1733
1762
  return merge
1734
1763
 
@@ -1755,34 +1784,39 @@ def _publish_member_bound(checkout: Path, project: str, member: str, bound: str,
1755
1784
  raise ArchiveError(f"member {member} origin/{bound} moved: {remote_bound}")
1756
1785
 
1757
1786
 
1758
- def _require_member_close(checkout: Path, member: str, bound: str, reviewed_head: str) -> None:
1787
+ def _require_member_close(checkout: Path, member: str, bound: str, reviewed_head: str, default: str) -> None:
1759
1788
  if optional_ref(checkout, f"refs/heads/{bound}") != reviewed_head:
1760
1789
  raise ArchiveError(f"member {member} {bound} is not at its reviewed HEAD {reviewed_head}")
1761
- if default_branch_name(refresh_origin(checkout)["remote_default"]) != "main":
1762
- raise ArchiveError(f"member {member} remote default must be main")
1790
+ live = default_branch_name(refresh_origin(checkout)["remote_default"])
1791
+ if live != default:
1792
+ raise ArchiveError(f"member {member} remote default must be {default}, got {live!r}")
1763
1793
 
1764
1794
 
1765
1795
  def integrate_member(coordinator: Path, member: str, archive_path: str, reviewed_head: str) -> dict:
1766
- """Direct-mode member close: publish the bound branch, merge it into main, then tag."""
1767
- checkout, project, bound, subject, tag_name = _member_names(coordinator, member, archive_path)
1796
+ """Direct-mode member close: publish the bound branch, merge it into the member
1797
+ default branch, then tag."""
1798
+ checkout, project, bound, subject, tag_name, default = _member_names(coordinator, member, archive_path)
1799
+ origin_default = f"origin/{default}"
1768
1800
  body = _member_merge_body(archive_path, member, reviewed_head)
1769
- _require_member_close(checkout, member, bound, reviewed_head)
1770
- merge = _find_member_merge(checkout, subject, body, reviewed_head)
1801
+ _require_member_close(checkout, member, bound, reviewed_head, default)
1802
+ merge = _find_member_merge(checkout, subject, body, reviewed_head, default)
1771
1803
  if merge is None:
1772
1804
  origin_main = archive_milestone.require_git_success(
1773
- run_git(checkout, "rev-parse", "origin/main"), "resolve member origin/main")
1805
+ run_git(checkout, "rev-parse", origin_default), f"resolve member {origin_default}")
1774
1806
  ancestry = run_git(checkout, "merge-base", "--is-ancestor", reviewed_head, origin_main)
1775
1807
  if ancestry.returncode == 0:
1776
- raise ArchiveError("member reviewed HEAD reached origin/main outside Path; user-approved recovery required")
1808
+ raise ArchiveError(
1809
+ f"member reviewed HEAD reached {origin_default} outside Path; user-approved recovery required")
1777
1810
  if ancestry.returncode != 1:
1778
1811
  archive_milestone.require_git_success(ancestry, "inspect member reviewed HEAD ancestry")
1779
1812
  merge = _create_member_merge(checkout, project, archive_path, subject, body, reviewed_head, origin_main)
1780
- # Publish in order: bound branch, main, tag; a rerun publishes only what is missing.
1813
+ # Publish in order: bound branch, default branch, tag; a rerun publishes only what is missing.
1781
1814
  _publish_member_bound(checkout, project, member, bound, reviewed_head)
1782
- if run_git(checkout, "merge-base", "--is-ancestor", merge, "origin/main").returncode != 0:
1783
- _push_member_ref(checkout, project, merge, "refs/heads/main", merge, None)
1815
+ if run_git(checkout, "merge-base", "--is-ancestor", merge, origin_default).returncode != 0:
1816
+ _push_member_ref(checkout, project, merge, f"refs/heads/{default}", merge, None)
1784
1817
  archive_milestone.require_git_success(
1785
- run_git(checkout, "update-ref", "refs/remotes/origin/main", merge), "refresh member origin/main")
1818
+ run_git(checkout, "update-ref", f"refs/remotes/{origin_default}", merge),
1819
+ f"refresh member {origin_default}")
1786
1820
  tag_object, tag_published = ensure_integration_tag(checkout, tag_name, merge)
1787
1821
  if not tag_published:
1788
1822
  _push_member_ref(checkout, project, f"refs/tags/{tag_name}", f"refs/tags/{tag_name}", tag_object, None)
@@ -1796,12 +1830,12 @@ def integrate_member(coordinator: Path, member: str, archive_path: str, reviewed
1796
1830
 
1797
1831
  def integrate_member_pull_request(coordinator: Path, member: str, archive_path: str, reviewed_head: str) -> dict:
1798
1832
  """Pull-request member close: open one PR for the bound branch; after a human merge, tag it."""
1799
- checkout, project, bound, subject, tag_name = _member_names(coordinator, member, archive_path)
1833
+ checkout, project, bound, subject, tag_name, default = _member_names(coordinator, member, archive_path)
1800
1834
  body = _member_merge_body(archive_path, member, reviewed_head)
1801
- _require_member_close(checkout, member, bound, reviewed_head)
1835
+ _require_member_close(checkout, member, bound, reviewed_head, default)
1802
1836
  require_github_authentication()
1803
1837
  repository = github_repository(checkout)
1804
- pull = find_pull_request(repository, bound, reviewed_head)
1838
+ pull = find_pull_request(repository, bound, reviewed_head, default)
1805
1839
  if pull is None or pull["merged_at"] is None:
1806
1840
  if pull is not None and pull["state"] != "open":
1807
1841
  raise ArchiveError(f"member {member} pull request was closed without merging")
@@ -1809,12 +1843,12 @@ def integrate_member_pull_request(coordinator: Path, member: str, archive_path:
1809
1843
  if pull is None:
1810
1844
  pull = require_pull_request_shape(github_api_json(
1811
1845
  f"repos/{repository}/pulls", "--method", "POST", "-f", f"title={subject}",
1812
- "-f", f"head={bound}", "-f", "base=main", "-f", f"body={body}\n\n---\n{PR_CREDIT_LINE}"))
1813
- require_pull_request_identity(repository, pull, bound, reviewed_head)
1846
+ "-f", f"head={bound}", "-f", f"base={default}", "-f", f"body={body}\n\n---\n{PR_CREDIT_LINE}"))
1847
+ require_pull_request_identity(repository, pull, bound, reviewed_head, default)
1814
1848
  else:
1815
1849
  pull = update_pull_request_body(
1816
1850
  repository, pull, archive_path, reviewed_head, bound,
1817
- f"{body}\n\n---\n{PR_CREDIT_LINE}",
1851
+ f"{body}\n\n---\n{PR_CREDIT_LINE}", default,
1818
1852
  )
1819
1853
  require_pull_request_merge_provenance(repository, pull["number"])
1820
1854
  return {"status": "awaiting-merge", "mode": "pull-request", "member": member,
@@ -1824,10 +1858,10 @@ def integrate_member_pull_request(coordinator: Path, member: str, archive_path:
1824
1858
  raise ArchiveError(f"member {member} pull request merge metadata is invalid")
1825
1859
  require_pull_request_merge_provenance(repository, pull["number"], merge)
1826
1860
  refresh_origin(checkout)
1827
- require_pull_request_merge(checkout, merge, reviewed_head, "origin/main")
1861
+ require_pull_request_merge(checkout, merge, reviewed_head, f"origin/{default}")
1828
1862
  pull = update_pull_request_body(
1829
1863
  repository, pull, archive_path, reviewed_head, bound,
1830
- f"{body}\n\n---\n{PR_CREDIT_LINE}",
1864
+ f"{body}\n\n---\n{PR_CREDIT_LINE}", default,
1831
1865
  )
1832
1866
  message = member_pull_request_tag_message(tag_name, pull["html_url"], reviewed_head, merge)
1833
1867
  tag_object, tag_published = ensure_integration_tag(checkout, tag_name, merge, message)
@@ -1842,8 +1876,8 @@ def integrate_member_pull_request(coordinator: Path, member: str, archive_path:
1842
1876
  def validate_member_integrated(
1843
1877
  coordinator: Path, member: str, archive_path: str, reviewed_head: str, *, refresh: bool = True
1844
1878
  ) -> dict:
1845
- """Prove the member merge is on origin/main and its published tag points at it."""
1846
- checkout, _, bound, subject, tag_name = _member_names(coordinator, member, archive_path)
1879
+ """Prove the member merge is on the member default branch and its published tag points at it."""
1880
+ checkout, _, bound, subject, tag_name, default = _member_names(coordinator, member, archive_path)
1847
1881
  tracking = f"refs/remotes/origin/tags/{tag_name}"
1848
1882
  if refresh:
1849
1883
  refresh_origin(checkout)
@@ -1866,7 +1900,7 @@ def validate_member_integrated(
1866
1900
  raise ArchiveError(f"member {member} tag {tag_name} names a different landing")
1867
1901
  require_github_authentication()
1868
1902
  repository = github_repository(checkout)
1869
- pull = find_pull_request(repository, bound, reviewed_head)
1903
+ pull = find_pull_request(repository, bound, reviewed_head, default)
1870
1904
  if pull is None:
1871
1905
  raise ArchiveError(f"member {member} GitHub pull request is missing")
1872
1906
  if pull["html_url"] != metadata["Pull-Request"]:
@@ -1875,16 +1909,16 @@ def validate_member_integrated(
1875
1909
  or pull["merge_commit_sha"] != merge):
1876
1910
  raise ArchiveError(f"member {member} GitHub pull request is not merged at the tagged landing")
1877
1911
  require_pull_request_merge_provenance(repository, pull["number"], merge)
1878
- require_pull_request_merge(checkout, merge, reviewed_head, "origin/main")
1912
+ require_pull_request_merge(checkout, merge, reviewed_head, f"origin/{default}")
1879
1913
  require_annotated_tag(
1880
1914
  checkout, tracking, merge, f"member tag {tag_name}",
1881
1915
  member_pull_request_tag_message(tag_name, pull["html_url"], reviewed_head, merge),
1882
1916
  )
1883
1917
  else:
1884
1918
  merge = _find_member_merge(checkout, subject, _member_merge_body(archive_path, member, reviewed_head),
1885
- reviewed_head)
1919
+ reviewed_head, default)
1886
1920
  if merge is None:
1887
- raise ArchiveError(f"member {member} has no {subject!r} merge on origin/main")
1921
+ raise ArchiveError(f"member {member} has no {subject!r} merge on origin/{default}")
1888
1922
  if published is None:
1889
1923
  raise ArchiveError(f"member {member} tag {tag_name} is not published")
1890
1924
  require_annotated_tag(checkout, tracking, merge, f"member tag {tag_name}")
@@ -1898,7 +1932,7 @@ def retire_member(coordinator: Path, member: str, archive_path: str, reviewed_he
1898
1932
  import members
1899
1933
  except ImportError: # pragma: no cover - package import used by tests
1900
1934
  from scripts import members
1901
- checkout, project, bound, _, tag_name = _member_names(coordinator, member, archive_path)
1935
+ checkout, project, bound, _, tag_name, default = _member_names(coordinator, member, archive_path)
1902
1936
  proven = validate_member_integrated(coordinator, member, archive_path, reviewed_head)
1903
1937
  if (proven["merge"], proven["tag"]) != (merge, tag):
1904
1938
  raise ArchiveError(f"member {member} integration differs from the ship commit")
@@ -1937,7 +1971,7 @@ def retire_member(coordinator: Path, member: str, archive_path: str, reviewed_he
1937
1971
  archive_milestone.require_git_success(run_git(checkout, "update-ref", "-d", bound_ref, reviewed_head),
1938
1972
  "delete member bound branch")
1939
1973
  run_git(checkout, "update-ref", "-d", f"refs/remotes/origin/{bound}")
1940
- for kind, ref in (("push", bound_ref), ("push", "refs/heads/main"), ("push", f"refs/tags/{tag_name}"),
1974
+ for kind, ref in (("push", bound_ref), ("push", f"refs/heads/{default}"), ("push", f"refs/tags/{tag_name}"),
1941
1975
  ("delete", bound_ref)):
1942
1976
  members.clear_authorization(checkout, project, kind, ref)
1943
1977
  # The last sidecar retires here at milestone end; isolation's retires also