@danmoisan/drm-copilot-mcp 1.1.22 → 1.1.24

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 (261) hide show
  1. package/out/mcp-server.js +18758 -12030
  2. package/package.json +1 -1
  3. package/resources/claude-customizations/.claude/agent-memory/orchestrator/MEMORY.md +1 -1
  4. package/resources/claude-customizations/.claude/agent-memory/orchestrator/feedback_test_files_count_against_500_cap.md +4 -4
  5. package/resources/claude-customizations/.claude/agents/csharp-typed-engineer.md +1 -1
  6. package/resources/claude-customizations/.claude/agents/discovery-capability-sentinel.md +34 -0
  7. package/resources/claude-customizations/.claude/agents/feature-review.md +8 -0
  8. package/resources/claude-customizations/.claude/agents/legacy-parity-analyst.md +101 -43
  9. package/resources/claude-customizations/.claude/agents/migration-coverage-reviewer.md +107 -43
  10. package/resources/claude-customizations/.claude/agents/orchestrator.md +1 -1
  11. package/resources/claude-customizations/.claude/agents/parallel-orchestrator.md +60 -6
  12. package/resources/claude-customizations/.claude/agents/parallel-planner.md +21 -1
  13. package/resources/claude-customizations/.claude/agents/powershell-typed-engineer.md +1 -1
  14. package/resources/claude-customizations/.claude/agents/pr-author.md +48 -7
  15. package/resources/claude-customizations/.claude/agents/python-typed-engineer.md +1 -1
  16. package/resources/claude-customizations/.claude/agents/requirements-reconciler.md +117 -42
  17. package/resources/claude-customizations/.claude/agents/runtime-characterization-analyst.md +103 -43
  18. package/resources/claude-customizations/.claude/hooks/discovery-capability-probe.ps1 +102 -0
  19. package/resources/claude-customizations/.claude/hooks/enforce-discovery-artifact-gate.ps1 +69 -194
  20. package/resources/claude-customizations/.claude/hooks/enforce-discovery-planning-gate.ps1 +87 -0
  21. package/resources/claude-customizations/.claude/hooks/enforce-epic-merge-gate-green-ci.ps1 +325 -0
  22. package/resources/claude-customizations/.claude/hooks/enforce-epic-merge-gate.ps1 +29 -7
  23. package/resources/claude-customizations/.claude/hooks/enforce-epic-worktree-removal-gate-resolution.ps1 +23 -10
  24. package/resources/claude-customizations/.claude/hooks/enforce-epic-worktree-removal-gate.ps1 +29 -21
  25. package/resources/claude-customizations/.claude/hooks/enforce-file-size-limit.ps1 +244 -0
  26. package/resources/claude-customizations/.claude/hooks/enforce-model-routing-receipt.ps1 +51 -0
  27. package/resources/claude-customizations/.claude/hooks/enforce-orchestration-preimplementation-gate-epic-scope.ps1 +168 -48
  28. package/resources/claude-customizations/.claude/hooks/enforce-orchestration-preimplementation-gate.ps1 +1 -1
  29. package/resources/claude-customizations/.claude/hooks/enforce-parallel-worktree-removal-gate.ps1 +22 -11
  30. package/resources/claude-customizations/.claude/hooks/enforce-powershell-batch-budget.ps1 +59 -20
  31. package/resources/claude-customizations/.claude/hooks/enforce-pr-author-command-allowlist.ps1 +51 -4
  32. package/resources/claude-customizations/.claude/hooks/enforce-pr-author-skill-helpers.ps1 +72 -11
  33. package/resources/claude-customizations/.claude/hooks/enforce-pr-author-skill.current-branch.ps1 +149 -0
  34. package/resources/claude-customizations/.claude/hooks/enforce-pr-author-skill.epic-base-branch.ps1 +4 -2
  35. package/resources/claude-customizations/.claude/hooks/enforce-python-batch-budget.ps1 +59 -20
  36. package/resources/claude-customizations/.claude/hooks/record-discovery-agent-start.ps1 +132 -0
  37. package/resources/claude-customizations/.claude/hooks/validate-discovery-artifact-gate.ps1 +56 -212
  38. package/resources/claude-customizations/.claude/hooks/validate-orchestrator-output-feature-folder.ps1 +146 -0
  39. package/resources/claude-customizations/.claude/hooks/validate-orchestrator-output-rejection.ps1 +172 -0
  40. package/resources/claude-customizations/.claude/hooks/validate-orchestrator-output.ps1 +34 -4
  41. package/resources/claude-customizations/.claude/lib/blast-radius/BlastRadius.psm1 +9 -3
  42. package/resources/claude-customizations/.claude/lib/blast-radius/BlastRadiusAggregate.psm1 +154 -0
  43. package/resources/claude-customizations/.claude/lib/blast-radius/BlastRadiusCombination.psm1 +228 -0
  44. package/resources/claude-customizations/.claude/lib/blast-radius/BlastRadiusExtraction.psm1 +1 -0
  45. package/resources/claude-customizations/.claude/lib/blast-radius/BlastRadiusNormalization.psm1 +4 -2
  46. package/resources/claude-customizations/.claude/lib/blast-radius/BlastRadiusScheduling.psm1 +63 -16
  47. package/resources/claude-customizations/.claude/lib/blast-radius/BlastRadiusTokenShape.psm1 +56 -1
  48. package/resources/claude-customizations/.claude/lib/blast-radius/BlastRadiusWriteIntent.psm1 +4 -1
  49. package/resources/claude-customizations/.claude/lib/cleanup-manifest/CleanupWorktreeManifest.psm1 +33 -6
  50. package/resources/claude-customizations/.claude/lib/codex-routing/CodexDeployment.psm1 +5 -1
  51. package/resources/claude-customizations/.claude/lib/codex-routing/CodexDiscoveryRouting.psm1 +161 -0
  52. package/resources/claude-customizations/.claude/lib/codex-routing/CodexTopology.psm1 +25 -2
  53. package/resources/claude-customizations/.claude/lib/discovery-validation/DiscoveryAuthority.psd1 +90 -0
  54. package/resources/claude-customizations/.claude/lib/discovery-validation/DiscoveryAuthority.psm1 +493 -0
  55. package/resources/claude-customizations/.claude/lib/discovery-validation/DiscoveryAuthorization.psm1 +479 -0
  56. package/resources/claude-customizations/.claude/lib/discovery-validation/DiscoveryCapability.psm1 +468 -0
  57. package/resources/claude-customizations/.claude/lib/discovery-validation/DiscoveryEncoding.psm1 +156 -0
  58. package/resources/claude-customizations/.claude/lib/discovery-validation/DiscoveryManifest.psm1 +384 -0
  59. package/resources/claude-customizations/.claude/lib/discovery-validation/DiscoveryObservation.psm1 +217 -0
  60. package/resources/claude-customizations/.claude/lib/discovery-validation/DiscoveryPayload.psm1 +276 -0
  61. package/resources/claude-customizations/.claude/lib/discovery-validation/DiscoveryPlanning.psm1 +336 -0
  62. package/resources/claude-customizations/.claude/lib/discovery-validation/DiscoveryRootGrant.psm1 +164 -0
  63. package/resources/claude-customizations/.claude/lib/discovery-validation/DiscoveryStart.psm1 +440 -0
  64. package/resources/claude-customizations/.claude/lib/discovery-validation/DiscoveryStartRecord.psm1 +296 -0
  65. package/resources/claude-customizations/.claude/lib/discovery-validation/DiscoveryStop.psm1 +336 -0
  66. package/resources/claude-customizations/.claude/lib/discovery-validation/DiscoveryToolRouting.psm1 +228 -0
  67. package/resources/claude-customizations/.claude/lib/discovery-validation/DiscoveryValidation.psm1 +188 -341
  68. package/resources/claude-customizations/.claude/lib/file-size-policy/FileSizePolicy.psm1 +434 -0
  69. package/resources/claude-customizations/.claude/lib/orchestrator-state/OrchestratorStateFeatureFolderRecord.psm1 +166 -0
  70. package/resources/claude-customizations/.claude/lib/orchestrator-state/OrchestratorStateIssueAdoption.psm1 +8 -3
  71. package/resources/claude-customizations/.claude/lib/worktree-resolution/HookTargetWorktree.psm1 +391 -0
  72. package/resources/claude-customizations/.claude/lib/worktree-resolution/WorktreeRunRecordPath.psm1 +185 -0
  73. package/resources/claude-customizations/.claude/lib/worktree-resolution/WorktreeRunResolution.psm1 +11 -21
  74. package/resources/claude-customizations/.claude/rules/general-code-change.md +4 -1
  75. package/resources/claude-customizations/.claude/rules/orchestrator-state.md +29 -5
  76. package/resources/claude-customizations/.claude/rules/parallel-orchestration.md +152 -20
  77. package/resources/claude-customizations/.claude/rules/powershell.md +1 -1
  78. package/resources/claude-customizations/.claude/rules/shell.md +1 -1
  79. package/resources/claude-customizations/.claude/settings.json +36 -3
  80. package/resources/claude-customizations/.claude/skills/adjudicate-unspecified-behavior/SKILL.md +135 -0
  81. package/resources/claude-customizations/.claude/skills/characterize-runtime-behavior/SKILL.md +134 -0
  82. package/resources/claude-customizations/.claude/skills/cleanup-merged-worktrees/SKILL.md +2 -2
  83. package/resources/claude-customizations/.claude/skills/discovery-behavior-reconciliation/SKILL.md +28 -47
  84. package/resources/claude-customizations/.claude/skills/discovery-coverage-ledger/SKILL.md +32 -48
  85. package/resources/claude-customizations/.claude/skills/discovery-parity-matrix/SKILL.md +28 -45
  86. package/resources/claude-customizations/.claude/skills/discovery-repo-inventory/SKILL.md +28 -62
  87. package/resources/claude-customizations/.claude/skills/discovery-runtime-characterization/SKILL.md +28 -45
  88. package/resources/claude-customizations/.claude/skills/discovery-validate-artifacts/SKILL.md +28 -61
  89. package/resources/claude-customizations/.claude/skills/discovery-workflow/SKILL.md +55 -139
  90. package/resources/claude-customizations/.claude/skills/execution-environment/SKILL.md +25 -10
  91. package/resources/claude-customizations/.claude/skills/extract-feature-contract/SKILL.md +133 -0
  92. package/resources/claude-customizations/.claude/skills/feature-promotion-lifecycle/SKILL.md +1 -0
  93. package/resources/claude-customizations/.claude/skills/generate-acceptance-scenarios/SKILL.md +132 -0
  94. package/resources/claude-customizations/.claude/skills/initialize-discovery-workspace/SKILL.md +131 -0
  95. package/resources/claude-customizations/.claude/skills/inventory-legacy-system/SKILL.md +131 -0
  96. package/resources/claude-customizations/.claude/skills/orchestrate/SKILL.md +15 -7
  97. package/resources/claude-customizations/.claude/skills/parallel-add/SKILL.md +25 -2
  98. package/resources/claude-customizations/.claude/skills/parallel-close/SKILL.md +11 -1
  99. package/resources/claude-customizations/.claude/skills/parallel-orchestrate/SKILL.md +124 -14
  100. package/resources/claude-customizations/.claude/skills/parallel-plan/SKILL.md +72 -7
  101. package/resources/claude-customizations/.claude/skills/parallel-remove/SKILL.md +15 -0
  102. package/resources/claude-customizations/.claude/skills/parallel-run/SKILL.md +6 -0
  103. package/resources/claude-customizations/.claude/skills/pr-author/SKILL.md +56 -9
  104. package/resources/claude-customizations/.claude/skills/reconcile-parity-matrix/SKILL.md +131 -0
  105. package/resources/claude-customizations/.claude/skills/review-discovery-coverage/SKILL.md +129 -0
  106. package/resources/claude-customizations/.claude/skills/validate-discovery-artifacts/SKILL.md +127 -0
  107. package/resources/claude-customizations/.claude-variants/csharp-legacy/agents/csharp-typed-engineer.md +1 -1
  108. package/resources/claude-customizations/config/blast-radius.json +6 -5
  109. package/resources/claude-customizations/config/orchestration-routing.json +61 -1
  110. package/resources/claude-customizations/pack-manifests/core.json +40 -1
  111. package/resources/codex-and-agents-customizations/.agents/skills/adjudicate-unspecified-behavior/SKILL.md +135 -0
  112. package/resources/codex-and-agents-customizations/.agents/skills/atomic-planner/SKILL.md +7 -0
  113. package/resources/codex-and-agents-customizations/.agents/skills/characterize-runtime-behavior/SKILL.md +134 -0
  114. package/resources/codex-and-agents-customizations/.agents/skills/discovery-behavior-reconciliation/SKILL.md +46 -0
  115. package/resources/codex-and-agents-customizations/.agents/skills/discovery-coverage-ledger/SKILL.md +50 -0
  116. package/resources/codex-and-agents-customizations/.agents/skills/discovery-parity-matrix/SKILL.md +46 -0
  117. package/resources/codex-and-agents-customizations/.agents/skills/discovery-repo-inventory/SKILL.md +46 -0
  118. package/resources/codex-and-agents-customizations/.agents/skills/discovery-runtime-characterization/SKILL.md +46 -0
  119. package/resources/codex-and-agents-customizations/.agents/skills/discovery-validate-artifacts/SKILL.md +46 -0
  120. package/resources/codex-and-agents-customizations/.agents/skills/discovery-workflow/SKILL.md +62 -0
  121. package/resources/codex-and-agents-customizations/.agents/skills/execution-environment/SKILL.md +25 -10
  122. package/resources/codex-and-agents-customizations/.agents/skills/extract-feature-contract/SKILL.md +133 -0
  123. package/resources/codex-and-agents-customizations/.agents/skills/feature-promotion-lifecycle/SKILL.md +1 -1
  124. package/resources/codex-and-agents-customizations/.agents/skills/feature-review/SKILL.md +8 -0
  125. package/resources/codex-and-agents-customizations/.agents/skills/general-code-change/SKILL.md +4 -1
  126. package/resources/codex-and-agents-customizations/.agents/skills/generate-acceptance-scenarios/SKILL.md +132 -0
  127. package/resources/codex-and-agents-customizations/.agents/skills/initialize-discovery-workspace/SKILL.md +131 -0
  128. package/resources/codex-and-agents-customizations/.agents/skills/inventory-legacy-system/SKILL.md +131 -0
  129. package/resources/codex-and-agents-customizations/.agents/skills/orchestrator-workflow/SKILL.md +8 -0
  130. package/resources/codex-and-agents-customizations/.agents/skills/powershell/SKILL.md +1 -1
  131. package/resources/codex-and-agents-customizations/.agents/skills/reconcile-parity-matrix/SKILL.md +131 -0
  132. package/resources/codex-and-agents-customizations/.agents/skills/review-discovery-coverage/SKILL.md +129 -0
  133. package/resources/codex-and-agents-customizations/.agents/skills/validate-discovery-artifacts/SKILL.md +127 -0
  134. package/resources/codex-and-agents-customizations/.codex/agents/csharp-typed-engineer-c1.toml +1 -1
  135. package/resources/codex-and-agents-customizations/.codex/agents/csharp-typed-engineer-c2.toml +1 -1
  136. package/resources/codex-and-agents-customizations/.codex/agents/csharp-typed-engineer-c3-elevated.toml +1 -1
  137. package/resources/codex-and-agents-customizations/.codex/agents/csharp-typed-engineer-c3.toml +1 -1
  138. package/resources/codex-and-agents-customizations/.codex/agents/csharp-typed-engineer-c4.toml +1 -1
  139. package/resources/codex-and-agents-customizations/.codex/agents/csharp-typed-engineer.toml +1 -1
  140. package/resources/codex-and-agents-customizations/.codex/agents/discovery-capability-sentinel.toml +51 -0
  141. package/resources/codex-and-agents-customizations/.codex/agents/feature-review.toml +8 -0
  142. package/resources/codex-and-agents-customizations/.codex/agents/legacy-parity-analyst-c1.toml +148 -0
  143. package/resources/codex-and-agents-customizations/.codex/agents/legacy-parity-analyst-c2.toml +148 -0
  144. package/resources/codex-and-agents-customizations/.codex/agents/legacy-parity-analyst-c3-elevated.toml +148 -0
  145. package/resources/codex-and-agents-customizations/.codex/agents/legacy-parity-analyst-c3.toml +148 -0
  146. package/resources/codex-and-agents-customizations/.codex/agents/legacy-parity-analyst-c4.toml +148 -0
  147. package/resources/codex-and-agents-customizations/.codex/agents/legacy-parity-analyst.toml +148 -0
  148. package/resources/codex-and-agents-customizations/.codex/agents/migration-coverage-reviewer-c1.toml +154 -0
  149. package/resources/codex-and-agents-customizations/.codex/agents/migration-coverage-reviewer-c2.toml +154 -0
  150. package/resources/codex-and-agents-customizations/.codex/agents/migration-coverage-reviewer-c3-elevated.toml +154 -0
  151. package/resources/codex-and-agents-customizations/.codex/agents/migration-coverage-reviewer-c3.toml +154 -0
  152. package/resources/codex-and-agents-customizations/.codex/agents/migration-coverage-reviewer-c4.toml +154 -0
  153. package/resources/codex-and-agents-customizations/.codex/agents/migration-coverage-reviewer.toml +154 -0
  154. package/resources/codex-and-agents-customizations/.codex/agents/powershell-typed-engineer-c1.toml +1 -1
  155. package/resources/codex-and-agents-customizations/.codex/agents/powershell-typed-engineer-c2.toml +1 -1
  156. package/resources/codex-and-agents-customizations/.codex/agents/powershell-typed-engineer-c3-elevated.toml +1 -1
  157. package/resources/codex-and-agents-customizations/.codex/agents/powershell-typed-engineer-c3.toml +1 -1
  158. package/resources/codex-and-agents-customizations/.codex/agents/powershell-typed-engineer-c4.toml +1 -1
  159. package/resources/codex-and-agents-customizations/.codex/agents/powershell-typed-engineer.toml +1 -1
  160. package/resources/codex-and-agents-customizations/.codex/agents/python-typed-engineer-c1.toml +1 -1
  161. package/resources/codex-and-agents-customizations/.codex/agents/python-typed-engineer-c2.toml +1 -1
  162. package/resources/codex-and-agents-customizations/.codex/agents/python-typed-engineer-c3-elevated.toml +1 -1
  163. package/resources/codex-and-agents-customizations/.codex/agents/python-typed-engineer-c3.toml +1 -1
  164. package/resources/codex-and-agents-customizations/.codex/agents/python-typed-engineer-c4.toml +1 -1
  165. package/resources/codex-and-agents-customizations/.codex/agents/python-typed-engineer.toml +1 -1
  166. package/resources/codex-and-agents-customizations/.codex/agents/requirements-reconciler-c1.toml +164 -0
  167. package/resources/codex-and-agents-customizations/.codex/agents/requirements-reconciler-c2.toml +164 -0
  168. package/resources/codex-and-agents-customizations/.codex/agents/requirements-reconciler-c3-elevated.toml +164 -0
  169. package/resources/codex-and-agents-customizations/.codex/agents/requirements-reconciler-c3.toml +164 -0
  170. package/resources/codex-and-agents-customizations/.codex/agents/requirements-reconciler-c4.toml +164 -0
  171. package/resources/codex-and-agents-customizations/.codex/agents/requirements-reconciler.toml +164 -0
  172. package/resources/codex-and-agents-customizations/.codex/agents/runtime-characterization-analyst-c1.toml +150 -0
  173. package/resources/codex-and-agents-customizations/.codex/agents/runtime-characterization-analyst-c2.toml +150 -0
  174. package/resources/codex-and-agents-customizations/.codex/agents/runtime-characterization-analyst-c3-elevated.toml +150 -0
  175. package/resources/codex-and-agents-customizations/.codex/agents/runtime-characterization-analyst-c3.toml +150 -0
  176. package/resources/codex-and-agents-customizations/.codex/agents/runtime-characterization-analyst-c4.toml +150 -0
  177. package/resources/codex-and-agents-customizations/.codex/agents/runtime-characterization-analyst.toml +150 -0
  178. package/resources/codex-and-agents-customizations/.codex/config.toml +39 -3
  179. package/resources/codex-and-agents-customizations/.codex/hooks/codex-agent-profile-attestation.ps1 +22 -0
  180. package/resources/codex-and-agents-customizations/.codex/hooks/discovery-capability-probe.ps1 +97 -0
  181. package/resources/codex-and-agents-customizations/.codex/hooks/discovery-start-attestation.ps1 +171 -0
  182. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-codex-model-routing.ps1 +4 -1
  183. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-discovery-artifact-gate.ps1 +187 -0
  184. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-discovery-planning-gate.ps1 +149 -0
  185. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-file-size-limit.ps1 +282 -0
  186. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-orchestration-preimplementation-gate-epic-scope.ps1 +239 -2
  187. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-orchestration-preimplementation-gate.ps1 +6 -15
  188. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-powershell-batch-budget.ps1 +54 -15
  189. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-python-batch-budget.ps1 +54 -15
  190. package/resources/codex-and-agents-customizations/.codex/hooks/file-size-policy.ps1 +421 -0
  191. package/resources/codex-and-agents-customizations/.codex/hooks/hook-target-worktree.ps1 +369 -0
  192. package/resources/codex-and-agents-customizations/.codex/hooks/record-subagent-routing-attestation.ps1 +8 -0
  193. package/resources/codex-and-agents-customizations/.codex/hooks/validate-codex-subagent-routing.ps1 +22 -1
  194. package/resources/codex-and-agents-customizations/.codex/hooks/validate-discovery-agent-output.ps1 +178 -0
  195. package/resources/codex-and-agents-customizations/.codex/scripts/Resolve-CodexTopology.ps1 +11 -1
  196. package/resources/codex-and-agents-customizations/.codex-variants/csharp-legacy/agents/csharp-typed-engineer.toml +1 -1
  197. package/resources/codex-and-agents-customizations/AGENTS.md +4 -1
  198. package/resources/codex-and-agents-customizations/pack-manifests/core.json +65 -1
  199. package/resources/config/orchestration-routing.json +61 -1
  200. package/resources/customizations/.github/agents/commentary-remediation.agent.md +1 -1
  201. package/resources/customizations/.github/agents/discovery-capability-sentinel.agent.md +34 -0
  202. package/resources/customizations/.github/agents/legacy-parity-analyst.agent.md +122 -0
  203. package/resources/customizations/.github/agents/migration-coverage-reviewer.agent.md +128 -0
  204. package/resources/customizations/.github/agents/python-execution-only-typed.agent.md +1 -1
  205. package/resources/customizations/.github/agents/python-typed-engineer.agent.md +1 -1
  206. package/resources/customizations/.github/agents/requirements-reconciler.agent.md +138 -0
  207. package/resources/customizations/.github/agents/runtime-characterization-analyst.agent.md +124 -0
  208. package/resources/customizations/.github/hooks/discovery-agent-start.ps1 +139 -0
  209. package/resources/customizations/.github/hooks/discovery-agent-stop.ps1 +123 -0
  210. package/resources/customizations/.github/hooks/discovery-capability-probe.ps1 +98 -0
  211. package/resources/customizations/.github/hooks/discovery-planning.ps1 +91 -0
  212. package/resources/customizations/.github/hooks/discovery-pre-tool.ps1 +123 -0
  213. package/resources/customizations/.github/hooks/discovery.json +35 -0
  214. package/resources/customizations/.github/instructions/general-code-change.instructions.md +5 -2
  215. package/resources/customizations/.github/instructions/mermaid.instructions.md +85 -0
  216. package/resources/customizations/.github/instructions/powershell-code-change.instructions.md +1 -1
  217. package/resources/customizations/.github/prompts/execute-hard-lock.prompt.md +105 -0
  218. package/resources/customizations/.github/prompts/remediate-comments.prompt.md +1 -1
  219. package/resources/customizations/.github/skills/adjudicate-unspecified-behavior/SKILL.md +135 -0
  220. package/resources/customizations/.github/skills/characterize-runtime-behavior/SKILL.md +134 -0
  221. package/resources/customizations/.github/skills/discovery-behavior-reconciliation/SKILL.md +46 -0
  222. package/resources/customizations/.github/skills/discovery-coverage-ledger/SKILL.md +50 -0
  223. package/resources/customizations/.github/skills/discovery-parity-matrix/SKILL.md +46 -0
  224. package/resources/customizations/.github/skills/discovery-repo-inventory/SKILL.md +46 -0
  225. package/resources/customizations/.github/skills/discovery-runtime-characterization/SKILL.md +46 -0
  226. package/resources/customizations/.github/skills/discovery-validate-artifacts/SKILL.md +46 -0
  227. package/resources/customizations/.github/skills/discovery-workflow/SKILL.md +62 -0
  228. package/resources/customizations/.github/skills/execution-environment/SKILL.md +25 -10
  229. package/resources/customizations/.github/skills/extract-feature-contract/SKILL.md +133 -0
  230. package/resources/customizations/.github/skills/feature-review-workflow/SKILL.md +8 -0
  231. package/resources/customizations/.github/skills/generate-acceptance-scenarios/SKILL.md +132 -0
  232. package/resources/customizations/.github/skills/initialize-discovery-workspace/SKILL.md +131 -0
  233. package/resources/customizations/.github/skills/inventory-legacy-system/SKILL.md +131 -0
  234. package/resources/customizations/.github/skills/reconcile-parity-matrix/SKILL.md +131 -0
  235. package/resources/customizations/.github/skills/review-discovery-coverage/SKILL.md +129 -0
  236. package/resources/customizations/.github/skills/validate-discovery-artifacts/SKILL.md +127 -0
  237. package/resources/lib/codex-routing/CodexDeployment.psm1 +5 -1
  238. package/resources/lib/codex-routing/CodexDiscoveryRouting.psm1 +161 -0
  239. package/resources/lib/codex-routing/CodexTopology.psm1 +25 -2
  240. package/resources/lib/discovery-validation/DiscoveryAuthority.psd1 +90 -0
  241. package/resources/lib/discovery-validation/DiscoveryAuthority.psm1 +493 -0
  242. package/resources/lib/discovery-validation/DiscoveryAuthorization.psm1 +479 -0
  243. package/resources/lib/discovery-validation/DiscoveryCapability.psm1 +468 -0
  244. package/resources/lib/discovery-validation/DiscoveryEncoding.psm1 +156 -0
  245. package/resources/lib/discovery-validation/DiscoveryManifest.psm1 +384 -0
  246. package/resources/lib/discovery-validation/DiscoveryObservation.psm1 +217 -0
  247. package/resources/lib/discovery-validation/DiscoveryPayload.psm1 +276 -0
  248. package/resources/lib/discovery-validation/DiscoveryPlanning.psm1 +336 -0
  249. package/resources/lib/discovery-validation/DiscoveryRootGrant.psm1 +164 -0
  250. package/resources/lib/discovery-validation/DiscoveryStart.psm1 +440 -0
  251. package/resources/lib/discovery-validation/DiscoveryStartRecord.psm1 +296 -0
  252. package/resources/lib/discovery-validation/DiscoveryStop.psm1 +336 -0
  253. package/resources/lib/discovery-validation/DiscoveryToolRouting.psm1 +228 -0
  254. package/resources/powershell/PoshQC/PoshQC.Parallel.psm1 +452 -0
  255. package/resources/powershell/PoshQC/PoshQC.Shard.psm1 +106 -8
  256. package/resources/powershell/PoshQC/PoshQC.Testing.psm1 +12 -0
  257. package/resources/powershell/PoshQC/PoshQC.psd1 +6 -1
  258. package/resources/powershell/PoshQC/PoshQC.psm1 +7 -1
  259. package/resources/powershell/PoshQC/README.md +20 -1
  260. package/resources/templates/policy_audit/code-review.yyyy-MM-ddTHH-mm.md +4 -4
  261. package/resources/templates/policy_audit/policy-audit.yyyy-MM-ddTHH-mm.md +4 -4
