@uwmd/core 1.1.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/README.md +79 -0
- package/dist/agents/bancroft.d.ts +32 -0
- package/dist/agents/bancroft.d.ts.map +1 -0
- package/dist/agents/bancroft.js +292 -0
- package/dist/agents/bancroft.js.map +1 -0
- package/dist/agents/schemas.d.ts +13 -0
- package/dist/agents/schemas.d.ts.map +1 -0
- package/dist/agents/schemas.js +74 -0
- package/dist/agents/schemas.js.map +1 -0
- package/dist/bindings.d.ts +85 -0
- package/dist/bindings.d.ts.map +1 -0
- package/dist/bindings.js +293 -0
- package/dist/bindings.js.map +1 -0
- package/dist/browser.d.ts +66 -0
- package/dist/browser.d.ts.map +1 -0
- package/dist/browser.js +53 -0
- package/dist/browser.js.map +1 -0
- package/dist/calc/builtins.d.ts +4 -0
- package/dist/calc/builtins.d.ts.map +1 -0
- package/dist/calc/builtins.js +329 -0
- package/dist/calc/builtins.js.map +1 -0
- package/dist/calc/dependencies.d.ts +34 -0
- package/dist/calc/dependencies.d.ts.map +1 -0
- package/dist/calc/dependencies.js +101 -0
- package/dist/calc/dependencies.js.map +1 -0
- package/dist/calc/errors.d.ts +8 -0
- package/dist/calc/errors.d.ts.map +1 -0
- package/dist/calc/errors.js +18 -0
- package/dist/calc/errors.js.map +1 -0
- package/dist/calc/evaluator.d.ts +5 -0
- package/dist/calc/evaluator.d.ts.map +1 -0
- package/dist/calc/evaluator.js +184 -0
- package/dist/calc/evaluator.js.map +1 -0
- package/dist/calc/index.d.ts +14 -0
- package/dist/calc/index.d.ts.map +1 -0
- package/dist/calc/index.js +56 -0
- package/dist/calc/index.js.map +1 -0
- package/dist/calc/parser.d.ts +32 -0
- package/dist/calc/parser.d.ts.map +1 -0
- package/dist/calc/parser.js +361 -0
- package/dist/calc/parser.js.map +1 -0
- package/dist/cascade.d.ts +85 -0
- package/dist/cascade.d.ts.map +1 -0
- package/dist/cascade.js +172 -0
- package/dist/cascade.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +843 -0
- package/dist/cli.js.map +1 -0
- package/dist/codec.d.ts +25 -0
- package/dist/codec.d.ts.map +1 -0
- package/dist/codec.js +62 -0
- package/dist/codec.js.map +1 -0
- package/dist/codecs.d.ts +6 -0
- package/dist/codecs.d.ts.map +1 -0
- package/dist/codecs.js +12 -0
- package/dist/codecs.js.map +1 -0
- package/dist/compactor.d.ts +11 -0
- package/dist/compactor.d.ts.map +1 -0
- package/dist/compactor.js +84 -0
- package/dist/compactor.js.map +1 -0
- package/dist/context-profiles.d.ts +30 -0
- package/dist/context-profiles.d.ts.map +1 -0
- package/dist/context-profiles.js +225 -0
- package/dist/context-profiles.js.map +1 -0
- package/dist/context.d.ts +55 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +288 -0
- package/dist/context.js.map +1 -0
- package/dist/dcf.d.ts +9 -0
- package/dist/dcf.d.ts.map +1 -0
- package/dist/dcf.js +75 -0
- package/dist/dcf.js.map +1 -0
- package/dist/debt.d.ts +11 -0
- package/dist/debt.d.ts.map +1 -0
- package/dist/debt.js +85 -0
- package/dist/debt.js.map +1 -0
- package/dist/defaults.d.ts +104 -0
- package/dist/defaults.d.ts.map +1 -0
- package/dist/defaults.js +622 -0
- package/dist/defaults.js.map +1 -0
- package/dist/derived.d.ts +17 -0
- package/dist/derived.d.ts.map +1 -0
- package/dist/derived.js +29 -0
- package/dist/derived.js.map +1 -0
- package/dist/editor.d.ts +76 -0
- package/dist/editor.d.ts.map +1 -0
- package/dist/editor.js +502 -0
- package/dist/editor.js.map +1 -0
- package/dist/envelope.d.ts +51 -0
- package/dist/envelope.d.ts.map +1 -0
- package/dist/envelope.js +213 -0
- package/dist/envelope.js.map +1 -0
- package/dist/format.d.ts +60 -0
- package/dist/format.d.ts.map +1 -0
- package/dist/format.js +115 -0
- package/dist/format.js.map +1 -0
- package/dist/gaps.d.ts +62 -0
- package/dist/gaps.d.ts.map +1 -0
- package/dist/gaps.js +272 -0
- package/dist/gaps.js.map +1 -0
- package/dist/index.d.ts +75 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +47 -0
- package/dist/index.js.map +1 -0
- package/dist/init.d.ts +15 -0
- package/dist/init.d.ts.map +1 -0
- package/dist/init.js +169 -0
- package/dist/init.js.map +1 -0
- package/dist/integrity-canonical.d.ts +17 -0
- package/dist/integrity-canonical.d.ts.map +1 -0
- package/dist/integrity-canonical.js +124 -0
- package/dist/integrity-canonical.js.map +1 -0
- package/dist/integrity.d.ts +54 -0
- package/dist/integrity.d.ts.map +1 -0
- package/dist/integrity.js +244 -0
- package/dist/integrity.js.map +1 -0
- package/dist/modules.d.ts +24 -0
- package/dist/modules.d.ts.map +1 -0
- package/dist/modules.js +322 -0
- package/dist/modules.js.map +1 -0
- package/dist/negotiation.d.ts +19 -0
- package/dist/negotiation.d.ts.map +1 -0
- package/dist/negotiation.js +70 -0
- package/dist/negotiation.js.map +1 -0
- package/dist/opstatement.d.ts +9 -0
- package/dist/opstatement.d.ts.map +1 -0
- package/dist/opstatement.js +80 -0
- package/dist/opstatement.js.map +1 -0
- package/dist/packs/excel-emit.d.ts +21 -0
- package/dist/packs/excel-emit.d.ts.map +1 -0
- package/dist/packs/excel-emit.js +135 -0
- package/dist/packs/excel-emit.js.map +1 -0
- package/dist/packs/index.d.ts +13 -0
- package/dist/packs/index.d.ts.map +1 -0
- package/dist/packs/index.js +37 -0
- package/dist/packs/index.js.map +1 -0
- package/dist/packs/industrial.d.ts +3 -0
- package/dist/packs/industrial.d.ts.map +1 -0
- package/dist/packs/industrial.js +115 -0
- package/dist/packs/industrial.js.map +1 -0
- package/dist/packs/multifamily.d.ts +3 -0
- package/dist/packs/multifamily.d.ts.map +1 -0
- package/dist/packs/multifamily.js +82 -0
- package/dist/packs/multifamily.js.map +1 -0
- package/dist/packs/office.d.ts +3 -0
- package/dist/packs/office.d.ts.map +1 -0
- package/dist/packs/office.js +108 -0
- package/dist/packs/office.js.map +1 -0
- package/dist/packs/retail.d.ts +3 -0
- package/dist/packs/retail.d.ts.map +1 -0
- package/dist/packs/retail.js +115 -0
- package/dist/packs/retail.js.map +1 -0
- package/dist/packs/self-storage.d.ts +3 -0
- package/dist/packs/self-storage.d.ts.map +1 -0
- package/dist/packs/self-storage.js +105 -0
- package/dist/packs/self-storage.js.map +1 -0
- package/dist/parser.d.ts +15 -0
- package/dist/parser.d.ts.map +1 -0
- package/dist/parser.js +430 -0
- package/dist/parser.js.map +1 -0
- package/dist/protocol.d.ts +389 -0
- package/dist/protocol.d.ts.map +1 -0
- package/dist/protocol.js +714 -0
- package/dist/protocol.js.map +1 -0
- package/dist/refinement.d.ts +63 -0
- package/dist/refinement.d.ts.map +1 -0
- package/dist/refinement.js +242 -0
- package/dist/refinement.js.map +1 -0
- package/dist/renderer.d.ts +22 -0
- package/dist/renderer.d.ts.map +1 -0
- package/dist/renderer.js +478 -0
- package/dist/renderer.js.map +1 -0
- package/dist/rentroll.d.ts +21 -0
- package/dist/rentroll.d.ts.map +1 -0
- package/dist/rentroll.js +256 -0
- package/dist/rentroll.js.map +1 -0
- package/dist/report.d.ts +29 -0
- package/dist/report.d.ts.map +1 -0
- package/dist/report.js +924 -0
- package/dist/report.js.map +1 -0
- package/dist/runner.d.ts +43 -0
- package/dist/runner.d.ts.map +1 -0
- package/dist/runner.js +288 -0
- package/dist/runner.js.map +1 -0
- package/dist/sourcesuses.d.ts +14 -0
- package/dist/sourcesuses.d.ts.map +1 -0
- package/dist/sourcesuses.js +63 -0
- package/dist/sourcesuses.js.map +1 -0
- package/dist/types.d.ts +248 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +15 -0
- package/dist/types.js.map +1 -0
- package/dist/uwcsv.d.ts +23 -0
- package/dist/uwcsv.d.ts.map +1 -0
- package/dist/uwcsv.js +877 -0
- package/dist/uwcsv.js.map +1 -0
- package/dist/uwjson.d.ts +19 -0
- package/dist/uwjson.d.ts.map +1 -0
- package/dist/uwjson.js +61 -0
- package/dist/uwjson.js.map +1 -0
- package/dist/uwxml.d.ts +18 -0
- package/dist/uwxml.d.ts.map +1 -0
- package/dist/uwxml.js +297 -0
- package/dist/uwxml.js.map +1 -0
- package/dist/validator.d.ts +35 -0
- package/dist/validator.d.ts.map +1 -0
- package/dist/validator.js +553 -0
- package/dist/validator.js.map +1 -0
- package/dist/valuation.d.ts +9 -0
- package/dist/valuation.d.ts.map +1 -0
- package/dist/valuation.js +34 -0
- package/dist/valuation.js.map +1 -0
- package/package.json +58 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Produce a canonical JSON serialization of `value` per RFC 8785 with the
|
|
3
|
+
* uw-md exclusions described above.
|
|
4
|
+
*
|
|
5
|
+
* Behavior:
|
|
6
|
+
* - Object keys sorted by code-unit comparison.
|
|
7
|
+
* - Strings JSON-escaped per RFC 8785 §3.2.2.
|
|
8
|
+
* - Numbers serialized per RFC 8785 §3.2.2.3 (ECMAScript ToString) with
|
|
9
|
+
* special-cases: integers render without decimals; non-finite numbers
|
|
10
|
+
* throw (JSON cannot represent them).
|
|
11
|
+
* - `undefined` values inside objects are dropped (mirrors JSON.stringify).
|
|
12
|
+
* - `_meta.content_hash` and `_meta.signature` are stripped before hashing.
|
|
13
|
+
*/
|
|
14
|
+
export declare function canonicalize(value: unknown): string;
|
|
15
|
+
/** RFC 8785 serialization without block-integrity field exclusions. */
|
|
16
|
+
export declare function canonicalizeExact(value: unknown): string;
|
|
17
|
+
//# sourceMappingURL=integrity-canonical.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"integrity-canonical.d.ts","sourceRoot":"","sources":["../src/integrity-canonical.ts"],"names":[],"mappings":"AAYA;;;;;;;;;;;;GAYG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAEnD;AAED,uEAAuE;AACvE,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAExD"}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
// JCS-style canonical JSON serialization for content_hash computation.
|
|
2
|
+
// Protocol §V.9 — "Canonical block JSON"
|
|
3
|
+
//
|
|
4
|
+
// Implements RFC 8785 (JCS) with one extension: the keys `content_hash` and
|
|
5
|
+
// `signature` inside any nested `_meta` object are removed before hashing.
|
|
6
|
+
// This keeps hash computation idempotent across multiple round trips through
|
|
7
|
+
// the cascade.
|
|
8
|
+
//
|
|
9
|
+
// Pure, dependency-free, deterministic across Node and modern browsers.
|
|
10
|
+
const PRESERVE_KEYS_REMOVED = ['content_hash', 'signature'];
|
|
11
|
+
/**
|
|
12
|
+
* Produce a canonical JSON serialization of `value` per RFC 8785 with the
|
|
13
|
+
* uw-md exclusions described above.
|
|
14
|
+
*
|
|
15
|
+
* Behavior:
|
|
16
|
+
* - Object keys sorted by code-unit comparison.
|
|
17
|
+
* - Strings JSON-escaped per RFC 8785 §3.2.2.
|
|
18
|
+
* - Numbers serialized per RFC 8785 §3.2.2.3 (ECMAScript ToString) with
|
|
19
|
+
* special-cases: integers render without decimals; non-finite numbers
|
|
20
|
+
* throw (JSON cannot represent them).
|
|
21
|
+
* - `undefined` values inside objects are dropped (mirrors JSON.stringify).
|
|
22
|
+
* - `_meta.content_hash` and `_meta.signature` are stripped before hashing.
|
|
23
|
+
*/
|
|
24
|
+
export function canonicalize(value) {
|
|
25
|
+
return serialize(stripExcludedKeys(value));
|
|
26
|
+
}
|
|
27
|
+
/** RFC 8785 serialization without block-integrity field exclusions. */
|
|
28
|
+
export function canonicalizeExact(value) {
|
|
29
|
+
return serialize(value);
|
|
30
|
+
}
|
|
31
|
+
function stripExcludedKeys(input) {
|
|
32
|
+
if (input === null || typeof input !== 'object')
|
|
33
|
+
return input;
|
|
34
|
+
if (Array.isArray(input))
|
|
35
|
+
return input.map(stripExcludedKeys);
|
|
36
|
+
const out = {};
|
|
37
|
+
const isMeta = looksLikeMeta(input);
|
|
38
|
+
for (const [k, v] of Object.entries(input)) {
|
|
39
|
+
if (isMeta && PRESERVE_KEYS_REMOVED.includes(k))
|
|
40
|
+
continue;
|
|
41
|
+
out[k] = stripExcludedKeys(v);
|
|
42
|
+
}
|
|
43
|
+
return out;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Heuristic: an object is "meta-shaped" if it carries any of the canonical
|
|
47
|
+
* meta fields. We strip the excluded keys from every meta-shaped sub-object,
|
|
48
|
+
* not only the top-level `_meta`, so that nested provenance (e.g. inside
|
|
49
|
+
* field_overrides) hashes consistently.
|
|
50
|
+
*/
|
|
51
|
+
function looksLikeMeta(obj) {
|
|
52
|
+
return ('section' in obj &&
|
|
53
|
+
'version' in obj &&
|
|
54
|
+
'source' in obj);
|
|
55
|
+
}
|
|
56
|
+
function serialize(value) {
|
|
57
|
+
if (value === null)
|
|
58
|
+
return 'null';
|
|
59
|
+
if (value === undefined)
|
|
60
|
+
return 'null'; // JSON has no undefined; treat as null
|
|
61
|
+
switch (typeof value) {
|
|
62
|
+
case 'boolean':
|
|
63
|
+
return value ? 'true' : 'false';
|
|
64
|
+
case 'number':
|
|
65
|
+
return serializeNumber(value);
|
|
66
|
+
case 'string':
|
|
67
|
+
return serializeString(value);
|
|
68
|
+
case 'object':
|
|
69
|
+
if (Array.isArray(value)) {
|
|
70
|
+
return `[${value.map(serialize).join(',')}]`;
|
|
71
|
+
}
|
|
72
|
+
return serializeObject(value);
|
|
73
|
+
default:
|
|
74
|
+
throw new Error(`canonicalize: cannot serialize value of type ${typeof value}`);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
function serializeObject(obj) {
|
|
78
|
+
const keys = Object.keys(obj).sort();
|
|
79
|
+
const parts = [];
|
|
80
|
+
for (const k of keys) {
|
|
81
|
+
const v = obj[k];
|
|
82
|
+
if (v === undefined)
|
|
83
|
+
continue;
|
|
84
|
+
parts.push(`${serializeString(k)}:${serialize(v)}`);
|
|
85
|
+
}
|
|
86
|
+
return `{${parts.join(',')}}`;
|
|
87
|
+
}
|
|
88
|
+
function serializeNumber(n) {
|
|
89
|
+
if (!Number.isFinite(n)) {
|
|
90
|
+
throw new Error(`canonicalize: cannot serialize non-finite number ${n}`);
|
|
91
|
+
}
|
|
92
|
+
// ECMAScript ToString already produces RFC 8785-compatible output for
|
|
93
|
+
// finite numbers, except that we want -0 to render as "0".
|
|
94
|
+
if (Object.is(n, -0))
|
|
95
|
+
return '0';
|
|
96
|
+
return String(n);
|
|
97
|
+
}
|
|
98
|
+
const ESCAPE_MAP = {
|
|
99
|
+
8: '\\b',
|
|
100
|
+
9: '\\t',
|
|
101
|
+
10: '\\n',
|
|
102
|
+
12: '\\f',
|
|
103
|
+
13: '\\r',
|
|
104
|
+
34: '\\"',
|
|
105
|
+
92: '\\\\',
|
|
106
|
+
};
|
|
107
|
+
function serializeString(s) {
|
|
108
|
+
let out = '"';
|
|
109
|
+
for (let i = 0; i < s.length; i++) {
|
|
110
|
+
const code = s.charCodeAt(i);
|
|
111
|
+
const escaped = ESCAPE_MAP[code];
|
|
112
|
+
if (escaped !== undefined) {
|
|
113
|
+
out += escaped;
|
|
114
|
+
continue;
|
|
115
|
+
}
|
|
116
|
+
if (code < 0x20) {
|
|
117
|
+
out += `\\u${code.toString(16).padStart(4, '0')}`;
|
|
118
|
+
continue;
|
|
119
|
+
}
|
|
120
|
+
out += s[i];
|
|
121
|
+
}
|
|
122
|
+
return `${out}"`;
|
|
123
|
+
}
|
|
124
|
+
//# sourceMappingURL=integrity-canonical.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"integrity-canonical.js","sourceRoot":"","sources":["../src/integrity-canonical.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { ParsedUWFile, UWBlock } from './types.js';
|
|
2
|
+
import type { EditPolicy } from './protocol.js';
|
|
3
|
+
/**
|
|
4
|
+
* SHA-256 of the canonicalized JSON of `value`. Returns the lowercase hex
|
|
5
|
+
* digest. Async to support Web Crypto on browsers without Node's `crypto`.
|
|
6
|
+
*/
|
|
7
|
+
export declare function sha256Hex(value: unknown): Promise<string>;
|
|
8
|
+
/** SHA-256 of an exact UTF-8 string, without JSON canonicalization. */
|
|
9
|
+
export declare function sha256TextHex(text: string): Promise<string>;
|
|
10
|
+
/**
|
|
11
|
+
* Compute the content_hash for a block. Strips the block's own
|
|
12
|
+
* `_meta.content_hash` and `_meta.signature` before hashing (handled by the
|
|
13
|
+
* canonicalizer).
|
|
14
|
+
*/
|
|
15
|
+
export declare function computeBlockHash(block: UWBlock): Promise<string>;
|
|
16
|
+
export type IntegrityCode = 'INT-01' | 'INT-02' | 'INT-03' | 'INT-04' | 'POL-01' | 'POL-02';
|
|
17
|
+
export interface IntegrityIssue {
|
|
18
|
+
code: IntegrityCode;
|
|
19
|
+
severity: 'error' | 'warning';
|
|
20
|
+
message: string;
|
|
21
|
+
section?: string;
|
|
22
|
+
expected?: string;
|
|
23
|
+
actual?: string;
|
|
24
|
+
}
|
|
25
|
+
export interface IntegrityResult {
|
|
26
|
+
ok: boolean;
|
|
27
|
+
issues: IntegrityIssue[];
|
|
28
|
+
chains_verified: number;
|
|
29
|
+
chains_with_hashes: number;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* For every supersede chain in the parsed file:
|
|
33
|
+
* - If at least one block in the chain carries `_meta.content_hash`, every
|
|
34
|
+
* block in the chain MUST carry one (else INT-03 warning).
|
|
35
|
+
* - Each block's recomputed hash MUST equal the stamped `content_hash`
|
|
36
|
+
* (else INT-04 warning).
|
|
37
|
+
* - Each non-root block's `parent_hash` MUST equal the prior block's
|
|
38
|
+
* `content_hash` (else INT-01 error).
|
|
39
|
+
*
|
|
40
|
+
* A chain with no hashes at all yields no findings and is not counted in
|
|
41
|
+
* `chains_verified`.
|
|
42
|
+
*/
|
|
43
|
+
export declare function verifyChain(parsed: ParsedUWFile): Promise<IntegrityResult>;
|
|
44
|
+
/**
|
|
45
|
+
* Cross-check `_meta.actor` and the operation that produced the block against
|
|
46
|
+
* BUILTIN_EDIT_POLICIES.
|
|
47
|
+
*
|
|
48
|
+
* - POL-01: actor not authorized for the section per its EditPolicy.
|
|
49
|
+
* - POL-02: section_replace used where the policy mandates section_supersede
|
|
50
|
+
* (heuristic: if `supersede_on_edit` and there are no superseded prior
|
|
51
|
+
* versions yet `version > 1`, the prior was overwritten not appended).
|
|
52
|
+
*/
|
|
53
|
+
export declare function verifyProvenance(parsed: ParsedUWFile, policies?: readonly EditPolicy[]): IntegrityResult;
|
|
54
|
+
//# sourceMappingURL=integrity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"integrity.d.ts","sourceRoot":"","sources":["../src/integrity.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACxD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAKhD;;;GAGG;AACH,wBAAsB,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAE/D;AAED,uEAAuE;AACvE,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAmBjE;AAWD;;;;GAIG;AACH,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAKtE;AAID,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAE5F,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,aAAa,CAAC;IACpB,QAAQ,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,cAAc,EAAE,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;IACxB,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAID;;;;;;;;;;;GAWG;AACH,wBAAsB,WAAW,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,eAAe,CAAC,CA2EhF;AAID;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,YAAY,EACpB,QAAQ,GAAE,SAAS,UAAU,EAA0B,GACtD,eAAe,CA0CjB"}
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
// Integrity layer: content_hash + parent_hash chains, provenance verification
|
|
2
|
+
// Protocol §V.9 / §V.10 — "Block integrity"
|
|
3
|
+
//
|
|
4
|
+
// Design notes:
|
|
5
|
+
// - Opt-in: a file with no hashes parses, validates, and verifies as
|
|
6
|
+
// `ok: true, chains_with_hashes: 0`.
|
|
7
|
+
// - The chain walk is per-section: each section's supersede sequence is its
|
|
8
|
+
// own chain. Cross-section chains are intentionally not modeled in v1.
|
|
9
|
+
// - SHA-256 implementation is split between Node (`createHash`) and Web
|
|
10
|
+
// Crypto (`crypto.subtle`). The browser entry point binds the latter via
|
|
11
|
+
// subpath export when adopters import from `@uwmd/core/browser`.
|
|
12
|
+
import { canonicalize } from './integrity-canonical.js';
|
|
13
|
+
import { BUILTIN_EDIT_POLICIES } from './protocol.js';
|
|
14
|
+
// ─── Hashing ─────────────────────────────────────────────────────────────────
|
|
15
|
+
/**
|
|
16
|
+
* SHA-256 of the canonicalized JSON of `value`. Returns the lowercase hex
|
|
17
|
+
* digest. Async to support Web Crypto on browsers without Node's `crypto`.
|
|
18
|
+
*/
|
|
19
|
+
export async function sha256Hex(value) {
|
|
20
|
+
return sha256TextHex(canonicalize(value));
|
|
21
|
+
}
|
|
22
|
+
/** SHA-256 of an exact UTF-8 string, without JSON canonicalization. */
|
|
23
|
+
export async function sha256TextHex(text) {
|
|
24
|
+
const bytes = new TextEncoder().encode(text);
|
|
25
|
+
const g = globalThis;
|
|
26
|
+
const isNode = !!g.process?.versions?.node;
|
|
27
|
+
if (isNode) {
|
|
28
|
+
const mod = (await import('node:crypto'));
|
|
29
|
+
return mod.createHash('sha256').update(bytes).digest('hex');
|
|
30
|
+
}
|
|
31
|
+
const subtle = g.crypto?.subtle;
|
|
32
|
+
if (!subtle)
|
|
33
|
+
throw new Error('integrity.sha256TextHex: no crypto provider available.');
|
|
34
|
+
const digest = await subtle.digest('SHA-256', bytes);
|
|
35
|
+
return bytesToHex(new Uint8Array(digest));
|
|
36
|
+
}
|
|
37
|
+
function bytesToHex(bytes) {
|
|
38
|
+
let out = '';
|
|
39
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
40
|
+
const b = bytes[i] ?? 0;
|
|
41
|
+
out += b.toString(16).padStart(2, '0');
|
|
42
|
+
}
|
|
43
|
+
return out;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Compute the content_hash for a block. Strips the block's own
|
|
47
|
+
* `_meta.content_hash` and `_meta.signature` before hashing (handled by the
|
|
48
|
+
* canonicalizer).
|
|
49
|
+
*/
|
|
50
|
+
export async function computeBlockHash(block) {
|
|
51
|
+
// The canonical scope is the block CONTENT including meta, since meta
|
|
52
|
+
// carries the cascade-relevant provenance. The two excluded keys are
|
|
53
|
+
// stripped by the canonicalizer.
|
|
54
|
+
return sha256Hex({ ...block.content, _meta: block.meta });
|
|
55
|
+
}
|
|
56
|
+
// ─── Chain verification ──────────────────────────────────────────────────────
|
|
57
|
+
/**
|
|
58
|
+
* For every supersede chain in the parsed file:
|
|
59
|
+
* - If at least one block in the chain carries `_meta.content_hash`, every
|
|
60
|
+
* block in the chain MUST carry one (else INT-03 warning).
|
|
61
|
+
* - Each block's recomputed hash MUST equal the stamped `content_hash`
|
|
62
|
+
* (else INT-04 warning).
|
|
63
|
+
* - Each non-root block's `parent_hash` MUST equal the prior block's
|
|
64
|
+
* `content_hash` (else INT-01 error).
|
|
65
|
+
*
|
|
66
|
+
* A chain with no hashes at all yields no findings and is not counted in
|
|
67
|
+
* `chains_verified`.
|
|
68
|
+
*/
|
|
69
|
+
export async function verifyChain(parsed) {
|
|
70
|
+
const issues = [];
|
|
71
|
+
let chainsWithHashes = 0;
|
|
72
|
+
let chainsVerified = 0;
|
|
73
|
+
for (const sectionId of Object.keys(parsed.sections)) {
|
|
74
|
+
// Build the chain: prior (superseded) blocks first, then current head.
|
|
75
|
+
const prior = parsed.superseded[sectionId] ?? [];
|
|
76
|
+
const head = currentBlock(parsed, sectionId);
|
|
77
|
+
if (!head)
|
|
78
|
+
continue;
|
|
79
|
+
const chain = [...prior, head];
|
|
80
|
+
const hasAnyHash = chain.some((b) => typeof b.meta.content_hash === 'string');
|
|
81
|
+
if (!hasAnyHash)
|
|
82
|
+
continue;
|
|
83
|
+
chainsWithHashes++;
|
|
84
|
+
let chainOK = true;
|
|
85
|
+
let prevHash = null;
|
|
86
|
+
for (let i = 0; i < chain.length; i++) {
|
|
87
|
+
const block = chain[i];
|
|
88
|
+
const stamped = block.meta.content_hash;
|
|
89
|
+
// INT-03: partial chain
|
|
90
|
+
if (typeof stamped !== 'string') {
|
|
91
|
+
issues.push({
|
|
92
|
+
code: 'INT-03',
|
|
93
|
+
severity: 'warning',
|
|
94
|
+
section: sectionId,
|
|
95
|
+
message: `Block v${block.meta.version} of '${sectionId}' has no content_hash but other blocks in the chain do.`,
|
|
96
|
+
});
|
|
97
|
+
chainOK = false;
|
|
98
|
+
continue;
|
|
99
|
+
}
|
|
100
|
+
// INT-04: hash mismatch
|
|
101
|
+
const recomputed = await computeBlockHash(block);
|
|
102
|
+
if (recomputed !== stamped) {
|
|
103
|
+
issues.push({
|
|
104
|
+
code: 'INT-04',
|
|
105
|
+
severity: 'warning',
|
|
106
|
+
section: sectionId,
|
|
107
|
+
message: `Block v${block.meta.version} of '${sectionId}' content_hash does not recompute.`,
|
|
108
|
+
expected: recomputed,
|
|
109
|
+
actual: stamped,
|
|
110
|
+
});
|
|
111
|
+
chainOK = false;
|
|
112
|
+
}
|
|
113
|
+
// INT-01: parent hash mismatch
|
|
114
|
+
if (i > 0) {
|
|
115
|
+
const parent = block.meta.parent_hash;
|
|
116
|
+
if (parent !== prevHash) {
|
|
117
|
+
issues.push({
|
|
118
|
+
code: 'INT-01',
|
|
119
|
+
severity: 'error',
|
|
120
|
+
section: sectionId,
|
|
121
|
+
message: `Block v${block.meta.version} of '${sectionId}' parent_hash does not match prior block.`,
|
|
122
|
+
expected: prevHash ?? '<null>',
|
|
123
|
+
actual: parent ?? '<missing>',
|
|
124
|
+
});
|
|
125
|
+
chainOK = false;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
prevHash = stamped;
|
|
129
|
+
}
|
|
130
|
+
if (chainOK)
|
|
131
|
+
chainsVerified++;
|
|
132
|
+
}
|
|
133
|
+
const errors = issues.filter((i) => i.severity === 'error').length;
|
|
134
|
+
return {
|
|
135
|
+
ok: errors === 0,
|
|
136
|
+
issues,
|
|
137
|
+
chains_verified: chainsVerified,
|
|
138
|
+
chains_with_hashes: chainsWithHashes,
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
// ─── Provenance verification ─────────────────────────────────────────────────
|
|
142
|
+
/**
|
|
143
|
+
* Cross-check `_meta.actor` and the operation that produced the block against
|
|
144
|
+
* BUILTIN_EDIT_POLICIES.
|
|
145
|
+
*
|
|
146
|
+
* - POL-01: actor not authorized for the section per its EditPolicy.
|
|
147
|
+
* - POL-02: section_replace used where the policy mandates section_supersede
|
|
148
|
+
* (heuristic: if `supersede_on_edit` and there are no superseded prior
|
|
149
|
+
* versions yet `version > 1`, the prior was overwritten not appended).
|
|
150
|
+
*/
|
|
151
|
+
export function verifyProvenance(parsed, policies = BUILTIN_EDIT_POLICIES) {
|
|
152
|
+
const issues = [];
|
|
153
|
+
for (const sectionId of Object.keys(parsed.sections)) {
|
|
154
|
+
const head = currentBlock(parsed, sectionId);
|
|
155
|
+
if (!head)
|
|
156
|
+
continue;
|
|
157
|
+
const policy = matchPolicy(head.meta.source, policies);
|
|
158
|
+
if (!policy)
|
|
159
|
+
continue;
|
|
160
|
+
// POL-01: authority check
|
|
161
|
+
const actorClass = classifyActor(head.meta.actor, head.meta.source);
|
|
162
|
+
if (!authorityAllows(policy.authority, actorClass)) {
|
|
163
|
+
issues.push({
|
|
164
|
+
code: 'POL-01',
|
|
165
|
+
severity: 'error',
|
|
166
|
+
section: sectionId,
|
|
167
|
+
message: `Actor '${head.meta.actor}' (class '${actorClass}') not authorized to write '${sectionId}' (policy authority '${policy.authority}').`,
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
// POL-02: replace-where-supersede-required
|
|
171
|
+
if (policy.supersede_on_edit &&
|
|
172
|
+
head.meta.version > 1 &&
|
|
173
|
+
(parsed.superseded[sectionId]?.length ?? 0) === 0) {
|
|
174
|
+
issues.push({
|
|
175
|
+
code: 'POL-02',
|
|
176
|
+
severity: 'error',
|
|
177
|
+
section: sectionId,
|
|
178
|
+
message: `Section '${sectionId}' (source pattern '${policy.source_pattern}') requires supersede_on_edit but version ${head.meta.version} has no superseded prior versions.`,
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
const errors = issues.filter((i) => i.severity === 'error').length;
|
|
183
|
+
return {
|
|
184
|
+
ok: errors === 0,
|
|
185
|
+
issues,
|
|
186
|
+
chains_verified: 0,
|
|
187
|
+
chains_with_hashes: 0,
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
// ─── Helpers ─────────────────────────────────────────────────────────────────
|
|
191
|
+
function currentBlock(parsed, sectionId) {
|
|
192
|
+
const entry = parsed.sections[sectionId];
|
|
193
|
+
if (!entry)
|
|
194
|
+
return null;
|
|
195
|
+
if ('annotation' in entry)
|
|
196
|
+
return entry;
|
|
197
|
+
// Multi-variant sections: integrity is per-variant; pick the first variant
|
|
198
|
+
// for now. Fuller treatment is RFC 0009.
|
|
199
|
+
const variants = Object.values(entry);
|
|
200
|
+
return variants[0] ?? null;
|
|
201
|
+
}
|
|
202
|
+
function matchPolicy(source, policies) {
|
|
203
|
+
for (const p of policies) {
|
|
204
|
+
if (globMatch(p.source_pattern, source))
|
|
205
|
+
return p;
|
|
206
|
+
}
|
|
207
|
+
return null;
|
|
208
|
+
}
|
|
209
|
+
function globMatch(pattern, value) {
|
|
210
|
+
// Tiny glob: supports trailing `*` and exact matches. Mirrors editor.ts.
|
|
211
|
+
if (pattern === value)
|
|
212
|
+
return true;
|
|
213
|
+
if (pattern.endsWith('/*')) {
|
|
214
|
+
const prefix = pattern.slice(0, -1); // keep the '/'
|
|
215
|
+
return value.startsWith(prefix);
|
|
216
|
+
}
|
|
217
|
+
if (pattern.endsWith('*')) {
|
|
218
|
+
const prefix = pattern.slice(0, -1);
|
|
219
|
+
return value.startsWith(prefix);
|
|
220
|
+
}
|
|
221
|
+
return false;
|
|
222
|
+
}
|
|
223
|
+
function classifyActor(actor, source) {
|
|
224
|
+
if (source.startsWith('system/') || source.startsWith('institution/'))
|
|
225
|
+
return 'system';
|
|
226
|
+
if (source.startsWith('agent/') || actor.startsWith('agent/'))
|
|
227
|
+
return 'agent';
|
|
228
|
+
return 'human';
|
|
229
|
+
}
|
|
230
|
+
function authorityAllows(authority, actor) {
|
|
231
|
+
switch (authority) {
|
|
232
|
+
case 'either':
|
|
233
|
+
return actor === 'agent' || actor === 'human';
|
|
234
|
+
case 'agent_only':
|
|
235
|
+
return actor === 'agent';
|
|
236
|
+
case 'human_only':
|
|
237
|
+
return actor === 'human';
|
|
238
|
+
case 'system_only':
|
|
239
|
+
return actor === 'system';
|
|
240
|
+
default:
|
|
241
|
+
return false;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
//# sourceMappingURL=integrity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"integrity.js","sourceRoot":"","sources":["../src/integrity.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type ModuleLoadResult, type ModuleManifest, type ProtocolError, type ViewerTier } from './protocol.js';
|
|
2
|
+
export interface ModuleRegistry {
|
|
3
|
+
modules: readonly ModuleManifest[];
|
|
4
|
+
byId: ReadonlyMap<string, ModuleManifest>;
|
|
5
|
+
byAssetClass: ReadonlyMap<string, readonly ModuleManifest[]>;
|
|
6
|
+
calculationsByAssetClass(asset_class: string): ModuleManifest[];
|
|
7
|
+
}
|
|
8
|
+
export interface LoadModuleOptions {
|
|
9
|
+
hostTier?: ViewerTier;
|
|
10
|
+
protocolVersion?: string;
|
|
11
|
+
formatVersion?: string;
|
|
12
|
+
alreadyLoaded?: readonly ModuleManifest[];
|
|
13
|
+
}
|
|
14
|
+
export interface CreateModuleRegistryOptions extends LoadModuleOptions {
|
|
15
|
+
modules: readonly ModuleManifest[];
|
|
16
|
+
}
|
|
17
|
+
export declare class ModuleRegistryError extends Error {
|
|
18
|
+
readonly errors: readonly ProtocolError[];
|
|
19
|
+
constructor(errors: readonly ProtocolError[]);
|
|
20
|
+
}
|
|
21
|
+
export declare function loadModuleManifest(candidate: unknown, opts?: LoadModuleOptions): ModuleLoadResult;
|
|
22
|
+
export declare function createModuleRegistry(opts: CreateModuleRegistryOptions): ModuleRegistry;
|
|
23
|
+
export declare function getModuleCalculationsForAssetClass(registry: ModuleRegistry, asset_class: string): import("./protocol.js").ModuleCalcDecl[];
|
|
24
|
+
//# sourceMappingURL=modules.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"modules.d.ts","sourceRoot":"","sources":["../src/modules.ts"],"names":[],"mappings":"AASA,OAAO,EAGL,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,UAAU,EAChB,MAAM,eAAe,CAAC;AAmCvB,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,SAAS,cAAc,EAAE,CAAC;IACnC,IAAI,EAAE,WAAW,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAC1C,YAAY,EAAE,WAAW,CAAC,MAAM,EAAE,SAAS,cAAc,EAAE,CAAC,CAAC;IAC7D,wBAAwB,CAAC,WAAW,EAAE,MAAM,GAAG,cAAc,EAAE,CAAC;CACjE;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,EAAE,UAAU,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,SAAS,cAAc,EAAE,CAAC;CAC3C;AAED,MAAM,WAAW,2BAA4B,SAAQ,iBAAiB;IACpE,OAAO,EAAE,SAAS,cAAc,EAAE,CAAC;CACpC;AAED,qBAAa,mBAAoB,SAAQ,KAAK;IAC5C,QAAQ,CAAC,MAAM,EAAE,SAAS,aAAa,EAAE,CAAC;gBAE9B,MAAM,EAAE,SAAS,aAAa,EAAE;CAK7C;AAED,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,OAAO,EAClB,IAAI,GAAE,iBAAsB,GAC3B,gBAAgB,CAMlB;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,2BAA2B,GAAG,cAAc,CAuCtF;AAED,wBAAgB,kCAAkC,CAChD,QAAQ,EAAE,cAAc,EACxB,WAAW,EAAE,MAAM,4CAKpB"}
|