Skip to content

Give the shooter its one missing flag, and redraw the frames - #103

Merged
EnesYilmazcode merged 3 commits into
mainfrom
claude/open-issues-eymdb2-shooter
Sep 2, 2026
Merged

Give the shooter its one missing flag, and redraw the frames#103
EnesYilmazcode merged 3 commits into
mainfrom
claude/open-issues-eymdb2-shooter

Conversation

@EnesYilmazcode

Copy link
Copy Markdown
Owner

docs/media had drifted a release behind the app: list.webp and list-full.webp still showed the duration chip bar #95 deleted, and room.webp still showed the on-map walk-time pill #94 removed. Twice the conclusion was that no browser was available in this environment. It was available, and the blocker was one launch argument.

The diagnosis: one flag

Chromium is at /opt/pw-browsers/chromium-1194/chrome-linux/chrome (Chromium 141). chromePaths() only searched /usr/bin/* and /snap/bin/chromium, so CHROME= was needed to get past findChrome() — and then the launch died with chrome exited with 1. That exit is Chromium's sandbox: it needs a non-root user to drop privileges to, refuses to start without one, and dies before it ever writes DevToolsActivePort. CI and container runs are root, so --no-sandbox is now added only when process.getuid?.() === 0; on a normal desktop account the sandbox stays on.

chromePaths() also learned the Playwright cache (PLAYWRIGHT_BROWSERS_PATH, then ~/.cache/ms-playwright, newest build first), so CHROME= is no longer required here. node scripts/shoot.mjs and --check both run clean with no environment variables set.

What was regenerated

All five frames in one run, not just the two stale ones, so the set is one moment of one app. Pinned clock (2026-09-16T10:20 Eastern) and pinned position (Thompson Library steps) unchanged — the same photograph, of a newer app.

The app prints different things now, so frames.json and the README follow the pictures:

  • the chip bar is gone; the sheet says "You asked for 2h00."
  • the ranking changed and departmental rooms carry a · departmental label, so the top rows are Cunz Hall 160 and PAES A111 where they were Psychology Building 115 and University Hall 448
  • the room screen's second button reads Directions, not Maps
  • ask.webp shows four buttons under "How long?", not three under "How long do you need?" — alt text that was already off the image before this change

The README's worked example read the third row of the middle screenshot, which is no longer Psychology Building 217. It now reads the second row, PAES A111. Every number in that paragraph is measured: the row and the room screen both print free till 4:00pm, the room screen prints Yours for 5h36 once you get there (read off the app during the shoot, via the script's own probe output), and PEA0111's Wednesday interval in data/rooms-1268.json starts at minute 970 — 4:10pm — which is the ten minutes of packup the row takes off. The #77 sentence keeps its point without quoting the old room's number.

How the images were verified

By opening each .webp and looking at it, before and after, not by exit code:

  • list.webp — before: a chip row 30m / 1h / 2h / rest of day pinned under the list, 2h lit red. After: no chip bar; the sheet header reads "You asked for 2h00." and the first row is Cunz Hall 160, 4 min.
  • room.webp — before: a red-on-black "3 min walk" pill sitting on the dashed line mid-map, plus the chip bar. After: the dashed line and the lit footprint are there and the pill is gone; the selected row is lit in the list with its chevron.
  • list-full.webp, timeline.webp, ask.webp — checked too: eight rooms in eight buildings 3–7 min out, the Cunz Hall 160 calendar with its two KNSISM blocks and the now-line at 10:20, and the four-button question screen.

Bytes

frame before after
ask.webp 76,668 79,702
list.webp 190,164 194,930
list-full.webp 172,926 189,674
room.webp 144,054 149,580
timeline.webp 120,482 149,184
total 704,294 763,070

+58,776 bytes, +8.3%. The frames are unchanged in size (1179x2556) and quality (WebP 95); the increase is content — the full-height list now carries eight taller rows, and the timeline frame shows a calendar with more drawn in it than the old one.

Checks

  • npm test — 731 tests, 727 pass, 0 fail, 4 skipped, matching the baseline on main. The readme test caught the drift first: it failed on list.webp alt text says "25 seats" and the screen does not until the alt text was rewritten to the new picture.
  • node scripts/check-dead-code.mjs --strict84 files, no dead code.
  • node scripts/shoot.mjs --check — clean, all five frames pass the blankness and stillness gates.

Not done

  • sw.js untouched: no SHELL_CACHE re-stamp, no SHELL_ASSETS edit.
  • The README's npm test # node --test, 589 tests, no network line is stale (it is 731 now). Left alone as unrelated to this change.
  • The first --check run of the session threw once inside boot() — an evaluate against about:blank before the navigation landed — and has not reproduced across the four runs since. Not chased in this PR; it is a race in Page.navigate/waitFor, not the sandbox.

🤖 Generated with Claude Code

https://claude.ai/code/session_017xiX95r6nnUUmhD3KwMnWM


Generated by Claude Code

docs/media had drifted a whole release behind the app: list.webp and
list-full.webp still showed the duration chip bar #95 deleted, and
room.webp still showed the on-map walk-time pill #94 removed. Twice the
conclusion was that no browser was available here. It was, and the
blocker was one launch argument.

Chromium's sandbox needs a non-root user to drop privileges to and
refuses to start without one, so as root it exits 1 before it ever
writes DevToolsActivePort — the "chrome exited with 1" that got read as
"no browser". --no-sandbox is added only when process.getuid() is 0, so
a desktop run keeps its sandbox. chromePaths() also learned the
Playwright cache (PLAYWRIGHT_BROWSERS_PATH and ~/.cache/ms-playwright,
newest build first), which is where the Chromium on this machine lives;
CHROME= still works and is no longer needed.

All five frames were regenerated in one run, not just the two stale
ones, so the set is one moment of one app. The pinned clock and pinned
position are unchanged, so the frames are the same photograph they
always were, of a newer app.

What the app now prints changed with them, so frames.json and the README
follow the pictures rather than the other way round:

  - the chip bar is gone and the sheet says "You asked for 2h00."
  - the list ranks differently and departmental rooms carry a label,
    so the top rows are Cunz Hall 160 and PAES A111
  - the room screen's second button reads Directions, not Maps
  - ask.webp shows four buttons under "How long?", not three under
    "How long do you need?" — alt text that was already off the image

The README's worked example pointed at the third row of the middle
screenshot, which is no longer Psychology Building 217. It now reads the
second row, PAES A111: the row and the room screen both say free till
4:00pm, the room screen says Yours for 5h36 once you get there (read off
the app during the shoot), and PEA0111's Wednesday interval in
data/rooms-1268.json starts at 970 minutes, 4:10pm, which is the ten
minutes of packup the row takes off. The #77 sentence keeps its point
without the old room's number.

Verified by opening each frame: no chip bar under the list, no "3 min
walk" pill on the map in room.webp.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017xiX95r6nnUUmhD3KwMnWM
…ndbox

Review verified every new README number from primary sources and found the
shooter's own race is more frequent than this branch disclosed: it hit on
the reviewer's first --check and twice in nine runs, roughly 20%, not the
zero-in-four reported here.

Page.navigate resolves when the navigation BEGINS, not when the document
commits, so the three predicates after it can run against the OUTGOING page.
From about:blank that is a loud crash and harmless. The second boot() of a
shoot reloads the SAME url, and there the stale document is the already
booted app: every predicate passes against it, boot() returns while the
reload is still in flight, and the ask frame can be a photograph of the
list. A wrong picture that looks right is the one failure this script must
not have, because nothing downstream can tell. It marks the document and
waits for the mark to disappear; only a committed navigation clears a
property set on the old one.

child.stderr.resume() threw away the browser's own explanation and left a
bare "chrome exited with 1". Two agents read that message and concluded no
browser existed on this machine, when the discarded text named the sandbox
and the fix was one flag -- this whole branch is the cost of that line. The
last 4 KB of stderr is kept and printed with the exit code.

Two alt texts described things the pictures do not show. list.webp's cited
"117 rooms free, 39 shown", which is the #say live region: .sr is 1px and
clip-path inset(50%), so no sighted reader can find it, and readme.test.mjs
cannot catch it because it checks alt numbers against innerText, which
includes screen-reader-only nodes. ask.webp's listed four duration buttons
as peers when 2 hours is filled accent red in the frame, which is also the
choice that makes the next screenshot read "You asked for 2h00."

The header claimed the finder covers a Playwright Chromium; that splice is
on the Linux branch only, and win32 and darwin return before it. Narrowed to
what the code does.

Re-ran the shooter after the race fix: all five frames and frames.json come
back byte-identical to the committed ones, so the change is to the failure
mode and not to the output.

731 tests, 727 pass, 0 fail. check-dead-code --strict: 84 files, no dead
code.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017xiX95r6nnUUmhD3KwMnWM
@EnesYilmazcode
EnesYilmazcode merged commit 7bf7b7e into main Sep 2, 2026
2 checks passed
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.

2 participants