@kya-os/mcp 1.16.2 → 1.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (469) hide show
  1. package/AUDITABILITY.md +129 -8
  2. package/CHANGELOG.md +641 -0
  3. package/CONFORMANCE.md +12 -6
  4. package/README.md +67 -26
  5. package/SPEC.md +105 -18
  6. package/dist/audit/adapters/legacy-audit-log.d.ts +0 -1
  7. package/dist/audit/adapters/mcp.d.ts +0 -1
  8. package/dist/audit/adapters/mcp.js +35 -20
  9. package/dist/audit/adapters/mcp.js.map +1 -1
  10. package/dist/audit/adapters/references.d.ts +9 -0
  11. package/dist/audit/adapters/references.js +22 -0
  12. package/dist/audit/adapters/references.js.map +1 -0
  13. package/dist/audit/assurance.d.ts +0 -1
  14. package/dist/audit/checkpoint-coordinator.d.ts +0 -1
  15. package/dist/audit/checkpoint.d.ts +17 -1
  16. package/dist/audit/checkpoint.js +76 -21
  17. package/dist/audit/checkpoint.js.map +1 -1
  18. package/dist/audit/cli.d.ts +0 -1
  19. package/dist/audit/crypto.d.ts +0 -1
  20. package/dist/audit/crypto.js +12 -3
  21. package/dist/audit/crypto.js.map +1 -1
  22. package/dist/audit/errors.d.ts +0 -1
  23. package/dist/audit/evidence.d.ts +0 -1
  24. package/dist/audit/index.d.ts +0 -1
  25. package/dist/audit/integrity.d.ts +0 -1
  26. package/dist/audit/merkle.d.ts +0 -1
  27. package/dist/audit/mirror-service.d.ts +0 -1
  28. package/dist/audit/projection.d.ts +1 -1
  29. package/dist/audit/projection.js +23 -2
  30. package/dist/audit/projection.js.map +1 -1
  31. package/dist/audit/providers/anchor.d.ts +0 -1
  32. package/dist/audit/providers/evidence.d.ts +0 -1
  33. package/dist/audit/providers/journal.d.ts +0 -1
  34. package/dist/audit/providers/memory-journal.d.ts +0 -1
  35. package/dist/audit/providers/observer.d.ts +0 -1
  36. package/dist/audit/providers/outbox.d.ts +35 -6
  37. package/dist/audit/providers/outbox.js +46 -8
  38. package/dist/audit/providers/outbox.js.map +1 -1
  39. package/dist/audit/providers/recorder-client.d.ts +0 -1
  40. package/dist/audit/providers/source-state.d.ts +24 -2
  41. package/dist/audit/providers/source-state.js +65 -44
  42. package/dist/audit/providers/source-state.js.map +1 -1
  43. package/dist/audit/read-contract.d.ts +0 -1
  44. package/dist/audit/read-service.d.ts +2 -3
  45. package/dist/audit/read-service.js +17 -12
  46. package/dist/audit/read-service.js.map +1 -1
  47. package/dist/audit/recorder-service.d.ts +33 -5
  48. package/dist/audit/recorder-service.js +116 -20
  49. package/dist/audit/recorder-service.js.map +1 -1
  50. package/dist/audit/reference-recorder.d.ts +0 -1
  51. package/dist/audit/replay-bundle.d.ts +0 -1
  52. package/dist/audit/replay-bundle.js +143 -36
  53. package/dist/audit/replay-bundle.js.map +1 -1
  54. package/dist/audit/schemas.d.ts +0 -1
  55. package/dist/audit/service.d.ts +6 -3
  56. package/dist/audit/service.js +55 -24
  57. package/dist/audit/service.js.map +1 -1
  58. package/dist/audit/testing/index.d.ts +0 -1
  59. package/dist/audit/testing/provider-contracts.d.ts +1 -2
  60. package/dist/audit/testing/provider-contracts.js +32 -2
  61. package/dist/audit/testing/provider-contracts.js.map +1 -1
  62. package/dist/audit/types.d.ts +0 -1
  63. package/dist/audit/verifier.d.ts +57 -5
  64. package/dist/audit/verifier.js +240 -49
  65. package/dist/audit/verifier.js.map +1 -1
  66. package/dist/auth/handshake.d.ts +12 -1
  67. package/dist/auth/handshake.js +44 -11
  68. package/dist/auth/handshake.js.map +1 -1
  69. package/dist/auth/index.d.ts +0 -1
  70. package/dist/auth/types.d.ts +0 -1
  71. package/dist/authz/accountability.d.ts +0 -1
  72. package/dist/authz/adapter.d.ts +0 -1
  73. package/dist/authz/examples/inmemory-oidc.d.ts +0 -1
  74. package/dist/authz/index.d.ts +0 -1
  75. package/dist/authz/oidc/authorize.d.ts +0 -1
  76. package/dist/authz/oidc/metadata.d.ts +0 -1
  77. package/dist/authz/oidc/oidc-adapter.d.ts +0 -1
  78. package/dist/authz/oidc/oidc-adapter.js +51 -3
  79. package/dist/authz/oidc/oidc-adapter.js.map +1 -1
  80. package/dist/authz/oidc/pending-flow-store.d.ts +6 -1
  81. package/dist/authz/oidc/pending-flow-store.js +22 -2
  82. package/dist/authz/oidc/pending-flow-store.js.map +1 -1
  83. package/dist/authz/oidc/pkce.d.ts +0 -1
  84. package/dist/authz/registry.d.ts +0 -1
  85. package/dist/authz/requirement.d.ts +0 -1
  86. package/dist/card/build.d.ts +0 -1
  87. package/dist/card/builder.d.ts +0 -1
  88. package/dist/card/cimd.d.ts +19 -5
  89. package/dist/card/cimd.js +52 -7
  90. package/dist/card/cimd.js.map +1 -1
  91. package/dist/card/delegation.d.ts +12 -4
  92. package/dist/card/delegation.js +38 -22
  93. package/dist/card/delegation.js.map +1 -1
  94. package/dist/card/emit.d.ts +0 -1
  95. package/dist/card/index.d.ts +0 -1
  96. package/dist/card/middleware.d.ts +0 -1
  97. package/dist/card/proof/build.d.ts +0 -1
  98. package/dist/card/proof/canonical.d.ts +0 -1
  99. package/dist/card/proof/canonical.js +6 -1
  100. package/dist/card/proof/canonical.js.map +1 -1
  101. package/dist/card/proof/http-sig.d.ts +0 -1
  102. package/dist/card/proof/index.d.ts +0 -1
  103. package/dist/card/proof/nonce-cache.d.ts +15 -14
  104. package/dist/card/proof/nonce-cache.js +22 -20
  105. package/dist/card/proof/nonce-cache.js.map +1 -1
  106. package/dist/card/proof/signer.d.ts +0 -1
  107. package/dist/card/proof/types.d.ts +10 -4
  108. package/dist/card/proof/types.js +2 -2
  109. package/dist/card/proof/verify.d.ts +0 -1
  110. package/dist/card/proof/verify.js +17 -3
  111. package/dist/card/proof/verify.js.map +1 -1
  112. package/dist/card/resolve.d.ts +0 -1
  113. package/dist/card/resolve.js +13 -8
  114. package/dist/card/resolve.js.map +1 -1
  115. package/dist/card/revocation.d.ts +0 -1
  116. package/dist/card/revocation.js +18 -6
  117. package/dist/card/revocation.js.map +1 -1
  118. package/dist/card/schema.d.ts +7 -6
  119. package/dist/card/schema.js +7 -3
  120. package/dist/card/schema.js.map +1 -1
  121. package/dist/card/verify.d.ts +0 -1
  122. package/dist/delegation/audience-validator.d.ts +0 -1
  123. package/dist/delegation/bitstring.d.ts +0 -1
  124. package/dist/delegation/cascading-revocation.d.ts +1 -2
  125. package/dist/delegation/cascading-revocation.js +34 -36
  126. package/dist/delegation/cascading-revocation.js.map +1 -1
  127. package/dist/delegation/chain-enforcement.d.ts +42 -5
  128. package/dist/delegation/chain-enforcement.js +127 -34
  129. package/dist/delegation/chain-enforcement.js.map +1 -1
  130. package/dist/delegation/delegation-graph.d.ts +30 -1
  131. package/dist/delegation/delegation-graph.js +33 -0
  132. package/dist/delegation/delegation-graph.js.map +1 -1
  133. package/dist/delegation/delegation-registration.d.ts +22 -0
  134. package/dist/delegation/delegation-registration.js +51 -0
  135. package/dist/delegation/delegation-registration.js.map +1 -0
  136. package/dist/delegation/delegation-status-entry.d.ts +22 -0
  137. package/dist/delegation/delegation-status-entry.js +42 -0
  138. package/dist/delegation/delegation-status-entry.js.map +1 -0
  139. package/dist/delegation/did-key-resolver.d.ts +0 -1
  140. package/dist/delegation/did-key-resolver.js +15 -4
  141. package/dist/delegation/did-key-resolver.js.map +1 -1
  142. package/dist/delegation/did-linkage.d.ts +0 -1
  143. package/dist/delegation/did-resolver-registry.d.ts +0 -1
  144. package/dist/delegation/did-web-resolver.d.ts +0 -1
  145. package/dist/delegation/did-web-resolver.js +40 -5
  146. package/dist/delegation/did-web-resolver.js.map +1 -1
  147. package/dist/delegation/holder-binding.d.ts +11 -11
  148. package/dist/delegation/holder-binding.js +8 -17
  149. package/dist/delegation/holder-binding.js.map +1 -1
  150. package/dist/delegation/index.d.ts +0 -1
  151. package/dist/delegation/outbound-headers.d.ts +0 -1
  152. package/dist/delegation/outbound-proof.d.ts +0 -1
  153. package/dist/delegation/scope-matcher.d.ts +25 -2
  154. package/dist/delegation/scope-matcher.js +75 -5
  155. package/dist/delegation/scope-matcher.js.map +1 -1
  156. package/dist/delegation/status-cache.d.ts +0 -1
  157. package/dist/delegation/statuslist-manager.d.ts +18 -2
  158. package/dist/delegation/statuslist-manager.js +40 -14
  159. package/dist/delegation/statuslist-manager.js.map +1 -1
  160. package/dist/delegation/storage/memory-graph-storage.d.ts +9 -3
  161. package/dist/delegation/storage/memory-graph-storage.js +28 -14
  162. package/dist/delegation/storage/memory-graph-storage.js.map +1 -1
  163. package/dist/delegation/storage/memory-statuslist-storage.d.ts +0 -1
  164. package/dist/delegation/utils.d.ts +5 -5
  165. package/dist/delegation/utils.js +4 -4
  166. package/dist/delegation/utils.js.map +1 -1
  167. package/dist/delegation/vc-issuer.d.ts +0 -1
  168. package/dist/delegation/vc-jwt-verify.d.ts +7 -2
  169. package/dist/delegation/vc-jwt-verify.js +55 -3
  170. package/dist/delegation/vc-jwt-verify.js.map +1 -1
  171. package/dist/delegation/vc-verification-checks.d.ts +0 -1
  172. package/dist/delegation/vc-verification-checks.js +9 -5
  173. package/dist/delegation/vc-verification-checks.js.map +1 -1
  174. package/dist/delegation/vc-verifier.d.ts +0 -1
  175. package/dist/delegation/vc-verifier.types.d.ts +0 -1
  176. package/dist/delegation/verification-method-key.d.ts +0 -1
  177. package/dist/delegation/verification-method-key.js +4 -3
  178. package/dist/delegation/verification-method-key.js.map +1 -1
  179. package/dist/errors.d.ts +0 -1
  180. package/dist/extension/declaration.d.ts +0 -1
  181. package/dist/extension/gate.d.ts +0 -1
  182. package/dist/extension/index.d.ts +0 -1
  183. package/dist/extension/settings.d.ts +0 -1
  184. package/dist/index.d.ts +2 -3
  185. package/dist/index.js +1 -1
  186. package/dist/index.js.map +1 -1
  187. package/dist/integrations/cheqd/dlr.d.ts +0 -1
  188. package/dist/integrations/cheqd/dlr.js +6 -1
  189. package/dist/integrations/cheqd/dlr.js.map +1 -1
  190. package/dist/integrations/cheqd/index.d.ts +0 -1
  191. package/dist/integrations/cheqd/linkage.d.ts +0 -1
  192. package/dist/integrations/cheqd/registrar.d.ts +0 -1
  193. package/dist/integrations/cheqd/resolver.d.ts +0 -1
  194. package/dist/integrations/cheqd/statuslist-resolver.d.ts +0 -1
  195. package/dist/logging/index.d.ts +0 -1
  196. package/dist/logging/logger.d.ts +0 -1
  197. package/dist/middleware/index.d.ts +0 -1
  198. package/dist/middleware/kya-os-transport.d.ts +5 -3
  199. package/dist/middleware/kya-os-transport.js +58 -24
  200. package/dist/middleware/kya-os-transport.js.map +1 -1
  201. package/dist/middleware/with-kya-os-server.d.ts +30 -4
  202. package/dist/middleware/with-kya-os-server.js +19 -0
  203. package/dist/middleware/with-kya-os-server.js.map +1 -1
  204. package/dist/middleware/with-kya-os.config-types.d.ts +32 -4
  205. package/dist/middleware/with-kya-os.d.ts +0 -1
  206. package/dist/middleware/with-kya-os.delegation-gate.d.ts +2 -1
  207. package/dist/middleware/with-kya-os.delegation-gate.js +37 -9
  208. package/dist/middleware/with-kya-os.delegation-gate.js.map +1 -1
  209. package/dist/middleware/with-kya-os.delegation-verify.d.ts +1 -1
  210. package/dist/middleware/with-kya-os.delegation-verify.js +52 -9
  211. package/dist/middleware/with-kya-os.delegation-verify.js.map +1 -1
  212. package/dist/middleware/with-kya-os.deps.d.ts +0 -1
  213. package/dist/middleware/with-kya-os.grants.d.ts +13 -6
  214. package/dist/middleware/with-kya-os.grants.js +56 -18
  215. package/dist/middleware/with-kya-os.grants.js.map +1 -1
  216. package/dist/middleware/with-kya-os.helpers.d.ts +0 -1
  217. package/dist/middleware/with-kya-os.js +14 -4
  218. package/dist/middleware/with-kya-os.js.map +1 -1
  219. package/dist/middleware/with-kya-os.policy-gate.d.ts +0 -1
  220. package/dist/middleware/with-kya-os.policy-gate.js +18 -9
  221. package/dist/middleware/with-kya-os.policy-gate.js.map +1 -1
  222. package/dist/middleware/with-kya-os.protocol.d.ts +0 -1
  223. package/dist/middleware/with-kya-os.session.d.ts +28 -1
  224. package/dist/middleware/with-kya-os.session.js +146 -7
  225. package/dist/middleware/with-kya-os.session.js.map +1 -1
  226. package/dist/middleware/with-kya-os.types.d.ts +28 -5
  227. package/dist/policy/approval.d.ts +13 -2
  228. package/dist/policy/approval.js +15 -4
  229. package/dist/policy/approval.js.map +1 -1
  230. package/dist/policy/classifier.d.ts +0 -1
  231. package/dist/policy/default-engine.d.ts +5 -2
  232. package/dist/policy/default-engine.js +10 -2
  233. package/dist/policy/default-engine.js.map +1 -1
  234. package/dist/policy/engine.d.ts +0 -1
  235. package/dist/policy/index.d.ts +0 -1
  236. package/dist/policy/projection.d.ts +0 -1
  237. package/dist/policy/types.d.ts +0 -1
  238. package/dist/proof/covered-request.d.ts +46 -0
  239. package/dist/proof/covered-request.js +107 -0
  240. package/dist/proof/covered-request.js.map +1 -0
  241. package/dist/proof/errors.d.ts +3 -1
  242. package/dist/proof/errors.js +5 -0
  243. package/dist/proof/errors.js.map +1 -1
  244. package/dist/proof/generator.d.ts +51 -1
  245. package/dist/proof/generator.js +71 -13
  246. package/dist/proof/generator.js.map +1 -1
  247. package/dist/proof/index.d.ts +1 -2
  248. package/dist/proof/index.js.map +1 -1
  249. package/dist/proof/verifier.d.ts +50 -12
  250. package/dist/proof/verifier.js +164 -84
  251. package/dist/proof/verifier.js.map +1 -1
  252. package/dist/providers/audit-log.d.ts +0 -1
  253. package/dist/providers/base.d.ts +19 -1
  254. package/dist/providers/base.js.map +1 -1
  255. package/dist/providers/grant-store.d.ts +8 -2
  256. package/dist/providers/grant-store.js +5 -5
  257. package/dist/providers/grant-store.js.map +1 -1
  258. package/dist/providers/index.d.ts +0 -1
  259. package/dist/providers/memory.d.ts +19 -1
  260. package/dist/providers/memory.js +53 -7
  261. package/dist/providers/memory.js.map +1 -1
  262. package/dist/providers/node-crypto.d.ts +4 -1
  263. package/dist/providers/node-crypto.js +32 -9
  264. package/dist/providers/node-crypto.js.map +1 -1
  265. package/dist/providers/nonce-admission.d.ts +31 -0
  266. package/dist/providers/nonce-admission.js +47 -0
  267. package/dist/providers/nonce-admission.js.map +1 -0
  268. package/dist/providers/nonce-retention.d.ts +8 -0
  269. package/dist/providers/nonce-retention.js +15 -0
  270. package/dist/providers/nonce-retention.js.map +1 -0
  271. package/dist/providers/runtime-fetch.d.ts +0 -1
  272. package/dist/providers/system-clock.d.ts +0 -1
  273. package/dist/providers/web-crypto.d.ts +0 -1
  274. package/dist/providers/web-crypto.js +7 -1
  275. package/dist/providers/web-crypto.js.map +1 -1
  276. package/dist/session/index.d.ts +0 -1
  277. package/dist/session/manager.d.ts +13 -1
  278. package/dist/session/manager.js +25 -9
  279. package/dist/session/manager.js.map +1 -1
  280. package/dist/session/session-store.d.ts +0 -1
  281. package/dist/types/protocol.d.ts +11 -3
  282. package/dist/types/protocol.js +21 -14
  283. package/dist/types/protocol.js.map +1 -1
  284. package/dist/utils/base58.d.ts +16 -3
  285. package/dist/utils/base58.js +34 -12
  286. package/dist/utils/base58.js.map +1 -1
  287. package/dist/utils/base64.d.ts +0 -1
  288. package/dist/utils/canonical-json.d.ts +7 -1
  289. package/dist/utils/canonical-json.js +130 -60
  290. package/dist/utils/canonical-json.js.map +1 -1
  291. package/dist/utils/crypto-service.d.ts +0 -1
  292. package/dist/utils/crypto-service.js +22 -2
  293. package/dist/utils/crypto-service.js.map +1 -1
  294. package/dist/utils/did-helpers.d.ts +0 -1
  295. package/dist/utils/ed25519-constants.d.ts +0 -1
  296. package/dist/utils/ed25519-public-key.d.ts +27 -0
  297. package/dist/utils/ed25519-public-key.js +86 -0
  298. package/dist/utils/ed25519-public-key.js.map +1 -0
  299. package/dist/utils/guards.d.ts +0 -1
  300. package/dist/utils/index.d.ts +0 -1
  301. package/dist/utils/ip-classifier.d.ts +0 -1
  302. package/dist/utils/safe-fetch-transports.d.ts +0 -1
  303. package/dist/utils/safe-fetch-types.d.ts +0 -1
  304. package/dist/utils/safe-fetch.d.ts +0 -1
  305. package/dist/utils/statuslist-bits.d.ts +0 -1
  306. package/dist/utils/statuslist-purpose.d.ts +0 -1
  307. package/dist/utils/ttl-cache.d.ts +0 -1
  308. package/dist/utils/url.d.ts +0 -1
  309. package/package.json +24 -19
  310. package/schemas/card-delegation-credential.json +4 -1
  311. package/dist/audit/adapters/legacy-audit-log.d.ts.map +0 -1
  312. package/dist/audit/adapters/mcp.d.ts.map +0 -1
  313. package/dist/audit/assurance.d.ts.map +0 -1
  314. package/dist/audit/checkpoint-coordinator.d.ts.map +0 -1
  315. package/dist/audit/checkpoint.d.ts.map +0 -1
  316. package/dist/audit/cli.d.ts.map +0 -1
  317. package/dist/audit/crypto.d.ts.map +0 -1
  318. package/dist/audit/errors.d.ts.map +0 -1
  319. package/dist/audit/evidence.d.ts.map +0 -1
  320. package/dist/audit/index.d.ts.map +0 -1
  321. package/dist/audit/integrity.d.ts.map +0 -1
  322. package/dist/audit/merkle.d.ts.map +0 -1
  323. package/dist/audit/mirror-service.d.ts.map +0 -1
  324. package/dist/audit/projection.d.ts.map +0 -1
  325. package/dist/audit/providers/anchor.d.ts.map +0 -1
  326. package/dist/audit/providers/evidence.d.ts.map +0 -1
  327. package/dist/audit/providers/journal.d.ts.map +0 -1
  328. package/dist/audit/providers/memory-journal.d.ts.map +0 -1
  329. package/dist/audit/providers/observer.d.ts.map +0 -1
  330. package/dist/audit/providers/outbox.d.ts.map +0 -1
  331. package/dist/audit/providers/recorder-client.d.ts.map +0 -1
  332. package/dist/audit/providers/source-state.d.ts.map +0 -1
  333. package/dist/audit/read-contract.d.ts.map +0 -1
  334. package/dist/audit/read-service.d.ts.map +0 -1
  335. package/dist/audit/recorder-service.d.ts.map +0 -1
  336. package/dist/audit/reference-recorder.d.ts.map +0 -1
  337. package/dist/audit/replay-bundle.d.ts.map +0 -1
  338. package/dist/audit/schemas.d.ts.map +0 -1
  339. package/dist/audit/service.d.ts.map +0 -1
  340. package/dist/audit/testing/index.d.ts.map +0 -1
  341. package/dist/audit/testing/provider-contracts.d.ts.map +0 -1
  342. package/dist/audit/types.d.ts.map +0 -1
  343. package/dist/audit/verifier.d.ts.map +0 -1
  344. package/dist/auth/handshake.d.ts.map +0 -1
  345. package/dist/auth/index.d.ts.map +0 -1
  346. package/dist/auth/types.d.ts.map +0 -1
  347. package/dist/authz/accountability.d.ts.map +0 -1
  348. package/dist/authz/adapter.d.ts.map +0 -1
  349. package/dist/authz/examples/inmemory-oidc.d.ts.map +0 -1
  350. package/dist/authz/index.d.ts.map +0 -1
  351. package/dist/authz/oidc/authorize.d.ts.map +0 -1
  352. package/dist/authz/oidc/metadata.d.ts.map +0 -1
  353. package/dist/authz/oidc/oidc-adapter.d.ts.map +0 -1
  354. package/dist/authz/oidc/pending-flow-store.d.ts.map +0 -1
  355. package/dist/authz/oidc/pkce.d.ts.map +0 -1
  356. package/dist/authz/registry.d.ts.map +0 -1
  357. package/dist/authz/requirement.d.ts.map +0 -1
  358. package/dist/card/build.d.ts.map +0 -1
  359. package/dist/card/builder.d.ts.map +0 -1
  360. package/dist/card/cimd.d.ts.map +0 -1
  361. package/dist/card/delegation.d.ts.map +0 -1
  362. package/dist/card/emit.d.ts.map +0 -1
  363. package/dist/card/index.d.ts.map +0 -1
  364. package/dist/card/middleware.d.ts.map +0 -1
  365. package/dist/card/proof/build.d.ts.map +0 -1
  366. package/dist/card/proof/canonical.d.ts.map +0 -1
  367. package/dist/card/proof/http-sig.d.ts.map +0 -1
  368. package/dist/card/proof/index.d.ts.map +0 -1
  369. package/dist/card/proof/nonce-cache.d.ts.map +0 -1
  370. package/dist/card/proof/signer.d.ts.map +0 -1
  371. package/dist/card/proof/types.d.ts.map +0 -1
  372. package/dist/card/proof/verify.d.ts.map +0 -1
  373. package/dist/card/resolve.d.ts.map +0 -1
  374. package/dist/card/revocation.d.ts.map +0 -1
  375. package/dist/card/schema.d.ts.map +0 -1
  376. package/dist/card/verify.d.ts.map +0 -1
  377. package/dist/delegation/audience-validator.d.ts.map +0 -1
  378. package/dist/delegation/bitstring.d.ts.map +0 -1
  379. package/dist/delegation/cascading-revocation.d.ts.map +0 -1
  380. package/dist/delegation/chain-enforcement.d.ts.map +0 -1
  381. package/dist/delegation/delegation-graph.d.ts.map +0 -1
  382. package/dist/delegation/did-key-resolver.d.ts.map +0 -1
  383. package/dist/delegation/did-linkage.d.ts.map +0 -1
  384. package/dist/delegation/did-resolver-registry.d.ts.map +0 -1
  385. package/dist/delegation/did-web-resolver.d.ts.map +0 -1
  386. package/dist/delegation/holder-binding.d.ts.map +0 -1
  387. package/dist/delegation/index.d.ts.map +0 -1
  388. package/dist/delegation/outbound-headers.d.ts.map +0 -1
  389. package/dist/delegation/outbound-proof.d.ts.map +0 -1
  390. package/dist/delegation/scope-matcher.d.ts.map +0 -1
  391. package/dist/delegation/status-cache.d.ts.map +0 -1
  392. package/dist/delegation/statuslist-manager.d.ts.map +0 -1
  393. package/dist/delegation/storage/memory-graph-storage.d.ts.map +0 -1
  394. package/dist/delegation/storage/memory-statuslist-storage.d.ts.map +0 -1
  395. package/dist/delegation/utils.d.ts.map +0 -1
  396. package/dist/delegation/vc-issuer.d.ts.map +0 -1
  397. package/dist/delegation/vc-jwt-verify.d.ts.map +0 -1
  398. package/dist/delegation/vc-verification-checks.d.ts.map +0 -1
  399. package/dist/delegation/vc-verifier.d.ts.map +0 -1
  400. package/dist/delegation/vc-verifier.types.d.ts.map +0 -1
  401. package/dist/delegation/verification-method-key.d.ts.map +0 -1
  402. package/dist/errors.d.ts.map +0 -1
  403. package/dist/extension/declaration.d.ts.map +0 -1
  404. package/dist/extension/gate.d.ts.map +0 -1
  405. package/dist/extension/index.d.ts.map +0 -1
  406. package/dist/extension/settings.d.ts.map +0 -1
  407. package/dist/index.d.ts.map +0 -1
  408. package/dist/integrations/cheqd/dlr.d.ts.map +0 -1
  409. package/dist/integrations/cheqd/index.d.ts.map +0 -1
  410. package/dist/integrations/cheqd/linkage.d.ts.map +0 -1
  411. package/dist/integrations/cheqd/registrar.d.ts.map +0 -1
  412. package/dist/integrations/cheqd/resolver.d.ts.map +0 -1
  413. package/dist/integrations/cheqd/statuslist-resolver.d.ts.map +0 -1
  414. package/dist/logging/index.d.ts.map +0 -1
  415. package/dist/logging/logger.d.ts.map +0 -1
  416. package/dist/middleware/index.d.ts.map +0 -1
  417. package/dist/middleware/kya-os-transport.d.ts.map +0 -1
  418. package/dist/middleware/with-kya-os-server.d.ts.map +0 -1
  419. package/dist/middleware/with-kya-os.config-types.d.ts.map +0 -1
  420. package/dist/middleware/with-kya-os.d.ts.map +0 -1
  421. package/dist/middleware/with-kya-os.delegation-gate.d.ts.map +0 -1
  422. package/dist/middleware/with-kya-os.delegation-verify.d.ts.map +0 -1
  423. package/dist/middleware/with-kya-os.deps.d.ts.map +0 -1
  424. package/dist/middleware/with-kya-os.grants.d.ts.map +0 -1
  425. package/dist/middleware/with-kya-os.helpers.d.ts.map +0 -1
  426. package/dist/middleware/with-kya-os.policy-gate.d.ts.map +0 -1
  427. package/dist/middleware/with-kya-os.protocol.d.ts.map +0 -1
  428. package/dist/middleware/with-kya-os.session.d.ts.map +0 -1
  429. package/dist/middleware/with-kya-os.types.d.ts.map +0 -1
  430. package/dist/policy/approval.d.ts.map +0 -1
  431. package/dist/policy/classifier.d.ts.map +0 -1
  432. package/dist/policy/default-engine.d.ts.map +0 -1
  433. package/dist/policy/engine.d.ts.map +0 -1
  434. package/dist/policy/index.d.ts.map +0 -1
  435. package/dist/policy/projection.d.ts.map +0 -1
  436. package/dist/policy/types.d.ts.map +0 -1
  437. package/dist/proof/errors.d.ts.map +0 -1
  438. package/dist/proof/generator.d.ts.map +0 -1
  439. package/dist/proof/index.d.ts.map +0 -1
  440. package/dist/proof/verifier.d.ts.map +0 -1
  441. package/dist/providers/audit-log.d.ts.map +0 -1
  442. package/dist/providers/base.d.ts.map +0 -1
  443. package/dist/providers/grant-store.d.ts.map +0 -1
  444. package/dist/providers/index.d.ts.map +0 -1
  445. package/dist/providers/memory.d.ts.map +0 -1
  446. package/dist/providers/node-crypto.d.ts.map +0 -1
  447. package/dist/providers/runtime-fetch.d.ts.map +0 -1
  448. package/dist/providers/system-clock.d.ts.map +0 -1
  449. package/dist/providers/web-crypto.d.ts.map +0 -1
  450. package/dist/session/index.d.ts.map +0 -1
  451. package/dist/session/manager.d.ts.map +0 -1
  452. package/dist/session/session-store.d.ts.map +0 -1
  453. package/dist/types/protocol.d.ts.map +0 -1
  454. package/dist/utils/base58.d.ts.map +0 -1
  455. package/dist/utils/base64.d.ts.map +0 -1
  456. package/dist/utils/canonical-json.d.ts.map +0 -1
  457. package/dist/utils/crypto-service.d.ts.map +0 -1
  458. package/dist/utils/did-helpers.d.ts.map +0 -1
  459. package/dist/utils/ed25519-constants.d.ts.map +0 -1
  460. package/dist/utils/guards.d.ts.map +0 -1
  461. package/dist/utils/index.d.ts.map +0 -1
  462. package/dist/utils/ip-classifier.d.ts.map +0 -1
  463. package/dist/utils/safe-fetch-transports.d.ts.map +0 -1
  464. package/dist/utils/safe-fetch-types.d.ts.map +0 -1
  465. package/dist/utils/safe-fetch.d.ts.map +0 -1
  466. package/dist/utils/statuslist-bits.d.ts.map +0 -1
  467. package/dist/utils/statuslist-purpose.d.ts.map +0 -1
  468. package/dist/utils/ttl-cache.d.ts.map +0 -1
  469. package/dist/utils/url.d.ts.map +0 -1
