diff --git a/packages/paperclip-runner/docs/phase-07-issue-thread-ui.md b/packages/paperclip-runner/docs/phase-07-issue-thread-ui.md index 0f4f7886878..684f3ff3c28 100644 --- a/packages/paperclip-runner/docs/phase-07-issue-thread-ui.md +++ b/packages/paperclip-runner/docs/phase-07-issue-thread-ui.md @@ -168,11 +168,17 @@ Hosts without the Playwright chromium system libraries can either run `pnpm --filter @paperclipai/paperclip-runner verify:rootless` or set `PAPERCLIP_RUNNER_CHROMIUM_PATH` to a preinstalled Chromium. -The committed PNGs are pinned to the Chromium build listed in the Phase 7G -verification evidence, so `check:phase7:ui` needs that same browser. Point -`PAPERCLIP_RUNNER_CHROMIUM_PATH` at it before comparing; a different build makes -every shot mismatch at once, which reads like a regression but is not one. The -check prints the Chromium version it recorded with whenever it reports drift. +The committed PNGs are pinned to the Chromium build and font environment listed +in `knowledge/evidence/phase-07/ui/index.md`, so `check:phase7:ui` needs that +same browser and font set. Point `PAPERCLIP_RUNNER_CHROMIUM_PATH` at the +recorded browser before comparing — and when that path is the agent-browser +wrapper, also set `PAPERCLIP_CHROMIUM_BIN` to the exact binary, because the +wrapper otherwise picks the newest installed Playwright Chromium. A different +build or font set makes every shot mismatch at once, which reads like a +regression but is not one. The recorder probes that `Inter` resolves distinctly +from the DejaVu Sans fallback and refuses to record or compare when it does +not; the drift report prints the Chromium version and font probe it recorded +with. ## Accessibility diff --git a/packages/paperclip-runner/knowledge/evidence/phase-07/ui/debug-panel-open--desktop.png b/packages/paperclip-runner/knowledge/evidence/phase-07/ui/debug-panel-open--desktop.png index 6b505bb55db..c872804359a 100644 Binary files a/packages/paperclip-runner/knowledge/evidence/phase-07/ui/debug-panel-open--desktop.png and b/packages/paperclip-runner/knowledge/evidence/phase-07/ui/debug-panel-open--desktop.png differ diff --git a/packages/paperclip-runner/knowledge/evidence/phase-07/ui/debug-panel-open--mobile.png b/packages/paperclip-runner/knowledge/evidence/phase-07/ui/debug-panel-open--mobile.png index 7faea91aa93..0f02a8720cf 100644 Binary files a/packages/paperclip-runner/knowledge/evidence/phase-07/ui/debug-panel-open--mobile.png and b/packages/paperclip-runner/knowledge/evidence/phase-07/ui/debug-panel-open--mobile.png differ diff --git a/packages/paperclip-runner/knowledge/evidence/phase-07/ui/deliverable-registered--desktop.png b/packages/paperclip-runner/knowledge/evidence/phase-07/ui/deliverable-registered--desktop.png index 9126b63e561..cca4e6be3f6 100644 Binary files a/packages/paperclip-runner/knowledge/evidence/phase-07/ui/deliverable-registered--desktop.png and b/packages/paperclip-runner/knowledge/evidence/phase-07/ui/deliverable-registered--desktop.png differ diff --git a/packages/paperclip-runner/knowledge/evidence/phase-07/ui/deliverable-registered--mobile.png b/packages/paperclip-runner/knowledge/evidence/phase-07/ui/deliverable-registered--mobile.png index f6734a8444a..7e5ffc8a961 100644 Binary files a/packages/paperclip-runner/knowledge/evidence/phase-07/ui/deliverable-registered--mobile.png and b/packages/paperclip-runner/knowledge/evidence/phase-07/ui/deliverable-registered--mobile.png differ diff --git a/packages/paperclip-runner/knowledge/evidence/phase-07/ui/denial-optional-tool--desktop.png b/packages/paperclip-runner/knowledge/evidence/phase-07/ui/denial-optional-tool--desktop.png index c1fa6dc90df..9b627e5c036 100644 Binary files a/packages/paperclip-runner/knowledge/evidence/phase-07/ui/denial-optional-tool--desktop.png and b/packages/paperclip-runner/knowledge/evidence/phase-07/ui/denial-optional-tool--desktop.png differ diff --git a/packages/paperclip-runner/knowledge/evidence/phase-07/ui/denial-optional-tool--mobile.png b/packages/paperclip-runner/knowledge/evidence/phase-07/ui/denial-optional-tool--mobile.png index 05ab5db4db6..713fbb6d767 100644 Binary files a/packages/paperclip-runner/knowledge/evidence/phase-07/ui/denial-optional-tool--mobile.png and b/packages/paperclip-runner/knowledge/evidence/phase-07/ui/denial-optional-tool--mobile.png differ diff --git a/packages/paperclip-runner/knowledge/evidence/phase-07/ui/disposition-terminal--desktop.png b/packages/paperclip-runner/knowledge/evidence/phase-07/ui/disposition-terminal--desktop.png index 8aef404e140..5afcd0f96da 100644 Binary files a/packages/paperclip-runner/knowledge/evidence/phase-07/ui/disposition-terminal--desktop.png and b/packages/paperclip-runner/knowledge/evidence/phase-07/ui/disposition-terminal--desktop.png differ diff --git a/packages/paperclip-runner/knowledge/evidence/phase-07/ui/disposition-terminal--mobile.png b/packages/paperclip-runner/knowledge/evidence/phase-07/ui/disposition-terminal--mobile.png index c5fd851d16c..4f33440c7f5 100644 Binary files a/packages/paperclip-runner/knowledge/evidence/phase-07/ui/disposition-terminal--mobile.png and b/packages/paperclip-runner/knowledge/evidence/phase-07/ui/disposition-terminal--mobile.png differ diff --git a/packages/paperclip-runner/knowledge/evidence/phase-07/ui/document-revision--desktop.png b/packages/paperclip-runner/knowledge/evidence/phase-07/ui/document-revision--desktop.png index 8b208b02396..9540e6471be 100644 Binary files a/packages/paperclip-runner/knowledge/evidence/phase-07/ui/document-revision--desktop.png and b/packages/paperclip-runner/knowledge/evidence/phase-07/ui/document-revision--desktop.png differ diff --git a/packages/paperclip-runner/knowledge/evidence/phase-07/ui/document-revision--mobile.png b/packages/paperclip-runner/knowledge/evidence/phase-07/ui/document-revision--mobile.png index 1620e903a76..7c01a909f91 100644 Binary files a/packages/paperclip-runner/knowledge/evidence/phase-07/ui/document-revision--mobile.png and b/packages/paperclip-runner/knowledge/evidence/phase-07/ui/document-revision--mobile.png differ diff --git a/packages/paperclip-runner/knowledge/evidence/phase-07/ui/index.md b/packages/paperclip-runner/knowledge/evidence/phase-07/ui/index.md index 66e452c1c81..2a44b42c1bc 100644 --- a/packages/paperclip-runner/knowledge/evidence/phase-07/ui/index.md +++ b/packages/paperclip-runner/knowledge/evidence/phase-07/ui/index.md @@ -27,3 +27,12 @@ Deterministic `fake` mode; no provider, runner, or credential is involved. - `thread-baseline--mobile.png` - `turn-streaming--desktop.png` - `turn-streaming--mobile.png` + +## Recording environment + +- Chromium 151.0.7922.34 — pin the exact binary with `PAPERCLIP_CHROMIUM_BIN` + (honoured by the agent-browser wrapper) alongside + `PAPERCLIP_RUNNER_CHROMIUM_PATH`. +- Sans stack resolves to Inter (probe: Inter 549px vs + DejaVu Sans 641px for the title string). The recorder + refuses to run when Inter does not resolve. diff --git a/packages/paperclip-runner/knowledge/evidence/phase-07/ui/interaction-confirmation-pending--desktop.png b/packages/paperclip-runner/knowledge/evidence/phase-07/ui/interaction-confirmation-pending--desktop.png index b99eb10519e..4e1932b9d7d 100644 Binary files a/packages/paperclip-runner/knowledge/evidence/phase-07/ui/interaction-confirmation-pending--desktop.png and b/packages/paperclip-runner/knowledge/evidence/phase-07/ui/interaction-confirmation-pending--desktop.png differ diff --git a/packages/paperclip-runner/knowledge/evidence/phase-07/ui/interaction-confirmation-pending--mobile.png b/packages/paperclip-runner/knowledge/evidence/phase-07/ui/interaction-confirmation-pending--mobile.png index 1ecd34b0271..d8083a537cb 100644 Binary files a/packages/paperclip-runner/knowledge/evidence/phase-07/ui/interaction-confirmation-pending--mobile.png and b/packages/paperclip-runner/knowledge/evidence/phase-07/ui/interaction-confirmation-pending--mobile.png differ diff --git a/packages/paperclip-runner/knowledge/evidence/phase-07/ui/interaction-question-pending--desktop.png b/packages/paperclip-runner/knowledge/evidence/phase-07/ui/interaction-question-pending--desktop.png index fcd55cf3654..1978d4e536b 100644 Binary files a/packages/paperclip-runner/knowledge/evidence/phase-07/ui/interaction-question-pending--desktop.png and b/packages/paperclip-runner/knowledge/evidence/phase-07/ui/interaction-question-pending--desktop.png differ diff --git a/packages/paperclip-runner/knowledge/evidence/phase-07/ui/interaction-question-pending--mobile.png b/packages/paperclip-runner/knowledge/evidence/phase-07/ui/interaction-question-pending--mobile.png index 8488dc44628..b3eba793d14 100644 Binary files a/packages/paperclip-runner/knowledge/evidence/phase-07/ui/interaction-question-pending--mobile.png and b/packages/paperclip-runner/knowledge/evidence/phase-07/ui/interaction-question-pending--mobile.png differ diff --git a/packages/paperclip-runner/knowledge/evidence/phase-07/ui/interaction-resolved-mixed--desktop.png b/packages/paperclip-runner/knowledge/evidence/phase-07/ui/interaction-resolved-mixed--desktop.png index aa20b44a2a4..f4ad00075d4 100644 Binary files a/packages/paperclip-runner/knowledge/evidence/phase-07/ui/interaction-resolved-mixed--desktop.png and b/packages/paperclip-runner/knowledge/evidence/phase-07/ui/interaction-resolved-mixed--desktop.png differ diff --git a/packages/paperclip-runner/knowledge/evidence/phase-07/ui/interaction-resolved-mixed--mobile.png b/packages/paperclip-runner/knowledge/evidence/phase-07/ui/interaction-resolved-mixed--mobile.png index 38804c2a4d7..dd9d31e1f07 100644 Binary files a/packages/paperclip-runner/knowledge/evidence/phase-07/ui/interaction-resolved-mixed--mobile.png and b/packages/paperclip-runner/knowledge/evidence/phase-07/ui/interaction-resolved-mixed--mobile.png differ diff --git a/packages/paperclip-runner/knowledge/evidence/phase-07/ui/reconnect-banner--desktop.png b/packages/paperclip-runner/knowledge/evidence/phase-07/ui/reconnect-banner--desktop.png index e6aa6383931..7c651e00243 100644 Binary files a/packages/paperclip-runner/knowledge/evidence/phase-07/ui/reconnect-banner--desktop.png and b/packages/paperclip-runner/knowledge/evidence/phase-07/ui/reconnect-banner--desktop.png differ diff --git a/packages/paperclip-runner/knowledge/evidence/phase-07/ui/reconnect-banner--mobile.png b/packages/paperclip-runner/knowledge/evidence/phase-07/ui/reconnect-banner--mobile.png index e9f753efb62..58a653abbce 100644 Binary files a/packages/paperclip-runner/knowledge/evidence/phase-07/ui/reconnect-banner--mobile.png and b/packages/paperclip-runner/knowledge/evidence/phase-07/ui/reconnect-banner--mobile.png differ diff --git a/packages/paperclip-runner/knowledge/evidence/phase-07/ui/replay-mode--desktop.png b/packages/paperclip-runner/knowledge/evidence/phase-07/ui/replay-mode--desktop.png index 3f211407af5..2e518b4c9e0 100644 Binary files a/packages/paperclip-runner/knowledge/evidence/phase-07/ui/replay-mode--desktop.png and b/packages/paperclip-runner/knowledge/evidence/phase-07/ui/replay-mode--desktop.png differ diff --git a/packages/paperclip-runner/knowledge/evidence/phase-07/ui/replay-mode--mobile.png b/packages/paperclip-runner/knowledge/evidence/phase-07/ui/replay-mode--mobile.png index 83312449b24..e50665e879e 100644 Binary files a/packages/paperclip-runner/knowledge/evidence/phase-07/ui/replay-mode--mobile.png and b/packages/paperclip-runner/knowledge/evidence/phase-07/ui/replay-mode--mobile.png differ diff --git a/packages/paperclip-runner/knowledge/evidence/phase-07/ui/thread-baseline--desktop.png b/packages/paperclip-runner/knowledge/evidence/phase-07/ui/thread-baseline--desktop.png index f991651de28..4fa0e8d0a13 100644 Binary files a/packages/paperclip-runner/knowledge/evidence/phase-07/ui/thread-baseline--desktop.png and b/packages/paperclip-runner/knowledge/evidence/phase-07/ui/thread-baseline--desktop.png differ diff --git a/packages/paperclip-runner/knowledge/evidence/phase-07/ui/thread-baseline--mobile.png b/packages/paperclip-runner/knowledge/evidence/phase-07/ui/thread-baseline--mobile.png index 3f127a9471e..ce8eb00a19e 100644 Binary files a/packages/paperclip-runner/knowledge/evidence/phase-07/ui/thread-baseline--mobile.png and b/packages/paperclip-runner/knowledge/evidence/phase-07/ui/thread-baseline--mobile.png differ diff --git a/packages/paperclip-runner/knowledge/evidence/phase-07/ui/turn-streaming--desktop.png b/packages/paperclip-runner/knowledge/evidence/phase-07/ui/turn-streaming--desktop.png index aaa68a944dc..567660b15c3 100644 Binary files a/packages/paperclip-runner/knowledge/evidence/phase-07/ui/turn-streaming--desktop.png and b/packages/paperclip-runner/knowledge/evidence/phase-07/ui/turn-streaming--desktop.png differ diff --git a/packages/paperclip-runner/knowledge/evidence/phase-07/ui/turn-streaming--mobile.png b/packages/paperclip-runner/knowledge/evidence/phase-07/ui/turn-streaming--mobile.png index 2b06ab765e7..701946904aa 100644 Binary files a/packages/paperclip-runner/knowledge/evidence/phase-07/ui/turn-streaming--mobile.png and b/packages/paperclip-runner/knowledge/evidence/phase-07/ui/turn-streaming--mobile.png differ diff --git a/packages/paperclip-runner/scripts/record-phase7-ui-evidence.mjs b/packages/paperclip-runner/scripts/record-phase7-ui-evidence.mjs index f92c542c166..5a288324083 100644 --- a/packages/paperclip-runner/scripts/record-phase7-ui-evidence.mjs +++ b/packages/paperclip-runner/scripts/record-phase7-ui-evidence.mjs @@ -81,6 +81,35 @@ async function startPreview() { // Set by `record` so a drift report can name the Chromium build that produced it. let browserVersion = "unknown"; +let fontProbe = { interWidth: 0, dejavuWidth: 0, interResolves: false }; + +/** + * The committed matrix is recorded with Inter active. When fontconfig cannot + * resolve Inter, every text node falls back to DejaVu Sans and all 24 shots + * drift at once — refuse to record or compare under that environment instead + * of producing a whole-page mystery diff. + */ +async function probeFonts(browser) { + const context = await browser.newContext(); + const page = await context.newPage(); + const probe = await page.evaluate(() => { + const canvas = document.createElement("canvas").getContext("2d"); + const sample = "Wire the runner spike to the mock control plane"; + const width = (font) => { + canvas.font = font; + return Math.round(canvas.measureText(sample).width); + }; + const interWidth = width("700 24px Inter"); + const dejavuWidth = width('700 24px "DejaVu Sans"'); + return { + interWidth, + dejavuWidth, + interResolves: document.fonts.check("16px Inter") && interWidth !== dejavuWidth, + }; + }); + await context.close(); + return probe; +} async function record(targetDir) { await mkdir(targetDir, { recursive: true }); @@ -92,6 +121,15 @@ async function record(targetDir) { browserVersion = browser.version(); const recorded = []; try { + fontProbe = await probeFonts(browser); + if (!fontProbe.interResolves) { + throw new Error( + `font environment mismatch: "Inter" does not resolve distinctly ` + + `(Inter ${fontProbe.interWidth}px vs DejaVu Sans ${fontProbe.dejavuWidth}px). ` + + "The committed matrix is recorded with Inter active; make Inter visible to " + + "fontconfig before recording or checking.", + ); + } for (const viewport of VIEWPORTS) { for (const slug of PHASE7_UI_SHOT_SLUGS) { const context = await browser.newContext({ @@ -146,6 +184,15 @@ async function main() { "", ...manifest.map((name) => `- \`${name}\``), "", + "## Recording environment", + "", + `- Chromium ${browserVersion} — pin the exact binary with \`PAPERCLIP_CHROMIUM_BIN\``, + " (honoured by the agent-browser wrapper) alongside", + " `PAPERCLIP_RUNNER_CHROMIUM_PATH`.", + `- Sans stack resolves to Inter (probe: Inter ${fontProbe.interWidth}px vs`, + ` DejaVu Sans ${fontProbe.dejavuWidth}px for the title string). The recorder`, + " refuses to run when Inter does not resolve.", + "", ].join("\n"), "utf8", ); @@ -183,10 +230,12 @@ async function main() { "Phase 7 UI evidence is not byte-stable:", ...drift, "", - `Recorded with Chromium ${browserVersion}.`, - "Committed PNGs are pinned to one Chromium build. A wholesale mismatch", - "usually means a different browser, not a UI regression: set", - "PAPERCLIP_RUNNER_CHROMIUM_PATH to the Chromium that recorded them.", + `Recorded with Chromium ${browserVersion}; sans probe Inter=${fontProbe.interWidth}px, DejaVu Sans=${fontProbe.dejavuWidth}px.`, + "Committed PNGs are pinned to one Chromium build and one font environment.", + "A wholesale mismatch usually means a different browser or font set, not a", + "UI regression: set PAPERCLIP_RUNNER_CHROMIUM_PATH (and PAPERCLIP_CHROMIUM_BIN", + "for the wrapper) to the Chromium that recorded them, and compare the font", + "probe against knowledge/evidence/phase-07/ui/index.md.", "", ].join("\n"), );