@danmoisan/drm-copilot-mcp 1.1.23 → 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 (199) hide show
  1. package/out/mcp-server.js +13347 -7926
  2. package/package.json +1 -1
  3. package/resources/claude-customizations/.claude/agents/discovery-capability-sentinel.md +34 -0
  4. package/resources/claude-customizations/.claude/agents/legacy-parity-analyst.md +101 -43
  5. package/resources/claude-customizations/.claude/agents/migration-coverage-reviewer.md +107 -43
  6. package/resources/claude-customizations/.claude/agents/parallel-orchestrator.md +14 -0
  7. package/resources/claude-customizations/.claude/agents/parallel-planner.md +21 -1
  8. package/resources/claude-customizations/.claude/agents/pr-author.md +17 -1
  9. package/resources/claude-customizations/.claude/agents/requirements-reconciler.md +117 -42
  10. package/resources/claude-customizations/.claude/agents/runtime-characterization-analyst.md +103 -43
  11. package/resources/claude-customizations/.claude/hooks/discovery-capability-probe.ps1 +102 -0
  12. package/resources/claude-customizations/.claude/hooks/enforce-discovery-artifact-gate.ps1 +69 -194
  13. package/resources/claude-customizations/.claude/hooks/enforce-discovery-planning-gate.ps1 +87 -0
  14. package/resources/claude-customizations/.claude/hooks/enforce-epic-merge-gate.ps1 +7 -1
  15. package/resources/claude-customizations/.claude/hooks/enforce-model-routing-receipt.ps1 +6 -3
  16. package/resources/claude-customizations/.claude/hooks/enforce-orchestration-preimplementation-gate-epic-scope.ps1 +168 -48
  17. package/resources/claude-customizations/.claude/hooks/enforce-orchestration-preimplementation-gate.ps1 +1 -1
  18. package/resources/claude-customizations/.claude/hooks/enforce-powershell-batch-budget.ps1 +59 -20
  19. package/resources/claude-customizations/.claude/hooks/enforce-pr-author-command-allowlist.ps1 +44 -3
  20. package/resources/claude-customizations/.claude/hooks/enforce-pr-author-skill-helpers.ps1 +60 -4
  21. package/resources/claude-customizations/.claude/hooks/enforce-pr-author-skill.epic-base-branch.ps1 +4 -2
  22. package/resources/claude-customizations/.claude/hooks/enforce-python-batch-budget.ps1 +59 -20
  23. package/resources/claude-customizations/.claude/hooks/record-discovery-agent-start.ps1 +132 -0
  24. package/resources/claude-customizations/.claude/hooks/validate-discovery-artifact-gate.ps1 +56 -212
  25. package/resources/claude-customizations/.claude/hooks/validate-orchestrator-output-rejection.ps1 +172 -0
  26. package/resources/claude-customizations/.claude/hooks/validate-orchestrator-output.ps1 +9 -1
  27. package/resources/claude-customizations/.claude/lib/blast-radius/BlastRadius.psm1 +9 -3
  28. package/resources/claude-customizations/.claude/lib/blast-radius/BlastRadiusAggregate.psm1 +154 -0
  29. package/resources/claude-customizations/.claude/lib/blast-radius/BlastRadiusCombination.psm1 +228 -0
  30. package/resources/claude-customizations/.claude/lib/blast-radius/BlastRadiusExtraction.psm1 +1 -0
  31. package/resources/claude-customizations/.claude/lib/blast-radius/BlastRadiusNormalization.psm1 +4 -2
  32. package/resources/claude-customizations/.claude/lib/blast-radius/BlastRadiusScheduling.psm1 +63 -16
  33. package/resources/claude-customizations/.claude/lib/blast-radius/BlastRadiusTokenShape.psm1 +56 -1
  34. package/resources/claude-customizations/.claude/lib/blast-radius/BlastRadiusWriteIntent.psm1 +4 -1
  35. package/resources/claude-customizations/.claude/lib/codex-routing/CodexDeployment.psm1 +5 -1
  36. package/resources/claude-customizations/.claude/lib/codex-routing/CodexDiscoveryRouting.psm1 +161 -0
  37. package/resources/claude-customizations/.claude/lib/codex-routing/CodexTopology.psm1 +25 -2
  38. package/resources/claude-customizations/.claude/lib/discovery-validation/DiscoveryAuthority.psd1 +90 -0
  39. package/resources/claude-customizations/.claude/lib/discovery-validation/DiscoveryAuthority.psm1 +493 -0
  40. package/resources/claude-customizations/.claude/lib/discovery-validation/DiscoveryAuthorization.psm1 +479 -0
  41. package/resources/claude-customizations/.claude/lib/discovery-validation/DiscoveryCapability.psm1 +468 -0
  42. package/resources/claude-customizations/.claude/lib/discovery-validation/DiscoveryEncoding.psm1 +156 -0
  43. package/resources/claude-customizations/.claude/lib/discovery-validation/DiscoveryManifest.psm1 +384 -0
  44. package/resources/claude-customizations/.claude/lib/discovery-validation/DiscoveryObservation.psm1 +217 -0
  45. package/resources/claude-customizations/.claude/lib/discovery-validation/DiscoveryPayload.psm1 +276 -0
  46. package/resources/claude-customizations/.claude/lib/discovery-validation/DiscoveryPlanning.psm1 +336 -0
  47. package/resources/claude-customizations/.claude/lib/discovery-validation/DiscoveryRootGrant.psm1 +164 -0
  48. package/resources/claude-customizations/.claude/lib/discovery-validation/DiscoveryStart.psm1 +440 -0
  49. package/resources/claude-customizations/.claude/lib/discovery-validation/DiscoveryStartRecord.psm1 +296 -0
  50. package/resources/claude-customizations/.claude/lib/discovery-validation/DiscoveryStop.psm1 +336 -0
  51. package/resources/claude-customizations/.claude/lib/discovery-validation/DiscoveryToolRouting.psm1 +228 -0
  52. package/resources/claude-customizations/.claude/lib/discovery-validation/DiscoveryValidation.psm1 +188 -341
  53. package/resources/claude-customizations/.claude/lib/worktree-resolution/HookTargetWorktree.psm1 +391 -0
  54. package/resources/claude-customizations/.claude/rules/orchestrator-state.md +1 -0
  55. package/resources/claude-customizations/.claude/rules/parallel-orchestration.md +150 -18
  56. package/resources/claude-customizations/.claude/settings.json +32 -3
  57. package/resources/claude-customizations/.claude/skills/adjudicate-unspecified-behavior/SKILL.md +135 -0
  58. package/resources/claude-customizations/.claude/skills/characterize-runtime-behavior/SKILL.md +134 -0
  59. package/resources/claude-customizations/.claude/skills/discovery-behavior-reconciliation/SKILL.md +28 -47
  60. package/resources/claude-customizations/.claude/skills/discovery-coverage-ledger/SKILL.md +32 -48
  61. package/resources/claude-customizations/.claude/skills/discovery-parity-matrix/SKILL.md +28 -45
  62. package/resources/claude-customizations/.claude/skills/discovery-repo-inventory/SKILL.md +28 -62
  63. package/resources/claude-customizations/.claude/skills/discovery-runtime-characterization/SKILL.md +28 -45
  64. package/resources/claude-customizations/.claude/skills/discovery-validate-artifacts/SKILL.md +28 -61
  65. package/resources/claude-customizations/.claude/skills/discovery-workflow/SKILL.md +55 -139
  66. package/resources/claude-customizations/.claude/skills/execution-environment/SKILL.md +24 -9
  67. package/resources/claude-customizations/.claude/skills/extract-feature-contract/SKILL.md +133 -0
  68. package/resources/claude-customizations/.claude/skills/generate-acceptance-scenarios/SKILL.md +132 -0
  69. package/resources/claude-customizations/.claude/skills/initialize-discovery-workspace/SKILL.md +131 -0
  70. package/resources/claude-customizations/.claude/skills/inventory-legacy-system/SKILL.md +131 -0
  71. package/resources/claude-customizations/.claude/skills/orchestrate/SKILL.md +5 -4
  72. package/resources/claude-customizations/.claude/skills/parallel-add/SKILL.md +21 -1
  73. package/resources/claude-customizations/.claude/skills/parallel-close/SKILL.md +11 -1
  74. package/resources/claude-customizations/.claude/skills/parallel-orchestrate/SKILL.md +34 -0
  75. package/resources/claude-customizations/.claude/skills/parallel-plan/SKILL.md +69 -6
  76. package/resources/claude-customizations/.claude/skills/parallel-remove/SKILL.md +15 -0
  77. package/resources/claude-customizations/.claude/skills/parallel-run/SKILL.md +6 -0
  78. package/resources/claude-customizations/.claude/skills/pr-author/SKILL.md +21 -4
  79. package/resources/claude-customizations/.claude/skills/reconcile-parity-matrix/SKILL.md +131 -0
  80. package/resources/claude-customizations/.claude/skills/review-discovery-coverage/SKILL.md +129 -0
  81. package/resources/claude-customizations/.claude/skills/validate-discovery-artifacts/SKILL.md +127 -0
  82. package/resources/claude-customizations/config/blast-radius.json +6 -5
  83. package/resources/claude-customizations/config/orchestration-routing.json +61 -1
  84. package/resources/claude-customizations/pack-manifests/core.json +33 -1
  85. package/resources/codex-and-agents-customizations/.agents/skills/adjudicate-unspecified-behavior/SKILL.md +135 -0
  86. package/resources/codex-and-agents-customizations/.agents/skills/atomic-planner/SKILL.md +7 -0
  87. package/resources/codex-and-agents-customizations/.agents/skills/characterize-runtime-behavior/SKILL.md +134 -0
  88. package/resources/codex-and-agents-customizations/.agents/skills/discovery-behavior-reconciliation/SKILL.md +46 -0
  89. package/resources/codex-and-agents-customizations/.agents/skills/discovery-coverage-ledger/SKILL.md +50 -0
  90. package/resources/codex-and-agents-customizations/.agents/skills/discovery-parity-matrix/SKILL.md +46 -0
  91. package/resources/codex-and-agents-customizations/.agents/skills/discovery-repo-inventory/SKILL.md +46 -0
  92. package/resources/codex-and-agents-customizations/.agents/skills/discovery-runtime-characterization/SKILL.md +46 -0
  93. package/resources/codex-and-agents-customizations/.agents/skills/discovery-validate-artifacts/SKILL.md +46 -0
  94. package/resources/codex-and-agents-customizations/.agents/skills/discovery-workflow/SKILL.md +62 -0
  95. package/resources/codex-and-agents-customizations/.agents/skills/execution-environment/SKILL.md +24 -9
  96. package/resources/codex-and-agents-customizations/.agents/skills/extract-feature-contract/SKILL.md +133 -0
  97. package/resources/codex-and-agents-customizations/.agents/skills/generate-acceptance-scenarios/SKILL.md +132 -0
  98. package/resources/codex-and-agents-customizations/.agents/skills/initialize-discovery-workspace/SKILL.md +131 -0
  99. package/resources/codex-and-agents-customizations/.agents/skills/inventory-legacy-system/SKILL.md +131 -0
  100. package/resources/codex-and-agents-customizations/.agents/skills/orchestrator-workflow/SKILL.md +8 -0
  101. package/resources/codex-and-agents-customizations/.agents/skills/reconcile-parity-matrix/SKILL.md +131 -0
  102. package/resources/codex-and-agents-customizations/.agents/skills/review-discovery-coverage/SKILL.md +129 -0
  103. package/resources/codex-and-agents-customizations/.agents/skills/validate-discovery-artifacts/SKILL.md +127 -0
  104. package/resources/codex-and-agents-customizations/.codex/agents/discovery-capability-sentinel.toml +51 -0
  105. package/resources/codex-and-agents-customizations/.codex/agents/legacy-parity-analyst-c1.toml +148 -0
  106. package/resources/codex-and-agents-customizations/.codex/agents/legacy-parity-analyst-c2.toml +148 -0
  107. package/resources/codex-and-agents-customizations/.codex/agents/legacy-parity-analyst-c3-elevated.toml +148 -0
  108. package/resources/codex-and-agents-customizations/.codex/agents/legacy-parity-analyst-c3.toml +148 -0
  109. package/resources/codex-and-agents-customizations/.codex/agents/legacy-parity-analyst-c4.toml +148 -0
  110. package/resources/codex-and-agents-customizations/.codex/agents/legacy-parity-analyst.toml +148 -0
  111. package/resources/codex-and-agents-customizations/.codex/agents/migration-coverage-reviewer-c1.toml +154 -0
  112. package/resources/codex-and-agents-customizations/.codex/agents/migration-coverage-reviewer-c2.toml +154 -0
  113. package/resources/codex-and-agents-customizations/.codex/agents/migration-coverage-reviewer-c3-elevated.toml +154 -0
  114. package/resources/codex-and-agents-customizations/.codex/agents/migration-coverage-reviewer-c3.toml +154 -0
  115. package/resources/codex-and-agents-customizations/.codex/agents/migration-coverage-reviewer-c4.toml +154 -0
  116. package/resources/codex-and-agents-customizations/.codex/agents/migration-coverage-reviewer.toml +154 -0
  117. package/resources/codex-and-agents-customizations/.codex/agents/requirements-reconciler-c1.toml +164 -0
  118. package/resources/codex-and-agents-customizations/.codex/agents/requirements-reconciler-c2.toml +164 -0
  119. package/resources/codex-and-agents-customizations/.codex/agents/requirements-reconciler-c3-elevated.toml +164 -0
  120. package/resources/codex-and-agents-customizations/.codex/agents/requirements-reconciler-c3.toml +164 -0
  121. package/resources/codex-and-agents-customizations/.codex/agents/requirements-reconciler-c4.toml +164 -0
  122. package/resources/codex-and-agents-customizations/.codex/agents/requirements-reconciler.toml +164 -0
  123. package/resources/codex-and-agents-customizations/.codex/agents/runtime-characterization-analyst-c1.toml +150 -0
  124. package/resources/codex-and-agents-customizations/.codex/agents/runtime-characterization-analyst-c2.toml +150 -0
  125. package/resources/codex-and-agents-customizations/.codex/agents/runtime-characterization-analyst-c3-elevated.toml +150 -0
  126. package/resources/codex-and-agents-customizations/.codex/agents/runtime-characterization-analyst-c3.toml +150 -0
  127. package/resources/codex-and-agents-customizations/.codex/agents/runtime-characterization-analyst-c4.toml +150 -0
  128. package/resources/codex-and-agents-customizations/.codex/agents/runtime-characterization-analyst.toml +150 -0
  129. package/resources/codex-and-agents-customizations/.codex/config.toml +33 -3
  130. package/resources/codex-and-agents-customizations/.codex/hooks/codex-agent-profile-attestation.ps1 +22 -0
  131. package/resources/codex-and-agents-customizations/.codex/hooks/discovery-capability-probe.ps1 +97 -0
  132. package/resources/codex-and-agents-customizations/.codex/hooks/discovery-start-attestation.ps1 +171 -0
  133. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-codex-model-routing.ps1 +4 -1
  134. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-discovery-artifact-gate.ps1 +187 -0
  135. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-discovery-planning-gate.ps1 +149 -0
  136. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-orchestration-preimplementation-gate-epic-scope.ps1 +239 -2
  137. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-orchestration-preimplementation-gate.ps1 +6 -15
  138. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-powershell-batch-budget.ps1 +54 -15
  139. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-python-batch-budget.ps1 +54 -15
  140. package/resources/codex-and-agents-customizations/.codex/hooks/hook-target-worktree.ps1 +369 -0
  141. package/resources/codex-and-agents-customizations/.codex/hooks/record-subagent-routing-attestation.ps1 +8 -0
  142. package/resources/codex-and-agents-customizations/.codex/hooks/validate-codex-subagent-routing.ps1 +22 -1
  143. package/resources/codex-and-agents-customizations/.codex/hooks/validate-discovery-agent-output.ps1 +178 -0
  144. package/resources/codex-and-agents-customizations/.codex/scripts/Resolve-CodexTopology.ps1 +11 -1
  145. package/resources/codex-and-agents-customizations/pack-manifests/core.json +63 -1
  146. package/resources/config/orchestration-routing.json +61 -1
  147. package/resources/customizations/.github/agents/discovery-capability-sentinel.agent.md +34 -0
  148. package/resources/customizations/.github/agents/legacy-parity-analyst.agent.md +122 -0
  149. package/resources/customizations/.github/agents/migration-coverage-reviewer.agent.md +128 -0
  150. package/resources/customizations/.github/agents/requirements-reconciler.agent.md +138 -0
  151. package/resources/customizations/.github/agents/runtime-characterization-analyst.agent.md +124 -0
  152. package/resources/customizations/.github/hooks/discovery-agent-start.ps1 +139 -0
  153. package/resources/customizations/.github/hooks/discovery-agent-stop.ps1 +123 -0
  154. package/resources/customizations/.github/hooks/discovery-capability-probe.ps1 +98 -0
  155. package/resources/customizations/.github/hooks/discovery-planning.ps1 +91 -0
  156. package/resources/customizations/.github/hooks/discovery-pre-tool.ps1 +123 -0
  157. package/resources/customizations/.github/hooks/discovery.json +35 -0
  158. package/resources/customizations/.github/instructions/mermaid.instructions.md +85 -0
  159. package/resources/customizations/.github/prompts/execute-hard-lock.prompt.md +105 -0
  160. package/resources/customizations/.github/skills/adjudicate-unspecified-behavior/SKILL.md +135 -0
  161. package/resources/customizations/.github/skills/characterize-runtime-behavior/SKILL.md +134 -0
  162. package/resources/customizations/.github/skills/discovery-behavior-reconciliation/SKILL.md +46 -0
  163. package/resources/customizations/.github/skills/discovery-coverage-ledger/SKILL.md +50 -0
  164. package/resources/customizations/.github/skills/discovery-parity-matrix/SKILL.md +46 -0
  165. package/resources/customizations/.github/skills/discovery-repo-inventory/SKILL.md +46 -0
  166. package/resources/customizations/.github/skills/discovery-runtime-characterization/SKILL.md +46 -0
  167. package/resources/customizations/.github/skills/discovery-validate-artifacts/SKILL.md +46 -0
  168. package/resources/customizations/.github/skills/discovery-workflow/SKILL.md +62 -0
  169. package/resources/customizations/.github/skills/execution-environment/SKILL.md +24 -9
  170. package/resources/customizations/.github/skills/extract-feature-contract/SKILL.md +133 -0
  171. package/resources/customizations/.github/skills/generate-acceptance-scenarios/SKILL.md +132 -0
  172. package/resources/customizations/.github/skills/initialize-discovery-workspace/SKILL.md +131 -0
  173. package/resources/customizations/.github/skills/inventory-legacy-system/SKILL.md +131 -0
  174. package/resources/customizations/.github/skills/reconcile-parity-matrix/SKILL.md +131 -0
  175. package/resources/customizations/.github/skills/review-discovery-coverage/SKILL.md +129 -0
  176. package/resources/customizations/.github/skills/validate-discovery-artifacts/SKILL.md +127 -0
  177. package/resources/lib/codex-routing/CodexDeployment.psm1 +5 -1
  178. package/resources/lib/codex-routing/CodexDiscoveryRouting.psm1 +161 -0
  179. package/resources/lib/codex-routing/CodexTopology.psm1 +25 -2
  180. package/resources/lib/discovery-validation/DiscoveryAuthority.psd1 +90 -0
  181. package/resources/lib/discovery-validation/DiscoveryAuthority.psm1 +493 -0
  182. package/resources/lib/discovery-validation/DiscoveryAuthorization.psm1 +479 -0
  183. package/resources/lib/discovery-validation/DiscoveryCapability.psm1 +468 -0
  184. package/resources/lib/discovery-validation/DiscoveryEncoding.psm1 +156 -0
  185. package/resources/lib/discovery-validation/DiscoveryManifest.psm1 +384 -0
  186. package/resources/lib/discovery-validation/DiscoveryObservation.psm1 +217 -0
  187. package/resources/lib/discovery-validation/DiscoveryPayload.psm1 +276 -0
  188. package/resources/lib/discovery-validation/DiscoveryPlanning.psm1 +336 -0
  189. package/resources/lib/discovery-validation/DiscoveryRootGrant.psm1 +164 -0
  190. package/resources/lib/discovery-validation/DiscoveryStart.psm1 +440 -0
  191. package/resources/lib/discovery-validation/DiscoveryStartRecord.psm1 +296 -0
  192. package/resources/lib/discovery-validation/DiscoveryStop.psm1 +336 -0
  193. package/resources/lib/discovery-validation/DiscoveryToolRouting.psm1 +228 -0
  194. package/resources/powershell/PoshQC/PoshQC.Parallel.psm1 +452 -0
  195. package/resources/powershell/PoshQC/PoshQC.Shard.psm1 +106 -8
  196. package/resources/powershell/PoshQC/PoshQC.Testing.psm1 +12 -0
  197. package/resources/powershell/PoshQC/PoshQC.psd1 +6 -1
  198. package/resources/powershell/PoshQC/PoshQC.psm1 +7 -1
  199. package/resources/powershell/PoshQC/README.md +20 -1
