Skip to content

fix(ui): simplify transcript geometry and preserve native scrolling - #5315

Merged
Astro-Han merged 47 commits into
mainfrom
fix/transcript-viewport-mounting
Sep 15, 2026
Merged

Astro-Han merged 47 commits into
mainfrom
fix/transcript-viewport-mounting

Conversation

@Astro-Han

@Astro-Han Astro-Han commented Sep 14, 2026

Copy link
Copy Markdown
Contributor

Problem and behavior

Cold upward traversal could change the reader during a held native scrollbar drag. Estimated row sizes changed the geometry independently of range publication, while application scrollTop compensation also changed Chromium's pressed-thumb origin. Deferring publication avoided some replacements but left reachable blank remembered space and did not resolve cold layout changes.

I replaced the second geometry system with a bounded window of real rows. The existing data window owns residency; Chromium owns native input and reading anchoring away from the scroll origin. At scrollTop zero, where Chromium does not establish an anchor, the existing scroll authority preserves the connected first row across synchronous publication. Explicit navigation and tail following take precedence over that correction. History publishes during input, while eviction waits for input to finish. Focus and selection protect their rows until released.

Visible readers request 16 KiB pages through the existing recovering-reader adapter instead of using the 128 KiB transport-fragment ceiling as a rendering batch. Background projections retain their original budgets, and the Host still completes oversized boundary Turns. No new dependency, geometry cache, publication buffer, or disclosure-state cache is introduced.

Other changes retained in this PR reduce redundant reasoning projection, defer tool-group bodies until first expansion, replace CSS Highlight work with span highlighting, and reuse unchanged prompt-rail items. Integration preserves #5301's final-reply/disclosure behavior and WorkHub accents.

The native scrollbar now describes the resident data window. Loading or evicting actual rows legitimately changes its extent; this is not a promise of a fixed whole-session thumb. Offscreen read-only disclosure state may reset when its data window is evicted, as previously accepted.

Discriminating experiments

  • Real rows with application anchor compensation still replaced the visible reader. Removing that compensation and allowing native anchoring preserved identity and position.
  • Native anchoring alone failed the exact-origin story by 5311 px and chained eight unnecessary history batches. Changing only the starting offset from zero to one pixel passed; disabling native anchoring at one pixel reproduced the failure. The correction is therefore confined to the origin, without shifting the starting position or restoring general compensation.
  • Keeping estimated virtualization with native anchoring still produced up to tens of pixels of cold correction. Removing the estimate/placeholder system eliminated that source of geometry change.
  • Evicting during a held drag could move toward newer Turns while dragging upward. That candidate was rejected; eviction remains input-aware.
  • Rendering the full 128 KiB batch introduced approximately 141 ms long tasks. In alternating trials in one Electron instance, a 16 KiB real-row reader removed those long tasks. Navigation task time was about 127 ms versus 121 ms for the virtualized reference; wall time was about 278 ms versus 231 ms. This is a continuity/simplicity tradeoff, not a claim of a navigation speedup.
  • Cold native input passed at 4x CPU with ordinary and 10x-length text, including held reversal and release. The committed regression no longer premeasures resident history and checks every observed stationary frame, Turn identity, direction, actual held publication, release continuity, and return to latest.

Validation

  • Production UI/Desktop builds and all four Desktop typechecks passed.
  • UI suite: 475 passed. Relevant Desktop range/navigation/WorkHub tests: 70 passed; the final reader-versus-background budget assertions also passed.
  • Native held-drag regression passed three repeated runs, plus final-source acceptance. All local Electron runs were hidden.
  • The exact test failing in CI run 34922024104, Host history paging/reader continuity/return to latest, passed on the new implementation.
  • Storybook continuity/selection release, tail affordance, initial history filling, and nested scrolling passed.
  • Full Storybook smoke passed: 364 stories / 393 theme renders. The continuity story now uses one round trip and an actual traversal away from the selected row, instead of repeated measured-height round trips and relying on the origin bug to move the reader. Its 15-second budget is unchanged. Extreme 12x CPU throttling can still exceed that budget; this is not a claim of an unrestricted timing guarantee.
  • The strengthened Electron regression rapidly reaches the actual origin (asserted), reverses twice, and tracks the same reader throughout each hold. Two normal and two 4x CPU runs passed. Subpixel exposure of a preceding row does not change the chosen anchor; every observed held/release frame still requires at most 1 px displacement.
  • Headless native-wheel probes passed for ordinary and mixed content: zero blank frames, zero stable-membership cold height change, maximum reverse glyph movement 0 / 0.59 px. Repeat traversal at 900 and 1352 px retained identical final extents.
  • E2E budget remains 38 tests / 22 files. Retired estimated-height/observer tests and the delayed-placeholder-only probe were removed; the actual reading and bounded-window assertions remain. Generated Astryx inventory was refreshed after file removal.

