codeforge-dev 1.4.0

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/.devcontainer/.env +22 -0
  2. package/.devcontainer/CHANGELOG.md +197 -0
  3. package/.devcontainer/CLAUDE.md +117 -0
  4. package/.devcontainer/README.md +222 -0
  5. package/.devcontainer/config/main-system-prompt.md +502 -0
  6. package/.devcontainer/config/settings.json +47 -0
  7. package/.devcontainer/devcontainer.json +94 -0
  8. package/.devcontainer/features/README.md +113 -0
  9. package/.devcontainer/features/agent-browser/README.md +65 -0
  10. package/.devcontainer/features/agent-browser/devcontainer-feature.json +23 -0
  11. package/.devcontainer/features/agent-browser/install.sh +79 -0
  12. package/.devcontainer/features/ast-grep/README.md +24 -0
  13. package/.devcontainer/features/ast-grep/devcontainer-feature.json +24 -0
  14. package/.devcontainer/features/ast-grep/install.sh +51 -0
  15. package/.devcontainer/features/ccstatusline/README.md +296 -0
  16. package/.devcontainer/features/ccstatusline/devcontainer-feature.json +19 -0
  17. package/.devcontainer/features/ccstatusline/install.sh +290 -0
  18. package/.devcontainer/features/ccusage/README.md +205 -0
  19. package/.devcontainer/features/ccusage/devcontainer-feature.json +38 -0
  20. package/.devcontainer/features/ccusage/install.sh +132 -0
  21. package/.devcontainer/features/claude-code/README.md +498 -0
  22. package/.devcontainer/features/claude-code/config/settings.json +36 -0
  23. package/.devcontainer/features/claude-code/config/system-prompt.md +118 -0
  24. package/.devcontainer/features/claude-code/config/world-building-sp.md +1432 -0
  25. package/.devcontainer/features/claude-code/devcontainer-feature.json +42 -0
  26. package/.devcontainer/features/claude-code/install.sh +466 -0
  27. package/.devcontainer/features/claude-monitor/README.md +74 -0
  28. package/.devcontainer/features/claude-monitor/devcontainer-feature.json +38 -0
  29. package/.devcontainer/features/claude-monitor/install.sh +99 -0
  30. package/.devcontainer/features/lsp-servers/README.md +85 -0
  31. package/.devcontainer/features/lsp-servers/devcontainer-feature.json +40 -0
  32. package/.devcontainer/features/lsp-servers/install.sh +116 -0
  33. package/.devcontainer/features/mcp-qdrant/CHANGES.md +399 -0
  34. package/.devcontainer/features/mcp-qdrant/README.md +474 -0
  35. package/.devcontainer/features/mcp-qdrant/devcontainer-feature.json +57 -0
  36. package/.devcontainer/features/mcp-qdrant/install.sh +295 -0
  37. package/.devcontainer/features/mcp-qdrant/poststart-hook.sh +129 -0
  38. package/.devcontainer/features/mcp-reasoner/README.md +177 -0
  39. package/.devcontainer/features/mcp-reasoner/devcontainer-feature.json +20 -0
  40. package/.devcontainer/features/mcp-reasoner/install.sh +177 -0
  41. package/.devcontainer/features/mcp-reasoner/poststart-hook.sh +67 -0
  42. package/.devcontainer/features/notify-hook/README.md +86 -0
  43. package/.devcontainer/features/notify-hook/devcontainer-feature.json +23 -0
  44. package/.devcontainer/features/notify-hook/install.sh +38 -0
  45. package/.devcontainer/features/splitrail/README.md +140 -0
  46. package/.devcontainer/features/splitrail/devcontainer-feature.json +34 -0
  47. package/.devcontainer/features/splitrail/install.sh +129 -0
  48. package/.devcontainer/features/tree-sitter/README.md +138 -0
  49. package/.devcontainer/features/tree-sitter/devcontainer-feature.json +52 -0
  50. package/.devcontainer/features/tree-sitter/install.sh +173 -0
  51. package/.devcontainer/plugins/devs-marketplace/.claude-plugin/marketplace.json +106 -0
  52. package/.devcontainer/plugins/devs-marketplace/plugins/auto-formatter/.claude-plugin/plugin.json +7 -0
  53. package/.devcontainer/plugins/devs-marketplace/plugins/auto-formatter/hooks/hooks.json +17 -0
  54. package/.devcontainer/plugins/devs-marketplace/plugins/auto-formatter/scripts/format-file.py +101 -0
  55. package/.devcontainer/plugins/devs-marketplace/plugins/auto-linter/.claude-plugin/plugin.json +7 -0
  56. package/.devcontainer/plugins/devs-marketplace/plugins/auto-linter/hooks/hooks.json +17 -0
  57. package/.devcontainer/plugins/devs-marketplace/plugins/auto-linter/scripts/lint-file.py +137 -0
  58. package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/.claude-plugin/plugin.json +8 -0
  59. package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/claude-code-headless/SKILL.md +387 -0
  60. package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/claude-code-headless/references/cli-flags-and-output.md +312 -0
  61. package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/claude-code-headless/references/sdk-and-mcp.md +569 -0
  62. package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/docker/SKILL.md +309 -0
  63. package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/docker/references/compose-services.md +438 -0
  64. package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/docker/references/dockerfile-patterns.md +340 -0
  65. package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/docker-py/SKILL.md +412 -0
  66. package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/docker-py/references/container-lifecycle.md +388 -0
  67. package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/docker-py/references/resources-and-security.md +444 -0
  68. package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/fastapi/SKILL.md +344 -0
  69. package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/fastapi/references/middleware-and-lifespan.md +254 -0
  70. package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/fastapi/references/pydantic-models.md +245 -0
  71. package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/fastapi/references/routing-and-dependencies.md +255 -0
  72. package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/fastapi/references/sse-and-streaming.md +318 -0
  73. package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/pydantic-ai/SKILL.md +345 -0
  74. package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/pydantic-ai/references/agents-and-tools.md +271 -0
  75. package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/pydantic-ai/references/models-and-streaming.md +422 -0
  76. package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/skill-building/SKILL.md +220 -0
  77. package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/skill-building/references/cross-vendor-principles.md +139 -0
  78. package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/skill-building/references/patterns-and-antipatterns.md +376 -0
  79. package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/skill-building/references/skill-authoring-patterns.md +356 -0
  80. package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/sqlite/SKILL.md +329 -0
  81. package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/sqlite/references/advanced-queries.md +314 -0
  82. package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/sqlite/references/javascript-patterns.md +323 -0
  83. package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/sqlite/references/python-patterns.md +354 -0
  84. package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/sqlite/references/schema-and-pragmas.md +326 -0
  85. package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/svelte5/SKILL.md +356 -0
  86. package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/svelte5/references/ai-sdk-svelte.md +128 -0
  87. package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/svelte5/references/component-patterns.md +332 -0
  88. package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/svelte5/references/layercake.md +203 -0
  89. package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/svelte5/references/migration-guide.md +350 -0
  90. package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/svelte5/references/runes-and-reactivity.md +328 -0
  91. package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/svelte5/references/spa-and-routing.md +262 -0
  92. package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/svelte5/references/svelte-dnd-action.md +181 -0
  93. package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/testing/SKILL.md +414 -0
  94. package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/testing/references/fastapi-testing.md +411 -0
  95. package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/testing/references/svelte-testing.md +538 -0
  96. package/.devcontainer/plugins/devs-marketplace/plugins/codeforge-lsp/.claude-plugin/plugin.json +7 -0
  97. package/.devcontainer/plugins/devs-marketplace/plugins/dangerous-command-blocker/.claude-plugin/plugin.json +7 -0
  98. package/.devcontainer/plugins/devs-marketplace/plugins/dangerous-command-blocker/hooks/hooks.json +17 -0
  99. package/.devcontainer/plugins/devs-marketplace/plugins/dangerous-command-blocker/scripts/block-dangerous.py +110 -0
  100. package/.devcontainer/plugins/devs-marketplace/plugins/notify-hook/.claude-plugin/plugin.json +7 -0
  101. package/.devcontainer/plugins/devs-marketplace/plugins/notify-hook/hooks/hooks.json +17 -0
  102. package/.devcontainer/plugins/devs-marketplace/plugins/planning-reminder/.claude-plugin/plugin.json +7 -0
  103. package/.devcontainer/plugins/devs-marketplace/plugins/planning-reminder/hooks/hooks.json +17 -0
  104. package/.devcontainer/plugins/devs-marketplace/plugins/protected-files-guard/.claude-plugin/plugin.json +7 -0
  105. package/.devcontainer/plugins/devs-marketplace/plugins/protected-files-guard/hooks/hooks.json +17 -0
  106. package/.devcontainer/plugins/devs-marketplace/plugins/protected-files-guard/scripts/guard-protected.py +108 -0
  107. package/.devcontainer/plugins/devs-marketplace/plugins/ticket-workflow/.claude-plugin/commands/ticket/357/200/272create-pr.md +337 -0
  108. package/.devcontainer/plugins/devs-marketplace/plugins/ticket-workflow/.claude-plugin/commands/ticket/357/200/272new.md +166 -0
  109. package/.devcontainer/plugins/devs-marketplace/plugins/ticket-workflow/.claude-plugin/commands/ticket/357/200/272review-commit.md +290 -0
  110. package/.devcontainer/plugins/devs-marketplace/plugins/ticket-workflow/.claude-plugin/commands/ticket/357/200/272work.md +257 -0
  111. package/.devcontainer/plugins/devs-marketplace/plugins/ticket-workflow/.claude-plugin/plugin.json +8 -0
  112. package/.devcontainer/plugins/devs-marketplace/plugins/ticket-workflow/.claude-plugin/system-prompt.md +184 -0
  113. package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/.claude-plugin/plugin.json +6 -0
  114. package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/config/planning-instructions.md +14 -0
  115. package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/functional-conjuring-map.md +989 -0
  116. package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/hooks/hooks.json +33 -0
  117. package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/scripts/__pycache__/post-enhance-task.cpython-314.pyc +0 -0
  118. package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/scripts/enhance-planning.py +71 -0
  119. package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/scripts/enhancers/enhance-plan.sh +68 -0
  120. package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/scripts/enhancers/enhance-task.sh +120 -0
  121. package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/scripts/post-enhance-plan.py +133 -0
  122. package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/scripts/post-enhance-task.py +253 -0
  123. package/.devcontainer/scripts/setup-aliases.sh +80 -0
  124. package/.devcontainer/scripts/setup-config.sh +28 -0
  125. package/.devcontainer/scripts/setup-irie-claude.sh +32 -0
  126. package/.devcontainer/scripts/setup-plugins.sh +80 -0
  127. package/.devcontainer/scripts/setup.sh +58 -0
  128. package/LICENSE.txt +674 -0
  129. package/README.md +267 -0
  130. package/package.json +44 -0
  131. package/setup.js +83 -0
