@mneme-ai/core 2.61.0 → 2.63.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/dist/agent_manifest.d.ts.map +1 -1
- package/dist/agent_manifest.js +10 -0
- package/dist/agent_manifest.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -1
- package/dist/mirrage/conscience_ladder.d.ts +35 -0
- package/dist/mirrage/conscience_ladder.d.ts.map +1 -0
- package/dist/mirrage/conscience_ladder.js +39 -0
- package/dist/mirrage/conscience_ladder.js.map +1 -0
- package/dist/mirrage/heuristics.d.ts +40 -0
- package/dist/mirrage/heuristics.d.ts.map +1 -0
- package/dist/mirrage/heuristics.js +105 -0
- package/dist/mirrage/heuristics.js.map +1 -0
- package/dist/mirrage/index.d.ts +160 -0
- package/dist/mirrage/index.d.ts.map +1 -0
- package/dist/mirrage/index.js +296 -0
- package/dist/mirrage/index.js.map +1 -0
- package/dist/mirrage/sentence_splitter.d.ts +22 -0
- package/dist/mirrage/sentence_splitter.d.ts.map +1 -0
- package/dist/mirrage/sentence_splitter.js +86 -0
- package/dist/mirrage/sentence_splitter.js.map +1 -0
- package/dist/time_crystal/gotcha_detector.d.ts +31 -0
- package/dist/time_crystal/gotcha_detector.d.ts.map +1 -0
- package/dist/time_crystal/gotcha_detector.js +81 -0
- package/dist/time_crystal/gotcha_detector.js.map +1 -0
- package/dist/time_crystal/index.d.ts +158 -0
- package/dist/time_crystal/index.d.ts.map +1 -0
- package/dist/time_crystal/index.js +289 -0
- package/dist/time_crystal/index.js.map +1 -0
- package/dist/time_crystal/problem_fingerprint.d.ts +43 -0
- package/dist/time_crystal/problem_fingerprint.d.ts.map +1 -0
- package/dist/time_crystal/problem_fingerprint.js +101 -0
- package/dist/time_crystal/problem_fingerprint.js.map +1 -0
- package/dist/time_crystal/ranking.d.ts +60 -0
- package/dist/time_crystal/ranking.d.ts.map +1 -0
- package/dist/time_crystal/ranking.js +90 -0
- package/dist/time_crystal/ranking.js.map +1 -0
- package/dist/truth_gate/claims.d.ts.map +1 -1
- package/dist/truth_gate/claims.js +38 -0
- package/dist/truth_gate/claims.js.map +1 -1
- package/dist/truth_gate/probes.d.ts.map +1 -1
- package/dist/truth_gate/probes.js +110 -0
- package/dist/truth_gate/probes.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v2.62.0 — MIRRAGE: live conscience for AI agents via MCP reverse-channel.
|
|
3
|
+
*
|
|
4
|
+
* User-framing roadmap (set v2.60 → continuing): conscience + memory +
|
|
5
|
+
* diplomat + bodyguard + time machine. v2.60=bodyguard (SKELETON KEY),
|
|
6
|
+
* v2.61=diplomat (PASSPORT), v2.62=**conscience** (MIRRAGE).
|
|
7
|
+
*
|
|
8
|
+
* Pre-MIRRAGE pattern: AI agent generates draft → user sees draft →
|
|
9
|
+
* IF user notices factual error → user corrects. Mneme only enters
|
|
10
|
+
* after user complaint. That's reactive.
|
|
11
|
+
*
|
|
12
|
+
* MIRRAGE flips it: BEFORE the agent commits a draft, it calls
|
|
13
|
+
* `mneme.mirrage.scan {draft}`; Mneme returns per-sentence nudges
|
|
14
|
+
* graded by 5-level CONSCIENCE LADDER (hint/suggestion/warning/
|
|
15
|
+
* block/reject) + suggested edit. The agent reads the nudges back
|
|
16
|
+
* into its own context and self-corrects BEFORE shipping to user.
|
|
17
|
+
*
|
|
18
|
+
* The "reverse channel" angle: MCP is normally pull (agent asks
|
|
19
|
+
* tool). MIRRAGE = push (Mneme injects warnings into agent's
|
|
20
|
+
* reflection step). One of the few legitimate uses of the MCP
|
|
21
|
+
* sampling primitive — agent's own model reads Mneme's verdict
|
|
22
|
+
* inline.
|
|
23
|
+
*
|
|
24
|
+
* 5 wild innovations:
|
|
25
|
+
*
|
|
26
|
+
* 1. CONSCIENCE LADDER (`conscience_ladder.ts`) — 5 escalation
|
|
27
|
+
* tiers (hint/suggestion/warning/block/reject) by risk score.
|
|
28
|
+
* Blocking tiers refuse to ship until agent retracts.
|
|
29
|
+
*
|
|
30
|
+
* 2. NUDGE-FATIGUE GATING — if the same agent received N similar
|
|
31
|
+
* nudges in the last 60min, downgrade priority. Avoid spam.
|
|
32
|
+
*
|
|
33
|
+
* 3. CROSS-AGENT WISDOM SHARING — when an agent ACK's a nudge,
|
|
34
|
+
* the lesson becomes a candidate broadcast for other agents
|
|
35
|
+
* in the project. Wisdom propagates.
|
|
36
|
+
*
|
|
37
|
+
* 4. STREAMING PARTIAL SCAN — accept cursor position; only scan
|
|
38
|
+
* sentences that ENDED before cursor (in-progress sentence
|
|
39
|
+
* skipped). Lets agents call scan continuously while writing.
|
|
40
|
+
*
|
|
41
|
+
* 5. HMAC-CHAINED NUDGE LEDGER — every scan + ack chains HMACs.
|
|
42
|
+
* Tamper-evident; court-admissible record of what the agent
|
|
43
|
+
* was warned about + when.
|
|
44
|
+
*/
|
|
45
|
+
import { createHash, createHmac } from "node:crypto";
|
|
46
|
+
import { appendFileSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
47
|
+
import { dirname, join } from "node:path";
|
|
48
|
+
import { splitSentences } from "./sentence_splitter.js";
|
|
49
|
+
import { extractFeatures, riskFromFeatures } from "./heuristics.js";
|
|
50
|
+
import { LEVELS, anyBlocks, levelForRisk } from "./conscience_ladder.js";
|
|
51
|
+
const KEY_ENV = "MNEME_MIRRAGE_KEY";
|
|
52
|
+
const DEFAULT_KEY = "mneme-mirrage-v1";
|
|
53
|
+
function keyOf() { return process.env[KEY_ENV] ?? DEFAULT_KEY; }
|
|
54
|
+
/* ── Canonical JSON HMAC (same convention as PASSPORT) ──────────── */
|
|
55
|
+
function canonicalJson(o) {
|
|
56
|
+
if (o === undefined)
|
|
57
|
+
return "null";
|
|
58
|
+
if (o === null || typeof o !== "object")
|
|
59
|
+
return JSON.stringify(o);
|
|
60
|
+
if (Array.isArray(o))
|
|
61
|
+
return "[" + o.map((x) => canonicalJson(x === undefined ? null : x)).join(",") + "]";
|
|
62
|
+
const entries = Object.entries(o).filter(([, v]) => v !== undefined);
|
|
63
|
+
entries.sort(([a], [b]) => a.localeCompare(b));
|
|
64
|
+
return "{" + entries.map(([k, v]) => JSON.stringify(k) + ":" + canonicalJson(v)).join(",") + "}";
|
|
65
|
+
}
|
|
66
|
+
function signHmac(body) {
|
|
67
|
+
return createHmac("sha256", keyOf()).update(canonicalJson(body)).digest("hex");
|
|
68
|
+
}
|
|
69
|
+
function ledgerPath(cwd) {
|
|
70
|
+
return join(cwd, ".mneme", "mirrage", "ledger.jsonl");
|
|
71
|
+
}
|
|
72
|
+
function lastLedgerHmac(cwd) {
|
|
73
|
+
try {
|
|
74
|
+
const lines = readFileSync(ledgerPath(cwd), "utf8").trim().split(/\n/).filter((l) => l.trim().length > 0);
|
|
75
|
+
if (lines.length === 0)
|
|
76
|
+
return "";
|
|
77
|
+
return JSON.parse(lines[lines.length - 1]).hmac;
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
return "";
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
function appendLedger(cwd, entry) {
|
|
84
|
+
const prevHmac = lastLedgerHmac(cwd);
|
|
85
|
+
const body = { ...entry, prevHmac };
|
|
86
|
+
const hmac = createHmac("sha256", keyOf()).update(prevHmac).update(canonicalJson(body)).digest("hex");
|
|
87
|
+
const row = { ...body, hmac };
|
|
88
|
+
try {
|
|
89
|
+
mkdirSync(dirname(ledgerPath(cwd)), { recursive: true });
|
|
90
|
+
appendFileSync(ledgerPath(cwd), JSON.stringify(row) + "\n");
|
|
91
|
+
}
|
|
92
|
+
catch { /* noop */ }
|
|
93
|
+
return row;
|
|
94
|
+
}
|
|
95
|
+
export function readLedger(cwd) {
|
|
96
|
+
try {
|
|
97
|
+
return readFileSync(ledgerPath(cwd), "utf8").trim().split(/\n/).filter((l) => l.trim().length > 0).map((l) => JSON.parse(l));
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
return [];
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
export function verifyLedgerChain(cwd) {
|
|
104
|
+
const lines = readLedger(cwd);
|
|
105
|
+
let prevHmac = "";
|
|
106
|
+
for (let i = 0; i < lines.length; i++) {
|
|
107
|
+
const row = lines[i];
|
|
108
|
+
if (row.prevHmac !== prevHmac)
|
|
109
|
+
return { ok: false, rows: i, brokenAt: i };
|
|
110
|
+
const { hmac, ...body } = row;
|
|
111
|
+
const expected = createHmac("sha256", keyOf()).update(prevHmac).update(canonicalJson(body)).digest("hex");
|
|
112
|
+
if (expected !== hmac)
|
|
113
|
+
return { ok: false, rows: i, brokenAt: i };
|
|
114
|
+
prevHmac = hmac;
|
|
115
|
+
}
|
|
116
|
+
return { ok: true, rows: lines.length };
|
|
117
|
+
}
|
|
118
|
+
/* ── Nudge-fatigue gating ───────────────────────────────────────── */
|
|
119
|
+
function fatiguePath(cwd) {
|
|
120
|
+
return join(cwd, ".mneme", "mirrage", "fatigue.json");
|
|
121
|
+
}
|
|
122
|
+
function readFatigue(cwd) {
|
|
123
|
+
try {
|
|
124
|
+
return JSON.parse(readFileSync(fatiguePath(cwd), "utf8"));
|
|
125
|
+
}
|
|
126
|
+
catch {
|
|
127
|
+
return { records: {} };
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
function writeFatigue(cwd, f) {
|
|
131
|
+
try {
|
|
132
|
+
mkdirSync(dirname(fatiguePath(cwd)), { recursive: true });
|
|
133
|
+
writeFileSync(fatiguePath(cwd), JSON.stringify(f, null, 2));
|
|
134
|
+
}
|
|
135
|
+
catch { /* noop */ }
|
|
136
|
+
}
|
|
137
|
+
function sentenceFingerprint(sentence) {
|
|
138
|
+
// Normalise whitespace + lowercase + hash.
|
|
139
|
+
const norm = sentence.replace(/\s+/g, " ").trim().toLowerCase();
|
|
140
|
+
return createHash("sha256").update(norm).digest("hex").slice(0, 16);
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Downgrade priority if the agent recently ACK'd N similar nudges.
|
|
144
|
+
* Returns a 0..1 multiplier on risk (1.0 = no fatigue; 0.6 = downgraded).
|
|
145
|
+
*/
|
|
146
|
+
function fatigueMultiplier(cwd, agent, fingerprint) {
|
|
147
|
+
const f = readFatigue(cwd);
|
|
148
|
+
const key = `${agent}|${fingerprint}`;
|
|
149
|
+
const rec = f.records[key];
|
|
150
|
+
if (!rec)
|
|
151
|
+
return 1.0;
|
|
152
|
+
const hoursSince = (Date.now() - new Date(rec.lastSeen).getTime()) / (60 * 60 * 1000);
|
|
153
|
+
if (hoursSince > 1)
|
|
154
|
+
return 1.0; // fatigue resets after 1 hour
|
|
155
|
+
// After 3 ACKs in 1 hour → downgrade 40%.
|
|
156
|
+
return Math.max(0.6, 1.0 - rec.count * 0.13);
|
|
157
|
+
}
|
|
158
|
+
/* ── Cross-agent wisdom broadcast ───────────────────────────────── */
|
|
159
|
+
function wisdomPath(cwd) {
|
|
160
|
+
return join(cwd, ".mneme", "mirrage", "wisdom_broadcasts.jsonl");
|
|
161
|
+
}
|
|
162
|
+
export function broadcastWisdom(cwd, lesson) {
|
|
163
|
+
try {
|
|
164
|
+
mkdirSync(dirname(wisdomPath(cwd)), { recursive: true });
|
|
165
|
+
appendFileSync(wisdomPath(cwd), JSON.stringify({ ...lesson, at: new Date().toISOString() }) + "\n");
|
|
166
|
+
}
|
|
167
|
+
catch { /* noop */ }
|
|
168
|
+
}
|
|
169
|
+
export function readWisdom(cwd) {
|
|
170
|
+
try {
|
|
171
|
+
return readFileSync(wisdomPath(cwd), "utf8").trim().split(/\n/).filter((l) => l.trim().length > 0).map((l) => JSON.parse(l));
|
|
172
|
+
}
|
|
173
|
+
catch {
|
|
174
|
+
return [];
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
/* ── Scan ───────────────────────────────────────────────────────── */
|
|
178
|
+
function suggestedReplacement(sentence, features) {
|
|
179
|
+
// Simple hedging: if absolutes were the driver, hedge them.
|
|
180
|
+
let s = sentence;
|
|
181
|
+
if (features.absolutes > 0) {
|
|
182
|
+
s = s.replace(/\balways\b/gi, "often")
|
|
183
|
+
.replace(/\bnever\b/gi, "rarely")
|
|
184
|
+
.replace(/\ball\b/gi, "many")
|
|
185
|
+
.replace(/\bevery\b/gi, "many")
|
|
186
|
+
.replace(/\bdefinitely\b/gi, "likely")
|
|
187
|
+
.replace(/\bcertainly\b/gi, "likely")
|
|
188
|
+
.replace(/\babsolutely\b/gi, "likely")
|
|
189
|
+
.replace(/\bguaranteed\b/gi, "likely")
|
|
190
|
+
.replace(/\bcannot\b/gi, "may not")
|
|
191
|
+
.replace(/\bmust\b/gi, "should");
|
|
192
|
+
if (s !== sentence)
|
|
193
|
+
return s;
|
|
194
|
+
}
|
|
195
|
+
// If entity-driven, the agent should verify — we don't auto-rewrite entities.
|
|
196
|
+
return undefined;
|
|
197
|
+
}
|
|
198
|
+
export function scanDraft(input) {
|
|
199
|
+
const at = new Date().toISOString();
|
|
200
|
+
const cwd = input.cwd ?? process.cwd();
|
|
201
|
+
const minRisk = input.minRisk ?? 0.30;
|
|
202
|
+
const t0 = performance.now();
|
|
203
|
+
const draft = typeof input.draft === "string" ? input.draft : "";
|
|
204
|
+
const all = splitSentences(draft);
|
|
205
|
+
// Streaming filter: only sentences ending strictly before cursor.
|
|
206
|
+
const sentences = typeof input.cursorPos === "number"
|
|
207
|
+
? all.filter((s) => s.end <= input.cursorPos)
|
|
208
|
+
: all;
|
|
209
|
+
const nudges = [];
|
|
210
|
+
for (const sent of sentences) {
|
|
211
|
+
const features = extractFeatures(sent.text);
|
|
212
|
+
const { risk: rawRisk, drivers } = riskFromFeatures(features);
|
|
213
|
+
const fp = sentenceFingerprint(sent.text);
|
|
214
|
+
const mul = input.noFatigueGate ? 1.0 : fatigueMultiplier(cwd, input.agent, fp);
|
|
215
|
+
const risk = Math.max(0, Math.min(1, rawRisk * mul));
|
|
216
|
+
const level = levelForRisk(risk);
|
|
217
|
+
if (!level || risk < minRisk)
|
|
218
|
+
continue;
|
|
219
|
+
const suggested = suggestedReplacement(sent.text, features);
|
|
220
|
+
const meta = LEVELS[level];
|
|
221
|
+
const nudgeBody = {
|
|
222
|
+
sentence: sent.text,
|
|
223
|
+
offset: sent.start,
|
|
224
|
+
level, symbol: meta.symbol, risk: +risk.toFixed(4),
|
|
225
|
+
drivers, suggested, blocksShip: meta.blocksShip, features,
|
|
226
|
+
};
|
|
227
|
+
nudges.push({
|
|
228
|
+
...nudgeBody,
|
|
229
|
+
id: createHash("sha256").update(`${at}|${sent.start}|${sent.text}`).digest("hex").slice(0, 16),
|
|
230
|
+
hmac: signHmac(nudgeBody),
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
// Compose suggested edit: replace nudge sentences with suggested form or drop.
|
|
234
|
+
let suggestedEdit = draft;
|
|
235
|
+
for (const n of nudges.slice().sort((a, b) => b.offset - a.offset)) {
|
|
236
|
+
const end = n.offset + n.sentence.length;
|
|
237
|
+
const replacement = n.suggested ?? `[retracted: ${n.symbol} ${n.level}]`;
|
|
238
|
+
suggestedEdit = suggestedEdit.slice(0, n.offset) + replacement + suggestedEdit.slice(end);
|
|
239
|
+
}
|
|
240
|
+
const scanId = createHash("sha256").update(`${at}|${input.agent}|${draft.slice(0, 64)}`).digest("hex").slice(0, 16);
|
|
241
|
+
const totalLatencyMs = +(performance.now() - t0).toFixed(2);
|
|
242
|
+
const blocksShip = anyBlocks(nudges.map((n) => n.level));
|
|
243
|
+
const bodyForHmac = { scanId, at, agent: input.agent, draftLength: draft.length, sentenceCount: sentences.length, nudges, suggestedEdit, blocksShip, totalLatencyMs };
|
|
244
|
+
const hmac = signHmac(bodyForHmac);
|
|
245
|
+
if (!input.noLedger)
|
|
246
|
+
appendLedger(cwd, { kind: "scan", at, scanId, agent: input.agent });
|
|
247
|
+
return { ...bodyForHmac, hmac };
|
|
248
|
+
}
|
|
249
|
+
export function verifyScanResult(r) {
|
|
250
|
+
if (!r || typeof r.hmac !== "string")
|
|
251
|
+
return false;
|
|
252
|
+
const { hmac, ...body } = r;
|
|
253
|
+
return signHmac(body) === hmac;
|
|
254
|
+
}
|
|
255
|
+
export function acknowledgeNudge(input) {
|
|
256
|
+
const cwd = input.cwd ?? process.cwd();
|
|
257
|
+
// Bump fatigue counter for this (agent, fingerprint) so future scans downgrade.
|
|
258
|
+
if (input.fingerprint) {
|
|
259
|
+
const f = readFatigue(cwd);
|
|
260
|
+
const key = `${input.agent}|${input.fingerprint}`;
|
|
261
|
+
const rec = f.records[key];
|
|
262
|
+
f.records[key] = { count: (rec?.count ?? 0) + 1, lastSeen: new Date().toISOString() };
|
|
263
|
+
writeFatigue(cwd, f);
|
|
264
|
+
}
|
|
265
|
+
// Append ledger row.
|
|
266
|
+
appendLedger(cwd, { kind: "ack", at: new Date().toISOString(), scanId: input.scanId, agent: input.agent, nudgeId: input.nudgeId, level: input.level });
|
|
267
|
+
// Broadcast wisdom if requested.
|
|
268
|
+
let broadcast = false;
|
|
269
|
+
if (input.broadcast && input.sentence && input.level && input.reason) {
|
|
270
|
+
broadcastWisdom(cwd, { sourceAgent: input.agent, sentence: input.sentence, level: input.level, reason: input.reason });
|
|
271
|
+
appendLedger(cwd, { kind: "broadcast", at: new Date().toISOString(), scanId: input.scanId, agent: input.agent, nudgeId: input.nudgeId, level: input.level });
|
|
272
|
+
broadcast = true;
|
|
273
|
+
}
|
|
274
|
+
return { ok: true, hint: broadcast ? "acked + wisdom broadcast" : "acked", broadcast };
|
|
275
|
+
}
|
|
276
|
+
/* ── Render ─────────────────────────────────────────────────────── */
|
|
277
|
+
export function renderBanner(r) {
|
|
278
|
+
const lines = [
|
|
279
|
+
`🪞 MIRRAGE · ${r.nudges.length} nudge(s) on ${r.sentenceCount} sentence(s) — ${r.totalLatencyMs}ms`,
|
|
280
|
+
r.blocksShip ? " 🛑 SHIP BLOCKED until retract" : " ✓ ship allowed",
|
|
281
|
+
"",
|
|
282
|
+
];
|
|
283
|
+
for (const n of r.nudges) {
|
|
284
|
+
lines.push(` ${n.symbol} ${n.level.padEnd(11)} risk=${(n.risk * 100).toFixed(0)}% ${n.sentence.slice(0, 100)}${n.sentence.length > 100 ? "…" : ""}`);
|
|
285
|
+
if (n.drivers.length > 0)
|
|
286
|
+
lines.push(` ↳ ${n.drivers.join(" · ")}`);
|
|
287
|
+
if (n.suggested)
|
|
288
|
+
lines.push(` ↳ suggested: ${n.suggested.slice(0, 100)}`);
|
|
289
|
+
}
|
|
290
|
+
return lines.join("\n");
|
|
291
|
+
}
|
|
292
|
+
/* ── Re-exports ─────────────────────────────────────────────────── */
|
|
293
|
+
export { splitSentences } from "./sentence_splitter.js";
|
|
294
|
+
export { extractFeatures, riskFromFeatures } from "./heuristics.js";
|
|
295
|
+
export { LEVELS, levelForRisk, anyBlocks } from "./conscience_ladder.js";
|
|
296
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/mirrage/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v2.62.0 — MIRRAGE sentence splitter.
|
|
3
|
+
*
|
|
4
|
+
* Splits a draft into sentence chunks suitable for per-claim ACGV /
|
|
5
|
+
* heuristic check. Handles:
|
|
6
|
+
* - common English abbreviations (Mr., Dr., e.g., i.e., etc.)
|
|
7
|
+
* - decimal numbers (3.14)
|
|
8
|
+
* - URLs / file paths (https://example.com / src/file.ts)
|
|
9
|
+
* - inline code blocks (preserved as single chunk)
|
|
10
|
+
*
|
|
11
|
+
* Pure, defensive — never throws.
|
|
12
|
+
*/
|
|
13
|
+
export interface Sentence {
|
|
14
|
+
/** Original sentence text. */
|
|
15
|
+
text: string;
|
|
16
|
+
/** Character offset where the sentence starts in the original draft. */
|
|
17
|
+
start: number;
|
|
18
|
+
/** Character offset where the sentence ends (exclusive). */
|
|
19
|
+
end: number;
|
|
20
|
+
}
|
|
21
|
+
export declare function splitSentences(draft: string): Sentence[];
|
|
22
|
+
//# sourceMappingURL=sentence_splitter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sentence_splitter.d.ts","sourceRoot":"","sources":["../../src/mirrage/sentence_splitter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAQH,MAAM,WAAW,QAAQ;IACvB,8BAA8B;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,wEAAwE;IACxE,KAAK,EAAE,MAAM,CAAC;IACd,4DAA4D;IAC5D,GAAG,EAAE,MAAM,CAAC;CACb;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ,EAAE,CAwDxD"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v2.62.0 — MIRRAGE sentence splitter.
|
|
3
|
+
*
|
|
4
|
+
* Splits a draft into sentence chunks suitable for per-claim ACGV /
|
|
5
|
+
* heuristic check. Handles:
|
|
6
|
+
* - common English abbreviations (Mr., Dr., e.g., i.e., etc.)
|
|
7
|
+
* - decimal numbers (3.14)
|
|
8
|
+
* - URLs / file paths (https://example.com / src/file.ts)
|
|
9
|
+
* - inline code blocks (preserved as single chunk)
|
|
10
|
+
*
|
|
11
|
+
* Pure, defensive — never throws.
|
|
12
|
+
*/
|
|
13
|
+
const ABBREVIATIONS = new Set([
|
|
14
|
+
"mr", "mrs", "ms", "dr", "prof", "sr", "jr", "st", "vs", "etc",
|
|
15
|
+
"e.g", "i.e", "u.s", "u.k", "no", "vol", "fig", "approx", "min", "max",
|
|
16
|
+
"inc", "ltd", "co", "corp", "esp", "incl", "exc",
|
|
17
|
+
]);
|
|
18
|
+
export function splitSentences(draft) {
|
|
19
|
+
if (typeof draft !== "string" || draft.length === 0)
|
|
20
|
+
return [];
|
|
21
|
+
const out = [];
|
|
22
|
+
let buf = "";
|
|
23
|
+
let bufStart = 0;
|
|
24
|
+
let i = 0;
|
|
25
|
+
let inCode = false;
|
|
26
|
+
let inUrl = false;
|
|
27
|
+
const flush = (offset) => {
|
|
28
|
+
const trimmed = buf.trim();
|
|
29
|
+
if (trimmed.length > 0) {
|
|
30
|
+
out.push({ text: trimmed, start: bufStart + buf.indexOf(trimmed), end: offset });
|
|
31
|
+
}
|
|
32
|
+
buf = "";
|
|
33
|
+
bufStart = offset;
|
|
34
|
+
};
|
|
35
|
+
while (i < draft.length) {
|
|
36
|
+
const ch = draft[i];
|
|
37
|
+
const next = draft[i + 1] ?? "";
|
|
38
|
+
// Track inline code blocks (single backtick segments).
|
|
39
|
+
if (ch === "`") {
|
|
40
|
+
inCode = !inCode;
|
|
41
|
+
buf += ch;
|
|
42
|
+
i++;
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
if (inCode) {
|
|
46
|
+
buf += ch;
|
|
47
|
+
i++;
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
// Track URLs heuristically: "://" entered, exit on whitespace.
|
|
51
|
+
if (ch === ":" && draft.slice(i, i + 3) === "://")
|
|
52
|
+
inUrl = true;
|
|
53
|
+
if (inUrl && /\s/.test(ch))
|
|
54
|
+
inUrl = false;
|
|
55
|
+
if (inUrl) {
|
|
56
|
+
buf += ch;
|
|
57
|
+
i++;
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
// Decimals: digit . digit → keep
|
|
61
|
+
if (ch === "." && /\d/.test(draft[i - 1] ?? "") && /\d/.test(next)) {
|
|
62
|
+
buf += ch;
|
|
63
|
+
i++;
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
// Abbreviation lookback: split only when next char is space/newline AND
|
|
67
|
+
// preceding word is NOT a known abbreviation.
|
|
68
|
+
if ((ch === "." || ch === "!" || ch === "?") && (/\s|$/.test(next) || i === draft.length - 1)) {
|
|
69
|
+
buf += ch;
|
|
70
|
+
// Inspect last word before the punctuation.
|
|
71
|
+
const lastSpace = Math.max(buf.lastIndexOf(" ", buf.length - 2), buf.lastIndexOf("\n", buf.length - 2));
|
|
72
|
+
const lastWord = buf.slice(lastSpace + 1, buf.length - 1).toLowerCase();
|
|
73
|
+
if (!ABBREVIATIONS.has(lastWord)) {
|
|
74
|
+
flush(i + 1);
|
|
75
|
+
bufStart = i + 1;
|
|
76
|
+
}
|
|
77
|
+
i++;
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
buf += ch;
|
|
81
|
+
i++;
|
|
82
|
+
}
|
|
83
|
+
flush(draft.length);
|
|
84
|
+
return out;
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=sentence_splitter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sentence_splitter.js","sourceRoot":"","sources":["../../src/mirrage/sentence_splitter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v2.63.0 — TIME-CRYSTAL gotcha detector.
|
|
3
|
+
*
|
|
4
|
+
* When an approach has MIXED outcomes (worked for some agents, failed
|
|
5
|
+
* for others), the failure-environment pattern is signal: there exists
|
|
6
|
+
* a CONDITION under which the approach breaks. Surface that.
|
|
7
|
+
*
|
|
8
|
+
* Algorithm:
|
|
9
|
+
* 1. For each approach group with ≥1 success AND ≥1 failure,
|
|
10
|
+
* compute the env keys / values that appear MORE OFTEN in
|
|
11
|
+
* failures than successes (information gain).
|
|
12
|
+
* 2. Emit gotcha rows: { approach, triggerConditions, severity }.
|
|
13
|
+
* 3. Also fold any explicit free-text notes that contain "fail" /
|
|
14
|
+
* "break" / "ไม่ work" / "พัง" / "doesn't" keywords.
|
|
15
|
+
*/
|
|
16
|
+
import type { WisdomRecord } from "./ranking.js";
|
|
17
|
+
export interface Gotcha {
|
|
18
|
+
approach: string;
|
|
19
|
+
/** Env conditions where this approach has elevated failure risk. */
|
|
20
|
+
triggerConditions: Array<{
|
|
21
|
+
key: string;
|
|
22
|
+
value: string;
|
|
23
|
+
failRateGain: number;
|
|
24
|
+
}>;
|
|
25
|
+
/** 0..1 severity score (higher = more reliable failure pattern). */
|
|
26
|
+
severity: number;
|
|
27
|
+
/** Free-text notes from contributors. */
|
|
28
|
+
notes: string[];
|
|
29
|
+
}
|
|
30
|
+
export declare function detectGotchas(records: WisdomRecord[]): Gotcha[];
|
|
31
|
+
//# sourceMappingURL=gotcha_detector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gotcha_detector.d.ts","sourceRoot":"","sources":["../../src/time_crystal/gotcha_detector.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAEjD,MAAM,WAAW,MAAM;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,oEAAoE;IACpE,iBAAiB,EAAE,KAAK,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/E,oEAAoE;IACpE,QAAQ,EAAE,MAAM,CAAC;IACjB,yCAAyC;IACzC,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAID,wBAAgB,aAAa,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,MAAM,EAAE,CA4D/D"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v2.63.0 — TIME-CRYSTAL gotcha detector.
|
|
3
|
+
*
|
|
4
|
+
* When an approach has MIXED outcomes (worked for some agents, failed
|
|
5
|
+
* for others), the failure-environment pattern is signal: there exists
|
|
6
|
+
* a CONDITION under which the approach breaks. Surface that.
|
|
7
|
+
*
|
|
8
|
+
* Algorithm:
|
|
9
|
+
* 1. For each approach group with ≥1 success AND ≥1 failure,
|
|
10
|
+
* compute the env keys / values that appear MORE OFTEN in
|
|
11
|
+
* failures than successes (information gain).
|
|
12
|
+
* 2. Emit gotcha rows: { approach, triggerConditions, severity }.
|
|
13
|
+
* 3. Also fold any explicit free-text notes that contain "fail" /
|
|
14
|
+
* "break" / "ไม่ work" / "พัง" / "doesn't" keywords.
|
|
15
|
+
*/
|
|
16
|
+
const FAILURE_WORDS = /\b(fail|fails|failed|fails?|break|breaks?|broke|doesn'?t|don'?t work|พัง|ใช้ไม่ได้|ไม่ work)\b/i;
|
|
17
|
+
export function detectGotchas(records) {
|
|
18
|
+
const byApproach = new Map();
|
|
19
|
+
for (const r of records) {
|
|
20
|
+
const k = r.approach.replace(/\s+/g, " ").trim().toLowerCase();
|
|
21
|
+
const list = byApproach.get(k) ?? [];
|
|
22
|
+
list.push(r);
|
|
23
|
+
byApproach.set(k, list);
|
|
24
|
+
}
|
|
25
|
+
const gotchas = [];
|
|
26
|
+
for (const [key, list] of byApproach.entries()) {
|
|
27
|
+
const successes = list.filter((r) => r.outcome === "success");
|
|
28
|
+
const failures = list.filter((r) => r.outcome === "failure");
|
|
29
|
+
if (failures.length === 0)
|
|
30
|
+
continue; // no signal
|
|
31
|
+
if (successes.length === 0 && failures.length < 3)
|
|
32
|
+
continue; // too few to call it a pattern
|
|
33
|
+
// Compute per-(key,value) failure-rate gain.
|
|
34
|
+
const envKeys = new Set();
|
|
35
|
+
for (const r of [...successes, ...failures])
|
|
36
|
+
for (const k of Object.keys(r.env ?? {}))
|
|
37
|
+
envKeys.add(k);
|
|
38
|
+
const triggers = [];
|
|
39
|
+
for (const k of envKeys) {
|
|
40
|
+
const valuesSeen = new Set();
|
|
41
|
+
for (const r of [...successes, ...failures]) {
|
|
42
|
+
const v = r.env?.[k];
|
|
43
|
+
if (v)
|
|
44
|
+
valuesSeen.add(v);
|
|
45
|
+
}
|
|
46
|
+
for (const v of valuesSeen) {
|
|
47
|
+
const failCountWithV = failures.filter((r) => r.env?.[k] === v).length;
|
|
48
|
+
const succCountWithV = successes.filter((r) => r.env?.[k] === v).length;
|
|
49
|
+
const totalWithV = failCountWithV + succCountWithV;
|
|
50
|
+
if (totalWithV < 2)
|
|
51
|
+
continue;
|
|
52
|
+
const failRate = failCountWithV / totalWithV;
|
|
53
|
+
const overallFailRate = failures.length / (failures.length + successes.length);
|
|
54
|
+
const gain = failRate - overallFailRate;
|
|
55
|
+
if (gain >= 0.30 && failRate >= 0.50) {
|
|
56
|
+
triggers.push({ key: k, value: v, failRateGain: +gain.toFixed(3) });
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
// Aggregate explicit notes that look like failure descriptions.
|
|
61
|
+
const notes = [];
|
|
62
|
+
for (const r of list) {
|
|
63
|
+
if (r.note && FAILURE_WORDS.test(r.note)) {
|
|
64
|
+
const norm = r.note.trim();
|
|
65
|
+
if (norm.length > 0 && !notes.includes(norm))
|
|
66
|
+
notes.push(norm);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
if (triggers.length === 0 && notes.length === 0)
|
|
70
|
+
continue;
|
|
71
|
+
const severity = Math.min(1, 0.4 + triggers.length * 0.15 + notes.length * 0.10 + (failures.length / Math.max(1, list.length)) * 0.30);
|
|
72
|
+
gotchas.push({
|
|
73
|
+
approach: list[0].approach, // representative casing
|
|
74
|
+
triggerConditions: triggers.sort((a, b) => b.failRateGain - a.failRateGain).slice(0, 5),
|
|
75
|
+
severity: +severity.toFixed(3),
|
|
76
|
+
notes: notes.slice(0, 5),
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
return gotchas.sort((a, b) => b.severity - a.severity);
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=gotcha_detector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gotcha_detector.js","sourceRoot":"","sources":["../../src/time_crystal/gotcha_detector.ts"],"names":[],"mappings":"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"}
|