shipwright-cli 3.2.0 → 3.3.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 (279) hide show
  1. package/.claude/agents/code-reviewer.md +2 -0
  2. package/.claude/agents/devops-engineer.md +2 -0
  3. package/.claude/agents/doc-fleet-agent.md +2 -0
  4. package/.claude/agents/pipeline-agent.md +2 -0
  5. package/.claude/agents/shell-script-specialist.md +2 -0
  6. package/.claude/agents/test-specialist.md +2 -0
  7. package/.claude/hooks/agent-crash-capture.sh +32 -0
  8. package/.claude/hooks/post-tool-use.sh +3 -2
  9. package/.claude/hooks/pre-tool-use.sh +35 -3
  10. package/README.md +4 -4
  11. package/claude-code/hooks/config-change.sh +18 -0
  12. package/claude-code/hooks/instructions-reloaded.sh +7 -0
  13. package/claude-code/hooks/worktree-create.sh +25 -0
  14. package/claude-code/hooks/worktree-remove.sh +20 -0
  15. package/config/code-constitution.json +130 -0
  16. package/dashboard/middleware/auth.ts +134 -0
  17. package/dashboard/middleware/constants.ts +21 -0
  18. package/dashboard/public/index.html +2 -6
  19. package/dashboard/public/styles.css +100 -97
  20. package/dashboard/routes/auth.ts +38 -0
  21. package/dashboard/server.ts +66 -25
  22. package/dashboard/services/config.ts +26 -0
  23. package/dashboard/services/db.ts +118 -0
  24. package/dashboard/src/canvas/pixel-agent.ts +298 -0
  25. package/dashboard/src/canvas/pixel-sprites.ts +440 -0
  26. package/dashboard/src/canvas/shipyard-effects.ts +367 -0
  27. package/dashboard/src/canvas/shipyard-scene.ts +616 -0
  28. package/dashboard/src/canvas/submarine-layout.ts +267 -0
  29. package/dashboard/src/components/header.ts +8 -7
  30. package/dashboard/src/core/router.ts +1 -0
  31. package/dashboard/src/design/submarine-theme.ts +253 -0
  32. package/dashboard/src/main.ts +2 -0
  33. package/dashboard/src/types/api.ts +2 -1
  34. package/dashboard/src/views/activity.ts +2 -1
  35. package/dashboard/src/views/shipyard.ts +39 -0
  36. package/dashboard/types/index.ts +166 -0
  37. package/docs/plans/2026-02-28-compound-audit-and-shipyard-design.md +186 -0
  38. package/docs/plans/2026-02-28-skipper-shipwright-implementation-plan.md +1182 -0
  39. package/docs/plans/2026-02-28-skipper-shipwright-integration-design.md +531 -0
  40. package/docs/plans/2026-03-01-ai-powered-skill-injection-design.md +298 -0
  41. package/docs/plans/2026-03-01-ai-powered-skill-injection-plan.md +1109 -0
  42. package/docs/plans/2026-03-01-capabilities-cleanup-plan.md +658 -0
  43. package/docs/plans/2026-03-01-clean-architecture-plan.md +924 -0
  44. package/docs/plans/2026-03-01-compound-audit-cascade-design.md +191 -0
  45. package/docs/plans/2026-03-01-compound-audit-cascade-plan.md +921 -0
  46. package/docs/plans/2026-03-01-deep-integration-plan.md +851 -0
  47. package/docs/plans/2026-03-01-pipeline-audit-trail-design.md +145 -0
  48. package/docs/plans/2026-03-01-pipeline-audit-trail-plan.md +770 -0
  49. package/docs/plans/2026-03-01-refined-depths-brand-design.md +382 -0
  50. package/docs/plans/2026-03-01-refined-depths-implementation.md +599 -0
  51. package/docs/plans/2026-03-01-skipper-kernel-integration-design.md +203 -0
  52. package/docs/plans/2026-03-01-unified-platform-design.md +272 -0
  53. package/docs/plans/2026-03-07-claude-code-feature-integration-design.md +189 -0
  54. package/docs/plans/2026-03-07-claude-code-feature-integration-plan.md +1165 -0
  55. package/docs/research/BACKLOG_QUICK_REFERENCE.md +352 -0
  56. package/docs/research/CUTTING_EDGE_RESEARCH_2026.md +546 -0
  57. package/docs/research/RESEARCH_INDEX.md +439 -0
  58. package/docs/research/RESEARCH_SOURCES.md +440 -0
  59. package/docs/research/RESEARCH_SUMMARY.txt +275 -0
  60. package/docs/superpowers/specs/2026-03-10-pipeline-quality-revolution-design.md +341 -0
  61. package/package.json +2 -2
  62. package/scripts/lib/adaptive-model.sh +427 -0
  63. package/scripts/lib/adaptive-timeout.sh +316 -0
  64. package/scripts/lib/audit-trail.sh +309 -0
  65. package/scripts/lib/auto-recovery.sh +471 -0
  66. package/scripts/lib/bandit-selector.sh +431 -0
  67. package/scripts/lib/bootstrap.sh +104 -2
  68. package/scripts/lib/causal-graph.sh +455 -0
  69. package/scripts/lib/compat.sh +126 -0
  70. package/scripts/lib/compound-audit.sh +337 -0
  71. package/scripts/lib/constitutional.sh +454 -0
  72. package/scripts/lib/context-budget.sh +359 -0
  73. package/scripts/lib/convergence.sh +594 -0
  74. package/scripts/lib/cost-optimizer.sh +634 -0
  75. package/scripts/lib/daemon-adaptive.sh +10 -0
  76. package/scripts/lib/daemon-dispatch.sh +106 -17
  77. package/scripts/lib/daemon-failure.sh +34 -4
  78. package/scripts/lib/daemon-patrol.sh +23 -2
  79. package/scripts/lib/daemon-poll-github.sh +361 -0
  80. package/scripts/lib/daemon-poll-health.sh +299 -0
  81. package/scripts/lib/daemon-poll.sh +27 -611
  82. package/scripts/lib/daemon-state.sh +112 -66
  83. package/scripts/lib/daemon-triage.sh +10 -0
  84. package/scripts/lib/dod-scorecard.sh +442 -0
  85. package/scripts/lib/error-actionability.sh +300 -0
  86. package/scripts/lib/formal-spec.sh +461 -0
  87. package/scripts/lib/helpers.sh +177 -4
  88. package/scripts/lib/intent-analysis.sh +409 -0
  89. package/scripts/lib/loop-convergence.sh +350 -0
  90. package/scripts/lib/loop-iteration.sh +682 -0
  91. package/scripts/lib/loop-progress.sh +48 -0
  92. package/scripts/lib/loop-restart.sh +185 -0
  93. package/scripts/lib/memory-effectiveness.sh +506 -0
  94. package/scripts/lib/mutation-executor.sh +352 -0
  95. package/scripts/lib/outcome-feedback.sh +521 -0
  96. package/scripts/lib/pipeline-cli.sh +336 -0
  97. package/scripts/lib/pipeline-commands.sh +1216 -0
  98. package/scripts/lib/pipeline-detection.sh +100 -2
  99. package/scripts/lib/pipeline-execution.sh +897 -0
  100. package/scripts/lib/pipeline-github.sh +28 -3
  101. package/scripts/lib/pipeline-intelligence-compound.sh +431 -0
  102. package/scripts/lib/pipeline-intelligence-scoring.sh +407 -0
  103. package/scripts/lib/pipeline-intelligence-skip.sh +181 -0
  104. package/scripts/lib/pipeline-intelligence.sh +100 -1136
  105. package/scripts/lib/pipeline-quality-bash-compat.sh +182 -0
  106. package/scripts/lib/pipeline-quality-checks.sh +17 -715
  107. package/scripts/lib/pipeline-quality-gates.sh +563 -0
  108. package/scripts/lib/pipeline-stages-build.sh +730 -0
  109. package/scripts/lib/pipeline-stages-delivery.sh +965 -0
  110. package/scripts/lib/pipeline-stages-intake.sh +1133 -0
  111. package/scripts/lib/pipeline-stages-monitor.sh +407 -0
  112. package/scripts/lib/pipeline-stages-review.sh +1022 -0
  113. package/scripts/lib/pipeline-stages.sh +59 -2929
  114. package/scripts/lib/pipeline-state.sh +36 -5
  115. package/scripts/lib/pipeline-util.sh +487 -0
  116. package/scripts/lib/policy-learner.sh +438 -0
  117. package/scripts/lib/process-reward.sh +493 -0
  118. package/scripts/lib/project-detect.sh +649 -0
  119. package/scripts/lib/quality-profile.sh +334 -0
  120. package/scripts/lib/recruit-commands.sh +885 -0
  121. package/scripts/lib/recruit-learning.sh +739 -0
  122. package/scripts/lib/recruit-roles.sh +648 -0
  123. package/scripts/lib/reward-aggregator.sh +458 -0
  124. package/scripts/lib/rl-optimizer.sh +362 -0
  125. package/scripts/lib/root-cause.sh +427 -0
  126. package/scripts/lib/scope-enforcement.sh +445 -0
  127. package/scripts/lib/session-restart.sh +493 -0
  128. package/scripts/lib/skill-memory.sh +300 -0
  129. package/scripts/lib/skill-registry.sh +775 -0
  130. package/scripts/lib/spec-driven.sh +476 -0
  131. package/scripts/lib/test-helpers.sh +18 -7
  132. package/scripts/lib/test-holdout.sh +429 -0
  133. package/scripts/lib/test-optimizer.sh +511 -0
  134. package/scripts/shipwright-file-suggest.sh +45 -0
  135. package/scripts/skills/adversarial-quality.md +61 -0
  136. package/scripts/skills/api-design.md +44 -0
  137. package/scripts/skills/architecture-design.md +50 -0
  138. package/scripts/skills/brainstorming.md +43 -0
  139. package/scripts/skills/data-pipeline.md +44 -0
  140. package/scripts/skills/deploy-safety.md +64 -0
  141. package/scripts/skills/documentation.md +38 -0
  142. package/scripts/skills/frontend-design.md +45 -0
  143. package/scripts/skills/generated/.gitkeep +0 -0
  144. package/scripts/skills/generated/_refinements/.gitkeep +0 -0
  145. package/scripts/skills/generated/_refinements/adversarial-quality.patch.md +3 -0
  146. package/scripts/skills/generated/_refinements/architecture-design.patch.md +3 -0
  147. package/scripts/skills/generated/_refinements/brainstorming.patch.md +3 -0
  148. package/scripts/skills/generated/cli-version-management.md +29 -0
  149. package/scripts/skills/generated/collection-system-validation.md +99 -0
  150. package/scripts/skills/generated/large-scale-c-refactoring-coordination.md +97 -0
  151. package/scripts/skills/generated/pattern-matching-similarity-scoring.md +195 -0
  152. package/scripts/skills/generated/test-parallelization-detection.md +65 -0
  153. package/scripts/skills/observability.md +79 -0
  154. package/scripts/skills/performance.md +48 -0
  155. package/scripts/skills/pr-quality.md +49 -0
  156. package/scripts/skills/product-thinking.md +43 -0
  157. package/scripts/skills/security-audit.md +49 -0
  158. package/scripts/skills/systematic-debugging.md +40 -0
  159. package/scripts/skills/testing-strategy.md +47 -0
  160. package/scripts/skills/two-stage-review.md +52 -0
  161. package/scripts/skills/validation-thoroughness.md +55 -0
  162. package/scripts/sw +9 -3
  163. package/scripts/sw-activity.sh +9 -2
  164. package/scripts/sw-adaptive.sh +2 -1
  165. package/scripts/sw-adversarial.sh +2 -1
  166. package/scripts/sw-architecture-enforcer.sh +3 -1
  167. package/scripts/sw-auth.sh +12 -2
  168. package/scripts/sw-autonomous.sh +5 -1
  169. package/scripts/sw-changelog.sh +4 -1
  170. package/scripts/sw-checkpoint.sh +2 -1
  171. package/scripts/sw-ci.sh +5 -1
  172. package/scripts/sw-cleanup.sh +4 -26
  173. package/scripts/sw-code-review.sh +10 -4
  174. package/scripts/sw-connect.sh +2 -1
  175. package/scripts/sw-context.sh +2 -1
  176. package/scripts/sw-cost.sh +48 -3
  177. package/scripts/sw-daemon.sh +66 -9
  178. package/scripts/sw-dashboard.sh +3 -1
  179. package/scripts/sw-db.sh +59 -16
  180. package/scripts/sw-decide.sh +8 -2
  181. package/scripts/sw-decompose.sh +360 -17
  182. package/scripts/sw-deps.sh +4 -1
  183. package/scripts/sw-developer-simulation.sh +4 -1
  184. package/scripts/sw-discovery.sh +325 -2
  185. package/scripts/sw-doc-fleet.sh +4 -1
  186. package/scripts/sw-docs-agent.sh +3 -1
  187. package/scripts/sw-docs.sh +2 -1
  188. package/scripts/sw-doctor.sh +453 -2
  189. package/scripts/sw-dora.sh +4 -1
  190. package/scripts/sw-durable.sh +4 -3
  191. package/scripts/sw-e2e-orchestrator.sh +17 -16
  192. package/scripts/sw-eventbus.sh +7 -1
  193. package/scripts/sw-evidence.sh +364 -12
  194. package/scripts/sw-feedback.sh +550 -9
  195. package/scripts/sw-fix.sh +20 -1
  196. package/scripts/sw-fleet-discover.sh +6 -2
  197. package/scripts/sw-fleet-viz.sh +4 -1
  198. package/scripts/sw-fleet.sh +5 -1
  199. package/scripts/sw-github-app.sh +16 -3
  200. package/scripts/sw-github-checks.sh +3 -2
  201. package/scripts/sw-github-deploy.sh +3 -2
  202. package/scripts/sw-github-graphql.sh +18 -7
  203. package/scripts/sw-guild.sh +5 -1
  204. package/scripts/sw-heartbeat.sh +5 -30
  205. package/scripts/sw-hello.sh +67 -0
  206. package/scripts/sw-hygiene.sh +6 -1
  207. package/scripts/sw-incident.sh +265 -1
  208. package/scripts/sw-init.sh +18 -2
  209. package/scripts/sw-instrument.sh +10 -2
  210. package/scripts/sw-intelligence.sh +42 -6
  211. package/scripts/sw-jira.sh +5 -1
  212. package/scripts/sw-launchd.sh +2 -1
  213. package/scripts/sw-linear.sh +4 -1
  214. package/scripts/sw-logs.sh +4 -1
  215. package/scripts/sw-loop.sh +432 -1128
  216. package/scripts/sw-memory.sh +356 -2
  217. package/scripts/sw-mission-control.sh +6 -1
  218. package/scripts/sw-model-router.sh +481 -26
  219. package/scripts/sw-otel.sh +13 -4
  220. package/scripts/sw-oversight.sh +14 -5
  221. package/scripts/sw-patrol-meta.sh +334 -0
  222. package/scripts/sw-pipeline-composer.sh +5 -1
  223. package/scripts/sw-pipeline-vitals.sh +2 -1
  224. package/scripts/sw-pipeline.sh +53 -2664
  225. package/scripts/sw-pm.sh +12 -5
  226. package/scripts/sw-pr-lifecycle.sh +2 -1
  227. package/scripts/sw-predictive.sh +7 -1
  228. package/scripts/sw-prep.sh +185 -2
  229. package/scripts/sw-ps.sh +5 -25
  230. package/scripts/sw-public-dashboard.sh +15 -3
  231. package/scripts/sw-quality.sh +2 -1
  232. package/scripts/sw-reaper.sh +8 -25
  233. package/scripts/sw-recruit.sh +156 -2303
  234. package/scripts/sw-regression.sh +19 -12
  235. package/scripts/sw-release-manager.sh +3 -1
  236. package/scripts/sw-release.sh +4 -1
  237. package/scripts/sw-remote.sh +3 -1
  238. package/scripts/sw-replay.sh +7 -1
  239. package/scripts/sw-retro.sh +158 -1
  240. package/scripts/sw-review-rerun.sh +3 -1
  241. package/scripts/sw-scale.sh +10 -3
  242. package/scripts/sw-security-audit.sh +6 -1
  243. package/scripts/sw-self-optimize.sh +6 -3
  244. package/scripts/sw-session.sh +9 -3
  245. package/scripts/sw-setup.sh +3 -1
  246. package/scripts/sw-stall-detector.sh +406 -0
  247. package/scripts/sw-standup.sh +15 -7
  248. package/scripts/sw-status.sh +3 -1
  249. package/scripts/sw-strategic.sh +4 -1
  250. package/scripts/sw-stream.sh +7 -1
  251. package/scripts/sw-swarm.sh +18 -6
  252. package/scripts/sw-team-stages.sh +13 -6
  253. package/scripts/sw-templates.sh +5 -29
  254. package/scripts/sw-testgen.sh +7 -1
  255. package/scripts/sw-tmux-pipeline.sh +4 -1
  256. package/scripts/sw-tmux-role-color.sh +2 -0
  257. package/scripts/sw-tmux-status.sh +1 -1
  258. package/scripts/sw-tmux.sh +3 -1
  259. package/scripts/sw-trace.sh +3 -1
  260. package/scripts/sw-tracker-github.sh +3 -0
  261. package/scripts/sw-tracker-jira.sh +3 -0
  262. package/scripts/sw-tracker-linear.sh +3 -0
  263. package/scripts/sw-tracker.sh +3 -1
  264. package/scripts/sw-triage.sh +2 -1
  265. package/scripts/sw-upgrade.sh +3 -1
  266. package/scripts/sw-ux.sh +5 -2
  267. package/scripts/sw-webhook.sh +3 -1
  268. package/scripts/sw-widgets.sh +3 -1
  269. package/scripts/sw-worktree.sh +15 -3
  270. package/scripts/test-skill-injection.sh +1233 -0
  271. package/templates/pipelines/autonomous.json +27 -3
  272. package/templates/pipelines/cost-aware.json +34 -8
  273. package/templates/pipelines/deployed.json +12 -0
  274. package/templates/pipelines/enterprise.json +12 -0
  275. package/templates/pipelines/fast.json +6 -0
  276. package/templates/pipelines/full.json +27 -3
  277. package/templates/pipelines/hotfix.json +6 -0
  278. package/templates/pipelines/standard.json +12 -0
  279. package/templates/pipelines/tdd.json +12 -0