Earlier approvals and remote CI apply to earlier heads. Fresh CI and external review are required for this update.

Keep the subject outside :where(ancestor *) in four generated Astryx rules. Matching, specificity, declarations and rule order stay equivalent, while ancestor :has matching no longer uses a universal descendant subject.

Validated dynamic focus/divider/header/footer states, 19 Storybook checks and six native history traversals. Paired real Host CPU4 traces and independent group reversions reproduce the style/layout cost. No new scroll state or estimate policy.
Preserve process disclosure, WorkHub accents and focus-aware navigation alongside virtual Turn mounting. Regenerate architecture and surface inventories.

Generated-by: OpenAI Codex
Read the rendered inter-block margin in pixels instead of parsing a CSS custom-property recipe. Keep fallback sizing until a measurable sample exists.

Generated-by: OpenAI Codex

@hqhq1025 hqhq1025 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Technical NO-GO: one P2 remains in the native-scrollbar history path. The change now publishes Host pages during active input, but the visible reading position is not preserved throughout the hold; the revised E2E only establishes recovery after release.

I reviewed the full 44-file diff, including virtual row mounting and height estimation, scroll/navigation authority, prompt/tool rendering optimizations, Storybook fixtures, and both performance harnesses. Local validation passed: build:test; UI 474/474; Desktop 2498/2498; full typecheck, lint, format, ASF, renderer architecture 112/112, E2E budget 38, Astryx inventory, production renderer and Storybook builds; the revised Electron scroll/Side Chat cases 2/2; the two-scene scroll-window run; the real-Host scroll-input run 1/1 with three trials; diff check; and a clean merge tree with current main 5f4614bfd. windows_recovery is green; required hosted test was still running at publication.

The performance harness records timing (the real-Host run observed 74-84 ms maximum long tasks and 101-133 ms maximum frame gaps here) but explicitly defines no performance threshold, so I treated it as diagnostic evidence rather than a regression gate. I did not exercise native Windows/macOS or a physical touchpad.

Automated review notice: This comment was posted by an automated review agent operated by hqhq1025. It is not an independent human review and does not replace one.

Comment thread packages/ui/src/transcript-scroll-authority.tsx Outdated

@jackwener jackwener left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Independent agent review — scope: the immediate-publication (wheel/touch) input path and transcript content/state. Reviewed at 4596ed40c8e8c570f1291bb1d692806e4cac4111. I am an AI agent (executing seat @kabi-opus) publishing through a shared GitHub account; this is an automated review, not a human sign-off. The held-thumb input path and real-Electron interaction coverage belong to another reviewer and are outside what I verified.

This is a COMMENT, not an approval, and the reason is a capability gap on my side, not a permission limit and not a code reservation. I hold approval rights and am declining to use them here because the interaction testing this scope requires did not run in my environment — see "What I could not verify".

A correction to my own earlier report

I previously attributed the held-thumb reading-position defect to "the anchored Turn is unmounted, so the post-commit querySelector returns null and the compensation silently no-ops". That attribution was wrong. virtual-transcript-turn.tsx:91 sets data-turn-id={mounted ? undefined : turnId} — an unmounted row keeps a placeholder element carrying data-turn-id, so the lookup at transcript-scroll-authority.tsx:147 resolves for any row still in the resident range. next is null only when a row leaves the range entirely or the session changes. I also checked this against the commit where I first reported it: the attribute was already present, and the fix commit never touched that file, so this was my error at the time rather than something the fix changed.

The defect itself was real and independently reproduced. Its actual mechanism is the one the code comment at transcript-scroll-authority.tsx:124 already states: Chromium owns thumb-to-content mapping until release, so a synchronous scrollTop correction cannot survive a range replacement mid-drag. The fix targets that correctly.

Verified — deleted tests are replacements, not lost coverage

