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