@danmoisan/drm-copilot-mcp 1.1.6 → 1.1.8

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 (56) hide show
  1. package/out/mcp-server.js +73 -1
  2. package/package.json +1 -1
  3. package/resources/claude-customizations/.claude/agents/atomic-planner.md +2 -0
  4. package/resources/claude-customizations/.claude/agents/parallel-orchestrator.md +6 -5
  5. package/resources/claude-customizations/.claude/agents/parallel-planner.md +24 -7
  6. package/resources/claude-customizations/.claude/agents/prd-feature.md +5 -0
  7. package/resources/claude-customizations/.claude/agents/task-researcher.md +3 -0
  8. package/resources/claude-customizations/.claude/hooks/enforce-orchestration-preimplementation-gate-modes.ps1 +8 -5
  9. package/resources/claude-customizations/.claude/hooks/enforce-powershell-batch-budget.ps1 +186 -13
  10. package/resources/claude-customizations/.claude/hooks/enforce-python-batch-budget.ps1 +186 -13
  11. package/resources/claude-customizations/.claude/hooks/persist-session-id.ps1 +16 -5
  12. package/resources/claude-customizations/.claude/hooks/validate-planner-output.ps1 +122 -0
  13. package/resources/claude-customizations/.claude/hooks/validate-prd-feature-output.ps1 +91 -0
  14. package/resources/claude-customizations/.claude/hooks/validate-task-researcher-output.ps1 +69 -1
  15. package/resources/claude-customizations/.claude/lib/bash/parallel-lane-assertion.sh +495 -0
  16. package/resources/claude-customizations/.claude/lib/bash/report-lane-assertion.sh +169 -0
  17. package/resources/claude-customizations/.claude/lib/blast-radius/BlastRadius.psm1 +7 -5
  18. package/resources/claude-customizations/.claude/lib/blast-radius/BlastRadiusConfig.psm1 +4 -2
  19. package/resources/claude-customizations/.claude/lib/blast-radius/BlastRadiusExtraction.psm1 +4 -2
  20. package/resources/claude-customizations/.claude/lib/blast-radius/BlastRadiusGlob.psm1 +2 -0
  21. package/resources/claude-customizations/.claude/lib/blast-radius/BlastRadiusNormalization.psm1 +5 -3
  22. package/resources/claude-customizations/.claude/lib/blast-radius/BlastRadiusTokenShape.psm1 +2 -0
  23. package/resources/claude-customizations/.claude/lib/blast-radius/BlastRadiusValidation.psm1 +6 -4
  24. package/resources/claude-customizations/.claude/lib/codex-routing/CodexDeployment.psm1 +2 -0
  25. package/resources/claude-customizations/.claude/lib/codex-routing/CodexTopology.psm1 +2 -0
  26. package/resources/claude-customizations/.claude/lib/discovery-validation/DiscoveryValidation.psm1 +16 -16
  27. package/resources/claude-customizations/.claude/lib/hook-payload/HookPayload.psm1 +2 -0
  28. package/resources/claude-customizations/.claude/lib/mermaid/MermaidGrammar.psm1 +2 -0
  29. package/resources/claude-customizations/.claude/lib/mermaid/MermaidLineScanner.psm1 +3 -1
  30. package/resources/claude-customizations/.claude/lib/mermaid/MermaidMarkdownFences.psm1 +2 -0
  31. package/resources/claude-customizations/.claude/lib/mermaid/MermaidValidation.psm1 +5 -3
  32. package/resources/claude-customizations/.claude/lib/model-routing/ModelRouting.psm1 +2 -0
  33. package/resources/claude-customizations/.claude/lib/orchestrator-state/OrchestratorState.psm1 +11 -0
  34. package/resources/claude-customizations/.claude/lib/orchestrator-state/OrchestratorStateCheckpointValue.psm1 +2 -0
  35. package/resources/claude-customizations/.claude/lib/orchestrator-state/OrchestratorStateCodexModelReceipts.psm1 +4 -2
  36. package/resources/claude-customizations/.claude/lib/orchestrator-state/OrchestratorStateCodexTopologyReceipts.psm1 +4 -2
  37. package/resources/claude-customizations/.claude/lib/orchestrator-state/OrchestratorStateCompletion.psm1 +9 -7
  38. package/resources/claude-customizations/.claude/lib/orchestrator-state/OrchestratorStateCompletionChecks.psm1 +4 -2
  39. package/resources/claude-customizations/.claude/lib/orchestrator-state/OrchestratorStateModelReceipts.psm1 +4 -2
  40. package/resources/claude-customizations/.claude/lib/orchestrator-state/OrchestratorStateReceipts.psm1 +3 -1
  41. package/resources/claude-customizations/.claude/lib/orchestrator-state/OrchestratorStateRoutingContract.psm1 +4 -2
  42. package/resources/claude-customizations/.claude/lib/orchestrator-state/OrchestratorStateRoutingMatrix.psm1 +3 -1
  43. package/resources/claude-customizations/.claude/lib/orchestrator-state/OrchestratorStateUnconditional.psm1 +7 -5
  44. package/resources/claude-customizations/.claude/lib/requirements/GeneratedDocumentCounters.psm1 +44 -0
  45. package/resources/claude-customizations/.claude/settings.json +9 -0
  46. package/resources/claude-customizations/.claude/skills/acceptance-criteria-tracking/SKILL.md +2 -0
  47. package/resources/claude-customizations/.claude/skills/atomic-plan-contract/SKILL.md +4 -0
  48. package/resources/claude-customizations/.claude/skills/epic-orchestrate/SKILL.md +4 -4
  49. package/resources/claude-customizations/.claude/skills/fill-feature-docs/SKILL.md +3 -0
  50. package/resources/claude-customizations/.claude/skills/parallel-add/SKILL.md +14 -9
  51. package/resources/claude-customizations/.claude/skills/parallel-orchestrate/SKILL.md +3 -3
  52. package/resources/claude-customizations/.claude/skills/parallel-plan/SKILL.md +10 -3
  53. package/resources/claude-customizations/.claude/skills/remediation-handoff-atomic-planner/SKILL.md +2 -0
  54. package/resources/claude-customizations/.claude/skills/research-issue/SKILL.md +3 -0
  55. package/resources/claude-customizations/pack-manifests/core.json +4 -0
  56. package/resources/codex-and-agents-customizations/.codex/config.toml +1 -1
