Skip to content

fix(foyer): R2 walkthrough repair — order, plain captions, aspect, distinct frames - #11

Merged
HomenShum merged 3 commits into
mainfrom
foyer-walkthrough-r2
Sep 13, 2026
Merged

HomenShum merged 3 commits into
mainfrom
foyer-walkthrough-r2

Conversation

@HomenShum

Copy link
Copy Markdown
Owner

What changed since PR #10

PR #10 (f1768ab, merged as a0750d1) shipped FOYER-V3's first three Node Foyer
walkthroughs (FYwall, FYphone, FYagent). Round-10 review (Judge/HRE/Steward)
found: the sealed FYwall/FYphone mp4 and judge verdicts predated the sealed
frames by 12 minutes (re-captured after rendering); FYphone published over a
judge P0 (jargon) and FYwall over two P1s; FYphone's GIF was a 390x219
letterboxed 16:9 clip; FYwall frames 00-03 were byte-identical and one caption
hardcoded a stale count; FYagent was judged rework (no persona, no cursor
interaction). This PR repairs all four items assigned to this worker.

Storyboard table (final, this branch)

id viewport captureKind frames distinct?
FYwall 1440x900 production 7 yes (all 7 sha256 unique)
FYphone 390x844 production 5 yes (all 5 sha256 unique)
FYagent 1440x900 preview (built preview, port 5270) 4 yes (all 4 sha256 unique)

All 16 frame sha256s are globally unique across the three captures. Every
capture's capturedAt < renderedAt < judgedAt (real timestamps, no re-capture
after render this round).

