@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
@@ -0,0 +1,311 @@
1
+ <#
2
+ .SYNOPSIS
3
+ Checkpoint resolution and Layer 2 decision helpers for validate-orchestrator-output.ps1 (issues #787, #840).
4
+
5
+ .DESCRIPTION
6
+ Dot-sourced by validate-orchestrator-output.ps1. Resolves the run checkpoint that a
7
+ SubagentStop validation reads through the exported functions of
8
+ WorktreeRunResolution.psm1 and Get-WorktreeItemLiveRoot (WorktreeItemResolution.psm1)
9
+ only, so the hook evaluates the checkpoint of the run that stopped rather than whatever
10
+ file sits at a session-relative path. The payload cwd is never used as a target selector.
11
+
12
+ Per artifact type: orchestrator-state resolves the enclosing worktree of the session
13
+ root; epic-orchestrator-state and parallel-orchestrator-state resolve from the
14
+ integration_branch: or parallel_slug: literal in the agent output, and otherwise from the
15
+ single distinct value recorded by the live worktrees' run checkpoints. A bound
16
+ -CheckpointPath is a repository-relative leaf that must compose the canonical checkpoint
17
+ path beneath the resolved root.
18
+
19
+ Reads no file except through Get-WorktreeRunCheckpointText and the
20
+ Test-OrchestratorOutputRunbookFile seam. Starts no process and invokes no Python.
21
+ #>
22
+
23
+ # The run kind each supported artifact type resolves as.
24
+ $script:OrchestratorOutputRunKind = @{
25
+ 'orchestrator-state' = 'item'
26
+ 'epic-orchestrator-state' = 'epic'
27
+ 'parallel-orchestrator-state' = 'parallel'
28
+ }
29
+
30
+ # Reason codes. The first two equal the WorktreeResolution.psm1 accessor values, which the
31
+ # sibling suite asserts, because this file calls no accessor of that module.
32
+ $script:OrchestratorOutputAmbiguousReasonCode = 'TARGET_WORKTREE_AMBIGUOUS'
33
+ $script:OrchestratorOutputNoTargetReasonCode = 'TARGET_WORKTREE_NOT_DERIVABLE'
34
+ $script:OrchestratorOutputMismatchReasonCode = 'CHECKPOINT_PATH_MISMATCH'
35
+
36
+ # The fixed instruction that follows Layer 2 violation lines, and the unevaluable token.
37
+ $script:OrchestratorOutputHaltInstruction = 'orchestrator hook: the lines above record a wave-barrier ordering violation in the epic checkpoint that this agent cannot clear. Report them to the operator and halt.'
38
+ $script:OrchestratorOutputUnevaluableToken = 'EPIC_WAVE_BARRIER_UNEVALUABLE:'
39
+
40
+ function ConvertTo-OrchestratorOutputResolution {
41
+ <#
42
+ .SYNOPSIS
43
+ Build the resolution result object.
44
+ .DESCRIPTION
45
+ Returns an object with exactly Resolved, CheckpointPath, WorktreeRoot, Status,
46
+ ReasonCode, and Detail; a value that is not supplied is $null.
47
+ #>
48
+ [CmdletBinding()]
49
+ [OutputType([pscustomobject])]
50
+ param(
51
+ [Parameter(Mandatory = $true)] [bool] $Resolved,
52
+ [AllowNull()] [object] $CheckpointPath = $null,
53
+ [AllowNull()] [object] $WorktreeRoot = $null,
54
+ [Parameter(Mandatory = $true)] [string] $Status,
55
+ [AllowNull()] [object] $ReasonCode = $null,
56
+ [Parameter(Mandatory = $true)] [AllowEmptyString()] [string] $Detail
57
+ )
58
+
59
+ return [pscustomobject]@{
60
+ Resolved = $Resolved
61
+ CheckpointPath = $CheckpointPath
62
+ WorktreeRoot = $WorktreeRoot
63
+ Status = $Status
64
+ ReasonCode = $ReasonCode
65
+ Detail = $Detail
66
+ }
67
+ }
68
+
69
+ function Test-OrchestratorOutputCheckpointLeafShape {
70
+ <#
71
+ .SYNOPSIS
72
+ Check that a -CheckpointPath value is a non-empty repository-relative leaf.
73
+ .DESCRIPTION
74
+ Pure. Normalizes the value (trim, forward slashes, no repeated separator, no leading
75
+ ./) and returns @{ Ok; Leaf; Detail }. A blank, rooted, or parent-escaping value is
76
+ not Ok.
77
+ #>
78
+ [CmdletBinding()]
79
+ [OutputType([hashtable])]
80
+ param(
81
+ [Parameter(Mandatory = $true)] [AllowEmptyString()] [string] $CheckpointPath
82
+ )
83
+
84
+ $leaf = ($CheckpointPath.Trim() -replace '\\', '/') -replace '/{2,}', '/'
85
+ while ($leaf.StartsWith('./')) { $leaf = $leaf.Substring(2) }
86
+
87
+ # Decision order: blank first, then rooted, then a .. segment; each names the value.
88
+ if ([string]::IsNullOrWhiteSpace($leaf)) {
89
+ return @{ Ok = $false; Leaf = $null; Detail = 'the -CheckpointPath value is empty' }
90
+ }
91
+ if ($leaf -match '^([A-Za-z]:|/)') {
92
+ return @{ Ok = $false; Leaf = $null; Detail = ("the -CheckpointPath value '{0}' is rooted; it must be a repository-relative path" -f $CheckpointPath) }
93
+ }
94
+ if (@($leaf -split '/') -contains '..') {
95
+ return @{ Ok = $false; Leaf = $null; Detail = ("the -CheckpointPath value '{0}' escapes the worktree root" -f $CheckpointPath) }
96
+ }
97
+ return @{ Ok = $true; Leaf = $leaf; Detail = $null }
98
+ }
99
+
100
+ function Test-OrchestratorOutputCheckpointLeaf {
101
+ <#
102
+ .SYNOPSIS
103
+ Cross-check a -CheckpointPath leaf against the canonical checkpoint of a run kind.
104
+ .DESCRIPTION
105
+ Composes the leaf beneath the resolved root and requires an ordinal match with
106
+ Get-WorktreeRunCheckpointPath for the kind. Returns @{ Ok; CanonicalPath; Detail }.
107
+ #>
108
+ [CmdletBinding()]
109
+ [OutputType([hashtable])]
110
+ param(
111
+ [Parameter(Mandatory = $true)] [AllowEmptyString()] [string] $CheckpointPath,
112
+ [Parameter(Mandatory = $true)] [ValidateSet('epic', 'parallel', 'item')] [string] $Kind,
113
+ [Parameter(Mandatory = $true)] [string] $WorktreeRoot
114
+ )
115
+
116
+ $shape = Test-OrchestratorOutputCheckpointLeafShape -CheckpointPath $CheckpointPath
117
+ if (-not $shape.Ok) { return @{ Ok = $false; CanonicalPath = $null; Detail = $shape.Detail } }
118
+ $canonical = Get-WorktreeRunCheckpointPath -Kind $Kind -WorktreeRoot $WorktreeRoot
119
+ $composed = (($WorktreeRoot.Trim() -replace '\\', '/').TrimEnd('/')) + '/' + $shape.Leaf
120
+ if ($composed -ceq $canonical) { return @{ Ok = $true; CanonicalPath = $canonical; Detail = $null } }
121
+ return @{
122
+ Ok = $false
123
+ CanonicalPath = $canonical
124
+ Detail = ("the -CheckpointPath value '{0}' composes '{1}' beneath the resolved root, which is not the canonical {2} checkpoint '{3}'" -f
125
+ $CheckpointPath, $composed, $Kind, $canonical)
126
+ }
127
+ }
128
+
129
+ function Find-OrchestratorOutputRunSignalValue {
130
+ <#
131
+ .SYNOPSIS
132
+ Collect the distinct run identity values recorded by the live worktrees' checkpoints.
133
+ .DESCRIPTION
134
+ For kind epic, the integration_branch of every checkpoint with route_id epic; for
135
+ kind parallel, the parallel_slug of every checkpoint with route_id parallel. Blank,
136
+ unparseable, non-object, and off-route checkpoints are skipped. Values are distinct
137
+ under ordinal comparison and kept in discovery order.
138
+ #>
139
+ [CmdletBinding()]
140
+ [OutputType([string[]], [object[]])]
141
+ param(
142
+ [Parameter(Mandatory = $true)] [ValidateSet('epic', 'parallel')] [string] $Kind,
143
+ [Parameter(Mandatory = $true)] [string] $SessionRoot
144
+ )
145
+
146
+ $field = if ($Kind -eq 'epic') { 'integration_branch' } else { 'parallel_slug' }
147
+ $route = if ($Kind -eq 'epic') { 'epic' } else { 'parallel' }
148
+ $values = [System.Collections.Generic.List[string]]::new()
149
+ # The seam returns its array as one object, so it is assigned before it is iterated.
150
+ $liveRoots = Get-WorktreeItemLiveRoot -SessionRoot $SessionRoot
151
+ foreach ($root in $liveRoots) {
152
+ if ([string]::IsNullOrWhiteSpace($root)) { continue }
153
+ $text = Get-WorktreeRunCheckpointText -Path (Get-WorktreeRunCheckpointPath -Kind $Kind -WorktreeRoot $root)
154
+ if ([string]::IsNullOrWhiteSpace($text)) { continue }
155
+ try { $parsed = ConvertFrom-Json -InputObject $text -NoEnumerate -ErrorAction Stop } catch { continue }
156
+ if ($parsed -isnot [System.Management.Automation.PSCustomObject]) { continue }
157
+ $names = @($parsed.PSObject.Properties.Name)
158
+ if (-not ($names -contains 'route_id') -or ([string]$parsed.route_id -cne $route)) { continue }
159
+ if (-not ($names -contains $field)) { continue }
160
+ $value = $parsed.$field
161
+ if ($value -isnot [string] -or [string]::IsNullOrWhiteSpace($value)) { continue }
162
+ if (-not $values.Contains($value)) { $values.Add($value) }
163
+ }
164
+ return , $values.ToArray()
165
+ }
166
+
167
+ function Resolve-OrchestratorOutputCheckpointPath {
168
+ <#
169
+ .SYNOPSIS
170
+ Resolve the absolute run checkpoint path for a SubagentStop validation.
171
+ .DESCRIPTION
172
+ Returns the ConvertTo-OrchestratorOutputResolution object. Resolved is $true only
173
+ when exactly one target resolves and the -CheckpointPath leaf composes its canonical
174
+ checkpoint path; otherwise Status, ReasonCode, and Detail name the failure. A
175
+ rejected -CheckpointPath is detected before any resolver call.
176
+ .PARAMETER ArtifactType
177
+ orchestrator-state, epic-orchestrator-state, or parallel-orchestrator-state.
178
+ .PARAMETER CheckpointPath
179
+ The bound repository-relative checkpoint leaf.
180
+ .PARAMETER AgentOutput
181
+ The agent's final output text, scanned for the run identity literals.
182
+ .PARAMETER SessionRoot
183
+ The calling process's path, used only to find the repository.
184
+ #>
185
+ [CmdletBinding()]
186
+ [OutputType([pscustomobject])]
187
+ param(
188
+ [Parameter(Mandatory = $true)] [AllowEmptyString()] [string] $ArtifactType,
189
+ [Parameter(Mandatory = $true)] [AllowEmptyString()] [string] $CheckpointPath,
190
+ [Parameter(Mandatory = $true)] [AllowEmptyString()] [string] $AgentOutput,
191
+ [Parameter(Mandatory = $true)] [string] $SessionRoot
192
+ )
193
+
194
+ if (-not $script:OrchestratorOutputRunKind.ContainsKey($ArtifactType)) {
195
+ return (ConvertTo-OrchestratorOutputResolution -Resolved $false -Status 'NoTarget' -ReasonCode $script:OrchestratorOutputNoTargetReasonCode -Detail (
196
+ "unsupported artifact type '{0}'; supported types: orchestrator-state, epic-orchestrator-state, parallel-orchestrator-state" -f $ArtifactType))
197
+ }
198
+ $kind = $script:OrchestratorOutputRunKind[$ArtifactType]
199
+
200
+ # A malformed leaf is rejected before any resolver call, so nothing is read for it.
201
+ $shape = Test-OrchestratorOutputCheckpointLeafShape -CheckpointPath $CheckpointPath
202
+ if (-not $shape.Ok) {
203
+ return (ConvertTo-OrchestratorOutputResolution -Resolved $false -Status 'Rejected' -ReasonCode $script:OrchestratorOutputMismatchReasonCode -Detail $shape.Detail)
204
+ }
205
+
206
+ # Routing table: item resolves the session worktree; epic and parallel take the agent
207
+ # output's literal first and fall back to discovery over the live run checkpoints.
208
+ if ($kind -eq 'item') {
209
+ $target = Resolve-WorktreeOperandTarget -Path '' -SessionRoot $SessionRoot
210
+ }
211
+ else {
212
+ $signal = Find-WorktreeRunIdentitySignal -Text $AgentOutput
213
+ $field = if ($kind -eq 'epic') { 'integration_branch' } else { 'parallel_slug' }
214
+ $identity = if ($kind -eq 'epic') { $signal.IntegrationBranch } else { $signal.ParallelSlug }
215
+ if ([string]::IsNullOrWhiteSpace($identity)) {
216
+ $discovered = [System.Collections.Generic.List[string]]::new()
217
+ foreach ($value in (Find-OrchestratorOutputRunSignalValue -Kind $kind -SessionRoot $SessionRoot)) { $discovered.Add([string]$value) }
218
+ if ($discovered.Count -gt 1) {
219
+ $detail = ("the {0} checkpoints of live worktrees record {1} distinct {2} values ({3}), and the agent output names no {2}: value" -f
220
+ $kind, $discovered.Count, $field, ($discovered -join ', '))
221
+ return (ConvertTo-OrchestratorOutputResolution -Resolved $false -Status 'Ambiguous' -ReasonCode $script:OrchestratorOutputAmbiguousReasonCode -Detail $detail)
222
+ }
223
+ $identity = if ($discovered.Count -eq 1) { $discovered[0] } else { '' }
224
+ }
225
+ $target = if ($kind -eq 'epic') {
226
+ Resolve-WorktreeEpicTarget -IntegrationBranch $identity -EpicSlug $signal.EpicSlug -SessionRoot $SessionRoot
227
+ }
228
+ else {
229
+ Resolve-WorktreeParallelTarget -ParallelSlug $identity -SessionRoot $SessionRoot
230
+ }
231
+ }
232
+
233
+ if ($target.Status -in @('NoTarget', 'Ambiguous')) {
234
+ return (ConvertTo-OrchestratorOutputResolution -Resolved $false -Status $target.Status -ReasonCode $target.ReasonCode -Detail $target.Detail)
235
+ }
236
+ $leaf = Test-OrchestratorOutputCheckpointLeaf -CheckpointPath $CheckpointPath -Kind $kind -WorktreeRoot $target.WorktreeRoot
237
+ if (-not $leaf.Ok) {
238
+ return (ConvertTo-OrchestratorOutputResolution -Resolved $false -Status 'Rejected' -ReasonCode $script:OrchestratorOutputMismatchReasonCode -Detail $leaf.Detail)
239
+ }
240
+ return (ConvertTo-OrchestratorOutputResolution -Resolved $true -CheckpointPath $leaf.CanonicalPath -WorktreeRoot $target.WorktreeRoot -Status $target.Status -Detail $target.Detail)
241
+ }
242
+
243
+ function Resolve-OrchestratorOutputRunbookPath {
244
+ <#
245
+ .SYNOPSIS
246
+ Place a runbook_path beneath the resolved worktree root.
247
+ .DESCRIPTION
248
+ Pure. A rooted value is returned with forward slashes; a relative value has any
249
+ leading ./ removed and is joined beneath the root.
250
+ #>
251
+ [CmdletBinding()]
252
+ [OutputType([string])]
253
+ param(
254
+ [Parameter(Mandatory = $true)] [string] $WorktreeRoot,
255
+ [Parameter(Mandatory = $true)] [AllowEmptyString()] [string] $RunbookPath
256
+ )
257
+
258
+ $path = ([string]$RunbookPath).Trim() -replace '\\', '/'
259
+ if ($path -match '^([A-Za-z]:/|/)') { return $path }
260
+ while ($path.StartsWith('./')) { $path = $path.Substring(2) }
261
+ return ((($WorktreeRoot.Trim() -replace '\\', '/').TrimEnd('/')) + '/' + $path.TrimStart('/'))
262
+ }
263
+
264
+ function Test-OrchestratorOutputRunbookFile {
265
+ <#
266
+ .SYNOPSIS
267
+ The runbook existence seam: $true when the path is an existing file.
268
+ #>
269
+ [CmdletBinding()]
270
+ [OutputType([bool])]
271
+ param(
272
+ [Parameter(Mandatory = $true)] [string] $Path
273
+ )
274
+
275
+ return (Test-Path -LiteralPath $Path -PathType Leaf)
276
+ }
277
+
278
+ function Get-OrchestratorOutputWaveBarrierDecision {
279
+ <#
280
+ .SYNOPSIS
281
+ Run the Layer 2 wave-barrier ordering check on epic checkpoint text.
282
+ .DESCRIPTION
283
+ Returns @{ Ok; Message } on success and @{ Ok; Repairable; Message } on a block, with
284
+ Repairable set to $false on every block (the agent cannot clear it, so it blocks once under
285
+ the re-entry policy of issue #903). Violation lines are surfaced unwrapped and followed by
286
+ the fixed report-and-halt instruction. A failed port import, an
287
+ EPIC_WAVE_BARRIER_UNEVALUABLE: error, or any other port failure blocks with a
288
+ message that starts with EPIC_WAVE_BARRIER_UNEVALUABLE:.
289
+ #>
290
+ [CmdletBinding()]
291
+ [OutputType([hashtable])]
292
+ param(
293
+ [Parameter(Mandatory = $true)] [AllowEmptyString()] [string] $CheckpointText
294
+ )
295
+
296
+ $lines = [System.Collections.Generic.List[string]]::new()
297
+ try {
298
+ foreach ($line in (Get-OrchestratorStateEpicWaveBarrierError -CheckpointText $CheckpointText)) { $lines.Add([string]$line) }
299
+ }
300
+ catch {
301
+ $message = $_.Exception.Message
302
+ if ($message.StartsWith($script:OrchestratorOutputUnevaluableToken, [System.StringComparison]::Ordinal)) {
303
+ return @{ Ok = $false; Repairable = $false; Message = $message }
304
+ }
305
+ return @{ Ok = $false; Repairable = $false; Message = ('{0} the wave-barrier ordering check failed: {1}' -f $script:OrchestratorOutputUnevaluableToken, $message) }
306
+ }
307
+
308
+ if ($lines.Count -eq 0) { return @{ Ok = $true; Message = $null } }
309
+ $lines.Add($script:OrchestratorOutputHaltInstruction)
310
+ return @{ Ok = $false; Repairable = $false; Message = ($lines -join "`n") }
311
+ }
@@ -0,0 +1,170 @@
1
+ <#
2
+ .SYNOPSIS
3
+ Routing-contract dispatch for the orchestrator SubagentStop hook validate-orchestrator-output.ps1 (issue #903).
4
+
5
+ .DESCRIPTION
6
+ Dot-sourced by validate-orchestrator-output.ps1 through a guarded load whose catch records the
7
+ failure with Add-HookDependencyFailure, so a missing or broken copy of this file blocks the
8
+ hook instead of failing open. It defines Test-OrchestratorCheckpointStructure and
9
+ Invoke-RoutingContractValidation, moved unchanged from the main hook file to keep that file
10
+ under the 500-line cap.
11
+
12
+ The default Invoker of Invoke-RoutingContractValidation resolves
13
+ ../lib/orchestrator-state/OrchestratorStateCompletion.psm1 from $PSScriptRoot, which is the
14
+ same directory for this dot-sourced file as for the main hook. The file starts no process
15
+ and invokes no Python.
16
+ #>
17
+
18
+ function Test-OrchestratorCheckpointStructure {
19
+ <#
20
+ .SYNOPSIS
21
+ Type-scoped structural check for the epic and parallel checkpoint types.
22
+ .DESCRIPTION
23
+ PD-3 implementation. The Python reference exposes no validation surface for
24
+ `epic-orchestrator-state` or `parallel-orchestrator-state` under this hook's
25
+ flag pair: argparse rejects the pair and exits 2 without running a single
26
+ check, so parity is UNDEFINED in this region. Rather than inherit an
27
+ undefined behavior, this hook defines it: the checkpoint must exist, parse
28
+ as JSON, and have an object root. That is the largest assertion that holds
29
+ for every checkpoint type without importing a schema this hook does not own.
30
+
31
+ Deliberately NOT applied here:
32
+ - the standard-checkpoint REQUIRED_STATE_KEYS presence block, whose key
33
+ set belongs to the standard checkpoint and would produce false
34
+ ROUTING_CONTRACT_BLOCKED verdicts against a well-formed epic or
35
+ parallel checkpoint (defect D-1),
36
+ - the model-routing gate, whose receipts live on the standard checkpoint.
37
+
38
+ The check fails closed: a missing file, unreadable content, invalid JSON, or
39
+ a non-object root all yield ExitCode 1 with the load error as Output.
40
+ .PARAMETER CheckpointPath
41
+ The path to the checkpoint JSON file.
42
+ .OUTPUTS
43
+ System.Collections.Hashtable with keys ExitCode (int, 0 or 1) and Output (string).
44
+ #>
45
+ [CmdletBinding()]
46
+ [OutputType([hashtable])]
47
+ param(
48
+ [Parameter(Mandatory = $true)]
49
+ [string] $CheckpointPath
50
+ )
51
+
52
+ # Get-OrchestratorStateCheckpoint already implements exactly the three
53
+ # structural conditions (exists, parses, object root) and reports each as a
54
+ # fail-closed Error string, so the structural leg reuses it rather than
55
+ # duplicating the load contract.
56
+ $loaded = Get-OrchestratorStateCheckpoint -CheckpointPath $CheckpointPath
57
+ if (-not $loaded.Ok) {
58
+ return @{ ExitCode = 1; Output = $loaded.Error }
59
+ }
60
+
61
+ return @{ ExitCode = 0; Output = '' }
62
+ }
63
+
64
+ function Invoke-RoutingContractValidation {
65
+ <#
66
+ .SYNOPSIS
67
+ Runs the portable routing-contract validation against the on-disk
68
+ checkpoint and reports whether it emitted errors.
69
+ .DESCRIPTION
70
+ Invokes the validation through an injectable scriptblock seam. As of issue
71
+ #475 the default Invoker names no interpreter and starts no subprocess: the
72
+ portable PowerShell path is the ONLY path, so the hook behaves identically
73
+ in this repository and in every destination that received only the
74
+ pushed-down `.claude` pack. The former capability-detection probe and the
75
+ interpreter-subprocess leg it guarded are both gone.
76
+
77
+ The default Invoker dispatches on ArtifactType:
78
+
79
+ orchestrator-state
80
+ the COMPLETE-PARITY completion validation
81
+ (Test-OrchestratorStateCompletionReadiness), a row-by-row port of the
82
+ Python call surface `--require-complete --require-model-routing`.
83
+
84
+ epic-orchestrator-state, parallel-orchestrator-state
85
+ the type-scoped structural check
86
+ (Test-OrchestratorCheckpointStructure): exists, parses as JSON,
87
+ object root. PD-3: this is DEFINED behavior in a region where Python
88
+ parity is UNDEFINED (argparse exit 2, zero checks run). It is a
89
+ design decision, not a deferral. The standard-checkpoint
90
+ REQUIRED_STATE_KEYS block and the model-routing gate are deliberately
91
+ not applied, which is the D-1 fix.
92
+
93
+ anything else
94
+ fail closed, naming the unsupported type. An unrecognized type must
95
+ never read as a clean pass.
96
+
97
+ ArtifactType defaults to 'orchestrator-state' so every existing caller of
98
+ this hook keeps its current behavior.
99
+
100
+ Returns a hashtable with keys:
101
+ - HasErrors: $true only when the validation reported a non-zero exit
102
+ code; $false when it exited 0. The exit code is the sole
103
+ discriminator.
104
+ - ErrorText: the validation's output text, carried through unchanged:
105
+ the error lines on a failure, empty on a clean pass.
106
+ #>
107
+ [CmdletBinding()]
108
+ [OutputType([hashtable])]
109
+ param(
110
+ [Parameter(Mandatory = $true)]
111
+ [string] $CheckpointPath,
112
+
113
+ [Parameter(Mandatory = $false)]
114
+ [string] $ArtifactType = 'orchestrator-state',
115
+
116
+ [Parameter(Mandatory = $false)]
117
+ [scriptblock] $Invoker = {
118
+ param($Path, $Type)
119
+ switch ($Type) {
120
+ 'orchestrator-state' {
121
+ # Import the portable completion module only when its function is not
122
+ # already available, so a repeated call (or a test that pre-imports and
123
+ # mocks the function) does not reload the module and reset the seam.
124
+ if (-not (Get-Command -Name Test-OrchestratorStateCompletionReadiness -ErrorAction SilentlyContinue)) {
125
+ Import-Module (Join-Path $PSScriptRoot '../lib/orchestrator-state/OrchestratorStateCompletion.psm1') -Force
126
+ }
127
+ $portable = Test-OrchestratorStateCompletionReadiness -CheckpointPath $Path
128
+ [pscustomobject]@{
129
+ ExitCode = $portable.ExitCode
130
+ Output = $portable.Output
131
+ }
132
+ }
133
+ { $_ -in @('epic-orchestrator-state', 'parallel-orchestrator-state') } {
134
+ # PD-3: defined fail-closed structural behavior in an
135
+ # undefined-parity region. See Test-OrchestratorCheckpointStructure.
136
+ $structural = Test-OrchestratorCheckpointStructure -CheckpointPath $Path
137
+ [pscustomobject]@{
138
+ ExitCode = $structural.ExitCode
139
+ Output = $structural.Output
140
+ }
141
+ }
142
+ default {
143
+ # Fail closed on an unwired type: an unrecognized artifact type is
144
+ # not a clean pass.
145
+ [pscustomobject]@{
146
+ ExitCode = 1
147
+ Output = "orchestrator hook: unsupported artifact type '$Type'; no validation surface is wired for it. Supported types: orchestrator-state, epic-orchestrator-state, parallel-orchestrator-state."
148
+ }
149
+ }
150
+ }
151
+ }
152
+ )
153
+
154
+ $result = & $Invoker $CheckpointPath $ArtifactType
155
+ $exitCode = 0
156
+ if ($null -ne $result -and ($result.PSObject.Properties.Name -contains 'ExitCode')) {
157
+ $exitCode = [int]$result.ExitCode
158
+ }
159
+ $outputText = ''
160
+ if ($null -ne $result -and ($result.PSObject.Properties.Name -contains 'Output')) {
161
+ $outputText = ([string]$result.Output).Trim()
162
+ }
163
+
164
+ # The exit code is the complete failure discriminator: every dispatch leg
165
+ # returns a non-zero ExitCode with its error text on failure and ExitCode 0
166
+ # with empty Output on a clean pass, so output text must not influence this
167
+ # decision.
168
+ $hasErrors = ($exitCode -ne 0)
169
+ return @{ HasErrors = $hasErrors; ErrorText = $outputText }
170
+ }