@uwmd/core 1.1.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (153) hide show
  1. package/README.md +3 -3
  2. package/dist/agents/bancroft.d.ts +22 -1
  3. package/dist/agents/bancroft.d.ts.map +1 -1
  4. package/dist/agents/bancroft.js +86 -60
  5. package/dist/agents/bancroft.js.map +1 -1
  6. package/dist/agents/provider.d.ts +62 -0
  7. package/dist/agents/provider.d.ts.map +1 -0
  8. package/dist/agents/provider.js +28 -0
  9. package/dist/agents/provider.js.map +1 -0
  10. package/dist/agents/providers/anthropic.d.ts +20 -0
  11. package/dist/agents/providers/anthropic.d.ts.map +1 -0
  12. package/dist/agents/providers/anthropic.js +104 -0
  13. package/dist/agents/providers/anthropic.js.map +1 -0
  14. package/dist/agents/providers/replay.d.ts +46 -0
  15. package/dist/agents/providers/replay.d.ts.map +1 -0
  16. package/dist/agents/providers/replay.js +162 -0
  17. package/dist/agents/providers/replay.js.map +1 -0
  18. package/dist/agents/schemas.d.ts +3 -3
  19. package/dist/agents/schemas.d.ts.map +1 -1
  20. package/dist/agents/schemas.js.map +1 -1
  21. package/dist/browser.d.ts +26 -3
  22. package/dist/browser.d.ts.map +1 -1
  23. package/dist/browser.js +23 -3
  24. package/dist/browser.js.map +1 -1
  25. package/dist/calc/builtins.d.ts +10 -0
  26. package/dist/calc/builtins.d.ts.map +1 -1
  27. package/dist/calc/builtins.js +64 -42
  28. package/dist/calc/builtins.js.map +1 -1
  29. package/dist/calc/errors.js +1 -1
  30. package/dist/calc/evaluator.js +6 -2
  31. package/dist/calc/evaluator.js.map +1 -1
  32. package/dist/calc/index.d.ts +7 -0
  33. package/dist/calc/index.d.ts.map +1 -1
  34. package/dist/calc/index.js +13 -1
  35. package/dist/calc/index.js.map +1 -1
  36. package/dist/calc/quantize.d.ts +56 -0
  37. package/dist/calc/quantize.d.ts.map +1 -0
  38. package/dist/calc/quantize.js +116 -0
  39. package/dist/calc/quantize.js.map +1 -0
  40. package/dist/cli-packages.d.ts +11 -0
  41. package/dist/cli-packages.d.ts.map +1 -0
  42. package/dist/cli-packages.js +177 -0
  43. package/dist/cli-packages.js.map +1 -0
  44. package/dist/cli.js +424 -28
  45. package/dist/cli.js.map +1 -1
  46. package/dist/context.js +23 -23
  47. package/dist/deal-package-context.d.ts +52 -0
  48. package/dist/deal-package-context.d.ts.map +1 -0
  49. package/dist/deal-package-context.js +132 -0
  50. package/dist/deal-package-context.js.map +1 -0
  51. package/dist/deal-package-zip.d.ts +36 -0
  52. package/dist/deal-package-zip.d.ts.map +1 -0
  53. package/dist/deal-package-zip.js +132 -0
  54. package/dist/deal-package-zip.js.map +1 -0
  55. package/dist/deal-package.d.ts +82 -0
  56. package/dist/deal-package.d.ts.map +1 -0
  57. package/dist/deal-package.js +189 -0
  58. package/dist/deal-package.js.map +1 -0
  59. package/dist/defaults.d.ts +48 -0
  60. package/dist/defaults.d.ts.map +1 -1
  61. package/dist/defaults.js +512 -0
  62. package/dist/defaults.js.map +1 -1
  63. package/dist/index.d.ts +32 -3
  64. package/dist/index.d.ts.map +1 -1
  65. package/dist/index.js +27 -3
  66. package/dist/index.js.map +1 -1
  67. package/dist/init.js +1 -1
  68. package/dist/init.js.map +1 -1
  69. package/dist/integrity.d.ts +9 -0
  70. package/dist/integrity.d.ts.map +1 -1
  71. package/dist/integrity.js +12 -2
  72. package/dist/integrity.js.map +1 -1
  73. package/dist/lease-abstract.d.ts +82 -0
  74. package/dist/lease-abstract.d.ts.map +1 -0
  75. package/dist/lease-abstract.js +183 -0
  76. package/dist/lease-abstract.js.map +1 -0
  77. package/dist/lite-bridge.d.ts +58 -0
  78. package/dist/lite-bridge.d.ts.map +1 -0
  79. package/dist/lite-bridge.js +525 -0
  80. package/dist/lite-bridge.js.map +1 -0
  81. package/dist/lite.d.ts +63 -0
  82. package/dist/lite.d.ts.map +1 -0
  83. package/dist/lite.js +362 -0
  84. package/dist/lite.js.map +1 -0
  85. package/dist/modules.d.ts.map +1 -1
  86. package/dist/modules.js +278 -13
  87. package/dist/modules.js.map +1 -1
  88. package/dist/packs/excel-emit.d.ts +18 -1
  89. package/dist/packs/excel-emit.d.ts.map +1 -1
  90. package/dist/packs/excel-emit.js +18 -1
  91. package/dist/packs/excel-emit.js.map +1 -1
  92. package/dist/packs/hospitality.d.ts +3 -0
  93. package/dist/packs/hospitality.d.ts.map +1 -0
  94. package/dist/packs/hospitality.js +122 -0
  95. package/dist/packs/hospitality.js.map +1 -0
  96. package/dist/packs/index.d.ts +5 -1
  97. package/dist/packs/index.d.ts.map +1 -1
  98. package/dist/packs/index.js +13 -1
  99. package/dist/packs/index.js.map +1 -1
  100. package/dist/packs/land.d.ts +3 -0
  101. package/dist/packs/land.d.ts.map +1 -0
  102. package/dist/packs/land.js +124 -0
  103. package/dist/packs/land.js.map +1 -0
  104. package/dist/packs/senior-housing.d.ts +3 -0
  105. package/dist/packs/senior-housing.d.ts.map +1 -0
  106. package/dist/packs/senior-housing.js +123 -0
  107. package/dist/packs/senior-housing.js.map +1 -0
  108. package/dist/packs/student-housing.d.ts +3 -0
  109. package/dist/packs/student-housing.d.ts.map +1 -0
  110. package/dist/packs/student-housing.js +124 -0
  111. package/dist/packs/student-housing.js.map +1 -0
  112. package/dist/parser.d.ts +9 -0
  113. package/dist/parser.d.ts.map +1 -1
  114. package/dist/parser.js +40 -6
  115. package/dist/parser.js.map +1 -1
  116. package/dist/protocol.d.ts +69 -2
  117. package/dist/protocol.d.ts.map +1 -1
  118. package/dist/protocol.js +109 -1
  119. package/dist/protocol.js.map +1 -1
  120. package/dist/receipts.d.ts +216 -0
  121. package/dist/receipts.d.ts.map +1 -0
  122. package/dist/receipts.js +554 -0
  123. package/dist/receipts.js.map +1 -0
  124. package/dist/report.js +165 -165
  125. package/dist/runner.d.ts +13 -0
  126. package/dist/runner.d.ts.map +1 -1
  127. package/dist/runner.js +5 -5
  128. package/dist/runner.js.map +1 -1
  129. package/dist/source-representation.d.ts +40 -0
  130. package/dist/source-representation.d.ts.map +1 -0
  131. package/dist/source-representation.js +114 -0
  132. package/dist/source-representation.js.map +1 -0
  133. package/dist/types.d.ts +9 -0
  134. package/dist/types.d.ts.map +1 -1
  135. package/dist/types.js +34 -0
  136. package/dist/types.js.map +1 -1
  137. package/dist/uwcsv.d.ts.map +1 -1
  138. package/dist/uwcsv.js +10 -78
  139. package/dist/uwcsv.js.map +1 -1
  140. package/dist/uwxml.d.ts.map +1 -1
  141. package/dist/uwxml.js +10 -2
  142. package/dist/uwxml.js.map +1 -1
  143. package/dist/validator.js +10 -10
  144. package/dist/validator.js.map +1 -1
  145. package/dist/version.d.ts +3 -0
  146. package/dist/version.d.ts.map +1 -0
  147. package/dist/version.js +8 -0
  148. package/dist/version.js.map +1 -0
  149. package/dist/zip-safety.d.ts +15 -0
  150. package/dist/zip-safety.d.ts.map +1 -0
  151. package/dist/zip-safety.js +109 -0
  152. package/dist/zip-safety.js.map +1 -0
  153. package/package.json +12 -3
@@ -0,0 +1,554 @@
1
+ // Verification receipts — RFC 0016 / `spec/UW_RECEIPT_v1.md`.
2
+ //
3
+ // A receipt is a small, detached JSON document that binds a canonical digest of
4
+ // an underwriting record to the deterministic outputs a named calc pack produced
5
+ // from it. It lets a party who did not run the calculation confirm, offline,
6
+ // that a stated set of numbers follows from a stated set of inputs.
7
+ //
8
+ // It deliberately attests NOTHING about whether those inputs are true. A record
9
+ // asserting a fabricated NOI can carry a perfectly valid receipt. See the
10
+ // assurance boundary in `spec/UW_RECEIPT_v1.md` §6 — consumers MUST NOT render a
11
+ // `verified` verdict as an unqualified checkmark.
12
+ //
13
+ // Layering: unsigned issuance and verification live here because core already
14
+ // has SHA-256 via `integrity.sha256TextHex` with no external dependency.
15
+ // Signature creation and validation belong to the separate signing package
16
+ // RFC 0010 proposes; a verifier without one returns `unverifiable` for a signed
17
+ // receipt rather than silently ignoring the signature.
18
+ import { evaluateCalc } from './calc/index.js';
19
+ import { canonicalizeUWEnvelope, fromUWEnvelope, toUWEnvelope, } from './envelope.js';
20
+ import { canonicalizeExact } from './integrity-canonical.js';
21
+ import { sha256TextHex } from './integrity.js';
22
+ import { canonicalizeUWLiteFinancial, parseUWLite } from './lite.js';
23
+ import { compileUWLite } from './lite-bridge.js';
24
+ import { getPackForAssetClass } from './packs/index.js';
25
+ import { parseUWFile } from './parser.js';
26
+ import { PROTOCOL_VERSION } from './protocol.js';
27
+ import { detectUWSourceRepresentation, UW_LITE_REPRESENTATION_ID, UW_LITE_REPRESENTATION_VERSION, UWX_REPRESENTATION_ID, UWX_REPRESENTATION_VERSION, } from './source-representation.js';
28
+ import { validateUWFile } from './validator.js';
29
+ import { CORE_PACKAGE_NAME, CORE_VERSION } from './version.js';
30
+ // ─── Constants ───────────────────────────────────────────────────────────────
31
+ export const UW_RECEIPT_VERSION = '1.0';
32
+ /** Canonicalization used for the Lite representation (UW_LITE_SPEC §6). */
33
+ export const UW_LITE_CANONICALIZATION = 'uw-lite-financial';
34
+ /** Canonicalization used for structured records (Document Envelope 1.0). */
35
+ export const UWX_CANONICALIZATION = 'uw-envelope-semantic';
36
+ /**
37
+ * Tolerance for comparing a stated numeric result against recomputation.
38
+ * Relative for large magnitudes, absolute near zero.
39
+ *
40
+ * Since §VIII.5, a *conforming* issuer can never need this: both sides quantize
41
+ * before comparison, so they agree exactly or disagree materially. It is kept as
42
+ * defence-in-depth against a third-party issuer running an alternate precision
43
+ * routine — that lands as a clean `RCP-03` naming the calc rather than an
44
+ * `RCP-04` digest mismatch that reads as corruption.
45
+ */
46
+ export const RECEIPT_RESULT_TOLERANCE = 1e-6;
47
+ /** The policy set a receipt names when the host applies core's built-in rules. */
48
+ export const BUILTIN_POLICY_SET = 'builtin';
49
+ export const BUILTIN_POLICY_SET_VERSION = '1.0';
50
+ /** Typed error, consistent with `ProtocolError` / `CalcError` / `ExcelEmitError`. */
51
+ export class ReceiptError extends Error {
52
+ code;
53
+ constructor(code, message) {
54
+ super(`[${code}] ${message}`);
55
+ this.name = 'ReceiptError';
56
+ this.code = code;
57
+ }
58
+ }
59
+ /**
60
+ * Parse, canonicalize, and digest a record. Throws a typed `ReceiptError` when
61
+ * the document has parse-level errors — an issuer MUST NOT emit a receipt for
62
+ * such a document (RFC 0016, extending UW_LITE_SPEC §5 to every representation).
63
+ */
64
+ export async function resolveReceiptSubject(content, options = {}) {
65
+ const detection = detectUWSourceRepresentation(content, options.filename, options.representation);
66
+ if (detection.representation === UW_LITE_REPRESENTATION_ID) {
67
+ const lite = parseUWLite(content);
68
+ const blocking = lite.issues.filter((issue) => issue.severity === 'error');
69
+ if (blocking.length > 0) {
70
+ throw new ReceiptError('RCP_PARSE_ERRORS', `Refusing to issue: the Lite document has ${blocking.length} parse error(s) [${blocking
71
+ .map((issue) => issue.code)
72
+ .join(', ')}].`);
73
+ }
74
+ const canonical = canonicalizeUWLiteFinancial(lite);
75
+ const compiled = compileUWLite(lite);
76
+ if (!compiled.ok) {
77
+ throw new ReceiptError('RCP_COMPILE_FAILED', `Refusing to issue: the Lite document does not compile [${compiled.report.issues
78
+ .filter((issue) => issue.severity === 'error')
79
+ .map((issue) => issue.code)
80
+ .join(', ')}].`);
81
+ }
82
+ return {
83
+ subject: {
84
+ representation: UW_LITE_REPRESENTATION_ID,
85
+ representation_version: UW_LITE_REPRESENTATION_VERSION,
86
+ canonicalization: UW_LITE_CANONICALIZATION,
87
+ canonicalization_version: UW_LITE_REPRESENTATION_VERSION,
88
+ digest: await digestOf(canonical),
89
+ },
90
+ canonical,
91
+ parsed: fromUWEnvelope(compiled.envelope),
92
+ envelope: compiled.envelope,
93
+ };
94
+ }
95
+ let parsed;
96
+ try {
97
+ parsed = parseUWFile(content);
98
+ }
99
+ catch (e) {
100
+ throw new ReceiptError('RCP_PARSE_ERRORS', `Refusing to issue: the structured document does not parse (${e instanceof Error ? e.message : String(e)}).`);
101
+ }
102
+ const envelope = toUWEnvelope(parsed);
103
+ const canonical = canonicalizeUWEnvelope(envelope);
104
+ return {
105
+ subject: {
106
+ representation: UWX_REPRESENTATION_ID,
107
+ representation_version: UWX_REPRESENTATION_VERSION,
108
+ canonicalization: UWX_CANONICALIZATION,
109
+ canonicalization_version: '1.0',
110
+ digest: await digestOf(canonical),
111
+ },
112
+ canonical,
113
+ parsed,
114
+ envelope,
115
+ };
116
+ }
117
+ async function digestOf(canonical) {
118
+ return `sha256:${await sha256TextHex(canonical)}`;
119
+ }
120
+ // ─── Computation ─────────────────────────────────────────────────────────────
121
+ /**
122
+ * Run every calc a pack declares. Throws when any one fails — a receipt states
123
+ * the pack's complete output set or it states nothing (RFC 0016).
124
+ */
125
+ export function computeReceiptResults(pack, parsed) {
126
+ const decls = pack.calculations ?? [];
127
+ if (decls.length === 0) {
128
+ throw new ReceiptError('RCP_NO_CALCULATIONS', `Pack '${pack.id}' declares no calculations, so it has no outputs to attest.`);
129
+ }
130
+ const ctx = { parsed, prior_results: {}, locale: 'en-US' };
131
+ const results = [];
132
+ const failures = [];
133
+ for (const decl of decls) {
134
+ const result = evaluateCalc(decl, ctx);
135
+ if (!result.ok) {
136
+ failures.push(`${decl.id} (${result.error?.code ?? 'unknown'})`);
137
+ continue;
138
+ }
139
+ // The engine reports "inputs absent" as a successful evaluation to null.
140
+ // A receipt records that as an uncomputed output, not as a computed null.
141
+ const computed = result.value !== null;
142
+ results.push({
143
+ calc_id: result.calc_id,
144
+ value: computed ? result.value : null,
145
+ ...(decl.unit ? { unit: decl.unit } : {}),
146
+ computed,
147
+ });
148
+ }
149
+ if (failures.length > 0) {
150
+ throw new ReceiptError('RCP_COMPUTATION_FAILED', `Refusing to issue: ${failures.length} of ${decls.length} pack calculations did not evaluate [${failures.join(', ')}].`);
151
+ }
152
+ // Deterministic order regardless of declaration order, so re-issuance over an
153
+ // unmodified record reproduces byte-identical results.
154
+ return results.sort((left, right) => left.calc_id.localeCompare(right.calc_id));
155
+ }
156
+ /** SHA-256 over the RFC 8785 canonicalization of the result set. */
157
+ export async function computeResultsDigest(results) {
158
+ return digestOf(canonicalizeExact(results));
159
+ }
160
+ /**
161
+ * Issue an unsigned receipt for a record. Either returns a receipt or throws a
162
+ * typed `ReceiptError` — never a caveated or partial receipt.
163
+ */
164
+ export async function issueReceipt(content, options = {}) {
165
+ const resolved = await resolveReceiptSubject(content, options);
166
+ const pack = resolvePack(resolved.parsed, options.pack);
167
+ const results = computeReceiptResults(pack, resolved.parsed);
168
+ const validation = validateUWFile(resolved.parsed);
169
+ return {
170
+ receipt_version: UW_RECEIPT_VERSION,
171
+ subject: resolved.subject,
172
+ computation: {
173
+ pack: pack.id,
174
+ pack_version: pack.version,
175
+ engine: options.engine ?? CORE_PACKAGE_NAME,
176
+ engine_version: options.engine_version ?? CORE_VERSION,
177
+ protocol_version: options.protocol_version ?? PROTOCOL_VERSION,
178
+ results,
179
+ results_digest: await computeResultsDigest(results),
180
+ },
181
+ policy: {
182
+ policy_set: options.policy_set ?? BUILTIN_POLICY_SET,
183
+ policy_set_version: options.policy_set_version ?? BUILTIN_POLICY_SET_VERSION,
184
+ validation: {
185
+ errors: validation.errors.length,
186
+ warnings: validation.warnings.length,
187
+ },
188
+ },
189
+ issued_at: options.issued_at ?? new Date().toISOString(),
190
+ issuer: options.issuer ?? `${CORE_PACKAGE_NAME}@${CORE_VERSION}`,
191
+ signature: null,
192
+ };
193
+ }
194
+ function resolvePack(parsed, override) {
195
+ const assetClass = parsed.frontmatter.asset_class;
196
+ const pack = override ?? (assetClass ? getPackForAssetClass(assetClass) : null);
197
+ if (!pack) {
198
+ throw new ReceiptError('RCP_PACK_UNRESOLVED', `No calc pack is registered for asset class '${assetClass ?? '(unset)'}'; pass one explicitly to issue a receipt.`);
199
+ }
200
+ if (!pack.version) {
201
+ throw new ReceiptError('RCP_PACK_UNVERSIONED', `Pack '${pack.id}' declares no version; an unversioned pack cannot be named in a receipt.`);
202
+ }
203
+ return pack;
204
+ }
205
+ /**
206
+ * The RFC 8785 canonicalization a signature covers: the receipt with
207
+ * `signature` set to null.
208
+ */
209
+ export function receiptSigningPayload(receipt) {
210
+ return canonicalizeExact({ ...receipt, signature: null });
211
+ }
212
+ /**
213
+ * Verify a receipt against a record.
214
+ *
215
+ * Reports exactly one of three verdicts and never collapses `unverifiable` into
216
+ * either of the others. Precedence:
217
+ *
218
+ * 1. A digest mismatch is decisive — the record changed. `failed`.
219
+ * 2. Otherwise, anything this verifier cannot decide (unknown pack, pack
220
+ * version it does not hold, a signature with no backend) → `unverifiable`.
221
+ * 3. Otherwise, recomputation disagreement → `failed`, unless the issuing
222
+ * engine identity (name *and* version) differs from this verifier's, in
223
+ * which case the disagreement is attributable to the engine and the
224
+ * verdict is `unverifiable` (RFC 0016 open question, resolved in
225
+ * `spec/UW_RECEIPT_v1.md` §5).
226
+ * 4. Otherwise `verified`.
227
+ *
228
+ * The verifier always recomputes; `results_digest` is checked only as a cheap
229
+ * corruption signal and never authorizes skipping the recomputation.
230
+ */
231
+ export async function verifyReceipt(receipt, content, options = {}) {
232
+ assertUWReceipt(receipt);
233
+ const issues = [];
234
+ // The document must canonicalize before anything can be compared to it.
235
+ let resolved;
236
+ try {
237
+ resolved = await resolveReceiptSubject(content, {
238
+ filename: options.filename,
239
+ representation: options.representation ?? receipt.subject.representation,
240
+ });
241
+ }
242
+ catch (e) {
243
+ return {
244
+ verdict: 'unverifiable',
245
+ issues: [
246
+ {
247
+ code: 'RCP-09',
248
+ severity: 'indeterminate',
249
+ message: `The record could not be canonicalized for comparison: ${e instanceof Error ? e.message : String(e)}`,
250
+ },
251
+ ],
252
+ };
253
+ }
254
+ // 1 — digest. Decisive on mismatch.
255
+ if (resolved.subject.digest !== receipt.subject.digest) {
256
+ return {
257
+ verdict: 'failed',
258
+ issues: [
259
+ {
260
+ code: 'RCP-01',
261
+ severity: 'failure',
262
+ message: 'The record\'s canonical financial content has changed since the receipt was issued.',
263
+ expected: receipt.subject.digest,
264
+ actual: resolved.subject.digest,
265
+ },
266
+ ],
267
+ };
268
+ }
269
+ // 2 — can this verifier decide at all?
270
+ const pack = lookupPack(receipt.computation.pack, options.packs);
271
+ if (!pack) {
272
+ issues.push({
273
+ code: 'RCP-05',
274
+ severity: 'indeterminate',
275
+ message: `This verifier does not hold pack '${receipt.computation.pack}', so it cannot recompute the stated results.`,
276
+ });
277
+ }
278
+ else if (pack.version !== receipt.computation.pack_version) {
279
+ issues.push({
280
+ code: 'RCP-06',
281
+ severity: 'indeterminate',
282
+ message: `This verifier holds pack '${pack.id}' at version ${pack.version}; the receipt names ${receipt.computation.pack_version}.`,
283
+ expected: receipt.computation.pack_version,
284
+ actual: pack.version,
285
+ });
286
+ }
287
+ if (receipt.signature && !options.signatureVerifier) {
288
+ issues.push({
289
+ code: 'RCP-08',
290
+ severity: 'indeterminate',
291
+ message: 'The receipt is signed and this verifier has no signature backend; the signature was not ignored, it was not checked.',
292
+ });
293
+ }
294
+ if (issues.some((issue) => issue.severity === 'indeterminate')) {
295
+ return { verdict: 'unverifiable', issues };
296
+ }
297
+ // 3 — recompute. `pack` is non-null here: a null pack produced RCP-05 above.
298
+ const resolvedPack = pack;
299
+ let recomputed;
300
+ try {
301
+ recomputed = computeReceiptResults(resolvedPack, resolved.parsed);
302
+ }
303
+ catch (e) {
304
+ return {
305
+ verdict: 'failed',
306
+ issues: [
307
+ {
308
+ code: 'RCP-03',
309
+ severity: 'failure',
310
+ message: `Recomputation did not produce the pack's declared outputs: ${e instanceof Error ? e.message : String(e)}`,
311
+ },
312
+ ],
313
+ recomputed: [],
314
+ };
315
+ }
316
+ // Engine identity is the pair, not the version alone. A version string only
317
+ // means something within one engine's release history: `2.1.0` of some other
318
+ // vendor's engine is not a later or earlier build of this one, it is an
319
+ // unrelated implementation that happens to have reached the same number. So a
320
+ // disagreement is attributable to the record only when both halves match.
321
+ const verifierEngine = options.engine ?? CORE_PACKAGE_NAME;
322
+ const verifierEngineVersion = options.engine_version ?? CORE_VERSION;
323
+ const engineMatches = receipt.computation.engine === verifierEngine &&
324
+ receipt.computation.engine_version === verifierEngineVersion;
325
+ if (receipt.signature && options.signatureVerifier) {
326
+ const valid = await options.signatureVerifier.verify(receipt, receiptSigningPayload(receipt));
327
+ if (!valid) {
328
+ return {
329
+ verdict: 'failed',
330
+ issues: [
331
+ {
332
+ code: 'RCP-01',
333
+ severity: 'failure',
334
+ message: 'The receipt signature did not validate.',
335
+ },
336
+ ],
337
+ recomputed,
338
+ };
339
+ }
340
+ }
341
+ const disagreements = compareResults(receipt.computation.results, recomputed);
342
+ if (disagreements.length > 0) {
343
+ if (!engineMatches) {
344
+ return {
345
+ verdict: 'unverifiable',
346
+ issues: [
347
+ {
348
+ code: 'RCP-07',
349
+ severity: 'indeterminate',
350
+ message: `Results disagree, but the receipt was issued by engine ${receipt.computation.engine}@${receipt.computation.engine_version} and this verifier runs ${verifierEngine}@${verifierEngineVersion}. The disagreement cannot be attributed to the record.`,
351
+ expected: `${receipt.computation.engine}@${receipt.computation.engine_version}`,
352
+ actual: `${verifierEngine}@${verifierEngineVersion}`,
353
+ },
354
+ ...disagreements,
355
+ ],
356
+ recomputed,
357
+ };
358
+ }
359
+ return { verdict: 'failed', issues: disagreements, recomputed };
360
+ }
361
+ // Corruption check, reported but not decisive on its own — recomputation
362
+ // already agreed, so a stale digest here means the field, not the numbers.
363
+ const expectedResultsDigest = await computeResultsDigest(receipt.computation.results);
364
+ if (expectedResultsDigest !== receipt.computation.results_digest) {
365
+ return {
366
+ verdict: 'failed',
367
+ issues: [
368
+ {
369
+ code: 'RCP-04',
370
+ severity: 'failure',
371
+ message: 'results_digest does not recompute over the stated results.',
372
+ expected: expectedResultsDigest,
373
+ actual: receipt.computation.results_digest,
374
+ },
375
+ ],
376
+ recomputed,
377
+ };
378
+ }
379
+ return { verdict: 'verified', issues: [], recomputed };
380
+ }
381
+ function lookupPack(id, packs) {
382
+ if (packs)
383
+ return packs.find((pack) => pack.id === id) ?? null;
384
+ for (const assetClass of [
385
+ 'multifamily',
386
+ 'office',
387
+ 'retail',
388
+ 'industrial',
389
+ 'self_storage',
390
+ ]) {
391
+ const pack = getPackForAssetClass(assetClass);
392
+ if (pack?.id === id)
393
+ return pack;
394
+ }
395
+ return null;
396
+ }
397
+ function compareResults(stated, recomputed) {
398
+ const issues = [];
399
+ const statedById = new Map(stated.map((result) => [result.calc_id, result]));
400
+ const recomputedById = new Map(recomputed.map((result) => [result.calc_id, result]));
401
+ for (const result of recomputed) {
402
+ if (!statedById.has(result.calc_id)) {
403
+ issues.push({
404
+ code: 'RCP-02',
405
+ severity: 'failure',
406
+ calc_id: result.calc_id,
407
+ message: `The receipt omits '${result.calc_id}', which the pack declares as an output.`,
408
+ });
409
+ }
410
+ }
411
+ for (const result of stated) {
412
+ if (!recomputedById.has(result.calc_id)) {
413
+ issues.push({
414
+ code: 'RCP-02',
415
+ severity: 'failure',
416
+ calc_id: result.calc_id,
417
+ message: `The receipt states '${result.calc_id}', which the pack does not compute.`,
418
+ });
419
+ }
420
+ }
421
+ for (const statedResult of stated) {
422
+ const actual = recomputedById.get(statedResult.calc_id);
423
+ if (!actual)
424
+ continue;
425
+ if (statedResult.computed !== actual.computed) {
426
+ issues.push({
427
+ code: 'RCP-03',
428
+ severity: 'failure',
429
+ calc_id: statedResult.calc_id,
430
+ message: statedResult.computed
431
+ ? `The receipt states a computed '${statedResult.calc_id}', but the record lacks the inputs to produce it.`
432
+ : `The receipt marks '${statedResult.calc_id}' uncomputed, but the record does produce it.`,
433
+ expected: statedResult.computed ? 'computed' : 'uncomputed',
434
+ actual: actual.computed ? 'computed' : 'uncomputed',
435
+ });
436
+ continue;
437
+ }
438
+ if (!statedResult.computed)
439
+ continue;
440
+ if (!valuesAgree(statedResult.value, actual.value)) {
441
+ issues.push({
442
+ code: 'RCP-03',
443
+ severity: 'failure',
444
+ calc_id: statedResult.calc_id,
445
+ message: `Stated '${statedResult.calc_id}' does not follow from the record.`,
446
+ expected: String(statedResult.value),
447
+ actual: String(actual.value),
448
+ });
449
+ }
450
+ }
451
+ return issues;
452
+ }
453
+ function valuesAgree(stated, actual) {
454
+ if (typeof stated === 'number' && typeof actual === 'number') {
455
+ if (Number.isNaN(stated) || Number.isNaN(actual))
456
+ return false;
457
+ if (stated === actual)
458
+ return true;
459
+ const scale = Math.max(1, Math.abs(stated), Math.abs(actual));
460
+ return Math.abs(stated - actual) <= RECEIPT_RESULT_TOLERANCE * scale;
461
+ }
462
+ return stated === actual;
463
+ }
464
+ // ─── Shape validation ────────────────────────────────────────────────────────
465
+ /** Structural check mirroring `spec/schemas/uw-receipt.schema.json`. */
466
+ export function assertUWReceipt(value) {
467
+ const fail = (message) => {
468
+ throw new ReceiptError('RCP_MALFORMED', message);
469
+ };
470
+ if (typeof value !== 'object' || value === null)
471
+ fail('A receipt must be an object.');
472
+ const receipt = value;
473
+ if (receipt['receipt_version'] !== UW_RECEIPT_VERSION) {
474
+ fail(`Unsupported receipt_version '${String(receipt['receipt_version'])}'.`);
475
+ }
476
+ const subject = receipt['subject'];
477
+ if (typeof subject !== 'object' || subject === null)
478
+ fail('receipt.subject must be an object.');
479
+ const s = subject;
480
+ for (const key of [
481
+ 'representation',
482
+ 'representation_version',
483
+ 'canonicalization',
484
+ 'canonicalization_version',
485
+ 'digest',
486
+ ]) {
487
+ if (typeof s[key] !== 'string')
488
+ fail(`receipt.subject.${key} must be a string.`);
489
+ }
490
+ if (!/^sha256:[0-9a-f]{64}$/.test(s['digest'])) {
491
+ fail('receipt.subject.digest must be sha256 followed by 64 lowercase hex characters.');
492
+ }
493
+ const computation = receipt['computation'];
494
+ if (typeof computation !== 'object' || computation === null) {
495
+ fail('receipt.computation must be an object.');
496
+ }
497
+ const c = computation;
498
+ for (const key of ['pack', 'pack_version', 'engine', 'engine_version', 'results_digest']) {
499
+ if (typeof c[key] !== 'string')
500
+ fail(`receipt.computation.${key} must be a string.`);
501
+ }
502
+ if (!Array.isArray(c['results']))
503
+ fail('receipt.computation.results must be an array.');
504
+ for (const entry of c['results']) {
505
+ if (typeof entry !== 'object' || entry === null)
506
+ fail('Each result must be an object.');
507
+ const r = entry;
508
+ if (typeof r['calc_id'] !== 'string')
509
+ fail('Each result needs a string calc_id.');
510
+ if (!['number', 'string', 'boolean'].includes(typeof r['value']) && r['value'] !== null) {
511
+ fail(`Result '${String(r['calc_id'])}' has a non-scalar value.`);
512
+ }
513
+ if (typeof r['computed'] !== 'boolean') {
514
+ fail(`Result '${String(r['calc_id'])}' must declare a boolean 'computed'.`);
515
+ }
516
+ if (r['computed'] === false && r['value'] !== null) {
517
+ fail(`Result '${String(r['calc_id'])}' is marked uncomputed but carries a value.`);
518
+ }
519
+ }
520
+ const policy = receipt['policy'];
521
+ if (typeof policy !== 'object' || policy === null)
522
+ fail('receipt.policy must be an object.');
523
+ const p = policy;
524
+ if (typeof p['policy_set'] !== 'string')
525
+ fail('receipt.policy.policy_set must be a string.');
526
+ if (typeof p['policy_set_version'] !== 'string') {
527
+ fail('receipt.policy.policy_set_version must be a string.');
528
+ }
529
+ const validation = p['validation'];
530
+ if (typeof validation !== 'object' || validation === null) {
531
+ fail('receipt.policy.validation must be an object.');
532
+ }
533
+ const v = validation;
534
+ for (const key of ['errors', 'warnings']) {
535
+ if (typeof v[key] !== 'number' || !Number.isInteger(v[key])) {
536
+ fail(`receipt.policy.validation.${key} must be an integer.`);
537
+ }
538
+ }
539
+ if (typeof receipt['issued_at'] !== 'string')
540
+ fail('receipt.issued_at must be a string.');
541
+ if (typeof receipt['issuer'] !== 'string')
542
+ fail('receipt.issuer must be a string.');
543
+ const signature = receipt['signature'];
544
+ if (signature !== null && signature !== undefined) {
545
+ if (typeof signature !== 'object')
546
+ fail('receipt.signature must be an object or null.');
547
+ const sig = signature;
548
+ for (const key of ['algorithm', 'key_id', 'value']) {
549
+ if (typeof sig[key] !== 'string')
550
+ fail(`receipt.signature.${key} must be a string.`);
551
+ }
552
+ }
553
+ }
554
+ //# sourceMappingURL=receipts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"receipts.js","sourceRoot":"","sources":["../src/receipts.ts"],"names":[],"mappings":"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"}