@mneme-ai/core 2.19.85-lite → 2.19.86-lite

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.
@@ -0,0 +1,77 @@
1
+ /**
2
+ * v2.19.86 — TIME-MACHINE POLYGRAPH (IDEA #4).
3
+ *
4
+ * "Did this AI's answers DRIFT over the past 30 days?" — line chart of
5
+ * agreement-over-time per vendor, sourced from the same `pulse.jsonl`
6
+ * ledger that powers IDEA #2 (World Pulse globe). No new ledger; no
7
+ * new write path; pure read-side aggregation on the existing data.
8
+ *
9
+ * The seamless integration trick:
10
+ * - Every Browser Polygraph dot already records (ts, vendor, color)
11
+ * into pulse.jsonl as of v2.19.84.
12
+ * - Time-machine just buckets those events by time + vendor and
13
+ * reports a 0..1 honesty score per bucket.
14
+ * - If a vendor's honesty FALLS over time → drift visible.
15
+ * - If a vendor's honesty RISES over time → it learned (or got
16
+ * retrained).
17
+ * - Vertical markers can overlay known release dates (claude-3.5
18
+ * → claude-4 etc.) for visual correlation.
19
+ *
20
+ * No-Ollama by construction — pulse events already contain the verdict
21
+ * (green/yellow/red/grey) computed by the multi-signal agreement; time-
22
+ * machine is pure arithmetic on those existing scores.
23
+ */
24
+ export interface PulseEventLite {
25
+ ts: number;
26
+ vendor: string;
27
+ color: "green" | "yellow" | "red" | "grey";
28
+ }
29
+ export interface TimelineBucket {
30
+ /** Bucket start time, ISO 8601. */
31
+ bucketStart: string;
32
+ /** Total events in bucket. */
33
+ total: number;
34
+ green: number;
35
+ yellow: number;
36
+ red: number;
37
+ grey: number;
38
+ /** Honesty score for this bucket: green / (green+yellow+red).
39
+ * Null when no judged events (i.e. all grey or empty). */
40
+ honestyPct: number | null;
41
+ }
42
+ export interface TimelineSeries {
43
+ vendor: string;
44
+ windowDays: number;
45
+ bucketHours: number;
46
+ buckets: TimelineBucket[];
47
+ /** Min / max honestyPct seen in the series (excluding null buckets). */
48
+ minHonesty: number | null;
49
+ maxHonesty: number | null;
50
+ /** Drift = last (non-null) honesty − first (non-null) honesty.
51
+ * Negative = vendor got worse over time. */
52
+ drift: number | null;
53
+ /** Mean across all judged events in the window. */
54
+ meanHonesty: number | null;
55
+ }
56
+ /** Build a per-vendor time-bucketed honesty series from pulse events. */
57
+ export declare function buildTimeline(events: PulseEventLite[], vendor: string, opts?: {
58
+ windowDays?: number;
59
+ bucketHours?: number;
60
+ }): TimelineSeries;
61
+ /** Convenience: render a series as an ASCII chart for the CLI. Each
62
+ * bucket = 1 column; height = honestyPct. Empty buckets shown as `·`. */
63
+ export declare function renderAsciiChart(series: TimelineSeries, opts?: {
64
+ height?: number;
65
+ }): string;
66
+ /** v2.19.86 — Cross-vendor comparison: given a set of vendors, return a
67
+ * table {timestamp, vendor1.honestyPct, vendor2.honestyPct, ...}. Used
68
+ * by the dashboard to draw multi-vendor overlay lines. */
69
+ export interface CrossVendorRow {
70
+ bucketStart: string;
71
+ [vendor: string]: string | number | null;
72
+ }
73
+ export declare function buildCrossVendorTable(events: PulseEventLite[], vendors: string[], opts?: {
74
+ windowDays?: number;
75
+ bucketHours?: number;
76
+ }): CrossVendorRow[];
77
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/time_machine/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,OAAO,GAAG,QAAQ,GAAG,KAAK,GAAG,MAAM,CAAC;CAC5C;AAED,MAAM,WAAW,cAAc;IAC7B,mCAAmC;IACnC,WAAW,EAAE,MAAM,CAAC;IACpB,8BAA8B;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IACzD;+DAC2D;IAC3D,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,wEAAwE;IACxE,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B;iDAC6C;IAC7C,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,mDAAmD;IACnD,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED,yEAAyE;AACzE,wBAAgB,aAAa,CAC3B,MAAM,EAAE,cAAc,EAAE,EACxB,MAAM,EAAE,MAAM,EACd,IAAI,GAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAO,GACvD,cAAc,CAkDhB;AAED;2EAC2E;AAC3E,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,cAAc,EAAE,IAAI,GAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,MAAM,CAoB/F;AAED;;2DAE2D;AAC3D,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;CAC1C;AAED,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,cAAc,EAAE,EACxB,OAAO,EAAE,MAAM,EAAE,EACjB,IAAI,GAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAO,GACvD,cAAc,EAAE,CAUlB"}
@@ -0,0 +1,115 @@
1
+ /**
2
+ * v2.19.86 — TIME-MACHINE POLYGRAPH (IDEA #4).
3
+ *
4
+ * "Did this AI's answers DRIFT over the past 30 days?" — line chart of
5
+ * agreement-over-time per vendor, sourced from the same `pulse.jsonl`
6
+ * ledger that powers IDEA #2 (World Pulse globe). No new ledger; no
7
+ * new write path; pure read-side aggregation on the existing data.
8
+ *
9
+ * The seamless integration trick:
10
+ * - Every Browser Polygraph dot already records (ts, vendor, color)
11
+ * into pulse.jsonl as of v2.19.84.
12
+ * - Time-machine just buckets those events by time + vendor and
13
+ * reports a 0..1 honesty score per bucket.
14
+ * - If a vendor's honesty FALLS over time → drift visible.
15
+ * - If a vendor's honesty RISES over time → it learned (or got
16
+ * retrained).
17
+ * - Vertical markers can overlay known release dates (claude-3.5
18
+ * → claude-4 etc.) for visual correlation.
19
+ *
20
+ * No-Ollama by construction — pulse events already contain the verdict
21
+ * (green/yellow/red/grey) computed by the multi-signal agreement; time-
22
+ * machine is pure arithmetic on those existing scores.
23
+ */
24
+ /** Build a per-vendor time-bucketed honesty series from pulse events. */
25
+ export function buildTimeline(events, vendor, opts = {}) {
26
+ const windowDays = opts.windowDays ?? 30;
27
+ const bucketHours = opts.bucketHours ?? 24;
28
+ const bucketMs = bucketHours * 3600_000;
29
+ const cutoff = Date.now() - windowDays * 24 * 3600_000;
30
+ const inWin = events.filter((e) => e.vendor === vendor && e.ts >= cutoff);
31
+ // Pre-compute the full bucket grid so empty days still render in the
32
+ // line chart (otherwise gaps look like missing data instead of "no
33
+ // activity that day").
34
+ const start = Math.floor(cutoff / bucketMs) * bucketMs;
35
+ const end = Math.floor(Date.now() / bucketMs) * bucketMs;
36
+ const grid = new Map();
37
+ for (let t = start; t <= end; t += bucketMs) {
38
+ grid.set(t, {
39
+ bucketStart: new Date(t).toISOString(),
40
+ total: 0, green: 0, yellow: 0, red: 0, grey: 0,
41
+ honestyPct: null,
42
+ });
43
+ }
44
+ for (const e of inWin) {
45
+ const bucketKey = Math.floor(e.ts / bucketMs) * bucketMs;
46
+ const b = grid.get(bucketKey);
47
+ if (!b)
48
+ continue; // outside the grid (shouldn't happen post-filter)
49
+ b.total += 1;
50
+ b[e.color] += 1;
51
+ }
52
+ // Compute honestyPct per bucket (after fill).
53
+ for (const b of grid.values()) {
54
+ const judged = b.green + b.yellow + b.red;
55
+ b.honestyPct = judged > 0 ? b.green / judged : null;
56
+ }
57
+ const buckets = [...grid.values()].sort((a, b) => a.bucketStart.localeCompare(b.bucketStart));
58
+ // Series-level stats from non-null buckets only.
59
+ const nonNull = buckets.filter((b) => b.honestyPct !== null);
60
+ let minHonesty = null;
61
+ let maxHonesty = null;
62
+ let drift = null;
63
+ let meanHonesty = null;
64
+ if (nonNull.length > 0) {
65
+ minHonesty = Math.min(...nonNull.map((b) => b.honestyPct));
66
+ maxHonesty = Math.max(...nonNull.map((b) => b.honestyPct));
67
+ drift = nonNull[nonNull.length - 1].honestyPct - nonNull[0].honestyPct;
68
+ const judgedTotal = inWin.filter((e) => e.color !== "grey").length;
69
+ const greenTotal = inWin.filter((e) => e.color === "green").length;
70
+ meanHonesty = judgedTotal > 0 ? greenTotal / judgedTotal : null;
71
+ }
72
+ return {
73
+ vendor, windowDays, bucketHours, buckets,
74
+ minHonesty, maxHonesty, drift, meanHonesty,
75
+ };
76
+ }
77
+ /** Convenience: render a series as an ASCII chart for the CLI. Each
78
+ * bucket = 1 column; height = honestyPct. Empty buckets shown as `·`. */
79
+ export function renderAsciiChart(series, opts = {}) {
80
+ const h = opts.height ?? 12;
81
+ const lines = [];
82
+ // Build the canvas top-down.
83
+ for (let row = h; row >= 1; row--) {
84
+ let line = "";
85
+ for (const b of series.buckets) {
86
+ if (b.honestyPct === null) {
87
+ line += "·";
88
+ continue;
89
+ }
90
+ const cellH = Math.ceil(b.honestyPct * h);
91
+ line += cellH >= row ? (b.honestyPct < 0.5 ? "▆" : b.honestyPct < 0.8 ? "▅" : "█") : " ";
92
+ }
93
+ lines.push(line);
94
+ }
95
+ // X-axis: just first + last bucket dates.
96
+ const first = series.buckets[0]?.bucketStart.slice(5, 10) ?? "";
97
+ const last = series.buckets[series.buckets.length - 1]?.bucketStart.slice(5, 10) ?? "";
98
+ const axis = first + " ".repeat(Math.max(0, series.buckets.length - first.length - last.length)) + last;
99
+ lines.push("─".repeat(series.buckets.length));
100
+ lines.push(axis);
101
+ return lines.join("\n");
102
+ }
103
+ export function buildCrossVendorTable(events, vendors, opts = {}) {
104
+ const series = vendors.map((v) => buildTimeline(events, v, opts));
105
+ const len = series[0]?.buckets.length ?? 0;
106
+ const out = [];
107
+ for (let i = 0; i < len; i++) {
108
+ const row = { bucketStart: series[0].buckets[i].bucketStart };
109
+ for (const s of series)
110
+ row[s.vendor] = s.buckets[i]?.honestyPct ?? null;
111
+ out.push(row);
112
+ }
113
+ return out;
114
+ }
115
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/time_machine/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * v2.19.86 — Time-Machine Polygraph deep tests.
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=time_machine.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"time_machine.test.d.ts","sourceRoot":"","sources":["../../src/time_machine/time_machine.test.ts"],"names":[],"mappings":"AAAA;;GAEG"}
@@ -0,0 +1,85 @@
1
+ /**
2
+ * v2.19.86 — Time-Machine Polygraph deep tests.
3
+ */
4
+ import { describe, it, expect } from "vitest";
5
+ import { buildTimeline, buildCrossVendorTable, renderAsciiChart } from "./index.js";
6
+ const NOW = Date.now();
7
+ const HOUR = 3600_000;
8
+ const DAY = 24 * HOUR;
9
+ function ev(daysAgo, vendor, color) {
10
+ return { ts: NOW - daysAgo * DAY, vendor, color };
11
+ }
12
+ describe("time_machine · buildTimeline", () => {
13
+ it("buckets daily honesty per vendor + computes drift", () => {
14
+ const events = [
15
+ ev(5, "claude-ai", "green"), ev(5, "claude-ai", "green"), ev(5, "claude-ai", "red"),
16
+ ev(4, "claude-ai", "green"), ev(4, "claude-ai", "yellow"),
17
+ ev(3, "claude-ai", "green"), ev(3, "claude-ai", "green"),
18
+ ev(2, "claude-ai", "green"), ev(2, "claude-ai", "green"), ev(2, "claude-ai", "green"),
19
+ ev(1, "claude-ai", "green"), ev(1, "claude-ai", "green"),
20
+ ];
21
+ const s = buildTimeline(events, "claude-ai", { windowDays: 7, bucketHours: 24 });
22
+ expect(s.vendor).toBe("claude-ai");
23
+ expect(s.buckets.length).toBeGreaterThan(0);
24
+ expect(s.meanHonesty).toBeGreaterThan(0.7); // 10/12 green
25
+ // First non-null bucket = 2/3 honest; last non-null = 2/2 = 100%; drift > 0
26
+ expect(s.drift).not.toBeNull();
27
+ expect(s.drift).toBeGreaterThan(0);
28
+ });
29
+ it("excludes other vendors from the series", () => {
30
+ const events = [
31
+ ev(1, "claude-ai", "green"),
32
+ ev(1, "chatgpt", "red"),
33
+ ev(1, "chatgpt", "red"),
34
+ ];
35
+ const claude = buildTimeline(events, "claude-ai", { windowDays: 7 });
36
+ const total = claude.buckets.reduce((s, b) => s + b.total, 0);
37
+ expect(total).toBe(1);
38
+ });
39
+ it("returns null stats when no judged events in window", () => {
40
+ const events = [ev(1, "ghost", "grey"), ev(1, "ghost", "grey")];
41
+ const s = buildTimeline(events, "ghost", { windowDays: 7 });
42
+ expect(s.meanHonesty).toBeNull();
43
+ expect(s.minHonesty).toBeNull();
44
+ expect(s.maxHonesty).toBeNull();
45
+ expect(s.drift).toBeNull();
46
+ });
47
+ it("fills the bucket grid (no gaps) so empty days still show on the chart", () => {
48
+ const events = [ev(0, "claude-ai", "green"), ev(6, "claude-ai", "red")];
49
+ const s = buildTimeline(events, "claude-ai", { windowDays: 7, bucketHours: 24 });
50
+ // 7-day window with 24h buckets → ~7-8 buckets total; all present.
51
+ expect(s.buckets.length).toBeGreaterThanOrEqual(7);
52
+ // Many buckets will have total=0 (no events) — that's the grid fill.
53
+ expect(s.buckets.some((b) => b.total === 0)).toBe(true);
54
+ });
55
+ });
56
+ describe("time_machine · renderAsciiChart", () => {
57
+ it("renders a chart without crashing + uses the height arg", () => {
58
+ const events = [
59
+ ev(2, "claude-ai", "green"), ev(2, "claude-ai", "red"),
60
+ ev(1, "claude-ai", "green"), ev(1, "claude-ai", "green"),
61
+ ];
62
+ const s = buildTimeline(events, "claude-ai", { windowDays: 3, bucketHours: 24 });
63
+ const chart = renderAsciiChart(s, { height: 6 });
64
+ expect(typeof chart).toBe("string");
65
+ expect(chart.length).toBeGreaterThan(0);
66
+ // Has an axis label + at least one bar character.
67
+ expect(/[▆▅█]/.test(chart)).toBe(true);
68
+ });
69
+ });
70
+ describe("time_machine · buildCrossVendorTable", () => {
71
+ it("aligns multiple vendors on the same bucket grid", () => {
72
+ const events = [
73
+ ev(1, "claude-ai", "green"), ev(1, "claude-ai", "green"),
74
+ ev(1, "chatgpt", "red"),
75
+ ];
76
+ const tbl = buildCrossVendorTable(events, ["claude-ai", "chatgpt"], { windowDays: 3 });
77
+ expect(tbl.length).toBeGreaterThan(0);
78
+ for (const row of tbl) {
79
+ expect(typeof row.bucketStart).toBe("string");
80
+ expect("claude-ai" in row).toBe(true);
81
+ expect("chatgpt" in row).toBe(true);
82
+ }
83
+ });
84
+ });
85
+ //# sourceMappingURL=time_machine.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"time_machine.test.js","sourceRoot":"","sources":["../../src/time_machine/time_machine.test.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mneme-ai/core",
3
- "version": "2.19.85-lite",
3
+ "version": "2.19.86-lite",
4
4
  "description": "Core indexing, retrieval, and graph engine for Mneme — LITE variant (no bundled WASM embedder, no native deps).",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",