@emilia-protocol/gate 0.11.0 → 0.14.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 (425) hide show
  1. package/CHANGELOG.md +80 -0
  2. package/README.md +310 -0
  3. package/action-control-manifest.js +3 -268
  4. package/action-escrow-custodian.js +3 -394
  5. package/action-escrow-evidence.js +3 -858
  6. package/action-escrow-package.js +3 -1668
  7. package/action-escrow-postgres.js +3 -337
  8. package/action-escrow-state.js +3 -396
  9. package/action-escrow-verifiers.js +3 -331
  10. package/action-escrow.js +3 -2447
  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 +1003 -0
  179. package/dist/index.d.ts.map +1 -0
  180. package/dist/index.js +1737 -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/proposal-to-effect.d.ts +146 -0
  203. package/dist/proposal-to-effect.d.ts.map +1 -0
  204. package/dist/proposal-to-effect.js +427 -0
  205. package/dist/proposal-to-effect.js.map +1 -0
  206. package/dist/protocol-state.d.ts +141 -0
  207. package/dist/protocol-state.d.ts.map +1 -0
  208. package/dist/protocol-state.js +106 -0
  209. package/dist/protocol-state.js.map +1 -0
  210. package/dist/receipt-program.d.ts +59 -0
  211. package/dist/receipt-program.d.ts.map +1 -0
  212. package/dist/receipt-program.js +1053 -0
  213. package/dist/receipt-program.js.map +1 -0
  214. package/dist/reliance-kernel.d.ts +66 -0
  215. package/dist/reliance-kernel.d.ts.map +1 -0
  216. package/dist/reliance-kernel.js +103 -0
  217. package/dist/reliance-kernel.js.map +1 -0
  218. package/dist/reliance-packet.d.ts +67 -0
  219. package/dist/reliance-packet.d.ts.map +1 -0
  220. package/dist/reliance-packet.js +176 -0
  221. package/dist/reliance-packet.js.map +1 -0
  222. package/dist/remedy-program-postgres.d.ts +37 -0
  223. package/dist/remedy-program-postgres.d.ts.map +1 -0
  224. package/dist/remedy-program-postgres.js +291 -0
  225. package/dist/remedy-program-postgres.js.map +1 -0
  226. package/dist/remedy-program-receipt.d.ts +97 -0
  227. package/dist/remedy-program-receipt.d.ts.map +1 -0
  228. package/dist/remedy-program-receipt.js +817 -0
  229. package/dist/remedy-program-receipt.js.map +1 -0
  230. package/dist/remedy-program.d.ts +76 -0
  231. package/dist/remedy-program.d.ts.map +1 -0
  232. package/dist/remedy-program.js +1346 -0
  233. package/dist/remedy-program.js.map +1 -0
  234. package/dist/reports/art14.d.ts +101 -0
  235. package/dist/reports/art14.d.ts.map +1 -0
  236. package/dist/reports/art14.js +340 -0
  237. package/dist/reports/art14.js.map +1 -0
  238. package/dist/reports/assurance-package.d.ts +197 -0
  239. package/dist/reports/assurance-package.d.ts.map +1 -0
  240. package/dist/reports/assurance-package.js +313 -0
  241. package/dist/reports/assurance-package.js.map +1 -0
  242. package/dist/reports/auditor-workpaper.d.ts +194 -0
  243. package/dist/reports/auditor-workpaper.d.ts.map +1 -0
  244. package/dist/reports/auditor-workpaper.js +545 -0
  245. package/dist/reports/auditor-workpaper.js.map +1 -0
  246. package/dist/reports/external-verification.d.ts +76 -0
  247. package/dist/reports/external-verification.d.ts.map +1 -0
  248. package/dist/reports/external-verification.js +209 -0
  249. package/dist/reports/external-verification.js.map +1 -0
  250. package/dist/reports/reperform.d.ts +122 -0
  251. package/dist/reports/reperform.d.ts.map +1 -0
  252. package/dist/reports/reperform.js +432 -0
  253. package/dist/reports/reperform.js.map +1 -0
  254. package/dist/reports/underwriter.d.ts +127 -0
  255. package/dist/reports/underwriter.d.ts.map +1 -0
  256. package/dist/reports/underwriter.js +348 -0
  257. package/dist/reports/underwriter.js.map +1 -0
  258. package/dist/retention.d.ts +88 -0
  259. package/dist/retention.d.ts.map +1 -0
  260. package/dist/retention.js +90 -0
  261. package/dist/retention.js.map +1 -0
  262. package/dist/roster.d.ts +113 -0
  263. package/dist/roster.d.ts.map +1 -0
  264. package/dist/roster.js +261 -0
  265. package/dist/roster.js.map +1 -0
  266. package/dist/runtime-monitor.d.ts +132 -0
  267. package/dist/runtime-monitor.d.ts.map +1 -0
  268. package/dist/runtime-monitor.js +197 -0
  269. package/dist/runtime-monitor.js.map +1 -0
  270. package/dist/settlement.d.ts +68 -0
  271. package/dist/settlement.d.ts.map +1 -0
  272. package/dist/settlement.js +306 -0
  273. package/dist/settlement.js.map +1 -0
  274. package/dist/siem.d.ts +261 -0
  275. package/dist/siem.d.ts.map +1 -0
  276. package/dist/siem.js +247 -0
  277. package/dist/siem.js.map +1 -0
  278. package/dist/store-postgres.d.ts +107 -0
  279. package/dist/store-postgres.d.ts.map +1 -0
  280. package/dist/store-postgres.js +152 -0
  281. package/dist/store-postgres.js.map +1 -0
  282. package/dist/store.d.ts +95 -0
  283. package/dist/store.d.ts.map +1 -0
  284. package/dist/store.js +202 -0
  285. package/dist/store.js.map +1 -0
  286. package/dist/strict-json.d.ts +14 -0
  287. package/dist/strict-json.d.ts.map +1 -0
  288. package/dist/strict-json.js +132 -0
  289. package/dist/strict-json.js.map +1 -0
  290. package/dist/trust-program-adapters.d.ts +122 -0
  291. package/dist/trust-program-adapters.d.ts.map +1 -0
  292. package/dist/trust-program-adapters.js +802 -0
  293. package/dist/trust-program-adapters.js.map +1 -0
  294. package/dist/trust-program-postgres.d.ts +41 -0
  295. package/dist/trust-program-postgres.d.ts.map +1 -0
  296. package/dist/trust-program-postgres.js +346 -0
  297. package/dist/trust-program-postgres.js.map +1 -0
  298. package/dist/trust-program-revocation.d.ts +206 -0
  299. package/dist/trust-program-revocation.d.ts.map +1 -0
  300. package/dist/trust-program-revocation.js +600 -0
  301. package/dist/trust-program-revocation.js.map +1 -0
  302. package/dist/trust-program.d.ts +197 -0
  303. package/dist/trust-program.d.ts.map +1 -0
  304. package/dist/trust-program.js +1351 -0
  305. package/dist/trust-program.js.map +1 -0
  306. package/dist/witness-postgres.d.ts +43 -0
  307. package/dist/witness-postgres.d.ts.map +1 -0
  308. package/dist/witness-postgres.js +92 -0
  309. package/dist/witness-postgres.js.map +1 -0
  310. package/dist/zk-range-proof.d.ts +78 -0
  311. package/dist/zk-range-proof.d.ts.map +1 -0
  312. package/dist/zk-range-proof.js +228 -0
  313. package/dist/zk-range-proof.js.map +1 -0
  314. package/eg1-conformance.js +3 -404
  315. package/enterprise.js +3 -180
  316. package/ep-assure.mjs +1 -0
  317. package/evidence-postgres.js +3 -356
  318. package/evidence.js +4 -360
  319. package/execution-binding.js +3 -212
  320. package/formal-runtime-map.js +4 -0
  321. package/index.js +4 -1249
  322. package/key-registry.js +3 -134
  323. package/mcp.js +3 -109
  324. package/metering.js +3 -226
  325. package/metrics.js +3 -231
  326. package/network-witness.js +3 -499
  327. package/package.json +35 -4
  328. package/proposal-to-effect.js +4 -0
  329. package/receipt-program.js +4 -0
  330. package/reliance-kernel.js +3 -112
  331. package/reliance-packet.js +3 -175
  332. package/remedy-program-postgres.js +4 -0
  333. package/remedy-program-receipt.js +4 -0
  334. package/remedy-program.js +4 -0
  335. package/reports/art14.js +0 -0
  336. package/reports/assurance-package.js +2 -312
  337. package/reports/auditor-workpaper.js +3 -537
  338. package/reports/external-verification.js +3 -222
  339. package/reports/reperform.js +3 -424
  340. package/reports/underwriter.js +3 -339
  341. package/retention.js +3 -84
  342. package/roster.js +3 -264
  343. package/runtime-monitor.js +4 -0
  344. package/settlement.js +3 -299
  345. package/siem.js +3 -235
  346. package/src/action-control-manifest.ts +424 -0
  347. package/src/action-escrow-custodian.ts +427 -0
  348. package/src/action-escrow-evidence.ts +1178 -0
  349. package/src/action-escrow-package.ts +1821 -0
  350. package/src/action-escrow-postgres.ts +366 -0
  351. package/src/action-escrow-state.ts +498 -0
  352. package/src/action-escrow-verifiers.ts +484 -0
  353. package/src/action-escrow.ts +3039 -0
  354. package/src/action-packs.ts +170 -0
  355. package/src/adapters/_kit.ts +117 -0
  356. package/src/adapters/aws.ts +142 -0
  357. package/src/adapters/cloudflare.ts +78 -0
  358. package/src/adapters/gcp.ts +71 -0
  359. package/src/adapters/github.ts +110 -0
  360. package/src/adapters/jira.ts +56 -0
  361. package/src/adapters/k8s.ts +71 -0
  362. package/src/adapters/linear.ts +56 -0
  363. package/src/adapters/salesforce.ts +56 -0
  364. package/src/adapters/stripe.ts +82 -0
  365. package/src/adapters/supabase.ts +122 -0
  366. package/src/adapters/terraform.ts +60 -0
  367. package/src/adapters/vercel.ts +85 -0
  368. package/src/aec-execution.ts +354 -0
  369. package/src/breakglass.ts +647 -0
  370. package/src/capability-receipt.ts +1258 -0
  371. package/src/cf1-conformance.ts +120 -0
  372. package/src/challenge-store.ts +70 -0
  373. package/src/control-plane.ts +374 -0
  374. package/src/coverage.ts +832 -0
  375. package/src/deployment-attestation.ts +259 -0
  376. package/src/eg1-conformance.ts +471 -0
  377. package/src/enterprise.ts +195 -0
  378. package/src/evidence-postgres.ts +374 -0
  379. package/src/evidence.ts +367 -0
  380. package/src/execution-binding.ts +236 -0
  381. package/src/formal-runtime-map.ts +24 -0
  382. package/src/index.ts +2127 -0
  383. package/src/key-registry.ts +150 -0
  384. package/src/mcp.ts +120 -0
  385. package/src/metering.ts +237 -0
  386. package/src/metrics.ts +232 -0
  387. package/src/network-witness.ts +585 -0
  388. package/src/proposal-to-effect.ts +571 -0
  389. package/src/protocol-state.ts +143 -0
  390. package/src/protocol-state.typecheck.ts +94 -0
  391. package/src/receipt-program.ts +1105 -0
  392. package/src/reliance-kernel.ts +119 -0
  393. package/src/reliance-packet.ts +206 -0
  394. package/src/remedy-program-postgres.ts +367 -0
  395. package/src/remedy-program-receipt.ts +891 -0
  396. package/src/remedy-program.ts +1388 -0
  397. package/src/reports/art14.ts +361 -0
  398. package/src/reports/assurance-package.ts +330 -0
  399. package/src/reports/auditor-workpaper.ts +558 -0
  400. package/src/reports/external-verification.ts +232 -0
  401. package/src/reports/reperform.ts +441 -0
  402. package/src/reports/underwriter.ts +356 -0
  403. package/src/retention.ts +100 -0
  404. package/src/roster.ts +273 -0
  405. package/src/runtime-monitor.ts +217 -0
  406. package/src/settlement.ts +313 -0
  407. package/src/siem.ts +247 -0
  408. package/src/store-postgres.ts +167 -0
  409. package/src/store.ts +214 -0
  410. package/src/strict-json.ts +115 -0
  411. package/src/trust-program-adapters.ts +847 -0
  412. package/src/trust-program-postgres.ts +429 -0
  413. package/src/trust-program-revocation.ts +751 -0
  414. package/src/trust-program.ts +1460 -0
  415. package/src/witness-postgres.ts +106 -0
  416. package/src/zk-range-proof.ts +250 -0
  417. package/store-postgres.js +3 -161
  418. package/store.js +4 -198
  419. package/strict-json.js +3 -102
  420. package/trust-program-adapters.js +4 -0
  421. package/trust-program-postgres.js +4 -0
  422. package/trust-program-revocation.js +4 -0
  423. package/trust-program.js +4 -0
  424. package/witness-postgres.js +3 -96
  425. package/zk-range-proof.js +4 -0
