agent-passport-system 7.1.0 → 7.2.1

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 (155) hide show
  1. package/README.md +4 -5
  2. package/SECURITY.md +2 -2
  3. package/dist/src/core/tool-integrity.d.ts +13 -0
  4. package/dist/src/core/tool-integrity.d.ts.map +1 -1
  5. package/dist/src/core/tool-integrity.js +1 -1
  6. package/dist/src/core/tool-integrity.js.map +1 -1
  7. package/dist/src/index.d.ts +28 -0
  8. package/dist/src/index.d.ts.map +1 -1
  9. package/dist/src/index.js +242 -0
  10. package/dist/src/index.js.map +1 -1
  11. package/dist/src/v2/activation/canonical.d.ts +40 -0
  12. package/dist/src/v2/activation/canonical.d.ts.map +1 -0
  13. package/dist/src/v2/activation/canonical.js +64 -0
  14. package/dist/src/v2/activation/canonical.js.map +1 -0
  15. package/dist/src/v2/activation/index.d.ts +4 -0
  16. package/dist/src/v2/activation/index.d.ts.map +1 -0
  17. package/dist/src/v2/activation/index.js +11 -0
  18. package/dist/src/v2/activation/index.js.map +1 -0
  19. package/dist/src/v2/activation/types.d.ts +268 -0
  20. package/dist/src/v2/activation/types.d.ts.map +1 -0
  21. package/dist/src/v2/activation/types.js +198 -0
  22. package/dist/src/v2/activation/types.js.map +1 -0
  23. package/dist/src/v2/activation/verify.d.ts +132 -0
  24. package/dist/src/v2/activation/verify.d.ts.map +1 -0
  25. package/dist/src/v2/activation/verify.js +406 -0
  26. package/dist/src/v2/activation/verify.js.map +1 -0
  27. package/dist/src/v2/authority-state/fencing.d.ts +49 -0
  28. package/dist/src/v2/authority-state/fencing.d.ts.map +1 -0
  29. package/dist/src/v2/authority-state/fencing.js +92 -0
  30. package/dist/src/v2/authority-state/fencing.js.map +1 -0
  31. package/dist/src/v2/authority-state/index.d.ts +7 -0
  32. package/dist/src/v2/authority-state/index.d.ts.map +1 -0
  33. package/dist/src/v2/authority-state/index.js +14 -0
  34. package/dist/src/v2/authority-state/index.js.map +1 -0
  35. package/dist/src/v2/authority-state/marker.d.ts +70 -0
  36. package/dist/src/v2/authority-state/marker.d.ts.map +1 -0
  37. package/dist/src/v2/authority-state/marker.js +122 -0
  38. package/dist/src/v2/authority-state/marker.js.map +1 -0
  39. package/dist/src/v2/authority-state/report.d.ts +55 -0
  40. package/dist/src/v2/authority-state/report.d.ts.map +1 -0
  41. package/dist/src/v2/authority-state/report.js +51 -0
  42. package/dist/src/v2/authority-state/report.js.map +1 -0
  43. package/dist/src/v2/authority-state/retained.d.ts +82 -0
  44. package/dist/src/v2/authority-state/retained.d.ts.map +1 -0
  45. package/dist/src/v2/authority-state/retained.js +93 -0
  46. package/dist/src/v2/authority-state/retained.js.map +1 -0
  47. package/dist/src/v2/authority-state/types.d.ts +198 -0
  48. package/dist/src/v2/authority-state/types.d.ts.map +1 -0
  49. package/dist/src/v2/authority-state/types.js +103 -0
  50. package/dist/src/v2/authority-state/types.js.map +1 -0
  51. package/dist/src/v2/authority-state/withdrawal.d.ts +80 -0
  52. package/dist/src/v2/authority-state/withdrawal.d.ts.map +1 -0
  53. package/dist/src/v2/authority-state/withdrawal.js +199 -0
  54. package/dist/src/v2/authority-state/withdrawal.js.map +1 -0
  55. package/dist/src/v2/bounds/canonical.d.ts +30 -0
  56. package/dist/src/v2/bounds/canonical.d.ts.map +1 -0
  57. package/dist/src/v2/bounds/canonical.js +69 -0
  58. package/dist/src/v2/bounds/canonical.js.map +1 -0
  59. package/dist/src/v2/bounds/evaluate.d.ts +107 -0
  60. package/dist/src/v2/bounds/evaluate.d.ts.map +1 -0
  61. package/dist/src/v2/bounds/evaluate.js +315 -0
  62. package/dist/src/v2/bounds/evaluate.js.map +1 -0
  63. package/dist/src/v2/bounds/index.d.ts +6 -0
  64. package/dist/src/v2/bounds/index.d.ts.map +1 -0
  65. package/dist/src/v2/bounds/index.js +13 -0
  66. package/dist/src/v2/bounds/index.js.map +1 -0
  67. package/dist/src/v2/bounds/purpose.d.ts +2 -0
  68. package/dist/src/v2/bounds/purpose.d.ts.map +1 -0
  69. package/dist/src/v2/bounds/purpose.js +23 -0
  70. package/dist/src/v2/bounds/purpose.js.map +1 -0
  71. package/dist/src/v2/bounds/record.d.ts +78 -0
  72. package/dist/src/v2/bounds/record.d.ts.map +1 -0
  73. package/dist/src/v2/bounds/record.js +170 -0
  74. package/dist/src/v2/bounds/record.js.map +1 -0
  75. package/dist/src/v2/bounds/types.d.ts +275 -0
  76. package/dist/src/v2/bounds/types.d.ts.map +1 -0
  77. package/dist/src/v2/bounds/types.js +124 -0
  78. package/dist/src/v2/bounds/types.js.map +1 -0
  79. package/dist/src/v2/capability-binding/binding.d.ts +67 -0
  80. package/dist/src/v2/capability-binding/binding.d.ts.map +1 -0
  81. package/dist/src/v2/capability-binding/binding.js +267 -0
  82. package/dist/src/v2/capability-binding/binding.js.map +1 -0
  83. package/dist/src/v2/capability-binding/digest.d.ts +33 -0
  84. package/dist/src/v2/capability-binding/digest.d.ts.map +1 -0
  85. package/dist/src/v2/capability-binding/digest.js +55 -0
  86. package/dist/src/v2/capability-binding/digest.js.map +1 -0
  87. package/dist/src/v2/capability-binding/identifier.d.ts +103 -0
  88. package/dist/src/v2/capability-binding/identifier.d.ts.map +1 -0
  89. package/dist/src/v2/capability-binding/identifier.js +281 -0
  90. package/dist/src/v2/capability-binding/identifier.js.map +1 -0
  91. package/dist/src/v2/capability-binding/index.d.ts +6 -0
  92. package/dist/src/v2/capability-binding/index.d.ts.map +1 -0
  93. package/dist/src/v2/capability-binding/index.js +13 -0
  94. package/dist/src/v2/capability-binding/index.js.map +1 -0
  95. package/dist/src/v2/capability-binding/pins.d.ts +30 -0
  96. package/dist/src/v2/capability-binding/pins.d.ts.map +1 -0
  97. package/dist/src/v2/capability-binding/pins.js +109 -0
  98. package/dist/src/v2/capability-binding/pins.js.map +1 -0
  99. package/dist/src/v2/capability-binding/types.d.ts +213 -0
  100. package/dist/src/v2/capability-binding/types.d.ts.map +1 -0
  101. package/dist/src/v2/capability-binding/types.js +150 -0
  102. package/dist/src/v2/capability-binding/types.js.map +1 -0
  103. package/dist/src/v2/chain-selection/index.d.ts +4 -0
  104. package/dist/src/v2/chain-selection/index.d.ts.map +1 -0
  105. package/dist/src/v2/chain-selection/index.js +11 -0
  106. package/dist/src/v2/chain-selection/index.js.map +1 -0
  107. package/dist/src/v2/chain-selection/select.d.ts +62 -0
  108. package/dist/src/v2/chain-selection/select.d.ts.map +1 -0
  109. package/dist/src/v2/chain-selection/select.js +390 -0
  110. package/dist/src/v2/chain-selection/select.js.map +1 -0
  111. package/dist/src/v2/chain-selection/types.d.ts +189 -0
  112. package/dist/src/v2/chain-selection/types.d.ts.map +1 -0
  113. package/dist/src/v2/chain-selection/types.js +81 -0
  114. package/dist/src/v2/chain-selection/types.js.map +1 -0
  115. package/dist/src/v2/lifecycle-state/index.d.ts +4 -0
  116. package/dist/src/v2/lifecycle-state/index.d.ts.map +1 -0
  117. package/dist/src/v2/lifecycle-state/index.js +10 -0
  118. package/dist/src/v2/lifecycle-state/index.js.map +1 -0
  119. package/dist/src/v2/lifecycle-state/map.d.ts +52 -0
  120. package/dist/src/v2/lifecycle-state/map.d.ts.map +1 -0
  121. package/dist/src/v2/lifecycle-state/map.js +122 -0
  122. package/dist/src/v2/lifecycle-state/map.js.map +1 -0
  123. package/dist/src/v2/lifecycle-state/state.d.ts +60 -0
  124. package/dist/src/v2/lifecycle-state/state.d.ts.map +1 -0
  125. package/dist/src/v2/lifecycle-state/state.js +157 -0
  126. package/dist/src/v2/lifecycle-state/state.js.map +1 -0
  127. package/dist/src/v2/lifecycle-state/types.d.ts +163 -0
  128. package/dist/src/v2/lifecycle-state/types.d.ts.map +1 -0
  129. package/dist/src/v2/lifecycle-state/types.js +121 -0
  130. package/dist/src/v2/lifecycle-state/types.js.map +1 -0
  131. package/dist/src/v2/status-coverage/decide.d.ts +52 -0
  132. package/dist/src/v2/status-coverage/decide.d.ts.map +1 -0
  133. package/dist/src/v2/status-coverage/decide.js +398 -0
  134. package/dist/src/v2/status-coverage/decide.js.map +1 -0
  135. package/dist/src/v2/status-coverage/index.d.ts +3 -0
  136. package/dist/src/v2/status-coverage/index.d.ts.map +1 -0
  137. package/dist/src/v2/status-coverage/index.js +10 -0
  138. package/dist/src/v2/status-coverage/index.js.map +1 -0
  139. package/dist/src/v2/status-coverage/types.d.ts +258 -0
  140. package/dist/src/v2/status-coverage/types.d.ts.map +1 -0
  141. package/dist/src/v2/status-coverage/types.js +127 -0
  142. package/dist/src/v2/status-coverage/types.js.map +1 -0
  143. package/dist/src/v2/suspension/evaluate.d.ts +88 -0
  144. package/dist/src/v2/suspension/evaluate.d.ts.map +1 -0
  145. package/dist/src/v2/suspension/evaluate.js +404 -0
  146. package/dist/src/v2/suspension/evaluate.js.map +1 -0
  147. package/dist/src/v2/suspension/index.d.ts +3 -0
  148. package/dist/src/v2/suspension/index.d.ts.map +1 -0
  149. package/dist/src/v2/suspension/index.js +10 -0
  150. package/dist/src/v2/suspension/index.js.map +1 -0
  151. package/dist/src/v2/suspension/types.d.ts +243 -0
  152. package/dist/src/v2/suspension/types.d.ts.map +1 -0
  153. package/dist/src/v2/suspension/types.js +135 -0
  154. package/dist/src/v2/suspension/types.js.map +1 -0
  155. package/package.json +8 -8
