agent-passport-system 3.0.0 → 3.2.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 (168) hide show
  1. package/README.md +7 -4
  2. package/dist/src/adapters/governance-hook.d.ts.map +1 -1
  3. package/dist/src/adapters/ibac-cedar.d.ts.map +1 -1
  4. package/dist/src/adapters/ibac-cedar.js +22 -4
  5. package/dist/src/adapters/ibac-cedar.js.map +1 -1
  6. package/dist/src/adapters/langchain.d.ts +1 -1
  7. package/dist/src/adapters/langchain.d.ts.map +1 -1
  8. package/dist/src/adapters/mcp.d.ts.map +1 -1
  9. package/dist/src/adapters/oauth-id-jag/index.js.map +1 -1
  10. package/dist/src/adapters/oauth-id-jag/types.d.ts.map +1 -1
  11. package/dist/src/adapters/oauth-id-jag/types.js.map +1 -1
  12. package/dist/src/adapters/oauth-rfc8693/types.d.ts +7 -7
  13. package/dist/src/adapters/oauth-rfc8693/types.d.ts.map +1 -1
  14. package/dist/src/adapters/remote-signer/handle-signer.d.ts.map +1 -1
  15. package/dist/src/adapters/remote-signer/local-signer.d.ts.map +1 -1
  16. package/dist/src/adapters/remote-signer/types.d.ts.map +1 -1
  17. package/dist/src/cli/index.js +12 -5
  18. package/dist/src/cli/index.js.map +1 -1
  19. package/dist/src/core/anchor-state.js.map +1 -1
  20. package/dist/src/core/aps-txt.js.map +1 -1
  21. package/dist/src/core/attestation.js.map +1 -1
  22. package/dist/src/core/canonical-jcs.js.map +1 -1
  23. package/dist/src/core/commerce.d.ts +1 -1
  24. package/dist/src/core/commerce.d.ts.map +1 -1
  25. package/dist/src/core/context.d.ts.map +1 -1
  26. package/dist/src/core/cross-chain.js.map +1 -1
  27. package/dist/src/core/data-enforcement.d.ts.map +1 -1
  28. package/dist/src/core/data-gateway.d.ts.map +1 -1
  29. package/dist/src/core/data-lifecycle.js.map +1 -1
  30. package/dist/src/core/data-source-attribution.js.map +1 -1
  31. package/dist/src/core/did-interop.d.ts.map +1 -1
  32. package/dist/src/core/did-interop.js +63 -0
  33. package/dist/src/core/did-interop.js.map +1 -1
  34. package/dist/src/core/execution-attestation.js.map +1 -1
  35. package/dist/src/core/gateway.d.ts.map +1 -1
  36. package/dist/src/core/governance.js.map +1 -1
  37. package/dist/src/core/obligations.js.map +1 -1
  38. package/dist/src/core/passport.js.map +1 -1
  39. package/dist/src/core/policy.d.ts.map +1 -1
  40. package/dist/src/core/principal.js.map +1 -1
  41. package/dist/src/core/reputation-authority.js.map +1 -1
  42. package/dist/src/core/time.js.map +1 -1
  43. package/dist/src/core/values.js.map +1 -1
  44. package/dist/src/crypto/key-storage.d.ts.map +1 -1
  45. package/dist/src/crypto/keys.js +1 -1
  46. package/dist/src/crypto/keys.js.map +1 -1
  47. package/dist/src/decisionReceipt.d.ts +3 -3
  48. package/dist/src/errors/identity-composition-error.d.ts.map +1 -1
  49. package/dist/src/errors/identity-composition-error.js.map +1 -1
  50. package/dist/src/interop/qntm-bridge.d.ts.map +1 -1
  51. package/dist/src/interop/qntm-bridge.js +36 -4
  52. package/dist/src/interop/qntm-bridge.js.map +1 -1
  53. package/dist/src/storage/volatile-backend.d.ts.map +1 -1
  54. package/dist/src/v2/accountability/__tests__/bundle.test.js.map +1 -1
  55. package/dist/src/v2/accountability/__tests__/contestability.test.js.map +1 -1
  56. package/dist/src/v2/accountability/__tests__/custody.test.js.map +1 -1
  57. package/dist/src/v2/accountability/__tests__/fixtures.test.js.map +1 -1
  58. package/dist/src/v2/assurance/descriptor.js.map +1 -1
  59. package/dist/src/v2/attribution-primitive/canonical.js.map +1 -1
  60. package/dist/src/v2/attribution-primitive/merkle.js.map +1 -1
  61. package/dist/src/v2/attribution-primitive/residual.js.map +1 -1
  62. package/dist/src/v2/attribution-weights/compute-axis.js.map +1 -1
  63. package/dist/src/v2/audience-binding/types.d.ts +1 -1
  64. package/dist/src/v2/bridge.js.map +1 -1
  65. package/dist/src/v2/claim-evidence-types.d.ts +5 -5
  66. package/dist/src/v2/claim-evidence-types.d.ts.map +1 -1
  67. package/dist/src/v2/composition-check/types.d.ts +2 -2
  68. package/dist/src/v2/context-provenance/__tests__/cross-lang-parity.test.js.map +1 -1
  69. package/dist/src/v2/context-provenance/vectors/generate-vectors.js.map +1 -1
  70. package/dist/src/v2/cross_issuer_attestation/__tests__/cross_issuer_attestation.test.js.map +1 -1
  71. package/dist/src/v2/delegation-v2.js.map +1 -1
  72. package/dist/src/v2/feasibility/__tests__/feasibility.test.js.map +1 -1
  73. package/dist/src/v2/feasibility/compiler.js.map +1 -1
  74. package/dist/src/v2/hash-pointer/profile.js.map +1 -1
  75. package/dist/src/v2/hash-pointer/types.d.ts +1 -1
  76. package/dist/src/v2/human-escalation.js.map +1 -1
  77. package/dist/src/v2/instruction-provenance/canonicalize.d.ts.map +1 -1
  78. package/dist/src/v2/instruction-provenance/canonicalize.js.map +1 -1
  79. package/dist/src/v2/instruction-provenance/envelope.d.ts.map +1 -1
  80. package/dist/src/v2/instruction-provenance/envelope.js.map +1 -1
  81. package/dist/src/v2/key-resolution/resolver.d.ts.map +1 -1
  82. package/dist/src/v2/key-resolution/resolver.js.map +1 -1
  83. package/dist/src/v2/memory_provenance/__tests__/memory_provenance.test.js.map +1 -1
  84. package/dist/src/v2/mutual-auth/certificate.js.map +1 -1
  85. package/dist/src/v2/offline-verifier/middleware.js.map +1 -1
  86. package/dist/src/v2/offline-verifier/verify.js.map +1 -1
  87. package/dist/src/v2/outcome-v2.js.map +1 -1
  88. package/dist/src/v2/payment-rails/acp/index.js.map +1 -1
  89. package/dist/src/v2/payment-rails/acp/types.d.ts +1 -1
  90. package/dist/src/v2/payment-rails/ap2/fixtures/_generate.js.map +1 -1
  91. package/dist/src/v2/payment-rails/ap2/index.js.map +1 -1
  92. package/dist/src/v2/payment-rails/conformance/binding-harness.js.map +1 -1
  93. package/dist/src/v2/payment-rails/conformance/fixtures/_generate.js.map +1 -1
  94. package/dist/src/v2/payment-rails/conformance/harness.js.map +1 -1
  95. package/dist/src/v2/payment-rails/cycles/evidence-resolution.js.map +1 -1
  96. package/dist/src/v2/payment-rails/cycles/index.js.map +1 -1
  97. package/dist/src/v2/payment-rails/cycles/types.d.ts +5 -5
  98. package/dist/src/v2/payment-rails/fixtures/_generate.js.map +1 -1
  99. package/dist/src/v2/payment-rails/hooks.js.map +1 -1
  100. package/dist/src/v2/payment-rails/mpp/index.js.map +1 -1
  101. package/dist/src/v2/payment-rails/mpp/types.d.ts +1 -1
  102. package/dist/src/v2/payment-rails/nano.d.ts.map +1 -1
  103. package/dist/src/v2/payment-rails/scope-resolution.js.map +1 -1
  104. package/dist/src/v2/payment-rails/stripe-issuing/fixtures/_generate-cross-rail.js.map +1 -1
  105. package/dist/src/v2/payment-rails/stripe-issuing/fixtures/_generate.js.map +1 -1
  106. package/dist/src/v2/payment-rails/stripe-issuing/primitives.js.map +1 -1
  107. package/dist/src/v2/payment-rails/x402/fixtures/_generate.js.map +1 -1
  108. package/dist/src/v2/payment-rails/x402/index.d.ts.map +1 -1
  109. package/dist/src/v2/policy-bundle/bundle.js.map +1 -1
  110. package/dist/src/v2/provisional-statement/promote.js.map +1 -1
  111. package/dist/src/v2/read_fidelity_receipt/__tests__/read_fidelity_receipt.test.d.ts +2 -0
  112. package/dist/src/v2/read_fidelity_receipt/__tests__/read_fidelity_receipt.test.d.ts.map +1 -0
  113. package/dist/src/v2/read_fidelity_receipt/__tests__/read_fidelity_receipt.test.js +392 -0
  114. package/dist/src/v2/read_fidelity_receipt/__tests__/read_fidelity_receipt.test.js.map +1 -0
  115. package/dist/src/v2/read_fidelity_receipt/index.d.ts +4 -0
  116. package/dist/src/v2/read_fidelity_receipt/index.d.ts.map +1 -0
  117. package/dist/src/v2/read_fidelity_receipt/index.js +16 -0
  118. package/dist/src/v2/read_fidelity_receipt/index.js.map +1 -0
  119. package/dist/src/v2/read_fidelity_receipt/receipt.d.ts +45 -0
  120. package/dist/src/v2/read_fidelity_receipt/receipt.d.ts.map +1 -0
  121. package/dist/src/v2/read_fidelity_receipt/receipt.js +283 -0
  122. package/dist/src/v2/read_fidelity_receipt/receipt.js.map +1 -0
  123. package/dist/src/v2/read_fidelity_receipt/sampler.d.ts +35 -0
  124. package/dist/src/v2/read_fidelity_receipt/sampler.d.ts.map +1 -0
  125. package/dist/src/v2/read_fidelity_receipt/sampler.js +110 -0
  126. package/dist/src/v2/read_fidelity_receipt/sampler.js.map +1 -0
  127. package/dist/src/v2/read_fidelity_receipt/types.d.ts +139 -0
  128. package/dist/src/v2/read_fidelity_receipt/types.d.ts.map +1 -0
  129. package/dist/src/v2/read_fidelity_receipt/types.js +17 -0
  130. package/dist/src/v2/read_fidelity_receipt/types.js.map +1 -0
  131. package/dist/src/v2/read_fidelity_receipt/vectors/generate.d.ts +2 -0
  132. package/dist/src/v2/read_fidelity_receipt/vectors/generate.d.ts.map +1 -0
  133. package/dist/src/v2/read_fidelity_receipt/vectors/generate.js +261 -0
  134. package/dist/src/v2/read_fidelity_receipt/vectors/generate.js.map +1 -0
  135. package/dist/src/v2/regulated-action/types.d.ts +7 -7
  136. package/dist/src/v2/regulated-action/types.d.ts.map +1 -1
  137. package/dist/src/v2/scope-registry/registry.js.map +1 -1
  138. package/dist/src/v2/semantic-scoping.js.map +1 -1
  139. package/dist/src/v2/transport/rfc9421/profile.d.ts +1 -1
  140. package/dist/src/v2/transport/rfc9421/profile.d.ts.map +1 -1
  141. package/dist/src/v2/transport/rfc9421/signature-base.js.map +1 -1
  142. package/dist/src/v2/trust-policy/types.d.ts +1 -1
  143. package/dist/src/v2/trust-policy/well-known.d.ts +2 -2
  144. package/dist/src/v2/verifier-hardening/index.d.ts.map +1 -1
  145. package/dist/src/v2/word_handles/__tests__/word_handles.test.d.ts +2 -0
  146. package/dist/src/v2/word_handles/__tests__/word_handles.test.d.ts.map +1 -0
  147. package/dist/src/v2/word_handles/__tests__/word_handles.test.js +312 -0
  148. package/dist/src/v2/word_handles/__tests__/word_handles.test.js.map +1 -0
  149. package/dist/src/v2/word_handles/codec.d.ts +54 -0
  150. package/dist/src/v2/word_handles/codec.d.ts.map +1 -0
  151. package/dist/src/v2/word_handles/codec.js +334 -0
  152. package/dist/src/v2/word_handles/codec.js.map +1 -0
  153. package/dist/src/v2/word_handles/index.d.ts +4 -0
  154. package/dist/src/v2/word_handles/index.d.ts.map +1 -0
  155. package/dist/src/v2/word_handles/index.js +13 -0
  156. package/dist/src/v2/word_handles/index.js.map +1 -0
  157. package/dist/src/v2/word_handles/lexicon.d.ts +7 -0
  158. package/dist/src/v2/word_handles/lexicon.d.ts.map +1 -0
  159. package/dist/src/v2/word_handles/lexicon.js +276 -0
  160. package/dist/src/v2/word_handles/lexicon.js.map +1 -0
  161. package/dist/src/v2/word_handles/types.d.ts +58 -0
  162. package/dist/src/v2/word_handles/types.d.ts.map +1 -0
  163. package/dist/src/v2/word_handles/types.js +13 -0
  164. package/dist/src/v2/word_handles/types.js.map +1 -0
  165. package/dist/src/verification/verify.d.ts.map +1 -1
  166. package/dist/src/verification/verify.js +6 -1
  167. package/dist/src/verification/verify.js.map +1 -1
  168. package/package.json +11 -12
