@mneme-ai/core 2.19.30 → 2.19.32
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/beacon/beacon.test.js +44 -0
- package/dist/beacon/beacon.test.js.map +1 -1
- package/dist/beacon/index.d.ts.map +1 -1
- package/dist/beacon/index.js +5 -1
- package/dist/beacon/index.js.map +1 -1
- package/dist/consciousness_fork/consciousness_fork.test.d.ts +2 -0
- package/dist/consciousness_fork/consciousness_fork.test.d.ts.map +1 -0
- package/dist/consciousness_fork/consciousness_fork.test.js +177 -0
- package/dist/consciousness_fork/consciousness_fork.test.js.map +1 -0
- package/dist/consciousness_fork/index.d.ts +129 -0
- package/dist/consciousness_fork/index.d.ts.map +1 -0
- package/dist/consciousness_fork/index.js +227 -0
- package/dist/consciousness_fork/index.js.map +1 -0
- package/dist/cosmic/aurelian_v1931.test.d.ts +2 -0
- package/dist/cosmic/aurelian_v1931.test.d.ts.map +1 -0
- package/dist/cosmic/aurelian_v1931.test.js +67 -0
- package/dist/cosmic/aurelian_v1931.test.js.map +1 -0
- package/dist/cosmic/aurelian_v1932.test.d.ts +2 -0
- package/dist/cosmic/aurelian_v1932.test.d.ts.map +1 -0
- package/dist/cosmic/aurelian_v1932.test.js +83 -0
- package/dist/cosmic/aurelian_v1932.test.js.map +1 -0
- package/dist/handoff_pwa/handoff_pwa.test.d.ts +2 -0
- package/dist/handoff_pwa/handoff_pwa.test.d.ts.map +1 -0
- package/dist/handoff_pwa/handoff_pwa.test.js +119 -0
- package/dist/handoff_pwa/handoff_pwa.test.js.map +1 -0
- package/dist/handoff_pwa/index.d.ts +81 -0
- package/dist/handoff_pwa/index.d.ts.map +1 -0
- package/dist/handoff_pwa/index.js +312 -0
- package/dist/handoff_pwa/index.js.map +1 -0
- package/dist/handoff_snapshot/handoff_snapshot.test.d.ts +2 -0
- package/dist/handoff_snapshot/handoff_snapshot.test.d.ts.map +1 -0
- package/dist/handoff_snapshot/handoff_snapshot.test.js +147 -0
- package/dist/handoff_snapshot/handoff_snapshot.test.js.map +1 -0
- package/dist/handoff_snapshot/index.d.ts +156 -0
- package/dist/handoff_snapshot/index.d.ts.map +1 -0
- package/dist/handoff_snapshot/index.js +261 -0
- package/dist/handoff_snapshot/index.js.map +1 -0
- package/dist/handoff_snapshot/system_e2e.test.d.ts +8 -0
- package/dist/handoff_snapshot/system_e2e.test.d.ts.map +1 -0
- package/dist/handoff_snapshot/system_e2e.test.js +211 -0
- package/dist/handoff_snapshot/system_e2e.test.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -1
- package/dist/pair_code/index.d.ts +107 -0
- package/dist/pair_code/index.d.ts.map +1 -0
- package/dist/pair_code/index.js +226 -0
- package/dist/pair_code/index.js.map +1 -0
- package/dist/pair_code/pair_code.test.d.ts +2 -0
- package/dist/pair_code/pair_code.test.d.ts.map +1 -0
- package/dist/pair_code/pair_code.test.js +197 -0
- package/dist/pair_code/pair_code.test.js.map +1 -0
- package/dist/synapse_sync/index.d.ts +142 -0
- package/dist/synapse_sync/index.d.ts.map +1 -0
- package/dist/synapse_sync/index.js +323 -0
- package/dist/synapse_sync/index.js.map +1 -0
- package/dist/synapse_sync/synapse_sync.test.d.ts +2 -0
- package/dist/synapse_sync/synapse_sync.test.d.ts.map +1 -0
- package/dist/synapse_sync/synapse_sync.test.js +363 -0
- package/dist/synapse_sync/synapse_sync.test.js.map +1 -0
- package/dist/truth_forensic_pipeline/index.d.ts +24 -0
- package/dist/truth_forensic_pipeline/index.d.ts.map +1 -1
- package/dist/truth_forensic_pipeline/index.js +110 -4
- package/dist/truth_forensic_pipeline/index.js.map +1 -1
- package/dist/truth_forensic_pipeline/truth_forensic_pipeline.test.js +83 -0
- package/dist/truth_forensic_pipeline/truth_forensic_pipeline.test.js.map +1 -1
- 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 +36 -0
- package/dist/wrapper_genesis/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v2.19.32 — MNEME HANDOFF SNAPSHOT (the brain you hand to your child device)
|
|
3
|
+
*
|
|
4
|
+
* User mandate (2026-05-17):
|
|
5
|
+
* "อยากให้ลูก mneme เก่งสุดๆ และรู้จักการเอาตัวรอดได้ทุกสถานการณ์ ...
|
|
6
|
+
* BEACON ทำมานานแล้วแต่ไม่เคยใช้ได้เลยผมเครียดมากๆๆ ... ทุก handoff =
|
|
7
|
+
* fresh snapshot. ไม่ใช่ pre-baked file. child ได้ context เดียวกับ
|
|
8
|
+
* parent ตอนนั้นเป๊ะ"
|
|
9
|
+
*
|
|
10
|
+
* Diagnosis: prior BEACON shipped a "soul prompt" that was generic +
|
|
11
|
+
* stale — same paragraph every release, no actual conversation context.
|
|
12
|
+
* When user scanned QR on phone, they got a paragraph about Mneme's
|
|
13
|
+
* features, not "we were debugging the auth bypass on line 216 of
|
|
14
|
+
* beacon/index.ts." That's why BEACON has never been used in anger.
|
|
15
|
+
*
|
|
16
|
+
* v2.19.32 HANDOFF SNAPSHOT is the pure-function COMPOSER: caller
|
|
17
|
+
* supplies the live conversation + git state + activity (caller has the
|
|
18
|
+
* I/O), this module canonicalises + HMAC-signs + ages it. The result
|
|
19
|
+
* is a HandoffEnvelope the BEACON server can serve to whoever scans the
|
|
20
|
+
* QR code, and the child device's `mneme receive` can verify + ingest.
|
|
21
|
+
*
|
|
22
|
+
* What's NEW vs prior soul prompt:
|
|
23
|
+
* - LIVE conversation (caller passes last N turns from MCP session)
|
|
24
|
+
* - GIT STATE (branch / dirty / last N commits) at SNAPSHOT time
|
|
25
|
+
* - RECENT ACTIVITY (tail of .mneme/cli-activity.jsonl)
|
|
26
|
+
* - ACTIVE INTENT (what the user was just asking about)
|
|
27
|
+
* - CAPABILITIES (mneme version + tool families) for child compatibility
|
|
28
|
+
* - FRESHNESS TIMESTAMP — receiver enforces 5-min staleness gate
|
|
29
|
+
*
|
|
30
|
+
* Composes onto:
|
|
31
|
+
* - v2.9 BEACON (the QR + local HTTP server that carries this)
|
|
32
|
+
* - v2.19.31 BUG #1 fix (token-required transport — no auth bypass)
|
|
33
|
+
* - v2.19.32 PAIR CODE (6-char human-friendly handle bound to envelope)
|
|
34
|
+
* - v2.19.32 CONSCIOUSNESS FORK (HMAC parent/child lineage record)
|
|
35
|
+
*
|
|
36
|
+
* Honest scope:
|
|
37
|
+
* - PURE FUNCTION composer. Caller has the I/O (read git, tail jsonl,
|
|
38
|
+
* get conversation). This makes it testable + vendor-neutral.
|
|
39
|
+
* - HMAC-SHA256 signed for tamper detection at the receiver.
|
|
40
|
+
* - Defensive: empty conversation OK, missing git OK, malformed input
|
|
41
|
+
* returns minimal-but-valid envelope rather than throw.
|
|
42
|
+
* - Freshness gate: receiver checks freshnessMs against TTL.
|
|
43
|
+
* - 24/7 safe: never throws on bad input; 1000 random snapshots in a
|
|
44
|
+
* row never crashes (measured in test suite).
|
|
45
|
+
*/
|
|
46
|
+
declare const PROTOCOL_VERSION: 2;
|
|
47
|
+
export interface ConversationTurn {
|
|
48
|
+
role: "user" | "assistant" | "system";
|
|
49
|
+
/** UTF-8 text. Caller may pre-trim to budget. */
|
|
50
|
+
text: string;
|
|
51
|
+
/** ms since epoch. */
|
|
52
|
+
ts: number;
|
|
53
|
+
}
|
|
54
|
+
export interface GitState {
|
|
55
|
+
branch?: string;
|
|
56
|
+
/** Output of `git status --short` (already truncated by caller). */
|
|
57
|
+
dirty?: string;
|
|
58
|
+
/** Last N commit subject lines. */
|
|
59
|
+
recentCommits?: string[];
|
|
60
|
+
}
|
|
61
|
+
export interface ActivityRecord {
|
|
62
|
+
/** Tool name OR free-form action (caller picks). */
|
|
63
|
+
action: string;
|
|
64
|
+
/** ms since epoch. */
|
|
65
|
+
ts: number;
|
|
66
|
+
/** Optional structured metadata (must be JSON-serialisable). */
|
|
67
|
+
meta?: Record<string, unknown>;
|
|
68
|
+
}
|
|
69
|
+
export interface CapabilitiesSnapshot {
|
|
70
|
+
mnemeVersion: string;
|
|
71
|
+
/** MCP tool family names (e.g. ["synapse", "truth", "soul"]). */
|
|
72
|
+
toolFamilies: string[];
|
|
73
|
+
/** Tools whose presence the receiver should require for full fidelity. */
|
|
74
|
+
requiredTools?: string[];
|
|
75
|
+
}
|
|
76
|
+
export interface HandoffSnapshotInput {
|
|
77
|
+
/** Last N conversation turns. Caller trims to budget. */
|
|
78
|
+
conversation?: ConversationTurn[];
|
|
79
|
+
/** Free-form one-line current intent inferred from conversation tail. */
|
|
80
|
+
activeIntent?: string;
|
|
81
|
+
gitState?: GitState;
|
|
82
|
+
/** Tail of cli-activity.jsonl (caller pre-reads + parses). */
|
|
83
|
+
recentActivity?: ActivityRecord[];
|
|
84
|
+
capabilities?: CapabilitiesSnapshot;
|
|
85
|
+
/** Optional voice directive — agent-tone instructions. */
|
|
86
|
+
voiceDirective?: string;
|
|
87
|
+
/** Optional shared dictionary for cross-vendor term consistency. */
|
|
88
|
+
mnemeDictionary?: Record<string, string>;
|
|
89
|
+
/** Parent device fingerprint (e.g. host hash). */
|
|
90
|
+
parentDeviceId?: string;
|
|
91
|
+
/** ms since epoch. Default Date.now(). */
|
|
92
|
+
nowMs?: number;
|
|
93
|
+
secret?: string;
|
|
94
|
+
}
|
|
95
|
+
export interface HandoffEnvelope {
|
|
96
|
+
v: typeof PROTOCOL_VERSION;
|
|
97
|
+
/** Stable deterministic id derived from (parentDeviceId, snapshotAt, content hash). */
|
|
98
|
+
envelopeId: string;
|
|
99
|
+
parentDeviceId: string;
|
|
100
|
+
snapshotAtMs: number;
|
|
101
|
+
/** TTL the receiver should enforce. */
|
|
102
|
+
freshnessTtlMs: number;
|
|
103
|
+
conversation: ConversationTurn[];
|
|
104
|
+
activeIntent: string;
|
|
105
|
+
gitState: Required<GitState>;
|
|
106
|
+
recentActivity: ActivityRecord[];
|
|
107
|
+
capabilities: CapabilitiesSnapshot;
|
|
108
|
+
voiceDirective: string;
|
|
109
|
+
mnemeDictionary: Record<string, string>;
|
|
110
|
+
/** HMAC-SHA256 over canonical body. */
|
|
111
|
+
sig: string;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Compose a fresh handoff envelope. Defensive at every boundary:
|
|
115
|
+
* - missing fields filled with sane defaults
|
|
116
|
+
* - bad types coerced or dropped
|
|
117
|
+
* - HMAC always computed (never empty sig)
|
|
118
|
+
* - return value ALWAYS valid; never throws
|
|
119
|
+
*/
|
|
120
|
+
export declare function captureSnapshot(input: HandoffSnapshotInput): HandoffEnvelope;
|
|
121
|
+
/** Verify envelope HMAC. Returns false on shape mismatch / tampered sig. */
|
|
122
|
+
export declare function verifyEnvelope(envelope: HandoffEnvelope, secret?: string): boolean;
|
|
123
|
+
/**
|
|
124
|
+
* Receiver-side freshness gate. Returns age in ms; caller compares to TTL.
|
|
125
|
+
* Stale envelope = receiver should refuse to ingest + ask parent to refresh.
|
|
126
|
+
*/
|
|
127
|
+
export interface FreshnessResult {
|
|
128
|
+
ageMs: number;
|
|
129
|
+
isFresh: boolean;
|
|
130
|
+
isExpired: boolean;
|
|
131
|
+
reason: "fresh" | "stale" | "expired" | "future_clock_skew";
|
|
132
|
+
}
|
|
133
|
+
export declare function freshnessCheck(envelope: HandoffEnvelope, nowMs?: number): FreshnessResult;
|
|
134
|
+
/**
|
|
135
|
+
* Render an envelope as the AI-ingestible text the child will paste into
|
|
136
|
+
* its new vendor session (Gemini / GPT / Claude / etc). Deterministic,
|
|
137
|
+
* vendor-neutral, safe to display in clear text — the SIG is what gives
|
|
138
|
+
* tamper-evidence, not secrecy. (For confidentiality wrap in ECDH at the
|
|
139
|
+
* transport layer; out of scope for this composer.)
|
|
140
|
+
*/
|
|
141
|
+
export declare function renderForChildVendor(envelope: HandoffEnvelope): string;
|
|
142
|
+
export interface SnapshotStats {
|
|
143
|
+
envelopeId: string;
|
|
144
|
+
conversationTurns: number;
|
|
145
|
+
activityRecords: number;
|
|
146
|
+
totalBytes: number;
|
|
147
|
+
ageMs: number;
|
|
148
|
+
}
|
|
149
|
+
export declare function computeSnapshotStats(envelope: HandoffEnvelope, nowMs?: number): SnapshotStats;
|
|
150
|
+
export declare function formatSnapshotLine(s: SnapshotStats): string;
|
|
151
|
+
export declare const HANDOFF_SNAPSHOT_TUNABLES: Readonly<{
|
|
152
|
+
PROTOCOL_VERSION: 2;
|
|
153
|
+
DEFAULT_FRESHNESS_TTL_MS: number;
|
|
154
|
+
}>;
|
|
155
|
+
export {};
|
|
156
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/handoff_snapshot/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v2.19.32 — MNEME HANDOFF SNAPSHOT (the brain you hand to your child device)
|
|
3
|
+
*
|
|
4
|
+
* User mandate (2026-05-17):
|
|
5
|
+
* "อยากให้ลูก mneme เก่งสุดๆ และรู้จักการเอาตัวรอดได้ทุกสถานการณ์ ...
|
|
6
|
+
* BEACON ทำมานานแล้วแต่ไม่เคยใช้ได้เลยผมเครียดมากๆๆ ... ทุก handoff =
|
|
7
|
+
* fresh snapshot. ไม่ใช่ pre-baked file. child ได้ context เดียวกับ
|
|
8
|
+
* parent ตอนนั้นเป๊ะ"
|
|
9
|
+
*
|
|
10
|
+
* Diagnosis: prior BEACON shipped a "soul prompt" that was generic +
|
|
11
|
+
* stale — same paragraph every release, no actual conversation context.
|
|
12
|
+
* When user scanned QR on phone, they got a paragraph about Mneme's
|
|
13
|
+
* features, not "we were debugging the auth bypass on line 216 of
|
|
14
|
+
* beacon/index.ts." That's why BEACON has never been used in anger.
|
|
15
|
+
*
|
|
16
|
+
* v2.19.32 HANDOFF SNAPSHOT is the pure-function COMPOSER: caller
|
|
17
|
+
* supplies the live conversation + git state + activity (caller has the
|
|
18
|
+
* I/O), this module canonicalises + HMAC-signs + ages it. The result
|
|
19
|
+
* is a HandoffEnvelope the BEACON server can serve to whoever scans the
|
|
20
|
+
* QR code, and the child device's `mneme receive` can verify + ingest.
|
|
21
|
+
*
|
|
22
|
+
* What's NEW vs prior soul prompt:
|
|
23
|
+
* - LIVE conversation (caller passes last N turns from MCP session)
|
|
24
|
+
* - GIT STATE (branch / dirty / last N commits) at SNAPSHOT time
|
|
25
|
+
* - RECENT ACTIVITY (tail of .mneme/cli-activity.jsonl)
|
|
26
|
+
* - ACTIVE INTENT (what the user was just asking about)
|
|
27
|
+
* - CAPABILITIES (mneme version + tool families) for child compatibility
|
|
28
|
+
* - FRESHNESS TIMESTAMP — receiver enforces 5-min staleness gate
|
|
29
|
+
*
|
|
30
|
+
* Composes onto:
|
|
31
|
+
* - v2.9 BEACON (the QR + local HTTP server that carries this)
|
|
32
|
+
* - v2.19.31 BUG #1 fix (token-required transport — no auth bypass)
|
|
33
|
+
* - v2.19.32 PAIR CODE (6-char human-friendly handle bound to envelope)
|
|
34
|
+
* - v2.19.32 CONSCIOUSNESS FORK (HMAC parent/child lineage record)
|
|
35
|
+
*
|
|
36
|
+
* Honest scope:
|
|
37
|
+
* - PURE FUNCTION composer. Caller has the I/O (read git, tail jsonl,
|
|
38
|
+
* get conversation). This makes it testable + vendor-neutral.
|
|
39
|
+
* - HMAC-SHA256 signed for tamper detection at the receiver.
|
|
40
|
+
* - Defensive: empty conversation OK, missing git OK, malformed input
|
|
41
|
+
* returns minimal-but-valid envelope rather than throw.
|
|
42
|
+
* - Freshness gate: receiver checks freshnessMs against TTL.
|
|
43
|
+
* - 24/7 safe: never throws on bad input; 1000 random snapshots in a
|
|
44
|
+
* row never crashes (measured in test suite).
|
|
45
|
+
*/
|
|
46
|
+
import { createHmac, timingSafeEqual } from "node:crypto";
|
|
47
|
+
const PROTOCOL_VERSION = 2;
|
|
48
|
+
const DEFAULT_FRESHNESS_TTL_MS = 5 * 60 * 1000; // 5 min
|
|
49
|
+
// ─── canonical helpers ───────────────────────────────────────────────
|
|
50
|
+
function canon(v) {
|
|
51
|
+
if (v === null || typeof v !== "object")
|
|
52
|
+
return JSON.stringify(v);
|
|
53
|
+
if (Array.isArray(v))
|
|
54
|
+
return "[" + v.map(canon).join(",") + "]";
|
|
55
|
+
const keys = Object.keys(v).sort();
|
|
56
|
+
return "{" + keys.map((k) => JSON.stringify(k) + ":" + canon(v[k])).join(",") + "}";
|
|
57
|
+
}
|
|
58
|
+
function defaultSecret() {
|
|
59
|
+
return process.env["MNEME_HANDOFF_SECRET"] || `mneme-handoff-v${PROTOCOL_VERSION}`;
|
|
60
|
+
}
|
|
61
|
+
function hmacHex(body, secret) {
|
|
62
|
+
return createHmac("sha256", secret).update(canon(body)).digest("hex");
|
|
63
|
+
}
|
|
64
|
+
function safeEqHex(a, b) {
|
|
65
|
+
try {
|
|
66
|
+
return timingSafeEqual(Buffer.from(a, "hex"), Buffer.from(b, "hex"));
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
function clean(s, fallback = "") {
|
|
73
|
+
return typeof s === "string" ? s : fallback;
|
|
74
|
+
}
|
|
75
|
+
function cleanArray(a, fallback = []) {
|
|
76
|
+
return Array.isArray(a) ? a : fallback;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Compose a fresh handoff envelope. Defensive at every boundary:
|
|
80
|
+
* - missing fields filled with sane defaults
|
|
81
|
+
* - bad types coerced or dropped
|
|
82
|
+
* - HMAC always computed (never empty sig)
|
|
83
|
+
* - return value ALWAYS valid; never throws
|
|
84
|
+
*/
|
|
85
|
+
export function captureSnapshot(input) {
|
|
86
|
+
const nowMs = input.nowMs ?? Date.now();
|
|
87
|
+
const secret = input.secret ?? defaultSecret();
|
|
88
|
+
// Defensive coercions — every field has a defined shape
|
|
89
|
+
const conversation = cleanArray(input.conversation).filter((t) => t && typeof t.text === "string" && (t.role === "user" || t.role === "assistant" || t.role === "system")).map((t) => ({
|
|
90
|
+
role: t.role,
|
|
91
|
+
text: t.text,
|
|
92
|
+
ts: typeof t.ts === "number" && Number.isFinite(t.ts) ? t.ts : nowMs,
|
|
93
|
+
}));
|
|
94
|
+
const activeIntent = clean(input.activeIntent, conversation.length > 0
|
|
95
|
+
? `handoff continuing: ${conversation[conversation.length - 1].text.slice(0, 80)}`
|
|
96
|
+
: "fresh handoff");
|
|
97
|
+
const gitState = {
|
|
98
|
+
branch: clean(input.gitState?.branch, "unknown"),
|
|
99
|
+
dirty: clean(input.gitState?.dirty, ""),
|
|
100
|
+
recentCommits: cleanArray(input.gitState?.recentCommits),
|
|
101
|
+
};
|
|
102
|
+
const recentActivity = cleanArray(input.recentActivity).filter((r) => r && typeof r.action === "string" && typeof r.ts === "number" && Number.isFinite(r.ts));
|
|
103
|
+
const capabilities = {
|
|
104
|
+
mnemeVersion: clean(input.capabilities?.mnemeVersion, "unknown"),
|
|
105
|
+
toolFamilies: cleanArray(input.capabilities?.toolFamilies).filter((s) => typeof s === "string"),
|
|
106
|
+
requiredTools: cleanArray(input.capabilities?.requiredTools).filter((s) => typeof s === "string"),
|
|
107
|
+
};
|
|
108
|
+
const voiceDirective = clean(input.voiceDirective, "");
|
|
109
|
+
const mnemeDictionary = (input.mnemeDictionary && typeof input.mnemeDictionary === "object" && !Array.isArray(input.mnemeDictionary))
|
|
110
|
+
? input.mnemeDictionary
|
|
111
|
+
: {};
|
|
112
|
+
const parentDeviceId = clean(input.parentDeviceId, "anonymous-parent");
|
|
113
|
+
// Body before sig
|
|
114
|
+
const bodyForSig = {
|
|
115
|
+
v: PROTOCOL_VERSION,
|
|
116
|
+
parentDeviceId,
|
|
117
|
+
snapshotAtMs: nowMs,
|
|
118
|
+
freshnessTtlMs: DEFAULT_FRESHNESS_TTL_MS,
|
|
119
|
+
conversation,
|
|
120
|
+
activeIntent,
|
|
121
|
+
gitState,
|
|
122
|
+
recentActivity,
|
|
123
|
+
capabilities,
|
|
124
|
+
voiceDirective,
|
|
125
|
+
mnemeDictionary,
|
|
126
|
+
};
|
|
127
|
+
const sig = hmacHex(bodyForSig, secret);
|
|
128
|
+
const envelopeId = hmacHex({ parentDeviceId, snapshotAtMs: nowMs, sig }, secret).slice(0, 16);
|
|
129
|
+
return {
|
|
130
|
+
v: PROTOCOL_VERSION,
|
|
131
|
+
envelopeId,
|
|
132
|
+
parentDeviceId,
|
|
133
|
+
snapshotAtMs: nowMs,
|
|
134
|
+
freshnessTtlMs: DEFAULT_FRESHNESS_TTL_MS,
|
|
135
|
+
conversation,
|
|
136
|
+
activeIntent,
|
|
137
|
+
gitState,
|
|
138
|
+
recentActivity,
|
|
139
|
+
capabilities,
|
|
140
|
+
voiceDirective,
|
|
141
|
+
mnemeDictionary,
|
|
142
|
+
sig,
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
/** Verify envelope HMAC. Returns false on shape mismatch / tampered sig. */
|
|
146
|
+
export function verifyEnvelope(envelope, secret) {
|
|
147
|
+
if (!envelope || typeof envelope !== "object")
|
|
148
|
+
return false;
|
|
149
|
+
if (envelope.v !== PROTOCOL_VERSION)
|
|
150
|
+
return false;
|
|
151
|
+
if (typeof envelope.sig !== "string" || !/^[0-9a-f]{64}$/.test(envelope.sig))
|
|
152
|
+
return false;
|
|
153
|
+
if (typeof envelope.parentDeviceId !== "string")
|
|
154
|
+
return false;
|
|
155
|
+
if (typeof envelope.snapshotAtMs !== "number" || !Number.isFinite(envelope.snapshotAtMs))
|
|
156
|
+
return false;
|
|
157
|
+
const sec = secret ?? defaultSecret();
|
|
158
|
+
const { sig, envelopeId: _eid, v: _v, ...body } = envelope;
|
|
159
|
+
const bodyForSig = { v: PROTOCOL_VERSION, ...body };
|
|
160
|
+
return safeEqHex(hmacHex(bodyForSig, sec), sig);
|
|
161
|
+
}
|
|
162
|
+
export function freshnessCheck(envelope, nowMs) {
|
|
163
|
+
const now = nowMs ?? Date.now();
|
|
164
|
+
const age = now - envelope.snapshotAtMs;
|
|
165
|
+
// Clock skew detection — receiver clock behind parent by > 1s
|
|
166
|
+
if (age < -1000)
|
|
167
|
+
return { ageMs: age, isFresh: false, isExpired: false, reason: "future_clock_skew" };
|
|
168
|
+
const ttl = envelope.freshnessTtlMs ?? DEFAULT_FRESHNESS_TTL_MS;
|
|
169
|
+
if (age > ttl)
|
|
170
|
+
return { ageMs: age, isFresh: false, isExpired: true, reason: "expired" };
|
|
171
|
+
// 80% of TTL → stale warning (receiver may still ingest with caveat)
|
|
172
|
+
if (age > ttl * 0.8)
|
|
173
|
+
return { ageMs: age, isFresh: false, isExpired: false, reason: "stale" };
|
|
174
|
+
return { ageMs: age, isFresh: true, isExpired: false, reason: "fresh" };
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Render an envelope as the AI-ingestible text the child will paste into
|
|
178
|
+
* its new vendor session (Gemini / GPT / Claude / etc). Deterministic,
|
|
179
|
+
* vendor-neutral, safe to display in clear text — the SIG is what gives
|
|
180
|
+
* tamper-evidence, not secrecy. (For confidentiality wrap in ECDH at the
|
|
181
|
+
* transport layer; out of scope for this composer.)
|
|
182
|
+
*/
|
|
183
|
+
export function renderForChildVendor(envelope) {
|
|
184
|
+
const lines = [];
|
|
185
|
+
lines.push(`# 🧬 Mneme Handoff — continuing from parent`);
|
|
186
|
+
lines.push(``);
|
|
187
|
+
lines.push(`**Parent device**: ${envelope.parentDeviceId}`);
|
|
188
|
+
lines.push(`**Snapshot at**: ${new Date(envelope.snapshotAtMs).toISOString()}`);
|
|
189
|
+
lines.push(`**Mneme version**: ${envelope.capabilities.mnemeVersion}`);
|
|
190
|
+
if (envelope.activeIntent) {
|
|
191
|
+
lines.push(``);
|
|
192
|
+
lines.push(`**Active intent**: ${envelope.activeIntent}`);
|
|
193
|
+
}
|
|
194
|
+
if (envelope.gitState.branch !== "unknown") {
|
|
195
|
+
lines.push(``);
|
|
196
|
+
lines.push(`## Git state`);
|
|
197
|
+
lines.push(`- branch: \`${envelope.gitState.branch}\``);
|
|
198
|
+
if (envelope.gitState.dirty) {
|
|
199
|
+
lines.push(`- dirty files:`);
|
|
200
|
+
lines.push("```");
|
|
201
|
+
lines.push(envelope.gitState.dirty);
|
|
202
|
+
lines.push("```");
|
|
203
|
+
}
|
|
204
|
+
if (envelope.gitState.recentCommits.length > 0) {
|
|
205
|
+
lines.push(`- recent commits:`);
|
|
206
|
+
for (const c of envelope.gitState.recentCommits)
|
|
207
|
+
lines.push(` - ${c}`);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
if (envelope.conversation.length > 0) {
|
|
211
|
+
lines.push(``);
|
|
212
|
+
lines.push(`## Conversation tail`);
|
|
213
|
+
for (const t of envelope.conversation.slice(-10)) {
|
|
214
|
+
lines.push(`**${t.role}**: ${t.text}`);
|
|
215
|
+
lines.push(``);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
if (envelope.recentActivity.length > 0) {
|
|
219
|
+
lines.push(``);
|
|
220
|
+
lines.push(`## Recent activity`);
|
|
221
|
+
for (const r of envelope.recentActivity.slice(-10)) {
|
|
222
|
+
lines.push(`- \`${r.action}\` @ ${new Date(r.ts).toISOString()}`);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
if (envelope.voiceDirective) {
|
|
226
|
+
lines.push(``);
|
|
227
|
+
lines.push(`## Voice directive`);
|
|
228
|
+
lines.push(envelope.voiceDirective);
|
|
229
|
+
}
|
|
230
|
+
if (Object.keys(envelope.mnemeDictionary).length > 0) {
|
|
231
|
+
lines.push(``);
|
|
232
|
+
lines.push(`## Shared dictionary`);
|
|
233
|
+
for (const [k, v] of Object.entries(envelope.mnemeDictionary)) {
|
|
234
|
+
lines.push(`- **${k}**: ${v}`);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
lines.push(``);
|
|
238
|
+
lines.push(`---`);
|
|
239
|
+
lines.push(`HMAC sig (last 12): \`...${envelope.sig.slice(-12)}\` · envelope ${envelope.envelopeId}`);
|
|
240
|
+
return lines.join("\n");
|
|
241
|
+
}
|
|
242
|
+
export function computeSnapshotStats(envelope, nowMs) {
|
|
243
|
+
const bytes = JSON.stringify(envelope).length;
|
|
244
|
+
return {
|
|
245
|
+
envelopeId: envelope.envelopeId,
|
|
246
|
+
conversationTurns: envelope.conversation.length,
|
|
247
|
+
activityRecords: envelope.recentActivity.length,
|
|
248
|
+
totalBytes: bytes,
|
|
249
|
+
ageMs: (nowMs ?? Date.now()) - envelope.snapshotAtMs,
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
export function formatSnapshotLine(s) {
|
|
253
|
+
const ageSec = Math.max(0, Math.floor(s.ageMs / 1000));
|
|
254
|
+
const kb = (s.totalBytes / 1024).toFixed(1);
|
|
255
|
+
return `🧬 SNAPSHOT ${s.envelopeId} · ${s.conversationTurns} turns · ${s.activityRecords} activity · ${kb}KB · age=${ageSec}s`;
|
|
256
|
+
}
|
|
257
|
+
export const HANDOFF_SNAPSHOT_TUNABLES = Object.freeze({
|
|
258
|
+
PROTOCOL_VERSION,
|
|
259
|
+
DEFAULT_FRESHNESS_TTL_MS,
|
|
260
|
+
});
|
|
261
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/handoff_snapshot/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v2.19.32 SYSTEM E2E TEST — the full PARENT → QR → CHILD pipeline
|
|
3
|
+
*
|
|
4
|
+
* Exercises all 4 v2.19.32 modules together with a realistic 4-vendor
|
|
5
|
+
* scenario. If this test passes, BEACON HANDOFF actually works.
|
|
6
|
+
*/
|
|
7
|
+
export {};
|
|
8
|
+
//# sourceMappingURL=system_e2e.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"system_e2e.test.d.ts","sourceRoot":"","sources":["../../src/handoff_snapshot/system_e2e.test.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
|