@@ -38,6 +38,7 @@ Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'BlastRadiusGlob.psm1')
38
38
  Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'BlastRadiusConfig.psm1') -Force -ErrorAction Stop
39
39
  Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'BlastRadiusConflict.psm1') -Force -ErrorAction Stop
40
40
  Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'BlastRadiusValidation.psm1') -Force -ErrorAction Stop
41
+ Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'BlastRadiusAggregate.psm1') -Force -ErrorAction Stop
41
42
 
42
43
  # Truth-table key and the label every reader error carries.
43
44
  $script:ToleranceKey = 'conflict_tolerance'
@@ -46,9 +47,15 @@ $script:ToleranceLabel = 'config["conflict_tolerance"]'
46
47
  # Member names of the key and of its two nested maps. Each must be carried
47
48
  # exactly, so a misspelled name fails fast instead of reading as absent.
48
49
  $script:MemberName = @('tolerance_percent', 'weights', 'band_durations', 'default_band', 'append_only_paths')
49
- $script:WeightName = @('same_file', 'possible_overlap', 'append_only', 'module')
50
+ $script:WeightName = @('same_file', 'possible_overlap', 'append_only', 'module', 'contract')
50
51
  $script:BandName = @('C1', 'C2', 'C3', 'C4')
51
52
 
53
+ # The one optional member (issue #1013): the issue-combination threshold, read
54
+ # as this default when absent. Pinned to COMBINATION_THRESHOLD_DEFAULT in the
55
+ # Python reference by a Pester parity row.
56
+ $script:CombinationThresholdName = 'combination_threshold_percent'
57
+ $script:CombinationThresholdDefault = 400
58
+
52
59
  # Reason kinds that make a conflict an edge at every tolerance: a shared surface
