shipwright-cli 3.1.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.
- package/.claude/agents/code-reviewer.md +2 -0
- package/.claude/agents/devops-engineer.md +2 -0
- package/.claude/agents/doc-fleet-agent.md +2 -0
- package/.claude/agents/pipeline-agent.md +2 -0
- package/.claude/agents/shell-script-specialist.md +2 -0
- package/.claude/agents/test-specialist.md +2 -0
- package/.claude/hooks/agent-crash-capture.sh +32 -0
- package/.claude/hooks/post-tool-use.sh +3 -2
- package/.claude/hooks/pre-tool-use.sh +35 -3
- package/README.md +22 -8
- package/claude-code/hooks/config-change.sh +18 -0
- package/claude-code/hooks/instructions-reloaded.sh +7 -0
- package/claude-code/hooks/worktree-create.sh +25 -0
- package/claude-code/hooks/worktree-remove.sh +20 -0
- package/config/code-constitution.json +130 -0
- package/config/defaults.json +25 -2
- package/config/policy.json +1 -1
- package/dashboard/middleware/auth.ts +134 -0
- package/dashboard/middleware/constants.ts +21 -0
- package/dashboard/public/index.html +8 -6
- package/dashboard/public/styles.css +176 -97
- package/dashboard/routes/auth.ts +38 -0
- package/dashboard/server.ts +117 -25
- package/dashboard/services/config.ts +26 -0
- package/dashboard/services/db.ts +118 -0
- package/dashboard/src/canvas/pixel-agent.ts +298 -0
- package/dashboard/src/canvas/pixel-sprites.ts +440 -0
- package/dashboard/src/canvas/shipyard-effects.ts +367 -0
- package/dashboard/src/canvas/shipyard-scene.ts +616 -0
- package/dashboard/src/canvas/submarine-layout.ts +267 -0
- package/dashboard/src/components/header.ts +8 -7
- package/dashboard/src/core/api.ts +5 -0
- package/dashboard/src/core/router.ts +1 -0
- package/dashboard/src/design/submarine-theme.ts +253 -0
- package/dashboard/src/main.ts +2 -0
- package/dashboard/src/types/api.ts +12 -1
- package/dashboard/src/views/activity.ts +2 -1
- package/dashboard/src/views/metrics.ts +69 -1
- package/dashboard/src/views/shipyard.ts +39 -0
- package/dashboard/types/index.ts +166 -0
- package/docs/plans/2026-02-28-compound-audit-and-shipyard-design.md +186 -0
- package/docs/plans/2026-02-28-skipper-shipwright-implementation-plan.md +1182 -0
- package/docs/plans/2026-02-28-skipper-shipwright-integration-design.md +531 -0
- package/docs/plans/2026-03-01-ai-powered-skill-injection-design.md +298 -0
- package/docs/plans/2026-03-01-ai-powered-skill-injection-plan.md +1109 -0
- package/docs/plans/2026-03-01-capabilities-cleanup-plan.md +658 -0
- package/docs/plans/2026-03-01-clean-architecture-plan.md +924 -0
- package/docs/plans/2026-03-01-compound-audit-cascade-design.md +191 -0
- package/docs/plans/2026-03-01-compound-audit-cascade-plan.md +921 -0
- package/docs/plans/2026-03-01-deep-integration-plan.md +851 -0
- package/docs/plans/2026-03-01-pipeline-audit-trail-design.md +145 -0
- package/docs/plans/2026-03-01-pipeline-audit-trail-plan.md +770 -0
- package/docs/plans/2026-03-01-refined-depths-brand-design.md +382 -0
- package/docs/plans/2026-03-01-refined-depths-implementation.md +599 -0
- package/docs/plans/2026-03-01-skipper-kernel-integration-design.md +203 -0
- package/docs/plans/2026-03-01-unified-platform-design.md +272 -0
- package/docs/plans/2026-03-07-claude-code-feature-integration-design.md +189 -0
- package/docs/plans/2026-03-07-claude-code-feature-integration-plan.md +1165 -0
- package/docs/research/BACKLOG_QUICK_REFERENCE.md +352 -0
- package/docs/research/CUTTING_EDGE_RESEARCH_2026.md +546 -0
- package/docs/research/RESEARCH_INDEX.md +439 -0
- package/docs/research/RESEARCH_SOURCES.md +440 -0
- package/docs/research/RESEARCH_SUMMARY.txt +275 -0
- package/docs/superpowers/specs/2026-03-10-pipeline-quality-revolution-design.md +341 -0
- package/package.json +2 -2
- package/scripts/lib/adaptive-model.sh +427 -0
- package/scripts/lib/adaptive-timeout.sh +316 -0
- package/scripts/lib/audit-trail.sh +309 -0
- package/scripts/lib/auto-recovery.sh +471 -0
- package/scripts/lib/bandit-selector.sh +431 -0
- package/scripts/lib/bootstrap.sh +104 -2
- package/scripts/lib/causal-graph.sh +455 -0
- package/scripts/lib/compat.sh +126 -0
- package/scripts/lib/compound-audit.sh +337 -0
- package/scripts/lib/constitutional.sh +454 -0
- package/scripts/lib/context-budget.sh +359 -0
- package/scripts/lib/convergence.sh +594 -0
- package/scripts/lib/cost-optimizer.sh +634 -0
- package/scripts/lib/daemon-adaptive.sh +14 -2
- package/scripts/lib/daemon-dispatch.sh +106 -17
- package/scripts/lib/daemon-failure.sh +34 -4
- package/scripts/lib/daemon-patrol.sh +25 -4
- package/scripts/lib/daemon-poll-github.sh +361 -0
- package/scripts/lib/daemon-poll-health.sh +299 -0
- package/scripts/lib/daemon-poll.sh +27 -611
- package/scripts/lib/daemon-state.sh +119 -66
- package/scripts/lib/daemon-triage.sh +10 -0
- package/scripts/lib/dod-scorecard.sh +442 -0
- package/scripts/lib/error-actionability.sh +300 -0
- package/scripts/lib/formal-spec.sh +461 -0
- package/scripts/lib/helpers.sh +180 -5
- package/scripts/lib/intent-analysis.sh +409 -0
- package/scripts/lib/loop-convergence.sh +350 -0
- package/scripts/lib/loop-iteration.sh +682 -0
- package/scripts/lib/loop-progress.sh +48 -0
- package/scripts/lib/loop-restart.sh +185 -0
- package/scripts/lib/memory-effectiveness.sh +506 -0
- package/scripts/lib/mutation-executor.sh +352 -0
- package/scripts/lib/outcome-feedback.sh +521 -0
- package/scripts/lib/pipeline-cli.sh +336 -0
- package/scripts/lib/pipeline-commands.sh +1216 -0
- package/scripts/lib/pipeline-detection.sh +101 -3
- package/scripts/lib/pipeline-execution.sh +897 -0
- package/scripts/lib/pipeline-github.sh +28 -3
- package/scripts/lib/pipeline-intelligence-compound.sh +431 -0
- package/scripts/lib/pipeline-intelligence-scoring.sh +407 -0
- package/scripts/lib/pipeline-intelligence-skip.sh +181 -0
- package/scripts/lib/pipeline-intelligence.sh +104 -1138
- package/scripts/lib/pipeline-quality-bash-compat.sh +182 -0
- package/scripts/lib/pipeline-quality-checks.sh +17 -711
- package/scripts/lib/pipeline-quality-gates.sh +563 -0
- package/scripts/lib/pipeline-stages-build.sh +730 -0
- package/scripts/lib/pipeline-stages-delivery.sh +965 -0
- package/scripts/lib/pipeline-stages-intake.sh +1133 -0
- package/scripts/lib/pipeline-stages-monitor.sh +407 -0
- package/scripts/lib/pipeline-stages-review.sh +1022 -0
- package/scripts/lib/pipeline-stages.sh +161 -2901
- package/scripts/lib/pipeline-state.sh +36 -5
- package/scripts/lib/pipeline-util.sh +487 -0
- package/scripts/lib/policy-learner.sh +438 -0
- package/scripts/lib/process-reward.sh +493 -0
- package/scripts/lib/project-detect.sh +649 -0
- package/scripts/lib/quality-profile.sh +334 -0
- package/scripts/lib/recruit-commands.sh +885 -0
- package/scripts/lib/recruit-learning.sh +739 -0
- package/scripts/lib/recruit-roles.sh +648 -0
- package/scripts/lib/reward-aggregator.sh +458 -0
- package/scripts/lib/rl-optimizer.sh +362 -0
- package/scripts/lib/root-cause.sh +427 -0
- package/scripts/lib/scope-enforcement.sh +445 -0
- package/scripts/lib/session-restart.sh +493 -0
- package/scripts/lib/skill-memory.sh +300 -0
- package/scripts/lib/skill-registry.sh +775 -0
- package/scripts/lib/spec-driven.sh +476 -0
- package/scripts/lib/test-helpers.sh +18 -7
- package/scripts/lib/test-holdout.sh +429 -0
- package/scripts/lib/test-optimizer.sh +511 -0
- package/scripts/shipwright-file-suggest.sh +45 -0
- package/scripts/skills/adversarial-quality.md +61 -0
- package/scripts/skills/api-design.md +44 -0
- package/scripts/skills/architecture-design.md +50 -0
- package/scripts/skills/brainstorming.md +43 -0
- package/scripts/skills/data-pipeline.md +44 -0
- package/scripts/skills/deploy-safety.md +64 -0
- package/scripts/skills/documentation.md +38 -0
- package/scripts/skills/frontend-design.md +45 -0
- package/scripts/skills/generated/.gitkeep +0 -0
- package/scripts/skills/generated/_refinements/.gitkeep +0 -0
- package/scripts/skills/generated/_refinements/adversarial-quality.patch.md +3 -0
- package/scripts/skills/generated/_refinements/architecture-design.patch.md +3 -0
- package/scripts/skills/generated/_refinements/brainstorming.patch.md +3 -0
- package/scripts/skills/generated/cli-version-management.md +29 -0
- package/scripts/skills/generated/collection-system-validation.md +99 -0
- package/scripts/skills/generated/large-scale-c-refactoring-coordination.md +97 -0
- package/scripts/skills/generated/pattern-matching-similarity-scoring.md +195 -0
- package/scripts/skills/generated/test-parallelization-detection.md +65 -0
- package/scripts/skills/observability.md +79 -0
- package/scripts/skills/performance.md +48 -0
- package/scripts/skills/pr-quality.md +49 -0
- package/scripts/skills/product-thinking.md +43 -0
- package/scripts/skills/security-audit.md +49 -0
- package/scripts/skills/systematic-debugging.md +40 -0
- package/scripts/skills/testing-strategy.md +47 -0
- package/scripts/skills/two-stage-review.md +52 -0
- package/scripts/skills/validation-thoroughness.md +55 -0
- package/scripts/sw +9 -3
- package/scripts/sw-activity.sh +9 -8
- package/scripts/sw-adaptive.sh +8 -7
- package/scripts/sw-adversarial.sh +2 -1
- package/scripts/sw-architecture-enforcer.sh +3 -1
- package/scripts/sw-auth.sh +12 -2
- package/scripts/sw-autonomous.sh +5 -1
- package/scripts/sw-changelog.sh +4 -1
- package/scripts/sw-checkpoint.sh +2 -1
- package/scripts/sw-ci.sh +15 -6
- package/scripts/sw-cleanup.sh +4 -26
- package/scripts/sw-code-review.sh +45 -20
- package/scripts/sw-connect.sh +2 -1
- package/scripts/sw-context.sh +2 -1
- package/scripts/sw-cost.sh +107 -5
- package/scripts/sw-daemon.sh +71 -11
- package/scripts/sw-dashboard.sh +3 -1
- package/scripts/sw-db.sh +71 -20
- package/scripts/sw-decide.sh +8 -2
- package/scripts/sw-decompose.sh +360 -17
- package/scripts/sw-deps.sh +4 -1
- package/scripts/sw-developer-simulation.sh +4 -1
- package/scripts/sw-discovery.sh +378 -5
- package/scripts/sw-doc-fleet.sh +4 -1
- package/scripts/sw-docs-agent.sh +3 -1
- package/scripts/sw-docs.sh +2 -1
- package/scripts/sw-doctor.sh +453 -2
- package/scripts/sw-dora.sh +4 -1
- package/scripts/sw-durable.sh +12 -7
- package/scripts/sw-e2e-orchestrator.sh +17 -16
- package/scripts/sw-eventbus.sh +13 -4
- package/scripts/sw-evidence.sh +364 -12
- package/scripts/sw-feedback.sh +550 -9
- package/scripts/sw-fix.sh +20 -1
- package/scripts/sw-fleet-discover.sh +6 -2
- package/scripts/sw-fleet-viz.sh +9 -4
- package/scripts/sw-fleet.sh +5 -1
- package/scripts/sw-github-app.sh +18 -4
- package/scripts/sw-github-checks.sh +3 -2
- package/scripts/sw-github-deploy.sh +3 -2
- package/scripts/sw-github-graphql.sh +18 -7
- package/scripts/sw-guild.sh +5 -1
- package/scripts/sw-heartbeat.sh +5 -30
- package/scripts/sw-hello.sh +67 -0
- package/scripts/sw-hygiene.sh +10 -3
- package/scripts/sw-incident.sh +273 -5
- package/scripts/sw-init.sh +18 -2
- package/scripts/sw-instrument.sh +10 -2
- package/scripts/sw-intelligence.sh +44 -7
- package/scripts/sw-jira.sh +5 -1
- package/scripts/sw-launchd.sh +2 -1
- package/scripts/sw-linear.sh +4 -1
- package/scripts/sw-logs.sh +4 -1
- package/scripts/sw-loop.sh +436 -1076
- package/scripts/sw-memory.sh +357 -3
- package/scripts/sw-mission-control.sh +6 -1
- package/scripts/sw-model-router.sh +483 -27
- package/scripts/sw-otel.sh +15 -4
- package/scripts/sw-oversight.sh +14 -5
- package/scripts/sw-patrol-meta.sh +334 -0
- package/scripts/sw-pipeline-composer.sh +7 -1
- package/scripts/sw-pipeline-vitals.sh +12 -6
- package/scripts/sw-pipeline.sh +54 -2653
- package/scripts/sw-pm.sh +16 -8
- package/scripts/sw-pr-lifecycle.sh +2 -1
- package/scripts/sw-predictive.sh +17 -5
- package/scripts/sw-prep.sh +185 -2
- package/scripts/sw-ps.sh +5 -25
- package/scripts/sw-public-dashboard.sh +17 -4
- package/scripts/sw-quality.sh +14 -6
- package/scripts/sw-reaper.sh +8 -25
- package/scripts/sw-recruit.sh +156 -2303
- package/scripts/sw-regression.sh +19 -12
- package/scripts/sw-release-manager.sh +3 -1
- package/scripts/sw-release.sh +4 -1
- package/scripts/sw-remote.sh +3 -1
- package/scripts/sw-replay.sh +7 -1
- package/scripts/sw-retro.sh +158 -1
- package/scripts/sw-review-rerun.sh +3 -1
- package/scripts/sw-scale.sh +14 -5
- package/scripts/sw-security-audit.sh +6 -1
- package/scripts/sw-self-optimize.sh +173 -6
- package/scripts/sw-session.sh +9 -3
- package/scripts/sw-setup.sh +3 -1
- package/scripts/sw-stall-detector.sh +406 -0
- package/scripts/sw-standup.sh +15 -7
- package/scripts/sw-status.sh +3 -1
- package/scripts/sw-strategic.sh +14 -6
- package/scripts/sw-stream.sh +13 -4
- package/scripts/sw-swarm.sh +20 -7
- package/scripts/sw-team-stages.sh +13 -6
- package/scripts/sw-templates.sh +7 -31
- package/scripts/sw-testgen.sh +17 -6
- package/scripts/sw-tmux-pipeline.sh +4 -1
- package/scripts/sw-tmux-role-color.sh +2 -0
- package/scripts/sw-tmux-status.sh +1 -1
- package/scripts/sw-tmux.sh +37 -1
- package/scripts/sw-trace.sh +3 -1
- package/scripts/sw-tracker-github.sh +3 -0
- package/scripts/sw-tracker-jira.sh +3 -0
- package/scripts/sw-tracker-linear.sh +3 -0
- package/scripts/sw-tracker.sh +3 -1
- package/scripts/sw-triage.sh +3 -2
- package/scripts/sw-upgrade.sh +3 -1
- package/scripts/sw-ux.sh +5 -2
- package/scripts/sw-webhook.sh +5 -2
- package/scripts/sw-widgets.sh +9 -4
- package/scripts/sw-worktree.sh +15 -3
- package/scripts/test-skill-injection.sh +1233 -0
- package/templates/pipelines/autonomous.json +27 -3
- package/templates/pipelines/cost-aware.json +34 -8
- package/templates/pipelines/deployed.json +12 -0
- package/templates/pipelines/enterprise.json +12 -0
- package/templates/pipelines/fast.json +6 -0
- package/templates/pipelines/full.json +27 -3
- package/templates/pipelines/hotfix.json +6 -0
- package/templates/pipelines/standard.json +12 -0
- 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
|
+
}
|