The first real production question broke retrieval, and the failure was structural, not a fluke. Search used Postgres full-text search, which ANDs every stemmed content word together — a chunk had to match every word of the question inside the same ~800-character window. "What is the role of an enabling team in a microservice architecture?" returned "I couldn't find relevant information" against a manual with a full page on enabling teams. Verified directly against the live database: zero rows for the strict AND match, while three chunks discussed the topic at length — none happened to also say "role" and "architecture" in the same chunk.
The designed answer already existed in the codebase: vector and hybrid search behind feature flags, with the pgvector column and index already migrated. But no embeddings had been backfilled and no embedding-provider key was set — turning the flags on meant a real migration-and-backfill pass, not a flag flip. The chosen fix was deliberately cheap: when the strict AND returns zero rows, retry the same lexemes OR'd together, ranked so chunks matching more terms still win. Zero new infrastructure, zero new API cost, one extra query only on the already-rare found-nothing path. Measured before the code was written: the OR-relaxed query returned six ranked results for the exact failing question, including both chunks that actually answer it.
Deployment had its own hurt: the first live deploy 500'd in a way that looked exactly like a CORS block, because an uncaught exception bypasses the CORS middleware's header-attaching step. The real traceback, pulled from Railway's deployment logs, was psycopg2 failing with "Network is unreachable" — Supabase's direct Postgres host resolves to IPv6 and Railway containers have no outbound IPv6 route. Fixed by switching to Supabase's IPv4-only connection pooler, safe here because the backend opens one connection per call and relies on no session-level state.
The lesson that stuck: get the real traceback before declaring a fix, and never trust a green local suite when CI's entry point differs — 450+ backend test functions now lock the retry behavior, the CORS fallback parsing, and the retry-backoff math.