@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.
Files changed (264) hide show
  1. package/out/mcp-server.js +1149 -661
  2. package/package.json +3 -2
  3. package/resources/claude-customizations/.claude/agents/atomic-executor.md +28 -6
  4. package/resources/claude-customizations/.claude/agents/atomic-planner.md +20 -2
  5. package/resources/claude-customizations/.claude/agents/epic-orchestrator.md +17 -4
  6. package/resources/claude-customizations/.claude/agents/epic-planner.md +5 -4
  7. package/resources/claude-customizations/.claude/agents/feature-review.md +6 -4
  8. package/resources/claude-customizations/.claude/agents/orchestrator.md +9 -5
  9. package/resources/claude-customizations/.claude/agents/parallel-orchestrator.md +35 -13
  10. package/resources/claude-customizations/.claude/agents/parallel-planner.md +9 -6
  11. package/resources/claude-customizations/.claude/agents/pr-author.md +15 -2
  12. package/resources/claude-customizations/.claude/agents/prd-feature.md +1 -1
  13. package/resources/claude-customizations/.claude/agents/task-researcher.md +8 -0
  14. package/resources/claude-customizations/.claude/hooks/check-powershell-test-purity.ps1 +7 -1
  15. package/resources/claude-customizations/.claude/hooks/check-python-test-purity.ps1 +7 -1
  16. package/resources/claude-customizations/.claude/hooks/enforce-checkpoint-monotonic.ps1 +7 -1
  17. package/resources/claude-customizations/.claude/hooks/enforce-completion-consistency.ps1 +111 -46
  18. package/resources/claude-customizations/.claude/hooks/enforce-completion-helpers.ps1 +105 -0
  19. package/resources/claude-customizations/.claude/hooks/enforce-discovery-artifact-gate.ps1 +8 -1
  20. package/resources/claude-customizations/.claude/hooks/enforce-epic-invocation-origin.ps1 +7 -1
  21. package/resources/claude-customizations/.claude/hooks/enforce-epic-merge-gate-command.ps1 +190 -0
  22. package/resources/claude-customizations/.claude/hooks/enforce-epic-merge-gate-resolution.ps1 +116 -59
  23. package/resources/claude-customizations/.claude/hooks/enforce-epic-merge-gate.ps1 +78 -77
  24. package/resources/claude-customizations/.claude/hooks/enforce-epic-wave-barrier.ps1 +74 -75
  25. package/resources/claude-customizations/.claude/hooks/enforce-epic-worktree-removal-gate-resolution.ps1 +127 -35
  26. package/resources/claude-customizations/.claude/hooks/enforce-epic-worktree-removal-gate.ps1 +61 -57
  27. package/resources/claude-customizations/.claude/hooks/enforce-evidence-locations.ps1 +7 -1
  28. package/resources/claude-customizations/.claude/hooks/enforce-feature-folder-order.ps1 +129 -39
  29. package/resources/claude-customizations/.claude/hooks/enforce-mermaid-validation.ps1 +7 -1
  30. package/resources/claude-customizations/.claude/hooks/enforce-model-routing-receipt.ps1 +9 -3
  31. package/resources/claude-customizations/.claude/hooks/enforce-orchestration-preimplementation-gate-epic-scope.ps1 +39 -51
  32. package/resources/claude-customizations/.claude/hooks/enforce-orchestration-preimplementation-gate-helpers.ps1 +31 -58
  33. package/resources/claude-customizations/.claude/hooks/enforce-orchestration-preimplementation-gate-modes.ps1 +63 -47
  34. package/resources/claude-customizations/.claude/hooks/enforce-orchestration-preimplementation-gate-targets.ps1 +433 -0
  35. package/resources/claude-customizations/.claude/hooks/enforce-orchestration-preimplementation-gate.ps1 +17 -12
  36. package/resources/claude-customizations/.claude/hooks/enforce-parallel-abandon-gate.ps1 +9 -3
  37. package/resources/claude-customizations/.claude/hooks/enforce-parallel-cohort-barrier.ps1 +65 -50
  38. package/resources/claude-customizations/.claude/hooks/enforce-parallel-drift-gate.ps1 +49 -42
  39. package/resources/claude-customizations/.claude/hooks/enforce-parallel-worktree-removal-gate.ps1 +54 -72
  40. package/resources/claude-customizations/.claude/hooks/enforce-powershell-batch-budget.ps1 +8 -2
  41. package/resources/claude-customizations/.claude/hooks/enforce-pr-author-command-allowlist.ps1 +279 -0
  42. package/resources/claude-customizations/.claude/hooks/enforce-pr-author-skill-helpers.ps1 +129 -75
  43. package/resources/claude-customizations/.claude/hooks/enforce-pr-author-skill.artifact-root.ps1 +233 -0
  44. package/resources/claude-customizations/.claude/hooks/enforce-pr-author-skill.docs-only.ps1 +224 -0
  45. package/resources/claude-customizations/.claude/hooks/enforce-pr-author-skill.ps1 +69 -24
  46. package/resources/claude-customizations/.claude/hooks/enforce-prd-feature-before-planner-helpers.ps1 +29 -18
  47. package/resources/claude-customizations/.claude/hooks/enforce-prd-feature-before-planner.ps1 +10 -4
  48. package/resources/claude-customizations/.claude/hooks/enforce-promotion-mcp-only.ps1 +14 -5
  49. package/resources/claude-customizations/.claude/hooks/enforce-python-batch-budget.ps1 +8 -2
  50. package/resources/claude-customizations/.claude/hooks/feature-folder-resolution.ps1 +373 -0
  51. package/resources/claude-customizations/.claude/hooks/feature-review-coverage-thresholds.ps1 +85 -0
  52. package/resources/claude-customizations/.claude/hooks/hook-command-heredoc.ps1 +119 -0
  53. package/resources/claude-customizations/.claude/hooks/hook-command-invocation-operands.ps1 +198 -0
  54. package/resources/claude-customizations/.claude/hooks/hook-command-invocation.ps1 +254 -255
  55. package/resources/claude-customizations/.claude/hooks/hook-command-payload-powershell.ps1 +201 -0
  56. package/resources/claude-customizations/.claude/hooks/hook-command-payload.ps1 +484 -0
  57. package/resources/claude-customizations/.claude/hooks/hook-command-scanner.ps1 +27 -110
  58. package/resources/claude-customizations/.claude/hooks/hook-dependency-guard.ps1 +114 -0
  59. package/resources/claude-customizations/.claude/hooks/hook-docs-only-diff.ps1 +497 -0
  60. package/resources/claude-customizations/.claude/hooks/premortem-section.ps1 +149 -0
  61. package/resources/claude-customizations/.claude/hooks/subagentstop-envelope.ps1 +192 -0
  62. package/resources/claude-customizations/.claude/hooks/validate-bash.ps1 +9 -3
  63. package/resources/claude-customizations/.claude/hooks/validate-discovery-artifact-gate.ps1 +40 -42
  64. package/resources/claude-customizations/.claude/hooks/validate-executor-output.ps1 +267 -113
  65. package/resources/claude-customizations/.claude/hooks/validate-feature-review-coverage-metrics.ps1 +180 -0
  66. package/resources/claude-customizations/.claude/hooks/validate-feature-review-coverage-rules.ps1 +195 -0
  67. package/resources/claude-customizations/.claude/hooks/validate-feature-review-coverage.ps1 +141 -395
  68. package/resources/claude-customizations/.claude/hooks/validate-orchestrator-output-resolution.ps1 +311 -0
  69. package/resources/claude-customizations/.claude/hooks/validate-orchestrator-output-routing.ps1 +170 -0
  70. package/resources/claude-customizations/.claude/hooks/validate-orchestrator-output.ps1 +115 -190
  71. package/resources/claude-customizations/.claude/hooks/validate-planner-output.ps1 +77 -33
  72. package/resources/claude-customizations/.claude/hooks/validate-pr-author-output.ps1 +39 -44
  73. package/resources/claude-customizations/.claude/hooks/validate-prd-feature-output.ps1 +43 -14
  74. package/resources/claude-customizations/.claude/hooks/validate-required-artifact-output.ps1 +66 -36
  75. package/resources/claude-customizations/.claude/hooks/validate-task-researcher-output.ps1 +52 -36
  76. package/resources/claude-customizations/.claude/lib/bash/mutate-parallel-run.sh +191 -0
  77. package/resources/claude-customizations/.claude/lib/bash/parallel-cohorts.sh +13 -3
  78. package/resources/claude-customizations/.claude/lib/bash/parallel-mutation-cli.sh +152 -0
  79. package/resources/claude-customizations/.claude/lib/bash/parallel-mutation-ops.sh +193 -0
  80. package/resources/claude-customizations/.claude/lib/bash/parallel-mutation.sh +322 -0
  81. package/resources/claude-customizations/.claude/lib/bash/remove-parallel-item.sh +146 -0
  82. package/resources/claude-customizations/.claude/lib/blast-radius/BlastRadiusExtraction.psm1 +23 -33
  83. package/resources/claude-customizations/.claude/lib/blast-radius/BlastRadiusTokenShape.psm1 +86 -6
  84. package/resources/claude-customizations/.claude/lib/ci-gate/Invoke-CiGateParser.ps1 +91 -19
  85. package/resources/claude-customizations/.claude/lib/ci-gate/Invoke-MergeConfirmationParser.ps1 +203 -0
  86. package/resources/claude-customizations/.claude/lib/orchestrator-state/OrchestratorStateEpicWaveBarrier.psm1 +346 -0
  87. package/resources/claude-customizations/.claude/lib/orchestrator-state/OrchestratorStateIssueAdoption.psm1 +24 -3
  88. package/resources/claude-customizations/.claude/lib/worktree-resolution/WorktreeItemResolution.psm1 +79 -2
  89. package/resources/claude-customizations/.claude/lib/worktree-resolution/WorktreeRunResolution.psm1 +3 -3
  90. package/resources/claude-customizations/.claude/rules/architecture-boundaries.md +5 -5
  91. package/resources/claude-customizations/.claude/rules/csharp.md +2 -2
  92. package/resources/claude-customizations/.claude/rules/general-code-change.md +1 -1
  93. package/resources/claude-customizations/.claude/rules/general-unit-test.md +3 -2
  94. package/resources/claude-customizations/.claude/rules/orchestrator-state.md +37 -4
  95. package/resources/claude-customizations/.claude/rules/parallel-orchestration.md +50 -5
  96. package/resources/claude-customizations/.claude/rules/plan-acceptance-gates.md +85 -10
  97. package/resources/claude-customizations/.claude/rules/quality-tiers.md +11 -7
  98. package/resources/claude-customizations/.claude/rules/shell.md +10 -8
  99. package/resources/claude-customizations/.claude/rules/typescript.md +1 -1
  100. package/resources/claude-customizations/.claude/settings.json +3 -4
  101. package/resources/claude-customizations/.claude/skills/acceptance-criteria-tracking/SKILL.md +1 -1
  102. package/resources/claude-customizations/.claude/skills/atomic-plan-contract/SKILL.md +52 -16
  103. package/resources/claude-customizations/.claude/skills/cleanup-merged-worktrees/SKILL.md +7 -3
  104. package/resources/claude-customizations/.claude/skills/cleanup-merged-worktrees/scripts/cleanup_worktrees_detached_lib.sh +1 -1
  105. package/resources/claude-customizations/.claude/skills/cleanup-merged-worktrees/scripts/cleanup_worktrees_enumerate_lib.sh +2 -0
  106. package/resources/claude-customizations/.claude/skills/cleanup-merged-worktrees/scripts/cleanup_worktrees_scan_helper.sh +2 -0
  107. package/resources/claude-customizations/.claude/skills/csharp-change-budget-router/SKILL.md +2 -2
  108. package/resources/claude-customizations/.claude/skills/epic-orchestrate/SKILL.md +45 -9
  109. package/resources/claude-customizations/.claude/skills/epic-plan/SKILL.md +5 -3
  110. package/resources/claude-customizations/.claude/skills/evidence-and-timestamp-conventions/SKILL.md +10 -1
  111. package/resources/claude-customizations/.claude/skills/execution-environment/SKILL.md +134 -0
  112. package/resources/claude-customizations/.claude/skills/feature-promotion-lifecycle/SKILL.md +1 -1
  113. package/resources/claude-customizations/.claude/skills/feature-review-workflow/SKILL.md +4 -3
  114. package/resources/claude-customizations/.claude/skills/orchestrate/SKILL.md +36 -15
  115. package/resources/claude-customizations/.claude/skills/parallel-add/SKILL.md +52 -14
  116. package/resources/claude-customizations/.claude/skills/parallel-close/SKILL.md +22 -9
  117. package/resources/claude-customizations/.claude/skills/parallel-orchestrate/SKILL.md +108 -21
  118. package/resources/claude-customizations/.claude/skills/parallel-plan/SKILL.md +63 -7
  119. package/resources/claude-customizations/.claude/skills/parallel-remove/SKILL.md +35 -12
  120. package/resources/claude-customizations/.claude/skills/powershell-change-budget-router/SKILL.md +1 -1
  121. package/resources/claude-customizations/.claude/skills/pr-author/SKILL.md +3 -1
  122. package/resources/claude-customizations/.claude/skills/python-change-budget-router/SKILL.md +1 -1
  123. package/resources/claude-customizations/.claude/skills/quota-throttling/SKILL.md +1 -1
  124. package/resources/claude-customizations/.claude/skills/remediation-handoff-atomic-planner/SKILL.md +16 -8
  125. package/resources/claude-customizations/.claude/skills/research-issue/SKILL.md +6 -0
  126. package/resources/claude-customizations/pack-manifests/core.json +27 -0
  127. package/resources/codex-and-agents-customizations/.agents/skills/README.md +1 -0
  128. package/resources/codex-and-agents-customizations/.agents/skills/acceptance-criteria-tracking/SKILL.md +1 -1
  129. package/resources/codex-and-agents-customizations/.agents/skills/architecture-boundaries/SKILL.md +5 -5
  130. package/resources/codex-and-agents-customizations/.agents/skills/atomic-executor/SKILL.md +19 -7
  131. package/resources/codex-and-agents-customizations/.agents/skills/atomic-plan-contract/SKILL.md +43 -4
  132. package/resources/codex-and-agents-customizations/.agents/skills/atomic-planner/SKILL.md +18 -6
  133. package/resources/codex-and-agents-customizations/.agents/skills/csharp/SKILL.md +2 -2
  134. package/resources/codex-and-agents-customizations/.agents/skills/csharp-change-budget-router/SKILL.md +2 -2
  135. package/resources/codex-and-agents-customizations/.agents/skills/csharp-qa-gate/SKILL.md +2 -2
  136. package/resources/codex-and-agents-customizations/.agents/skills/epic-orchestrate/SKILL.md +16 -1
  137. package/resources/codex-and-agents-customizations/.agents/skills/epic-plan/SKILL.md +17 -1
  138. package/resources/codex-and-agents-customizations/.agents/skills/epic-run/SKILL.md +2 -1
  139. package/resources/codex-and-agents-customizations/.agents/skills/evidence-and-timestamp-conventions/SKILL.md +10 -1
  140. package/resources/codex-and-agents-customizations/.agents/skills/execution-environment/SKILL.md +134 -0
  141. package/resources/codex-and-agents-customizations/.agents/skills/feature-review-workflow/SKILL.md +13 -5
  142. package/resources/codex-and-agents-customizations/.agents/skills/general-code-change/SKILL.md +1 -1
  143. package/resources/codex-and-agents-customizations/.agents/skills/general-unit-test/SKILL.md +3 -2
  144. package/resources/codex-and-agents-customizations/.agents/skills/orchestrate/SKILL.md +27 -8
  145. package/resources/codex-and-agents-customizations/.agents/skills/orchestrator-workflow/SKILL.md +1 -1
  146. package/resources/codex-and-agents-customizations/.agents/skills/powershell-change-budget-router/SKILL.md +1 -1
  147. package/resources/codex-and-agents-customizations/.agents/skills/python-change-budget-router/SKILL.md +1 -1
  148. package/resources/codex-and-agents-customizations/.agents/skills/quality-tiers/SKILL.md +11 -7
  149. package/resources/codex-and-agents-customizations/.agents/skills/remediation-handoff-atomic-planner/SKILL.md +7 -3
  150. package/resources/codex-and-agents-customizations/.agents/skills/research-issue/SKILL.md +6 -0
  151. package/resources/codex-and-agents-customizations/.agents/skills/translate-claude-to-codex/SKILL.md +1 -1
  152. package/resources/codex-and-agents-customizations/.agents-variants/csharp-legacy/skills/csharp/SKILL.md +2 -2
  153. package/resources/codex-and-agents-customizations/.agents-variants/csharp-legacy/skills/csharp-qa-gate/SKILL.md +2 -2
  154. package/resources/codex-and-agents-customizations/.codex/agents/atomic-executor-c1.toml +21 -6
  155. package/resources/codex-and-agents-customizations/.codex/agents/atomic-executor-c2.toml +21 -6
  156. package/resources/codex-and-agents-customizations/.codex/agents/atomic-executor-c3-elevated.toml +21 -6
  157. package/resources/codex-and-agents-customizations/.codex/agents/atomic-executor-c3.toml +21 -6
  158. package/resources/codex-and-agents-customizations/.codex/agents/atomic-executor-c4.toml +21 -6
  159. package/resources/codex-and-agents-customizations/.codex/agents/atomic-executor.toml +21 -6
  160. package/resources/codex-and-agents-customizations/.codex/agents/atomic-planner-c1.toml +15 -2
  161. package/resources/codex-and-agents-customizations/.codex/agents/atomic-planner-c2.toml +15 -2
  162. package/resources/codex-and-agents-customizations/.codex/agents/atomic-planner-c3-elevated.toml +15 -2
  163. package/resources/codex-and-agents-customizations/.codex/agents/atomic-planner-c3.toml +15 -2
  164. package/resources/codex-and-agents-customizations/.codex/agents/atomic-planner-c4.toml +15 -2
  165. package/resources/codex-and-agents-customizations/.codex/agents/atomic-planner.toml +15 -2
  166. package/resources/codex-and-agents-customizations/.codex/agents/atomic-planning.toml +1 -1
  167. package/resources/codex-and-agents-customizations/.codex/agents/csharp-atomic-planning.toml +1 -1
  168. package/resources/codex-and-agents-customizations/.codex/agents/epic-orchestrator.toml +4 -1
  169. package/resources/codex-and-agents-customizations/.codex/agents/feature-review.toml +6 -6
  170. package/resources/codex-and-agents-customizations/.codex/agents/orchestrator-c1.toml +7 -4
  171. package/resources/codex-and-agents-customizations/.codex/agents/orchestrator-c2.toml +7 -4
  172. package/resources/codex-and-agents-customizations/.codex/agents/orchestrator-c3-elevated.toml +7 -4
  173. package/resources/codex-and-agents-customizations/.codex/agents/orchestrator-c3.toml +7 -4
  174. package/resources/codex-and-agents-customizations/.codex/agents/orchestrator-c4.toml +7 -4
  175. package/resources/codex-and-agents-customizations/.codex/agents/orchestrator.toml +7 -4
  176. package/resources/codex-and-agents-customizations/.codex/agents/powershell-atomic-planning.toml +1 -1
  177. package/resources/codex-and-agents-customizations/.codex/agents/python-atomic-planning.toml +1 -1
  178. package/resources/codex-and-agents-customizations/.codex/agents/task-researcher-c1.toml +6 -0
  179. package/resources/codex-and-agents-customizations/.codex/agents/task-researcher-c2.toml +6 -0
  180. package/resources/codex-and-agents-customizations/.codex/agents/task-researcher-c3-elevated.toml +6 -0
  181. package/resources/codex-and-agents-customizations/.codex/agents/task-researcher-c3.toml +6 -0
  182. package/resources/codex-and-agents-customizations/.codex/agents/task-researcher-c4.toml +6 -0
  183. package/resources/codex-and-agents-customizations/.codex/agents/task-researcher.toml +6 -0
  184. package/resources/codex-and-agents-customizations/.codex/codex-web-setup.sh +318 -273
  185. package/resources/codex-and-agents-customizations/.codex/config.toml +1 -1
  186. package/resources/codex-and-agents-customizations/.codex/hooks/check-powershell-test-purity.ps1 +7 -1
  187. package/resources/codex-and-agents-customizations/.codex/hooks/check-python-test-purity.ps1 +7 -1
  188. package/resources/codex-and-agents-customizations/.codex/hooks/codex-epic-child-launch-attestation.ps1 +1 -1
  189. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-checkpoint-monotonic.ps1 +7 -1
  190. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-codex-model-routing.ps1 +8 -2
  191. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-completion-consistency.ps1 +97 -44
  192. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-completion-helpers.ps1 +105 -0
  193. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-epic-child-worktree-binding.ps1 +7 -1
  194. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-epic-merge-gate-command.ps1 +190 -0
  195. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-epic-merge-gate.ps1 +54 -43
  196. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-epic-planning-only.ps1 +6 -0
  197. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-epic-root-invocation.ps1 +7 -1
  198. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-epic-wave-barrier.ps1 +7 -1
  199. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-epic-worktree-removal-gate.ps1 +54 -41
  200. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-evidence-locations.ps1 +7 -1
  201. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-orchestration-preimplementation-gate-epic-scope.ps1 +35 -14
  202. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-orchestration-preimplementation-gate-helpers.ps1 +31 -58
  203. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-orchestration-preimplementation-gate-modes.ps1 +63 -47
  204. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-orchestration-preimplementation-gate-targets.ps1 +433 -0
  205. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-orchestration-preimplementation-gate.ps1 +24 -11
  206. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-powershell-batch-budget.ps1 +8 -2
  207. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-promotion-mcp-only.ps1 +13 -4
  208. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-python-batch-budget.ps1 +8 -2
  209. package/resources/codex-and-agents-customizations/.codex/hooks/feature-folder-resolution.ps1 +373 -0
  210. package/resources/codex-and-agents-customizations/.codex/hooks/feature-review-coverage-thresholds.ps1 +85 -0
  211. package/resources/codex-and-agents-customizations/.codex/hooks/hook-command-heredoc.ps1 +119 -0
  212. package/resources/codex-and-agents-customizations/.codex/hooks/hook-command-invocation-operands.ps1 +198 -0
  213. package/resources/codex-and-agents-customizations/.codex/hooks/hook-command-invocation.ps1 +254 -255
  214. package/resources/codex-and-agents-customizations/.codex/hooks/hook-command-payload-powershell.ps1 +201 -0
  215. package/resources/codex-and-agents-customizations/.codex/hooks/hook-command-payload.ps1 +484 -0
  216. package/resources/codex-and-agents-customizations/.codex/hooks/hook-command-scanner.ps1 +27 -110
  217. package/resources/codex-and-agents-customizations/.codex/hooks/hook-dependency-guard.ps1 +114 -0
  218. package/resources/codex-and-agents-customizations/.codex/hooks/hook-docs-only-diff.ps1 +497 -0
  219. package/resources/codex-and-agents-customizations/.codex/hooks/validate-bash.ps1 +8 -2
  220. package/resources/codex-and-agents-customizations/.codex/hooks/validate-codex-subagent-routing.ps1 +7 -1
  221. package/resources/codex-and-agents-customizations/.codex/hooks/validate-feature-review-coverage.ps1 +24 -8
  222. package/resources/codex-and-agents-customizations/.codex/prompts/feature-review-remediate.md +6 -4
  223. package/resources/codex-and-agents-customizations/pack-manifests/core.json +11 -0
  224. package/resources/customizations/.github/agents/atomic_executor.agent.md +21 -11
  225. package/resources/customizations/.github/agents/atomic_planning.agent.md +8 -3
  226. package/resources/customizations/.github/agents/csharp-atomic-executor.agent.md +13 -9
  227. package/resources/customizations/.github/agents/csharp-atomic-planning.agent.md +2 -2
  228. package/resources/customizations/.github/agents/csharp-orchestrator.agent.md +2 -2
  229. package/resources/customizations/.github/agents/csharp-typed-engineer.agent.md +5 -5
  230. package/resources/customizations/.github/agents/orchestrator.agent.md +8 -5
  231. package/resources/customizations/.github/agents/powershell-atomic-executor.agent.md +13 -9
  232. package/resources/customizations/.github/agents/powershell-atomic-planning.agent.md +2 -2
  233. package/resources/customizations/.github/agents/powershell-orchestrator.agent.md +2 -2
  234. package/resources/customizations/.github/agents/powershell-typed-engineer.agent.md +3 -3
  235. package/resources/customizations/.github/agents/python-atomic-executor.agent.md +13 -9
  236. package/resources/customizations/.github/agents/python-atomic-planning.agent.md +2 -2
  237. package/resources/customizations/.github/agents/python-orchestrator.agent.md +2 -2
  238. package/resources/customizations/.github/agents/task-researcher.agent.md +6 -0
  239. package/resources/customizations/.github/instructions/csharp-code-change.instructions.md +4 -4
  240. package/resources/customizations/.github/instructions/csharp-unit-test.instructions.md +2 -2
  241. package/resources/customizations/.github/prompts/generate-atomic-plan.prompt.md +16 -10
  242. package/resources/customizations/.github/prompts/orchestrate-csharp-work.prompt.md +2 -2
  243. package/resources/customizations/.github/prompts/orchestrate-powershell-work.prompt.md +1 -1
  244. package/resources/customizations/.github/prompts/orchestrate-python-work.prompt.md +1 -1
  245. package/resources/customizations/.github/prompts/orchestrate-work.prompt.md +2 -2
  246. package/resources/customizations/.github/skills/acceptance-criteria-tracking/SKILL.md +1 -1
  247. package/resources/customizations/.github/skills/atomic-plan-contract/SKILL.md +43 -4
  248. package/resources/customizations/.github/skills/csharp-change-budget-router/SKILL.md +1 -1
  249. package/resources/customizations/.github/skills/evidence-and-timestamp-conventions/SKILL.md +10 -1
  250. package/resources/customizations/.github/skills/execution-environment/SKILL.md +134 -0
  251. package/resources/customizations/.github/skills/feature-review-workflow/SKILL.md +1 -1
  252. package/resources/customizations/.github/skills/powershell-change-budget-router/SKILL.md +1 -1
  253. package/resources/customizations/.github/skills/remediation-handoff-atomic-planner/SKILL.md +7 -3
  254. package/resources/feature-templates/bug/plan.yyyy-MM-ddTHH-mm.md +10 -0
  255. package/resources/feature-templates/feature/plan.yyyy-MM-ddTHH-mm.md +11 -0
  256. package/resources/feature-templates/refactor/plan.yyyy-MM-ddTHH-mm.md +11 -0
  257. package/resources/powershell/PoshQC/PoshQC.Coverage.psm1 +314 -0
  258. package/resources/powershell/PoshQC/PoshQC.CoverageMerge.psm1 +163 -0
  259. package/resources/powershell/PoshQC/PoshQC.Shard.psm1 +296 -0
  260. package/resources/powershell/PoshQC/PoshQC.Testing.psm1 +48 -32
  261. package/resources/powershell/PoshQC/PoshQC.psd1 +7 -1
  262. package/resources/powershell/PoshQC/PoshQC.psm1 +18 -5
  263. package/resources/powershell/PoshQC/README.md +21 -3
  264. package/resources/powershell/PoshQC/settings/pester.runsettings.psd1 +5 -319
@@ -4,29 +4,30 @@
4
4
  #>
5
5
  [CmdletBinding()]
6
6
  param()
7
+ $script:HookDependencyGuardLoadFailed = $false; try { . (Join-Path $PSScriptRoot 'hook-dependency-guard.ps1') } catch { $script:HookDependencyGuardLoadFailed = $true }
7
8
 
8
9
 
9
- Import-Module (Join-Path $PSScriptRoot '../lib/hook-payload/HookPayload.psm1') -Force
10
+ try { Import-Module (Join-Path $PSScriptRoot '../lib/hook-payload/HookPayload.psm1') -Force -ErrorAction Stop } catch { Add-HookDependencyFailure -Name 'HookPayload.psm1' -ErrorRecord $_ }
10
11
 
11
12
  # Pure pathspec classifier for the issue #539 orchestration-bookkeeping staging exemption.
12
13
  # Extracted to a dot-sourced sibling so this file stays inside the 500-line cap, following
13
14
  # the enforce-pr-author-skill.ps1 headroom-split precedent.
14
- . (Join-Path $PSScriptRoot 'enforce-orchestration-preimplementation-gate-helpers.ps1')
15
+ try { . (Join-Path $PSScriptRoot 'enforce-orchestration-preimplementation-gate-helpers.ps1') } catch { Add-HookDependencyFailure -Name 'enforce-orchestration-preimplementation-gate-helpers.ps1' -ErrorRecord $_ }
15
16
 
