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
@@ -0,0 +1,506 @@
1
+ #!/usr/bin/env bash
2
+ # ╔═══════════════════════════════════════════════════════════════════════════╗
3
+ # ║ Memory Pattern Effectiveness Tracker — proactive failure prevention ║
4
+ # ║ Scores memory patterns · Ranks by effectiveness · Prunes ineffective ║
5
+ # ╚═══════════════════════════════════════════════════════════════════════════╝
6
+
7
+ # Module guard
8
+ [[ -n "${_MEMEFF_LOADED:-}" ]] && return 0
9
+ _MEMEFF_LOADED=1
10
+ set -euo pipefail
11
+
12
+ VERSION="3.3.0"
13
+
14
+ # ─── Helpers (loaded from parent context) ───────────────────────────────────
15
+ # Expects: info(), success(), warn(), error(), emit_event(), now_iso()
16
+ # If not available, provide fallbacks
17
+
18
+ [[ "$(type -t info 2>/dev/null)" == "function" ]] || info() { echo -e "\033[38;2;0;212;255m\033[1m▸\033[0m $*"; }
19
+ [[ "$(type -t success 2>/dev/null)" == "function" ]] || success() { echo -e "\033[38;2;74;222;128m\033[1m✓\033[0m $*"; }
20
+ [[ "$(type -t warn 2>/dev/null)" == "function" ]] || warn() { echo -e "\033[38;2;250;204;21m\033[1m⚠\033[0m $*"; }
21
+ [[ "$(type -t error 2>/dev/null)" == "function" ]] || error() { echo -e "\033[38;2;248;113;113m\033[1m✗\033[0m $*" >&2; }
22
+
23
+ if [[ "$(type -t now_iso 2>/dev/null)" != "function" ]]; then
24
+ now_iso() { date -u +"%Y-%m-%dT%H:%M:%SZ"; }
25
+ now_epoch() { date +%s; }
26
+ fi
27
+
28
+ if [[ "$(type -t emit_event 2>/dev/null)" != "function" ]]; then
29
+ emit_event() {
30
+ local event_type="$1"; shift
31
+ mkdir -p "${HOME}/.shipwright" 2>/dev/null || return 0
32
+ local payload="{\"ts\":\"$(now_iso)\",\"type\":\"$event_type\""
33
+ while [[ $# -gt 0 ]]; do
34
+ local key="${1%%=*}" val="${1#*=}"
35
+ payload="${payload},\"${key}\":\"${val}\""
36
+ shift
37
+ done
38
+ echo "${payload}}" >> "${HOME}/.shipwright/events.jsonl"
39
+ }
40
+ fi
41
+
42
+ # ─── Storage Paths ───────────────────────────────────────────────────────────
43
+
44
+ MEMEFF_DIR="${HOME}/.shipwright/optimization"
45
+ MEMEFF_INJECTIONS="${MEMEFF_DIR}/memory-injections.jsonl"
46
+ MEMEFF_OUTCOMES="${MEMEFF_DIR}/memory-outcomes.jsonl"
47
+ MEMEFF_SCORES="${MEMEFF_DIR}/memory-scores.json"
48
+ MEMEFF_ARCHIVE="${MEMEFF_DIR}/archive"
49
+
50
+ # ─── Initialize Storage ───────────────────────────────────────────────────────
51
+
52
+ memeff_init() {
53
+ mkdir -p "$MEMEFF_DIR" "$MEMEFF_ARCHIVE"
54
+ [[ -f "$MEMEFF_SCORES" ]] || echo '{}' > "$MEMEFF_SCORES"
55
+ }
56
+
57
+ # ─── 1. Track Memory Injection ──────────────────────────────────────────────
58
+
59
+ # Record when a memory pattern is injected
60
+ # memeff_track_injection <memory_id> <pipeline_id> <stage> <injection_context>
61
+ memeff_track_injection() {
62
+ local memory_id="${1:-}"
63
+ local pipeline_id="${2:-}"
64
+ local stage="${3:-unknown}"
65
+ local injection_context="${4:-}"
66
+
67
+ [[ -z "$memory_id" || -z "$pipeline_id" ]] && return 1
68
+
69
+ memeff_init
70
+
71
+ local ts
72
+ ts="$(now_iso)"
73
+ local injection_record
74
+ injection_record=$(jq -cn \
75
+ --arg mid "$memory_id" \
76
+ --arg pid "$pipeline_id" \
77
+ --arg stg "$stage" \
78
+ --arg ctx "$injection_context" \
79
+ --arg ts "$ts" \
80
+ '{
81
+ memory_id: $mid,
82
+ pipeline_id: $pid,
83
+ stage: $stg,
84
+ context: $ctx,
85
+ injected_at: $ts,
86
+ token_cost: 0,
87
+ outcome_recorded: false
88
+ }')
89
+
90
+ # Atomic write to JSONL
91
+ local tmp_injections
92
+ tmp_injections=$(mktemp "${MEMEFF_INJECTIONS}.tmp.XXXXXX")
93
+ {
94
+ [[ -f "$MEMEFF_INJECTIONS" ]] && cat "$MEMEFF_INJECTIONS"
95
+ echo "$injection_record"
96
+ } > "$tmp_injections"
97
+ mv "$tmp_injections" "$MEMEFF_INJECTIONS"
98
+
99
+ emit_event "memeff.injection" \
100
+ "memory_id=${memory_id}" \
101
+ "pipeline_id=${pipeline_id}" \
102
+ "stage=${stage}"
103
+
104
+ return 0
105
+ }
106
+
107
+ # ─── 2. Track Memory Outcome ──────────────────────────────────────────────
108
+
109
+ # Record pipeline outcome after injection
110
+ # memeff_track_outcome <memory_id> <pipeline_id> <outcome> [relevant_error]
111
+ memeff_track_outcome() {
112
+ local memory_id="${1:-}"
113
+ local pipeline_id="${2:-}"
114
+ local outcome="${3:-unknown}" # success, failure, inconclusive
115
+ local relevant_error="${4:-}"
116
+
117
+ [[ -z "$memory_id" || -z "$pipeline_id" ]] && return 1
118
+
119
+ memeff_init
120
+
121
+ # Find the corresponding injection (use fixed strings, not regex, to avoid special char issues)
122
+ local injection_record
123
+ injection_record=$(grep -F "\"memory_id\":\"${memory_id}\"" "$MEMEFF_INJECTIONS" 2>/dev/null | \
124
+ grep -F "\"pipeline_id\":\"${pipeline_id}\"" | tail -1 || true)
125
+
126
+ if [[ -z "$injection_record" ]]; then
127
+ warn "No injection record found for memory_id=$memory_id, pipeline_id=$pipeline_id"
128
+ return 1
129
+ fi
130
+
131
+ # Determine if pattern was relevant (did the injection prevent the error?)
132
+ local was_relevant="false"
133
+ if [[ "$outcome" == "success" ]]; then
134
+ was_relevant="true"
135
+ elif [[ "$outcome" == "failure" && -z "$relevant_error" ]]; then
136
+ was_relevant="false"
137
+ elif [[ "$outcome" == "failure" && -n "$relevant_error" ]]; then
138
+ # Failure occurred, but unrelated to this memory's domain
139
+ was_relevant="false"
140
+ fi
141
+
142
+ local ts
143
+ ts="$(now_iso)"
144
+ local outcome_record
145
+ outcome_record=$(jq -cn \
146
+ --arg mid "$memory_id" \
147
+ --arg pid "$pipeline_id" \
148
+ --arg out "$outcome" \
149
+ --arg relevant "$was_relevant" \
150
+ --arg err "$relevant_error" \
151
+ --arg ts "$ts" \
152
+ '{
153
+ memory_id: $mid,
154
+ pipeline_id: $pid,
155
+ outcome: $out,
156
+ was_relevant: ($relevant == "true"),
157
+ avoided_error: ($out == "success"),
158
+ error_description: $err,
159
+ recorded_at: $ts
160
+ }')
161
+
162
+ # Atomic write
163
+ local tmp_outcomes
164
+ tmp_outcomes=$(mktemp "${MEMEFF_OUTCOMES}.tmp.XXXXXX")
165
+ {
166
+ [[ -f "$MEMEFF_OUTCOMES" ]] && cat "$MEMEFF_OUTCOMES"
167
+ echo "$outcome_record"
168
+ } > "$tmp_outcomes"
169
+ mv "$tmp_outcomes" "$MEMEFF_OUTCOMES"
170
+
171
+ emit_event "memeff.outcome" \
172
+ "memory_id=${memory_id}" \
173
+ "pipeline_id=${pipeline_id}" \
174
+ "outcome=${outcome}" \
175
+ "was_relevant=${was_relevant}"
176
+
177
+ return 0
178
+ }
179
+
180
+ # ─── 3. Score Individual Pattern ────────────────────────────────────────────
181
+
182
+ # Calculate effectiveness score for a memory pattern
183
+ # memeff_score_pattern <memory_id>
184
+ # Returns: JSON with prevention_rate, relevance_rate, token_cost, effectiveness_score
185
+ memeff_score_pattern() {
186
+ local memory_id="${1:-}"
187
+ [[ -z "$memory_id" ]] && return 1
188
+
189
+ memeff_init
190
+
191
+ # Count outcomes for this pattern
192
+ local outcomes
193
+ outcomes=$(grep -F "\"memory_id\":\"${memory_id}\"" "$MEMEFF_OUTCOMES" 2>/dev/null || true)
194
+
195
+ local total_injections=0
196
+ local successful_preventions=0
197
+ local relevant_injections=0
198
+ local token_cost_total=0
199
+
200
+ while IFS= read -r line; do
201
+ [[ -z "$line" ]] && continue
202
+ total_injections=$((total_injections + 1))
203
+
204
+ # Check if outcome avoided the error
205
+ if echo "$line" | jq -e '.avoided_error == true' >/dev/null 2>&1; then
206
+ successful_preventions=$((successful_preventions + 1))
207
+ fi
208
+
209
+ # Check if pattern was relevant to the task
210
+ if echo "$line" | jq -e '.was_relevant == true' >/dev/null 2>&1; then
211
+ relevant_injections=$((relevant_injections + 1))
212
+ fi
213
+ done <<< "$outcomes"
214
+
215
+ # Calculate rates (avoid division by zero)
216
+ local prevention_rate=0
217
+ local relevance_rate=0
218
+ if [[ "$total_injections" -gt 0 ]]; then
219
+ prevention_rate=$((successful_preventions * 100 / total_injections))
220
+ relevance_rate=$((relevant_injections * 100 / total_injections))
221
+ fi
222
+
223
+ # Normalize token cost (assume ~100 tokens per injection on average)
224
+ local token_cost_normalized
225
+ if [[ "$total_injections" -gt 0 ]]; then
226
+ token_cost_normalized=$((token_cost_total / total_injections / 100))
227
+ else
228
+ token_cost_normalized=0
229
+ fi
230
+
231
+ # Effectiveness formula: (prevention * 0.5 + relevance * 0.3) - (token_cost * 0.2)
232
+ local effectiveness_score
233
+ effectiveness_score=$(( (prevention_rate * 50 + relevance_rate * 30) / 100 - (token_cost_normalized * 20) ))
234
+ [[ "$effectiveness_score" -lt 0 ]] && effectiveness_score=0
235
+ [[ "$effectiveness_score" -gt 100 ]] && effectiveness_score=100
236
+
237
+ # Return as JSON
238
+ jq -cn \
239
+ --arg mid "$memory_id" \
240
+ --argjson prev "$prevention_rate" \
241
+ --argjson rel "$relevance_rate" \
242
+ --argjson cost "$token_cost_normalized" \
243
+ --argjson score "$effectiveness_score" \
244
+ --argjson injections "$total_injections" \
245
+ '{
246
+ memory_id: $mid,
247
+ prevention_rate: $prev,
248
+ relevance_rate: $rel,
249
+ token_cost_normalized: $cost,
250
+ effectiveness_score: $score,
251
+ total_injections: $injections
252
+ }'
253
+ }
254
+
255
+ # ─── 4. Rank All Patterns ──────────────────────────────────────────────────
256
+
257
+ # Rank all patterns by effectiveness
258
+ # memeff_rank_patterns [limit]
259
+ # Returns: JSON array sorted by effectiveness_score descending
260
+ memeff_rank_patterns() {
261
+ local limit="${1:-50}"
262
+
263
+ memeff_init
264
+
265
+ # Extract all unique memory IDs from outcomes
266
+ local memory_ids
267
+ memory_ids=$(grep -o '"memory_id":"[^"]*"' "$MEMEFF_OUTCOMES" 2>/dev/null | \
268
+ sed 's/"memory_id":"//' | sed 's/"//' | \
269
+ sort -u || true)
270
+
271
+ local rankings=()
272
+ while IFS= read -r memory_id; do
273
+ [[ -z "$memory_id" ]] && continue
274
+ local score_json
275
+ score_json=$(memeff_score_pattern "$memory_id")
276
+ rankings+=("$score_json")
277
+ done <<< "$memory_ids"
278
+
279
+ # Sort by effectiveness_score descending
280
+ if [[ "${#rankings[@]}" -eq 0 ]]; then
281
+ echo "[]"
282
+ return 0
283
+ fi
284
+
285
+ printf '%s\n' "${rankings[@]}" | \
286
+ jq -s 'sort_by(-.effectiveness_score) | .[0:'"$limit"']'
287
+ }
288
+
289
+ # ─── 5. Prune Ineffective Patterns ──────────────────────────────────────────
290
+
291
+ # Remove or archive ineffective patterns
292
+ # memeff_prune_ineffective [dry_run]
293
+ # Score < 20 after 5+ injections → archive
294
+ # Score < 10 after 10+ injections → delete
295
+ memeff_prune_ineffective() {
296
+ local dry_run="${1:-true}"
297
+
298
+ memeff_init
299
+
300
+ local rankings
301
+ rankings=$(memeff_rank_patterns 999)
302
+
303
+ local archived=0
304
+ local deleted=0
305
+
306
+ echo "$rankings" | jq -c '.[]' | while IFS= read -r pattern; do
307
+ [[ -z "$pattern" ]] && continue
308
+
309
+ local mid score injections
310
+ mid=$(echo "$pattern" | jq -r '.memory_id')
311
+ score=$(echo "$pattern" | jq -r '.effectiveness_score // 0')
312
+ injections=$(echo "$pattern" | jq -r '.total_injections // 0')
313
+
314
+ # Score < 20 after 5+ injections → archive
315
+ if [[ "${score%.*}" -lt 20 && "$injections" -ge 5 ]]; then
316
+ if [[ "$dry_run" != "true" ]]; then
317
+ # Archive the pattern metadata
318
+ echo "Archiving memory_id=$mid (score=$score, injections=$injections)"
319
+ archived=$((archived + 1))
320
+ emit_event "memeff.archive" \
321
+ "memory_id=${mid}" \
322
+ "score=${score}" \
323
+ "reason=low_effectiveness"
324
+ else
325
+ info "DRY-RUN: Would archive memory_id=$mid (score=$score)"
326
+ fi
327
+ fi
328
+
329
+ # Score < 10 after 10+ injections → delete
330
+ if [[ "${score%.*}" -lt 10 && "$injections" -ge 10 ]]; then
331
+ if [[ "$dry_run" != "true" ]]; then
332
+ # Remove from tracking
333
+ echo "Deleting memory_id=$mid (score=$score, injections=$injections)"
334
+ deleted=$((deleted + 1))
335
+ emit_event "memeff.delete" \
336
+ "memory_id=${mid}" \
337
+ "score=${score}" \
338
+ "reason=critically_ineffective"
339
+ else
340
+ info "DRY-RUN: Would delete memory_id=$mid (score=$score)"
341
+ fi
342
+ fi
343
+ done
344
+
345
+ emit_event "memeff.prune_complete" \
346
+ "archived=${archived}" \
347
+ "deleted=${deleted}" \
348
+ "dry_run=${dry_run}"
349
+
350
+ return 0
351
+ }
352
+
353
+ # ─── 6. Proactive Scoring ──────────────────────────────────────────────────
354
+
355
+ # Score likelihood of preventing a specific failure
356
+ # memeff_proactive_score <error_signature> [affected_files]
357
+ # Returns: probability 0-100 that matching patterns prevent failure
358
+ memeff_proactive_score() {
359
+ local error_signature="${1:-}"
360
+ local affected_files="${2:-}"
361
+
362
+ [[ -z "$error_signature" ]] && return 1
363
+
364
+ memeff_init
365
+
366
+ # Search outcomes for patterns matching error_signature
367
+ local matching_patterns=()
368
+ local total_matches=0
369
+ local successful_matches=0
370
+
371
+ # Simple pattern matching on error description
372
+ [[ -f "$MEMEFF_OUTCOMES" ]] && while IFS= read -r line; do
373
+ [[ -z "$line" ]] && continue
374
+ local error_desc
375
+ error_desc=$(echo "$line" | jq -r '.error_description // ""' 2>/dev/null)
376
+
377
+ # Check if error_signature appears in outcomes
378
+ if echo "$error_desc" | grep -iqF "$error_signature" 2>/dev/null; then
379
+ total_matches=$((total_matches + 1))
380
+
381
+ # Count how many were successfully prevented
382
+ if echo "$line" | jq -e '.avoided_error == true' >/dev/null 2>&1; then
383
+ successful_matches=$((successful_matches + 1))
384
+ fi
385
+ fi
386
+ done < "$MEMEFF_OUTCOMES"
387
+
388
+ # Calculate probability
389
+ local probability=0
390
+ if [[ "$total_matches" -gt 0 ]]; then
391
+ probability=$((successful_matches * 100 / total_matches))
392
+ fi
393
+
394
+ # Cap between 0-100
395
+ [[ "$probability" -lt 0 ]] && probability=0
396
+ [[ "$probability" -gt 100 ]] && probability=100
397
+
398
+ jq -n \
399
+ --arg sig "$error_signature" \
400
+ --argjson prob "$probability" \
401
+ --argjson matches "$total_matches" \
402
+ '{
403
+ error_signature: $sig,
404
+ prevention_probability: $prob,
405
+ matching_patterns: $matches,
406
+ confidence: (if $matches >= 5 then "high" elif $matches >= 2 then "medium" else "low" end)
407
+ }'
408
+ }
409
+
410
+ # ─── 7. Effectiveness Report ───────────────────────────────────────────────
411
+
412
+ # Generate effectiveness dashboard
413
+ # memeff_report [format]
414
+ # format: "text" (default) or "json"
415
+ memeff_report() {
416
+ local format="${1:-text}"
417
+
418
+ memeff_init
419
+
420
+ local total_patterns=0
421
+ local avg_score=0
422
+ local total_injections=0
423
+
424
+ # Get all rankings
425
+ local rankings
426
+ rankings=$(memeff_rank_patterns 999)
427
+
428
+ # Calculate metrics
429
+ if [[ "$rankings" != "[]" ]]; then
430
+ total_patterns=$(echo "$rankings" | jq 'length')
431
+ avg_score=$(echo "$rankings" | jq '[.[].effectiveness_score] | add / length | round')
432
+ total_injections=$(echo "$rankings" | jq '[.[].total_injections] | add')
433
+ fi
434
+
435
+ if [[ "$format" == "json" ]]; then
436
+ # Return full JSON report
437
+ jq -cn \
438
+ --argjson total "$total_patterns" \
439
+ --argjson avg "$avg_score" \
440
+ --argjson injections "$total_injections" \
441
+ --argjson top "$( echo "$rankings" | jq '.[0:5]')" \
442
+ --argjson bottom "$( echo "$rankings" | jq '.[-5:]')" \
443
+ '{
444
+ summary: {
445
+ total_patterns: $total,
446
+ average_score: $avg,
447
+ total_injections: $injections
448
+ },
449
+ top_5: $top,
450
+ bottom_5: $bottom
451
+ }'
452
+ return 0
453
+ fi
454
+
455
+ # Text format
456
+ echo ""
457
+ echo "╔═══════════════════════════════════════════════════════════════════╗"
458
+ echo "║ Memory Pattern Effectiveness Report ║"
459
+ echo "╚═══════════════════════════════════════════════════════════════════╝"
460
+ echo ""
461
+ echo " Total Patterns: ${total_patterns}"
462
+ echo " Average Score: ${avg_score}/100"
463
+ echo " Total Injections: ${total_injections}"
464
+ echo ""
465
+
466
+ if [[ "$total_patterns" -gt 0 ]]; then
467
+ echo " Top 5 Most Effective Patterns:"
468
+ echo "$rankings" | jq -r '.[:5] | .[] | " [\(.effectiveness_score)] \(.memory_id) (inj: \(.total_injections))"' || true
469
+ echo ""
470
+
471
+ echo " Bottom 5 Least Effective Patterns:"
472
+ echo "$rankings" | jq -r '.[-5:] | reverse | .[] | " [\(.effectiveness_score)] \(.memory_id) (inj: \(.total_injections))"' || true
473
+ fi
474
+
475
+ echo ""
476
+ }
477
+
478
+ # ─── Integration Helpers ────────────────────────────────────────────────────
479
+
480
+ # Called by sw-loop.sh when injecting memory context
481
+ memeff_on_injection() {
482
+ local memory_id="$1"
483
+ local pipeline_id="$2"
484
+ local stage="$3"
485
+ memeff_track_injection "$memory_id" "$pipeline_id" "$stage" "automated_injection"
486
+ }
487
+
488
+ # Called by sw-pipeline.sh after completion
489
+ memeff_on_pipeline_complete() {
490
+ local pipeline_id="$1"
491
+ local outcome="$2" # success or failure
492
+ local error_context="${3:-}"
493
+
494
+ # Find all memories injected in this pipeline
495
+ local injected_memories
496
+ injected_memories=$(grep -E "\"pipeline_id\":\"${pipeline_id}\"" "$MEMEFF_INJECTIONS" 2>/dev/null | \
497
+ jq -r '.memory_id' | sort -u || true)
498
+
499
+ while IFS= read -r memory_id; do
500
+ [[ -z "$memory_id" ]] && continue
501
+ memeff_track_outcome "$memory_id" "$pipeline_id" "$outcome" "$error_context"
502
+ done <<< "$injected_memories"
503
+ }
504
+
505
+ # Export for sourcing
506
+ return 0