fix(retain): retry and fail loudly on schema-drifted fact extraction (#3708) (#3760)
A model without strict-schema support can return well-formed JSON whose fact objects have the wrong shape (no `what`/`factual_core`/`text`). Every such fact was skipped with only a log line, and — unlike the two sibling skip paths — the `missing 'what'` path did not set `has_malformed_facts`, so the re-prompt loop never ran. A response whose facts were all drifted returned `[]` on the first attempt, the document was committed with 0 memory units, and the operation reported `completed`: silent data loss. Streaming path: count an absent text key as malformed so the existing re-prompt runs, and raise once retries are exhausted and nothing usable came back — the same rule the non-dict response already follows (#1833), so the worker retries and ultimately fails the operation instead of committing an empty document. Batch path: it cannot re-prompt a single request, so record the drop in `extraction_errors` (surfaced in the operation's result_metadata, and escalatable via HINDSIGHT_API_FAIL_ON_EXTRACTION_ERRORS) instead of dropping it silently. A `what` that is *present* but empty or "N/A" is the model saying "nothing to extract here" — that stays a quiet skip in both paths, as does `"facts": []`, so content that genuinely holds no facts does not become a hard failure.
N
Nicolò Boschi committed
d8a71c31391411c3dfc79bf87dee7dc16cc44883
Parent: f4a9369
Committed by GitHub <noreply@github.com>
on 8/24/2026, 11:21:55 AM