@kya-os/mcp 1.16.1 → 1.17.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/AUDITABILITY.md +129 -8
- package/CHANGELOG.md +591 -0
- package/CONFORMANCE.md +4 -4
- package/README.md +65 -26
- package/SPEC.md +85 -17
- package/dist/audit/adapters/legacy-audit-log.d.ts +0 -1
- package/dist/audit/adapters/mcp.d.ts +0 -1
- package/dist/audit/adapters/mcp.js +35 -20
- package/dist/audit/adapters/mcp.js.map +1 -1
- package/dist/audit/adapters/references.d.ts +9 -0
- package/dist/audit/adapters/references.js +22 -0
- package/dist/audit/adapters/references.js.map +1 -0
- package/dist/audit/assurance.d.ts +0 -1
- package/dist/audit/checkpoint-coordinator.d.ts +0 -1
- package/dist/audit/checkpoint.d.ts +17 -1
- package/dist/audit/checkpoint.js +76 -21
- package/dist/audit/checkpoint.js.map +1 -1
- package/dist/audit/cli.d.ts +0 -1
- package/dist/audit/crypto.d.ts +0 -1
- package/dist/audit/crypto.js +12 -3
- package/dist/audit/crypto.js.map +1 -1
- package/dist/audit/errors.d.ts +0 -1
- package/dist/audit/evidence.d.ts +0 -1
- package/dist/audit/index.d.ts +0 -1
- package/dist/audit/integrity.d.ts +0 -1
- package/dist/audit/merkle.d.ts +0 -1
- package/dist/audit/mirror-service.d.ts +0 -1
- package/dist/audit/projection.d.ts +1 -1
- package/dist/audit/projection.js +23 -2
- package/dist/audit/projection.js.map +1 -1
- package/dist/audit/providers/anchor.d.ts +0 -1
- package/dist/audit/providers/evidence.d.ts +0 -1
- package/dist/audit/providers/journal.d.ts +0 -1
- package/dist/audit/providers/memory-journal.d.ts +0 -1
- package/dist/audit/providers/observer.d.ts +0 -1
- package/dist/audit/providers/outbox.d.ts +35 -6
- package/dist/audit/providers/outbox.js +46 -8
- package/dist/audit/providers/outbox.js.map +1 -1
- package/dist/audit/providers/recorder-client.d.ts +0 -1
- package/dist/audit/providers/source-state.d.ts +24 -2
- package/dist/audit/providers/source-state.js +65 -44
- package/dist/audit/providers/source-state.js.map +1 -1
- package/dist/audit/read-contract.d.ts +0 -1
- package/dist/audit/read-service.d.ts +2 -3
- package/dist/audit/read-service.js +17 -12
- package/dist/audit/read-service.js.map +1 -1
- package/dist/audit/recorder-service.d.ts +33 -5
- package/dist/audit/recorder-service.js +116 -20
- package/dist/audit/recorder-service.js.map +1 -1
- package/dist/audit/reference-recorder.d.ts +0 -1
- package/dist/audit/replay-bundle.d.ts +0 -1
- package/dist/audit/replay-bundle.js +143 -36
- package/dist/audit/replay-bundle.js.map +1 -1
- package/dist/audit/schemas.d.ts +0 -1
- package/dist/audit/service.d.ts +6 -3
- package/dist/audit/service.js +55 -24
- package/dist/audit/service.js.map +1 -1
- package/dist/audit/testing/index.d.ts +0 -1
- package/dist/audit/testing/provider-contracts.d.ts +1 -2
- package/dist/audit/testing/provider-contracts.js +32 -2
- package/dist/audit/testing/provider-contracts.js.map +1 -1
- package/dist/audit/types.d.ts +0 -1
- package/dist/audit/verifier.d.ts +57 -5
- package/dist/audit/verifier.js +240 -49
- package/dist/audit/verifier.js.map +1 -1
- package/dist/auth/handshake.d.ts +12 -1
- package/dist/auth/handshake.js +44 -11
- package/dist/auth/handshake.js.map +1 -1
- package/dist/auth/index.d.ts +0 -1
- package/dist/auth/types.d.ts +0 -1
- package/dist/authz/accountability.d.ts +0 -1
- package/dist/authz/adapter.d.ts +0 -1
- package/dist/authz/examples/inmemory-oidc.d.ts +0 -1
- package/dist/authz/index.d.ts +0 -1
- package/dist/authz/oidc/authorize.d.ts +0 -1
- package/dist/authz/oidc/metadata.d.ts +0 -1
- package/dist/authz/oidc/oidc-adapter.d.ts +0 -1
- package/dist/authz/oidc/oidc-adapter.js +51 -3
- package/dist/authz/oidc/oidc-adapter.js.map +1 -1
- package/dist/authz/oidc/pending-flow-store.d.ts +6 -1
- package/dist/authz/oidc/pending-flow-store.js +22 -2
- package/dist/authz/oidc/pending-flow-store.js.map +1 -1
- package/dist/authz/oidc/pkce.d.ts +0 -1
- package/dist/authz/registry.d.ts +0 -1
- package/dist/authz/requirement.d.ts +0 -1
- package/dist/card/build.d.ts +0 -1
- package/dist/card/builder.d.ts +0 -1
- package/dist/card/cimd.d.ts +19 -5
- package/dist/card/cimd.js +52 -7
- package/dist/card/cimd.js.map +1 -1
- package/dist/card/delegation.d.ts +0 -1
- package/dist/card/delegation.js +25 -15
- package/dist/card/delegation.js.map +1 -1
- package/dist/card/emit.d.ts +0 -1
- package/dist/card/index.d.ts +0 -1
- package/dist/card/middleware.d.ts +0 -1
- package/dist/card/proof/build.d.ts +0 -1
- package/dist/card/proof/canonical.d.ts +0 -1
- package/dist/card/proof/canonical.js +6 -1
- package/dist/card/proof/canonical.js.map +1 -1
- package/dist/card/proof/http-sig.d.ts +0 -1
- package/dist/card/proof/index.d.ts +0 -1
- package/dist/card/proof/nonce-cache.d.ts +15 -14
- package/dist/card/proof/nonce-cache.js +22 -20
- package/dist/card/proof/nonce-cache.js.map +1 -1
- package/dist/card/proof/signer.d.ts +0 -1
- package/dist/card/proof/types.d.ts +10 -4
- package/dist/card/proof/types.js +2 -2
- package/dist/card/proof/verify.d.ts +0 -1
- package/dist/card/proof/verify.js +17 -3
- package/dist/card/proof/verify.js.map +1 -1
- package/dist/card/resolve.d.ts +0 -1
- package/dist/card/resolve.js +13 -8
- package/dist/card/resolve.js.map +1 -1
- package/dist/card/revocation.d.ts +0 -1
- package/dist/card/revocation.js +18 -6
- package/dist/card/revocation.js.map +1 -1
- package/dist/card/schema.d.ts +7 -6
- package/dist/card/schema.js +7 -3
- package/dist/card/schema.js.map +1 -1
- package/dist/card/verify.d.ts +0 -1
- package/dist/delegation/audience-validator.d.ts +0 -1
- package/dist/delegation/bitstring.d.ts +0 -1
- package/dist/delegation/cascading-revocation.d.ts +1 -2
- package/dist/delegation/cascading-revocation.js +34 -36
- package/dist/delegation/cascading-revocation.js.map +1 -1
- package/dist/delegation/chain-enforcement.d.ts +26 -5
- package/dist/delegation/chain-enforcement.js +110 -34
- package/dist/delegation/chain-enforcement.js.map +1 -1
- package/dist/delegation/delegation-graph.d.ts +30 -1
- package/dist/delegation/delegation-graph.js +33 -0
- package/dist/delegation/delegation-graph.js.map +1 -1
- package/dist/delegation/delegation-registration.d.ts +22 -0
- package/dist/delegation/delegation-registration.js +51 -0
- package/dist/delegation/delegation-registration.js.map +1 -0
- package/dist/delegation/delegation-status-entry.d.ts +22 -0
- package/dist/delegation/delegation-status-entry.js +42 -0
- package/dist/delegation/delegation-status-entry.js.map +1 -0
- package/dist/delegation/did-key-resolver.d.ts +0 -1
- package/dist/delegation/did-key-resolver.js +15 -4
- package/dist/delegation/did-key-resolver.js.map +1 -1
- package/dist/delegation/did-linkage.d.ts +0 -1
- package/dist/delegation/did-resolver-registry.d.ts +0 -1
- package/dist/delegation/did-web-resolver.d.ts +0 -1
- package/dist/delegation/did-web-resolver.js +40 -5
- package/dist/delegation/did-web-resolver.js.map +1 -1
- package/dist/delegation/holder-binding.d.ts +11 -11
- package/dist/delegation/holder-binding.js +8 -17
- package/dist/delegation/holder-binding.js.map +1 -1
- package/dist/delegation/index.d.ts +0 -1
- package/dist/delegation/outbound-headers.d.ts +0 -1
- package/dist/delegation/outbound-proof.d.ts +0 -1
- package/dist/delegation/scope-matcher.d.ts +25 -2
- package/dist/delegation/scope-matcher.js +75 -5
- package/dist/delegation/scope-matcher.js.map +1 -1
- package/dist/delegation/status-cache.d.ts +0 -1
- package/dist/delegation/statuslist-manager.d.ts +18 -2
- package/dist/delegation/statuslist-manager.js +40 -14
- package/dist/delegation/statuslist-manager.js.map +1 -1
- package/dist/delegation/storage/memory-graph-storage.d.ts +9 -3
- package/dist/delegation/storage/memory-graph-storage.js +28 -14
- package/dist/delegation/storage/memory-graph-storage.js.map +1 -1
- package/dist/delegation/storage/memory-statuslist-storage.d.ts +0 -1
- package/dist/delegation/utils.d.ts +5 -5
- package/dist/delegation/utils.js +4 -4
- package/dist/delegation/utils.js.map +1 -1
- package/dist/delegation/vc-issuer.d.ts +0 -1
- package/dist/delegation/vc-jwt-verify.d.ts +7 -2
- package/dist/delegation/vc-jwt-verify.js +55 -3
- package/dist/delegation/vc-jwt-verify.js.map +1 -1
- package/dist/delegation/vc-verification-checks.d.ts +0 -1
- package/dist/delegation/vc-verification-checks.js +9 -5
- package/dist/delegation/vc-verification-checks.js.map +1 -1
- package/dist/delegation/vc-verifier.d.ts +0 -1
- package/dist/delegation/vc-verifier.types.d.ts +0 -1
- package/dist/delegation/verification-method-key.d.ts +0 -1
- package/dist/delegation/verification-method-key.js +4 -3
- package/dist/delegation/verification-method-key.js.map +1 -1
- package/dist/errors.d.ts +0 -1
- package/dist/extension/declaration.d.ts +0 -1
- package/dist/extension/gate.d.ts +0 -1
- package/dist/extension/index.d.ts +0 -1
- package/dist/extension/settings.d.ts +0 -1
- package/dist/index.d.ts +2 -3
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/integrations/cheqd/dlr.d.ts +0 -1
- package/dist/integrations/cheqd/dlr.js +6 -1
- package/dist/integrations/cheqd/dlr.js.map +1 -1
- package/dist/integrations/cheqd/index.d.ts +0 -1
- package/dist/integrations/cheqd/linkage.d.ts +0 -1
- package/dist/integrations/cheqd/registrar.d.ts +0 -1
- package/dist/integrations/cheqd/resolver.d.ts +0 -1
- package/dist/integrations/cheqd/statuslist-resolver.d.ts +0 -1
- package/dist/logging/index.d.ts +0 -1
- package/dist/logging/logger.d.ts +0 -1
- package/dist/middleware/index.d.ts +0 -1
- package/dist/middleware/kya-os-transport.d.ts +5 -3
- package/dist/middleware/kya-os-transport.js +58 -24
- package/dist/middleware/kya-os-transport.js.map +1 -1
- package/dist/middleware/with-kya-os-server.d.ts +24 -4
- package/dist/middleware/with-kya-os-server.js +7 -0
- package/dist/middleware/with-kya-os-server.js.map +1 -1
- package/dist/middleware/with-kya-os.config-types.d.ts +22 -4
- package/dist/middleware/with-kya-os.d.ts +0 -1
- package/dist/middleware/with-kya-os.delegation-gate.d.ts +2 -1
- package/dist/middleware/with-kya-os.delegation-gate.js +37 -9
- package/dist/middleware/with-kya-os.delegation-gate.js.map +1 -1
- package/dist/middleware/with-kya-os.delegation-verify.d.ts +1 -1
- package/dist/middleware/with-kya-os.delegation-verify.js +45 -9
- package/dist/middleware/with-kya-os.delegation-verify.js.map +1 -1
- package/dist/middleware/with-kya-os.deps.d.ts +0 -1
- package/dist/middleware/with-kya-os.grants.d.ts +13 -6
- package/dist/middleware/with-kya-os.grants.js +56 -18
- package/dist/middleware/with-kya-os.grants.js.map +1 -1
- package/dist/middleware/with-kya-os.helpers.d.ts +0 -1
- package/dist/middleware/with-kya-os.js +14 -4
- package/dist/middleware/with-kya-os.js.map +1 -1
- package/dist/middleware/with-kya-os.policy-gate.d.ts +0 -1
- package/dist/middleware/with-kya-os.policy-gate.js +18 -9
- package/dist/middleware/with-kya-os.policy-gate.js.map +1 -1
- package/dist/middleware/with-kya-os.protocol.d.ts +0 -1
- package/dist/middleware/with-kya-os.session.d.ts +28 -1
- package/dist/middleware/with-kya-os.session.js +146 -7
- package/dist/middleware/with-kya-os.session.js.map +1 -1
- package/dist/middleware/with-kya-os.types.d.ts +28 -5
- package/dist/policy/approval.d.ts +13 -2
- package/dist/policy/approval.js +15 -4
- package/dist/policy/approval.js.map +1 -1
- package/dist/policy/classifier.d.ts +0 -1
- package/dist/policy/default-engine.d.ts +5 -2
- package/dist/policy/default-engine.js +10 -2
- package/dist/policy/default-engine.js.map +1 -1
- package/dist/policy/engine.d.ts +0 -1
- package/dist/policy/index.d.ts +0 -1
- package/dist/policy/projection.d.ts +0 -1
- package/dist/policy/types.d.ts +0 -1
- package/dist/proof/covered-request.d.ts +46 -0
- package/dist/proof/covered-request.js +107 -0
- package/dist/proof/covered-request.js.map +1 -0
- package/dist/proof/errors.d.ts +3 -1
- package/dist/proof/errors.js +5 -0
- package/dist/proof/errors.js.map +1 -1
- package/dist/proof/generator.d.ts +51 -1
- package/dist/proof/generator.js +71 -13
- package/dist/proof/generator.js.map +1 -1
- package/dist/proof/index.d.ts +1 -2
- package/dist/proof/index.js.map +1 -1
- package/dist/proof/verifier.d.ts +50 -12
- package/dist/proof/verifier.js +164 -84
- package/dist/proof/verifier.js.map +1 -1
- package/dist/providers/audit-log.d.ts +0 -1
- package/dist/providers/base.d.ts +19 -1
- package/dist/providers/base.js.map +1 -1
- package/dist/providers/grant-store.d.ts +8 -2
- package/dist/providers/grant-store.js +5 -5
- package/dist/providers/grant-store.js.map +1 -1
- package/dist/providers/index.d.ts +0 -1
- package/dist/providers/memory.d.ts +19 -1
- package/dist/providers/memory.js +53 -7
- package/dist/providers/memory.js.map +1 -1
- package/dist/providers/node-crypto.d.ts +4 -1
- package/dist/providers/node-crypto.js +32 -9
- package/dist/providers/node-crypto.js.map +1 -1
- package/dist/providers/nonce-admission.d.ts +31 -0
- package/dist/providers/nonce-admission.js +47 -0
- package/dist/providers/nonce-admission.js.map +1 -0
- package/dist/providers/nonce-retention.d.ts +8 -0
- package/dist/providers/nonce-retention.js +15 -0
- package/dist/providers/nonce-retention.js.map +1 -0
- package/dist/providers/runtime-fetch.d.ts +0 -1
- package/dist/providers/system-clock.d.ts +0 -1
- package/dist/providers/web-crypto.d.ts +0 -1
- package/dist/providers/web-crypto.js +7 -1
- package/dist/providers/web-crypto.js.map +1 -1
- package/dist/session/index.d.ts +0 -1
- package/dist/session/manager.d.ts +13 -1
- package/dist/session/manager.js +25 -9
- package/dist/session/manager.js.map +1 -1
- package/dist/session/session-store.d.ts +0 -1
- package/dist/types/protocol.d.ts +11 -3
- package/dist/types/protocol.js +21 -14
- package/dist/types/protocol.js.map +1 -1
- package/dist/utils/base58.d.ts +16 -3
- package/dist/utils/base58.js +34 -12
- package/dist/utils/base58.js.map +1 -1
- package/dist/utils/base64.d.ts +0 -1
- package/dist/utils/canonical-json.d.ts +7 -1
- package/dist/utils/canonical-json.js +130 -60
- package/dist/utils/canonical-json.js.map +1 -1
- package/dist/utils/crypto-service.d.ts +0 -1
- package/dist/utils/crypto-service.js +22 -2
- package/dist/utils/crypto-service.js.map +1 -1
- package/dist/utils/did-helpers.d.ts +0 -1
- package/dist/utils/ed25519-constants.d.ts +0 -1
- package/dist/utils/ed25519-public-key.d.ts +27 -0
- package/dist/utils/ed25519-public-key.js +86 -0
- package/dist/utils/ed25519-public-key.js.map +1 -0
- package/dist/utils/guards.d.ts +0 -1
- package/dist/utils/index.d.ts +0 -1
- package/dist/utils/ip-classifier.d.ts +0 -1
- package/dist/utils/safe-fetch-transports.d.ts +0 -1
- package/dist/utils/safe-fetch-types.d.ts +0 -1
- package/dist/utils/safe-fetch.d.ts +0 -1
- package/dist/utils/statuslist-bits.d.ts +0 -1
- package/dist/utils/statuslist-purpose.d.ts +0 -1
- package/dist/utils/ttl-cache.d.ts +0 -1
- package/dist/utils/url.d.ts +0 -1
- package/package.json +9 -6
- package/schemas/card-delegation-credential.json +4 -1
- package/schemas/delegation-credential.json +122 -30
- package/dist/audit/adapters/legacy-audit-log.d.ts.map +0 -1
- package/dist/audit/adapters/mcp.d.ts.map +0 -1
- package/dist/audit/assurance.d.ts.map +0 -1
- package/dist/audit/checkpoint-coordinator.d.ts.map +0 -1
- package/dist/audit/checkpoint.d.ts.map +0 -1
- package/dist/audit/cli.d.ts.map +0 -1
- package/dist/audit/crypto.d.ts.map +0 -1
- package/dist/audit/errors.d.ts.map +0 -1
- package/dist/audit/evidence.d.ts.map +0 -1
- package/dist/audit/index.d.ts.map +0 -1
- package/dist/audit/integrity.d.ts.map +0 -1
- package/dist/audit/merkle.d.ts.map +0 -1
- package/dist/audit/mirror-service.d.ts.map +0 -1
- package/dist/audit/projection.d.ts.map +0 -1
- package/dist/audit/providers/anchor.d.ts.map +0 -1
- package/dist/audit/providers/evidence.d.ts.map +0 -1
- package/dist/audit/providers/journal.d.ts.map +0 -1
- package/dist/audit/providers/memory-journal.d.ts.map +0 -1
- package/dist/audit/providers/observer.d.ts.map +0 -1
- package/dist/audit/providers/outbox.d.ts.map +0 -1
- package/dist/audit/providers/recorder-client.d.ts.map +0 -1
- package/dist/audit/providers/source-state.d.ts.map +0 -1
- package/dist/audit/read-contract.d.ts.map +0 -1
- package/dist/audit/read-service.d.ts.map +0 -1
- package/dist/audit/recorder-service.d.ts.map +0 -1
- package/dist/audit/reference-recorder.d.ts.map +0 -1
- package/dist/audit/replay-bundle.d.ts.map +0 -1
- package/dist/audit/schemas.d.ts.map +0 -1
- package/dist/audit/service.d.ts.map +0 -1
- package/dist/audit/testing/index.d.ts.map +0 -1
- package/dist/audit/testing/provider-contracts.d.ts.map +0 -1
- package/dist/audit/types.d.ts.map +0 -1
- package/dist/audit/verifier.d.ts.map +0 -1
- package/dist/auth/handshake.d.ts.map +0 -1
- package/dist/auth/index.d.ts.map +0 -1
- package/dist/auth/types.d.ts.map +0 -1
- package/dist/authz/accountability.d.ts.map +0 -1
- package/dist/authz/adapter.d.ts.map +0 -1
- package/dist/authz/examples/inmemory-oidc.d.ts.map +0 -1
- package/dist/authz/index.d.ts.map +0 -1
- package/dist/authz/oidc/authorize.d.ts.map +0 -1
- package/dist/authz/oidc/metadata.d.ts.map +0 -1
- package/dist/authz/oidc/oidc-adapter.d.ts.map +0 -1
- package/dist/authz/oidc/pending-flow-store.d.ts.map +0 -1
- package/dist/authz/oidc/pkce.d.ts.map +0 -1
- package/dist/authz/registry.d.ts.map +0 -1
- package/dist/authz/requirement.d.ts.map +0 -1
- package/dist/card/build.d.ts.map +0 -1
- package/dist/card/builder.d.ts.map +0 -1
- package/dist/card/cimd.d.ts.map +0 -1
- package/dist/card/delegation.d.ts.map +0 -1
- package/dist/card/emit.d.ts.map +0 -1
- package/dist/card/index.d.ts.map +0 -1
- package/dist/card/middleware.d.ts.map +0 -1
- package/dist/card/proof/build.d.ts.map +0 -1
- package/dist/card/proof/canonical.d.ts.map +0 -1
- package/dist/card/proof/http-sig.d.ts.map +0 -1
- package/dist/card/proof/index.d.ts.map +0 -1
- package/dist/card/proof/nonce-cache.d.ts.map +0 -1
- package/dist/card/proof/signer.d.ts.map +0 -1
- package/dist/card/proof/types.d.ts.map +0 -1
- package/dist/card/proof/verify.d.ts.map +0 -1
- package/dist/card/resolve.d.ts.map +0 -1
- package/dist/card/revocation.d.ts.map +0 -1
- package/dist/card/schema.d.ts.map +0 -1
- package/dist/card/verify.d.ts.map +0 -1
- package/dist/delegation/audience-validator.d.ts.map +0 -1
- package/dist/delegation/bitstring.d.ts.map +0 -1
- package/dist/delegation/cascading-revocation.d.ts.map +0 -1
- package/dist/delegation/chain-enforcement.d.ts.map +0 -1
- package/dist/delegation/delegation-graph.d.ts.map +0 -1
- package/dist/delegation/did-key-resolver.d.ts.map +0 -1
- package/dist/delegation/did-linkage.d.ts.map +0 -1
- package/dist/delegation/did-resolver-registry.d.ts.map +0 -1
- package/dist/delegation/did-web-resolver.d.ts.map +0 -1
- package/dist/delegation/holder-binding.d.ts.map +0 -1
- package/dist/delegation/index.d.ts.map +0 -1
- package/dist/delegation/outbound-headers.d.ts.map +0 -1
- package/dist/delegation/outbound-proof.d.ts.map +0 -1
- package/dist/delegation/scope-matcher.d.ts.map +0 -1
- package/dist/delegation/status-cache.d.ts.map +0 -1
- package/dist/delegation/statuslist-manager.d.ts.map +0 -1
- package/dist/delegation/storage/memory-graph-storage.d.ts.map +0 -1
- package/dist/delegation/storage/memory-statuslist-storage.d.ts.map +0 -1
- package/dist/delegation/utils.d.ts.map +0 -1
- package/dist/delegation/vc-issuer.d.ts.map +0 -1
- package/dist/delegation/vc-jwt-verify.d.ts.map +0 -1
- package/dist/delegation/vc-verification-checks.d.ts.map +0 -1
- package/dist/delegation/vc-verifier.d.ts.map +0 -1
- package/dist/delegation/vc-verifier.types.d.ts.map +0 -1
- package/dist/delegation/verification-method-key.d.ts.map +0 -1
- package/dist/errors.d.ts.map +0 -1
- package/dist/extension/declaration.d.ts.map +0 -1
- package/dist/extension/gate.d.ts.map +0 -1
- package/dist/extension/index.d.ts.map +0 -1
- package/dist/extension/settings.d.ts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/integrations/cheqd/dlr.d.ts.map +0 -1
- package/dist/integrations/cheqd/index.d.ts.map +0 -1
- package/dist/integrations/cheqd/linkage.d.ts.map +0 -1
- package/dist/integrations/cheqd/registrar.d.ts.map +0 -1
- package/dist/integrations/cheqd/resolver.d.ts.map +0 -1
- package/dist/integrations/cheqd/statuslist-resolver.d.ts.map +0 -1
- package/dist/logging/index.d.ts.map +0 -1
- package/dist/logging/logger.d.ts.map +0 -1
- package/dist/middleware/index.d.ts.map +0 -1
- package/dist/middleware/kya-os-transport.d.ts.map +0 -1
- package/dist/middleware/with-kya-os-server.d.ts.map +0 -1
- package/dist/middleware/with-kya-os.config-types.d.ts.map +0 -1
- package/dist/middleware/with-kya-os.d.ts.map +0 -1
- package/dist/middleware/with-kya-os.delegation-gate.d.ts.map +0 -1
- package/dist/middleware/with-kya-os.delegation-verify.d.ts.map +0 -1
- package/dist/middleware/with-kya-os.deps.d.ts.map +0 -1
- package/dist/middleware/with-kya-os.grants.d.ts.map +0 -1
- package/dist/middleware/with-kya-os.helpers.d.ts.map +0 -1
- package/dist/middleware/with-kya-os.policy-gate.d.ts.map +0 -1
- package/dist/middleware/with-kya-os.protocol.d.ts.map +0 -1
- package/dist/middleware/with-kya-os.session.d.ts.map +0 -1
- package/dist/middleware/with-kya-os.types.d.ts.map +0 -1
- package/dist/policy/approval.d.ts.map +0 -1
- package/dist/policy/classifier.d.ts.map +0 -1
- package/dist/policy/default-engine.d.ts.map +0 -1
- package/dist/policy/engine.d.ts.map +0 -1
- package/dist/policy/index.d.ts.map +0 -1
- package/dist/policy/projection.d.ts.map +0 -1
- package/dist/policy/types.d.ts.map +0 -1
- package/dist/proof/errors.d.ts.map +0 -1
- package/dist/proof/generator.d.ts.map +0 -1
- package/dist/proof/index.d.ts.map +0 -1
- package/dist/proof/verifier.d.ts.map +0 -1
- package/dist/providers/audit-log.d.ts.map +0 -1
- package/dist/providers/base.d.ts.map +0 -1
- package/dist/providers/grant-store.d.ts.map +0 -1
- package/dist/providers/index.d.ts.map +0 -1
- package/dist/providers/memory.d.ts.map +0 -1
- package/dist/providers/node-crypto.d.ts.map +0 -1
- package/dist/providers/runtime-fetch.d.ts.map +0 -1
- package/dist/providers/system-clock.d.ts.map +0 -1
- package/dist/providers/web-crypto.d.ts.map +0 -1
- package/dist/session/index.d.ts.map +0 -1
- package/dist/session/manager.d.ts.map +0 -1
- package/dist/session/session-store.d.ts.map +0 -1
- package/dist/types/protocol.d.ts.map +0 -1
- package/dist/utils/base58.d.ts.map +0 -1
- package/dist/utils/base64.d.ts.map +0 -1
- package/dist/utils/canonical-json.d.ts.map +0 -1
- package/dist/utils/crypto-service.d.ts.map +0 -1
- package/dist/utils/did-helpers.d.ts.map +0 -1
- package/dist/utils/ed25519-constants.d.ts.map +0 -1
- package/dist/utils/guards.d.ts.map +0 -1
- package/dist/utils/index.d.ts.map +0 -1
- package/dist/utils/ip-classifier.d.ts.map +0 -1
- package/dist/utils/safe-fetch-transports.d.ts.map +0 -1
- package/dist/utils/safe-fetch-types.d.ts.map +0 -1
- package/dist/utils/safe-fetch.d.ts.map +0 -1
- package/dist/utils/statuslist-bits.d.ts.map +0 -1
- package/dist/utils/statuslist-purpose.d.ts.map +0 -1
- package/dist/utils/ttl-cache.d.ts.map +0 -1
- package/dist/utils/url.d.ts.map +0 -1
|
@@ -1,31 +1,58 @@
|
|
|
1
|
-
|
|
1
|
+
import { AUDIT_ERROR_CODES, AuditProtocolError } from '../errors.js';
|
|
2
|
+
const DEFAULT_REDELIVERY_WINDOW = 1024;
|
|
3
|
+
function publicClaim(claim) {
|
|
4
|
+
return {
|
|
5
|
+
sequence: claim.sequence.toString(),
|
|
6
|
+
...(claim.previousSourceEventDigest === undefined
|
|
7
|
+
? {}
|
|
8
|
+
: { previousSourceEventDigest: claim.previousSourceEventDigest }),
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* In-process reference source-watermark state. Production AAP-3 needs
|
|
13
|
+
* durability. Memory is bounded by the pending (unreceipted) events plus the
|
|
14
|
+
* redelivery window, however long a gap stays open.
|
|
15
|
+
*/
|
|
2
16
|
export class MemoryAuditSourceState {
|
|
3
17
|
capabilities = { durability: 'ephemeral', atomicClaim: true };
|
|
4
18
|
states = new Map();
|
|
19
|
+
redeliveryWindow;
|
|
20
|
+
constructor(options = {}) {
|
|
21
|
+
this.redeliveryWindow = options.redeliveryWindow ?? DEFAULT_REDELIVERY_WINDOW;
|
|
22
|
+
if (!Number.isSafeInteger(this.redeliveryWindow) || this.redeliveryWindow < 0) {
|
|
23
|
+
throw new RangeError('Source redelivery window must be a non-negative safe integer');
|
|
24
|
+
}
|
|
25
|
+
}
|
|
5
26
|
async claimEvent(sourceId, eventId) {
|
|
6
27
|
const state = this.state(sourceId);
|
|
7
28
|
const existing = state.claims.get(eventId);
|
|
8
29
|
if (existing !== undefined) {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
? {}
|
|
13
|
-
: { previousSourceEventDigest: existing.previousSourceEventDigest }),
|
|
14
|
-
};
|
|
30
|
+
if (state.retained.delete(eventId))
|
|
31
|
+
state.retained.add(eventId);
|
|
32
|
+
return publicClaim(existing);
|
|
15
33
|
}
|
|
16
34
|
state.next += 1n;
|
|
17
|
-
const previousSourceEventDigest = state.eventDigests.get(state.next - 1n);
|
|
18
35
|
const claim = {
|
|
19
36
|
sequence: state.next,
|
|
20
|
-
...(
|
|
37
|
+
...(state.latestDigest === undefined ? {} : { previousSourceEventDigest: state.latestDigest }),
|
|
21
38
|
};
|
|
39
|
+
state.latestDigest = undefined;
|
|
22
40
|
state.claims.set(eventId, claim);
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
41
|
+
state.pending.set(claim.sequence, eventId);
|
|
42
|
+
return publicClaim(claim);
|
|
43
|
+
}
|
|
44
|
+
async abandonClaim(sourceId, eventId, sequence) {
|
|
45
|
+
const state = this.state(sourceId);
|
|
46
|
+
const claim = state.claims.get(eventId);
|
|
47
|
+
// An emitted claim may already be in flight, and a later claim has linked
|
|
48
|
+
// past this one; either way the sequence stays a visible pending gap.
|
|
49
|
+
if (claim === undefined || claim.sequence !== BigInt(sequence) ||
|
|
50
|
+
claim.eventDigest !== undefined || claim.sequence !== state.next)
|
|
51
|
+
return;
|
|
52
|
+
state.claims.delete(eventId);
|
|
53
|
+
state.pending.delete(claim.sequence);
|
|
54
|
+
state.next -= 1n;
|
|
55
|
+
state.latestDigest = claim.previousSourceEventDigest;
|
|
29
56
|
}
|
|
30
57
|
async markEmitted(sourceId, eventId, sequence, eventDigest) {
|
|
31
58
|
const state = this.state(sourceId);
|
|
@@ -33,47 +60,42 @@ export class MemoryAuditSourceState {
|
|
|
33
60
|
const claim = state.claims.get(eventId);
|
|
34
61
|
if (claim?.sequence !== parsed)
|
|
35
62
|
throw new RangeError('Unknown source event claim');
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
63
|
+
if (claim.eventDigest !== undefined && claim.eventDigest !== eventDigest) {
|
|
64
|
+
// The same conflict the recorder reports for a reused event ID, so a
|
|
65
|
+
// caller sees one error whichever layer catches the divergent content.
|
|
66
|
+
throw new AuditProtocolError(AUDIT_ERROR_CODES.EVENT_ID_CONFLICT, `Source event identity collision: ${eventId}`, { sourceId, eventId });
|
|
39
67
|
}
|
|
40
|
-
|
|
68
|
+
claim.eventDigest = eventDigest;
|
|
69
|
+
if (parsed === state.next)
|
|
70
|
+
state.latestDigest = eventDigest;
|
|
41
71
|
}
|
|
42
72
|
async markReceipted(sourceId, sequence) {
|
|
43
73
|
const parsed = BigInt(sequence);
|
|
44
74
|
const state = this.state(sourceId);
|
|
45
75
|
if (parsed < 1n || parsed > state.next)
|
|
46
76
|
throw new RangeError('Unknown source sequence');
|
|
47
|
-
|
|
77
|
+
const eventId = state.pending.get(parsed);
|
|
78
|
+
if (eventId === undefined)
|
|
48
79
|
return;
|
|
49
|
-
state.
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
for (const [eventId, claim] of state.claims) {
|
|
57
|
-
if (claim.sequence < state.receiptedWatermark)
|
|
58
|
-
state.claims.delete(eventId);
|
|
59
|
-
}
|
|
60
|
-
for (const sequenceNumber of state.eventDigests.keys()) {
|
|
61
|
-
if (sequenceNumber < state.receiptedWatermark)
|
|
62
|
-
state.eventDigests.delete(sequenceNumber);
|
|
80
|
+
state.pending.delete(parsed);
|
|
81
|
+
state.retained.add(eventId);
|
|
82
|
+
for (const oldest of state.retained) {
|
|
83
|
+
if (state.retained.size <= this.redeliveryWindow)
|
|
84
|
+
break;
|
|
85
|
+
state.retained.delete(oldest);
|
|
86
|
+
state.claims.delete(oldest);
|
|
63
87
|
}
|
|
64
88
|
}
|
|
65
89
|
async getState(sourceId) {
|
|
66
90
|
const state = this.state(sourceId);
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
pendingSequences.push(sequence.toString());
|
|
71
|
-
}
|
|
91
|
+
// Claims take strictly increasing sequences and are only ever removed, so
|
|
92
|
+
// the map's insertion order is already ascending.
|
|
93
|
+
const pending = [...state.pending.keys()];
|
|
72
94
|
return {
|
|
73
95
|
sourceId,
|
|
74
96
|
highestEmitted: state.next.toString(),
|
|
75
|
-
highestReceipted: state.
|
|
76
|
-
pendingSequences,
|
|
97
|
+
highestReceipted: (pending.length === 0 ? state.next : pending[0] - 1n).toString(),
|
|
98
|
+
pendingSequences: pending.map((value) => value.toString()),
|
|
77
99
|
};
|
|
78
100
|
}
|
|
79
101
|
state(sourceId) {
|
|
@@ -82,10 +104,9 @@ export class MemoryAuditSourceState {
|
|
|
82
104
|
return existing;
|
|
83
105
|
const created = {
|
|
84
106
|
next: 0n,
|
|
85
|
-
|
|
86
|
-
receipted: new Set(),
|
|
107
|
+
pending: new Map(),
|
|
87
108
|
claims: new Map(),
|
|
88
|
-
|
|
109
|
+
retained: new Set(),
|
|
89
110
|
};
|
|
90
111
|
this.states.set(sourceId, created);
|
|
91
112
|
return created;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"source-state.js","sourceRoot":"","sources":["../../../src/audit/providers/source-state.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"source-state.js","sourceRoot":"","sources":["../../../src/audit/providers/source-state.ts"],"names":[],"mappings":"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"}
|
|
@@ -442,4 +442,3 @@ export declare function toAuditHeadResponse(head: AuditHead | null): AuditHeadRe
|
|
|
442
442
|
export declare function toAuditListEntriesResponse(page: AuditReadEntriesPage): AuditListEntriesResponseV1;
|
|
443
443
|
export declare function toAuditInclusionProofResponse(proof: AuditBundleInclusionProofV1): AuditInclusionProofResponseV1;
|
|
444
444
|
export declare function toAuditConsistencyProofResponse(proof: AuditBundleConsistencyProofV1): AuditConsistencyProofResponseV1;
|
|
445
|
-
//# sourceMappingURL=read-contract.d.ts.map
|
|
@@ -78,8 +78,8 @@ export declare const MAX_READ_ENTRIES_LIMIT = 1000;
|
|
|
78
78
|
* proofs are needed, an {@link AuditCheckpointReadAccess}.
|
|
79
79
|
*
|
|
80
80
|
* Reads ride the journal's ordered `readRange`, so paging cost is independent of
|
|
81
|
-
* ledger size.
|
|
82
|
-
*
|
|
81
|
+
* ledger size. Each page is bounded by the head read before it, which decides
|
|
82
|
+
* whether a further page exists.
|
|
83
83
|
*/
|
|
84
84
|
export declare class LocalAuditReadService implements AuditReadService {
|
|
85
85
|
private readonly journal;
|
|
@@ -96,4 +96,3 @@ export declare class LocalAuditReadService implements AuditReadService {
|
|
|
96
96
|
}
|
|
97
97
|
/** One-call composition helper mirroring {@link createLocalAuditRecorder}. */
|
|
98
98
|
export declare function createLocalAuditReadService(deps: AuditReadServiceDeps): AuditReadService;
|
|
99
|
-
//# sourceMappingURL=read-service.d.ts.map
|
|
@@ -20,8 +20,8 @@ function requireDecimal(value, label) {
|
|
|
20
20
|
* proofs are needed, an {@link AuditCheckpointReadAccess}.
|
|
21
21
|
*
|
|
22
22
|
* Reads ride the journal's ordered `readRange`, so paging cost is independent of
|
|
23
|
-
* ledger size.
|
|
24
|
-
*
|
|
23
|
+
* ledger size. Each page is bounded by the head read before it, which decides
|
|
24
|
+
* whether a further page exists.
|
|
25
25
|
*/
|
|
26
26
|
export class LocalAuditReadService {
|
|
27
27
|
journal;
|
|
@@ -36,21 +36,26 @@ export class LocalAuditReadService {
|
|
|
36
36
|
async listEntries(query) {
|
|
37
37
|
const limit = clampLimit(query.limit);
|
|
38
38
|
const ledger = ledgerOf(query);
|
|
39
|
-
//
|
|
40
|
-
|
|
39
|
+
// The head is read first and bounds the page, so the echoed head and the
|
|
40
|
+
// cursor describe the same snapshot even while appends continue.
|
|
41
|
+
const head = await this.journal.getHead(ledger);
|
|
42
|
+
if (head === null)
|
|
43
|
+
return { entries: [], head, nextAfterSequence: null };
|
|
44
|
+
const headSequence = BigInt(head.sequence);
|
|
45
|
+
const entries = [];
|
|
41
46
|
for await (const entry of this.journal.readRange({
|
|
42
47
|
...ledger,
|
|
43
48
|
...(query.afterSequence === undefined ? {} : { afterSequence: query.afterSequence }),
|
|
44
|
-
limit
|
|
49
|
+
limit,
|
|
45
50
|
})) {
|
|
46
|
-
|
|
47
|
-
if (collected.length > limit)
|
|
51
|
+
if (BigInt(entry.core.sequence) > headSequence)
|
|
48
52
|
break;
|
|
53
|
+
entries.push(entry);
|
|
49
54
|
}
|
|
50
|
-
const
|
|
51
|
-
const
|
|
52
|
-
|
|
53
|
-
|
|
55
|
+
const last = entries[entries.length - 1];
|
|
56
|
+
const nextAfterSequence = last === undefined || last.core.sequence === head.sequence
|
|
57
|
+
? null
|
|
58
|
+
: last.core.sequence;
|
|
54
59
|
return { entries, head, nextAfterSequence };
|
|
55
60
|
}
|
|
56
61
|
async getLatestCheckpoint(ledger) {
|
|
@@ -104,7 +109,7 @@ export class LocalAuditReadService {
|
|
|
104
109
|
async entryAtSequence(ledger, sequence) {
|
|
105
110
|
const value = requireDecimal(sequence, 'sequence');
|
|
106
111
|
// `readRange` is exclusive on afterSequence, so start one below the target.
|
|
107
|
-
const afterSequence = value >
|
|
112
|
+
const afterSequence = value > 0n ? String(value - 1n) : undefined;
|
|
108
113
|
for await (const entry of this.journal.readRange({
|
|
109
114
|
...ledger,
|
|
110
115
|
...(afterSequence === undefined ? {} : { afterSequence }),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"read-service.js","sourceRoot":"","sources":["../../src/audit/read-service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AA6FpE,MAAM,CAAC,MAAM,0BAA0B,GAAG,GAAG,CAAC;AAC9C,MAAM,CAAC,MAAM,sBAAsB,GAAG,IAAI,CAAC;AAE3C,SAAS,UAAU,CAAC,KAAyB;IAC3C,IAAI,KAAK,KAAK,SAAS,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,0BAA0B,CAAC;IACtF,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,sBAAsB,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAC1E,CAAC;AAED,SAAS,QAAQ,CAAC,GAAmB;IACnC,OAAO,EAAE,QAAQ,EAAE,GAAG,CAAC,QAAQ,EAAE,aAAa,EAAE,GAAG,CAAC,aAAa,EAAE,CAAC;AACtE,CAAC;AAED,SAAS,cAAc,CAAC,KAAoB,EAAE,KAAa;IACzD,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACrC,MAAM,IAAI,kBAAkB,CAC1B,iBAAiB,CAAC,kBAAkB,EACpC,GAAG,KAAK,kDAAkD,EAC1D,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,CACnB,CAAC;IACJ,CAAC;IACD,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;AACvB,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,OAAO,qBAAqB;IACf,OAAO,CAAuB;IAC9B,WAAW,CAA6B;IAEzD,YAAY,IAA0B;QACpC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;QAC5B,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC;IACtC,CAAC;IAED,OAAO,CAAC,MAAsB;QAC5B,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;IAChD,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,KAA4B;QAC5C,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACtC,MAAM,MAAM,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;QAE/B,
|
|
1
|
+
{"version":3,"file":"read-service.js","sourceRoot":"","sources":["../../src/audit/read-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -54,25 +54,53 @@ export declare class AuditRecorderService {
|
|
|
54
54
|
private readonly config;
|
|
55
55
|
private readonly maxAppendConflicts;
|
|
56
56
|
private initialization?;
|
|
57
|
+
/** Highest head this recorder has itself appended in its epoch. */
|
|
58
|
+
private committedHead;
|
|
59
|
+
/** Highest head the journal has reported in a compare-and-append result. */
|
|
60
|
+
private reportedHead;
|
|
61
|
+
/** Write-ahead evidence objects held by submissions in flight, by object ID. */
|
|
62
|
+
private readonly heldEvidence;
|
|
57
63
|
constructor(config: AuditRecorderServiceConfig);
|
|
58
64
|
submitAuthenticated(submission: AuditRecorderSubmission, context: AuthenticatedAuditSubmissionContext): Promise<SignedAuditEntryV1>;
|
|
59
65
|
/**
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
66
|
+
* Registers this submission as a holder of each evidence object it carries.
|
|
67
|
+
* An object two submissions hold at once is marked shared for as long as
|
|
68
|
+
* either still holds it: both may have seen it as new, and the other may
|
|
69
|
+
* already have committed a reference to it.
|
|
70
|
+
*/
|
|
71
|
+
private holdEvidence;
|
|
72
|
+
private releaseEvidence;
|
|
73
|
+
/**
|
|
74
|
+
* Best-effort compensation for write-ahead evidence whose append failed. Only
|
|
75
|
+
* objects this submission newly stored are disposed: an object that already
|
|
76
|
+
* existed may be referenced by another committed entry, and so may one that
|
|
77
|
+
* a concurrent submission held at the same time. They are disposed only
|
|
78
|
+
* after re-confirming that no committed entry claims this event identity, so
|
|
79
|
+
* a raced idempotent commit is never stripped of its evidence. Failures here
|
|
80
|
+
* leave orphans for operator retention tooling.
|
|
64
81
|
*/
|
|
65
82
|
private disposeUncommittedEvidence;
|
|
66
83
|
private validateSubmissionEnvelope;
|
|
67
84
|
private validateEventAuthority;
|
|
85
|
+
/** Persists write-ahead evidence and returns the objects that did not exist before. */
|
|
68
86
|
private persistSubmittedEvidence;
|
|
69
87
|
private ensureInitialized;
|
|
70
88
|
private validateExistingGenesis;
|
|
71
89
|
private genesisEvent;
|
|
72
90
|
private appendEvent;
|
|
91
|
+
/**
|
|
92
|
+
* The compare-and-append result is the journal's authoritative head. One
|
|
93
|
+
* below a head this recorder had committed before issuing the append, or a
|
|
94
|
+
* different digest at a sequence the journal already reported, means a
|
|
95
|
+
* failover to a lagging primary or a restore. Retrying there would sign a
|
|
96
|
+
* second entry at a receipted sequence, so the recorder fails closed. The
|
|
97
|
+
* heads compared are the ones known when the append was issued, so a
|
|
98
|
+
* concurrent submission's later commit never makes a correct answer look
|
|
99
|
+
* stale.
|
|
100
|
+
*/
|
|
101
|
+
private assertNoRegression;
|
|
73
102
|
private identifyEvent;
|
|
74
103
|
private resolveDuplicate;
|
|
75
104
|
private buildCandidate;
|
|
76
105
|
private ledgerRef;
|
|
77
106
|
}
|
|
78
|
-
//# sourceMappingURL=recorder-service.d.ts.map
|
|
@@ -15,6 +15,14 @@ function sameHead(left, right) {
|
|
|
15
15
|
return left === right;
|
|
16
16
|
return left.entryDigest === right.entryDigest && left.sequence === right.sequence;
|
|
17
17
|
}
|
|
18
|
+
/** The later of two heads; at an equal sequence the first one is kept. */
|
|
19
|
+
function higherHead(current, candidate) {
|
|
20
|
+
if (candidate === null)
|
|
21
|
+
return current;
|
|
22
|
+
if (current === null)
|
|
23
|
+
return candidate;
|
|
24
|
+
return BigInt(candidate.sequence) > BigInt(current.sequence) ? candidate : current;
|
|
25
|
+
}
|
|
18
26
|
function sameSigner(left, right) {
|
|
19
27
|
return left.did === right.did && left.kid === right.kid && left.alg === right.alg;
|
|
20
28
|
}
|
|
@@ -31,6 +39,12 @@ export class AuditRecorderService {
|
|
|
31
39
|
config;
|
|
32
40
|
maxAppendConflicts;
|
|
33
41
|
initialization;
|
|
42
|
+
/** Highest head this recorder has itself appended in its epoch. */
|
|
43
|
+
committedHead = null;
|
|
44
|
+
/** Highest head the journal has reported in a compare-and-append result. */
|
|
45
|
+
reportedHead = null;
|
|
46
|
+
/** Write-ahead evidence objects held by submissions in flight, by object ID. */
|
|
47
|
+
heldEvidence = new Map();
|
|
34
48
|
constructor(config) {
|
|
35
49
|
this.config = config;
|
|
36
50
|
if ((config.previousEpochId === undefined) !==
|
|
@@ -62,29 +76,66 @@ export class AuditRecorderService {
|
|
|
62
76
|
throw new AuditProtocolError(AUDIT_ERROR_CODES.EPOCH_MISMATCH, 'Wrong audit ledger epoch');
|
|
63
77
|
}
|
|
64
78
|
await this.ensureInitialized();
|
|
65
|
-
|
|
79
|
+
const held = this.holdEvidence(submission.encryptedEvidence);
|
|
66
80
|
try {
|
|
67
|
-
|
|
81
|
+
const stored = await this.persistSubmittedEvidence(submission.encryptedEvidence, producerEvent);
|
|
82
|
+
try {
|
|
83
|
+
return await this.appendEvent(producerEvent, context, false, identity);
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
await this.disposeUncommittedEvidence(stored, identity);
|
|
87
|
+
throw error;
|
|
88
|
+
}
|
|
68
89
|
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
throw error;
|
|
90
|
+
finally {
|
|
91
|
+
this.releaseEvidence(held);
|
|
72
92
|
}
|
|
73
93
|
}
|
|
74
94
|
/**
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
*
|
|
78
|
-
*
|
|
95
|
+
* Registers this submission as a holder of each evidence object it carries.
|
|
96
|
+
* An object two submissions hold at once is marked shared for as long as
|
|
97
|
+
* either still holds it: both may have seen it as new, and the other may
|
|
98
|
+
* already have committed a reference to it.
|
|
79
99
|
*/
|
|
80
|
-
|
|
81
|
-
|
|
100
|
+
holdEvidence(evidence) {
|
|
101
|
+
const objectIds = [...new Set(evidence.map((item) => item.ref.objectId))];
|
|
102
|
+
for (const objectId of objectIds) {
|
|
103
|
+
const hold = this.heldEvidence.get(objectId);
|
|
104
|
+
if (hold === undefined)
|
|
105
|
+
this.heldEvidence.set(objectId, { holders: 1, shared: false });
|
|
106
|
+
else
|
|
107
|
+
this.heldEvidence.set(objectId, { holders: hold.holders + 1, shared: true });
|
|
108
|
+
}
|
|
109
|
+
return objectIds;
|
|
110
|
+
}
|
|
111
|
+
releaseEvidence(objectIds) {
|
|
112
|
+
for (const objectId of objectIds) {
|
|
113
|
+
const hold = this.heldEvidence.get(objectId);
|
|
114
|
+
if (hold.holders === 1)
|
|
115
|
+
this.heldEvidence.delete(objectId);
|
|
116
|
+
else
|
|
117
|
+
this.heldEvidence.set(objectId, { ...hold, holders: hold.holders - 1 });
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Best-effort compensation for write-ahead evidence whose append failed. Only
|
|
122
|
+
* objects this submission newly stored are disposed: an object that already
|
|
123
|
+
* existed may be referenced by another committed entry, and so may one that
|
|
124
|
+
* a concurrent submission held at the same time. They are disposed only
|
|
125
|
+
* after re-confirming that no committed entry claims this event identity, so
|
|
126
|
+
* a raced idempotent commit is never stripped of its evidence. Failures here
|
|
127
|
+
* leave orphans for operator retention tooling.
|
|
128
|
+
*/
|
|
129
|
+
async disposeUncommittedEvidence(stored, identity) {
|
|
130
|
+
if (stored.length === 0 || this.config.evidence === undefined)
|
|
82
131
|
return;
|
|
83
132
|
try {
|
|
84
133
|
const committed = await this.config.journal.getByIdempotencyKey(this.config.ledgerId, identity.idempotencyKey);
|
|
85
134
|
if (committed !== null)
|
|
86
135
|
return;
|
|
87
|
-
for (const item of
|
|
136
|
+
for (const item of stored) {
|
|
137
|
+
if (this.heldEvidence.get(item.ref.objectId)?.shared === true)
|
|
138
|
+
continue;
|
|
88
139
|
await this.config.evidence.applyRetention({
|
|
89
140
|
kind: 'dispose',
|
|
90
141
|
ref: item.ref,
|
|
@@ -114,15 +165,17 @@ export class AuditRecorderService {
|
|
|
114
165
|
throw new AuditProtocolError(AUDIT_ERROR_CODES.UNAUTHORIZED_SUBMISSION, 'Event tenant does not match the authenticated tenant authority');
|
|
115
166
|
}
|
|
116
167
|
}
|
|
168
|
+
/** Persists write-ahead evidence and returns the objects that did not exist before. */
|
|
117
169
|
async persistSubmittedEvidence(evidence, event) {
|
|
118
170
|
if (evidence.length === 0)
|
|
119
|
-
return;
|
|
171
|
+
return [];
|
|
120
172
|
if (this.config.evidence === undefined) {
|
|
121
173
|
throw new AuditProtocolError(AUDIT_ERROR_CODES.EVIDENCE_FAILURE, 'Encrypted evidence was submitted but no evidence provider is configured');
|
|
122
174
|
}
|
|
123
175
|
try {
|
|
124
176
|
const refs = new Map(collectAuditEvidenceRefs(event).map((ref) => [ref.objectId, ref]));
|
|
125
177
|
const submitted = new Set();
|
|
178
|
+
const stored = [];
|
|
126
179
|
for (const item of evidence) {
|
|
127
180
|
const referenced = refs.get(item.ref.objectId);
|
|
128
181
|
if (submitted.has(item.ref.objectId) || referenced === undefined ||
|
|
@@ -130,8 +183,12 @@ export class AuditRecorderService {
|
|
|
130
183
|
throw new AuditProtocolError(AUDIT_ERROR_CODES.EVIDENCE_FAILURE, 'Submitted evidence does not exactly match a unique frozen event reference', { objectId: item.ref.objectId });
|
|
131
184
|
}
|
|
132
185
|
submitted.add(item.ref.objectId);
|
|
186
|
+
const existed = await this.config.evidence.has(item.ref);
|
|
133
187
|
await this.config.evidence.putIfAbsent(item);
|
|
188
|
+
if (!existed)
|
|
189
|
+
stored.push(item);
|
|
134
190
|
}
|
|
191
|
+
return stored;
|
|
135
192
|
}
|
|
136
193
|
catch (error) {
|
|
137
194
|
if (error instanceof AuditProtocolError &&
|
|
@@ -242,7 +299,14 @@ export class AuditRecorderService {
|
|
|
242
299
|
}
|
|
243
300
|
const ledger = this.ledgerRef();
|
|
244
301
|
for (let attempt = 0; attempt <= this.maxAppendConflicts; attempt += 1) {
|
|
245
|
-
|
|
302
|
+
// A read behind this recorder's own commits (a lagging replica) is not
|
|
303
|
+
// an append position: compare-and-append against the committed head, so
|
|
304
|
+
// a stale read costs one retry and a journal that really moved backwards
|
|
305
|
+
// answers with a conflict that proves it instead of accepting a second
|
|
306
|
+
// entry at a receipted sequence.
|
|
307
|
+
const committed = this.committedHead;
|
|
308
|
+
const reported = this.reportedHead;
|
|
309
|
+
const head = higherHead(committed, await this.config.journal.getHead(ledger));
|
|
246
310
|
if (genesis && head !== null) {
|
|
247
311
|
const raced = await this.config.journal.getByIdempotencyKey(this.config.ledgerId, idempotencyKey);
|
|
248
312
|
if (raced !== null)
|
|
@@ -261,20 +325,52 @@ export class AuditRecorderService {
|
|
|
261
325
|
catch (error) {
|
|
262
326
|
throw new AuditProtocolError(AUDIT_ERROR_CODES.JOURNAL_FAILURE, 'Audit journal append failed', undefined, { cause: error });
|
|
263
327
|
}
|
|
264
|
-
if (result.kind === 'appended'
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
: result.entry
|
|
328
|
+
if (result.kind === 'appended') {
|
|
329
|
+
const appended = {
|
|
330
|
+
...ledger,
|
|
331
|
+
sequence: result.entry.core.sequence,
|
|
332
|
+
entryDigest: result.entry.entryDigest,
|
|
333
|
+
};
|
|
334
|
+
this.committedHead = higherHead(this.committedHead, appended);
|
|
335
|
+
this.reportedHead = higherHead(this.reportedHead, appended);
|
|
336
|
+
return result.entry;
|
|
268
337
|
}
|
|
269
|
-
if (result.kind === 'idempotency_conflict') {
|
|
270
|
-
|
|
338
|
+
if (result.kind === 'duplicate' || result.kind === 'idempotency_conflict') {
|
|
339
|
+
const existing = result.kind === 'duplicate' ? result.entry : result.existing;
|
|
340
|
+
// A replica that lost the cold-start genesis race finds a genesis that
|
|
341
|
+
// differs only in recorder-authored timing; it is accepted on epoch
|
|
342
|
+
// configuration, never as an event-identity conflict.
|
|
343
|
+
return genesis
|
|
344
|
+
? this.validateExistingGenesis(existing)
|
|
345
|
+
: this.resolveDuplicate(existing, eventDigest);
|
|
271
346
|
}
|
|
347
|
+
this.assertNoRegression(result.actualHead, committed, reported);
|
|
348
|
+
this.reportedHead = higherHead(this.reportedHead, result.actualHead);
|
|
272
349
|
if (sameHead(head, result.actualHead)) {
|
|
273
350
|
throw new AuditProtocolError(AUDIT_ERROR_CODES.JOURNAL_FAILURE, 'Audit journal reported a head conflict without advancing its head');
|
|
274
351
|
}
|
|
275
352
|
}
|
|
276
353
|
throw new AuditProtocolError(AUDIT_ERROR_CODES.APPEND_CONFLICT_EXHAUSTED, 'Audit append conflict retry budget exhausted');
|
|
277
354
|
}
|
|
355
|
+
/**
|
|
356
|
+
* The compare-and-append result is the journal's authoritative head. One
|
|
357
|
+
* below a head this recorder had committed before issuing the append, or a
|
|
358
|
+
* different digest at a sequence the journal already reported, means a
|
|
359
|
+
* failover to a lagging primary or a restore. Retrying there would sign a
|
|
360
|
+
* second entry at a receipted sequence, so the recorder fails closed. The
|
|
361
|
+
* heads compared are the ones known when the append was issued, so a
|
|
362
|
+
* concurrent submission's later commit never makes a correct answer look
|
|
363
|
+
* stale.
|
|
364
|
+
*/
|
|
365
|
+
assertNoRegression(actual, committed, reported) {
|
|
366
|
+
const forks = (known) => known !== null && actual !== null &&
|
|
367
|
+
known.sequence === actual.sequence && known.entryDigest !== actual.entryDigest;
|
|
368
|
+
if ((committed !== null &&
|
|
369
|
+
(actual === null || BigInt(actual.sequence) < BigInt(committed.sequence))) ||
|
|
370
|
+
forks(committed) || forks(reported)) {
|
|
371
|
+
throw new AuditProtocolError(AUDIT_ERROR_CODES.JOURNAL_FAILURE, 'Audit journal head moved behind a head this recorder already committed or saw', { committedSequence: committed?.sequence, reportedSequence: actual?.sequence });
|
|
372
|
+
}
|
|
373
|
+
}
|
|
278
374
|
async identifyEvent(event, context) {
|
|
279
375
|
const eventDigest = await digestAuditEvent(this.config.hasher, event);
|
|
280
376
|
const idempotencyKey = await hashAuditValue(this.config.hasher, AUDIT_DIGEST_DOMAINS.idempotency, {
|