qlm-measure 0.2.1 → 0.2.3

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 (68) hide show
  1. package/README.md +24 -139
  2. package/dist/checks.d.ts +21 -0
  3. package/dist/checks.d.ts.map +1 -0
  4. package/dist/checks.js +25 -0
  5. package/dist/checks.js.map +1 -0
  6. package/dist/cli.d.ts +7 -0
  7. package/dist/cli.d.ts.map +1 -0
  8. package/dist/cli.js +314 -0
  9. package/dist/cli.js.map +1 -0
  10. package/dist/clients/engine-client.d.ts +1 -1
  11. package/dist/clients/engine-client.d.ts.map +1 -1
  12. package/dist/clients/engine-client.js +1 -1
  13. package/dist/clients/engine-client.js.map +1 -1
  14. package/dist/clients/index.d.ts +4 -4
  15. package/dist/clients/index.d.ts.map +1 -1
  16. package/dist/clients/index.js +2 -2
  17. package/dist/clients/index.js.map +1 -1
  18. package/dist/clients/ontology-client.d.ts +10 -0
  19. package/dist/clients/ontology-client.d.ts.map +1 -1
  20. package/dist/clients/ontology-client.js +4 -0
  21. package/dist/clients/ontology-client.js.map +1 -1
  22. package/dist/emitter/index.d.ts +2 -2
  23. package/dist/emitter/index.d.ts.map +1 -1
  24. package/dist/emitter/index.js +1 -1
  25. package/dist/emitter/index.js.map +1 -1
  26. package/dist/emitter/measurement-emitter.d.ts +1 -1
  27. package/dist/emitter/measurement-emitter.d.ts.map +1 -1
  28. package/dist/index.d.ts +23 -16
  29. package/dist/index.d.ts.map +1 -1
  30. package/dist/index.js +16 -8
  31. package/dist/index.js.map +1 -1
  32. package/dist/recorder.d.ts +33 -0
  33. package/dist/recorder.d.ts.map +1 -0
  34. package/dist/recorder.js +129 -0
  35. package/dist/recorder.js.map +1 -0
  36. package/dist/rules.d.ts +10 -0
  37. package/dist/rules.d.ts.map +1 -0
  38. package/dist/rules.js +46 -0
  39. package/dist/rules.js.map +1 -0
  40. package/dist/schema/evidence-record.d.ts +2 -2
  41. package/dist/schema/evidence-record.d.ts.map +1 -1
  42. package/dist/schema/index.d.ts +6 -6
  43. package/dist/schema/index.d.ts.map +1 -1
  44. package/dist/schema/index.js +2 -2
  45. package/dist/schema/index.js.map +1 -1
  46. package/dist/schema/measurement-event.d.ts +1 -1
  47. package/dist/schema/measurement-event.d.ts.map +1 -1
  48. package/dist/schema/observation-event.d.ts +1 -1
  49. package/dist/schema/observation-event.d.ts.map +1 -1
  50. package/dist/verifier/hash.d.ts +6 -7
  51. package/dist/verifier/hash.d.ts.map +1 -1
  52. package/dist/verifier/hash.js +143 -39
  53. package/dist/verifier/hash.js.map +1 -1
  54. package/dist/verifier/index.d.ts +4 -4
  55. package/dist/verifier/index.d.ts.map +1 -1
  56. package/dist/verifier/index.js +3 -3
  57. package/dist/verifier/index.js.map +1 -1
  58. package/dist/verifier/replay.d.ts +1 -1
  59. package/dist/verifier/replay.d.ts.map +1 -1
  60. package/dist/verifier/verify-record.d.ts +4 -30
  61. package/dist/verifier/verify-record.d.ts.map +1 -1
  62. package/dist/verifier/verify-record.js +44 -83
  63. package/dist/verifier/verify-record.js.map +1 -1
  64. package/dist/verifier-v03.d.ts +24 -0
  65. package/dist/verifier-v03.d.ts.map +1 -0
  66. package/dist/verifier-v03.js +205 -0
  67. package/dist/verifier-v03.js.map +1 -0
  68. package/package.json +5 -1
@@ -1,73 +1,177 @@
1
1
  /**
2
2
  * Hash utilities for evidence record integrity.
3
3
  *
4
- * Uses SHA-256 via the Web Crypto API (browser) or Node crypto module.
4
+ * Uses SHA-256 via Node's crypto module (ESM import).
5
5
  * Canonical serialization ensures deterministic hashing.
6
6
  */
7
+ import { createHash } from "crypto";
7
8
  /**
8
- * Canonical JSON serialization — sorted keys, no whitespace.
9
- * Ensures the same object always produces the same hash regardless
10
- * of property insertion order.
9
+ * Format a number to match Python's json.dumps output.
10
+ *
11
+ * Python's json.dumps uses different formatting for int vs float:
12
+ * int 9200 → "9200" (no decimal point)
13
+ * float 1.0 → "1.0" (always has decimal point)
14
+ * float 3e-05 → "3e-05" (2-digit exponent minimum)
15
+ *
16
+ * JS has no int/float distinction. We use Number.isInteger() as the
17
+ * heuristic: if the JSON source had no decimal point, Python stored
18
+ * it as int and wrote it without .0.
19
+ *
20
+ * For the entry-hash hashable subset, only evidentialWeight,
21
+ * priorPosterior, and updatedPosterior are Python floats. version is
22
+ * an int. Everything inside event follows Python's own int/float typing
23
+ * from the original JSON (which round-trips through JSON.parse identically).
11
24
  */
