emrg: composer draft via separate store channel (no transcript re-render per keystroke, #1100) - #1106
Conversation
… re-render per keystroke, #1100)
argszero
left a comment
There was a problem hiding this comment.
✅ LGTM — cycle cyc20260902-125430
Reviewed the full diff + verified locally on the branch (typecheck clean, full renderer suite 499 passed incl. 21 transcript tests; Agent.md breakdown accurate).
- Design is sound: Composer.tsx reads the draft only in event handlers (onCreate / session-switch effect) — the editor owns its live display, so no render path depends on main-channel notifications for draft writes. Moving setComposerDraft to a dedicated channel (subscribeDraft/getDraftVersion, own counter) correctly stops per-keystroke TranscriptView re-renders without breaking draft persistence/restore semantics.
- mutateDraft/notifyDraft cleanly isolate the two counters; unsubscribe works; the added tests cover channel isolation in both directions (main silent on draft writes, draft version untouched by main mutations).
- CI test + test-windows both pass (33590826243).
argszero
left a comment
There was a problem hiding this comment.
✅ LGTM — cycle cyc20260902-134030
Re-reviewed head 86f5a20 (unchanged since the 1/3 review) as an independent cycle.
- Re-verified locally on the branch: typecheck clean; full renderer suite 499 passed (45 files), incl. the 2 new transcript channel-isolation tests (21 total).
- Design re-confirmed: setComposerDraft now routes through mutateDraft → only draftVersion bumps and only draft subscribers fire; main-channel listeners stay silent on keystrokes, so TranscriptView no longer re-renders per keystroke. subscribeDraft/getDraftVersion symmetry with the main subscribe/getVersion pair is clean; unsubscribe path correct.
- Agent.md count 497→499 consistent with actual suite output; CI test + test-windows both pass (33590826243).
argszero
left a comment
There was a problem hiding this comment.
✅ LGTM — cycle cyc20260902-140135
Third consecutive approval (cyc125430 1/3, cyc134030 2/3, this cycle 3/3). Head 86f5a20 unchanged, CI test + test-windows both pass (33590826243), mergeable CLEAN. Code previously verified in depth on this exact head (typecheck clean, full renderer suite 499 passed incl. 21 transcript tests; Agent.md counts consistent). Merging.
Summary
Implements the secondary item flagged in issue #1100 (noted in my #1101 feedback): Composer draft writes currently go through the shared transcript store's main mutation path, so every keystroke bumps the store version and re-renders the whole transcript (
TranscriptViewsubscribes tostore.getVersion). Typing cost was O(transcript) per keystroke.Changes
emrg/gui/renderer/src/lib/transcript.ts: the transcript store now exposes a dedicated draft channel —subscribeDraft(listener)+getDraftVersion(), backed by its owndraftVersioncounter and listener set.setComposerDraftwrites throughmutateDraft()(bumps onlydraftVersion, notifies only draft subscribers) instead ofmutate()(mainversion+++ full notify).getComposerDraft(sid)still reads on demand, per-session draft persistence (rant 2026-09-01T20:28:31) intact, session-switch restore inComposeruntouched.transcript.test.ts: +2 tests — draft writes do not bump the main version / do not notify main subscribers while the draft channel fires and increments independently; main-channel mutations do not bumpdraftVersion(channels fully decoupled, unsubscribe works on both).Agent.md: renderer count 497 -> 499 (transcript 19 -> 21).Verification
tsc --noEmit: cleannode --test: 101 tests / 93 pass / 0 fail / 8 skip (unchanged)import emrg+python -m emrg --help: OKWhy this design