@@ -0,0 +1,337 @@
1
+ #!/usr/bin/env bash
2
+ # ╔═══════════════════════════════════════════════════════════════════════════╗
3
+ # ║ compound-audit — Adaptive multi-agent audit cascade ║
4
+ # ║ ║
5
+ # ║ Runs specialized audit agents in parallel, deduplicates findings, ║
6
+ # ║ escalates to specialists when needed, and converges when confidence ║
7
+ # ║ is high. All functions fail-open with || return 0. ║
8
+ # ╚═══════════════════════════════════════════════════════════════════════════╝
9
+
10
+ [[ -n "${_COMPOUND_AUDIT_LOADED:-}" ]] && return 0
11
+ _COMPOUND_AUDIT_LOADED=1
12
+
13
+ # ─── Agent prompt templates ────────────────────────────────────────────────
14
+ # Each agent gets the same context but a specialized lens.
15
+
16
+ _COMPOUND_AGENT_PROMPTS_logic="You are a Logic Auditor. Focus ONLY on:
17
+ - Control flow bugs, off-by-one errors, wrong conditions
18
+ - Algorithm errors, incorrect logic, null/undefined paths
19
+ - Race conditions, state management bugs
20
+ - Edge cases in arithmetic or string operations
21
+ Do NOT report style issues, missing features, or integration problems."
22
+
23
+ _COMPOUND_AGENT_PROMPTS_integration="You are an Integration Auditor. Focus ONLY on:
24
+ - Missing imports, broken call chains, unconnected components
25
+ - Mismatched interfaces between modules
26
+ - Functions called with wrong arguments or missing arguments
27
+ - Wiring gaps where new code isn't connected to existing code
28
+ Do NOT report logic bugs, style issues, or missing features."
29
+
30
+ _COMPOUND_AGENT_PROMPTS_completeness="You are a Completeness Auditor. Focus ONLY on:
31
+ - Spec vs. implementation gaps (does the code do what the plan says?)
32
+ - Missing test coverage for new functionality
33
+ - TODO/FIXME/placeholder code left behind
34
+ - Partial implementations (feature started but not finished)
35
+ Do NOT report logic bugs, style issues, or integration problems."
36
+
37
+ _COMPOUND_AGENT_PROMPTS_security="You are a Security Auditor. Focus ONLY on:
38
+ - Command injection, path traversal, input validation gaps
39
+ - Credential/secret exposure in code or logs
40
+ - Authentication/authorization bypass paths
41
+ - OWASP top 10 vulnerability patterns
42
+ Do NOT report non-security issues."
43
+
44
+ _COMPOUND_AGENT_PROMPTS_error_handling="You are an Error Handling Auditor. Focus ONLY on:
45
+ - Silent error swallowing (empty catch blocks, ignored return codes)
46
+ - Missing error paths (what happens when X fails?)
47
+ - Inconsistent error handling patterns
48
+ - Unchecked return values from external commands
49
+ Do NOT report non-error-handling issues."
50
+
51
+ _COMPOUND_AGENT_PROMPTS_performance="You are a Performance Auditor. Focus ONLY on:
52
+ - O(n^2) or worse patterns in loops
53
+ - Unbounded memory allocation or file reads
54
+ - Missing pagination or streaming for large data
55
+ - Repeated expensive operations that could be cached
56
+ Do NOT report non-performance issues."
57
+
58
+ _COMPOUND_AGENT_PROMPTS_edge_case="You are an Edge Case Auditor. Focus ONLY on:
59
+ - Zero-length inputs, empty strings, empty arrays
60
+ - Maximum/minimum boundary values
61
+ - Unicode, special characters, newlines in data
62
+ - Concurrent access, timing-dependent behavior
63
+ Do NOT report non-edge-case issues."
64
+
65
+ # ─── compound_audit_build_prompt ───────────────────────────────────────────
66
+ # Builds the full prompt for a specific agent type.
67
+ #
68
+ # Usage: compound_audit_build_prompt "logic" "$diff" "$plan" "$prev_findings_json"
69
+ compound_audit_build_prompt() {
70
+ local agent_type="$1"
71
+ local diff="$2"
72
+ local plan_summary="$3"
73
+ local prev_findings="$4"
74
+
75
+ # Get agent-specific instructions
76
+ local varname="_COMPOUND_AGENT_PROMPTS_${agent_type}"
77
+ local specialization="${!varname:-"You are a code auditor. Review the changes for issues."}"
78
+
79
+ cat <<EOF
80
+ ${specialization}
81
+
82
+ ## Code Changes (cumulative diff)
83
+ \`\`\`
84
+ ${diff}
85
+ \`\`\`
86
+
87
+ ## Implementation Plan/Spec
88
+ ${plan_summary}
89
+
90
+ ## Previously Found Issues (do NOT repeat these)
91
+ ${prev_findings}
92
+
93
+ ## Output Format
94
+ Return ONLY valid JSON (no markdown, no explanation):
95
+ {"findings":[{"severity":"critical|high|medium|low","category":"${agent_type}","file":"path/to/file","line":0,"description":"One sentence","evidence":"The specific code","suggestion":"How to fix"}]}
96
+
97
+ If no issues found, return: {"findings":[]}
98
+ EOF
99
+ }
100
+
101
+ # ─── compound_audit_parse_findings ─────────────────────────────────────────
102
+ # Parses agent output into a findings array. Handles malformed output.
103
+ #
104
+ # Usage: compound_audit_parse_findings "$agent_stdout"
105
+ # Output: JSON array of findings (or empty array on failure)
106
+ compound_audit_parse_findings() {
107
+ local raw_output="$1"
108
+
109
+ # Strip markdown code fences if present
110
+ local cleaned
111
+ cleaned=$(echo "$raw_output" | sed 's/^```json//;s/^```//;s/```$//' | tr -d '\r')
112
+
113
+ # Try to extract findings array
114
+ local findings
115
+ findings=$(echo "$cleaned" | jq -r '.findings // []' 2>/dev/null) || findings="[]"
116
+
117
+ # Validate it's actually an array
118
+ if echo "$findings" | jq -e 'type == "array"' >/dev/null 2>&1; then
119
+ echo "$findings"
120
+ else
121
+ echo "[]"
122
+ fi
123
+ }
124
+
125
+ # ─── compound_audit_dedup_structural ───────────────────────────────────────
126
+ # Tier 1 dedup: same file + same category + lines within 5 = duplicate.
127
+ # Keeps the first (highest severity) finding in each group.
128
+ #
129
+ # Usage: compound_audit_dedup_structural "$findings_json_array"
130
+ # Output: Deduplicated JSON array
131
+ compound_audit_dedup_structural() {
132
+ local findings="$1"
133
+
134
+ [[ -z "$findings" || "$findings" == "[]" ]] && { echo "[]"; return 0; }
135
+
136
+ # Use jq to group by file+category, then within each group merge findings
137
+ # whose lines are within 5 of each other
138
+ echo "$findings" | jq '
139
+ # Sort by severity priority (critical first) then by line
140
+ def sev_order: if . == "critical" then 0 elif . == "high" then 1
141
+ elif . == "medium" then 2 else 3 end;
142
+
143
+ sort_by([(.severity | sev_order), .line]) |
144
+
145
+ # Group by file + category
146
+ group_by([.file, .category]) |
147
+
148
+ # Within each group, merge findings with lines within 5
149
+ map(
150
+ reduce .[] as $item ([];
151
+ if length == 0 then [$item]
152
+ elif (. | last | .line) and $item.line and
153
+ (($item.line - (. | last | .line)) | fabs) <= 5
154
+ then . # Skip duplicate (nearby line, same file+category)
155
+ else . + [$item]
156
+ end
157
+ )
158
+ ) | flatten
159
+ ' 2>/dev/null || echo "$findings"
160
+ }
161
+
162
+ # ─── Escalation trigger keywords ──────────────────────────────────────────
163
+ _COMPOUND_TRIGGERS_security="injection|auth|secret|credential|permission|bypass|xss|csrf|traversal|sanitiz"
164
+ _COMPOUND_TRIGGERS_error_handling="catch|swallow|silent|ignore.*error|missing.*error|unchecked|unhandled"
165
+ _COMPOUND_TRIGGERS_performance="O\\(n|loop.*loop|unbounded|pagination|cache|memory.*leak|quadratic"
166
+ _COMPOUND_TRIGGERS_edge_case="boundary|empty.*input|null.*check|zero.*length|unicode|concurrent|race"
167
+
168
+ # ─── compound_audit_escalate ──────────────────────────────────────────────
169
+ # Scans findings for trigger keywords, returns space-separated specialist list.
170
+ #
171
+ # Usage: compound_audit_escalate "$findings_json_array"
172
+ # Output: Space-separated specialist names (e.g., "security error_handling")
173
+ compound_audit_escalate() {
174
+ local findings="$1"
175
+
176
+ [[ -z "$findings" || "$findings" == "[]" ]] && return 0
177
+
178
+ # Flatten all finding text for keyword scanning
179
+ local all_text
180
+ all_text=$(echo "$findings" | jq -r '.[] | .description + " " + .evidence + " " + .file' 2>/dev/null | tr '[:upper:]' '[:lower:]') || return 0
181
+
182
+ local specialists=""
183
+ local spec
184
+ for spec in security error_handling performance edge_case; do
185
+ local varname="_COMPOUND_TRIGGERS_${spec}"
186
+ local pattern="${!varname:-}"
187
+ if [[ -n "$pattern" ]] && echo "$all_text" | grep -qEi "$pattern" 2>/dev/null; then
188
+ specialists="${specialists:+${specialists} }${spec}"
189
+ fi
190
+ done
191
+
192
+ echo "$specialists"
193
+ }
194
+
195
+ # ─── compound_audit_converged ─────────────────────────────────────────────
196
+ # Checks stop conditions for the cascade loop.
197
+ #
198
+ # Usage: compound_audit_converged "$new_findings" "$all_prev_findings" $cycle $max_cycles
199
+ # Output: Reason string if converged ("no_criticals", "dup_rate", "max_cycles"), empty if not
200
+ compound_audit_converged() {
201
+ local new_findings="$1"
202
+ local prev_findings="$2"
203
+ local cycle="$3"
204
+ local max_cycles="$4"
205
+
206
+ # Hard cap: max cycles reached
207
+ if [[ "$cycle" -ge "$max_cycles" ]]; then
208
+ echo "max_cycles"
209
+ return 0
210
+ fi
211
+
212
+ # No findings at all = converged
213
+ local new_count
214
+ new_count=$(echo "$new_findings" | jq 'length' 2>/dev/null || echo "0")
215
+ if [[ "$new_count" -eq 0 ]]; then
216
+ echo "no_criticals"
217
+ return 0
218
+ fi
219
+
220
+ # Check for critical/high in new findings
221
+ local crit_high_count
222
+ crit_high_count=$(echo "$new_findings" | jq '[.[] | select(.severity == "critical" or .severity == "high")] | length' 2>/dev/null || echo "0")
223
+
224
+ # If previous findings exist, check duplicate rate via structural match
225
+ local prev_count
226
+ prev_count=$(echo "$prev_findings" | jq 'length' 2>/dev/null || echo "0")
227
+ if [[ "$prev_count" -gt 0 && "$new_count" -gt 0 ]]; then
228
+ # Count how many new findings structurally match previous ones
229
+ local dup_count=0
230
+ local i=0
231
+ while [[ "$i" -lt "$new_count" ]]; do
232
+ local nf nc nl
233
+ nf=$(echo "$new_findings" | jq -r ".[$i].file // \"\"" 2>/dev/null)
234
+ nc=$(echo "$new_findings" | jq -r ".[$i].category // \"\"" 2>/dev/null)
235
+ nl=$(echo "$new_findings" | jq -r ".[$i].line // 0" 2>/dev/null)
236
+
237
+ # Check if any previous finding matches file+category+nearby line
238
+ local match
239
+ match=$(echo "$prev_findings" | jq --arg f "$nf" --arg c "$nc" --argjson l "$nl" \
240
+ '[.[] | select(.file == $f and .category == $c and ((.line // 0) - $l | fabs) <= 5)] | length' 2>/dev/null || echo "0")
241
+ [[ "$match" -gt 0 ]] && dup_count=$((dup_count + 1))
242
+ i=$((i + 1))
243
+ done
244
+
245
+ # If all findings are duplicates, converged
246
+ if [[ "$dup_count" -eq "$new_count" ]]; then
247
+ echo "dup_rate"
248
+ return 0
249
+ fi
250
+ fi
251
+
252
+ # No critical/high = converged
253
+ if [[ "$crit_high_count" -eq 0 ]]; then
254
+ echo "no_criticals"
255
+ return 0
256
+ fi
257
+
258
+ # Not converged
259
+ echo ""
260
+ return 0
261
+ }
262
+
263
+ # ─── compound_audit_run_cycle ─────────────────────────────────────────────
264
+ # Runs multiple agents in parallel and collects their findings.
265
+ #
266
+ # Usage: compound_audit_run_cycle "logic integration completeness" "$diff" "$plan" "$prev_findings" $cycle
267
+ # Output: Merged JSON array of all findings
268
+ compound_audit_run_cycle() {
269
+ local agents="$1"
270
+ local diff="$2"
271
+ local plan_summary="$3"
272
+ local prev_findings="$4"
273
+ local cycle="$5"
274
+
275
+ local model="${COMPOUND_AUDIT_MODEL:-haiku}"
276
+ local temp_dir
277
+ temp_dir=$(mktemp -d) || return 0
278
+
279
+ # Emit cycle start event
280
+ type audit_emit >/dev/null 2>&1 && \
281
+ audit_emit "compound.cycle_start" "cycle=$cycle" "agents=$agents" || true
282
+
283
+ # Launch agents in parallel
284
+ local pids=()
285
+ local agent
286
+ for agent in $agents; do
287
+ local prompt
288
+ prompt=$(compound_audit_build_prompt "$agent" "$diff" "$plan_summary" "$prev_findings")
289
+
290
+ (
291
+ local output
292
+ output=$(echo "$prompt" | claude -p --model "$model" 2>/dev/null) || output='{"findings":[]}'
293
+ echo "$output" > "$temp_dir/${agent}.json"
294
+ ) &
295
+ pids+=($!)
296
+ done
297
+
298
+ # Wait for all agents
299
+ local pid
300
+ for pid in "${pids[@]}"; do
301
+ wait "$pid" 2>/dev/null || true
302
+ done
303
+
304
+ # Merge findings from all agents
305
+ local all_findings="[]"
306
+ for agent in $agents; do
307
+ local agent_file="$temp_dir/${agent}.json"
308
+ if [[ -f "$agent_file" ]]; then
309
+ local agent_findings
310
+ agent_findings=$(compound_audit_parse_findings "$(cat "$agent_file")")
311
+
312
+ # Emit individual findings as audit events
313
+ local i=0
314
+ local fc
315
+ fc=$(echo "$agent_findings" | jq 'length' 2>/dev/null || echo "0")
316
+ while [[ "$i" -lt "$fc" ]]; do
317
+ local sev desc file line
318
+ sev=$(echo "$agent_findings" | jq -r ".[$i].severity" 2>/dev/null)
319
+ desc=$(echo "$agent_findings" | jq -r ".[$i].description" 2>/dev/null)
320
+ file=$(echo "$agent_findings" | jq -r ".[$i].file" 2>/dev/null)
321
+ line=$(echo "$agent_findings" | jq -r ".[$i].line" 2>/dev/null)
322
+ type audit_emit >/dev/null 2>&1 && \
323
+ audit_emit "compound.finding" "cycle=$cycle" "agent=$agent" \
324
+ "severity=$sev" "file=$file" "line=$line" "description=$desc" || true
325
+ i=$((i + 1))
326
+ done
327
+
328
+ # Merge into all_findings
329
+ all_findings=$(echo "$all_findings" "$agent_findings" | jq -s '.[0] + .[1]' 2>/dev/null || echo "$all_findings")
330
+ fi
331
+ done
332
+
333
+ # Cleanup
334
+ rm -rf "$temp_dir" 2>/dev/null || true
335
+
336
+ echo "$all_findings"
337
+ }