In brief
The Model Council's fallback chain silently swaps models when the primary fails. GPT-5.5 Pro hit a 120-second timeout on document debates and fell back to GPT-4o for weeks before anyone noticed. The front-end badge shows the original model name. The Execution Metrics collapse the truth into a single field: FALLBACK_TRIGGERED. The debate completes. The verdict is signed. The user never knows. The fallback chain is the right architecture for reliability. The badge is the wrong contract for trust. Every developer running multi-model production pipelines will hit this. The fix is not removing the fallback. It is making the swap visible.
Part 1 of 3: Verification Illusions
The governance dashboard showed something I had never seen before. Three debates in a row. FALLBACK_TRIGGERED. Same model. Same debate type. Same failure mode.
GPT-5.5 Pro was not running the debates. GPT-4o was. For weeks.
Key Takeaways
- The response card shows the model name you selected. The Execution Metrics record the model that actually ran. These are not the same thing.
- GPT-5.5 Pro hit a 120-second timeout on document-augmented debates and silently fell back to GPT-4o. The verdict was signed. The badge said GPT-5.5 Pro. The field said FALLBACK_TRIGGERED.
- Every developer running multi-model pipelines with timeouts will hit this. The architecture is correct. The UI contract is wrong.
- The fallback chain is the right safety net. Making the swap invisible is the wrong default. The badge should show what ran, not what was requested.
The badge says one thing. The telemetry says another.
The Model Council renders a response card for every model in the deliberation. GPT-5.6 Terra. Qwen 3 235B. Claude Sonnet 4.6. Gemini 3.6 Flash. Four cards, four badges, four named models.
Under each card sits a collapsed panel labelled Execution Metrics. Most users never expand it. It shows MODELS_DEPLOYED, CALLS_EXECUTED, STATE_VERDICT, DURATION, TOKENS. And one more field.
FALLBACK_TRIGGERED.
┌─────────────────────────┐
│ DEBATE UI BADGE │
│ "GPT-5.6 Terra" │ ← WHAT YOU SEE
└───────────┬─────────────┘
│
▼
┌─────────────────────────┐
│ 120s TIMEOUT │
│ fires at 127s │
│ model never responds │
└───────────┬─────────────┘
│
▼
┌─────────────────────────┐
│ FALLBACK CHAIN │
│ GPT-5.6 → GPT-4o │ ← WHAT ACTUALLY RAN
│ (swap is silent) │
└───────────┬─────────────┘
│
▼
┌─────────────────────────┐
│ FALLBACK_TRIGGERED │
│ = true │ ← THE TRUTH
│ (buried in collapsed │
│ metrics panel) │
└─────────────────────────┘
That field is a boolean. True means the model you asked for never ran. Something else did.
The badge on the card does not change. It continues to display the primary model name. GPT-5.6 Terra. The same badge you saw during the deliberation. The same name that signed the verdict. The same model you trusted because you chose it.
The fallback model is recorded nowhere in the visible UI. Not in the response card. Not in the verdict. Not in the summary. Only in the collapsed metrics panel, behind a label most users skip.
This is not a bug. It is the correct architectural choice for reliability. And it is the wrong contract for trust.
120 seconds. That is how long a model has to prove it exists.
Document-augmented debates send larger prompts. The document text, the system context, the persona, the cross-examination history. A prompt that a model handles in 40 seconds dry can take 90 seconds with a 50-page PDF attached.
The engine gives each model a hard deadline. On standard debates, it is generous. On document debates, it was 120 seconds.
GPT-5.5 Pro is fast on reasoning tasks. It is slower on structured analysis with long context. On a document debate with a legal filing or a technical report, the model would push past 120 seconds. Sometimes 130. Sometimes 150.
The engine does not wait. At 120 seconds, the timeout fires. The primary model is marked as failed. The fallback chain activates.
The same-provider fallback tries first. For OpenAI models, that means GPT-4o picks up the context and continues. GPT-4o is faster on long documents. It completes inside the window. The debate continues. The user sees tokens arriving. The verdict is synthesised.
The badge says GPT-5.5 Pro. The field says FALLBACK_TRIGGERED. The cost is different. The reasoning quality is different. The model architecture that produced the analysis is different. None of this is visible.
I found this by accident. Scanning the governance dashboard at midnight. Three debates. Same pattern. FALLBACK_TRIGGERED on GPT-5.5 Pro. Every document debate for weeks had run on GPT-4o. The badge had been lying to every user.
The Roster Problem describes how the council selects models. Six axes. Streaming verification as the gate. The fallback chain is the roster's safety net. It is maintained, audited daily, and structured for resilience. The chain is not the problem. The silence is.
The fallback chain is right. The invisibility is wrong.
The fallback chain exists for a reason. A debate that fails because one model timed out costs the user three debates consumed and produces nothing. That is worse than a completed debate with one slightly weaker model.
The architecture is deliberate. Each primary model has two same-provider alternatives. If both fail, three cross-provider alternatives take over. The source code defines this in CROSS_FALLBACKS and FAMILY_FALLBACKS in types.ts. The debate engine wraps every model call in executeModelCall(), which nests the fallback attempt inside error handling. If the primary fails, the fallback runs. If the fallback succeeds, the response is returned. The caller never distinguishes. The response is just a response.
This is the right call for reliability. A production pipeline that falls over when one model times out is not production-ready. The engine makes the pragmatic choice: degrade gracefully, surface the data, keep the debate alive.
The gap is between what the engine records and what the UI displays. The engine knows exactly which model ran. The insertResponse() function captures the actual model ID, the fallback flag, and the latency breakdown. The data is there, in the database, in every response row, since the first debate ever run.
The response card renders the primary model name. Not the actual model name. The badge is static. It is assigned when the debate starts, pinned to a card position, and never updated. The deliberation runs. The fallback fires. The badge stays the same.
This is a UI contract problem. The badge promises a specific model. The engine delivers whatever model survived. The data records the truth. The interface hides it.
The Green Checkmark Lie established the thesis. The green checkmark proved the author agreed with itself. It did not prove the code shipped. The fallback lie is the same pattern. The badge proves you asked for a model. It does not prove that model answered.
Every developer running multi-model pipelines will hit this
The fallback lie is not specific to the Model Council. It is a structural property of any system that runs multiple models with timeouts.
Set a deadline. Give a model a task. If the deadline fires, route to a cheaper model that finishes faster. Surface the original model name because that is what the user configured. Record the swap in telemetry that most users never check.
The developer who built the pipeline knows the swap happened. The user who consumed the output does not. The gap is the same gap that separates every backend engineer from every front-end user. The engineer trusts the telemetry. The user trusts the badge.
The fix is not removing the fallback chain. A pipeline that cannot degrade is a pipeline that cannot survive production. The fix is making the swap visible. If the fallback fires, the badge should change. The response card should show both names: requested and actual. The verdict should carry a note. Not a warning. A fact.
This is two lines of front-end logic. Check FALLBACK_TRIGGERED. If true, render the actual model name alongside the requested one. Do not hide the swap in a collapsed metrics panel. Surface it at the same level as the model badge that currently lies.
Provenance