@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
|
@@ -0,0 +1,432 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
/**
|
|
3
|
+
* EMILIA Gate — independent re-performance verifier (EP-GATE-REPERFORMANCE-v1).
|
|
4
|
+
*
|
|
5
|
+
* The auditor's "trust nothing, recompute everything" tool. Re-performance is
|
|
6
|
+
* the highest form of audit evidence: instead of reading the deployer's report
|
|
7
|
+
* and believing it, the auditor takes the raw evidence entries and REDOES the
|
|
8
|
+
* work — rebuilds the hash chain link by link and checks it with the evidence
|
|
9
|
+
* log's own verifier, cryptographically re-verifies every receipt / signoff /
|
|
10
|
+
* quorum document an entry carries, recomputes the decision counts from
|
|
11
|
+
* scratch, and diffs those recomputed numbers against what a report pack
|
|
12
|
+
* claims. Vendor logs assert; this recomputes.
|
|
13
|
+
*
|
|
14
|
+
* INDEPENDENCE BY CONSTRUCTION: counts are recomputed here from the raw
|
|
15
|
+
* entries — this module deliberately does NOT import metering.js or any report
|
|
16
|
+
* builder, so a bug in a report builder cannot hide from its own cross-check.
|
|
17
|
+
* The only imports are the primitives being re-driven: the evidence log's real
|
|
18
|
+
* verify() and the protocol verifiers (verifyEmiliaReceipt /
|
|
19
|
+
* verifyWebAuthnSignoff / verifyQuorum).
|
|
20
|
+
*
|
|
21
|
+
* FAIL CLOSED everywhere:
|
|
22
|
+
* - one broken chain link fails the chain from that point — the remainder is
|
|
23
|
+
* not vouched for;
|
|
24
|
+
* - one failed re-verification is a NAMED failure ({hash, reason}), never
|
|
25
|
+
* absorbed into a pass count;
|
|
26
|
+
* - an entry that references a receipt but does not carry the verifiable
|
|
27
|
+
* material is counted `not_reverifiable` — never silently passed;
|
|
28
|
+
* - a reported pack of unknown @version is refused, never fuzzily matched.
|
|
29
|
+
*
|
|
30
|
+
* HONESTY BOUNDARY (carried inside the artifact): this SUPPORTS an auditor's
|
|
31
|
+
* re-performance procedure. It does not conclude, opine, or certify — and it
|
|
32
|
+
* cannot establish log COMPLETENESS (a chain rewritten in full, or entries
|
|
33
|
+
* withheld before supply, is invisible from the entries alone; anchor the head
|
|
34
|
+
* hash externally to close that), nor runtime freshness / one-time consumption
|
|
35
|
+
* (properties of the moment of decision, not re-performable after the fact).
|
|
36
|
+
*
|
|
37
|
+
* Deterministic: pure over (entries, issuerKeys); time enters only through the
|
|
38
|
+
* injectable `now` (generated_at). No sampling, no randomness.
|
|
39
|
+
*/
|
|
40
|
+
import crypto from 'node:crypto';
|
|
41
|
+
import { createEvidenceLog } from '../evidence.js';
|
|
42
|
+
import { validatePinnedQuorumPolicy, verifyEmiliaReceipt } from '@emilia-protocol/require-receipt';
|
|
43
|
+
import { verifyQuorum, verifyWebAuthnSignoff } from '@emilia-protocol/verify';
|
|
44
|
+
export const REPERFORMANCE_VERSION = 'EP-GATE-REPERFORMANCE-v1';
|
|
45
|
+
// Wire-format identifiers of the packs compareToReported() can cross-check.
|
|
46
|
+
// Restated locally — NOT imported from the builders — so this module remains a
|
|
47
|
+
// standalone auditor tool with zero dependency on the code it checks.
|
|
48
|
+
const USAGE_PACK_VERSION = 'EP-GATE-USAGE-v1';
|
|
49
|
+
const UNDERWRITER_PACK_VERSION = 'EP-GATE-UNDERWRITER-ATTESTATION-v1';
|
|
50
|
+
/** Deterministic key-sorted copy — output is byte-stable regardless of entry order. */
|
|
51
|
+
function sortedCounts(obj) {
|
|
52
|
+
const out = {};
|
|
53
|
+
for (const k of Object.keys(obj).sort())
|
|
54
|
+
out[k] = obj[k];
|
|
55
|
+
return out;
|
|
56
|
+
}
|
|
57
|
+
/** The checks a verifier reported false, as one stable, named string. */
|
|
58
|
+
function failingChecks(checks) {
|
|
59
|
+
const bad = Object.keys(checks || {}).filter((k) => checks[k] === false).sort();
|
|
60
|
+
return bad.length ? bad.join('+') : 'unspecified';
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* The verifiable payloads an entry CARRIES (not the verification RESULTS the
|
|
64
|
+
* gate recorded about them — `tier_evidence` / `rejected` are the gate's own
|
|
65
|
+
* conclusions and are deliberately ignored: re-performance trusts nothing the
|
|
66
|
+
* gate concluded, only material it can re-verify itself).
|
|
67
|
+
*
|
|
68
|
+
* Recognized carriers:
|
|
69
|
+
* - entry.receipt full EP-RECEIPT-v1 document
|
|
70
|
+
* - entry.signoff / payload.signoff WebAuthn device-signoff evidence,
|
|
71
|
+
* with the approver key at entry.approver_public_key or
|
|
72
|
+
* receipt.payload.approver_public_key
|
|
73
|
+
* - entry.quorum / payload.quorum full EP-QUORUM-v1 document
|
|
74
|
+
*/
|
|
75
|
+
function collectMaterial(e) {
|
|
76
|
+
const out = [];
|
|
77
|
+
const receipt = e.receipt;
|
|
78
|
+
const payload = receipt && typeof receipt === 'object' && receipt.payload
|
|
79
|
+
&& typeof receipt.payload === 'object' ? receipt.payload : null;
|
|
80
|
+
if (receipt !== undefined && receipt !== null)
|
|
81
|
+
out.push({ type: 'receipt', doc: receipt });
|
|
82
|
+
const signoff = e.signoff ?? payload?.signoff;
|
|
83
|
+
if (signoff !== undefined && signoff !== null) {
|
|
84
|
+
out.push({
|
|
85
|
+
type: 'signoff',
|
|
86
|
+
doc: signoff,
|
|
87
|
+
key: e.approver_public_key ?? payload?.approver_public_key ?? null,
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
const quorum = e.quorum ?? payload?.quorum;
|
|
91
|
+
if (quorum !== undefined && quorum !== null)
|
|
92
|
+
out.push({ type: 'quorum', doc: quorum });
|
|
93
|
+
return out;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Re-verify one carried payload. Returns null on pass, a NAMED reason on fail.
|
|
97
|
+
* Freshness is intentionally not re-enforced (maxAgeSec: 0): it was a runtime
|
|
98
|
+
* property of the decision moment and cannot be re-performed at audit time —
|
|
99
|
+
* what IS re-performed is the cryptography (signature, issuer trust, action
|
|
100
|
+
* binding, ceremony checks).
|
|
101
|
+
*/
|
|
102
|
+
function spkiFingerprint(value) {
|
|
103
|
+
try {
|
|
104
|
+
const key = crypto.createPublicKey({ key: Buffer.from(value, 'base64url'), format: 'der', type: 'spki' });
|
|
105
|
+
return crypto.createHash('sha256').update(key.export({ type: 'spki', format: 'der' })).digest('hex');
|
|
106
|
+
}
|
|
107
|
+
catch {
|
|
108
|
+
return null;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
function pinnedApproverEntry(approverKeys, approver, carriedKey = null) {
|
|
112
|
+
if (!approverKeys || typeof approverKeys !== 'object' || Array.isArray(approverKeys))
|
|
113
|
+
return null;
|
|
114
|
+
const candidates = Object.values(approverKeys).filter((entry) => entry && typeof entry === 'object'
|
|
115
|
+
&& entry.approver_id === approver && typeof entry.public_key === 'string');
|
|
116
|
+
if (carriedKey) {
|
|
117
|
+
const fingerprint = spkiFingerprint(carriedKey);
|
|
118
|
+
const matches = candidates.filter((entry) => fingerprint && spkiFingerprint(entry.public_key) === fingerprint);
|
|
119
|
+
return matches.length === 1 ? matches[0] : null;
|
|
120
|
+
}
|
|
121
|
+
return candidates.length === 1 ? candidates[0] : null;
|
|
122
|
+
}
|
|
123
|
+
function reverifyMaterial(m, { issuerKeys, action, rpId, allowedOrigins, approverKeys, quorumPolicy, quorumPolicies, }) {
|
|
124
|
+
if (m.type === 'receipt') {
|
|
125
|
+
const r = verifyEmiliaReceipt(m.doc, {
|
|
126
|
+
trustedKeys: issuerKeys, allowInlineKey: false, action, maxAgeSec: 0,
|
|
127
|
+
});
|
|
128
|
+
return r.ok ? null : `receipt:${r.reason}`;
|
|
129
|
+
}
|
|
130
|
+
if (m.type === 'signoff') {
|
|
131
|
+
if (typeof rpId !== 'string' || !rpId || !Array.isArray(allowedOrigins) || allowedOrigins.length === 0) {
|
|
132
|
+
return 'signoff:relying_party_scope_unpinned';
|
|
133
|
+
}
|
|
134
|
+
const approver = m.doc?.context?.approver;
|
|
135
|
+
const entry = pinnedApproverEntry(approverKeys, approver, m.key);
|
|
136
|
+
if (!entry)
|
|
137
|
+
return 'signoff:approver_key_unpinned_or_ambiguous';
|
|
138
|
+
const r = verifyWebAuthnSignoff(m.doc, entry.public_key, { rpId, allowedOrigins });
|
|
139
|
+
return r.valid ? null : `signoff:${r.error ? `error:${r.error}` : `checks_failed:${failingChecks(r.checks)}`}`;
|
|
140
|
+
}
|
|
141
|
+
if (m.type === 'quorum') {
|
|
142
|
+
if (typeof rpId !== 'string' || !rpId || !Array.isArray(allowedOrigins) || allowedOrigins.length === 0) {
|
|
143
|
+
return 'quorum:relying_party_scope_unpinned';
|
|
144
|
+
}
|
|
145
|
+
const pinnedPolicy = (quorumPolicies && typeof quorumPolicies === 'object' ? quorumPolicies[action] : null)
|
|
146
|
+
|| quorumPolicy;
|
|
147
|
+
const policy = validatePinnedQuorumPolicy(pinnedPolicy);
|
|
148
|
+
if (!policy.ok)
|
|
149
|
+
return `quorum:${policy.reason}`;
|
|
150
|
+
const members = Array.isArray(m.doc?.members) ? m.doc.members.map((member) => {
|
|
151
|
+
const entry = pinnedApproverEntry(approverKeys, member?.signoff?.context?.approver, member?.approver_public_key);
|
|
152
|
+
return entry ? { ...member, approver_public_key: entry.public_key } : null;
|
|
153
|
+
}) : [];
|
|
154
|
+
if (members.length === 0 || members.some((member) => !member))
|
|
155
|
+
return 'quorum:approver_key_unpinned_or_ambiguous';
|
|
156
|
+
const r = verifyQuorum({ ...m.doc, policy: policy.policy, members }, { rpId, allowedOrigins });
|
|
157
|
+
return r.valid ? null : `quorum:checks_failed:${failingChecks(r.checks)}`;
|
|
158
|
+
}
|
|
159
|
+
/* c8 ignore next */
|
|
160
|
+
return `unknown_material:${m.type}`; // unreachable; fail closed regardless
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Re-perform the evidence: rebuild the chain, re-verify carried cryptographic
|
|
164
|
+
* material, recompute the counts. Async because the chain is rebuilt through
|
|
165
|
+
* the evidence log's own (async) record().
|
|
166
|
+
*
|
|
167
|
+
* The entries MUST be the complete log from genesis (`evidence.all()` or a
|
|
168
|
+
* full export). A partial slice fails the chain (fail closed) because its
|
|
169
|
+
* first link cannot chain from 'genesis'.
|
|
170
|
+
*
|
|
171
|
+
* Chain method — drives evidence.js's REAL verify(), twice over:
|
|
172
|
+
* 1. every supplied entry body (its own seq/prev_hash included, its hash
|
|
173
|
+
* stripped) is re-recorded into a fresh createEvidenceLog(), which
|
|
174
|
+
* recomputes the canonical-JSON sha256 for that exact body; a recomputed
|
|
175
|
+
* hash that differs from the SUPPLIED hash is a tampered/forged entry —
|
|
176
|
+
* broken from that point;
|
|
177
|
+
* 2. the rebuilt log's own verify() then walks the whole chain, catching
|
|
178
|
+
* link-level attacks the per-entry recompute cannot (a removed entry, or
|
|
179
|
+
* an entry rewritten WITH a consistently recomputed hash — its successor's
|
|
180
|
+
* prev_hash no longer matches).
|
|
181
|
+
*
|
|
182
|
+
* @param {Array<object>} entries the full evidence log (evidence.all())
|
|
183
|
+
* @param {object} [o]
|
|
184
|
+
* @param {string[]} [o.issuerKeys=[]] pinned base64url SPKI issuer keys, sourced
|
|
185
|
+
* by the AUDITOR out of band — never from the entries themselves
|
|
186
|
+
* @param {number|function} [o.now=Date.now] clock for generated_at (pin for determinism)
|
|
187
|
+
* @param {object} [o.approverKeys={}] auditor-pinned identity-bound approver keys
|
|
188
|
+
* @param {string|null} [o.rpId] bind carried WebAuthn assertions to this relying-party id
|
|
189
|
+
* @param {string[]} [o.allowedOrigins=[]] exact accepted WebAuthn origins
|
|
190
|
+
* @param {object} [o.quorumPolicy] auditor-pinned global organizational quorum rule
|
|
191
|
+
* @param {object} [o.quorumPolicies] action_type -> auditor-pinned quorum rule
|
|
192
|
+
* @returns {Promise<object>} EP-GATE-REPERFORMANCE-v1 document:
|
|
193
|
+
* { chain: {ok, entries, head}, receipts: {reverified, failed, not_reverifiable},
|
|
194
|
+
* counts: {allows, denies, replays_blocked, by_action_type}, ... }
|
|
195
|
+
*/
|
|
196
|
+
export async function reperformEvidence(entries = [], { issuerKeys = [], approverKeys = {}, now = Date.now, rpId = null, allowedOrigins = [], quorumPolicy = null, quorumPolicies = {}, } = {}) {
|
|
197
|
+
if (!Array.isArray(entries)) {
|
|
198
|
+
throw new Error('reperform: entries must be an array (evidence.all() or a full export)');
|
|
199
|
+
}
|
|
200
|
+
if (!Array.isArray(issuerKeys)) {
|
|
201
|
+
throw new Error('reperform: issuerKeys must be an array of base64url SPKI issuer keys');
|
|
202
|
+
}
|
|
203
|
+
/* ------------------------------- chain -------------------------------- */
|
|
204
|
+
const rebuilt = createEvidenceLog();
|
|
205
|
+
let broken = null;
|
|
206
|
+
for (let i = 0; i < entries.length; i++) {
|
|
207
|
+
const e = entries[i];
|
|
208
|
+
if (!e || typeof e !== 'object' || Array.isArray(e)) {
|
|
209
|
+
broken = { at: i, seq: null, reason: 'not_an_object' };
|
|
210
|
+
break;
|
|
211
|
+
}
|
|
212
|
+
const seq = Number.isInteger(e.seq) ? e.seq : null;
|
|
213
|
+
if (seq === null) {
|
|
214
|
+
broken = { at: i, seq: null, reason: 'missing_seq' };
|
|
215
|
+
break;
|
|
216
|
+
}
|
|
217
|
+
if (typeof e.prev_hash !== 'string' || e.prev_hash.length === 0) {
|
|
218
|
+
broken = { at: i, seq, reason: 'missing_prev_hash' };
|
|
219
|
+
break;
|
|
220
|
+
}
|
|
221
|
+
if (typeof e.hash !== 'string' || e.hash.length === 0) {
|
|
222
|
+
broken = { at: i, seq, reason: 'missing_hash' };
|
|
223
|
+
break;
|
|
224
|
+
}
|
|
225
|
+
// Re-record the EXACT supplied body (own seq/prev_hash override the fresh
|
|
226
|
+
// log's defaults via the record() spread) so the recomputed hash is over
|
|
227
|
+
// byte-identical canonical material.
|
|
228
|
+
const { hash: suppliedHash, ...body } = e;
|
|
229
|
+
const rec = await rebuilt.record(body);
|
|
230
|
+
if (rec.hash !== suppliedHash) {
|
|
231
|
+
broken = { at: i, seq, reason: 'hash_mismatch' };
|
|
232
|
+
break;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
// Drive the REAL evidence.js verifier over the rebuilt chain — the link walk
|
|
236
|
+
// (prev_hash continuity from 'genesis') is its judgment, not a reimplementation.
|
|
237
|
+
const rv = rebuilt.verify();
|
|
238
|
+
if (!broken && !rv.ok)
|
|
239
|
+
broken = { at: rv.at ?? null, seq: rv.at ?? null, reason: rv.reason };
|
|
240
|
+
const chain = {
|
|
241
|
+
ok: !broken,
|
|
242
|
+
entries: entries.length,
|
|
243
|
+
// A broken chain vouches for NO head — even a valid prefix's.
|
|
244
|
+
head: !broken ? (rv.head ?? null) : null,
|
|
245
|
+
...(broken ? { broken_at: broken.at, broken_seq: broken.seq, reason: broken.reason } : {}),
|
|
246
|
+
};
|
|
247
|
+
/* ------------------- receipts + counts (from scratch) ------------------ */
|
|
248
|
+
const receipts = { reverified: 0, failed: [], not_reverifiable: 0, no_receipt_presented: 0 };
|
|
249
|
+
const warnings = [];
|
|
250
|
+
const byAction = Object.create(null);
|
|
251
|
+
let allows = 0;
|
|
252
|
+
let denies = 0;
|
|
253
|
+
let replaysBlocked = 0;
|
|
254
|
+
entries.forEach((e, index) => {
|
|
255
|
+
if (!e || typeof e !== 'object' || Array.isArray(e)) {
|
|
256
|
+
warnings.push({ index, reason: 'not_an_object' });
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
if (typeof e.kind !== 'string' || e.kind.length === 0) {
|
|
260
|
+
warnings.push({ index, reason: 'missing_kind' });
|
|
261
|
+
return;
|
|
262
|
+
}
|
|
263
|
+
// Counts: guarded decisions only ('not_guarded' pass-throughs ran without
|
|
264
|
+
// the control; execution records are provenance, not enforcement). Fail
|
|
265
|
+
// closed: only a literal `true` counts as an allow.
|
|
266
|
+
if (e.kind === 'decision' && e.reason !== 'not_guarded') {
|
|
267
|
+
if (e.allow === true)
|
|
268
|
+
allows += 1;
|
|
269
|
+
else
|
|
270
|
+
denies += 1;
|
|
271
|
+
if (e.reason === 'replay_refused')
|
|
272
|
+
replaysBlocked += 1;
|
|
273
|
+
const action = typeof e.action === 'string' && e.action ? e.action : 'unknown';
|
|
274
|
+
byAction[action] = (byAction[action] || 0) + 1;
|
|
275
|
+
}
|
|
276
|
+
// Re-verification: any entry that carries material gets it re-verified;
|
|
277
|
+
// ALL carried payloads must verify for the entry to count as reverified —
|
|
278
|
+
// each failure is a named {hash, reason}, never absorbed.
|
|
279
|
+
const hash = typeof e.hash === 'string' && e.hash ? e.hash : null;
|
|
280
|
+
const material = collectMaterial(e);
|
|
281
|
+
if (material.length > 0) {
|
|
282
|
+
let allOk = true;
|
|
283
|
+
for (const m of material) {
|
|
284
|
+
const reason = reverifyMaterial(m, {
|
|
285
|
+
issuerKeys,
|
|
286
|
+
approverKeys,
|
|
287
|
+
action: typeof e.action === 'string' && e.action ? e.action : null,
|
|
288
|
+
rpId,
|
|
289
|
+
allowedOrigins,
|
|
290
|
+
quorumPolicy,
|
|
291
|
+
quorumPolicies,
|
|
292
|
+
});
|
|
293
|
+
if (reason) {
|
|
294
|
+
allOk = false;
|
|
295
|
+
receipts.failed.push({ hash, reason });
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
if (allOk)
|
|
299
|
+
receipts.reverified += 1;
|
|
300
|
+
return;
|
|
301
|
+
}
|
|
302
|
+
// No material carried. A decision that REFERENCES a receipt (receipt_id
|
|
303
|
+
// recorded) but does not carry it cannot be re-performed — surfaced as
|
|
304
|
+
// not_reverifiable, never silently passed. A decision where no receipt was
|
|
305
|
+
// presented at all (pass-through, receipt_required refusal) has nothing to
|
|
306
|
+
// re-verify and is reported separately for transparency.
|
|
307
|
+
if (e.kind === 'decision') {
|
|
308
|
+
if (e.receipt_id !== null && e.receipt_id !== undefined)
|
|
309
|
+
receipts.not_reverifiable += 1;
|
|
310
|
+
else
|
|
311
|
+
receipts.no_receipt_presented += 1;
|
|
312
|
+
}
|
|
313
|
+
});
|
|
314
|
+
const nowMs = typeof now === 'function' ? now() : now;
|
|
315
|
+
return {
|
|
316
|
+
'@version': REPERFORMANCE_VERSION,
|
|
317
|
+
product: 'EMILIA Gate',
|
|
318
|
+
generated_at: new Date(nowMs).toISOString(),
|
|
319
|
+
honesty: {
|
|
320
|
+
reperforms: 'Independent recomputation from the supplied evidence entries: the hash chain is rebuilt '
|
|
321
|
+
+ 'and checked with the evidence log\'s own verifier, carried receipt/signoff/quorum material '
|
|
322
|
+
+ 'is cryptographically re-verified against auditor-pinned issuer and identity-bound approver keys, '
|
|
323
|
+
+ 'WebAuthn scope, and organizational quorum policy; decision counts '
|
|
324
|
+
+ 'are recomputed from scratch without reference to any report builder.',
|
|
325
|
+
does_not_establish: [
|
|
326
|
+
'Completeness of the log: a chain rewritten in full, or entries withheld before they were supplied, is not detectable from the entries alone. Anchor the head hash externally to close this.',
|
|
327
|
+
'Runtime freshness or one-time consumption: those were properties of the moment of decision and cannot be re-performed after the fact; cryptographic material is re-verified, runtime state is not.',
|
|
328
|
+
'Issuer and approver key custody, enrollment, or identity proofing, which remain external trust roots the auditor supplies out of band.',
|
|
329
|
+
'The business correctness or wisdom of any authorized action.',
|
|
330
|
+
],
|
|
331
|
+
status: 'Support for an audit re-performance procedure. This document does not conclude, opine, or certify; any conclusion is the auditor\'s.',
|
|
332
|
+
},
|
|
333
|
+
input: {
|
|
334
|
+
entries_supplied: entries.length,
|
|
335
|
+
issuer_keys_pinned: issuerKeys.length,
|
|
336
|
+
approver_keys_pinned: approverKeys && typeof approverKeys === 'object'
|
|
337
|
+
? Object.keys(approverKeys).length : 0,
|
|
338
|
+
relying_party_scope_pinned: typeof rpId === 'string' && rpId.length > 0
|
|
339
|
+
&& Array.isArray(allowedOrigins) && allowedOrigins.length > 0,
|
|
340
|
+
quorum_policies_pinned: (quorumPolicy ? 1 : 0)
|
|
341
|
+
+ (quorumPolicies && typeof quorumPolicies === 'object' ? Object.keys(quorumPolicies).length : 0),
|
|
342
|
+
expects: 'the complete evidence log from genesis (evidence.all() or a full export)',
|
|
343
|
+
},
|
|
344
|
+
chain,
|
|
345
|
+
receipts,
|
|
346
|
+
counts: {
|
|
347
|
+
allows,
|
|
348
|
+
denies,
|
|
349
|
+
replays_blocked: replaysBlocked,
|
|
350
|
+
by_action_type: sortedCounts(byAction),
|
|
351
|
+
},
|
|
352
|
+
integrity_warnings: warnings,
|
|
353
|
+
};
|
|
354
|
+
}
|
|
355
|
+
/** Extract the recomputed counts, fail closed on anything unrecognized. */
|
|
356
|
+
function countsFrom(recomputed) {
|
|
357
|
+
if (!recomputed || typeof recomputed !== 'object') {
|
|
358
|
+
throw new Error('compareToReported: recomputed must be the reperformEvidence result (or its counts)');
|
|
359
|
+
}
|
|
360
|
+
const c = recomputed['@version'] === REPERFORMANCE_VERSION ? recomputed.counts : recomputed;
|
|
361
|
+
if (!c || typeof c !== 'object') {
|
|
362
|
+
throw new Error('compareToReported: recomputed carries no counts');
|
|
363
|
+
}
|
|
364
|
+
for (const k of ['allows', 'denies', 'replays_blocked']) {
|
|
365
|
+
if (!Number.isFinite(c[k]) || c[k] < 0) {
|
|
366
|
+
throw new Error(`compareToReported: recomputed.${k} must be a finite number >= 0 — refusing to compare`);
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
const by = c.by_action_type;
|
|
370
|
+
return { ...c, by_action_type: by && typeof by === 'object' && !Array.isArray(by) ? by : {} };
|
|
371
|
+
}
|
|
372
|
+
/**
|
|
373
|
+
* Diff recomputed counts against a reported pack — the auditor's tie-out.
|
|
374
|
+
*
|
|
375
|
+
* Accepts an EP-GATE-USAGE-v1 pack (meterUsage output or the signed-ready
|
|
376
|
+
* buildUsageStatement body) or an EP-GATE-UNDERWRITER-ATTESTATION-v1 pack.
|
|
377
|
+
* Only the OVERLAPPING NUMERIC fields are compared; an unknown pack @version
|
|
378
|
+
* is refused (fail closed), never fuzzily matched. A reported field that is
|
|
379
|
+
* missing or non-numeric is itself a named drift — a stripped pack can never
|
|
380
|
+
* silently match.
|
|
381
|
+
*
|
|
382
|
+
* The comparison is meaningful only when the recomputation ran over exactly
|
|
383
|
+
* the entries the reported pack was built from (same slice, same window);
|
|
384
|
+
* scoping the slice is the auditor's procedure, not this function's.
|
|
385
|
+
*
|
|
386
|
+
* @param {object} recomputed reperformEvidence() result (or its .counts)
|
|
387
|
+
* @param {object} reportedPack usage or underwriter pack
|
|
388
|
+
* @returns {{match: boolean, pack_version: string, drift: Array<{field, reported, recomputed}>}}
|
|
389
|
+
*/
|
|
390
|
+
export function compareToReported(recomputed, reportedPack) {
|
|
391
|
+
const counts = countsFrom(recomputed);
|
|
392
|
+
if (!reportedPack || typeof reportedPack !== 'object') {
|
|
393
|
+
throw new Error('compareToReported: reportedPack must be an object');
|
|
394
|
+
}
|
|
395
|
+
const version = reportedPack['@version'];
|
|
396
|
+
const drift = [];
|
|
397
|
+
const check = (field, reported, rec) => {
|
|
398
|
+
if (!Number.isFinite(reported) || reported !== rec) {
|
|
399
|
+
drift.push({ field, reported: reported === undefined ? null : reported, recomputed: rec });
|
|
400
|
+
}
|
|
401
|
+
};
|
|
402
|
+
if (version === USAGE_PACK_VERSION) {
|
|
403
|
+
check('allows', reportedPack.allows, counts.allows);
|
|
404
|
+
check('denies', reportedPack.denies, counts.denies);
|
|
405
|
+
check('replays_blocked', reportedPack.replays_blocked, counts.replays_blocked);
|
|
406
|
+
check('protected_actions', reportedPack.protected_actions, counts.allows + counts.denies);
|
|
407
|
+
const reportedBy = reportedPack.by_action_type;
|
|
408
|
+
const byOk = reportedBy && typeof reportedBy === 'object' && !Array.isArray(reportedBy);
|
|
409
|
+
const keys = new Set([
|
|
410
|
+
...Object.keys(counts.by_action_type),
|
|
411
|
+
...(byOk ? Object.keys(reportedBy) : []),
|
|
412
|
+
]);
|
|
413
|
+
for (const k of [...keys].sort()) {
|
|
414
|
+
// An absent key in a well-formed histogram means zero occurrences.
|
|
415
|
+
const rep = byOk && reportedBy[k] !== undefined ? reportedBy[k] : 0;
|
|
416
|
+
check(`by_action_type.${k}`, rep, counts.by_action_type[k] ?? 0);
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
else if (version === UNDERWRITER_PACK_VERSION) {
|
|
420
|
+
check('volume.guarded_decisions', reportedPack.volume?.guarded_decisions, counts.allows + counts.denies);
|
|
421
|
+
check('volume.allowed', reportedPack.volume?.allowed, counts.allows);
|
|
422
|
+
check('volume.denied', reportedPack.volume?.denied, counts.denies);
|
|
423
|
+
check('denials.total', reportedPack.denials?.total, counts.denies);
|
|
424
|
+
check('replay.attempts_blocked', reportedPack.replay?.attempts_blocked, counts.replays_blocked);
|
|
425
|
+
}
|
|
426
|
+
else {
|
|
427
|
+
throw new Error(`compareToReported: unknown pack @version ${JSON.stringify(version ?? null)} — refusing to compare (fail closed)`);
|
|
428
|
+
}
|
|
429
|
+
return { match: drift.length === 0, pack_version: version, drift };
|
|
430
|
+
}
|
|
431
|
+
export default { REPERFORMANCE_VERSION, reperformEvidence, compareToReported };
|
|
432
|
+
//# sourceMappingURL=reperform.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reperform.js","sourceRoot":"","sources":["../../src/reports/reperform.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EMILIA Gate — underwriter control attestation (AI-liability loss-run analogue).
|
|
3
|
+
*
|
|
4
|
+
* The artifact an AI-liability underwriter prices premium credit against — the
|
|
5
|
+
* MFA-for-cyber analogue: evidence that a deny-by-default authorization control
|
|
6
|
+
* was IN FORCE and OPERATING over the policy period, computed from the gate's
|
|
7
|
+
* tamper-evident evidence log. Pure function: same entries + same options in,
|
|
8
|
+
* identical JSON out (pin `now` for a byte-stable artifact).
|
|
9
|
+
*
|
|
10
|
+
* HONESTY BOUNDARY (carried inside the artifact): this attests CONTROL
|
|
11
|
+
* OPERATION only. It does not attest the business correctness of any authorized
|
|
12
|
+
* action, and it is not an insurance document until adopted by the carrier.
|
|
13
|
+
* Near-miss / remediation narrative belongs to the broker — the builder emits
|
|
14
|
+
* those fields as null and NEVER fabricates prose.
|
|
15
|
+
*
|
|
16
|
+
* Fail closed: a missing insured or an invalid period is an error, not a guess.
|
|
17
|
+
* Entries that cannot be verified as log records (unparseable time, missing
|
|
18
|
+
* hash, unknown kind, decision without an allow verdict) are EXCLUDED from every
|
|
19
|
+
* attested count and surfaced as integrity_warnings — the attestation never
|
|
20
|
+
* counts what it cannot account for. A zero-activity period is a valid (boring)
|
|
21
|
+
* attestation, not an error.
|
|
22
|
+
*/
|
|
23
|
+
export declare const UNDERWRITER_ATTESTATION_VERSION = "EP-GATE-UNDERWRITER-ATTESTATION-v1";
|
|
24
|
+
/**
|
|
25
|
+
* Build the underwriter attestation over a slice of the evidence log.
|
|
26
|
+
* @param {Array<object>} entries evidence.all() (or a durable export of it)
|
|
27
|
+
* @param {object} [o]
|
|
28
|
+
* @param {string} [o.insured] named insured (required)
|
|
29
|
+
* @param {string|null} [o.policyRef] carrier policy/submission reference (null until bound)
|
|
30
|
+
* @param {string|number} [o.periodStart] inclusive period start (ISO or epoch ms)
|
|
31
|
+
* @param {string|number} [o.periodEnd] inclusive period end (ISO or epoch ms)
|
|
32
|
+
* @param {number|Function} [o.now] clock for generated_at (pin for determinism)
|
|
33
|
+
* @returns {object} EP-GATE-UNDERWRITER-ATTESTATION-v1 document
|
|
34
|
+
*/
|
|
35
|
+
export declare function buildUnderwriterAttestation(entries?: any[], { insured, policyRef, periodStart, periodEnd, now, }?: {
|
|
36
|
+
insured?: string;
|
|
37
|
+
policyRef?: string | null;
|
|
38
|
+
periodStart?: string | number;
|
|
39
|
+
periodEnd?: string | number;
|
|
40
|
+
now?: number | (() => number);
|
|
41
|
+
}): {
|
|
42
|
+
'@version': string;
|
|
43
|
+
product: string;
|
|
44
|
+
generated_at: string;
|
|
45
|
+
insured: string;
|
|
46
|
+
policy_ref: string | null;
|
|
47
|
+
period: {
|
|
48
|
+
start: string;
|
|
49
|
+
end: string;
|
|
50
|
+
};
|
|
51
|
+
honesty: {
|
|
52
|
+
attests: string;
|
|
53
|
+
does_not_attest: string[];
|
|
54
|
+
status: string;
|
|
55
|
+
};
|
|
56
|
+
control_in_force: {
|
|
57
|
+
control: string;
|
|
58
|
+
mode: string;
|
|
59
|
+
statement: string;
|
|
60
|
+
guarded_decisions: number;
|
|
61
|
+
first_decision_at: any;
|
|
62
|
+
last_decision_at: any;
|
|
63
|
+
};
|
|
64
|
+
volume: {
|
|
65
|
+
guarded_decisions: number;
|
|
66
|
+
allowed: number;
|
|
67
|
+
denied: number;
|
|
68
|
+
by_action_family: Record<string, any>;
|
|
69
|
+
};
|
|
70
|
+
denials: {
|
|
71
|
+
total: number;
|
|
72
|
+
rate: number | null;
|
|
73
|
+
reasons: Record<string, any>;
|
|
74
|
+
};
|
|
75
|
+
replay: {
|
|
76
|
+
attempts_blocked: number;
|
|
77
|
+
};
|
|
78
|
+
assurance: {
|
|
79
|
+
required_tier_distribution: Record<string, number>;
|
|
80
|
+
credited_tier_distribution_on_allow: Record<string, number>;
|
|
81
|
+
};
|
|
82
|
+
quorum_usage: {
|
|
83
|
+
hard_action_decisions: number;
|
|
84
|
+
allowed: number;
|
|
85
|
+
denied: number;
|
|
86
|
+
};
|
|
87
|
+
exceptions: {
|
|
88
|
+
uncontrolled_passthroughs: number;
|
|
89
|
+
uncontrolled_actions: any[];
|
|
90
|
+
replay_defense_bypassed: number;
|
|
91
|
+
};
|
|
92
|
+
executions: {
|
|
93
|
+
recorded: number;
|
|
94
|
+
executed: number;
|
|
95
|
+
failed: number;
|
|
96
|
+
};
|
|
97
|
+
narrative: {
|
|
98
|
+
near_misses: null;
|
|
99
|
+
remediation: null;
|
|
100
|
+
completed_by: string;
|
|
101
|
+
};
|
|
102
|
+
evidence: {
|
|
103
|
+
log_entries_supplied: number;
|
|
104
|
+
in_scope: number;
|
|
105
|
+
first_hash: any;
|
|
106
|
+
last_hash: any;
|
|
107
|
+
integrity_warnings: {
|
|
108
|
+
index: number;
|
|
109
|
+
seq: number | null;
|
|
110
|
+
reason: string;
|
|
111
|
+
}[];
|
|
112
|
+
};
|
|
113
|
+
};
|
|
114
|
+
/**
|
|
115
|
+
* Render the attestation for a submission packet. Refuses any document that is
|
|
116
|
+
* not an EP-GATE-UNDERWRITER-ATTESTATION-v1 — never renders what it cannot
|
|
117
|
+
* vouch the shape of. Narrative fields render exactly as present in the pack
|
|
118
|
+
* (the broker fills them into the JSON); null renders as a placeholder.
|
|
119
|
+
*/
|
|
120
|
+
export declare function renderMarkdown(pack: any): string;
|
|
121
|
+
declare const _default: {
|
|
122
|
+
UNDERWRITER_ATTESTATION_VERSION: string;
|
|
123
|
+
buildUnderwriterAttestation: typeof buildUnderwriterAttestation;
|
|
124
|
+
renderMarkdown: typeof renderMarkdown;
|
|
125
|
+
};
|
|
126
|
+
export default _default;
|
|
127
|
+
//# sourceMappingURL=underwriter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"underwriter.d.ts","sourceRoot":"","sources":["../../src/reports/underwriter.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,eAAO,MAAM,+BAA+B,uCAAuC,CAAC;AA6CpF;;;;;;;;;;GAUG;AACH,wBAAgB,2BAA2B,CAAC,OAAO,GAAE,GAAG,EAAO,EAAE,EAC/D,OAAO,EAAE,SAAgB,EAAE,WAAW,EAAE,SAAS,EAAE,GAAc,GAClE,GAAE;IACD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC9B,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC5B,GAAG,CAAC,EAAE,MAAM,GAAG,CAAC,MAAM,MAAM,CAAC,CAAC;CAC1B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mBAmBqB,MAAM;iBAAO,MAAM,GAAG,IAAI;oBAAU,MAAM;;;EAuHpE;AAkCD;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,IAAI,KAAA,UAuFlC;;;;;;AAED,wBAAgG"}
|