@opengsd/gsd-path 1.0.0 → 1.1.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 +28 -11
- package/DOCS.md +6 -5
- package/FULL.md +9 -13
- package/QUICK.md +3 -3
- package/README.md +151 -14
- package/RUNTIME.md +7 -1
- package/WORKFLOW.md +30 -14
- package/package.json +15 -1
- package/platforms/shared-agents/dispatch.md +6 -0
- package/scripts/archive_milestone.py +10 -118
- package/scripts/bootstrap_repository.py +25 -3
- package/scripts/build_recovery.py +287 -0
- package/scripts/check_docs_audit.py +5 -3
- package/scripts/check_handoffs.py +1 -1
- package/scripts/detect_project.py +11 -2
- package/scripts/dispatch_driver.py +4 -2
- package/scripts/git_guard.py +2 -1
- package/scripts/install.mjs +2 -0
- package/scripts/install.py +2 -0
- package/scripts/integration.py +28 -22
- package/scripts/isolation.py +9 -1
- package/scripts/lean_verification.py +1 -1
- package/scripts/pipeline_diagnose.py +12 -3
- package/scripts/pipeline_state.py +114 -186
- package/scripts/pipeline_undo.py +11 -7
- package/scripts/promote_lookahead.py +30 -162
- package/scripts/roadmap.py +321 -0
- package/scripts/skill-resources.json +79 -1
- package/scripts/state_checkpoint.py +109 -72
- package/scripts/state_promote.py +42 -44
- package/scripts/task_context.py +73 -0
- package/scripts/token_budget.py +40 -1
- package/scripts/workflow_run.py +116 -7
- package/skills/gsd-path/BUILD.md +47 -575
- package/skills/gsd-path/DECIDE.md +2 -6
- package/skills/gsd-path/DEFINE.md +10 -14
- package/skills/gsd-path/INSPECT.md +30 -8
- package/skills/gsd-path/PLAN.md +25 -17
- package/skills/gsd-path/RESEARCH.md +3 -6
- package/skills/gsd-path/ROADMAP.md +22 -58
- package/skills/gsd-path/SHIP.md +5 -4
- package/skills/gsd-path/SKILL.md +24 -14
- package/skills/gsd-path/references/build-abandon.md +33 -0
- package/skills/gsd-path/references/build-native.md +494 -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/dispatch.md +6 -0
- package/skills/gsd-path/references/docs-auditor.md +14 -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 -150
- package/skills/gsd-path/scripts/__pycache__/_common.cpython-312.pyc +0 -0
- package/skills/gsd-path/scripts/__pycache__/archive_milestone.cpython-312.pyc +0 -0
- package/skills/gsd-path/scripts/__pycache__/build_recovery.cpython-312.pyc +0 -0
- package/skills/gsd-path/scripts/__pycache__/build_state.cpython-312.pyc +0 -0
- package/skills/gsd-path/scripts/__pycache__/check_handoffs.cpython-312.pyc +0 -0
- package/skills/gsd-path/scripts/__pycache__/check_task_briefs.cpython-312.pyc +0 -0
- package/skills/gsd-path/scripts/__pycache__/detect_project.cpython-312.pyc +0 -0
- package/skills/gsd-path/scripts/__pycache__/discussion_records.cpython-312.pyc +0 -0
- package/skills/gsd-path/scripts/__pycache__/discussion_validate.cpython-312.pyc +0 -0
- package/skills/gsd-path/scripts/__pycache__/integration.cpython-312.pyc +0 -0
- package/skills/gsd-path/scripts/__pycache__/isolation.cpython-312.pyc +0 -0
- package/skills/gsd-path/scripts/__pycache__/loop_run.cpython-312.pyc +0 -0
- package/skills/gsd-path/scripts/__pycache__/pipeline_git.cpython-312.pyc +0 -0
- package/skills/gsd-path/scripts/__pycache__/pipeline_state.cpython-312.pyc +0 -0
- package/skills/gsd-path/scripts/__pycache__/review_findings.cpython-312.pyc +0 -0
- package/skills/gsd-path/scripts/__pycache__/review_panel.cpython-312.pyc +0 -0
- package/skills/gsd-path/scripts/__pycache__/roadmap.cpython-312.pyc +0 -0
- package/skills/gsd-path/scripts/__pycache__/state_checkpoint.cpython-312.pyc +0 -0
- package/skills/gsd-path/scripts/__pycache__/task_context.cpython-312.pyc +0 -0
- package/skills/gsd-path/scripts/__pycache__/workflow_run.cpython-312.pyc +0 -0
- package/skills/gsd-path/scripts/archive_milestone.py +10 -118
- package/skills/gsd-path/scripts/bootstrap_repository.py +25 -3
- package/skills/gsd-path/scripts/build_recovery.py +287 -0
- package/skills/gsd-path/scripts/check_docs_audit.py +5 -3
- package/skills/gsd-path/scripts/check_handoffs.py +1 -1
- package/skills/gsd-path/scripts/detect_project.py +11 -2
- package/skills/gsd-path/scripts/dispatch_driver.py +4 -2
- package/skills/gsd-path/scripts/integration.py +28 -22
- package/skills/gsd-path/scripts/isolation.py +9 -1
- package/skills/gsd-path/scripts/lean_verification.py +1 -1
- package/skills/gsd-path/scripts/pipeline_state.py +114 -186
- package/skills/gsd-path/scripts/promote_lookahead.py +30 -162
- package/skills/gsd-path/scripts/roadmap.py +321 -0
- package/skills/gsd-path/scripts/state_checkpoint.py +109 -72
- package/skills/gsd-path/scripts/state_promote.py +42 -44
- 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 +116 -7
- package/skills/gsd-path/templates/wave-review.md +1 -1
- package/skills/gsd-path-build/SKILL.md +47 -575
- package/skills/gsd-path-build/references/build-abandon.md +33 -0
- package/skills/gsd-path-build/references/build-native.md +494 -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 +6 -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 -150
- package/skills/gsd-path-build/scripts/__pycache__/_common.cpython-312.pyc +0 -0
- package/skills/gsd-path-build/scripts/__pycache__/archive_milestone.cpython-312.pyc +0 -0
- package/skills/gsd-path-build/scripts/__pycache__/build_recovery.cpython-312.pyc +0 -0
- package/skills/gsd-path-build/scripts/__pycache__/build_state.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/__pycache__/check_task_briefs.cpython-312.pyc +0 -0
- package/skills/gsd-path-build/scripts/__pycache__/detect_project.cpython-312.pyc +0 -0
- package/skills/gsd-path-build/scripts/__pycache__/discussion_validate.cpython-312.pyc +0 -0
- package/skills/gsd-path-build/scripts/__pycache__/isolation.cpython-312.pyc +0 -0
- package/skills/gsd-path-build/scripts/__pycache__/loop_run.cpython-312.pyc +0 -0
- package/skills/gsd-path-build/scripts/__pycache__/pipeline_git.cpython-312.pyc +0 -0
- package/skills/gsd-path-build/scripts/__pycache__/pipeline_state.cpython-312.pyc +0 -0
- package/skills/gsd-path-build/scripts/__pycache__/review_findings.cpython-312.pyc +0 -0
- package/skills/gsd-path-build/scripts/__pycache__/review_panel.cpython-312.pyc +0 -0
- package/skills/gsd-path-build/scripts/__pycache__/roadmap.cpython-312.pyc +0 -0
- package/skills/gsd-path-build/scripts/__pycache__/state_checkpoint.cpython-312.pyc +0 -0
- package/skills/gsd-path-build/scripts/__pycache__/task_context.cpython-312.pyc +0 -0
- package/skills/gsd-path-build/scripts/__pycache__/workflow_run.cpython-312.pyc +0 -0
- package/skills/gsd-path-build/scripts/archive_milestone.py +10 -118
- package/skills/gsd-path-build/scripts/build_recovery.py +287 -0
- package/skills/gsd-path-build/scripts/check_handoffs.py +1 -1
- package/skills/gsd-path-build/scripts/detect_project.py +1526 -0
- package/skills/gsd-path-build/scripts/dispatch_driver.py +4 -2
- package/skills/gsd-path-build/scripts/integration.py +28 -22
- package/skills/gsd-path-build/scripts/isolation.py +9 -1
- package/skills/gsd-path-build/scripts/pipeline_state.py +114 -186
- package/skills/gsd-path-build/scripts/promote_lookahead.py +283 -0
- package/skills/gsd-path-build/scripts/roadmap.py +321 -0
- package/skills/gsd-path-build/scripts/state_checkpoint.py +109 -72
- package/skills/gsd-path-build/scripts/state_promote.py +42 -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 +116 -7
- package/skills/gsd-path-build/templates/wave-review.md +1 -1
- package/skills/gsd-path-decide/SKILL.md +2 -6
- package/skills/gsd-path-decide/references/dispatch.md +6 -0
- package/skills/gsd-path-decide/scripts/__pycache__/_common.cpython-312.pyc +0 -0
- package/skills/gsd-path-decide/scripts/__pycache__/archive_milestone.cpython-312.pyc +0 -0
- package/skills/gsd-path-decide/scripts/__pycache__/detect_project.cpython-312.pyc +0 -0
- package/skills/gsd-path-decide/scripts/__pycache__/discussion_validate.cpython-312.pyc +0 -0
- package/skills/gsd-path-decide/scripts/__pycache__/isolation.cpython-312.pyc +0 -0
- package/skills/gsd-path-decide/scripts/__pycache__/pipeline_git.cpython-312.pyc +0 -0
- package/skills/gsd-path-decide/scripts/__pycache__/pipeline_state.cpython-312.pyc +0 -0
- package/skills/gsd-path-decide/scripts/__pycache__/review_panel.cpython-312.pyc +0 -0
- package/skills/gsd-path-decide/scripts/__pycache__/roadmap.cpython-312.pyc +0 -0
- package/skills/gsd-path-decide/scripts/__pycache__/state_checkpoint.cpython-312.pyc +0 -0
- package/skills/gsd-path-decide/scripts/archive_milestone.py +2157 -0
- package/skills/gsd-path-decide/scripts/build_recovery.py +287 -0
- package/skills/gsd-path-decide/scripts/check_handoffs.py +1 -1
- package/skills/gsd-path-decide/scripts/detect_project.py +1526 -0
- package/skills/gsd-path-decide/scripts/discussion_validate.py +1321 -0
- package/skills/gsd-path-decide/scripts/integration.py +1439 -0
- package/skills/gsd-path-decide/scripts/isolation.py +9 -1
- package/skills/gsd-path-decide/scripts/pipeline_state.py +114 -186
- package/skills/gsd-path-decide/scripts/promote_lookahead.py +283 -0
- package/skills/gsd-path-decide/scripts/review_panel.py +553 -0
- package/skills/gsd-path-decide/scripts/roadmap.py +321 -0
- package/skills/gsd-path-decide/scripts/state_checkpoint.py +109 -72
- package/skills/gsd-path-decide/scripts/state_promote.py +42 -44
- package/skills/gsd-path-define/SKILL.md +10 -14
- package/skills/gsd-path-define/references/build-recovery.md +78 -0
- package/skills/gsd-path-define/scripts/__pycache__/_common.cpython-312.pyc +0 -0
- package/skills/gsd-path-define/scripts/__pycache__/archive_milestone.cpython-312.pyc +0 -0
- package/skills/gsd-path-define/scripts/__pycache__/detect_project.cpython-312.pyc +0 -0
- package/skills/gsd-path-define/scripts/__pycache__/discussion_validate.cpython-312.pyc +0 -0
- package/skills/gsd-path-define/scripts/__pycache__/isolation.cpython-312.pyc +0 -0
- package/skills/gsd-path-define/scripts/__pycache__/pipeline_git.cpython-312.pyc +0 -0
- package/skills/gsd-path-define/scripts/__pycache__/pipeline_state.cpython-312.pyc +0 -0
- package/skills/gsd-path-define/scripts/__pycache__/review_panel.cpython-312.pyc +0 -0
- package/skills/gsd-path-define/scripts/__pycache__/roadmap.cpython-312.pyc +0 -0
- package/skills/gsd-path-define/scripts/__pycache__/state_checkpoint.cpython-312.pyc +0 -0
- package/skills/gsd-path-define/scripts/archive_milestone.py +2157 -0
- package/skills/gsd-path-define/scripts/build_recovery.py +287 -0
- package/skills/gsd-path-define/scripts/check_handoffs.py +1 -1
- package/skills/gsd-path-define/scripts/detect_project.py +11 -2
- package/skills/gsd-path-define/scripts/discussion_validate.py +1321 -0
- package/skills/gsd-path-define/scripts/integration.py +1439 -0
- package/skills/gsd-path-define/scripts/isolation.py +9 -1
- package/skills/gsd-path-define/scripts/pipeline_state.py +114 -186
- package/skills/gsd-path-define/scripts/promote_lookahead.py +283 -0
- package/skills/gsd-path-define/scripts/review_panel.py +553 -0
- package/skills/gsd-path-define/scripts/roadmap.py +321 -0
- package/skills/gsd-path-define/scripts/state_checkpoint.py +109 -72
- package/skills/gsd-path-define/scripts/state_promote.py +42 -44
- package/skills/gsd-path-docs-audit/references/dispatch.md +6 -0
- package/skills/gsd-path-docs-audit/references/docs-auditor.md +14 -0
- package/skills/gsd-path-docs-audit/scripts/__pycache__/_common.cpython-312.pyc +0 -0
- package/skills/gsd-path-docs-audit/scripts/__pycache__/archive_milestone.cpython-312.pyc +0 -0
- package/skills/gsd-path-docs-audit/scripts/__pycache__/build_recovery.cpython-312.pyc +0 -0
- package/skills/gsd-path-docs-audit/scripts/__pycache__/detect_project.cpython-312.pyc +0 -0
- package/skills/gsd-path-docs-audit/scripts/__pycache__/discussion_validate.cpython-312.pyc +0 -0
- package/skills/gsd-path-docs-audit/scripts/__pycache__/isolation.cpython-312.pyc +0 -0
- package/skills/gsd-path-docs-audit/scripts/__pycache__/pipeline_git.cpython-312.pyc +0 -0
- package/skills/gsd-path-docs-audit/scripts/__pycache__/pipeline_state.cpython-312.pyc +0 -0
- package/skills/gsd-path-docs-audit/scripts/__pycache__/review_panel.cpython-312.pyc +0 -0
- package/skills/gsd-path-docs-audit/scripts/__pycache__/roadmap.cpython-312.pyc +0 -0
- package/skills/gsd-path-docs-audit/scripts/__pycache__/state_checkpoint.cpython-312.pyc +0 -0
- package/skills/gsd-path-docs-audit/scripts/archive_milestone.py +2157 -0
- package/skills/gsd-path-docs-audit/scripts/build_recovery.py +287 -0
- package/skills/gsd-path-docs-audit/scripts/check_docs_audit.py +5 -3
- package/skills/gsd-path-docs-audit/scripts/check_handoffs.py +1 -1
- package/skills/gsd-path-docs-audit/scripts/detect_project.py +1526 -0
- package/skills/gsd-path-docs-audit/scripts/discussion_validate.py +1321 -0
- package/skills/gsd-path-docs-audit/scripts/integration.py +1439 -0
- package/skills/gsd-path-docs-audit/scripts/isolation.py +9 -1
- package/skills/gsd-path-docs-audit/scripts/pipeline_state.py +114 -186
- package/skills/gsd-path-docs-audit/scripts/promote_lookahead.py +283 -0
- package/skills/gsd-path-docs-audit/scripts/review_panel.py +553 -0
- package/skills/gsd-path-docs-audit/scripts/roadmap.py +321 -0
- package/skills/gsd-path-docs-audit/scripts/state_checkpoint.py +109 -72
- package/skills/gsd-path-docs-audit/scripts/state_promote.py +42 -44
- package/skills/gsd-path-forensics/scripts/__pycache__/pipeline_undo.cpython-312.pyc +0 -0
- package/skills/gsd-path-forensics/scripts/pipeline_diagnose.py +12 -3
- package/skills/gsd-path-forensics/scripts/pipeline_undo.py +11 -7
- package/skills/gsd-path-inspect/SKILL.md +30 -8
- package/skills/gsd-path-inspect/references/dispatch.md +6 -0
- package/skills/gsd-path-inspect/references/docs-auditor.md +14 -0
- package/skills/gsd-path-inspect/scripts/__pycache__/_common.cpython-312.pyc +0 -0
- package/skills/gsd-path-inspect/scripts/__pycache__/archive_milestone.cpython-312.pyc +0 -0
- package/skills/gsd-path-inspect/scripts/__pycache__/build_recovery.cpython-312.pyc +0 -0
- package/skills/gsd-path-inspect/scripts/__pycache__/detect_project.cpython-312.pyc +0 -0
- package/skills/gsd-path-inspect/scripts/__pycache__/discussion_validate.cpython-312.pyc +0 -0
- package/skills/gsd-path-inspect/scripts/__pycache__/isolation.cpython-312.pyc +0 -0
- package/skills/gsd-path-inspect/scripts/__pycache__/pipeline_git.cpython-312.pyc +0 -0
- package/skills/gsd-path-inspect/scripts/__pycache__/pipeline_state.cpython-312.pyc +0 -0
- package/skills/gsd-path-inspect/scripts/__pycache__/review_panel.cpython-312.pyc +0 -0
- package/skills/gsd-path-inspect/scripts/__pycache__/roadmap.cpython-312.pyc +0 -0
- package/skills/gsd-path-inspect/scripts/__pycache__/state_checkpoint.cpython-312.pyc +0 -0
- package/skills/gsd-path-inspect/scripts/archive_milestone.py +2157 -0
- package/skills/gsd-path-inspect/scripts/build_recovery.py +287 -0
- package/skills/gsd-path-inspect/scripts/check_docs_audit.py +5 -3
- package/skills/gsd-path-inspect/scripts/check_handoffs.py +1 -1
- package/skills/gsd-path-inspect/scripts/detect_project.py +11 -2
- package/skills/gsd-path-inspect/scripts/discussion_validate.py +1321 -0
- package/skills/gsd-path-inspect/scripts/integration.py +1439 -0
- package/skills/gsd-path-inspect/scripts/isolation.py +9 -1
- package/skills/gsd-path-inspect/scripts/pipeline_state.py +114 -186
- package/skills/gsd-path-inspect/scripts/promote_lookahead.py +283 -0
- package/skills/gsd-path-inspect/scripts/review_panel.py +553 -0
- package/skills/gsd-path-inspect/scripts/roadmap.py +321 -0
- package/skills/gsd-path-inspect/scripts/state_checkpoint.py +109 -72
- package/skills/gsd-path-inspect/scripts/state_promote.py +42 -44
- package/skills/gsd-path-inspect/scripts/workflow_run.py +226 -0
- package/skills/gsd-path-plan/SKILL.md +25 -17
- package/skills/gsd-path-plan/references/build-recovery.md +78 -0
- package/skills/gsd-path-plan/references/dispatch.md +6 -0
- package/skills/gsd-path-plan/scripts/__pycache__/_common.cpython-312.pyc +0 -0
- package/skills/gsd-path-plan/scripts/__pycache__/archive_milestone.cpython-312.pyc +0 -0
- package/skills/gsd-path-plan/scripts/__pycache__/detect_project.cpython-312.pyc +0 -0
- package/skills/gsd-path-plan/scripts/__pycache__/discussion_validate.cpython-312.pyc +0 -0
- package/skills/gsd-path-plan/scripts/__pycache__/isolation.cpython-312.pyc +0 -0
- package/skills/gsd-path-plan/scripts/__pycache__/pipeline_git.cpython-312.pyc +0 -0
- package/skills/gsd-path-plan/scripts/__pycache__/pipeline_state.cpython-312.pyc +0 -0
- package/skills/gsd-path-plan/scripts/__pycache__/review_panel.cpython-312.pyc +0 -0
- package/skills/gsd-path-plan/scripts/__pycache__/roadmap.cpython-312.pyc +0 -0
- package/skills/gsd-path-plan/scripts/__pycache__/state_checkpoint.cpython-312.pyc +0 -0
- package/skills/gsd-path-plan/scripts/archive_milestone.py +2157 -0
- package/skills/gsd-path-plan/scripts/build_recovery.py +287 -0
- package/skills/gsd-path-plan/scripts/check_handoffs.py +1 -1
- package/skills/gsd-path-plan/scripts/detect_project.py +1526 -0
- package/skills/gsd-path-plan/scripts/discussion_validate.py +1321 -0
- package/skills/gsd-path-plan/scripts/integration.py +1439 -0
- package/skills/gsd-path-plan/scripts/isolation.py +9 -1
- package/skills/gsd-path-plan/scripts/pipeline_state.py +114 -186
- package/skills/gsd-path-plan/scripts/promote_lookahead.py +283 -0
- package/skills/gsd-path-plan/scripts/roadmap.py +321 -0
- package/skills/gsd-path-plan/scripts/state_checkpoint.py +109 -72
- package/skills/gsd-path-plan/scripts/state_promote.py +42 -44
- package/skills/gsd-path-plan/scripts/workflow_run.py +116 -7
- package/skills/gsd-path-research/SKILL.md +3 -6
- package/skills/gsd-path-research/references/dispatch.md +6 -0
- package/skills/gsd-path-research/scripts/__pycache__/_common.cpython-312.pyc +0 -0
- package/skills/gsd-path-research/scripts/__pycache__/archive_milestone.cpython-312.pyc +0 -0
- package/skills/gsd-path-research/scripts/__pycache__/detect_project.cpython-312.pyc +0 -0
- package/skills/gsd-path-research/scripts/__pycache__/discussion_validate.cpython-312.pyc +0 -0
- package/skills/gsd-path-research/scripts/__pycache__/isolation.cpython-312.pyc +0 -0
- package/skills/gsd-path-research/scripts/__pycache__/pipeline_git.cpython-312.pyc +0 -0
- package/skills/gsd-path-research/scripts/__pycache__/pipeline_state.cpython-312.pyc +0 -0
- package/skills/gsd-path-research/scripts/__pycache__/review_panel.cpython-312.pyc +0 -0
- package/skills/gsd-path-research/scripts/__pycache__/roadmap.cpython-312.pyc +0 -0
- package/skills/gsd-path-research/scripts/__pycache__/state_checkpoint.cpython-312.pyc +0 -0
- package/skills/gsd-path-research/scripts/archive_milestone.py +2157 -0
- package/skills/gsd-path-research/scripts/build_recovery.py +287 -0
- package/skills/gsd-path-research/scripts/check_handoffs.py +1 -1
- package/skills/gsd-path-research/scripts/detect_project.py +1526 -0
- package/skills/gsd-path-research/scripts/discussion_validate.py +1321 -0
- package/skills/gsd-path-research/scripts/integration.py +1439 -0
- package/skills/gsd-path-research/scripts/isolation.py +9 -1
- package/skills/gsd-path-research/scripts/pipeline_state.py +114 -186
- package/skills/gsd-path-research/scripts/promote_lookahead.py +283 -0
- package/skills/gsd-path-research/scripts/review_panel.py +553 -0
- package/skills/gsd-path-research/scripts/roadmap.py +321 -0
- package/skills/gsd-path-research/scripts/state_checkpoint.py +109 -72
- package/skills/gsd-path-research/scripts/state_promote.py +42 -44
- package/skills/gsd-path-roadmap/SKILL.md +22 -58
- package/skills/gsd-path-roadmap/references/dispatch.md +6 -0
- package/skills/gsd-path-roadmap/scripts/__pycache__/_common.cpython-312.pyc +0 -0
- package/skills/gsd-path-roadmap/scripts/__pycache__/archive_milestone.cpython-312.pyc +0 -0
- package/skills/gsd-path-roadmap/scripts/__pycache__/detect_project.cpython-312.pyc +0 -0
- package/skills/gsd-path-roadmap/scripts/__pycache__/discussion_validate.cpython-312.pyc +0 -0
- package/skills/gsd-path-roadmap/scripts/__pycache__/isolation.cpython-312.pyc +0 -0
- package/skills/gsd-path-roadmap/scripts/__pycache__/pipeline_git.cpython-312.pyc +0 -0
- package/skills/gsd-path-roadmap/scripts/__pycache__/pipeline_state.cpython-312.pyc +0 -0
- package/skills/gsd-path-roadmap/scripts/__pycache__/review_panel.cpython-312.pyc +0 -0
- package/skills/gsd-path-roadmap/scripts/__pycache__/roadmap.cpython-312.pyc +0 -0
- package/skills/gsd-path-roadmap/scripts/__pycache__/state_checkpoint.cpython-312.pyc +0 -0
- package/skills/gsd-path-roadmap/scripts/archive_milestone.py +10 -118
- package/skills/gsd-path-roadmap/scripts/build_recovery.py +287 -0
- package/skills/gsd-path-roadmap/scripts/check_handoffs.py +1 -1
- package/skills/gsd-path-roadmap/scripts/detect_project.py +11 -2
- package/skills/gsd-path-roadmap/scripts/integration.py +28 -22
- package/skills/gsd-path-roadmap/scripts/isolation.py +9 -1
- package/skills/gsd-path-roadmap/scripts/pipeline_state.py +114 -186
- package/skills/gsd-path-roadmap/scripts/promote_lookahead.py +30 -162
- package/skills/gsd-path-roadmap/scripts/roadmap.py +321 -0
- package/skills/gsd-path-roadmap/scripts/state_checkpoint.py +109 -72
- package/skills/gsd-path-roadmap/scripts/state_promote.py +42 -44
- package/skills/gsd-path-ship/SKILL.md +5 -4
- package/skills/gsd-path-ship/references/dispatch.md +6 -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 -150
- package/skills/gsd-path-ship/scripts/__pycache__/_common.cpython-312.pyc +0 -0
- package/skills/gsd-path-ship/scripts/__pycache__/archive_milestone.cpython-312.pyc +0 -0
- package/skills/gsd-path-ship/scripts/__pycache__/build_recovery.cpython-312.pyc +0 -0
- package/skills/gsd-path-ship/scripts/__pycache__/build_state.cpython-312.pyc +0 -0
- package/skills/gsd-path-ship/scripts/__pycache__/check_handoffs.cpython-312.pyc +0 -0
- package/skills/gsd-path-ship/scripts/__pycache__/check_task_briefs.cpython-312.pyc +0 -0
- package/skills/gsd-path-ship/scripts/__pycache__/detect_project.cpython-312.pyc +0 -0
- package/skills/gsd-path-ship/scripts/__pycache__/discussion_validate.cpython-312.pyc +0 -0
- package/skills/gsd-path-ship/scripts/__pycache__/isolation.cpython-312.pyc +0 -0
- package/skills/gsd-path-ship/scripts/__pycache__/pipeline_git.cpython-312.pyc +0 -0
- package/skills/gsd-path-ship/scripts/__pycache__/pipeline_state.cpython-312.pyc +0 -0
- package/skills/gsd-path-ship/scripts/__pycache__/review_panel.cpython-312.pyc +0 -0
- package/skills/gsd-path-ship/scripts/__pycache__/roadmap.cpython-312.pyc +0 -0
- package/skills/gsd-path-ship/scripts/__pycache__/state_checkpoint.cpython-312.pyc +0 -0
- package/skills/gsd-path-ship/scripts/archive_milestone.py +10 -118
- package/skills/gsd-path-ship/scripts/build_recovery.py +287 -0
- package/skills/gsd-path-ship/scripts/check_handoffs.py +1 -1
- package/skills/gsd-path-ship/scripts/detect_project.py +1526 -0
- package/skills/gsd-path-ship/scripts/integration.py +28 -22
- package/skills/gsd-path-ship/scripts/isolation.py +9 -1
- package/skills/gsd-path-ship/scripts/lean_verification.py +1 -1
- package/skills/gsd-path-ship/scripts/pipeline_state.py +114 -186
- package/skills/gsd-path-ship/scripts/promote_lookahead.py +283 -0
- package/skills/gsd-path-ship/scripts/roadmap.py +321 -0
- package/skills/gsd-path-ship/scripts/state_checkpoint.py +109 -72
- package/skills/gsd-path-ship/scripts/state_promote.py +42 -44
- package/skills/gsd-path-ship/scripts/workflow_run.py +116 -7
- package/skills/gsd-path-ship/templates/wave-review.md +1 -1
- package/skills/gsd-path-undo/scripts/pipeline_undo.py +11 -7
- package/skills/path/BUILD.md +47 -575
- package/skills/path/DECIDE.md +2 -6
- package/skills/path/DEFINE.md +10 -14
- package/skills/path/INSPECT.md +30 -8
- package/skills/path/PLAN.md +25 -17
- package/skills/path/RESEARCH.md +3 -6
- package/skills/path/ROADMAP.md +22 -58
- package/skills/path/SHIP.md +5 -4
- package/skills/path/SKILL.md +24 -14
- package/skills/path/references/build-abandon.md +33 -0
- package/skills/path/references/build-native.md +494 -0
- package/skills/path/references/build-recovery.md +78 -0
- package/skills/path/references/coder.md +8 -3
- package/skills/path/references/dispatch.md +6 -0
- package/skills/path/references/docs-auditor.md +14 -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 -150
- package/skills/path/scripts/archive_milestone.py +10 -118
- package/skills/path/scripts/bootstrap_repository.py +25 -3
- package/skills/path/scripts/build_recovery.py +287 -0
- package/skills/path/scripts/check_docs_audit.py +5 -3
- package/skills/path/scripts/check_handoffs.py +1 -1
- package/skills/path/scripts/detect_project.py +11 -2
- package/skills/path/scripts/dispatch_driver.py +4 -2
- package/skills/path/scripts/integration.py +28 -22
- package/skills/path/scripts/isolation.py +9 -1
- package/skills/path/scripts/lean_verification.py +1 -1
- package/skills/path/scripts/pipeline_state.py +114 -186
- package/skills/path/scripts/promote_lookahead.py +30 -162
- package/skills/path/scripts/roadmap.py +321 -0
- package/skills/path/scripts/state_checkpoint.py +109 -72
- package/skills/path/scripts/state_promote.py +42 -44
- 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 +116 -7
- package/skills/path/templates/wave-review.md +1 -1
|
@@ -11,6 +11,31 @@ from pathlib import Path, PurePosixPath
|
|
|
11
11
|
from typing import Mapping, Optional
|
|
12
12
|
|
|
13
13
|
|
|
14
|
+
if __package__: # imported as scripts.state_promote
|
|
15
|
+
from . import pipeline_state, state_checkpoint
|
|
16
|
+
from .pipeline_state import (
|
|
17
|
+
NULL,
|
|
18
|
+
PROMOTION_RESIDUAL,
|
|
19
|
+
PROMOTION_SCHEMA,
|
|
20
|
+
PROMOTION_TRACKS,
|
|
21
|
+
SLUG_RE,
|
|
22
|
+
PipelineState,
|
|
23
|
+
PipelineStateError,
|
|
24
|
+
)
|
|
25
|
+
else: # standalone script or sibling import
|
|
26
|
+
import pipeline_state
|
|
27
|
+
import state_checkpoint
|
|
28
|
+
from pipeline_state import (
|
|
29
|
+
NULL,
|
|
30
|
+
PROMOTION_RESIDUAL,
|
|
31
|
+
PROMOTION_SCHEMA,
|
|
32
|
+
PROMOTION_TRACKS,
|
|
33
|
+
SLUG_RE,
|
|
34
|
+
PipelineState,
|
|
35
|
+
PipelineStateError,
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
|
|
14
39
|
def _render_roadmap(
|
|
15
40
|
text: str,
|
|
16
41
|
previous_milestone: str,
|
|
@@ -243,9 +268,9 @@ def _completed_promotion(
|
|
|
243
268
|
if _head_with_exact_message(repo, subject, fields) != head:
|
|
244
269
|
raise PipelineStateError("completed promotion has the wrong commit message")
|
|
245
270
|
|
|
246
|
-
active_text =
|
|
247
|
-
next_text =
|
|
248
|
-
roadmap_text =
|
|
271
|
+
active_text = state_checkpoint._git_text_at(repo, base, ".project/STATE.md")
|
|
272
|
+
next_text = state_checkpoint._git_text_at(repo, base, ".project/next/STATE.md")
|
|
273
|
+
roadmap_text = state_checkpoint._git_text_at(repo, base, ".project/ROADMAP.md")
|
|
249
274
|
if active_text is None or next_text is None or roadmap_text is None:
|
|
250
275
|
raise PipelineStateError("promotion parent is missing required metadata")
|
|
251
276
|
active_state = pipeline_state._state_from_text(active_text, "promotion parent STATE.md")
|
|
@@ -265,7 +290,7 @@ def _completed_promotion(
|
|
|
265
290
|
)
|
|
266
291
|
|
|
267
292
|
_promotion_tree_mapping(repo, base, head)
|
|
268
|
-
drift =
|
|
293
|
+
drift = state_checkpoint._classify_plan_drift(repo, next_state, base, landing)
|
|
269
294
|
expected_roadmap = _render_roadmap(
|
|
270
295
|
roadmap_text,
|
|
271
296
|
active_state.milestone,
|
|
@@ -273,11 +298,11 @@ def _completed_promotion(
|
|
|
273
298
|
branch,
|
|
274
299
|
landing,
|
|
275
300
|
)
|
|
276
|
-
current_roadmap =
|
|
301
|
+
current_roadmap = state_checkpoint._git_text_at(repo, head, ".project/ROADMAP.md")
|
|
277
302
|
if current_roadmap != expected_roadmap:
|
|
278
303
|
raise PipelineStateError("completed promotion has invalid ROADMAP.md")
|
|
279
304
|
|
|
280
|
-
current_state =
|
|
305
|
+
current_state = state_checkpoint._git_text_at(repo, head, ".project/STATE.md")
|
|
281
306
|
if current_state is None:
|
|
282
307
|
raise PipelineStateError("completed promotion has no STATE.md")
|
|
283
308
|
event = re.escape(_promotion_event(drift, branch, landing, base))
|
|
@@ -438,10 +463,10 @@ def _prepare_promotion(
|
|
|
438
463
|
if source.exists() or source.is_symlink():
|
|
439
464
|
if destination.exists() or destination.is_symlink():
|
|
440
465
|
raise PipelineStateError(f"promotion destination already exists: {destination}")
|
|
441
|
-
tracks[name] =
|
|
466
|
+
tracks[name] = state_checkpoint._tree_digest(source)
|
|
442
467
|
if not tracks:
|
|
443
468
|
raise PipelineStateError("lookahead track has no promotable artifacts")
|
|
444
|
-
drift =
|
|
469
|
+
drift = state_checkpoint._classify_plan_drift(repo, next_state, base, landing)
|
|
445
470
|
roadmap_path = project / "ROADMAP.md"
|
|
446
471
|
roadmap_text = pipeline_state._read_real_file(roadmap_path, "ROADMAP.md")
|
|
447
472
|
target_state = _promotion_state(
|
|
@@ -464,10 +489,10 @@ def _prepare_promotion(
|
|
|
464
489
|
"landing": landing,
|
|
465
490
|
"base": base,
|
|
466
491
|
"tracks": tracks,
|
|
467
|
-
"residual_sha256":
|
|
468
|
-
"next_state_sha256":
|
|
469
|
-
"active_state_sha256":
|
|
470
|
-
"roadmap_sha256":
|
|
492
|
+
"residual_sha256": state_checkpoint._tree_digest(next_root, tuple(tracks)),
|
|
493
|
+
"next_state_sha256": state_checkpoint._sha256(next_text),
|
|
494
|
+
"active_state_sha256": state_checkpoint._sha256(active_text),
|
|
495
|
+
"roadmap_sha256": state_checkpoint._sha256(roadmap_text),
|
|
471
496
|
"target_state": target_state,
|
|
472
497
|
"target_roadmap": target_roadmap,
|
|
473
498
|
"drift": drift,
|
|
@@ -521,7 +546,7 @@ def _resume_track_moves(project: Path, journal: dict[str, object], path: Path) -
|
|
|
521
546
|
if not source_exists and not destination_exists:
|
|
522
547
|
raise PipelineStateError(f"promotion lost both source and destination: {name}")
|
|
523
548
|
candidate = source if source_exists else destination
|
|
524
|
-
if
|
|
549
|
+
if state_checkpoint._tree_digest(candidate) != expected_digest:
|
|
525
550
|
raise PipelineStateError(f"promotion track drifted: {name}")
|
|
526
551
|
if source_exists:
|
|
527
552
|
source.rename(destination)
|
|
@@ -542,7 +567,7 @@ def _resume_metadata(project: Path, journal: dict[str, object], path: Path) -> N
|
|
|
542
567
|
raise PipelineStateError("promotion journal has invalid metadata")
|
|
543
568
|
if current == desired:
|
|
544
569
|
continue
|
|
545
|
-
if
|
|
570
|
+
if state_checkpoint._sha256(current) != expected_original:
|
|
546
571
|
raise PipelineStateError(f"promotion metadata drifted: {target}")
|
|
547
572
|
pipeline_state._atomic_write(target, desired)
|
|
548
573
|
journal["stage"] = f"updated:{target.name}"
|
|
@@ -560,9 +585,9 @@ def _resume_next_removal(
|
|
|
560
585
|
if residual.exists() or residual.is_symlink():
|
|
561
586
|
raise PipelineStateError("promotion has both next track and residual staging")
|
|
562
587
|
next_text = pipeline_state._read_real_file(next_root / "STATE.md", "next/STATE.md")
|
|
563
|
-
if
|
|
588
|
+
if state_checkpoint._sha256(next_text) != journal.get("next_state_sha256"):
|
|
564
589
|
raise PipelineStateError("lookahead STATE drifted during promotion")
|
|
565
|
-
if
|
|
590
|
+
if state_checkpoint._tree_digest(next_root) != journal.get("residual_sha256"):
|
|
566
591
|
raise PipelineStateError("lookahead residual drifted during promotion")
|
|
567
592
|
next_root.rename(residual)
|
|
568
593
|
journal["stage"] = "next-staged"
|
|
@@ -574,7 +599,7 @@ def _resume_next_removal(
|
|
|
574
599
|
raise PipelineStateError("promotion lost next track and residual staging")
|
|
575
600
|
if residual.is_symlink() or not residual.is_dir():
|
|
576
601
|
raise PipelineStateError(f"promotion residual must be a real directory: {residual}")
|
|
577
|
-
if
|
|
602
|
+
if state_checkpoint._tree_digest(residual) != journal.get("residual_sha256"):
|
|
578
603
|
raise PipelineStateError("staged lookahead residual drifted during promotion")
|
|
579
604
|
|
|
580
605
|
|
|
@@ -714,30 +739,3 @@ def promote_next(
|
|
|
714
739
|
"commit": commit,
|
|
715
740
|
"drift": journal["drift"],
|
|
716
741
|
}
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
# pipeline_state imports this module, so the parent is resolved after the
|
|
720
|
-
# definitions above. Parent functions are looked up on the module at call time
|
|
721
|
-
# so patches applied to pipeline_state stay visible here.
|
|
722
|
-
if __package__: # imported as scripts.state_promote
|
|
723
|
-
from . import pipeline_state
|
|
724
|
-
from .pipeline_state import (
|
|
725
|
-
NULL,
|
|
726
|
-
PROMOTION_RESIDUAL,
|
|
727
|
-
PROMOTION_SCHEMA,
|
|
728
|
-
PROMOTION_TRACKS,
|
|
729
|
-
SLUG_RE,
|
|
730
|
-
PipelineState,
|
|
731
|
-
PipelineStateError,
|
|
732
|
-
)
|
|
733
|
-
else: # standalone script or sibling import
|
|
734
|
-
import pipeline_state
|
|
735
|
-
from pipeline_state import (
|
|
736
|
-
NULL,
|
|
737
|
-
PROMOTION_RESIDUAL,
|
|
738
|
-
PROMOTION_SCHEMA,
|
|
739
|
-
PROMOTION_TRACKS,
|
|
740
|
-
SLUG_RE,
|
|
741
|
-
PipelineState,
|
|
742
|
-
PipelineStateError,
|
|
743
|
-
)
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Run canonical workflow helpers with fixed arguments and fail-stop receipts."""
|
|
3
|
+
|
|
4
|
+
import argparse
|
|
5
|
+
import hashlib
|
|
6
|
+
import json
|
|
7
|
+
import subprocess
|
|
8
|
+
import sys
|
|
9
|
+
import tempfile
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
|
|
12
|
+
try:
|
|
13
|
+
from scripts import _common
|
|
14
|
+
except ImportError: # bundled copy inside a skill's scripts directory
|
|
15
|
+
import _common
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class StepFailed(RuntimeError):
|
|
19
|
+
pass
|
|
20
|
+
|
|
21
|
+
INSPECTION_SPECS = (("inspect_codebase", "codebase-mapper", "codebase", "evidence-codebase.md"),
|
|
22
|
+
("inspect_docs", "docs-auditor", "docs-audit", "DOCS-AUDIT.md"))
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def run_workflow(repo: Path, action: str, project_dir: str, expected_head: str = None,
|
|
26
|
+
task_id: str = None, round_size: int = None, inspection: Path = None,
|
|
27
|
+
mapper_reviewed: bool = False) -> dict:
|
|
28
|
+
steps = []
|
|
29
|
+
outputs = {}
|
|
30
|
+
scripts = Path(__file__).resolve().parent
|
|
31
|
+
|
|
32
|
+
def step(script, *arguments, raw=False):
|
|
33
|
+
command = [sys.executable, "-B", str(scripts / script), *arguments]
|
|
34
|
+
completed = subprocess.run(command, cwd=repo, capture_output=True, text=True)
|
|
35
|
+
receipt = {"script": script, "command": command, "exit_code": completed.returncode,
|
|
36
|
+
"stdout": completed.stdout, "stderr": completed.stderr}
|
|
37
|
+
steps.append(receipt)
|
|
38
|
+
if completed.stderr:
|
|
39
|
+
sys.stderr.write(completed.stderr)
|
|
40
|
+
if completed.returncode:
|
|
41
|
+
raise StepFailed(script)
|
|
42
|
+
if raw:
|
|
43
|
+
return completed.stdout
|
|
44
|
+
try:
|
|
45
|
+
receipt["result"] = json.loads(completed.stdout)
|
|
46
|
+
except json.JSONDecodeError as error:
|
|
47
|
+
raise StepFailed(f"{script} did not return JSON") from error
|
|
48
|
+
return receipt["result"]
|
|
49
|
+
|
|
50
|
+
common = ["--repo", str(repo), "--project-dir", project_dir]
|
|
51
|
+
try:
|
|
52
|
+
if action == "route":
|
|
53
|
+
step("pipeline_state.py", "route", *common)
|
|
54
|
+
elif action == "prepare-inspect":
|
|
55
|
+
state = step("pipeline_state.py", "validate", *common)["state"]
|
|
56
|
+
if project_dir != ".project" or state["phase"] != "inspect" or state["status"] != "active":
|
|
57
|
+
raise StepFailed("initial inspection requires the active inspect track")
|
|
58
|
+
specs = INSPECTION_SPECS
|
|
59
|
+
if any((repo / project_dir / "research" / spec[3]).exists() or
|
|
60
|
+
(repo / project_dir / "research" / spec[3]).is_symlink() for spec in specs):
|
|
61
|
+
raise StepFailed("prior inspection evidence requires the re-inspection contract")
|
|
62
|
+
branch = subprocess.run(["git", "branch", "--show-current"], cwd=repo,
|
|
63
|
+
capture_output=True, text=True, check=True).stdout.strip()
|
|
64
|
+
if branch != state["branch"]:
|
|
65
|
+
raise StepFailed("current branch differs from the recorded inspection branch")
|
|
66
|
+
pending = step("discussion_records.py", "pending", "--repo", str(repo))
|
|
67
|
+
if pending["pending"]:
|
|
68
|
+
raise StepFailed("pending discussion requires its owner disposition")
|
|
69
|
+
inventory = step("check_docs_audit.py", "--repo", str(repo), "--emit-inventory", raw=True)
|
|
70
|
+
resources = scripts.parent
|
|
71
|
+
if not (resources / "references").is_dir():
|
|
72
|
+
resources = resources / "skills/gsd-path"
|
|
73
|
+
for _, role, template, _ in specs:
|
|
74
|
+
for path in (resources / "references" / f"{role}.md", resources / "templates" / f"{template}.md"):
|
|
75
|
+
if not path.is_file():
|
|
76
|
+
raise StepFailed(f"missing inspection resource: {path}")
|
|
77
|
+
staging = Path(tempfile.mkdtemp(prefix="gsd-path-inspect-"))
|
|
78
|
+
inventory_file = staging / "inventory.txt"
|
|
79
|
+
inventory_file.write_text(inventory, encoding="utf-8")
|
|
80
|
+
assignments = []
|
|
81
|
+
for task_name, role, template, filename in specs:
|
|
82
|
+
isolated = step("isolation.py", "isolate-verify", "--repo", str(repo),
|
|
83
|
+
"--base", expected_head, "--name", task_name.replace("_", "-"))
|
|
84
|
+
role_path = resources / "references" / f"{role}.md"
|
|
85
|
+
template_path = resources / "templates" / f"{template}.md"
|
|
86
|
+
output = f"{project_dir}/research/{filename}"
|
|
87
|
+
brief_file = staging / f"{task_name}.md"
|
|
88
|
+
brief = (f"Logical task: {task_name}\nRead and follow role: {role_path}\n"
|
|
89
|
+
f"Template: {template_path}\nRepository and command cwd: {isolated['worktree']}\n"
|
|
90
|
+
f"Recorded baseline and Audited HEAD: {isolated['base']}\n"
|
|
91
|
+
f"Write only: {Path(isolated['worktree']) / output}\n"
|
|
92
|
+
"Use only this supplied sidecar for project commands; do not create worktrees.\n"
|
|
93
|
+
"The parent owns gates, collection, retirement, and phase state.\n"
|
|
94
|
+
"Exclude .git, node_modules, .project/archive, and installed GSD Path and path skill bundles.\n")
|
|
95
|
+
if task_name == "inspect_docs":
|
|
96
|
+
brief += ("Alignment mode: false. No prior audit or changed set.\n"
|
|
97
|
+
"Frozen inventory follows; use it exactly, without rediscovery:\n" + inventory)
|
|
98
|
+
brief_file.write_text(brief, encoding="utf-8")
|
|
99
|
+
assignments.append({**isolated, "task_name": task_name, "role": str(role_path),
|
|
100
|
+
"template": str(template_path), "output": output,
|
|
101
|
+
"brief_file": str(brief_file)})
|
|
102
|
+
receipt_file = staging / "inspection.json"
|
|
103
|
+
outputs["inspection"] = {"repo": str(repo), "base": expected_head,
|
|
104
|
+
"inventory_file": str(inventory_file),
|
|
105
|
+
"inventory_sha256": hashlib.sha256(inventory_file.read_bytes()).hexdigest(),
|
|
106
|
+
"assignments": assignments, "receipt_file": str(receipt_file)}
|
|
107
|
+
_common.atomic_write(receipt_file, json.dumps(outputs["inspection"], sort_keys=True) + "\n")
|
|
108
|
+
elif action == "finish-inspect":
|
|
109
|
+
if not mapper_reviewed or inspection is None or project_dir != ".project":
|
|
110
|
+
raise StepFailed("finish-inspect requires the prepared active track and mapper review")
|
|
111
|
+
prepared = json.loads(inspection.read_text(encoding="utf-8"))
|
|
112
|
+
if prepared["repo"] != str(repo) or prepared["base"] != expected_head:
|
|
113
|
+
raise StepFailed("inspection receipt does not match repository and expected HEAD")
|
|
114
|
+
assignments = {a["task_name"]: a for a in prepared["assignments"]}
|
|
115
|
+
if len(prepared["assignments"]) != len(INSPECTION_SPECS) or set(assignments) != {s[0] for s in INSPECTION_SPECS}:
|
|
116
|
+
raise StepFailed("inspection receipt must name both original assignments")
|
|
117
|
+
for task_name, _, _, filename in INSPECTION_SPECS:
|
|
118
|
+
assignment = assignments[task_name]
|
|
119
|
+
if assignment["base"] != expected_head or assignment["output"] != f".project/research/{filename}":
|
|
120
|
+
raise StepFailed("inspection assignment changed its baseline or output")
|
|
121
|
+
inventory_file = Path(prepared["inventory_file"])
|
|
122
|
+
if hashlib.sha256(inventory_file.read_bytes()).hexdigest() != prepared["inventory_sha256"]:
|
|
123
|
+
raise StepFailed("frozen inspection inventory changed")
|
|
124
|
+
state = step("pipeline_state.py", "validate", *common)["state"]
|
|
125
|
+
if state["phase"] != "inspect" or state["status"] != "active":
|
|
126
|
+
raise StepFailed("inspection completion requires inspect/active")
|
|
127
|
+
branch = subprocess.run(["git", "branch", "--show-current"], cwd=repo,
|
|
128
|
+
capture_output=True, text=True, check=True).stdout.strip()
|
|
129
|
+
if state["branch"] != branch:
|
|
130
|
+
raise StepFailed("current branch differs from the recorded inspection branch")
|
|
131
|
+
pending = step("discussion_records.py", "pending", "--repo", str(repo))
|
|
132
|
+
if pending["pending"]:
|
|
133
|
+
raise StepFailed("pending discussion requires its owner disposition")
|
|
134
|
+
docs = assignments["inspect_docs"]
|
|
135
|
+
step("check_docs_audit.py", "--repo", docs["worktree"], "--audit", docs["output"],
|
|
136
|
+
"--inventory", str(inventory_file))
|
|
137
|
+
if f"Audited HEAD: {expected_head}" not in (Path(docs["worktree"]) / docs["output"]).read_text().splitlines():
|
|
138
|
+
raise StepFailed("audit does not name the supplied inspection baseline")
|
|
139
|
+
for task_name, _, _, _ in INSPECTION_SPECS:
|
|
140
|
+
assignment = assignments[task_name]
|
|
141
|
+
step("isolation.py", "collect-artifact", "--repo", str(repo),
|
|
142
|
+
"--source", assignment["worktree"], "--base", expected_head,
|
|
143
|
+
"--branch", assignment["branch"], "--source-path", assignment["output"],
|
|
144
|
+
"--destination-path", assignment["output"])
|
|
145
|
+
step("isolation.py", "retire", "--repo", str(repo), "--worktree", assignment["worktree"],
|
|
146
|
+
"--branch", assignment["branch"])
|
|
147
|
+
expected = [part for key, value in state.items()
|
|
148
|
+
for part in (f"--expect-{key}", "null" if value is None else str(value))]
|
|
149
|
+
step("pipeline_state.py", "transition", *common, *expected,
|
|
150
|
+
"--set-phase", "inspect", "--set-status", "done", "--event", "inspection artifacts passed")
|
|
151
|
+
elif action == "lint-round":
|
|
152
|
+
head = subprocess.run(["git", "rev-parse", "--verify", "HEAD"],
|
|
153
|
+
cwd=repo, capture_output=True, text=True, check=True).stdout.strip()
|
|
154
|
+
step("check_task_briefs.py", "--repo", str(repo), "--base", head,
|
|
155
|
+
"--tasks-dir", f"{project_dir}/tasks")
|
|
156
|
+
step("check_handoffs.py", "plan", *common)
|
|
157
|
+
elif action == "prepare-task":
|
|
158
|
+
task = step("isolation.py", "isolate-task", "--repo", str(repo),
|
|
159
|
+
"--base", expected_head, "--task-id", task_id,
|
|
160
|
+
"--round-size", str(round_size))
|
|
161
|
+
if task["mode"] == "serial":
|
|
162
|
+
step("isolation.py", "isolate-verify", "--repo", str(repo),
|
|
163
|
+
"--base", expected_head, "--name", f"task-{task_id.lower()}-verify")
|
|
164
|
+
elif action == "build-evidence":
|
|
165
|
+
proof = step("build_state.py", "verify-landed", *common, "--head", expected_head)
|
|
166
|
+
# The landing proof has one canonical home; lean final-review reuse allows only this path.
|
|
167
|
+
evidence = repo / project_dir / "build" / "evidence.json"
|
|
168
|
+
_common.atomic_write(evidence, json.dumps(proof, indent=2, sort_keys=True) + "\n")
|
|
169
|
+
steps.append({"script": "workflow_run.py", "evidence": str(evidence)})
|
|
170
|
+
elif action == "prepare-final":
|
|
171
|
+
if project_dir != ".project":
|
|
172
|
+
raise StepFailed("final review requires the active milestone")
|
|
173
|
+
pending = step("discussion_records.py", "pending", "--repo", str(repo))
|
|
174
|
+
if pending["pending"]:
|
|
175
|
+
raise StepFailed("pending discussion requires its owner disposition")
|
|
176
|
+
step("build_state.py", "verify-landed", *common, "--head", expected_head)
|
|
177
|
+
step("lean_verification.py", "--repo", str(repo), "--expected-head", expected_head)
|
|
178
|
+
else:
|
|
179
|
+
pending = step("discussion_records.py", "pending", "--repo", str(repo))
|
|
180
|
+
if pending["pending"]:
|
|
181
|
+
raise StepFailed("pending discussion requires its owner disposition")
|
|
182
|
+
step("check_handoffs.py", "plan", *common)
|
|
183
|
+
head = subprocess.run(["git", "rev-parse", "--verify", "HEAD"],
|
|
184
|
+
cwd=repo, capture_output=True, text=True, check=True).stdout.strip()
|
|
185
|
+
step("check_task_briefs.py", "--repo", str(repo), "--base", head,
|
|
186
|
+
"--tasks-dir", f"{project_dir}/tasks")
|
|
187
|
+
panel = ["validate-plan", "--plan", str(repo / project_dir / "plan/PLAN.md"),
|
|
188
|
+
"--intent", str(repo / project_dir / "intent/INTENT.md")]
|
|
189
|
+
charter = repo / ".project/CHARTER.md"
|
|
190
|
+
if charter.exists():
|
|
191
|
+
panel += ["--charter", str(charter)]
|
|
192
|
+
step("review_panel.py", *panel)
|
|
193
|
+
if action == "approve-plan":
|
|
194
|
+
step("pipeline_state.py", "approve", *common, "--kind", "plan",
|
|
195
|
+
"--expected-head", expected_head)
|
|
196
|
+
except (StepFailed, OSError, subprocess.CalledProcessError, ValueError, KeyError, TypeError) as error:
|
|
197
|
+
return {"status": "blocked", "reason": str(error), "steps": steps,
|
|
198
|
+
"next": "$gsd-path-forensics"}
|
|
199
|
+
return {"status": "complete", "steps": steps, **outputs}
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
def main(argv=None):
|
|
203
|
+
parser = argparse.ArgumentParser(description=__doc__)
|
|
204
|
+
parser.add_argument("action", choices=("route", "gate-plan", "approve-plan", "build-evidence", "lint-round", "prepare-task", "prepare-final", "prepare-inspect", "finish-inspect"))
|
|
205
|
+
parser.add_argument("--repo", type=Path, required=True)
|
|
206
|
+
parser.add_argument("--project-dir", choices=(".project", ".project/next"), default=".project")
|
|
207
|
+
parser.add_argument("--expected-head")
|
|
208
|
+
parser.add_argument("--task-id")
|
|
209
|
+
parser.add_argument("--round-size", type=int)
|
|
210
|
+
parser.add_argument("--inspection", type=Path)
|
|
211
|
+
parser.add_argument("--mapper-reviewed", action="store_true")
|
|
212
|
+
arguments = parser.parse_args(argv)
|
|
213
|
+
if arguments.action in {"approve-plan", "build-evidence", "prepare-task", "prepare-final", "prepare-inspect", "finish-inspect"} and not arguments.expected_head:
|
|
214
|
+
parser.error(f"{arguments.action} requires --expected-head")
|
|
215
|
+
if arguments.action == "prepare-task" and (not arguments.task_id or arguments.round_size is None):
|
|
216
|
+
parser.error("prepare-task requires --task-id and --round-size")
|
|
217
|
+
result = run_workflow(arguments.repo.resolve(), arguments.action,
|
|
218
|
+
arguments.project_dir, arguments.expected_head,
|
|
219
|
+
arguments.task_id, arguments.round_size, arguments.inspection,
|
|
220
|
+
arguments.mapper_reviewed)
|
|
221
|
+
print(json.dumps(result, sort_keys=True))
|
|
222
|
+
return 0 if result["status"] == "complete" else 1
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
if __name__ == "__main__":
|
|
226
|
+
raise SystemExit(main())
|
|
@@ -29,8 +29,11 @@ Before dispatch, enter from `decide/done` or `define/done` with
|
|
|
29
29
|
`--set-phase plan --set-status active`, and event `planning started`. Resume
|
|
30
30
|
`plan/blocked` through the same helper with event `planning resumed`. Require
|
|
31
31
|
the returned track state to be `plan/active`; never edit STATE directly.
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
For a blocked build, use the [build recovery contract](references/build-recovery.md).
|
|
33
|
+
The runtime's `build-repair` mode owns structural changes to the remaining task
|
|
34
|
+
inventory and the normal approval checkpoint; it is distinct from append-only
|
|
35
|
+
patch mode. Otherwise later phases block instead of replacing an approved plan.
|
|
36
|
+
Patch mode requires an approved plan, no in-progress task, and
|
|
34
37
|
state `plan/done` or `ship/blocked`; any other state blocks. `build/done` is
|
|
35
38
|
reserved exclusively for the build orchestrator's transition recovery and
|
|
36
39
|
must return there instead of reopening planning. When an active router
|
|
@@ -74,10 +77,17 @@ router supplied lookahead mode. Every per-milestone path below, including
|
|
|
74
77
|
review-panel evidence, is rooted there. Program inputs remain at `.project/`
|
|
75
78
|
as stated in Lookahead mode.
|
|
76
79
|
|
|
77
|
-
1.
|
|
78
|
-
|
|
79
|
-
and
|
|
80
|
-
|
|
80
|
+
1. Resolve the local [plan template](templates/plan.md), [task template](templates/task.md),
|
|
81
|
+
`scripts/check_handoffs.py`, and `scripts/review_panel.py` to absolute paths.
|
|
82
|
+
Quick mode reads the plan and task templates because the parent writes
|
|
83
|
+
those artifacts. Other modes pass their paths to the planner. Execute the
|
|
84
|
+
helpers through the commands below and consume their results; their Python
|
|
85
|
+
source is not planning input. Read helper source only when diagnosing a
|
|
86
|
+
concrete failure that the returned error and documented recovery cannot
|
|
87
|
+
explain.
|
|
88
|
+
2. In quick mode, skip planner dispatch and follow Quick mode below; do not
|
|
89
|
+
load the planner role or dispatch contract. In other modes, resolve the
|
|
90
|
+
local [planner role](references/planner.md) for the child, then follow the
|
|
81
91
|
local [runtime dispatch contract](references/dispatch.md) with deterministic
|
|
82
92
|
logical task name `plan`. Give it absolute role, `AGENTS.md`, `WORKFLOW.md`,
|
|
83
93
|
input, template, and output paths, including `.project/LESSONS.md` when it
|
|
@@ -133,7 +143,7 @@ as stated in Lookahead mode.
|
|
|
133
143
|
- Require a `Review depth` value (`full`, `deep`, or `verify-only`) on
|
|
134
144
|
every wave. Wave 1 and any wave touching authentication, authorization,
|
|
135
145
|
payments, data migration, or concurrency requires `full` or `deep`;
|
|
136
|
-
quick-lane single waves
|
|
146
|
+
this includes quick-lane single waves. The planner assigns `deep`
|
|
137
147
|
sparingly to waves where a wrong merge is irreversible or
|
|
138
148
|
security-critical.
|
|
139
149
|
- When INTENT.md `Surfaces:` is not `none`, require a PLAN.md
|
|
@@ -199,7 +209,9 @@ as stated in Lookahead mode.
|
|
|
199
209
|
- `status: error` or exit 2 — use the same guarded transition to set
|
|
200
210
|
`plan/blocked` with an event naming the helper error, link PLAN.md, and stop.
|
|
201
211
|
A named family that is not advertised is an assertion failure.
|
|
202
|
-
- `status: ready` —
|
|
212
|
+
- `status: ready` — resolve the local
|
|
213
|
+
[plan-panel template](templates/plan-panel.md) for the reviewers; other
|
|
214
|
+
statuses do not load this template. For each selected family, spawn one independent child
|
|
203
215
|
with logical task name `review_plan_panel_<family>`, the reviewer role
|
|
204
216
|
in plan-panel mode, the plan-panel template, and the exact helper-returned
|
|
205
217
|
model slug when the host advertises model selection. Never override the
|
|
@@ -257,12 +269,8 @@ as stated in Lookahead mode.
|
|
|
257
269
|
(event `patch plan approved`) without a plan checkpoint because build's
|
|
258
270
|
patch re-entry commits the artifacts with its `build/active` transition.
|
|
259
271
|
`pipeline_state.py transition` never approves a plan. Confirm approval,
|
|
260
|
-
link PLAN.md again, and
|
|
261
|
-
|
|
262
|
-
active `$gsd-path`, return control to that router so its bundled build
|
|
263
|
-
contract starts. When invoked directly, stop and tell the user to explicitly
|
|
264
|
-
invoke `$gsd-path`, which routes to build; do not invoke an explicit-only
|
|
265
|
-
sibling skill yourself.
|
|
272
|
+
link PLAN.md again, and use the executable phase handoff in AGENTS.md.
|
|
273
|
+
The plan approval also authorizes build; do not add another approval gate.
|
|
266
274
|
|
|
267
275
|
## Ordering rules
|
|
268
276
|
|
|
@@ -273,8 +281,8 @@ as stated in Lookahead mode.
|
|
|
273
281
|
## Quick mode
|
|
274
282
|
|
|
275
283
|
Legal entry: `define/done` where INTENT.md records `Lane: quick` (transition
|
|
276
|
-
to `plan/active
|
|
277
|
-
|
|
284
|
+
to `plan/active` using exactly the Preconditions event `planning started`;
|
|
285
|
+
record the skipped research and decide phases in the synthesis). Quick mode dispatches no planner agent — the orchestrator writes
|
|
278
286
|
the artifacts directly:
|
|
279
287
|
|
|
280
288
|
1. Write `.project/research/SYNTHESIS.md` containing only `## Settled` lines
|
|
@@ -282,7 +290,7 @@ the artifacts directly:
|
|
|
282
290
|
plus a minimal `## For the planner` naming the walking skeleton. No
|
|
283
291
|
invented decisions or runner-ups.
|
|
284
292
|
2. Write `.project/plan/PLAN.md` with exactly one wave — `Review depth:
|
|
285
|
-
|
|
293
|
+
full` or `deep` — and at most two deliverable-sized task files
|
|
286
294
|
(project policy),
|
|
287
295
|
honoring every task-contract rule above and `.project/LESSONS.md` when it
|
|
288
296
|
exists. Write `review_panel: off` and `finding_skeptics: off` regardless
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# Return a blocked build to its contract owner
|
|
2
|
+
|
|
3
|
+
Use this contract only for an active milestone at `build/blocked`: a documented
|
|
4
|
+
structural plan defect, or an explicit user ruling that changes approved intent.
|
|
5
|
+
It does not reopen ship, archived milestones, or lookahead. Build owns entry;
|
|
6
|
+
Define owns intent corrections; Plan owns the replacement task inventory and
|
|
7
|
+
approval. Routing remains a caller handoff under AGENTS.md.
|
|
8
|
+
|
|
9
|
+
## Build: checkpoint and enter
|
|
10
|
+
|
|
11
|
+
1. Record the finding or verbatim user ruling in STATE through its helper.
|
|
12
|
+
Stop dispatch. Use the normal recovery and retirement procedures until
|
|
13
|
+
every task is either unstarted `pending` with null dispatch metadata or
|
|
14
|
+
proven `done`. Preserve owned uncommitted work before any retirement.
|
|
15
|
+
Settle reviewers and their sidecars too. Dispatch records must have no pending
|
|
16
|
+
cleanup; records with reviewer `worktree` and `branch` ownership must also
|
|
17
|
+
record `cleanup_complete`. A `blocked` or `collected` outcome alone does not
|
|
18
|
+
prove retirement. Records that never owned a reviewer sidecar do not require
|
|
19
|
+
that retirement receipt. Use the existing dispatch retirement procedures;
|
|
20
|
+
recovery does not retire sidecars itself. Never infer that a timed-out child
|
|
21
|
+
stopped. Checkpoint the blocked state and artifacts using the Build
|
|
22
|
+
bookkeeping contract; the primary must be clean.
|
|
23
|
+
2. Run `pipeline_state.py transition` with the complete current state expected,
|
|
24
|
+
`--set-status active`, and the matching target and event:
|
|
25
|
+
|
|
26
|
+
| Cause | Target | Exact event |
|
|
27
|
+
| --- | --- | --- |
|
|
28
|
+
| User changes a criterion, constraint, or veto | `--set-phase define` | `build intent corrections requested` |
|
|
29
|
+
| Task inventory, dependency, or wave repair | `--set-phase plan` | `build plan repair requested` |
|
|
30
|
+
|
|
31
|
+
The helper records the committed recovery base in STATE atomically. Do not
|
|
32
|
+
author or edit that record. Milestone, branch, integration settings, and
|
|
33
|
+
landed task contracts remain fixed throughout recovery.
|
|
34
|
+
3. Return to the router or name the selected explicit skill. The route names
|
|
35
|
+
`corrections` for Define and `build-repair` for Plan. Other blocked-build
|
|
36
|
+
failures continue through ordinary Build recovery.
|
|
37
|
+
|
|
38
|
+
## Define and Plan: prepare before editing
|
|
39
|
+
|
|
40
|
+
Run the bundled `pipeline_state.py prepare-build-recovery --repo <absolute-root>`
|
|
41
|
+
before changing any recovery artifact. This repeatable operation preserves the
|
|
42
|
+
old review directory under `plan/build-recovery-<base>/review` and starts a fresh
|
|
43
|
+
active review directory. STATE's recorded base owns an interrupted move; rerun
|
|
44
|
+
this command to finish it. The helper validates the preserved bytes against Git.
|
|
45
|
+
Do not remove, rewrite, or use the preserved reviews as current approval.
|
|
46
|
+
|
|
47
|
+
**Define corrections.** Read the existing intent and governing program artifacts.
|
|
48
|
+
Interview only the requested change; append the user's words under
|
|
49
|
+
`## Corrections`, revise the affected intent, and present the delta for approval.
|
|
50
|
+
Keep the milestone identity. Reclassify the lane using the normal lane rules.
|
|
51
|
+
After approval, use the normal `define/active → define/done` transition and route
|
|
52
|
+
from the approved lane. Standard intent goes through Research and Decide again;
|
|
53
|
+
quick and milestone intent use their existing evidence gates. A program charter
|
|
54
|
+
or roadmap conflict still requires its legal owner gate; this path cannot waive it.
|
|
55
|
+
|
|
56
|
+
**Plan build-repair.** Read the corrected intent, current synthesis, existing plan,
|
|
57
|
+
task files, and recovery base. Use the normal planner, lint, panel, and approval
|
|
58
|
+
gates. Repair the remaining task inventory as needed, including split, rename,
|
|
59
|
+
dependency, or wave changes. Keep IDs ordered and contiguous. Preserve every
|
|
60
|
+
landed task file byte-for-byte, including its recorded base and proof. Any new
|
|
61
|
+
work to satisfy a corrected criterion belongs in new pending tasks, not rewritten
|
|
62
|
+
landed contracts. A plan-only recovery must not change approved intent.
|
|
63
|
+
|
|
64
|
+
## Approve and return to Build
|
|
65
|
+
|
|
66
|
+
Use normal `pipeline_state.py approve --kind plan --expected-head <HEAD>`.
|
|
67
|
+
Neither `--patch` nor `--defer-checkpoint` is legal for recovery. The helper
|
|
68
|
+
checks landed-task preservation and restored intent ownership, restores review
|
|
69
|
+
evidence only for unchanged contracts, and creates the normal journaled plan
|
|
70
|
+
checkpoint. A failed approval leaves recovery open.
|
|
71
|
+
|
|
72
|
+
Return through `plan/done → build/active` with event `build started`. The dispatch
|
|
73
|
+
driver uses a separate record directory for this recovery base, while retaining
|
|
74
|
+
the milestone budget ledger. Resume only from the new approved task inventory.
|
|
75
|
+
Unchanged wave evidence remains usable; changed waves need review in the new
|
|
76
|
+
record directory. Retained task Verify receipts remain historical evidence for
|
|
77
|
+
their original task and base, never proof for a changed task. Final review still
|
|
78
|
+
requires current-HEAD evidence before shipment.
|
|
@@ -122,6 +122,12 @@ directory for the full logical session; resumptions reuse it. Record completed
|
|
|
122
122
|
parent CLI run events and each native child's session events with stable logical
|
|
123
123
|
task names before the next dispatch. The helper reads host counters and refuses
|
|
124
124
|
incomplete or ambiguous usage; never estimate tokens or reset the ledger.
|
|
125
|
+
When the verified CLI adapter reports cumulative counters across `resume`, record
|
|
126
|
+
each later invocation with `--previous-events <previous recorded CLI events>`.
|
|
127
|
+
The helper checks thread identity and records only the new output, preserving the
|
|
128
|
+
raw total and predecessor. Keep that chain in order; never sum cumulative totals.
|
|
129
|
+
Use ordinary `record` for per-invocation counters. An unknown counter convention
|
|
130
|
+
is unproven usage, not permission to guess.
|
|
125
131
|
Run `admit` for the next task and stop dispatch on a blocked result. Preserve
|
|
126
132
|
its output in the dispatch evidence. This gates observed usage only: concurrent
|
|
127
133
|
or in-flight work can overrun before the host reports usage. Codex CLI has no
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|