@emilia-protocol/gate 0.10.0 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +91 -0
- package/README.md +272 -0
- package/action-control-manifest.js +3 -268
- package/action-escrow-custodian.js +4 -0
- package/action-escrow-evidence.js +4 -0
- package/action-escrow-package.js +4 -0
- package/action-escrow-postgres.js +4 -0
- package/action-escrow-state.js +4 -0
- package/action-escrow-verifiers.js +4 -0
- package/action-escrow.js +4 -0
- package/action-packs.js +3 -140
- package/adapters/_kit.js +3 -104
- package/adapters/aws.js +3 -108
- package/adapters/cloudflare.js +3 -54
- package/adapters/gcp.js +3 -70
- package/adapters/github.js +3 -109
- package/adapters/jira.js +3 -55
- package/adapters/k8s.js +3 -70
- package/adapters/linear.js +3 -55
- package/adapters/salesforce.js +3 -55
- package/adapters/stripe.js +3 -81
- package/adapters/supabase.js +3 -121
- package/adapters/terraform.js +3 -59
- package/adapters/vercel.js +3 -84
- package/aec-execution.js +3 -312
- package/breakglass.js +3 -582
- package/capability-receipt.js +4 -0
- package/cf1-conformance.js +3 -106
- package/challenge-store.js +3 -69
- package/control-plane.js +3 -340
- package/coverage.js +3 -721
- package/demo.mjs +1 -1
- package/deployment-attestation.js +3 -247
- package/dist/action-control-manifest.d.ts +82 -0
- package/dist/action-control-manifest.d.ts.map +1 -0
- package/dist/action-control-manifest.js +422 -0
- package/dist/action-control-manifest.js.map +1 -0
- package/dist/action-escrow-custodian.d.ts +74 -0
- package/dist/action-escrow-custodian.d.ts.map +1 -0
- package/dist/action-escrow-custodian.js +363 -0
- package/dist/action-escrow-custodian.js.map +1 -0
- package/dist/action-escrow-evidence.d.ts +130 -0
- package/dist/action-escrow-evidence.d.ts.map +1 -0
- package/dist/action-escrow-evidence.js +1012 -0
- package/dist/action-escrow-evidence.js.map +1 -0
- package/dist/action-escrow-package.d.ts +10 -0
- package/dist/action-escrow-package.d.ts.map +1 -0
- package/dist/action-escrow-package.js +1583 -0
- package/dist/action-escrow-package.js.map +1 -0
- package/dist/action-escrow-postgres.d.ts +62 -0
- package/dist/action-escrow-postgres.d.ts.map +1 -0
- package/dist/action-escrow-postgres.js +339 -0
- package/dist/action-escrow-postgres.js.map +1 -0
- package/dist/action-escrow-state.d.ts +141 -0
- package/dist/action-escrow-state.d.ts.map +1 -0
- package/dist/action-escrow-state.js +413 -0
- package/dist/action-escrow-state.js.map +1 -0
- package/dist/action-escrow-verifiers.d.ts +65 -0
- package/dist/action-escrow-verifiers.d.ts.map +1 -0
- package/dist/action-escrow-verifiers.js +421 -0
- package/dist/action-escrow-verifiers.js.map +1 -0
- package/dist/action-escrow.d.ts +112 -0
- package/dist/action-escrow.d.ts.map +1 -0
- package/dist/action-escrow.js +2661 -0
- package/dist/action-escrow.js.map +1 -0
- package/dist/action-packs.d.ts +54 -0
- package/dist/action-packs.d.ts.map +1 -0
- package/dist/action-packs.js +143 -0
- package/dist/action-packs.js.map +1 -0
- package/dist/adapters/_kit.d.ts +50 -0
- package/dist/adapters/_kit.d.ts.map +1 -0
- package/dist/adapters/_kit.js +98 -0
- package/dist/adapters/_kit.js.map +1 -0
- package/dist/adapters/aws.d.ts +158 -0
- package/dist/adapters/aws.d.ts.map +1 -0
- package/dist/adapters/aws.js +136 -0
- package/dist/adapters/aws.js.map +1 -0
- package/dist/adapters/cloudflare.d.ts +116 -0
- package/dist/adapters/cloudflare.d.ts.map +1 -0
- package/dist/adapters/cloudflare.js +75 -0
- package/dist/adapters/cloudflare.js.map +1 -0
- package/dist/adapters/gcp.d.ts +139 -0
- package/dist/adapters/gcp.d.ts.map +1 -0
- package/dist/adapters/gcp.js +69 -0
- package/dist/adapters/gcp.js.map +1 -0
- package/dist/adapters/github.d.ts +123 -0
- package/dist/adapters/github.d.ts.map +1 -0
- package/dist/adapters/github.js +105 -0
- package/dist/adapters/github.js.map +1 -0
- package/dist/adapters/jira.d.ts +109 -0
- package/dist/adapters/jira.d.ts.map +1 -0
- package/dist/adapters/jira.js +54 -0
- package/dist/adapters/jira.js.map +1 -0
- package/dist/adapters/k8s.d.ts +139 -0
- package/dist/adapters/k8s.d.ts.map +1 -0
- package/dist/adapters/k8s.js +69 -0
- package/dist/adapters/k8s.js.map +1 -0
- package/dist/adapters/linear.d.ts +109 -0
- package/dist/adapters/linear.d.ts.map +1 -0
- package/dist/adapters/linear.js +54 -0
- package/dist/adapters/linear.js.map +1 -0
- package/dist/adapters/salesforce.d.ts +109 -0
- package/dist/adapters/salesforce.d.ts.map +1 -0
- package/dist/adapters/salesforce.js +54 -0
- package/dist/adapters/salesforce.js.map +1 -0
- package/dist/adapters/stripe.d.ts +116 -0
- package/dist/adapters/stripe.d.ts.map +1 -0
- package/dist/adapters/stripe.js +77 -0
- package/dist/adapters/stripe.js.map +1 -0
- package/dist/adapters/supabase.d.ts +127 -0
- package/dist/adapters/supabase.d.ts.map +1 -0
- package/dist/adapters/supabase.js +112 -0
- package/dist/adapters/supabase.js.map +1 -0
- package/dist/adapters/terraform.d.ts +109 -0
- package/dist/adapters/terraform.d.ts.map +1 -0
- package/dist/adapters/terraform.js +58 -0
- package/dist/adapters/terraform.js.map +1 -0
- package/dist/adapters/vercel.d.ts +114 -0
- package/dist/adapters/vercel.d.ts.map +1 -0
- package/dist/adapters/vercel.js +81 -0
- package/dist/adapters/vercel.js.map +1 -0
- package/dist/aec-execution.d.ts +107 -0
- package/dist/aec-execution.d.ts.map +1 -0
- package/dist/aec-execution.js +334 -0
- package/dist/aec-execution.js.map +1 -0
- package/dist/breakglass.d.ts +205 -0
- package/dist/breakglass.d.ts.map +1 -0
- package/dist/breakglass.js +627 -0
- package/dist/breakglass.js.map +1 -0
- package/dist/capability-receipt.d.ts +601 -0
- package/dist/capability-receipt.d.ts.map +1 -0
- package/dist/capability-receipt.js +1177 -0
- package/dist/capability-receipt.js.map +1 -0
- package/dist/cf1-conformance.d.ts +83 -0
- package/dist/cf1-conformance.d.ts.map +1 -0
- package/dist/cf1-conformance.js +94 -0
- package/dist/cf1-conformance.js.map +1 -0
- package/dist/challenge-store.d.ts +20 -0
- package/dist/challenge-store.d.ts.map +1 -0
- package/dist/challenge-store.js +62 -0
- package/dist/challenge-store.js.map +1 -0
- package/dist/control-plane.d.ts +136 -0
- package/dist/control-plane.d.ts.map +1 -0
- package/dist/control-plane.js +349 -0
- package/dist/control-plane.js.map +1 -0
- package/dist/coverage.d.ts +156 -0
- package/dist/coverage.d.ts.map +1 -0
- package/dist/coverage.js +768 -0
- package/dist/coverage.js.map +1 -0
- package/dist/deployment-attestation.d.ts +93 -0
- package/dist/deployment-attestation.d.ts.map +1 -0
- package/dist/deployment-attestation.js +262 -0
- package/dist/deployment-attestation.js.map +1 -0
- package/dist/eg1-conformance.d.ts +286 -0
- package/dist/eg1-conformance.d.ts.map +1 -0
- package/dist/eg1-conformance.js +379 -0
- package/dist/eg1-conformance.js.map +1 -0
- package/dist/enterprise.d.ts +88 -0
- package/dist/enterprise.d.ts.map +1 -0
- package/dist/enterprise.js +194 -0
- package/dist/enterprise.js.map +1 -0
- package/dist/evidence-postgres.d.ts +123 -0
- package/dist/evidence-postgres.d.ts.map +1 -0
- package/dist/evidence-postgres.js +343 -0
- package/dist/evidence-postgres.js.map +1 -0
- package/dist/evidence.d.ts +113 -0
- package/dist/evidence.d.ts.map +1 -0
- package/dist/evidence.js +369 -0
- package/dist/evidence.js.map +1 -0
- package/dist/execution-binding.d.ts +49 -0
- package/dist/execution-binding.d.ts.map +1 -0
- package/dist/execution-binding.js +243 -0
- package/dist/execution-binding.js.map +1 -0
- package/dist/formal-runtime-map.d.ts +42 -0
- package/dist/formal-runtime-map.d.ts.map +1 -0
- package/dist/formal-runtime-map.js +23 -0
- package/dist/formal-runtime-map.js.map +1 -0
- package/dist/index.d.ts +1002 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1736 -0
- package/dist/index.js.map +1 -0
- package/dist/key-registry.d.ts +60 -0
- package/dist/key-registry.d.ts.map +1 -0
- package/dist/key-registry.js +144 -0
- package/dist/key-registry.js.map +1 -0
- package/dist/mcp.d.ts +53 -0
- package/dist/mcp.d.ts.map +1 -0
- package/dist/mcp.js +112 -0
- package/dist/mcp.js.map +1 -0
- package/dist/metering.d.ts +80 -0
- package/dist/metering.d.ts.map +1 -0
- package/dist/metering.js +227 -0
- package/dist/metering.js.map +1 -0
- package/dist/metrics.d.ts +68 -0
- package/dist/metrics.d.ts.map +1 -0
- package/dist/metrics.js +242 -0
- package/dist/metrics.js.map +1 -0
- package/dist/network-witness.d.ts +167 -0
- package/dist/network-witness.d.ts.map +1 -0
- package/dist/network-witness.js +520 -0
- package/dist/network-witness.js.map +1 -0
- package/dist/protocol-state.d.ts +141 -0
- package/dist/protocol-state.d.ts.map +1 -0
- package/dist/protocol-state.js +106 -0
- package/dist/protocol-state.js.map +1 -0
- package/dist/receipt-program.d.ts +59 -0
- package/dist/receipt-program.d.ts.map +1 -0
- package/dist/receipt-program.js +1053 -0
- package/dist/receipt-program.js.map +1 -0
- package/dist/reliance-kernel.d.ts +66 -0
- package/dist/reliance-kernel.d.ts.map +1 -0
- package/dist/reliance-kernel.js +103 -0
- package/dist/reliance-kernel.js.map +1 -0
- package/dist/reliance-packet.d.ts +67 -0
- package/dist/reliance-packet.d.ts.map +1 -0
- package/dist/reliance-packet.js +176 -0
- package/dist/reliance-packet.js.map +1 -0
- package/dist/remedy-program-postgres.d.ts +37 -0
- package/dist/remedy-program-postgres.d.ts.map +1 -0
- package/dist/remedy-program-postgres.js +291 -0
- package/dist/remedy-program-postgres.js.map +1 -0
- package/dist/remedy-program-receipt.d.ts +97 -0
- package/dist/remedy-program-receipt.d.ts.map +1 -0
- package/dist/remedy-program-receipt.js +817 -0
- package/dist/remedy-program-receipt.js.map +1 -0
- package/dist/remedy-program.d.ts +76 -0
- package/dist/remedy-program.d.ts.map +1 -0
- package/dist/remedy-program.js +1346 -0
- package/dist/remedy-program.js.map +1 -0
- package/dist/reports/art14.d.ts +101 -0
- package/dist/reports/art14.d.ts.map +1 -0
- package/dist/reports/art14.js +340 -0
- package/dist/reports/art14.js.map +1 -0
- package/dist/reports/assurance-package.d.ts +197 -0
- package/dist/reports/assurance-package.d.ts.map +1 -0
- package/dist/reports/assurance-package.js +313 -0
- package/dist/reports/assurance-package.js.map +1 -0
- package/dist/reports/auditor-workpaper.d.ts +194 -0
- package/dist/reports/auditor-workpaper.d.ts.map +1 -0
- package/dist/reports/auditor-workpaper.js +545 -0
- package/dist/reports/auditor-workpaper.js.map +1 -0
- package/dist/reports/external-verification.d.ts +76 -0
- package/dist/reports/external-verification.d.ts.map +1 -0
- package/dist/reports/external-verification.js +209 -0
- package/dist/reports/external-verification.js.map +1 -0
- package/dist/reports/reperform.d.ts +122 -0
- package/dist/reports/reperform.d.ts.map +1 -0
- package/dist/reports/reperform.js +432 -0
- package/dist/reports/reperform.js.map +1 -0
- package/dist/reports/underwriter.d.ts +127 -0
- package/dist/reports/underwriter.d.ts.map +1 -0
- package/dist/reports/underwriter.js +348 -0
- package/dist/reports/underwriter.js.map +1 -0
- package/dist/retention.d.ts +88 -0
- package/dist/retention.d.ts.map +1 -0
- package/dist/retention.js +90 -0
- package/dist/retention.js.map +1 -0
- package/dist/roster.d.ts +113 -0
- package/dist/roster.d.ts.map +1 -0
- package/dist/roster.js +261 -0
- package/dist/roster.js.map +1 -0
- package/dist/runtime-monitor.d.ts +132 -0
- package/dist/runtime-monitor.d.ts.map +1 -0
- package/dist/runtime-monitor.js +197 -0
- package/dist/runtime-monitor.js.map +1 -0
- package/dist/settlement.d.ts +68 -0
- package/dist/settlement.d.ts.map +1 -0
- package/dist/settlement.js +306 -0
- package/dist/settlement.js.map +1 -0
- package/dist/siem.d.ts +261 -0
- package/dist/siem.d.ts.map +1 -0
- package/dist/siem.js +247 -0
- package/dist/siem.js.map +1 -0
- package/dist/store-postgres.d.ts +107 -0
- package/dist/store-postgres.d.ts.map +1 -0
- package/dist/store-postgres.js +152 -0
- package/dist/store-postgres.js.map +1 -0
- package/dist/store.d.ts +95 -0
- package/dist/store.d.ts.map +1 -0
- package/dist/store.js +202 -0
- package/dist/store.js.map +1 -0
- package/dist/strict-json.d.ts +14 -0
- package/dist/strict-json.d.ts.map +1 -0
- package/dist/strict-json.js +132 -0
- package/dist/strict-json.js.map +1 -0
- package/dist/trust-program-adapters.d.ts +122 -0
- package/dist/trust-program-adapters.d.ts.map +1 -0
- package/dist/trust-program-adapters.js +802 -0
- package/dist/trust-program-adapters.js.map +1 -0
- package/dist/trust-program-postgres.d.ts +41 -0
- package/dist/trust-program-postgres.d.ts.map +1 -0
- package/dist/trust-program-postgres.js +346 -0
- package/dist/trust-program-postgres.js.map +1 -0
- package/dist/trust-program-revocation.d.ts +206 -0
- package/dist/trust-program-revocation.d.ts.map +1 -0
- package/dist/trust-program-revocation.js +600 -0
- package/dist/trust-program-revocation.js.map +1 -0
- package/dist/trust-program.d.ts +197 -0
- package/dist/trust-program.d.ts.map +1 -0
- package/dist/trust-program.js +1351 -0
- package/dist/trust-program.js.map +1 -0
- package/dist/witness-postgres.d.ts +43 -0
- package/dist/witness-postgres.d.ts.map +1 -0
- package/dist/witness-postgres.js +92 -0
- package/dist/witness-postgres.js.map +1 -0
- package/dist/zk-range-proof.d.ts +78 -0
- package/dist/zk-range-proof.d.ts.map +1 -0
- package/dist/zk-range-proof.js +228 -0
- package/dist/zk-range-proof.js.map +1 -0
- package/eg1-conformance.js +3 -404
- package/enterprise.js +3 -180
- package/ep-assure.mjs +1 -0
- package/evidence-postgres.js +3 -356
- package/evidence.js +4 -360
- package/execution-binding.js +3 -212
- package/formal-runtime-map.js +4 -0
- package/index.js +4 -1249
- package/key-registry.js +3 -134
- package/mcp.js +3 -109
- package/metering.js +3 -226
- package/metrics.js +3 -231
- package/network-witness.js +3 -499
- package/package.json +47 -4
- package/receipt-program.js +4 -0
- package/reliance-kernel.js +3 -112
- package/reliance-packet.js +3 -175
- package/remedy-program-postgres.js +4 -0
- package/remedy-program-receipt.js +4 -0
- package/remedy-program.js +4 -0
- package/reports/art14.js +0 -0
- package/reports/assurance-package.js +2 -312
- package/reports/auditor-workpaper.js +3 -537
- package/reports/external-verification.js +3 -222
- package/reports/reperform.js +3 -424
- package/reports/underwriter.js +3 -339
- package/retention.js +3 -84
- package/roster.js +3 -264
- package/runtime-monitor.js +4 -0
- package/settlement.js +3 -299
- package/siem.js +3 -235
- package/src/action-control-manifest.ts +424 -0
- package/src/action-escrow-custodian.ts +427 -0
- package/src/action-escrow-evidence.ts +1178 -0
- package/src/action-escrow-package.ts +1821 -0
- package/src/action-escrow-postgres.ts +366 -0
- package/src/action-escrow-state.ts +498 -0
- package/src/action-escrow-verifiers.ts +484 -0
- package/src/action-escrow.ts +3039 -0
- package/src/action-packs.ts +170 -0
- package/src/adapters/_kit.ts +117 -0
- package/src/adapters/aws.ts +142 -0
- package/src/adapters/cloudflare.ts +78 -0
- package/src/adapters/gcp.ts +71 -0
- package/src/adapters/github.ts +110 -0
- package/src/adapters/jira.ts +56 -0
- package/src/adapters/k8s.ts +71 -0
- package/src/adapters/linear.ts +56 -0
- package/src/adapters/salesforce.ts +56 -0
- package/src/adapters/stripe.ts +82 -0
- package/src/adapters/supabase.ts +122 -0
- package/src/adapters/terraform.ts +60 -0
- package/src/adapters/vercel.ts +85 -0
- package/src/aec-execution.ts +354 -0
- package/src/breakglass.ts +647 -0
- package/src/capability-receipt.ts +1258 -0
- package/src/cf1-conformance.ts +120 -0
- package/src/challenge-store.ts +70 -0
- package/src/control-plane.ts +374 -0
- package/src/coverage.ts +832 -0
- package/src/deployment-attestation.ts +259 -0
- package/src/eg1-conformance.ts +471 -0
- package/src/enterprise.ts +195 -0
- package/src/evidence-postgres.ts +374 -0
- package/src/evidence.ts +367 -0
- package/src/execution-binding.ts +236 -0
- package/src/formal-runtime-map.ts +24 -0
- package/src/index.ts +2122 -0
- package/src/key-registry.ts +150 -0
- package/src/mcp.ts +120 -0
- package/src/metering.ts +237 -0
- package/src/metrics.ts +232 -0
- package/src/network-witness.ts +585 -0
- package/src/protocol-state.ts +143 -0
- package/src/protocol-state.typecheck.ts +94 -0
- package/src/receipt-program.ts +1105 -0
- package/src/reliance-kernel.ts +119 -0
- package/src/reliance-packet.ts +206 -0
- package/src/remedy-program-postgres.ts +367 -0
- package/src/remedy-program-receipt.ts +891 -0
- package/src/remedy-program.ts +1388 -0
- package/src/reports/art14.ts +361 -0
- package/src/reports/assurance-package.ts +330 -0
- package/src/reports/auditor-workpaper.ts +558 -0
- package/src/reports/external-verification.ts +232 -0
- package/src/reports/reperform.ts +441 -0
- package/src/reports/underwriter.ts +356 -0
- package/src/retention.ts +100 -0
- package/src/roster.ts +273 -0
- package/src/runtime-monitor.ts +217 -0
- package/src/settlement.ts +313 -0
- package/src/siem.ts +247 -0
- package/src/store-postgres.ts +167 -0
- package/src/store.ts +214 -0
- package/src/strict-json.ts +115 -0
- package/src/trust-program-adapters.ts +847 -0
- package/src/trust-program-postgres.ts +429 -0
- package/src/trust-program-revocation.ts +751 -0
- package/src/trust-program.ts +1460 -0
- package/src/witness-postgres.ts +106 -0
- package/src/zk-range-proof.ts +250 -0
- package/store-postgres.js +3 -161
- package/store.js +4 -198
- package/strict-json.js +3 -85
- package/trust-program-adapters.js +4 -0
- package/trust-program-postgres.js +4 -0
- package/trust-program-revocation.js +4 -0
- package/trust-program.js +4 -0
- package/witness-postgres.js +3 -96
- package/zk-range-proof.js +4 -0
package/store.js
CHANGED
|
@@ -1,198 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
*
|
|
4
|
-
|
|
5
|
-
* A receipt authorizes ONE action, once. The gate consumes a receipt's
|
|
6
|
-
* identifier the first time it is used; any later presentation of the same
|
|
7
|
-
* receipt is a replay and is refused. The in-memory store is an explicit
|
|
8
|
-
* test/demo opt-in; security-bearing gates use the durable contract below.
|
|
9
|
-
*/
|
|
10
|
-
export class MemoryConsumptionStore {
|
|
11
|
-
constructor() {
|
|
12
|
-
this.durable = false;
|
|
13
|
-
this.ownershipFenced = false;
|
|
14
|
-
this.permanentConsumption = false;
|
|
15
|
-
this.seen = new Set();
|
|
16
|
-
this.reserved = new Set();
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
/** Returns true the FIRST time a key is seen, false on every replay. */
|
|
20
|
-
async consume(key) {
|
|
21
|
-
if (this.seen.has(key) || this.reserved.has(key)) return false;
|
|
22
|
-
this.seen.add(key);
|
|
23
|
-
return true;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
/** Reserve an id while an action is in flight; blocks concurrent replay. */
|
|
27
|
-
async reserve(key) {
|
|
28
|
-
if (this.seen.has(key) || this.reserved.has(key)) return false;
|
|
29
|
-
this.reserved.add(key);
|
|
30
|
-
return true;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/** Commit a reserved id after an external-effect attempt begins. */
|
|
34
|
-
async commit(key) {
|
|
35
|
-
this.reserved.delete(key);
|
|
36
|
-
this.seen.add(key);
|
|
37
|
-
return true;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/** Release only when the caller can prove the external effect never began. */
|
|
41
|
-
async release(key) {
|
|
42
|
-
this.reserved.delete(key);
|
|
43
|
-
return true;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
async has(key) {
|
|
47
|
-
return this.seen.has(key) || this.reserved.has(key);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
get size() {
|
|
51
|
-
return this.seen.size;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
export const DURABLE_CONSUMPTION_VERSION = 'EP-GATE-DURABLE-CONSUMPTION-v2';
|
|
56
|
-
|
|
57
|
-
/** Capability contract required by security-bearing Gate execution paths. */
|
|
58
|
-
export function isSecureConsumptionStore(store) {
|
|
59
|
-
if (!store || typeof store !== 'object') return false;
|
|
60
|
-
return store.durable === true
|
|
61
|
-
&& store.ownershipFenced === true
|
|
62
|
-
&& store.permanentConsumption === true
|
|
63
|
-
&& typeof store.consume === 'function'
|
|
64
|
-
&& typeof store.reserve === 'function'
|
|
65
|
-
&& typeof store.commit === 'function';
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
const COMMITTED_VALUE = 'committed:v2';
|
|
69
|
-
const RESERVED_PREFIX = 'reserved:v2:';
|
|
70
|
-
|
|
71
|
-
function defaultReservationToken() {
|
|
72
|
-
if (typeof globalThis.crypto?.randomUUID !== 'function') {
|
|
73
|
-
throw new Error('secure crypto.randomUUID() is required for durable reservation fencing');
|
|
74
|
-
}
|
|
75
|
-
return globalThis.crypto.randomUUID();
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* Production custody for replay defense: a durable consumption store backed by
|
|
80
|
-
* any shared key-value backend (Redis, Postgres, DynamoDB, ...), so a receipt
|
|
81
|
-
* consumed on one pod/lambda cannot be replayed on another.
|
|
82
|
-
*
|
|
83
|
-
* The backend MUST provide atomic insert-if-absent plus atomic conditional
|
|
84
|
-
* transition and delete. Together they make replay defense and reservation
|
|
85
|
-
* ownership sound under concurrency:
|
|
86
|
-
*
|
|
87
|
-
* backend = {
|
|
88
|
-
* async addIfAbsent(key, value): boolean
|
|
89
|
-
* async compareAndSet(key, expected, replacement): boolean
|
|
90
|
-
* async deleteIfValue(key, expected): boolean
|
|
91
|
-
* async has(key): boolean
|
|
92
|
-
* }
|
|
93
|
-
*
|
|
94
|
-
* State per receipt id is a single ownership-fenced value. A reservation is
|
|
95
|
-
* `reserved:v2:<random token>` and only the store instance holding that token
|
|
96
|
-
* can commit or release it. This prevents a delayed worker from deleting or
|
|
97
|
-
* committing a newer worker's reservation after timeout/failover.
|
|
98
|
-
*
|
|
99
|
-
* Reservations deliberately receive NO TTL. A crash after an external effect
|
|
100
|
-
* has begun is an indeterminate outcome, and automatically reopening the key
|
|
101
|
-
* would permit a duplicate effect. Operators must reconcile abandoned
|
|
102
|
-
* reservations. `ttlSeconds` applies only after a value is committed, when the
|
|
103
|
-
* receipt's own freshness window independently prevents reuse.
|
|
104
|
-
*/
|
|
105
|
-
export function createDurableConsumptionStore(backend, { ttlSeconds, reservationTokenFactory = defaultReservationToken } = {}) {
|
|
106
|
-
for (const m of ['addIfAbsent', 'compareAndSet', 'deleteIfValue', 'has']) {
|
|
107
|
-
if (typeof backend?.[m] !== 'function') {
|
|
108
|
-
throw new Error(`createDurableConsumptionStore: backend must implement async ${m}(). `
|
|
109
|
-
+ 'addIfAbsent and conditional transitions MUST be atomic or replay defense is not fleet-safe.');
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
if (typeof reservationTokenFactory !== 'function') {
|
|
113
|
-
throw new Error('createDurableConsumptionStore: reservationTokenFactory must be a function');
|
|
114
|
-
}
|
|
115
|
-
if (ttlSeconds !== undefined && ttlSeconds !== null
|
|
116
|
-
&& (!Number.isSafeInteger(ttlSeconds) || ttlSeconds <= 0)) {
|
|
117
|
-
throw new Error('createDurableConsumptionStore: ttlSeconds must be a positive safe integer when supplied');
|
|
118
|
-
}
|
|
119
|
-
const opt = ttlSeconds ? { ttlSeconds } : undefined;
|
|
120
|
-
const ownedReservations = new Map();
|
|
121
|
-
|
|
122
|
-
function ownedValue(key) {
|
|
123
|
-
const token = ownedReservations.get(key);
|
|
124
|
-
if (!token) {
|
|
125
|
-
throw new Error(`durable consumption transition refused: this store does not own reservation ${key}`);
|
|
126
|
-
}
|
|
127
|
-
return `${RESERVED_PREFIX}${token}`;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
return {
|
|
131
|
-
durable: backend.durable === true,
|
|
132
|
-
ownershipFenced: true,
|
|
133
|
-
permanentConsumption: ttlSeconds === undefined || ttlSeconds === null,
|
|
134
|
-
retentionSeconds: ttlSeconds ?? null,
|
|
135
|
-
async health() {
|
|
136
|
-
if (typeof backend.health !== 'function') return { ok: false, reason: 'backend_health_unavailable' };
|
|
137
|
-
return backend.health();
|
|
138
|
-
},
|
|
139
|
-
async reserve(key) {
|
|
140
|
-
const token = reservationTokenFactory();
|
|
141
|
-
if (typeof token !== 'string' || token.length < 16) {
|
|
142
|
-
throw new Error('reservationTokenFactory must return an unpredictable string of at least 16 characters');
|
|
143
|
-
}
|
|
144
|
-
const inserted = (await backend.addIfAbsent(key, `${RESERVED_PREFIX}${token}`)) === true;
|
|
145
|
-
if (inserted) ownedReservations.set(key, token);
|
|
146
|
-
return inserted;
|
|
147
|
-
},
|
|
148
|
-
async commit(key) {
|
|
149
|
-
const expected = ownedValue(key);
|
|
150
|
-
const changed = await backend.compareAndSet(key, expected, COMMITTED_VALUE, opt);
|
|
151
|
-
if (changed !== true) {
|
|
152
|
-
throw new Error(`durable consumption commit refused: reservation ownership was lost for ${key}`);
|
|
153
|
-
}
|
|
154
|
-
ownedReservations.delete(key);
|
|
155
|
-
return true;
|
|
156
|
-
},
|
|
157
|
-
async release(key) {
|
|
158
|
-
const expected = ownedValue(key);
|
|
159
|
-
const deleted = await backend.deleteIfValue(key, expected);
|
|
160
|
-
ownedReservations.delete(key);
|
|
161
|
-
if (deleted !== true) {
|
|
162
|
-
throw new Error(`durable consumption release refused: reservation ownership was lost for ${key}`);
|
|
163
|
-
}
|
|
164
|
-
return true;
|
|
165
|
-
},
|
|
166
|
-
async consume(key) { return (await backend.addIfAbsent(key, COMMITTED_VALUE, opt)) === true; },
|
|
167
|
-
async has(key) { return (await backend.has(key)) === true; },
|
|
168
|
-
};
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
/** In-memory reference backend (for tests/single-process). addIfAbsent is atomic in a single thread. */
|
|
172
|
-
export function createMemoryBackend() {
|
|
173
|
-
const map = new Map();
|
|
174
|
-
return {
|
|
175
|
-
durable: false,
|
|
176
|
-
async addIfAbsent(key, value) { if (map.has(key)) return false; map.set(key, value); return true; },
|
|
177
|
-
async compareAndSet(key, expected, replacement) {
|
|
178
|
-
if (map.get(key) !== expected) return false;
|
|
179
|
-
map.set(key, replacement);
|
|
180
|
-
return true;
|
|
181
|
-
},
|
|
182
|
-
async deleteIfValue(key, expected) {
|
|
183
|
-
if (map.get(key) !== expected) return false;
|
|
184
|
-
return map.delete(key);
|
|
185
|
-
},
|
|
186
|
-
async has(key) { return map.has(key); },
|
|
187
|
-
async get(key) { return map.get(key); },
|
|
188
|
-
get size() { return map.size; },
|
|
189
|
-
};
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
export default {
|
|
193
|
-
MemoryConsumptionStore,
|
|
194
|
-
createDurableConsumptionStore,
|
|
195
|
-
createMemoryBackend,
|
|
196
|
-
isSecureConsumptionStore,
|
|
197
|
-
DURABLE_CONSUMPTION_VERSION,
|
|
198
|
-
};
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
// Compatibility entry point for the TypeScript store module.
|
|
3
|
+
export * from './dist/store.js';
|
|
4
|
+
export { default } from './dist/store.js';
|
package/strict-json.js
CHANGED
|
@@ -1,86 +1,4 @@
|
|
|
1
1
|
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
-
//
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
export const MAX_JSON_DEPTH = 64;
|
|
6
|
-
|
|
7
|
-
export function strictJsonGate(raw) {
|
|
8
|
-
if (typeof raw !== 'string') return { ok: false, reason: 'JSON input must be text' };
|
|
9
|
-
try { JSON.parse(raw); } catch { return { ok: false, reason: 'invalid JSON syntax' }; }
|
|
10
|
-
let index = 0;
|
|
11
|
-
const stack = [];
|
|
12
|
-
let reason = null;
|
|
13
|
-
const escapes = { '"': '"', '\\': '\\', '/': '/', b: '\b', f: '\f', n: '\n', r: '\r', t: '\t' };
|
|
14
|
-
|
|
15
|
-
function readString() {
|
|
16
|
-
index += 1;
|
|
17
|
-
let output = '';
|
|
18
|
-
while (index < raw.length) {
|
|
19
|
-
const character = raw[index];
|
|
20
|
-
if (character === '"') { index += 1; return output; }
|
|
21
|
-
if (character !== '\\') { output += character; index += 1; continue; }
|
|
22
|
-
const escape = raw[index + 1];
|
|
23
|
-
if (escape !== 'u') {
|
|
24
|
-
output += escapes[escape] ?? '';
|
|
25
|
-
index += 2;
|
|
26
|
-
continue;
|
|
27
|
-
}
|
|
28
|
-
const first = Number.parseInt(raw.slice(index + 2, index + 6), 16);
|
|
29
|
-
index += 6;
|
|
30
|
-
if (first >= 0xd800 && first <= 0xdbff) {
|
|
31
|
-
if (raw[index] === '\\' && raw[index + 1] === 'u') {
|
|
32
|
-
const second = Number.parseInt(raw.slice(index + 2, index + 6), 16);
|
|
33
|
-
if (second >= 0xdc00 && second <= 0xdfff) {
|
|
34
|
-
output += String.fromCharCode(first, second);
|
|
35
|
-
index += 6;
|
|
36
|
-
continue;
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
reason = 'unpaired high surrogate escape';
|
|
40
|
-
return null;
|
|
41
|
-
}
|
|
42
|
-
if (first >= 0xdc00 && first <= 0xdfff) {
|
|
43
|
-
reason = 'unpaired low surrogate escape';
|
|
44
|
-
return null;
|
|
45
|
-
}
|
|
46
|
-
output += String.fromCharCode(first);
|
|
47
|
-
}
|
|
48
|
-
reason = 'unterminated string';
|
|
49
|
-
return null;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
while (index < raw.length) {
|
|
53
|
-
const character = raw[index];
|
|
54
|
-
if (character === '{') {
|
|
55
|
-
stack.push({ object: true, keys: new Set(), expectsKey: true });
|
|
56
|
-
if (stack.length > MAX_JSON_DEPTH) return { ok: false, reason: `nesting depth exceeds ${MAX_JSON_DEPTH}` };
|
|
57
|
-
index += 1;
|
|
58
|
-
} else if (character === '[') {
|
|
59
|
-
stack.push({ object: false });
|
|
60
|
-
if (stack.length > MAX_JSON_DEPTH) return { ok: false, reason: `nesting depth exceeds ${MAX_JSON_DEPTH}` };
|
|
61
|
-
index += 1;
|
|
62
|
-
} else if (character === '}' || character === ']') {
|
|
63
|
-
stack.pop();
|
|
64
|
-
index += 1;
|
|
65
|
-
} else if (character === ',') {
|
|
66
|
-
const top = stack.at(-1);
|
|
67
|
-
if (top?.object) top.expectsKey = true;
|
|
68
|
-
index += 1;
|
|
69
|
-
} else if (character === '"') {
|
|
70
|
-
const top = stack.at(-1);
|
|
71
|
-
const isKey = Boolean(top?.object && top.expectsKey);
|
|
72
|
-
const value = readString();
|
|
73
|
-
if (reason) return { ok: false, reason };
|
|
74
|
-
if (isKey) {
|
|
75
|
-
if (top.keys.has(value)) return { ok: false, reason: 'duplicate object member name' };
|
|
76
|
-
top.keys.add(value);
|
|
77
|
-
top.expectsKey = false;
|
|
78
|
-
}
|
|
79
|
-
} else {
|
|
80
|
-
index += 1;
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
return { ok: true };
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
export default { strictJsonGate, MAX_JSON_DEPTH };
|
|
2
|
+
// Compatibility entry point for the TypeScript strict-json module.
|
|
3
|
+
export * from './dist/strict-json.js';
|
|
4
|
+
export { default } from './dist/strict-json.js';
|
package/trust-program.js
ADDED
package/witness-postgres.js
CHANGED
|
@@ -1,97 +1,4 @@
|
|
|
1
1
|
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
-
|
|
3
|
-
*
|
|
4
|
-
|
|
5
|
-
* The migration owns synchronization and authorization. Runtime callers get
|
|
6
|
-
* EXECUTE on one SECURITY DEFINER function, not INSERT/UPDATE privileges on the
|
|
7
|
-
* checkpoint table. Database ambiguity is allowed to throw so the witness
|
|
8
|
-
* ingestion kernel can fail closed as `sequence_store_unavailable`.
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
export const PG_WITNESS_SEQUENCE_VERSION = 'EP-GATE-PG-WITNESS-SEQUENCE-v1';
|
|
12
|
-
export const WITNESS_CHECKPOINT_FUNCTION = 'emilia_gate_evidence.advance_network_witness_checkpoint';
|
|
13
|
-
|
|
14
|
-
const DIGEST_RE = /^sha256:[0-9a-f]{64}$/;
|
|
15
|
-
const CLOSED_REASONS = new Set(['statement_replay', 'sequence_rollback', 'sequence_equivocation']);
|
|
16
|
-
|
|
17
|
-
export const WITNESS_SEQUENCE_SQL = Object.freeze({
|
|
18
|
-
advance: `SELECT accepted, reason
|
|
19
|
-
FROM ${WITNESS_CHECKPOINT_FUNCTION}($1, $2, $3::bytea, $4::bigint, $5)`,
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
function scopedId(value, label) {
|
|
23
|
-
if (typeof value !== 'string' || value.length === 0 || value.length > 256
|
|
24
|
-
|| /[\u0000-\u001f\u007f]/.test(value)) {
|
|
25
|
-
throw new Error(`${label} must be a non-empty control-free string of at most 256 characters`);
|
|
26
|
-
}
|
|
27
|
-
return value;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
function streamBytes(value) {
|
|
31
|
-
if (typeof value !== 'string' || value.length > 513) {
|
|
32
|
-
throw new Error('witness streamId is invalid');
|
|
33
|
-
}
|
|
34
|
-
const parts = value.split('\0');
|
|
35
|
-
if (parts.length !== 2 || parts.some((part) => part.length === 0 || part.length > 256
|
|
36
|
-
|| /[\u0000-\u001f\u007f]/.test(part))) {
|
|
37
|
-
throw new Error('witness streamId must contain one witness-id/capture-point separator');
|
|
38
|
-
}
|
|
39
|
-
return Buffer.from(value, 'utf8');
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
function definitiveRow(result) {
|
|
43
|
-
if (!result || result.rowCount !== 1 || !Array.isArray(result.rows)
|
|
44
|
-
|| result.rows.length !== 1 || typeof result.rows[0]?.accepted !== 'boolean') {
|
|
45
|
-
throw new Error('witness checkpoint outcome is unproven');
|
|
46
|
-
}
|
|
47
|
-
const { accepted, reason } = result.rows[0];
|
|
48
|
-
if (accepted) {
|
|
49
|
-
if (reason !== null && reason !== undefined && reason !== '') {
|
|
50
|
-
throw new Error('accepted witness checkpoint carried a refusal reason');
|
|
51
|
-
}
|
|
52
|
-
return { accepted: true, reason: null };
|
|
53
|
-
}
|
|
54
|
-
if (!CLOSED_REASONS.has(reason)) {
|
|
55
|
-
throw new Error('witness checkpoint returned an unknown refusal reason');
|
|
56
|
-
}
|
|
57
|
-
return { accepted: false, reason };
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Create the durable store expected by acceptNetworkWitnessStatement().
|
|
62
|
-
* `query` is a node-postgres style function such as pool.query.bind(pool).
|
|
63
|
-
*/
|
|
64
|
-
export function createPostgresWitnessSequenceStore({ query, tenantId, gateId } = {}) {
|
|
65
|
-
if (typeof query !== 'function') {
|
|
66
|
-
throw new Error('createPostgresWitnessSequenceStore: query must be an async pg-style function');
|
|
67
|
-
}
|
|
68
|
-
const tenant = scopedId(tenantId, 'tenantId');
|
|
69
|
-
const gate = scopedId(gateId, 'gateId');
|
|
70
|
-
return Object.freeze({
|
|
71
|
-
durable: true,
|
|
72
|
-
scope: Object.freeze({ tenantId: tenant, gateId: gate }),
|
|
73
|
-
async advance(streamId, sequence, statementDigest) {
|
|
74
|
-
if (!Number.isSafeInteger(sequence) || sequence < 0) {
|
|
75
|
-
throw new Error('witness sequence must be a non-negative safe integer');
|
|
76
|
-
}
|
|
77
|
-
if (typeof statementDigest !== 'string' || !DIGEST_RE.test(statementDigest)) {
|
|
78
|
-
throw new Error('witness statement digest is invalid');
|
|
79
|
-
}
|
|
80
|
-
const result = await query(WITNESS_SEQUENCE_SQL.advance, [
|
|
81
|
-
tenant,
|
|
82
|
-
gate,
|
|
83
|
-
streamBytes(streamId),
|
|
84
|
-
sequence,
|
|
85
|
-
statementDigest,
|
|
86
|
-
]);
|
|
87
|
-
return definitiveRow(result);
|
|
88
|
-
},
|
|
89
|
-
});
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
export default {
|
|
93
|
-
PG_WITNESS_SEQUENCE_VERSION,
|
|
94
|
-
WITNESS_CHECKPOINT_FUNCTION,
|
|
95
|
-
WITNESS_SEQUENCE_SQL,
|
|
96
|
-
createPostgresWitnessSequenceStore,
|
|
97
|
-
};
|
|
2
|
+
// Compatibility entry point for the TypeScript witness-postgres module.
|
|
3
|
+
export * from './dist/witness-postgres.js';
|
|
4
|
+
export { default } from './dist/witness-postgres.js';
|