@danmoisan/drm-copilot-mcp 1.1.18 → 1.1.20
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/out/mcp-server.js +1149 -661
- package/package.json +3 -2
- package/resources/claude-customizations/.claude/agents/atomic-executor.md +28 -6
- package/resources/claude-customizations/.claude/agents/atomic-planner.md +20 -2
- package/resources/claude-customizations/.claude/agents/epic-orchestrator.md +17 -4
- package/resources/claude-customizations/.claude/agents/epic-planner.md +5 -4
- package/resources/claude-customizations/.claude/agents/feature-review.md +6 -4
- package/resources/claude-customizations/.claude/agents/orchestrator.md +9 -5
- package/resources/claude-customizations/.claude/agents/parallel-orchestrator.md +35 -13
- package/resources/claude-customizations/.claude/agents/parallel-planner.md +9 -6
- package/resources/claude-customizations/.claude/agents/pr-author.md +15 -2
- package/resources/claude-customizations/.claude/agents/prd-feature.md +1 -1
- package/resources/claude-customizations/.claude/agents/task-researcher.md +8 -0
- package/resources/claude-customizations/.claude/hooks/check-powershell-test-purity.ps1 +7 -1
- package/resources/claude-customizations/.claude/hooks/check-python-test-purity.ps1 +7 -1
- package/resources/claude-customizations/.claude/hooks/enforce-checkpoint-monotonic.ps1 +7 -1
- package/resources/claude-customizations/.claude/hooks/enforce-completion-consistency.ps1 +111 -46
- package/resources/claude-customizations/.claude/hooks/enforce-completion-helpers.ps1 +105 -0
- package/resources/claude-customizations/.claude/hooks/enforce-discovery-artifact-gate.ps1 +8 -1
- package/resources/claude-customizations/.claude/hooks/enforce-epic-invocation-origin.ps1 +7 -1
- package/resources/claude-customizations/.claude/hooks/enforce-epic-merge-gate-command.ps1 +190 -0
- package/resources/claude-customizations/.claude/hooks/enforce-epic-merge-gate-resolution.ps1 +116 -59
- package/resources/claude-customizations/.claude/hooks/enforce-epic-merge-gate.ps1 +78 -77
- package/resources/claude-customizations/.claude/hooks/enforce-epic-wave-barrier.ps1 +74 -75
- package/resources/claude-customizations/.claude/hooks/enforce-epic-worktree-removal-gate-resolution.ps1 +127 -35
- package/resources/claude-customizations/.claude/hooks/enforce-epic-worktree-removal-gate.ps1 +61 -57
- package/resources/claude-customizations/.claude/hooks/enforce-evidence-locations.ps1 +7 -1
- package/resources/claude-customizations/.claude/hooks/enforce-feature-folder-order.ps1 +129 -39
- package/resources/claude-customizations/.claude/hooks/enforce-mermaid-validation.ps1 +7 -1
- package/resources/claude-customizations/.claude/hooks/enforce-model-routing-receipt.ps1 +9 -3
- package/resources/claude-customizations/.claude/hooks/enforce-orchestration-preimplementation-gate-epic-scope.ps1 +39 -51
- package/resources/claude-customizations/.claude/hooks/enforce-orchestration-preimplementation-gate-helpers.ps1 +31 -58
- package/resources/claude-customizations/.claude/hooks/enforce-orchestration-preimplementation-gate-modes.ps1 +63 -47
- package/resources/claude-customizations/.claude/hooks/enforce-orchestration-preimplementation-gate-targets.ps1 +433 -0
- package/resources/claude-customizations/.claude/hooks/enforce-orchestration-preimplementation-gate.ps1 +17 -12
- package/resources/claude-customizations/.claude/hooks/enforce-parallel-abandon-gate.ps1 +9 -3
- package/resources/claude-customizations/.claude/hooks/enforce-parallel-cohort-barrier.ps1 +65 -50
- package/resources/claude-customizations/.claude/hooks/enforce-parallel-drift-gate.ps1 +49 -42
- package/resources/claude-customizations/.claude/hooks/enforce-parallel-worktree-removal-gate.ps1 +54 -72
- package/resources/claude-customizations/.claude/hooks/enforce-powershell-batch-budget.ps1 +8 -2
- package/resources/claude-customizations/.claude/hooks/enforce-pr-author-command-allowlist.ps1 +279 -0
- package/resources/claude-customizations/.claude/hooks/enforce-pr-author-skill-helpers.ps1 +129 -75
- package/resources/claude-customizations/.claude/hooks/enforce-pr-author-skill.artifact-root.ps1 +233 -0
- package/resources/claude-customizations/.claude/hooks/enforce-pr-author-skill.docs-only.ps1 +224 -0
- package/resources/claude-customizations/.claude/hooks/enforce-pr-author-skill.ps1 +69 -24
- package/resources/claude-customizations/.claude/hooks/enforce-prd-feature-before-planner-helpers.ps1 +29 -18
- package/resources/claude-customizations/.claude/hooks/enforce-prd-feature-before-planner.ps1 +10 -4
- package/resources/claude-customizations/.claude/hooks/enforce-promotion-mcp-only.ps1 +14 -5
- package/resources/claude-customizations/.claude/hooks/enforce-python-batch-budget.ps1 +8 -2
- package/resources/claude-customizations/.claude/hooks/feature-folder-resolution.ps1 +373 -0
- package/resources/claude-customizations/.claude/hooks/feature-review-coverage-thresholds.ps1 +85 -0
- package/resources/claude-customizations/.claude/hooks/hook-command-heredoc.ps1 +119 -0
- package/resources/claude-customizations/.claude/hooks/hook-command-invocation-operands.ps1 +198 -0
- package/resources/claude-customizations/.claude/hooks/hook-command-invocation.ps1 +254 -255
- package/resources/claude-customizations/.claude/hooks/hook-command-payload-powershell.ps1 +201 -0
- package/resources/claude-customizations/.claude/hooks/hook-command-payload.ps1 +484 -0
- package/resources/claude-customizations/.claude/hooks/hook-command-scanner.ps1 +27 -110
- package/resources/claude-customizations/.claude/hooks/hook-dependency-guard.ps1 +114 -0
- package/resources/claude-customizations/.claude/hooks/hook-docs-only-diff.ps1 +497 -0
- package/resources/claude-customizations/.claude/hooks/premortem-section.ps1 +149 -0
- package/resources/claude-customizations/.claude/hooks/subagentstop-envelope.ps1 +192 -0
- package/resources/claude-customizations/.claude/hooks/validate-bash.ps1 +9 -3
- package/resources/claude-customizations/.claude/hooks/validate-discovery-artifact-gate.ps1 +40 -42
- package/resources/claude-customizations/.claude/hooks/validate-executor-output.ps1 +267 -113
- package/resources/claude-customizations/.claude/hooks/validate-feature-review-coverage-metrics.ps1 +180 -0
- package/resources/claude-customizations/.claude/hooks/validate-feature-review-coverage-rules.ps1 +195 -0
- package/resources/claude-customizations/.claude/hooks/validate-feature-review-coverage.ps1 +141 -395
- package/resources/claude-customizations/.claude/hooks/validate-orchestrator-output-resolution.ps1 +311 -0
- package/resources/claude-customizations/.claude/hooks/validate-orchestrator-output-routing.ps1 +170 -0
- package/resources/claude-customizations/.claude/hooks/validate-orchestrator-output.ps1 +115 -190
- package/resources/claude-customizations/.claude/hooks/validate-planner-output.ps1 +77 -33
- package/resources/claude-customizations/.claude/hooks/validate-pr-author-output.ps1 +39 -44
- package/resources/claude-customizations/.claude/hooks/validate-prd-feature-output.ps1 +43 -14
- package/resources/claude-customizations/.claude/hooks/validate-required-artifact-output.ps1 +66 -36
- package/resources/claude-customizations/.claude/hooks/validate-task-researcher-output.ps1 +52 -36
- package/resources/claude-customizations/.claude/lib/bash/mutate-parallel-run.sh +191 -0
- package/resources/claude-customizations/.claude/lib/bash/parallel-cohorts.sh +13 -3
- package/resources/claude-customizations/.claude/lib/bash/parallel-mutation-cli.sh +152 -0
- package/resources/claude-customizations/.claude/lib/bash/parallel-mutation-ops.sh +193 -0
- package/resources/claude-customizations/.claude/lib/bash/parallel-mutation.sh +322 -0
- package/resources/claude-customizations/.claude/lib/bash/remove-parallel-item.sh +146 -0
- package/resources/claude-customizations/.claude/lib/blast-radius/BlastRadiusExtraction.psm1 +23 -33
- package/resources/claude-customizations/.claude/lib/blast-radius/BlastRadiusTokenShape.psm1 +86 -6
- package/resources/claude-customizations/.claude/lib/ci-gate/Invoke-CiGateParser.ps1 +91 -19
- package/resources/claude-customizations/.claude/lib/ci-gate/Invoke-MergeConfirmationParser.ps1 +203 -0
- package/resources/claude-customizations/.claude/lib/orchestrator-state/OrchestratorStateEpicWaveBarrier.psm1 +346 -0
- package/resources/claude-customizations/.claude/lib/orchestrator-state/OrchestratorStateIssueAdoption.psm1 +24 -3
- package/resources/claude-customizations/.claude/lib/worktree-resolution/WorktreeItemResolution.psm1 +79 -2
- package/resources/claude-customizations/.claude/lib/worktree-resolution/WorktreeRunResolution.psm1 +3 -3
- package/resources/claude-customizations/.claude/rules/architecture-boundaries.md +5 -5
- package/resources/claude-customizations/.claude/rules/csharp.md +2 -2
- package/resources/claude-customizations/.claude/rules/general-code-change.md +1 -1
- package/resources/claude-customizations/.claude/rules/general-unit-test.md +3 -2
- package/resources/claude-customizations/.claude/rules/orchestrator-state.md +37 -4
- package/resources/claude-customizations/.claude/rules/parallel-orchestration.md +50 -5
- package/resources/claude-customizations/.claude/rules/plan-acceptance-gates.md +85 -10
- package/resources/claude-customizations/.claude/rules/quality-tiers.md +11 -7
- package/resources/claude-customizations/.claude/rules/shell.md +10 -8
- package/resources/claude-customizations/.claude/rules/typescript.md +1 -1
- package/resources/claude-customizations/.claude/settings.json +3 -4
- package/resources/claude-customizations/.claude/skills/acceptance-criteria-tracking/SKILL.md +1 -1
- package/resources/claude-customizations/.claude/skills/atomic-plan-contract/SKILL.md +52 -16
- package/resources/claude-customizations/.claude/skills/cleanup-merged-worktrees/SKILL.md +7 -3
- package/resources/claude-customizations/.claude/skills/cleanup-merged-worktrees/scripts/cleanup_worktrees_detached_lib.sh +1 -1
- package/resources/claude-customizations/.claude/skills/cleanup-merged-worktrees/scripts/cleanup_worktrees_enumerate_lib.sh +2 -0
- package/resources/claude-customizations/.claude/skills/cleanup-merged-worktrees/scripts/cleanup_worktrees_scan_helper.sh +2 -0
- package/resources/claude-customizations/.claude/skills/csharp-change-budget-router/SKILL.md +2 -2
- package/resources/claude-customizations/.claude/skills/epic-orchestrate/SKILL.md +45 -9
- package/resources/claude-customizations/.claude/skills/epic-plan/SKILL.md +5 -3
- package/resources/claude-customizations/.claude/skills/evidence-and-timestamp-conventions/SKILL.md +10 -1
- package/resources/claude-customizations/.claude/skills/execution-environment/SKILL.md +134 -0
- package/resources/claude-customizations/.claude/skills/feature-promotion-lifecycle/SKILL.md +1 -1
- package/resources/claude-customizations/.claude/skills/feature-review-workflow/SKILL.md +4 -3
- package/resources/claude-customizations/.claude/skills/orchestrate/SKILL.md +36 -15
- package/resources/claude-customizations/.claude/skills/parallel-add/SKILL.md +52 -14
- package/resources/claude-customizations/.claude/skills/parallel-close/SKILL.md +22 -9
- package/resources/claude-customizations/.claude/skills/parallel-orchestrate/SKILL.md +108 -21
- package/resources/claude-customizations/.claude/skills/parallel-plan/SKILL.md +63 -7
- package/resources/claude-customizations/.claude/skills/parallel-remove/SKILL.md +35 -12
- package/resources/claude-customizations/.claude/skills/powershell-change-budget-router/SKILL.md +1 -1
- package/resources/claude-customizations/.claude/skills/pr-author/SKILL.md +3 -1
- package/resources/claude-customizations/.claude/skills/python-change-budget-router/SKILL.md +1 -1
- package/resources/claude-customizations/.claude/skills/quota-throttling/SKILL.md +1 -1
- package/resources/claude-customizations/.claude/skills/remediation-handoff-atomic-planner/SKILL.md +16 -8
- package/resources/claude-customizations/.claude/skills/research-issue/SKILL.md +6 -0
- package/resources/claude-customizations/pack-manifests/core.json +27 -0
- package/resources/codex-and-agents-customizations/.agents/skills/README.md +1 -0
- package/resources/codex-and-agents-customizations/.agents/skills/acceptance-criteria-tracking/SKILL.md +1 -1
- package/resources/codex-and-agents-customizations/.agents/skills/architecture-boundaries/SKILL.md +5 -5
- package/resources/codex-and-agents-customizations/.agents/skills/atomic-executor/SKILL.md +19 -7
- package/resources/codex-and-agents-customizations/.agents/skills/atomic-plan-contract/SKILL.md +43 -4
- package/resources/codex-and-agents-customizations/.agents/skills/atomic-planner/SKILL.md +18 -6
- package/resources/codex-and-agents-customizations/.agents/skills/csharp/SKILL.md +2 -2
- package/resources/codex-and-agents-customizations/.agents/skills/csharp-change-budget-router/SKILL.md +2 -2
- package/resources/codex-and-agents-customizations/.agents/skills/csharp-qa-gate/SKILL.md +2 -2
- package/resources/codex-and-agents-customizations/.agents/skills/epic-orchestrate/SKILL.md +16 -1
- package/resources/codex-and-agents-customizations/.agents/skills/epic-plan/SKILL.md +17 -1
- package/resources/codex-and-agents-customizations/.agents/skills/epic-run/SKILL.md +2 -1
- package/resources/codex-and-agents-customizations/.agents/skills/evidence-and-timestamp-conventions/SKILL.md +10 -1
- package/resources/codex-and-agents-customizations/.agents/skills/execution-environment/SKILL.md +134 -0
- package/resources/codex-and-agents-customizations/.agents/skills/feature-review-workflow/SKILL.md +13 -5
- package/resources/codex-and-agents-customizations/.agents/skills/general-code-change/SKILL.md +1 -1
- package/resources/codex-and-agents-customizations/.agents/skills/general-unit-test/SKILL.md +3 -2
- package/resources/codex-and-agents-customizations/.agents/skills/orchestrate/SKILL.md +27 -8
- package/resources/codex-and-agents-customizations/.agents/skills/orchestrator-workflow/SKILL.md +1 -1
- package/resources/codex-and-agents-customizations/.agents/skills/powershell-change-budget-router/SKILL.md +1 -1
- package/resources/codex-and-agents-customizations/.agents/skills/python-change-budget-router/SKILL.md +1 -1
- package/resources/codex-and-agents-customizations/.agents/skills/quality-tiers/SKILL.md +11 -7
- package/resources/codex-and-agents-customizations/.agents/skills/remediation-handoff-atomic-planner/SKILL.md +7 -3
- package/resources/codex-and-agents-customizations/.agents/skills/research-issue/SKILL.md +6 -0
- package/resources/codex-and-agents-customizations/.agents/skills/translate-claude-to-codex/SKILL.md +1 -1
- package/resources/codex-and-agents-customizations/.agents-variants/csharp-legacy/skills/csharp/SKILL.md +2 -2
- package/resources/codex-and-agents-customizations/.agents-variants/csharp-legacy/skills/csharp-qa-gate/SKILL.md +2 -2
- package/resources/codex-and-agents-customizations/.codex/agents/atomic-executor-c1.toml +21 -6
- package/resources/codex-and-agents-customizations/.codex/agents/atomic-executor-c2.toml +21 -6
- package/resources/codex-and-agents-customizations/.codex/agents/atomic-executor-c3-elevated.toml +21 -6
- package/resources/codex-and-agents-customizations/.codex/agents/atomic-executor-c3.toml +21 -6
- package/resources/codex-and-agents-customizations/.codex/agents/atomic-executor-c4.toml +21 -6
- package/resources/codex-and-agents-customizations/.codex/agents/atomic-executor.toml +21 -6
- package/resources/codex-and-agents-customizations/.codex/agents/atomic-planner-c1.toml +15 -2
- package/resources/codex-and-agents-customizations/.codex/agents/atomic-planner-c2.toml +15 -2
- package/resources/codex-and-agents-customizations/.codex/agents/atomic-planner-c3-elevated.toml +15 -2
- package/resources/codex-and-agents-customizations/.codex/agents/atomic-planner-c3.toml +15 -2
- package/resources/codex-and-agents-customizations/.codex/agents/atomic-planner-c4.toml +15 -2
- package/resources/codex-and-agents-customizations/.codex/agents/atomic-planner.toml +15 -2
- package/resources/codex-and-agents-customizations/.codex/agents/atomic-planning.toml +1 -1
- package/resources/codex-and-agents-customizations/.codex/agents/csharp-atomic-planning.toml +1 -1
- package/resources/codex-and-agents-customizations/.codex/agents/epic-orchestrator.toml +4 -1
- package/resources/codex-and-agents-customizations/.codex/agents/feature-review.toml +6 -6
- package/resources/codex-and-agents-customizations/.codex/agents/orchestrator-c1.toml +7 -4
- package/resources/codex-and-agents-customizations/.codex/agents/orchestrator-c2.toml +7 -4
- package/resources/codex-and-agents-customizations/.codex/agents/orchestrator-c3-elevated.toml +7 -4
- package/resources/codex-and-agents-customizations/.codex/agents/orchestrator-c3.toml +7 -4
- package/resources/codex-and-agents-customizations/.codex/agents/orchestrator-c4.toml +7 -4
- package/resources/codex-and-agents-customizations/.codex/agents/orchestrator.toml +7 -4
- package/resources/codex-and-agents-customizations/.codex/agents/powershell-atomic-planning.toml +1 -1
- package/resources/codex-and-agents-customizations/.codex/agents/python-atomic-planning.toml +1 -1
- package/resources/codex-and-agents-customizations/.codex/agents/task-researcher-c1.toml +6 -0
- package/resources/codex-and-agents-customizations/.codex/agents/task-researcher-c2.toml +6 -0
- package/resources/codex-and-agents-customizations/.codex/agents/task-researcher-c3-elevated.toml +6 -0
- package/resources/codex-and-agents-customizations/.codex/agents/task-researcher-c3.toml +6 -0
- package/resources/codex-and-agents-customizations/.codex/agents/task-researcher-c4.toml +6 -0
- package/resources/codex-and-agents-customizations/.codex/agents/task-researcher.toml +6 -0
- package/resources/codex-and-agents-customizations/.codex/codex-web-setup.sh +318 -273
- package/resources/codex-and-agents-customizations/.codex/config.toml +1 -1
- package/resources/codex-and-agents-customizations/.codex/hooks/check-powershell-test-purity.ps1 +7 -1
- package/resources/codex-and-agents-customizations/.codex/hooks/check-python-test-purity.ps1 +7 -1
- package/resources/codex-and-agents-customizations/.codex/hooks/codex-epic-child-launch-attestation.ps1 +1 -1
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-checkpoint-monotonic.ps1 +7 -1
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-codex-model-routing.ps1 +8 -2
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-completion-consistency.ps1 +97 -44
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-completion-helpers.ps1 +105 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-epic-child-worktree-binding.ps1 +7 -1
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-epic-merge-gate-command.ps1 +190 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-epic-merge-gate.ps1 +54 -43
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-epic-planning-only.ps1 +6 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-epic-root-invocation.ps1 +7 -1
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-epic-wave-barrier.ps1 +7 -1
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-epic-worktree-removal-gate.ps1 +54 -41
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-evidence-locations.ps1 +7 -1
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-orchestration-preimplementation-gate-epic-scope.ps1 +35 -14
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-orchestration-preimplementation-gate-helpers.ps1 +31 -58
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-orchestration-preimplementation-gate-modes.ps1 +63 -47
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-orchestration-preimplementation-gate-targets.ps1 +433 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-orchestration-preimplementation-gate.ps1 +24 -11
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-powershell-batch-budget.ps1 +8 -2
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-promotion-mcp-only.ps1 +13 -4
- package/resources/codex-and-agents-customizations/.codex/hooks/enforce-python-batch-budget.ps1 +8 -2
- package/resources/codex-and-agents-customizations/.codex/hooks/feature-folder-resolution.ps1 +373 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/feature-review-coverage-thresholds.ps1 +85 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/hook-command-heredoc.ps1 +119 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/hook-command-invocation-operands.ps1 +198 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/hook-command-invocation.ps1 +254 -255
- package/resources/codex-and-agents-customizations/.codex/hooks/hook-command-payload-powershell.ps1 +201 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/hook-command-payload.ps1 +484 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/hook-command-scanner.ps1 +27 -110
- package/resources/codex-and-agents-customizations/.codex/hooks/hook-dependency-guard.ps1 +114 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/hook-docs-only-diff.ps1 +497 -0
- package/resources/codex-and-agents-customizations/.codex/hooks/validate-bash.ps1 +8 -2
- package/resources/codex-and-agents-customizations/.codex/hooks/validate-codex-subagent-routing.ps1 +7 -1
- package/resources/codex-and-agents-customizations/.codex/hooks/validate-feature-review-coverage.ps1 +24 -8
- package/resources/codex-and-agents-customizations/.codex/prompts/feature-review-remediate.md +6 -4
- package/resources/codex-and-agents-customizations/pack-manifests/core.json +11 -0
- package/resources/customizations/.github/agents/atomic_executor.agent.md +21 -11
- package/resources/customizations/.github/agents/atomic_planning.agent.md +8 -3
- package/resources/customizations/.github/agents/csharp-atomic-executor.agent.md +13 -9
- package/resources/customizations/.github/agents/csharp-atomic-planning.agent.md +2 -2
- package/resources/customizations/.github/agents/csharp-orchestrator.agent.md +2 -2
- package/resources/customizations/.github/agents/csharp-typed-engineer.agent.md +5 -5
- package/resources/customizations/.github/agents/orchestrator.agent.md +8 -5
- package/resources/customizations/.github/agents/powershell-atomic-executor.agent.md +13 -9
- package/resources/customizations/.github/agents/powershell-atomic-planning.agent.md +2 -2
- package/resources/customizations/.github/agents/powershell-orchestrator.agent.md +2 -2
- package/resources/customizations/.github/agents/powershell-typed-engineer.agent.md +3 -3
- package/resources/customizations/.github/agents/python-atomic-executor.agent.md +13 -9
- package/resources/customizations/.github/agents/python-atomic-planning.agent.md +2 -2
- package/resources/customizations/.github/agents/python-orchestrator.agent.md +2 -2
- package/resources/customizations/.github/agents/task-researcher.agent.md +6 -0
- package/resources/customizations/.github/instructions/csharp-code-change.instructions.md +4 -4
- package/resources/customizations/.github/instructions/csharp-unit-test.instructions.md +2 -2
- package/resources/customizations/.github/prompts/generate-atomic-plan.prompt.md +16 -10
- package/resources/customizations/.github/prompts/orchestrate-csharp-work.prompt.md +2 -2
- package/resources/customizations/.github/prompts/orchestrate-powershell-work.prompt.md +1 -1
- package/resources/customizations/.github/prompts/orchestrate-python-work.prompt.md +1 -1
- package/resources/customizations/.github/prompts/orchestrate-work.prompt.md +2 -2
- package/resources/customizations/.github/skills/acceptance-criteria-tracking/SKILL.md +1 -1
- package/resources/customizations/.github/skills/atomic-plan-contract/SKILL.md +43 -4
- package/resources/customizations/.github/skills/csharp-change-budget-router/SKILL.md +1 -1
- package/resources/customizations/.github/skills/evidence-and-timestamp-conventions/SKILL.md +10 -1
- package/resources/customizations/.github/skills/execution-environment/SKILL.md +134 -0
- package/resources/customizations/.github/skills/feature-review-workflow/SKILL.md +1 -1
- package/resources/customizations/.github/skills/powershell-change-budget-router/SKILL.md +1 -1
- package/resources/customizations/.github/skills/remediation-handoff-atomic-planner/SKILL.md +7 -3
- package/resources/feature-templates/bug/plan.yyyy-MM-ddTHH-mm.md +10 -0
- package/resources/feature-templates/feature/plan.yyyy-MM-ddTHH-mm.md +11 -0
- package/resources/feature-templates/refactor/plan.yyyy-MM-ddTHH-mm.md +11 -0
- package/resources/powershell/PoshQC/PoshQC.Coverage.psm1 +314 -0
- package/resources/powershell/PoshQC/PoshQC.CoverageMerge.psm1 +163 -0
- package/resources/powershell/PoshQC/PoshQC.Shard.psm1 +296 -0
- package/resources/powershell/PoshQC/PoshQC.Testing.psm1 +48 -32
- package/resources/powershell/PoshQC/PoshQC.psd1 +7 -1
- package/resources/powershell/PoshQC/PoshQC.psm1 +18 -5
- package/resources/powershell/PoshQC/README.md +21 -3
- package/resources/powershell/PoshQC/settings/pester.runsettings.psd1 +5 -319
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
<#
|
|
2
|
+
.SYNOPSIS
|
|
3
|
+
Docs-only exemption from the checkpoint preflight of enforce-pr-author-skill.ps1 (issue #901).
|
|
4
|
+
|
|
5
|
+
.DESCRIPTION
|
|
6
|
+
Dot-sourced by enforce-pr-author-skill-helpers.ps1. Get-PrAuthorBypassReason calls
|
|
7
|
+
Get-PrAuthorDocsOnlyExemption only in its non-epic branch and only after
|
|
8
|
+
Invoke-OrchestratorStatePreflight reports errors. The exemption lets a gh pr create call
|
|
9
|
+
continue to the receipt checks when the branch changes nothing outside docs/. It fails
|
|
10
|
+
closed: every condition below must hold, and the first that does not names the sub-code
|
|
11
|
+
the caller appends to its ORCHESTRATOR_STATE_PREFLIGHT_FAILED denial.
|
|
12
|
+
|
|
13
|
+
E1 DOCS_ONLY_EXEMPTION_NOT_CREATE - the command is a structural gh pr create.
|
|
14
|
+
E2 DOCS_ONLY_EXEMPTION_CHECKPOINT_PRESENT - no checkpoint file exists at the resolved path.
|
|
15
|
+
E3 DOCS_ONLY_EXEMPTION_BASE_UNRESOLVED - exactly one explicit --base, a conservative branch
|
|
16
|
+
spelling without '..', and no base or repository
|
|
17
|
+
override: no single-dash token whose letters
|
|
18
|
+
include B or R (-B, -R, -dB, -Rx), no --repo or
|
|
19
|
+
--repo= token, and no inline GH_REPO= prefix.
|
|
20
|
+
E4 DOCS_ONLY_EXEMPTION_BASE_UNRESOLVED - refs/remotes/origin/<base> resolves to a commit.
|
|
21
|
+
E5 DOCS_ONLY_EXEMPTION_DIFF_FAILED - git diff <commit>...HEAD exits 0 without throwing,
|
|
22
|
+
and non-empty output ends with NUL.
|
|
23
|
+
E6 DOCS_ONLY_EXEMPTION_EMPTY_DIFF - the diff lists at least one path.
|
|
24
|
+
E7 DOCS_ONLY_EXEMPTION_NON_DOCS_PATH - every path starts with docs/ (ordinal).
|
|
25
|
+
|
|
26
|
+
The diff runs with --no-renames so a rename from outside docs/ reports its old path, with -z
|
|
27
|
+
so no path is quoted, and with --no-relative, --no-color, and --no-ext-diff so repository
|
|
28
|
+
configuration cannot change the listing.
|
|
29
|
+
|
|
30
|
+
Residual limit: a GH_REPO value exported by an earlier shell command or inherited from the
|
|
31
|
+
session environment is not visible in the command text, so this file cannot detect it.
|
|
32
|
+
|
|
33
|
+
.NOTES
|
|
34
|
+
PowerShell 7+. Depends, at call time, on Test-CommandLineInvocation,
|
|
35
|
+
Get-CommandLineStructuralMatch, and Get-CommandLineFlagValue from the command parsers the
|
|
36
|
+
helpers file loads. It reads no file content. The git executable runs only through
|
|
37
|
+
Invoke-PrAuthorDocsOnlyGitExe, the single executable seam, which never throws. Mirrored
|
|
38
|
+
byte-identically under extensions/drm-copilot/resources/claude-customizations/.
|
|
39
|
+
Dot-sources hook-docs-only-diff.ps1 (issue #927), whose Get-DocsOnlyDiffTextViolation
|
|
40
|
+
performs the E5 NUL check and the E6 and E7 path classification.
|
|
41
|
+
#>
|
|
42
|
+
[CmdletBinding()]
|
|
43
|
+
param()
|
|
44
|
+
. (Join-Path $PSScriptRoot 'hook-docs-only-diff.ps1')
|
|
45
|
+
|
|
46
|
+
function Invoke-PrAuthorDocsOnlyGitExe {
|
|
47
|
+
<#
|
|
48
|
+
.SYNOPSIS
|
|
49
|
+
Run git -C <root> with the given arguments. The single executable seam; tests mock it.
|
|
50
|
+
.DESCRIPTION
|
|
51
|
+
Never throws: an uncaught error ends the hook with exit 1, which PreToolUse treats as
|
|
52
|
+
non-blocking, so a throw here would allow the call. A root that is not an existing
|
|
53
|
+
directory, or a git that cannot start, returns ExitCode -1. Standard error is discarded
|
|
54
|
+
so that it is never read as path data.
|
|
55
|
+
.PARAMETER WorktreeRoot
|
|
56
|
+
The resolved worktree root git runs in.
|
|
57
|
+
.PARAMETER GitArgs
|
|
58
|
+
The git arguments that follow -C <root>.
|
|
59
|
+
.PARAMETER GitInvoker
|
|
60
|
+
The scriptblock that runs git; a unit test passes a test-local stand-in so that this
|
|
61
|
+
body runs without starting a process.
|
|
62
|
+
.OUTPUTS
|
|
63
|
+
System.Management.Automation.PSCustomObject with ExitCode and Output.
|
|
64
|
+
#>
|
|
65
|
+
[CmdletBinding()]
|
|
66
|
+
[OutputType([pscustomobject])]
|
|
67
|
+
param(
|
|
68
|
+
[AllowNull()][AllowEmptyString()][string] $WorktreeRoot,
|
|
69
|
+
[Parameter(Mandatory)][string[]] $GitArgs,
|
|
70
|
+
[ValidateNotNull()][scriptblock] $GitInvoker = { git @args 2>$null }
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
$failure = [pscustomobject]@{ ExitCode = -1; Output = '' }
|
|
74
|
+
if ([string]::IsNullOrWhiteSpace($WorktreeRoot) -or -not (Test-Path -LiteralPath $WorktreeRoot -PathType Container)) {
|
|
75
|
+
return $failure
|
|
76
|
+
}
|
|
77
|
+
try {
|
|
78
|
+
$lines = @(& $GitInvoker -C $WorktreeRoot @GitArgs 2>$null)
|
|
79
|
+
$code = $LASTEXITCODE
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
return $failure
|
|
83
|
+
}
|
|
84
|
+
return [pscustomobject]@{ ExitCode = [int]$code; Output = ($lines -join "`n") }
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function Test-PrAuthorDocsOnlyCheckpointPresence {
|
|
88
|
+
<#
|
|
89
|
+
.SYNOPSIS
|
|
90
|
+
Return $true when a checkpoint file exists at the path, and also for a blank path.
|
|
91
|
+
.DESCRIPTION
|
|
92
|
+
A blank path cannot prove that no checkpoint exists, so it reports presence (fail closed).
|
|
93
|
+
.PARAMETER CheckpointPath
|
|
94
|
+
The absolute checkpoint path identity resolution composed.
|
|
95
|
+
.OUTPUTS
|
|
96
|
+
System.Boolean
|
|
97
|
+
#>
|
|
98
|
+
[CmdletBinding()]
|
|
99
|
+
[OutputType([bool])]
|
|
100
|
+
param(
|
|
101
|
+
[AllowNull()][AllowEmptyString()][string] $CheckpointPath
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
if ([string]::IsNullOrWhiteSpace($CheckpointPath)) {
|
|
105
|
+
return $true
|
|
106
|
+
}
|
|
107
|
+
return (Test-Path -LiteralPath $CheckpointPath -PathType Leaf)
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function Get-PrAuthorDocsOnlyBaseName {
|
|
111
|
+
<#
|
|
112
|
+
.SYNOPSIS
|
|
113
|
+
Return the single explicit --base value of a gh pr create command, or $null.
|
|
114
|
+
.DESCRIPTION
|
|
115
|
+
Returns $null when the command is not a structural gh pr create; when a single-dash
|
|
116
|
+
token has B or R among its letters (-B base and -R repository, alone or clustered as in
|
|
117
|
+
-dB or -dR); when a token is --repo, starts with --repo=, or starts with GH_REPO=; when
|
|
118
|
+
--base appears other than exactly once; when its value is missing or dash-leading; when
|
|
119
|
+
the value is not a conservative branch spelling; or when it contains '..'.
|
|
120
|
+
.PARAMETER CommandText
|
|
121
|
+
The Bash command text under evaluation.
|
|
122
|
+
.OUTPUTS
|
|
123
|
+
System.String or $null
|
|
124
|
+
#>
|
|
125
|
+
[CmdletBinding()]
|
|
126
|
+
[OutputType([string])]
|
|
127
|
+
param(
|
|
128
|
+
[Parameter(Mandatory)][AllowEmptyString()][string] $CommandText
|
|
129
|
+
)
|
|
130
|
+
|
|
131
|
+
$subcommandPath = @('pr', 'create')
|
|
132
|
+
$match = Get-CommandLineStructuralMatch -CommandText $CommandText -CommandWord 'gh' -SubcommandPath $subcommandPath
|
|
133
|
+
if ($null -eq $match) {
|
|
134
|
+
return $null
|
|
135
|
+
}
|
|
136
|
+
$baseTokenCount = 0
|
|
137
|
+
foreach ($token in @($match.Segment.Tokens)) {
|
|
138
|
+
$text = [string]$token
|
|
139
|
+
if ($text.Length -ge 2 -and $text[0] -eq '-' -and $text[1] -ne '-' -and $text.Substring(1).IndexOfAny([char[]]@('B', 'R')) -ge 0) {
|
|
140
|
+
return $null
|
|
141
|
+
}
|
|
142
|
+
if ($text -eq '--repo' -or $text.StartsWith('--repo=', [System.StringComparison]::OrdinalIgnoreCase) -or $text.StartsWith('GH_REPO=', [System.StringComparison]::OrdinalIgnoreCase)) {
|
|
143
|
+
return $null
|
|
144
|
+
}
|
|
145
|
+
if ($text -eq '--base' -or $text.StartsWith('--base=', [System.StringComparison]::OrdinalIgnoreCase)) {
|
|
146
|
+
$baseTokenCount++
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
if ($baseTokenCount -ne 1) {
|
|
150
|
+
return $null
|
|
151
|
+
}
|
|
152
|
+
$base = Get-CommandLineFlagValue -CommandText $CommandText -CommandWord 'gh' -SubcommandPath $subcommandPath -FlagName '--base'
|
|
153
|
+
if ($null -eq $base -or $base -cnotmatch '^[A-Za-z0-9][A-Za-z0-9._/-]*$' -or $base.Contains('..')) {
|
|
154
|
+
return $null
|
|
155
|
+
}
|
|
156
|
+
return $base
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
function Get-PrAuthorDocsOnlyExemption {
|
|
160
|
+
<#
|
|
161
|
+
.SYNOPSIS
|
|
162
|
+
Decide whether a failed preflight is exempt because the branch changes only docs/.
|
|
163
|
+
.DESCRIPTION
|
|
164
|
+
Evaluates E1 to E7 of the file header in order and returns at the first failure.
|
|
165
|
+
Each git call is wrapped so that a throwing seam denies rather than escapes.
|
|
166
|
+
.PARAMETER CommandText
|
|
167
|
+
The Bash command text under evaluation.
|
|
168
|
+
.PARAMETER WorktreeRoot
|
|
169
|
+
The resolved worktree root the diff is computed in.
|
|
170
|
+
.PARAMETER CheckpointPath
|
|
171
|
+
The resolved checkpoint path whose absence E2 requires.
|
|
172
|
+
.OUTPUTS
|
|
173
|
+
System.Collections.Specialized.OrderedDictionary with Exempt and Reason.
|
|
174
|
+
#>
|
|
175
|
+
[CmdletBinding()]
|
|
176
|
+
[OutputType([System.Collections.Specialized.OrderedDictionary])]
|
|
177
|
+
param(
|
|
178
|
+
[Parameter(Mandatory)][string] $CommandText,
|
|
179
|
+
[AllowNull()][AllowEmptyString()][string] $WorktreeRoot,
|
|
180
|
+
[AllowNull()][AllowEmptyString()][string] $CheckpointPath
|
|
181
|
+
)
|
|
182
|
+
|
|
183
|
+
if (-not (Test-CommandLineInvocation -CommandText $CommandText -CommandWord 'gh' -SubcommandPath @('pr', 'create'))) {
|
|
184
|
+
return [ordered]@{ Exempt = $false; Reason = 'DOCS_ONLY_EXEMPTION_NOT_CREATE: only gh pr create is eligible.' }
|
|
185
|
+
}
|
|
186
|
+
if (Test-PrAuthorDocsOnlyCheckpointPresence -CheckpointPath $CheckpointPath) {
|
|
187
|
+
return [ordered]@{ Exempt = $false; Reason = "DOCS_ONLY_EXEMPTION_CHECKPOINT_PRESENT: a checkpoint file exists at '$CheckpointPath', so its preflight governs." }
|
|
188
|
+
}
|
|
189
|
+
$base = Get-PrAuthorDocsOnlyBaseName -CommandText $CommandText
|
|
190
|
+
if ($null -eq $base) {
|
|
191
|
+
return [ordered]@{ Exempt = $false; Reason = 'DOCS_ONLY_EXEMPTION_BASE_UNRESOLVED: pass exactly one explicit --base <branch>; -B, -R, --repo, a single-dash shorthand cluster containing B or R, and an inline GH_REPO= prefix are not accepted.' }
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
$baseRef = 'refs/remotes/origin/' + $base + '^{commit}'
|
|
195
|
+
try {
|
|
196
|
+
$revParse = Invoke-PrAuthorDocsOnlyGitExe -WorktreeRoot $WorktreeRoot -GitArgs @('rev-parse', '--verify', '--quiet', $baseRef)
|
|
197
|
+
}
|
|
198
|
+
catch {
|
|
199
|
+
$revParse = $null
|
|
200
|
+
}
|
|
201
|
+
$commit = ''
|
|
202
|
+
if ($null -ne $revParse) {
|
|
203
|
+
$commit = ([string]$revParse.Output).Trim()
|
|
204
|
+
}
|
|
205
|
+
if ($null -eq $revParse -or $revParse.ExitCode -ne 0 -or $commit -cnotmatch '^[0-9a-f]{40}([0-9a-f]{24})?$') {
|
|
206
|
+
return [ordered]@{ Exempt = $false; Reason = "DOCS_ONLY_EXEMPTION_BASE_UNRESOLVED: refs/remotes/origin/$base does not resolve to a commit in the target worktree." }
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
try {
|
|
210
|
+
$diff = Invoke-PrAuthorDocsOnlyGitExe -WorktreeRoot $WorktreeRoot -GitArgs @('diff', '--name-only', '-z', '--no-renames', '--no-color', '--no-ext-diff', '--no-relative', ($commit + '...HEAD'))
|
|
211
|
+
}
|
|
212
|
+
catch {
|
|
213
|
+
$diff = $null
|
|
214
|
+
}
|
|
215
|
+
if ($null -eq $diff -or $diff.ExitCode -ne 0) {
|
|
216
|
+
return [ordered]@{ Exempt = $false; Reason = "DOCS_ONLY_EXEMPTION_DIFF_FAILED: git diff against origin/$base could not be computed." }
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
$violation = Get-DocsOnlyDiffTextViolation -DiffText ([string]$diff.Output) -BaseName $base
|
|
220
|
+
if ($violation) {
|
|
221
|
+
return [ordered]@{ Exempt = $false; Reason = $violation }
|
|
222
|
+
}
|
|
223
|
+
return [ordered]@{ Exempt = $true; Reason = $null }
|
|
224
|
+
}
|
|
@@ -19,18 +19,49 @@
|
|
|
19
19
|
Block cases:
|
|
20
20
|
Case A - gh pr create or gh pr edit with --body (inline, no --body-file): blocked.
|
|
21
21
|
Case B - gh pr create with neither --body nor --body-file: blocked.
|
|
22
|
-
Case C - gh pr create or gh pr edit with --body-file but context artifact absent
|
|
22
|
+
Case C - gh pr create or gh pr edit with --body-file but context artifact absent beneath
|
|
23
|
+
the resolved worktree: blocked.
|
|
23
24
|
Preflight - --body-file/context present: orchestrator-state checkpoint must pass
|
|
24
25
|
--require-pr-creation-ready before receipt verification runs, else blocked.
|
|
25
|
-
|
|
26
|
-
|
|
26
|
+
Docs-only - issue #901: when the preflight fails, gh pr create proceeds to receipt
|
|
27
|
+
verification only when every condition holds: no checkpoint file exists
|
|
28
|
+
beneath the resolved worktree; the command carries exactly one explicit
|
|
29
|
+
--base <branch> and no base or repository override (issue #927: no
|
|
30
|
+
single-dash token whose letters include B or R, such as -B, -R, or -dB; no
|
|
31
|
+
--repo or --repo= token; no inline GH_REPO= prefix); refs/remotes/origin/<branch>
|
|
32
|
+
resolves to a commit; git diff --name-only -z --no-renames <commit>...HEAD
|
|
33
|
+
exits 0, ends its non-empty output with NUL, and lists at least one path; and
|
|
34
|
+
every listed path starts with docs/ (ordinal, case-sensitive). Otherwise the
|
|
35
|
+
deny keeps ORCHESTRATOR_STATE_PREFLIGHT_FAILED and appends one sub-code:
|
|
36
|
+
DOCS_ONLY_EXEMPTION_NOT_CREATE - gh pr edit is never exempt.
|
|
37
|
+
DOCS_ONLY_EXEMPTION_CHECKPOINT_PRESENT - a checkpoint file exists.
|
|
38
|
+
DOCS_ONLY_EXEMPTION_BASE_UNRESOLVED - no single explicit --base, a base or
|
|
39
|
+
repository override is present, or
|
|
40
|
+
the base does not resolve on origin.
|
|
41
|
+
DOCS_ONLY_EXEMPTION_DIFF_FAILED - the diff exits non-zero, throws, or
|
|
42
|
+
returns output not ending with NUL.
|
|
43
|
+
DOCS_ONLY_EXEMPTION_EMPTY_DIFF - the diff lists no path.
|
|
44
|
+
DOCS_ONLY_EXEMPTION_NON_DOCS_PATH - a listed path is outside docs/.
|
|
45
|
+
The exemption never applies under epic scope.
|
|
46
|
+
Receipt - preflight passed or docs-only exemption applied: the SHA-256 receipt is
|
|
47
|
+
verified in the ordered checks (Section below). The first failing check blocks.
|
|
27
48
|
|
|
28
49
|
Receipt verification decision order on the --body-file-with-context path:
|
|
29
50
|
PR_BODY_PATH_NONCANONICAL -> PR_AUTHOR_RECEIPT_MISSING -> PR_AUTHOR_RECEIPT_NUMBER_MISMATCH
|
|
30
51
|
-> PR_AUTHOR_RECEIPT_HASH_MISMATCH -> PR_AUTHOR_RECEIPT_STALE -> allow.
|
|
31
52
|
|
|
53
|
+
Issue #850: the context summary, the body, and the receipt are read beneath the worktree
|
|
54
|
+
the call resolves to (the item worktree, or the epic checkpoint's worktree under epic
|
|
55
|
+
scope), not beneath the process directory, so a gate running in the session worktree
|
|
56
|
+
validates the artifacts of the item it gates.
|
|
57
|
+
|
|
32
58
|
.NOTES
|
|
33
|
-
Compatible with PowerShell 7+.
|
|
59
|
+
Compatible with PowerShell 7+. Dependencies are in-repository only: hook-dependency-guard.ps1,
|
|
60
|
+
the HookPayload, OrchestratorState, and OrchestratorStateUnconditional modules, and the
|
|
61
|
+
epic-base-branch and helpers siblings; the helpers load the command parsers, the
|
|
62
|
+
worktree-resolution modules, and the artifact-root and docs-only siblings.
|
|
63
|
+
No PowerShell Gallery module is required.
|
|
64
|
+
The docs-only exemption runs the git executable at call time (issue #901).
|
|
34
65
|
|
|
35
66
|
Enforcement strength: the SHA-256 receipt is a policy-level integrity check that binds the
|
|
36
67
|
PR body bytes to the receipt the pr-author agent wrote. It is not a cryptographic or security
|
|
@@ -42,28 +73,34 @@
|
|
|
42
73
|
#>
|
|
43
74
|
[CmdletBinding()]
|
|
44
75
|
param()
|
|
76
|
+
$script:HookDependencyGuardLoadFailed = $false; try { . (Join-Path $PSScriptRoot 'hook-dependency-guard.ps1') } catch { $script:HookDependencyGuardLoadFailed = $true }
|
|
45
77
|
|
|
46
78
|
|
|
47
|
-
Import-Module (Join-Path $PSScriptRoot '../lib/hook-payload/HookPayload.psm1') -Force
|
|
79
|
+
try { Import-Module (Join-Path $PSScriptRoot '../lib/hook-payload/HookPayload.psm1') -Force -ErrorAction Stop } catch { Add-HookDependencyFailure -Name 'HookPayload.psm1' -ErrorRecord $_ }
|
|
48
80
|
$script:PrContextArtifactPath = 'artifacts/pr_context.summary.txt'
|
|
49
81
|
# Null until the resolution step assigns the absolute path of the resolved worktree's
|
|
50
82
|
# checkpoint (issue #673); a relative default here was the process-directory binding.
|
|
51
83
|
$script:OrchestratorStateCheckpointPath = $null
|
|
52
84
|
|
|
53
|
-
Import-Module (Join-Path $PSScriptRoot '../lib/orchestrator-state/OrchestratorState.psm1') -Force
|
|
85
|
+
try { Import-Module (Join-Path $PSScriptRoot '../lib/orchestrator-state/OrchestratorState.psm1') -Force -ErrorAction Stop } catch { Add-HookDependencyFailure -Name 'OrchestratorState.psm1' -ErrorRecord $_ }
|
|
54
86
|
|
|
55
87
|
function Get-PrContextArtifactExistence {
|
|
56
88
|
<#
|
|
57
89
|
.SYNOPSIS
|
|
58
90
|
Wrapper around Test-Path for the PR context artifact. Tests mock this function.
|
|
91
|
+
.PARAMETER Path
|
|
92
|
+
The absolute path of artifacts/pr_context.summary.txt beneath the resolved worktree.
|
|
59
93
|
.OUTPUTS
|
|
60
94
|
System.Boolean
|
|
61
95
|
#>
|
|
62
96
|
[CmdletBinding()]
|
|
63
97
|
[OutputType([bool])]
|
|
64
|
-
param(
|
|
98
|
+
param(
|
|
99
|
+
[Parameter(Mandatory)]
|
|
100
|
+
[string] $Path
|
|
101
|
+
)
|
|
65
102
|
|
|
66
|
-
return [bool](Test-Path -LiteralPath $
|
|
103
|
+
return [bool](Test-Path -LiteralPath $Path)
|
|
67
104
|
}
|
|
68
105
|
|
|
69
106
|
function Get-PrBodyFileBytes {
|
|
@@ -75,7 +112,8 @@ function Get-PrBodyFileBytes {
|
|
|
75
112
|
This is the injectable boundary for body-file bytes in tests; no test writes the body file
|
|
76
113
|
to disk. The bytes are hashed inline by the receipt verification function.
|
|
77
114
|
.PARAMETER BodyFilePath
|
|
78
|
-
The
|
|
115
|
+
The absolute path to the PR body file beneath the resolved worktree (for example
|
|
116
|
+
<worktree>/artifacts/pr_body_5.md).
|
|
79
117
|
.OUTPUTS
|
|
80
118
|
System.Byte[] or $null
|
|
81
119
|
#>
|
|
@@ -103,7 +141,8 @@ function Get-PrAuthorReceiptContent {
|
|
|
103
141
|
or $null when the receipt file is absent. This is the injectable boundary for receipt
|
|
104
142
|
content in tests; no test writes the receipt file to disk.
|
|
105
143
|
.PARAMETER ReceiptFilePath
|
|
106
|
-
The
|
|
144
|
+
The absolute path to the receipt file beneath the resolved worktree (for example
|
|
145
|
+
<worktree>/artifacts/pr_body_5.receipt.json).
|
|
107
146
|
.OUTPUTS
|
|
108
147
|
System.String or $null
|
|
109
148
|
#>
|
|
@@ -129,25 +168,32 @@ function Get-PrContextSummaryLastWriteUtc {
|
|
|
129
168
|
Returns the LastWriteTimeUtc of artifacts/pr_context.summary.txt, or $null when the file is
|
|
130
169
|
absent. The staleness check compares the receipt's created_at against this value; both are
|
|
131
170
|
artifact metadata, so no wall-clock seam is required.
|
|
171
|
+
.PARAMETER Path
|
|
172
|
+
The absolute path of artifacts/pr_context.summary.txt beneath the resolved worktree.
|
|
132
173
|
.OUTPUTS
|
|
133
174
|
System.DateTime or $null
|
|
134
175
|
#>
|
|
135
176
|
[CmdletBinding()]
|
|
136
177
|
[OutputType([datetime])]
|
|
137
|
-
param(
|
|
178
|
+
param(
|
|
179
|
+
[Parameter(Mandatory)]
|
|
180
|
+
[string] $Path
|
|
181
|
+
)
|
|
138
182
|
|
|
139
|
-
if (-not (Test-Path -LiteralPath $
|
|
183
|
+
if (-not (Test-Path -LiteralPath $Path)) {
|
|
140
184
|
return $null
|
|
141
185
|
}
|
|
142
186
|
|
|
143
|
-
return (Get-Item -LiteralPath $
|
|
187
|
+
return (Get-Item -LiteralPath $Path).LastWriteTimeUtc
|
|
144
188
|
}
|
|
145
189
|
|
|
146
|
-
. (Join-Path $PSScriptRoot 'enforce-pr-author-skill.epic-base-branch.ps1')
|
|
190
|
+
try { . (Join-Path $PSScriptRoot 'enforce-pr-author-skill.epic-base-branch.ps1') } catch { Add-HookDependencyFailure -Name 'enforce-pr-author-skill.epic-base-branch.ps1' -ErrorRecord $_ }
|
|
147
191
|
|
|
148
192
|
# Dot-source the receipt-verification and bypass-reason helpers. Guarded so dot-sourcing this
|
|
149
193
|
# hook in tests loads the helpers too (issue #501 headroom split).
|
|
150
|
-
. (Join-Path $PSScriptRoot 'enforce-pr-author-skill-helpers.ps1')
|
|
194
|
+
try { . (Join-Path $PSScriptRoot 'enforce-pr-author-skill-helpers.ps1') } catch { Add-HookDependencyFailure -Name 'enforce-pr-author-skill-helpers.ps1' -ErrorRecord $_ }
|
|
195
|
+
try { Import-Module (Join-Path $PSScriptRoot '../lib/orchestrator-state/OrchestratorStateUnconditional.psm1') -Force -Global -ErrorAction Stop } catch { Add-HookDependencyFailure -Name 'OrchestratorStateUnconditional.psm1' -ErrorRecord $_ }
|
|
196
|
+
try { Import-Module (Join-Path $PSScriptRoot '../lib/orchestrator-state/OrchestratorState.psm1') -Force -Global -ErrorAction Stop } catch { Add-HookDependencyFailure -Name 'OrchestratorState.psm1' -ErrorRecord $_ }
|
|
151
197
|
|
|
152
198
|
function Invoke-PrAuthorSkillDecision {
|
|
153
199
|
<#
|
|
@@ -168,6 +214,8 @@ function Invoke-PrAuthorSkillDecision {
|
|
|
168
214
|
[AllowEmptyString()]
|
|
169
215
|
[string] $ToolInputRaw
|
|
170
216
|
)
|
|
217
|
+
$dependencyDecision = Get-HookDependencyFailureDecision -HookEvent PreToolUse -ReasonPrefix 'PR_AUTHOR_SKILL_BLOCKED:'
|
|
218
|
+
if ($null -ne $dependencyDecision) { return $dependencyDecision }
|
|
171
219
|
|
|
172
220
|
$payload = Resolve-ClaudeHookToolInput -Raw $ToolInputRaw
|
|
173
221
|
if (-not $payload.IsValid) {
|
|
@@ -182,8 +230,7 @@ function Invoke-PrAuthorSkillDecision {
|
|
|
182
230
|
return Get-PrAuthorSkillAllowDecision
|
|
183
231
|
}
|
|
184
232
|
|
|
185
|
-
$
|
|
186
|
-
$reason = Get-PrAuthorBypassReason -CommandText $commandText -ContextExists $contextExists
|
|
233
|
+
$reason = Get-PrAuthorBypassReason -CommandText $commandText
|
|
187
234
|
|
|
188
235
|
if ($reason) {
|
|
189
236
|
return Get-PrAuthorSkillBlockDecision -Reason $reason
|
|
@@ -242,8 +289,6 @@ function Test-PrAuthorBypassRequired {
|
|
|
242
289
|
Return $true when a Bash command requires the pr-author skill to run first.
|
|
243
290
|
.PARAMETER CommandText
|
|
244
291
|
The Bash command text extracted from the envelope's tool_input.
|
|
245
|
-
.PARAMETER ContextExists
|
|
246
|
-
Whether artifacts/pr_context.summary.txt currently exists on disk.
|
|
247
292
|
.OUTPUTS
|
|
248
293
|
System.Boolean
|
|
249
294
|
#>
|
|
@@ -251,13 +296,10 @@ function Test-PrAuthorBypassRequired {
|
|
|
251
296
|
[OutputType([bool])]
|
|
252
297
|
param(
|
|
253
298
|
[Parameter(Mandatory)]
|
|
254
|
-
[string] $CommandText
|
|
255
|
-
|
|
256
|
-
[Parameter(Mandatory)]
|
|
257
|
-
[bool] $ContextExists
|
|
299
|
+
[string] $CommandText
|
|
258
300
|
)
|
|
259
301
|
|
|
260
|
-
return ($null -ne (Get-PrAuthorBypassReason -CommandText $CommandText
|
|
302
|
+
return ($null -ne (Get-PrAuthorBypassReason -CommandText $CommandText))
|
|
261
303
|
}
|
|
262
304
|
|
|
263
305
|
function Invoke-PrAuthorSkillEntryPoint {
|
|
@@ -302,6 +344,9 @@ function Invoke-PrAuthorSkillEntryPoint {
|
|
|
302
344
|
if ($MyInvocation.InvocationName -eq '.') {
|
|
303
345
|
return
|
|
304
346
|
}
|
|
347
|
+
if ($script:HookDependencyGuardLoadFailed) { [Console]::Error.WriteLine('PR_AUTHOR_SKILL_BLOCKED: hook-dependency-guard.ps1 failed to load; the gate fails closed.'); exit 2 }
|
|
348
|
+
$dependencyDecision = Get-HookDependencyFailureDecision -HookEvent PreToolUse -ReasonPrefix 'PR_AUTHOR_SKILL_BLOCKED:'
|
|
349
|
+
if ($null -ne $dependencyDecision) { $dependencyDecision | ConvertTo-Json -Compress -Depth 5 | Write-Output; exit 0 }
|
|
305
350
|
|
|
306
351
|
# The entry point returns its [int] exit code as the last pipeline element and the
|
|
307
352
|
# decision JSON before it. `exit (<call>)` would capture BOTH into the exit
|
package/resources/claude-customizations/.claude/hooks/enforce-prd-feature-before-planner-helpers.ps1
CHANGED
|
@@ -10,13 +10,16 @@
|
|
|
10
10
|
cap as target resolution grows.
|
|
11
11
|
|
|
12
12
|
The file declares no file-scope parameter block, no requires directive, and no
|
|
13
|
-
entrypoint. Apart from its function declarations,
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
13
|
+
entrypoint. Apart from its function declarations, its file-scope statements are
|
|
14
|
+
the resolution-module import that follows this block, which brings in issue
|
|
15
|
+
#669's path normalisation and ambiguity reason code, and the guarded dot-source
|
|
16
|
+
of the pure shared resolver feature-folder-resolution.ps1 (issue #565), which
|
|
17
|
+
owns the single work-mode parser. The module import is deliberately unguarded,
|
|
18
|
+
for the same reason the parent hook's is: a resolution module that cannot be
|
|
19
|
+
loaded is itself the target-not-resolvable state, so letting the failure surface
|
|
20
|
+
fails the gate closed rather than degrading it to a permissive path. A failed
|
|
21
|
+
dot-source of the shared resolver makes Resolve-PrdFeatureWorkMode return $null,
|
|
22
|
+
which the planner gate's deny-on-unknown branch treats as an unreadable marker.
|
|
20
23
|
.NOTES
|
|
21
24
|
Compatible with PowerShell 7+. Read-only resolution logic.
|
|
22
25
|
#>
|
|
@@ -24,7 +27,17 @@
|
|
|
24
27
|
# Issue #669 owns path normalisation and the ambiguity reason code. The import is
|
|
25
28
|
# unguarded for the same reason the parent's is: a resolution module that cannot be
|
|
26
29
|
# loaded is itself the target-not-resolvable state.
|
|
27
|
-
Import-Module (Join-Path $PSScriptRoot '../lib/worktree-resolution/WorktreeResolution.psm1') -Force
|
|
30
|
+
Import-Module (Join-Path $PSScriptRoot '../lib/worktree-resolution/WorktreeResolution.psm1') -Force -ErrorAction Stop
|
|
31
|
+
|
|
32
|
+
# Shared work-mode parser (issue #565). Guarded so a failed dot-source fails closed
|
|
33
|
+
# through the planner gate's deny-on-unknown branch.
|
|
34
|
+
$script:PrdFeatureFolderResolutionImportFailure = $null
|
|
35
|
+
try {
|
|
36
|
+
. (Join-Path $PSScriptRoot 'feature-folder-resolution.ps1')
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
$script:PrdFeatureFolderResolutionImportFailure = 'feature-folder-resolution.ps1'
|
|
40
|
+
}
|
|
28
41
|
|
|
29
42
|
function Resolve-PrdFeatureWorkMode {
|
|
30
43
|
<#
|
|
@@ -36,7 +49,10 @@ function Resolve-PrdFeatureWorkMode {
|
|
|
36
49
|
Recognizes minor-audit, full-feature, full-bug, and the legacy full
|
|
37
50
|
marker (normalized to full-feature), mirroring the regex convention
|
|
38
51
|
used by scripts/dev_tools/prompt_mode_contract.py so both runtimes
|
|
39
|
-
agree on what counts as a valid marker line.
|
|
52
|
+
agree on what counts as a valid marker line. Delegates to the single
|
|
53
|
+
shared parser, Resolve-FeatureFolderWorkMode (issue #565), with an empty
|
|
54
|
+
-UnresolvedMode so an unresolved marker still returns $null here; a
|
|
55
|
+
failed dot-source of the shared resolver also returns $null.
|
|
40
56
|
#>
|
|
41
57
|
[CmdletBinding()]
|
|
42
58
|
[OutputType([string])]
|
|
@@ -45,20 +61,15 @@ function Resolve-PrdFeatureWorkMode {
|
|
|
45
61
|
[string] $IssueContent
|
|
46
62
|
)
|
|
47
63
|
|
|
48
|
-
if (
|
|
64
|
+
if ($script:PrdFeatureFolderResolutionImportFailure) {
|
|
49
65
|
return $null
|
|
50
66
|
}
|
|
51
67
|
|
|
52
|
-
$
|
|
53
|
-
if (-not $
|
|
68
|
+
$mode = Resolve-FeatureFolderWorkMode -IssueContent $IssueContent -UnresolvedMode ''
|
|
69
|
+
if (-not $mode) {
|
|
54
70
|
return $null
|
|
55
71
|
}
|
|
56
|
-
|
|
57
|
-
$rawMode = $match.Groups[1].Value
|
|
58
|
-
if ($rawMode -eq 'full') {
|
|
59
|
-
return 'full-feature'
|
|
60
|
-
}
|
|
61
|
-
return $rawMode
|
|
72
|
+
return $mode
|
|
62
73
|
}
|
|
63
74
|
|
|
64
75
|
function Get-PrdFeatureRequiredFile {
|
package/resources/claude-customizations/.claude/hooks/enforce-prd-feature-before-planner.ps1
CHANGED
|
@@ -98,9 +98,10 @@
|
|
|
98
98
|
#>
|
|
99
99
|
[CmdletBinding()]
|
|
100
100
|
param()
|
|
101
|
+
$script:HookDependencyGuardLoadFailed = $false; try { . (Join-Path $PSScriptRoot 'hook-dependency-guard.ps1') } catch { $script:HookDependencyGuardLoadFailed = $true }
|
|
101
102
|
|
|
102
103
|
|
|
103
|
-
Import-Module (Join-Path $PSScriptRoot '../lib/hook-payload/HookPayload.psm1') -Force
|
|
104
|
+
try { Import-Module (Join-Path $PSScriptRoot '../lib/hook-payload/HookPayload.psm1') -Force -ErrorAction Stop } catch { Add-HookDependencyFailure -Name 'HookPayload.psm1' -ErrorRecord $_ }
|
|
104
105
|
# Issue #669 owns worktree location and path normalisation; issue #673 owns the
|
|
105
106
|
# portable-identity resolution this gate now selects a worktree with. Both imports are
|
|
106
107
|
# unguarded on purpose: a resolution module that cannot be loaded is itself the
|
|
@@ -108,9 +109,9 @@ Import-Module (Join-Path $PSScriptRoot '../lib/hook-payload/HookPayload.psm1') -
|
|
|
108
109
|
# a permissive path. Both are required rather than one: the absolute-path join the probe
|
|
109
110
|
# step below calls is exported only by the first, because a module whose exports are pinned
|
|
110
111
|
# by an explicit list does not re-export a sibling's functions to its own importer.
|
|
111
|
-
Import-Module (Join-Path $PSScriptRoot '../lib/worktree-resolution/WorktreeTargetResolution.psm1') -Force
|
|
112
|
-
Import-Module (Join-Path $PSScriptRoot '../lib/worktree-resolution/WorktreeItemResolution.psm1') -Force
|
|
113
|
-
. (Join-Path $PSScriptRoot 'enforce-prd-feature-before-planner-helpers.ps1')
|
|
112
|
+
try { Import-Module (Join-Path $PSScriptRoot '../lib/worktree-resolution/WorktreeTargetResolution.psm1') -Force -ErrorAction Stop } catch { Add-HookDependencyFailure -Name 'WorktreeTargetResolution.psm1' -ErrorRecord $_ }
|
|
113
|
+
try { Import-Module (Join-Path $PSScriptRoot '../lib/worktree-resolution/WorktreeItemResolution.psm1') -Force -ErrorAction Stop } catch { Add-HookDependencyFailure -Name 'WorktreeItemResolution.psm1' -ErrorRecord $_ }
|
|
114
|
+
try { . (Join-Path $PSScriptRoot 'enforce-prd-feature-before-planner-helpers.ps1') } catch { Add-HookDependencyFailure -Name 'enforce-prd-feature-before-planner-helpers.ps1' -ErrorRecord $_ }
|
|
114
115
|
function Get-PrdFeatureFileExistence {
|
|
115
116
|
<#
|
|
116
117
|
.SYNOPSIS
|
|
@@ -316,6 +317,8 @@ function Invoke-PrdFeatureBeforePlannerDecision {
|
|
|
316
317
|
[AllowNull()]
|
|
317
318
|
[object] $ResolvedTarget
|
|
318
319
|
)
|
|
320
|
+
$dependencyDecision = Get-HookDependencyFailureDecision -HookEvent PreToolUse -ReasonPrefix 'PRD_FEATURE_BLOCKED:'
|
|
321
|
+
if ($null -ne $dependencyDecision) { return $dependencyDecision }
|
|
319
322
|
|
|
320
323
|
$envelope = Resolve-ClaudeHookToolInput -Raw $ToolInputRaw
|
|
321
324
|
if (-not $envelope.IsValid) {
|
|
@@ -469,6 +472,9 @@ function Invoke-PrdFeatureBeforePlannerDecision {
|
|
|
469
472
|
if ($MyInvocation.InvocationName -eq '.') {
|
|
470
473
|
return
|
|
471
474
|
}
|
|
475
|
+
if ($script:HookDependencyGuardLoadFailed) { [Console]::Error.WriteLine('PRD_FEATURE_BLOCKED: hook-dependency-guard.ps1 failed to load; the gate fails closed.'); exit 2 }
|
|
476
|
+
$dependencyDecision = Get-HookDependencyFailureDecision -HookEvent PreToolUse -ReasonPrefix 'PRD_FEATURE_BLOCKED:'
|
|
477
|
+
if ($null -ne $dependencyDecision) { $dependencyDecision | ConvertTo-Json -Compress -Depth 5 | Write-Output; exit 0 }
|
|
472
478
|
|
|
473
479
|
$decision = Invoke-PrdFeatureBeforePlannerDecision -ToolInputRaw (Read-ClaudeHookRawPayload)
|
|
474
480
|
|
|
@@ -28,15 +28,16 @@
|
|
|
28
28
|
#>
|
|
29
29
|
[CmdletBinding()]
|
|
30
30
|
param()
|
|
31
|
+
$script:HookDependencyGuardLoadFailed = $false; try { . (Join-Path $PSScriptRoot 'hook-dependency-guard.ps1') } catch { $script:HookDependencyGuardLoadFailed = $true }
|
|
31
32
|
|
|
32
33
|
|
|
33
|
-
Import-Module (Join-Path $PSScriptRoot '../lib/hook-payload/HookPayload.psm1') -Force
|
|
34
|
+
try { Import-Module (Join-Path $PSScriptRoot '../lib/hook-payload/HookPayload.psm1') -Force -ErrorAction Stop } catch { Add-HookDependencyFailure -Name 'HookPayload.psm1' -ErrorRecord $_ }
|
|
34
35
|
|
|
35
36
|
# Shared command-line parser (issue #545). Every forbidden-token scan and both `gh`
|
|
36
37
|
# expressions below run against each segment's clause-ordered scan text, and the
|
|
37
38
|
# structural matcher reaches the relocating `gh` spellings adjacency cannot.
|
|
38
|
-
. (Join-Path $PSScriptRoot 'hook-command-scanner.ps1')
|
|
39
|
-
. (Join-Path $PSScriptRoot 'hook-command-invocation.ps1')
|
|
39
|
+
try { . (Join-Path $PSScriptRoot 'hook-command-scanner.ps1') } catch { Add-HookDependencyFailure -Name 'hook-command-scanner.ps1' -ErrorRecord $_ }
|
|
40
|
+
try { . (Join-Path $PSScriptRoot 'hook-command-invocation.ps1') } catch { Add-HookDependencyFailure -Name 'hook-command-invocation.ps1' -ErrorRecord $_ }
|
|
40
41
|
|
|
41
42
|
$script:PromotionMcpOnlyBlockedReason = 'PROMOTION_MCP_ONLY_BLOCKED: Direct Bash promotion-script execution is not allowed in agent sessions. Use the drm-copilot MCP promotion tools instead.'
|
|
42
43
|
|
|
@@ -112,9 +113,12 @@ function Get-PromotionBypassReason {
|
|
|
112
113
|
}
|
|
113
114
|
|
|
114
115
|
# `gh issue create` and `gh issue new` are direct bypasses of the MCP
|
|
115
|
-
# promotion path. Tolerate any flags after the subcommand.
|
|
116
|
+
# promotion path. Tolerate any flags after the subcommand. The adjacency
|
|
117
|
+
# expression reads the masked text, so a quoted mention is not a match; wrapper
|
|
118
|
+
# payloads and substitution bodies are covered by the structural check below
|
|
119
|
+
# (issue #824).
|
|
116
120
|
foreach ($segment in $segments) {
|
|
117
|
-
if ($segment.
|
|
121
|
+
if ($segment.MaskedText -match '(?i)\bgh\s+issue\s+(?:create|new)\b') {
|
|
118
122
|
return (Get-PromotionMcpOnlyGhIssueBlockedReason)
|
|
119
123
|
}
|
|
120
124
|
}
|
|
@@ -227,6 +231,8 @@ function Invoke-PromotionMcpOnlyDecision {
|
|
|
227
231
|
param(
|
|
228
232
|
[string] $ToolInputRaw
|
|
229
233
|
)
|
|
234
|
+
$dependencyDecision = Get-HookDependencyFailureDecision -HookEvent PreToolUse -ReasonPrefix 'PROMOTION_MCP_ONLY_BLOCKED:'
|
|
235
|
+
if ($null -ne $dependencyDecision) { return $dependencyDecision }
|
|
230
236
|
|
|
231
237
|
$payload = Resolve-ClaudeHookToolInput -Raw $ToolInputRaw
|
|
232
238
|
if (-not $payload.IsValid) {
|
|
@@ -291,6 +297,9 @@ function Invoke-PromotionMcpOnlyEntryPoint {
|
|
|
291
297
|
if ($MyInvocation.InvocationName -eq '.') {
|
|
292
298
|
return
|
|
293
299
|
}
|
|
300
|
+
if ($script:HookDependencyGuardLoadFailed) { [Console]::Error.WriteLine('PROMOTION_MCP_ONLY_BLOCKED: hook-dependency-guard.ps1 failed to load; the gate fails closed.'); exit 2 }
|
|
301
|
+
$dependencyDecision = Get-HookDependencyFailureDecision -HookEvent PreToolUse -ReasonPrefix 'PROMOTION_MCP_ONLY_BLOCKED:'
|
|
302
|
+
if ($null -ne $dependencyDecision) { $dependencyDecision | ConvertTo-Json -Compress -Depth 5 | Write-Output; exit 0 }
|
|
294
303
|
|
|
295
304
|
# The entry point returns its [int] exit code as the last pipeline element and the
|
|
296
305
|
# decision JSON before it. `exit (<call>)` would capture BOTH into the exit
|
|
@@ -57,10 +57,11 @@
|
|
|
57
57
|
#>
|
|
58
58
|
[CmdletBinding()]
|
|
59
59
|
param()
|
|
60
|
+
$script:HookDependencyGuardLoadFailed = $false; try { . (Join-Path $PSScriptRoot 'hook-dependency-guard.ps1') } catch { $script:HookDependencyGuardLoadFailed = $true }
|
|
60
61
|
|
|
61
62
|
|
|
62
|
-
Import-Module (Join-Path $PSScriptRoot '../lib/hook-payload/HookPayload.psm1') -Force
|
|
63
|
-
. (Join-Path $PSScriptRoot 'enforce-batch-budget-route.ps1')
|
|
63
|
+
try { Import-Module (Join-Path $PSScriptRoot '../lib/hook-payload/HookPayload.psm1') -Force -ErrorAction Stop } catch { Add-HookDependencyFailure -Name 'HookPayload.psm1' -ErrorRecord $_ }
|
|
64
|
+
try { . (Join-Path $PSScriptRoot 'enforce-batch-budget-route.ps1') } catch { Add-HookDependencyFailure -Name 'enforce-batch-budget-route.ps1' -ErrorRecord $_ }
|
|
64
65
|
|
|
65
66
|
function Test-PythonBatchBudgetPathInRoot {
|
|
66
67
|
<#
|
|
@@ -280,6 +281,8 @@ function Invoke-PythonBatchBudgetDecision {
|
|
|
280
281
|
[AllowEmptyString()]
|
|
281
282
|
[string] $ObservedRoute = ''
|
|
282
283
|
)
|
|
284
|
+
$dependencyDecision = Get-HookDependencyFailureDecision -HookEvent PreToolUse -ReasonPrefix 'PYTHON_LARGE_PATH_REQUIRED:'
|
|
285
|
+
if ($null -ne $dependencyDecision) { return $dependencyDecision }
|
|
283
286
|
|
|
284
287
|
$normalized = $FilePath -replace '\\', '/'
|
|
285
288
|
if ($normalized -notmatch '\.py$') {
|
|
@@ -477,6 +480,9 @@ function Invoke-PythonBatchBudgetEntryPoint {
|
|
|
477
480
|
if ($MyInvocation.InvocationName -eq '.') {
|
|
478
481
|
return
|
|
479
482
|
}
|
|
483
|
+
if ($script:HookDependencyGuardLoadFailed) { [Console]::Error.WriteLine('PYTHON_LARGE_PATH_REQUIRED: hook-dependency-guard.ps1 failed to load; the gate fails closed.'); exit 2 }
|
|
484
|
+
$dependencyDecision = Get-HookDependencyFailureDecision -HookEvent PreToolUse -ReasonPrefix 'PYTHON_LARGE_PATH_REQUIRED:'
|
|
485
|
+
if ($null -ne $dependencyDecision) { $dependencyDecision | ConvertTo-Json -Compress -Depth 5 | Write-Output; exit 0 }
|
|
480
486
|
|
|
481
487
|
# The entry point returns its [int] exit code as the last pipeline element and the
|
|
482
488
|
# decision JSON before it. `exit (<call>)` would capture BOTH into the exit
|