@mneme-ai/core 2.45.0 → 2.46.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.
Files changed (59) hide show
  1. package/dist/agent_manifest.d.ts +1 -1
  2. package/dist/agent_manifest.d.ts.map +1 -1
  3. package/dist/agent_manifest.js +8 -0
  4. package/dist/agent_manifest.js.map +1 -1
  5. package/dist/index.d.ts +1 -1
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +14 -2
  8. package/dist/index.js.map +1 -1
  9. package/dist/nemesis/classifier.d.ts +39 -0
  10. package/dist/nemesis/classifier.d.ts.map +1 -0
  11. package/dist/nemesis/classifier.js +133 -0
  12. package/dist/nemesis/classifier.js.map +1 -0
  13. package/dist/nemesis/drift_timeline.d.ts +35 -0
  14. package/dist/nemesis/drift_timeline.d.ts.map +1 -0
  15. package/dist/nemesis/drift_timeline.js +98 -0
  16. package/dist/nemesis/drift_timeline.js.map +1 -0
  17. package/dist/nemesis/env_scan.d.ts +40 -0
  18. package/dist/nemesis/env_scan.d.ts.map +1 -0
  19. package/dist/nemesis/env_scan.js +74 -0
  20. package/dist/nemesis/env_scan.js.map +1 -0
  21. package/dist/nemesis/eu_ai_act_stamp.d.ts +30 -0
  22. package/dist/nemesis/eu_ai_act_stamp.d.ts.map +1 -0
  23. package/dist/nemesis/eu_ai_act_stamp.js +116 -0
  24. package/dist/nemesis/eu_ai_act_stamp.js.map +1 -0
  25. package/dist/nemesis/features.d.ts +13 -0
  26. package/dist/nemesis/features.d.ts.map +1 -0
  27. package/dist/nemesis/features.js +151 -0
  28. package/dist/nemesis/features.js.map +1 -0
  29. package/dist/nemesis/git_hook_installer.d.ts +24 -0
  30. package/dist/nemesis/git_hook_installer.d.ts.map +1 -0
  31. package/dist/nemesis/git_hook_installer.js +71 -0
  32. package/dist/nemesis/git_hook_installer.js.map +1 -0
  33. package/dist/nemesis/identity_verifier.d.ts +25 -0
  34. package/dist/nemesis/identity_verifier.d.ts.map +1 -0
  35. package/dist/nemesis/identity_verifier.js +106 -0
  36. package/dist/nemesis/identity_verifier.js.map +1 -0
  37. package/dist/nemesis/index.d.ts +26 -0
  38. package/dist/nemesis/index.d.ts.map +1 -0
  39. package/dist/nemesis/index.js +30 -0
  40. package/dist/nemesis/index.js.map +1 -0
  41. package/dist/nemesis/replay_attack.d.ts +27 -0
  42. package/dist/nemesis/replay_attack.d.ts.map +1 -0
  43. package/dist/nemesis/replay_attack.js +60 -0
  44. package/dist/nemesis/replay_attack.js.map +1 -0
  45. package/dist/nemesis/types.d.ts +160 -0
  46. package/dist/nemesis/types.d.ts.map +1 -0
  47. package/dist/nemesis/types.js +9 -0
  48. package/dist/nemesis/types.js.map +1 -0
  49. package/dist/nemesis/watermark.d.ts +32 -0
  50. package/dist/nemesis/watermark.d.ts.map +1 -0
  51. package/dist/nemesis/watermark.js +83 -0
  52. package/dist/nemesis/watermark.js.map +1 -0
  53. package/dist/truth_gate/claims.d.ts.map +1 -1
  54. package/dist/truth_gate/claims.js +10 -0
  55. package/dist/truth_gate/claims.js.map +1 -1
  56. package/dist/truth_gate/probes.d.ts.map +1 -1
  57. package/dist/truth_gate/probes.js +117 -0
  58. package/dist/truth_gate/probes.js.map +1 -1
  59. package/package.json +1 -1
