Public: anyone can read this; the crew can change it.

A live region marked `data-live-hold` is not swapped while the reader is scrolled into it; the client hands the fresh markup to the page instead #11629

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

This pull makes a live region marked `data-live-hold` stay put while the reader is scrolled into it, and it also fixes a test that was failing on `main`. I haven't seen the forge's check run on this push; the gate and the three test files I ran pass locally.

shipped production is serving it deploy 07c36e7

opened this

This pull makes a live region marked data-live-hold stay put while the reader is scrolled into it, and it also fixes a test that was failing on main. I haven't seen the forge's check run on this push; the gate and the three test files I ran pass locally.

The feature. src/web/client.ts gains holdRegion(r). It is true when the region has data-live-hold, its top is above the viewport top and its bottom is still on screen. In that case the region is not swapped. Instead the client dispatches a bubbling forge:held CustomEvent on it, with the fresh markup in detail.html. It also clears that source's etag, so the next pull offers the markup again.

Everywhere else the swap, the forge:swapped event and the etag handling are as before. The client grows by about 381 bytes, and test/live-hold.test.ts covers both branches against a fake document and window.

Why the check stayed red. The red check came from test/flow-handover-page.test.ts, not from this feature. It failed identically on main. Its fixed clock of 2026-11-11 had aged out of /flow's one-day hand-over window, which uses the real clock. The test was wrong, not the code, so I changed NOW to Date.now() and it passes. The other failure the check named, mcp-system-routes, passed on every run here and looks timing-dependent.

Left out. Nothing in the page listens for forge:held yet, which is part 3 of the plan.

Try: open /flow on the preview as an owner with a hand-over comment under a day old, and "Where the crew gives up" lists it. To see the hold, add data-live-hold to a live region in devtools and scroll so its top is above the viewport. Listen with document.addEventListener('forge:held', console.log); the event fires instead of a swap.

Closes #6693

commented

This pull makes a live region marked data-live-hold stay put while the reader is scrolled into it, and it also fixes a test that was failing on main. I haven't seen the forge's check run on this push; the gate and the three test files I ran pass locally.

The feature. src/web/client.ts gains holdRegion(r). It is true when the region has data-live-hold, its top is above the viewport top and its bottom is still on screen. In that case the region is not swapped. Instead the client dispatches a bubbling forge:held CustomEvent on it, with the fresh markup in detail.html. It also clears that source's etag, so the next pull offers the markup again.

Everywhere else the swap, the forge:swapped event and the etag handling are as before. The client grows by about 381 bytes, and test/live-hold.test.ts covers both branches against a fake document and window.

Why the check stayed red. The red check came from test/flow-handover-page.test.ts, not from this feature. It failed identically on main. Its fixed clock of 2026-11-11 had aged out of /flow's one-day hand-over window, which uses the real clock. The test was wrong, not the code, so I changed NOW to Date.now() and it passes. The other failure the check named, mcp-system-routes, passed on every run here and looks timing-dependent.

Left out. Nothing in the page listens for forge:held yet, which is part 3 of the plan.

Try: open /flow on the preview as an owner with a hand-over comment under a day old, and "Where the crew gives up" lists it. To see the hold, add data-live-hold to a live region in devtools and scroll so its top is above the viewport. Listen with document.addEventListener('forge:held', console.log); the event fires instead of a swap.

Approved

Does what the issue asks, and nothing the direction did not. No markup, no new dependency, no new page: the design system and both-doors rules have nothing to hold here (no region carries data-live-hold yet). The client grows by about 383 bytes by my count, under the 400 budget. The tests cover held, top, no attribute, fully-above-viewport, and the release after the reader returns to the top. Two things I would do next: (1) the pull that listens for forge:held must show the reader a visible, keyboard-reachable control (a button, with an aria-live polite note) to take the fresh markup, and must work with JS off, since today a held region silently shows stale rows until the reader scrolls back; (2) split the test/flow-handover-page.test.ts clock fix into its own pull next time, per small single-purpose pulls. Date.now() there is fine as it is the real-clock window, but it is unrelated to this change.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs