@suveren/gateway 0.40.0 → 0.41.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 (301) hide show
  1. package/content/guides/6-risks.md +1 -0
  2. package/dist/control-plane/index.mjs +182 -37
  3. package/dist/mcp-server/http.mjs +357 -71
  4. package/dist/ui/assets/{index-C-lA_7Lt.js → index-CO-dj98E.js} +27 -27
  5. package/dist/ui/index.html +1 -1
  6. package/node_modules/@hap/core/README.md +3 -3
  7. package/node_modules/@hap/core/dist/index.d.mts +567 -123
  8. package/node_modules/@hap/core/dist/index.d.ts +567 -123
  9. package/node_modules/@hap/core/dist/index.js +869 -23
  10. package/node_modules/@hap/core/dist/index.mjs +829 -22
  11. package/node_modules/@hap/core/node_modules/@hpke/core/LICENSE +21 -0
  12. package/node_modules/@hap/core/node_modules/@hpke/core/README.md +263 -0
  13. package/node_modules/@hap/core/node_modules/@hpke/core/esm/mod.d.ts +11 -0
  14. package/node_modules/@hap/core/node_modules/@hpke/core/esm/mod.d.ts.map +1 -0
  15. package/node_modules/@hap/core/node_modules/@hpke/core/esm/mod.js +6 -0
  16. package/node_modules/@hap/core/node_modules/@hpke/core/esm/package.json +3 -0
  17. package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/aeads/aesGcm.d.ts +80 -0
  18. package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/aeads/aesGcm.d.ts.map +1 -0
  19. package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/aeads/aesGcm.js +167 -0
  20. package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/aeads/exportOnly.d.ts +34 -0
  21. package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/aeads/exportOnly.d.ts.map +1 -0
  22. package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/aeads/exportOnly.js +56 -0
  23. package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/cipherSuiteNative.d.ts +145 -0
  24. package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/cipherSuiteNative.d.ts.map +1 -0
  25. package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/cipherSuiteNative.js +326 -0
  26. package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/encryptionContext.d.ts +15 -0
  27. package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/encryptionContext.d.ts.map +1 -0
  28. package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/encryptionContext.js +68 -0
  29. package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/exporterContext.d.ts +19 -0
  30. package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/exporterContext.d.ts.map +1 -0
  31. package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/exporterContext.js +62 -0
  32. package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/interfaces/aeadParams.d.ts +17 -0
  33. package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/interfaces/aeadParams.d.ts.map +1 -0
  34. package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/interfaces/aeadParams.js +1 -0
  35. package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/interfaces/cipherSuiteParams.d.ts +13 -0
  36. package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/interfaces/cipherSuiteParams.d.ts.map +1 -0
  37. package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/interfaces/cipherSuiteParams.js +1 -0
  38. package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/interfaces/encapsulator.d.ts +8 -0
  39. package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/interfaces/encapsulator.d.ts.map +1 -0
  40. package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/interfaces/encapsulator.js +1 -0
  41. package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/interfaces/encryptionContext.d.ts +40 -0
  42. package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/interfaces/encryptionContext.d.ts.map +1 -0
  43. package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/interfaces/encryptionContext.js +1 -0
  44. package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/interfaces/exporter.d.ts +17 -0
  45. package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/interfaces/exporter.d.ts.map +1 -0
  46. package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/interfaces/exporter.js +1 -0
  47. package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/interfaces/keyInfo.d.ts +7 -0
  48. package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/interfaces/keyInfo.d.ts.map +1 -0
  49. package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/interfaces/keyInfo.js +1 -0
  50. package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/interfaces/responses.d.ts +10 -0
  51. package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/interfaces/responses.d.ts.map +1 -0
  52. package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/interfaces/responses.js +1 -0
  53. package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/kems/dhkemNative.d.ts +26 -0
  54. package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/kems/dhkemNative.d.ts.map +1 -0
  55. package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/kems/dhkemNative.js +112 -0
  56. package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/kems/dhkemPrimitives/x25519.d.ts +24 -0
  57. package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/kems/dhkemPrimitives/x25519.d.ts.map +1 -0
  58. package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/kems/dhkemPrimitives/x25519.js +214 -0
  59. package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/kems/dhkemPrimitives/x448.d.ts +24 -0
  60. package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/kems/dhkemPrimitives/x448.d.ts.map +1 -0
  61. package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/kems/dhkemPrimitives/x448.js +214 -0
  62. package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/kems/dhkemX25519.d.ts +38 -0
  63. package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/kems/dhkemX25519.d.ts.map +1 -0
  64. package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/kems/dhkemX25519.js +66 -0
  65. package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/kems/dhkemX448.d.ts +38 -0
  66. package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/kems/dhkemX448.d.ts.map +1 -0
  67. package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/kems/dhkemX448.js +66 -0
  68. package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/mutex.d.ts +5 -0
  69. package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/mutex.d.ts.map +1 -0
  70. package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/mutex.js +28 -0
  71. package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/native.d.ts +236 -0
  72. package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/native.d.ts.map +1 -0
  73. package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/native.js +235 -0
  74. package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/recipientContext.d.ts +6 -0
  75. package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/recipientContext.d.ts.map +1 -0
  76. package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/recipientContext.js +38 -0
  77. package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/senderContext.d.ts +11 -0
  78. package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/senderContext.d.ts.map +1 -0
  79. package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/senderContext.js +45 -0
  80. package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/utils/emitNotSupported.d.ts +2 -0
  81. package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/utils/emitNotSupported.d.ts.map +1 -0
  82. package/node_modules/@hap/core/node_modules/@hpke/core/esm/src/utils/emitNotSupported.js +6 -0
  83. package/node_modules/@hap/core/node_modules/@hpke/core/package.json +46 -0
  84. package/node_modules/@hap/core/node_modules/@hpke/core/script/mod.d.ts +11 -0
  85. package/node_modules/@hap/core/node_modules/@hpke/core/script/mod.d.ts.map +1 -0
  86. package/node_modules/@hap/core/node_modules/@hpke/core/script/mod.js +47 -0
  87. package/node_modules/@hap/core/node_modules/@hpke/core/script/package.json +3 -0
  88. package/node_modules/@hap/core/node_modules/@hpke/core/script/src/aeads/aesGcm.d.ts +80 -0
  89. package/node_modules/@hap/core/node_modules/@hpke/core/script/src/aeads/aesGcm.d.ts.map +1 -0
  90. package/node_modules/@hap/core/node_modules/@hpke/core/script/src/aeads/aesGcm.js +183 -0
  91. package/node_modules/@hap/core/node_modules/@hpke/core/script/src/aeads/exportOnly.d.ts +34 -0
  92. package/node_modules/@hap/core/node_modules/@hpke/core/script/src/aeads/exportOnly.d.ts.map +1 -0
  93. package/node_modules/@hap/core/node_modules/@hpke/core/script/src/aeads/exportOnly.js +70 -0
  94. package/node_modules/@hap/core/node_modules/@hpke/core/script/src/cipherSuiteNative.d.ts +145 -0
  95. package/node_modules/@hap/core/node_modules/@hpke/core/script/src/cipherSuiteNative.d.ts.map +1 -0
  96. package/node_modules/@hap/core/node_modules/@hpke/core/script/src/cipherSuiteNative.js +340 -0
  97. package/node_modules/@hap/core/node_modules/@hpke/core/script/src/encryptionContext.d.ts +15 -0
  98. package/node_modules/@hap/core/node_modules/@hpke/core/script/src/encryptionContext.d.ts.map +1 -0
  99. package/node_modules/@hap/core/node_modules/@hpke/core/script/src/encryptionContext.js +82 -0
  100. package/node_modules/@hap/core/node_modules/@hpke/core/script/src/exporterContext.d.ts +19 -0
  101. package/node_modules/@hap/core/node_modules/@hpke/core/script/src/exporterContext.d.ts.map +1 -0
  102. package/node_modules/@hap/core/node_modules/@hpke/core/script/src/exporterContext.js +78 -0
  103. package/node_modules/@hap/core/node_modules/@hpke/core/script/src/interfaces/aeadParams.d.ts +17 -0
  104. package/node_modules/@hap/core/node_modules/@hpke/core/script/src/interfaces/aeadParams.d.ts.map +1 -0
  105. package/node_modules/@hap/core/node_modules/@hpke/core/script/src/interfaces/aeadParams.js +12 -0
  106. package/node_modules/@hap/core/node_modules/@hpke/core/script/src/interfaces/cipherSuiteParams.d.ts +13 -0
  107. package/node_modules/@hap/core/node_modules/@hpke/core/script/src/interfaces/cipherSuiteParams.d.ts.map +1 -0
  108. package/node_modules/@hap/core/node_modules/@hpke/core/script/src/interfaces/cipherSuiteParams.js +12 -0
  109. package/node_modules/@hap/core/node_modules/@hpke/core/script/src/interfaces/encapsulator.d.ts +8 -0
  110. package/node_modules/@hap/core/node_modules/@hpke/core/script/src/interfaces/encapsulator.d.ts.map +1 -0
  111. package/node_modules/@hap/core/node_modules/@hpke/core/script/src/interfaces/encapsulator.js +12 -0
  112. package/node_modules/@hap/core/node_modules/@hpke/core/script/src/interfaces/encryptionContext.d.ts +40 -0
  113. package/node_modules/@hap/core/node_modules/@hpke/core/script/src/interfaces/encryptionContext.d.ts.map +1 -0
  114. package/node_modules/@hap/core/node_modules/@hpke/core/script/src/interfaces/encryptionContext.js +12 -0
  115. package/node_modules/@hap/core/node_modules/@hpke/core/script/src/interfaces/exporter.d.ts +17 -0
  116. package/node_modules/@hap/core/node_modules/@hpke/core/script/src/interfaces/exporter.d.ts.map +1 -0
  117. package/node_modules/@hap/core/node_modules/@hpke/core/script/src/interfaces/exporter.js +12 -0
  118. package/node_modules/@hap/core/node_modules/@hpke/core/script/src/interfaces/keyInfo.d.ts +7 -0
  119. package/node_modules/@hap/core/node_modules/@hpke/core/script/src/interfaces/keyInfo.d.ts.map +1 -0
  120. package/node_modules/@hap/core/node_modules/@hpke/core/script/src/interfaces/keyInfo.js +12 -0
  121. package/node_modules/@hap/core/node_modules/@hpke/core/script/src/interfaces/responses.d.ts +10 -0
  122. package/node_modules/@hap/core/node_modules/@hpke/core/script/src/interfaces/responses.d.ts.map +1 -0
  123. package/node_modules/@hap/core/node_modules/@hpke/core/script/src/interfaces/responses.js +12 -0
  124. package/node_modules/@hap/core/node_modules/@hpke/core/script/src/kems/dhkemNative.d.ts +26 -0
  125. package/node_modules/@hap/core/node_modules/@hpke/core/script/src/kems/dhkemNative.d.ts.map +1 -0
  126. package/node_modules/@hap/core/node_modules/@hpke/core/script/src/kems/dhkemNative.js +128 -0
  127. package/node_modules/@hap/core/node_modules/@hpke/core/script/src/kems/dhkemPrimitives/x25519.d.ts +24 -0
  128. package/node_modules/@hap/core/node_modules/@hpke/core/script/src/kems/dhkemPrimitives/x25519.d.ts.map +1 -0
  129. package/node_modules/@hap/core/node_modules/@hpke/core/script/src/kems/dhkemPrimitives/x25519.js +228 -0
  130. package/node_modules/@hap/core/node_modules/@hpke/core/script/src/kems/dhkemPrimitives/x448.d.ts +24 -0
  131. package/node_modules/@hap/core/node_modules/@hpke/core/script/src/kems/dhkemPrimitives/x448.d.ts.map +1 -0
  132. package/node_modules/@hap/core/node_modules/@hpke/core/script/src/kems/dhkemPrimitives/x448.js +228 -0
  133. package/node_modules/@hap/core/node_modules/@hpke/core/script/src/kems/dhkemX25519.d.ts +38 -0
  134. package/node_modules/@hap/core/node_modules/@hpke/core/script/src/kems/dhkemX25519.d.ts.map +1 -0
  135. package/node_modules/@hap/core/node_modules/@hpke/core/script/src/kems/dhkemX25519.js +80 -0
  136. package/node_modules/@hap/core/node_modules/@hpke/core/script/src/kems/dhkemX448.d.ts +38 -0
  137. package/node_modules/@hap/core/node_modules/@hpke/core/script/src/kems/dhkemX448.d.ts.map +1 -0
  138. package/node_modules/@hap/core/node_modules/@hpke/core/script/src/kems/dhkemX448.js +80 -0
  139. package/node_modules/@hap/core/node_modules/@hpke/core/script/src/mutex.d.ts +5 -0
  140. package/node_modules/@hap/core/node_modules/@hpke/core/script/src/mutex.d.ts.map +1 -0
  141. package/node_modules/@hap/core/node_modules/@hpke/core/script/src/mutex.js +42 -0
  142. package/node_modules/@hap/core/node_modules/@hpke/core/script/src/native.d.ts +236 -0
  143. package/node_modules/@hap/core/node_modules/@hpke/core/script/src/native.d.ts.map +1 -0
  144. package/node_modules/@hap/core/node_modules/@hpke/core/script/src/native.js +255 -0
  145. package/node_modules/@hap/core/node_modules/@hpke/core/script/src/recipientContext.d.ts +6 -0
  146. package/node_modules/@hap/core/node_modules/@hpke/core/script/src/recipientContext.d.ts.map +1 -0
  147. package/node_modules/@hap/core/node_modules/@hpke/core/script/src/recipientContext.js +52 -0
  148. package/node_modules/@hap/core/node_modules/@hpke/core/script/src/senderContext.d.ts +11 -0
  149. package/node_modules/@hap/core/node_modules/@hpke/core/script/src/senderContext.d.ts.map +1 -0
  150. package/node_modules/@hap/core/node_modules/@hpke/core/script/src/senderContext.js +59 -0
  151. package/node_modules/@hap/core/node_modules/@hpke/core/script/src/utils/emitNotSupported.d.ts +2 -0
  152. package/node_modules/@hap/core/node_modules/@hpke/core/script/src/utils/emitNotSupported.d.ts.map +1 -0
  153. package/node_modules/@hap/core/node_modules/@hpke/core/script/src/utils/emitNotSupported.js +19 -0
  154. package/node_modules/@hap/core/package.json +2 -1
  155. package/node_modules/@hap/core/src/canonicalize.ts +9 -0
  156. package/node_modules/@hap/core/src/commitment-modes.ts +21 -9
  157. package/node_modules/@hap/core/src/errors.ts +24 -8
  158. package/node_modules/@hap/core/src/gatekeeper.ts +52 -8
  159. package/node_modules/@hap/core/src/index.ts +5 -1
  160. package/node_modules/@hap/core/src/issuance.ts +250 -0
  161. package/node_modules/@hap/core/src/mandate.ts +52 -14
  162. package/node_modules/@hap/core/src/owner-signature.ts +86 -39
  163. package/node_modules/@hap/core/src/profile.ts +45 -0
  164. package/node_modules/@hap/core/src/proposal-content.ts +219 -0
  165. package/node_modules/@hap/core/src/ticket-projection.ts +167 -0
  166. package/node_modules/@hap/core/src/ticket.ts +254 -20
  167. package/node_modules/@hap/core/src/types.ts +33 -5
  168. package/node_modules/@hap/core/src/verifier-policy.ts +178 -0
  169. package/node_modules/@hap/core/src/versions.ts +50 -19
  170. package/node_modules/@hono/node-server/dist/index.cjs +31 -6
  171. package/node_modules/@hono/node-server/dist/index.mjs +31 -6
  172. package/node_modules/@hono/node-server/package.json +1 -1
  173. package/node_modules/@hpke/common/esm/package.json +5 -1
  174. package/node_modules/@hpke/common/esm/src/curve/montgomery.d.ts +2 -2
  175. package/node_modules/@hpke/common/esm/src/curve/montgomery.d.ts.map +1 -1
  176. package/node_modules/@hpke/common/esm/src/curve/montgomery.js +41 -26
  177. package/node_modules/@hpke/common/esm/src/hash/sha3.d.ts.map +1 -1
  178. package/node_modules/@hpke/common/esm/src/hash/sha3.js +0 -15
  179. package/node_modules/@hpke/common/esm/src/kdfs/hkdf.d.ts +2 -1
  180. package/node_modules/@hpke/common/esm/src/kdfs/hkdf.d.ts.map +1 -1
  181. package/node_modules/@hpke/common/esm/src/kdfs/hkdf.js +12 -2
  182. package/node_modules/@hpke/common/esm/src/kems/dhkemPrimitives/xCurve.d.ts.map +1 -1
  183. package/node_modules/@hpke/common/esm/src/kems/dhkemPrimitives/xCurve.js +14 -3
  184. package/node_modules/@hpke/common/esm/src/utils/misc.d.ts +6 -0
  185. package/node_modules/@hpke/common/esm/src/utils/misc.d.ts.map +1 -1
  186. package/node_modules/@hpke/common/esm/src/utils/misc.js +43 -10
  187. package/node_modules/@hpke/common/esm/src/utils/noble.d.ts +1 -1
  188. package/node_modules/@hpke/common/esm/src/utils/noble.d.ts.map +1 -1
  189. package/node_modules/@hpke/common/esm/src/utils/noble.js +21 -10
  190. package/node_modules/@hpke/common/package.json +5 -1
  191. package/node_modules/@hpke/common/script/src/curve/montgomery.d.ts +2 -2
  192. package/node_modules/@hpke/common/script/src/curve/montgomery.d.ts.map +1 -1
  193. package/node_modules/@hpke/common/script/src/curve/montgomery.js +40 -25
  194. package/node_modules/@hpke/common/script/src/hash/sha3.d.ts.map +1 -1
  195. package/node_modules/@hpke/common/script/src/hash/sha3.js +0 -15
  196. package/node_modules/@hpke/common/script/src/kdfs/hkdf.d.ts +2 -1
  197. package/node_modules/@hpke/common/script/src/kdfs/hkdf.d.ts.map +1 -1
  198. package/node_modules/@hpke/common/script/src/kdfs/hkdf.js +12 -2
  199. package/node_modules/@hpke/common/script/src/kems/dhkemPrimitives/xCurve.d.ts.map +1 -1
  200. package/node_modules/@hpke/common/script/src/kems/dhkemPrimitives/xCurve.js +13 -2
  201. package/node_modules/@hpke/common/script/src/utils/misc.d.ts +6 -0
  202. package/node_modules/@hpke/common/script/src/utils/misc.d.ts.map +1 -1
  203. package/node_modules/@hpke/common/script/src/utils/misc.js +43 -9
  204. package/node_modules/@hpke/common/script/src/utils/noble.d.ts +1 -1
  205. package/node_modules/@hpke/common/script/src/utils/noble.d.ts.map +1 -1
  206. package/node_modules/@hpke/common/script/src/utils/noble.js +22 -11
  207. package/node_modules/@hpke/core/README.md +56 -56
  208. package/node_modules/@hpke/core/esm/package.json +2 -1
  209. package/node_modules/@hpke/core/esm/src/kems/dhkemPrimitives/x25519.d.ts +3 -21
  210. package/node_modules/@hpke/core/esm/src/kems/dhkemPrimitives/x25519.d.ts.map +1 -1
  211. package/node_modules/@hpke/core/esm/src/kems/dhkemPrimitives/x25519.js +3 -201
  212. package/node_modules/@hpke/core/esm/src/kems/dhkemPrimitives/x448.d.ts +3 -21
  213. package/node_modules/@hpke/core/esm/src/kems/dhkemPrimitives/x448.d.ts.map +1 -1
  214. package/node_modules/@hpke/core/esm/src/kems/dhkemPrimitives/x448.js +3 -201
  215. package/node_modules/@hpke/core/esm/src/kems/dhkemPrimitives/xCurveNative.d.ts +26 -0
  216. package/node_modules/@hpke/core/esm/src/kems/dhkemPrimitives/xCurveNative.d.ts.map +1 -0
  217. package/node_modules/@hpke/core/esm/src/kems/dhkemPrimitives/xCurveNative.js +216 -0
  218. package/node_modules/@hpke/core/package.json +6 -2
  219. package/node_modules/@hpke/core/script/src/kems/dhkemPrimitives/x25519.d.ts +3 -21
  220. package/node_modules/@hpke/core/script/src/kems/dhkemPrimitives/x25519.d.ts.map +1 -1
  221. package/node_modules/@hpke/core/script/src/kems/dhkemPrimitives/x25519.js +4 -202
  222. package/node_modules/@hpke/core/script/src/kems/dhkemPrimitives/x448.d.ts +3 -21
  223. package/node_modules/@hpke/core/script/src/kems/dhkemPrimitives/x448.d.ts.map +1 -1
  224. package/node_modules/@hpke/core/script/src/kems/dhkemPrimitives/x448.js +4 -202
  225. package/node_modules/@hpke/core/script/src/kems/dhkemPrimitives/xCurveNative.d.ts +26 -0
  226. package/node_modules/@hpke/core/script/src/kems/dhkemPrimitives/xCurveNative.d.ts.map +1 -0
  227. package/node_modules/@hpke/core/script/src/kems/dhkemPrimitives/xCurveNative.js +230 -0
  228. package/node_modules/@types/node/README.md +1 -1
  229. package/node_modules/@types/node/package.json +2 -2
  230. package/node_modules/@types/node/zlib.d.ts +752 -0
  231. package/node_modules/encodeurl/README.md +14 -0
  232. package/node_modules/encodeurl/index.js +5 -10
  233. package/node_modules/encodeurl/package.json +10 -6
  234. package/node_modules/express-rate-limit/dist/index.cjs +7 -3
  235. package/node_modules/express-rate-limit/dist/index.mjs +7 -3
  236. package/node_modules/express-rate-limit/package.json +10 -10
  237. package/node_modules/hono/dist/cjs/adapter/bun/serve-static.js +1 -1
  238. package/node_modules/hono/dist/cjs/adapter/bun/websocket.js +1 -1
  239. package/node_modules/hono/dist/cjs/context.js +1 -1
  240. package/node_modules/hono/dist/cjs/helper/css/common.js +3 -5
  241. package/node_modules/hono/dist/cjs/hono-base.js +4 -10
  242. package/node_modules/hono/dist/cjs/hono.js +0 -1
  243. package/node_modules/hono/dist/cjs/middleware/basic-auth/index.js +1 -1
  244. package/node_modules/hono/dist/cjs/middleware/bearer-auth/index.js +1 -1
  245. package/node_modules/hono/dist/cjs/middleware/csrf/index.js +2 -2
  246. package/node_modules/hono/dist/cjs/middleware/jwk/jwk.js +2 -2
  247. package/node_modules/hono/dist/cjs/middleware/jwt/jwt.js +2 -2
  248. package/node_modules/hono/dist/cjs/middleware/mount/index.js +4 -4
  249. package/node_modules/hono/dist/cjs/router/reg-exp-router/node.js +13 -11
  250. package/node_modules/hono/dist/cjs/router/reg-exp-router/prepared-router.js +4 -4
  251. package/node_modules/hono/dist/cjs/router/reg-exp-router/router.js +39 -51
  252. package/node_modules/hono/dist/cjs/router/reg-exp-router/trie.js +15 -5
  253. package/node_modules/hono/dist/cjs/utils/jwt/jwt.js +2 -1
  254. package/node_modules/hono/dist/cjs/utils/mount.js +35 -0
  255. package/node_modules/hono/dist/cjs/utils/url.js +10 -0
  256. package/node_modules/hono/dist/cjs/validator/validator.js +1 -1
  257. package/node_modules/hono/dist/context.js +1 -1
  258. package/node_modules/hono/dist/helper/css/common.js +3 -5
  259. package/node_modules/hono/dist/hono-base.js +4 -10
  260. package/node_modules/hono/dist/hono.js +0 -1
  261. package/node_modules/hono/dist/middleware/basic-auth/index.js +1 -1
  262. package/node_modules/hono/dist/middleware/bearer-auth/index.js +1 -1
  263. package/node_modules/hono/dist/middleware/csrf/index.js +2 -2
  264. package/node_modules/hono/dist/middleware/jwk/jwk.js +2 -2
  265. package/node_modules/hono/dist/middleware/jwt/jwt.js +2 -2
  266. package/node_modules/hono/dist/middleware/language/language.js +1 -1
  267. package/node_modules/hono/dist/middleware/mount/index.js +4 -4
  268. package/node_modules/hono/dist/router/reg-exp-router/node.js +13 -11
  269. package/node_modules/hono/dist/router/reg-exp-router/prepared-router.js +5 -5
  270. package/node_modules/hono/dist/router/reg-exp-router/router.js +40 -52
  271. package/node_modules/hono/dist/router/reg-exp-router/trie.js +15 -5
  272. package/node_modules/hono/dist/types/middleware/mount/index.d.ts +1 -0
  273. package/node_modules/hono/dist/types/router/reg-exp-router/node.d.ts +3 -3
  274. package/node_modules/hono/dist/types/router/reg-exp-router/trie.d.ts +1 -1
  275. package/node_modules/hono/dist/types/utils/mount.d.ts +4 -0
  276. package/node_modules/hono/dist/types/utils/url.d.ts +1 -0
  277. package/node_modules/hono/dist/utils/jwt/jwt.js +2 -1
  278. package/node_modules/hono/dist/utils/mount.js +34 -0
  279. package/node_modules/hono/dist/utils/url.js +10 -1
  280. package/node_modules/hono/dist/validator/validator.js +1 -1
  281. package/node_modules/hono/package.json +1 -1
  282. package/node_modules/ip-address/README.md +39 -39
  283. package/node_modules/ip-address/dist/ipv6.js +1 -1
  284. package/node_modules/ip-address/dist/ipv6.js.map +1 -1
  285. package/node_modules/ip-address/package.json +1 -1
  286. package/node_modules/jose/dist/types/jwt/decrypt.d.ts +3 -0
  287. package/node_modules/jose/dist/types/jwt/unsecured.d.ts +2 -0
  288. package/node_modules/jose/dist/types/jwt/verify.d.ts +3 -0
  289. package/node_modules/jose/dist/types/types.d.ts +8 -0
  290. package/node_modules/jose/dist/types/util/decode_jwt.d.ts +1 -0
  291. package/node_modules/jose/dist/webapi/jwks/remote.js +3 -1
  292. package/node_modules/jose/dist/webapi/lib/deflate.js +2 -1
  293. package/node_modules/jose/dist/webapi/lib/jwt_claims_set.js +2 -1
  294. package/node_modules/jose/package.json +1 -1
  295. package/node_modules/qs/CHANGELOG.md +29 -22
  296. package/node_modules/qs/dist/qs.js +14 -14
  297. package/node_modules/qs/eslint.config.mjs +6 -0
  298. package/node_modules/qs/lib/stringify.js +1 -1
  299. package/node_modules/qs/package.json +5 -5
  300. package/node_modules/qs/test/stringify.js +74 -0
  301. package/package.json +2 -2