12
- export function canonicalize(obj) {
13
- return JSON.stringify(obj, (_, value) => {
14
- if (value && typeof value === "object" && !Array.isArray(value)) {
15
- return Object.keys(value).sort().reduce((sorted, key) => {
16
- sorted[key] = value[key];
17
- return sorted;
18
- }, {});
25
+ /**
26
+ * Format a number to match Python's json.dumps output.
27
+ *
28
+ * Python uses the shortest decimal representation that round-trips
29
+ * (David Gay's dtoa algorithm). JS's Number.toString() also uses dtoa
30
+ * but sometimes produces longer representations with floating-point noise.
31
+ *
32
+ * We match Python by finding the shortest representation that round-trips.
33
+ */
34
+ function pyNumberFormat(n) {
35
+ if (Object.is(n, -0))
36
+ return "-0.0";
37
+ if (!Number.isFinite(n))
38
+ return String(n);
39
+ // Python int path
40
+ if (Number.isInteger(n) && Math.abs(n) < Number.MAX_SAFE_INTEGER) {
41
+ return n.toString();
42
+ }
43
+ // Find the shortest decimal representation that round-trips
44
+ // This matches Python's float.__repr__ (shortest via dtoa)
45
+ let best = JSON.stringify(n);
46
+ // Try progressively shorter representations
47
+ for (let prec = 17; prec >= 1; prec--) {
48
+ const candidate = n.toPrecision(prec);
49
+ if (parseFloat(candidate) === n) {
50
+ best = candidate;
19
51
  }
20
- return value;
52
+ else {
53
+ break; // once it stops round-tripping, shorter won't work either
54
+ }
55
+ }
56
+ // Remove unnecessary trailing zeros and decimal point
57
+ // but keep at least one digit after decimal for floats
58
+ if (best.includes(".") && !best.includes("e") && !best.includes("E")) {
59
+ best = best.replace(/0+$/, "");
60
+ if (best.endsWith("."))
61
+ best += "0"; // keep the .0 for e.g. "1.0"
62
+ }
63
+ // Python uses scientific notation for abs < 1e-4
64
+ const abs = Math.abs(n);
65
+ if (abs > 0 && abs < 1e-4) {
66
+ // Force scientific notation matching Python
67
+ if (!best.includes("e") && !best.includes("E")) {
68
+ const exp = Math.floor(Math.log10(abs));
69
+ const mantissa = n / Math.pow(10, exp);
70
+ // Use shortest mantissa
71
+ let mBest = String(mantissa);
72
+ for (let p = 17; p >= 1; p--) {
73
+ const mc = mantissa.toPrecision(p);
74
+ if (parseFloat(mc) * Math.pow(10, exp) === n) {
75
+ mBest = mc;
76
+ }
77
+ else
78
+ break;
79
+ }
80
+ // Clean mantissa
81
+ if (mBest.includes(".")) {
82
+ mBest = mBest.replace(/0+$/, "").replace(/\.$/, "");
83
+ }
84
+ best = `${mBest}e-${String(-exp).padStart(2, "0")}`;
85
+ }
86
+ }
87
+ // Fix exponent padding: e-7 → e-07, e+2 → e+02
88
+ best = best.replace(/e([+-])(\d)$/, "e$10$2");
89
+ return best;
90
+ }
91
+ /**
92
+ * Format a string to match Python's json.dumps output.
93
+ * Python escapes all non-ASCII characters to \\uXXXX by default.
94
+ * JS JSON.stringify passes them through as UTF-8.
95
+ */
96
+ function pyStringFormat(s) {
97
+ let result = JSON.stringify(s);
98
+ // Replace non-ASCII characters with \\uXXXX escapes, matching Python
99
+ result = result.replace(/[\u0080-\uffff]/g, (ch) => {
100
+ return "\\u" + ch.charCodeAt(0).toString(16).padStart(4, "0");
21
101
  });
102
+ return result;
22
103
  }
23
104
  /**
24
- * Compute SHA-256 hash of a string.
25
- * Works in both browser (Web Crypto) and Node (crypto module).
105
+ * Canonical JSON serialization — sorted keys, no whitespace.
106
+ * Matches Python's json.dumps(sort_keys=True, separators=(",",":"), default=str)
107
+ * byte-for-byte, including number and string formatting.
26
108
  */
27
- export function sha256(input) {
28
- // Node.js path
29
- try {
30
- // eslint-disable-next-line @typescript-eslint/no-require-imports
31
- const crypto = require("crypto");
32
- return crypto.createHash("sha256").update(input).digest("hex");
109
+ export function canonicalize(obj) {
110
+ return _canonicalizeValue(obj);
111
+ }
112
+ function _canonicalizeValue(val) {
113
+ if (val === null)
114
+ return "null";
115
+ if (val === undefined)
116
+ return "null";
117
+ if (typeof val === "boolean")
118
+ return val ? "true" : "false";
119
+ if (typeof val === "number")
120
+ return pyNumberFormat(val);
121
+ if (typeof val === "string")
122
+ return pyStringFormat(val);
123
+ if (Array.isArray(val)) {
124
+ return "[" + val.map(_canonicalizeValue).join(",") + "]";
33
125
  }
34
- catch {
35
- // Browser path — synchronous fallback using a simple hash
36
- // Note: in production, use Web Crypto API (async) for true SHA-256
37
- return simpleHash(input);
126
+ if (typeof val === "object") {
127
+ const keys = Object.keys(val).sort();
128
+ const pairs = keys.map(k => {
129
+ const v = val[k];
130
+ return JSON.stringify(k) + ":" + _canonicalizeValue(v);
131
+ });
132
+ return "{" + pairs.join(",") + "}";
38
133
  }
134
+ return JSON.stringify(val);
39
135
  }
40
- /** Simple non-cryptographic hash for browser environments without crypto. */
41
- function simpleHash(str) {
42
- let hash = 0;
43
- for (let i = 0; i < str.length; i++) {
44
- const char = str.charCodeAt(i);
45
- hash = ((hash << 5) - hash + char) | 0;
46
- }
47
- return Math.abs(hash).toString(16).padStart(8, "0");
136
+ /**
137
+ * Compute SHA-256 hash of a string.
138
+ */
139
+ export function sha256(input) {
140
+ return createHash("sha256").update(input).digest("hex");
48
141
  }
49
142
  /**
50
143
  * Compute the canonical hash of an evidence entry.
51
- * Hashes all fields EXCEPT entryHash and prevHash (which are the chain links).
144
+ * Every field must be explicitly null (not undefined) to match Python.
52
145
  */
53
146
  export function hashEntry(entry) {
54
147
  const hashable = {
55
148
  version: entry.version,
56
149
  timestamp: entry.timestamp,
57
150
  event: entry.event,
58
- scaffoldType: entry.scaffoldType,
59
- depthLevel: entry.depthLevel,
60
- epistemicMode: entry.epistemicMode,
61
- triageResult: entry.triageResult,
151
+ scaffoldType: entry.scaffoldType ?? null,
152
+ depthLevel: entry.depthLevel ?? null,
153
+ epistemicMode: entry.epistemicMode ?? null,
154
+ triageResult: entry.triageResult ?? null,
62
155
  evidentialWeight: entry.evidentialWeight,
63
156
  priorPosterior: entry.priorPosterior,
64
157
  updatedPosterior: entry.updatedPosterior,
65
158
  nonInterventionDecision: entry.nonInterventionDecision ?? null,
66
159
  };
67
- return sha256(canonicalize(hashable));
160
+ // Build canonical, then fix the three Python-float fields:
161
+ // evidentialWeight, priorPosterior, updatedPosterior are Python floats.
162
+ // Python writes 1.0 for float(1), but JS Number.isInteger(1) returns true
163
+ // and pyNumberFormat writes "1". Fix by post-processing these three fields.
164
+ let canonical = _canonicalizeValue(hashable);
165
+ for (const field of ["evidentialWeight", "priorPosterior", "updatedPosterior"]) {
166
+ const val = hashable[field];
167
+ if (typeof val === "number" && Number.isInteger(val)) {
168
+ canonical = canonical.replace(new RegExp(`"${field}":(-?\\d+)(?=[,}\\]])`), `"${field}":$1.0`);
169
+ }
170
+ }
171
+ return sha256(canonical);
68
172
  }
69
173
  /**
70
- * Compute a hash over a canonical string (for summary hashes, etc.).
174
+ * Compute a hash over a canonical string.
71
175
  */
72
176
  export function hashCanonical(input) {
73
177
  return sha256(input);
@@ -1 +1 @@
1
- {"version":3,"file":"hash.js","sourceRoot":"","sources":["../../src/verifier/hash.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,GAAY;IACvC,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE;QACtC,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YAChE,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC,MAAM,CAA0B,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE;gBAC/E,MAAM,CAAC,GAAG,CAAC,GAAI,KAAiC,CAAC,GAAG,CAAC,CAAC;gBACtD,OAAO,MAAM,CAAC;YAChB,CAAC,EAAE,EAAE,CAAC,CAAC;QACT,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,MAAM,CAAC,KAAa;IAClC,eAAe;IACf,IAAI,CAAC;QACH,iEAAiE;QACjE,MAAM,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;QACjC,OAAO,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACjE,CAAC;IAAC,MAAM,CAAC;QACP,0DAA0D;QAC1D,mEAAmE;QACnE,OAAO,UAAU,CAAC,KAAK,CAAC,CAAC;IAC3B,CAAC;AACH,CAAC;AAED,6EAA6E;AAC7E,SAAS,UAAU,CAAC,GAAW;IAC7B,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACpC,MAAM,IAAI,GAAG,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;QAC/B,IAAI,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;IACzC,CAAC;IACD,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AACtD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,SAAS,CAAC,KAAoB;IAC5C,MAAM,QAAQ,GAAG;QACf,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,YAAY,EAAE,KAAK,CAAC,YAAY;QAChC,UAAU,EAAE,KAAK,CAAC,UAAU;QAC5B,aAAa,EAAE,KAAK,CAAC,aAAa;QAClC,YAAY,EAAE,KAAK,CAAC,YAAY;QAChC,gBAAgB,EAAE,KAAK,CAAC,gBAAgB;QACxC,cAAc,EAAE,KAAK,CAAC,cAAc;QACpC,gBAAgB,EAAE,KAAK,CAAC,gBAAgB;QACxC,uBAAuB,EAAE,KAAK,CAAC,uBAAuB,IAAI,IAAI;KAC/D,CAAC;IACF,OAAO,MAAM,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC;AACxC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,KAAa;IACzC,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;AACvB,CAAC"}
1
+ {"version":3,"file":"hash.js","sourceRoot":"","sources":["../../src/verifier/hash.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
- export { verifyRecord } from "./verify-record";
2
- export type { VerificationResult, Violation } from "./verify-record";
3
- export { replayToVersion, posteriorAtVersion, summarizeToVersion } from "./replay";
4
- export { hashEntry, hashCanonical, canonicalize, sha256 } from "./hash";
1
+ export { verifyRecord } from "./verify-record.js";
2
+ export type { VerificationResult, Violation } from "./verify-record.js";
3
+ export { replayToVersion, posteriorAtVersion, summarizeToVersion } from "./replay.js";
4
+ export { hashEntry, hashCanonical, canonicalize, sha256 } from "./hash.js";
5
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/verifier/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,YAAY,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACrE,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AACnF,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/verifier/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,YAAY,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACxE,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACtF,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC"}
@@ -1,4 +1,4 @@
1
- export { verifyRecord } from "./verify-record";
2
- export { replayToVersion, posteriorAtVersion, summarizeToVersion } from "./replay";
3
- export { hashEntry, hashCanonical, canonicalize, sha256 } from "./hash";
1
+ export { verifyRecord } from "./verify-record.js";
2
+ export { replayToVersion, posteriorAtVersion, summarizeToVersion } from "./replay.js";
3
+ export { hashEntry, hashCanonical, canonicalize, sha256 } from "./hash.js";
4
4
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/verifier/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE/C,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AACnF,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/verifier/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACtF,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC"}
@@ -4,7 +4,7 @@
4
4
  * This is pure bookkeeping: it slices the entry array to version N
5
5
  * and returns the logged values. It does NOT recompute any posteriors.
6
6
  */
7
- import type { EvidenceRecord, EvidenceEntry } from "../schema/evidence-record";
7
+ import type { EvidenceRecord, EvidenceEntry } from "../schema/evidence-record.js";
8
8
  /**
9
9
  * Replay an evidence record to a specific version.
10
10
  *
@@ -1 +1 @@
1
- {"version":3,"file":"replay.d.ts","sourceRoot":"","sources":["../../src/verifier/replay.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAE/E;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,cAAc,EACtB,aAAa,EAAE,MAAM,GACpB,aAAa,EAAE,CAEjB;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,cAAc,EACtB,aAAa,EAAE,MAAM,GACpB,MAAM,GAAG,IAAI,CAIf;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,cAAc,EACtB,aAAa,EAAE,MAAM,GACpB;IACD,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,oBAAoB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7C,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC5C,CAkBA"}
1
+ {"version":3,"file":"replay.d.ts","sourceRoot":"","sources":["../../src/verifier/replay.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAElF;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,cAAc,EACtB,aAAa,EAAE,MAAM,GACpB,aAAa,EAAE,CAEjB;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,cAAc,EACtB,aAAa,EAAE,MAAM,GACpB,MAAM,GAAG,IAAI,CAIf;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,cAAc,EACtB,aAAa,EAAE,MAAM,GACpB;IACD,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,oBAAoB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7C,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC5C,CAkBA"}
@@ -2,47 +2,21 @@
2
2
  * Evidence Record Verifier
3
3
  *
4
4
  * Verifies the bookkeeping integrity of an evidence record WITHOUT
5
- * containing any estimation mathematics. This distinction is the design:
6
- * "verify instead of trust."
5
+ * containing any estimation mathematics.
7
6
  *
8
- * What it checks:
9
- * - Schema validity (required fields present, correct types)
10
- * - Strictly monotonic version numbers
11
- * - Timestamp monotonicity (with configurable tolerance)
12
- * - Hash-chain integrity (prevHash linkage, entryHash recompute)
13
- * - Posterior chain consistency (each priorPosterior = previous updatedPosterior)
14
- * - Compaction-boundary integrity
15
- * - Enum validity (all enum values are from the public vocabulary)
16
- *
17
- * What it MUST NOT do (enforced by test):
18
- * - Never recompute a posterior
19
- * - Never contain an update function
20
- * - Never embed a weight or threshold
21
- * - Never import from any estimation module
7
+ * verify makes no network calls. Records never leave your machine.
22
8
  */
23
- import type { EvidenceRecord } from "../schema/evidence-record";
9
+ import type { EvidenceRecord } from "../schema/evidence-record.js";
24
10
  export interface Violation {
25
- /** Entry version where the violation was found, or 0 for record-level. */
26
11
  version: number;
27
- /** Category of the violation. */
28
12
  category: "schema" | "version" | "timestamp" | "hash" | "posterior" | "compaction" | "enum";
29
- /** Human-readable description. */
30
13
  message: string;
14
+ checkId: string;
31
15
  }
32
16
  export interface VerificationResult {
33
- /** Whether the record passed all checks. */
34
17
  valid: boolean;
35
- /** List of violations found. */
36
18
  violations: Violation[];
37
- /** Number of entries checked. */
38
19
  entriesChecked: number;
39
20
  }
40
- /**
41
- * Verify the integrity of an evidence record.
42
- *
43
- * @param record The evidence record to verify.
44
- * @param timestampToleranceMs Maximum allowed backward timestamp drift (default: 1000ms).
45
- * @returns Verification result with any violations found.
46
- */
47
21
  export declare function verifyRecord(record: EvidenceRecord, timestampToleranceMs?: number): VerificationResult;
48
22
  //# sourceMappingURL=verify-record.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"verify-record.d.ts","sourceRoot":"","sources":["../../src/verifier/verify-record.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAiB,MAAM,2BAA2B,CAAC;AAI/E,MAAM,WAAW,SAAS;IACxB,0EAA0E;IAC1E,OAAO,EAAE,MAAM,CAAC;IAChB,iCAAiC;IACjC,QAAQ,EAAE,QAAQ,GAAG,SAAS,GAAG,WAAW,GAAG,MAAM,GAAG,WAAW,GAAG,YAAY,GAAG,MAAM,CAAC;IAC5F,kCAAkC;IAClC,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,kBAAkB;IACjC,4CAA4C;IAC5C,KAAK,EAAE,OAAO,CAAC;IACf,gCAAgC;IAChC,UAAU,EAAE,SAAS,EAAE,CAAC;IACxB,iCAAiC;IACjC,cAAc,EAAE,MAAM,CAAC;CACxB;AAOD;;;;;;GAMG;AACH,wBAAgB,YAAY,CAC1B,MAAM,EAAE,cAAc,EACtB,oBAAoB,GAAE,MAAa,GAClC,kBAAkB,CA2IpB"}
1
+ {"version":3,"file":"verify-record.d.ts","sourceRoot":"","sources":["../../src/verifier/verify-record.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAiB,MAAM,8BAA8B,CAAC;AAIlF,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,QAAQ,GAAG,SAAS,GAAG,WAAW,GAAG,MAAM,GAAG,WAAW,GAAG,YAAY,GAAG,MAAM,CAAC;IAC5F,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,OAAO,CAAC;IACf,UAAU,EAAE,SAAS,EAAE,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;CACxB;AAYD,wBAAgB,YAAY,CAC1B,MAAM,EAAE,cAAc,EACtB,oBAAoB,GAAE,MAAa,GAClC,kBAAkB,CAwHpB"}
@@ -2,148 +2,113 @@
2
2
  * Evidence Record Verifier
3
3
  *
4
4
  * Verifies the bookkeeping integrity of an evidence record WITHOUT
5
- * containing any estimation mathematics. This distinction is the design:
6
- * "verify instead of trust."
5
+ * containing any estimation mathematics.
7
6
  *
8
- * What it checks:
9
- * - Schema validity (required fields present, correct types)
10
- * - Strictly monotonic version numbers
11
- * - Timestamp monotonicity (with configurable tolerance)
12
- * - Hash-chain integrity (prevHash linkage, entryHash recompute)
13
- * - Posterior chain consistency (each priorPosterior = previous updatedPosterior)
14
- * - Compaction-boundary integrity
15
- * - Enum validity (all enum values are from the public vocabulary)
16
- *
17
- * What it MUST NOT do (enforced by test):
18
- * - Never recompute a posterior
19
- * - Never contain an update function
20
- * - Never embed a weight or threshold
21
- * - Never import from any estimation module
7
+ * verify makes no network calls. Records never leave your machine.
22
8
  */
23
- import { hashEntry } from "./hash";
9
+ import { hashEntry } from "./hash.js";
24
10
  const VALID_SCAFFOLD_TYPES = ["none", "socratic", "probing", "metacognitive", "scaffolding", "explain", "hint", "demonstrate"];
25
11
  const VALID_DEPTH_LEVELS = ["surface", "conceptual", "transfer", "integration"];
26
12
  const VALID_EPISTEMIC_MODES = ["experience", "inference", "analogy", "testimony"];
27
13
  const VALID_TRIAGE_RESULTS = ["correct", "slip", "misconception", "disengagement", "ambiguous"];
28
- /**
29
- * Verify the integrity of an evidence record.
30
- *
31
- * @param record The evidence record to verify.
32
- * @param timestampToleranceMs Maximum allowed backward timestamp drift (default: 1000ms).
33
- * @returns Verification result with any violations found.
34
- */
14
+ function isValidISO8601(ts) {
15
+ const d = new Date(ts);
16
+ return !isNaN(d.getTime()) && ts.length > 0;
17
+ }
35
18
  export function verifyRecord(record, timestampToleranceMs = 1000) {
36
19
  const violations = [];
37
- // Record-level schema checks
38
20
  if (!record.studentScopeId || typeof record.studentScopeId !== "string") {
39
- violations.push({ version: 0, category: "schema", message: "Missing or invalid studentScopeId" });
21
+ violations.push({ version: 0, category: "schema", message: "Missing or invalid studentScopeId", checkId: "SCHEMA.REQUIRED" });
40
22
  }
41
23
  if (!Array.isArray(record.entries)) {
42
- violations.push({ version: 0, category: "schema", message: "entries must be an array" });
24
+ violations.push({ version: 0, category: "schema", message: "entries must be an array", checkId: "SCHEMA.REQUIRED" });
43
25
  return { valid: false, violations, entriesChecked: 0 };
44
26
  }
45
- // Compaction boundary check
27
+ // Compaction boundary
46
28
  if (record.compactedBefore) {
47
29
  if (typeof record.compactedBefore.version !== "number") {
48
- violations.push({ version: 0, category: "compaction", message: "compactedBefore.version must be a number" });
30
+ violations.push({ version: 0, category: "compaction", message: "compactedBefore.version must be a number", checkId: "COMPACTION.BOUNDARY" });
49
31
  }
50
32
  if (typeof record.compactedBefore.summaryHash !== "string" || !record.compactedBefore.summaryHash) {
51
- violations.push({ version: 0, category: "compaction", message: "compactedBefore.summaryHash must be a non-empty string" });
33
+ violations.push({ version: 0, category: "compaction", message: "compactedBefore.summaryHash must be a non-empty string", checkId: "COMPACTION.BOUNDARY" });
52
34
  }
53
- // First entry version must be > compaction boundary
54
35
  if (record.entries.length > 0 && record.entries[0].version <= record.compactedBefore.version) {
55
36
  violations.push({
56
- version: record.entries[0].version,
57
- category: "compaction",
37
+ version: record.entries[0].version, category: "compaction",
58
38
  message: `First entry version (${record.entries[0].version}) must be > compaction boundary (${record.compactedBefore.version})`,
39
+ checkId: "COMPACTION.BOUNDARY",
59
40
  });
60
41
  }
61
42
  }
62
43
  let prevVersion = record.compactedBefore?.version ?? 0;
63
44
  let prevTimestamp = "";
64
45
  let prevHash = record.compactedBefore?.summaryHash ?? "";
65
- // Track last updatedPosterior per scope for posterior chain check
66
46
  let lastUpdatedPosterior = null;
67
- for (let i = 0; i < record.entries.length; i++) {
68
- const entry = record.entries[i];
47
+ for (const entry of record.entries) {
69
48
  const v = entry.version ?? -1;
70
- // Schema validation
49
+ // SCHEMA.REQUIRED
71
50
  if (typeof v !== "number" || v < 1) {
72
- violations.push({ version: v, category: "schema", message: "version must be a positive integer" });
51
+ violations.push({ version: v, category: "schema", message: "version must be a positive integer", checkId: "SCHEMA.REQUIRED" });
73
52
  }
74
53
  if (typeof entry.timestamp !== "string" || !entry.timestamp) {
75
- violations.push({ version: v, category: "schema", message: "timestamp is required" });
76
- }
77
- if (entry.event === undefined || entry.event === null) {
78
- violations.push({ version: v, category: "schema", message: "event is required" });
54
+ violations.push({ version: v, category: "schema", message: "timestamp is required", checkId: "SCHEMA.REQUIRED" });
79
55
  }
56
+ // SCHEMA.TYPES
80
57
  if (typeof entry.evidentialWeight !== "number") {
81
- violations.push({ version: v, category: "schema", message: "evidentialWeight must be a number" });
58
+ violations.push({ version: v, category: "schema", message: "evidentialWeight must be a number", checkId: "SCHEMA.TYPES" });
82
59
  }
83
60
  if (typeof entry.priorPosterior !== "number") {
84
- violations.push({ version: v, category: "schema", message: "priorPosterior must be a number" });
61
+ violations.push({ version: v, category: "schema", message: "priorPosterior must be a number", checkId: "SCHEMA.TYPES" });
85
62
  }
86
63
  if (typeof entry.updatedPosterior !== "number") {
87
- violations.push({ version: v, category: "schema", message: "updatedPosterior must be a number" });
64
+ violations.push({ version: v, category: "schema", message: "updatedPosterior must be a number", checkId: "SCHEMA.TYPES" });
88
65
  }
89
- // Strictly monotonic versions
66
+ // SCHEMA.TIMESTAMP_FORMAT
67
+ if (typeof entry.timestamp === "string" && entry.timestamp && !isValidISO8601(entry.timestamp)) {
68
+ violations.push({ version: v, category: "timestamp", message: `Timestamp is not valid ISO 8601: "${entry.timestamp}"`, checkId: "SCHEMA.TIMESTAMP_FORMAT" });
69
+ }
70
+ // VERSION.MONOTONIC
90
71
  if (v <= prevVersion) {
91
- violations.push({
92
- version: v,
93
- category: "version",
94
- message: `Version ${v} is not strictly greater than previous ${prevVersion}`,
95
- });
72
+ violations.push({ version: v, category: "version", message: `Version ${v} <= previous ${prevVersion}`, checkId: "VERSION.MONOTONIC" });
96
73
  }
97
- // Timestamp monotonicity (with tolerance)
74
+ // TIMESTAMP.MONOTONIC
98
75
  if (prevTimestamp && entry.timestamp) {
99
76
  const prevMs = new Date(prevTimestamp).getTime();
100
77
  const currMs = new Date(entry.timestamp).getTime();
101
78
  if (!isNaN(prevMs) && !isNaN(currMs) && currMs < prevMs - timestampToleranceMs) {
102
- violations.push({
103
- version: v,
104
- category: "timestamp",
105
- message: `Timestamp goes backward: ${entry.timestamp} < ${prevTimestamp} (tolerance: ${timestampToleranceMs}ms)`,
106
- });
79
+ violations.push({ version: v, category: "timestamp", message: "Timestamp goes backward", checkId: "TIMESTAMP.MONOTONIC" });
107
80
  }
108
81
  }
109
- // Enum validation
82
+ // ENUM.VALID
110
83
  if (entry.scaffoldType && !VALID_SCAFFOLD_TYPES.includes(entry.scaffoldType)) {
111
- violations.push({ version: v, category: "enum", message: `Invalid scaffoldType: ${entry.scaffoldType}` });
84
+ violations.push({ version: v, category: "enum", message: `Invalid scaffoldType: ${entry.scaffoldType}`, checkId: "ENUM.VALID" });
112
85
  }
113
86
  if (entry.depthLevel && !VALID_DEPTH_LEVELS.includes(entry.depthLevel)) {
114
- violations.push({ version: v, category: "enum", message: `Invalid depthLevel: ${entry.depthLevel}` });
87
+ violations.push({ version: v, category: "enum", message: `Invalid depthLevel: ${entry.depthLevel}`, checkId: "ENUM.VALID" });
115
88
  }
116
89
  if (entry.epistemicMode && !VALID_EPISTEMIC_MODES.includes(entry.epistemicMode)) {
117
- violations.push({ version: v, category: "enum", message: `Invalid epistemicMode: ${entry.epistemicMode}` });
90
+ violations.push({ version: v, category: "enum", message: `Invalid epistemicMode: ${entry.epistemicMode}`, checkId: "ENUM.VALID" });
118
91
  }
119
92
  if (entry.triageResult && !VALID_TRIAGE_RESULTS.includes(entry.triageResult)) {
120
- violations.push({ version: v, category: "enum", message: `Invalid triageResult: ${entry.triageResult}` });
93
+ violations.push({ version: v, category: "enum", message: `Invalid triageResult: ${entry.triageResult}`, checkId: "ENUM.VALID" });
121
94
  }
122
- // Hash-chain integrity
95
+ // HASH.PREV_LINK
123
96
  if (entry.prevHash !== prevHash) {
124
- violations.push({
125
- version: v,
126
- category: "hash",
127
- message: `prevHash mismatch: expected "${prevHash}", got "${entry.prevHash}"`,
128
- });
97
+ violations.push({ version: v, category: "hash", message: "prevHash mismatch", checkId: "HASH.PREV_LINK" });
129
98
  }
99
+ // HASH.ENTRY_RECOMPUTE
130
100
  const computedHash = hashEntry(entry);
131
101
  if (entry.entryHash !== computedHash) {
132
- violations.push({
133
- version: v,
134
- category: "hash",
135
- message: `entryHash mismatch: expected "${computedHash}", got "${entry.entryHash}"`,
136
- });
102
+ violations.push({ version: v, category: "hash", message: "entryHash mismatch", checkId: "HASH.ENTRY_RECOMPUTE" });
137
103
  }
138
- // Posterior chain consistency
139
- // Each entry's priorPosterior should equal the previous entry's updatedPosterior
104
+ // POSTERIOR.CHAIN
140
105
  if (lastUpdatedPosterior !== null && typeof entry.priorPosterior === "number") {
141
106
  const diff = Math.abs(entry.priorPosterior - lastUpdatedPosterior);
142
107
  if (diff > 1e-9) {
143
108
  violations.push({
144
- version: v,
145
- category: "posterior",
146
- message: `priorPosterior (${entry.priorPosterior}) does not match previous updatedPosterior (${lastUpdatedPosterior})`,
109
+ version: v, category: "posterior",
110
+ message: `priorPosterior (${entry.priorPosterior}) != previous updatedPosterior (${lastUpdatedPosterior})`,
111
+ checkId: "POSTERIOR.CHAIN",
147
112
  });
148
113
  }
149
114
  }
@@ -154,10 +119,6 @@ export function verifyRecord(record, timestampToleranceMs = 1000) {
154
119
  lastUpdatedPosterior = entry.updatedPosterior;
155
120
  }
156
121
  }
157
- return {
158
- valid: violations.length === 0,
159
- violations,
160
- entriesChecked: record.entries.length,
161
- };
122
+ return { valid: violations.length === 0, violations, entriesChecked: record.entries.length };
162
123
  }
163
124
  //# sourceMappingURL=verify-record.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"verify-record.js","sourceRoot":"","sources":["../../src/verifier/verify-record.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAIH,OAAO,EAAE,SAAS,EAAiB,MAAM,QAAQ,CAAC;AAoBlD,MAAM,oBAAoB,GAAmB,CAAC,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,eAAe,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,EAAE,aAAa,CAAC,CAAC;AAC/I,MAAM,kBAAkB,GAAiB,CAAC,SAAS,EAAE,YAAY,EAAE,UAAU,EAAE,aAAa,CAAC,CAAC;AAC9F,MAAM,qBAAqB,GAAoB,CAAC,YAAY,EAAE,WAAW,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC;AACnG,MAAM,oBAAoB,GAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,eAAe,EAAE,eAAe,EAAE,WAAW,CAAC,CAAC;AAEhH;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAC1B,MAAsB,EACtB,uBAA+B,IAAI;IAEnC,MAAM,UAAU,GAAgB,EAAE,CAAC;IAEnC,6BAA6B;IAC7B,IAAI,CAAC,MAAM,CAAC,cAAc,IAAI,OAAO,MAAM,CAAC,cAAc,KAAK,QAAQ,EAAE,CAAC;QACxE,UAAU,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,mCAAmC,EAAE,CAAC,CAAC;IACpG,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;QACnC,UAAU,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,0BAA0B,EAAE,CAAC,CAAC;QACzF,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,CAAC,EAAE,CAAC;IACzD,CAAC;IAED,4BAA4B;IAC5B,IAAI,MAAM,CAAC,eAAe,EAAE,CAAC;QAC3B,IAAI,OAAO,MAAM,CAAC,eAAe,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;YACvD,UAAU,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,YAAY,EAAE,OAAO,EAAE,0CAA0C,EAAE,CAAC,CAAC;QAC/G,CAAC;QACD,IAAI,OAAO,MAAM,CAAC,eAAe,CAAC,WAAW,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,WAAW,EAAE,CAAC;YAClG,UAAU,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,YAAY,EAAE,OAAO,EAAE,wDAAwD,EAAE,CAAC,CAAC;QAC7H,CAAC;QACD,oDAAoD;QACpD,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,MAAM,CAAC,eAAe,CAAC,OAAO,EAAE,CAAC;YAC7F,UAAU,CAAC,IAAI,CAAC;gBACd,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO;gBAClC,QAAQ,EAAE,YAAY;gBACtB,OAAO,EAAE,wBAAwB,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,oCAAoC,MAAM,CAAC,eAAe,CAAC,OAAO,GAAG;aAChI,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,IAAI,WAAW,GAAG,MAAM,CAAC,eAAe,EAAE,OAAO,IAAI,CAAC,CAAC;IACvD,IAAI,aAAa,GAAG,EAAE,CAAC;IACvB,IAAI,QAAQ,GAAG,MAAM,CAAC,eAAe,EAAE,WAAW,IAAI,EAAE,CAAC;IACzD,kEAAkE;IAClE,IAAI,oBAAoB,GAAkB,IAAI,CAAC;IAE/C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC/C,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QAChC,MAAM,CAAC,GAAG,KAAK,CAAC,OAAO,IAAI,CAAC,CAAC,CAAC;QAE9B,oBAAoB;QACpB,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YACnC,UAAU,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,oCAAoC,EAAE,CAAC,CAAC;QACrG,CAAC;QACD,IAAI,OAAO,KAAK,CAAC,SAAS,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC;YAC5D,UAAU,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,uBAAuB,EAAE,CAAC,CAAC;QACxF,CAAC;QACD,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,KAAK,KAAK,IAAI,EAAE,CAAC;YACtD,UAAU,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,mBAAmB,EAAE,CAAC,CAAC;QACpF,CAAC;QACD,IAAI,OAAO,KAAK,CAAC,gBAAgB,KAAK,QAAQ,EAAE,CAAC;YAC/C,UAAU,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,mCAAmC,EAAE,CAAC,CAAC;QACpG,CAAC;QACD,IAAI,OAAO,KAAK,CAAC,cAAc,KAAK,QAAQ,EAAE,CAAC;YAC7C,UAAU,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,iCAAiC,EAAE,CAAC,CAAC;QAClG,CAAC;QACD,IAAI,OAAO,KAAK,CAAC,gBAAgB,KAAK,QAAQ,EAAE,CAAC;YAC/C,UAAU,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,mCAAmC,EAAE,CAAC,CAAC;QACpG,CAAC;QAED,8BAA8B;QAC9B,IAAI,CAAC,IAAI,WAAW,EAAE,CAAC;YACrB,UAAU,CAAC,IAAI,CAAC;gBACd,OAAO,EAAE,CAAC;gBACV,QAAQ,EAAE,SAAS;gBACnB,OAAO,EAAE,WAAW,CAAC,0CAA0C,WAAW,EAAE;aAC7E,CAAC,CAAC;QACL,CAAC;QAED,0CAA0C;QAC1C,IAAI,aAAa,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;YACrC,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC,aAAa,CAAC,CAAC,OAAO,EAAE,CAAC;YACjD,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,CAAC;YACnD,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,MAAM,GAAG,MAAM,GAAG,oBAAoB,EAAE,CAAC;gBAC/E,UAAU,CAAC,IAAI,CAAC;oBACd,OAAO,EAAE,CAAC;oBACV,QAAQ,EAAE,WAAW;oBACrB,OAAO,EAAE,4BAA4B,KAAK,CAAC,SAAS,MAAM,aAAa,gBAAgB,oBAAoB,KAAK;iBACjH,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,kBAAkB;QAClB,IAAI,KAAK,CAAC,YAAY,IAAI,CAAC,oBAAoB,CAAC,QAAQ,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE,CAAC;YAC7E,UAAU,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,yBAAyB,KAAK,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;QAC5G,CAAC;QACD,IAAI,KAAK,CAAC,UAAU,IAAI,CAAC,kBAAkB,CAAC,QAAQ,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC;YACvE,UAAU,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,uBAAuB,KAAK,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;QACxG,CAAC;QACD,IAAI,KAAK,CAAC,aAAa,IAAI,CAAC,qBAAqB,CAAC,QAAQ,CAAC,KAAK,CAAC,aAAa,CAAC,EAAE,CAAC;YAChF,UAAU,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,0BAA0B,KAAK,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC;QAC9G,CAAC;QACD,IAAI,KAAK,CAAC,YAAY,IAAI,CAAC,oBAAoB,CAAC,QAAQ,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE,CAAC;YAC7E,UAAU,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,yBAAyB,KAAK,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;QAC5G,CAAC;QAED,uBAAuB;QACvB,IAAI,KAAK,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;YAChC,UAAU,CAAC,IAAI,CAAC;gBACd,OAAO,EAAE,CAAC;gBACV,QAAQ,EAAE,MAAM;gBAChB,OAAO,EAAE,gCAAgC,QAAQ,WAAW,KAAK,CAAC,QAAQ,GAAG;aAC9E,CAAC,CAAC;QACL,CAAC;QACD,MAAM,YAAY,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;QACtC,IAAI,KAAK,CAAC,SAAS,KAAK,YAAY,EAAE,CAAC;YACrC,UAAU,CAAC,IAAI,CAAC;gBACd,OAAO,EAAE,CAAC;gBACV,QAAQ,EAAE,MAAM;gBAChB,OAAO,EAAE,iCAAiC,YAAY,WAAW,KAAK,CAAC,SAAS,GAAG;aACpF,CAAC,CAAC;QACL,CAAC;QAED,8BAA8B;QAC9B,iFAAiF;QACjF,IAAI,oBAAoB,KAAK,IAAI,IAAI,OAAO,KAAK,CAAC,cAAc,KAAK,QAAQ,EAAE,CAAC;YAC9E,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,cAAc,GAAG,oBAAoB,CAAC,CAAC;YACnE,IAAI,IAAI,GAAG,IAAI,EAAE,CAAC;gBAChB,UAAU,CAAC,IAAI,CAAC;oBACd,OAAO,EAAE,CAAC;oBACV,QAAQ,EAAE,WAAW;oBACrB,OAAO,EAAE,mBAAmB,KAAK,CAAC,cAAc,+CAA+C,oBAAoB,GAAG;iBACvH,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,WAAW,GAAG,CAAC,CAAC;QAChB,aAAa,GAAG,KAAK,CAAC,SAAS,CAAC;QAChC,QAAQ,GAAG,KAAK,CAAC,SAAS,CAAC;QAC3B,IAAI,OAAO,KAAK,CAAC,gBAAgB,KAAK,QAAQ,EAAE,CAAC;YAC/C,oBAAoB,GAAG,KAAK,CAAC,gBAAgB,CAAC;QAChD,CAAC;IACH,CAAC;IAED,OAAO;QACL,KAAK,EAAE,UAAU,CAAC,MAAM,KAAK,CAAC;QAC9B,UAAU;QACV,cAAc,EAAE,MAAM,CAAC,OAAO,CAAC,MAAM;KACtC,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"verify-record.js","sourceRoot":"","sources":["../../src/verifier/verify-record.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Verifier for schema 0.3 records — two-level verification.
3
+ * Evidence chain + estimate chains + record-level consent/attestation checks.
4
+ */
5
+ export interface Violation03 {
6
+ version: number;
7
+ category: string;
8
+ message: string;
9
+ checkId: string;
10
+ chain: string;
11
+ }
12
+ export interface VerificationResult03 {
13
+ valid: boolean;
14
+ level: number;
15
+ violations: Violation03[];
16
+ entriesChecked: number;
17
+ estimators: Array<{
18
+ name: string;
19
+ version: string;
20
+ opaque: boolean;
21
+ }>;
22
+ }
23
+ export declare function verifyRecordV03(record: Record<string, any>, timestampToleranceMs?: number, estimateTolerance?: number): VerificationResult03;
24
+ //# sourceMappingURL=verifier-v03.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verifier-v03.d.ts","sourceRoot":"","sources":["../src/verifier-v03.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAoBH,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,WAAW,EAAE,CAAC;IAC1B,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;CACvE;AAUD,wBAAgB,eAAe,CAC7B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC3B,oBAAoB,SAAO,EAC3B,iBAAiB,SAAO,GACvB,oBAAoB,CA+KtB"}