@emilia-protocol/gate 0.10.0 → 0.13.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 (419) hide show
  1. package/CHANGELOG.md +91 -0
  2. package/README.md +272 -0
  3. package/action-control-manifest.js +3 -268
  4. package/action-escrow-custodian.js +4 -0
  5. package/action-escrow-evidence.js +4 -0
  6. package/action-escrow-package.js +4 -0
  7. package/action-escrow-postgres.js +4 -0
  8. package/action-escrow-state.js +4 -0
  9. package/action-escrow-verifiers.js +4 -0
  10. package/action-escrow.js +4 -0
  11. package/action-packs.js +3 -140
  12. package/adapters/_kit.js +3 -104
  13. package/adapters/aws.js +3 -108
  14. package/adapters/cloudflare.js +3 -54
  15. package/adapters/gcp.js +3 -70
  16. package/adapters/github.js +3 -109
  17. package/adapters/jira.js +3 -55
  18. package/adapters/k8s.js +3 -70
  19. package/adapters/linear.js +3 -55
  20. package/adapters/salesforce.js +3 -55
  21. package/adapters/stripe.js +3 -81
  22. package/adapters/supabase.js +3 -121
  23. package/adapters/terraform.js +3 -59
  24. package/adapters/vercel.js +3 -84
  25. package/aec-execution.js +3 -312
  26. package/breakglass.js +3 -582
  27. package/capability-receipt.js +4 -0
  28. package/cf1-conformance.js +3 -106
  29. package/challenge-store.js +3 -69
  30. package/control-plane.js +3 -340
  31. package/coverage.js +3 -721
  32. package/demo.mjs +1 -1
  33. package/deployment-attestation.js +3 -247
  34. package/dist/action-control-manifest.d.ts +82 -0
  35. package/dist/action-control-manifest.d.ts.map +1 -0
  36. package/dist/action-control-manifest.js +422 -0
  37. package/dist/action-control-manifest.js.map +1 -0
  38. package/dist/action-escrow-custodian.d.ts +74 -0
  39. package/dist/action-escrow-custodian.d.ts.map +1 -0
  40. package/dist/action-escrow-custodian.js +363 -0
  41. package/dist/action-escrow-custodian.js.map +1 -0
  42. package/dist/action-escrow-evidence.d.ts +130 -0
  43. package/dist/action-escrow-evidence.d.ts.map +1 -0
  44. package/dist/action-escrow-evidence.js +1012 -0
  45. package/dist/action-escrow-evidence.js.map +1 -0
  46. package/dist/action-escrow-package.d.ts +10 -0
  47. package/dist/action-escrow-package.d.ts.map +1 -0
  48. package/dist/action-escrow-package.js +1583 -0
  49. package/dist/action-escrow-package.js.map +1 -0
  50. package/dist/action-escrow-postgres.d.ts +62 -0
  51. package/dist/action-escrow-postgres.d.ts.map +1 -0
  52. package/dist/action-escrow-postgres.js +339 -0
  53. package/dist/action-escrow-postgres.js.map +1 -0
  54. package/dist/action-escrow-state.d.ts +141 -0
  55. package/dist/action-escrow-state.d.ts.map +1 -0
  56. package/dist/action-escrow-state.js +413 -0
  57. package/dist/action-escrow-state.js.map +1 -0
  58. package/dist/action-escrow-verifiers.d.ts +65 -0
  59. package/dist/action-escrow-verifiers.d.ts.map +1 -0
  60. package/dist/action-escrow-verifiers.js +421 -0
  61. package/dist/action-escrow-verifiers.js.map +1 -0
  62. package/dist/action-escrow.d.ts +112 -0
  63. package/dist/action-escrow.d.ts.map +1 -0
  64. package/dist/action-escrow.js +2661 -0
  65. package/dist/action-escrow.js.map +1 -0
  66. package/dist/action-packs.d.ts +54 -0
  67. package/dist/action-packs.d.ts.map +1 -0
  68. package/dist/action-packs.js +143 -0
  69. package/dist/action-packs.js.map +1 -0
  70. package/dist/adapters/_kit.d.ts +50 -0
  71. package/dist/adapters/_kit.d.ts.map +1 -0
  72. package/dist/adapters/_kit.js +98 -0
  73. package/dist/adapters/_kit.js.map +1 -0
  74. package/dist/adapters/aws.d.ts +158 -0
  75. package/dist/adapters/aws.d.ts.map +1 -0
  76. package/dist/adapters/aws.js +136 -0
  77. package/dist/adapters/aws.js.map +1 -0
  78. package/dist/adapters/cloudflare.d.ts +116 -0
  79. package/dist/adapters/cloudflare.d.ts.map +1 -0
  80. package/dist/adapters/cloudflare.js +75 -0
  81. package/dist/adapters/cloudflare.js.map +1 -0
  82. package/dist/adapters/gcp.d.ts +139 -0
  83. package/dist/adapters/gcp.d.ts.map +1 -0
  84. package/dist/adapters/gcp.js +69 -0
  85. package/dist/adapters/gcp.js.map +1 -0
  86. package/dist/adapters/github.d.ts +123 -0
  87. package/dist/adapters/github.d.ts.map +1 -0
  88. package/dist/adapters/github.js +105 -0
  89. package/dist/adapters/github.js.map +1 -0
  90. package/dist/adapters/jira.d.ts +109 -0
  91. package/dist/adapters/jira.d.ts.map +1 -0
  92. package/dist/adapters/jira.js +54 -0
  93. package/dist/adapters/jira.js.map +1 -0
  94. package/dist/adapters/k8s.d.ts +139 -0
  95. package/dist/adapters/k8s.d.ts.map +1 -0
  96. package/dist/adapters/k8s.js +69 -0
  97. package/dist/adapters/k8s.js.map +1 -0
  98. package/dist/adapters/linear.d.ts +109 -0
  99. package/dist/adapters/linear.d.ts.map +1 -0
  100. package/dist/adapters/linear.js +54 -0
  101. package/dist/adapters/linear.js.map +1 -0
  102. package/dist/adapters/salesforce.d.ts +109 -0
  103. package/dist/adapters/salesforce.d.ts.map +1 -0
  104. package/dist/adapters/salesforce.js +54 -0
  105. package/dist/adapters/salesforce.js.map +1 -0
  106. package/dist/adapters/stripe.d.ts +116 -0
  107. package/dist/adapters/stripe.d.ts.map +1 -0
  108. package/dist/adapters/stripe.js +77 -0
  109. package/dist/adapters/stripe.js.map +1 -0
  110. package/dist/adapters/supabase.d.ts +127 -0
  111. package/dist/adapters/supabase.d.ts.map +1 -0
  112. package/dist/adapters/supabase.js +112 -0
  113. package/dist/adapters/supabase.js.map +1 -0
  114. package/dist/adapters/terraform.d.ts +109 -0
  115. package/dist/adapters/terraform.d.ts.map +1 -0
  116. package/dist/adapters/terraform.js +58 -0
  117. package/dist/adapters/terraform.js.map +1 -0
  118. package/dist/adapters/vercel.d.ts +114 -0
  119. package/dist/adapters/vercel.d.ts.map +1 -0
  120. package/dist/adapters/vercel.js +81 -0
  121. package/dist/adapters/vercel.js.map +1 -0
  122. package/dist/aec-execution.d.ts +107 -0
  123. package/dist/aec-execution.d.ts.map +1 -0
  124. package/dist/aec-execution.js +334 -0
  125. package/dist/aec-execution.js.map +1 -0
  126. package/dist/breakglass.d.ts +205 -0
  127. package/dist/breakglass.d.ts.map +1 -0
  128. package/dist/breakglass.js +627 -0
  129. package/dist/breakglass.js.map +1 -0
  130. package/dist/capability-receipt.d.ts +601 -0
  131. package/dist/capability-receipt.d.ts.map +1 -0
  132. package/dist/capability-receipt.js +1177 -0
  133. package/dist/capability-receipt.js.map +1 -0
  134. package/dist/cf1-conformance.d.ts +83 -0
  135. package/dist/cf1-conformance.d.ts.map +1 -0
  136. package/dist/cf1-conformance.js +94 -0
  137. package/dist/cf1-conformance.js.map +1 -0
  138. package/dist/challenge-store.d.ts +20 -0
  139. package/dist/challenge-store.d.ts.map +1 -0
  140. package/dist/challenge-store.js +62 -0
  141. package/dist/challenge-store.js.map +1 -0
  142. package/dist/control-plane.d.ts +136 -0
  143. package/dist/control-plane.d.ts.map +1 -0
  144. package/dist/control-plane.js +349 -0
  145. package/dist/control-plane.js.map +1 -0
  146. package/dist/coverage.d.ts +156 -0
  147. package/dist/coverage.d.ts.map +1 -0
  148. package/dist/coverage.js +768 -0
  149. package/dist/coverage.js.map +1 -0
  150. package/dist/deployment-attestation.d.ts +93 -0
  151. package/dist/deployment-attestation.d.ts.map +1 -0
  152. package/dist/deployment-attestation.js +262 -0
  153. package/dist/deployment-attestation.js.map +1 -0
  154. package/dist/eg1-conformance.d.ts +286 -0
  155. package/dist/eg1-conformance.d.ts.map +1 -0
  156. package/dist/eg1-conformance.js +379 -0
  157. package/dist/eg1-conformance.js.map +1 -0
  158. package/dist/enterprise.d.ts +88 -0
  159. package/dist/enterprise.d.ts.map +1 -0
  160. package/dist/enterprise.js +194 -0
  161. package/dist/enterprise.js.map +1 -0
  162. package/dist/evidence-postgres.d.ts +123 -0
  163. package/dist/evidence-postgres.d.ts.map +1 -0
  164. package/dist/evidence-postgres.js +343 -0
  165. package/dist/evidence-postgres.js.map +1 -0
  166. package/dist/evidence.d.ts +113 -0
  167. package/dist/evidence.d.ts.map +1 -0
  168. package/dist/evidence.js +369 -0
  169. package/dist/evidence.js.map +1 -0
  170. package/dist/execution-binding.d.ts +49 -0
  171. package/dist/execution-binding.d.ts.map +1 -0
  172. package/dist/execution-binding.js +243 -0
  173. package/dist/execution-binding.js.map +1 -0
  174. package/dist/formal-runtime-map.d.ts +42 -0
  175. package/dist/formal-runtime-map.d.ts.map +1 -0
  176. package/dist/formal-runtime-map.js +23 -0
  177. package/dist/formal-runtime-map.js.map +1 -0
  178. package/dist/index.d.ts +1002 -0
  179. package/dist/index.d.ts.map +1 -0
  180. package/dist/index.js +1736 -0
  181. package/dist/index.js.map +1 -0
  182. package/dist/key-registry.d.ts +60 -0
  183. package/dist/key-registry.d.ts.map +1 -0
  184. package/dist/key-registry.js +144 -0
  185. package/dist/key-registry.js.map +1 -0
  186. package/dist/mcp.d.ts +53 -0
  187. package/dist/mcp.d.ts.map +1 -0
  188. package/dist/mcp.js +112 -0
  189. package/dist/mcp.js.map +1 -0
  190. package/dist/metering.d.ts +80 -0
  191. package/dist/metering.d.ts.map +1 -0
  192. package/dist/metering.js +227 -0
  193. package/dist/metering.js.map +1 -0
  194. package/dist/metrics.d.ts +68 -0
  195. package/dist/metrics.d.ts.map +1 -0
  196. package/dist/metrics.js +242 -0
  197. package/dist/metrics.js.map +1 -0
  198. package/dist/network-witness.d.ts +167 -0
  199. package/dist/network-witness.d.ts.map +1 -0
  200. package/dist/network-witness.js +520 -0
  201. package/dist/network-witness.js.map +1 -0
  202. package/dist/protocol-state.d.ts +141 -0
  203. package/dist/protocol-state.d.ts.map +1 -0
  204. package/dist/protocol-state.js +106 -0
  205. package/dist/protocol-state.js.map +1 -0
  206. package/dist/receipt-program.d.ts +59 -0
  207. package/dist/receipt-program.d.ts.map +1 -0
  208. package/dist/receipt-program.js +1053 -0
  209. package/dist/receipt-program.js.map +1 -0
  210. package/dist/reliance-kernel.d.ts +66 -0
  211. package/dist/reliance-kernel.d.ts.map +1 -0
  212. package/dist/reliance-kernel.js +103 -0
  213. package/dist/reliance-kernel.js.map +1 -0
  214. package/dist/reliance-packet.d.ts +67 -0
  215. package/dist/reliance-packet.d.ts.map +1 -0
  216. package/dist/reliance-packet.js +176 -0
  217. package/dist/reliance-packet.js.map +1 -0
  218. package/dist/remedy-program-postgres.d.ts +37 -0
  219. package/dist/remedy-program-postgres.d.ts.map +1 -0
  220. package/dist/remedy-program-postgres.js +291 -0
  221. package/dist/remedy-program-postgres.js.map +1 -0
  222. package/dist/remedy-program-receipt.d.ts +97 -0
  223. package/dist/remedy-program-receipt.d.ts.map +1 -0
  224. package/dist/remedy-program-receipt.js +817 -0
  225. package/dist/remedy-program-receipt.js.map +1 -0
  226. package/dist/remedy-program.d.ts +76 -0
  227. package/dist/remedy-program.d.ts.map +1 -0
  228. package/dist/remedy-program.js +1346 -0
  229. package/dist/remedy-program.js.map +1 -0
  230. package/dist/reports/art14.d.ts +101 -0
  231. package/dist/reports/art14.d.ts.map +1 -0
  232. package/dist/reports/art14.js +340 -0
  233. package/dist/reports/art14.js.map +1 -0
  234. package/dist/reports/assurance-package.d.ts +197 -0
  235. package/dist/reports/assurance-package.d.ts.map +1 -0
  236. package/dist/reports/assurance-package.js +313 -0
  237. package/dist/reports/assurance-package.js.map +1 -0
  238. package/dist/reports/auditor-workpaper.d.ts +194 -0
  239. package/dist/reports/auditor-workpaper.d.ts.map +1 -0
  240. package/dist/reports/auditor-workpaper.js +545 -0
  241. package/dist/reports/auditor-workpaper.js.map +1 -0
  242. package/dist/reports/external-verification.d.ts +76 -0
  243. package/dist/reports/external-verification.d.ts.map +1 -0
  244. package/dist/reports/external-verification.js +209 -0
  245. package/dist/reports/external-verification.js.map +1 -0
  246. package/dist/reports/reperform.d.ts +122 -0
  247. package/dist/reports/reperform.d.ts.map +1 -0
  248. package/dist/reports/reperform.js +432 -0
  249. package/dist/reports/reperform.js.map +1 -0
  250. package/dist/reports/underwriter.d.ts +127 -0
  251. package/dist/reports/underwriter.d.ts.map +1 -0
  252. package/dist/reports/underwriter.js +348 -0
  253. package/dist/reports/underwriter.js.map +1 -0
  254. package/dist/retention.d.ts +88 -0
  255. package/dist/retention.d.ts.map +1 -0
  256. package/dist/retention.js +90 -0
  257. package/dist/retention.js.map +1 -0
  258. package/dist/roster.d.ts +113 -0
  259. package/dist/roster.d.ts.map +1 -0
  260. package/dist/roster.js +261 -0
  261. package/dist/roster.js.map +1 -0
  262. package/dist/runtime-monitor.d.ts +132 -0
  263. package/dist/runtime-monitor.d.ts.map +1 -0
  264. package/dist/runtime-monitor.js +197 -0
  265. package/dist/runtime-monitor.js.map +1 -0
  266. package/dist/settlement.d.ts +68 -0
  267. package/dist/settlement.d.ts.map +1 -0
  268. package/dist/settlement.js +306 -0
  269. package/dist/settlement.js.map +1 -0
  270. package/dist/siem.d.ts +261 -0
  271. package/dist/siem.d.ts.map +1 -0
  272. package/dist/siem.js +247 -0
  273. package/dist/siem.js.map +1 -0
  274. package/dist/store-postgres.d.ts +107 -0
  275. package/dist/store-postgres.d.ts.map +1 -0
  276. package/dist/store-postgres.js +152 -0
  277. package/dist/store-postgres.js.map +1 -0
  278. package/dist/store.d.ts +95 -0
  279. package/dist/store.d.ts.map +1 -0
  280. package/dist/store.js +202 -0
  281. package/dist/store.js.map +1 -0
  282. package/dist/strict-json.d.ts +14 -0
  283. package/dist/strict-json.d.ts.map +1 -0
  284. package/dist/strict-json.js +132 -0
  285. package/dist/strict-json.js.map +1 -0
  286. package/dist/trust-program-adapters.d.ts +122 -0
  287. package/dist/trust-program-adapters.d.ts.map +1 -0
  288. package/dist/trust-program-adapters.js +802 -0
  289. package/dist/trust-program-adapters.js.map +1 -0
  290. package/dist/trust-program-postgres.d.ts +41 -0
  291. package/dist/trust-program-postgres.d.ts.map +1 -0
  292. package/dist/trust-program-postgres.js +346 -0
  293. package/dist/trust-program-postgres.js.map +1 -0
  294. package/dist/trust-program-revocation.d.ts +206 -0
  295. package/dist/trust-program-revocation.d.ts.map +1 -0
  296. package/dist/trust-program-revocation.js +600 -0
  297. package/dist/trust-program-revocation.js.map +1 -0
  298. package/dist/trust-program.d.ts +197 -0
  299. package/dist/trust-program.d.ts.map +1 -0
  300. package/dist/trust-program.js +1351 -0
  301. package/dist/trust-program.js.map +1 -0
  302. package/dist/witness-postgres.d.ts +43 -0
  303. package/dist/witness-postgres.d.ts.map +1 -0
  304. package/dist/witness-postgres.js +92 -0
  305. package/dist/witness-postgres.js.map +1 -0
  306. package/dist/zk-range-proof.d.ts +78 -0
  307. package/dist/zk-range-proof.d.ts.map +1 -0
  308. package/dist/zk-range-proof.js +228 -0
  309. package/dist/zk-range-proof.js.map +1 -0
  310. package/eg1-conformance.js +3 -404
  311. package/enterprise.js +3 -180
  312. package/ep-assure.mjs +1 -0
  313. package/evidence-postgres.js +3 -356
  314. package/evidence.js +4 -360
  315. package/execution-binding.js +3 -212
  316. package/formal-runtime-map.js +4 -0
  317. package/index.js +4 -1249
  318. package/key-registry.js +3 -134
  319. package/mcp.js +3 -109
  320. package/metering.js +3 -226
  321. package/metrics.js +3 -231
  322. package/network-witness.js +3 -499
  323. package/package.json +47 -4
  324. package/receipt-program.js +4 -0
  325. package/reliance-kernel.js +3 -112
  326. package/reliance-packet.js +3 -175
  327. package/remedy-program-postgres.js +4 -0
  328. package/remedy-program-receipt.js +4 -0
  329. package/remedy-program.js +4 -0
  330. package/reports/art14.js +0 -0
  331. package/reports/assurance-package.js +2 -312
  332. package/reports/auditor-workpaper.js +3 -537
  333. package/reports/external-verification.js +3 -222
  334. package/reports/reperform.js +3 -424
  335. package/reports/underwriter.js +3 -339
  336. package/retention.js +3 -84
  337. package/roster.js +3 -264
  338. package/runtime-monitor.js +4 -0
  339. package/settlement.js +3 -299
  340. package/siem.js +3 -235
  341. package/src/action-control-manifest.ts +424 -0
  342. package/src/action-escrow-custodian.ts +427 -0
  343. package/src/action-escrow-evidence.ts +1178 -0
  344. package/src/action-escrow-package.ts +1821 -0
  345. package/src/action-escrow-postgres.ts +366 -0
  346. package/src/action-escrow-state.ts +498 -0
  347. package/src/action-escrow-verifiers.ts +484 -0
  348. package/src/action-escrow.ts +3039 -0
  349. package/src/action-packs.ts +170 -0
  350. package/src/adapters/_kit.ts +117 -0
  351. package/src/adapters/aws.ts +142 -0
  352. package/src/adapters/cloudflare.ts +78 -0
  353. package/src/adapters/gcp.ts +71 -0
  354. package/src/adapters/github.ts +110 -0
  355. package/src/adapters/jira.ts +56 -0
  356. package/src/adapters/k8s.ts +71 -0
  357. package/src/adapters/linear.ts +56 -0
  358. package/src/adapters/salesforce.ts +56 -0
  359. package/src/adapters/stripe.ts +82 -0
  360. package/src/adapters/supabase.ts +122 -0
  361. package/src/adapters/terraform.ts +60 -0
  362. package/src/adapters/vercel.ts +85 -0
  363. package/src/aec-execution.ts +354 -0
  364. package/src/breakglass.ts +647 -0
  365. package/src/capability-receipt.ts +1258 -0
  366. package/src/cf1-conformance.ts +120 -0
  367. package/src/challenge-store.ts +70 -0
  368. package/src/control-plane.ts +374 -0
  369. package/src/coverage.ts +832 -0
  370. package/src/deployment-attestation.ts +259 -0
  371. package/src/eg1-conformance.ts +471 -0
  372. package/src/enterprise.ts +195 -0
  373. package/src/evidence-postgres.ts +374 -0
  374. package/src/evidence.ts +367 -0
  375. package/src/execution-binding.ts +236 -0
  376. package/src/formal-runtime-map.ts +24 -0
  377. package/src/index.ts +2122 -0
  378. package/src/key-registry.ts +150 -0
  379. package/src/mcp.ts +120 -0
  380. package/src/metering.ts +237 -0
  381. package/src/metrics.ts +232 -0
  382. package/src/network-witness.ts +585 -0
  383. package/src/protocol-state.ts +143 -0
  384. package/src/protocol-state.typecheck.ts +94 -0
  385. package/src/receipt-program.ts +1105 -0
  386. package/src/reliance-kernel.ts +119 -0
  387. package/src/reliance-packet.ts +206 -0
  388. package/src/remedy-program-postgres.ts +367 -0
  389. package/src/remedy-program-receipt.ts +891 -0
  390. package/src/remedy-program.ts +1388 -0
  391. package/src/reports/art14.ts +361 -0
  392. package/src/reports/assurance-package.ts +330 -0
  393. package/src/reports/auditor-workpaper.ts +558 -0
  394. package/src/reports/external-verification.ts +232 -0
  395. package/src/reports/reperform.ts +441 -0
  396. package/src/reports/underwriter.ts +356 -0
  397. package/src/retention.ts +100 -0
  398. package/src/roster.ts +273 -0
  399. package/src/runtime-monitor.ts +217 -0
  400. package/src/settlement.ts +313 -0
  401. package/src/siem.ts +247 -0
  402. package/src/store-postgres.ts +167 -0
  403. package/src/store.ts +214 -0
  404. package/src/strict-json.ts +115 -0
  405. package/src/trust-program-adapters.ts +847 -0
  406. package/src/trust-program-postgres.ts +429 -0
  407. package/src/trust-program-revocation.ts +751 -0
  408. package/src/trust-program.ts +1460 -0
  409. package/src/witness-postgres.ts +106 -0
  410. package/src/zk-range-proof.ts +250 -0
  411. package/store-postgres.js +3 -161
  412. package/store.js +4 -198
  413. package/strict-json.js +3 -85
  414. package/trust-program-adapters.js +4 -0
  415. package/trust-program-postgres.js +4 -0
  416. package/trust-program-revocation.js +4 -0
  417. package/trust-program.js +4 -0
  418. package/witness-postgres.js +3 -96
  419. package/zk-range-proof.js +4 -0
@@ -0,0 +1,802 @@
1
+ // @ts-nocheck
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ /**
4
+ * Constructor-pinned adapters for the Gate Trust Program profile.
5
+ *
6
+ * These adapters do not create another policy engine. They provide the narrow
7
+ * joins needed to consume existing Quorum, AEC, Receipt Program, and Action
8
+ * Escrow verification results without allowing a presenter to choose verifier
9
+ * functions, trust roots, policies, mappings, or expected values at runtime.
10
+ */
11
+ import crypto from 'node:crypto';
12
+ // The compatibility entry point resolves to dist both from src during native
13
+ // TypeScript tests and from the compiled dist module.
14
+ // @ts-ignore -- declarations live behind the compatibility entry point.
15
+ import { canonicalize } from '../execution-binding.js';
16
+ const DIGEST = /^sha256:[0-9a-f]{64}$/;
17
+ const BASE64URL = /^[A-Za-z0-9_-]+$/;
18
+ const TRUST_BINDING_KEYS = new Set([
19
+ 'instance_id',
20
+ 'program_digest',
21
+ 'program_version',
22
+ 'root_caid',
23
+ 'action_digest',
24
+ 'stage_id',
25
+ 'requirement_id',
26
+ 'policy_digest',
27
+ 'predecessor_receipt_digests',
28
+ ]);
29
+ const ARTIFACT_KEYS = new Set(['evidence_id', 'binding', 'evidence']);
30
+ const QUORUM_EVIDENCE_KEYS = new Set(['members']);
31
+ const QUORUM_MEMBER_KEYS = new Set(['role', 'signoff']);
32
+ const RECEIPT_EVIDENCE_KEYS = new Set(['certificate']);
33
+ const ACTION_ESCROW_EVIDENCE_KEYS = new Set([
34
+ 'package', 'document_bytes', 'project_record_bytes',
35
+ ]);
36
+ const ACTION_ESCROW_COMPONENT_VERIFIERS = Object.freeze([
37
+ 'verifyBinding',
38
+ 'verifyProjectRecord',
39
+ 'verifyProfile',
40
+ 'verifyDocumentExecution',
41
+ 'verifyAgreementAcceptance',
42
+ 'verifyReleaseApproval',
43
+ 'verifyFunding',
44
+ 'verifyMilestone',
45
+ 'verifyRelease',
46
+ 'verifyAmendment',
47
+ 'verifyState',
48
+ ]);
49
+ const FORBIDDEN_RUNTIME_TRUST_KEYS = new Set([
50
+ 'approverKeys',
51
+ 'componentVerifiers',
52
+ 'expectedAction',
53
+ 'expectedActionDigest',
54
+ 'expectedAgreementId',
55
+ 'expectedContext',
56
+ 'expectedProgramDigest',
57
+ 'keys',
58
+ 'keysByType',
59
+ 'mappings',
60
+ 'policies',
61
+ 'policiesByType',
62
+ 'resolveCaid',
63
+ 'trustedCertificateKeys',
64
+ 'trustedConfiguration',
65
+ 'trustedKeys',
66
+ 'trustRoots',
67
+ 'verificationOptions',
68
+ 'verifierFunctions',
69
+ 'verifiers',
70
+ ]);
71
+ const VERIFY_PACKAGE = '@emilia-protocol/verify';
72
+ const AEC_PACKAGE = '@emilia-protocol/verify/evidence-chain';
73
+ const LOCAL_VERIFY_PACKAGE = '../../verify/index.js';
74
+ const LOCAL_AEC_PACKAGE = '../../verify/evidence-chain.js';
75
+ const RECEIPT_PROGRAM_MODULE = '../receipt-program.js';
76
+ const ACTION_ESCROW_EVIDENCE_MODULE = '../action-escrow-evidence.js';
77
+ async function verifyQuorumDefault(quorum, options) {
78
+ try {
79
+ const verifier = await import(VERIFY_PACKAGE);
80
+ return verifier.verifyQuorum(quorum, options);
81
+ }
82
+ catch (error) {
83
+ if (error?.code !== 'ERR_MODULE_NOT_FOUND')
84
+ throw error;
85
+ const verifier = await import(LOCAL_VERIFY_PACKAGE);
86
+ return verifier.verifyQuorum(quorum, options);
87
+ }
88
+ }
89
+ async function verifyAuthorizationChainDefault(chain, options) {
90
+ try {
91
+ const verifier = await import(AEC_PACKAGE);
92
+ return verifier.verifyAuthorizationChain(chain, options);
93
+ }
94
+ catch (error) {
95
+ if (error?.code !== 'ERR_MODULE_NOT_FOUND')
96
+ throw error;
97
+ const verifier = await import(LOCAL_AEC_PACKAGE);
98
+ return verifier.verifyAuthorizationChain(chain, options);
99
+ }
100
+ }
101
+ async function verifyReceiptProgramCertificateDefault(certificate, options) {
102
+ const verifier = await import(RECEIPT_PROGRAM_MODULE);
103
+ return verifier.verifyReceiptProgramCertificate(certificate, options);
104
+ }
105
+ async function verifyActionEscrowEvidencePackageDefault(pkg, options) {
106
+ const verifier = await import(ACTION_ESCROW_EVIDENCE_MODULE);
107
+ return verifier.verifyActionEscrowEvidencePackage(pkg, options);
108
+ }
109
+ function refusal(reason) {
110
+ return Object.freeze({ valid: false, reason });
111
+ }
112
+ function terminalRefusal(reason) {
113
+ return Object.freeze({
114
+ valid: false,
115
+ reason,
116
+ outcome: null,
117
+ evidence_digest: null,
118
+ });
119
+ }
120
+ function isRecord(value) {
121
+ if (value === null || typeof value !== 'object' || Array.isArray(value))
122
+ return false;
123
+ const prototype = Object.getPrototypeOf(value);
124
+ return prototype === Object.prototype || prototype === null;
125
+ }
126
+ /** Only enumerable data properties are accepted from a presenter. */
127
+ function isDataRecord(value) {
128
+ if (!isRecord(value))
129
+ return false;
130
+ return Reflect.ownKeys(value).every((key) => {
131
+ if (typeof key !== 'string')
132
+ return false;
133
+ const descriptor = Object.getOwnPropertyDescriptor(value, key);
134
+ return descriptor?.enumerable === true && Object.hasOwn(descriptor, 'value');
135
+ });
136
+ }
137
+ function exactKeys(value, allowed, required = allowed) {
138
+ return isDataRecord(value)
139
+ && Object.keys(value).every((key) => allowed.has(key))
140
+ && [...required].every((key) => Object.hasOwn(value, key));
141
+ }
142
+ function canonicalCopy(value) {
143
+ return JSON.parse(canonicalize(value));
144
+ }
145
+ function canonicalDigest(value) {
146
+ return `sha256:${crypto.createHash('sha256')
147
+ .update(Buffer.from(canonicalize(value), 'utf8')).digest('hex')}`;
148
+ }
149
+ function deepFreeze(value) {
150
+ if (!value || typeof value !== 'object' || Object.isFrozen(value))
151
+ return value;
152
+ Object.freeze(value);
153
+ for (const child of Object.values(value))
154
+ deepFreeze(child);
155
+ return value;
156
+ }
157
+ /**
158
+ * Snapshot constructor-owned configuration while preserving injected verifier
159
+ * function identity. Host objects such as KeyObject are immutable references;
160
+ * canonical data and byte arrays are copied.
161
+ */
162
+ function snapshotPinned(value, seen = new WeakMap()) {
163
+ if (value === null || typeof value !== 'object')
164
+ return value;
165
+ if (value instanceof Uint8Array)
166
+ return Uint8Array.from(value);
167
+ if (value instanceof ArrayBuffer)
168
+ return value.slice(0);
169
+ if (value instanceof Date)
170
+ return new Date(value.getTime());
171
+ if (value instanceof crypto.KeyObject)
172
+ return value;
173
+ if (seen.has(value))
174
+ return seen.get(value);
175
+ if (Array.isArray(value)) {
176
+ const result = [];
177
+ seen.set(value, result);
178
+ for (const entry of value)
179
+ result.push(snapshotPinned(entry, seen));
180
+ return Object.freeze(result);
181
+ }
182
+ if (!isDataRecord(value)) {
183
+ throw new TypeError('pinned adapter configuration must use data properties');
184
+ }
185
+ const result = {};
186
+ seen.set(value, result);
187
+ for (const [key, entry] of Object.entries(value))
188
+ result[key] = snapshotPinned(entry, seen);
189
+ return Object.freeze(result);
190
+ }
191
+ function canonicalInstant(value) {
192
+ if (typeof value !== 'string'
193
+ || !/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{1,9})?(?:Z|[+-]\d{2}:\d{2})$/.test(value)) {
194
+ return null;
195
+ }
196
+ const parsed = Date.parse(value);
197
+ return Number.isFinite(parsed) ? new Date(parsed).toISOString() : null;
198
+ }
199
+ function normalizedStrings(value) {
200
+ if (!Array.isArray(value) || value.length === 0 || value.length > 256)
201
+ return null;
202
+ const normalized = [];
203
+ for (const entry of value) {
204
+ if (typeof entry !== 'string' || entry.length === 0 || entry.length > 512
205
+ || /[\u0000-\u001f\u007f]/.test(entry))
206
+ return null;
207
+ normalized.push(entry);
208
+ }
209
+ return [...new Set(normalized)].sort();
210
+ }
211
+ function normalizedFingerprints(value) {
212
+ if (!Array.isArray(value) || value.length === 0 || value.length > 256
213
+ || value.some((entry) => typeof entry !== 'string' || !DIGEST.test(entry)))
214
+ return null;
215
+ return [...new Set(value)].sort();
216
+ }
217
+ function containsRuntimeTrustConfiguration(value) {
218
+ const stack = [value];
219
+ const seen = new WeakSet();
220
+ while (stack.length) {
221
+ const current = stack.pop();
222
+ if (!current || typeof current !== 'object')
223
+ continue;
224
+ if (seen.has(current))
225
+ return true;
226
+ seen.add(current);
227
+ if (Array.isArray(current)) {
228
+ stack.push(...current);
229
+ continue;
230
+ }
231
+ if (!isDataRecord(current))
232
+ return true;
233
+ for (const [key, entry] of Object.entries(current)) {
234
+ if (FORBIDDEN_RUNTIME_TRUST_KEYS.has(key))
235
+ return true;
236
+ if (entry && typeof entry === 'object')
237
+ stack.push(entry);
238
+ }
239
+ }
240
+ return false;
241
+ }
242
+ function normalizeVerifiedClaims(result) {
243
+ const subjects = normalizedStrings(result.subjects);
244
+ const keyFingerprints = normalizedFingerprints(result.key_fingerprints);
245
+ const issuedAt = canonicalInstant(result.issued_at);
246
+ const expiresAt = canonicalInstant(result.expires_at);
247
+ const revocationCheckedAt = result.revocation_checked_at === null
248
+ || result.revocation_checked_at === undefined
249
+ ? null : canonicalInstant(result.revocation_checked_at);
250
+ if (!subjects || !keyFingerprints)
251
+ return refusal('evidence_principal_set_invalid');
252
+ if (!issuedAt || !expiresAt || Date.parse(expiresAt) <= Date.parse(issuedAt)) {
253
+ return refusal('evidence_time_invalid');
254
+ }
255
+ if (result.revocation_checked_at !== null && result.revocation_checked_at !== undefined
256
+ && revocationCheckedAt === null)
257
+ return refusal('evidence_revocation_time_invalid');
258
+ return Object.freeze({
259
+ valid: true,
260
+ reason: null,
261
+ binding_digest: result.binding_digest,
262
+ policy_digest: result.policy_digest,
263
+ subjects,
264
+ key_fingerprints: keyFingerprints,
265
+ issued_at: issuedAt,
266
+ expires_at: expiresAt,
267
+ revocation_checked_at: revocationCheckedAt,
268
+ });
269
+ }
270
+ function exactTrustBinding(value, requirement, program) {
271
+ if (!exactKeys(value, TRUST_BINDING_KEYS)
272
+ || typeof value.instance_id !== 'string' || value.instance_id.length === 0
273
+ || typeof value.stage_id !== 'string' || value.stage_id.length === 0
274
+ || value.requirement_id !== requirement.requirement_id
275
+ || value.policy_digest !== requirement.policy_digest
276
+ || value.program_version !== program.version
277
+ || value.root_caid !== program.root_caid
278
+ || value.action_digest !== program.action_digest
279
+ || !DIGEST.test(value.program_digest)
280
+ || !Array.isArray(value.predecessor_receipt_digests)
281
+ || value.predecessor_receipt_digests.some((entry) => typeof entry !== 'string' || !DIGEST.test(entry))
282
+ || new Set(value.predecessor_receipt_digests).size
283
+ !== value.predecessor_receipt_digests.length
284
+ || value.predecessor_receipt_digests.some((entry, index) => index > 0
285
+ && entry < value.predecessor_receipt_digests[index - 1]))
286
+ return null;
287
+ let digest;
288
+ try {
289
+ if (value.program_digest !== canonicalDigest(program))
290
+ return null;
291
+ digest = canonicalDigest(value);
292
+ }
293
+ catch {
294
+ return null;
295
+ }
296
+ return { binding: deepFreeze(canonicalCopy(value)), digest };
297
+ }
298
+ function resolvePinnedInstant(value) {
299
+ return typeof value === 'function' ? value() : value;
300
+ }
301
+ /**
302
+ * Wrap any evidence verifier in the Trust Program stage-verifier contract.
303
+ * Runtime artifacts have a closed three-field envelope, so trust configuration
304
+ * cannot ride beside the evidence and influence verification.
305
+ */
306
+ export function createPinnedEvidenceAdapter({ policyDigest, verify, trustedConfiguration = {}, metadata, }) {
307
+ if (!DIGEST.test(policyDigest) || typeof verify !== 'function'
308
+ || (metadata !== undefined && typeof metadata !== 'function')) {
309
+ throw new TypeError('pinned evidence adapter configuration invalid');
310
+ }
311
+ const pinnedConfiguration = snapshotPinned(trustedConfiguration);
312
+ return async function pinnedEvidenceAdapter({ artifact, requirement, program }) {
313
+ if (!exactKeys(artifact, ARTIFACT_KEYS))
314
+ return refusal('artifact_schema_invalid');
315
+ if (!isDataRecord(requirement) || !isDataRecord(program))
316
+ return refusal('verification_context_invalid');
317
+ if (requirement.policy_digest !== policyDigest)
318
+ return refusal('requirement_policy_mismatch');
319
+ const expected = exactTrustBinding(artifact.binding, requirement, program);
320
+ if (!expected)
321
+ return refusal('trust_binding_invalid');
322
+ let evidence;
323
+ try {
324
+ evidence = deepFreeze(canonicalCopy(artifact.evidence));
325
+ }
326
+ catch {
327
+ return refusal('evidence_not_canonical');
328
+ }
329
+ if (containsRuntimeTrustConfiguration(evidence)) {
330
+ return refusal('artifact_trust_configuration_forbidden');
331
+ }
332
+ const context = Object.freeze({
333
+ trustedConfiguration: pinnedConfiguration,
334
+ expectedBinding: expected.binding,
335
+ expectedBindingDigest: expected.digest,
336
+ expectedPolicyDigest: policyDigest,
337
+ requirement: deepFreeze(canonicalCopy(requirement)),
338
+ program: deepFreeze(canonicalCopy(program)),
339
+ });
340
+ let verified;
341
+ try {
342
+ verified = await verify(evidence, context);
343
+ }
344
+ catch {
345
+ return refusal('evidence_verification_failed');
346
+ }
347
+ if (!isDataRecord(verified) || verified.valid !== true) {
348
+ return refusal(typeof verified?.reason === 'string'
349
+ ? verified.reason : 'evidence_verification_failed');
350
+ }
351
+ let claims = verified;
352
+ if (metadata) {
353
+ try {
354
+ const resolved = await metadata(verified, Object.freeze({ ...context, evidence }));
355
+ if (!isDataRecord(resolved))
356
+ return refusal('evidence_metadata_invalid');
357
+ claims = { ...verified, ...resolved };
358
+ }
359
+ catch {
360
+ return refusal('evidence_metadata_invalid');
361
+ }
362
+ }
363
+ if (claims.binding_digest !== expected.digest)
364
+ return refusal('evidence_binding_mismatch');
365
+ if (claims.policy_digest !== policyDigest)
366
+ return refusal('evidence_policy_mismatch');
367
+ return normalizeVerifiedClaims(claims);
368
+ };
369
+ }
370
+ /** Canonical SHA-256 fingerprint of an SPKI public key. */
371
+ export function canonicalKeyFingerprint(value) {
372
+ try {
373
+ let key;
374
+ if (value instanceof crypto.KeyObject) {
375
+ key = value.type === 'public' ? value : crypto.createPublicKey(value);
376
+ }
377
+ else {
378
+ if (typeof value !== 'string' || !BASE64URL.test(value))
379
+ return null;
380
+ const bytes = Buffer.from(value, 'base64url');
381
+ if (bytes.toString('base64url') !== value)
382
+ return null;
383
+ key = crypto.createPublicKey({ key: bytes, type: 'spki', format: 'der' });
384
+ }
385
+ const spki = key.export({ type: 'spki', format: 'der' });
386
+ return `sha256:${crypto.createHash('sha256').update(spki).digest('hex')}`;
387
+ }
388
+ catch {
389
+ return null;
390
+ }
391
+ }
392
+ function publicKeyValue(value) {
393
+ try {
394
+ if (typeof value === 'string')
395
+ return canonicalKeyFingerprint(value) ? value : null;
396
+ if (!(value instanceof crypto.KeyObject))
397
+ return null;
398
+ const key = value.type === 'public' ? value : crypto.createPublicKey(value);
399
+ return key.export({ type: 'spki', format: 'der' }).toString('base64url');
400
+ }
401
+ catch {
402
+ return null;
403
+ }
404
+ }
405
+ function validQuorumPolicy(policy) {
406
+ if (!isDataRecord(policy)
407
+ || !['threshold', 'ordered'].includes(policy.mode)
408
+ || !Number.isSafeInteger(policy.required) || policy.required < 1
409
+ || !Array.isArray(policy.approvers) || policy.approvers.length === 0
410
+ || policy.required > policy.approvers.length)
411
+ return false;
412
+ const slots = new Set();
413
+ for (const slot of policy.approvers) {
414
+ if (!isDataRecord(slot) || typeof slot.role !== 'string' || slot.role.length === 0
415
+ || typeof slot.approver !== 'string' || slot.approver.length === 0)
416
+ return false;
417
+ const key = `${slot.role}\u0000${slot.approver}`;
418
+ if (slots.has(key))
419
+ return false;
420
+ slots.add(key);
421
+ }
422
+ return true;
423
+ }
424
+ /** Compose Trust Program with the repository's Quorum verifier. */
425
+ export function createQuorumTrustProgramAdapter(options) {
426
+ const policy = snapshotPinned(options.policy);
427
+ const approverKeys = snapshotPinned(options.approverKeys);
428
+ const verificationOptions = snapshotPinned(options.verificationOptions ?? {});
429
+ const verifyQuorum = options.verifyQuorum ?? verifyQuorumDefault;
430
+ const policyValid = validQuorumPolicy(policy);
431
+ const pinnedKeysValid = policyValid && policy.approvers.every((slot) => publicKeyValue(approverKeys[slot.approver]) !== null);
432
+ return createPinnedEvidenceAdapter({
433
+ policyDigest: options.policyDigest,
434
+ verify: async (evidence, context) => {
435
+ if (!policyValid || !pinnedKeysValid)
436
+ return refusal('quorum_policy_invalid');
437
+ if (!exactKeys(evidence, QUORUM_EVIDENCE_KEYS)
438
+ || !Array.isArray(evidence.members) || evidence.members.length === 0
439
+ || evidence.members.length > policy.approvers.length) {
440
+ return refusal('quorum_evidence_schema_invalid');
441
+ }
442
+ const members = [];
443
+ for (const member of evidence.members) {
444
+ if (!exactKeys(member, QUORUM_MEMBER_KEYS)
445
+ || typeof member.role !== 'string' || !isDataRecord(member.signoff)
446
+ || !isDataRecord(member.signoff.context)
447
+ || typeof member.signoff.context.approver !== 'string') {
448
+ return refusal('quorum_evidence_schema_invalid');
449
+ }
450
+ const approver = member.signoff.context.approver;
451
+ const admitted = policy.approvers.some((slot) => slot.role === member.role && slot.approver === approver);
452
+ const publicKey = publicKeyValue(approverKeys[approver]);
453
+ if (!admitted || !publicKey)
454
+ return refusal('quorum_member_not_pinned');
455
+ members.push({
456
+ role: member.role,
457
+ approver_public_key: publicKey,
458
+ signoff: member.signoff,
459
+ });
460
+ }
461
+ let result;
462
+ try {
463
+ result = await verifyQuorum({
464
+ '@type': 'ep.quorum',
465
+ action_hash: context.expectedBindingDigest,
466
+ policy,
467
+ members,
468
+ }, verificationOptions);
469
+ }
470
+ catch {
471
+ return refusal('quorum_verification_failed');
472
+ }
473
+ if (!isDataRecord(result) || result.valid !== true)
474
+ return refusal('quorum_verification_failed');
475
+ const issued = members.map((member) => canonicalInstant(member.signoff.context.issued_at));
476
+ const expires = members.map((member) => canonicalInstant(member.signoff.context.expires_at));
477
+ if (issued.some((entry) => entry === null) || expires.some((entry) => entry === null)) {
478
+ return refusal('evidence_time_invalid');
479
+ }
480
+ const subjects = members.map((member) => member.signoff.context.approver);
481
+ const fingerprints = members.map((member) => canonicalKeyFingerprint(member.approver_public_key));
482
+ if (fingerprints.some((entry) => entry === null))
483
+ return refusal('evidence_principal_set_invalid');
484
+ return {
485
+ valid: true,
486
+ binding_digest: context.expectedBindingDigest,
487
+ policy_digest: options.policyDigest,
488
+ subjects,
489
+ key_fingerprints: fingerprints,
490
+ issued_at: issued.sort()[0],
491
+ expires_at: expires.sort()[0],
492
+ revocation_checked_at: resolvePinnedInstant(options.revocationCheckedAt),
493
+ };
494
+ },
495
+ });
496
+ }
497
+ /** Compose Trust Program with AEC under RP-owned policy, action, and trust roots. */
498
+ export function createAecTrustProgramAdapter(options) {
499
+ if (typeof options.requirement !== 'string' || !options.requirement.trim()) {
500
+ throw new TypeError('AEC relying-party requirement required');
501
+ }
502
+ const keysByType = snapshotPinned(options.keysByType);
503
+ const policiesByType = snapshotPinned(options.policiesByType);
504
+ const verifiers = snapshotPinned(options.verifiers ?? {});
505
+ const verifyAuthorizationChain = options.verifyAuthorizationChain
506
+ ?? verifyAuthorizationChainDefault;
507
+ return createPinnedEvidenceAdapter({
508
+ policyDigest: options.policyDigest,
509
+ metadata: options.metadata,
510
+ verify: async (chain, context) => {
511
+ let result;
512
+ try {
513
+ result = await verifyAuthorizationChain(chain, {
514
+ keysByType,
515
+ policiesByType,
516
+ verifiers,
517
+ requirement: options.requirement,
518
+ expectedAction: context.expectedBinding,
519
+ expectedActionDigest: context.expectedBindingDigest,
520
+ verificationTime: resolvePinnedInstant(options.verificationTime),
521
+ });
522
+ }
523
+ catch {
524
+ return refusal('aec_verification_failed');
525
+ }
526
+ const actionDigest = typeof result?.action_digest === 'string'
527
+ ? result.action_digest.replace(/^sha256:/, '') : null;
528
+ if (!isDataRecord(result) || result.satisfied !== true
529
+ || result.expected_action_bound !== true
530
+ || actionDigest !== context.expectedBindingDigest.slice('sha256:'.length)) {
531
+ return refusal('aec_verification_failed');
532
+ }
533
+ return {
534
+ ...result,
535
+ valid: true,
536
+ binding_digest: context.expectedBindingDigest,
537
+ policy_digest: options.policyDigest,
538
+ };
539
+ },
540
+ });
541
+ }
542
+ function receiptProgramOwnership(binding) {
543
+ return isDataRecord(binding)
544
+ && binding.consequence_mode === 'receipt-program'
545
+ && typeof binding.capability_template_digest === 'string'
546
+ && DIGEST.test(binding.capability_template_digest)
547
+ && binding.escrow_profile_digest === null;
548
+ }
549
+ function actionEscrowOwnership(binding, profileDigest) {
550
+ return isDataRecord(binding)
551
+ && binding.consequence_mode === 'action-escrow'
552
+ && binding.capability_template_digest === null
553
+ && binding.escrow_profile_digest === profileDigest
554
+ && DIGEST.test(binding.escrow_profile_digest);
555
+ }
556
+ /** Explicitly detect and refuse Action Escrow nested under Receipt Program. */
557
+ export function containsActionEscrowConsequence(value) {
558
+ const stack = [value];
559
+ const seen = new WeakSet();
560
+ while (stack.length) {
561
+ const current = stack.pop();
562
+ if (!current || typeof current !== 'object')
563
+ continue;
564
+ if (seen.has(current))
565
+ return true;
566
+ seen.add(current);
567
+ if (Array.isArray(current)) {
568
+ stack.push(...current);
569
+ continue;
570
+ }
571
+ if (!isDataRecord(current))
572
+ return true;
573
+ for (const [key, entry] of Object.entries(current)) {
574
+ if (key.startsWith('action_escrow')
575
+ || (key === 'consequence_mode' && entry === 'action-escrow')
576
+ || (typeof entry === 'string'
577
+ && (entry.startsWith('EP-ACTION-ESCROW-')
578
+ || entry.toLowerCase().includes('action-escrow'))))
579
+ return true;
580
+ if (entry && typeof entry === 'object')
581
+ stack.push(entry);
582
+ }
583
+ }
584
+ return false;
585
+ }
586
+ function withOptions(fn, options) {
587
+ Object.defineProperty(fn, 'options', {
588
+ configurable: false,
589
+ enumerable: false,
590
+ writable: false,
591
+ value: options,
592
+ });
593
+ return Object.freeze(fn);
594
+ }
595
+ /** Verify and normalize one Receipt Program terminal certificate. */
596
+ export function createReceiptProgramTerminalOutcomeVerifier(options) {
597
+ if (typeof options.programId !== 'string' || options.programId.length === 0
598
+ || (options.programDigest !== undefined && !DIGEST.test(options.programDigest))
599
+ || typeof options.resolveCaid !== 'function') {
600
+ throw new TypeError('Receipt Program adapter configuration invalid');
601
+ }
602
+ const pinned = snapshotPinned({
603
+ programId: options.programId,
604
+ programDigest: options.programDigest,
605
+ trustedCertificateKeys: options.trustedCertificateKeys,
606
+ expectedContext: options.expectedContext,
607
+ resolveCaid: options.resolveCaid,
608
+ });
609
+ const verifyCertificate = options.verifyReceiptProgramCertificate
610
+ ?? verifyReceiptProgramCertificateDefault;
611
+ const verifier = async ({ evidence, authorizationBinding }) => {
612
+ if (!receiptProgramOwnership(authorizationBinding)) {
613
+ return terminalRefusal('consequence_ownership_invalid');
614
+ }
615
+ if (!exactKeys(evidence, RECEIPT_EVIDENCE_KEYS)) {
616
+ return terminalRefusal('receipt_program_evidence_schema_invalid');
617
+ }
618
+ let certificate;
619
+ try {
620
+ certificate = deepFreeze(canonicalCopy(evidence.certificate));
621
+ }
622
+ catch {
623
+ return terminalRefusal('receipt_program_evidence_invalid');
624
+ }
625
+ if (containsActionEscrowConsequence(certificate?.program)) {
626
+ return terminalRefusal('action_escrow_receipt_program_nesting_refused');
627
+ }
628
+ let result;
629
+ try {
630
+ result = await verifyCertificate(certificate, {
631
+ trustedCertificateKeys: pinned.trustedCertificateKeys,
632
+ expectedContext: pinned.expectedContext,
633
+ resolveCaid: pinned.resolveCaid,
634
+ });
635
+ }
636
+ catch {
637
+ return terminalRefusal('receipt_program_verification_failed');
638
+ }
639
+ const certificateProgram = certificate.program;
640
+ if (!isDataRecord(result) || result.ok !== true
641
+ || !isDataRecord(certificateProgram)
642
+ || !['executed', 'refused', 'indeterminate'].includes(result.outcome)
643
+ || certificate.outcome !== result.outcome
644
+ || certificateProgram.program_id !== pinned.programId
645
+ || certificateProgram.operation_id !== authorizationBinding.operation_id
646
+ || certificateProgram.action_digest !== authorizationBinding.action_digest
647
+ || certificateProgram.caid !== authorizationBinding.root_caid
648
+ || (pinned.programDigest !== undefined && result.program_digest !== pinned.programDigest)) {
649
+ return terminalRefusal('receipt_program_binding_mismatch');
650
+ }
651
+ return Object.freeze({
652
+ valid: true,
653
+ reason: null,
654
+ outcome: result.outcome,
655
+ evidence_digest: canonicalDigest(certificate),
656
+ });
657
+ };
658
+ return withOptions(verifier, pinned);
659
+ }
660
+ /** Trust Program executionOutcomeVerifier wrapper for Receipt Program. */
661
+ export function createReceiptProgramExecutionOutcomeVerifier(options) {
662
+ const terminal = createReceiptProgramTerminalOutcomeVerifier(options);
663
+ return async function receiptProgramExecutionOutcomeVerifier(input) {
664
+ const result = await terminal(input);
665
+ return result.valid === true
666
+ && result.outcome === input.outcome
667
+ && result.evidence_digest === input.evidenceDigest;
668
+ };
669
+ }
670
+ function actionEscrowOutcome(stage) {
671
+ if (stage === 'released' || stage === 'completed')
672
+ return 'executed';
673
+ if (stage === 'cancelled')
674
+ return 'refused';
675
+ if (stage === 'release_indeterminate')
676
+ return 'indeterminate';
677
+ return null;
678
+ }
679
+ /** Verify and normalize one Action Escrow authenticated terminal package. */
680
+ export function createActionEscrowTerminalOutcomeVerifier(options) {
681
+ if (typeof options.agreementId !== 'string' || options.agreementId.length === 0
682
+ || typeof options.operationId !== 'string' || options.operationId.length === 0
683
+ || options.operationId.length > 512 || /[\u0000-\u001f\u007f]/.test(options.operationId)
684
+ || !DIGEST.test(options.releaseActionDigest) || !DIGEST.test(options.profileDigest)
685
+ || !isDataRecord(options.componentVerifiers)) {
686
+ throw new TypeError('Action Escrow adapter configuration invalid');
687
+ }
688
+ const componentVerifiers = snapshotPinned(options.componentVerifiers);
689
+ const pinned = snapshotPinned({
690
+ agreementId: options.agreementId,
691
+ operationId: options.operationId,
692
+ releaseActionDigest: options.releaseActionDigest,
693
+ profileDigest: options.profileDigest,
694
+ componentVerifiers,
695
+ now: options.now,
696
+ maxDocumentBytes: options.maxDocumentBytes,
697
+ maxProjectRecordBytes: options.maxProjectRecordBytes,
698
+ });
699
+ const verifyPackage = options.verifyActionEscrowEvidencePackage
700
+ ?? verifyActionEscrowEvidencePackageDefault;
701
+ const verifier = async ({ evidence, authorizationBinding }) => {
702
+ if (!actionEscrowOwnership(authorizationBinding, pinned.profileDigest)) {
703
+ return terminalRefusal('consequence_ownership_invalid');
704
+ }
705
+ if (authorizationBinding.operation_id !== pinned.operationId) {
706
+ return terminalRefusal('action_escrow_binding_mismatch');
707
+ }
708
+ if (!exactKeys(evidence, ACTION_ESCROW_EVIDENCE_KEYS, new Set(['package', 'document_bytes'])))
709
+ return terminalRefusal('action_escrow_evidence_schema_invalid');
710
+ let pkg;
711
+ try {
712
+ pkg = deepFreeze(canonicalCopy(evidence.package));
713
+ }
714
+ catch {
715
+ return terminalRefusal('action_escrow_evidence_invalid');
716
+ }
717
+ const outcome = actionEscrowOutcome(pkg.stage);
718
+ if (!outcome)
719
+ return terminalRefusal('action_escrow_state_not_terminal');
720
+ if (pkg.agreement_id !== pinned.agreementId || pkg.package_digest === undefined
721
+ || !DIGEST.test(pkg.package_digest)) {
722
+ return terminalRefusal('action_escrow_binding_mismatch');
723
+ }
724
+ if (outcome !== 'refused'
725
+ && (!isDataRecord(pkg.release)
726
+ || pkg.release.operation_idempotency_key !== pinned.operationId)) {
727
+ return terminalRefusal('action_escrow_binding_mismatch');
728
+ }
729
+ if (!(evidence.document_bytes instanceof Uint8Array)
730
+ || (evidence.project_record_bytes !== undefined
731
+ && !(evidence.project_record_bytes instanceof Uint8Array))) {
732
+ return terminalRefusal('action_escrow_evidence_invalid');
733
+ }
734
+ const verificationOptions = {
735
+ documentBytes: Uint8Array.from(evidence.document_bytes),
736
+ expectedAgreementId: pinned.agreementId,
737
+ };
738
+ if (evidence.project_record_bytes !== undefined) {
739
+ verificationOptions.projectRecordBytes = Uint8Array.from(evidence.project_record_bytes);
740
+ }
741
+ for (const name of ACTION_ESCROW_COMPONENT_VERIFIERS) {
742
+ const candidate = componentVerifiers[name];
743
+ if (candidate !== undefined) {
744
+ if (typeof candidate !== 'function')
745
+ return terminalRefusal('action_escrow_verifier_invalid');
746
+ verificationOptions[name] = candidate;
747
+ }
748
+ }
749
+ if (pinned.now !== undefined)
750
+ verificationOptions.now = resolvePinnedInstant(pinned.now);
751
+ if (pinned.maxDocumentBytes !== undefined) {
752
+ verificationOptions.maxDocumentBytes = pinned.maxDocumentBytes;
753
+ }
754
+ if (pinned.maxProjectRecordBytes !== undefined) {
755
+ verificationOptions.maxProjectRecordBytes = pinned.maxProjectRecordBytes;
756
+ }
757
+ let result;
758
+ try {
759
+ result = await verifyPackage(pkg, verificationOptions);
760
+ }
761
+ catch {
762
+ return terminalRefusal('action_escrow_verification_failed');
763
+ }
764
+ if (!isDataRecord(result) || result.valid !== true
765
+ || result.package_digest !== pkg.package_digest
766
+ || result.agreement_id !== pinned.agreementId
767
+ || result.action_digest !== pinned.releaseActionDigest
768
+ || result.profile_digest !== pinned.profileDigest
769
+ || authorizationBinding.action_digest !== pinned.releaseActionDigest) {
770
+ return terminalRefusal('action_escrow_binding_mismatch');
771
+ }
772
+ return Object.freeze({
773
+ valid: true,
774
+ reason: null,
775
+ outcome,
776
+ evidence_digest: result.package_digest,
777
+ });
778
+ };
779
+ return withOptions(verifier, pinned);
780
+ }
781
+ /** Trust Program executionOutcomeVerifier wrapper for Action Escrow. */
782
+ export function createActionEscrowExecutionOutcomeVerifier(options) {
783
+ const terminal = createActionEscrowTerminalOutcomeVerifier(options);
784
+ return async function actionEscrowExecutionOutcomeVerifier(input) {
785
+ const result = await terminal(input);
786
+ return result.valid === true
787
+ && result.outcome === input.outcome
788
+ && result.evidence_digest === input.evidenceDigest;
789
+ };
790
+ }
791
+ export default {
792
+ canonicalKeyFingerprint,
793
+ containsActionEscrowConsequence,
794
+ createPinnedEvidenceAdapter,
795
+ createQuorumTrustProgramAdapter,
796
+ createAecTrustProgramAdapter,
797
+ createReceiptProgramTerminalOutcomeVerifier,
798
+ createReceiptProgramExecutionOutcomeVerifier,
799
+ createActionEscrowTerminalOutcomeVerifier,
800
+ createActionEscrowExecutionOutcomeVerifier,
801
+ };
802
+ //# sourceMappingURL=trust-program-adapters.js.map