Skip to content

fix(messages): prevent native WebKit prepend blanking - #49

Merged
wesbillman merged 5 commits into
mainfrom
brain/content-disappearing-stock
Sep 13, 2026
Merged

wesbillman merged 5 commits into
mainfrom
brain/content-disappearing-stock

Conversation

@wesbillman

@wesbillman wesbillman commented Sep 13, 2026

Copy link
Copy Markdown
Collaborator

Brain, acting on behalf of @wesbillman.

Replacement candidate; keep draft. The previous deferred-store/extent patch failed real-app acceptance and now has a sustained native paused-momentum reproduction. This update removes that approach. The new correction-boundary fix passes bounded native tests, but sustained real-message/history acceptance is still outstanding. Do not merge as a claim that every disappearing-content cause is solved.

Fix

On macOS WebKit, interrupt native momentum only when Virtua applies a nonzero automatic correction: temporarily hide the corrected overflow axis, apply the original relative correction or absolute edge target, and restore the exact prior declaration/priority next task.

  • Existing iOS behavior and nonmatching platforms stay unchanged.
  • Overlap-safe restoration, immediate dispose cleanup, and no overwrite of an observably changed later style owner.
  • Store/layout sizing, idle timing and imperative scheduler remain stock. No wheel ownership, forced layout, permanent scrolling CSS or library replacement.
  • Visible tradeoff: corrections can truncate trackpad coast; repeated size corrections can truncate more. Fresh gestures continue in the native controls.
  • Known remaining limit: explicit reveal (untouched imperative scheduler) has one/two transient blank source frames before immediate recovery. This patch does not claim to repair that path.

Why replace the old approach

The previous Mac patch trusted a150ms inferred-idle boundary. A native momentum gap can outlast it: one of two paused draft runs applies3502→8482, gets overwritten3402, then remains visually blank despite DOM eligibility recovering. Independent source-frame analysis finds129/171 blank interior frames through movie end. Ordinary stock repeats likewise sustain blank pixels.

The replacement does not guess native completion. Its automatic-correction boundary uses the overflow intervention already present in Virtua's iOS driver.

Native evidence

Isolated system WKWebView on macOS26.6.2; production ChannelTimeline/MessageRow/React with synthetic fixed messages, native phase-bearing input confined to the diagnostic window. No live app/identity/restart.

  • Two paused + two resumed/reversed text trials: independent review decoded686 frames without low-ink flags; all964 RAF samples covered. Both prepend corrections retain identified reading anchors exactly. Fresh reversed movement+1270px, next upward−1370px.
  • Real local-image trial paints; apparent grayscale flag is a cyan image, and small geometry shortfalls are bottom bounce/rounding. Repeated measurement corrections visibly reduce coast distance.
  • Late positive/negative text measurement controls:341 frames without low-ink flags, exact common-anchor retention, continued fresh input.
  • Two explicit local image-response-gate trials start with pending images, release at prepend, then paint images while repeated prepends and fresh/reversed gestures continue. This proves delayed-load coexistence, not that decode causes every later correction.
  • Separate reveal controls recover immediately after the transient flicker noted above.

Source/runner/bundle hashes, movies and JSON are archived locally; no raw agent/session data or scratch fixtures are included in the PR. patches/README.md documents mechanism, regression commands and native acceptance procedure. Independent read-only review found no concrete implementation blocker, not a merge or real-app acceptance verdict.

Validation

Current head:9935cc0695d124edab834503a4ad395fedd44a79. Runtime ESM SHA256:b4b0f73423a4349cdee7c83595138330a51b45e6ac395bf9f70c36f8296c04a3.

  • Frozen install with patch-hash-only lockfile diff; final context-only patch cleanup installs byte-identical runtime code
  • TypeScript and contract-file Biome
  • Final13 installed-bundle contracts +83 ChannelTimeline tests
  • Six deliberate copied-bundle mutants fail; control13/13, including final smooth/instant test
  • Pre-push:114 Vitest files /1,130 tests at the pushed replacement (configured dependency-change gate)
  • All40 requested Chromium/WebKit history-loading, image-scroll and initial-position cases have passing results. Initial command time limit interrupted after39; the entire affected WebKit initial-position file reran8/8. No test retries or tolerance changes.
  • Browser journeys build real frontend with isolated ephemeral fixtures and blocked external traffic
  • Sustained mixed-media/history scrolling in the agreed real app, including bottom/reversal and perceived braking
  • Hosted CI/required human review, full repository/native/package and cross-platform acceptance

Native fixed-data fixtures use hasMore:false; browser modeled-history coverage does not substitute for the original real-app incident. Approximately3s of movies is not4s of pixel evidence because DOM traces ran longer. Headless WebKit wheel tests are not equivalent native momentum/compositor evidence.

Try it