16
17
  # Pure mode dispatch and per-mode readiness predicates for issue #554. A new sibling
17
18
  # rather than an addition to the helpers file above, whose header declares a different
18
19
  # normative contract and which lacks headroom; leaving that file byte-untouched is the
19
20
  # proof the issue #539 exemption is behaviourally unchanged.
20
- . (Join-Path $PSScriptRoot 'enforce-orchestration-preimplementation-gate-modes.ps1')
21
+ try { . (Join-Path $PSScriptRoot 'enforce-orchestration-preimplementation-gate-modes.ps1') } catch { Add-HookDependencyFailure -Name 'enforce-orchestration-preimplementation-gate-modes.ps1' -ErrorRecord $_ }
21
22
 
22
23
  # Epic-scope command and path legs (issue #663, decision D2), the three checkpoint read
23
24
  # seams, the mode deny reason, and the target resolution with its import guard (issue
24
25
  # #690), all relocated to this sibling to keep the gate inside the 500-line cap.
25
- . (Join-Path $PSScriptRoot 'enforce-orchestration-preimplementation-gate-epic-scope.ps1')
26
+ try { . (Join-Path $PSScriptRoot 'enforce-orchestration-preimplementation-gate-epic-scope.ps1') } catch { Add-HookDependencyFailure -Name 'enforce-orchestration-preimplementation-gate-epic-scope.ps1' -ErrorRecord $_ }
26
27
 