@@ -28,12 +28,14 @@
28
28
  rely on the PSCustomObject conversion this module performs; no other
29
29
  shape is accepted.
30
30
  - Every returned collection is deduplicated and ordinally sorted.
31
+ CONVENTION: this module fails fast at module scope and imports its siblings with -ErrorAction Stop.
31
32
  #>
32
33
 
33
34
  Set-StrictMode -Version Latest
35
+ $ErrorActionPreference = 'Stop'
34
36
 
35
- Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'BlastRadiusExtraction.psm1') -Force
36
- Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'BlastRadiusGlob.psm1') -Force
37
+ Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'BlastRadiusExtraction.psm1') -Force -ErrorAction Stop
38
+ Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'BlastRadiusGlob.psm1') -Force -ErrorAction Stop
37
39
 
38
40
  # Keys read from the parsed config/blast-radius.json truth table.
39
41
  $script:ConfigSharedSurfaceKey = 'shared_surfaces'
@@ -33,16 +33,18 @@
33
33
  - Every returned collection is deduplicated and ordinally sorted via
34
34
  [StringComparer]::Ordinal, so identical inputs produce identical output
35
35
  in both languages regardless of the current culture.
36
+ CONVENTION: this module fails fast at module scope and imports its siblings with -ErrorAction Stop.
36
37
  #>
37
38
 
38
39
  Set-StrictMode -Version Latest
40
+ $ErrorActionPreference = 'Stop'
39
41
 
40
42
  # Get-OrdinalSortedEntry moved to BlastRadiusGlob.psm1, where its sibling ordinal
41
43
  # primitive Get-OrdinalSmallestEntry already lives, so this module stays within
42
44
  # the 500-line limit (issue #452). The import keeps every pre-existing call site
43
45
  # and test source-compatible, and introduces no cycle because the Glob module
44
46
  # imports no sibling.
45
- Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'BlastRadiusGlob.psm1') -Force
47
+ Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'BlastRadiusGlob.psm1') -Force -ErrorAction Stop
46
48
 
47
49
  # Test-MultipleFeatureFolderSpan moved to BlastRadiusTokenShape.psm1, joining the
48
50
  # new Test-PlaceholderMarker predicate that could not be added here: this module
@@ -52,7 +54,7 @@ Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'BlastRadiusGlob.psm1')
52
54
  # introduces no cycle, because the TokenShape module imports no sibling. This
53
55
  # follows the same re-import-and-re-export pattern used above for the relocated
54
56
  # ordinal-sort helper.
55
- Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'BlastRadiusTokenShape.psm1') -Force
57
+ Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'BlastRadiusTokenShape.psm1') -Force -ErrorAction Stop
56
58
 
57
59
  # Plan-structure patterns. The regex text mirrors the Python constants so radius
58
60
  # derivation and the plan validator can never disagree about which lines are
@@ -31,9 +31,11 @@
31
31
  newline in .NET.
32
32
  - Comparisons and ordering use [StringComparer]::Ordinal and
33
33
  [string]::CompareOrdinal so results do not vary with the current culture.
34
+ CONVENTION: this module fails fast at module scope and imports its siblings with -ErrorAction Stop.
34
35
  #>
35
36
 
36
37
  Set-StrictMode -Version Latest
38
+ $ErrorActionPreference = 'Stop'
37
39
 
38
40
  # Wildcards that make a path entry a pattern rather than a file. The question
39
41
  # mark is included because the subsumption helper treats it as a pattern;
@@ -27,13 +27,15 @@
27
27
  - An empty mandate-read collection excludes nothing, so a truth table with
28
28
  no mandate_reads key reproduces pre-change behaviour exactly.
29
29
  - Every returned collection is deduplicated and ordinally sorted.
30
+ CONVENTION: this module fails fast at module scope and imports its siblings with -ErrorAction Stop.
30
31
  #>
31
32
 
32
33
  Set-StrictMode -Version Latest
34
+ $ErrorActionPreference = 'Stop'
33
35
 
