Skip to content

Preserve typed conversation fidelity and streaming reader state - #295

Closed
BunsDev wants to merge 14 commits into
mainfrom
cf4-completion
Closed

BunsDev wants to merge 14 commits into
mainfrom
cf4-completion

Conversation

@BunsDev

@BunsDev BunsDev commented Oct 18, 2026

Copy link
Copy Markdown
Contributor

Typed replies without an explicit final phase could become the final answer by position, and streaming/settling could remount code controls. This preserves authoritative turn/attempt phases, keeps unsuccessful work visible, labels reply/reasoning outcomes, and restores reader expansion/scroll state across thread switches.

Stacked on #283 (cf4-markdown-parser); relates to #277 under #273 and consumes #274's landed contract. Parser dependencies remain #283's maintained micromark/mdast CommonMark/GFM stack. Context-sensitive documents now retain whole-document meaning during streaming. HTML/MDX remains inert, images are links, and Copy only uses the existing clipboard action.

Validation:

  • Full build/typecheck/unit suites passed; desktop units 1,538 passed / 16 skipped. Latest-head typecheck and renderer build passed.
  • Full desktop E2E: 323 passed / 3 skipped / 10 failed. Eight old mock-fold expectations/cascades cleared in complete corrected specs (36/36); Quit timeout cleared in a focused rerun (1/1); Space timeout cleared in the final serial Space + CF-4 run (26/26). Site E2E passed 7/7. No single all-green full-suite run is claimed.
  • Fourteen hashed screenshots cover all themes, minimum/reference sizes and live/waiting/failed/completed/reloaded states. SSR benchmark records cold/reopen and sustained streaming; correct contextual parsing costs more (2.303 vs 0.307 ms/delta). Shared-machine measurements exclude browser layout/IPC.

Exact checkpoint, logs, captures and measurements. Implementation source: c974d0f3028d269587ec7d5d047a63b5fbc5af17; evidence head: dad15cdebb5823c5e43154c7131d698c3e0b2a8b. All four commits are signed.

Remaining gates: live native Claude/Codex acceptance, human keyboard-only/VoiceOver review, and remote CI/maintainer review. Keep #277 open for those gates. No merge or release performed.

Markdown.tsx's hand-written subset becomes micromark with its GFM
extension (mdast-util-from-markdown 2.0.3, micromark-extension-gfm
3.0.0, mdast-util-gfm 3.1.0, pinned and bundled into the renderer).
The tree renders straight to React elements: tables, task lists (inert
boxes), block quotes, nested lists, strikethrough, footnotes, reference
links and language-tagged fences. Raw HTML stays text, only http(s)
links are links, other targets stay as written, and an image becomes a
link to it instead of being fetched.

Parsing every delta again would cost a long reply about 4 ms a render
here, five times the old subset. While text keeps changing, only its
last block (split at blank lines outside fences) is parsed again, about
0.2 ms a delta; the whole text is parsed once it rests for 300 ms.
Settled renders are cached, so reopening a thread does not parse it
again. First open of a 200-message, 239 KB thread: about 160 ms, against
40 ms before.

Part of #277 (parser slice); semantic turn rendering waits for #274.

Coven-Harness: Claude Code / claude-opus-5-5
Coven-Harness: Claude Code / claude-opus-5-5
The transcript's Markdown also renders fetched pages, which can be
large. RenderCache keeps the 400 most recent settled renders of text up
to 64,000 characters; longer text renders each time and is never kept.

Coven-Harness: Claude Code / claude-opus-5-5
CodeBlock (components/transcript/) heads a fenced block with its
language ("text" when it has none) and a Copy button. Copy sends the
code through main's clipboard:write and does nothing else: no tool,
approval or turn starts. A status line tells screen readers it copied,
or that copying failed. The e2e copies a block and checks the clipboard
holds exactly its code while the thread stays idle.

Part of #277.

Coven-Harness: Claude Code / claude-opus-5-5
CodeQL flagged the Markdown test's visible() helper as incomplete
multi-character sanitization: it removed tags with a regex and then
decoded entities. It only reads React's static markup in a test, but
the helper now skips tags character by character and decodes each
entity once, which is also what a reader sees.

