@opengsd/gsd-path 1.5.0 → 1.6.1
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.
- package/AGENTS.md +1 -1
- package/CHANGELOG.md +169 -0
- package/DOCS.md +4 -3
- package/FULL.md +68 -7
- package/HOOKS.md +81 -4
- package/MIGRATE.md +12 -0
- package/QUICK.md +4 -2
- package/README.md +69 -16
- package/RUNTIME.md +23 -5
- package/UPDATE.md +35 -0
- package/WORKFLOW.md +66 -7
- package/package.json +1 -1
- package/scripts/_common.py +150 -1
- package/scripts/build_recovery.py +62 -30
- package/scripts/build_state.py +195 -5
- package/scripts/check_handoffs.py +92 -30
- package/scripts/check_task_briefs.py +27 -19
- package/scripts/detect_project.py +17 -2
- package/scripts/discussion_records.py +9 -1
- package/scripts/discussion_validate.py +7 -6
- package/scripts/dispatch_driver.py +174 -36
- package/scripts/git_guard.py +42 -7
- package/scripts/guard_hook.py +1216 -47
- package/scripts/install.mjs +76 -3
- package/scripts/install.py +182 -37
- package/scripts/integration.py +115 -68
- package/scripts/isolation.py +192 -23
- package/scripts/members.py +68 -25
- package/scripts/migrate_core.py +2 -0
- package/scripts/model_policy.py +13 -2
- package/scripts/pipeline_diagnose.py +17 -2
- package/scripts/pipeline_git.py +87 -35
- package/scripts/pipeline_state.py +31 -7
- package/scripts/pipeline_undo.py +17 -8
- package/scripts/promote_lookahead.py +3 -3
- package/scripts/review_findings.py +180 -44
- package/scripts/roadmap.py +9 -1
- package/scripts/runtime_store.py +1 -0
- package/scripts/state_checkpoint.py +30 -9
- package/scripts/state_promote.py +92 -5
- package/scripts/task_context.py +2 -0
- package/scripts/workflow_run.py +9 -2
- package/skills/gsd-path/DEFINE.md +6 -2
- package/skills/gsd-path/PLAN.md +6 -2
- package/skills/gsd-path/ROADMAP.md +16 -6
- package/skills/gsd-path/SHIP.md +38 -11
- package/skills/gsd-path/SKILL.md +52 -24
- package/skills/gsd-path/references/build-native.md +96 -9
- package/skills/gsd-path/references/build-recovery.md +13 -0
- package/skills/gsd-path/references/coder.md +7 -3
- package/skills/gsd-path/references/model-policy.md +3 -1
- package/skills/gsd-path/references/operating-rules.md +14 -5
- package/skills/gsd-path/references/planner.md +13 -1
- package/skills/gsd-path/references/reviewer-final.md +5 -5
- package/skills/gsd-path/references/reviewer-wave.md +46 -13
- package/skills/gsd-path/references/runtime-selection.md +10 -0
- package/skills/gsd-path/scripts/_common.py +150 -1
- package/skills/gsd-path/scripts/build_recovery.py +62 -30
- package/skills/gsd-path/scripts/build_state.py +195 -5
- package/skills/gsd-path/scripts/check_handoffs.py +92 -30
- package/skills/gsd-path/scripts/check_task_briefs.py +27 -19
- package/skills/gsd-path/scripts/detect_project.py +17 -2
- package/skills/gsd-path/scripts/discussion_records.py +9 -1
- package/skills/gsd-path/scripts/discussion_validate.py +7 -6
- package/skills/gsd-path/scripts/dispatch_driver.py +174 -36
- package/skills/gsd-path/scripts/git_guard.py +42 -7
- package/skills/gsd-path/scripts/integration.py +115 -68
- package/skills/gsd-path/scripts/isolation.py +192 -23
- package/skills/gsd-path/scripts/members.py +68 -25
- package/skills/gsd-path/scripts/model_policy.py +13 -2
- package/skills/gsd-path/scripts/pipeline_git.py +87 -35
- package/skills/gsd-path/scripts/pipeline_state.py +31 -7
- package/skills/gsd-path/scripts/promote_lookahead.py +3 -3
- package/skills/gsd-path/scripts/review_findings.py +180 -44
- package/skills/gsd-path/scripts/roadmap.py +9 -1
- package/skills/gsd-path/scripts/state_checkpoint.py +30 -9
- package/skills/gsd-path/scripts/state_promote.py +92 -5
- package/skills/gsd-path/scripts/task_context.py +2 -0
- package/skills/gsd-path/scripts/workflow_run.py +9 -2
- package/skills/gsd-path/templates/final-review.md +5 -5
- package/skills/gsd-path/templates/state.md +1 -0
- package/skills/gsd-path/templates/task.md +1 -0
- package/skills/gsd-path/templates/wave-review.md +18 -9
- package/skills/gsd-path-build/references/build-native.md +96 -9
- package/skills/gsd-path-build/references/build-recovery.md +13 -0
- package/skills/gsd-path-build/references/coder.md +7 -3
- package/skills/gsd-path-build/references/model-policy.md +3 -1
- package/skills/gsd-path-build/references/operating-rules.md +14 -5
- package/skills/gsd-path-build/references/reviewer-final.md +5 -5
- package/skills/gsd-path-build/references/reviewer-wave.md +46 -13
- package/skills/gsd-path-build/references/runtime-selection.md +10 -0
- package/skills/gsd-path-build/scripts/_common.py +150 -1
- package/skills/gsd-path-build/scripts/build_recovery.py +62 -30
- package/skills/gsd-path-build/scripts/build_state.py +195 -5
- package/skills/gsd-path-build/scripts/check_handoffs.py +92 -30
- package/skills/gsd-path-build/scripts/check_task_briefs.py +27 -19
- package/skills/gsd-path-build/scripts/detect_project.py +17 -2
- package/skills/gsd-path-build/scripts/discussion_records.py +9 -1
- package/skills/gsd-path-build/scripts/discussion_validate.py +7 -6
- package/skills/gsd-path-build/scripts/dispatch_driver.py +174 -36
- package/skills/gsd-path-build/scripts/integration.py +115 -68
- package/skills/gsd-path-build/scripts/isolation.py +192 -23
- package/skills/gsd-path-build/scripts/members.py +68 -25
- package/skills/gsd-path-build/scripts/model_policy.py +13 -2
- package/skills/gsd-path-build/scripts/pipeline_git.py +87 -35
- package/skills/gsd-path-build/scripts/pipeline_state.py +31 -7
- package/skills/gsd-path-build/scripts/promote_lookahead.py +3 -3
- package/skills/gsd-path-build/scripts/review_findings.py +180 -44
- package/skills/gsd-path-build/scripts/roadmap.py +9 -1
- package/skills/gsd-path-build/scripts/state_checkpoint.py +30 -9
- package/skills/gsd-path-build/scripts/state_promote.py +92 -5
- package/skills/gsd-path-build/scripts/task_context.py +2 -0
- package/skills/gsd-path-build/scripts/workflow_run.py +9 -2
- package/skills/gsd-path-build/templates/task.md +1 -0
- package/skills/gsd-path-build/templates/wave-review.md +18 -9
- package/skills/gsd-path-decide/references/model-policy.md +3 -1
- package/skills/gsd-path-decide/references/operating-rules.md +14 -5
- package/skills/gsd-path-decide/references/runtime-selection.md +10 -0
- package/skills/gsd-path-decide/scripts/_common.py +150 -1
- package/skills/gsd-path-decide/scripts/build_recovery.py +62 -30
- package/skills/gsd-path-decide/scripts/check_handoffs.py +92 -30
- package/skills/gsd-path-decide/scripts/check_task_briefs.py +27 -19
- package/skills/gsd-path-decide/scripts/detect_project.py +17 -2
- package/skills/gsd-path-decide/scripts/discussion_records.py +9 -1
- package/skills/gsd-path-decide/scripts/discussion_validate.py +7 -6
- package/skills/gsd-path-decide/scripts/integration.py +115 -68
- package/skills/gsd-path-decide/scripts/isolation.py +192 -23
- package/skills/gsd-path-decide/scripts/members.py +68 -25
- package/skills/gsd-path-decide/scripts/model_policy.py +13 -2
- package/skills/gsd-path-decide/scripts/pipeline_git.py +87 -35
- package/skills/gsd-path-decide/scripts/pipeline_state.py +31 -7
- package/skills/gsd-path-decide/scripts/promote_lookahead.py +3 -3
- package/skills/gsd-path-decide/scripts/roadmap.py +9 -1
- package/skills/gsd-path-decide/scripts/state_checkpoint.py +30 -9
- package/skills/gsd-path-decide/scripts/state_promote.py +92 -5
- package/skills/gsd-path-define/SKILL.md +6 -2
- package/skills/gsd-path-define/references/build-recovery.md +13 -0
- package/skills/gsd-path-define/references/operating-rules.md +14 -5
- package/skills/gsd-path-define/references/runtime-selection.md +10 -0
- package/skills/gsd-path-define/scripts/_common.py +150 -1
- package/skills/gsd-path-define/scripts/build_recovery.py +62 -30
- package/skills/gsd-path-define/scripts/check_handoffs.py +92 -30
- package/skills/gsd-path-define/scripts/check_task_briefs.py +27 -19
- package/skills/gsd-path-define/scripts/detect_project.py +17 -2
- package/skills/gsd-path-define/scripts/discussion_records.py +9 -1
- package/skills/gsd-path-define/scripts/discussion_validate.py +7 -6
- package/skills/gsd-path-define/scripts/integration.py +115 -68
- package/skills/gsd-path-define/scripts/isolation.py +192 -23
- package/skills/gsd-path-define/scripts/members.py +68 -25
- package/skills/gsd-path-define/scripts/model_policy.py +13 -2
- package/skills/gsd-path-define/scripts/pipeline_git.py +87 -35
- package/skills/gsd-path-define/scripts/pipeline_state.py +31 -7
- package/skills/gsd-path-define/scripts/promote_lookahead.py +3 -3
- package/skills/gsd-path-define/scripts/roadmap.py +9 -1
- package/skills/gsd-path-define/scripts/state_checkpoint.py +30 -9
- package/skills/gsd-path-define/scripts/state_promote.py +92 -5
- package/skills/gsd-path-define/templates/state.md +1 -0
- package/skills/gsd-path-discuss/references/operating-rules.md +14 -5
- package/skills/gsd-path-discuss/references/runtime-selection.md +10 -0
- package/skills/gsd-path-discuss/scripts/_common.py +150 -1
- package/skills/gsd-path-discuss/scripts/discussion_records.py +9 -1
- package/skills/gsd-path-discuss/scripts/model_policy.py +13 -2
- package/skills/gsd-path-docs-audit/references/model-policy.md +3 -1
- package/skills/gsd-path-docs-audit/references/operating-rules.md +14 -5
- package/skills/gsd-path-docs-audit/references/runtime-selection.md +10 -0
- package/skills/gsd-path-docs-audit/scripts/_common.py +150 -1
- package/skills/gsd-path-docs-audit/scripts/build_recovery.py +62 -30
- package/skills/gsd-path-docs-audit/scripts/check_handoffs.py +92 -30
- package/skills/gsd-path-docs-audit/scripts/check_task_briefs.py +27 -19
- package/skills/gsd-path-docs-audit/scripts/detect_project.py +17 -2
- package/skills/gsd-path-docs-audit/scripts/discussion_records.py +9 -1
- package/skills/gsd-path-docs-audit/scripts/discussion_validate.py +7 -6
- package/skills/gsd-path-docs-audit/scripts/integration.py +115 -68
- package/skills/gsd-path-docs-audit/scripts/isolation.py +192 -23
- package/skills/gsd-path-docs-audit/scripts/members.py +68 -25
- package/skills/gsd-path-docs-audit/scripts/model_policy.py +13 -2
- package/skills/gsd-path-docs-audit/scripts/pipeline_git.py +87 -35
- package/skills/gsd-path-docs-audit/scripts/pipeline_state.py +31 -7
- package/skills/gsd-path-docs-audit/scripts/promote_lookahead.py +3 -3
- package/skills/gsd-path-docs-audit/scripts/roadmap.py +9 -1
- package/skills/gsd-path-docs-audit/scripts/state_checkpoint.py +30 -9
- package/skills/gsd-path-docs-audit/scripts/state_promote.py +92 -5
- package/skills/gsd-path-forensics/references/operating-rules.md +14 -5
- package/skills/gsd-path-forensics/references/runtime-selection.md +10 -0
- package/skills/gsd-path-forensics/scripts/_common.py +150 -1
- package/skills/gsd-path-forensics/scripts/discussion_records.py +9 -1
- package/skills/gsd-path-forensics/scripts/model_policy.py +13 -2
- package/skills/gsd-path-forensics/scripts/pipeline_diagnose.py +17 -2
- package/skills/gsd-path-forensics/scripts/pipeline_undo.py +17 -8
- package/skills/gsd-path-inspect/references/model-policy.md +3 -1
- package/skills/gsd-path-inspect/references/operating-rules.md +14 -5
- package/skills/gsd-path-inspect/references/runtime-selection.md +10 -0
- package/skills/gsd-path-inspect/scripts/_common.py +150 -1
- package/skills/gsd-path-inspect/scripts/build_recovery.py +62 -30
- package/skills/gsd-path-inspect/scripts/check_handoffs.py +92 -30
- package/skills/gsd-path-inspect/scripts/check_task_briefs.py +27 -19
- package/skills/gsd-path-inspect/scripts/detect_project.py +17 -2
- package/skills/gsd-path-inspect/scripts/discussion_records.py +9 -1
- package/skills/gsd-path-inspect/scripts/discussion_validate.py +7 -6
- package/skills/gsd-path-inspect/scripts/integration.py +115 -68
- package/skills/gsd-path-inspect/scripts/isolation.py +192 -23
- package/skills/gsd-path-inspect/scripts/members.py +68 -25
- package/skills/gsd-path-inspect/scripts/model_policy.py +13 -2
- package/skills/gsd-path-inspect/scripts/pipeline_git.py +87 -35
- package/skills/gsd-path-inspect/scripts/pipeline_state.py +31 -7
- package/skills/gsd-path-inspect/scripts/promote_lookahead.py +3 -3
- package/skills/gsd-path-inspect/scripts/roadmap.py +9 -1
- package/skills/gsd-path-inspect/scripts/state_checkpoint.py +30 -9
- package/skills/gsd-path-inspect/scripts/state_promote.py +92 -5
- package/skills/gsd-path-inspect/scripts/workflow_run.py +9 -2
- package/skills/gsd-path-inspect/templates/state.md +1 -0
- package/skills/gsd-path-loop/references/operating-rules.md +14 -5
- package/skills/gsd-path-loop/references/runtime-selection.md +10 -0
- package/skills/gsd-path-loop/scripts/_common.py +150 -1
- package/skills/gsd-path-loop/scripts/discussion_records.py +9 -1
- package/skills/gsd-path-loop/scripts/model_policy.py +13 -2
- package/skills/gsd-path-migrate/SKILL.md +8 -0
- package/skills/gsd-path-migrate/references/operating-rules.md +14 -5
- package/skills/gsd-path-migrate/references/runtime-selection.md +10 -0
- package/skills/gsd-path-migrate/scripts/_common.py +150 -1
- package/skills/gsd-path-migrate/scripts/discussion_records.py +9 -1
- package/skills/gsd-path-migrate/scripts/migrate_core.py +2 -0
- package/skills/gsd-path-migrate/scripts/model_policy.py +13 -2
- package/skills/gsd-path-plan/SKILL.md +6 -2
- package/skills/gsd-path-plan/references/build-recovery.md +13 -0
- package/skills/gsd-path-plan/references/model-policy.md +3 -1
- package/skills/gsd-path-plan/references/operating-rules.md +14 -5
- package/skills/gsd-path-plan/references/planner.md +13 -1
- package/skills/gsd-path-plan/references/runtime-selection.md +10 -0
- package/skills/gsd-path-plan/scripts/_common.py +150 -1
- package/skills/gsd-path-plan/scripts/build_recovery.py +62 -30
- package/skills/gsd-path-plan/scripts/check_handoffs.py +92 -30
- package/skills/gsd-path-plan/scripts/check_task_briefs.py +27 -19
- package/skills/gsd-path-plan/scripts/detect_project.py +17 -2
- package/skills/gsd-path-plan/scripts/discussion_records.py +9 -1
- package/skills/gsd-path-plan/scripts/discussion_validate.py +7 -6
- package/skills/gsd-path-plan/scripts/integration.py +115 -68
- package/skills/gsd-path-plan/scripts/isolation.py +192 -23
- package/skills/gsd-path-plan/scripts/members.py +68 -25
- package/skills/gsd-path-plan/scripts/model_policy.py +13 -2
- package/skills/gsd-path-plan/scripts/pipeline_git.py +87 -35
- package/skills/gsd-path-plan/scripts/pipeline_state.py +31 -7
- package/skills/gsd-path-plan/scripts/promote_lookahead.py +3 -3
- package/skills/gsd-path-plan/scripts/roadmap.py +9 -1
- package/skills/gsd-path-plan/scripts/state_checkpoint.py +30 -9
- package/skills/gsd-path-plan/scripts/state_promote.py +92 -5
- package/skills/gsd-path-plan/scripts/workflow_run.py +9 -2
- package/skills/gsd-path-plan/templates/task.md +1 -0
- package/skills/gsd-path-research/references/model-policy.md +3 -1
- package/skills/gsd-path-research/references/operating-rules.md +14 -5
- package/skills/gsd-path-research/references/runtime-selection.md +10 -0
- package/skills/gsd-path-research/scripts/_common.py +150 -1
- package/skills/gsd-path-research/scripts/build_recovery.py +62 -30
- package/skills/gsd-path-research/scripts/check_handoffs.py +92 -30
- package/skills/gsd-path-research/scripts/check_task_briefs.py +27 -19
- package/skills/gsd-path-research/scripts/detect_project.py +17 -2
- package/skills/gsd-path-research/scripts/discussion_records.py +9 -1
- package/skills/gsd-path-research/scripts/discussion_validate.py +7 -6
- package/skills/gsd-path-research/scripts/integration.py +115 -68
- package/skills/gsd-path-research/scripts/isolation.py +192 -23
- package/skills/gsd-path-research/scripts/members.py +68 -25
- package/skills/gsd-path-research/scripts/model_policy.py +13 -2
- package/skills/gsd-path-research/scripts/pipeline_git.py +87 -35
- package/skills/gsd-path-research/scripts/pipeline_state.py +31 -7
- package/skills/gsd-path-research/scripts/promote_lookahead.py +3 -3
- package/skills/gsd-path-research/scripts/roadmap.py +9 -1
- package/skills/gsd-path-research/scripts/state_checkpoint.py +30 -9
- package/skills/gsd-path-research/scripts/state_promote.py +92 -5
- package/skills/gsd-path-roadmap/SKILL.md +16 -6
- package/skills/gsd-path-roadmap/references/model-policy.md +3 -1
- package/skills/gsd-path-roadmap/references/operating-rules.md +14 -5
- package/skills/gsd-path-roadmap/references/runtime-selection.md +10 -0
- package/skills/gsd-path-roadmap/scripts/_common.py +150 -1
- package/skills/gsd-path-roadmap/scripts/build_recovery.py +62 -30
- package/skills/gsd-path-roadmap/scripts/check_handoffs.py +92 -30
- package/skills/gsd-path-roadmap/scripts/check_task_briefs.py +27 -19
- package/skills/gsd-path-roadmap/scripts/detect_project.py +17 -2
- package/skills/gsd-path-roadmap/scripts/discussion_records.py +9 -1
- package/skills/gsd-path-roadmap/scripts/discussion_validate.py +7 -6
- package/skills/gsd-path-roadmap/scripts/integration.py +115 -68
- package/skills/gsd-path-roadmap/scripts/isolation.py +192 -23
- package/skills/gsd-path-roadmap/scripts/members.py +68 -25
- package/skills/gsd-path-roadmap/scripts/model_policy.py +13 -2
- package/skills/gsd-path-roadmap/scripts/pipeline_git.py +87 -35
- package/skills/gsd-path-roadmap/scripts/pipeline_state.py +31 -7
- package/skills/gsd-path-roadmap/scripts/promote_lookahead.py +3 -3
- package/skills/gsd-path-roadmap/scripts/roadmap.py +9 -1
- package/skills/gsd-path-roadmap/scripts/state_checkpoint.py +30 -9
- package/skills/gsd-path-roadmap/scripts/state_promote.py +92 -5
- package/skills/gsd-path-ship/SKILL.md +38 -11
- package/skills/gsd-path-ship/references/model-policy.md +3 -1
- package/skills/gsd-path-ship/references/operating-rules.md +14 -5
- package/skills/gsd-path-ship/references/reviewer-final.md +5 -5
- package/skills/gsd-path-ship/references/reviewer-wave.md +46 -13
- package/skills/gsd-path-ship/references/runtime-selection.md +10 -0
- package/skills/gsd-path-ship/scripts/_common.py +150 -1
- package/skills/gsd-path-ship/scripts/build_recovery.py +62 -30
- package/skills/gsd-path-ship/scripts/build_state.py +195 -5
- package/skills/gsd-path-ship/scripts/check_handoffs.py +92 -30
- package/skills/gsd-path-ship/scripts/check_task_briefs.py +27 -19
- package/skills/gsd-path-ship/scripts/detect_project.py +17 -2
- package/skills/gsd-path-ship/scripts/discussion_records.py +9 -1
- package/skills/gsd-path-ship/scripts/discussion_validate.py +7 -6
- package/skills/gsd-path-ship/scripts/integration.py +115 -68
- package/skills/gsd-path-ship/scripts/isolation.py +192 -23
- package/skills/gsd-path-ship/scripts/members.py +68 -25
- package/skills/gsd-path-ship/scripts/model_policy.py +13 -2
- package/skills/gsd-path-ship/scripts/pipeline_git.py +87 -35
- package/skills/gsd-path-ship/scripts/pipeline_state.py +31 -7
- package/skills/gsd-path-ship/scripts/promote_lookahead.py +3 -3
- package/skills/gsd-path-ship/scripts/roadmap.py +9 -1
- package/skills/gsd-path-ship/scripts/state_checkpoint.py +30 -9
- package/skills/gsd-path-ship/scripts/state_promote.py +92 -5
- package/skills/gsd-path-ship/scripts/workflow_run.py +9 -2
- package/skills/gsd-path-ship/templates/final-review.md +5 -5
- package/skills/gsd-path-ship/templates/wave-review.md +18 -9
- package/skills/gsd-path-undo/references/operating-rules.md +14 -5
- package/skills/gsd-path-undo/references/runtime-selection.md +10 -0
- package/skills/gsd-path-undo/scripts/_common.py +150 -1
- package/skills/gsd-path-undo/scripts/discussion_records.py +9 -1
- package/skills/gsd-path-undo/scripts/model_policy.py +13 -2
- package/skills/gsd-path-undo/scripts/pipeline_undo.py +17 -8
- package/skills/path/DEFINE.md +6 -2
- package/skills/path/PLAN.md +6 -2
- package/skills/path/ROADMAP.md +16 -6
- package/skills/path/SHIP.md +38 -11
- package/skills/path/SKILL.md +52 -24
- package/skills/path/references/build-native.md +96 -9
- package/skills/path/references/build-recovery.md +13 -0
- package/skills/path/references/coder.md +7 -3
- package/skills/path/references/model-policy.md +3 -1
- package/skills/path/references/operating-rules.md +14 -5
- package/skills/path/references/planner.md +13 -1
- package/skills/path/references/reviewer-final.md +5 -5
- package/skills/path/references/reviewer-wave.md +46 -13
- package/skills/path/references/runtime-selection.md +10 -0
- package/skills/path/scripts/_common.py +150 -1
- package/skills/path/scripts/build_recovery.py +62 -30
- package/skills/path/scripts/build_state.py +195 -5
- package/skills/path/scripts/check_handoffs.py +92 -30
- package/skills/path/scripts/check_task_briefs.py +27 -19
- package/skills/path/scripts/detect_project.py +17 -2
- package/skills/path/scripts/discussion_records.py +9 -1
- package/skills/path/scripts/discussion_validate.py +7 -6
- package/skills/path/scripts/dispatch_driver.py +174 -36
- package/skills/path/scripts/git_guard.py +42 -7
- package/skills/path/scripts/integration.py +115 -68
- package/skills/path/scripts/isolation.py +192 -23
- package/skills/path/scripts/members.py +68 -25
- package/skills/path/scripts/model_policy.py +13 -2
- package/skills/path/scripts/pipeline_git.py +87 -35
- package/skills/path/scripts/pipeline_state.py +31 -7
- package/skills/path/scripts/promote_lookahead.py +3 -3
- package/skills/path/scripts/review_findings.py +180 -44
- package/skills/path/scripts/roadmap.py +9 -1
- package/skills/path/scripts/state_checkpoint.py +30 -9
- package/skills/path/scripts/state_promote.py +92 -5
- package/skills/path/scripts/task_context.py +2 -0
- package/skills/path/scripts/workflow_run.py +9 -2
- package/skills/path/templates/final-review.md +5 -5
- package/skills/path/templates/state.md +1 -0
- package/skills/path/templates/task.md +1 -0
- package/skills/path/templates/wave-review.md +18 -9
package/scripts/integration.py
CHANGED
|
@@ -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(
|
|
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") !=
|
|
664
|
-
raise ArchiveError("GitHub pull request base is not
|
|
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(
|
|
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=
|
|
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") ==
|
|
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
|
|
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(
|
|
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,
|
|
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 =
|
|
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,
|
|
766
|
+
f"title={integrate_subject(archive_name, base)}",
|
|
755
767
|
"-f",
|
|
756
768
|
f"head={branch}",
|
|
757
769
|
"-f",
|
|
758
|
-
"base=
|
|
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
|
|
|
@@ -833,6 +845,8 @@ def require_pull_request_merge(
|
|
|
833
845
|
merge_commit: str,
|
|
834
846
|
ship_commit: str,
|
|
835
847
|
remote_default: str,
|
|
848
|
+
*,
|
|
849
|
+
allow_rebase: bool = False,
|
|
836
850
|
) -> None:
|
|
837
851
|
resolved = optional_ref(project, merge_commit)
|
|
838
852
|
if resolved != merge_commit:
|
|
@@ -841,16 +855,25 @@ def require_pull_request_merge(
|
|
|
841
855
|
run_git(project, "rev-list", "--parents", "-n", "1", merge_commit),
|
|
842
856
|
"inspect pull-request merge parents",
|
|
843
857
|
).split()
|
|
844
|
-
if len(parents)
|
|
858
|
+
if allow_rebase and len(parents) == 2:
|
|
859
|
+
problem = _common.rebase_landing_problem(project, ship_commit, merge_commit)
|
|
860
|
+
if problem is not None:
|
|
861
|
+
raise ArchiveError(
|
|
862
|
+
"pull-request integration must use a two-parent merge commit "
|
|
863
|
+
f"or a rebase merge of the ship commits: {problem}"
|
|
864
|
+
)
|
|
865
|
+
elif len(parents) != 3:
|
|
845
866
|
raise ArchiveError("pull-request integration must use a two-parent merge commit")
|
|
846
|
-
|
|
867
|
+
elif parents[2] != ship_commit:
|
|
847
868
|
raise ArchiveError("pull-request merge second parent is not the ship commit")
|
|
848
869
|
first_parent = archive_milestone.require_git_success(
|
|
849
870
|
run_git(project, "rev-list", "--first-parent", remote_default),
|
|
850
871
|
"inspect remote-default first-parent history",
|
|
851
872
|
).splitlines()
|
|
852
873
|
if merge_commit not in first_parent:
|
|
853
|
-
raise ArchiveError(
|
|
874
|
+
raise ArchiveError(
|
|
875
|
+
f"pull-request merge is not on {remote_default} first-parent history"
|
|
876
|
+
)
|
|
854
877
|
|
|
855
878
|
|
|
856
879
|
def require_pull_request_merge_provenance(
|
|
@@ -967,7 +990,8 @@ def integrate_pull_request(
|
|
|
967
990
|
raise ArchiveError("pull-request integration requires a bound branch")
|
|
968
991
|
require_github_authentication()
|
|
969
992
|
repository = github_repository(project)
|
|
970
|
-
|
|
993
|
+
base = state.default_branch
|
|
994
|
+
pull = find_pull_request(repository, branch, ship_commit, base)
|
|
971
995
|
if pull is None:
|
|
972
996
|
publish_bound_branch(project, branch, ship_commit)
|
|
973
997
|
pull = create_pull_request(
|
|
@@ -976,6 +1000,7 @@ def integrate_pull_request(
|
|
|
976
1000
|
archive_path,
|
|
977
1001
|
archive_name,
|
|
978
1002
|
ship_commit,
|
|
1003
|
+
base,
|
|
979
1004
|
)
|
|
980
1005
|
elif pull["merged_at"] is None:
|
|
981
1006
|
if pull["state"] != "open":
|
|
@@ -986,6 +1011,7 @@ def integrate_pull_request(
|
|
|
986
1011
|
archive_path,
|
|
987
1012
|
ship_commit,
|
|
988
1013
|
branch,
|
|
1014
|
+
base=base,
|
|
989
1015
|
)
|
|
990
1016
|
if pull["merged_at"] is None:
|
|
991
1017
|
if pull["state"] != "open":
|
|
@@ -1009,13 +1035,16 @@ def integrate_pull_request(
|
|
|
1009
1035
|
merge_commit,
|
|
1010
1036
|
)
|
|
1011
1037
|
remote_default = refresh_origin(project)["remote_default"]
|
|
1012
|
-
require_pull_request_merge(
|
|
1038
|
+
require_pull_request_merge(
|
|
1039
|
+
project, merge_commit, ship_commit, remote_default, allow_rebase=True
|
|
1040
|
+
)
|
|
1013
1041
|
pull = update_pull_request_body(
|
|
1014
1042
|
repository,
|
|
1015
1043
|
pull,
|
|
1016
1044
|
archive_path,
|
|
1017
1045
|
ship_commit,
|
|
1018
1046
|
branch,
|
|
1047
|
+
base=base,
|
|
1019
1048
|
)
|
|
1020
1049
|
tag_name = f"milestone/{archive_name}"
|
|
1021
1050
|
message = pull_request_tag_message(
|
|
@@ -1075,6 +1104,11 @@ def integrate_external_landing(
|
|
|
1075
1104
|
"mode": "external-landing",
|
|
1076
1105
|
"archive": archive_path,
|
|
1077
1106
|
"commit": ship_commit,
|
|
1107
|
+
"branch": bound_branch,
|
|
1108
|
+
"merge_subject": integrate_subject(archive_name, default_name),
|
|
1109
|
+
"merge_body": integrate_commit_body(
|
|
1110
|
+
archive_path, ship_commit, default_name, bound_branch
|
|
1111
|
+
),
|
|
1078
1112
|
}
|
|
1079
1113
|
if contains_ship.returncode != 0:
|
|
1080
1114
|
archive_milestone.require_git_success(
|
|
@@ -1158,8 +1192,10 @@ def integrate(repo: Path, slug: str) -> dict:
|
|
|
1158
1192
|
|
|
1159
1193
|
remote_default = refresh_origin(project)["remote_default"]
|
|
1160
1194
|
default_name = default_branch_name(remote_default)
|
|
1161
|
-
if default_name !=
|
|
1162
|
-
raise ArchiveError(
|
|
1195
|
+
if default_name != state.default_branch:
|
|
1196
|
+
raise ArchiveError(
|
|
1197
|
+
f"remote default must be {state.default_branch}, got {default_name!r}"
|
|
1198
|
+
)
|
|
1163
1199
|
if bound_branch == default_name:
|
|
1164
1200
|
raise ArchiveError("bound branch must not be the remote default")
|
|
1165
1201
|
remote_default_sha = archive_milestone.require_git_success(
|
|
@@ -1266,7 +1302,7 @@ def integrate(repo: Path, slug: str) -> dict:
|
|
|
1266
1302
|
"origin",
|
|
1267
1303
|
f"{merge_commit}:refs/heads/{default_name}",
|
|
1268
1304
|
),
|
|
1269
|
-
"push integration merge to
|
|
1305
|
+
f"push integration merge to {default_name}",
|
|
1270
1306
|
)
|
|
1271
1307
|
archive_milestone.require_git_success(
|
|
1272
1308
|
run_git(project, "update-ref", f"refs/remotes/{remote_default}", merge_commit),
|
|
@@ -1411,10 +1447,12 @@ def validate_integrated(
|
|
|
1411
1447
|
if bound_branch == default_name:
|
|
1412
1448
|
raise ArchiveError(
|
|
1413
1449
|
f"bound branch {bound_branch!r} is the remote default; "
|
|
1414
|
-
"ship merges onto
|
|
1450
|
+
"ship merges onto the default branch, never onto the work branch"
|
|
1451
|
+
)
|
|
1452
|
+
if default_name != state.default_branch:
|
|
1453
|
+
raise ArchiveError(
|
|
1454
|
+
f"remote default must be {state.default_branch}, got {default_name!r}"
|
|
1415
1455
|
)
|
|
1416
|
-
if default_name != "main":
|
|
1417
|
-
raise ArchiveError(f"remote default must be main, got {default_name!r}")
|
|
1418
1456
|
|
|
1419
1457
|
# (b) Resolve the integration proof selected before build.
|
|
1420
1458
|
tag_name = f"milestone/{archive_name}"
|
|
@@ -1430,7 +1468,7 @@ def validate_integrated(
|
|
|
1430
1468
|
pull_request = metadata["Pull-Request"]
|
|
1431
1469
|
require_github_authentication()
|
|
1432
1470
|
repository = github_repository(project)
|
|
1433
|
-
pull = find_pull_request(repository, bound_branch, ship_commit)
|
|
1471
|
+
pull = find_pull_request(repository, bound_branch, ship_commit, default_name)
|
|
1434
1472
|
if pull is None:
|
|
1435
1473
|
raise ArchiveError("GitHub pull request for the ship commit is missing")
|
|
1436
1474
|
if pull["html_url"] != pull_request:
|
|
@@ -1446,7 +1484,9 @@ def validate_integrated(
|
|
|
1446
1484
|
pull["number"],
|
|
1447
1485
|
merge_commit,
|
|
1448
1486
|
)
|
|
1449
|
-
require_pull_request_merge(
|
|
1487
|
+
require_pull_request_merge(
|
|
1488
|
+
project, merge_commit, ship_commit, remote_default, allow_rebase=True
|
|
1489
|
+
)
|
|
1450
1490
|
require_annotated_tag(
|
|
1451
1491
|
project,
|
|
1452
1492
|
tag_ref,
|
|
@@ -1623,21 +1663,23 @@ def require_published_integration(
|
|
|
1623
1663
|
)
|
|
1624
1664
|
|
|
1625
1665
|
|
|
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,
|
|
1666
|
+
def _member_names(coordinator: Path, member: str, archive_path: str) -> tuple[Path, str, str, str, str, str]:
|
|
1667
|
+
"""A member's checkout, coordinator project, bound branch, merge subject, tag,
|
|
1668
|
+
and the default branch that MEMBERS.md records for it."""
|
|
1628
1669
|
try:
|
|
1629
1670
|
import isolation
|
|
1630
1671
|
except ImportError: # pragma: no cover - package import used by tests
|
|
1631
1672
|
from scripts import isolation
|
|
1632
1673
|
try:
|
|
1633
1674
|
checkout, project = isolation.member_checkout(coordinator.resolve(), member)
|
|
1675
|
+
default = isolation.member_default_branch(coordinator.resolve(), member)
|
|
1634
1676
|
except isolation.IsolationError as error:
|
|
1635
1677
|
raise ArchiveError(str(error)) from error
|
|
1636
1678
|
archive_name = PurePosixPath(archive_path).name
|
|
1637
1679
|
identifier = milestone_id(milestone_number(archive_name))
|
|
1638
1680
|
bound = f"gsd-path/{project}-{identifier}"
|
|
1639
|
-
subject = f"integrate: {project} {identifier} — merge {bound} into
|
|
1640
|
-
return checkout, project, bound, subject, f"milestone/{project}-{archive_name}"
|
|
1681
|
+
subject = f"integrate: {project} {identifier} — merge {bound} into {default}"
|
|
1682
|
+
return checkout, project, bound, subject, f"milestone/{project}-{archive_name}", default
|
|
1641
1683
|
|
|
1642
1684
|
|
|
1643
1685
|
def _member_merge_body(archive_path: str, member: str, reviewed_head: str) -> str:
|
|
@@ -1664,16 +1706,16 @@ def member_pull_request_tag_metadata(contents: str) -> dict[str, str]:
|
|
|
1664
1706
|
return fields
|
|
1665
1707
|
|
|
1666
1708
|
|
|
1667
|
-
def _find_member_merge(checkout: Path, subject: str, body: str, reviewed_head: str) -> Optional[str]:
|
|
1668
|
-
"""The member merge in
|
|
1709
|
+
def _find_member_merge(checkout: Path, subject: str, body: str, reviewed_head: str, default: str) -> Optional[str]:
|
|
1710
|
+
"""The member merge in the first-parent history of origin/<default>, if published."""
|
|
1669
1711
|
log = archive_milestone.require_git_success(
|
|
1670
|
-
run_git(checkout, "log", "--first-parent", "--format=%H%x00%s", "origin/
|
|
1671
|
-
"inspect member origin/
|
|
1712
|
+
run_git(checkout, "log", "--first-parent", "--format=%H%x00%s", f"origin/{default}"),
|
|
1713
|
+
f"inspect member origin/{default} first-parent history",
|
|
1672
1714
|
)
|
|
1673
1715
|
matches = [commit for commit, _, text in (line.partition("\x00") for line in log.splitlines())
|
|
1674
1716
|
if text == subject]
|
|
1675
1717
|
if len(matches) > 1:
|
|
1676
|
-
raise ArchiveError(f"multiple member merges named {subject!r} on origin/
|
|
1718
|
+
raise ArchiveError(f"multiple member merges named {subject!r} on origin/{default}")
|
|
1677
1719
|
if not matches:
|
|
1678
1720
|
return None
|
|
1679
1721
|
_require_member_merge(checkout, matches[0], subject, body, reviewed_head)
|
|
@@ -1728,7 +1770,7 @@ def _create_member_merge(checkout: Path, project: str, archive_path: str, subjec
|
|
|
1728
1770
|
+ (", ".join(conflicts) or (merged.stderr or merged.stdout).strip()))
|
|
1729
1771
|
merge = archive_milestone.require_git_success(run_git(worktree, "rev-parse", "HEAD"), "resolve member merge")
|
|
1730
1772
|
if _require_member_merge(worktree, merge, subject, body, reviewed_head) != origin_main:
|
|
1731
|
-
raise ArchiveError("member merge first parent is not origin
|
|
1773
|
+
raise ArchiveError("member merge first parent is not the origin default branch")
|
|
1732
1774
|
remove_registered_worktree(checkout, branch, worktree)
|
|
1733
1775
|
return merge
|
|
1734
1776
|
|
|
@@ -1755,34 +1797,39 @@ def _publish_member_bound(checkout: Path, project: str, member: str, bound: str,
|
|
|
1755
1797
|
raise ArchiveError(f"member {member} origin/{bound} moved: {remote_bound}")
|
|
1756
1798
|
|
|
1757
1799
|
|
|
1758
|
-
def _require_member_close(checkout: Path, member: str, bound: str, reviewed_head: str) -> None:
|
|
1800
|
+
def _require_member_close(checkout: Path, member: str, bound: str, reviewed_head: str, default: str) -> None:
|
|
1759
1801
|
if optional_ref(checkout, f"refs/heads/{bound}") != reviewed_head:
|
|
1760
1802
|
raise ArchiveError(f"member {member} {bound} is not at its reviewed HEAD {reviewed_head}")
|
|
1761
|
-
|
|
1762
|
-
|
|
1803
|
+
live = default_branch_name(refresh_origin(checkout)["remote_default"])
|
|
1804
|
+
if live != default:
|
|
1805
|
+
raise ArchiveError(f"member {member} remote default must be {default}, got {live!r}")
|
|
1763
1806
|
|
|
1764
1807
|
|
|
1765
1808
|
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
|
|
1767
|
-
|
|
1809
|
+
"""Direct-mode member close: publish the bound branch, merge it into the member
|
|
1810
|
+
default branch, then tag."""
|
|
1811
|
+
checkout, project, bound, subject, tag_name, default = _member_names(coordinator, member, archive_path)
|
|
1812
|
+
origin_default = f"origin/{default}"
|
|
1768
1813
|
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)
|
|
1814
|
+
_require_member_close(checkout, member, bound, reviewed_head, default)
|
|
1815
|
+
merge = _find_member_merge(checkout, subject, body, reviewed_head, default)
|
|
1771
1816
|
if merge is None:
|
|
1772
1817
|
origin_main = archive_milestone.require_git_success(
|
|
1773
|
-
run_git(checkout, "rev-parse",
|
|
1818
|
+
run_git(checkout, "rev-parse", origin_default), f"resolve member {origin_default}")
|
|
1774
1819
|
ancestry = run_git(checkout, "merge-base", "--is-ancestor", reviewed_head, origin_main)
|
|
1775
1820
|
if ancestry.returncode == 0:
|
|
1776
|
-
raise ArchiveError(
|
|
1821
|
+
raise ArchiveError(
|
|
1822
|
+
f"member reviewed HEAD reached {origin_default} outside Path; user-approved recovery required")
|
|
1777
1823
|
if ancestry.returncode != 1:
|
|
1778
1824
|
archive_milestone.require_git_success(ancestry, "inspect member reviewed HEAD ancestry")
|
|
1779
1825
|
merge = _create_member_merge(checkout, project, archive_path, subject, body, reviewed_head, origin_main)
|
|
1780
|
-
# Publish in order: bound branch,
|
|
1826
|
+
# Publish in order: bound branch, default branch, tag; a rerun publishes only what is missing.
|
|
1781
1827
|
_publish_member_bound(checkout, project, member, bound, reviewed_head)
|
|
1782
|
-
if run_git(checkout, "merge-base", "--is-ancestor", merge,
|
|
1783
|
-
_push_member_ref(checkout, project, merge, "refs/heads/
|
|
1828
|
+
if run_git(checkout, "merge-base", "--is-ancestor", merge, origin_default).returncode != 0:
|
|
1829
|
+
_push_member_ref(checkout, project, merge, f"refs/heads/{default}", merge, None)
|
|
1784
1830
|
archive_milestone.require_git_success(
|
|
1785
|
-
run_git(checkout, "update-ref", "refs/remotes/
|
|
1831
|
+
run_git(checkout, "update-ref", f"refs/remotes/{origin_default}", merge),
|
|
1832
|
+
f"refresh member {origin_default}")
|
|
1786
1833
|
tag_object, tag_published = ensure_integration_tag(checkout, tag_name, merge)
|
|
1787
1834
|
if not tag_published:
|
|
1788
1835
|
_push_member_ref(checkout, project, f"refs/tags/{tag_name}", f"refs/tags/{tag_name}", tag_object, None)
|
|
@@ -1796,12 +1843,12 @@ def integrate_member(coordinator: Path, member: str, archive_path: str, reviewed
|
|
|
1796
1843
|
|
|
1797
1844
|
def integrate_member_pull_request(coordinator: Path, member: str, archive_path: str, reviewed_head: str) -> dict:
|
|
1798
1845
|
"""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)
|
|
1846
|
+
checkout, project, bound, subject, tag_name, default = _member_names(coordinator, member, archive_path)
|
|
1800
1847
|
body = _member_merge_body(archive_path, member, reviewed_head)
|
|
1801
|
-
_require_member_close(checkout, member, bound, reviewed_head)
|
|
1848
|
+
_require_member_close(checkout, member, bound, reviewed_head, default)
|
|
1802
1849
|
require_github_authentication()
|
|
1803
1850
|
repository = github_repository(checkout)
|
|
1804
|
-
pull = find_pull_request(repository, bound, reviewed_head)
|
|
1851
|
+
pull = find_pull_request(repository, bound, reviewed_head, default)
|
|
1805
1852
|
if pull is None or pull["merged_at"] is None:
|
|
1806
1853
|
if pull is not None and pull["state"] != "open":
|
|
1807
1854
|
raise ArchiveError(f"member {member} pull request was closed without merging")
|
|
@@ -1809,12 +1856,12 @@ def integrate_member_pull_request(coordinator: Path, member: str, archive_path:
|
|
|
1809
1856
|
if pull is None:
|
|
1810
1857
|
pull = require_pull_request_shape(github_api_json(
|
|
1811
1858
|
f"repos/{repository}/pulls", "--method", "POST", "-f", f"title={subject}",
|
|
1812
|
-
"-f", f"head={bound}", "-f", "base=
|
|
1813
|
-
require_pull_request_identity(repository, pull, bound, reviewed_head)
|
|
1859
|
+
"-f", f"head={bound}", "-f", f"base={default}", "-f", f"body={body}\n\n---\n{PR_CREDIT_LINE}"))
|
|
1860
|
+
require_pull_request_identity(repository, pull, bound, reviewed_head, default)
|
|
1814
1861
|
else:
|
|
1815
1862
|
pull = update_pull_request_body(
|
|
1816
1863
|
repository, pull, archive_path, reviewed_head, bound,
|
|
1817
|
-
f"{body}\n\n---\n{PR_CREDIT_LINE}",
|
|
1864
|
+
f"{body}\n\n---\n{PR_CREDIT_LINE}", default,
|
|
1818
1865
|
)
|
|
1819
1866
|
require_pull_request_merge_provenance(repository, pull["number"])
|
|
1820
1867
|
return {"status": "awaiting-merge", "mode": "pull-request", "member": member,
|
|
@@ -1824,10 +1871,10 @@ def integrate_member_pull_request(coordinator: Path, member: str, archive_path:
|
|
|
1824
1871
|
raise ArchiveError(f"member {member} pull request merge metadata is invalid")
|
|
1825
1872
|
require_pull_request_merge_provenance(repository, pull["number"], merge)
|
|
1826
1873
|
refresh_origin(checkout)
|
|
1827
|
-
require_pull_request_merge(checkout, merge, reviewed_head, "origin/
|
|
1874
|
+
require_pull_request_merge(checkout, merge, reviewed_head, f"origin/{default}")
|
|
1828
1875
|
pull = update_pull_request_body(
|
|
1829
1876
|
repository, pull, archive_path, reviewed_head, bound,
|
|
1830
|
-
f"{body}\n\n---\n{PR_CREDIT_LINE}",
|
|
1877
|
+
f"{body}\n\n---\n{PR_CREDIT_LINE}", default,
|
|
1831
1878
|
)
|
|
1832
1879
|
message = member_pull_request_tag_message(tag_name, pull["html_url"], reviewed_head, merge)
|
|
1833
1880
|
tag_object, tag_published = ensure_integration_tag(checkout, tag_name, merge, message)
|
|
@@ -1842,8 +1889,8 @@ def integrate_member_pull_request(coordinator: Path, member: str, archive_path:
|
|
|
1842
1889
|
def validate_member_integrated(
|
|
1843
1890
|
coordinator: Path, member: str, archive_path: str, reviewed_head: str, *, refresh: bool = True
|
|
1844
1891
|
) -> dict:
|
|
1845
|
-
"""Prove the member merge is on
|
|
1846
|
-
checkout, _, bound, subject, tag_name = _member_names(coordinator, member, archive_path)
|
|
1892
|
+
"""Prove the member merge is on the member default branch and its published tag points at it."""
|
|
1893
|
+
checkout, _, bound, subject, tag_name, default = _member_names(coordinator, member, archive_path)
|
|
1847
1894
|
tracking = f"refs/remotes/origin/tags/{tag_name}"
|
|
1848
1895
|
if refresh:
|
|
1849
1896
|
refresh_origin(checkout)
|
|
@@ -1866,7 +1913,7 @@ def validate_member_integrated(
|
|
|
1866
1913
|
raise ArchiveError(f"member {member} tag {tag_name} names a different landing")
|
|
1867
1914
|
require_github_authentication()
|
|
1868
1915
|
repository = github_repository(checkout)
|
|
1869
|
-
pull = find_pull_request(repository, bound, reviewed_head)
|
|
1916
|
+
pull = find_pull_request(repository, bound, reviewed_head, default)
|
|
1870
1917
|
if pull is None:
|
|
1871
1918
|
raise ArchiveError(f"member {member} GitHub pull request is missing")
|
|
1872
1919
|
if pull["html_url"] != metadata["Pull-Request"]:
|
|
@@ -1875,16 +1922,16 @@ def validate_member_integrated(
|
|
|
1875
1922
|
or pull["merge_commit_sha"] != merge):
|
|
1876
1923
|
raise ArchiveError(f"member {member} GitHub pull request is not merged at the tagged landing")
|
|
1877
1924
|
require_pull_request_merge_provenance(repository, pull["number"], merge)
|
|
1878
|
-
require_pull_request_merge(checkout, merge, reviewed_head, "origin/
|
|
1925
|
+
require_pull_request_merge(checkout, merge, reviewed_head, f"origin/{default}")
|
|
1879
1926
|
require_annotated_tag(
|
|
1880
1927
|
checkout, tracking, merge, f"member tag {tag_name}",
|
|
1881
1928
|
member_pull_request_tag_message(tag_name, pull["html_url"], reviewed_head, merge),
|
|
1882
1929
|
)
|
|
1883
1930
|
else:
|
|
1884
1931
|
merge = _find_member_merge(checkout, subject, _member_merge_body(archive_path, member, reviewed_head),
|
|
1885
|
-
reviewed_head)
|
|
1932
|
+
reviewed_head, default)
|
|
1886
1933
|
if merge is None:
|
|
1887
|
-
raise ArchiveError(f"member {member} has no {subject!r} merge on origin/
|
|
1934
|
+
raise ArchiveError(f"member {member} has no {subject!r} merge on origin/{default}")
|
|
1888
1935
|
if published is None:
|
|
1889
1936
|
raise ArchiveError(f"member {member} tag {tag_name} is not published")
|
|
1890
1937
|
require_annotated_tag(checkout, tracking, merge, f"member tag {tag_name}")
|
|
@@ -1898,7 +1945,7 @@ def retire_member(coordinator: Path, member: str, archive_path: str, reviewed_he
|
|
|
1898
1945
|
import members
|
|
1899
1946
|
except ImportError: # pragma: no cover - package import used by tests
|
|
1900
1947
|
from scripts import members
|
|
1901
|
-
checkout, project, bound, _, tag_name = _member_names(coordinator, member, archive_path)
|
|
1948
|
+
checkout, project, bound, _, tag_name, default = _member_names(coordinator, member, archive_path)
|
|
1902
1949
|
proven = validate_member_integrated(coordinator, member, archive_path, reviewed_head)
|
|
1903
1950
|
if (proven["merge"], proven["tag"]) != (merge, tag):
|
|
1904
1951
|
raise ArchiveError(f"member {member} integration differs from the ship commit")
|
|
@@ -1937,7 +1984,7 @@ def retire_member(coordinator: Path, member: str, archive_path: str, reviewed_he
|
|
|
1937
1984
|
archive_milestone.require_git_success(run_git(checkout, "update-ref", "-d", bound_ref, reviewed_head),
|
|
1938
1985
|
"delete member bound branch")
|
|
1939
1986
|
run_git(checkout, "update-ref", "-d", f"refs/remotes/origin/{bound}")
|
|
1940
|
-
for kind, ref in (("push", bound_ref), ("push", "refs/heads/
|
|
1987
|
+
for kind, ref in (("push", bound_ref), ("push", f"refs/heads/{default}"), ("push", f"refs/tags/{tag_name}"),
|
|
1941
1988
|
("delete", bound_ref)):
|
|
1942
1989
|
members.clear_authorization(checkout, project, kind, ref)
|
|
1943
1990
|
# The last sidecar retires here at milestone end; isolation's retires also
|