27
28
  # Shared command-line parser (issue #545): per-segment scan text and structural matching.
28
- . (Join-Path $PSScriptRoot 'hook-command-scanner.ps1')
29
- . (Join-Path $PSScriptRoot 'hook-command-invocation.ps1')
29
+ try { . (Join-Path $PSScriptRoot 'hook-command-scanner.ps1') } catch { Add-HookDependencyFailure -Name 'hook-command-scanner.ps1' -ErrorRecord $_ }
30
+ try { . (Join-Path $PSScriptRoot 'hook-command-invocation.ps1') } catch { Add-HookDependencyFailure -Name 'hook-command-invocation.ps1' -ErrorRecord $_ }
30
31
 
31
32
  # Every orchestration checkpoint a planner or orchestrator surface writes. Writing one
32
33
  # of these is orchestration bookkeeping, not implementation, so the gate must not
@@ -306,9 +307,8 @@ function Invoke-OrchestrationPreimplementationGateDecision {
306
307
  [AllowEmptyString()]
307
308
  [string] $ParallelCheckpointRaw
308
309
  )
309
-
310
- # A failed worktree-resolution import denies before any other logic (issue #690).
311
- $importFailure = Get-OrchestrationGateImportFailureDecision; if ($null -ne $importFailure) { return $importFailure }
310
+ $dependencyDecision = Get-HookDependencyFailureDecision -HookEvent PreToolUse -ReasonPrefix 'PREIMPLEMENTATION_GATE_BLOCKED:'
311
+ if ($null -ne $dependencyDecision) { return $dependencyDecision }
312
312
 
313
313
  $payload = Resolve-ClaudeHookToolInput -Raw $ToolInputRaw