package/CHANGELOG.md CHANGED
@@ -7,6 +7,647 @@ Versioning: https://semver.org/spec/v2.0.0.html
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [1.18.0] - 2026-10-08
11
+
12
+ ### Added
13
+
14
+ - **`maxChainLength` for delegation chains.** `validateDelegationChain` and
15
+ the middleware's `delegation` config take an optional cap on how many
16
+ credentials one chain may hold, checked before any of them is verified. A
17
+ resolver could return a chain of any length, and each credential costs a
18
+ signature check and possibly a DID resolution. It is a local cost limit, not
19
+ a protocol rule about how far authority may be delegated: it is unset by
20
+ default, and SPEC.md §6.4 records that the base profile leaves chain length
21
+ unbounded. The middleware refuses a value that is not a positive integer at
22
+ startup rather than rejecting every call. The cap applies to the chain
23
+ `resolveDelegationChain` returns, not to the resolver's own fetches.
24
+
25
+ ### Changed
26
+
27
+ - **The Entity Card chain limit is opt-in, as on the base profile.**
28
+ `validateDelegationChain` and `evaluateDelegationChain` in
29
+ `@kya-os/mcp/card` rejected any chain of more than `MAX_DELEGATION_DEPTH`
30
+ (10) credentials unless the caller passed a larger `maxDepth`. They now
31
+ accept any length unless the caller sets `maxChainLength`, the option's name
32
+ on both profiles. **A verifier that relied on the default now accepts chains
33
+ of 11 credentials or more; pass `maxChainLength: MAX_DELEGATION_DEPTH` to
34
+ keep the previous behavior.** A longer chain broadens nothing: every hop
35
+ still attenuates its parent, so the cap bounded only the verifier's work.
36
+ SPEC.md §6.10 drops the cap from the attenuation invariants and states it,
37
+ non-normatively, as a local limit, as §6.4 does for the base profile. A
38
+ limit that is not a positive integer rejects every chain; previously `NaN`
39
+ accepted every length.
40
+
41
+ ### Deprecated
42
+
43
+ - **`maxDepth` on the Entity Card `DelegationChainContext`.** Use
44
+ `maxChainLength`, which wins when both are set.
45
+
46
+ ### Fixed
47
+
48
+ - **The `example:*` scripts run from a fresh clone.** They resolved
49
+ `@kya-os/mcp` to `dist/`, which a clone does not have until `npm run build`,
50
+ and the node-server and authz-inspector examples, being packages of their
51
+ own, could not resolve it at all without a per-example install. The scripts
52
+ and `scripts/demo.sh` now run the examples from `src/` through
53
+ `tsconfig.examples.json`, so the root `npm install` is all they need. Two
54
+ scripts are added for the consent-persistence scenarios.
55
+ - **`withKyaOs()` warns when the server is already connected.** It wraps
56
+ transports by patching `connect()`, so a transport connected before it ran
57
+ was never wrapped, and its tool results went out without a KYA-OS proof or
58
+ a transport audit record, silently. It now logs a warning saying so, on MCP
59
+ SDK 1.3 and later. When the server had no tools before connecting, the
60
+ warning also explains the SDK's refusal to register `_kyaos`.
61
+
62
+ ### Documentation
63
+
64
+ - **CONFORMANCE.md L2.17 names the current proof keys.** It told verifiers to
65
+ read `org.kya-os/proof`, a key no server writes since the role-named keys
66
+ of SPEC.md §7.6. It now names `org.kya-os/response-proof`, keeps the prior
67
+ keys as 1.x fallbacks, in that order, and separates the request proof under
68
+ `org.kya-os/request-proof`.
69
+ - **SPEC.md §6.10 says how to tell the two delegation profiles apart.** The
70
+ first `@context` entry selects the rule set.
71
+
72
+ ## [1.17.0] - 2026-10-05
73
+
74
+ ### Added
75
+
76
+ - **Scope helpers in `@kya-os/mcp/delegation`.** `matcherContains(outer,
77
+ inner)` decides, by sound rules only, whether one scope matcher grants
78
+ everything another grants. `authorityContains(authority)` builds that check
79
+ once for a whole list of matchers. `scopeAuthority(credential)` returns a
80
+ credential's flat scopes and CRISP matchers as one list of matchers.
81
+ `crispScopes(credential)` returns its CRISP matchers. Scope attenuation
82
+ below is built on them.
83
+ - **Signer binding options for `ProofVerifier.verifyProof`.** An optional
84
+ fourth argument, `{ expectedDid, expectedAudience }` (type
85
+ `ProofVerificationOptions`), rejects a proof from another signer
86
+ (`DID_MISMATCH`) or addressed to another audience (`AUDIENCE_MISMATCH`);
87
+ `expectedAudience` may list several DIDs. Omitting it verifies as before.
88
+ - **`withKyaOs` takes `nonceCache`, `requireAtomicNonce`, and
89
+ `responseProofProfile`.** The adapter could not pass them to the middleware,
90
+ and its `session` option documented a top-level `nonceCache` that did not
91
+ exist. Each replica of a multi-replica deployment therefore kept a private
92
+ in-memory nonce cache and accepted a handshake replayed from another
93
+ replica (SPEC.md §5.5, §11.2; SPEC-MCP-EXTENSION.md §10.4),
94
+ `requireAtomicNonce` was unreachable, and envelope-profile proofs could not
95
+ be enabled. All three now pass through to `createKyaOsMiddleware`. Each is
96
+ optional, and leaving it out keeps the previous default.
97
+ - **`KyaOsCallContext.principal` and `KyaOsCallContext.approvals`.**
98
+ `wrapWithDelegation` fills them for the handler it wraps; see the
99
+ `withPolicyGate` entry under Security. Both are optional members.
100
+ - **`verifyApprovalQuorum` takes several request hashes.** Its `requestHash`
101
+ argument may be a list of hashes that identify the one suspended action; a
102
+ grant over any of them counts. A single string works as before.
103
+
104
+ - **Audit verification and delivery hooks, all optional.**
105
+ `AuditArtifactVerifier` gains `verifySignedCheckpoint` (a checkpoint without
106
+ its leaves), `verifyCurrentKeys` (over `AuditSignedArtifacts`), a
107
+ `maxClockSkewMs` option, and an optional
108
+ `AuditVerificationContext` argument on `verifyEntries`, `verifyCheckpoint`,
109
+ and `verifyObservation` that carries the checkpoints a policy's checkpoint
110
+ bounds name. `applyRequiredAuditProfile` applies a policy's
111
+ `requiredAuditProfile` to a report. `AUDIT_REASON_CODES` gains
112
+ `KEY_BOUNDARY_UNRESOLVED`, `KEY_NOT_CURRENT`, `MERKLE_PROOF_MISSING`,
113
+ `OBSERVATION_FUTURE_DATED`, and `REQUIRED_PROFILE_UNMET`. On the write path,
114
+ `AuditOutboxItemKey` and `auditOutboxItemKey` identify an outbox item by
115
+ source and event ID, `AuditOutboxProvider.capabilities.keyedBySource` opts an
116
+ adapter into receiving that key, `AuditTrailConfiguration` gains
117
+ `onAcknowledgementFailure`, `AuditSourceStateProvider` gains an optional
118
+ `abandonClaim`, and `MemoryAuditSourceState` takes a `redeliveryWindow`.
119
+ Every new provider member is optional, so existing adapters still implement
120
+ their interfaces.
121
+
122
+ ### Changed
123
+
124
+ - **SPEC.md: the `did:key` verification method id is `<did>#<multibase>`.**
125
+ §4.3, the §6.2 example and Appendix C.2 and C.3 gave `<did>#keys-1`, which
126
+ contradicts the W3C did:key method and which no standard resolver,
127
+ including this one, resolves. They, and `CONFORMANCE.md` L1.1, now give the
128
+ W3C form. No code changes.
129
+ - **`json-canonicalize` 3.0.1.** Entity Card proofs (the request hash and the
130
+ covered claims) and cheqd DLR content still canonicalize through
131
+ `json-canonicalize`. 3.x throws on `NaN` and `Infinity`, as RFC 8785
132
+ §3.2.2.3 requires, where 2.0.0 wrote `null`; every JSON value canonicalizes
133
+ to the same bytes as before. A received JSON-RPC request cannot carry those
134
+ values, so verifying calls is unaffected. Minting a card proof, or preparing
135
+ DLR content, with a non-finite number now fails instead of hashing `null`:
136
+ the rule `canonicalizeJson` already applies to response proofs and audit
137
+ records. The package also ships dual ESM/CJS builds.
138
+ - **Built with TypeScript 6.0.** The emitted JavaScript and declaration files
139
+ are byte-identical to the 5.9 build.
140
+ - **Declaration maps are no longer published.** The `.d.ts.map` files pointed
141
+ at `src/`, which the package does not include, so Go to Definition already
142
+ fell back to the `.d.ts`. Types are unchanged. JavaScript source maps stay:
143
+ under `node --enable-source-maps`, or an error tracker that applies source
144
+ maps, stack traces still name the `src/*.ts` file and line. The package drops
145
+ from 691 to 525 files and from 2.69 MB to 2.47 MB unpacked.
146
+
147
+ ### Security
148
+
149
+ - **Scope attenuation across scope representations.** `validateScopeAttenuation`
150
+ treated a parent credential that restricts scope only through
151
+ `constraints.crisp.scopes` matchers as unrestricted, because its flat scope
152
+ list was empty. A re-delegated child could then claim any flat scope (for
153
+ example `admin:root` under a parent limited to the `safe:` prefix), and the
154
+ chain validated. Both credentials are now read as one typed authority (flat
155
+ scopes as `exact` matchers, plus CRISP matchers), and every scope and matcher
156
+ the child grants must be proven inside the parent's authority by sound
157
+ containment rules; anything unprovable is rejected. Sound narrowings that
158
+ were rejected before are now accepted: a flat scope that a parent's matcher
159
+ grants, an `exact` matcher for a parent's flat scope, and a narrower `prefix`
160
+ or `path-prefix` under the parent's. A malformed scope entry proves nothing,
161
+ so it fails closed instead of throwing. A parent with no scopes of either
162
+ kind stays scope-unrestricted, as before (SPEC.md §6.3, §6.4).
163
+ - **`verifyProofDetached` replay and skew bypass.** The signature was checked
164
+ over the payload the caller supplied, while the timestamp and replay checks
165
+ read `proof.meta`, which that payload did not bind: an accepted proof with a
166
+ fresh `meta.nonce`, `ts` or hash verified again. The supplied payload must
167
+ now equal the payload rebuilt from `meta` byte for byte
168
+ (`INVALID_JWS_PAYLOAD`). A caller that passes the canonical payload, as the
169
+ method documents, sees no change.
170
+ - **`ProofGenerator.verifyProof` checks `meta` through the signature.** It
171
+ verified the JWS against its embedded payload and compared the hashes in the
172
+ unsigned `meta`, so a proof with rewritten `meta.requestHash` and
173
+ `meta.responseHash` verified for a different call, and one without
174
+ `meta.responseHash` accepted any response. It now verifies the signature
175
+ over the payload rebuilt from `meta`, requires a response exactly when the
176
+ proof binds one (the rule `ProofVerifier` already applied), and checks
177
+ `meta.did` and `meta.kid` against its identity. It still checks the artifact
178
+ only, with no freshness or replay state. Proofs it minted verify as before.
179
+ - **The embedded JWS payload must be the signed one.** Verification put the
180
+ payload rebuilt from `meta` in place of the JWS's own payload segment
181
+ without looking at that segment, so an intermediary could rewrite the
182
+ embedded `aud`, `responseHash` or `outcome` that JWT tooling and audit
183
+ stores read, and the proof still verified. `CryptoService.verifyJWS` with a
184
+ detached payload now also requires an embedded payload that differs from it
185
+ to verify under the same signature, which only the signed payload does
186
+ (SPEC.md §7.4: the `meta` block and the decoded payload reconcile exactly).
187
+ A JWS without a payload segment (`header..signature`) verifies as before,
188
+ and so does every proof this library mints.
189
+ - **`kid` must belong to `did`.** A proof signed with one DID's key could name
190
+ another DID as its signer (`iss`/`sub`) and verify against the key its `kid`
191
+ named. `ProofVerifier` now rejects a DID URL `kid` whose DID is not
192
+ `meta.did` (`KID_DID_MISMATCH`), as the Entity Card verifier already did
193
+ (SPEC-ENTITY-CARD.md §8). A relative `kid` is unaffected.
194
+ - **The `withKyaOs` transport no longer re-signs results a wrapper already
195
+ proved.** It ran `wrapWithProof` again over every non-error `tools/call`
196
+ result. A `needs_authorization` challenge from `wrapWithDelegation` (not an
197
+ error result) lost its signed `outcome: "needs_authorization"` proof to an
198
+ outcome-less one, which SPEC.md §7.2 reads as `allowed`, and the audit trail
199
+ gained a started and succeeded lifecycle for a call that never ran. A
200
+ delegated call lost its scope-bearing proof and was recorded twice. Once a
201
+ middleware is connected to the transport, its wrappers and outcome paths
202
+ stamp what they return with a random per-middleware token in a private
203
+ `_meta` member, and the transport passes a stamped result through untouched.
204
+ The stamp lives in `_meta` because the MCP SDK re-creates the result object
205
+ when it validates it. The transport removes it from every result before the
206
+ message is sent, so it never reaches the wire. A result without the stamp
207
+ is proved and audited as before, whatever proof, `proofError` or
208
+ `org.kya-os/audit` members it carries: those are removed first, so content
209
+ relayed from an upstream server cannot suppress this server's proof and
210
+ audit events or ship its own proof in their place. Other `_meta` members are
211
+ kept. A middleware used without the transport stamps nothing.
212
+ - **`withPolicyGate` composed inside `wrapWithDelegation` sees the verified
213
+ call.** The delegation gate strips every `_kyaos*` argument before its
214
+ handler runs. The policy gate then projected its principal from the already
215
+ stripped `_kyaos_delegation`, so engines saw `agentDid: "unknown"` and no
216
+ delegated scopes (a deny-list engine allowed everything), and
217
+ `_kyaos_approvals` never arrived, so no step-up could be satisfied. The
218
+ delegation gate now passes the authenticated principal and scopes (for a
219
+ durable grant, those of its re-verified credential) and the approvals in the
220
+ call context, and the policy gate prefers them. Approvals stay outside the
221
+ holder-binding request hash. A policy gate used on its own behaves as
222
+ before.
223
+ - **did:key and base58 input is bounded before decoding.** The did:key path
224
+ decoded the whole counterparty-supplied DID before checking it was a 34-byte
225
+ key, and `base58Decode` had no input limit and quadratic cost: one 100 KB
226
+ `did:key:z…` in a tool call held the event loop for seconds. A did:key whose
227
+ base58 part is longer than 64 characters (an Ed25519 key is always 47) is
228
+ now rejected unread, and its payload must be exactly the prefix and 32-byte
229
+ key. `publicKeyMultibase` and `publicKeyBase58` in DID documents are decoded
230
+ only up to 1024 characters, enough for any published public key.
231
+ `base58Decode` takes that bound as a new optional `maxLength` argument (the
232
+ package root exports 1024 as `MAX_BASE58_DECODE_LENGTH`), and a `maxLength`
233
+ that is not a non-negative integer throws a `RangeError`. Called without
234
+ it, `base58Decode` decodes any length, as before. Its byte conversion is now
235
+ linear; accumulating the digits stays quadratic, which the bound keeps
236
+ small. Every well-formed Ed25519 did:key and verification method resolves
237
+ as before.
238
+ - **`GenericOidcAdapter` accepts only a real token response.** Any 2xx JSON
239
+ body from the token endpoint was a successful authorization, including `{}`
240
+ and the HTTP 200 `{"error":"bad_verification_code"}` some providers return
241
+ for a bad or replayed code. The body must now be a JSON object with no
242
+ `error` member and a non-empty string `access_token` (RFC 6749 §5.1). A
243
+ non-Bearer `token_type` (some providers send `bot`) is accepted. The granted
244
+ scopes are read strictly: an absent `scope` means the requested scopes
245
+ (RFC 6749 §5.1), a string is split on whitespace, so `""` grants none, a
246
+ list of strings is taken as is, and any other `scope` fails the
247
+ authorization instead of granting the requested scopes.
248
+ - **`DefaultPolicyEngine` step-up counts distinct, allowed approvers.** One
249
+ approver listed twice in `humanApprovals` satisfied a quorum of two, and
250
+ `stepUpApprovers` was returned in the step-up challenge but not enforced.
251
+ Only distinct approvers, and only those on the allowlist when one is set,
252
+ now count toward `stepUpQuorum`. `verifyApprovalQuorum` reports the verified
253
+ approvers as `QuorumResult.approvers`, the set `humanApprovals` should be
254
+ built from. It always sets the field; the field is optional, so code that
255
+ builds its own `QuorumResult` still compiles. The `stepUpQuorum` value
256
+ itself is read as before, and distinct, allowed approvals decide as before.
257
+ - **Small-order Ed25519 public keys are rejected.** Under such a key one
258
+ signature verifies for every message, so anyone could sign as a did:key
259
+ built from it, and OpenSSL, WebCrypto and `jose` all accept it.
260
+ `NodeCryptoProvider` and `WebCryptoProvider` now refuse the small-order
261
+ encodings libsodium blocks, and so does every path that imports a key
262
+ itself: VC-JWT verification, Entity Card proofs and their HTTP message
263
+ signatures, and `CompactJwsAuditSignatureVerifier`. Those check the imported
264
+ key rather than the JWK, because Node's JWK import tolerates junk in `x`.
265
+ The audit verifier cannot read back a public key its resolver imported as
266
+ non-extractable, and verifies under such a key as before.
267
+ `NodeCryptoProvider` also decodes keys strictly, as `WebCryptoProvider`
268
+ already did: a 64-byte key or a key with trailing junk no longer verifies.
269
+ ASCII whitespace in a key is still ignored, as both decoders did, so a key
270
+ read from a file with its newline verifies as before, and so does a 32-byte
271
+ key in base64, unpadded base64, or base64url.
272
+ - **Strict canonicalization never honours `toJSON`.** `canonicalizeJson` and
273
+ `canonicalizeJsonBytes` validated their input and then serialized it with
274
+ `json-canonicalize`, which hands any object with a `toJSON` member to
275
+ `JSON.stringify`: `{"toJSON":"x", ...}` came out unsorted (not RFC 8785),
276
+ and a hidden `toJSON` function, or one on an array, replaced the value that
277
+ was hashed or signed. They now serialize the validated value themselves, in
278
+ one pass linear in the size of the input. Properties JSON does not carry
279
+ (non-enumerable ones, and an array's non-index ones such as a `toJSON`) are
280
+ ignored, as before, and never consulted, so `'abc'.match(/b/)` still
281
+ serializes as `["b"]`. An accessor array element is now refused, as an
282
+ accessor member already was, because the value checked could differ from
283
+ the value written. Output is byte-identical to `json-canonicalize` for plain
284
+ JSON (anything `JSON.parse` returns or an object literal builds), and the
285
+ conformance vectors are unchanged.
286
+
287
+ - **Graph revocation is checked for the whole chain.** `validateDelegationChain`
288
+ asked its `RevocationChecker` about the leaf only, so a leaf minted after an
289
+ ancestor's revocation, and therefore never registered in the graph, still
290
+ validated. Every credential in the verified chain is now checked, root
291
+ first, and a checker that throws fails the chain instead of throwing.
292
+
293
+ - **Revocation is recorded in the graph.** `revokeDelegation` only flipped a
294
+ status bit when `credentialStatusId` had the form `<list>#<digits>`, and
295
+ otherwise reported success while recording nothing, so a delegation whose
296
+ status id was a `urn:uuid:` read as live after revocation (SPEC.md §6.5 step
297
+ 1). `DelegationNode` gains an optional `revoked` flag, which revocation sets,
298
+ restore clears, and `isRevoked` honours alongside the status bit, and
299
+ `registerDelegation` accepts an optional structured `credentialStatus` so no
300
+ id has to be parsed. A status id that names no list entry still registers
301
+ and revokes without error, as before; it now also reads as revoked. Both
302
+ fields are optional, so existing storage providers keep working. One that
303
+ persists a fixed set of node fields must also store `revoked`: revocation
304
+ reads the node back, and revoking a delegation that has no status list
305
+ entry through a provider that dropped the mark now throws, naming that
306
+ requirement, instead of reporting success while recording nothing. With an
307
+ entry, the status bit still records it.
308
+
309
+ - **Registering a delegation id again cannot replace it.** `registerDelegation`
310
+ overwrote the stored node whenever an id was registered again, dropping its
311
+ `credentialStatusId`, revocation and children: re-registering a revoked
312
+ ancestor read its whole subtree as live again, and re-registering a node
313
+ under its own descendant left a parent cycle that `getChain` walked forever.
314
+ A repeat registration that matches the stored node in every registered field
315
+ (`parentId`, `issuerDid`, `subjectDid`, `credentialStatusId`,
316
+ `credentialStatus`) is now a no-op that returns the stored node, children
317
+ and revocation intact, so retries stay safe. One that differs in any of them
318
+ throws, as does a delegation naming itself as parent, on the non-atomic path
319
+ and in `MemoryDelegationGraphStorage.registerNodeAtomic`; the memory store's
320
+ chain walk throws on a cycle. A custom `AtomicDelegationGraphStorageProvider`
321
+ should apply the same rule, since only it can close the race between the
322
+ manager's check and its write.
323
+
324
+ - **First status list creation is serialized with updates.** A status list was
325
+ created on first allocation outside its update lock, so a concurrent
326
+ allocation could replace a list that had just recorded a revocation with a
327
+ fresh, empty one (SPEC.md §11.10). Creation now runs inside the list's lock
328
+ and re-reads the list there.
329
+
330
+ - **`did:web` host labels cannot smuggle in another URL.** The host label is
331
+ percent-decoded, and what it decoded to was used unchecked:
332
+ `did:web:trusted.example%40attacker.example` fetched its document from
333
+ `attacker.example`, and `%2F`, `%3F` and `%23` injected a path, query or
334
+ fragment. A host that decodes to `@`, `/`, `\`, `?`, `#`, whitespace, a
335
+ control character, or a `:` beyond one port separator (a bracketed IPv6
336
+ literal keeps its own colons) is now rejected, as is a path component that
337
+ decodes to a separator, a dot-segment or nothing (SPEC.md §4.4). A malformed
338
+ escape returns `null` instead of throwing. Ports, IPv4 and IPv6 literals and
339
+ percent-encoded internationalized hosts resolve as before.
340
+
341
+ - **Unreadable validity bounds fail closed.** An `expirationDate` that did not
342
+ parse (`2020-02-30T25:00:00Z`) and a non-numeric `constraints.notAfter` or
343
+ `notBefore` were read as no bound at all, so the credential never expired;
344
+ a `notAfter` of `0` was skipped the same way. A present bound that cannot be
345
+ read now places the credential outside its validity window. Basic checks
346
+ also accepted any delegation `status` other than `revoked` and `expired`
347
+ (`suspended`, or none), though the type allows only `active`, `revoked` and
348
+ `expired`; only `active` passes now.
349
+
350
+ - **VC-JWT verification no longer throws on hostile input.** A JOSE header or
351
+ claims set that is not a JSON object (`null`, an array), a `kid` that is not
352
+ a string, and a DID resolver that throws all escaped `verifyDelegationJwt`
353
+ as exceptions, so a caller outside a `try` recorded no rejection. Each now
354
+ returns a failed result.
355
+
356
+ - **CIMD documents can no longer speak for another origin's DID.**
357
+ `cardFromClientMetadata` accepted any declared `_meta["org.kya-os/did"]`,
358
+ and `verifyCimdBind` took the DID from the DID document rather than the card,
359
+ so a document at `https://attacker.example/clients/x` declaring
360
+ `did:web:victim.example:clients:acme` produced a victim-id card whose bind
361
+ check passed. `cardFromClientMetadata` now rejects a declared `did:web`
362
+ whose origin (host and port) differs from the `client_id`'s. Every
363
+ same-origin shape the CIMD draft allows still derives a card: a root with a
364
+ trailing slash, a query, an explicit `:443`, a root DID declared on a path
365
+ `client_id`, and a declared `did:key`. `verifyCimdBind(cimd, didDoc,
366
+ expectedDid?)` takes an optional third argument (pass the card's `id`) and
367
+ then also requires `didDoc.id` to be that DID and `client_id` to be its HTTPS
368
+ form, compared as normalized URLs. Two-argument calls behave exactly as
369
+ before, so they cannot detect a card/document mismatch.
370
+
371
+ - **`resolveCard` no longer conflates distinct `did:web` DIDs.** The identity
372
+ binding percent-decoded each segment and rejoined with `:`, so
373
+ `did:web:host:users:alice%3Aagent` accepted Alice's card
374
+ `did:web:host:users:alice:agent`, and `did:web:host:8443` accepted a card for
375
+ the port-form `did:web:host%3A8443`. DIDs are now compared in canonical
376
+ encoded form: host lowercased, each segment decoded and re-encoded, so two
377
+ spellings of one DID still match.
378
+
379
+ - **`MaxAmount` attenuation compares exact decimals.** Limits were truncated to
380
+ six fractional digits, so `100.0000009` passed as a narrowing of `100`, and a
381
+ child `0.0000009` under a parent `0.0000001` (both scaled to zero) passed
382
+ too. Both limits are now scaled to the longer fraction and compared exactly
383
+ (SPEC.md §6.10).
384
+
385
+ - **Audit checkpoints no longer sign a rewritten history.**
386
+ `AuditCheckpointBuilder.createCheckpoint` compared the journal with the latest
387
+ checkpoint only when both had the same tree size. A journal that had been
388
+ rewritten or restored and had since grown got a new signed checkpoint chained
389
+ to the old one, which it does not extend: a split view carrying the
390
+ recorder's own signature. The builder now checks that the journal still holds
391
+ the latest checkpoint's exact tree as its prefix and fails with
392
+ `AUDIT_CHECKPOINT_CONFLICT` otherwise.
393
+
394
+ - **Audit verification policies are enforced instead of ignored.** The
395
+ `validFromCheckpoint` / `validUntilCheckpoint` bounds (on recorder, observer,
396
+ and exporter keys and on trusted ledger epochs), `requiredAuditProfile`, and
397
+ `keyRevocationMode` were schema-valid but never read, so an entry signed after
398
+ its key's validity boundary verified, and a bundle without checkpoints passed
399
+ an AAP-4 policy with exit code 0. Checkpoint bounds now place each artifact by
400
+ tree position against checkpoints resolved by digest; a bound that cannot be
401
+ placed (a missing boundary, one in another epoch, or any bound on an exporter
402
+ key, since an export has no ledger position) makes the dimension
403
+ `indeterminate`, never `valid`. A required profile marks each dimension it
404
+ depends on `invalid` unless it is `valid`. Under `keyRevocationMode`
405
+ `current` or `both`, every signing key must also still be valid at
406
+ `verifiedAt`, reported in `currentAuthorization` (`AUDIT_KEY_NOT_CURRENT`);
407
+ `as_observed` is unchanged. Every policy that 1.16 accepted is still
408
+ accepted; none is rejected for the constraints it uses.
409
+
410
+ - **A predecessor epoch ends at the terminal checkpoint its successor
411
+ committed.** The bundle verifier only checked that the committed terminal
412
+ checkpoint was present, so a stale authority that kept checkpointing the old
413
+ epoch after rollover verified as valid. A predecessor checkpoint over a larger
414
+ tree than that terminal now reports `AUDIT_CHECKPOINT_FORK_DETECTED`. Entries
415
+ past the terminal alone are not a fork, since the terminal checkpoint's own
416
+ `checkpoint.created` event follows it.
417
+
418
+ - **The recorder fails closed when its journal moves backwards.** After a
419
+ failover to a lagging primary or a restore, `AuditRecorderService` appended on
420
+ the lower head and signed a second, different entry at an already receipted
421
+ sequence. A head read below this recorder's own commits is now raised to its
422
+ committed head for the compare-and-append, so a stale read replica still only
423
+ costs a retry, and a journal whose compare-and-append answer reports a head
424
+ below that committed head, or a different digest at a sequence it already
425
+ reported, fails with `AUDIT_JOURNAL_FAILURE` before anything is appended.
426
+
427
+ - **Hostile references can no longer keep an MCP audit event out of the
428
+ ledger.** `McpAuditEventAdapter` truncated references by UTF-16 code units and
429
+ passed context references through unbounded, so a presented credential ID
430
+ with a lone surrogate, a split surrogate pair, or more than 256 characters
431
+ made the event fail canonicalization or schema validation, even in
432
+ best-effort mode, and a rejected delegation went unrecorded. Every caller
433
+ reference, including `authorization.*` and correlation/causation IDs, is now
434
+ kept verbatim when well-formed and within bounds, and otherwise recorded as
435
+ the `sha256:` digest of its UTF-8 encoding. An over-long tool name or
436
+ reference that 1.16 truncated is recorded as that digest instead.
437
+ `wrapWithDelegation` still truncates a rejected credential's ID to 256 code
438
+ units before the adapter sees it, as in 1.16.
439
+
440
+ - **A failed append no longer disposes evidence a committed entry still uses.**
441
+ The recorder's cleanup after a failed append disposed every submitted
442
+ evidence object, including one that already existed and that an earlier
443
+ committed entry references (a session's shared actor object, for example).
444
+ Only objects that the failed submission newly stored are disposed now, and
445
+ never one that a concurrent submission to the same recorder held at the same
446
+ time, since that submission may have committed a reference to it.
447
+
448
+ - **A projection built from a forked history is never reported verified.**
449
+ `AuditProjectionWorker.reconcile` reported a lagging projection as `pending`
450
+ without checking its offset digest, and `synchronize` appended entries that do
451
+ not chain from that offset. Reconciliation now compares the offset with the
452
+ journal entry at that sequence (`gap_detected` on mismatch), and
453
+ synchronization fails with `AUDIT_PROJECTION_CONFLICT` instead of extending a
454
+ foreign prefix.
455
+
456
+ ### Fixed
457
+
458
+ - **A `requestHash` over the request as sent now verifies.** SPEC.md §7.3 and
459
+ Appendix C.1 describe `requestHash` over the `tools/call` request, while the
460
+ middleware hashes `{method: <tool name>, params: <arguments>}`, so a client
461
+ recomputing the hash from the request it sent always got
462
+ `CONTENT_BINDING_MISMATCH`, and a holder-of-key request proof minted that
463
+ way never bound at the PEP. Every verifier of a received request hash now
464
+ accepts either shape of the same call: `ProofVerifier` content binding,
465
+ `ProofGenerator.verifyProof`, the holder-binding check of
466
+ `wrapWithDelegation` and durable-grant resolution, and step-up approval
467
+ grants in `withPolicyGate`. The caller may hold the request in either shape
468
+ (`{method: "tools/call", params: {name, arguments}}` as sent, or the legacy
469
+ shape), and both hashes are derived from it; the §7.3 shape leaves out
470
+ `params._meta` and the `_kyaos*` control arguments. Producers are
471
+ unchanged: response and outcome proofs, the `requestHash` of a
472
+ `needs_approval` challenge, and `generateRequestProof` still emit the
473
+ legacy shape, so verifiers of earlier releases keep accepting them. Each
474
+ accepted hash covers the same tool name and business arguments, so no proof
475
+ over a different call is admitted. §7.3 now states the control-argument and
476
+ `_meta` exclusions, and Appendix C.1 gives covered-request vectors.
477
+ - **`fetchPublicKeyFromDID` resolves the `kid` proofs carry.** It prefixed `#`
478
+ to every `kid`, so a full DID URL (`did:key:z…#z…`, the form this library
479
+ mints) never matched. A DID URL `kid` must now name the DID being resolved
480
+ (`KID_DID_MISMATCH` otherwise) and match the verification method id; a bare
481
+ fragment is still resolved against the DID.
482
+ - **`MemoryResumeTokenStore` stays bounded.** A token is minted for every
483
+ unauthorized call, and was deleted only when that exact token was read after
484
+ it expired; fulfilled tokens were never deleted. `create()` now drops expired
485
+ tokens and `fulfill()` deletes the token. A challenge's `expiresAt` is now
486
+ the expiry the store enforces, read back from the store: it came from
487
+ `authorization.resumeTokenTtl`, so a configured hour was advertised for a
488
+ token the default store expires after 10 minutes. `resumeTokenTtl` is now
489
+ the fallback for a store that cannot report a future expiry in
490
+ milliseconds.
491
+ - **Expired sessions no longer switch off the single-session fallback.** The
492
+ fallback counted every stored session, live or expired, and nothing swept
493
+ them, so once a second session had existed proofs stopped for every
494
+ unthreaded call. A count above one now sweeps expired sessions first (at
495
+ most once a minute). Concurrent first calls under `autoSession` share one
496
+ auto-created session instead of racing into two.
497
+ - **Proofs keep handler `_meta` keys.** Attaching a proof, or a `proofError`
498
+ in the middleware or the transport, replaced `_meta` and dropped keys such
499
+ as `traceparent` and `io.modelcontextprotocol/related-task`. They are now
500
+ merged (SPEC.md §7.6). The proof, `proofError` and `org.kya-os/audit`
501
+ members are the exception: only the middleware sets them, so a handler's
502
+ copies are still dropped when a proof or proof error is attached, and a
503
+ relayed upstream result cannot place them next to this server's proof.
504
+ - **The transport matches proofs to responses only.** A server-initiated
505
+ request (for example `elicitation/create`) whose id equalled a pending
506
+ `tools/call` id consumed that call's entry, and the tool response shipped
507
+ unproven. Entries for cancelled calls are also dropped on
508
+ `notifications/cancelled`.
509
+ - **SPEC.md: nonce retention is bounded by the acceptance window.** §5.2, §5.5
510
+ and §11.2 required nonces to be kept for the session TTL plus a minute,
511
+ while §5.2 also recommended 60 seconds. A nonce presented after its
512
+ timestamp leaves the acceptance window is rejected on that timestamp, so the
513
+ longer retention bought memory and denial-of-service exposure and no
514
+ protection. §5.5 now requires retention until `ts + skew` plus a margin, for
515
+ the widest skew the verifier may apply, which is what the reference
516
+ implementation already does, and says why the bound holds on every
517
+ nonce-checked path. CONFORMANCE.md L2.5 follows, and L2.11 describes the
518
+ per-proof nonce and both request-hash shapes.
519
+ - **In-memory replay and pending-flow stores evict on their own.**
520
+ `MemoryNonceCacheProvider`, the default replay store for `withKyaOs` and
521
+ `SessionManager`, and `MemoryPendingFlowStore` freed expired entries only on
522
+ an explicit `cleanup()`, which nothing schedules, so every handshake nonce
523
+ and abandoned authorization flow stayed resident. Both now sweep expired
524
+ entries as they are written to: every 1000 writes, or after a minute. A live
525
+ entry is never swept, and `cleanup()` works as before.
526
+ - **`@kya-os/mcp/providers` bundles for browsers and Workers again.** The
527
+ entry documented for `WebCryptoProvider` also exports `NodeCryptoProvider`,
528
+ which imported `node:crypto` at module load and broke every browser bundle.
529
+ `node:crypto` now loads on first use; the exports are unchanged.
530
+ - **cheqd DLR content hashes are always computed.** `prepareCheqdDlrResource`
531
+ returned a caller-supplied `contentHash` as the artifact's content address
532
+ without checking it against the bytes being anchored. The hash is now
533
+ always computed from the canonical content bytes, and a supplied one that
534
+ differs throws. Canonicalization of the content is unchanged.
535
+
536
+ - **Status list indexes stay inside the list.** `updateStatus` parsed
537
+ `statusListIndex` with `parseInt`, so revoking `"5abc"` flipped bit 5, which
538
+ belongs to another credential, while `checkStatus` already parsed strictly.
539
+ Both now share the strict parser. `allocateStatusEntry` also handed out
540
+ indexes past the end of the list, which no read or revocation could reach;
541
+ it now throws once the list is full (SPEC.md §6.7).
542
+
543
+ - **A status list with an unreadable validity window is not fresh.** A
544
+ `validUntil` / `validFrom` (or `expirationDate` / `issuanceDate`) that was
545
+ present but not a parseable date was treated as absent, so the list read as
546
+ live. It now reads as not fresh (L3 → L2); the revocation bit is still read.
547
+
548
+ - **Card schemas match the published JSON Schemas.** `CapabilityAttestation`
549
+ stripped unknown members (the JSON Schema allows them), dropping sidecar
550
+ fields such as `credentialStatus` before the capability verifier saw them;
551
+ extra members are now preserved. `DelegationCredentialSchema.type` accepted
552
+ any string array; it now requires `VerifiableCredential` and
553
+ `DelegationCredential`, so another VC with a ZCAP-shaped subject is not read
554
+ as a delegation hop. `schemas/card-delegation-credential.json` enforces the
555
+ same two types it already documented.
556
+
557
+ - **`getInclusionProof` works for sequence 1.** The entry lookup started its
558
+ range read after sequence 1 for any sequence up to 1, so the first entry after
559
+ genesis could never be proven.
560
+
561
+ - **`listEntries` pages are bounded by the head they echo.** The head was read
562
+ after the page, so a concurrent append could return `nextAfterSequence: null`
563
+ with a head beyond the last entry, contrary to SPEC-AUDIT-READ §2.2. The head
564
+ is now read first and bounds the page.
565
+
566
+ - **Subset replay bundles verify.** A checkpoint was verified only against every
567
+ leaf of its tree, and included checkpoints had to link directly, so a
568
+ legitimate export of a sequence range or of non-adjacent checkpoints was
569
+ invalid. Without its complete prefix, a checkpoint is now verified by
570
+ signature, digest, trust, and declared range, and each covered entry needs a
571
+ verified inclusion proof (`AUDIT_MERKLE_PROOF_MISSING` otherwise).
572
+ Checkpoints that could have omitted ones between them may be bound by a
573
+ verified consistency proof instead of a direct `previousCheckpointDigest`
574
+ link, the rule independent observers already apply.
575
+
576
+ - **Concurrent checkpoints on one builder chain in order.** Two concurrent
577
+ `createCheckpoint` calls at different sizes could both chain to the same
578
+ predecessor. A builder now serializes its calls per ledger epoch. The
579
+ `AuditCheckpointStore` contract is unchanged.
580
+
581
+ - **A failed checkpoint lifecycle hook runs again.** When `onCheckpointCreated`
582
+ threw after the checkpoint was stored, a retry returned the stored checkpoint
583
+ without calling the hook, losing the lifecycle event. The builder's next
584
+ `createCheckpoint` call now runs the hook again for every checkpoint whose
585
+ hook failed, oldest first and before any newer checkpoint's, even when the
586
+ ledger has grown in between; the hook should be idempotent on the checkpoint
587
+ digest. A hook that completed is not repeated.
588
+
589
+ - **A future-dated observation is not fresh.** With a freshness requirement,
590
+ an observation dated after `verifiedAt` passed. One dated beyond the clock
591
+ skew allowance (`maxClockSkewMs`, default 120 s) is now `invalid` with
592
+ `AUDIT_OBSERVATION_FUTURE_DATED`.
593
+
594
+ - **Redelivering a stable event ID returns the original receipt.**
595
+ `MemoryAuditSourceState` dropped the claims of receipted events, so an
596
+ at-least-once redelivery after later events got a new source sequence and was
597
+ rejected as `AUDIT_EVENT_ID_CONFLICT`. Receipted claims are now retained for a
598
+ bounded `redeliveryWindow` (default 1024 per source). Different content under
599
+ a retained event ID is still an `AuditProtocolError` with
600
+ `AUDIT_EVENT_ID_CONFLICT`, now raised by the source state; it was a plain
601
+ `Error` there before.
602
+
603
+ - **Rejected input no longer consumes a source sequence.** The trail claimed a
604
+ source sequence before validating the event, so schema-invalid input, a lone
605
+ surrogate, or an unreferenced evidence object left a permanent gap and a
606
+ broken `previousSourceEventDigest` link. Validation now runs first, and a
607
+ claim whose event cannot be emitted is released through the optional
608
+ `abandonClaim`.
609
+
610
+ - **Source state no longer leaks behind an open gap.** One unreceipted sequence
611
+ stopped `MemoryAuditSourceState` from pruning anything after it. It now keeps
612
+ only pending events plus the redelivery window.
613
+
614
+ - **A replica that loses the cold-start genesis race recovers.** When every read
615
+ was stale, the losing genesis surfaced as an idempotency conflict and failed
616
+ with `AUDIT_EVENT_ID_CONFLICT`; it is now validated against the epoch
617
+ configuration like any raced genesis.
618
+
619
+ - **A committed outbox item is never reported as a delivery failure.** If
620
+ `markDelivered` threw after the recorder committed, `flush()` called
621
+ `markFailed` and `onDeliveryFailure`. The item now counts as delivered, the
622
+ error goes to the new `onAcknowledgementFailure` callback, and redelivery
623
+ resolves to the same receipt.
624
+
625
+ - **Outbox items are identified by source and event ID.** Event IDs are unique
626
+ only within a source, but `MemoryAuditOutbox` keyed items by event ID alone,
627
+ so one source could acknowledge or displace another's pending item.
628
+ `markDelivered` and `markFailed` now accept an `AuditOutboxItemKey` as well as
629
+ a bare event ID, and the trail passes the key to an outbox that declares
630
+ `capabilities.keyedBySource`, as `MemoryAuditOutbox` now does. An adapter
631
+ that implements `markDelivered(eventId: string)` still type-checks and still
632
+ receives the bare event ID, and so does a `MemoryAuditOutbox` subclass that
633
+ overrides `markDelivered` or `markFailed`: the memory outbox declares the
634
+ capability only for its own implementations, unless the subclass declares it
635
+ again. `MemoryAuditOutbox` throws on a bare event ID that more than one source
636
+ has pending instead of guessing.
637
+
638
+ - **Default audit event IDs are random.** `audit_<time>_<counter>` was unique
639
+ only per trail instance, so two trails sharing an outbox collided. Defaults
640
+ are now `audit_<uuid>`; `eventIdFactory` still overrides them.
641
+
642
+ ### Deprecated
643
+
644
+ - **The legacy request-hash shape.** `requestHash` over
645
+ `{method: <tool name>, params: <arguments>}` is deprecated in favour of the
646
+ SPEC.md §7.3 covered `tools/call` request. Producers switch to the §7.3
647
+ shape in 2.0.0; verifiers accept both until then.
648
+ - `ProofVerifier.verifyProofDetached`. The payload it takes must now equal the
649
+ payload rebuilt from `proof.meta`, so it adds nothing over `verifyProof`.
650
+
10
651
  ## [1.16.2] - 2026-09-21
11
652
 
12
653
  ### Changed