@mneme-ai/core 2.79.0 → 2.81.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 +2 -0
- package/dist/agent_manifest.js.map +1 -1
- package/dist/flight_recorder/flight_recorder.test.d.ts +20 -0
- package/dist/flight_recorder/flight_recorder.test.d.ts.map +1 -0
- package/dist/flight_recorder/flight_recorder.test.js +185 -0
- package/dist/flight_recorder/flight_recorder.test.js.map +1 -0
- package/dist/flight_recorder/index.d.ts +11 -0
- package/dist/flight_recorder/index.d.ts.map +1 -0
- package/dist/flight_recorder/index.js +11 -0
- package/dist/flight_recorder/index.js.map +1 -0
- package/dist/flight_recorder/recorder.d.ts +120 -0
- package/dist/flight_recorder/recorder.d.ts.map +1 -0
- package/dist/flight_recorder/recorder.js +173 -0
- package/dist/flight_recorder/recorder.js.map +1 -0
- package/dist/honesty_score/honesty_score.test.d.ts +14 -0
- package/dist/honesty_score/honesty_score.test.d.ts.map +1 -0
- package/dist/honesty_score/honesty_score.test.js +130 -0
- package/dist/honesty_score/honesty_score.test.js.map +1 -0
- package/dist/honesty_score/index.d.ts +93 -0
- package/dist/honesty_score/index.d.ts.map +1 -0
- package/dist/honesty_score/index.js +118 -0
- package/dist/honesty_score/index.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/truth_gate/claims.d.ts.map +1 -1
- package/dist/truth_gate/claims.js +20 -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 +61 -0
- package/dist/truth_gate/probes.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v2.80.0 — FLIGHT RECORDER pinned + QUAN (property/fuzz) tests.
|
|
3
|
+
*
|
|
4
|
+
* Pinned (F):
|
|
5
|
+
* F1 record → chain verifies offline
|
|
6
|
+
* F2 truth-delta classifier (MATCH / CONTRADICT / UNVERIFIED)
|
|
7
|
+
* F3 replay pinpoints the first incident + counts
|
|
8
|
+
* F4 seal → verifySeal; wrong head rejected
|
|
9
|
+
* F5 every frame verifies over-the-wire (serialization survives)
|
|
10
|
+
*
|
|
11
|
+
* QUAN (Q) — exhaustive property/fuzz invariants (the "weird" tests):
|
|
12
|
+
* Q1 N random frames → chain ALWAYS verifies (integrity invariant)
|
|
13
|
+
* Q2 tamper at EVERY position → verify ALWAYS fails (no silent pass)
|
|
14
|
+
* Q3 swap ANY two frames → chain breaks (causal order is load-bearing)
|
|
15
|
+
* Q4 a PREFIX of a chain is valid; dropping a MIDDLE frame breaks it
|
|
16
|
+
* Q5 classifyTruthDelta is total (never throws) over fuzz + deterministic
|
|
17
|
+
* Q6 seal commits the head; tampering a frame post-seal is caught
|
|
18
|
+
*/
|
|
19
|
+
import { describe, it, expect } from "vitest";
|
|
20
|
+
import { mkdtempSync } from "node:fs";
|
|
21
|
+
import { tmpdir } from "node:os";
|
|
22
|
+
import { join } from "node:path";
|
|
23
|
+
import { record, readCdr, verifyCdr, replay, seal, verifySeal, classifyTruthDelta, } from "./index.js";
|
|
24
|
+
import { verifyChain } from "../notary/index.js";
|
|
25
|
+
const repo = () => mkdtempSync(join(tmpdir(), "mneme-flight-"));
|
|
26
|
+
describe("v2.80.0 F1 — record + verify (PINNED)", () => {
|
|
27
|
+
it("F1.1 a recorded sequence verifies offline + chains", () => {
|
|
28
|
+
const r = repo();
|
|
29
|
+
record(r, { agent: "claude", kind: "action", action: "edit file a.ts" });
|
|
30
|
+
record(r, { agent: "claude", kind: "tool-call", action: "run tests", claim: "all pass", observedReality: "all pass" });
|
|
31
|
+
const v = verifyCdr(r);
|
|
32
|
+
expect(v.valid).toBe(true);
|
|
33
|
+
expect(v.frames).toBe(2);
|
|
34
|
+
expect(readCdr(r)[1].prev).toBe(readCdr(r)[0].receiptId);
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
describe("v2.80.0 F2 — truth-delta classifier (PINNED)", () => {
|
|
38
|
+
it("F2.1 MATCH / CONTRADICT / UNVERIFIED", () => {
|
|
39
|
+
expect(classifyTruthDelta("19 vessels", "19 vessels")).toBe("MATCH");
|
|
40
|
+
expect(classifyTruthDelta("the file exists", "no such file — missing")).toBe("CONTRADICT");
|
|
41
|
+
expect(classifyTruthDelta("count is 400", "count is 100000")).toBe("CONTRADICT");
|
|
42
|
+
expect(classifyTruthDelta("react 19 ships rsc", "react 19 ships rsc by default")).toBe("MATCH");
|
|
43
|
+
expect(classifyTruthDelta("the sky is blue", "bananas are yellow")).toBe("UNVERIFIED");
|
|
44
|
+
expect(classifyTruthDelta(undefined, "x")).toBe("UNVERIFIED");
|
|
45
|
+
});
|
|
46
|
+
it("F2.2 explicit caller verdict overrides the heuristic", () => {
|
|
47
|
+
const r = repo();
|
|
48
|
+
const f = record(r, { agent: "a", action: "x", claim: "same", observedReality: "same", truthDelta: "CONTRADICT" });
|
|
49
|
+
expect(f.truthDelta).toBe("CONTRADICT"); // caller wins even though heuristic would MATCH
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
describe("v2.80.0 F3 — replay (PINNED)", () => {
|
|
53
|
+
it("F3.1 finds the first incident + counts", () => {
|
|
54
|
+
const r = repo();
|
|
55
|
+
record(r, { agent: "a", action: "step 1", claim: "ok", observedReality: "ok" }); // MATCH
|
|
56
|
+
record(r, { agent: "a", action: "step 2" }); // UNVERIFIED
|
|
57
|
+
record(r, { agent: "a", action: "step 3", claim: "no bug", observedReality: "bug: refuted" }); // CONTRADICT
|
|
58
|
+
record(r, { agent: "a", action: "step 4", claim: "x", observedReality: "false" }); // CONTRADICT
|
|
59
|
+
const rep = replay(r);
|
|
60
|
+
expect(rep.frames).toBe(4);
|
|
61
|
+
expect(rep.chainValid).toBe(true);
|
|
62
|
+
expect(rep.incidentSeq).toBe(2); // first CONTRADICT is seq #2 (0-indexed step 3)
|
|
63
|
+
expect(rep.counts).toEqual({ match: 1, contradict: 2, unverified: 1 });
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
describe("v2.80.0 F4 — seal (PINNED)", () => {
|
|
67
|
+
it("F4.1 seal verifies + commits the head; a wrong head is rejected", () => {
|
|
68
|
+
const r = repo();
|
|
69
|
+
record(r, { agent: "a", action: "x" });
|
|
70
|
+
const head = readCdr(r)[0].receiptId;
|
|
71
|
+
const s = seal(r);
|
|
72
|
+
expect(s.head).toBe(head);
|
|
73
|
+
expect(verifySeal(s, head).valid).toBe(true);
|
|
74
|
+
expect(verifySeal(s, "deadbeef").valid).toBe(false);
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
describe("v2.80.0 F5 — over-the-wire (PINNED)", () => {
|
|
78
|
+
it("F5.1 each frame verifies after JSON round-trip (third party, offline)", () => {
|
|
79
|
+
const r = repo();
|
|
80
|
+
record(r, { agent: "a", action: "x", reasoning: "because y" });
|
|
81
|
+
record(r, { agent: "a", action: "z", claim: "c", observedReality: "c" });
|
|
82
|
+
const wire = JSON.parse(JSON.stringify(readCdr(r)));
|
|
83
|
+
expect(verifyChain(wire).valid).toBe(true);
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
// ─────────────────────────── QUAN (property / fuzz) ───────────────────────────
|
|
87
|
+
const KINDS = ["action", "decision", "claim", "tool-call", "payment", "observation"];
|
|
88
|
+
function randFrame(i) {
|
|
89
|
+
const seedy = (n) => (i * 2654435761 + n * 40503) >>> 0;
|
|
90
|
+
const pick = (arr, n) => arr[seedy(n) % arr.length];
|
|
91
|
+
const withClaim = seedy(3) % 2 === 0;
|
|
92
|
+
return {
|
|
93
|
+
agent: pick(["claude", "gpt", "gemini", "grok", "cursor"], 1),
|
|
94
|
+
kind: pick(KINDS, 2),
|
|
95
|
+
action: `op-${i}-${seedy(4).toString(36)}`,
|
|
96
|
+
...(withClaim ? { claim: `claim ${seedy(5) % 100}`, observedReality: `reality ${seedy(6) % 100}` } : {}),
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
describe("v2.80.0 Q1-Q4 — chain integrity invariants (QUAN)", () => {
|
|
100
|
+
it("Q1 N random frames → the chain ALWAYS verifies", () => {
|
|
101
|
+
const r = repo();
|
|
102
|
+
const N = 40;
|
|
103
|
+
for (let i = 0; i < N; i++)
|
|
104
|
+
record(r, randFrame(i));
|
|
105
|
+
const v = verifyCdr(r);
|
|
106
|
+
expect(v.valid).toBe(true);
|
|
107
|
+
expect(v.frames).toBe(N);
|
|
108
|
+
});
|
|
109
|
+
it("Q2 tampering ANY field at EVERY position → verify ALWAYS fails", () => {
|
|
110
|
+
const r = repo();
|
|
111
|
+
for (let i = 0; i < 12; i++)
|
|
112
|
+
record(r, randFrame(i));
|
|
113
|
+
const chain = readCdr(r);
|
|
114
|
+
for (let i = 0; i < chain.length; i++) {
|
|
115
|
+
// tamper the payload (action) of frame i — its signature must now fail.
|
|
116
|
+
const mutated = chain.map((c, j) => j === i
|
|
117
|
+
? { ...c, payload: { ...c.payload, action: "TAMPERED" } }
|
|
118
|
+
: c);
|
|
119
|
+
expect(verifyChain(mutated).valid, `tamper at ${i} must fail`).toBe(false);
|
|
120
|
+
// also tamper the subject (a body field outside payload)
|
|
121
|
+
const mutated2 = chain.map((c, j) => j === i ? { ...c, subject: "evil" } : c);
|
|
122
|
+
expect(verifyChain(mutated2).valid, `subject tamper at ${i} must fail`).toBe(false);
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
it("Q3 swapping ANY two frames breaks the causal chain", () => {
|
|
126
|
+
const r = repo();
|
|
127
|
+
for (let i = 0; i < 8; i++)
|
|
128
|
+
record(r, randFrame(i));
|
|
129
|
+
const chain = readCdr(r);
|
|
130
|
+
expect(verifyChain(chain).valid).toBe(true);
|
|
131
|
+
for (let i = 0; i < chain.length; i++) {
|
|
132
|
+
for (let j = i + 1; j < chain.length; j++) {
|
|
133
|
+
const swapped = chain.slice();
|
|
134
|
+
[swapped[i], swapped[j]] = [swapped[j], swapped[i]];
|
|
135
|
+
expect(verifyChain(swapped).valid, `swap ${i}<->${j} must break`).toBe(false);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
it("Q4 a PREFIX is valid; dropping a MIDDLE frame breaks the chain", () => {
|
|
140
|
+
const r = repo();
|
|
141
|
+
for (let i = 0; i < 10; i++)
|
|
142
|
+
record(r, randFrame(i));
|
|
143
|
+
const chain = readCdr(r);
|
|
144
|
+
for (let k = 1; k <= chain.length; k++) {
|
|
145
|
+
expect(verifyChain(chain.slice(0, k)).valid, `prefix len ${k}`).toBe(true);
|
|
146
|
+
}
|
|
147
|
+
// drop a middle frame → the following frame's prev no longer matches.
|
|
148
|
+
const holed = chain.filter((_, idx) => idx !== 4);
|
|
149
|
+
expect(verifyChain(holed).valid).toBe(false);
|
|
150
|
+
});
|
|
151
|
+
});
|
|
152
|
+
describe("v2.80.0 Q5 — truth-delta is total + deterministic (QUAN)", () => {
|
|
153
|
+
it("Q5.1 never throws over fuzz inputs + is deterministic", () => {
|
|
154
|
+
const samples = [];
|
|
155
|
+
for (let i = 0; i < 200; i++) {
|
|
156
|
+
const s = (n) => (((i + 1) * (n * 7 + 3)) % 13 === 0) ? undefined : `tok ${(i * n) % 97} ${(i % 3 === 0) ? "false" : "ok"} ${i % 100}`;
|
|
157
|
+
samples.push([s(1), s(2)]);
|
|
158
|
+
}
|
|
159
|
+
for (const [a, b] of samples) {
|
|
160
|
+
const v1 = classifyTruthDelta(a, b);
|
|
161
|
+
const v2 = classifyTruthDelta(a, b);
|
|
162
|
+
expect(["MATCH", "CONTRADICT", "UNVERIFIED"]).toContain(v1);
|
|
163
|
+
expect(v2).toBe(v1); // deterministic
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
});
|
|
167
|
+
describe("v2.80.0 Q6 — seal commits the head (QUAN)", () => {
|
|
168
|
+
it("Q6.1 sealing then tampering a frame is caught by chain re-verify", () => {
|
|
169
|
+
const r = repo();
|
|
170
|
+
for (let i = 0; i < 6; i++)
|
|
171
|
+
record(r, randFrame(i));
|
|
172
|
+
const chain = readCdr(r);
|
|
173
|
+
const head = chain[chain.length - 1].receiptId;
|
|
174
|
+
const s = seal(r);
|
|
175
|
+
expect(verifySeal(s, head).valid).toBe(true);
|
|
176
|
+
// An attacker edits frame #2 after the seal. The seal signature still
|
|
177
|
+
// verifies (it signed the OLD head), but the head it commits no longer
|
|
178
|
+
// matches the tampered chain's verification — and the chain itself fails.
|
|
179
|
+
const tampered = chain.map((c, j) => j === 2 ? { ...c, payload: { ...c.payload, action: "edited" } } : c);
|
|
180
|
+
expect(verifyChain(tampered).valid).toBe(false);
|
|
181
|
+
// The seal still commits the original head, exposing the divergence.
|
|
182
|
+
expect(s.receipt.payload.head).toBe(head);
|
|
183
|
+
});
|
|
184
|
+
});
|
|
185
|
+
//# sourceMappingURL=flight_recorder.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flight_recorder.test.js","sourceRoot":"","sources":["../../src/flight_recorder/flight_recorder.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v2.80.0 — FLIGHT RECORDER · the tamper-evident, replayable AI black box.
|
|
3
|
+
*
|
|
4
|
+
* Diamond 💎3 of the TRUST FABRIC. Built on the v2.79 NOTARY spine: every frame
|
|
5
|
+
* is an Ed25519-signed, chained receipt, so the whole cockpit-data-recorder is
|
|
6
|
+
* tamper-evident + attributable + verifiable OFFLINE by any third party. Replay
|
|
7
|
+
* pinpoints the first claim-vs-reality divergence; seal produces one
|
|
8
|
+
* court-admissible artifact.
|
|
9
|
+
*/
|
|
10
|
+
export { record, readCdr, verifyCdr, replay, seal, verifySeal, classifyTruthDelta, type FrameKind, type TruthDelta, type FramePayload, type RecordInput, type RecordedFrame, type CdrVerifyResult, type ReplayResult, type FlightSeal, } from "./recorder.js";
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/flight_recorder/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EACL,MAAM,EACN,OAAO,EACP,SAAS,EACT,MAAM,EACN,IAAI,EACJ,UAAU,EACV,kBAAkB,EAClB,KAAK,SAAS,EACd,KAAK,UAAU,EACf,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,KAAK,YAAY,EACjB,KAAK,UAAU,GAChB,MAAM,eAAe,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v2.80.0 — FLIGHT RECORDER · the tamper-evident, replayable AI black box.
|
|
3
|
+
*
|
|
4
|
+
* Diamond 💎3 of the TRUST FABRIC. Built on the v2.79 NOTARY spine: every frame
|
|
5
|
+
* is an Ed25519-signed, chained receipt, so the whole cockpit-data-recorder is
|
|
6
|
+
* tamper-evident + attributable + verifiable OFFLINE by any third party. Replay
|
|
7
|
+
* pinpoints the first claim-vs-reality divergence; seal produces one
|
|
8
|
+
* court-admissible artifact.
|
|
9
|
+
*/
|
|
10
|
+
export { record, readCdr, verifyCdr, replay, seal, verifySeal, classifyTruthDelta, } from "./recorder.js";
|
|
11
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/flight_recorder/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EACL,MAAM,EACN,OAAO,EACP,SAAS,EACT,MAAM,EACN,IAAI,EACJ,UAAU,EACV,kBAAkB,GASnB,MAAM,eAAe,CAAC"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v2.80.0 — FLIGHT RECORDER · the AI black box (diamond 💎3, built on the v2.79 NOTARY spine).
|
|
3
|
+
*
|
|
4
|
+
* When an agent controls a PC (Grok Computer), pays via x402, or merges code,
|
|
5
|
+
* an incident needs a court-admissible record: WHAT it did, WHY (reasoning),
|
|
6
|
+
* and what it CLAIMED vs what was TRUE (truth-delta) — in causal order, and
|
|
7
|
+
* impossible to forge after the fact.
|
|
8
|
+
*
|
|
9
|
+
* Design — every frame IS a NOTARY receipt:
|
|
10
|
+
* - Each recorded frame is signed (Ed25519) + chained (prev → receiptId).
|
|
11
|
+
* - The whole CDR therefore inherits NOTARY's three guarantees at once:
|
|
12
|
+
* tamper-evidence (any edit breaks the signature),
|
|
13
|
+
* attribution (who recorded it — the issuer key),
|
|
14
|
+
* portability (a third party verifies OFFLINE with the public key).
|
|
15
|
+
* - `seal()` issues ONE final receipt over the chain head — the single
|
|
16
|
+
* artifact you hand an auditor / insurer / court.
|
|
17
|
+
* - `replay()` walks the chain in causal order and pinpoints the first
|
|
18
|
+
* truth-delta divergence (the "incident moment").
|
|
19
|
+
*
|
|
20
|
+
* No new crypto here — it composes the NOTARY primitive. Pure logic except
|
|
21
|
+
* record/seal (sign) and the jsonl read/append. Defensive: never throws on
|
|
22
|
+
* read; malformed lines are skipped.
|
|
23
|
+
*/
|
|
24
|
+
import { type NotaryReceipt, type IssuerKeyPair } from "../notary/index.js";
|
|
25
|
+
export type FrameKind = "action" | "decision" | "claim" | "tool-call" | "payment" | "observation";
|
|
26
|
+
export type TruthDelta = "MATCH" | "CONTRADICT" | "UNVERIFIED";
|
|
27
|
+
/** The data a caller records. The recorder wraps it in a signed receipt. */
|
|
28
|
+
export interface FramePayload {
|
|
29
|
+
seq: number;
|
|
30
|
+
agent: string;
|
|
31
|
+
kind: FrameKind;
|
|
32
|
+
/** What the agent did (free text / structured summary). */
|
|
33
|
+
action: string;
|
|
34
|
+
/** Why — reasoning trace (optional). */
|
|
35
|
+
reasoning?: string;
|
|
36
|
+
/** A checkable claim the agent asserted (optional). */
|
|
37
|
+
claim?: string;
|
|
38
|
+
/** What was actually observed/true (optional). */
|
|
39
|
+
observedReality?: string;
|
|
40
|
+
/** Claim-vs-reality verdict. Caller may supply (e.g. from `mneme verify`);
|
|
41
|
+
* else computed heuristically from claim + observedReality. */
|
|
42
|
+
truthDelta?: TruthDelta;
|
|
43
|
+
}
|
|
44
|
+
export interface RecordInput {
|
|
45
|
+
agent: string;
|
|
46
|
+
kind?: FrameKind;
|
|
47
|
+
action: string;
|
|
48
|
+
reasoning?: string;
|
|
49
|
+
claim?: string;
|
|
50
|
+
observedReality?: string;
|
|
51
|
+
/** Explicit verdict from a real verifier; overrides the heuristic. */
|
|
52
|
+
truthDelta?: TruthDelta;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Heuristic claim-vs-reality classifier. HONEST SCOPE: this is a deterministic
|
|
56
|
+
* string/number heuristic, NOT semantic truth — feed a real verifier's verdict
|
|
57
|
+
* via RecordInput.truthDelta when you have one. Returns UNVERIFIED when it
|
|
58
|
+
* cannot decide rather than guessing.
|
|
59
|
+
*/
|
|
60
|
+
export declare function classifyTruthDelta(claim?: string, observed?: string): TruthDelta;
|
|
61
|
+
/** Read the chain of receipts (one per jsonl line). Skips malformed lines. */
|
|
62
|
+
export declare function readCdr(repoRoot: string): NotaryReceipt[];
|
|
63
|
+
export interface RecordedFrame {
|
|
64
|
+
seq: number;
|
|
65
|
+
receiptId: string;
|
|
66
|
+
truthDelta: TruthDelta;
|
|
67
|
+
receipt: NotaryReceipt;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Record one frame: compute truth-delta, chain onto the prior receiptId, sign,
|
|
71
|
+
* append. Returns the recorded frame. The returned receipt verifies offline.
|
|
72
|
+
*/
|
|
73
|
+
export declare function record(repoRoot: string, input: RecordInput, keyPair?: IssuerKeyPair): RecordedFrame;
|
|
74
|
+
export interface CdrVerifyResult {
|
|
75
|
+
valid: boolean;
|
|
76
|
+
reason: string;
|
|
77
|
+
frames: number;
|
|
78
|
+
brokenAt?: number;
|
|
79
|
+
}
|
|
80
|
+
/** Verify the whole black box: every frame signs + chains (offline, public-key). */
|
|
81
|
+
export declare function verifyCdr(repoRoot: string, opts?: {
|
|
82
|
+
sameIssuer?: boolean;
|
|
83
|
+
}): CdrVerifyResult;
|
|
84
|
+
export interface ReplayResult {
|
|
85
|
+
frames: number;
|
|
86
|
+
/** Causal-order summary lines (human readable). */
|
|
87
|
+
narrative: string[];
|
|
88
|
+
/** seq of the first CONTRADICT frame, or null. The "incident moment". */
|
|
89
|
+
incidentSeq: number | null;
|
|
90
|
+
counts: {
|
|
91
|
+
match: number;
|
|
92
|
+
contradict: number;
|
|
93
|
+
unverified: number;
|
|
94
|
+
};
|
|
95
|
+
/** Verified offline before replaying? */
|
|
96
|
+
chainValid: boolean;
|
|
97
|
+
}
|
|
98
|
+
/** Walk the chain in causal order, surface the first truth-delta divergence. */
|
|
99
|
+
export declare function replay(repoRoot: string): ReplayResult;
|
|
100
|
+
export interface FlightSeal {
|
|
101
|
+
v: 1;
|
|
102
|
+
frames: number;
|
|
103
|
+
head: string | null;
|
|
104
|
+
contradictions: number;
|
|
105
|
+
incidentSeq: number | null;
|
|
106
|
+
/** The single court-admissible artifact: a signed receipt over the chain head. */
|
|
107
|
+
receipt: NotaryReceipt;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Seal the black box: issue ONE NOTARY receipt over the chain head + summary.
|
|
111
|
+
* Since each frame chains onto the prior receiptId, the head commits the entire
|
|
112
|
+
* sequence — verifying the seal + the head's chain proves the whole flight.
|
|
113
|
+
*/
|
|
114
|
+
export declare function seal(repoRoot: string, keyPair?: IssuerKeyPair): FlightSeal;
|
|
115
|
+
/** Verify a seal offline (signature) AND that it commits the expected head. */
|
|
116
|
+
export declare function verifySeal(seal: FlightSeal, expectedHead: string | null): {
|
|
117
|
+
valid: boolean;
|
|
118
|
+
reason: string;
|
|
119
|
+
};
|
|
120
|
+
//# sourceMappingURL=recorder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recorder.d.ts","sourceRoot":"","sources":["../../src/flight_recorder/recorder.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v2.80.0 — FLIGHT RECORDER · the AI black box (diamond 💎3, built on the v2.79 NOTARY spine).
|
|
3
|
+
*
|
|
4
|
+
* When an agent controls a PC (Grok Computer), pays via x402, or merges code,
|
|
5
|
+
* an incident needs a court-admissible record: WHAT it did, WHY (reasoning),
|
|
6
|
+
* and what it CLAIMED vs what was TRUE (truth-delta) — in causal order, and
|
|
7
|
+
* impossible to forge after the fact.
|
|
8
|
+
*
|
|
9
|
+
* Design — every frame IS a NOTARY receipt:
|
|
10
|
+
* - Each recorded frame is signed (Ed25519) + chained (prev → receiptId).
|
|
11
|
+
* - The whole CDR therefore inherits NOTARY's three guarantees at once:
|
|
12
|
+
* tamper-evidence (any edit breaks the signature),
|
|
13
|
+
* attribution (who recorded it — the issuer key),
|
|
14
|
+
* portability (a third party verifies OFFLINE with the public key).
|
|
15
|
+
* - `seal()` issues ONE final receipt over the chain head — the single
|
|
16
|
+
* artifact you hand an auditor / insurer / court.
|
|
17
|
+
* - `replay()` walks the chain in causal order and pinpoints the first
|
|
18
|
+
* truth-delta divergence (the "incident moment").
|
|
19
|
+
*
|
|
20
|
+
* No new crypto here — it composes the NOTARY primitive. Pure logic except
|
|
21
|
+
* record/seal (sign) and the jsonl read/append. Defensive: never throws on
|
|
22
|
+
* read; malformed lines are skipped.
|
|
23
|
+
*/
|
|
24
|
+
import { existsSync, readFileSync, appendFileSync, mkdirSync } from "node:fs";
|
|
25
|
+
import { join } from "node:path";
|
|
26
|
+
import { issueReceipt, verifyReceipt, verifyChain } from "../notary/index.js";
|
|
27
|
+
const CDR_REL = ".mneme/flight_recorder/cdr.jsonl";
|
|
28
|
+
function cdrPath(repoRoot) {
|
|
29
|
+
return join(repoRoot, CDR_REL);
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Heuristic claim-vs-reality classifier. HONEST SCOPE: this is a deterministic
|
|
33
|
+
* string/number heuristic, NOT semantic truth — feed a real verifier's verdict
|
|
34
|
+
* via RecordInput.truthDelta when you have one. Returns UNVERIFIED when it
|
|
35
|
+
* cannot decide rather than guessing.
|
|
36
|
+
*/
|
|
37
|
+
export function classifyTruthDelta(claim, observed) {
|
|
38
|
+
if (!claim || !observed)
|
|
39
|
+
return "UNVERIFIED";
|
|
40
|
+
const norm = (s) => s.toLowerCase().replace(/\s+/g, " ").trim();
|
|
41
|
+
const c = norm(claim);
|
|
42
|
+
const o = norm(observed);
|
|
43
|
+
if (c.length === 0 || o.length === 0)
|
|
44
|
+
return "UNVERIFIED";
|
|
45
|
+
if (c === o)
|
|
46
|
+
return "MATCH";
|
|
47
|
+
// Explicit refutation language in the observation.
|
|
48
|
+
if (/\b(false|incorrect|refuted|wrong|not true|does not|doesn't|did not|didn't|no such|missing|failed)\b/.test(o)) {
|
|
49
|
+
return "CONTRADICT";
|
|
50
|
+
}
|
|
51
|
+
// Numeric disagreement: if both carry numbers and none of the claim's numbers
|
|
52
|
+
// appear in the observation, treat as contradiction.
|
|
53
|
+
const nums = (s) => (s.match(/-?\d+(?:\.\d+)?/g) ?? []);
|
|
54
|
+
const cn = nums(c), on = nums(o);
|
|
55
|
+
if (cn.length > 0 && on.length > 0) {
|
|
56
|
+
const overlap = cn.some((x) => on.includes(x));
|
|
57
|
+
if (!overlap)
|
|
58
|
+
return "CONTRADICT";
|
|
59
|
+
}
|
|
60
|
+
// Observation entails the claim (substring) → match.
|
|
61
|
+
if (o.includes(c) || c.includes(o))
|
|
62
|
+
return "MATCH";
|
|
63
|
+
return "UNVERIFIED";
|
|
64
|
+
}
|
|
65
|
+
/** Read the chain of receipts (one per jsonl line). Skips malformed lines. */
|
|
66
|
+
export function readCdr(repoRoot) {
|
|
67
|
+
const p = cdrPath(repoRoot);
|
|
68
|
+
if (!existsSync(p))
|
|
69
|
+
return [];
|
|
70
|
+
const out = [];
|
|
71
|
+
for (const line of readFileSync(p, "utf8").split("\n")) {
|
|
72
|
+
const t = line.trim();
|
|
73
|
+
if (!t)
|
|
74
|
+
continue;
|
|
75
|
+
try {
|
|
76
|
+
out.push(JSON.parse(t));
|
|
77
|
+
}
|
|
78
|
+
catch { /* skip malformed */ }
|
|
79
|
+
}
|
|
80
|
+
return out;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Record one frame: compute truth-delta, chain onto the prior receiptId, sign,
|
|
84
|
+
* append. Returns the recorded frame. The returned receipt verifies offline.
|
|
85
|
+
*/
|
|
86
|
+
export function record(repoRoot, input, keyPair) {
|
|
87
|
+
const chain = readCdr(repoRoot);
|
|
88
|
+
const seq = chain.length;
|
|
89
|
+
const prev = chain.length > 0 ? chain[chain.length - 1].receiptId : null;
|
|
90
|
+
const truthDelta = input.truthDelta ?? classifyTruthDelta(input.claim, input.observedReality);
|
|
91
|
+
const payload = {
|
|
92
|
+
seq,
|
|
93
|
+
agent: input.agent,
|
|
94
|
+
kind: input.kind ?? "action",
|
|
95
|
+
action: input.action,
|
|
96
|
+
...(input.reasoning !== undefined ? { reasoning: input.reasoning } : {}),
|
|
97
|
+
...(input.claim !== undefined ? { claim: input.claim } : {}),
|
|
98
|
+
...(input.observedReality !== undefined ? { observedReality: input.observedReality } : {}),
|
|
99
|
+
truthDelta,
|
|
100
|
+
};
|
|
101
|
+
const receipt = issueReceipt(repoRoot, {
|
|
102
|
+
kind: "reasoning-trace",
|
|
103
|
+
subject: `frame:${seq}:${input.action.slice(0, 64)}`,
|
|
104
|
+
payload,
|
|
105
|
+
prev,
|
|
106
|
+
}, keyPair);
|
|
107
|
+
try {
|
|
108
|
+
const dir = join(repoRoot, ".mneme", "flight_recorder");
|
|
109
|
+
if (!existsSync(dir))
|
|
110
|
+
mkdirSync(dir, { recursive: true });
|
|
111
|
+
appendFileSync(cdrPath(repoRoot), JSON.stringify(receipt) + "\n", "utf8");
|
|
112
|
+
}
|
|
113
|
+
catch { /* best-effort persistence; the returned receipt is still valid */ }
|
|
114
|
+
return { seq, receiptId: receipt.receiptId, truthDelta, receipt };
|
|
115
|
+
}
|
|
116
|
+
/** Verify the whole black box: every frame signs + chains (offline, public-key). */
|
|
117
|
+
export function verifyCdr(repoRoot, opts = {}) {
|
|
118
|
+
const chain = readCdr(repoRoot);
|
|
119
|
+
if (chain.length === 0)
|
|
120
|
+
return { valid: true, reason: "empty recorder", frames: 0 };
|
|
121
|
+
const v = verifyChain(chain, { sameIssuer: opts.sameIssuer });
|
|
122
|
+
return { valid: v.valid, reason: v.reason, frames: chain.length, brokenAt: v.brokenAt };
|
|
123
|
+
}
|
|
124
|
+
/** Walk the chain in causal order, surface the first truth-delta divergence. */
|
|
125
|
+
export function replay(repoRoot) {
|
|
126
|
+
const chain = readCdr(repoRoot);
|
|
127
|
+
const chainValid = chain.length === 0 ? true : verifyChain(chain).valid;
|
|
128
|
+
const narrative = [];
|
|
129
|
+
const counts = { match: 0, contradict: 0, unverified: 0 };
|
|
130
|
+
let incidentSeq = null;
|
|
131
|
+
for (const r of chain) {
|
|
132
|
+
const p = (r.payload ?? {});
|
|
133
|
+
const td = (p.truthDelta ?? "UNVERIFIED");
|
|
134
|
+
if (td === "MATCH")
|
|
135
|
+
counts.match++;
|
|
136
|
+
else if (td === "CONTRADICT")
|
|
137
|
+
counts.contradict++;
|
|
138
|
+
else
|
|
139
|
+
counts.unverified++;
|
|
140
|
+
if (td === "CONTRADICT" && incidentSeq === null)
|
|
141
|
+
incidentSeq = p.seq ?? null;
|
|
142
|
+
const mark = td === "CONTRADICT" ? "🔴" : td === "MATCH" ? "🟢" : "⚪";
|
|
143
|
+
narrative.push(`${mark} #${p.seq ?? "?"} [${p.kind ?? "?"}] ${p.agent ?? "?"}: ${String(p.action ?? "").slice(0, 80)}${p.claim ? ` — claim: "${String(p.claim).slice(0, 60)}" vs reality (${td})` : ""}`);
|
|
144
|
+
}
|
|
145
|
+
return { frames: chain.length, narrative, incidentSeq, counts, chainValid };
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Seal the black box: issue ONE NOTARY receipt over the chain head + summary.
|
|
149
|
+
* Since each frame chains onto the prior receiptId, the head commits the entire
|
|
150
|
+
* sequence — verifying the seal + the head's chain proves the whole flight.
|
|
151
|
+
*/
|
|
152
|
+
export function seal(repoRoot, keyPair) {
|
|
153
|
+
const chain = readCdr(repoRoot);
|
|
154
|
+
const r = replay(repoRoot);
|
|
155
|
+
const head = chain.length > 0 ? chain[chain.length - 1].receiptId : null;
|
|
156
|
+
const receipt = issueReceipt(repoRoot, {
|
|
157
|
+
kind: "generic",
|
|
158
|
+
subject: `flight-seal:${head ?? "empty"}`,
|
|
159
|
+
payload: { head, frames: chain.length, contradictions: r.counts.contradict, incidentSeq: r.incidentSeq },
|
|
160
|
+
}, keyPair);
|
|
161
|
+
return { v: 1, frames: chain.length, head, contradictions: r.counts.contradict, incidentSeq: r.incidentSeq, receipt };
|
|
162
|
+
}
|
|
163
|
+
/** Verify a seal offline (signature) AND that it commits the expected head. */
|
|
164
|
+
export function verifySeal(seal, expectedHead) {
|
|
165
|
+
const v = verifyReceipt(seal.receipt);
|
|
166
|
+
if (!v.valid)
|
|
167
|
+
return { valid: false, reason: `seal signature: ${v.reason}` };
|
|
168
|
+
const committedHead = seal.receipt.payload?.head ?? null;
|
|
169
|
+
if (committedHead !== expectedHead)
|
|
170
|
+
return { valid: false, reason: "seal does not commit the expected chain head" };
|
|
171
|
+
return { valid: true, reason: "ok" };
|
|
172
|
+
}
|
|
173
|
+
//# sourceMappingURL=recorder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recorder.js","sourceRoot":"","sources":["../../src/flight_recorder/recorder.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v2.81.0 — HONESTY CREDIT SCORE pinned + QUAN tests.
|
|
3
|
+
* H1 Wilson-LB scoring: small sample penalized; perfect-large > perfect-small
|
|
4
|
+
* H2 band boundaries (PLATINUM/GOLD/SILVER/BRONZE/UNTRUSTED/UNMEASURED)
|
|
5
|
+
* H3 issue → verifyHonestyReceipt round trip (offline)
|
|
6
|
+
* H4 tamper / wrong-issuer / expiry rejected
|
|
7
|
+
* H5 shouldTrust band gating + expiry + issuer assertion
|
|
8
|
+
* QUAN:
|
|
9
|
+
* Q1 monotonic: more true (same total) ⇒ score never decreases
|
|
10
|
+
* Q2 score always in [0,100]; total+deterministic over fuzz; never throws
|
|
11
|
+
* Q3 a vendor cannot self-promote by forging the payload (signature catches it)
|
|
12
|
+
*/
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=honesty_score.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"honesty_score.test.d.ts","sourceRoot":"","sources":["../../src/honesty_score/honesty_score.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG"}
|