@@ -0,0 +1,116 @@
1
+ /**
2
+ * v2.46.0 — NEMESIS ORGAN 3: EU AI Act Article 50 AUTO-STAMPER.
3
+ *
4
+ * EU AI Act Article 50 enforceable 2 Aug 2026 requires machine-readable
5
+ * disclosure of AI-generated content. NEMESIS auto-appends a sentinel-
6
+ * bracketed block to commit messages that's:
7
+ * - human-readable
8
+ * - machine-parseable (single regex)
9
+ * - HMAC-signed (tamper-evident; verifiable offline)
10
+ * - locale-independent
11
+ *
12
+ * Format (appended to commit message body):
13
+ *
14
+ * <!-- AI-GENERATED-CONTENT
15
+ * regime=EU-AI-ACT-2024 article=50 vendor=claude-code confidence=0.98
16
+ * content-type=text/x-source-code at=2026-05-24T08:32:11.444Z
17
+ * hmac=7a6302153ee6a839...
18
+ * -->
19
+ *
20
+ * Pure deterministic; never throws. Caller wires it into git pre-commit
21
+ * via `nemesis install-hook`.
22
+ */
23
+ import { createHmac } from "node:crypto";
24
+ const HMAC_KEY = process.env["MNEME_NEMESIS_KEY"] ?? "MNEME-NEMESIS-DEFAULT-KEY-v2.46";
25
+ const REGIME = "EU-AI-ACT-2024";
26
+ const ARTICLE = "50";
27
+ function canonicalStampBody(s, message) {
28
+ // Order matters for HMAC; we sort keys explicitly.
29
+ return JSON.stringify({
30
+ article: s.article,
31
+ at: s.at,
32
+ confidence: Number(s.confidence.toFixed(4)),
33
+ contentType: s.contentType,
34
+ message,
35
+ regime: s.regime,
36
+ vendor: s.vendor,
37
+ });
38
+ }
39
+ export function stampArticle50(input) {
40
+ if (!input || typeof input.vendor !== "string" || input.vendor.length === 0) {
41
+ return {
42
+ ok: false,
43
+ reason: "vendor is required (e.g. 'claude-code', 'codex', 'cursor')",
44
+ stampedMessage: input?.message ?? "",
45
+ stamp: {
46
+ at: "", vendor: "", confidence: 0, contentType: "text/x-source-code",
47
+ hmac: "", regime: REGIME, article: ARTICLE,
48
+ },
49
+ };
50
+ }
51
+ const at = new Date().toISOString();
52
+ const contentType = input.contentType ?? "text/x-source-code";
53
+ const confidence = Math.max(0, Math.min(1, input.confidence ?? 0));
54
+ const message = input.message ?? "";
55
+ const body = {
56
+ at, vendor: input.vendor, confidence, contentType, regime: REGIME, article: ARTICLE,
57
+ };
58
+ const hmac = createHmac("sha256", HMAC_KEY).update(canonicalStampBody(body, message)).digest("hex").slice(0, 32);
59
+ const stamp = { ...body, hmac };
60
+ const block = [
61
+ "",
62
+ "<!-- AI-GENERATED-CONTENT",
63
+ `regime=${REGIME} article=${ARTICLE} vendor=${input.vendor} confidence=${confidence.toFixed(2)}`,
64
+ `content-type=${contentType} at=${at}`,
65
+ `hmac=${hmac}`,
66
+ "-->",
67
+ ].join("\n");
68
+ return {
69
+ ok: true,
70
+ stampedMessage: message.endsWith("\n") ? message + block : message + "\n" + block,
71
+ stamp,
72
+ };
73
+ }
74
+ /**
75
+ * Parse a stamped message + HMAC-verify. Returns valid=false on any
76
+ * tamper / missing field / regex mismatch.
77
+ */
78
+ export function verifyStamp(stampedMessage) {
79
+ if (!stampedMessage)
80
+ return { valid: false, reason: "empty input" };
81
+ const blockMatch = stampedMessage.match(/<!--\s*AI-GENERATED-CONTENT\s*([\s\S]*?)\s*-->/);
82
+ if (!blockMatch)
83
+ return { valid: false, reason: "no AI-GENERATED-CONTENT block found" };
84
+ const block = blockMatch[1];
85
+ const pick = (key) => {
86
+ const m = block.match(new RegExp(`(?:^|\\s)${key}=(\\S+)`));
87
+ return m ? m[1] : null;
88
+ };
89
+ const regime = pick("regime");
90
+ const article = pick("article");
91
+ const vendor = pick("vendor");
92
+ const confidence = pick("confidence");
93
+ const contentType = pick("content-type");
94
+ const at = pick("at");
95
+ const hmac = pick("hmac");
96
+ if (!regime || !article || !vendor || !confidence || !contentType || !at || !hmac) {
97
+ return { valid: false, reason: `missing fields in stamp block: regime=${!!regime} article=${!!article} vendor=${!!vendor} confidence=${!!confidence} contentType=${!!contentType} at=${!!at} hmac=${!!hmac}` };
98
+ }
99
+ if (regime !== REGIME)
100
+ return { valid: false, reason: `regime mismatch: expected ${REGIME}, got ${regime}` };
101
+ if (article !== ARTICLE)
102
+ return { valid: false, reason: `article mismatch: expected ${ARTICLE}, got ${article}` };
103
+ const confidenceNum = parseFloat(confidence);
104
+ if (!Number.isFinite(confidenceNum))
105
+ return { valid: false, reason: "confidence is not a number" };
106
+ // Recompute HMAC over the body + original message (everything before the block).
107
+ const message = stampedMessage.slice(0, blockMatch.index).replace(/\n+$/, "");
108
+ const body = {
109
+ at, vendor, confidence: confidenceNum, contentType, regime: REGIME, article: ARTICLE,
110
+ };
111
+ const expected = createHmac("sha256", HMAC_KEY).update(canonicalStampBody(body, message)).digest("hex").slice(0, 32);
112
+ if (expected !== hmac)
113
+ return { valid: false, reason: "HMAC mismatch — stamp was tampered" };
114
+ return { valid: true, parsed: { ...body, hmac } };
115
+ }
116
+ //# sourceMappingURL=eu_ai_act_stamp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eu_ai_act_stamp.js","sourceRoot":"","sources":["../../src/nemesis/eu_ai_act_stamp.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * v2.46.0 — NEMESIS ORGAN 1: FINGERPRINTER (41 features).
3
+ *
4
+ * Implements the 41-feature vector from arxiv 2601.17406 — pure
5
+ * deterministic extraction (no ML model needed for the EXTRACTOR; the
6
+ * CLASSIFIER applies the paper's feature weights to predict vendor).
7
+ *
8
+ * Each feature is documented in types.ts. Every value is a finite
9
+ * non-negative real. NEVER throws — empty inputs return zero-vector.
10
+ */
11
+ import type { Fingerprint, Fixture } from "./types.js";
12
+ export declare function extractFingerprint(fixture: Fixture): Fingerprint;
13
+ //# sourceMappingURL=features.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"features.d.ts","sourceRoot":"","sources":["../../src/nemesis/features.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAqDvD,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,WAAW,CA6GhE"}
@@ -0,0 +1,151 @@
1
+ /**
2
+ * v2.46.0 — NEMESIS ORGAN 1: FINGERPRINTER (41 features).
3
+ *
4
+ * Implements the 41-feature vector from arxiv 2601.17406 — pure
5
+ * deterministic extraction (no ML model needed for the EXTRACTOR; the
6
+ * CLASSIFIER applies the paper's feature weights to predict vendor).
7
+ *
8
+ * Each feature is documented in types.ts. Every value is a finite
9
+ * non-negative real. NEVER throws — empty inputs return zero-vector.
10
+ */
11
+ function safeDivide(num, den) {
12
+ return den === 0 ? 0 : num / den;
13
+ }
14
+ function shannonEntropyNormalized(counts) {
15
+ const total = counts.reduce((a, b) => a + b, 0);
16
+ if (total === 0 || counts.length === 0)
17
+ return 0;
18
+ let h = 0;
19
+ for (const c of counts) {
20
+ if (c === 0)
21
+ continue;
22
+ const p = c / total;
23
+ h += -p * Math.log2(p);
24
+ }
25
+ const maxH = Math.log2(Math.max(1, counts.length));
26
+ return maxH === 0 ? 0 : h / maxH; // ∈ [0, 1]
27
+ }
28
+ /**
29
+ * Parse a unified diff into per-file added/removed line counts +
30
+ * collected added-line text.
31
+ */
32
+ function parseDiff(diff) {
33
+ const perFile = new Map();
34
+ const addedLines = [];
35
+ const removedLines = [];
36
+ let current = null;
37
+ let currentName = "";
38
+ for (const ln of diff.split("\n")) {
39
+ const m = ln.match(/^diff --git a\/(\S+) b\/(\S+)/);
40
+ if (m) {
41
+ currentName = m[2];
42
+ current = { added: 0, removed: 0 };
43
+ perFile.set(currentName, current);
44
+ continue;
45
+ }
46
+ if (!current)
47
+ continue;
48
+ if (ln.startsWith("+") && !ln.startsWith("+++")) {
49
+ current.added++;
50
+ addedLines.push(ln.slice(1));
51
+ }
52
+ else if (ln.startsWith("-") && !ln.startsWith("---")) {
53
+ current.removed++;
54
+ removedLines.push(ln.slice(1));
55
+ }
56
+ }
57
+ return { perFile, addedLines, removedLines };
58
+ }
59
+ export function extractFingerprint(fixture) {
60
+ const diff = fixture.diff ?? "";
61
+ const prDesc = fixture.prDescription ?? "";
62
+ const commits = fixture.commitMessages ?? [];
63
+ // ── Commit shape ──
64
+ const commit_count = commits.length;
65
+ const multiline = commits.filter((c) => /\n/.test(c)).length;
66
+ const multiline_commit_ratio = safeDivide(multiline, commit_count);
67
+ const commitLineCounts = commits.map((c) => c.split("\n").length);
68
+ const mean_commit_lines = commit_count === 0 ? 0 : commitLineCounts.reduce((a, b) => a + b, 0) / commit_count;
69
+ const max_commit_chars = commits.reduce((m, c) => Math.max(m, c.length), 0);
70
+ const commit_bullet_count = commits.reduce((n, c) => n + (c.match(/^[\s>]*[-*+]\s/gm)?.length ?? 0), 0);
71
+ // ── Diff parse ──
72
+ const { perFile, addedLines, removedLines } = parseDiff(diff);
73
+ const added_lines = addedLines.length;
74
+ const removed_lines = removedLines.length;
75
+ const net_lines = added_lines - removed_lines;
76
+ const files_touched = perFile.size;
77
+ const addedJoined = addedLines.join("\n");
78
+ // Conditional / control flow
79
+ const if_count = (addedJoined.match(/\b(if|elif|else\s+if)\b/g) ?? []).length;
80
+ const switch_count = (addedJoined.match(/\b(switch|case|match)\b/g) ?? []).length;
81
+ const try_count = (addedJoined.match(/\b(try|catch|except|finally)\b/g) ?? []).length;
82
+ const conditional_density = safeDivide(if_count + switch_count + try_count, added_lines);
83
+ // ── PR description shape ──
84
+ const pr_desc_length_chars = prDesc.length;
85
+ const pr_desc_length_words = prDesc.split(/\s+/).filter(Boolean).length;
86
+ const pr_desc_length_lines = prDesc.split("\n").length;
87
+ const bullet_point_count = (prDesc.match(/^[\s>]*[-*+]\s/gm) ?? []).length;
88
+ const hyperlink_count = (prDesc.match(/\[[^\]]+\]\([^)]+\)/g) ?? []).length +
89
+ (prDesc.match(/\bhttps?:\/\/\S+/g) ?? []).length;
90
+ const heading_count = (prDesc.match(/^#{1,6}\s/gm) ?? []).length;
91
+ const code_fence_count = (prDesc.match(/```/g) ?? []).length / 2;
92
+ const inline_code_count = (prDesc.match(/`[^`\n]+`/g) ?? []).length;
93
+ // ── Change concentration ──
94
+ const perFileCounts = [...perFile.values()].map((v) => v.added + v.removed);
95
+ const distributed_changes_score = shannonEntropyNormalized(perFileCounts);
96
+ const change_concentration = 1 - distributed_changes_score;
97
+ // ── Line shape ──
98
+ const lineLengths = addedLines.map((l) => l.length);
99
+ const mean_line_length = lineLengths.length === 0 ? 0 : lineLengths.reduce((a, b) => a + b, 0) / lineLengths.length;
100
+ const max_line_length = lineLengths.reduce((m, l) => Math.max(m, l), 0);
101
+ const long_line_ratio = safeDivide(lineLengths.filter((l) => l > 100).length, lineLengths.length);
102
+ // ── Comments / blanks ──
103
+ const comment_count = addedLines.filter((l) => /^\s*(\/\/|#|\/\*|\*\s|---)/.test(l)).length;
104
+ const comment_ratio = safeDivide(comment_count, added_lines);
105
+ const blank_line_count = addedLines.filter((l) => /^\s*$/.test(l)).length;
106
+ const blank_line_ratio = safeDivide(blank_line_count, added_lines);
107
+ // ── Test / doc files ──
108
+ const filePaths = [...perFile.keys()];
109
+ const test_files_touched = filePaths.filter((p) => /\.(test|spec)\.|__tests__\/|tests?\//.test(p)).length;
110
+ const doc_files_touched = filePaths.filter((p) => /\.(md|rst|txt|adoc)$|docs?\//i.test(p)).length;
111
+ const test_file_ratio = safeDivide(test_files_touched, files_touched);
112
+ // ── Hygiene markers ──
113
+ const debug_print_count = (addedJoined.match(/\bconsole\.log\(/g) ?? []).length +
114
+ (addedJoined.match(/\bprint\(/g) ?? []).length +
115
+ (addedJoined.match(/\bdebugger\b/g) ?? []).length;
116
+ const todo_marker_count = (addedJoined.match(/\b(TODO|FIXME|XXX|HACK)\b/g) ?? []).length;
117
+ // ── Imports ──
118
+ const import_count = (addedJoined.match(/^\s*import\s/gm) ?? []).length +
119
+ (addedJoined.match(/\brequire\(/g) ?? []).length +
120
+ (addedJoined.match(/\bfrom\s+["']/g) ?? []).length;
121
+ const relative_import_count = (addedJoined.match(/from\s+["']\.{1,2}\//g) ?? []).length;
122
+ // ── Punctuation density ──
123
+ const semicolon_count = (addedJoined.match(/;/g) ?? []).length;
124
+ const semicolon_density = safeDivide(semicolon_count, added_lines);
125
+ const brace_count = (addedJoined.match(/[{}]/g) ?? []).length;
126
+ const brace_density = safeDivide(brace_count, added_lines);
127
+ const paren_count = (addedJoined.match(/[()]/g) ?? []).length;
128
+ const paren_density = safeDivide(paren_count, added_lines);
129
+ // ── Naming style ──
130
+ const identifiers = addedJoined.match(/\b[A-Za-z_][A-Za-z0-9_]{2,}\b/g) ?? [];
131
+ const camel_case_count = identifiers.filter((id) => /^[a-z][a-z0-9]*[A-Z]/.test(id)).length;
132
+ const snake_case_count = identifiers.filter((id) => /^[a-z][a-z0-9]*_[a-z]/.test(id)).length;
133
+ const mean_identifier_length = identifiers.length === 0 ? 0 : identifiers.reduce((s, i) => s + i.length, 0) / identifiers.length;
134
+ return {
135
+ multiline_commit_ratio, mean_commit_lines, max_commit_chars, commit_count,
136
+ conditional_density, if_count, switch_count, try_count,
137
+ pr_desc_length_chars, pr_desc_length_words, pr_desc_length_lines,
138
+ bullet_point_count, hyperlink_count, heading_count, code_fence_count, inline_code_count,
139
+ change_concentration, distributed_changes_score, files_touched,
140
+ added_lines, removed_lines, net_lines,
141
+ mean_line_length, max_line_length, long_line_ratio,
142
+ comment_ratio, blank_line_ratio,
143
+ test_files_touched, doc_files_touched, test_file_ratio,
144
+ debug_print_count, todo_marker_count,
145
+ import_count, relative_import_count,
146
+ semicolon_density, brace_density, paren_density,
147
+ camel_case_count, snake_case_count, mean_identifier_length,
148
+ commit_bullet_count,
149
+ };
150
+ }
151
+ //# sourceMappingURL=features.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"features.js","sourceRoot":"","sources":["../../src/nemesis/features.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * v2.46.0 — NEMESIS ORGAN 3 surface: GIT PRE-COMMIT HOOK INSTALLER.
3
+ *
4
+ * Installs a `.git/hooks/prepare-commit-msg` script that calls
5
+ * `mneme nemesis eu_stamp` for every commit and appends the Article 50
6
+ * disclosure block to the staged commit message.
7
+ *
8
+ * DRY-RUN default. Defensive: never throws.
9
+ */
10
+ export interface InstallHookInput {
11
+ repoRoot: string;
12
+ dryRun?: boolean;
13
+ }
14
+ export interface InstallHookResult {
15
+ ok: boolean;
16
+ reason?: string;
17
+ hookPath?: string;
18
+ plannedScript: string;
19
+ installed?: boolean;
20
+ /** When a hook already exists, we don't overwrite — return the existing body so the caller can merge manually. */
21
+ existing?: string;
22
+ }
23
+ export declare function installPreCommitHook(input: InstallHookInput): InstallHookResult;
24
+ //# sourceMappingURL=git_hook_installer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git_hook_installer.d.ts","sourceRoot":"","sources":["../../src/nemesis/git_hook_installer.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AA8BH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,kHAAkH;IAClH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,gBAAgB,GAAG,iBAAiB,CAgC/E"}
@@ -0,0 +1,71 @@
1
+ /**
2
+ * v2.46.0 — NEMESIS ORGAN 3 surface: GIT PRE-COMMIT HOOK INSTALLER.
3
+ *
4
+ * Installs a `.git/hooks/prepare-commit-msg` script that calls
5
+ * `mneme nemesis eu_stamp` for every commit and appends the Article 50
6
+ * disclosure block to the staged commit message.
7
+ *
8
+ * DRY-RUN default. Defensive: never throws.
9
+ */
10
+ import { existsSync, mkdirSync, writeFileSync, readFileSync } from "node:fs";
11
+ import { join } from "node:path";
12
+ const HOOK_SCRIPT = `#!/bin/sh
13
+ # Mneme NEMESIS — EU AI Act Article 50 auto-stamper (v2.46.0+)
14
+ # Auto-installed by \`mneme nemesis install-hook\`.
15
+ #
16
+ # Reads the in-progress commit message, asks mneme nemesis for the
17
+ # detected vendor + confidence, and appends a machine-readable
18
+ # disclosure block. Skips if the message already contains one.
19
+ MSG_FILE="$1"
20
+ [ -z "$MSG_FILE" ] && exit 0
21
+ grep -q 'AI-GENERATED-CONTENT' "$MSG_FILE" 2>/dev/null && exit 0
22
+ # Best-effort detection via env scan (cheapest signal); fallback "unknown"
23
+ VENDOR="unknown"
24
+ [ -n "$CLAUDECODE" ] && VENDOR="claude-code"
25
+ [ -n "$CURSOR_AGENT" ] && VENDOR="cursor"
26
+ [ -n "$DEVIN_SESSION" ] && VENDOR="devin"
27
+ [ -n "$COPILOT_AGENT" ] && VENDOR="copilot"
28
+ [ -n "$CODEX_AGENT" ] && VENDOR="codex"
29
+ [ "$VENDOR" = "unknown" ] && exit 0
30
+ MSG=$(cat "$MSG_FILE")
31
+ mneme nemesis eu_stamp --message "$MSG" --vendor "$VENDOR" --json 2>/dev/null | \
32
+ node -e 'let s=""; process.stdin.on("data",d=>s+=d); process.stdin.on("end",()=>{try{const j=JSON.parse(s);if(j&&j.ok)process.stdout.write(j.stampedMessage)}catch{}})' \
33
+ > "$MSG_FILE.new" && mv "$MSG_FILE.new" "$MSG_FILE"
34
+ exit 0
35
+ `;
36
+ export function installPreCommitHook(input) {
37
+ const plannedScript = HOOK_SCRIPT;
38
+ if (!input || !input.repoRoot) {
39
+ return { ok: false, reason: "repoRoot required", plannedScript };
40
+ }
41
+ const dryRun = input.dryRun !== false; // default TRUE
42
+ const hookDir = join(input.repoRoot, ".git", "hooks");
43
+ const hookPath = join(hookDir, "prepare-commit-msg");
44
+ if (dryRun) {
45
+ return { ok: true, hookPath, plannedScript, installed: false };
46
+ }
47
+ if (!existsSync(join(input.repoRoot, ".git"))) {
48
+ return { ok: false, reason: "not a git repo (no .git directory)", hookPath, plannedScript };
49
+ }
50
+ try {
51
+ if (!existsSync(hookDir))
52
+ mkdirSync(hookDir, { recursive: true });
53
+ if (existsSync(hookPath)) {
54
+ const existing = readFileSync(hookPath, "utf8");
55
+ if (existing.includes("mneme nemesis eu_stamp")) {
56
+ return { ok: true, hookPath, plannedScript, installed: true, existing };
57
+ }
58
+ return {
59
+ ok: false,
60
+ reason: "existing prepare-commit-msg hook found; refuse to overwrite. Add the NEMESIS body manually or move the existing hook aside.",
61
+ hookPath, plannedScript, existing,
62
+ };
63
+ }
64
+ writeFileSync(hookPath, plannedScript, { mode: 0o755 });
65
+ return { ok: true, hookPath, plannedScript, installed: true };
66
+ }
67
+ catch (e) {
68
+ return { ok: false, reason: `install failed: ${e.message}`, hookPath, plannedScript };
69
+ }
70
+ }
71
+ //# sourceMappingURL=git_hook_installer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git_hook_installer.js","sourceRoot":"","sources":["../../src/nemesis/git_hook_installer.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,MAAM,WAAW,GAAG;;;;;;;;;;;;;;;;;;;;;;;CAuBnB,CAAC;AAiBF,MAAM,UAAU,oBAAoB,CAAC,KAAuB;IAC1D,MAAM,aAAa,GAAG,WAAW,CAAC;IAClC,IAAI,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;QAC9B,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,mBAAmB,EAAE,aAAa,EAAE,CAAC;IACnE,CAAC;IACD,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,KAAK,KAAK,CAAC,CAAC,eAAe;IACtD,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;IACtD,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,EAAE,oBAAoB,CAAC,CAAC;IACrD,IAAI,MAAM,EAAE,CAAC;QACX,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,aAAa,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;IACjE,CAAC;IACD,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC;QAC9C,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,oCAAoC,EAAE,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC9F,CAAC;IACD,IAAI,CAAC;QACH,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;YAAE,SAAS,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAClE,IAAI,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YACzB,MAAM,QAAQ,GAAG,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;YAChD,IAAI,QAAQ,CAAC,QAAQ,CAAC,wBAAwB,CAAC,EAAE,CAAC;gBAChD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,aAAa,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;YAC1E,CAAC;YACD,OAAO;gBACL,EAAE,EAAE,KAAK;gBACT,MAAM,EAAE,6HAA6H;gBACrI,QAAQ,EAAE,aAAa,EAAE,QAAQ;aAClC,CAAC;QACJ,CAAC;QACD,aAAa,CAAC,QAAQ,EAAE,aAAa,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QACxD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,aAAa,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;IAChE,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,mBAAoB,CAAW,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,aAAa,EAAE,CAAC;IACnG,CAAC;AACH,CAAC"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * v2.46.0 — NEMESIS ORGAN 2: LIE DETECTOR.
3
+ *
4
+ * Compares CLAIMED vendor (whoever the AI agent says it is) against
5
+ * DETECTED vendor (from fingerprinter + env scan). Divergence → alert.
6
+ *
7
+ * Verdict ladder:
8
+ * CONFIRMED claimed = detected with confidence ≥ 0.40
9
+ * DISPUTED different vendor but detector confidence < 0.65
10
+ * IMPOSSIBLE different vendor AND detector confidence ≥ 0.65
11
+ * INCONCLUSIVE detector returned unknown / confidence < 0.10
12
+ *
13
+ * Every verdict carries an HMAC over the canonical body so an
14
+ * external auditor can verify the verdict was actually computed
15
+ * (and not faked by the AI agent itself).
16
+ */
17
+ import type { Fixture, IdentityClaimInput, IdentityVerdict } from "./types.js";
18
+ export declare function verifyIdentityClaim(input: IdentityClaimInput): IdentityVerdict;
19
+ /**
20
+ * Verify the HMAC of a returned IdentityVerdict. Returns false if
21
+ * any field was tampered after the verdict was signed.
22
+ */
23
+ export declare function verifyIdentityHmac(v: IdentityVerdict): boolean;
24
+ export type { Fixture, IdentityClaimInput, IdentityVerdict };
25
+ //# sourceMappingURL=identity_verifier.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"identity_verifier.d.ts","sourceRoot":"","sources":["../../src/nemesis/identity_verifier.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,KAAK,EACV,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAC7C,MAAM,YAAY,CAAC;AA6BpB,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,kBAAkB,GAAG,eAAe,CAgD9E;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,eAAe,GAAG,OAAO,CAU9D;AAGD,YAAY,EAAE,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,CAAC"}
@@ -0,0 +1,106 @@
1
+ /**
2
+ * v2.46.0 — NEMESIS ORGAN 2: LIE DETECTOR.
3
+ *
4
+ * Compares CLAIMED vendor (whoever the AI agent says it is) against
5
+ * DETECTED vendor (from fingerprinter + env scan). Divergence → alert.
6
+ *
7
+ * Verdict ladder:
8
+ * CONFIRMED claimed = detected with confidence ≥ 0.40
9
+ * DISPUTED different vendor but detector confidence < 0.65
10
+ * IMPOSSIBLE different vendor AND detector confidence ≥ 0.65
11
+ * INCONCLUSIVE detector returned unknown / confidence < 0.10
12
+ *
13
+ * Every verdict carries an HMAC over the canonical body so an
14
+ * external auditor can verify the verdict was actually computed
15
+ * (and not faked by the AI agent itself).
16
+ */
17
+ import { createHmac } from "node:crypto";
18
+ import { extractFingerprint } from "./features.js";
19
+ import { classifyAgent } from "./classifier.js";
20
+ import { scanEnv } from "./env_scan.js";
21
+ const HMAC_KEY = process.env["MNEME_NEMESIS_KEY"] ?? "MNEME-NEMESIS-DEFAULT-KEY-v2.46";
22
+ function canonical(obj) {
23
+ const keys = Object.keys(obj).sort();
24
+ return JSON.stringify(keys.reduce((acc, k) => { acc[k] = obj[k]; return acc; }, {}));
25
+ }
26
+ function hmacOf(body) {
27
+ return createHmac("sha256", HMAC_KEY).update(canonical(body)).digest("hex").slice(0, 32);
28
+ }
29
+ function normalizeVendor(s) {
30
+ const x = (s ?? "").toLowerCase().trim();
31
+ // common aliases
32
+ const map = {
33
+ "claude": "claude-code", "claude-code": "claude-code", "claudecode": "claude-code", "anthropic-claude": "claude-code",
34
+ "codex": "codex", "openai-codex": "codex", "openai-codex-cli": "codex",
35
+ "copilot": "copilot", "github-copilot": "copilot", "gh-copilot": "copilot",
36
+ "cursor": "cursor", "cursor-agent": "cursor",
37
+ "devin": "devin", "cognition-devin": "devin",
38
+ };
39
+ return map[x] ?? x;
40
+ }
41
+ export function verifyIdentityClaim(input) {
42
+ const claimedRaw = input.claimedVendor ?? "";
43
+ const claimed = normalizeVendor(claimedRaw);
44
+ const fp = extractFingerprint(input.fixture);
45
+ const fpVerdict = classifyAgent(fp);
46
+ const envVerdict = scanEnv();
47
+ // Fuse fingerprint + env detector. Env evidence boosts confidence
48
+ // when it agrees; reduces when it disagrees.
49
+ let detected = fpVerdict.topVendor;
50
+ let confidence = fpVerdict.confidence;
51
+ if (envVerdict.vendor !== "unknown") {
52
+ if (envVerdict.vendor === fpVerdict.topVendor) {
53
+ // Agreement boost
54
+ confidence = Math.min(0.99, confidence + 0.20);
55
+ }
56
+ else if (fpVerdict.confidence < 0.40) {
57
+ // Env wins when fingerprint is weak
58
+ detected = envVerdict.vendor;
59
+ confidence = Math.min(0.95, envVerdict.confidence + fpVerdict.confidence * 0.30);
60
+ }
61
+ }
62
+ // Compute verdict.
63
+ let verdict;
64
+ let reasoning;
65
+ if (detected === "unknown" || confidence < 0.10) {
66
+ verdict = "INCONCLUSIVE";
67
+ reasoning = `detector returned ${detected} with confidence ${confidence.toFixed(2)} — cannot judge claim`;
68
+ }
69
+ else if (claimed === detected) {
70
+ verdict = "CONFIRMED";
71
+ reasoning = `claim=${claimed} matches detected=${detected} (conf ${confidence.toFixed(2)})`;
72
+ }
73
+ else if (confidence >= 0.65) {
74
+ verdict = "IMPOSSIBLE";
75
+ reasoning = `claim=${claimed} contradicts detected=${detected} with HIGH confidence ${confidence.toFixed(2)}`;
76
+ }
77
+ else {
78
+ verdict = "DISPUTED";
79
+ reasoning = `claim=${claimed} differs from detected=${detected} but detector confidence ${confidence.toFixed(2)} is below threshold`;
80
+ }
81
+ const body = {
82
+ verdict,
83
+ claimedVendor: claimed,
84
+ fingerprintTop: detected,
85
+ fingerprintConfidence: Number(confidence.toFixed(4)),
86
+ reasoning,
87
+ };
88
+ const hmac = hmacOf(body);
89
+ return { ...body, hmac };
90
+ }
91
+ /**
92
+ * Verify the HMAC of a returned IdentityVerdict. Returns false if
93
+ * any field was tampered after the verdict was signed.
94
+ */
95
+ export function verifyIdentityHmac(v) {
96
+ const body = {
97
+ verdict: v.verdict,
98
+ claimedVendor: v.claimedVendor,
99
+ fingerprintTop: v.fingerprintTop,
100
+ fingerprintConfidence: Number(v.fingerprintConfidence.toFixed(4)),
101
+ reasoning: v.reasoning,
102
+ };
103
+ const expected = hmacOf(body);
104
+ return expected === v.hmac;
105
+ }
106
+ //# sourceMappingURL=identity_verifier.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"identity_verifier.js","sourceRoot":"","sources":["../../src/nemesis/identity_verifier.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * v2.46.0 — NEMESIS public surface.
3
+ *
4
+ * The world's first Anti-Identity-Lie Engine for AI Coding Agents.
5
+ *
6
+ * ORGAN 1 FINGERPRINTER — features.ts + env_scan.ts (41-axis vector + env markers)
7
+ * ORGAN 2 LIE DETECTOR — classifier.ts + identity_verifier.ts (claim vs detected; HMAC verdict)
8
+ * ORGAN 3 ARTICLE 50 STAMP — eu_ai_act_stamp.ts + watermark.ts + git_hook_installer.ts
9
+ * ORGAN 4 DRIFT TIMELINE — drift_timeline.ts (per-vendor fingerprint history + σ-based drift)
10
+ * ORGAN 5 REPLAY DETECTOR — replay_attack.ts (stealth-upgrade/downgrade/swap)
11
+ *
12
+ * Composes: arxiv 2601.17406 fingerprinting + Mneme HMAC chain +
13
+ * EU AI Act Article 50 (Aug 2026 deadline) + HONEST MIRROR + ARGUS.
14
+ */
15
+ export type { VendorId, Fixture, Fingerprint, AgentVerdict, IdentityClaimInput, IdentityVerdict, IdentityVerdictKind, Article50StampInput, Article50Stamp, StampResult, VerifyStampResult, } from "./types.js";
16
+ export { extractFingerprint } from "./features.js";
17
+ export { scanEnv, type EnvScanResult } from "./env_scan.js";
18
+ export { classifyAgent, SIGNATURES } from "./classifier.js";
19
+ export { verifyIdentityClaim, verifyIdentityHmac } from "./identity_verifier.js";
20
+ export { stampArticle50, verifyStamp } from "./eu_ai_act_stamp.js";
21
+ export { encodeWatermark, decodeWatermark } from "./watermark.js";
22
+ export { installPreCommitHook, type InstallHookInput, type InstallHookResult } from "./git_hook_installer.js";
23
+ export { recordFingerprint, readTimeline, computeVariance, type DriftEntry, type VarianceResult } from "./drift_timeline.js";
24
+ export { detectReplayAttack, type ReplayResult } from "./replay_attack.js";
25
+ export { generateProbes, gradeRun, recordRun, readRuns, trendFor, type Probe, type ProbeFamily, type NemesisRun, type TrendSeries, } from "./nemesis.js";
26
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/nemesis/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,YAAY,EACV,QAAQ,EAAE,OAAO,EAAE,WAAW,EAAE,YAAY,EAC5C,kBAAkB,EAAE,eAAe,EAAE,mBAAmB,EACxD,mBAAmB,EAAE,cAAc,EAAE,WAAW,EAAE,iBAAiB,GACpE,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,eAAe,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AACjF,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnE,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAClE,OAAO,EAAE,oBAAoB,EAAE,KAAK,gBAAgB,EAAE,KAAK,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC9G,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,eAAe,EAAE,KAAK,UAAU,EAAE,KAAK,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC7H,OAAO,EAAE,kBAAkB,EAAE,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAO3E,OAAO,EACL,cAAc,EACd,QAAQ,EACR,SAAS,EACT,QAAQ,EACR,QAAQ,EACR,KAAK,KAAK,EACV,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,WAAW,GACjB,MAAM,cAAc,CAAC"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * v2.46.0 — NEMESIS public surface.
3
+ *
4
+ * The world's first Anti-Identity-Lie Engine for AI Coding Agents.
5
+ *
6
+ * ORGAN 1 FINGERPRINTER — features.ts + env_scan.ts (41-axis vector + env markers)
7
+ * ORGAN 2 LIE DETECTOR — classifier.ts + identity_verifier.ts (claim vs detected; HMAC verdict)
8
+ * ORGAN 3 ARTICLE 50 STAMP — eu_ai_act_stamp.ts + watermark.ts + git_hook_installer.ts
9
+ * ORGAN 4 DRIFT TIMELINE — drift_timeline.ts (per-vendor fingerprint history + σ-based drift)
10
+ * ORGAN 5 REPLAY DETECTOR — replay_attack.ts (stealth-upgrade/downgrade/swap)
11
+ *
12
+ * Composes: arxiv 2601.17406 fingerprinting + Mneme HMAC chain +
13
+ * EU AI Act Article 50 (Aug 2026 deadline) + HONEST MIRROR + ARGUS.
14
+ */
15
+ export { extractFingerprint } from "./features.js";
16
+ export { scanEnv } from "./env_scan.js";
17
+ export { classifyAgent, SIGNATURES } from "./classifier.js";
18
+ export { verifyIdentityClaim, verifyIdentityHmac } from "./identity_verifier.js";
19
+ export { stampArticle50, verifyStamp } from "./eu_ai_act_stamp.js";
20
+ export { encodeWatermark, decodeWatermark } from "./watermark.js";
21
+ export { installPreCommitHook } from "./git_hook_installer.js";
22
+ export { recordFingerprint, readTimeline, computeVariance } from "./drift_timeline.js";
23
+ export { detectReplayAttack } from "./replay_attack.js";
24
+ // v1.61 NEMESIS PROTOCOL (Tier 5 — weekly adversarial audit) lives in
25
+ // nemesis.ts alongside the new v2.46.0 ANTI-IDENTITY-LIE ENGINE. Both
26
+ // export through this barrel so downstream consumers (MCP `nemesis.generate`
27
+ // / `nemesis.grade` / `nemesis.trend` Tier 5 tools) continue to work
28
+ // unchanged. Two distinct primitives sharing one namespace by design.
29
+ export { generateProbes, gradeRun, recordRun, readRuns, trendFor, } from "./nemesis.js";
30
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/nemesis/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAQH,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,OAAO,EAAsB,MAAM,eAAe,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AACjF,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnE,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAClE,OAAO,EAAE,oBAAoB,EAAiD,MAAM,yBAAyB,CAAC;AAC9G,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,eAAe,EAAwC,MAAM,qBAAqB,CAAC;AAC7H,OAAO,EAAE,kBAAkB,EAAqB,MAAM,oBAAoB,CAAC;AAE3E,sEAAsE;AACtE,sEAAsE;AACtE,6EAA6E;AAC7E,qEAAqE;AACrE,sEAAsE;AACtE,OAAO,EACL,cAAc,EACd,QAAQ,EACR,SAAS,EACT,QAAQ,EACR,QAAQ,GAKT,MAAM,cAAc,CAAC"}