@mneme-ai/core 1.68.0 → 1.70.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/hyperscan/bench.d.ts +32 -0
- package/dist/hyperscan/bench.d.ts.map +1 -0
- package/dist/hyperscan/bench.js +81 -0
- package/dist/hyperscan/bench.js.map +1 -0
- package/dist/hyperscan/cross_citation.d.ts +51 -0
- package/dist/hyperscan/cross_citation.d.ts.map +1 -0
- package/dist/hyperscan/cross_citation.js +140 -0
- package/dist/hyperscan/cross_citation.js.map +1 -0
- package/dist/hyperscan/cross_source_qa.d.ts +49 -0
- package/dist/hyperscan/cross_source_qa.d.ts.map +1 -0
- package/dist/hyperscan/cross_source_qa.js +219 -0
- package/dist/hyperscan/cross_source_qa.js.map +1 -0
- package/dist/hyperscan/hyperscan.test.d.ts +5 -0
- package/dist/hyperscan/hyperscan.test.d.ts.map +1 -0
- package/dist/hyperscan/hyperscan.test.js +191 -0
- package/dist/hyperscan/hyperscan.test.js.map +1 -0
- package/dist/hyperscan/hyperscan_molecule.d.ts +76 -0
- package/dist/hyperscan/hyperscan_molecule.d.ts.map +1 -0
- package/dist/hyperscan/hyperscan_molecule.js +144 -0
- package/dist/hyperscan/hyperscan_molecule.js.map +1 -0
- package/dist/hyperscan/index.d.ts +26 -0
- package/dist/hyperscan/index.d.ts.map +1 -0
- package/dist/hyperscan/index.js +26 -0
- package/dist/hyperscan/index.js.map +1 -0
- package/dist/hyperscan/nucleus_dust_htc.d.ts +71 -0
- package/dist/hyperscan/nucleus_dust_htc.d.ts.map +1 -0
- package/dist/hyperscan/nucleus_dust_htc.js +242 -0
- package/dist/hyperscan/nucleus_dust_htc.js.map +1 -0
- package/dist/hyperscan/prose_shadow.d.ts +50 -0
- package/dist/hyperscan/prose_shadow.d.ts.map +1 -0
- package/dist/hyperscan/prose_shadow.js +225 -0
- package/dist/hyperscan/prose_shadow.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +23 -0
- package/dist/index.js.map +1 -1
- package/dist/precog/bayesian_priors.d.ts +49 -0
- package/dist/precog/bayesian_priors.d.ts.map +1 -0
- package/dist/precog/bayesian_priors.js +135 -0
- package/dist/precog/bayesian_priors.js.map +1 -0
- package/dist/precog/firewall.d.ts +72 -0
- package/dist/precog/firewall.d.ts.map +1 -0
- package/dist/precog/firewall.js +141 -0
- package/dist/precog/firewall.js.map +1 -0
- package/dist/precog/index.d.ts +54 -0
- package/dist/precog/index.d.ts.map +1 -0
- package/dist/precog/index.js +94 -0
- package/dist/precog/index.js.map +1 -0
- package/dist/precog/package_verifier.d.ts +45 -0
- package/dist/precog/package_verifier.d.ts.map +1 -0
- package/dist/precog/package_verifier.js +139 -0
- package/dist/precog/package_verifier.js.map +1 -0
- package/dist/precog/precog.test.d.ts +5 -0
- package/dist/precog/precog.test.d.ts.map +1 -0
- package/dist/precog/precog.test.js +224 -0
- package/dist/precog/precog.test.js.map +1 -0
- package/dist/precog/sha_version_verifier.d.ts +34 -0
- package/dist/precog/sha_version_verifier.d.ts.map +1 -0
- package/dist/precog/sha_version_verifier.js +131 -0
- package/dist/precog/sha_version_verifier.js.map +1 -0
- package/dist/precog/temporal_verifier.d.ts +45 -0
- package/dist/precog/temporal_verifier.d.ts.map +1 -0
- package/dist/precog/temporal_verifier.js +139 -0
- package/dist/precog/temporal_verifier.js.map +1 -0
- package/dist/precog/trust_certificate.d.ts +44 -0
- package/dist/precog/trust_certificate.d.ts.map +1 -0
- package/dist/precog/trust_certificate.js +103 -0
- package/dist/precog/trust_certificate.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v1.70.0 -- PRECOG P3: TEMPORAL VERIFIER.
|
|
3
|
+
*
|
|
4
|
+
* Catches "we deleted X last week" / "yesterday Y was added" / "3
|
|
5
|
+
* days ago we shipped Z" -- temporal claims that need to be
|
|
6
|
+
* corroborated by `git log` within the bounded window.
|
|
7
|
+
*
|
|
8
|
+
* "last week" -> window [now-14d, now-1d]
|
|
9
|
+
* "yesterday" -> window [now-2d, now-1d]
|
|
10
|
+
* "today" -> window [now-1d, now]
|
|
11
|
+
* "3 days ago" -> window [now-4d, now-2d]
|
|
12
|
+
* "last month" -> window [now-45d, now-15d]
|
|
13
|
+
* "X days ago" -> window [now-X-1d, now-X+1d]
|
|
14
|
+
*
|
|
15
|
+
* Verifier checks:
|
|
16
|
+
* 1. Were there ANY commits in the window? (sanity)
|
|
17
|
+
* 2. If claim mentions a verb (add/delete/fix/ship), is there a
|
|
18
|
+
* commit with that verb root in subject within the window?
|
|
19
|
+
* 3. If claim names a file, does git log -- <file> show commits in window?
|
|
20
|
+
*
|
|
21
|
+
* Honest "INSUFFICIENT_EVIDENCE" verdict when window is empty.
|
|
22
|
+
*/
|
|
23
|
+
export interface TemporalReference {
|
|
24
|
+
/** The phrase that triggered the match. */
|
|
25
|
+
phrase: string;
|
|
26
|
+
/** Window start (ms since epoch). */
|
|
27
|
+
fromMs: number;
|
|
28
|
+
/** Window end (ms since epoch). */
|
|
29
|
+
toMs: number;
|
|
30
|
+
offset: number;
|
|
31
|
+
}
|
|
32
|
+
export interface TemporalSuspect {
|
|
33
|
+
ref: TemporalReference;
|
|
34
|
+
reason: string;
|
|
35
|
+
confidence: number;
|
|
36
|
+
}
|
|
37
|
+
export interface TemporalReport {
|
|
38
|
+
refs: TemporalReference[];
|
|
39
|
+
suspects: TemporalSuspect[];
|
|
40
|
+
corroborated: TemporalReference[];
|
|
41
|
+
headline: string;
|
|
42
|
+
}
|
|
43
|
+
export declare function extractTemporalRefs(text: string): TemporalReference[];
|
|
44
|
+
export declare function verifyTemporal(repoRoot: string, text: string): TemporalReport;
|
|
45
|
+
//# sourceMappingURL=temporal_verifier.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"temporal_verifier.d.ts","sourceRoot":"","sources":["../../src/precog/temporal_verifier.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAIH,MAAM,WAAW,iBAAiB;IAChC,2CAA2C;IAC3C,MAAM,EAAE,MAAM,CAAC;IACf,qCAAqC;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,mCAAmC;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,iBAAiB,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,iBAAiB,EAAE,CAAC;IAC1B,QAAQ,EAAE,eAAe,EAAE,CAAC;IAC5B,YAAY,EAAE,iBAAiB,EAAE,CAAC;IAClC,QAAQ,EAAE,MAAM,CAAC;CAClB;AAkBD,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,iBAAiB,EAAE,CA6BrE;AAmCD,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,cAAc,CA0C7E"}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v1.70.0 -- PRECOG P3: TEMPORAL VERIFIER.
|
|
3
|
+
*
|
|
4
|
+
* Catches "we deleted X last week" / "yesterday Y was added" / "3
|
|
5
|
+
* days ago we shipped Z" -- temporal claims that need to be
|
|
6
|
+
* corroborated by `git log` within the bounded window.
|
|
7
|
+
*
|
|
8
|
+
* "last week" -> window [now-14d, now-1d]
|
|
9
|
+
* "yesterday" -> window [now-2d, now-1d]
|
|
10
|
+
* "today" -> window [now-1d, now]
|
|
11
|
+
* "3 days ago" -> window [now-4d, now-2d]
|
|
12
|
+
* "last month" -> window [now-45d, now-15d]
|
|
13
|
+
* "X days ago" -> window [now-X-1d, now-X+1d]
|
|
14
|
+
*
|
|
15
|
+
* Verifier checks:
|
|
16
|
+
* 1. Were there ANY commits in the window? (sanity)
|
|
17
|
+
* 2. If claim mentions a verb (add/delete/fix/ship), is there a
|
|
18
|
+
* commit with that verb root in subject within the window?
|
|
19
|
+
* 3. If claim names a file, does git log -- <file> show commits in window?
|
|
20
|
+
*
|
|
21
|
+
* Honest "INSUFFICIENT_EVIDENCE" verdict when window is empty.
|
|
22
|
+
*/
|
|
23
|
+
import { execSync } from "node:child_process";
|
|
24
|
+
const PHRASE_RES = [
|
|
25
|
+
{ pattern: /\b(today)\b/gi, days: { from: 1, to: 0 } },
|
|
26
|
+
{ pattern: /\b(yesterday)\b/gi, days: { from: 2, to: 1 } },
|
|
27
|
+
{ pattern: /\b(last\s+week)\b/gi, days: { from: 14, to: 1 } },
|
|
28
|
+
{ pattern: /\b(last\s+month)\b/gi, days: { from: 45, to: 15 } },
|
|
29
|
+
{ pattern: /\b(last\s+quarter)\b/gi, days: { from: 120, to: 45 } },
|
|
30
|
+
{ pattern: /\b(this\s+week)\b/gi, days: { from: 7, to: 0 } },
|
|
31
|
+
];
|
|
32
|
+
const N_DAYS_AGO = /\b(\d+)\s+days?\s+ago\b/gi;
|
|
33
|
+
const VERB_PATTERN = /\b(added?|deleted?|removed?|shipped?|fixed?|merged?|reverted?|deployed?|released?|refactored?)\b/gi;
|
|
34
|
+
const FILE_PATTERN = /([\w./_-]+\.(?:ts|tsx|js|mjs|cjs|jsx|json|md|sql|yml|yaml|py|rs|go))/g;
|
|
35
|
+
const DAY_MS = 86400 * 1000;
|
|
36
|
+
export function extractTemporalRefs(text) {
|
|
37
|
+
const out = [];
|
|
38
|
+
const seen = new Set();
|
|
39
|
+
const now = Date.now();
|
|
40
|
+
for (const { pattern, days } of PHRASE_RES) {
|
|
41
|
+
for (const m of text.matchAll(pattern)) {
|
|
42
|
+
const phrase = m[1].toLowerCase();
|
|
43
|
+
const key = `${phrase}|${m.index}`;
|
|
44
|
+
if (seen.has(key))
|
|
45
|
+
continue;
|
|
46
|
+
seen.add(key);
|
|
47
|
+
out.push({
|
|
48
|
+
phrase,
|
|
49
|
+
fromMs: now - days.from * DAY_MS,
|
|
50
|
+
toMs: now - days.to * DAY_MS,
|
|
51
|
+
offset: m.index ?? 0,
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
for (const m of text.matchAll(N_DAYS_AGO)) {
|
|
56
|
+
const n = Number(m[1]);
|
|
57
|
+
if (!Number.isFinite(n) || n < 0)
|
|
58
|
+
continue;
|
|
59
|
+
out.push({
|
|
60
|
+
phrase: m[0].toLowerCase(),
|
|
61
|
+
fromMs: now - (n + 1) * DAY_MS,
|
|
62
|
+
toMs: now - Math.max(0, n - 1) * DAY_MS,
|
|
63
|
+
offset: m.index ?? 0,
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
return out;
|
|
67
|
+
}
|
|
68
|
+
function queryGitWindow(repoRoot, ref, verbs, files) {
|
|
69
|
+
const since = new Date(ref.fromMs).toISOString();
|
|
70
|
+
const until = new Date(ref.toMs).toISOString();
|
|
71
|
+
let totalCommits = 0;
|
|
72
|
+
let subjects = "";
|
|
73
|
+
try {
|
|
74
|
+
const r = execSync(`git -C "${repoRoot}" log --since="${since}" --until="${until}" --pretty=format:%s`, { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"], timeout: 3000 });
|
|
75
|
+
subjects = r;
|
|
76
|
+
totalCommits = r.split("\n").filter(Boolean).length;
|
|
77
|
+
}
|
|
78
|
+
catch { /* */ }
|
|
79
|
+
let verbMatches = 0;
|
|
80
|
+
for (const v of verbs) {
|
|
81
|
+
const re = new RegExp(`\\b${v.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}\\b`, "i");
|
|
82
|
+
if (re.test(subjects))
|
|
83
|
+
verbMatches += 1;
|
|
84
|
+
}
|
|
85
|
+
let fileTouches = 0;
|
|
86
|
+
for (const f of files.slice(0, 3)) {
|
|
87
|
+
try {
|
|
88
|
+
const r = execSync(`git -C "${repoRoot}" log --since="${since}" --until="${until}" --format=%H -- "${f}"`, { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"], timeout: 3000 });
|
|
89
|
+
if (r.trim().split("\n").filter(Boolean).length > 0)
|
|
90
|
+
fileTouches += 1;
|
|
91
|
+
}
|
|
92
|
+
catch { /* */ }
|
|
93
|
+
}
|
|
94
|
+
return { totalCommits, verbMatches, fileTouches };
|
|
95
|
+
}
|
|
96
|
+
export function verifyTemporal(repoRoot, text) {
|
|
97
|
+
const refs = extractTemporalRefs(text);
|
|
98
|
+
if (refs.length === 0) {
|
|
99
|
+
return { refs, suspects: [], corroborated: [], headline: "No temporal claims in text." };
|
|
100
|
+
}
|
|
101
|
+
// Extract verbs + files ONCE for the whole text -- conservative: any temporal
|
|
102
|
+
// ref in the text takes context from all verbs/files in the same text.
|
|
103
|
+
const verbs = [...new Set([...text.matchAll(VERB_PATTERN)].map((m) => m[1].toLowerCase()))];
|
|
104
|
+
const files = [...new Set([...text.matchAll(FILE_PATTERN)].map((m) => m[1]))];
|
|
105
|
+
const suspects = [];
|
|
106
|
+
const corroborated = [];
|
|
107
|
+
for (const ref of refs) {
|
|
108
|
+
const result = queryGitWindow(repoRoot, ref, verbs, files);
|
|
109
|
+
if (result.totalCommits === 0) {
|
|
110
|
+
suspects.push({
|
|
111
|
+
ref,
|
|
112
|
+
reason: `No git commits in window [${new Date(ref.fromMs).toISOString().slice(0, 10)} .. ${new Date(ref.toMs).toISOString().slice(0, 10)}] for "${ref.phrase}".`,
|
|
113
|
+
confidence: 0.85,
|
|
114
|
+
});
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
// If claim names verbs or files, require corroboration.
|
|
118
|
+
if (verbs.length > 0 && result.verbMatches === 0 && files.length === 0) {
|
|
119
|
+
suspects.push({
|
|
120
|
+
ref,
|
|
121
|
+
reason: `${result.totalCommits} commit(s) in window but none match the claimed verbs (${verbs.slice(0, 3).join(", ")}).`,
|
|
122
|
+
confidence: 0.7,
|
|
123
|
+
});
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
if (files.length > 0 && result.fileTouches === 0) {
|
|
127
|
+
suspects.push({
|
|
128
|
+
ref,
|
|
129
|
+
reason: `${result.totalCommits} commit(s) in window but none touched the named file(s).`,
|
|
130
|
+
confidence: 0.8,
|
|
131
|
+
});
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
corroborated.push(ref);
|
|
135
|
+
}
|
|
136
|
+
const headline = `${refs.length} temporal claim(s); ${corroborated.length} corroborated, ${suspects.length} suspect.`;
|
|
137
|
+
return { refs, suspects, corroborated, headline };
|
|
138
|
+
}
|
|
139
|
+
//# sourceMappingURL=temporal_verifier.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"temporal_verifier.js","sourceRoot":"","sources":["../../src/precog/temporal_verifier.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAyB9C,MAAM,UAAU,GAAmE;IACjF,EAAE,OAAO,EAAE,eAAe,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE;IACtD,EAAE,OAAO,EAAE,mBAAmB,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE;IAC1D,EAAE,OAAO,EAAE,qBAAqB,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE;IAC7D,EAAE,OAAO,EAAE,sBAAsB,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE;IAC/D,EAAE,OAAO,EAAE,wBAAwB,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE;IAClE,EAAE,OAAO,EAAE,qBAAqB,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE;CAC7D,CAAC;AAEF,MAAM,UAAU,GAAG,2BAA2B,CAAC;AAE/C,MAAM,YAAY,GAAG,oGAAoG,CAAC;AAC1H,MAAM,YAAY,GAAG,uEAAuE,CAAC;AAE7F,MAAM,MAAM,GAAG,KAAK,GAAG,IAAI,CAAC;AAE5B,MAAM,UAAU,mBAAmB,CAAC,IAAY;IAC9C,MAAM,GAAG,GAAwB,EAAE,CAAC;IACpC,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,KAAK,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,UAAU,EAAE,CAAC;QAC3C,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;YACvC,MAAM,MAAM,GAAG,CAAC,CAAC,CAAC,CAAE,CAAC,WAAW,EAAE,CAAC;YACnC,MAAM,GAAG,GAAG,GAAG,MAAM,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC;YACnC,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;gBAAE,SAAS;YAC5B,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACd,GAAG,CAAC,IAAI,CAAC;gBACP,MAAM;gBACN,MAAM,EAAE,GAAG,GAAG,IAAI,CAAC,IAAI,GAAG,MAAM;gBAChC,IAAI,EAAE,GAAG,GAAG,IAAI,CAAC,EAAE,GAAG,MAAM;gBAC5B,MAAM,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC;aACrB,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;QAC1C,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACvB,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;YAAE,SAAS;QAC3C,GAAG,CAAC,IAAI,CAAC;YACP,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE;YAC1B,MAAM,EAAE,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,MAAM;YAC9B,IAAI,EAAE,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,GAAG,MAAM;YACvC,MAAM,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC;SACrB,CAAC,CAAC;IACL,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAQD,SAAS,cAAc,CAAC,QAAgB,EAAE,GAAsB,EAAE,KAAe,EAAE,KAAe;IAChG,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC;IACjD,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;IAC/C,IAAI,YAAY,GAAG,CAAC,CAAC;IACrB,IAAI,QAAQ,GAAG,EAAE,CAAC;IAClB,IAAI,CAAC;QACH,MAAM,CAAC,GAAG,QAAQ,CAAC,WAAW,QAAQ,kBAAkB,KAAK,cAAc,KAAK,sBAAsB,EACpG,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;QAC5E,QAAQ,GAAG,CAAC,CAAC;QACb,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC;IACtD,CAAC;IAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC;IACjB,IAAI,WAAW,GAAG,CAAC,CAAC;IACpB,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,MAAM,EAAE,GAAG,IAAI,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QAChF,IAAI,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC;YAAE,WAAW,IAAI,CAAC,CAAC;IAC1C,CAAC;IACD,IAAI,WAAW,GAAG,CAAC,CAAC;IACpB,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;QAClC,IAAI,CAAC;YACH,MAAM,CAAC,GAAG,QAAQ,CAAC,WAAW,QAAQ,kBAAkB,KAAK,cAAc,KAAK,qBAAqB,CAAC,GAAG,EACvG,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;YAC5E,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,GAAG,CAAC;gBAAE,WAAW,IAAI,CAAC,CAAC;QACxE,CAAC;QAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC;IACnB,CAAC;IACD,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,CAAC;AACpD,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,QAAgB,EAAE,IAAY;IAC3D,MAAM,IAAI,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC;IACvC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,YAAY,EAAE,EAAE,EAAE,QAAQ,EAAE,6BAA6B,EAAE,CAAC;IAC3F,CAAC;IACD,8EAA8E;IAC9E,uEAAuE;IACvE,MAAM,KAAK,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAE,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC;IAC7F,MAAM,KAAK,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,CAAC;IAC/E,MAAM,QAAQ,GAAsB,EAAE,CAAC;IACvC,MAAM,YAAY,GAAwB,EAAE,CAAC;IAC7C,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,MAAM,GAAG,cAAc,CAAC,QAAQ,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;QAC3D,IAAI,MAAM,CAAC,YAAY,KAAK,CAAC,EAAE,CAAC;YAC9B,QAAQ,CAAC,IAAI,CAAC;gBACZ,GAAG;gBACH,MAAM,EAAE,6BAA6B,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,GAAG,CAAC,MAAM,IAAI;gBAChK,UAAU,EAAE,IAAI;aACjB,CAAC,CAAC;YACH,SAAS;QACX,CAAC;QACD,wDAAwD;QACxD,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,MAAM,CAAC,WAAW,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvE,QAAQ,CAAC,IAAI,CAAC;gBACZ,GAAG;gBACH,MAAM,EAAE,GAAG,MAAM,CAAC,YAAY,0DAA0D,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI;gBACxH,UAAU,EAAE,GAAG;aAChB,CAAC,CAAC;YACH,SAAS;QACX,CAAC;QACD,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,MAAM,CAAC,WAAW,KAAK,CAAC,EAAE,CAAC;YACjD,QAAQ,CAAC,IAAI,CAAC;gBACZ,GAAG;gBACH,MAAM,EAAE,GAAG,MAAM,CAAC,YAAY,0DAA0D;gBACxF,UAAU,EAAE,GAAG;aAChB,CAAC,CAAC;YACH,SAAS;QACX,CAAC;QACD,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACzB,CAAC;IACD,MAAM,QAAQ,GAAG,GAAG,IAAI,CAAC,MAAM,uBAAuB,YAAY,CAAC,MAAM,kBAAkB,QAAQ,CAAC,MAAM,WAAW,CAAC;IACtH,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,YAAY,EAAE,QAAQ,EAAE,CAAC;AACpD,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v1.70.0 -- PRECOG P5: TRUST CERTIFICATE.
|
|
3
|
+
*
|
|
4
|
+
* After a claim passes verification, mint an HMAC-signed certificate.
|
|
5
|
+
* Downstream consumers (apps, the user's UI, mesh peers) can verify
|
|
6
|
+
* the certificate without re-running every checker.
|
|
7
|
+
*
|
|
8
|
+
* issueCertificate(claim, verifierResults) -> { cert, signers, ts }
|
|
9
|
+
* verifyCertificate(cert) -> boolean
|
|
10
|
+
*
|
|
11
|
+
* The "SSL for AI claims" the user described.
|
|
12
|
+
*/
|
|
13
|
+
export interface VerifierResult {
|
|
14
|
+
name: string;
|
|
15
|
+
passed: boolean;
|
|
16
|
+
detail?: string;
|
|
17
|
+
}
|
|
18
|
+
export interface TrustCertificate {
|
|
19
|
+
/** Stable id = sha256(claim || payload). */
|
|
20
|
+
id: string;
|
|
21
|
+
/** Original claim (truncated to 500 chars). */
|
|
22
|
+
claim: string;
|
|
23
|
+
/** Verifier names that passed. */
|
|
24
|
+
signers: string[];
|
|
25
|
+
/** Verifier names that flagged. */
|
|
26
|
+
flaggedBy: string[];
|
|
27
|
+
/** Verdict band. */
|
|
28
|
+
verdict: "CERTIFIED" | "CONDITIONAL" | "REVOKED";
|
|
29
|
+
/** ISO ts. */
|
|
30
|
+
issuedAt: string;
|
|
31
|
+
/** Expiry (ISO). */
|
|
32
|
+
expiresAt: string;
|
|
33
|
+
/** HMAC over canonical payload. */
|
|
34
|
+
hmac: string;
|
|
35
|
+
}
|
|
36
|
+
export interface IssueOptions {
|
|
37
|
+
/** Window during which the cert is valid (ms). Default 24h. */
|
|
38
|
+
ttlMs?: number;
|
|
39
|
+
}
|
|
40
|
+
export declare function issueCertificate(repoRoot: string, claim: string, verifierResults: VerifierResult[], opts?: IssueOptions): TrustCertificate;
|
|
41
|
+
export type VerifyVerdict = "VALID" | "INVALID_HMAC" | "EXPIRED" | "NOT_CERTIFIED";
|
|
42
|
+
export declare function verifyCertificate(repoRoot: string, cert: TrustCertificate): VerifyVerdict;
|
|
43
|
+
export declare function readCertLedger(repoRoot: string): TrustCertificate[];
|
|
44
|
+
//# sourceMappingURL=trust_certificate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trust_certificate.d.ts","sourceRoot":"","sources":["../../src/precog/trust_certificate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAUH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,4CAA4C;IAC5C,EAAE,EAAE,MAAM,CAAC;IACX,+CAA+C;IAC/C,KAAK,EAAE,MAAM,CAAC;IACd,kCAAkC;IAClC,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,mCAAmC;IACnC,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,oBAAoB;IACpB,OAAO,EAAE,WAAW,GAAG,aAAa,GAAG,SAAS,CAAC;IACjD,cAAc;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,oBAAoB;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,mCAAmC;IACnC,IAAI,EAAE,MAAM,CAAC;CACd;AAuBD,MAAM,WAAW,YAAY;IAC3B,+DAA+D;IAC/D,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,EACb,eAAe,EAAE,cAAc,EAAE,EACjC,IAAI,CAAC,EAAE,YAAY,GAClB,gBAAgB,CA2BlB;AAED,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,cAAc,GAAG,SAAS,GAAG,eAAe,CAAC;AAEnF,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,gBAAgB,GAAG,aAAa,CAQzF;AAED,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,gBAAgB,EAAE,CAWnE"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v1.70.0 -- PRECOG P5: TRUST CERTIFICATE.
|
|
3
|
+
*
|
|
4
|
+
* After a claim passes verification, mint an HMAC-signed certificate.
|
|
5
|
+
* Downstream consumers (apps, the user's UI, mesh peers) can verify
|
|
6
|
+
* the certificate without re-running every checker.
|
|
7
|
+
*
|
|
8
|
+
* issueCertificate(claim, verifierResults) -> { cert, signers, ts }
|
|
9
|
+
* verifyCertificate(cert) -> boolean
|
|
10
|
+
*
|
|
11
|
+
* The "SSL for AI claims" the user described.
|
|
12
|
+
*/
|
|
13
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync, appendFileSync } from "node:fs";
|
|
14
|
+
import { createHash, createHmac, randomBytes } from "node:crypto";
|
|
15
|
+
import { join } from "node:path";
|
|
16
|
+
const PRECOG_DIR = ".mneme/precog";
|
|
17
|
+
const CERT_LEDGER = ".mneme/precog/certificates.jsonl";
|
|
18
|
+
const SECRET_FILE = ".mneme/precog/cert-secret";
|
|
19
|
+
function ensureSecret(repoRoot) {
|
|
20
|
+
const path = join(repoRoot, SECRET_FILE);
|
|
21
|
+
if (existsSync(path))
|
|
22
|
+
return readFileSync(path, "utf8").trim();
|
|
23
|
+
const dir = join(repoRoot, PRECOG_DIR);
|
|
24
|
+
if (!existsSync(dir))
|
|
25
|
+
mkdirSync(dir, { recursive: true });
|
|
26
|
+
const s = randomBytes(32).toString("hex");
|
|
27
|
+
try {
|
|
28
|
+
writeFileSync(path, s, "utf8");
|
|
29
|
+
}
|
|
30
|
+
catch { /* */ }
|
|
31
|
+
return s;
|
|
32
|
+
}
|
|
33
|
+
function canonical(payload) {
|
|
34
|
+
return JSON.stringify({
|
|
35
|
+
claim: payload.claim,
|
|
36
|
+
signers: [...payload.signers].sort(),
|
|
37
|
+
flaggedBy: [...payload.flaggedBy].sort(),
|
|
38
|
+
verdict: payload.verdict,
|
|
39
|
+
issuedAt: payload.issuedAt,
|
|
40
|
+
expiresAt: payload.expiresAt,
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
export function issueCertificate(repoRoot, claim, verifierResults, opts) {
|
|
44
|
+
const secret = ensureSecret(repoRoot);
|
|
45
|
+
const issuedAt = new Date().toISOString();
|
|
46
|
+
const ttlMs = opts?.ttlMs ?? 24 * 3600 * 1000;
|
|
47
|
+
const expiresAt = new Date(Date.now() + ttlMs).toISOString();
|
|
48
|
+
const signers = verifierResults.filter((v) => v.passed).map((v) => v.name);
|
|
49
|
+
const flaggedBy = verifierResults.filter((v) => !v.passed).map((v) => v.name);
|
|
50
|
+
const verdict = flaggedBy.length === 0
|
|
51
|
+
? "CERTIFIED"
|
|
52
|
+
: signers.length > flaggedBy.length
|
|
53
|
+
? "CONDITIONAL"
|
|
54
|
+
: "REVOKED";
|
|
55
|
+
const payload = {
|
|
56
|
+
claim: claim.slice(0, 500),
|
|
57
|
+
signers, flaggedBy, verdict, issuedAt, expiresAt,
|
|
58
|
+
};
|
|
59
|
+
const canon = canonical(payload);
|
|
60
|
+
const hmac = createHmac("sha256", secret).update(canon).digest("hex");
|
|
61
|
+
const id = createHash("sha256").update(canon).digest("hex").slice(0, 16);
|
|
62
|
+
const cert = { ...payload, id, hmac };
|
|
63
|
+
// Persist to ledger.
|
|
64
|
+
try {
|
|
65
|
+
const dir = join(repoRoot, PRECOG_DIR);
|
|
66
|
+
if (!existsSync(dir))
|
|
67
|
+
mkdirSync(dir, { recursive: true });
|
|
68
|
+
appendFileSync(join(repoRoot, CERT_LEDGER), JSON.stringify(cert) + "\n", "utf8");
|
|
69
|
+
}
|
|
70
|
+
catch { /* */ }
|
|
71
|
+
return cert;
|
|
72
|
+
}
|
|
73
|
+
export function verifyCertificate(repoRoot, cert) {
|
|
74
|
+
if (Date.parse(cert.expiresAt) < Date.now())
|
|
75
|
+
return "EXPIRED";
|
|
76
|
+
const secret = ensureSecret(repoRoot);
|
|
77
|
+
const canon = canonical(cert);
|
|
78
|
+
const expected = createHmac("sha256", secret).update(canon).digest("hex");
|
|
79
|
+
if (expected !== cert.hmac)
|
|
80
|
+
return "INVALID_HMAC";
|
|
81
|
+
if (cert.verdict === "REVOKED")
|
|
82
|
+
return "NOT_CERTIFIED";
|
|
83
|
+
return "VALID";
|
|
84
|
+
}
|
|
85
|
+
export function readCertLedger(repoRoot) {
|
|
86
|
+
const p = join(repoRoot, CERT_LEDGER);
|
|
87
|
+
if (!existsSync(p))
|
|
88
|
+
return [];
|
|
89
|
+
const out = [];
|
|
90
|
+
try {
|
|
91
|
+
for (const line of readFileSync(p, "utf8").split("\n")) {
|
|
92
|
+
if (!line.trim())
|
|
93
|
+
continue;
|
|
94
|
+
try {
|
|
95
|
+
out.push(JSON.parse(line));
|
|
96
|
+
}
|
|
97
|
+
catch { /* */ }
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
catch { /* */ }
|
|
101
|
+
return out;
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=trust_certificate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trust_certificate.js","sourceRoot":"","sources":["../../src/precog/trust_certificate.ts"],"names":[],"mappings":"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"}
|