@atomicmemory/core 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +27 -0
- package/LICENSE +201 -0
- package/README.md +314 -0
- package/dist/app/bind-ephemeral.d.ts +18 -0
- package/dist/app/bind-ephemeral.js +22 -0
- package/dist/app/cors-headers.d.ts +12 -0
- package/dist/app/cors-headers.js +18 -0
- package/dist/app/create-app.d.ts +25 -0
- package/dist/app/create-app.js +156 -0
- package/dist/app/runtime-config-route-snapshot.d.ts +27 -0
- package/dist/app/runtime-config-route-snapshot.js +27 -0
- package/dist/app/runtime-container.d.ts +281 -0
- package/dist/app/runtime-container.js +297 -0
- package/dist/app/startup-checks.d.ts +28 -0
- package/dist/app/startup-checks.js +45 -0
- package/dist/bin.d.ts +17 -0
- package/dist/bin.js +128 -0
- package/dist/config.d.ts +680 -0
- package/dist/config.js +808 -0
- package/dist/db/agent-trust-repository.d.ts +49 -0
- package/dist/db/agent-trust-repository.js +66 -0
- package/dist/db/belief-edges-repository.d.ts +68 -0
- package/dist/db/belief-edges-repository.js +124 -0
- package/dist/db/claim-repository.d.ts +6 -0
- package/dist/db/claim-repository.js +4 -0
- package/dist/db/contradictions-repository.d.ts +56 -0
- package/dist/db/contradictions-repository.js +88 -0
- package/dist/db/document-chunk-repository.d.ts +48 -0
- package/dist/db/document-chunk-repository.js +145 -0
- package/dist/db/document-chunk-types.d.ts +35 -0
- package/dist/db/document-chunk-types.js +9 -0
- package/dist/db/document-list-cursor.d.ts +45 -0
- package/dist/db/document-list-cursor.js +111 -0
- package/dist/db/document-list-repository.d.ts +103 -0
- package/dist/db/document-list-repository.js +204 -0
- package/dist/db/entity-cards-repository.d.ts +37 -0
- package/dist/db/entity-cards-repository.js +46 -0
- package/dist/db/entity-values-repository.d.ts +26 -0
- package/dist/db/entity-values-repository.js +57 -0
- package/dist/db/link-repository.d.ts +30 -0
- package/dist/db/link-repository.js +54 -0
- package/dist/db/memory-repository.d.ts +163 -0
- package/dist/db/memory-repository.js +232 -0
- package/dist/db/migrate.d.ts +6 -0
- package/dist/db/migrate.js +36 -0
- package/dist/db/mmr.d.ts +14 -0
- package/dist/db/mmr.js +57 -0
- package/dist/db/passport-feed-repository.d.ts +91 -0
- package/dist/db/passport-feed-repository.js +198 -0
- package/dist/db/pg-episode-store.d.ts +19 -0
- package/dist/db/pg-episode-store.js +17 -0
- package/dist/db/pg-link-store.d.ts +17 -0
- package/dist/db/pg-link-store.js +14 -0
- package/dist/db/pg-memory-store.d.ts +68 -0
- package/dist/db/pg-memory-store.js +53 -0
- package/dist/db/pg-recap-store.d.ts +13 -0
- package/dist/db/pg-recap-store.js +19 -0
- package/dist/db/pg-representation-store.d.ts +17 -0
- package/dist/db/pg-representation-store.js +17 -0
- package/dist/db/pg-search-store.d.ts +29 -0
- package/dist/db/pg-search-store.js +47 -0
- package/dist/db/pool.d.ts +5 -0
- package/dist/db/pool.js +21 -0
- package/dist/db/ppr.d.ts +56 -0
- package/dist/db/ppr.js +178 -0
- package/dist/db/query-helpers.d.ts +44 -0
- package/dist/db/query-helpers.js +60 -0
- package/dist/db/raw-doc-artifact-sync.d.ts +128 -0
- package/dist/db/raw-doc-artifact-sync.js +259 -0
- package/dist/db/raw-document-blob-repository.d.ts +148 -0
- package/dist/db/raw-document-blob-repository.js +300 -0
- package/dist/db/raw-document-repository.d.ts +104 -0
- package/dist/db/raw-document-repository.js +410 -0
- package/dist/db/raw-document-status-repository.d.ts +122 -0
- package/dist/db/raw-document-status-repository.js +183 -0
- package/dist/db/raw-document-types.d.ts +236 -0
- package/dist/db/raw-document-types.js +10 -0
- package/dist/db/raw-storage-reconciliation-repository.d.ts +110 -0
- package/dist/db/raw-storage-reconciliation-repository.js +200 -0
- package/dist/db/reflection-jobs-repository.d.ts +33 -0
- package/dist/db/reflection-jobs-repository.js +48 -0
- package/dist/db/reflections-repository.d.ts +41 -0
- package/dist/db/reflections-repository.js +83 -0
- package/dist/db/repository-claims.d.ts +141 -0
- package/dist/db/repository-claims.js +376 -0
- package/dist/db/repository-deferred-audn.d.ts +33 -0
- package/dist/db/repository-deferred-audn.js +69 -0
- package/dist/db/repository-document-delete.d.ts +53 -0
- package/dist/db/repository-document-delete.js +156 -0
- package/dist/db/repository-entities.d.ts +114 -0
- package/dist/db/repository-entities.js +317 -0
- package/dist/db/repository-entity-attributes.d.ts +41 -0
- package/dist/db/repository-entity-attributes.js +65 -0
- package/dist/db/repository-entity-graph.d.ts +32 -0
- package/dist/db/repository-entity-graph.js +87 -0
- package/dist/db/repository-first-mentions.d.ts +41 -0
- package/dist/db/repository-first-mentions.js +79 -0
- package/dist/db/repository-lessons.d.ts +51 -0
- package/dist/db/repository-lessons.js +90 -0
- package/dist/db/repository-links.d.ts +26 -0
- package/dist/db/repository-links.js +105 -0
- package/dist/db/repository-observation.d.ts +26 -0
- package/dist/db/repository-observation.js +51 -0
- package/dist/db/repository-read.d.ts +56 -0
- package/dist/db/repository-read.js +271 -0
- package/dist/db/repository-recaps.d.ts +59 -0
- package/dist/db/repository-recaps.js +158 -0
- package/dist/db/repository-representations.d.ts +48 -0
- package/dist/db/repository-representations.js +162 -0
- package/dist/db/repository-temporal-state.d.ts +35 -0
- package/dist/db/repository-temporal-state.js +46 -0
- package/dist/db/repository-tll.d.ts +88 -0
- package/dist/db/repository-tll.js +179 -0
- package/dist/db/repository-types.d.ts +313 -0
- package/dist/db/repository-types.js +142 -0
- package/dist/db/repository-user-profiles.d.ts +17 -0
- package/dist/db/repository-user-profiles.js +28 -0
- package/dist/db/repository-vector-search.d.ts +33 -0
- package/dist/db/repository-vector-search.js +373 -0
- package/dist/db/repository-wipe.d.ts +34 -0
- package/dist/db/repository-wipe.js +94 -0
- package/dist/db/repository-write.d.ts +61 -0
- package/dist/db/repository-write.js +279 -0
- package/dist/db/schema.sql +1355 -0
- package/dist/db/storage-artifact-delete-tx.d.ts +56 -0
- package/dist/db/storage-artifact-delete-tx.js +123 -0
- package/dist/db/storage-artifact-providers.d.ts +21 -0
- package/dist/db/storage-artifact-providers.js +21 -0
- package/dist/db/storage-artifact-recovery-repository.d.ts +66 -0
- package/dist/db/storage-artifact-recovery-repository.js +58 -0
- package/dist/db/storage-artifact-repository.d.ts +329 -0
- package/dist/db/storage-artifact-repository.js +497 -0
- package/dist/db/stores.d.ts +220 -0
- package/dist/db/stores.js +12 -0
- package/dist/db/summaries-repository.d.ts +74 -0
- package/dist/db/summaries-repository.js +125 -0
- package/dist/eval/beam-10m-loader.d.ts +98 -0
- package/dist/eval/beam-10m-loader.js +128 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.js +17 -0
- package/dist/middleware/require-bearer.d.ts +27 -0
- package/dist/middleware/require-bearer.js +60 -0
- package/dist/middleware/validate-response.d.ts +33 -0
- package/dist/middleware/validate-response.js +55 -0
- package/dist/middleware/validate.d.ts +43 -0
- package/dist/middleware/validate.js +85 -0
- package/dist/routes/agents.d.ts +13 -0
- package/dist/routes/agents.js +89 -0
- package/dist/routes/document-response-formatters.d.ts +98 -0
- package/dist/routes/document-response-formatters.js +243 -0
- package/dist/routes/documents.d.ts +74 -0
- package/dist/routes/documents.js +425 -0
- package/dist/routes/memories.d.ts +29 -0
- package/dist/routes/memories.js +725 -0
- package/dist/routes/memory-response-formatters.d.ts +179 -0
- package/dist/routes/memory-response-formatters.js +210 -0
- package/dist/routes/public-raw-storage-metadata.d.ts +54 -0
- package/dist/routes/public-raw-storage-metadata.js +56 -0
- package/dist/routes/reflect.d.ts +14 -0
- package/dist/routes/reflect.js +19 -0
- package/dist/routes/response-schema-map.d.ts +14 -0
- package/dist/routes/response-schema-map.js +69 -0
- package/dist/routes/route-errors.d.ts +12 -0
- package/dist/routes/route-errors.js +30 -0
- package/dist/routes/storage-error-handlers.d.ts +34 -0
- package/dist/routes/storage-error-handlers.js +185 -0
- package/dist/routes/storage-response-formatters.d.ts +44 -0
- package/dist/routes/storage-response-formatters.js +155 -0
- package/dist/routes/storage.d.ts +38 -0
- package/dist/routes/storage.js +369 -0
- package/dist/routes/upstream-provider-errors.d.ts +19 -0
- package/dist/routes/upstream-provider-errors.js +95 -0
- package/dist/schemas/agents.d.ts +79 -0
- package/dist/schemas/agents.js +126 -0
- package/dist/schemas/common.d.ts +110 -0
- package/dist/schemas/common.js +190 -0
- package/dist/schemas/document-list-responses.d.ts +102 -0
- package/dist/schemas/document-list-responses.js +87 -0
- package/dist/schemas/document-list-schemas.d.ts +123 -0
- package/dist/schemas/document-list-schemas.js +174 -0
- package/dist/schemas/document-response-schemas.d.ts +610 -0
- package/dist/schemas/document-response-schemas.js +264 -0
- package/dist/schemas/document-status-envelope.d.ts +48 -0
- package/dist/schemas/document-status-envelope.js +54 -0
- package/dist/schemas/documents.d.ts +292 -0
- package/dist/schemas/documents.js +449 -0
- package/dist/schemas/errors.d.ts +75 -0
- package/dist/schemas/errors.js +105 -0
- package/dist/schemas/memories.d.ts +378 -0
- package/dist/schemas/memories.js +542 -0
- package/dist/schemas/openapi.d.ts +24 -0
- package/dist/schemas/openapi.js +1038 -0
- package/dist/schemas/response-scalars.d.ts +10 -0
- package/dist/schemas/response-scalars.js +10 -0
- package/dist/schemas/responses.d.ts +536 -0
- package/dist/schemas/responses.js +350 -0
- package/dist/schemas/search-response-parts.d.ts +97 -0
- package/dist/schemas/search-response-parts.js +103 -0
- package/dist/schemas/storage-schemas.d.ts +175 -0
- package/dist/schemas/storage-schemas.js +277 -0
- package/dist/schemas/zod-setup.d.ts +15 -0
- package/dist/schemas/zod-setup.js +17 -0
- package/dist/server.d.ts +13 -0
- package/dist/server.js +57 -0
- package/dist/services/abstract-query-policy.d.ts +13 -0
- package/dist/services/abstract-query-policy.js +50 -0
- package/dist/services/affinity-clustering.d.ts +66 -0
- package/dist/services/affinity-clustering.js +125 -0
- package/dist/services/agentic-retrieval.d.ts +38 -0
- package/dist/services/agentic-retrieval.js +126 -0
- package/dist/services/answer-format.d.ts +56 -0
- package/dist/services/answer-format.js +118 -0
- package/dist/services/answer-rescue.d.ts +72 -0
- package/dist/services/answer-rescue.js +177 -0
- package/dist/services/answer-verifier.d.ts +24 -0
- package/dist/services/answer-verifier.js +73 -0
- package/dist/services/api-retry.d.ts +6 -0
- package/dist/services/api-retry.js +41 -0
- package/dist/services/assistant-turn-filter.d.ts +20 -0
- package/dist/services/assistant-turn-filter.js +69 -0
- package/dist/services/atomicmem-uri.d.ts +33 -0
- package/dist/services/atomicmem-uri.js +86 -0
- package/dist/services/audit-events.d.ts +54 -0
- package/dist/services/audit-events.js +56 -0
- package/dist/services/chunked-extraction.d.ts +21 -0
- package/dist/services/chunked-extraction.js +108 -0
- package/dist/services/claim-slotting.d.ts +27 -0
- package/dist/services/claim-slotting.js +38 -0
- package/dist/services/claude-code-llm.d.ts +19 -0
- package/dist/services/claude-code-llm.js +96 -0
- package/dist/services/composite-dedup.d.ts +50 -0
- package/dist/services/composite-dedup.js +153 -0
- package/dist/services/composite-grouping.d.ts +41 -0
- package/dist/services/composite-grouping.js +111 -0
- package/dist/services/composite-staleness.d.ts +20 -0
- package/dist/services/composite-staleness.js +50 -0
- package/dist/services/conciseness-preference.d.ts +14 -0
- package/dist/services/conciseness-preference.js +42 -0
- package/dist/services/conflict-policy.d.ts +20 -0
- package/dist/services/conflict-policy.js +335 -0
- package/dist/services/consensus-extraction.d.ts +39 -0
- package/dist/services/consensus-extraction.js +147 -0
- package/dist/services/consensus-validation.d.ts +52 -0
- package/dist/services/consensus-validation.js +206 -0
- package/dist/services/consolidation-service.d.ts +60 -0
- package/dist/services/consolidation-service.js +171 -0
- package/dist/services/content-detection.d.ts +18 -0
- package/dist/services/content-detection.js +25 -0
- package/dist/services/contradiction-surfacing.d.ts +62 -0
- package/dist/services/contradiction-surfacing.js +111 -0
- package/dist/services/cost-telemetry.d.ts +39 -0
- package/dist/services/cost-telemetry.js +58 -0
- package/dist/services/counter-evidence.d.ts +34 -0
- package/dist/services/counter-evidence.js +92 -0
- package/dist/services/current-state-ranking.d.ts +21 -0
- package/dist/services/current-state-ranking.js +152 -0
- package/dist/services/deferred-audn.d.ts +47 -0
- package/dist/services/deferred-audn.js +162 -0
- package/dist/services/document-chunker.d.ts +50 -0
- package/dist/services/document-chunker.js +153 -0
- package/dist/services/document-failure-markers.d.ts +91 -0
- package/dist/services/document-failure-markers.js +305 -0
- package/dist/services/document-indexer.d.ts +122 -0
- package/dist/services/document-indexer.js +405 -0
- package/dist/services/document-service.d.ts +245 -0
- package/dist/services/document-service.js +325 -0
- package/dist/services/document-upload-artifact-sync.d.ts +80 -0
- package/dist/services/document-upload-artifact-sync.js +162 -0
- package/dist/services/document-upload-beta2-recovery.d.ts +72 -0
- package/dist/services/document-upload-beta2-recovery.js +94 -0
- package/dist/services/document-upload.d.ts +44 -0
- package/dist/services/document-upload.js +353 -0
- package/dist/services/embedding.d.ts +57 -0
- package/dist/services/embedding.js +416 -0
- package/dist/services/entity-attribute-extractor.d.ts +34 -0
- package/dist/services/entity-attribute-extractor.js +117 -0
- package/dist/services/entity-card-synthesis.d.ts +54 -0
- package/dist/services/entity-card-synthesis.js +92 -0
- package/dist/services/entity-dedup.d.ts +9 -0
- package/dist/services/entity-dedup.js +14 -0
- package/dist/services/entity-graph.d.ts +17 -0
- package/dist/services/entity-graph.js +135 -0
- package/dist/services/entropy-gate.d.ts +52 -0
- package/dist/services/entropy-gate.js +56 -0
- package/dist/services/episode-fetcher.d.ts +47 -0
- package/dist/services/episode-fetcher.js +128 -0
- package/dist/services/event-anchor-facts.d.ts +8 -0
- package/dist/services/event-anchor-facts.js +205 -0
- package/dist/services/event-chain-detector.d.ts +52 -0
- package/dist/services/event-chain-detector.js +83 -0
- package/dist/services/extraction-cache.d.ts +9 -0
- package/dist/services/extraction-cache.js +54 -0
- package/dist/services/extraction-enrichment.d.ts +9 -0
- package/dist/services/extraction-enrichment.js +223 -0
- package/dist/services/extraction.d.ts +69 -0
- package/dist/services/extraction.js +596 -0
- package/dist/services/fact-normalization.d.ts +12 -0
- package/dist/services/fact-normalization.js +248 -0
- package/dist/services/filecoin-observability.d.ts +127 -0
- package/dist/services/filecoin-observability.js +200 -0
- package/dist/services/first-mention-service.d.ts +76 -0
- package/dist/services/first-mention-service.js +186 -0
- package/dist/services/hierarchical-retrieval.d.ts +49 -0
- package/dist/services/hierarchical-retrieval.js +50 -0
- package/dist/services/ingest-fact-pipeline.d.ts +32 -0
- package/dist/services/ingest-fact-pipeline.js +212 -0
- package/dist/services/ingest-post-write.d.ts +50 -0
- package/dist/services/ingest-post-write.js +117 -0
- package/dist/services/ingest-trace.d.ts +32 -0
- package/dist/services/ingest-trace.js +60 -0
- package/dist/services/input-sanitizer.d.ts +41 -0
- package/dist/services/input-sanitizer.js +135 -0
- package/dist/services/iterative-retrieval.d.ts +26 -0
- package/dist/services/iterative-retrieval.js +139 -0
- package/dist/services/keyword-expansion.d.ts +10 -0
- package/dist/services/keyword-expansion.js +26 -0
- package/dist/services/lesson-service.d.ts +68 -0
- package/dist/services/lesson-service.js +178 -0
- package/dist/services/literal-extractor.d.ts +16 -0
- package/dist/services/literal-extractor.js +74 -0
- package/dist/services/literal-list-protection.d.ts +17 -0
- package/dist/services/literal-list-protection.js +134 -0
- package/dist/services/literal-query-expansion.d.ts +20 -0
- package/dist/services/literal-query-expansion.js +181 -0
- package/dist/services/llm.d.ts +61 -0
- package/dist/services/llm.js +265 -0
- package/dist/services/memcell-projection.d.ts +17 -0
- package/dist/services/memcell-projection.js +41 -0
- package/dist/services/memory-audn.d.ts +43 -0
- package/dist/services/memory-audn.js +419 -0
- package/dist/services/memory-crud.d.ts +93 -0
- package/dist/services/memory-crud.js +255 -0
- package/dist/services/memory-ingest.d.ts +21 -0
- package/dist/services/memory-ingest.js +249 -0
- package/dist/services/memory-lifecycle.d.ts +75 -0
- package/dist/services/memory-lifecycle.js +108 -0
- package/dist/services/memory-lineage.d.ts +181 -0
- package/dist/services/memory-lineage.js +232 -0
- package/dist/services/memory-network.d.ts +40 -0
- package/dist/services/memory-network.js +75 -0
- package/dist/services/memory-search-types.d.ts +25 -0
- package/dist/services/memory-search-types.js +10 -0
- package/dist/services/memory-search.d.ts +48 -0
- package/dist/services/memory-search.js +505 -0
- package/dist/services/memory-service-types.d.ts +371 -0
- package/dist/services/memory-service-types.js +8 -0
- package/dist/services/memory-service.d.ts +152 -0
- package/dist/services/memory-service.js +225 -0
- package/dist/services/memory-storage.d.ts +33 -0
- package/dist/services/memory-storage.js +328 -0
- package/dist/services/msr-aggregator.d.ts +38 -0
- package/dist/services/msr-aggregator.js +97 -0
- package/dist/services/msr-detector.d.ts +35 -0
- package/dist/services/msr-detector.js +65 -0
- package/dist/services/namespace-retrieval.d.ts +60 -0
- package/dist/services/namespace-retrieval.js +180 -0
- package/dist/services/observation-date-extraction.d.ts +12 -0
- package/dist/services/observation-date-extraction.js +50 -0
- package/dist/services/observation-service.d.ts +27 -0
- package/dist/services/observation-service.js +84 -0
- package/dist/services/packaging-observability.d.ts +29 -0
- package/dist/services/packaging-observability.js +146 -0
- package/dist/services/query-expansion.d.ts +83 -0
- package/dist/services/query-expansion.js +242 -0
- package/dist/services/query-keyword-matches.d.ts +6 -0
- package/dist/services/query-keyword-matches.js +56 -0
- package/dist/services/query-term-visibility.d.ts +28 -0
- package/dist/services/query-term-visibility.js +100 -0
- package/dist/services/quick-extraction.d.ts +25 -0
- package/dist/services/quick-extraction.js +431 -0
- package/dist/services/quoted-entity-extraction.d.ts +10 -0
- package/dist/services/quoted-entity-extraction.js +161 -0
- package/dist/services/raw-storage-reconciler-backoff.d.ts +8 -0
- package/dist/services/raw-storage-reconciler-backoff.js +14 -0
- package/dist/services/raw-storage-reconciler-scheduler.d.ts +29 -0
- package/dist/services/raw-storage-reconciler-scheduler.js +43 -0
- package/dist/services/raw-storage-reconciler.d.ts +71 -0
- package/dist/services/raw-storage-reconciler.js +278 -0
- package/dist/services/recap-builder.d.ts +49 -0
- package/dist/services/recap-builder.js +157 -0
- package/dist/services/reflect-jobs.d.ts +23 -0
- package/dist/services/reflect-jobs.js +36 -0
- package/dist/services/reflect-prompts.d.ts +71 -0
- package/dist/services/reflect-prompts.js +99 -0
- package/dist/services/reflect-retrieval.d.ts +33 -0
- package/dist/services/reflect-retrieval.js +30 -0
- package/dist/services/reflect.d.ts +49 -0
- package/dist/services/reflect.js +84 -0
- package/dist/services/relative-temporal.d.ts +14 -0
- package/dist/services/relative-temporal.js +163 -0
- package/dist/services/relevance-policy.d.ts +37 -0
- package/dist/services/relevance-policy.js +109 -0
- package/dist/services/rerank.d.ts +32 -0
- package/dist/services/rerank.js +118 -0
- package/dist/services/reranker.d.ts +20 -0
- package/dist/services/reranker.js +99 -0
- package/dist/services/retrieval-channel-rules.d.ts +34 -0
- package/dist/services/retrieval-channel-rules.js +41 -0
- package/dist/services/retrieval-config-overlay.d.ts +36 -0
- package/dist/services/retrieval-config-overlay.js +44 -0
- package/dist/services/retrieval-format.d.ts +119 -0
- package/dist/services/retrieval-format.js +559 -0
- package/dist/services/retrieval-policy.d.ts +69 -0
- package/dist/services/retrieval-policy.js +275 -0
- package/dist/services/retrieval-profiles.d.ts +37 -0
- package/dist/services/retrieval-profiles.js +90 -0
- package/dist/services/retrieval-side-effects.d.ts +14 -0
- package/dist/services/retrieval-side-effects.js +26 -0
- package/dist/services/retrieval-trace.d.ts +108 -0
- package/dist/services/retrieval-trace.js +147 -0
- package/dist/services/rrf-fusion.d.ts +18 -0
- package/dist/services/rrf-fusion.js +34 -0
- package/dist/services/search-pipeline.d.ts +71 -0
- package/dist/services/search-pipeline.js +788 -0
- package/dist/services/session-date.d.ts +20 -0
- package/dist/services/session-date.js +61 -0
- package/dist/services/session-packaging.d.ts +53 -0
- package/dist/services/session-packaging.js +182 -0
- package/dist/services/session-summary-generator.d.ts +53 -0
- package/dist/services/session-summary-generator.js +134 -0
- package/dist/services/specialists/cr-specialist.d.ts +52 -0
- package/dist/services/specialists/cr-specialist.js +121 -0
- package/dist/services/specialists/dispatch.d.ts +53 -0
- package/dist/services/specialists/dispatch.js +102 -0
- package/dist/services/specialists/ie-ku-specialist.d.ts +37 -0
- package/dist/services/specialists/ie-ku-specialist.js +63 -0
- package/dist/services/specialists/msr-specialist.d.ts +61 -0
- package/dist/services/specialists/msr-specialist.js +162 -0
- package/dist/services/specialists/tr-specialist.d.ts +37 -0
- package/dist/services/specialists/tr-specialist.js +146 -0
- package/dist/services/storage-key-prefix.d.ts +42 -0
- package/dist/services/storage-key-prefix.js +45 -0
- package/dist/services/storage-put-recovery.d.ts +71 -0
- package/dist/services/storage-put-recovery.js +269 -0
- package/dist/services/storage-service-errors.d.ts +124 -0
- package/dist/services/storage-service-errors.js +189 -0
- package/dist/services/storage-service.d.ts +176 -0
- package/dist/services/storage-service.js +423 -0
- package/dist/services/subject-aware-ranking.d.ts +19 -0
- package/dist/services/subject-aware-ranking.js +161 -0
- package/dist/services/supplemental-extraction.d.ts +7 -0
- package/dist/services/supplemental-extraction.js +116 -0
- package/dist/services/tbc-execution.d.ts +49 -0
- package/dist/services/tbc-execution.js +284 -0
- package/dist/services/temporal-classifier.d.ts +56 -0
- package/dist/services/temporal-classifier.js +94 -0
- package/dist/services/temporal-endpoint-evidence.d.ts +12 -0
- package/dist/services/temporal-endpoint-evidence.js +313 -0
- package/dist/services/temporal-fingerprint.d.ts +6 -0
- package/dist/services/temporal-fingerprint.js +12 -0
- package/dist/services/temporal-format.d.ts +9 -0
- package/dist/services/temporal-format.js +21 -0
- package/dist/services/temporal-intent.d.ts +39 -0
- package/dist/services/temporal-intent.js +78 -0
- package/dist/services/temporal-query-constraints.d.ts +16 -0
- package/dist/services/temporal-query-constraints.js +107 -0
- package/dist/services/temporal-query-expansion.d.ts +14 -0
- package/dist/services/temporal-query-expansion.js +131 -0
- package/dist/services/temporal-rerank.d.ts +22 -0
- package/dist/services/temporal-rerank.js +47 -0
- package/dist/services/temporal-result-protection.d.ts +7 -0
- package/dist/services/temporal-result-protection.js +60 -0
- package/dist/services/temporal-state-write.d.ts +57 -0
- package/dist/services/temporal-state-write.js +45 -0
- package/dist/services/tiered-context.d.ts +87 -0
- package/dist/services/tiered-context.js +214 -0
- package/dist/services/tiered-loading.d.ts +88 -0
- package/dist/services/tiered-loading.js +263 -0
- package/dist/services/timeline-pack.d.ts +36 -0
- package/dist/services/timeline-pack.js +50 -0
- package/dist/services/timing.d.ts +13 -0
- package/dist/services/timing.js +72 -0
- package/dist/services/tll-augmentation.d.ts +20 -0
- package/dist/services/tll-augmentation.js +125 -0
- package/dist/services/tll-retrieval.d.ts +55 -0
- package/dist/services/tll-retrieval.js +101 -0
- package/dist/services/topic-abstraction.d.ts +36 -0
- package/dist/services/topic-abstraction.js +105 -0
- package/dist/services/trust-scoring.d.ts +43 -0
- package/dist/services/trust-scoring.js +89 -0
- package/dist/services/typed-belief-calculus.d.ts +126 -0
- package/dist/services/typed-belief-calculus.js +204 -0
- package/dist/services/upload-config.d.ts +34 -0
- package/dist/services/upload-config.js +23 -0
- package/dist/services/upload-decision.d.ts +65 -0
- package/dist/services/upload-decision.js +98 -0
- package/dist/services/upload-helpers.d.ts +107 -0
- package/dist/services/upload-helpers.js +148 -0
- package/dist/services/user-profile-builder.d.ts +22 -0
- package/dist/services/user-profile-builder.js +109 -0
- package/dist/services/voyage-embedding.d.ts +22 -0
- package/dist/services/voyage-embedding.js +77 -0
- package/dist/services/write-security.d.ts +31 -0
- package/dist/services/write-security.js +64 -0
- package/dist/storage/artifact-public-redaction.d.ts +34 -0
- package/dist/storage/artifact-public-redaction.js +83 -0
- package/dist/storage/cleanup.d.ts +103 -0
- package/dist/storage/cleanup.js +138 -0
- package/dist/storage/codec-factory.d.ts +17 -0
- package/dist/storage/codec-factory.js +33 -0
- package/dist/storage/codecs/aes-gcm-codec.d.ts +44 -0
- package/dist/storage/codecs/aes-gcm-codec.js +108 -0
- package/dist/storage/codecs/noop-codec.d.ts +16 -0
- package/dist/storage/codecs/noop-codec.js +23 -0
- package/dist/storage/factory.d.ts +44 -0
- package/dist/storage/factory.js +99 -0
- package/dist/storage/filecoin-cid-validation.d.ts +82 -0
- package/dist/storage/filecoin-cid-validation.js +122 -0
- package/dist/storage/filecoin-public-metadata.d.ts +73 -0
- package/dist/storage/filecoin-public-metadata.js +110 -0
- package/dist/storage/local-fs-store.d.ts +39 -0
- package/dist/storage/local-fs-store.js +145 -0
- package/dist/storage/pointer-uri-allowlist.d.ts +38 -0
- package/dist/storage/pointer-uri-allowlist.js +70 -0
- package/dist/storage/provider-metadata-projection.d.ts +27 -0
- package/dist/storage/provider-metadata-projection.js +68 -0
- package/dist/storage/providers/filecoin/backend.d.ts +42 -0
- package/dist/storage/providers/filecoin/backend.js +250 -0
- package/dist/storage/providers/filecoin/config.d.ts +70 -0
- package/dist/storage/providers/filecoin/config.js +275 -0
- package/dist/storage/providers/filecoin/errors.d.ts +45 -0
- package/dist/storage/providers/filecoin/errors.js +56 -0
- package/dist/storage/providers/filecoin/filecoin-pin-car.d.ts +78 -0
- package/dist/storage/providers/filecoin/filecoin-pin-car.js +155 -0
- package/dist/storage/providers/filecoin/filecoin-pin-client.d.ts +92 -0
- package/dist/storage/providers/filecoin/filecoin-pin-client.js +199 -0
- package/dist/storage/providers/filecoin/filecoin-pin-mapping.d.ts +58 -0
- package/dist/storage/providers/filecoin/filecoin-pin-mapping.js +103 -0
- package/dist/storage/providers/filecoin/filecoin-pin-timeout.d.ts +30 -0
- package/dist/storage/providers/filecoin/filecoin-pin-timeout.js +53 -0
- package/dist/storage/providers/filecoin/filecoin-pin-vendor.d.ts +111 -0
- package/dist/storage/providers/filecoin/filecoin-pin-vendor.js +87 -0
- package/dist/storage/providers/filecoin/hints.d.ts +71 -0
- package/dist/storage/providers/filecoin/hints.js +123 -0
- package/dist/storage/providers/filecoin/index.d.ts +51 -0
- package/dist/storage/providers/filecoin/index.js +103 -0
- package/dist/storage/providers/filecoin/ipfs-cid.d.ts +50 -0
- package/dist/storage/providers/filecoin/ipfs-cid.js +64 -0
- package/dist/storage/providers/filecoin/metadata.d.ts +72 -0
- package/dist/storage/providers/filecoin/metadata.js +137 -0
- package/dist/storage/providers/filecoin/piece-cid.d.ts +48 -0
- package/dist/storage/providers/filecoin/piece-cid.js +57 -0
- package/dist/storage/providers/filecoin/provider-client.d.ts +234 -0
- package/dist/storage/providers/filecoin/provider-client.js +27 -0
- package/dist/storage/providers/filecoin/readiness.d.ts +62 -0
- package/dist/storage/providers/filecoin/readiness.js +85 -0
- package/dist/storage/providers/filecoin/retriever.d.ts +82 -0
- package/dist/storage/providers/filecoin/retriever.js +63 -0
- package/dist/storage/providers/filecoin/skeleton-client.d.ts +36 -0
- package/dist/storage/providers/filecoin/skeleton-client.js +55 -0
- package/dist/storage/providers/filecoin/synapse-client.d.ts +169 -0
- package/dist/storage/providers/filecoin/synapse-client.js +343 -0
- package/dist/storage/providers/filecoin/synapse-construction.d.ts +26 -0
- package/dist/storage/providers/filecoin/synapse-construction.js +47 -0
- package/dist/storage/providers/filecoin/synapse-error-mapping.d.ts +23 -0
- package/dist/storage/providers/filecoin/synapse-error-mapping.js +49 -0
- package/dist/storage/providers/filecoin/synapse-readiness.d.ts +37 -0
- package/dist/storage/providers/filecoin/synapse-readiness.js +231 -0
- package/dist/storage/providers/filecoin/uri.d.ts +49 -0
- package/dist/storage/providers/filecoin/uri.js +84 -0
- package/dist/storage/providers/filecoin/verified-fetch-lifecycle.d.ts +77 -0
- package/dist/storage/providers/filecoin/verified-fetch-lifecycle.js +196 -0
- package/dist/storage/providers/filecoin/verified-fetch-retriever.d.ts +54 -0
- package/dist/storage/providers/filecoin/verified-fetch-retriever.js +81 -0
- package/dist/storage/providers/filecoin/verified-fetch-vendor.d.ts +71 -0
- package/dist/storage/providers/filecoin/verified-fetch-vendor.js +94 -0
- package/dist/storage/raw-content-codec.d.ts +89 -0
- package/dist/storage/raw-content-codec.js +47 -0
- package/dist/storage/raw-content-store-backend-adapter.d.ts +28 -0
- package/dist/storage/raw-content-store-backend-adapter.js +67 -0
- package/dist/storage/raw-content-store.d.ts +228 -0
- package/dist/storage/raw-content-store.js +27 -0
- package/dist/storage/s3-store.d.ts +42 -0
- package/dist/storage/s3-store.js +181 -0
- package/dist/storage/storage-backend-registry.d.ts +58 -0
- package/dist/storage/storage-backend-registry.js +56 -0
- package/dist/storage/storage-backend.d.ts +82 -0
- package/dist/storage/storage-backend.js +14 -0
- package/dist/storage/storage-capabilities.d.ts +56 -0
- package/dist/storage/storage-capabilities.js +170 -0
- package/dist/storage/store-registry.d.ts +67 -0
- package/dist/storage/store-registry.js +77 -0
- package/dist/vector-math.d.ts +15 -0
- package/dist/vector-math.js +31 -0
- package/dist/xml-escape.d.ts +5 -0
- package/dist/xml-escape.js +7 -0
- package/openapi.json +15395 -0
- package/openapi.yaml +10794 -0
- package/package.json +119 -0
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Managed-blob cleanup helper (raw-content + per-row provider dispatch).
|
|
3
|
+
*
|
|
4
|
+
* Every code path that soft- or hard-deletes a `raw_documents` row
|
|
5
|
+
* backed by `storage_mode='managed_blob'` runs the collected
|
|
6
|
+
* `(storage_provider, storage_uri)` tuples through this helper *after*
|
|
7
|
+
* the DB transaction commits.
|
|
8
|
+
*
|
|
9
|
+
* per-row provider dispatch changes: cleanup dispatches per `blob.storageProvider` via
|
|
10
|
+
* a `RawContentStoreRegistry`, not via a single active store. A row
|
|
11
|
+
* created when the deployment was on `local_fs` and still pending
|
|
12
|
+
* cleanup after the deployment switched to `filecoin` is handled by
|
|
13
|
+
* the registered legacy adapter (`RAW_STORAGE_LEGACY_PROVIDERS`).
|
|
14
|
+
* Providers that aren't registered surface as failures with an
|
|
15
|
+
* explicit error message — never silent no-ops.
|
|
16
|
+
*
|
|
17
|
+
* Result shape: `successes` carries one entry per non-failure outcome
|
|
18
|
+
* (including `deleted: false` already-missing) so callers can write the
|
|
19
|
+
* correct terminal marker (`blob_deleted` vs `blob_tombstoned`) based
|
|
20
|
+
* on the adapter's `semantics` field. The legacy `deleted` /
|
|
21
|
+
* `alreadyMissing` counters are kept for backwards-compatible metrics.
|
|
22
|
+
*
|
|
23
|
+
* Failure model: per-blob delete is attempted independently. The
|
|
24
|
+
* adapter's `delete()` already treats "missing" as a NON-ERROR
|
|
25
|
+
* outcome with `deleted: false`. Adapter errors (network, auth,
|
|
26
|
+
* permission, missing provider) are NEVER swallowed — they're
|
|
27
|
+
* collected on `failures` and the caller MUST surface a 500 to the
|
|
28
|
+
* client (see `ManagedBlobCleanupError`). No degraded mode.
|
|
29
|
+
*
|
|
30
|
+
* Hint plumbing: `ManagedBlobRef.rawStorageMetadata` carries the
|
|
31
|
+
* row's `raw_documents.raw_storage_metadata` JSONB so the cleanup
|
|
32
|
+
* loop can hand it to `RawContentStore.delete(uri, hints)` as an
|
|
33
|
+
* opaque `RawContentHints` object. The Filecoin adapter narrows
|
|
34
|
+
* this to `filecoin.data_set_id` + `filecoin.copies[].piece_id`
|
|
35
|
+
* and issues a hinted `deletePiece({ piece: BigInt(pieceId) })`
|
|
36
|
+
* against the resolved context — which bypasses the SDK's
|
|
37
|
+
* CID→active-piece lookup and lets a freshly-uploaded piece
|
|
38
|
+
* (still pre-PDP-proof) be deleted directly. Non-Filecoin
|
|
39
|
+
* adapters (local_fs, s3) ignore the `hints` argument.
|
|
40
|
+
*/
|
|
41
|
+
import type { RawContentDeleteResult } from './raw-content-store.js';
|
|
42
|
+
import type { RawContentStoreRegistry } from './store-registry.js';
|
|
43
|
+
export interface ManagedBlobRef {
|
|
44
|
+
/** Source-row id — required so the cleanup loop can sync the
|
|
45
|
+
* paired `storage_artifacts` row by id (URIs are not globally
|
|
46
|
+
* unique across documents). */
|
|
47
|
+
rawDocumentId: string;
|
|
48
|
+
storageProvider: string;
|
|
49
|
+
storageUri: string;
|
|
50
|
+
/** `raw_documents.raw_storage_metadata` JSONB (defaulted to `{}`
|
|
51
|
+
* by the repository mapper for legacy rows). Threaded through
|
|
52
|
+
* to `RawContentStore.delete` as opaque `RawContentHints` —
|
|
53
|
+
* each adapter narrows its own provider sibling. Required:
|
|
54
|
+
* production repository rows always populate it (the
|
|
55
|
+
* `toManagedBlobRef` mapper coerces missing/non-object JSONB
|
|
56
|
+
* to `{}`), and direct test callers pass `{}` explicitly. */
|
|
57
|
+
rawStorageMetadata: Record<string, unknown>;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Result entries DO NOT extend `ManagedBlobRef`. `rawStorageMetadata`
|
|
61
|
+
* is INPUT-ONLY hint material (Filecoin sidecar fields like
|
|
62
|
+
* `data_set_id` / `copies[].piece_id`) and must never appear on
|
|
63
|
+
* a result record or in `ManagedBlobCleanupError.result` — those
|
|
64
|
+
* surface to route handlers / 500 envelopes / observability and
|
|
65
|
+
* the hint sidecar isn't on the public allowlist. The cleanup
|
|
66
|
+
* loop hands the metadata to `RawContentStore.delete` and then
|
|
67
|
+
* drops it before constructing the entry below.
|
|
68
|
+
*/
|
|
69
|
+
export interface ManagedBlobCleanupSuccess {
|
|
70
|
+
rawDocumentId: string;
|
|
71
|
+
storageProvider: string;
|
|
72
|
+
storageUri: string;
|
|
73
|
+
/** True when the adapter actively removed bytes; false for already-missing. */
|
|
74
|
+
deleted: boolean;
|
|
75
|
+
/** What the adapter's delete did — drives terminal marker selection. */
|
|
76
|
+
semantics: RawContentDeleteResult['semantics'];
|
|
77
|
+
}
|
|
78
|
+
export interface ManagedBlobFailure {
|
|
79
|
+
rawDocumentId: string;
|
|
80
|
+
storageProvider: string;
|
|
81
|
+
storageUri: string;
|
|
82
|
+
message: string;
|
|
83
|
+
}
|
|
84
|
+
export interface ManagedBlobCleanupResult {
|
|
85
|
+
attempted: number;
|
|
86
|
+
/** Count metric — number of `successes` with `deleted=true`. */
|
|
87
|
+
deleted: number;
|
|
88
|
+
/** Count metric — number of `successes` with `deleted=false`. */
|
|
89
|
+
alreadyMissing: number;
|
|
90
|
+
/** One entry per non-failure outcome; iteration drives marker writes. */
|
|
91
|
+
successes: ManagedBlobCleanupSuccess[];
|
|
92
|
+
failures: ManagedBlobFailure[];
|
|
93
|
+
}
|
|
94
|
+
export declare function cleanupManagedBlobs(registry: RawContentStoreRegistry, blobs: ManagedBlobRef[]): Promise<ManagedBlobCleanupResult>;
|
|
95
|
+
/**
|
|
96
|
+
* Thrown by callers when one or more blob deletes raised. Wraps the
|
|
97
|
+
* cleanup result so the route layer can surface a 500 with the failed
|
|
98
|
+
* URIs instead of silently corrupting the cleanup contract.
|
|
99
|
+
*/
|
|
100
|
+
export declare class ManagedBlobCleanupError extends Error {
|
|
101
|
+
readonly result: ManagedBlobCleanupResult;
|
|
102
|
+
constructor(result: ManagedBlobCleanupResult);
|
|
103
|
+
}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Managed-blob cleanup helper (raw-content + per-row provider dispatch).
|
|
3
|
+
*
|
|
4
|
+
* Every code path that soft- or hard-deletes a `raw_documents` row
|
|
5
|
+
* backed by `storage_mode='managed_blob'` runs the collected
|
|
6
|
+
* `(storage_provider, storage_uri)` tuples through this helper *after*
|
|
7
|
+
* the DB transaction commits.
|
|
8
|
+
*
|
|
9
|
+
* per-row provider dispatch changes: cleanup dispatches per `blob.storageProvider` via
|
|
10
|
+
* a `RawContentStoreRegistry`, not via a single active store. A row
|
|
11
|
+
* created when the deployment was on `local_fs` and still pending
|
|
12
|
+
* cleanup after the deployment switched to `filecoin` is handled by
|
|
13
|
+
* the registered legacy adapter (`RAW_STORAGE_LEGACY_PROVIDERS`).
|
|
14
|
+
* Providers that aren't registered surface as failures with an
|
|
15
|
+
* explicit error message — never silent no-ops.
|
|
16
|
+
*
|
|
17
|
+
* Result shape: `successes` carries one entry per non-failure outcome
|
|
18
|
+
* (including `deleted: false` already-missing) so callers can write the
|
|
19
|
+
* correct terminal marker (`blob_deleted` vs `blob_tombstoned`) based
|
|
20
|
+
* on the adapter's `semantics` field. The legacy `deleted` /
|
|
21
|
+
* `alreadyMissing` counters are kept for backwards-compatible metrics.
|
|
22
|
+
*
|
|
23
|
+
* Failure model: per-blob delete is attempted independently. The
|
|
24
|
+
* adapter's `delete()` already treats "missing" as a NON-ERROR
|
|
25
|
+
* outcome with `deleted: false`. Adapter errors (network, auth,
|
|
26
|
+
* permission, missing provider) are NEVER swallowed — they're
|
|
27
|
+
* collected on `failures` and the caller MUST surface a 500 to the
|
|
28
|
+
* client (see `ManagedBlobCleanupError`). No degraded mode.
|
|
29
|
+
*
|
|
30
|
+
* Hint plumbing: `ManagedBlobRef.rawStorageMetadata` carries the
|
|
31
|
+
* row's `raw_documents.raw_storage_metadata` JSONB so the cleanup
|
|
32
|
+
* loop can hand it to `RawContentStore.delete(uri, hints)` as an
|
|
33
|
+
* opaque `RawContentHints` object. The Filecoin adapter narrows
|
|
34
|
+
* this to `filecoin.data_set_id` + `filecoin.copies[].piece_id`
|
|
35
|
+
* and issues a hinted `deletePiece({ piece: BigInt(pieceId) })`
|
|
36
|
+
* against the resolved context — which bypasses the SDK's
|
|
37
|
+
* CID→active-piece lookup and lets a freshly-uploaded piece
|
|
38
|
+
* (still pre-PDP-proof) be deleted directly. Non-Filecoin
|
|
39
|
+
* adapters (local_fs, s3) ignore the `hints` argument.
|
|
40
|
+
*/
|
|
41
|
+
import { emitFilecoinEvent } from '../services/filecoin-observability.js';
|
|
42
|
+
export async function cleanupManagedBlobs(registry, blobs) {
|
|
43
|
+
const result = {
|
|
44
|
+
attempted: blobs.length,
|
|
45
|
+
deleted: 0,
|
|
46
|
+
alreadyMissing: 0,
|
|
47
|
+
successes: [],
|
|
48
|
+
failures: [],
|
|
49
|
+
};
|
|
50
|
+
for (const blob of blobs) {
|
|
51
|
+
await processOneBlob(registry, blob, result);
|
|
52
|
+
}
|
|
53
|
+
return result;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Process a single blob through the registry-resolved adapter
|
|
57
|
+
* and append the outcome to `result`. Split out so the outer
|
|
58
|
+
* loop stays under the workspace complexity caps after the
|
|
59
|
+
* Phase 7 observability emit was added.
|
|
60
|
+
*
|
|
61
|
+
* Closed-key discipline: we NEVER spread `...blob` into a
|
|
62
|
+
* result entry — that would carry `rawStorageMetadata` (the
|
|
63
|
+
* Filecoin sidecar with `piece_id` / `data_set_id` / planted
|
|
64
|
+
* secrets) into the success/failure output, the
|
|
65
|
+
* `ManagedBlobCleanupError.result` payload, and downstream
|
|
66
|
+
* observability. Each entry is built from the three public
|
|
67
|
+
* fields (`rawDocumentId`, `storageProvider`, `storageUri`)
|
|
68
|
+
* plus the adapter's own scalars (`deleted`, `semantics`,
|
|
69
|
+
* `message`). The `RawContentDeleteResult.txHash` field, when
|
|
70
|
+
* present, is routed ONLY to the internal observability event
|
|
71
|
+
* — never to the success entry. Pinned by
|
|
72
|
+
* `cleanup-leak-invariants.test.ts`.
|
|
73
|
+
*/
|
|
74
|
+
async function processOneBlob(registry, blob, result) {
|
|
75
|
+
const publicRef = {
|
|
76
|
+
rawDocumentId: blob.rawDocumentId,
|
|
77
|
+
storageProvider: blob.storageProvider,
|
|
78
|
+
storageUri: blob.storageUri,
|
|
79
|
+
};
|
|
80
|
+
const store = registry.get(blob.storageProvider);
|
|
81
|
+
if (!store) {
|
|
82
|
+
result.failures.push({
|
|
83
|
+
...publicRef,
|
|
84
|
+
message: `managed_blob cleanup requested for provider '${blob.storageProvider}' but no ` +
|
|
85
|
+
'adapter is registered. Set RAW_STORAGE_LEGACY_PROVIDERS to include this provider, ' +
|
|
86
|
+
'or migrate the row before retiring its adapter.',
|
|
87
|
+
});
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
try {
|
|
91
|
+
const r = await store.delete(blob.storageUri, blob.rawStorageMetadata);
|
|
92
|
+
if (r.deleted)
|
|
93
|
+
result.deleted++;
|
|
94
|
+
else
|
|
95
|
+
result.alreadyMissing++;
|
|
96
|
+
emitDeleteTxHashIfAny(blob.storageProvider, r);
|
|
97
|
+
result.successes.push({ ...publicRef, deleted: r.deleted, semantics: r.semantics });
|
|
98
|
+
}
|
|
99
|
+
catch (err) {
|
|
100
|
+
result.failures.push({
|
|
101
|
+
...publicRef,
|
|
102
|
+
message: err instanceof Error ? err.message : String(err),
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Phase 7 billing/cost-impact metadata. If the Filecoin adapter
|
|
108
|
+
* returned an on-chain `txHash` (the Synapse SDK's `deletePiece`
|
|
109
|
+
* scheduled-removal tx), emit it on the internal
|
|
110
|
+
* `filecoin.delete.tombstoned` observability event for
|
|
111
|
+
* operator-side cost auditing. The hash NEVER reaches the
|
|
112
|
+
* cleanup-result DTO — it travels only on the closed
|
|
113
|
+
* `FilecoinEventPayload.deleteTxHash` channel.
|
|
114
|
+
*/
|
|
115
|
+
function emitDeleteTxHashIfAny(storageProvider, r) {
|
|
116
|
+
if (r.txHash === undefined || storageProvider !== 'filecoin')
|
|
117
|
+
return;
|
|
118
|
+
emitFilecoinEvent('filecoin.delete.tombstoned', {
|
|
119
|
+
provider: storageProvider,
|
|
120
|
+
deleteTxHash: r.txHash,
|
|
121
|
+
statusAfter: r.semantics === 'deleted' ? 'blob_deleted' : 'blob_tombstoned',
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Thrown by callers when one or more blob deletes raised. Wraps the
|
|
126
|
+
* cleanup result so the route layer can surface a 500 with the failed
|
|
127
|
+
* URIs instead of silently corrupting the cleanup contract.
|
|
128
|
+
*/
|
|
129
|
+
export class ManagedBlobCleanupError extends Error {
|
|
130
|
+
result;
|
|
131
|
+
constructor(result) {
|
|
132
|
+
const first = result.failures[0];
|
|
133
|
+
super(`managed_blob cleanup failed: ${result.failures.length} of ${result.attempted} ` +
|
|
134
|
+
`(first: ${first?.storageUri ?? '<unknown>'}: ${first?.message ?? '<no message>'})`);
|
|
135
|
+
this.result = result;
|
|
136
|
+
this.name = 'ManagedBlobCleanupError';
|
|
137
|
+
}
|
|
138
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Construct the `RawContentCodec` instance the upload service wraps
|
|
3
|
+
* around `RawContentStore.put()` / `get()` (Phase 5 wiring).
|
|
4
|
+
*
|
|
5
|
+
* The factory is composition-root code: validates the configured
|
|
6
|
+
* codec/keyring is consistent (config validation already enforced this
|
|
7
|
+
* at startup; this is defense-in-depth) and returns the codec
|
|
8
|
+
* implementation. Returns the noop codec for `RAW_CONTENT_CODEC='none'`
|
|
9
|
+
* — bytes pass through unchanged but a `{ name: 'none', version: 1 }`
|
|
10
|
+
* sidecar still lands in `raw_storage_metadata.codec` so the read
|
|
11
|
+
* path branches deterministically.
|
|
12
|
+
*/
|
|
13
|
+
import type { RuntimeConfig } from '../config.js';
|
|
14
|
+
import type { RawContentCodec } from './raw-content-codec.js';
|
|
15
|
+
type CodecConfig = Pick<RuntimeConfig, 'rawContentCodec' | 'rawContentCodecKeys' | 'rawContentCodecActiveKeyId'>;
|
|
16
|
+
export declare function buildRawContentCodec(cfg: CodecConfig): RawContentCodec;
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Construct the `RawContentCodec` instance the upload service wraps
|
|
3
|
+
* around `RawContentStore.put()` / `get()` (Phase 5 wiring).
|
|
4
|
+
*
|
|
5
|
+
* The factory is composition-root code: validates the configured
|
|
6
|
+
* codec/keyring is consistent (config validation already enforced this
|
|
7
|
+
* at startup; this is defense-in-depth) and returns the codec
|
|
8
|
+
* implementation. Returns the noop codec for `RAW_CONTENT_CODEC='none'`
|
|
9
|
+
* — bytes pass through unchanged but a `{ name: 'none', version: 1 }`
|
|
10
|
+
* sidecar still lands in `raw_storage_metadata.codec` so the read
|
|
11
|
+
* path branches deterministically.
|
|
12
|
+
*/
|
|
13
|
+
import { NoopRawContentCodec } from './codecs/noop-codec.js';
|
|
14
|
+
import { AesGcmRawContentCodec } from './codecs/aes-gcm-codec.js';
|
|
15
|
+
export function buildRawContentCodec(cfg) {
|
|
16
|
+
if (cfg.rawContentCodec === 'none') {
|
|
17
|
+
return new NoopRawContentCodec();
|
|
18
|
+
}
|
|
19
|
+
if (!cfg.rawContentCodecActiveKeyId) {
|
|
20
|
+
throw new Error("buildRawContentCodec: RAW_CONTENT_CODEC='aes_gcm' requires RAW_CONTENT_CODEC_ACTIVE_KEY_ID.");
|
|
21
|
+
}
|
|
22
|
+
const keys = Array.from(cfg.rawContentCodecKeys.entries()).map(([keyId, key]) => ({
|
|
23
|
+
keyId,
|
|
24
|
+
key,
|
|
25
|
+
}));
|
|
26
|
+
if (keys.length === 0) {
|
|
27
|
+
throw new Error("buildRawContentCodec: RAW_CONTENT_CODEC='aes_gcm' requires a non-empty RAW_CONTENT_CODEC_KEYS ring.");
|
|
28
|
+
}
|
|
29
|
+
return new AesGcmRawContentCodec({
|
|
30
|
+
keys,
|
|
31
|
+
activeKeyId: cfg.rawContentCodecActiveKeyId,
|
|
32
|
+
});
|
|
33
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AES-256-GCM content codec backed by a keyring. `encode` picks the
|
|
3
|
+
* caller-provided ACTIVE key and writes `{ name, version, key_id,
|
|
4
|
+
* nonce, tag, encoded_content_hash, encoded_size_bytes }` into the
|
|
5
|
+
* sidecar metadata. `decode` reads `key_id` from the metadata, looks up
|
|
6
|
+
* THAT key in the ring, and runs `createDecipheriv` — wrong key, wrong
|
|
7
|
+
* nonce, or tampered ciphertext all surface as
|
|
8
|
+
* `RawContentCodecError` via the GCM auth tag.
|
|
9
|
+
*
|
|
10
|
+
* Keys are 32 bytes (AES-256). Nonces are 12 random bytes per encode
|
|
11
|
+
* (the GCM IV — must be unique per (key, message) pair). Tags are 16
|
|
12
|
+
* bytes (the default GCM auth tag size).
|
|
13
|
+
*
|
|
14
|
+
* Encoding stores diagnostic context (`encoded_content_hash`,
|
|
15
|
+
* `encoded_size_bytes`) under the codec sidecar — these never reach
|
|
16
|
+
* the wire (rev-6 §6 redaction allowlist), they exist so ops can
|
|
17
|
+
* correlate the bytes the adapter saw with the row's plaintext
|
|
18
|
+
* `content_hash`.
|
|
19
|
+
*/
|
|
20
|
+
import type { RawContentCodec, RawContentCodecDecodeInput, RawContentCodecDecodeResult, RawContentCodecEncodeInput, RawContentCodecEncodeResult } from '../raw-content-codec.js';
|
|
21
|
+
/**
|
|
22
|
+
* Keyring entry: parsed 32-byte key paired with its operator-assigned
|
|
23
|
+
* id. The id is what ends up in `raw_storage_metadata.codec.key_id`
|
|
24
|
+
* so future decodes can find the right key even after rotation.
|
|
25
|
+
*/
|
|
26
|
+
export interface AesGcmKeyringEntry {
|
|
27
|
+
keyId: string;
|
|
28
|
+
key: Buffer;
|
|
29
|
+
}
|
|
30
|
+
/** Operator-provided keyring config consumed by the codec constructor. */
|
|
31
|
+
export interface AesGcmKeyringConfig {
|
|
32
|
+
/** Every key the codec can decode with. MUST contain `activeKeyId`. */
|
|
33
|
+
keys: ReadonlyArray<AesGcmKeyringEntry>;
|
|
34
|
+
/** Which key id to use for new `encode` calls. */
|
|
35
|
+
activeKeyId: string;
|
|
36
|
+
}
|
|
37
|
+
export declare class AesGcmRawContentCodec implements RawContentCodec {
|
|
38
|
+
readonly name: "aes_gcm";
|
|
39
|
+
private readonly ring;
|
|
40
|
+
private readonly activeKeyId;
|
|
41
|
+
constructor(config: AesGcmKeyringConfig);
|
|
42
|
+
encode(input: RawContentCodecEncodeInput): Promise<RawContentCodecEncodeResult>;
|
|
43
|
+
decode(input: RawContentCodecDecodeInput): Promise<RawContentCodecDecodeResult>;
|
|
44
|
+
}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AES-256-GCM content codec backed by a keyring. `encode` picks the
|
|
3
|
+
* caller-provided ACTIVE key and writes `{ name, version, key_id,
|
|
4
|
+
* nonce, tag, encoded_content_hash, encoded_size_bytes }` into the
|
|
5
|
+
* sidecar metadata. `decode` reads `key_id` from the metadata, looks up
|
|
6
|
+
* THAT key in the ring, and runs `createDecipheriv` — wrong key, wrong
|
|
7
|
+
* nonce, or tampered ciphertext all surface as
|
|
8
|
+
* `RawContentCodecError` via the GCM auth tag.
|
|
9
|
+
*
|
|
10
|
+
* Keys are 32 bytes (AES-256). Nonces are 12 random bytes per encode
|
|
11
|
+
* (the GCM IV — must be unique per (key, message) pair). Tags are 16
|
|
12
|
+
* bytes (the default GCM auth tag size).
|
|
13
|
+
*
|
|
14
|
+
* Encoding stores diagnostic context (`encoded_content_hash`,
|
|
15
|
+
* `encoded_size_bytes`) under the codec sidecar — these never reach
|
|
16
|
+
* the wire (rev-6 §6 redaction allowlist), they exist so ops can
|
|
17
|
+
* correlate the bytes the adapter saw with the row's plaintext
|
|
18
|
+
* `content_hash`.
|
|
19
|
+
*/
|
|
20
|
+
import { createCipheriv, createDecipheriv, createHash, randomBytes } from 'node:crypto';
|
|
21
|
+
import { RawContentCodecError, RawContentCodecKeyNotFoundError, } from '../raw-content-codec.js';
|
|
22
|
+
const AES_GCM_CODEC_VERSION = 1;
|
|
23
|
+
const AES_GCM_KEY_BYTES = 32;
|
|
24
|
+
const AES_GCM_NONCE_BYTES = 12;
|
|
25
|
+
const AES_GCM_TAG_BYTES = 16;
|
|
26
|
+
function assertKeyBytes(keyId, key) {
|
|
27
|
+
if (key.length !== AES_GCM_KEY_BYTES) {
|
|
28
|
+
throw new RawContentCodecError(`AES-256-GCM key '${keyId}' must be exactly ${AES_GCM_KEY_BYTES} bytes (got ${key.length}).`);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
export class AesGcmRawContentCodec {
|
|
32
|
+
name = 'aes_gcm';
|
|
33
|
+
ring;
|
|
34
|
+
activeKeyId;
|
|
35
|
+
constructor(config) {
|
|
36
|
+
if (config.keys.length === 0) {
|
|
37
|
+
throw new RawContentCodecError('AES-GCM codec requires at least one key in the ring.');
|
|
38
|
+
}
|
|
39
|
+
this.ring = new Map();
|
|
40
|
+
for (const entry of config.keys) {
|
|
41
|
+
assertKeyBytes(entry.keyId, entry.key);
|
|
42
|
+
if (this.ring.has(entry.keyId)) {
|
|
43
|
+
throw new RawContentCodecError(`Duplicate keyId '${entry.keyId}' in keyring.`);
|
|
44
|
+
}
|
|
45
|
+
this.ring.set(entry.keyId, entry.key);
|
|
46
|
+
}
|
|
47
|
+
if (!this.ring.has(config.activeKeyId)) {
|
|
48
|
+
throw new RawContentCodecError(`Active key id '${config.activeKeyId}' is not present in the keyring.`);
|
|
49
|
+
}
|
|
50
|
+
this.activeKeyId = config.activeKeyId;
|
|
51
|
+
}
|
|
52
|
+
async encode(input) {
|
|
53
|
+
const key = this.ring.get(this.activeKeyId);
|
|
54
|
+
if (!key) {
|
|
55
|
+
throw new RawContentCodecKeyNotFoundError(this.activeKeyId);
|
|
56
|
+
}
|
|
57
|
+
const nonce = randomBytes(AES_GCM_NONCE_BYTES);
|
|
58
|
+
const cipher = createCipheriv('aes-256-gcm', key, nonce);
|
|
59
|
+
const ciphertext = Buffer.concat([cipher.update(input.body), cipher.final()]);
|
|
60
|
+
const tag = cipher.getAuthTag();
|
|
61
|
+
const encodedHash = createHash('sha256').update(ciphertext).digest('hex');
|
|
62
|
+
const metadata = {
|
|
63
|
+
name: 'aes_gcm',
|
|
64
|
+
version: AES_GCM_CODEC_VERSION,
|
|
65
|
+
key_id: this.activeKeyId,
|
|
66
|
+
nonce: nonce.toString('base64url'),
|
|
67
|
+
tag: tag.toString('base64url'),
|
|
68
|
+
encoded_content_hash: encodedHash,
|
|
69
|
+
encoded_size_bytes: ciphertext.length,
|
|
70
|
+
};
|
|
71
|
+
return { body: ciphertext, metadata };
|
|
72
|
+
}
|
|
73
|
+
async decode(input) {
|
|
74
|
+
const { metadata } = input;
|
|
75
|
+
if (metadata.name !== 'aes_gcm') {
|
|
76
|
+
throw new RawContentCodecError(`AES-GCM codec cannot decode metadata.name='${metadata.name}'.`);
|
|
77
|
+
}
|
|
78
|
+
if (!metadata.key_id) {
|
|
79
|
+
throw new RawContentCodecError('AES-GCM codec metadata is missing key_id.');
|
|
80
|
+
}
|
|
81
|
+
const key = this.ring.get(metadata.key_id);
|
|
82
|
+
if (!key) {
|
|
83
|
+
throw new RawContentCodecKeyNotFoundError(metadata.key_id);
|
|
84
|
+
}
|
|
85
|
+
const nonce = decodeBase64Url(metadata.nonce, 'nonce', AES_GCM_NONCE_BYTES);
|
|
86
|
+
const tag = decodeBase64Url(metadata.tag, 'tag', AES_GCM_TAG_BYTES);
|
|
87
|
+
const decipher = createDecipheriv('aes-256-gcm', key, nonce);
|
|
88
|
+
decipher.setAuthTag(tag);
|
|
89
|
+
try {
|
|
90
|
+
const plaintext = Buffer.concat([decipher.update(input.body), decipher.final()]);
|
|
91
|
+
return { body: plaintext };
|
|
92
|
+
}
|
|
93
|
+
catch (err) {
|
|
94
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
95
|
+
throw new RawContentCodecError(`AES-GCM decode failed (auth tag mismatch or tamper): ${reason}`);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
function decodeBase64Url(value, field, expectedBytes) {
|
|
100
|
+
if (!value) {
|
|
101
|
+
throw new RawContentCodecError(`AES-GCM codec metadata is missing '${field}'.`);
|
|
102
|
+
}
|
|
103
|
+
const buf = Buffer.from(value, 'base64url');
|
|
104
|
+
if (buf.length !== expectedBytes) {
|
|
105
|
+
throw new RawContentCodecError(`AES-GCM codec metadata '${field}' has ${buf.length} bytes; expected ${expectedBytes}.`);
|
|
106
|
+
}
|
|
107
|
+
return buf;
|
|
108
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pass-through codec: bytes go in and bytes come out unchanged. Used
|
|
3
|
+
* when `RAW_CONTENT_CODEC=none` — the immediate-provider default for
|
|
4
|
+
* `local_fs` / `s3` deployments where operator-level encryption isn't
|
|
5
|
+
* needed (or is handled below the application layer by the provider).
|
|
6
|
+
*
|
|
7
|
+
* Round-trips a `name + version` sidecar so the read path can branch on
|
|
8
|
+
* `metadata.codec.name === 'none'` deterministically rather than
|
|
9
|
+
* inferring "no codec" from a missing key.
|
|
10
|
+
*/
|
|
11
|
+
import type { RawContentCodec, RawContentCodecDecodeInput, RawContentCodecDecodeResult, RawContentCodecEncodeInput, RawContentCodecEncodeResult } from '../raw-content-codec.js';
|
|
12
|
+
export declare class NoopRawContentCodec implements RawContentCodec {
|
|
13
|
+
readonly name: "none";
|
|
14
|
+
encode(input: RawContentCodecEncodeInput): Promise<RawContentCodecEncodeResult>;
|
|
15
|
+
decode(input: RawContentCodecDecodeInput): Promise<RawContentCodecDecodeResult>;
|
|
16
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pass-through codec: bytes go in and bytes come out unchanged. Used
|
|
3
|
+
* when `RAW_CONTENT_CODEC=none` — the immediate-provider default for
|
|
4
|
+
* `local_fs` / `s3` deployments where operator-level encryption isn't
|
|
5
|
+
* needed (or is handled below the application layer by the provider).
|
|
6
|
+
*
|
|
7
|
+
* Round-trips a `name + version` sidecar so the read path can branch on
|
|
8
|
+
* `metadata.codec.name === 'none'` deterministically rather than
|
|
9
|
+
* inferring "no codec" from a missing key.
|
|
10
|
+
*/
|
|
11
|
+
const NOOP_CODEC_VERSION = 1;
|
|
12
|
+
export class NoopRawContentCodec {
|
|
13
|
+
name = 'none';
|
|
14
|
+
async encode(input) {
|
|
15
|
+
return {
|
|
16
|
+
body: input.body,
|
|
17
|
+
metadata: { name: 'none', version: NOOP_CODEC_VERSION },
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
async decode(input) {
|
|
21
|
+
return { body: input.body };
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Builds the `RawContentStore` instance backing
|
|
3
|
+
* `rawStorageMode='managed_blob'`.
|
|
4
|
+
*
|
|
5
|
+
* The actual cross-field validation happens at config-load time in
|
|
6
|
+
* `src/config.ts` (`validateRawStorageConfig`). This factory trusts
|
|
7
|
+
* the validated config: when `rawStorageMode='managed_blob'` arrives,
|
|
8
|
+
* the provider-specific fields are already non-null. When mode is
|
|
9
|
+
* `pointer_only`, the factory returns `null` and document upload routes
|
|
10
|
+
* report 503 to clients that try to upload anyway — see the route
|
|
11
|
+
* layer for the user-facing error envelope.
|
|
12
|
+
*/
|
|
13
|
+
import type { RuntimeConfig } from '../config.js';
|
|
14
|
+
import type { RawContentStore } from './raw-content-store.js';
|
|
15
|
+
type RawStorageConfig = Pick<RuntimeConfig, 'rawStorageMode' | 'rawStorageProvider' | 'rawStorageLocalFsRoot' | 'rawStorageS3Bucket' | 'rawStorageS3Region' | 'rawStorageS3Endpoint' | 'rawStorageS3AccessKeyId' | 'rawStorageS3SecretAccessKey' | 'rawStorageDeploymentEnv' | 'rawStorageLegacyProviders' | 'filecoinProvider'>;
|
|
16
|
+
/**
|
|
17
|
+
* Returns `null` when raw bytes are not stored by core (pointer-only
|
|
18
|
+
* default). Returns a configured adapter when
|
|
19
|
+
* `rawStorageMode='managed_blob'`.
|
|
20
|
+
*
|
|
21
|
+
* Async because some providers (e.g. the Synapse-backed Filecoin
|
|
22
|
+
* client) may need async composition at startup. The current
|
|
23
|
+
* `createFilecoinStorageBackend` is synchronous internally; the
|
|
24
|
+
* async return type preserves the boundary for future
|
|
25
|
+
* providers that need awaitable construction (handshake,
|
|
26
|
+
* credential exchange, etc.) without forcing a signature change.
|
|
27
|
+
*/
|
|
28
|
+
export declare function buildRawContentStore(cfg: RawStorageConfig): Promise<RawContentStore | null>;
|
|
29
|
+
/**
|
|
30
|
+
* Build read-only adapters for any legacy providers configured via
|
|
31
|
+
* `RAW_STORAGE_LEGACY_PROVIDERS`. Composition-root code registers
|
|
32
|
+
* these in the `RawContentStoreRegistry` alongside the active store
|
|
33
|
+
* so cleanup dispatches historical rows to the right adapter (Phase
|
|
34
|
+
* 4a §6 — `local-fs://...` rows on a Filecoin-active deployment
|
|
35
|
+
* still need a registered `local_fs` adapter to run their DELETE).
|
|
36
|
+
*
|
|
37
|
+
* `validateRawStorageConfig` already enforced that every named legacy
|
|
38
|
+
* provider has its full env block; this function trusts that
|
|
39
|
+
* validation and re-runs the per-provider builder. Returns an empty
|
|
40
|
+
* array when the operator hasn't configured any legacy providers —
|
|
41
|
+
* the common single-provider deployment.
|
|
42
|
+
*/
|
|
43
|
+
export declare function buildLegacyStores(cfg: RawStorageConfig): ReadonlyArray<RawContentStore>;
|
|
44
|
+
export {};
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Builds the `RawContentStore` instance backing
|
|
3
|
+
* `rawStorageMode='managed_blob'`.
|
|
4
|
+
*
|
|
5
|
+
* The actual cross-field validation happens at config-load time in
|
|
6
|
+
* `src/config.ts` (`validateRawStorageConfig`). This factory trusts
|
|
7
|
+
* the validated config: when `rawStorageMode='managed_blob'` arrives,
|
|
8
|
+
* the provider-specific fields are already non-null. When mode is
|
|
9
|
+
* `pointer_only`, the factory returns `null` and document upload routes
|
|
10
|
+
* report 503 to clients that try to upload anyway — see the route
|
|
11
|
+
* layer for the user-facing error envelope.
|
|
12
|
+
*/
|
|
13
|
+
import { LocalFsRawContentStore } from './local-fs-store.js';
|
|
14
|
+
import { S3RawContentStore } from './s3-store.js';
|
|
15
|
+
/**
|
|
16
|
+
* Returns `null` when raw bytes are not stored by core (pointer-only
|
|
17
|
+
* default). Returns a configured adapter when
|
|
18
|
+
* `rawStorageMode='managed_blob'`.
|
|
19
|
+
*
|
|
20
|
+
* Async because some providers (e.g. the Synapse-backed Filecoin
|
|
21
|
+
* client) may need async composition at startup. The current
|
|
22
|
+
* `createFilecoinStorageBackend` is synchronous internally; the
|
|
23
|
+
* async return type preserves the boundary for future
|
|
24
|
+
* providers that need awaitable construction (handshake,
|
|
25
|
+
* credential exchange, etc.) without forcing a signature change.
|
|
26
|
+
*/
|
|
27
|
+
export async function buildRawContentStore(cfg) {
|
|
28
|
+
if (cfg.rawStorageMode !== 'managed_blob')
|
|
29
|
+
return null;
|
|
30
|
+
if (cfg.rawStorageProvider === 'local_fs')
|
|
31
|
+
return buildLocalFs(cfg);
|
|
32
|
+
if (cfg.rawStorageProvider === 's3')
|
|
33
|
+
return buildS3(cfg);
|
|
34
|
+
if (cfg.rawStorageProvider === 'filecoin') {
|
|
35
|
+
if (cfg.filecoinProvider === null) {
|
|
36
|
+
// Defense-in-depth: `parseFilecoinProviderConfig` in
|
|
37
|
+
// `src/config.ts` already enforces "filecoin selected ⇒ full
|
|
38
|
+
// RAW_STORAGE_FILECOIN_* env block", so this branch is
|
|
39
|
+
// unreachable in production. Throw rather than silently
|
|
40
|
+
// construct a half-wired backend that advertises supportsHead
|
|
41
|
+
// / supportsGet but cannot actually perform either.
|
|
42
|
+
throw new Error("buildRawContentStore: rawStorageProvider='filecoin' but filecoinProvider config is null. " +
|
|
43
|
+
'Set the full RAW_STORAGE_FILECOIN_* env block.');
|
|
44
|
+
}
|
|
45
|
+
// Lazy: heavy Filecoin packages (`@filoz/synapse-sdk`, `viem`)
|
|
46
|
+
// resolve ONLY here, never on non-Filecoin startup. The defense-
|
|
47
|
+
// in-depth `cfg.filecoinProvider === null` throw above runs
|
|
48
|
+
// BEFORE the import, so a misconfigured deployment fails fast
|
|
49
|
+
// without pulling the vendor SDK either.
|
|
50
|
+
const { createFilecoinStorageBackend } = await import('./providers/filecoin/index.js');
|
|
51
|
+
return createFilecoinStorageBackend(cfg.filecoinProvider);
|
|
52
|
+
}
|
|
53
|
+
// Defense-in-depth: config validation should already have caught this.
|
|
54
|
+
throw new Error(`buildRawContentStore: rawStorageMode='managed_blob' but provider is missing/unknown ` +
|
|
55
|
+
`(got '${cfg.rawStorageProvider}'). Fix RAW_STORAGE_PROVIDER and restart.`);
|
|
56
|
+
}
|
|
57
|
+
function buildLocalFs(cfg) {
|
|
58
|
+
if (!cfg.rawStorageLocalFsRoot) {
|
|
59
|
+
throw new Error("buildRawContentStore(local_fs): RAW_STORAGE_LOCAL_FS_ROOT is required.");
|
|
60
|
+
}
|
|
61
|
+
return new LocalFsRawContentStore({ root: cfg.rawStorageLocalFsRoot });
|
|
62
|
+
}
|
|
63
|
+
function buildS3(cfg) {
|
|
64
|
+
if (!cfg.rawStorageS3Bucket || !cfg.rawStorageS3Region
|
|
65
|
+
|| !cfg.rawStorageS3AccessKeyId || !cfg.rawStorageS3SecretAccessKey) {
|
|
66
|
+
throw new Error("buildRawContentStore(s3): bucket/region/access-key-id/secret-access-key are all required.");
|
|
67
|
+
}
|
|
68
|
+
return new S3RawContentStore({
|
|
69
|
+
bucket: cfg.rawStorageS3Bucket,
|
|
70
|
+
region: cfg.rawStorageS3Region,
|
|
71
|
+
endpoint: cfg.rawStorageS3Endpoint ?? undefined,
|
|
72
|
+
accessKeyId: cfg.rawStorageS3AccessKeyId,
|
|
73
|
+
secretAccessKey: cfg.rawStorageS3SecretAccessKey,
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Build read-only adapters for any legacy providers configured via
|
|
78
|
+
* `RAW_STORAGE_LEGACY_PROVIDERS`. Composition-root code registers
|
|
79
|
+
* these in the `RawContentStoreRegistry` alongside the active store
|
|
80
|
+
* so cleanup dispatches historical rows to the right adapter (Phase
|
|
81
|
+
* 4a §6 — `local-fs://...` rows on a Filecoin-active deployment
|
|
82
|
+
* still need a registered `local_fs` adapter to run their DELETE).
|
|
83
|
+
*
|
|
84
|
+
* `validateRawStorageConfig` already enforced that every named legacy
|
|
85
|
+
* provider has its full env block; this function trusts that
|
|
86
|
+
* validation and re-runs the per-provider builder. Returns an empty
|
|
87
|
+
* array when the operator hasn't configured any legacy providers —
|
|
88
|
+
* the common single-provider deployment.
|
|
89
|
+
*/
|
|
90
|
+
export function buildLegacyStores(cfg) {
|
|
91
|
+
return cfg.rawStorageLegacyProviders.map((provider) => {
|
|
92
|
+
if (provider === 'local_fs')
|
|
93
|
+
return buildLocalFs(cfg);
|
|
94
|
+
if (provider === 's3')
|
|
95
|
+
return buildS3(cfg);
|
|
96
|
+
// Defense-in-depth: validation already rejects 'filecoin' here.
|
|
97
|
+
throw new Error(`buildLegacyStores: provider '${provider}' is not registerable as legacy.`);
|
|
98
|
+
});
|
|
99
|
+
}
|