three failure modes, two enforcement points
prompt-for-JSON (no strict mode)
generate freely
parse JSON
validate against schema
FAIL 1: parse error
FAIL 2: schema violation
SUCCESS: typed payload
retry on failure (max 3x)
expensive but necessary without strict mode
strict mode / constrained decoding
decode with schema-aware logit mask
grammar FSM rejects invalid next-tokens
output parses (always)
output validates (always)
SUCCESS: typed payload
REFUSAL: typed reason
OpenAI : response_format strict:true
Anthropic : input_schema on tool_use
Gemini : responseSchema + grammar
Open : outlines / guidance / lm-format-enforcer
under strict, only the refusal branch stays; the retry loop collapses.