agent-passport-system 3.3.1 → 4.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/README.md +6 -2
  2. package/dist/src/core/attribution.d.ts +3 -1
  3. package/dist/src/core/attribution.d.ts.map +1 -1
  4. package/dist/src/core/attribution.js +30 -21
  5. package/dist/src/core/attribution.js.map +1 -1
  6. package/dist/src/core/bilateral-receipt.d.ts.map +1 -1
  7. package/dist/src/core/bilateral-receipt.js +14 -0
  8. package/dist/src/core/bilateral-receipt.js.map +1 -1
  9. package/dist/src/core/canonical-jcs.d.ts +11 -0
  10. package/dist/src/core/canonical-jcs.d.ts.map +1 -1
  11. package/dist/src/core/canonical-jcs.js +39 -0
  12. package/dist/src/core/canonical-jcs.js.map +1 -1
  13. package/dist/src/core/charter.d.ts +16 -2
  14. package/dist/src/core/charter.d.ts.map +1 -1
  15. package/dist/src/core/charter.js +65 -14
  16. package/dist/src/core/charter.js.map +1 -1
  17. package/dist/src/core/delegation.d.ts.map +1 -1
  18. package/dist/src/core/delegation.js +17 -0
  19. package/dist/src/core/delegation.js.map +1 -1
  20. package/dist/src/core/evidence-bundle.d.ts +4 -3
  21. package/dist/src/core/evidence-bundle.d.ts.map +1 -1
  22. package/dist/src/core/evidence-bundle.js +5 -4
  23. package/dist/src/core/evidence-bundle.js.map +1 -1
  24. package/dist/src/core/governance-consumer.d.ts.map +1 -1
  25. package/dist/src/core/governance-consumer.js +5 -2
  26. package/dist/src/core/governance-consumer.js.map +1 -1
  27. package/dist/src/core/is-record.d.ts +3 -0
  28. package/dist/src/core/is-record.d.ts.map +1 -0
  29. package/dist/src/core/is-record.js +23 -0
  30. package/dist/src/core/is-record.js.map +1 -0
  31. package/dist/src/core/reversibility-fold.d.ts +425 -0
  32. package/dist/src/core/reversibility-fold.d.ts.map +1 -0
  33. package/dist/src/core/reversibility-fold.js +513 -0
  34. package/dist/src/core/reversibility-fold.js.map +1 -0
  35. package/dist/src/index.d.ts +1 -1
  36. package/dist/src/index.d.ts.map +1 -1
  37. package/dist/src/index.js +1 -1
  38. package/dist/src/index.js.map +1 -1
  39. package/dist/src/types/execution-envelope.d.ts +7 -0
  40. package/dist/src/types/execution-envelope.d.ts.map +1 -1
  41. package/dist/src/v2/accountability/verify/action.d.ts.map +1 -1
  42. package/dist/src/v2/accountability/verify/action.js +6 -0
  43. package/dist/src/v2/accountability/verify/action.js.map +1 -1
  44. package/dist/src/v2/accountability/verify/bundle.d.ts.map +1 -1
  45. package/dist/src/v2/accountability/verify/bundle.js +6 -0
  46. package/dist/src/v2/accountability/verify/bundle.js.map +1 -1
  47. package/dist/src/v2/accountability/verify/contestability.d.ts.map +1 -1
  48. package/dist/src/v2/accountability/verify/contestability.js +6 -0
  49. package/dist/src/v2/accountability/verify/contestability.js.map +1 -1
  50. package/dist/src/v2/accountability/verify/custody.d.ts.map +1 -1
  51. package/dist/src/v2/accountability/verify/custody.js +6 -0
  52. package/dist/src/v2/accountability/verify/custody.js.map +1 -1
  53. package/dist/src/v2/attribution-settlement/merkle.d.ts +5 -3
  54. package/dist/src/v2/attribution-settlement/merkle.d.ts.map +1 -1
  55. package/dist/src/v2/attribution-settlement/merkle.js +48 -20
  56. package/dist/src/v2/attribution-settlement/merkle.js.map +1 -1
  57. package/dist/src/v2/offline-verifier/context.d.ts.map +1 -1
  58. package/dist/src/v2/offline-verifier/context.js +6 -0
  59. package/dist/src/v2/offline-verifier/context.js.map +1 -1
  60. package/dist/src/v2/offline-verifier/verify.d.ts.map +1 -1
  61. package/dist/src/v2/offline-verifier/verify.js +23 -0
  62. package/dist/src/v2/offline-verifier/verify.js.map +1 -1
  63. package/dist/src/verification/verify.d.ts.map +1 -1
  64. package/dist/src/verification/verify.js +7 -0
  65. package/dist/src/verification/verify.js.map +1 -1
  66. package/package.json +4 -4
