agent-passport-system 1.45.0 → 1.46.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 (34) hide show
  1. package/README.md +2 -2
  2. package/dist/src/v2/attribution-settlement/aggregate.d.ts +30 -0
  3. package/dist/src/v2/attribution-settlement/aggregate.d.ts.map +1 -0
  4. package/dist/src/v2/attribution-settlement/aggregate.js +306 -0
  5. package/dist/src/v2/attribution-settlement/aggregate.js.map +1 -0
  6. package/dist/src/v2/attribution-settlement/contributor-query.d.ts +21 -0
  7. package/dist/src/v2/attribution-settlement/contributor-query.d.ts.map +1 -0
  8. package/dist/src/v2/attribution-settlement/contributor-query.js +147 -0
  9. package/dist/src/v2/attribution-settlement/contributor-query.js.map +1 -0
  10. package/dist/src/v2/attribution-settlement/index.d.ts +9 -0
  11. package/dist/src/v2/attribution-settlement/index.d.ts.map +1 -0
  12. package/dist/src/v2/attribution-settlement/index.js +14 -0
  13. package/dist/src/v2/attribution-settlement/index.js.map +1 -0
  14. package/dist/src/v2/attribution-settlement/merkle.d.ts +20 -0
  15. package/dist/src/v2/attribution-settlement/merkle.d.ts.map +1 -0
  16. package/dist/src/v2/attribution-settlement/merkle.js +100 -0
  17. package/dist/src/v2/attribution-settlement/merkle.js.map +1 -0
  18. package/dist/src/v2/attribution-settlement/sign.d.ts +16 -0
  19. package/dist/src/v2/attribution-settlement/sign.d.ts.map +1 -0
  20. package/dist/src/v2/attribution-settlement/sign.js +55 -0
  21. package/dist/src/v2/attribution-settlement/sign.js.map +1 -0
  22. package/dist/src/v2/attribution-settlement/types.d.ts +127 -0
  23. package/dist/src/v2/attribution-settlement/types.d.ts.map +1 -0
  24. package/dist/src/v2/attribution-settlement/types.js +11 -0
  25. package/dist/src/v2/attribution-settlement/types.js.map +1 -0
  26. package/dist/src/v2/attribution-settlement/verify.d.ts +17 -0
  27. package/dist/src/v2/attribution-settlement/verify.d.ts.map +1 -0
  28. package/dist/src/v2/attribution-settlement/verify.js +227 -0
  29. package/dist/src/v2/attribution-settlement/verify.js.map +1 -0
  30. package/dist/src/v2/index.d.ts +2 -0
  31. package/dist/src/v2/index.d.ts.map +1 -1
  32. package/dist/src/v2/index.js +5 -0
  33. package/dist/src/v2/index.js.map +1 -1
  34. package/package.json +3 -3
package/README.md CHANGED
@@ -123,11 +123,11 @@ Institutional governance: charters, offices, federation, reserves, multi-party a
123
123
  npx agent-passport-system-mcp