314
314
  if (-not $payload.IsValid) {
@@ -383,11 +383,13 @@ function Invoke-OrchestrationPreimplementationGateDecision {
383
383
  $modeCheckpoint = ConvertFrom-CheckpointJson -Json ([string]$modeRaw)
384
384
  } catch { $modeCheckpoint = $null }
385
385
  $folder = Find-OrchestrationDelegationTargetFolder -Prompt $prompt
386
- $issue = Find-OrchestrationDelegationIssueNumber -Prompt $prompt
386
+ # Only the keyed issue number breaks a tie among cited folders (#565 CR-1); the bare hash form feeds the D3 record lookup only.
387
+ $issue = Find-OrchestrationDelegationIssueNumber -Prompt $prompt -KeyedOnly
388
+ $fallbackIssue = Find-OrchestrationDelegationIssueNumber -Prompt $prompt
387
389
  $failure = if ($isEpic) {
388
- Get-EpicOrchestrationReadinessFailure -Checkpoint $modeCheckpoint -TargetFolder $folder -IssueNumber $issue
390
+ Get-EpicOrchestrationReadinessFailure -Checkpoint $modeCheckpoint -TargetFolder $folder -IssueNumber $issue -FallbackIssueNumber $fallbackIssue
389
391
  } else {
390
- Get-ParallelOrchestrationReadinessFailure -Checkpoint $modeCheckpoint -TargetFolder $folder -IssueNumber $issue
392
+ Get-ParallelOrchestrationReadinessFailure -Checkpoint $modeCheckpoint -TargetFolder $folder -IssueNumber $issue -FallbackIssueNumber $fallbackIssue
391
393
  }
392
394
  if (-not $failure) { return Get-OrchestrationPreimplementationGateAllowDecision }
393
395
  return Get-OrchestrationPreimplementationGateBlockDecision -Reason (
@@ -454,6 +456,9 @@ function Invoke-OrchestrationPreimplementationGateEntryPoint {
454
456
  if ($MyInvocation.InvocationName -eq '.') {
455
457
  return
456
458
  }
459
+ if ($script:HookDependencyGuardLoadFailed) { [Console]::Error.WriteLine('PREIMPLEMENTATION_GATE_BLOCKED: hook-dependency-guard.ps1 failed to load; the gate fails closed.'); exit 2 }
460
+ $dependencyDecision = Get-HookDependencyFailureDecision -HookEvent PreToolUse -ReasonPrefix 'PREIMPLEMENTATION_GATE_BLOCKED:'
461
+ if ($null -ne $dependencyDecision) { $dependencyDecision | ConvertTo-Json -Compress -Depth 5 | Write-Output; exit 0 }
457
462
 
458
463
  # The entry point returns its [int] exit code as the last pipeline element and the
459
464
  # decision JSON before it. `exit (<call>)` would capture BOTH into the exit
@@ -32,9 +32,10 @@
32
32
  #>
33
33
  [CmdletBinding()]
34
34
  param()
35
+ $script:HookDependencyGuardLoadFailed = $false; try { . (Join-Path $PSScriptRoot 'hook-dependency-guard.ps1') } catch { $script:HookDependencyGuardLoadFailed = $true }
35
36
 
36
37
 
37
- Import-Module (Join-Path $PSScriptRoot '../lib/hook-payload/HookPayload.psm1') -Force
38
+ try { Import-Module (Join-Path $PSScriptRoot '../lib/hook-payload/HookPayload.psm1') -Force -ErrorAction Stop } catch { Add-HookDependencyFailure -Name 'HookPayload.psm1' -ErrorRecord $_ }
38
39
  # The two tokens this gate matches on. These are the ONLY places either token literal
39
40
  # appears in this file; the seam test extracts the consumer-side values from exactly
40
41
  # these two named assignments.
@@ -48,8 +49,8 @@ $script:AbandonBlockedReasonCode = 'PARALLEL_ABANDON_BLOCKED'
48
49
  # rather than above them, deliberately: the assignments keep their existing line numbers,
49
50
  # so the diff shows no change at either line. Both are still declared before any function
50
51
  # body runs, because the file executes top to bottom before any of its functions is called.
51
- . (Join-Path $PSScriptRoot 'hook-command-scanner.ps1')
52
- . (Join-Path $PSScriptRoot 'hook-command-invocation.ps1')
52
+ try { . (Join-Path $PSScriptRoot 'hook-command-scanner.ps1') } catch { Add-HookDependencyFailure -Name 'hook-command-scanner.ps1' -ErrorRecord $_ }
53
+ try { . (Join-Path $PSScriptRoot 'hook-command-invocation.ps1') } catch { Add-HookDependencyFailure -Name 'hook-command-invocation.ps1' -ErrorRecord $_ }
53
54
 
54
55
  function Get-ParallelAbandonGateToolInput {
55
56
  <#
@@ -314,6 +315,8 @@ function Invoke-ParallelAbandonGateDecision {
314
315
  [AllowEmptyString()]
315
316
  [string] $ToolInputRaw
316
317
  )
318
+ $dependencyDecision = Get-HookDependencyFailureDecision -HookEvent PreToolUse -ReasonPrefix 'enforce-parallel-abandon-gate:'
319
+ if ($null -ne $dependencyDecision) { return $dependencyDecision }
317
320
 
318
321
  # An absent payload carries no command to gate, so there is nothing in scope. This is
319
322
  # allow rather than deny because the gate constrains one specific destructive command
@@ -345,6 +348,9 @@ function Invoke-ParallelAbandonGateDecision {
345
348
  if ($MyInvocation.InvocationName -eq '.') {
346
349
  return
347
350
  }
351
+ if ($script:HookDependencyGuardLoadFailed) { [Console]::Error.WriteLine('enforce-parallel-abandon-gate: hook-dependency-guard.ps1 failed to load; the gate fails closed.'); exit 2 }
352
+ $dependencyDecision = Get-HookDependencyFailureDecision -HookEvent PreToolUse -ReasonPrefix 'enforce-parallel-abandon-gate:'
353
+ if ($null -ne $dependencyDecision) { $dependencyDecision | ConvertTo-Json -Compress -Depth 5 | Write-Output; exit 0 }
348
354
 
349
355
  $decision = Invoke-ParallelAbandonGateDecision -ToolInputRaw (Get-ParallelAbandonGateToolInput)
350
356
 
@@ -13,24 +13,29 @@
13
13
  conflict_edges[], and position is read from the current cohort coloring.
14
14
 
15
15
  Resolution and decision procedure:
16
- 1. Resolve the target item's feature folder from the prompt text by scanning for a
17
- docs/features/active/<token> path, mirroring the epic hook's technique
18
- (longest match wins; a .md-suffixed match uses its parent directory).
19
- 2. Resolve the worktree whose parallel checkpoint records the prompt's
20
- parallel_slug: value (issue #690), deny an unresolved or ambiguous target, then
21
- read artifacts/orchestration/parallel-orchestrator-state.json beneath that
22
- worktree and locate the items[] record whose feature_folder resolves to the same
23
- basename.
24
- 3. Project the cohort coloring to the cohorts[] rows whose generation equals the
16
+ 1. Resolve the worktree whose parallel checkpoint records the prompt's
17
+ parallel_slug: value (issue #690) and deny an unresolved or ambiguous target.
18
+ 2. Collect the cited feature-folder candidates with the shared resolver
19
+ (feature-folder-resolution.ps1, issue #565): every docs/features/active/<token>
20
+ path is truncated to its feature-folder segment, so a nested research/ or
21
+ evidence/ citation names its own folder. No candidate denies.
22
+ 3. Read artifacts/orchestration/parallel-orchestrator-state.json beneath that
23
+ worktree and select the target among the candidates with
24
+ Select-FeatureFolderTarget. The canonical issue-number line, when it names exactly
25
+ one number, breaks a tie among the cited run items; two or more remaining
26
+ candidates otherwise deny as ambiguous. Neither string length nor prompt position
27
+ takes part in the selection. Then locate the items[] record whose feature_folder
28
+ resolves to the selected basename.
29
+ 4. Project the cohort coloring to the cohorts[] rows whose generation equals the
25
30
  top-level recolor_generation, and read the target item's cohort index from that
26
31
  projection.
27
- 4. Collect every conflict_edges[] neighbor of the target item.
28
- 5. Deny with reason PARALLEL_COHORT_BARRIER_BLOCKED unless every neighbor that sits
32
+ 5. Collect every conflict_edges[] neighbor of the target item.
33
+ 6. Deny with reason PARALLEL_COHORT_BARRIER_BLOCKED unless every neighbor that sits
29
34
  in a strictly prior current-generation cohort has merge_status in
30
35
  {merged, worktree_removed}. ci_green does NOT satisfy the barrier: an item whose
31
36
  CI is green has not merged, so its worktree is still live and its contention is
32
37
  unresolved. Same-cohort and later-cohort neighbors do not block Layer 1.
33
- 6. A missing or unparseable checkpoint, an unresolved feature-folder token, a
38
+ 7. A missing or unparseable checkpoint, an unresolved feature-folder token, a
34
39
  missing items[] record, a target with no current-generation cohort assignment, a
35
40
  missing neighbor record, and a missing merge_status all deny (fail-closed).
36
41
 
@@ -43,24 +48,33 @@
43
48
  SubagentStop time.
44
49
 
45
50
  .NOTES
46
- Compatible with PowerShell 7+. Depends on WorktreeRunResolution.psm1 (issue #690),
47
- imported inside a guard: a failed import is recorded and the decision denies naming
48
- the module. Filesystem reads go through an injectable wrapper function so tests can
49
- mock the boundary without writing temporary files.
51
+ Compatible with PowerShell 7+. Depends on WorktreeItemResolution.psm1 and
52
+ WorktreeRunResolution.psm1 (issue #690) and the pure sibling
53
+ feature-folder-resolution.ps1 (issue #565), each loaded inside a guard: the first
54
+ failure is recorded and the decision denies naming the dependency. Filesystem reads go
55
+ through an injectable wrapper function so tests can mock the boundary without writing
56
+ temporary files.
50
57
  #>
51
58
  [CmdletBinding()]
52
59
  param()
60
+ $script:HookDependencyGuardLoadFailed = $false; try { . (Join-Path $PSScriptRoot 'hook-dependency-guard.ps1') } catch { $script:HookDependencyGuardLoadFailed = $true }
53
61
 
54
62
 
55
- Import-Module (Join-Path $PSScriptRoot '../lib/hook-payload/HookPayload.psm1') -Force
63
+ try { Import-Module (Join-Path $PSScriptRoot '../lib/hook-payload/HookPayload.psm1') -Force -ErrorAction Stop } catch { Add-HookDependencyFailure -Name 'HookPayload.psm1' -ErrorRecord $_ }
56
64
 
57
- # Import guard (issue #690): a failed import denies instead of failing open.
65
+ try { Import-Module (Join-Path $PSScriptRoot '../lib/worktree-resolution/WorktreeItemResolution.psm1') -Force -ErrorAction Stop } catch { Add-HookDependencyFailure -Name 'WorktreeItemResolution.psm1' -ErrorRecord $_ }
66
+ try { Import-Module (Join-Path $PSScriptRoot '../lib/worktree-resolution/WorktreeRunResolution.psm1') -Force -ErrorAction Stop } catch { Add-HookDependencyFailure -Name 'WorktreeRunResolution.psm1' -ErrorRecord $_ }
58
67
  $script:ParallelCohortBarrierResolutionImportFailure = $null
68
+
69
+ # Shared feature-folder resolution (issue #565). Guarded so a failed dot-source denies
70
+ # rather than failing open; an earlier recorded failure is kept.
59
71
  try {
60
- Import-Module (Join-Path $PSScriptRoot '../lib/worktree-resolution/WorktreeRunResolution.psm1') -Force -ErrorAction Stop
72
+ . (Join-Path $PSScriptRoot 'feature-folder-resolution.ps1')
61
73
  }
62
74
  catch {
63
- $script:ParallelCohortBarrierResolutionImportFailure = 'WorktreeRunResolution.psm1'
75
+ if (-not $script:ParallelCohortBarrierResolutionImportFailure) {
76
+ $script:ParallelCohortBarrierResolutionImportFailure = 'feature-folder-resolution.ps1'
77
+ }
64
78
  }
65
79
 
66
80
  $script:AllowedMergeStatuses = @('merged', 'worktree_removed')
@@ -68,7 +82,7 @@ $script:ParallelModeMarker = 'Parallel mode: true'
68
82
 
69
83
  # Dot-source the record-resolution and barrier helpers. Guarded so dot-sourcing this
70
84
  # hook in tests loads the helpers too (issue #501 headroom split).
71
- . (Join-Path $PSScriptRoot 'enforce-parallel-cohort-barrier-helpers.ps1')
85
+ try { . (Join-Path $PSScriptRoot 'enforce-parallel-cohort-barrier-helpers.ps1') } catch { Add-HookDependencyFailure -Name 'enforce-parallel-cohort-barrier-helpers.ps1' -ErrorRecord $_ }
72
86
 
73
87
  function Get-ParallelCohortBarrierCheckpointContent {
74
88
  <#
@@ -147,43 +161,27 @@ function Get-ParallelCohortBarrierFolderBasename {
147
161
  function Find-ParallelCohortBarrierFeatureFolderFromPrompt {
148
162
  <#
149
163
  .SYNOPSIS
150
- Scans a prompt string for docs/features/active/<...> path tokens and returns the
151
- longest unique match's basename. Returns $null when no match is found.
164
+ Returns the distinct feature-folder basenames cited in a prompt, in first-occurrence
165
+ order. Returns no output when no folder is cited.
152
166
  .DESCRIPTION
153
- Mirrors the epic wave-barrier hook's technique: forward- or backslash-separated
154
- path tokens are accepted, the longest match wins, and a .md-suffixed match resolves
155
- to its parent directory before the basename is extracted.
167
+ Delegates to Find-FeatureFolderCandidate in the shared resolver (issue #565): each
168
+ docs/features/active/<token> path, in either separator style, is truncated to its
169
+ feature-folder segment, so a nested research/ or evidence/ citation names its own
170
+ folder. Selection among several candidates is made by Select-FeatureFolderTarget.
156
171
  .PARAMETER Prompt
157
172
  The delegation prompt text under evaluation.
158
173
  .OUTPUTS
159
- System.String or $null
174
+ System.String[]
160
175
  #>
161
176
  [CmdletBinding()]
162
- [OutputType([string])]
177
+ [OutputType([string[]])]
163
178
  param(
164
179
  [Parameter(Mandatory)]
165
180
  [AllowEmptyString()]
166
181
  [string] $Prompt
167
182
  )
168
183
 
169
- if (-not $Prompt) {
170
- return $null
171
- }
172
-
173
- $pattern = 'docs[\\/]+features[\\/]+active[\\/]+[^\s"''`]+'
174
- $matchList = [regex]::Matches($Prompt, $pattern)
175
- if ($matchList.Count -eq 0) {
176
- return $null
177
- }
178
-
179
- $unique = @{}
180
- foreach ($m in $matchList) {
181
- $normalized = ($m.Value -replace '\\', '/').TrimEnd('/')
182
- $unique[$normalized] = $true
183
- }
184
-
185
- $candidates = @(@($unique.Keys) | Sort-Object -Property Length -Descending)
186
- return (Get-ParallelCohortBarrierFolderBasename -FolderPath $candidates[0])
184
+ return [string[]]@(Find-FeatureFolderCandidate -Text $Prompt)
187
185
  }
188
186
 
189
187
  function Get-ParallelCohortBarrierAllowDecision {
@@ -230,11 +228,13 @@ function Invoke-ParallelCohortBarrierDecision {
230
228
  param(
231
229
  [string] $ToolInputRaw
232
230
  )
231
+ $dependencyDecision = Get-HookDependencyFailureDecision -HookEvent PreToolUse -ReasonPrefix 'PARALLEL_COHORT_BARRIER_BLOCKED:'
232
+ if ($null -ne $dependencyDecision) { return $dependencyDecision }
233
233
 
234
- # A failed worktree-resolution import denies before any other logic (issue #690).
234
+ # A failed dependency import denies before any other logic (issue #565).
235
235
  if ($script:ParallelCohortBarrierResolutionImportFailure) {
236
236
  return Get-ParallelCohortBarrierBlockDecision -Reason (
237
- "PARALLEL_COHORT_BARRIER_BLOCKED: the worktree-resolution module '$($script:ParallelCohortBarrierResolutionImportFailure)' " +
237
+ "PARALLEL_COHORT_BARRIER_BLOCKED: the dependency '$($script:ParallelCohortBarrierResolutionImportFailure)' " +
238
238
  'failed to import, so the parallel checkpoint that governs this delegation cannot be located; the gate fails closed.')
239
239
  }
240
240
 
@@ -262,8 +262,8 @@ function Invoke-ParallelCohortBarrierDecision {
262
262
  return Get-ParallelCohortBarrierBlockDecision -Reason "PARALLEL_COHORT_BARRIER_BLOCKED: $($target.ReasonCode): $($target.Detail)"
263
263
  }
264
264
 
265
- $featureFolder = Find-ParallelCohortBarrierFeatureFolderFromPrompt -Prompt $prompt
266
- if (-not $featureFolder) {
265
+ $candidates = @(Find-ParallelCohortBarrierFeatureFolderFromPrompt -Prompt $prompt)
266
+ if ($candidates.Count -eq 0) {
267
267
  return Get-ParallelCohortBarrierBlockDecision -Reason 'PARALLEL_COHORT_BARRIER_BLOCKED: a parallel-mode orchestrator delegation must reference the target item feature folder path (docs/features/active/<folder>) in the prompt so its conflict edges and cohort position can be verified.'
268
268
  }
269
269
 
@@ -277,6 +277,18 @@ function Invoke-ParallelCohortBarrierDecision {
277
277
  }
278
278
  }
279
279
 
280
+ # The target is selected among the cited candidates (issue #565). The canonical
281
+ # issue-number line breaks a tie only when it names exactly one number.
282
+ $records = if ($null -ne $checkpoint -and @($checkpoint.PSObject.Properties.Name) -contains 'items') { @($checkpoint.items) } else { @() }
283
+ $selectionArguments = @{ Records = $records; Candidate = $candidates }
284
+ $declared = Find-WorktreeItemIssueSignal -Text $prompt
285
+ if (@($declared).Count -eq 1) { $selectionArguments['DeclaredIssueNumber'] = [int]@($declared)[0] }
286
+ $selection = Select-FeatureFolderTarget @selectionArguments
287
+ if ($selection.Status -eq 'Ambiguous') {
288
+ return Get-ParallelCohortBarrierBlockDecision -Reason "PARALLEL_COHORT_BARRIER_BLOCKED: $($selection.Detail)."
289
+ }
290
+ $featureFolder = $selection.Basename
291
+
280
292
  $itemRecord = Find-ParallelCohortBarrierItemRecord -Checkpoint $checkpoint -FeatureFolder $featureFolder
281
293
  if (Test-ParallelCohortBarrierClear -Checkpoint $checkpoint -ItemRecord $itemRecord) {
282
294
  return Get-ParallelCohortBarrierAllowDecision
@@ -327,5 +339,8 @@ function Invoke-ParallelCohortBarrierEntryPoint {
327
339
  if ($MyInvocation.InvocationName -eq '.') {
328
340
  return
329
341
  }
342
+ if ($script:HookDependencyGuardLoadFailed) { [Console]::Error.WriteLine('PARALLEL_COHORT_BARRIER_BLOCKED: hook-dependency-guard.ps1 failed to load; the gate fails closed.'); exit 2 }
343
+ $dependencyDecision = Get-HookDependencyFailureDecision -HookEvent PreToolUse -ReasonPrefix 'PARALLEL_COHORT_BARRIER_BLOCKED:'
344
+ if ($null -ne $dependencyDecision) { $dependencyDecision | ConvertTo-Json -Compress -Depth 5 | Write-Output; exit 0 }
330
345
 
331
346
  exit (Invoke-ParallelCohortBarrierEntryPoint)
@@ -8,13 +8,14 @@
8
8
  parallel-mode kickoff marker defined in the "Parallel-Mode Kickoff Parameter" section
9
9
  of .claude/skills/parallel-orchestrate/SKILL.md, matched byte-for-byte (ordinal).
10
10
 
11
- Decision procedure: resolve the target item's feature folder from the prompt by scanning
12
- for a docs/features/active/<token> path, the shape the parallel kickoff contract emits
13
- for exactly this purpose (adapted from enforce-epic-wave-barrier.ps1's
14
- Find-EpicWaveBarrierFeatureFolderFromPrompt: longest match wins, a .md-suffixed match
15
- uses its parent directory); read the parallel checkpoint and locate the items[] record
16
- whose feature_folder basename matches; derive which item keys have an unresolved latest
17
- drift event; deny with PARALLEL_DRIFT_GATE_BLOCKED when the resolved item is one of them
11
+ Decision procedure: collect the cited feature-folder candidates with the shared resolver
12
+ (feature-folder-resolution.ps1, issue #565), which truncates every docs/features/active/
13
+ path to its feature-folder segment; read the parallel checkpoint and select the target
14
+ among the candidates with Select-FeatureFolderTarget, using the canonical issue-number
15
+ line as a tie-break when it names exactly one number and denying an unresolved tie as
16
+ ambiguous; locate the items[] record whose feature_folder basename matches the selected
17
+ basename, which is also the folder the finding probe inspects; derive which item keys
18
+ have an unresolved latest drift event; deny with PARALLEL_DRIFT_GATE_BLOCKED when the resolved item is one of them
18
19
  and no synthetic Blocking finding file dated at or after that item's latest drift event has
19
20
  been written. Allowed: a non-feature-review target, a prompt without the marker, a resolved
20
21
  latest event, and an unresolved event whose finding file is dated at or after it, so the
@@ -50,8 +51,10 @@
50
51
  ambiguous target denies after the subagent and marker filter and before the folder check.
51
52
 
52
53
  .NOTES
53
- PowerShell 7+. Depends on WorktreeRunResolution.psm1 (issue #690), imported inside a
54
- guard: a failed import is recorded and the decision denies naming the module. Both read
54
+ PowerShell 7+. Depends on WorktreeItemResolution.psm1 and WorktreeRunResolution.psm1
55
+ (issue #690) and the pure sibling feature-folder-resolution.ps1 (issue #565), each
56
+ loaded inside a guard: the first failure is recorded and the decision denies naming
57
+ the dependency. Both read
55
58
  boundaries -- the checkpoint read and the finding-file existence check -- are injectable
56
59
  wrapper functions, so tests mock them without writing temporary files.
57
60
 
@@ -65,23 +68,27 @@
65
68
  #>
66
69
  [CmdletBinding()]
67
70
  param()
71
+ $script:HookDependencyGuardLoadFailed = $false; try { . (Join-Path $PSScriptRoot 'hook-dependency-guard.ps1') } catch { $script:HookDependencyGuardLoadFailed = $true }
68
72
 
69
73
 
70
- Import-Module (Join-Path $PSScriptRoot '../lib/hook-payload/HookPayload.psm1') -Force
74
+ try { Import-Module (Join-Path $PSScriptRoot '../lib/hook-payload/HookPayload.psm1') -Force -ErrorAction Stop } catch { Add-HookDependencyFailure -Name 'HookPayload.psm1' -ErrorRecord $_ }
71
75
 
72
- # Import guard (issue #690): a failed import denies instead of failing open.
76
+ try { Import-Module (Join-Path $PSScriptRoot '../lib/worktree-resolution/WorktreeItemResolution.psm1') -Force -ErrorAction Stop } catch { Add-HookDependencyFailure -Name 'WorktreeItemResolution.psm1' -ErrorRecord $_ }
77
+ try { Import-Module (Join-Path $PSScriptRoot '../lib/worktree-resolution/WorktreeRunResolution.psm1') -Force -ErrorAction Stop } catch { Add-HookDependencyFailure -Name 'WorktreeRunResolution.psm1' -ErrorRecord $_ }
73
78
  $script:ParallelDriftGateResolutionImportFailure = $null
79
+
80
+ # Shared feature-folder resolution (issue #565). Guarded so a failed dot-source denies
81
+ # rather than failing open; an earlier recorded failure is kept.
74
82
  try {
75
- Import-Module (Join-Path $PSScriptRoot '../lib/worktree-resolution/WorktreeRunResolution.psm1') -Force -ErrorAction Stop
83
+ . (Join-Path $PSScriptRoot 'feature-folder-resolution.ps1')
76
84
  }
77
85
  catch {
78
- $script:ParallelDriftGateResolutionImportFailure = 'WorktreeRunResolution.psm1'
86
+ if (-not $script:ParallelDriftGateResolutionImportFailure) { $script:ParallelDriftGateResolutionImportFailure = 'feature-folder-resolution.ps1' }
79
87
  }
80
88
 
81
89
  # Dot-source the shape-and-derivation helpers. Guarded so a missing file produces a clear error
82
90
  # and so dot-sourcing this hook in tests loads the helpers too.
83
- $script:ParallelDriftGateHelpersPath = Join-Path $PSScriptRoot 'enforce-parallel-drift-gate-helpers.ps1'
84
- . $script:ParallelDriftGateHelpersPath
91
+ try { . (Join-Path $PSScriptRoot 'enforce-parallel-drift-gate-helpers.ps1') } catch { Add-HookDependencyFailure -Name 'enforce-parallel-drift-gate-helpers.ps1' -ErrorRecord $_ }
85
92
 
86
93
  $script:ParallelModeMarker = 'Parallel mode: true'
87
94
  $script:ReviewSubagentType = 'feature-review'
@@ -209,32 +216,16 @@ function Test-ParallelDriftFindingPresent {
209
216
  function Find-ParallelDriftGateFeatureFolderFromPrompt {
210
217
  <#
211
218
  .SYNOPSIS
212
- Scan a delegation prompt for docs/features/active/<...> path tokens and return the
213
- longest unique match's basename, or $null when none is found.
219
+ Return the distinct feature-folder basenames cited in a delegation prompt, in
220
+ first-occurrence order, through the shared Find-FeatureFolderCandidate (issue #565).
221
+ A nested research/ or evidence/ citation names its own folder. No output when no
222
+ folder is cited; selection among several is made by Select-FeatureFolderTarget.
214
223
  #>
215
224
  [CmdletBinding()]
216
- [OutputType([string])]
225
+ [OutputType([string[]])]
217
226
  param([Parameter(Mandatory)][AllowEmptyString()][string] $Prompt)
218
227
 
219
- if (-not $Prompt) {
220
- return $null
221
- }
222
- $matchList = [regex]::Matches($Prompt, 'docs[\\/]+features[\\/]+active[\\/]+[^\s"''`]+')
223
- if ($matchList.Count -eq 0) {
224
- return $null
225
- }
226
-
227
- # Collect distinct normalized tokens so the longest, most specific one can be selected.
228
- $unique = @{}
229
- foreach ($found in $matchList) {
230
- $unique[($found.Value -replace '\\', '/').TrimEnd('/')] = $true
231
- }
232
-
233
- $best = @(@($unique.Keys) | Sort-Object -Property Length -Descending)[0]
234
- if ($best -match '\.md$') {
235
- $best = $best -replace '/[^/]+\.md$', ''
236
- }
237
- return ($best -split '/')[-1]
228
+ return [string[]]@(Find-FeatureFolderCandidate -Text $Prompt)
238
229
  }
239
230
 
240
231
  function Find-ParallelDriftGateItemRecord {
@@ -318,11 +309,13 @@ function Invoke-ParallelDriftGateDecision {
318
309
  [AllowEmptyString()]
319
310
  [string] $ToolInputRaw
320
311
  )
312
+ $dependencyDecision = Get-HookDependencyFailureDecision -HookEvent PreToolUse -ReasonPrefix 'PARALLEL_DRIFT_GATE_BLOCKED:'
313
+ if ($null -ne $dependencyDecision) { return $dependencyDecision }
321
314
 
322
- # A failed worktree-resolution import denies before any other logic (issue #690).
315
+ # A failed dependency import denies before any other logic (issue #565).
323
316
  if ($script:ParallelDriftGateResolutionImportFailure) {
324
317
  return Get-ParallelDriftGateBlockDecision -Reason (
325
- "PARALLEL_DRIFT_GATE_BLOCKED: the worktree-resolution module '$($script:ParallelDriftGateResolutionImportFailure)' " +
318
+ "PARALLEL_DRIFT_GATE_BLOCKED: the dependency '$($script:ParallelDriftGateResolutionImportFailure)' " +
326
319
  'failed to import, so the parallel checkpoint that governs this review cannot be located; the gate fails closed.')
327
320
  }
328
321
 
@@ -352,8 +345,8 @@ function Invoke-ParallelDriftGateDecision {
352
345
  return Get-ParallelDriftGateBlockDecision -Reason "PARALLEL_DRIFT_GATE_BLOCKED: $($target.ReasonCode): $($target.Detail)"
353
346
  }
354
347
 
355
- $featureFolder = Find-ParallelDriftGateFeatureFolderFromPrompt -Prompt $prompt
356
- if (-not $featureFolder) {
348
+ $candidates = @(Find-ParallelDriftGateFeatureFolderFromPrompt -Prompt $prompt)
349
+ if ($candidates.Count -eq 0) {
357
350
  return Get-ParallelDriftGateBlockDecision -Reason 'PARALLEL_DRIFT_GATE_BLOCKED: a parallel-mode feature-review delegation must reference the target item feature folder in the prompt so its drift state can be verified.'
358
351
  }
359
352
 
@@ -367,8 +360,19 @@ function Invoke-ParallelDriftGateDecision {
367
360
  }
368
361
  }
369
362
  if ($null -eq $checkpoint) {
370
- return Get-ParallelDriftGateBlockDecision -Reason "PARALLEL_DRIFT_GATE_BLOCKED: the parallel checkpoint 'artifacts/orchestration/parallel-orchestrator-state.json' in worktree '$($target.WorktreeRoot)' is missing or unreadable, so the drift state of '$featureFolder' cannot be verified."
363
+ return Get-ParallelDriftGateBlockDecision -Reason "PARALLEL_DRIFT_GATE_BLOCKED: the parallel checkpoint 'artifacts/orchestration/parallel-orchestrator-state.json' in worktree '$($target.WorktreeRoot)' is missing or unreadable, so the drift state of '$($candidates -join ', ')' cannot be verified."
364
+ }
365
+
366
+ # The target is selected among the cited candidates (issue #565). The canonical
367
+ # issue-number line breaks a tie only when it names exactly one number.
368
+ $selectionArguments = @{ Records = @($checkpoint.items | Where-Object { $null -ne $_ }); Candidate = $candidates }
369
+ $declared = Find-WorktreeItemIssueSignal -Text $prompt
370
+ if (@($declared).Count -eq 1) { $selectionArguments['DeclaredIssueNumber'] = [int]@($declared)[0] }
371
+ $selection = Select-FeatureFolderTarget @selectionArguments
372
+ if ($selection.Status -eq 'Ambiguous') {
373
+ return Get-ParallelDriftGateBlockDecision -Reason "PARALLEL_DRIFT_GATE_BLOCKED: $($selection.Detail)."
371
374
  }
375
+ $featureFolder = $selection.Basename
372
376
 
373
377
  $item = Find-ParallelDriftGateItemRecord -Checkpoint $checkpoint -FeatureFolder $featureFolder
374
378
  if ($null -eq $item -or -not (Test-ParallelDriftGateItemKey -Value $item.issue_num)) {
@@ -440,5 +444,8 @@ function Invoke-ParallelDriftGateEntryPoint {
440
444
  if ($MyInvocation.InvocationName -eq '.') {
441
445
  return
442
446
  }
447
+ if ($script:HookDependencyGuardLoadFailed) { [Console]::Error.WriteLine('PARALLEL_DRIFT_GATE_BLOCKED: hook-dependency-guard.ps1 failed to load; the gate fails closed.'); exit 2 }
448
+ $dependencyDecision = Get-HookDependencyFailureDecision -HookEvent PreToolUse -ReasonPrefix 'PARALLEL_DRIFT_GATE_BLOCKED:'
449
+ if ($null -ne $dependencyDecision) { $dependencyDecision | ConvertTo-Json -Compress -Depth 5 | Write-Output; exit 0 }
443
450
 
444
451
  exit (Invoke-ParallelDriftGateEntryPoint)