Judge results (Gemini gemini-3.6-flash, run twice per final mp4, worse

verdict + max P0 recorded per this repo's own documented judge variance)

id run 1 run 2 recorded (worse) P0 / P1 / P2
FYwall fix-then-publish publish fix-then-publish 0 / 1 / 1
FYphone publish publish publish 0 / 1 / 1
FYagent fix-then-publish rework rework 1 / 3 / 0

FYwall and FYphone: zero P0 on both runs after the caption rewrite (the
original P0/P1s were exactly the jargon words the judge cited — "sha256",
"ledger stability count", "soft-hyphenated", "inert backdrop", "stranded on
body" — all replaced with plain-language equivalents; "sweep" is now
explicitly glossed on first use since the product's own header text uses it).

FYagent still comes back rework. This is the same structural limitation this
repo's own f1768ab commit already named and deferred: goto-based JSON
navigation has no in-app element to animate a cursor onto, so motion_craft and
cursor_truth stay low even with a real persona and a full round-trip storyboard
(the round-2 fix here). A real fix needs a fake-browser-chrome address bar or a
curl-style panel — bigger than a caption rewrite, left for a follow-up round
exactly as the original commit said. Recorded honestly rather than resampled
until a better verdict appeared (this repo's README explicitly warns against
that: re-asking a judge until the number improves is a bias, not a fix).

What else changed

  • Order enforced structurally: capturedAt/renderedAt/judgedAt are now three
    independently-sourced timestamps (capture-time write, mp4 mtime, judge's own
    clock) instead of being able to drift apart via an out-of-order re-run.
  • FYphone renders at its own portrait aspect: Walkthrough.jsx takes an
    optional per-composition canvasW/canvasH (defaults preserve every other
    caller — Root.jsx, RoomOsRoot.jsx — unchanged); FoyerRoot.jsx derives it
    from each capture's own viewport. FYphone's canvas is now 780x1688 (was
    1920x1080, hence the letterboxed GIF); final GIF 270x585 (was 390x219).
  • Distinct frames: new "center" and "scrollAbs" act types in
    walkthrough.foyer.mjs; a caption may carry a live-read {n} placeholder so
    a number in a caption can never go stale relative to what the frame shows.
  • FYagent persona rewrite: an integrator wiring their own agent to the
    board, with cursor moves onto real content (wall root, then each contract
    file's own <pre> body) and a full loop back to the wall.

Media (published into node-foyer's public/media/walkthroughs//)

id poster gif aspect match
FYwall 720x450, 38.2 KB 400x250, 855 KB exact (1440x900)
FYphone 390x844, 43.2 KB 270x585, 896 KB 0.07% off (390x844)
FYagent 720x450, 38.6 KB 400x250, 422 KB exact (1440x900)

Total posters+GIFs: ~2.19 MB (budget 4 MB). Every poster is a single-frame PNG
(no APNG); every GIF's frame content verified legible via direct ffmpeg-decoded
frame extraction (not ImageMagick's [N] indexing, which mis-decoded these
diff-mode GIFs and briefly looked like a real defect before cross-checking).

Not done here (by design, out of this worker's scope)

  • FYagent's rework verdict stands; a real fix is a bigger feature (address-bar
    chrome / curl panel), not a caption change.
  • node-foyer's public/media/walkthroughs.json seal and data/walkthroughs.manifest.json
    are the planner's/this worker's node-foyer-side deliverable, reported separately.

🤖 Generated with Claude Code

HomenShum and others added 3 commits September 12, 2026 20:23
…spect, distinct frames

Repairs all four round-10 findings assigned to this worker for FYwall/FYphone/FYagent:

- Order is now strictly capture -> render -> judge every time: capturedAt is written
  once at capture, renderedAt is the real mtime of the rendered mp4, judgedAt comes
  from the judge's own timestamp. No re-capture after rendering this round; any
  content fix always went back through all three stages, never patched judge output
  alone. capture.json also now carries `viewport` and a demoUrl fixed to the literal
  "built preview" for FYagent (round-10 minor: it shipped a localhost URL).

- Captions rewritten in plain words throughout (round-10 P0 on FYphone, P1s on
  FYwall): no "soft-hyphenated", "inert backdrop", "stranded on body", "44px
  target", or unglossed "sweep" — every technical fact is said in terms of what a
  first-time visitor sees and why it matters. "Verified" is explained as the
  product's own deploy workflow reading its live page back and confirming the
  build ids agree. Re-judged (Gemini, run twice per final mp4 per this repo's own
  documented judge variance, worse verdict + max P0 recorded): FYwall
  fix-then-publish 0 P0, FYphone publish 0 P0. FYagent still comes back rework —
  a structural limitation this repo's own f1768ab commit already named (goto-based
  JSON navigation has no in-app element to animate a cursor onto; a real
  address-bar/curl panel is the actual fix) — recorded honestly rather than
  resampled or reframed until a good number appeared.

- FYphone now renders at its own portrait aspect instead of letterboxing inside a
  fixed 16:9 canvas (round-10 P0 evidence: a 390x219 illegible GIF). Walkthrough.jsx
  takes an optional per-composition canvasW/canvasH (defaults preserve every other
  caller's existing 1920x1080 unchanged); FoyerRoot.jsx derives it from each
  capture's own viewport (390x844 -> 780x1688 canvas, matching aspect exactly;
  1440x900 captures render 1:1). Final GIFs: FYwall 400x250, FYphone 270x585,
  FYagent 400x250 — all within 0.1% of their capture's aspect ratio.

- Every beat now produces its own distinct frame (round-10 minor: FYwall 00-03 and
  FYphone 03-04 were byte-identical). walkthrough.foyer.mjs gains "center" (scroll
  a different card to the middle of the viewport) and "scrollAbs" (an explicit
  pixel offset, for cases where centering an element near the top clamps to the
  same scroll position a prior frame already used) act types. A caption may now
  also carry a live-read {n} placeholder — FYwall's "held steady for N checks"
  used to hardcode a stale count; it now reads the real attribute value at capture
  time.

- FYagent's storyboard is rewritten around an explicit persona (an integrator
  wiring their own AI agent to the board before anything is connected) with real
  cursor moves that land on content each frame actually shows: the wall root, then
  the two contract files' own <pre> body, then a full round trip back to the wall
  re-confirming the same honest "file" label. Captured against a built preview of
  node-foyer HEAD (ad70fc8d) with VITE_CONVEX_URL unset, port 5270.

FYwall/FYphone captureBuildSha ec2a44e19b (production); FYagent ad70fc8d127f74
(built preview, matches HEAD at capture time). All three build shas verified as
ancestor commits of node-foyer HEAD. All frame sha256s are globally unique across
the three captures.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
@HomenShum
HomenShum merged commit 4c83398 into main Sep 13, 2026
2 checks passed
@HomenShum
HomenShum deleted the foyer-walkthrough-r2 branch September 13, 2026 03:39
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.

1 participant