124
124
  ```
125
125
 
126
- 20 essential tools by default. Set `APS_PROFILE=full` for all 149 tools. Profiles: essential, identity, governance, coordination, commerce, data, gateway, comms, minimal, full.
126
+ 20 essential tools by default. Set `APS_PROFILE=full` for all 151 tools. Profiles: essential, identity, governance, coordination, commerce, data, gateway, comms, minimal, full.
127
127
 
128
128
  ## Numbers
129
129
 
130
- 2,910 tests. 8 protocol layers. 11 framework adapters. Gateway evaluation under 2ms. Zero heavy dependencies. Apache-2.0.
130
+ 2,937 tests. 8 protocol layers. 11 framework adapters. Gateway evaluation under 2ms. Zero heavy dependencies. Apache-2.0.
131
131
 
132
132
  ## Papers
133
133
 
@@ -0,0 +1,30 @@
1
+ import type { AttributionPrimitive } from '../attribution-primitive/types.js';
2
+ import type { SettlementContributor, SettlementPeriod, SettlementRecord, SettlementResidualBucket } from './types.js';
3
+ /** Canonical per-contributor leaf hash — hex sha256 of the canonical
4
+ * body (contributor_did, total_weight, contribution_count). Exposed so
5
+ * contributor-query verifiers recompute the same bytes. */
6
+ export declare function contributorLeafHashHex(c: SettlementContributor): string;
7
+ /** Residual-bucket leaf hash for the per-axis tree. Canonicalizes the
8
+ * full bucket object. */
9
+ export declare function residualLeafHashHex(r: SettlementResidualBucket): string;
10
+ /** 6-digit decimal form for settlement weights. Unlike Build A's
11
+ * `toWeightString`, settlement weights can exceed 1.0 (they accumulate
12
+ * over many actions); the 6-digit precision is preserved. Rejects
13
+ * non-finite or negative values. */
14
+ export declare function formatSettlementWeight(v: number): string;
15
+ export interface AggregateOptions {
16
+ /** Gateway DID that will sign the settlement record. */
17
+ gateway_did: string;
18
+ /** Override issued_at (tests, replayed audits). Must be canonical. */
19
+ issued_at?: string;
20
+ /** When false, throws on any receipt whose timestamp is outside
21
+ * [t0, t1). Default is true — out-of-period receipts are silently
22
+ * dropped so a caller can hand us an uncurated batch. */
23
+ skipOutOfPeriod?: boolean;
24
+ }
25
+ /** Compute the unsigned settlement record for `receipts` over `period`.
26
+ * Half-open interval [t0, t1) — receipts at exactly t1 are excluded.
27
+ * Returns the record minus its `signature` field; callers pass the
28
+ * result to `signSettlementRecord` to produce the signed record. */
29
+ export declare function aggregateAttributionPrimitives(receipts: AttributionPrimitive[], period: SettlementPeriod, options: AggregateOptions): Omit<SettlementRecord, 'signature'>;
30
+ //# sourceMappingURL=aggregate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aggregate.d.ts","sourceRoot":"","sources":["../../../../src/v2/attribution-settlement/aggregate.ts"],"names":[],"mappings":"AAkCA,OAAO,KAAK,EAEV,oBAAoB,EASrB,MAAM,mCAAmC,CAAA;AAE1C,OAAO,KAAK,EAEV,qBAAqB,EACrB,gBAAgB,EAChB,gBAAgB,EAChB,wBAAwB,EACzB,MAAM,YAAY,CAAA;AA8BnB;;4DAE4D;AAC5D,wBAAgB,sBAAsB,CAAC,CAAC,EAAE,qBAAqB,GAAG,MAAM,CAEvE;AAED;0BAC0B;AAC1B,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,wBAAwB,GAAG,MAAM,CAEvE;AA6GD;;;qCAGqC;AACrC,wBAAgB,sBAAsB,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAQxD;AA4ED,MAAM,WAAW,gBAAgB;IAC/B,wDAAwD;IACxD,WAAW,EAAE,MAAM,CAAA;IACnB,sEAAsE;IACtE,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;8DAE0D;IAC1D,eAAe,CAAC,EAAE,OAAO,CAAA;CAC1B;AAED;;;qEAGqE;AACrE,wBAAgB,8BAA8B,CAC5C,QAAQ,EAAE,oBAAoB,EAAE,EAChC,MAAM,EAAE,gBAAgB,EACxB,OAAO,EAAE,gBAAgB,GACxB,IAAI,CAAC,gBAAgB,EAAE,WAAW,CAAC,CA6ErC"}
@@ -0,0 +1,306 @@
1
+ // Copyright 2024-2026 Tymofii Pidlisnyi. Apache-2.0 license. See LICENSE.
2
+ // ══════════════════════════════════════════════════════════════════
3
+ // Attribution Settlement — aggregation (Build C)
4
+ // ══════════════════════════════════════════════════════════════════
5
+ // Spec: BUILD-C-SETTLEMENT-PIPELINE.md §"The aggregation".
6
+ //
7
+ // Given a stream of Attribution Primitives whose timestamps fall within
8
+ // [t0, t1) (half-open; I-C5 / property test #7), compute:
9
+ //
10
+ // - per-axis per-contributor total_weight (sum of signed weights)
11
+ // - per-axis residual bucket aggregation
12
+ // - per-axis balanced-Merkle axis_merkle_root
13
+ // - input_receipts_hash (Merkle commitment over sorted action_refs)
14
+ //
15
+ // Axis weight sourcing:
16
+ // D contribution_weight (Build B normalized; sums to ~1 per receipt)
17
+ // C compute_share (Build B normalized; sums to ~1 per receipt)
18
+ // P weight if present on every explicit entry; equal-split (1/|P|)
19
+ // otherwise. Mixed-weight receipts fall back to the weights they
20
+ // carry and omit unweighted entries — documented in the handoff.
21
+ // G equal-split (1/|G|) — governance axis has no weight field in
22
+ // Build A. Equal-split preserves I-C2 conservation (Σ weights per
23
+ // receipt = 1) without inventing economic meaning the spec declines
24
+ // to define.
25
+ //
26
+ // Residual buckets are treated as a single virtual contributor per axis;
27
+ // their `total_pooled_weight` sums across the period (I-C6).
28
+ // ══════════════════════════════════════════════════════════════════
29
+ import { createHash } from 'node:crypto';
30
+ import { canonicalize } from '../../core/canonical.js';
31
+ import { assertCanonicalTimestamp, } from '../attribution-primitive/canonical.js';
32
+ import { buildMerkleRoot, emptyAxisMerkleRoot, leafHash } from './merkle.js';
33
+ function isResidual(x) {
34
+ return (typeof x === 'object' &&
35
+ x !== null &&
36
+ 'residual_id' in x &&
37
+ typeof x.residual_id === 'string' &&
38
+ x.residual_id.startsWith('residual:'));
39
+ }
40
+ function weightNumber(w) {
41
+ const n = Number.parseFloat(w);
42
+ if (!Number.isFinite(n))
43
+ throw new Error(`attribution-settlement: invalid weight string "${w}"`);
44
+ return n;
45
+ }
46
+ function contributorLeafBody(c) {
47
+ return {
48
+ contributor_did: c.contributor_did,
49
+ total_weight: c.total_weight,
50
+ contribution_count: c.contribution_count,
51
+ };
52
+ }
53
+ /** Canonical per-contributor leaf hash — hex sha256 of the canonical
54
+ * body (contributor_did, total_weight, contribution_count). Exposed so
55
+ * contributor-query verifiers recompute the same bytes. */
56
+ export function contributorLeafHashHex(c) {
57
+ return createHash('sha256').update(canonicalize(contributorLeafBody(c))).digest('hex');
58
+ }
59
+ /** Residual-bucket leaf hash for the per-axis tree. Canonicalizes the
60
+ * full bucket object. */
61
+ export function residualLeafHashHex(r) {
62
+ return createHash('sha256').update(canonicalize(r)).digest('hex');
63
+ }
64
+ function emptyAccum() {
65
+ return {
66
+ map: new Map(),
67
+ pooledWeight: 0,
68
+ pooledMemberCount: 0,
69
+ perReceiptResidualHashes: [],
70
+ totalActions: 0,
71
+ };
72
+ }
73
+ function addContributor(accum, did, weight) {
74
+ const cur = accum.map.get(did);
75
+ if (cur) {
76
+ cur.total += weight;
77
+ cur.count += 1;
78
+ }
79
+ else {
80
+ accum.map.set(did, { total: weight, count: 1 });
81
+ }
82
+ }
83
+ function accumulateResidual(accum, bucket) {
84
+ accum.pooledWeight += weightNumber(bucket.total_pooled_weight);
85
+ accum.pooledMemberCount += bucket.count_of_pooled_contributors;
86
+ accum.perReceiptResidualHashes.push(bucket.pooled_contributors_hash);
87
+ }
88
+ function pooledWeightOfReceipt(residuals) {
89
+ let w = 0;
90
+ for (const r of residuals)
91
+ w += weightNumber(r.total_pooled_weight);
92
+ return w;
93
+ }
94
+ function processDataAxis(items, accum) {
95
+ if (items.length === 0)
96
+ return;
97
+ accum.totalActions += 1;
98
+ for (const item of items) {
99
+ if (isResidual(item)) {
100
+ accumulateResidual(accum, item);
101
+ }
102
+ else {
103
+ const e = item;
104
+ addContributor(accum, e.source_did, weightNumber(e.contribution_weight));
105
+ }
106
+ }
107
+ }
108
+ function processComputeAxis(items, accum) {
109
+ if (items.length === 0)
110
+ return;
111
+ accum.totalActions += 1;
112
+ for (const item of items) {
113
+ if (isResidual(item)) {
114
+ accumulateResidual(accum, item);
115
+ }
116
+ else {
117
+ const e = item;
118
+ addContributor(accum, e.provider_did, weightNumber(e.compute_share));
119
+ }
120
+ }
121
+ }
122
+ function protocolEntryDid(e) {
123
+ return `${e.module_id}@${e.module_version}`;
124
+ }
125
+ function processProtocolAxis(items, accum) {
126
+ if (items.length === 0)
127
+ return;
128
+ accum.totalActions += 1;
129
+ const explicit = items.filter((x) => !isResidual(x));
130
+ const residuals = items.filter((x) => isResidual(x));
131
+ for (const r of residuals)
132
+ accumulateResidual(accum, r);
133
+ const anyWeighted = explicit.some((e) => e.weight !== undefined);
134
+ if (anyWeighted) {
135
+ for (const e of explicit) {
136
+ if (e.weight === undefined)
137
+ continue;
138
+ addContributor(accum, protocolEntryDid(e), weightNumber(e.weight));
139
+ }
140
+ }
141
+ else if (explicit.length > 0) {
142
+ const budget = Math.max(0, 1 - pooledWeightOfReceipt(residuals));
143
+ const w = budget / explicit.length;
144
+ for (const e of explicit) {
145
+ addContributor(accum, protocolEntryDid(e), w);
146
+ }
147
+ }
148
+ }
149
+ function processGovernanceAxis(items, accum) {
150
+ if (items.length === 0)
151
+ return;
152
+ accum.totalActions += 1;
153
+ const w = 1 / items.length;
154
+ for (const e of items) {
155
+ addContributor(accum, e.signer_did, w);
156
+ }
157
+ }
158
+ /** 6-digit decimal form for settlement weights. Unlike Build A's
159
+ * `toWeightString`, settlement weights can exceed 1.0 (they accumulate
160
+ * over many actions); the 6-digit precision is preserved. Rejects
161
+ * non-finite or negative values. */
162
+ export function formatSettlementWeight(v) {
163
+ if (!Number.isFinite(v)) {
164
+ throw new Error(`attribution-settlement: weight must be finite, got ${v}`);
165
+ }
166
+ if (v < 0) {
167
+ throw new Error(`attribution-settlement: weight must be non-negative, got ${v}`);
168
+ }
169
+ return v.toFixed(6);
170
+ }
171
+ function finalizeAxis(axis, accum, period) {
172
+ const dids = [...accum.map.keys()].sort();
173
+ const contributors = dids.map((did) => {
174
+ const { total, count } = accum.map.get(did);
175
+ const totalStr = formatSettlementWeight(total);
176
+ const leafBody = {
177
+ contributor_did: did,
178
+ total_weight: totalStr,
179
+ contribution_count: count,
180
+ };
181
+ const merkle_leaf_hash = createHash('sha256')
182
+ .update(canonicalize(leafBody))
183
+ .digest('hex');
184
+ return {
185
+ contributor_did: did,
186
+ total_weight: totalStr,
187
+ contribution_count: count,
188
+ merkle_leaf_hash,
189
+ };
190
+ });
191
+ let residual_bucket = null;
192
+ if (accum.pooledMemberCount > 0 || accum.perReceiptResidualHashes.length > 0) {
193
+ if (axis === 'G') {
194
+ throw new Error('attribution-settlement: governance axis cannot carry a residual bucket');
195
+ }
196
+ const sortedPerReceiptHashes = [...accum.perReceiptResidualHashes].sort();
197
+ const pooled_contributors_hash = createHash('sha256')
198
+ .update(canonicalize(sortedPerReceiptHashes))
199
+ .digest('hex');
200
+ const residual_id = `residual:${axis}`;
201
+ residual_bucket = {
202
+ residual_id,
203
+ total_pooled_weight: formatSettlementWeight(accum.pooledWeight),
204
+ count_of_pooled_contributors: accum.pooledMemberCount,
205
+ pooled_contributors_hash,
206
+ };
207
+ }
208
+ const leafHashes = contributors.map((c) => Buffer.from(c.merkle_leaf_hash, 'hex'));
209
+ if (residual_bucket) {
210
+ leafHashes.push(Buffer.from(residualLeafHashHex(residual_bucket), 'hex'));
211
+ }
212
+ const axis_merkle_root = leafHashes.length === 0 ? emptyAxisMerkleRoot() : buildMerkleRoot(leafHashes).toString('hex');
213
+ return {
214
+ axis,
215
+ period,
216
+ total_actions: accum.totalActions,
217
+ contributors,
218
+ residual_bucket,
219
+ axis_merkle_root,
220
+ };
221
+ }
222
+ function assertPeriod(period) {
223
+ if (!period || typeof period !== 'object') {
224
+ throw new Error('attribution-settlement: period required');
225
+ }
226
+ assertCanonicalTimestamp(period.t0);
227
+ assertCanonicalTimestamp(period.t1);
228
+ if (Date.parse(period.t0) >= Date.parse(period.t1)) {
229
+ throw new Error('attribution-settlement: period.t0 must be strictly before period.t1');
230
+ }
231
+ if (typeof period.period_id !== 'string' || period.period_id.length === 0) {
232
+ throw new Error('attribution-settlement: period.period_id required');
233
+ }
234
+ }
235
+ /** Compute the unsigned settlement record for `receipts` over `period`.
236
+ * Half-open interval [t0, t1) — receipts at exactly t1 are excluded.
237
+ * Returns the record minus its `signature` field; callers pass the
238
+ * result to `signSettlementRecord` to produce the signed record. */
239
+ export function aggregateAttributionPrimitives(receipts, period, options) {
240
+ if (!Array.isArray(receipts)) {
241
+ throw new Error('attribution-settlement: receipts must be an array');
242
+ }
243
+ if (!options || typeof options.gateway_did !== 'string' || options.gateway_did.length === 0) {
244
+ throw new Error('attribution-settlement: options.gateway_did required');
245
+ }
246
+ assertPeriod(period);
247
+ const t0 = Date.parse(period.t0);
248
+ const t1 = Date.parse(period.t1);
249
+ const skipOut = options.skipOutOfPeriod !== false;
250
+ const accums = {
251
+ D: emptyAccum(),
252
+ P: emptyAccum(),
253
+ G: emptyAccum(),
254
+ C: emptyAccum(),
255
+ };
256
+ const inPeriod = [];
257
+ for (const r of receipts) {
258
+ assertCanonicalTimestamp(r.timestamp);
259
+ const ts = Date.parse(r.timestamp);
260
+ if (ts < t0 || ts >= t1) {
261
+ if (!skipOut) {
262
+ throw new Error(`attribution-settlement: receipt ${r.action_ref} timestamp ${r.timestamp} outside period [${period.t0}, ${period.t1})`);
263
+ }
264
+ continue;
265
+ }
266
+ inPeriod.push(r);
267
+ }
268
+ for (const r of inPeriod) {
269
+ processDataAxis(r.axes.D, accums.D);
270
+ processProtocolAxis(r.axes.P, accums.P);
271
+ processGovernanceAxis(r.axes.G, accums.G);
272
+ processComputeAxis(r.axes.C, accums.C);
273
+ }
274
+ // Deep-clone period per axis so the shared-reference DAG doesn't trip
275
+ // core/canonical.ts's cycle detector (which treats any revisit as a
276
+ // cycle — a separate latent bug, worked around here). JSON-safe clone
277
+ // is fine: period is three plain strings.
278
+ const clonePeriod = () => ({
279
+ t0: period.t0,
280
+ t1: period.t1,
281
+ period_id: period.period_id,
282
+ });
283
+ const axes = {
284
+ D: finalizeAxis('D', accums.D, clonePeriod()),
285
+ P: finalizeAxis('P', accums.P, clonePeriod()),
286
+ G: finalizeAxis('G', accums.G, clonePeriod()),
287
+ C: finalizeAxis('C', accums.C, clonePeriod()),
288
+ };
289
+ const sortedActionRefs = inPeriod.map((r) => r.action_ref).sort();
290
+ const actionRefLeaves = sortedActionRefs.map((ref) => leafHash(ref));
291
+ const input_receipts_hash = actionRefLeaves.length === 0
292
+ ? emptyAxisMerkleRoot()
293
+ : buildMerkleRoot(actionRefLeaves).toString('hex');
294
+ const issued_at = options.issued_at ?? new Date().toISOString();
295
+ assertCanonicalTimestamp(issued_at);
296
+ return {
297
+ schema: 'aps.settlement.v1',
298
+ period,
299
+ gateway_did: options.gateway_did,
300
+ axes,
301
+ input_receipts_hash,
302
+ total_input_count: inPeriod.length,
303
+ issued_at,
304
+ };
305
+ }
306
+ //# sourceMappingURL=aggregate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aggregate.js","sourceRoot":"","sources":["../../../../src/v2/attribution-settlement/aggregate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import type { ContributorQueryResponse, SettlementRecord, SettlementVerifyResult } from './types.js';
2
+ /** Build the per-contributor query response. Returns null if the
3
+ * contributor has no share on any axis — callers can surface that
4
+ * distinctly from "the gateway returned a response, here it is". */
5
+ export declare function buildContributorQueryResponse(record: SettlementRecord, contributorDid: string, opts?: {
6
+ gateway_jwks?: string;
7
+ }): ContributorQueryResponse | null;
8
+ /** Verify a contributor-query response end-to-end. Checks:
9
+ *
10
+ * (a) the embedded SettlementRecord passes S1–S4
11
+ * (b) each per_axis body's (leaf, leaf_index, merkle_path) reconstructs
12
+ * `axis_root`, which matches `record.axes[X].axis_merkle_root`
13
+ * (c) the claimed total_weight and contribution_count match the
14
+ * record's per-axis contributor row
15
+ * (d) settlement_record_hash recomputes
16
+ *
17
+ * Returns the same discriminated result type as `verifySettlementRecord`. */
18
+ export declare function verifyContributorQueryResponse(response: ContributorQueryResponse, options: {
19
+ gatewayPublicKeyHex: string;
20
+ }): SettlementVerifyResult;
21
+ //# sourceMappingURL=contributor-query.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contributor-query.d.ts","sourceRoot":"","sources":["../../../../src/v2/attribution-settlement/contributor-query.ts"],"names":[],"mappings":"AA0BA,OAAO,KAAK,EAEV,wBAAwB,EAExB,gBAAgB,EAChB,sBAAsB,EACvB,MAAM,YAAY,CAAA;AAoBnB;;qEAEqE;AACrE,wBAAgB,6BAA6B,CAC3C,MAAM,EAAE,gBAAgB,EACxB,cAAc,EAAE,MAAM,EACtB,IAAI,CAAC,EAAE;IAAE,YAAY,CAAC,EAAE,MAAM,CAAA;CAAE,GAC/B,wBAAwB,GAAG,IAAI,CAqCjC;AAED;;;;;;;;;8EAS8E;AAC9E,wBAAgB,8BAA8B,CAC5C,QAAQ,EAAE,wBAAwB,EAClC,OAAO,EAAE;IAAE,mBAAmB,EAAE,MAAM,CAAA;CAAE,GACvC,sBAAsB,CAsExB"}
@@ -0,0 +1,147 @@
1
+ // Copyright 2024-2026 Tymofii Pidlisnyi. Apache-2.0 license. See LICENSE.
2
+ // ══════════════════════════════════════════════════════════════════
3
+ // Attribution Settlement — contributor-query response (Build C)
4
+ // ══════════════════════════════════════════════════════════════════
5
+ // Spec: BUILD-C-SETTLEMENT-PIPELINE.md §"The contributor query".
6
+ //
7
+ // Given a signed SettlementRecord and a contributor DID, construct the
8
+ // per-axis proof bundle: for each axis where the contributor has a
9
+ // share, return the Merkle path from their leaf to that axis's root.
10
+ //
11
+ // Verification is fully self-contained: the response embeds the signed
12
+ // record so a third party can reproduce S1–S2 end-to-end with only the
13
+ // gateway public key.
14
+ // ══════════════════════════════════════════════════════════════════
15
+ import { buildContributorMerklePath, verifyMerklePath, } from './merkle.js';
16
+ import { residualLeafHashHex } from './aggregate.js';
17
+ import { settlementRecordHash, verifySettlementSignature, } from './sign.js';
18
+ import { verifySettlementRecord } from './verify.js';
19
+ function buildAxisLeaves(axis) {
20
+ const leaves = axis.contributors.map((c) => Buffer.from(c.merkle_leaf_hash, 'hex'));
21
+ if (axis.residual_bucket) {
22
+ leaves.push(Buffer.from(residualLeafHashHex(axis.residual_bucket), 'hex'));
23
+ }
24
+ return leaves;
25
+ }
26
+ function findContributorIndex(axis, contributorDid) {
27
+ for (let i = 0; i < axis.contributors.length; i++) {
28
+ if (axis.contributors[i].contributor_did === contributorDid)
29
+ return i;
30
+ }
31
+ return -1;
32
+ }
33
+ /** Build the per-contributor query response. Returns null if the
34
+ * contributor has no share on any axis — callers can surface that
35
+ * distinctly from "the gateway returned a response, here it is". */
36
+ export function buildContributorQueryResponse(record, contributorDid, opts) {
37
+ if (!contributorDid || typeof contributorDid !== 'string') {
38
+ throw new Error('attribution-settlement: contributorDid required');
39
+ }
40
+ const per_axis = {};
41
+ let anyFound = false;
42
+ for (const tag of ['D', 'P', 'G', 'C']) {
43
+ const axis = record.axes[tag];
44
+ const idx = findContributorIndex(axis, contributorDid);
45
+ if (idx < 0)
46
+ continue;
47
+ const leaves = buildAxisLeaves(axis);
48
+ const merkle_path = buildContributorMerklePath(leaves, idx);
49
+ const body = {
50
+ total_weight: axis.contributors[idx].total_weight,
51
+ contribution_count: axis.contributors[idx].contribution_count,
52
+ leaf_index: idx,
53
+ merkle_path,
54
+ axis_root: axis.axis_merkle_root,
55
+ };
56
+ per_axis[tag] = body;
57
+ anyFound = true;
58
+ }
59
+ if (!anyFound)
60
+ return null;
61
+ const { signature: _unused, ...unsigned } = record;
62
+ void _unused;
63
+ return {
64
+ settlement_record: record,
65
+ settlement_record_hash: settlementRecordHash(unsigned),
66
+ contributor_did: contributorDid,
67
+ per_axis,
68
+ gateway_jwks: opts?.gateway_jwks,
69
+ };
70
+ }
71
+ /** Verify a contributor-query response end-to-end. Checks:
72
+ *
73
+ * (a) the embedded SettlementRecord passes S1–S4
74
+ * (b) each per_axis body's (leaf, leaf_index, merkle_path) reconstructs
75
+ * `axis_root`, which matches `record.axes[X].axis_merkle_root`
76
+ * (c) the claimed total_weight and contribution_count match the
77
+ * record's per-axis contributor row
78
+ * (d) settlement_record_hash recomputes
79
+ *
80
+ * Returns the same discriminated result type as `verifySettlementRecord`. */
81
+ export function verifyContributorQueryResponse(response, options) {
82
+ if (!response || typeof response !== 'object') {
83
+ return { valid: false, reason: 'MALFORMED', detail: 'response must be an object' };
84
+ }
85
+ if (!options || !options.gatewayPublicKeyHex) {
86
+ return { valid: false, reason: 'MALFORMED', detail: 'options.gatewayPublicKeyHex required' };
87
+ }
88
+ if (!response.settlement_record) {
89
+ return { valid: false, reason: 'MALFORMED', detail: 'settlement_record required' };
90
+ }
91
+ // (a) delegate to the settlement verifier for S1–S4.
92
+ const inner = verifySettlementRecord(response.settlement_record, {
93
+ gatewayPublicKeyHex: options.gatewayPublicKeyHex,
94
+ });
95
+ if (!inner.valid)
96
+ return inner;
97
+ // Redundant sanity-check on the signature — verifySettlementRecord
98
+ // already did this, but we want a distinct code path that future
99
+ // refactors can't silently drop.
100
+ if (!verifySettlementSignature(response.settlement_record, options.gatewayPublicKeyHex)) {
101
+ return { valid: false, reason: 'SIGNATURE_INVALID' };
102
+ }
103
+ // (d) settlement_record_hash recomputes.
104
+ const { signature: _unused, ...body } = response.settlement_record;
105
+ void _unused;
106
+ const expectedHash = settlementRecordHash(body);
107
+ if (expectedHash !== response.settlement_record_hash.toLowerCase()) {
108
+ return { valid: false, reason: 'MERKLE_ROOT_MISMATCH', detail: 'settlement_record_hash mismatch' };
109
+ }
110
+ // (b, c) per-axis path and claim verification.
111
+ for (const tag of Object.keys(response.per_axis)) {
112
+ const axisBody = response.per_axis[tag];
113
+ if (!axisBody)
114
+ continue;
115
+ const axis = response.settlement_record.axes[tag];
116
+ if (axisBody.axis_root.toLowerCase() !== axis.axis_merkle_root.toLowerCase()) {
117
+ return { valid: false, reason: 'MERKLE_ROOT_MISMATCH', detail: `axes.${tag}.axis_root mismatch` };
118
+ }
119
+ if (axisBody.leaf_index < 0 || axisBody.leaf_index >= axis.contributors.length) {
120
+ return { valid: false, reason: 'MALFORMED', detail: `axes.${tag}.leaf_index out of range` };
121
+ }
122
+ const row = axis.contributors[axisBody.leaf_index];
123
+ if (row.contributor_did !== response.contributor_did) {
124
+ return {
125
+ valid: false,
126
+ reason: 'MERKLE_ROOT_MISMATCH',
127
+ detail: `axes.${tag}.leaf_index points to a different DID`,
128
+ };
129
+ }
130
+ if (row.total_weight !== axisBody.total_weight) {
131
+ return { valid: false, reason: 'MALFORMED', detail: `axes.${tag}.total_weight claim mismatch` };
132
+ }
133
+ if (row.contribution_count !== axisBody.contribution_count) {
134
+ return {
135
+ valid: false,
136
+ reason: 'MALFORMED',
137
+ detail: `axes.${tag}.contribution_count claim mismatch`,
138
+ };
139
+ }
140
+ const leaf = Buffer.from(row.merkle_leaf_hash, 'hex');
141
+ if (!verifyMerklePath(leaf, axisBody.leaf_index, axisBody.merkle_path, axisBody.axis_root)) {
142
+ return { valid: false, reason: 'MERKLE_ROOT_MISMATCH', detail: `axes.${tag} merkle_path does not reconstruct axis_root` };
143
+ }
144
+ }
145
+ return { valid: true };
146
+ }
147
+ //# sourceMappingURL=contributor-query.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contributor-query.js","sourceRoot":"","sources":["../../../../src/v2/attribution-settlement/contributor-query.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ export type { SettlementAxisIndex, SettlementContributor, SettlementPeriod, SettlementRecord, SettlementResidualBucket, SettlementVerifyReason, SettlementVerifyResult, ContributorQueryAxisBody, ContributorQueryResponse, } from './types.js';
2
+ export { aggregateAttributionPrimitives, contributorLeafHashHex, formatSettlementWeight, residualLeafHashHex, } from './aggregate.js';
3
+ export type { AggregateOptions } from './aggregate.js';
4
+ export { buildContributorMerklePath, buildMerkleRoot, emptyAxisMerkleRoot, leafHash as settlementLeafHash, verifyMerklePath, } from './merkle.js';
5
+ export { settlementRecordHash, settlementSigningPayload, signSettlementRecord, verifySettlementSignature, } from './sign.js';
6
+ export { verifySettlementRecord } from './verify.js';
7
+ export type { VerifySettlementOptions } from './verify.js';
8
+ export { buildContributorQueryResponse, verifyContributorQueryResponse, } from './contributor-query.js';
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/v2/attribution-settlement/index.ts"],"names":[],"mappings":"AASA,YAAY,EACV,mBAAmB,EACnB,qBAAqB,EACrB,gBAAgB,EAChB,gBAAgB,EAChB,wBAAwB,EACxB,sBAAsB,EACtB,sBAAsB,EACtB,wBAAwB,EACxB,wBAAwB,GACzB,MAAM,YAAY,CAAA;AAEnB,OAAO,EACL,8BAA8B,EAC9B,sBAAsB,EACtB,sBAAsB,EACtB,mBAAmB,GACpB,MAAM,gBAAgB,CAAA;AACvB,YAAY,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AAEtD,OAAO,EACL,0BAA0B,EAC1B,eAAe,EACf,mBAAmB,EACnB,QAAQ,IAAI,kBAAkB,EAC9B,gBAAgB,GACjB,MAAM,aAAa,CAAA;AAEpB,OAAO,EACL,oBAAoB,EACpB,wBAAwB,EACxB,oBAAoB,EACpB,yBAAyB,GAC1B,MAAM,WAAW,CAAA;AAElB,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAA;AACpD,YAAY,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAA;AAE1D,OAAO,EACL,6BAA6B,EAC7B,8BAA8B,GAC/B,MAAM,wBAAwB,CAAA"}
@@ -0,0 +1,14 @@
1
+ // Copyright 2024-2026 Tymofii Pidlisnyi. Apache-2.0 license. See LICENSE.
2
+ // Attribution Settlement — public surface (Build C).
3
+ //
4
+ // Spec: BUILD-C-SETTLEMENT-PIPELINE.md. Turns a stream of Attribution
5
+ // Primitives over a settlement period into one signed, queryable
6
+ // settlement record. Settlement is evidence, not payment: the economic
7
+ // conversion (weight → currency) stays gateway-private. Reuses Build A
8
+ // canonicalization and Build B weight formats; zero duplicate crypto.
9
+ export { aggregateAttributionPrimitives, contributorLeafHashHex, formatSettlementWeight, residualLeafHashHex, } from './aggregate.js';
10
+ export { buildContributorMerklePath, buildMerkleRoot, emptyAxisMerkleRoot, leafHash as settlementLeafHash, verifyMerklePath, } from './merkle.js';
11
+ export { settlementRecordHash, settlementSigningPayload, signSettlementRecord, verifySettlementSignature, } from './sign.js';
12
+ export { verifySettlementRecord } from './verify.js';
13
+ export { buildContributorQueryResponse, verifyContributorQueryResponse, } from './contributor-query.js';
14
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/v2/attribution-settlement/index.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,qDAAqD;AACrD,EAAE;AACF,sEAAsE;AACtE,iEAAiE;AACjE,uEAAuE;AACvE,uEAAuE;AACvE,sEAAsE;AActE,OAAO,EACL,8BAA8B,EAC9B,sBAAsB,EACtB,sBAAsB,EACtB,mBAAmB,GACpB,MAAM,gBAAgB,CAAA;AAGvB,OAAO,EACL,0BAA0B,EAC1B,eAAe,EACf,mBAAmB,EACnB,QAAQ,IAAI,kBAAkB,EAC9B,gBAAgB,GACjB,MAAM,aAAa,CAAA;AAEpB,OAAO,EACL,oBAAoB,EACpB,wBAAwB,EACxB,oBAAoB,EACpB,yBAAyB,GAC1B,MAAM,WAAW,CAAA;AAElB,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAA;AAGpD,OAAO,EACL,6BAA6B,EAC7B,8BAA8B,GAC/B,MAAM,wBAAwB,CAAA"}
@@ -0,0 +1,20 @@
1
+ /** sha256(canonicalize(obj)) as raw 32 bytes. */
2
+ export declare function leafHash(obj: unknown): Buffer;
3
+ /** Build a balanced binary Merkle tree over arbitrary leaf hashes and
4
+ * return the root as raw bytes. Odd levels duplicate the trailing node
5
+ * (the standard fold convention). Throws on empty input — the caller is
6
+ * responsible for using the empty-axis convention in that case. */
7
+ export declare function buildMerkleRoot(leaves: Buffer[]): Buffer;
8
+ /** Returns the sibling hashes (bottom-up) required to reconstruct the
9
+ * root from `leaves[targetIndex]`. The returned hex strings are 32-byte
10
+ * sha256 digests. Verification also needs the leaf index so the
11
+ * verifier knows which side of each hashNode the sibling sits on —
12
+ * {@link verifyMerklePath} takes that argument. */
13
+ export declare function buildContributorMerklePath(leaves: Buffer[], targetIndex: number): string[];
14
+ /** Reconstruct the Merkle root from (leaf, leafIndex, path) and compare
15
+ * against `expectedRootHex`. Returns a boolean. Hex comparison is done
16
+ * lowercase-insensitively. */
17
+ export declare function verifyMerklePath(leaf: Buffer, leafIndex: number, path: string[], expectedRootHex: string): boolean;
18
+ /** Convenience: the canonical empty-axis merkle root (I-C5). */
19
+ export declare function emptyAxisMerkleRoot(): string;
20
+ //# sourceMappingURL=merkle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"merkle.d.ts","sourceRoot":"","sources":["../../../../src/v2/attribution-settlement/merkle.ts"],"names":[],"mappings":"AAsBA,iDAAiD;AACjD,wBAAgB,QAAQ,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAE7C;AAED;;;oEAGoE;AACpE,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,CAexD;AAED;;;;oDAIoD;AACpD,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,MAAM,EAAE,EAChB,WAAW,EAAE,MAAM,GAClB,MAAM,EAAE,CA2BV;AAED;;+BAE+B;AAC/B,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EAAE,EACd,eAAe,EAAE,MAAM,GACtB,OAAO,CAaT;AAED,gEAAgE;AAChE,wBAAgB,mBAAmB,IAAI,MAAM,CAE5C"}