@@ -0,0 +1,989 @@
1
+ # Plan: Advanced Plan & Task Validation System
2
+
3
+ ## Problem Statement
4
+
5
+ The workflow-enhancer plugin currently provides basic plan and task enhancement hooks, but lacks intelligent validation. Plans can be approved without verifying they address user requirements, contain unmarked assumptions, or have adequate risk mitigation. Tasks can be created without verifying coverage against the approved plan.
6
+
7
+ This creates risk of:
8
+ - Requirements silently dropped or misunderstood
9
+ - Assumptions made without explicit approval
10
+ - High-risk changes without mitigation strategies
11
+ - Tasks that don't cover the full plan scope
12
+
13
+ ## Scope Definition
14
+
15
+ ### In Scope
16
+ - Marker enforcement system (`[ASSUMPTION]`, `[DEFERRED]`, `[APPROVED]`)
17
+ - Bash-based syntactic validation (fast gate)
18
+ - Opus-based semantic analysis (reasoning over plan + transcript + tasks)
19
+ - Sonnet-based verification (file access for grounding claims)
20
+ - Task coverage matrix generation
21
+ - Risk escalation detection and mitigation verification
22
+
23
+ ### Out of Scope
24
+ - Historical pattern matching [DEFERRED] [APPROVED]
25
+ - Dependency graph visualization [DEFERRED] [APPROVED]
26
+ - Context window monitoring [DEFERRED] [APPROVED]
27
+ - Real-time collaboration hooks [DEFERRED] [APPROVED]
28
+ - External CI/CD integration [DEFERRED] [APPROVED]
29
+
30
+ ### Assumptions
31
+ - Claude CLI supports headless mode with model selection [ASSUMPTION]
32
+ - Transcript JSONL format is stable and parseable [ASSUMPTION]
33
+ - Token costs for Opus/Sonnet calls are acceptable (~$0.05-0.08 per plan) [ASSUMPTION]
34
+
35
+ ## Current State
36
+
37
+ ```
38
+ PreToolUse (EnterPlanMode)
39
+ └── enhance-planning.py
40
+ └── Injects planning-instructions.md content (basic template)
41
+
42
+ PostToolUse (Write to /plans/)
43
+ └── post-enhance-plan.py
44
+ └── Detects plan files
45
+ └── Runs enhance-plan.sh (placeholder, no real validation)
46
+ └── Returns additionalContext
47
+
48
+ PostToolUse (TaskCreate|TaskUpdate)
49
+ └── post-enhance-task.py
50
+ └── Finds task file
51
+ └── Finds session plan (correlation implemented)
52
+ └── Runs enhance-task.sh (placeholder)
53
+ └── Returns additionalContext
54
+ ```
55
+
56
+ ## Desired State
57
+
58
+ ```
59
+ PreToolUse (EnterPlanMode)
60
+ └── enhance-planning.py
61
+ └── Injects comprehensive planning-instructions.md:
62
+ ├── Required section template
63
+ ├── Marker syntax requirements
64
+ ├── Assumption/deferral rules
65
+ └── Risk documentation requirements
66
+
67
+ PostToolUse (Write to /plans/)
68
+ └── post-enhance-plan.py (orchestrator)
69
+
70
+ ├── LAYER 1: Bash Validators (fast gate)
71
+ │ ├── section_validator.sh → Required sections present
72
+ │ ├── marker_validator.sh → [ASSUMPTION], [DEFERRED], [APPROVED] syntax
73
+ │ ├── assumption_detector.sh → Unmarked assumption language
74
+ │ └── risk_detector.sh → High-risk keywords, mitigation check
75
+
76
+ ├── LAYER 2: Opus Analyzer (reasoning, 1-2 turns)
77
+ │ └── opus_analyzer.py
78
+ │ ├── Input: plan + transcript + tasks
79
+ │ ├── Requirement traceability analysis
80
+ │ ├── Assumption audit
81
+ │ ├── Gap/ambiguity detection
82
+ │ ├── Task coverage matrix
83
+ │ └── Risk assessment
84
+
85
+ └── LAYER 3: Sonnet Verifier (conditional, file access)
86
+ └── sonnet_verifier.py
87
+ ├── Triggered by: Opus concerns OR high-risk flags
88
+ ├── File path verification
89
+ ├── Pattern alignment check
90
+ ├── Conflict detection
91
+ └── Security spot-check
92
+
93
+ PostToolUse (TaskCreate|TaskUpdate)
94
+ └── post-enhance-task.py
95
+ └── [Existing functionality]
96
+ └── Coverage data passed to Opus in plan validation
97
+ ```
98
+
99
+ ## Technical Approach
100
+
101
+ ### Phase 1: Planning Instructions Enhancement
102
+
103
+ **Files:**
104
+ - `config/planning-instructions.md` - complete rewrite
105
+
106
+ **Content to inject:**
107
+
108
+ ```markdown
109
+ ## Required Plan Sections
110
+
111
+ Your plan MUST include these sections:
112
+
113
+ 1. **Problem Statement** - What problem and why it matters
114
+ 2. **Scope Definition** - In scope, out of scope, assumptions
115
+ 3. **Current vs Desired State** - Before and after
116
+ 4. **Technical Approach** - Phases with files and steps
117
+ 5. **Verification Checklist** - How to confirm completion
118
+ 6. **Risks and Mitigations** - What could go wrong
119
+
120
+ ## Required Markers
121
+
122
+ ### Assumptions
123
+ Any assumption MUST be marked: `[ASSUMPTION]`
124
+ Approved assumptions: `[ASSUMPTION] [APPROVED]`
125
+
126
+ Example:
127
+ - Database supports JSON columns [ASSUMPTION] [APPROVED]
128
+
129
+ ### Deferrals
130
+ Anything deferred MUST be marked: `[DEFERRED]`
131
+ Approved deferrals: `[DEFERRED] [APPROVED]`
132
+
133
+ Example:
134
+ - Admin panel [DEFERRED] [APPROVED] - Phase 2 work
135
+
136
+ ### Unapproved markers will be flagged
137
+ The plan validator will reject plans with:
138
+ - `[ASSUMPTION]` without `[APPROVED]`
139
+ - `[DEFERRED]` without `[APPROVED]`
140
+ - Assumption-like language without `[ASSUMPTION]` marker
141
+
142
+ ## Risk Documentation
143
+
144
+ High-risk patterns MUST have explicit mitigation:
145
+ - Data deletion/modification → Backup strategy
146
+ - Production changes → Rollback plan
147
+ - Auth/security changes → Security review notes
148
+ - Schema migrations → Migration rollback steps
149
+ ```
150
+
151
+ **Verification:**
152
+ - Enter plan mode, verify instructions appear in context
153
+ - Create plan without markers, verify they're requested
154
+
155
+ ---
156
+
157
+ ### Phase 2: Bash Validators
158
+
159
+ **Files to create:**
160
+ - `scripts/lib/section_validator.sh`
161
+ - `scripts/lib/marker_validator.sh`
162
+ - `scripts/lib/assumption_detector.sh`
163
+ - `scripts/lib/risk_detector.sh`
164
+
165
+ #### section_validator.sh
166
+
167
+ ```bash
168
+ #!/bin/bash
169
+ # Validates required sections exist in plan
170
+ # Exit 0 = pass, Exit 1 = fail with errors on stderr
171
+
172
+ PLAN_FILE="$1"
173
+ errors=0
174
+
175
+ required_sections=(
176
+ "## Problem Statement"
177
+ "## Scope Definition"
178
+ "## Current.*State|## Current State"
179
+ "## Desired.*State|## Desired State"
180
+ "## Verification"
181
+ "## Risks"
182
+ )
183
+
184
+ for pattern in "${required_sections[@]}"; do
185
+ if ! grep -qE "$pattern" "$PLAN_FILE"; then
186
+ echo "MISSING SECTION: $pattern" >&2
187
+ ((errors++))
188
+ fi
189
+ done
190
+
191
+ exit $((errors > 0 ? 1 : 0))
192
+ ```
193
+
194
+ #### marker_validator.sh
195
+
196
+ ```bash
197
+ #!/bin/bash
198
+ # Validates marker syntax and approval status
199
+ # Exit 0 = pass, Exit 1 = warnings, Exit 2 = errors
200
+
201
+ PLAN_FILE="$1"
202
+ errors=0
203
+ warnings=0
204
+
205
+ # Find deferrals without approval
206
+ unapproved_deferrals=$(grep -n '\[DEFERRED\]' "$PLAN_FILE" | grep -v '\[APPROVED\]')
207
+ if [[ -n "$unapproved_deferrals" ]]; then
208
+ echo "UNAPPROVED DEFERRAL:" >&2
209
+ echo "$unapproved_deferrals" >&2
210
+ ((errors++))
211
+ fi
212
+
213
+ # Find assumptions without approval
214
+ unapproved_assumptions=$(grep -n '\[ASSUMPTION\]' "$PLAN_FILE" | grep -v '\[APPROVED\]')
215
+ if [[ -n "$unapproved_assumptions" ]]; then
216
+ echo "UNAPPROVED ASSUMPTION:" >&2
217
+ echo "$unapproved_assumptions" >&2
218
+ ((errors++))
219
+ fi
220
+
221
+ # Check for TBD/placeholder items
222
+ tbd_items=$(grep -n -iE '\bTBD\b|\bTODO\b|\bPLACEHOLDER\b' "$PLAN_FILE")
223
+ if [[ -n "$tbd_items" ]]; then
224
+ echo "UNRESOLVED ITEMS:" >&2
225
+ echo "$tbd_items" >&2
226
+ ((errors++))
227
+ fi
228
+
229
+ if [[ $errors -gt 0 ]]; then
230
+ exit 2
231
+ elif [[ $warnings -gt 0 ]]; then
232
+ exit 1
233
+ else
234
+ exit 0
235
+ fi
236
+ ```
237
+
238
+ #### assumption_detector.sh
239
+
240
+ ```bash
241
+ #!/bin/bash
242
+ # Detects assumption-like language without [ASSUMPTION] marker
243
+
244
+ PLAN_FILE="$1"
245
+ warnings=0
246
+
247
+ assumption_patterns=(
248
+ "assum[ei]"
249
+ "expect that"
250
+ "should be able"
251
+ "probably"
252
+ "likely"
253
+ "I believe"
254
+ "presumably"
255
+ "should work"
256
+ "will likely"
257
+ )
258
+
259
+ for pattern in "${assumption_patterns[@]}"; do
260
+ matches=$(grep -in "$pattern" "$PLAN_FILE" | grep -v '\[ASSUMPTION\]')
261
+ if [[ -n "$matches" ]]; then
262
+ echo "UNMARKED ASSUMPTION LANGUAGE:" >&2
263
+ echo "$matches" >&2
264
+ ((warnings++))
265
+ fi
266
+ done
267
+
268
+ exit $((warnings > 0 ? 1 : 0))
269
+ ```
270
+
271
+ #### risk_detector.sh
272
+
273
+ ```bash
274
+ #!/bin/bash
275
+ # Detects high-risk patterns and checks for mitigation
276
+
277
+ PLAN_FILE="$1"
278
+ warnings=0
279
+
280
+ declare -A risk_patterns=(
281
+ ["DELETE|DROP|TRUNCATE|rm -rf|remove.*all"]="CRITICAL:destructive-operation"
282
+ ["production|prod environment|live server"]="HIGH:production-impact"
283
+ ["migration|schema change|ALTER TABLE|database change"]="HIGH:data-migration"
284
+ ["auth|password|token|secret|credential|API.key"]="HIGH:security-sensitive"
285
+ ["\.env|environment variable|config secret"]="HIGH:secrets-handling"
286
+ )
287
+
288
+ for pattern in "${!risk_patterns[@]}"; do
289
+ severity="${risk_patterns[$pattern]%:*}"
290
+ category="${risk_patterns[$pattern]#*:}"
291
+
292
+ if grep -qiE "$pattern" "$PLAN_FILE"; then
293
+ echo "RISK DETECTED [$severity]: $category" >&2
294
+
295
+ # Check for mitigation
296
+ if ! grep -qiE "mitigat|rollback|backup|revert|recover" "$PLAN_FILE"; then
297
+ echo " WARNING: No mitigation strategy found for $category" >&2
298
+ ((warnings++))
299
+ fi
300
+ fi
301
+ done
302
+
303
+ exit $((warnings > 0 ? 1 : 0))
304
+ ```
305
+
306
+ **Verification:**
307
+ - Run each validator against sample plans
308
+ - Verify correct exit codes and error messages
309
+
310
+ ---
311
+
312
+ ### Phase 3: Transcript Parser
313
+
314
+ **File to create:**
315
+ - `scripts/lib/transcript_parser.py`
316
+
317
+ ```python
318
+ #!/usr/bin/env python3
319
+ """Extract user messages from session transcript for analysis."""
320
+
321
+ import json
322
+ import sys
323
+ from pathlib import Path
324
+
325
+
326
+ def extract_user_messages(transcript_path: str, max_chars: int = 4000) -> str:
327
+ """
328
+ Extract user messages from JSONL transcript.
329
+
330
+ Args:
331
+ transcript_path: Path to session JSONL file
332
+ max_chars: Maximum characters to return (truncate from end)
333
+
334
+ Returns:
335
+ Concatenated user messages, most recent last
336
+ """
337
+ messages = []
338
+
339
+ try:
340
+ with open(transcript_path) as f:
341
+ for line in f:
342
+ try:
343
+ entry = json.loads(line)
344
+ if entry.get("type") == "user":
345
+ msg = entry.get("message", "")
346
+ if msg:
347
+ messages.append(msg)
348
+ except json.JSONDecodeError:
349
+ continue
350
+ except (OSError, IOError) as e:
351
+ print(f"Error reading transcript: {e}", file=sys.stderr)
352
+ return ""
353
+
354
+ combined = "\n---\n".join(messages)
355
+
356
+ # Truncate from beginning if too long (keep recent messages)
357
+ if len(combined) > max_chars:
358
+ combined = "...[truncated]...\n" + combined[-max_chars:]
359
+
360
+ return combined
361
+
362
+
363
+ def extract_requirements(transcript_path: str) -> list[str]:
364
+ """
365
+ Extract likely requirements from user messages.
366
+
367
+ Heuristic: Lines that look like requirements (imperative, bullet points, etc.)
368
+ """
369
+ messages = extract_user_messages(transcript_path, max_chars=10000)
370
+ requirements = []
371
+
372
+ for line in messages.split("\n"):
373
+ line = line.strip()
374
+ # Heuristic patterns for requirements
375
+ if any([
376
+ line.startswith("- "),
377
+ line.startswith("* "),
378
+ line.startswith("1.") or line.startswith("2."),
379
+ "should" in line.lower(),
380
+ "must" in line.lower(),
381
+ "need" in line.lower(),
382
+ "want" in line.lower(),
383
+ ]):
384
+ requirements.append(line)
385
+
386
+ return requirements
387
+
388
+
389
+ if __name__ == "__main__":
390
+ if len(sys.argv) < 2:
391
+ print("Usage: transcript_parser.py <transcript_path>", file=sys.stderr)
392
+ sys.exit(1)
393
+
394
+ print(extract_user_messages(sys.argv[1]))
395
+ ```
396
+
397
+ **Verification:**
398
+ - Run against actual session transcript
399
+ - Verify user messages extracted correctly
400
+
401
+ ---
402
+
403
+ ### Phase 4: Opus Analyzer
404
+
405
+ **File to create:**
406
+ - `scripts/lib/opus_analyzer.py`
407
+
408
+ ```python
409
+ #!/usr/bin/env python3
410
+ """
411
+ Opus-based semantic analysis of implementation plans.
412
+
413
+ Analyzes plan against transcript and tasks for:
414
+ - Requirement coverage
415
+ - Assumption audit
416
+ - Gap detection
417
+ - Task coverage matrix
418
+ - Risk assessment
419
+ """
420
+
421
+ import json
422
+ import subprocess
423
+ import sys
424
+ from pathlib import Path
425
+ from dataclasses import dataclass
426
+
427
+
428
+ @dataclass
429
+ class AnalysisResult:
430
+ requirements: list[dict] # {req, status, location}
431
+ assumptions: list[dict] # {text, marked, approved}
432
+ gaps: list[str]
433
+ ambiguities: list[str]
434
+ task_coverage: dict # {plan_item: task_or_uncovered}
435
+ risks: list[dict] # {risk, severity, mitigation}
436
+ raw_response: str
437
+
438
+
439
+ OPUS_PROMPT = '''You are an implementation plan auditor. Analyze the provided data and report findings.
440
+
441
+ ## INPUT DATA
442
+
443
+ ### User's Original Messages (from session transcript):
444
+ """
445
+ {user_messages}
446
+ """
447
+
448
+ ### The Implementation Plan:
449
+ """
450
+ {plan_content}
451
+ """
452
+
453
+ ### Current Task List (if any):
454
+ """
455
+ {task_json}
456
+ """
457
+
458
+ ## ANALYSIS REQUIRED
459
+
460
+ Respond in this exact format:
461
+
462
+ ### REQUIREMENTS
463
+ For each user requirement identified:
464
+ REQ: [requirement text]
465
+ STATUS: ADDRESSED | PARTIAL | MISSING
466
+ LOCATION: [section in plan, or "not found"]
467
+
468
+ ### ASSUMPTIONS
469
+ For each assumption (explicit or implicit):
470
+ ASSUMPTION: [text]
471
+ MARKED: YES | NO
472
+ APPROVED: YES | NO
473
+
474
+ ### GAPS
475
+ GAP: [what's missing or could fail]
476
+
477
+ ### AMBIGUITIES
478
+ AMBIGUITY: [what's unclear or has multiple interpretations]
479
+
480
+ ### TASK_COVERAGE
481
+ PLAN_ITEM: [phase/step from plan]
482
+ COVERED_BY: [task subject] | UNCOVERED
483
+
484
+ COVERAGE_SCORE: X/Y
485
+
486
+ ### RISKS
487
+ RISK: [pattern or concern]
488
+ SEVERITY: CRITICAL | HIGH | MEDIUM
489
+ MITIGATION: PRESENT | MISSING
490
+
491
+ ## RULES
492
+ - Be terse. No explanations unless critical.
493
+ - Flag only issues, not successes (except for REQUIREMENTS status).
494
+ - If task list is empty, skip TASK_COVERAGE section.
495
+ '''
496
+
497
+
498
+ def run_opus_analysis(
499
+ plan_content: str,
500
+ user_messages: str,
501
+ task_json: str = "[]",
502
+ timeout: int = 60
503
+ ) -> AnalysisResult:
504
+ """
505
+ Run Opus analysis on plan.
506
+
507
+ Args:
508
+ plan_content: The implementation plan markdown
509
+ user_messages: Extracted user messages from transcript
510
+ task_json: JSON string of current tasks
511
+ timeout: Max seconds to wait for response
512
+
513
+ Returns:
514
+ AnalysisResult with parsed findings
515
+ """
516
+ prompt = OPUS_PROMPT.format(
517
+ user_messages=user_messages,
518
+ plan_content=plan_content,
519
+ task_json=task_json
520
+ )
521
+
522
+ try:
523
+ # Call Claude CLI in headless mode
524
+ result = subprocess.run(
525
+ ["claude", "--print", "--model", "opus", "-p", prompt],
526
+ capture_output=True,
527
+ text=True,
528
+ timeout=timeout
529
+ )
530
+
531
+ if result.returncode != 0:
532
+ raise RuntimeError(f"Claude CLI error: {result.stderr}")
533
+
534
+ response = result.stdout.strip()
535
+ return parse_opus_response(response)
536
+
537
+ except subprocess.TimeoutExpired:
538
+ raise RuntimeError("Opus analysis timed out")
539
+ except FileNotFoundError:
540
+ raise RuntimeError("Claude CLI not found")
541
+
542
+
543
+ def parse_opus_response(response: str) -> AnalysisResult:
544
+ """Parse structured Opus response into AnalysisResult."""
545
+
546
+ # Initialize result containers
547
+ requirements = []
548
+ assumptions = []
549
+ gaps = []
550
+ ambiguities = []
551
+ task_coverage = {}
552
+ risks = []
553
+
554
+ current_section = None
555
+ current_item = {}
556
+
557
+ for line in response.split("\n"):
558
+ line = line.strip()
559
+
560
+ # Section headers
561
+ if line.startswith("### "):
562
+ current_section = line[4:].upper()
563
+ continue
564
+
565
+ # Parse based on current section
566
+ if current_section == "REQUIREMENTS":
567
+ if line.startswith("REQ:"):
568
+ if current_item:
569
+ requirements.append(current_item)
570
+ current_item = {"req": line[4:].strip()}
571
+ elif line.startswith("STATUS:"):
572
+ current_item["status"] = line[7:].strip()
573
+ elif line.startswith("LOCATION:"):
574
+ current_item["location"] = line[9:].strip()
575
+ requirements.append(current_item)
576
+ current_item = {}
577
+
578
+ elif current_section == "ASSUMPTIONS":
579
+ if line.startswith("ASSUMPTION:"):
580
+ if current_item:
581
+ assumptions.append(current_item)
582
+ current_item = {"text": line[11:].strip()}
583
+ elif line.startswith("MARKED:"):
584
+ current_item["marked"] = line[7:].strip() == "YES"
585
+ elif line.startswith("APPROVED:"):
586
+ current_item["approved"] = line[9:].strip() == "YES"
587
+ assumptions.append(current_item)
588
+ current_item = {}
589
+
590
+ elif current_section == "GAPS":
591
+ if line.startswith("GAP:"):
592
+ gaps.append(line[4:].strip())
593
+
594
+ elif current_section == "AMBIGUITIES":
595
+ if line.startswith("AMBIGUITY:"):
596
+ ambiguities.append(line[10:].strip())
597
+
598
+ elif current_section == "TASK_COVERAGE":
599
+ if line.startswith("PLAN_ITEM:"):
600
+ current_item = {"plan_item": line[10:].strip()}
601
+ elif line.startswith("COVERED_BY:"):
602
+ current_item["covered_by"] = line[11:].strip()
603
+ task_coverage[current_item["plan_item"]] = current_item["covered_by"]
604
+ current_item = {}
605
+
606
+ elif current_section == "RISKS":
607
+ if line.startswith("RISK:"):
608
+ if current_item:
609
+ risks.append(current_item)
610
+ current_item = {"risk": line[5:].strip()}
611
+ elif line.startswith("SEVERITY:"):
612
+ current_item["severity"] = line[9:].strip()
613
+ elif line.startswith("MITIGATION:"):
614
+ current_item["mitigation"] = line[11:].strip()
615
+ risks.append(current_item)
616
+ current_item = {}
617
+
618
+ return AnalysisResult(
619
+ requirements=requirements,
620
+ assumptions=assumptions,
621
+ gaps=gaps,
622
+ ambiguities=ambiguities,
623
+ task_coverage=task_coverage,
624
+ risks=risks,
625
+ raw_response=response
626
+ )
627
+
628
+
629
+ def format_findings(result: AnalysisResult) -> str:
630
+ """Format analysis results for additionalContext."""
631
+
632
+ lines = ["--- Opus Plan Analysis ---"]
633
+
634
+ # Requirements
635
+ missing = [r for r in result.requirements if r.get("status") == "MISSING"]
636
+ partial = [r for r in result.requirements if r.get("status") == "PARTIAL"]
637
+ if missing:
638
+ lines.append(f"\nMISSING REQUIREMENTS ({len(missing)}):")
639
+ for r in missing:
640
+ lines.append(f" - {r['req']}")
641
+ if partial:
642
+ lines.append(f"\nPARTIAL REQUIREMENTS ({len(partial)}):")
643
+ for r in partial:
644
+ lines.append(f" - {r['req']} (at: {r.get('location', '?')})")
645
+
646
+ # Assumptions
647
+ unmarked = [a for a in result.assumptions if not a.get("marked")]
648
+ unapproved = [a for a in result.assumptions if a.get("marked") and not a.get("approved")]
649
+ if unmarked:
650
+ lines.append(f"\nUNMARKED ASSUMPTIONS ({len(unmarked)}):")
651
+ for a in unmarked:
652
+ lines.append(f" - {a['text']}")
653
+ if unapproved:
654
+ lines.append(f"\nUNAPPROVED ASSUMPTIONS ({len(unapproved)}):")
655
+ for a in unapproved:
656
+ lines.append(f" - {a['text']}")
657
+
658
+ # Gaps
659
+ if result.gaps:
660
+ lines.append(f"\nGAPS ({len(result.gaps)}):")
661
+ for g in result.gaps:
662
+ lines.append(f" - {g}")
663
+
664
+ # Ambiguities
665
+ if result.ambiguities:
666
+ lines.append(f"\nAMBIGUITIES ({len(result.ambiguities)}):")
667
+ for a in result.ambiguities:
668
+ lines.append(f" - {a}")
669
+
670
+ # Task coverage
671
+ uncovered = [k for k, v in result.task_coverage.items() if v == "UNCOVERED"]
672
+ if uncovered:
673
+ lines.append(f"\nUNCOVERED PLAN ITEMS ({len(uncovered)}):")
674
+ for item in uncovered:
675
+ lines.append(f" - {item}")
676
+
677
+ # Risks
678
+ critical = [r for r in result.risks if r.get("severity") == "CRITICAL"]
679
+ high_no_mitigation = [r for r in result.risks
680
+ if r.get("severity") == "HIGH" and r.get("mitigation") == "MISSING"]
681
+ if critical:
682
+ lines.append(f"\nCRITICAL RISKS ({len(critical)}):")
683
+ for r in critical:
684
+ lines.append(f" - {r['risk']} (mitigation: {r.get('mitigation', '?')})")
685
+ if high_no_mitigation:
686
+ lines.append(f"\nHIGH RISKS WITHOUT MITIGATION ({len(high_no_mitigation)}):")
687
+ for r in high_no_mitigation:
688
+ lines.append(f" - {r['risk']}")
689
+
690
+ lines.append("\n--- End Opus Analysis ---")
691
+
692
+ return "\n".join(lines)
693
+
694
+
695
+ if __name__ == "__main__":
696
+ # Test with sample data
697
+ print("Opus analyzer module loaded. Use run_opus_analysis() to analyze plans.")
698
+ ```
699
+
700
+ **Verification:**
701
+ - Test with sample plan, transcript, and tasks
702
+ - Verify Claude CLI invocation works
703
+ - Verify response parsing handles edge cases
704
+
705
+ ---
706
+
707
+ ### Phase 5: Sonnet Verifier
708
+
709
+ **File to create:**
710
+ - `scripts/lib/sonnet_verifier.py`
711
+
712
+ ```python
713
+ #!/usr/bin/env python3
714
+ """
715
+ Sonnet-based verification of implementation plans.
716
+
717
+ Verifies claims in the plan against actual codebase:
718
+ - File paths exist/don't exist as expected
719
+ - Proposed changes align with existing patterns
720
+ - No conflicts with existing code
721
+ - Security concerns addressed
722
+ """
723
+
724
+ import subprocess
725
+ import sys
726
+ from dataclasses import dataclass
727
+
728
+
729
+ @dataclass
730
+ class VerificationResult:
731
+ verified: list[str]
732
+ conflicts: list[str]
733
+ missing: list[str]
734
+ security: list[str]
735
+ raw_response: str
736
+
737
+
738
+ SONNET_PROMPT = '''You are verifying an implementation plan against the actual codebase.
739
+
740
+ ## Context from Opus Analysis
741
+ {opus_summary}
742
+
743
+ ## Plan Being Verified
744
+ """
745
+ {plan_content}
746
+ """
747
+
748
+ ## Your Tasks
749
+
750
+ 1. **File Verification**: For each file path mentioned in the plan:
751
+ - Use Read tool to check if it exists
752
+ - Verify described current state matches reality
753
+
754
+ 2. **Pattern Alignment**: For proposed changes:
755
+ - Read similar existing code (max 3 files)
756
+ - Confirm approach matches codebase conventions
757
+
758
+ 3. **Conflict Detection**: Check if changes would conflict with:
759
+ - Existing functionality in mentioned files
760
+
761
+ 4. **Security Spot-Check**: For any auth/data/API changes:
762
+ - Note any security concerns
763
+
764
+ ## Rules
765
+ - Maximum 5 file reads total
766
+ - Focus on CRITICAL and HIGH items from Opus analysis first
767
+ - Skip verification for low-risk items
768
+
769
+ ## Output Format (use exactly these tags)
770
+ [VERIFIED] item - checks out
771
+ [CONFLICT] item - issue description
772
+ [MISSING] item - file or pattern not found
773
+ [SECURITY] item - concern description
774
+ '''
775
+
776
+
777
+ def run_sonnet_verification(
778
+ plan_content: str,
779
+ opus_summary: str,
780
+ max_turns: int = 5,
781
+ timeout: int = 120
782
+ ) -> VerificationResult:
783
+ """
784
+ Run Sonnet verification on plan.
785
+
786
+ Args:
787
+ plan_content: The implementation plan markdown
788
+ opus_summary: Summary of Opus findings to focus verification
789
+ max_turns: Maximum conversation turns (file reads)
790
+ timeout: Max seconds to wait
791
+
792
+ Returns:
793
+ VerificationResult with parsed findings
794
+ """
795
+ prompt = SONNET_PROMPT.format(
796
+ opus_summary=opus_summary,
797
+ plan_content=plan_content
798
+ )
799
+
800
+ try:
801
+ # Call Claude CLI with Sonnet, allowing some turns for file reads
802
+ result = subprocess.run(
803
+ ["claude", "--print", "--model", "sonnet",
804
+ "--max-turns", str(max_turns), "-p", prompt],
805
+ capture_output=True,
806
+ text=True,
807
+ timeout=timeout
808
+ )
809
+
810
+ if result.returncode != 0:
811
+ raise RuntimeError(f"Claude CLI error: {result.stderr}")
812
+
813
+ response = result.stdout.strip()
814
+ return parse_sonnet_response(response)
815
+
816
+ except subprocess.TimeoutExpired:
817
+ raise RuntimeError("Sonnet verification timed out")
818
+ except FileNotFoundError:
819
+ raise RuntimeError("Claude CLI not found")
820
+
821
+
822
+ def parse_sonnet_response(response: str) -> VerificationResult:
823
+ """Parse Sonnet response into VerificationResult."""
824
+
825
+ verified = []
826
+ conflicts = []
827
+ missing = []
828
+ security = []
829
+
830
+ for line in response.split("\n"):
831
+ line = line.strip()
832
+ if line.startswith("[VERIFIED]"):
833
+ verified.append(line[10:].strip())
834
+ elif line.startswith("[CONFLICT]"):
835
+ conflicts.append(line[10:].strip())
836
+ elif line.startswith("[MISSING]"):
837
+ missing.append(line[9:].strip())
838
+ elif line.startswith("[SECURITY]"):
839
+ security.append(line[10:].strip())
840
+
841
+ return VerificationResult(
842
+ verified=verified,
843
+ conflicts=conflicts,
844
+ missing=missing,
845
+ security=security,
846
+ raw_response=response
847
+ )
848
+
849
+
850
+ def format_verification(result: VerificationResult) -> str:
851
+ """Format verification results for additionalContext."""
852
+
853
+ lines = ["--- Sonnet Verification ---"]
854
+
855
+ if result.conflicts:
856
+ lines.append(f"\nCONFLICTS ({len(result.conflicts)}):")
857
+ for c in result.conflicts:
858
+ lines.append(f" - {c}")
859
+
860
+ if result.missing:
861
+ lines.append(f"\nMISSING ({len(result.missing)}):")
862
+ for m in result.missing:
863
+ lines.append(f" - {m}")
864
+
865
+ if result.security:
866
+ lines.append(f"\nSECURITY CONCERNS ({len(result.security)}):")
867
+ for s in result.security:
868
+ lines.append(f" - {s}")
869
+
870
+ if result.verified and not (result.conflicts or result.missing or result.security):
871
+ lines.append(f"\nAll {len(result.verified)} items verified successfully.")
872
+
873
+ lines.append("\n--- End Verification ---")
874
+
875
+ return "\n".join(lines)
876
+
877
+
878
+ if __name__ == "__main__":
879
+ print("Sonnet verifier module loaded. Use run_sonnet_verification() to verify plans.")
880
+ ```
881
+
882
+ **Verification:**
883
+ - Test with plan containing file references
884
+ - Verify file reads work within turn limit
885
+ - Verify response parsing
886
+
887
+ ---
888
+
889
+ ### Phase 6: Orchestrator Update
890
+
891
+ **File to modify:**
892
+ - `scripts/post-enhance-plan.py`
893
+
894
+ **Changes:**
895
+ 1. Import new modules
896
+ 2. Add orchestration logic for three-layer validation
897
+ 3. Aggregate results into additionalContext
898
+
899
+ ```python
900
+ # New orchestration flow (pseudocode)
901
+
902
+ def handle_plan_write(plan_path, transcript_path, cwd, session_id):
903
+ plan_content = read_file(plan_path)
904
+ results = []
905
+
906
+ # Layer 1: Bash validators
907
+ bash_results = run_bash_validators(plan_path)
908
+ if bash_results.has_errors:
909
+ return format_bash_errors(bash_results)
910
+ results.append(bash_results)
911
+
912
+ # Layer 2: Opus analysis
913
+ user_messages = extract_user_messages(transcript_path)
914
+ task_json = get_task_json(session_id)
915
+
916
+ opus_result = run_opus_analysis(plan_content, user_messages, task_json)
917
+ results.append(opus_result)
918
+
919
+ # Layer 3: Sonnet verification (conditional)
920
+ needs_verification = (
921
+ opus_result.has_critical_risks or
922
+ opus_result.has_missing_requirements or
923
+ bash_results.risk_keywords_found
924
+ )
925
+
926
+ if needs_verification:
927
+ sonnet_result = run_sonnet_verification(
928
+ plan_content,
929
+ summarize_opus_findings(opus_result)
930
+ )
931
+ results.append(sonnet_result)
932
+
933
+ return format_all_results(results)
934
+ ```
935
+
936
+ **Verification:**
937
+ - End-to-end test with plan creation
938
+ - Verify all layers execute in correct order
939
+ - Verify conditional Sonnet invocation
940
+
941
+ ---
942
+
943
+ ## Files to Create/Modify
944
+
945
+ | File | Action | Description |
946
+ |------|--------|-------------|
947
+ | `config/planning-instructions.md` | Modify | Add marker requirements, section template |
948
+ | `scripts/lib/section_validator.sh` | Create | Validate required sections |
949
+ | `scripts/lib/marker_validator.sh` | Create | Validate marker syntax |
950
+ | `scripts/lib/assumption_detector.sh` | Create | Detect unmarked assumptions |
951
+ | `scripts/lib/risk_detector.sh` | Create | Detect risks, check mitigation |
952
+ | `scripts/lib/transcript_parser.py` | Create | Extract user messages from JSONL |
953
+ | `scripts/lib/opus_analyzer.py` | Create | Opus semantic analysis |
954
+ | `scripts/lib/sonnet_verifier.py` | Create | Sonnet file verification |
955
+ | `scripts/post-enhance-plan.py` | Modify | Orchestrate three-layer validation |
956
+
957
+ ## Risks and Mitigations
958
+
959
+ | Risk | Severity | Mitigation |
960
+ |------|----------|------------|
961
+ | Claude CLI syntax differs from assumed | HIGH | Verify CLI flags before implementation |
962
+ | Token costs exceed budget | MEDIUM | Add cost caps, skip Sonnet for low-risk |
963
+ | Opus/Sonnet timeout on complex plans | MEDIUM | Set reasonable timeouts, fallback to bash-only |
964
+ | Response parsing fails on edge cases | MEDIUM | Add robust error handling, log raw responses |
965
+ | False positives annoy users | MEDIUM | Tune prompts, add severity thresholds |
966
+
967
+ ## Verification Checklist
968
+
969
+ - [ ] Planning instructions injection works
970
+ - [ ] Each bash validator runs independently
971
+ - [ ] Transcript parser extracts messages correctly
972
+ - [ ] Opus analyzer produces structured output
973
+ - [ ] Sonnet verifier respects turn limits
974
+ - [ ] Orchestrator chains all layers correctly
975
+ - [ ] additionalContext returned to Claude
976
+ - [ ] End-to-end: Create plan, see validation results
977
+
978
+ ## Dependencies
979
+
980
+ - Claude CLI with headless mode support
981
+ - `jq` for JSON parsing in bash scripts
982
+ - Python 3.10+ for type hints
983
+ - Session transcript accessible via `transcript_path`
984
+
985
+ ## Open Questions
986
+
987
+ 1. **Claude CLI flags**: Need to verify exact syntax for `--model`, `--print`, `--max-turns`
988
+ 2. **Cost thresholds**: At what risk level should Sonnet verification trigger?
989
+ 3. **Blocking vs warning**: Should critical issues block plan approval or just warn?