@danmoisan/drm-copilot-mcp 1.0.13 → 1.0.15

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 (131) hide show
  1. package/out/mcp-server.js +3160 -458
  2. package/package.json +1 -1
  3. package/resources/claude-customizations/.claude/agents/epic-orchestrator.md +24 -0
  4. package/resources/claude-customizations/.claude/agents/epic-planner.md +121 -0
  5. package/resources/claude-customizations/.claude/agents/orchestrator.md +2 -2
  6. package/resources/claude-customizations/.claude/hooks/enforce-epic-invocation-origin.ps1 +246 -0
  7. package/resources/claude-customizations/.claude/settings.json +9 -2
  8. package/resources/claude-customizations/.claude/skills/epic-orchestrate/SKILL.md +7 -0
  9. package/resources/claude-customizations/.claude/skills/epic-plan/SKILL.md +189 -0
  10. package/resources/claude-customizations/.claude/skills/epic-run/SKILL.md +38 -0
  11. package/resources/claude-customizations/.claude/skills/orchestrate/SKILL.md +21 -2
  12. package/resources/claude-customizations/pack-manifests/core.json +4 -0
  13. package/resources/codex-and-agents-customizations/.agents/skills/architecture-boundaries/SKILL.md +0 -1
  14. package/resources/codex-and-agents-customizations/.agents/skills/codex-model-routing/SKILL.md +100 -0
  15. package/resources/codex-and-agents-customizations/.agents/skills/codex-model-routing/agents/openai.yaml +4 -0
  16. package/resources/codex-and-agents-customizations/.agents/skills/epic-orchestrate/SKILL.md +170 -0
  17. package/resources/codex-and-agents-customizations/.agents/skills/epic-plan/SKILL.md +230 -0
  18. package/resources/codex-and-agents-customizations/.agents/skills/epic-run/SKILL.md +39 -0
  19. package/resources/codex-and-agents-customizations/.agents/skills/general-code-change/SKILL.md +0 -1
  20. package/resources/codex-and-agents-customizations/.agents/skills/general-unit-test/SKILL.md +0 -1
  21. package/resources/codex-and-agents-customizations/.agents/skills/orchestrate/SKILL.md +89 -9
  22. package/resources/codex-and-agents-customizations/.agents/skills/orchestrator-workflow/SKILL.md +39 -4
  23. package/resources/codex-and-agents-customizations/.agents/skills/quality-tiers/SKILL.md +0 -1
  24. package/resources/codex-and-agents-customizations/.agents/skills/tonality/SKILL.md +0 -1
  25. package/resources/codex-and-agents-customizations/.codex/agents/atomic-executor-c1.toml +153 -0
  26. package/resources/codex-and-agents-customizations/.codex/agents/atomic-executor-c2.toml +153 -0
  27. package/resources/codex-and-agents-customizations/.codex/agents/atomic-executor-c3-elevated.toml +153 -0
  28. package/resources/codex-and-agents-customizations/.codex/agents/atomic-executor-c3.toml +153 -0
  29. package/resources/codex-and-agents-customizations/.codex/agents/atomic-executor-c4.toml +153 -0
  30. package/resources/codex-and-agents-customizations/.codex/agents/atomic-executor.toml +2 -0
  31. package/resources/codex-and-agents-customizations/.codex/agents/atomic-planner-c1.toml +95 -0
  32. package/resources/codex-and-agents-customizations/.codex/agents/atomic-planner-c2.toml +95 -0
  33. package/resources/codex-and-agents-customizations/.codex/agents/atomic-planner-c3-elevated.toml +95 -0
  34. package/resources/codex-and-agents-customizations/.codex/agents/atomic-planner-c3.toml +95 -0
  35. package/resources/codex-and-agents-customizations/.codex/agents/atomic-planner-c4.toml +95 -0
  36. package/resources/codex-and-agents-customizations/.codex/agents/atomic-planner.toml +2 -0
  37. package/resources/codex-and-agents-customizations/.codex/agents/csharp-typed-engineer-c1.toml +99 -0
  38. package/resources/codex-and-agents-customizations/.codex/agents/csharp-typed-engineer-c2.toml +99 -0
  39. package/resources/codex-and-agents-customizations/.codex/agents/csharp-typed-engineer-c3-elevated.toml +99 -0
  40. package/resources/codex-and-agents-customizations/.codex/agents/csharp-typed-engineer-c3.toml +99 -0
  41. package/resources/codex-and-agents-customizations/.codex/agents/csharp-typed-engineer-c4.toml +99 -0
  42. package/resources/codex-and-agents-customizations/.codex/agents/csharp-typed-engineer.toml +2 -0
  43. package/resources/codex-and-agents-customizations/.codex/agents/epic-orchestrator.toml +96 -0
  44. package/resources/codex-and-agents-customizations/.codex/agents/epic-planner.toml +97 -0
  45. package/resources/codex-and-agents-customizations/.codex/agents/feature-reviewer-c1.toml +62 -0
  46. package/resources/codex-and-agents-customizations/.codex/agents/feature-reviewer-c2.toml +62 -0
  47. package/resources/codex-and-agents-customizations/.codex/agents/feature-reviewer-c3-elevated.toml +62 -0
  48. package/resources/codex-and-agents-customizations/.codex/agents/feature-reviewer-c3.toml +62 -0
  49. package/resources/codex-and-agents-customizations/.codex/agents/feature-reviewer-c4.toml +62 -0
  50. package/resources/codex-and-agents-customizations/.codex/agents/feature-reviewer.toml +2 -0
  51. package/resources/codex-and-agents-customizations/.codex/agents/orchestrator-c1.toml +200 -0
  52. package/resources/codex-and-agents-customizations/.codex/agents/orchestrator-c2.toml +200 -0
  53. package/resources/codex-and-agents-customizations/.codex/agents/orchestrator-c3-elevated.toml +200 -0
  54. package/resources/codex-and-agents-customizations/.codex/agents/orchestrator-c3.toml +200 -0
  55. package/resources/codex-and-agents-customizations/.codex/agents/orchestrator-c4.toml +200 -0
  56. package/resources/codex-and-agents-customizations/.codex/agents/orchestrator.toml +53 -3
  57. package/resources/codex-and-agents-customizations/.codex/agents/powershell-typed-engineer-c1.toml +110 -0
  58. package/resources/codex-and-agents-customizations/.codex/agents/powershell-typed-engineer-c2.toml +110 -0
  59. package/resources/codex-and-agents-customizations/.codex/agents/powershell-typed-engineer-c3-elevated.toml +110 -0
  60. package/resources/codex-and-agents-customizations/.codex/agents/powershell-typed-engineer-c3.toml +110 -0
  61. package/resources/codex-and-agents-customizations/.codex/agents/powershell-typed-engineer-c4.toml +110 -0
  62. package/resources/codex-and-agents-customizations/.codex/agents/powershell-typed-engineer.toml +2 -0
  63. package/resources/codex-and-agents-customizations/.codex/agents/pr-author-c1.toml +28 -0
  64. package/resources/codex-and-agents-customizations/.codex/agents/pr-author-c2.toml +28 -0
  65. package/resources/codex-and-agents-customizations/.codex/agents/pr-author-c3-elevated.toml +28 -0
  66. package/resources/codex-and-agents-customizations/.codex/agents/pr-author-c3.toml +28 -0
  67. package/resources/codex-and-agents-customizations/.codex/agents/pr-author-c4.toml +28 -0
  68. package/resources/codex-and-agents-customizations/.codex/agents/pr-author.toml +2 -0
  69. package/resources/codex-and-agents-customizations/.codex/agents/prd-feature-c1.toml +55 -0
  70. package/resources/codex-and-agents-customizations/.codex/agents/prd-feature-c2.toml +55 -0
  71. package/resources/codex-and-agents-customizations/.codex/agents/prd-feature-c3-elevated.toml +55 -0
  72. package/resources/codex-and-agents-customizations/.codex/agents/prd-feature-c3.toml +55 -0
  73. package/resources/codex-and-agents-customizations/.codex/agents/prd-feature-c4.toml +55 -0
  74. package/resources/codex-and-agents-customizations/.codex/agents/prd-feature.toml +2 -0
  75. package/resources/codex-and-agents-customizations/.codex/agents/python-typed-engineer-c1.toml +102 -0
  76. package/resources/codex-and-agents-customizations/.codex/agents/python-typed-engineer-c2.toml +102 -0
  77. package/resources/codex-and-agents-customizations/.codex/agents/python-typed-engineer-c3-elevated.toml +102 -0
  78. package/resources/codex-and-agents-customizations/.codex/agents/python-typed-engineer-c3.toml +102 -0
  79. package/resources/codex-and-agents-customizations/.codex/agents/python-typed-engineer-c4.toml +102 -0
  80. package/resources/codex-and-agents-customizations/.codex/agents/python-typed-engineer.toml +2 -0
  81. package/resources/codex-and-agents-customizations/.codex/agents/task-researcher-c1.toml +105 -0
  82. package/resources/codex-and-agents-customizations/.codex/agents/task-researcher-c2.toml +105 -0
  83. package/resources/codex-and-agents-customizations/.codex/agents/task-researcher-c3-elevated.toml +105 -0
  84. package/resources/codex-and-agents-customizations/.codex/agents/task-researcher-c3.toml +105 -0
  85. package/resources/codex-and-agents-customizations/.codex/agents/task-researcher-c4.toml +105 -0
  86. package/resources/codex-and-agents-customizations/.codex/agents/task-researcher.toml +2 -0
  87. package/resources/codex-and-agents-customizations/.codex/agents/typescript-engineer-c1.toml +50 -0
  88. package/resources/codex-and-agents-customizations/.codex/agents/typescript-engineer-c2.toml +50 -0
  89. package/resources/codex-and-agents-customizations/.codex/agents/typescript-engineer-c3-elevated.toml +50 -0
  90. package/resources/codex-and-agents-customizations/.codex/agents/typescript-engineer-c3.toml +50 -0
  91. package/resources/codex-and-agents-customizations/.codex/agents/typescript-engineer-c4.toml +50 -0
  92. package/resources/codex-and-agents-customizations/.codex/agents/typescript-engineer.toml +2 -0
  93. package/resources/codex-and-agents-customizations/.codex/config.toml +202 -37
  94. package/resources/codex-and-agents-customizations/.codex/hooks/authorize-root-epic-invocation.ps1 +236 -0
  95. package/resources/codex-and-agents-customizations/.codex/hooks/check-powershell-test-purity.ps1 +178 -69
  96. package/resources/codex-and-agents-customizations/.codex/hooks/check-python-test-purity.ps1 +92 -19
  97. package/resources/codex-and-agents-customizations/.codex/hooks/codex-agent-profile-attestation.ps1 +199 -0
  98. package/resources/codex-and-agents-customizations/.codex/hooks/codex-authority-store.ps1 +182 -0
  99. package/resources/codex-and-agents-customizations/.codex/hooks/codex-epic-child-launch-attestation.ps1 +129 -0
  100. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-checkpoint-monotonic.ps1 +148 -31
  101. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-codex-model-routing.ps1 +198 -0
  102. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-completion-consistency.ps1 +28 -19
  103. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-epic-child-worktree-binding.ps1 +325 -0
  104. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-epic-merge-gate.ps1 +140 -0
  105. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-epic-planning-only.ps1 +292 -0
  106. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-epic-root-invocation.ps1 +135 -0
  107. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-epic-wave-barrier.ps1 +295 -0
  108. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-epic-worktree-removal-gate.ps1 +151 -0
  109. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-evidence-locations.ps1 +99 -34
  110. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-orchestration-preimplementation-gate.ps1 +143 -27
  111. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-powershell-batch-budget.ps1 +88 -43
  112. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-promotion-mcp-only.ps1 +65 -20
  113. package/resources/codex-and-agents-customizations/.codex/hooks/enforce-python-batch-budget.ps1 +88 -42
  114. package/resources/codex-and-agents-customizations/.codex/hooks/record-subagent-routing-attestation.ps1 +414 -0
  115. package/resources/codex-and-agents-customizations/.codex/hooks/validate-bash.ps1 +164 -51
  116. package/resources/codex-and-agents-customizations/.codex/hooks/validate-codex-subagent-routing.ps1 +154 -0
  117. package/resources/codex-and-agents-customizations/.codex/hooks/validate-feature-review-coverage.ps1 +58 -23
  118. package/resources/codex-and-agents-customizations/AGENTS.md +27 -0
  119. package/resources/codex-and-agents-customizations/pack-manifests/core.json +66 -1
  120. package/resources/codex-and-agents-customizations/pack-manifests/csharp-legacy.json +6 -1
  121. package/resources/codex-and-agents-customizations/pack-manifests/csharp-modern.json +6 -1
  122. package/resources/codex-and-agents-customizations/pack-manifests/powershell.json +6 -1
  123. package/resources/codex-and-agents-customizations/pack-manifests/python.json +6 -1
  124. package/resources/codex-and-agents-customizations/pack-manifests/typescript.json +6 -1
  125. package/resources/config/orchestration-routing.json +167 -0
  126. package/resources/powershell/PoshQC/PoshQC.Analyzer.psm1 +1 -1
  127. package/resources/powershell/PoshQC/PoshQC.ScanConfig.psm1 +125 -0
  128. package/resources/powershell/PoshQC/PoshQC.Testing.psm1 +14 -2
  129. package/resources/powershell/PoshQC/PoshQC.psd1 +0 -4
  130. package/resources/powershell/PoshQC/PoshQC.psm1 +26 -6
  131. package/resources/powershell/PoshQC/settings/pester.runsettings.psd1 +34 -18
