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 @@
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"}
@@ -0,0 +1,315 @@
1
+ // Copyright (c) 2026 Tymofii Pidlisnyi
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ //
4
+ // PROPOSED, OPT-IN. Assessing fulfilment records and evaluating a bound's state.
5
+ //
6
+ // Pure. No clock, no I/O, no network. Every instant compared here is supplied by the
7
+ // caller, and every resolver is the caller's. Not required by draft-pidlisnyi-aps-03; see
8
+ // ./types.ts for the specification position.
9
+ import { lifecycleState, notEstablished } from '../lifecycle-state/state.js';
10
+ import { verifyAuthorityBoundFulfilmentSignature } from './canonical.js';
11
+ import { AUTHORITY_BOUND_FULFILMENT_TYPE, AUTHORITY_BOUND_TYPE, ATTESTOR_ROLE_ANSWERS, BOUND_KINDS, } from './types.js';
12
+ /** Thrown when an input this module cannot read at all is passed. A malformed BOUND is a
13
+ * programming error, not a verdict: the module was asked a question about nothing. A
14
+ * malformed FULFILMENT RECORD is different and never throws, because a record somebody
15
+ * else wrote is data, and the right answer about it is a rejection with a reason code. */
16
+ export class AuthorityBoundError extends Error {
17
+ code;
18
+ constructor(code, message) {
19
+ super(message);
20
+ this.name = 'AuthorityBoundError';
21
+ this.code = code;
22
+ }
23
+ }
24
+ const CANONICAL_UNSIGNED_INTEGER = /^(0|[1-9][0-9]*)$/;
25
+ const DELEGATION_ID = /^sha256:[0-9a-f]{64}$/;
26
+ const SIGNATURE_HEX = /^[0-9a-f]{128}$/;
27
+ export function isBoundKind(value) {
28
+ return typeof value === 'string' && BOUND_KINDS.includes(value);
29
+ }
30
+ export function isAttestorRoleAnswer(value) {
31
+ return (typeof value === 'string' && ATTESTOR_ROLE_ANSWERS.includes(value));
32
+ }
33
+ /** Shape check for a bound declaration. Throws, for the reason `AuthorityBoundError`
34
+ * documents. */
35
+ export function assertAuthorityBound(bound) {
36
+ if (bound === null || typeof bound !== 'object') {
37
+ throw new AuthorityBoundError('BOUND_MALFORMED', 'bound is not an object');
38
+ }
39
+ if (bound.record_type !== AUTHORITY_BOUND_TYPE) {
40
+ throw new AuthorityBoundError('BOUND_RECORD_TYPE_UNSUPPORTED', `record_type must be ${AUTHORITY_BOUND_TYPE}`);
41
+ }
42
+ if (typeof bound.bound_id !== 'string' || bound.bound_id.length === 0) {
43
+ throw new AuthorityBoundError('BOUND_MALFORMED', 'bound_id must be a non-empty string');
44
+ }
45
+ if (typeof bound.delegation_id !== 'string' || !DELEGATION_ID.test(bound.delegation_id)) {
46
+ throw new AuthorityBoundError('BOUND_MALFORMED', 'delegation_id must be sha256:<64 lowercase hex>');
47
+ }
48
+ if (!isBoundKind(bound.kind)) {
49
+ throw new AuthorityBoundError('BOUND_KIND_UNSUPPORTED', `kind must be one of ${BOUND_KINDS.join(', ')}`);
50
+ }
51
+ if (typeof bound.value !== 'string' || bound.value.length === 0) {
52
+ throw new AuthorityBoundError('BOUND_MALFORMED', 'value must be a non-empty string');
53
+ }
54
+ if (bound.kind !== 'purpose' && !CANONICAL_UNSIGNED_INTEGER.test(bound.value)) {
55
+ throw new AuthorityBoundError('BOUND_VALUE_NONCANONICAL', `a ${bound.kind} bound's value must be a canonical unsigned decimal integer`);
56
+ }
57
+ if (!Array.isArray(bound.fulfilment_attestor_roles)) {
58
+ throw new AuthorityBoundError('BOUND_MALFORMED', 'fulfilment_attestor_roles must be an array, empty if nobody but the issuer may attest');
59
+ }
60
+ for (const role of bound.fulfilment_attestor_roles) {
61
+ if (typeof role !== 'string' || role.length === 0) {
62
+ throw new AuthorityBoundError('BOUND_MALFORMED', 'fulfilment_attestor_roles must contain only non-empty strings');
63
+ }
64
+ }
65
+ }
66
+ /** True only for a record this module can read far enough to assess. A record that fails
67
+ * here is rejected with `FULFILMENT_SCHEMA_INVALID`, never thrown on. */
68
+ function readableFulfilment(record) {
69
+ return (record !== null &&
70
+ typeof record === 'object' &&
71
+ record.record_type === AUTHORITY_BOUND_FULFILMENT_TYPE &&
72
+ typeof record.bound_id === 'string' &&
73
+ record.bound_id.length > 0 &&
74
+ typeof record.delegation_id === 'string' &&
75
+ DELEGATION_ID.test(record.delegation_id) &&
76
+ typeof record.attestor === 'string' &&
77
+ record.attestor.length > 0 &&
78
+ typeof record.verification_method === 'string' &&
79
+ record.verification_method.length > 0 &&
80
+ typeof record.attested_at === 'string' &&
81
+ record.attested_at.length > 0 &&
82
+ (record.outcome === 'fulfilled' || record.outcome === 'not_fulfilled') &&
83
+ typeof record.reason_code === 'string' &&
84
+ record.reason_code.length > 0 &&
85
+ typeof record.signature === 'string' &&
86
+ SIGNATURE_HEX.test(record.signature));
87
+ }
88
+ function assessment(attestor, attestedAt, accepted, reasonCode, extra = {}) {
89
+ const out = { attestor, attested_at: attestedAt, accepted, reason_code: reasonCode };
90
+ if (extra.role_answer !== undefined)
91
+ out.role_answer = extra.role_answer;
92
+ if (extra.missing !== undefined)
93
+ out.missing = Object.freeze([...extra.missing]);
94
+ return Object.freeze(out);
95
+ }
96
+ /**
97
+ * Assess ONE fulfilment record against one bound.
98
+ *
99
+ * The order of the checks is the substance of this function, not an implementation detail.
100
+ * Standing is asked FIRST and authenticity SECOND, and each produces its own code, because
101
+ * "authenticated by somebody who may not say this" and "not authenticated at all" are
102
+ * different failures and collapsing them loses the distinction CAND-01 turns on. A valid
103
+ * signature establishes who signed. It does not establish that the signer was allowed to
104
+ * make this statement.
105
+ *
106
+ * `FULFILMENT_OUTCOME_NOT_FULFILLED` carries no `missing` limbs, and that is deliberate: a
107
+ * record from a party with standing saying the purpose was NOT met is a conclusion the
108
+ * verifier reached, not a gap in its evidence. Every other rejection names a limb.
109
+ *
110
+ * Concept source: aeoess/agent-authority-lifecycle, invariant candidate CAND-01 and
111
+ * invariant candidate BROAD-L7. Proposed.
112
+ */
113
+ export function assessFulfilment(input) {
114
+ assertAuthorityBound(input.bound);
115
+ const { bound, record, atInstant } = input;
116
+ if (bound.kind !== 'purpose') {
117
+ return assessment('', '', false, 'FULFILMENT_NOT_APPLICABLE_TO_KIND', {
118
+ missing: ['coverage'],
119
+ });
120
+ }
121
+ if (!readableFulfilment(record)) {
122
+ return assessment('', '', false, 'FULFILMENT_SCHEMA_INVALID', { missing: ['source'] });
123
+ }
124
+ const attestor = record.attestor;
125
+ const attestedAt = record.attested_at;
126
+ // The record has to be about THIS bound on THIS delegation. A coverage gap: the claim does
127
+ // not state that it covers what the verdict needed.
128
+ if (record.bound_id !== bound.bound_id || record.delegation_id !== bound.delegation_id) {
129
+ return assessment(attestor, attestedAt, false, 'FULFILMENT_NOT_BOUND_TO_BOUND', {
130
+ missing: ['coverage'],
131
+ });
132
+ }
133
+ if (attestedAt > atInstant) {
134
+ return assessment(attestor, attestedAt, false, 'FULFILMENT_NOT_YET_ATTESTED', {
135
+ missing: ['coverage'],
136
+ });
137
+ }
138
+ const roleAnswer = input.resolveAttestorRole(attestor, bound.fulfilment_attestor_roles, atInstant);
139
+ if (!isAttestorRoleAnswer(roleAnswer)) {
140
+ return assessment(attestor, attestedAt, false, 'FULFILMENT_ATTESTOR_ROLE_UNKNOWN', {
141
+ missing: ['source'],
142
+ });
143
+ }
144
+ if (roleAnswer === 'unknown') {
145
+ return assessment(attestor, attestedAt, false, 'FULFILMENT_ATTESTOR_ROLE_UNKNOWN', {
146
+ role_answer: roleAnswer,
147
+ missing: ['source'],
148
+ });
149
+ }
150
+ if (roleAnswer === 'does_not_hold_role') {
151
+ return assessment(attestor, attestedAt, false, 'FULFILMENT_ATTESTOR_WITHOUT_STANDING', {
152
+ role_answer: roleAnswer,
153
+ missing: ['source'],
154
+ });
155
+ }
156
+ const publicKey = input.resolveVerificationKey(attestor, record.verification_method, attestedAt);
157
+ if (typeof publicKey !== 'string' || publicKey.length === 0) {
158
+ return assessment(attestor, attestedAt, false, 'FULFILMENT_KEY_UNRESOLVED', {
159
+ role_answer: roleAnswer,
160
+ missing: ['source'],
161
+ });
162
+ }
163
+ if (!verifyAuthorityBoundFulfilmentSignature(record, publicKey)) {
164
+ return assessment(attestor, attestedAt, false, 'FULFILMENT_SIGNATURE_INVALID', {
165
+ role_answer: roleAnswer,
166
+ missing: ['source'],
167
+ });
168
+ }
169
+ if (record.outcome !== 'fulfilled') {
170
+ return assessment(attestor, attestedAt, false, 'FULFILMENT_OUTCOME_NOT_FULFILLED', {
171
+ role_answer: roleAnswer,
172
+ });
173
+ }
174
+ return assessment(attestor, attestedAt, true, 'FULFILMENT_ACCEPTED', {
175
+ role_answer: roleAnswer,
176
+ });
177
+ }
178
+ function decimal(value, fallback) {
179
+ const raw = value ?? fallback;
180
+ if (!CANONICAL_UNSIGNED_INTEGER.test(raw)) {
181
+ throw new AuthorityBoundError('COUNTER_NONCANONICAL', `expected a canonical unsigned decimal integer, got ${JSON.stringify(raw)}`);
182
+ }
183
+ return BigInt(raw);
184
+ }
185
+ function lifecycleFor(state, reasonCode, missing) {
186
+ if (state === 'not_established')
187
+ return notEstablished(missing, reasonCode);
188
+ return lifecycleState({
189
+ verdict: state === 'exhausted' ? 'invalid' : 'valid',
190
+ reason_code: reasonCode,
191
+ });
192
+ }
193
+ /**
194
+ * Evaluate one bound's state at one instant.
195
+ *
196
+ * THE RESOLUTION RULE, and why it is this way round. For a purpose bound:
197
+ *
198
+ * 1. If any fulfilment record was ACCEPTED, the state is `exhausted`.
199
+ * 2. Otherwise, if any record was rejected on an EVIDENTIAL ground (signature, standing,
200
+ * unresolved role, unresolved key, unreadable shape), the state is `not_established`.
201
+ * 3. Otherwise the state is `not_reached`.
202
+ *
203
+ * Step 1 comes before step 2 on purpose, and it is invariant CAND-02's rule made
204
+ * executable: an exhaustion that WAS established is never downgraded by a later claim
205
+ * nobody could authenticate. A later finding is a new record about an earlier one, never a
206
+ * rewrite of it. Because the rule is a fold over the whole set rather than a running
207
+ * mutation, the verdict is the same whatever order the records arrive in, which is what
208
+ * makes it safe for a caller to keep them in an unordered store.
209
+ *
210
+ * Step 3 reads `not_reached` from an empty record set, and that is the one reading here
211
+ * worth arguing with. It is a positive claim: the bound is declared, no evidence reaches
212
+ * it, and under the applicable authority model a purpose that nobody has recorded as met is
213
+ * a purpose that is not met. A model whose default runs the other way (absence of a
214
+ * periodic fulfilment report is itself the trigger) is a model this function cannot
215
+ * express, and a caller in that position should report `not_established` with a `source`
216
+ * limb rather than passing an empty set and reading the answer as a finding. CAND-01's
217
+ * carve-out for a declared default on absence is the reason the disclaimer is here and not
218
+ * a silent assumption.
219
+ *
220
+ * A `use_count` bound needs no records at all: the ADMISSION reaches it, so `consumed`
221
+ * against `value` is the whole computation. A `budget` bound is answered by the ledger's
222
+ * counter, per draft-03 section 3.4, verbatim: "Signatures establish static limits; they do
223
+ * not establish the current cumulative total."
224
+ *
225
+ * Reported ALONGSIDE a chain result, never merged into it, and never in place of it. A
226
+ * grant can be exhausted while its chain still verifies `valid`, which is the whole point:
227
+ * exhaustion is invisible to chain verification. A grant can also be expired AND exhausted,
228
+ * and then the chain result says `EXPIRED` and this says `exhaustion` and neither
229
+ * overwrites the other. Invariant L10.
230
+ *
231
+ * Concept source: aeoess/agent-authority-lifecycle, invariant L10 and invariant candidates
232
+ * CAND-01 and CAND-02. All proposed.
233
+ */
234
+ export function evaluateBound(input) {
235
+ assertAuthorityBound(input.bound);
236
+ const { bound } = input;
237
+ if (typeof input.atInstant !== 'string' || input.atInstant.length === 0) {
238
+ throw new AuthorityBoundError('INSTANT_MISSING', 'atInstant must be a non-empty string');
239
+ }
240
+ const assessments = [];
241
+ let state;
242
+ let reasonCode;
243
+ let remaining;
244
+ const missing = [];
245
+ if (bound.kind === 'purpose') {
246
+ const records = input.fulfilments ?? [];
247
+ if (records.length > 0) {
248
+ if (typeof input.resolveAttestorRole !== 'function') {
249
+ throw new AuthorityBoundError('ROLE_RESOLVER_MISSING', 'a purpose bound with fulfilment records needs resolveAttestorRole');
250
+ }
251
+ if (typeof input.resolveVerificationKey !== 'function') {
252
+ throw new AuthorityBoundError('KEY_RESOLVER_MISSING', 'a purpose bound with fulfilment records needs resolveVerificationKey');
253
+ }
254
+ }
255
+ const resolveAttestorRole = input.resolveAttestorRole ?? (() => 'unknown');
256
+ const resolveVerificationKey = input.resolveVerificationKey ?? (() => null);
257
+ for (const record of records) {
258
+ assessments.push(assessFulfilment({
259
+ bound,
260
+ record,
261
+ atInstant: input.atInstant,
262
+ resolveAttestorRole,
263
+ resolveVerificationKey,
264
+ }));
265
+ }
266
+ const accepted = assessments.some(a => a.accepted);
267
+ const unestablished = assessments.filter(a => !a.accepted && a.missing !== undefined);
268
+ if (accepted) {
269
+ state = 'exhausted';
270
+ reasonCode = 'PURPOSE_EXHAUSTED';
271
+ }
272
+ else if (unestablished.length > 0) {
273
+ state = 'not_established';
274
+ reasonCode = 'BOUND_STATE_NOT_ESTABLISHED';
275
+ for (const a of unestablished) {
276
+ for (const gap of a.missing ?? [])
277
+ if (!missing.includes(gap))
278
+ missing.push(gap);
279
+ }
280
+ }
281
+ else {
282
+ state = 'not_reached';
283
+ reasonCode = 'BOUND_NOT_REACHED';
284
+ }
285
+ }
286
+ else if (bound.kind === 'use_count') {
287
+ const limit = decimal(bound.value, '0');
288
+ const consumed = decimal(input.consumed, '0');
289
+ const left = consumed >= limit ? 0n : limit - consumed;
290
+ remaining = left.toString(10);
291
+ state = consumed >= limit ? 'exhausted' : 'not_reached';
292
+ reasonCode = state === 'exhausted' ? 'USE_COUNT_EXHAUSTED' : 'BOUND_NOT_REACHED';
293
+ }
294
+ else {
295
+ const ceiling = decimal(bound.value, '0');
296
+ const committed = decimal(input.budgetCounter?.committed, '0');
297
+ const reserved = decimal(input.budgetCounter?.reserved, '0');
298
+ state = committed + reserved >= ceiling ? 'exhausted' : 'not_reached';
299
+ reasonCode = state === 'exhausted' ? 'BUDGET_EXHAUSTED' : 'BOUND_NOT_REACHED';
300
+ }
301
+ const ending = state === 'exhausted' ? 'exhaustion' : null;
302
+ const result = {
303
+ bound_id: bound.bound_id,
304
+ kind: bound.kind,
305
+ bound_state: state,
306
+ reason_code: reasonCode,
307
+ ending,
308
+ lifecycle: lifecycleFor(state, reasonCode, missing.length > 0 ? missing : ['source']),
309
+ fulfilments: Object.freeze([...assessments]),
310
+ };
311
+ if (remaining !== undefined)
312
+ result.remaining = remaining;
313
+ return Object.freeze(result);
314
+ }
315
+ //# sourceMappingURL=evaluate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evaluate.js","sourceRoot":"","sources":["../../../../src/v2/bounds/evaluate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ export * from './types.js';
2
+ export * from './canonical.js';
3
+ export * from './evaluate.js';
4
+ export * from './record.js';
5
+ export * from './purpose.js';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/v2/bounds/index.ts"],"names":[],"mappings":"AAQA,cAAc,YAAY,CAAA;AAC1B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,eAAe,CAAA;AAC7B,cAAc,aAAa,CAAA;AAC3B,cAAc,cAAc,CAAA"}
@@ -0,0 +1,13 @@
1
+ // Copyright (c) 2026 Tymofii Pidlisnyi
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ //
4
+ // PROPOSED, OPT-IN. Non-time bounds on a grant: purpose, use count and budget.
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 L10 and
7
+ // invariant candidates CAND-01 and CAND-02. See ./types.ts.
8
+ export * from './types.js';
9
+ export * from './canonical.js';
10
+ export * from './evaluate.js';
11
+ export * from './record.js';
12
+ export * from './purpose.js';
13
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/v2/bounds/index.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,sCAAsC;AACtC,EAAE;AACF,+EAA+E;AAC/E,2FAA2F;AAC3F,0FAA0F;AAC1F,4DAA4D;AAE5D,cAAc,YAAY,CAAA;AAC1B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,eAAe,CAAA;AAC7B,cAAc,aAAa,CAAA;AAC3B,cAAc,cAAc,CAAA"}
@@ -0,0 +1,2 @@
1
+ export { isPurposePermitted, purposeCategory } from '../../core/data-lifecycle.js';
2
+ //# sourceMappingURL=purpose.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"purpose.d.ts","sourceRoot":"","sources":["../../../../src/v2/bounds/purpose.ts"],"names":[],"mappings":"AAsBA,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAA"}
@@ -0,0 +1,23 @@
1
+ // Copyright (c) 2026 Tymofii Pidlisnyi
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ //
4
+ // PROPOSED module, but these two functions are NOT new and NOT proposed. They are the
5
+ // hierarchical purpose helpers that have shipped in `src/core/data-lifecycle.ts` since
6
+ // before this module existed, re-exported here so that both reference SDKs agree on where
7
+ // purpose membership lives.
8
+ //
9
+ // WHY THE RE-EXPORT. The Python SDK had no port of either function. Adding them there under
10
+ // a `data_lifecycle` module, to hold two functions, would have put the same primitive at two
11
+ // unrelated paths in the two languages, which becomes a cross-language test annoyance the
12
+ // first time a vector references it. Both SDKs now expose them from the bounds module, and
13
+ // the TypeScript original stays exported from its old path too, so nothing that imports it
14
+ // today changes.
15
+ //
16
+ // PURPOSE MEMBERSHIP IS NOT PURPOSE EXHAUSTION, and the distinction is the reason this file
17
+ // carries a comment at all. `isPurposePermitted` answers whether a requested purpose falls
18
+ // inside a set of allowed purposes. It answers `true` for the second compressor purchase
19
+ // exactly as it does for the first. Membership can therefore never decide exhaustion, and a
20
+ // boundary that checks only membership is the defective implementation the purpose-bound
21
+ // case corpus exists to catch. `evaluateBound` is the exhaustion question.
22
+ export { isPurposePermitted, purposeCategory } from '../../core/data-lifecycle.js';
23
+ //# sourceMappingURL=purpose.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"purpose.js","sourceRoot":"","sources":["../../../../src/v2/bounds/purpose.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,sCAAsC;AACtC,EAAE;AACF,sFAAsF;AACtF,uFAAuF;AACvF,0FAA0F;AAC1F,4BAA4B;AAC5B,EAAE;AACF,4FAA4F;AAC5F,6FAA6F;AAC7F,0FAA0F;AAC1F,2FAA2F;AAC3F,2FAA2F;AAC3F,iBAAiB;AACjB,EAAE;AACF,4FAA4F;AAC5F,2FAA2F;AAC3F,yFAAyF;AACzF,4FAA4F;AAC5F,yFAAyF;AACzF,2EAA2E;AAE3E,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAA"}