@opengsd/gsd-path 1.4.0 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +460 -341
- package/DOCS.md +16 -5
- package/FULL.md +67 -6
- package/HOOKS.md +158 -10
- package/MIGRATE.md +12 -0
- package/QUICK.md +4 -2
- package/README.md +136 -116
- package/RUNTIME.md +24 -6
- package/UPDATE.md +39 -3
- package/WORKFLOW.md +80 -4
- package/package.json +5 -2
- package/platforms/shared-agents/dispatch.md +13 -0
- package/scripts/_common.py +256 -2
- package/scripts/archive_milestone.py +14 -13
- package/scripts/build_recovery.py +155 -58
- package/scripts/build_state.py +274 -8
- package/scripts/check_docs_audit.py +77 -4
- package/scripts/check_handoffs.py +635 -57
- package/scripts/check_task_briefs.py +293 -32
- package/scripts/detect_project.py +260 -20
- package/scripts/discussion_records.py +9 -1
- package/scripts/discussion_validate.py +93 -35
- package/scripts/dispatch_driver.py +549 -53
- package/scripts/git_guard.py +27 -8
- package/scripts/guard_hook.py +2630 -210
- package/scripts/install.mjs +99 -11
- package/scripts/install.py +231 -46
- package/scripts/integration.py +244 -65
- package/scripts/isolation.py +539 -70
- package/scripts/loop_run.py +16 -4
- package/scripts/members.py +77 -32
- package/scripts/migrate_core.py +2 -0
- package/scripts/model_policy.py +5 -1
- package/scripts/path_config.py +3 -3
- package/scripts/pipeline_diagnose.py +17 -2
- package/scripts/pipeline_git.py +131 -42
- package/scripts/pipeline_state.py +139 -39
- package/scripts/pipeline_undo.py +118 -16
- package/scripts/promote_lookahead.py +3 -3
- package/scripts/review_findings.py +180 -44
- package/scripts/roadmap.py +9 -1
- package/scripts/runtime_store.py +21 -2
- package/scripts/skill-resources.json +9 -2
- package/scripts/state_checkpoint.py +39 -36
- package/scripts/state_promote.py +15 -4
- package/scripts/status_runtime.py +22 -4
- package/scripts/task_context.py +14 -3
- package/scripts/wizard.mjs +1 -0
- package/scripts/workflow_run.py +14 -4
- package/scripts/worktree_paths.py +54 -2
- package/skills/gsd-path/DEFINE.md +34 -5
- package/skills/gsd-path/PLAN.md +14 -3
- package/skills/gsd-path/RESEARCH.md +11 -0
- package/skills/gsd-path/ROADMAP.md +16 -6
- package/skills/gsd-path/SHIP.md +32 -5
- package/skills/gsd-path/SKILL.md +52 -24
- package/skills/gsd-path/references/build-native.md +112 -10
- package/skills/gsd-path/references/build-recovery.md +13 -0
- package/skills/gsd-path/references/coder.md +7 -3
- package/skills/gsd-path/references/dispatch.md +13 -0
- package/skills/gsd-path/references/docs-auditor.md +5 -0
- package/skills/gsd-path/references/operating-rules.md +11 -3
- package/skills/gsd-path/references/planner.md +26 -4
- package/skills/gsd-path/references/reviewer-final.md +20 -2
- package/skills/gsd-path/references/reviewer-wave.md +56 -12
- package/skills/gsd-path/references/reviewer.md +3 -1
- package/skills/gsd-path/references/runtime-selection.md +9 -0
- package/skills/gsd-path/references/spec-probes.md +150 -0
- package/skills/gsd-path/scripts/_common.py +256 -2
- package/skills/gsd-path/scripts/archive_milestone.py +14 -13
- package/skills/gsd-path/scripts/build_recovery.py +155 -58
- package/skills/gsd-path/scripts/build_state.py +274 -8
- package/skills/gsd-path/scripts/check_docs_audit.py +77 -4
- package/skills/gsd-path/scripts/check_handoffs.py +635 -57
- package/skills/gsd-path/scripts/check_task_briefs.py +293 -32
- package/skills/gsd-path/scripts/detect_project.py +260 -20
- package/skills/gsd-path/scripts/discussion_records.py +9 -1
- package/skills/gsd-path/scripts/discussion_validate.py +93 -35
- package/skills/gsd-path/scripts/dispatch_driver.py +549 -53
- package/skills/gsd-path/scripts/git_guard.py +27 -8
- package/skills/gsd-path/scripts/integration.py +244 -65
- package/skills/gsd-path/scripts/isolation.py +539 -70
- package/skills/gsd-path/scripts/loop_run.py +16 -4
- package/skills/gsd-path/scripts/members.py +77 -32
- package/skills/gsd-path/scripts/model_policy.py +5 -1
- package/skills/gsd-path/scripts/path_config.py +3 -3
- package/skills/gsd-path/scripts/pipeline_git.py +131 -42
- package/skills/gsd-path/scripts/pipeline_state.py +139 -39
- package/skills/gsd-path/scripts/promote_lookahead.py +3 -3
- package/skills/gsd-path/scripts/review_findings.py +180 -44
- package/skills/gsd-path/scripts/roadmap.py +9 -1
- package/skills/gsd-path/scripts/state_checkpoint.py +39 -36
- package/skills/gsd-path/scripts/state_promote.py +15 -4
- package/skills/gsd-path/scripts/status_runtime.py +22 -4
- package/skills/gsd-path/scripts/task_context.py +14 -3
- package/skills/gsd-path/scripts/workflow_run.py +14 -4
- package/skills/gsd-path/scripts/worktree_paths.py +54 -2
- package/skills/gsd-path/templates/docs-audit.md +5 -1
- package/skills/gsd-path/templates/final-review.md +11 -2
- package/skills/gsd-path/templates/intent.md +30 -0
- package/skills/gsd-path/templates/patch-findings.md +3 -3
- package/skills/gsd-path/templates/plan.md +17 -2
- package/skills/gsd-path/templates/research-handoff.md +14 -3
- package/skills/gsd-path/templates/state.md +2 -1
- package/skills/gsd-path/templates/task.md +1 -0
- package/skills/gsd-path/templates/wave-review.md +28 -9
- package/skills/gsd-path-build/references/build-native.md +112 -10
- package/skills/gsd-path-build/references/build-recovery.md +13 -0
- package/skills/gsd-path-build/references/coder.md +7 -3
- package/skills/gsd-path-build/references/dispatch.md +13 -0
- package/skills/gsd-path-build/references/operating-rules.md +11 -3
- package/skills/gsd-path-build/references/reviewer-final.md +20 -2
- package/skills/gsd-path-build/references/reviewer-wave.md +56 -12
- package/skills/gsd-path-build/references/reviewer.md +3 -1
- package/skills/gsd-path-build/references/runtime-selection.md +9 -0
- package/skills/gsd-path-build/references/spec-probes.md +150 -0
- package/skills/gsd-path-build/scripts/_common.py +256 -2
- package/skills/gsd-path-build/scripts/archive_milestone.py +14 -13
- package/skills/gsd-path-build/scripts/build_recovery.py +155 -58
- package/skills/gsd-path-build/scripts/build_state.py +274 -8
- package/skills/gsd-path-build/scripts/check_handoffs.py +635 -57
- package/skills/gsd-path-build/scripts/check_task_briefs.py +293 -32
- package/skills/gsd-path-build/scripts/detect_project.py +260 -20
- package/skills/gsd-path-build/scripts/discussion_records.py +9 -1
- package/skills/gsd-path-build/scripts/discussion_validate.py +93 -35
- package/skills/gsd-path-build/scripts/dispatch_driver.py +549 -53
- package/skills/gsd-path-build/scripts/integration.py +244 -65
- package/skills/gsd-path-build/scripts/isolation.py +539 -70
- package/skills/gsd-path-build/scripts/loop_run.py +16 -4
- package/skills/gsd-path-build/scripts/members.py +77 -32
- package/skills/gsd-path-build/scripts/model_policy.py +5 -1
- package/skills/gsd-path-build/scripts/path_config.py +3 -3
- package/skills/gsd-path-build/scripts/pipeline_git.py +131 -42
- package/skills/gsd-path-build/scripts/pipeline_state.py +139 -39
- package/skills/gsd-path-build/scripts/promote_lookahead.py +3 -3
- package/skills/gsd-path-build/scripts/review_findings.py +180 -44
- package/skills/gsd-path-build/scripts/roadmap.py +9 -1
- package/skills/gsd-path-build/scripts/state_checkpoint.py +39 -36
- package/skills/gsd-path-build/scripts/state_promote.py +15 -4
- package/skills/gsd-path-build/scripts/task_context.py +14 -3
- package/skills/gsd-path-build/scripts/workflow_run.py +14 -4
- package/skills/gsd-path-build/scripts/worktree_paths.py +54 -2
- package/skills/gsd-path-build/templates/task.md +1 -0
- package/skills/gsd-path-build/templates/wave-review.md +28 -9
- package/skills/gsd-path-decide/references/dispatch.md +13 -0
- package/skills/gsd-path-decide/references/operating-rules.md +11 -3
- package/skills/gsd-path-decide/references/runtime-selection.md +9 -0
- package/skills/gsd-path-decide/scripts/_common.py +256 -2
- package/skills/gsd-path-decide/scripts/archive_milestone.py +14 -13
- package/skills/gsd-path-decide/scripts/build_recovery.py +155 -58
- package/skills/gsd-path-decide/scripts/check_handoffs.py +635 -57
- package/skills/gsd-path-decide/scripts/check_task_briefs.py +293 -32
- package/skills/gsd-path-decide/scripts/detect_project.py +260 -20
- package/skills/gsd-path-decide/scripts/discussion_records.py +9 -1
- package/skills/gsd-path-decide/scripts/discussion_validate.py +93 -35
- package/skills/gsd-path-decide/scripts/integration.py +244 -65
- package/skills/gsd-path-decide/scripts/isolation.py +539 -70
- package/skills/gsd-path-decide/scripts/loop_run.py +16 -4
- package/skills/gsd-path-decide/scripts/members.py +77 -32
- package/skills/gsd-path-decide/scripts/model_policy.py +5 -1
- package/skills/gsd-path-decide/scripts/path_config.py +3 -3
- package/skills/gsd-path-decide/scripts/pipeline_git.py +131 -42
- package/skills/gsd-path-decide/scripts/pipeline_state.py +139 -39
- package/skills/gsd-path-decide/scripts/promote_lookahead.py +3 -3
- package/skills/gsd-path-decide/scripts/roadmap.py +9 -1
- package/skills/gsd-path-decide/scripts/state_checkpoint.py +39 -36
- package/skills/gsd-path-decide/scripts/state_promote.py +15 -4
- package/skills/gsd-path-decide/scripts/worktree_paths.py +54 -2
- package/skills/gsd-path-define/SKILL.md +34 -5
- package/skills/gsd-path-define/references/build-recovery.md +13 -0
- package/skills/gsd-path-define/references/operating-rules.md +11 -3
- package/skills/gsd-path-define/references/runtime-selection.md +9 -0
- package/skills/gsd-path-define/references/spec-probes.md +150 -0
- package/skills/gsd-path-define/scripts/_common.py +256 -2
- package/skills/gsd-path-define/scripts/archive_milestone.py +14 -13
- package/skills/gsd-path-define/scripts/build_recovery.py +155 -58
- package/skills/gsd-path-define/scripts/check_handoffs.py +635 -57
- package/skills/gsd-path-define/scripts/check_task_briefs.py +293 -32
- package/skills/gsd-path-define/scripts/detect_project.py +260 -20
- package/skills/gsd-path-define/scripts/discussion_records.py +9 -1
- package/skills/gsd-path-define/scripts/discussion_validate.py +93 -35
- package/skills/gsd-path-define/scripts/integration.py +244 -65
- package/skills/gsd-path-define/scripts/isolation.py +539 -70
- package/skills/gsd-path-define/scripts/loop_run.py +16 -4
- package/skills/gsd-path-define/scripts/members.py +77 -32
- package/skills/gsd-path-define/scripts/model_policy.py +5 -1
- package/skills/gsd-path-define/scripts/path_config.py +3 -3
- package/skills/gsd-path-define/scripts/pipeline_git.py +131 -42
- package/skills/gsd-path-define/scripts/pipeline_state.py +139 -39
- package/skills/gsd-path-define/scripts/promote_lookahead.py +3 -3
- package/skills/gsd-path-define/scripts/roadmap.py +9 -1
- package/skills/gsd-path-define/scripts/state_checkpoint.py +39 -36
- package/skills/gsd-path-define/scripts/state_promote.py +15 -4
- package/skills/gsd-path-define/scripts/worktree_paths.py +54 -2
- package/skills/gsd-path-define/templates/intent.md +30 -0
- package/skills/gsd-path-define/templates/state.md +2 -1
- package/skills/gsd-path-discuss/references/operating-rules.md +11 -3
- package/skills/gsd-path-discuss/references/runtime-selection.md +9 -0
- package/skills/gsd-path-discuss/scripts/_common.py +256 -2
- package/skills/gsd-path-discuss/scripts/discussion_records.py +9 -1
- package/skills/gsd-path-discuss/scripts/loop_run.py +16 -4
- package/skills/gsd-path-discuss/scripts/model_policy.py +5 -1
- package/skills/gsd-path-discuss/scripts/path_config.py +3 -3
- package/skills/gsd-path-discuss/scripts/worktree_paths.py +54 -2
- package/skills/gsd-path-docs-audit/references/dispatch.md +13 -0
- package/skills/gsd-path-docs-audit/references/docs-auditor.md +5 -0
- package/skills/gsd-path-docs-audit/references/operating-rules.md +11 -3
- package/skills/gsd-path-docs-audit/references/runtime-selection.md +9 -0
- package/skills/gsd-path-docs-audit/scripts/_common.py +256 -2
- package/skills/gsd-path-docs-audit/scripts/archive_milestone.py +14 -13
- package/skills/gsd-path-docs-audit/scripts/build_recovery.py +155 -58
- package/skills/gsd-path-docs-audit/scripts/check_docs_audit.py +77 -4
- package/skills/gsd-path-docs-audit/scripts/check_handoffs.py +635 -57
- package/skills/gsd-path-docs-audit/scripts/check_task_briefs.py +293 -32
- package/skills/gsd-path-docs-audit/scripts/detect_project.py +260 -20
- package/skills/gsd-path-docs-audit/scripts/discussion_records.py +9 -1
- package/skills/gsd-path-docs-audit/scripts/discussion_validate.py +93 -35
- package/skills/gsd-path-docs-audit/scripts/integration.py +244 -65
- package/skills/gsd-path-docs-audit/scripts/isolation.py +539 -70
- package/skills/gsd-path-docs-audit/scripts/loop_run.py +16 -4
- package/skills/gsd-path-docs-audit/scripts/members.py +77 -32
- package/skills/gsd-path-docs-audit/scripts/model_policy.py +5 -1
- package/skills/gsd-path-docs-audit/scripts/path_config.py +3 -3
- package/skills/gsd-path-docs-audit/scripts/pipeline_git.py +131 -42
- package/skills/gsd-path-docs-audit/scripts/pipeline_state.py +139 -39
- package/skills/gsd-path-docs-audit/scripts/promote_lookahead.py +3 -3
- package/skills/gsd-path-docs-audit/scripts/roadmap.py +9 -1
- package/skills/gsd-path-docs-audit/scripts/state_checkpoint.py +39 -36
- package/skills/gsd-path-docs-audit/scripts/state_promote.py +15 -4
- package/skills/gsd-path-docs-audit/scripts/worktree_paths.py +54 -2
- package/skills/gsd-path-docs-audit/templates/docs-audit.md +5 -1
- package/skills/gsd-path-forensics/references/operating-rules.md +11 -3
- package/skills/gsd-path-forensics/references/runtime-selection.md +9 -0
- package/skills/gsd-path-forensics/scripts/_common.py +256 -2
- package/skills/gsd-path-forensics/scripts/discussion_records.py +9 -1
- package/skills/gsd-path-forensics/scripts/loop_run.py +16 -4
- package/skills/gsd-path-forensics/scripts/model_policy.py +5 -1
- package/skills/gsd-path-forensics/scripts/path_config.py +3 -3
- package/skills/gsd-path-forensics/scripts/pipeline_diagnose.py +17 -2
- package/skills/gsd-path-forensics/scripts/pipeline_undo.py +118 -16
- package/skills/gsd-path-forensics/scripts/worktree_paths.py +54 -2
- package/skills/gsd-path-inspect/references/dispatch.md +13 -0
- package/skills/gsd-path-inspect/references/docs-auditor.md +5 -0
- package/skills/gsd-path-inspect/references/operating-rules.md +11 -3
- package/skills/gsd-path-inspect/references/runtime-selection.md +9 -0
- package/skills/gsd-path-inspect/scripts/_common.py +256 -2
- package/skills/gsd-path-inspect/scripts/archive_milestone.py +14 -13
- package/skills/gsd-path-inspect/scripts/build_recovery.py +155 -58
- package/skills/gsd-path-inspect/scripts/check_docs_audit.py +77 -4
- package/skills/gsd-path-inspect/scripts/check_handoffs.py +635 -57
- package/skills/gsd-path-inspect/scripts/check_task_briefs.py +293 -32
- package/skills/gsd-path-inspect/scripts/detect_project.py +260 -20
- package/skills/gsd-path-inspect/scripts/discussion_records.py +9 -1
- package/skills/gsd-path-inspect/scripts/discussion_validate.py +93 -35
- package/skills/gsd-path-inspect/scripts/integration.py +244 -65
- package/skills/gsd-path-inspect/scripts/isolation.py +539 -70
- package/skills/gsd-path-inspect/scripts/loop_run.py +16 -4
- package/skills/gsd-path-inspect/scripts/members.py +77 -32
- package/skills/gsd-path-inspect/scripts/model_policy.py +5 -1
- package/skills/gsd-path-inspect/scripts/path_config.py +3 -3
- package/skills/gsd-path-inspect/scripts/pipeline_git.py +131 -42
- package/skills/gsd-path-inspect/scripts/pipeline_state.py +139 -39
- package/skills/gsd-path-inspect/scripts/promote_lookahead.py +3 -3
- package/skills/gsd-path-inspect/scripts/roadmap.py +9 -1
- package/skills/gsd-path-inspect/scripts/state_checkpoint.py +39 -36
- package/skills/gsd-path-inspect/scripts/state_promote.py +15 -4
- package/skills/gsd-path-inspect/scripts/workflow_run.py +14 -4
- package/skills/gsd-path-inspect/scripts/worktree_paths.py +54 -2
- package/skills/gsd-path-inspect/templates/docs-audit.md +5 -1
- package/skills/gsd-path-inspect/templates/state.md +2 -1
- package/skills/gsd-path-loop/references/operating-rules.md +11 -3
- package/skills/gsd-path-loop/references/runtime-selection.md +9 -0
- package/skills/gsd-path-loop/scripts/_common.py +256 -2
- package/skills/gsd-path-loop/scripts/discussion_records.py +9 -1
- package/skills/gsd-path-loop/scripts/loop_run.py +16 -4
- package/skills/gsd-path-loop/scripts/model_policy.py +5 -1
- package/skills/gsd-path-loop/scripts/path_config.py +3 -3
- package/skills/gsd-path-loop/scripts/worktree_paths.py +54 -2
- package/skills/gsd-path-migrate/SKILL.md +8 -0
- package/skills/gsd-path-migrate/references/operating-rules.md +11 -3
- package/skills/gsd-path-migrate/references/runtime-selection.md +9 -0
- package/skills/gsd-path-migrate/scripts/_common.py +256 -2
- package/skills/gsd-path-migrate/scripts/discussion_records.py +9 -1
- package/skills/gsd-path-migrate/scripts/loop_run.py +16 -4
- package/skills/gsd-path-migrate/scripts/migrate_core.py +2 -0
- package/skills/gsd-path-migrate/scripts/model_policy.py +5 -1
- package/skills/gsd-path-migrate/scripts/path_config.py +3 -3
- package/skills/gsd-path-plan/SKILL.md +14 -3
- package/skills/gsd-path-plan/references/build-recovery.md +13 -0
- package/skills/gsd-path-plan/references/dispatch.md +13 -0
- package/skills/gsd-path-plan/references/operating-rules.md +11 -3
- package/skills/gsd-path-plan/references/planner.md +26 -4
- package/skills/gsd-path-plan/references/runtime-selection.md +9 -0
- package/skills/gsd-path-plan/references/spec-probes.md +150 -0
- package/skills/gsd-path-plan/scripts/_common.py +256 -2
- package/skills/gsd-path-plan/scripts/archive_milestone.py +14 -13
- package/skills/gsd-path-plan/scripts/build_recovery.py +155 -58
- package/skills/gsd-path-plan/scripts/check_handoffs.py +635 -57
- package/skills/gsd-path-plan/scripts/check_task_briefs.py +293 -32
- package/skills/gsd-path-plan/scripts/detect_project.py +260 -20
- package/skills/gsd-path-plan/scripts/discussion_records.py +9 -1
- package/skills/gsd-path-plan/scripts/discussion_validate.py +93 -35
- package/skills/gsd-path-plan/scripts/integration.py +244 -65
- package/skills/gsd-path-plan/scripts/isolation.py +539 -70
- package/skills/gsd-path-plan/scripts/loop_run.py +16 -4
- package/skills/gsd-path-plan/scripts/members.py +77 -32
- package/skills/gsd-path-plan/scripts/model_policy.py +5 -1
- package/skills/gsd-path-plan/scripts/path_config.py +3 -3
- package/skills/gsd-path-plan/scripts/pipeline_git.py +131 -42
- package/skills/gsd-path-plan/scripts/pipeline_state.py +139 -39
- package/skills/gsd-path-plan/scripts/promote_lookahead.py +3 -3
- package/skills/gsd-path-plan/scripts/roadmap.py +9 -1
- package/skills/gsd-path-plan/scripts/state_checkpoint.py +39 -36
- package/skills/gsd-path-plan/scripts/state_promote.py +15 -4
- package/skills/gsd-path-plan/scripts/workflow_run.py +14 -4
- package/skills/gsd-path-plan/scripts/worktree_paths.py +54 -2
- package/skills/gsd-path-plan/templates/patch-findings.md +3 -3
- package/skills/gsd-path-plan/templates/plan.md +17 -2
- package/skills/gsd-path-plan/templates/task.md +1 -0
- package/skills/gsd-path-research/SKILL.md +11 -0
- package/skills/gsd-path-research/references/dispatch.md +13 -0
- package/skills/gsd-path-research/references/operating-rules.md +11 -3
- package/skills/gsd-path-research/references/runtime-selection.md +9 -0
- package/skills/gsd-path-research/scripts/_common.py +256 -2
- package/skills/gsd-path-research/scripts/archive_milestone.py +14 -13
- package/skills/gsd-path-research/scripts/build_recovery.py +155 -58
- package/skills/gsd-path-research/scripts/check_handoffs.py +635 -57
- package/skills/gsd-path-research/scripts/check_task_briefs.py +293 -32
- package/skills/gsd-path-research/scripts/detect_project.py +260 -20
- package/skills/gsd-path-research/scripts/discussion_records.py +9 -1
- package/skills/gsd-path-research/scripts/discussion_validate.py +93 -35
- package/skills/gsd-path-research/scripts/integration.py +244 -65
- package/skills/gsd-path-research/scripts/isolation.py +539 -70
- package/skills/gsd-path-research/scripts/loop_run.py +16 -4
- package/skills/gsd-path-research/scripts/members.py +77 -32
- package/skills/gsd-path-research/scripts/model_policy.py +5 -1
- package/skills/gsd-path-research/scripts/path_config.py +3 -3
- package/skills/gsd-path-research/scripts/pipeline_git.py +131 -42
- package/skills/gsd-path-research/scripts/pipeline_state.py +139 -39
- package/skills/gsd-path-research/scripts/promote_lookahead.py +3 -3
- package/skills/gsd-path-research/scripts/roadmap.py +9 -1
- package/skills/gsd-path-research/scripts/state_checkpoint.py +39 -36
- package/skills/gsd-path-research/scripts/state_promote.py +15 -4
- package/skills/gsd-path-research/scripts/worktree_paths.py +54 -2
- package/skills/gsd-path-research/templates/research-handoff.md +14 -3
- package/skills/gsd-path-roadmap/SKILL.md +16 -6
- package/skills/gsd-path-roadmap/references/dispatch.md +13 -0
- package/skills/gsd-path-roadmap/references/operating-rules.md +11 -3
- package/skills/gsd-path-roadmap/references/runtime-selection.md +9 -0
- package/skills/gsd-path-roadmap/scripts/_common.py +256 -2
- package/skills/gsd-path-roadmap/scripts/archive_milestone.py +14 -13
- package/skills/gsd-path-roadmap/scripts/build_recovery.py +155 -58
- package/skills/gsd-path-roadmap/scripts/check_handoffs.py +635 -57
- package/skills/gsd-path-roadmap/scripts/check_task_briefs.py +293 -32
- package/skills/gsd-path-roadmap/scripts/detect_project.py +260 -20
- package/skills/gsd-path-roadmap/scripts/discussion_records.py +9 -1
- package/skills/gsd-path-roadmap/scripts/discussion_validate.py +93 -35
- package/skills/gsd-path-roadmap/scripts/integration.py +244 -65
- package/skills/gsd-path-roadmap/scripts/isolation.py +539 -70
- package/skills/gsd-path-roadmap/scripts/loop_run.py +16 -4
- package/skills/gsd-path-roadmap/scripts/members.py +77 -32
- package/skills/gsd-path-roadmap/scripts/model_policy.py +5 -1
- package/skills/gsd-path-roadmap/scripts/path_config.py +3 -3
- package/skills/gsd-path-roadmap/scripts/pipeline_git.py +131 -42
- package/skills/gsd-path-roadmap/scripts/pipeline_state.py +139 -39
- package/skills/gsd-path-roadmap/scripts/promote_lookahead.py +3 -3
- package/skills/gsd-path-roadmap/scripts/roadmap.py +9 -1
- package/skills/gsd-path-roadmap/scripts/state_checkpoint.py +39 -36
- package/skills/gsd-path-roadmap/scripts/state_promote.py +15 -4
- package/skills/gsd-path-roadmap/scripts/worktree_paths.py +54 -2
- package/skills/gsd-path-ship/SKILL.md +32 -5
- package/skills/gsd-path-ship/references/dispatch.md +13 -0
- package/skills/gsd-path-ship/references/operating-rules.md +11 -3
- package/skills/gsd-path-ship/references/reviewer-final.md +20 -2
- package/skills/gsd-path-ship/references/reviewer-wave.md +56 -12
- package/skills/gsd-path-ship/references/reviewer.md +3 -1
- package/skills/gsd-path-ship/references/runtime-selection.md +9 -0
- package/skills/gsd-path-ship/references/spec-probes.md +150 -0
- package/skills/gsd-path-ship/scripts/_common.py +256 -2
- package/skills/gsd-path-ship/scripts/archive_milestone.py +14 -13
- package/skills/gsd-path-ship/scripts/build_recovery.py +155 -58
- package/skills/gsd-path-ship/scripts/build_state.py +274 -8
- package/skills/gsd-path-ship/scripts/check_handoffs.py +635 -57
- package/skills/gsd-path-ship/scripts/check_task_briefs.py +293 -32
- package/skills/gsd-path-ship/scripts/detect_project.py +260 -20
- package/skills/gsd-path-ship/scripts/discussion_records.py +9 -1
- package/skills/gsd-path-ship/scripts/discussion_validate.py +93 -35
- package/skills/gsd-path-ship/scripts/integration.py +244 -65
- package/skills/gsd-path-ship/scripts/isolation.py +539 -70
- package/skills/gsd-path-ship/scripts/loop_run.py +16 -4
- package/skills/gsd-path-ship/scripts/members.py +77 -32
- package/skills/gsd-path-ship/scripts/model_policy.py +5 -1
- package/skills/gsd-path-ship/scripts/path_config.py +3 -3
- package/skills/gsd-path-ship/scripts/pipeline_git.py +131 -42
- package/skills/gsd-path-ship/scripts/pipeline_state.py +139 -39
- package/skills/gsd-path-ship/scripts/promote_lookahead.py +3 -3
- package/skills/gsd-path-ship/scripts/roadmap.py +9 -1
- package/skills/gsd-path-ship/scripts/state_checkpoint.py +39 -36
- package/skills/gsd-path-ship/scripts/state_promote.py +15 -4
- package/skills/gsd-path-ship/scripts/workflow_run.py +14 -4
- package/skills/gsd-path-ship/scripts/worktree_paths.py +54 -2
- package/skills/gsd-path-ship/templates/final-review.md +11 -2
- package/skills/gsd-path-ship/templates/patch-findings.md +3 -3
- package/skills/gsd-path-ship/templates/wave-review.md +28 -9
- package/skills/gsd-path-undo/references/operating-rules.md +11 -3
- package/skills/gsd-path-undo/references/runtime-selection.md +9 -0
- package/skills/gsd-path-undo/scripts/_common.py +256 -2
- package/skills/gsd-path-undo/scripts/discussion_records.py +9 -1
- package/skills/gsd-path-undo/scripts/loop_run.py +16 -4
- package/skills/gsd-path-undo/scripts/model_policy.py +5 -1
- package/skills/gsd-path-undo/scripts/path_config.py +3 -3
- package/skills/gsd-path-undo/scripts/pipeline_undo.py +118 -16
- package/skills/gsd-path-undo/scripts/worktree_paths.py +54 -2
- package/skills/path/DEFINE.md +34 -5
- package/skills/path/PLAN.md +14 -3
- package/skills/path/RESEARCH.md +11 -0
- package/skills/path/ROADMAP.md +16 -6
- package/skills/path/SHIP.md +32 -5
- package/skills/path/SKILL.md +52 -24
- package/skills/path/references/build-native.md +112 -10
- package/skills/path/references/build-recovery.md +13 -0
- package/skills/path/references/coder.md +7 -3
- package/skills/path/references/dispatch.md +13 -0
- package/skills/path/references/docs-auditor.md +5 -0
- package/skills/path/references/operating-rules.md +11 -3
- package/skills/path/references/planner.md +26 -4
- package/skills/path/references/reviewer-final.md +20 -2
- package/skills/path/references/reviewer-wave.md +56 -12
- package/skills/path/references/reviewer.md +3 -1
- package/skills/path/references/runtime-selection.md +9 -0
- package/skills/path/references/spec-probes.md +150 -0
- package/skills/path/scripts/_common.py +256 -2
- package/skills/path/scripts/archive_milestone.py +14 -13
- package/skills/path/scripts/build_recovery.py +155 -58
- package/skills/path/scripts/build_state.py +274 -8
- package/skills/path/scripts/check_docs_audit.py +77 -4
- package/skills/path/scripts/check_handoffs.py +635 -57
- package/skills/path/scripts/check_task_briefs.py +293 -32
- package/skills/path/scripts/detect_project.py +260 -20
- package/skills/path/scripts/discussion_records.py +9 -1
- package/skills/path/scripts/discussion_validate.py +93 -35
- package/skills/path/scripts/dispatch_driver.py +549 -53
- package/skills/path/scripts/git_guard.py +27 -8
- package/skills/path/scripts/integration.py +244 -65
- package/skills/path/scripts/isolation.py +539 -70
- package/skills/path/scripts/loop_run.py +16 -4
- package/skills/path/scripts/members.py +77 -32
- package/skills/path/scripts/model_policy.py +5 -1
- package/skills/path/scripts/path_config.py +3 -3
- package/skills/path/scripts/pipeline_git.py +131 -42
- package/skills/path/scripts/pipeline_state.py +139 -39
- package/skills/path/scripts/promote_lookahead.py +3 -3
- package/skills/path/scripts/review_findings.py +180 -44
- package/skills/path/scripts/roadmap.py +9 -1
- package/skills/path/scripts/state_checkpoint.py +39 -36
- package/skills/path/scripts/state_promote.py +15 -4
- package/skills/path/scripts/status_runtime.py +22 -4
- package/skills/path/scripts/task_context.py +14 -3
- package/skills/path/scripts/workflow_run.py +14 -4
- package/skills/path/scripts/worktree_paths.py +54 -2
- package/skills/path/templates/docs-audit.md +5 -1
- package/skills/path/templates/final-review.md +11 -2
- package/skills/path/templates/intent.md +30 -0
- package/skills/path/templates/patch-findings.md +3 -3
- package/skills/path/templates/plan.md +17 -2
- package/skills/path/templates/research-handoff.md +14 -3
- package/skills/path/templates/state.md +2 -1
- package/skills/path/templates/task.md +1 -0
- package/skills/path/templates/wave-review.md +28 -9
- package/skills/gsd-path/scripts/__pycache__/_common.cpython-312.pyc +0 -0
- package/skills/gsd-path/scripts/__pycache__/check_handoffs.cpython-312.pyc +0 -0
- package/skills/gsd-path-build/scripts/__pycache__/_common.cpython-312.pyc +0 -0
- package/skills/gsd-path-build/scripts/__pycache__/check_handoffs.cpython-312.pyc +0 -0
- package/skills/gsd-path-inspect/scripts/__pycache__/_common.cpython-312.pyc +0 -0
- package/skills/gsd-path-plan/scripts/__pycache__/_common.cpython-312.pyc +0 -0
- package/skills/gsd-path-ship/scripts/__pycache__/_common.cpython-312.pyc +0 -0
|
@@ -10,7 +10,8 @@
|
|
|
10
10
|
"cursor": {"local_root": ".cursor/skills", "guard_tier": "native-fail-closed", "child_apis": ["Task"]},
|
|
11
11
|
"zed": {"local_root": ".agents/skills", "guard_tier": "git-only", "invocation_prefix": "/", "child_apis": ["spawn_agent"]},
|
|
12
12
|
"kiro": {"local_root": ".kiro/skills", "guard_tier": "git-only", "child_apis": ["invoke_sub_agent"]},
|
|
13
|
-
"kimi": {"local_root": ".kimi-code/skills", "guard_tier": "git-only", "child_apis": ["Agent"]}
|
|
13
|
+
"kimi": {"local_root": ".kimi-code/skills", "guard_tier": "git-only", "child_apis": ["Agent"]},
|
|
14
|
+
"muse": {"local_root": ".agents/skills", "guard_tier": "git-only", "invocation_prefix": "/", "child_apis": ["muse.subagent_spawn"]}
|
|
14
15
|
},
|
|
15
16
|
"skills": [
|
|
16
17
|
"gsd-path",
|
|
@@ -96,7 +97,9 @@
|
|
|
96
97
|
"skills/",
|
|
97
98
|
"platforms/",
|
|
98
99
|
"AGENTS.md",
|
|
99
|
-
"WORKFLOW.md"
|
|
100
|
+
"WORKFLOW.md",
|
|
101
|
+
"!**/__pycache__/**",
|
|
102
|
+
"!**/*.pyc"
|
|
100
103
|
],
|
|
101
104
|
"phase_resources": {
|
|
102
105
|
"gsd-path-build": [
|
|
@@ -114,6 +117,7 @@
|
|
|
114
117
|
"references/reviewer-skeptic.md",
|
|
115
118
|
"references/reviewer-final.md",
|
|
116
119
|
"references/reviewer-panel.md",
|
|
120
|
+
"references/spec-probes.md",
|
|
117
121
|
|
|
118
122
|
"templates/task.md",
|
|
119
123
|
"templates/wave-review.md",
|
|
@@ -138,6 +142,7 @@
|
|
|
138
142
|
"references/runtime-selection.md",
|
|
139
143
|
"references/operating-rules.md",
|
|
140
144
|
"references/build-recovery.md",
|
|
145
|
+
"references/spec-probes.md",
|
|
141
146
|
"templates/charter.md",
|
|
142
147
|
"templates/intent.md",
|
|
143
148
|
"templates/state.md"
|
|
@@ -173,6 +178,7 @@
|
|
|
173
178
|
"references/dispatch.md",
|
|
174
179
|
"references/model-policy.md",
|
|
175
180
|
"references/planner.md",
|
|
181
|
+
"references/spec-probes.md",
|
|
176
182
|
"templates/patch-findings.md",
|
|
177
183
|
"templates/plan.md",
|
|
178
184
|
"templates/plan-panel.md",
|
|
@@ -206,6 +212,7 @@
|
|
|
206
212
|
"references/reviewer-skeptic.md",
|
|
207
213
|
"references/reviewer-final.md",
|
|
208
214
|
"references/reviewer-panel.md",
|
|
215
|
+
"references/spec-probes.md",
|
|
209
216
|
|
|
210
217
|
"templates/archive-manifest.md",
|
|
211
218
|
"templates/final-review.md",
|
|
@@ -18,14 +18,14 @@ from pathlib import Path, PurePosixPath
|
|
|
18
18
|
from typing import Mapping, Optional, Sequence
|
|
19
19
|
|
|
20
20
|
if __package__:
|
|
21
|
-
from .isolation import IsolationError, checkpoint as isolation_checkpoint,
|
|
21
|
+
from .isolation import IsolationError, checkpoint as isolation_checkpoint, PROJECT_ENTRIES
|
|
22
22
|
else:
|
|
23
23
|
try:
|
|
24
|
-
from isolation import IsolationError, checkpoint as isolation_checkpoint,
|
|
24
|
+
from isolation import IsolationError, checkpoint as isolation_checkpoint, PROJECT_ENTRIES
|
|
25
25
|
except ModuleNotFoundError as error: # pragma: no cover - package imports used by tests
|
|
26
26
|
if error.name != "isolation":
|
|
27
27
|
raise
|
|
28
|
-
from scripts.isolation import IsolationError, checkpoint as isolation_checkpoint,
|
|
28
|
+
from scripts.isolation import IsolationError, checkpoint as isolation_checkpoint, PROJECT_ENTRIES
|
|
29
29
|
|
|
30
30
|
|
|
31
31
|
if __package__:
|
|
@@ -164,9 +164,16 @@ def _approval_details(
|
|
|
164
164
|
raise PipelineStateError(f"unsupported approval kind: {kind}")
|
|
165
165
|
|
|
166
166
|
|
|
167
|
-
def _reslice_roadmap(
|
|
167
|
+
def _reslice_roadmap(
|
|
168
|
+
repo: Path, before: str, candidate: str, state: PipelineState, state_text: str, selected: str,
|
|
169
|
+
) -> str:
|
|
170
|
+
# Define may amend its active entry until intent approval. A return to
|
|
171
|
+
# define after that approval always leaves an active recovery record.
|
|
172
|
+
amend_active = state.phase == "define" and not (
|
|
173
|
+
pipeline_state._build_recovery().context(repo, state_text) or {}
|
|
174
|
+
).get("active")
|
|
168
175
|
try:
|
|
169
|
-
return roadmap.reslice(before, candidate, state.phase, selected)
|
|
176
|
+
return roadmap.reslice(before, candidate, state.phase, selected, amend_active)
|
|
170
177
|
except roadmap.RoadmapError as error:
|
|
171
178
|
raise PipelineStateError(str(error)) from error
|
|
172
179
|
|
|
@@ -223,6 +230,10 @@ def _approval_journal(repo: Path, journal: Mapping[str, object]) -> dict[str, ob
|
|
|
223
230
|
expected_keys.add("baseline_before")
|
|
224
231
|
if not isinstance(journal.get("baseline_before"), str):
|
|
225
232
|
raise PipelineStateError("checkpoint journal has an invalid re-slice baseline")
|
|
233
|
+
if "recovery_reviews" in journal:
|
|
234
|
+
expected_keys.add("recovery_reviews")
|
|
235
|
+
if journal.get("kind") != "plan" or not isinstance(journal["recovery_reviews"], dict):
|
|
236
|
+
raise PipelineStateError("checkpoint journal has an invalid recovery review report")
|
|
226
237
|
if set(journal) != expected_keys:
|
|
227
238
|
raise PipelineStateError("checkpoint journal has invalid fields")
|
|
228
239
|
if journal.get("schema") != CHECKPOINT_SCHEMA or journal.get("repo") != str(repo):
|
|
@@ -307,7 +318,8 @@ def _approval_journal(repo: Path, journal: Mapping[str, object]) -> dict[str, ob
|
|
|
307
318
|
if journal["roadmap_path"] != ".project/ROADMAP.md":
|
|
308
319
|
raise PipelineStateError("checkpoint journal has an invalid ROADMAP path")
|
|
309
320
|
expected_roadmap = _reslice_roadmap(
|
|
310
|
-
str(journal["baseline_before"]), str(journal["roadmap_before"]), before,
|
|
321
|
+
repo, str(journal["baseline_before"]), str(journal["roadmap_before"]), before,
|
|
322
|
+
str(journal["state_before"]), str(selected),
|
|
311
323
|
) if journal["kind"] == "roadmap-reslice" else _activate_roadmap_milestone(
|
|
312
324
|
str(journal["roadmap_before"]),
|
|
313
325
|
str(selected),
|
|
@@ -423,7 +435,7 @@ def _resume_checkpoint_locked(
|
|
|
423
435
|
raise PipelineStateError("approval checkpoint returned the wrong commit")
|
|
424
436
|
_unlink_checkpoint_journal(journal_path)
|
|
425
437
|
state = pipeline_state._state_from_text(str(transaction["state_after"]))
|
|
426
|
-
|
|
438
|
+
approved: dict[str, object] = {
|
|
427
439
|
"schema": CHECKPOINT_SCHEMA,
|
|
428
440
|
"status": "approved",
|
|
429
441
|
"kind": transaction["kind"],
|
|
@@ -432,6 +444,9 @@ def _resume_checkpoint_locked(
|
|
|
432
444
|
"paths": committed.get("paths"),
|
|
433
445
|
"state": state.json(),
|
|
434
446
|
}
|
|
447
|
+
if "recovery_reviews" in transaction:
|
|
448
|
+
approved["recovery_reviews"] = transaction["recovery_reviews"]
|
|
449
|
+
return approved
|
|
435
450
|
|
|
436
451
|
|
|
437
452
|
def _validate_plan_briefs(repo: Path, kind: str, project_dir: str) -> None:
|
|
@@ -444,14 +459,14 @@ def _validate_plan_briefs(repo: Path, kind: str, project_dir: str) -> None:
|
|
|
444
459
|
# Pre-Git approval defers base-dependent checks to build.
|
|
445
460
|
return
|
|
446
461
|
if __package__:
|
|
447
|
-
from .check_task_briefs import BriefError, _member_bases, validate_task_briefs
|
|
462
|
+
from .check_task_briefs import BriefError, _member_bases, plan_validation_bases, validate_task_briefs
|
|
448
463
|
else:
|
|
449
464
|
try:
|
|
450
|
-
from check_task_briefs import BriefError, _member_bases, validate_task_briefs
|
|
465
|
+
from check_task_briefs import BriefError, _member_bases, plan_validation_bases, validate_task_briefs
|
|
451
466
|
except ModuleNotFoundError as error: # pragma: no cover - package imports
|
|
452
467
|
if error.name != "check_task_briefs":
|
|
453
468
|
raise
|
|
454
|
-
from scripts.check_task_briefs import BriefError, _member_bases, validate_task_briefs
|
|
469
|
+
from scripts.check_task_briefs import BriefError, _member_bases, plan_validation_bases, validate_task_briefs
|
|
455
470
|
if __package__:
|
|
456
471
|
from . import check_handoffs
|
|
457
472
|
else:
|
|
@@ -462,28 +477,10 @@ def _validate_plan_briefs(repo: Path, kind: str, project_dir: str) -> None:
|
|
|
462
477
|
raise
|
|
463
478
|
from scripts import check_handoffs
|
|
464
479
|
try:
|
|
465
|
-
tasks, dependency_files = check_handoffs.plan_brief_inputs(repo, project_dir)
|
|
466
|
-
landed_bases = {}
|
|
467
480
|
member_base = _member_bases(repo)
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
agent = check_handoffs._task_scalar(text, task_id, "agent")
|
|
472
|
-
if agent in {"", "null"}:
|
|
473
|
-
raise BriefError(f"{task_id} landed task has no recorded agent")
|
|
474
|
-
member = check_handoffs._strict_frontmatter(text, task_id).get("repo")
|
|
475
|
-
base_repo = repo
|
|
476
|
-
if member is not None:
|
|
477
|
-
located = member_base(member) if isinstance(member, str) and member else None
|
|
478
|
-
if located is None:
|
|
479
|
-
raise BriefError(f"repo: names no member in MEMBERS.md: {member}")
|
|
480
|
-
base_repo = located[0]
|
|
481
|
-
recorded_base = check_handoffs._task_scalar(text, task_id, "base")
|
|
482
|
-
try:
|
|
483
|
-
landed_bases[task_id] = require_commit(base_repo, require_full_sha(recorded_base))
|
|
484
|
-
except IsolationError as error:
|
|
485
|
-
raise BriefError(f"{task_id} landed task has invalid historical base: {error}") from error
|
|
486
|
-
dependency_files[task_id] = set()
|
|
481
|
+
tasks, dependency_files, landed_bases = plan_validation_bases(
|
|
482
|
+
repo, project_dir, member_base, initial=True
|
|
483
|
+
)
|
|
487
484
|
validate_task_briefs(
|
|
488
485
|
repo, head.stdout.strip(), f"{project_dir}/tasks",
|
|
489
486
|
dependency_files=dependency_files, landed_bases=landed_bases,
|
|
@@ -581,7 +578,10 @@ def checkpoint_approval(
|
|
|
581
578
|
f"{expected_head}^{{commit}}",
|
|
582
579
|
).stdout.strip()
|
|
583
580
|
if resolved_head != expected_head:
|
|
584
|
-
raise PipelineStateError(
|
|
581
|
+
raise PipelineStateError(
|
|
582
|
+
"expected-head must be an exact full commit SHA; "
|
|
583
|
+
"resolve a ref or a short SHA with git rev-parse first"
|
|
584
|
+
)
|
|
585
585
|
if pipeline_state._run_git(resolved, "rev-parse", "HEAD").stdout.strip() != expected_head:
|
|
586
586
|
raise PipelineStateError("approval must start at expected-head")
|
|
587
587
|
active_state, _, _ = pipeline_state.load_state(resolved)
|
|
@@ -596,8 +596,9 @@ def checkpoint_approval(
|
|
|
596
596
|
state, state_before, state_path = pipeline_state.load_state(resolved, project_dir)
|
|
597
597
|
changes, event, subject, body = _approval_details(kind, state, selected_milestone)
|
|
598
598
|
_validate_plan_briefs(resolved, kind, project_dir)
|
|
599
|
+
recovery_reviews = None
|
|
599
600
|
if kind == "plan" and project_dir == ".project":
|
|
600
|
-
pipeline_state._build_recovery().restore_unchanged_reviews(resolved)
|
|
601
|
+
recovery_reviews = pipeline_state._build_recovery().restore_unchanged_reviews(resolved)
|
|
601
602
|
expected = {
|
|
602
603
|
"phase": state.phase,
|
|
603
604
|
"status": state.status,
|
|
@@ -629,7 +630,7 @@ def checkpoint_approval(
|
|
|
629
630
|
if kind == "roadmap-reslice":
|
|
630
631
|
baseline_before = pipeline_state._read_real_file(project / "ROADMAP.before-reslice.md", "re-slice baseline")
|
|
631
632
|
roadmap_after = _reslice_roadmap(
|
|
632
|
-
baseline_before, roadmap_before, state, selected_milestone,
|
|
633
|
+
resolved, baseline_before, roadmap_before, state, state_before, selected_milestone,
|
|
633
634
|
) if kind == "roadmap-reslice" else _activate_roadmap_milestone(
|
|
634
635
|
roadmap_before,
|
|
635
636
|
selected_milestone,
|
|
@@ -659,6 +660,8 @@ def checkpoint_approval(
|
|
|
659
660
|
}
|
|
660
661
|
if baseline_before is not None:
|
|
661
662
|
journal["baseline_before"] = baseline_before
|
|
663
|
+
if recovery_reviews is not None:
|
|
664
|
+
journal["recovery_reviews"] = recovery_reviews
|
|
662
665
|
pipeline_state._write_json(journal_path, journal)
|
|
663
666
|
return _resume_checkpoint_locked(resolved, project, journal_path, journal)
|
|
664
667
|
|
|
@@ -740,8 +743,8 @@ def defer_approval(
|
|
|
740
743
|
if kind == "roadmap-reslice":
|
|
741
744
|
baseline = project / "ROADMAP.before-reslice.md"
|
|
742
745
|
roadmap_after = _reslice_roadmap(
|
|
743
|
-
pipeline_state._read_real_file(baseline, "re-slice baseline"),
|
|
744
|
-
roadmap_before, state, selected_milestone,
|
|
746
|
+
resolved, pipeline_state._read_real_file(baseline, "re-slice baseline"),
|
|
747
|
+
roadmap_before, state, state_before, selected_milestone,
|
|
745
748
|
)
|
|
746
749
|
else:
|
|
747
750
|
roadmap_after = _activate_roadmap_milestone(roadmap_before, selected_milestone)
|
package/scripts/state_promote.py
CHANGED
|
@@ -377,17 +377,22 @@ def _prepare_promotion(
|
|
|
377
377
|
head = pipeline_state._run_git(repo, "rev-parse", "HEAD").stdout.strip()
|
|
378
378
|
if head != base:
|
|
379
379
|
raise PipelineStateError(f"promotion must start at base SHA: {head} != {base}")
|
|
380
|
-
|
|
380
|
+
active_state, active_text, _ = pipeline_state.load_state(repo)
|
|
381
|
+
remote_default = f"origin/{active_state.default_branch}"
|
|
382
|
+
remote = pipeline_state._run_git(
|
|
383
|
+
repo, "rev-parse", "--verify", f"{remote_default}^{{commit}}"
|
|
384
|
+
).stdout.strip()
|
|
381
385
|
if remote != base:
|
|
382
386
|
raise PipelineStateError(
|
|
383
|
-
f"base SHA is not current
|
|
387
|
+
f"base SHA is not current {remote_default}: {base} != {remote}"
|
|
384
388
|
)
|
|
385
389
|
if not pipeline_state._is_ancestor(repo, landing, base):
|
|
386
|
-
raise PipelineStateError(
|
|
390
|
+
raise PipelineStateError(
|
|
391
|
+
f"landing is not an ancestor of the current {active_state.default_branch} base"
|
|
392
|
+
)
|
|
387
393
|
if pipeline_state._run_git(repo, "status", "--porcelain", "--untracked-files=all").stdout:
|
|
388
394
|
raise PipelineStateError("promotion must start from a clean worktree")
|
|
389
395
|
|
|
390
|
-
active_state, active_text, _ = pipeline_state.load_state(repo)
|
|
391
396
|
if active_state.phase != "shipped" or active_state.status != "done":
|
|
392
397
|
raise PipelineStateError("promotion requires active STATE shipped/done")
|
|
393
398
|
if active_state.milestone is None:
|
|
@@ -456,6 +461,12 @@ def _prepare_promotion(
|
|
|
456
461
|
raise PipelineStateError(
|
|
457
462
|
"lookahead integration_default does not match the active project"
|
|
458
463
|
)
|
|
464
|
+
if next_state.default_branch != active_state.default_branch:
|
|
465
|
+
raise PipelineStateError(
|
|
466
|
+
"lookahead default_branch does not match the active project: copy "
|
|
467
|
+
f"`default_branch: {active_state.default_branch}` from .project/STATE.md "
|
|
468
|
+
"into .project/next/STATE.md"
|
|
469
|
+
)
|
|
459
470
|
if next_state.milestone != milestone:
|
|
460
471
|
raise PipelineStateError(
|
|
461
472
|
f"requested milestone {milestone} != next STATE milestone {next_state.milestone}"
|
|
@@ -6,6 +6,7 @@ import hashlib
|
|
|
6
6
|
import errno
|
|
7
7
|
import json
|
|
8
8
|
import os
|
|
9
|
+
import stat
|
|
9
10
|
import subprocess
|
|
10
11
|
import sys
|
|
11
12
|
import time
|
|
@@ -151,7 +152,17 @@ def validate_runtime(data: dict) -> Path:
|
|
|
151
152
|
path = root / name
|
|
152
153
|
if path.is_symlink() or hashlib.sha256(path.read_bytes()).hexdigest() != expected:
|
|
153
154
|
raise ValueError(f"runtime file changed: {name}")
|
|
154
|
-
|
|
155
|
+
runtime_entries = set()
|
|
156
|
+
for path in root.iterdir():
|
|
157
|
+
if path.name == "__pycache__":
|
|
158
|
+
if not stat.S_ISDIR(path.lstat().st_mode):
|
|
159
|
+
raise ValueError("unexpected runtime files")
|
|
160
|
+
for cached in path.iterdir():
|
|
161
|
+
if cached.suffix != ".pyc" or not stat.S_ISREG(cached.lstat().st_mode):
|
|
162
|
+
raise ValueError("unexpected runtime files")
|
|
163
|
+
continue
|
|
164
|
+
runtime_entries.add(path.name)
|
|
165
|
+
if runtime_entries != set(files) | {"manifest.json"}:
|
|
155
166
|
raise ValueError("unexpected runtime files")
|
|
156
167
|
except (OSError, ValueError, TypeError) as error:
|
|
157
168
|
raise ValueError(hint + f" ({error})") from error
|
|
@@ -167,8 +178,13 @@ def run_guard(repo: Path, name: str) -> None:
|
|
|
167
178
|
root = resolve_runtime(repo)
|
|
168
179
|
sys.dont_write_bytecode = True
|
|
169
180
|
sys.path.insert(0, str(root))
|
|
170
|
-
|
|
171
|
-
|
|
181
|
+
previous_pycache_prefix = sys.pycache_prefix
|
|
182
|
+
sys.pycache_prefix = str(root / "manifest.json")
|
|
183
|
+
try:
|
|
184
|
+
code = compile((root / name).read_bytes(), str(root / name), "exec")
|
|
185
|
+
exec(code, {"__name__": "__main__", "__file__": str(repo / ".gsd-path" / name)})
|
|
186
|
+
finally:
|
|
187
|
+
sys.pycache_prefix = previous_pycache_prefix
|
|
172
188
|
|
|
173
189
|
|
|
174
190
|
def launch(repo: Path) -> int:
|
|
@@ -179,7 +195,9 @@ def launch(repo: Path) -> int:
|
|
|
179
195
|
except (OSError, ValueError) as error:
|
|
180
196
|
print(str(error), file=sys.stderr)
|
|
181
197
|
return 2
|
|
182
|
-
return subprocess.call([sys.executable, "-B",
|
|
198
|
+
return subprocess.call([sys.executable, "-B", "-X",
|
|
199
|
+
f"pycache_prefix={runtime.parent / 'manifest.json'}",
|
|
200
|
+
str(runtime), "status", "--repo", str(repo)],
|
|
183
201
|
env={**os.environ, "GIT_OPTIONAL_LOCKS": "0"})
|
|
184
202
|
runtime = parent / "runtime" / "pipeline_state.py"
|
|
185
203
|
lock = repo / ".gsd-path-install-lock"
|
package/scripts/task_context.py
CHANGED
|
@@ -1,23 +1,27 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
|
+
# gsd-path project runtime
|
|
2
3
|
"""Render a read-only coder intent view from the approved task and intent."""
|
|
3
4
|
|
|
4
5
|
import argparse
|
|
5
6
|
import hashlib
|
|
6
7
|
import re
|
|
7
8
|
import sys
|
|
9
|
+
sys.dont_write_bytecode = True
|
|
8
10
|
from pathlib import Path
|
|
9
11
|
|
|
10
12
|
try:
|
|
11
13
|
from scripts import check_handoffs as contracts
|
|
14
|
+
from scripts import _common
|
|
12
15
|
except ImportError:
|
|
13
16
|
import check_handoffs as contracts
|
|
17
|
+
import _common
|
|
14
18
|
|
|
15
19
|
|
|
16
20
|
def render(repo: Path, task: Path) -> str:
|
|
17
21
|
intent_path = repo.resolve() / '.project/intent/INTENT.md'
|
|
18
22
|
task = task.resolve()
|
|
19
|
-
intent =
|
|
20
|
-
task_text =
|
|
23
|
+
intent = _common.read_user_text(intent_path)
|
|
24
|
+
task_text = _common.read_user_text(task)
|
|
21
25
|
owned = contracts._owned_criteria(task_text, task.stem)
|
|
22
26
|
criteria = contracts._success_criteria(intent)
|
|
23
27
|
unknown = set(owned) - set(criteria)
|
|
@@ -40,7 +44,14 @@ def render(repo: Path, task: Path) -> str:
|
|
|
40
44
|
if simple:
|
|
41
45
|
before, after = intent[:section.start('body')], intent[section.end('body'):]
|
|
42
46
|
# Corrections and task interfaces can explicitly refer to another SC.
|
|
43
|
-
|
|
47
|
+
# The spec-probe tables name every SC by design, so they select nothing.
|
|
48
|
+
scanned = re.sub(r'(?ms)^## (?:Edge coverage|Prohibitions)[ \t]*\n.*?(?=^## |\Z)', '',
|
|
49
|
+
before + after)
|
|
50
|
+
required = set(owned) | set(re.findall(r'\bSC\d+\b', scanned + task_text))
|
|
51
|
+
# An owned criterion's edge or prohibition ruled into another SC needs that SC's text.
|
|
52
|
+
for rows in (contracts.edge_coverage(intent, criteria), contracts.prohibitions(intent, criteria)):
|
|
53
|
+
required |= {row['target'] for row in (rows or {}).values()
|
|
54
|
+
if row['target'] and row['criterion'] in owned}
|
|
44
55
|
selected = ''.join(chunk for item, chunk in zip(items, chunks) if f'SC{item[1]}' in required)
|
|
45
56
|
projected = before + '\n' + (selected or '- No criteria assigned.\n\n') + after
|
|
46
57
|
mode = 'owned-criteria'
|
package/scripts/wizard.mjs
CHANGED
package/scripts/workflow_run.py
CHANGED
|
@@ -77,7 +77,7 @@ def run_workflow(repo: Path, action: str, project_dir: str, expected_head: str =
|
|
|
77
77
|
head = subprocess.run(["git", "rev-parse", "--verify", "HEAD"],
|
|
78
78
|
cwd=repo, capture_output=True, encoding="utf-8", errors="replace", check=True).stdout.strip()
|
|
79
79
|
step("check_task_briefs.py", "--repo", str(repo), "--base", head,
|
|
80
|
-
"--tasks-dir", f"{project_dir}/tasks")
|
|
80
|
+
"--tasks-dir", f"{project_dir}/tasks", "--project-dir", project_dir)
|
|
81
81
|
panel = ["validate-plan", "--plan", str(repo / project_dir / "plan/PLAN.md"),
|
|
82
82
|
"--intent", str(repo / project_dir / "intent/INTENT.md")]
|
|
83
83
|
charter = repo / ".project/CHARTER.md"
|
|
@@ -199,7 +199,7 @@ def run_workflow(repo: Path, action: str, project_dir: str, expected_head: str =
|
|
|
199
199
|
head = subprocess.run(["git", "rev-parse", "--verify", "HEAD"],
|
|
200
200
|
cwd=repo, capture_output=True, encoding="utf-8", errors="replace", check=True).stdout.strip()
|
|
201
201
|
step("check_task_briefs.py", "--repo", str(repo), "--base", head,
|
|
202
|
-
"--tasks-dir", f"{project_dir}/tasks")
|
|
202
|
+
"--tasks-dir", f"{project_dir}/tasks", "--project-dir", project_dir)
|
|
203
203
|
step("check_handoffs.py", "plan", *common)
|
|
204
204
|
elif action == "prepare-task" and _task_member(repo, project_dir, task_id):
|
|
205
205
|
# A member task works in a sidecar of its member; its Verify runs there at finish.
|
|
@@ -210,8 +210,14 @@ def run_workflow(repo: Path, action: str, project_dir: str, expected_head: str =
|
|
|
210
210
|
"--base", expected_head, "--task-id", task_id,
|
|
211
211
|
"--round-size", str(round_size))
|
|
212
212
|
if task["mode"] == "serial":
|
|
213
|
+
name = f"task-{task_id.lower()}-verify"
|
|
214
|
+
stale = isolation.sidecar_root(repo, "verify", name)
|
|
215
|
+
if os.path.lexists(stale / ".git"):
|
|
216
|
+
# An earlier prepare-task left this sidecar. Only one that is proven untouched is replaced.
|
|
217
|
+
steps.append({"script": "isolation.py", "result": isolation.retire_stale_verify(
|
|
218
|
+
repo, stale, isolation.verify_branch_name(name))})
|
|
213
219
|
step("isolation.py", "isolate-verify", "--repo", str(repo),
|
|
214
|
-
"--base", expected_head, "--name",
|
|
220
|
+
"--base", expected_head, "--name", name)
|
|
215
221
|
elif action == "build-evidence":
|
|
216
222
|
proof = step("build_state.py", "verify-landed", *common, "--head", expected_head)
|
|
217
223
|
# The landing proof has one canonical home; lean final-review reuse allows only this path.
|
|
@@ -257,6 +263,9 @@ def run_workflow(repo: Path, action: str, project_dir: str, expected_head: str =
|
|
|
257
263
|
ruled.add(row[0])
|
|
258
264
|
if any(len(row) == 6 and row[4] == "NEEDS-USER" and row[0] not in ruled for row in queue):
|
|
259
265
|
raise StepFailed("DOCS-AUDIT.md has NEEDS-USER rows without a user ruling")
|
|
266
|
+
if kind == "intent":
|
|
267
|
+
# Malformed or incomplete spec-probe tables are not a pre-approvable draft.
|
|
268
|
+
step("check_handoffs.py", "intent", *common)
|
|
260
269
|
if kind == "plan":
|
|
261
270
|
if gate_plan()["mode"] != "off":
|
|
262
271
|
raise StepFailed("pre-approval requires review_panel off")
|
|
@@ -275,7 +284,8 @@ def run_workflow(repo: Path, action: str, project_dir: str, expected_head: str =
|
|
|
275
284
|
if action == "approve-plan":
|
|
276
285
|
step("pipeline_state.py", "approve", *common, "--kind", "plan",
|
|
277
286
|
"--expected-head", expected_head)
|
|
278
|
-
except (StepFailed, OSError, subprocess.CalledProcessError,
|
|
287
|
+
except (StepFailed, isolation.IsolationError, OSError, subprocess.CalledProcessError,
|
|
288
|
+
ValueError, KeyError, TypeError) as error:
|
|
279
289
|
return {"status": "blocked", "reason": str(error), "steps": steps,
|
|
280
290
|
"next": next_step}
|
|
281
291
|
return {"status": "complete", "steps": steps, **outputs}
|
|
@@ -22,6 +22,27 @@ else:
|
|
|
22
22
|
from scripts import _common
|
|
23
23
|
|
|
24
24
|
|
|
25
|
+
def _worktree_list_porcelain(primary: Path) -> tuple[str, bool]:
|
|
26
|
+
try:
|
|
27
|
+
if __package__:
|
|
28
|
+
from . import pipeline_git as pg
|
|
29
|
+
else:
|
|
30
|
+
from scripts import pipeline_git as pg
|
|
31
|
+
except ImportError:
|
|
32
|
+
try:
|
|
33
|
+
import pipeline_git as pg
|
|
34
|
+
except ImportError:
|
|
35
|
+
pg = None
|
|
36
|
+
if pg is not None:
|
|
37
|
+
return pg.worktree_list_porcelain(primary)
|
|
38
|
+
try:
|
|
39
|
+
output = _git(primary, "worktree", "list", "--porcelain", "-z")
|
|
40
|
+
return output, True
|
|
41
|
+
except ValueError:
|
|
42
|
+
output = _git(primary, "worktree", "list", "--porcelain")
|
|
43
|
+
return output, False
|
|
44
|
+
|
|
45
|
+
|
|
25
46
|
def _git(primary: Path, *args: str) -> str:
|
|
26
47
|
result = _common.run_git(primary, *args)
|
|
27
48
|
if result.returncode:
|
|
@@ -82,6 +103,33 @@ def _workspace(primary: Path, pin: bool) -> Path:
|
|
|
82
103
|
return workspace
|
|
83
104
|
|
|
84
105
|
|
|
106
|
+
def release_workspace(primary: Path) -> bool:
|
|
107
|
+
"""Forget the pinned placement receipt once no linked worktrees remain.
|
|
108
|
+
|
|
109
|
+
Lets GSD_PATH_WORKTREE_ROOT (or a new default) apply again at the next
|
|
110
|
+
milestone's first allocation. Returns True when a receipt was removed;
|
|
111
|
+
any remaining linked worktree (including one only still registered) keeps
|
|
112
|
+
the pin.
|
|
113
|
+
"""
|
|
114
|
+
primary = primary.resolve()
|
|
115
|
+
common = Path(_git(primary, "rev-parse", "--git-common-dir"))
|
|
116
|
+
common = (primary / common).resolve()
|
|
117
|
+
receipt = common / "gsd-path" / "workspaces" / f"{_identity(primary)}.json"
|
|
118
|
+
if not receipt.is_file():
|
|
119
|
+
return False
|
|
120
|
+
output, nul_separated = _worktree_list_porcelain(primary)
|
|
121
|
+
records = output.split("\0\0") if nul_separated else [
|
|
122
|
+
block for block in output.strip().split("\n\n") if block.strip()
|
|
123
|
+
]
|
|
124
|
+
for record in records:
|
|
125
|
+
fields = record.split("\0") if nul_separated else record.splitlines()
|
|
126
|
+
for field in fields:
|
|
127
|
+
if field.startswith("worktree ") and Path(field[len("worktree "):]).resolve() != primary:
|
|
128
|
+
return False
|
|
129
|
+
receipt.unlink()
|
|
130
|
+
return True
|
|
131
|
+
|
|
132
|
+
|
|
85
133
|
def worktree_path(primary: Path, kind: str, name: str, *, pin: bool = False) -> Path:
|
|
86
134
|
primary = primary.resolve()
|
|
87
135
|
if kind not in {"task", "verify", "integrate", "bound"} or not name or Path(name).name != name or name in {".", ".."}:
|
|
@@ -91,9 +139,13 @@ def worktree_path(primary: Path, kind: str, name: str, *, pin: bool = False) ->
|
|
|
91
139
|
legacy = (primary.parent / f".{primary.name}-gsd-path-integrate-{name}"
|
|
92
140
|
if kind == "integrate" else primary.parent / f"{primary.name}.gsd-path" / kind / name)
|
|
93
141
|
branch = f"refs/heads/gsd-path-{kind}/{name}"
|
|
94
|
-
|
|
142
|
+
output, nul_separated = _worktree_list_porcelain(primary)
|
|
143
|
+
if nul_separated:
|
|
144
|
+
records = output.split("\0\0")
|
|
145
|
+
else:
|
|
146
|
+
records = [block for block in output.strip().split("\n\n") if block.strip()]
|
|
95
147
|
for record in records:
|
|
96
|
-
fields = record.split("\0")
|
|
148
|
+
fields = record.split("\0") if nul_separated else record.splitlines()
|
|
97
149
|
# Compare as paths: git prints forward slashes on Windows.
|
|
98
150
|
worktrees = [Path(field[len("worktree "):]) for field in fields if field.startswith("worktree ")]
|
|
99
151
|
if legacy in worktrees and f"branch {branch}" in fields:
|
|
@@ -100,6 +100,10 @@ Obtain a confident answer in every area before finishing:
|
|
|
100
100
|
give every named surface at least one success criterion observable
|
|
101
101
|
there. A criterion satisfied by a passing test alone does not cover a
|
|
102
102
|
surface.
|
|
103
|
+
9. **Edges and prohibitions** — once the success criteria are drafted, run
|
|
104
|
+
the [spec-reach probes](references/spec-probes.md): every applicable edge
|
|
105
|
+
and every kept prohibition gets the user's ruling in INTENT.md
|
|
106
|
+
`## Edge coverage` and `## Prohibitions`.
|
|
103
107
|
|
|
104
108
|
## Program mode
|
|
105
109
|
|
|
@@ -149,7 +153,10 @@ State ownership. There is no re-interview of charter or roadmap scope:
|
|
|
149
153
|
`Lane: milestone`, `Surfaces:` copied verbatim from the entry, and
|
|
150
154
|
`Review panel:` copied from CHARTER.md (default
|
|
151
155
|
the configured preference when CHARTER omits it). The confirmation may override the copied
|
|
152
|
-
panel value; do not invent `detected` or a named list.
|
|
156
|
+
panel value; do not invent `detected` or a named list. Run the
|
|
157
|
+
[spec-reach probes](references/spec-probes.md) over the derived criteria
|
|
158
|
+
and draft `## Edge coverage` and `## Prohibitions` with recommended
|
|
159
|
+
rulings. When brownfield,
|
|
153
160
|
fill `## Current state` from the map, record doc-vs-code rulings as in
|
|
154
161
|
Brownfield mode, and add protected existing behavior under Scope out.
|
|
155
162
|
Write Ground truth paths from the track root: `.project` normally, or
|
|
@@ -157,10 +164,16 @@ State ownership. There is no re-interview of charter or roadmap scope:
|
|
|
157
164
|
active `research/` paths.
|
|
158
165
|
3. Present one confirmation, not an interview: playback the derivation (and
|
|
159
166
|
brownfield ground truth when present), link the resolved absolute INTENT.md
|
|
160
|
-
path, and ask approve or adjust.
|
|
167
|
+
path, and ask approve or adjust. The confirmation lists each proposed edge
|
|
168
|
+
and prohibition ruling for the user to accept or change; it never rules on
|
|
169
|
+
them silently. A requested change that contradicts the
|
|
161
170
|
charter or the resolved roadmap entry is a scope change — this phase never
|
|
162
|
-
edits the roadmap; surface it to the user for a `$gsd-path-roadmap`
|
|
163
|
-
|
|
171
|
+
edits the roadmap; surface it to the user for a `$gsd-path-roadmap`
|
|
172
|
+
re-slice. Before intent approval, that re-slice keeps `define/active` and
|
|
173
|
+
can change the scope of this milestone's `active` entry; after its
|
|
174
|
+
approval, draft INTENT.md again from the changed entry. In `corrections`
|
|
175
|
+
mode the intent is already approved, so the re-slice waits for the next
|
|
176
|
+
milestone boundary.
|
|
164
177
|
4. On approval, finalize per the Output contract, setting `milestone` to the
|
|
165
178
|
resolved entry's slug. The router continues with milestone-scoped research
|
|
166
179
|
when the entry lists open questions, otherwise planning.
|
|
@@ -254,7 +267,15 @@ question. The rules change for every primary mode:
|
|
|
254
267
|
the brownfield map already established. Milestone mode skips this step.
|
|
255
268
|
5. Stop when coverage is complete or the user says `enough`. Record remaining
|
|
256
269
|
uncertainty under `## Open questions` with `RESEARCH` or `NEEDS-USER`.
|
|
257
|
-
|
|
270
|
+
`enough` does not skip the next step.
|
|
271
|
+
6. In standard mode, run the [spec-reach probes](references/spec-probes.md)
|
|
272
|
+
over the drafted success criteria: one question round for edges, then one
|
|
273
|
+
for kept prohibitions, each with a recommended ruling first. A ruling
|
|
274
|
+
observable where the user sees the work becomes or amends a success
|
|
275
|
+
criterion; write every ruling into `## Edge coverage` and
|
|
276
|
+
`## Prohibitions`. Program mode skips this step (each milestone runs it
|
|
277
|
+
in milestone mode); milestone mode runs it inside its confirmation.
|
|
278
|
+
7. Classify the proposed milestone lane before writing the approval draft.
|
|
258
279
|
Milestone mode keeps `Lane: milestone` and skips this classification.
|
|
259
280
|
Program mode writes CHARTER.md instead of INTENT.md. Otherwise choose
|
|
260
281
|
`quick` when scope fits at most two deliverable-sized tasks (project
|
|
@@ -275,6 +296,11 @@ question. The rules change for every primary mode:
|
|
|
275
296
|
## Output contract
|
|
276
297
|
|
|
277
298
|
At approval, retain the already reviewed `Lane:` value and its one-line reason.
|
|
299
|
+
Before every approval question on INTENT.md, run the bundled `python3
|
|
300
|
+
<absolute-bundled-script> intent --repo <absolute-root>` helper
|
|
301
|
+
(`scripts/check_handoffs.py`, plus `--project-dir .project/next` in
|
|
302
|
+
lookahead). It checks the success criteria, Surfaces, and both probe tables;
|
|
303
|
+
fix a failure in the draft before asking. It approves nothing.
|
|
278
304
|
Before presenting an approval draft without a CHARTER or explicit panel choice,
|
|
279
305
|
read `settings.review_panel.value` from the selected runtime's `path_config.py
|
|
280
306
|
show --repo <absolute-root>` (bundle for legacy projects; off for older selected
|
|
@@ -302,5 +328,8 @@ Use the executable phase handoff in AGENTS.md for the next action.
|
|
|
302
328
|
- In brownfield mode, state mapped facts for correction; never re-ask them.
|
|
303
329
|
- Treat solution-shaped problems as hypotheses and uncover the underlying pain.
|
|
304
330
|
- Preserve vetoes and corrections verbatim.
|
|
331
|
+
- Never rule on an edge's behavior or a prohibition yourself; recommend,
|
|
332
|
+
then record the user's ruling. An edge the user has not ruled on is a
|
|
333
|
+
required answer, including under pre-approval.
|
|
305
334
|
- Wrap up when every coverage-checklist area is answered or the user signals
|
|
306
335
|
done, and tag remaining gaps.
|
package/skills/gsd-path/PLAN.md
CHANGED
|
@@ -115,9 +115,13 @@ as stated in Lookahead mode.
|
|
|
115
115
|
In patch mode, tasks already `done` keep their landed metadata; only
|
|
116
116
|
the appended patch tasks must start clean.
|
|
117
117
|
- Require every dependency id to exist, forbid later-wave dependencies,
|
|
118
|
-
detect cycles, and forbid file overlap between planned tasks
|
|
119
|
-
wave. Same-wave
|
|
120
|
-
|
|
118
|
+
detect cycles, and forbid unordered file overlap between planned tasks
|
|
119
|
+
in the same wave. Same-wave tasks may share files only when one
|
|
120
|
+
transitively depends on the other through `deps`; the build executes
|
|
121
|
+
them in dependency layers.
|
|
122
|
+
- Require an optional `supersedes` field to be a list of different task
|
|
123
|
+
ids; each one names an existing task of an earlier wave, in the same
|
|
124
|
+
repo, that shares a declared file with the task.
|
|
121
125
|
- Reject a declared dependency that carries neither data nor a prerequisite
|
|
122
126
|
effect. A `deps` edge is valid only when the dependent consumes a symbol,
|
|
123
127
|
signature, schema, endpoint, file format, or path named in that
|
|
@@ -157,6 +161,13 @@ as stated in Lookahead mode.
|
|
|
157
161
|
command's output — not an internal unit test.
|
|
158
162
|
Require the surface to land in the same wave as the capability behind
|
|
159
163
|
it, never in a later polish wave.
|
|
164
|
+
- When INTENT.md has `## Edge coverage`, require a PLAN.md
|
|
165
|
+
`## Held-out checks` row for every `held-out` edge and for no other
|
|
166
|
+
edge. The named test is in that task's `files`, the task's Verify runs
|
|
167
|
+
it, and the task's Acceptance criteria state the edge id and its ruling
|
|
168
|
+
(see [spec-reach probes](references/spec-probes.md)). An edge or
|
|
169
|
+
prohibition ruled `criterion SCn` needs no extra row; it is covered as
|
|
170
|
+
SCn. Put each `judgment` prohibition in its owning task's Approach.
|
|
160
171
|
- Prove every intent constraint and synthesis decision is covered, that no
|
|
161
172
|
scope-out veto appears in a task, and that `Project verify` is a real,
|
|
162
173
|
non-placeholder command in PLAN.md. Every Verify — task and project —
|
|
@@ -84,6 +84,17 @@ settled brownfield input.
|
|
|
84
84
|
template before dispatch. Record every standard dimension exactly once as
|
|
85
85
|
`dispatched` or `skipped` with a reason, and assign every research question
|
|
86
86
|
to at least one dispatched dimension. No question may remain unassigned.
|
|
87
|
+
Copy each question to exactly one `Question assignments` row. Assign one or
|
|
88
|
+
more dispatched dimension slugs there, each in its own code span and
|
|
89
|
+
separated by commas, as in:
|
|
90
|
+
|
|
91
|
+
```md
|
|
92
|
+
- `[RESEARCH] Which approach is viable?` → `stack`, `pitfalls`
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
List a dimension only once per row. Every dispatched dimension must own at
|
|
96
|
+
least one question, and its evidence file must answer every question
|
|
97
|
+
assigned to it. Use `- none` only when there are no research questions.
|
|
87
98
|
2. Decide which standard dimensions have work: dispatch a dimension only when
|
|
88
99
|
it has at least one assigned `RESEARCH` question from INTENT.md or
|
|
89
100
|
CHARTER.md. Unsettled choices and risks need that source question before
|