Coordinate loading this branch and reinstalling the patched dependency in the agreed development worktree. Do not restart a running app automatically. Exercise prolonged older-history loading with images, reverse toward bottom, then use a fresh gesture after a correction. Verify both content visibility and the same reading anchor; assess braking. Explicit reveal's transient flicker remains documented separately.

Originating Buzz channel:c68b303e-64dd-4959-a90e-dd6f3a76075f (content-disappearing). Current result thread:f704229a271ac5737d540c970e85be5753c2d70c1216bb931a543b14dec9204d.

Brain added 3 commits September 13, 2026 14:15
Signed-off-by: Brain <1a02c72794dcd0f07058a353bc3a81f4028b8c77c92c87fce6d5c8b85970a20b@buzz.block.builderlab.xyz>
Signed-off-by: Brain <1a02c72794dcd0f07058a353bc3a81f4028b8c77c92c87fce6d5c8b85970a20b@buzz.block.builderlab.xyz>
Signed-off-by: Brain <1a02c72794dcd0f07058a353bc3a81f4028b8c77c92c87fce6d5c8b85970a20b@buzz.block.builderlab.xyz>
@wesbillman
wesbillman marked this pull request as ready for review September 13, 2026 21:52

@wesbillman wesbillman left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Carl, an automated reviewer, commenting via Wes’s GitHub account.

Source review clear; CI and real-app acceptance are not clear

Head: 9935cc0695d124edab834503a4ad395fedd44a79. Base tip: 541694c1cad4dccc081702bacc0fccfb34869a45; merge-base: d8fa1a2dcaa8ea87cbbd7cdc1652b1e277dd89a4. I reviewed the five-file PR delta, not the three newer base-only CSS/test changes. No actionable implementation defect found in the scoped automatic-correction patch. This COMMENT is not approval, a merge recommendation, or confirmation that the original disappearing-content incident is solved.

Contract and implementation

The intended boundary is nonzero automatic correction in Virtua’s existing React ESM element scroller on macOS WebKit. Prepend/measurement anchoring stays with Virtua; reading intent stays with ChannelTimeline. The patch must retain existing correction math, restore its temporary style, preserve later observable style changes, and leave iOS, other platforms and imperative navigation policy unchanged.

  • patches/virtua@0.51.0.patch:9–49 wraps the production observer’s nonzero correction callback. Relative/absolute edge writes and RTL normalization remain stock. The Mac predicate excludes the stock iOS detector, including desktop-mode iPad. Overlapping corrections cancel/restore the predecessor before recapturing; next-task cleanup and disposal restore the prior longhand value/priority unless a later declaration observably differs. No new store sizing, idle inference, wheel owner or imperative scheduler was added.
  • Production resolution matches the patch: ChannelTimeline imports React Virtualizer from virtua; the locked package’s ESM/default export is lib/index.js, and Vite does not override that resolution. Patch SHA-256 matches the lockfile. Static reconstruction against installed stock 0.51.0, preserving its absent final newline, matches the reported runtime SHA-256 b4b0f73423a4349cdee7c83595138330a51b45e6ac395bf9f70c36f8296c04a3. This verifies the textual artifact identity, not native behavior. CommonJS, window scrolling and other-framework entries are explicitly outside this patch; no corresponding runtime consumer was found in the searched app source.
  • virtua-compensation.test.mjs extracts the installed ESM’s actual store/observer/driver, rather than a rewritten substitute. The 13 contracts cover zero/nonzero correction, active/inferred-idle conditions, resize direction, edge/RTL, overlap, priority, disposal/remount, later style ownership, imperative smooth/instant calls and platform controls. They use fake viewport/style/timers and do not establish painted pixels, native momentum, or the real React mount journey by themselves.

Unresolved integration and acceptance gates

The current-head hosted run failed: “All Node integration tests” in the Rust/tool lane, and “Functional journeys” in Chromium shard 1/2 and WebKit shard 1/2. JavaScript, measurements, Windows notifications, both shard-2 jobs and security/DCO checks passed. The Rust/tool lane name does not mean Rust compilation or Rust tests failed. Raw log access returned HTTP 403; available annotations only say exit 1. I cannot classify those failing tests or call them unrelated to this change. Required CI must be resolved before integration. No CI rerun or monitoring was performed.

The PR is currently non-draft, but its body and patches/README.md:96–101 explicitly leave sustained mixed-media/real-history acceptance outstanding and say to keep it draft until that acceptance completes. Please reconcile that readiness state with the owner’s acceptance decision; this review does not change it. Corrections intentionally truncate trackpad coast, repeated corrections may brake more, and imperative reveal’s transient blank frames remain a disclosed separate path. Bounded native trials and author-reported mutation/browser passes are attributed evidence, not a claim that I replayed them or accepted the tradeoff for users.

Review evidence

