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.
Files changed (303) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +377 -0
  3. package/dist/agent/finance-agent.d.ts +44 -0
  4. package/dist/agent/finance-agent.js +75 -0
  5. package/dist/agent/finance-agent.js.map +1 -0
  6. package/dist/agent/legal-agent.d.ts +44 -0
  7. package/dist/agent/legal-agent.js +76 -0
  8. package/dist/agent/legal-agent.js.map +1 -0
  9. package/dist/agent/medical-agent.d.ts +44 -0
  10. package/dist/agent/medical-agent.js +75 -0
  11. package/dist/agent/medical-agent.js.map +1 -0
  12. package/dist/agent/trusted-agent-registry.d.ts +53 -0
  13. package/dist/agent/trusted-agent-registry.js +57 -0
  14. package/dist/agent/trusted-agent-registry.js.map +1 -0
  15. package/dist/audit/audit-chain-verifier.d.ts +10 -0
  16. package/dist/audit/audit-chain-verifier.js +67 -0
  17. package/dist/audit/audit-chain-verifier.js.map +1 -0
  18. package/dist/audit/audit-log.d.ts +48 -0
  19. package/dist/audit/audit-log.js +74 -0
  20. package/dist/audit/audit-log.js.map +1 -0
  21. package/dist/audit/sqlite-audit-log.d.ts +29 -0
  22. package/dist/audit/sqlite-audit-log.js +142 -0
  23. package/dist/audit/sqlite-audit-log.js.map +1 -0
  24. package/dist/auth/access-context-issuer.d.ts +18 -0
  25. package/dist/auth/access-context-issuer.js +88 -0
  26. package/dist/auth/access-context-issuer.js.map +1 -0
  27. package/dist/auth/assert-authorized-for-subject.d.ts +2 -0
  28. package/dist/auth/assert-authorized-for-subject.js +20 -0
  29. package/dist/auth/assert-authorized-for-subject.js.map +1 -0
  30. package/dist/auth/backend-context-minting-boundary.d.ts +23 -0
  31. package/dist/auth/backend-context-minting-boundary.js +281 -0
  32. package/dist/auth/backend-context-minting-boundary.js.map +1 -0
  33. package/dist/auth/default-authorization-policy.d.ts +7 -0
  34. package/dist/auth/default-authorization-policy.js +64 -0
  35. package/dist/auth/default-authorization-policy.js.map +1 -0
  36. package/dist/auth/fake-auth-adapter.d.ts +7 -0
  37. package/dist/auth/fake-auth-adapter.js +27 -0
  38. package/dist/auth/fake-auth-adapter.js.map +1 -0
  39. package/dist/auth/http-client.d.ts +12 -0
  40. package/dist/auth/http-client.js +7 -0
  41. package/dist/auth/http-client.js.map +1 -0
  42. package/dist/auth/in-memory-grant-resolver.d.ts +21 -0
  43. package/dist/auth/in-memory-grant-resolver.js +73 -0
  44. package/dist/auth/in-memory-grant-resolver.js.map +1 -0
  45. package/dist/auth/in-memory-tenant-boundary.d.ts +16 -0
  46. package/dist/auth/in-memory-tenant-boundary.js +37 -0
  47. package/dist/auth/in-memory-tenant-boundary.js.map +1 -0
  48. package/dist/auth/jwks-key-ring-auth-adapter.d.ts +38 -0
  49. package/dist/auth/jwks-key-ring-auth-adapter.js +123 -0
  50. package/dist/auth/jwks-key-ring-auth-adapter.js.map +1 -0
  51. package/dist/auth/jwks-key-ring.d.ts +25 -0
  52. package/dist/auth/jwks-key-ring.js +111 -0
  53. package/dist/auth/jwks-key-ring.js.map +1 -0
  54. package/dist/auth/jwt-auth-adapter.d.ts +15 -0
  55. package/dist/auth/jwt-auth-adapter.js +59 -0
  56. package/dist/auth/jwt-auth-adapter.js.map +1 -0
  57. package/dist/auth/jwt-core.d.ts +32 -0
  58. package/dist/auth/jwt-core.js +226 -0
  59. package/dist/auth/jwt-core.js.map +1 -0
  60. package/dist/auth/jwt-key-ring-auth-adapter.d.ts +16 -0
  61. package/dist/auth/jwt-key-ring-auth-adapter.js +58 -0
  62. package/dist/auth/jwt-key-ring-auth-adapter.js.map +1 -0
  63. package/dist/auth/oidc-discovery.d.ts +15 -0
  64. package/dist/auth/oidc-discovery.js +46 -0
  65. package/dist/auth/oidc-discovery.js.map +1 -0
  66. package/dist/auth/production-scoped-life-api.d.ts +58 -0
  67. package/dist/auth/production-scoped-life-api.js +802 -0
  68. package/dist/auth/production-scoped-life-api.js.map +1 -0
  69. package/dist/auth/proposal-scope-inspector.d.ts +3 -0
  70. package/dist/auth/proposal-scope-inspector.js +42 -0
  71. package/dist/auth/proposal-scope-inspector.js.map +1 -0
  72. package/dist/auth/proposal-scoped-life-api.d.ts +21 -0
  73. package/dist/auth/proposal-scoped-life-api.js +168 -0
  74. package/dist/auth/proposal-scoped-life-api.js.map +1 -0
  75. package/dist/auth/rate-limited-context-minting-boundary.d.ts +27 -0
  76. package/dist/auth/rate-limited-context-minting-boundary.js +77 -0
  77. package/dist/auth/rate-limited-context-minting-boundary.js.map +1 -0
  78. package/dist/auth/revocation-aware-auth-adapter.d.ts +21 -0
  79. package/dist/auth/revocation-aware-auth-adapter.js +88 -0
  80. package/dist/auth/revocation-aware-auth-adapter.js.map +1 -0
  81. package/dist/auth/sqlite-grant-resolver.d.ts +8 -0
  82. package/dist/auth/sqlite-grant-resolver.js +78 -0
  83. package/dist/auth/sqlite-grant-resolver.js.map +1 -0
  84. package/dist/auth/sqlite-tenant-boundary.d.ts +7 -0
  85. package/dist/auth/sqlite-tenant-boundary.js +41 -0
  86. package/dist/auth/sqlite-tenant-boundary.js.map +1 -0
  87. package/dist/auth/static-jwt-key-ring.d.ts +13 -0
  88. package/dist/auth/static-jwt-key-ring.js +73 -0
  89. package/dist/auth/static-jwt-key-ring.js.map +1 -0
  90. package/dist/auth/subject-scoped-life-api.d.ts +14 -0
  91. package/dist/auth/subject-scoped-life-api.js +51 -0
  92. package/dist/auth/subject-scoped-life-api.js.map +1 -0
  93. package/dist/auth/test-context-minting-boundary.d.ts +13 -0
  94. package/dist/auth/test-context-minting-boundary.js +74 -0
  95. package/dist/auth/test-context-minting-boundary.js.map +1 -0
  96. package/dist/auth/types.d.ts +77 -0
  97. package/dist/auth/types.js +16 -0
  98. package/dist/auth/types.js.map +1 -0
  99. package/dist/compliance/subject-data-report.d.ts +43 -0
  100. package/dist/compliance/subject-data-report.js +155 -0
  101. package/dist/compliance/subject-data-report.js.map +1 -0
  102. package/dist/consent/consent-guard.d.ts +4 -0
  103. package/dist/consent/consent-guard.js +37 -0
  104. package/dist/consent/consent-guard.js.map +1 -0
  105. package/dist/consent/grant-registry.d.ts +7 -0
  106. package/dist/consent/grant-registry.js +13 -0
  107. package/dist/consent/grant-registry.js.map +1 -0
  108. package/dist/consent/intersect-selector.d.ts +3 -0
  109. package/dist/consent/intersect-selector.js +66 -0
  110. package/dist/consent/intersect-selector.js.map +1 -0
  111. package/dist/contract/diagnostics.d.ts +32 -0
  112. package/dist/contract/diagnostics.js +112 -0
  113. package/dist/contract/diagnostics.js.map +1 -0
  114. package/dist/contract/project-contracts.d.ts +5 -0
  115. package/dist/contract/project-contracts.js +159 -0
  116. package/dist/contract/project-contracts.js.map +1 -0
  117. package/dist/contract/types.d.ts +32 -0
  118. package/dist/contract/types.js +5 -0
  119. package/dist/contract/types.js.map +1 -0
  120. package/dist/crypto/aes-gcm.d.ts +11 -0
  121. package/dist/crypto/aes-gcm.js +78 -0
  122. package/dist/crypto/aes-gcm.js.map +1 -0
  123. package/dist/crypto/claim-serializer.d.ts +26 -0
  124. package/dist/crypto/claim-serializer.js +59 -0
  125. package/dist/crypto/claim-serializer.js.map +1 -0
  126. package/dist/crypto/sha256.d.ts +12 -0
  127. package/dist/crypto/sha256.js +40 -0
  128. package/dist/crypto/sha256.js.map +1 -0
  129. package/dist/crypto/static-key.d.ts +11 -0
  130. package/dist/crypto/static-key.js +60 -0
  131. package/dist/crypto/static-key.js.map +1 -0
  132. package/dist/crypto/types.d.ts +20 -0
  133. package/dist/crypto/types.js +8 -0
  134. package/dist/crypto/types.js.map +1 -0
  135. package/dist/datasource/trusted-data-source-registry.d.ts +51 -0
  136. package/dist/datasource/trusted-data-source-registry.js +57 -0
  137. package/dist/datasource/trusted-data-source-registry.js.map +1 -0
  138. package/dist/erasure/tombstone.d.ts +13 -0
  139. package/dist/erasure/tombstone.js +20 -0
  140. package/dist/erasure/tombstone.js.map +1 -0
  141. package/dist/evidence/evidence-backed-claim-creator.d.ts +48 -0
  142. package/dist/evidence/evidence-backed-claim-creator.js +107 -0
  143. package/dist/evidence/evidence-backed-claim-creator.js.map +1 -0
  144. package/dist/evidence/in-memory-raw-document-store.d.ts +26 -0
  145. package/dist/evidence/in-memory-raw-document-store.js +84 -0
  146. package/dist/evidence/in-memory-raw-document-store.js.map +1 -0
  147. package/dist/evidence/raw-document-store.d.ts +12 -0
  148. package/dist/evidence/raw-document-store.js +8 -0
  149. package/dist/evidence/raw-document-store.js.map +1 -0
  150. package/dist/evidence/source-evidence-validator.d.ts +4 -0
  151. package/dist/evidence/source-evidence-validator.js +14 -0
  152. package/dist/evidence/source-evidence-validator.js.map +1 -0
  153. package/dist/evidence/sqlite-raw-document-store.d.ts +19 -0
  154. package/dist/evidence/sqlite-raw-document-store.js +122 -0
  155. package/dist/evidence/sqlite-raw-document-store.js.map +1 -0
  156. package/dist/guardian/guardian-registry.d.ts +96 -0
  157. package/dist/guardian/guardian-registry.js +95 -0
  158. package/dist/guardian/guardian-registry.js.map +1 -0
  159. package/dist/index.d.ts +44 -0
  160. package/dist/index.js +72 -0
  161. package/dist/index.js.map +1 -0
  162. package/dist/observability/health.d.ts +12 -0
  163. package/dist/observability/health.js +16 -0
  164. package/dist/observability/health.js.map +1 -0
  165. package/dist/observability/logger.d.ts +21 -0
  166. package/dist/observability/logger.js +40 -0
  167. package/dist/observability/logger.js.map +1 -0
  168. package/dist/observability/metrics.d.ts +15 -0
  169. package/dist/observability/metrics.js +52 -0
  170. package/dist/observability/metrics.js.map +1 -0
  171. package/dist/persistence/backup.d.ts +24 -0
  172. package/dist/persistence/backup.js +251 -0
  173. package/dist/persistence/backup.js.map +1 -0
  174. package/dist/persistence/decryptability-scan.d.ts +10 -0
  175. package/dist/persistence/decryptability-scan.js +144 -0
  176. package/dist/persistence/decryptability-scan.js.map +1 -0
  177. package/dist/persistence/in-memory-unit-of-work.d.ts +11 -0
  178. package/dist/persistence/in-memory-unit-of-work.js +32 -0
  179. package/dist/persistence/in-memory-unit-of-work.js.map +1 -0
  180. package/dist/persistence/key-availability.d.ts +9 -0
  181. package/dist/persistence/key-availability.js +125 -0
  182. package/dist/persistence/key-availability.js.map +1 -0
  183. package/dist/persistence/sqlite/migrations.d.ts +9 -0
  184. package/dist/persistence/sqlite/migrations.js +535 -0
  185. package/dist/persistence/sqlite/migrations.js.map +1 -0
  186. package/dist/persistence/sqlite/schema.d.ts +10 -0
  187. package/dist/persistence/sqlite/schema.js +101 -0
  188. package/dist/persistence/sqlite/schema.js.map +1 -0
  189. package/dist/persistence/sqlite/sqlite-fact-store.d.ts +24 -0
  190. package/dist/persistence/sqlite/sqlite-fact-store.js +207 -0
  191. package/dist/persistence/sqlite/sqlite-fact-store.js.map +1 -0
  192. package/dist/persistence/sqlite/sqlite-source-registry.d.ts +17 -0
  193. package/dist/persistence/sqlite/sqlite-source-registry.js +132 -0
  194. package/dist/persistence/sqlite/sqlite-source-registry.js.map +1 -0
  195. package/dist/persistence/sqlite/sqlite-unit-of-work.d.ts +8 -0
  196. package/dist/persistence/sqlite/sqlite-unit-of-work.js +41 -0
  197. package/dist/persistence/sqlite/sqlite-unit-of-work.js.map +1 -0
  198. package/dist/persistence/sqlite/types.d.ts +24 -0
  199. package/dist/persistence/sqlite/types.js +28 -0
  200. package/dist/persistence/sqlite/types.js.map +1 -0
  201. package/dist/persistence/unit-of-work.d.ts +6 -0
  202. package/dist/persistence/unit-of-work.js +15 -0
  203. package/dist/persistence/unit-of-work.js.map +1 -0
  204. package/dist/proposal/accepted-claim-appender.d.ts +7 -0
  205. package/dist/proposal/accepted-claim-appender.js +16 -0
  206. package/dist/proposal/accepted-claim-appender.js.map +1 -0
  207. package/dist/proposal/in-memory-proposal-queue.d.ts +21 -0
  208. package/dist/proposal/in-memory-proposal-queue.js +218 -0
  209. package/dist/proposal/in-memory-proposal-queue.js.map +1 -0
  210. package/dist/proposal/policy-aware-proposal-queue.d.ts +23 -0
  211. package/dist/proposal/policy-aware-proposal-queue.js +162 -0
  212. package/dist/proposal/policy-aware-proposal-queue.js.map +1 -0
  213. package/dist/proposal/proposal-policy.d.ts +37 -0
  214. package/dist/proposal/proposal-policy.js +72 -0
  215. package/dist/proposal/proposal-policy.js.map +1 -0
  216. package/dist/proposal/proposal-queue.d.ts +13 -0
  217. package/dist/proposal/proposal-queue.js +15 -0
  218. package/dist/proposal/proposal-queue.js.map +1 -0
  219. package/dist/proposal/source-aware-claim-appender.d.ts +13 -0
  220. package/dist/proposal/source-aware-claim-appender.js +47 -0
  221. package/dist/proposal/source-aware-claim-appender.js.map +1 -0
  222. package/dist/proposal/sqlite-proposal-queue.d.ts +26 -0
  223. package/dist/proposal/sqlite-proposal-queue.js +282 -0
  224. package/dist/proposal/sqlite-proposal-queue.js.map +1 -0
  225. package/dist/resolution/resolve-claims.d.ts +4 -0
  226. package/dist/resolution/resolve-claims.js +101 -0
  227. package/dist/resolution/resolve-claims.js.map +1 -0
  228. package/dist/resolution/trust-profile.d.ts +12 -0
  229. package/dist/resolution/trust-profile.js +23 -0
  230. package/dist/resolution/trust-profile.js.map +1 -0
  231. package/dist/resolution/types.d.ts +15 -0
  232. package/dist/resolution/types.js +8 -0
  233. package/dist/resolution/types.js.map +1 -0
  234. package/dist/sdk/create-backend-integrated-life-api-for-test.d.ts +23 -0
  235. package/dist/sdk/create-backend-integrated-life-api-for-test.js +240 -0
  236. package/dist/sdk/create-backend-integrated-life-api-for-test.js.map +1 -0
  237. package/dist/sdk/create-life-api.d.ts +55 -0
  238. package/dist/sdk/create-life-api.js +251 -0
  239. package/dist/sdk/create-life-api.js.map +1 -0
  240. package/dist/sdk/create-sqlite-life-api.d.ts +33 -0
  241. package/dist/sdk/create-sqlite-life-api.js +654 -0
  242. package/dist/sdk/create-sqlite-life-api.js.map +1 -0
  243. package/dist/sdk/life-api.d.ts +27 -0
  244. package/dist/sdk/life-api.js +17 -0
  245. package/dist/sdk/life-api.js.map +1 -0
  246. package/dist/sdk/validation.d.ts +8 -0
  247. package/dist/sdk/validation.js +216 -0
  248. package/dist/sdk/validation.js.map +1 -0
  249. package/dist/source/in-memory-source-registry.d.ts +15 -0
  250. package/dist/source/in-memory-source-registry.js +104 -0
  251. package/dist/source/in-memory-source-registry.js.map +1 -0
  252. package/dist/source/source-aware-fact-store.d.ts +19 -0
  253. package/dist/source/source-aware-fact-store.js +40 -0
  254. package/dist/source/source-aware-fact-store.js.map +1 -0
  255. package/dist/source/source-kind-predicate-policy.d.ts +4 -0
  256. package/dist/source/source-kind-predicate-policy.js +62 -0
  257. package/dist/source/source-kind-predicate-policy.js.map +1 -0
  258. package/dist/source/source-registry.d.ts +11 -0
  259. package/dist/source/source-registry.js +12 -0
  260. package/dist/source/source-registry.js.map +1 -0
  261. package/dist/store/in-memory-fact-store.d.ts +25 -0
  262. package/dist/store/in-memory-fact-store.js +192 -0
  263. package/dist/store/in-memory-fact-store.js.map +1 -0
  264. package/dist/surface/context-query.d.ts +21 -0
  265. package/dist/surface/context-query.js +113 -0
  266. package/dist/surface/context-query.js.map +1 -0
  267. package/dist/surface/evidence-backed-context-query.d.ts +62 -0
  268. package/dist/surface/evidence-backed-context-query.js +240 -0
  269. package/dist/surface/evidence-backed-context-query.js.map +1 -0
  270. package/dist/types/access-context.d.ts +25 -0
  271. package/dist/types/access-context.js +6 -0
  272. package/dist/types/access-context.js.map +1 -0
  273. package/dist/types/claim.d.ts +48 -0
  274. package/dist/types/claim.js +5 -0
  275. package/dist/types/claim.js.map +1 -0
  276. package/dist/types/consent.d.ts +41 -0
  277. package/dist/types/consent.js +3 -0
  278. package/dist/types/consent.js.map +1 -0
  279. package/dist/types/crypto-boundary.d.ts +12 -0
  280. package/dist/types/crypto-boundary.js +15 -0
  281. package/dist/types/crypto-boundary.js.map +1 -0
  282. package/dist/types/evidence.d.ts +31 -0
  283. package/dist/types/evidence.js +8 -0
  284. package/dist/types/evidence.js.map +1 -0
  285. package/dist/types/fact-store.d.ts +24 -0
  286. package/dist/types/fact-store.js +12 -0
  287. package/dist/types/fact-store.js.map +1 -0
  288. package/dist/types/ids.d.ts +36 -0
  289. package/dist/types/ids.js +11 -0
  290. package/dist/types/ids.js.map +1 -0
  291. package/dist/types/proposal.d.ts +38 -0
  292. package/dist/types/proposal.js +7 -0
  293. package/dist/types/proposal.js.map +1 -0
  294. package/dist/types/source.d.ts +33 -0
  295. package/dist/types/source.js +6 -0
  296. package/dist/types/source.js.map +1 -0
  297. package/dist/types/trust.d.ts +24 -0
  298. package/dist/types/trust.js +5 -0
  299. package/dist/types/trust.js.map +1 -0
  300. package/dist/utilities/deep-freeze.d.ts +1 -0
  301. package/dist/utilities/deep-freeze.js +17 -0
  302. package/dist/utilities/deep-freeze.js.map +1 -0
  303. package/package.json +55 -0
