@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
@@ -1,357 +1,4 @@
1
1
  // SPDX-License-Identifier: Apache-2.0
2
- /**
3
- * EMILIA Gate production evidence backend for Postgres.
4
- *
5
- * The deployment SQL exposes one SECURITY DEFINER append function. That
6
- * function locks the tenant/gate/stream head, checks the caller's expected
7
- * head, inserts one immutable record, and advances the head in the same SQL
8
- * statement transaction. Runtime roles receive SELECT and EXECUTE only; they
9
- * cannot insert, update, delete, or truncate evidence tables directly.
10
- *
11
- * Database errors and malformed driver responses always propagate on the
12
- * write path. A storage outage must never be mistaken for a successful append
13
- * or an ordinary contention retry.
14
- */
15
-
16
- import {
17
- canonicalEvidenceJson,
18
- verifyEvidenceRecord,
19
- } from './evidence.js';
20
-
21
- export const PG_EVIDENCE_VERSION = 'EP-GATE-PG-EVIDENCE-v1';
22
- export const EVIDENCE_SCHEMA = 'emilia_gate_evidence';
23
- export const EVIDENCE_RECORDS_TABLE = `${EVIDENCE_SCHEMA}.records`;
24
- export const EVIDENCE_HEADS_TABLE = `${EVIDENCE_SCHEMA}.heads`;
25
- export const EVIDENCE_APPEND_FUNCTION = `${EVIDENCE_SCHEMA}.append_record`;
26
-
27
- const HEX_256 = /^[0-9a-f]{64}$/;
28
- // evidence.js permits 1 MiB of raw string/key bytes. JSON control-character
29
- // escaping can expand those bytes by up to 6x, plus bounded container syntax.
30
- const MAX_CANONICAL_BYTES = 8 * 1024 * 1024;
31
-
32
- /** Exact statements issued by the adapter, exported for audit and test fakes. */
33
- export const EVIDENCE_SQL = Object.freeze({
34
- health: `SELECT
35
- to_regclass('${EVIDENCE_RECORDS_TABLE}') IS NOT NULL AS records_ready,
36
- to_regclass('${EVIDENCE_HEADS_TABLE}') IS NOT NULL AS heads_ready,
37
- to_regprocedure('${EVIDENCE_APPEND_FUNCTION}(text,text,text,text,jsonb,text)') IS NOT NULL AS append_ready,
38
- CASE WHEN to_regclass('${EVIDENCE_RECORDS_TABLE}') IS NULL THEN FALSE
39
- ELSE has_table_privilege(current_user, to_regclass('${EVIDENCE_RECORDS_TABLE}'), 'SELECT') END AS can_read_records,
40
- CASE WHEN to_regclass('${EVIDENCE_HEADS_TABLE}') IS NULL THEN FALSE
41
- ELSE has_table_privilege(current_user, to_regclass('${EVIDENCE_HEADS_TABLE}'), 'SELECT') END AS can_read_heads,
42
- CASE WHEN to_regclass('${EVIDENCE_RECORDS_TABLE}') IS NULL THEN FALSE ELSE (
43
- has_table_privilege(current_user, to_regclass('${EVIDENCE_RECORDS_TABLE}'), 'INSERT')
44
- OR has_table_privilege(current_user, to_regclass('${EVIDENCE_RECORDS_TABLE}'), 'UPDATE')
45
- OR has_table_privilege(current_user, to_regclass('${EVIDENCE_RECORDS_TABLE}'), 'DELETE')
46
- OR has_table_privilege(current_user, to_regclass('${EVIDENCE_RECORDS_TABLE}'), 'TRUNCATE')
47
- ) END AS can_write_records_directly,
48
- CASE WHEN to_regclass('${EVIDENCE_HEADS_TABLE}') IS NULL THEN FALSE ELSE (
49
- has_table_privilege(current_user, to_regclass('${EVIDENCE_HEADS_TABLE}'), 'INSERT')
50
- OR has_table_privilege(current_user, to_regclass('${EVIDENCE_HEADS_TABLE}'), 'UPDATE')
51
- OR has_table_privilege(current_user, to_regclass('${EVIDENCE_HEADS_TABLE}'), 'DELETE')
52
- OR has_table_privilege(current_user, to_regclass('${EVIDENCE_HEADS_TABLE}'), 'TRUNCATE')
53
- ) END AS can_write_heads_directly,
54
- CASE WHEN to_regprocedure('${EVIDENCE_APPEND_FUNCTION}(text,text,text,text,jsonb,text)') IS NULL THEN FALSE
55
- ELSE has_function_privilege(current_user,
56
- to_regprocedure('${EVIDENCE_APPEND_FUNCTION}(text,text,text,text,jsonb,text)'), 'EXECUTE') END AS can_append`,
57
-
58
- readHead: `SELECT head_seq AS seq, head_hash AS hash
59
- FROM ${EVIDENCE_HEADS_TABLE}
60
- WHERE tenant_id = $1 AND gate_id = $2 AND stream_id = $3`,
61
-
62
- getById: `SELECT seq, record_id, prev_hash, hash, record
63
- FROM ${EVIDENCE_RECORDS_TABLE}
64
- WHERE tenant_id = $1 AND gate_id = $2 AND stream_id = $3 AND record_id = $4`,
65
-
66
- readAll: `SELECT seq, record_id, prev_hash, hash, record
67
- FROM ${EVIDENCE_RECORDS_TABLE}
68
- WHERE tenant_id = $1 AND gate_id = $2 AND stream_id = $3
69
- ORDER BY seq ASC`,
70
-
71
- // One SELECT gives verify() a single MVCC snapshot of rows and head.
72
- snapshot: `SELECT
73
- COALESCE((
74
- SELECT jsonb_agg(jsonb_build_object(
75
- 'seq', r.seq,
76
- 'record_id', r.record_id,
77
- 'prev_hash', r.prev_hash,
78
- 'hash', r.hash,
79
- 'record', r.record
80
- ) ORDER BY r.seq ASC)
81
- FROM ${EVIDENCE_RECORDS_TABLE} r
82
- WHERE r.tenant_id = $1 AND r.gate_id = $2 AND r.stream_id = $3
83
- ), '[]'::jsonb) AS record_rows,
84
- (
85
- SELECT CASE WHEN h.head_seq = -1 THEN NULL ELSE jsonb_build_object(
86
- 'seq', h.head_seq, 'hash', h.head_hash
87
- ) END
88
- FROM ${EVIDENCE_HEADS_TABLE} h
89
- WHERE h.tenant_id = $1 AND h.gate_id = $2 AND h.stream_id = $3
90
- ) AS head`,
91
-
92
- appendIfHead: `SELECT ${EVIDENCE_APPEND_FUNCTION}($1, $2, $3, $4, $5::jsonb, $6) AS appended`,
93
- });
94
-
95
- function assertScopedId(value, label, { minLength = 1, maxLength = 256 } = {}) {
96
- if (typeof value !== 'string' || value.length < minLength
97
- || value.length > maxLength || value.includes('\0')) {
98
- throw new Error(`${label} must be a string of ${minLength} to ${maxLength} characters`);
99
- }
100
- return value;
101
- }
102
-
103
- function queryRows(result, operation) {
104
- if (!result || !Number.isInteger(result.rowCount) || result.rowCount < 0
105
- || !Array.isArray(result.rows) || result.rows.length !== result.rowCount) {
106
- throw new Error(`${operation}: malformed Postgres result; storage outcome is unproven`);
107
- }
108
- return result.rows;
109
- }
110
-
111
- function parseSequence(value, operation, { sentinel = false } = {}) {
112
- let parsed = value;
113
- if (typeof value === 'string' && /^-?(0|[1-9][0-9]*)$/.test(value)) parsed = Number(value);
114
- const minimum = sentinel ? -1 : 0;
115
- if (!Number.isSafeInteger(parsed) || parsed < minimum) {
116
- throw new Error(`${operation}: Postgres returned an invalid evidence sequence`);
117
- }
118
- return parsed;
119
- }
120
-
121
- function parseJson(value, operation) {
122
- if (typeof value !== 'string') return value;
123
- try {
124
- return JSON.parse(value);
125
- } catch {
126
- throw new Error(`${operation}: Postgres returned malformed JSON`);
127
- }
128
- }
129
-
130
- function normalizeHead(value, operation) {
131
- const head = parseJson(value, operation);
132
- if (head === null || head === undefined) return null;
133
- if (!head || typeof head !== 'object' || Array.isArray(head)) {
134
- throw new Error(`${operation}: Postgres returned a malformed evidence head`);
135
- }
136
- const seq = parseSequence(head.seq, operation, { sentinel: true });
137
- if (seq === -1) {
138
- if (head.hash !== null && head.hash !== undefined) {
139
- throw new Error(`${operation}: empty evidence head has a hash`);
140
- }
141
- return null;
142
- }
143
- if (typeof head.hash !== 'string' || !HEX_256.test(head.hash)) {
144
- throw new Error(`${operation}: Postgres returned a malformed evidence head hash`);
145
- }
146
- return { seq, hash: head.hash };
147
- }
148
-
149
- function normalizeRecordRow(value, operation) {
150
- const row = parseJson(value, operation);
151
- if (!row || typeof row !== 'object' || Array.isArray(row)) {
152
- throw new Error(`${operation}: Postgres returned a malformed evidence row`);
153
- }
154
- const seq = parseSequence(row.seq, operation);
155
- const record = parseJson(row.record, operation);
156
- if (!record || typeof record !== 'object' || Array.isArray(record)
157
- || record.seq !== seq
158
- || record.record_id !== row.record_id
159
- || record.prev_hash !== row.prev_hash
160
- || record.hash !== row.hash) {
161
- throw new Error(`${operation}: evidence row metadata does not match its record`);
162
- }
163
- return structuredClone(record);
164
- }
165
-
166
- function canonicalAppendPayload(record, expectedHeadHash) {
167
- if (expectedHeadHash !== null && (typeof expectedHeadHash !== 'string' || !HEX_256.test(expectedHeadHash))) {
168
- throw new Error('appendIfHead: expected head must be null or a lowercase SHA-256 hash');
169
- }
170
- if (!verifyEvidenceRecord(record, { atomicRequired: true })) {
171
- throw new Error('appendIfHead: record is not a valid canonical atomic evidence record');
172
- }
173
- if (expectedHeadHash === null) {
174
- if (record.seq !== 0 || record.prev_hash !== 'genesis') {
175
- throw new Error('appendIfHead: genesis append has an invalid sequence or predecessor');
176
- }
177
- } else if (record.seq < 1 || record.prev_hash !== expectedHeadHash) {
178
- throw new Error('appendIfHead: record does not extend the expected head');
179
- }
180
-
181
- let persisted;
182
- try {
183
- persisted = JSON.parse(JSON.stringify(record));
184
- } catch {
185
- throw new Error('appendIfHead: record is not losslessly JSON-serializable');
186
- }
187
- if (!persisted || typeof persisted !== 'object' || Array.isArray(persisted)
188
- || canonicalEvidenceJson(persisted) !== canonicalEvidenceJson(record)
189
- || !verifyEvidenceRecord(persisted, { atomicRequired: true })) {
190
- throw new Error('appendIfHead: record is not losslessly JSON-serializable');
191
- }
192
-
193
- const { hash: _hash, ...body } = persisted;
194
- const canonicalBody = canonicalEvidenceJson(body);
195
- if (typeof canonicalBody !== 'string' || Buffer.byteLength(canonicalBody, 'utf8') > MAX_CANONICAL_BYTES) {
196
- throw new Error('appendIfHead: canonical evidence body exceeds the Postgres limit');
197
- }
198
- return { canonicalBody, persisted };
199
- }
200
-
201
- function verifyHistory(records, head) {
202
- const recordIds = new Set();
203
- const sequences = new Set();
204
- let previous = 'genesis';
205
-
206
- for (let index = 0; index < records.length; index++) {
207
- const record = records[index];
208
- if (sequences.has(record.seq)) return { ok: false, at: record.seq, reason: 'fork_detected' };
209
- sequences.add(record.seq);
210
- if (record.seq !== index) return { ok: false, at: index, reason: 'sequence_gap_or_rollback' };
211
- if (record.prev_hash !== previous) {
212
- return { ok: false, at: index, reason: 'fork_or_predecessor_mismatch' };
213
- }
214
- if (recordIds.has(record.record_id)) {
215
- return { ok: false, at: index, reason: 'duplicate_record_id' };
216
- }
217
- if (!verifyEvidenceRecord(record, { atomicRequired: true })) {
218
- return { ok: false, at: index, reason: 'hash_mismatch_or_malformed_record' };
219
- }
220
- recordIds.add(record.record_id);
221
- previous = record.hash;
222
- }
223
-
224
- const expectedHead = records.length === 0
225
- ? null
226
- : { seq: records.length - 1, hash: previous };
227
- if ((expectedHead === null && head !== null)
228
- || (expectedHead !== null && (head === null
229
- || head.seq !== expectedHead.seq || head.hash !== expectedHead.hash))) {
230
- return { ok: false, reason: 'head_rollback_or_mismatch' };
231
- }
232
- return { ok: true, length: records.length, head: expectedHead?.hash ?? null };
233
- }
234
-
235
- /**
236
- * Create a tenant-and-gate-bound backend for createAtomicEvidenceLog().
237
- *
238
- * `query` is a node-postgres style function such as `pool.query.bind(pool)`.
239
- * The migration must be installed and the connection role must inherit or SET
240
- * ROLE to `emilia_gate_evidence_runtime`.
241
- */
242
- export function createPostgresEvidenceBackend({ query, tenantId, gateId } = {}) {
243
- if (typeof query !== 'function') {
244
- throw new Error('createPostgresEvidenceBackend: query must be an async pg-style function that throws on failure');
245
- }
246
- const tenant = assertScopedId(tenantId, 'tenantId');
247
- const gate = assertScopedId(gateId, 'gateId');
248
- const scope = Object.freeze({ tenantId: tenant, gateId: gate });
249
- const scopeParams = (streamId) => [tenant, gate, assertScopedId(streamId, 'streamId')];
250
-
251
- async function readHead(streamId) {
252
- const rows = queryRows(await query(EVIDENCE_SQL.readHead, scopeParams(streamId)), 'readHead');
253
- if (rows.length > 1) throw new Error('readHead: Postgres returned multiple scoped heads');
254
- return rows.length === 0 ? null : normalizeHead(rows[0], 'readHead');
255
- }
256
-
257
- async function getById(streamId, recordId) {
258
- assertScopedId(recordId, 'recordId', { minLength: 16 });
259
- const rows = queryRows(
260
- await query(EVIDENCE_SQL.getById, [...scopeParams(streamId), recordId]),
261
- 'getById',
262
- );
263
- if (rows.length > 1) throw new Error('getById: Postgres returned duplicate scoped record IDs');
264
- return rows.length === 0 ? null : normalizeRecordRow(rows[0], 'getById');
265
- }
266
-
267
- async function appendIfHead(streamId, expectedHeadHash, record) {
268
- const params = scopeParams(streamId);
269
- const { canonicalBody, persisted } = canonicalAppendPayload(record, expectedHeadHash);
270
- const rows = queryRows(
271
- await query(EVIDENCE_SQL.appendIfHead, [
272
- ...params,
273
- expectedHeadHash,
274
- persisted,
275
- canonicalBody,
276
- ]),
277
- 'appendIfHead',
278
- );
279
- if (rows.length !== 1 || typeof rows[0]?.appended !== 'boolean') {
280
- throw new Error('appendIfHead: Postgres did not return a definitive append verdict');
281
- }
282
- return rows[0].appended;
283
- }
284
-
285
- async function readAll(streamId) {
286
- const rows = queryRows(await query(EVIDENCE_SQL.readAll, scopeParams(streamId)), 'readAll');
287
- return rows.map((row) => normalizeRecordRow(row, 'readAll'));
288
- }
289
-
290
- async function readSnapshot(streamId) {
291
- const rows = queryRows(await query(EVIDENCE_SQL.snapshot, scopeParams(streamId)), 'verify');
292
- if (rows.length !== 1) throw new Error('verify: Postgres did not return one scoped snapshot');
293
- const recordRows = parseJson(rows[0].record_rows, 'verify');
294
- if (!Array.isArray(recordRows)) throw new Error('verify: Postgres returned malformed evidence history');
295
- return {
296
- records: recordRows.map((row) => normalizeRecordRow(row, 'verify')),
297
- head: normalizeHead(rows[0].head, 'verify'),
298
- };
299
- }
300
-
301
- return {
302
- durable: true,
303
- persisted: true,
304
- strict: true,
305
- forkAware: true,
306
- atomicAppend: true,
307
- appendOnly: true,
308
- version: PG_EVIDENCE_VERSION,
309
- scope,
310
- readHead,
311
- head: readHead,
312
- getById,
313
- appendIfHead,
314
- readAll,
315
- all: readAll,
316
- async verify(streamId) {
317
- try {
318
- const snapshot = await readSnapshot(streamId);
319
- return verifyHistory(snapshot.records, snapshot.head);
320
- } catch {
321
- return { ok: false, reason: 'backend_read_failed_or_malformed' };
322
- }
323
- },
324
- async health() {
325
- const rows = queryRows(await query(EVIDENCE_SQL.health, []), 'health');
326
- if (rows.length !== 1) throw new Error('health: Postgres did not return one readiness row');
327
- const checks = {
328
- recordsReady: rows[0].records_ready === true,
329
- headsReady: rows[0].heads_ready === true,
330
- appendReady: rows[0].append_ready === true,
331
- canReadRecords: rows[0].can_read_records === true,
332
- canReadHeads: rows[0].can_read_heads === true,
333
- noDirectRecordWrites: rows[0].can_write_records_directly === false,
334
- noDirectHeadWrites: rows[0].can_write_heads_directly === false,
335
- canAppend: rows[0].can_append === true,
336
- };
337
- return {
338
- ok: Object.values(checks).every(Boolean),
339
- version: PG_EVIDENCE_VERSION,
340
- scope,
341
- checks,
342
- };
343
- },
344
- };
345
- }
346
-
347
- const postgresEvidence = {
348
- createPostgresEvidenceBackend,
349
- EVIDENCE_SQL,
350
- EVIDENCE_SCHEMA,
351
- EVIDENCE_RECORDS_TABLE,
352
- EVIDENCE_HEADS_TABLE,
353
- EVIDENCE_APPEND_FUNCTION,
354
- PG_EVIDENCE_VERSION,
355
- };
356
-
357
- export default postgresEvidence;
2
+ // Compatibility entry point for the TypeScript evidence-postgres module.
3
+ export * from './dist/evidence-postgres.js';
4
+ export { default } from './dist/evidence-postgres.js';