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.
Files changed (283) 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 +22 -8
  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/config/defaults.json +25 -2
  17. package/config/policy.json +1 -1
  18. package/dashboard/middleware/auth.ts +134 -0
  19. package/dashboard/middleware/constants.ts +21 -0
  20. package/dashboard/public/index.html +8 -6
  21. package/dashboard/public/styles.css +176 -97
  22. package/dashboard/routes/auth.ts +38 -0
  23. package/dashboard/server.ts +117 -25
  24. package/dashboard/services/config.ts +26 -0
  25. package/dashboard/services/db.ts +118 -0
  26. package/dashboard/src/canvas/pixel-agent.ts +298 -0
  27. package/dashboard/src/canvas/pixel-sprites.ts +440 -0
  28. package/dashboard/src/canvas/shipyard-effects.ts +367 -0
  29. package/dashboard/src/canvas/shipyard-scene.ts +616 -0
  30. package/dashboard/src/canvas/submarine-layout.ts +267 -0
  31. package/dashboard/src/components/header.ts +8 -7
  32. package/dashboard/src/core/api.ts +5 -0
  33. package/dashboard/src/core/router.ts +1 -0
  34. package/dashboard/src/design/submarine-theme.ts +253 -0
  35. package/dashboard/src/main.ts +2 -0
  36. package/dashboard/src/types/api.ts +12 -1
  37. package/dashboard/src/views/activity.ts +2 -1
  38. package/dashboard/src/views/metrics.ts +69 -1
  39. package/dashboard/src/views/shipyard.ts +39 -0
  40. package/dashboard/types/index.ts +166 -0
  41. package/docs/plans/2026-02-28-compound-audit-and-shipyard-design.md +186 -0
  42. package/docs/plans/2026-02-28-skipper-shipwright-implementation-plan.md +1182 -0
  43. package/docs/plans/2026-02-28-skipper-shipwright-integration-design.md +531 -0
  44. package/docs/plans/2026-03-01-ai-powered-skill-injection-design.md +298 -0
  45. package/docs/plans/2026-03-01-ai-powered-skill-injection-plan.md +1109 -0
  46. package/docs/plans/2026-03-01-capabilities-cleanup-plan.md +658 -0
  47. package/docs/plans/2026-03-01-clean-architecture-plan.md +924 -0
  48. package/docs/plans/2026-03-01-compound-audit-cascade-design.md +191 -0
  49. package/docs/plans/2026-03-01-compound-audit-cascade-plan.md +921 -0
  50. package/docs/plans/2026-03-01-deep-integration-plan.md +851 -0
  51. package/docs/plans/2026-03-01-pipeline-audit-trail-design.md +145 -0
  52. package/docs/plans/2026-03-01-pipeline-audit-trail-plan.md +770 -0
  53. package/docs/plans/2026-03-01-refined-depths-brand-design.md +382 -0
  54. package/docs/plans/2026-03-01-refined-depths-implementation.md +599 -0
  55. package/docs/plans/2026-03-01-skipper-kernel-integration-design.md +203 -0
  56. package/docs/plans/2026-03-01-unified-platform-design.md +272 -0
  57. package/docs/plans/2026-03-07-claude-code-feature-integration-design.md +189 -0
  58. package/docs/plans/2026-03-07-claude-code-feature-integration-plan.md +1165 -0
  59. package/docs/research/BACKLOG_QUICK_REFERENCE.md +352 -0
  60. package/docs/research/CUTTING_EDGE_RESEARCH_2026.md +546 -0
  61. package/docs/research/RESEARCH_INDEX.md +439 -0
  62. package/docs/research/RESEARCH_SOURCES.md +440 -0
  63. package/docs/research/RESEARCH_SUMMARY.txt +275 -0
  64. package/docs/superpowers/specs/2026-03-10-pipeline-quality-revolution-design.md +341 -0
  65. package/package.json +2 -2
  66. package/scripts/lib/adaptive-model.sh +427 -0
  67. package/scripts/lib/adaptive-timeout.sh +316 -0
  68. package/scripts/lib/audit-trail.sh +309 -0
  69. package/scripts/lib/auto-recovery.sh +471 -0
  70. package/scripts/lib/bandit-selector.sh +431 -0
  71. package/scripts/lib/bootstrap.sh +104 -2
  72. package/scripts/lib/causal-graph.sh +455 -0
  73. package/scripts/lib/compat.sh +126 -0
  74. package/scripts/lib/compound-audit.sh +337 -0
  75. package/scripts/lib/constitutional.sh +454 -0
  76. package/scripts/lib/context-budget.sh +359 -0
  77. package/scripts/lib/convergence.sh +594 -0
  78. package/scripts/lib/cost-optimizer.sh +634 -0
  79. package/scripts/lib/daemon-adaptive.sh +14 -2
  80. package/scripts/lib/daemon-dispatch.sh +106 -17
  81. package/scripts/lib/daemon-failure.sh +34 -4
  82. package/scripts/lib/daemon-patrol.sh +25 -4
  83. package/scripts/lib/daemon-poll-github.sh +361 -0
  84. package/scripts/lib/daemon-poll-health.sh +299 -0
  85. package/scripts/lib/daemon-poll.sh +27 -611
  86. package/scripts/lib/daemon-state.sh +119 -66
  87. package/scripts/lib/daemon-triage.sh +10 -0
  88. package/scripts/lib/dod-scorecard.sh +442 -0
  89. package/scripts/lib/error-actionability.sh +300 -0
  90. package/scripts/lib/formal-spec.sh +461 -0
  91. package/scripts/lib/helpers.sh +180 -5
  92. package/scripts/lib/intent-analysis.sh +409 -0
  93. package/scripts/lib/loop-convergence.sh +350 -0
  94. package/scripts/lib/loop-iteration.sh +682 -0
  95. package/scripts/lib/loop-progress.sh +48 -0
  96. package/scripts/lib/loop-restart.sh +185 -0
  97. package/scripts/lib/memory-effectiveness.sh +506 -0
  98. package/scripts/lib/mutation-executor.sh +352 -0
  99. package/scripts/lib/outcome-feedback.sh +521 -0
  100. package/scripts/lib/pipeline-cli.sh +336 -0
  101. package/scripts/lib/pipeline-commands.sh +1216 -0
  102. package/scripts/lib/pipeline-detection.sh +101 -3
  103. package/scripts/lib/pipeline-execution.sh +897 -0
  104. package/scripts/lib/pipeline-github.sh +28 -3
  105. package/scripts/lib/pipeline-intelligence-compound.sh +431 -0
  106. package/scripts/lib/pipeline-intelligence-scoring.sh +407 -0
  107. package/scripts/lib/pipeline-intelligence-skip.sh +181 -0
  108. package/scripts/lib/pipeline-intelligence.sh +104 -1138
  109. package/scripts/lib/pipeline-quality-bash-compat.sh +182 -0
  110. package/scripts/lib/pipeline-quality-checks.sh +17 -711
  111. package/scripts/lib/pipeline-quality-gates.sh +563 -0
  112. package/scripts/lib/pipeline-stages-build.sh +730 -0
  113. package/scripts/lib/pipeline-stages-delivery.sh +965 -0
  114. package/scripts/lib/pipeline-stages-intake.sh +1133 -0
  115. package/scripts/lib/pipeline-stages-monitor.sh +407 -0
  116. package/scripts/lib/pipeline-stages-review.sh +1022 -0
  117. package/scripts/lib/pipeline-stages.sh +161 -2901
  118. package/scripts/lib/pipeline-state.sh +36 -5
  119. package/scripts/lib/pipeline-util.sh +487 -0
  120. package/scripts/lib/policy-learner.sh +438 -0
  121. package/scripts/lib/process-reward.sh +493 -0
  122. package/scripts/lib/project-detect.sh +649 -0
  123. package/scripts/lib/quality-profile.sh +334 -0
  124. package/scripts/lib/recruit-commands.sh +885 -0
  125. package/scripts/lib/recruit-learning.sh +739 -0
  126. package/scripts/lib/recruit-roles.sh +648 -0
  127. package/scripts/lib/reward-aggregator.sh +458 -0
  128. package/scripts/lib/rl-optimizer.sh +362 -0
  129. package/scripts/lib/root-cause.sh +427 -0
  130. package/scripts/lib/scope-enforcement.sh +445 -0
  131. package/scripts/lib/session-restart.sh +493 -0
  132. package/scripts/lib/skill-memory.sh +300 -0
  133. package/scripts/lib/skill-registry.sh +775 -0
  134. package/scripts/lib/spec-driven.sh +476 -0
  135. package/scripts/lib/test-helpers.sh +18 -7
  136. package/scripts/lib/test-holdout.sh +429 -0
  137. package/scripts/lib/test-optimizer.sh +511 -0
  138. package/scripts/shipwright-file-suggest.sh +45 -0
  139. package/scripts/skills/adversarial-quality.md +61 -0
  140. package/scripts/skills/api-design.md +44 -0
  141. package/scripts/skills/architecture-design.md +50 -0
  142. package/scripts/skills/brainstorming.md +43 -0
  143. package/scripts/skills/data-pipeline.md +44 -0
  144. package/scripts/skills/deploy-safety.md +64 -0
  145. package/scripts/skills/documentation.md +38 -0
  146. package/scripts/skills/frontend-design.md +45 -0
  147. package/scripts/skills/generated/.gitkeep +0 -0
  148. package/scripts/skills/generated/_refinements/.gitkeep +0 -0
  149. package/scripts/skills/generated/_refinements/adversarial-quality.patch.md +3 -0
  150. package/scripts/skills/generated/_refinements/architecture-design.patch.md +3 -0
  151. package/scripts/skills/generated/_refinements/brainstorming.patch.md +3 -0
  152. package/scripts/skills/generated/cli-version-management.md +29 -0
  153. package/scripts/skills/generated/collection-system-validation.md +99 -0
  154. package/scripts/skills/generated/large-scale-c-refactoring-coordination.md +97 -0
  155. package/scripts/skills/generated/pattern-matching-similarity-scoring.md +195 -0
  156. package/scripts/skills/generated/test-parallelization-detection.md +65 -0
  157. package/scripts/skills/observability.md +79 -0
  158. package/scripts/skills/performance.md +48 -0
  159. package/scripts/skills/pr-quality.md +49 -0
  160. package/scripts/skills/product-thinking.md +43 -0
  161. package/scripts/skills/security-audit.md +49 -0
  162. package/scripts/skills/systematic-debugging.md +40 -0
  163. package/scripts/skills/testing-strategy.md +47 -0
  164. package/scripts/skills/two-stage-review.md +52 -0
  165. package/scripts/skills/validation-thoroughness.md +55 -0
  166. package/scripts/sw +9 -3
  167. package/scripts/sw-activity.sh +9 -8
  168. package/scripts/sw-adaptive.sh +8 -7
  169. package/scripts/sw-adversarial.sh +2 -1
  170. package/scripts/sw-architecture-enforcer.sh +3 -1
  171. package/scripts/sw-auth.sh +12 -2
  172. package/scripts/sw-autonomous.sh +5 -1
  173. package/scripts/sw-changelog.sh +4 -1
  174. package/scripts/sw-checkpoint.sh +2 -1
  175. package/scripts/sw-ci.sh +15 -6
  176. package/scripts/sw-cleanup.sh +4 -26
  177. package/scripts/sw-code-review.sh +45 -20
  178. package/scripts/sw-connect.sh +2 -1
  179. package/scripts/sw-context.sh +2 -1
  180. package/scripts/sw-cost.sh +107 -5
  181. package/scripts/sw-daemon.sh +71 -11
  182. package/scripts/sw-dashboard.sh +3 -1
  183. package/scripts/sw-db.sh +71 -20
  184. package/scripts/sw-decide.sh +8 -2
  185. package/scripts/sw-decompose.sh +360 -17
  186. package/scripts/sw-deps.sh +4 -1
  187. package/scripts/sw-developer-simulation.sh +4 -1
  188. package/scripts/sw-discovery.sh +378 -5
  189. package/scripts/sw-doc-fleet.sh +4 -1
  190. package/scripts/sw-docs-agent.sh +3 -1
  191. package/scripts/sw-docs.sh +2 -1
  192. package/scripts/sw-doctor.sh +453 -2
  193. package/scripts/sw-dora.sh +4 -1
  194. package/scripts/sw-durable.sh +12 -7
  195. package/scripts/sw-e2e-orchestrator.sh +17 -16
  196. package/scripts/sw-eventbus.sh +13 -4
  197. package/scripts/sw-evidence.sh +364 -12
  198. package/scripts/sw-feedback.sh +550 -9
  199. package/scripts/sw-fix.sh +20 -1
  200. package/scripts/sw-fleet-discover.sh +6 -2
  201. package/scripts/sw-fleet-viz.sh +9 -4
  202. package/scripts/sw-fleet.sh +5 -1
  203. package/scripts/sw-github-app.sh +18 -4
  204. package/scripts/sw-github-checks.sh +3 -2
  205. package/scripts/sw-github-deploy.sh +3 -2
  206. package/scripts/sw-github-graphql.sh +18 -7
  207. package/scripts/sw-guild.sh +5 -1
  208. package/scripts/sw-heartbeat.sh +5 -30
  209. package/scripts/sw-hello.sh +67 -0
  210. package/scripts/sw-hygiene.sh +10 -3
  211. package/scripts/sw-incident.sh +273 -5
  212. package/scripts/sw-init.sh +18 -2
  213. package/scripts/sw-instrument.sh +10 -2
  214. package/scripts/sw-intelligence.sh +44 -7
  215. package/scripts/sw-jira.sh +5 -1
  216. package/scripts/sw-launchd.sh +2 -1
  217. package/scripts/sw-linear.sh +4 -1
  218. package/scripts/sw-logs.sh +4 -1
  219. package/scripts/sw-loop.sh +436 -1076
  220. package/scripts/sw-memory.sh +357 -3
  221. package/scripts/sw-mission-control.sh +6 -1
  222. package/scripts/sw-model-router.sh +483 -27
  223. package/scripts/sw-otel.sh +15 -4
  224. package/scripts/sw-oversight.sh +14 -5
  225. package/scripts/sw-patrol-meta.sh +334 -0
  226. package/scripts/sw-pipeline-composer.sh +7 -1
  227. package/scripts/sw-pipeline-vitals.sh +12 -6
  228. package/scripts/sw-pipeline.sh +54 -2653
  229. package/scripts/sw-pm.sh +16 -8
  230. package/scripts/sw-pr-lifecycle.sh +2 -1
  231. package/scripts/sw-predictive.sh +17 -5
  232. package/scripts/sw-prep.sh +185 -2
  233. package/scripts/sw-ps.sh +5 -25
  234. package/scripts/sw-public-dashboard.sh +17 -4
  235. package/scripts/sw-quality.sh +14 -6
  236. package/scripts/sw-reaper.sh +8 -25
  237. package/scripts/sw-recruit.sh +156 -2303
  238. package/scripts/sw-regression.sh +19 -12
  239. package/scripts/sw-release-manager.sh +3 -1
  240. package/scripts/sw-release.sh +4 -1
  241. package/scripts/sw-remote.sh +3 -1
  242. package/scripts/sw-replay.sh +7 -1
  243. package/scripts/sw-retro.sh +158 -1
  244. package/scripts/sw-review-rerun.sh +3 -1
  245. package/scripts/sw-scale.sh +14 -5
  246. package/scripts/sw-security-audit.sh +6 -1
  247. package/scripts/sw-self-optimize.sh +173 -6
  248. package/scripts/sw-session.sh +9 -3
  249. package/scripts/sw-setup.sh +3 -1
  250. package/scripts/sw-stall-detector.sh +406 -0
  251. package/scripts/sw-standup.sh +15 -7
  252. package/scripts/sw-status.sh +3 -1
  253. package/scripts/sw-strategic.sh +14 -6
  254. package/scripts/sw-stream.sh +13 -4
  255. package/scripts/sw-swarm.sh +20 -7
  256. package/scripts/sw-team-stages.sh +13 -6
  257. package/scripts/sw-templates.sh +7 -31
  258. package/scripts/sw-testgen.sh +17 -6
  259. package/scripts/sw-tmux-pipeline.sh +4 -1
  260. package/scripts/sw-tmux-role-color.sh +2 -0
  261. package/scripts/sw-tmux-status.sh +1 -1
  262. package/scripts/sw-tmux.sh +37 -1
  263. package/scripts/sw-trace.sh +3 -1
  264. package/scripts/sw-tracker-github.sh +3 -0
  265. package/scripts/sw-tracker-jira.sh +3 -0
  266. package/scripts/sw-tracker-linear.sh +3 -0
  267. package/scripts/sw-tracker.sh +3 -1
  268. package/scripts/sw-triage.sh +3 -2
  269. package/scripts/sw-upgrade.sh +3 -1
  270. package/scripts/sw-ux.sh +5 -2
  271. package/scripts/sw-webhook.sh +5 -2
  272. package/scripts/sw-widgets.sh +9 -4
  273. package/scripts/sw-worktree.sh +15 -3
  274. package/scripts/test-skill-injection.sh +1233 -0
  275. package/templates/pipelines/autonomous.json +27 -3
  276. package/templates/pipelines/cost-aware.json +34 -8
  277. package/templates/pipelines/deployed.json +12 -0
  278. package/templates/pipelines/enterprise.json +12 -0
  279. package/templates/pipelines/fast.json +6 -0
  280. package/templates/pipelines/full.json +27 -3
  281. package/templates/pipelines/hotfix.json +6 -0
  282. package/templates/pipelines/standard.json +12 -0
  283. package/templates/pipelines/tdd.json +12 -0