53
60
  # or a contract dependency cannot be reconciled by a merge step.
54
61
  $script:HardReasonKind = @('shared_surface_overlap', 'contract_dependency')
@@ -140,15 +147,18 @@ function Get-ConfigConflictTolerance {
140
147
  .DESCRIPTION
141
148
  Port of config_conflict_tolerance. An absent or null key returns the
142
149
  strict semantics: tolerance 0, every weight 1, every band duration 1,
143
- default_band C1, and no append-only paths.
150
+ default_band C1, no append-only paths, and the default combination
151
+ threshold. combination_threshold_percent is optional: when present it
152
+ must be an integer of at least 0, and when absent it reads as 400.
144
153
 
145
154
  .PARAMETER Config
146
155
  Parsed config/blast-radius.json.
147
156
 
148
157
  .OUTPUTS
149
158
  System.Collections.Hashtable. Keys tolerance_percent, weights,
150
- band_durations, default_band, and append_only_paths. Every error message
151
- names the conflict_tolerance key.
159
+ band_durations, default_band, append_only_paths, and
160
+ combination_threshold_percent. Every error message names the
161
+ conflict_tolerance key.
152
162
  #>
153
163
  [CmdletBinding()]
154
164
  [OutputType([hashtable])]
@@ -165,22 +175,32 @@ function Get-ConfigConflictTolerance {
165
175
  foreach ($entry in $script:WeightName) { $unit[$entry] = [long]1 }
166
176
  $band = @{}
167
177
  foreach ($entry in $script:BandName) { $band[$entry] = [long]1 }
168
- return @{ tolerance_percent = [long]0; weights = $unit; band_durations = $band; default_band = $script:BandName[0]; append_only_paths = [string[]]@() }
178
+ return @{ tolerance_percent = [long]0; weights = $unit; band_durations = $band; default_band = $script:BandName[0]; append_only_paths = [string[]]@(); combination_threshold_percent = [long]$script:CombinationThresholdDefault }
169
179
  }
170
180
 
171
181
  $member = Get-RequiredMapping -Value $value -FieldName $script:ToleranceLabel
172
- Assert-ExactMemberName -Mapping $member -Name $script:MemberName -FieldName $script:ToleranceLabel
182
+ # The optional member joins the exact name set only when it is present, so
183
+ # every other unknown name is still rejected.
184
+ $hasThreshold = $member.ContainsKey($script:CombinationThresholdName)
185
+ $names = if ($hasThreshold) { @($script:MemberName) + $script:CombinationThresholdName } else { $script:MemberName }
186
+ Assert-ExactMemberName -Mapping $member -Name $names -FieldName $script:ToleranceLabel
173
187
  $defaultBand = $member['default_band']
174
188
  if ($defaultBand -isnot [string] -or $script:BandName -cnotcontains $defaultBand) {
175
189
  throw "$script:ToleranceLabel[""default_band""] must be one of $($script:BandName -join ', ')."
176
190
  }
177
191
 
192
+ $threshold = [long]$script:CombinationThresholdDefault
193
+ if ($hasThreshold) {
194
+ $threshold = Get-RequiredInteger -Value $member[$script:CombinationThresholdName] -FieldName "$script:ToleranceLabel[""$script:CombinationThresholdName""]" -Minimum 0
195
+ }
196
+
178
197
  return @{
179
- tolerance_percent = Get-RequiredInteger -Value $member['tolerance_percent'] -FieldName "$script:ToleranceLabel[""tolerance_percent""]" -Minimum 0
180
- weights = Get-RequiredIntegerMap -Value $member['weights'] -Name $script:WeightName -Member 'weights'
181
- band_durations = Get-RequiredIntegerMap -Value $member['band_durations'] -Name $script:BandName -Member 'band_durations'
182
- default_band = [string]$defaultBand
183
- append_only_paths = [string[]]@(Get-RequiredStringList -Value $member['append_only_paths'] -FieldName "$script:ToleranceLabel[""append_only_paths""]")
198
+ tolerance_percent = Get-RequiredInteger -Value $member['tolerance_percent'] -FieldName "$script:ToleranceLabel[""tolerance_percent""]" -Minimum 0
199
+ weights = Get-RequiredIntegerMap -Value $member['weights'] -Name $script:WeightName -Member 'weights'
200
+ band_durations = Get-RequiredIntegerMap -Value $member['band_durations'] -Name $script:BandName -Member 'band_durations'
201
+ default_band = [string]$defaultBand
202
+ append_only_paths = [string[]]@(Get-RequiredStringList -Value $member['append_only_paths'] -FieldName "$script:ToleranceLabel[""append_only_paths""]")
203
+ combination_threshold_percent = $threshold
184
204
  }
185
205
  }
