What to build
api-server routes between two physical DB pools — prod db and assets assets_db (#333). The selection is a hand-written convention (state.assets_db.as_ref() vs state.db), and a typo routes a query to the wrong physical database — a production-incident-class bug.
A runtime trait abstraction was considered and rejected (shallow, and it can't model the legitimate dual-pool sites; KISS/YAGNI). Instead, add a static CI guard to the existing .github/workflows/api-server-invariants.yml: a grep-based check that flags assets_db references outside the sanctioned domains, so a stray pool reference fails CI instead of shipping.
Acceptance criteria
Blocked by
None - can start immediately
What to build
api-server routes between two physical DB pools — prod
dband assetsassets_db(#333). The selection is a hand-written convention (state.assets_db.as_ref()vsstate.db), and a typo routes a query to the wrong physical database — a production-incident-class bug.A runtime trait abstraction was considered and rejected (shallow, and it can't model the legitimate dual-pool sites; KISS/YAGNI). Instead, add a static CI guard to the existing
.github/workflows/api-server-invariants.yml: a grep-based check that flagsassets_dbreferences outside the sanctioned domains, so a stray pool reference fails CI instead of shipping.Acceptance criteria
api-server-invariants.ymlgains a check that fails whenassets_dbis referenced outside an allowlist of domains that legitimately use it (raw_posts, plus any genuine dual-pool sites such as verify/delete flows)main; a deliberately-wrongassets_dbreference in a prod-only domain makes it failBlocked by
None - can start immediately