End-to-end probe of a 2-way parallel-calls Codex turn revealed the
visible assistant message looked like:
<synthesis text>
[Codex tab 1/2]
<tab 1 text>
[Codex tab 2/2]
<tab 2 text>
--- Synthesis ---
The synthesis came first (no label), then the tabs, then a trailing
"--- Synthesis ---" line with nothing below it. The header comment in
chat-adapter.ts said the intent was "[tabs] ... [synthesis]" but the
implementation prepended cumulativeText (which carries the synthesis
deltas the backend emits after codex_gather) before the tabs.
Fix: split renderCodexBuffer into renderCodexTabsBlock (pure per-tab
rendering, no trailing divider) and reorder renderFullContent so when
Codex fan-out is active the output is:
[Codex tab 1/N]
<tab 1>
[Codex tab N/N]
<tab N>
--- Synthesis ---
<synthesis text from cumulativeText>
The non-Codex case still returns cumulativeText unchanged.