Bundled pre-session doc + ops work: - docs/modules/**: sync across advisory-ai, airgap, cli, excititor, export-center, findings-ledger, notifier, notify, platform, router, sbom-service, ui, web (architectural + operational updates) - docs/features/**: updates to checked excititor vex pipeline, developer workspace, quick verify drawer - docs top-level: README, quickstart, API_CLI_REFERENCE, UI_GUIDE, code-of-conduct/TESTING_PRACTICES updates - docs/qa/feature-checks/: FLOW.md + excititor state update - docs/implplan/: remaining sprint updates + new Concelier source credentials sprint (SPRINT_20260422_003) - docs-archived/implplan/: 30 sprint archival moves (ElkSharp series, misc completed sprints) - devops/compose: .env + services compose + env example + router gateway config updates File-level granularity preserved. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2.7 KiB
2.7 KiB
Bundle Catalog & Items Repositories
Scope
- Deterministic storage for offline bundle metadata with tenant isolation (RLS) and stable ordering.
- Ready for PostgreSQL-backed implementation while providing in-memory deterministic reference behavior.
Schema (logical)
bundle_catalog:tenant_id(string, PK part, RLS partition)bundle_id(string, PK part)digest(hex string)imported_at_utc(datetime)content_paths(array of strings, sorted ordinal)
bundle_items:tenant_id(string, PK part, RLS partition)bundle_id(string, PK part)path(string, PK part)digest(hex string)size_bytes(long)
Implementation delivered
- 2025-11-20: In-memory repositories enforcing tenant isolation and deterministic ordering:
InMemoryBundleCatalogRepository(upsert + list ordered bybundle_id).InMemoryBundleItemRepository(bulk upsert + list ordered bypath).
- Models:
BundleCatalogEntry,BundleItem. - Tests cover upsert overwrite semantics, tenant isolation, and deterministic ordering (
tests/AirGap/StellaOps.AirGap.Importer.Tests/InMemoryBundleRepositoriesTests.cs). - 2026-04-20: Durable file-backed repositories for the live CLI mirror import path:
FileSystemBundleCatalogRepositorystores tenant-scoped bundle catalog entries under the offline-kit local state root with atomic JSON writes.FileSystemBundleItemRepositorystores tenant+bundle item manifests under the same root with deterministic ordinal ordering bypath.src/Cli/StellaOps.Clinow registers the file-backed repositories forMirrorBundleImportService, so imported metadata survives fresh CLI processes instead of disappearing with the process-local container state.
Migration notes (for PostgreSQL backends)
- Create compound unique indexes on (
tenant_id,bundle_id) for catalog; (tenant_id,bundle_id,path) for items. - Enforce RLS by always scoping queries to
tenant_idand validating it at repository boundary (as done in in-memory reference impl). - Keep paths lowercased or use ordinal comparisons to avoid locale drift; sort before persistence to preserve determinism.
Runtime contract
- Live CLI mirror-bundle import uses the durable file-backed repositories rooted under
%LocalApplicationData%/stellaops/offline-kit/state/mirror-bundles. - In-memory repositories remain valid for deterministic tests and isolated non-persistent harnesses, but they are no longer the live CLI runtime default.
Next steps
- If the AirGap controller or another shared service requires multi-process or multi-node bundle metadata, add a PostgreSQL-backed repository pair that mirrors the same tenant scoping and deterministic ordering.
Owners
- AirGap Importer Guild.