34
- Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'BlastRadiusExtraction.psm1') -Force
35
- Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'BlastRadiusGlob.psm1') -Force
36
- Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'BlastRadiusConfig.psm1') -Force
36
+ Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'BlastRadiusExtraction.psm1') -Force -ErrorAction Stop
37
+ Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'BlastRadiusGlob.psm1') -Force -ErrorAction Stop
38
+ Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'BlastRadiusConfig.psm1') -Force -ErrorAction Stop
37
39
 
38
40
  # Markdown ATX heading pattern used to locate spec interface sections. Relocated
39
41
  # with Get-ContractIdentifier: $script: scope is per module, so the variable must
@@ -49,9 +49,11 @@
49
49
  throws for any input, because the classifier that calls them runs over
50
50
  every inline-code span in a document and a throw would abort an entire
51
51
  derivation over one stray span.
52
+ CONVENTION: this module fails fast at module scope and imports its siblings with -ErrorAction Stop.
52
53
  #>
53
54
 
54
55
  Set-StrictMode -Version Latest
56
+ $ErrorActionPreference = 'Stop'
55
57
 
56
58
  # Placeholder and interpolation markers. A token carrying any of these was
57
59
  # written to document a shape, not to name a file, so it can never be a write
@@ -30,14 +30,16 @@
30
30
  explicitly because the Python reference rejects it.
31
31
  - Finding message text is a contract literal shared with the Python
32
32
  reference and the cross-language fixture corpus; do not reword it.
33
+ CONVENTION: this module fails fast at module scope and imports its siblings with -ErrorAction Stop.
33
34
  #>
34
35
 
35
36
  Set-StrictMode -Version Latest
37
+ $ErrorActionPreference = 'Stop'
36
38
 
37
- Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'BlastRadiusExtraction.psm1') -Force
38
- Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'BlastRadiusGlob.psm1') -Force
39
- Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'BlastRadiusConfig.psm1') -Force
40
- Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'BlastRadiusNormalization.psm1') -Force
39
+ Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'BlastRadiusExtraction.psm1') -Force -ErrorAction Stop
40
+ Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'BlastRadiusGlob.psm1') -Force -ErrorAction Stop
41
+ Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'BlastRadiusConfig.psm1') -Force -ErrorAction Stop
42
+ Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'BlastRadiusNormalization.psm1') -Force -ErrorAction Stop
41
43
 
42
44
  # Finding vocabulary. These strings are contract literals consumed by the
43
45
  # downstream parallel schema and planner features.
@@ -36,9 +36,11 @@
36
36
 
37
37
  The function is pure: it reads no file, starts no process, and never mutates
38
38
  its input.
39
+ CONVENTION: this module fails fast at module scope and imports its siblings with -ErrorAction Stop.
39
40
  #>
40
41
 
41
42
  Set-StrictMode -Version Latest
43
+ $ErrorActionPreference = 'Stop'
42
44
 
43
45
  # The complexity-band vocabulary, ordered lowest to highest. Pinned to BAND_ORDER
44
46
  # in scripts/dev_tools/compute_complexity_floor.py.
@@ -47,9 +47,11 @@
47
47
 
48
48
  The function is pure: it reads no file, starts no process, and never mutates
49
49
  its input.
50
+ CONVENTION: this module fails fast at module scope and imports its siblings with -ErrorAction Stop.
50
51
  #>
51
52
 
52
53
  Set-StrictMode -Version Latest
54
+ $ErrorActionPreference = 'Stop'
53
55
 
54
56
  # The three permitted execution contexts, the sorted tuple rendering the Python
55
57
  # message interpolates, and the two contexts that mark epic child work.
@@ -29,29 +29,29 @@
29
29
  OR on non-empty output, so the previous Python CLI's success line
30
30
  ("<type> validation passed: <path>") turned a PASSING validation into a DENY.
31
31
 
32
- PARITY with `validate_discovery_profile.py` / `validate_discovery_schema_artifacts.py`.
33
- Error families are preserved: `invalid JSON (...)`,
34
- `JSON root must be an object for validation`, `schema resolution failed (...)`,
35
- `Profile document is empty.`, `Profile document root must be a mapping.`,
36
- `Missing required field: <field>.` Schema location resolves solely from each
37
- artifact's own `$schema`, as in the reference; the type-to-file table below is
38
- documentation and artifact-type validation only. Deliberate divergences: an
39
- `http(s)://` `$schema` is NOT fetched (no guaranteed destination network, so a
40
- non-`file` scheme is reported fail-closed in the `schema resolution failed (...)`
41
- family), and `file://` resolves through `[uri]::LocalPath` rather than the
42
- reference's `Path(parsed.path)`, which mishandles a Windows `file:///C:/...` path.
43
- Unavoidable divergence: per-violation wording comes from `Test-Json`, not
44
- `jsonschema`, so violation strings differ while family and verdict match. The
45
- profile check reproduces the placeholder contract without a YAML parser (PowerShell
46
- ships none); see `Get-DiscoveryProfileValidationError` for what is and is not
47
- detected.
32
+ PARITY with `validate_discovery_profile.py` / `validate_discovery_schema_artifacts.py`. Error
33
+ families are preserved: `invalid JSON (...)`, `JSON root must be an object for validation`,
34
+ `schema resolution failed (...)`, `Profile document is empty.`,
35
+ `Profile document root must be a mapping.`, `Missing required field: <field>.` Schema
36
+ location resolves solely from each artifact's own `$schema`, as in the reference; the
37
+ type-to-file table below is documentation and artifact-type validation only. Deliberate
38
+ divergences: an `http(s)://` `$schema` is NOT fetched (no guaranteed destination network,
39
+ so a non-`file` scheme is reported fail-closed in the `schema resolution failed (...)`
40
+ family), and `file://` resolves through `[uri]::LocalPath` rather than the reference's
41
+ `Path(parsed.path)`, which mishandles a Windows `file:///C:/...` path. Unavoidable
42
+ divergence: per-violation wording comes from `Test-Json`, not `jsonschema`, so violation
43
+ strings differ while family and verdict match. The profile check reproduces the
44
+ placeholder contract without a YAML parser (PowerShell ships none); see
45
+ `Get-DiscoveryProfileValidationError` for what is and is not detected.
48
46
  .EXAMPLE