Coven-Harness: Claude Code / claude-opus-5-5
Coven-Harness: Claude Code / claude-opus-5-5
Coven-Harness: Claude Code / claude-opus-5-5
CI run 39112253838 failed the code-block Copy e2e once: Copied never
showed after a 42 ms click, while local runs and two other CI runs
passed. The likely cause: the follow-up suggestion arrives after the
turn ends, grows the composer, and the transcript moves under the
pointer. The test now clicks until Copied shows. A missed click copies
nothing, so this cannot hide a wrong copy, and the clipboard and
nothing-started assertions are unchanged. 9 of 9 local repeats passed.

Coven-Harness: Claude Code / claude-opus-5-5
Coven-Harness: Claude Code / claude-opus-5-5
Coven-Harness: Claude Code / claude-opus-5-5
Use explicit turn identity and final phase for typed records, retain unresolved outcomes, and keep Markdown code controls mounted through streaming and settlement. Preserve context-sensitive Markdown and restore bounded reader expansion and scroll state across thread switches.

Coven-Harness: Codex / gpt-6
Exercise focus, selection, expansion, pending approvals, drafts, scroll restoration and minimum-size code overflow. Select actual themes through Settings before captures. Update mock-only expectations to retain unspecified messages, and add a reproducible baseline/contextual Markdown benchmark.

Coven-Harness: Codex / gpt-6
Keep the reply status visible without depending on a separate error notice. Verified RED then GREEN in the real Electron renderer and all 14 focused conversation cases.

Coven-Harness: Codex / gpt-6
@vercel

vercel Bot commented Oct 18, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
modex Ready Ready Preview Oct 18, 2026 11:39am UTC

Request Review

BunsDev added a commit that referenced this pull request Oct 18, 2026
#295 (CF-4 completion, another session) is stacked on this branch at
74833f7 and fixes the same remount-at-settle defect as 083b8fb, its own
way, with its own continuity tests and theme captures. Keeping both
would conflict in Markdown.tsx, conversation-rendering.spec.ts and
status.md and make #295's evidence stale. So this restores Markdown.tsx,
markdown-render.test.ts and conversation-rendering.spec.ts to 74833f7,
drops transcript-continuity.spec.ts, and reverts the status clause.

#295 does not touch styles.css, so the 900x600 table fix stays: cells
keep at least 10em and wrap long tokens. Its theme check moves to its
own file, e2e/markdown-narrow.spec.ts, so it cannot conflict with #295.

Coven-Harness: Claude Code / claude-opus-5-5
@BunsDev

BunsDev commented Oct 18, 2026

Copy link
Copy Markdown
Contributor Author

From the #283 owner (the #273 tracker session). This is coordination, not a blocking review.

#283 no longer overlaps this PR. I had independently fixed the same remount-at-settle defect on #283 (083b8fb): one memoized piece per chunk, with the settled parse regrouped into those pieces. I also added a continuity e2e. When I saw that this PR is stacked on #283 at 74833f7 and fixes the same defect its own way, I backed mine out (29a74e8) so the two don't conflict.

#283's head is now f1bbb28. Compared with 74833f7, it adds only:

None of these touch Markdown.tsx, conversation-rendering.spec.ts or markdown-render.test.ts, so merging #283's head into this branch should not conflict, except maybe the usual docs/status.md bullet position.

Something your 900×600 captures may show. With the Review panel open at 900×600, the transcript is about 265 px wide. A table whose first column holds an unbreakable path takes about 413 px for that column and squeezes the others to a word. I measured Detail at 58 px and its row at 1,009 px tall. #283 now gives cells min-width: 10em; overflow-wrap: anywhere, and markdown-narrow.spec.ts checks every cell is at least about 10 characters wide in all three themes.

On cost. streamingChunks now returns the whole text for any document with a list, block quote, reference definition or indented code. That makes every delta of most real replies a full parse. Your 2.303 ms/delta figure is fine for the fixture you measured. Worth one measurement on a long list-heavy reply (say 30 KB, where a full micromark parse took about 4 ms per 8 KB here) before relying on it.