@@ -0,0 +1,16 @@
1
+ // D2b Observability — HealthCheck types.
2
+ //
3
+ // PRODUCTION_OBSERVABILITY_HEALTHCHECK_SURFACE_SPECIFIED_001
4
+ // PRODUCTION_OBSERVABILITY_HEALTHCHECK_NO_DATA_EXPOSURE_001
5
+ // PRODUCTION_OBSERVABILITY_HEALTHCHECK_ITEM_NAMES_STABLE_001
6
+ //
7
+ // HealthStatus semantics:
8
+ // "ok" — all critical local checks passed.
9
+ // "degraded" — at least one non-critical check degraded (reserved for future checks).
10
+ // "failed" — at least one critical local check failed.
11
+ //
12
+ // "ok" does NOT mean operational production readiness, backup readiness,
13
+ // GDPR/legal readiness, or external IdP/KMS readiness.
14
+ // PRODUCTION_OBSERVABILITY_HEALTHCHECK_NOT_OPERATIONAL_READINESS_CLAIM_001
15
+ export {};
16
+ //# sourceMappingURL=health.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"health.js","sourceRoot":"","sources":["../../src/observability/health.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,EAAE;AACF,6DAA6D;AAC7D,4DAA4D;AAC5D,6DAA6D;AAC7D,EAAE;AACF,0BAA0B;AAC1B,mDAAmD;AACnD,wFAAwF;AACxF,2DAA2D;AAC3D,EAAE;AACF,yEAAyE;AACzE,uDAAuD;AACvD,2EAA2E"}
@@ -0,0 +1,21 @@
1
+ export type LogLevel = "debug" | "info" | "warn" | "error";
2
+ export interface LogEvent {
3
+ readonly level: LogLevel;
4
+ readonly code: string;
5
+ readonly component: string;
6
+ readonly operation: string;
7
+ readonly message: string;
8
+ readonly timestamp: string;
9
+ readonly errorName?: string;
10
+ readonly reasonCode?: string;
11
+ readonly contextKind?: string;
12
+ readonly correlationId?: string;
13
+ }
14
+ export interface Logger {
15
+ debug?(event: LogEvent): void | Promise<void>;
16
+ info?(event: LogEvent): void | Promise<void>;
17
+ warn?(event: LogEvent): void | Promise<void>;
18
+ error?(event: LogEvent): void | Promise<void>;
19
+ }
20
+ export declare const noopLogger: Logger;
21
+ export declare function safeLog(logger: Logger | undefined, event: LogEvent): void;
@@ -0,0 +1,40 @@
1
+ // D2a — Logger and Operator Diagnostics.
2
+ //
3
+ // PRODUCTION_OBSERVABILITY_LOGGER_INTERFACE_SPECIFIED_001: Logger has four optional level methods.
4
+ // PRODUCTION_OBSERVABILITY_NOOP_LOGGER_DEFAULT_001: noopLogger is frozen with no methods.
5
+ // PRODUCTION_OBSERVABILITY_NO_CONSOLE_DEFAULT_001: no console output emitted by default.
6
+ // PRODUCTION_OBSERVABILITY_LOGGER_FAILURE_NON_INTERFERING_001: safeLog swallows all logger failures.
7
+ // PRODUCTION_OBSERVABILITY_LOGGER_NOT_AUDIT_SOURCE_001: Logger is not tamper-evident and must not
8
+ // be used as compliance evidence or to prove authorization decisions.
9
+ // PRODUCTION_OBSERVABILITY_HEALTHCHECK_DEFERRED_001: healthCheck is not part of this module (D2b).
10
+ // PRODUCTION_OBSERVABILITY_METRICS_DEFERRED_001: metrics are not part of this module (D2c).
11
+ //
12
+ // Sensitive data policy: LogEvent fields must not contain rawBytes, JWTs, tokens, personId,
13
+ // subjectId, candidateClaims, decrypted payloads, raw documents, Error.message, or Error.stack.
14
+ // See docs/specs/post-mvp-observability-d2a-logger-spec.md §8 for the full policy.
15
+ // noopLogger: library default. No methods — no console output — frozen.
16
+ // PRODUCTION_OBSERVABILITY_NOOP_LOGGER_DEFAULT_001
17
+ // PRODUCTION_OBSERVABILITY_NO_CONSOLE_DEFAULT_001
18
+ export const noopLogger = Object.freeze({});
19
+ // safeLog: emit a sanitized LogEvent to the logger at the matching level.
20
+ // If the logger is absent, the matching method does not exist, the method throws synchronously,
21
+ // or the returned Promise rejects — all failures are swallowed.
22
+ // Never throws. Never masks the caller's error. Never affects transaction outcome.
23
+ // PRODUCTION_OBSERVABILITY_LOGGER_FAILURE_NON_INTERFERING_001
24
+ export function safeLog(logger, event) {
25
+ if (logger === undefined)
26
+ return;
27
+ const method = logger[event.level];
28
+ if (typeof method !== "function")
29
+ return;
30
+ try {
31
+ const result = method.call(logger, event);
32
+ if (result instanceof Promise) {
33
+ result.catch(() => { });
34
+ }
35
+ }
36
+ catch {
37
+ /* sync logger failure swallowed */
38
+ }
39
+ }
40
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/observability/logger.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,EAAE;AACF,mGAAmG;AACnG,0FAA0F;AAC1F,yFAAyF;AACzF,qGAAqG;AACrG,kGAAkG;AAClG,wEAAwE;AACxE,mGAAmG;AACnG,4FAA4F;AAC5F,EAAE;AACF,4FAA4F;AAC5F,gGAAgG;AAChG,mFAAmF;AA6BnF,wEAAwE;AACxE,mDAAmD;AACnD,kDAAkD;AAClD,MAAM,CAAC,MAAM,UAAU,GAAW,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;AAEpD,0EAA0E;AAC1E,gGAAgG;AAChG,gEAAgE;AAChE,mFAAmF;AACnF,8DAA8D;AAC9D,MAAM,UAAU,OAAO,CACrB,MAA0B,EAC1B,KAAe;IAEf,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO;IACjC,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACnC,IAAI,OAAO,MAAM,KAAK,UAAU;QAAE,OAAO;IACzC,IAAI,CAAC;QACH,MAAM,MAAM,GAAI,MAAgD,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QACrF,IAAI,MAAM,YAAY,OAAO,EAAE,CAAC;YAC9B,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,GAAwC,CAAC,CAAC,CAAC;QAC/D,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,mCAAmC;IACrC,CAAC;AACH,CAAC"}
@@ -0,0 +1,15 @@
1
+ export type MetricName = "factory.create.failure" | "audit.write.failure" | "allow_path.rollback" | "health_check.outcome" | "proposal.mutation.outcome";
2
+ export interface MetricLabels {
3
+ readonly component?: string;
4
+ readonly operation?: string;
5
+ readonly status?: "ok" | "failed" | "degraded" | "success" | "denied";
6
+ readonly errorCode?: string;
7
+ readonly checkName?: string;
8
+ readonly contextKind?: string;
9
+ }
10
+ export interface MetricsRecorder {
11
+ increment?(name: MetricName, value?: number, labels?: MetricLabels): void | Promise<void>;
12
+ observe?(name: MetricName, value: number, labels?: MetricLabels): void | Promise<void>;
13
+ }
14
+ export declare const noopMetricsRecorder: MetricsRecorder;
15
+ export declare function safeRecord(metrics: MetricsRecorder | undefined, name: MetricName, value: number, labels?: MetricLabels): void;
@@ -0,0 +1,52 @@
1
+ // D2c — Metrics Boundary.
2
+ //
3
+ // PRODUCTION_METRICS_BOUNDARY_SPECIFIED_001: D2c defines the metrics boundary.
4
+ // MetricsRecorder is the push-style adapter contract; noopMetricsRecorder is
5
+ // the library default. No external sink, HTTP endpoint, or OpenTelemetry added.
6
+ // PRODUCTION_METRICS_NO_EXTERNAL_SINK_001: no external sink in this library.
7
+ // PRODUCTION_METRICS_NO_HIGH_CARDINALITY_LABELS_001: labels use only the closed
8
+ // low-cardinality set — component, operation, status, errorCode, checkName, contextKind.
9
+ // PRODUCTION_METRICS_NO_PERSONAL_DATA_LABELS_001: labels never contain personId,
10
+ // subjectId, proposalId, claimId, documentId, agentId, keyId, rawBytes,
11
+ // Error.message, Error.stack, SQL, file paths, or decrypted payload content.
12
+ // PRODUCTION_METRICS_FAILURE_NON_INTERFERING_001: safeRecord swallows all recorder
13
+ // failures. A failing recorder never masks a business error, changes a transaction,
14
+ // or alters HealthCheckResult.
15
+ // PRODUCTION_METRICS_NOT_AUDIT_SOURCE_001: metrics are not tamper-evident. Must not
16
+ // be used as compliance evidence or to prove authorization decisions.
17
+ // PRODUCTION_METRICS_NOT_OPERATIONAL_READINESS_CLAIM_001: metric counts do not imply
18
+ // operational production readiness, SLA/SLO, or GDPR/legal readiness.
19
+ // PRODUCTION_METRICS_NO_PRODUCT_API_SURFACE_001: no metrics method on
20
+ // ProductionScopedLifeApi. MetricsRecorder is a factory config input only.
21
+ // PRODUCTION_METRICS_NAMES_STABLE_001: MetricName is a closed union. Five stable names.
22
+ // PRODUCTION_METRICS_NOOP_DEFAULT_001: noopMetricsRecorder is the library default.
23
+ //
24
+ // See docs/specs/post-mvp-observability-d2c-metrics-spec.md for full policy.
25
+ // noopMetricsRecorder: library default. Frozen. No external call. No output.
26
+ // PRODUCTION_METRICS_NOOP_DEFAULT_001
27
+ export const noopMetricsRecorder = Object.freeze({
28
+ increment() { },
29
+ observe() { },
30
+ });
31
+ // safeRecord: emit a counter increment to the recorder.
32
+ // PRODUCTION_METRICS_FAILURE_NON_INTERFERING_001: swallows all recorder failures
33
+ // (sync throw and async reject). Never throws. Never masks the caller's error.
34
+ // Never affects transaction outcome. Not exported from src/index.ts.
35
+ export function safeRecord(metrics, name, value, labels) {
36
+ if (metrics === undefined)
37
+ return;
38
+ const method = metrics.increment;
39
+ if (typeof method !== "function")
40
+ return;
41
+ try {
42
+ const result = method
43
+ .call(metrics, name, value, labels);
44
+ if (result instanceof Promise) {
45
+ result.catch(() => { });
46
+ }
47
+ }
48
+ catch {
49
+ /* sync recorder failure swallowed */
50
+ }
51
+ }
52
+ //# sourceMappingURL=metrics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metrics.js","sourceRoot":"","sources":["../../src/observability/metrics.ts"],"names":[],"mappings":"AAAA,0BAA0B;AAC1B,EAAE;AACF,+EAA+E;AAC/E,+EAA+E;AAC/E,kFAAkF;AAClF,6EAA6E;AAC7E,gFAAgF;AAChF,2FAA2F;AAC3F,iFAAiF;AACjF,0EAA0E;AAC1E,+EAA+E;AAC/E,mFAAmF;AACnF,sFAAsF;AACtF,iCAAiC;AACjC,oFAAoF;AACpF,wEAAwE;AACxE,qFAAqF;AACrF,wEAAwE;AACxE,sEAAsE;AACtE,6EAA6E;AAC7E,wFAAwF;AACxF,mFAAmF;AACnF,EAAE;AACF,6EAA6E;AAkC7E,6EAA6E;AAC7E,sCAAsC;AACtC,MAAM,CAAC,MAAM,mBAAmB,GAAoB,MAAM,CAAC,MAAM,CAAC;IAChE,SAAS,KAAI,CAAC;IACd,OAAO,KAAM,CAAC;CACf,CAAC,CAAC;AAEH,wDAAwD;AACxD,iFAAiF;AACjF,iFAAiF;AACjF,uEAAuE;AACvE,MAAM,UAAU,UAAU,CACxB,OAAoC,EACpC,IAAmB,EACnB,KAAe,EACf,MAAqB;IAErB,IAAI,OAAO,KAAK,SAAS;QAAE,OAAO;IAClC,MAAM,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC;IACjC,IAAI,OAAO,MAAM,KAAK,UAAU;QAAE,OAAO;IACzC,IAAI,CAAC;QACH,MAAM,MAAM,GAAI,MAAgF;aAC7F,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;QACtC,IAAI,MAAM,YAAY,OAAO,EAAE,CAAC;YAC9B,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,GAA0C,CAAC,CAAC,CAAC;QACjE,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,qCAAqC;IACvC,CAAC;AACH,CAAC"}
@@ -0,0 +1,24 @@
1
+ import Database from "better-sqlite3";
2
+ type SemanticCheckCode = "RESTORE_SEMANTIC_ORPHANED_CLAIM_SOURCES_001" | "RESTORE_SEMANTIC_ORPHANED_EVIDENCE_REFS_001" | "RESTORE_SEMANTIC_ORPHANED_PROPOSAL_GRANTS_001" | "RESTORE_SEMANTIC_AUDIT_SEQUENCE_DUPLICATE_001";
3
+ export interface SemanticValidationResult {
4
+ readonly status: "ok" | "failed";
5
+ readonly checkedAt: string;
6
+ readonly checkCount?: number;
7
+ readonly failedChecks?: readonly SemanticCheckCode[];
8
+ readonly errorName?: string;
9
+ }
10
+ export interface BackupResult {
11
+ readonly status: "ok" | "failed";
12
+ readonly createdAt: string;
13
+ readonly errorName?: string;
14
+ }
15
+ export interface ValidationResult {
16
+ readonly status: "ok" | "failed";
17
+ readonly checkedAt: string;
18
+ readonly schemaVersion?: number;
19
+ readonly errorName?: string;
20
+ }
21
+ export declare function backupSQLiteDatabase(db: Database.Database, destinationPath: string): Promise<BackupResult>;
22
+ export declare function validateBackup(sourcePath: string): Promise<ValidationResult>;
23
+ export declare function validateRestoreSemantics(sourcePath: string): Promise<SemanticValidationResult>;
24
+ export {};
@@ -0,0 +1,251 @@
1
+ // D3a — SQLite Backup and Restore Validation boundary.
2
+ //
3
+ // PRODUCTION_BACKUP_BOUNDARY_SPECIFIED_001: all 8 schema tables are included
4
+ // in a backup via the SQLite backup API (db.backup). The backup is a
5
+ // consistent, self-contained SQLite file — no .wal/.shm files required.
6
+ // PRODUCTION_BACKUP_SQLITE_CONSISTENCY_STRATEGY_SPECIFIED_001: uses
7
+ // db.backup(dest) — online-safe, WAL-consistent, SAVEPOINT-safe. Never
8
+ // copies .db/.wal/.shm files manually; never uses VACUUM INTO.
9
+ // PRODUCTION_BACKUP_NO_DECRYPTED_PAYLOAD_EXPORT_001: backup copies encrypted
10
+ // ciphertext columns only. No encrypted payload is decrypted, read, logged,
11
+ // or returned. No key provider is required.
12
+ // PRODUCTION_BACKUP_NO_KEY_MATERIAL_CLAIM_001: backup does not include or
13
+ // manage external key material. AES-256 keys reside in StaticKeyProvider
14
+ // process memory only — never in the DB. Restore requires the original key
15
+ // provider to read encrypted payloads.
16
+ // PRODUCTION_BACKUP_POST_BACKUP_VERIFICATION_REQUIRED_001: after db.backup()
17
+ // resolves, verifyCurrentSchema is run on the destination file. BackupResult
18
+ // reflects both steps.
19
+ // PRODUCTION_BACKUP_NEVER_THROWS_001: backupSQLiteDatabase never throws.
20
+ // Failures are expressed as BackupResult { status: "failed" }.
21
+ // PRODUCTION_RESTORE_VALIDATION_SPECIFIED_001: validateBackup opens the backup
22
+ // read-only, runs verifyCurrentSchema, and confirms migration_version equals
23
+ // CURRENT_SCHEMA_VERSION.
24
+ // PRODUCTION_RESTORE_NO_ACTIVE_DB_OVERWRITE_001: validateBackup opens a
25
+ // separate read-only connection. It does not overwrite or modify any
26
+ // currently-open production database.
27
+ // PRODUCTION_BACKUP_NOT_OPERATIONAL_READINESS_CLAIM_001: a successful backup
28
+ // does not constitute operational production readiness, SLA, or disaster
29
+ // recovery guarantee.
30
+ // PRODUCTION_BACKUP_NOT_GDPR_LEGAL_CLAIM_001: backup/restore does not
31
+ // constitute GDPR-valid erasure or legal compliance. Restoring from backup
32
+ // before an erasure event reconstitutes erased data — this is a known
33
+ // limitation.
34
+ //
35
+ // Semantic Restore Validation (Rank 3):
36
+ // RESTORE_SEMANTIC_VALIDATION_OFFLINE_ONLY_001: validateRestoreSemantics opens
37
+ // backup read-only; makes no writes; emits no audit events.
38
+ // RESTORE_SEMANTIC_VALIDATION_SANITIZED_001: result carries only status,
39
+ // checkedAt, checkCount, failedChecks (error codes), and errorName. No entity
40
+ // IDs, no row counts, no DB path, no Error.message or Error.stack in result.
41
+ // RESTORE_SEMANTIC_VALIDATION_NEVER_THROWS_001: validateRestoreSemantics never
42
+ // throws. All failures expressed as { status: "failed", ... }.
43
+ // RESTORE_SEMANTIC_VALIDATION_NOT_OPERATIONAL_READINESS_001: { status: "ok" }
44
+ // does NOT constitute DR readiness, SLA, or legal erasure compliance.
45
+ // RESTORE_SEMANTIC_VALIDATION_NOT_PRODUCT_API_001: not on ProductionApiBundle,
46
+ // ProductionScopedLifeApi, or root-exported from src/index.ts.
47
+ import Database from "better-sqlite3";
48
+ import { verifyCurrentSchema, CURRENT_SCHEMA_VERSION, } from "./sqlite/migrations.js";
49
+ // ─── backupSQLiteDatabase ──────────────────────────────────────────────────────
50
+ // Copies the database using the SQLite backup API (sqlite3_backup_*).
51
+ // Online-safe: runs while other connections write; WAL-consistent; SAVEPOINT-safe.
52
+ // After the backup resolves, verifyCurrentSchema is run on the destination file.
53
+ // Returns { status: "failed" } on any failure — never throws.
54
+ // Does not write audit events. Does not require key material. Does not read or
55
+ // return any encrypted payload column content.
56
+ export async function backupSQLiteDatabase(db, destinationPath) {
57
+ const createdAt = new Date().toISOString();
58
+ // Step 1: SQLite backup API — online-safe, WAL-consistent.
59
+ try {
60
+ await db.backup(destinationPath);
61
+ }
62
+ catch (err) {
63
+ return {
64
+ status: "failed",
65
+ createdAt,
66
+ ...(err instanceof Error ? { errorName: err.name } : {}),
67
+ };
68
+ }
69
+ // Step 2: Post-backup structural verification on destination (read-only).
70
+ let verifyDb;
71
+ try {
72
+ verifyDb = new Database(destinationPath, { readonly: true, fileMustExist: true });
73
+ const structResult = verifyCurrentSchema(verifyDb);
74
+ if (!structResult.ok) {
75
+ return { status: "failed", createdAt, errorName: "BackupVerificationError" };
76
+ }
77
+ return { status: "ok", createdAt };
78
+ }
79
+ catch (err) {
80
+ return {
81
+ status: "failed",
82
+ createdAt,
83
+ ...(err instanceof Error ? { errorName: err.name } : {}),
84
+ };
85
+ }
86
+ finally {
87
+ try {
88
+ verifyDb?.close();
89
+ }
90
+ catch { /* ignore close errors */ }
91
+ }
92
+ }
93
+ // ─── validateBackup ────────────────────────────────────────────────────────────
94
+ // Opens the backup file read-only and verifies:
95
+ // 1. All required tables, columns, and indexes exist (verifyCurrentSchema)
96
+ // 2. migration_version === CURRENT_SCHEMA_VERSION
97
+ // Returns { status: "ok", schemaVersion } on success.
98
+ // Returns { status: "failed", errorName } on failure — never throws.
99
+ // Does not decrypt payloads. Does not require key material. Does not write to
100
+ // any table. Closes the read-only connection before returning.
101
+ export async function validateBackup(sourcePath) {
102
+ const checkedAt = new Date().toISOString();
103
+ let db;
104
+ try {
105
+ db = new Database(sourcePath, { readonly: true, fileMustExist: true });
106
+ // Structural check — tables, columns, indexes.
107
+ const structResult = verifyCurrentSchema(db);
108
+ if (!structResult.ok) {
109
+ return { status: "failed", checkedAt, errorName: "SchemaVerificationError" };
110
+ }
111
+ // Migration version check.
112
+ const row = db
113
+ .prepare("SELECT value FROM schema_meta WHERE key = 'migration_version'")
114
+ .get();
115
+ const version = row !== undefined ? parseInt(row.value, 10) : NaN;
116
+ if (!Number.isFinite(version) || version !== CURRENT_SCHEMA_VERSION) {
117
+ return {
118
+ status: "failed",
119
+ checkedAt,
120
+ errorName: "SchemaMigrationVersionError",
121
+ ...(Number.isFinite(version) ? { schemaVersion: version } : {}),
122
+ };
123
+ }
124
+ return { status: "ok", checkedAt, schemaVersion: version };
125
+ }
126
+ catch (err) {
127
+ return {
128
+ status: "failed",
129
+ checkedAt,
130
+ ...(err instanceof Error ? { errorName: err.name } : {}),
131
+ };
132
+ }
133
+ finally {
134
+ try {
135
+ db?.close();
136
+ }
137
+ catch { /* ignore close errors */ }
138
+ }
139
+ }
140
+ // ─── validateRestoreSemantics ─────────────────────────────────────────────────
141
+ // Opens the backup file (or any migrated SQLite file) read-only and runs four
142
+ // application-layer referential integrity checks that structural and cryptographic
143
+ // validation cannot detect:
144
+ //
145
+ // 1. Orphaned claim→source references
146
+ // (claims.source_id NOT IN sources.id)
147
+ // 2. Orphaned source evidence references
148
+ // (sources.evidence_id references a raw_documents.id that does not exist)
149
+ // 3. Orphaned proposal→grant references
150
+ // (proposals.under_grant NOT IN auth_grants.grant_id)
151
+ // 4. Duplicate audit event sequence numbers
152
+ // (audit_events.sequence uniqueness violated post-restore)
153
+ //
154
+ // Returns { status: "ok" } when all four checks pass.
155
+ // Returns { status: "failed", failedChecks: [...] } listing which checks failed
156
+ // (error codes only — no entity IDs, no row counts, no hash values).
157
+ // Returns { status: "failed", errorName } on DB open or schema setup failure.
158
+ //
159
+ // Never throws (RESTORE_SEMANTIC_VALIDATION_NEVER_THROWS_001).
160
+ // Opens a separate read-only connection — does not modify any open DB
161
+ // (RESTORE_SEMANTIC_VALIDATION_OFFLINE_ONLY_001).
162
+ // { status: "ok" } is NOT a DR/SLA/GDPR claim
163
+ // (RESTORE_SEMANTIC_VALIDATION_NOT_OPERATIONAL_READINESS_001).
164
+ export async function validateRestoreSemantics(sourcePath) {
165
+ const checkedAt = new Date().toISOString();
166
+ let db;
167
+ try {
168
+ db = new Database(sourcePath, { readonly: true, fileMustExist: true });
169
+ // Structural guard — fail fast if schema is invalid or wrong version.
170
+ // Reuses the same verifyCurrentSchema guard as validateBackup.
171
+ const structResult = verifyCurrentSchema(db);
172
+ if (!structResult.ok) {
173
+ return { status: "failed", checkedAt, errorName: "SchemaVerificationError" };
174
+ }
175
+ const failed = [];
176
+ // ── Check 1: Orphaned claim→source references ──────────────────────────
177
+ // RESTORE_SEMANTIC_ORPHANED_CLAIM_SOURCES_001
178
+ // Every claims.source_id must resolve to a sources.id in the same backup.
179
+ // An orphaned source_id indicates a truncated or partial backup.
180
+ const orphanedClaims = db
181
+ .prepare(`SELECT COUNT(*) AS cnt FROM claims
182
+ WHERE source_id NOT IN (SELECT id FROM sources)`)
183
+ .get();
184
+ if (orphanedClaims.cnt > 0) {
185
+ failed.push("RESTORE_SEMANTIC_ORPHANED_CLAIM_SOURCES_001");
186
+ }
187
+ // ── Check 2: Orphaned source→evidence references ───────────────────────
188
+ // RESTORE_SEMANTIC_ORPHANED_EVIDENCE_REFS_001
189
+ // Every non-null sources.evidence_id must resolve to a raw_documents.id.
190
+ // NULL evidence_id is allowed (source without attached document).
191
+ const orphanedEvidence = db
192
+ .prepare(`SELECT COUNT(*) AS cnt FROM sources
193
+ WHERE evidence_id IS NOT NULL
194
+ AND evidence_id NOT IN (SELECT id FROM raw_documents)`)
195
+ .get();
196
+ if (orphanedEvidence.cnt > 0) {
197
+ failed.push("RESTORE_SEMANTIC_ORPHANED_EVIDENCE_REFS_001");
198
+ }
199
+ // ── Check 3: Orphaned proposal→grant references ────────────────────────
200
+ // RESTORE_SEMANTIC_ORPHANED_PROPOSAL_GRANTS_001
201
+ // Every proposals.under_grant must resolve to an auth_grants.grant_id.
202
+ const orphanedGrants = db
203
+ .prepare(`SELECT COUNT(*) AS cnt FROM proposals
204
+ WHERE under_grant NOT IN (SELECT grant_id FROM auth_grants)`)
205
+ .get();
206
+ if (orphanedGrants.cnt > 0) {
207
+ failed.push("RESTORE_SEMANTIC_ORPHANED_PROPOSAL_GRANTS_001");
208
+ }
209
+ // ── Check 4: Duplicate audit event sequence numbers ────────────────────
210
+ // RESTORE_SEMANTIC_AUDIT_SEQUENCE_DUPLICATE_001
211
+ // The audit_events_sequence_unique index enforces uniqueness at write time.
212
+ // This check is defense-in-depth after restore — a corrupt restore could
213
+ // violate the constraint without triggering an index rebuild.
214
+ const dupSequences = db
215
+ .prepare(`SELECT COUNT(*) AS cnt FROM (
216
+ SELECT sequence FROM audit_events
217
+ GROUP BY sequence HAVING COUNT(*) > 1
218
+ )`)
219
+ .get();
220
+ if (dupSequences.cnt > 0) {
221
+ failed.push("RESTORE_SEMANTIC_AUDIT_SEQUENCE_DUPLICATE_001");
222
+ }
223
+ // ── Aggregate result ───────────────────────────────────────────────────
224
+ const TOTAL_CHECKS = 4;
225
+ if (failed.length === 0) {
226
+ return { status: "ok", checkedAt, checkCount: TOTAL_CHECKS };
227
+ }
228
+ return {
229
+ status: "failed",
230
+ checkedAt,
231
+ checkCount: TOTAL_CHECKS,
232
+ failedChecks: failed,
233
+ };
234
+ }
235
+ catch (err) {
236
+ // DB open, schema verification, or SQL threw. checkCount is omitted —
237
+ // setup itself failed before any individual check could run.
238
+ return {
239
+ status: "failed",
240
+ checkedAt,
241
+ ...(err instanceof Error ? { errorName: err.name } : {}),
242
+ };
243
+ }
244
+ finally {
245
+ try {
246
+ db?.close();
247
+ }
248
+ catch { /* ignore close errors */ }
249
+ }
250
+ }
251
+ //# sourceMappingURL=backup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backup.js","sourceRoot":"","sources":["../../src/persistence/backup.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { CryptoBoundary } from "../crypto/types.js";
2
+ export interface DecryptabilityScanResult {
3
+ readonly status: "ok" | "partial" | "failed";
4
+ readonly scannedAt: string;
5
+ readonly totalCount?: number;
6
+ readonly decryptedCount?: number;
7
+ readonly failedCount?: number;
8
+ readonly errorName?: string;
9
+ }
10
+ export declare function scanBackupDecryptability(sourcePath: string, cryptoBoundary: CryptoBoundary): Promise<DecryptabilityScanResult>;
@@ -0,0 +1,144 @@
1
+ // D4c — Full Decryptability Scan boundary.
2
+ //
3
+ // PRODUCTION_DECRYPTABILITY_SCAN_OFFLINE_ONLY_001:
4
+ // Opens backup file read-only. Makes no writes to any SQLite table.
5
+ // Does not emit audit events. Does not call logger.
6
+ // PRODUCTION_DECRYPTABILITY_SCAN_NO_PLAINTEXT_EXPOSURE_001:
7
+ // Decrypted bytes are discarded immediately after each decrypt call.
8
+ // Plaintext never appears in result, errors, logs, metrics, or audit.
9
+ // PRODUCTION_DECRYPTABILITY_SCAN_AGGREGATE_RESULT_ONLY_001:
10
+ // Result contains only status, scannedAt, totalCount, decryptedCount,
11
+ // failedCount, and errorName. No entity IDs, no keyId strings, no
12
+ // ciphertext fragments, no per-row breakdown, no per-table breakdown.
13
+ // PRODUCTION_DECRYPTABILITY_SCAN_THREE_TABLES_001:
14
+ // Covers all three encrypted tables: claims.encrypted_payload,
15
+ // raw_documents.encrypted_blob, proposals.encrypted_payload.
16
+ // PRODUCTION_DECRYPTABILITY_SCAN_NOT_PRODUCT_API_001:
17
+ // Not on ProductionApiBundle, ProductionScopedLifeApi, or package root.
18
+ // PRODUCTION_DECRYPTABILITY_SCAN_NEVER_THROWS_001:
19
+ // scanBackupDecryptability never throws. All errors expressed as
20
+ // DecryptabilityScanResult { status: "failed", scannedAt, errorName }.
21
+ //
22
+ // IMPORTANT: failedCount does NOT distinguish between wrong key bytes,
23
+ // corrupt ciphertext, malformed blob, or any other decrypt failure.
24
+ // This utility proves only that AES-GCM tag verification succeeds (or fails)
25
+ // for each row with the provided CryptoBoundary. It is NOT a recovery claim.
26
+ //
27
+ // See docs/specs/post-mvp-d4c-decryptability-scan-spec.md
28
+ import Database from "better-sqlite3";
29
+ import { verifyCurrentSchema } from "./sqlite/migrations.js";
30
+ // ─── Inventory SQL ────────────────────────────────────────────────────────────
31
+ // Retrieves raw JSON blobs from all three encrypted payload columns.
32
+ // Results are ordered to enable deterministic test assertions.
33
+ // No entity IDs, primary keys, or foreign keys are selected.
34
+ const DECRYPT_INVENTORY_SQL = `
35
+ SELECT encrypted_payload AS blob FROM claims
36
+ UNION ALL
37
+ SELECT encrypted_blob AS blob FROM raw_documents
38
+ UNION ALL
39
+ SELECT encrypted_payload AS blob FROM proposals
40
+ ORDER BY 1
41
+ `;
42
+ // ─── scanBackupDecryptability ─────────────────────────────────────────────────
43
+ // Opens a backup file (or any migrated SQLite file) read-only and attempts to
44
+ // decrypt every encrypted payload using the provided CryptoBoundary.
45
+ //
46
+ // All decryption is delegated to the provided CryptoBoundary parameter.
47
+ // This file contains no raw WebCrypto API calls (CRYPTO_BOUNDARY_ONLY_001).
48
+ //
49
+ // Decrypted bytes are discarded immediately after the decrypt call. They are
50
+ // never assigned to a persistent variable, returned, logged, or audited.
51
+ //
52
+ // Algorithm:
53
+ // 1. Open sourcePath read-only (fileMustExist: true).
54
+ // 2. Run verifyCurrentSchema — fail fast if not a valid, current-version DB.
55
+ // 3. Run DECRYPT_INVENTORY_SQL to enumerate all encrypted blobs.
56
+ // 4. For each blob:
57
+ // a. Parse JSON → EncryptedBlob (malformed → failedCount++; continue)
58
+ // b. Call cryptoBoundary.decryptBytes(blob) → discard plaintext
59
+ // c. On throw (CRYPTO_TAMPER_DETECTED_001 or CRYPTO_WRONG_KEY_FAIL_CLOSED_001)
60
+ // → failedCount++; continue
61
+ // 5. Close DB.
62
+ // 6. Return aggregate DecryptabilityScanResult — counts only.
63
+ //
64
+ // Status semantics:
65
+ // "ok" — failedCount === 0; all rows decrypted.
66
+ // "partial" — failedCount > 0 && decryptedCount > 0; some rows failed.
67
+ // "failed" — DB open/schema/inventory failed (counts omitted); OR
68
+ // decryptedCount === 0 (all rows failed; counts present).
69
+ export async function scanBackupDecryptability(sourcePath, cryptoBoundary) {
70
+ const scannedAt = new Date().toISOString();
71
+ let db;
72
+ try {
73
+ db = new Database(sourcePath, { readonly: true, fileMustExist: true });
74
+ // Structural check — fail early if schema is invalid or wrong version.
75
+ const structResult = verifyCurrentSchema(db);
76
+ if (!structResult.ok) {
77
+ return { status: "failed", scannedAt, errorName: "SchemaVerificationError" };
78
+ }
79
+ // Enumerate all encrypted blobs. No entity IDs are selected — only blob text.
80
+ const rows = db
81
+ .prepare(DECRYPT_INVENTORY_SQL)
82
+ .all();
83
+ let decryptedCount = 0;
84
+ let failedCount = 0;
85
+ for (const row of rows) {
86
+ // Malformed or NULL blob — count as failed; no plaintext involved.
87
+ if (row.blob === null || row.blob === "") {
88
+ failedCount++;
89
+ continue;
90
+ }
91
+ let parsed;
92
+ try {
93
+ parsed = JSON.parse(row.blob);
94
+ }
95
+ catch {
96
+ // Blob is not valid JSON — cannot construct EncryptedBlob.
97
+ failedCount++;
98
+ continue;
99
+ }
100
+ if (typeof parsed !== "object" ||
101
+ parsed === null ||
102
+ Array.isArray(parsed) ||
103
+ parsed["algorithm"] !== "AES-256-GCM") {
104
+ failedCount++;
105
+ continue;
106
+ }
107
+ const blob = parsed;
108
+ try {
109
+ // Attempt AES-GCM decrypt — the only thing we verify is that the tag
110
+ // passes. Returned Uint8Array is discarded immediately.
111
+ await cryptoBoundary.decryptBytes(blob);
112
+ decryptedCount++;
113
+ }
114
+ catch {
115
+ // CRYPTO_TAMPER_DETECTED_001: tag verification failed (corrupt ciphertext,
116
+ // wrong key bytes, or wrong IV). CRYPTO_WRONG_KEY_FAIL_CLOSED_001: keyId
117
+ // unknown to provider. Both are unrecoverable per-row failures.
118
+ // failedCount does not distinguish these failure modes — it is an aggregate.
119
+ failedCount++;
120
+ }
121
+ }
122
+ const totalCount = decryptedCount + failedCount;
123
+ const status = failedCount === 0 ? "ok"
124
+ : decryptedCount > 0 ? "partial"
125
+ : /* all rows failed */ "failed";
126
+ return { status, scannedAt, totalCount, decryptedCount, failedCount };
127
+ }
128
+ catch (err) {
129
+ // DB open, schema verification, or inventory SQL threw.
130
+ // Counts are omitted — the inventory step itself failed.
131
+ return {
132
+ status: "failed",
133
+ scannedAt,
134
+ ...(err instanceof Error ? { errorName: err.name } : {}),
135
+ };
136
+ }
137
+ finally {
138
+ try {
139
+ db?.close();
140
+ }
141
+ catch { /* ignore close errors */ }
142
+ }
143
+ }
144
+ //# sourceMappingURL=decryptability-scan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decryptability-scan.js","sourceRoot":"","sources":["../../src/persistence/decryptability-scan.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import type { UnitOfWork } from "./unit-of-work.js";
2
+ import { InMemoryRawDocumentStore } from "../evidence/in-memory-raw-document-store.js";
3
+ import { InMemorySourceRegistry } from "../source/in-memory-source-registry.js";
4
+ import { InMemoryFactStore } from "../store/in-memory-fact-store.js";
5
+ export declare class InMemoryUnitOfWork implements UnitOfWork {
6
+ private readonly _docStore;
7
+ private readonly _srcReg;
8
+ private readonly _factStore;
9
+ constructor(_docStore: InMemoryRawDocumentStore, _srcReg: InMemorySourceRegistry, _factStore: InMemoryFactStore);
10
+ run<T>(fn: () => Promise<T>): Promise<T>;
11
+ }