49
47
  Invoke-DiscoveryArtifactValidation -ValidatorArgs @('evidence-reference', $path)
50
48
 
51
49
  Returns @{ ExitCode = 0; Output = '' } when the artifact conforms.
50
+ CONVENTION: this module fails fast at module scope and imports its siblings with -ErrorAction Stop.
52
51
  #>
53
52
 
54
53
  Set-StrictMode -Version Latest
54
+ $ErrorActionPreference = 'Stop'
55
55
 
56
56
  # Schema-governed artifact types mapped to their filenames under `schemas/discovery/v1/`.
57
57
  # Verified against `validate_discovery_artifacts.py`: `runtime-scenario`,
@@ -37,9 +37,11 @@
37
37
  Compatible with PowerShell 7+. No external module dependencies, no filesystem
38
38
  access, no subprocess, no network, and no wall-clock read. Mirrored
39
39
  byte-identically under extensions/drm-copilot/resources/claude-customizations/.
40
+ CONVENTION: this module fails fast at module scope and imports its siblings with -ErrorAction Stop.
40
41
  #>
41
42
 
42
43
  Set-StrictMode -Version Latest
44
+ $ErrorActionPreference = 'Stop'
43
45
 
44
46
  # Anomaly codes. These are the only values Get-ClaudeHookPayloadAnomalyReason maps.
45
47
  $script:AnomalyEmptyPayload = 'EmptyPayload'
@@ -28,9 +28,11 @@
28
28
  policy for free-text and plugin-backed grammars. Brackets are structural only
29
29
  where they delimit node shapes or attribute blocks: a gantt task named
30
30
  `Deploy (phase 1` must never be blocked as unbalanced.
31
+ CONVENTION: this module fails fast at module scope and imports its siblings with -ErrorAction Stop.
31
32
  #>
32
33
 
33
34
  Set-StrictMode -Version Latest
35
+ $ErrorActionPreference = 'Stop'
34
36
 
35
37
  $script:MermaidGrammarVersion = '11.17.0'
36
38
  $script:MermaidGrammarSourceUrl = 'https://mermaid.js.org/intro/syntax-reference.html'
@@ -30,11 +30,13 @@
30
30
  Pinned to Mermaid 11.17.0 through MermaidGrammar.psm1. Every function is
31
31
  pure: no filesystem, subprocess, network, or wall-clock access, and no input
32
32
  is mutated.
33
+ CONVENTION: this module fails fast at module scope and imports its siblings with -ErrorAction Stop.
33
34
  #>
34
35
 
35
36
  Set-StrictMode -Version Latest
37
+ $ErrorActionPreference = 'Stop'
36
38
 
37
- Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'MermaidGrammar.psm1') -Force
39
+ Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'MermaidGrammar.psm1') -Force -ErrorAction Stop
38
40
 
39
41
  # Arrow-token affix tables. An arrow candidate is a run of `-`, `=`, `.`, or `~`
40
42
  # (the "core") optionally extended by one of these affixes on either side. The
@@ -32,9 +32,11 @@
32
32
  Pinned to Mermaid 11.17.0 through MermaidGrammar.psm1. Every function is pure:
33
33
  no filesystem, subprocess, network, or wall-clock access, and no input is
34
34
  mutated.
35
+ CONVENTION: this module fails fast at module scope and imports its siblings with -ErrorAction Stop.
35
36
  #>
36
37
 
37
38
  Set-StrictMode -Version Latest
39
+ $ErrorActionPreference = 'Stop'
38
40
 
39
41
  # The marker text must be exactly `mermaid-validator: ignore` and is
40
42
  # case-sensitive. Whitespace is permitted around the line, around the comment
@@ -37,13 +37,15 @@
37
37
  no filesystem, subprocess, network, or wall-clock access, and no input is
38
38
  mutated. CRLF, CR, and LF inputs produce identical verdicts because line
39
39
  splitting is normalized once in MermaidMarkdownFences.psm1.
40
+ CONVENTION: this module fails fast at module scope and imports its siblings with -ErrorAction Stop.
40
41
  #>
41
42
 
42
43
  Set-StrictMode -Version Latest
44
+ $ErrorActionPreference = 'Stop'
43
45
 