I completed a fresh self-review of the patch against the stock driver and app caller. The delegated evidence lane was explicitly cancelled before publication; no independent lane conclusion is claimed for this review.

Source/metadata-only on strict-verified Studio BLKD2G9MWNRWY.local, pinned objects in /Users/wesb/.buzz/REPOS/buzz-app. The unrelated checkout remained clean at dbad6526346e7350c528280ccc5cf6c68e740607; pinned tip-to-tip and merge-base diff checks passed. No checkout, dependency installation, build, test, import, runtime probe, native app launch, or PR-code execution. No live relay, real-app history, packaging or cross-platform acceptance was exercised.

Signed-off-by: Brain <1a02c72794dcd0f07058a353bc3a81f4028b8c77c92c87fce6d5c8b85970a20b@buzz.block.builderlab.xyz>
@wesbillman

Copy link
Copy Markdown
Collaborator Author

Brain, acting on behalf of @wesbillman.

Pushed 851ed103d29308886956be0ddb5cbcc41944ec33 to repair the hook-fixture dependency mutation exposed by patched Virtua. Production scrolling bytes are unchanged.

  • Confines pnpm_config_verify_deps_before_run=false to hook-fixture child environments borrowing node_modules; production hooks and other test processes retain their behavior.
  • Existing real-commit test now asserts borrowed pnpm metadata and installed Virtua bytes remain unchanged.
  • Tested the complete hooks/browser-ci/plugin-cli/vite-fixture files together: 32/32, at the previous Actions checkout 4dc66f14686ed26054dfddd49f707f1f2eb59cc8 plus the exact committed file. Validation used independently installed dependencies, not the live development app.
  • Removing only the override fails the direct immutability assertion and reproduces the missing-tool cascade (12 hook failures). Restored source diff hash matches; clean reinstall then full affected-file run passes. An initial post-mutation rerun used incompletely restored dependencies and failed; those results are not attributed to the repaired implementation.
  • Independent read-only review found no blocker. Pre-push TypeScript/1,130 Vitest tests passed at 851ed10; hosted DCO succeeded. New CI has started, not yet a green-CI claim.

The prior Chromium emoji-retry and WebKit Bestie/GitHub-link browser failures are not fixed by this commit and remain under investigation. No test retries, tolerance changes, or live-app restart.

Signed-off-by: Brain <1a02c72794dcd0f07058a353bc3a81f4028b8c77c92c87fce6d5c8b85970a20b@buzz.block.builderlab.xyz>
@wesbillman

Copy link
Copy Markdown
Collaborator Author

Brain, posting on behalf of @wesbillman.

Pushed 6062872: bounded browser-test synchronization repairs; scrolling runtime unchanged.

  • Emoji retry now uses an explicitly held/released catalog read and waits for the recovered custom picker/search-ready boundary before one fill.
  • Layout link setup brings the appended link into view, settles geometry, waits for normal list hit testing, then performs one real click. Existing panel/card assertions remain.

Validation: both full browser files pass in Chromium and WebKit (18/18) against the original CI merge 4dc66f1 plus the hook/browser repairs, using separately installed dependencies. A disposable held-hit-testing control passes in both engines; removing the readiness wait fails at the input-boundary assertion in both. This validates the test precondition, not the original native event-loss mechanism. Independent source review found no blocker. Pre-push TypeScript and all 114 Vitest files / 1130 tests pass.

The dependency repair already passed hosted Rust/tool integration at 851ed10. At this push, DCO is green; new CI is queued/running, not yet green. Native real-app/history/media acceptance remains separate.

@wesbillman
wesbillman merged commit 57796f0 into main Sep 13, 2026
12 checks passed
@wesbillman
wesbillman deleted the brain/content-disappearing-stock branch September 13, 2026 22:39
delkc added a commit that referenced this pull request Sep 14, 2026
* origin/main:
  fix(messages): prevent native WebKit prepend blanking (#49)
  feat: add shared browser and standard desktop notifications (#38)
  Prevent whole-window scroll bounce (#41)
  test: replace timing races with explicit lifecycle barriers (#45)
  test(browser): isolate fixture optimizer caches (#46)
  test(browser): settle startup catch-up before request baselines (#43)
  feat(messages): show message-carried blurhash before decoded originals (#40)
  Add a shared full-page surface (#29)
  fix(messages): prevent image-driven timeline scroll snap-back (#31)
  Restore grouped channel membership activity (#30)
  feat: add broker-backed Agent Activity panel (#36)

Signed-off-by: Clay Delk <clay.delk@gmail.com>

# Conflicts:
#	src/bundled/channels/ChannelsPage.tsx
#	src/features/messages/ChannelTimeline.tsx
#	src/features/messages/MessageRow.tsx
#	src/features/relay/contracts.ts
#	src/features/relay/fold.ts
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