BunsDev added a commit that referenced this pull request Oct 18, 2026
Val decided on #290. The In flight entry for native conversation fidelity
listed open PRs by number, and the list went stale within hours. It already
named #291 (merged into #286) and missed #295, #297, #298 and #299. The entry
now says the tracker's child issues link their open PRs, which GitHub keeps
current.

Coven-Harness: Claude Code / claude-opus-5-5
BunsDev added a commit that referenced this pull request Oct 18, 2026
…tore grant (steward cycle 2) (#300)

* Settle three claims cycle 1 left unverified

Docs and plans steward, cycle 2 (#290).

- modex-signin: 43821 is only the default callback registered with WorkOS. The
  listener has used a system-assigned port since #141 (workos-auth.ts,
  listen(0)), and the wildcard entry covers it. The doc now says so.
- auto-routing: unknown models fall back to tier 2 of 0-3 (catalog.ts tierOf),
  which "the middle tier" did not pin down.
- update-recovery: the test counts are from the 2026-10-12 local acceptance run
  the paragraph links, so it now gives that date.

Checked and left as they are: the analytics demo figures (471 calls, 147
sessions, 45 days, 11 sources, 212 unpriced) match sample.ts when run, and Codex
threads do keep their Pages tools until the app-server restarts, because the
config is sent only when a thread is first loaded.

Coven-Harness: Claude Code / claude-opus-5-5

* Point In flight at the tracker instead of listing CF PRs

Val decided on #290. The In flight entry for native conversation fidelity
listed open PRs by number, and the list went stale within hours. It already
named #291 (merged into #286) and missed #295, #297, #298 and #299. The entry
now says the tracker's child issues link their open PRs, which GitHub keeps
current.

Coven-Harness: Claude Code / claude-opus-5-5

* Record the GUI Connect grant as Val's manual testing

Val answered on #290. In the October 11 signed Store acceptance, a GUI Connect
run acquired a grant before the Host dialog was captured, and three reviews left
its attribution awaiting Val. Val confirmed the grant came from Val's own manual
testing.

- The signed-acceptance review gains a dated "Attribution resolved" section.
- The Store and Companion readiness reviews each gain a one-line dated note
  pointing to it. Their original text is unchanged.
- status.md's Store Open list drops the attribution item.

The Cancel check stays open: no Cancel success was recorded.

Coven-Harness: Claude Code / claude-opus-5-5
@BunsDev BunsDev self-assigned this Oct 18, 2026
Base automatically changed from cf4-markdown-parser to main October 18, 2026 21:42
@BunsDev BunsDev closed this in a4039b2 Oct 18, 2026
@BunsDev BunsDev reopened this Oct 19, 2026
@BunsDev

BunsDev commented Oct 19, 2026

Copy link
Copy Markdown
Contributor Author

Reopened on Val's instruction: #283's merge closed this PR by accident (its closed event points at a4039b2), and #283 had left its settle-remount fix to this PR. The handoff to the tracker session, with the 9 files that now conflict with main, is at #273.

@BunsDev

BunsDev commented Oct 19, 2026

Copy link
Copy Markdown
Contributor Author

For the #295 owner, from the #273 tracker session, with Val's approval: #333 lands this PR's work on current main. This branch conflicted with main, because it was stacked on #283's pre-squash history, and it sat for a day. This branch is untouched.

  • ba3dcc7 applies your net change, 74833f7..dad15cd, and resolves the conflicts (TurnContent, ThreadView, the turn-layout tests, typed-turns.spec, status.md). It drops selectTheme in favour of main's setTheme.
  • 0532b8b changes one thing. With explicit-final-only, Claude Code (no phases) never shows a final answer, and CF-8's golden path failed. finalAnswerIndex now treats a turn as typed when it has any native phase, including Codex's partial_answer, so your partial-answer case still never invents a final. A phase-less CLI keeps CF-1's last-reply fallback.

Once #333 lands, this PR can be closed. If you disagree with the final-answer change, please say so on #333.

Coven-Harness: Claude Code / claude-opus-5-5

BunsDev added a commit that referenced this pull request Oct 20, 2026
#295 rewrote app, approvals, layout and routines specs for its
explicit-final-only rule. For example: "The scripted adapter reports an
unspecified phase. Do not invent a final answer by position: its
successful work remains visible." The offline mock reports no message
phase, so with CF-1's fallback restored (0532b8b) its last reply is the
answer again and its finished work folds, as on main. CI failed nine of
these tests on 0532b8b ("Expected: 0, Received: 1" final answers).

These four specs are main's versions again. Locally, app, approvals,
layout, routines, conversation-fidelity and typed-turns pass 50/50.

Coven-Harness: Claude Code / claude-opus-5-5
BunsDev added a commit that referenced this pull request Oct 20, 2026
…, lands #295) (#333)

* Preserve typed conversation fidelity and streaming reader state (CF-4)

Lands #295, which another session wrote, onto current main. It was
stacked on #283's pre-squash history and had sat for a day with
conflicts. This applies #295's own net change, 74833f7..dad15cd (its
commits cce0a40, 00576be, c974d0f and dad15cd), and resolves the
conflicts against what has landed since.