186
206
 
@@ -221,7 +241,10 @@ function Get-BlastRadiusPairCost {
221
241
  .DESCRIPTION
222
242
  Port of pair_cost. Sums the weight of every overlapping path pair left
223
243
  after the mergeable exclusion, then adds the module weight times the
224
- number of shared modules. Mergeable paths therefore contribute 0.
244
+ number of shared modules and the contract weight times the number of
245
+ distinct shared contract identifiers (the ordinal intersection the
246
+ relation reads for contract_dependency, each identifier counted once).
247
+ Mergeable paths therefore contribute 0.
225
248
 
226
249
  .PARAMETER RadiusA
227
250
  First radius record.
@@ -269,7 +292,10 @@ function Get-BlastRadiusPairCost {
269
292
  $cost += Get-PathPairWeight -EntryA $pair['EntryA'] -EntryB $pair['EntryB'] -Tolerance $Tolerance
270
293
  }
271
294
  $sharedModule = @(@($left['modules']) | Where-Object { @($right['modules']) -ccontains $_ })
272
- return $cost + ([long]$Tolerance['weights']['module'] * $sharedModule.Count)
295
+ # Distinct shared contract identifiers, compared ordinally like the relation.
296
+ $sharedContract = [System.Collections.Generic.HashSet[string]]::new([string[]]@($left['contracts']), [StringComparer]::Ordinal)
297
+ $sharedContract.IntersectWith([string[]]@($right['contracts']))
298
+ return $cost + ([long]$Tolerance['weights']['module'] * $sharedModule.Count) + ([long]$Tolerance['weights']['contract'] * $sharedContract.Count)
273
299
  }