@@ -3,6 +3,28 @@
3
3
  [[ -n "${_PIPELINE_GITHUB_LOADED:-}" ]] && return 0
4
4
  _PIPELINE_GITHUB_LOADED=1
5
5
 
6
+ # Defaults for variables normally set by sw-pipeline.sh (safe under set -u).
7
+ NO_GITHUB="${NO_GITHUB:-false}"
8
+ GOAL="${GOAL:-}"
9
+ PIPELINE_NAME="${PIPELINE_NAME:-pipeline}"
10
+ PIPELINE_CONFIG="${PIPELINE_CONFIG:-}"
11
+ GIT_BRANCH="${GIT_BRANCH:-}"
12
+ PIPELINE_START_EPOCH="${PIPELINE_START_EPOCH:-}"
13
+ ARTIFACTS_DIR="${ARTIFACTS_DIR:-.claude/pipeline-artifacts}"
14
+ GH_AVAILABLE="${GH_AVAILABLE:-false}"
15
+ REPO_OWNER="${REPO_OWNER:-}"
16
+ REPO_NAME="${REPO_NAME:-}"
17
+ PROGRESS_COMMENT_ID="${PROGRESS_COMMENT_ID:-}"
18
+
19
+ # ─── Markdown Escaping ───────────────────────────────────────────────
20
+ # Escape markdown special characters to prevent injection
21
+ escape_markdown() {
22
+ local text="$1"
23
+ # Escape ], [, (, ), *, _, \, `, #, -, +, .
24
+ # This prevents markdown syntax injection in GitHub comments
25
+ echo "$text" | sed 's/\([\\`*_\[\]()#+\-\.!]\)/\\\1/g'
26
+ }
27
+
6
28
  gh_init() {
7
29
  if [[ "$NO_GITHUB" == "true" ]]; then
8
30
  GH_AVAILABLE=false
@@ -107,9 +129,12 @@ gh_get_issue_meta() {
107
129
  # Build a progress table for GitHub comment
108
130
  # Usage: gh_build_progress_body
109
131
  gh_build_progress_body() {
132
+ local escaped_goal
133
+ escaped_goal=$(escape_markdown "${GOAL}")
134
+
110
135
  local body="## 🤖 Pipeline Progress — \`${PIPELINE_NAME}\`
111
136
 
112
- **Delivering:** ${GOAL}
137
+ **Delivering:** ${escaped_goal}
113
138
 
114
139
  | Stage | Status | Duration | |
115
140
  |-------|--------|----------|-|"
@@ -118,8 +143,8 @@ gh_build_progress_body() {
118
143
  stages=$(jq -c '.stages[]' "$PIPELINE_CONFIG" 2>/dev/null)
119
144
  while IFS= read -r -u 3 stage; do
120
145
  local id enabled
121
- id=$(echo "$stage" | jq -r '.id')
122
- enabled=$(echo "$stage" | jq -r '.enabled')
146
+ id=$(echo "$stage" | jq -r '.id' 2>/dev/null) || id=""
147
+ enabled=$(echo "$stage" | jq -r '.enabled' 2>/dev/null) || enabled=""
123
148
 
124
149
  if [[ "$enabled" != "true" ]]; then
125
150
  body="${body}
@@ -0,0 +1,431 @@
1
+ # pipeline-intelligence-compound.sh — DoD/security/compound audit for pipeline-intelligence.sh
2
+ # Source from pipeline-intelligence.sh. Requires state, ARTIFACTS_DIR.
3
+ [[ -n "${_PIPELINE_INTELLIGENCE_COMPOUND_LOADED:-}" ]] && return 0
4
+ _PIPELINE_INTELLIGENCE_COMPOUND_LOADED=1
5
+
6
+ # Defaults for variables normally set by sw-pipeline.sh (safe under set -u).
7
+ ARTIFACTS_DIR="${ARTIFACTS_DIR:-.claude/pipeline-artifacts}"
8
+ SCRIPT_DIR="${SCRIPT_DIR:-$(cd "$(dirname "${BASH_SOURCE[0]}")/.."/bin/pwd)}"
9
+ NO_GITHUB="${NO_GITHUB:-false}"
10
+
11
+ pipeline_verify_dod() {
12
+ local artifacts_dir="${1:-$ARTIFACTS_DIR}"
13
+ local checks_total=0 checks_passed=0
14
+ local results=""
15
+
16
+ # 1. Test coverage: verify changed source files have test counterparts
17
+ local changed_files
18
+ changed_files=$(git diff --name-only "${BASE_BRANCH:-main}...HEAD" 2>/dev/null || true)
19
+ local missing_tests=""
20
+ local files_checked=0
21
+
22
+ if [[ -n "$changed_files" ]]; then
23
+ while IFS= read -r src_file; do
24
+ [[ -z "$src_file" ]] && continue
25
+ # Only check source code files
26
+ case "$src_file" in
27
+ *.ts|*.js|*.tsx|*.jsx|*.py|*.go|*.rs|*.sh)
28
+ # Skip test files themselves and config files
29
+ case "$src_file" in
30
+ *test*|*spec*|*__tests__*|*.config.*|*.d.ts) continue ;;
31
+ esac
32
+ files_checked=$((files_checked + 1))
33
+ checks_total=$((checks_total + 1))
34
+ # Check for corresponding test file
35
+ local base_name dir_name ext
36
+ base_name=$(basename "$src_file")
37
+ dir_name=$(dirname "$src_file")
38
+ ext="${base_name##*.}"
39
+ local stem="${base_name%.*}"
40
+ local test_found=false
41
+ # Common test file patterns
42
+ for pattern in \
43
+ "${dir_name}/${stem}.test.${ext}" \
44
+ "${dir_name}/${stem}.spec.${ext}" \
45
+ "${dir_name}/__tests__/${stem}.test.${ext}" \
46
+ "${dir_name}/${stem}-test.${ext}" \
47
+ "${dir_name}/test_${stem}.${ext}" \
48
+ "${dir_name}/${stem}_test.${ext}"; do
49
+ if [[ -f "$pattern" ]]; then
50
+ test_found=true
51
+ break
52
+ fi
53
+ done
54
+ if $test_found; then
55
+ checks_passed=$((checks_passed + 1))
56
+ else
57
+ missing_tests="${missing_tests}${src_file}\n"
58
+ fi
59
+ ;;
60
+ esac
61
+ done <<EOF
62
+ $changed_files
63
+ EOF
64
+ fi
65
+
66
+ # 2. Test-added verification: if significant logic added, ensure tests were also added
67
+ local logic_lines=0 test_lines=0
68
+ if [[ -n "$changed_files" ]]; then
69
+ local full_diff
70
+ full_diff=$(git diff "${BASE_BRANCH:-main}...HEAD" 2>/dev/null || true)
71
+ if [[ -n "$full_diff" ]]; then
72
+ # Count added lines matching source patterns (rough heuristic)
73
+ logic_lines=$(echo "$full_diff" | grep -cE '^\+.*(function |class |if |for |while |return |export )' 2>/dev/null || true)
74
+ logic_lines="${logic_lines:-0}"
75
+ # Count added lines in test files
76
+ test_lines=$(echo "$full_diff" | grep -cE '^\+.*(it\(|test\(|describe\(|expect\(|assert|def test_|func Test)' 2>/dev/null || true)
77
+ test_lines="${test_lines:-0}"
78
+ fi
79
+ fi
80
+ checks_total=$((checks_total + 1))
81
+ local test_ratio_passed=true
82
+ if [[ "$logic_lines" -gt 20 && "$test_lines" -eq 0 ]]; then
83
+ test_ratio_passed=false
84
+ warn "DoD verification: ${logic_lines} logic lines added but no test lines detected"
85
+ else
86
+ checks_passed=$((checks_passed + 1))
87
+ fi
88
+
89
+ # 3. Behavioral verification: check DoD audit artifacts for evidence
90
+ local dod_audit_file="$artifacts_dir/dod-audit.md"
91
+ local dod_verified=0 dod_total_items=0
92
+ if [[ -f "$dod_audit_file" ]]; then
93
+ # Count items marked as passing
94
+ dod_total_items=$(grep -cE '^\s*-\s*\[x\]' "$dod_audit_file" 2>/dev/null || true)
95
+ dod_total_items="${dod_total_items:-0}"
96
+ local dod_failing
97
+ dod_failing=$(grep -cE '^\s*-\s*\[\s\]' "$dod_audit_file" 2>/dev/null || true)
98
+ dod_failing="${dod_failing:-0}"
99
+ dod_verified=$dod_total_items
100
+ checks_total=$((checks_total + dod_total_items + ${dod_failing:-0}))
101
+ checks_passed=$((checks_passed + dod_total_items))
102
+ fi
103
+
104
+ # Compute pass rate
105
+ local pass_rate=100
106
+ if [[ "$checks_total" -gt 0 ]]; then
107
+ pass_rate=$(( (checks_passed * 100) / checks_total ))
108
+ fi
109
+
110
+ # Write results
111
+ local tmp_result
112
+ tmp_result=$(mktemp)
113
+ jq -n \
114
+ --argjson checks_total "$checks_total" \
115
+ --argjson checks_passed "$checks_passed" \
116
+ --argjson pass_rate "$pass_rate" \
117
+ --argjson files_checked "$files_checked" \
118
+ --arg missing_tests "$(echo -e "$missing_tests" | head -20)" \
119
+ --argjson logic_lines "$logic_lines" \
120
+ --argjson test_lines "$test_lines" \
121
+ --argjson test_ratio_passed "$test_ratio_passed" \
122
+ --argjson dod_verified "$dod_verified" \
123
+ '{
124
+ checks_total: $checks_total,
125
+ checks_passed: $checks_passed,
126
+ pass_rate: $pass_rate,
127
+ files_checked: $files_checked,
128
+ missing_tests: ($missing_tests | split("\n") | map(select(. != ""))),
129
+ logic_lines: $logic_lines,
130
+ test_lines: $test_lines,
131
+ test_ratio_passed: $test_ratio_passed,
132
+ dod_verified: $dod_verified
133
+ }' > "$tmp_result" 2>/dev/null
134
+ mv "$tmp_result" "$artifacts_dir/dod-verification.json"
135
+
136
+ emit_event "pipeline.dod_verification" \
137
+ "issue=${ISSUE_NUMBER:-0}" \
138
+ "checks_total=$checks_total" \
139
+ "checks_passed=$checks_passed" \
140
+ "pass_rate=$pass_rate"
141
+
142
+ # Fail if pass rate < 70%
143
+ if [[ "$pass_rate" -lt 70 ]]; then
144
+ warn "DoD verification: ${pass_rate}% pass rate (${checks_passed}/${checks_total} checks)"
145
+ return 1
146
+ fi
147
+
148
+ success "DoD verification: ${pass_rate}% pass rate (${checks_passed}/${checks_total} checks)"
149
+ return 0
150
+ }
151
+
152
+ # ──────────────────────────────────────────────────────────────────────────────
153
+ # 7. Source Code Security Scan
154
+ # Grep-based vulnerability pattern matching on changed files.
155
+
156
+ pipeline_security_source_scan() {
157
+ local base_branch="${1:-${BASE_BRANCH:-main}}"
158
+ local findings="[]"
159
+ local finding_count=0
160
+
161
+ local changed_files
162
+ changed_files=$(git diff --name-only "${base_branch}...HEAD" 2>/dev/null || true)
163
+ [[ -z "$changed_files" ]] && { echo "[]"; return 0; }
164
+
165
+ local tmp_findings
166
+ tmp_findings=$(mktemp)
167
+ echo "[]" > "$tmp_findings"
168
+
169
+ while IFS= read -r file; do
170
+ [[ -z "$file" || ! -f "$file" ]] && continue
171
+ # Only scan code files
172
+ case "$file" in
173
+ *.ts|*.js|*.tsx|*.jsx|*.py|*.go|*.rs|*.java|*.rb|*.php|*.sh) ;;
174
+ *) continue ;;
175
+ esac
176
+
177
+ # SQL injection patterns
178
+ local sql_matches
179
+ sql_matches=$(grep -nE '(query|execute|sql)\s*\(?\s*[`"'"'"']\s*.*\$\{|\.query\s*\(\s*[`"'"'"'].*\+' "$file" 2>/dev/null || true)
180
+ if [[ -n "$sql_matches" ]]; then
181
+ while IFS= read -r match; do
182
+ [[ -z "$match" ]] && continue
183
+ local line_num="${match%%:*}"
184
+ finding_count=$((finding_count + 1))
185
+ local current
186
+ current=$(cat "$tmp_findings")
187
+ echo "$current" | jq --arg f "$file" --arg l "$line_num" --arg p "sql_injection" \
188
+ '. + [{"file":$f,"line":($l|tonumber),"pattern":$p,"severity":"critical","description":"Potential SQL injection via string concatenation"}]' \
189
+ > "$tmp_findings" 2>/dev/null || true
190
+ done <<SQLEOF
191
+ $sql_matches
192
+ SQLEOF
193
+ fi
194
+
195
+ # XSS patterns
196
+ local xss_matches
197
+ xss_matches=$(grep -nE 'innerHTML\s*=|document\.write\s*\(|dangerouslySetInnerHTML' "$file" 2>/dev/null || true)
198
+ if [[ -n "$xss_matches" ]]; then
199
+ while IFS= read -r match; do
200
+ [[ -z "$match" ]] && continue
201
+ local line_num="${match%%:*}"
202
+ finding_count=$((finding_count + 1))
203
+ local current
204
+ current=$(cat "$tmp_findings")
205
+ echo "$current" | jq --arg f "$file" --arg l "$line_num" --arg p "xss" \
206
+ '. + [{"file":$f,"line":($l|tonumber),"pattern":$p,"severity":"critical","description":"Potential XSS via unsafe DOM manipulation"}]' \
207
+ > "$tmp_findings" 2>/dev/null || true
208
+ done <<XSSEOF
209
+ $xss_matches
210
+ XSSEOF
211
+ fi
212
+
213
+ # Command injection patterns
214
+ local cmd_matches
215
+ cmd_matches=$(grep -nE 'eval\s*\(|child_process|os\.system\s*\(|subprocess\.(call|run|Popen)\s*\(' "$file" 2>/dev/null || true)
216
+ if [[ -n "$cmd_matches" ]]; then
217
+ while IFS= read -r match; do
218
+ [[ -z "$match" ]] && continue
219
+ local line_num="${match%%:*}"
220
+ finding_count=$((finding_count + 1))
221
+ local current
222
+ current=$(cat "$tmp_findings")
223
+ echo "$current" | jq --arg f "$file" --arg l "$line_num" --arg p "command_injection" \
224
+ '. + [{"file":$f,"line":($l|tonumber),"pattern":$p,"severity":"critical","description":"Potential command injection via unsafe execution"}]' \
225
+ > "$tmp_findings" 2>/dev/null || true
226
+ done <<CMDEOF
227
+ $cmd_matches
228
+ CMDEOF
229
+ fi
230
+
231
+ # Hardcoded secrets patterns
232
+ local secret_matches
233
+ secret_matches=$(grep -nEi '(password|api_key|secret|token)\s*=\s*['"'"'"][A-Za-z0-9+/=]{8,}['"'"'"]' "$file" 2>/dev/null || true)
234
+ if [[ -n "$secret_matches" ]]; then
235
+ while IFS= read -r match; do
236
+ [[ -z "$match" ]] && continue
237
+ local line_num="${match%%:*}"
238
+ finding_count=$((finding_count + 1))
239
+ local current
240
+ current=$(cat "$tmp_findings")
241
+ echo "$current" | jq --arg f "$file" --arg l "$line_num" --arg p "hardcoded_secret" \
242
+ '. + [{"file":$f,"line":($l|tonumber),"pattern":$p,"severity":"critical","description":"Potential hardcoded secret or credential"}]' \
243
+ > "$tmp_findings" 2>/dev/null || true
244
+ done <<SECEOF
245
+ $secret_matches
246
+ SECEOF
247
+ fi
248
+
249
+ # Insecure crypto patterns
250
+ local crypto_matches
251
+ crypto_matches=$(grep -nE '(md5|MD5|sha1|SHA1)\s*\(' "$file" 2>/dev/null || true)
252
+ if [[ -n "$crypto_matches" ]]; then
253
+ while IFS= read -r match; do
254
+ [[ -z "$match" ]] && continue
255
+ local line_num="${match%%:*}"
256
+ finding_count=$((finding_count + 1))
257
+ local current
258
+ current=$(cat "$tmp_findings")
259
+ echo "$current" | jq --arg f "$file" --arg l "$line_num" --arg p "insecure_crypto" \
260
+ '. + [{"file":$f,"line":($l|tonumber),"pattern":$p,"severity":"major","description":"Weak cryptographic function (consider SHA-256+)"}]' \
261
+ > "$tmp_findings" 2>/dev/null || true
262
+ done <<CRYEOF
263
+ $crypto_matches
264
+ CRYEOF
265
+ fi
266
+ done <<FILESEOF
267
+ $changed_files
268
+ FILESEOF
269
+
270
+ # Write to artifacts and output
271
+ findings=$(cat "$tmp_findings")
272
+ rm -f "$tmp_findings"
273
+
274
+ if [[ -n "${ARTIFACTS_DIR:-}" ]]; then
275
+ local tmp_scan
276
+ tmp_scan=$(mktemp)
277
+ echo "$findings" > "$tmp_scan"
278
+ mv "$tmp_scan" "$ARTIFACTS_DIR/security-source-scan.json"
279
+ fi
280
+
281
+ emit_event "pipeline.security_source_scan" \
282
+ "issue=${ISSUE_NUMBER:-0}" \
283
+ "findings=$finding_count"
284
+
285
+ echo "$finding_count"
286
+ }
287
+
288
+ # ──────────────────────────────────────────────────────────────────────────────
289
+ # 8. Quality Score Recording
290
+ # Writes quality scores to JSONL for learning.
291
+
292
+ compound_rebuild_with_feedback() {
293
+ local feedback_file="$ARTIFACTS_DIR/quality-feedback.md"
294
+
295
+ # ── Intelligence: classify findings and determine routing ──
296
+ local route="correctness"
297
+ route=$(classify_quality_findings 2>/dev/null) || route="correctness"
298
+
299
+ # ── Build structured findings JSON alongside markdown ──
300
+ local structured_findings="[]"
301
+ local s_total_critical=0 s_total_major=0 s_total_minor=0
302
+
303
+ if [[ -f "$ARTIFACTS_DIR/classified-findings.json" ]]; then
304
+ s_total_critical=$(jq -r '.security // 0' "$ARTIFACTS_DIR/classified-findings.json" 2>/dev/null || echo "0")
305
+ s_total_major=$(jq -r '.correctness // 0' "$ARTIFACTS_DIR/classified-findings.json" 2>/dev/null || echo "0")
306
+ s_total_minor=$(jq -r '.style // 0' "$ARTIFACTS_DIR/classified-findings.json" 2>/dev/null || echo "0")
307
+ fi
308
+
309
+ local tmp_qf
310
+ tmp_qf="$(mktemp)"
311
+ jq -n \
312
+ --arg route "$route" \
313
+ --argjson total_critical "$s_total_critical" \
314
+ --argjson total_major "$s_total_major" \
315
+ --argjson total_minor "$s_total_minor" \
316
+ '{route: $route, total_critical: $total_critical, total_major: $total_major, total_minor: $total_minor}' \
317
+ > "$tmp_qf" 2>/dev/null && mv "$tmp_qf" "$ARTIFACTS_DIR/quality-findings.json" || rm -f "$tmp_qf"
318
+
319
+ # ── Architecture route: backtrack to design instead of rebuild ──
320
+ if [[ "$route" == "architecture" ]]; then
321
+ info "Architecture-level findings detected — attempting backtrack to design"
322
+ if pipeline_backtrack_to_stage "design" "architecture_violation" 2>/dev/null; then
323
+ return 0
324
+ fi
325
+ # Backtrack failed or already used — fall through to standard rebuild
326
+ warn "Backtrack unavailable — falling through to standard rebuild"
327
+ fi
328
+
329
+ # Collect all findings (prioritized by classification)
330
+ {
331
+ echo "# Quality Feedback — Issues to Fix"
332
+ echo ""
333
+
334
+ # Security findings first (highest priority)
335
+ if [[ "$route" == "security" || -f "$ARTIFACTS_DIR/security-audit.log" ]] && grep -qiE 'critical|high' "$ARTIFACTS_DIR/security-audit.log" 2>/dev/null; then
336
+ echo "## 🔴 PRIORITY: Security Findings (fix these first)"
337
+ cat "$ARTIFACTS_DIR/security-audit.log"
338
+ echo ""
339
+ echo "Security issues MUST be resolved before any other changes."
340
+ echo ""
341
+ fi
342
+
343
+ # Correctness findings
344
+ if [[ -f "$ARTIFACTS_DIR/adversarial-review.md" ]]; then
345
+ echo "## Adversarial Review Findings"
346
+ cat "$ARTIFACTS_DIR/adversarial-review.md"
347
+ echo ""
348
+ fi
349
+ if [[ -f "$ARTIFACTS_DIR/negative-review.md" ]]; then
350
+ echo "## Negative Prompting Concerns"
351
+ cat "$ARTIFACTS_DIR/negative-review.md"
352
+ echo ""
353
+ fi
354
+ if [[ -f "$ARTIFACTS_DIR/dod-audit.md" ]]; then
355
+ echo "## DoD Audit Failures"
356
+ grep "❌" "$ARTIFACTS_DIR/dod-audit.md" 2>/dev/null || true
357
+ echo ""
358
+ fi
359
+ if [[ -f "$ARTIFACTS_DIR/api-compat.log" ]] && grep -qi 'BREAKING' "$ARTIFACTS_DIR/api-compat.log" 2>/dev/null; then
360
+ echo "## API Breaking Changes"
361
+ cat "$ARTIFACTS_DIR/api-compat.log"
362
+ echo ""
363
+ fi
364
+
365
+ # Style findings last (deprioritized, informational)
366
+ if [[ -f "$ARTIFACTS_DIR/classified-findings.json" ]]; then
367
+ local style_count
368
+ style_count=$(jq -r '.style // 0' "$ARTIFACTS_DIR/classified-findings.json" 2>/dev/null || echo "0")
369
+ if [[ "$style_count" -gt 0 ]]; then
370
+ echo "## Style Notes (non-blocking, address if time permits)"
371
+ echo "${style_count} style suggestions found. These do not block the build."
372
+ echo ""
373
+ fi
374
+ fi
375
+ } > "$feedback_file"
376
+
377
+ # Validate feedback file has actual content
378
+ if [[ ! -s "$feedback_file" ]]; then
379
+ warn "No quality feedback collected — skipping rebuild"
380
+ return 1
381
+ fi
382
+
383
+ # Reset build/test stages
384
+ set_stage_status "build" "pending"
385
+ set_stage_status "test" "pending"
386
+ set_stage_status "review" "pending"
387
+
388
+ # Augment GOAL with quality feedback (route-specific instructions)
389
+ local original_goal="$GOAL"
390
+ local feedback_content
391
+ feedback_content=$(cat "$feedback_file")
392
+
393
+ local route_instruction=""
394
+ case "$route" in
395
+ security)
396
+ route_instruction="SECURITY PRIORITY: Fix all security vulnerabilities FIRST, then address other issues. Security issues are BLOCKING."
397
+ ;;
398
+ performance)
399
+ route_instruction="PERFORMANCE PRIORITY: Address performance regressions and optimizations. Check for N+1 queries, memory leaks, and algorithmic complexity."
400
+ ;;
401
+ testing)
402
+ route_instruction="TESTING PRIORITY: Add missing test coverage and fix flaky tests before addressing other issues."
403
+ ;;
404
+ correctness)
405
+ route_instruction="Fix every issue listed above while keeping all existing functionality working."
406
+ ;;
407
+ architecture)
408
+ route_instruction="ARCHITECTURE: Fix structural issues. Check dependency direction, layer boundaries, and separation of concerns."
409
+ ;;
410
+ *)
411
+ route_instruction="Fix every issue listed above while keeping all existing functionality working."
412
+ ;;
413
+ esac
414
+
415
+ GOAL="$GOAL
416
+
417
+ IMPORTANT — Compound quality review found issues (route: ${route}). Fix ALL of these:
418
+ $feedback_content
419
+
420
+ ${route_instruction}"
421
+
422
+ # Re-run self-healing build→test
423
+ info "Rebuilding with quality feedback (route: ${route})..."
424
+ if self_healing_build_test; then
425
+ GOAL="$original_goal"
426
+ return 0
427
+ else
428
+ GOAL="$original_goal"
429
+ return 1
430
+ fi
431
+ }