life-as-api 0.2.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/LICENSE +21 -0
- package/README.md +377 -0
- package/dist/agent/finance-agent.d.ts +44 -0
- package/dist/agent/finance-agent.js +75 -0
- package/dist/agent/finance-agent.js.map +1 -0
- package/dist/agent/legal-agent.d.ts +44 -0
- package/dist/agent/legal-agent.js +76 -0
- package/dist/agent/legal-agent.js.map +1 -0
- package/dist/agent/medical-agent.d.ts +44 -0
- package/dist/agent/medical-agent.js +75 -0
- package/dist/agent/medical-agent.js.map +1 -0
- package/dist/agent/trusted-agent-registry.d.ts +53 -0
- package/dist/agent/trusted-agent-registry.js +57 -0
- package/dist/agent/trusted-agent-registry.js.map +1 -0
- package/dist/audit/audit-chain-verifier.d.ts +10 -0
- package/dist/audit/audit-chain-verifier.js +67 -0
- package/dist/audit/audit-chain-verifier.js.map +1 -0
- package/dist/audit/audit-log.d.ts +48 -0
- package/dist/audit/audit-log.js +74 -0
- package/dist/audit/audit-log.js.map +1 -0
- package/dist/audit/sqlite-audit-log.d.ts +29 -0
- package/dist/audit/sqlite-audit-log.js +142 -0
- package/dist/audit/sqlite-audit-log.js.map +1 -0
- package/dist/auth/access-context-issuer.d.ts +18 -0
- package/dist/auth/access-context-issuer.js +88 -0
- package/dist/auth/access-context-issuer.js.map +1 -0
- package/dist/auth/assert-authorized-for-subject.d.ts +2 -0
- package/dist/auth/assert-authorized-for-subject.js +20 -0
- package/dist/auth/assert-authorized-for-subject.js.map +1 -0
- package/dist/auth/backend-context-minting-boundary.d.ts +23 -0
- package/dist/auth/backend-context-minting-boundary.js +281 -0
- package/dist/auth/backend-context-minting-boundary.js.map +1 -0
- package/dist/auth/default-authorization-policy.d.ts +7 -0
- package/dist/auth/default-authorization-policy.js +64 -0
- package/dist/auth/default-authorization-policy.js.map +1 -0
- package/dist/auth/fake-auth-adapter.d.ts +7 -0
- package/dist/auth/fake-auth-adapter.js +27 -0
- package/dist/auth/fake-auth-adapter.js.map +1 -0
- package/dist/auth/http-client.d.ts +12 -0
- package/dist/auth/http-client.js +7 -0
- package/dist/auth/http-client.js.map +1 -0
- package/dist/auth/in-memory-grant-resolver.d.ts +21 -0
- package/dist/auth/in-memory-grant-resolver.js +73 -0
- package/dist/auth/in-memory-grant-resolver.js.map +1 -0
- package/dist/auth/in-memory-tenant-boundary.d.ts +16 -0
- package/dist/auth/in-memory-tenant-boundary.js +37 -0
- package/dist/auth/in-memory-tenant-boundary.js.map +1 -0
- package/dist/auth/jwks-key-ring-auth-adapter.d.ts +38 -0
- package/dist/auth/jwks-key-ring-auth-adapter.js +123 -0
- package/dist/auth/jwks-key-ring-auth-adapter.js.map +1 -0
- package/dist/auth/jwks-key-ring.d.ts +25 -0
- package/dist/auth/jwks-key-ring.js +111 -0
- package/dist/auth/jwks-key-ring.js.map +1 -0
- package/dist/auth/jwt-auth-adapter.d.ts +15 -0
- package/dist/auth/jwt-auth-adapter.js +59 -0
- package/dist/auth/jwt-auth-adapter.js.map +1 -0
- package/dist/auth/jwt-core.d.ts +32 -0
- package/dist/auth/jwt-core.js +226 -0
- package/dist/auth/jwt-core.js.map +1 -0
- package/dist/auth/jwt-key-ring-auth-adapter.d.ts +16 -0
- package/dist/auth/jwt-key-ring-auth-adapter.js +58 -0
- package/dist/auth/jwt-key-ring-auth-adapter.js.map +1 -0
- package/dist/auth/oidc-discovery.d.ts +15 -0
- package/dist/auth/oidc-discovery.js +46 -0
- package/dist/auth/oidc-discovery.js.map +1 -0
- package/dist/auth/production-scoped-life-api.d.ts +58 -0
- package/dist/auth/production-scoped-life-api.js +802 -0
- package/dist/auth/production-scoped-life-api.js.map +1 -0
- package/dist/auth/proposal-scope-inspector.d.ts +3 -0
- package/dist/auth/proposal-scope-inspector.js +42 -0
- package/dist/auth/proposal-scope-inspector.js.map +1 -0
- package/dist/auth/proposal-scoped-life-api.d.ts +21 -0
- package/dist/auth/proposal-scoped-life-api.js +168 -0
- package/dist/auth/proposal-scoped-life-api.js.map +1 -0
- package/dist/auth/rate-limited-context-minting-boundary.d.ts +27 -0
- package/dist/auth/rate-limited-context-minting-boundary.js +77 -0
- package/dist/auth/rate-limited-context-minting-boundary.js.map +1 -0
- package/dist/auth/revocation-aware-auth-adapter.d.ts +21 -0
- package/dist/auth/revocation-aware-auth-adapter.js +88 -0
- package/dist/auth/revocation-aware-auth-adapter.js.map +1 -0
- package/dist/auth/sqlite-grant-resolver.d.ts +8 -0
- package/dist/auth/sqlite-grant-resolver.js +78 -0
- package/dist/auth/sqlite-grant-resolver.js.map +1 -0
- package/dist/auth/sqlite-tenant-boundary.d.ts +7 -0
- package/dist/auth/sqlite-tenant-boundary.js +41 -0
- package/dist/auth/sqlite-tenant-boundary.js.map +1 -0
- package/dist/auth/static-jwt-key-ring.d.ts +13 -0
- package/dist/auth/static-jwt-key-ring.js +73 -0
- package/dist/auth/static-jwt-key-ring.js.map +1 -0
- package/dist/auth/subject-scoped-life-api.d.ts +14 -0
- package/dist/auth/subject-scoped-life-api.js +51 -0
- package/dist/auth/subject-scoped-life-api.js.map +1 -0
- package/dist/auth/test-context-minting-boundary.d.ts +13 -0
- package/dist/auth/test-context-minting-boundary.js +74 -0
- package/dist/auth/test-context-minting-boundary.js.map +1 -0
- package/dist/auth/types.d.ts +77 -0
- package/dist/auth/types.js +16 -0
- package/dist/auth/types.js.map +1 -0
- package/dist/compliance/subject-data-report.d.ts +43 -0
- package/dist/compliance/subject-data-report.js +155 -0
- package/dist/compliance/subject-data-report.js.map +1 -0
- package/dist/consent/consent-guard.d.ts +4 -0
- package/dist/consent/consent-guard.js +37 -0
- package/dist/consent/consent-guard.js.map +1 -0
- package/dist/consent/grant-registry.d.ts +7 -0
- package/dist/consent/grant-registry.js +13 -0
- package/dist/consent/grant-registry.js.map +1 -0
- package/dist/consent/intersect-selector.d.ts +3 -0
- package/dist/consent/intersect-selector.js +66 -0
- package/dist/consent/intersect-selector.js.map +1 -0
- package/dist/contract/diagnostics.d.ts +32 -0
- package/dist/contract/diagnostics.js +112 -0
- package/dist/contract/diagnostics.js.map +1 -0
- package/dist/contract/project-contracts.d.ts +5 -0
- package/dist/contract/project-contracts.js +159 -0
- package/dist/contract/project-contracts.js.map +1 -0
- package/dist/contract/types.d.ts +32 -0
- package/dist/contract/types.js +5 -0
- package/dist/contract/types.js.map +1 -0
- package/dist/crypto/aes-gcm.d.ts +11 -0
- package/dist/crypto/aes-gcm.js +78 -0
- package/dist/crypto/aes-gcm.js.map +1 -0
- package/dist/crypto/claim-serializer.d.ts +26 -0
- package/dist/crypto/claim-serializer.js +59 -0
- package/dist/crypto/claim-serializer.js.map +1 -0
- package/dist/crypto/sha256.d.ts +12 -0
- package/dist/crypto/sha256.js +40 -0
- package/dist/crypto/sha256.js.map +1 -0
- package/dist/crypto/static-key.d.ts +11 -0
- package/dist/crypto/static-key.js +60 -0
- package/dist/crypto/static-key.js.map +1 -0
- package/dist/crypto/types.d.ts +20 -0
- package/dist/crypto/types.js +8 -0
- package/dist/crypto/types.js.map +1 -0
- package/dist/datasource/trusted-data-source-registry.d.ts +51 -0
- package/dist/datasource/trusted-data-source-registry.js +57 -0
- package/dist/datasource/trusted-data-source-registry.js.map +1 -0
- package/dist/erasure/tombstone.d.ts +13 -0
- package/dist/erasure/tombstone.js +20 -0
- package/dist/erasure/tombstone.js.map +1 -0
- package/dist/evidence/evidence-backed-claim-creator.d.ts +48 -0
- package/dist/evidence/evidence-backed-claim-creator.js +107 -0
- package/dist/evidence/evidence-backed-claim-creator.js.map +1 -0
- package/dist/evidence/in-memory-raw-document-store.d.ts +26 -0
- package/dist/evidence/in-memory-raw-document-store.js +84 -0
- package/dist/evidence/in-memory-raw-document-store.js.map +1 -0
- package/dist/evidence/raw-document-store.d.ts +12 -0
- package/dist/evidence/raw-document-store.js +8 -0
- package/dist/evidence/raw-document-store.js.map +1 -0
- package/dist/evidence/source-evidence-validator.d.ts +4 -0
- package/dist/evidence/source-evidence-validator.js +14 -0
- package/dist/evidence/source-evidence-validator.js.map +1 -0
- package/dist/evidence/sqlite-raw-document-store.d.ts +19 -0
- package/dist/evidence/sqlite-raw-document-store.js +122 -0
- package/dist/evidence/sqlite-raw-document-store.js.map +1 -0
- package/dist/guardian/guardian-registry.d.ts +96 -0
- package/dist/guardian/guardian-registry.js +95 -0
- package/dist/guardian/guardian-registry.js.map +1 -0
- package/dist/index.d.ts +44 -0
- package/dist/index.js +72 -0
- package/dist/index.js.map +1 -0
- package/dist/observability/health.d.ts +12 -0
- package/dist/observability/health.js +16 -0
- package/dist/observability/health.js.map +1 -0
- package/dist/observability/logger.d.ts +21 -0
- package/dist/observability/logger.js +40 -0
- package/dist/observability/logger.js.map +1 -0
- package/dist/observability/metrics.d.ts +15 -0
- package/dist/observability/metrics.js +52 -0
- package/dist/observability/metrics.js.map +1 -0
- package/dist/persistence/backup.d.ts +24 -0
- package/dist/persistence/backup.js +251 -0
- package/dist/persistence/backup.js.map +1 -0
- package/dist/persistence/decryptability-scan.d.ts +10 -0
- package/dist/persistence/decryptability-scan.js +144 -0
- package/dist/persistence/decryptability-scan.js.map +1 -0
- package/dist/persistence/in-memory-unit-of-work.d.ts +11 -0
- package/dist/persistence/in-memory-unit-of-work.js +32 -0
- package/dist/persistence/in-memory-unit-of-work.js.map +1 -0
- package/dist/persistence/key-availability.d.ts +9 -0
- package/dist/persistence/key-availability.js +125 -0
- package/dist/persistence/key-availability.js.map +1 -0
- package/dist/persistence/sqlite/migrations.d.ts +9 -0
- package/dist/persistence/sqlite/migrations.js +535 -0
- package/dist/persistence/sqlite/migrations.js.map +1 -0
- package/dist/persistence/sqlite/schema.d.ts +10 -0
- package/dist/persistence/sqlite/schema.js +101 -0
- package/dist/persistence/sqlite/schema.js.map +1 -0
- package/dist/persistence/sqlite/sqlite-fact-store.d.ts +24 -0
- package/dist/persistence/sqlite/sqlite-fact-store.js +207 -0
- package/dist/persistence/sqlite/sqlite-fact-store.js.map +1 -0
- package/dist/persistence/sqlite/sqlite-source-registry.d.ts +17 -0
- package/dist/persistence/sqlite/sqlite-source-registry.js +132 -0
- package/dist/persistence/sqlite/sqlite-source-registry.js.map +1 -0
- package/dist/persistence/sqlite/sqlite-unit-of-work.d.ts +8 -0
- package/dist/persistence/sqlite/sqlite-unit-of-work.js +41 -0
- package/dist/persistence/sqlite/sqlite-unit-of-work.js.map +1 -0
- package/dist/persistence/sqlite/types.d.ts +24 -0
- package/dist/persistence/sqlite/types.js +28 -0
- package/dist/persistence/sqlite/types.js.map +1 -0
- package/dist/persistence/unit-of-work.d.ts +6 -0
- package/dist/persistence/unit-of-work.js +15 -0
- package/dist/persistence/unit-of-work.js.map +1 -0
- package/dist/proposal/accepted-claim-appender.d.ts +7 -0
- package/dist/proposal/accepted-claim-appender.js +16 -0
- package/dist/proposal/accepted-claim-appender.js.map +1 -0
- package/dist/proposal/in-memory-proposal-queue.d.ts +21 -0
- package/dist/proposal/in-memory-proposal-queue.js +218 -0
- package/dist/proposal/in-memory-proposal-queue.js.map +1 -0
- package/dist/proposal/policy-aware-proposal-queue.d.ts +23 -0
- package/dist/proposal/policy-aware-proposal-queue.js +162 -0
- package/dist/proposal/policy-aware-proposal-queue.js.map +1 -0
- package/dist/proposal/proposal-policy.d.ts +37 -0
- package/dist/proposal/proposal-policy.js +72 -0
- package/dist/proposal/proposal-policy.js.map +1 -0
- package/dist/proposal/proposal-queue.d.ts +13 -0
- package/dist/proposal/proposal-queue.js +15 -0
- package/dist/proposal/proposal-queue.js.map +1 -0
- package/dist/proposal/source-aware-claim-appender.d.ts +13 -0
- package/dist/proposal/source-aware-claim-appender.js +47 -0
- package/dist/proposal/source-aware-claim-appender.js.map +1 -0
- package/dist/proposal/sqlite-proposal-queue.d.ts +26 -0
- package/dist/proposal/sqlite-proposal-queue.js +282 -0
- package/dist/proposal/sqlite-proposal-queue.js.map +1 -0
- package/dist/resolution/resolve-claims.d.ts +4 -0
- package/dist/resolution/resolve-claims.js +101 -0
- package/dist/resolution/resolve-claims.js.map +1 -0
- package/dist/resolution/trust-profile.d.ts +12 -0
- package/dist/resolution/trust-profile.js +23 -0
- package/dist/resolution/trust-profile.js.map +1 -0
- package/dist/resolution/types.d.ts +15 -0
- package/dist/resolution/types.js +8 -0
- package/dist/resolution/types.js.map +1 -0
- package/dist/sdk/create-backend-integrated-life-api-for-test.d.ts +23 -0
- package/dist/sdk/create-backend-integrated-life-api-for-test.js +240 -0
- package/dist/sdk/create-backend-integrated-life-api-for-test.js.map +1 -0
- package/dist/sdk/create-life-api.d.ts +55 -0
- package/dist/sdk/create-life-api.js +251 -0
- package/dist/sdk/create-life-api.js.map +1 -0
- package/dist/sdk/create-sqlite-life-api.d.ts +33 -0
- package/dist/sdk/create-sqlite-life-api.js +654 -0
- package/dist/sdk/create-sqlite-life-api.js.map +1 -0
- package/dist/sdk/life-api.d.ts +27 -0
- package/dist/sdk/life-api.js +17 -0
- package/dist/sdk/life-api.js.map +1 -0
- package/dist/sdk/validation.d.ts +8 -0
- package/dist/sdk/validation.js +216 -0
- package/dist/sdk/validation.js.map +1 -0
- package/dist/source/in-memory-source-registry.d.ts +15 -0
- package/dist/source/in-memory-source-registry.js +104 -0
- package/dist/source/in-memory-source-registry.js.map +1 -0
- package/dist/source/source-aware-fact-store.d.ts +19 -0
- package/dist/source/source-aware-fact-store.js +40 -0
- package/dist/source/source-aware-fact-store.js.map +1 -0
- package/dist/source/source-kind-predicate-policy.d.ts +4 -0
- package/dist/source/source-kind-predicate-policy.js +62 -0
- package/dist/source/source-kind-predicate-policy.js.map +1 -0
- package/dist/source/source-registry.d.ts +11 -0
- package/dist/source/source-registry.js +12 -0
- package/dist/source/source-registry.js.map +1 -0
- package/dist/store/in-memory-fact-store.d.ts +25 -0
- package/dist/store/in-memory-fact-store.js +192 -0
- package/dist/store/in-memory-fact-store.js.map +1 -0
- package/dist/surface/context-query.d.ts +21 -0
- package/dist/surface/context-query.js +113 -0
- package/dist/surface/context-query.js.map +1 -0
- package/dist/surface/evidence-backed-context-query.d.ts +62 -0
- package/dist/surface/evidence-backed-context-query.js +240 -0
- package/dist/surface/evidence-backed-context-query.js.map +1 -0
- package/dist/types/access-context.d.ts +25 -0
- package/dist/types/access-context.js +6 -0
- package/dist/types/access-context.js.map +1 -0
- package/dist/types/claim.d.ts +48 -0
- package/dist/types/claim.js +5 -0
- package/dist/types/claim.js.map +1 -0
- package/dist/types/consent.d.ts +41 -0
- package/dist/types/consent.js +3 -0
- package/dist/types/consent.js.map +1 -0
- package/dist/types/crypto-boundary.d.ts +12 -0
- package/dist/types/crypto-boundary.js +15 -0
- package/dist/types/crypto-boundary.js.map +1 -0
- package/dist/types/evidence.d.ts +31 -0
- package/dist/types/evidence.js +8 -0
- package/dist/types/evidence.js.map +1 -0
- package/dist/types/fact-store.d.ts +24 -0
- package/dist/types/fact-store.js +12 -0
- package/dist/types/fact-store.js.map +1 -0
- package/dist/types/ids.d.ts +36 -0
- package/dist/types/ids.js +11 -0
- package/dist/types/ids.js.map +1 -0
- package/dist/types/proposal.d.ts +38 -0
- package/dist/types/proposal.js +7 -0
- package/dist/types/proposal.js.map +1 -0
- package/dist/types/source.d.ts +33 -0
- package/dist/types/source.js +6 -0
- package/dist/types/source.js.map +1 -0
- package/dist/types/trust.d.ts +24 -0
- package/dist/types/trust.js +5 -0
- package/dist/types/trust.js.map +1 -0
- package/dist/utilities/deep-freeze.d.ts +1 -0
- package/dist/utilities/deep-freeze.js +17 -0
- package/dist/utilities/deep-freeze.js.map +1 -0
- package/package.json +55 -0
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
// InMemoryRawDocumentStore — Slice-09.
|
|
2
|
+
//
|
|
3
|
+
// RAW_DOCUMENT_BYTES_ENCRYPTED_AT_REST_001: stores EncryptedBlob, not plaintext bytes.
|
|
4
|
+
// RAW_DOCUMENT_IMMUTABLE_001: no update/delete path exists.
|
|
5
|
+
// RAW_DOCUMENT_ACCESS_BOUND_001: putDocument/getDocument restricted to EvidenceWriter.
|
|
6
|
+
// RAW_DOCUMENT_AGENT_NO_DIRECT_READ_001: runtime guard on putDocument + getDocument.
|
|
7
|
+
import { asEvidenceId, asISOTime } from "../types/ids.js";
|
|
8
|
+
function isEvidenceWriter(ctx) {
|
|
9
|
+
return ctx.kind === "owner" || ctx.kind === "system_projection" || ctx.kind === "test";
|
|
10
|
+
}
|
|
11
|
+
export class InMemoryRawDocumentStore {
|
|
12
|
+
_crypto;
|
|
13
|
+
_entries = new Map();
|
|
14
|
+
constructor(_crypto) {
|
|
15
|
+
this._crypto = _crypto;
|
|
16
|
+
}
|
|
17
|
+
async putDocument(ctx, input) {
|
|
18
|
+
if (!isEvidenceWriter(ctx)) {
|
|
19
|
+
throw new Error("RAW_DOCUMENT_ACCESS_BOUND_001: only Owner/System/Test may write raw documents");
|
|
20
|
+
}
|
|
21
|
+
const id = asEvidenceId(`ev_${globalThis.crypto.randomUUID()}`);
|
|
22
|
+
const encryptedBlob = await this._crypto.encryptBytes(input.bytes);
|
|
23
|
+
const createdAt = asISOTime(new Date().toISOString());
|
|
24
|
+
const ref = Object.freeze({
|
|
25
|
+
id,
|
|
26
|
+
uri: `evidence://${id}`,
|
|
27
|
+
mimeType: input.mimeType,
|
|
28
|
+
byteLength: input.bytes.byteLength,
|
|
29
|
+
encrypted: true,
|
|
30
|
+
createdAt,
|
|
31
|
+
...(input.label !== undefined ? { label: input.label } : {}),
|
|
32
|
+
});
|
|
33
|
+
this._entries.set(id, {
|
|
34
|
+
ref,
|
|
35
|
+
encryptedBlob,
|
|
36
|
+
createdBy: ctx,
|
|
37
|
+
...(input.metadata !== undefined ? { metadata: Object.freeze({ ...input.metadata }) } : {}),
|
|
38
|
+
});
|
|
39
|
+
return ref;
|
|
40
|
+
}
|
|
41
|
+
// ── Unit-of-Work snapshot support (UNIT_OF_WORK_IN_MEMORY_ATOMIC_BEHAVIOR_001) ──
|
|
42
|
+
_uowSnapshot() {
|
|
43
|
+
return new Map(this._entries);
|
|
44
|
+
}
|
|
45
|
+
_uowRestore(snap) {
|
|
46
|
+
this._entries.clear();
|
|
47
|
+
for (const [k, v] of snap)
|
|
48
|
+
this._entries.set(k, v);
|
|
49
|
+
}
|
|
50
|
+
async getDocument(ctx, evidenceId) {
|
|
51
|
+
if (!isEvidenceWriter(ctx)) {
|
|
52
|
+
throw new Error("RAW_DOCUMENT_AGENT_NO_DIRECT_READ_001: AgentConsentContext and AuditContext cannot read raw document bytes");
|
|
53
|
+
}
|
|
54
|
+
const entry = this._entries.get(evidenceId);
|
|
55
|
+
if (entry === undefined)
|
|
56
|
+
return undefined;
|
|
57
|
+
// Decrypt on every call — plaintext never cached in memory (RAW_DOCUMENT_BYTES_ENCRYPTED_AT_REST_001).
|
|
58
|
+
const plainBytes = await this._crypto.decryptBytes(entry.encryptedBlob);
|
|
59
|
+
return Object.freeze({
|
|
60
|
+
id: entry.ref.id,
|
|
61
|
+
mimeType: entry.ref.mimeType,
|
|
62
|
+
byteLength: entry.ref.byteLength,
|
|
63
|
+
createdAt: entry.ref.createdAt,
|
|
64
|
+
createdBy: entry.createdBy,
|
|
65
|
+
plainBytes: new Uint8Array(plainBytes), // defensive copy
|
|
66
|
+
...(entry.ref.label !== undefined ? { label: entry.ref.label } : {}),
|
|
67
|
+
...(entry.metadata !== undefined ? { metadata: entry.metadata } : {}),
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
getEvidenceRef(ctx, evidenceId) {
|
|
71
|
+
if (ctx == null)
|
|
72
|
+
throw new TypeError("AccessContext is required");
|
|
73
|
+
return this._entries.get(evidenceId)?.ref;
|
|
74
|
+
}
|
|
75
|
+
listEvidenceRefs(ctx, filter) {
|
|
76
|
+
if (ctx == null)
|
|
77
|
+
throw new TypeError("AccessContext is required");
|
|
78
|
+
let refs = Array.from(this._entries.values()).map((e) => e.ref);
|
|
79
|
+
if (filter?.mimeType !== undefined)
|
|
80
|
+
refs = refs.filter((r) => r.mimeType === filter.mimeType);
|
|
81
|
+
return refs;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=in-memory-raw-document-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"in-memory-raw-document-store.js","sourceRoot":"","sources":["../../src/evidence/in-memory-raw-document-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { EvidenceId } from "../types/ids.js";
|
|
2
|
+
import type { AccessContext } from "../types/access-context.js";
|
|
3
|
+
import type { EvidenceFilter, EvidenceRef, EvidenceWriter, RawDocument, RawDocumentInput } from "../types/evidence.js";
|
|
4
|
+
export interface RawDocumentStore {
|
|
5
|
+
putDocument(ctx: EvidenceWriter, input: RawDocumentInput): Promise<EvidenceRef>;
|
|
6
|
+
getDocument(ctx: EvidenceWriter, evidenceId: EvidenceId): Promise<RawDocument | undefined>;
|
|
7
|
+
getEvidenceRef(ctx: AccessContext, evidenceId: EvidenceId): EvidenceRef | undefined;
|
|
8
|
+
listEvidenceRefs(ctx: AccessContext, filter?: EvidenceFilter): EvidenceRef[];
|
|
9
|
+
}
|
|
10
|
+
export interface FactoryCompatibleRawDocumentStore extends RawDocumentStore {
|
|
11
|
+
readonly factoryCompatible: "durable-raw-document-store";
|
|
12
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
// RawDocumentStore interface — Slice-09.
|
|
2
|
+
//
|
|
3
|
+
// RAW_DOCUMENT_STORE_EXISTS_001: a single typed home for encrypted raw documents.
|
|
4
|
+
// RAW_DOCUMENT_ACCESS_BOUND_001: putDocument/getDocument require an EvidenceWriter.
|
|
5
|
+
// RAW_DOCUMENT_AGENT_NO_DIRECT_READ_001: getDocument is type- and runtime-bound to EvidenceWriter.
|
|
6
|
+
// getEvidenceRef/listEvidenceRefs expose metadata-only refs to any AccessContext.
|
|
7
|
+
export {};
|
|
8
|
+
//# sourceMappingURL=raw-document-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"raw-document-store.js","sourceRoot":"","sources":["../../src/evidence/raw-document-store.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,EAAE;AACF,kFAAkF;AAClF,oFAAoF;AACpF,mGAAmG;AACnG,kFAAkF"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { AccessContext } from "../types/access-context.js";
|
|
2
|
+
import type { SourceInput } from "../types/source.js";
|
|
3
|
+
import type { RawDocumentStore } from "./raw-document-store.js";
|
|
4
|
+
export declare function validateSourceEvidenceRef(sourceInput: SourceInput, store: RawDocumentStore, ctx: AccessContext): void;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// source-evidence-validator — Slice-09.
|
|
2
|
+
//
|
|
3
|
+
// RAW_DOCUMENT_SOURCE_LINK_001: validateSourceEvidenceRef ensures evidenceRef.id resolves.
|
|
4
|
+
// RAW_DOCUMENT_EVIDENCE_REF_EXISTS_001: unresolved evidence ids are rejected.
|
|
5
|
+
export function validateSourceEvidenceRef(sourceInput, store, ctx) {
|
|
6
|
+
const evidenceId = sourceInput.evidenceRef?.id;
|
|
7
|
+
if (evidenceId === undefined)
|
|
8
|
+
return;
|
|
9
|
+
const ref = store.getEvidenceRef(ctx, evidenceId);
|
|
10
|
+
if (ref === undefined) {
|
|
11
|
+
throw new Error(`RAW_DOCUMENT_EVIDENCE_REF_EXISTS_001: evidenceId "${evidenceId}" is not registered in RawDocumentStore`);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=source-evidence-validator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"source-evidence-validator.js","sourceRoot":"","sources":["../../src/evidence/source-evidence-validator.ts"],"names":[],"mappings":"AAAA,wCAAwC;AACxC,EAAE;AACF,2FAA2F;AAC3F,8EAA8E;AAO9E,MAAM,UAAU,yBAAyB,CACvC,WAAwB,EACxB,KAA6B,EAC7B,GAA0B;IAE1B,MAAM,UAAU,GAAG,WAAW,CAAC,WAAW,EAAE,EAA4B,CAAC;IACzE,IAAI,UAAU,KAAK,SAAS;QAAE,OAAO;IACrC,MAAM,GAAG,GAAG,KAAK,CAAC,cAAc,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;IAClD,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CACb,qDAAqD,UAAU,yCAAyC,CACzG,CAAC;IACJ,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import Database from "better-sqlite3";
|
|
2
|
+
import type { EvidenceId } from "../types/ids.js";
|
|
3
|
+
import type { AccessContext } from "../types/access-context.js";
|
|
4
|
+
import type { CryptoBoundary } from "../crypto/types.js";
|
|
5
|
+
import type { EvidenceFilter, EvidenceRef, EvidenceWriter, RawDocument, RawDocumentInput } from "../types/evidence.js";
|
|
6
|
+
import type { FactoryCompatibleRawDocumentStore } from "./raw-document-store.js";
|
|
7
|
+
export declare class SQLiteRawDocumentStore implements FactoryCompatibleRawDocumentStore {
|
|
8
|
+
private readonly _crypto;
|
|
9
|
+
readonly factoryCompatible: "durable-raw-document-store";
|
|
10
|
+
private readonly _db;
|
|
11
|
+
private readonly _ownsConnection;
|
|
12
|
+
constructor(dbPathOrDb: string | Database.Database, _crypto: CryptoBoundary);
|
|
13
|
+
close(): void;
|
|
14
|
+
putDocument(ctx: EvidenceWriter, input: RawDocumentInput): Promise<EvidenceRef>;
|
|
15
|
+
getDocument(ctx: EvidenceWriter, evidenceId: EvidenceId): Promise<RawDocument | undefined>;
|
|
16
|
+
getEvidenceRef(ctx: AccessContext, evidenceId: EvidenceId): EvidenceRef | undefined;
|
|
17
|
+
listEvidenceRefs(ctx: AccessContext, filter?: EvidenceFilter): EvidenceRef[];
|
|
18
|
+
getRawEncryptedBlob(evidenceId: EvidenceId): string | undefined;
|
|
19
|
+
}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
// SQLiteRawDocumentStore — Slice-09 durable encrypted document store.
|
|
2
|
+
//
|
|
3
|
+
// RAW_DOCUMENT_BYTES_ENCRYPTED_AT_REST_001: encrypted_blob column stores JSON EncryptedBlob only.
|
|
4
|
+
// RAW_DOCUMENT_IMMUTABLE_001: INSERT only — no UPDATE/DELETE anywhere in this file.
|
|
5
|
+
// RAW_DOCUMENT_ACCESS_BOUND_001 / RAW_DOCUMENT_AGENT_NO_DIRECT_READ_001: writer guard on put/get.
|
|
6
|
+
// RAW_DOCUMENT_SQLITE_REOPEN_ROUND_TRIP_001: documents survive a close + reopen cycle.
|
|
7
|
+
// RAW_DOCUMENT_METADATA_PLAINTEXT_ACCEPTED_001: metadata columns are plaintext.
|
|
8
|
+
//
|
|
9
|
+
// CRYPTO_BOUNDARY_ONLY_001: all encryption delegated to the injected CryptoBoundary —
|
|
10
|
+
// this module imports no crypto primitives and uses no WebCrypto APIs directly.
|
|
11
|
+
import Database from "better-sqlite3";
|
|
12
|
+
import { asEvidenceId, asISOTime } from "../types/ids.js";
|
|
13
|
+
import { initializeSchema } from "../persistence/sqlite/schema.js";
|
|
14
|
+
function isEvidenceWriter(ctx) {
|
|
15
|
+
return ctx.kind === "owner" || ctx.kind === "system_projection" || ctx.kind === "test";
|
|
16
|
+
}
|
|
17
|
+
function rowToEvidenceRef(row) {
|
|
18
|
+
const id = asEvidenceId(row.id);
|
|
19
|
+
return Object.freeze({
|
|
20
|
+
id,
|
|
21
|
+
uri: `evidence://${id}`,
|
|
22
|
+
mimeType: row.mime_type,
|
|
23
|
+
byteLength: row.byte_length,
|
|
24
|
+
encrypted: true,
|
|
25
|
+
createdAt: asISOTime(row.created_at),
|
|
26
|
+
...(row.label != null ? { label: row.label } : {}),
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
export class SQLiteRawDocumentStore {
|
|
30
|
+
_crypto;
|
|
31
|
+
// RAW_DOCUMENT_STORE_FACTORY_COMPATIBLE_REQUIRED_001 / RAW_DOCUMENT_STORE_DURABLE_REQUIRED_001
|
|
32
|
+
factoryCompatible = "durable-raw-document-store";
|
|
33
|
+
_db;
|
|
34
|
+
_ownsConnection;
|
|
35
|
+
// Accepts a file path (opens own connection) or a shared Database instance
|
|
36
|
+
// (e.g., for SQLiteUnitOfWork transactions — UNIT_OF_WORK_SQLITE_TRANSACTION_001).
|
|
37
|
+
constructor(dbPathOrDb, _crypto) {
|
|
38
|
+
this._crypto = _crypto;
|
|
39
|
+
if (typeof dbPathOrDb === "string") {
|
|
40
|
+
this._db = new Database(dbPathOrDb);
|
|
41
|
+
this._ownsConnection = true;
|
|
42
|
+
initializeSchema(this._db);
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
this._db = dbPathOrDb;
|
|
46
|
+
this._ownsConnection = false;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
close() {
|
|
50
|
+
if (this._ownsConnection)
|
|
51
|
+
this._db.close();
|
|
52
|
+
}
|
|
53
|
+
async putDocument(ctx, input) {
|
|
54
|
+
if (!isEvidenceWriter(ctx)) {
|
|
55
|
+
throw new Error("RAW_DOCUMENT_ACCESS_BOUND_001: only Owner/System/Test may write raw documents");
|
|
56
|
+
}
|
|
57
|
+
const id = asEvidenceId(`ev_${globalThis.crypto.randomUUID()}`);
|
|
58
|
+
const encryptedBlob = await this._crypto.encryptBytes(input.bytes);
|
|
59
|
+
const createdAt = asISOTime(new Date().toISOString());
|
|
60
|
+
// RAW_DOCUMENT_IMMUTABLE_001: INSERT only.
|
|
61
|
+
this._db.prepare(`
|
|
62
|
+
INSERT INTO raw_documents (id, mime_type, byte_length, label, created_at, created_by, encrypted_blob, metadata)
|
|
63
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
64
|
+
`).run(id, input.mimeType, input.bytes.byteLength, input.label ?? null, createdAt, JSON.stringify(ctx), JSON.stringify(encryptedBlob), input.metadata != null ? JSON.stringify(input.metadata) : null);
|
|
65
|
+
return rowToEvidenceRef({
|
|
66
|
+
id,
|
|
67
|
+
mime_type: input.mimeType,
|
|
68
|
+
byte_length: input.bytes.byteLength,
|
|
69
|
+
label: input.label ?? null,
|
|
70
|
+
created_at: createdAt,
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
async getDocument(ctx, evidenceId) {
|
|
74
|
+
if (!isEvidenceWriter(ctx)) {
|
|
75
|
+
throw new Error("RAW_DOCUMENT_AGENT_NO_DIRECT_READ_001: AgentConsentContext and AuditContext cannot read raw document bytes");
|
|
76
|
+
}
|
|
77
|
+
const row = this._db.prepare("SELECT * FROM raw_documents WHERE id = ?").get(evidenceId);
|
|
78
|
+
if (row === undefined)
|
|
79
|
+
return undefined;
|
|
80
|
+
const blob = JSON.parse(row.encrypted_blob);
|
|
81
|
+
const plainBytes = await this._crypto.decryptBytes(blob);
|
|
82
|
+
const createdBy = JSON.parse(row.created_by);
|
|
83
|
+
return Object.freeze({
|
|
84
|
+
id: asEvidenceId(row.id),
|
|
85
|
+
mimeType: row.mime_type,
|
|
86
|
+
byteLength: row.byte_length,
|
|
87
|
+
createdAt: asISOTime(row.created_at),
|
|
88
|
+
createdBy: Object.freeze(createdBy),
|
|
89
|
+
plainBytes: new Uint8Array(plainBytes), // defensive copy
|
|
90
|
+
...(row.label != null ? { label: row.label } : {}),
|
|
91
|
+
...(row.metadata != null ? { metadata: Object.freeze(JSON.parse(row.metadata)) } : {}),
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
getEvidenceRef(ctx, evidenceId) {
|
|
95
|
+
if (ctx == null)
|
|
96
|
+
throw new TypeError("AccessContext is required");
|
|
97
|
+
const row = this._db
|
|
98
|
+
.prepare("SELECT id, mime_type, byte_length, label, created_at FROM raw_documents WHERE id = ?")
|
|
99
|
+
.get(evidenceId);
|
|
100
|
+
return row !== undefined ? rowToEvidenceRef(row) : undefined;
|
|
101
|
+
}
|
|
102
|
+
listEvidenceRefs(ctx, filter) {
|
|
103
|
+
if (ctx == null)
|
|
104
|
+
throw new TypeError("AccessContext is required");
|
|
105
|
+
let sql = "SELECT id, mime_type, byte_length, label, created_at FROM raw_documents";
|
|
106
|
+
const params = [];
|
|
107
|
+
if (filter?.mimeType !== undefined) {
|
|
108
|
+
sql += " WHERE mime_type = ?";
|
|
109
|
+
params.push(filter.mimeType);
|
|
110
|
+
}
|
|
111
|
+
const rows = this._db.prepare(sql).all(...params);
|
|
112
|
+
return rows.map(rowToEvidenceRef);
|
|
113
|
+
}
|
|
114
|
+
// Return the raw encrypted_blob column for a given document (for at-rest verification).
|
|
115
|
+
getRawEncryptedBlob(evidenceId) {
|
|
116
|
+
const row = this._db
|
|
117
|
+
.prepare("SELECT encrypted_blob FROM raw_documents WHERE id = ?")
|
|
118
|
+
.get(evidenceId);
|
|
119
|
+
return row?.encrypted_blob;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=sqlite-raw-document-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sqlite-raw-document-store.js","sourceRoot":"","sources":["../../src/evidence/sqlite-raw-document-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import type { PersonId } from "../types/ids.js";
|
|
2
|
+
/** A single guardian ↔ ward relationship record. */
|
|
3
|
+
export interface GuardianRelationship {
|
|
4
|
+
/** Principal-ID of the guardian — matches VerifiedPrincipal.principalId. */
|
|
5
|
+
readonly guardianId: string;
|
|
6
|
+
/** PersonId of the ward (the person being assisted). */
|
|
7
|
+
readonly wardId: string;
|
|
8
|
+
/**
|
|
9
|
+
* Scopes this guardian is authorised to act on.
|
|
10
|
+
* Vocabulary (host-defined):
|
|
11
|
+
* "context:mint" — prerequisite for mintGuardianContext
|
|
12
|
+
* "proposal:accept" — acceptProposal + rejectProposal on behalf of ward
|
|
13
|
+
* "proposal:create" — createProposal on behalf of ward
|
|
14
|
+
* "grant:create" — host-side grant store operations (declared; not enforced here)
|
|
15
|
+
* "consent:decide" — reserved for future Consent facade
|
|
16
|
+
* Read operations are implied by a successfully minted guardian context.
|
|
17
|
+
* Erasure (requestErasure / getErasureStatus) is NEVER delegable regardless of scopes.
|
|
18
|
+
*/
|
|
19
|
+
readonly guardianScopes: ReadonlyArray<string>;
|
|
20
|
+
/** Timestamp when the relationship was established (epoch ms). */
|
|
21
|
+
readonly establishedAt: number;
|
|
22
|
+
/** Optional expiry (epoch ms). Absent = unlimited duration. */
|
|
23
|
+
readonly validUntil?: number;
|
|
24
|
+
/** Who established the relationship. */
|
|
25
|
+
readonly establishedBy: "ward" | "legal-authority";
|
|
26
|
+
/** Free-text note, e.g. Betreuungsnummer from a court order. */
|
|
27
|
+
readonly notes?: string;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Trust gate for guardian-context minting and scope enforcement.
|
|
31
|
+
* GUARDIAN_REGISTRY_FAIL_CLOSED_001: configured → checked before every guardian action.
|
|
32
|
+
* Implementations must be fail-closed: any exception → treated as unauthorised.
|
|
33
|
+
*/
|
|
34
|
+
export interface GuardianRegistry {
|
|
35
|
+
/**
|
|
36
|
+
* Returns the stored relationship or undefined.
|
|
37
|
+
* NOTE: this is a raw lookup — it does NOT enforce expiry.
|
|
38
|
+
* Use isAuthorized for all authorisation decisions.
|
|
39
|
+
* Returns the record even if expired (transparency / audit purposes).
|
|
40
|
+
*/
|
|
41
|
+
getRelationship(guardianId: string, wardId: string): Promise<GuardianRelationship | undefined>;
|
|
42
|
+
/**
|
|
43
|
+
* Returns true iff guardianId has an active, unexpired relationship for wardId
|
|
44
|
+
* that includes the given scope.
|
|
45
|
+
* GUARDIAN_REGISTRY_FAIL_CLOSED_001: any exception → false.
|
|
46
|
+
* GUARDIAN_REGISTRY_EXPIRY_ENFORCED_001: validUntil <= now() → false.
|
|
47
|
+
* GUARDIAN_REGISTRY_SCOPE_EXACT_MATCH_001: exact match only.
|
|
48
|
+
*/
|
|
49
|
+
isAuthorized(guardianId: string, wardId: string, scope: string): Promise<boolean>;
|
|
50
|
+
/**
|
|
51
|
+
* Returns all stored relationships for the ward, including expired ones.
|
|
52
|
+
* Callers must not use this for authorisation decisions — use isAuthorized.
|
|
53
|
+
* The full list (including expired) is returned for transparency and audit.
|
|
54
|
+
*/
|
|
55
|
+
listGuardiansFor(wardId: string): Promise<ReadonlyArray<GuardianRelationship>>;
|
|
56
|
+
}
|
|
57
|
+
/** Development / test implementation of GuardianRegistry. */
|
|
58
|
+
export declare class InMemoryGuardianRegistry implements GuardianRegistry {
|
|
59
|
+
private readonly _entries;
|
|
60
|
+
private readonly _now;
|
|
61
|
+
constructor(opts?: {
|
|
62
|
+
readonly now?: () => number;
|
|
63
|
+
});
|
|
64
|
+
private static _key;
|
|
65
|
+
/**
|
|
66
|
+
* Register or replace a relationship.
|
|
67
|
+
* Re-registering the same guardianId + wardId pair overwrites the previous entry.
|
|
68
|
+
*/
|
|
69
|
+
register(rel: GuardianRelationship): this;
|
|
70
|
+
/**
|
|
71
|
+
* Revoke a relationship (ward's right to withdraw).
|
|
72
|
+
* Returns true if the relationship existed and was removed, false if unknown.
|
|
73
|
+
* GUARDIAN_REVOCATION_NEXT_MINT_ENFORCED_001: after revocation, the next
|
|
74
|
+
* mintGuardianContext call will be denied. Short-lived existing contexts
|
|
75
|
+
* are NOT retroactively revoked — this limitation is documented.
|
|
76
|
+
*/
|
|
77
|
+
revoke(guardianId: string, wardId: string): boolean;
|
|
78
|
+
/**
|
|
79
|
+
* Raw lookup — returns stored record regardless of expiry.
|
|
80
|
+
* GUARDIAN_REGISTRY_FAIL_CLOSED_001: use isAuthorized for all authorisation.
|
|
81
|
+
*/
|
|
82
|
+
getRelationship(guardianId: string, wardId: string): Promise<GuardianRelationship | undefined>;
|
|
83
|
+
/**
|
|
84
|
+
* GUARDIAN_REGISTRY_FAIL_CLOSED_001: unknown pair → false, exception → false.
|
|
85
|
+
* GUARDIAN_REGISTRY_EXPIRY_ENFORCED_001: validUntil defined and <= now() → false.
|
|
86
|
+
* GUARDIAN_REGISTRY_SCOPE_EXACT_MATCH_001: exact match in guardianScopes.
|
|
87
|
+
* Never throws — caller treats exceptions as untrusted anyway.
|
|
88
|
+
*/
|
|
89
|
+
isAuthorized(guardianId: string, wardId: string, scope: string): Promise<boolean>;
|
|
90
|
+
/**
|
|
91
|
+
* Returns all stored relationships for a ward (including expired).
|
|
92
|
+
* For transparency; not for authorisation decisions.
|
|
93
|
+
*/
|
|
94
|
+
listGuardiansFor(wardId: string): Promise<ReadonlyArray<GuardianRelationship>>;
|
|
95
|
+
}
|
|
96
|
+
export type { PersonId };
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
// Platform-03 — Guardian Registry.
|
|
2
|
+
//
|
|
3
|
+
// GUARDIAN_REGISTRY_FAIL_CLOSED_001: isAuthorized returns false for any unknown
|
|
4
|
+
// pair, expired relationship, missing scope, or exception — never fail-open.
|
|
5
|
+
// GUARDIAN_REGISTRY_EXPIRY_ENFORCED_001: validUntil epoch-ms <= now() → denied.
|
|
6
|
+
// Absence of validUntil = unlimited authorization.
|
|
7
|
+
// GUARDIAN_REGISTRY_SCOPE_EXACT_MATCH_001: scope must appear exactly in
|
|
8
|
+
// guardianScopes; prefix or substring matches are not accepted.
|
|
9
|
+
// GUARDIAN_REGISTRY_INTERFACE_GUARDIAN_MODULE_ONLY_001: GuardianRegistry interface
|
|
10
|
+
// is defined exclusively in src/guardian/; auth/ and sdk/ import type-only;
|
|
11
|
+
// no implementation is imported by production src code other than the re-export
|
|
12
|
+
// in src/index.ts.
|
|
13
|
+
// ─── InMemoryGuardianRegistry ─────────────────────────────────────────────────
|
|
14
|
+
/** Development / test implementation of GuardianRegistry. */
|
|
15
|
+
export class InMemoryGuardianRegistry {
|
|
16
|
+
// Composite key: `${guardianId}::${wardId}`
|
|
17
|
+
_entries = new Map();
|
|
18
|
+
_now;
|
|
19
|
+
constructor(opts) {
|
|
20
|
+
this._now = opts?.now ?? (() => Date.now());
|
|
21
|
+
}
|
|
22
|
+
static _key(guardianId, wardId) {
|
|
23
|
+
return `${guardianId}::${wardId}`;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Register or replace a relationship.
|
|
27
|
+
* Re-registering the same guardianId + wardId pair overwrites the previous entry.
|
|
28
|
+
*/
|
|
29
|
+
register(rel) {
|
|
30
|
+
this._entries.set(InMemoryGuardianRegistry._key(rel.guardianId, rel.wardId), rel);
|
|
31
|
+
return this;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Revoke a relationship (ward's right to withdraw).
|
|
35
|
+
* Returns true if the relationship existed and was removed, false if unknown.
|
|
36
|
+
* GUARDIAN_REVOCATION_NEXT_MINT_ENFORCED_001: after revocation, the next
|
|
37
|
+
* mintGuardianContext call will be denied. Short-lived existing contexts
|
|
38
|
+
* are NOT retroactively revoked — this limitation is documented.
|
|
39
|
+
*/
|
|
40
|
+
revoke(guardianId, wardId) {
|
|
41
|
+
const key = InMemoryGuardianRegistry._key(guardianId, wardId);
|
|
42
|
+
if (!this._entries.has(key))
|
|
43
|
+
return false;
|
|
44
|
+
this._entries.delete(key);
|
|
45
|
+
return true;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Raw lookup — returns stored record regardless of expiry.
|
|
49
|
+
* GUARDIAN_REGISTRY_FAIL_CLOSED_001: use isAuthorized for all authorisation.
|
|
50
|
+
*/
|
|
51
|
+
async getRelationship(guardianId, wardId) {
|
|
52
|
+
return this._entries.get(InMemoryGuardianRegistry._key(guardianId, wardId));
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* GUARDIAN_REGISTRY_FAIL_CLOSED_001: unknown pair → false, exception → false.
|
|
56
|
+
* GUARDIAN_REGISTRY_EXPIRY_ENFORCED_001: validUntil defined and <= now() → false.
|
|
57
|
+
* GUARDIAN_REGISTRY_SCOPE_EXACT_MATCH_001: exact match in guardianScopes.
|
|
58
|
+
* Never throws — caller treats exceptions as untrusted anyway.
|
|
59
|
+
*/
|
|
60
|
+
async isAuthorized(guardianId, wardId, scope) {
|
|
61
|
+
try {
|
|
62
|
+
const rel = this._entries.get(InMemoryGuardianRegistry._key(guardianId, wardId));
|
|
63
|
+
if (rel === undefined)
|
|
64
|
+
return false;
|
|
65
|
+
// Expiry check — epoch-ms comparison (GUARDIAN_REGISTRY_EXPIRY_ENFORCED_001).
|
|
66
|
+
if (rel.validUntil !== undefined) {
|
|
67
|
+
const nowMs = this._now();
|
|
68
|
+
// validUntil <= now → expired
|
|
69
|
+
if (rel.validUntil <= nowMs)
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
// Exact scope match (GUARDIAN_REGISTRY_SCOPE_EXACT_MATCH_001).
|
|
73
|
+
if (!rel.guardianScopes.includes(scope))
|
|
74
|
+
return false;
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
// GUARDIAN_REGISTRY_FAIL_CLOSED_001: any exception → false.
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Returns all stored relationships for a ward (including expired).
|
|
84
|
+
* For transparency; not for authorisation decisions.
|
|
85
|
+
*/
|
|
86
|
+
async listGuardiansFor(wardId) {
|
|
87
|
+
const result = [];
|
|
88
|
+
for (const rel of this._entries.values()) {
|
|
89
|
+
if (rel.wardId === wardId)
|
|
90
|
+
result.push(rel);
|
|
91
|
+
}
|
|
92
|
+
return result;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=guardian-registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guardian-registry.js","sourceRoot":"","sources":["../../src/guardian/guardian-registry.ts"],"names":[],"mappings":"AAAA,mCAAmC;AACnC,EAAE;AACF,gFAAgF;AAChF,+EAA+E;AAC/E,gFAAgF;AAChF,qDAAqD;AACrD,wEAAwE;AACxE,kEAAkE;AAClE,mFAAmF;AACnF,8EAA8E;AAC9E,kFAAkF;AAClF,qBAAqB;AAmErB,iFAAiF;AAEjF,6DAA6D;AAC7D,MAAM,OAAO,wBAAwB;IACnC,4CAA4C;IAC3B,QAAQ,GAAG,IAAI,GAAG,EAAgC,CAAC;IACnD,IAAI,CAAe;IAEpC,YAAY,IAAsC;QAChD,IAAI,CAAC,IAAI,GAAG,IAAI,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;IAC9C,CAAC;IAEO,MAAM,CAAC,IAAI,CAAC,UAAkB,EAAE,MAAc;QACpD,OAAO,GAAG,UAAU,KAAK,MAAM,EAAE,CAAC;IACpC,CAAC;IAED;;;OAGG;IACH,QAAQ,CAAC,GAAyB;QAChC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,wBAAwB,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,GAAG,CAAC,CAAC;QAClF,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;OAMG;IACH,MAAM,CAAC,UAAkB,EAAE,MAAc;QACvC,MAAM,GAAG,GAAG,wBAAwB,CAAC,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;QAC9D,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,OAAO,KAAK,CAAC;QAC1C,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC1B,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,eAAe,CAAC,UAAkB,EAAE,MAAc;QACtD,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,wBAAwB,CAAC,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC;IAC9E,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,YAAY,CAAC,UAAkB,EAAE,MAAc,EAAE,KAAa;QAClE,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,wBAAwB,CAAC,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC;YACjF,IAAI,GAAG,KAAK,SAAS;gBAAE,OAAO,KAAK,CAAC;YAEpC,8EAA8E;YAC9E,IAAI,GAAG,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;gBACjC,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;gBAC1B,8BAA8B;gBAC9B,IAAI,GAAG,CAAC,UAAU,IAAI,KAAK;oBAAE,OAAO,KAAK,CAAC;YAC5C,CAAC;YAED,+DAA+D;YAC/D,IAAI,CAAC,GAAG,CAAC,cAAc,CAAC,QAAQ,CAAC,KAAK,CAAC;gBAAE,OAAO,KAAK,CAAC;YAEtD,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,MAAM,CAAC;YACP,4DAA4D;YAC5D,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,gBAAgB,CAAC,MAAc;QACnC,MAAM,MAAM,GAA2B,EAAE,CAAC;QAC1C,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC;YACzC,IAAI,GAAG,CAAC,MAAM,KAAK,MAAM;gBAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC9C,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;CACF"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
export type { LifeApi, SdkAdminContext } from "./sdk/life-api.js";
|
|
2
|
+
export type { LifeApiTestBundle } from "./sdk/create-life-api.js";
|
|
3
|
+
export { createInMemoryLifeApiForTest } from "./sdk/create-life-api.js";
|
|
4
|
+
export type { AccessContextIssuer } from "./auth/access-context-issuer.js";
|
|
5
|
+
export type { AccessContext, AgentConsentContext, OwnerContext, SystemProjectionContext, TestContext, } from "./types/access-context.js";
|
|
6
|
+
export type { ConsentGrant, AgentIdentity, Capability } from "./types/consent.js";
|
|
7
|
+
export type { PersonId, ClaimId, ContractId, GrantId, SourceId, EvidenceId, ProposalId, AuditId, ISOTime, } from "./types/ids.js";
|
|
8
|
+
export { asPersonId, asClaimId, asContractId, asGrantId, asSourceId, asEvidenceId, asProposalId, asISOTime, } from "./types/ids.js";
|
|
9
|
+
export type { EvidenceRef, EvidenceFilter } from "./types/evidence.js";
|
|
10
|
+
export type { Source, SourceInput, SourceFilter, SourceKind, SourceStatus } from "./types/source.js";
|
|
11
|
+
export type { Proposal, ProposalInput, ProposalFilter, ProposalStatus, ProposalAuthor, AcceptOptions, RejectOptions, ProposalDecider, } from "./types/proposal.js";
|
|
12
|
+
export type { QueryContractsInput, ContextQueryResult, HydratedContractProjection, HydratedContractFieldProjection, HydratedContractFields, } from "./surface/evidence-backed-context-query.js";
|
|
13
|
+
export type { EvidenceClaimCreator, CreateClaimWithNewEvidenceInput, CreateClaimFromExistingEvidenceInput, EvidenceBackedClaimResult, EvidenceBackedClaimWithNewEvidenceResult, } from "./evidence/evidence-backed-claim-creator.js";
|
|
14
|
+
export type { PrincipalType, VerifiedPrincipal, AuthAdapter, AuthorizationDecision, AuthorizationPolicy, TenantBoundary, GrantDescriptor, GrantResolver, Clock, MintedContext, MintOptions, ContextMintingBoundary, } from "./auth/types.js";
|
|
15
|
+
export type { ProductionFactoryConfig } from "./sdk/create-sqlite-life-api.js";
|
|
16
|
+
export { createSQLiteLifeApiForProduction } from "./sdk/create-sqlite-life-api.js";
|
|
17
|
+
export type { ProductionApiBundle, ProductionScopedLifeApi, ListProposalsInput, } from "./auth/production-scoped-life-api.js";
|
|
18
|
+
export { assertAuthorizedForSubject } from "./auth/assert-authorized-for-subject.js";
|
|
19
|
+
export { SubjectScopedLifeApi, createSubjectScopedLifeApi } from "./auth/subject-scoped-life-api.js";
|
|
20
|
+
export { inspectProposalScope } from "./auth/proposal-scope-inspector.js";
|
|
21
|
+
export { ProposalScopedLifeApi, createProposalScopedLifeApi } from "./auth/proposal-scoped-life-api.js";
|
|
22
|
+
export type { Logger, LogEvent, LogLevel } from "./observability/logger.js";
|
|
23
|
+
export { noopLogger } from "./observability/logger.js";
|
|
24
|
+
export type { HealthStatus, HealthCheckItem, HealthCheckResult } from "./observability/health.js";
|
|
25
|
+
export type { MetricsRecorder, MetricName, MetricLabels } from "./observability/metrics.js";
|
|
26
|
+
export { noopMetricsRecorder } from "./observability/metrics.js";
|
|
27
|
+
export type { KeyProvider, KeyDescriptor } from "./crypto/types.js";
|
|
28
|
+
export type { TrustedAgentRegistry, TrustedAgentRegistryEntry } from "./agent/trusted-agent-registry.js";
|
|
29
|
+
export { InMemoryTrustedAgentRegistry } from "./agent/trusted-agent-registry.js";
|
|
30
|
+
export type { TrustedDataSourceRegistry, TrustedDataSourceEntry } from "./datasource/trusted-data-source-registry.js";
|
|
31
|
+
export { InMemoryTrustedDataSourceRegistry } from "./datasource/trusted-data-source-registry.js";
|
|
32
|
+
export type { ProposalPolicy, ProposalPolicyInput, ProposalDisposition } from "./proposal/proposal-policy.js";
|
|
33
|
+
export { DefaultProposalPolicy, RegistryBackedProposalPolicy } from "./proposal/proposal-policy.js";
|
|
34
|
+
export type { GuardianRegistry, GuardianRelationship } from "./guardian/guardian-registry.js";
|
|
35
|
+
export { InMemoryGuardianRegistry } from "./guardian/guardian-registry.js";
|
|
36
|
+
export type { GuardianContextMintingBoundary } from "./auth/types.js";
|
|
37
|
+
export type { SubjectDataReport, GrantSummary, ProposalSummary, AuditEventSummary, SubjectDataReportOptions, } from "./compliance/subject-data-report.js";
|
|
38
|
+
export { generateSubjectDataReport } from "./compliance/subject-data-report.js";
|
|
39
|
+
export { MedicalAgent, medicalAgentRegistryEntry, MEDICAL_AGENT_ID, MEDICAL_AGENT_VERSION, ALLOWED_MEDICAL_PURPOSES } from "./agent/medical-agent.js";
|
|
40
|
+
export type { MedicalPurpose } from "./agent/medical-agent.js";
|
|
41
|
+
export { FinanceAgent, financeAgentRegistryEntry, FINANCE_AGENT_ID, FINANCE_AGENT_VERSION, ALLOWED_FINANCE_PURPOSES } from "./agent/finance-agent.js";
|
|
42
|
+
export type { FinancePurpose } from "./agent/finance-agent.js";
|
|
43
|
+
export { LegalAgent, legalAgentRegistryEntry, LEGAL_AGENT_ID, LEGAL_AGENT_VERSION, ALLOWED_LEGAL_PURPOSES } from "./agent/legal-agent.js";
|
|
44
|
+
export type { LegalPurpose } from "./agent/legal-agent.js";
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
// Life as API — Public SDK surface.
|
|
2
|
+
//
|
|
3
|
+
// SDK_EXPORTS_ONLY_SAFE_SURFACE_001: only LifeApi, the factory, and required
|
|
4
|
+
// input/output types are exported. Internal implementations are NOT exported.
|
|
5
|
+
// SDK_DOES_NOT_EXPORT_RAW_FACTSTORE_001: concrete FactStore implementations are not exported.
|
|
6
|
+
// SDK_DOES_NOT_EXPORT_RAW_CRYPTO_001: crypto primitive implementations are not exported.
|
|
7
|
+
// Blocked: AesGcmCryptoBoundary, StaticKeyProvider, ClaimSerializer, EncryptedBlob,
|
|
8
|
+
// CryptoBoundary. Interface types (KeyProvider, KeyDescriptor) ARE exported — see below.
|
|
9
|
+
// SDK_DOES_NOT_EXPORT_RAW_DOCUMENT_BYTES_001: concrete document store and getDocument() absent.
|
|
10
|
+
// SDK_DOES_NOT_EXPORT_SOURCE_MUTATION_DIRECTLY_001: registries are not exported directly.
|
|
11
|
+
// SDK_NO_INTERNAL_PATH_IMPORTS_001: callers import only from this file, not from src/ internals.
|
|
12
|
+
// SDK_TYPECHECK_PUBLIC_API_001: types exported here are the source of truth for all callers.
|
|
13
|
+
export { createInMemoryLifeApiForTest } from "./sdk/create-life-api.js";
|
|
14
|
+
export { asPersonId, asClaimId, asContractId, asGrantId, asSourceId, asEvidenceId, asProposalId, asISOTime, } from "./types/ids.js";
|
|
15
|
+
export { createSQLiteLifeApiForProduction } from "./sdk/create-sqlite-life-api.js";
|
|
16
|
+
// ─── Auth boundary helpers (Production-01b) ──────────────────────────────────
|
|
17
|
+
//
|
|
18
|
+
// AUTH_CONTEXT_SUBJECT_SCOPE_HELPER_001: assertAuthorizedForSubject() is a
|
|
19
|
+
// host-adapter helper that enforces subject scope when authorizedPersonId is
|
|
20
|
+
// present on a MintedContext. It does NOT provide full LifeApi callsite
|
|
21
|
+
// enforcement (AUTH_CONTEXT_SUBJECT_SCOPE_ENFORCED_001 is deferred).
|
|
22
|
+
// AUTH_TEST_ISSUER_NOT_PRODUCTION_001: TestContextMintingBoundary and
|
|
23
|
+
// DefaultAuthorizationPolicy are NOT exported — test/dev only.
|
|
24
|
+
export { assertAuthorizedForSubject } from "./auth/assert-authorized-for-subject.js";
|
|
25
|
+
// ─── SubjectScopedLifeApi facade (Production-01c) ────────────────────────────
|
|
26
|
+
//
|
|
27
|
+
// AUTH_CONTEXT_SUBJECT_SCOPE_ENFORCED_001: enforced for SubjectScopedLifeApi
|
|
28
|
+
// facade surface. Excluded methods remain deferred to Production-01d.
|
|
29
|
+
// SubjectScopedLifeApi does NOT implement LifeApi — it is a narrower surface.
|
|
30
|
+
// Host adapters use SubjectScopedLifeApi to bind MintedContext to a LifeApi
|
|
31
|
+
// instance; excluded methods must be called on LifeApi directly.
|
|
32
|
+
export { SubjectScopedLifeApi, createSubjectScopedLifeApi } from "./auth/subject-scoped-life-api.js";
|
|
33
|
+
// ─── Proposal scope (Production-01d-a) ───────────────────────────────────────
|
|
34
|
+
//
|
|
35
|
+
// AUTH_PROPOSAL_ACCEPT_SCOPE_CHECKED_001: inspectProposalScope fires before
|
|
36
|
+
// every acceptProposal delegation. ProposalId-only is not subject-free proof.
|
|
37
|
+
// AUTH_PROPOSAL_CANDIDATE_CLAIMS_SCOPED_001: every candidateClaim has a required
|
|
38
|
+
// subject: PersonId — candidateClaims are always subject-scoped.
|
|
39
|
+
// ProposalScopedLifeApi does NOT implement LifeApi — narrower, scope-checked surface.
|
|
40
|
+
// Production-01d-a: acceptProposal only. get/list/reject/create remain deferred.
|
|
41
|
+
export { inspectProposalScope } from "./auth/proposal-scope-inspector.js";
|
|
42
|
+
export { ProposalScopedLifeApi, createProposalScopedLifeApi } from "./auth/proposal-scoped-life-api.js";
|
|
43
|
+
export { noopLogger } from "./observability/logger.js";
|
|
44
|
+
export { noopMetricsRecorder } from "./observability/metrics.js";
|
|
45
|
+
export { InMemoryTrustedAgentRegistry } from "./agent/trusted-agent-registry.js";
|
|
46
|
+
export { InMemoryTrustedDataSourceRegistry } from "./datasource/trusted-data-source-registry.js";
|
|
47
|
+
export { DefaultProposalPolicy, RegistryBackedProposalPolicy } from "./proposal/proposal-policy.js";
|
|
48
|
+
export { InMemoryGuardianRegistry } from "./guardian/guardian-registry.js";
|
|
49
|
+
export { generateSubjectDataReport } from "./compliance/subject-data-report.js";
|
|
50
|
+
// ─── Platform-05 — Certified First-Party Agents ──────────────────────────────
|
|
51
|
+
//
|
|
52
|
+
// PURPOSE_TAG_VOCABULARY_EXTENDED_PLATFORM05_001: PurposeTag gained 11 additive values
|
|
53
|
+
// for certified first-party agents (diagnosis, treatment, emergency, tax, credit_check,
|
|
54
|
+
// insurance_claim, account_overview, notary, contract_review, evidence_preservation,
|
|
55
|
+
// court_filing). Union-widening only — fully backward-compatible.
|
|
56
|
+
// MEDICAL_AGENT_PURPOSE_BOUND_001 / FINANCE_AGENT_PURPOSE_BOUND_001 / LEGAL_AGENT_PURPOSE_BOUND_001:
|
|
57
|
+
// each agent acts only when MintedContext.declaredPurpose is within its own allowed set.
|
|
58
|
+
// MEDICAL_AGENT_REGISTRY_ENTRY_001 / FINANCE_AGENT_REGISTRY_ENTRY_001 / LEGAL_AGENT_REGISTRY_ENTRY_001:
|
|
59
|
+
// the *AgentRegistryEntry() factories build a TrustedAgentRegistryEntry certifiedBy
|
|
60
|
+
// "life-as-api-foundation" for direct registration with a TrustedAgentRegistry (Platform-01).
|
|
61
|
+
// MEDICAL_AGENT_SCOPE_ENFORCED_001 / FINANCE_AGENT_SCOPE_ENFORCED_001 / LEGAL_AGENT_SCOPE_ENFORCED_001:
|
|
62
|
+
// run() throws a *_SCOPE_DENIED_001 coded error, fail-closed, for any purpose outside the
|
|
63
|
+
// agent's allowed set — including an absent declaredPurpose.
|
|
64
|
+
// MEDICAL_AGENT_READ_ONLY_001 / FINANCE_AGENT_READ_ONLY_001 / LEGAL_AGENT_READ_ONLY_001:
|
|
65
|
+
// each agent's constructor accepts only a query function — no propose/write capability.
|
|
66
|
+
// MEDICAL_AGENT_AUDIT_TRAIL_001 / FINANCE_AGENT_AUDIT_TRAIL_001 / LEGAL_AGENT_AUDIT_TRAIL_001:
|
|
67
|
+
// the optional onAudit hook fires on every run() call; real audit persistence is a host
|
|
68
|
+
// responsibility.
|
|
69
|
+
export { MedicalAgent, medicalAgentRegistryEntry, MEDICAL_AGENT_ID, MEDICAL_AGENT_VERSION, ALLOWED_MEDICAL_PURPOSES } from "./agent/medical-agent.js";
|
|
70
|
+
export { FinanceAgent, financeAgentRegistryEntry, FINANCE_AGENT_ID, FINANCE_AGENT_VERSION, ALLOWED_FINANCE_PURPOSES } from "./agent/finance-agent.js";
|
|
71
|
+
export { LegalAgent, legalAgentRegistryEntry, LEGAL_AGENT_ID, LEGAL_AGENT_VERSION, ALLOWED_LEGAL_PURPOSES } from "./agent/legal-agent.js";
|
|
72
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,oCAAoC;AACpC,EAAE;AACF,6EAA6E;AAC7E,gFAAgF;AAChF,8FAA8F;AAC9F,yFAAyF;AACzF,sFAAsF;AACtF,2FAA2F;AAC3F,gGAAgG;AAChG,0FAA0F;AAC1F,iGAAiG;AACjG,6FAA6F;AAM7F,OAAO,EAAE,4BAA4B,EAAE,MAA0B,0BAA0B,CAAC;AA8C5F,OAAO,EACL,UAAU,EACV,SAAS,EACT,YAAY,EACZ,SAAS,EACT,UAAU,EACV,YAAY,EACZ,YAAY,EACZ,SAAS,GACV,MAAM,gBAAgB,CAAC;AAuExB,OAAO,EAAE,gCAAgC,EAAE,MAAe,iCAAiC,CAAC;AAgB5F,gFAAgF;AAChF,EAAE;AACF,2EAA2E;AAC3E,+EAA+E;AAC/E,0EAA0E;AAC1E,uEAAuE;AACvE,sEAAsE;AACtE,iEAAiE;AAEjE,OAAO,EAAE,0BAA0B,EAAE,MAAqB,yCAAyC,CAAC;AAEpG,gFAAgF;AAChF,EAAE;AACF,6EAA6E;AAC7E,wEAAwE;AACxE,8EAA8E;AAC9E,4EAA4E;AAC5E,iEAAiE;AAEjE,OAAO,EAAE,oBAAoB,EAAE,0BAA0B,EAAE,MAAM,mCAAmC,CAAC;AAErG,gFAAgF;AAChF,EAAE;AACF,4EAA4E;AAC5E,gFAAgF;AAChF,iFAAiF;AACjF,mEAAmE;AACnE,sFAAsF;AACtF,iFAAiF;AAEjF,OAAO,EAAE,oBAAoB,EAAE,MAAwC,oCAAoC,CAAC;AAC5G,OAAO,EAAE,qBAAqB,EAAE,2BAA2B,EAAE,MAAU,oCAAoC,CAAC;AAW5G,OAAO,EAAE,UAAU,EAAE,MAAkD,2BAA2B,CAAC;AAqBnG,OAAO,EAAE,mBAAmB,EAAE,MAAyC,4BAA4B,CAAC;AA4BpG,OAAO,EAAE,4BAA4B,EAAE,MAA+B,mCAAmC,CAAC;AAwB1G,OAAO,EAAE,iCAAiC,EAAE,MAA4B,8CAA8C,CAAC;AAGvH,OAAO,EAAE,qBAAqB,EAAE,4BAA4B,EAAE,MAAgB,+BAA+B,CAAC;AAiB9G,OAAO,EAAE,wBAAwB,EAAE,MAA0B,iCAAiC,CAAC;AA4B/F,OAAO,EAAE,yBAAyB,EAAE,MAAyB,qCAAqC,CAAC;AAEnG,gFAAgF;AAChF,EAAE;AACF,uFAAuF;AACvF,0FAA0F;AAC1F,uFAAuF;AACvF,oEAAoE;AACpE,qGAAqG;AACrG,2FAA2F;AAC3F,wGAAwG;AACxG,sFAAsF;AACtF,gGAAgG;AAChG,wGAAwG;AACxG,4FAA4F;AAC5F,+DAA+D;AAC/D,yFAAyF;AACzF,0FAA0F;AAC1F,+FAA+F;AAC/F,0FAA0F;AAC1F,oBAAoB;AAEpB,OAAO,EAAE,YAAY,EAAE,yBAAyB,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AAGtJ,OAAO,EAAE,YAAY,EAAE,yBAAyB,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AAGtJ,OAAO,EAAE,UAAU,EAAE,uBAAuB,EAAE,cAAc,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,MAAgB,wBAAwB,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export type HealthStatus = "ok" | "degraded" | "failed";
|
|
2
|
+
export interface HealthCheckItem {
|
|
3
|
+
readonly name: string;
|
|
4
|
+
readonly status: HealthStatus;
|
|
5
|
+
readonly code: string;
|
|
6
|
+
readonly errorName?: string;
|
|
7
|
+
}
|
|
8
|
+
export interface HealthCheckResult {
|
|
9
|
+
readonly status: HealthStatus;
|
|
10
|
+
readonly checkedAt: string;
|
|
11
|
+
readonly checks: readonly HealthCheckItem[];
|
|
12
|
+
}
|