Context
A browser witness at Engine 00b6f2aa6a placed a SharedCanvas at viewport (21,154), size 1038×799. After its resize notification, canvasRect instead held left:0, top:0. A click on a rendered target missed by the canvas's screen offset. Measuring the current DOM rectangle before converting that click restored the hit.
Triage decision: repair the shared coordinate contract, rather than retain a consumer-specific correction.
The Problem
onDomResize() passes data.contentRect to updateSize(), which caches the supplied rectangle. forwardPointer() then subtracts its origin from viewport clientX/clientY. ResizeObserver's content rectangle is relative to the element's padding origin, so it cannot serve as a viewport origin. Existing pointer tests start from an already-correct rectangle and omit this transition.
The Architectural Reality
Design authority: src/app/SharedCanvas.mjs#forwardPointer promises “the canvas-relative position”; updateSize says it caches “the bounding rect.” src/main/addon/ResizeObserver.mjs#createSyntheticEntry explicitly defines contentRect relative to the padding origin. ResizeObserver.dispatchResizeEvents already supplies data.rect from the observed element's viewport measurement. component.Base#getDomRect remains the initial/missing-size measurement path.
The App Worker host converts coordinates; the Canvas Worker consumes local coordinates. Renderer gestures and remote routing remain unchanged.
The Fix
Consume the resize payload's existing rect as the viewport pointer rectangle while retaining contentRect dimensions for renderer sizing, and cover resize → pointer forwarding in the existing test/playwright/unit/canvas/PointerInput.spec.mjs. Keep ordinary pointer forwarding synchronous; no DOM measurement per movement event.
Prescription checked: src/app/SharedCanvas.mjs — owns the concern. The independent read rejected replacing content-box dimensions with bounding-box dimensions. Its existing updateSize helper can accept the pointer rectangle separately, defaulting to the sizing rectangle for existing callers.
Contract Ledger
| Target Surface |
Source of Authority |
Proposed Behavior |
Fallback |
Docs |
Evidence |
| SharedCanvas resize → canvasRect → forwardPointer |
SharedCanvas.mjs methods above; ResizeObserver.mjs contentRect contract |
Keep content-box dimensions and viewport pointer geometry separate after resize; forward local CSS coordinates and existing window/button/modifier facts |
Existing readiness and missing-rectangle guards |
Owning method JSDoc |
Red/green offset-resize unit control and browser pointer receipt |
Decision Record impact
none; restore the existing coordinate contract.
Acceptance Criteria
Out of Scope
New gestures, worker topology, new remote entry points, and generic position tracking without resize.
Avoided Traps
Do not change ResizeObserver's documented contentRect semantics, add per-mousemove DOM round trips, or hide the error in individual renderers.
Related and sweeps
#19173 / PR #19179 introduced the pointer transport; #9314 concerns resize-event routing.
Live latest-20 open issues and latest-30 all-state A2A checked at 2026-10-11 01:51Z: no equivalent or overlapping claim. Own assignments: two open, neither this surface. Live SharedCanvas/open and canvas-pointer-resize searches found none. KB surfaced only related historical canvas issues. Three prior-art MC queries plus a final symptom query surfaced resize/canvas history, no decision covering this mismatch. No new .mjs file or Agent OS structure change.
Origin Session ID: 56e85f26-e03f-486f-8cd7-94db0602291c
Retrieval Hint: SharedCanvas pointer position shifted after resize contentRect viewport origin
Context
A browser witness at Engine
00b6f2aa6aplaced a SharedCanvas at viewport(21,154), size1038×799. After its resize notification,canvasRectinstead heldleft:0, top:0. A click on a rendered target missed by the canvas's screen offset. Measuring the current DOM rectangle before converting that click restored the hit.Triage decision: repair the shared coordinate contract, rather than retain a consumer-specific correction.
The Problem
onDomResize()passesdata.contentRecttoupdateSize(), which caches the supplied rectangle.forwardPointer()then subtracts its origin from viewportclientX/clientY. ResizeObserver's content rectangle is relative to the element's padding origin, so it cannot serve as a viewport origin. Existing pointer tests start from an already-correct rectangle and omit this transition.The Architectural Reality
Design authority:
src/app/SharedCanvas.mjs#forwardPointerpromises “the canvas-relative position”;updateSizesays it caches “the bounding rect.”src/main/addon/ResizeObserver.mjs#createSyntheticEntryexplicitly defines contentRect relative to the padding origin.ResizeObserver.dispatchResizeEventsalready suppliesdata.rectfrom the observed element's viewport measurement.component.Base#getDomRectremains the initial/missing-size measurement path.The App Worker host converts coordinates; the Canvas Worker consumes local coordinates. Renderer gestures and remote routing remain unchanged.
The Fix
Consume the resize payload's existing
rectas the viewport pointer rectangle while retainingcontentRectdimensions for renderer sizing, and cover resize → pointer forwarding in the existingtest/playwright/unit/canvas/PointerInput.spec.mjs. Keep ordinary pointer forwarding synchronous; no DOM measurement per movement event.Prescription checked:
src/app/SharedCanvas.mjs— owns the concern. The independent read rejected replacing content-box dimensions with bounding-box dimensions. Its existingupdateSizehelper can accept the pointer rectangle separately, defaulting to the sizing rectangle for existing callers.Contract Ledger
Decision Record impact
none; restore the existing coordinate contract.
Acceptance Criteria
Out of Scope
New gestures, worker topology, new remote entry points, and generic position tracking without resize.
Avoided Traps
Do not change ResizeObserver's documented contentRect semantics, add per-mousemove DOM round trips, or hide the error in individual renderers.
Related and sweeps
#19173/ PR#19179introduced the pointer transport;#9314concerns resize-event routing. Live latest-20 open issues and latest-30 all-state A2A checked at 2026-10-11 01:51Z: no equivalent or overlapping claim. Own assignments: two open, neither this surface. Live SharedCanvas/open and canvas-pointer-resize searches found none. KB surfaced only related historical canvas issues. Three prior-art MC queries plus a final symptom query surfaced resize/canvas history, no decision covering this mismatch. No new .mjs file or Agent OS structure change.Origin Session ID: 56e85f26-e03f-486f-8cd7-94db0602291c Retrieval Hint: SharedCanvas pointer position shifted after resize contentRect viewport origin