dual-brain 0.2.30 → 0.3.1
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/.dual-brain/docs/claude-code-extension-points.md +32 -0
- package/.dual-brain/docs/data-tools-capabilities.md +181 -0
- package/.dual-brain/docs/ecosystem-tools.md +91 -0
- package/.dual-brain/docs/panel-handoff.md +124 -0
- package/.dual-brain/docs/ruflo-analysis.md +48 -0
- package/bin/dual-brain.mjs +56 -56
- package/dist/mcp-server/index.d.ts +27 -0
- package/dist/mcp-server/index.js +359 -0
- package/dist/mcp-server/index.js.map +1 -0
- package/dist/src/agent-protocol.d.ts +163 -0
- package/dist/src/agent-protocol.js +368 -0
- package/dist/src/agent-protocol.js.map +1 -0
- package/dist/src/agents/registry.d.ts +52 -0
- package/dist/src/agents/registry.js +393 -0
- package/dist/src/agents/registry.js.map +1 -0
- package/dist/src/awareness.d.ts +93 -0
- package/dist/src/awareness.js +406 -0
- package/dist/src/awareness.js.map +1 -0
- package/dist/src/brief.d.ts +48 -0
- package/dist/src/brief.js +179 -0
- package/dist/src/brief.js.map +1 -0
- package/dist/src/calibration.d.ts +32 -0
- package/dist/src/calibration.js +133 -0
- package/dist/src/calibration.js.map +1 -0
- package/dist/src/checkpoint.d.ts +33 -0
- package/dist/src/checkpoint.js +99 -0
- package/dist/src/checkpoint.js.map +1 -0
- package/dist/src/ci-triage.d.ts +33 -0
- package/dist/src/ci-triage.js +193 -0
- package/dist/src/ci-triage.js.map +1 -0
- package/dist/src/cognitive-loop.d.ts +56 -0
- package/dist/src/cognitive-loop.js +495 -0
- package/dist/src/cognitive-loop.js.map +1 -0
- package/dist/src/collaboration.d.ts +147 -0
- package/dist/src/collaboration.js +438 -0
- package/dist/src/collaboration.js.map +1 -0
- package/dist/src/context-intel.d.ts +47 -0
- package/dist/src/context-intel.js +156 -0
- package/dist/src/context-intel.js.map +1 -0
- package/dist/src/context.d.ts +53 -0
- package/dist/src/context.js +332 -0
- package/dist/src/context.js.map +1 -0
- package/dist/src/continuity.d.ts +89 -0
- package/dist/src/continuity.js +230 -0
- package/dist/src/continuity.js.map +1 -0
- package/dist/src/cost-tracker.d.ts +47 -0
- package/dist/src/cost-tracker.js +170 -0
- package/dist/src/cost-tracker.js.map +1 -0
- package/dist/src/debrief.d.ts +53 -0
- package/dist/src/debrief.js +222 -0
- package/dist/src/debrief.js.map +1 -0
- package/dist/src/decide.d.ts +96 -0
- package/dist/src/decide.js +744 -0
- package/dist/src/decide.js.map +1 -0
- package/dist/src/decompose.d.ts +39 -0
- package/dist/src/decompose.js +218 -0
- package/dist/src/decompose.js.map +1 -0
- package/dist/src/detect.d.ts +91 -0
- package/dist/src/detect.js +544 -0
- package/dist/src/detect.js.map +1 -0
- package/dist/src/dispatch.d.ts +154 -0
- package/dist/src/dispatch.js +1306 -0
- package/dist/src/dispatch.js.map +1 -0
- package/dist/src/doctor.d.ts +421 -0
- package/dist/src/doctor.js +1689 -0
- package/dist/src/doctor.js.map +1 -0
- package/dist/src/engine.d.ts +70 -0
- package/dist/src/engine.js +155 -0
- package/dist/src/engine.js.map +1 -0
- package/dist/src/envelope.d.ts +36 -0
- package/dist/src/envelope.js +80 -0
- package/dist/src/envelope.js.map +1 -0
- package/dist/src/failure-memory.d.ts +55 -0
- package/dist/src/failure-memory.js +175 -0
- package/dist/src/failure-memory.js.map +1 -0
- package/dist/src/fx.d.ts +87 -0
- package/dist/src/fx.js +272 -0
- package/dist/src/fx.js.map +1 -0
- package/dist/src/governance.d.ts +93 -0
- package/dist/src/governance.js +261 -0
- package/dist/src/governance.js.map +1 -0
- package/dist/src/handoff.d.ts +11 -0
- package/dist/src/handoff.js +90 -0
- package/dist/src/handoff.js.map +1 -0
- package/dist/src/head-protocol.d.ts +76 -0
- package/dist/src/head-protocol.js +109 -0
- package/dist/src/head-protocol.js.map +1 -0
- package/dist/src/head.d.ts +222 -0
- package/dist/src/head.js +765 -0
- package/dist/src/head.js.map +1 -0
- package/dist/src/health.d.ts +132 -0
- package/dist/src/health.js +435 -0
- package/dist/src/health.js.map +1 -0
- package/dist/src/inbox.d.ts +70 -0
- package/dist/src/inbox.js +218 -0
- package/dist/src/inbox.js.map +1 -0
- package/dist/src/index.d.ts +33 -0
- package/dist/src/index.js +38 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/install-hooks.d.ts +13 -0
- package/dist/src/install-hooks.js +88 -0
- package/dist/src/install-hooks.js.map +1 -0
- package/dist/src/integrity.d.ts +59 -0
- package/dist/src/integrity.js +206 -0
- package/dist/src/integrity.js.map +1 -0
- package/dist/src/intelligence.d.ts +104 -0
- package/dist/src/intelligence.js +391 -0
- package/dist/src/intelligence.js.map +1 -0
- package/dist/src/ledger.d.ts +54 -0
- package/dist/src/ledger.js +179 -0
- package/dist/src/ledger.js.map +1 -0
- package/dist/src/living-docs.d.ts +14 -0
- package/dist/src/living-docs.js +197 -0
- package/dist/src/living-docs.js.map +1 -0
- package/dist/src/memory-tiers.d.ts +37 -0
- package/dist/src/memory-tiers.js +160 -0
- package/dist/src/memory-tiers.js.map +1 -0
- package/dist/src/model-profiles.d.ts +65 -0
- package/dist/src/model-profiles.js +568 -0
- package/dist/src/model-profiles.js.map +1 -0
- package/dist/src/models.d.ts +58 -0
- package/dist/src/models.js +327 -0
- package/dist/src/models.js.map +1 -0
- package/dist/src/narrative.d.ts +54 -0
- package/dist/src/narrative.js +163 -0
- package/dist/src/narrative.js.map +1 -0
- package/dist/src/nextstep.d.ts +16 -0
- package/dist/src/nextstep.js +103 -0
- package/dist/src/nextstep.js.map +1 -0
- package/dist/src/observer.d.ts +18 -0
- package/dist/src/observer.js +251 -0
- package/dist/src/observer.js.map +1 -0
- package/dist/src/outcome.d.ts +110 -0
- package/dist/src/outcome.js +377 -0
- package/dist/src/outcome.js.map +1 -0
- package/dist/src/pipeline.d.ts +167 -0
- package/dist/src/pipeline.js +1503 -0
- package/dist/src/pipeline.js.map +1 -0
- package/dist/src/playbook.d.ts +59 -0
- package/dist/src/playbook.js +238 -0
- package/dist/src/playbook.js.map +1 -0
- package/dist/src/pr-agent.d.ts +97 -0
- package/dist/src/pr-agent.js +195 -0
- package/dist/src/pr-agent.js.map +1 -0
- package/dist/src/predictive.d.ts +57 -0
- package/dist/src/predictive.js +230 -0
- package/dist/src/predictive.js.map +1 -0
- package/dist/src/profile.d.ts +294 -0
- package/dist/src/profile.js +1347 -0
- package/dist/src/profile.js.map +1 -0
- package/dist/src/prompt-audit.d.ts +22 -0
- package/dist/src/prompt-audit.js +194 -0
- package/dist/src/prompt-audit.js.map +1 -0
- package/dist/src/prompt-intel.d.ts +12 -0
- package/dist/src/prompt-intel.js +321 -0
- package/dist/src/prompt-intel.js.map +1 -0
- package/dist/src/provider-context.d.ts +121 -0
- package/dist/src/provider-context.js +222 -0
- package/dist/src/provider-context.js.map +1 -0
- package/dist/src/provider-manager.d.ts +92 -0
- package/dist/src/provider-manager.js +428 -0
- package/dist/src/provider-manager.js.map +1 -0
- package/dist/src/receipt.d.ts +87 -0
- package/dist/src/receipt.js +326 -0
- package/dist/src/receipt.js.map +1 -0
- package/dist/src/recommendations.d.ts +13 -0
- package/dist/src/recommendations.js +291 -0
- package/dist/src/recommendations.js.map +1 -0
- package/dist/src/redact.d.ts +15 -0
- package/dist/src/redact.js +129 -0
- package/dist/src/redact.js.map +1 -0
- package/dist/src/replit.d.ts +397 -0
- package/dist/src/replit.js +1160 -0
- package/dist/src/replit.js.map +1 -0
- package/dist/src/repo.d.ts +149 -0
- package/dist/src/repo.js +416 -0
- package/dist/src/repo.js.map +1 -0
- package/dist/src/revert.d.ts +30 -0
- package/dist/src/revert.js +166 -0
- package/dist/src/revert.js.map +1 -0
- package/dist/src/room.d.ts +102 -0
- package/dist/src/room.js +212 -0
- package/dist/src/room.js.map +1 -0
- package/dist/src/routing-advisor.d.ts +57 -0
- package/dist/src/routing-advisor.js +221 -0
- package/dist/src/routing-advisor.js.map +1 -0
- package/dist/src/self-correct.d.ts +40 -0
- package/dist/src/self-correct.js +137 -0
- package/dist/src/self-correct.js.map +1 -0
- package/dist/src/session-lock.d.ts +35 -0
- package/dist/src/session-lock.js +134 -0
- package/dist/src/session-lock.js.map +1 -0
- package/dist/src/session.d.ts +267 -0
- package/dist/src/session.js +1660 -0
- package/dist/src/session.js.map +1 -0
- package/dist/src/settings-tui.d.ts +5 -0
- package/dist/src/settings-tui.js +422 -0
- package/dist/src/settings-tui.js.map +1 -0
- package/dist/src/setup-flow.d.ts +63 -0
- package/dist/src/setup-flow.js +233 -0
- package/dist/src/setup-flow.js.map +1 -0
- package/dist/src/signal.d.ts +19 -0
- package/dist/src/signal.js +122 -0
- package/dist/src/signal.js.map +1 -0
- package/dist/src/simmer.d.ts +85 -0
- package/dist/src/simmer.js +224 -0
- package/dist/src/simmer.js.map +1 -0
- package/dist/src/state-export.d.ts +129 -0
- package/dist/src/state-export.js +233 -0
- package/dist/src/state-export.js.map +1 -0
- package/dist/src/strategy.d.ts +54 -0
- package/dist/src/strategy.js +95 -0
- package/dist/src/strategy.js.map +1 -0
- package/dist/src/subscription.d.ts +40 -0
- package/dist/src/subscription.js +189 -0
- package/dist/src/subscription.js.map +1 -0
- package/dist/src/templates.d.ts +208 -0
- package/dist/src/templates.js +238 -0
- package/dist/src/templates.js.map +1 -0
- package/dist/src/test.d.ts +9 -0
- package/dist/src/test.js +1173 -0
- package/dist/src/test.js.map +1 -0
- package/dist/src/think-engine.d.ts +67 -0
- package/dist/src/think-engine.js +412 -0
- package/dist/src/think-engine.js.map +1 -0
- package/dist/src/tui.d.ts +71 -0
- package/dist/src/tui.js +242 -0
- package/dist/src/tui.js.map +1 -0
- package/dist/src/types.d.ts +177 -0
- package/dist/src/types.js +6 -0
- package/dist/src/types.js.map +1 -0
- package/dist/src/update-check.d.ts +7 -0
- package/dist/src/update-check.js +36 -0
- package/dist/src/update-check.js.map +1 -0
- package/dist/src/wave-planner.d.ts +30 -0
- package/dist/src/wave-planner.js +281 -0
- package/dist/src/wave-planner.js.map +1 -0
- package/hooks/head-guard.sh +41 -0
- package/hooks/precompact.mjs +3 -3
- package/hooks/session-end.mjs +3 -3
- package/hooks/task-classifier.mjs +328 -0
- package/hooks/vibe-router.mjs +387 -0
- package/install.mjs +2 -2
- package/package.json +29 -153
- package/src/agents/registry.mjs +0 -405
- package/src/awareness.mjs +0 -425
- package/src/brief.mjs +0 -266
- package/src/calibration.mjs +0 -148
- package/src/checkpoint.mjs +0 -109
- package/src/ci-triage.mjs +0 -191
- package/src/cognitive-loop.mjs +0 -562
- package/src/collaboration.mjs +0 -545
- package/src/context-intel.mjs +0 -158
- package/src/context.mjs +0 -389
- package/src/continuity.mjs +0 -298
- package/src/cost-tracker.mjs +0 -184
- package/src/debrief.mjs +0 -228
- package/src/decide.mjs +0 -1099
- package/src/decompose.mjs +0 -331
- package/src/detect.mjs +0 -702
- package/src/dispatch.mjs +0 -1447
- package/src/doctor.mjs +0 -1607
- package/src/envelope.mjs +0 -139
- package/src/failure-memory.mjs +0 -178
- package/src/fx.mjs +0 -276
- package/src/governance.mjs +0 -279
- package/src/handoff.mjs +0 -87
- package/src/head-protocol.mjs +0 -128
- package/src/head.mjs +0 -952
- package/src/health.mjs +0 -528
- package/src/inbox.mjs +0 -195
- package/src/index.mjs +0 -44
- package/src/install-hooks.mjs +0 -100
- package/src/integrity.mjs +0 -245
- package/src/intelligence.mjs +0 -447
- package/src/ledger.mjs +0 -196
- package/src/living-docs.mjs +0 -210
- package/src/memory-tiers.mjs +0 -193
- package/src/models.mjs +0 -363
- package/src/narrative.mjs +0 -169
- package/src/nextstep.mjs +0 -100
- package/src/observer.mjs +0 -241
- package/src/outcome.mjs +0 -400
- package/src/pipeline.mjs +0 -1711
- package/src/playbook.mjs +0 -257
- package/src/pr-agent.mjs +0 -214
- package/src/predictive.mjs +0 -250
- package/src/profile.mjs +0 -1411
- package/src/prompt-audit.mjs +0 -231
- package/src/prompt-intel.mjs +0 -325
- package/src/provider-context.mjs +0 -257
- package/src/receipt.mjs +0 -344
- package/src/recommendations.mjs +0 -296
- package/src/redact.mjs +0 -192
- package/src/replit.mjs +0 -1210
- package/src/repo.mjs +0 -445
- package/src/revert.mjs +0 -149
- package/src/routing-advisor.mjs +0 -204
- package/src/self-correct.mjs +0 -147
- package/src/session-lock.mjs +0 -160
- package/src/session.mjs +0 -1655
- package/src/settings-tui.mjs +0 -373
- package/src/setup-flow.mjs +0 -223
- package/src/signal.mjs +0 -115
- package/src/simmer.mjs +0 -241
- package/src/strategy.mjs +0 -235
- package/src/subscription.mjs +0 -212
- package/src/templates.mjs +0 -260
- package/src/think-engine.mjs +0 -428
- package/src/tui.mjs +0 -276
- package/src/update-check.mjs +0 -35
- package/src/wave-planner.mjs +0 -294
package/src/predictive.mjs
DELETED
|
@@ -1,250 +0,0 @@
|
|
|
1
|
-
/** Predictive Dispatch — Layer 3: anticipates failure modes BEFORE dispatching. */
|
|
2
|
-
import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'fs';
|
|
3
|
-
import { join } from 'path';
|
|
4
|
-
|
|
5
|
-
const DIAG_DIR = join(process.cwd(), '.dualbrain', 'diagnostic');
|
|
6
|
-
const STATE_PATH = join(DIAG_DIR, 'current.json');
|
|
7
|
-
const WEIGHTS_PATH = join(DIAG_DIR, 'pattern-weights.json');
|
|
8
|
-
|
|
9
|
-
export function loadSessionPatterns() {
|
|
10
|
-
const empty = { frequencies: [], avgSeverity: 0, precedingTools: {}, timeTrends: [] };
|
|
11
|
-
if (!existsSync(STATE_PATH)) return empty;
|
|
12
|
-
|
|
13
|
-
let state;
|
|
14
|
-
try { state = JSON.parse(readFileSync(STATE_PATH, 'utf8')); }
|
|
15
|
-
catch { return empty; }
|
|
16
|
-
|
|
17
|
-
const noticings = state.noticings || [];
|
|
18
|
-
if (!noticings.length) return empty;
|
|
19
|
-
|
|
20
|
-
const counts = {};
|
|
21
|
-
const severityMap = { low: 1, medium: 2, high: 3 };
|
|
22
|
-
let totalSeverity = 0;
|
|
23
|
-
for (const n of noticings) {
|
|
24
|
-
counts[n.type] = (counts[n.type] || 0) + 1;
|
|
25
|
-
totalSeverity += severityMap[n.severity] || 1;
|
|
26
|
-
}
|
|
27
|
-
const frequencies = Object.entries(counts)
|
|
28
|
-
.map(([type, count]) => ({ type, count }))
|
|
29
|
-
.sort((a, b) => b.count - a.count);
|
|
30
|
-
|
|
31
|
-
const toolCalls = state.toolCalls || [];
|
|
32
|
-
const precedingTools = {};
|
|
33
|
-
for (const n of noticings) {
|
|
34
|
-
const before = toolCalls.filter(tc => tc.ts < n.ts).slice(-3).map(tc => tc.tool);
|
|
35
|
-
if (!precedingTools[n.type]) precedingTools[n.type] = [];
|
|
36
|
-
precedingTools[n.type].push(...before);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
const sessionStart = state.startedAt || noticings[0]?.ts || 0;
|
|
40
|
-
const sessionEnd = state.lastActivity || noticings[noticings.length - 1]?.ts || Date.now();
|
|
41
|
-
const duration = sessionEnd - sessionStart || 1;
|
|
42
|
-
const timeTrends = noticings.map(n => ({
|
|
43
|
-
type: n.type, position: (n.ts - sessionStart) / duration,
|
|
44
|
-
}));
|
|
45
|
-
|
|
46
|
-
return { frequencies, avgSeverity: totalSeverity / noticings.length, precedingTools, timeTrends };
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
function loadWeights() {
|
|
50
|
-
if (!existsSync(WEIGHTS_PATH)) return {};
|
|
51
|
-
try { return JSON.parse(readFileSync(WEIGHTS_PATH, 'utf8')); }
|
|
52
|
-
catch { return {}; }
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
export function predictFailureModes(agentSpec, context = {}) {
|
|
56
|
-
const predictions = [];
|
|
57
|
-
const patterns = context.patterns || loadSessionPatterns();
|
|
58
|
-
const weights = loadWeights();
|
|
59
|
-
const objective = agentSpec.objective || '';
|
|
60
|
-
const scope = agentSpec.scope || {};
|
|
61
|
-
const files = scope.files || [];
|
|
62
|
-
const tier = agentSpec.tier || '';
|
|
63
|
-
const priorFailures = context.priorFailures || [];
|
|
64
|
-
const activeWaves = context.activeWaves || [];
|
|
65
|
-
const lastReadAge = context.lastReadAge || 0; // ms
|
|
66
|
-
|
|
67
|
-
const applyWeight = (mode, base) => {
|
|
68
|
-
const w = weights[mode];
|
|
69
|
-
if (!w) return base;
|
|
70
|
-
// Shift likelihood based on historical accuracy
|
|
71
|
-
return Math.min(1, Math.max(0, base + (w.accuracy - 0.5) * 0.3));
|
|
72
|
-
};
|
|
73
|
-
|
|
74
|
-
// scope-explosion
|
|
75
|
-
const multiTarget = files.length > 3 || /\band\b|multiple|several|all/i.test(objective);
|
|
76
|
-
const priorScopeCreep = patterns.frequencies.some(f => f.type === 'scope-creep' && f.count >= 2);
|
|
77
|
-
if (multiTarget || priorScopeCreep) {
|
|
78
|
-
const base = multiTarget && priorScopeCreep ? 0.8 : 0.7;
|
|
79
|
-
predictions.push({
|
|
80
|
-
mode: 'scope-explosion',
|
|
81
|
-
likelihood: applyWeight('scope-explosion', base),
|
|
82
|
-
basis: multiTarget
|
|
83
|
-
? `Objective references ${files.length || 'multiple'} targets`
|
|
84
|
-
: 'Prior waves encountered scope creep',
|
|
85
|
-
prevention: `If scope grows beyond ${Math.max(files.length, 3)} files, STOP and report back rather than continuing.`,
|
|
86
|
-
});
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
// missing-context
|
|
90
|
-
const noFiles = files.length === 0;
|
|
91
|
-
const executeWithoutSearch = tier === 'execute' && !(context.priorSearchWave);
|
|
92
|
-
if (noFiles || executeWithoutSearch) {
|
|
93
|
-
const base = 0.6;
|
|
94
|
-
predictions.push({
|
|
95
|
-
mode: 'missing-context',
|
|
96
|
-
likelihood: applyWeight('missing-context', base),
|
|
97
|
-
basis: noFiles
|
|
98
|
-
? 'No files specified in scope — agent may waste tokens searching'
|
|
99
|
-
: 'Execute tier dispatched without prior search wave',
|
|
100
|
-
prevention: `Read the current state of target files before making changes. If unsure what to modify, list candidates first.`,
|
|
101
|
-
});
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
// wrong-approach
|
|
105
|
-
const hasStuckLoop = patterns.frequencies.some(f => f.type === 'stuck-loop' && f.count >= 2);
|
|
106
|
-
const objectiveFailed = priorFailures.some(f =>
|
|
107
|
-
f.objective && objective.toLowerCase().includes(f.objective.toLowerCase().slice(0, 20))
|
|
108
|
-
);
|
|
109
|
-
if (hasStuckLoop || objectiveFailed) {
|
|
110
|
-
const base = objectiveFailed ? 0.8 : 0.6;
|
|
111
|
-
predictions.push({
|
|
112
|
-
mode: 'wrong-approach',
|
|
113
|
-
likelihood: applyWeight('wrong-approach', base),
|
|
114
|
-
basis: objectiveFailed
|
|
115
|
-
? 'Prior attempt at this objective failed'
|
|
116
|
-
: 'Diagnostic shows stuck-loop pattern in session',
|
|
117
|
-
prevention: `Try a fundamentally different approach than previous attempts. If stuck after 2 tries, report back with what was tried.`,
|
|
118
|
-
});
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
// blocked-dependency
|
|
122
|
-
const refsOtherWave = activeWaves.some(w =>
|
|
123
|
-
objective.toLowerCase().includes(w.output?.toLowerCase()?.slice(0, 20) || '___none')
|
|
124
|
-
);
|
|
125
|
-
if (refsOtherWave) {
|
|
126
|
-
predictions.push({
|
|
127
|
-
mode: 'blocked-dependency',
|
|
128
|
-
likelihood: applyWeight('blocked-dependency', 0.5),
|
|
129
|
-
basis: 'Objective references output from an in-progress wave',
|
|
130
|
-
prevention: `If blocked by a dependency from another wave, pivot to independent work or report the blocker.`,
|
|
131
|
-
});
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
// stale-assumption
|
|
135
|
-
if (lastReadAge > 5 * 60 * 1000 && files.length > 0) {
|
|
136
|
-
predictions.push({
|
|
137
|
-
mode: 'stale-assumption',
|
|
138
|
-
likelihood: applyWeight('stale-assumption', 0.4),
|
|
139
|
-
basis: `Files in scope were last read ${Math.round(lastReadAge / 60000)}m ago — may have changed`,
|
|
140
|
-
prevention: `Re-read ${files.slice(0, 3).join(', ')} before assuming current state.`,
|
|
141
|
-
});
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
return predictions;
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
export function generatePreventions(predictions) {
|
|
148
|
-
const actionable = predictions
|
|
149
|
-
.filter(p => p.likelihood >= 0.4)
|
|
150
|
-
.sort((a, b) => b.likelihood - a.likelihood)
|
|
151
|
-
.slice(0, 5);
|
|
152
|
-
|
|
153
|
-
if (!actionable.length) return '';
|
|
154
|
-
|
|
155
|
-
const lines = actionable.map(p => `- [${p.prevention}]`);
|
|
156
|
-
return `⚠ Pre-flight awareness:\n${lines.join('\n')}`;
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
export function scoreDispatchReadiness(agentSpec, wavePlan = {}, predictions = []) {
|
|
160
|
-
const blockers = [];
|
|
161
|
-
const warnings = [];
|
|
162
|
-
let score = 1.0;
|
|
163
|
-
|
|
164
|
-
const files = agentSpec.scope?.files || [];
|
|
165
|
-
const priorSearch = wavePlan.completedSearchWave || false;
|
|
166
|
-
const hasContext = files.length > 0 || priorSearch;
|
|
167
|
-
|
|
168
|
-
// Scope researched?
|
|
169
|
-
if (!hasContext) {
|
|
170
|
-
blockers.push('No files in scope and no prior search wave — context unknown');
|
|
171
|
-
score -= 0.3;
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
// High-likelihood predictions
|
|
175
|
-
const highRisk = predictions.filter(p => p.likelihood >= 0.7);
|
|
176
|
-
const medRisk = predictions.filter(p => p.likelihood >= 0.4 && p.likelihood < 0.7);
|
|
177
|
-
|
|
178
|
-
for (const p of highRisk) {
|
|
179
|
-
blockers.push(`High-risk: ${p.mode} (${Math.round(p.likelihood * 100)}%) — ${p.basis}`);
|
|
180
|
-
score -= 0.25;
|
|
181
|
-
}
|
|
182
|
-
for (const p of medRisk) {
|
|
183
|
-
warnings.push(`${p.mode} (${Math.round(p.likelihood * 100)}%) — ${p.basis}`);
|
|
184
|
-
score -= 0.1;
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
// Unresolved blockers from prior waves
|
|
188
|
-
const unresolvedBlockers = wavePlan.unresolvedBlockers || [];
|
|
189
|
-
for (const b of unresolvedBlockers) {
|
|
190
|
-
blockers.push(`Unresolved from prior wave: ${b}`);
|
|
191
|
-
score -= 0.2;
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
score = Math.max(0, Math.min(1, score));
|
|
195
|
-
const ready = score >= 0.5 && blockers.length === 0;
|
|
196
|
-
|
|
197
|
-
let suggestion = '';
|
|
198
|
-
if (!ready) {
|
|
199
|
-
if (blockers.some(b => b.includes('context unknown'))) {
|
|
200
|
-
suggestion = 'Run a search/read wave first to establish context before executing.';
|
|
201
|
-
} else if (highRisk.length) {
|
|
202
|
-
suggestion = `Address high-risk predictions: ${highRisk.map(p => p.mode).join(', ')}. Add preventions to prompt or restructure scope.`;
|
|
203
|
-
} else {
|
|
204
|
-
suggestion = 'Resolve listed blockers before dispatching.';
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
return { ready, score, blockers, warnings, suggestion };
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
export function evolvePatterns(newDebrief, predictions) {
|
|
212
|
-
const weights = loadWeights();
|
|
213
|
-
|
|
214
|
-
for (const pred of predictions) {
|
|
215
|
-
if (!weights[pred.mode]) {
|
|
216
|
-
weights[pred.mode] = { correct: 0, incorrect: 0, accuracy: 0.5 };
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
const w = weights[pred.mode];
|
|
220
|
-
const occurred = debriefContainsPattern(newDebrief, pred.mode);
|
|
221
|
-
|
|
222
|
-
if (occurred && pred.likelihood >= 0.4) {
|
|
223
|
-
w.correct++;
|
|
224
|
-
} else if (!occurred && pred.likelihood >= 0.4) {
|
|
225
|
-
w.incorrect++;
|
|
226
|
-
} else if (occurred && pred.likelihood < 0.4) {
|
|
227
|
-
// Missed prediction — we should have predicted higher
|
|
228
|
-
w.incorrect++;
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
const total = w.correct + w.incorrect;
|
|
232
|
-
w.accuracy = total > 0 ? w.correct / total : 0.5;
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
mkdirSync(DIAG_DIR, { recursive: true });
|
|
236
|
-
writeFileSync(WEIGHTS_PATH, JSON.stringify(weights, null, 2));
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
function debriefContainsPattern(debrief, mode) {
|
|
240
|
-
if (!debrief) return false;
|
|
241
|
-
const modeMap = {
|
|
242
|
-
'scope-explosion': ['scope-creep', 'scope_explosion', 'expanded'],
|
|
243
|
-
'missing-context': ['missing-context', 'no_context', 'searched'],
|
|
244
|
-
'wrong-approach': ['stuck-loop', 'wrong_approach', 'retry'],
|
|
245
|
-
'blocked-dependency': ['blocked', 'dependency', 'waiting'],
|
|
246
|
-
'stale-assumption': ['stale', 'outdated', 'changed'],
|
|
247
|
-
};
|
|
248
|
-
const text = JSON.stringify([...(debrief.issues || []), ...(debrief.patterns || [])]).toLowerCase();
|
|
249
|
-
return (modeMap[mode] || [mode]).some(k => text.includes(k));
|
|
250
|
-
}
|