44
- Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'MermaidGrammar.psm1') -Force
45
- Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'MermaidLineScanner.psm1') -Force
46
- Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'MermaidMarkdownFences.psm1') -Force
46
+ Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'MermaidGrammar.psm1') -Force -ErrorAction Stop
47
+ Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'MermaidLineScanner.psm1') -Force -ErrorAction Stop
48
+ Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'MermaidMarkdownFences.psm1') -Force -ErrorAction Stop
47
49
 
48
50
  function Get-MermaidFinding {
49
51
  <#
@@ -18,9 +18,11 @@
18
18
  model_budget) by a static config-parity Pester test, and the Python modules
19
19
  remain the validator's authoritative reference. This module is one half of a
20
20
  two-language mirror; it never imports validator logic.
21
+ CONVENTION: this module fails fast at module scope and imports its siblings with -ErrorAction Stop.
21
22
  #>
22
23
 
23
24
  Set-StrictMode -Version Latest
25
+ $ErrorActionPreference = 'Stop'
24
26
 
25
27
  # The fixed complexity-band vocabulary, ordered from lowest to highest rigor.
26
28
  # The array order defines "higher" and "lower" band comparisons used by the
@@ -27,9 +27,11 @@
27
27
  (Invoke-OrchestratorStatePreflight) consumed by
28
28
  .claude/hooks/enforce-pr-author-skill.ps1. Its default seam runs the portable
29
29
  in-process validation and names no interpreter on any code path.
30
+ CONVENTION: this module fails fast at module scope and imports its siblings with -ErrorAction Stop.
30
31
  #>
31
32
 
32
33
  Set-StrictMode -Version Latest
34
+ $ErrorActionPreference = 'Stop'
33
35
 
34
36
  # The canonical top-level checkpoint keys required by the primary validator.
35
37
  # Pinned to REQUIRED_STATE_KEYS in scripts/dev_tools/validate_orchestrator_state.py.
@@ -139,6 +141,15 @@ function Get-OrchestratorStateCheckpoint {
139
141
  - Ok (bool): $true when the file exists and parsed to a JSON object.
140
142
  - State (object): the parsed PSCustomObject on success, otherwise $null.
141
143
  - Error (string): a non-empty failure message on failure, otherwise ''.
144
+ .NOTES
145
+ VALUE CONTRACT. An ISO-8601-valued key in the returned State is date-coerced by ConvertFrom-Json
146
+ into System.DateTime, not the string the checkpoint holds. The module-declared ISO-8601 key
147
+ families are last_updated, started_at, completed_at, and verified_at. Every current validation
148
+ is presence-only, so the coercion is unobservable today. Two future exposures make it worth
149
+ stating: value comparison in OrchestratorStateCheckpointValue.psm1, which reports a mismatch
150
+ when one side is a string and the other is not, and the [string] $ComputedAt binding in
151
+ BlastRadius.psm1, which would coerce a DateTime to a culture-dependent string with no error.
152
+ A post-parse repair back to a string is PROHIBITED as lossy in both offset and format.
142
153
  #>
143
154
  [CmdletBinding()]
144
155
  [OutputType([hashtable])]
@@ -23,9 +23,11 @@
23
23
  Every function is pure: it reads no file, starts no process, and never mutates
24
24
  its input. The module imports nothing, so it is the leaf of the parity family's
25
25
  import graph and cannot participate in a load-order cycle.
26
+ CONVENTION: this module fails fast at module scope and imports its siblings with -ErrorAction Stop.
26
27
  #>
27
28
 
28
29
  Set-StrictMode -Version Latest
30
+ $ErrorActionPreference = 'Stop'
29
31
 
30
32
  # The numeric CLR types a JSON number can deserialize to, used by the Python
31
33
  # zero-equivalence predicate so a value is compared numerically, not by type.
@@ -22,16 +22,18 @@
22
22
 
23
23
  Every function is pure: it reads no file, starts no process, and never mutates
24
24
  its input.
25
+ CONVENTION: this module fails fast at module scope and imports its siblings with -ErrorAction Stop.
25
26
  #>
26
27
 
27
28
  Set-StrictMode -Version Latest
29
+ $ErrorActionPreference = 'Stop'
28
30
 
29
31
  # Import the shared checkpoint-value primitives and the single Codex deployment
30
32
  # resolver, resolved relative to this module's directory so both imports travel
31
33
  # with the pushed-down pack regardless of the working directory.
32
- Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'OrchestratorStateCheckpointValue.psm1') -Force
34
+ Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'OrchestratorStateCheckpointValue.psm1') -Force -ErrorAction Stop
33
35
  $script:CodexDeploymentModulePath = Join-Path -Path (Join-Path -Path $PSScriptRoot -ChildPath '..') -ChildPath (Join-Path -Path 'codex-routing' -ChildPath 'CodexDeployment.psm1')
34
- Import-Module $script:CodexDeploymentModulePath -Force
36
+ Import-Module $script:CodexDeploymentModulePath -Force -ErrorAction Stop
35
37
 
36
38
  # The checkpoint key this family validates.
37
39
  $script:CODEX_MODEL_ROUTING_RECEIPTS_KEY = 'codex_model_routing_receipts'
@@ -25,16 +25,18 @@
25
25
 
26
26
  Every function is pure: it reads no file, starts no process, and never mutates
27
27
  its input.
28
+ CONVENTION: this module fails fast at module scope and imports its siblings with -ErrorAction Stop.
28
29
  #>
29
30
 
30
31
  Set-StrictMode -Version Latest
32
+ $ErrorActionPreference = 'Stop'
31
33
 
32
34
  # Import the shared checkpoint-value primitives and the single Codex topology
33
35
  # resolver, resolved relative to this module's directory so both imports travel
34
36
  # with the pushed-down pack regardless of the working directory.
35
- Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'OrchestratorStateCheckpointValue.psm1') -Force
37
+ Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'OrchestratorStateCheckpointValue.psm1') -Force -ErrorAction Stop
36
38
  $script:CodexTopologyModulePath = Join-Path -Path (Join-Path -Path $PSScriptRoot -ChildPath '..') -ChildPath (Join-Path -Path 'codex-routing' -ChildPath 'CodexTopology.psm1')
37
- Import-Module $script:CodexTopologyModulePath -Force
39
+ Import-Module $script:CodexTopologyModulePath -Force -ErrorAction Stop
38
40
 
39
41
  # The checkpoint key this family validates.
40
42
  $script:CODEX_TOPOLOGY_RECEIPTS_KEY = 'codex_topology_receipts'
@@ -44,21 +44,23 @@
44
44
  receipt still yields error text containing the literal token
45
45
  `model_routing_receipts`, so the completion hook maps the failure to its
46
46
  `MODEL_ROUTING_BLOCKED:` block reason.
47
+ CONVENTION: this module fails fast at module scope and imports its siblings with -ErrorAction Stop.
47
48
  #>
48
49
 
49
50
  Set-StrictMode -Version Latest
51
+ $ErrorActionPreference = 'Stop'
50
52
 
51
53
  # Import the sibling shared module, the portable model-routing formulas, and the
52
54
  # ported check families, resolved relative to this module's directory so every
53
55
  # import travels with the pushed-down pack regardless of the working directory.
54
- Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'OrchestratorState.psm1') -Force
56
+ Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'OrchestratorState.psm1') -Force -ErrorAction Stop
55
57
  $script:ModelRoutingModulePath = Join-Path -Path (Join-Path -Path $PSScriptRoot -ChildPath '..') -ChildPath (Join-Path -Path 'model-routing' -ChildPath 'ModelRouting.psm1')
56
- Import-Module $script:ModelRoutingModulePath -Force
57
- Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'OrchestratorStateCheckpointValue.psm1') -Force
58
- Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'OrchestratorStateModelReceipts.psm1') -Force
59
- Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'OrchestratorStateUnconditional.psm1') -Force
60
- Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'OrchestratorStateCompletionChecks.psm1') -Force
61
- Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'OrchestratorStateRoutingContract.psm1') -Force
58
+ Import-Module $script:ModelRoutingModulePath -Force -ErrorAction Stop
59
+ Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'OrchestratorStateCheckpointValue.psm1') -Force -ErrorAction Stop
60
+ Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'OrchestratorStateModelReceipts.psm1') -Force -ErrorAction Stop
61
+ Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'OrchestratorStateUnconditional.psm1') -Force -ErrorAction Stop
62
+ Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'OrchestratorStateCompletionChecks.psm1') -Force -ErrorAction Stop
63
+ Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'OrchestratorStateRoutingContract.psm1') -Force -ErrorAction Stop
62
64
 
63
65
  # The two optional keys the M3 leg re-validates, guarded on key presence so an
64
66
  # absent key does not emit a spurious "must be a list when present" error.
@@ -33,15 +33,17 @@
33
33
 
34
34
  Every function is pure: it reads no file, starts no process, and never mutates
35
35
  its input.
36
+ CONVENTION: this module fails fast at module scope and imports its siblings with -ErrorAction Stop.
36
37
  #>
37
38
 
38
39
  Set-StrictMode -Version Latest
40
+ $ErrorActionPreference = 'Stop'
39
41
 
40
42
  # Import the shared checkpoint-value primitives and the pinned routing matrix,
41
43
  # resolved relative to this module's directory so both imports travel with the
42
44
  # pushed-down pack regardless of the working directory.
43
- Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'OrchestratorStateCheckpointValue.psm1') -Force
44
- Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'OrchestratorStateRoutingMatrix.psm1') -Force
45
+ Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'OrchestratorStateCheckpointValue.psm1') -Force -ErrorAction Stop
46
+ Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'OrchestratorStateRoutingMatrix.psm1') -Force -ErrorAction Stop
45
47
 
46
48
  # The six step-status keys, in report order.
47
49
  $script:STEP_STATUS_KEYS = @(
@@ -19,16 +19,18 @@
19
19
 
20
20
  Every function is pure: it reads no file, starts no process, and never mutates
21
21
  its input. Each check returns a string array, empty when the block is valid.
22
+ CONVENTION: this module fails fast at module scope and imports its siblings with -ErrorAction Stop.
22
23
  #>
23
24
 
24
25
  Set-StrictMode -Version Latest
26
+ $ErrorActionPreference = 'Stop'
25
27
 
26
28
  # Import the shared checkpoint-value primitives and the two reference formulas,
27
29
  # resolved relative to this module's directory so the imports travel with the
28
30
  # pushed-down pack regardless of the consumer repository's working directory.
29
- Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'OrchestratorStateCheckpointValue.psm1') -Force
31
+ Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'OrchestratorStateCheckpointValue.psm1') -Force -ErrorAction Stop
30
32
  $script:ModelRoutingModulePath = Join-Path -Path (Join-Path -Path $PSScriptRoot -ChildPath '..') -ChildPath (Join-Path -Path 'model-routing' -ChildPath 'ModelRouting.psm1')
