@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,244 @@
1
+ <#
2
+ .SYNOPSIS
3
+ Pre-tool-use hook that blocks a Write or Edit leaving a covered file above 800 lines.
4
+
5
+ .DESCRIPTION
6
+ This script is invoked by the Claude Code PreToolUse hook before any Write or Edit
7
+ operation. It enforces the hard tier of the tiered file-size policy: 500 lines is
8
+ guidance, 700 lines is advisory, and above 800 lines a split is enforced regardless
9
+ of logical separability. The policy functions live in the shared module
10
+ ../lib/file-size-policy/FileSizePolicy.psm1.
11
+
12
+ Decision order:
13
+ 1. A dependency-load failure denies (fail closed).
14
+ 2. An unreadable envelope denies.
15
+ 3. A path that is not covered (outside the extension allowlist, under an excluded
16
+ directory, or outside the repository root) allows with no file read.
17
+ 4. Write: the resulting size is the logical line count of content. The pre-write
18
+ file is read only when that size is above 800.
19
+ Edit: the pre-edit file is read through the ReadFileContent seam and the
20
+ old_string to new_string replacement is applied in memory. An unreadable or
21
+ missing file, or an edit that cannot be resolved, denies.
22
+ 5. The baseline-free pre-edit-size ratchet decides: a result above 800 lines is
23
+ denied unless the file already existed and does not grow.
24
+
25
+ The hook does not read config/file-size-baseline.json, because it ships to
26
+ repositories that have no baseline; the repository's CI gate is the
27
+ baseline-aware check. The deny shape is hookSpecificOutput.permissionDecision =
28
+ 'deny' with permissionDecisionReason, exit 0.
29
+
30
+ .NOTES
31
+ Compatible with PowerShell 7+.
32
+ This script must not modify any state; it is a read-only validation gate.
33
+ #>
34
+ [CmdletBinding()]
35
+ param()
36
+ $script:HookDependencyGuardLoadFailed = $false; try { . (Join-Path $PSScriptRoot 'hook-dependency-guard.ps1') } catch { $script:HookDependencyGuardLoadFailed = $true }
37
+
38
+ try { Import-Module (Join-Path $PSScriptRoot '../lib/hook-payload/HookPayload.psm1') -Force -ErrorAction Stop } catch { Add-HookDependencyFailure -Name 'HookPayload.psm1' -ErrorRecord $_ }
39
+ try { Import-Module (Join-Path $PSScriptRoot '../lib/file-size-policy/FileSizePolicy.psm1') -Force -ErrorAction Stop } catch { Add-HookDependencyFailure -Name 'FileSizePolicy.psm1' -ErrorRecord $_ }
40
+
41
+ function Get-FileSizeLimitBlockDecision {
42
+ <#
43
+ .SYNOPSIS
44
+ Constructs a deny-decision ordered dictionary carrying the supplied reason.
45
+ .PARAMETER Reason
46
+ The deny reason; it starts with FILE_SIZE_LIMIT_BLOCKED:.
47
+ #>
48
+ [CmdletBinding()]
49
+ [OutputType([System.Collections.Specialized.OrderedDictionary])]
50
+ param(
51
+ [Parameter(Mandatory)]
52
+ [string] $Reason
53
+ )
54
+
55
+ return [ordered]@{
56
+ hookSpecificOutput = [ordered]@{
57
+ hookEventName = 'PreToolUse'
58
+ permissionDecision = 'deny'
59
+ permissionDecisionReason = $Reason
60
+ }
61
+ }
62
+ }
63
+
64
+ function Get-FileSizeLimitAllowDecision {
65
+ <#
66
+ .SYNOPSIS
67
+ Constructs the allow-decision ordered dictionary.
68
+ #>
69
+ [CmdletBinding()]
70
+ [OutputType([System.Collections.Specialized.OrderedDictionary])]
71
+ param()
72
+
73
+ return [ordered]@{ hookSpecificOutput = [ordered]@{ hookEventName = 'PreToolUse'; permissionDecision = 'allow' } }
74
+ }
75
+
76
+ function Get-FileSizeLimitReplaceAllFlag {
77
+ <#
78
+ .SYNOPSIS
79
+ Returns the boolean value of the replace_all property of an Edit tool input.
80
+ .DESCRIPTION
81
+ A boolean is returned as is; a string is true only when its trimmed value is
82
+ 'true' (case-insensitive); every other value, and an absent property, is false.
83
+ No [bool] cast is used because [bool]'false' is $true in PowerShell.
84
+ .PARAMETER ToolInput
85
+ The tool_input object.
86
+ #>
87
+ [CmdletBinding()]
88
+ [OutputType([bool])]
89
+ param(
90
+ [AllowNull()]
91
+ [object] $ToolInput
92
+ )
93
+
94
+ $value = Get-ClaudeHookEnvelopeValue -Envelope $ToolInput -Name 'replace_all'
95
+ if ($value -is [bool]) {
96
+ return $value
97
+ }
98
+ if ($value -is [string]) {
99
+ return ($value.Trim() -ieq 'true')
100
+ }
101
+ return $false
102
+ }
103
+
104
+ function Invoke-FileSizeLimitDecision {
105
+ <#
106
+ .SYNOPSIS
107
+ Parses the PreToolUse envelope and returns an allow-or-deny decision.
108
+ .PARAMETER ToolInputRaw
109
+ The raw JSON hook payload acquired by Read-ClaudeHookRawPayload.
110
+ .PARAMETER RepositoryRoot
111
+ The repository root used to resolve relative paths. Defaults to the current
112
+ location, which is the project root when Claude Code runs the hook.
113
+ .PARAMETER ReadFileContent
114
+ Seam that returns the text of a file, $null when the file does not exist, and
115
+ throws when it cannot be read. Tests supply in-memory content.
116
+ #>
117
+ [CmdletBinding()]
118
+ [OutputType([System.Collections.Specialized.OrderedDictionary])]
119
+ param(
120
+ [AllowNull()]
121
+ [AllowEmptyString()]
122
+ [string] $ToolInputRaw,
123
+
124
+ [string] $RepositoryRoot = (Get-Location).ProviderPath,
125
+
126
+ [scriptblock] $ReadFileContent = {
127
+ param([string] $Path)
128
+ if (-not (Test-Path -LiteralPath $Path -PathType Leaf)) { return $null }
129
+ return [System.IO.File]::ReadAllText($Path)
130
+ }
131
+ )
132
+ $dependencyDecision = Get-HookDependencyFailureDecision -HookEvent PreToolUse -ReasonPrefix 'FILE_SIZE_LIMIT_BLOCKED:'
133
+ if ($null -ne $dependencyDecision) { return $dependencyDecision }
134
+
135
+ $payload = Resolve-ClaudeHookToolInput -Raw $ToolInputRaw
136
+ if (-not $payload.IsValid) {
137
+ return Get-FileSizeLimitBlockDecision -Reason ('FILE_SIZE_LIMIT_BLOCKED: payload anomaly - ' +
138
+ (Get-ClaudeHookPayloadAnomalyReason -Anomaly $payload.Anomaly) +
139
+ '. The gate fails closed on an envelope it cannot read.')
140
+ }
141
+
142
+ $toolInput = $payload.Value
143
+ $filePath = Get-ClaudeHookToolInputString -ToolInput $toolInput -Name 'file_path'
144
+ $relativePath = ConvertTo-FileSizeRelativePath -Path $filePath -RepositoryRoot $RepositoryRoot
145
+ if (-not (Test-FileSizeCoveredPath -RelativePath $relativePath)) {
146
+ return Get-FileSizeLimitAllowDecision
147
+ }
148
+
149
+ $isRooted = ($filePath -match '^[\\/]') -or ($filePath -match '^[A-Za-z]:[\\/]')
150
+ $readPath = if ($isRooted) { $filePath } else { Join-Path $RepositoryRoot $relativePath }
151
+ $toolName = Get-ClaudeHookToolInputString -ToolInput $payload.Envelope -Name 'tool_name'
152
+ $isEdit = ($toolName -eq 'Edit')
153
+
154
+ $resultCount = 0
155
+ if (-not $isEdit) {
156
+ $resultCount = Get-FileSizeLogicalLineCount -Content (Get-ClaudeHookToolInputString -ToolInput $toolInput -Name 'content')
157
+ if ($resultCount -le (Get-FileSizePolicyLimit).HardLimit) {
158
+ return Get-FileSizeLimitAllowDecision
159
+ }
160
+ }
161
+
162
+ try {
163
+ $preEditContent = & $ReadFileContent $readPath
164
+ } catch {
165
+ return Get-FileSizeLimitBlockDecision -Reason "FILE_SIZE_LIMIT_BLOCKED: '$relativePath' could not be read to measure its size ($($_.Exception.Message)). The gate fails closed for a covered file."
166
+ }
167
+
168
+ $preEditCount = $null
169
+ if ($null -ne $preEditContent) {
170
+ $preEditCount = Get-FileSizeLogicalLineCount -Content ([string]$preEditContent)
171
+ }
172
+
173
+ if ($isEdit) {
174
+ if ($null -eq $preEditContent) {
175
+ return Get-FileSizeLimitBlockDecision -Reason "FILE_SIZE_LIMIT_BLOCKED: '$relativePath' does not exist, so the Edit cannot be measured. The gate fails closed for a covered file."
176
+ }
177
+ $edit = Resolve-FileSizeEditContent -Content ([string]$preEditContent) `
178
+ -OldString (Get-ClaudeHookToolInputString -ToolInput $toolInput -Name 'old_string') `
179
+ -NewString (Get-ClaudeHookToolInputString -ToolInput $toolInput -Name 'new_string') `
180
+ -ReplaceAll (Get-FileSizeLimitReplaceAllFlag -ToolInput $toolInput)
181
+ if ($null -ne $edit.Failure) {
182
+ return Get-FileSizeLimitBlockDecision -Reason "FILE_SIZE_LIMIT_BLOCKED: the Edit to '$relativePath' could not be resolved in memory ($($edit.Failure)). The gate fails closed for a covered file."
183
+ }
184
+ $resultCount = Get-FileSizeLogicalLineCount -Content $edit.Content
185
+ }
186
+
187
+ $decision = Get-FileSizeHookDecision -RelativePath $relativePath -ResultLineCount $resultCount -PreEditLineCount $preEditCount
188
+ if ($decision.Allowed) {
189
+ return Get-FileSizeLimitAllowDecision
190
+ }
191
+ return Get-FileSizeLimitBlockDecision -Reason $decision.Reason
192
+ }
193
+
194
+ function Invoke-FileSizeLimitEntryPoint {
195
+ <#
196
+ .SYNOPSIS
197
+ Runs the file-size decision and returns the process exit code.
198
+ .DESCRIPTION
199
+ Acquires the payload through the shared reader unless the caller supplies one,
200
+ writes the compact JSON decision to the output stream, and returns 0. It never
201
+ returns 1: exit 1 is non-blocking for PreToolUse, so every anomaly is already a
202
+ deny decision by the time control reaches here.
203
+ .PARAMETER ToolInputRaw
204
+ Optional pre-acquired payload text. When omitted the ReadPayload seam runs.
205
+ .PARAMETER ReadPayload
206
+ Seam for payload acquisition.
207
+ #>
208
+ [CmdletBinding()]
209
+ [OutputType([int])]
210
+ param(
211
+ [AllowNull()]
212
+ [AllowEmptyString()]
213
+ [string] $ToolInputRaw,
214
+
215
+ [scriptblock] $ReadPayload = { Read-ClaudeHookRawPayload }
216
+ )
217
+
218
+ if (-not $PSBoundParameters.ContainsKey('ToolInputRaw')) {
219
+ $ToolInputRaw = [string](& $ReadPayload)
220
+ }
221
+
222
+ $decision = Invoke-FileSizeLimitDecision -ToolInputRaw $ToolInputRaw
223
+
224
+ $decision | ConvertTo-Json -Compress -Depth 5 | Write-Output
225
+
226
+ return 0
227
+ }
228
+
229
+ # Guard allows dot-sourcing in tests without executing the entrypoint.
230
+ if ($MyInvocation.InvocationName -eq '.') {
231
+ return
232
+ }
233
+ if ($script:HookDependencyGuardLoadFailed) { [Console]::Error.WriteLine('FILE_SIZE_LIMIT_BLOCKED: hook-dependency-guard.ps1 failed to load; the gate fails closed.'); exit 2 }
234
+ $dependencyDecision = Get-HookDependencyFailureDecision -HookEvent PreToolUse -ReasonPrefix 'FILE_SIZE_LIMIT_BLOCKED:'
235
+ if ($null -ne $dependencyDecision) { $dependencyDecision | ConvertTo-Json -Compress -Depth 5 | Write-Output; exit 0 }
236
+
237
+ # The entry point returns its [int] exit code as the last pipeline element and the
238
+ # decision JSON before it, so the decision is written explicitly here first.
239
+ $entryPointResult = @(Invoke-FileSizeLimitEntryPoint)
240
+ if ($entryPointResult.Count -gt 1) {
241
+ $entryPointResult[0..($entryPointResult.Count - 2)] | Write-Output
242
+ }
243
+
244
+ exit ([int]$entryPointResult[-1])
@@ -40,6 +40,14 @@
40
40
  delegation prompt to a receipt-gated subagent type carries the canonical issue
41
41
  number line and a `branch:` label naming the item's branch.
42
42
 
43
+ Author-asserted autoclose line (issue #989): for subagent `pr-author` only, once the
44
+ per-feature receipt is confirmed, a checkpoint that records an `issue-num` and whose
45
+ `epic_mode` is not true requires the prompt line
46
+ `Author-asserted autoclose issues: #<issue-num>` at the start of a line. Its absence denies
47
+ with the AUTHOR_ASSERTED_AUTOCLOSE_MISSING sub-code (Get-ModelRoutingAuthorAssertedReason).
48
+ The epic-scope path is not subject to this rule. Only the JSON boolean true waives the line;
49
+ a string or number such as "true" or 1 does not (issue #1001).
50
+
43
51
  .NOTES
44
52
  Compatible with PowerShell 7+. Read-only presence-gating deterrent.
45
53
  #>
@@ -198,6 +206,44 @@ function Get-ModelRoutingTargetCheckpointResolution {
198
206
  }
199
207
  }
200
208
 
209
+ function Get-ModelRoutingAuthorAssertedReason {
210
+ <#
211
+ .SYNOPSIS
212
+ Return the deny reason for a pr-author delegation that omits the author-asserted line, or $null.
213
+ .DESCRIPTION
214
+ Returns $null when the checkpoint records no usable issue-num, when it carries an
215
+ epic_mode property whose value is true (an epic child whose integration PR owns the
216
+ closing keyword), or when a prompt line starts with 'Author-asserted autoclose issues:'
217
+ and names '#<issue-num>' later on that line with no digit after the number. Property
218
+ presence is tested first because strict mode throws on a missing property. Only the
219
+ JSON boolean true waives the line: a string or number such as "true" or 1 does not
220
+ (issue #1001).
221
+ .PARAMETER Checkpoint
222
+ The resolved per-feature checkpoint object.
223
+ .PARAMETER PromptText
224
+ The delegation prompt.
225
+ .OUTPUTS
226
+ System.String or $null
227
+ #>
228
+ [CmdletBinding()]
229
+ [OutputType([string])]
230
+ param(
231
+ [Parameter(Mandatory)][AllowNull()] $Checkpoint,
232
+ [Parameter(Mandatory)][AllowEmptyString()][string] $PromptText
233
+ )
234
+
235
+ $names = @($Checkpoint.PSObject.Properties.Name)
236
+ $issue = if ($names -contains 'issue-num') { ConvertTo-WorktreeItemIssueNumber -Value $Checkpoint.'issue-num' } else { $null }
237
+ if ($null -eq $issue -or ($names -contains 'epic_mode' -and ($Checkpoint.epic_mode -is [bool]) -and $Checkpoint.epic_mode)) {
238
+ return $null
239
+ }
240
+ $line = "Author-asserted autoclose issues: #$issue"
241
+ if ([regex]::IsMatch($PromptText, '(?m)^Author-asserted autoclose issues:[^\r\n]*#' + $issue + '(?!\d)')) {
242
+ return $null
243
+ }
244
+ return "MODEL_ROUTING_RECEIPT_BLOCKED: AUTHOR_ASSERTED_AUTOCLOSE_MISSING: the checkpoint records issue-num $issue, so the Agent(pr-author) delegation prompt must carry the line '$line' so the PR body emits '- Closes #$issue'. Add that line on its own line, or omit it only for an epic child (epic_mode true)."
245
+ }
246
+
201
247
  function Invoke-ModelRoutingReceiptDecision {
202
248
  <#
203
249
  .SYNOPSIS
@@ -274,6 +320,11 @@ function Invoke-ModelRoutingReceiptDecision {
274
320
 
275
321
  $checkpoint = Get-ModelRoutingCheckpoint -CheckpointPath $resolution.CheckpointPath
276
322
  if (Test-ModelRoutingReceiptPresent -Checkpoint $checkpoint -Subagent $subagent) {
323
+ # Issue #989: the pr-author delegation names the item's issue as author-asserted.
324
+ $authorAssertedReason = if ($subagent -eq 'pr-author') { Get-ModelRoutingAuthorAssertedReason -Checkpoint $checkpoint -PromptText $prompt } else { $null }
325
+ if ($authorAssertedReason) {
326
+ return [ordered]@{ hookSpecificOutput = [ordered]@{ hookEventName = 'PreToolUse'; permissionDecision = 'deny'; permissionDecisionReason = $authorAssertedReason } }
327
+ }
277
328
  return $allow
278
329
  }
279
330
 
@@ -3,7 +3,7 @@
3
3
  Epic-scope legs, checkpoint read seams, and target resolution of the preimplementation gate.
4
4
 
5
5
  .DESCRIPTION
6
- Dot-sourced by enforce-orchestration-preimplementation-gate.ps1. Holds four groups of
6
+ Dot-sourced by enforce-orchestration-preimplementation-gate.ps1. Holds five groups of
7
7
  functions:
8
8
 
9
9
  - The import guards for the worktree-resolution modules (issue #690). A failed import
@@ -15,13 +15,20 @@
15
15
  read binds to the calling process's directory. Get-CheckpointContent and
16
16
  Get-OrchestrationModeDenyReason were relocated here from the gate file by issue #690
17
17
  to keep the gate inside the 500-line cap.
18
+ - The target-resolution building blocks of issue #1010: the worktree-list wrapper
19
+ Get-OrchestrationGateWorktreeList (the only listing seam), the recording invoker
20
+ Invoke-OrchestrationGateWorktreeList, which records a failed or empty listing in
21
+ $script:OrchestrationGateWorktreeListFailed, and the command-operand parser
22
+ Get-OrchestrationGateCommandOperandPath for git add and git commit.
18
23
  - The target resolution of issue #690. Resolve-OrchestrationGateTarget selects the
19
24
  worktree whose checkpoint governs the call from portable identity only: the
20
25
  integration_branch: value for an epic delegation, the parallel_slug: value for a
21
- parallel delegation, the file_path or git -C operand for the path and command legs,
22
- and the canonical issue-number line and branch: label for a single-feature
23
- delegation. Read-OrchestrationGateCheckpoint reads the checkpoint beneath the
24
- resolved root, or returns the deny for an unresolved target.
26
+ parallel delegation, and the canonical issue-number line and branch: label for a
27
+ single-feature delegation. The path and command legs resolve through
28
+ Resolve-HookTargetWorktree (issue #1010) from the file_path or from every git add
29
+ and git commit selector and absolute operand. Read-OrchestrationGateCheckpoint reads
30
+ the checkpoint beneath the resolved root, or returns the deny for an unresolved
31
+ target.
25
32
  - The epic-scope decision for the command and path legs (issue #663). A staging
26
33
  command or a Write/Edit call is epic scope when the effective worktree's HEAD equals
27
34
  the integration branch of the epic checkpoint that Resolve-EpicScopeCheckpoint
@@ -30,21 +37,24 @@
30
37
 
31
38
  .NOTES
32
39
  PowerShell 7+. Depends on functions the gate defines or dot-sources before any call:
33
- Split-OrchestrationCommandLine and ConvertTo-OrchestrationCommandToken (helpers file),
34
40
  Get-OrchestrationDelegationCheckpointPath (modes file), the gate's allow and block
35
- decision constructors, and, through the targets file this file dot-sources (issue #738),
36
- Read-CommandLineSegment, Get-CommandLineGlobalOption, and Get-CommandLineInvocation
37
- (loaded by the gate's dot-source of hook-command-invocation.ps1). Imports
38
- WorktreeItemResolution.psm1 and WorktreeRunResolution.psm1 before
39
- EpicScopeResolution.psm1, so the nested import inside EpicScopeResolution reuses the
40
- same module instance. Mirrored byte-identically under
41
+ decision constructors, and Read-CommandLineSegment, Get-CommandLineGlobalOption, and
42
+ Get-CommandLineInvocation (loaded by the gate's dot-source of
43
+ hook-command-invocation.ps1), which the targets file this file dot-sources (issue #738)
44
+ and Get-OrchestrationGateCommandOperandPath call. Imports
45
+ WorktreeResolution.psm1 (the reason-code accessors), then WorktreeItemResolution.psm1
46
+ and WorktreeRunResolution.psm1 before EpicScopeResolution.psm1, so the nested import
47
+ inside EpicScopeResolution reuses the same module instance, and HookTargetWorktree.psm1
48
+ (Resolve-HookTargetWorktree, issue #1009) last. Mirrored byte-identically under
41
49
  extensions/drm-copilot/resources/claude-customizations/.
42
50
  #>
43
51
 
52
+ try { Import-Module (Join-Path $PSScriptRoot '../lib/worktree-resolution/WorktreeResolution.psm1') -Force -ErrorAction Stop } catch { Add-HookDependencyFailure -Name 'WorktreeResolution.psm1' -ErrorRecord $_ }
44
53
  try { Import-Module (Join-Path $PSScriptRoot '../lib/worktree-resolution/WorktreeItemResolution.psm1') -Force -ErrorAction Stop } catch { Add-HookDependencyFailure -Name 'WorktreeItemResolution.psm1' -ErrorRecord $_ }
45
54
  try { Import-Module (Join-Path $PSScriptRoot '../lib/worktree-resolution/WorktreeRunResolution.psm1') -Force -ErrorAction Stop } catch { Add-HookDependencyFailure -Name 'WorktreeRunResolution.psm1' -ErrorRecord $_ }
46
55
  try { Import-Module (Join-Path $PSScriptRoot '../lib/worktree-resolution/EpicScopeResolution.psm1') -Force -ErrorAction Stop } catch { Add-HookDependencyFailure -Name 'EpicScopeResolution.psm1' -ErrorRecord $_ }
47
56
  try { Import-Module (Join-Path $PSScriptRoot '../lib/worktree-resolution/EpicScopeReadiness.psm1') -Force -ErrorAction Stop } catch { Add-HookDependencyFailure -Name 'EpicScopeReadiness.psm1' -ErrorRecord $_ }
57
+ try { Import-Module (Join-Path $PSScriptRoot '../lib/worktree-resolution/HookTargetWorktree.psm1') -Force -ErrorAction Stop } catch { Add-HookDependencyFailure -Name 'HookTargetWorktree.psm1' -ErrorRecord $_ }
48
58
  # Per-segment target resolution for the epic-scope decision (issue #738).
49
59
  . (Join-Path $PSScriptRoot 'enforce-orchestration-preimplementation-gate-targets.ps1')
50
60
 
@@ -102,15 +112,137 @@ function Get-OrchestrationModeDenyReason {
102
112
  'require that checkpoint to satisfy every readiness predicate before implementation begins.')
103
113
  }
104
114
 
115
+ function Get-OrchestrationGateWorktreeList {
116
+ <#
117
+ .SYNOPSIS
118
+ Returns the porcelain worktree listing for the session root (issue #1010 seam).
119
+ .DESCRIPTION
120
+ Runs the listing exactly as the default WorktreeListInvoker of
121
+ Resolve-HookTargetWorktree does and returns an empty string on a non-zero exit. It
122
+ is the only test seam for the listing.
123
+ .OUTPUTS
124
+ System.String
125
+ #>
126
+ [CmdletBinding()]
127
+ [OutputType([string])]
128
+ param([Parameter(Mandatory)][string] $SessionRoot)
129
+
130
+ $porcelain = & git -C $SessionRoot worktree list --porcelain 2>$null
131
+ if ($LASTEXITCODE -ne 0) { return '' }
132
+ return ($porcelain -join "`n")
133
+ }
134
+
135
+ function Invoke-OrchestrationGateWorktreeList {
136
+ <#
137
+ .SYNOPSIS
138
+ Recording WorktreeListInvoker: returns the listing and records a listing failure.
139
+ .DESCRIPTION
140
+ Sets $script:OrchestrationGateWorktreeListFailed when the wrapper throws (and then
141
+ rethrows) or when its text holds no worktree entry, so the gate denies instead of
142
+ accepting the resolver's session-root fallback (issue #1010, spec E1).
143
+ .OUTPUTS
144
+ System.String
145
+ #>
146
+ [CmdletBinding()]
147
+ [OutputType([string])]
148
+ param([Parameter(Mandatory)][string] $SessionRoot)
149
+
150
+ try {
151
+ $text = [string](Get-OrchestrationGateWorktreeList -SessionRoot $SessionRoot)
152
+ } catch {
153
+ $script:OrchestrationGateWorktreeListFailed = $true
154
+ throw
155
+ }
156
+ if (@(ConvertFrom-HookTargetWorktreePorcelain -Text $text).Count -eq 0) {
157
+ $script:OrchestrationGateWorktreeListFailed = $true
158
+ }
159
+ return $text
160
+ }
161
+
162
+ function Get-OrchestrationGateCommandOperandPath {
163
+ <#
164
+ .SYNOPSIS
165
+ Returns the worktree-selecting paths of every git add and git commit invocation.
166
+ .DESCRIPTION
167
+ Scans every Structural match of git add and git commit (every command segment and
168
+ wrapper payload). Each -C value in any git global-option position and each absolute
169
+ operand is returned, distinct and in first-seen order. Relative operands, a -C on a
170
+ git segment invoking neither add nor commit, and Indeterminate matches are ignored.
171
+ For a match whose record is not argument-injected, a subcommand-aware walk (issue
172
+ #1010, F2) also reads the tokens after the subcommand with a per-subcommand option
173
+ model, compared case-sensitively: a value option consumes the next token unless its
174
+ value is inline (--name=value) or attached (-mvalue); a standalone flag consumes
175
+ itself; '--' makes every later token an operand; a redirection and its target are
176
+ skipped; any other dash token, such as the cluster -am, stops the walk. Its literal
177
+ absolute tokens are returned, and a token the walk reads as an option value is not
178
+ returned as an operand.
179
+ .PARAMETER Command
180
+ The full command line.
181
+ .OUTPUTS
182
+ System.String[]
183
+ #>
184
+ [CmdletBinding()]
185
+ [OutputType([string[]])]
186
+ param([Parameter(Mandatory)][AllowEmptyString()][string] $Command)
187
+
188
+ $valueOptions = @{
189
+ commit = @('-m', '--message', '-F', '--file', '--author', '--date', '-C', '--reuse-message', '-c', '--reedit-message', '-t', '--template', '--fixup', '--squash', '--trailer', '--pathspec-from-file')
190
+ add = @('--pathspec-from-file', '--chmod')
191
+ }
192
+ $flagOptions = @{
193
+ commit = @('-a', '--all', '--amend', '--no-edit', '--no-verify', '-n', '-s', '--signoff', '-q', '--quiet', '-v', '--verbose', '--allow-empty', '-o', '--only', '-i', '--include', '--pathspec-file-nul')
194
+ add = @('-A', '--all', '-u', '--update', '-f', '--force', '-N', '--intent-to-add', '-n', '--dry-run', '-v', '--verbose', '--pathspec-file-nul')
195
+ }
196
+ $absolutePattern = '^([A-Za-z]:[\\/]|/)'
197
+ $paths = [System.Collections.Generic.List[string]]::new()
198
+ foreach ($subcommand in @('add', 'commit')) {
199
+ foreach ($match in @(Get-CommandLineInvocation -CommandText $Command -CommandWord 'git' -SubcommandPath @($subcommand))) {
200
+ if ($match.Status -ne 'Structural') { continue }
201
+ $walked = [System.Collections.Generic.List[string]]::new()
202
+ $optionValues = [System.Collections.Generic.List[string]]::new()
203
+ $tokens = if ($match.Segment.ArgumentInjected) { [string[]]@() } else { [string[]]@($match.Segment.Tokens) }
204
+ $afterSeparator = $false
205
+ for ($index = [int]$match.OperandIndex; $index -lt $tokens.Count; $index++) {
206
+ $token = $tokens[$index]
207
+ if (-not $afterSeparator -and $token -match '^(<|>|\d*>|&>)') {
208
+ if ($token -match '^(\d*[<>]{1,2}&?|&>{1,2})$') { $index++ }
209
+ continue
210
+ }
211
+ if ($afterSeparator -or -not $token.StartsWith('-')) { $walked.Add($token); continue }
212
+ if ($token -ceq '--') { $afterSeparator = $true; continue }
213
+ $name = if ($token.IndexOf('=') -gt 0) { $token.Substring(0, $token.IndexOf('=')) } else { $token }
214
+ if ($valueOptions[$subcommand] -ccontains $name) {
215
+ if ($name -ceq $token -and $index + 1 -lt $tokens.Count) { $index++; $optionValues.Add($tokens[$index]) }
216
+ continue
217
+ }
218
+ if ($token -match '^-[^-].' -and $valueOptions[$subcommand] -ccontains $token.Substring(0, 2)) { continue }
219
+ if ($flagOptions[$subcommand] -ccontains $token) { continue }
220
+ break
221
+ }
222
+ $candidates = @(@($match.GlobalOptions) | Where-Object { $_.Name -ceq '-C' -and $_.Value } | ForEach-Object { [string]$_.Value })
223
+ $candidates += @(@($match.Operands) | Where-Object { $_ -match $absolutePattern -and $optionValues -cnotcontains $_ })
224
+ $candidates += @($walked | Where-Object { $_ -match $absolutePattern -and (Test-CommandLineTokenLiteral -Token $_) })
225
+ foreach ($candidate in $candidates) {
226
+ if ($paths -notcontains $candidate) { $paths.Add($candidate) }
227
+ }
228
+ }
229
+ }
230
+ return [string[]]$paths.ToArray()
231
+ }
232
+
105
233
  function Resolve-OrchestrationGateTarget {
106
234
  <#
107
235
  .SYNOPSIS
108
236
  Resolves the worktree whose checkpoint governs a gated call (issue #690 seam).
109
237
  .DESCRIPTION
110
238
  An epic delegation is keyed on integration_branch: (with epic_feature_folder: as a
111
- cross-check), a parallel delegation on parallel_slug:, a path leg on its file_path
112
- operand, a command leg on its git -C selector (none means the session root), and a
113
- single-feature delegation on its canonical issue-number line and branch: label.
239
+ cross-check), a parallel delegation on parallel_slug:, and a single-feature
240
+ delegation on its canonical issue-number line and branch: label. The path and
241
+ command legs use Resolve-HookTargetWorktree (issue #1010): a path leg passes its
242
+ file_path, a command leg the Get-OrchestrationGateCommandOperandPath result, and the
243
+ recording invoker supplies the worktree listing. A failed or empty listing denies as
244
+ not derivable instead of falling back to the session root; an ambiguous result
245
+ denies as ambiguous; a null root denies as not derivable.
114
246
  .OUTPUTS
115
247
  System.Management.Automation.PSCustomObject (the worktree-resolution target result).
116
248
  #>
@@ -131,13 +263,29 @@ function Resolve-OrchestrationGateTarget {
131
263
  }
132
264
  return Resolve-WorktreeParallelTarget -ParallelSlug $signal.ParallelSlug -SessionRoot $sessionRoot
133
265
  }
134
- if ($FilePath) {
135
- return Resolve-WorktreeOperandTarget -Path $FilePath -SessionRoot $sessionRoot
266
+ if (-not $FilePath -and -not $Command) {
267
+ return Resolve-WorktreeItemTarget -Text $Prompt -SessionRoot $sessionRoot
268
+ }
269
+ $script:OrchestrationGateWorktreeListFailed = $false
270
+ $invoker = { param($SessionRoot) Invoke-OrchestrationGateWorktreeList -SessionRoot $SessionRoot }
271
+ $resolved = if ($FilePath) {
272
+ Resolve-HookTargetWorktree -SessionRoot $sessionRoot -FilePath @($FilePath) -WorktreeListInvoker $invoker
273
+ } else {
274
+ Resolve-HookTargetWorktree -SessionRoot $sessionRoot -CommandOperandPath @(Get-OrchestrationGateCommandOperandPath -Command $Command) -WorktreeListInvoker $invoker
275
+ }
276
+ $detail = "resolver source $($resolved.Source): $($resolved.Detail)"
277
+ if ($script:OrchestrationGateWorktreeListFailed) {
278
+ return [pscustomobject]@{ Status = 'NoTarget'; WorktreeRoot = $null; ReasonCode = (Get-WorktreeResolutionNoTargetReasonCode); Detail = "the worktree listing failed or named no worktree; $detail" }
136
279
  }
137
- if ($Command) {
138
- return Resolve-WorktreeOperandTarget -Path (Get-OrchestrationEpicScopeSelector -Command $Command) -SessionRoot $sessionRoot
280
+ if ($resolved.Ambiguous) {
281
+ return [pscustomobject]@{ Status = 'Ambiguous'; WorktreeRoot = $null; ReasonCode = (Get-WorktreeResolutionAmbiguityReasonCode); Detail = $detail }
139
282
  }
140
- return Resolve-WorktreeItemTarget -Text $Prompt -SessionRoot $sessionRoot
283
+ if ([string]::IsNullOrEmpty([string]$resolved.WorktreeRoot)) {
284
+ return [pscustomobject]@{ Status = 'NoTarget'; WorktreeRoot = $null; ReasonCode = (Get-WorktreeResolutionNoTargetReasonCode); Detail = $detail }
285
+ }
286
+ $isSession = [string]::Equals([string]$resolved.WorktreeRoot, (ConvertTo-HookTargetWorktreeNormalizedPath -Path $sessionRoot), [System.StringComparison]::OrdinalIgnoreCase)
287
+ $status = if ($isSession) { 'SessionRoot' } else { 'OtherWorktree' }
288
+ return [pscustomobject]@{ Status = $status; WorktreeRoot = [string]$resolved.WorktreeRoot; ReasonCode = $null; Detail = $detail }
141
289
  }
142
290
 
143
291
  function Read-OrchestrationGateCheckpoint {
@@ -187,34 +335,6 @@ function Read-OrchestrationGateCheckpoint {
187
335
  }
188
336
  }
189
337
 
190
- function Get-OrchestrationEpicScopeSelector {
191
- <#
192
- .SYNOPSIS
193
- Returns the value of a leading `git -C <value>` selector, or $null.
194
- .DESCRIPTION
195
- Pure. Reads only the first segment of the command line, split and tokenized with
196
- the helpers-file parser so quoting is handled exactly as the staging exemption
197
- handles it. An unbalanced command line has no decidable selector and returns $null.
198
- .PARAMETER Command
199
- The full command line.
200
- .OUTPUTS
201
- System.String
202
- #>
203
- [CmdletBinding()]
204
- [OutputType([string])]
205
- param([Parameter(Mandatory)][AllowEmptyString()][string] $Command)
206
-
207
- $split = Split-OrchestrationCommandLine -CommandText $Command
208
- if (-not $split.Balanced -or @($split.Segments).Count -eq 0) {
209
- return $null
210
- }
211
- $token = @(ConvertTo-OrchestrationCommandToken -Segment ([string]@($split.Segments)[0]).Trim())
212
- if ($token.Count -ge 3 -and $token[0] -ceq 'git' -and $token[1] -ceq '-C' -and $token[2]) {
213
- return $token[2]
214
- }
215
- return $null
216
- }
217
-
218
338
  function Get-OrchestrationEpicScopeDecision {
219
339
  <#
220
340
  .SYNOPSIS
@@ -239,7 +239,7 @@ function Test-OrchestrationReady {
239
239
  }
240
240
  $lifecycleReady = $false
241
241
  if ($Payload.PSObject.Properties.Name -contains 'lifecycle_ready') {
242
- $lifecycleReady = [bool]$Payload.lifecycle_ready
242
+ $lifecycleReady = ($Payload.lifecycle_ready -is [bool]) -and $Payload.lifecycle_ready
243
243
  }
244
244
 
245
245
  if (-not $issueNum -or -not $featureFolder -or -not $routeId -or -not $lifecycleReady) {