@primust/artifact-core 1.0.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.
- package/LICENSE +93 -0
- package/dist/canonical.d.ts +11 -0
- package/dist/canonical.d.ts.map +1 -1
- package/dist/canonical.js +92 -0
- package/dist/canonical.js.map +1 -1
- package/dist/commitment.d.ts +56 -8
- package/dist/commitment.d.ts.map +1 -1
- package/dist/commitment.js +71 -26
- package/dist/commitment.js.map +1 -1
- package/dist/commitment.test.js +14 -3
- package/dist/commitment.test.js.map +1 -1
- package/dist/hierarchical_leaf.d.ts +72 -0
- package/dist/hierarchical_leaf.d.ts.map +1 -0
- package/dist/hierarchical_leaf.js +144 -0
- package/dist/hierarchical_leaf.js.map +1 -0
- package/dist/hierarchical_leaf.test.d.ts +15 -0
- package/dist/hierarchical_leaf.test.d.ts.map +1 -0
- package/dist/hierarchical_leaf.test.js +145 -0
- package/dist/hierarchical_leaf.test.js.map +1 -0
- package/dist/index.d.ts +9 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -1
- package/dist/index.js.map +1 -1
- package/dist/metadata_source.d.ts +4 -0
- package/dist/metadata_source.d.ts.map +1 -0
- package/dist/metadata_source.js +54 -0
- package/dist/metadata_source.js.map +1 -0
- package/dist/metadata_source.test.d.ts +2 -0
- package/dist/metadata_source.test.d.ts.map +1 -0
- package/dist/metadata_source.test.js +29 -0
- package/dist/metadata_source.test.js.map +1 -0
- package/dist/reversibility_taxonomy.d.ts +23 -0
- package/dist/reversibility_taxonomy.d.ts.map +1 -0
- package/dist/reversibility_taxonomy.js +208 -0
- package/dist/reversibility_taxonomy.js.map +1 -0
- package/dist/reversibility_taxonomy.test.d.ts +2 -0
- package/dist/reversibility_taxonomy.test.d.ts.map +1 -0
- package/dist/reversibility_taxonomy.test.js +146 -0
- package/dist/reversibility_taxonomy.test.js.map +1 -0
- package/dist/signing.d.ts.map +1 -1
- package/dist/signing.js +30 -6
- package/dist/signing.js.map +1 -1
- package/dist/trust_edge_mapping.d.ts +12 -0
- package/dist/trust_edge_mapping.d.ts.map +1 -0
- package/dist/trust_edge_mapping.js +88 -0
- package/dist/trust_edge_mapping.js.map +1 -0
- package/dist/trust_edge_mapping.test.d.ts +2 -0
- package/dist/trust_edge_mapping.test.d.ts.map +1 -0
- package/dist/trust_edge_mapping.test.js +86 -0
- package/dist/trust_edge_mapping.test.js.map +1 -0
- package/dist/types/artifact.d.ts +65 -4
- package/dist/types/artifact.d.ts.map +1 -1
- package/dist/types/proof_artifact.d.ts +52 -0
- package/dist/types/proof_artifact.d.ts.map +1 -0
- package/dist/types/proof_artifact.js +12 -0
- package/dist/types/proof_artifact.js.map +1 -0
- package/dist/validate-artifact.d.ts.map +1 -1
- package/dist/validate-artifact.js +88 -10
- package/dist/validate-artifact.js.map +1 -1
- package/dist/validate-artifact.test.js +16 -2
- package/dist/validate-artifact.test.js.map +1 -1
- package/package.json +13 -7
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Primust Artifact Core — Hierarchical-ZK Canonical Encoder (L13 P3)
|
|
3
|
+
*
|
|
4
|
+
* Implements the leaf encoders specified in
|
|
5
|
+
* `followup/L13_STEP3_HIERARCHICAL_ZK_LEAF_DESIGN.md` §3.6.
|
|
6
|
+
*
|
|
7
|
+
* This module is the language-independent encoding contract: TS (SDK +
|
|
8
|
+
* verifier) and Python (`primust-verify`) MUST produce byte-identical
|
|
9
|
+
* `poseidon2:<hex>` output for the same logical input. The parity test at
|
|
10
|
+
* §13 T-7 exercises shared fixtures against both implementations.
|
|
11
|
+
*
|
|
12
|
+
* No new crypto primitive is introduced — every step is a composition of
|
|
13
|
+
* `_bytesToFieldElements` + `_parseHashToField` + `_poseidon2Sponge` +
|
|
14
|
+
* the `poseidon2:` hex-format helper.
|
|
15
|
+
*
|
|
16
|
+
* Three leaf shapes are exposed:
|
|
17
|
+
*
|
|
18
|
+
* 1. `poseidon2HexRecordLeaf` (§4) — the 4-tuple per-record leaf hash
|
|
19
|
+
* (commitment_hash, check_result_u8, manifest_hash, sequence_index).
|
|
20
|
+
* Fed into `buildCommitmentRoot(record_leaves, 'poseidon2')` to
|
|
21
|
+
* obtain an action-unit's `action_unit_merkle_root`.
|
|
22
|
+
*
|
|
23
|
+
* 2. `poseidon2HexL1ActionUnitLeaf` (§3.1) — the 3-tuple action-unit
|
|
24
|
+
* leaf (action_unit_id, aggregated_result_u8, action_unit_merkle_root).
|
|
25
|
+
* Used as a run leaf when action_unit_count ≤ 64.
|
|
26
|
+
*
|
|
27
|
+
* 3. `poseidon2HexL2SuperUnitLeaf` (§3.2) — the 3-tuple super-unit
|
|
28
|
+
* leaf (super_unit_id, super_unit_aggregated_result_u8,
|
|
29
|
+
* super_unit_action_unit_merkle_root). Used as a run leaf when
|
|
30
|
+
* action_unit_count > 64. Identical math to L1; the circuit cannot
|
|
31
|
+
* tell L1 and L2 leaves apart.
|
|
32
|
+
*/
|
|
33
|
+
/**
|
|
34
|
+
* Per-record leaf hash (§4). The 4-tuple feeds the per-action-unit
|
|
35
|
+
* Merkle fold whose root is the `action_unit_merkle_root` consumed by
|
|
36
|
+
* the L1/L2 leaf encoders below.
|
|
37
|
+
*
|
|
38
|
+
* Encoding (§3.6):
|
|
39
|
+
* elements = [
|
|
40
|
+
* parseHashToField(commitment_hash),
|
|
41
|
+
* BigInt(check_result_u8),
|
|
42
|
+
* parseHashToField(manifest_hash),
|
|
43
|
+
* BigInt(sequence_index),
|
|
44
|
+
* ]
|
|
45
|
+
* return 'poseidon2:' + sponge(elements).hex64
|
|
46
|
+
*
|
|
47
|
+
* @param commitmentHash must match `^(sha256|poseidon2):[0-9a-f]{64}$`.
|
|
48
|
+
* @param checkResultU8 0..255 (codec spec lives outside this module).
|
|
49
|
+
* @param manifestHash same shape as commitmentHash.
|
|
50
|
+
* @param sequenceIndex 0..BN254_MODULUS-1; bigint or number.
|
|
51
|
+
*/
|
|
52
|
+
export declare function poseidon2HexRecordLeaf(commitmentHash: string, checkResultU8: number, manifestHash: string, sequenceIndex: bigint | number): string;
|
|
53
|
+
/**
|
|
54
|
+
* L1 action-unit leaf (§3.1). Used as a run leaf when
|
|
55
|
+
* action_unit_count ≤ 64.
|
|
56
|
+
*
|
|
57
|
+
* Encoding (§3.6):
|
|
58
|
+
* elements = concat(
|
|
59
|
+
* bytesToFieldElements(utf8(action_unit_id)),
|
|
60
|
+
* [BigInt(aggregated_result_u8)],
|
|
61
|
+
* [parseHashToField(action_unit_merkle_root)],
|
|
62
|
+
* )
|
|
63
|
+
* return 'poseidon2:' + sponge(elements).hex64
|
|
64
|
+
*/
|
|
65
|
+
export declare function poseidon2HexL1ActionUnitLeaf(actionUnitId: string, aggregatedResultU8: number, actionUnitMerkleRoot: string): string;
|
|
66
|
+
/**
|
|
67
|
+
* L2 super-unit leaf (§3.2). Used as a run leaf when
|
|
68
|
+
* action_unit_count > 64. Identical math to L1; the circuit cannot
|
|
69
|
+
* distinguish the two leaf shapes.
|
|
70
|
+
*/
|
|
71
|
+
export declare function poseidon2HexL2SuperUnitLeaf(superUnitId: string, superUnitAggregatedResultU8: number, superUnitActionUnitMerkleRoot: string): string;
|
|
72
|
+
//# sourceMappingURL=hierarchical_leaf.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hierarchical_leaf.d.ts","sourceRoot":"","sources":["../src/hierarchical_leaf.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAqEH;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,sBAAsB,CACpC,cAAc,EAAE,MAAM,EACtB,aAAa,EAAE,MAAM,EACrB,YAAY,EAAE,MAAM,EACpB,aAAa,EAAE,MAAM,GAAG,MAAM,GAC7B,MAAM,CAQR;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,4BAA4B,CAC1C,YAAY,EAAE,MAAM,EACpB,kBAAkB,EAAE,MAAM,EAC1B,oBAAoB,EAAE,MAAM,GAC3B,MAAM,CAOR;AAED;;;;GAIG;AACH,wBAAgB,2BAA2B,CACzC,WAAW,EAAE,MAAM,EACnB,2BAA2B,EAAE,MAAM,EACnC,6BAA6B,EAAE,MAAM,GACpC,MAAM,CAOR"}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Primust Artifact Core — Hierarchical-ZK Canonical Encoder (L13 P3)
|
|
3
|
+
*
|
|
4
|
+
* Implements the leaf encoders specified in
|
|
5
|
+
* `followup/L13_STEP3_HIERARCHICAL_ZK_LEAF_DESIGN.md` §3.6.
|
|
6
|
+
*
|
|
7
|
+
* This module is the language-independent encoding contract: TS (SDK +
|
|
8
|
+
* verifier) and Python (`primust-verify`) MUST produce byte-identical
|
|
9
|
+
* `poseidon2:<hex>` output for the same logical input. The parity test at
|
|
10
|
+
* §13 T-7 exercises shared fixtures against both implementations.
|
|
11
|
+
*
|
|
12
|
+
* No new crypto primitive is introduced — every step is a composition of
|
|
13
|
+
* `_bytesToFieldElements` + `_parseHashToField` + `_poseidon2Sponge` +
|
|
14
|
+
* the `poseidon2:` hex-format helper.
|
|
15
|
+
*
|
|
16
|
+
* Three leaf shapes are exposed:
|
|
17
|
+
*
|
|
18
|
+
* 1. `poseidon2HexRecordLeaf` (§4) — the 4-tuple per-record leaf hash
|
|
19
|
+
* (commitment_hash, check_result_u8, manifest_hash, sequence_index).
|
|
20
|
+
* Fed into `buildCommitmentRoot(record_leaves, 'poseidon2')` to
|
|
21
|
+
* obtain an action-unit's `action_unit_merkle_root`.
|
|
22
|
+
*
|
|
23
|
+
* 2. `poseidon2HexL1ActionUnitLeaf` (§3.1) — the 3-tuple action-unit
|
|
24
|
+
* leaf (action_unit_id, aggregated_result_u8, action_unit_merkle_root).
|
|
25
|
+
* Used as a run leaf when action_unit_count ≤ 64.
|
|
26
|
+
*
|
|
27
|
+
* 3. `poseidon2HexL2SuperUnitLeaf` (§3.2) — the 3-tuple super-unit
|
|
28
|
+
* leaf (super_unit_id, super_unit_aggregated_result_u8,
|
|
29
|
+
* super_unit_action_unit_merkle_root). Used as a run leaf when
|
|
30
|
+
* action_unit_count > 64. Identical math to L1; the circuit cannot
|
|
31
|
+
* tell L1 and L2 leaves apart.
|
|
32
|
+
*/
|
|
33
|
+
import { BN254_MODULUS, _bytesToFieldElements, _parseHashToField, _poseidon2Sponge, } from './commitment.js';
|
|
34
|
+
// ── Helpers ──────────────────────────────────────────────────────────
|
|
35
|
+
/** Format a BN254 field element as a poseidon2-prefixed 64-hex commitment. */
|
|
36
|
+
function _poseidon2Hex(field) {
|
|
37
|
+
return 'poseidon2:' + field.toString(16).padStart(64, '0');
|
|
38
|
+
}
|
|
39
|
+
/** UTF-8 encode a string to bytes — wrapped so behavior is one line per call. */
|
|
40
|
+
const _utf8Encoder = new TextEncoder();
|
|
41
|
+
function _utf8(value) {
|
|
42
|
+
return _utf8Encoder.encode(value);
|
|
43
|
+
}
|
|
44
|
+
/** Encode an unsigned 8-bit value as a single field element. */
|
|
45
|
+
function _encodeU8(value, fieldName) {
|
|
46
|
+
if (!Number.isInteger(value) || value < 0 || value > 255) {
|
|
47
|
+
throw new Error(`${fieldName} must be an integer in [0, 255]; got ${value}`);
|
|
48
|
+
}
|
|
49
|
+
return BigInt(value);
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Encode a u64 sequence index as a single field element.
|
|
53
|
+
*
|
|
54
|
+
* Rejects JS `number` values that are not safe integers — per t_62bc
|
|
55
|
+
* correctness HOLD on PR #363: `BigInt(unsafeNumber)` silently rounds
|
|
56
|
+
* the value BEFORE conversion (`9007199254740993` → `9007199254740992`
|
|
57
|
+
* because JS already lost the bit), so a Python caller that passes the
|
|
58
|
+
* exact integer would produce a different field element than a JS
|
|
59
|
+
* caller passing the same numeric literal. To preserve TS↔Python
|
|
60
|
+
* parity, the encoder requires either a `bigint` or a safe-integer
|
|
61
|
+
* `number`.
|
|
62
|
+
*/
|
|
63
|
+
function _encodeU64(value, fieldName) {
|
|
64
|
+
if (typeof value === 'number') {
|
|
65
|
+
if (!Number.isInteger(value)) {
|
|
66
|
+
throw new Error(`${fieldName} must be an integer; got ${value}`);
|
|
67
|
+
}
|
|
68
|
+
if (!Number.isSafeInteger(value)) {
|
|
69
|
+
throw new Error(`${fieldName} number ${value} exceeds Number.MAX_SAFE_INTEGER ` +
|
|
70
|
+
`(${Number.MAX_SAFE_INTEGER}); pass a bigint to avoid silent ` +
|
|
71
|
+
'rounding (TS↔Python parity)');
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
const v = typeof value === 'bigint' ? value : BigInt(value);
|
|
75
|
+
if (v < 0n)
|
|
76
|
+
throw new Error(`${fieldName} must be non-negative; got ${v}`);
|
|
77
|
+
if (v >= BN254_MODULUS) {
|
|
78
|
+
throw new Error(`${fieldName} must be < BN254_MODULUS; got ${v} (exceeds field)`);
|
|
79
|
+
}
|
|
80
|
+
return v;
|
|
81
|
+
}
|
|
82
|
+
// ── Public API ───────────────────────────────────────────────────────
|
|
83
|
+
/**
|
|
84
|
+
* Per-record leaf hash (§4). The 4-tuple feeds the per-action-unit
|
|
85
|
+
* Merkle fold whose root is the `action_unit_merkle_root` consumed by
|
|
86
|
+
* the L1/L2 leaf encoders below.
|
|
87
|
+
*
|
|
88
|
+
* Encoding (§3.6):
|
|
89
|
+
* elements = [
|
|
90
|
+
* parseHashToField(commitment_hash),
|
|
91
|
+
* BigInt(check_result_u8),
|
|
92
|
+
* parseHashToField(manifest_hash),
|
|
93
|
+
* BigInt(sequence_index),
|
|
94
|
+
* ]
|
|
95
|
+
* return 'poseidon2:' + sponge(elements).hex64
|
|
96
|
+
*
|
|
97
|
+
* @param commitmentHash must match `^(sha256|poseidon2):[0-9a-f]{64}$`.
|
|
98
|
+
* @param checkResultU8 0..255 (codec spec lives outside this module).
|
|
99
|
+
* @param manifestHash same shape as commitmentHash.
|
|
100
|
+
* @param sequenceIndex 0..BN254_MODULUS-1; bigint or number.
|
|
101
|
+
*/
|
|
102
|
+
export function poseidon2HexRecordLeaf(commitmentHash, checkResultU8, manifestHash, sequenceIndex) {
|
|
103
|
+
const elements = [
|
|
104
|
+
_parseHashToField(commitmentHash),
|
|
105
|
+
_encodeU8(checkResultU8, 'checkResultU8'),
|
|
106
|
+
_parseHashToField(manifestHash),
|
|
107
|
+
_encodeU64(sequenceIndex, 'sequenceIndex'),
|
|
108
|
+
];
|
|
109
|
+
return _poseidon2Hex(_poseidon2Sponge(elements));
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* L1 action-unit leaf (§3.1). Used as a run leaf when
|
|
113
|
+
* action_unit_count ≤ 64.
|
|
114
|
+
*
|
|
115
|
+
* Encoding (§3.6):
|
|
116
|
+
* elements = concat(
|
|
117
|
+
* bytesToFieldElements(utf8(action_unit_id)),
|
|
118
|
+
* [BigInt(aggregated_result_u8)],
|
|
119
|
+
* [parseHashToField(action_unit_merkle_root)],
|
|
120
|
+
* )
|
|
121
|
+
* return 'poseidon2:' + sponge(elements).hex64
|
|
122
|
+
*/
|
|
123
|
+
export function poseidon2HexL1ActionUnitLeaf(actionUnitId, aggregatedResultU8, actionUnitMerkleRoot) {
|
|
124
|
+
const elements = [
|
|
125
|
+
..._bytesToFieldElements(_utf8(actionUnitId)),
|
|
126
|
+
_encodeU8(aggregatedResultU8, 'aggregatedResultU8'),
|
|
127
|
+
_parseHashToField(actionUnitMerkleRoot),
|
|
128
|
+
];
|
|
129
|
+
return _poseidon2Hex(_poseidon2Sponge(elements));
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* L2 super-unit leaf (§3.2). Used as a run leaf when
|
|
133
|
+
* action_unit_count > 64. Identical math to L1; the circuit cannot
|
|
134
|
+
* distinguish the two leaf shapes.
|
|
135
|
+
*/
|
|
136
|
+
export function poseidon2HexL2SuperUnitLeaf(superUnitId, superUnitAggregatedResultU8, superUnitActionUnitMerkleRoot) {
|
|
137
|
+
const elements = [
|
|
138
|
+
..._bytesToFieldElements(_utf8(superUnitId)),
|
|
139
|
+
_encodeU8(superUnitAggregatedResultU8, 'superUnitAggregatedResultU8'),
|
|
140
|
+
_parseHashToField(superUnitActionUnitMerkleRoot),
|
|
141
|
+
];
|
|
142
|
+
return _poseidon2Hex(_poseidon2Sponge(elements));
|
|
143
|
+
}
|
|
144
|
+
//# sourceMappingURL=hierarchical_leaf.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hierarchical_leaf.js","sourceRoot":"","sources":["../src/hierarchical_leaf.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* T-7 cross-language parity tests for the L13 P3 canonical encoder.
|
|
3
|
+
*
|
|
4
|
+
* The golden fixtures at `schemas/golden/hierarchical_leaf_vectors.json`
|
|
5
|
+
* are produced by the Python encoder and asserted byte-for-byte by both
|
|
6
|
+
* Python and TS test suites. A drift between TS and Python on any fixture
|
|
7
|
+
* means a sealed VPEC's verifier-side root recompute will diverge from the
|
|
8
|
+
* SDK-side root emission — i.e. proofs that the SDK generates will not
|
|
9
|
+
* verify.
|
|
10
|
+
*
|
|
11
|
+
* Per merged design doc:
|
|
12
|
+
* followup/L13_STEP3_HIERARCHICAL_ZK_LEAF_DESIGN.md §13 T-7.
|
|
13
|
+
*/
|
|
14
|
+
export {};
|
|
15
|
+
//# sourceMappingURL=hierarchical_leaf.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hierarchical_leaf.test.d.ts","sourceRoot":"","sources":["../src/hierarchical_leaf.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG"}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* T-7 cross-language parity tests for the L13 P3 canonical encoder.
|
|
3
|
+
*
|
|
4
|
+
* The golden fixtures at `schemas/golden/hierarchical_leaf_vectors.json`
|
|
5
|
+
* are produced by the Python encoder and asserted byte-for-byte by both
|
|
6
|
+
* Python and TS test suites. A drift between TS and Python on any fixture
|
|
7
|
+
* means a sealed VPEC's verifier-side root recompute will diverge from the
|
|
8
|
+
* SDK-side root emission — i.e. proofs that the SDK generates will not
|
|
9
|
+
* verify.
|
|
10
|
+
*
|
|
11
|
+
* Per merged design doc:
|
|
12
|
+
* followup/L13_STEP3_HIERARCHICAL_ZK_LEAF_DESIGN.md §13 T-7.
|
|
13
|
+
*/
|
|
14
|
+
import { readFileSync } from 'node:fs';
|
|
15
|
+
import { resolve } from 'node:path';
|
|
16
|
+
import { describe, expect, it } from 'vitest';
|
|
17
|
+
import { BN254_MODULUS } from './commitment.js';
|
|
18
|
+
import { poseidon2HexL1ActionUnitLeaf, poseidon2HexL2SuperUnitLeaf, poseidon2HexRecordLeaf, } from './hierarchical_leaf.js';
|
|
19
|
+
// ── Fixture loading ──────────────────────────────────────────────────
|
|
20
|
+
const vectorsPath = resolve(__dirname, '../../../schemas/golden/hierarchical_leaf_vectors.json');
|
|
21
|
+
const VECTORS = JSON.parse(readFileSync(vectorsPath, 'utf-8'));
|
|
22
|
+
// ── record-leaf (§4 / §3.6) ──────────────────────────────────────────
|
|
23
|
+
describe('hierarchical_leaf / record leaf (§4)', () => {
|
|
24
|
+
for (const v of VECTORS.record_leaves) {
|
|
25
|
+
it(`golden vector — ${v.name}`, () => {
|
|
26
|
+
const actual = poseidon2HexRecordLeaf(v.inputs.commitment_hash, v.inputs.check_result_u8, v.inputs.manifest_hash, BigInt(v.inputs.sequence_index));
|
|
27
|
+
expect(actual).toBe(v.expected);
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
// ── L1 action-unit leaf (§3.1 / §3.6) ────────────────────────────────
|
|
32
|
+
describe('hierarchical_leaf / L1 action-unit leaf (§3.1)', () => {
|
|
33
|
+
for (const v of VECTORS.l1_action_unit_leaves) {
|
|
34
|
+
it(`golden vector — ${v.name}`, () => {
|
|
35
|
+
const actual = poseidon2HexL1ActionUnitLeaf(v.inputs.action_unit_id, v.inputs.aggregated_result_u8, v.inputs.action_unit_merkle_root);
|
|
36
|
+
expect(actual).toBe(v.expected);
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
// ── L2 super-unit leaf (§3.2 / §3.6) ─────────────────────────────────
|
|
41
|
+
describe('hierarchical_leaf / L2 super-unit leaf (§3.2)', () => {
|
|
42
|
+
for (const v of VECTORS.l2_super_unit_leaves) {
|
|
43
|
+
it(`golden vector — ${v.name}`, () => {
|
|
44
|
+
const actual = poseidon2HexL2SuperUnitLeaf(v.inputs.super_unit_id, v.inputs.super_unit_aggregated_result_u8, v.inputs.super_unit_action_unit_merkle_root);
|
|
45
|
+
expect(actual).toBe(v.expected);
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
// ── L1 / L2 indistinguishability invariant ───────────────────────────
|
|
50
|
+
describe('hierarchical_leaf / L1 == L2 indistinguishability (§3.2)', () => {
|
|
51
|
+
for (const v of VECTORS.l1_l2_indistinguishability) {
|
|
52
|
+
it(`circuit cannot distinguish L1 vs L2 — ${v.name}`, () => {
|
|
53
|
+
const l1 = poseidon2HexL1ActionUnitLeaf(v.inputs.id, v.inputs.result_u8, v.inputs.sub_root);
|
|
54
|
+
const l2 = poseidon2HexL2SuperUnitLeaf(v.inputs.id, v.inputs.result_u8, v.inputs.sub_root);
|
|
55
|
+
expect(l1).toBe(v.expected_l1);
|
|
56
|
+
expect(l2).toBe(v.expected_l2);
|
|
57
|
+
expect(l1).toBe(l2);
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
// ── Negative paths — input validation ────────────────────────────────
|
|
62
|
+
describe('hierarchical_leaf / validation', () => {
|
|
63
|
+
const VALID = 'poseidon2:' + 'a'.repeat(64);
|
|
64
|
+
it('rejects negative u8 in record leaf', () => {
|
|
65
|
+
expect(() => poseidon2HexRecordLeaf(VALID, -1, VALID, 0n)).toThrow(/checkResultU8/);
|
|
66
|
+
});
|
|
67
|
+
it('rejects u8 > 255 in record leaf', () => {
|
|
68
|
+
expect(() => poseidon2HexRecordLeaf(VALID, 256, VALID, 0n)).toThrow(/checkResultU8/);
|
|
69
|
+
});
|
|
70
|
+
it('rejects non-integer u8', () => {
|
|
71
|
+
expect(() => poseidon2HexRecordLeaf(VALID, 1.5, VALID, 0n)).toThrow(/checkResultU8/);
|
|
72
|
+
});
|
|
73
|
+
it('rejects negative sequence_index', () => {
|
|
74
|
+
expect(() => poseidon2HexRecordLeaf(VALID, 0, VALID, -1n)).toThrow(/sequenceIndex/);
|
|
75
|
+
});
|
|
76
|
+
it('rejects sequence_index overflowing BN254', () => {
|
|
77
|
+
expect(() => poseidon2HexRecordLeaf(VALID, 0, VALID, BN254_MODULUS)).toThrow(/sequenceIndex/);
|
|
78
|
+
});
|
|
79
|
+
it('rejects prefixless hash in L1 leaf', () => {
|
|
80
|
+
expect(() => poseidon2HexL1ActionUnitLeaf('au_x', 0, 'a'.repeat(64))).toThrow(/Invalid hash format/);
|
|
81
|
+
});
|
|
82
|
+
// t_62bc HOLD #2898 — unsafe-integer numeric sequenceIndex parity gap.
|
|
83
|
+
// JS BigInt() silently rounds a number above Number.MAX_SAFE_INTEGER
|
|
84
|
+
// BEFORE conversion, so the TS encoder would hash a different field
|
|
85
|
+
// element than the Python encoder for the same integer literal. The
|
|
86
|
+
// encoder must reject such values, forcing callers to pass a bigint.
|
|
87
|
+
it('rejects numeric sequenceIndex above Number.MAX_SAFE_INTEGER (T-7 parity gap)', () => {
|
|
88
|
+
// Number.MAX_SAFE_INTEGER + 2 is 9007199254740993 mathematically,
|
|
89
|
+
// but JS already loses the bit and stores it as 9007199254740992.
|
|
90
|
+
// The encoder must reject the value rather than silently encode
|
|
91
|
+
// the rounded number — Python would encode the exact integer
|
|
92
|
+
// 9007199254740993, so the TS↔Python parity breaks. The test
|
|
93
|
+
// demonstrates the encoder's rejection on a non-safe-integer
|
|
94
|
+
// numeric input.
|
|
95
|
+
const unsafe = Number.MAX_SAFE_INTEGER + 2;
|
|
96
|
+
expect(Number.isSafeInteger(unsafe)).toBe(false);
|
|
97
|
+
expect(() => poseidon2HexRecordLeaf(VALID, 0, VALID, unsafe)).toThrow(/exceeds Number\.MAX_SAFE_INTEGER|pass a bigint/);
|
|
98
|
+
});
|
|
99
|
+
it('rejects non-integer numeric sequenceIndex (defensive)', () => {
|
|
100
|
+
expect(() => poseidon2HexRecordLeaf(VALID, 0, VALID, 1.5)).toThrow(/must be an integer/);
|
|
101
|
+
});
|
|
102
|
+
it('accepts bigint sequenceIndex above Number.MAX_SAFE_INTEGER (parity path)', () => {
|
|
103
|
+
// The bigint path is the parity-correct way to encode a sequence
|
|
104
|
+
// index above 2**53-1 — TS encodes the exact field element, no
|
|
105
|
+
// rounding. (BN254_MODULUS upper bound still applies.)
|
|
106
|
+
const aboveSafe = BigInt(Number.MAX_SAFE_INTEGER) + 2n;
|
|
107
|
+
expect(() => poseidon2HexRecordLeaf(VALID, 0, VALID, aboveSafe)).not.toThrow();
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
// ── Encoding invariants spot-checks ──────────────────────────────────
|
|
111
|
+
describe('hierarchical_leaf / encoding invariants', () => {
|
|
112
|
+
const ROOT = 'poseidon2:' + '0'.repeat(64);
|
|
113
|
+
it('record leaf produces poseidon2:hex64 shape', () => {
|
|
114
|
+
const r = poseidon2HexRecordLeaf(ROOT, 0, ROOT, 0n);
|
|
115
|
+
expect(r.startsWith('poseidon2:')).toBe(true);
|
|
116
|
+
expect(r.length).toBe('poseidon2:'.length + 64);
|
|
117
|
+
});
|
|
118
|
+
it('L1 leaf produces poseidon2:hex64 shape', () => {
|
|
119
|
+
const r = poseidon2HexL1ActionUnitLeaf('au_x', 0, ROOT);
|
|
120
|
+
expect(r.startsWith('poseidon2:')).toBe(true);
|
|
121
|
+
expect(r.length).toBe('poseidon2:'.length + 64);
|
|
122
|
+
});
|
|
123
|
+
it('L2 leaf produces poseidon2:hex64 shape', () => {
|
|
124
|
+
const r = poseidon2HexL2SuperUnitLeaf('su_x', 0, ROOT);
|
|
125
|
+
expect(r.startsWith('poseidon2:')).toBe(true);
|
|
126
|
+
expect(r.length).toBe('poseidon2:'.length + 64);
|
|
127
|
+
});
|
|
128
|
+
it('record leaf is deterministic', () => {
|
|
129
|
+
const a = poseidon2HexRecordLeaf(ROOT, 4, ROOT, 42n);
|
|
130
|
+
const b = poseidon2HexRecordLeaf(ROOT, 4, ROOT, 42n);
|
|
131
|
+
expect(a).toBe(b);
|
|
132
|
+
});
|
|
133
|
+
it('different commitment_hash produces different leaf', () => {
|
|
134
|
+
const a = poseidon2HexRecordLeaf('sha256:' + 'a'.repeat(64), 0, ROOT, 0n);
|
|
135
|
+
const b = poseidon2HexRecordLeaf('sha256:' + 'b'.repeat(64), 0, ROOT, 0n);
|
|
136
|
+
expect(a).not.toBe(b);
|
|
137
|
+
});
|
|
138
|
+
it('sha256:HEX and poseidon2:HEX produce identical leaf (algorithm-agnostic-after-parse, per ZK ruling §3.2)', () => {
|
|
139
|
+
const hex = 'a'.repeat(64);
|
|
140
|
+
const a = poseidon2HexRecordLeaf('sha256:' + hex, 0, ROOT, 0n);
|
|
141
|
+
const b = poseidon2HexRecordLeaf('poseidon2:' + hex, 0, ROOT, 0n);
|
|
142
|
+
expect(a).toBe(b);
|
|
143
|
+
});
|
|
144
|
+
});
|
|
145
|
+
//# sourceMappingURL=hierarchical_leaf.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hierarchical_leaf.test.js","sourceRoot":"","sources":["../src/hierarchical_leaf.test.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,17 @@
|
|
|
1
1
|
export { canonical } from './canonical.js';
|
|
2
2
|
export { generateKeyPair, sign, verify, rotateKey, toBase64Url, fromBase64Url } from './signing.js';
|
|
3
|
-
export { commit, commitOutput, buildCommitmentRoot, selectProofLevel, ZK_IS_BLOCKING, } from './commitment.js';
|
|
3
|
+
export { commit, commitOutput, buildCommitmentRoot, selectProofLevel, ZK_IS_BLOCKING, BN254_MODULUS, } from './commitment.js';
|
|
4
4
|
export type { CommitmentResult } from './commitment.js';
|
|
5
|
+
export { poseidon2HexRecordLeaf, poseidon2HexL1ActionUnitLeaf, poseidon2HexL2SuperUnitLeaf, } from './hierarchical_leaf.js';
|
|
5
6
|
export { validateArtifact } from './validate-artifact.js';
|
|
6
7
|
export type { ValidationError, ValidationResult } from './validate-artifact.js';
|
|
7
8
|
export type { SignerRecord, SignatureEnvelope, KeyStatus, RevocationReason, SignerType, } from './types.js';
|
|
8
9
|
export type { VPECArtifact, ProofLevel, SurfaceEntry, ProofDistribution, Coverage, GapEntry, ZkProof, ArtifactIssuer, ArtifactSignature, TimestampAnchor, TransparencyLog, PendingFlags, GapType, GapSeverity, SurfaceType, ObservationMode, ScopeType, PolicyBasis, ArtifactState, CommitmentAlgorithm, Prover, ProverSystem, TsaProvider, OrgRegion, } from './types/artifact.js';
|
|
10
|
+
export type { ProofArtifact, VerificationStatus } from './types/proof_artifact.js';
|
|
11
|
+
export { TAXONOMY_VERSION, REVERSIBILITY_CLASSES, isReversibilityClass, classify as classifyReversibility, isWedgeSurfaceCovered, } from './reversibility_taxonomy.js';
|
|
12
|
+
export type { ReversibilityClass, ClassifyOptions } from './reversibility_taxonomy.js';
|
|
13
|
+
export { MAPPING_VERSION, TRUST_EDGES, classify as classifyTrustEdge, knownKinds as knownTrustEdgeKinds, } from './trust_edge_mapping.js';
|
|
14
|
+
export type { TrustEdge } from './trust_edge_mapping.js';
|
|
15
|
+
export { METADATA_SOURCE_VALUES, isMetadataSource } from './metadata_source.js';
|
|
16
|
+
export type { MetadataSource } from './metadata_source.js';
|
|
9
17
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AACpG,OAAO,EACL,MAAM,EACN,YAAY,EACZ,mBAAmB,EACnB,gBAAgB,EAChB,cAAc,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AACpG,OAAO,EACL,MAAM,EACN,YAAY,EACZ,mBAAmB,EACnB,gBAAgB,EAChB,cAAc,EACd,aAAa,GACd,MAAM,iBAAiB,CAAC;AACzB,YAAY,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,EACL,sBAAsB,EACtB,4BAA4B,EAC5B,2BAA2B,GAC5B,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,YAAY,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAChF,YAAY,EACV,YAAY,EACZ,iBAAiB,EACjB,SAAS,EACT,gBAAgB,EAChB,UAAU,GACX,MAAM,YAAY,CAAC;AACpB,YAAY,EACV,YAAY,EACZ,UAAU,EACV,YAAY,EACZ,iBAAiB,EACjB,QAAQ,EACR,QAAQ,EACR,OAAO,EACP,cAAc,EACd,iBAAiB,EACjB,eAAe,EACf,eAAe,EACf,YAAY,EACZ,OAAO,EACP,WAAW,EACX,WAAW,EACX,eAAe,EACf,SAAS,EACT,WAAW,EACX,aAAa,EACb,mBAAmB,EACnB,MAAM,EACN,YAAY,EACZ,WAAW,EACX,SAAS,GACV,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AACnF,OAAO,EACL,gBAAgB,EAChB,qBAAqB,EACrB,oBAAoB,EACpB,QAAQ,IAAI,qBAAqB,EACjC,qBAAqB,GACtB,MAAM,6BAA6B,CAAC;AACrC,YAAY,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AACvF,OAAO,EACL,eAAe,EACf,WAAW,EACX,QAAQ,IAAI,iBAAiB,EAC7B,UAAU,IAAI,mBAAmB,GAClC,MAAM,yBAAyB,CAAC;AACjC,YAAY,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAChF,YAAY,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
// @primust/artifact-core — Canonical JSON, hashing, signing, commitments, artifact types
|
|
2
2
|
export { canonical } from './canonical.js';
|
|
3
3
|
export { generateKeyPair, sign, verify, rotateKey, toBase64Url, fromBase64Url } from './signing.js';
|
|
4
|
-
export { commit, commitOutput, buildCommitmentRoot, selectProofLevel, ZK_IS_BLOCKING, } from './commitment.js';
|
|
4
|
+
export { commit, commitOutput, buildCommitmentRoot, selectProofLevel, ZK_IS_BLOCKING, BN254_MODULUS, } from './commitment.js';
|
|
5
|
+
export { poseidon2HexRecordLeaf, poseidon2HexL1ActionUnitLeaf, poseidon2HexL2SuperUnitLeaf, } from './hierarchical_leaf.js';
|
|
5
6
|
export { validateArtifact } from './validate-artifact.js';
|
|
7
|
+
export { TAXONOMY_VERSION, REVERSIBILITY_CLASSES, isReversibilityClass, classify as classifyReversibility, isWedgeSurfaceCovered, } from './reversibility_taxonomy.js';
|
|
8
|
+
export { MAPPING_VERSION, TRUST_EDGES, classify as classifyTrustEdge, knownKinds as knownTrustEdgeKinds, } from './trust_edge_mapping.js';
|
|
9
|
+
export { METADATA_SOURCE_VALUES, isMetadataSource } from './metadata_source.js';
|
|
6
10
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,yFAAyF;AACzF,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AACpG,OAAO,EACL,MAAM,EACN,YAAY,EACZ,mBAAmB,EACnB,gBAAgB,EAChB,cAAc,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,yFAAyF;AACzF,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AACpG,OAAO,EACL,MAAM,EACN,YAAY,EACZ,mBAAmB,EACnB,gBAAgB,EAChB,cAAc,EACd,aAAa,GACd,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACL,sBAAsB,EACtB,4BAA4B,EAC5B,2BAA2B,GAC5B,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAoC1D,OAAO,EACL,gBAAgB,EAChB,qBAAqB,EACrB,oBAAoB,EACpB,QAAQ,IAAI,qBAAqB,EACjC,qBAAqB,GACtB,MAAM,6BAA6B,CAAC;AAErC,OAAO,EACL,eAAe,EACf,WAAW,EACX,QAAQ,IAAI,iBAAiB,EAC7B,UAAU,IAAI,mBAAmB,GAClC,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export declare const METADATA_SOURCE_VALUES: readonly ["hook_observed", "sdk_decomposed", "sdk_caller_supplied", "hook_and_sdk_concordant"];
|
|
2
|
+
export type MetadataSource = (typeof METADATA_SOURCE_VALUES)[number];
|
|
3
|
+
export declare function isMetadataSource(value: unknown): value is MetadataSource;
|
|
4
|
+
//# sourceMappingURL=metadata_source.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metadata_source.d.ts","sourceRoot":"","sources":["../src/metadata_source.ts"],"names":[],"mappings":"AAkCA,eAAO,MAAM,sBAAsB,gGAmBzB,CAAC;AAEX,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,sBAAsB,CAAC,CAAC,MAAM,CAAC,CAAC;AAErE,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,cAAc,CAIxE"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
// metadata_source enum — TypeScript sibling of
|
|
2
|
+
// `packages/primust-checks/src/primust_checks/metadata_source.py`.
|
|
3
|
+
//
|
|
4
|
+
// Single source of truth for the metadata_source CHECK enum on
|
|
5
|
+
// check_execution_records (migration 179) on the TS side.
|
|
6
|
+
//
|
|
7
|
+
// Each of the four values is a PRECISE, NARROW provenance claim —
|
|
8
|
+
// not a fallback ladder. The values' trust meaning depends on staying
|
|
9
|
+
// narrow.
|
|
10
|
+
//
|
|
11
|
+
// - 'hook_observed' — A runtime intercept (CC / Cursor / Anthropic
|
|
12
|
+
// Agent SDK lifecycle hook) saw this at the framework boundary.
|
|
13
|
+
// Substrate witness; strongest non-repudiation.
|
|
14
|
+
//
|
|
15
|
+
// - 'sdk_decomposed' — An SDK adapter derived the bounded metadata
|
|
16
|
+
// in-process (LLM quadruple, enforcement attribution, redaction).
|
|
17
|
+
// Adapter composition — observed and shaped, not relayed.
|
|
18
|
+
//
|
|
19
|
+
// - 'sdk_caller_supplied' — App code passed metadata args to
|
|
20
|
+
// run.record() and the SDK relayed without deriving or
|
|
21
|
+
// independently observing. Caller-as-source-of-truth. Honest,
|
|
22
|
+
// narrow; weaker evidence than hook_observed (no substrate
|
|
23
|
+
// witness) or sdk_decomposed (no adapter composition).
|
|
24
|
+
//
|
|
25
|
+
// - 'hook_and_sdk_concordant' — Both layers independently confirmed
|
|
26
|
+
// the same fact via the trace_context join (Phase 3+). Cross-
|
|
27
|
+
// checked; highest trust. Back-filled server-side.
|
|
28
|
+
//
|
|
29
|
+
// - NULL — RESERVED for legacy pre-179 rows and aggregator-emitted
|
|
30
|
+
// records with no single per-record derivation. No new emitter
|
|
31
|
+
// should land NULL. A NULL on a fresh record is an emitter bug.
|
|
32
|
+
//
|
|
33
|
+
// SI-1: enum-constrained string, never content.
|
|
34
|
+
export const METADATA_SOURCE_VALUES = [
|
|
35
|
+
// Runtime intercept saw the event at the framework boundary.
|
|
36
|
+
// Substrate witness; strongest non-repudiation.
|
|
37
|
+
'hook_observed',
|
|
38
|
+
// SDK adapter derived the bounded metadata in-process (LLM
|
|
39
|
+
// quadruple, enforcement attribution, redaction). Adapter
|
|
40
|
+
// composition — observed and shaped, not relayed.
|
|
41
|
+
'sdk_decomposed',
|
|
42
|
+
// App code passed metadata args to run.record() and the SDK
|
|
43
|
+
// relayed without deriving or independently observing. Honest,
|
|
44
|
+
// narrow; weaker than hook_observed / sdk_decomposed.
|
|
45
|
+
'sdk_caller_supplied',
|
|
46
|
+
// Both layers independently confirmed the same fact via the
|
|
47
|
+
// trace_context join (Phase 3+). Cross-checked; highest trust.
|
|
48
|
+
// Back-filled server-side; never emitted directly by a single layer.
|
|
49
|
+
'hook_and_sdk_concordant',
|
|
50
|
+
];
|
|
51
|
+
export function isMetadataSource(value) {
|
|
52
|
+
return (typeof value === 'string' && METADATA_SOURCE_VALUES.includes(value));
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=metadata_source.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metadata_source.js","sourceRoot":"","sources":["../src/metadata_source.ts"],"names":[],"mappings":"AAAA,+CAA+C;AAC/C,mEAAmE;AACnE,EAAE;AACF,+DAA+D;AAC/D,0DAA0D;AAC1D,EAAE;AACF,kEAAkE;AAClE,sEAAsE;AACtE,UAAU;AACV,EAAE;AACF,qEAAqE;AACrE,oEAAoE;AACpE,oDAAoD;AACpD,EAAE;AACF,qEAAqE;AACrE,sEAAsE;AACtE,8DAA8D;AAC9D,EAAE;AACF,+DAA+D;AAC/D,2DAA2D;AAC3D,kEAAkE;AAClE,+DAA+D;AAC/D,2DAA2D;AAC3D,EAAE;AACF,sEAAsE;AACtE,kEAAkE;AAClE,uDAAuD;AACvD,EAAE;AACF,qEAAqE;AACrE,mEAAmE;AACnE,oEAAoE;AACpE,EAAE;AACF,gDAAgD;AAEhD,MAAM,CAAC,MAAM,sBAAsB,GAAG;IACpC,6DAA6D;IAC7D,gDAAgD;IAChD,eAAe;IAEf,2DAA2D;IAC3D,0DAA0D;IAC1D,kDAAkD;IAClD,gBAAgB;IAEhB,4DAA4D;IAC5D,+DAA+D;IAC/D,sDAAsD;IACtD,qBAAqB;IAErB,4DAA4D;IAC5D,+DAA+D;IAC/D,qEAAqE;IACrE,yBAAyB;CACjB,CAAC;AAIX,MAAM,UAAU,gBAAgB,CAAC,KAAc;IAC7C,OAAO,CACL,OAAO,KAAK,KAAK,QAAQ,IAAK,sBAA4C,CAAC,QAAQ,CAAC,KAAK,CAAC,CAC3F,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metadata_source.test.d.ts","sourceRoot":"","sources":["../src/metadata_source.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { METADATA_SOURCE_VALUES, isMetadataSource } from './metadata_source.js';
|
|
3
|
+
describe('metadata_source', () => {
|
|
4
|
+
it('has exactly the four canonical values from migration 179', () => {
|
|
5
|
+
expect(new Set(METADATA_SOURCE_VALUES)).toEqual(new Set([
|
|
6
|
+
'hook_observed',
|
|
7
|
+
'sdk_decomposed',
|
|
8
|
+
'sdk_caller_supplied',
|
|
9
|
+
'hook_and_sdk_concordant',
|
|
10
|
+
]));
|
|
11
|
+
});
|
|
12
|
+
it('isMetadataSource accepts all four enum strings', () => {
|
|
13
|
+
for (const v of METADATA_SOURCE_VALUES) {
|
|
14
|
+
expect(isMetadataSource(v)).toBe(true);
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
it('rejects unknown strings (including the distinct `source` enum)', () => {
|
|
18
|
+
expect(isMetadataSource('garbage')).toBe(false);
|
|
19
|
+
expect(isMetadataSource('hook')).toBe(false); // bare 'hook' is `source`, not metadata_source
|
|
20
|
+
expect(isMetadataSource('sdk')).toBe(false);
|
|
21
|
+
});
|
|
22
|
+
it('rejects non-strings', () => {
|
|
23
|
+
expect(isMetadataSource(null)).toBe(false);
|
|
24
|
+
expect(isMetadataSource(42)).toBe(false);
|
|
25
|
+
expect(isMetadataSource([])).toBe(false);
|
|
26
|
+
expect(isMetadataSource({ value: 'hook_observed' })).toBe(false);
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
//# sourceMappingURL=metadata_source.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metadata_source.test.js","sourceRoot":"","sources":["../src/metadata_source.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAEhF,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;IAC/B,EAAE,CAAC,0DAA0D,EAAE,GAAG,EAAE;QAClE,MAAM,CAAC,IAAI,GAAG,CAAC,sBAAsB,CAAC,CAAC,CAAC,OAAO,CAC7C,IAAI,GAAG,CAAC;YACN,eAAe;YACf,gBAAgB;YAChB,qBAAqB;YACrB,yBAAyB;SAC1B,CAAC,CACH,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gDAAgD,EAAE,GAAG,EAAE;QACxD,KAAK,MAAM,CAAC,IAAI,sBAAsB,EAAE,CAAC;YACvC,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACzC,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gEAAgE,EAAE,GAAG,EAAE;QACxE,MAAM,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAChD,MAAM,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,+CAA+C;QAC7F,MAAM,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qBAAqB,EAAE,GAAG,EAAE;QAC7B,MAAM,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC3C,MAAM,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACzC,MAAM,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACzC,MAAM,CAAC,gBAAgB,CAAC,EAAE,KAAK,EAAE,eAAe,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACnE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export declare const TAXONOMY_VERSION: "1.0.0";
|
|
2
|
+
export declare const REVERSIBILITY_CLASSES: readonly ["reversible", "append_only", "external_side_effect", "irreversible", "unknown"];
|
|
3
|
+
export type ReversibilityClass = (typeof REVERSIBILITY_CLASSES)[number];
|
|
4
|
+
export declare function isReversibilityClass(v: unknown): v is ReversibilityClass;
|
|
5
|
+
export interface ClassifyOptions {
|
|
6
|
+
overrides?: Record<string, string>;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Classify an outbound action by `(target_system_kind, operation)`.
|
|
10
|
+
*
|
|
11
|
+
* Lookup order:
|
|
12
|
+
* 1. Customer override for the exact (kind, op) pair.
|
|
13
|
+
* 2. System default for the exact (kind, op) pair.
|
|
14
|
+
* 3. Per-kind fallback.
|
|
15
|
+
* 4. `'unknown'`.
|
|
16
|
+
*/
|
|
17
|
+
export declare function classify(target_system_kind: string, operation: string, options?: ClassifyOptions): ReversibilityClass;
|
|
18
|
+
/**
|
|
19
|
+
* True if this kind has real (non-`'unknown'`) classifications in the
|
|
20
|
+
* system defaults. Used by the Phase 1 acceptance gate.
|
|
21
|
+
*/
|
|
22
|
+
export declare function isWedgeSurfaceCovered(target_system_kind: string): boolean;
|
|
23
|
+
//# sourceMappingURL=reversibility_taxonomy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reversibility_taxonomy.d.ts","sourceRoot":"","sources":["../src/reversibility_taxonomy.ts"],"names":[],"mappings":"AAcA,eAAO,MAAM,gBAAgB,EAAG,OAAgB,CAAC;AAEjD,eAAO,MAAM,qBAAqB,2FAMxB,CAAC;AAEX,MAAM,MAAM,kBAAkB,GAAG,CAAC,OAAO,qBAAqB,CAAC,CAAC,MAAM,CAAC,CAAC;AAGxE,wBAAgB,oBAAoB,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,IAAI,kBAAkB,CAExE;AAgKD,MAAM,WAAW,eAAe;IAI9B,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACpC;AAED;;;;;;;;GAQG;AACH,wBAAgB,QAAQ,CACtB,kBAAkB,EAAE,MAAM,EAC1B,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,eAAoB,GAC5B,kBAAkB,CAcpB;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,kBAAkB,EAAE,MAAM,GAAG,OAAO,CAMzE"}
|