@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
|
@@ -91,7 +91,7 @@ STATE_FIELDS = (
|
|
|
91
91
|
"integration_source",
|
|
92
92
|
)
|
|
93
93
|
LEGACY_STATE_FIELDS = STATE_FIELDS[:7]
|
|
94
|
-
INTEGRATION_MODES = ("direct", "pull-request")
|
|
94
|
+
INTEGRATION_MODES = ("direct", "pull-request", "external-landing")
|
|
95
95
|
INTEGRATION_SOURCES = ("default", "milestone")
|
|
96
96
|
NULL = "null"
|
|
97
97
|
SLUG_RE = re.compile(r"^[a-z0-9][a-z0-9-]*$")
|
|
@@ -141,6 +141,8 @@ CROSS_PHASE_TRANSITIONS = {
|
|
|
141
141
|
("decide", "done", "plan", "active"),
|
|
142
142
|
("roadmap", "done", "define", "active"),
|
|
143
143
|
("plan", "done", "build", "active"),
|
|
144
|
+
("plan", "active", "define", "active"),
|
|
145
|
+
("plan", "blocked", "define", "active"),
|
|
144
146
|
("build", "blocked", "define", "active"),
|
|
145
147
|
("build", "blocked", "plan", "active"),
|
|
146
148
|
("build", "active", "ship", "active"),
|
|
@@ -171,9 +173,14 @@ class PipelineState:
|
|
|
171
173
|
integration_default: str
|
|
172
174
|
integration: str
|
|
173
175
|
integration_source: str
|
|
176
|
+
default_branch: str = "main"
|
|
174
177
|
|
|
175
178
|
def json(self) -> dict[str, Optional[str]]:
|
|
176
|
-
|
|
179
|
+
# ponytail: default_branch stays out of this payload; guard_hook, install
|
|
180
|
+
# and the daemon probe accept only the closed STATE_FIELDS set.
|
|
181
|
+
payload = asdict(self)
|
|
182
|
+
del payload["default_branch"]
|
|
183
|
+
return payload
|
|
177
184
|
|
|
178
185
|
|
|
179
186
|
@dataclass(frozen=True)
|
|
@@ -193,11 +200,24 @@ def _run_git(
|
|
|
193
200
|
*arguments: str,
|
|
194
201
|
check: bool = True,
|
|
195
202
|
) -> subprocess.CompletedProcess[str]:
|
|
203
|
+
command = _common.git_command(repo, *arguments)
|
|
196
204
|
result = subprocess.run(
|
|
197
|
-
|
|
205
|
+
command,
|
|
198
206
|
capture_output=True,
|
|
199
207
|
encoding="utf-8", errors="replace",
|
|
200
208
|
)
|
|
209
|
+
if (
|
|
210
|
+
check
|
|
211
|
+
and result.returncode != 0
|
|
212
|
+
and arguments
|
|
213
|
+
and arguments[0] == "commit"
|
|
214
|
+
and _common.git_index_lock_retryable(result.stderr)
|
|
215
|
+
):
|
|
216
|
+
result = subprocess.run(
|
|
217
|
+
command,
|
|
218
|
+
capture_output=True,
|
|
219
|
+
encoding="utf-8", errors="replace",
|
|
220
|
+
)
|
|
201
221
|
if check and result.returncode != 0:
|
|
202
222
|
detail = result.stderr.strip() or result.stdout.strip()
|
|
203
223
|
raise PipelineStateError(f"git {' '.join(arguments)} failed: {detail}")
|
|
@@ -275,7 +295,7 @@ def _bound_branch_number(value: str) -> Optional[int]:
|
|
|
275
295
|
def _state_from_text(text: str, label: str = "STATE.md") -> PipelineState:
|
|
276
296
|
values = _parse_frontmatter(text, label)
|
|
277
297
|
missing = [field for field in LEGACY_STATE_FIELDS if field not in values]
|
|
278
|
-
extra = sorted(set(values) - set(STATE_FIELDS))
|
|
298
|
+
extra = sorted(set(values) - set(STATE_FIELDS) - {"default_branch"})
|
|
279
299
|
if missing:
|
|
280
300
|
raise PipelineStateError(f"{label} is missing fields: {', '.join(missing)}")
|
|
281
301
|
if extra:
|
|
@@ -307,6 +327,7 @@ def _state_from_text(text: str, label: str = "STATE.md") -> PipelineState:
|
|
|
307
327
|
integration_default=integration_default,
|
|
308
328
|
integration=integration,
|
|
309
329
|
integration_source=integration_source,
|
|
330
|
+
default_branch=values.get("default_branch", "main"),
|
|
310
331
|
)
|
|
311
332
|
_validate_state_values(state, label)
|
|
312
333
|
return state
|
|
@@ -340,6 +361,10 @@ def _validate_state_values(state: PipelineState, label: str) -> None:
|
|
|
340
361
|
raise PipelineStateError(
|
|
341
362
|
f"{label} default-sourced integration must match integration_default"
|
|
342
363
|
)
|
|
364
|
+
if not _common.valid_default_branch(state.default_branch):
|
|
365
|
+
raise PipelineStateError(
|
|
366
|
+
f"{label} has invalid default_branch: {state.default_branch}"
|
|
367
|
+
)
|
|
343
368
|
if state.branch is not None and _bound_branch_number(state.branch) is None:
|
|
344
369
|
raise PipelineStateError(f"{label} has invalid branch: {state.branch}")
|
|
345
370
|
archive_match = ARCHIVE_RE.fullmatch(state.archive or "")
|
|
@@ -401,6 +426,7 @@ def validate_state(repo: Path, project_dir: str = ".project") -> dict[str, objec
|
|
|
401
426
|
"status": "valid",
|
|
402
427
|
"path": str(path),
|
|
403
428
|
"state": state.json(),
|
|
429
|
+
"default_branch": state.default_branch,
|
|
404
430
|
}
|
|
405
431
|
|
|
406
432
|
|
|
@@ -683,8 +709,10 @@ def status_state(repo: Path, project_dir: str = ".project") -> dict[str, object]
|
|
|
683
709
|
if branch
|
|
684
710
|
else None
|
|
685
711
|
)
|
|
712
|
+
# The key keeps its name for status consumers; the ref follows STATE.
|
|
713
|
+
default_branch = load_state(resolved, project_dir)[0].default_branch
|
|
686
714
|
origin_main = (
|
|
687
|
-
_optional_rev(resolved, "refs/remotes/origin/
|
|
715
|
+
_optional_rev(resolved, f"refs/remotes/origin/{default_branch}") if has_git else None
|
|
688
716
|
)
|
|
689
717
|
pending, pending_error = _pending_answers(resolved)
|
|
690
718
|
lookahead = resolved / ".project" / "next"
|
|
@@ -707,6 +735,7 @@ def status_state(repo: Path, project_dir: str = ".project") -> dict[str, object]
|
|
|
707
735
|
"advance": False,
|
|
708
736
|
"completion": completion,
|
|
709
737
|
"state": state,
|
|
738
|
+
"default_branch": default_branch,
|
|
710
739
|
"route": route,
|
|
711
740
|
"path": str(_track_root(resolved, project_dir) / "STATE.md"),
|
|
712
741
|
"git": {
|
|
@@ -866,7 +895,12 @@ def _route_result(
|
|
|
866
895
|
route["phase"] = phase
|
|
867
896
|
if mode is not None:
|
|
868
897
|
route["mode"] = mode
|
|
869
|
-
return {
|
|
898
|
+
return {
|
|
899
|
+
"schema": ROUTE_SCHEMA,
|
|
900
|
+
"state": state.json(),
|
|
901
|
+
"default_branch": state.default_branch,
|
|
902
|
+
"route": route,
|
|
903
|
+
}
|
|
870
904
|
|
|
871
905
|
|
|
872
906
|
def _legacy_bind_next_landing(repo: Path, state: PipelineState) -> str:
|
|
@@ -911,36 +945,13 @@ def _legacy_bind_next_landing(repo: Path, state: PipelineState) -> str:
|
|
|
911
945
|
return landing
|
|
912
946
|
|
|
913
947
|
|
|
914
|
-
def
|
|
948
|
+
def _bind_next_journal_recovery(
|
|
915
949
|
repo: Path,
|
|
916
950
|
state: PipelineState,
|
|
951
|
+
path: Path,
|
|
952
|
+
transaction: dict[str, object],
|
|
953
|
+
current: Optional[str],
|
|
917
954
|
) -> Optional[dict[str, object]]:
|
|
918
|
-
journal_root = _git_path(repo, BIND_NEXT_JOURNAL_DIR)
|
|
919
|
-
if not journal_root.exists() and not journal_root.is_symlink():
|
|
920
|
-
return None
|
|
921
|
-
if journal_root.is_symlink() or not journal_root.is_dir():
|
|
922
|
-
raise PipelineStateError(f"bind-next journal root must be a real directory: {journal_root}")
|
|
923
|
-
|
|
924
|
-
matches: list[tuple[Path, dict[str, object]]] = []
|
|
925
|
-
for path in sorted(journal_root.glob("*.json")):
|
|
926
|
-
transaction = _read_json(path)
|
|
927
|
-
if transaction.get("schema") not in {
|
|
928
|
-
LEGACY_BIND_NEXT_JOURNAL_SCHEMA,
|
|
929
|
-
BIND_NEXT_JOURNAL_SCHEMA,
|
|
930
|
-
}:
|
|
931
|
-
raise PipelineStateError(f"bind-next journal has invalid schema: {path}")
|
|
932
|
-
if transaction.get("repo") != str(repo):
|
|
933
|
-
raise PipelineStateError(f"bind-next journal belongs to another worktree: {path}")
|
|
934
|
-
if transaction.get("previous_branch") == state.branch:
|
|
935
|
-
matches.append((path, transaction))
|
|
936
|
-
if not matches:
|
|
937
|
-
return None
|
|
938
|
-
if len(matches) != 1:
|
|
939
|
-
raise PipelineStateError("multiple bind-next journals claim the current STATE branch")
|
|
940
|
-
if state.phase != "shipped" or state.status != "done":
|
|
941
|
-
raise PipelineStateError("bind-next journal requires STATE shipped/done")
|
|
942
|
-
|
|
943
|
-
path, transaction = matches[0]
|
|
944
955
|
required = (
|
|
945
956
|
"branch",
|
|
946
957
|
"previous_branch",
|
|
@@ -1017,12 +1028,37 @@ def _bind_next_recovery(
|
|
|
1017
1028
|
raise PipelineStateError("bind-next journal landing does not contain ship")
|
|
1018
1029
|
if not _is_ancestor(repo, landing, base):
|
|
1019
1030
|
raise PipelineStateError("bind-next journal landing is not an ancestor of base")
|
|
1020
|
-
if transaction["remote_default"] != "origin/
|
|
1031
|
+
if transaction["remote_default"] != f"origin/{state.default_branch}":
|
|
1021
1032
|
raise PipelineStateError("bind-next journal has invalid remote default")
|
|
1022
1033
|
if stage not in {"prepared", "switched", "retired"}:
|
|
1023
1034
|
raise PipelineStateError("bind-next journal has invalid stage")
|
|
1024
1035
|
|
|
1025
|
-
|
|
1036
|
+
stale_retired = False
|
|
1037
|
+
if stage == "retired":
|
|
1038
|
+
target_ref = _run_git(
|
|
1039
|
+
repo,
|
|
1040
|
+
"show-ref",
|
|
1041
|
+
"--verify",
|
|
1042
|
+
"--quiet",
|
|
1043
|
+
f"refs/heads/{branch}",
|
|
1044
|
+
check=False,
|
|
1045
|
+
)
|
|
1046
|
+
if target_ref.returncode not in {0, 1}:
|
|
1047
|
+
detail = (target_ref.stderr or target_ref.stdout).strip()
|
|
1048
|
+
raise PipelineStateError(
|
|
1049
|
+
f"could not check bind-next target branch {branch}: {detail}"
|
|
1050
|
+
)
|
|
1051
|
+
target_exists = target_ref.returncode == 0
|
|
1052
|
+
stale_retired = current not in {previous, branch} or not target_exists
|
|
1053
|
+
if stale_retired:
|
|
1054
|
+
# If the completed target is gone while the previous branch is checked
|
|
1055
|
+
# out, still prove that branch has not moved away from the recorded ship.
|
|
1056
|
+
if current == previous:
|
|
1057
|
+
head = _run_git(repo, "rev-parse", "HEAD").stdout.strip()
|
|
1058
|
+
if head != ship:
|
|
1059
|
+
raise PipelineStateError("bind-next previous branch is not at journal ship")
|
|
1060
|
+
return None
|
|
1061
|
+
|
|
1026
1062
|
if current not in {previous, branch}:
|
|
1027
1063
|
raise PipelineStateError("bind-next journal does not own the current branch")
|
|
1028
1064
|
if current == previous and stage != "prepared":
|
|
@@ -1057,6 +1093,52 @@ def _bind_next_recovery(
|
|
|
1057
1093
|
return result
|
|
1058
1094
|
|
|
1059
1095
|
|
|
1096
|
+
def _bind_next_recovery(
|
|
1097
|
+
repo: Path,
|
|
1098
|
+
state: PipelineState,
|
|
1099
|
+
) -> Optional[dict[str, object]]:
|
|
1100
|
+
journal_root = _git_path(repo, BIND_NEXT_JOURNAL_DIR)
|
|
1101
|
+
if not journal_root.exists() and not journal_root.is_symlink():
|
|
1102
|
+
return None
|
|
1103
|
+
if journal_root.is_symlink() or not journal_root.is_dir():
|
|
1104
|
+
raise PipelineStateError(f"bind-next journal root must be a real directory: {journal_root}")
|
|
1105
|
+
|
|
1106
|
+
matches: list[tuple[Path, dict[str, object]]] = []
|
|
1107
|
+
for path in sorted(journal_root.glob("*.json")):
|
|
1108
|
+
transaction = _read_json(path)
|
|
1109
|
+
if transaction.get("schema") not in {
|
|
1110
|
+
LEGACY_BIND_NEXT_JOURNAL_SCHEMA,
|
|
1111
|
+
BIND_NEXT_JOURNAL_SCHEMA,
|
|
1112
|
+
}:
|
|
1113
|
+
raise PipelineStateError(f"bind-next journal has invalid schema: {path}")
|
|
1114
|
+
if transaction.get("repo") != str(repo):
|
|
1115
|
+
raise PipelineStateError(f"bind-next journal belongs to another worktree: {path}")
|
|
1116
|
+
if transaction.get("previous_branch") == state.branch:
|
|
1117
|
+
matches.append((path, transaction))
|
|
1118
|
+
if not matches:
|
|
1119
|
+
return None
|
|
1120
|
+
if state.phase != "shipped" or state.status != "done":
|
|
1121
|
+
if len(matches) != 1:
|
|
1122
|
+
raise PipelineStateError("multiple bind-next journals claim the current STATE branch")
|
|
1123
|
+
raise PipelineStateError("bind-next journal requires STATE shipped/done")
|
|
1124
|
+
|
|
1125
|
+
current = _current_branch(repo)
|
|
1126
|
+
recoveries: list[dict[str, object]] = []
|
|
1127
|
+
for path, transaction in matches:
|
|
1128
|
+
recovery = _bind_next_journal_recovery(
|
|
1129
|
+
repo,
|
|
1130
|
+
state,
|
|
1131
|
+
path,
|
|
1132
|
+
transaction,
|
|
1133
|
+
current,
|
|
1134
|
+
)
|
|
1135
|
+
if recovery is not None:
|
|
1136
|
+
recoveries.append(recovery)
|
|
1137
|
+
if len(recoveries) > 1:
|
|
1138
|
+
raise PipelineStateError("multiple bind-next journals claim the current STATE branch")
|
|
1139
|
+
return recoveries[0] if recoveries else None
|
|
1140
|
+
|
|
1141
|
+
|
|
1060
1142
|
def _pending_discussion_block(repo: Path, phase: Optional[str]) -> Optional[str]:
|
|
1061
1143
|
pending, error = _pending_answers(repo)
|
|
1062
1144
|
if error:
|
|
@@ -1077,7 +1159,7 @@ def route_state(repo: Path, project_dir: str = ".project") -> dict[str, object]:
|
|
|
1077
1159
|
result["recovery"] = recovery
|
|
1078
1160
|
if route.get("phase") == "define":
|
|
1079
1161
|
route["mode"] = "corrections"
|
|
1080
|
-
elif route.get("phase") == "plan":
|
|
1162
|
+
elif route.get("phase") == "plan" and recovery.get("source", "build") == "build":
|
|
1081
1163
|
route["mode"] = "build-repair"
|
|
1082
1164
|
if route["action"] == "run-phase" and result["state"]["archive"] is None:
|
|
1083
1165
|
reason = _pending_discussion_block(_repo_root(repo), route.get("phase"))
|
|
@@ -1668,6 +1750,8 @@ def _validate_transition(
|
|
|
1668
1750
|
},
|
|
1669
1751
|
("define", "done", "plan", "active"): {"planning started"},
|
|
1670
1752
|
("decide", "done", "plan", "active"): {"planning started"},
|
|
1753
|
+
("plan", "active", "define", "active"): {"plan intent corrections requested"},
|
|
1754
|
+
("plan", "blocked", "define", "active"): {"plan intent corrections requested"},
|
|
1671
1755
|
("ship", "blocked", "plan", "active"): {"patch plan reopened"},
|
|
1672
1756
|
("ship", "active", "shipped", "done"): {
|
|
1673
1757
|
"archive preflight passed; shipment recorded",
|
|
@@ -1693,7 +1777,10 @@ def transition_state(
|
|
|
1693
1777
|
if unsupported:
|
|
1694
1778
|
raise PipelineStateError(f"unsupported state fields: {', '.join(sorted(unsupported))}")
|
|
1695
1779
|
if not changes:
|
|
1696
|
-
raise PipelineStateError(
|
|
1780
|
+
raise PipelineStateError(
|
|
1781
|
+
"transition requires at least one changed field; "
|
|
1782
|
+
"to record only a Log event, pass --set-status with the current status"
|
|
1783
|
+
)
|
|
1697
1784
|
required_expected = {"phase", "status", "branch", "archive"} | set(changes)
|
|
1698
1785
|
missing_expected = sorted(required_expected - set(expected))
|
|
1699
1786
|
if missing_expected:
|
|
@@ -1720,9 +1807,10 @@ def transition_state(
|
|
|
1720
1807
|
)
|
|
1721
1808
|
if reason:
|
|
1722
1809
|
raise PipelineStateError(reason)
|
|
1723
|
-
|
|
1810
|
+
leaving_define = (state.phase, after.phase, after.status) == ("define", "define", "done")
|
|
1811
|
+
if leaving_define or (state.phase in {"research", "decide"} and (
|
|
1724
1812
|
after.phase != state.phase or after.status == "done"
|
|
1725
|
-
):
|
|
1813
|
+
)):
|
|
1726
1814
|
if __package__:
|
|
1727
1815
|
from . import check_handoffs
|
|
1728
1816
|
else:
|
|
@@ -1731,6 +1819,8 @@ def transition_state(
|
|
|
1731
1819
|
except ImportError: # pragma: no cover - package imports used by tests
|
|
1732
1820
|
from scripts import check_handoffs
|
|
1733
1821
|
validator = {
|
|
1822
|
+
# Approved intent carries its spec-reach probe tables complete.
|
|
1823
|
+
"define": check_handoffs.validate_intent_probes,
|
|
1734
1824
|
"research": check_handoffs.validate_research_artifacts,
|
|
1735
1825
|
"decide": check_handoffs.validate_decide_artifacts,
|
|
1736
1826
|
}[state.phase]
|
|
@@ -1747,6 +1837,16 @@ def transition_state(
|
|
|
1747
1837
|
rendered, after.phase,
|
|
1748
1838
|
_build_recovery().MARKER + json.dumps(recovery, sort_keys=True),
|
|
1749
1839
|
)
|
|
1840
|
+
elif (
|
|
1841
|
+
state.phase == "plan"
|
|
1842
|
+
and state.status in {"active", "blocked"}
|
|
1843
|
+
and (after.phase, after.status) == ("define", "active")
|
|
1844
|
+
):
|
|
1845
|
+
recovery = _build_recovery().begin(resolved, state, after, event)
|
|
1846
|
+
rendered = _append_event(
|
|
1847
|
+
rendered, after.phase,
|
|
1848
|
+
_build_recovery().MARKER + json.dumps(recovery, sort_keys=True),
|
|
1849
|
+
)
|
|
1750
1850
|
_atomic_write(path, rendered)
|
|
1751
1851
|
return {
|
|
1752
1852
|
"schema": STATE_SCHEMA,
|
|
@@ -198,10 +198,10 @@ def select_fetched_base(
|
|
|
198
198
|
use_lookahead: bool,
|
|
199
199
|
) -> dict:
|
|
200
200
|
root = repo.resolve()
|
|
201
|
-
if not
|
|
201
|
+
if not remote_default.startswith("origin/") or not _common.valid_default_branch(
|
|
202
|
+
remote_default.removeprefix("origin/")
|
|
203
|
+
):
|
|
202
204
|
raise LookaheadError("remote default must be an origin branch")
|
|
203
|
-
if ".." in remote_default or "//" in remote_default:
|
|
204
|
-
raise LookaheadError("remote default is invalid")
|
|
205
205
|
resolved = subprocess.run(
|
|
206
206
|
["git", "-C", str(root), "rev-parse", "--verify", f"{remote_default}^{{commit}}"],
|
|
207
207
|
capture_output=True,
|