shipwright-cli 3.0.0 → 3.1.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 (135) hide show
  1. package/README.md +3 -3
  2. package/completions/_shipwright +247 -93
  3. package/completions/shipwright.bash +69 -15
  4. package/completions/shipwright.fish +309 -41
  5. package/config/decision-tiers.json +55 -0
  6. package/config/event-schema.json +142 -5
  7. package/config/policy.json +8 -0
  8. package/package.json +3 -3
  9. package/scripts/lib/architecture.sh +2 -1
  10. package/scripts/lib/bootstrap.sh +0 -0
  11. package/scripts/lib/config.sh +0 -0
  12. package/scripts/lib/daemon-adaptive.sh +0 -0
  13. package/scripts/lib/daemon-dispatch.sh +24 -1
  14. package/scripts/lib/daemon-failure.sh +0 -0
  15. package/scripts/lib/daemon-health.sh +0 -0
  16. package/scripts/lib/daemon-patrol.sh +40 -5
  17. package/scripts/lib/daemon-poll.sh +17 -0
  18. package/scripts/lib/daemon-state.sh +10 -0
  19. package/scripts/lib/daemon-triage.sh +1 -1
  20. package/scripts/lib/decide-autonomy.sh +295 -0
  21. package/scripts/lib/decide-scoring.sh +228 -0
  22. package/scripts/lib/decide-signals.sh +462 -0
  23. package/scripts/lib/fleet-failover.sh +0 -0
  24. package/scripts/lib/helpers.sh +16 -17
  25. package/scripts/lib/pipeline-detection.sh +0 -0
  26. package/scripts/lib/pipeline-github.sh +0 -0
  27. package/scripts/lib/pipeline-intelligence.sh +20 -3
  28. package/scripts/lib/pipeline-quality-checks.sh +3 -2
  29. package/scripts/lib/pipeline-quality.sh +0 -0
  30. package/scripts/lib/pipeline-stages.sh +199 -32
  31. package/scripts/lib/pipeline-state.sh +14 -0
  32. package/scripts/lib/policy.sh +0 -0
  33. package/scripts/lib/test-helpers.sh +0 -0
  34. package/scripts/postinstall.mjs +75 -1
  35. package/scripts/signals/example-collector.sh +36 -0
  36. package/scripts/sw +8 -4
  37. package/scripts/sw-activity.sh +1 -1
  38. package/scripts/sw-adaptive.sh +1 -1
  39. package/scripts/sw-adversarial.sh +1 -1
  40. package/scripts/sw-architecture-enforcer.sh +1 -1
  41. package/scripts/sw-auth.sh +1 -1
  42. package/scripts/sw-autonomous.sh +1 -1
  43. package/scripts/sw-changelog.sh +1 -1
  44. package/scripts/sw-checkpoint.sh +1 -1
  45. package/scripts/sw-ci.sh +1 -1
  46. package/scripts/sw-cleanup.sh +1 -1
  47. package/scripts/sw-code-review.sh +1 -1
  48. package/scripts/sw-connect.sh +1 -1
  49. package/scripts/sw-context.sh +1 -1
  50. package/scripts/sw-cost.sh +12 -3
  51. package/scripts/sw-daemon.sh +2 -2
  52. package/scripts/sw-dashboard.sh +1 -1
  53. package/scripts/sw-db.sh +41 -34
  54. package/scripts/sw-decide.sh +685 -0
  55. package/scripts/sw-decompose.sh +1 -1
  56. package/scripts/sw-deps.sh +1 -1
  57. package/scripts/sw-developer-simulation.sh +1 -1
  58. package/scripts/sw-discovery.sh +27 -1
  59. package/scripts/sw-doc-fleet.sh +1 -1
  60. package/scripts/sw-docs-agent.sh +1 -1
  61. package/scripts/sw-docs.sh +1 -1
  62. package/scripts/sw-doctor.sh +1 -1
  63. package/scripts/sw-dora.sh +1 -1
  64. package/scripts/sw-durable.sh +1 -1
  65. package/scripts/sw-e2e-orchestrator.sh +1 -1
  66. package/scripts/sw-eventbus.sh +1 -1
  67. package/scripts/sw-evidence.sh +1 -1
  68. package/scripts/sw-feedback.sh +1 -1
  69. package/scripts/sw-fix.sh +1 -1
  70. package/scripts/sw-fleet-discover.sh +1 -1
  71. package/scripts/sw-fleet-viz.sh +1 -1
  72. package/scripts/sw-fleet.sh +1 -1
  73. package/scripts/sw-github-app.sh +1 -1
  74. package/scripts/sw-github-checks.sh +1 -1
  75. package/scripts/sw-github-deploy.sh +1 -1
  76. package/scripts/sw-github-graphql.sh +1 -1
  77. package/scripts/sw-guild.sh +1 -1
  78. package/scripts/sw-heartbeat.sh +1 -1
  79. package/scripts/sw-hygiene.sh +1 -1
  80. package/scripts/sw-incident.sh +1 -1
  81. package/scripts/sw-init.sh +1 -1
  82. package/scripts/sw-instrument.sh +1 -1
  83. package/scripts/sw-intelligence.sh +9 -5
  84. package/scripts/sw-jira.sh +1 -1
  85. package/scripts/sw-launchd.sh +1 -1
  86. package/scripts/sw-linear.sh +1 -1
  87. package/scripts/sw-logs.sh +1 -1
  88. package/scripts/sw-loop.sh +267 -17
  89. package/scripts/sw-memory.sh +22 -5
  90. package/scripts/sw-mission-control.sh +1 -1
  91. package/scripts/sw-model-router.sh +1 -1
  92. package/scripts/sw-otel.sh +5 -3
  93. package/scripts/sw-oversight.sh +1 -1
  94. package/scripts/sw-pipeline-composer.sh +1 -1
  95. package/scripts/sw-pipeline-vitals.sh +1 -1
  96. package/scripts/sw-pipeline.sh +73 -1
  97. package/scripts/sw-pm.sh +1 -1
  98. package/scripts/sw-pr-lifecycle.sh +7 -4
  99. package/scripts/sw-predictive.sh +1 -1
  100. package/scripts/sw-prep.sh +1 -1
  101. package/scripts/sw-ps.sh +1 -1
  102. package/scripts/sw-public-dashboard.sh +1 -1
  103. package/scripts/sw-quality.sh +9 -5
  104. package/scripts/sw-reaper.sh +1 -1
  105. package/scripts/sw-regression.sh +1 -1
  106. package/scripts/sw-release-manager.sh +1 -1
  107. package/scripts/sw-release.sh +1 -1
  108. package/scripts/sw-remote.sh +1 -1
  109. package/scripts/sw-replay.sh +1 -1
  110. package/scripts/sw-retro.sh +1 -1
  111. package/scripts/sw-review-rerun.sh +1 -1
  112. package/scripts/sw-scale.sh +66 -10
  113. package/scripts/sw-security-audit.sh +1 -1
  114. package/scripts/sw-self-optimize.sh +1 -1
  115. package/scripts/sw-session.sh +3 -3
  116. package/scripts/sw-setup.sh +1 -1
  117. package/scripts/sw-standup.sh +1 -1
  118. package/scripts/sw-status.sh +1 -1
  119. package/scripts/sw-strategic.sh +1 -1
  120. package/scripts/sw-stream.sh +1 -1
  121. package/scripts/sw-swarm.sh +1 -1
  122. package/scripts/sw-team-stages.sh +1 -1
  123. package/scripts/sw-templates.sh +1 -1
  124. package/scripts/sw-testgen.sh +1 -1
  125. package/scripts/sw-tmux-pipeline.sh +1 -1
  126. package/scripts/sw-tmux.sh +1 -1
  127. package/scripts/sw-trace.sh +1 -1
  128. package/scripts/sw-tracker.sh +1 -1
  129. package/scripts/sw-triage.sh +6 -6
  130. package/scripts/sw-upgrade.sh +1 -1
  131. package/scripts/sw-ux.sh +1 -1
  132. package/scripts/sw-webhook.sh +1 -1
  133. package/scripts/sw-widgets.sh +1 -1
  134. package/scripts/sw-worktree.sh +1 -1
  135. package/scripts/update-homebrew-sha.sh +21 -15