package/CHANGELOG.md CHANGED
@@ -4,6 +4,86 @@
4
4
  All notable changes to `@emilia-protocol/gate` are documented here.
5
5
  This package follows [Semantic Versioning](https://semver.org/).
6
6
 
7
+ ## 0.14.0 (2026-07-22)
8
+
9
+ ### Added
10
+
11
+ - `./proposal-to-effect`, an orchestration profile over CAID, the existing
12
+ `EP-APPROVAL-v1` acquisition rail, signed AEB evaluation, Gate authorization,
13
+ durable operation reservation, exact effect invocation, and authenticated
14
+ reconciliation.
15
+ - An executable end-to-end example and profile vectors covering exact-action
16
+ mutation, stale evidence, one-time replay, indeterminate effects, and
17
+ post-effect commit failure.
18
+
19
+ ### Security
20
+
21
+ - A proposal is explicitly non-authoritative and carries no signature, permit,
22
+ or presenter-controlled authorization decision.
23
+ - AEB and Gate make independent, fail-closed decisions over the same operation,
24
+ initiator, CAID, normalized action, and relying-party pins.
25
+ - Once an effect may have executed, failed bookkeeping cannot release its AEB
26
+ reservation. The operation remains frozen until authenticated provider
27
+ evidence proves `COMMITTED` or `NOT_COMMITTED`.
28
+
29
+ ## 0.13.0 (2026-07-20)
30
+
31
+ ### Added
32
+
33
+ - A receipt-program execution kernel that composes CAID matching, Gate
34
+ authorization, bounded capability reservation, provider execution,
35
+ execution evidence, and an operator-signed content-addressed certificate.
36
+ - Offline certificate verification under a separately pinned operator key,
37
+ context, and evidence record, including CAID re-performance, exact schemas and
38
+ instruction sequencing, result digest, action/operation binding, and Gate
39
+ evidence-record references.
40
+ - A tenant-bound Trust Program kernel for staged, ordered or threshold
41
+ authorization ceremonies, with durable Postgres state, revocation handling,
42
+ exact predecessor/evidence bindings, and tenant-wide replay refusal.
43
+ - Explicit `executed`, `refused`, and `indeterminate` terminal states. Provider
44
+ timeout and non-canonical provider output halt the operation without restoring
45
+ replay authority.
46
+
47
+ ### Security
48
+
49
+ - Production construction requires both a durable atomic evidence log and a
50
+ durable capability store, an external KMS/HSM signer, pinned certificate
51
+ context, pinned result projector, and finite provider deadline. Process-local
52
+ state and keys are available only behind an explicit test/demo opt-in.
53
+ - CAID resolution, operation-id field selection, certificate signing and
54
+ context, result projection, deadline, clock, and Gate trust are
55
+ constructor-pinned; runtime requests cannot replace them.
56
+ - Provider code receives deep-frozen snapshots rather than Gate's live
57
+ authorization objects. Complete certificates are appended to the atomic
58
+ evidence log, and signer/persistence failures preserve Gate's terminal state
59
+ without issuing contradictory proof.
60
+ - The certificate is an operator-signed integrity and binding artifact. It is
61
+ not a zero-knowledge proof and does not attest that an external provider's
62
+ statement is truthful.
63
+
64
+ ## 0.12.0 (2026-07-18)
65
+
66
+ ### Added
67
+
68
+ - A distinct contractor release-template profile that requires a signed
69
+ `project_record_snapshot_digest` while preserving the closed legacy profile.
70
+ - A contractor evidence-package profile that carries and re-verifies the exact
71
+ project-record sidecar bytes under a relying-party-owned verifier.
72
+ - A read-only Procore change-order source adapter with complete pagination and
73
+ stable double-fetch snapshots.
74
+
75
+ ### Security
76
+
77
+ - A project-system source record cannot become agreement acceptance or release
78
+ authority. Replacing its committed snapshot changes the action digest and
79
+ fails closed.
80
+ - Existing Action Escrow templates without a project source remain valid under
81
+ their original closed profile; new contractor artifacts use an explicit
82
+ version boundary and cannot be silently downgraded.
83
+ - Unmarked project-bound artifacts from the unreleased `0.11.1` preview remain
84
+ readable only through the contractor package path, which requires the exact
85
+ project-record sidecar and a relying-party-owned source verifier.
86
+
7
87
  ## 0.11.0 (2026-07-17)
8
88
 
9
89
  ### Added
package/README.md CHANGED
@@ -59,6 +59,64 @@ if (!out.ok) throw out.body; // 428 Receipt Required
59
59
  console.log(out.packet.verdict); // "rely"
60
60
  ```
61
61
 
62
+ ## Proposal to effect
63
+
64
+ `@emilia-protocol/gate/proposal-to-effect` closes the loop from an agent's
65
+ proposal to a controlled consequence without minting another authorization
66
+ format. The proposal is an unsigned, short-lived request; authority remains in
67
+ `EP-RECEIPT-v1` and the relying party's pinned AEB requirement.
68
+
69
+ ```js
70
+ import { createProposalToEffect } from '@emilia-protocol/gate/proposal-to-effect';
71
+
72
+ const controller = createProposalToEffect({
73
+ gate,
74
+ profiles: {
75
+ 'payment-release': {
76
+ id: 'payment-release',
77
+ action_type: 'payment.release',
78
+ selector: { protocol: 'mcp', tool: 'release_payment' },
79
+ required_fields: [
80
+ 'action_type', 'amount_usd', 'currency',
81
+ 'payment_instruction_id', 'beneficiary_account_hash',
82
+ ],
83
+ authorization: {
84
+ authorization_endpoint: 'https://authorize.example/v1/approvals',
85
+ flow: 'EP-APPROVAL-v1',
86
+ },
87
+ aeb_requirement_ref: 'requirement:payment-release',
88
+ ttl_sec: 300,
89
+ canonicalize_action: deriveCanonicalPaymentActionAndCaid,
90
+ },
91
+ },
92
+ aeb: {
93
+ config: pinnedAebConfig,
94
+ adapters: pinnedAebAdapters,
95
+ store: durableOperationStore,
96
+ resolve_artifacts,
97
+ verify_provider_evidence,
98
+ },
99
+ });
100
+
101
+ const proposal = controller.prepare({
102
+ proposal_id, profile_id: 'payment-release', operation_id,
103
+ initiator_id: authenticatedAgentId, action: paymentFromSystemOfRecord,
104
+ });
105
+
106
+ const result = await controller.execute(
107
+ { proposal, receipt, evaluation: signedAebEvaluation },
108
+ ({ action }) => paymentProvider.release(action),
109
+ );
110
+ ```
111
+
112
+ The controller re-verifies the signed AEB evaluation, runs Gate policy,
113
+ reserves the operation before invoking the effect, and consumes it after
114
+ success. An uncertain provider result remains reserved; only authenticated
115
+ provider evidence bound to the same operation, CAID, and action digest can
116
+ reconcile it. See
117
+ [`docs/protocol/proposal-to-effect-profile-v1.md`](../../docs/protocol/proposal-to-effect-profile-v1.md)
118
+ and run `node examples/proposal-to-effect/demo.mjs` from the repository root.
119
+
62
120
  ## Three-plane deployment
63
121
 
64
122
  High-consequence infrastructure separates three jobs instead of asking one
@@ -295,6 +353,245 @@ challenge. The Gate composes that and adds the lifecycle controls a firewall nee
295
353
  can establish a declared surface as `gated`; a passive network witness alone is always
296
354
  `witness_only`. Inventory completeness remains an explicit relying-party assumption.
297
355
 
356
+ ## Formal-to-runtime bridge
357
+
358
+ Every Gate has an explicit runtime lifecycle monitor. It mirrors the load-bearing
359
+ state ordering behind the formal model: authorization must precede the effect,
360
+ consumption is one-way, and execution evidence follows the effect attempt. A
361
+ divergence emits a bounded `SPEC_DIVERGENCE` event and moves the Gate into
362
+ fail-closed safe mode. In safe mode, pass-through is disabled and a receipt must
363
+ earn at least Class-A assurance before execution.
364
+
365
+ ```js
366
+ import { createRuntimeMonitor, createTrustedActionFirewall } from '@emilia-protocol/gate';
367
+
368
+ const monitor = createRuntimeMonitor({
369
+ onDivergence: (event) => siem.append(event),
370
+ authorizeRecovery: (request) => operatorApproval.verify(request),
371
+ });
372
+ const gate = createTrustedActionFirewall({ runtimeMonitor: monitor, /* ... */ });
373
+ ```
374
+
375
+ Recovery is explicit and operator-authorized; it never re-authorizes a prior
376
+ receipt. The repository's `check:runtime-bridge` gate binds each monitor
377
+ theorem to an invariant declared in `formal/ep_handshake.cfg`, so a renamed or
378
+ removed formal source cannot silently leave the runtime map stale. This is a
379
+ machine-checked coverage binding, not a claim that TLA+ is automatically
380
+ compiled into JavaScript: the formal specifications remain the source of the
381
+ invariants and the monitor's transition table is covered by its own tests.
382
+
383
+ ## Capability receipts
384
+
385
+ `capability-receipt.js` adds an issuer-signed capability envelope around an
386
+ ordinary EP receipt. The envelope binds a secret preimage, an integer budget,
387
+ currency, expiry, a signed delegation chain, and an optional `m-of-n` Shamir
388
+ threshold. The envelope's `consumed` field is only an issuance invariant; spend
389
+ state lives in an atomic capability store and is never trusted from the bearer
390
+ object.
391
+
392
+ ```js
393
+ import {
394
+ createMemoryCapabilityStore,
395
+ executeWithCapability,
396
+ mintCapabilityReceipt,
397
+ } from '@emilia-protocol/gate/capability-receipt';
398
+
399
+ const minted = mintCapabilityReceipt(baseReceipt, {
400
+ issuerPrivateKey,
401
+ budget: { amount: 1_000_000, currency: 'USD' },
402
+ expiry: '2026-12-31T00:00:00.000Z',
403
+ scope: {
404
+ profile: CAPABILITY_SCOPE_PROFILE,
405
+ operation_id_field: 'payment_instruction_id',
406
+ action_digests: allowedPaymentActions.map(capabilityActionDigest),
407
+ },
408
+ });
409
+ const store = createMemoryCapabilityStore(); // tests only; use Postgres in production
410
+ store.registerCapability(minted.capabilityReceipt);
411
+ await executeWithCapability({
412
+ capabilityReceipt: minted.capabilityReceipt,
413
+ secret: minted.secret,
414
+ action: { amount: 10_000, currency: 'USD' },
415
+ observedAction: actionFromTheSystemOfRecord,
416
+ store,
417
+ gate,
418
+ trustedIssuerKeys: [capabilityIssuerPublicKey],
419
+ operationId: 'provider-idempotency-key',
420
+ executeAction: sendPayment,
421
+ });
422
+ ```
423
+
424
+ The production adapter requires a transaction callback and locks the capability
425
+ state row before reserving budget. If the external effect throws, the reserved
426
+ amount is committed as indeterminate; it is never silently reopened. The
427
+ capability path is separate from ordinary receipt consumption: the capability
428
+ store owns replay and budget state for each explicitly supplied operation ID.
429
+ The verifier requires a pinned capability issuer key. Every operation must
430
+ match one exact signed action digest, and the caller's stable operation ID must
431
+ equal the signed scope's field in the executor-observed action. The same digest
432
+ is persisted with the reservation. The separate budget projection must match
433
+ the amount and currency in that verified action, and the effect callback
434
+ receives a clone of the verified action—not the projection. A new operation ID
435
+ therefore cannot relabel the same payment instruction after a timeout.
436
+
437
+ The built-in `urn:emilia:scope:action-digest-set-v1` profile is exact-byte
438
+ scope. `urn:emilia:scope:caid-set-v1` is also supported for interoperable
439
+ material-action scope, but only when the deployment supplies its pinned CAID
440
+ resolver as `capabilityCaidResolver`; a missing, unknown, or non-matching CAID
441
+ fails closed. CAID correlates content here—it does not replace issuer trust,
442
+ human authorization, holder proof, or durable budget state.
443
+
444
+ ### Gate-integrated capability enforcement
445
+
446
+ For an action that must be both human-authorized and budget-limited, pass the
447
+ capability store when constructing the Gate and supply a capability to `run()`
448
+ or `guard()`:
449
+
450
+ ```js
451
+ const gate = createTrustedActionFirewall({
452
+ capabilityStore: postgresCapabilityStore,
453
+ capabilityTrustedIssuerKeys: [capabilityIssuerPublicKey],
454
+ capabilityCaidResolver: resolveWithPinnedCaidRegistry, // for caid-set scopes
455
+ // ...the ordinary Gate trust and durable evidence configuration
456
+ });
457
+
458
+ const result = await gate.run({
459
+ selector: { protocol: 'mcp', tool: 'release_payment' },
460
+ observedAction: actionFromTheSystemOfRecord,
461
+ capability: {
462
+ capabilityReceipt,
463
+ secret,
464
+ action: { amount: 10_000, currency: 'USD' },
465
+ operationId: 'provider-idempotency-key',
466
+ },
467
+ }, (authorization, operation) => sendPayment(actionFromTheSystemOfRecord, {
468
+ idempotencyKey: operation.providerIdempotencyKey,
469
+ authorization,
470
+ }));
471
+ ```
472
+
473
+ The Gate verifies the ordinary receipt first without consuming it, requires the
474
+ capability amount and currency to equal the observed action's `amount` or
475
+ `amount_usd` and `currency`, checks the signed exact-action scope, reserves the
476
+ budget and action digest before calling `sendPayment`, and passes the stable
477
+ operation ID to the provider adapter as its idempotency key. A replay,
478
+ out-of-scope action, operation relabel, overspend, missing registration, or
479
+ envelope mismatch never enters the effect. An exception after the effect begins
480
+ commits the amount as `indeterminate` and keeps the operation closed for
481
+ authenticated reconciliation. Capability issuer keys are pinned separately
482
+ from the ordinary receipt trust list.
483
+
484
+ Delegation is issuer-authorized and budget-backed: `delegateCapabilityReceipt`
485
+ atomically reserves and commits the child budget against the parent before the
486
+ child is registered. A failed child registration is reported for
487
+ reconciliation; it never creates spendable budget out of thin air. A holder
488
+ cannot edit `delegation_chain` or enlarge a child because the issuer signs the
489
+ entire envelope.
490
+
491
+ ## Receipt programs
492
+
493
+ `createReceiptProgramKernel()` composes CAID, the Gate capability path, and the
494
+ evidence log into one bounded instruction surface. The instruction descriptor
495
+ and certificate encoding are deterministic; external effects are not. It does not create a
496
+ second ledger or bypass Gate. A successful run emits an Ed25519-signed
497
+ certificate over the exact program, provider result projection, execution
498
+ steps, and compact Gate evidence references.
499
+
500
+ ```js
501
+ import {
502
+ createReceiptProgramKernel,
503
+ verifyReceiptProgramCertificate,
504
+ } from '@emilia-protocol/gate/receipt-program';
505
+
506
+ const certificateContext = {
507
+ issuer: 'emilia-operator',
508
+ tenant: 'acme',
509
+ environment: 'production',
510
+ audience: 'acme-audit',
511
+ key_id: 'kms://receipt-program-1',
512
+ };
513
+
514
+ const kernel = createReceiptProgramKernel({
515
+ gate, // already configured production Gate
516
+ resolveCaid, // relying-party-pinned synchronous resolver
517
+ operationIdField: 'payment_instruction_id',
518
+ certificateSigner: {
519
+ keyId: 'kms://receipt-program-1',
520
+ custody: 'kms',
521
+ publicKey: operatorPublicKey,
522
+ sign: (bytes) => signWithKms(bytes),
523
+ },
524
+ certificateContext,
525
+ projectResult: (raw) => ({
526
+ provider: raw.provider,
527
+ provider_operation_id: raw.provider_operation_id,
528
+ status: raw.status,
529
+ }),
530
+ effectTimeoutMs: 15_000,
531
+ });
532
+
533
+ const run = await kernel.run({
534
+ programId: 'delegated-payment-v1',
535
+ instructionId: 'release-milestone-1',
536
+ caid,
537
+ selector: { protocol: 'mcp', tool: 'release_payment' },
538
+ observedAction: actionFromTheSystemOfRecord,
539
+ capability: {
540
+ capabilityReceipt,
541
+ secret,
542
+ action: { amount: 50, currency: 'USD' },
543
+ operationId: actionFromTheSystemOfRecord.payment_instruction_id,
544
+ },
545
+ }, async (_authorization, operation) => ({
546
+ provider: 'licensed-custodian',
547
+ provider_operation_id: operation.providerIdempotencyKey,
548
+ status: await releaseWithIdempotency(operation.providerIdempotencyKey),
549
+ }));
550
+
551
+ const checked = verifyReceiptProgramCertificate(run.certificate, {
552
+ trustedCertificateKeys: {
553
+ 'kms://receipt-program-1': operatorPublicKey,
554
+ },
555
+ resolveCaid,
556
+ expectedContext: certificateContext,
557
+ certificateEvidence: run.certificate_evidence,
558
+ // Must check this exact record against the relying party's pinned stream,
559
+ // authenticated snapshot, or inclusion proof. Rehashing the object is not enough.
560
+ verifyCertificateInclusion: verifyInPinnedEvidenceStream,
561
+ requireAtomicCertificateEvidence: true,
562
+ });
563
+ ```
564
+
565
+ Production construction requires a durable atomic evidence log and durable
566
+ capability store, external KMS/HSM signing custody, an exact certificate
567
+ context, and a pinned disclosure projector. Provider code receives only frozen
568
+ copies of authorization and operation data. A provider exception, real deadline
569
+ expiry, or invalid result projection after invocation becomes `indeterminate`
570
+ and leaves the operation closed to blind replay. A certificate is returned as
571
+ durable proof only after signing and complete-certificate evidence append
572
+ succeed; typed signer/persistence failures preserve Gate's terminal outcome.
573
+ `checked.ok` means certificate validity, not provider success—inspect
574
+ `checked.outcome` and `checked.execution_succeeded`. The certificate proves
575
+ operator-signed integrity and binding; it is not a zero-knowledge proof or
576
+ independent proof of provider truth. See the runnable `examples/receipt-program/` reference and the
577
+ [architecture profile](../../docs/architecture/RECEIPT-PROGRAM-EXECUTION-KERNEL.md).
578
+
579
+ ## Zero-knowledge range receipts
580
+
581
+ `zk-range-proof.js` provides `EP-ZK-RANGE-RECEIPT-v1`. It uses Bulletproofs over
582
+ Ristretto255 to prove a hidden integer `v` satisfies `0 <= v <= max` without
583
+ revealing `v` or its blinding factor. The second commitment proves the upper
584
+ bound relation `max - v` without relying on a mutable claim. The envelope
585
+ binds a public policy hash, predicate, base-receipt digest, issuer key, and
586
+ nonce. The ordinary EP receipt signature must still be verified separately.
587
+
588
+ The cryptographic engine is an explicit optional backend:
589
+ `@aptos-labs/confidential-asset-bindings@1.1.2`. It is not pulled into the
590
+ default Gate install because its WASM/mobile distribution is large. A
591
+ deployment enabling ZK receipts must pin, audit, and pass the backend's own
592
+ proof tests. This v1 is a genuine hidden-range proof; it is not a claim that
593
+ the repository automatically compiles all TLA+ invariants into R1CS.
594
+
298
595
  ## Action Escrow
299
596
 
300
597
  Action Escrow is the Gate profile for a two-party agreement whose downstream
@@ -315,6 +612,19 @@ adjudicate disputes, or make an agreement legally enforceable. An ambiguous
315
612
  provider outcome enters reconciliation and is never retried as though nothing
316
613
  happened.
317
614
 
615
+ Construction and contractor integrations use the explicit
616
+ `EP-ACTION-ESCROW-CONTRACTOR-TEMPLATE-v1` profile. Build its DAB verifier with
617
+ `createActionEscrowContractorDocumentBindingVerifier()` and its portable
618
+ six-row package with `assembleActionEscrowContractorEvidencePackage()`. The
619
+ package carries the exact project-system sidecar bytes beside the PDF and
620
+ re-performs both under relying-party-owned verifiers. A project record is
621
+ source evidence only: it cannot fill agreement-acceptance, release-approval,
622
+ or custodian-effect rows. The legacy template and package APIs refuse the
623
+ contractor profile instead of silently ignoring its project-source binding.
624
+ Unmarked project-bound artifacts from the unreleased `0.11.1` preview remain
625
+ verifiable only through the contractor package path, including its exact
626
+ sidecar and relying-party-owned project-source verifier.
627
+
318
628
  ## Production custody
319
629
 
320
630
  The three things a serious buyer (CISO, auditor, insurer) asks after the demo:
@@ -1,269 +1,4 @@
1
1
  // SPDX-License-Identifier: Apache-2.0
2
- //
3
- // EP Action Control Manifest: the missing control-plane waist between agent
4
- // runtimes, receipt formats, transparency logs, and system-of-record adapters.
5
- //
6
- // A receipt proves an authorization event. This manifest tells an executor
7
- // when a receipt is required, what assurance tier is required, which material
8
- // fields must be observed from the system of record, and what evidence must be
9
- // emitted after the effect boundary.
10
-
11
- import { HIGH_RISK_ACTION_PACKS, DEFAULT_PASS_THROUGH_ACTIONS } from './action-packs.js';
12
-
13
- export const ACTION_CONTROL_MANIFEST_VERSION = 'EP-ACTION-CONTROL-MANIFEST-v0.2';
14
- export const ACTION_CONTROL_SCHEMA_URL = 'https://www.emiliaprotocol.ai/docs/schemas/agent-action-control-manifest-v0.2.schema.json';
15
- export const ACTION_CONTROL_CONFORMANCE_LEVEL = 'EG-1';
16
-
17
- const RISK_LEVELS = new Set(['low', 'medium', 'high', 'critical']);
18
- const ASSURANCE_CLASSES = new Set(['software', 'class_a', 'quorum']);
19
- const ENFORCEMENT_POINTS = new Set(['pre_execution', 'pre_effect_commit']);
20
-
21
- export const ACTION_CONTROL_DEFAULTS = Object.freeze({
22
- decision_point: 'pre_effect_commit',
23
- missing_receipt: 'refuse',
24
- invalid_receipt: 'refuse',
25
- stale_receipt: 'refuse',
26
- replay: 'one_time_consumption',
27
- evidence_log: 'strict',
28
- });
29
-
30
- export const ACTION_CONTROL_EVIDENCE_PROFILES = Object.freeze({
31
- authorization_receipt: 'EP-RECEIPT-v1',
32
- execution_attestation: 'EP-EXECUTION-ATTESTATION-v1',
33
- reliance_packet: 'EP-RELIANCE-PACKET-v1',
34
- transparency: 'SCITT-compatible Signed Statement',
35
- });
36
-
37
- export const ACTION_CONTROL_CONFORMANCE_CHECKS = Object.freeze([
38
- 'missing_receipt_refused',
39
- 'software_on_classA_refused',
40
- 'execution_drift_refused',
41
- 'valid_classA_runs',
42
- 'replay_refused',
43
- 'tampered_refused',
44
- 'execution_proof_binds',
45
- 'reliance_packet_rely',
46
- ]);
47
-
48
- function cloneJson(value) {
49
- return value == null ? value : JSON.parse(JSON.stringify(value));
50
- }
51
-
52
- function normalizeRisk(risk) {
53
- return RISK_LEVELS.has(risk) ? risk : 'high';
54
- }
55
-
56
- function normalizeAssurance(value) {
57
- return ASSURANCE_CLASSES.has(value) ? value : 'software';
58
- }
59
-
60
- function defaultControlForAction(action) {
61
- const requiredFields = action.execution_binding?.required_fields || [];
62
- if (!action.receipt_required) {
63
- return {
64
- enforcement_point: 'none',
65
- authorization_receipt: { required: false },
66
- evidence_output: { audit_event: true },
67
- };
68
- }
69
- return {
70
- enforcement_point: 'pre_effect_commit',
71
- status: 428,
72
- challenge_header: 'Receipt-Required',
73
- proof_header: 'X-EMILIA-Receipt',
74
- authorization_receipt: {
75
- required: true,
76
- profile: 'EP-RECEIPT-v1',
77
- signature: 'Ed25519 over RFC 8785 canonical JSON',
78
- verifier: 'offline',
79
- },
80
- replay: {
81
- mode: 'one_time_consumption',
82
- receipt_id_required: true,
83
- },
84
- execution_binding: {
85
- required: true,
86
- source: 'system_of_record',
87
- required_fields: [...requiredFields],
88
- },
89
- transparency: {
90
- mode: 'registerable',
91
- profile: 'SCITT Signed Statement',
92
- required: false,
93
- },
94
- evidence_output: {
95
- audit_event: true,
96
- execution_attestation: true,
97
- reliance_packet: true,
98
- blocked_attempts: true,
99
- },
100
- };
101
- }
102
-
103
- export function toActionControl(action) {
104
- const out = {
105
- id: action.id,
106
- label: action.label || action.description || action.id,
107
- action_type: action.action_type,
108
- risk: normalizeRisk(action.risk || (action.receipt_required ? 'high' : 'low')),
109
- receipt_required: !!action.receipt_required,
110
- assurance_class: normalizeAssurance(action.assurance_class),
111
- max_age_sec: action.max_age_sec || 900,
112
- match: cloneJson(action.match || {}),
113
- why: action.why || action.description || null,
114
- control: cloneJson(action.control || defaultControlForAction(action)),
115
- conformance: {
116
- level: ACTION_CONTROL_CONFORMANCE_LEVEL,
117
- checks: [...ACTION_CONTROL_CONFORMANCE_CHECKS],
118
- ...(action.conformance || {}),
119
- },
120
- };
121
- if (action.quorum) out.quorum = cloneJson(action.quorum);
122
- if (action.business_authorization || action.businessAuthorization) {
123
- out.business_authorization = cloneJson(action.business_authorization || action.businessAuthorization);
124
- }
125
- return out;
126
- }
127
-
128
- export function createDefaultActionControlManifest({
129
- service = {},
130
- includePassThrough = true,
131
- extraActions = [],
132
- } = {}) {
133
- const actions = [
134
- ...HIGH_RISK_ACTION_PACKS.map(toActionControl),
135
- ...(includePassThrough ? DEFAULT_PASS_THROUGH_ACTIONS.map(toActionControl) : []),
136
- ...extraActions.map(toActionControl),
137
- ];
138
- return {
139
- '@version': ACTION_CONTROL_MANIFEST_VERSION,
140
- '$schema': ACTION_CONTROL_SCHEMA_URL,
141
- profile: 'agent-action-control',
142
- service: {
143
- name: service.name || 'EMILIA Gate default action controls',
144
- issuer: service.issuer || 'https://www.emiliaprotocol.ai',
145
- manifest_url: service.manifest_url || 'https://www.emiliaprotocol.ai/.well-known/agent-action-control.json',
146
- ...service,
147
- },
148
- defaults: { ...ACTION_CONTROL_DEFAULTS },
149
- evidence_profiles: { ...ACTION_CONTROL_EVIDENCE_PROFILES },
150
- actions,
151
- };
152
- }
153
-
154
- function selectorMatches(match = {}, selector = {}) {
155
- if (!match || typeof match !== 'object') return false;
156
- return Object.entries(match).every(([k, v]) => selector[k] === v);
157
- }
158
-
159
- export function findActionControl(manifest, selector = {}) {
160
- if (!manifest || !Array.isArray(manifest.actions)) return null;
161
- return manifest.actions.find((action) => {
162
- if (selector.action_type && action.action_type === selector.action_type) return true;
163
- return selectorMatches(action.match, selector);
164
- }) || null;
165
- }
166
-
167
- export function validateActionControlManifest(manifest) {
168
- const errors = [];
169
- if (!manifest || typeof manifest !== 'object' || Array.isArray(manifest)) {
170
- return { ok: false, errors: ['manifest must be an object'] };
171
- }
172
- if (manifest['@version'] !== ACTION_CONTROL_MANIFEST_VERSION) {
173
- errors.push(`@version must be ${ACTION_CONTROL_MANIFEST_VERSION}`);
174
- }
175
- if (manifest.profile !== 'agent-action-control' && manifest.profile !== 'emilia.action-control') {
176
- errors.push('profile must be agent-action-control (or the deployed alias emilia.action-control)');
177
- }
178
- if (!manifest.service || typeof manifest.service !== 'object') {
179
- errors.push('service object is required');
180
- }
181
- if (!manifest.defaults || typeof manifest.defaults !== 'object') {
182
- errors.push('defaults object is required');
183
- }
184
- if (!Array.isArray(manifest.actions) || manifest.actions.length === 0) {
185
- errors.push('actions must be a non-empty array');
186
- }
187
- for (const [idx, action] of (manifest.actions || []).entries()) {
188
- const prefix = `actions[${idx}]`;
189
- if (!action || typeof action !== 'object') {
190
- errors.push(`${prefix} must be an object`);
191
- continue;
192
- }
193
- if (!action.id || typeof action.id !== 'string') errors.push(`${prefix}.id is required`);
194
- if (!action.action_type || typeof action.action_type !== 'string') errors.push(`${prefix}.action_type is required`);
195
- if (!action.match || typeof action.match !== 'object') errors.push(`${prefix}.match is required`);
196
- if (typeof action.receipt_required !== 'boolean') errors.push(`${prefix}.receipt_required must be boolean`);
197
- if (!RISK_LEVELS.has(action.risk)) errors.push(`${prefix}.risk must be low|medium|high|critical`);
198
- if (!ASSURANCE_CLASSES.has(action.assurance_class)) errors.push(`${prefix}.assurance_class must be software|class_a|quorum`);
199
- // Key-class floor: a critical action must be bound to a human key. normalizeAssurance()
200
- // defaults a missing or unrecognized tier to the weakest 'software', so this also fails
201
- // closed on a critical action whose tier was omitted rather than silently downgrading it.
202
- if (action.receipt_required && action.risk === 'critical' && action.assurance_class === 'software') {
203
- errors.push(`${prefix}.assurance_class must be class_a or quorum when risk is critical`);
204
- }
205
- if (action.receipt_required) {
206
- if (!Number.isFinite(action.max_age_sec) || action.max_age_sec <= 0) errors.push(`${prefix}.max_age_sec must be positive`);
207
- const control = action.control;
208
- if (!control || typeof control !== 'object') {
209
- errors.push(`${prefix}.control is required when receipt_required=true`);
210
- continue;
211
- }
212
- if (!ENFORCEMENT_POINTS.has(control.enforcement_point)) {
213
- errors.push(`${prefix}.control.enforcement_point must be pre_execution or pre_effect_commit`);
214
- }
215
- if (control.status !== 428) errors.push(`${prefix}.control.status must be 428`);
216
- if (control.authorization_receipt?.required !== true) errors.push(`${prefix}.control.authorization_receipt.required must be true`);
217
- if (control.authorization_receipt?.profile !== 'EP-RECEIPT-v1') errors.push(`${prefix}.control.authorization_receipt.profile must be EP-RECEIPT-v1`);
218
- if (control.authorization_receipt?.verifier !== 'offline') errors.push(`${prefix}.control.authorization_receipt.verifier must be offline`);
219
- if (control.replay?.mode !== 'one_time_consumption') errors.push(`${prefix}.control.replay.mode must be one_time_consumption`);
220
- if (control.replay?.receipt_id_required !== true) errors.push(`${prefix}.control.replay.receipt_id_required must be true`);
221
- const fields = control.execution_binding?.required_fields;
222
- if (control.execution_binding?.required !== true) errors.push(`${prefix}.control.execution_binding.required must be true`);
223
- if (control.execution_binding?.source !== 'system_of_record') errors.push(`${prefix}.control.execution_binding.source must be system_of_record`);
224
- if (!Array.isArray(fields) || fields.length === 0 || fields.some((f) => typeof f !== 'string' || !f)) {
225
- errors.push(`${prefix}.control.execution_binding.required_fields must be a non-empty string array`);
226
- }
227
- if (control.evidence_output?.execution_attestation !== true) errors.push(`${prefix}.control.evidence_output.execution_attestation must be true`);
228
- if (control.evidence_output?.reliance_packet !== true) errors.push(`${prefix}.control.evidence_output.reliance_packet must be true`);
229
- if (action.conformance?.level !== ACTION_CONTROL_CONFORMANCE_LEVEL) errors.push(`${prefix}.conformance.level must be ${ACTION_CONTROL_CONFORMANCE_LEVEL}`);
230
- if (action.business_authorization !== undefined) {
231
- const business = action.business_authorization;
232
- const policy = business?.policy;
233
- const approvers = business?.allowed_approvers;
234
- if (!business || typeof business !== 'object' || Array.isArray(business)) {
235
- errors.push(`${prefix}.business_authorization must be an object`);
236
- } else {
237
- if (!policy || typeof policy !== 'object' || Array.isArray(policy)
238
- || typeof policy.id !== 'string' || !policy.id
239
- || typeof policy.hash !== 'string' || !policy.hash) {
240
- errors.push(`${prefix}.business_authorization.policy must pin non-empty id and hash`);
241
- }
242
- if (typeof business.tenant_id !== 'string' || !business.tenant_id) {
243
- errors.push(`${prefix}.business_authorization.tenant_id must be a non-empty string`);
244
- }
245
- if (!Array.isArray(approvers) || approvers.length === 0
246
- || approvers.some((entry) => !entry || typeof entry !== 'object'
247
- || typeof entry.subject !== 'string' || !entry.subject
248
- || typeof entry.role !== 'string' || !entry.role)) {
249
- errors.push(`${prefix}.business_authorization.allowed_approvers must name subject and role`);
250
- }
251
- }
252
- }
253
- }
254
- }
255
- return { ok: errors.length === 0, errors };
256
- }
257
-
258
- export default {
259
- ACTION_CONTROL_MANIFEST_VERSION,
260
- ACTION_CONTROL_SCHEMA_URL,
261
- ACTION_CONTROL_CONFORMANCE_LEVEL,
262
- ACTION_CONTROL_DEFAULTS,
263
- ACTION_CONTROL_EVIDENCE_PROFILES,
264
- ACTION_CONTROL_CONFORMANCE_CHECKS,
265
- toActionControl,
266
- createDefaultActionControlManifest,
267
- findActionControl,
268
- validateActionControlManifest,
269
- };
2
+ // Compatibility entry point for the TypeScript action-control manifest.
3
+ export * from './dist/action-control-manifest.js';
4
+ export { default } from './dist/action-control-manifest.js';