Split from the #323 audit (verified @ d1d724f). Three related operational hazards in the delivered document-RAG path:
- Silent-empty everywhere:
retrieve_chunks catches ALL exceptions → [] via a bare print (rag_service.py:137-139) — invisible to the app-logging path; an ungrounded tutor turn is indistinguishable from a grounded one at every layer. → logger + a metric/event. - Poisoned rows: a failed embed batch is logged and then upserted anyway with
embedding: None (rag_service.py:192,213) — permanently unretrievable, and nothing ever re-indexes them. - Durability inversion: DBOS wraps
/upload/sync (documents.py:615) which never indexes; the indexing route (streaming /upload) is non-durable by design (ADR 0011:179-181) — a crash between _persist_document and the post-roll task loses chunks permanently behind a healthy-looking documents row. At minimum document the gap; ideally give indexing a retry/backfill trigger (backfill_document_chunks.py exists but nothing invokes it).
Split from the #323 audit (verified @ d1d724f). Three related operational hazards in the delivered document-RAG path:
retrieve_chunkscatches ALL exceptions →[]via a bareprint(rag_service.py:137-139) — invisible to the app-logging path; an ungrounded tutor turn is indistinguishable from a grounded one at every layer. → logger + a metric/event.embedding: None(rag_service.py:192,213) — permanently unretrievable, and nothing ever re-indexes them./upload/sync(documents.py:615) which never indexes; the indexing route (streaming/upload) is non-durable by design (ADR 0011:179-181) — a crash between_persist_documentand the post-roll task loses chunks permanently behind a healthy-looking documents row. At minimum document the gap; ideally give indexing a retry/backfill trigger (backfill_document_chunks.py exists but nothing invokes it).