@@ -15,12 +15,15 @@
15
15
  "required": ["job_id"],
16
16
  "optional": ["error", "stage"]
17
17
  },
18
- "stage.started": { "required": ["job_id", "stage"], "optional": [] },
18
+ "stage.started": { "required": ["stage"], "optional": ["issue", "job_id"] },
19
19
  "stage.completed": {
20
- "required": ["job_id", "stage"],
21
- "optional": ["duration_s"]
20
+ "required": ["stage"],
21
+ "optional": ["issue", "job_id", "duration_s", "result"]
22
+ },
23
+ "stage.failed": {
24
+ "required": ["stage"],
25
+ "optional": ["issue", "job_id", "error", "error_class", "duration_s"]
22
26
  },
23
- "stage.failed": { "required": ["job_id", "stage"], "optional": ["error"] },
24
27
  "daemon.started": { "required": [], "optional": ["pid", "mode"] },
25
28
  "daemon.stopped": { "required": [], "optional": ["reason"] },
26
29
  "daemon.claimed": { "required": ["issue"], "optional": ["repo", "title"] },
@@ -76,6 +79,140 @@
76
79
  "required": ["session_id"],
77
80
  "optional": ["template", "agents"]
78
81
  },
79
- "session.ended": { "required": ["session_id"], "optional": ["duration_s"] }
82
+ "session.ended": { "required": ["session_id"], "optional": ["duration_s"] },
83
+ "memory.fix_outcome": {
84
+ "required": ["pattern"],
85
+ "optional": ["outcome", "repo"]
86
+ },
87
+ "memory.global_aggregated": {
88
+ "required": [],
89
+ "optional": ["repo", "patterns_promoted"]
90
+ },
91
+ "memory.not_available": {
92
+ "required": ["path"],
93
+ "optional": ["action"]
94
+ },
95
+ "memory.export": {
96
+ "required": [],
97
+ "optional": ["repo"]
98
+ },
99
+ "cost.budget_unconfigured": {
100
+ "required": ["status"],
101
+ "optional": []
102
+ },
103
+ "scale.recommendation": {
104
+ "required": [],
105
+ "optional": ["iterations", "coverage", "modules", "has_recommendations"]
106
+ },
107
+ "pr.skipped": {
108
+ "required": ["issue"],
109
+ "optional": ["reason"]
110
+ },
111
+ "pr.rejected": {
112
+ "required": ["issue"],
113
+ "optional": ["reason"]
114
+ },
115
+ "intelligence.compose": {
116
+ "required": [],
117
+ "optional": ["stage_count", "complexity"]
118
+ },
119
+ "intelligence.synthesize": {
120
+ "required": [],
121
+ "optional": ["fix_count", "cause_count"]
122
+ },
123
+ "simulation.complete": {
124
+ "required": [],
125
+ "optional": ["issue", "concerns"]
126
+ },
127
+ "daemon.hard_limit": {
128
+ "required": ["issue"],
129
+ "optional": ["elapsed_s", "limit_s", "pid"]
130
+ },
131
+ "daemon.stalled": {
132
+ "required": ["issue"],
133
+ "optional": ["no_progress", "elapsed_s", "pid"]
134
+ },
135
+ "daemon.nudge": {
136
+ "required": ["issue"],
137
+ "optional": ["no_progress", "stage", "elapsed_s"]
138
+ },
139
+ "daemon.stuck_kill": {
140
+ "required": ["issue"],
141
+ "optional": [
142
+ "no_progress",
143
+ "repeated_errors",
144
+ "stage",
145
+ "elapsed_s",
146
+ "pid",
147
+ "reason"
148
+ ]
149
+ },
150
+ "convergence.tests_passed": {
151
+ "required": [],
152
+ "optional": ["issue", "cycle"]
153
+ },
154
+ "vitals.snapshot": {
155
+ "required": [],
156
+ "optional": [
157
+ "issue",
158
+ "stage",
159
+ "iteration",
160
+ "diff_count",
161
+ "files_changed",
162
+ "error"
163
+ ]
164
+ },
165
+ "retry.classified": {
166
+ "required": ["stage"],
167
+ "optional": ["issue", "attempt", "error_class"]
168
+ },
169
+ "retry.escalated": {
170
+ "required": ["stage"],
171
+ "optional": ["issue", "reason"]
172
+ },
173
+ "retry.skipped": {
174
+ "required": ["stage"],
175
+ "optional": ["issue", "reason"]
176
+ },
177
+ "pipeline.anomaly": {
178
+ "required": ["stage"],
179
+ "optional": ["metric", "value", "severity"]
180
+ },
181
+ "pipeline.cost": {
182
+ "required": [],
183
+ "optional": ["issue", "stage", "cost_usd", "model"]
184
+ },
185
+ "pipeline.cleanup": {
186
+ "required": [],
187
+ "optional": ["issue", "reason"]
188
+ },
189
+ "pipeline.comment_failed": {
190
+ "required": [],
191
+ "optional": ["issue"]
192
+ },
193
+ "loop.iteration_start": {
194
+ "required": ["iteration"],
195
+ "optional": ["issue", "goal"]
196
+ },
197
+ "loop.iteration_complete": {
198
+ "required": ["iteration"],
199
+ "optional": ["issue", "test_result", "duration_s"]
200
+ },
201
+ "loop.restart": {
202
+ "required": [],
203
+ "optional": ["issue", "restart_count", "reason"]
204
+ },
205
+ "loop.stuckness_detected": {
206
+ "required": [],
207
+ "optional": ["issue", "iteration", "reason"]
208
+ },
209
+ "stage.skipped": {
210
+ "required": ["stage"],
211
+ "optional": ["issue", "reason"]
212
+ },
213
+ "stage.artifact_miss": {
214
+ "required": ["stage"],
215
+ "optional": ["issue"]
216
+ }
80
217
  }
81
218
  }
@@ -222,5 +222,13 @@
222
222
  "default_model": "sonnet",
223
223
  "promote_threshold_tasks": 10,
224
224
  "promote_threshold_success_rate": 85
225
+ },
226
+ "decision": {
227
+ "enabled": false,
228
+ "cycle_interval_seconds": 1800,
229
+ "tiers_file": "config/decision-tiers.json",
230
+ "outcome_learning_enabled": true,
231
+ "outcome_min_samples": 10,
232
+ "dedup_window_days": 7
225
233
  }
226
234
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shipwright-cli",
3
- "version": "3.0.0",
3
+ "version": "3.1.0",
4
4
  "description": "Orchestrate autonomous Claude Code agent teams in tmux",
5
5
  "bin": {
6
6
  "shipwright": "scripts/sw",
@@ -36,9 +36,9 @@
36
36
  "dashboard:test": "vitest run --config dashboard/vitest.config.ts",
37
37
  "dashboard:test:watch": "vitest --config dashboard/vitest.config.ts",
38
38
  "dashboard:test:coverage": "vitest run --config dashboard/vitest.config.ts --coverage",
39
- "test": "bash scripts/sw-agi-roadmap-test.sh && bash scripts/sw-activity-test.sh && bash scripts/sw-adaptive-test.sh && bash scripts/sw-adversarial-test.sh && bash scripts/sw-architecture-enforcer-test.sh && bash scripts/sw-auth-test.sh && bash scripts/sw-autonomous-test.sh && bash scripts/sw-changelog-test.sh && bash scripts/sw-checkpoint-test.sh && bash scripts/sw-ci-test.sh && bash scripts/sw-cleanup-test.sh && bash scripts/sw-code-review-test.sh && bash scripts/sw-connect-test.sh && bash scripts/sw-context-test.sh && bash scripts/sw-cost-test.sh && bash scripts/sw-daemon-test.sh && bash scripts/sw-dashboard-test.sh && bash scripts/sw-db-test.sh && bash scripts/sw-decompose-test.sh && bash scripts/sw-deps-test.sh && bash scripts/sw-developer-simulation-test.sh && bash scripts/sw-discovery-test.sh && bash scripts/sw-doc-fleet-test.sh && bash scripts/sw-docs-agent-test.sh && bash scripts/sw-docs-test.sh && bash scripts/sw-doctor-test.sh && bash scripts/sw-dora-test.sh && bash scripts/sw-durable-test.sh && bash scripts/sw-e2e-orchestrator-test.sh && bash scripts/sw-eventbus-test.sh && bash scripts/sw-feedback-test.sh && bash scripts/sw-fix-test.sh && bash scripts/sw-fleet-discover-test.sh && bash scripts/sw-fleet-test.sh && bash scripts/sw-fleet-viz-test.sh && bash scripts/sw-frontier-test.sh && bash scripts/sw-github-app-test.sh && bash scripts/sw-github-checks-test.sh && bash scripts/sw-github-deploy-test.sh && bash scripts/sw-github-graphql-test.sh && bash scripts/sw-guild-test.sh && bash scripts/sw-heartbeat-test.sh && bash scripts/sw-hygiene-test.sh && bash scripts/sw-incident-test.sh && bash scripts/sw-init-test.sh && bash scripts/sw-instrument-test.sh && bash scripts/sw-intelligence-test.sh && bash scripts/sw-jira-test.sh && bash scripts/sw-launchd-test.sh && bash scripts/sw-linear-test.sh && bash scripts/sw-logs-test.sh && bash scripts/sw-loop-test.sh && bash scripts/sw-memory-test.sh && bash scripts/sw-mission-control-test.sh && bash scripts/sw-model-router-test.sh && bash scripts/sw-otel-test.sh && bash scripts/sw-oversight-test.sh && bash scripts/sw-patrol-meta-test.sh && bash scripts/sw-pipeline-composer-test.sh && bash scripts/sw-pipeline-test.sh && bash scripts/sw-pipeline-vitals-test.sh && bash scripts/sw-pm-test.sh && bash scripts/sw-pr-lifecycle-test.sh && bash scripts/sw-predictive-test.sh && bash scripts/sw-prep-test.sh && bash scripts/sw-ps-test.sh && bash scripts/sw-public-dashboard-test.sh && bash scripts/sw-quality-test.sh && bash scripts/sw-reaper-test.sh && bash scripts/sw-recruit-test.sh && bash scripts/sw-regression-test.sh && bash scripts/sw-release-manager-test.sh && bash scripts/sw-release-test.sh && bash scripts/sw-remote-test.sh && bash scripts/sw-replay-test.sh && bash scripts/sw-retro-test.sh && bash scripts/sw-scale-test.sh && bash scripts/sw-security-audit-test.sh && bash scripts/sw-self-optimize-test.sh && bash scripts/sw-session-test.sh && bash scripts/sw-setup-test.sh && bash scripts/sw-standup-test.sh && bash scripts/sw-status-test.sh && bash scripts/sw-strategic-test.sh && bash scripts/sw-stream-test.sh && bash scripts/sw-swarm-test.sh && bash scripts/sw-team-stages-test.sh && bash scripts/sw-templates-test.sh && bash scripts/sw-testgen-test.sh && bash scripts/sw-tmux-pipeline-test.sh && bash scripts/sw-tmux-test.sh && bash scripts/sw-trace-test.sh && bash scripts/sw-tracker-test.sh && bash scripts/sw-triage-test.sh && bash scripts/sw-upgrade-test.sh && bash scripts/sw-ux-test.sh && bash scripts/sw-webhook-test.sh && bash scripts/sw-widgets-test.sh && bash scripts/sw-worktree-test.sh && bash scripts/sw-policy-e2e-test.sh && bash scripts/sw-e2e-smoke-test.sh && bash scripts/sw-dashboard-e2e-test.sh",
39
+ "test": "bash scripts/sw-agi-roadmap-test.sh && bash scripts/sw-activity-test.sh && bash scripts/sw-adaptive-test.sh && bash scripts/sw-adversarial-test.sh && bash scripts/sw-architecture-enforcer-test.sh && bash scripts/sw-auth-test.sh && bash scripts/sw-autonomous-test.sh && bash scripts/sw-changelog-test.sh && bash scripts/sw-checkpoint-test.sh && bash scripts/sw-ci-test.sh && bash scripts/sw-cleanup-test.sh && bash scripts/sw-code-review-test.sh && bash scripts/sw-connect-test.sh && bash scripts/sw-context-test.sh && bash scripts/sw-cost-test.sh && bash scripts/sw-daemon-test.sh && bash scripts/sw-dashboard-test.sh && bash scripts/sw-db-test.sh && bash scripts/sw-decompose-test.sh && bash scripts/sw-decide-test.sh && bash scripts/sw-deps-test.sh && bash scripts/sw-developer-simulation-test.sh && bash scripts/sw-discovery-test.sh && bash scripts/sw-doc-fleet-test.sh && bash scripts/sw-docs-agent-test.sh && bash scripts/sw-docs-test.sh && bash scripts/sw-doctor-test.sh && bash scripts/sw-dora-test.sh && bash scripts/sw-durable-test.sh && bash scripts/sw-e2e-orchestrator-test.sh && bash scripts/sw-eventbus-test.sh && bash scripts/sw-feedback-test.sh && bash scripts/sw-fix-test.sh && bash scripts/sw-fleet-discover-test.sh && bash scripts/sw-fleet-test.sh && bash scripts/sw-fleet-viz-test.sh && bash scripts/sw-frontier-test.sh && bash scripts/sw-github-app-test.sh && bash scripts/sw-github-checks-test.sh && bash scripts/sw-github-deploy-test.sh && bash scripts/sw-github-graphql-test.sh && bash scripts/sw-guild-test.sh && bash scripts/sw-heartbeat-test.sh && bash scripts/sw-hygiene-test.sh && bash scripts/sw-incident-test.sh && bash scripts/sw-init-test.sh && bash scripts/sw-instrument-test.sh && bash scripts/sw-intelligence-test.sh && bash scripts/sw-jira-test.sh && bash scripts/sw-launchd-test.sh && bash scripts/sw-linear-test.sh && bash scripts/sw-logs-test.sh && bash scripts/sw-loop-test.sh && bash scripts/sw-memory-test.sh && bash scripts/sw-mission-control-test.sh && bash scripts/sw-model-router-test.sh && bash scripts/sw-otel-test.sh && bash scripts/sw-oversight-test.sh && bash scripts/sw-patrol-meta-test.sh && bash scripts/sw-pipeline-composer-test.sh && bash scripts/sw-pipeline-test.sh && bash scripts/sw-pipeline-vitals-test.sh && bash scripts/sw-pm-test.sh && bash scripts/sw-pr-lifecycle-test.sh && bash scripts/sw-predictive-test.sh && bash scripts/sw-prep-test.sh && bash scripts/sw-ps-test.sh && bash scripts/sw-public-dashboard-test.sh && bash scripts/sw-quality-test.sh && bash scripts/sw-reaper-test.sh && bash scripts/sw-recruit-test.sh && bash scripts/sw-regression-test.sh && bash scripts/sw-release-manager-test.sh && bash scripts/sw-release-test.sh && bash scripts/sw-remote-test.sh && bash scripts/sw-replay-test.sh && bash scripts/sw-retro-test.sh && bash scripts/sw-scale-test.sh && bash scripts/sw-security-audit-test.sh && bash scripts/sw-self-optimize-test.sh && bash scripts/sw-session-test.sh && bash scripts/sw-setup-test.sh && bash scripts/sw-standup-test.sh && bash scripts/sw-status-test.sh && bash scripts/sw-strategic-test.sh && bash scripts/sw-stream-test.sh && bash scripts/sw-swarm-test.sh && bash scripts/sw-team-stages-test.sh && bash scripts/sw-templates-test.sh && bash scripts/sw-testgen-test.sh && bash scripts/sw-tmux-pipeline-test.sh && bash scripts/sw-tmux-test.sh && bash scripts/sw-trace-test.sh && bash scripts/sw-tracker-test.sh && bash scripts/sw-triage-test.sh && bash scripts/sw-upgrade-test.sh && bash scripts/sw-ux-test.sh && bash scripts/sw-webhook-test.sh && bash scripts/sw-widgets-test.sh && bash scripts/sw-worktree-test.sh && bash scripts/sw-lib-compat-test.sh && bash scripts/sw-lib-helpers-test.sh && bash scripts/sw-lib-daemon-dispatch-test.sh && bash scripts/sw-lib-daemon-failure-test.sh && bash scripts/sw-lib-daemon-poll-test.sh && bash scripts/sw-lib-daemon-state-test.sh && bash scripts/sw-lib-daemon-triage-test.sh && bash scripts/sw-lib-pipeline-detection-test.sh && bash scripts/sw-lib-pipeline-intelligence-test.sh && bash scripts/sw-lib-pipeline-quality-checks-test.sh && bash scripts/sw-lib-pipeline-stages-test.sh && bash scripts/sw-lib-pipeline-state-test.sh && bash scripts/sw-adapters-test.sh && bash scripts/sw-evidence-test.sh && bash scripts/sw-review-rerun-test.sh && bash scripts/sw-tracker-providers-test.sh && bash scripts/sw-budget-chaos-test.sh && bash scripts/sw-autonomous-e2e-test.sh && bash scripts/sw-memory-discovery-e2e-test.sh && bash scripts/sw-policy-e2e-test.sh && bash scripts/sw-e2e-smoke-test.sh && bash scripts/sw-dashboard-e2e-test.sh",
40
40
  "test:smoke": "bash scripts/sw-e2e-smoke-test.sh",
41
- "test:integration": "bash scripts/sw-e2e-integration-test.sh",
41
+ "test:integration": "bash scripts/sw-e2e-integration-test.sh && bash scripts/sw-e2e-system-test.sh && bash scripts/sw-server-api-test.sh && bash scripts/sw-integration-claude-test.sh",
42
42
  "harness:evidence:capture": "bash scripts/sw-evidence.sh capture",
43
43
  "harness:evidence:verify": "bash scripts/sw-evidence.sh verify",
44
44
  "harness:evidence:pre-pr": "bash scripts/sw-evidence.sh pre-pr",
@@ -45,7 +45,8 @@ $(find "$repo_root" -type f \( -name '*.ts' -o -name '*.js' -o -name '*.py' -o -
45
45
  while IFS= read -r f; do
46
46
  [[ -f "$f" ]] || continue
47
47
  local exports=0
48
- exports=$(grep -c "^export " "$f" 2>/dev/null || echo "0")
48
+ exports=$(grep -c "^export " "$f" 2>/dev/null || true)
49
+ exports="${exports:-0}"
49
50
  [[ "$exports" -gt 2 ]] 2>/dev/null && context="${context} $(basename "$f"): $exports exports
50
51
  "
51
52
  done < <(find "$repo_root/src" "$repo_root/lib" -name "*.ts" -o -name "*.js" 2>/dev/null | head -30)
File without changes
File without changes
File without changes
@@ -282,7 +282,30 @@ daemon_reap_completed() {
282
282
 
283
283
  # Check if process is still running
284
284
  if kill -0 "$pid" 2>/dev/null; then
285
- continue
285
+ # Guard against PID reuse: if job has been running > 6 hours and
286
+ # the process tree doesn't contain sw-pipeline/sw-loop, it's stale
287
+ local _started_at _start_e _age_s
288
+ _started_at=$(echo "$job" | jq -r '.started_at // empty')
289
+ if [[ -n "$_started_at" ]]; then
290
+ _start_e=$(TZ=UTC date -j -f "%Y-%m-%dT%H:%M:%SZ" "$_started_at" +%s 2>/dev/null || date -d "$_started_at" +%s 2>/dev/null || echo "0")
291
+ _age_s=$(( $(now_epoch) - ${_start_e:-0} ))
292
+ if [[ "$_age_s" -gt 21600 ]]; then # 6 hours
293
+ # Verify this PID is actually our pipeline (not a reused PID)
294
+ local _proc_cmd
295
+ _proc_cmd=$(ps -p "$pid" -o command= 2>/dev/null || true)
296
+ if [[ -z "$_proc_cmd" ]] || ! echo "$_proc_cmd" | grep -qE 'sw-pipeline|sw-loop|claude' 2>/dev/null; then
297
+ daemon_log WARN "Stale job #${issue_num}: PID $pid running ${_age_s}s but not a pipeline process — force-reaping"
298
+ emit_event "daemon.stale_dead" "issue=$issue_num" "pid=$pid" "elapsed_s=$_age_s"
299
+ # Fall through to reap logic
300
+ else
301
+ continue
302
+ fi
303
+ else
304
+ continue
305
+ fi
306
+ else
307
+ continue
308
+ fi
286
309
  fi
287
310
 
288
311
  # Process is dead — determine exit code
File without changes
File without changes
@@ -3,6 +3,28 @@
3
3
  [[ -n "${_DAEMON_PATROL_LOADED:-}" ]] && return 0
4
4
  _DAEMON_PATROL_LOADED=1
5
5
 
6
+ # ─── Decision Engine Signal Mode ─────────────────────────────────────────────
7
+ # When DECISION_ENGINE_ENABLED=true, patrol writes candidates to the pending
8
+ # signals file instead of creating GitHub issues directly. The decision engine
9
+ # collects, scores, and acts on these signals with tiered autonomy.
10
+ SIGNALS_PENDING_FILE="${HOME}/.shipwright/signals/pending.jsonl"
11
+
12
+ _patrol_emit_signal() {
13
+ local id="$1" signal="$2" category="$3" title="$4" description="$5"
14
+ local risk="${6:-50}" confidence="${7:-0.80}" dedup_key="$8"
15
+ mkdir -p "$(dirname "$SIGNALS_PENDING_FILE")"
16
+ local ts
17
+ ts=$(now_iso)
18
+ local candidate
19
+ candidate=$(jq -n \
20
+ --arg id "$id" --arg signal "$signal" --arg category "$category" \
21
+ --arg title "$title" --arg desc "$description" \
22
+ --argjson risk "$risk" --arg conf "$confidence" \
23
+ --arg dedup "$dedup_key" --arg ts "$ts" \
24
+ '{id:$id, signal:$signal, category:$category, title:$title, description:$desc, evidence:{}, risk_score:$risk, confidence:$conf, dedup_key:$dedup, collected_at:$ts}')
25
+ echo "$candidate" >> "$SIGNALS_PENDING_FILE"
26
+ }
27
+
6
28
  patrol_build_labels() {
7
29
  local check_label="$1"
8
30
  local labels="${PATROL_LABEL},${check_label}"
@@ -76,8 +98,16 @@ daemon_patrol() {
76
98
  findings=$((findings + 1))
77
99
  emit_event "patrol.finding" "check=security" "severity=$severity" "package=$name"
78
100
 
79
- # Check if issue already exists
80
- if [[ "$NO_GITHUB" != "true" ]] && [[ "$dry_run" != "true" ]]; then
101
+ # Route to decision engine or create issue directly
102
+ if [[ "${DECISION_ENGINE_ENABLED:-false}" == "true" ]]; then
103
+ local _cat="security_patch"
104
+ [[ "$severity" == "critical" ]] && _cat="security_critical"
105
+ _patrol_emit_signal "sec-${name}" "security" "$_cat" \
106
+ "Security: ${title} in ${name}" \
107
+ "Fix ${severity} vulnerability in ${name}" \
108
+ "$([[ "$severity" == "critical" ]] && echo 80 || echo 50)" \
109
+ "0.95" "security:${name}:${title}"
110
+ elif [[ "$NO_GITHUB" != "true" ]] && [[ "$dry_run" != "true" ]]; then
81
111
  local existing
82
112
  existing=$(gh issue list --label "$PATROL_LABEL" --label "security" \
83
113
  --search "Security: $name" --json number -q 'length' 2>/dev/null || echo "0")
@@ -202,8 +232,13 @@ Auto-detected by \`shipwright daemon patrol\`." \
202
232
  fi
203
233
  done < <(echo "$outdated_json" | jq -c 'to_entries[]' 2>/dev/null)
204
234
 
205
- # Create a single issue for all stale deps
206
- if [[ "$findings" -gt 0 ]] && [[ "$NO_GITHUB" != "true" ]] && [[ "$dry_run" != "true" ]]; then
235
+ # Route to decision engine or create issue
236
+ if [[ "$findings" -gt 0 ]] && [[ "${DECISION_ENGINE_ENABLED:-false}" == "true" ]]; then
237
+ _patrol_emit_signal "deps-stale-${findings}" "deps" "deps_major" \
238
+ "Update ${findings} stale dependencies" \
239
+ "Packages 2+ major versions behind" \
240
+ 45 "0.90" "deps:stale:${findings}"
241
+ elif [[ "$findings" -gt 0 ]] && [[ "$NO_GITHUB" != "true" ]] && [[ "$dry_run" != "true" ]]; then
207
242
  local existing
208
243
  existing=$(gh issue list --label "$PATROL_LABEL" --label "dependencies" \
209
244
  --search "Stale dependencies" --json number -q 'length' 2>/dev/null || echo "0")
@@ -814,7 +849,7 @@ Auto-detected by \`shipwright daemon patrol\` on $(now_iso)." \
814
849
  if [[ ! -f "$scripts_dir/sw-${name}-test.sh" ]]; then
815
850
  # Count usage across other scripts
816
851
  local usage_count
817
- usage_count=$(grep -rl "sw-${name}" "$scripts_dir"/sw-*.sh 2>/dev/null | grep -cv "$basename" 2>/dev/null || echo "0")
852
+ usage_count=$(grep -rl "sw-${name}" "$scripts_dir"/sw-*.sh 2>/dev/null | grep -cv "$basename" 2>/dev/null || true)
818
853
  usage_count=${usage_count:-0}
819
854
 
820
855
  local line_count
@@ -1196,6 +1196,23 @@ daemon_poll_loop() {
1196
1196
  daemon_patrol --once || daemon_log WARN "daemon_patrol failed — continuing"
1197
1197
  LAST_PATROL_EPOCH=$now_e
1198
1198
  fi
1199
+
1200
+ # Decision engine cycle (if enabled)
1201
+ local _decision_enabled
1202
+ _decision_enabled=$(policy_get ".decision.enabled" "false" 2>/dev/null || echo "false")
1203
+ if [[ "$_decision_enabled" == "true" ]]; then
1204
+ local _decision_interval
1205
+ _decision_interval=$(policy_get ".decision.cycle_interval_seconds" "1800" 2>/dev/null || echo "1800")
1206
+ local _last_decision_epoch="${_LAST_DECISION_EPOCH:-0}"
1207
+ if [[ $((now_e - _last_decision_epoch)) -ge "$_decision_interval" ]]; then
1208
+ daemon_log INFO "Running decision engine cycle"
1209
+ if [[ -f "$SCRIPT_DIR/sw-decide.sh" ]]; then
1210
+ DECISION_ENGINE_ENABLED=true bash "$SCRIPT_DIR/sw-decide.sh" run --once 2>/dev/null || \
1211
+ daemon_log WARN "Decision engine cycle failed — continuing"
1212
+ fi
1213
+ _LAST_DECISION_EPOCH=$now_e
1214
+ fi
1215
+ fi
1199
1216
  fi
1200
1217
 
1201
1218
  # ── Adaptive poll interval: adjust sleep based on queue state ──
@@ -390,6 +390,16 @@ init_state() {
390
390
  atomic_write_state "$init_json"
391
391
  ) 200>"$lock_file"
392
392
  else
393
+ # Validate existing state file JSON before using it
394
+ if ! jq '.' "$STATE_FILE" >/dev/null 2>&1; then
395
+ daemon_log WARN "Corrupted state file detected — backing up and resetting"
396
+ cp "$STATE_FILE" "${STATE_FILE}.corrupted.$(date +%s)" 2>/dev/null || true
397
+ rm -f "$STATE_FILE"
398
+ # Re-initialize as fresh state (recursive call with file removed)
399
+ init_state
400
+ return
401
+ fi
402
+
393
403
  # Update PID and start time in existing state
394
404
  locked_state_update \
395
405
  --arg pid "$$" \
@@ -250,7 +250,7 @@ select_pipeline_template() {
250
250
  _dora_events=$(tail -500 "${EVENTS_FILE:-$HOME/.shipwright/events.jsonl}" \
251
251
  | grep '"type":"pipeline.completed"' 2>/dev/null \
252
252
  | tail -5 || true)
253
- _dora_total=$(echo "$_dora_events" | grep -c '.' 2>/dev/null || echo "0")
253
+ _dora_total=$(echo "$_dora_events" | grep -c '.' 2>/dev/null || true)
254
254
  _dora_total="${_dora_total:-0}"
255
255
  if [[ "$_dora_total" -ge 3 ]]; then
256
256
  _dora_failures=$(echo "$_dora_events" | grep -c '"result":"failure"' 2>/dev/null || true)