fix(chat): avoid dirty placement IDs for equal height reports
Equal DOM height confirmations currently mark rows dirty even when the state updater keeps their existing measurement. This makes later placement consider unchanged rows. Mark only entries that differ from the state React applies the updater to.
Keep scheduling equal corrective reports: a lower-priority height of 200 can still be queued while the rendered height is 100. Dropping a new report of 100 against the rendered value loses that correction. The regression reproduces this with React's real priority queues; enabling the naive guard makes the final height incorrectly become 200. Row pruning and Minimal Mode also write this state, so this change deliberately leaves scheduling intact.
Leo: “i also think we've done a lot of great work wrt perf and loading but i don't think we've pushed to the limit yet. things should be instant and not shift layouts AND not take many resources”.
The change stays inside flushDrawn's equality/dirty-marking lines. #33624 (80865735, mounted measurement batching) and #33629 (9e3e8347, first motion) were inspected: neither edits that body, so this is based independently on 5dee1ab988e. No new loop, observer, timer or cache. Settled transcript geometry and design/chat-transcript.md remain unchanged. The overbroad dirty marking originated in #19648.
Performance
Same production-callback React harness, 120 equal-height confirmation ticks. These are bookkeeping counts, not browser CPU or frame-time measurements.
| Metric | Before | After | Delta | Harness or run link |
|---|---|---|---|---|
| Dirty IDs accumulated across 120 confirmation ticks | 120 | 0 | -120 | webviews/test/drawn-height-priority.test.tsx |
| setDrawn calls per confirmation tick | 1 | 1 | 0 | same harness |
| Extra renders per confirmation tick | 0 | 0 | 0 | same harness |
The idle CPU increase tracked by #33368 remains unresolved; this PR makes no claim about it.
Validation: focused single-file unit test: 3 passed, 9 assertions. Base: equal/mixed dirty-ID cases fail. Naive rendered-value guard: priority regression fails (200 instead of 100). Fleet replay, compile check and the finished webview verdict will be recorded before landing. Risk: changed IDs must survive React's updater rebasing; correction scheduling is preserved and tested.
🤖 Generated with Codex
Agent session: agent session
![Autofix with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-dark-3x.png)
Open in [code]smith · Need help on this PR? Tag @codesmith-bot with what you need.
Summary by cubic
Fixes equal-height transcript confirmations marking rows dirty, so placement no longer reprocesses unchanged rows (120 dirty IDs per run drop to 0).
The equality check now runs inside React's state updater against the rebased state rather than the last committed measurement, so an equal report can still supersede a lower-priority height queued in another lane; scheduling is deliberately preserved.
Adds a test harness that compiles the production flushDrawn callback through node vm, covering idle equal confirmations, mixed batches, and the lower-priority correction regression.
Performance
Same production-callback React harness, 120 equal-height confirmation ticks. These are bookkeeping counts, not browser CPU or frame-time measurements.
| Metric | Before | After | Delta |
|---|---|---|---|
| Dirty IDs accumulated across 120 ticks | 120 | 0 | -120 |
| setDrawn calls per tick | 1 | 1 | 0 |
| Extra renders per tick | 0 | 0 | 0 |
Validation: focused single-file unit test, 3 passed and 9 assertions.