@opengsd/gsd-path 1.0.0 → 1.2.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/AGENTS.md +33 -13
- package/CHANGELOG.md +68 -0
- package/DOCS.md +75 -6
- package/FULL.md +12 -15
- package/HOOKS.md +18 -9
- package/QUICK.md +8 -6
- package/README.md +218 -14
- package/RUNTIME.md +16 -5
- package/UPDATE.md +30 -11
- package/WORKFLOW.md +35 -16
- package/package.json +23 -1
- package/platforms/claude/dispatch.md +4 -4
- package/platforms/copilot/dispatch.md +4 -4
- package/platforms/cursor/dispatch.md +5 -10
- package/platforms/grok/dispatch.md +4 -6
- package/platforms/kimi/dispatch.md +4 -4
- package/platforms/kiro/dispatch.md +4 -6
- package/platforms/opencode/dispatch.md +4 -4
- package/platforms/qwen/dispatch.md +4 -4
- package/platforms/shared-agents/dispatch.md +12 -19
- package/scripts/_common.py +5 -0
- package/scripts/archive_milestone.py +30 -124
- package/scripts/bootstrap_repository.py +33 -4
- package/scripts/build_recovery.py +292 -0
- package/scripts/build_state.py +2 -0
- package/scripts/check_docs_audit.py +7 -3
- package/scripts/check_handoffs.py +7 -1
- package/scripts/check_task_briefs.py +3 -0
- package/scripts/detect_project.py +22 -3
- package/scripts/discussion_records.py +3 -0
- package/scripts/discussion_validate.py +8 -3
- package/scripts/dispatch_driver.py +233 -22
- package/scripts/git_guard.py +14 -5
- package/scripts/guard_hook.py +11 -1
- package/scripts/install.mjs +54 -1448
- package/scripts/install.py +155 -188
- package/scripts/integration.py +54 -28
- package/scripts/isolation.py +24 -6
- package/scripts/jev_review.py +138 -0
- package/scripts/lean_verification.py +3 -1
- package/scripts/loop_run.py +2 -0
- package/scripts/model_policy.py +279 -0
- package/scripts/path_config.py +248 -0
- package/scripts/pipeline_diagnose.py +15 -3
- package/scripts/pipeline_git.py +3 -0
- package/scripts/pipeline_state.py +117 -186
- package/scripts/pipeline_undo.py +14 -7
- package/scripts/promote_lookahead.py +33 -162
- package/scripts/review_panel.py +11 -0
- package/scripts/roadmap.py +326 -0
- package/scripts/runtime_store.py +278 -0
- package/scripts/skill-resources.json +182 -4
- package/scripts/state_checkpoint.py +114 -72
- package/scripts/state_promote.py +47 -44
- package/scripts/status_runtime.py +92 -6
- package/scripts/task_context.py +73 -0
- package/scripts/token_budget.py +40 -1
- package/scripts/workflow_run.py +128 -8
- package/scripts/worktree_paths.py +94 -0
- package/skills/gsd-path/BUILD.md +54 -575
- package/skills/gsd-path/DECIDE.md +4 -6
- package/skills/gsd-path/DEFINE.md +23 -21
- package/skills/gsd-path/DOCS-AUDIT.md +2 -0
- package/skills/gsd-path/INSPECT.md +32 -8
- package/skills/gsd-path/PLAN.md +29 -19
- package/skills/gsd-path/RESEARCH.md +5 -6
- package/skills/gsd-path/ROADMAP.md +24 -58
- package/skills/gsd-path/SHIP.md +29 -17
- package/skills/gsd-path/SKILL.md +46 -22
- package/skills/gsd-path/references/build-abandon.md +33 -0
- package/skills/gsd-path/references/build-native.md +502 -0
- package/skills/gsd-path/references/build-recovery.md +78 -0
- package/skills/gsd-path/references/coder.md +8 -3
- package/skills/gsd-path/references/config.md +57 -0
- package/skills/gsd-path/references/dispatch.md +12 -19
- package/skills/gsd-path/references/docs-auditor.md +14 -0
- package/skills/gsd-path/references/jev-review.md +82 -0
- package/skills/gsd-path/references/model-policy.md +139 -0
- package/skills/gsd-path/references/reviewer-final.md +21 -0
- package/skills/gsd-path/references/reviewer-panel.md +17 -0
- package/skills/gsd-path/references/reviewer-skeptic.md +20 -0
- package/skills/gsd-path/references/reviewer-wave.md +89 -0
- package/skills/gsd-path/references/reviewer.md +12 -148
- package/skills/gsd-path/references/runtime-selection.md +25 -0
- 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/scripts/_common.py +5 -0
- package/skills/gsd-path/scripts/archive_milestone.py +30 -124
- package/skills/gsd-path/scripts/bootstrap_repository.py +33 -4
- package/skills/gsd-path/scripts/build_recovery.py +292 -0
- package/skills/gsd-path/scripts/build_state.py +2 -0
- package/skills/gsd-path/scripts/check_docs_audit.py +7 -3
- package/skills/gsd-path/scripts/check_handoffs.py +7 -1
- package/skills/gsd-path/scripts/check_task_briefs.py +3 -0
- package/skills/gsd-path/scripts/detect_project.py +22 -3
- package/skills/gsd-path/scripts/discussion_records.py +3 -0
- package/skills/gsd-path/scripts/discussion_validate.py +8 -3
- package/skills/gsd-path/scripts/dispatch_driver.py +233 -22
- package/skills/gsd-path/scripts/git_guard.py +768 -0
- package/skills/gsd-path/scripts/integration.py +54 -28
- package/skills/gsd-path/scripts/isolation.py +24 -6
- package/skills/gsd-path/scripts/jev_review.py +138 -0
- package/skills/gsd-path/scripts/lean_verification.py +3 -1
- package/skills/gsd-path/scripts/loop_run.py +2 -0
- package/skills/gsd-path/scripts/model_policy.py +279 -0
- package/skills/gsd-path/scripts/path_config.py +248 -0
- package/skills/gsd-path/scripts/pipeline_git.py +3 -0
- package/skills/gsd-path/scripts/pipeline_state.py +117 -186
- package/skills/gsd-path/scripts/promote_lookahead.py +33 -162
- package/skills/gsd-path/scripts/review_panel.py +11 -0
- package/skills/gsd-path/scripts/roadmap.py +326 -0
- package/skills/gsd-path/scripts/state_checkpoint.py +114 -72
- package/skills/gsd-path/scripts/state_promote.py +47 -44
- package/skills/gsd-path/scripts/status_runtime.py +208 -0
- package/skills/gsd-path/scripts/task_context.py +73 -0
- package/skills/gsd-path/scripts/token_budget.py +40 -1
- package/skills/gsd-path/scripts/workflow_run.py +128 -8
- package/skills/gsd-path/scripts/worktree_paths.py +94 -0
- package/skills/gsd-path/templates/skeptic.md +1 -1
- package/skills/gsd-path/templates/task.md +2 -0
- package/skills/gsd-path/templates/wave-panel.md +1 -1
- package/skills/gsd-path/templates/wave-review.md +1 -1
- package/skills/gsd-path-build/SKILL.md +54 -575
- package/skills/gsd-path-build/references/build-abandon.md +33 -0
- package/skills/gsd-path-build/references/build-native.md +502 -0
- package/skills/gsd-path-build/references/build-recovery.md +78 -0
- package/skills/gsd-path-build/references/coder.md +8 -3
- package/skills/gsd-path-build/references/dispatch.md +12 -19
- package/skills/gsd-path-build/references/jev-review.md +82 -0
- package/skills/gsd-path-build/references/model-policy.md +139 -0
- package/skills/gsd-path-build/references/reviewer-final.md +21 -0
- package/skills/gsd-path-build/references/reviewer-panel.md +17 -0
- package/skills/gsd-path-build/references/reviewer-skeptic.md +20 -0
- package/skills/gsd-path-build/references/reviewer-wave.md +89 -0
- package/skills/gsd-path-build/references/reviewer.md +12 -148
- package/skills/gsd-path-build/references/runtime-selection.md +25 -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-build/scripts/_common.py +5 -0
- package/skills/gsd-path-build/scripts/archive_milestone.py +30 -124
- package/skills/gsd-path-build/scripts/build_recovery.py +292 -0
- package/skills/gsd-path-build/scripts/build_state.py +2 -0
- package/skills/gsd-path-build/scripts/check_handoffs.py +7 -1
- package/skills/gsd-path-build/scripts/check_task_briefs.py +3 -0
- package/skills/gsd-path-build/scripts/detect_project.py +1536 -0
- package/skills/gsd-path-build/scripts/discussion_records.py +3 -0
- package/skills/gsd-path-build/scripts/discussion_validate.py +8 -3
- package/skills/gsd-path-build/scripts/dispatch_driver.py +233 -22
- package/skills/gsd-path-build/scripts/integration.py +54 -28
- package/skills/gsd-path-build/scripts/isolation.py +24 -6
- package/skills/gsd-path-build/scripts/jev_review.py +138 -0
- package/skills/gsd-path-build/scripts/loop_run.py +2 -0
- package/skills/gsd-path-build/scripts/model_policy.py +279 -0
- package/skills/gsd-path-build/scripts/path_config.py +248 -0
- package/skills/gsd-path-build/scripts/pipeline_git.py +3 -0
- package/skills/gsd-path-build/scripts/pipeline_state.py +117 -186
- package/skills/gsd-path-build/scripts/promote_lookahead.py +286 -0
- package/skills/gsd-path-build/scripts/review_panel.py +11 -0
- package/skills/gsd-path-build/scripts/roadmap.py +326 -0
- package/skills/gsd-path-build/scripts/state_checkpoint.py +114 -72
- package/skills/gsd-path-build/scripts/state_promote.py +47 -44
- package/skills/gsd-path-build/scripts/task_context.py +73 -0
- package/skills/gsd-path-build/scripts/token_budget.py +40 -1
- package/skills/gsd-path-build/scripts/workflow_run.py +128 -8
- package/skills/gsd-path-build/scripts/worktree_paths.py +94 -0
- package/skills/gsd-path-build/templates/skeptic.md +1 -1
- package/skills/gsd-path-build/templates/task.md +2 -0
- package/skills/gsd-path-build/templates/wave-panel.md +1 -1
- package/skills/gsd-path-build/templates/wave-review.md +1 -1
- package/skills/gsd-path-decide/SKILL.md +4 -6
- package/skills/gsd-path-decide/references/dispatch.md +12 -19
- package/skills/gsd-path-decide/references/model-policy.md +139 -0
- package/skills/gsd-path-decide/references/runtime-selection.md +25 -0
- package/skills/gsd-path-decide/scripts/_common.py +5 -0
- package/skills/gsd-path-decide/scripts/archive_milestone.py +2171 -0
- package/skills/gsd-path-decide/scripts/build_recovery.py +292 -0
- package/skills/gsd-path-decide/scripts/check_handoffs.py +7 -1
- package/skills/gsd-path-decide/scripts/check_task_briefs.py +3 -0
- package/skills/gsd-path-decide/scripts/detect_project.py +1536 -0
- package/skills/gsd-path-decide/scripts/discussion_records.py +3 -0
- package/skills/gsd-path-decide/scripts/discussion_validate.py +1326 -0
- package/skills/gsd-path-decide/scripts/integration.py +1459 -0
- package/skills/gsd-path-decide/scripts/isolation.py +24 -6
- package/skills/gsd-path-decide/scripts/loop_run.py +839 -0
- package/skills/gsd-path-decide/scripts/model_policy.py +279 -0
- package/skills/gsd-path-decide/scripts/path_config.py +248 -0
- package/skills/gsd-path-decide/scripts/pipeline_git.py +3 -0
- package/skills/gsd-path-decide/scripts/pipeline_state.py +117 -186
- package/skills/gsd-path-decide/scripts/promote_lookahead.py +286 -0
- package/skills/gsd-path-decide/scripts/review_panel.py +564 -0
- package/skills/gsd-path-decide/scripts/roadmap.py +326 -0
- package/skills/gsd-path-decide/scripts/state_checkpoint.py +114 -72
- package/skills/gsd-path-decide/scripts/state_promote.py +47 -44
- package/skills/gsd-path-decide/scripts/worktree_paths.py +94 -0
- package/skills/gsd-path-define/SKILL.md +23 -21
- package/skills/gsd-path-define/references/build-recovery.md +78 -0
- package/skills/gsd-path-define/references/runtime-selection.md +25 -0
- package/skills/gsd-path-define/scripts/_common.py +5 -0
- package/skills/gsd-path-define/scripts/archive_milestone.py +2171 -0
- package/skills/gsd-path-define/scripts/build_recovery.py +292 -0
- package/skills/gsd-path-define/scripts/check_handoffs.py +7 -1
- package/skills/gsd-path-define/scripts/check_task_briefs.py +3 -0
- package/skills/gsd-path-define/scripts/detect_project.py +22 -3
- package/skills/gsd-path-define/scripts/discussion_records.py +3 -0
- package/skills/gsd-path-define/scripts/discussion_validate.py +1326 -0
- package/skills/gsd-path-define/scripts/integration.py +1459 -0
- package/skills/gsd-path-define/scripts/isolation.py +24 -6
- package/skills/gsd-path-define/scripts/loop_run.py +839 -0
- package/skills/gsd-path-define/scripts/model_policy.py +279 -0
- package/skills/gsd-path-define/scripts/path_config.py +248 -0
- package/skills/gsd-path-define/scripts/pipeline_git.py +3 -0
- package/skills/gsd-path-define/scripts/pipeline_state.py +117 -186
- package/skills/gsd-path-define/scripts/promote_lookahead.py +286 -0
- package/skills/gsd-path-define/scripts/review_panel.py +564 -0
- package/skills/gsd-path-define/scripts/roadmap.py +326 -0
- package/skills/gsd-path-define/scripts/state_checkpoint.py +114 -72
- package/skills/gsd-path-define/scripts/state_promote.py +47 -44
- package/skills/gsd-path-define/scripts/worktree_paths.py +94 -0
- package/skills/gsd-path-discuss/SKILL.md +2 -0
- package/skills/gsd-path-discuss/references/runtime-selection.md +25 -0
- package/skills/gsd-path-discuss/scripts/_common.py +5 -0
- package/skills/gsd-path-discuss/scripts/discussion_records.py +3 -0
- package/skills/gsd-path-discuss/scripts/loop_run.py +839 -0
- package/skills/gsd-path-discuss/scripts/model_policy.py +279 -0
- package/skills/gsd-path-discuss/scripts/path_config.py +248 -0
- package/skills/gsd-path-discuss/scripts/review_panel.py +564 -0
- package/skills/gsd-path-discuss/scripts/worktree_paths.py +94 -0
- package/skills/gsd-path-docs-audit/SKILL.md +2 -0
- package/skills/gsd-path-docs-audit/references/dispatch.md +12 -19
- package/skills/gsd-path-docs-audit/references/docs-auditor.md +14 -0
- package/skills/gsd-path-docs-audit/references/model-policy.md +139 -0
- package/skills/gsd-path-docs-audit/references/runtime-selection.md +25 -0
- package/skills/gsd-path-docs-audit/scripts/_common.py +5 -0
- package/skills/gsd-path-docs-audit/scripts/archive_milestone.py +2171 -0
- package/skills/gsd-path-docs-audit/scripts/build_recovery.py +292 -0
- package/skills/gsd-path-docs-audit/scripts/check_docs_audit.py +7 -3
- package/skills/gsd-path-docs-audit/scripts/check_handoffs.py +7 -1
- package/skills/gsd-path-docs-audit/scripts/check_task_briefs.py +3 -0
- package/skills/gsd-path-docs-audit/scripts/detect_project.py +1536 -0
- package/skills/gsd-path-docs-audit/scripts/discussion_records.py +3 -0
- package/skills/gsd-path-docs-audit/scripts/discussion_validate.py +1326 -0
- package/skills/gsd-path-docs-audit/scripts/integration.py +1459 -0
- package/skills/gsd-path-docs-audit/scripts/isolation.py +24 -6
- package/skills/gsd-path-docs-audit/scripts/loop_run.py +839 -0
- package/skills/gsd-path-docs-audit/scripts/model_policy.py +279 -0
- package/skills/gsd-path-docs-audit/scripts/path_config.py +248 -0
- package/skills/gsd-path-docs-audit/scripts/pipeline_git.py +3 -0
- package/skills/gsd-path-docs-audit/scripts/pipeline_state.py +117 -186
- package/skills/gsd-path-docs-audit/scripts/promote_lookahead.py +286 -0
- package/skills/gsd-path-docs-audit/scripts/review_panel.py +564 -0
- package/skills/gsd-path-docs-audit/scripts/roadmap.py +326 -0
- package/skills/gsd-path-docs-audit/scripts/state_checkpoint.py +114 -72
- package/skills/gsd-path-docs-audit/scripts/state_promote.py +47 -44
- package/skills/gsd-path-docs-audit/scripts/worktree_paths.py +94 -0
- package/skills/gsd-path-forensics/SKILL.md +9 -5
- package/skills/gsd-path-forensics/references/runtime-selection.md +25 -0
- package/skills/gsd-path-forensics/scripts/_common.py +5 -0
- package/skills/gsd-path-forensics/scripts/discussion_records.py +3 -0
- package/skills/gsd-path-forensics/scripts/loop_run.py +839 -0
- package/skills/gsd-path-forensics/scripts/model_policy.py +279 -0
- package/skills/gsd-path-forensics/scripts/path_config.py +248 -0
- package/skills/gsd-path-forensics/scripts/pipeline_diagnose.py +15 -3
- package/skills/gsd-path-forensics/scripts/pipeline_undo.py +14 -7
- package/skills/gsd-path-forensics/scripts/review_panel.py +564 -0
- package/skills/gsd-path-forensics/scripts/worktree_paths.py +94 -0
- package/skills/gsd-path-inspect/SKILL.md +32 -8
- package/skills/gsd-path-inspect/references/dispatch.md +12 -19
- package/skills/gsd-path-inspect/references/docs-auditor.md +14 -0
- package/skills/gsd-path-inspect/references/model-policy.md +139 -0
- package/skills/gsd-path-inspect/references/runtime-selection.md +25 -0
- package/skills/gsd-path-inspect/scripts/__pycache__/_common.cpython-312.pyc +0 -0
- package/skills/gsd-path-inspect/scripts/_common.py +5 -0
- package/skills/gsd-path-inspect/scripts/archive_milestone.py +2171 -0
- package/skills/gsd-path-inspect/scripts/build_recovery.py +292 -0
- package/skills/gsd-path-inspect/scripts/check_docs_audit.py +7 -3
- package/skills/gsd-path-inspect/scripts/check_handoffs.py +7 -1
- package/skills/gsd-path-inspect/scripts/check_task_briefs.py +3 -0
- package/skills/gsd-path-inspect/scripts/detect_project.py +22 -3
- package/skills/gsd-path-inspect/scripts/discussion_records.py +3 -0
- package/skills/gsd-path-inspect/scripts/discussion_validate.py +1326 -0
- package/skills/gsd-path-inspect/scripts/integration.py +1459 -0
- package/skills/gsd-path-inspect/scripts/isolation.py +24 -6
- package/skills/gsd-path-inspect/scripts/loop_run.py +839 -0
- package/skills/gsd-path-inspect/scripts/model_policy.py +279 -0
- package/skills/gsd-path-inspect/scripts/path_config.py +248 -0
- package/skills/gsd-path-inspect/scripts/pipeline_git.py +3 -0
- package/skills/gsd-path-inspect/scripts/pipeline_state.py +117 -186
- package/skills/gsd-path-inspect/scripts/promote_lookahead.py +286 -0
- package/skills/gsd-path-inspect/scripts/review_panel.py +564 -0
- package/skills/gsd-path-inspect/scripts/roadmap.py +326 -0
- package/skills/gsd-path-inspect/scripts/state_checkpoint.py +114 -72
- package/skills/gsd-path-inspect/scripts/state_promote.py +47 -44
- package/skills/gsd-path-inspect/scripts/workflow_run.py +237 -0
- package/skills/gsd-path-inspect/scripts/worktree_paths.py +94 -0
- package/skills/gsd-path-loop/SKILL.md +2 -0
- package/skills/gsd-path-loop/references/runtime-selection.md +25 -0
- package/skills/gsd-path-loop/scripts/_common.py +5 -0
- package/skills/gsd-path-loop/scripts/discussion_records.py +3 -0
- package/skills/gsd-path-loop/scripts/loop_run.py +2 -0
- package/skills/gsd-path-loop/scripts/model_policy.py +279 -0
- package/skills/gsd-path-loop/scripts/path_config.py +248 -0
- package/skills/gsd-path-loop/scripts/review_panel.py +564 -0
- package/skills/gsd-path-loop/scripts/worktree_paths.py +94 -0
- package/skills/gsd-path-migrate/SKILL.md +2 -0
- package/skills/gsd-path-migrate/references/runtime-selection.md +25 -0
- package/skills/gsd-path-migrate/scripts/_common.py +185 -0
- package/skills/gsd-path-migrate/scripts/discussion_records.py +3 -0
- package/skills/gsd-path-migrate/scripts/loop_run.py +839 -0
- package/skills/gsd-path-migrate/scripts/model_policy.py +279 -0
- package/skills/gsd-path-migrate/scripts/path_config.py +248 -0
- package/skills/gsd-path-migrate/scripts/review_panel.py +564 -0
- package/skills/gsd-path-plan/SKILL.md +29 -19
- package/skills/gsd-path-plan/references/build-recovery.md +78 -0
- package/skills/gsd-path-plan/references/dispatch.md +12 -19
- package/skills/gsd-path-plan/references/model-policy.md +139 -0
- package/skills/gsd-path-plan/references/runtime-selection.md +25 -0
- package/skills/gsd-path-plan/scripts/__pycache__/_common.cpython-312.pyc +0 -0
- package/skills/gsd-path-plan/scripts/_common.py +5 -0
- package/skills/gsd-path-plan/scripts/archive_milestone.py +2171 -0
- package/skills/gsd-path-plan/scripts/build_recovery.py +292 -0
- package/skills/gsd-path-plan/scripts/check_handoffs.py +7 -1
- package/skills/gsd-path-plan/scripts/check_task_briefs.py +3 -0
- package/skills/gsd-path-plan/scripts/detect_project.py +1536 -0
- package/skills/gsd-path-plan/scripts/discussion_records.py +3 -0
- package/skills/gsd-path-plan/scripts/discussion_validate.py +1326 -0
- package/skills/gsd-path-plan/scripts/integration.py +1459 -0
- package/skills/gsd-path-plan/scripts/isolation.py +24 -6
- package/skills/gsd-path-plan/scripts/loop_run.py +839 -0
- package/skills/gsd-path-plan/scripts/model_policy.py +279 -0
- package/skills/gsd-path-plan/scripts/path_config.py +248 -0
- package/skills/gsd-path-plan/scripts/pipeline_git.py +3 -0
- package/skills/gsd-path-plan/scripts/pipeline_state.py +117 -186
- package/skills/gsd-path-plan/scripts/promote_lookahead.py +286 -0
- package/skills/gsd-path-plan/scripts/review_panel.py +11 -0
- package/skills/gsd-path-plan/scripts/roadmap.py +326 -0
- package/skills/gsd-path-plan/scripts/state_checkpoint.py +114 -72
- package/skills/gsd-path-plan/scripts/state_promote.py +47 -44
- package/skills/gsd-path-plan/scripts/workflow_run.py +128 -8
- package/skills/gsd-path-plan/scripts/worktree_paths.py +94 -0
- package/skills/gsd-path-plan/templates/task.md +2 -0
- package/skills/gsd-path-research/SKILL.md +5 -6
- package/skills/gsd-path-research/references/dispatch.md +12 -19
- package/skills/gsd-path-research/references/model-policy.md +139 -0
- package/skills/gsd-path-research/references/runtime-selection.md +25 -0
- package/skills/gsd-path-research/scripts/_common.py +5 -0
- package/skills/gsd-path-research/scripts/archive_milestone.py +2171 -0
- package/skills/gsd-path-research/scripts/build_recovery.py +292 -0
- package/skills/gsd-path-research/scripts/check_handoffs.py +7 -1
- package/skills/gsd-path-research/scripts/check_task_briefs.py +3 -0
- package/skills/gsd-path-research/scripts/detect_project.py +1536 -0
- package/skills/gsd-path-research/scripts/discussion_records.py +3 -0
- package/skills/gsd-path-research/scripts/discussion_validate.py +1326 -0
- package/skills/gsd-path-research/scripts/integration.py +1459 -0
- package/skills/gsd-path-research/scripts/isolation.py +24 -6
- package/skills/gsd-path-research/scripts/loop_run.py +839 -0
- package/skills/gsd-path-research/scripts/model_policy.py +279 -0
- package/skills/gsd-path-research/scripts/path_config.py +248 -0
- package/skills/gsd-path-research/scripts/pipeline_git.py +3 -0
- package/skills/gsd-path-research/scripts/pipeline_state.py +117 -186
- package/skills/gsd-path-research/scripts/promote_lookahead.py +286 -0
- package/skills/gsd-path-research/scripts/review_panel.py +564 -0
- package/skills/gsd-path-research/scripts/roadmap.py +326 -0
- package/skills/gsd-path-research/scripts/state_checkpoint.py +114 -72
- package/skills/gsd-path-research/scripts/state_promote.py +47 -44
- package/skills/gsd-path-research/scripts/worktree_paths.py +94 -0
- package/skills/gsd-path-roadmap/SKILL.md +24 -58
- package/skills/gsd-path-roadmap/references/dispatch.md +12 -19
- package/skills/gsd-path-roadmap/references/model-policy.md +139 -0
- package/skills/gsd-path-roadmap/references/runtime-selection.md +25 -0
- package/skills/gsd-path-roadmap/scripts/_common.py +5 -0
- package/skills/gsd-path-roadmap/scripts/archive_milestone.py +30 -124
- package/skills/gsd-path-roadmap/scripts/build_recovery.py +292 -0
- package/skills/gsd-path-roadmap/scripts/check_handoffs.py +7 -1
- package/skills/gsd-path-roadmap/scripts/check_task_briefs.py +3 -0
- package/skills/gsd-path-roadmap/scripts/detect_project.py +22 -3
- package/skills/gsd-path-roadmap/scripts/discussion_records.py +3 -0
- package/skills/gsd-path-roadmap/scripts/discussion_validate.py +8 -3
- package/skills/gsd-path-roadmap/scripts/integration.py +54 -28
- package/skills/gsd-path-roadmap/scripts/isolation.py +24 -6
- package/skills/gsd-path-roadmap/scripts/loop_run.py +839 -0
- package/skills/gsd-path-roadmap/scripts/model_policy.py +279 -0
- package/skills/gsd-path-roadmap/scripts/path_config.py +248 -0
- package/skills/gsd-path-roadmap/scripts/pipeline_git.py +3 -0
- package/skills/gsd-path-roadmap/scripts/pipeline_state.py +117 -186
- package/skills/gsd-path-roadmap/scripts/promote_lookahead.py +33 -162
- package/skills/gsd-path-roadmap/scripts/review_panel.py +11 -0
- package/skills/gsd-path-roadmap/scripts/roadmap.py +326 -0
- package/skills/gsd-path-roadmap/scripts/state_checkpoint.py +114 -72
- package/skills/gsd-path-roadmap/scripts/state_promote.py +47 -44
- package/skills/gsd-path-roadmap/scripts/worktree_paths.py +94 -0
- package/skills/gsd-path-ship/SKILL.md +29 -17
- package/skills/gsd-path-ship/references/dispatch.md +12 -19
- package/skills/gsd-path-ship/references/jev-review.md +82 -0
- package/skills/gsd-path-ship/references/model-policy.md +139 -0
- package/skills/gsd-path-ship/references/reviewer-final.md +21 -0
- package/skills/gsd-path-ship/references/reviewer-panel.md +17 -0
- package/skills/gsd-path-ship/references/reviewer-skeptic.md +20 -0
- package/skills/gsd-path-ship/references/reviewer-wave.md +89 -0
- package/skills/gsd-path-ship/references/reviewer.md +12 -148
- package/skills/gsd-path-ship/references/runtime-selection.md +25 -0
- package/skills/gsd-path-ship/scripts/__pycache__/_common.cpython-312.pyc +0 -0
- package/skills/gsd-path-ship/scripts/_common.py +5 -0
- package/skills/gsd-path-ship/scripts/archive_milestone.py +30 -124
- package/skills/gsd-path-ship/scripts/build_recovery.py +292 -0
- package/skills/gsd-path-ship/scripts/build_state.py +2 -0
- package/skills/gsd-path-ship/scripts/check_handoffs.py +7 -1
- package/skills/gsd-path-ship/scripts/check_task_briefs.py +3 -0
- package/skills/gsd-path-ship/scripts/detect_project.py +1536 -0
- package/skills/gsd-path-ship/scripts/discussion_records.py +3 -0
- package/skills/gsd-path-ship/scripts/discussion_validate.py +8 -3
- package/skills/gsd-path-ship/scripts/integration.py +54 -28
- package/skills/gsd-path-ship/scripts/isolation.py +24 -6
- package/skills/gsd-path-ship/scripts/jev_review.py +138 -0
- package/skills/gsd-path-ship/scripts/lean_verification.py +3 -1
- package/skills/gsd-path-ship/scripts/loop_run.py +839 -0
- package/skills/gsd-path-ship/scripts/model_policy.py +279 -0
- package/skills/gsd-path-ship/scripts/path_config.py +248 -0
- package/skills/gsd-path-ship/scripts/pipeline_git.py +3 -0
- package/skills/gsd-path-ship/scripts/pipeline_state.py +117 -186
- package/skills/gsd-path-ship/scripts/promote_lookahead.py +286 -0
- package/skills/gsd-path-ship/scripts/review_panel.py +11 -0
- package/skills/gsd-path-ship/scripts/roadmap.py +326 -0
- package/skills/gsd-path-ship/scripts/state_checkpoint.py +114 -72
- package/skills/gsd-path-ship/scripts/state_promote.py +47 -44
- package/skills/gsd-path-ship/scripts/workflow_run.py +128 -8
- package/skills/gsd-path-ship/scripts/worktree_paths.py +94 -0
- package/skills/gsd-path-ship/templates/wave-review.md +1 -1
- package/skills/gsd-path-undo/SKILL.md +2 -0
- package/skills/gsd-path-undo/references/runtime-selection.md +25 -0
- package/skills/gsd-path-undo/scripts/_common.py +5 -0
- package/skills/gsd-path-undo/scripts/discussion_records.py +3 -0
- package/skills/gsd-path-undo/scripts/loop_run.py +839 -0
- package/skills/gsd-path-undo/scripts/model_policy.py +279 -0
- package/skills/gsd-path-undo/scripts/path_config.py +248 -0
- package/skills/gsd-path-undo/scripts/pipeline_undo.py +14 -7
- package/skills/gsd-path-undo/scripts/review_panel.py +564 -0
- package/skills/gsd-path-undo/scripts/worktree_paths.py +94 -0
- package/skills/path/BUILD.md +54 -575
- package/skills/path/DECIDE.md +4 -6
- package/skills/path/DEFINE.md +23 -21
- package/skills/path/DOCS-AUDIT.md +2 -0
- package/skills/path/INSPECT.md +32 -8
- package/skills/path/PLAN.md +29 -19
- package/skills/path/RESEARCH.md +5 -6
- package/skills/path/ROADMAP.md +24 -58
- package/skills/path/SHIP.md +29 -17
- package/skills/path/SKILL.md +46 -22
- package/skills/path/references/build-abandon.md +33 -0
- package/skills/path/references/build-native.md +502 -0
- package/skills/path/references/build-recovery.md +78 -0
- package/skills/path/references/coder.md +8 -3
- package/skills/path/references/config.md +57 -0
- package/skills/path/references/dispatch.md +12 -19
- package/skills/path/references/docs-auditor.md +14 -0
- package/skills/path/references/jev-review.md +82 -0
- package/skills/path/references/model-policy.md +139 -0
- package/skills/path/references/reviewer-final.md +21 -0
- package/skills/path/references/reviewer-panel.md +17 -0
- package/skills/path/references/reviewer-skeptic.md +20 -0
- package/skills/path/references/reviewer-wave.md +89 -0
- package/skills/path/references/reviewer.md +12 -148
- package/skills/path/references/runtime-selection.md +25 -0
- package/skills/path/scripts/_common.py +5 -0
- package/skills/path/scripts/archive_milestone.py +30 -124
- package/skills/path/scripts/bootstrap_repository.py +33 -4
- package/skills/path/scripts/build_recovery.py +292 -0
- package/skills/path/scripts/build_state.py +2 -0
- package/skills/path/scripts/check_docs_audit.py +7 -3
- package/skills/path/scripts/check_handoffs.py +7 -1
- package/skills/path/scripts/check_task_briefs.py +3 -0
- package/skills/path/scripts/detect_project.py +22 -3
- package/skills/path/scripts/discussion_records.py +3 -0
- package/skills/path/scripts/discussion_validate.py +8 -3
- package/skills/path/scripts/dispatch_driver.py +233 -22
- package/skills/path/scripts/git_guard.py +768 -0
- package/skills/path/scripts/integration.py +54 -28
- package/skills/path/scripts/isolation.py +24 -6
- package/skills/path/scripts/jev_review.py +138 -0
- package/skills/path/scripts/lean_verification.py +3 -1
- package/skills/path/scripts/loop_run.py +2 -0
- package/skills/path/scripts/model_policy.py +279 -0
- package/skills/path/scripts/path_config.py +248 -0
- package/skills/path/scripts/pipeline_git.py +3 -0
- package/skills/path/scripts/pipeline_state.py +117 -186
- package/skills/path/scripts/promote_lookahead.py +33 -162
- package/skills/path/scripts/review_panel.py +11 -0
- package/skills/path/scripts/roadmap.py +326 -0
- package/skills/path/scripts/state_checkpoint.py +114 -72
- package/skills/path/scripts/state_promote.py +47 -44
- package/skills/path/scripts/status_runtime.py +208 -0
- package/skills/path/scripts/task_context.py +73 -0
- package/skills/path/scripts/token_budget.py +40 -1
- package/skills/path/scripts/workflow_run.py +128 -8
- package/skills/path/scripts/worktree_paths.py +94 -0
- package/skills/path/templates/skeptic.md +1 -1
- package/skills/path/templates/task.md +2 -0
- package/skills/path/templates/wave-panel.md +1 -1
- package/skills/path/templates/wave-review.md +1 -1
|
@@ -19,6 +19,9 @@ import shutil
|
|
|
19
19
|
import stat
|
|
20
20
|
import subprocess
|
|
21
21
|
import sys
|
|
22
|
+
|
|
23
|
+
# Runtime helpers must not modify their immutable installation.
|
|
24
|
+
sys.dont_write_bytecode = True
|
|
22
25
|
from dataclasses import asdict, dataclass
|
|
23
26
|
from datetime import date
|
|
24
27
|
from pathlib import Path, PurePosixPath
|
|
@@ -32,8 +35,9 @@ try:
|
|
|
32
35
|
collect_artifact_recoveries,
|
|
33
36
|
)
|
|
34
37
|
import _common
|
|
38
|
+
import roadmap
|
|
35
39
|
except ModuleNotFoundError as error: # pragma: no cover - package imports used by tests
|
|
36
|
-
if error.name not in {"isolation", "_common"}:
|
|
40
|
+
if error.name not in {"isolation", "_common", "roadmap"}:
|
|
37
41
|
raise
|
|
38
42
|
from scripts.isolation import (
|
|
39
43
|
IsolationError,
|
|
@@ -41,7 +45,7 @@ except ModuleNotFoundError as error: # pragma: no cover - package imports used
|
|
|
41
45
|
checkpoint as isolation_checkpoint,
|
|
42
46
|
collect_artifact_recoveries,
|
|
43
47
|
)
|
|
44
|
-
from scripts import _common
|
|
48
|
+
from scripts import _common, roadmap
|
|
45
49
|
|
|
46
50
|
try: # pragma: no cover - exercised only on Windows
|
|
47
51
|
import fcntl
|
|
@@ -82,7 +86,6 @@ SLUG_RE = re.compile(r"^[a-z0-9][a-z0-9-]*$")
|
|
|
82
86
|
BOUND_BRANCH_RE = _common.BOUND_BRANCH_RE
|
|
83
87
|
ARCHIVE_RE = re.compile(r"^\.project/archive/(\d{3,})-([a-z0-9][a-z0-9-]*)/?$")
|
|
84
88
|
FRONTMATTER_RE = re.compile(r"^([a-z_]+):\s*([^#]*?)(?:\s+#.*)?$")
|
|
85
|
-
ROADMAP_HEADING_RE = re.compile(r"^### (M\d{3,}) — ([a-z0-9][a-z0-9-]*)\s*$")
|
|
86
89
|
TASK_ID_RE = re.compile(r"^T\d{3,}$")
|
|
87
90
|
TASK_FILE_RE = re.compile(r"^(T\d{3,})-[a-z0-9][a-z0-9-]*\.md$")
|
|
88
91
|
PLAN_APPROVAL_SUBJECT = "plan: build plan approved"
|
|
@@ -110,7 +113,7 @@ LOOKAHEAD_EVIDENCE_RE = re.compile(r"^research/evidence-[a-z0-9][a-z0-9-]*\.md$"
|
|
|
110
113
|
PROMOTION_RESIDUAL = ".gsd-path-promote-next-residual"
|
|
111
114
|
CHECKPOINT_SCHEMA = "gsd-path/state-checkpoint/v1"
|
|
112
115
|
CHECKPOINT_JOURNAL_NAME = "gsd-path-state-checkpoint.json"
|
|
113
|
-
CHECKPOINT_KINDS = ("plan", "roadmap")
|
|
116
|
+
CHECKPOINT_KINDS = ("plan", "roadmap", "roadmap-reslice")
|
|
114
117
|
SHIPMENT_SCHEMA = "gsd-path/shipment/v1"
|
|
115
118
|
SHIPMENT_JOURNAL_NAME = "gsd-path-shipment.json"
|
|
116
119
|
UNDO_TRANSACTION_SCHEMA = "gsd-path/undo-transaction/v2"
|
|
@@ -126,6 +129,8 @@ CROSS_PHASE_TRANSITIONS = {
|
|
|
126
129
|
("decide", "done", "plan", "active"),
|
|
127
130
|
("roadmap", "done", "define", "active"),
|
|
128
131
|
("plan", "done", "build", "active"),
|
|
132
|
+
("build", "blocked", "define", "active"),
|
|
133
|
+
("build", "blocked", "plan", "active"),
|
|
129
134
|
("build", "active", "ship", "active"),
|
|
130
135
|
("build", "done", "ship", "active"),
|
|
131
136
|
("ship", "active", "shipped", "done"),
|
|
@@ -166,99 +171,10 @@ class ApprovedTaskContract:
|
|
|
166
171
|
files: tuple[str, ...]
|
|
167
172
|
|
|
168
173
|
|
|
169
|
-
#
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
from .state_checkpoint import (
|
|
174
|
-
_sha256,
|
|
175
|
-
_tree_digest,
|
|
176
|
-
_checkpoint_artifact_digest,
|
|
177
|
-
_roadmap_status,
|
|
178
|
-
_activate_roadmap_milestone,
|
|
179
|
-
_approval_details,
|
|
180
|
-
_checkpoint_request_fields,
|
|
181
|
-
_checkpoint_file,
|
|
182
|
-
_approval_journal,
|
|
183
|
-
_remove_checkpoint_temporary,
|
|
184
|
-
_converge_checkpoint_file,
|
|
185
|
-
_unlink_checkpoint_journal,
|
|
186
|
-
_resume_checkpoint_locked,
|
|
187
|
-
checkpoint_approval,
|
|
188
|
-
_checkpoint_deferral_error,
|
|
189
|
-
defer_approval,
|
|
190
|
-
resume_checkpoint,
|
|
191
|
-
_task_files,
|
|
192
|
-
_approval_checkpoint,
|
|
193
|
-
_validate_approval_track,
|
|
194
|
-
_safe_declared_paths,
|
|
195
|
-
_git_text_at,
|
|
196
|
-
_approved_task_contracts,
|
|
197
|
-
_task_contracts_at,
|
|
198
|
-
_classify_plan_drift,
|
|
199
|
-
)
|
|
200
|
-
from .state_promote import (
|
|
201
|
-
_render_roadmap,
|
|
202
|
-
_promotion_event,
|
|
203
|
-
_promotion_state,
|
|
204
|
-
_head_with_exact_message,
|
|
205
|
-
_tree_entries,
|
|
206
|
-
_promotion_tree_mapping,
|
|
207
|
-
_completed_promotion,
|
|
208
|
-
_prepare_promotion,
|
|
209
|
-
_require_journal_request,
|
|
210
|
-
_resume_track_moves,
|
|
211
|
-
_resume_metadata,
|
|
212
|
-
_resume_next_removal,
|
|
213
|
-
_commit_promotion,
|
|
214
|
-
promote_next,
|
|
215
|
-
)
|
|
216
|
-
else: # standalone script or sibling import
|
|
217
|
-
if __name__ == "__main__":
|
|
218
|
-
sys.modules.setdefault("pipeline_state", sys.modules[__name__])
|
|
219
|
-
from state_checkpoint import (
|
|
220
|
-
_sha256,
|
|
221
|
-
_tree_digest,
|
|
222
|
-
_checkpoint_artifact_digest,
|
|
223
|
-
_roadmap_status,
|
|
224
|
-
_activate_roadmap_milestone,
|
|
225
|
-
_approval_details,
|
|
226
|
-
_checkpoint_request_fields,
|
|
227
|
-
_checkpoint_file,
|
|
228
|
-
_approval_journal,
|
|
229
|
-
_remove_checkpoint_temporary,
|
|
230
|
-
_converge_checkpoint_file,
|
|
231
|
-
_unlink_checkpoint_journal,
|
|
232
|
-
_resume_checkpoint_locked,
|
|
233
|
-
checkpoint_approval,
|
|
234
|
-
_checkpoint_deferral_error,
|
|
235
|
-
defer_approval,
|
|
236
|
-
resume_checkpoint,
|
|
237
|
-
_task_files,
|
|
238
|
-
_approval_checkpoint,
|
|
239
|
-
_validate_approval_track,
|
|
240
|
-
_safe_declared_paths,
|
|
241
|
-
_git_text_at,
|
|
242
|
-
_approved_task_contracts,
|
|
243
|
-
_task_contracts_at,
|
|
244
|
-
_classify_plan_drift,
|
|
245
|
-
)
|
|
246
|
-
from state_promote import (
|
|
247
|
-
_render_roadmap,
|
|
248
|
-
_promotion_event,
|
|
249
|
-
_promotion_state,
|
|
250
|
-
_head_with_exact_message,
|
|
251
|
-
_tree_entries,
|
|
252
|
-
_promotion_tree_mapping,
|
|
253
|
-
_completed_promotion,
|
|
254
|
-
_prepare_promotion,
|
|
255
|
-
_require_journal_request,
|
|
256
|
-
_resume_track_moves,
|
|
257
|
-
_resume_metadata,
|
|
258
|
-
_resume_next_removal,
|
|
259
|
-
_commit_promotion,
|
|
260
|
-
promote_next,
|
|
261
|
-
)
|
|
174
|
+
# Standalone transaction imports must reuse this state module and its types.
|
|
175
|
+
if __name__ == "__main__":
|
|
176
|
+
sys.modules.setdefault("pipeline_state", sys.modules[__name__])
|
|
177
|
+
|
|
262
178
|
|
|
263
179
|
def _run_git(
|
|
264
180
|
repo: Path,
|
|
@@ -693,6 +609,21 @@ def _next_skill(route: Mapping[str, object]) -> Optional[str]:
|
|
|
693
609
|
return None
|
|
694
610
|
|
|
695
611
|
|
|
612
|
+
def _completion_status(repo: Path, state: Mapping[str, object], project_dir: str) -> dict:
|
|
613
|
+
if project_dir != ".project" or state.get("phase") != "shipped":
|
|
614
|
+
return {"status": "not-shipped"}
|
|
615
|
+
if __package__:
|
|
616
|
+
from . import integration
|
|
617
|
+
else:
|
|
618
|
+
import integration
|
|
619
|
+
try:
|
|
620
|
+
proof = integration.validate_integrated(
|
|
621
|
+
repo, str(state.get("milestone") or ""), refresh=False, historical=True)
|
|
622
|
+
except (integration.ArchiveError, OSError) as error:
|
|
623
|
+
return {"status": "unverified", "reason": str(error)}
|
|
624
|
+
return {"status": "verified", "proof": proof}
|
|
625
|
+
|
|
626
|
+
|
|
696
627
|
def status_state(repo: Path, project_dir: str = ".project") -> dict[str, object]:
|
|
697
628
|
"""Report owned state, route, and git facts without advancing a phase."""
|
|
698
629
|
resolved = _repo_root(repo)
|
|
@@ -726,9 +657,11 @@ def status_state(repo: Path, project_dir: str = ".project") -> dict[str, object]
|
|
|
726
657
|
"undo": None,
|
|
727
658
|
"collect_artifact": None,
|
|
728
659
|
}
|
|
660
|
+
completion = _completion_status(resolved, state, project_dir)
|
|
729
661
|
return {
|
|
730
662
|
"schema": STATUS_SCHEMA,
|
|
731
663
|
"advance": False,
|
|
664
|
+
"completion": completion,
|
|
732
665
|
"state": state,
|
|
733
666
|
"route": route,
|
|
734
667
|
"path": str(_track_root(resolved, project_dir) / "STATE.md"),
|
|
@@ -753,6 +686,28 @@ def status_state(repo: Path, project_dir: str = ".project") -> dict[str, object]
|
|
|
753
686
|
"lookahead": lookahead.exists() or lookahead.is_symlink(),
|
|
754
687
|
"journals": journals,
|
|
755
688
|
"next_skill": _next_skill(route if isinstance(route, dict) else {}),
|
|
689
|
+
"handoff": phase_handoff(state, route, _track_root(resolved, project_dir) / "STATE.md", completion),
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
|
|
693
|
+
def phase_handoff(state: Mapping[str, object], route: Mapping[str, object], path: Path,
|
|
694
|
+
completion: Mapping[str, object]) -> dict[str, str]:
|
|
695
|
+
"""Present the authoritative route without granting continuation authority."""
|
|
696
|
+
action = route["action"]
|
|
697
|
+
if action == "run-phase":
|
|
698
|
+
next_action = f"Invoke $gsd-path to continue with {route['phase']}."
|
|
699
|
+
router_next = f"Continue with {route['phase']}; honor its input and approval gates."
|
|
700
|
+
else:
|
|
701
|
+
next_action = router_next = f"{action}: {route['reason']}"
|
|
702
|
+
outcome = f"{state['phase']}/{state['status']}"
|
|
703
|
+
if completion["status"] == "unverified":
|
|
704
|
+
outcome = f"Unverified: {outcome}"
|
|
705
|
+
return {
|
|
706
|
+
"outcome": outcome,
|
|
707
|
+
"review": str(path),
|
|
708
|
+
"next": next_action,
|
|
709
|
+
"phase_next": next_action,
|
|
710
|
+
"router_next": router_next,
|
|
756
711
|
}
|
|
757
712
|
|
|
758
713
|
|
|
@@ -784,50 +739,11 @@ def _intent_lane(track: Path) -> Optional[str]:
|
|
|
784
739
|
|
|
785
740
|
|
|
786
741
|
def _active_roadmap_has_questions(project: Path, milestone: Optional[str] = None) -> bool:
|
|
787
|
-
"""Report open questions for the active entry, or for ``milestone`` when given."""
|
|
788
742
|
text = _read_real_file(project / "ROADMAP.md", "ROADMAP.md")
|
|
789
|
-
lines = text.splitlines()
|
|
790
|
-
active_section: Optional[list[str]] = None
|
|
791
|
-
for index, line in enumerate(lines):
|
|
792
|
-
heading = ROADMAP_HEADING_RE.fullmatch(line)
|
|
793
|
-
if heading is None:
|
|
794
|
-
continue
|
|
795
|
-
if int(heading.group(1).removeprefix("M")) < 1:
|
|
796
|
-
raise PipelineStateError(
|
|
797
|
-
f"ROADMAP.md has invalid milestone id: {heading.group(1)}"
|
|
798
|
-
)
|
|
799
|
-
end = next(
|
|
800
|
-
(
|
|
801
|
-
cursor
|
|
802
|
-
for cursor in range(index + 1, len(lines))
|
|
803
|
-
if ROADMAP_HEADING_RE.fullmatch(lines[cursor]) is not None
|
|
804
|
-
),
|
|
805
|
-
len(lines),
|
|
806
|
-
)
|
|
807
|
-
section = lines[index:end]
|
|
808
|
-
if milestone is not None:
|
|
809
|
-
if heading.group(2) == milestone:
|
|
810
|
-
active_section = section
|
|
811
|
-
continue
|
|
812
|
-
if any(re.fullmatch(r"Status:\s*active(?:\s+#.*)?", item) for item in section):
|
|
813
|
-
if active_section is not None:
|
|
814
|
-
raise PipelineStateError("ROADMAP.md has more than one active milestone")
|
|
815
|
-
active_section = section
|
|
816
|
-
if active_section is None:
|
|
817
|
-
if milestone is not None:
|
|
818
|
-
raise PipelineStateError(f"ROADMAP.md is missing lookahead milestone: {milestone}")
|
|
819
|
-
raise PipelineStateError("ROADMAP.md has no active milestone")
|
|
820
743
|
try:
|
|
821
|
-
|
|
822
|
-
except
|
|
823
|
-
raise PipelineStateError(
|
|
824
|
-
questions = [
|
|
825
|
-
line[2:].strip()
|
|
826
|
-
for line in active_section[start:]
|
|
827
|
-
if line.startswith("- ")
|
|
828
|
-
]
|
|
829
|
-
return any(question.lower() != "none" for question in questions)
|
|
830
|
-
|
|
744
|
+
return roadmap.has_questions(text, milestone)
|
|
745
|
+
except roadmap.RoadmapError as error:
|
|
746
|
+
raise PipelineStateError(str(error)) from error
|
|
831
747
|
|
|
832
748
|
def _valid_patch_findings(repo: Path) -> bool:
|
|
833
749
|
validator = Path(__file__).resolve().with_name("check_handoffs.py")
|
|
@@ -1106,6 +1022,14 @@ def route_state(repo: Path, project_dir: str = ".project") -> dict[str, object]:
|
|
|
1106
1022
|
"""Route ordinary phase work only when its pending discussion owner can enter."""
|
|
1107
1023
|
result = _route_state(repo, project_dir)
|
|
1108
1024
|
route = result["route"]
|
|
1025
|
+
if project_dir == ".project" and route["action"] == "run-phase":
|
|
1026
|
+
recovery = _build_recovery().context(_repo_root(repo))
|
|
1027
|
+
if recovery and recovery["active"]:
|
|
1028
|
+
result["recovery"] = recovery
|
|
1029
|
+
if route.get("phase") == "define":
|
|
1030
|
+
route["mode"] = "corrections"
|
|
1031
|
+
elif route.get("phase") == "plan":
|
|
1032
|
+
route["mode"] = "build-repair"
|
|
1109
1033
|
if route["action"] == "run-phase" and result["state"]["archive"] is None:
|
|
1110
1034
|
reason = _pending_discussion_block(_repo_root(repo), route.get("phase"))
|
|
1111
1035
|
if reason:
|
|
@@ -1159,7 +1083,11 @@ def _route_state(repo: Path, project_dir: str = ".project") -> dict[str, object]
|
|
|
1159
1083
|
return result
|
|
1160
1084
|
checkpoint_journal = _git_path(resolved, CHECKPOINT_JOURNAL_NAME)
|
|
1161
1085
|
if checkpoint_journal.exists() or checkpoint_journal.is_symlink():
|
|
1162
|
-
|
|
1086
|
+
if __package__:
|
|
1087
|
+
from . import state_checkpoint
|
|
1088
|
+
else:
|
|
1089
|
+
import state_checkpoint
|
|
1090
|
+
transaction = state_checkpoint._approval_journal(
|
|
1163
1091
|
resolved,
|
|
1164
1092
|
_read_json(checkpoint_journal),
|
|
1165
1093
|
)
|
|
@@ -1736,6 +1664,16 @@ def transition_state(
|
|
|
1736
1664
|
event,
|
|
1737
1665
|
project_dir,
|
|
1738
1666
|
)
|
|
1667
|
+
recovery_context = _build_recovery().context(resolved, text) if project_dir == ".project" else None
|
|
1668
|
+
if recovery_context and recovery_context["active"]:
|
|
1669
|
+
if (state.milestone, state.branch, state.archive) != (after.milestone, after.branch, after.archive):
|
|
1670
|
+
raise PipelineStateError("build recovery must preserve milestone identity")
|
|
1671
|
+
if state.phase == "build" and after.phase in {"define", "plan"}:
|
|
1672
|
+
recovery = _build_recovery().begin(resolved, state, after, event)
|
|
1673
|
+
rendered = _append_event(
|
|
1674
|
+
rendered, after.phase,
|
|
1675
|
+
_build_recovery().MARKER + json.dumps(recovery, sort_keys=True),
|
|
1676
|
+
)
|
|
1739
1677
|
if after.status != "blocked":
|
|
1740
1678
|
reason = _pending_discussion_block(
|
|
1741
1679
|
resolved, after.phase if after.status == "active" else None
|
|
@@ -1767,6 +1705,14 @@ def transition_state(
|
|
|
1767
1705
|
}
|
|
1768
1706
|
|
|
1769
1707
|
|
|
1708
|
+
def _build_recovery():
|
|
1709
|
+
if __package__:
|
|
1710
|
+
from scripts import build_recovery
|
|
1711
|
+
else:
|
|
1712
|
+
import build_recovery
|
|
1713
|
+
return build_recovery
|
|
1714
|
+
|
|
1715
|
+
|
|
1770
1716
|
def configure_integration(
|
|
1771
1717
|
repo: Path,
|
|
1772
1718
|
scope: str,
|
|
@@ -1786,7 +1732,9 @@ def configure_integration(
|
|
|
1786
1732
|
project = _track_root(resolved, project_dir)
|
|
1787
1733
|
with _state_lock(project):
|
|
1788
1734
|
state, text, path = load_state(resolved, project_dir)
|
|
1789
|
-
if state.phase in {"build", "ship", "shipped"}
|
|
1735
|
+
if state.phase in {"build", "ship", "shipped"} or (
|
|
1736
|
+
project_dir == ".project" and _build_recovery().context(resolved, text)
|
|
1737
|
+
):
|
|
1790
1738
|
raise PipelineStateError("integration mode is locked when build starts")
|
|
1791
1739
|
if scope == "default":
|
|
1792
1740
|
integration = (
|
|
@@ -2022,49 +1970,18 @@ def _render_transition(
|
|
|
2022
1970
|
|
|
2023
1971
|
|
|
2024
1972
|
def _roadmap_sections(text: str) -> dict[str, tuple[str, int, int]]:
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
if match:
|
|
2030
|
-
if int(match.group(1).removeprefix("M")) < 1:
|
|
2031
|
-
raise PipelineStateError(f"ROADMAP.md has invalid milestone id: {match.group(1)}")
|
|
2032
|
-
headings.append((match.group(1), match.group(2), index))
|
|
2033
|
-
sections: dict[str, tuple[str, int, int]] = {}
|
|
2034
|
-
for position, (milestone_id, slug, start) in enumerate(headings):
|
|
2035
|
-
end = headings[position + 1][2] if position + 1 < len(headings) else len(lines)
|
|
2036
|
-
if slug in sections:
|
|
2037
|
-
raise PipelineStateError(f"ROADMAP.md repeats milestone slug: {slug}")
|
|
2038
|
-
sections[slug] = (milestone_id, start, end)
|
|
2039
|
-
return sections
|
|
2040
|
-
|
|
1973
|
+
try:
|
|
1974
|
+
return roadmap.strict_sections(text)
|
|
1975
|
+
except roadmap.RoadmapError as error:
|
|
1976
|
+
raise PipelineStateError(str(error)) from error
|
|
2041
1977
|
|
|
2042
1978
|
def _replace_roadmap_field(
|
|
2043
|
-
lines: list[str],
|
|
2044
|
-
start: int,
|
|
2045
|
-
end: int,
|
|
2046
|
-
field: str,
|
|
2047
|
-
expected: set[str],
|
|
2048
|
-
value: str,
|
|
1979
|
+
lines: list[str], start: int, end: int, field: str, expected: set[str], value: str,
|
|
2049
1980
|
) -> None:
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
match = re.match(rf"^({re.escape(field)}:\s*)(\S+)(.*)$", raw)
|
|
2055
|
-
if match is None:
|
|
2056
|
-
continue
|
|
2057
|
-
if found is not None:
|
|
2058
|
-
raise PipelineStateError(f"ROADMAP.md repeats {field} in one milestone")
|
|
2059
|
-
if match.group(2) not in expected:
|
|
2060
|
-
raise PipelineStateError(
|
|
2061
|
-
f"ROADMAP.md {field} is {match.group(2)}, expected {sorted(expected)}"
|
|
2062
|
-
)
|
|
2063
|
-
lines[index] = f"{match.group(1)}{value}{match.group(3)}{ending}"
|
|
2064
|
-
found = index
|
|
2065
|
-
if found is None:
|
|
2066
|
-
raise PipelineStateError(f"ROADMAP.md milestone is missing {field}")
|
|
2067
|
-
|
|
1981
|
+
try:
|
|
1982
|
+
return roadmap.replace_field(lines, start, end, field, expected, value)
|
|
1983
|
+
except roadmap.RoadmapError as error:
|
|
1984
|
+
raise PipelineStateError(str(error)) from error
|
|
2068
1985
|
|
|
2069
1986
|
def _git_path(repo: Path, name: str) -> Path:
|
|
2070
1987
|
value = _run_git(repo, "rev-parse", "--git-path", name).stdout.strip()
|
|
@@ -2163,7 +2080,7 @@ def _specified_fields(arguments: argparse.Namespace, prefix: str) -> dict[str, O
|
|
|
2163
2080
|
def parse_args(argv: Optional[Sequence[str]] = None) -> argparse.Namespace:
|
|
2164
2081
|
parser = argparse.ArgumentParser(description=__doc__)
|
|
2165
2082
|
subparsers = parser.add_subparsers(dest="command", required=True)
|
|
2166
|
-
for command in ("validate", "route", "status"):
|
|
2083
|
+
for command in ("validate", "route", "status", "prepare-build-recovery"):
|
|
2167
2084
|
subparser = subparsers.add_parser(command)
|
|
2168
2085
|
subparser.add_argument("--repo", required=True, type=Path)
|
|
2169
2086
|
subparser.add_argument("--project-dir", default=".project")
|
|
@@ -2204,6 +2121,16 @@ def parse_args(argv: Optional[Sequence[str]] = None) -> argparse.Namespace:
|
|
|
2204
2121
|
|
|
2205
2122
|
def main(argv: Optional[Sequence[str]] = None) -> int:
|
|
2206
2123
|
args = parse_args(argv)
|
|
2124
|
+
if args.command in {"approve", "resume-checkpoint"}:
|
|
2125
|
+
if __package__:
|
|
2126
|
+
from . import state_checkpoint
|
|
2127
|
+
else:
|
|
2128
|
+
import state_checkpoint
|
|
2129
|
+
elif args.command == "promote-next":
|
|
2130
|
+
if __package__:
|
|
2131
|
+
from . import state_promote
|
|
2132
|
+
else:
|
|
2133
|
+
import state_promote
|
|
2207
2134
|
try:
|
|
2208
2135
|
if args.command == "validate":
|
|
2209
2136
|
result = validate_state(args.repo, args.project_dir)
|
|
@@ -2211,6 +2138,10 @@ def main(argv: Optional[Sequence[str]] = None) -> int:
|
|
|
2211
2138
|
result = route_state(args.repo, args.project_dir)
|
|
2212
2139
|
elif args.command == "status":
|
|
2213
2140
|
result = status_state(args.repo, args.project_dir)
|
|
2141
|
+
elif args.command == "prepare-build-recovery":
|
|
2142
|
+
if args.project_dir != ".project":
|
|
2143
|
+
raise PipelineStateError("build recovery requires the active track")
|
|
2144
|
+
result = _build_recovery().prepare(args.repo)
|
|
2214
2145
|
elif args.command == "transition":
|
|
2215
2146
|
result = transition_state(
|
|
2216
2147
|
args.repo,
|
|
@@ -2224,7 +2155,7 @@ def main(argv: Optional[Sequence[str]] = None) -> int:
|
|
|
2224
2155
|
raise PipelineStateError(
|
|
2225
2156
|
"--expected-head is not accepted with --defer-checkpoint or --patch"
|
|
2226
2157
|
)
|
|
2227
|
-
result = defer_approval(
|
|
2158
|
+
result = state_checkpoint.defer_approval(
|
|
2228
2159
|
args.repo,
|
|
2229
2160
|
args.kind,
|
|
2230
2161
|
args.project_dir,
|
|
@@ -2236,7 +2167,7 @@ def main(argv: Optional[Sequence[str]] = None) -> int:
|
|
|
2236
2167
|
raise PipelineStateError(
|
|
2237
2168
|
"approve requires --expected-head unless --defer-checkpoint or --patch"
|
|
2238
2169
|
)
|
|
2239
|
-
result = checkpoint_approval(
|
|
2170
|
+
result = state_checkpoint.checkpoint_approval(
|
|
2240
2171
|
args.repo,
|
|
2241
2172
|
args.kind,
|
|
2242
2173
|
args.expected_head,
|
|
@@ -2244,7 +2175,7 @@ def main(argv: Optional[Sequence[str]] = None) -> int:
|
|
|
2244
2175
|
args.milestone,
|
|
2245
2176
|
)
|
|
2246
2177
|
elif args.command == "resume-checkpoint":
|
|
2247
|
-
result = resume_checkpoint(args.repo)
|
|
2178
|
+
result = state_checkpoint.resume_checkpoint(args.repo)
|
|
2248
2179
|
elif args.command == "promote-next":
|
|
2249
2180
|
if args.integrate is not None and (
|
|
2250
2181
|
args.base is not None or args.landing is not None
|
|
@@ -2262,7 +2193,7 @@ def main(argv: Optional[Sequence[str]] = None) -> int:
|
|
|
2262
2193
|
raise PipelineStateError(
|
|
2263
2194
|
"promote-next requires --base or legacy --integrate"
|
|
2264
2195
|
)
|
|
2265
|
-
result = promote_next(
|
|
2196
|
+
result = state_promote.promote_next(
|
|
2266
2197
|
args.repo,
|
|
2267
2198
|
args.milestone,
|
|
2268
2199
|
args.branch,
|