@mneme-ai/core 2.45.0 → 2.47.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 +1 -1
- package/dist/agent_manifest.d.ts.map +1 -1
- package/dist/agent_manifest.js +8 -0
- package/dist/agent_manifest.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +14 -2
- package/dist/index.js.map +1 -1
- package/dist/nemesis/calibration_corpus.d.ts +40 -0
- package/dist/nemesis/calibration_corpus.d.ts.map +1 -0
- package/dist/nemesis/calibration_corpus.js +148 -0
- package/dist/nemesis/calibration_corpus.js.map +1 -0
- package/dist/nemesis/classifier.d.ts +39 -0
- package/dist/nemesis/classifier.d.ts.map +1 -0
- package/dist/nemesis/classifier.js +133 -0
- package/dist/nemesis/classifier.js.map +1 -0
- package/dist/nemesis/classifier_calibrated.d.ts +48 -0
- package/dist/nemesis/classifier_calibrated.d.ts.map +1 -0
- package/dist/nemesis/classifier_calibrated.js +166 -0
- package/dist/nemesis/classifier_calibrated.js.map +1 -0
- package/dist/nemesis/drift_timeline.d.ts +35 -0
- package/dist/nemesis/drift_timeline.d.ts.map +1 -0
- package/dist/nemesis/drift_timeline.js +98 -0
- package/dist/nemesis/drift_timeline.js.map +1 -0
- package/dist/nemesis/env_scan.d.ts +40 -0
- package/dist/nemesis/env_scan.d.ts.map +1 -0
- package/dist/nemesis/env_scan.js +74 -0
- package/dist/nemesis/env_scan.js.map +1 -0
- package/dist/nemesis/eu_ai_act_stamp.d.ts +30 -0
- package/dist/nemesis/eu_ai_act_stamp.d.ts.map +1 -0
- package/dist/nemesis/eu_ai_act_stamp.js +116 -0
- package/dist/nemesis/eu_ai_act_stamp.js.map +1 -0
- package/dist/nemesis/features.d.ts +13 -0
- package/dist/nemesis/features.d.ts.map +1 -0
- package/dist/nemesis/features.js +151 -0
- package/dist/nemesis/features.js.map +1 -0
- package/dist/nemesis/git_hook_installer.d.ts +24 -0
- package/dist/nemesis/git_hook_installer.d.ts.map +1 -0
- package/dist/nemesis/git_hook_installer.js +71 -0
- package/dist/nemesis/git_hook_installer.js.map +1 -0
- package/dist/nemesis/identity_verifier.d.ts +25 -0
- package/dist/nemesis/identity_verifier.d.ts.map +1 -0
- package/dist/nemesis/identity_verifier.js +106 -0
- package/dist/nemesis/identity_verifier.js.map +1 -0
- package/dist/nemesis/index.d.ts +30 -0
- package/dist/nemesis/index.d.ts.map +1 -0
- package/dist/nemesis/index.js +36 -0
- package/dist/nemesis/index.js.map +1 -0
- package/dist/nemesis/key_management.d.ts +30 -0
- package/dist/nemesis/key_management.d.ts.map +1 -0
- package/dist/nemesis/key_management.js +91 -0
- package/dist/nemesis/key_management.js.map +1 -0
- package/dist/nemesis/learning_loop.d.ts +45 -0
- package/dist/nemesis/learning_loop.d.ts.map +1 -0
- package/dist/nemesis/learning_loop.js +116 -0
- package/dist/nemesis/learning_loop.js.map +1 -0
- package/dist/nemesis/replay_attack.d.ts +27 -0
- package/dist/nemesis/replay_attack.d.ts.map +1 -0
- package/dist/nemesis/replay_attack.js +60 -0
- package/dist/nemesis/replay_attack.js.map +1 -0
- package/dist/nemesis/types.d.ts +160 -0
- package/dist/nemesis/types.d.ts.map +1 -0
- package/dist/nemesis/types.js +9 -0
- package/dist/nemesis/types.js.map +1 -0
- package/dist/nemesis/watermark.d.ts +32 -0
- package/dist/nemesis/watermark.d.ts.map +1 -0
- package/dist/nemesis/watermark.js +83 -0
- package/dist/nemesis/watermark.js.map +1 -0
- package/dist/truth_gate/claims.d.ts.map +1 -1
- package/dist/truth_gate/claims.js +10 -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 +126 -0
- package/dist/truth_gate/probes.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v2.47.0 — CALIBRATED CLASSIFIER (production-grade).
|
|
3
|
+
*
|
|
4
|
+
* Replaces v2.46.0's fixed-weight heuristic with a per-vendor
|
|
5
|
+
* Mahalanobis-style log-likelihood score derived from the seed
|
|
6
|
+
* calibration corpus + the (opt-in) self-calibrating learning ledger.
|
|
7
|
+
*
|
|
8
|
+
* Algorithm:
|
|
9
|
+
* For each vendor V with stats {feature_i: (mean_i, stdev_i)}:
|
|
10
|
+
* logL(fp | V) = − Σ_i ((fp[i] − mean_i) / max(stdev_i, ε))²
|
|
11
|
+
*
|
|
12
|
+
* Top vendor = argmax logL. Confidence = softmax(logL) of the top.
|
|
13
|
+
*
|
|
14
|
+
* Only DISCRIMINATIVE features are used (the ones with high inter-vendor
|
|
15
|
+
* variance) — others would just add noise. We compute discriminativeness
|
|
16
|
+
* dynamically per feature.
|
|
17
|
+
*
|
|
18
|
+
* Falls back to v2.46.0 heuristic classifier when seed stats unavailable
|
|
19
|
+
* (e.g. user has deleted the corpus). Defensive: never throws.
|
|
20
|
+
*/
|
|
21
|
+
import { seedStats, buildSeedCorpus } from "./calibration_corpus.js";
|
|
22
|
+
import { classifyAgent as heuristicClassify } from "./classifier.js";
|
|
23
|
+
import { extractFingerprint } from "./features.js";
|
|
24
|
+
const EPSILON_FLOOR = 1e-3;
|
|
25
|
+
/** Cap per-feature z² so a single zero-stdev mismatch can't dominate. */
|
|
26
|
+
const Z_SQUARED_CAP = 100;
|
|
27
|
+
/** EPSILON_FLOOR for any feature with stdev<= this threshold is set to 10% of mean (or floor). */
|
|
28
|
+
function effectiveStdev(mean, stdev) {
|
|
29
|
+
if (stdev > EPSILON_FLOOR)
|
|
30
|
+
return stdev;
|
|
31
|
+
// Zero-stdev: scale to mean's magnitude so features with large means don't
|
|
32
|
+
// produce absurd z-scores. If mean is also tiny, use floor.
|
|
33
|
+
const relative = Math.abs(mean) * 0.10;
|
|
34
|
+
return Math.max(relative, EPSILON_FLOOR);
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Compute discriminativeness per feature: ratio of cross-vendor mean
|
|
38
|
+
* variance to within-vendor variance. Higher = more discriminative.
|
|
39
|
+
* Features with discriminativeness < threshold are excluded from scoring.
|
|
40
|
+
*/
|
|
41
|
+
function discriminativeFeatures(statsMap, minDiscrim = 0.5) {
|
|
42
|
+
const featureKeys = new Set();
|
|
43
|
+
for (const s of statsMap.values())
|
|
44
|
+
for (const k of Object.keys(s.features))
|
|
45
|
+
featureKeys.add(k);
|
|
46
|
+
const out = [];
|
|
47
|
+
for (const k of featureKeys) {
|
|
48
|
+
const means = [];
|
|
49
|
+
const stdevs = [];
|
|
50
|
+
for (const s of statsMap.values()) {
|
|
51
|
+
const f = s.features[k];
|
|
52
|
+
if (!f)
|
|
53
|
+
continue;
|
|
54
|
+
means.push(f.mean);
|
|
55
|
+
stdevs.push(f.stdev);
|
|
56
|
+
}
|
|
57
|
+
if (means.length < 2)
|
|
58
|
+
continue;
|
|
59
|
+
const meanOfMeans = means.reduce((a, b) => a + b, 0) / means.length;
|
|
60
|
+
const meansVar = means.reduce((s, m) => s + (m - meanOfMeans) ** 2, 0) / means.length;
|
|
61
|
+
const meanStdev = stdevs.reduce((a, b) => a + b, 0) / stdevs.length;
|
|
62
|
+
const denom = meanStdev * meanStdev + EPSILON_FLOOR;
|
|
63
|
+
const discrim = meansVar / denom;
|
|
64
|
+
if (discrim >= minDiscrim)
|
|
65
|
+
out.push(k);
|
|
66
|
+
}
|
|
67
|
+
return out;
|
|
68
|
+
}
|
|
69
|
+
let _cachedDiscrim = null;
|
|
70
|
+
function getDiscriminativeFeatures() {
|
|
71
|
+
if (_cachedDiscrim)
|
|
72
|
+
return _cachedDiscrim;
|
|
73
|
+
try {
|
|
74
|
+
_cachedDiscrim = discriminativeFeatures(seedStats());
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
_cachedDiscrim = [];
|
|
78
|
+
}
|
|
79
|
+
return _cachedDiscrim;
|
|
80
|
+
}
|
|
81
|
+
export function __resetCalibratedCacheForTest() { _cachedDiscrim = null; }
|
|
82
|
+
/**
|
|
83
|
+
* Calibrated log-likelihood score per vendor. Pure deterministic.
|
|
84
|
+
*/
|
|
85
|
+
function scoreCalibrated(fp) {
|
|
86
|
+
const stats = (() => { try {
|
|
87
|
+
return seedStats();
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
return new Map();
|
|
91
|
+
} })();
|
|
92
|
+
if (stats.size === 0)
|
|
93
|
+
return { scores: {}, discrim: [] };
|
|
94
|
+
const discrim = getDiscriminativeFeatures();
|
|
95
|
+
if (discrim.length === 0)
|
|
96
|
+
return { scores: {}, discrim };
|
|
97
|
+
const scores = {};
|
|
98
|
+
const fpObj = fp;
|
|
99
|
+
for (const [vendor, vstats] of stats) {
|
|
100
|
+
let logL = 0;
|
|
101
|
+
for (const k of discrim) {
|
|
102
|
+
const f = vstats.features[k];
|
|
103
|
+
if (!f)
|
|
104
|
+
continue;
|
|
105
|
+
const sd = effectiveStdev(f.mean, f.stdev);
|
|
106
|
+
const z = (Number(fpObj[k] ?? 0) - f.mean) / sd;
|
|
107
|
+
const zSq = Math.min(Z_SQUARED_CAP, z * z);
|
|
108
|
+
logL -= zSq;
|
|
109
|
+
}
|
|
110
|
+
scores[vendor] = logL;
|
|
111
|
+
}
|
|
112
|
+
return { scores, discrim };
|
|
113
|
+
}
|
|
114
|
+
function softmaxTop(scores) {
|
|
115
|
+
const entries = Object.entries(scores);
|
|
116
|
+
if (entries.length === 0)
|
|
117
|
+
return { topVendor: "unknown", confidence: 0 };
|
|
118
|
+
const maxLogL = Math.max(...entries.map(([, v]) => v));
|
|
119
|
+
const exps = entries.map(([k, v]) => [k, Math.exp((v - maxLogL) / Math.max(1, entries.length))]);
|
|
120
|
+
const sum = exps.reduce((s, [, v]) => s + v, 0);
|
|
121
|
+
const sorted = exps.sort((a, b) => b[1] - a[1]);
|
|
122
|
+
const top = sorted[0];
|
|
123
|
+
return { topVendor: top[0], confidence: sum === 0 ? 0 : top[1] / sum };
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Calibrated classification. Falls back to v2.46.0 heuristic when the
|
|
127
|
+
* calibration corpus is unavailable.
|
|
128
|
+
*/
|
|
129
|
+
export function classifyAgentCalibrated(fp) {
|
|
130
|
+
const { scores, discrim } = scoreCalibrated(fp);
|
|
131
|
+
if (Object.keys(scores).length === 0) {
|
|
132
|
+
// Fallback to heuristic; tag the reasoning so callers know
|
|
133
|
+
const fallback = heuristicClassify(fp);
|
|
134
|
+
return { ...fallback, reasoning: `heuristic fallback (no seed corpus): ${fallback.reasoning}` };
|
|
135
|
+
}
|
|
136
|
+
const { topVendor, confidence } = softmaxTop(scores);
|
|
137
|
+
const driving = discrim.slice(0, 3).join(", ");
|
|
138
|
+
return {
|
|
139
|
+
topVendor,
|
|
140
|
+
confidence,
|
|
141
|
+
scores,
|
|
142
|
+
reasoning: `calibrated log-likelihood over ${discrim.length} discriminative features (top: ${driving}); top vendor ${topVendor} (conf ${confidence.toFixed(2)})`,
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
export function evaluateSeedAccuracy() {
|
|
146
|
+
const entries = buildSeedCorpus();
|
|
147
|
+
const perVendor = {};
|
|
148
|
+
let total = 0;
|
|
149
|
+
let correct = 0;
|
|
150
|
+
for (const e of entries) {
|
|
151
|
+
const fp = extractFingerprint(e.fixture);
|
|
152
|
+
const v = classifyAgentCalibrated(fp);
|
|
153
|
+
const isCorrect = v.topVendor === e.vendor;
|
|
154
|
+
total++;
|
|
155
|
+
if (isCorrect)
|
|
156
|
+
correct++;
|
|
157
|
+
const pv = perVendor[e.vendor] ?? { total: 0, correct: 0, accuracy: 0 };
|
|
158
|
+
pv.total++;
|
|
159
|
+
if (isCorrect)
|
|
160
|
+
pv.correct++;
|
|
161
|
+
pv.accuracy = pv.correct / pv.total;
|
|
162
|
+
perVendor[e.vendor] = pv;
|
|
163
|
+
}
|
|
164
|
+
return { total, correct, accuracy: total === 0 ? 0 : correct / total, perVendor };
|
|
165
|
+
}
|
|
166
|
+
//# sourceMappingURL=classifier_calibrated.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"classifier_calibrated.js","sourceRoot":"","sources":["../../src/nemesis/classifier_calibrated.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAGH,OAAO,EAAE,SAAS,EAAE,eAAe,EAAoB,MAAM,yBAAyB,CAAC;AACvF,OAAO,EAAE,aAAa,IAAI,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACrE,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAEnD,MAAM,aAAa,GAAG,IAAI,CAAC;AAC3B,yEAAyE;AACzE,MAAM,aAAa,GAAG,GAAG,CAAC;AAC1B,kGAAkG;AAClG,SAAS,cAAc,CAAC,IAAY,EAAE,KAAa;IACjD,IAAI,KAAK,GAAG,aAAa;QAAE,OAAO,KAAK,CAAC;IACxC,2EAA2E;IAC3E,4DAA4D;IAC5D,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IACvC,OAAO,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;AAC3C,CAAC;AAED;;;;GAIG;AACH,SAAS,sBAAsB,CAAC,QAAoC,EAAE,UAAU,GAAG,GAAG;IACpF,MAAM,WAAW,GAAG,IAAI,GAAG,EAAU,CAAC;IACtC,KAAK,MAAM,CAAC,IAAI,QAAQ,CAAC,MAAM,EAAE;QAAE,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC;YAAE,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAC/F,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,KAAK,MAAM,CAAC,IAAI,WAAW,EAAE,CAAC;QAC5B,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,KAAK,MAAM,CAAC,IAAI,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC;YAClC,MAAM,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;YACxB,IAAI,CAAC,CAAC;gBAAE,SAAS;YACjB,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YACnB,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QACvB,CAAC;QACD,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;YAAE,SAAS;QAC/B,MAAM,WAAW,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC;QACpE,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC;QACtF,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC;QACpE,MAAM,KAAK,GAAG,SAAS,GAAG,SAAS,GAAG,aAAa,CAAC;QACpD,MAAM,OAAO,GAAG,QAAQ,GAAG,KAAK,CAAC;QACjC,IAAI,OAAO,IAAI,UAAU;YAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACzC,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,IAAI,cAAc,GAAoB,IAAI,CAAC;AAC3C,SAAS,yBAAyB;IAChC,IAAI,cAAc;QAAE,OAAO,cAAc,CAAC;IAC1C,IAAI,CAAC;QACH,cAAc,GAAG,sBAAsB,CAAC,SAAS,EAAE,CAAC,CAAC;IACvD,CAAC;IAAC,MAAM,CAAC;QACP,cAAc,GAAG,EAAE,CAAC;IACtB,CAAC;IACD,OAAO,cAAc,CAAC;AACxB,CAAC;AAED,MAAM,UAAU,6BAA6B,KAAW,cAAc,GAAG,IAAI,CAAC,CAAC,CAAC;AAEhF;;GAEG;AACH,SAAS,eAAe,CAAC,EAAe;IACtC,MAAM,KAAK,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;QAAC,OAAO,SAAS,EAAE,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC;QAAC,OAAO,IAAI,GAAG,EAAyB,CAAC;IAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC3G,IAAI,KAAK,CAAC,IAAI,KAAK,CAAC;QAAE,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;IACzD,MAAM,OAAO,GAAG,yBAAyB,EAAE,CAAC;IAC5C,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC;IACzD,MAAM,MAAM,GAAsC,EAAE,CAAC;IACrD,MAAM,KAAK,GAAG,EAAuC,CAAC;IACtD,KAAK,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACrC,IAAI,IAAI,GAAG,CAAC,CAAC;QACb,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;YACxB,MAAM,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;YAC7B,IAAI,CAAC,CAAC;gBAAE,SAAS;YACjB,MAAM,EAAE,GAAG,cAAc,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC;YAC3C,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;YAChD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;YAC3C,IAAI,IAAI,GAAG,CAAC;QACd,CAAC;QACD,MAAM,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;IACxB,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;AAC7B,CAAC;AAED,SAAS,UAAU,CAAC,MAAyC;IAC3D,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAA8B,CAAC;IACpE,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC;IACzE,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IACvD,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAuB,CAAC,CAAC;IACvH,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;IAChD,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAChD,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC,CAAE,CAAC;IACvB,OAAO,EAAE,SAAS,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,EAAE,CAAC;AACzE,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,uBAAuB,CAAC,EAAe;IACrD,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,eAAe,CAAC,EAAE,CAAC,CAAC;IAChD,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACrC,2DAA2D;QAC3D,MAAM,QAAQ,GAAG,iBAAiB,CAAC,EAAE,CAAC,CAAC;QACvC,OAAO,EAAE,GAAG,QAAQ,EAAE,SAAS,EAAE,wCAAwC,QAAQ,CAAC,SAAS,EAAE,EAAE,CAAC;IAClG,CAAC;IACD,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;IACrD,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC/C,OAAO;QACL,SAAS;QACT,UAAU;QACV,MAAM;QACN,SAAS,EAAE,kCAAkC,OAAO,CAAC,MAAM,kCAAkC,OAAO,iBAAiB,SAAS,UAAU,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG;KACjK,CAAC;AACJ,CAAC;AAkBD,MAAM,UAAU,oBAAoB;IAClC,MAAM,OAAO,GAAG,eAAe,EAAE,CAAC;IAClC,MAAM,SAAS,GAAgC,EAAE,CAAC;IAClD,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,MAAM,EAAE,GAAG,kBAAkB,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;QACzC,MAAM,CAAC,GAAG,uBAAuB,CAAC,EAAE,CAAC,CAAC;QACtC,MAAM,SAAS,GAAG,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,MAAM,CAAC;QAC3C,KAAK,EAAE,CAAC;QACR,IAAI,SAAS;YAAE,OAAO,EAAE,CAAC;QACzB,MAAM,EAAE,GAAG,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC;QACxE,EAAE,CAAC,KAAK,EAAE,CAAC;QACX,IAAI,SAAS;YAAE,EAAE,CAAC,OAAO,EAAE,CAAC;QAC5B,EAAE,CAAC,QAAQ,GAAG,EAAE,CAAC,OAAO,GAAG,EAAE,CAAC,KAAK,CAAC;QACpC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;IAC3B,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,GAAG,KAAK,EAAE,SAAS,EAAE,CAAC;AACpF,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v2.46.0 — NEMESIS ORGAN 4: MODEL DRIFT TIMELINE.
|
|
3
|
+
*
|
|
4
|
+
* Records each fingerprint per vendor over time + computes variance.
|
|
5
|
+
* When a vendor's fingerprint distribution shifts past N standard
|
|
6
|
+
* deviations, NEMESIS surfaces "vendor X changed personality on Y".
|
|
7
|
+
*
|
|
8
|
+
* Ledger: `.mneme/nemesis/drift-<vendor>.jsonl` — one row per recorded
|
|
9
|
+
* fingerprint, capped at 200 most-recent rows per vendor.
|
|
10
|
+
*/
|
|
11
|
+
export interface DriftEntry {
|
|
12
|
+
at: string;
|
|
13
|
+
vendor: string;
|
|
14
|
+
fingerprint: Record<string, number>;
|
|
15
|
+
}
|
|
16
|
+
export interface VarianceResult {
|
|
17
|
+
feature: string;
|
|
18
|
+
vendor: string;
|
|
19
|
+
mean: number;
|
|
20
|
+
stdev: number;
|
|
21
|
+
/** Most recent value of the feature. */
|
|
22
|
+
latest: number;
|
|
23
|
+
/** Z-score of the latest vs the prior distribution. */
|
|
24
|
+
z: number;
|
|
25
|
+
driftDetected: boolean;
|
|
26
|
+
/** ISO timestamp of the drift event (the latest entry). */
|
|
27
|
+
driftAt?: string;
|
|
28
|
+
}
|
|
29
|
+
export declare function recordFingerprint(repoRoot: string, vendor: string, fingerprint: Record<string, number>): {
|
|
30
|
+
ok: boolean;
|
|
31
|
+
reason?: string;
|
|
32
|
+
};
|
|
33
|
+
export declare function readTimeline(repoRoot: string, vendor: string): DriftEntry[];
|
|
34
|
+
export declare function computeVariance(repoRoot: string, vendor: string, feature: string): VarianceResult;
|
|
35
|
+
//# sourceMappingURL=drift_timeline.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"drift_timeline.d.ts","sourceRoot":"","sources":["../../src/nemesis/drift_timeline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAQH,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACrC;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,wCAAwC;IACxC,MAAM,EAAE,MAAM,CAAC;IACf,uDAAuD;IACvD,CAAC,EAAE,MAAM,CAAC;IACV,aAAa,EAAE,OAAO,CAAC;IACvB,2DAA2D;IAC3D,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAYD,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAoBzI;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,UAAU,EAAE,CAY3E;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,cAAc,CAyBjG"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v2.46.0 — NEMESIS ORGAN 4: MODEL DRIFT TIMELINE.
|
|
3
|
+
*
|
|
4
|
+
* Records each fingerprint per vendor over time + computes variance.
|
|
5
|
+
* When a vendor's fingerprint distribution shifts past N standard
|
|
6
|
+
* deviations, NEMESIS surfaces "vendor X changed personality on Y".
|
|
7
|
+
*
|
|
8
|
+
* Ledger: `.mneme/nemesis/drift-<vendor>.jsonl` — one row per recorded
|
|
9
|
+
* fingerprint, capped at 200 most-recent rows per vendor.
|
|
10
|
+
*/
|
|
11
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync, appendFileSync } from "node:fs";
|
|
12
|
+
import { join } from "node:path";
|
|
13
|
+
const LEDGER_CAP = 200;
|
|
14
|
+
const DRIFT_SIGMA_THRESHOLD = 3; // 3σ = "real" drift
|
|
15
|
+
function dirOf(repoRoot) {
|
|
16
|
+
const dir = join(repoRoot, ".mneme", "nemesis");
|
|
17
|
+
if (!existsSync(dir)) {
|
|
18
|
+
try {
|
|
19
|
+
mkdirSync(dir, { recursive: true });
|
|
20
|
+
}
|
|
21
|
+
catch { /* */ }
|
|
22
|
+
}
|
|
23
|
+
return dir;
|
|
24
|
+
}
|
|
25
|
+
function safeVendor(v) {
|
|
26
|
+
return v.replace(/[^a-zA-Z0-9._-]/g, "_") || "anonymous";
|
|
27
|
+
}
|
|
28
|
+
export function recordFingerprint(repoRoot, vendor, fingerprint) {
|
|
29
|
+
try {
|
|
30
|
+
const ledger = join(dirOf(repoRoot), `drift-${safeVendor(vendor)}.jsonl`);
|
|
31
|
+
const entry = { at: new Date().toISOString(), vendor, fingerprint };
|
|
32
|
+
// Roll the ledger if it's at cap.
|
|
33
|
+
if (existsSync(ledger)) {
|
|
34
|
+
try {
|
|
35
|
+
const body = readFileSync(ledger, "utf8");
|
|
36
|
+
const lines = body.split("\n").filter(Boolean);
|
|
37
|
+
if (lines.length >= LEDGER_CAP) {
|
|
38
|
+
const trimmed = lines.slice(-(LEDGER_CAP - 1));
|
|
39
|
+
writeFileSync(ledger, trimmed.join("\n") + "\n");
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
catch { /* */ }
|
|
43
|
+
}
|
|
44
|
+
appendFileSync(ledger, JSON.stringify(entry) + "\n");
|
|
45
|
+
return { ok: true };
|
|
46
|
+
}
|
|
47
|
+
catch (e) {
|
|
48
|
+
return { ok: false, reason: e.message };
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
export function readTimeline(repoRoot, vendor) {
|
|
52
|
+
try {
|
|
53
|
+
const ledger = join(dirOf(repoRoot), `drift-${safeVendor(vendor)}.jsonl`);
|
|
54
|
+
if (!existsSync(ledger))
|
|
55
|
+
return [];
|
|
56
|
+
const body = readFileSync(ledger, "utf8");
|
|
57
|
+
const out = [];
|
|
58
|
+
for (const ln of body.split("\n")) {
|
|
59
|
+
if (!ln.trim())
|
|
60
|
+
continue;
|
|
61
|
+
try {
|
|
62
|
+
out.push(JSON.parse(ln));
|
|
63
|
+
}
|
|
64
|
+
catch { /* skip */ }
|
|
65
|
+
}
|
|
66
|
+
return out;
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
return [];
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
export function computeVariance(repoRoot, vendor, feature) {
|
|
73
|
+
const tl = readTimeline(repoRoot, vendor);
|
|
74
|
+
if (tl.length === 0) {
|
|
75
|
+
return { feature, vendor, mean: 0, stdev: 0, latest: 0, z: 0, driftDetected: false };
|
|
76
|
+
}
|
|
77
|
+
const values = tl.map((e) => Number(e.fingerprint[feature] ?? 0)).filter((n) => Number.isFinite(n));
|
|
78
|
+
if (values.length === 0) {
|
|
79
|
+
return { feature, vendor, mean: 0, stdev: 0, latest: 0, z: 0, driftDetected: false };
|
|
80
|
+
}
|
|
81
|
+
// Compute mean + stdev of all-but-latest, compare latest against that distribution.
|
|
82
|
+
const latestValue = values[values.length - 1];
|
|
83
|
+
const priorValues = values.slice(0, -1);
|
|
84
|
+
if (priorValues.length < 2) {
|
|
85
|
+
return { feature, vendor, mean: latestValue, stdev: 0, latest: latestValue, z: 0, driftDetected: false };
|
|
86
|
+
}
|
|
87
|
+
const mean = priorValues.reduce((a, b) => a + b, 0) / priorValues.length;
|
|
88
|
+
const variance = priorValues.reduce((s, v) => s + (v - mean) ** 2, 0) / priorValues.length;
|
|
89
|
+
const stdev = Math.sqrt(variance);
|
|
90
|
+
const z = stdev === 0 ? 0 : Math.abs(latestValue - mean) / stdev;
|
|
91
|
+
const driftDetected = z >= DRIFT_SIGMA_THRESHOLD && stdev > 0;
|
|
92
|
+
return {
|
|
93
|
+
feature, vendor, mean, stdev, latest: latestValue, z,
|
|
94
|
+
driftDetected,
|
|
95
|
+
driftAt: driftDetected ? tl[tl.length - 1].at : undefined,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=drift_timeline.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"drift_timeline.js","sourceRoot":"","sources":["../../src/nemesis/drift_timeline.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v2.46.0 — NEMESIS ORGAN 1 addon: ENV-SCAN.
|
|
3
|
+
*
|
|
4
|
+
* Each AI coding agent sets a recognizable env var when it spawns
|
|
5
|
+
* child processes. Detecting these is the cheapest + most reliable
|
|
6
|
+
* vendor signal — zero false positives, zero ML needed.
|
|
7
|
+
*
|
|
8
|
+
* Public sources:
|
|
9
|
+
* CLAUDECODE = "1" Claude Code
|
|
10
|
+
* CLAUDE_CODE_* = Claude Code
|
|
11
|
+
* CURSOR_AGENT = "1" Cursor
|
|
12
|
+
* CURSOR_TRACE_ID Cursor
|
|
13
|
+
* CONTINUE_* Continue.dev
|
|
14
|
+
* GITHUB_COPILOT_* GitHub Copilot CLI
|
|
15
|
+
* COPILOT_AGENT Copilot Workspace
|
|
16
|
+
* AIDER_* Aider
|
|
17
|
+
* GEMINI_CLI Gemini CLI
|
|
18
|
+
* DEVIN_SESSION Devin
|
|
19
|
+
* ANTHROPIC_API_KEY Claude API
|
|
20
|
+
* OPENAI_API_KEY OpenAI / Codex
|
|
21
|
+
* CODER_* Coder
|
|
22
|
+
* WINDSURF_* Windsurf / Codeium
|
|
23
|
+
*
|
|
24
|
+
* Pure deterministic; reads only the env object passed in (default
|
|
25
|
+
* process.env). NEVER throws.
|
|
26
|
+
*/
|
|
27
|
+
import type { VendorId } from "./types.js";
|
|
28
|
+
export interface EnvScanResult {
|
|
29
|
+
vendor: VendorId;
|
|
30
|
+
/** Confidence ∈ [0, 1]. */
|
|
31
|
+
confidence: number;
|
|
32
|
+
/** Per-marker evidence. */
|
|
33
|
+
evidence: Array<{
|
|
34
|
+
key: string;
|
|
35
|
+
value: string;
|
|
36
|
+
vendor: VendorId;
|
|
37
|
+
}>;
|
|
38
|
+
}
|
|
39
|
+
export declare function scanEnv(env?: NodeJS.ProcessEnv | Record<string, string | undefined>): EnvScanResult;
|
|
40
|
+
//# sourceMappingURL=env_scan.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env_scan.d.ts","sourceRoot":"","sources":["../../src/nemesis/env_scan.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAyB3C,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,QAAQ,CAAC;IACjB,2BAA2B;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,2BAA2B;IAC3B,QAAQ,EAAE,KAAK,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,QAAQ,CAAA;KAAE,CAAC,CAAC;CACnE;AAED,wBAAgB,OAAO,CAAC,GAAG,GAAE,MAAM,CAAC,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAe,GAAG,aAAa,CA0BhH"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v2.46.0 — NEMESIS ORGAN 1 addon: ENV-SCAN.
|
|
3
|
+
*
|
|
4
|
+
* Each AI coding agent sets a recognizable env var when it spawns
|
|
5
|
+
* child processes. Detecting these is the cheapest + most reliable
|
|
6
|
+
* vendor signal — zero false positives, zero ML needed.
|
|
7
|
+
*
|
|
8
|
+
* Public sources:
|
|
9
|
+
* CLAUDECODE = "1" Claude Code
|
|
10
|
+
* CLAUDE_CODE_* = Claude Code
|
|
11
|
+
* CURSOR_AGENT = "1" Cursor
|
|
12
|
+
* CURSOR_TRACE_ID Cursor
|
|
13
|
+
* CONTINUE_* Continue.dev
|
|
14
|
+
* GITHUB_COPILOT_* GitHub Copilot CLI
|
|
15
|
+
* COPILOT_AGENT Copilot Workspace
|
|
16
|
+
* AIDER_* Aider
|
|
17
|
+
* GEMINI_CLI Gemini CLI
|
|
18
|
+
* DEVIN_SESSION Devin
|
|
19
|
+
* ANTHROPIC_API_KEY Claude API
|
|
20
|
+
* OPENAI_API_KEY OpenAI / Codex
|
|
21
|
+
* CODER_* Coder
|
|
22
|
+
* WINDSURF_* Windsurf / Codeium
|
|
23
|
+
*
|
|
24
|
+
* Pure deterministic; reads only the env object passed in (default
|
|
25
|
+
* process.env). NEVER throws.
|
|
26
|
+
*/
|
|
27
|
+
const MARKERS = [
|
|
28
|
+
{ key: "CLAUDECODE", vendor: "claude-code", match: (v) => v === "1" || v.toLowerCase() === "true" },
|
|
29
|
+
{ key: "CLAUDE_CODE_ENTRYPOINT", vendor: "claude-code" },
|
|
30
|
+
{ key: "CLAUDE_CODE_SSE_PORT", vendor: "claude-code" },
|
|
31
|
+
{ key: "CURSOR_AGENT", vendor: "cursor", match: (v) => v === "1" || v.toLowerCase() === "true" },
|
|
32
|
+
{ key: "CURSOR_TRACE_ID", vendor: "cursor" },
|
|
33
|
+
{ key: "COPILOT_AGENT", vendor: "copilot" },
|
|
34
|
+
{ key: "GH_COPILOT_TOKEN", vendor: "copilot" },
|
|
35
|
+
{ key: "GITHUB_COPILOT_CLI", vendor: "copilot" },
|
|
36
|
+
{ key: "DEVIN_SESSION", vendor: "devin" },
|
|
37
|
+
{ key: "DEVIN_API_KEY", vendor: "devin" },
|
|
38
|
+
// Codex CLI uses OpenAI's CLI ARG conventions but env shape is OPENAI_*
|
|
39
|
+
// We only flag codex when OPENAI_API_KEY + a CODEX-specific marker.
|
|
40
|
+
{ key: "OPENAI_CODEX", vendor: "codex" },
|
|
41
|
+
{ key: "CODEX_AGENT", vendor: "codex" },
|
|
42
|
+
];
|
|
43
|
+
export function scanEnv(env = process.env) {
|
|
44
|
+
const evidence = [];
|
|
45
|
+
const perVendor = {};
|
|
46
|
+
try {
|
|
47
|
+
for (const m of MARKERS) {
|
|
48
|
+
const v = env[m.key];
|
|
49
|
+
if (typeof v !== "string" || v.length === 0)
|
|
50
|
+
continue;
|
|
51
|
+
if (m.match && !m.match(v))
|
|
52
|
+
continue;
|
|
53
|
+
evidence.push({ key: m.key, value: v.slice(0, 32), vendor: m.vendor });
|
|
54
|
+
perVendor[m.vendor] = (perVendor[m.vendor] ?? 0) + 1;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
catch { /* defensive */ }
|
|
58
|
+
if (evidence.length === 0) {
|
|
59
|
+
return { vendor: "unknown", confidence: 0, evidence: [] };
|
|
60
|
+
}
|
|
61
|
+
// Pick the vendor with the most distinct markers.
|
|
62
|
+
let top = "unknown";
|
|
63
|
+
let topN = 0;
|
|
64
|
+
for (const [v, n] of Object.entries(perVendor)) {
|
|
65
|
+
if ((n ?? 0) > topN) {
|
|
66
|
+
topN = n ?? 0;
|
|
67
|
+
top = v;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
const total = Object.values(perVendor).reduce((a, b) => a + (b ?? 0), 0);
|
|
71
|
+
const confidence = total === 0 ? 0 : topN / total;
|
|
72
|
+
return { vendor: top, confidence, evidence };
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=env_scan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env_scan.js","sourceRoot":"","sources":["../../src/nemesis/env_scan.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
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 type { Article50StampInput, StampResult, VerifyStampResult } from "./types.js";
|
|
24
|
+
export declare function stampArticle50(input: Article50StampInput): StampResult;
|
|
25
|
+
/**
|
|
26
|
+
* Parse a stamped message + HMAC-verify. Returns valid=false on any
|
|
27
|
+
* tamper / missing field / regex mismatch.
|
|
28
|
+
*/
|
|
29
|
+
export declare function verifyStamp(stampedMessage: string): VerifyStampResult;
|
|
30
|
+
//# sourceMappingURL=eu_ai_act_stamp.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eu_ai_act_stamp.d.ts","sourceRoot":"","sources":["../../src/nemesis/eu_ai_act_stamp.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAGH,OAAO,KAAK,EACM,mBAAmB,EAAE,WAAW,EAAE,iBAAiB,EACpE,MAAM,YAAY,CAAC;AAmBpB,wBAAgB,cAAc,CAAC,KAAK,EAAE,mBAAmB,GAAG,WAAW,CAkCtE;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,cAAc,EAAE,MAAM,GAAG,iBAAiB,CA+BrE"}
|
|
@@ -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":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAKzC,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,IAAI,iCAAiC,CAAC;AACvF,MAAM,MAAM,GAAG,gBAAgB,CAAC;AAChC,MAAM,OAAO,GAAG,IAAI,CAAC;AAErB,SAAS,kBAAkB,CAAC,CAA+B,EAAE,OAAe;IAC1E,mDAAmD;IACnD,OAAO,IAAI,CAAC,SAAS,CAAC;QACpB,OAAO,EAAE,CAAC,CAAC,OAAO;QAClB,EAAE,EAAE,CAAC,CAAC,EAAE;QACR,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QAC3C,WAAW,EAAE,CAAC,CAAC,WAAW;QAC1B,OAAO;QACP,MAAM,EAAE,CAAC,CAAC,MAAM;QAChB,MAAM,EAAE,CAAC,CAAC,MAAM;KACjB,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,KAA0B;IACvD,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,CAAC,MAAM,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5E,OAAO;YACL,EAAE,EAAE,KAAK;YACT,MAAM,EAAE,4DAA4D;YACpE,cAAc,EAAE,KAAK,EAAE,OAAO,IAAI,EAAE;YACpC,KAAK,EAAE;gBACL,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE,WAAW,EAAE,oBAAoB;gBACpE,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO;aAC3C;SACF,CAAC;IACJ,CAAC;IACD,MAAM,EAAE,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACpC,MAAM,WAAW,GAAG,KAAK,CAAC,WAAW,IAAI,oBAAoB,CAAC;IAC9D,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,UAAU,IAAI,CAAC,CAAC,CAAC,CAAC;IACnE,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,IAAI,EAAE,CAAC;IACpC,MAAM,IAAI,GAAiC;QACzC,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO;KACpF,CAAC;IACF,MAAM,IAAI,GAAG,UAAU,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,MAAM,CAAC,kBAAkB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACjH,MAAM,KAAK,GAAmB,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,CAAC;IAChD,MAAM,KAAK,GAAG;QACZ,EAAE;QACF,2BAA2B;QAC3B,UAAU,MAAM,YAAY,OAAO,WAAW,KAAK,CAAC,MAAM,eAAe,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE;QAChG,gBAAgB,WAAW,OAAO,EAAE,EAAE;QACtC,QAAQ,IAAI,EAAE;QACd,KAAK;KACN,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACb,OAAO;QACL,EAAE,EAAE,IAAI;QACR,cAAc,EAAE,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,OAAO,GAAG,IAAI,GAAG,KAAK;QACjF,KAAK;KACN,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,cAAsB;IAChD,IAAI,CAAC,cAAc;QAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC;IACpE,MAAM,UAAU,GAAG,cAAc,CAAC,KAAK,CAAC,gDAAgD,CAAC,CAAC;IAC1F,IAAI,CAAC,UAAU;QAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,qCAAqC,EAAE,CAAC;IACxF,MAAM,KAAK,GAAG,UAAU,CAAC,CAAC,CAAE,CAAC;IAC7B,MAAM,IAAI,GAAG,CAAC,GAAW,EAAiB,EAAE;QAC1C,MAAM,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,YAAY,GAAG,SAAS,CAAC,CAAC,CAAC;QAC5D,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IAC1B,CAAC,CAAC;IACF,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC9B,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC;IAChC,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC9B,MAAM,UAAU,GAAG,IAAI,CAAC,YAAY,CAAC,CAAC;IACtC,MAAM,WAAW,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC;IACzC,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC;IACtB,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC;IAC1B,IAAI,CAAC,MAAM,IAAI,CAAC,OAAO,IAAI,CAAC,MAAM,IAAI,CAAC,UAAU,IAAI,CAAC,WAAW,IAAI,CAAC,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC;QAClF,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,yCAAyC,CAAC,CAAC,MAAM,YAAY,CAAC,CAAC,OAAO,WAAW,CAAC,CAAC,MAAM,eAAe,CAAC,CAAC,UAAU,gBAAgB,CAAC,CAAC,WAAW,OAAO,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;IACjN,CAAC;IACD,IAAI,MAAM,KAAK,MAAM;QAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,6BAA6B,MAAM,SAAS,MAAM,EAAE,EAAE,CAAC;IAC7G,IAAI,OAAO,KAAK,OAAO;QAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,8BAA8B,OAAO,SAAS,OAAO,EAAE,EAAE,CAAC;IAClH,MAAM,aAAa,GAAG,UAAU,CAAC,UAAU,CAAC,CAAC;IAC7C,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAC;QAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,4BAA4B,EAAE,CAAC;IACnG,iFAAiF;IACjF,MAAM,OAAO,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAC9E,MAAM,IAAI,GAAiC;QACzC,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO;KACrF,CAAC;IACF,MAAM,QAAQ,GAAG,UAAU,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,MAAM,CAAC,kBAAkB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACrH,IAAI,QAAQ,KAAK,IAAI;QAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,oCAAoC,EAAE,CAAC;IAC7F,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC;AACpD,CAAC"}
|
|
@@ -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"}
|