Context
ai/config.template.mjs engines.chroma.database was one of the four inline-process.env leaf defaults baselined by the SSOT lint (#12474, on dev):
database: leaf(process.env.UNIT_TEST_MODE === 'true' ? CHROMA_TEST_DATABASE : CHROMA_PRODUCTION_DATABASE, 'NEO_CHROMA_DATABASE', 'string')
The clean, fail-closed static case of the #12451 declarative-reshape half — the lint half landed (#12474); this leaf is the first reshape burndown.
Shipped Contract (3-leaf toggle) — Contract Ledger
PR #12481 shipped the 3-leaf toggle design steered by @tobiu (SSOT + KISS + safe-by-construction), NOT the originally-planned npm-script env relocation (see Superseded below). Backfilled per @neo-gpt's #12481 review.
| Surface |
Type |
Contract |
engines.chroma.database |
config leaf |
Prod DB name. Literal default 'default_database'; env override NEO_CHROMA_DATABASE. No inline process.env. |
engines.chroma.databaseTest |
config leaf |
Test DB name. Literal default 'neo-unit-test'; env override NEO_CHROMA_DATABASE_TEST. |
engines.chroma.useTestDatabase |
config leaf |
Selection toggle. Default false; env override UNIT_TEST_MODE (boolean, env-arg form — lint-clean). |
ChromaManager.resolveChromaClientConfig() |
consumer |
Reads the resolved toggle; returns databaseTest when on, else database. Pure config reads, no inline process.env. |
fail-closed guard (ChromaManager) |
invariant |
Refuses when the resolved DB === database while the toggle is on (refuses prod-DB-under-test → loud, never silent bleed). |
Safe-by-construction: both DB names are config values (not an npm-script-only env). Bare npx playwright (without npm run test-unit) still resolves the toggle from UNIT_TEST_MODE and points at databaseTest — it cannot bleed unit collections into production. (Caveat: requires the gitignored ai/config.mjs overlay to be current — see PR #12481 Rollout Note.)
The Fix — SUPERSEDED
⚠️ Superseded by the 3-leaf toggle above (per @tobiu's design steer + @neo-gpt's #12481 review). The original plan — make the leaf declarative + relocate the test override to the test-unit npm-script shell env (NEO_CHROMA_DATABASE=neo-unit-test) — was rejected: moving the test DB name into an npm-script-only env meant bare npx playwright lost it → prod-bleed risk ("oh, I forgot to use npm run test-unit"). The shipped design keeps both names as config values + a toggle. Original text retained for provenance:
Make the leaf declarative — leaf(CHROMA_PRODUCTION_DATABASE, 'NEO_CHROMA_DATABASE', 'string') — and relocate the test override to the test-unit npm script shell env (NEO_CHROMA_DATABASE=neo-unit-test). Drop the now-reshaped NEO_CHROMA_DATABASE row from the lint BASELINE.
Acceptance Criteria (shipped)
Scope
Chroma database leaf only. The graph (NEO_MEMORY_DB_PATH) static case + the dynamic collection-name cases remain on #12451 (their own follow-ups — distinct risk/complexity).
Refs #12451 (reshape umbrella). Part of Epic #12456 (AiConfig reactive Provider SSOT cleanup).
Origin Session ID: 3ecb40bf-bfef-40b1-8693-a8aae5afa1b7
Authored by Claude Opus 4.8 (Claude Code), /lead-role.
Contract Ledger + supersede annotation backfilled per @neo-gpt #12481 review (2026-06-04).
Context
ai/config.template.mjsengines.chroma.databasewas one of the four inline-process.envleaf defaults baselined by the SSOT lint (#12474, on dev):database: leaf(process.env.UNIT_TEST_MODE === 'true' ? CHROMA_TEST_DATABASE : CHROMA_PRODUCTION_DATABASE, 'NEO_CHROMA_DATABASE', 'string')The clean, fail-closed static case of the #12451 declarative-reshape half — the lint half landed (#12474); this leaf is the first reshape burndown.
Shipped Contract (3-leaf toggle) — Contract Ledger
PR #12481 shipped the 3-leaf toggle design steered by @tobiu (SSOT + KISS + safe-by-construction), NOT the originally-planned npm-script env relocation (see Superseded below). Backfilled per @neo-gpt's #12481 review.
engines.chroma.database'default_database'; env overrideNEO_CHROMA_DATABASE. No inlineprocess.env.engines.chroma.databaseTest'neo-unit-test'; env overrideNEO_CHROMA_DATABASE_TEST.engines.chroma.useTestDatabasefalse; env overrideUNIT_TEST_MODE(boolean, env-arg form — lint-clean).ChromaManager.resolveChromaClientConfig()databaseTestwhen on, elsedatabase. Pure config reads, no inlineprocess.env.ChromaManager)databasewhile the toggle is on (refuses prod-DB-under-test → loud, never silent bleed).Safe-by-construction: both DB names are config values (not an npm-script-only env). Bare
npx playwright(withoutnpm run test-unit) still resolves the toggle fromUNIT_TEST_MODEand points atdatabaseTest— it cannot bleed unit collections into production. (Caveat: requires the gitignoredai/config.mjsoverlay to be current — see PR #12481 Rollout Note.)The Fix— SUPERSEDEDAcceptance Criteria (shipped)
engines.chroma.databaseleaf is declarative (no inlineprocess.env); env override via theNEO_CHROMA_DATABASEarg.databaseTestis a config leaf + theuseTestDatabasetoggle (NOT an npm-script-only env — supersedes the originaltest-unit-env AC).NEO_CHROMA_DATABASErow is removed from the SSOT-lintBASELINE(lint green: 3 baselined, no new violation, no stale row).ChromaManagerfail-closed guard is the by-construction backstop).Scope
Chroma database leaf only. The graph (
NEO_MEMORY_DB_PATH) static case + the dynamic collection-name cases remain on #12451 (their own follow-ups — distinct risk/complexity).Refs #12451 (reshape umbrella). Part of Epic #12456 (AiConfig reactive Provider SSOT cleanup).
Origin Session ID: 3ecb40bf-bfef-40b1-8693-a8aae5afa1b7 Authored by Claude Opus 4.8 (Claude Code), /lead-role. Contract Ledger + supersede annotation backfilled per @neo-gpt #12481 review (2026-06-04).