This PR deletes 7 tests, 6 of them constraining publication-coalescing semantics (touch waiting for the last contact, held-scrollbar coalescing, edge wheel without scrollend, navigation during a hold, idle admission ordering, held fill before trimming). I compared what each removed test constrained against what now constrains it. Every one has a replacement, and the new names state the new contract directly — wheel and touch publish immediately; a held thumb leaves publication with its owner. This is a deliberate semantic inversion, correctly re-pinned. No finding.

Method note, since it nearly produced a false report: my first pass computed the diff against a stale local main, yielding 252 files and a long list of "deleted tests" that belonged to other merged work. Re-fetching main gave the real scope — 46 files, 1903 insertions, 327 deletions. Nothing from the bad pass was reported.

Observation — the wheel path has no reading-continuity assertion

scripts/perf/scroll-input.spec.ts exercises the wheel path and records publicationsDuringInput as a metric, but asserts nothing about reading continuity; its assertions cover reach, wheel delivery, and mount bounds. The continuity assertions added by this PR are on the held-thumb path. Since commitRange defers only when pointer !== undefined (transcript-scroll-authority.tsx:126) — strictly narrower than isInputActive() at :121, which also tracks gesture and touchHeld — wheel and touch publish mid-gesture by design, and that design is currently unasserted for reading continuity. This is a test-coverage gap, not a demonstrated defect; I could not run the interaction test that would settle whether it is also a live defect.

Observation — the documented cold-history drift bound looks understated

The PR records residual cold-history drift as a few pixels. The bound is actually the estimate error, and the fallback estimate is a constant: use-transcript-known-space.ts:53 uses const estimate = 320 for any row without a computed estimate.

Running the exported estimator directly against representative content:

content estimate
plain paragraph 22px
long plain paragraph 1034px
closed code fence 44px
list / heading / table / unclosed fence / mermaid undefined → falls back to 320

simpleText() additionally requires the turn to have no tools, no notes, a completed status and a single settled text item, so any turn containing tool activity gets no estimate at all. In a real session that is most turns. A first measurement of a tall cold turn above the reader therefore corrects by its full estimate error — for a 3000px turn that is 2680px, not a few pixels. The 320→314 correction reported for the measured case is a short row, which is the favourable end of this range.

I am not claiming an observed jump: whether such a row can sit above the reader at first measurement needs the cold-history interaction run I could not perform. But the invariant's scoping was put up for review, and "a few pixels" describes the measured sample rather than the mechanism's range.

Verified, no findings

  • TurnViewModel.assistantThinking is removed with no remaining consumers; reasoning still renders through the timeline entries, which are the rendering source of truth.
  • virtual-transcript-turn.tsx:56 consumes entries.at(-1) from a batched IntersectionObserver delivery — correct, and covered by a new test.
  • Production code is byte-identical between the previous head and this one; only e2e-budget.json and scroll-geometry.spec.ts differ.

What I could not verify

Real Electron would not launch in my environment: electron.launch timed out at 180s on two runs, stopping after Debugger attached. I ran this repository's own scripts/perf/scroll-input.spec.ts as a control and it fails the same way, so this is environmental rather than a defect in my harness or in the PR. The host has a working window server and sufficient disk, so neither explains it.

Consequently I did not verify, and make no claim about: cold versus warm history drift, reverse-drag behaviour, pagination boundaries, session-switch and navigation races, or any real-device touch behaviour. Those need a reviewer with a working Electron environment. Code review, CI status and merge readiness are separate concerns; nothing here is a statement that this PR may be merged.

@hqhq1025 hqhq1025 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed the native held-thumb path and the current test-only follow-up. The measured-reader E2E now passes locally, but one production-path P2 remains: fast native thumb reversals can render a full viewport of placeholder shells for one frame.

Validation included real Electron/CDP input, the previous known-bad head as a negative control, build:test, the focused scroll suites (39/39), the updated official geometry E2E (1/1), and an adversarial first-read 4,054 px Markdown Turn (2/2 preserved the prior anchor within 0.3125 px). The required hosted test check is still running.

Automated review notice: This comment was posted by an automated review agent operated by hqhq1025. It is not an independent human review and does not replace one.

Comment thread packages/ui/src/virtual-transcript-turn.tsx Outdated
@jackwener

Copy link
Copy Markdown
Member

Correction to my earlier review (@kabi-opus, automated agent review, shared account).

In my review I argued that the recorded cold-history drift of "a few pixels" understates the bound, because the fallback row estimate is a constant 320 (use-transcript-known-space.ts:53) for any turn the estimator declines — which includes every turn containing tool activity. I recommended rewording the PR description on that basis.

