agent-passport-system 7.0.0 → 7.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 (198) hide show
  1. package/SECURITY.md +11 -0
  2. package/dist/src/core/tool-integrity.d.ts +13 -0
  3. package/dist/src/core/tool-integrity.d.ts.map +1 -1
  4. package/dist/src/core/tool-integrity.js +1 -1
  5. package/dist/src/core/tool-integrity.js.map +1 -1
  6. package/dist/src/index.d.ts +52 -2
  7. package/dist/src/index.d.ts.map +1 -1
  8. package/dist/src/index.js +282 -1
  9. package/dist/src/index.js.map +1 -1
  10. package/dist/src/v2/activation/canonical.d.ts +40 -0
  11. package/dist/src/v2/activation/canonical.d.ts.map +1 -0
  12. package/dist/src/v2/activation/canonical.js +64 -0
  13. package/dist/src/v2/activation/canonical.js.map +1 -0
  14. package/dist/src/v2/activation/index.d.ts +4 -0
  15. package/dist/src/v2/activation/index.d.ts.map +1 -0
  16. package/dist/src/v2/activation/index.js +11 -0
  17. package/dist/src/v2/activation/index.js.map +1 -0
  18. package/dist/src/v2/activation/types.d.ts +268 -0
  19. package/dist/src/v2/activation/types.d.ts.map +1 -0
  20. package/dist/src/v2/activation/types.js +198 -0
  21. package/dist/src/v2/activation/types.js.map +1 -0
  22. package/dist/src/v2/activation/verify.d.ts +132 -0
  23. package/dist/src/v2/activation/verify.d.ts.map +1 -0
  24. package/dist/src/v2/activation/verify.js +406 -0
  25. package/dist/src/v2/activation/verify.js.map +1 -0
  26. package/dist/src/v2/authority-revocation/canonical.d.ts +46 -0
  27. package/dist/src/v2/authority-revocation/canonical.d.ts.map +1 -0
  28. package/dist/src/v2/authority-revocation/canonical.js +68 -0
  29. package/dist/src/v2/authority-revocation/canonical.js.map +1 -0
  30. package/dist/src/v2/authority-revocation/index.d.ts +9 -0
  31. package/dist/src/v2/authority-revocation/index.d.ts.map +1 -0
  32. package/dist/src/v2/authority-revocation/index.js +11 -0
  33. package/dist/src/v2/authority-revocation/index.js.map +1 -0
  34. package/dist/src/v2/authority-revocation/issue.d.ts +54 -0
  35. package/dist/src/v2/authority-revocation/issue.d.ts.map +1 -0
  36. package/dist/src/v2/authority-revocation/issue.js +111 -0
  37. package/dist/src/v2/authority-revocation/issue.js.map +1 -0
  38. package/dist/src/v2/authority-revocation/record.d.ts +69 -0
  39. package/dist/src/v2/authority-revocation/record.d.ts.map +1 -0
  40. package/dist/src/v2/authority-revocation/record.js +51 -0
  41. package/dist/src/v2/authority-revocation/record.js.map +1 -0
  42. package/dist/src/v2/authority-revocation/resolver.d.ts +30 -0
  43. package/dist/src/v2/authority-revocation/resolver.d.ts.map +1 -0
  44. package/dist/src/v2/authority-revocation/resolver.js +52 -0
  45. package/dist/src/v2/authority-revocation/resolver.js.map +1 -0
  46. package/dist/src/v2/authority-revocation/schema.d.ts +15 -0
  47. package/dist/src/v2/authority-revocation/schema.d.ts.map +1 -0
  48. package/dist/src/v2/authority-revocation/schema.js +107 -0
  49. package/dist/src/v2/authority-revocation/schema.js.map +1 -0
  50. package/dist/src/v2/authority-revocation/store.d.ts +55 -0
  51. package/dist/src/v2/authority-revocation/store.d.ts.map +1 -0
  52. package/dist/src/v2/authority-revocation/store.js +69 -0
  53. package/dist/src/v2/authority-revocation/store.js.map +1 -0
  54. package/dist/src/v2/authority-revocation/types.d.ts +136 -0
  55. package/dist/src/v2/authority-revocation/types.d.ts.map +1 -0
  56. package/dist/src/v2/authority-revocation/types.js +11 -0
  57. package/dist/src/v2/authority-revocation/types.js.map +1 -0
  58. package/dist/src/v2/authority-revocation/verify.d.ts +38 -0
  59. package/dist/src/v2/authority-revocation/verify.d.ts.map +1 -0
  60. package/dist/src/v2/authority-revocation/verify.js +139 -0
  61. package/dist/src/v2/authority-revocation/verify.js.map +1 -0
  62. package/dist/src/v2/authority-state/fencing.d.ts +49 -0
  63. package/dist/src/v2/authority-state/fencing.d.ts.map +1 -0
  64. package/dist/src/v2/authority-state/fencing.js +92 -0
  65. package/dist/src/v2/authority-state/fencing.js.map +1 -0
  66. package/dist/src/v2/authority-state/index.d.ts +7 -0
  67. package/dist/src/v2/authority-state/index.d.ts.map +1 -0
  68. package/dist/src/v2/authority-state/index.js +14 -0
  69. package/dist/src/v2/authority-state/index.js.map +1 -0
  70. package/dist/src/v2/authority-state/marker.d.ts +70 -0
  71. package/dist/src/v2/authority-state/marker.d.ts.map +1 -0
  72. package/dist/src/v2/authority-state/marker.js +122 -0
  73. package/dist/src/v2/authority-state/marker.js.map +1 -0
  74. package/dist/src/v2/authority-state/report.d.ts +55 -0
  75. package/dist/src/v2/authority-state/report.d.ts.map +1 -0
  76. package/dist/src/v2/authority-state/report.js +51 -0
  77. package/dist/src/v2/authority-state/report.js.map +1 -0
  78. package/dist/src/v2/authority-state/retained.d.ts +82 -0
  79. package/dist/src/v2/authority-state/retained.d.ts.map +1 -0
  80. package/dist/src/v2/authority-state/retained.js +93 -0
  81. package/dist/src/v2/authority-state/retained.js.map +1 -0
  82. package/dist/src/v2/authority-state/types.d.ts +198 -0
  83. package/dist/src/v2/authority-state/types.d.ts.map +1 -0
  84. package/dist/src/v2/authority-state/types.js +103 -0
  85. package/dist/src/v2/authority-state/types.js.map +1 -0
  86. package/dist/src/v2/authority-state/withdrawal.d.ts +80 -0
  87. package/dist/src/v2/authority-state/withdrawal.d.ts.map +1 -0
  88. package/dist/src/v2/authority-state/withdrawal.js +199 -0
  89. package/dist/src/v2/authority-state/withdrawal.js.map +1 -0
  90. package/dist/src/v2/bounds/canonical.d.ts +30 -0
  91. package/dist/src/v2/bounds/canonical.d.ts.map +1 -0
  92. package/dist/src/v2/bounds/canonical.js +69 -0
  93. package/dist/src/v2/bounds/canonical.js.map +1 -0
  94. package/dist/src/v2/bounds/evaluate.d.ts +107 -0
  95. package/dist/src/v2/bounds/evaluate.d.ts.map +1 -0
  96. package/dist/src/v2/bounds/evaluate.js +315 -0
  97. package/dist/src/v2/bounds/evaluate.js.map +1 -0
  98. package/dist/src/v2/bounds/index.d.ts +6 -0
  99. package/dist/src/v2/bounds/index.d.ts.map +1 -0
  100. package/dist/src/v2/bounds/index.js +13 -0
  101. package/dist/src/v2/bounds/index.js.map +1 -0
  102. package/dist/src/v2/bounds/purpose.d.ts +2 -0
  103. package/dist/src/v2/bounds/purpose.d.ts.map +1 -0
  104. package/dist/src/v2/bounds/purpose.js +23 -0
  105. package/dist/src/v2/bounds/purpose.js.map +1 -0
  106. package/dist/src/v2/bounds/record.d.ts +78 -0
  107. package/dist/src/v2/bounds/record.d.ts.map +1 -0
  108. package/dist/src/v2/bounds/record.js +170 -0
  109. package/dist/src/v2/bounds/record.js.map +1 -0
  110. package/dist/src/v2/bounds/types.d.ts +275 -0
  111. package/dist/src/v2/bounds/types.d.ts.map +1 -0
  112. package/dist/src/v2/bounds/types.js +124 -0
  113. package/dist/src/v2/bounds/types.js.map +1 -0
  114. package/dist/src/v2/capability-binding/binding.d.ts +67 -0
  115. package/dist/src/v2/capability-binding/binding.d.ts.map +1 -0
  116. package/dist/src/v2/capability-binding/binding.js +267 -0
  117. package/dist/src/v2/capability-binding/binding.js.map +1 -0
  118. package/dist/src/v2/capability-binding/digest.d.ts +33 -0
  119. package/dist/src/v2/capability-binding/digest.d.ts.map +1 -0
  120. package/dist/src/v2/capability-binding/digest.js +55 -0
  121. package/dist/src/v2/capability-binding/digest.js.map +1 -0
  122. package/dist/src/v2/capability-binding/identifier.d.ts +103 -0
  123. package/dist/src/v2/capability-binding/identifier.d.ts.map +1 -0
  124. package/dist/src/v2/capability-binding/identifier.js +281 -0
  125. package/dist/src/v2/capability-binding/identifier.js.map +1 -0
  126. package/dist/src/v2/capability-binding/index.d.ts +6 -0
  127. package/dist/src/v2/capability-binding/index.d.ts.map +1 -0
  128. package/dist/src/v2/capability-binding/index.js +13 -0
  129. package/dist/src/v2/capability-binding/index.js.map +1 -0
  130. package/dist/src/v2/capability-binding/pins.d.ts +30 -0
  131. package/dist/src/v2/capability-binding/pins.d.ts.map +1 -0
  132. package/dist/src/v2/capability-binding/pins.js +109 -0
  133. package/dist/src/v2/capability-binding/pins.js.map +1 -0
  134. package/dist/src/v2/capability-binding/types.d.ts +213 -0
  135. package/dist/src/v2/capability-binding/types.d.ts.map +1 -0
  136. package/dist/src/v2/capability-binding/types.js +150 -0
  137. package/dist/src/v2/capability-binding/types.js.map +1 -0
  138. package/dist/src/v2/chain-selection/index.d.ts +4 -0
  139. package/dist/src/v2/chain-selection/index.d.ts.map +1 -0
  140. package/dist/src/v2/chain-selection/index.js +11 -0
  141. package/dist/src/v2/chain-selection/index.js.map +1 -0
  142. package/dist/src/v2/chain-selection/select.d.ts +62 -0
  143. package/dist/src/v2/chain-selection/select.d.ts.map +1 -0
  144. package/dist/src/v2/chain-selection/select.js +390 -0
  145. package/dist/src/v2/chain-selection/select.js.map +1 -0
  146. package/dist/src/v2/chain-selection/types.d.ts +189 -0
  147. package/dist/src/v2/chain-selection/types.d.ts.map +1 -0
  148. package/dist/src/v2/chain-selection/types.js +81 -0
  149. package/dist/src/v2/chain-selection/types.js.map +1 -0
  150. package/dist/src/v2/lifecycle-state/index.d.ts +4 -0
  151. package/dist/src/v2/lifecycle-state/index.d.ts.map +1 -0
  152. package/dist/src/v2/lifecycle-state/index.js +10 -0
  153. package/dist/src/v2/lifecycle-state/index.js.map +1 -0
  154. package/dist/src/v2/lifecycle-state/map.d.ts +52 -0
  155. package/dist/src/v2/lifecycle-state/map.d.ts.map +1 -0
  156. package/dist/src/v2/lifecycle-state/map.js +122 -0
  157. package/dist/src/v2/lifecycle-state/map.js.map +1 -0
  158. package/dist/src/v2/lifecycle-state/state.d.ts +60 -0
  159. package/dist/src/v2/lifecycle-state/state.d.ts.map +1 -0
  160. package/dist/src/v2/lifecycle-state/state.js +157 -0
  161. package/dist/src/v2/lifecycle-state/state.js.map +1 -0
  162. package/dist/src/v2/lifecycle-state/types.d.ts +163 -0
  163. package/dist/src/v2/lifecycle-state/types.d.ts.map +1 -0
  164. package/dist/src/v2/lifecycle-state/types.js +121 -0
  165. package/dist/src/v2/lifecycle-state/types.js.map +1 -0
  166. package/dist/src/v2/receipt-core/composite.d.ts +69 -3
  167. package/dist/src/v2/receipt-core/composite.d.ts.map +1 -1
  168. package/dist/src/v2/receipt-core/composite.js +75 -9
  169. package/dist/src/v2/receipt-core/composite.js.map +1 -1
  170. package/dist/src/v2/receipt-core/predecessor.d.ts +95 -0
  171. package/dist/src/v2/receipt-core/predecessor.d.ts.map +1 -0
  172. package/dist/src/v2/receipt-core/predecessor.js +115 -0
  173. package/dist/src/v2/receipt-core/predecessor.js.map +1 -0
  174. package/dist/src/v2/status-coverage/decide.d.ts +52 -0
  175. package/dist/src/v2/status-coverage/decide.d.ts.map +1 -0
  176. package/dist/src/v2/status-coverage/decide.js +398 -0
  177. package/dist/src/v2/status-coverage/decide.js.map +1 -0
  178. package/dist/src/v2/status-coverage/index.d.ts +3 -0
  179. package/dist/src/v2/status-coverage/index.d.ts.map +1 -0
  180. package/dist/src/v2/status-coverage/index.js +10 -0
  181. package/dist/src/v2/status-coverage/index.js.map +1 -0
  182. package/dist/src/v2/status-coverage/types.d.ts +258 -0
  183. package/dist/src/v2/status-coverage/types.d.ts.map +1 -0
  184. package/dist/src/v2/status-coverage/types.js +127 -0
  185. package/dist/src/v2/status-coverage/types.js.map +1 -0
  186. package/dist/src/v2/suspension/evaluate.d.ts +88 -0
  187. package/dist/src/v2/suspension/evaluate.d.ts.map +1 -0
  188. package/dist/src/v2/suspension/evaluate.js +404 -0
  189. package/dist/src/v2/suspension/evaluate.js.map +1 -0
  190. package/dist/src/v2/suspension/index.d.ts +3 -0
  191. package/dist/src/v2/suspension/index.d.ts.map +1 -0
  192. package/dist/src/v2/suspension/index.js +10 -0
  193. package/dist/src/v2/suspension/index.js.map +1 -0
  194. package/dist/src/v2/suspension/types.d.ts +243 -0
  195. package/dist/src/v2/suspension/types.d.ts.map +1 -0
  196. package/dist/src/v2/suspension/types.js +135 -0
  197. package/dist/src/v2/suspension/types.js.map +1 -0
  198. package/package.json +10 -7
