Render one scripted chat turn to a file — the plan-218 acceptance capture.
Purpose
-------
Plan 218's acceptance target is the operator's layout mock at
``docs/architecture/Terminal output layout Improvements.txt``. Proving a
render matches it needs a DETERMINISTIC capture of the same event
sequence, taken twice: once on the pre-218 tree and once after, so the
report can show them side by side.
This script drives a presenter through exactly the mock's sequence —
welcome banner, the two pre-turn notices, the session-start rule, the
prompt echo, one streamed answer, the per-iteration metadata, and the
turn-end rule — with every clock-dependent value injected, so two runs
differ only where the LAYOUT differs.
It runs unchanged on a pre-218 tree: hooks plan 218 adds are called
through ``getattr`` guards, so the "before" capture is taken with the
same script as the "after" one.
Responsibilities
----------------
- :func:`render` — drive one presenter and return the captured text.
- :func:`main` — write the rich and plain captures to a UTF-8 file.
Diagnostics
-----------
Domain: OC_CHAT.MAIN
Levels:
L2 — lifecycle events
L3 — semantic details
L4 — deep tracing
Contracts
---------
- Deterministic: timestamps, token counts and durations are fixed
literals; the only variable is terminal width, which is a parameter.
- Console output is ASCII-only (the capture itself is UTF-8 and goes to
the ``--out`` file) so the script is safe under a cp1252 console.
- Read-only with respect to the app: it constructs presenters directly
and never touches a session, the registry, or the network.
Dependencies
------------
- oc_diagnostics (structured debug logging via _dbg)
- rich.console (lazy; Console, which renders the rich capture into a string buffer at a fixed width)
- oc_chat.core.iteration_stat (lazy; IterationStat, the pinned record the per-iteration metadata line reports)
- oc_ui.terminal.statusline (lazy; StatusBarState, the pinned status snapshot bound to each presenter)
- oc_ui.terminal.rich_presenter (lazy; RichPresenter, the rich presenter under capture)
- oc_ui.terminal.presenter (lazy; ConsolePresenter, the plain presenter under capture)
- oc_ui.terminal.input (lazy; build_prompt_prefix for the prompt echo line)
- rich.text (lazy; Text, so the prompt echo prints without markup parsing)