Bundle Catalog & Items Repositories
Audience: engineers working on the Stella Ops AirGap Importer and CLI mirror-import path.
This reference describes how offline bundle metadata (the bundle catalog and per-bundle item manifests) is stored: the logical schema, the repository implementations (in-memory and durable file-backed), the runtime contract, and migration notes for a future PostgreSQL backend.
Scope
- Deterministic storage for offline bundle metadata with tenant isolation (RLS) and stable ordering.
- Ready for a 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.
