@mneme-ai/core 2.52.0 → 2.54.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 +23 -0
- package/dist/agent_manifest.js.map +1 -1
- package/dist/catalog_count.d.ts +47 -0
- package/dist/catalog_count.d.ts.map +1 -0
- package/dist/catalog_count.js +76 -0
- package/dist/catalog_count.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/indispensability.d.ts +31 -0
- package/dist/indispensability.d.ts.map +1 -0
- package/dist/indispensability.js +182 -0
- package/dist/indispensability.js.map +1 -0
- package/dist/nemesis/corpus_augmenter.d.ts +69 -0
- package/dist/nemesis/corpus_augmenter.d.ts.map +1 -0
- package/dist/nemesis/corpus_augmenter.js +164 -0
- package/dist/nemesis/corpus_augmenter.js.map +1 -0
- package/dist/nemesis/eu_ai_act_stamp.d.ts.map +1 -1
- package/dist/nemesis/eu_ai_act_stamp.js +14 -0
- package/dist/nemesis/eu_ai_act_stamp.js.map +1 -1
- package/dist/nemesis/gavel.d.ts +102 -0
- package/dist/nemesis/gavel.d.ts.map +1 -0
- package/dist/nemesis/gavel.js +192 -0
- package/dist/nemesis/gavel.js.map +1 -0
- package/dist/nemesis/index.d.ts +6 -0
- package/dist/nemesis/index.d.ts.map +1 -1
- package/dist/nemesis/index.js +14 -0
- package/dist/nemesis/index.js.map +1 -1
- package/dist/nemesis/janus.d.ts +93 -0
- package/dist/nemesis/janus.d.ts.map +1 -0
- package/dist/nemesis/janus.js +160 -0
- package/dist/nemesis/janus.js.map +1 -0
- package/dist/nemesis/key_setup.d.ts +65 -0
- package/dist/nemesis/key_setup.d.ts.map +1 -0
- package/dist/nemesis/key_setup.js +173 -0
- package/dist/nemesis/key_setup.js.map +1 -0
- package/dist/nemesis/lethe.d.ts +112 -0
- package/dist/nemesis/lethe.d.ts.map +1 -0
- package/dist/nemesis/lethe.js +211 -0
- package/dist/nemesis/lethe.js.map +1 -0
- package/dist/nemesis/nimbus.d.ts +117 -0
- package/dist/nemesis/nimbus.d.ts.map +1 -0
- package/dist/nemesis/nimbus.js +208 -0
- package/dist/nemesis/nimbus.js.map +1 -0
- package/dist/perf_budget.d.ts +48 -0
- package/dist/perf_budget.d.ts.map +1 -0
- package/dist/perf_budget.js +111 -0
- package/dist/perf_budget.js.map +1 -0
- package/dist/release_gate/probe_coverage.d.ts +16 -1
- package/dist/release_gate/probe_coverage.d.ts.map +1 -1
- package/dist/release_gate/probe_coverage.js +13 -4
- package/dist/release_gate/probe_coverage.js.map +1 -1
- package/dist/release_gate/wiring_lag.d.ts +65 -0
- package/dist/release_gate/wiring_lag.d.ts.map +1 -0
- package/dist/release_gate/wiring_lag.js +116 -0
- package/dist/release_gate/wiring_lag.js.map +1 -0
- package/dist/strategy.d.ts +43 -0
- package/dist/strategy.d.ts.map +1 -0
- package/dist/strategy.js +117 -0
- package/dist/strategy.js.map +1 -0
- package/dist/truth_gate/claims.d.ts.map +1 -1
- package/dist/truth_gate/claims.js +41 -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 +248 -0
- package/dist/truth_gate/probes.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v2.54.0 — LETHE: GDPR forget primitive (Merkle exclusion proof).
|
|
3
|
+
*
|
|
4
|
+
* Greek mythology: river in Hades that erases memory.
|
|
5
|
+
*
|
|
6
|
+
* Problem: EU GDPR Art 17 (right to erasure) + AI-specific provisions
|
|
7
|
+
* require that personal data — including fingerprint-style behavioural
|
|
8
|
+
* markers — be REMOVABLE on request. But Mneme's HMAC chains are
|
|
9
|
+
* tamper-evident by design: removing rows breaks the chain.
|
|
10
|
+
*
|
|
11
|
+
* Solution (cryptographically rigorous, not just "delete"):
|
|
12
|
+
* 1. Build a Merkle tree over the chain rows.
|
|
13
|
+
* 2. To "forget" row R, REPLACE the row's leaf with `H("forgotten:" || nonce)`
|
|
14
|
+
* where nonce is fresh per request.
|
|
15
|
+
* 3. Recompute the Merkle root from the modified leaves.
|
|
16
|
+
* 4. Issue a FORGET RECEIPT: signed proof tree showing
|
|
17
|
+
* (a) the row WAS in the chain (by original leaf hash, kept ONLY as
|
|
18
|
+
* the path to the root — never the content)
|
|
19
|
+
* (b) the row is NOW erased (replacement leaf)
|
|
20
|
+
* (c) the new Merkle root that subsequent verifiers can use
|
|
21
|
+
* (d) timestamp + GDPR jurisdiction tag
|
|
22
|
+
*
|
|
23
|
+
* Verifiers downstream:
|
|
24
|
+
* - Future readers see the new root + the FORGET ENVELOPE; they cannot
|
|
25
|
+
* recover the original content (it was the only place stored).
|
|
26
|
+
* - The exclusion proof is a few hundred bytes regardless of chain size.
|
|
27
|
+
*
|
|
28
|
+
* Composes: createHash + the existing HMAC-chained ledger pattern.
|
|
29
|
+
* Pure deterministic + defensive; never throws.
|
|
30
|
+
*/
|
|
31
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync, appendFileSync, copyFileSync } from "node:fs";
|
|
32
|
+
import { join } from "node:path";
|
|
33
|
+
import { createHash, createHmac, randomBytes } from "node:crypto";
|
|
34
|
+
const LETHE_DIR = ".mneme/nemesis/lethe";
|
|
35
|
+
const FORGET_LEDGER = "forget_receipts.jsonl";
|
|
36
|
+
const KEY_ENV = "MNEME_LETHE_KEY";
|
|
37
|
+
const DEFAULT_KEY = "mneme-lethe-v1";
|
|
38
|
+
function keyOf() {
|
|
39
|
+
return process.env[KEY_ENV] ?? DEFAULT_KEY;
|
|
40
|
+
}
|
|
41
|
+
function leafOf(content) {
|
|
42
|
+
return createHash("sha256").update("leaf:").update(content).digest("hex");
|
|
43
|
+
}
|
|
44
|
+
function parentOf(left, right) {
|
|
45
|
+
return createHash("sha256").update("parent:").update(left).update(":").update(right).digest("hex");
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Build a Merkle tree from a list of row contents. Odd-count layers
|
|
49
|
+
* duplicate the last element (standard Bitcoin-style construction).
|
|
50
|
+
*/
|
|
51
|
+
export function buildMerkleTree(rows) {
|
|
52
|
+
if (!Array.isArray(rows) || rows.length === 0) {
|
|
53
|
+
const empty = createHash("sha256").update("empty").digest("hex");
|
|
54
|
+
return { root: empty, leaves: [], count: 0 };
|
|
55
|
+
}
|
|
56
|
+
const leaves = rows.map(leafOf);
|
|
57
|
+
let level = [...leaves];
|
|
58
|
+
while (level.length > 1) {
|
|
59
|
+
const next = [];
|
|
60
|
+
for (let i = 0; i < level.length; i += 2) {
|
|
61
|
+
const a = level[i];
|
|
62
|
+
const b = i + 1 < level.length ? level[i + 1] : level[i];
|
|
63
|
+
next.push(parentOf(a, b));
|
|
64
|
+
}
|
|
65
|
+
level = next;
|
|
66
|
+
}
|
|
67
|
+
return { root: level[0], leaves, count: rows.length };
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Build an inclusion proof for the leaf at `index`.
|
|
71
|
+
* Returns the sibling path from the leaf up to (but not including) the root.
|
|
72
|
+
*/
|
|
73
|
+
export function buildInclusionProof(rows, index) {
|
|
74
|
+
if (!Array.isArray(rows) || index < 0 || index >= rows.length)
|
|
75
|
+
return null;
|
|
76
|
+
const leaves = rows.map(leafOf);
|
|
77
|
+
const leafHash = leaves[index];
|
|
78
|
+
let level = [...leaves];
|
|
79
|
+
let pos = index;
|
|
80
|
+
const proof = [];
|
|
81
|
+
while (level.length > 1) {
|
|
82
|
+
const isLeft = pos % 2 === 0;
|
|
83
|
+
const siblingIdx = isLeft ? pos + 1 : pos - 1;
|
|
84
|
+
const sibling = level[siblingIdx] ?? level[pos];
|
|
85
|
+
proof.push({ sibling, position: isLeft ? "left" : "right" });
|
|
86
|
+
const next = [];
|
|
87
|
+
for (let i = 0; i < level.length; i += 2) {
|
|
88
|
+
const a = level[i];
|
|
89
|
+
const b = i + 1 < level.length ? level[i + 1] : level[i];
|
|
90
|
+
next.push(parentOf(a, b));
|
|
91
|
+
}
|
|
92
|
+
level = next;
|
|
93
|
+
pos = Math.floor(pos / 2);
|
|
94
|
+
}
|
|
95
|
+
return { proof, root: level[0], leafHash };
|
|
96
|
+
}
|
|
97
|
+
/** Verify an inclusion proof. Pure. */
|
|
98
|
+
export function verifyInclusionProof(leafHash, proof, expectedRoot) {
|
|
99
|
+
if (typeof leafHash !== "string" || !Array.isArray(proof))
|
|
100
|
+
return false;
|
|
101
|
+
let cur = leafHash;
|
|
102
|
+
for (const step of proof) {
|
|
103
|
+
if (step.position === "left")
|
|
104
|
+
cur = parentOf(cur, step.sibling);
|
|
105
|
+
else
|
|
106
|
+
cur = parentOf(step.sibling, cur);
|
|
107
|
+
}
|
|
108
|
+
return cur === expectedRoot;
|
|
109
|
+
}
|
|
110
|
+
function hmacOf(body) {
|
|
111
|
+
return createHmac("sha256", keyOf()).update(JSON.stringify(body)).digest("hex");
|
|
112
|
+
}
|
|
113
|
+
function forgetLeaf(nonce) {
|
|
114
|
+
return createHash("sha256").update("forgotten:").update(nonce).digest("hex");
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Read a JSONL ledger + perform GDPR forget on a specific row. Pure
|
|
118
|
+
* cryptographic operation; ledger rewrite + backup are best-effort.
|
|
119
|
+
*/
|
|
120
|
+
export function forgetRow(input) {
|
|
121
|
+
try {
|
|
122
|
+
const p = join(input.repoRoot, input.ledgerRelative);
|
|
123
|
+
if (!existsSync(p))
|
|
124
|
+
return { ok: false, reason: `ledger not found: ${p}` };
|
|
125
|
+
const rows = readFileSync(p, "utf8").split("\n").filter((l) => l.trim());
|
|
126
|
+
if (input.rowIndex < 0 || input.rowIndex >= rows.length) {
|
|
127
|
+
return { ok: false, reason: `row ${input.rowIndex} out of range (ledger has ${rows.length} rows)` };
|
|
128
|
+
}
|
|
129
|
+
const originalTree = buildMerkleTree(rows);
|
|
130
|
+
const inclusion = buildInclusionProof(rows, input.rowIndex);
|
|
131
|
+
if (!inclusion)
|
|
132
|
+
return { ok: false, reason: "failed to build inclusion proof" };
|
|
133
|
+
const nonce = randomBytes(16).toString("hex");
|
|
134
|
+
const replacementHash = forgetLeaf(nonce);
|
|
135
|
+
const newRows = [...rows];
|
|
136
|
+
// Replace with a sentinel that's parseable + non-PII
|
|
137
|
+
const sentinel = JSON.stringify({ at: new Date().toISOString(), forgotten: true, leafHash: replacementHash, jurisdiction: input.jurisdiction ?? "EU-GDPR-Art17" });
|
|
138
|
+
newRows[input.rowIndex] = sentinel;
|
|
139
|
+
const newTree = buildMerkleTree(newRows);
|
|
140
|
+
const bodyForHmac = {
|
|
141
|
+
at: new Date().toISOString(),
|
|
142
|
+
jurisdiction: input.jurisdiction ?? "EU-GDPR-Art17",
|
|
143
|
+
ledger: input.ledgerRelative,
|
|
144
|
+
forgottenIndex: input.rowIndex,
|
|
145
|
+
originalLeafHash: inclusion.leafHash,
|
|
146
|
+
replacementLeafHash: replacementHash,
|
|
147
|
+
inclusionProof: inclusion.proof,
|
|
148
|
+
originalRoot: originalTree.root,
|
|
149
|
+
newRoot: newTree.root,
|
|
150
|
+
};
|
|
151
|
+
const receipt = { ...bodyForHmac, hmac: hmacOf(bodyForHmac) };
|
|
152
|
+
if (input.dryRun) {
|
|
153
|
+
return { ok: true, receipt, reason: "dry-run: receipt built, ledger untouched" };
|
|
154
|
+
}
|
|
155
|
+
// Backup + rewrite
|
|
156
|
+
const backupPath = p + ".pre-lethe.bak";
|
|
157
|
+
try {
|
|
158
|
+
copyFileSync(p, backupPath);
|
|
159
|
+
}
|
|
160
|
+
catch { /* */ }
|
|
161
|
+
try {
|
|
162
|
+
writeFileSync(p, newRows.join("\n") + "\n");
|
|
163
|
+
}
|
|
164
|
+
catch (e) {
|
|
165
|
+
return { ok: false, reason: `ledger rewrite failed: ${e.message}` };
|
|
166
|
+
}
|
|
167
|
+
// Append receipt to forget ledger
|
|
168
|
+
try {
|
|
169
|
+
const dir = join(input.repoRoot, LETHE_DIR);
|
|
170
|
+
if (!existsSync(dir))
|
|
171
|
+
mkdirSync(dir, { recursive: true });
|
|
172
|
+
appendFileSync(join(dir, FORGET_LEDGER), JSON.stringify(receipt) + "\n");
|
|
173
|
+
}
|
|
174
|
+
catch { /* */ }
|
|
175
|
+
return { ok: true, receipt, newLedgerPath: p, backupPath, reason: `row ${input.rowIndex} forgotten; old root ${originalTree.root.slice(0, 8)}… → new root ${newTree.root.slice(0, 8)}…` };
|
|
176
|
+
}
|
|
177
|
+
catch (e) {
|
|
178
|
+
return { ok: false, reason: `forget failed: ${e.message}` };
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
/** Verify a forget receipt cryptographically — does the inclusion proof
|
|
182
|
+
* reconstruct the original root + does the HMAC match? Pure. */
|
|
183
|
+
export function verifyForgetReceipt(receipt) {
|
|
184
|
+
if (!receipt || typeof receipt.hmac !== "string")
|
|
185
|
+
return { ok: false, reason: "missing hmac" };
|
|
186
|
+
const { hmac, ...body } = receipt;
|
|
187
|
+
const expectedHmac = hmacOf(body);
|
|
188
|
+
if (expectedHmac !== hmac)
|
|
189
|
+
return { ok: false, reason: "hmac mismatch" };
|
|
190
|
+
const recoveredRoot = verifyInclusionProof(receipt.originalLeafHash, receipt.inclusionProof, receipt.originalRoot);
|
|
191
|
+
if (!recoveredRoot)
|
|
192
|
+
return { ok: false, reason: "inclusion proof does not reconstruct original root" };
|
|
193
|
+
return { ok: true, reason: "receipt verified — row was in chain + has been forgotten + new root computed correctly" };
|
|
194
|
+
}
|
|
195
|
+
/** List all forget receipts in this repo. */
|
|
196
|
+
export function listForgetReceipts(repoRoot) {
|
|
197
|
+
const p = join(repoRoot, LETHE_DIR, FORGET_LEDGER);
|
|
198
|
+
if (!existsSync(p))
|
|
199
|
+
return [];
|
|
200
|
+
const out = [];
|
|
201
|
+
for (const line of readFileSync(p, "utf8").split("\n")) {
|
|
202
|
+
if (!line.trim())
|
|
203
|
+
continue;
|
|
204
|
+
try {
|
|
205
|
+
out.push(JSON.parse(line));
|
|
206
|
+
}
|
|
207
|
+
catch { /* skip */ }
|
|
208
|
+
}
|
|
209
|
+
return out;
|
|
210
|
+
}
|
|
211
|
+
//# sourceMappingURL=lethe.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lethe.js","sourceRoot":"","sources":["../../src/nemesis/lethe.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v2.54.0 — NIMBUS: federated trust mesh primitive.
|
|
3
|
+
*
|
|
4
|
+
* Latin: cloud / aura. Per-org leaderboards + cross-org reputation
|
|
5
|
+
* transfer, gated by CONSENT FABRIC.
|
|
6
|
+
*
|
|
7
|
+
* Design (network-effects-first):
|
|
8
|
+
* Each Mneme installation can publish a signed LEADERBOARD CARD
|
|
9
|
+
* summarising the org's TRUSTed primitives:
|
|
10
|
+
* - COLOSSEUM top-5 vendors + ELO scores
|
|
11
|
+
* - HONEST MIRROR per-vendor false-rate windowed lower bound
|
|
12
|
+
* - NEMESIS dispute count
|
|
13
|
+
* - Org-level consent + scope (which artifacts shareable)
|
|
14
|
+
*
|
|
15
|
+
* Consumers subscribe to other orgs' cards + compute weighted
|
|
16
|
+
* cross-org reputation. The trust mesh is a federation, not a
|
|
17
|
+
* central server.
|
|
18
|
+
*
|
|
19
|
+
* v2.54 ships the LOCAL pub/sub primitive (no network). Network
|
|
20
|
+
* transport is a future extension via the existing bridge.
|
|
21
|
+
*
|
|
22
|
+
* Privacy: only AGGREGATED scores cross the boundary. Per-commit
|
|
23
|
+
* fingerprints + raw activity never leave the org.
|
|
24
|
+
*
|
|
25
|
+
* Composes: createHmac + the existing leaderboard / mirror primitives.
|
|
26
|
+
* Pure deterministic + defensive; never throws.
|
|
27
|
+
*/
|
|
28
|
+
export interface NimbusVendorEntry {
|
|
29
|
+
vendor: string;
|
|
30
|
+
elo?: number;
|
|
31
|
+
falseRateLB?: number;
|
|
32
|
+
/** Sample size — readers can weight by N. */
|
|
33
|
+
n?: number;
|
|
34
|
+
}
|
|
35
|
+
export interface NimbusCard {
|
|
36
|
+
/** Anonymized org identifier (HMAC of git-remote or user-set tag). */
|
|
37
|
+
orgFingerprint: string;
|
|
38
|
+
at: string;
|
|
39
|
+
/** Top vendors by ELO (from COLOSSEUM). */
|
|
40
|
+
topByElo: NimbusVendorEntry[];
|
|
41
|
+
/** Vendors by lowest false-rate LB (from HONEST MIRROR / BOUNTY). */
|
|
42
|
+
topByHonesty: NimbusVendorEntry[];
|
|
43
|
+
/** Consent fields — what may consumers do with this card. */
|
|
44
|
+
consent: {
|
|
45
|
+
sharedScopes: string[];
|
|
46
|
+
expiresAt: string;
|
|
47
|
+
/** Revocation URI (if any). */
|
|
48
|
+
revocationRef?: string;
|
|
49
|
+
};
|
|
50
|
+
/** Optional sticky note for human readers. */
|
|
51
|
+
note?: string;
|
|
52
|
+
/** Card-level HMAC. */
|
|
53
|
+
hmac: string;
|
|
54
|
+
}
|
|
55
|
+
export interface PublishInput {
|
|
56
|
+
repoRoot: string;
|
|
57
|
+
orgTag: string;
|
|
58
|
+
topByElo?: NimbusVendorEntry[];
|
|
59
|
+
topByHonesty?: NimbusVendorEntry[];
|
|
60
|
+
sharedScopes?: string[];
|
|
61
|
+
expiresAtIso?: string;
|
|
62
|
+
revocationRef?: string;
|
|
63
|
+
note?: string;
|
|
64
|
+
persist?: boolean;
|
|
65
|
+
}
|
|
66
|
+
export interface PublishResult {
|
|
67
|
+
ok: boolean;
|
|
68
|
+
card?: NimbusCard;
|
|
69
|
+
path?: string;
|
|
70
|
+
reason: string;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Publish a NIMBUS card to the local pub-store. Pure: card is just a
|
|
74
|
+
* signed JSON envelope; transport to other orgs is the caller's job
|
|
75
|
+
* (HTTP / git / file copy / etc).
|
|
76
|
+
*/
|
|
77
|
+
export declare function publishCard(input: PublishInput): PublishResult;
|
|
78
|
+
/** Verify a NIMBUS card's HMAC + expiry. Pure. */
|
|
79
|
+
export declare function verifyCard(card: NimbusCard): {
|
|
80
|
+
ok: boolean;
|
|
81
|
+
expired: boolean;
|
|
82
|
+
reason: string;
|
|
83
|
+
};
|
|
84
|
+
export interface SubscriptionEntry {
|
|
85
|
+
at: string;
|
|
86
|
+
orgFingerprint: string;
|
|
87
|
+
card: NimbusCard;
|
|
88
|
+
/** Caller's local trust weight for this org (0..1). */
|
|
89
|
+
trustWeight: number;
|
|
90
|
+
}
|
|
91
|
+
export interface SubscribeInput {
|
|
92
|
+
repoRoot: string;
|
|
93
|
+
card: NimbusCard;
|
|
94
|
+
trustWeight?: number;
|
|
95
|
+
persist?: boolean;
|
|
96
|
+
}
|
|
97
|
+
export declare function subscribeCard(input: SubscribeInput): {
|
|
98
|
+
ok: boolean;
|
|
99
|
+
entry?: SubscriptionEntry;
|
|
100
|
+
reason: string;
|
|
101
|
+
};
|
|
102
|
+
/**
|
|
103
|
+
* Compute cross-org weighted reputation: per vendor, weighted average
|
|
104
|
+
* of (ELO + 1/(1+falseRateLB)) across all subscribed cards.
|
|
105
|
+
* Returns a ranked list with confidence.
|
|
106
|
+
*/
|
|
107
|
+
export interface CrossOrgReputation {
|
|
108
|
+
vendor: string;
|
|
109
|
+
weightedScore: number;
|
|
110
|
+
contributingOrgs: number;
|
|
111
|
+
/** Sum of trustWeights — proxy for confidence. */
|
|
112
|
+
totalWeight: number;
|
|
113
|
+
}
|
|
114
|
+
export declare function computeCrossOrgReputation(repoRoot: string): CrossOrgReputation[];
|
|
115
|
+
export declare function listPublished(repoRoot: string): NimbusCard[];
|
|
116
|
+
export declare function listSubscriptions(repoRoot: string): SubscriptionEntry[];
|
|
117
|
+
//# sourceMappingURL=nimbus.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nimbus.d.ts","sourceRoot":"","sources":["../../src/nemesis/nimbus.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v2.54.0 — NIMBUS: federated trust mesh primitive.
|
|
3
|
+
*
|
|
4
|
+
* Latin: cloud / aura. Per-org leaderboards + cross-org reputation
|
|
5
|
+
* transfer, gated by CONSENT FABRIC.
|
|
6
|
+
*
|
|
7
|
+
* Design (network-effects-first):
|
|
8
|
+
* Each Mneme installation can publish a signed LEADERBOARD CARD
|
|
9
|
+
* summarising the org's TRUSTed primitives:
|
|
10
|
+
* - COLOSSEUM top-5 vendors + ELO scores
|
|
11
|
+
* - HONEST MIRROR per-vendor false-rate windowed lower bound
|
|
12
|
+
* - NEMESIS dispute count
|
|
13
|
+
* - Org-level consent + scope (which artifacts shareable)
|
|
14
|
+
*
|
|
15
|
+
* Consumers subscribe to other orgs' cards + compute weighted
|
|
16
|
+
* cross-org reputation. The trust mesh is a federation, not a
|
|
17
|
+
* central server.
|
|
18
|
+
*
|
|
19
|
+
* v2.54 ships the LOCAL pub/sub primitive (no network). Network
|
|
20
|
+
* transport is a future extension via the existing bridge.
|
|
21
|
+
*
|
|
22
|
+
* Privacy: only AGGREGATED scores cross the boundary. Per-commit
|
|
23
|
+
* fingerprints + raw activity never leave the org.
|
|
24
|
+
*
|
|
25
|
+
* Composes: createHmac + the existing leaderboard / mirror primitives.
|
|
26
|
+
* Pure deterministic + defensive; never throws.
|
|
27
|
+
*/
|
|
28
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync, appendFileSync } from "node:fs";
|
|
29
|
+
import { join } from "node:path";
|
|
30
|
+
import { createHmac } from "node:crypto";
|
|
31
|
+
const NIMBUS_DIR = ".mneme/nemesis/nimbus";
|
|
32
|
+
const PUBLISHED_FILE = "published_cards.jsonl";
|
|
33
|
+
const SUBSCRIPTIONS_FILE = "subscriptions.jsonl";
|
|
34
|
+
const KEY_ENV = "MNEME_NIMBUS_KEY";
|
|
35
|
+
const DEFAULT_KEY = "mneme-nimbus-v1";
|
|
36
|
+
function keyOf() {
|
|
37
|
+
return process.env[KEY_ENV] ?? DEFAULT_KEY;
|
|
38
|
+
}
|
|
39
|
+
function hmacOf(body) {
|
|
40
|
+
return createHmac("sha256", keyOf()).update(JSON.stringify(body)).digest("hex");
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Publish a NIMBUS card to the local pub-store. Pure: card is just a
|
|
44
|
+
* signed JSON envelope; transport to other orgs is the caller's job
|
|
45
|
+
* (HTTP / git / file copy / etc).
|
|
46
|
+
*/
|
|
47
|
+
export function publishCard(input) {
|
|
48
|
+
try {
|
|
49
|
+
if (!input || !input.orgTag)
|
|
50
|
+
return { ok: false, reason: "orgTag required" };
|
|
51
|
+
const orgFingerprint = createHmac("sha256", keyOf()).update("org:").update(input.orgTag).digest("hex").slice(0, 16);
|
|
52
|
+
const at = new Date().toISOString();
|
|
53
|
+
const expiresAt = input.expiresAtIso ?? new Date(Date.now() + 90 * 86_400_000).toISOString();
|
|
54
|
+
const cardBody = {
|
|
55
|
+
orgFingerprint,
|
|
56
|
+
at,
|
|
57
|
+
topByElo: input.topByElo ?? [],
|
|
58
|
+
topByHonesty: input.topByHonesty ?? [],
|
|
59
|
+
consent: {
|
|
60
|
+
sharedScopes: input.sharedScopes ?? ["leaderboard:read"],
|
|
61
|
+
expiresAt,
|
|
62
|
+
revocationRef: input.revocationRef,
|
|
63
|
+
},
|
|
64
|
+
note: input.note,
|
|
65
|
+
};
|
|
66
|
+
const card = { ...cardBody, hmac: hmacOf(cardBody) };
|
|
67
|
+
if (input.persist !== false) {
|
|
68
|
+
try {
|
|
69
|
+
const dir = join(input.repoRoot, NIMBUS_DIR);
|
|
70
|
+
if (!existsSync(dir))
|
|
71
|
+
mkdirSync(dir, { recursive: true });
|
|
72
|
+
const p = join(dir, PUBLISHED_FILE);
|
|
73
|
+
appendFileSync(p, JSON.stringify(card) + "\n");
|
|
74
|
+
return { ok: true, card, path: p, reason: `card published to ${p}` };
|
|
75
|
+
}
|
|
76
|
+
catch (e) {
|
|
77
|
+
return { ok: true, card, reason: `card built but persist failed: ${e.message}` };
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return { ok: true, card, reason: "card built (no persist)" };
|
|
81
|
+
}
|
|
82
|
+
catch (e) {
|
|
83
|
+
return { ok: false, reason: `publish failed: ${e.message}` };
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
/** Verify a NIMBUS card's HMAC + expiry. Pure. */
|
|
87
|
+
export function verifyCard(card) {
|
|
88
|
+
if (!card || typeof card.hmac !== "string")
|
|
89
|
+
return { ok: false, expired: false, reason: "missing card or hmac" };
|
|
90
|
+
const { hmac, ...body } = card;
|
|
91
|
+
const expected = hmacOf(body);
|
|
92
|
+
if (expected !== hmac)
|
|
93
|
+
return { ok: false, expired: false, reason: "hmac mismatch" };
|
|
94
|
+
const expired = Date.parse(card.consent.expiresAt) < Date.now();
|
|
95
|
+
if (expired)
|
|
96
|
+
return { ok: false, expired: true, reason: "card expired" };
|
|
97
|
+
return { ok: true, expired: false, reason: "card verified + within expiry" };
|
|
98
|
+
}
|
|
99
|
+
export function subscribeCard(input) {
|
|
100
|
+
try {
|
|
101
|
+
if (!input || !input.card)
|
|
102
|
+
return { ok: false, reason: "card required" };
|
|
103
|
+
const v = verifyCard(input.card);
|
|
104
|
+
if (!v.ok)
|
|
105
|
+
return { ok: false, reason: `card refused: ${v.reason}` };
|
|
106
|
+
const trustWeight = typeof input.trustWeight === "number" ? Math.max(0, Math.min(1, input.trustWeight)) : 0.5;
|
|
107
|
+
const entry = {
|
|
108
|
+
at: new Date().toISOString(),
|
|
109
|
+
orgFingerprint: input.card.orgFingerprint,
|
|
110
|
+
card: input.card,
|
|
111
|
+
trustWeight,
|
|
112
|
+
};
|
|
113
|
+
if (input.persist !== false) {
|
|
114
|
+
try {
|
|
115
|
+
const dir = join(input.repoRoot, NIMBUS_DIR);
|
|
116
|
+
if (!existsSync(dir))
|
|
117
|
+
mkdirSync(dir, { recursive: true });
|
|
118
|
+
appendFileSync(join(dir, SUBSCRIPTIONS_FILE), JSON.stringify(entry) + "\n");
|
|
119
|
+
}
|
|
120
|
+
catch { /* */ }
|
|
121
|
+
}
|
|
122
|
+
return { ok: true, entry, reason: "card subscribed + verified" };
|
|
123
|
+
}
|
|
124
|
+
catch (e) {
|
|
125
|
+
return { ok: false, reason: `subscribe failed: ${e.message}` };
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
export function computeCrossOrgReputation(repoRoot) {
|
|
129
|
+
const p = join(repoRoot, NIMBUS_DIR, SUBSCRIPTIONS_FILE);
|
|
130
|
+
if (!existsSync(p))
|
|
131
|
+
return [];
|
|
132
|
+
const entries = [];
|
|
133
|
+
for (const line of readFileSync(p, "utf8").split("\n")) {
|
|
134
|
+
if (!line.trim())
|
|
135
|
+
continue;
|
|
136
|
+
try {
|
|
137
|
+
entries.push(JSON.parse(line));
|
|
138
|
+
}
|
|
139
|
+
catch { /* */ }
|
|
140
|
+
}
|
|
141
|
+
// Aggregate
|
|
142
|
+
const acc = new Map();
|
|
143
|
+
for (const e of entries) {
|
|
144
|
+
const w = e.trustWeight;
|
|
145
|
+
const seen = new Set();
|
|
146
|
+
for (const v of e.card.topByElo) {
|
|
147
|
+
const score = (v.elo ?? 1200) / 2000; // normalize to ~0..1
|
|
148
|
+
const cur = acc.get(v.vendor) ?? { weightedScoreSum: 0, orgs: new Set(), totalWeight: 0 };
|
|
149
|
+
cur.weightedScoreSum += score * w;
|
|
150
|
+
cur.totalWeight += w;
|
|
151
|
+
cur.orgs.add(e.orgFingerprint);
|
|
152
|
+
acc.set(v.vendor, cur);
|
|
153
|
+
seen.add(v.vendor);
|
|
154
|
+
}
|
|
155
|
+
for (const v of e.card.topByHonesty) {
|
|
156
|
+
if (seen.has(v.vendor))
|
|
157
|
+
continue;
|
|
158
|
+
const score = 1 / (1 + (v.falseRateLB ?? 0.5));
|
|
159
|
+
const cur = acc.get(v.vendor) ?? { weightedScoreSum: 0, orgs: new Set(), totalWeight: 0 };
|
|
160
|
+
cur.weightedScoreSum += score * w;
|
|
161
|
+
cur.totalWeight += w;
|
|
162
|
+
cur.orgs.add(e.orgFingerprint);
|
|
163
|
+
acc.set(v.vendor, cur);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
const out = [];
|
|
167
|
+
for (const [vendor, a] of acc) {
|
|
168
|
+
out.push({
|
|
169
|
+
vendor,
|
|
170
|
+
weightedScore: a.totalWeight > 0 ? +(a.weightedScoreSum / a.totalWeight).toFixed(3) : 0,
|
|
171
|
+
contributingOrgs: a.orgs.size,
|
|
172
|
+
totalWeight: +a.totalWeight.toFixed(3),
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
return out.sort((a, b) => b.weightedScore - a.weightedScore);
|
|
176
|
+
}
|
|
177
|
+
export function listPublished(repoRoot) {
|
|
178
|
+
const p = join(repoRoot, NIMBUS_DIR, PUBLISHED_FILE);
|
|
179
|
+
if (!existsSync(p))
|
|
180
|
+
return [];
|
|
181
|
+
const out = [];
|
|
182
|
+
for (const line of readFileSync(p, "utf8").split("\n")) {
|
|
183
|
+
if (!line.trim())
|
|
184
|
+
continue;
|
|
185
|
+
try {
|
|
186
|
+
out.push(JSON.parse(line));
|
|
187
|
+
}
|
|
188
|
+
catch { /* */ }
|
|
189
|
+
}
|
|
190
|
+
return out;
|
|
191
|
+
}
|
|
192
|
+
export function listSubscriptions(repoRoot) {
|
|
193
|
+
const p = join(repoRoot, NIMBUS_DIR, SUBSCRIPTIONS_FILE);
|
|
194
|
+
if (!existsSync(p))
|
|
195
|
+
return [];
|
|
196
|
+
const out = [];
|
|
197
|
+
for (const line of readFileSync(p, "utf8").split("\n")) {
|
|
198
|
+
if (!line.trim())
|
|
199
|
+
continue;
|
|
200
|
+
try {
|
|
201
|
+
out.push(JSON.parse(line));
|
|
202
|
+
}
|
|
203
|
+
catch { /* */ }
|
|
204
|
+
}
|
|
205
|
+
return out;
|
|
206
|
+
}
|
|
207
|
+
void writeFileSync; // referenced for future use (revoke API)
|
|
208
|
+
//# sourceMappingURL=nimbus.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nimbus.js","sourceRoot":"","sources":["../../src/nemesis/nimbus.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v2.54.0 — PERFORMANCE BUDGET infrastructure.
|
|
3
|
+
*
|
|
4
|
+
* From the v2.53 audit: "ถ้า latency เกิน 100ms ใน git hook → user
|
|
5
|
+
* disable → product ตาย". Lock budgets per operation + measure them
|
|
6
|
+
* deterministically every TG run; release-script refuses tag if any
|
|
7
|
+
* budget regresses.
|
|
8
|
+
*
|
|
9
|
+
* Budgets are MEASURED in-process (avoids subprocess noise) where
|
|
10
|
+
* possible. The CLI-level ops also expose budgets via the subprocess
|
|
11
|
+
* benchmark suite for end-to-end verification.
|
|
12
|
+
*
|
|
13
|
+
* Pure deterministic + defensive; never throws.
|
|
14
|
+
*/
|
|
15
|
+
export interface PerfBudget {
|
|
16
|
+
/** Op identifier. */
|
|
17
|
+
op: string;
|
|
18
|
+
/** Budget ceiling in milliseconds (warm-path target). */
|
|
19
|
+
budgetMs: number;
|
|
20
|
+
/** Optional cold-path ceiling (first call). */
|
|
21
|
+
coldBudgetMs?: number;
|
|
22
|
+
/** Human-readable rationale for the budget. */
|
|
23
|
+
rationale: string;
|
|
24
|
+
}
|
|
25
|
+
export declare const PERF_BUDGETS: ReadonlyArray<PerfBudget>;
|
|
26
|
+
export interface PerfMeasurement {
|
|
27
|
+
op: string;
|
|
28
|
+
budgetMs: number;
|
|
29
|
+
warmMeanMs: number;
|
|
30
|
+
warmP95Ms: number;
|
|
31
|
+
coldFirstMs: number;
|
|
32
|
+
iterations: number;
|
|
33
|
+
ok: boolean;
|
|
34
|
+
}
|
|
35
|
+
export interface PerfBudgetReport {
|
|
36
|
+
ok: boolean;
|
|
37
|
+
measurements: PerfMeasurement[];
|
|
38
|
+
failing: string[];
|
|
39
|
+
at: string;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Run the full perf budget suite in-process. Iterations chosen so total
|
|
43
|
+
* runtime stays <2s on typical hardware.
|
|
44
|
+
*/
|
|
45
|
+
export declare function runPerfBudget(): PerfBudgetReport;
|
|
46
|
+
/** Human-friendly text report. */
|
|
47
|
+
export declare function renderPerfBudgetReport(r: PerfBudgetReport): string;
|
|
48
|
+
//# sourceMappingURL=perf_budget.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"perf_budget.d.ts","sourceRoot":"","sources":["../src/perf_budget.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAQH,MAAM,WAAW,UAAU;IACzB,qBAAqB;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,yDAAyD;IACzD,QAAQ,EAAE,MAAM,CAAC;IACjB,+CAA+C;IAC/C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,+CAA+C;IAC/C,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,eAAO,MAAM,YAAY,EAAE,aAAa,CAAC,UAAU,CAMlD,CAAC;AAEF,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,EAAE,EAAE,OAAO,CAAC;CACb;AAED,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,OAAO,CAAC;IACZ,YAAY,EAAE,eAAe,EAAE,CAAC;IAChC,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,EAAE,EAAE,MAAM,CAAC;CACZ;AAqCD;;;GAGG;AACH,wBAAgB,aAAa,IAAI,gBAAgB,CAwBhD;AAED,kCAAkC;AAClC,wBAAgB,sBAAsB,CAAC,CAAC,EAAE,gBAAgB,GAAG,MAAM,CAUlE"}
|