Terra round fix list (batch; do not edit the repo while local-test.ts runs against it)

1. [low, latent, verified in code] src/llm/openaiResponses.ts:41-48 assistantItems: the engine streams every output_text delta into one text (queryEngine.ts:1721 text += delta), and parseResponse joins a message's parts with ''. assistantItems compares that history text with native output_text parts joined by '\n', so a reply with 2+ text parts or message items never matches and its encrypted reasoning is silently not replayed. Fix: compare both sides joined with '' and, when they match, replay each native message item's own text in its own place. Add a unit test (two message items around a function_call; one message with two parts).
   Not seen live: all 151 terra messages matched (one text part each).

2. [low, catalog] src/shared/contextWindows.ts: gpt-6.1-terra missing -> 200K fallback. Official page (developers.openai.com/api/docs/models/gpt-6.1-terra, read 2026-10-30): context window 1,050,000; max input 922,000; max output 128,000; long-context tier >272K at 2x input/cache, 1.5x output (matches pricing.ts). Add 'gpt-6.1-terra': 922_000 (published max input, used as the combined budget, conservative) with the dated source; add the URL to docs/research/context-usage.txt.
3. [low, catalog; g8 terra max: 37 requests, 32,129 output tokens in total, no cutoff] src/shared/outputLimits.ts: gpt-6.1-terra missing -> max output 32768 at every effort (OUTPUT_BUDGET high 96000 / max 128000 is clamped by the unknown-model 32K ceiling). Reasoning at high/max effort can be cut off by the 32K cap. Add 'gpt-6.1-terra': 128000. Check g8 on terra (max effort) for incomplete/length stops.
4. [harness] runner: for terra, run c1-c3 with GCODE_CONTEXT_LIMIT ~45000 so context-full, mid-turn auto-compaction and the 'stop' choice are exercised (terra tokens ≈ 0.736 × Claude's). Haiku keeps 60000.
=> These change OpenAI-path behaviour: rerun terra 58 on the final snapshot as well as Haiku 58.

STATUS 2026-10-30 (repo edited after the local tests ended):
- 1 DONE: openaiResponses.ts assistantItems compares texts without separators and replays each native message text in place; test 'a reply of several text parts still replays its reasoning, each text in its place' (tests/openai-responses.test.ts) 5/5.
- 2+3 DONE: contextWindows 'gpt-6.1-terra': 922_000, outputLimits 'gpt-6.1-terra': 128000, source URL in docs/research/context-usage.txt; test in tests/model-tables.test.ts 3/3. Desktop imports the shared table (Settings.tsx:27).
- 4 DONE: runner.ts CONTEXT_LIMITS terra c1-c3 = 45000.
- d2 exit code x3: NOT changed (decision): the error line feeds the desktop error and the session-memory first line; dropping the code there loses user-facing info, and removing the 'Exit code' line would need a heuristic. Cosmetic, report only.
- root tsc ok.

5. [HIGH] images.ts visionCapabilities: add gpt-6.1-terra (official: input text+image) with the OpenAI policy. Test: capabilities, FileRead returns an image block, Responses buildBody sends input_image (user message and tool result).
6. [low] FileReadTool: an image with no vision says the model cannot receive images (not 'Binary file detected'); update tests/desktop-fixes-c.test.ts.
7. [MEDIUM] observations.ts text: <br> and block boundaries read as whitespace, display:none skipped, then shownText; plan.ts describe; real-browser test.
=> full suite was stopped mid-run (repo changing); rerun after 5-7.
STATUS 5-7 DONE: images.ts gpt-6.1-terra vision (OpenAI policy), test 'GPT-6.1 Terra takes images…' (input_image in user message and after function_call_output); FileRead image without vision -> 'Image file (.png): the current model cannot receive images…' (desktop-fixes-c test updated); observations.ts renderedText (<br>, block edges, display:none skipped, letters as written) + plan.ts describe + real-browser test 'reads a line break and block edges as spaces' (browser-v2 8/8 with GCODE_BROWSER_TEST=1); browser runtime rebuilt (worker.mjs has renderedText). root tsc ok.
