LearnNewsExamplesServices
Frontmatter
id16000
titleWorkstation canvas proof must honor the film capture profile
stateClosed
labels
bugaitesting
assigneesneo-gpt-emmy
createdAtJul 26, 2026, 5:58 PM
updatedAtJul 26, 2026, 7:12 PM
githubUrlhttps://github.com/neomjs/neo/issues/16000
authorneo-gpt-emmy
commentsCount0
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]
closedAtJul 26, 2026, 7:12 PM

Workstation canvas proof must honor the film capture profile

Closed Backlog/active-chunk-10 bugaitesting
neo-gpt-emmy
neo-gpt-emmy commented on Jul 26, 2026, 5:58 PM

Context

The #15252 film QA pass on current dev exposed one independent red path after the recent Workstation choreography merges. At dev SHA 6c528583f94d8b26f8bd0fe88a3e10d9020020bc, the focused real-browser run

NEO_E2E_PORT=8124 npx playwright test workstation/WorkstationNL -c test/playwright/playwright.config.e2e.mjs --workers=1

reproduces on a macOS / Apple Silicon seat: the GL boot probe passes, then the Workstation journey exhausts its Canvas-worker proof at targetCanvas.screenshot().

Live latest-open sweep: checked the latest 20 open issues at 2026-07-26T15:57Z; no equivalent ticket exists. The recent A2A claim window also contains no overlapping owner. #15912 explicitly left this witness out of scope, so this is its actionable successor rather than a duplicate.

The Problem

The journey runs under two intentionally different browser contracts:

  1. the default benchmark profile includes --disable-frame-rate-limit; its App Worker, Canvas Worker, DOM, and Neural Link state stay live, but #15912 proved that this host presents no compositor frames for Playwright screenshots; and
  2. NEO_FILM_TAKE=1 removes that flag, presents frames on glass, and is the profile where pixel capture is valid.

WorkstationNL ignores that boundary. It always calls targetCanvas.screenshot() before and after mutating the exact Sparkline record, so the benchmark profile waits for a frame that its own launch contract deliberately does not present.

The semantic worker receipt is independently available in both profiles: pulseScaleSparkline() returns the exact component and record identity, and the component's values change is observed through Neural Link.

Live Revalidation

The ticket's initial prescription—replace the locator screenshot with a page screenshot clipped to boundingBox()—was falsified after creation:

  • page.screenshot({clip}) also starves under the default profile, so bypassing locator actionability does not bypass the missing compositor frame.
  • CDP Page.startScreencast emits no baseline frame under that profile.
  • serializing the placeholder canvas with toDataURL() remains unchanged even though the worker-owned values change.

The live source authority is already explicit in test/playwright/e2e/utils/gpuIntent.mjs: the default launch list is benchmark-oriented, while FILM_LAUNCH_ARGS exists specifically because capture requires frames on glass.

The Fix

  1. Make WorkstationNL read the existing NEO_FILM_TAKE run mode.
  2. Preserve the exact component/record and worker-value mutation receipts in every run.
  3. Run the exact-canvas before/after screenshot assertion only under the film profile, where presented frames are part of the declared contract.
  4. Make the spec's summary and inline rationale state the profile split so a future cleanup cannot silently restore the impossible default-profile capture.

Decision Record impact: none.

Acceptance Criteria

  • The default focused journey clears the former Canvas screenshot gate and reaches the later docking choreography while preserving exact component/record and worker-value receipts.
  • Under NEO_FILM_TAKE=1, the same journey additionally proves that the exact target Canvas pixels change.
  • The default and film launch profiles remain byte-identical; this ticket consumes their established boundary rather than retuning either profile.
  • No production or app code changes.
  • Any later cross-zone choreography failure remains reported against its own owner and is not misrepresented as a Canvas regression.

Out of Scope

  • Implementing or promoting the three test.fixme scenes in WorkstationFiveBeatNL.spec.mjs.
  • Changing #15906 cross-window docking ownership or choreography.
  • Native multi-display film admission, capture assembly, or publication.
  • Retuning benchmark launch flags or weakening the film-profile pixel proof.

Avoided Traps

  • Longer timeout: cannot produce a compositor frame that the active launch profile suppresses.
  • Page-level clipped screenshot: shares the same missing presented-frame dependency.
  • Production debug API: would add product surface solely to work around a test-profile mismatch.
  • Values-only in film mode: would discard a valid independent rendering receipt where capture is supported.
  • Calling later cross-zone failures a Canvas red: conflates separately owned choreography with the proof this ticket corrects.

Related

Related: #15252, #15912, #15906

Retrieval Hint: WorkstationNL Canvas screenshot benchmark profile filmTake disable-frame-rate-limit