31
- Import-Module $script:ModelRoutingModulePath -Force
33
+ Import-Module $script:ModelRoutingModulePath -Force -ErrorAction Stop
32
34
 
33
35
  # The complexity-band vocabulary, ordered lowest to highest. Pinned to BAND_ORDER
34
36
  # in scripts/dev_tools/compute_complexity_floor.py and to the identical ordering
@@ -27,14 +27,16 @@
27
27
 
28
28
  Every function is pure: it reads no file, starts no process, and never mutates
29
29
  its input. Each check returns a string array, empty when the block is valid.
30
+ CONVENTION: this module fails fast at module scope and imports its siblings with -ErrorAction Stop.
30
31
  #>
31
32
 
32
33
  Set-StrictMode -Version Latest
34
+ $ErrorActionPreference = 'Stop'
33
35
 
34
36
  # Import the shared checkpoint-value primitives, resolved relative to this
35
37
  # module's directory so the import travels with the pushed-down pack regardless
36
38
  # of the consumer repository's working directory.
37
- Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'OrchestratorStateCheckpointValue.psm1') -Force
39
+ Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'OrchestratorStateCheckpointValue.psm1') -Force -ErrorAction Stop
38
40
 
39
41
  # The eight keys every list-form delegation receipt must carry. Pinned to
40
42
  # REQUIRED_RECEIPT_KEYS in scripts/dev_tools/validate_orchestrator_state.py.
@@ -45,15 +45,17 @@
45
45
 
46
46
  Every function is pure: it reads no file, starts no process, and never mutates
47
47
  its input.
48
+ CONVENTION: this module fails fast at module scope and imports its siblings with -ErrorAction Stop.
48
49
  #>
49
50
 
50
51
  Set-StrictMode -Version Latest
52
+ $ErrorActionPreference = 'Stop'
51
53
 
52
54
  # Import the shared checkpoint-value primitives and the pinned routing matrix,
53
55
  # resolved relative to this module's directory so both imports travel with the
54
56
  # pushed-down pack regardless of the working directory.
55
- Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'OrchestratorStateCheckpointValue.psm1') -Force
56
- Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'OrchestratorStateRoutingMatrix.psm1') -Force
57
+ Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'OrchestratorStateCheckpointValue.psm1') -Force -ErrorAction Stop
58
+ Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'OrchestratorStateRoutingMatrix.psm1') -Force -ErrorAction Stop
57
59
 
58
60
  # The promotion-entry MCP tools and the promotion type that triggers substitution.
59
61
  $script:FEATURE_PROMOTION_ENTRY_TOOL = 'new_potential_entry'
@@ -33,13 +33,15 @@
33
33
 
34
34
  Every function is pure: it reads no file, starts no process, and never mutates
35
35
  its input.
36
+ CONVENTION: this module fails fast at module scope and imports its siblings with -ErrorAction Stop.
36
37
  #>
37
38
 
38
39
  Set-StrictMode -Version Latest
40
+ $ErrorActionPreference = 'Stop'
39
41
 
40
42
  # Import the shared checkpoint-value primitives, resolved relative to this
41
43
  # module's directory so the import travels with the pushed-down pack.
42
- Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'OrchestratorStateCheckpointValue.psm1') -Force
44
+ Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'OrchestratorStateCheckpointValue.psm1') -Force -ErrorAction Stop
43
45
 
44
46
  # The pinned routing-matrix subset. Each route records the two gate flags and the
45
47
  # three required-name lists the completion checks consume. A gate flag of $null
@@ -37,20 +37,22 @@
37
37
 
38
38
  The function is pure: it reads no file, starts no process, and never mutates
39
39
  its input.
40
+ CONVENTION: this module fails fast at module scope and imports its siblings with -ErrorAction Stop.
40
41
  #>
41
42
 
42
43
  Set-StrictMode -Version Latest
44
+ $ErrorActionPreference = 'Stop'
43
45
 
44
46
  # Import the four leaf check modules eagerly. None of them imports this module,
45
47
  # so this import graph has no cycle. OrchestratorState.psm1 is deliberately NOT
46
48
  # imported here; it is loaded lazily inside the function, because the preflight
47
49
  # path in that module imports this one and an eager import in both directions
48
50
  # would couple their load order.
49
- Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'OrchestratorStateReceipts.psm1') -Force
50
- Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'OrchestratorStateModelReceipts.psm1') -Force
51
- Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'OrchestratorStateCodexModelReceipts.psm1') -Force
52
- Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'OrchestratorStateCodexTopologyReceipts.psm1') -Force
53
- Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'OrchestratorStateCheckpointValue.psm1') -Force
51
+ Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'OrchestratorStateReceipts.psm1') -Force -ErrorAction Stop
52
+ Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'OrchestratorStateModelReceipts.psm1') -Force -ErrorAction Stop
53
+ Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'OrchestratorStateCodexModelReceipts.psm1') -Force -ErrorAction Stop
54
+ Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'OrchestratorStateCodexTopologyReceipts.psm1') -Force -ErrorAction Stop
55
+ Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'OrchestratorStateCheckpointValue.psm1') -Force -ErrorAction Stop
54
56
 