@@ -0,0 +1,513 @@
1
+ // Copyright (c) 2026 Tymofii Pidlisnyi
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ // Reversibility fold - foundation (spec v2, reversibility-fold-design-v2.md)
4
+ //
5
+ // A new primitive that reuses the trust-domain-counting and provisional/final
6
+ // lifecycle patterns already established in APS, applied to reversibility.
7
+ //
8
+ // This module is the FOUNDATION only: the two-axis output types and their
9
+ // projection (step 1), and the versioned mapping-profile registry (step 2).
10
+ // It touches no receipt envelope, no gateway, and no existing wire shape.
11
+ // The effect-instantiation block, lifecycle records, fold, divergence, and
12
+ // admission checkpoint are later steps and are not implemented here.
13
+ import { createHash } from 'node:crypto';
14
+ import { sign, verify } from '../crypto/keys.js';
15
+ import { canonicalizeJCS } from './canonical-jcs.js';
16
+ /** Pure projection realized -> enforcement (spec section 0).
17
+ * `unresolved` becomes `irreversible` (conservative, fail-closed). Every
18
+ * other value is the identity. This is the ONLY place `unresolved` is
19
+ * mapped to `irreversible`; realized truth is never rewritten. */
20
+ export function enforcementFrom(realized) {
21
+ return realized === 'unresolved' ? 'irreversible' : realized;
22
+ }
23
+ /** Stable id of the v0 mapping profile. Chosen value; the spec fixes no
24
+ * literal, only that classification_profile_id must be bound. */
25
+ export const REVERSIBILITY_MAPPING_V0_ID = 'reversibility-mapping-v0';
26
+ /** The v0 mapping rules (v4 sections 4, 4.1, 10), as a pure function.
27
+ *
28
+ * v0 has NO external-compensable path. External compensability is a FUTURE
29
+ * profile (reversibility-mapping-v1) built on the deferred four-object subsystem
30
+ * of v4 section 10, never a branch inside the v0 profile. v4 section 10 rejects
31
+ * the domain-separation-without-authority model (a non-empty reversal-right
32
+ * signer different from the principal): a registration outside operator control
33
+ * shows only separation, not authority-over-a-mechanism, so it cannot ground
34
+ * compensability. This profile must not behave differently by entry point.
35
+ *
36
+ * - external-irreversible AND external-reversible -> irreversible. Upper bound
37
+ * (label upper_bound) unless finality is settled AND the target binding is
38
+ * verified. The two external buckets are treated identically in v0.
39
+ * - internal -> irreversible, treated exactly like an external-irreversible
40
+ * effect (upper_bound unless finality settled AND target binding verified). A
41
+ * self-declared recovery_mechanism_ref derives nothing (v4 s4 / s4.1), so v0
42
+ * has no internal-compensable path.
43
+ * - unbound / missing externality -> unresolved.
44
+ * v0 therefore emits no compensable outcome at all. */
45
+ export function classifyV0(facts) {
46
+ const ext = facts.externality;
47
+ // Unbound / missing externality: we cannot even name the bucket. Honest
48
+ // unresolved; enforcementFrom() lifts this to irreversible for admission.
49
+ if (ext === undefined || ext === null) {
50
+ return { realized: 'unresolved', reason: 'RM_V0_UNBOUND' };
51
+ }
52
+ // Any external effect -> irreversible; upper bound unless finality is settled
53
+ // AND target binding verified. v0 has no external-compensable path, so the
54
+ // legacy 'external-reversible' taxonomy value is treated exactly as
55
+ // 'external-irreversible' here (no compensable branch, no reversal-right read).
56
+ if (ext === 'external-irreversible' || ext === 'external-reversible') {
57
+ const finalityVerified = facts.finalityState === 'settled';
58
+ const definitive = finalityVerified && facts.targetBindingVerified === true;
59
+ return definitive
60
+ ? { realized: 'irreversible', reason: 'RM_V0_EXTERNAL_DEFINITIVE' }
61
+ : { realized: 'irreversible', label: 'upper_bound', reason: 'RM_V0_EXTERNAL_UPPER_BOUND' };
62
+ }
63
+ // internal -> irreversible in v0. A self-declared recovery_mechanism_ref is
64
+ // self-attestation and derives NOTHING about the class (v4 s4 / s4.1), the same
65
+ // conflation removed for the external path: a producer cannot mint
66
+ // compensability by naming a rollback path. v0 has no verifier-checked recovery
67
+ // evidence (recoveryMechanismRef, recoveryController, recovery_deadline, and
68
+ // evidence_status are all producer-declared, and the only verifier-supplied
69
+ // signal, targetBindingVerified, is the external resource-confirmation check).
70
+ // internal-compensable requires a verified recovery result that v0 defers, so
71
+ // internal is treated exactly as an external-irreversible effect: irreversible
72
+ // plus upper_bound, unless finality is settled AND the binding is verified. v0
73
+ // therefore has no compensable outcome at all, the sound and consistent
74
+ // position across both externality axes.
75
+ if (ext === 'internal') {
76
+ const finalityVerified = facts.finalityState === 'settled';
77
+ const definitive = finalityVerified && facts.targetBindingVerified === true;
78
+ return definitive
79
+ ? { realized: 'irreversible', reason: 'RM_V0_INTERNAL_DEFINITIVE' }
80
+ : { realized: 'irreversible', label: 'upper_bound', reason: 'RM_V0_INTERNAL_UPPER_BOUND' };
81
+ }
82
+ // Unreachable for typed inputs. Any unrecognized externality bucket is
83
+ // treated as unbound and fails to unresolved (never a compensable fall-open).
84
+ return { realized: 'unresolved', reason: 'RM_V0_UNBOUND' };
85
+ }
86
+ /** The v0 profile function object. */
87
+ export const reversibilityMappingV0 = {
88
+ id: REVERSIBILITY_MAPPING_V0_ID,
89
+ classify: classifyV0,
90
+ };
91
+ /** The AUTHORITATIVE, canonical content of the v0 profile (v4 section 4): its
92
+ * input schema, mapping rules, reason-code set, and time semantics, and nothing
93
+ * else. No runtime, diagnostic, or human-facing metadata (display name,
94
+ * comments, timestamps) is included, so those can change without changing the
95
+ * content digest. This object is what the digest commits to. */
96
+ export const REVERSIBILITY_PROFILE_V0_CONTENT = {
97
+ profile_id: REVERSIBILITY_MAPPING_V0_ID,
98
+ input_fields: ['externality', 'finality_state', 'target_binding_verified'],
99
+ externality_values: ['internal', 'external-reversible', 'external-irreversible'],
100
+ finality_values: ['settled', 'pending', 'expired', 'contradicted'],
101
+ external_compensable: false,
102
+ internal_compensable: false,
103
+ // label is present only when the rule emits one (upper_bound). No null values
104
+ // anywhere in the content: the three SDK JCS implementations disagree on
105
+ // null-valued keys (TS and Python drop them, Go keeps them), so a null-free
106
+ // content is the parity-safe form that canonicalizes byte-identically.
107
+ // v0 has no compensable outcome: both compensable strengths require verified
108
+ // recovery evidence that v0 defers, and a self-declared recovery_mechanism_ref
109
+ // derives nothing, so it is not a classification input.
110
+ rules: [
111
+ { id: 'unbound', when: 'externality_absent', realized: 'unresolved', reason: 'RM_V0_UNBOUND' },
112
+ { id: 'external_definitive', when: 'externality_external AND finality_settled AND target_binding_verified', realized: 'irreversible', reason: 'RM_V0_EXTERNAL_DEFINITIVE' },
113
+ { id: 'external_upper_bound', when: 'externality_external AND NOT(finality_settled AND target_binding_verified)', realized: 'irreversible', label: 'upper_bound', reason: 'RM_V0_EXTERNAL_UPPER_BOUND' },
114
+ { id: 'internal_definitive', when: 'externality_internal AND finality_settled AND target_binding_verified', realized: 'irreversible', reason: 'RM_V0_INTERNAL_DEFINITIVE' },
115
+ { id: 'internal_upper_bound', when: 'externality_internal AND NOT(finality_settled AND target_binding_verified)', realized: 'irreversible', label: 'upper_bound', reason: 'RM_V0_INTERNAL_UPPER_BOUND' },
116
+ ],
117
+ reason_codes: ['RM_V0_UNBOUND', 'RM_V0_EXTERNAL_DEFINITIVE', 'RM_V0_EXTERNAL_UPPER_BOUND', 'RM_V0_INTERNAL_DEFINITIVE', 'RM_V0_INTERNAL_UPPER_BOUND'],
118
+ time_semantics: { clock_skew_ms: 0, finality_source: 'bound_input', target_binding_source: 'verifier_supplied' },
119
+ schema_version: 'v0',
120
+ };
121
+ /** Domain-separated content digest of a profile (v4 section 4):
122
+ * SHA-256( UTF8("APS-REVERSIBILITY-PROFILE-V0") || 0x00 || UTF8(JCS(content)) ).
123
+ * Any language that JCS-canonicalizes the same content reproduces this byte-for-
124
+ * byte. */
125
+ export function profileContentDigest(content) {
126
+ const preimage = Buffer.concat([
127
+ Buffer.from('APS-REVERSIBILITY-PROFILE-V0', 'utf8'),
128
+ Buffer.from([0x00]),
129
+ Buffer.from(canonicalizeJCS(content), 'utf8'),
130
+ ]);
131
+ return 'sha256:' + createHash('sha256').update(preimage).digest('hex');
132
+ }
133
+ /** The v0 profile's content digest. */
134
+ export const REVERSIBILITY_MAPPING_V0_DIGEST = profileContentDigest(REVERSIBILITY_PROFILE_V0_CONTENT);
135
+ /** The immutable content-addressed registry (v4 section 4). It never mutates an
136
+ * existing (id, digest) pair; a change to a profile's content yields a new
137
+ * digest and is a NEW profile with a new id. Resolving an unknown id, or an
138
+ * (id, digest) mismatch, is a DISTINCT failure, never a silent fallback. */
139
+ const PROFILE_REGISTRY = new Map([
140
+ [REVERSIBILITY_MAPPING_V0_ID, {
141
+ profile: reversibilityMappingV0,
142
+ content: REVERSIBILITY_PROFILE_V0_CONTENT,
143
+ digest: REVERSIBILITY_MAPPING_V0_DIGEST,
144
+ metadata: {
145
+ display_name: 'Reversibility mapping v0',
146
+ description: 'Fail-closed v0 classifier: internal and external both resolve to irreversible; no compensable outcome, since verified recovery evidence is deferred.',
147
+ },
148
+ }],
149
+ ]);
150
+ /** Resolve a mapping profile function by its classification_profile_id. Returns
151
+ * undefined for an unknown id (a distinct event from unbound facts). */
152
+ export function getClassificationProfile(id) {
153
+ return PROFILE_REGISTRY.get(id)?.profile;
154
+ }
155
+ /** Resolve the full registered profile (function, content, digest, metadata). */
156
+ export function getRegisteredProfile(id) {
157
+ return PROFILE_REGISTRY.get(id);
158
+ }
159
+ /** The registry's content digest for a profile id, or undefined if unknown. */
160
+ export function getProfileDigest(id) {
161
+ return PROFILE_REGISTRY.get(id)?.digest;
162
+ }
163
+ /** The set of registered profile ids. */
164
+ export function registeredProfileIds() {
165
+ return [...PROFILE_REGISTRY.keys()];
166
+ }
167
+ /** Check a declared profile id + content digest against the immutable registry.
168
+ * An id not in the registry fails unknown_profile; a known id whose declared
169
+ * digest does not equal the registry digest fails digest_mismatch. */
170
+ export function verifyProfileBinding(id, declaredDigest) {
171
+ const registered = PROFILE_REGISTRY.get(id);
172
+ if (registered === undefined) {
173
+ return { ok: false, reason: 'unknown_profile', classificationProfileId: id };
174
+ }
175
+ if (declaredDigest !== registered.digest) {
176
+ return { ok: false, reason: 'digest_mismatch', classificationProfileId: id, declaredDigest, expectedDigest: registered.digest };
177
+ }
178
+ return { ok: true, digest: registered.digest };
179
+ }
180
+ /** Map an RAPV0 externality onto the value used for EffectFacts.externality.
181
+ * 'none' or absent -> undefined (unbound), which classifies unresolved.
182
+ * internal -> internal. Both external buckets -> external-irreversible: the
183
+ * legacy 'external-reversible' taxonomy carried a stronger meaning than v0
184
+ * grants, so it is NOT passed through as-is; mapping it to external-irreversible
185
+ * keeps it from being a backdoor into compensability (v4 s4/s10). This is a pure
186
+ * adapter, not an import-and-couple. */
187
+ export function rapvExternalityToEffectFacts(externality) {
188
+ if (externality == null || externality === 'none')
189
+ return undefined;
190
+ if (externality === 'internal')
191
+ return 'internal';
192
+ return 'external-irreversible';
193
+ }
194
+ /** Derive the classifier externality bucket from an element's raw facts (v4
195
+ * section 4.1). internal -> internal. external -> external-irreversible,
196
+ * ALWAYS, in v0: there is no verified reversal right in v0, so no external
197
+ * effect reaches external-reversible, and a self-declared recovery_mechanism_ref
198
+ * derives NOTHING about the class. recovery_mechanism_ref remains a carried raw
199
+ * fact and still informs the INTERNAL branch's observable-recovery test; it is
200
+ * simply not evidence of reversibility for an external effect. Downstream, an
201
+ * external effect classifies to irreversible + upper_bound (target binding is
202
+ * not verified in v0), never bare irreversible and never compensable. */
203
+ function deriveExternality(element) {
204
+ if (element.effect_scope === 'internal')
205
+ return 'internal';
206
+ return 'external-irreversible';
207
+ }
208
+ /** Build classifier facts from an element plus verifier context. Note what is
209
+ * deliberately NOT supplied here: actingPrincipal and the external reversal-
210
+ * right attestation are the actor axis (a later step), so an external-
211
+ * reversible effect fails closed to irreversible under this recompute until
212
+ * that step supplies verified actor-axis facts. targetBindingVerified comes
213
+ * only from the verifier context, never from the element (hard rule). */
214
+ function effectFactsFromElement(element, options) {
215
+ return {
216
+ externality: deriveExternality(element),
217
+ recoveryController: element.recovery_controller,
218
+ recoveryMechanismRef: element.recovery_mechanism_ref,
219
+ finalityState: element.finality_state,
220
+ targetBindingVerified: options?.targetBindingVerified === true,
221
+ };
222
+ }
223
+ /** Recompute the realized class for one effect element. Resolves the mapping
224
+ * profile by classification_profile_id; an unknown id is surfaced as its own
225
+ * failure and is NOT classified. Otherwise runs the profile over the element's
226
+ * facts and returns the ClassificationResult. */
227
+ export function recomputeEffect(element, options) {
228
+ const registered = getRegisteredProfile(element.classification_profile_id);
229
+ if (registered === undefined) {
230
+ return { status: 'unknown_profile', classificationProfileId: element.classification_profile_id };
231
+ }
232
+ // Bind id to content: a declared digest that does not match the registry is a
233
+ // DISTINCT failure from an unknown profile, and is not classified.
234
+ if (element.classification_profile_digest !== registered.digest) {
235
+ return {
236
+ status: 'profile_digest_mismatch',
237
+ classificationProfileId: element.classification_profile_id,
238
+ declaredDigest: element.classification_profile_digest,
239
+ expectedDigest: registered.digest,
240
+ };
241
+ }
242
+ const facts = effectFactsFromElement(element, options);
243
+ return {
244
+ status: 'recomputed',
245
+ classificationProfileId: element.classification_profile_id,
246
+ result: registered.profile.classify(facts),
247
+ };
248
+ }
249
+ /** Recompute every effect in a block, per element. No folding or collapsing to
250
+ * a maximum here (that is the fold, a later step). */
251
+ export function recomputeBlock(block, options) {
252
+ return block.instantiated_effects.map((e) => recomputeEffect(e, options));
253
+ }
254
+ /** Verify an element's asserted cache class (if any) against the recompute.
255
+ * A cache is a convenience only and is never trusted: a mismatch fails. An
256
+ * unknown profile or a profile-digest mismatch cannot be verified and surfaces
257
+ * distinctly. */
258
+ export function verifyAssertedClass(element, options) {
259
+ const outcome = recomputeEffect(element, options);
260
+ if (outcome.status === 'unknown_profile') {
261
+ return { ok: false, reason: 'unknown_profile', classificationProfileId: outcome.classificationProfileId };
262
+ }
263
+ if (outcome.status === 'profile_digest_mismatch') {
264
+ return {
265
+ ok: false,
266
+ reason: 'profile_digest_mismatch',
267
+ classificationProfileId: outcome.classificationProfileId,
268
+ declaredDigest: outcome.declaredDigest,
269
+ expectedDigest: outcome.expectedDigest,
270
+ };
271
+ }
272
+ const recomputed = outcome.result;
273
+ if (element.asserted_realized_class === undefined) {
274
+ return { ok: true, recomputed };
275
+ }
276
+ if (element.asserted_realized_class !== recomputed.realized) {
277
+ return { ok: false, reason: 'mismatch', asserted: element.asserted_realized_class, recomputed: recomputed.realized };
278
+ }
279
+ return { ok: true, recomputed };
280
+ }
281
+ /** SHA-256 (over strict JCS bytes) of an execution receipt. Any change to the
282
+ * execution receipt changes this hash, so a hash-link detects a rewrite. */
283
+ export function hashExecutionReceipt(receipt) {
284
+ return 'sha256:' + createHash('sha256').update(canonicalizeJCS(receipt)).digest('hex');
285
+ }
286
+ /** Create a reconciliation receipt hash-linked to an execution receipt and
287
+ * signed over its canonical body. Does not touch the execution receipt. */
288
+ export function createReconciliationReceipt(execution, input) {
289
+ const body = {
290
+ stage: 'reconciliation',
291
+ execution_receipt_hash: hashExecutionReceipt(execution),
292
+ action_ref: execution.action_ref,
293
+ realized_class: input.realized_class,
294
+ evidence_status: input.evidence_status,
295
+ reconciled_at: input.reconciled_at,
296
+ };
297
+ const value = sign(canonicalizeJCS(body), input.signerPrivateKey);
298
+ return { ...body, signature: { algorithm: 'Ed25519', public_key: input.signerPublicKey, value } };
299
+ }
300
+ /** The realized classes a reconciliation may refine a pending stage into.
301
+ * pending -> compensable and pending -> irreversible only. */
302
+ const MONOTONIC_RECONCILED_CLASSES = new Set([
303
+ 'compensable',
304
+ 'irreversible',
305
+ ]);
306
+ /** Validate a reconciliation against its execution receipt. Rejects a broken
307
+ * hash-link (a rewritten execution receipt), an invalid signature, a stage
308
+ * that is not pending, and any non-monotonic realized class. */
309
+ export function validateTransition(execution, reconciliation) {
310
+ const errors = [];
311
+ // Hash-link integrity: the reconciliation must reference THIS execution
312
+ // receipt. A post-hoc rewrite of the execution receipt breaks the link.
313
+ if (reconciliation.execution_receipt_hash !== hashExecutionReceipt(execution)) {
314
+ errors.push('hash-link mismatch: reconciliation does not reference this execution receipt');
315
+ }
316
+ if (reconciliation.action_ref !== execution.action_ref) {
317
+ errors.push('action_ref mismatch between stages');
318
+ }
319
+ // Signature over the reconciliation body (excluding the signature block).
320
+ const { signature, ...body } = reconciliation;
321
+ if (!verify(canonicalizeJCS(body), signature.value, signature.public_key)) {
322
+ errors.push('reconciliation signature invalid');
323
+ }
324
+ // Monotonic transition: the execution stage is provisional (pending); the
325
+ // reconciliation may only refine to compensable or irreversible. Anything
326
+ // else is an arbitrary replacement and is rejected.
327
+ if (execution.evidence_status !== 'pending') {
328
+ errors.push('execution receipt is not in the pending stage');
329
+ }
330
+ if (!MONOTONIC_RECONCILED_CLASSES.has(reconciliation.realized_class)) {
331
+ errors.push(`non-monotonic realized_class '${reconciliation.realized_class}' (only compensable or irreversible refine a pending stage)`);
332
+ }
333
+ return { ok: errors.length === 0, errors };
334
+ }
335
+ /** The enforcement class that GOVERNED admission. This reads ONLY the execution
336
+ * receipt: the reconciliation's realized class is audit-time truth and carries
337
+ * no enforcement power, so a consumer cannot read the final class as the one
338
+ * that gated the action. */
339
+ export function admittedEnforcementClass(execution) {
340
+ return execution.admitted_enforcement_class;
341
+ }
342
+ // ══════════════════════════════════════
343
+ // STEP v0-2 - Effect identity and lineage (v4 section 2)
344
+ // ══════════════════════════════════════
345
+ //
346
+ // Every effect element carries a stable identity so precedence is defined
347
+ // without array position. The fold (a later step) classifies from the LATEST
348
+ // valid lineage state per effect_id, never from position in instantiated_effects
349
+ // and never from the existence of a right. This step adds and validates the
350
+ // identity fields only; it does not build the fold.
351
+ /** The signed authoritative fields of one effect state as a null-free object
352
+ * (v4 section 2). It commits to every signed field: effect_id, sequence,
353
+ * predecessor_effect_state_hash, the raw effect facts, classification_profile_id,
354
+ * classification_profile_digest, the evidence status, and the receipt/action
355
+ * binding (action_ref, action_instance_id). The asserted class is signed content
356
+ * and part of the state identity, so it is included when present, but it is
357
+ * non-authoritative for classification (a verifier recomputes). Computed
358
+ * verification outputs, the state hash itself, and out-of-object signatures are
359
+ * excluded: the builder reads only the known signed fields, so an extra property
360
+ * on the element object cannot enter the preimage. Only non-null fields are
361
+ * included, the same parity-safe rule the profile content follows, because the
362
+ * SDK JCS implementations diverge on null-valued keys. */
363
+ export function effectStatePreimage(el) {
364
+ const p = {
365
+ effect_scope: el.effect_scope,
366
+ effect_target_ref: el.effect_target_ref,
367
+ finality_state: el.finality_state,
368
+ evidence_status: el.evidence_status,
369
+ classification_profile_id: el.classification_profile_id,
370
+ classification_profile_digest: el.classification_profile_digest,
371
+ action_ref: el.action_ref,
372
+ action_instance_id: el.action_instance_id,
373
+ effect_id: el.effect_id,
374
+ sequence: el.sequence,
375
+ };
376
+ if (el.recovery_mechanism_ref != null)
377
+ p.recovery_mechanism_ref = el.recovery_mechanism_ref;
378
+ if (el.recovery_controller != null)
379
+ p.recovery_controller = el.recovery_controller;
380
+ if (el.recovery_deadline != null)
381
+ p.recovery_deadline = el.recovery_deadline;
382
+ if (el.predecessor_effect_state_hash != null)
383
+ p.predecessor_effect_state_hash = el.predecessor_effect_state_hash;
384
+ if (el.asserted_realized_class !== undefined)
385
+ p.asserted_realized_class = el.asserted_realized_class;
386
+ return p;
387
+ }
388
+ /** Domain-separated hash of one effect state (v4 section 2):
389
+ * SHA-256( UTF8("APS-REVERSIBILITY-EFFECT-STATE-V0") || 0x00 || UTF8(JCS(preimage)) )
390
+ * over the null-free preimage of every signed authoritative field. Chains a
391
+ * lineage: a later state's predecessor_effect_state_hash references this. Any
392
+ * language that JCS-canonicalizes the same preimage reproduces it byte-for-byte. */
393
+ export function hashEffectState(element) {
394
+ const preimage = Buffer.concat([
395
+ Buffer.from('APS-REVERSIBILITY-EFFECT-STATE-V0', 'utf8'),
396
+ Buffer.from([0x00]),
397
+ Buffer.from(canonicalizeJCS(effectStatePreimage(element)), 'utf8'),
398
+ ]);
399
+ return 'sha256:' + createHash('sha256').update(preimage).digest('hex');
400
+ }
401
+ /** Deterministic derivation of an effect_id (v4 section 2):
402
+ * base64url( SHA-256( UTF8("APS-REVERSIBILITY-EFFECT-ID-V0") || 0x00 ||
403
+ * UTF8(JCS({action_ref, action_instance_id, local_effect_id})) ) ), where
404
+ * local_effect_id is unique within the receipt and STABLE across retries (an
405
+ * id, not a nonce). The id is a function of stable inputs, so a retry produces
406
+ * the same effect_id and the same lineage identity. */
407
+ export function deriveEffectId(action_ref, action_instance_id, local_effect_id) {
408
+ const preimage = Buffer.concat([
409
+ Buffer.from('APS-REVERSIBILITY-EFFECT-ID-V0', 'utf8'),
410
+ Buffer.from([0x00]),
411
+ Buffer.from(canonicalizeJCS({ action_ref, action_instance_id, local_effect_id }), 'utf8'),
412
+ ]);
413
+ return createHash('sha256').update(preimage).digest('base64url');
414
+ }
415
+ /** Validate one effect_id's lineage, order-invariant. First removes exact
416
+ * duplicates (same full hash), then enforces the graph invariant. */
417
+ function validateOneLineage(states) {
418
+ // Deduplicate exact-duplicate states by full effect-state hash.
419
+ const byHash = new Map();
420
+ let duplicate_count = 0;
421
+ for (const s of states) {
422
+ const h = hashEffectState(s);
423
+ if (byHash.has(h))
424
+ duplicate_count++;
425
+ else
426
+ byHash.set(h, s);
427
+ }
428
+ const unique = [...byHash.values()];
429
+ // Exactly one root at sequence 0 with a null predecessor.
430
+ const roots = unique.filter((s) => s.predecessor_effect_state_hash === null);
431
+ if (roots.length > 1)
432
+ return { status: 'equivocation', duplicate_count };
433
+ if (roots.length === 0)
434
+ return { status: 'lineage_incomplete', duplicate_count };
435
+ if (roots[0].sequence !== 0)
436
+ return { status: 'lineage_incomplete', duplicate_count };
437
+ // Fork: no predecessor hash may have more than one distinct successor. This
438
+ // holds regardless of the successors' sequences, so a fork whose branches sit
439
+ // at different sequences is still a fork, not a broken link.
440
+ const succOfPred = new Map();
441
+ for (const s of unique) {
442
+ if (s.predecessor_effect_state_hash !== null) {
443
+ succOfPred.set(s.predecessor_effect_state_hash, (succOfPred.get(s.predecessor_effect_state_hash) ?? 0) + 1);
444
+ }
445
+ }
446
+ if ([...succOfPred.values()].some((c) => c > 1)) {
447
+ return { status: 'lineage_conflicted', duplicate_count };
448
+ }
449
+ // At most one state per sequence. A remaining collision (not from a shared
450
+ // predecessor, since forks were already caught) is an equivocation about the
451
+ // position: two states claim the same sequence with different hashes.
452
+ const bySeq = new Map();
453
+ for (const s of unique)
454
+ bySeq.set(s.sequence, (bySeq.get(s.sequence) ?? 0) + 1);
455
+ if ([...bySeq.values()].some((c) => c > 1)) {
456
+ return { status: 'equivocation', duplicate_count };
457
+ }
458
+ // Consecutive sequences 0..n-1 (a gap is incomplete), and each state at n>0
459
+ // references the hash of the state at n-1 (else the chain link is invalid).
460
+ const ordered = [...unique].sort((a, b) => a.sequence - b.sequence);
461
+ for (let i = 0; i < ordered.length; i++) {
462
+ if (ordered[i].sequence !== i)
463
+ return { status: 'lineage_incomplete', duplicate_count };
464
+ }
465
+ for (let i = 1; i < ordered.length; i++) {
466
+ if (ordered[i].predecessor_effect_state_hash !== hashEffectState(ordered[i - 1])) {
467
+ return { status: 'invalid_state', duplicate_count };
468
+ }
469
+ }
470
+ return { status: 'ok', duplicate_count };
471
+ }
472
+ /** Validate the identity and lineage structure of a block, independent of array
473
+ * order (v4 section 2, corrected). Returns a TYPED status plus a duplicate_count.
474
+ * The block is ok only when every effect_id's lineage is ok; otherwise the
475
+ * status is that of the lexicographically first non-ok effect_id (deterministic).
476
+ * This validates identity only; the lineage-based fold reading (classify from
477
+ * the latest lineage state per effect_id) is the fold, not built here. */
478
+ export function validateEffectLineage(block) {
479
+ const byEffect = new Map();
480
+ for (const el of block.instantiated_effects) {
481
+ const states = byEffect.get(el.effect_id) ?? [];
482
+ states.push(el);
483
+ byEffect.set(el.effect_id, states);
484
+ }
485
+ let duplicate_count = 0;
486
+ let firstNonOk;
487
+ for (const effectId of [...byEffect.keys()].sort()) {
488
+ const r = validateOneLineage(byEffect.get(effectId));
489
+ duplicate_count += r.duplicate_count;
490
+ if (r.status !== 'ok' && firstNonOk === undefined)
491
+ firstNonOk = r.status;
492
+ }
493
+ return { status: firstNonOk ?? 'ok', duplicate_count };
494
+ }
495
+ /** The latest valid state per effect_id, but ONLY for an ok lineage. Returns
496
+ * undefined for any non-ok block, so a caller cannot pull a latest state from an
497
+ * incomplete, conflicted, equivocating, or invalid lineage. Order-invariant. */
498
+ export function latestValidEffectStates(block) {
499
+ if (validateEffectLineage(block).status !== 'ok')
500
+ return undefined;
501
+ const byEffect = new Map();
502
+ for (const el of block.instantiated_effects) {
503
+ const states = byEffect.get(el.effect_id) ?? [];
504
+ states.push(el);
505
+ byEffect.set(el.effect_id, states);
506
+ }
507
+ const latest = new Map();
508
+ for (const [id, states] of byEffect) {
509
+ latest.set(id, [...states].sort((a, b) => b.sequence - a.sequence)[0]);
510
+ }
511
+ return latest;
512
+ }
513
+ //# sourceMappingURL=reversibility-fold.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reversibility-fold.js","sourceRoot":"","sources":["../../../src/core/reversibility-fold.ts"],"names":[],"mappings":"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"}
@@ -148,7 +148,7 @@ export { computeContentHash, verifyContentHash, createContentAddressableIntent,
148
148
  export type { ScopeInterpretation, ContentHash, ContentHashAlgorithm, DecisionSemantics, DecisionArtifact, DecisionArtifactVerification, } from './types/decision-semantics.js';
149
149
  export type { CharterStatus, OfficeHolderMode, OfficeStatus, OfficeHolder, OfficeDelegationPolicy, Office, CharterSignature, DelegationSurvival, DissolutionPolicy, DisputeVenue, CharterCore, SuccessionTrigger, SuccessionRule, QuorumFailurePolicy, OfficeRegistry, CharterAmendment, CharterVerification, AmendmentVerification, OfficeTransfer, } from './types/charter.js';
150
150
  export type { KeyClassRequirement, MultiClassThresholdPolicy, ApprovalType, ApprovalPolicy, ApprovalSignature, ApprovalSubjectType, ApprovalRequest, ApprovalEvaluation, KeyClassStatus, } from './types/approval.js';
151
- export { createCharter, signCharter, verifyCharter, createAmendment, signAmendment, verifyAmendment, evaluateThreshold, createOfficeRegistry, createOfficeTransfer, createApprovalRequest, addApprovalSignature, evaluateApprovalRequest, findOffice, findOfficesByHolder, resolveSuccessor, checkIncompatibility, checkQuorum, } from './core/charter.js';
151
+ export { createCharter, signCharter, verifyCharter, createAmendment, signAmendment, verifyAmendment, evaluateThreshold, createOfficeRegistry, createOfficeTransfer, createApprovalRequest, addApprovalSignature, evaluateApprovalRequest, approvalSignContent, findOffice, findOfficesByHolder, resolveSuccessor, checkIncompatibility, checkQuorum, } from './core/charter.js';
152
152
  export type { CreateCharterOptions, CreateAmendmentOptions, CreateOfficeTransferOptions } from './core/charter.js';
153
153
  export type { HybridTimestamp, TemporalBound, TemporalRights, TemporalOrdering, TemporalValidation, SessionBoundary, } from './types/time.js';
154
154
  export { DEFAULT_NTP_DRIFT_MS, DEFAULT_SESSION_GAP_MS, createHybridTimestamp, createHybridTimestampAt, createTemporalBound, compareTimestamps, isTemporalBoundExpired, validateTemporalRights, resetLogicalCounter, extractSessions, } from './core/time.js';