@@ -0,0 +1,97 @@
1
+ <#
2
+ .SYNOPSIS
3
+ Codex capability probe for discovery agents: observes registration, handler hashes and the recorded sentinel observations.
4
+
5
+ .DESCRIPTION
6
+ Not an event hook. The gateway doctor and the operator script
7
+ scripts/dev-tools/Test-DiscoveryHostCapability.ps1 run this probe to observe
8
+ whether this workspace's Codex host provides the required discovery controls:
9
+ the SubagentStart, PreToolUse and SubagentStop handlers registered in
10
+ .codex/config.toml for the four discovery agents and the controlled tools, their
11
+ current hashes, and the host observations the PreToolUse gate recorded while the
12
+ discovery-capability-sentinel agent ran in session SessionId. The result is a
13
+ capability-attestation-shaped JSON document on stdout; exit 0 when supported, 1
14
+ when unsupported. A session without observations, or whose sentinel observation
15
+ carries no agent_id, is unsupported.
16
+
17
+ .NOTES
18
+ Issue #980. Requires PowerShell 7+. Invokes NO external process and makes no
19
+ in-process sentinel decision.
20
+ #>
21
+ [CmdletBinding()]
22
+ param(
23
+ [Parameter(Mandatory = $false)][string]$WorkspaceRoot = (Split-Path (Split-Path $PSScriptRoot -Parent) -Parent),
24
+ [Parameter(Mandatory = $false)][string]$SessionId = 'capability-probe',
25
+ [Parameter(Mandatory = $false)][AllowNull()][string]$Nonce = $null,
26
+ [Parameter(Mandatory = $false)][bool]$WorkspaceTrusted = $true,
27
+ [Parameter(Mandatory = $false)][AllowNull()][string]$RuntimeJson = $null
28
+ )
29
+
30
+ . (Join-Path $PSScriptRoot 'enforce-discovery-artifact-gate.ps1')
31
+ Import-Module (Get-DiscoveryHelperModulePath -ModuleName 'DiscoveryCapability.psm1') -Force -Global -ErrorAction Stop
32
+
33
+ function Get-DiscoveryProbeRuntime {
34
+ <#
35
+ .SYNOPSIS
36
+ Returns the runtime identity the probe records: the caller's JSON, or the local configuration digest.
37
+ #>
38
+ [CmdletBinding()]
39
+ [OutputType([System.Collections.Specialized.OrderedDictionary])]
40
+ param([Parameter(Mandatory = $false)][AllowNull()][string]$RuntimeJson, [Parameter(Mandatory = $true)][string]$WorkspaceRoot)
41
+
42
+ if (-not [string]::IsNullOrWhiteSpace($RuntimeJson)) {
43
+ $parsed = ConvertFrom-Json -InputObject $RuntimeJson -Depth 4
44
+ $runtime = [ordered]@{}
45
+ foreach ($key in @('build_sha256', 'package_version', 'policy_sha256', 'policy_version', 'schema_version')) {
46
+ # The runtime identity contract types policy_version as an integer; the hosts compare it canonically.
47
+ $runtime[$key] = $(if ($key -eq 'policy_version') { [int]$parsed.$key } else { [string]$parsed.$key })
48
+ }
49
+ return $runtime
50
+ }
51
+ # The workspace root is a host-modelled path string; Join-Path would require its drive to exist locally.
52
+ $configuration = "$($WorkspaceRoot.TrimEnd('/', '\'))/.codex/config.toml"
53
+ $digest = $(if (Test-Path -LiteralPath $configuration -PathType Leaf) { Get-DiscoveryBytesSha256Hex -Bytes ([System.IO.File]::ReadAllBytes($configuration)) } else { '0' * 64 })
54
+ return [ordered]@{ build_sha256 = $digest; package_version = '2.0.0'; policy_sha256 = $digest; policy_version = 2; schema_version = '2.0.0' }
55
+ }
56
+
57
+ function Invoke-DiscoveryCapabilityProbe {
58
+ <#
59
+ .SYNOPSIS
60
+ Runs the Codex capability observation and returns the attestation-shaped document.
61
+ #>
62
+ [CmdletBinding()]
63
+ [OutputType([System.Collections.Specialized.OrderedDictionary])]
64
+ param(
65
+ [Parameter(Mandatory = $true)][string]$WorkspaceRoot,
66
+ [Parameter(Mandatory = $true)][string]$SessionId,
67
+ [Parameter(Mandatory = $false)][AllowNull()][string]$Nonce = $null,
68
+ [Parameter(Mandatory = $false)][bool]$WorkspaceTrusted = $true,
69
+ [Parameter(Mandatory = $false)][AllowNull()][string]$RuntimeJson = $null,
70
+ [Parameter(Mandatory = $false)][AllowNull()][hashtable]$HostEnvironment = $null,
71
+ [Parameter(Mandatory = $false)][AllowNull()][hashtable]$Store = $null,
72
+ [Parameter(Mandatory = $false)][AllowNull()][scriptblock]$ReadBytes = $null,
73
+ [Parameter(Mandatory = $false)][AllowNull()][nullable[datetime]]$Now = $null
74
+ )
75
+
76
+ if ([string]::IsNullOrEmpty($Nonce)) { $Nonce = Get-DiscoveryAuthorizationNonce }
77
+ if ($null -eq $HostEnvironment) { $HostEnvironment = Get-DiscoveryTrustedHostEnvironment }
78
+ if ($null -eq $Store) { $Store = Get-DiscoveryDefaultStore }
79
+ if ($null -eq $Now) { $Now = [datetime]::UtcNow }
80
+ $parameters = @{
81
+ HostName = 'codex'; WorkspaceRoot = $WorkspaceRoot; SessionId = $SessionId; Nonce = $Nonce; WorkspaceTrusted = $WorkspaceTrusted; Now = $Now
82
+ Runtime = (Get-DiscoveryProbeRuntime -RuntimeJson $RuntimeJson -WorkspaceRoot $WorkspaceRoot)
83
+ HostEnvironment = $HostEnvironment; Store = $Store
84
+ }
85
+ if ($null -ne $ReadBytes) { $parameters['ReadBytes'] = $ReadBytes }
86
+ $observation = Get-DiscoveryCapabilityObservation @parameters
87
+ # The doctor, the agent preparation and the start attestation read only the protected session copy.
88
+ [void](Write-DiscoveryCapabilityAttestation -Observation $observation -WorkspaceRoot $WorkspaceRoot -HostEnvironment $HostEnvironment -Store $Store)
89
+ return $observation
90
+ }
91
+
92
+ if ($MyInvocation.InvocationName -eq '.') {
93
+ return
94
+ }
95
+ $observation = Invoke-DiscoveryCapabilityProbe -WorkspaceRoot $WorkspaceRoot -SessionId $SessionId -Nonce $Nonce -WorkspaceTrusted $WorkspaceTrusted -RuntimeJson $RuntimeJson
96
+ $observation | ConvertTo-Json -Depth 8 | Write-Output
97
+ exit $(if ($observation['status'] -eq 'supported') { 0 } else { 1 })
@@ -0,0 +1,171 @@
1
+ <#
2
+ .SYNOPSIS
3
+ Codex SubagentStart attestation for discovery specialists through the protected discovery store.
4
+
5
+ .DESCRIPTION
6
+ Dot-sourced by record-subagent-routing-attestation.ps1. A Codex start whose agent
7
+ type names a discovery specialist is attested against the explicit
8
+ `discovery-invocation` receipt the root prepared in the protected store, through
9
+ the shared DiscoveryStart module (published under .codex/lib/discovery-validation,
10
+ or read from .claude/lib when this repository hosts itself). The result is
11
+ projected into the schema-2 routing attestation the Codex PreToolUse gates
12
+ already consume, with receipt_kind `discovery-invocation`, so an unattested or
13
+ drifted specialist is denied before its first tool use. No orchestrator
14
+ checkpoint, repository HEAD or epic receipt is read for a discovery start.
15
+ #>
16
+ [CmdletBinding()]
17
+ param()
18
+
19
+ $script:CodexDiscoveryAgentTypePattern = '^(legacy-parity-analyst|runtime-characterization-analyst|requirements-reconciler|migration-coverage-reviewer)(-c(1|2|3|4|3-elevated))?$'
20
+ $script:CodexDiscoveryStartPrefix = 'DISCOVERY_START_ATTESTATION_BLOCKED:'
21
+ $script:CodexDiscoveryStartModules = @('DiscoveryEncoding.psm1', 'DiscoveryAuthority.psm1', 'DiscoveryPayload.psm1', 'DiscoveryStartRecord.psm1', 'DiscoveryStart.psm1')
22
+
23
+ function Test-CodexDiscoveryAgentType {
24
+ [CmdletBinding()]
25
+ [OutputType([bool])]
26
+ param([AllowNull()][AllowEmptyString()][string] $AgentType)
27
+
28
+ return -not [string]::IsNullOrWhiteSpace($AgentType) -and $AgentType -cmatch $script:CodexDiscoveryAgentTypePattern
29
+ }
30
+
31
+ function Get-CodexDiscoveryStartModulePath {
32
+ <#
33
+ .SYNOPSIS
34
+ Returns the published (.codex/lib) or self-hosting (.claude/lib) path of one helper module.
35
+ #>
36
+ [CmdletBinding()]
37
+ [OutputType([string])]
38
+ param(
39
+ [Parameter(Mandatory)][string] $ModuleName,
40
+ [string] $ScriptRoot = $PSScriptRoot
41
+ )
42
+
43
+ $published = Join-Path $ScriptRoot "../lib/discovery-validation/$ModuleName"
44
+ $selfHosted = Join-Path $ScriptRoot "../../.claude/lib/discovery-validation/$ModuleName"
45
+ foreach ($candidate in @($published, $selfHosted)) {
46
+ if (Test-Path -LiteralPath $candidate -PathType Leaf) { return $candidate }
47
+ }
48
+ return $published
49
+ }
50
+
51
+ function Import-CodexDiscoveryStartModule {
52
+ <#
53
+ .SYNOPSIS
54
+ Loads the shared discovery modules a discovery start needs; ordinary starts never load them.
55
+ #>
56
+ [CmdletBinding()]
57
+ param([string] $ScriptRoot = $PSScriptRoot)
58
+
59
+ foreach ($moduleName in $script:CodexDiscoveryStartModules) {
60
+ Import-Module (Get-CodexDiscoveryStartModulePath -ModuleName $moduleName -ScriptRoot $ScriptRoot) -Force -Global -ErrorAction Stop
61
+ }
62
+ }
63
+
64
+ function Get-CodexDiscoveryStartAttestation {
65
+ <#
66
+ .SYNOPSIS
67
+ Builds the schema-2 attestation of a Codex discovery start from the protected invocation.
68
+ .DESCRIPTION
69
+ The actual model comes from the SubagentStart payload and the actual effort and
70
+ profile hash from the generated Codex profile; both must equal the deployment
71
+ the root prepared. routing_valid is true only when the shared decision
72
+ attested the start; discovery_code and discovery_reason carry the decision.
73
+ #>
74
+ [CmdletBinding()]
75
+ [OutputType([System.Collections.Specialized.OrderedDictionary])]
76
+ param(
77
+ [Parameter(Mandatory)] $Payload,
78
+ [Parameter(Mandatory)][string] $RepositoryRoot,
79
+ [Parameter(Mandatory)][datetimeoffset] $Now,
80
+ [AllowNull()][hashtable] $HostEnvironment = $null,
81
+ [AllowNull()][hashtable] $Store = $null,
82
+ [AllowNull()][string] $Nonce = $null,
83
+ [AllowNull()] $AgentProfile = $null,
84
+ [string] $HandlerPath = (Join-Path $PSScriptRoot 'record-subagent-routing-attestation.ps1')
85
+ )
86
+
87
+ $agentId = [string]$Payload.agent_id
88
+ $agentType = [string]$Payload.agent_type
89
+ $model = [string]$Payload.model
90
+ if (-not $agentId -or -not $agentType -or -not $model) {
91
+ throw "$($script:CodexDiscoveryStartPrefix) SubagentStart requires agent_id, agent_type, and model."
92
+ }
93
+ Import-CodexDiscoveryStartModule
94
+ $profileValidationError = $null
95
+ if ($null -eq $AgentProfile) {
96
+ try { $AgentProfile = Get-CodexAgentProfileAttestation -RepositoryRoot $RepositoryRoot -AgentType $agentType } catch { $profileValidationError = [string]$_ }
97
+ }
98
+ $sharedProfile = $(if ($null -ne $AgentProfile) { ConvertTo-CodexSharedAgentProfile -AgentProfile $AgentProfile } else { $null })
99
+ # The principal comes from the payload alone: Codex supplies no parent identifier, so the parent is the literal root.
100
+ $normalized = [pscustomobject]@{
101
+ HostName = 'codex'; Event = 'SubagentStart'; SessionId = [string]$Payload.session_id; AgentId = $agentId; AgentType = $agentType; ParentAgentId = $null
102
+ ToolName = $null; ToolInput = $null; Cwd = $RepositoryRoot; ToolUseId = $null; Anomaly = $null
103
+ }
104
+ if ([string]::IsNullOrWhiteSpace($normalized.SessionId)) { $normalized.Anomaly = 'MissingSessionId' }
105
+ $handlerSha256 = $(if (Test-Path -LiteralPath $HandlerPath -PathType Leaf) { Get-DiscoveryBytesSha256Hex -Bytes ([System.IO.File]::ReadAllBytes($HandlerPath)) } else { '0' * 64 })
106
+ $parameters = @{ Normalized = $normalized; HandlerSha256 = $handlerSha256; Now = $Now.UtcDateTime; ActualModel = $model }
107
+ $parameters['HostEnvironment'] = $(if ($null -ne $HostEnvironment) { $HostEnvironment } else { Get-DiscoveryTrustedHostEnvironment })
108
+ if ($null -ne $Store) { $parameters['Store'] = $Store }
109
+ if (-not [string]::IsNullOrEmpty($Nonce)) { $parameters['Nonce'] = $Nonce }
110
+ if ($null -ne $sharedProfile) { $parameters['AgentProfile'] = $sharedProfile; $parameters['ActualReasoningEffort'] = $sharedProfile.ProfileReasoningEffort }
111
+ $outcome = $(if ($null -eq $sharedProfile) {
112
+ [pscustomobject]@{ Decision = 'deny'; Code = 'PROFILE'; Reason = "the agent profile could not be read: $profileValidationError"; Attestation = $null; AttestationPath = $null; Invocation = $null }
113
+ } else { Get-DiscoveryStartDecision @parameters })
114
+ $record = $outcome.Invocation
115
+ $attested = ($outcome.Decision -eq 'attest')
116
+ return [ordered]@{
117
+ schema_version = 2
118
+ receipt_kind = 'discovery-invocation'
119
+ session_id = [string]$Payload.session_id
120
+ turn_id = [string]$Payload.turn_id
121
+ agent_id = $agentId
122
+ agent_type = $agentType
123
+ transcript_path = [string]$Payload.transcript_path
124
+ attestation_key = Get-SubagentAttestationKey -TranscriptPath ([string]$Payload.transcript_path) -AgentId $agentId
125
+ actual_model = $model
126
+ expected_model = $(if ($null -ne $record) { [string]$record.deployment.model } else { '' })
127
+ actual_reasoning_effort = $(if ($null -ne $AgentProfile) { [string]$AgentProfile.profile_reasoning_effort } else { $null })
128
+ expected_reasoning_effort = $(if ($null -ne $record) { [string]$record.deployment.reasoning_effort } else { '' })
129
+ profile_name = $(if ($null -ne $AgentProfile) { [string]$AgentProfile.profile_name } else { $null })
130
+ profile_model = $(if ($null -ne $AgentProfile) { [string]$AgentProfile.profile_model } else { $null })
131
+ profile_path = $(if ($null -ne $AgentProfile) { [string]$AgentProfile.profile_path } else { $null })
132
+ profile_sha256 = $(if ($null -ne $AgentProfile) { [string]$AgentProfile.profile_sha256 } else { $null })
133
+ profile_validation_error = $profileValidationError
134
+ routing_valid = $attested
135
+ launch_authority_valid = $attested
136
+ root_authorized = $null
137
+ root_entry_kind = $null
138
+ root_epic_reference = $null
139
+ root_kickoff_path = $null
140
+ authority_repository_sha256 = Get-CodexAuthorityRepositoryKey -RepositoryRoot $RepositoryRoot
141
+ provenance_valid = $true
142
+ enforcement_marker = $(if ($attested) { $null } else { 'DISCOVERY_START_ATTESTATION_BLOCKED' })
143
+ invocation_id = $(if ($null -ne $record) { [string]$record.invocation_id } else { $null })
144
+ start_attestation_ref = $(if ($attested) { [string]$outcome.Attestation['start_attestation_ref'] } else { $null })
145
+ discovery_code = $outcome.Code
146
+ discovery_reason = $outcome.Reason
147
+ recorded_at = $Now.ToUniversalTime().ToString('o')
148
+ }
149
+ }
150
+
151
+ function Get-CodexDiscoveryStartCommandOutput {
152
+ <#
153
+ .SYNOPSIS
154
+ Returns the SubagentStart stdout for a discovery attestation, or $null when the start was attested.
155
+ #>
156
+ [CmdletBinding()]
157
+ [OutputType([string])]
158
+ param(
159
+ [Parameter(Mandatory)][System.Collections.IDictionary] $Attestation,
160
+ [Parameter(Mandatory)][string] $AttestationPath
161
+ )
162
+
163
+ if ([bool]$Attestation.routing_valid) { return $null }
164
+ return [ordered]@{
165
+ systemMessage = "$($script:CodexDiscoveryStartPrefix) $($Attestation.discovery_reason) Attestation: $AttestationPath"
166
+ hookSpecificOutput = [ordered]@{
167
+ hookEventName = 'SubagentStart'
168
+ additionalContext = "$($script:CodexDiscoveryStartPrefix) no discovery tool grant is active for this agent. Do not read or mutate state; report the blocked start and stop."
169
+ }
170
+ } | ConvertTo-Json -Compress -Depth 5
171
+ }
@@ -127,7 +127,10 @@ function Test-CodexModelGateAgentType {
127
127
  [OutputType([bool])]
128
128
  param([Parameter(Mandatory)][string] $AgentType)
129
129
 
130
- return $AgentType -match '-c(?:1|2|3|4|3-elevated)$' -or @(
130
+ # Discovery specialists are gated by their SubagentStart attestation of the
131
+ # protected invocation (issue #980); a start without one denies the first tool use.
132
+ return $AgentType -match '-c(?:1|2|3|4|3-elevated)$' -or
133
+ $AgentType -cmatch '^(legacy-parity-analyst|runtime-characterization-analyst|requirements-reconciler|migration-coverage-reviewer)$' -or @(
131
134
  'orchestrator', 'atomic-planner', 'atomic-executor', 'feature-review',
132
135
  'feature-reviewer', 'task-researcher', 'prd-feature', 'pr-author',
133
136
  'python-typed-engineer', 'powershell-typed-engineer',
@@ -0,0 +1,187 @@
1
+ <#
2
+ .SYNOPSIS
3
+ Native PreToolUse authorization adapter for Codex discovery agents.
4
+
5
+ .DESCRIPTION
6
+ Invoked by the Codex PreToolUse hook. The hook reads the Codex envelope from
7
+ stdin, derives the trusted principal from the payload alone (session, the
8
+ host-assigned agent_id and agent_type when the payload carries them, and the
9
+ literal parent root), and takes its decision from the shared
10
+ DiscoveryAuthorization module (published under .codex/lib/discovery-validation,
11
+ or read from .claude/lib when this repository hosts itself):
12
+
13
+ - a root call (no agent_id) of prepare_discovery_agent, run_discovery_doctor or
14
+ a controlled discovery tool is allowed with a one-use root grant the MCP
15
+ server consumes; every other root call and every call of an agent that is
16
+ not a discovery specialist allows silently (no stdout), so ordinary
17
+ sessions keep the behavior of their other gates;
18
+ - a sentinel envelope is observed for the capability probe and never granted;
19
+ - a discovery specialist may use read-only native tools and the controlled
20
+ discovery MCP tools only; shell, exec and evaluation tools, generic
21
+ apply_patch/Write/Edit mutations, nested agents, foreign MCP servers,
22
+ root-only discovery operations and caller-supplied identity fields are denied
23
+ before execution with a PreToolUse deny decision at exit 0;
24
+ - every controlled call must name the specialist's started invocation through
25
+ invocation_ref and is recorded as one short-lived, one-use tool-authorization;
26
+ the Codex SubagentStart attestation binds the prepared invocation, and the
27
+ gate's first-call binding reports PROFILE when no start attested the agent.
28
+
29
+ An envelope the hook cannot read is a hard failure: the reason goes to stderr
30
+ and the hook exits 2. Dependency failures deny with the
31
+ DISCOVERY_ARTIFACT_GATE_BLOCKED: prefix (issue #980).
32
+
33
+ .NOTES
34
+ Requires PowerShell 7+. Invokes NO external process and never reads a profile,
35
+ locator or request field to decide identity or authority.
36
+ #>
37
+ [CmdletBinding()]
38
+ param()
39
+ $script:HookDependencyGuardLoadFailed = $false; try { . (Join-Path $PSScriptRoot 'hook-dependency-guard.ps1') } catch { $script:HookDependencyGuardLoadFailed = $true }
40
+
41
+ function Get-DiscoveryHelperModulePath {
42
+ <#
43
+ .SYNOPSIS
44
+ Returns the published (.codex/lib) or self-hosting (.claude/lib) path of one helper module.
45
+ .DESCRIPTION
46
+ The published destination holds the helpers beside .codex/hooks under
47
+ .codex/lib/discovery-validation; this repository holds them under
48
+ .claude/lib/discovery-validation. The first existing candidate wins; when
49
+ neither exists the published path is returned so the import failure names it.
50
+ #>
51
+ [CmdletBinding()]
52
+ [OutputType([string])]
53
+ param(
54
+ [Parameter(Mandatory = $true)][string]$ModuleName,
55
+ [Parameter(Mandatory = $false)][string]$ScriptRoot = $PSScriptRoot
56
+ )
57
+
58
+ $published = Join-Path $ScriptRoot "../lib/discovery-validation/$ModuleName"
59
+ $selfHosted = Join-Path $ScriptRoot "../../.claude/lib/discovery-validation/$ModuleName"
60
+ # Resolution order: the destination layout first, then the repository layout.
61
+ foreach ($candidate in @($published, $selfHosted)) {
62
+ if (Test-Path -LiteralPath $candidate -PathType Leaf) { return $candidate }
63
+ }
64
+ return $published
65
+ }
66
+
67
+ function Import-DiscoveryGateSelfHostedModule {
68
+ <#
69
+ .SYNOPSIS
70
+ Imports the shared helpers from this repository's .claude/lib layout when no published .codex/lib exists (exemption D4).
71
+ #>
72
+ [CmdletBinding()]
73
+ param()
74
+
75
+ $ScriptRoot = $PSScriptRoot
76
+ try { Import-Module (Join-Path $ScriptRoot '../../.claude/lib/discovery-validation/DiscoveryEncoding.psm1') -Force -Global -ErrorAction Stop } catch { Add-HookDependencyFailure -Name 'DiscoveryEncoding.psm1' -ErrorRecord $_ }
77
+ try { Import-Module (Join-Path $ScriptRoot '../../.claude/lib/discovery-validation/DiscoveryAuthority.psm1') -Force -Global -ErrorAction Stop } catch { Add-HookDependencyFailure -Name 'DiscoveryAuthority.psm1' -ErrorRecord $_ }
78
+ try { Import-Module (Join-Path $ScriptRoot '../../.claude/lib/discovery-validation/DiscoveryPayload.psm1') -Force -Global -ErrorAction Stop } catch { Add-HookDependencyFailure -Name 'DiscoveryPayload.psm1' -ErrorRecord $_ }
79
+ try { Import-Module (Join-Path $ScriptRoot '../../.claude/lib/discovery-validation/DiscoveryToolRouting.psm1') -Force -Global -ErrorAction Stop } catch { Add-HookDependencyFailure -Name 'DiscoveryToolRouting.psm1' -ErrorRecord $_ }
80
+ try { Import-Module (Join-Path $ScriptRoot '../../.claude/lib/discovery-validation/DiscoveryStartRecord.psm1') -Force -Global -ErrorAction Stop } catch { Add-HookDependencyFailure -Name 'DiscoveryStartRecord.psm1' -ErrorRecord $_ }
81
+ try { Import-Module (Join-Path $ScriptRoot '../../.claude/lib/discovery-validation/DiscoveryRootGrant.psm1') -Force -Global -ErrorAction Stop } catch { Add-HookDependencyFailure -Name 'DiscoveryRootGrant.psm1' -ErrorRecord $_ }
82
+ try { Import-Module (Join-Path $ScriptRoot '../../.claude/lib/discovery-validation/DiscoveryObservation.psm1') -Force -Global -ErrorAction Stop } catch { Add-HookDependencyFailure -Name 'DiscoveryObservation.psm1' -ErrorRecord $_ }
83
+ try { Import-Module (Join-Path $ScriptRoot '../../.claude/lib/discovery-validation/DiscoveryStart.psm1') -Force -Global -ErrorAction Stop } catch { Add-HookDependencyFailure -Name 'DiscoveryStart.psm1' -ErrorRecord $_ }
84
+ try { Import-Module (Join-Path $ScriptRoot '../../.claude/lib/discovery-validation/DiscoveryAuthorization.psm1') -Force -Global -ErrorAction Stop } catch { Add-HookDependencyFailure -Name 'DiscoveryAuthorization.psm1' -ErrorRecord $_ }
85
+ }
86
+
87
+ # The published destination keeps the helpers beside .codex/hooks; this repository hosts them under .claude/lib.
88
+ if (Test-Path -LiteralPath (Join-Path $PSScriptRoot '../lib/discovery-validation/DiscoveryEncoding.psm1') -PathType Leaf) {
89
+ try { Import-Module (Join-Path $PSScriptRoot '../lib/discovery-validation/DiscoveryEncoding.psm1') -Force -Global -ErrorAction Stop } catch { Add-HookDependencyFailure -Name 'DiscoveryEncoding.psm1' -ErrorRecord $_ }
90
+ try { Import-Module (Join-Path $PSScriptRoot '../lib/discovery-validation/DiscoveryAuthority.psm1') -Force -Global -ErrorAction Stop } catch { Add-HookDependencyFailure -Name 'DiscoveryAuthority.psm1' -ErrorRecord $_ }
91
+ try { Import-Module (Join-Path $PSScriptRoot '../lib/discovery-validation/DiscoveryPayload.psm1') -Force -Global -ErrorAction Stop } catch { Add-HookDependencyFailure -Name 'DiscoveryPayload.psm1' -ErrorRecord $_ }
92
+ try { Import-Module (Join-Path $PSScriptRoot '../lib/discovery-validation/DiscoveryToolRouting.psm1') -Force -Global -ErrorAction Stop } catch { Add-HookDependencyFailure -Name 'DiscoveryToolRouting.psm1' -ErrorRecord $_ }
93
+ try { Import-Module (Join-Path $PSScriptRoot '../lib/discovery-validation/DiscoveryStartRecord.psm1') -Force -Global -ErrorAction Stop } catch { Add-HookDependencyFailure -Name 'DiscoveryStartRecord.psm1' -ErrorRecord $_ }
94
+ try { Import-Module (Join-Path $PSScriptRoot '../lib/discovery-validation/DiscoveryRootGrant.psm1') -Force -Global -ErrorAction Stop } catch { Add-HookDependencyFailure -Name 'DiscoveryRootGrant.psm1' -ErrorRecord $_ }
95
+ try { Import-Module (Join-Path $PSScriptRoot '../lib/discovery-validation/DiscoveryObservation.psm1') -Force -Global -ErrorAction Stop } catch { Add-HookDependencyFailure -Name 'DiscoveryObservation.psm1' -ErrorRecord $_ }
96
+ try { Import-Module (Join-Path $PSScriptRoot '../lib/discovery-validation/DiscoveryStart.psm1') -Force -Global -ErrorAction Stop } catch { Add-HookDependencyFailure -Name 'DiscoveryStart.psm1' -ErrorRecord $_ }
97
+ try { Import-Module (Join-Path $PSScriptRoot '../lib/discovery-validation/DiscoveryAuthorization.psm1') -Force -Global -ErrorAction Stop } catch { Add-HookDependencyFailure -Name 'DiscoveryAuthorization.psm1' -ErrorRecord $_ }
98
+ } else {
99
+ Import-DiscoveryGateSelfHostedModule
100
+ }
101
+
102
+ $script:DiscoveryGateReasonPrefix = 'DISCOVERY_ARTIFACT_GATE_BLOCKED:'
103
+ $script:DiscoveryGateHandlerPath = $PSCommandPath
104
+
105
+ function Get-DiscoveryGateHandlerSha256 {
106
+ <#
107
+ .SYNOPSIS
108
+ Returns the SHA-256 of this handler's own bytes for the authorization writer record.
109
+ #>
110
+ [CmdletBinding()]
111
+ [OutputType([string])]
112
+ param([Parameter(Mandatory = $false)][AllowNull()][string]$HandlerPath = $script:DiscoveryGateHandlerPath)
113
+
114
+ if ([string]::IsNullOrEmpty($HandlerPath) -or -not (Test-Path -LiteralPath $HandlerPath -PathType Leaf)) {
115
+ return ('0' * 64)
116
+ }
117
+ return Get-DiscoveryBytesSha256Hex -Bytes ([System.IO.File]::ReadAllBytes($HandlerPath))
118
+ }
119
+
120
+ function Invoke-DiscoveryArtifactGateDecision {
121
+ <#
122
+ .SYNOPSIS
123
+ Parses the Codex PreToolUse envelope and returns the decision outcome.
124
+ .DESCRIPTION
125
+ Returns the shared outcome object (Decision, Code, Reason, Record,
126
+ RecordPath). Every seam defaults to the real host and is injectable. A
127
+ recorded dependency failure returns a deny outcome before the envelope is read.
128
+ #>
129
+ [CmdletBinding()]
130
+ [OutputType([pscustomobject])]
131
+ param(
132
+ [Parameter(Mandatory = $false)][AllowNull()][AllowEmptyString()][string]$ToolInputRaw,
133
+ [Parameter(Mandatory = $false)][AllowNull()][hashtable]$HostEnvironment = $null,
134
+ [Parameter(Mandatory = $false)][AllowNull()][hashtable]$Store = $null,
135
+ [Parameter(Mandatory = $false)][AllowNull()][nullable[datetime]]$Now = $null,
136
+ [Parameter(Mandatory = $false)][AllowNull()][string]$Nonce = $null
137
+ )
138
+ $dependencyDecision = Get-HookDependencyFailureDecision -HookEvent PreToolUse -ReasonPrefix $script:DiscoveryGateReasonPrefix
139
+ if ($null -ne $dependencyDecision) { return $dependencyDecision }
140
+
141
+ # Seams resolve only after the dependency check so a missing module denies
142
+ # instead of raising while a default is evaluated.
143
+ if ($null -eq $HostEnvironment) { $HostEnvironment = Get-DiscoveryTrustedHostEnvironment }
144
+ if ($null -eq $Store) { $Store = Get-DiscoveryDefaultStore }
145
+ if ($null -eq $Now) { $Now = [datetime]::UtcNow }
146
+ if ([string]::IsNullOrEmpty($Nonce)) { $Nonce = Get-DiscoveryAuthorizationNonce }
147
+
148
+ $normalized = ConvertFrom-DiscoveryHostPayloadText -HostName 'codex' -Text $ToolInputRaw
149
+ return Get-DiscoveryPreToolDecision -Normalized $normalized -HostEnvironment $HostEnvironment `
150
+ -HandlerSha256 (Get-DiscoveryGateHandlerSha256) -Store $Store -Now $Now -Nonce $Nonce
151
+ }
152
+
153
+ function Invoke-DiscoveryArtifactGateEntryPoint {
154
+ <#
155
+ .SYNOPSIS
156
+ Reads one Codex PreToolUse payload, writes the decision and returns the process exit code.
157
+ .DESCRIPTION
158
+ An unreadable envelope writes its reason to stderr and returns 2. A deny
159
+ writes the PreToolUse decision JSON to stdout and returns 0. An allow writes
160
+ nothing and returns 0, as the Codex gates do.
161
+ #>
162
+ [CmdletBinding()]
163
+ [OutputType([int])]
164
+ param([Parameter(Mandatory = $false)][AllowNull()][AllowEmptyString()][string]$PayloadRaw)
165
+
166
+ $outcome = Invoke-DiscoveryArtifactGateDecision -ToolInputRaw $PayloadRaw
167
+ # A dependency failure is already the PreToolUse deny decision.
168
+ if ($outcome -is [System.Collections.IDictionary]) { [Console]::Out.WriteLine(($outcome | ConvertTo-Json -Compress -Depth 5)); return 0 }
169
+ if ($outcome.Decision -eq 'allow') { return 0 }
170
+ if ($outcome.Code -eq 'ENVELOPE') {
171
+ [Console]::Error.WriteLine("$($script:DiscoveryGateReasonPrefix) $($outcome.Reason)")
172
+ return 2
173
+ }
174
+ $decision = ConvertTo-DiscoveryPreToolHookOutput -Outcome $outcome -ReasonPrefix $script:DiscoveryGateReasonPrefix
175
+ [Console]::Out.WriteLine(($decision | ConvertTo-Json -Compress -Depth 5))
176
+ return 0
177
+ }
178
+
179
+ # Guard allows dot-sourcing in tests without executing the entrypoint.
180
+ if ($MyInvocation.InvocationName -eq '.') {
181
+ return
182
+ }
183
+ if ($script:HookDependencyGuardLoadFailed) { [Console]::Error.WriteLine('DISCOVERY_ARTIFACT_GATE_BLOCKED: hook-dependency-guard.ps1 failed to load; the gate fails closed.'); exit 2 }
184
+ $dependencyDecision = Get-HookDependencyFailureDecision -HookEvent PreToolUse -ReasonPrefix 'DISCOVERY_ARTIFACT_GATE_BLOCKED:'
185
+ if ($null -ne $dependencyDecision) { $dependencyDecision | ConvertTo-Json -Compress -Depth 5 | Write-Output; exit 0 }
186
+
187
+ exit (Invoke-DiscoveryArtifactGateEntryPoint -PayloadRaw ([Console]::In.ReadToEnd()))
@@ -0,0 +1,149 @@
1
+ <#
2
+ .SYNOPSIS
3
+ Codex PreToolUse hook that gates planner and orchestrator launches on current configured discovery authority.
4
+
5
+ .DESCRIPTION
6
+ Invoked by the Codex PreToolUse hook. The hook reads the Codex envelope from
7
+ stdin, recognizes an atomic-planner or orchestrator launch, and takes its
8
+ decision from the shared DiscoveryPlanning module (published under
9
+ .codex/lib/discovery-validation, or read from .claude/lib when this repository
10
+ hosts itself):
11
+
12
+ - a call that is not a planner or orchestrator launch, and a workspace without
13
+ a protected discovery activation, allow silently (no stdout) so the existing
14
+ Codex gates keep their behavior;
15
+ - an active workspace must still hold the activated locator and domain profile
16
+ and the protected session must hold a current, passing, gateway-written
17
+ planning-mode receipt for this host and session; otherwise the launch is
18
+ denied with a PreToolUse deny decision at exit 0.
19
+
20
+ An envelope the hook cannot read is a hard failure: the reason goes to stderr
21
+ and the hook exits 2. Dependency failures deny with the
22
+ DISCOVERY_PLANNING_GATE_BLOCKED: prefix. The hook never runs Python (issue #980).
23
+
24
+ .NOTES
25
+ Requires PowerShell 7+. Invokes NO external process.
26
+ #>
27
+ [CmdletBinding()]
28
+ param()
29
+ $script:HookDependencyGuardLoadFailed = $false; try { . (Join-Path $PSScriptRoot 'hook-dependency-guard.ps1') } catch { $script:HookDependencyGuardLoadFailed = $true }
30
+
31
+ function Get-DiscoveryPlanningHelperModulePath {
32
+ <#
33
+ .SYNOPSIS
34
+ Returns the published (.codex/lib) or self-hosting (.claude/lib) path of one helper module.
35
+ #>
36
+ [CmdletBinding()]
37
+ [OutputType([string])]
38
+ param(
39
+ [Parameter(Mandatory = $true)][string]$ModuleName,
40
+ [Parameter(Mandatory = $false)][string]$ScriptRoot = $PSScriptRoot
41
+ )
42
+
43
+ $published = Join-Path $ScriptRoot "../lib/discovery-validation/$ModuleName"
44
+ $selfHosted = Join-Path $ScriptRoot "../../.claude/lib/discovery-validation/$ModuleName"
45
+ foreach ($candidate in @($published, $selfHosted)) {
46
+ if (Test-Path -LiteralPath $candidate -PathType Leaf) { return $candidate }
47
+ }
48
+ return $published
49
+ }
50
+
51
+ function Import-DiscoveryPlanningSelfHostedModule {
52
+ <#
53
+ .SYNOPSIS
54
+ Imports the shared helpers from this repository's .claude/lib layout when no published .codex/lib exists (exemption D4).
55
+ #>
56
+ [CmdletBinding()]
57
+ param()
58
+
59
+ $ScriptRoot = $PSScriptRoot
60
+ try { Import-Module (Join-Path $ScriptRoot '../../.claude/lib/discovery-validation/DiscoveryEncoding.psm1') -Force -Global -ErrorAction Stop } catch { Add-HookDependencyFailure -Name 'DiscoveryEncoding.psm1' -ErrorRecord $_ }
61
+ try { Import-Module (Join-Path $ScriptRoot '../../.claude/lib/discovery-validation/DiscoveryAuthority.psm1') -Force -Global -ErrorAction Stop } catch { Add-HookDependencyFailure -Name 'DiscoveryAuthority.psm1' -ErrorRecord $_ }
62
+ try { Import-Module (Join-Path $ScriptRoot '../../.claude/lib/discovery-validation/DiscoveryManifest.psm1') -Force -Global -ErrorAction Stop } catch { Add-HookDependencyFailure -Name 'DiscoveryManifest.psm1' -ErrorRecord $_ }
63
+ try { Import-Module (Join-Path $ScriptRoot '../../.claude/lib/discovery-validation/DiscoveryPayload.psm1') -Force -Global -ErrorAction Stop } catch { Add-HookDependencyFailure -Name 'DiscoveryPayload.psm1' -ErrorRecord $_ }
64
+ try { Import-Module (Join-Path $ScriptRoot '../../.claude/lib/discovery-validation/DiscoveryToolRouting.psm1') -Force -Global -ErrorAction Stop } catch { Add-HookDependencyFailure -Name 'DiscoveryToolRouting.psm1' -ErrorRecord $_ }
65
+ try { Import-Module (Join-Path $ScriptRoot '../../.claude/lib/discovery-validation/DiscoveryAuthorization.psm1') -Force -Global -ErrorAction Stop } catch { Add-HookDependencyFailure -Name 'DiscoveryAuthorization.psm1' -ErrorRecord $_ }
66
+ try { Import-Module (Join-Path $ScriptRoot '../../.claude/lib/discovery-validation/DiscoveryStartRecord.psm1') -Force -Global -ErrorAction Stop } catch { Add-HookDependencyFailure -Name 'DiscoveryStartRecord.psm1' -ErrorRecord $_ }
67
+ try { Import-Module (Join-Path $ScriptRoot '../../.claude/lib/discovery-validation/DiscoveryPlanning.psm1') -Force -Global -ErrorAction Stop } catch { Add-HookDependencyFailure -Name 'DiscoveryPlanning.psm1' -ErrorRecord $_ }
68
+ }
69
+
70
+ # The published destination keeps the helpers beside .codex/hooks; this repository hosts them under .claude/lib.
71
+ if (Test-Path -LiteralPath (Join-Path $PSScriptRoot '../lib/discovery-validation/DiscoveryEncoding.psm1') -PathType Leaf) {
72
+ try { Import-Module (Join-Path $PSScriptRoot '../lib/discovery-validation/DiscoveryEncoding.psm1') -Force -Global -ErrorAction Stop } catch { Add-HookDependencyFailure -Name 'DiscoveryEncoding.psm1' -ErrorRecord $_ }
73
+ try { Import-Module (Join-Path $PSScriptRoot '../lib/discovery-validation/DiscoveryAuthority.psm1') -Force -Global -ErrorAction Stop } catch { Add-HookDependencyFailure -Name 'DiscoveryAuthority.psm1' -ErrorRecord $_ }
74
+ try { Import-Module (Join-Path $PSScriptRoot '../lib/discovery-validation/DiscoveryManifest.psm1') -Force -Global -ErrorAction Stop } catch { Add-HookDependencyFailure -Name 'DiscoveryManifest.psm1' -ErrorRecord $_ }
75
+ try { Import-Module (Join-Path $PSScriptRoot '../lib/discovery-validation/DiscoveryPayload.psm1') -Force -Global -ErrorAction Stop } catch { Add-HookDependencyFailure -Name 'DiscoveryPayload.psm1' -ErrorRecord $_ }
76
+ try { Import-Module (Join-Path $PSScriptRoot '../lib/discovery-validation/DiscoveryToolRouting.psm1') -Force -Global -ErrorAction Stop } catch { Add-HookDependencyFailure -Name 'DiscoveryToolRouting.psm1' -ErrorRecord $_ }
77
+ try { Import-Module (Join-Path $PSScriptRoot '../lib/discovery-validation/DiscoveryAuthorization.psm1') -Force -Global -ErrorAction Stop } catch { Add-HookDependencyFailure -Name 'DiscoveryAuthorization.psm1' -ErrorRecord $_ }
78
+ try { Import-Module (Join-Path $PSScriptRoot '../lib/discovery-validation/DiscoveryStartRecord.psm1') -Force -Global -ErrorAction Stop } catch { Add-HookDependencyFailure -Name 'DiscoveryStartRecord.psm1' -ErrorRecord $_ }
79
+ try { Import-Module (Join-Path $PSScriptRoot '../lib/discovery-validation/DiscoveryPlanning.psm1') -Force -Global -ErrorAction Stop } catch { Add-HookDependencyFailure -Name 'DiscoveryPlanning.psm1' -ErrorRecord $_ }
80
+ } else {
81
+ Import-DiscoveryPlanningSelfHostedModule
82
+ }
83
+
84
+ $script:DiscoveryPlanningReasonPrefix = 'DISCOVERY_PLANNING_GATE_BLOCKED:'
85
+
86
+ function Invoke-DiscoveryPlanningGateDecision {
87
+ <#
88
+ .SYNOPSIS
89
+ Parses the Codex PreToolUse envelope and returns the planning outcome.
90
+ .DESCRIPTION
91
+ Returns the shared outcome object (Decision, Code, Reason, Receipt,
92
+ Prerequisite). Every seam defaults to the real host and is injectable. A
93
+ recorded dependency failure returns a deny outcome before the envelope is read.
94
+ #>
95
+ [CmdletBinding()]
96
+ [OutputType([pscustomobject])]
97
+ param(
98
+ [Parameter(Mandatory = $false)][AllowNull()][AllowEmptyString()][string]$ToolInputRaw,
99
+ [Parameter(Mandatory = $false)][AllowNull()][hashtable]$HostEnvironment = $null,
100
+ [Parameter(Mandatory = $false)][AllowNull()][hashtable]$Store = $null,
101
+ [Parameter(Mandatory = $false)][AllowNull()][scriptblock]$ReadBytes = $null
102
+ )
103
+ $dependencyDecision = Get-HookDependencyFailureDecision -HookEvent PreToolUse -ReasonPrefix $script:DiscoveryPlanningReasonPrefix
104
+ if ($null -ne $dependencyDecision) { return $dependencyDecision }
105
+
106
+ if ($null -eq $HostEnvironment) { $HostEnvironment = Get-DiscoveryTrustedHostEnvironment }
107
+ if ($null -eq $Store) { $Store = Get-DiscoveryStartStore }
108
+
109
+ $normalized = ConvertFrom-DiscoveryHostPayloadText -HostName 'codex' -Text $ToolInputRaw
110
+ $parameters = @{ Normalized = $normalized; HostEnvironment = $HostEnvironment; Store = $Store }
111
+ if ($null -ne $ReadBytes) { $parameters['ReadBytes'] = $ReadBytes }
112
+ return Get-DiscoveryPlanningDecision @parameters
113
+ }
114
+
115
+ function Invoke-DiscoveryPlanningGateEntryPoint {
116
+ <#
117
+ .SYNOPSIS
118
+ Reads one Codex PreToolUse payload, writes the decision and returns the process exit code.
119
+ .DESCRIPTION
120
+ An unreadable envelope writes its reason to stderr and returns 2. A deny
121
+ writes the PreToolUse decision JSON to stdout and returns 0. An allow writes
122
+ nothing and returns 0, as the Codex gates do.
123
+ #>
124
+ [CmdletBinding()]
125
+ [OutputType([int])]
126
+ param([Parameter(Mandatory = $false)][AllowNull()][AllowEmptyString()][string]$PayloadRaw)
127
+
128
+ $outcome = Invoke-DiscoveryPlanningGateDecision -ToolInputRaw $PayloadRaw
129
+ # A dependency failure is already the PreToolUse deny decision.
130
+ if ($outcome -is [System.Collections.IDictionary]) { [Console]::Out.WriteLine(($outcome | ConvertTo-Json -Compress -Depth 5)); return 0 }
131
+ if ($outcome.Decision -eq 'allow') { return 0 }
132
+ if ($outcome.Code -eq 'ENVELOPE') {
133
+ [Console]::Error.WriteLine("$($script:DiscoveryPlanningReasonPrefix) $($outcome.Reason)")
134
+ return 2
135
+ }
136
+ $decision = ConvertTo-DiscoveryPlanningHookOutput -Outcome $outcome -ReasonPrefix $script:DiscoveryPlanningReasonPrefix
137
+ [Console]::Out.WriteLine(($decision | ConvertTo-Json -Compress -Depth 5))
138
+ return 0
139
+ }
140
+
141
+ # Guard allows dot-sourcing in tests without executing the entrypoint.
142
+ if ($MyInvocation.InvocationName -eq '.') {
143
+ return
144
+ }
145
+ if ($script:HookDependencyGuardLoadFailed) { [Console]::Error.WriteLine('DISCOVERY_PLANNING_GATE_BLOCKED: hook-dependency-guard.ps1 failed to load; the gate fails closed.'); exit 2 }
146
+ $dependencyDecision = Get-HookDependencyFailureDecision -HookEvent PreToolUse -ReasonPrefix 'DISCOVERY_PLANNING_GATE_BLOCKED:'
147
+ if ($null -ne $dependencyDecision) { $dependencyDecision | ConvertTo-Json -Compress -Depth 5 | Write-Output; exit 0 }
148
+
149
+ exit (Invoke-DiscoveryPlanningGateEntryPoint -PayloadRaw ([Console]::In.ReadToEnd()))