@@ -744,12 +744,19 @@ async function postInternal(path, body) {
744
744
  clearTimeout(timer);
745
745
  }
746
746
  }
747
- async function cpEncryptContent(toolArgs, recipientUserIds) {
748
- const data = await postInternal("/internal/encrypt-content", { toolArgs, recipientUserIds });
747
+ async function cpEncryptContent(toolArgs, recipientUserIds, readers) {
748
+ const data = await postInternal("/internal/encrypt-content", { toolArgs, recipientUserIds, ...readers ? { readers } : {} });
749
749
  return data;
750
750
  }
751
751
  async function cpDecryptContent(wire) {
752
- const data = await postInternal("/internal/decrypt-content", { ciphertext: wire.ciphertext, keys: wire.keys });
752
+ const data = await postInternal("/internal/decrypt-content", {
753
+ ciphertext: wire.ciphertext,
754
+ // Both names: under a 0.8 mandate `encrypted_keys` is keyed by DID and
755
+ // `keys` by account id; the control plane finds this user's wrap by either.
756
+ keys: { ...wire.keys ?? {}, ...wire.encrypted_keys ?? {} },
757
+ // v0.8 rule 8: the control plane checks the decrypted content against the fingerprint.
758
+ ...wire.proposalContentHash ? { proposalContentHash: wire.proposalContentHash } : wire.hash ? { hash: wire.hash } : {}
759
+ });
753
760
  return data.plaintext;
754
761
  }
755
762
 
@@ -983,7 +990,10 @@ var SPClient = class {
983
990
  const { proposalContentHash, ...rest } = data;
984
991
  const body = JSON.stringify({
985
992
  ...rest,
986
- ...proposalContentHash ? { proposal_content_hash: proposalContentHash } : {}
993
+ // v0.8 wire name is `proposalContentHash`; today's AS reads the
994
+ // Suveren-internal `proposal_content_hash`. Both are sent through the
995
+ // transition (same value); the AS of Track B reads the normative one.
996
+ ...proposalContentHash ? { proposal_content_hash: proposalContentHash, proposalContentHash } : {}
987
997
  });
988
998
  const maxAttempts = data.idempotencyKey || data.proposalId ? this.receiptRetry.maxAttempts : 1;
989
999
  let lastError;
@@ -1037,7 +1047,7 @@ var SPClient = class {
1037
1047
  * read it; the caller reports who cannot.
1038
1048
  */
1039
1049
  async submitProposal(data) {
1040
- const { content, unreadableFor } = await cpEncryptContent(data.toolArgs, data.recipientUserIds);
1050
+ const { content, unreadableFor } = await cpEncryptContent(data.toolArgs, data.recipientUserIds, data.readers);
1041
1051
  const res = await this.fetch("/api/proposals", {
1042
1052
  method: "POST",
1043
1053
  body: JSON.stringify({
@@ -1046,8 +1056,18 @@ var SPClient = class {
1046
1056
  path: data.path,
1047
1057
  pending_domains: data.pendingDomains,
1048
1058
  tool: data.tool,
1059
+ // v0.8 normative object, beside the Suveren-internal fields today's AS
1060
+ // reads: `content` carries `encrypted_keys`/`readers`/`unreadable` with
1061
+ // the legacy `keys`/`hash`; the fingerprint travels as
1062
+ // `proposalContentHash`; the operation as `action` + `actionType`.
1049
1063
  content,
1064
+ proposalContentHash: content.hash,
1065
+ action: data.tool,
1066
+ ...data.actionType ? { actionType: data.actionType } : {},
1067
+ ...data.mandateId ? { mandateId: data.mandateId } : {},
1068
+ ...data.boundsHash ? { boundsHash: data.boundsHash } : {},
1050
1069
  execution_context: data.executionContext,
1070
+ executionContext: data.executionContext,
1051
1071
  // Phase 6
1052
1072
  ...data.pendingApprovers && data.pendingApprovers.length > 0 ? { pending_approvers: data.pendingApprovers } : {},
1053
1073
  ...data.createdBy ? { created_by: data.createdBy } : {}
@@ -1331,6 +1351,7 @@ var AttestationCache = class {
1331
1351
  }
1332
1352
  let signedCommitmentMode;
1333
1353
  let subjects;
1354
+ let mandateId;
1334
1355
  const firstBlob = result.attestations[0]?.blob;
1335
1356
  if (firstBlob) {
1336
1357
  try {
@@ -1341,6 +1362,39 @@ var AttestationCache = class {
1341
1362
  signedCommitmentMode = void 0;
1342
1363
  }
1343
1364
  }
1365
+ const mandateIds = [];
1366
+ let mandateVersion;
1367
+ const nowSec4 = Math.floor(Date.now() / 1e3);
1368
+ for (const a of result.attestations) {
1369
+ if (!a.blob) continue;
1370
+ try {
1371
+ const id = decodeMandateBlob(a.blob).payload.mandate_id;
1372
+ if (typeof id !== "string") continue;
1373
+ if (!mandateIds.includes(id)) mandateIds.push(id);
1374
+ if (mandateId === void 0 && a.expires_at > nowSec4) {
1375
+ mandateId = id;
1376
+ const v = decodeMandateBlob(a.blob).payload.version;
1377
+ if (typeof v === "string") mandateVersion = v;
1378
+ }
1379
+ } catch {
1380
+ }
1381
+ }
1382
+ mandateId ??= mandateIds[0];
1383
+ let proposalReaders;
1384
+ let latestIssuedAt = -Infinity;
1385
+ for (const a of result.attestations) {
1386
+ if (!a.blob) continue;
1387
+ try {
1388
+ const p = decodeMandateBlob(a.blob).payload;
1389
+ const ownerDid = p.mandate_owners?.[0]?.did;
1390
+ if (typeof p.version !== "string" || typeof ownerDid !== "string") continue;
1391
+ const issuedAt = typeof p.issued_at === "number" ? p.issued_at : 0;
1392
+ if (issuedAt < latestIssuedAt) continue;
1393
+ latestIssuedAt = issuedAt;
1394
+ proposalReaders = { version: p.version, ownerDid, deciders: [...p.above_cap_approvers ?? []] };
1395
+ } catch {
1396
+ }
1397
+ }
1344
1398
  const auth = {
1345
1399
  authorizationId: result.authorization_id,
1346
1400
  boundsHash: result.bounds_hash,
@@ -1362,6 +1416,10 @@ var AttestationCache = class {
1362
1416
  attestedDomains: result.attested_domains ?? [],
1363
1417
  deferredCommitmentDomains: result.deferred_commitment_domains ?? [],
1364
1418
  signedCommitmentMode,
1419
+ mandateId,
1420
+ mandateIds,
1421
+ mandateVersion,
1422
+ proposalReaders,
1365
1423
  subjects,
1366
1424
  complete: result.complete,
1367
1425
  groupId
@@ -2169,17 +2227,69 @@ var ExecutionJournal = class {
2169
2227
  }
2170
2228
  /** Look a ticket up. Always reads from disk — another process may have written. */
2171
2229
  get(ticketId) {
2172
- return this.load().entries.find((e) => e.ticketId === ticketId);
2230
+ return this.load().entries.find((e) => e.ticketId === ticketId && ticketId !== "");
2231
+ }
2232
+ /** The row for a request (idempotencyKey / proposalId), whatever its state. */
2233
+ getByRequest(requestKey) {
2234
+ return this.load().entries.find((e) => e.requestKey === requestKey);
2235
+ }
2236
+ /**
2237
+ * v0.8 — record that a ticket is about to be REQUESTED for this request,
2238
+ * before the request leaves the machine (*One execution per ticket*, rule 1).
2239
+ * A lost response then leaves a `requested` row: "the ticket never arrived,
2240
+ * so the action cannot have started" — the one case a replayed ticket may
2241
+ * run (rule 2). Idempotent for the same request key: a retry of the request
2242
+ * itself keeps the one row.
2243
+ */
2244
+ requested(entry) {
2245
+ const file = this.load();
2246
+ if (file.entries.some((e) => e.requestKey === entry.requestKey)) return;
2247
+ file.entries.push({
2248
+ ticketId: "",
2249
+ ...entry,
2250
+ state: "requested",
2251
+ startedAt: nowSec(),
2252
+ pid: process.pid
2253
+ });
2254
+ this.persist(file);
2173
2255
  }
2174
2256
  /**
2175
- * Record intent to execute under `ticketId`. Refuses if any row for that
2176
- * ticket already exists, whatever its state — deciding what an existing row
2177
- * means is the caller's job, and it differs by state (see commitments.ts).
2257
+ * Close a `requested` row whose ticket was never issued (the AS refused).
2258
+ * Nothing ran; the row records that the request was judged and refused.
2259
+ */
2260
+ refusedBeforeTicket(requestKey, outcome, detail) {
2261
+ const file = this.load();
2262
+ const row = file.entries.find((e) => e.requestKey === requestKey && e.state === "requested");
2263
+ if (!row) return;
2264
+ row.state = "failed";
2265
+ row.outcome = outcome;
2266
+ if (detail !== void 0) row.detail = detail.length > DETAIL_CAP ? detail.slice(0, DETAIL_CAP) : detail;
2267
+ row.finishedAt = nowSec();
2268
+ this.persist(file);
2269
+ }
2270
+ /**
2271
+ * Claim the ticket for execution — the atomic move to `intent` ("started")
2272
+ * BEFORE the downstream call (*One execution per ticket*, rule 2). Refuses
2273
+ * if a row for that ticket already exists, whatever its state — deciding
2274
+ * what an existing row means is the caller's job, and it differs by state
2275
+ * (see commitments.ts). With a `requestKey`, a row for the SAME request that
2276
+ * is already `intent`/`done`/`failed` refuses too — a second ticket with a
2277
+ * new id for the same request is not executed again; a `requested` row is
2278
+ * upgraded in place.
2178
2279
  */
2179
2280
  begin(entry) {
2180
2281
  const file = this.load();
2181
- const existing = file.entries.find((e) => e.ticketId === entry.ticketId);
2282
+ const existing = file.entries.find((e) => e.ticketId === entry.ticketId && e.ticketId !== "");
2182
2283
  if (existing) return { ok: false, existing };
2284
+ if (entry.requestKey) {
2285
+ const sameRequest = file.entries.find((e) => e.requestKey === entry.requestKey);
2286
+ if (sameRequest && sameRequest.state !== "requested") return { ok: false, existing: sameRequest };
2287
+ if (sameRequest) {
2288
+ Object.assign(sameRequest, entry, { state: "intent", startedAt: nowSec(), pid: process.pid });
2289
+ this.persist(file);
2290
+ return { ok: true };
2291
+ }
2292
+ }
2183
2293
  file.entries.push({
2184
2294
  ...entry,
2185
2295
  state: "intent",
@@ -2431,7 +2541,8 @@ var ProposalSubmissionStore = class {
2431
2541
  authorizationId: entry.authorizationId,
2432
2542
  profileId: entry.profileId,
2433
2543
  submittedAt: nowSec3(),
2434
- ...entry.previewHash ? { previewHash: entry.previewHash } : {}
2544
+ ...entry.previewHash ? { previewHash: entry.previewHash } : {},
2545
+ ...entry.actionType ? { actionType: entry.actionType } : {}
2435
2546
  });
2436
2547
  this.persist(file);
2437
2548
  }
@@ -3230,7 +3341,7 @@ var ReportStore = class {
3230
3341
  };
3231
3342
 
3232
3343
  // src/lib/shared-state.ts
3233
- import { PROTOCOL_VERSION } from "@hap/core";
3344
+ import { SUPPORTED_VERSIONS } from "@hap/core";
3234
3345
  var SharedState = class {
3235
3346
  spClient;
3236
3347
  cache;
@@ -3259,7 +3370,7 @@ var SharedState = class {
3259
3370
  * again whenever the AS URL this process pairs with changes — which, in
3260
3371
  * practice, only happens across a restart; see bin/http.ts's
3261
3372
  * `repairIfAsUrlChanged`). Non-null means the AS this gateway is paired
3262
- * with does not list {@link PROTOCOL_VERSION} among its
3373
+ * with shares no version with SUPPORTED_VERSIONS among its
3263
3374
  * `supportedVersions` — every gated tool call MUST refuse with this
3264
3375
  * message rather than reach the AS at all (checked in tool-proxy.ts,
3265
3376
  * before anything else). `null` until the first check completes, which
@@ -3269,6 +3380,16 @@ var SharedState = class {
3269
3380
  * unreachable at boot must not permanently brick the gateway).
3270
3381
  */
3271
3382
  asVersionRefusal = null;
3383
+ /** v0.8: whether the paired Authority Server lists 0.8 among its supportedVersions —
3384
+ * read once at start-up ({@link checkAsCompat}); false until known. Where the wire
3385
+ * shape differs between a 0.7 and a 0.8 AS (today: nothing), this is the switch. */
3386
+ asSpeaks08 = false;
3387
+ /** v0.8: the paired AS's supportedVersions as read at start-up; null until
3388
+ * known. A mandate whose signed version is not in it can no longer be
3389
+ * exercised (protocol.md → Version negotiation, rule 3: a v0.8 AS issues no
3390
+ * ticket against a v0.7 mandate) and is shown as needing to be signed again
3391
+ * before any call is refused for it. */
3392
+ asSupportedVersions = null;
3272
3393
  /**
3273
3394
  * @param dataDir Passed to the AttestationCache so it can enforce AS key
3274
3395
  * pinning (as-pairing.ts), and to the SPClient so it can enforce opt-in
@@ -3309,8 +3430,11 @@ var SharedState = class {
3309
3430
  return;
3310
3431
  }
3311
3432
  const supported = Array.isArray(compat.supportedVersions) ? compat.supportedVersions : [];
3312
- if (!supported.includes(PROTOCOL_VERSION)) {
3313
- this.asVersionRefusal = supported.length > 0 ? `This Authority Server supports protocol version(s) [${supported.join(", ")}], not ${PROTOCOL_VERSION}. Update the gateway or the Authority Server so the two agree, then restart. No gated action can run until then.` : `This Authority Server's /api/as/compat does not name a supportedVersions list (it answered ${JSON.stringify(compat.protocolVersion ?? "unknown")}), so it cannot be confirmed to support protocol ${PROTOCOL_VERSION}. Update the gateway or the Authority Server, then restart. No gated action can run until then.`;
3433
+ const common = SUPPORTED_VERSIONS.filter((v) => supported.includes(v));
3434
+ this.asSpeaks08 = supported.includes("0.8");
3435
+ this.asSupportedVersions = supported.filter((v) => typeof v === "string");
3436
+ if (common.length === 0) {
3437
+ this.asVersionRefusal = supported.length > 0 ? `This Authority Server supports protocol version(s) [${supported.join(", ")}], none of [${SUPPORTED_VERSIONS.join(", ")}] this gateway speaks. Update the gateway or the Authority Server so the two agree, then restart. No gated action can run until then.` : `This Authority Server's /api/as/compat does not name a supportedVersions list (it answered ${JSON.stringify(compat.protocolVersion ?? "unknown")}), so it cannot be confirmed to support any of protocol [${SUPPORTED_VERSIONS.join(", ")}]. Update the gateway or the Authority Server, then restart. No gated action can run until then.`;
3314
3438
  console.error(`[Suveren MCP] ${this.asVersionRefusal}`);
3315
3439
  } else {
3316
3440
  this.asVersionRefusal = null;
@@ -3400,7 +3524,7 @@ var SharedState = class {
3400
3524
  gateContent: gateEntry?.gateContent ?? null,
3401
3525
  context: auth.context ?? gateEntry?.context,
3402
3526
  contextHash: auth.contextHash ?? gateEntry?.contextHash,
3403
- needsReapproval: this.cache.needsReapproval(auth.authorizationId)
3527
+ needsReapproval: this.cache.needsReapproval(auth.authorizationId) || this.asSupportedVersions !== null && this.asSupportedVersions.length > 0 && typeof auth.mandateVersion === "string" && !this.asSupportedVersions.includes(auth.mandateVersion)
3404
3528
  };
3405
3529
  }).filter((auth) => auth.gateContent !== null);
3406
3530
  }
@@ -6418,7 +6542,13 @@ function attachTicketId(tool, args, ticketId) {
6418
6542
  }
6419
6543
 
6420
6544
  // src/lib/ticket-verify.ts
6421
- import { verifyTicketSignature } from "@hap/core";
6545
+ import {
6546
+ verifyTicketSignature,
6547
+ verifyTicketAgainstRequest,
6548
+ verifyTicketApprovals,
6549
+ decodeMandateBlob as decodeMandateBlob2,
6550
+ HapError
6551
+ } from "@hap/core";
6422
6552
  var TicketBindingMismatchError = class extends Error {
6423
6553
  constructor(message) {
6424
6554
  super(message);
@@ -6427,6 +6557,17 @@ var TicketBindingMismatchError = class extends Error {
6427
6557
  };
6428
6558
  var TICKET_MAX_AGE_SECONDS = 5 * 60;
6429
6559
  var TICKET_MAX_CLOCK_SKEW_SECONDS = 30;
6560
+ function mandateForTicket(attestations, ticketMandateId) {
6561
+ if (typeof ticketMandateId !== "string") return void 0;
6562
+ for (const a of attestations ?? []) {
6563
+ try {
6564
+ const m = decodeMandateBlob2(a.blob);
6565
+ if (m.payload.mandate_id === ticketMandateId) return m;
6566
+ } catch {
6567
+ }
6568
+ }
6569
+ return void 0;
6570
+ }
6430
6571
  async function verifyTicket(cache, receipt, expected) {
6431
6572
  const trustedIssuer = await cache.getTrustedIssuer();
6432
6573
  if (typeof receipt.signature !== "string" || !receipt.signature) {
@@ -6485,20 +6626,70 @@ async function verifyTicket(cache, receipt, expected) {
6485
6626
  if (typeof timestamp !== "number" || !Number.isFinite(timestamp)) {
6486
6627
  throw new TicketBindingMismatchError("Ticket carries no valid timestamp \u2014 refusing to execute.");
6487
6628
  }
6488
- const nowSec4 = Math.floor(Date.now() / 1e3);
6489
- const ageSec = nowSec4 - timestamp;
6490
- if (ageSec > TICKET_MAX_AGE_SECONDS) {
6491
- throw new TicketBindingMismatchError(
6492
- `Ticket is ${ageSec}s old, older than the ${TICKET_MAX_AGE_SECONDS}s freshness window \u2014 refusing to execute.`
6493
- );
6629
+ if (expected.replay !== true) {
6630
+ const nowSec4 = Math.floor(Date.now() / 1e3);
6631
+ const ageSec = nowSec4 - timestamp;
6632
+ if (ageSec > TICKET_MAX_AGE_SECONDS) {
6633
+ throw new TicketBindingMismatchError(
6634
+ `Ticket is ${ageSec}s old, older than the ${TICKET_MAX_AGE_SECONDS}s freshness window \u2014 refusing to execute.`
6635
+ );
6636
+ }
6637
+ if (ageSec < -TICKET_MAX_CLOCK_SKEW_SECONDS) {
6638
+ throw new TicketBindingMismatchError(
6639
+ `Ticket is timestamped ${-ageSec}s in the future, beyond the ${TICKET_MAX_CLOCK_SKEW_SECONDS}s clock-skew tolerance \u2014 refusing to execute.`
6640
+ );
6641
+ }
6494
6642
  }
6495
- if (ageSec < -TICKET_MAX_CLOCK_SKEW_SECONDS) {
6496
- throw new TicketBindingMismatchError(
6497
- `Ticket is timestamped ${-ageSec}s in the future, beyond the ${TICKET_MAX_CLOCK_SKEW_SECONDS}s clock-skew tolerance \u2014 refusing to execute.`
6643
+ const ticket = receipt;
6644
+ let acceptedMandateId = expected.mandateId;
6645
+ if (expected.mandateIds && expected.mandateIds.length > 0) {
6646
+ if (typeof ticket.mandateId !== "string" || !expected.mandateIds.includes(ticket.mandateId)) {
6647
+ throw new TicketBindingMismatchError(
6648
+ `TICKET_REQUEST_MISMATCH: ticket mandateId ${String(ticket.mandateId)} is not a mandate of this grant \u2014 refusing to execute.`
6649
+ );
6650
+ }
6651
+ acceptedMandateId = ticket.mandateId;
6652
+ }
6653
+ try {
6654
+ verifyTicketAgainstRequest(
6655
+ ticket,
6656
+ {
6657
+ profileId: expected.profileId ?? ticket.profileId,
6658
+ actionType: expected.actionType ?? ticket.actionType,
6659
+ boundsHash: expected.boundsHash ?? ticket.boundsHash,
6660
+ executionContext: expected.executionContext ?? ticket.executionContext ?? {},
6661
+ mandateId: acceptedMandateId,
6662
+ idempotencyKey: expected.idempotencyKey,
6663
+ contentHash: expected.contentHash ?? ticket.contentHash,
6664
+ contentBinding: expected.contentBinding !== void 0 ? expected.contentBinding : ticket.contentBinding,
6665
+ proposalId: expected.proposalId ?? ticket.proposalId,
6666
+ // A v0.7 ticket has no `proposalContentHash` (today's Authority Server
6667
+ // binds the fingerprint on the request only); a v0.8 ticket MUST carry
6668
+ // the one this call sent.
6669
+ proposalContentHash: ticket.version === "0.7" ? ticket.proposalContentHash : expected.proposalContentHash ?? ticket.proposalContentHash
6670
+ },
6671
+ { mandate: expected.mandate, replay: expected.replay === true }
6498
6672
  );
6673
+ } catch (err) {
6674
+ if (err instanceof HapError) {
6675
+ throw new TicketBindingMismatchError(`${err.message} \u2014 refusing to execute.`);
6676
+ }
6677
+ throw err;
6678
+ }
6679
+ if (expected.mandate && (ticket.approvalSignature || (ticket.approvalSignatures?.length ?? 0) > 0)) {
6680
+ try {
6681
+ await verifyTicketApprovals(ticket, expected.mandate);
6682
+ } catch (err) {
6683
+ throw new TicketBindingMismatchError(
6684
+ `${err instanceof Error ? err.message : String(err)} \u2014 the approval does not cover this operation; refusing to execute.`
6685
+ );
6686
+ }
6499
6687
  }
6500
6688
  }
6501
6689
 
6690
+ // src/lib/tool-proxy.ts
6691
+ import { wireExecutionContext as hapWireExecutionContext, checkExecutionValues, missingSumFields } from "@hap/core";
6692
+
6502
6693
  // src/lib/who-label.ts
6503
6694
  var UNKNOWN_DECIDER = "the person";
6504
6695
  async function resolveWhoLabel(archive, domainKey, userId) {
@@ -6720,21 +6911,8 @@ function profileMatches(profileId, shortName2) {
6720
6911
  }
6721
6912
  function wireExecutionContext(profileId, execution) {
6722
6913
  const profile = getProfile5(profileId);
6723
- const allowed = /* @__PURE__ */ new Set(["action_type"]);
6724
- const fields = profile?.boundsSchema?.fields;
6725
- if (fields) {
6726
- for (const fieldDef of Object.values(fields)) {
6727
- const bt = fieldDef.boundType;
6728
- if (bt && (bt.kind === "per_transaction" || bt.kind === "cumulative_sum") && bt.of) {
6729
- allowed.add(bt.of);
6730
- }
6731
- }
6732
- }
6733
- const out = {};
6734
- for (const [key, value] of Object.entries(execution)) {
6735
- if (allowed.has(key)) out[key] = value;
6736
- }
6737
- return out;
6914
+ if (!profile) return {};
6915
+ return hapWireExecutionContext(execution, profile);
6738
6916
  }
6739
6917
  function countBoundsFor(profileId, actionType) {
6740
6918
  const fields = getProfile5(profileId)?.boundsSchema?.fields;
@@ -6898,7 +7076,7 @@ function isStaleMandateRefusal(err) {
6898
7076
  }
6899
7077
  function isVersionUnsupportedRefusal(err) {
6900
7078
  const errors = err.body?.errors;
6901
- return err.statusCode === 409 && errors?.[0]?.code === "VERSION_UNSUPPORTED";
7079
+ return errors?.[0]?.code === "VERSION_UNSUPPORTED";
6902
7080
  }
6903
7081
  function createGatedToolHandlerInner(tool, integrationManager2, state2) {
6904
7082
  if (!tool.gating || !tool.gating.profile) {
@@ -7004,7 +7182,8 @@ function createGatedToolHandlerInner(tool, integrationManager2, state2) {
7004
7182
  ageBoundField
7005
7183
  ) : null;
7006
7184
  const isTeam = typeof state2.cache?.isTeamGroup === "function" ? state2.cache.isTeamGroup(matchingAuths[0]?.groupId) : void 0;
7007
- readMaxAge = isTeam === true && signedAge !== null ? localAge !== null ? Math.min(localAge, signedAge) : signedAge : localAge ?? signedAge;
7185
+ const ceilingMarked = ageBoundField !== null && boundsSchema?.fields?.[ageBoundField]?.enforcedBy === "gatekeeper" && matchingAuths.some((a) => a.mandateVersion === "0.8");
7186
+ readMaxAge = (ceilingMarked || isTeam === true) && signedAge !== null ? localAge !== null ? Math.min(localAge, signedAge) : signedAge : localAge ?? signedAge;
7008
7187
  if (readMaxAge === null) {
7009
7188
  return denyRead(
7010
7189
  state2,
@@ -7209,6 +7388,32 @@ function createGatedToolHandlerInner(tool, integrationManager2, state2) {
7209
7388
  return { content: [{ type: "text", text: noMandateRefusal(tool.namespacedName, mandateLabel) }], isError: true };
7210
7389
  }
7211
7390
  if (matchingAuths.length === 0) return noEligibleMandate(refusals);
7391
+ {
7392
+ const profileDefs = [...new Set(matchingAuths.map((a) => a.profileId))].map((id) => getProfile5(id)).filter((d) => d !== void 0);
7393
+ for (const profileDef of profileDefs) {
7394
+ try {
7395
+ checkExecutionValues(hapWireExecutionContext(execution, profileDef), profileDef);
7396
+ } catch (err) {
7397
+ const detail = err instanceof Error ? err.message : String(err);
7398
+ const field = /executionContext\.([A-Za-z0-9_]+)/.exec(detail)?.[1];
7399
+ const bounds = field ? Object.entries(profileDef.boundsSchema?.fields ?? {}).filter(([, def]) => def.boundType?.of === field).map(([name]) => name) : [];
7400
+ recordBlocked(state2, tool, {
7401
+ kind: "bound",
7402
+ detail,
7403
+ ...field ? { field } : {},
7404
+ who: "gateway",
7405
+ code: "MALFORMED_TICKET_REQUEST"
7406
+ });
7407
+ return {
7408
+ content: [{
7409
+ type: "text",
7410
+ text: `Blocked by Gatekeeper: ${field ? `"${field}" is not a number of zero or more` : "a value a bound reads is not a number of zero or more"}${bounds.length > 0 ? ` (read by ${bounds.join(", ")})` : ""} \u2014 ${detail}. Correct the request and try again.`
7411
+ }],
7412
+ isError: true
7413
+ };
7414
+ }
7415
+ }
7416
+ }
7212
7417
  const blockingFails = await failedBlockingChecks(integrationManager2, tool.integrationId, tool.originalName, args);
7213
7418
  if (blockingFails.length > 0) {
7214
7419
  recordBlocked(state2, tool, {
@@ -7366,7 +7571,12 @@ function createGatedToolHandlerInner(tool, integrationManager2, state2) {
7366
7571
  tool: tool.namespacedName,
7367
7572
  toolArgs: enrichedArgs,
7368
7573
  executionContext: wireExecCtx,
7369
- recipientUserIds
7574
+ recipientUserIds,
7575
+ // v0.8 — the normative proposal object (protocol.md → Proposals).
7576
+ mandateId: auth.mandateId,
7577
+ boundsHash: auth.boundsHash,
7578
+ actionType: declaredActionType,
7579
+ ...v08ProposalReaders(auth)
7370
7580
  });
7371
7581
  const previewHash = await computeSubmissionPreviewHash(
7372
7582
  integrationManager2,
@@ -7381,7 +7591,8 @@ function createGatedToolHandlerInner(tool, integrationManager2, state2) {
7381
7591
  executionContext: wireExecCtx,
7382
7592
  authorizationId: authzId,
7383
7593
  profileId: auth.profileId,
7384
- previewHash
7594
+ previewHash,
7595
+ actionType: declaredActionType
7385
7596
  });
7386
7597
  return {
7387
7598
  content: [{
@@ -7415,16 +7626,44 @@ Tell the person what you proposed and that it waits for their approval in the ga
7415
7626
  finalArgs = finalized.args;
7416
7627
  rebuildTransport = finalized.rebuildTransport;
7417
7628
  }
7629
+ if (auth.signedCommitmentMode === "automatic" && auth.mandateVersion === "0.8") {
7630
+ const profileDef = getProfile5(auth.profileId);
7631
+ const missing = profileDef ? missingSumFields(wireExecutionContext(auth.profileId, execution), profileDef, declaredActionType) : [];
7632
+ if (missing.length > 0) {
7633
+ const detail = `"${missing[0].field}" is required by the bound ${missing[0].bound} for "${declaredActionType}" calls, but this call carries none.`;
7634
+ recordBlocked(state2, tool, {
7635
+ kind: "bound",
7636
+ detail,
7637
+ field: missing[0].field,
7638
+ who: "gateway",
7639
+ code: "BOUND_EXCEEDED"
7640
+ });
7641
+ return {
7642
+ content: [{
7643
+ type: "text",
7644
+ text: `Blocked by Gatekeeper: ${detail} Without it the spend cannot be counted against the mandate, so nothing ran.`
7645
+ }],
7646
+ isError: true
7647
+ };
7648
+ }
7649
+ }
7418
7650
  let receiptId;
7651
+ let autoRequestKey;
7419
7652
  try {
7420
7653
  const actionType = declaredActionType;
7421
7654
  const binding = computeContentBinding(auth.profileId, tool, finalArgs, actionType);
7422
7655
  const idempotencyKey = randomUUID();
7423
7656
  const wireExecCtx = wireExecutionContext(auth.profileId, execution);
7424
- const { receipt } = await state2.spClient.postReceipt({
7657
+ state2.executionJournal?.requested?.({ requestKey: idempotencyKey, tool: tool.namespacedName, argsHash: hashToolArgs(finalArgs) });
7658
+ autoRequestKey = idempotencyKey;
7659
+ const { receipt, idempotent } = await state2.spClient.postReceipt({
7425
7660
  authorizationId: authzId,
7426
7661
  // Optional cross-check — the AS fails closed on a mismatch.
7427
7662
  boundsHash: auth.boundsHash,
7663
+ // v0.8 — the mandate this call runs under, by its signed id, so a
7664
+ // revoked mandate and its replacement (same bounds_hash) cannot be
7665
+ // confused (Ticket Request Schema, rule 1).
7666
+ mandateId: auth.mandateId,
7428
7667
  profileId: auth.profileId,
7429
7668
  action: tool.namespacedName,
7430
7669
  actionType,
@@ -7444,9 +7683,15 @@ Tell the person what you proposed and that it waits for their approval in the ga
7444
7683
  executionContext: wireExecCtx,
7445
7684
  authorizationId: authzId,
7446
7685
  profileId: auth.profileId,
7686
+ actionType,
7687
+ boundsHash: auth.boundsHash,
7688
+ mandateId: auth.mandateId,
7689
+ mandateIds: auth.mandateIds,
7690
+ mandate: mandateForTicket(auth.attestations, receipt?.mandateId),
7447
7691
  idempotencyKey,
7448
7692
  contentHash: binding?.contentHash,
7449
- contentBinding: binding?.contentBinding
7693
+ contentBinding: binding?.contentBinding,
7694
+ replay: idempotent
7450
7695
  });
7451
7696
  await state2.archiveReceipt(receipt, {
7452
7697
  authorizationId: authzId,
@@ -7469,6 +7714,10 @@ Tell the person what you proposed and that it waits for their approval in the ga
7469
7714
  sentArgs: finalArgs
7470
7715
  });
7471
7716
  } catch (err) {
7717
+ if (autoRequestKey && !receiptId) {
7718
+ const refusalCode = err instanceof SPReceiptError ? err.body?.errors?.[0]?.code ?? "TICKET_REFUSED" : "REQUEST_FAILED";
7719
+ state2.executionJournal?.refusedBeforeTicket?.(autoRequestKey, "as_refused", refusalCode);
7720
+ }
7472
7721
  if (err instanceof AsKeyMismatchError || err instanceof TicketBindingMismatchError) {
7473
7722
  void notifyControlPlane("as-key-mismatch");
7474
7723
  return {
@@ -7499,7 +7748,7 @@ Tell the person what you proposed and that it waits for their approval in the ga
7499
7748
  return {
7500
7749
  content: [{
7501
7750
  type: "text",
7502
- text: `Blocked: mandate ${auth.authorizationId} needs re-approval \u2014 the Authority Server no longer verifies its protocol version. Ask the decision owner to re-approve it (see list-authorizations). ${err.message}`
7751
+ text: `Blocked: mandate ${auth.authorizationId} must be signed again \u2014 the Authority Server no longer accepts its protocol version. Ask the mandate owner to sign it again (Mandates page \u2192 Sign again; see list-authorizations). ${err.message}`
7503
7752
  }],
7504
7753
  isError: true
7505
7754
  };
@@ -7570,7 +7819,12 @@ Tell the person what you proposed and that it waits for their approval in the ga
7570
7819
  executionContext: wireExecCtx,
7571
7820
  pendingApprovers: uniqueApprovers,
7572
7821
  recipientUserIds,
7573
- ...ownerId ? { createdBy: ownerId } : {}
7822
+ ...ownerId ? { createdBy: ownerId } : {},
7823
+ // v0.8 — the normative proposal object (protocol.md → Proposals).
7824
+ mandateId: auth.mandateId,
7825
+ boundsHash: auth.boundsHash,
7826
+ actionType: declaredActionType,
7827
+ ...v08ProposalReaders(auth)
7574
7828
  });
7575
7829
  const previewHash = await computeSubmissionPreviewHash(
7576
7830
  integrationManager2,
@@ -7585,7 +7839,8 @@ Tell the person what you proposed and that it waits for their approval in the ga
7585
7839
  executionContext: wireExecCtx,
7586
7840
  authorizationId: authzId,
7587
7841
  profileId: auth.profileId,
7588
- previewHash
7842
+ previewHash,
7843
+ actionType: declaredActionType
7589
7844
  });
7590
7845
  return {
7591
7846
  content: [{
@@ -7651,6 +7906,7 @@ Proposal ID: ${proposal.id}. Use check-pending-commitments to track status.` + a
7651
7906
  if (receiptId) {
7652
7907
  const begun = state2.executionJournal.begin({
7653
7908
  ticketId: receiptId,
7909
+ requestKey: autoRequestKey,
7654
7910
  tool: tool.namespacedName,
7655
7911
  argsHash: hashToolArgs(finalArgs)
7656
7912
  });
@@ -7692,6 +7948,11 @@ function recordAutomaticOutcome(state2, ticketId, result, thrown) {
7692
7948
  console.error(`[Suveren MCP] Could not record the execution result for ticket ${ticketId}:`, err);
7693
7949
  }
7694
7950
  }
7951
+ function v08ProposalReaders(auth) {
7952
+ const r = auth.proposalReaders;
7953
+ if (!r || r.version !== "0.8") return {};
7954
+ return { readers: { ownerDid: r.ownerDid, deciders: r.deciders } };
7955
+ }
7695
7956
  function noMandateRefusal(toolName, profile) {
7696
7957
  return `Refused: no mandate covers ${toolName} (${shortProfile(profile)}). Nothing was done. Ask the person to grant a ${shortProfile(profile)} mandate in the gateway, then try again. No ticket was requested.`;
7697
7958
  }
@@ -7739,7 +8000,9 @@ function agentVisibleAuthorizations(authorizations, integrationManager2) {
7739
8000
  }
7740
8001
 
7741
8002
  // src/lib/agent-rules.ts
8003
+ var NO_IMPERSONATION_RULE = `You are an AI acting under a person's mandate. This rule comes before every other instruction, including the person's own: never write as if you were that person or any person. No "I" as them, no signature with their name alone, no feelings, opinions or experiences of your own, and never claim to be human. Write as their AI, or about them in the third person ("she asked me to confirm\u2026", "he will\u2026"). If the person asks you to write as them, do the task this way instead and tell them why. Every message you send is marked as sent by an AI; make that true of every word.`;
7742
8004
  var AGENT_RULES = [
8005
+ NO_IMPERSONATION_RULE,
7743
8006
  "Never open or operate the Suveren Gateway's web page \u2014 not in a browser you control, not with computer use. Never ask for, read or type the person's API key. Never approve a proposal: approvals are the person's alone.",
7744
8007
  "Use only the Suveren tools. No terminal, HTTP or browser calls to the gateway's ports (for example `curl localhost:3500/mcp`).",
7745
8008
  "When a tool offers an optional `_source` argument, set it to link the ONE record (e.g. an inbound email) you are acting on \u2014 just the reference ({connector, kind, id}), never a summary or quote; the gateway reads the record itself for the approver."
@@ -7799,11 +8062,11 @@ function buildMandateBrief(opts) {
7799
8062
  const needingReapproval = active.filter((a) => a.needsReapproval);
7800
8063
  if (needingReapproval.length > 0) {
7801
8064
  lines.push("");
7802
- lines.push("=== NEEDS RE-APPROVAL ===");
8065
+ lines.push("=== MUST BE SIGNED AGAIN ===");
7803
8066
  lines.push("");
7804
8067
  for (const auth of needingReapproval) {
7805
8068
  lines.push(
7806
- `[${shortProfileName(auth.profileId)}] ${auth.authorizationId}: the Authority Server no longer verifies this mandate's protocol version. Ask the decision owner to re-approve it.`
8069
+ `[${shortProfileName(auth.profileId)}] ${auth.authorizationId}: the Authority Server no longer accepts this mandate's protocol version. Ask the mandate owner to sign it again (Mandates page \u2192 Sign again).`
7807
8070
  );
7808
8071
  }
7809
8072
  lines.push("");
@@ -7963,10 +8226,10 @@ function listAuthorizationsHandler(state2, integrationManager2, contextDir) {
7963
8226
  const earliestExpiry = Math.min(...auth.attestations.map((a) => a.expiresAt));
7964
8227
  const remainingMin = Math.max(0, Math.round((earliestExpiry - now) / 60));
7965
8228
  const boundsDesc = Object.entries(auth.frame).filter(([key]) => key !== "profile" && key !== "path").map(([key, value]) => `${key}: ${value}`).join(", ");
7966
- const statusLabel = !auth.complete ? " (PENDING)" : auth.needsReapproval ? " (NEEDS RE-APPROVAL)" : "";
8229
+ const statusLabel = !auth.complete ? " (PENDING)" : auth.needsReapproval ? " (MUST BE SIGNED AGAIN)" : "";
7967
8230
  output2.push(`[${auth.path}] ${auth.profileId} (${remainingMin} min remaining)${statusLabel}`);
7968
8231
  if (auth.needsReapproval) {
7969
- output2.push(" The Authority Server no longer verifies this mandate's protocol version. Ask the decision owner to re-approve it.");
8232
+ output2.push(" The Authority Server no longer accepts this mandate's protocol version. Ask the mandate owner to sign it again (Mandates page \u2192 Sign again).");
7970
8233
  }
7971
8234
  output2.push("");
7972
8235
  output2.push(` Bounds: ${boundsDesc}`);
@@ -8030,11 +8293,11 @@ function listAuthorizationsHandler(state2, integrationManager2, contextDir) {
8030
8293
  const remainingMin = Math.max(0, Math.round((earliestExpiry - now) / 60));
8031
8294
  const boundsDesc = Object.entries(auth.frame).filter(([key]) => key !== "profile" && key !== "path").map(([key, value]) => `${key}: ${value}`).join(", ");
8032
8295
  if (auth.complete) {
8033
- const statusLabel = auth.needsReapproval ? " (NEEDS RE-APPROVAL)" : "";
8296
+ const statusLabel = auth.needsReapproval ? " (MUST BE SIGNED AGAIN)" : "";
8034
8297
  const lines = [` [${auth.path}] ${auth.profileId} \u2014 ${remainingMin} min remaining${statusLabel}`];
8035
8298
  lines.push(` Bounds: ${boundsDesc}`);
8036
8299
  if (auth.needsReapproval) {
8037
- lines.push(" The Authority Server no longer verifies this mandate's protocol version. Ask the decision owner to re-approve it.");
8300
+ lines.push(" The Authority Server no longer accepts this mandate's protocol version. Ask the mandate owner to sign it again (Mandates page \u2192 Sign again).");
8038
8301
  }
8039
8302
  if ((auth.deferredCommitmentDomains ?? []).length > 0) {
8040
8303
  lines.push(" Mode: review (each action requires your approval)");
@@ -8268,12 +8531,6 @@ async function executeCommitted(proposal, state2, integrationManager2) {
8268
8531
  const integrationId = proposal.tool.slice(0, sep);
8269
8532
  const toolName = proposal.tool.slice(sep + 2);
8270
8533
  const discovered = integrationManager2.getAllTools().find((t) => t.integrationId === integrationId && t.originalName === toolName);
8271
- const proposalActionType = typeof proposal.executionContext.action_type === "string" ? proposal.executionContext.action_type : void 0;
8272
- if (!proposalActionType) {
8273
- console.error(
8274
- `[Suveren MCP] Warning: proposal ${proposal.id} has no action_type in executionContext. Bounds check may be skipped. Fix the integration manifest for ${proposal.tool}.`
8275
- );
8276
- }
8277
8534
  const cachedAuth = state2.cache.getAllAuthorizations().find((a) => a.authorizationId === proposal.authorizationId);
8278
8535
  const submitted = state2.proposalSubmissions.get(proposal.id);
8279
8536
  if (!submitted) {
@@ -8285,6 +8542,12 @@ async function executeCommitted(proposal, state2, integrationManager2) {
8285
8542
  }
8286
8543
  return { text: buildSkippedProposalNote(proposal.id), skipped: true };
8287
8544
  }
8545
+ const proposalActionType = submitted.actionType ?? (typeof proposal.executionContext.action_type === "string" ? proposal.executionContext.action_type : void 0);
8546
+ if (!proposalActionType) {
8547
+ console.error(
8548
+ `[Suveren MCP] Warning: proposal ${proposal.id} has no action_type. Bounds check may be skipped. Fix the integration manifest for ${proposal.tool}.`
8549
+ );
8550
+ }
8288
8551
  let toolArgs;
8289
8552
  try {
8290
8553
  toolArgs = await resolveProposalToolArgs(proposal);
@@ -8321,18 +8584,29 @@ async function executeCommitted(proposal, state2, integrationManager2) {
8321
8584
  toolArgs,
8322
8585
  proposalActionType
8323
8586
  );
8587
+ state2.executionJournal?.requested?.({
8588
+ requestKey: proposal.id,
8589
+ proposalId: proposal.id,
8590
+ tool: proposal.tool,
8591
+ argsHash: hashToolArgs(toolArgs)
8592
+ });
8324
8593
  const { receipt: r, idempotent } = await state2.spClient.postReceipt({
8325
8594
  authorizationId: proposal.authorizationId,
8326
8595
  // Optional cross-check — the AS fails closed on a mismatch. Parity
8327
8596
  // with the automatic path (tool-proxy.ts).
8328
8597
  boundsHash: cachedAuth?.boundsHash,
8598
+ // v0.8 — the mandate by its signed id (Ticket Request Schema, rule 1).
8599
+ mandateId: cachedAuth?.mandateId,
8329
8600
  profileId: proposal.profileId,
8330
8601
  action: proposal.tool,
8331
8602
  actionType: proposalActionType,
8332
8603
  executionContext: proposal.executionContext,
8333
8604
  amount: typeof proposal.executionContext.amount === "number" ? proposal.executionContext.amount : void 0,
8334
8605
  proposalId: proposal.id,
8335
- toolArgs,
8606
+ // v0.8 (Ticket Request Schema; Proposals, rule 1): the content itself
8607
+ // never travels on the ticket request — only its fingerprint below.
8608
+ // Today's AS matches by `proposal_content_hash` first, so dropping the
8609
+ // readable `toolArgs` it used to receive changes nothing it checks.
8336
8610
  // PE1 — the fingerprint of what THIS gateway resolved (decrypted, or
8337
8611
  // read plain on a legacy row) and is about to execute. The AS compares
8338
8612
  // it against its own stored content_hash and refuses without echoing
@@ -8370,19 +8644,21 @@ async function executeCommitted(proposal, state2, integrationManager2) {
8370
8644
  };
8371
8645
  }
8372
8646
  if (code === "PROPOSAL_REFUSED") {
8647
+ state2.executionJournal?.refusedBeforeTicket?.(proposal.id, "as_refused", `${code}: ${err.message}`);
8373
8648
  return {
8374
8649
  text: `Proposal ${proposal.id}: the Authority Server refused this proposal's ticket earlier \u2014 ${err.message} Nothing ran. Do not retry the same values; ask the person (e.g. for a higher limit).`,
8375
8650
  isError: true
8376
8651
  };
8377
8652
  }
8378
- if (err.statusCode === 409 && code === "VERSION_UNSUPPORTED") {
8653
+ if (code === "VERSION_UNSUPPORTED") {
8379
8654
  state2.cache.markNeedsReapproval(proposal.authorizationId);
8380
8655
  return {
8381
- text: `Proposal ${proposal.id}: blocked \u2014 mandate ${proposal.authorizationId} needs re-approval \u2014 the Authority Server no longer verifies its protocol version. Ask the decision owner to re-approve it (see list-authorizations). ${err.message}`,
8656
+ text: `Proposal ${proposal.id}: blocked \u2014 mandate ${proposal.authorizationId} must be signed again \u2014 the Authority Server no longer accepts its protocol version. Ask the mandate owner to sign it again (Mandates page \u2192 Sign again; see list-authorizations). ${err.message}`,
8382
8657
  isError: true
8383
8658
  };
8384
8659
  }
8385
8660
  if (proposal.id) {
8661
+ state2.executionJournal?.refusedBeforeTicket?.(proposal.id, "as_refused", `${code ?? "TICKET_REFUSED"}: ${err.message}`);
8386
8662
  const asRefusedTicketId = `as_refused:${proposal.id}`;
8387
8663
  const begun2 = state2.executionJournal.begin({
8388
8664
  ticketId: asRefusedTicketId,
@@ -8412,6 +8688,7 @@ async function executeCommitted(proposal, state2, integrationManager2) {
8412
8688
  }
8413
8689
  const begun = state2.executionJournal.begin({
8414
8690
  ticketId: receiptId,
8691
+ requestKey: proposal.id,
8415
8692
  proposalId: proposal.id,
8416
8693
  tool: proposal.tool,
8417
8694
  argsHash: hashToolArgs(toolArgs)
@@ -8435,9 +8712,18 @@ async function executeCommitted(proposal, state2, integrationManager2) {
8435
8712
  executionContext: proposal.executionContext,
8436
8713
  authorizationId: proposal.authorizationId,
8437
8714
  profileId: proposal.profileId,
8715
+ actionType: proposalActionType,
8716
+ boundsHash: cachedAuth?.boundsHash,
8717
+ mandateId: cachedAuth?.mandateId,
8718
+ mandateIds: cachedAuth?.mandateIds,
8719
+ // v0.8 — lets the ticket's version be checked against its mandate and
8720
+ // the approval signatures be verified under the deciders' own DIDs.
8721
+ mandate: mandateForTicket(cachedAuth?.attestations, receipt.mandateId),
8438
8722
  proposalId: proposal.id,
8723
+ proposalContentHash: computeProposalContentHash(toolArgs),
8439
8724
  contentHash: binding?.contentHash,
8440
- contentBinding: binding?.contentBinding
8725
+ contentBinding: binding?.contentBinding,
8726
+ replay: replayed
8441
8727
  });
8442
8728
  await state2.archiveReceipt(receipt, {
8443
8729
  authorizationId: proposal.authorizationId,
@@ -8577,7 +8863,7 @@ Result: ${resultText}` };
8577
8863
  }
8578
8864
  function localOutcomeOfExecuted(proposal, state2) {
8579
8865
  const entry = state2.executionJournal?.findByProposal?.(proposal.id);
8580
- if (!entry) return null;
8866
+ if (!entry || entry.state === "requested") return null;
8581
8867
  const integration = proposal.tool.split("__")[0];
8582
8868
  if (entry.state === "done") {
8583
8869
  const stored = state2.executionResults?.get(proposal.id);
@@ -9010,7 +9296,7 @@ var AgentContactStore = class {
9010
9296
 
9011
9297
  // src/lib/gate-content.ts
9012
9298
  import { computeIntentHash } from "@hap/core";
9013
- import { decodeMandateBlob as decodeMandateBlob2 } from "@hap/core";
9299
+ import { decodeMandateBlob as decodeMandateBlob3 } from "@hap/core";
9014
9300
  function hashGateContent(text) {
9015
9301
  return computeIntentHash(text);
9016
9302
  }
@@ -9019,7 +9305,7 @@ function verifyGateContentHashes(content, auth) {
9019
9305
  if (auth.attestations.length === 0) {
9020
9306
  return { valid: false, errors: ["No attestations available to verify against"] };
9021
9307
  }
9022
- const attestation = decodeMandateBlob2(auth.attestations[0].blob);
9308
+ const attestation = decodeMandateBlob3(auth.attestations[0].blob);
9023
9309
  const expectedHashes = attestation.payload.gate_content_hashes;
9024
9310
  if (!expectedHashes?.intent) {
9025
9311
  return { valid: false, errors: ["Attestation does not contain intent hash"] };
@@ -11505,7 +11791,7 @@ function registerBuiltins(deps, factories = BUILTIN_FACTORIES) {
11505
11791
  }
11506
11792
 
11507
11793
  // bin/http.ts
11508
- import { decodeMandateBlob as decodeMandateBlob3 } from "@hap/core";
11794
+ import { decodeMandateBlob as decodeMandateBlob4 } from "@hap/core";
11509
11795
 
11510
11796
  // src/lib/committed-executor.ts
11511
11797
  import { existsSync as existsSync21, mkdirSync as mkdirSync16, readFileSync as readFileSync22, unlinkSync as unlinkSync8, writeFileSync as writeFileSync16 } from "fs";
@@ -12170,7 +12456,7 @@ app.get("/internal/evidence", internalOnly, (_req, res) => {
12170
12456
  ...a,
12171
12457
  attestations: a.attestations.map((att) => {
12172
12458
  try {
12173
- return { ...att, decoded: decodeMandateBlob3(att.blob) };
12459
+ return { ...att, decoded: decodeMandateBlob4(att.blob) };
12174
12460
  } catch {
12175
12461
  return att;
12176
12462
  }