@opengsd/gsd-path 1.3.0 → 1.4.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 +2 -207
- package/CHANGELOG.md +294 -0
- package/DOCS.md +19 -10
- package/FULL.md +9 -3
- package/GUIDE.md +1 -1
- package/HOOKS.md +9 -6
- package/QUICK.md +4 -1
- package/README.md +63 -11
- package/RUNTIME.md +1 -1
- package/UPDATE.md +61 -12
- package/WORKFLOW.md +22 -6
- package/package.json +9 -8
- package/scripts/_common.py +472 -19
- package/scripts/archive_milestone.py +146 -73
- package/scripts/bootstrap_repository.py +8 -5
- package/scripts/build_recovery.py +4 -1
- package/scripts/build_state.py +66 -23
- package/scripts/check_docs_audit.py +14 -3
- package/scripts/check_handoffs.py +116 -20
- package/scripts/check_task_briefs.py +60 -8
- package/scripts/check_update.py +2 -2
- package/scripts/core_hook_gate.py +10 -1
- package/scripts/core_hook_settings.py +11 -4
- package/scripts/detect_project.py +345 -15
- package/scripts/discussion_records.py +19 -13
- package/scripts/discussion_validate.py +66 -21
- package/scripts/dispatch_driver.py +111 -26
- package/scripts/git_guard.py +116 -29
- package/scripts/guard_hook.py +151 -29
- package/scripts/install.mjs +55 -39
- package/scripts/install.py +564 -41
- package/scripts/integration.py +434 -24
- package/scripts/isolation.py +1077 -28
- package/scripts/lean_verification.py +99 -19
- package/scripts/loop_run.py +20 -30
- package/scripts/members.py +704 -0
- package/scripts/migrate_core.py +2 -2
- package/scripts/path_config.py +2 -2
- package/scripts/pipeline_diagnose.py +82 -31
- package/scripts/pipeline_git.py +61 -22
- package/scripts/pipeline_state.py +176 -54
- package/scripts/pipeline_undo.py +117 -22
- package/scripts/promote_lookahead.py +1 -1
- package/scripts/review_panel.py +1 -1
- package/scripts/runtime_store.py +49 -11
- package/scripts/skill-resources.json +28 -3
- package/scripts/state_checkpoint.py +140 -31
- package/scripts/state_promote.py +2 -0
- package/scripts/status_runtime.py +36 -6
- package/scripts/sync_skill_resources.py +8 -7
- package/scripts/token_budget.py +12 -8
- package/scripts/workflow_run.py +103 -29
- package/scripts/worktree_paths.py +18 -8
- package/skills/gsd-path/BUILD.md +7 -1
- package/skills/gsd-path/DECIDE.md +11 -4
- package/skills/gsd-path/DEFINE.md +8 -1
- package/skills/gsd-path/DOCS-AUDIT.md +6 -4
- package/skills/gsd-path/INSPECT.md +5 -4
- package/skills/gsd-path/PLAN.md +7 -1
- package/skills/gsd-path/RESEARCH.md +2 -1
- package/skills/gsd-path/ROADMAP.md +2 -1
- package/skills/gsd-path/SHIP.md +27 -10
- package/skills/gsd-path/SKILL.md +45 -1
- package/skills/gsd-path/references/build-native.md +47 -14
- package/skills/gsd-path/references/codebase-mapper.md +2 -1
- package/skills/gsd-path/references/docs-auditor.md +2 -1
- package/skills/gsd-path/references/operating-rules.md +214 -0
- package/skills/gsd-path/references/planner.md +8 -0
- package/skills/gsd-path/references/reviewer-wave.md +3 -1
- package/skills/gsd-path/scripts/__pycache__/_common.cpython-312.pyc +0 -0
- package/skills/gsd-path/scripts/__pycache__/check_handoffs.cpython-312.pyc +0 -0
- package/skills/gsd-path/scripts/_common.py +472 -19
- package/skills/gsd-path/scripts/archive_milestone.py +146 -73
- package/skills/gsd-path/scripts/bootstrap_repository.py +8 -5
- package/skills/gsd-path/scripts/build_recovery.py +4 -1
- package/skills/gsd-path/scripts/build_state.py +66 -23
- package/skills/gsd-path/scripts/check_docs_audit.py +14 -3
- package/skills/gsd-path/scripts/check_handoffs.py +116 -20
- package/skills/gsd-path/scripts/check_task_briefs.py +60 -8
- package/skills/gsd-path/scripts/check_update.py +2 -2
- package/skills/gsd-path/scripts/detect_project.py +345 -15
- package/skills/gsd-path/scripts/discussion_records.py +19 -13
- package/skills/gsd-path/scripts/discussion_validate.py +66 -21
- package/skills/gsd-path/scripts/dispatch_driver.py +111 -26
- package/skills/gsd-path/scripts/git_guard.py +116 -29
- package/skills/gsd-path/scripts/integration.py +434 -24
- package/skills/gsd-path/scripts/isolation.py +1077 -28
- package/skills/gsd-path/scripts/lean_verification.py +99 -19
- package/skills/gsd-path/scripts/loop_run.py +20 -30
- package/skills/gsd-path/scripts/members.py +704 -0
- package/skills/gsd-path/scripts/path_config.py +2 -2
- package/skills/gsd-path/scripts/pipeline_git.py +61 -22
- package/skills/gsd-path/scripts/pipeline_state.py +176 -54
- package/skills/gsd-path/scripts/promote_lookahead.py +1 -1
- package/skills/gsd-path/scripts/review_panel.py +1 -1
- package/skills/gsd-path/scripts/state_checkpoint.py +140 -31
- package/skills/gsd-path/scripts/state_promote.py +2 -0
- package/skills/gsd-path/scripts/status_runtime.py +36 -6
- package/skills/gsd-path/scripts/token_budget.py +12 -8
- package/skills/gsd-path/scripts/workflow_run.py +103 -29
- package/skills/gsd-path/scripts/worktree_paths.py +18 -8
- package/skills/gsd-path/templates/codebase.md +1 -1
- package/skills/gsd-path/templates/docs-audit.md +1 -1
- package/skills/gsd-path/templates/final-review.md +5 -2
- package/skills/gsd-path/templates/gap-review.md +2 -1
- package/skills/gsd-path/templates/task.md +1 -0
- package/skills/gsd-path/templates/wave-review.md +3 -1
- package/skills/gsd-path-build/SKILL.md +7 -1
- package/skills/gsd-path-build/references/build-native.md +47 -14
- package/skills/gsd-path-build/references/operating-rules.md +214 -0
- package/skills/gsd-path-build/references/reviewer-wave.md +3 -1
- package/skills/gsd-path-build/scripts/__pycache__/_common.cpython-312.pyc +0 -0
- package/skills/gsd-path-build/scripts/__pycache__/check_handoffs.cpython-312.pyc +0 -0
- package/skills/gsd-path-build/scripts/_common.py +472 -19
- package/skills/gsd-path-build/scripts/archive_milestone.py +146 -73
- package/skills/gsd-path-build/scripts/build_recovery.py +4 -1
- package/skills/gsd-path-build/scripts/build_state.py +66 -23
- package/skills/gsd-path-build/scripts/check_handoffs.py +116 -20
- package/skills/gsd-path-build/scripts/check_task_briefs.py +60 -8
- package/skills/gsd-path-build/scripts/detect_project.py +345 -15
- package/skills/gsd-path-build/scripts/discussion_records.py +19 -13
- package/skills/gsd-path-build/scripts/discussion_validate.py +66 -21
- package/skills/gsd-path-build/scripts/dispatch_driver.py +111 -26
- package/skills/gsd-path-build/scripts/integration.py +434 -24
- package/skills/gsd-path-build/scripts/isolation.py +1077 -28
- package/skills/gsd-path-build/scripts/loop_run.py +20 -30
- package/skills/gsd-path-build/scripts/members.py +704 -0
- package/skills/gsd-path-build/scripts/path_config.py +2 -2
- package/skills/gsd-path-build/scripts/pipeline_git.py +61 -22
- package/skills/gsd-path-build/scripts/pipeline_state.py +176 -54
- package/skills/gsd-path-build/scripts/promote_lookahead.py +1 -1
- package/skills/gsd-path-build/scripts/review_panel.py +1 -1
- package/skills/gsd-path-build/scripts/state_checkpoint.py +140 -31
- package/skills/gsd-path-build/scripts/state_promote.py +2 -0
- package/skills/gsd-path-build/scripts/token_budget.py +12 -8
- package/skills/gsd-path-build/scripts/workflow_run.py +103 -29
- package/skills/gsd-path-build/scripts/worktree_paths.py +18 -8
- package/skills/gsd-path-build/templates/task.md +1 -0
- package/skills/gsd-path-build/templates/wave-review.md +3 -1
- package/skills/gsd-path-decide/SKILL.md +11 -4
- package/skills/gsd-path-decide/references/operating-rules.md +214 -0
- package/skills/gsd-path-decide/scripts/_common.py +472 -19
- package/skills/gsd-path-decide/scripts/archive_milestone.py +146 -73
- package/skills/gsd-path-decide/scripts/build_recovery.py +4 -1
- package/skills/gsd-path-decide/scripts/check_handoffs.py +116 -20
- package/skills/gsd-path-decide/scripts/check_task_briefs.py +60 -8
- package/skills/gsd-path-decide/scripts/detect_project.py +345 -15
- package/skills/gsd-path-decide/scripts/discussion_records.py +19 -13
- package/skills/gsd-path-decide/scripts/discussion_validate.py +66 -21
- package/skills/gsd-path-decide/scripts/integration.py +434 -24
- package/skills/gsd-path-decide/scripts/isolation.py +1077 -28
- package/skills/gsd-path-decide/scripts/loop_run.py +20 -30
- package/skills/gsd-path-decide/scripts/members.py +704 -0
- package/skills/gsd-path-decide/scripts/path_config.py +2 -2
- package/skills/gsd-path-decide/scripts/pipeline_git.py +61 -22
- package/skills/gsd-path-decide/scripts/pipeline_state.py +176 -54
- package/skills/gsd-path-decide/scripts/promote_lookahead.py +1 -1
- package/skills/gsd-path-decide/scripts/review_panel.py +1 -1
- package/skills/gsd-path-decide/scripts/state_checkpoint.py +140 -31
- package/skills/gsd-path-decide/scripts/state_promote.py +2 -0
- package/skills/gsd-path-decide/scripts/worktree_paths.py +18 -8
- package/skills/gsd-path-define/SKILL.md +8 -1
- package/skills/gsd-path-define/references/operating-rules.md +214 -0
- package/skills/gsd-path-define/scripts/_common.py +472 -19
- package/skills/gsd-path-define/scripts/archive_milestone.py +146 -73
- package/skills/gsd-path-define/scripts/build_recovery.py +4 -1
- package/skills/gsd-path-define/scripts/check_handoffs.py +116 -20
- package/skills/gsd-path-define/scripts/check_task_briefs.py +60 -8
- package/skills/gsd-path-define/scripts/detect_project.py +345 -15
- package/skills/gsd-path-define/scripts/discussion_records.py +19 -13
- package/skills/gsd-path-define/scripts/discussion_validate.py +66 -21
- package/skills/gsd-path-define/scripts/integration.py +434 -24
- package/skills/gsd-path-define/scripts/isolation.py +1077 -28
- package/skills/gsd-path-define/scripts/loop_run.py +20 -30
- package/skills/gsd-path-define/scripts/members.py +704 -0
- package/skills/gsd-path-define/scripts/path_config.py +2 -2
- package/skills/gsd-path-define/scripts/pipeline_git.py +61 -22
- package/skills/gsd-path-define/scripts/pipeline_state.py +176 -54
- package/skills/gsd-path-define/scripts/promote_lookahead.py +1 -1
- package/skills/gsd-path-define/scripts/review_panel.py +1 -1
- package/skills/gsd-path-define/scripts/state_checkpoint.py +140 -31
- package/skills/gsd-path-define/scripts/state_promote.py +2 -0
- package/skills/gsd-path-define/scripts/worktree_paths.py +18 -8
- package/skills/gsd-path-discuss/SKILL.md +2 -1
- package/skills/gsd-path-discuss/references/operating-rules.md +214 -0
- package/skills/gsd-path-discuss/scripts/_common.py +472 -19
- package/skills/gsd-path-discuss/scripts/discussion_records.py +19 -13
- package/skills/gsd-path-discuss/scripts/loop_run.py +20 -30
- package/skills/gsd-path-discuss/scripts/path_config.py +2 -2
- package/skills/gsd-path-discuss/scripts/review_panel.py +1 -1
- package/skills/gsd-path-discuss/scripts/worktree_paths.py +18 -8
- package/skills/gsd-path-docs-audit/SKILL.md +6 -4
- package/skills/gsd-path-docs-audit/references/docs-auditor.md +2 -1
- package/skills/gsd-path-docs-audit/references/operating-rules.md +214 -0
- package/skills/gsd-path-docs-audit/scripts/_common.py +472 -19
- package/skills/gsd-path-docs-audit/scripts/archive_milestone.py +146 -73
- package/skills/gsd-path-docs-audit/scripts/build_recovery.py +4 -1
- package/skills/gsd-path-docs-audit/scripts/check_docs_audit.py +14 -3
- package/skills/gsd-path-docs-audit/scripts/check_handoffs.py +116 -20
- package/skills/gsd-path-docs-audit/scripts/check_task_briefs.py +60 -8
- package/skills/gsd-path-docs-audit/scripts/detect_project.py +345 -15
- package/skills/gsd-path-docs-audit/scripts/discussion_records.py +19 -13
- package/skills/gsd-path-docs-audit/scripts/discussion_validate.py +66 -21
- package/skills/gsd-path-docs-audit/scripts/integration.py +434 -24
- package/skills/gsd-path-docs-audit/scripts/isolation.py +1077 -28
- package/skills/gsd-path-docs-audit/scripts/loop_run.py +20 -30
- package/skills/gsd-path-docs-audit/scripts/members.py +704 -0
- package/skills/gsd-path-docs-audit/scripts/path_config.py +2 -2
- package/skills/gsd-path-docs-audit/scripts/pipeline_git.py +61 -22
- package/skills/gsd-path-docs-audit/scripts/pipeline_state.py +176 -54
- package/skills/gsd-path-docs-audit/scripts/promote_lookahead.py +1 -1
- package/skills/gsd-path-docs-audit/scripts/review_panel.py +1 -1
- package/skills/gsd-path-docs-audit/scripts/state_checkpoint.py +140 -31
- package/skills/gsd-path-docs-audit/scripts/state_promote.py +2 -0
- package/skills/gsd-path-docs-audit/scripts/worktree_paths.py +18 -8
- package/skills/gsd-path-docs-audit/templates/docs-audit.md +1 -1
- package/skills/gsd-path-forensics/SKILL.md +2 -1
- package/skills/gsd-path-forensics/references/operating-rules.md +214 -0
- package/skills/gsd-path-forensics/scripts/_common.py +472 -19
- package/skills/gsd-path-forensics/scripts/discussion_records.py +19 -13
- package/skills/gsd-path-forensics/scripts/loop_run.py +20 -30
- package/skills/gsd-path-forensics/scripts/path_config.py +2 -2
- package/skills/gsd-path-forensics/scripts/pipeline_diagnose.py +82 -31
- package/skills/gsd-path-forensics/scripts/pipeline_undo.py +117 -22
- package/skills/gsd-path-forensics/scripts/review_panel.py +1 -1
- package/skills/gsd-path-forensics/scripts/worktree_paths.py +18 -8
- package/skills/gsd-path-inspect/SKILL.md +5 -4
- package/skills/gsd-path-inspect/references/codebase-mapper.md +2 -1
- package/skills/gsd-path-inspect/references/docs-auditor.md +2 -1
- package/skills/gsd-path-inspect/references/operating-rules.md +214 -0
- package/skills/gsd-path-inspect/scripts/__pycache__/_common.cpython-312.pyc +0 -0
- package/skills/gsd-path-inspect/scripts/_common.py +472 -19
- package/skills/gsd-path-inspect/scripts/archive_milestone.py +146 -73
- package/skills/gsd-path-inspect/scripts/build_recovery.py +4 -1
- package/skills/gsd-path-inspect/scripts/check_docs_audit.py +14 -3
- package/skills/gsd-path-inspect/scripts/check_handoffs.py +116 -20
- package/skills/gsd-path-inspect/scripts/check_task_briefs.py +60 -8
- package/skills/gsd-path-inspect/scripts/detect_project.py +345 -15
- package/skills/gsd-path-inspect/scripts/discussion_records.py +19 -13
- package/skills/gsd-path-inspect/scripts/discussion_validate.py +66 -21
- package/skills/gsd-path-inspect/scripts/integration.py +434 -24
- package/skills/gsd-path-inspect/scripts/isolation.py +1077 -28
- package/skills/gsd-path-inspect/scripts/loop_run.py +20 -30
- package/skills/gsd-path-inspect/scripts/members.py +704 -0
- package/skills/gsd-path-inspect/scripts/path_config.py +2 -2
- package/skills/gsd-path-inspect/scripts/pipeline_git.py +61 -22
- package/skills/gsd-path-inspect/scripts/pipeline_state.py +176 -54
- package/skills/gsd-path-inspect/scripts/promote_lookahead.py +1 -1
- package/skills/gsd-path-inspect/scripts/review_panel.py +1 -1
- package/skills/gsd-path-inspect/scripts/state_checkpoint.py +140 -31
- package/skills/gsd-path-inspect/scripts/state_promote.py +2 -0
- package/skills/gsd-path-inspect/scripts/workflow_run.py +103 -29
- package/skills/gsd-path-inspect/scripts/worktree_paths.py +18 -8
- package/skills/gsd-path-inspect/templates/codebase.md +1 -1
- package/skills/gsd-path-inspect/templates/docs-audit.md +1 -1
- package/skills/gsd-path-loop/SKILL.md +2 -1
- package/skills/gsd-path-loop/references/operating-rules.md +214 -0
- package/skills/gsd-path-loop/scripts/_common.py +472 -19
- package/skills/gsd-path-loop/scripts/discussion_records.py +19 -13
- package/skills/gsd-path-loop/scripts/loop_run.py +20 -30
- package/skills/gsd-path-loop/scripts/path_config.py +2 -2
- package/skills/gsd-path-loop/scripts/review_panel.py +1 -1
- package/skills/gsd-path-loop/scripts/worktree_paths.py +18 -8
- package/skills/gsd-path-migrate/SKILL.md +2 -1
- package/skills/gsd-path-migrate/references/operating-rules.md +214 -0
- package/skills/gsd-path-migrate/scripts/_common.py +472 -19
- package/skills/gsd-path-migrate/scripts/core_hook_gate.py +10 -1
- package/skills/gsd-path-migrate/scripts/core_hook_settings.py +11 -4
- package/skills/gsd-path-migrate/scripts/discussion_records.py +19 -13
- package/skills/gsd-path-migrate/scripts/loop_run.py +20 -30
- package/skills/gsd-path-migrate/scripts/migrate_core.py +2 -2
- package/skills/gsd-path-migrate/scripts/path_config.py +2 -2
- package/skills/gsd-path-migrate/scripts/review_panel.py +1 -1
- package/skills/gsd-path-plan/SKILL.md +7 -1
- package/skills/gsd-path-plan/references/operating-rules.md +214 -0
- package/skills/gsd-path-plan/references/planner.md +8 -0
- package/skills/gsd-path-plan/scripts/__pycache__/_common.cpython-312.pyc +0 -0
- package/skills/gsd-path-plan/scripts/_common.py +472 -19
- package/skills/gsd-path-plan/scripts/archive_milestone.py +146 -73
- package/skills/gsd-path-plan/scripts/build_recovery.py +4 -1
- package/skills/gsd-path-plan/scripts/check_handoffs.py +116 -20
- package/skills/gsd-path-plan/scripts/check_task_briefs.py +60 -8
- package/skills/gsd-path-plan/scripts/detect_project.py +345 -15
- package/skills/gsd-path-plan/scripts/discussion_records.py +19 -13
- package/skills/gsd-path-plan/scripts/discussion_validate.py +66 -21
- package/skills/gsd-path-plan/scripts/integration.py +434 -24
- package/skills/gsd-path-plan/scripts/isolation.py +1077 -28
- package/skills/gsd-path-plan/scripts/loop_run.py +20 -30
- package/skills/gsd-path-plan/scripts/members.py +704 -0
- package/skills/gsd-path-plan/scripts/path_config.py +2 -2
- package/skills/gsd-path-plan/scripts/pipeline_git.py +61 -22
- package/skills/gsd-path-plan/scripts/pipeline_state.py +176 -54
- package/skills/gsd-path-plan/scripts/promote_lookahead.py +1 -1
- package/skills/gsd-path-plan/scripts/review_panel.py +1 -1
- package/skills/gsd-path-plan/scripts/state_checkpoint.py +140 -31
- package/skills/gsd-path-plan/scripts/state_promote.py +2 -0
- package/skills/gsd-path-plan/scripts/workflow_run.py +103 -29
- package/skills/gsd-path-plan/scripts/worktree_paths.py +18 -8
- package/skills/gsd-path-plan/templates/task.md +1 -0
- package/skills/gsd-path-research/SKILL.md +2 -1
- package/skills/gsd-path-research/references/operating-rules.md +214 -0
- package/skills/gsd-path-research/scripts/_common.py +472 -19
- package/skills/gsd-path-research/scripts/archive_milestone.py +146 -73
- package/skills/gsd-path-research/scripts/build_recovery.py +4 -1
- package/skills/gsd-path-research/scripts/check_handoffs.py +116 -20
- package/skills/gsd-path-research/scripts/check_task_briefs.py +60 -8
- package/skills/gsd-path-research/scripts/detect_project.py +345 -15
- package/skills/gsd-path-research/scripts/discussion_records.py +19 -13
- package/skills/gsd-path-research/scripts/discussion_validate.py +66 -21
- package/skills/gsd-path-research/scripts/integration.py +434 -24
- package/skills/gsd-path-research/scripts/isolation.py +1077 -28
- package/skills/gsd-path-research/scripts/loop_run.py +20 -30
- package/skills/gsd-path-research/scripts/members.py +704 -0
- package/skills/gsd-path-research/scripts/path_config.py +2 -2
- package/skills/gsd-path-research/scripts/pipeline_git.py +61 -22
- package/skills/gsd-path-research/scripts/pipeline_state.py +176 -54
- package/skills/gsd-path-research/scripts/promote_lookahead.py +1 -1
- package/skills/gsd-path-research/scripts/review_panel.py +1 -1
- package/skills/gsd-path-research/scripts/state_checkpoint.py +140 -31
- package/skills/gsd-path-research/scripts/state_promote.py +2 -0
- package/skills/gsd-path-research/scripts/worktree_paths.py +18 -8
- package/skills/gsd-path-roadmap/SKILL.md +2 -1
- package/skills/gsd-path-roadmap/references/operating-rules.md +214 -0
- package/skills/gsd-path-roadmap/scripts/_common.py +472 -19
- package/skills/gsd-path-roadmap/scripts/archive_milestone.py +146 -73
- package/skills/gsd-path-roadmap/scripts/build_recovery.py +4 -1
- package/skills/gsd-path-roadmap/scripts/check_handoffs.py +116 -20
- package/skills/gsd-path-roadmap/scripts/check_task_briefs.py +60 -8
- package/skills/gsd-path-roadmap/scripts/detect_project.py +345 -15
- package/skills/gsd-path-roadmap/scripts/discussion_records.py +19 -13
- package/skills/gsd-path-roadmap/scripts/discussion_validate.py +66 -21
- package/skills/gsd-path-roadmap/scripts/integration.py +434 -24
- package/skills/gsd-path-roadmap/scripts/isolation.py +1077 -28
- package/skills/gsd-path-roadmap/scripts/loop_run.py +20 -30
- package/skills/gsd-path-roadmap/scripts/members.py +704 -0
- package/skills/gsd-path-roadmap/scripts/path_config.py +2 -2
- package/skills/gsd-path-roadmap/scripts/pipeline_git.py +61 -22
- package/skills/gsd-path-roadmap/scripts/pipeline_state.py +176 -54
- package/skills/gsd-path-roadmap/scripts/promote_lookahead.py +1 -1
- package/skills/gsd-path-roadmap/scripts/review_panel.py +1 -1
- package/skills/gsd-path-roadmap/scripts/state_checkpoint.py +140 -31
- package/skills/gsd-path-roadmap/scripts/state_promote.py +2 -0
- package/skills/gsd-path-roadmap/scripts/worktree_paths.py +18 -8
- package/skills/gsd-path-ship/SKILL.md +27 -10
- package/skills/gsd-path-ship/references/operating-rules.md +214 -0
- package/skills/gsd-path-ship/references/reviewer-wave.md +3 -1
- package/skills/gsd-path-ship/scripts/__pycache__/_common.cpython-312.pyc +0 -0
- package/skills/gsd-path-ship/scripts/_common.py +472 -19
- package/skills/gsd-path-ship/scripts/archive_milestone.py +146 -73
- package/skills/gsd-path-ship/scripts/build_recovery.py +4 -1
- package/skills/gsd-path-ship/scripts/build_state.py +66 -23
- package/skills/gsd-path-ship/scripts/check_handoffs.py +116 -20
- package/skills/gsd-path-ship/scripts/check_task_briefs.py +60 -8
- package/skills/gsd-path-ship/scripts/detect_project.py +345 -15
- package/skills/gsd-path-ship/scripts/discussion_records.py +19 -13
- package/skills/gsd-path-ship/scripts/discussion_validate.py +66 -21
- package/skills/gsd-path-ship/scripts/integration.py +434 -24
- package/skills/gsd-path-ship/scripts/isolation.py +1077 -28
- package/skills/gsd-path-ship/scripts/lean_verification.py +99 -19
- package/skills/gsd-path-ship/scripts/loop_run.py +20 -30
- package/skills/gsd-path-ship/scripts/members.py +704 -0
- package/skills/gsd-path-ship/scripts/path_config.py +2 -2
- package/skills/gsd-path-ship/scripts/pipeline_git.py +61 -22
- package/skills/gsd-path-ship/scripts/pipeline_state.py +176 -54
- package/skills/gsd-path-ship/scripts/promote_lookahead.py +1 -1
- package/skills/gsd-path-ship/scripts/review_panel.py +1 -1
- package/skills/gsd-path-ship/scripts/state_checkpoint.py +140 -31
- package/skills/gsd-path-ship/scripts/state_promote.py +2 -0
- package/skills/gsd-path-ship/scripts/workflow_run.py +103 -29
- package/skills/gsd-path-ship/scripts/worktree_paths.py +18 -8
- package/skills/gsd-path-ship/templates/final-review.md +5 -2
- package/skills/gsd-path-ship/templates/gap-review.md +2 -1
- package/skills/gsd-path-ship/templates/wave-review.md +3 -1
- package/skills/gsd-path-undo/SKILL.md +2 -1
- package/skills/gsd-path-undo/references/operating-rules.md +214 -0
- package/skills/gsd-path-undo/scripts/_common.py +472 -19
- package/skills/gsd-path-undo/scripts/discussion_records.py +19 -13
- package/skills/gsd-path-undo/scripts/loop_run.py +20 -30
- package/skills/gsd-path-undo/scripts/path_config.py +2 -2
- package/skills/gsd-path-undo/scripts/pipeline_undo.py +117 -22
- package/skills/gsd-path-undo/scripts/review_panel.py +1 -1
- package/skills/gsd-path-undo/scripts/worktree_paths.py +18 -8
- package/skills/path/BUILD.md +7 -1
- package/skills/path/DECIDE.md +11 -4
- package/skills/path/DEFINE.md +8 -1
- package/skills/path/DOCS-AUDIT.md +6 -4
- package/skills/path/INSPECT.md +5 -4
- package/skills/path/PLAN.md +7 -1
- package/skills/path/RESEARCH.md +2 -1
- package/skills/path/ROADMAP.md +2 -1
- package/skills/path/SHIP.md +27 -10
- package/skills/path/SKILL.md +45 -1
- package/skills/path/references/build-native.md +47 -14
- package/skills/path/references/codebase-mapper.md +2 -1
- package/skills/path/references/docs-auditor.md +2 -1
- package/skills/path/references/operating-rules.md +214 -0
- package/skills/path/references/planner.md +8 -0
- package/skills/path/references/reviewer-wave.md +3 -1
- package/skills/path/scripts/_common.py +472 -19
- package/skills/path/scripts/archive_milestone.py +146 -73
- package/skills/path/scripts/bootstrap_repository.py +8 -5
- package/skills/path/scripts/build_recovery.py +4 -1
- package/skills/path/scripts/build_state.py +66 -23
- package/skills/path/scripts/check_docs_audit.py +14 -3
- package/skills/path/scripts/check_handoffs.py +116 -20
- package/skills/path/scripts/check_task_briefs.py +60 -8
- package/skills/path/scripts/check_update.py +2 -2
- package/skills/path/scripts/detect_project.py +345 -15
- package/skills/path/scripts/discussion_records.py +19 -13
- package/skills/path/scripts/discussion_validate.py +66 -21
- package/skills/path/scripts/dispatch_driver.py +111 -26
- package/skills/path/scripts/git_guard.py +116 -29
- package/skills/path/scripts/integration.py +434 -24
- package/skills/path/scripts/isolation.py +1077 -28
- package/skills/path/scripts/lean_verification.py +99 -19
- package/skills/path/scripts/loop_run.py +20 -30
- package/skills/path/scripts/members.py +704 -0
- package/skills/path/scripts/path_config.py +2 -2
- package/skills/path/scripts/pipeline_git.py +61 -22
- package/skills/path/scripts/pipeline_state.py +176 -54
- package/skills/path/scripts/promote_lookahead.py +1 -1
- package/skills/path/scripts/review_panel.py +1 -1
- package/skills/path/scripts/state_checkpoint.py +140 -31
- package/skills/path/scripts/state_promote.py +2 -0
- package/skills/path/scripts/status_runtime.py +36 -6
- package/skills/path/scripts/token_budget.py +12 -8
- package/skills/path/scripts/workflow_run.py +103 -29
- package/skills/path/scripts/worktree_paths.py +18 -8
- package/skills/path/templates/codebase.md +1 -1
- package/skills/path/templates/docs-audit.md +1 -1
- package/skills/path/templates/final-review.md +5 -2
- package/skills/path/templates/gap-review.md +2 -1
- package/skills/path/templates/task.md +1 -0
- package/skills/path/templates/wave-review.md +3 -1
|
@@ -174,13 +174,13 @@ def set_value(repo, scope, key, value, reset=False):
|
|
|
174
174
|
if scope == 'project':
|
|
175
175
|
state, _, _ = sibling('pipeline_state').load_state(repo)
|
|
176
176
|
branch = subprocess.run(['git', '-C', str(repo), 'branch', '--show-current'],
|
|
177
|
-
capture_output=True,
|
|
177
|
+
capture_output=True, encoding="utf-8", errors="replace")
|
|
178
178
|
if branch.returncode or not state.branch or branch.stdout.strip() != state.branch:
|
|
179
179
|
raise ValueError('Run the router to bind the project branch before editing settings.')
|
|
180
180
|
head = subprocess.run(['git', '-C', str(repo), 'rev-parse', '--verify', 'HEAD'], capture_output=True)
|
|
181
181
|
if head.returncode == 0:
|
|
182
182
|
closed = subprocess.run([sys.executable, '-B', str(Path(__file__).with_name('git_guard.py')),
|
|
183
|
-
'closed-milestone'], cwd=repo, capture_output=True,
|
|
183
|
+
'closed-milestone'], cwd=repo, capture_output=True, encoding="utf-8", errors="replace")
|
|
184
184
|
if closed.returncode:
|
|
185
185
|
raise ValueError(closed.stderr.strip() or 'Cannot verify the milestone branch is open.')
|
|
186
186
|
if scope == 'project' and key == 'integration':
|
|
@@ -10,6 +10,7 @@ from __future__ import annotations
|
|
|
10
10
|
|
|
11
11
|
import argparse
|
|
12
12
|
import json
|
|
13
|
+
import os
|
|
13
14
|
import shlex
|
|
14
15
|
import sys
|
|
15
16
|
|
|
@@ -20,14 +21,14 @@ from typing import Callable, Optional, Sequence
|
|
|
20
21
|
|
|
21
22
|
|
|
22
23
|
def _load_diagnose_modules():
|
|
23
|
-
|
|
24
|
-
import archive_milestone
|
|
25
|
-
import detect_project
|
|
26
|
-
import discussion_records
|
|
27
|
-
import integration
|
|
28
|
-
import isolation
|
|
29
|
-
import pipeline_git
|
|
30
|
-
import pipeline_state
|
|
24
|
+
if __package__:
|
|
25
|
+
from . import archive_milestone
|
|
26
|
+
from . import detect_project
|
|
27
|
+
from . import discussion_records
|
|
28
|
+
from . import integration
|
|
29
|
+
from . import isolation
|
|
30
|
+
from . import pipeline_git
|
|
31
|
+
from . import pipeline_state
|
|
31
32
|
return (
|
|
32
33
|
archive_milestone,
|
|
33
34
|
detect_project,
|
|
@@ -37,17 +38,35 @@ def _load_diagnose_modules():
|
|
|
37
38
|
pipeline_git,
|
|
38
39
|
pipeline_state,
|
|
39
40
|
)
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
41
|
+
else:
|
|
42
|
+
try:
|
|
43
|
+
import archive_milestone
|
|
44
|
+
import detect_project
|
|
45
|
+
import discussion_records
|
|
46
|
+
import integration
|
|
47
|
+
import isolation
|
|
48
|
+
import pipeline_git
|
|
49
|
+
import pipeline_state
|
|
50
|
+
return (
|
|
51
|
+
archive_milestone,
|
|
52
|
+
detect_project,
|
|
53
|
+
discussion_records,
|
|
54
|
+
integration,
|
|
55
|
+
isolation,
|
|
56
|
+
pipeline_git,
|
|
57
|
+
pipeline_state,
|
|
58
|
+
)
|
|
59
|
+
except ModuleNotFoundError as error:
|
|
60
|
+
if error.name not in {
|
|
61
|
+
"archive_milestone",
|
|
62
|
+
"detect_project",
|
|
63
|
+
"discussion_records",
|
|
64
|
+
"integration",
|
|
65
|
+
"isolation",
|
|
66
|
+
"pipeline_git",
|
|
67
|
+
"pipeline_state",
|
|
68
|
+
}:
|
|
69
|
+
raise
|
|
51
70
|
try:
|
|
52
71
|
from scripts import (
|
|
53
72
|
archive_milestone,
|
|
@@ -116,21 +135,25 @@ _worktree_report = isolation._worktree_report
|
|
|
116
135
|
PipelineStateError = pipeline_state.PipelineStateError
|
|
117
136
|
status_state = pipeline_state.status_state
|
|
118
137
|
validate_state = pipeline_state.validate_state
|
|
138
|
+
_run_git = pipeline_state._run_git
|
|
119
139
|
|
|
120
|
-
|
|
121
|
-
import pipeline_undo
|
|
122
|
-
|
|
123
|
-
if error.name != "pipeline_undo":
|
|
124
|
-
raise
|
|
140
|
+
if __package__:
|
|
141
|
+
from . import pipeline_undo
|
|
142
|
+
else:
|
|
125
143
|
try:
|
|
126
|
-
|
|
144
|
+
import pipeline_undo
|
|
127
145
|
except ModuleNotFoundError as error:
|
|
128
|
-
if error.name
|
|
146
|
+
if error.name != "pipeline_undo":
|
|
129
147
|
raise
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
148
|
+
try:
|
|
149
|
+
from scripts import pipeline_undo
|
|
150
|
+
except ModuleNotFoundError as error:
|
|
151
|
+
if error.name not in {"scripts", "scripts.pipeline_undo"}:
|
|
152
|
+
raise
|
|
153
|
+
shared = Path(__file__).resolve().parents[2] / "gsd-path" / "scripts"
|
|
154
|
+
if str(shared) not in sys.path:
|
|
155
|
+
sys.path.insert(0, str(shared))
|
|
156
|
+
import pipeline_undo
|
|
134
157
|
|
|
135
158
|
UndoError = pipeline_undo.UndoError
|
|
136
159
|
undo_preview = pipeline_undo.preview
|
|
@@ -194,7 +217,12 @@ def _state_template() -> Path:
|
|
|
194
217
|
|
|
195
218
|
def _command(module: object, *arguments: object) -> str:
|
|
196
219
|
script = Path(str(getattr(module, "__file__"))).resolve()
|
|
197
|
-
|
|
220
|
+
def text(value: object) -> str:
|
|
221
|
+
# Agents paste this into Git Bash on Windows, where unquoted
|
|
222
|
+
# backslashes are escapes; forward slashes need no quoting.
|
|
223
|
+
return value.as_posix() if isinstance(value, Path) and os.name == "nt" else str(value)
|
|
224
|
+
|
|
225
|
+
return shlex.join([text(Path(sys.executable)), text(script), *map(text, arguments)])
|
|
198
226
|
|
|
199
227
|
|
|
200
228
|
def _route_retry(
|
|
@@ -391,6 +419,29 @@ def diagnose(repo: Path) -> dict[str, object]:
|
|
|
391
419
|
for key, path in (status.get("journals") or {}).items()
|
|
392
420
|
if path
|
|
393
421
|
}
|
|
422
|
+
pending_members = [row["name"] for row in status.get("members") or [] if row["close"] == "pending"]
|
|
423
|
+
if pending_members:
|
|
424
|
+
findings.append(
|
|
425
|
+
_finding(
|
|
426
|
+
"member-close",
|
|
427
|
+
"stuck",
|
|
428
|
+
"member close is pending for: " + ", ".join(pending_members),
|
|
429
|
+
_command(archive_milestone, "close-members", "--repo", resolved),
|
|
430
|
+
)
|
|
431
|
+
)
|
|
432
|
+
common = _run_git(resolved, "rev-parse", "--path-format=absolute", "--git-common-dir", check=False)
|
|
433
|
+
landings = sorted(
|
|
434
|
+
(Path(common.stdout.strip()) / "gsd-path" / "member-landings").glob("*.json")
|
|
435
|
+
) if common.returncode == 0 else []
|
|
436
|
+
if landings:
|
|
437
|
+
findings.append(
|
|
438
|
+
_finding(
|
|
439
|
+
"member-landing",
|
|
440
|
+
"stuck",
|
|
441
|
+
"member landing journal is pending: " + ", ".join(path.stem for path in landings),
|
|
442
|
+
"resume build; the dispatch driver finishes pending member landings before new work",
|
|
443
|
+
)
|
|
444
|
+
)
|
|
394
445
|
undo_probe = by_name["undo-preview"]
|
|
395
446
|
undo_result = undo_probe["result"] if undo_probe["ok"] else None
|
|
396
447
|
route_retry = _route_retry(resolved, route, undo_result)
|
|
@@ -25,22 +25,30 @@ from pathlib import Path, PurePosixPath
|
|
|
25
25
|
from typing import Optional, Sequence
|
|
26
26
|
|
|
27
27
|
def _load_pipeline_modules():
|
|
28
|
-
|
|
29
|
-
import archive_milestone
|
|
30
|
-
import isolation
|
|
31
|
-
import pipeline_git
|
|
32
|
-
import pipeline_state
|
|
33
|
-
import state_checkpoint
|
|
28
|
+
if __package__:
|
|
29
|
+
from . import archive_milestone
|
|
30
|
+
from . import isolation
|
|
31
|
+
from . import pipeline_git
|
|
32
|
+
from . import pipeline_state
|
|
33
|
+
from . import state_checkpoint
|
|
34
34
|
return archive_milestone, isolation, pipeline_git, pipeline_state, state_checkpoint
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
35
|
+
else:
|
|
36
|
+
try:
|
|
37
|
+
import archive_milestone
|
|
38
|
+
import isolation
|
|
39
|
+
import pipeline_git
|
|
40
|
+
import pipeline_state
|
|
41
|
+
import state_checkpoint
|
|
42
|
+
return archive_milestone, isolation, pipeline_git, pipeline_state, state_checkpoint
|
|
43
|
+
except ModuleNotFoundError as error:
|
|
44
|
+
if error.name not in {
|
|
45
|
+
"archive_milestone",
|
|
46
|
+
"isolation",
|
|
47
|
+
"pipeline_git",
|
|
48
|
+
"pipeline_state",
|
|
49
|
+
"state_checkpoint",
|
|
50
|
+
}:
|
|
51
|
+
raise
|
|
44
52
|
try:
|
|
45
53
|
from scripts import archive_milestone, isolation, pipeline_git, pipeline_state, state_checkpoint
|
|
46
54
|
return archive_milestone, isolation, pipeline_git, pipeline_state, state_checkpoint
|
|
@@ -94,7 +102,7 @@ UNDO_TRANSACTION_SCHEMA = pipeline_state.UNDO_TRANSACTION_SCHEMA
|
|
|
94
102
|
UNDO_TRANSACTION_NAME = pipeline_state.UNDO_TRANSACTION_NAME
|
|
95
103
|
ROADMAP_APPROVAL_SUBJECT = "roadmap: program roadmap approved"
|
|
96
104
|
TASK_SUBJECT_RE = re.compile(r"^(T\d{3,}): .+")
|
|
97
|
-
KINDS = ("checkpoint", "task", "uncommitted-archive", "lookahead")
|
|
105
|
+
KINDS = ("checkpoint", "task", "member-task", "uncommitted-archive", "lookahead")
|
|
98
106
|
PROMOTION_PREFIX = "router: promote lookahead milestone "
|
|
99
107
|
ABANDON_PREFIX = "build: abandon milestone "
|
|
100
108
|
INTEGRATE_PREFIX = "integrate: "
|
|
@@ -528,6 +536,7 @@ def _prepare_transaction(
|
|
|
528
536
|
branch: str,
|
|
529
537
|
archive: Optional[str],
|
|
530
538
|
discussion: Optional[dict[str, bytes]],
|
|
539
|
+
member_fields: Optional[dict[str, str]] = None,
|
|
531
540
|
) -> dict[str, object]:
|
|
532
541
|
transaction = {
|
|
533
542
|
"schema": UNDO_TRANSACTION_SCHEMA,
|
|
@@ -545,6 +554,8 @@ def _prepare_transaction(
|
|
|
545
554
|
),
|
|
546
555
|
"discussion": _encode_discussion(discussion),
|
|
547
556
|
}
|
|
557
|
+
if member_fields is not None:
|
|
558
|
+
transaction.update(member_fields)
|
|
548
559
|
_write_json(_git_path(repo, UNDO_TRANSACTION_NAME), transaction)
|
|
549
560
|
return transaction
|
|
550
561
|
|
|
@@ -641,7 +652,7 @@ def _transaction_recovery_stage(
|
|
|
641
652
|
expected_head = str(transaction["expected_head"])
|
|
642
653
|
parent = str(transaction["parent"])
|
|
643
654
|
current = _optional_rev(repo, "HEAD")
|
|
644
|
-
if transaction["kind"]
|
|
655
|
+
if transaction["kind"] in {"checkpoint", "member-task"}:
|
|
645
656
|
allowed = {expected_head, parent}
|
|
646
657
|
else:
|
|
647
658
|
allowed = {expected_head}
|
|
@@ -662,8 +673,60 @@ def _transaction_recovery_stage(
|
|
|
662
673
|
return "reset"
|
|
663
674
|
|
|
664
675
|
|
|
676
|
+
def _member_undo_parent(repo: Path, member: str, landing: str) -> str:
|
|
677
|
+
"""The member landing's parent, while that landing is the unpublished bound tip."""
|
|
678
|
+
checkout, _, entry = isolation._member_context(repo, member)
|
|
679
|
+
bound = entry["branch"]
|
|
680
|
+
if _run_git(checkout, "rev-parse", f"refs/heads/{bound}").stdout.strip() != landing:
|
|
681
|
+
raise UndoError(f"member {member} {bound} moved past this landing")
|
|
682
|
+
_require_member_unpublished(checkout, member, landing, bound)
|
|
683
|
+
return _run_git(checkout, "rev-parse", f"{landing}^").stdout.strip()
|
|
684
|
+
|
|
685
|
+
|
|
686
|
+
def _require_member_unpublished(checkout: Path, member: str, landing: str, bound: str) -> None:
|
|
687
|
+
for ref, where in (("refs/remotes/origin/main", "origin/main"), (f"refs/remotes/origin/{bound}", f"origin/{bound}")):
|
|
688
|
+
if _run_git(checkout, "merge-base", "--is-ancestor", landing, ref, check=False).returncode == 0:
|
|
689
|
+
raise UndoError(f"member {member} landing is already on {where}")
|
|
690
|
+
|
|
691
|
+
|
|
692
|
+
def _require_no_member_landing_journal(repo: Path) -> None:
|
|
693
|
+
directory = isolation.common_git_dir(repo).joinpath(*isolation.MEMBER_LANDING_DIR)
|
|
694
|
+
if any(directory.glob("*.json")):
|
|
695
|
+
raise UndoError("member landing journal is pending; recover member landing first")
|
|
696
|
+
|
|
697
|
+
|
|
698
|
+
def _undo_member_landing(repo: Path, transaction: dict[str, object]) -> None:
|
|
699
|
+
"""Reset the member bound branch first; a resumed undo finds it already reset."""
|
|
700
|
+
member = str(transaction["member"])
|
|
701
|
+
checkout, _, entry = isolation._member_context(repo, member)
|
|
702
|
+
tip = _run_git(checkout, "rev-parse", f"refs/heads/{entry['branch']}").stdout.strip()
|
|
703
|
+
if tip == transaction["member_parent"]:
|
|
704
|
+
_require_member_unpublished(checkout, member, str(transaction["landing"]), entry["branch"])
|
|
705
|
+
return
|
|
706
|
+
if tip != transaction["landing"]:
|
|
707
|
+
raise UndoError(f"member {member} bound branch moved during undo")
|
|
708
|
+
if _member_undo_parent(repo, member, str(transaction["landing"])) != transaction["member_parent"]:
|
|
709
|
+
raise UndoError(f"member {member} landing parent changed during undo")
|
|
710
|
+
bound = Path(isolation.member_bound_checkout(repo, member)["checkout"])
|
|
711
|
+
if _run_git(bound, "status", "--porcelain", "--untracked-files=all").stdout:
|
|
712
|
+
raise UndoError(f"member {member} bound checkout is dirty")
|
|
713
|
+
_run_git(bound, "reset", "--hard", str(transaction["member_parent"]))
|
|
714
|
+
|
|
715
|
+
|
|
665
716
|
def _finish_transaction(repo: Path, transaction: dict[str, object]) -> None:
|
|
717
|
+
if transaction["kind"] == "member-task":
|
|
718
|
+
with isolation._member_landing_lock(repo):
|
|
719
|
+
_finish_transaction_locked(repo, transaction)
|
|
720
|
+
return
|
|
721
|
+
_finish_transaction_locked(repo, transaction)
|
|
722
|
+
|
|
723
|
+
|
|
724
|
+
def _finish_transaction_locked(repo: Path, transaction: dict[str, object]) -> None:
|
|
725
|
+
if transaction["kind"] == "member-task":
|
|
726
|
+
_require_no_member_landing_journal(repo)
|
|
666
727
|
stage = _transaction_recovery_stage(repo, transaction)
|
|
728
|
+
if transaction["kind"] == "member-task":
|
|
729
|
+
_undo_member_landing(repo, transaction)
|
|
667
730
|
if stage == "prepared":
|
|
668
731
|
_require_unpublished_reset(repo, str(transaction["branch"]))
|
|
669
732
|
_reset_to(repo, str(transaction["parent"]))
|
|
@@ -675,11 +738,7 @@ def _finish_transaction(repo: Path, transaction: dict[str, object]) -> None:
|
|
|
675
738
|
_remove_untracked_tree(repo, archive)
|
|
676
739
|
path = _git_path(repo, UNDO_TRANSACTION_NAME)
|
|
677
740
|
path.unlink()
|
|
678
|
-
|
|
679
|
-
try:
|
|
680
|
-
os.fsync(descriptor)
|
|
681
|
-
finally:
|
|
682
|
-
os.close(descriptor)
|
|
741
|
+
pipeline_state._common.fsync_directory(path.parent)
|
|
683
742
|
|
|
684
743
|
|
|
685
744
|
def classify_undo(repo: Path) -> dict[str, object]:
|
|
@@ -821,6 +880,28 @@ def classify_undo(repo: Path) -> dict[str, object]:
|
|
|
821
880
|
proof_error = _task_proof_error(resolved, head)
|
|
822
881
|
if proof_error:
|
|
823
882
|
return _blocked([f"task landing ownership is unproven: {proof_error}"])
|
|
883
|
+
record = isolation.MEMBER_RECORD_RE.search(body)
|
|
884
|
+
if record is not None:
|
|
885
|
+
try:
|
|
886
|
+
_require_no_member_landing_journal(resolved)
|
|
887
|
+
member_parent = _member_undo_parent(resolved, record["member"], record["landing"])
|
|
888
|
+
except (IsolationError, UndoError, PipelineStateError) as error:
|
|
889
|
+
return _blocked([f"member landing undo is unsafe: {error}"])
|
|
890
|
+
return {
|
|
891
|
+
"kind": "member-task",
|
|
892
|
+
"branch": recorded_branch,
|
|
893
|
+
"head": head,
|
|
894
|
+
"parent": parent,
|
|
895
|
+
"subject": subject,
|
|
896
|
+
"member": record["member"],
|
|
897
|
+
"landing": record["landing"],
|
|
898
|
+
"member_parent": member_parent,
|
|
899
|
+
"effects": [
|
|
900
|
+
f"reset member {record['member']} bound branch to {member_parent}",
|
|
901
|
+
f"reset {recorded_branch} to {parent}",
|
|
902
|
+
],
|
|
903
|
+
"blocked": [],
|
|
904
|
+
}
|
|
824
905
|
return {
|
|
825
906
|
"kind": "task",
|
|
826
907
|
"branch": recorded_branch,
|
|
@@ -978,6 +1059,20 @@ def apply_undo(repo: Path, kind: str, expected_head: str) -> dict[str, object]:
|
|
|
978
1059
|
discussion,
|
|
979
1060
|
)
|
|
980
1061
|
_finish_transaction(resolved, transaction)
|
|
1062
|
+
elif kind == "member-task":
|
|
1063
|
+
with isolation._member_landing_lock(resolved):
|
|
1064
|
+
_require_no_member_landing_journal(resolved)
|
|
1065
|
+
if preview(resolved)["target"] != target:
|
|
1066
|
+
raise UndoError("member task undo target changed after preview")
|
|
1067
|
+
if _worktree_changes(resolved):
|
|
1068
|
+
raise UndoError("worktree changed after member task undo preview")
|
|
1069
|
+
_require_unpublished_reset(resolved, str(target["branch"]))
|
|
1070
|
+
transaction = _prepare_transaction(
|
|
1071
|
+
resolved, kind, expected_head, str(target["parent"]), str(target["branch"]), None, None,
|
|
1072
|
+
{"member": str(target["member"]), "landing": str(target["landing"]),
|
|
1073
|
+
"member_parent": str(target["member_parent"])},
|
|
1074
|
+
)
|
|
1075
|
+
_finish_transaction_locked(resolved, transaction)
|
|
981
1076
|
elif kind == "task":
|
|
982
1077
|
parent = target["parent"]
|
|
983
1078
|
if not parent:
|
|
@@ -470,7 +470,7 @@ def merge_artifacts(
|
|
|
470
470
|
lines.append(artifact["text"].rstrip())
|
|
471
471
|
lines.append("")
|
|
472
472
|
output.parent.mkdir(parents=True, exist_ok=True)
|
|
473
|
-
output.
|
|
473
|
+
output.write_bytes(("\n".join(lines).rstrip() + "\n").encode("utf-8"))
|
|
474
474
|
return {
|
|
475
475
|
"output": str(output.resolve()),
|
|
476
476
|
"families": families,
|
|
@@ -13,10 +13,13 @@ import os
|
|
|
13
13
|
import tempfile
|
|
14
14
|
from pathlib import Path
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
import _common
|
|
18
|
-
|
|
19
|
-
|
|
16
|
+
if __package__:
|
|
17
|
+
from . import _common
|
|
18
|
+
else:
|
|
19
|
+
try:
|
|
20
|
+
import _common
|
|
21
|
+
except ImportError:
|
|
22
|
+
from scripts import _common
|
|
20
23
|
|
|
21
24
|
|
|
22
25
|
def _git(primary: Path, *args: str) -> str:
|
|
@@ -27,7 +30,10 @@ def _git(primary: Path, *args: str) -> str:
|
|
|
27
30
|
|
|
28
31
|
|
|
29
32
|
def _identity(path: Path) -> str:
|
|
30
|
-
|
|
33
|
+
digest = hashlib.sha256(os.fsencode(path)).hexdigest()
|
|
34
|
+
# Two identities nest in every managed path; full digests would use about
|
|
35
|
+
# 130 of Windows' 260-character MAX_PATH before any repository content.
|
|
36
|
+
return digest[:16] if os.name == "nt" else digest
|
|
31
37
|
|
|
32
38
|
|
|
33
39
|
def _workspace(primary: Path, pin: bool) -> Path:
|
|
@@ -65,7 +71,7 @@ def _workspace(primary: Path, pin: bool) -> Path:
|
|
|
65
71
|
receipt.parent.mkdir(parents=True, exist_ok=True)
|
|
66
72
|
fd, temporary = tempfile.mkstemp(dir=receipt.parent)
|
|
67
73
|
try:
|
|
68
|
-
with os.fdopen(fd, "w", encoding="utf-8") as handle:
|
|
74
|
+
with os.fdopen(fd, "w", encoding="utf-8", newline="\n") as handle:
|
|
69
75
|
json.dump({"primary": str(primary), "root": str(workspace)}, handle)
|
|
70
76
|
try:
|
|
71
77
|
os.link(temporary, receipt)
|
|
@@ -78,15 +84,19 @@ def _workspace(primary: Path, pin: bool) -> Path:
|
|
|
78
84
|
|
|
79
85
|
def worktree_path(primary: Path, kind: str, name: str, *, pin: bool = False) -> Path:
|
|
80
86
|
primary = primary.resolve()
|
|
81
|
-
if kind not in {"task", "verify", "integrate"} or not name or Path(name).name != name or name in {".", ".."}:
|
|
87
|
+
if kind not in {"task", "verify", "integrate", "bound"} or not name or Path(name).name != name or name in {".", ".."}:
|
|
82
88
|
raise ValueError("invalid managed worktree kind or name")
|
|
89
|
+
if kind == "bound":
|
|
90
|
+
return _workspace(primary, pin) / kind / name
|
|
83
91
|
legacy = (primary.parent / f".{primary.name}-gsd-path-integrate-{name}"
|
|
84
92
|
if kind == "integrate" else primary.parent / f"{primary.name}.gsd-path" / kind / name)
|
|
85
93
|
branch = f"refs/heads/gsd-path-{kind}/{name}"
|
|
86
94
|
records = _git(primary, "worktree", "list", "--porcelain", "-z").split("\0\0")
|
|
87
95
|
for record in records:
|
|
88
96
|
fields = record.split("\0")
|
|
89
|
-
|
|
97
|
+
# Compare as paths: git prints forward slashes on Windows.
|
|
98
|
+
worktrees = [Path(field[len("worktree "):]) for field in fields if field.startswith("worktree ")]
|
|
99
|
+
if legacy in worktrees and f"branch {branch}" in fields:
|
|
90
100
|
return legacy
|
|
91
101
|
# Keep collision checks and missing-directory recovery at the old location.
|
|
92
102
|
if os.path.lexists(legacy):
|
|
@@ -3,7 +3,8 @@ name: gsd-path-inspect
|
|
|
3
3
|
description: Inspect an existing codebase and its documentation to establish brownfield ground truth before intent is defined. Use only when the user explicitly invokes $gsd-path-inspect or an active $gsd-path router explicitly routes to this phase.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
Before executing project helpers, read [runtime selection](references/runtime-selection.md)
|
|
6
|
+
Before executing project helpers, read [runtime selection](references/runtime-selection.md)
|
|
7
|
+
and [operating rules](references/operating-rules.md).
|
|
7
8
|
|
|
8
9
|
# GSD Path Inspect Phase
|
|
9
10
|
|
|
@@ -112,15 +113,15 @@ Preparation never changes phase state; neither command dispatches agents.
|
|
|
112
113
|
includes its path and revision for project commands; expected new pipeline
|
|
113
114
|
artifacts do not make product code dirty. Each agent writes only its
|
|
114
115
|
assigned output under that sidecar and keeps it there for the gates in step
|
|
115
|
-
3. Otherwise no
|
|
116
|
+
3; its `Repo root` header still names the absolute primary. Otherwise no
|
|
116
117
|
project command may run. The docs-auditor brief carries current HEAD as the
|
|
117
118
|
audit baseline only when its verify sidecar was created at HEAD; otherwise
|
|
118
119
|
it carries `none`. The auditor writes that baseline as `Audited HEAD`.
|
|
119
120
|
3. Gate both artifacts against their templates: the codebase evidence needs
|
|
120
121
|
a filled `## Map` plus findings as observed — no quota, but an empty
|
|
121
122
|
findings section must say why; the docs audit must pass the bundled
|
|
122
|
-
`python3 <absolute check_docs_audit.py> --repo <docs sidecar> --
|
|
123
|
-
<track-relative DOCS-AUDIT.md> --inventory <frozen inventory file>`, where
|
|
123
|
+
`python3 <absolute check_docs_audit.py> --repo <docs sidecar> --primary
|
|
124
|
+
<absolute primary> --audit <track-relative DOCS-AUDIT.md> --inventory <frozen inventory file>`, where
|
|
124
125
|
the audit path is `.project/research/DOCS-AUDIT.md` normally and
|
|
125
126
|
`.project/next/research/DOCS-AUDIT.md` in Lookahead mode; add
|
|
126
127
|
`--prior-audit <temporary prior-audit file>` when one was preserved and
|
|
@@ -10,7 +10,8 @@ change nothing outside your single output file.
|
|
|
10
10
|
- Read AGENTS.md and the template before scanning. Stop on a missing path.
|
|
11
11
|
- Write only the assigned output using the template. When the brief supplies a
|
|
12
12
|
disposable root, write the output under that root at the relative handoff
|
|
13
|
-
path; the orchestrator transfers it after validation.
|
|
13
|
+
path; the orchestrator transfers it after validation. `Repo root` still names
|
|
14
|
+
the primary repo root, never the disposable root. Do not ask the user
|
|
14
15
|
questions.
|
|
15
16
|
|
|
16
17
|
## What to establish
|
|
@@ -11,7 +11,8 @@ actually does. Read-only: change nothing outside your single output file.
|
|
|
11
11
|
- Read AGENTS.md and the template before auditing. Stop on a missing path.
|
|
12
12
|
- Write only the assigned output using the template. When the brief supplies a
|
|
13
13
|
disposable root, write the output under that root at the relative handoff
|
|
14
|
-
path; the orchestrator transfers it after validation.
|
|
14
|
+
path; the orchestrator transfers it after validation. `Repo root` still names
|
|
15
|
+
the primary repo root, never the disposable root. Do not ask the user
|
|
15
16
|
questions.
|
|
16
17
|
|
|
17
18
|
## Method
|