274
300
 
275
301
  function Get-BlastRadiusPairBenefit {
@@ -423,7 +449,9 @@ function Get-BlastRadiusConflictEdge {
423
449
  Port of schedule_conflict_edges. Visits every unordered pair once in
424
450
  ascending key order. A pair whose decision is an edge is recorded as an
425
451
  edge; a conflict within tolerance is recorded as a tolerated overlap; a
426
- pair that does not conflict appears in neither list.
452
+ pair that does not conflict appears in neither list. The aggregate cap
453
+ of BlastRadiusAggregate.psm1 (issue #1013) then promotes tolerated
454
+ overlaps until every item is within its cap.
427
455
 
428
456
  .PARAMETER Item
429
457
  The run's items: records carrying key (an integer issue number), radius,
@@ -454,7 +482,7 @@ function Get-BlastRadiusConflictEdge {
454
482
  )
455
483
 
456
484
  if ($null -eq $Relation) { throw $script:RelationRequired }
457
- [void](Get-ConfigConflictTolerance -Config $Config)
485
+ $tolerance = Get-ConfigConflictTolerance -Config $Config
458
486
  $ordered = @(Get-OrderedSchedulingItem -Item $Item)
459
487
 
460
488
  $edge = [System.Collections.Generic.List[object]]::new()
@@ -472,7 +500,26 @@ function Get-BlastRadiusConflictEdge {
472
500
  }
473
501
  }
474
502
 
475
- return @{ edges = @($edge.ToArray()); tolerated_overlaps = @($tolerated.ToArray()) }
503
+ # Aggregate cap post-pass (issue #1013, D-2): promote each cap-selected
504
+ # tolerated overlap to a non-hard edge carrying its first reason, then
505
+ # re-sort both lists by (a, b). At tolerance 0 nothing is tolerated.
506
+ $band = @{}
507
+ foreach ($entry in $ordered) { $band[$entry['key']] = $entry['band'] }
508
+ $promoted = [System.Collections.Generic.HashSet[string]]::new()
509
+ foreach ($pair in @(Get-AggregateCappedPair -ToleratedOverlap @($tolerated.ToArray()) -Band $band -Tolerance $tolerance)) {
510
+ [void]$promoted.Add(('{0}-{1}' -f $pair['a'], $pair['b']))
511
+ }
512
+ $kept = [System.Collections.Generic.List[object]]::new()
513
+ foreach ($overlap in $tolerated) {
514
+ if ($promoted.Contains(('{0}-{1}' -f $overlap['a'], $overlap['b']))) {
515
+ $edge.Add([ordered]@{ a = $overlap['a']; b = $overlap['b']; reason = @($overlap['reasons'])[0]; hard = $false; cost = $overlap['cost']; benefit = $overlap['benefit'] })
516
+ } else {
517
+ $kept.Add($overlap)
518
+ }
519
+ }
520
+ $sortedEdge = @($edge.ToArray() | Sort-Object -Property { $_['a'] }, { $_['b'] })
521
+
522
+ return @{ edges = $sortedEdge; tolerated_overlaps = @($kept.ToArray()) }
476
523
  }
477
524
 
478
525
  Export-ModuleMember -Function `
@@ -55,6 +55,12 @@
55
55
  from the Python source and pins them equal. A non-ASCII extension is
56
56
  rejected before lower-casing (issue #903); ToLowerInvariant then matches
57
57
  Python's str.lower on ASCII input, and known-name membership is ordinal.
58
+ - Test-GenericContractToken (issue #1006) ports is_generic_contract_token.
59
+ Its stem array equals GENERIC_CONTRACT_STEMS; a Pester parity test reads
60
+ the Python constant from the source and pins $script:GenericContractStem
61
+ equal to it. A token is first checked ordinally to be ASCII, because a
62
+ .NET case-insensitive match folds the Kelvin sign and the long s to
63
+ ASCII letters while Python re.ASCII does not (the issue #903 precedent).
58
64
  CONVENTION: this module fails fast at module scope and imports its siblings with -ErrorAction Stop.
59
65
  #>
60
66
 
@@ -114,6 +120,20 @@ $script:KnownFileName = [System.Collections.Generic.HashSet[string]]::new(
114
120
  ),
115
121
  [StringComparer]::Ordinal)
116
122
 
123
+ # Default spreadsheet sheet-tab stems (issue #1006). A spreadsheet application
124
+ # names a new worksheet or chart sheet with one of these stems followed by a
125
+ # number, so a spec that mentions Sheet1 names a worksheet, not a contract. The
126
+ # array is closed and is pinned equal to GENERIC_CONTRACT_STEMS in the Python
127
+ # reference by a Pester parity test, so edit both files together. The pattern is
128
+ # anchored with \A and \z to match Python's re.fullmatch, and the ASCII pattern
129
+ # is applied first with -cmatch so the comparison is ordinal.
130
+ $script:GenericContractStem = [string[]]@('Sheet', 'Chart')
131
+ $script:GenericContractPattern = [regex]::new(
132
+ '\A(?:' + ($script:GenericContractStem -join '|') + ')[0-9]+\z',
133
+ [System.Text.RegularExpressions.RegexOptions]::IgnoreCase -bor
134
+ [System.Text.RegularExpressions.RegexOptions]::CultureInvariant)
135
+ $script:AsciiOnlyPattern = '\A[\x00-\x7F]*\z'
136
+
117
137
  function Test-PlaceholderMarker {
118
138
  <#
119
139
  .SYNOPSIS
@@ -263,7 +283,42 @@ function Test-FileShapedComponent {
263
283
  return $script:FileExtensionPattern.IsMatch($extension.ToLowerInvariant())
264
284
  }
265
285
 
286
+ function Test-GenericContractToken {
287
+ <#
288
+ .SYNOPSIS
289
+ Report whether a contract token is a default sheet-tab name (issue #1006).
290
+
291
+ .DESCRIPTION
292
+ Port of is_generic_contract_token. Two unrelated work items whose specs
293
+ both named the worksheet Sheet1 in an interface section were given a
294
+ hard contract_dependency edge, because the contract harvest accepts any
295
+ separator-free token carrying a letter. A default sheet-tab name
296
+ identifies no exported symbol, schema, or CLI identifier, so every
297
+ contract-filtering site rejects it with this predicate.
298
+
299
+ .PARAMETER Token
300
+ One candidate contract identifier. The empty string is accepted and
301
+ reports false.
302
+
303
+ .OUTPUTS
304
+ System.Boolean. True only when the token is ASCII and fully matches a
305
+ stem of $script:GenericContractStem followed by one or more ASCII
306
+ digits, compared case-insensitively; otherwise false.
307
+ #>
308
+ [CmdletBinding()]
309
+ [OutputType([bool])]
310
+ param(
311
+ [Parameter(Mandatory = $true)]
312
+ [AllowEmptyString()]
313
+ [string] $Token
314
+ )
315
+
316
+ if ($Token -cnotmatch $script:AsciiOnlyPattern) { return $false }
317
+ return $script:GenericContractPattern.IsMatch($Token)
318
+ }
319
+
266
320
  Export-ModuleMember -Function `
267
321
  Test-PlaceholderMarker, `
268
322
  Test-MultipleFeatureFolderSpan, `
269
- Test-FileShapedComponent
323
+ Test-FileShapedComponent, `
324
+ Test-GenericContractToken
@@ -343,9 +343,12 @@ function Get-WriteIntentSpecContract {
343
343
  continue
344
344
  }
345
345
 
346
+ # A default spreadsheet sheet-tab name such as Sheet1 is not a contract
347
+ # (issue #1006).
346
348
  foreach ($token in @(Get-SingleWordToken -Line $line)) {
347
349
  if ($token.IndexOf('/') -lt 0 -and $token.IndexOf('*') -lt 0 -and
348
- $token.IndexOf('?') -lt 0 -and $script:ContractLetterPattern.IsMatch($token)) {
350
+ $token.IndexOf('?') -lt 0 -and $script:ContractLetterPattern.IsMatch($token) -and
351
+ -not (Test-GenericContractToken -Token $token)) {
349
352
  $identifier.Add($token)
350
353
  }
351
354
  }
@@ -75,7 +75,11 @@ $script:GENERATED_AGENT_FAMILIES = @(
75
75
  'python-typed-engineer',
76
76
  'powershell-typed-engineer',
77
77
  'csharp-typed-engineer',
78
- 'typescript-engineer'
78
+ 'typescript-engineer',
79
+ 'legacy-parity-analyst',
80
+ 'runtime-characterization-analyst',
81
+ 'requirements-reconciler',
82
+ 'migration-coverage-reviewer'
79
83
  )
80
84
  $script:LOGICAL_AGENT_ALIASES = @{ 'feature-review' = 'feature-reviewer' }
81
85
 
@@ -0,0 +1,161 @@
1
+ <#
2
+ .SYNOPSIS
3
+ Constrain direct discovery routing to the fixed operation contracts.
4
+ .DESCRIPTION
5
+ Pure companion to CodexTopology. Constants mirror discovery_operations in
6
+ config/orchestration-routing.json so published consumers need no config or
7
+ interpreter. Receipts describe a specialist and allowed output kinds; they
8
+ grant no writes, approvals, installation rights, or native tool authority.
9
+ CONVENTION: this module fails fast at module scope and imports its siblings with -ErrorAction Stop.
10
+ #>
11
+ Set-StrictMode -Version Latest
12
+ $ErrorActionPreference = 'Stop'
13
+
14
+ # Keep each exact operation independent: sharing a role never broadens its kinds.
15
+ $script:DISCOVERY_OPERATIONS = @{
16
+ 'inventory-legacy-system' = @{
17
+ role = 'legacy-parity-analyst'
18
+ kinds = @('coverage-ledger', 'evidence-reference', 'inventory-snapshot',
19
+ 'required-output-manifest', 'unspecified-behavior', 'unspecified-behavior-collection')
20
+ }
21
+ 'extract-feature-contract' = @{
22
+ role = 'legacy-parity-analyst'
23
+ kinds = @('coverage-ledger', 'evidence-reference', 'feature-contract',
24
+ 'required-output-manifest', 'unspecified-behavior', 'unspecified-behavior-collection')
25
+ }
26
+ 'characterize-runtime-behavior' = @{
27
+ role = 'runtime-characterization-analyst'
28
+ kinds = @('evidence-payload', 'evidence-reference', 'required-output-manifest',
29
+ 'runtime-characterization-scenario', 'unspecified-behavior', 'unspecified-behavior-collection')
30
+ }
31
+ 'reconcile-parity-matrix' = @{
32
+ role = 'requirements-reconciler'
33
+ kinds = @('parity-matrix', 'required-output-manifest',
34
+ 'unspecified-behavior', 'unspecified-behavior-collection')
35
+ }
36
+ 'review-discovery-coverage' = @{
37
+ role = 'migration-coverage-reviewer'
38
+ kinds = @('completion-report', 'coverage-report', 'parity-report',
39
+ 'required-output-manifest', 'validation-report')
40
+ }
41
+ 'adjudicate-unspecified-behavior' = @{
42
+ role = 'requirements-reconciler'
43
+ kinds = @('acceptance-specification', 'acceptance-view', 'product-decision',
44
+ 'product-decision-collection', 'required-output-manifest',
45
+ 'unspecified-behavior', 'unspecified-behavior-collection')
46
+ }
47
+ 'generate-acceptance-scenarios' = @{
48
+ role = 'requirements-reconciler'
49
+ kinds = @('acceptance-specification', 'acceptance-view', 'required-output-manifest')
50
+ }
51
+ 'initialize-discovery-workspace' = @{
52
+ role = 'migration-coverage-reviewer'
53
+ kinds = @('coverage-report', 'required-output-manifest', 'validation-report')
54
+ }
55
+ 'validate-discovery-artifacts' = @{
56
+ role = 'migration-coverage-reviewer'
57
+ kinds = @('coverage-report', 'required-output-manifest', 'validation-report')
58
+ }
59
+ }
60
+
61
+ function Resolve-CodexDiscoveryTopology {
62
+ <#
63
+ .SYNOPSIS
64
+ Select a fixed discovery role or allow the unchanged ordinary route.
65
+ .DESCRIPTION
66
+ Called after topology validates context, languages, counts and boolean
67
+ type. Validates selectors without coercion, rejects nonzero code/test
68
+ scope and root overrides, then returns a new seventeen-key receipt.
69
+ Ordinary requests with no skill return null. Invalid selectors or
70
+ combinations throw ArgumentException in the shared contract order.
71
+ No I/O or native authority is created; returned arrays are fresh copies.
72
+ .PARAMETER InvocationKind
73
+ Exact ordinary or discovery string; all other values are rejected.
74
+ .PARAMETER SkillId
75
+ Exact canonical skill string for discovery, null for ordinary requests.
76
+ .PARAMETER Context
77
+ Execution context already validated by the topology resolver; retained
78
+ unchanged. Named Context because ExecutionContext is a readonly
79
+ automatic variable.
80
+ .PARAMETER Language
81
+ Already normalized languages. Discovery requires an empty collection.
82
+ .PARAMETER ProductionFileCount
83
+ Already validated integer count. Discovery requires zero.
84
+ .PARAMETER TestFileCount
85
+ Already validated integer count. Discovery requires zero.
86
+ .PARAMETER CrossCutting
87
+ Already validated boolean. Discovery requires false.
88
+ .PARAMETER RootPersona
89
+ Raw optional root override. Discovery requires null.
90
+ .OUTPUTS
91
+ System.Collections.Hashtable for discovery, or null for ordinary routing.
92
+ #>
93
+ [CmdletBinding()]
94
+ [OutputType([hashtable])]
95
+ param(
96
+ [Parameter(Mandatory)][AllowNull()][object] $InvocationKind,
97
+ [Parameter(Mandatory)][AllowNull()][object] $SkillId,
98
+ [Parameter(Mandatory)][string] $Context,
99
+ [Parameter(Mandatory)][AllowEmptyCollection()][string[]] $Language,
100
+ [Parameter(Mandatory)][int] $ProductionFileCount,
101
+ [Parameter(Mandatory)][int] $TestFileCount,
102
+ [Parameter(Mandatory)][bool] $CrossCutting,
103
+ [Parameter(Mandatory)][AllowNull()][object] $RootPersona
104
+ )
105
+
106
+ # Object selectors retain their actual types; case-insensitive coercion
107
+ # would otherwise admit unsupported operations at this authority boundary.
108
+ if ($InvocationKind -isnot [string] -or @('ordinary', 'discovery') -cnotcontains $InvocationKind) {
109
+ throw [System.ArgumentException]::new('invocation_kind must be ordinary or discovery.')
110
+ }
111
+ if ($InvocationKind -ceq 'ordinary') {
112
+ if ($null -ne $SkillId) {
113
+ throw [System.ArgumentException]::new('skill_id is only valid for discovery invocations.')
114
+ }
115
+ return $null
116
+ }
117
+
118
+ # Reject discovery scope before looking up a role, preserving guard order
119
+ # even when several fields are malformed in the same invocation.
120
+ if ($null -ne $RootPersona) {
121
+ throw [System.ArgumentException]::new('Discovery invocations do not accept root_persona.')
122
+ }
123
+ if ($ProductionFileCount -ne 0) {
124
+ throw [System.ArgumentException]::new('Discovery invocations require production_file_count=0.')
125
+ }
126
+ if ($TestFileCount -ne 0) {
127
+ throw [System.ArgumentException]::new('Discovery invocations require test_file_count=0.')
128
+ }
129
+ if ($Language.Count -ne 0) {
130
+ throw [System.ArgumentException]::new('Discovery invocations do not accept languages.')
131
+ }
132
+ if ($CrossCutting) {
133
+ throw [System.ArgumentException]::new('Discovery invocations do not accept cross_cutting.')
134
+ }
135
+ if ($SkillId -isnot [string] -or $script:DISCOVERY_OPERATIONS.Keys -cnotcontains $SkillId) {
136
+ throw [System.ArgumentException]::new('Discovery invocations require a supported skill_id.')
137
+ }
138
+
139
+ $operation = $script:DISCOVERY_OPERATIONS[$SkillId]
140
+ return @{
141
+ execution_context = $Context
142
+ languages = [string[]]@()
143
+ production_file_count = 0
144
+ test_file_count = 0
145
+ cross_cutting = $false
146
+ root_persona = $null
147
+ route = 'discovery'
148
+ topology = 'discovery_specialist'
149
+ logical_agent = $operation.role
150
+ routing_reason = 'fixed_discovery_operation'
151
+ max_production_files = 0
152
+ max_test_files = 0
153
+ invocation_kind = 'discovery'
154
+ skill_id = $SkillId
155
+ output_contract_version = '2.0.0'
156
+ permissible_artifact_kinds = [string[]]@($operation.kinds)
157
+ gate_mode = 'agent-output'
158
+ }
159
+ }
160
+
161
+ Export-ModuleMember -Function Resolve-CodexDiscoveryTopology
@@ -53,6 +53,8 @@
53
53
  Set-StrictMode -Version Latest
54
54
  $ErrorActionPreference = 'Stop'
55
55
 
56
+ Import-Module (Join-Path $PSScriptRoot 'CodexDiscoveryRouting.psm1') -ErrorAction Stop
57
+
56
58
  # The three permitted execution contexts, the sorted tuple rendering the Python
57
59
  # message interpolates, and the two contexts that mark epic child work.
58
60
  $script:VALID_EXECUTION_CONTEXTS = @('standalone', 'epic_preparation_child', 'epic_execution_child')
@@ -249,11 +251,17 @@ function Resolve-CodexTopology {
249
251
  Whether the change is cross-cutting. Must be a boolean.
250
252
  .PARAMETER RootPersona
251
253
  An optional forced root persona, which requires a standalone context.
254
+ .PARAMETER InvocationKind
255
+ Exact ordinary or discovery selector. Defaults to ordinary routing.
256
+ .PARAMETER SkillId
257
+ Exact canonical discovery operation. Must be absent for ordinary routing.
252
258
  .OUTPUTS
253
259
  System.Collections.Hashtable with the twelve resolved keys:
254
260
  execution_context, languages, production_file_count, test_file_count,
255
261
  cross_cutting, root_persona, route, topology, logical_agent,
256
- routing_reason, max_production_files, max_test_files.
262
+ routing_reason, max_production_files, max_test_files. Discovery adds
263
+ invocation_kind, skill_id, output_contract_version,
264
+ permissible_artifact_kinds, and gate_mode; it grants no write authority.
257
265
  #>
258
266
  [CmdletBinding()]
259
267
  [OutputType([hashtable])]
@@ -281,7 +289,15 @@ function Resolve-CodexTopology {
281
289
 
282
290
  [Parameter(Mandatory = $false)]
283
291
  [AllowNull()]
284
- [object] $RootPersona = $null
292
+ [object] $RootPersona = $null,
293
+
294
+ [Parameter(Mandatory = $false)]
295
+ [AllowNull()]
296
+ [object] $InvocationKind = 'ordinary',
297
+
298
+ [Parameter(Mandatory = $false)]
299
+ [AllowNull()]
300
+ [object] $SkillId = $null
285
301
  )
286
302
 
287
303
  if ($script:VALID_EXECUTION_CONTEXTS -cnotcontains $ExecutionContext) {
@@ -307,6 +323,13 @@ function Resolve-CodexTopology {
307
323
  $testCount = [int]$TestFileCount
308
324
  $isCrossCutting = [bool]$CrossCutting
309
325
 
326
+ # Discovery validates its closed selector before ordinary root/epic/count
327
+ # dispatch. A fixed specialist receipt conveys routing, never tool grants.
328
+ $discovery = Resolve-CodexDiscoveryTopology -InvocationKind $InvocationKind -SkillId $SkillId `
329
+ -Context $context -Language $languages -ProductionFileCount $productionCount `
330
+ -TestFileCount $testCount -CrossCutting $isCrossCutting -RootPersona $RootPersona
331
+ if ($null -ne $discovery) { return $discovery }
332
+
310
333
  # A forced root persona short-circuits all escalation logic and selects
311
334
  # itself, but only from a standalone context.
312
335
  if ($null -ne $RootPersona) {
@@ -0,0 +1,90 @@
1
+ @{
2
+ # Module manifest for the shared native discovery authority primitives (issue #980).
3
+ # Importing this manifest loads the authority, manifest and payload modules together
4
+ # so a hook can take every narrow primitive from one import.
5
+ RootModule = 'DiscoveryAuthority.psm1'
6
+ ModuleVersion = '2.0.0'
7
+ GUID = '5d0b8e5e-3b7f-4a2a-9f8e-2f9f0b9a7c11'
8
+ Author = 'drm-copilot'
9
+ CompanyName = 'drm-copilot'
10
+ Copyright = '(c) drm-copilot. All rights reserved.'
11
+ Description = 'Protected discovery authority location, activation decoding, input-manifest freshness and host envelope normalization for native discovery hooks.'
12
+ PowerShellVersion = '7.0'
13
+ NestedModules = @('DiscoveryEncoding.psm1', 'DiscoveryManifest.psm1', 'DiscoveryPayload.psm1', 'DiscoveryAuthorization.psm1', 'DiscoveryStartRecord.psm1', 'DiscoveryStart.psm1', 'DiscoveryStop.psm1', 'DiscoveryPlanning.psm1', 'DiscoveryCapability.psm1')
14
+ FunctionsToExport = @(
15
+ 'Get-DiscoverySha256Hex',
16
+ 'Get-DiscoveryBytesSha256Hex',
17
+ 'ConvertTo-DiscoveryCanonicalJson',
18
+ 'Invoke-DiscoveryStoreSeam',
19
+ 'Resolve-DiscoveryAuthorityLocation',
20
+ 'Get-DiscoveryTrustedHostEnvironment',
21
+ 'Get-DiscoveryPartitionName',
22
+ 'Get-DiscoverySessionDirectory',
23
+ 'Get-DiscoveryInvocationDirectory',
24
+ 'Get-DiscoveryActivationRecordPath',
25
+ 'Test-DiscoveryProtectedPath',
26
+ 'Test-DiscoveryRelativePath',
27
+ 'ConvertFrom-DiscoveryActivationRecord',
28
+ 'Read-DiscoveryActivationState',
29
+ 'ConvertFrom-DiscoveryInputManifest',
30
+ 'Get-DiscoveryInputManifestDigest',
31
+ 'Get-DiscoveryWorkspacePath',
32
+ 'Compare-DiscoveryInputManifest',
33
+ 'Assert-DiscoveryInputsFresh',
34
+ 'Test-DiscoverySupportedHost',
35
+ 'ConvertFrom-DiscoveryHostEnvelope',
36
+ 'ConvertFrom-DiscoveryHostPayloadText',
37
+ 'Get-DiscoveryTrustedPrincipal',
38
+ 'Get-DiscoveryHostEnvironmentValueTable',
39
+ 'Get-DiscoveryPayloadAnomalyReason',
40
+ 'Resolve-DiscoveryToolName',
41
+ 'Get-DiscoveryToolOperation',
42
+ 'Get-DiscoveryInputDigest',
43
+ 'Find-DiscoveryAgentInvocation',
44
+ 'ConvertTo-DiscoveryToolAuthorizationRecord',
45
+ 'Get-DiscoveryDefaultStore',
46
+ 'Get-DiscoveryAuthorizationNonce',
47
+ 'Get-DiscoveryPreToolDecision',
48
+ 'ConvertTo-DiscoveryPreToolHookOutput',
49
+ 'Get-DiscoveryAgentRole',
50
+ 'Get-DiscoveryAgentProfilePath',
51
+ 'ConvertFrom-DiscoveryMarkdownProfile',
52
+ 'Read-DiscoveryAgentProfile',
53
+ 'ConvertTo-DiscoveryUtcInstant',
54
+ 'ConvertTo-DiscoveryStartedInvocationText',
55
+ 'ConvertTo-DiscoveryStartAttestationRecord',
56
+ 'Get-DiscoveryStartStore',
57
+ 'Get-DiscoveryStartAttestationFileName',
58
+ 'Find-DiscoveryPreparedInvocation',
59
+ 'Get-DiscoveryDeploymentMismatch',
60
+ 'Get-DiscoveryCapabilityMismatch',
61
+ 'Get-DiscoveryStartDecision',
62
+ 'Get-DiscoveryAuthorizationNonceText',
63
+ 'ConvertTo-DiscoveryStartHookOutput',
64
+ 'Find-DiscoveryAgentInvocationForStop',
65
+ 'Get-DiscoveryReceiptMismatch',
66
+ 'Get-DiscoveryStopDecision',
67
+ 'Get-DiscoveryStopVerdict',
68
+ 'Get-DiscoveryPlanningTarget',
69
+ 'Get-DiscoveryPlanningPrerequisite',
70
+ 'Get-DiscoveryPlanningReceiptMismatch',
71
+ 'Get-DiscoveryPlanningDecision',
72
+ 'ConvertTo-DiscoveryPlanningHookOutput',
73
+ 'Get-DiscoverySentinelRequest',
74
+ 'Get-DiscoverySentinelEnvelope',
75
+ 'Get-DiscoverySessionObservation',
76
+ 'Get-DiscoveryObservationEvidence',
77
+ 'Get-DiscoveryHostRegistration',
78
+ 'Test-DiscoveryHandlerRegistered',
79
+ 'Get-DiscoveryCapabilityObservation',
80
+ 'Write-DiscoveryCapabilityAttestation'
81
+ )
82
+ CmdletsToExport = @()
83
+ VariablesToExport = @()
84
+ AliasesToExport = @()
85
+ PrivateData = @{
86
+ PSData = @{
87
+ Tags = @('drm-copilot', 'discovery', 'hooks')
88
+ }
89
+ }
90
+ }