@opengsd/gsd-path 1.3.1 → 1.5.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 +331 -69
- package/DOCS.md +25 -9
- package/FULL.md +12 -5
- package/GUIDE.md +1 -1
- package/HOOKS.md +104 -14
- package/QUICK.md +5 -2
- package/README.md +131 -111
- package/RUNTIME.md +2 -2
- package/UPDATE.md +61 -11
- package/WORKFLOW.md +44 -7
- package/package.json +13 -9
- package/platforms/shared-agents/dispatch.md +13 -0
- package/scripts/_common.py +619 -18
- package/scripts/archive_milestone.py +160 -86
- package/scripts/bootstrap_repository.py +8 -5
- package/scripts/build_recovery.py +100 -32
- package/scripts/build_state.py +143 -24
- package/scripts/check_docs_audit.py +91 -7
- package/scripts/check_handoffs.py +662 -50
- package/scripts/check_task_briefs.py +338 -30
- 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 +587 -32
- package/scripts/discussion_records.py +19 -13
- package/scripts/discussion_validate.py +152 -50
- package/scripts/dispatch_driver.py +501 -46
- package/scripts/git_guard.py +118 -31
- package/scripts/guard_hook.py +1567 -194
- package/scripts/install.mjs +77 -46
- package/scripts/install.py +611 -50
- package/scripts/integration.py +580 -25
- package/scripts/isolation.py +1438 -57
- package/scripts/lean_verification.py +99 -19
- package/scripts/loop_run.py +31 -29
- package/scripts/members.py +706 -0
- package/scripts/migrate_core.py +2 -2
- package/scripts/path_config.py +5 -5
- package/scripts/pipeline_diagnose.py +82 -31
- package/scripts/pipeline_git.py +124 -34
- package/scripts/pipeline_state.py +287 -87
- package/scripts/pipeline_undo.py +218 -30
- package/scripts/promote_lookahead.py +1 -1
- package/scripts/review_panel.py +1 -1
- package/scripts/runtime_store.py +55 -11
- package/scripts/skill-resources.json +37 -5
- package/scripts/state_checkpoint.py +135 -44
- package/scripts/state_promote.py +2 -0
- package/scripts/status_runtime.py +58 -10
- package/scripts/sync_skill_resources.py +8 -7
- package/scripts/task_context.py +12 -3
- package/scripts/token_budget.py +12 -8
- package/scripts/wizard.mjs +1 -0
- package/scripts/workflow_run.py +107 -30
- package/scripts/worktree_paths.py +72 -10
- package/skills/gsd-path/BUILD.md +7 -1
- package/skills/gsd-path/DECIDE.md +11 -4
- package/skills/gsd-path/DEFINE.md +36 -4
- package/skills/gsd-path/DOCS-AUDIT.md +6 -4
- package/skills/gsd-path/INSPECT.md +5 -4
- package/skills/gsd-path/PLAN.md +18 -4
- package/skills/gsd-path/RESEARCH.md +13 -1
- package/skills/gsd-path/ROADMAP.md +2 -1
- package/skills/gsd-path/SHIP.md +33 -11
- package/skills/gsd-path/SKILL.md +45 -1
- package/skills/gsd-path/references/build-native.md +63 -15
- package/skills/gsd-path/references/codebase-mapper.md +2 -1
- package/skills/gsd-path/references/dispatch.md +13 -0
- package/skills/gsd-path/references/docs-auditor.md +7 -1
- package/skills/gsd-path/references/operating-rules.md +214 -0
- package/skills/gsd-path/references/planner.md +22 -4
- package/skills/gsd-path/references/reviewer-final.md +20 -2
- package/skills/gsd-path/references/reviewer-wave.md +18 -5
- package/skills/gsd-path/references/reviewer.md +3 -1
- package/skills/gsd-path/references/spec-probes.md +150 -0
- package/skills/gsd-path/scripts/_common.py +619 -18
- package/skills/gsd-path/scripts/archive_milestone.py +160 -86
- package/skills/gsd-path/scripts/bootstrap_repository.py +8 -5
- package/skills/gsd-path/scripts/build_recovery.py +100 -32
- package/skills/gsd-path/scripts/build_state.py +143 -24
- package/skills/gsd-path/scripts/check_docs_audit.py +91 -7
- package/skills/gsd-path/scripts/check_handoffs.py +662 -50
- package/skills/gsd-path/scripts/check_task_briefs.py +338 -30
- package/skills/gsd-path/scripts/check_update.py +2 -2
- package/skills/gsd-path/scripts/detect_project.py +587 -32
- package/skills/gsd-path/scripts/discussion_records.py +19 -13
- package/skills/gsd-path/scripts/discussion_validate.py +152 -50
- package/skills/gsd-path/scripts/dispatch_driver.py +501 -46
- package/skills/gsd-path/scripts/git_guard.py +118 -31
- package/skills/gsd-path/scripts/integration.py +580 -25
- package/skills/gsd-path/scripts/isolation.py +1438 -57
- package/skills/gsd-path/scripts/lean_verification.py +99 -19
- package/skills/gsd-path/scripts/loop_run.py +31 -29
- package/skills/gsd-path/scripts/members.py +706 -0
- package/skills/gsd-path/scripts/path_config.py +5 -5
- package/skills/gsd-path/scripts/pipeline_git.py +124 -34
- package/skills/gsd-path/scripts/pipeline_state.py +287 -87
- 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 +135 -44
- package/skills/gsd-path/scripts/state_promote.py +2 -0
- package/skills/gsd-path/scripts/status_runtime.py +58 -10
- package/skills/gsd-path/scripts/task_context.py +12 -3
- package/skills/gsd-path/scripts/token_budget.py +12 -8
- package/skills/gsd-path/scripts/workflow_run.py +107 -30
- package/skills/gsd-path/scripts/worktree_paths.py +72 -10
- package/skills/gsd-path/templates/codebase.md +1 -1
- package/skills/gsd-path/templates/docs-audit.md +6 -2
- package/skills/gsd-path/templates/final-review.md +16 -4
- package/skills/gsd-path/templates/gap-review.md +2 -1
- 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 +1 -1
- package/skills/gsd-path/templates/task.md +1 -0
- package/skills/gsd-path/templates/wave-review.md +16 -4
- package/skills/gsd-path-build/SKILL.md +7 -1
- package/skills/gsd-path-build/references/build-native.md +63 -15
- package/skills/gsd-path-build/references/dispatch.md +13 -0
- package/skills/gsd-path-build/references/operating-rules.md +214 -0
- package/skills/gsd-path-build/references/reviewer-final.md +20 -2
- package/skills/gsd-path-build/references/reviewer-wave.md +18 -5
- package/skills/gsd-path-build/references/reviewer.md +3 -1
- package/skills/gsd-path-build/references/spec-probes.md +150 -0
- package/skills/gsd-path-build/scripts/_common.py +619 -18
- package/skills/gsd-path-build/scripts/archive_milestone.py +160 -86
- package/skills/gsd-path-build/scripts/build_recovery.py +100 -32
- package/skills/gsd-path-build/scripts/build_state.py +143 -24
- package/skills/gsd-path-build/scripts/check_handoffs.py +662 -50
- package/skills/gsd-path-build/scripts/check_task_briefs.py +338 -30
- package/skills/gsd-path-build/scripts/detect_project.py +587 -32
- package/skills/gsd-path-build/scripts/discussion_records.py +19 -13
- package/skills/gsd-path-build/scripts/discussion_validate.py +152 -50
- package/skills/gsd-path-build/scripts/dispatch_driver.py +501 -46
- package/skills/gsd-path-build/scripts/integration.py +580 -25
- package/skills/gsd-path-build/scripts/isolation.py +1438 -57
- package/skills/gsd-path-build/scripts/loop_run.py +31 -29
- package/skills/gsd-path-build/scripts/members.py +706 -0
- package/skills/gsd-path-build/scripts/path_config.py +5 -5
- package/skills/gsd-path-build/scripts/pipeline_git.py +124 -34
- package/skills/gsd-path-build/scripts/pipeline_state.py +287 -87
- 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 +135 -44
- package/skills/gsd-path-build/scripts/state_promote.py +2 -0
- package/skills/gsd-path-build/scripts/task_context.py +12 -3
- package/skills/gsd-path-build/scripts/token_budget.py +12 -8
- package/skills/gsd-path-build/scripts/workflow_run.py +107 -30
- package/skills/gsd-path-build/scripts/worktree_paths.py +72 -10
- package/skills/gsd-path-build/templates/task.md +1 -0
- package/skills/gsd-path-build/templates/wave-review.md +16 -4
- package/skills/gsd-path-decide/SKILL.md +11 -4
- package/skills/gsd-path-decide/references/dispatch.md +13 -0
- package/skills/gsd-path-decide/references/operating-rules.md +214 -0
- package/skills/gsd-path-decide/scripts/_common.py +619 -18
- package/skills/gsd-path-decide/scripts/archive_milestone.py +160 -86
- package/skills/gsd-path-decide/scripts/build_recovery.py +100 -32
- package/skills/gsd-path-decide/scripts/check_handoffs.py +662 -50
- package/skills/gsd-path-decide/scripts/check_task_briefs.py +338 -30
- package/skills/gsd-path-decide/scripts/detect_project.py +587 -32
- package/skills/gsd-path-decide/scripts/discussion_records.py +19 -13
- package/skills/gsd-path-decide/scripts/discussion_validate.py +152 -50
- package/skills/gsd-path-decide/scripts/integration.py +580 -25
- package/skills/gsd-path-decide/scripts/isolation.py +1438 -57
- package/skills/gsd-path-decide/scripts/loop_run.py +31 -29
- package/skills/gsd-path-decide/scripts/members.py +706 -0
- package/skills/gsd-path-decide/scripts/path_config.py +5 -5
- package/skills/gsd-path-decide/scripts/pipeline_git.py +124 -34
- package/skills/gsd-path-decide/scripts/pipeline_state.py +287 -87
- 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 +135 -44
- package/skills/gsd-path-decide/scripts/state_promote.py +2 -0
- package/skills/gsd-path-decide/scripts/worktree_paths.py +72 -10
- package/skills/gsd-path-define/SKILL.md +36 -4
- package/skills/gsd-path-define/references/operating-rules.md +214 -0
- package/skills/gsd-path-define/references/spec-probes.md +150 -0
- package/skills/gsd-path-define/scripts/_common.py +619 -18
- package/skills/gsd-path-define/scripts/archive_milestone.py +160 -86
- package/skills/gsd-path-define/scripts/build_recovery.py +100 -32
- package/skills/gsd-path-define/scripts/check_handoffs.py +662 -50
- package/skills/gsd-path-define/scripts/check_task_briefs.py +338 -30
- package/skills/gsd-path-define/scripts/detect_project.py +587 -32
- package/skills/gsd-path-define/scripts/discussion_records.py +19 -13
- package/skills/gsd-path-define/scripts/discussion_validate.py +152 -50
- package/skills/gsd-path-define/scripts/integration.py +580 -25
- package/skills/gsd-path-define/scripts/isolation.py +1438 -57
- package/skills/gsd-path-define/scripts/loop_run.py +31 -29
- package/skills/gsd-path-define/scripts/members.py +706 -0
- package/skills/gsd-path-define/scripts/path_config.py +5 -5
- package/skills/gsd-path-define/scripts/pipeline_git.py +124 -34
- package/skills/gsd-path-define/scripts/pipeline_state.py +287 -87
- 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 +135 -44
- package/skills/gsd-path-define/scripts/state_promote.py +2 -0
- package/skills/gsd-path-define/scripts/worktree_paths.py +72 -10
- package/skills/gsd-path-define/templates/intent.md +30 -0
- package/skills/gsd-path-define/templates/state.md +1 -1
- 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 +619 -18
- package/skills/gsd-path-discuss/scripts/discussion_records.py +19 -13
- package/skills/gsd-path-discuss/scripts/loop_run.py +31 -29
- package/skills/gsd-path-discuss/scripts/path_config.py +5 -5
- package/skills/gsd-path-discuss/scripts/review_panel.py +1 -1
- package/skills/gsd-path-discuss/scripts/worktree_paths.py +72 -10
- package/skills/gsd-path-docs-audit/SKILL.md +6 -4
- package/skills/gsd-path-docs-audit/references/dispatch.md +13 -0
- package/skills/gsd-path-docs-audit/references/docs-auditor.md +7 -1
- package/skills/gsd-path-docs-audit/references/operating-rules.md +214 -0
- package/skills/gsd-path-docs-audit/scripts/_common.py +619 -18
- package/skills/gsd-path-docs-audit/scripts/archive_milestone.py +160 -86
- package/skills/gsd-path-docs-audit/scripts/build_recovery.py +100 -32
- package/skills/gsd-path-docs-audit/scripts/check_docs_audit.py +91 -7
- package/skills/gsd-path-docs-audit/scripts/check_handoffs.py +662 -50
- package/skills/gsd-path-docs-audit/scripts/check_task_briefs.py +338 -30
- package/skills/gsd-path-docs-audit/scripts/detect_project.py +587 -32
- package/skills/gsd-path-docs-audit/scripts/discussion_records.py +19 -13
- package/skills/gsd-path-docs-audit/scripts/discussion_validate.py +152 -50
- package/skills/gsd-path-docs-audit/scripts/integration.py +580 -25
- package/skills/gsd-path-docs-audit/scripts/isolation.py +1438 -57
- package/skills/gsd-path-docs-audit/scripts/loop_run.py +31 -29
- package/skills/gsd-path-docs-audit/scripts/members.py +706 -0
- package/skills/gsd-path-docs-audit/scripts/path_config.py +5 -5
- package/skills/gsd-path-docs-audit/scripts/pipeline_git.py +124 -34
- package/skills/gsd-path-docs-audit/scripts/pipeline_state.py +287 -87
- 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 +135 -44
- package/skills/gsd-path-docs-audit/scripts/state_promote.py +2 -0
- package/skills/gsd-path-docs-audit/scripts/worktree_paths.py +72 -10
- package/skills/gsd-path-docs-audit/templates/docs-audit.md +6 -2
- 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 +619 -18
- package/skills/gsd-path-forensics/scripts/discussion_records.py +19 -13
- package/skills/gsd-path-forensics/scripts/loop_run.py +31 -29
- package/skills/gsd-path-forensics/scripts/path_config.py +5 -5
- package/skills/gsd-path-forensics/scripts/pipeline_diagnose.py +82 -31
- package/skills/gsd-path-forensics/scripts/pipeline_undo.py +218 -30
- package/skills/gsd-path-forensics/scripts/review_panel.py +1 -1
- package/skills/gsd-path-forensics/scripts/worktree_paths.py +72 -10
- 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/dispatch.md +13 -0
- package/skills/gsd-path-inspect/references/docs-auditor.md +7 -1
- package/skills/gsd-path-inspect/references/operating-rules.md +214 -0
- package/skills/gsd-path-inspect/scripts/_common.py +619 -18
- package/skills/gsd-path-inspect/scripts/archive_milestone.py +160 -86
- package/skills/gsd-path-inspect/scripts/build_recovery.py +100 -32
- package/skills/gsd-path-inspect/scripts/check_docs_audit.py +91 -7
- package/skills/gsd-path-inspect/scripts/check_handoffs.py +662 -50
- package/skills/gsd-path-inspect/scripts/check_task_briefs.py +338 -30
- package/skills/gsd-path-inspect/scripts/detect_project.py +587 -32
- package/skills/gsd-path-inspect/scripts/discussion_records.py +19 -13
- package/skills/gsd-path-inspect/scripts/discussion_validate.py +152 -50
- package/skills/gsd-path-inspect/scripts/integration.py +580 -25
- package/skills/gsd-path-inspect/scripts/isolation.py +1438 -57
- package/skills/gsd-path-inspect/scripts/loop_run.py +31 -29
- package/skills/gsd-path-inspect/scripts/members.py +706 -0
- package/skills/gsd-path-inspect/scripts/path_config.py +5 -5
- package/skills/gsd-path-inspect/scripts/pipeline_git.py +124 -34
- package/skills/gsd-path-inspect/scripts/pipeline_state.py +287 -87
- 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 +135 -44
- package/skills/gsd-path-inspect/scripts/state_promote.py +2 -0
- package/skills/gsd-path-inspect/scripts/workflow_run.py +107 -30
- package/skills/gsd-path-inspect/scripts/worktree_paths.py +72 -10
- package/skills/gsd-path-inspect/templates/codebase.md +1 -1
- package/skills/gsd-path-inspect/templates/docs-audit.md +6 -2
- package/skills/gsd-path-inspect/templates/state.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 +619 -18
- package/skills/gsd-path-loop/scripts/discussion_records.py +19 -13
- package/skills/gsd-path-loop/scripts/loop_run.py +31 -29
- package/skills/gsd-path-loop/scripts/path_config.py +5 -5
- package/skills/gsd-path-loop/scripts/review_panel.py +1 -1
- package/skills/gsd-path-loop/scripts/worktree_paths.py +72 -10
- 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 +619 -18
- 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 +31 -29
- package/skills/gsd-path-migrate/scripts/migrate_core.py +2 -2
- package/skills/gsd-path-migrate/scripts/path_config.py +5 -5
- package/skills/gsd-path-migrate/scripts/review_panel.py +1 -1
- package/skills/gsd-path-plan/SKILL.md +18 -4
- package/skills/gsd-path-plan/references/dispatch.md +13 -0
- package/skills/gsd-path-plan/references/operating-rules.md +214 -0
- package/skills/gsd-path-plan/references/planner.md +22 -4
- package/skills/gsd-path-plan/references/spec-probes.md +150 -0
- package/skills/gsd-path-plan/scripts/_common.py +619 -18
- package/skills/gsd-path-plan/scripts/archive_milestone.py +160 -86
- package/skills/gsd-path-plan/scripts/build_recovery.py +100 -32
- package/skills/gsd-path-plan/scripts/check_handoffs.py +662 -50
- package/skills/gsd-path-plan/scripts/check_task_briefs.py +338 -30
- package/skills/gsd-path-plan/scripts/detect_project.py +587 -32
- package/skills/gsd-path-plan/scripts/discussion_records.py +19 -13
- package/skills/gsd-path-plan/scripts/discussion_validate.py +152 -50
- package/skills/gsd-path-plan/scripts/integration.py +580 -25
- package/skills/gsd-path-plan/scripts/isolation.py +1438 -57
- package/skills/gsd-path-plan/scripts/loop_run.py +31 -29
- package/skills/gsd-path-plan/scripts/members.py +706 -0
- package/skills/gsd-path-plan/scripts/path_config.py +5 -5
- package/skills/gsd-path-plan/scripts/pipeline_git.py +124 -34
- package/skills/gsd-path-plan/scripts/pipeline_state.py +287 -87
- 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 +135 -44
- package/skills/gsd-path-plan/scripts/state_promote.py +2 -0
- package/skills/gsd-path-plan/scripts/workflow_run.py +107 -30
- package/skills/gsd-path-plan/scripts/worktree_paths.py +72 -10
- 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 +13 -1
- package/skills/gsd-path-research/references/dispatch.md +13 -0
- package/skills/gsd-path-research/references/operating-rules.md +214 -0
- package/skills/gsd-path-research/scripts/_common.py +619 -18
- package/skills/gsd-path-research/scripts/archive_milestone.py +160 -86
- package/skills/gsd-path-research/scripts/build_recovery.py +100 -32
- package/skills/gsd-path-research/scripts/check_handoffs.py +662 -50
- package/skills/gsd-path-research/scripts/check_task_briefs.py +338 -30
- package/skills/gsd-path-research/scripts/detect_project.py +587 -32
- package/skills/gsd-path-research/scripts/discussion_records.py +19 -13
- package/skills/gsd-path-research/scripts/discussion_validate.py +152 -50
- package/skills/gsd-path-research/scripts/integration.py +580 -25
- package/skills/gsd-path-research/scripts/isolation.py +1438 -57
- package/skills/gsd-path-research/scripts/loop_run.py +31 -29
- package/skills/gsd-path-research/scripts/members.py +706 -0
- package/skills/gsd-path-research/scripts/path_config.py +5 -5
- package/skills/gsd-path-research/scripts/pipeline_git.py +124 -34
- package/skills/gsd-path-research/scripts/pipeline_state.py +287 -87
- 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 +135 -44
- package/skills/gsd-path-research/scripts/state_promote.py +2 -0
- package/skills/gsd-path-research/scripts/worktree_paths.py +72 -10
- package/skills/gsd-path-research/templates/research-handoff.md +14 -3
- package/skills/gsd-path-roadmap/SKILL.md +2 -1
- package/skills/gsd-path-roadmap/references/dispatch.md +13 -0
- package/skills/gsd-path-roadmap/references/operating-rules.md +214 -0
- package/skills/gsd-path-roadmap/scripts/_common.py +619 -18
- package/skills/gsd-path-roadmap/scripts/archive_milestone.py +160 -86
- package/skills/gsd-path-roadmap/scripts/build_recovery.py +100 -32
- package/skills/gsd-path-roadmap/scripts/check_handoffs.py +662 -50
- package/skills/gsd-path-roadmap/scripts/check_task_briefs.py +338 -30
- package/skills/gsd-path-roadmap/scripts/detect_project.py +587 -32
- package/skills/gsd-path-roadmap/scripts/discussion_records.py +19 -13
- package/skills/gsd-path-roadmap/scripts/discussion_validate.py +152 -50
- package/skills/gsd-path-roadmap/scripts/integration.py +580 -25
- package/skills/gsd-path-roadmap/scripts/isolation.py +1438 -57
- package/skills/gsd-path-roadmap/scripts/loop_run.py +31 -29
- package/skills/gsd-path-roadmap/scripts/members.py +706 -0
- package/skills/gsd-path-roadmap/scripts/path_config.py +5 -5
- package/skills/gsd-path-roadmap/scripts/pipeline_git.py +124 -34
- package/skills/gsd-path-roadmap/scripts/pipeline_state.py +287 -87
- 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 +135 -44
- package/skills/gsd-path-roadmap/scripts/state_promote.py +2 -0
- package/skills/gsd-path-roadmap/scripts/worktree_paths.py +72 -10
- package/skills/gsd-path-ship/SKILL.md +33 -11
- package/skills/gsd-path-ship/references/dispatch.md +13 -0
- package/skills/gsd-path-ship/references/operating-rules.md +214 -0
- package/skills/gsd-path-ship/references/reviewer-final.md +20 -2
- package/skills/gsd-path-ship/references/reviewer-wave.md +18 -5
- package/skills/gsd-path-ship/references/reviewer.md +3 -1
- package/skills/gsd-path-ship/references/spec-probes.md +150 -0
- package/skills/gsd-path-ship/scripts/_common.py +619 -18
- package/skills/gsd-path-ship/scripts/archive_milestone.py +160 -86
- package/skills/gsd-path-ship/scripts/build_recovery.py +100 -32
- package/skills/gsd-path-ship/scripts/build_state.py +143 -24
- package/skills/gsd-path-ship/scripts/check_handoffs.py +662 -50
- package/skills/gsd-path-ship/scripts/check_task_briefs.py +338 -30
- package/skills/gsd-path-ship/scripts/detect_project.py +587 -32
- package/skills/gsd-path-ship/scripts/discussion_records.py +19 -13
- package/skills/gsd-path-ship/scripts/discussion_validate.py +152 -50
- package/skills/gsd-path-ship/scripts/integration.py +580 -25
- package/skills/gsd-path-ship/scripts/isolation.py +1438 -57
- package/skills/gsd-path-ship/scripts/lean_verification.py +99 -19
- package/skills/gsd-path-ship/scripts/loop_run.py +31 -29
- package/skills/gsd-path-ship/scripts/members.py +706 -0
- package/skills/gsd-path-ship/scripts/path_config.py +5 -5
- package/skills/gsd-path-ship/scripts/pipeline_git.py +124 -34
- package/skills/gsd-path-ship/scripts/pipeline_state.py +287 -87
- 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 +135 -44
- package/skills/gsd-path-ship/scripts/state_promote.py +2 -0
- package/skills/gsd-path-ship/scripts/workflow_run.py +107 -30
- package/skills/gsd-path-ship/scripts/worktree_paths.py +72 -10
- package/skills/gsd-path-ship/templates/final-review.md +16 -4
- package/skills/gsd-path-ship/templates/gap-review.md +2 -1
- package/skills/gsd-path-ship/templates/patch-findings.md +3 -3
- package/skills/gsd-path-ship/templates/wave-review.md +16 -4
- 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 +619 -18
- package/skills/gsd-path-undo/scripts/discussion_records.py +19 -13
- package/skills/gsd-path-undo/scripts/loop_run.py +31 -29
- package/skills/gsd-path-undo/scripts/path_config.py +5 -5
- package/skills/gsd-path-undo/scripts/pipeline_undo.py +218 -30
- package/skills/gsd-path-undo/scripts/review_panel.py +1 -1
- package/skills/gsd-path-undo/scripts/worktree_paths.py +72 -10
- package/skills/path/BUILD.md +7 -1
- package/skills/path/DECIDE.md +11 -4
- package/skills/path/DEFINE.md +36 -4
- package/skills/path/DOCS-AUDIT.md +6 -4
- package/skills/path/INSPECT.md +5 -4
- package/skills/path/PLAN.md +18 -4
- package/skills/path/RESEARCH.md +13 -1
- package/skills/path/ROADMAP.md +2 -1
- package/skills/path/SHIP.md +33 -11
- package/skills/path/SKILL.md +45 -1
- package/skills/path/references/build-native.md +63 -15
- package/skills/path/references/codebase-mapper.md +2 -1
- package/skills/path/references/dispatch.md +13 -0
- package/skills/path/references/docs-auditor.md +7 -1
- package/skills/path/references/operating-rules.md +214 -0
- package/skills/path/references/planner.md +22 -4
- package/skills/path/references/reviewer-final.md +20 -2
- package/skills/path/references/reviewer-wave.md +18 -5
- package/skills/path/references/reviewer.md +3 -1
- package/skills/path/references/spec-probes.md +150 -0
- package/skills/path/scripts/_common.py +619 -18
- package/skills/path/scripts/archive_milestone.py +160 -86
- package/skills/path/scripts/bootstrap_repository.py +8 -5
- package/skills/path/scripts/build_recovery.py +100 -32
- package/skills/path/scripts/build_state.py +143 -24
- package/skills/path/scripts/check_docs_audit.py +91 -7
- package/skills/path/scripts/check_handoffs.py +662 -50
- package/skills/path/scripts/check_task_briefs.py +338 -30
- package/skills/path/scripts/check_update.py +2 -2
- package/skills/path/scripts/detect_project.py +587 -32
- package/skills/path/scripts/discussion_records.py +19 -13
- package/skills/path/scripts/discussion_validate.py +152 -50
- package/skills/path/scripts/dispatch_driver.py +501 -46
- package/skills/path/scripts/git_guard.py +118 -31
- package/skills/path/scripts/integration.py +580 -25
- package/skills/path/scripts/isolation.py +1438 -57
- package/skills/path/scripts/lean_verification.py +99 -19
- package/skills/path/scripts/loop_run.py +31 -29
- package/skills/path/scripts/members.py +706 -0
- package/skills/path/scripts/path_config.py +5 -5
- package/skills/path/scripts/pipeline_git.py +124 -34
- package/skills/path/scripts/pipeline_state.py +287 -87
- 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 +135 -44
- package/skills/path/scripts/state_promote.py +2 -0
- package/skills/path/scripts/status_runtime.py +58 -10
- package/skills/path/scripts/task_context.py +12 -3
- package/skills/path/scripts/token_budget.py +12 -8
- package/skills/path/scripts/workflow_run.py +107 -30
- package/skills/path/scripts/worktree_paths.py +72 -10
- package/skills/path/templates/codebase.md +1 -1
- package/skills/path/templates/docs-audit.md +6 -2
- package/skills/path/templates/final-review.md +16 -4
- package/skills/path/templates/gap-review.md +2 -1
- 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 +1 -1
- package/skills/path/templates/task.md +1 -0
- package/skills/path/templates/wave-review.md +16 -4
- 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
|
@@ -6,6 +6,7 @@ hook wiring. Inspection failures and violations both exit 1: unreadable Git
|
|
|
6
6
|
state cannot prove archive immutability or safe publication.
|
|
7
7
|
"""
|
|
8
8
|
|
|
9
|
+
import json
|
|
9
10
|
import re
|
|
10
11
|
import subprocess
|
|
11
12
|
from functools import lru_cache
|
|
@@ -19,8 +20,9 @@ sys.path.insert(0, str(_HERE / "runtime" if (_HERE / "runtime" / "isolation.py")
|
|
|
19
20
|
sys.dont_write_bytecode = True # a hook must not leave __pycache__ in the worktree
|
|
20
21
|
try:
|
|
21
22
|
from isolation import BOOKKEEPING_PREFIXES, NULL_SHA, _landing_state, task_frontmatter
|
|
22
|
-
from pipeline_git import is_ship_subject, task_commit_body
|
|
23
|
+
from pipeline_git import is_ship_subject, ship_body_matches, ship_commit_body, task_commit_body
|
|
23
24
|
from pipeline_state import _completion_status
|
|
25
|
+
import members
|
|
24
26
|
except ImportError as error: # pragma: no cover - broken install
|
|
25
27
|
print(
|
|
26
28
|
f"gsd-path guard: pipeline runtime is missing ({error}); commit blocked; "
|
|
@@ -57,6 +59,10 @@ PRODUCT_HINT = (
|
|
|
57
59
|
f"while this worktree carries unfinished milestone state, {LANDING_HINT}; "
|
|
58
60
|
"findings during ship reopen through the patch plan"
|
|
59
61
|
)
|
|
62
|
+
MEMBER_PUSH_HINT = (
|
|
63
|
+
"a member publishes its coordinator's Path refs, or work from them, only with "
|
|
64
|
+
"a coordinator authorization for that exact ref and object"
|
|
65
|
+
)
|
|
60
66
|
PUBLICATION_HINT = (
|
|
61
67
|
"unshipped milestone work reaches a remote only as its ship commit "
|
|
62
68
|
"(STATE shipped/done) through archive_milestone.py integrate; findings during "
|
|
@@ -76,7 +82,7 @@ INTEGRATION_STATE_FIELDS = LEGACY_STATE_FIELDS | {
|
|
|
76
82
|
"integration",
|
|
77
83
|
}
|
|
78
84
|
PROVENANCE_STATE_FIELDS = INTEGRATION_STATE_FIELDS | {"integration_source"}
|
|
79
|
-
INTEGRATION_MODES = {"direct", "pull-request"}
|
|
85
|
+
INTEGRATION_MODES = {"direct", "pull-request", "external-landing"}
|
|
80
86
|
INTEGRATION_SOURCES = {"default", "milestone"}
|
|
81
87
|
|
|
82
88
|
|
|
@@ -84,7 +90,7 @@ def staged_entries():
|
|
|
84
90
|
output = subprocess.run(
|
|
85
91
|
["git", "diff", "--cached", "--name-status", "-z", "--find-renames"],
|
|
86
92
|
capture_output=True,
|
|
87
|
-
|
|
93
|
+
encoding="utf-8", errors="replace",
|
|
88
94
|
check=True,
|
|
89
95
|
).stdout
|
|
90
96
|
tokens = output.split("\0")
|
|
@@ -139,7 +145,7 @@ def committed_archive_roots():
|
|
|
139
145
|
head = subprocess.run(
|
|
140
146
|
["git", "rev-parse", "--verify", "--quiet", "HEAD^{commit}"],
|
|
141
147
|
capture_output=True,
|
|
142
|
-
|
|
148
|
+
encoding="utf-8", errors="replace",
|
|
143
149
|
check=False,
|
|
144
150
|
)
|
|
145
151
|
if head.returncode == 1:
|
|
@@ -148,7 +154,7 @@ def committed_archive_roots():
|
|
|
148
154
|
output = subprocess.run(
|
|
149
155
|
["git", "ls-tree", "-r", "--name-only", "HEAD", "--", ARCHIVE_PREFIX],
|
|
150
156
|
capture_output=True,
|
|
151
|
-
|
|
157
|
+
encoding="utf-8", errors="replace",
|
|
152
158
|
check=True,
|
|
153
159
|
).stdout
|
|
154
160
|
return {
|
|
@@ -162,7 +168,7 @@ def staged_file(path):
|
|
|
162
168
|
return subprocess.run(
|
|
163
169
|
["git", "show", f":{path}"],
|
|
164
170
|
capture_output=True,
|
|
165
|
-
|
|
171
|
+
encoding="utf-8", errors="replace",
|
|
166
172
|
check=True,
|
|
167
173
|
).stdout
|
|
168
174
|
|
|
@@ -176,7 +182,7 @@ def shown_file(revspec):
|
|
|
176
182
|
shown = subprocess.run(
|
|
177
183
|
["git", "show", revspec],
|
|
178
184
|
capture_output=True,
|
|
179
|
-
|
|
185
|
+
encoding="utf-8", errors="replace",
|
|
180
186
|
check=False,
|
|
181
187
|
)
|
|
182
188
|
return shown.stdout if shown.returncode == 0 else None
|
|
@@ -187,7 +193,7 @@ def state_at(revision):
|
|
|
187
193
|
subprocess.run(
|
|
188
194
|
["git", "cat-file", "-e", revision],
|
|
189
195
|
capture_output=True,
|
|
190
|
-
|
|
196
|
+
encoding="utf-8", errors="replace",
|
|
191
197
|
check=True,
|
|
192
198
|
)
|
|
193
199
|
content = shown_file(f"{revision}:.project/STATE.md")
|
|
@@ -288,12 +294,25 @@ def ship_contract_violations(entries, subject, body, new_archives, state):
|
|
|
288
294
|
reviewed_head = subprocess.run(
|
|
289
295
|
["git", "rev-parse", "--verify", "HEAD"],
|
|
290
296
|
capture_output=True,
|
|
291
|
-
|
|
297
|
+
encoding="utf-8", errors="replace",
|
|
292
298
|
check=True,
|
|
293
299
|
).stdout.strip()
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
300
|
+
lock = f"{archive}/build/members.json"
|
|
301
|
+
staged_lock = subprocess.run(
|
|
302
|
+
["git", "ls-files", "--cached", "--", lock],
|
|
303
|
+
capture_output=True,
|
|
304
|
+
encoding="utf-8", errors="replace",
|
|
305
|
+
check=True,
|
|
306
|
+
).stdout
|
|
307
|
+
locked = [entry["name"] for entry in json.loads(staged_file(lock))["members"]] if staged_lock else []
|
|
308
|
+
rows = members.read_member_close(
|
|
309
|
+
Path(git_output("rev-parse", "--path-format=absolute", "--git-common-dir")), Path(archive).name
|
|
310
|
+
) if locked else []
|
|
311
|
+
if [row["name"] for row in rows] != locked or any(row["status"] != "integrated" for row in rows):
|
|
312
|
+
found.append("ship commit requires every locked member closed; run archive_milestone.py close-members")
|
|
313
|
+
expected_body = ship_commit_body(archive, reviewed_head, rows).rstrip("\n")
|
|
314
|
+
if not ship_body_matches(body, expected_body):
|
|
315
|
+
found.append("ship commit body does not match Archive, Reviewed-HEAD, and closed members")
|
|
297
316
|
changed_paths = {
|
|
298
317
|
new if code in "CR" else old
|
|
299
318
|
for code, old, new in entries
|
|
@@ -383,11 +402,15 @@ def staged_abandon_target(new_archives, state):
|
|
|
383
402
|
|
|
384
403
|
|
|
385
404
|
@lru_cache(maxsize=None)
|
|
405
|
+
def git_output(*arguments):
|
|
406
|
+
return subprocess.run(["git", *arguments], capture_output=True, encoding="utf-8", errors="replace", check=True).stdout.strip()
|
|
407
|
+
|
|
408
|
+
|
|
386
409
|
def current_branch():
|
|
387
410
|
return subprocess.run(
|
|
388
411
|
["git", "branch", "--show-current"],
|
|
389
412
|
capture_output=True,
|
|
390
|
-
|
|
413
|
+
encoding="utf-8", errors="replace",
|
|
391
414
|
check=True,
|
|
392
415
|
).stdout.strip()
|
|
393
416
|
|
|
@@ -398,7 +421,7 @@ def closed_milestone_reason():
|
|
|
398
421
|
return None
|
|
399
422
|
commits = subprocess.run(
|
|
400
423
|
["git", "log", "--format=%H", "--grep=^ship:", "HEAD"],
|
|
401
|
-
capture_output=True,
|
|
424
|
+
capture_output=True, encoding="utf-8", errors="replace", check=True,
|
|
402
425
|
).stdout.splitlines()
|
|
403
426
|
if any(ship_commit_at(sha, branch) for sha in commits):
|
|
404
427
|
return (f"closed milestone {branch} accepts no new work; finish integration "
|
|
@@ -411,7 +434,7 @@ def head_descends_from(commit):
|
|
|
411
434
|
subprocess.run(
|
|
412
435
|
["git", "merge-base", "--is-ancestor", commit, "HEAD"],
|
|
413
436
|
capture_output=True,
|
|
414
|
-
|
|
437
|
+
encoding="utf-8", errors="replace",
|
|
415
438
|
check=False,
|
|
416
439
|
).returncode
|
|
417
440
|
== 0
|
|
@@ -429,7 +452,7 @@ def repo_root():
|
|
|
429
452
|
subprocess.run(
|
|
430
453
|
["git", "rev-parse", "--show-toplevel"],
|
|
431
454
|
capture_output=True,
|
|
432
|
-
|
|
455
|
+
encoding="utf-8", errors="replace",
|
|
433
456
|
check=True,
|
|
434
457
|
).stdout.strip()
|
|
435
458
|
)
|
|
@@ -505,7 +528,7 @@ def ship_commit_at(sha, bound):
|
|
|
505
528
|
shown = subprocess.run(
|
|
506
529
|
["git", "show", "--no-patch", "--format=%s", sha],
|
|
507
530
|
capture_output=True,
|
|
508
|
-
|
|
531
|
+
encoding="utf-8", errors="replace",
|
|
509
532
|
check=True,
|
|
510
533
|
)
|
|
511
534
|
archive = state.get("archive") or ""
|
|
@@ -514,13 +537,7 @@ def ship_commit_at(sha, bound):
|
|
|
514
537
|
)
|
|
515
538
|
|
|
516
539
|
|
|
517
|
-
def
|
|
518
|
-
"""Refuse ref updates that publish unshipped milestone work.
|
|
519
|
-
|
|
520
|
-
A bound-named ref moves only to, or away from, its strict ship commit. Any
|
|
521
|
-
other ref may not carry a commit whose STATE.md still owes a ship commit.
|
|
522
|
-
"""
|
|
523
|
-
found = []
|
|
540
|
+
def _push_updates(lines):
|
|
524
541
|
for line in lines:
|
|
525
542
|
parts = line.split()
|
|
526
543
|
if len(parts) != 4:
|
|
@@ -528,6 +545,60 @@ def pre_push_violations(lines):
|
|
|
528
545
|
local_ref, local_sha, remote_ref, remote_sha = parts
|
|
529
546
|
if any(re.fullmatch(r"[0-9a-fA-F]{40}", sha) is None for sha in (local_sha, remote_sha)):
|
|
530
547
|
raise ValueError(f"unexpected pre-push SHA: {line!r}")
|
|
548
|
+
yield local_ref, local_sha, remote_ref, remote_sha
|
|
549
|
+
|
|
550
|
+
|
|
551
|
+
def _commits(*arguments):
|
|
552
|
+
listed = subprocess.run(
|
|
553
|
+
["git", "rev-list", *arguments], capture_output=True, encoding="utf-8", errors="replace", check=True
|
|
554
|
+
)
|
|
555
|
+
return set(listed.stdout.split())
|
|
556
|
+
|
|
557
|
+
|
|
558
|
+
def member_pre_push_violations(lines, role):
|
|
559
|
+
"""Member mode: the member's own STATE is ignored; coordinator refs need authorization."""
|
|
560
|
+
checkout, project = repo_root(), role["project"]
|
|
561
|
+
reserved = members.member_ref_prefixes(project)
|
|
562
|
+
members.require_origin_main(checkout)
|
|
563
|
+
exclude = ["--not", "refs/remotes/origin/main"]
|
|
564
|
+
member_work = None
|
|
565
|
+
found = []
|
|
566
|
+
for _, local_sha, remote_ref, remote_sha in _push_updates(lines):
|
|
567
|
+
if local_sha == NULL_SHA:
|
|
568
|
+
if remote_ref.startswith(reserved) and not members.authorized(
|
|
569
|
+
checkout, project, "delete", remote_ref, remote_sha
|
|
570
|
+
):
|
|
571
|
+
found.append(f"{remote_ref} deletion is not authorized by {project}; {MEMBER_PUSH_HINT}")
|
|
572
|
+
continue
|
|
573
|
+
if members.authorized(checkout, project, "push", remote_ref, local_sha):
|
|
574
|
+
continue
|
|
575
|
+
if remote_ref.startswith(reserved):
|
|
576
|
+
found.append(
|
|
577
|
+
f"{remote_ref} <- {local_sha[:12]} is not authorized by {project}; {MEMBER_PUSH_HINT}"
|
|
578
|
+
)
|
|
579
|
+
continue
|
|
580
|
+
if member_work is None:
|
|
581
|
+
bound = [ref for ref in subprocess.run(
|
|
582
|
+
["git", "for-each-ref", "--format=%(refname)", "refs/heads/gsd-path/"],
|
|
583
|
+
capture_output=True, encoding="utf-8", errors="replace", check=True,
|
|
584
|
+
).stdout.split() if ref.startswith(f"refs/heads/gsd-path/{project}-")]
|
|
585
|
+
member_work = _commits(*bound, *exclude) if bound else set()
|
|
586
|
+
if member_work & _commits(local_sha, *exclude):
|
|
587
|
+
found.append(
|
|
588
|
+
f"{remote_ref} <- {local_sha[:12]} carries unpublished {project} member work; "
|
|
589
|
+
f"{MEMBER_PUSH_HINT}"
|
|
590
|
+
)
|
|
591
|
+
return found
|
|
592
|
+
|
|
593
|
+
|
|
594
|
+
def pre_push_violations(lines):
|
|
595
|
+
"""Refuse ref updates that publish unshipped milestone work.
|
|
596
|
+
|
|
597
|
+
A bound-named ref moves only to, or away from, its strict ship commit. Any
|
|
598
|
+
other ref may not carry a commit whose STATE.md still owes a ship commit.
|
|
599
|
+
"""
|
|
600
|
+
found = []
|
|
601
|
+
for local_ref, local_sha, remote_ref, remote_sha in _push_updates(lines):
|
|
531
602
|
names = [ref.removeprefix("refs/heads/") for ref in (local_ref, remote_ref)]
|
|
532
603
|
bounds = {name for name in names if BOUND_BRANCH.fullmatch(name)}
|
|
533
604
|
if bounds:
|
|
@@ -574,7 +645,7 @@ def default_branch():
|
|
|
574
645
|
origin_head = subprocess.run(
|
|
575
646
|
["git", "symbolic-ref", "--quiet", "--short", "refs/remotes/origin/HEAD"],
|
|
576
647
|
capture_output=True,
|
|
577
|
-
|
|
648
|
+
encoding="utf-8", errors="replace",
|
|
578
649
|
check=False,
|
|
579
650
|
)
|
|
580
651
|
if origin_head.returncode == 0 and origin_head.stdout.strip().startswith("origin/"):
|
|
@@ -582,7 +653,7 @@ def default_branch():
|
|
|
582
653
|
configured = subprocess.run(
|
|
583
654
|
["git", "config", "--get", "init.defaultBranch"],
|
|
584
655
|
capture_output=True,
|
|
585
|
-
|
|
656
|
+
encoding="utf-8", errors="replace",
|
|
586
657
|
check=False,
|
|
587
658
|
)
|
|
588
659
|
if configured.returncode == 0 and configured.stdout.strip():
|
|
@@ -604,7 +675,7 @@ def is_integration_merge(subject):
|
|
|
604
675
|
merge_head = subprocess.run(
|
|
605
676
|
["git", "rev-parse", "--verify", "--quiet", "MERGE_HEAD^{commit}"],
|
|
606
677
|
capture_output=True,
|
|
607
|
-
|
|
678
|
+
encoding="utf-8", errors="replace",
|
|
608
679
|
check=False,
|
|
609
680
|
)
|
|
610
681
|
bound_head = subprocess.run(
|
|
@@ -616,7 +687,7 @@ def is_integration_merge(subject):
|
|
|
616
687
|
f"refs/heads/{match.group('branch')}^{{commit}}",
|
|
617
688
|
],
|
|
618
689
|
capture_output=True,
|
|
619
|
-
|
|
690
|
+
encoding="utf-8", errors="replace",
|
|
620
691
|
check=False,
|
|
621
692
|
)
|
|
622
693
|
return (
|
|
@@ -708,18 +779,34 @@ def report(found, action):
|
|
|
708
779
|
|
|
709
780
|
|
|
710
781
|
def main(argv):
|
|
782
|
+
# Git reads hook output as UTF-8; a Windows pipe would default to cp1252.
|
|
783
|
+
# In-process callers may substitute text streams.
|
|
784
|
+
for stream in (sys.stdout, sys.stderr):
|
|
785
|
+
if hasattr(stream, "reconfigure"):
|
|
786
|
+
stream.reconfigure(encoding="utf-8", errors="replace")
|
|
711
787
|
if len(argv) > 1 and argv[1] == "closed-milestone":
|
|
712
788
|
reason = closed_milestone_reason()
|
|
713
789
|
return report([reason] if reason else [], "mutation")
|
|
714
790
|
if len(argv) > 1 and argv[1] == "pre-push":
|
|
715
791
|
try:
|
|
716
|
-
|
|
792
|
+
stdin = getattr(sys.stdin, "buffer", None)
|
|
793
|
+
text = (stdin.read().decode("utf-8", errors="surrogateescape")
|
|
794
|
+
if stdin is not None else sys.stdin.read())
|
|
795
|
+
lines = text.splitlines()
|
|
796
|
+
role = members.member_role(repo_root())
|
|
797
|
+
found = member_pre_push_violations(lines, role) if role else pre_push_violations(lines)
|
|
717
798
|
except Exception as error:
|
|
718
799
|
print(f"gsd-path guard: inspection failed; push blocked ({error})", file=sys.stderr)
|
|
719
800
|
return 1
|
|
720
801
|
return report(found, "push")
|
|
721
802
|
try:
|
|
722
|
-
|
|
803
|
+
# A member follows its coordinator, so its own STATE does not gate commits.
|
|
804
|
+
role = members.member_role(repo_root())
|
|
805
|
+
member = role is not None
|
|
806
|
+
if member and current_branch().startswith(f"gsd-path/{role['project']}-"):
|
|
807
|
+
return report([f"direct commits on the member bound branch {current_branch()} are refused; "
|
|
808
|
+
"member tasks land there through Path"], "commit")
|
|
809
|
+
reason = None if member else closed_milestone_reason()
|
|
723
810
|
if reason:
|
|
724
811
|
return report([reason], "commit")
|
|
725
812
|
entries = staged_entries()
|
|
@@ -740,7 +827,7 @@ def main(argv):
|
|
|
740
827
|
)
|
|
741
828
|
if abandon is not None:
|
|
742
829
|
current_archive = abandon[0]
|
|
743
|
-
landing = product_commit_violations(entries, subject, body)
|
|
830
|
+
landing = [] if member else product_commit_violations(entries, subject, body)
|
|
744
831
|
except Exception as error:
|
|
745
832
|
print(
|
|
746
833
|
f"gsd-path guard: inspection failed; commit blocked ({error}); "
|