I withdraw that recommendation. Another reviewer has since tested it directly: with the first-load turn replaced by a 160-line Markdown list whose real height is ~4054px, the real Host page kept the original anchor within 0.3125px, 2/2. I did not run that experiment myself — I could not launch Electron in my environment, which is why I raised this as an untested hypothesis rather than a finding — so I am relaying their result, not confirming it independently.

The arithmetic I published is still correct and still checkable: the estimate for a list-bearing turn really is the constant 320 regardless of its real height. What does not follow is the step I took next — that a large estimate error becomes a proportionally large reading-position movement. It does not, because the anchor compensation re-aligns the anchored row's top after each publication, so height error above the reader is absorbed rather than shown. Stating the fact was fine; carrying it through to a user-visible consequence without testing that step was not, and a 4054px case is a fair test of it.

The description's characterisation of the residual as small is consistent with the evidence now available. Nothing else in my review depends on this point.

@Astro-Han Astro-Han changed the title fix(ui): stabilize virtual transcript scrolling and reduce rendering work fix(ui): simplify transcript geometry and preserve native scrolling Sep 15, 2026

@hqhq1025 hqhq1025 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed exact head 94a48534bc3d17f71981b57936fea9eb589af438. I found no P0-P2 product blocker in the scoped transcript-scroll paths; one P3 regression-test reliability issue is noted inline.

The change removes estimated-height placeholder virtualization, renders resident Turns as real DOM rows, uses native anchoring away from scrollTop === 0, explicitly preserves the first row at the origin, and delays trimming while input or a history read is active.

Product-path evidence:

  • Four independent visible-window Electron processes used real CDP native-scrollbar input, cold unseen Host history, one continuous held thumb, fast reversals, and 300 ms stationary holds. Each captured 86-96 held rAF samples with zero blank real-text frames; stationary Turn identity and top position stayed within 1 px while the resident range changed.
  • At least two runs captured the three-condition origin case: pointer held at scrollTop === 0, a Host prepend caused the JavaScript correction, then a further held native reversal moved correctly toward newer Turns. The proposed pressed-thumb-origin failure did not reproduce.
  • The two prior P2s (a blank viewport during reversal and reader displacement during held publication) therefore did not reproduce on this head.

Checks: UI dist 475/475; focused Desktop transcript/navigation/scroll 89/89; official geometry E2E visible 3/3; hosted test and windows_recovery succeeded; git diff --check passed; the PR base is an ancestor; a merge tree against current main 72cd8b1f532872ef1bcca875a7a7cae4e7b1448e was created successfully.

Unverified: physical macOS/Windows scrollbar behavior, touch input, and accessibility-driven scrolling were not independently exercised.

Automated review notice: This comment was posted by an automated review agent operated by hqhq1025. It is not an independent human review and does not replace one.

Comment thread apps/desktop/e2e/scroll-geometry.spec.ts Outdated

@jackwener jackwener left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Independent agent review — code and local-suite cross-verification only. Reviewed at 94a48534bc3d17f71981b57936fea9eb589af438. I am an AI agent (executing seat @kabi-opus) publishing through a shared GitHub account; this is an automated review, not a human sign-off.

This is a COMMENT and not an approval, because the thing this PR fixes is the one thing my scope cannot reach. Reading-position preservation is now delegated to the browser's native scroll anchoring, and the new scroll-origin correction interacts with Chromium's pressed-thumb input origin. jsdom has no layout, no scroll anchoring and no scrollbar thumb, so both are unverifiable in unit tests by construction — the new test name says as much: range publication leaves native input and reading geometry with the browser. It asserts that the code does not interfere, not that the position is kept. Real Electron would not launch in my environment, so I did not verify the PR's central claim. That is a capability limit, not a code reservation and not a permissions limit.

Verified from source

Each architectural claim in the description matches the tree:

  • The estimated-height ledger, the placeholder row and the separate body virtualization are gone — not merely unreferenced. transcript-height-estimate.ts, use-transcript-known-space.ts and virtual-transcript-turn.tsx are absent from the tree, and data-virtual-placeholder / hasRenderedTurn have zero occurrences repository-wide. (A git diff --name-status against the merge base shows no deletions here, because those files only ever existed on earlier heads of this branch; presence in the tree is the check that actually answers the question.)
  • History publishes during input: commitRange no longer gates on a held pointer.
  • Eviction waits for input: use-chat-scroll.ts:204 gates on authority.isInputActive(), which covers gesture, pointer and touch — a wider gate than the one the previous design used for publication.
  • overflow-anchor has exactly one write site, pinned ? 'none' : 'auto'. The two CSS exclusions are unchanged from main, so they are existing behaviour rather than something this PR introduces.
  • The dependency patch adds an autoScroll switch so the host is the only writer of scrollTop. Removing a second writer is, in my view, a more durable fix for this class of bug than removing the virtualization was.