@@ -0,0 +1,283 @@
1
+ // Copyright 2024-2026 Tymofii Pidlisnyi. Apache-2.0 license. See LICENSE.
2
+ // ══════════════════════════════════════════════════════════════════
3
+ // read_fidelity_receipt (v2): create and verify
4
+ // ══════════════════════════════════════════════════════════════════
5
+ // Signature convention: sig is EXCLUDED from the signing preimage.
6
+ // The preimage is canonicalizeJCS(record with the sig key removed
7
+ // entirely). Verification order: shape checks and n consistency,
8
+ // then the Ed25519 signature against the embedded attester, then the
9
+ // seed derivation. A record tampered after signing fails on the
10
+ // signature; a record re-signed after a nonce or presentation swap
11
+ // carries a valid signature and fails on the seed derivation, which
12
+ // is the replay binding doing its job.
13
+ // ══════════════════════════════════════════════════════════════════
14
+ import { createHash } from 'node:crypto';
15
+ import { canonicalizeJCS } from '../../core/canonical-jcs.js';
16
+ import { sign, verify as edVerify, publicKeyFromPrivate } from '../../crypto/keys.js';
17
+ import { commitSpans, deriveSeed, sampleSpans, scoreResponses } from './sampler.js';
18
+ const DIGEST_RE = /^sha256:[0-9a-f]{64}$/;
19
+ const HEX64_RE = /^[0-9a-f]{64}$/;
20
+ const HEX128_RE = /^[0-9a-f]{128}$/;
21
+ const ISO_8601_RE = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{1,9})?(?:Z|[+-]\d{2}:\d{2})$/;
22
+ function sha256hex(input) {
23
+ return createHash('sha256').update(input, 'utf8').digest('hex');
24
+ }
25
+ /**
26
+ * Canonical signing preimage: RFC 8785 JCS of the record with the
27
+ * `sig` key removed entirely. Accepts a signed record (sig dropped)
28
+ * or an unsigned draft (no sig key present).
29
+ */
30
+ export function canonicalNoSig(record) {
31
+ const { sig: _sig, ...rest } = record;
32
+ return canonicalizeJCS(rest);
33
+ }
34
+ /**
35
+ * Structural checks shared by verifyReadFidelityReceipt and
36
+ * verifyAgainstSource. Returns the first failing reason, or null when
37
+ * the value is structurally a ReadFidelityReceipt. Does NOT check the
38
+ * signature or the seed derivation.
39
+ */
40
+ function shapeReason(value) {
41
+ if (typeof value !== 'object' || value === null || Array.isArray(value)) {
42
+ return 'INVALID_TYPE';
43
+ }
44
+ const r = value;
45
+ if (r.type !== 'read_fidelity_receipt')
46
+ return 'INVALID_TYPE';
47
+ if (typeof r.content_digest !== 'string' || !DIGEST_RE.test(r.content_digest)) {
48
+ return 'INVALID_CONTENT_DIGEST';
49
+ }
50
+ if (r.presentation_digest !== null &&
51
+ (typeof r.presentation_digest !== 'string' ||
52
+ !DIGEST_RE.test(r.presentation_digest))) {
53
+ return 'INVALID_PRESENTATION_DIGEST';
54
+ }
55
+ const challengeReason = challengeShapeReason(r.challenge);
56
+ if (challengeReason !== null)
57
+ return challengeReason;
58
+ const c = r.challenge;
59
+ const commitments = c.span_commitments;
60
+ if (typeof r.n !== 'number' || !Number.isInteger(r.n) || r.n < 1) {
61
+ return 'INVALID_N';
62
+ }
63
+ if (r.n !== commitments.length)
64
+ return 'N_MISMATCH';
65
+ if (typeof r.k !== 'number' ||
66
+ !Number.isInteger(r.k) ||
67
+ r.k < 0 ||
68
+ r.k > r.n) {
69
+ return 'INVALID_K';
70
+ }
71
+ if (typeof r.response_digest !== 'string' || !DIGEST_RE.test(r.response_digest)) {
72
+ return 'INVALID_RESPONSE_DIGEST';
73
+ }
74
+ if (r.scoring_method !== 'exact_match_v1')
75
+ return 'INVALID_SCORING_METHOD';
76
+ if (typeof r.attester !== 'string' || !HEX64_RE.test(r.attester)) {
77
+ return 'INVALID_ATTESTER';
78
+ }
79
+ if (typeof r.model_claim !== 'string' || typeof r.runtime_claim !== 'string') {
80
+ return 'INVALID_CLAIMS';
81
+ }
82
+ if (r.verification_method !== 'asserted' &&
83
+ r.verification_method !== 'provider_attestation') {
84
+ return 'INVALID_VERIFICATION_METHOD';
85
+ }
86
+ for (const field of [
87
+ 'challenge_issued_at',
88
+ 'response_observed_at',
89
+ 'receipt_issued_at',
90
+ ]) {
91
+ const t = r[field];
92
+ if (typeof t !== 'string' || !ISO_8601_RE.test(t))
93
+ return 'INVALID_TIMESTAMP';
94
+ }
95
+ if ('lexicon_id' in r || 'lexicon_profile' in r) {
96
+ if (typeof r.lexicon_id !== 'string' || !DIGEST_RE.test(r.lexicon_id)) {
97
+ return 'INVALID_LEXICON_FIELDS';
98
+ }
99
+ if ('lexicon_profile' in r &&
100
+ (typeof r.lexicon_profile !== 'string' || r.lexicon_profile.length === 0)) {
101
+ return 'INVALID_LEXICON_FIELDS';
102
+ }
103
+ }
104
+ if (typeof r.sig !== 'string' || !HEX128_RE.test(r.sig)) {
105
+ return 'INVALID_SIG_FORMAT';
106
+ }
107
+ return null;
108
+ }
109
+ function challengeShapeReason(value) {
110
+ if (typeof value !== 'object' || value === null || Array.isArray(value)) {
111
+ return 'INVALID_CHALLENGE';
112
+ }
113
+ const c = value;
114
+ if (typeof c.nonce !== 'string' || c.nonce.length === 0)
115
+ return 'INVALID_CHALLENGE';
116
+ if (typeof c.seed !== 'string' || !HEX64_RE.test(c.seed))
117
+ return 'INVALID_CHALLENGE';
118
+ if (c.algorithm !== 'span_sample_v1')
119
+ return 'INVALID_CHALLENGE';
120
+ if (c.version !== '1')
121
+ return 'INVALID_CHALLENGE';
122
+ if (typeof c.span_len !== 'number' ||
123
+ !Number.isInteger(c.span_len) ||
124
+ c.span_len < 1) {
125
+ return 'INVALID_CHALLENGE';
126
+ }
127
+ if (!Array.isArray(c.span_commitments) || c.span_commitments.length === 0) {
128
+ return 'INVALID_CHALLENGE';
129
+ }
130
+ for (const s of c.span_commitments) {
131
+ if (typeof s !== 'string' || !DIGEST_RE.test(s))
132
+ return 'INVALID_CHALLENGE';
133
+ }
134
+ return null;
135
+ }
136
+ function seedMatches(record) {
137
+ return (record.challenge.seed ===
138
+ deriveSeed(record.content_digest, record.presentation_digest, record.challenge.nonce, record.challenge.version));
139
+ }
140
+ /**
141
+ * Build and sign a read fidelity receipt. Validates the input
142
+ * (n MUST equal challenge.span_commitments.length, challenge.seed MUST
143
+ * equal the seed derivation, every digest MUST be
144
+ * "sha256:<64 lowercase hex>", timestamps MUST be ISO 8601), sets
145
+ * `attester` from the private key, and signs the JCS canonical form of
146
+ * the record with the sig key excluded. Throws on any validation
147
+ * failure; nothing is signed unless the record is internally
148
+ * consistent.
149
+ */
150
+ export function createReadFidelityReceipt(fields, privateKeyHex) {
151
+ const attester = publicKeyFromPrivate(privateKeyHex);
152
+ const draft = {
153
+ type: 'read_fidelity_receipt',
154
+ content_digest: fields.content_digest,
155
+ presentation_digest: fields.presentation_digest,
156
+ challenge: {
157
+ nonce: fields.challenge.nonce,
158
+ seed: fields.challenge.seed,
159
+ algorithm: fields.challenge.algorithm,
160
+ version: fields.challenge.version,
161
+ span_len: fields.challenge.span_len,
162
+ span_commitments: [...fields.challenge.span_commitments],
163
+ },
164
+ response_digest: fields.response_digest,
165
+ k: fields.k,
166
+ n: fields.n,
167
+ scoring_method: fields.scoring_method,
168
+ attester,
169
+ model_claim: fields.model_claim,
170
+ runtime_claim: fields.runtime_claim,
171
+ verification_method: fields.verification_method,
172
+ challenge_issued_at: fields.challenge_issued_at,
173
+ response_observed_at: fields.response_observed_at,
174
+ receipt_issued_at: fields.receipt_issued_at,
175
+ ...(fields.lexicon_id !== undefined ? { lexicon_id: fields.lexicon_id } : {}),
176
+ ...(fields.lexicon_profile !== undefined
177
+ ? { lexicon_profile: fields.lexicon_profile }
178
+ : {}),
179
+ };
180
+ if (fields.n !== fields.challenge.span_commitments.length) {
181
+ throw new Error(`n (${fields.n}) must equal challenge.span_commitments.length ` +
182
+ `(${fields.challenge.span_commitments.length})`);
183
+ }
184
+ // Full structural validation on the draft plus a placeholder sig so
185
+ // create and verify enforce the identical shape rules.
186
+ const reason = shapeReason({ ...draft, sig: '0'.repeat(128) });
187
+ if (reason !== null) {
188
+ throw new Error(`invalid read fidelity receipt input: ${reason}`);
189
+ }
190
+ const expectedSeed = deriveSeed(fields.content_digest, fields.presentation_digest, fields.challenge.nonce, fields.challenge.version);
191
+ if (fields.challenge.seed !== expectedSeed) {
192
+ throw new Error('challenge.seed does not match the seed derivation over ' +
193
+ 'content_digest, presentation_digest, nonce, and version');
194
+ }
195
+ const sig = sign(canonicalNoSig(draft), privateKeyHex);
196
+ return { ...draft, sig };
197
+ }
198
+ /**
199
+ * Verify a read fidelity receipt: shape checks, n consistency against
200
+ * challenge.span_commitments, Ed25519 signature against the embedded
201
+ * attester, and the seed derivation recompute. Accepts unknown and
202
+ * never throws on malformed input; failures carry a reason code.
203
+ */
204
+ export function verifyReadFidelityReceipt(record) {
205
+ const reason = shapeReason(record);
206
+ if (reason !== null)
207
+ return { valid: false, reason };
208
+ const r = record;
209
+ if (!edVerify(canonicalNoSig(r), r.sig, r.attester)) {
210
+ return { valid: false, reason: 'SIGNATURE_INVALID' };
211
+ }
212
+ if (!seedMatches(r)) {
213
+ return { valid: false, reason: 'SEED_MISMATCH' };
214
+ }
215
+ return { valid: true };
216
+ }
217
+ /**
218
+ * Verify a receipt against the source text it claims to sample:
219
+ * everything verifyReadFidelityReceipt checks, plus a recompute of the
220
+ * spans from challenge.seed / n / span_len over `sourceText`, a sha256
221
+ * commitment of each recomputed span, and a positionwise comparison
222
+ * against challenge.span_commitments. ALL commitments must match.
223
+ * `signature_valid` and `seed_valid` are reported independently.
224
+ */
225
+ export function verifyAgainstSource(record, sourceText) {
226
+ const reason = shapeReason(record);
227
+ if (reason !== null) {
228
+ return {
229
+ valid: false,
230
+ reason,
231
+ commitment_matches: [],
232
+ signature_valid: false,
233
+ seed_valid: false,
234
+ };
235
+ }
236
+ const r = record;
237
+ const signature_valid = edVerify(canonicalNoSig(r), r.sig, r.attester);
238
+ const seed_valid = seedMatches(r);
239
+ let commitment_matches = [];
240
+ let spanReason = null;
241
+ try {
242
+ const spans = sampleSpans(sourceText, r.challenge.seed, r.n, r.challenge.span_len);
243
+ const recomputed = commitSpans(spans.map((s) => s.text));
244
+ commitment_matches = recomputed.map((c, i) => c === r.challenge.span_commitments[i]);
245
+ }
246
+ catch {
247
+ spanReason = 'SPAN_RECOMPUTE_FAILED';
248
+ }
249
+ const allMatch = spanReason === null && commitment_matches.every((m) => m === true);
250
+ const valid = signature_valid && seed_valid && allMatch;
251
+ let failure;
252
+ if (!signature_valid)
253
+ failure = 'SIGNATURE_INVALID';
254
+ else if (!seed_valid)
255
+ failure = 'SEED_MISMATCH';
256
+ else if (spanReason !== null)
257
+ failure = spanReason;
258
+ else if (!allMatch)
259
+ failure = 'COMMITMENT_MISMATCH';
260
+ return valid
261
+ ? { valid, commitment_matches, signature_valid, seed_valid }
262
+ : { valid, reason: failure, commitment_matches, signature_valid, seed_valid };
263
+ }
264
+ /**
265
+ * Recompute k for a set of readback responses against the source text:
266
+ * resample the spans the record commits to, score `responses` under
267
+ * exact_match_v1, and compare the recomputed k with the recorded k and
268
+ * the responses JCS digest with the recorded response_digest. Throws
269
+ * when the source cannot produce the spans (wrong length) or when
270
+ * `responses` has the wrong length; use verifyAgainstSource first to
271
+ * establish that the record matches the source at all.
272
+ */
273
+ export function verifyResponses(record, sourceText, responses) {
274
+ const spans = sampleSpans(sourceText, record.challenge.seed, record.n, record.challenge.span_len);
275
+ const { k } = scoreResponses(spans.map((s) => s.text), responses);
276
+ const digest = `sha256:${sha256hex(canonicalizeJCS(responses))}`;
277
+ return {
278
+ k_recomputed: k,
279
+ matches_claimed_k: k === record.k,
280
+ response_digest_ok: digest === record.response_digest,
281
+ };
282
+ }
283
+ //# sourceMappingURL=receipt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"receipt.js","sourceRoot":"","sources":["../../../../src/v2/read_fidelity_receipt/receipt.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ import type { SampledSpan, ScoreResponsesResult } from './types.js';
2
+ /**
3
+ * Derive the challenge seed. The preimage is the RFC 8785 JCS
4
+ * canonicalization of an object carrying the four bound fields, so the
5
+ * component boundaries are unambiguous: presentation_digest is a
6
+ * distinct JSON member (null when absent), never foldable into the
7
+ * nonce. An earlier concatenation preimage let a null-presentation
8
+ * record with nonce = P || N derive the same seed as a P-presentation
9
+ * record with nonce N; the structured preimage closes that.
10
+ */
11
+ export declare function deriveSeed(contentDigest: string, presentationDigestOrNull: string | null, nonce: string, version: string): string;
12
+ /**
13
+ * Sample `n` spans of `spanLen` code points from `sourceText` at
14
+ * distinct positions determined by `seed` (algorithm span_sample_v1).
15
+ *
16
+ * The source is split into code points via Array.from, so astral
17
+ * characters (emoji) count as one position each and spans never split
18
+ * a surrogate pair. With L code points the position range is
19
+ * L - spanLen + 1. Throws when spanLen or n is not a positive integer,
20
+ * when the source is shorter than spanLen code points, or when n
21
+ * exceeds the position range.
22
+ */
23
+ export declare function sampleSpans(sourceText: string, seed: string, n: number, spanLen: number): SampledSpan[];
24
+ /**
25
+ * Commit to span texts: "sha256:" + sha256hex(UTF-8 of each span
26
+ * text), in the given (sampling) order.
27
+ */
28
+ export declare function commitSpans(spanTexts: readonly string[]): string[];
29
+ /**
30
+ * Score responses against span texts under exact_match_v1: exact
31
+ * string equality per index. Throws when the arrays differ in length;
32
+ * a missing response is a protocol error, not a miss.
33
+ */
34
+ export declare function scoreResponses(spanTexts: readonly string[], responses: readonly string[]): ScoreResponsesResult;
35
+ //# sourceMappingURL=sampler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sampler.d.ts","sourceRoot":"","sources":["../../../../src/v2/read_fidelity_receipt/sampler.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,WAAW,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAA;AAMnE;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CACxB,aAAa,EAAE,MAAM,EACrB,wBAAwB,EAAE,MAAM,GAAG,IAAI,EACvC,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,GACd,MAAM,CASR;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,WAAW,CACzB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,EACZ,CAAC,EAAE,MAAM,EACT,OAAO,EAAE,MAAM,GACd,WAAW,EAAE,CAqCf;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,EAAE,CAElE;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAC5B,SAAS,EAAE,SAAS,MAAM,EAAE,EAC5B,SAAS,EAAE,SAAS,MAAM,EAAE,GAC3B,oBAAoB,CAYtB"}
@@ -0,0 +1,110 @@
1
+ // Copyright 2024-2026 Tymofii Pidlisnyi. Apache-2.0 license. See LICENSE.
2
+ // ══════════════════════════════════════════════════════════════════
3
+ // read_fidelity_receipt (v2): seed derivation, span sampler, scoring
4
+ // ══════════════════════════════════════════════════════════════════
5
+ // Deterministic, pure functions: no I/O, no clock, no randomness.
6
+ // Bit-exact across languages:
7
+ // seed = sha256hex(utf8( canonicalizeJCS({
8
+ // content_digest, presentation_digest (null when absent),
9
+ // nonce, version }) )) (RFC 8785 JCS preimage)
10
+ // position i, attempt j:
11
+ // h = sha256(utf8(seed + ":" + i + ":" + j))
12
+ // pos = BE-uint64(first 8 bytes of h) mod range
13
+ // bump j on repeat until the position is unused
14
+ // span text = code points [pos, pos + spanLen), Array.from slicing.
15
+ // ══════════════════════════════════════════════════════════════════
16
+ import { createHash } from 'node:crypto';
17
+ import { canonicalizeJCS } from '../../core/canonical-jcs.js';
18
+ function sha256hex(input) {
19
+ return createHash('sha256').update(input, 'utf8').digest('hex');
20
+ }
21
+ /**
22
+ * Derive the challenge seed. The preimage is the RFC 8785 JCS
23
+ * canonicalization of an object carrying the four bound fields, so the
24
+ * component boundaries are unambiguous: presentation_digest is a
25
+ * distinct JSON member (null when absent), never foldable into the
26
+ * nonce. An earlier concatenation preimage let a null-presentation
27
+ * record with nonce = P || N derive the same seed as a P-presentation
28
+ * record with nonce N; the structured preimage closes that.
29
+ */
30
+ export function deriveSeed(contentDigest, presentationDigestOrNull, nonce, version) {
31
+ return sha256hex(canonicalizeJCS({
32
+ content_digest: contentDigest,
33
+ presentation_digest: presentationDigestOrNull,
34
+ nonce,
35
+ version,
36
+ }));
37
+ }
38
+ /**
39
+ * Sample `n` spans of `spanLen` code points from `sourceText` at
40
+ * distinct positions determined by `seed` (algorithm span_sample_v1).
41
+ *
42
+ * The source is split into code points via Array.from, so astral
43
+ * characters (emoji) count as one position each and spans never split
44
+ * a surrogate pair. With L code points the position range is
45
+ * L - spanLen + 1. Throws when spanLen or n is not a positive integer,
46
+ * when the source is shorter than spanLen code points, or when n
47
+ * exceeds the position range.
48
+ */
49
+ export function sampleSpans(sourceText, seed, n, spanLen) {
50
+ if (!Number.isInteger(spanLen) || spanLen < 1) {
51
+ throw new Error(`spanLen must be a positive integer, got ${spanLen}`);
52
+ }
53
+ if (!Number.isInteger(n) || n < 1) {
54
+ throw new Error(`n must be a positive integer, got ${n}`);
55
+ }
56
+ const cps = Array.from(sourceText);
57
+ const L = cps.length;
58
+ if (L < spanLen) {
59
+ throw new Error(`source has ${L} code points, need at least spanLen ${spanLen}`);
60
+ }
61
+ const range = L - spanLen + 1;
62
+ if (n > range) {
63
+ throw new Error(`n ${n} exceeds the position range ${range}`);
64
+ }
65
+ const used = new Set();
66
+ const spans = [];
67
+ for (let i = 0; i < n; i++) {
68
+ for (let j = 0;; j++) {
69
+ const h = createHash('sha256')
70
+ .update(`${seed}:${i}:${j}`, 'utf8')
71
+ .digest();
72
+ const pos = Number(h.readBigUInt64BE(0) % BigInt(range));
73
+ if (used.has(pos))
74
+ continue;
75
+ used.add(pos);
76
+ spans.push({
77
+ pos,
78
+ len: spanLen,
79
+ text: cps.slice(pos, pos + spanLen).join(''),
80
+ });
81
+ break;
82
+ }
83
+ }
84
+ return spans;
85
+ }
86
+ /**
87
+ * Commit to span texts: "sha256:" + sha256hex(UTF-8 of each span
88
+ * text), in the given (sampling) order.
89
+ */
90
+ export function commitSpans(spanTexts) {
91
+ return spanTexts.map((t) => `sha256:${sha256hex(t)}`);
92
+ }
93
+ /**
94
+ * Score responses against span texts under exact_match_v1: exact
95
+ * string equality per index. Throws when the arrays differ in length;
96
+ * a missing response is a protocol error, not a miss.
97
+ */
98
+ export function scoreResponses(spanTexts, responses) {
99
+ if (spanTexts.length !== responses.length) {
100
+ throw new Error(`responses length ${responses.length} does not match span count ${spanTexts.length}`);
101
+ }
102
+ const results = spanTexts.map((t, i) => responses[i] === t);
103
+ let k = 0;
104
+ for (const r of results) {
105
+ if (r)
106
+ k++;
107
+ }
108
+ return { k, results };
109
+ }
110
+ //# sourceMappingURL=sampler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sampler.js","sourceRoot":"","sources":["../../../../src/v2/read_fidelity_receipt/sampler.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,139 @@
1
+ /** Literal tag for record discrimination at the wire level. */
2
+ export type ReadFidelityReceiptType = 'read_fidelity_receipt';
3
+ /** The v1 sampling algorithm identifier. */
4
+ export type ReadFidelitySamplingAlgorithm = 'span_sample_v1';
5
+ /** The v1 scoring method identifier: exact string equality per span. */
6
+ export type ReadFidelityScoringMethod = 'exact_match_v1';
7
+ /**
8
+ * How the executor claims were checked. `asserted` means the attester
9
+ * simply asserts model_claim and runtime_claim; `provider_attestation`
10
+ * means a provider-level attestation backs them.
11
+ */
12
+ export type ReadFidelityVerificationMethod = 'asserted' | 'provider_attestation';
13
+ /**
14
+ * The challenge block. The nonce is verifier-supplied and never
15
+ * derivable from the document alone. The seed MUST equal
16
+ * sha256hex(utf8( canonicalizeJCS({
17
+ * content_digest, presentation_digest, nonce, version }) ))
18
+ * the RFC 8785 JCS preimage of those four fields (presentation_digest
19
+ * null when absent); verifiers recompute and reject on mismatch, which
20
+ * is the replay binding: reusing commitments under a different nonce,
21
+ * content, or presentation breaks the derivation.
22
+ */
23
+ export interface ReadFidelityChallenge {
24
+ /** Verifier-supplied; never derivable from the document alone. */
25
+ readonly nonce: string;
26
+ /** MUST equal the seed derivation over content, presentation, nonce, version. */
27
+ readonly seed: string;
28
+ readonly algorithm: ReadFidelitySamplingAlgorithm;
29
+ readonly version: '1';
30
+ /** Span length in code points; required to recompute spans. */
31
+ readonly span_len: number;
32
+ /**
33
+ * sha256 of the UTF-8 bytes of each span text, in sampling order,
34
+ * each as "sha256:<64 lowercase hex>". Raw span texts are NOT in
35
+ * the record.
36
+ */
37
+ readonly span_commitments: readonly string[];
38
+ }
39
+ /**
40
+ * A read fidelity receipt proves sampled readback fidelity at the stated n under the declared sampling
41
+ * assumptions. It does not prove every byte was read correctly, does not prove perception or comprehension,
42
+ * does not prove which channel was used, and carries no normative pass threshold: the consumer judges k of n.
43
+ */
44
+ export interface ReadFidelityReceipt {
45
+ readonly type: ReadFidelityReceiptType;
46
+ /** Digest of the canonical content bytes, "sha256:<64 lowercase hex>". */
47
+ readonly content_digest: string;
48
+ /** Digest of the rendered presentation as served, or null. */
49
+ readonly presentation_digest: string | null;
50
+ readonly challenge: ReadFidelityChallenge;
51
+ /**
52
+ * "sha256:" + sha256hex(canonicalizeJCS(responses)) where responses
53
+ * is the ordered array of readback strings.
54
+ */
55
+ readonly response_digest: string;
56
+ /** Count of responses that exactly matched their span text. */
57
+ readonly k: number;
58
+ /** Sample count; MUST equal challenge.span_commitments.length. */
59
+ readonly n: number;
60
+ readonly scoring_method: ReadFidelityScoringMethod;
61
+ /**
62
+ * Ed25519 public key hex of the SIGNING identity. May differ from
63
+ * the executing model; model_claim and runtime_claim are claims
64
+ * about the executor, not proofs.
65
+ */
66
+ readonly attester: string;
67
+ readonly model_claim: string;
68
+ readonly runtime_claim: string;
69
+ readonly verification_method: ReadFidelityVerificationMethod;
70
+ /** ISO 8601, caller-provided; the library never reads a wall clock. */
71
+ readonly challenge_issued_at: string;
72
+ /** ISO 8601, caller-provided; the library never reads a wall clock. */
73
+ readonly response_observed_at: string;
74
+ /** ISO 8601, caller-provided; the library never reads a wall clock. */
75
+ readonly receipt_issued_at: string;
76
+ /** Optional; present when word_digest_handles appear in the flow. */
77
+ readonly lexicon_id?: string;
78
+ /** Optional; "single-list-v1", alongside lexicon_id. */
79
+ readonly lexicon_profile?: string;
80
+ /** 128 hex chars, Ed25519 over canonicalizeJCS(record with sig excluded). */
81
+ readonly sig: string;
82
+ }
83
+ /**
84
+ * Input to createReadFidelityReceipt: the record minus the fields the
85
+ * library sets itself (`type` is the literal, `attester` is derived
86
+ * from the private key, `sig` is computed).
87
+ */
88
+ export type CreateReadFidelityReceiptInput = Omit<ReadFidelityReceipt, 'type' | 'attester' | 'sig'>;
89
+ /** One sampled span: code-point position, length, and text. */
90
+ export interface SampledSpan {
91
+ /** Start position in code points (Array.from indexing). */
92
+ readonly pos: number;
93
+ /** Span length in code points; equals the requested spanLen. */
94
+ readonly len: number;
95
+ readonly text: string;
96
+ }
97
+ /** Result of scoreResponses: per-span exact-match flags and their count. */
98
+ export interface ScoreResponsesResult {
99
+ readonly k: number;
100
+ readonly results: readonly boolean[];
101
+ }
102
+ /**
103
+ * Failure reasons for verifyReadFidelityReceipt and verifyAgainstSource.
104
+ * Check order in verifyReadFidelityReceipt: shape (INVALID_* and
105
+ * N_MISMATCH), then SIGNATURE_INVALID, then SEED_MISMATCH. A record
106
+ * tampered after signing therefore fails on the signature; a record
107
+ * re-signed after a nonce or presentation swap carries a valid
108
+ * signature and fails on the seed derivation instead.
109
+ */
110
+ export type ReadFidelityVerifyReason = 'INVALID_TYPE' | 'INVALID_CONTENT_DIGEST' | 'INVALID_PRESENTATION_DIGEST' | 'INVALID_CHALLENGE' | 'INVALID_N' | 'N_MISMATCH' | 'INVALID_K' | 'INVALID_RESPONSE_DIGEST' | 'INVALID_SCORING_METHOD' | 'INVALID_ATTESTER' | 'INVALID_CLAIMS' | 'INVALID_VERIFICATION_METHOD' | 'INVALID_TIMESTAMP' | 'INVALID_LEXICON_FIELDS' | 'INVALID_SIG_FORMAT' | 'SIGNATURE_INVALID' | 'SEED_MISMATCH' | 'SPAN_RECOMPUTE_FAILED' | 'COMMITMENT_MISMATCH';
111
+ /** Result of verifyReadFidelityReceipt. */
112
+ export interface ReadFidelityVerifyResult {
113
+ readonly valid: boolean;
114
+ readonly reason?: ReadFidelityVerifyReason;
115
+ }
116
+ /**
117
+ * Result of verifyAgainstSource. `commitment_matches[i]` compares the
118
+ * recomputed commitment of span i against challenge.span_commitments[i];
119
+ * ALL must match for validity. `signature_valid` and `seed_valid` are
120
+ * reported independently so a caller can see which binding broke.
121
+ */
122
+ export interface VerifyAgainstSourceResult {
123
+ readonly valid: boolean;
124
+ readonly reason?: ReadFidelityVerifyReason;
125
+ readonly commitment_matches: readonly boolean[];
126
+ readonly signature_valid: boolean;
127
+ readonly seed_valid: boolean;
128
+ }
129
+ /**
130
+ * Result of verifyResponses: the recomputed k over the supplied
131
+ * responses, whether it equals the recorded k, and whether the
132
+ * responses JCS-hash to the recorded response_digest.
133
+ */
134
+ export interface VerifyResponsesResult {
135
+ readonly k_recomputed: number;
136
+ readonly matches_claimed_k: boolean;
137
+ readonly response_digest_ok: boolean;
138
+ }
139
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/v2/read_fidelity_receipt/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ // Copyright 2024-2026 Tymofii Pidlisnyi. Apache-2.0 license. See LICENSE.
2
+ // ══════════════════════════════════════════════════════════════════
3
+ // read_fidelity_receipt (v2): TypeScript types
4
+ // ══════════════════════════════════════════════════════════════════
5
+ // A signed record of a sampled readback challenge: a verifier supplies
6
+ // a nonce, the seed binds that nonce to the exact content digest and
7
+ // presentation digest, spans are sampled deterministically from the
8
+ // seed, and the record commits to the span hashes and the scored
9
+ // readback result (k of n). The raw span texts and responses are NOT
10
+ // in the record; only their commitments and digests are.
11
+ //
12
+ // Signature convention: `sig` is EXCLUDED from the signing preimage.
13
+ // The preimage is canonicalizeJCS(record with the sig key removed
14
+ // entirely), NOT a record with sig set to an empty string.
15
+ // ══════════════════════════════════════════════════════════════════
16
+ export {};
17
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/v2/read_fidelity_receipt/types.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,qEAAqE;AACrE,+CAA+C;AAC/C,qEAAqE;AACrE,uEAAuE;AACvE,qEAAqE;AACrE,oEAAoE;AACpE,iEAAiE;AACjE,qEAAqE;AACrE,yDAAyD;AACzD,EAAE;AACF,qEAAqE;AACrE,kEAAkE;AAClE,2DAA2D;AAC3D,qEAAqE"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=generate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../../../../src/v2/read_fidelity_receipt/vectors/generate.ts"],"names":[],"mappings":""}