@@ -0,0 +1,103 @@
1
+ // Copyright (c) 2026 Tymofii Pidlisnyi
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ //
4
+ // PROPOSED, OPT-IN. Authority state markers, write fencing, and withdrawal of a recorded
5
+ // revocation.
6
+ //
7
+ // NOT REQUIRED BY draft-pidlisnyi-aps-03. The published text contains no occurrence of
8
+ // `epoch`, `fencing`, `snapshot`, `replica` or `restore`, and defines no record for
9
+ // withdrawing a revocation. What it does fix, and what this module is careful not to
10
+ // disturb, is section 3.3: "Verification returns one of valid, invalid, indeterminate, or
11
+ // unsupported with a stable failure code", and section 3.5: "Revocation is irreversible."
12
+ // `AuthorityValidationState`, `AuthorityValidationResult`, `AuthorityRevocationStore` and
13
+ // everything `verifyAuthorityDelegationChain` returns are unchanged, and a caller that does
14
+ // not import this module sees exactly today's behaviour.
15
+ //
16
+ // Concept source: the aeoess/agent-authority-lifecycle concept document
17
+ // (AUTHORITY-LIFECYCLE.md, the `Authority epoch` concept and invariants L3, L7 and L11;
18
+ // OPEN-QUESTIONS.md, `Authority rollback`) and its invariant candidates CAND-08 (no silent
19
+ // restoration from rollback or stale state) and CAND-02 (later evidence does not rewrite
20
+ // earlier evidence). Every one of those is proposed, not specified. Nothing here claims
21
+ // otherwise, and `OPEN-QUESTIONS.md` keeps open both the mechanism and what a verifier
22
+ // should return after a restore.
23
+ //
24
+ // Three deliberate non-decisions are encoded as types rather than as behaviour:
25
+ //
26
+ // 1. The proposed text says an authority epoch is "where a system uses generations" and
27
+ // stops. It does not say who advances one, whether it is global or per delegation,
28
+ // whether it is signed, or what evidence carries it. `StateMarker` is therefore an
29
+ // opaque comparable supplied by the caller, and this module defines only the comparison.
30
+ // 2. A verifier with no prior observation has nothing to compare against. That is
31
+ // `unplaceable`, and it is not a verdict. The caller says what to do with it.
32
+ // 3. Who may withdraw a revocation is not stated anywhere. Standing is resolved through an
33
+ // injected callback and never read from the record asserting it.
34
+ /** What a marker is counted within. Comparing two markers from different scopes orders
35
+ * nothing, so the comparison reports `unplaceable` rather than inventing an order.
36
+ *
37
+ * The proposed text names none of these. They exist because the fixture that forced this
38
+ * module had to pick one (it picked a global integer on a state view) and recorded that
39
+ * the choice was not read from the text. Carrying the scope makes that choice visible in
40
+ * the record instead of implicit in the deployment. Proposed. */
41
+ export const STATE_MARKER_SCOPES = ['global', 'per_delegation', 'per_principal', 'per_store'];
42
+ /** The result of placing a presented marker against what a verifier has established.
43
+ *
44
+ * - `forward` the presented marker advanced, or held equal. Read the view normally.
45
+ * - `regressed` the presented marker went backwards against an established high-water
46
+ * mark. CAND-08's refusal case.
47
+ * - `unplaceable` there is nothing to compare against, or the two markers are counted in
48
+ * different scopes. **Deliberately not a verdict.** A high-water mark has
49
+ * to start somewhere and neither the proposed text nor draft-03 says
50
+ * whether a first read is trusted or refused. Both are defensible and the
51
+ * outcomes differ, so this module reports the fact and the caller
52
+ * decides. See `UnplaceableDisposition`. */
53
+ export const MONOTONICITY_OUTCOMES = ['forward', 'regressed', 'unplaceable'];
54
+ /** What a caller wants done with an `unplaceable` presented view. Required, with no
55
+ * default, because the SDK picking one would be the SDK deciding a question its own
56
+ * concept source records as undecided. */
57
+ export const UNPLACEABLE_DISPOSITIONS = ['read_presented', 'refuse'];
58
+ /** Why a fenced write was refused.
59
+ *
60
+ * - `stale_fencing_token` the token went backwards against the highest already seen.
61
+ * The only one of the three the source states.
62
+ * - `fencing_scope_mismatch` the token is counted in a different scope from the log's, so
63
+ * it cannot be ordered against what the log holds.
64
+ * - `fencing_token_unreadable` the token is absent or not a well-formed `StateMarker`.
65
+ *
66
+ * A write path that cannot order a token is not fenced, so the second and third refuse
67
+ * rather than guess. Neither is in any source; both are this module's choice. */
68
+ export const FENCED_WRITE_REFUSAL_CODES = [
69
+ 'stale_fencing_token',
70
+ 'fencing_scope_mismatch',
71
+ 'fencing_token_unreadable',
72
+ ];
73
+ /** The record type a withdrawal carries.
74
+ *
75
+ * `proposed:` is load-bearing. Record fields, failure-class names and verifier semantics
76
+ * are conformance vocabulary reserved to the maintainer, and neither draft-03 nor the
77
+ * proposed text defines a record for withdrawing a recorded revocation or says what a
78
+ * verifier should do with one. This is a placeholder to argue about, not APS vocabulary. */
79
+ export const REVOCATION_WITHDRAWAL_RECORD_TYPE = 'proposed:aps:revocation-withdrawal:v0';
80
+ export const REVOCATION_WITHDRAWAL_VERSION = '0';
81
+ /** What an injected standing resolver may answer.
82
+ *
83
+ * `unknown` is a first-class answer and is not `no_standing`. A verifier that cannot
84
+ * establish whether the withdrawer had standing has not established that they lacked it,
85
+ * and the refusal reason says which of the two happened. */
86
+ export const WITHDRAWAL_STANDINGS = ['has_standing', 'no_standing', 'unknown'];
87
+ /** Why a withdrawal was accepted or refused. Stable, module-local codes. */
88
+ export const WITHDRAWAL_OUTCOME_CODES = [
89
+ /** Accepted as a record. Accepted never means the revocation is gone. */
90
+ 'WITHDRAWAL_ACCEPTED',
91
+ /** The record is not a well-formed `RevocationWithdrawalV0`. */
92
+ 'WITHDRAWAL_SCHEMA_INVALID',
93
+ /** No revocation in the held set carries the `revocation_id` this record names. */
94
+ 'WITHDRAWAL_NAMES_NO_HELD_REVOCATION',
95
+ /** The named revocation exists but is a revocation of a different delegation. */
96
+ 'WITHDRAWAL_TARGET_MISMATCH',
97
+ /** The resolver established that this party may not withdraw this revocation. */
98
+ 'WITHDRAWAL_SIGNER_WITHOUT_STANDING',
99
+ /** The resolver could not establish standing either way. Not the same finding as the
100
+ * one above, and reported as `not_established` rather than as a denial. */
101
+ 'WITHDRAWAL_STANDING_NOT_ESTABLISHED',
102
+ ];
103
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/v2/authority-state/types.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,sCAAsC;AACtC,EAAE;AACF,yFAAyF;AACzF,cAAc;AACd,EAAE;AACF,uFAAuF;AACvF,oFAAoF;AACpF,qFAAqF;AACrF,0FAA0F;AAC1F,0FAA0F;AAC1F,0FAA0F;AAC1F,4FAA4F;AAC5F,yDAAyD;AACzD,EAAE;AACF,wEAAwE;AACxE,wFAAwF;AACxF,2FAA2F;AAC3F,yFAAyF;AACzF,wFAAwF;AACxF,uFAAuF;AACvF,iCAAiC;AACjC,EAAE;AACF,gFAAgF;AAChF,EAAE;AACF,yFAAyF;AACzF,uFAAuF;AACvF,uFAAuF;AACvF,6FAA6F;AAC7F,mFAAmF;AACnF,kFAAkF;AAClF,4FAA4F;AAC5F,qEAAqE;AAIrE;;;;;;kEAMkE;AAClE,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,QAAQ,EAAE,gBAAgB,EAAE,eAAe,EAAE,WAAW,CAAU,CAAA;AAsBtG;;;;;;;;;;8DAU8D;AAC9D,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,SAAS,EAAE,WAAW,EAAE,aAAa,CAAU,CAAA;AAIrF;;2CAE2C;AAC3C,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,gBAAgB,EAAE,QAAQ,CAAU,CAAA;AA6B7E;;;;;;;;;kFASkF;AAClF,MAAM,CAAC,MAAM,0BAA0B,GAAG;IACxC,qBAAqB;IACrB,wBAAwB;IACxB,0BAA0B;CAClB,CAAA;AAoBV;;;;;6FAK6F;AAC7F,MAAM,CAAC,MAAM,iCAAiC,GAAG,uCAAgD,CAAA;AACjG,MAAM,CAAC,MAAM,6BAA6B,GAAG,GAAY,CAAA;AAkCzD;;;;6DAI6D;AAC7D,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,cAAc,EAAE,aAAa,EAAE,SAAS,CAAU,CAAA;AAgBvF,4EAA4E;AAC5E,MAAM,CAAC,MAAM,wBAAwB,GAAG;IACtC,yEAAyE;IACzE,qBAAqB;IACrB,gEAAgE;IAChE,2BAA2B;IAC3B,mFAAmF;IACnF,qCAAqC;IACrC,iFAAiF;IACjF,4BAA4B;IAC5B,iFAAiF;IACjF,oCAAoC;IACpC;gFAC4E;IAC5E,qCAAqC;CAC7B,CAAA"}
@@ -0,0 +1,80 @@
1
+ import type { AuthorityRevocationV1 } from '../authority-revocation/types.js';
2
+ import { type CorrectedRevocationView, type RevocationWithdrawalV0, type WithdrawalEvaluation, type WithdrawalStanding, type WithdrawalStandingResolver } from './types.js';
3
+ export declare function isWithdrawalStanding(value: unknown): value is WithdrawalStanding;
4
+ export interface RevocationWithdrawalInput {
5
+ readonly revocation_id: string;
6
+ readonly delegation_id: string;
7
+ readonly withdrawn_by: string;
8
+ readonly withdrawn_at: string;
9
+ readonly reason_code: string;
10
+ readonly detail?: string;
11
+ }
12
+ /**
13
+ * Build a `RevocationWithdrawalV0`.
14
+ *
15
+ * A shape constructor and nothing more. It does not sign, does not canonicalize, and does
16
+ * not compute an identifier, because minting the signed form of a record type is a
17
+ * conformance-vocabulary decision reserved to the maintainer and this module is not making
18
+ * it. `record_type` carries the `proposed:` namespace for the same reason.
19
+ *
20
+ * An absent `detail` is absent, never `null`: the key is not present at all, matching how
21
+ * the revocation record treats its own optional detail.
22
+ */
23
+ export declare function revocationWithdrawal(input: RevocationWithdrawalInput): RevocationWithdrawalV0;
24
+ /** A standing resolver that accepts a withdrawal only from the party the revocation itself
25
+ * names as revoker.
26
+ *
27
+ * Supplied because it is the rule the forcing fixture chose and it needs to be runnable.
28
+ * IT IS A CHOICE, NOT A RULE READ FROM ANY TEXT. Draft-03 section 3.5 names the issuer as
29
+ * the party who may revoke; nothing in draft-03 or in the proposed text says who may
30
+ * withdraw a revocation, and the concept document's own `Lifecycle standing` entry says
31
+ * the party who may change an artifact "is not always the issuer". A deployment whose
32
+ * authority model gives a security function, a successor or a quorum standing to correct a
33
+ * publication error should pass its own resolver instead of this one. */
34
+ export declare const withdrawalSignerIsRevoker: WithdrawalStandingResolver;
35
+ /**
36
+ * Decide whether one withdrawal record is accepted against a set of held revocations.
37
+ *
38
+ * Four questions, kept separate on purpose, each with its own code:
39
+ *
40
+ * 1. Is the record a well-formed withdrawal? `WITHDRAWAL_SCHEMA_INVALID`.
41
+ * 2. Does it name a revocation the held set actually contains?
42
+ * `WITHDRAWAL_NAMES_NO_HELD_REVOCATION`.
43
+ * 3. Does that revocation revoke the delegation this record names?
44
+ * `WITHDRAWAL_TARGET_MISMATCH`.
45
+ * 4. May this party withdraw it? Asked of the injected resolver, never of the record.
46
+ * `WITHDRAWAL_SIGNER_WITHOUT_STANDING` when the resolver establishes they may not, and
47
+ * `WITHDRAWAL_STANDING_NOT_ESTABLISHED` when it cannot establish either way.
48
+ *
49
+ * The last split is the wording rule, executable: a standing question the verifier could
50
+ * not answer is not established, and that is not the same finding as a party established to
51
+ * lack standing. Both refuse the withdrawal, and a caller reporting the refusal has to be
52
+ * able to say which one happened.
53
+ *
54
+ * AUTHENTICATION IS THE CALLER'S. This function never checks a signature, because a
55
+ * withdrawal has no signed form in this SDK, on purpose; see `RevocationWithdrawalV0`.
56
+ * Whoever calls it is the party asserting the record is genuine, exactly as whoever calls
57
+ * `insertVerifiedRevocation` asserts the revocation was verified.
58
+ *
59
+ * NOTHING HERE REMOVES A REVOCATION, on any path. An accepted withdrawal is a record about
60
+ * a record. The held set handed in is not mutated and no store is touched.
61
+ */
62
+ export declare function evaluateRevocationWithdrawal(withdrawal: RevocationWithdrawalV0, heldRevocations: readonly AuthorityRevocationV1[], resolveStanding: WithdrawalStandingResolver): WithdrawalEvaluation;
63
+ /**
64
+ * The current position of one revocation together with every withdrawal referencing it.
65
+ *
66
+ * This is the field that did not exist. A verifier that must report "revoked, and the
67
+ * revoker later said this was recorded in error" had nowhere to put the second half, in
68
+ * either reference SDK or in the proposed text, so it could only report the first half and
69
+ * drop the rest.
70
+ *
71
+ * `revocation` is present and unchanged whether or not anything was accepted. Accepted
72
+ * withdrawals are listed, refused ones are listed with their codes, and neither list makes
73
+ * the revocation ineffective: a later finding is a new record that references the earlier
74
+ * one and states its own effect, never an edit of it and never its removal.
75
+ *
76
+ * Withdrawals naming a different revocation are not silently dropped. They are evaluated,
77
+ * refused `WITHDRAWAL_NAMES_NO_HELD_REVOCATION`, and appear in `refused`.
78
+ */
79
+ export declare function correctedRevocationView(revocation: AuthorityRevocationV1, withdrawals: readonly RevocationWithdrawalV0[], resolveStanding: WithdrawalStandingResolver): CorrectedRevocationView;
80
+ //# sourceMappingURL=withdrawal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"withdrawal.d.ts","sourceRoot":"","sources":["../../../../src/v2/authority-state/withdrawal.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,kCAAkC,CAAA;AAE7E,OAAO,EAIL,KAAK,uBAAuB,EAC5B,KAAK,sBAAsB,EAC3B,KAAK,oBAAoB,EACzB,KAAK,kBAAkB,EACvB,KAAK,0BAA0B,EAChC,MAAM,YAAY,CAAA;AAInB,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,kBAAkB,CAEhF;AAED,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;IAC9B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;IAC9B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;IAC7B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;IAC7B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CACzB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,yBAAyB,GAAG,sBAAsB,CA8C7F;AAED;;;;;;;;;0EAS0E;AAC1E,eAAO,MAAM,yBAAyB,EAAE,0BACyC,CAAA;AAgBjF;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,4BAA4B,CAC1C,UAAU,EAAE,sBAAsB,EAClC,eAAe,EAAE,SAAS,qBAAqB,EAAE,EACjD,eAAe,EAAE,0BAA0B,GAC1C,oBAAoB,CAqDtB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,uBAAuB,CACrC,UAAU,EAAE,qBAAqB,EACjC,WAAW,EAAE,SAAS,sBAAsB,EAAE,EAC9C,eAAe,EAAE,0BAA0B,GAC1C,uBAAuB,CAUzB"}
@@ -0,0 +1,199 @@
1
+ // Copyright (c) 2026 Tymofii Pidlisnyi
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ //
4
+ // PROPOSED, OPT-IN. Withdrawal, or correction, of a recorded revocation.
5
+ // See ./types.ts for the specification position. Concept source:
6
+ // aeoess/agent-authority-lifecycle, invariant candidate CAND-02 (later evidence does not
7
+ // rewrite earlier evidence) and invariant L3 (reauthorization creates new authority).
8
+ // Proposed.
9
+ //
10
+ // THE ONE SENTENCE THIS FILE EXISTS FOR. A corrected false revocation is a separate record,
11
+ // not a resurrection. Draft-03 section 3.5 states "Revocation is irreversible", and nothing
12
+ // below relaxes that: an accepted withdrawal leaves the revocation held, leaves it
13
+ // verifying byte for byte, and leaves every chain verdict exactly where it was. What the
14
+ // withdrawal changes is what a verifier can REPORT, which had no representation at all.
15
+ //
16
+ // Continuity after a correction still needs a fresh grant from a principal who currently
17
+ // holds authority. This module mints no grant and no authority of any kind.
18
+ import { AuthorityStateError } from './marker.js';
19
+ import { REVOCATION_WITHDRAWAL_RECORD_TYPE, REVOCATION_WITHDRAWAL_VERSION, WITHDRAWAL_STANDINGS, } from './types.js';
20
+ const ID = /^sha256:[0-9a-f]{64}$/;
21
+ export function isWithdrawalStanding(value) {
22
+ return typeof value === 'string' && WITHDRAWAL_STANDINGS.includes(value);
23
+ }
24
+ /**
25
+ * Build a `RevocationWithdrawalV0`.
26
+ *
27
+ * A shape constructor and nothing more. It does not sign, does not canonicalize, and does
28
+ * not compute an identifier, because minting the signed form of a record type is a
29
+ * conformance-vocabulary decision reserved to the maintainer and this module is not making
30
+ * it. `record_type` carries the `proposed:` namespace for the same reason.
31
+ *
32
+ * An absent `detail` is absent, never `null`: the key is not present at all, matching how
33
+ * the revocation record treats its own optional detail.
34
+ */
35
+ export function revocationWithdrawal(input) {
36
+ if (input === null || typeof input !== 'object') {
37
+ throw new AuthorityStateError('WITHDRAWAL_MALFORMED', 'a withdrawal input must be an object');
38
+ }
39
+ for (const field of ['revocation_id', 'delegation_id']) {
40
+ if (typeof input[field] !== 'string' || !ID.test(input[field])) {
41
+ throw new AuthorityStateError('WITHDRAWAL_ID_NONCANONICAL', `${field} must be sha256:<64 lowercase hex>`);
42
+ }
43
+ }
44
+ for (const field of ['withdrawn_by', 'withdrawn_at', 'reason_code']) {
45
+ if (typeof input[field] !== 'string' || input[field].length === 0) {
46
+ throw new AuthorityStateError('WITHDRAWAL_FIELD_REQUIRED', `${field} must be a non-empty string`);
47
+ }
48
+ }
49
+ if (input.detail !== undefined && (typeof input.detail !== 'string' || input.detail.length === 0)) {
50
+ throw new AuthorityStateError('WITHDRAWAL_DETAIL_INVALID', 'detail must be a non-empty string when present');
51
+ }
52
+ const record = {
53
+ record_type: REVOCATION_WITHDRAWAL_RECORD_TYPE,
54
+ version: REVOCATION_WITHDRAWAL_VERSION,
55
+ revocation_id: input.revocation_id,
56
+ delegation_id: input.delegation_id,
57
+ withdrawn_by: input.withdrawn_by,
58
+ withdrawn_at: input.withdrawn_at,
59
+ reason_code: input.reason_code,
60
+ };
61
+ if (input.detail !== undefined)
62
+ record.detail = input.detail;
63
+ return Object.freeze(record);
64
+ }
65
+ /** A standing resolver that accepts a withdrawal only from the party the revocation itself
66
+ * names as revoker.
67
+ *
68
+ * Supplied because it is the rule the forcing fixture chose and it needs to be runnable.
69
+ * IT IS A CHOICE, NOT A RULE READ FROM ANY TEXT. Draft-03 section 3.5 names the issuer as
70
+ * the party who may revoke; nothing in draft-03 or in the proposed text says who may
71
+ * withdraw a revocation, and the concept document's own `Lifecycle standing` entry says
72
+ * the party who may change an artifact "is not always the issuer". A deployment whose
73
+ * authority model gives a security function, a successor or a quorum standing to correct a
74
+ * publication error should pass its own resolver instead of this one. */
75
+ export const withdrawalSignerIsRevoker = (withdrawal, revocation) => withdrawal.withdrawn_by === revocation.revoker ? 'has_standing' : 'no_standing';
76
+ function malformed(withdrawal) {
77
+ const w = withdrawal;
78
+ if (w === null || typeof w !== 'object')
79
+ return true;
80
+ if (w.record_type !== REVOCATION_WITHDRAWAL_RECORD_TYPE)
81
+ return true;
82
+ if (w.version !== REVOCATION_WITHDRAWAL_VERSION)
83
+ return true;
84
+ if (typeof w.revocation_id !== 'string' || !ID.test(w.revocation_id))
85
+ return true;
86
+ if (typeof w.delegation_id !== 'string' || !ID.test(w.delegation_id))
87
+ return true;
88
+ for (const field of ['withdrawn_by', 'withdrawn_at', 'reason_code']) {
89
+ const value = w[field];
90
+ if (typeof value !== 'string' || value.length === 0)
91
+ return true;
92
+ }
93
+ return false;
94
+ }
95
+ /**
96
+ * Decide whether one withdrawal record is accepted against a set of held revocations.
97
+ *
98
+ * Four questions, kept separate on purpose, each with its own code:
99
+ *
100
+ * 1. Is the record a well-formed withdrawal? `WITHDRAWAL_SCHEMA_INVALID`.
101
+ * 2. Does it name a revocation the held set actually contains?
102
+ * `WITHDRAWAL_NAMES_NO_HELD_REVOCATION`.
103
+ * 3. Does that revocation revoke the delegation this record names?
104
+ * `WITHDRAWAL_TARGET_MISMATCH`.
105
+ * 4. May this party withdraw it? Asked of the injected resolver, never of the record.
106
+ * `WITHDRAWAL_SIGNER_WITHOUT_STANDING` when the resolver establishes they may not, and
107
+ * `WITHDRAWAL_STANDING_NOT_ESTABLISHED` when it cannot establish either way.
108
+ *
109
+ * The last split is the wording rule, executable: a standing question the verifier could
110
+ * not answer is not established, and that is not the same finding as a party established to
111
+ * lack standing. Both refuse the withdrawal, and a caller reporting the refusal has to be
112
+ * able to say which one happened.
113
+ *
114
+ * AUTHENTICATION IS THE CALLER'S. This function never checks a signature, because a
115
+ * withdrawal has no signed form in this SDK, on purpose; see `RevocationWithdrawalV0`.
116
+ * Whoever calls it is the party asserting the record is genuine, exactly as whoever calls
117
+ * `insertVerifiedRevocation` asserts the revocation was verified.
118
+ *
119
+ * NOTHING HERE REMOVES A REVOCATION, on any path. An accepted withdrawal is a record about
120
+ * a record. The held set handed in is not mutated and no store is touched.
121
+ */
122
+ export function evaluateRevocationWithdrawal(withdrawal, heldRevocations, resolveStanding) {
123
+ if (malformed(withdrawal)) {
124
+ return Object.freeze({
125
+ accepted: false,
126
+ reason_code: 'WITHDRAWAL_SCHEMA_INVALID',
127
+ standing: null,
128
+ withdrawal,
129
+ });
130
+ }
131
+ const target = (heldRevocations ?? []).find(r => r?.revocation_id === withdrawal.revocation_id);
132
+ if (target === undefined) {
133
+ return Object.freeze({
134
+ accepted: false,
135
+ reason_code: 'WITHDRAWAL_NAMES_NO_HELD_REVOCATION',
136
+ standing: null,
137
+ withdrawal,
138
+ });
139
+ }
140
+ if (target.delegation_id !== withdrawal.delegation_id) {
141
+ return Object.freeze({
142
+ accepted: false,
143
+ reason_code: 'WITHDRAWAL_TARGET_MISMATCH',
144
+ standing: null,
145
+ withdrawal,
146
+ });
147
+ }
148
+ let standing;
149
+ try {
150
+ standing = resolveStanding(withdrawal, target);
151
+ }
152
+ catch {
153
+ standing = 'unknown';
154
+ }
155
+ if (!isWithdrawalStanding(standing))
156
+ standing = 'unknown';
157
+ if (standing === 'has_standing') {
158
+ return Object.freeze({
159
+ accepted: true,
160
+ reason_code: 'WITHDRAWAL_ACCEPTED',
161
+ standing,
162
+ withdrawal,
163
+ });
164
+ }
165
+ return Object.freeze({
166
+ accepted: false,
167
+ reason_code: standing === 'no_standing'
168
+ ? 'WITHDRAWAL_SIGNER_WITHOUT_STANDING'
169
+ : 'WITHDRAWAL_STANDING_NOT_ESTABLISHED',
170
+ standing,
171
+ withdrawal,
172
+ });
173
+ }
174
+ /**
175
+ * The current position of one revocation together with every withdrawal referencing it.
176
+ *
177
+ * This is the field that did not exist. A verifier that must report "revoked, and the
178
+ * revoker later said this was recorded in error" had nowhere to put the second half, in
179
+ * either reference SDK or in the proposed text, so it could only report the first half and
180
+ * drop the rest.
181
+ *
182
+ * `revocation` is present and unchanged whether or not anything was accepted. Accepted
183
+ * withdrawals are listed, refused ones are listed with their codes, and neither list makes
184
+ * the revocation ineffective: a later finding is a new record that references the earlier
185
+ * one and states its own effect, never an edit of it and never its removal.
186
+ *
187
+ * Withdrawals naming a different revocation are not silently dropped. They are evaluated,
188
+ * refused `WITHDRAWAL_NAMES_NO_HELD_REVOCATION`, and appear in `refused`.
189
+ */
190
+ export function correctedRevocationView(revocation, withdrawals, resolveStanding) {
191
+ const held = [revocation];
192
+ const evaluations = (withdrawals ?? []).map(w => evaluateRevocationWithdrawal(w, held, resolveStanding));
193
+ return Object.freeze({
194
+ revocation,
195
+ accepted: Object.freeze(evaluations.filter(e => e.accepted)),
196
+ refused: Object.freeze(evaluations.filter(e => !e.accepted)),
197
+ });
198
+ }
199
+ //# sourceMappingURL=withdrawal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"withdrawal.js","sourceRoot":"","sources":["../../../../src/v2/authority-state/withdrawal.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ import type { AuthorityBoundFulfilment, AuthorityBoundFulfilmentBody, AuthorityExhaustion, AuthorityExhaustionBody } from './types.js';
2
+ /** Domain tags. Each is a distinct tag followed by one zero byte, the same discipline
3
+ * `AuthorityDelegationV1` and `AuthorityRevocationV1` follow, so bytes minted for one
4
+ * construction can never be read as bytes minted for another. The `PROPOSED-` prefix is
5
+ * part of the tag: if any of this is ever specified, the specified construction will use a
6
+ * different tag and records minted under this one will not verify under it. That is the
7
+ * intended behaviour, not a migration problem to solve later. */
8
+ export declare const AUTHORITY_BOUND_FULFILMENT_SIGNATURE_DOMAIN = "PROPOSED-APS-AUTHORITY-BOUND-FULFILMENT-SIGNATURE-V0\0";
9
+ export declare const AUTHORITY_EXHAUSTION_ID_DOMAIN = "PROPOSED-APS-AUTHORITY-EXHAUSTION-ID-V0\0";
10
+ export declare const AUTHORITY_EXHAUSTION_SIGNATURE_DOMAIN = "PROPOSED-APS-AUTHORITY-EXHAUSTION-SIGNATURE-V0\0";
11
+ /** Exact Ed25519 preimage for a fulfilment attestation: the domain tag plus RFC 8785 JCS of
12
+ * the record with `signature` absent. */
13
+ export declare function authorityBoundFulfilmentSignatureInput(body: AuthorityBoundFulfilmentBody): string;
14
+ /** Write-boundary twin. Use when ISSUING. The verification path keeps calling the
15
+ * unrestricted form, so a record minted before the write rule still verifies. */
16
+ export declare function authorityBoundFulfilmentSignatureInputForWrite(body: AuthorityBoundFulfilmentBody): string;
17
+ export declare function signAuthorityBoundFulfilment(body: AuthorityBoundFulfilmentBody, privateKeyHex: string): string;
18
+ export declare function verifyAuthorityBoundFulfilmentSignature(record: AuthorityBoundFulfilment, publicKeyHex: string): boolean;
19
+ /** Exact preimage for `exhaustion_id`: the ID domain tag plus JCS of the body. */
20
+ export declare function authorityExhaustionIdInput(body: AuthorityExhaustionBody): string;
21
+ export declare function computeAuthorityExhaustionId(body: AuthorityExhaustionBody): string;
22
+ export declare function computeAuthorityExhaustionIdForWrite(body: AuthorityExhaustionBody): string;
23
+ /** Exact Ed25519 preimage for the exhaustion record: the signature domain tag plus JCS of
24
+ * the record with `signature` absent. `exhaustion_id` IS inside this preimage, so the
25
+ * identifier is signed rather than being an unauthenticated label beside the signature. */
26
+ export declare function authorityExhaustionSignatureInput(record: Omit<AuthorityExhaustion, 'signature'>): string;
27
+ export declare function authorityExhaustionSignatureInputForWrite(record: Omit<AuthorityExhaustion, 'signature'>): string;
28
+ export declare function signAuthorityExhaustion(record: Omit<AuthorityExhaustion, 'signature'>, privateKeyHex: string): string;
29
+ export declare function verifyAuthorityExhaustionSignature(record: AuthorityExhaustion, publicKeyHex: string): boolean;
30
+ //# sourceMappingURL=canonical.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"canonical.d.ts","sourceRoot":"","sources":["../../../../src/v2/bounds/canonical.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EACV,wBAAwB,EACxB,4BAA4B,EAC5B,mBAAmB,EACnB,uBAAuB,EACxB,MAAM,YAAY,CAAA;AAEnB;;;;;kEAKkE;AAClE,eAAO,MAAM,2CAA2C,2DACE,CAAA;AAC1D,eAAO,MAAM,8BAA8B,8CAA8C,CAAA;AACzF,eAAO,MAAM,qCAAqC,qDACE,CAAA;AAWpD;0CAC0C;AAC1C,wBAAgB,sCAAsC,CACpD,IAAI,EAAE,4BAA4B,GACjC,MAAM,CAER;AAED;kFACkF;AAClF,wBAAgB,8CAA8C,CAC5D,IAAI,EAAE,4BAA4B,GACjC,MAAM,CAER;AAED,wBAAgB,4BAA4B,CAC1C,IAAI,EAAE,4BAA4B,EAClC,aAAa,EAAE,MAAM,GACpB,MAAM,CAER;AAED,wBAAgB,uCAAuC,CACrD,MAAM,EAAE,wBAAwB,EAChC,YAAY,EAAE,MAAM,GACnB,OAAO,CAQT;AAED,kFAAkF;AAClF,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,uBAAuB,GAAG,MAAM,CAEhF;AAED,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,uBAAuB,GAAG,MAAM,CAElF;AAED,wBAAgB,oCAAoC,CAAC,IAAI,EAAE,uBAAuB,GAAG,MAAM,CAI1F;AAED;;4FAE4F;AAC5F,wBAAgB,iCAAiC,CAC/C,MAAM,EAAE,IAAI,CAAC,mBAAmB,EAAE,WAAW,CAAC,GAC7C,MAAM,CAER;AAED,wBAAgB,yCAAyC,CACvD,MAAM,EAAE,IAAI,CAAC,mBAAmB,EAAE,WAAW,CAAC,GAC7C,MAAM,CAER;AAED,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,IAAI,CAAC,mBAAmB,EAAE,WAAW,CAAC,EAC9C,aAAa,EAAE,MAAM,GACpB,MAAM,CAER;AAED,wBAAgB,kCAAkC,CAChD,MAAM,EAAE,mBAAmB,EAC3B,YAAY,EAAE,MAAM,GACnB,OAAO,CAQT"}
@@ -0,0 +1,69 @@
1
+ // Copyright (c) 2026 Tymofii Pidlisnyi
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ //
4
+ // PROPOSED, OPT-IN. Content addressing and Ed25519 signing for the two records this module
5
+ // declares. Nothing here reimplements JCS, SHA-256 or Ed25519: each comes from the helper
6
+ // the rest of this package already uses.
7
+ //
8
+ // Not required by draft-pidlisnyi-aps-03. See ./types.ts for the specification position.
9
+ import { createHash } from 'node:crypto';
10
+ import { canonicalizeJCS, canonicalizeJCSForWrite } from '../../core/canonical-jcs.js';
11
+ import { sign, verify } from '../../crypto/keys.js';
12
+ /** Domain tags. Each is a distinct tag followed by one zero byte, the same discipline
13
+ * `AuthorityDelegationV1` and `AuthorityRevocationV1` follow, so bytes minted for one
14
+ * construction can never be read as bytes minted for another. The `PROPOSED-` prefix is
15
+ * part of the tag: if any of this is ever specified, the specified construction will use a
16
+ * different tag and records minted under this one will not verify under it. That is the
17
+ * intended behaviour, not a migration problem to solve later. */
18
+ export const AUTHORITY_BOUND_FULFILMENT_SIGNATURE_DOMAIN = 'PROPOSED-APS-AUTHORITY-BOUND-FULFILMENT-SIGNATURE-V0\0';
19
+ export const AUTHORITY_EXHAUSTION_ID_DOMAIN = 'PROPOSED-APS-AUTHORITY-EXHAUSTION-ID-V0\0';
20
+ export const AUTHORITY_EXHAUSTION_SIGNATURE_DOMAIN = 'PROPOSED-APS-AUTHORITY-EXHAUSTION-SIGNATURE-V0\0';
21
+ function sha256Hex(value) {
22
+ return createHash('sha256').update(value, 'utf8').digest('hex');
23
+ }
24
+ function withoutSignature(record) {
25
+ const { signature: _signature, ...body } = record;
26
+ return body;
27
+ }
28
+ /** Exact Ed25519 preimage for a fulfilment attestation: the domain tag plus RFC 8785 JCS of
29
+ * the record with `signature` absent. */
30
+ export function authorityBoundFulfilmentSignatureInput(body) {
31
+ return AUTHORITY_BOUND_FULFILMENT_SIGNATURE_DOMAIN + canonicalizeJCS(body);
32
+ }
33
+ /** Write-boundary twin. Use when ISSUING. The verification path keeps calling the
34
+ * unrestricted form, so a record minted before the write rule still verifies. */
35
+ export function authorityBoundFulfilmentSignatureInputForWrite(body) {
36
+ return AUTHORITY_BOUND_FULFILMENT_SIGNATURE_DOMAIN + canonicalizeJCSForWrite(body);
37
+ }
38
+ export function signAuthorityBoundFulfilment(body, privateKeyHex) {
39
+ return sign(authorityBoundFulfilmentSignatureInputForWrite(body), privateKeyHex);
40
+ }
41
+ export function verifyAuthorityBoundFulfilmentSignature(record, publicKeyHex) {
42
+ return verify(authorityBoundFulfilmentSignatureInput(withoutSignature(record)), record.signature, publicKeyHex);
43
+ }
44
+ /** Exact preimage for `exhaustion_id`: the ID domain tag plus JCS of the body. */
45
+ export function authorityExhaustionIdInput(body) {
46
+ return AUTHORITY_EXHAUSTION_ID_DOMAIN + canonicalizeJCS(body);
47
+ }
48
+ export function computeAuthorityExhaustionId(body) {
49
+ return `sha256:${sha256Hex(authorityExhaustionIdInput(body))}`;
50
+ }
51
+ export function computeAuthorityExhaustionIdForWrite(body) {
52
+ return `sha256:${sha256Hex(AUTHORITY_EXHAUSTION_ID_DOMAIN + canonicalizeJCSForWrite(body))}`;
53
+ }
54
+ /** Exact Ed25519 preimage for the exhaustion record: the signature domain tag plus JCS of
55
+ * the record with `signature` absent. `exhaustion_id` IS inside this preimage, so the
56
+ * identifier is signed rather than being an unauthenticated label beside the signature. */
57
+ export function authorityExhaustionSignatureInput(record) {
58
+ return AUTHORITY_EXHAUSTION_SIGNATURE_DOMAIN + canonicalizeJCS(record);
59
+ }
60
+ export function authorityExhaustionSignatureInputForWrite(record) {
61
+ return AUTHORITY_EXHAUSTION_SIGNATURE_DOMAIN + canonicalizeJCSForWrite(record);
62
+ }
63
+ export function signAuthorityExhaustion(record, privateKeyHex) {
64
+ return sign(authorityExhaustionSignatureInputForWrite(record), privateKeyHex);
65
+ }
66
+ export function verifyAuthorityExhaustionSignature(record, publicKeyHex) {
67
+ return verify(authorityExhaustionSignatureInput(withoutSignature(record)), record.signature, publicKeyHex);
68
+ }
69
+ //# sourceMappingURL=canonical.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"canonical.js","sourceRoot":"","sources":["../../../../src/v2/bounds/canonical.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,sCAAsC;AACtC,EAAE;AACF,2FAA2F;AAC3F,0FAA0F;AAC1F,yCAAyC;AACzC,EAAE;AACF,yFAAyF;AAEzF,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACxC,OAAO,EAAE,eAAe,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAA;AACtF,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAA;AAQnD;;;;;kEAKkE;AAClE,MAAM,CAAC,MAAM,2CAA2C,GACtD,wDAAwD,CAAA;AAC1D,MAAM,CAAC,MAAM,8BAA8B,GAAG,2CAA2C,CAAA;AACzF,MAAM,CAAC,MAAM,qCAAqC,GAChD,kDAAkD,CAAA;AAEpD,SAAS,SAAS,CAAC,KAAa;IAC9B,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;AACjE,CAAC;AAED,SAAS,gBAAgB,CAAkC,MAAS;IAClE,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,GAAG,IAAI,EAAE,GAAG,MAAM,CAAA;IACjD,OAAO,IAAI,CAAA;AACb,CAAC;AAED;0CAC0C;AAC1C,MAAM,UAAU,sCAAsC,CACpD,IAAkC;IAElC,OAAO,2CAA2C,GAAG,eAAe,CAAC,IAAI,CAAC,CAAA;AAC5E,CAAC;AAED;kFACkF;AAClF,MAAM,UAAU,8CAA8C,CAC5D,IAAkC;IAElC,OAAO,2CAA2C,GAAG,uBAAuB,CAAC,IAAI,CAAC,CAAA;AACpF,CAAC;AAED,MAAM,UAAU,4BAA4B,CAC1C,IAAkC,EAClC,aAAqB;IAErB,OAAO,IAAI,CAAC,8CAA8C,CAAC,IAAI,CAAC,EAAE,aAAa,CAAC,CAAA;AAClF,CAAC;AAED,MAAM,UAAU,uCAAuC,CACrD,MAAgC,EAChC,YAAoB;IAEpB,OAAO,MAAM,CACX,sCAAsC,CACpC,gBAAgB,CAAC,MAAM,CAAiC,CACzD,EACD,MAAM,CAAC,SAAS,EAChB,YAAY,CACb,CAAA;AACH,CAAC;AAED,kFAAkF;AAClF,MAAM,UAAU,0BAA0B,CAAC,IAA6B;IACtE,OAAO,8BAA8B,GAAG,eAAe,CAAC,IAAI,CAAC,CAAA;AAC/D,CAAC;AAED,MAAM,UAAU,4BAA4B,CAAC,IAA6B;IACxE,OAAO,UAAU,SAAS,CAAC,0BAA0B,CAAC,IAAI,CAAC,CAAC,EAAE,CAAA;AAChE,CAAC;AAED,MAAM,UAAU,oCAAoC,CAAC,IAA6B;IAChF,OAAO,UAAU,SAAS,CACxB,8BAA8B,GAAG,uBAAuB,CAAC,IAAI,CAAC,CAC/D,EAAE,CAAA;AACL,CAAC;AAED;;4FAE4F;AAC5F,MAAM,UAAU,iCAAiC,CAC/C,MAA8C;IAE9C,OAAO,qCAAqC,GAAG,eAAe,CAAC,MAAM,CAAC,CAAA;AACxE,CAAC;AAED,MAAM,UAAU,yCAAyC,CACvD,MAA8C;IAE9C,OAAO,qCAAqC,GAAG,uBAAuB,CAAC,MAAM,CAAC,CAAA;AAChF,CAAC;AAED,MAAM,UAAU,uBAAuB,CACrC,MAA8C,EAC9C,aAAqB;IAErB,OAAO,IAAI,CAAC,yCAAyC,CAAC,MAAM,CAAC,EAAE,aAAa,CAAC,CAAA;AAC/E,CAAC;AAED,MAAM,UAAU,kCAAkC,CAChD,MAA2B,EAC3B,YAAoB;IAEpB,OAAO,MAAM,CACX,iCAAiC,CAC/B,gBAAgB,CAAC,MAAM,CAA2C,CACnE,EACD,MAAM,CAAC,SAAS,EAChB,YAAY,CACb,CAAA;AACH,CAAC"}
@@ -0,0 +1,107 @@
1
+ import { type AttestorRoleAnswer, type AttestorRoleResolver, type AuthorityBound, type AuthorityBoundFulfilment, type BoundEvaluation, type BoundKind, type BoundVerificationKeyResolver, type FulfilmentAssessment } from './types.js';
2
+ /** Thrown when an input this module cannot read at all is passed. A malformed BOUND is a
3
+ * programming error, not a verdict: the module was asked a question about nothing. A
4
+ * malformed FULFILMENT RECORD is different and never throws, because a record somebody
5
+ * else wrote is data, and the right answer about it is a rejection with a reason code. */
6
+ export declare class AuthorityBoundError extends Error {
7
+ readonly code: string;
8
+ constructor(code: string, message: string);
9
+ }
10
+ export declare function isBoundKind(value: unknown): value is BoundKind;
11
+ export declare function isAttestorRoleAnswer(value: unknown): value is AttestorRoleAnswer;
12
+ /** Shape check for a bound declaration. Throws, for the reason `AuthorityBoundError`
13
+ * documents. */
14
+ export declare function assertAuthorityBound(bound: AuthorityBound): void;
15
+ export interface AssessFulfilmentInput {
16
+ readonly bound: AuthorityBound;
17
+ readonly record: AuthorityBoundFulfilment;
18
+ /** The instant the question is asked at. A record attested later than this is not read:
19
+ * a verifier asked about Tuesday does not get to use Wednesday's evidence. */
20
+ readonly atInstant: string;
21
+ readonly resolveAttestorRole: AttestorRoleResolver;
22
+ readonly resolveVerificationKey: BoundVerificationKeyResolver;
23
+ }
24
+ /**
25
+ * Assess ONE fulfilment record against one bound.
26
+ *
27
+ * The order of the checks is the substance of this function, not an implementation detail.
28
+ * Standing is asked FIRST and authenticity SECOND, and each produces its own code, because
29
+ * "authenticated by somebody who may not say this" and "not authenticated at all" are
30
+ * different failures and collapsing them loses the distinction CAND-01 turns on. A valid
31
+ * signature establishes who signed. It does not establish that the signer was allowed to
32
+ * make this statement.
33
+ *
34
+ * `FULFILMENT_OUTCOME_NOT_FULFILLED` carries no `missing` limbs, and that is deliberate: a
35
+ * record from a party with standing saying the purpose was NOT met is a conclusion the
36
+ * verifier reached, not a gap in its evidence. Every other rejection names a limb.
37
+ *
38
+ * Concept source: aeoess/agent-authority-lifecycle, invariant candidate CAND-01 and
39
+ * invariant candidate BROAD-L7. Proposed.
40
+ */
41
+ export declare function assessFulfilment(input: AssessFulfilmentInput): FulfilmentAssessment;
42
+ export interface EvaluateBoundInput {
43
+ readonly bound: AuthorityBound;
44
+ /** Every fulfilment claim the caller holds for this bound. Order is preserved in the
45
+ * result and does not change the verdict: see the resolution rule below. Empty for a
46
+ * `use_count` or `budget` bound, where no attestation is involved. */
47
+ readonly fulfilments?: readonly AuthorityBoundFulfilment[];
48
+ readonly atInstant: string;
49
+ readonly resolveAttestorRole?: AttestorRoleResolver;
50
+ readonly resolveVerificationKey?: BoundVerificationKeyResolver;
51
+ /** kind `use_count` only: admissions already counted against this bound, as a canonical
52
+ * unsigned decimal integer string. The caller's ledger owns this number. This module
53
+ * does not count admissions, because counting them means holding state across events and
54
+ * a pure function has none. */
55
+ readonly consumed?: string;
56
+ /** kind `budget` only: the committed and reserved totals, exactly as
57
+ * `InMemoryAuthorityBudgetLedger.counter(delegationId)` returns them. The budget kind
58
+ * delegates to that ledger and never reimplements it: draft-03 section 3.4 already
59
+ * states the rule, and the ledger already enforces it. */
60
+ readonly budgetCounter?: {
61
+ readonly committed: string;
62
+ readonly reserved: string;
63
+ };
64
+ }
65
+ /**
66
+ * Evaluate one bound's state at one instant.
67
+ *
68
+ * THE RESOLUTION RULE, and why it is this way round. For a purpose bound:
69
+ *
70
+ * 1. If any fulfilment record was ACCEPTED, the state is `exhausted`.
71
+ * 2. Otherwise, if any record was rejected on an EVIDENTIAL ground (signature, standing,
72
+ * unresolved role, unresolved key, unreadable shape), the state is `not_established`.
73
+ * 3. Otherwise the state is `not_reached`.
74
+ *
75
+ * Step 1 comes before step 2 on purpose, and it is invariant CAND-02's rule made
76
+ * executable: an exhaustion that WAS established is never downgraded by a later claim
77
+ * nobody could authenticate. A later finding is a new record about an earlier one, never a
78
+ * rewrite of it. Because the rule is a fold over the whole set rather than a running
79
+ * mutation, the verdict is the same whatever order the records arrive in, which is what
80
+ * makes it safe for a caller to keep them in an unordered store.
81
+ *
82
+ * Step 3 reads `not_reached` from an empty record set, and that is the one reading here
83
+ * worth arguing with. It is a positive claim: the bound is declared, no evidence reaches
84
+ * it, and under the applicable authority model a purpose that nobody has recorded as met is
85
+ * a purpose that is not met. A model whose default runs the other way (absence of a
86
+ * periodic fulfilment report is itself the trigger) is a model this function cannot
87
+ * express, and a caller in that position should report `not_established` with a `source`
88
+ * limb rather than passing an empty set and reading the answer as a finding. CAND-01's
89
+ * carve-out for a declared default on absence is the reason the disclaimer is here and not
90
+ * a silent assumption.
91
+ *
92
+ * A `use_count` bound needs no records at all: the ADMISSION reaches it, so `consumed`
93
+ * against `value` is the whole computation. A `budget` bound is answered by the ledger's
94
+ * counter, per draft-03 section 3.4, verbatim: "Signatures establish static limits; they do
95
+ * not establish the current cumulative total."
96
+ *
97
+ * Reported ALONGSIDE a chain result, never merged into it, and never in place of it. A
98
+ * grant can be exhausted while its chain still verifies `valid`, which is the whole point:
99
+ * exhaustion is invisible to chain verification. A grant can also be expired AND exhausted,
100
+ * and then the chain result says `EXPIRED` and this says `exhaustion` and neither
101
+ * overwrites the other. Invariant L10.
102
+ *
103
+ * Concept source: aeoess/agent-authority-lifecycle, invariant L10 and invariant candidates
104
+ * CAND-01 and CAND-02. All proposed.
105
+ */
106
+ export declare function evaluateBound(input: EvaluateBoundInput): BoundEvaluation;
107
+ //# sourceMappingURL=evaluate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evaluate.d.ts","sourceRoot":"","sources":["../../../../src/v2/bounds/evaluate.ts"],"names":[],"mappings":"AAYA,OAAO,EAKL,KAAK,kBAAkB,EACvB,KAAK,oBAAoB,EACzB,KAAK,cAAc,EACnB,KAAK,wBAAwB,EAE7B,KAAK,eAAe,EACpB,KAAK,SAAS,EAGd,KAAK,4BAA4B,EACjC,KAAK,oBAAoB,EAC1B,MAAM,YAAY,CAAA;AAEnB;;;2FAG2F;AAC3F,qBAAa,mBAAoB,SAAQ,KAAK;IAC5C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IAErB,YAAY,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAIxC;CACF;AAMD,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,SAAS,CAE9D;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,kBAAkB,CAIhF;AAED;iBACiB;AACjB,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,cAAc,GAAG,IAAI,CAgDhE;AA+CD,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,KAAK,EAAE,cAAc,CAAA;IAC9B,QAAQ,CAAC,MAAM,EAAE,wBAAwB,CAAA;IACzC;mFAC+E;IAC/E,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,mBAAmB,EAAE,oBAAoB,CAAA;IAClD,QAAQ,CAAC,sBAAsB,EAAE,4BAA4B,CAAA;CAC9D;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,GAAG,oBAAoB,CAiFnF;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,KAAK,EAAE,cAAc,CAAA;IAC9B;;2EAEuE;IACvE,QAAQ,CAAC,WAAW,CAAC,EAAE,SAAS,wBAAwB,EAAE,CAAA;IAC1D,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,mBAAmB,CAAC,EAAE,oBAAoB,CAAA;IACnD,QAAQ,CAAC,sBAAsB,CAAC,EAAE,4BAA4B,CAAA;IAC9D;;;oCAGgC;IAChC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;IAC1B;;;+DAG2D;IAC3D,QAAQ,CAAC,aAAa,CAAC,EAAE;QAAE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAA;CACnF;AAyBD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,kBAAkB,GAAG,eAAe,CA6FxE"}