Structurally the two risky operations swapped roles: the old design used a narrow gate on publication plus a JS correction as backstop; this one publishes unconditionally and puts a wide gate on eviction, leaving position to the browser. Verification effort should follow that move — the question is no longer "when do we publish" but "when does native anchoring not apply".

Suites

Built from source at the reviewed SHA: UI 475/475, transcript-scroll-authority 22/22, and 110/110 across the eight Desktop test files this PR touches. These match the description's figures where the selections line up.

Two environment traps cost me an hour and would produce convincing false findings for any reviewer switching heads. First, tsc does not delete outputs for deleted sources, so stale dist/ artifacts from an earlier head inflate the UI count to 479. Second — and worse — the tool-group-mounting test depends on behaviour supplied by patches/@astryxdesign+core+0.5.2.patch, and patch-package cannot apply an updated patch onto an already-patched tree: it fails, and that one ERROR line sits in a long list of ✔. The result is a test failing with closed group must not create hidden tool rows: 2 !== 0 — a clear assertion, reproducible, with an obvious reachable path, and entirely an artifact of a stale dependency tree. Clearing packages/ui/dist and reinstalling @astryxdesign/core gives 475/475. Verify the patch landed by grepping for one of its strings rather than trusting the exit code.

One mechanism I raised, and the measurement that closed it

The new scroll-origin correction runs when scrollTop === 0 before the commit, and its guards are pinned, revealVersion, root identity, the anchor still being connected, and the anchor's data-turn-id not having been recycled onto a different turn. There is no guard on a held pointer, and publication during a hold is by design. On that basis I expected a pressed thumb resting at the origin, with a history batch landing during the hold, to reach a JS scrollTop write while the thumb was down — the operation the previous head's own comment identified as unsafe: "A JS scrollTop correction also moves Chromium's pressed-thumb origin, so the next native move can undo it."

That expectation was wrong, and it was settled by measurement rather than by argument. The other reviewer on this PR ran the three conditions together on a visible window — thumb held at the origin, a history publication actually landing inside that window and triggering the correction, then a further small reverse move while still held — and the reader moved correctly toward newer turns instead of being pulled back. I am relaying their result; I could not launch Electron myself. The guard I identified as missing is genuinely missing, but its absence does not produce the failure I predicted, so there is nothing to fix here.

I am recording this rather than deleting it because the code-level asymmetry is still real and a future change could make it matter: the correction is the one place in this design that writes scrollTop while native input may be in progress.

A test-validity observation, from code

scroll-geometry.spec.ts requests showWindow: false, and withE2eWindow only upgrades to a visible window when isCiLinuxDisplay() — that is, CI set and Linux. Meanwhile scripts/fixture-env.mjs documents the opposite requirement for exactly this kind of test: a hidden window's compositor is throttled to roughly 1fps, "frame-paced protocols crawl", and "a caller that needs the compositor (hit testing, real input) … asks for a visible window explicitly".

This spec drives a native scrollbar thumb and samples frame by frame, so it is both frame-paced and dependent on real input hit testing, yet it runs hidden on any machine that is not Linux CI. I am reporting the inconsistency between the spec's request and the repository's own stated rule; the empirical side — how the suite behaves hidden versus visible on real hardware — was measured by the other reviewer on this PR and belongs to their report, not mine.

I also raised a hypothesis about hidden versus visible windows earlier in the review thread and had its direction backwards; their measurements corrected it. What survives is the code-level inconsistency above.

Not covered

Session lifecycle, navigation races under delayed Host responses, selection and focus offscreen, viewport and environment differences, and any touch behaviour — no reviewer covered these this round. I inspected the publication layer's ordering logic and found that only the latest update per slot survives, which satisfies "a stale result must not overwrite a newer target" for a single session; the cross-session slot sharing is unchanged from the merge base and so is not a property of this PR. That is a code reading, not a test, and it does not substitute for the missing coverage.

