@emilia-protocol/gate 0.11.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 +58 -0
  2. package/README.md +252 -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 +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 +31 -2
  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 -102
  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,170 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // EMILIA Gate default action packs: the high-risk families that should require
3
+ // pre-execution human authorization before a machine mutates the world.
4
+
5
+ export const ACTION_RISK_MANIFEST_VERSION = 'EP-ACTION-RISK-MANIFEST-v0.1';
6
+
7
+ /**
8
+ * Shape of a single action-pack entry. `business_authorization` is not part
9
+ * of the shipped defaults below but is a legitimate dynamic extension point:
10
+ * callers (e.g. lib/gate/reference-lab.js) attach it to a manifest entry
11
+ * after createDefaultActionRiskManifest() returns, before enforcement.
12
+ */
13
+ type ActionPack = {
14
+ id: string;
15
+ label: string;
16
+ action_type: string;
17
+ risk?: string;
18
+ receipt_required: boolean;
19
+ assurance_class?: string;
20
+ match: { protocol: string; tool: string };
21
+ why?: string;
22
+ execution_binding?: { required_fields: string[]; caid_selector?: { field: string } };
23
+ business_authorization?: Record<string, any>;
24
+ };
25
+
26
+ export const HIGH_RISK_ACTION_PACKS: readonly ActionPack[] = Object.freeze([
27
+ Object.freeze({
28
+ id: 'money_movement.release',
29
+ label: 'Money movement',
30
+ action_type: 'payment.release',
31
+ risk: 'critical',
32
+ receipt_required: true,
33
+ assurance_class: 'class_a',
34
+ match: { protocol: 'mcp', tool: 'release_payment' },
35
+ why: 'Moves funds or releases value. Requires a named human signoff, not an agent-only key.',
36
+ execution_binding: {
37
+ required_fields: ['action_type', 'amount_usd', 'currency', 'payment_instruction_id', 'beneficiary_account_hash'],
38
+ caid_selector: { field: 'action_caid' },
39
+ },
40
+ }),
41
+ Object.freeze({
42
+ id: 'money_movement.bank_details_change',
43
+ label: 'Bank-detail change',
44
+ action_type: 'payment.bank_details.change',
45
+ risk: 'critical',
46
+ receipt_required: true,
47
+ assurance_class: 'class_a',
48
+ match: { protocol: 'mcp', tool: 'change_bank_details' },
49
+ why: 'Changes where future money flows. Treats payee, beneficiary, vendor, and payroll account changes as high-risk by category.',
50
+ execution_binding: {
51
+ required_fields: ['action_type', 'account_holder_id', 'payment_instruction_id', 'bank_account_hash'],
52
+ },
53
+ }),
54
+ Object.freeze({
55
+ id: 'production.deploy',
56
+ label: 'Production deploy',
57
+ action_type: 'deploy.production',
58
+ risk: 'critical',
59
+ receipt_required: true,
60
+ assurance_class: 'quorum',
61
+ match: { protocol: 'mcp', tool: 'deploy_production' },
62
+ why: 'Changes live production behavior. Quorum is the cryptographic two-person rule for hard operational cuts.',
63
+ execution_binding: {
64
+ required_fields: ['action_type', 'repo', 'commit_sha', 'environment', 'artifact_digest'],
65
+ },
66
+ }),
67
+ Object.freeze({
68
+ id: 'permissions.admin_change',
69
+ label: 'Permission or admin change',
70
+ action_type: 'permission.admin.change',
71
+ risk: 'critical',
72
+ receipt_required: true,
73
+ assurance_class: 'quorum',
74
+ match: { protocol: 'mcp', tool: 'change_permissions' },
75
+ why: 'Changes who can act next. Privilege changes deserve stronger proof than the session that requested them.',
76
+ execution_binding: {
77
+ required_fields: ['action_type', 'principal_id', 'role', 'scope'],
78
+ },
79
+ }),
80
+ Object.freeze({
81
+ id: 'data.bulk_export',
82
+ label: 'Bulk data export',
83
+ action_type: 'data.export',
84
+ risk: 'high',
85
+ receipt_required: true,
86
+ assurance_class: 'class_a',
87
+ match: { protocol: 'mcp', tool: 'export_customer_data' },
88
+ why: 'Moves sensitive data out of its system of record. The recipient and purpose must be bound to the approval.',
89
+ execution_binding: {
90
+ required_fields: ['action_type', 'dataset', 'recipient', 'purpose', 'row_count_max'],
91
+ },
92
+ }),
93
+ Object.freeze({
94
+ id: 'records.delete',
95
+ label: 'Record deletion',
96
+ action_type: 'record.delete',
97
+ risk: 'high',
98
+ receipt_required: true,
99
+ assurance_class: 'class_a',
100
+ match: { protocol: 'mcp', tool: 'delete_record' },
101
+ why: 'Destroys or hides state. The record identity and pre-state must be bound before deletion.',
102
+ execution_binding: {
103
+ required_fields: ['action_type', 'record_type', 'record_id', 'before_state_hash'],
104
+ },
105
+ }),
106
+ Object.freeze({
107
+ id: 'regulated.decision_override',
108
+ label: 'Regulated decision override',
109
+ action_type: 'regulated.decision.override',
110
+ risk: 'critical',
111
+ receipt_required: true,
112
+ assurance_class: 'quorum',
113
+ match: { protocol: 'mcp', tool: 'override_regulated_decision' },
114
+ why: 'Changes a decision with legal, benefit, credit, clinical, or safety impact. Requires named accountability.',
115
+ execution_binding: {
116
+ required_fields: ['action_type', 'case_id', 'decision_id', 'subject_id', 'override_reason'],
117
+ },
118
+ }),
119
+ ]);
120
+
121
+ export const DEFAULT_PASS_THROUGH_ACTIONS: readonly ActionPack[] = Object.freeze([
122
+ Object.freeze({
123
+ id: 'observe.read_status',
124
+ label: 'Read-only status',
125
+ action_type: 'read.status',
126
+ receipt_required: false,
127
+ match: { protocol: 'mcp', tool: 'read_status' },
128
+ }),
129
+ ]);
130
+
131
+ export function createDefaultActionRiskManifest({
132
+ includePassThrough = true,
133
+ extraActions = [],
134
+ }: { includePassThrough?: boolean; extraActions?: ActionPack[] } = {}) {
135
+ return {
136
+ '@version': ACTION_RISK_MANIFEST_VERSION,
137
+ actions: [
138
+ ...HIGH_RISK_ACTION_PACKS.map((a) => ({
139
+ ...a,
140
+ match: { ...a.match },
141
+ execution_binding: a.execution_binding
142
+ ? {
143
+ ...a.execution_binding,
144
+ required_fields: [...a.execution_binding.required_fields],
145
+ ...(a.execution_binding.caid_selector
146
+ ? { caid_selector: { ...a.execution_binding.caid_selector } }
147
+ : {}),
148
+ }
149
+ : undefined,
150
+ })),
151
+ ...(includePassThrough ? DEFAULT_PASS_THROUGH_ACTIONS.map((a) => ({ ...a, match: { ...a.match } })) : []),
152
+ ...extraActions,
153
+ ],
154
+ };
155
+ }
156
+
157
+ export const DEFAULT_GATE_MANIFEST = Object.freeze(createDefaultActionRiskManifest());
158
+
159
+ export function highRiskActionTypes(actions = HIGH_RISK_ACTION_PACKS) {
160
+ return actions.filter((a) => a.receipt_required).map((a) => a.action_type);
161
+ }
162
+
163
+ export default {
164
+ ACTION_RISK_MANIFEST_VERSION,
165
+ HIGH_RISK_ACTION_PACKS,
166
+ DEFAULT_PASS_THROUGH_ACTIONS,
167
+ DEFAULT_GATE_MANIFEST,
168
+ createDefaultActionRiskManifest,
169
+ highRiskActionTypes,
170
+ };
@@ -0,0 +1,117 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ /**
3
+ * EMILIA Gate — System-of-Record adapter kit. One enforcement contract shared by
4
+ * every adapter (GitHub, Stripe, Supabase, AWS, ...): map a destructive op to a
5
+ * gate selector + the observed system-of-record fields, run it through
6
+ * gate.run(), and FAIL CLOSED — if the gate refuses, the real client call is
7
+ * never made and we throw EMILIA_RECEIPT_REQUIRED.
8
+ *
9
+ * An op spec is: { selector, observed(params) -> {fields...},
10
+ * actuator?(params, observed) -> {fields...}, perform(client, actuator) -> result }.
11
+ * `observed` must return the same material fields the action pack binds, drawn
12
+ * from the call params (the system-of-record facts), so a receipt for resource A
13
+ * cannot authorize a mutation of resource B.
14
+ */
15
+ import { canonicalize, hashCanonical } from '../execution-binding.js';
16
+
17
+ export { hashCanonical };
18
+
19
+ function deepFreeze(value) {
20
+ if (value && typeof value === 'object' && !Object.isFrozen(value)) {
21
+ for (const child of Object.values(value)) deepFreeze(child);
22
+ Object.freeze(value);
23
+ }
24
+ return value;
25
+ }
26
+
27
+ /** Canonical plain-data snapshot used at the actuator boundary. */
28
+ export function canonicalActuatorObject(value) {
29
+ return deepFreeze(JSON.parse(canonicalize(value)));
30
+ }
31
+
32
+ /** Build an EP-ACTION-RISK-MANIFEST-v0.1 from a frozen action pack (deep-copied). */
33
+ export function manifestFromPack(pack, extraActions = []) {
34
+ return {
35
+ '@version': 'EP-ACTION-RISK-MANIFEST-v0.1',
36
+ actions: [
37
+ ...pack.map((a) => ({
38
+ ...a,
39
+ match: { ...a.match },
40
+ execution_binding: a.execution_binding
41
+ ? { ...a.execution_binding, required_fields: [...a.execution_binding.required_fields] }
42
+ : undefined,
43
+ ...(a.business_authorization
44
+ ? { business_authorization: canonicalActuatorObject(a.business_authorization) }
45
+ : {}),
46
+ })),
47
+ ...extraActions,
48
+ ],
49
+ };
50
+ }
51
+
52
+ /**
53
+ * Create an adapter from a system name + op map.
54
+ * @returns {{ ops:object, OPS:readonly string[], guard:(gate,client,{op,params,receipt})=>Promise<{result,reliance,execution}> }}
55
+ */
56
+ export function createAdapter({ system, ops }) {
57
+ if (!system || !ops || typeof ops !== 'object') throw new Error('createAdapter requires { system, ops }');
58
+ const OPS = Object.freeze(Object.keys(ops));
59
+
60
+ /**
61
+ * @param {object} gate
62
+ * @param {object} client
63
+ */
64
+ async function guard(
65
+ gate,
66
+ client,
67
+ { op, params = {}, receipt = null }: { op?: string; params?: object; receipt?: any } = {},
68
+ ) {
69
+ if (!gate || typeof gate.run !== 'function') throw new Error(`${system} adapter requires an EMILIA Gate (with .run)`);
70
+ const spec = ops[op as string];
71
+ if (!spec) throw new Error(`${system} adapter: unknown op "${op}" (expected one of: ${OPS.join(', ')})`);
72
+ if (!receipt) {
73
+ const refused = await gate.run(
74
+ { selector: spec.selector, receipt: null, observedAction: null },
75
+ () => { throw new Error('unreachable_adapter_effect'); },
76
+ );
77
+ const e = new Error(`EMILIA Gate refused ${system}:${op} — ${refused.authorization.reason}`) as Error & {
78
+ code?: string; status?: any; gate?: any; challenge?: any;
79
+ };
80
+ e.code = 'EMILIA_RECEIPT_REQUIRED';
81
+ e.status = refused.status;
82
+ e.gate = refused.authorization;
83
+ e.challenge = refused.body;
84
+ throw e;
85
+ }
86
+ // Snapshot before any asynchronous verification. Caller-owned params may be
87
+ // mutated while gate.run() awaits evidence/storage; neither the observation
88
+ // nor the eventual provider call may follow that mutable reference.
89
+ const input = canonicalActuatorObject(params);
90
+ const observedAction = canonicalActuatorObject(spec.observed(input));
91
+ // Default to the verified fields only. Operations that need a preimage for a
92
+ // bound digest (SQL, RLS, secret values, queries) must opt in with an explicit
93
+ // actuator() constructor. The unrestricted caller object is never passed.
94
+ const actuator = canonicalActuatorObject(
95
+ typeof spec.actuator === 'function' ? spec.actuator(input, observedAction) : observedAction,
96
+ );
97
+ const out = await gate.run(
98
+ { selector: spec.selector, receipt, observedAction },
99
+ () => spec.perform(client, actuator),
100
+ );
101
+ if (!out.ok) {
102
+ const e = new Error(`EMILIA Gate refused ${system}:${op} — ${out.authorization.reason}`) as Error & {
103
+ code?: string; status?: any; gate?: any; challenge?: any;
104
+ };
105
+ e.code = 'EMILIA_RECEIPT_REQUIRED';
106
+ e.status = out.status;
107
+ e.gate = out.authorization;
108
+ e.challenge = out.body;
109
+ throw e;
110
+ }
111
+ return { result: out.result, reliance: out.packet, execution: out.execution };
112
+ }
113
+
114
+ return { ops, OPS, guard };
115
+ }
116
+
117
+ export default { createAdapter, manifestFromPack, hashCanonical, canonicalActuatorObject };
@@ -0,0 +1,142 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ /**
3
+ * EMILIA Gate — AWS System-of-Record adapter (IAM + network).
4
+ *
5
+ * "Install this before your agent can change cloud permissions or open the
6
+ * network." Wraps the high-blast-radius AWS operations — attach IAM policy,
7
+ * create access key, delete user, and open a security-group ingress — so they
8
+ * never reach AWS without a valid, sufficiently-assured, non-replayed receipt
9
+ * bound to THIS principal/policy/group. Privilege and network changes default
10
+ * to quorum (the two-person rule).
11
+ *
12
+ * import { IAMClient, EC2Client } from '@aws-sdk/...';
13
+ * import { createGate } from '@emilia-protocol/gate';
14
+ * import { createAwsManifest, guardAwsMutation } from '@emilia-protocol/gate/adapters/aws';
15
+ *
16
+ * const gate = createGate({ manifest: createAwsManifest(), trustedKeys: [ISSUER], store: sharedConsumptionStore });
17
+ * // client: { iam: { attachUserPolicy, createAccessKey, deleteUser }, ec2: { authorizeSecurityGroupIngress } }
18
+ * await guardAwsMutation(gate, client, {
19
+ * op: 'iam.attach_policy', params: { user: 'svc-bot', policy_arn: 'arn:aws:iam::aws:policy/AdministratorAccess' }, receipt,
20
+ * });
21
+ */
22
+ import { createAdapter, manifestFromPack } from './_kit.js';
23
+
24
+ /**
25
+ * @typedef {object} AwsIamClient
26
+ * @property {(input: {UserName: string, PolicyArn: string}) => any} attachUserPolicy
27
+ * @property {(input: {UserName: string}) => any} createAccessKey
28
+ * @property {(input: {UserName: string}) => any} deleteUser
29
+ */
30
+ /**
31
+ * @typedef {object} AwsEc2Client
32
+ * @property {(input: {GroupId: string, CidrIp: string, FromPort: number, ToPort: number, IpProtocol: string}) => any} authorizeSecurityGroupIngress
33
+ */
34
+ /** @typedef {{ iam: AwsIamClient, ec2: AwsEc2Client }} AwsClient */
35
+
36
+ export const AWS_ACTION_PACK = Object.freeze([
37
+ Object.freeze({
38
+ id: 'aws.iam.attach_policy', label: 'IAM attach policy', action_type: 'aws.iam.attach_policy',
39
+ risk: 'critical', receipt_required: true, assurance_class: 'quorum',
40
+ match: { protocol: 'aws', tool: 'attach_user_policy' },
41
+ why: 'Grants permissions. Privilege escalation deserves the two-person rule.',
42
+ execution_binding: { required_fields: ['action_type', 'user', 'policy_arn'] },
43
+ }),
44
+ Object.freeze({
45
+ id: 'aws.iam.create_access_key', label: 'IAM create access key', action_type: 'aws.iam.create_access_key',
46
+ risk: 'critical', receipt_required: true, assurance_class: 'class_a',
47
+ match: { protocol: 'aws', tool: 'create_access_key' },
48
+ why: 'Mints long-lived credentials. Bind the user to a named approval.',
49
+ execution_binding: { required_fields: ['action_type', 'user'] },
50
+ }),
51
+ Object.freeze({
52
+ id: 'aws.iam.delete_user', label: 'IAM delete user', action_type: 'aws.iam.delete_user',
53
+ risk: 'high', receipt_required: true, assurance_class: 'class_a',
54
+ match: { protocol: 'aws', tool: 'delete_user' },
55
+ why: 'Destroys an identity. Bind the target user.',
56
+ execution_binding: { required_fields: ['action_type', 'user'] },
57
+ }),
58
+ Object.freeze({
59
+ id: 'aws.ec2.authorize_ingress', label: 'Open security-group ingress', action_type: 'aws.ec2.authorize_ingress',
60
+ risk: 'critical', receipt_required: true, assurance_class: 'quorum',
61
+ match: { protocol: 'aws', tool: 'authorize_security_group_ingress' },
62
+ why: 'Opens the network. Bind group/CIDR/port so 0.0.0.0/0:22 cannot slip through.',
63
+ execution_binding: { required_fields: ['action_type', 'group_id', 'cidr', 'protocol', 'from_port', 'to_port'] },
64
+ }),
65
+ ]);
66
+
67
+ const OPS = {
68
+ 'iam.attach_policy': {
69
+ selector: { protocol: 'aws', tool: 'attach_user_policy' },
70
+ /** @param {{user: string, policy_arn: string}} p */
71
+ observed: (p) => ({ action_type: 'aws.iam.attach_policy', user: p.user, policy_arn: p.policy_arn }),
72
+ /**
73
+ * @param {AwsClient} client
74
+ * @param {{user: string, policy_arn: string}} p
75
+ */
76
+ perform: (client, p) => client.iam.attachUserPolicy({ UserName: p.user, PolicyArn: p.policy_arn }),
77
+ },
78
+ 'iam.create_access_key': {
79
+ selector: { protocol: 'aws', tool: 'create_access_key' },
80
+ /** @param {{user: string}} p */
81
+ observed: (p) => ({ action_type: 'aws.iam.create_access_key', user: p.user }),
82
+ /**
83
+ * @param {AwsClient} client
84
+ * @param {{user: string}} p
85
+ */
86
+ perform: (client, p) => client.iam.createAccessKey({ UserName: p.user }),
87
+ },
88
+ 'iam.delete_user': {
89
+ selector: { protocol: 'aws', tool: 'delete_user' },
90
+ /** @param {{user: string}} p */
91
+ observed: (p) => ({ action_type: 'aws.iam.delete_user', user: p.user }),
92
+ /**
93
+ * @param {AwsClient} client
94
+ * @param {{user: string}} p
95
+ */
96
+ perform: (client, p) => client.iam.deleteUser({ UserName: p.user }),
97
+ },
98
+ 'ec2.authorize_ingress': {
99
+ selector: { protocol: 'aws', tool: 'authorize_security_group_ingress' },
100
+ /** @param {{group_id: string, cidr: string, protocol?: string, from_port: number, to_port?: number}} p */
101
+ observed: (p) => ({
102
+ action_type: 'aws.ec2.authorize_ingress',
103
+ group_id: p.group_id,
104
+ cidr: p.cidr,
105
+ protocol: p.protocol ?? 'tcp',
106
+ from_port: p.from_port,
107
+ to_port: p.to_port ?? p.from_port,
108
+ }),
109
+ /**
110
+ * @param {AwsClient} client
111
+ * @param {{group_id: string, cidr: string, protocol: string, from_port: number, to_port: number}} p
112
+ */
113
+ perform: (client, p) => client.ec2.authorizeSecurityGroupIngress({
114
+ GroupId: p.group_id,
115
+ CidrIp: p.cidr,
116
+ FromPort: p.from_port,
117
+ ToPort: p.to_port,
118
+ IpProtocol: p.protocol,
119
+ }),
120
+ },
121
+ };
122
+
123
+ const adapter = createAdapter({ system: 'aws', ops: OPS });
124
+ export const AWS_OPS = adapter.OPS;
125
+
126
+ /** @param {object[]} extraActions */
127
+ export function createAwsManifest(extraActions = []) {
128
+ return manifestFromPack(AWS_ACTION_PACK, extraActions);
129
+ }
130
+
131
+ /**
132
+ * Guard a high-blast-radius AWS mutation behind the gate.
133
+ * @param {object} gate a gate built with createAwsManifest()
134
+ * @param {AwsClient} client { iam: {attachUserPolicy, createAccessKey, deleteUser}, ec2: {authorizeSecurityGroupIngress} }
135
+ * @param {{ op: string, params?: object, receipt?: any }} args { op, params, receipt }
136
+ * @throws Error{code:'EMILIA_RECEIPT_REQUIRED'} if refused — the call never reaches AWS
137
+ */
138
+ export function guardAwsMutation(gate, client, args) {
139
+ return adapter.guard(gate, client, /** @type {{ op: any, params: any, receipt: any }} */ (args));
140
+ }
141
+
142
+ export default { AWS_ACTION_PACK, AWS_OPS, createAwsManifest, guardAwsMutation };
@@ -0,0 +1,78 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ /**
3
+ * EMILIA Gate — Cloudflare System-of-Record adapter.
4
+ * Guards DNS record delete, zone delete, and WAF/firewall disable so they never
5
+ * reach Cloudflare without a receipt bound to THIS zone. Client injected.
6
+ */
7
+ import { createAdapter, manifestFromPack } from './_kit.js';
8
+
9
+ /**
10
+ * @typedef {object} CloudflareClient
11
+ * @property {(input: {zone: string, recordId: string}) => any} deleteDnsRecord
12
+ * @property {(input: {zone: string}) => any} deleteZone
13
+ * @property {(input: {zone: string, ruleId: string, enabled: boolean}) => any} setFirewallRule
14
+ */
15
+
16
+ export const CLOUDFLARE_ACTION_PACK = Object.freeze([
17
+ Object.freeze({
18
+ id: 'cloudflare.dns.delete', label: 'Delete DNS record', action_type: 'cloudflare.dns.delete',
19
+ risk: 'high', receipt_required: true, assurance_class: 'class_a',
20
+ match: { protocol: 'cloudflare', tool: 'delete_dns_record' },
21
+ why: 'Removing DNS can take a service offline or enable takeover. Bind zone+record.',
22
+ execution_binding: { required_fields: ['action_type', 'zone', 'record_id'] },
23
+ }),
24
+ Object.freeze({
25
+ id: 'cloudflare.zone.delete', label: 'Delete zone', action_type: 'cloudflare.zone.delete',
26
+ risk: 'critical', receipt_required: true, assurance_class: 'quorum',
27
+ match: { protocol: 'cloudflare', tool: 'delete_zone' },
28
+ why: 'Deletes an entire zone. Quorum.',
29
+ execution_binding: { required_fields: ['action_type', 'zone'] },
30
+ }),
31
+ Object.freeze({
32
+ id: 'cloudflare.firewall.disable', label: 'Disable firewall rule', action_type: 'cloudflare.firewall.disable',
33
+ risk: 'critical', receipt_required: true, assurance_class: 'quorum',
34
+ match: { protocol: 'cloudflare', tool: 'set_firewall_rule' },
35
+ why: 'Disabling WAF/firewall opens the perimeter. Quorum + bind zone+rule.',
36
+ execution_binding: { required_fields: ['action_type', 'zone', 'rule_id'] },
37
+ }),
38
+ ]);
39
+
40
+ const OPS = {
41
+ 'dns.delete': {
42
+ selector: { protocol: 'cloudflare', tool: 'delete_dns_record' },
43
+ /** @param {{zone: string, record_id: string}} p */
44
+ observed: (p) => ({ action_type: 'cloudflare.dns.delete', zone: p.zone, record_id: p.record_id }),
45
+ /**
46
+ * @param {CloudflareClient} c
47
+ * @param {{zone: string, record_id: string}} p
48
+ */
49
+ perform: (c, p) => c.deleteDnsRecord({ zone: p.zone, recordId: p.record_id }),
50
+ },
51
+ 'zone.delete': {
52
+ selector: { protocol: 'cloudflare', tool: 'delete_zone' },
53
+ /** @param {{zone: string}} p */
54
+ observed: (p) => ({ action_type: 'cloudflare.zone.delete', zone: p.zone }),
55
+ /**
56
+ * @param {CloudflareClient} c
57
+ * @param {{zone: string}} p
58
+ */
59
+ perform: (c, p) => c.deleteZone({ zone: p.zone }),
60
+ },
61
+ 'firewall.disable': {
62
+ selector: { protocol: 'cloudflare', tool: 'set_firewall_rule' },
63
+ /** @param {{zone: string, rule_id: string}} p */
64
+ observed: (p) => ({ action_type: 'cloudflare.firewall.disable', zone: p.zone, rule_id: p.rule_id }),
65
+ /**
66
+ * @param {CloudflareClient} c
67
+ * @param {{zone: string, rule_id: string}} p
68
+ */
69
+ perform: (c, p) => c.setFirewallRule({ zone: p.zone, ruleId: p.rule_id, enabled: false }),
70
+ },
71
+ };
72
+
73
+ const adapter = createAdapter({ system: 'cloudflare', ops: OPS });
74
+ export const CLOUDFLARE_OPS = adapter.OPS;
75
+ /** @param {object[]} extra */
76
+ export function createCloudflareManifest(extra = []) { return manifestFromPack(CLOUDFLARE_ACTION_PACK, extra); }
77
+ export function guardCloudflareMutation(gate, client, args) { return adapter.guard(gate, client, args); }
78
+ export default { CLOUDFLARE_ACTION_PACK, CLOUDFLARE_OPS, createCloudflareManifest, guardCloudflareMutation };
@@ -0,0 +1,71 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ /**
3
+ * EMILIA Gate — Google Cloud System-of-Record adapter.
4
+ *
5
+ * "Install this before your agent can change cloud permissions or delete a
6
+ * project." Guards the high-blast-radius GCP operations — IAM policy set,
7
+ * service-account key create, project delete, storage bucket delete — so they
8
+ * never reach GCP without a receipt bound to THIS resource/member/role. Client
9
+ * is injected (the @google-cloud SDKs or a thin wrapper).
10
+ */
11
+ import { createAdapter, manifestFromPack } from './_kit.js';
12
+
13
+ export const GCP_ACTION_PACK = Object.freeze([
14
+ Object.freeze({
15
+ id: 'gcp.iam.set_policy', label: 'GCP IAM set policy', action_type: 'gcp.iam.set_policy',
16
+ risk: 'critical', receipt_required: true, assurance_class: 'quorum',
17
+ match: { protocol: 'gcp', tool: 'set_iam_policy' },
18
+ why: 'Grants cloud permissions. Bind resource+member+role; quorum.',
19
+ execution_binding: { required_fields: ['action_type', 'resource', 'member', 'role'] },
20
+ }),
21
+ Object.freeze({
22
+ id: 'gcp.sa_key.create', label: 'GCP service-account key create', action_type: 'gcp.sa_key.create',
23
+ risk: 'critical', receipt_required: true, assurance_class: 'class_a',
24
+ match: { protocol: 'gcp', tool: 'create_service_account_key' },
25
+ why: 'Mints long-lived cloud credentials. Bind the service account.',
26
+ execution_binding: { required_fields: ['action_type', 'service_account'] },
27
+ }),
28
+ Object.freeze({
29
+ id: 'gcp.project.delete', label: 'GCP project delete', action_type: 'gcp.project.delete',
30
+ risk: 'critical', receipt_required: true, assurance_class: 'quorum',
31
+ match: { protocol: 'gcp', tool: 'delete_project' },
32
+ why: 'Deletes an entire project. Quorum.',
33
+ execution_binding: { required_fields: ['action_type', 'project'] },
34
+ }),
35
+ Object.freeze({
36
+ id: 'gcp.storage.bucket_delete', label: 'GCP bucket delete', action_type: 'gcp.storage.bucket_delete',
37
+ risk: 'high', receipt_required: true, assurance_class: 'class_a',
38
+ match: { protocol: 'gcp', tool: 'delete_bucket' },
39
+ why: 'Destroys a storage bucket and its objects. Bind the bucket.',
40
+ execution_binding: { required_fields: ['action_type', 'bucket'] },
41
+ }),
42
+ ]);
43
+
44
+ const OPS = {
45
+ 'iam.set_policy': {
46
+ selector: { protocol: 'gcp', tool: 'set_iam_policy' },
47
+ observed: (p) => ({ action_type: 'gcp.iam.set_policy', resource: p.resource, member: p.member, role: p.role }),
48
+ perform: (c, p) => c.setIamPolicy({ resource: p.resource, member: p.member, role: p.role }),
49
+ },
50
+ 'sa_key.create': {
51
+ selector: { protocol: 'gcp', tool: 'create_service_account_key' },
52
+ observed: (p) => ({ action_type: 'gcp.sa_key.create', service_account: p.service_account }),
53
+ perform: (c, p) => c.createServiceAccountKey({ service_account: p.service_account }),
54
+ },
55
+ 'project.delete': {
56
+ selector: { protocol: 'gcp', tool: 'delete_project' },
57
+ observed: (p) => ({ action_type: 'gcp.project.delete', project: p.project }),
58
+ perform: (c, p) => c.deleteProject({ project: p.project }),
59
+ },
60
+ 'storage.bucket_delete': {
61
+ selector: { protocol: 'gcp', tool: 'delete_bucket' },
62
+ observed: (p) => ({ action_type: 'gcp.storage.bucket_delete', bucket: p.bucket }),
63
+ perform: (c, p) => c.deleteBucket({ bucket: p.bucket }),
64
+ },
65
+ };
66
+
67
+ const adapter = createAdapter({ system: 'gcp', ops: OPS });
68
+ export const GCP_OPS = adapter.OPS;
69
+ export function createGcpManifest(extraActions = []) { return manifestFromPack(GCP_ACTION_PACK, extraActions); }
70
+ export function guardGcpMutation(gate, client, args) { return adapter.guard(gate, client, args); }
71
+ export default { GCP_ACTION_PACK, GCP_OPS, createGcpManifest, guardGcpMutation };