A reasoning sketch that lists ids as bare strings (`{"nodes": ["A", "B"]}`) has truthy
arrays but no node/edge objects. The winner gate tested the raw parsed value, so the
sketch won and then sanitized to empty, shadowing the real fragment that followed and
re-triggering the #2880 hollow-response bisection. Sanitize before the emptiness gate so
such a sketch is demoted to the empty-fragment tier. Also document the keyed-candidate
cap crowd-out as a known gap.
Reasoning-first models think out loud, fence the answer, or both, so the reply is not a
bare JSON object and the strict parse dropped the whole chunk. Try the whole reply first
(unchanged fast path), then each balanced-brace candidate, preferring braces that carry
the extraction keys so narration braces do not shadow the answer; a shape restatement
that carries the keys but no content is kept only as a last resort.