@@ -0,0 +1,406 @@
1
+ // Copyright (c) 2026 Tymofii Pidlisnyi
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ //
4
+ // PROPOSED, OPT-IN. Deciding whether an activation condition is established at an instant.
5
+ // See ./types.ts for the specification position and for the three parameters this module
6
+ // refuses to default.
7
+ import { parseRfc3339 } from '../../core/rfc3339.js';
8
+ import { verify as verifyEd25519 } from '../../crypto/keys.js';
9
+ import { mapAuthorityValidationToLifecycle } from '../lifecycle-state/map.js';
10
+ import { lifecycleState } from '../lifecycle-state/state.js';
11
+ import { activationAttestationSignatureInput } from './canonical.js';
12
+ import { ACTIVATION_ATTESTATION_TYPE, ACTIVATION_CONDITION_TYPE, ACTIVATION_GAPS_BY_REASON, ACTIVATION_INSTANT_BASES, ActivationError, } from './types.js';
13
+ /** How far through the checks a rejected attestation got. When no record was accepted, the
14
+ * reported code is the reason of the record that got FURTHEST, so the verdict names the
15
+ * closest thing to usable evidence that was presented. Ties break on `attestation_id`
16
+ * ascending, which makes the answer independent of presentation order. */
17
+ const REJECTION_RANK = Object.freeze({
18
+ ATTESTATION_RECORD_TYPE_NOT_ACCEPTED: 1,
19
+ ATTESTATION_SIGNATURE_UNVERIFIED: 2,
20
+ ATTESTATION_ATTESTOR_BINDING_MISMATCH: 3,
21
+ ATTESTATION_ATTESTOR_ROLE_UNKNOWN: 4,
22
+ ATTESTATION_ROLE_CLAIM_CONFLICT: 5,
23
+ ATTESTATION_ATTESTOR_ROLE_MISMATCH: 6,
24
+ ATTESTATION_CONDITION_MISMATCH: 7,
25
+ ATTESTATION_UNKNOWN_ASSERTION: 8,
26
+ ATTESTATION_INSTANT_MALFORMED: 9,
27
+ ATTESTATION_DOES_NOT_REACH_ACTION: 10,
28
+ // Verdict-level codes never rank: they are not rejections of a record.
29
+ ACTIVATION_ESTABLISHED: 0,
30
+ CONDITION_DATE_NOT_REACHED: 0,
31
+ CONDITION_ESTABLISHED_NOT_YET_OCCURRED: 0,
32
+ CONDITION_FIRST_OCCURRED_AFTER_ACTION: 0,
33
+ CONDITION_EVIDENCE_CONFLICT: 0,
34
+ ACTIVATION_THRESHOLD_NOT_MET: 0,
35
+ NO_ATTESTATION_PRESENTED: 0,
36
+ CONDITION_DELEGATION_MISMATCH: 0,
37
+ });
38
+ function assertInstant(value, label) {
39
+ const parsed = parseRfc3339(value);
40
+ if (!parsed.ok) {
41
+ throw new ActivationError('INSTANT_MALFORMED', `${label} is not an RFC 3339 instant with an offset (${parsed.reason})`);
42
+ }
43
+ return parsed.ms;
44
+ }
45
+ /** Shape rules, each with the reason it exists. A condition that breaks one is a programming
46
+ * error at the caller, not a verdict about evidence, so this throws.
47
+ *
48
+ * Exported so a caller can validate a condition it received before reaching a boundary. */
49
+ export function validateActivationCondition(condition) {
50
+ if (condition === null || typeof condition !== 'object') {
51
+ throw new ActivationError('CONDITION_MALFORMED', 'condition is not an object');
52
+ }
53
+ if (condition.record_type !== ACTIVATION_CONDITION_TYPE) {
54
+ throw new ActivationError('CONDITION_RECORD_TYPE_UNKNOWN', `condition record_type must be ${ACTIVATION_CONDITION_TYPE}`);
55
+ }
56
+ for (const field of ['condition_id', 'delegation_id']) {
57
+ if (typeof condition[field] !== 'string' || condition[field].length === 0) {
58
+ throw new ActivationError('CONDITION_MALFORMED', `condition ${field} must be a non-empty string`);
59
+ }
60
+ }
61
+ if (condition.condition_type === 'date') {
62
+ assertInstant(condition.activation_date, 'condition activation_date');
63
+ return condition;
64
+ }
65
+ if (condition.condition_type === 'recorded_event') {
66
+ for (const field of ['event_type', 'event_id']) {
67
+ if (typeof condition[field] !== 'string' || condition[field].length === 0) {
68
+ throw new ActivationError('CONDITION_MALFORMED', `condition ${field} must be a non-empty string`);
69
+ }
70
+ }
71
+ const roles = condition.required_attestor_roles;
72
+ if (!Array.isArray(roles) || roles.length === 0) {
73
+ // A condition naming no accepted source has not stated what it accepts. Accepting
74
+ // anything would make the role check decorative, and refusing everything would be a
75
+ // fail-closed ruling the text does not state. Refuse the CONDITION instead.
76
+ throw new ActivationError('CONDITION_ROLES_REQUIRED', 'required_attestor_roles must name at least one role');
77
+ }
78
+ for (const role of roles) {
79
+ if (typeof role !== 'string' || role.length === 0) {
80
+ throw new ActivationError('CONDITION_ROLES_REQUIRED', 'required_attestor_roles must contain only non-empty strings');
81
+ }
82
+ }
83
+ if (!Number.isInteger(condition.threshold) || condition.threshold < 1) {
84
+ throw new ActivationError('CONDITION_THRESHOLD_INVALID', 'threshold must be an integer of at least 1, and this module declares no default');
85
+ }
86
+ if (!ACTIVATION_INSTANT_BASES.includes(condition.instant_basis)) {
87
+ throw new ActivationError('CONDITION_INSTANT_BASIS_REQUIRED', `instant_basis must be one of ${ACTIVATION_INSTANT_BASES.join(', ')}, and this module declares no default`);
88
+ }
89
+ return condition;
90
+ }
91
+ throw new ActivationError('CONDITION_TYPE_UNKNOWN', 'condition_type must be date or recorded_event');
92
+ }
93
+ function classify(attestation, condition, actionMs, input) {
94
+ const usesOwnPreimage = input.attestationPreimage === undefined;
95
+ const accepted = input.acceptedAttestationRecordTypes;
96
+ // 1. Record type. A record whose type the model has not declared it accepts for this
97
+ // condition is not evidence, however well it verifies.
98
+ if (usesOwnPreimage) {
99
+ if (attestation.record_type !== ACTIVATION_ATTESTATION_TYPE) {
100
+ return { ok: false, reason: 'ATTESTATION_RECORD_TYPE_NOT_ACCEPTED' };
101
+ }
102
+ }
103
+ else if (!accepted.includes(attestation.record_type)) {
104
+ return { ok: false, reason: 'ATTESTATION_RECORD_TYPE_NOT_ACCEPTED' };
105
+ }
106
+ // 2. Signature, over the record's own bytes, under the key authorized at `attested_at`.
107
+ if (typeof attestation.attested_at !== 'string') {
108
+ return { ok: false, reason: 'ATTESTATION_INSTANT_MALFORMED' };
109
+ }
110
+ if (!parseRfc3339(attestation.attested_at).ok) {
111
+ return { ok: false, reason: 'ATTESTATION_INSTANT_MALFORMED' };
112
+ }
113
+ if (typeof attestation.verification_method !== 'string' ||
114
+ typeof attestation.signature !== 'string' ||
115
+ typeof attestation.attestor !== 'string') {
116
+ return { ok: false, reason: 'ATTESTATION_SIGNATURE_UNVERIFIED' };
117
+ }
118
+ const resolved = input.resolveVerificationKey(attestation.attestor, attestation.verification_method, attestation.attested_at);
119
+ // A resolver failure and a missing key are the same finding here: no accepted source
120
+ // produced a key, so the record is not usable evidence. The granular key-resolution
121
+ // outcomes belong to chain verification, which reports them on its own result.
122
+ if (typeof resolved !== 'string' || resolved.length === 0) {
123
+ return { ok: false, reason: 'ATTESTATION_SIGNATURE_UNVERIFIED' };
124
+ }
125
+ const preimage = usesOwnPreimage
126
+ ? activationAttestationSignatureInput(attestation)
127
+ : input.attestationPreimage(attestation);
128
+ let signatureOk = false;
129
+ try {
130
+ signatureOk = verifyEd25519(preimage, attestation.signature, resolved);
131
+ }
132
+ catch {
133
+ signatureOk = false;
134
+ }
135
+ if (!signatureOk)
136
+ return { ok: false, reason: 'ATTESTATION_SIGNATURE_UNVERIFIED' };
137
+ // 3. The verification method has to belong to the attestor the body names, or a valid
138
+ // signature says nothing about who attested.
139
+ if (!attestation.verification_method.startsWith(`${attestation.attestor}#`)) {
140
+ return { ok: false, reason: 'ATTESTATION_ATTESTOR_BINDING_MISMATCH' };
141
+ }
142
+ // 4. The attestor's own role claim, checked AGAINST the resolver. Never believed.
143
+ if (typeof attestation.attestor_role === 'string' && attestation.attestor_role.length > 0) {
144
+ const claimed = input.resolveAttestorRole(attestation.attestor, attestation.attestor_role, attestation.attested_at);
145
+ if (claimed === 'unknown')
146
+ return { ok: false, reason: 'ATTESTATION_ATTESTOR_ROLE_UNKNOWN' };
147
+ if (claimed !== 'holds')
148
+ return { ok: false, reason: 'ATTESTATION_ROLE_CLAIM_CONFLICT' };
149
+ }
150
+ // 5. Does the attestor hold a role the condition requires? A source the model does not
151
+ // accept for THIS condition is not evidence in either direction: it cannot establish the
152
+ // condition and it cannot establish that the condition was unmet.
153
+ let holdsRequired = false;
154
+ let anyUnknown = false;
155
+ for (const role of condition.required_attestor_roles) {
156
+ const standing = input.resolveAttestorRole(attestation.attestor, role, attestation.attested_at);
157
+ if (standing === 'holds') {
158
+ holdsRequired = true;
159
+ break;
160
+ }
161
+ if (standing === 'unknown')
162
+ anyUnknown = true;
163
+ }
164
+ if (!holdsRequired) {
165
+ return {
166
+ ok: false,
167
+ reason: anyUnknown
168
+ ? 'ATTESTATION_ATTESTOR_ROLE_UNKNOWN'
169
+ : 'ATTESTATION_ATTESTOR_ROLE_MISMATCH',
170
+ };
171
+ }
172
+ // 6. Condition binding.
173
+ if (attestation.condition_id !== condition.condition_id ||
174
+ attestation.event_type !== condition.event_type ||
175
+ attestation.event_id !== condition.event_id) {
176
+ return { ok: false, reason: 'ATTESTATION_CONDITION_MISMATCH' };
177
+ }
178
+ // 7. What it establishes, measured on the instant the CONDITION declares governs.
179
+ if (attestation.assertion === 'condition_occurred') {
180
+ const raw = condition.instant_basis === 'attestation_written'
181
+ ? attestation.attested_at
182
+ : attestation.occurred_at;
183
+ if (typeof raw !== 'string')
184
+ return { ok: false, reason: 'ATTESTATION_UNKNOWN_ASSERTION' };
185
+ const parsed = parseRfc3339(raw);
186
+ if (!parsed.ok)
187
+ return { ok: false, reason: 'ATTESTATION_INSTANT_MALFORMED' };
188
+ return {
189
+ ok: true,
190
+ finding: parsed.ms <= actionMs ? 'occurred_by_action' : 'occurred_after_action',
191
+ };
192
+ }
193
+ if (attestation.assertion === 'condition_not_occurred_through') {
194
+ const raw = attestation.not_occurred_through;
195
+ if (typeof raw !== 'string')
196
+ return { ok: false, reason: 'ATTESTATION_UNKNOWN_ASSERTION' };
197
+ const parsed = parseRfc3339(raw);
198
+ if (!parsed.ok)
199
+ return { ok: false, reason: 'ATTESTATION_INSTANT_MALFORMED' };
200
+ // A negative that stops short of the action instant says nothing about the interval
201
+ // between where it stops and the action. That is the coverage limb, not a source problem.
202
+ if (parsed.ms < actionMs)
203
+ return { ok: false, reason: 'ATTESTATION_DOES_NOT_REACH_ACTION' };
204
+ return { ok: true, finding: 'not_occurred_through_action' };
205
+ }
206
+ return { ok: false, reason: 'ATTESTATION_UNKNOWN_ASSERTION' };
207
+ }
208
+ function notEstablishedFor(code) {
209
+ return lifecycleState({
210
+ verdict: 'not_established',
211
+ reason_code: code,
212
+ missing: ACTIVATION_GAPS_BY_REASON[code] ?? ['source'],
213
+ });
214
+ }
215
+ /**
216
+ * Decide whether an activation condition is established for one action at one instant.
217
+ *
218
+ * Three verdicts are reachable and `invalid` is not one of them:
219
+ *
220
+ * | situation | verdict |
221
+ * |--------------------------------------------------------------|---------------------|
222
+ * | condition established at or before the action instant | `valid` |
223
+ * | established as not met at that instant, or first met after it | `not_yet_effective` |
224
+ * | the verifier cannot tell | `not_established` |
225
+ *
226
+ * NOT ESTABLISHED IS NOT THE NEGATION OF THE CLAIM. It says the verifier could not reach a
227
+ * conclusion and names which establishment limb was missing. `not_yet_effective` says the
228
+ * verifier DID reach a conclusion and it was negative; its remedy is to wait, where
229
+ * `not_established`'s remedy is a better source. Collapsing the two throws away a decidable
230
+ * answer the verifier already had.
231
+ *
232
+ * NO RETROACTIVE ACTIVATION, KEYED ON THE CONDITION'S OWN INSTANT. A record putting the
233
+ * condition's first occurrence after the action instant leaves that action
234
+ * `not_yet_effective`, and the SAME record establishes the condition for any later action.
235
+ * What the rule keys on is the condition's instant, not the instant someone wrote the record:
236
+ * learning on Thursday that a condition was met on Monday is the normal case for any model
237
+ * built around an after-the-fact determination, and under
238
+ * `instant_basis: 'condition_occurrence'` such a record establishes the condition. A model
239
+ * that reads it the other way says so with `instant_basis: 'attestation_written'`.
240
+ *
241
+ * ORDER OF RESOLUTION, and why contradiction sits above acceptance:
242
+ *
243
+ * 1. two accepted records that disagree `not_established`, `CONDITION_EVIDENCE_CONFLICT`
244
+ * 2. `threshold` records say occurred by it `valid`
245
+ * 3. `threshold` records say not occurred `not_yet_effective`
246
+ * 4. `threshold` records say occurred after `not_yet_effective`
247
+ * 5. some accepted, fewer than `threshold` `not_established`, `ACTIVATION_THRESHOLD_NOT_MET`
248
+ * 6. none accepted `not_established`, furthest rejection reason
249
+ *
250
+ * Contradiction is evaluated on PRESENCE, not on counts. Two acceptable records that disagree
251
+ * leave the verifier unable to tell which holds, and neither is discarded in favour of the
252
+ * other: preferring the later record, or the negative one, or a majority, would each be a
253
+ * precedence rule the concept text does not state.
254
+ *
255
+ * This function reads no clock and makes no network call. `actionInstant` is a parameter.
256
+ *
257
+ * Proposed. Concept source: aeoess/agent-authority-lifecycle, invariant candidates CAND-04
258
+ * and CAND-13 (activation half) and BROAD-L7. Not required by draft-pidlisnyi-aps-03.
259
+ */
260
+ export function verifyActivation(input) {
261
+ if (input === null || typeof input !== 'object') {
262
+ throw new ActivationError('INPUT_MALFORMED', 'input is not an object');
263
+ }
264
+ if (typeof input.resolveAttestorRole !== 'function') {
265
+ throw new ActivationError('ROLE_RESOLVER_REQUIRED', 'resolveAttestorRole is required: role standing is resolved outside the record, always');
266
+ }
267
+ if (typeof input.resolveVerificationKey !== 'function') {
268
+ throw new ActivationError('KEY_RESOLVER_REQUIRED', 'resolveVerificationKey is required');
269
+ }
270
+ if (input.attestationPreimage !== undefined) {
271
+ const accepted = input.acceptedAttestationRecordTypes;
272
+ if (!Array.isArray(accepted) || accepted.length === 0) {
273
+ throw new ActivationError('ACCEPTED_RECORD_TYPES_REQUIRED', 'acceptedAttestationRecordTypes must name at least one type when attestationPreimage is supplied');
274
+ }
275
+ }
276
+ if (typeof input.delegationId !== 'string' || input.delegationId.length === 0) {
277
+ throw new ActivationError('DELEGATION_ID_REQUIRED', 'delegationId must be a non-empty string');
278
+ }
279
+ const condition = validateActivationCondition(input.condition);
280
+ const actionMs = assertInstant(input.actionInstant, 'actionInstant');
281
+ const presented = input.attestations ?? [];
282
+ if (condition.delegation_id !== input.delegationId) {
283
+ return Object.freeze({
284
+ state: notEstablishedFor('CONDITION_DELEGATION_MISMATCH'),
285
+ condition_id: condition.condition_id,
286
+ condition_type: condition.condition_type,
287
+ findings: Object.freeze([]),
288
+ rejections: Object.freeze([]),
289
+ });
290
+ }
291
+ // A date condition needs no evidence at all. The verifier reads the date off the condition
292
+ // and compares it with the action instant, so an unreached date is a KNOWN negative and
293
+ // never an unknown one. Presented attestations are not consulted.
294
+ if (condition.condition_type === 'date') {
295
+ const reached = assertInstant(condition.activation_date, 'condition activation_date') <= actionMs;
296
+ return Object.freeze({
297
+ state: reached
298
+ ? lifecycleState({ verdict: 'valid', reason_code: 'ACTIVATION_ESTABLISHED' })
299
+ : lifecycleState({
300
+ verdict: 'not_yet_effective',
301
+ reason_code: 'CONDITION_DATE_NOT_REACHED',
302
+ }),
303
+ condition_id: condition.condition_id,
304
+ condition_type: condition.condition_type,
305
+ findings: Object.freeze([]),
306
+ rejections: Object.freeze([]),
307
+ });
308
+ }
309
+ const findings = [];
310
+ const rejections = [];
311
+ const counts = {
312
+ occurred_by_action: 0,
313
+ occurred_after_action: 0,
314
+ not_occurred_through_action: 0,
315
+ };
316
+ for (const attestation of presented) {
317
+ if (attestation === null || typeof attestation !== 'object') {
318
+ throw new ActivationError('ATTESTATION_MALFORMED', 'an attestation is not an object');
319
+ }
320
+ const id = typeof attestation.attestation_id === 'string' ? attestation.attestation_id : '';
321
+ const attestor = typeof attestation.attestor === 'string' ? attestation.attestor : '';
322
+ const outcome = classify(attestation, condition, actionMs, input);
323
+ if (outcome.ok) {
324
+ counts[outcome.finding] += 1;
325
+ findings.push(Object.freeze({ attestation_id: id, attestor, finding: outcome.finding }));
326
+ }
327
+ else {
328
+ rejections.push(Object.freeze({ attestation_id: id, attestor, reason_code: outcome.reason }));
329
+ }
330
+ }
331
+ const frozen = {
332
+ condition_id: condition.condition_id,
333
+ condition_type: condition.condition_type,
334
+ findings: Object.freeze([...findings]),
335
+ rejections: Object.freeze([...rejections]),
336
+ };
337
+ if (counts.occurred_by_action > 0 && counts.not_occurred_through_action > 0) {
338
+ return Object.freeze({ ...frozen, state: notEstablishedFor('CONDITION_EVIDENCE_CONFLICT') });
339
+ }
340
+ if (counts.occurred_by_action >= condition.threshold) {
341
+ return Object.freeze({
342
+ ...frozen,
343
+ state: lifecycleState({ verdict: 'valid', reason_code: 'ACTIVATION_ESTABLISHED' }),
344
+ });
345
+ }
346
+ if (counts.not_occurred_through_action >= condition.threshold) {
347
+ return Object.freeze({
348
+ ...frozen,
349
+ state: lifecycleState({
350
+ verdict: 'not_yet_effective',
351
+ reason_code: 'CONDITION_ESTABLISHED_NOT_YET_OCCURRED',
352
+ }),
353
+ });
354
+ }
355
+ if (counts.occurred_after_action >= condition.threshold) {
356
+ return Object.freeze({
357
+ ...frozen,
358
+ state: lifecycleState({
359
+ verdict: 'not_yet_effective',
360
+ reason_code: 'CONDITION_FIRST_OCCURRED_AFTER_ACTION',
361
+ }),
362
+ });
363
+ }
364
+ if (findings.length > 0) {
365
+ return Object.freeze({ ...frozen, state: notEstablishedFor('ACTIVATION_THRESHOLD_NOT_MET') });
366
+ }
367
+ if (rejections.length === 0) {
368
+ return Object.freeze({ ...frozen, state: notEstablishedFor('NO_ATTESTATION_PRESENTED') });
369
+ }
370
+ const furthest = [...rejections].sort((a, b) => {
371
+ const rank = REJECTION_RANK[b.reason_code] - REJECTION_RANK[a.reason_code];
372
+ return rank !== 0 ? rank : a.attestation_id.localeCompare(b.attestation_id);
373
+ })[0];
374
+ return Object.freeze({ ...frozen, state: notEstablishedFor(furthest.reason_code) });
375
+ }
376
+ /**
377
+ * Report an activation result ALONGSIDE a chain result, never merged into it.
378
+ *
379
+ * Two stages, in order, and the order is the point:
380
+ *
381
+ * 1. Chain verification decides whether the grant is valid at the action instant. Its
382
+ * four-value result is returned untouched in `chain`.
383
+ * 2. Activation is asked ONLY when the chain is valid. A grant that does not verify is not a
384
+ * grant that is waiting on a condition, and reporting `not_yet_effective` for a revoked
385
+ * or unparented grant would say the remedy is to wait when it is not.
386
+ *
387
+ * This is also where CAND-13's activation half lands. A pre-committed replacement grant is an
388
+ * ordinary grant with an ordinary condition, so it needs no separate machinery here, and the
389
+ * ordering is what keeps L1 intact: if the pre-committing instrument is revoked, the
390
+ * replacement's chain is invalid and no activation evidence can make it exercisable. Nothing
391
+ * in this module can turn an invalid chain into a `valid` lifecycle verdict.
392
+ *
393
+ * `activation` may be `null`, which is how a caller says no activation module ran. The
394
+ * composite then carries only the chain's own reading.
395
+ *
396
+ * Proposed. Concept source: aeoess/agent-authority-lifecycle, invariant L1 and invariant
397
+ * candidates CAND-04 and CAND-13.
398
+ */
399
+ export function composeActivation(chain, activation, options = {}) {
400
+ const mapped = mapAuthorityValidationToLifecycle(chain, options.mapping ?? {});
401
+ if (chain.state !== 'valid' || activation === null) {
402
+ return Object.freeze({ chain, lifecycle: mapped });
403
+ }
404
+ return Object.freeze({ chain, lifecycle: activation.state });
405
+ }
406
+ //# sourceMappingURL=verify.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify.js","sourceRoot":"","sources":["../../../../src/v2/activation/verify.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,sCAAsC;AACtC,EAAE;AACF,2FAA2F;AAC3F,yFAAyF;AACzF,sBAAsB;AAEtB,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AACpD,OAAO,EAAE,MAAM,IAAI,aAAa,EAAE,MAAM,sBAAsB,CAAA;AAM9D,OAAO,EAAE,iCAAiC,EAAE,MAAM,2BAA2B,CAAA;AAC7E,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAA;AAK5D,OAAO,EAAE,mCAAmC,EAAE,MAAM,gBAAgB,CAAA;AACpE,OAAO,EACL,2BAA2B,EAC3B,yBAAyB,EACzB,yBAAyB,EACzB,wBAAwB,EACxB,eAAe,GAUhB,MAAM,YAAY,CAAA;AAEnB;;;2EAG2E;AAC3E,MAAM,cAAc,GAAmD,MAAM,CAAC,MAAM,CAAC;IACnF,oCAAoC,EAAE,CAAC;IACvC,gCAAgC,EAAE,CAAC;IACnC,qCAAqC,EAAE,CAAC;IACxC,iCAAiC,EAAE,CAAC;IACpC,+BAA+B,EAAE,CAAC;IAClC,kCAAkC,EAAE,CAAC;IACrC,8BAA8B,EAAE,CAAC;IACjC,6BAA6B,EAAE,CAAC;IAChC,6BAA6B,EAAE,CAAC;IAChC,iCAAiC,EAAE,EAAE;IACrC,uEAAuE;IACvE,sBAAsB,EAAE,CAAC;IACzB,0BAA0B,EAAE,CAAC;IAC7B,sCAAsC,EAAE,CAAC;IACzC,qCAAqC,EAAE,CAAC;IACxC,2BAA2B,EAAE,CAAC;IAC9B,4BAA4B,EAAE,CAAC;IAC/B,wBAAwB,EAAE,CAAC;IAC3B,6BAA6B,EAAE,CAAC;CACjC,CAAC,CAAA;AAyCF,SAAS,aAAa,CAAC,KAAa,EAAE,KAAa;IACjD,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAA;IAClC,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;QACf,MAAM,IAAI,eAAe,CACvB,mBAAmB,EACnB,GAAG,KAAK,+CAA+C,MAAM,CAAC,MAAM,GAAG,CACxE,CAAA;IACH,CAAC;IACD,OAAO,MAAM,CAAC,EAAE,CAAA;AAClB,CAAC;AAED;;;4FAG4F;AAC5F,MAAM,UAAU,2BAA2B,CACzC,SAAgC;IAEhC,IAAI,SAAS,KAAK,IAAI,IAAI,OAAO,SAAS,KAAK,QAAQ,EAAE,CAAC;QACxD,MAAM,IAAI,eAAe,CAAC,qBAAqB,EAAE,4BAA4B,CAAC,CAAA;IAChF,CAAC;IACD,IAAI,SAAS,CAAC,WAAW,KAAK,yBAAyB,EAAE,CAAC;QACxD,MAAM,IAAI,eAAe,CACvB,+BAA+B,EAC/B,iCAAiC,yBAAyB,EAAE,CAC7D,CAAA;IACH,CAAC;IACD,KAAK,MAAM,KAAK,IAAI,CAAC,cAAc,EAAE,eAAe,CAAU,EAAE,CAAC;QAC/D,IAAI,OAAO,SAAS,CAAC,KAAK,CAAC,KAAK,QAAQ,IAAI,SAAS,CAAC,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC1E,MAAM,IAAI,eAAe,CACvB,qBAAqB,EACrB,aAAa,KAAK,6BAA6B,CAChD,CAAA;QACH,CAAC;IACH,CAAC;IAED,IAAI,SAAS,CAAC,cAAc,KAAK,MAAM,EAAE,CAAC;QACxC,aAAa,CAAC,SAAS,CAAC,eAAe,EAAE,2BAA2B,CAAC,CAAA;QACrE,OAAO,SAAS,CAAA;IAClB,CAAC;IAED,IAAI,SAAS,CAAC,cAAc,KAAK,gBAAgB,EAAE,CAAC;QAClD,KAAK,MAAM,KAAK,IAAI,CAAC,YAAY,EAAE,UAAU,CAAU,EAAE,CAAC;YACxD,IAAI,OAAO,SAAS,CAAC,KAAK,CAAC,KAAK,QAAQ,IAAI,SAAS,CAAC,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC1E,MAAM,IAAI,eAAe,CACvB,qBAAqB,EACrB,aAAa,KAAK,6BAA6B,CAChD,CAAA;YACH,CAAC;QACH,CAAC;QACD,MAAM,KAAK,GAAG,SAAS,CAAC,uBAAuB,CAAA;QAC/C,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAChD,kFAAkF;YAClF,oFAAoF;YACpF,4EAA4E;YAC5E,MAAM,IAAI,eAAe,CACvB,0BAA0B,EAC1B,qDAAqD,CACtD,CAAA;QACH,CAAC;QACD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAClD,MAAM,IAAI,eAAe,CACvB,0BAA0B,EAC1B,6DAA6D,CAC9D,CAAA;YACH,CAAC;QACH,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,SAAS,CAAC,IAAI,SAAS,CAAC,SAAS,GAAG,CAAC,EAAE,CAAC;YACtE,MAAM,IAAI,eAAe,CACvB,6BAA6B,EAC7B,iFAAiF,CAClF,CAAA;QACH,CAAC;QACD,IAAI,CAAE,wBAA8C,CAAC,QAAQ,CAAC,SAAS,CAAC,aAAa,CAAC,EAAE,CAAC;YACvF,MAAM,IAAI,eAAe,CACvB,kCAAkC,EAClC,gCAAgC,wBAAwB,CAAC,IAAI,CAAC,IAAI,CAAC,uCAAuC,CAC3G,CAAA;QACH,CAAC;QACD,OAAO,SAAS,CAAA;IAClB,CAAC;IAED,MAAM,IAAI,eAAe,CACvB,wBAAwB,EACxB,+CAA+C,CAChD,CAAA;AACH,CAAC;AAMD,SAAS,QAAQ,CACf,WAAoC,EACpC,SAA6C,EAC7C,QAAgB,EAChB,KAAkC;IAElC,MAAM,eAAe,GAAG,KAAK,CAAC,mBAAmB,KAAK,SAAS,CAAA;IAC/D,MAAM,QAAQ,GAAG,KAAK,CAAC,8BAA8B,CAAA;IAErD,qFAAqF;IACrF,0DAA0D;IAC1D,IAAI,eAAe,EAAE,CAAC;QACpB,IAAI,WAAW,CAAC,WAAW,KAAK,2BAA2B,EAAE,CAAC;YAC5D,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,sCAAsC,EAAE,CAAA;QACtE,CAAC;IACH,CAAC;SAAM,IAAI,CAAC,QAAS,CAAC,QAAQ,CAAC,WAAW,CAAC,WAAW,CAAC,EAAE,CAAC;QACxD,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,sCAAsC,EAAE,CAAA;IACtE,CAAC;IAED,wFAAwF;IACxF,IAAI,OAAO,WAAW,CAAC,WAAW,KAAK,QAAQ,EAAE,CAAC;QAChD,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,+BAA+B,EAAE,CAAA;IAC/D,CAAC;IACD,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC,EAAE,EAAE,CAAC;QAC9C,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,+BAA+B,EAAE,CAAA;IAC/D,CAAC;IACD,IACE,OAAO,WAAW,CAAC,mBAAmB,KAAK,QAAQ;QACnD,OAAO,WAAW,CAAC,SAAS,KAAK,QAAQ;QACzC,OAAO,WAAW,CAAC,QAAQ,KAAK,QAAQ,EACxC,CAAC;QACD,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,kCAAkC,EAAE,CAAA;IAClE,CAAC;IACD,MAAM,QAAQ,GAAG,KAAK,CAAC,sBAAsB,CAC3C,WAAW,CAAC,QAAQ,EACpB,WAAW,CAAC,mBAAmB,EAC/B,WAAW,CAAC,WAAW,CACxB,CAAA;IACD,qFAAqF;IACrF,oFAAoF;IACpF,+EAA+E;IAC/E,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1D,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,kCAAkC,EAAE,CAAA;IAClE,CAAC;IACD,MAAM,QAAQ,GAAG,eAAe;QAC9B,CAAC,CAAC,mCAAmC,CAAC,WAAW,CAAC;QAClD,CAAC,CAAC,KAAK,CAAC,mBAAoB,CAAC,WAAW,CAAC,CAAA;IAC3C,IAAI,WAAW,GAAG,KAAK,CAAA;IACvB,IAAI,CAAC;QACH,WAAW,GAAG,aAAa,CAAC,QAAQ,EAAE,WAAW,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAA;IACxE,CAAC;IAAC,MAAM,CAAC;QACP,WAAW,GAAG,KAAK,CAAA;IACrB,CAAC;IACD,IAAI,CAAC,WAAW;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,kCAAkC,EAAE,CAAA;IAElF,sFAAsF;IACtF,gDAAgD;IAChD,IAAI,CAAC,WAAW,CAAC,mBAAmB,CAAC,UAAU,CAAC,GAAG,WAAW,CAAC,QAAQ,GAAG,CAAC,EAAE,CAAC;QAC5E,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,uCAAuC,EAAE,CAAA;IACvE,CAAC;IAED,kFAAkF;IAClF,IAAI,OAAO,WAAW,CAAC,aAAa,KAAK,QAAQ,IAAI,WAAW,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC1F,MAAM,OAAO,GAAG,KAAK,CAAC,mBAAmB,CACvC,WAAW,CAAC,QAAQ,EACpB,WAAW,CAAC,aAAa,EACzB,WAAW,CAAC,WAAW,CACxB,CAAA;QACD,IAAI,OAAO,KAAK,SAAS;YAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,mCAAmC,EAAE,CAAA;QAC5F,IAAI,OAAO,KAAK,OAAO;YAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,iCAAiC,EAAE,CAAA;IAC1F,CAAC;IAED,uFAAuF;IACvF,4FAA4F;IAC5F,qEAAqE;IACrE,IAAI,aAAa,GAAG,KAAK,CAAA;IACzB,IAAI,UAAU,GAAG,KAAK,CAAA;IACtB,KAAK,MAAM,IAAI,IAAI,SAAS,CAAC,uBAAuB,EAAE,CAAC;QACrD,MAAM,QAAQ,GAAG,KAAK,CAAC,mBAAmB,CAAC,WAAW,CAAC,QAAQ,EAAE,IAAI,EAAE,WAAW,CAAC,WAAW,CAAC,CAAA;QAC/F,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;YACzB,aAAa,GAAG,IAAI,CAAA;YACpB,MAAK;QACP,CAAC;QACD,IAAI,QAAQ,KAAK,SAAS;YAAE,UAAU,GAAG,IAAI,CAAA;IAC/C,CAAC;IACD,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,OAAO;YACL,EAAE,EAAE,KAAK;YACT,MAAM,EAAE,UAAU;gBAChB,CAAC,CAAC,mCAAmC;gBACrC,CAAC,CAAC,oCAAoC;SACzC,CAAA;IACH,CAAC;IAED,wBAAwB;IACxB,IACE,WAAW,CAAC,YAAY,KAAK,SAAS,CAAC,YAAY;QACnD,WAAW,CAAC,UAAU,KAAK,SAAS,CAAC,UAAU;QAC/C,WAAW,CAAC,QAAQ,KAAK,SAAS,CAAC,QAAQ,EAC3C,CAAC;QACD,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,gCAAgC,EAAE,CAAA;IAChE,CAAC;IAED,kFAAkF;IAClF,IAAI,WAAW,CAAC,SAAS,KAAK,oBAAoB,EAAE,CAAC;QACnD,MAAM,GAAG,GACP,SAAS,CAAC,aAAa,KAAK,qBAAqB;YAC/C,CAAC,CAAC,WAAW,CAAC,WAAW;YACzB,CAAC,CAAC,WAAW,CAAC,WAAW,CAAA;QAC7B,IAAI,OAAO,GAAG,KAAK,QAAQ;YAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,+BAA+B,EAAE,CAAA;QAC1F,MAAM,MAAM,GAAG,YAAY,CAAC,GAAG,CAAC,CAAA;QAChC,IAAI,CAAC,MAAM,CAAC,EAAE;YAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,+BAA+B,EAAE,CAAA;QAC7E,OAAO;YACL,EAAE,EAAE,IAAI;YACR,OAAO,EAAE,MAAM,CAAC,EAAE,IAAI,QAAQ,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,uBAAuB;SAChF,CAAA;IACH,CAAC;IAED,IAAI,WAAW,CAAC,SAAS,KAAK,gCAAgC,EAAE,CAAC;QAC/D,MAAM,GAAG,GAAG,WAAW,CAAC,oBAAoB,CAAA;QAC5C,IAAI,OAAO,GAAG,KAAK,QAAQ;YAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,+BAA+B,EAAE,CAAA;QAC1F,MAAM,MAAM,GAAG,YAAY,CAAC,GAAG,CAAC,CAAA;QAChC,IAAI,CAAC,MAAM,CAAC,EAAE;YAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,+BAA+B,EAAE,CAAA;QAC7E,oFAAoF;QACpF,0FAA0F;QAC1F,IAAI,MAAM,CAAC,EAAE,GAAG,QAAQ;YAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,mCAAmC,EAAE,CAAA;QAC3F,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,6BAA6B,EAAE,CAAA;IAC7D,CAAC;IAED,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,+BAA+B,EAAE,CAAA;AAC/D,CAAC;AAED,SAAS,iBAAiB,CAAC,IAA0B;IACnD,OAAO,cAAc,CAAC;QACpB,OAAO,EAAE,iBAAiB;QAC1B,WAAW,EAAE,IAAI;QACjB,OAAO,EAAE,yBAAyB,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC;KACvD,CAAC,CAAA;AACJ,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAkC;IACjE,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAChD,MAAM,IAAI,eAAe,CAAC,iBAAiB,EAAE,wBAAwB,CAAC,CAAA;IACxE,CAAC;IACD,IAAI,OAAO,KAAK,CAAC,mBAAmB,KAAK,UAAU,EAAE,CAAC;QACpD,MAAM,IAAI,eAAe,CACvB,wBAAwB,EACxB,uFAAuF,CACxF,CAAA;IACH,CAAC;IACD,IAAI,OAAO,KAAK,CAAC,sBAAsB,KAAK,UAAU,EAAE,CAAC;QACvD,MAAM,IAAI,eAAe,CAAC,uBAAuB,EAAE,oCAAoC,CAAC,CAAA;IAC1F,CAAC;IACD,IAAI,KAAK,CAAC,mBAAmB,KAAK,SAAS,EAAE,CAAC;QAC5C,MAAM,QAAQ,GAAG,KAAK,CAAC,8BAA8B,CAAA;QACrD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtD,MAAM,IAAI,eAAe,CACvB,gCAAgC,EAChC,iGAAiG,CAClG,CAAA;QACH,CAAC;IACH,CAAC;IACD,IAAI,OAAO,KAAK,CAAC,YAAY,KAAK,QAAQ,IAAI,KAAK,CAAC,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC9E,MAAM,IAAI,eAAe,CAAC,wBAAwB,EAAE,yCAAyC,CAAC,CAAA;IAChG,CAAC;IAED,MAAM,SAAS,GAAG,2BAA2B,CAAC,KAAK,CAAC,SAAS,CAAC,CAAA;IAC9D,MAAM,QAAQ,GAAG,aAAa,CAAC,KAAK,CAAC,aAAa,EAAE,eAAe,CAAC,CAAA;IACpE,MAAM,SAAS,GAAG,KAAK,CAAC,YAAY,IAAI,EAAE,CAAA;IAE1C,IAAI,SAAS,CAAC,aAAa,KAAK,KAAK,CAAC,YAAY,EAAE,CAAC;QACnD,OAAO,MAAM,CAAC,MAAM,CAAC;YACnB,KAAK,EAAE,iBAAiB,CAAC,+BAA+B,CAAC;YACzD,YAAY,EAAE,SAAS,CAAC,YAAY;YACpC,cAAc,EAAE,SAAS,CAAC,cAAc;YACxC,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;YAC3B,UAAU,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;SAC9B,CAAC,CAAA;IACJ,CAAC;IAED,2FAA2F;IAC3F,wFAAwF;IACxF,kEAAkE;IAClE,IAAI,SAAS,CAAC,cAAc,KAAK,MAAM,EAAE,CAAC;QACxC,MAAM,OAAO,GAAG,aAAa,CAAC,SAAS,CAAC,eAAe,EAAE,2BAA2B,CAAC,IAAI,QAAQ,CAAA;QACjG,OAAO,MAAM,CAAC,MAAM,CAAC;YACnB,KAAK,EAAE,OAAO;gBACZ,CAAC,CAAC,cAAc,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,wBAAwB,EAAE,CAAC;gBAC7E,CAAC,CAAC,cAAc,CAAC;oBACb,OAAO,EAAE,mBAAmB;oBAC5B,WAAW,EAAE,4BAA4B;iBAC1C,CAAC;YACN,YAAY,EAAE,SAAS,CAAC,YAAY;YACpC,cAAc,EAAE,SAAS,CAAC,cAAc;YACxC,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;YAC3B,UAAU,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;SAC9B,CAAC,CAAA;IACJ,CAAC;IAED,MAAM,QAAQ,GAAwB,EAAE,CAAA;IACxC,MAAM,UAAU,GAA0B,EAAE,CAAA;IAC5C,MAAM,MAAM,GAA0C;QACpD,kBAAkB,EAAE,CAAC;QACrB,qBAAqB,EAAE,CAAC;QACxB,2BAA2B,EAAE,CAAC;KAC/B,CAAA;IAED,KAAK,MAAM,WAAW,IAAI,SAAS,EAAE,CAAC;QACpC,IAAI,WAAW,KAAK,IAAI,IAAI,OAAO,WAAW,KAAK,QAAQ,EAAE,CAAC;YAC5D,MAAM,IAAI,eAAe,CAAC,uBAAuB,EAAE,iCAAiC,CAAC,CAAA;QACvF,CAAC;QACD,MAAM,EAAE,GAAG,OAAO,WAAW,CAAC,cAAc,KAAK,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,CAAA;QAC3F,MAAM,QAAQ,GAAG,OAAO,WAAW,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAA;QACrF,MAAM,OAAO,GAAG,QAAQ,CAAC,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAA;QACjE,IAAI,OAAO,CAAC,EAAE,EAAE,CAAC;YACf,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;YAC5B,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,cAAc,EAAE,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAAA;QAC1F,CAAC;aAAM,CAAC;YACN,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,cAAc,EAAE,EAAE,EAAE,QAAQ,EAAE,WAAW,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAA;QAC/F,CAAC;IACH,CAAC;IAED,MAAM,MAAM,GAAG;QACb,YAAY,EAAE,SAAS,CAAC,YAAY;QACpC,cAAc,EAAE,SAAS,CAAC,cAAc;QACxC,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC;QACtC,UAAU,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC;KAC3C,CAAA;IAED,IAAI,MAAM,CAAC,kBAAkB,GAAG,CAAC,IAAI,MAAM,CAAC,2BAA2B,GAAG,CAAC,EAAE,CAAC;QAC5E,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,MAAM,EAAE,KAAK,EAAE,iBAAiB,CAAC,6BAA6B,CAAC,EAAE,CAAC,CAAA;IAC9F,CAAC;IACD,IAAI,MAAM,CAAC,kBAAkB,IAAI,SAAS,CAAC,SAAS,EAAE,CAAC;QACrD,OAAO,MAAM,CAAC,MAAM,CAAC;YACnB,GAAG,MAAM;YACT,KAAK,EAAE,cAAc,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,wBAAwB,EAAE,CAAC;SACnF,CAAC,CAAA;IACJ,CAAC;IACD,IAAI,MAAM,CAAC,2BAA2B,IAAI,SAAS,CAAC,SAAS,EAAE,CAAC;QAC9D,OAAO,MAAM,CAAC,MAAM,CAAC;YACnB,GAAG,MAAM;YACT,KAAK,EAAE,cAAc,CAAC;gBACpB,OAAO,EAAE,mBAAmB;gBAC5B,WAAW,EAAE,wCAAwC;aACtD,CAAC;SACH,CAAC,CAAA;IACJ,CAAC;IACD,IAAI,MAAM,CAAC,qBAAqB,IAAI,SAAS,CAAC,SAAS,EAAE,CAAC;QACxD,OAAO,MAAM,CAAC,MAAM,CAAC;YACnB,GAAG,MAAM;YACT,KAAK,EAAE,cAAc,CAAC;gBACpB,OAAO,EAAE,mBAAmB;gBAC5B,WAAW,EAAE,uCAAuC;aACrD,CAAC;SACH,CAAC,CAAA;IACJ,CAAC;IACD,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,MAAM,EAAE,KAAK,EAAE,iBAAiB,CAAC,8BAA8B,CAAC,EAAE,CAAC,CAAA;IAC/F,CAAC;IAED,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5B,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,MAAM,EAAE,KAAK,EAAE,iBAAiB,CAAC,0BAA0B,CAAC,EAAE,CAAC,CAAA;IAC3F,CAAC;IACD,MAAM,QAAQ,GAAG,CAAC,GAAG,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QAC7C,MAAM,IAAI,GAAG,cAAc,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,cAAc,CAAC,CAAC,CAAC,WAAW,CAAC,CAAA;QAC1E,OAAO,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,aAAa,CAAC,CAAC,CAAC,cAAc,CAAC,CAAA;IAC7E,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IACL,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,MAAM,EAAE,KAAK,EAAE,iBAAiB,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC,CAAA;AACrF,CAAC;AAiBD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,UAAU,iBAAiB,CAC/B,KAAgC,EAChC,UAAmC,EACnC,OAAO,GAAiC,EAAE;IAE1C,MAAM,MAAM,GAAG,iCAAiC,CAAC,KAAK,EAAE,OAAO,CAAC,OAAO,IAAI,EAAE,CAAC,CAAA;IAC9E,IAAI,KAAK,CAAC,KAAK,KAAK,OAAO,IAAI,UAAU,KAAK,IAAI,EAAE,CAAC;QACnD,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC,CAAA;IACpD,CAAC;IACD,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,UAAU,CAAC,KAAK,EAAE,CAAC,CAAA;AAC9D,CAAC"}
@@ -0,0 +1,49 @@
1
+ import type { FencedWrite, FencedWriteOutcome, StateMarker } from './types.js';
2
+ /**
3
+ * An authority-state publication log with a fencing gate on every write.
4
+ *
5
+ * Generic in the payload on purpose: this class orders writes and stores nothing about
6
+ * authority itself. The payload is whatever the deployment publishes as a state view, a
7
+ * store handle, a snapshot identifier or a record set. The SDK has no opinion about it.
8
+ *
9
+ * The gate, in one line each:
10
+ *
11
+ * - a token BELOW the highest already accepted is refused, `stale_fencing_token`
12
+ * - a token EQUAL to it is accepted, because equal has not gone backwards: the same holder
13
+ * is retrying, and the retry is idempotent
14
+ * - a token ABOVE it is accepted, and so is a token the log has never seen before, as long
15
+ * as it does not go backwards. The gate fences state that is behind, not state that
16
+ * merely differs
17
+ * - a token counted in a DIFFERENT SCOPE from the log's is refused,
18
+ * `fencing_scope_mismatch`, and an absent or malformed token is refused
19
+ * `fencing_token_unreadable`. Two markers from different scopes order nothing, and a
20
+ * write path that cannot order a token is not fenced. Neither refusal is in any source;
21
+ * both are this module's choice, and they are kept apart because an unreadable token is
22
+ * a different finding from a backwards one
23
+ *
24
+ * A refused write changes nothing: not the published payload, not the highest token. That
25
+ * is the property the whole class exists for, and a caller reads `accepted` to learn which
26
+ * of the two happened rather than comparing payloads.
27
+ *
28
+ * NOT DURABLE, NOT CONCURRENT, NOT A LOCK SERVICE. This holds one token and one payload in
29
+ * this process's heap. It acquires no lock, contacts no lock service, and its check-then-set
30
+ * is one synchronous statement sequence, which is safe on this runtime and is a property of
31
+ * the runtime rather than a pattern a durable store may copy. The same warning
32
+ * `InMemoryAuthorityRevocationStore` carries applies here for the same reason.
33
+ */
34
+ export declare class FencedAuthorityStateLog<T> {
35
+ private highest;
36
+ private payload;
37
+ private written;
38
+ /** The highest token accepted so far, or `null` when nothing has been published. */
39
+ highestToken(): StateMarker | null;
40
+ /** What is published now. `undefined` when no write has landed, which a caller must tell
41
+ * apart from a write that landed carrying `undefined`; `hasPublished()` is how. */
42
+ published(): T | undefined;
43
+ hasPublished(): boolean;
44
+ /** Submit a write. See the class doc for the four outcomes. Never throws for a malformed
45
+ * token: an unreadable token is one that cannot be shown to have moved forward, so it is
46
+ * refused. */
47
+ write(write: FencedWrite<T>): FencedWriteOutcome<T>;
48
+ }
49
+ //# sourceMappingURL=fencing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fencing.d.ts","sourceRoot":"","sources":["../../../../src/v2/authority-state/fencing.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,WAAW,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAE9E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,qBAAa,uBAAuB,CAAC,CAAC;IACpC,OAAO,CAAC,OAAO,CAA2B;IAC1C,OAAO,CAAC,OAAO,CAA2B;IAC1C,OAAO,CAAC,OAAO,CAAQ;IAEvB,oFAAoF;IACpF,YAAY,IAAI,WAAW,GAAG,IAAI,CAEjC;IAED;wFACoF;IACpF,SAAS,IAAI,CAAC,GAAG,SAAS,CAEzB;IAED,YAAY,IAAI,OAAO,CAEtB;IAED;;mBAEe;IACf,KAAK,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC,GAAG,kBAAkB,CAAC,CAAC,CAAC,CAmBlD;CACF"}
@@ -0,0 +1,92 @@
1
+ // Copyright (c) 2026 Tymofii Pidlisnyi
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ //
4
+ // PROPOSED, OPT-IN. Fencing on the authority-state WRITE path.
5
+ // See ./types.ts for the specification position. Proposed.
6
+ //
7
+ // WHY THIS IS A SEPARATE AXIS FROM THE READ PATH. A read-side high-water mark protects one
8
+ // verifier that has already seen the newer state. It does nothing for a verifier that has
9
+ // seen nothing, reading a published view that a stale writer republished underneath it. A
10
+ // partition that resolves the wrong way rolls authority back with no restore involved, and
11
+ // the read path never sees a regression because the published state simply IS the old
12
+ // state. So the check has to exist where the write lands.
13
+ //
14
+ // The rule implemented here is the one Kleppmann's "How to do distributed locking" states:
15
+ // the storage server takes an active role in checking tokens and rejects any write on which
16
+ // the token has gone backwards. `OPEN-QUESTIONS.md` names authority rollback as open and
17
+ // names an append-only revocation log a restore must replay as the other candidate
18
+ // mechanism in the same sentence. That one is NOT modelled here. Neither is specified.
19
+ import { compareStateMarker, sameScope } from './marker.js';
20
+ /**
21
+ * An authority-state publication log with a fencing gate on every write.
22
+ *
23
+ * Generic in the payload on purpose: this class orders writes and stores nothing about
24
+ * authority itself. The payload is whatever the deployment publishes as a state view, a
25
+ * store handle, a snapshot identifier or a record set. The SDK has no opinion about it.
26
+ *
27
+ * The gate, in one line each:
28
+ *
29
+ * - a token BELOW the highest already accepted is refused, `stale_fencing_token`
30
+ * - a token EQUAL to it is accepted, because equal has not gone backwards: the same holder
31
+ * is retrying, and the retry is idempotent
32
+ * - a token ABOVE it is accepted, and so is a token the log has never seen before, as long
33
+ * as it does not go backwards. The gate fences state that is behind, not state that
34
+ * merely differs
35
+ * - a token counted in a DIFFERENT SCOPE from the log's is refused,
36
+ * `fencing_scope_mismatch`, and an absent or malformed token is refused
37
+ * `fencing_token_unreadable`. Two markers from different scopes order nothing, and a
38
+ * write path that cannot order a token is not fenced. Neither refusal is in any source;
39
+ * both are this module's choice, and they are kept apart because an unreadable token is
40
+ * a different finding from a backwards one
41
+ *
42
+ * A refused write changes nothing: not the published payload, not the highest token. That
43
+ * is the property the whole class exists for, and a caller reads `accepted` to learn which
44
+ * of the two happened rather than comparing payloads.
45
+ *
46
+ * NOT DURABLE, NOT CONCURRENT, NOT A LOCK SERVICE. This holds one token and one payload in
47
+ * this process's heap. It acquires no lock, contacts no lock service, and its check-then-set
48
+ * is one synchronous statement sequence, which is safe on this runtime and is a property of
49
+ * the runtime rather than a pattern a durable store may copy. The same warning
50
+ * `InMemoryAuthorityRevocationStore` carries applies here for the same reason.
51
+ */
52
+ export class FencedAuthorityStateLog {
53
+ highest = null;
54
+ payload = undefined;
55
+ written = false;
56
+ /** The highest token accepted so far, or `null` when nothing has been published. */
57
+ highestToken() {
58
+ return this.highest;
59
+ }
60
+ /** What is published now. `undefined` when no write has landed, which a caller must tell
61
+ * apart from a write that landed carrying `undefined`; `hasPublished()` is how. */
62
+ published() {
63
+ return this.payload;
64
+ }
65
+ hasPublished() {
66
+ return this.written;
67
+ }
68
+ /** Submit a write. See the class doc for the four outcomes. Never throws for a malformed
69
+ * token: an unreadable token is one that cannot be shown to have moved forward, so it is
70
+ * refused. */
71
+ write(write) {
72
+ const token = write?.token;
73
+ // Read the token on its own first. An unreadable token is a different finding from a
74
+ // stale one, and collapsing them would report a backwards move that never happened.
75
+ if (compareStateMarker(token, token) !== 'forward') {
76
+ return { accepted: false, code: 'fencing_token_unreadable', published: this.highest };
77
+ }
78
+ if (this.highest !== null) {
79
+ if (!sameScope(this.highest, token)) {
80
+ return { accepted: false, code: 'fencing_scope_mismatch', published: this.highest };
81
+ }
82
+ if (compareStateMarker(this.highest, token) !== 'forward') {
83
+ return { accepted: false, code: 'stale_fencing_token', published: this.highest };
84
+ }
85
+ }
86
+ this.highest = token;
87
+ this.payload = write.payload;
88
+ this.written = true;
89
+ return { accepted: true, published: token, payload: write.payload };
90
+ }
91
+ }
92
+ //# sourceMappingURL=fencing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fencing.js","sourceRoot":"","sources":["../../../../src/v2/authority-state/fencing.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,sCAAsC;AACtC,EAAE;AACF,+DAA+D;AAC/D,2DAA2D;AAC3D,EAAE;AACF,2FAA2F;AAC3F,0FAA0F;AAC1F,0FAA0F;AAC1F,2FAA2F;AAC3F,sFAAsF;AACtF,0DAA0D;AAC1D,EAAE;AACF,2FAA2F;AAC3F,4FAA4F;AAC5F,yFAAyF;AACzF,mFAAmF;AACnF,uFAAuF;AAEvF,OAAO,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAG3D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,MAAM,OAAO,uBAAuB;IAC1B,OAAO,GAAuB,IAAI,CAAA;IAClC,OAAO,GAAkB,SAAS,CAAA;IAClC,OAAO,GAAG,KAAK,CAAA;IAEvB,oFAAoF;IACpF,YAAY;QACV,OAAO,IAAI,CAAC,OAAO,CAAA;IACrB,CAAC;IAED;wFACoF;IACpF,SAAS;QACP,OAAO,IAAI,CAAC,OAAO,CAAA;IACrB,CAAC;IAED,YAAY;QACV,OAAO,IAAI,CAAC,OAAO,CAAA;IACrB,CAAC;IAED;;mBAEe;IACf,KAAK,CAAC,KAAqB;QACzB,MAAM,KAAK,GAAG,KAAK,EAAE,KAAK,CAAA;QAC1B,qFAAqF;QACrF,oFAAoF;QACpF,IAAI,kBAAkB,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,SAAS,EAAE,CAAC;YACnD,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,0BAA0B,EAAE,SAAS,EAAE,IAAI,CAAC,OAAO,EAAE,CAAA;QACvF,CAAC;QACD,IAAI,IAAI,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;YAC1B,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,EAAE,CAAC;gBACpC,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,wBAAwB,EAAE,SAAS,EAAE,IAAI,CAAC,OAAO,EAAE,CAAA;YACrF,CAAC;YACD,IAAI,kBAAkB,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,KAAK,SAAS,EAAE,CAAC;gBAC1D,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,qBAAqB,EAAE,SAAS,EAAE,IAAI,CAAC,OAAO,EAAE,CAAA;YAClF,CAAC;QACH,CAAC;QACD,IAAI,CAAC,OAAO,GAAG,KAAK,CAAA;QACpB,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC,OAAO,CAAA;QAC5B,IAAI,CAAC,OAAO,GAAG,IAAI,CAAA;QACnB,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAA;IACrE,CAAC;CACF"}
@@ -0,0 +1,7 @@
1
+ export * from './types.js';
2
+ export * from './marker.js';
3
+ export * from './retained.js';
4
+ export * from './fencing.js';
5
+ export * from './withdrawal.js';
6
+ export * from './report.js';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/v2/authority-state/index.ts"],"names":[],"mappings":"AAQA,cAAc,YAAY,CAAA;AAC1B,cAAc,aAAa,CAAA;AAC3B,cAAc,eAAe,CAAA;AAC7B,cAAc,cAAc,CAAA;AAC5B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,aAAa,CAAA"}
@@ -0,0 +1,14 @@
1
+ // Copyright (c) 2026 Tymofii Pidlisnyi
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ //
4
+ // PROPOSED, OPT-IN authority state markers, write fencing and revocation withdrawal.
5
+ // Nothing here is required by draft-pidlisnyi-aps-03 and nothing here changes any existing
6
+ // exported behaviour. Concept source: aeoess/agent-authority-lifecycle, invariant candidates
7
+ // CAND-08 and CAND-02.
8
+ export * from './types.js';
9
+ export * from './marker.js';
10
+ export * from './retained.js';
11
+ export * from './fencing.js';
12
+ export * from './withdrawal.js';
13
+ export * from './report.js';
14
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/v2/authority-state/index.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,sCAAsC;AACtC,EAAE;AACF,qFAAqF;AACrF,2FAA2F;AAC3F,6FAA6F;AAC7F,uBAAuB;AAEvB,cAAc,YAAY,CAAA;AAC1B,cAAc,aAAa,CAAA;AAC3B,cAAc,eAAe,CAAA;AAC7B,cAAc,cAAc,CAAA;AAC5B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,aAAa,CAAA"}