@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
package/dist/siem.d.ts ADDED
@@ -0,0 +1,261 @@
1
+ /**
2
+ * EMILIA Gate — SIEM export of the evidence log (EP-GATE-SIEM-EXPORT-v1).
3
+ *
4
+ * Gate decisions must land where the SOC already looks: Splunk, Sentinel,
5
+ * Datadog. Two static, offline mappings over evidence-log entries:
6
+ * - OCSF (JSON object) for OCSF-native pipelines (Amazon Security Lake,
7
+ * Splunk CIM-OCSF, Sentinel ASIM ingestion);
8
+ * - CEF (single line) as the lowest-common-denominator syslog fallback.
9
+ * Pure functions: entry in, event out — no network, no wall clock. Every
10
+ * timestamp in the output comes from the entry itself, so a fixed entry maps
11
+ * to a byte-identical event on every call and every host.
12
+ *
13
+ * OCSF class choice — class_uid 6003 (API Activity, category 6 Application
14
+ * Activity). The gate is a policy-enforcement point in front of a tool/API
15
+ * call: each evidence entry is one attempted API operation with an
16
+ * allow/deny (or executed/failed) disposition, which is exactly what 6003
17
+ * models via status_id. The IAM alternatives fit worse: 3003 Authorize
18
+ * Session models session-privilege grants (no deny activity), and 6004 Web
19
+ * Resource Access Activity is deprecated in current OCSF.
20
+ *
21
+ * Mapping table (evidence entry → OCSF 6003):
22
+ * entry.at (ISO) → time (epoch ms; 0 sentinel if unparseable)
23
+ * entry.kind → activity_name ('decision'|'execution'), activity_id 99 (Other)
24
+ * entry.action → api.operation
25
+ * entry.allow / outcome → status_id 1 Success / 2 Failure (+ status)
26
+ * entry.reason / outcome → status_detail
27
+ * entry.subject → actor.user.uid
28
+ * entry.receipt_id → metadata.correlation_uid
29
+ * entry.hash → metadata.uid (ties the event to the evidence chain)
30
+ * allow → severity_id 1 Informational; refuse/fail → 3 Medium
31
+ * required_tier, selector, seq, prev_hash → unmapped.* (no OCSF slot)
32
+ *
33
+ * A malformed entry NEVER throws out of the mappers: it becomes a structured
34
+ * error event (status Failure, status_detail 'malformed_evidence_entry') so
35
+ * the corruption itself is visible in the SIEM instead of silently dropped.
36
+ */
37
+ export declare const SIEM_EXPORT_VERSION = "EP-GATE-SIEM-EXPORT-v1";
38
+ export declare const SIEM_OCSF_CLASS_UID = 6003;
39
+ /**
40
+ * Map an evidence-log entry to an OCSF API Activity (6003) event object.
41
+ * Static and deterministic: same entry, same object, always. Malformed input
42
+ * yields a structured error event rather than throwing (see module doc).
43
+ * @param {object} entry one record from evidence.all()
44
+ * @returns {object} OCSF-shaped event
45
+ */
46
+ export declare function toOCSF(entry: any): {
47
+ activity_id: number;
48
+ activity_name: string;
49
+ category_uid: number;
50
+ category_name: string;
51
+ class_uid: number;
52
+ class_name: string;
53
+ type_uid: number;
54
+ time: number;
55
+ severity_id: number;
56
+ severity: string;
57
+ status_id: number;
58
+ status: string;
59
+ status_detail: string;
60
+ metadata: {
61
+ version: string;
62
+ log_name: string;
63
+ product: {
64
+ name: string;
65
+ vendor_name: string;
66
+ };
67
+ uid: null;
68
+ correlation_uid: null;
69
+ };
70
+ actor: {
71
+ user: {
72
+ uid: null;
73
+ };
74
+ };
75
+ api: {
76
+ operation: null;
77
+ };
78
+ unmapped: {
79
+ error: string;
80
+ entry_preview: any;
81
+ kind?: undefined;
82
+ required_tier?: undefined;
83
+ selector?: undefined;
84
+ evidence_seq?: undefined;
85
+ prev_hash?: undefined;
86
+ };
87
+ } | {
88
+ activity_id: number;
89
+ activity_name: string | undefined;
90
+ category_uid: number;
91
+ category_name: string;
92
+ class_uid: number;
93
+ class_name: string;
94
+ type_uid: number;
95
+ time: number | undefined;
96
+ severity_id: number;
97
+ severity: string;
98
+ status_id: number;
99
+ status: string;
100
+ status_detail: any;
101
+ metadata: {
102
+ version: string;
103
+ log_name: string;
104
+ product: {
105
+ name: string;
106
+ vendor_name: string;
107
+ };
108
+ uid: any;
109
+ correlation_uid: any;
110
+ };
111
+ actor: {
112
+ user: {
113
+ uid: any;
114
+ };
115
+ };
116
+ api: {
117
+ operation: any;
118
+ };
119
+ unmapped: {
120
+ kind: string | undefined;
121
+ required_tier: any;
122
+ selector: any;
123
+ evidence_seq: any;
124
+ prev_hash: any;
125
+ error?: undefined;
126
+ entry_preview?: undefined;
127
+ };
128
+ };
129
+ /**
130
+ * Map an evidence-log entry to a one-line CEF string (syslog fallback for
131
+ * SIEMs without OCSF ingestion). Same determinism and malformed-input
132
+ * contract as toOCSF.
133
+ * @param {object} entry one record from evidence.all()
134
+ * @returns {string} `CEF:0|...` single line
135
+ */
136
+ export declare function toCEF(entry: any): string;
137
+ /**
138
+ * Create a forwarder that ships evidence entries to a SIEM sink.
139
+ *
140
+ * INVARIANT: SIEM export must NEVER block or crash enforcement. The gate path
141
+ * calls forward() fire-and-forget; a sink that throws, rejects, or is down is
142
+ * recorded on the internal `dropped` counter (exposed via stats()) and NOTHING
143
+ * propagates back to the caller — forward() always resolves, never rejects.
144
+ * This is the inverse of the evidence log's strict mode: the evidence log is
145
+ * the authoritative record and fails closed; the SIEM copy is telemetry and
146
+ * fails open, silently, with an auditable drop count.
147
+ *
148
+ * Configuration errors (unknown format, missing sink) DO throw — at
149
+ * construction time, before anything is on the gate path.
150
+ *
151
+ * @param {object} [o]
152
+ * @param {'ocsf'|'cef'} [o.format='ocsf']
153
+ * @param {function} [o.sink] receives the mapped event (object for ocsf, string for cef); may be async
154
+ * @returns {{ forward(entry): Promise<{delivered:boolean, event:object|string|null}>, stats(): object }}
155
+ */
156
+ export declare function createSiemForwarder({ format, sink }?: {
157
+ format?: 'ocsf' | 'cef';
158
+ sink?: (event: any) => any;
159
+ }): {
160
+ forward: (entry: any) => Promise<{
161
+ delivered: boolean;
162
+ event: string | {
163
+ activity_id: number;
164
+ activity_name: string;
165
+ category_uid: number;
166
+ category_name: string;
167
+ class_uid: number;
168
+ class_name: string;
169
+ type_uid: number;
170
+ time: number;
171
+ severity_id: number;
172
+ severity: string;
173
+ status_id: number;
174
+ status: string;
175
+ status_detail: string;
176
+ metadata: {
177
+ version: string;
178
+ log_name: string;
179
+ product: {
180
+ name: string;
181
+ vendor_name: string;
182
+ };
183
+ uid: null;
184
+ correlation_uid: null;
185
+ };
186
+ actor: {
187
+ user: {
188
+ uid: null;
189
+ };
190
+ };
191
+ api: {
192
+ operation: null;
193
+ };
194
+ unmapped: {
195
+ error: string;
196
+ entry_preview: any;
197
+ kind?: undefined;
198
+ required_tier?: undefined;
199
+ selector?: undefined;
200
+ evidence_seq?: undefined;
201
+ prev_hash?: undefined;
202
+ };
203
+ } | {
204
+ activity_id: number;
205
+ activity_name: string | undefined;
206
+ category_uid: number;
207
+ category_name: string;
208
+ class_uid: number;
209
+ class_name: string;
210
+ type_uid: number;
211
+ time: number | undefined;
212
+ severity_id: number;
213
+ severity: string;
214
+ status_id: number;
215
+ status: string;
216
+ status_detail: any;
217
+ metadata: {
218
+ version: string;
219
+ log_name: string;
220
+ product: {
221
+ name: string;
222
+ vendor_name: string;
223
+ };
224
+ uid: any;
225
+ correlation_uid: any;
226
+ };
227
+ actor: {
228
+ user: {
229
+ uid: any;
230
+ };
231
+ };
232
+ api: {
233
+ operation: any;
234
+ };
235
+ unmapped: {
236
+ kind: string | undefined;
237
+ required_tier: any;
238
+ selector: any;
239
+ evidence_seq: any;
240
+ prev_hash: any;
241
+ error?: undefined;
242
+ entry_preview?: undefined;
243
+ };
244
+ } | null;
245
+ }>;
246
+ stats: () => {
247
+ format: "ocsf" | "cef";
248
+ forwarded: number;
249
+ dropped: number;
250
+ malformed: number;
251
+ };
252
+ };
253
+ declare const _default: {
254
+ SIEM_EXPORT_VERSION: string;
255
+ SIEM_OCSF_CLASS_UID: number;
256
+ toOCSF: typeof toOCSF;
257
+ toCEF: typeof toCEF;
258
+ createSiemForwarder: typeof createSiemForwarder;
259
+ };
260
+ export default _default;
261
+ //# sourceMappingURL=siem.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"siem.d.ts","sourceRoot":"","sources":["../src/siem.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAEH,eAAO,MAAM,mBAAmB,2BAA2B,CAAC;AAC5D,eAAO,MAAM,mBAAmB,OAAO,CAAC;AAkCxC;;;;;;GAMG;AACH,wBAAgB,MAAM,CAAC,KAAK,KAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAwD3B;AAYD;;;;;;GAMG;AACH,wBAAgB,KAAK,CAAC,KAAK,KAAA,UA2B1B;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,mBAAmB,CAAC,EAAE,MAAe,EAAE,IAAI,EAAE,GAAE;IAC7D,MAAM,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IACxB,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,GAAG,CAAC;CACvB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAsCL;;;;;;;;AAED,wBAAgG"}
package/dist/siem.js ADDED
@@ -0,0 +1,247 @@
1
+ // @ts-nocheck
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ /**
4
+ * EMILIA Gate — SIEM export of the evidence log (EP-GATE-SIEM-EXPORT-v1).
5
+ *
6
+ * Gate decisions must land where the SOC already looks: Splunk, Sentinel,
7
+ * Datadog. Two static, offline mappings over evidence-log entries:
8
+ * - OCSF (JSON object) for OCSF-native pipelines (Amazon Security Lake,
9
+ * Splunk CIM-OCSF, Sentinel ASIM ingestion);
10
+ * - CEF (single line) as the lowest-common-denominator syslog fallback.
11
+ * Pure functions: entry in, event out — no network, no wall clock. Every
12
+ * timestamp in the output comes from the entry itself, so a fixed entry maps
13
+ * to a byte-identical event on every call and every host.
14
+ *
15
+ * OCSF class choice — class_uid 6003 (API Activity, category 6 Application
16
+ * Activity). The gate is a policy-enforcement point in front of a tool/API
17
+ * call: each evidence entry is one attempted API operation with an
18
+ * allow/deny (or executed/failed) disposition, which is exactly what 6003
19
+ * models via status_id. The IAM alternatives fit worse: 3003 Authorize
20
+ * Session models session-privilege grants (no deny activity), and 6004 Web
21
+ * Resource Access Activity is deprecated in current OCSF.
22
+ *
23
+ * Mapping table (evidence entry → OCSF 6003):
24
+ * entry.at (ISO) → time (epoch ms; 0 sentinel if unparseable)
25
+ * entry.kind → activity_name ('decision'|'execution'), activity_id 99 (Other)
26
+ * entry.action → api.operation
27
+ * entry.allow / outcome → status_id 1 Success / 2 Failure (+ status)
28
+ * entry.reason / outcome → status_detail
29
+ * entry.subject → actor.user.uid
30
+ * entry.receipt_id → metadata.correlation_uid
31
+ * entry.hash → metadata.uid (ties the event to the evidence chain)
32
+ * allow → severity_id 1 Informational; refuse/fail → 3 Medium
33
+ * required_tier, selector, seq, prev_hash → unmapped.* (no OCSF slot)
34
+ *
35
+ * A malformed entry NEVER throws out of the mappers: it becomes a structured
36
+ * error event (status Failure, status_detail 'malformed_evidence_entry') so
37
+ * the corruption itself is visible in the SIEM instead of silently dropped.
38
+ */
39
+ export const SIEM_EXPORT_VERSION = 'EP-GATE-SIEM-EXPORT-v1';
40
+ export const SIEM_OCSF_CLASS_UID = 6003; // API Activity
41
+ const OCSF_SCHEMA_VERSION = '1.1.0';
42
+ const CATEGORY_UID = 6; // Application Activity
43
+ const PRODUCT = { name: 'EMILIA Gate', vendor_name: 'Emilia Protocol' };
44
+ const PREVIEW_MAX = 256;
45
+ /**
46
+ * Shape-check an evidence entry and derive the disposition. An entry is
47
+ * mappable only if it carries a parseable timestamp AND a verdict (a decision's
48
+ * `allow` boolean or an execution's `outcome` string) — anything else is
49
+ * treated as malformed and surfaced as an error event, never a throw.
50
+ */
51
+ function classifyEntry(entry) {
52
+ if (!entry || typeof entry !== 'object' || Array.isArray(entry))
53
+ return { valid: false };
54
+ const timeMs = typeof entry.at === 'string' ? Date.parse(entry.at) : NaN;
55
+ const hasVerdict = typeof entry.allow === 'boolean' || typeof entry.outcome === 'string';
56
+ if (!Number.isFinite(timeMs) || !hasVerdict)
57
+ return { valid: false };
58
+ const kind = entry.kind === 'execution' ? 'execution' : 'decision';
59
+ const success = typeof entry.allow === 'boolean' ? entry.allow === true : entry.outcome === 'executed';
60
+ return { valid: true, kind, success, timeMs };
61
+ }
62
+ /** Bounded, throw-proof rendering of an unmappable entry for the error event. */
63
+ function safePreview(entry) {
64
+ let s;
65
+ try {
66
+ s = typeof entry === 'string' ? entry : JSON.stringify(entry);
67
+ }
68
+ catch {
69
+ s = '[unserializable]';
70
+ }
71
+ if (s == null)
72
+ s = String(entry);
73
+ return s.replace(/[\r\n]+/g, ' ').slice(0, PREVIEW_MAX);
74
+ }
75
+ /**
76
+ * Map an evidence-log entry to an OCSF API Activity (6003) event object.
77
+ * Static and deterministic: same entry, same object, always. Malformed input
78
+ * yields a structured error event rather than throwing (see module doc).
79
+ * @param {object} entry one record from evidence.all()
80
+ * @returns {object} OCSF-shaped event
81
+ */
82
+ export function toOCSF(entry) {
83
+ const c = classifyEntry(entry);
84
+ if (!c.valid) {
85
+ return {
86
+ activity_id: 0,
87
+ activity_name: 'Unknown',
88
+ category_uid: CATEGORY_UID,
89
+ category_name: 'Application Activity',
90
+ class_uid: SIEM_OCSF_CLASS_UID,
91
+ class_name: 'API Activity',
92
+ type_uid: SIEM_OCSF_CLASS_UID * 100 + 0,
93
+ // No trustworthy timestamp inside the entry; 0 sentinel, never the wall
94
+ // clock — the mapping stays pure and the bad entry stays evident.
95
+ time: 0,
96
+ severity_id: 3,
97
+ severity: 'Medium',
98
+ status_id: 2,
99
+ status: 'Failure',
100
+ status_detail: 'malformed_evidence_entry',
101
+ metadata: { version: OCSF_SCHEMA_VERSION, log_name: SIEM_EXPORT_VERSION, product: PRODUCT, uid: null, correlation_uid: null },
102
+ actor: { user: { uid: null } },
103
+ api: { operation: null },
104
+ unmapped: { error: 'malformed_evidence_entry', entry_preview: safePreview(entry) },
105
+ };
106
+ }
107
+ return {
108
+ activity_id: 99,
109
+ activity_name: c.kind,
110
+ category_uid: CATEGORY_UID,
111
+ category_name: 'Application Activity',
112
+ class_uid: SIEM_OCSF_CLASS_UID,
113
+ class_name: 'API Activity',
114
+ type_uid: SIEM_OCSF_CLASS_UID * 100 + 99,
115
+ time: c.timeMs,
116
+ severity_id: c.success ? 1 : 3,
117
+ severity: c.success ? 'Informational' : 'Medium',
118
+ status_id: c.success ? 1 : 2,
119
+ status: c.success ? 'Success' : 'Failure',
120
+ status_detail: entry.reason ?? entry.outcome ?? null,
121
+ metadata: {
122
+ version: OCSF_SCHEMA_VERSION,
123
+ log_name: SIEM_EXPORT_VERSION,
124
+ product: PRODUCT,
125
+ uid: entry.hash ?? null,
126
+ correlation_uid: entry.receipt_id ?? null,
127
+ },
128
+ actor: { user: { uid: entry.subject ?? null } },
129
+ api: { operation: entry.action ?? null },
130
+ unmapped: {
131
+ kind: c.kind,
132
+ required_tier: entry.required_tier ?? null,
133
+ selector: entry.selector ?? null,
134
+ evidence_seq: Number.isFinite(entry.seq) ? entry.seq : null,
135
+ prev_hash: entry.prev_hash ?? null,
136
+ },
137
+ };
138
+ }
139
+ // CEF escaping per the ArcSight CEF spec: prefix fields escape backslash and
140
+ // pipe; extension values escape backslash and equals. Newlines are collapsed
141
+ // in both — a CEF record is one line, always.
142
+ function escPrefix(v) {
143
+ return String(v).replace(/\\/g, '\\\\').replace(/\|/g, '\\|').replace(/[\r\n]+/g, ' ');
144
+ }
145
+ function escExt(v) {
146
+ return String(v).replace(/\\/g, '\\\\').replace(/=/g, '\\=').replace(/[\r\n]+/g, ' ');
147
+ }
148
+ /**
149
+ * Map an evidence-log entry to a one-line CEF string (syslog fallback for
150
+ * SIEMs without OCSF ingestion). Same determinism and malformed-input
151
+ * contract as toOCSF.
152
+ * @param {object} entry one record from evidence.all()
153
+ * @returns {string} `CEF:0|...` single line
154
+ */
155
+ export function toCEF(entry) {
156
+ const c = classifyEntry(entry);
157
+ if (!c.valid) {
158
+ const ext = [
159
+ 'act=error',
160
+ 'outcome=malformed_evidence_entry',
161
+ `msg=${escExt(safePreview(entry))}`,
162
+ `cs4=${escExt(SIEM_EXPORT_VERSION)}`, 'cs4Label=export_version',
163
+ ].join(' ');
164
+ return `CEF:0|EmiliaProtocol|Gate|1|gate.malformed|malformed evidence entry|5|${ext}`;
165
+ }
166
+ const verdictWord = c.kind === 'execution'
167
+ ? (c.success ? 'executed' : 'failed')
168
+ : (c.success ? 'allowed' : 'refused');
169
+ const signatureId = `gate.${c.kind}.${c.success ? 'allow' : 'deny'}`;
170
+ const name = `${entry.action ?? 'unknown_action'} ${verdictWord}`;
171
+ const severity = c.success ? 3 : 7;
172
+ const ext = [`end=${c.timeMs}`, `act=${c.success ? 'allow' : 'deny'}`];
173
+ const reason = entry.reason ?? entry.outcome;
174
+ if (reason != null)
175
+ ext.push(`outcome=${escExt(reason)}`);
176
+ if (entry.subject != null)
177
+ ext.push(`suser=${escExt(entry.subject)}`);
178
+ if (entry.receipt_id != null)
179
+ ext.push(`cs1=${escExt(entry.receipt_id)}`, 'cs1Label=receipt_id');
180
+ if (entry.hash != null)
181
+ ext.push(`cs2=${escExt(entry.hash)}`, 'cs2Label=evidence_hash');
182
+ if (entry.required_tier != null)
183
+ ext.push(`cs3=${escExt(entry.required_tier)}`, 'cs3Label=required_tier');
184
+ ext.push(`cs4=${escExt(SIEM_EXPORT_VERSION)}`, 'cs4Label=export_version');
185
+ if (Number.isFinite(entry.seq))
186
+ ext.push(`cn1=${entry.seq}`, 'cn1Label=evidence_seq');
187
+ return `CEF:0|EmiliaProtocol|Gate|1|${escPrefix(signatureId)}|${escPrefix(name)}|${severity}|${ext.join(' ')}`;
188
+ }
189
+ /**
190
+ * Create a forwarder that ships evidence entries to a SIEM sink.
191
+ *
192
+ * INVARIANT: SIEM export must NEVER block or crash enforcement. The gate path
193
+ * calls forward() fire-and-forget; a sink that throws, rejects, or is down is
194
+ * recorded on the internal `dropped` counter (exposed via stats()) and NOTHING
195
+ * propagates back to the caller — forward() always resolves, never rejects.
196
+ * This is the inverse of the evidence log's strict mode: the evidence log is
197
+ * the authoritative record and fails closed; the SIEM copy is telemetry and
198
+ * fails open, silently, with an auditable drop count.
199
+ *
200
+ * Configuration errors (unknown format, missing sink) DO throw — at
201
+ * construction time, before anything is on the gate path.
202
+ *
203
+ * @param {object} [o]
204
+ * @param {'ocsf'|'cef'} [o.format='ocsf']
205
+ * @param {function} [o.sink] receives the mapped event (object for ocsf, string for cef); may be async
206
+ * @returns {{ forward(entry): Promise<{delivered:boolean, event:object|string|null}>, stats(): object }}
207
+ */
208
+ export function createSiemForwarder({ format = 'ocsf', sink } = {}) {
209
+ if (format !== 'ocsf' && format !== 'cef') {
210
+ throw new Error(`EMILIA Gate SIEM: unknown format "${format}" (expected 'ocsf' or 'cef')`);
211
+ }
212
+ if (typeof sink !== 'function') {
213
+ throw new Error('EMILIA Gate SIEM: a sink function is required');
214
+ }
215
+ // Rebind to a locally-scoped const: `sink` the parameter is typed
216
+ // `function|undefined` (it's optional in the JSDoc signature above), and
217
+ // that widened type is what closures below would otherwise capture even
218
+ // though the throw guard just proved it's a function for the lifetime of
219
+ // this forwarder. No behavior change, just handing the closure the type
220
+ // the guard already guarantees.
221
+ /** @type {function} */
222
+ const sinkFn = sink;
223
+ const counts = { forwarded: 0, dropped: 0, malformed: 0 };
224
+ async function forward(entry) {
225
+ let event = null;
226
+ try {
227
+ if (!classifyEntry(entry).valid)
228
+ counts.malformed += 1;
229
+ event = format === 'cef' ? toCEF(entry) : toOCSF(entry);
230
+ await sinkFn(event);
231
+ counts.forwarded += 1;
232
+ return { delivered: true, event };
233
+ }
234
+ catch {
235
+ // Sink failure (or any unexpected mapper failure): counted, never
236
+ // propagated — enforcement must not depend on SIEM availability.
237
+ counts.dropped += 1;
238
+ return { delivered: false, event };
239
+ }
240
+ }
241
+ function stats() {
242
+ return { format, forwarded: counts.forwarded, dropped: counts.dropped, malformed: counts.malformed };
243
+ }
244
+ return { forward, stats };
245
+ }
246
+ export default { SIEM_EXPORT_VERSION, SIEM_OCSF_CLASS_UID, toOCSF, toCEF, createSiemForwarder };
247
+ //# sourceMappingURL=siem.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"siem.js","sourceRoot":"","sources":["../src/siem.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,107 @@
1
+ /**
2
+ * EMILIA Gate — reference DURABLE consumption backend: Postgres
3
+ * (EP-GATE-PG-CONSUMPTION-v2).
4
+ *
5
+ * Replay defense that survives restarts. This module implements the backend
6
+ * contract consumed by `createDurableConsumptionStore` in ./store.js:
7
+ *
8
+ * backend = {
9
+ * async addIfAbsent(key, value, { ttlSeconds }?) : boolean // true iff inserted
10
+ * async compareAndSet(key, expected, replacement, { ttlSeconds }?) : boolean
11
+ * async deleteIfValue(key, expected) : boolean
12
+ * async has(key) : boolean
13
+ * }
14
+ *
15
+ * plus a `cleanupExpired(now)` garbage-collection statement.
16
+ *
17
+ * Each transition is one SQL statement. `addIfAbsent` decides first use;
18
+ * `compareAndSet` and `deleteIfValue` bind commit/release to the opaque owner of
19
+ * the current reservation. There is no read-then-write interval in which a
20
+ * delayed worker can overwrite or remove a newer worker's reservation.
21
+ *
22
+ * FAIL-CLOSED CONTRACT: if the injected `query` THROWS (connection down,
23
+ * timeout, constraint other than the PK, ...) the error PROPAGATES to the
24
+ * caller — nothing here catches it. The gate must refuse an action when
25
+ * one-time-use cannot be proven; a backend error is NEVER treated as
26
+ * not-consumed (which would admit replays during an outage) and never treated
27
+ * as consumed-silently (which would mask the outage as a replay verdict).
28
+ * Likewise, an EXPIRED row that cleanup has not yet removed still refuses:
29
+ * TTL expiry is garbage collection, never a grant — the gate already rejects
30
+ * stale receipts on freshness, so nothing is lost by refusing conservatively.
31
+ *
32
+ * Deterministic by construction: the pg-style `query(text, params)` function
33
+ * and the clock (`now`) are both injected, so tests run against an in-memory
34
+ * fake with real ON CONFLICT semantics — no network, no database.
35
+ */
36
+ export declare const PG_CONSUMPTION_VERSION = "EP-GATE-PG-CONSUMPTION-v2";
37
+ /** Single consumption table. Timestamps are epoch milliseconds (BIGINT) so the
38
+ * injected JS clock maps 1:1 onto column values with no timezone ambiguity. */
39
+ export declare const CONSUMPTION_TABLE = "ep_gate_consumption";
40
+ export declare const CONSUMPTION_TABLE_DDL = "CREATE TABLE IF NOT EXISTS ep_gate_consumption (\n consumption_key TEXT PRIMARY KEY,\n state TEXT NOT NULL,\n consumed_at BIGINT NOT NULL,\n expires_at BIGINT\n);\nCREATE INDEX IF NOT EXISTS ep_gate_consumption_expires_idx\n ON ep_gate_consumption (expires_at) WHERE expires_at IS NOT NULL;";
41
+ /** The exact statements the backend issues — exported for transparency and so
42
+ * a fake client can implement them without parsing SQL. */
43
+ export declare const CONSUMPTION_SQL: {
44
+ health: string;
45
+ /** $1 key, $2 state, $3 consumed_at ms, $4 expires_at ms|null. rowCount 1 = consumed, 0 = replay. */
46
+ addIfAbsent: string;
47
+ /** $1 key, $2 expected state, $3 replacement, $4 consumed_at ms, $5 expires_at ms|null. */
48
+ compareAndSet: string;
49
+ /** $1 key, $2 expected state. */
50
+ deleteIfValue: string;
51
+ /** $1 key. Any row — even an expired one — counts as consumed until cleaned. */
52
+ has: string;
53
+ /** $1 now ms. Removes ONLY rows whose TTL has elapsed; NULL expires_at never expires. */
54
+ cleanupExpired: string;
55
+ };
56
+ /**
57
+ * Create the Postgres consumption backend.
58
+ * @param {{ query?: (text: string, params: any[]) => Promise<{ rowCount: number, rows?: any[] }>, now?: number|function }} [o]
59
+ * `query` is a pg-style query function (e.g. `pool.query.bind(pool)`). Injected
60
+ * so tests need no database. MUST throw on failure — errors propagate (fail
61
+ * closed). `now` is the injected clock (ms or () => ms).
62
+ * @returns backend conforming to createDurableConsumptionStore, plus cleanupExpired(now).
63
+ */
64
+ export declare function createPostgresBackend({ query, now, }?: {
65
+ query?: (text: string, params: any[]) => Promise<{
66
+ rowCount: number;
67
+ rows?: any[];
68
+ }>;
69
+ now?: number | (() => number);
70
+ }): {
71
+ durable: boolean;
72
+ health(): Promise<{
73
+ ok: boolean;
74
+ version: string;
75
+ }>;
76
+ /** True iff THIS call inserted the row — the atomic consumed-vs-replay decision. */
77
+ addIfAbsent(key: any, value: any, opt: any): Promise<boolean>;
78
+ /** Ownership-fenced reserved -> committed transition. */
79
+ compareAndSet(key: any, expected: any, replacement: any, opt: any): Promise<boolean>;
80
+ /** Remove only the reservation owned by the caller. */
81
+ deleteIfValue(key: any, expected: any): Promise<boolean>;
82
+ /** Present = consumed. Expired-but-uncleaned rows still count (conservative). */
83
+ has(key: any): Promise<boolean>;
84
+ /** Garbage-collect rows whose TTL elapsed. Returns the number removed. */
85
+ cleanupExpired(at: any): Promise<number>;
86
+ };
87
+ declare const _default: {
88
+ createPostgresBackend: typeof createPostgresBackend;
89
+ CONSUMPTION_TABLE_DDL: string;
90
+ CONSUMPTION_TABLE: string;
91
+ CONSUMPTION_SQL: {
92
+ health: string;
93
+ /** $1 key, $2 state, $3 consumed_at ms, $4 expires_at ms|null. rowCount 1 = consumed, 0 = replay. */
94
+ addIfAbsent: string;
95
+ /** $1 key, $2 expected state, $3 replacement, $4 consumed_at ms, $5 expires_at ms|null. */
96
+ compareAndSet: string;
97
+ /** $1 key, $2 expected state. */
98
+ deleteIfValue: string;
99
+ /** $1 key. Any row — even an expired one — counts as consumed until cleaned. */
100
+ has: string;
101
+ /** $1 now ms. Removes ONLY rows whose TTL has elapsed; NULL expires_at never expires. */
102
+ cleanupExpired: string;
103
+ };
104
+ PG_CONSUMPTION_VERSION: string;
105
+ };
106
+ export default _default;
107
+ //# sourceMappingURL=store-postgres.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store-postgres.d.ts","sourceRoot":"","sources":["../src/store-postgres.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAEH,eAAO,MAAM,sBAAsB,8BAA8B,CAAC;AAElE;+EAC+E;AAC/E,eAAO,MAAM,iBAAiB,wBAAwB,CAAC;AAEvD,eAAO,MAAM,qBAAqB,+TAOmC,CAAC;AAEtE;2DAC2D;AAC3D,eAAO,MAAM,eAAe;;IAK1B,qGAAqG;;IAGrG,2FAA2F;;IAG3F,iCAAiC;;IAEjC,gFAAgF;;IAEhF,yFAAyF;;CAG1F,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,EACpC,KAAK,EACL,GAAc,GACf,GAAE;IACD,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,GAAG,EAAE,CAAA;KAAE,CAAC,CAAC;IACrF,GAAG,CAAC,EAAE,MAAM,GAAG,CAAC,MAAM,MAAM,CAAC,CAAC;CAC1B;;;;;;IAkCF,oFAAoF;;IAWpF,yDAAyD;;IASzD,uDAAuD;;IASvD,iFAAiF;;IAMjF,0EAA0E;;EAO7E;;;;;;;QAzGC,qGAAqG;;QAGrG,2FAA2F;;QAG3F,iCAAiC;;QAEjC,gFAAgF;;QAEhF,yFAAyF;;;;;AAiG3F,wBAA4H"}