@@ -1,72 +1,185 @@
1
- # Converted hook
2
- # Review the generated hook behavior before enabling it.
3
1
 
4
2
  <#
5
3
  .SYNOPSIS
6
- Pre-tool-use hook for Claude Code that blocks dangerous Bash commands.
4
+ Codex PreToolUse hook that blocks dangerous shell commands.
7
5
 
8
6
  .DESCRIPTION
9
- This script is invoked by the Claude Code PreToolUse hook before any Bash
10
- command is executed. It reads the proposed command string from the
11
- CLAUDE_TOOL_INPUT environment variable (JSON with a 'command' field) or
12
- falls back to the first positional argument. If the command matches any
13
- blocked pattern (destructive operations such as forced deletions, forced
14
- pushes, or hard resets), the script exits with code 1 to prevent execution.
15
- Safe commands exit with code 0.
7
+ Reads one Codex hook payload from stdin, validates tool_input.command, and emits the current
8
+ PreToolUse deny envelope for destructive operations. Malformed hook input fails closed with
9
+ exit code 2 and the reason on stderr. Safe commands emit no output and exit 0.
16
10
 
17
11
  .NOTES
18
- Compatible with PowerShell 7+.
19
- This script must not modify any state; it is a read-only validation gate.
12
+ Compatible with PowerShell 7+. This hook is read-only.
20
13
  #>
21
14
  [CmdletBinding()]
22
- param(
23
- [Parameter(Position = 0, Mandatory = $false)]
24
- [string]$CommandInput
25
- )
26
-
27
- # Blocked patterns that represent destructive or irreversible operations.
28
- $blockedPatterns = @(
29
- 'rm -rf',
30
- 'git push --force',
31
- 'git push origin --force',
32
- 'Remove-Item -Recurse -Force',
33
- 'git reset --hard',
34
- 'git push -f'
35
- )
36
-
37
- # Resolve the command string from CLAUDE_TOOL_INPUT JSON or positional argument.
38
- $commandToCheck = ''
39
-
40
- if ($env:CLAUDE_TOOL_INPUT) {
41
- try {
42
- $parsed = $env:CLAUDE_TOOL_INPUT | ConvertFrom-Json
43
- if ($parsed.command) {
44
- $commandToCheck = $parsed.command
15
+ param()
16
+
17
+ function Get-BlockedBashPattern {
18
+ [CmdletBinding()]
19
+ [OutputType([string[]])]
20
+ param()
21
+
22
+ return [string[]]@(
23
+ 'rm -rf',
24
+ 'git push --force',
25
+ 'git push origin --force',
26
+ 'Remove-Item -Recurse -Force',
27
+ 'git reset --hard',
28
+ 'git push -f'
29
+ )
30
+ }
31
+
32
+ function Get-BlockedPatternMatch {
33
+ [CmdletBinding()]
34
+ [OutputType([string])]
35
+ param(
36
+ [Parameter(Mandatory = $false)]
37
+ [AllowEmptyString()]
38
+ [AllowNull()]
39
+ [string] $Command
40
+ )
41
+
42
+ if (-not $Command) {
43
+ return $null
44
+ }
45
+
46
+ foreach ($pattern in (Get-BlockedBashPattern)) {
47
+ if ($Command.Contains($pattern)) {
48
+ return $pattern
45
49
  }
46
50
  }
47
- catch {
48
- # If JSON parsing fails, treat the raw environment variable as the command.
49
- $commandToCheck = $env:CLAUDE_TOOL_INPUT
51
+
52
+ return $null
53
+ }
54
+
55
+ function Get-BashBlockReason {
56
+ [CmdletBinding()]
57
+ [OutputType([string])]
58
+ param(
59
+ [Parameter(Mandatory = $false)]
60
+ [AllowEmptyString()]
61
+ [AllowNull()]
62
+ [string] $Command
63
+ )
64
+
65
+ $pattern = Get-BlockedPatternMatch -Command $Command
66
+ if (-not $pattern) {
67
+ return $null
50
68
  }
69
+
70
+ return "Blocked dangerous command pattern detected: '$pattern'"
51
71
  }
52
72
 
53
- # Fall back to positional argument when the environment variable is absent or empty.
54
- if (-not $commandToCheck -and $CommandInput) {
55
- $commandToCheck = $CommandInput
73
+ function Get-BashDenyDecision {
74
+ [CmdletBinding()]
75
+ [OutputType([System.Collections.Specialized.OrderedDictionary])]
76
+ param(
77
+ [Parameter(Mandatory)]
78
+ [string] $Reason
79
+ )
80
+
81
+ [ordered]@{
82
+ hookSpecificOutput = [ordered]@{
83
+ hookEventName = 'PreToolUse'
84
+ permissionDecision = 'deny'
85
+ permissionDecisionReason = $Reason
86
+ }
87
+ }
56
88
  }
57
89
 
58
- # When no command is provided, allow execution (nothing to validate).
59
- if (-not $commandToCheck) {
60
- exit 0
90
+ function Get-BashCommandToCheck {
91
+ [CmdletBinding()]
92
+ [OutputType([string])]
93
+ param(
94
+ [Parameter(Mandatory = $false)]
95
+ [AllowEmptyString()]
96
+ [AllowNull()]
97
+ [string] $ToolInputRaw,
98
+
99
+ [Parameter(Mandatory = $false)]
100
+ [AllowEmptyString()]
101
+ [AllowNull()]
102
+ [string] $PositionalInput
103
+ )
104
+
105
+ if ($ToolInputRaw) {
106
+ try {
107
+ $parsed = $ToolInputRaw | ConvertFrom-Json -ErrorAction Stop
108
+ if ($parsed.command) {
109
+ return [string]$parsed.command
110
+ }
111
+ } catch {
112
+ # If JSON parsing fails, treat the raw input as the command.
113
+ return $ToolInputRaw
114
+ }
115
+ }
116
+
117
+ if ($PositionalInput) {
118
+ return $PositionalInput
119
+ }
120
+
121
+ return ''
122
+ }
123
+
124
+ function Invoke-ValidateBashDecision {
125
+ [CmdletBinding()]
126
+ [OutputType([System.Collections.Specialized.OrderedDictionary])]
127
+ param(
128
+ [Parameter(Mandatory = $false)]
129
+ [AllowEmptyString()]
130
+ [AllowNull()]
131
+ [string] $ToolInputRaw,
132
+
133
+ [Parameter(Mandatory = $false)]
134
+ [AllowEmptyString()]
135
+ [AllowNull()]
136
+ [string] $PositionalInput
137
+ )
138
+
139
+ $commandToCheck = Get-BashCommandToCheck -ToolInputRaw $ToolInputRaw -PositionalInput $PositionalInput
140
+
141
+ $reason = Get-BashBlockReason -Command $commandToCheck
142
+ if ($reason) {
143
+ return Get-BashDenyDecision -Reason $reason
144
+ }
145
+
146
+ return $null
61
147
  }
62
148
 
63
- # Check the command against each blocked pattern.
64
- foreach ($pattern in $blockedPatterns) {
65
- if ($commandToCheck.Contains($pattern)) {
66
- Write-Error "Blocked dangerous command pattern detected: '$pattern'"
67
- exit 1
149
+ function ConvertFrom-CodexBashHookPayload {
150
+ [CmdletBinding()]
151
+ param([Parameter(Mandatory)][string] $PayloadRaw)
152
+
153
+ if ([string]::IsNullOrWhiteSpace($PayloadRaw)) {
154
+ throw 'validate-bash hook input is empty.'
155
+ }
156
+ try {
157
+ $payload = $PayloadRaw | ConvertFrom-Json -ErrorAction Stop
158
+ } catch {
159
+ throw "validate-bash hook input is malformed JSON: $_"
160
+ }
161
+ if ($payload.PSObject.Properties.Name -notcontains 'tool_input' -or $null -eq $payload.tool_input) {
162
+ throw 'validate-bash hook input is missing tool_input.'
163
+ }
164
+ if ([string]$payload.hook_event_name -ne 'PreToolUse' -or [string]$payload.tool_name -ne 'Bash') {
165
+ throw 'validate-bash requires a PreToolUse Bash payload.'
68
166
  }
167
+ return $payload
69
168
  }
70
169
 
71
- # Command passed all checks.
72
- exit 0
170
+ if ($MyInvocation.InvocationName -eq '.') {
171
+ return
172
+ }
173
+
174
+ try {
175
+ $payload = ConvertFrom-CodexBashHookPayload -PayloadRaw ([Console]::In.ReadToEnd())
176
+ $toolInputRaw = $payload.tool_input | ConvertTo-Json -Compress -Depth 20
177
+ $decision = Invoke-ValidateBashDecision -ToolInputRaw $toolInputRaw
178
+ if ($null -ne $decision -and $decision.hookSpecificOutput.permissionDecision -eq 'deny') {
179
+ $decision | ConvertTo-Json -Compress -Depth 5 | Write-Output
180
+ }
181
+ exit 0
182
+ } catch {
183
+ [Console]::Error.WriteLine([string]$_)
184
+ exit 2
185
+ }
@@ -0,0 +1,154 @@
1
+ <#
2
+ .SYNOPSIS
3
+ Requests continuation when a routed subagent stops without valid model or epic provenance.
4
+
5
+ .DESCRIPTION
6
+ SubagentStop is a continuation mechanism, not a hard output rejection. This hook supplies the
7
+ in-process backstop; the MCP checkpoint validator remains the authoritative completion gate.
8
+ #>
9
+ [CmdletBinding()]
10
+ param()
11
+
12
+ . (Join-Path $PSScriptRoot 'codex-authority-store.ps1')
13
+
14
+ function ConvertFrom-CodexStopJson {
15
+ [CmdletBinding()]
16
+ param([Parameter(Mandatory)][string] $Raw, [Parameter(Mandatory)][string] $Name)
17
+
18
+ if ([string]::IsNullOrWhiteSpace($Raw)) {
19
+ throw "MODEL_ROUTING_ATTESTATION_BLOCKED: $Name is empty."
20
+ }
21
+ try {
22
+ return $Raw | ConvertFrom-Json -ErrorAction Stop
23
+ } catch {
24
+ throw "MODEL_ROUTING_ATTESTATION_BLOCKED: $Name is malformed JSON: $_"
25
+ }
26
+ }
27
+
28
+ function Test-CodexStopGatedAgent {
29
+ [CmdletBinding()]
30
+ [OutputType([bool])]
31
+ param([Parameter(Mandatory)][string] $AgentType)
32
+
33
+ if ($AgentType -match '-c(?:1|2|3|4|3-elevated)$') {
34
+ return $true
35
+ }
36
+ return @(
37
+ 'epic-planner', 'epic-orchestrator', 'orchestrator', 'atomic-planner',
38
+ 'atomic-executor', 'feature-review', 'feature-reviewer', 'task-researcher',
39
+ 'prd-feature', 'pr-author', 'python-typed-engineer', 'powershell-typed-engineer',
40
+ 'csharp-typed-engineer', 'typescript-engineer'
41
+ ) -contains $AgentType
42
+ }
43
+
44
+ function Get-CodexStopContinuation {
45
+ [CmdletBinding()]
46
+ [OutputType([System.Collections.Specialized.OrderedDictionary])]
47
+ param(
48
+ [Parameter(Mandatory)][string] $Reason,
49
+ [Parameter(Mandatory)][bool] $AlreadyContinued
50
+ )
51
+
52
+ if ($AlreadyContinued) {
53
+ return [ordered]@{
54
+ continue = $false
55
+ stopReason = $Reason
56
+ systemMessage = $Reason
57
+ }
58
+ }
59
+ return [ordered]@{
60
+ decision = 'block'
61
+ reason = $Reason
62
+ }
63
+ }
64
+
65
+ function Invoke-CodexSubagentStopDecision {
66
+ [CmdletBinding()]
67
+ param(
68
+ [Parameter(Mandatory)][string] $PayloadRaw,
69
+ [AllowNull()][AllowEmptyString()][string] $AttestationRaw
70
+ )
71
+
72
+ $payload = ConvertFrom-CodexStopJson -Raw $PayloadRaw -Name 'SubagentStop input'
73
+ $agentType = [string]$payload.agent_type
74
+ if (-not $agentType -or -not (Test-CodexStopGatedAgent -AgentType $agentType)) {
75
+ return $null
76
+ }
77
+ $alreadyContinued = $payload.stop_hook_active -is [bool] -and [bool]$payload.stop_hook_active
78
+ if ([string]::IsNullOrWhiteSpace($AttestationRaw)) {
79
+ $marker = if (@('epic-planner', 'epic-orchestrator') -contains $agentType) {
80
+ 'EPIC_INVOCATION_ORIGIN_BLOCKED'
81
+ } else {
82
+ 'MODEL_ROUTING_ATTESTATION_BLOCKED'
83
+ }
84
+ $reason = '{0}: no SubagentStart attestation exists for ''{1}''.' -f $marker, $agentType
85
+ return Get-CodexStopContinuation -Reason $reason -AlreadyContinued $alreadyContinued
86
+ }
87
+
88
+ $attestation = ConvertFrom-CodexStopJson -Raw $AttestationRaw -Name 'routing attestation'
89
+ if ([string]$attestation.agent_id -ne [string]$payload.agent_id -or
90
+ [string]$attestation.agent_type -ne $agentType) {
91
+ return Get-CodexStopContinuation -Reason "MODEL_ROUTING_ATTESTATION_BLOCKED: attestation identity does not match '$agentType'." -AlreadyContinued $alreadyContinued
92
+ }
93
+ if (@('epic-planner', 'epic-orchestrator') -contains $agentType) {
94
+ if ($attestation.provenance_valid -isnot [bool] -or -not [bool]$attestation.provenance_valid) {
95
+ return Get-CodexStopContinuation -Reason "EPIC_INVOCATION_ORIGIN_BLOCKED: '$agentType' lacks valid root provenance." -AlreadyContinued $alreadyContinued
96
+ }
97
+ }
98
+ if ($attestation.routing_valid -isnot [bool] -or -not [bool]$attestation.routing_valid) {
99
+ return Get-CodexStopContinuation -Reason "MODEL_ROUTING_ATTESTATION_BLOCKED: '$agentType' did not run under its recorded deployment model." -AlreadyContinued $alreadyContinued
100
+ }
101
+ if (-not [string]::IsNullOrWhiteSpace([string]$payload.model) -and
102
+ [string]$attestation.actual_model -ne [string]$payload.model) {
103
+ return Get-CodexStopContinuation -Reason "MODEL_ROUTING_ATTESTATION_BLOCKED: stop model differs from the start attestation for '$agentType'." -AlreadyContinued $alreadyContinued
104
+ }
105
+ return $null
106
+ }
107
+
108
+ function Find-CodexStopAttestationRaw {
109
+ [CmdletBinding()]
110
+ [OutputType([string])]
111
+ param([Parameter(Mandatory)][string] $StateRoot, [Parameter(Mandatory)][string] $AgentId)
112
+
113
+ if (-not (Test-Path -LiteralPath $StateRoot -PathType Container)) {
114
+ return ''
115
+ }
116
+ foreach ($path in Get-ChildItem -LiteralPath $StateRoot -Filter 'codex-routing-attestation.*.json' -File) {
117
+ try {
118
+ $raw = Get-Content -Raw -LiteralPath $path.FullName
119
+ $value = $raw | ConvertFrom-Json -ErrorAction Stop
120
+ if ([string]$value.agent_id -eq $AgentId) {
121
+ return $raw
122
+ }
123
+ } catch {
124
+ continue
125
+ }
126
+ }
127
+ return ''
128
+ }
129
+
130
+ if ($MyInvocation.InvocationName -eq '.') {
131
+ return
132
+ }
133
+
134
+ try {
135
+ $payloadRaw = [Console]::In.ReadToEnd()
136
+ $payload = ConvertFrom-CodexStopJson -Raw $payloadRaw -Name 'SubagentStop input'
137
+ $repositoryRoot = Split-Path (Split-Path $PSScriptRoot -Parent) -Parent
138
+ $sessionId = [string]$payload.session_id
139
+ if ([string]::IsNullOrWhiteSpace($sessionId)) {
140
+ throw 'MODEL_ROUTING_ATTESTATION_BLOCKED: SubagentStop session_id is empty.'
141
+ }
142
+ $stateRoot = Get-CodexAuthorityStateRoot `
143
+ -RepositoryRoot $repositoryRoot `
144
+ -SessionId $sessionId
145
+ $attestationRaw = Find-CodexStopAttestationRaw -StateRoot $stateRoot -AgentId ([string]$payload.agent_id)
146
+ $decision = Invoke-CodexSubagentStopDecision -PayloadRaw $payloadRaw -AttestationRaw $attestationRaw
147
+ if ($null -ne $decision) {
148
+ $decision | ConvertTo-Json -Compress -Depth 5 | Write-Output
149
+ }
150
+ exit 0
151
+ } catch {
152
+ [Console]::Error.WriteLine([string]$_)
153
+ exit 2
154
+ }
@@ -1,6 +1,3 @@
1
- # Converted hook
2
- # Review the generated hook behavior before enabling it.
3
-
4
1
  <#
5
2
  .SYNOPSIS
6
3
  SubagentStop hook that validates feature-review coverage verdicts against the branch diff.
@@ -33,8 +30,10 @@
33
30
  PowerShell artifacts/pester/powershell-coverage.xml (JaCoCo XML)
34
31
  CSharp artifacts/csharp/coverage.xml (JaCoCo XML)
35
32
 
36
- On a validation failure the script writes a block decision to stdout and exits 1.
37
- Read-only: inspects artifacts on disk and never modifies state.
33
+ Reads one Codex SubagentStop payload from stdin. On validation failure, the hook
34
+ requests one continuation with decision=block and exit 0. If stop_hook_active is
35
+ already true, it emits continue=false to avoid a continuation loop. Malformed input
36
+ fails closed with exit 2 and the reason on stderr.
38
37
 
39
38
  .NOTES
40
39
  Compatible with PowerShell 7+.
@@ -45,15 +44,7 @@ param()
45
44
  $ErrorActionPreference = 'Stop'
46
45
 
47
46
  function Get-RepoRoot {
48
- $start = (Get-Location).Path
49
- $current = $start
50
- while ($true) {
51
- if (Test-Path (Join-Path $current '.claude')) { return $current }
52
- $parent = Split-Path $current -Parent
53
- if (-not $parent -or $parent -eq $current) { break }
54
- $current = $parent
55
- }
56
- return $start
47
+ return Split-Path (Split-Path $PSScriptRoot -Parent) -Parent
57
48
  }
58
49
 
59
50
  function Get-LatestPolicyAudit {
@@ -214,17 +205,51 @@ function Test-LanguageCoverageRow {
214
205
  return @{ Ok = $true; Reason = $null }
215
206
  }
216
207
 
217
- function Write-BlockDecision {
218
- param([string]$Reason)
208
+ function Get-FeatureReviewCoverageContinuation {
209
+ [CmdletBinding()]
210
+ [OutputType([System.Collections.Specialized.OrderedDictionary])]
211
+ param(
212
+ [Parameter(Mandatory)][string] $Reason,
213
+ [Parameter(Mandatory)][bool] $StopHookActive
214
+ )
219
215
 
220
- $payload = [ordered]@{
216
+ if ($StopHookActive) {
217
+ return [ordered]@{
218
+ continue = $false
219
+ stopReason = $Reason
220
+ systemMessage = $Reason
221
+ }
222
+ }
223
+ return [ordered]@{
221
224
  decision = 'block'
222
225
  reason = $Reason
223
- } | ConvertTo-Json -Compress
224
- Write-Output $payload
226
+ }
227
+ }
228
+
229
+ if ($MyInvocation.InvocationName -eq '.') {
230
+ return
225
231
  }
226
232
 
227
233
  try {
234
+ $payloadRaw = [Console]::In.ReadToEnd()
235
+ if ([string]::IsNullOrWhiteSpace($payloadRaw)) {
236
+ throw 'validate-feature-review-coverage hook input is empty.'
237
+ }
238
+ try {
239
+ $payload = $payloadRaw | ConvertFrom-Json -ErrorAction Stop
240
+ } catch {
241
+ throw "validate-feature-review-coverage hook input is malformed JSON: $_"
242
+ }
243
+ if ($payload.PSObject.Properties.Name -notcontains 'stop_hook_active' -or
244
+ $payload.stop_hook_active -isnot [bool]) {
245
+ throw 'validate-feature-review-coverage hook input requires boolean stop_hook_active.'
246
+ }
247
+ if ([string]$payload.hook_event_name -ne 'SubagentStop' -or
248
+ @('feature-review', 'feature-reviewer') -notcontains [string]$payload.agent_type) {
249
+ throw 'validate-feature-review-coverage requires a feature-review SubagentStop payload.'
250
+ }
251
+ $stopHookActive = [bool]$payload.stop_hook_active
252
+
228
253
  $repoRoot = Get-RepoRoot
229
254
  $audit = Get-LatestPolicyAudit -RepoRoot $repoRoot
230
255
  if (-not $audit) {
@@ -253,13 +278,23 @@ try {
253
278
  $header = "Feature-review coverage validation failed against branch diff."
254
279
  $body = " - " + ($failures -join "`n - ")
255
280
  $footer = "Audit file: $($audit.FullName)`nFix the policy-audit to carry an explicit PASS or FAIL verdict per language with changed files, and reflect repo-wide coverage below 80% as FAIL."
256
- Write-BlockDecision -Reason ("{0}`n{1}`n{2}" -f $header, $body, $footer)
257
- exit 1
281
+ $reason = "{0}`n{1}`n{2}" -f $header, $body, $footer
282
+ Get-FeatureReviewCoverageContinuation -Reason $reason -StopHookActive $stopHookActive |
283
+ ConvertTo-Json -Compress -Depth 5 |
284
+ Write-Output
285
+ exit 0
258
286
  }
259
287
 
260
288
  exit 0
261
289
  }
262
290
  catch {
263
- Write-BlockDecision -Reason ("Feature-review coverage validator error: {0}" -f $_.Exception.Message)
264
- exit 1
291
+ $reason = "Feature-review coverage validator error: $($_.Exception.Message)"
292
+ if ($null -ne $stopHookActive -and $stopHookActive) {
293
+ Get-FeatureReviewCoverageContinuation -Reason $reason -StopHookActive $true |
294
+ ConvertTo-Json -Compress -Depth 5 |
295
+ Write-Output
296
+ exit 0
297
+ }
298
+ [Console]::Error.WriteLine($reason)
299
+ exit 2
265
300
  }
@@ -315,3 +315,30 @@ This repository uses a four-layer Claude Code runtime architecture that maps the
315
315
  The `.claude/` directory is the standalone runtime surface for Claude Code. Skills, agents, and rules under `.claude/` are self-contained and do not require reading from `.github/` at runtime. The `.github/` directory contains the parallel Copilot-native customization surface.
316
316
 
317
317
  The orchestration checkpoint path for this runtime is `artifacts/orchestration/orchestrator-state.json`. The main session reads `artifacts/orchestration/orchestrator-state.json` before worker delegation and updates the same file across phase transitions.
318
+
319
+ ## Codex Epic Planning and Model Routing
320
+
321
+ The Codex main session has no default orchestrator agent. Use the native skills
322
+ as explicit entry points:
323
+
324
+ - `epic-plan` delegates master scoping and complete preparation through preflight
325
+ to the `epic-planner` agent.
326
+ - `epic-run` executes a prepared epic from the committed
327
+ `docs/features/epics/<slug>/epic-kickoff.md` artifact.
328
+ - `epic-orchestrate` executes a valid manually authored epic manifest.
329
+
330
+ The ordinary `orchestrator` must not invoke either epic persona. Both epic
331
+ personas delegate to child orchestrators, so epic entry requires main-session
332
+ provenance and is enforced by Codex hooks and completion validators.
333
+
334
+ Production-file count selects the engineer/orchestrator topology. C1-C4
335
+ complexity, execution context, and the monotonic orchestration ceiling select an
336
+ exact generated Codex agent profile through `codex-model-routing`. The canonical
337
+ policy is `config/orchestration-routing.json`; deterministic topology receipts,
338
+ exact model slugs, and model-routing receipts must be persisted before
339
+ delegation. Silent model fallback is prohibited.
340
+
341
+ Planning and execution use separate durable checkpoints:
342
+
343
+ - `artifacts/orchestration/epic-planner-state.json`
344
+ - `artifacts/orchestration/epic-orchestrator-state.json`
@@ -8,6 +8,11 @@
8
8
  ".agents/skills/atomic-executor/SKILL.md",
9
9
  ".agents/skills/atomic-plan-contract/SKILL.md",
10
10
  ".agents/skills/atomic-planner/SKILL.md",
11
+ ".agents/skills/codex-model-routing/SKILL.md",
12
+ ".agents/skills/codex-model-routing/agents/openai.yaml",
13
+ ".agents/skills/epic-orchestrate/SKILL.md",
14
+ ".agents/skills/epic-plan/SKILL.md",
15
+ ".agents/skills/epic-run/SKILL.md",
11
16
  ".agents/skills/evidence-and-timestamp-conventions/SKILL.md",
12
17
  ".agents/skills/orchestrate/SKILL.md",
13
18
  ".agents/skills/orchestrator-workflow/SKILL.md",
@@ -17,8 +22,68 @@
17
22
  ".codex/config.toml",
18
23
  ".codex/agents/atomic-executor.toml",
19
24
  ".codex/agents/atomic-planner.toml",
25
+ ".codex/agents/epic-orchestrator.toml",
26
+ ".codex/agents/epic-planner.toml",
20
27
  ".codex/agents/orchestrator.toml",
28
+ ".codex/hooks/authorize-root-epic-invocation.ps1",
29
+ ".codex/hooks/codex-agent-profile-attestation.ps1",
30
+ ".codex/hooks/codex-authority-store.ps1",
31
+ ".codex/hooks/codex-epic-child-launch-attestation.ps1",
32
+ ".codex/hooks/enforce-codex-model-routing.ps1",
33
+ ".codex/hooks/enforce-epic-child-worktree-binding.ps1",
34
+ ".codex/hooks/enforce-epic-merge-gate.ps1",
35
+ ".codex/hooks/enforce-epic-planning-only.ps1",
36
+ ".codex/hooks/enforce-epic-root-invocation.ps1",
37
+ ".codex/hooks/enforce-epic-wave-barrier.ps1",
38
+ ".codex/hooks/enforce-epic-worktree-removal-gate.ps1",
39
+ ".codex/hooks/record-subagent-routing-attestation.ps1",
40
+ ".codex/hooks/validate-codex-subagent-routing.ps1",
41
+ ".codex/scripts/epic-child-launch-contract.ps1",
42
+ ".codex/scripts/epic-child-launch-runtime.ps1",
43
+ ".codex/scripts/epic-child-persistence-runtime.ps1",
44
+ ".codex/scripts/epic-child-sandbox-preflight.ps1",
45
+ ".codex/scripts/launch-epic-child-wave.ps1",
46
+ ".codex/scripts/resume-epic-child.ps1",
21
47
  ".codex/prompts/generate-pr.md",
22
- ".codex/prompts/orchestrate-work.md"
48
+ ".codex/prompts/orchestrate-work.md",
49
+ ".codex/agents/feature-reviewer.toml",
50
+ ".codex/agents/task-researcher.toml",
51
+ ".codex/agents/prd-feature.toml",
52
+ ".codex/agents/pr-author.toml",
53
+ ".codex/agents/orchestrator-c1.toml",
54
+ ".codex/agents/orchestrator-c2.toml",
55
+ ".codex/agents/orchestrator-c3.toml",
56
+ ".codex/agents/orchestrator-c3-elevated.toml",
57
+ ".codex/agents/orchestrator-c4.toml",
58
+ ".codex/agents/atomic-planner-c1.toml",
59
+ ".codex/agents/atomic-planner-c2.toml",
60
+ ".codex/agents/atomic-planner-c3.toml",
61
+ ".codex/agents/atomic-planner-c3-elevated.toml",
62
+ ".codex/agents/atomic-planner-c4.toml",
63
+ ".codex/agents/atomic-executor-c1.toml",
64
+ ".codex/agents/atomic-executor-c2.toml",
65
+ ".codex/agents/atomic-executor-c3.toml",
66
+ ".codex/agents/atomic-executor-c3-elevated.toml",
67
+ ".codex/agents/atomic-executor-c4.toml",
68
+ ".codex/agents/feature-reviewer-c1.toml",
69
+ ".codex/agents/feature-reviewer-c2.toml",
70
+ ".codex/agents/feature-reviewer-c3.toml",
71
+ ".codex/agents/feature-reviewer-c3-elevated.toml",
72
+ ".codex/agents/feature-reviewer-c4.toml",
73
+ ".codex/agents/task-researcher-c1.toml",
74
+ ".codex/agents/task-researcher-c2.toml",
75
+ ".codex/agents/task-researcher-c3.toml",
76
+ ".codex/agents/task-researcher-c3-elevated.toml",
77
+ ".codex/agents/task-researcher-c4.toml",
78
+ ".codex/agents/prd-feature-c1.toml",
79
+ ".codex/agents/prd-feature-c2.toml",
80
+ ".codex/agents/prd-feature-c3.toml",
81
+ ".codex/agents/prd-feature-c3-elevated.toml",
82
+ ".codex/agents/prd-feature-c4.toml",
83
+ ".codex/agents/pr-author-c1.toml",
84
+ ".codex/agents/pr-author-c2.toml",
85
+ ".codex/agents/pr-author-c3.toml",
86
+ ".codex/agents/pr-author-c3-elevated.toml",
87
+ ".codex/agents/pr-author-c4.toml"
23
88
  ]
24
89
  }
@@ -6,6 +6,11 @@
6
6
  ".agents/skills/csharp/SKILL.md",
7
7
  ".agents/skills/csharp-qa-gate/SKILL.md",
8
8
  ".agents/skills/invoke-csharp-engineer/SKILL.md",
9
- ".codex/agents/csharp-typed-engineer.toml"
9
+ ".codex/agents/csharp-typed-engineer.toml",
10
+ ".codex/agents/csharp-typed-engineer-c1.toml",
11
+ ".codex/agents/csharp-typed-engineer-c2.toml",
12
+ ".codex/agents/csharp-typed-engineer-c3.toml",
13
+ ".codex/agents/csharp-typed-engineer-c3-elevated.toml",
14
+ ".codex/agents/csharp-typed-engineer-c4.toml"
10
15
  ]
11
16
  }
@@ -5,6 +5,11 @@
5
5
  ".agents/skills/csharp/SKILL.md",
6
6
  ".agents/skills/csharp-qa-gate/SKILL.md",
7
7
  ".agents/skills/invoke-csharp-engineer/SKILL.md",
8
- ".codex/agents/csharp-typed-engineer.toml"
8
+ ".codex/agents/csharp-typed-engineer.toml",
9
+ ".codex/agents/csharp-typed-engineer-c1.toml",
10
+ ".codex/agents/csharp-typed-engineer-c2.toml",
11
+ ".codex/agents/csharp-typed-engineer-c3.toml",
12
+ ".codex/agents/csharp-typed-engineer-c3-elevated.toml",
13
+ ".codex/agents/csharp-typed-engineer-c4.toml"
9
14
  ]
10
15
  }
@@ -10,6 +10,11 @@
10
10
  ".codex/agents/powershell-typed-engineer.toml",
11
11
  ".codex/agents/powershell-orchestrator.toml",
12
12
  ".codex/agents/powershell-atomic-executor.toml",
13
- ".codex/agents/powershell-atomic-planning.toml"
13
+ ".codex/agents/powershell-atomic-planning.toml",
14
+ ".codex/agents/powershell-typed-engineer-c1.toml",
15
+ ".codex/agents/powershell-typed-engineer-c2.toml",
16
+ ".codex/agents/powershell-typed-engineer-c3.toml",
17
+ ".codex/agents/powershell-typed-engineer-c3-elevated.toml",
18
+ ".codex/agents/powershell-typed-engineer-c4.toml"
14
19
  ]
15
20
  }