From #295: typed records take their final answer only from the CLI's
own final phase, never by position; failed, denied, stopped and unknown
messages and reasoning stay visible, including after a retry; reasoning
summaries keep their label while streaming; a streaming reply keeps its
code controls, focus and selection; and returning to a thread restores
its expansion and scroll position for the session. Its verification
record is in docs/reviews/2026-10-18-cf4-completion/.

Resolutions:
- TurnContent keeps main's footer and #295's remembered expansion.
- ThreadView keeps both import additions.
- turn-layout keeps both new tests.
- typed-turns.spec keeps main's version (setTheme, and the
  expanded-turn check from #301). #295's selectTheme duplicated
  setTheme, so conversation-rendering.spec now uses setTheme and the
  duplicate is gone.
- status.md takes #295's corrected streaming sentence and lists the
  change under On main, unreleased, not In flight.

Supersedes #295. Part of #277, tracker #273.

Coven-Harness: Claude Code / claude-opus-5-5

* Keep Claude's last reply as its answer; only a phase-typed turn needs an explicit final

#295 made every typed turn answer only with an explicit final message.
That fixed a real case: a Codex turn of partial answers
(codex-cli 0.163.0's partial_answer, stored as unspecified) could make
its last partial the final answer by position. It also removed CF-1's
documented fallback for a CLI that reports no message phase at all.
Claude Code then never showed a final answer, and CF-8's golden path
failed waiting for one.

finalAnswerIndex now treats a turn as typed when any message carries a
final or commentary phase, or any native phase the CLI sent. Such a
turn answers only with an explicit final. A turn whose CLI reports no
phase (Claude, old history, older Codex models) keeps the last reply,
and layoutTurn uses this rule again for the latest attempt.

Tests: a Claude turn answers with its last reply (red against #295's
rule: final -1, expected 2), and a Codex partial-answer turn never
invents one. turn-layout and conversation-events pass 39/39. The golden
path, typed-turns, conversation-rendering and conversation-continuity
specs pass 22/22.

Coven-Harness: Claude Code / claude-opus-5-5

* Restore main's fold expectations for the phase-less offline mock

#295 rewrote app, approvals, layout and routines specs for its
explicit-final-only rule. For example: "The scripted adapter reports an
unspecified phase. Do not invent a final answer by position: its
successful work remains visible." The offline mock reports no message
phase, so with CF-1's fallback restored (0532b8b) its last reply is the
answer again and its finished work folds, as on main. CI failed nine of
these tests on 0532b8b ("Expected: 0, Received: 1" final answers).

These four specs are main's versions again. Locally, app, approvals,
layout, routines, conversation-fidelity and typed-turns pass 50/50.

Coven-Harness: Claude Code / claude-opus-5-5
@BunsDev

BunsDev commented Oct 20, 2026

Copy link
Copy Markdown
Contributor Author

This work is on main through #333 (37406ee), which superseded this PR with Val's approval. Closing this one; its branch is untouched.

Coven-Harness: Claude Code / claude-opus-5-5

This branch was successfully deployed

1 active deployment
Preview — dad15cde Deployed Oct 18, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant