@opengsd/gsd-path 1.4.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.
- package/CHANGELOG.md +460 -341
- package/DOCS.md +16 -5
- package/FULL.md +67 -6
- package/HOOKS.md +158 -10
- package/MIGRATE.md +12 -0
- package/QUICK.md +4 -2
- package/README.md +136 -116
- package/RUNTIME.md +24 -6
- package/UPDATE.md +39 -3
- package/WORKFLOW.md +80 -4
- package/package.json +5 -2
- package/platforms/shared-agents/dispatch.md +13 -0
- package/scripts/_common.py +256 -2
- package/scripts/archive_milestone.py +14 -13
- package/scripts/build_recovery.py +155 -58
- package/scripts/build_state.py +274 -8
- package/scripts/check_docs_audit.py +77 -4
- package/scripts/check_handoffs.py +635 -57
- package/scripts/check_task_briefs.py +293 -32
- package/scripts/detect_project.py +260 -20
- package/scripts/discussion_records.py +9 -1
- package/scripts/discussion_validate.py +93 -35
- package/scripts/dispatch_driver.py +549 -53
- package/scripts/git_guard.py +27 -8
- package/scripts/guard_hook.py +2630 -210
- package/scripts/install.mjs +99 -11
- package/scripts/install.py +231 -46
- package/scripts/integration.py +244 -65
- package/scripts/isolation.py +539 -70
- package/scripts/loop_run.py +16 -4
- package/scripts/members.py +77 -32
- package/scripts/migrate_core.py +2 -0
- package/scripts/model_policy.py +5 -1
- package/scripts/path_config.py +3 -3
- package/scripts/pipeline_diagnose.py +17 -2
- package/scripts/pipeline_git.py +131 -42
- package/scripts/pipeline_state.py +139 -39
- package/scripts/pipeline_undo.py +118 -16
- 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 +21 -2
- package/scripts/skill-resources.json +9 -2
- package/scripts/state_checkpoint.py +39 -36
- package/scripts/state_promote.py +15 -4
- package/scripts/status_runtime.py +22 -4
- package/scripts/task_context.py +14 -3
- package/scripts/wizard.mjs +1 -0
- package/scripts/workflow_run.py +14 -4
- package/scripts/worktree_paths.py +54 -2
- package/skills/gsd-path/DEFINE.md +34 -5
- package/skills/gsd-path/PLAN.md +14 -3
- package/skills/gsd-path/RESEARCH.md +11 -0
- package/skills/gsd-path/ROADMAP.md +16 -6
- package/skills/gsd-path/SHIP.md +32 -5
- package/skills/gsd-path/SKILL.md +52 -24
- package/skills/gsd-path/references/build-native.md +112 -10
- package/skills/gsd-path/references/build-recovery.md +13 -0
- package/skills/gsd-path/references/coder.md +7 -3
- package/skills/gsd-path/references/dispatch.md +13 -0
- package/skills/gsd-path/references/docs-auditor.md +5 -0
- package/skills/gsd-path/references/operating-rules.md +11 -3
- package/skills/gsd-path/references/planner.md +26 -4
- package/skills/gsd-path/references/reviewer-final.md +20 -2
- package/skills/gsd-path/references/reviewer-wave.md +56 -12
- package/skills/gsd-path/references/reviewer.md +3 -1
- package/skills/gsd-path/references/runtime-selection.md +9 -0
- package/skills/gsd-path/references/spec-probes.md +150 -0
- package/skills/gsd-path/scripts/_common.py +256 -2
- package/skills/gsd-path/scripts/archive_milestone.py +14 -13
- package/skills/gsd-path/scripts/build_recovery.py +155 -58
- package/skills/gsd-path/scripts/build_state.py +274 -8
- package/skills/gsd-path/scripts/check_docs_audit.py +77 -4
- package/skills/gsd-path/scripts/check_handoffs.py +635 -57
- package/skills/gsd-path/scripts/check_task_briefs.py +293 -32
- package/skills/gsd-path/scripts/detect_project.py +260 -20
- package/skills/gsd-path/scripts/discussion_records.py +9 -1
- package/skills/gsd-path/scripts/discussion_validate.py +93 -35
- package/skills/gsd-path/scripts/dispatch_driver.py +549 -53
- package/skills/gsd-path/scripts/git_guard.py +27 -8
- package/skills/gsd-path/scripts/integration.py +244 -65
- package/skills/gsd-path/scripts/isolation.py +539 -70
- package/skills/gsd-path/scripts/loop_run.py +16 -4
- package/skills/gsd-path/scripts/members.py +77 -32
- package/skills/gsd-path/scripts/model_policy.py +5 -1
- package/skills/gsd-path/scripts/path_config.py +3 -3
- package/skills/gsd-path/scripts/pipeline_git.py +131 -42
- package/skills/gsd-path/scripts/pipeline_state.py +139 -39
- 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 +39 -36
- package/skills/gsd-path/scripts/state_promote.py +15 -4
- package/skills/gsd-path/scripts/status_runtime.py +22 -4
- package/skills/gsd-path/scripts/task_context.py +14 -3
- package/skills/gsd-path/scripts/workflow_run.py +14 -4
- package/skills/gsd-path/scripts/worktree_paths.py +54 -2
- package/skills/gsd-path/templates/docs-audit.md +5 -1
- package/skills/gsd-path/templates/final-review.md +11 -2
- package/skills/gsd-path/templates/intent.md +30 -0
- package/skills/gsd-path/templates/patch-findings.md +3 -3
- package/skills/gsd-path/templates/plan.md +17 -2
- package/skills/gsd-path/templates/research-handoff.md +14 -3
- package/skills/gsd-path/templates/state.md +2 -1
- package/skills/gsd-path/templates/task.md +1 -0
- package/skills/gsd-path/templates/wave-review.md +28 -9
- package/skills/gsd-path-build/references/build-native.md +112 -10
- 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/dispatch.md +13 -0
- package/skills/gsd-path-build/references/operating-rules.md +11 -3
- package/skills/gsd-path-build/references/reviewer-final.md +20 -2
- package/skills/gsd-path-build/references/reviewer-wave.md +56 -12
- package/skills/gsd-path-build/references/reviewer.md +3 -1
- package/skills/gsd-path-build/references/runtime-selection.md +9 -0
- package/skills/gsd-path-build/references/spec-probes.md +150 -0
- package/skills/gsd-path-build/scripts/_common.py +256 -2
- package/skills/gsd-path-build/scripts/archive_milestone.py +14 -13
- package/skills/gsd-path-build/scripts/build_recovery.py +155 -58
- package/skills/gsd-path-build/scripts/build_state.py +274 -8
- package/skills/gsd-path-build/scripts/check_handoffs.py +635 -57
- package/skills/gsd-path-build/scripts/check_task_briefs.py +293 -32
- package/skills/gsd-path-build/scripts/detect_project.py +260 -20
- package/skills/gsd-path-build/scripts/discussion_records.py +9 -1
- package/skills/gsd-path-build/scripts/discussion_validate.py +93 -35
- package/skills/gsd-path-build/scripts/dispatch_driver.py +549 -53
- package/skills/gsd-path-build/scripts/integration.py +244 -65
- package/skills/gsd-path-build/scripts/isolation.py +539 -70
- package/skills/gsd-path-build/scripts/loop_run.py +16 -4
- package/skills/gsd-path-build/scripts/members.py +77 -32
- package/skills/gsd-path-build/scripts/model_policy.py +5 -1
- package/skills/gsd-path-build/scripts/path_config.py +3 -3
- package/skills/gsd-path-build/scripts/pipeline_git.py +131 -42
- package/skills/gsd-path-build/scripts/pipeline_state.py +139 -39
- 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 +39 -36
- package/skills/gsd-path-build/scripts/state_promote.py +15 -4
- package/skills/gsd-path-build/scripts/task_context.py +14 -3
- package/skills/gsd-path-build/scripts/workflow_run.py +14 -4
- package/skills/gsd-path-build/scripts/worktree_paths.py +54 -2
- package/skills/gsd-path-build/templates/task.md +1 -0
- package/skills/gsd-path-build/templates/wave-review.md +28 -9
- package/skills/gsd-path-decide/references/dispatch.md +13 -0
- package/skills/gsd-path-decide/references/operating-rules.md +11 -3
- package/skills/gsd-path-decide/references/runtime-selection.md +9 -0
- package/skills/gsd-path-decide/scripts/_common.py +256 -2
- package/skills/gsd-path-decide/scripts/archive_milestone.py +14 -13
- package/skills/gsd-path-decide/scripts/build_recovery.py +155 -58
- package/skills/gsd-path-decide/scripts/check_handoffs.py +635 -57
- package/skills/gsd-path-decide/scripts/check_task_briefs.py +293 -32
- package/skills/gsd-path-decide/scripts/detect_project.py +260 -20
- package/skills/gsd-path-decide/scripts/discussion_records.py +9 -1
- package/skills/gsd-path-decide/scripts/discussion_validate.py +93 -35
- package/skills/gsd-path-decide/scripts/integration.py +244 -65
- package/skills/gsd-path-decide/scripts/isolation.py +539 -70
- package/skills/gsd-path-decide/scripts/loop_run.py +16 -4
- package/skills/gsd-path-decide/scripts/members.py +77 -32
- package/skills/gsd-path-decide/scripts/model_policy.py +5 -1
- package/skills/gsd-path-decide/scripts/path_config.py +3 -3
- package/skills/gsd-path-decide/scripts/pipeline_git.py +131 -42
- package/skills/gsd-path-decide/scripts/pipeline_state.py +139 -39
- 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 +39 -36
- package/skills/gsd-path-decide/scripts/state_promote.py +15 -4
- package/skills/gsd-path-decide/scripts/worktree_paths.py +54 -2
- package/skills/gsd-path-define/SKILL.md +34 -5
- package/skills/gsd-path-define/references/build-recovery.md +13 -0
- package/skills/gsd-path-define/references/operating-rules.md +11 -3
- package/skills/gsd-path-define/references/runtime-selection.md +9 -0
- package/skills/gsd-path-define/references/spec-probes.md +150 -0
- package/skills/gsd-path-define/scripts/_common.py +256 -2
- package/skills/gsd-path-define/scripts/archive_milestone.py +14 -13
- package/skills/gsd-path-define/scripts/build_recovery.py +155 -58
- package/skills/gsd-path-define/scripts/check_handoffs.py +635 -57
- package/skills/gsd-path-define/scripts/check_task_briefs.py +293 -32
- package/skills/gsd-path-define/scripts/detect_project.py +260 -20
- package/skills/gsd-path-define/scripts/discussion_records.py +9 -1
- package/skills/gsd-path-define/scripts/discussion_validate.py +93 -35
- package/skills/gsd-path-define/scripts/integration.py +244 -65
- package/skills/gsd-path-define/scripts/isolation.py +539 -70
- package/skills/gsd-path-define/scripts/loop_run.py +16 -4
- package/skills/gsd-path-define/scripts/members.py +77 -32
- package/skills/gsd-path-define/scripts/model_policy.py +5 -1
- package/skills/gsd-path-define/scripts/path_config.py +3 -3
- package/skills/gsd-path-define/scripts/pipeline_git.py +131 -42
- package/skills/gsd-path-define/scripts/pipeline_state.py +139 -39
- 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 +39 -36
- package/skills/gsd-path-define/scripts/state_promote.py +15 -4
- package/skills/gsd-path-define/scripts/worktree_paths.py +54 -2
- package/skills/gsd-path-define/templates/intent.md +30 -0
- package/skills/gsd-path-define/templates/state.md +2 -1
- package/skills/gsd-path-discuss/references/operating-rules.md +11 -3
- package/skills/gsd-path-discuss/references/runtime-selection.md +9 -0
- package/skills/gsd-path-discuss/scripts/_common.py +256 -2
- package/skills/gsd-path-discuss/scripts/discussion_records.py +9 -1
- package/skills/gsd-path-discuss/scripts/loop_run.py +16 -4
- package/skills/gsd-path-discuss/scripts/model_policy.py +5 -1
- package/skills/gsd-path-discuss/scripts/path_config.py +3 -3
- package/skills/gsd-path-discuss/scripts/worktree_paths.py +54 -2
- package/skills/gsd-path-docs-audit/references/dispatch.md +13 -0
- package/skills/gsd-path-docs-audit/references/docs-auditor.md +5 -0
- package/skills/gsd-path-docs-audit/references/operating-rules.md +11 -3
- package/skills/gsd-path-docs-audit/references/runtime-selection.md +9 -0
- package/skills/gsd-path-docs-audit/scripts/_common.py +256 -2
- package/skills/gsd-path-docs-audit/scripts/archive_milestone.py +14 -13
- package/skills/gsd-path-docs-audit/scripts/build_recovery.py +155 -58
- package/skills/gsd-path-docs-audit/scripts/check_docs_audit.py +77 -4
- package/skills/gsd-path-docs-audit/scripts/check_handoffs.py +635 -57
- package/skills/gsd-path-docs-audit/scripts/check_task_briefs.py +293 -32
- package/skills/gsd-path-docs-audit/scripts/detect_project.py +260 -20
- package/skills/gsd-path-docs-audit/scripts/discussion_records.py +9 -1
- package/skills/gsd-path-docs-audit/scripts/discussion_validate.py +93 -35
- package/skills/gsd-path-docs-audit/scripts/integration.py +244 -65
- package/skills/gsd-path-docs-audit/scripts/isolation.py +539 -70
- package/skills/gsd-path-docs-audit/scripts/loop_run.py +16 -4
- package/skills/gsd-path-docs-audit/scripts/members.py +77 -32
- package/skills/gsd-path-docs-audit/scripts/model_policy.py +5 -1
- package/skills/gsd-path-docs-audit/scripts/path_config.py +3 -3
- package/skills/gsd-path-docs-audit/scripts/pipeline_git.py +131 -42
- package/skills/gsd-path-docs-audit/scripts/pipeline_state.py +139 -39
- 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 +39 -36
- package/skills/gsd-path-docs-audit/scripts/state_promote.py +15 -4
- package/skills/gsd-path-docs-audit/scripts/worktree_paths.py +54 -2
- package/skills/gsd-path-docs-audit/templates/docs-audit.md +5 -1
- package/skills/gsd-path-forensics/references/operating-rules.md +11 -3
- package/skills/gsd-path-forensics/references/runtime-selection.md +9 -0
- package/skills/gsd-path-forensics/scripts/_common.py +256 -2
- package/skills/gsd-path-forensics/scripts/discussion_records.py +9 -1
- package/skills/gsd-path-forensics/scripts/loop_run.py +16 -4
- package/skills/gsd-path-forensics/scripts/model_policy.py +5 -1
- package/skills/gsd-path-forensics/scripts/path_config.py +3 -3
- package/skills/gsd-path-forensics/scripts/pipeline_diagnose.py +17 -2
- package/skills/gsd-path-forensics/scripts/pipeline_undo.py +118 -16
- package/skills/gsd-path-forensics/scripts/worktree_paths.py +54 -2
- package/skills/gsd-path-inspect/references/dispatch.md +13 -0
- package/skills/gsd-path-inspect/references/docs-auditor.md +5 -0
- package/skills/gsd-path-inspect/references/operating-rules.md +11 -3
- package/skills/gsd-path-inspect/references/runtime-selection.md +9 -0
- package/skills/gsd-path-inspect/scripts/_common.py +256 -2
- package/skills/gsd-path-inspect/scripts/archive_milestone.py +14 -13
- package/skills/gsd-path-inspect/scripts/build_recovery.py +155 -58
- package/skills/gsd-path-inspect/scripts/check_docs_audit.py +77 -4
- package/skills/gsd-path-inspect/scripts/check_handoffs.py +635 -57
- package/skills/gsd-path-inspect/scripts/check_task_briefs.py +293 -32
- package/skills/gsd-path-inspect/scripts/detect_project.py +260 -20
- package/skills/gsd-path-inspect/scripts/discussion_records.py +9 -1
- package/skills/gsd-path-inspect/scripts/discussion_validate.py +93 -35
- package/skills/gsd-path-inspect/scripts/integration.py +244 -65
- package/skills/gsd-path-inspect/scripts/isolation.py +539 -70
- package/skills/gsd-path-inspect/scripts/loop_run.py +16 -4
- package/skills/gsd-path-inspect/scripts/members.py +77 -32
- package/skills/gsd-path-inspect/scripts/model_policy.py +5 -1
- package/skills/gsd-path-inspect/scripts/path_config.py +3 -3
- package/skills/gsd-path-inspect/scripts/pipeline_git.py +131 -42
- package/skills/gsd-path-inspect/scripts/pipeline_state.py +139 -39
- 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 +39 -36
- package/skills/gsd-path-inspect/scripts/state_promote.py +15 -4
- package/skills/gsd-path-inspect/scripts/workflow_run.py +14 -4
- package/skills/gsd-path-inspect/scripts/worktree_paths.py +54 -2
- package/skills/gsd-path-inspect/templates/docs-audit.md +5 -1
- package/skills/gsd-path-inspect/templates/state.md +2 -1
- package/skills/gsd-path-loop/references/operating-rules.md +11 -3
- package/skills/gsd-path-loop/references/runtime-selection.md +9 -0
- package/skills/gsd-path-loop/scripts/_common.py +256 -2
- package/skills/gsd-path-loop/scripts/discussion_records.py +9 -1
- package/skills/gsd-path-loop/scripts/loop_run.py +16 -4
- package/skills/gsd-path-loop/scripts/model_policy.py +5 -1
- package/skills/gsd-path-loop/scripts/path_config.py +3 -3
- package/skills/gsd-path-loop/scripts/worktree_paths.py +54 -2
- package/skills/gsd-path-migrate/SKILL.md +8 -0
- package/skills/gsd-path-migrate/references/operating-rules.md +11 -3
- package/skills/gsd-path-migrate/references/runtime-selection.md +9 -0
- package/skills/gsd-path-migrate/scripts/_common.py +256 -2
- package/skills/gsd-path-migrate/scripts/discussion_records.py +9 -1
- package/skills/gsd-path-migrate/scripts/loop_run.py +16 -4
- package/skills/gsd-path-migrate/scripts/migrate_core.py +2 -0
- package/skills/gsd-path-migrate/scripts/model_policy.py +5 -1
- package/skills/gsd-path-migrate/scripts/path_config.py +3 -3
- package/skills/gsd-path-plan/SKILL.md +14 -3
- package/skills/gsd-path-plan/references/build-recovery.md +13 -0
- package/skills/gsd-path-plan/references/dispatch.md +13 -0
- package/skills/gsd-path-plan/references/operating-rules.md +11 -3
- package/skills/gsd-path-plan/references/planner.md +26 -4
- package/skills/gsd-path-plan/references/runtime-selection.md +9 -0
- package/skills/gsd-path-plan/references/spec-probes.md +150 -0
- package/skills/gsd-path-plan/scripts/_common.py +256 -2
- package/skills/gsd-path-plan/scripts/archive_milestone.py +14 -13
- package/skills/gsd-path-plan/scripts/build_recovery.py +155 -58
- package/skills/gsd-path-plan/scripts/check_handoffs.py +635 -57
- package/skills/gsd-path-plan/scripts/check_task_briefs.py +293 -32
- package/skills/gsd-path-plan/scripts/detect_project.py +260 -20
- package/skills/gsd-path-plan/scripts/discussion_records.py +9 -1
- package/skills/gsd-path-plan/scripts/discussion_validate.py +93 -35
- package/skills/gsd-path-plan/scripts/integration.py +244 -65
- package/skills/gsd-path-plan/scripts/isolation.py +539 -70
- package/skills/gsd-path-plan/scripts/loop_run.py +16 -4
- package/skills/gsd-path-plan/scripts/members.py +77 -32
- package/skills/gsd-path-plan/scripts/model_policy.py +5 -1
- package/skills/gsd-path-plan/scripts/path_config.py +3 -3
- package/skills/gsd-path-plan/scripts/pipeline_git.py +131 -42
- package/skills/gsd-path-plan/scripts/pipeline_state.py +139 -39
- 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 +39 -36
- package/skills/gsd-path-plan/scripts/state_promote.py +15 -4
- package/skills/gsd-path-plan/scripts/workflow_run.py +14 -4
- package/skills/gsd-path-plan/scripts/worktree_paths.py +54 -2
- package/skills/gsd-path-plan/templates/patch-findings.md +3 -3
- package/skills/gsd-path-plan/templates/plan.md +17 -2
- package/skills/gsd-path-plan/templates/task.md +1 -0
- package/skills/gsd-path-research/SKILL.md +11 -0
- package/skills/gsd-path-research/references/dispatch.md +13 -0
- package/skills/gsd-path-research/references/operating-rules.md +11 -3
- package/skills/gsd-path-research/references/runtime-selection.md +9 -0
- package/skills/gsd-path-research/scripts/_common.py +256 -2
- package/skills/gsd-path-research/scripts/archive_milestone.py +14 -13
- package/skills/gsd-path-research/scripts/build_recovery.py +155 -58
- package/skills/gsd-path-research/scripts/check_handoffs.py +635 -57
- package/skills/gsd-path-research/scripts/check_task_briefs.py +293 -32
- package/skills/gsd-path-research/scripts/detect_project.py +260 -20
- package/skills/gsd-path-research/scripts/discussion_records.py +9 -1
- package/skills/gsd-path-research/scripts/discussion_validate.py +93 -35
- package/skills/gsd-path-research/scripts/integration.py +244 -65
- package/skills/gsd-path-research/scripts/isolation.py +539 -70
- package/skills/gsd-path-research/scripts/loop_run.py +16 -4
- package/skills/gsd-path-research/scripts/members.py +77 -32
- package/skills/gsd-path-research/scripts/model_policy.py +5 -1
- package/skills/gsd-path-research/scripts/path_config.py +3 -3
- package/skills/gsd-path-research/scripts/pipeline_git.py +131 -42
- package/skills/gsd-path-research/scripts/pipeline_state.py +139 -39
- 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 +39 -36
- package/skills/gsd-path-research/scripts/state_promote.py +15 -4
- package/skills/gsd-path-research/scripts/worktree_paths.py +54 -2
- package/skills/gsd-path-research/templates/research-handoff.md +14 -3
- package/skills/gsd-path-roadmap/SKILL.md +16 -6
- package/skills/gsd-path-roadmap/references/dispatch.md +13 -0
- package/skills/gsd-path-roadmap/references/operating-rules.md +11 -3
- package/skills/gsd-path-roadmap/references/runtime-selection.md +9 -0
- package/skills/gsd-path-roadmap/scripts/_common.py +256 -2
- package/skills/gsd-path-roadmap/scripts/archive_milestone.py +14 -13
- package/skills/gsd-path-roadmap/scripts/build_recovery.py +155 -58
- package/skills/gsd-path-roadmap/scripts/check_handoffs.py +635 -57
- package/skills/gsd-path-roadmap/scripts/check_task_briefs.py +293 -32
- package/skills/gsd-path-roadmap/scripts/detect_project.py +260 -20
- package/skills/gsd-path-roadmap/scripts/discussion_records.py +9 -1
- package/skills/gsd-path-roadmap/scripts/discussion_validate.py +93 -35
- package/skills/gsd-path-roadmap/scripts/integration.py +244 -65
- package/skills/gsd-path-roadmap/scripts/isolation.py +539 -70
- package/skills/gsd-path-roadmap/scripts/loop_run.py +16 -4
- package/skills/gsd-path-roadmap/scripts/members.py +77 -32
- package/skills/gsd-path-roadmap/scripts/model_policy.py +5 -1
- package/skills/gsd-path-roadmap/scripts/path_config.py +3 -3
- package/skills/gsd-path-roadmap/scripts/pipeline_git.py +131 -42
- package/skills/gsd-path-roadmap/scripts/pipeline_state.py +139 -39
- 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 +39 -36
- package/skills/gsd-path-roadmap/scripts/state_promote.py +15 -4
- package/skills/gsd-path-roadmap/scripts/worktree_paths.py +54 -2
- package/skills/gsd-path-ship/SKILL.md +32 -5
- package/skills/gsd-path-ship/references/dispatch.md +13 -0
- package/skills/gsd-path-ship/references/operating-rules.md +11 -3
- package/skills/gsd-path-ship/references/reviewer-final.md +20 -2
- package/skills/gsd-path-ship/references/reviewer-wave.md +56 -12
- package/skills/gsd-path-ship/references/reviewer.md +3 -1
- package/skills/gsd-path-ship/references/runtime-selection.md +9 -0
- package/skills/gsd-path-ship/references/spec-probes.md +150 -0
- package/skills/gsd-path-ship/scripts/_common.py +256 -2
- package/skills/gsd-path-ship/scripts/archive_milestone.py +14 -13
- package/skills/gsd-path-ship/scripts/build_recovery.py +155 -58
- package/skills/gsd-path-ship/scripts/build_state.py +274 -8
- package/skills/gsd-path-ship/scripts/check_handoffs.py +635 -57
- package/skills/gsd-path-ship/scripts/check_task_briefs.py +293 -32
- package/skills/gsd-path-ship/scripts/detect_project.py +260 -20
- package/skills/gsd-path-ship/scripts/discussion_records.py +9 -1
- package/skills/gsd-path-ship/scripts/discussion_validate.py +93 -35
- package/skills/gsd-path-ship/scripts/integration.py +244 -65
- package/skills/gsd-path-ship/scripts/isolation.py +539 -70
- package/skills/gsd-path-ship/scripts/loop_run.py +16 -4
- package/skills/gsd-path-ship/scripts/members.py +77 -32
- package/skills/gsd-path-ship/scripts/model_policy.py +5 -1
- package/skills/gsd-path-ship/scripts/path_config.py +3 -3
- package/skills/gsd-path-ship/scripts/pipeline_git.py +131 -42
- package/skills/gsd-path-ship/scripts/pipeline_state.py +139 -39
- 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 +39 -36
- package/skills/gsd-path-ship/scripts/state_promote.py +15 -4
- package/skills/gsd-path-ship/scripts/workflow_run.py +14 -4
- package/skills/gsd-path-ship/scripts/worktree_paths.py +54 -2
- package/skills/gsd-path-ship/templates/final-review.md +11 -2
- package/skills/gsd-path-ship/templates/patch-findings.md +3 -3
- package/skills/gsd-path-ship/templates/wave-review.md +28 -9
- package/skills/gsd-path-undo/references/operating-rules.md +11 -3
- package/skills/gsd-path-undo/references/runtime-selection.md +9 -0
- package/skills/gsd-path-undo/scripts/_common.py +256 -2
- package/skills/gsd-path-undo/scripts/discussion_records.py +9 -1
- package/skills/gsd-path-undo/scripts/loop_run.py +16 -4
- package/skills/gsd-path-undo/scripts/model_policy.py +5 -1
- package/skills/gsd-path-undo/scripts/path_config.py +3 -3
- package/skills/gsd-path-undo/scripts/pipeline_undo.py +118 -16
- package/skills/gsd-path-undo/scripts/worktree_paths.py +54 -2
- package/skills/path/DEFINE.md +34 -5
- package/skills/path/PLAN.md +14 -3
- package/skills/path/RESEARCH.md +11 -0
- package/skills/path/ROADMAP.md +16 -6
- package/skills/path/SHIP.md +32 -5
- package/skills/path/SKILL.md +52 -24
- package/skills/path/references/build-native.md +112 -10
- package/skills/path/references/build-recovery.md +13 -0
- package/skills/path/references/coder.md +7 -3
- package/skills/path/references/dispatch.md +13 -0
- package/skills/path/references/docs-auditor.md +5 -0
- package/skills/path/references/operating-rules.md +11 -3
- package/skills/path/references/planner.md +26 -4
- package/skills/path/references/reviewer-final.md +20 -2
- package/skills/path/references/reviewer-wave.md +56 -12
- package/skills/path/references/reviewer.md +3 -1
- package/skills/path/references/runtime-selection.md +9 -0
- package/skills/path/references/spec-probes.md +150 -0
- package/skills/path/scripts/_common.py +256 -2
- package/skills/path/scripts/archive_milestone.py +14 -13
- package/skills/path/scripts/build_recovery.py +155 -58
- package/skills/path/scripts/build_state.py +274 -8
- package/skills/path/scripts/check_docs_audit.py +77 -4
- package/skills/path/scripts/check_handoffs.py +635 -57
- package/skills/path/scripts/check_task_briefs.py +293 -32
- package/skills/path/scripts/detect_project.py +260 -20
- package/skills/path/scripts/discussion_records.py +9 -1
- package/skills/path/scripts/discussion_validate.py +93 -35
- package/skills/path/scripts/dispatch_driver.py +549 -53
- package/skills/path/scripts/git_guard.py +27 -8
- package/skills/path/scripts/integration.py +244 -65
- package/skills/path/scripts/isolation.py +539 -70
- package/skills/path/scripts/loop_run.py +16 -4
- package/skills/path/scripts/members.py +77 -32
- package/skills/path/scripts/model_policy.py +5 -1
- package/skills/path/scripts/path_config.py +3 -3
- package/skills/path/scripts/pipeline_git.py +131 -42
- package/skills/path/scripts/pipeline_state.py +139 -39
- 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 +39 -36
- package/skills/path/scripts/state_promote.py +15 -4
- package/skills/path/scripts/status_runtime.py +22 -4
- package/skills/path/scripts/task_context.py +14 -3
- package/skills/path/scripts/workflow_run.py +14 -4
- package/skills/path/scripts/worktree_paths.py +54 -2
- package/skills/path/templates/docs-audit.md +5 -1
- package/skills/path/templates/final-review.md +11 -2
- package/skills/path/templates/intent.md +30 -0
- package/skills/path/templates/patch-findings.md +3 -3
- package/skills/path/templates/plan.md +17 -2
- package/skills/path/templates/research-handoff.md +14 -3
- package/skills/path/templates/state.md +2 -1
- package/skills/path/templates/task.md +1 -0
- package/skills/path/templates/wave-review.md +28 -9
- package/skills/gsd-path/scripts/__pycache__/_common.cpython-312.pyc +0 -0
- package/skills/gsd-path/scripts/__pycache__/check_handoffs.cpython-312.pyc +0 -0
- package/skills/gsd-path-build/scripts/__pycache__/_common.cpython-312.pyc +0 -0
- package/skills/gsd-path-build/scripts/__pycache__/check_handoffs.cpython-312.pyc +0 -0
- package/skills/gsd-path-inspect/scripts/__pycache__/_common.cpython-312.pyc +0 -0
- package/skills/gsd-path-plan/scripts/__pycache__/_common.cpython-312.pyc +0 -0
- package/skills/gsd-path-ship/scripts/__pycache__/_common.cpython-312.pyc +0 -0
package/scripts/loop_run.py
CHANGED
|
@@ -514,16 +514,28 @@ def run_shell(command: str, timeout: float) -> tuple[Optional[int], str]:
|
|
|
514
514
|
"""Run one spec command; a hung command counts as failed (exit None).
|
|
515
515
|
|
|
516
516
|
POSIX runs /bin/sh as shell=True did; Windows runs Git for Windows bash, not
|
|
517
|
-
cmd.exe. A timeout kills the whole process group
|
|
518
|
-
|
|
517
|
+
cmd.exe. A timeout kills the whole process group when possible; if output
|
|
518
|
+
pipes stay open, drain them with a short grace timeout and then close them.
|
|
519
519
|
"""
|
|
520
520
|
argv = _common.bash_argv(command) if os.name == "nt" else ["/bin/sh", "-c", command]
|
|
521
521
|
process = _common.popen_group(argv, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
522
|
+
stdout = b""
|
|
523
|
+
stderr = b""
|
|
522
524
|
try:
|
|
523
525
|
stdout, stderr = process.communicate(timeout=timeout)
|
|
524
|
-
except subprocess.TimeoutExpired:
|
|
526
|
+
except subprocess.TimeoutExpired as expired:
|
|
525
527
|
_common.kill_tree(process)
|
|
526
|
-
|
|
528
|
+
try:
|
|
529
|
+
stdout, stderr = process.communicate(timeout=5)
|
|
530
|
+
except subprocess.TimeoutExpired as drained:
|
|
531
|
+
stdout = drained.stdout or expired.stdout or b""
|
|
532
|
+
stderr = drained.stderr or expired.stderr or b""
|
|
533
|
+
if process.stdout:
|
|
534
|
+
process.stdout.close()
|
|
535
|
+
if process.stderr:
|
|
536
|
+
process.stderr.close()
|
|
537
|
+
process.kill()
|
|
538
|
+
process.wait(timeout=5)
|
|
527
539
|
output = stdout.decode("utf-8", errors="replace") + stderr.decode("utf-8", errors="replace")
|
|
528
540
|
return None, f"{output}\ntimed out at the admitted wall-clock deadline"
|
|
529
541
|
return process.returncode, (stdout + stderr).decode("utf-8", errors="replace")
|
package/scripts/members.py
CHANGED
|
@@ -35,6 +35,8 @@ MARKER_SCHEMA = "gsd-path/member/v1"
|
|
|
35
35
|
MARKER_KEYS = {"schema", "coordinator", "project", "name"}
|
|
36
36
|
NAME_RE = re.compile(r"^[a-z0-9][a-z0-9-]*$")
|
|
37
37
|
FIELDS = ("Checkout", "Remote", "Integration")
|
|
38
|
+
# Optional: `add` records it one time; a row without it means main.
|
|
39
|
+
DEFAULT_BRANCH_FIELD = "Default branch"
|
|
38
40
|
INTEGRATIONS = ("default", "direct", "pull-request")
|
|
39
41
|
GITHUB_REMOTE_RE = re.compile(
|
|
40
42
|
r"(?:https://github\.com/|git@github\.com:|ssh://git@github\.com/)([^/\s]+)/([^/\s]+)"
|
|
@@ -221,9 +223,10 @@ def read_members(coordinator: Path) -> list[dict[str, str]]:
|
|
|
221
223
|
if not line.strip():
|
|
222
224
|
continue
|
|
223
225
|
key, separator, value = line.partition(":")
|
|
224
|
-
|
|
226
|
+
field = key.lower().replace(" ", "_")
|
|
227
|
+
if not separator or key not in (*FIELDS, DEFAULT_BRANCH_FIELD) or field in current:
|
|
225
228
|
raise MembersError(f"MEMBERS.md line {number}: unexpected line {line!r}")
|
|
226
|
-
current[
|
|
229
|
+
current[field] = value.strip()
|
|
227
230
|
if not preamble or preamble[0] != "# Members":
|
|
228
231
|
raise MembersError("MEMBERS.md format error: expected # Members")
|
|
229
232
|
rest = preamble[1:]
|
|
@@ -247,16 +250,37 @@ def read_members(coordinator: Path) -> list[dict[str, str]]:
|
|
|
247
250
|
)
|
|
248
251
|
if not Path(member["checkout"]).is_absolute():
|
|
249
252
|
raise MembersError(f"MEMBERS.md member {member['name']} Checkout must be absolute")
|
|
253
|
+
if not _common.valid_default_branch(default_branch(member)):
|
|
254
|
+
raise MembersError(
|
|
255
|
+
f"MEMBERS.md member {member['name']} has invalid Default branch: {member['default_branch']}"
|
|
256
|
+
)
|
|
250
257
|
return members
|
|
251
258
|
|
|
252
259
|
|
|
260
|
+
def default_branch(member: dict[str, str]) -> str:
|
|
261
|
+
"""The default branch a MEMBERS.md row records; a row without the field means main."""
|
|
262
|
+
return member.get("default_branch", "main")
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
def member_default_branch(coordinator: Path, name: str) -> str:
|
|
266
|
+
"""The default branch MEMBERS.md records for the member `name`."""
|
|
267
|
+
for member in read_members(coordinator):
|
|
268
|
+
if member["name"] == name:
|
|
269
|
+
return default_branch(member)
|
|
270
|
+
raise MembersError(f"member {name} is not in MEMBERS.md")
|
|
271
|
+
|
|
272
|
+
|
|
253
273
|
def check_member(
|
|
254
274
|
coordinator: Path,
|
|
255
275
|
coordinator_name: str,
|
|
256
276
|
checkout: Path,
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
277
|
+
recorded: Optional[dict[str, str]] = None,
|
|
278
|
+
refuse_reserved_refs: bool = True,
|
|
279
|
+
) -> tuple[str, str]:
|
|
280
|
+
"""Refuse a checkout that cannot join; return its origin URL and default branch.
|
|
281
|
+
|
|
282
|
+
`recorded` is the member's MEMBERS.md row. Without it (`add`), the default
|
|
283
|
+
branch is the local origin/HEAD, read this one time; an unset ref means main."""
|
|
260
284
|
if checkout.is_symlink() or not checkout.is_dir():
|
|
261
285
|
raise MembersError(f"member checkout is not a real directory: {checkout}")
|
|
262
286
|
checkout = checkout.resolve()
|
|
@@ -278,12 +302,21 @@ def check_member(
|
|
|
278
302
|
remote = _git(checkout, "config", "--get", "remote.origin.url")
|
|
279
303
|
if not GITHUB_REMOTE_RE.fullmatch(remote):
|
|
280
304
|
raise MembersError(f"member requires a GitHub.com origin: {remote}")
|
|
281
|
-
if
|
|
282
|
-
raise MembersError(f"member origin changed: {
|
|
283
|
-
|
|
284
|
-
if
|
|
285
|
-
|
|
286
|
-
|
|
305
|
+
if recorded is not None and remote != recorded["remote"]:
|
|
306
|
+
raise MembersError(f"member origin changed: {recorded['remote']} -> {remote}")
|
|
307
|
+
live = _common.origin_default_branch(checkout)
|
|
308
|
+
default = live if recorded is None else default_branch(recorded)
|
|
309
|
+
if live != default:
|
|
310
|
+
raise MembersError(
|
|
311
|
+
f"member remote default must be {default}, got {live}: {checkout}; "
|
|
312
|
+
"run `git remote set-head origin --auto` when the local origin/HEAD is stale"
|
|
313
|
+
)
|
|
314
|
+
if not _common.valid_default_branch(default):
|
|
315
|
+
raise MembersError(
|
|
316
|
+
f"member default branch {default!r} cannot be recorded in MEMBERS.md: it is a "
|
|
317
|
+
"GSD Path reserved name or it has a character that the file cannot hold"
|
|
318
|
+
)
|
|
319
|
+
require_origin_branch(checkout, default)
|
|
287
320
|
member_state = checkout / ".project" / "STATE.md"
|
|
288
321
|
if member_state.exists() or member_state.is_symlink():
|
|
289
322
|
if member_state.is_symlink() or not member_state.is_file():
|
|
@@ -294,14 +327,15 @@ def check_member(
|
|
|
294
327
|
raise MembersError(f"member STATE.md is unreadable: {error}") from error
|
|
295
328
|
if state.milestone is not None and (state.phase, state.status) != ("shipped", "done"):
|
|
296
329
|
raise MembersError(f"member has an active milestone: {state.milestone}")
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
330
|
+
if refuse_reserved_refs:
|
|
331
|
+
prefixes = member_ref_prefixes(coordinator_name) + tuple(
|
|
332
|
+
"refs/remotes/origin/" + branch.format(coordinator_name) for branch in MEMBER_BRANCH_FORMATS
|
|
333
|
+
)
|
|
334
|
+
refs = _git(checkout, "for-each-ref", "--format=%(refname)").splitlines()
|
|
335
|
+
colliding = [ref for ref in refs if ref.startswith(prefixes)]
|
|
336
|
+
if colliding:
|
|
337
|
+
raise MembersError("member refs collide with coordinator names: " + ", ".join(colliding))
|
|
338
|
+
return remote, default
|
|
305
339
|
|
|
306
340
|
|
|
307
341
|
MEMBER_CLOSE_SCHEMA = "gsd-path/member-close/v1"
|
|
@@ -336,12 +370,14 @@ def write_member_close(common: Path, archive_name: str, rows: list[dict]) -> Non
|
|
|
336
370
|
_common.atomic_write(path, json.dumps({"schema": MEMBER_CLOSE_SCHEMA, "members": rows}, indent=2) + "\n")
|
|
337
371
|
|
|
338
372
|
|
|
339
|
-
def
|
|
373
|
+
def require_origin_branch(checkout: Path, branch: str) -> str:
|
|
374
|
+
"""The commit of the member's fetched default branch `branch`."""
|
|
340
375
|
baseline = _common.run_git(
|
|
341
|
-
checkout, "rev-parse", "--verify", "--quiet", "refs/remotes/origin/
|
|
376
|
+
checkout, "rev-parse", "--verify", "--quiet", f"refs/remotes/origin/{branch}^{{commit}}"
|
|
342
377
|
)
|
|
343
378
|
if baseline.returncode != 0:
|
|
344
|
-
raise MembersError("member requires refs/remotes/origin/
|
|
379
|
+
raise MembersError(f"member requires refs/remotes/origin/{branch}; run git fetch origin")
|
|
380
|
+
return baseline.stdout.strip()
|
|
345
381
|
|
|
346
382
|
|
|
347
383
|
def member_ref_prefixes(project: str) -> tuple[str, ...]:
|
|
@@ -403,7 +439,8 @@ def _task_members(coordinator: Path) -> set[str]:
|
|
|
403
439
|
|
|
404
440
|
def lock_build_members(coordinator: Path) -> Optional[list[dict[str, str]]]:
|
|
405
441
|
"""At build start, lock the members tasks name (MEMBERS.md order) and create
|
|
406
|
-
each member's bound branch at its origin
|
|
442
|
+
each member's bound branch at its recorded default branch on origin. None when
|
|
443
|
+
no task names a member."""
|
|
407
444
|
root, state = _coordinator(coordinator)
|
|
408
445
|
named = _task_members(root)
|
|
409
446
|
lock_path = root / LOCK_PATH
|
|
@@ -442,8 +479,8 @@ def lock_build_members(coordinator: Path) -> Optional[list[dict[str, str]]]:
|
|
|
442
479
|
remote = _git(checkout, "config", "--get", "remote.origin.url")
|
|
443
480
|
if remote != member["remote"]:
|
|
444
481
|
raise MembersError(f"member origin changed: {member['remote']} -> {remote}")
|
|
445
|
-
|
|
446
|
-
base =
|
|
482
|
+
default = default_branch(member)
|
|
483
|
+
base = require_origin_branch(checkout, default)
|
|
447
484
|
existing = _common.run_git(checkout, "rev-parse", "--verify", "--quiet", f"refs/heads/{branch}")
|
|
448
485
|
if existing.returncode == 0:
|
|
449
486
|
tip = existing.stdout.strip()
|
|
@@ -456,7 +493,7 @@ def lock_build_members(coordinator: Path) -> Optional[list[dict[str, str]]]:
|
|
|
456
493
|
elif _common.run_git(checkout, "merge-base", "--is-ancestor", tip, base).returncode == 0:
|
|
457
494
|
base = tip
|
|
458
495
|
else:
|
|
459
|
-
raise MembersError(f"member {member['name']} branch {branch} has commits not on origin/
|
|
496
|
+
raise MembersError(f"member {member['name']} branch {branch} has commits not on origin/{default}")
|
|
460
497
|
else:
|
|
461
498
|
missing.append((checkout, base))
|
|
462
499
|
entries.append({"name": member["name"], "branch": branch, "base": base})
|
|
@@ -473,6 +510,8 @@ def render(members: Sequence[dict[str, str]]) -> str:
|
|
|
473
510
|
f"Checkout: {member['checkout']}\n"
|
|
474
511
|
f"Remote: {member['remote']}\n"
|
|
475
512
|
f"Integration: {member['integration']}\n"
|
|
513
|
+
# A row that never had the field keeps none, so old rows are not rewritten.
|
|
514
|
+
+ (f"{DEFAULT_BRANCH_FIELD}: {member['default_branch']}\n" if "default_branch" in member else "")
|
|
476
515
|
for member in members
|
|
477
516
|
]
|
|
478
517
|
return "\n".join([HEADER, *sections])
|
|
@@ -486,7 +525,7 @@ def add_member(repo: Path, name: str, checkout: Path, integration: str) -> list[
|
|
|
486
525
|
raise MembersError(f"invalid member name: {name!r}")
|
|
487
526
|
members = read_members(root)
|
|
488
527
|
resolved = checkout.resolve()
|
|
489
|
-
remote = check_member(root, state.project, checkout)
|
|
528
|
+
remote, default = check_member(root, state.project, checkout)
|
|
490
529
|
common = Path(_git(resolved, "rev-parse", "--path-format=absolute", "--git-common-dir")).resolve()
|
|
491
530
|
identity = _remote_identity(remote)
|
|
492
531
|
for member in members:
|
|
@@ -497,7 +536,8 @@ def add_member(repo: Path, name: str, checkout: Path, integration: str) -> list[
|
|
|
497
536
|
raise MembersError(f"member already recorded: {member['name']}")
|
|
498
537
|
_refuse_foreign_marker(resolved, root, state.project, name)
|
|
499
538
|
members.append(
|
|
500
|
-
{"name": name, "checkout": str(resolved), "remote": remote, "integration": integration
|
|
539
|
+
{"name": name, "checkout": str(resolved), "remote": remote, "integration": integration,
|
|
540
|
+
"default_branch": default}
|
|
501
541
|
)
|
|
502
542
|
_write_marker(resolved, root, state.project, name)
|
|
503
543
|
_common.atomic_write(root / ".project" / MEMBERS_FILE, render(members))
|
|
@@ -558,8 +598,9 @@ def create_member(repo: Path, name: str, checkout: Path, integration: str, githu
|
|
|
558
598
|
_common.atomic_write(journal, json.dumps(recorded, indent=2, sort_keys=True) + "\n")
|
|
559
599
|
listed = [member for member in read_members(root) if member["name"] == name]
|
|
560
600
|
if listed:
|
|
561
|
-
if (len(listed) != 1 or listed[0]
|
|
562
|
-
|
|
601
|
+
if (len(listed) != 1 or {**listed[0], "default_branch": default_branch(listed[0])} != {
|
|
602
|
+
"name": name, "checkout": str(resolved), "remote": url,
|
|
603
|
+
"integration": integration, "default_branch": "main"}
|
|
563
604
|
or member_role(resolved) != {"coordinator": root, "project": state.project, "name": name}):
|
|
564
605
|
raise MembersError(f"member already recorded with a different checkout or marker: {name}")
|
|
565
606
|
journal.unlink()
|
|
@@ -608,6 +649,10 @@ def create_member(repo: Path, name: str, checkout: Path, integration: str, githu
|
|
|
608
649
|
cloned = _common.run_git(resolved.parent, "clone", "-q", url, str(resolved))
|
|
609
650
|
if cloned.returncode != 0:
|
|
610
651
|
raise MembersError(f"could not clone {url}: {(cloned.stderr or cloned.stdout).strip()}")
|
|
652
|
+
# ponytail: --create stays main-only, because a new repository uses main;
|
|
653
|
+
# `add` joins an existing repository with any default branch.
|
|
654
|
+
if _common.origin_default_branch(resolved) != "main":
|
|
655
|
+
raise MembersError(f"member remote default must be main: {resolved}")
|
|
611
656
|
recorded["step"] = "join"
|
|
612
657
|
_common.atomic_write(journal, json.dumps(recorded, indent=2, sort_keys=True) + "\n")
|
|
613
658
|
joined = add_member(root, name, resolved, integration)
|
|
@@ -620,7 +665,7 @@ def validate_members(repo: Path) -> list[dict[str, str]]:
|
|
|
620
665
|
members = read_members(root)
|
|
621
666
|
for member in members:
|
|
622
667
|
checkout = Path(member["checkout"])
|
|
623
|
-
check_member(root, state.project, checkout, member
|
|
668
|
+
check_member(root, state.project, checkout, member, refuse_reserved_refs=False)
|
|
624
669
|
try:
|
|
625
670
|
role = member_role(checkout)
|
|
626
671
|
except MembersError as error:
|
|
@@ -639,7 +684,7 @@ def repair_members(repo: Path) -> list[dict[str, str]]:
|
|
|
639
684
|
members = read_members(root)
|
|
640
685
|
for member in members:
|
|
641
686
|
checkout = Path(member["checkout"])
|
|
642
|
-
check_member(root, state.project, checkout, member
|
|
687
|
+
check_member(root, state.project, checkout, member, refuse_reserved_refs=False)
|
|
643
688
|
_refuse_foreign_marker(checkout.resolve(), root, state.project, member["name"])
|
|
644
689
|
for member in members:
|
|
645
690
|
checkout = Path(member["checkout"]).resolve()
|
package/scripts/migrate_core.py
CHANGED
package/scripts/model_policy.py
CHANGED
|
@@ -202,7 +202,11 @@ def native_record(args):
|
|
|
202
202
|
identity = {'repo': str(args.repo.resolve()), 'project_dir': args.project_dir,
|
|
203
203
|
'scope': args.scope, 'assignment': args.assignment, 'role': args.role}
|
|
204
204
|
if data is not None and data.get('identity') != identity:
|
|
205
|
-
|
|
205
|
+
recorded = data.get('identity')
|
|
206
|
+
recorded = recorded if isinstance(recorded, dict) else {}
|
|
207
|
+
differing = ', '.join(f'{field}: {value}, record has {recorded.get(field)}'
|
|
208
|
+
for field, value in identity.items() if recorded.get(field) != value)
|
|
209
|
+
raise PolicyError(f'record belongs to another assignment or milestone/track/cycle ({differing})')
|
|
206
210
|
if args.action == 'release':
|
|
207
211
|
if data is None or not args.terminal_result:
|
|
208
212
|
raise PolicyError('release requires an existing record and terminal-result evidence')
|
package/scripts/path_config.py
CHANGED
|
@@ -13,7 +13,7 @@ sys.dont_write_bytecode = True
|
|
|
13
13
|
ROLES = ('coder', 'reviewer', 'review_panel', 'skeptic', 'inspect_codebase',
|
|
14
14
|
'inspect_docs', 'docs_audit', 'research', 'decide', 'roadmap', 'plan', 'plan_patch')
|
|
15
15
|
HOSTS = ('codex', 'claude', 'grok', 'opencode', 'copilot', 'qwen', 'antigravity',
|
|
16
|
-
'cursor', 'zed', 'kiro', 'kimi')
|
|
16
|
+
'cursor', 'zed', 'kiro', 'kimi', 'muse')
|
|
17
17
|
|
|
18
18
|
|
|
19
19
|
def sibling(name):
|
|
@@ -73,8 +73,8 @@ def validate_value(key, value):
|
|
|
73
73
|
if not isinstance(value, str) or not value or value != value.strip():
|
|
74
74
|
raise ValueError(f'{key} requires a nonempty string')
|
|
75
75
|
if key == 'integration':
|
|
76
|
-
if value not in ('direct', 'pull-request'):
|
|
77
|
-
raise ValueError('integration must be direct or
|
|
76
|
+
if value not in ('direct', 'pull-request', 'external-landing'):
|
|
77
|
+
raise ValueError('integration must be direct, pull-request, or external-landing')
|
|
78
78
|
elif key == 'review_panel':
|
|
79
79
|
if any(char.isspace() for char in value):
|
|
80
80
|
raise ValueError('use off, detected, or comma-separated families without spaces')
|
|
@@ -13,6 +13,7 @@ import json
|
|
|
13
13
|
import os
|
|
14
14
|
import shlex
|
|
15
15
|
import sys
|
|
16
|
+
import traceback
|
|
16
17
|
|
|
17
18
|
# Runtime helpers must not modify their immutable installation.
|
|
18
19
|
sys.dont_write_bytecode = True
|
|
@@ -86,7 +87,7 @@ def _load_diagnose_modules():
|
|
|
86
87
|
pipeline_git,
|
|
87
88
|
pipeline_state,
|
|
88
89
|
)
|
|
89
|
-
except
|
|
90
|
+
except ImportError as error: # a foreign `scripts` package
|
|
90
91
|
if error.name not in {
|
|
91
92
|
"scripts",
|
|
92
93
|
"scripts.archive_milestone",
|
|
@@ -98,6 +99,13 @@ def _load_diagnose_modules():
|
|
|
98
99
|
"scripts.pipeline_state",
|
|
99
100
|
}:
|
|
100
101
|
raise
|
|
102
|
+
# A plain ImportError raised while a `scripts` module loaded is not a
|
|
103
|
+
# foreign package. A missing module falls back, as before.
|
|
104
|
+
if not isinstance(error, ModuleNotFoundError) and any(
|
|
105
|
+
frame.f_globals.get("__name__", "").startswith("scripts.")
|
|
106
|
+
for frame, _ in traceback.walk_tb(error.__traceback__)
|
|
107
|
+
):
|
|
108
|
+
raise
|
|
101
109
|
shared = Path(__file__).resolve().parents[2] / "gsd-path" / "scripts"
|
|
102
110
|
sys.path.insert(0, str(shared))
|
|
103
111
|
import archive_milestone
|
|
@@ -147,9 +155,16 @@ else:
|
|
|
147
155
|
raise
|
|
148
156
|
try:
|
|
149
157
|
from scripts import pipeline_undo
|
|
150
|
-
except
|
|
158
|
+
except ImportError as error: # a foreign `scripts` package
|
|
151
159
|
if error.name not in {"scripts", "scripts.pipeline_undo"}:
|
|
152
160
|
raise
|
|
161
|
+
# A plain ImportError raised while a `scripts` module loaded is not a
|
|
162
|
+
# foreign package. A missing module falls back, as before.
|
|
163
|
+
if not isinstance(error, ModuleNotFoundError) and any(
|
|
164
|
+
frame.f_globals.get("__name__", "").startswith("scripts.")
|
|
165
|
+
for frame, _ in traceback.walk_tb(error.__traceback__)
|
|
166
|
+
):
|
|
167
|
+
raise
|
|
153
168
|
shared = Path(__file__).resolve().parents[2] / "gsd-path" / "scripts"
|
|
154
169
|
if str(shared) not in sys.path:
|
|
155
170
|
sys.path.insert(0, str(shared))
|