55
57
  # The checkpoint key whose value carries the delegation receipts. It is read with
56
58
  # the Python `is not None` guard rather than a presence guard, matching the
@@ -0,0 +1,44 @@
1
+ <#
2
+ .SYNOPSIS
3
+ Markdown checkbox counting for generated requirement documents.
4
+
5
+ .DESCRIPTION
6
+ Provides Get-NamedSectionCheckboxCount, a pure function that counts the
7
+ markdown checkbox items contained by a named heading section. It reads no
8
+ file, starts no process, and never mutates its input.
9
+ CONVENTION: this module fails fast at module scope and imports its siblings with -ErrorAction Stop.
10
+ #>
11
+
12
+ Set-StrictMode -Version Latest
13
+ $ErrorActionPreference = 'Stop'
14
+
15
+ <#
16
+ .SYNOPSIS
17
+ Counts markdown checkbox items contained by a named heading section.
18
+ #>
19
+ function Get-NamedSectionCheckboxCount {
20
+ [CmdletBinding()]
21
+ [OutputType([int])]
22
+ param(
23
+ [Parameter(Mandatory = $true)][AllowEmptyString()][string] $Document,
24
+ [Parameter(Mandatory = $true)][string] $Heading
25
+ )
26
+
27
+ $headingPattern = '^(?<marks>#{1,6})\s+' + [regex]::Escape($Heading) + '\s*$'
28
+ $inside = $false
29
+ $level = 0
30
+ $count = 0
31
+ foreach ($line in ($Document -split "`r?`n")) {
32
+ if (-not $inside) {
33
+ $match = [regex]::Match($line, $headingPattern)
34
+ if ($match.Success) { $inside = $true; $level = $match.Groups['marks'].Value.Length }
35
+ continue
36
+ }
37
+ $nextHeading = [regex]::Match($line, '^(?<marks>#{1,6})\s+')
38
+ if ($nextHeading.Success -and $nextHeading.Groups['marks'].Value.Length -le $level) { break }
39
+ if ($line -match '^\s*[-*]\s+\[[ xX]\]\s+') { $count++ }
40
+ }
41
+ return $count
42
+ }
43
+
44
+ Export-ModuleMember -Function Get-NamedSectionCheckboxCount
@@ -239,6 +239,15 @@
239
239
  }
240
240
  ]
241
241
  },
242
+ {
243
+ "matcher": "prd-feature",
244
+ "hooks": [
245
+ {
246
+ "type": "command",
247
+ "command": "pwsh -NoProfile -File .claude/hooks/validate-prd-feature-output.ps1"
248
+ }
249
+ ]
250
+ },
242
251
  {
243
252
  "matcher": "pr-author",
244
253
  "hooks": [
@@ -35,6 +35,8 @@ When multiple AC source files exist, track checkboxes in **each** applicable fil
35
35
 
36
36
  ## AC Identification
37
37
 
38
+ For generated-document summaries, call `.claude/lib/requirements/GeneratedDocumentCounters.psm1` and supply `Acceptance Criteria` as the named section. The counter begins after that heading and ends at the next equal-or-shallower heading. Do not use `scripts/dev_tools/plan_progress_report.py`, which counts plan tasks rather than generated requirements criteria.
39
+
38
40
  Acceptance criteria are markdown checkbox items within AC source files.
39
41
 
40
42
  Deterministic heading rule:
@@ -155,6 +155,10 @@ Declaration requirement. Every plan handoff MUST carry exactly one of these two
155
155
 
156
156
  ## Preflight Validation (Planner ↔ Executor)
157
157
 
158
+ ### Planner Internal Review Record
159
+
160
+ Before executor preflight, the planner must emit exactly one bounded record between `PLANNER-INTERNAL-REVIEW: PASS` and the existing `PREFLIGHT:` signal. The record requires exactly one passing declaration each for `CITATION-TO-TREE`, `AC-TRACEABILITY`, and `SCOPE-BOUNDARY`; one or more `CITATION: <repository-relative path> | <nonblank locator>` entries; exactly one `AC-INVENTORY:` declaration containing unique nonblank IDs; one `AC-MAPPING: <ID> | IMPLEMENTATION: <nonblank> | TESTS: <nonblank> | EVIDENCE: <nonblank>` for every and only inventory ID; and exactly one `UNRESOLVED-GAPS: NONE`. Missing, blank, duplicate, non-passing, out-of-bounds, or inventory/mapping-disagreeing declarations block handoff. If review cannot pass, emit `SELF-REVIEW: BLOCKED` and do not hand the plan to preflight. `SELF-REVIEW: RE-DERIVED THIS PASS` remains distinct and does not replace executor clearance.
161
+
158
162
  When validating or handing off plans for execution:
159
163
  - Use the directive line: `DIRECTIVE: PREFLIGHT VALIDATION ONLY`.
160
164
  - Require one of the exact signals: