@danmoisan/drm-copilot-mcp 1.1.17 → 1.1.19

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 (225) hide show
  1. package/out/mcp-server.js +1405 -684
  2. package/package.json +6 -4
  3. package/resources/claude-customizations/.claude/agents/atomic-executor.md +11 -0
  4. package/resources/claude-customizations/.claude/agents/atomic-planner.md +10 -0
  5. package/resources/claude-customizations/.claude/agents/epic-orchestrator.md +12 -4
  6. package/resources/claude-customizations/.claude/agents/epic-planner.md +5 -4
  7. package/resources/claude-customizations/.claude/agents/feature-review.md +16 -5
  8. package/resources/claude-customizations/.claude/agents/orchestrator.md +21 -7
  9. package/resources/claude-customizations/.claude/agents/parallel-orchestrator.md +37 -13
  10. package/resources/claude-customizations/.claude/agents/parallel-planner.md +9 -6
  11. package/resources/claude-customizations/.claude/agents/pr-author.md +15 -2
  12. package/resources/claude-customizations/.claude/agents/prd-feature.md +1 -1
  13. package/resources/claude-customizations/.claude/hooks/check-powershell-test-purity.ps1 +7 -1
  14. package/resources/claude-customizations/.claude/hooks/check-python-test-purity.ps1 +7 -1
  15. package/resources/claude-customizations/.claude/hooks/enforce-checkpoint-monotonic.ps1 +7 -1
  16. package/resources/claude-customizations/.claude/hooks/enforce-completion-consistency.ps1 +111 -46
  17. package/resources/claude-customizations/.claude/hooks/enforce-completion-helpers.ps1 +105 -0
  18. package/resources/claude-customizations/.claude/hooks/enforce-discovery-artifact-gate.ps1 +8 -1
  19. package/resources/claude-customizations/.claude/hooks/enforce-epic-invocation-origin.ps1 +7 -1
  20. package/resources/claude-customizations/.claude/hooks/enforce-epic-merge-gate-resolution.ps1 +116 -59
  21. package/resources/claude-customizations/.claude/hooks/enforce-epic-merge-gate.ps1 +55 -23
  22. package/resources/claude-customizations/.claude/hooks/enforce-epic-wave-barrier.ps1 +74 -75
  23. package/resources/claude-customizations/.claude/hooks/enforce-epic-worktree-removal-gate-resolution.ps1 +127 -35
  24. package/resources/claude-customizations/.claude/hooks/enforce-epic-worktree-removal-gate.ps1 +61 -57
  25. package/resources/claude-customizations/.claude/hooks/enforce-evidence-locations.ps1 +7 -1
  26. package/resources/claude-customizations/.claude/hooks/enforce-feature-folder-order.ps1 +129 -39
  27. package/resources/claude-customizations/.claude/hooks/enforce-mermaid-validation.ps1 +7 -1
  28. package/resources/claude-customizations/.claude/hooks/enforce-model-routing-receipt.ps1 +9 -3
  29. package/resources/claude-customizations/.claude/hooks/enforce-orchestration-preimplementation-gate-epic-scope.ps1 +39 -51
  30. package/resources/claude-customizations/.claude/hooks/enforce-orchestration-preimplementation-gate-helpers.ps1 +31 -58
  31. package/resources/claude-customizations/.claude/hooks/enforce-orchestration-preimplementation-gate-modes.ps1 +63 -47
  32. package/resources/claude-customizations/.claude/hooks/enforce-orchestration-preimplementation-gate-targets.ps1 +433 -0
  33. package/resources/claude-customizations/.claude/hooks/enforce-orchestration-preimplementation-gate.ps1 +17 -12
  34. package/resources/claude-customizations/.claude/hooks/enforce-parallel-abandon-gate.ps1 +9 -3
  35. package/resources/claude-customizations/.claude/hooks/enforce-parallel-cohort-barrier.ps1 +65 -50
  36. package/resources/claude-customizations/.claude/hooks/enforce-parallel-drift-gate.ps1 +49 -42
  37. package/resources/claude-customizations/.claude/hooks/enforce-parallel-worktree-removal-gate.ps1 +54 -72
  38. package/resources/claude-customizations/.claude/hooks/enforce-powershell-batch-budget.ps1 +8 -2
  39. package/resources/claude-customizations/.claude/hooks/enforce-pr-author-command-allowlist.ps1 +279 -0
  40. package/resources/claude-customizations/.claude/hooks/enforce-pr-author-skill-helpers.ps1 +129 -75
  41. package/resources/claude-customizations/.claude/hooks/enforce-pr-author-skill.artifact-root.ps1 +233 -0
  42. package/resources/claude-customizations/.claude/hooks/enforce-pr-author-skill.docs-only.ps1 +224 -0
  43. package/resources/claude-customizations/.claude/hooks/enforce-pr-author-skill.ps1 +69 -24
  44. package/resources/claude-customizations/.claude/hooks/enforce-prd-feature-before-planner-helpers.ps1 +29 -18
  45. package/resources/claude-customizations/.claude/hooks/enforce-prd-feature-before-planner.ps1 +10 -4
  46. package/resources/claude-customizations/.claude/hooks/enforce-promotion-mcp-only.ps1 +14 -5
  47. package/resources/claude-customizations/.claude/hooks/enforce-python-batch-budget.ps1 +8 -2
  48. package/resources/claude-customizations/.claude/hooks/feature-folder-resolution.ps1 +373 -0
  49. package/resources/claude-customizations/.claude/hooks/feature-review-coverage-thresholds.ps1 +85 -0
  50. package/resources/claude-customizations/.claude/hooks/hook-command-heredoc.ps1 +119 -0
  51. package/resources/claude-customizations/.claude/hooks/hook-command-invocation-operands.ps1 +198 -0
  52. package/resources/claude-customizations/.claude/hooks/hook-command-invocation.ps1 +254 -255
  53. package/resources/claude-customizations/.claude/hooks/hook-command-payload-powershell.ps1 +201 -0
  54. package/resources/claude-customizations/.claude/hooks/hook-command-payload.ps1 +484 -0
  55. package/resources/claude-customizations/.claude/hooks/hook-command-scanner.ps1 +27 -110
  56. package/resources/claude-customizations/.claude/hooks/hook-dependency-guard.ps1 +114 -0
  57. package/resources/claude-customizations/.claude/hooks/hook-docs-only-diff.ps1 +493 -0
  58. package/resources/claude-customizations/.claude/hooks/subagentstop-envelope.ps1 +192 -0
  59. package/resources/claude-customizations/.claude/hooks/validate-bash.ps1 +9 -3
  60. package/resources/claude-customizations/.claude/hooks/validate-discovery-artifact-gate.ps1 +40 -42
  61. package/resources/claude-customizations/.claude/hooks/validate-executor-output.ps1 +66 -38
  62. package/resources/claude-customizations/.claude/hooks/validate-feature-review-coverage-metrics.ps1 +180 -0
  63. package/resources/claude-customizations/.claude/hooks/validate-feature-review-coverage-rules.ps1 +195 -0
  64. package/resources/claude-customizations/.claude/hooks/validate-feature-review-coverage.ps1 +141 -395
  65. package/resources/claude-customizations/.claude/hooks/validate-orchestrator-output-resolution.ps1 +311 -0
  66. package/resources/claude-customizations/.claude/hooks/validate-orchestrator-output-routing.ps1 +170 -0
  67. package/resources/claude-customizations/.claude/hooks/validate-orchestrator-output.ps1 +115 -190
  68. package/resources/claude-customizations/.claude/hooks/validate-planner-output.ps1 +64 -32
  69. package/resources/claude-customizations/.claude/hooks/validate-pr-author-output.ps1 +39 -44
  70. package/resources/claude-customizations/.claude/hooks/validate-prd-feature-output.ps1 +43 -14
  71. package/resources/claude-customizations/.claude/hooks/validate-required-artifact-output.ps1 +66 -36
  72. package/resources/claude-customizations/.claude/hooks/validate-task-researcher-output.ps1 +31 -34
  73. package/resources/claude-customizations/.claude/lib/bash/mutate-parallel-run.sh +191 -0
  74. package/resources/claude-customizations/.claude/lib/bash/parallel-cohorts.sh +13 -3
  75. package/resources/claude-customizations/.claude/lib/bash/parallel-lane-assertion.sh +4 -2
  76. package/resources/claude-customizations/.claude/lib/bash/parallel-mutation-cli.sh +152 -0
  77. package/resources/claude-customizations/.claude/lib/bash/parallel-mutation-ops.sh +193 -0
  78. package/resources/claude-customizations/.claude/lib/bash/parallel-mutation.sh +322 -0
  79. package/resources/claude-customizations/.claude/lib/bash/remove-parallel-item.sh +146 -0
  80. package/resources/claude-customizations/.claude/lib/blast-radius/BlastRadiusExtraction.psm1 +23 -33
  81. package/resources/claude-customizations/.claude/lib/blast-radius/BlastRadiusTokenShape.psm1 +86 -6
  82. package/resources/claude-customizations/.claude/lib/ci-gate/Invoke-CiGateParser.ps1 +91 -19
  83. package/resources/claude-customizations/.claude/lib/orchestrator-state/OrchestratorState.psm1 +6 -13
  84. package/resources/claude-customizations/.claude/lib/orchestrator-state/OrchestratorStateEpicWaveBarrier.psm1 +346 -0
  85. package/resources/claude-customizations/.claude/lib/orchestrator-state/OrchestratorStateIssueAdoption.psm1 +396 -0
  86. package/resources/claude-customizations/.claude/lib/orchestrator-state/OrchestratorStateReceipts.psm1 +22 -15
  87. package/resources/claude-customizations/.claude/lib/orchestrator-state/OrchestratorStateRemediationAccounting.psm1 +337 -0
  88. package/resources/claude-customizations/.claude/lib/orchestrator-state/OrchestratorStateRoutingContract.psm1 +9 -1
  89. package/resources/claude-customizations/.claude/lib/worktree-resolution/WorktreeItemResolution.psm1 +79 -2
  90. package/resources/claude-customizations/.claude/lib/worktree-resolution/WorktreeRunResolution.psm1 +3 -3
  91. package/resources/claude-customizations/.claude/rules/architecture-boundaries.md +5 -5
  92. package/resources/claude-customizations/.claude/rules/csharp.md +2 -2
  93. package/resources/claude-customizations/.claude/rules/general-code-change.md +1 -1
  94. package/resources/claude-customizations/.claude/rules/general-unit-test.md +3 -2
  95. package/resources/claude-customizations/.claude/rules/orchestrator-state.md +153 -4
  96. package/resources/claude-customizations/.claude/rules/parallel-orchestration.md +50 -5
  97. package/resources/claude-customizations/.claude/rules/plan-acceptance-gates.md +47 -8
  98. package/resources/claude-customizations/.claude/rules/quality-tiers.md +11 -7
  99. package/resources/claude-customizations/.claude/rules/shell.md +10 -8
  100. package/resources/claude-customizations/.claude/rules/typescript.md +1 -1
  101. package/resources/claude-customizations/.claude/settings.json +3 -4
  102. package/resources/claude-customizations/.claude/skills/acceptance-criteria-tracking/SKILL.md +9 -1
  103. package/resources/claude-customizations/.claude/skills/atomic-plan-contract/SKILL.md +7 -1
  104. package/resources/claude-customizations/.claude/skills/cleanup-merged-worktrees/SKILL.md +11 -3
  105. package/resources/claude-customizations/.claude/skills/cleanup-merged-worktrees/scripts/cleanup-worktrees.sh +11 -2
  106. package/resources/claude-customizations/.claude/skills/cleanup-merged-worktrees/scripts/cleanup_worktrees_detached_lib.sh +1 -1
  107. package/resources/claude-customizations/.claude/skills/cleanup-merged-worktrees/scripts/cleanup_worktrees_enumerate_lib.sh +171 -5
  108. package/resources/claude-customizations/.claude/skills/cleanup-merged-worktrees/scripts/cleanup_worktrees_preserve_lib.sh +1 -1
  109. package/resources/claude-customizations/.claude/skills/cleanup-merged-worktrees/scripts/cleanup_worktrees_report_records_lib.sh +6 -43
  110. package/resources/claude-customizations/.claude/skills/cleanup-merged-worktrees/scripts/cleanup_worktrees_scan_helper.sh +6 -15
  111. package/resources/claude-customizations/.claude/skills/epic-orchestrate/SKILL.md +45 -11
  112. package/resources/claude-customizations/.claude/skills/epic-plan/SKILL.md +1 -1
  113. package/resources/claude-customizations/.claude/skills/evidence-and-timestamp-conventions/SKILL.md +13 -0
  114. package/resources/claude-customizations/.claude/skills/feature-promotion-lifecycle/SKILL.md +10 -0
  115. package/resources/claude-customizations/.claude/skills/feature-review-workflow/SKILL.md +7 -4
  116. package/resources/claude-customizations/.claude/skills/orchestrate/SKILL.md +42 -16
  117. package/resources/claude-customizations/.claude/skills/parallel-add/SKILL.md +52 -14
  118. package/resources/claude-customizations/.claude/skills/parallel-close/SKILL.md +22 -9
  119. package/resources/claude-customizations/.claude/skills/parallel-orchestrate/SKILL.md +97 -19
  120. package/resources/claude-customizations/.claude/skills/parallel-plan/SKILL.md +63 -7
  121. package/resources/claude-customizations/.claude/skills/parallel-remove/SKILL.md +35 -12
  122. package/resources/claude-customizations/.claude/skills/pr-author/SKILL.md +3 -1
  123. package/resources/claude-customizations/.claude/skills/quota-throttling/SKILL.md +1 -1
  124. package/resources/claude-customizations/.claude/skills/remediation-handoff-atomic-planner/SKILL.md +7 -3
  125. package/resources/claude-customizations/pack-manifests/core.json +25 -0
  126. package/resources/codex-and-agents-customizations/.agents/skills/acceptance-criteria-tracking/SKILL.md +9 -1
  127. package/resources/codex-and-agents-customizations/.agents/skills/architecture-boundaries/SKILL.md +5 -5
  128. package/resources/codex-and-agents-customizations/.agents/skills/atomic-executor/SKILL.md +11 -0
  129. package/resources/codex-and-agents-customizations/.agents/skills/atomic-plan-contract/SKILL.md +4 -0
  130. package/resources/codex-and-agents-customizations/.agents/skills/atomic-planner/SKILL.md +10 -0
  131. package/resources/codex-and-agents-customizations/.agents/skills/csharp/SKILL.md +2 -2
  132. package/resources/codex-and-agents-customizations/.agents/skills/csharp-qa-gate/SKILL.md +2 -2
  133. package/resources/codex-and-agents-customizations/.agents/skills/epic-orchestrate/SKILL.md +13 -3
  134. package/resources/codex-and-agents-customizations/.agents/skills/epic-plan/SKILL.md +17 -1
  135. package/resources/codex-and-agents-customizations/.agents/skills/epic-run/SKILL.md +2 -1
  136. package/resources/codex-and-agents-customizations/.agents/skills/evidence-and-timestamp-conventions/SKILL.md +13 -0
  137. package/resources/codex-and-agents-customizations/.agents/skills/feature-promotion-lifecycle/SKILL.md +1 -1
  138. package/resources/codex-and-agents-customizations/.agents/skills/feature-review/SKILL.md +30 -6
  139. package/resources/codex-and-agents-customizations/.agents/skills/feature-review-workflow/SKILL.md +16 -6
  140. package/resources/codex-and-agents-customizations/.agents/skills/general-code-change/SKILL.md +1 -1
  141. package/resources/codex-and-agents-customizations/.agents/skills/general-unit-test/SKILL.md +3 -2
  142. package/resources/codex-and-agents-customizations/.agents/skills/orchestrate/SKILL.md +43 -11
  143. package/resources/codex-and-agents-customizations/.agents/skills/orchestrator-state/SKILL.md +41 -2
  144. package/resources/codex-and-agents-customizations/.agents/skills/orchestrator-workflow/SKILL.md +19 -4
  145. package/resources/codex-and-agents-customizations/.agents/skills/quality-tiers/SKILL.md +11 -7
  146. package/resources/codex-and-agents-customizations/.agents/skills/remediation-handoff-atomic-planner/SKILL.md +2 -0
  147. package/resources/codex-and-agents-customizations/.agents/skills/translate-claude-to-codex/SKILL.md +1 -1
  148. package/resources/codex-and-agents-customizations/.agents-variants/csharp-legacy/skills/csharp/SKILL.md +2 -2
  149. package/resources/codex-and-agents-customizations/.agents-variants/csharp-legacy/skills/csharp-qa-gate/SKILL.md +2 -2
  150. package/resources/codex-and-agents-customizations/.codex/agents/atomic-executor-c1.toml +11 -0
  151. package/resources/codex-and-agents-customizations/.codex/agents/atomic-executor-c2.toml +11 -0
  152. package/resources/codex-and-agents-customizations/.codex/agents/atomic-executor-c3-elevated.toml +11 -0
  153. package/resources/codex-and-agents-customizations/.codex/agents/atomic-executor-c3.toml +11 -0
  154. package/resources/codex-and-agents-customizations/.codex/agents/atomic-executor-c4.toml +11 -0
  155. package/resources/codex-and-agents-customizations/.codex/agents/atomic-executor.toml +11 -0
  156. package/resources/codex-and-agents-customizations/.codex/agents/atomic-planner-c1.toml +10 -0
  157. package/resources/codex-and-agents-customizations/.codex/agents/atomic-planner-c2.toml +10 -0
  158. package/resources/codex-and-agents-customizations/.codex/agents/atomic-planner-c3-elevated.toml +10 -0
  159. package/resources/codex-and-agents-customizations/.codex/agents/atomic-planner-c3.toml +10 -0
  160. package/resources/codex-and-agents-customizations/.codex/agents/atomic-planner-c4.toml +10 -0
  161. package/resources/codex-and-agents-customizations/.codex/agents/atomic-planner.toml +10 -0
  162. package/resources/codex-and-agents-customizations/.codex/agents/epic-orchestrator.toml +2 -1
  163. package/resources/codex-and-agents-customizations/.codex/agents/feature-review.toml +6 -6
  164. package/resources/codex-and-agents-customizations/.codex/agents/feature-reviewer-c1.toml +1 -0
  165. package/resources/codex-and-agents-customizations/.codex/agents/feature-reviewer-c2.toml +1 -0
  166. package/resources/codex-and-agents-customizations/.codex/agents/feature-reviewer-c3-elevated.toml +1 -0
  167. package/resources/codex-and-agents-customizations/.codex/agents/feature-reviewer-c3.toml +1 -0
  168. package/resources/codex-and-agents-customizations/.codex/agents/feature-reviewer-c4.toml +1 -0
  169. package/resources/codex-and-agents-customizations/.codex/agents/feature-reviewer.toml +1 -0
  170. package/resources/codex-and-agents-customizations/.codex/agents/orchestrator-c1.toml +3 -3
  171. package/resources/codex-and-agents-customizations/.codex/agents/orchestrator-c2.toml +3 -3
  172. package/resources/codex-and-agents-customizations/.codex/agents/orchestrator-c3-elevated.toml +3 -3
  173. package/resources/codex-and-agents-customizations/.codex/agents/orchestrator-c3.toml +3 -3
  174. package/resources/codex-and-agents-customizations/.codex/agents/orchestrator-c4.toml +3 -3
  175. package/resources/codex-and-agents-customizations/.codex/agents/orchestrator.toml +3 -3
  176. package/resources/codex-and-agents-customizations/.codex/codex-web-setup.sh +318 -273
  177. package/resources/codex-and-agents-customizations/.codex/config.toml +1 -1
  178. package/resources/codex-and-agents-customizations/.codex/hooks/check-powershell-test-purity.ps1 +7 -1
  179. package/resources/codex-and-agents-customizations/.codex/hooks/check-python-test-purity.ps1 +7 -1
  180. package/resources/codex-and-agents-customizations/.codex/hooks/codex-epic-child-launch-attestation.ps1 +1 -1
  181. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-checkpoint-monotonic.ps1 +7 -1
  182. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-codex-model-routing.ps1 +8 -2
  183. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-completion-consistency.ps1 +97 -44
  184. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-completion-helpers.ps1 +105 -0
  185. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-epic-child-worktree-binding.ps1 +7 -1
  186. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-epic-merge-gate.ps1 +37 -5
  187. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-epic-planning-only.ps1 +6 -0
  188. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-epic-root-invocation.ps1 +7 -1
  189. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-epic-wave-barrier.ps1 +7 -1
  190. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-epic-worktree-removal-gate.ps1 +54 -41
  191. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-evidence-locations.ps1 +7 -1
  192. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-orchestration-preimplementation-gate-epic-scope.ps1 +35 -14
  193. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-orchestration-preimplementation-gate-helpers.ps1 +31 -58
  194. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-orchestration-preimplementation-gate-modes.ps1 +63 -47
  195. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-orchestration-preimplementation-gate-targets.ps1 +433 -0
  196. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-orchestration-preimplementation-gate.ps1 +24 -11
  197. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-powershell-batch-budget.ps1 +8 -2
  198. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-promotion-mcp-only.ps1 +13 -4
  199. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-python-batch-budget.ps1 +8 -2
  200. package/resources/codex-and-agents-customizations/.codex/hooks/feature-folder-resolution.ps1 +373 -0
  201. package/resources/codex-and-agents-customizations/.codex/hooks/feature-review-coverage-thresholds.ps1 +85 -0
  202. package/resources/codex-and-agents-customizations/.codex/hooks/hook-command-heredoc.ps1 +119 -0
  203. package/resources/codex-and-agents-customizations/.codex/hooks/hook-command-invocation-operands.ps1 +198 -0
  204. package/resources/codex-and-agents-customizations/.codex/hooks/hook-command-invocation.ps1 +254 -255
  205. package/resources/codex-and-agents-customizations/.codex/hooks/hook-command-payload-powershell.ps1 +201 -0
  206. package/resources/codex-and-agents-customizations/.codex/hooks/hook-command-payload.ps1 +484 -0
  207. package/resources/codex-and-agents-customizations/.codex/hooks/hook-command-scanner.ps1 +27 -110
  208. package/resources/codex-and-agents-customizations/.codex/hooks/hook-dependency-guard.ps1 +114 -0
  209. package/resources/codex-and-agents-customizations/.codex/hooks/hook-docs-only-diff.ps1 +493 -0
  210. package/resources/codex-and-agents-customizations/.codex/hooks/validate-bash.ps1 +8 -2
  211. package/resources/codex-and-agents-customizations/.codex/hooks/validate-codex-subagent-routing.ps1 +7 -1
  212. package/resources/codex-and-agents-customizations/.codex/hooks/validate-feature-review-coverage.ps1 +24 -8
  213. package/resources/codex-and-agents-customizations/pack-manifests/core.json +9 -0
  214. package/resources/customizations/.github/agents/csharp-typed-engineer.agent.md +2 -2
  215. package/resources/customizations/.github/instructions/csharp-code-change.instructions.md +4 -4
  216. package/resources/customizations/.github/instructions/csharp-unit-test.instructions.md +2 -2
  217. package/resources/customizations/.github/skills/acceptance-criteria-tracking/SKILL.md +9 -1
  218. package/resources/customizations/.github/skills/atomic-plan-contract/SKILL.md +4 -0
  219. package/resources/customizations/.github/skills/evidence-and-timestamp-conventions/SKILL.md +13 -0
  220. package/resources/customizations/.github/skills/feature-review-workflow/SKILL.md +1 -1
  221. package/resources/powershell/PoshQC/PoshQC.Coverage.psm1 +314 -0
  222. package/resources/powershell/PoshQC/PoshQC.Testing.psm1 +25 -28
  223. package/resources/powershell/PoshQC/PoshQC.psm1 +1 -0
  224. package/resources/powershell/PoshQC/README.md +8 -2
  225. package/resources/powershell/PoshQC/settings/pester.runsettings.psd1 +2 -315
@@ -0,0 +1,346 @@
1
+ <#
2
+ .SYNOPSIS
3
+ PowerShell port of the epic wave-barrier Layer 2 ordering check (issue #840).
4
+
5
+ .DESCRIPTION
6
+ Ports validate_wave_barrier_ordering (scripts/dev_tools/_epic_orchestrator_state_wave_barrier.py)
7
+ as reached through validate_epic_orchestrator_state_text: feature extraction, the union
8
+ index with lifecycle-prefix normalization, the start guard, and the status and timing
9
+ checks with status-before-timing precedence. For in-parity inputs the violation strings
10
+ are byte-identical to the Python authority.
11
+
12
+ The checkpoint is parsed with System.Text.Json (JsonDocument), not ConvertFrom-Json:
13
+ ConvertFrom-Json coerces ISO-8601 strings to DateTime and reads property names
14
+ case-insensitively, and either behavior would break parity. Properties are read through
15
+ an ordinal, last-definition-wins enumeration, which matches Python json semantics for a
16
+ duplicate key.
17
+
18
+ An input this port does not evaluate fails closed with an error whose message starts
19
+ with EPIC_WAVE_BARRIER_UNEVALUABLE:. The declared divergence classes are listed in
20
+ tests/scripts/claude-lib/orchestrator-state/OrchestratorStateEpicWaveBarrier.Parity.Tests.ps1.
21
+
22
+ .NOTES
23
+ PowerShell 7+. Reads no file and starts no process: the caller supplies checkpoint text
24
+ it has already read. Mirrored byte-identically into the bundled extension payload.
25
+ CONVENTION: this module fails fast at module scope and imports its siblings with -ErrorAction Stop.
26
+ #>
27
+
28
+ Set-StrictMode -Version Latest
29
+ $ErrorActionPreference = 'Stop'
30
+
31
+ # Lifecycle prefixes a folder hint may carry, tested in this order; the first match is stripped.
32
+ $script:LifecyclePrefixes = @('docs/features/active/', 'docs/features/completed/', 'active/', 'completed/')
33
+
34
+ # The merge statuses that durably confirm a dependency edge, and the literal not-started status.
35
+ $script:MergedStatuses = @('merged', 'worktree_removed')
36
+ $script:NotStartedStatus = 'not_started'
37
+
38
+ # A JSON number token that Python reads as an int; any other number token is not compared.
39
+ $script:IntegerTokenPattern = '^-?(0|[1-9][0-9]*)$'
40
+
41
+ # The fail-closed token and the two violation formats of the Python authority.
42
+ $script:UnevaluableToken = 'EPIC_WAVE_BARRIER_UNEVALUABLE:'
43
+ $script:StatusViolationFormat = 'EPIC_WAVE_BARRIER_VIOLATION: {0} is treated as started while dependency {1} is not merged'
44
+ $script:TimingViolationFormat = 'EPIC_WAVE_BARRIER_VIOLATION: {0} worktree_created_at precedes dependency {1} merge_confirmed_at'
45
+
46
+ # Private: the last property of an object element whose name equals Name (ordinal), so a
47
+ # duplicate key resolves the way Python json does. Found is $false when there is none.
48
+ function Get-EpicWaveBarrierProperty {
49
+ [CmdletBinding()]
50
+ [OutputType([pscustomobject])]
51
+ param(
52
+ [Parameter(Mandatory = $true)] [System.Text.Json.JsonElement] $Element,
53
+ [Parameter(Mandatory = $true)] [string] $Name
54
+ )
55
+
56
+ $found = $false
57
+ $value = $null
58
+ foreach ($property in $Element.EnumerateObject()) {
59
+ if ([string]::Equals($property.Name, $Name, [System.StringComparison]::Ordinal)) {
60
+ $found = $true
61
+ $value = $property.Value
62
+ }
63
+ }
64
+ return [pscustomobject]@{ Found = $found; Value = $value }
65
+ }
66
+
67
+ # Private: the string value of a named property, or $null when it is absent or not a string.
68
+ function Get-EpicWaveBarrierString {
69
+ [CmdletBinding()]
70
+ [OutputType([string])]
71
+ param(
72
+ [Parameter(Mandatory = $true)] [System.Text.Json.JsonElement] $Element,
73
+ [Parameter(Mandatory = $true)] [string] $Name
74
+ )
75
+
76
+ $property = Get-EpicWaveBarrierProperty -Element $Element -Name $Name
77
+ if ($property.Found -and $property.Value.ValueKind -eq [System.Text.Json.JsonValueKind]::String) {
78
+ return $property.Value.GetString()
79
+ }
80
+ return $null
81
+ }
82
+
83
+ # Private: strip the first matching lifecycle prefix (ordinal), as _normalize_folder_hint does.
84
+ function ConvertTo-EpicWaveBarrierFolderHint {
85
+ [CmdletBinding()]
86
+ [OutputType([string])]
87
+ param(
88
+ [Parameter(Mandatory = $true)] [AllowEmptyString()] [string] $Value
89
+ )
90
+
91
+ foreach ($prefix in $script:LifecyclePrefixes) {
92
+ if ($Value.StartsWith($prefix, [System.StringComparison]::Ordinal)) {
93
+ return $Value.Substring($prefix.Length)
94
+ }
95
+ }
96
+ return $Value
97
+ }
98
+
99
+ # Private: the canonical decimal text of an integer token; BigInteger keeps values beyond
100
+ # 64 bits exact and renders -0 as 0, as Python str(int) does.
101
+ function ConvertTo-EpicWaveBarrierIntegerText {
102
+ [CmdletBinding()]
103
+ [OutputType([string])]
104
+ param(
105
+ [Parameter(Mandatory = $true)] [string] $RawToken
106
+ )
107
+
108
+ $invariant = [System.Globalization.CultureInfo]::InvariantCulture
109
+ return [System.Numerics.BigInteger]::Parse($RawToken, $invariant).ToString($invariant)
110
+ }
111
+
112
+ # Private: the union-index key of a JSON number. Python indexes an int by value; a
113
+ # non-integer token is outside parity, so it fails closed rather than being compared.
114
+ function Get-EpicWaveBarrierNumberKey {
115
+ [CmdletBinding()]
116
+ [OutputType([string])]
117
+ param(
118
+ [Parameter(Mandatory = $true)] [System.Text.Json.JsonElement] $Element,
119
+ [Parameter(Mandatory = $true)] [string] $Role,
120
+ [Parameter(Mandatory = $true)] [AllowEmptyString()] [string] $Folder
121
+ )
122
+
123
+ $raw = $Element.GetRawText()
124
+ if ($raw -cnotmatch $script:IntegerTokenPattern) {
125
+ throw ("{0} feature '{1}' has a non-integer numeric {2} token '{3}', which this port does not compare" -f
126
+ $script:UnevaluableToken, $Folder, $Role, $raw)
127
+ }
128
+ return 'n:' + (ConvertTo-EpicWaveBarrierIntegerText -RawToken $raw)
129
+ }
130
+
131
+ # Private: render a resolved dependency reference as Python str() renders the raw value.
132
+ # Only strings, booleans, and integer numbers resolve, so no other kind reaches this point.
133
+ function Format-EpicWaveBarrierReference {
134
+ [CmdletBinding()]
135
+ [OutputType([string])]
136
+ param(
137
+ [Parameter(Mandatory = $true)] [System.Text.Json.JsonElement] $Element
138
+ )
139
+
140
+ $kind = $Element.ValueKind
141
+ if ($kind -eq [System.Text.Json.JsonValueKind]::String) { return $Element.GetString() }
142
+ if ($kind -eq [System.Text.Json.JsonValueKind]::True) { return 'True' }
143
+ if ($kind -eq [System.Text.Json.JsonValueKind]::False) { return 'False' }
144
+ return (ConvertTo-EpicWaveBarrierIntegerText -RawToken $Element.GetRawText())
145
+ }
146
+
147
+ # Private: the start guard of feature_has_started. A string worktree_created_at (empty
148
+ # included) starts a feature; otherwise only the exact string not_started leaves it unstarted.
149
+ function Test-EpicWaveBarrierFeatureStarted {
150
+ [CmdletBinding()]
151
+ [OutputType([bool])]
152
+ param(
153
+ [Parameter(Mandatory = $true)] [System.Text.Json.JsonElement] $Feature
154
+ )
155
+
156
+ if ($null -ne (Get-EpicWaveBarrierString -Element $Feature -Name 'worktree_created_at')) { return $true }
157
+ $status = Get-EpicWaveBarrierProperty -Element $Feature -Name 'merge_status'
158
+ if (-not $status.Found) { return $true }
159
+ $isNotStarted = ($status.Value.ValueKind -eq [System.Text.Json.JsonValueKind]::String) -and
160
+ [string]::Equals($status.Value.GetString(), $script:NotStartedStatus, [System.StringComparison]::Ordinal)
161
+ return (-not $isNotStarted)
162
+ }
163
+
164
+ # Private: whether a dependency's merge_status is a string equal (ordinal) to a merged status.
165
+ # An absent or non-string status arrives as $null, which the [string] binding turns into an
166
+ # empty string, and an empty string is not a merged status.
167
+ function Test-EpicWaveBarrierMerged {
168
+ [CmdletBinding()]
169
+ [OutputType([bool])]
170
+ param(
171
+ [Parameter(Mandatory = $true)] [AllowNull()] [AllowEmptyString()] [string] $Status
172
+ )
173
+
174
+ foreach ($merged in $script:MergedStatuses) {
175
+ if ([string]::Equals($Status, $merged, [System.StringComparison]::Ordinal)) { return $true }
176
+ }
177
+ return $false
178
+ }
179
+
180
+ # Private: the union-index key of a feature's issue_num, or $null when it is absent, null,
181
+ # or a string (a string issue_num is never matched by a non-string reference).
182
+ function Get-EpicWaveBarrierIssueKey {
183
+ [CmdletBinding()]
184
+ [OutputType([string])]
185
+ param(
186
+ [Parameter(Mandatory = $true)] [System.Text.Json.JsonElement] $Feature,
187
+ [Parameter(Mandatory = $true)] [AllowEmptyString()] [string] $Folder
188
+ )
189
+
190
+ $issue = Get-EpicWaveBarrierProperty -Element $Feature -Name 'issue_num'
191
+ if (-not $issue.Found) { return $null }
192
+ $kind = $issue.Value.ValueKind
193
+ # Routing table: an array or object cannot be hashed by the authority (fail closed);
194
+ # booleans key as 1 and 0 because Python treats True == 1; numbers key by value.
195
+ if ($kind -eq [System.Text.Json.JsonValueKind]::Array -or $kind -eq [System.Text.Json.JsonValueKind]::Object) {
196
+ throw ("{0} feature '{1}' has an issue_num that is an array or object, which the Python authority cannot index" -f
197
+ $script:UnevaluableToken, $Folder)
198
+ }
199
+ if ($kind -eq [System.Text.Json.JsonValueKind]::True) { return 'n:1' }
200
+ if ($kind -eq [System.Text.Json.JsonValueKind]::False) { return 'n:0' }
201
+ if ($kind -eq [System.Text.Json.JsonValueKind]::Number) {
202
+ return (Get-EpicWaveBarrierNumberKey -Element $issue.Value -Role 'issue_num' -Folder $Folder)
203
+ }
204
+ return $null
205
+ }
206
+
207
+ # Private: the object entries of a list-valued features property, in order; empty when the
208
+ # root is not an object or features is absent or not a list.
209
+ function Get-EpicWaveBarrierFeatureEntry {
210
+ [CmdletBinding()]
211
+ [OutputType([System.Text.Json.JsonElement[]], [object[]])]
212
+ param(
213
+ [Parameter(Mandatory = $true)] [System.Text.Json.JsonElement] $Root
214
+ )
215
+
216
+ $entries = [System.Collections.Generic.List[System.Text.Json.JsonElement]]::new()
217
+ if ($Root.ValueKind -ne [System.Text.Json.JsonValueKind]::Object) { return , $entries.ToArray() }
218
+ $features = Get-EpicWaveBarrierProperty -Element $Root -Name 'features'
219
+ if (-not $features.Found -or $features.Value.ValueKind -ne [System.Text.Json.JsonValueKind]::Array) {
220
+ return , $entries.ToArray()
221
+ }
222
+ # Keep only object-shaped entries, as _extract_features does.
223
+ foreach ($item in $features.Value.EnumerateArray()) {
224
+ if ($item.ValueKind -eq [System.Text.Json.JsonValueKind]::Object) { $entries.Add($item) }
225
+ }
226
+ return , $entries.ToArray()
227
+ }
228
+
229
+ # Private: resolve one depends_on element to a feature folder through the union index, or
230
+ # $null. A string consults the folder hints only; a boolean or number consults issue_num only.
231
+ function Resolve-EpicWaveBarrierReference {
232
+ [CmdletBinding()]
233
+ [OutputType([string])]
234
+ param(
235
+ [Parameter(Mandatory = $true)] [System.Text.Json.JsonElement] $Dependency,
236
+ [Parameter(Mandatory = $true)] [System.Collections.Generic.Dictionary[string, string]] $ByHint,
237
+ [Parameter(Mandatory = $true)] [System.Collections.Generic.Dictionary[string, string]] $ByIssue,
238
+ [Parameter(Mandatory = $true)] [AllowEmptyString()] [string] $Folder
239
+ )
240
+
241
+ $kind = $Dependency.ValueKind
242
+ $key = $null
243
+ $map = $ByIssue
244
+ if ($kind -eq [System.Text.Json.JsonValueKind]::String) {
245
+ $key = ConvertTo-EpicWaveBarrierFolderHint -Value $Dependency.GetString()
246
+ $map = $ByHint
247
+ }
248
+ elseif ($kind -eq [System.Text.Json.JsonValueKind]::True) { $key = 'n:1' }
249
+ elseif ($kind -eq [System.Text.Json.JsonValueKind]::False) { $key = 'n:0' }
250
+ elseif ($kind -eq [System.Text.Json.JsonValueKind]::Number) {
251
+ $key = Get-EpicWaveBarrierNumberKey -Element $Dependency -Role 'depends_on reference' -Folder $Folder
252
+ }
253
+ if ($null -eq $key -or -not $map.ContainsKey($key)) { return $null }
254
+ return $map[$key]
255
+ }
256
+
257
+ # Private: the violation lines for the object entries, in feature and depends_on order.
258
+ function Get-EpicWaveBarrierViolation {
259
+ [CmdletBinding()]
260
+ [OutputType([string])]
261
+ param(
262
+ [Parameter(Mandatory = $true)] [AllowEmptyCollection()] [System.Text.Json.JsonElement[]] $Entry
263
+ )
264
+
265
+ $ordinal = [System.StringComparer]::Ordinal
266
+ $byFolder = [System.Collections.Generic.Dictionary[string, System.Text.Json.JsonElement]]::new($ordinal)
267
+ $byHint = [System.Collections.Generic.Dictionary[string, string]]::new($ordinal)
268
+ $byIssue = [System.Collections.Generic.Dictionary[string, string]]::new($ordinal)
269
+
270
+ # Build the lookups: every string folder by name, and every non-empty string folder by
271
+ # its normalized hint and its issue_num. A later duplicate replaces an earlier one.
272
+ foreach ($feature in $Entry) {
273
+ $folder = Get-EpicWaveBarrierString -Element $feature -Name 'feature_folder'
274
+ if ($null -eq $folder) { continue }
275
+ $byFolder[$folder] = $feature
276
+ if ($folder.Length -eq 0) { continue }
277
+ $byHint[(ConvertTo-EpicWaveBarrierFolderHint -Value $folder)] = $folder
278
+ $issueKey = Get-EpicWaveBarrierIssueKey -Feature $feature -Folder $folder
279
+ if ($null -ne $issueKey) { $byIssue[$issueKey] = $folder }
280
+ }
281
+
282
+ # Check every started feature with a list depends_on; each edge yields at most one line,
283
+ # and the status violation takes precedence over the timing violation.
284
+ foreach ($feature in $Entry) {
285
+ $folder = Get-EpicWaveBarrierString -Element $feature -Name 'feature_folder'
286
+ $dependsOn = Get-EpicWaveBarrierProperty -Element $feature -Name 'depends_on'
287
+ if ($null -eq $folder -or -not $dependsOn.Found -or $dependsOn.Value.ValueKind -ne [System.Text.Json.JsonValueKind]::Array) { continue }
288
+ if (-not (Test-EpicWaveBarrierFeatureStarted -Feature $feature)) { continue }
289
+ $created = Get-EpicWaveBarrierString -Element $feature -Name 'worktree_created_at'
290
+ foreach ($dependency in $dependsOn.Value.EnumerateArray()) {
291
+ $resolved = Resolve-EpicWaveBarrierReference -Dependency $dependency -ByHint $byHint -ByIssue $byIssue -Folder $folder
292
+ if ($null -eq $resolved -or -not $byFolder.ContainsKey($resolved)) { continue }
293
+ $target = $byFolder[$resolved]
294
+ $reference = Format-EpicWaveBarrierReference -Element $dependency
295
+ if (-not (Test-EpicWaveBarrierMerged -Status (Get-EpicWaveBarrierString -Element $target -Name 'merge_status'))) {
296
+ $script:StatusViolationFormat -f $folder, $reference
297
+ continue
298
+ }
299
+ $confirmed = Get-EpicWaveBarrierString -Element $target -Name 'merge_confirmed_at'
300
+ if ($null -ne $confirmed -and $null -ne $created -and [string]::CompareOrdinal($confirmed, $created) -gt 0) {
301
+ $script:TimingViolationFormat -f $folder, $reference
302
+ }
303
+ }
304
+ }
305
+ }
306
+
307
+ function Get-OrchestratorStateEpicWaveBarrierError {
308
+ <#
309
+ .SYNOPSIS
310
+ Return the EPIC_WAVE_BARRIER_VIOLATION lines for an epic checkpoint's text.
311
+ .DESCRIPTION
312
+ Parses the text with System.Text.Json default options and applies the Layer 2
313
+ ordering check. Returns an empty array when there is no violation, when the root is
314
+ not an object, or when features is absent or not a list. Throws an error whose
315
+ message starts with EPIC_WAVE_BARRIER_UNEVALUABLE: for text System.Text.Json does
316
+ not parse (including NaN or Infinity literals and nesting deeper than 64 levels), an
317
+ array or object issue_num, and a non-integer number token that the check consults.
318
+ .PARAMETER CheckpointText
319
+ The raw epic checkpoint JSON text.
320
+ .OUTPUTS
321
+ System.String[]
322
+ #>
323
+ [CmdletBinding()]
324
+ [OutputType([string[]], [object[]])]
325
+ param(
326
+ [Parameter(Mandatory = $true)] [AllowEmptyString()] [string] $CheckpointText
327
+ )
328
+
329
+ $document = $null
330
+ try {
331
+ $document = [System.Text.Json.JsonDocument]::Parse($CheckpointText, [System.Text.Json.JsonDocumentOptions]::new())
332
+ }
333
+ catch {
334
+ throw ('{0} the checkpoint is not parseable by System.Text.Json with default options (a non-standard literal such as NaN or Infinity, or nesting deeper than 64 levels): {1}' -f
335
+ $script:UnevaluableToken, $_.Exception.Message)
336
+ }
337
+ try {
338
+ $entries = Get-EpicWaveBarrierFeatureEntry -Root $document.RootElement
339
+ return , [string[]] @(Get-EpicWaveBarrierViolation -Entry $entries)
340
+ }
341
+ finally {
342
+ $document.Dispose()
343
+ }
344
+ }
345
+
346
+ Export-ModuleMember -Function Get-OrchestratorStateEpicWaveBarrierError