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