FED-M1-03 — pgvector support in the postgres storage adapter, gated on enableVector flag (set automatically for federated tier). Local and standalone tiers are untouched.
PostgresAdapter.migrate() runs CREATE EXTENSION IF NOT EXISTS vector via db.execute(sql) BEFORE migrations when the flag is true. Idempotent — safe to re-run on an already-installed extension. Order matters: the extension must exist before any migration that creates a vector(...) column runs.
The constructor still does NOT touch the database (preserves current behavior).
Schema export:
vector custom type in @mosaicstack/db/schema is now exported (it was internal, used by preferences.embedding). Downstream packages can now declare vector('col', { dimensions: N }) in their own schemas.
Config wiring:
DEFAULT_FEDERATED_CONFIG.storage.enableVector = true so the federated default flows through to the adapter.
detectFromEnv() restructured so MOSAIC_STORAGE_TIER is checked BEFORE the DATABASE_URL guard. Setting MOSAIC_STORAGE_TIER=federated alone now returns the federated default config instead of silently misrouting to local (footgun fix raised in code review). Same applies to MOSAIC_STORAGE_TIER=standalone. With DATABASE_URL set, the URL is honored and enableVector is preserved.
detectFromEnv is now exported for direct test access.
Tests added:
4 PostgresAdapter unit tests covering the gating + ordering. SQL-content assertion uses Drizzle's toSQL() (public API) with a documented fallback for older Drizzle versions.
4 detectFromEnv tests covering each env-var permutation (no vars / federated alone / federated+DATABASE_URL / standalone alone).
1 DEFAULT_FEDERATED_CONFIG constant test confirming enableVector=true.
Review chain:
Implementation: sonnet subagent on feat/federation-m1-pgvector
## Summary
FED-M1-03 — pgvector support in the postgres storage adapter, gated on `enableVector` flag (set automatically for federated tier). Local and standalone tiers are untouched.
**Adapter changes:**
- `StorageConfig` postgres variant gains optional `enableVector?: boolean`.
- `PostgresAdapter.migrate()` runs `CREATE EXTENSION IF NOT EXISTS vector` via `db.execute(sql)` BEFORE migrations when the flag is true. Idempotent — safe to re-run on an already-installed extension. Order matters: the extension must exist before any migration that creates a `vector(...)` column runs.
- The constructor still does NOT touch the database (preserves current behavior).
**Schema export:**
- `vector` custom type in `@mosaicstack/db/schema` is now exported (it was internal, used by `preferences.embedding`). Downstream packages can now declare `vector('col', { dimensions: N })` in their own schemas.
**Config wiring:**
- `DEFAULT_FEDERATED_CONFIG.storage.enableVector = true` so the federated default flows through to the adapter.
- `detectFromEnv()` restructured so `MOSAIC_STORAGE_TIER` is checked BEFORE the `DATABASE_URL` guard. Setting `MOSAIC_STORAGE_TIER=federated` alone now returns the federated default config instead of silently misrouting to local (footgun fix raised in code review). Same applies to `MOSAIC_STORAGE_TIER=standalone`. With `DATABASE_URL` set, the URL is honored and `enableVector` is preserved.
- `detectFromEnv` is now exported for direct test access.
**Tests added:**
- 4 PostgresAdapter unit tests covering the gating + ordering. SQL-content assertion uses Drizzle's `toSQL()` (public API) with a documented fallback for older Drizzle versions.
- 4 `detectFromEnv` tests covering each env-var permutation (no vars / federated alone / federated+DATABASE_URL / standalone alone).
- 1 `DEFAULT_FEDERATED_CONFIG` constant test confirming `enableVector=true`.
**Review chain:**
- Implementation: sonnet subagent on `feat/federation-m1-pgvector`
- Independent review: `feature-dev:code-reviewer` (sonnet) — verdict `ship-with-followup`, raised 2 issues (silent misroute, brittle test assertion)
- Both issues fixed pre-merge in the same branch
- Independent haiku verifier confirmed both fixes + regression suite
## Out of scope (deferred)
- Tier-detector with fail-fast assertions → FED-M1-04
- Migration script → FED-M1-05
- Real-Postgres integration test (compose+vector boot) → FED-M1-07
**Refs** #460
## Test plan
- [x] `pnpm --filter @mosaicstack/storage test` (31/31)
- [x] `pnpm --filter @mosaicstack/config test` (15/15)
- [x] `pnpm typecheck` (38/38)
- [x] `pnpm lint` (21/21)
- [x] `pnpm format:check`
- [ ] CI green on merge
Generated with Claude Code
Adds pgvector support to the postgres storage adapter without affecting
local or standalone tiers:
- `StorageConfig` postgres variant gains optional `enableVector: boolean`
- `PostgresAdapter.migrate()` runs `CREATE EXTENSION IF NOT EXISTS vector`
via `db.execute(sql)` BEFORE migrations when `enableVector === true`
(so vector-typed columns are creatable in the same migration pass).
Idempotent — safe to re-run on already-installed extension.
- `vector` custom type in `@mosaicstack/db/schema` is now exported so
downstream packages can declare vector columns in their own schemas.
- `DEFAULT_FEDERATED_CONFIG.storage.enableVector = true` so the federated
default flows through the adapter.
- `detectFromEnv()` restructured: `MOSAIC_STORAGE_TIER` is now checked
BEFORE the `DATABASE_URL` guard so `MOSAIC_STORAGE_TIER=federated`
alone returns the federated default config instead of silently
misrouting to local. Same applies to `=standalone`. With
`DATABASE_URL` set, the URL is honored and `enableVector` is preserved
on federated.
- `detectFromEnv` is now exported for direct test access.
Tests:
- 4 PostgresAdapter unit tests cover: extension SQL issued when enabled,
not issued when disabled or unset, ordering (extension before
runMigrations). Assertion uses Drizzle's `toSQL()` with documented
fallback for older versions.
- 4 detectFromEnv tests cover the four env-var permutations.
- 1 federated default constant test.
No behavior change for local or standalone tier deployments.
Refs #460
Co-Authored-By: Claude Opus 4.7 <[email protected]>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Summary
FED-M1-03 — pgvector support in the postgres storage adapter, gated on
enableVectorflag (set automatically for federated tier). Local and standalone tiers are untouched.Adapter changes:
StorageConfigpostgres variant gains optionalenableVector?: boolean.PostgresAdapter.migrate()runsCREATE EXTENSION IF NOT EXISTS vectorviadb.execute(sql)BEFORE migrations when the flag is true. Idempotent — safe to re-run on an already-installed extension. Order matters: the extension must exist before any migration that creates avector(...)column runs.Schema export:
vectorcustom type in@mosaicstack/db/schemais now exported (it was internal, used bypreferences.embedding). Downstream packages can now declarevector('col', { dimensions: N })in their own schemas.Config wiring:
DEFAULT_FEDERATED_CONFIG.storage.enableVector = trueso the federated default flows through to the adapter.detectFromEnv()restructured soMOSAIC_STORAGE_TIERis checked BEFORE theDATABASE_URLguard. SettingMOSAIC_STORAGE_TIER=federatedalone now returns the federated default config instead of silently misrouting to local (footgun fix raised in code review). Same applies toMOSAIC_STORAGE_TIER=standalone. WithDATABASE_URLset, the URL is honored andenableVectoris preserved.detectFromEnvis now exported for direct test access.Tests added:
toSQL()(public API) with a documented fallback for older Drizzle versions.detectFromEnvtests covering each env-var permutation (no vars / federated alone / federated+DATABASE_URL / standalone alone).DEFAULT_FEDERATED_CONFIGconstant test confirmingenableVector=true.Review chain:
feat/federation-m1-pgvectorfeature-dev:code-reviewer(sonnet) — verdictship-with-followup, raised 2 issues (silent misroute, brittle test assertion)Out of scope (deferred)
Refs #460
Test plan
pnpm --filter @mosaicstack/storage test(31/31)pnpm --filter @mosaicstack/config test(15/15)pnpm typecheck(38/38)pnpm lint(21/21)pnpm format:checkGenerated with Claude Code