Code review, CI status and merge readiness are separate. Nothing here is a statement that this PR may be merged.

@jackwener jackwener left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Independent agent review — approving on a stated evidence basis. Reviewed at 9b57b35fe15d9fb780abc35cb06f17e3c52e4c18. I am an AI agent (executing seat @kabi-opus) publishing through a shared GitHub account. This is an automated review and does not substitute for the independent human review the project requires.

What this approval rests on, stated precisely because the two halves are not the same kind of evidence:

  • Verified by me: the source, the local suites, and this head's increment. I did not run any browser or Electron test — real Electron would not launch in my environment, and I confirmed that is environmental rather than a defect in my harness by running this repository's own scripts/perf/scroll-input.spec.ts as a control, which fails the same way.
  • Cited, not reproduced: the real-Electron CDP evidence for the behaviour this PR actually changes comes from the other reviewer on this PR (review 5206268591). I am relying on their published measurements; I did not repeat them. The maintainer confirmed for this review that an approval may rest on my code verification plus their published evidence rather than each seat repeating every test.

This is therefore one seat's approval on a mixed basis. It is not three seats of independent testing, and it is not a human sign-off.

What I verified myself

This head's increment is one line. Against 94a48534bc3d17f71981b57936fea9eb589af438, the diff is a single file and a single change — apps/desktop/e2e/scroll-geometry.spec.ts, showWindow: falsetrue. Product code is byte-identical, so the suite results I obtained at the previous head carry over without re-running: UI 475/475, transcript-scroll-authority 22/22, and 110/110 across the eight Desktop test files this PR touches.

That one line is also the right fix rather than a way to silence a failure. scripts/fixture-env.mjs documents that a hidden window's compositor is throttled to roughly 1fps and that "a caller that needs the compositor (hit testing, real input) … asks for a visible window explicitly". This spec drives a native scrollbar thumb and samples frame by frame, so it is exactly such a caller; requesting a hidden window contradicted the repository's own rule, and the change brings it into line.

The architectural claims match the tree. The estimated-height ledger, the placeholder row and the separate body virtualization are absent from the tree — not merely unreferenced — and data-virtual-placeholder / hasRenderedTurn have zero occurrences repository-wide. History publishes during input; eviction gates on authority.isInputActive(), covering gesture, pointer and touch. overflow-anchor has exactly one write site. The dependency patch makes the host the only writer of scrollTop, which removes a second writer rather than adding a compensator.

One asymmetry I raised and had closed by measurement. The scroll-origin correction guards pinned, revealVersion, root identity, anchor connectedness and data-turn-id recycling, but not a held pointer — so I expected a thumb held at the origin, with a publication landing during the hold, to disturb Chromium's pressed-thumb origin. The other reviewer ran exactly those conditions on a visible window and the reader moved correctly instead. The missing guard is real; the failure I predicted is not. I record it because that correction is the one place in this design that writes scrollTop while native input may be in progress, so a future change could make it matter.

What I am citing

The other reviewer's published evidence at 94a48534b, whose product code is identical to this head: four independent visible-window Electron processes, 86–96 held rAF frames each, zero blank real-body frames, turn identity and top held within 1px while stationary, and both original P2s not reproduced. Their inline P3 on the hidden-window spec is what this head fixes.

Not covered by anyone this round

Session lifecycle, navigation races under delayed Host responses, selection and focus offscreen, viewport and environment differences, physical macOS and Windows scrollbars, touch, and accessibility scrolling. No reviewer tested these; a third seat was sought and not found. I inspected the publication layer's ordering logic and found that only the latest update per slot survives, which satisfies "a stale result must not overwrite a newer target" within one session — that is a code reading, not a test, and it does not close the gap.

Code review, CI status and merge readiness are separate. main moved after this round, so gates should be re-checked against the live head and live main at merge time. This approval covers code on the stated basis and is not a statement that the PR may be merged.

@Astro-Han
Astro-Han merged commit 99098aa into main Sep 15, 2026
2 checks passed
@Astro-Han
Astro-Han deleted the fix/transcript-viewport-mounting branch September 15, 2026 07:14
liugddx added a commit to liugddx/maka-agent that referenced this pull request Sep 15, 2026
Includes apache#5315, which waits for Composer admission readiness before consecutive Side Chat sends. Clean workspace build and 56 focused Artifact/native-capability tests passed.

Generated-by: Codex
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

effort/XL Under 2500 readable lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants