@mneme-ai/core 2.19.13 → 2.19.15
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/chimera_embedder/chimera_embedder.test.d.ts +2 -0
- package/dist/chimera_embedder/chimera_embedder.test.d.ts.map +1 -0
- package/dist/chimera_embedder/chimera_embedder.test.js +158 -0
- package/dist/chimera_embedder/chimera_embedder.test.js.map +1 -0
- package/dist/chimera_embedder/index.d.ts +92 -0
- package/dist/chimera_embedder/index.d.ts.map +1 -0
- package/dist/chimera_embedder/index.js +157 -0
- package/dist/chimera_embedder/index.js.map +1 -0
- package/dist/cli_dreams/cli_dreams.test.d.ts +2 -0
- package/dist/cli_dreams/cli_dreams.test.d.ts.map +1 -0
- package/dist/cli_dreams/cli_dreams.test.js +161 -0
- package/dist/cli_dreams/cli_dreams.test.js.map +1 -0
- package/dist/cli_dreams/index.d.ts +124 -0
- package/dist/cli_dreams/index.d.ts.map +1 -0
- package/dist/cli_dreams/index.js +205 -0
- package/dist/cli_dreams/index.js.map +1 -0
- package/dist/consequence_ledger/consequence_ledger.test.d.ts +2 -0
- package/dist/consequence_ledger/consequence_ledger.test.d.ts.map +1 -0
- package/dist/consequence_ledger/consequence_ledger.test.js +140 -0
- package/dist/consequence_ledger/consequence_ledger.test.js.map +1 -0
- package/dist/consequence_ledger/index.d.ts +114 -0
- package/dist/consequence_ledger/index.d.ts.map +1 -0
- package/dist/consequence_ledger/index.js +234 -0
- package/dist/consequence_ledger/index.js.map +1 -0
- package/dist/cosmic/aurelian_v1914.test.d.ts +2 -0
- package/dist/cosmic/aurelian_v1914.test.d.ts.map +1 -0
- package/dist/cosmic/aurelian_v1914.test.js +59 -0
- package/dist/cosmic/aurelian_v1914.test.js.map +1 -0
- package/dist/cosmic/aurelian_v1915.test.d.ts +2 -0
- package/dist/cosmic/aurelian_v1915.test.d.ts.map +1 -0
- package/dist/cosmic/aurelian_v1915.test.js +34 -0
- package/dist/cosmic/aurelian_v1915.test.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/truth_forensic_pipeline/index.d.ts +133 -0
- package/dist/truth_forensic_pipeline/index.d.ts.map +1 -0
- package/dist/truth_forensic_pipeline/index.js +346 -0
- package/dist/truth_forensic_pipeline/index.js.map +1 -0
- package/dist/truth_forensic_pipeline/truth_forensic_pipeline.test.d.ts +2 -0
- package/dist/truth_forensic_pipeline/truth_forensic_pipeline.test.d.ts.map +1 -0
- package/dist/truth_forensic_pipeline/truth_forensic_pipeline.test.js +256 -0
- package/dist/truth_forensic_pipeline/truth_forensic_pipeline.test.js.map +1 -0
- package/dist/whats_new.d.ts.map +1 -1
- package/dist/whats_new.js +16 -0
- package/dist/whats_new.js.map +1 -1
- package/dist/wrapper_genesis/index.d.ts.map +1 -1
- package/dist/wrapper_genesis/index.js +16 -0
- package/dist/wrapper_genesis/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v2.19.14 — MNEME CLI DREAMS (idle-time insight generation)
|
|
3
|
+
*
|
|
4
|
+
* "When you sleep, your codebase doesn't. Mneme's daemon spawns 100
|
|
5
|
+
* plausible-but-unverified claims about your repo during idle hours
|
|
6
|
+
* (local Ollama, free). Each enters a CHRONOSTASIS-style witness loop;
|
|
7
|
+
* refutations file in overnight; by morning the crystallised survivors
|
|
8
|
+
* appear as a digest: 'while you slept, here are 5 facts I now know
|
|
9
|
+
* about your repo that I didn't know yesterday'.
|
|
10
|
+
*
|
|
11
|
+
* No vendor will ship this because it costs compute + risks runaway
|
|
12
|
+
* cloud cost. Mneme runs it on YOUR machine via local-only inference;
|
|
13
|
+
* cost is amortised across hours nobody is using the machine. The CLI
|
|
14
|
+
* that learns about you while you sleep."
|
|
15
|
+
*
|
|
16
|
+
* Architecture (vendor-agnostic orchestrator):
|
|
17
|
+
* - `enqueueDreams({seeds})` — caller supplies N plausible claim strings
|
|
18
|
+
* (generated by their preferred local model). We HMAC-tag each one
|
|
19
|
+
* and add to the pending queue.
|
|
20
|
+
* - `recordDreamVerdict({dreamId, verdict, evidence?})` — caller (or
|
|
21
|
+
* CHRONOSTASIS in v2.19.5) reports the witness verdict per dream.
|
|
22
|
+
* - `morningDigest({since?})` — returns the night's crystallised dreams
|
|
23
|
+
* + refuted ones (for honest accounting) + still-pending count.
|
|
24
|
+
* - HMAC-chained ledger so the digest is tamper-evident.
|
|
25
|
+
*
|
|
26
|
+
* Honest scope:
|
|
27
|
+
* - We do NOT generate the dreams — caller does (Ollama, Claude, etc.).
|
|
28
|
+
* - We do NOT execute witness verdicts — caller does (Mneme INVERSE-LLM,
|
|
29
|
+
* CHRONOSTASIS, or any other verifier).
|
|
30
|
+
* - We provide: queue, dedup, verdict state machine, digest aggregation,
|
|
31
|
+
* chain integrity.
|
|
32
|
+
*/
|
|
33
|
+
declare const PROTOCOL_VERSION: 1;
|
|
34
|
+
export type DreamStatus = "pending" | "verified" | "refuted" | "inconclusive";
|
|
35
|
+
export interface DreamRecord {
|
|
36
|
+
v: typeof PROTOCOL_VERSION;
|
|
37
|
+
id: string;
|
|
38
|
+
claim: string;
|
|
39
|
+
source: string;
|
|
40
|
+
status: DreamStatus;
|
|
41
|
+
generatedAt: number;
|
|
42
|
+
resolvedAt: number | null;
|
|
43
|
+
evidence: string | null;
|
|
44
|
+
/** Confidence reported by the witness, [0..1]. */
|
|
45
|
+
confidence: number | null;
|
|
46
|
+
prevSig: string | null;
|
|
47
|
+
sig: string;
|
|
48
|
+
}
|
|
49
|
+
export interface DreamLedger {
|
|
50
|
+
v: typeof PROTOCOL_VERSION;
|
|
51
|
+
records: DreamRecord[];
|
|
52
|
+
}
|
|
53
|
+
export declare function emptyDreamLedger(): DreamLedger;
|
|
54
|
+
export interface EnqueueInput {
|
|
55
|
+
ledger: DreamLedger;
|
|
56
|
+
seeds: Array<{
|
|
57
|
+
claim: string;
|
|
58
|
+
source: string;
|
|
59
|
+
}>;
|
|
60
|
+
nowMs?: number;
|
|
61
|
+
secret?: string;
|
|
62
|
+
}
|
|
63
|
+
export interface EnqueueResult {
|
|
64
|
+
ledger: DreamLedger;
|
|
65
|
+
enqueued: number;
|
|
66
|
+
duplicatesSkipped: number;
|
|
67
|
+
rejectedAtCap: number;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Add new dreams to the queue. Deduplicates by EXACT claim (case-sensitive)
|
|
71
|
+
* across existing pending records. Hard cap MAX_DREAMS_PER_NIGHT prevents
|
|
72
|
+
* runaway queues even if a generator misbehaves.
|
|
73
|
+
*/
|
|
74
|
+
export declare function enqueueDreams(input: EnqueueInput): EnqueueResult;
|
|
75
|
+
export interface VerdictInput {
|
|
76
|
+
ledger: DreamLedger;
|
|
77
|
+
dreamId: string;
|
|
78
|
+
verdict: "verified" | "refuted" | "inconclusive";
|
|
79
|
+
evidence?: string;
|
|
80
|
+
confidence?: number;
|
|
81
|
+
nowMs?: number;
|
|
82
|
+
secret?: string;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Record the witness verdict for a previously-enqueued dream. Pure update:
|
|
86
|
+
* we DO NOT re-sign earlier records (their HMAC stays valid against their
|
|
87
|
+
* own body). A new record appended captures the verdict — the chain remains
|
|
88
|
+
* appendable and the dream's status is derived from the most-recent record
|
|
89
|
+
* for its id.
|
|
90
|
+
*/
|
|
91
|
+
export declare function recordDreamVerdict(input: VerdictInput): {
|
|
92
|
+
ledger: DreamLedger;
|
|
93
|
+
ok: boolean;
|
|
94
|
+
reason?: string;
|
|
95
|
+
};
|
|
96
|
+
export interface MorningDigest {
|
|
97
|
+
generatedAt: string;
|
|
98
|
+
windowStartMs: number;
|
|
99
|
+
totalDreamed: number;
|
|
100
|
+
crystallised: DreamRecord[];
|
|
101
|
+
refuted: DreamRecord[];
|
|
102
|
+
inconclusive: DreamRecord[];
|
|
103
|
+
stillPending: number;
|
|
104
|
+
ratioCrystallised: number;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Aggregate dreams generated since `since` into a morning digest.
|
|
108
|
+
* Returns the LATEST record per dream id (so status reflects the verdict).
|
|
109
|
+
*/
|
|
110
|
+
export declare function morningDigest(opts: {
|
|
111
|
+
ledger: DreamLedger;
|
|
112
|
+
since?: number;
|
|
113
|
+
nowMs?: number;
|
|
114
|
+
}): MorningDigest;
|
|
115
|
+
/** Verify the HMAC chain of the dream ledger (prevSig + sig per record). */
|
|
116
|
+
export declare function verifyDreamLedger(ledger: DreamLedger, secret?: string): {
|
|
117
|
+
ok: boolean;
|
|
118
|
+
brokenAt?: number;
|
|
119
|
+
reason?: string;
|
|
120
|
+
};
|
|
121
|
+
export declare function listPendingDreams(ledger: DreamLedger): DreamRecord[];
|
|
122
|
+
export declare function formatDigestLine(d: MorningDigest): string;
|
|
123
|
+
export {};
|
|
124
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli_dreams/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAIH,QAAA,MAAM,gBAAgB,EAAG,CAAU,CAAC;AAGpC,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,UAAU,GAAG,SAAS,GAAG,cAAc,CAAC;AAE9E,MAAM,WAAW,WAAW;IAC1B,CAAC,EAAE,OAAO,gBAAgB,CAAC;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,WAAW,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,kDAAkD;IAClD,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,WAAW;IAC1B,CAAC,EAAE,OAAO,gBAAgB,CAAC;IAC3B,OAAO,EAAE,WAAW,EAAE,CAAC;CACxB;AA4BD,wBAAgB,gBAAgB,IAAI,WAAW,CAE9C;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,WAAW,CAAC;IACpB,KAAK,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAChD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,WAAW,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,aAAa,EAAE,MAAM,CAAC;CACvB;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,YAAY,GAAG,aAAa,CA6ChE;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,WAAW,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,UAAU,GAAG,SAAS,GAAG,cAAc,CAAC;IACjD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,YAAY,GAAG;IAAE,MAAM,EAAE,WAAW,CAAC;IAAC,EAAE,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAyB7G;AAED,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,WAAW,EAAE,CAAC;IAC5B,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,YAAY,EAAE,WAAW,EAAE,CAAC;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE;IAClC,MAAM,EAAE,WAAW,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GAAG,aAAa,CAwBhB;AAED,4EAA4E;AAC5E,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,WAAW,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAe3H;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,WAAW,GAAG,WAAW,EAAE,CAIpE;AAED,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,aAAa,GAAG,MAAM,CAEzD"}
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v2.19.14 — MNEME CLI DREAMS (idle-time insight generation)
|
|
3
|
+
*
|
|
4
|
+
* "When you sleep, your codebase doesn't. Mneme's daemon spawns 100
|
|
5
|
+
* plausible-but-unverified claims about your repo during idle hours
|
|
6
|
+
* (local Ollama, free). Each enters a CHRONOSTASIS-style witness loop;
|
|
7
|
+
* refutations file in overnight; by morning the crystallised survivors
|
|
8
|
+
* appear as a digest: 'while you slept, here are 5 facts I now know
|
|
9
|
+
* about your repo that I didn't know yesterday'.
|
|
10
|
+
*
|
|
11
|
+
* No vendor will ship this because it costs compute + risks runaway
|
|
12
|
+
* cloud cost. Mneme runs it on YOUR machine via local-only inference;
|
|
13
|
+
* cost is amortised across hours nobody is using the machine. The CLI
|
|
14
|
+
* that learns about you while you sleep."
|
|
15
|
+
*
|
|
16
|
+
* Architecture (vendor-agnostic orchestrator):
|
|
17
|
+
* - `enqueueDreams({seeds})` — caller supplies N plausible claim strings
|
|
18
|
+
* (generated by their preferred local model). We HMAC-tag each one
|
|
19
|
+
* and add to the pending queue.
|
|
20
|
+
* - `recordDreamVerdict({dreamId, verdict, evidence?})` — caller (or
|
|
21
|
+
* CHRONOSTASIS in v2.19.5) reports the witness verdict per dream.
|
|
22
|
+
* - `morningDigest({since?})` — returns the night's crystallised dreams
|
|
23
|
+
* + refuted ones (for honest accounting) + still-pending count.
|
|
24
|
+
* - HMAC-chained ledger so the digest is tamper-evident.
|
|
25
|
+
*
|
|
26
|
+
* Honest scope:
|
|
27
|
+
* - We do NOT generate the dreams — caller does (Ollama, Claude, etc.).
|
|
28
|
+
* - We do NOT execute witness verdicts — caller does (Mneme INVERSE-LLM,
|
|
29
|
+
* CHRONOSTASIS, or any other verifier).
|
|
30
|
+
* - We provide: queue, dedup, verdict state machine, digest aggregation,
|
|
31
|
+
* chain integrity.
|
|
32
|
+
*/
|
|
33
|
+
import { createHmac, timingSafeEqual } from "node:crypto";
|
|
34
|
+
const PROTOCOL_VERSION = 1;
|
|
35
|
+
const MAX_DREAMS_PER_NIGHT = 1000; // sanity cap
|
|
36
|
+
function canon(v) {
|
|
37
|
+
if (v === null || typeof v !== "object")
|
|
38
|
+
return JSON.stringify(v);
|
|
39
|
+
if (Array.isArray(v))
|
|
40
|
+
return "[" + v.map(canon).join(",") + "]";
|
|
41
|
+
const keys = Object.keys(v).sort();
|
|
42
|
+
return "{" + keys.map((k) => JSON.stringify(k) + ":" + canon(v[k])).join(",") + "}";
|
|
43
|
+
}
|
|
44
|
+
function defaultSecret() {
|
|
45
|
+
return process.env["MNEME_DREAM_SECRET"] || `mneme-cli-dreams-v${PROTOCOL_VERSION}`;
|
|
46
|
+
}
|
|
47
|
+
function signRecord(body, secret) {
|
|
48
|
+
return createHmac("sha256", secret).update(canon(body)).digest("hex");
|
|
49
|
+
}
|
|
50
|
+
function safeEqHex(a, b) {
|
|
51
|
+
try {
|
|
52
|
+
return timingSafeEqual(Buffer.from(a, "hex"), Buffer.from(b, "hex"));
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
function makeDreamId(claim, generatedAt) {
|
|
59
|
+
return "drm-" + createHmac("sha256", "mneme-dream-id")
|
|
60
|
+
.update(`${claim}|${generatedAt}`)
|
|
61
|
+
.digest("hex").slice(0, 14);
|
|
62
|
+
}
|
|
63
|
+
export function emptyDreamLedger() {
|
|
64
|
+
return { v: PROTOCOL_VERSION, records: [] };
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Add new dreams to the queue. Deduplicates by EXACT claim (case-sensitive)
|
|
68
|
+
* across existing pending records. Hard cap MAX_DREAMS_PER_NIGHT prevents
|
|
69
|
+
* runaway queues even if a generator misbehaves.
|
|
70
|
+
*/
|
|
71
|
+
export function enqueueDreams(input) {
|
|
72
|
+
const nowMs = input.nowMs ?? Date.now();
|
|
73
|
+
const secret = input.secret ?? defaultSecret();
|
|
74
|
+
const pendingClaims = new Set(input.ledger.records.filter((r) => r.status === "pending").map((r) => r.claim));
|
|
75
|
+
let added = [];
|
|
76
|
+
let duplicates = 0;
|
|
77
|
+
let rejected = 0;
|
|
78
|
+
const pendingCountBefore = pendingClaims.size;
|
|
79
|
+
for (let i = 0; i < input.seeds.length; i++) {
|
|
80
|
+
const seed = input.seeds[i];
|
|
81
|
+
if (pendingClaims.has(seed.claim)) {
|
|
82
|
+
duplicates++;
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
if (pendingCountBefore + added.length >= MAX_DREAMS_PER_NIGHT) {
|
|
86
|
+
rejected++;
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
pendingClaims.add(seed.claim);
|
|
90
|
+
const prevSig = added.length > 0
|
|
91
|
+
? added[added.length - 1].sig
|
|
92
|
+
: (input.ledger.records[input.ledger.records.length - 1]?.sig ?? null);
|
|
93
|
+
const body = {
|
|
94
|
+
v: PROTOCOL_VERSION,
|
|
95
|
+
id: makeDreamId(seed.claim, nowMs + i),
|
|
96
|
+
claim: seed.claim,
|
|
97
|
+
source: seed.source,
|
|
98
|
+
status: "pending",
|
|
99
|
+
generatedAt: nowMs + i,
|
|
100
|
+
resolvedAt: null,
|
|
101
|
+
evidence: null,
|
|
102
|
+
confidence: null,
|
|
103
|
+
prevSig,
|
|
104
|
+
};
|
|
105
|
+
const sig = signRecord(body, secret);
|
|
106
|
+
added.push({ ...body, sig });
|
|
107
|
+
}
|
|
108
|
+
return {
|
|
109
|
+
ledger: { v: PROTOCOL_VERSION, records: [...input.ledger.records, ...added] },
|
|
110
|
+
enqueued: added.length,
|
|
111
|
+
duplicatesSkipped: duplicates,
|
|
112
|
+
rejectedAtCap: rejected,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Record the witness verdict for a previously-enqueued dream. Pure update:
|
|
117
|
+
* we DO NOT re-sign earlier records (their HMAC stays valid against their
|
|
118
|
+
* own body). A new record appended captures the verdict — the chain remains
|
|
119
|
+
* appendable and the dream's status is derived from the most-recent record
|
|
120
|
+
* for its id.
|
|
121
|
+
*/
|
|
122
|
+
export function recordDreamVerdict(input) {
|
|
123
|
+
const orig = input.ledger.records.slice().reverse().find((r) => r.id === input.dreamId);
|
|
124
|
+
if (!orig)
|
|
125
|
+
return { ledger: input.ledger, ok: false, reason: `dream id '${input.dreamId}' not found` };
|
|
126
|
+
if (orig.status !== "pending") {
|
|
127
|
+
return { ledger: input.ledger, ok: false, reason: `dream '${input.dreamId}' already resolved (status=${orig.status})` };
|
|
128
|
+
}
|
|
129
|
+
const nowMs = input.nowMs ?? Date.now();
|
|
130
|
+
const prevSig = input.ledger.records[input.ledger.records.length - 1].sig;
|
|
131
|
+
const body = {
|
|
132
|
+
v: PROTOCOL_VERSION,
|
|
133
|
+
id: orig.id,
|
|
134
|
+
claim: orig.claim,
|
|
135
|
+
source: orig.source,
|
|
136
|
+
status: input.verdict,
|
|
137
|
+
generatedAt: orig.generatedAt,
|
|
138
|
+
resolvedAt: nowMs,
|
|
139
|
+
evidence: input.evidence ?? null,
|
|
140
|
+
confidence: input.confidence ?? null,
|
|
141
|
+
prevSig,
|
|
142
|
+
};
|
|
143
|
+
const sig = signRecord(body, input.secret ?? defaultSecret());
|
|
144
|
+
return {
|
|
145
|
+
ledger: { v: PROTOCOL_VERSION, records: [...input.ledger.records, { ...body, sig }] },
|
|
146
|
+
ok: true,
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Aggregate dreams generated since `since` into a morning digest.
|
|
151
|
+
* Returns the LATEST record per dream id (so status reflects the verdict).
|
|
152
|
+
*/
|
|
153
|
+
export function morningDigest(opts) {
|
|
154
|
+
const since = opts.since ?? 0;
|
|
155
|
+
// Latest record per id (since the chain may have multiple updates).
|
|
156
|
+
const byId = new Map();
|
|
157
|
+
for (const r of opts.ledger.records) {
|
|
158
|
+
if (r.generatedAt < since)
|
|
159
|
+
continue;
|
|
160
|
+
byId.set(r.id, r);
|
|
161
|
+
}
|
|
162
|
+
const all = Array.from(byId.values());
|
|
163
|
+
const crystallised = all.filter((r) => r.status === "verified");
|
|
164
|
+
const refuted = all.filter((r) => r.status === "refuted");
|
|
165
|
+
const inconclusive = all.filter((r) => r.status === "inconclusive");
|
|
166
|
+
const stillPending = all.filter((r) => r.status === "pending").length;
|
|
167
|
+
const total = all.length;
|
|
168
|
+
return {
|
|
169
|
+
generatedAt: new Date(opts.nowMs ?? Date.now()).toISOString(),
|
|
170
|
+
windowStartMs: since,
|
|
171
|
+
totalDreamed: total,
|
|
172
|
+
crystallised,
|
|
173
|
+
refuted,
|
|
174
|
+
inconclusive,
|
|
175
|
+
stillPending,
|
|
176
|
+
ratioCrystallised: total === 0 ? 0 : crystallised.length / total,
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
/** Verify the HMAC chain of the dream ledger (prevSig + sig per record). */
|
|
180
|
+
export function verifyDreamLedger(ledger, secret) {
|
|
181
|
+
const sec = secret ?? defaultSecret();
|
|
182
|
+
let prevSig = null;
|
|
183
|
+
for (let i = 0; i < ledger.records.length; i++) {
|
|
184
|
+
const r = ledger.records[i];
|
|
185
|
+
const { sig, ...body } = r;
|
|
186
|
+
if (body.prevSig !== prevSig) {
|
|
187
|
+
return { ok: false, brokenAt: i, reason: `prevSig mismatch at step ${i}` };
|
|
188
|
+
}
|
|
189
|
+
if (!safeEqHex(signRecord(body, sec), sig)) {
|
|
190
|
+
return { ok: false, brokenAt: i, reason: `HMAC mismatch at step ${i}` };
|
|
191
|
+
}
|
|
192
|
+
prevSig = sig;
|
|
193
|
+
}
|
|
194
|
+
return { ok: true };
|
|
195
|
+
}
|
|
196
|
+
export function listPendingDreams(ledger) {
|
|
197
|
+
const byId = new Map();
|
|
198
|
+
for (const r of ledger.records)
|
|
199
|
+
byId.set(r.id, r);
|
|
200
|
+
return Array.from(byId.values()).filter((r) => r.status === "pending");
|
|
201
|
+
}
|
|
202
|
+
export function formatDigestLine(d) {
|
|
203
|
+
return `🦠 DREAMS · ${d.crystallised.length} crystallised · ${d.refuted.length} refuted · ${d.stillPending} pending · ratio=${d.ratioCrystallised.toFixed(2)}`;
|
|
204
|
+
}
|
|
205
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli_dreams/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"consequence_ledger.test.d.ts","sourceRoot":"","sources":["../../src/consequence_ledger/consequence_ledger.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { emptyConsequenceLedger, recordRun, recordDelta, queryConsequences, verifyConsequenceLedger, listRecentRuns, formatConsequenceLine, } from "./index.js";
|
|
3
|
+
const SECRET = "csq-test-secret-887766";
|
|
4
|
+
function seedRuns() {
|
|
5
|
+
let l = emptyConsequenceLedger();
|
|
6
|
+
const ids = [];
|
|
7
|
+
l = recordRun({ ledger: l, cmd: "mneme.verify", args: { strict: true }, result: { ok: true }, repoStateBefore: "sha-A", recordedAtMs: 1_000_000, secret: SECRET });
|
|
8
|
+
ids.push(l.records[l.records.length - 1].id);
|
|
9
|
+
l = recordRun({ ledger: l, cmd: "mneme.verify", args: { strict: false }, result: { ok: true }, repoStateBefore: "sha-A", recordedAtMs: 1_001_000, secret: SECRET });
|
|
10
|
+
ids.push(l.records[l.records.length - 1].id);
|
|
11
|
+
l = recordRun({ ledger: l, cmd: "mneme.upgrade", args: {}, result: { newVersion: "2.19.14" }, repoStateBefore: "sha-A", recordedAtMs: 1_002_000, secret: SECRET });
|
|
12
|
+
ids.push(l.records[l.records.length - 1].id);
|
|
13
|
+
return { ledger: l, ids };
|
|
14
|
+
}
|
|
15
|
+
describe("v2.19.14 CONSEQUENCE LEDGER · recordRun", () => {
|
|
16
|
+
it("records a run with HMAC-chained sig; resultDigest is sha256 of canonical result", () => {
|
|
17
|
+
const { ledger, ids } = seedRuns();
|
|
18
|
+
expect(ledger.records).toHaveLength(3);
|
|
19
|
+
expect(ledger.records[0].prevSig).toBeNull();
|
|
20
|
+
expect(ledger.records[1].prevSig).toBe(ledger.records[0].sig);
|
|
21
|
+
expect(ledger.records[0].resultDigest).toMatch(/^[a-f0-9]{64}$/);
|
|
22
|
+
expect(ids).toHaveLength(3);
|
|
23
|
+
});
|
|
24
|
+
it("records start with deltaSummary=null + repoStateAfter=null (delta arrives later)", () => {
|
|
25
|
+
const { ledger } = seedRuns();
|
|
26
|
+
expect(ledger.records.every((r) => r.deltaSummary === null && r.repoStateAfter === null)).toBe(true);
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
describe("v2.19.14 CONSEQUENCE LEDGER · recordDelta", () => {
|
|
30
|
+
it("appends a delta record for an existing run id", () => {
|
|
31
|
+
const { ledger: l0, ids } = seedRuns();
|
|
32
|
+
const r = recordDelta({
|
|
33
|
+
ledger: l0,
|
|
34
|
+
runId: ids[0],
|
|
35
|
+
repoStateAfter: "sha-B",
|
|
36
|
+
deltaSummary: { commitsAdded: 2, commitsRemoved: 3, filesChanged: 5, status: "rollback" },
|
|
37
|
+
recordedAtMs: 1_000_000 + 24 * 60 * 60 * 1000,
|
|
38
|
+
secret: SECRET,
|
|
39
|
+
});
|
|
40
|
+
expect(r.ok).toBe(true);
|
|
41
|
+
expect(r.ledger.records).toHaveLength(4);
|
|
42
|
+
const last = r.ledger.records[3];
|
|
43
|
+
expect(last.id).toBe(ids[0]);
|
|
44
|
+
expect(last.deltaSummary).toEqual({ commitsAdded: 2, commitsRemoved: 3, filesChanged: 5, status: "rollback" });
|
|
45
|
+
});
|
|
46
|
+
it("refuses to record delta for an unknown id", () => {
|
|
47
|
+
const { ledger } = seedRuns();
|
|
48
|
+
const r = recordDelta({ ledger, runId: "csq-doesnt-exist", repoStateAfter: "sha-X", deltaSummary: {}, secret: SECRET });
|
|
49
|
+
expect(r.ok).toBe(false);
|
|
50
|
+
});
|
|
51
|
+
it("refuses to overwrite an already-recorded delta", () => {
|
|
52
|
+
const { ledger: l0, ids } = seedRuns();
|
|
53
|
+
const l1 = recordDelta({ ledger: l0, runId: ids[0], repoStateAfter: "sha-B", deltaSummary: { x: 1 }, recordedAtMs: 1_005_000, secret: SECRET }).ledger;
|
|
54
|
+
const r = recordDelta({ ledger: l1, runId: ids[0], repoStateAfter: "sha-C", deltaSummary: { x: 2 }, recordedAtMs: 1_006_000, secret: SECRET });
|
|
55
|
+
expect(r.ok).toBe(false);
|
|
56
|
+
expect(r.reason).toContain("already recorded");
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
describe("v2.19.14 CONSEQUENCE LEDGER · queryConsequences aggregation", () => {
|
|
60
|
+
it("computes mean for numeric delta fields across runs", () => {
|
|
61
|
+
let { ledger, ids } = seedRuns();
|
|
62
|
+
ledger = recordDelta({ ledger, runId: ids[0], repoStateAfter: "B", deltaSummary: { commitsRemoved: 3, filesChanged: 5 }, recordedAtMs: 1_100_000, secret: SECRET }).ledger;
|
|
63
|
+
ledger = recordDelta({ ledger, runId: ids[1], repoStateAfter: "C", deltaSummary: { commitsRemoved: 1, filesChanged: 2 }, recordedAtMs: 1_101_000, secret: SECRET }).ledger;
|
|
64
|
+
const agg = queryConsequences({ ledger, cmd: "mneme.verify", nowMs: 2_000_000 });
|
|
65
|
+
expect(agg.totalRuns).toBe(2);
|
|
66
|
+
expect(agg.runsWithDelta).toBe(2);
|
|
67
|
+
expect(agg.averages.commitsRemoved).toBe(2); // (3 + 1) / 2
|
|
68
|
+
expect(agg.averages.filesChanged).toBe(3.5);
|
|
69
|
+
});
|
|
70
|
+
it("non-numeric delta fields become top-5 histograms sorted by count desc", () => {
|
|
71
|
+
let { ledger, ids } = seedRuns();
|
|
72
|
+
ledger = recordDelta({ ledger, runId: ids[0], repoStateAfter: "B", deltaSummary: { status: "rollback" }, recordedAtMs: 1_100_000, secret: SECRET }).ledger;
|
|
73
|
+
ledger = recordDelta({ ledger, runId: ids[1], repoStateAfter: "C", deltaSummary: { status: "rollback" }, recordedAtMs: 1_101_000, secret: SECRET }).ledger;
|
|
74
|
+
const agg = queryConsequences({ ledger, cmd: "mneme.verify", nowMs: 2_000_000 });
|
|
75
|
+
expect(agg.histograms.status).toBeDefined();
|
|
76
|
+
expect(agg.histograms.status[0]).toEqual({ value: "rollback", count: 2 });
|
|
77
|
+
});
|
|
78
|
+
it("windowMs filters older runs out", () => {
|
|
79
|
+
const { ledger } = seedRuns();
|
|
80
|
+
const agg = queryConsequences({ ledger, cmd: "mneme.verify", windowMs: 500, nowMs: 1_001_500 });
|
|
81
|
+
// only the run at 1_001_000 falls within [1_001_000, 1_001_500]
|
|
82
|
+
expect(agg.totalRuns).toBe(1);
|
|
83
|
+
});
|
|
84
|
+
it("query for an unseen cmd returns zeros + no averages", () => {
|
|
85
|
+
const { ledger } = seedRuns();
|
|
86
|
+
const agg = queryConsequences({ ledger, cmd: "mneme.never_run" });
|
|
87
|
+
expect(agg.totalRuns).toBe(0);
|
|
88
|
+
expect(agg.runsWithDelta).toBe(0);
|
|
89
|
+
expect(Object.keys(agg.averages)).toHaveLength(0);
|
|
90
|
+
});
|
|
91
|
+
it("aggregates dedup by id (delta record overrides original)", () => {
|
|
92
|
+
let { ledger, ids } = seedRuns();
|
|
93
|
+
ledger = recordDelta({ ledger, runId: ids[0], repoStateAfter: "B", deltaSummary: { commitsRemoved: 7 }, recordedAtMs: 1_100_000, secret: SECRET }).ledger;
|
|
94
|
+
const agg = queryConsequences({ ledger, cmd: "mneme.verify", nowMs: 2_000_000 });
|
|
95
|
+
// totalRuns = 2 distinct ids for mneme.verify, not 3 (the dup record + original)
|
|
96
|
+
expect(agg.totalRuns).toBe(2);
|
|
97
|
+
expect(agg.runsWithDelta).toBe(1);
|
|
98
|
+
expect(agg.averages.commitsRemoved).toBe(7);
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
describe("v2.19.14 CONSEQUENCE LEDGER · verify + list + formatter", () => {
|
|
102
|
+
it("verifyConsequenceLedger passes untampered chain", () => {
|
|
103
|
+
let { ledger, ids } = seedRuns();
|
|
104
|
+
ledger = recordDelta({ ledger, runId: ids[0], repoStateAfter: "B", deltaSummary: { x: 1 }, recordedAtMs: 1_100_000, secret: SECRET }).ledger;
|
|
105
|
+
expect(verifyConsequenceLedger(ledger, SECRET).ok).toBe(true);
|
|
106
|
+
});
|
|
107
|
+
it("verifyConsequenceLedger detects tampered cmd at exact step", () => {
|
|
108
|
+
const { ledger } = seedRuns();
|
|
109
|
+
const tampered = {
|
|
110
|
+
...ledger,
|
|
111
|
+
records: ledger.records.map((r, i) => (i === 1 ? { ...r, cmd: "mneme.evil" } : r)),
|
|
112
|
+
};
|
|
113
|
+
const v = verifyConsequenceLedger(tampered, SECRET);
|
|
114
|
+
expect(v.ok).toBe(false);
|
|
115
|
+
expect(v.brokenAt).toBe(1);
|
|
116
|
+
});
|
|
117
|
+
it("listRecentRuns returns latest-per-id, newest first, capped at limit", () => {
|
|
118
|
+
let { ledger, ids } = seedRuns();
|
|
119
|
+
ledger = recordDelta({ ledger, runId: ids[0], repoStateAfter: "B", deltaSummary: { x: 1 }, recordedAtMs: 1_100_000, secret: SECRET }).ledger;
|
|
120
|
+
const list = listRecentRuns(ledger, { limit: 2 });
|
|
121
|
+
expect(list).toHaveLength(2);
|
|
122
|
+
// sorted descending by recordedAtMs (which is preserved on delta records)
|
|
123
|
+
expect(list[0].recordedAtMs).toBeGreaterThanOrEqual(list[1].recordedAtMs);
|
|
124
|
+
});
|
|
125
|
+
it("formatter line shows cmd + run count + averages snippet with ⏳", () => {
|
|
126
|
+
const line = formatConsequenceLine({
|
|
127
|
+
cmd: "mneme.verify",
|
|
128
|
+
totalRuns: 10,
|
|
129
|
+
runsWithDelta: 8,
|
|
130
|
+
averages: { commitsRemoved: 3.0, filesChanged: 5.5 },
|
|
131
|
+
histograms: {},
|
|
132
|
+
oldestRunMs: 0,
|
|
133
|
+
newestRunMs: 1000,
|
|
134
|
+
});
|
|
135
|
+
expect(line).toContain("⏳");
|
|
136
|
+
expect(line).toContain("mneme.verify");
|
|
137
|
+
expect(line).toContain("commitsRemoved=3.0");
|
|
138
|
+
});
|
|
139
|
+
});
|
|
140
|
+
//# sourceMappingURL=consequence_ledger.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"consequence_ledger.test.js","sourceRoot":"","sources":["../../src/consequence_ledger/consequence_ledger.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v2.19.14 — MNEME TEMPORAL CONSEQUENCE LEDGER (causal-aware CLI)
|
|
3
|
+
*
|
|
4
|
+
* "Every `mneme verify` you run gets logged with a sha of the repo state
|
|
5
|
+
* at T+0. Twenty-four hours later, you (or the daemon) pushes the new
|
|
6
|
+
* state sha — Mneme computes the delta and links it to the original
|
|
7
|
+
* run. After 90 days you can ask: 'what does `mneme verify` tend to
|
|
8
|
+
* cause within 24 hours?' Answer: 'on average, you delete 3 commits
|
|
9
|
+
* in the next 24h after running it.' CLI that knows what its OWN
|
|
10
|
+
* output causes — the first causal-aware AI tool."
|
|
11
|
+
*
|
|
12
|
+
* Architecture:
|
|
13
|
+
* - HMAC-chained record: { cmd, args, resultDigest, repoStateBefore,
|
|
14
|
+
* repoStateAfter?, deltaSummary?, ts, prevSig, sig }
|
|
15
|
+
* - At record time: caller pushes cmd + args + resultDigest + state-now.
|
|
16
|
+
* - At T+~24h: caller (or daemon) pushes the new state + a deltaSummary
|
|
17
|
+
* (free-text JSON e.g. {commitsAdded, commitsRemoved, filesChanged}).
|
|
18
|
+
* - Query: aggregate { cmd → { avgDeltaSummary, n, lastSeen } } over
|
|
19
|
+
* records whose delta was recorded.
|
|
20
|
+
*
|
|
21
|
+
* Honest scope:
|
|
22
|
+
* - We don't compute the delta ourselves — caller supplies it (git diff,
|
|
23
|
+
* filesystem snapshot, whatever). Caller decides what 'delta' means.
|
|
24
|
+
* - Correlation, not causation. We can say "X happened after Y" not
|
|
25
|
+
* "Y caused X" — caller's responsibility to interpret.
|
|
26
|
+
* - Aggregation is mean over numeric fields the caller chose to record.
|
|
27
|
+
* Non-numeric fields are tallied via top-K most common values.
|
|
28
|
+
*/
|
|
29
|
+
declare const PROTOCOL_VERSION: 1;
|
|
30
|
+
export interface ConsequenceRecord {
|
|
31
|
+
v: typeof PROTOCOL_VERSION;
|
|
32
|
+
id: string;
|
|
33
|
+
cmd: string;
|
|
34
|
+
args: Record<string, unknown>;
|
|
35
|
+
/** SHA-256 of the canonicalised result, so callers can dedupe identical results. */
|
|
36
|
+
resultDigest: string;
|
|
37
|
+
repoStateBefore: string;
|
|
38
|
+
repoStateAfter: string | null;
|
|
39
|
+
/** Caller-defined summary of what changed (keys are caller's choice). */
|
|
40
|
+
deltaSummary: Record<string, unknown> | null;
|
|
41
|
+
recordedAtMs: number;
|
|
42
|
+
deltaRecordedAtMs: number | null;
|
|
43
|
+
prevSig: string | null;
|
|
44
|
+
sig: string;
|
|
45
|
+
}
|
|
46
|
+
export interface ConsequenceLedger {
|
|
47
|
+
v: typeof PROTOCOL_VERSION;
|
|
48
|
+
records: ConsequenceRecord[];
|
|
49
|
+
}
|
|
50
|
+
export declare function emptyConsequenceLedger(): ConsequenceLedger;
|
|
51
|
+
export interface RecordRunInput {
|
|
52
|
+
ledger: ConsequenceLedger;
|
|
53
|
+
cmd: string;
|
|
54
|
+
args?: Record<string, unknown>;
|
|
55
|
+
result: unknown;
|
|
56
|
+
repoStateBefore: string;
|
|
57
|
+
recordedAtMs?: number;
|
|
58
|
+
secret?: string;
|
|
59
|
+
}
|
|
60
|
+
export declare function recordRun(input: RecordRunInput): ConsequenceLedger;
|
|
61
|
+
export interface RecordDeltaInput {
|
|
62
|
+
ledger: ConsequenceLedger;
|
|
63
|
+
runId: string;
|
|
64
|
+
repoStateAfter: string;
|
|
65
|
+
deltaSummary: Record<string, unknown>;
|
|
66
|
+
recordedAtMs?: number;
|
|
67
|
+
secret?: string;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Append a delta record for a previous run. The original record stays
|
|
71
|
+
* appendable (we don't rewrite its sig); the latest record per `id` is
|
|
72
|
+
* the source of truth for queries.
|
|
73
|
+
*/
|
|
74
|
+
export declare function recordDelta(input: RecordDeltaInput): {
|
|
75
|
+
ledger: ConsequenceLedger;
|
|
76
|
+
ok: boolean;
|
|
77
|
+
reason?: string;
|
|
78
|
+
};
|
|
79
|
+
export interface ConsequenceQuery {
|
|
80
|
+
cmd: string;
|
|
81
|
+
windowMs?: number;
|
|
82
|
+
nowMs?: number;
|
|
83
|
+
}
|
|
84
|
+
export interface ConsequenceAggregate {
|
|
85
|
+
cmd: string;
|
|
86
|
+
totalRuns: number;
|
|
87
|
+
runsWithDelta: number;
|
|
88
|
+
averages: Record<string, number>;
|
|
89
|
+
histograms: Record<string, Array<{
|
|
90
|
+
value: string;
|
|
91
|
+
count: number;
|
|
92
|
+
}>>;
|
|
93
|
+
oldestRunMs: number | null;
|
|
94
|
+
newestRunMs: number | null;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Aggregate delta summaries for a given cmd. Numeric fields → mean over
|
|
98
|
+
* runs with a recorded delta. Non-numeric fields → top-5 most common values
|
|
99
|
+
* with counts. Pure read; no side effects.
|
|
100
|
+
*/
|
|
101
|
+
export declare function queryConsequences(opts: {
|
|
102
|
+
ledger: ConsequenceLedger;
|
|
103
|
+
} & ConsequenceQuery): ConsequenceAggregate;
|
|
104
|
+
export declare function verifyConsequenceLedger(ledger: ConsequenceLedger, secret?: string): {
|
|
105
|
+
ok: boolean;
|
|
106
|
+
brokenAt?: number;
|
|
107
|
+
reason?: string;
|
|
108
|
+
};
|
|
109
|
+
export declare function listRecentRuns(ledger: ConsequenceLedger, opts?: {
|
|
110
|
+
limit?: number;
|
|
111
|
+
}): ConsequenceRecord[];
|
|
112
|
+
export declare function formatConsequenceLine(a: ConsequenceAggregate): string;
|
|
113
|
+
export {};
|
|
114
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/consequence_ledger/index.ts"],"names":[],"mappings":"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"}
|