85 KiB
C2a Home, folders, What's New: evidence log
Package card: docs/phase2/PLAN.md §2.4 "C2a Home, folders, What's New". Concept: docs/phase2/concepts/home-apps.md (HA, owned by C2a) and docs/phase2/concepts/xc-home-search.md (XC, owned by C2a). Steam build at the time of writing: 11094443 (C1b's and P10's reading of /tmp/lgs/steam-build.json, 2026-10-07; this session needed no device step).
C2a owns: theme/41-home.css, device/rt/41-home.js, device/rt/41-search-apps.js, theme/layers/41-home.json, docs/phase2/concepts/home-apps.md, docs/phase2/concepts/xc-home-search.md, the mockups home-apps-home.html, -home-t1.html, -apps.html, -collections.html, -folder.html, -depth.html, -search.html, home-apps.css, home-apps.js, home-apps-icons.js, this log and docs/phase2/wp/C2a-cmp.json.
Status
Round R2 fix pass 1 done (session 6, 2026-10-07 17:10-21:06). Not READY: one gate result is open (G-OUTLINE on the Apps section with pad focus on a program cell, REQ C2a->P10 #22), and AT-13 is half met (REQ C2a->C1b #23). Everything else of the review is fixed and re-run live in both input modes; with those two settled, the state to mark READY is wp.c2a with wp.p3 and wp.c1a.
- Fixed (code deployed,
_wipidentical, evidence rows R2F- and AT- below):** majors M1, M3, M4, M5, M6, M7, M8, M9, M10 (motion tokens; the b20 easing itself is disputed, D-C2a-15), M11, M12, M13, M14, M15 (M2 was fixed by P3); minors m1, m2, m4, m5, m6, m7, m8, m10, m11, m12, m13, m14, m15. - Not fixed: m3 (P-16 selected-segment glow band reads dL 0 in the bright room: recorded, the glow is P4's white rim), m9 (text-glyph badges kept, D-C2a decision), m16 (folder while the module is failed: C1a's map, REQ #18), off-axis bare disc glass at 30° (P7, REQ P8->P7 already open).
- Gates, batch 12/13 (20:04-21:04, CSS-only,
--flags wp.c2a,wp.p3,wp.c1a): SIZE / TYPE / OUTLINE / MOTION PASS at rest, card open, folder, Reduce Motion and Increase Contrast in both modes; Collections and Apps in pad fail OUTLINE only on the focused disc's left edge (P4's raised-material rim light, ratio .388; the crop looks right: a soft rim, no hairline), REQ #22; What's New TYPE fails only on Steam's own Friends count "1" (12 px, Steam's feed, not ours). MOTION close under Reduce Motion fixed this pass (the segment's P4 pseudo-element transitioned--lgs-focus).pad-bfsWhat's New truncated at budget (Steam's feed, 340 moves), not a defect of ours. - Native: two
native-sessionruns (19:45, 19:58): all foursgcheckstates PASS in the second; Steam's texture under the open card holds only the card. Left in CSS-only. - Device at the end: theme on, CSS-only, route
/library/home(stock), no flags, no menu, pointer parked; every hv frame deleted on both machines; nothing launched (all launchesmode: logged), no setting changed.
Earlier milestones:
Session 5 status (superseded by the R2 fix pass):
READY: wp.c2a (with wp.p3 and wp.c1a, which it was verified with: P3 gives attention and the input stub, C1a's shell answers the windowless hook; without wp.p3 the module does not install and Home stays Steam's page with the T1 restyle). Milestone reached: M3 (T3), 2026-10-07 09:45 (session 5, expedited, the last C2a session). Native (T5) is written and runs, but native Home is not ready: see REQ C2a->P8 #17.
- Evidence for READY (CSS-only,
--flags wp.c2a,wp.p3,wp.c1a, build 11094443, 08:26-09:20; runs that another agent's native session overlapped were rerun, M3-G1):gates(SIZE, TYPE, OUTLINE, MOTION) PASS in both--mode laserand--mode padon Home at rest, Home with the card open, Collections, Apps and a folder (VR). What's New (/library/lgs/steamhome): TYPE, OUTLINE, MOTION PASS; SIZE has one item, Steam's sale banner sampled below the window edge (gate defect, REQ C2a->P10 #13).- AUD:
/library/lgs/steamhomeagainst stock/library/homeby relative DOM path: 190 visible items, 151 controls, 0 GONE / HIDDEN / SHRUNK / UNCLICKABLE / TEXT (M3-AUD;gates --stock-routekeys by absolute path, so it lists every item GONE for a moved page). - Gamepad: honeycomb, top row, sections and pages re-tested on the final code (M3-N2, all as M3-N1); B at the Home root bubbles to Steam, which goes back in history exactly as on stock Home (
b_probe.js, stock);pad-bfs13 nodes reached, 0 irreversible; 5 targets unreached only because the sweep cannot recover after Left on the search field leaves the main window, which stock Home does too (REQ C2a->P10 #14). - No runtime errors: module
homeinstalled, its log has no warning or error after Recent, the card, Collections and Apps (M3-E1). - Functions: X / Play and the card's Play log
primarythrough P2's action logger; More and ≡ open Steam's own tile menu; folders and What's New routes work (M3-M1, M3-C1, M3-R1).
- Session 5 changes:
41-home.json: the card and name plate rules come before the disc rule, and the disc of the card's own cell is excluded (the open card was dropped as "overlaps a kept layer").41-home.js: disc plates are circles (data-lgs-plate-r="capsule"; Steam's 50 % radius was read as 50 px, r 75 of 180); only the card's own cell is an occluder; mosaic bands follow the low layout (the discs' lower 34 px were outside the bands); the folder's top row is a plain row (a one-control Focusable was judged as a 1280 × 108 target over Steam's header) and its title takes no pointer events; cells carry their name asaria-labeland a stable first classc2a-cell/c2a-seg(pad-bfs keys); Up returns to the top-row control that Down came from (D-C2a-13). A trial that kept focus at row ends and consumed B was reverted after stock probes (D-C2a-13). - Native (T5) check, three
native-sessionruns, 09:19-09:39 (P7 is at M1; the user asked for the native glass work, so it was run): the reporter gives exactly the planned report:windowless, no cover, 18 plates (C1a's Back and search, section track, What's New, 13 discs, the card), 4 mosaic bands over the plates, one pophome-cardat +15 mm (dz 0.0407),interactive: false, no errors; at rest no pops (sgcheck PASS).sgcheckwith the card open: one FAIL, R1 on the card's square corner (sgcheck ignores the pop's own radius, REQ C2a->P10 #16). Headset view: wrong. Threehv --lookframes (viewed, deleted on both machines): the first showed another page, the second and third showed native Home as a grey rounded slab about 1280 × 656 with no disc glass and no disc art (labels and dots visible). The CSS-only frame of the same minute showed Steam's T1 Home: the headset texture lags the DOM by several seconds. Filed REQ C2a->P8 #17 (daemon / glassd withshapes: [], plates and explicit mosaic on windowless surfaces). Left in CSS-only mode ("back to CSS only: yes"). - Files:
theme/41-home.css,device/rt/41-home.js,theme/layers/41-home.json,docs/phase2/wp/C2a-cmp.json;_wipcopies identical.device/rt/41-search-apps.jsnot written: C1b's21-search.jsappeared during this session but C1b is at M0; the provider is the next step for whoever continues (C1b's "Interface announced", HA §6). - How to run the T3 Home in a step:
--flags wp.c2a,wp.p3,wp.c1aand--mode laser|pad; wait about 1.5 s in the pre for the module to install and the override to re-enter the route. The module is removed at the step's exit. - Open, owned by others: REQ #6 (C2c: delete the Home rules from
40-library.css), #5 (C1b), #11 (P2locarguments), #13, #14, #16 (P10 gates, pad-bfs, sgcheck), #17 (P8/P9 native windowless). C2c's REQ-7 to the coordinator. - Known gaps (not route-matrix states): Friends activity feed, Recommended store widgets, store capsules' 12 px prices and 28 px avatars (M2-G3, D-C2a-8). AT-10 (native pop at 0.041 u) is met by the report, not yet by the headset (REQ #17).
Milestone reached: M2 (T1), 2026-10-07 06:55 (session 3), with one gate item blocked outside this package: G-SIZE P-08 on Steam's partly visible sale banner at rest (%{SeasonalSale}, cut by C1a's glass clip at y 656), REQ C2a->P10 #9. M0 was reached in session 2. M3 (session 4 from 07:16, reached in session 5): device/rt/41-home.js slice 2 is live behind wp.c2a: Steam's footer hidden as Steam's Home hides it (footer store HideFooter(), no #Footer node), explicit honeycomb neighbours with one-step memory and D-pad page turning, LB/RB sections, Steam's own tile menu (Steam's app context menu component, found by source) from ≡ and the card's More, Steam tokens for strings with glyph segments, the library sets as folders with their tabs, art candidates (custom .jpg/.png), the card's playtime line, What's New and folder routes (Evidence M3-*).
- M2 evidence (CSS-only,
/library/home, laser and pad, build 11094443): rest and "focus on a shelf card": G-AUD, G-TYPE, G-OUTLINE, G-MOTION PASS; G-SIZE PASS but the banner item (M2-G1). Feed scrolled: all five PASS (M2-G2). G-PAD parity with stock (M2-P1). T3-node CSS on a static fixture: mockup rects within 0-6 px (M2-C1), SIZE/TYPE/OUTLINE PASS both modes (M2-C3), P-14 +62 L (M2-F1).
Requests
-
REQ C2a->C1a: #1 route map,
/library/home: make itwindowlessonly when C2a's hook answers.41-home.jswill register__LGS_RT.shell.glassMode('home', () => live ? 'windowless' : null)(the hook WN §3.1.1 already offers C5a and C3b); withnull, or no hook registered, usewindow-full(Steam's own Home in a window, which hides its footer). Why: if the Home override fails to install (P2 fail-closed), WN's map would still saywindowlessand Steam's Home feed would float over the room with no glass (HA §3, §3.7, AT-22)./library/lgs/folder/*can stay unconditionallywindowless(those routes exist only while the override runs). C1a answer (2026-10-07, session 2): adopted (WN §3.1.1):/library/homeiswindowlessonly while your hook answers; withnull, a throwing hook or none, it iswindow-full. Hook:__LGS_RT.shell.glassMode('home', fn)→{remove()}; call__LGS_RT.shell.refreshGlass()iflivechanges after the route settled. Folders staywindowless. -
REQ C2a->C1a: #2 on every
windowlessroute (Home, folders,/invites, CC-M), tag Steam's Back circle and the search circle as plates:data-lgs-plate="liquid"with stable ids (suggestedshell-back,shell-search). Why: on windowless routes there is no window cover, so the toolbar row's glass must be plates (PLAN §1.2, reporter §2.2); these are Steam's nodes styled by C1a, so C2a should not tag them from41-home.js(HA §10.2). C1a answer: adopted (WN §3.2 "Windowless routes"): on everywindowlessroute the shell's T2 tags the Back circledata-lgs-plate="liquid"+data-lgs-plate-id="shell-back"and the search circle"shell-search"; CSS-only they take the CSS plate look. C2a tags nothing in the toolbar. -
REQ C2a->C1c: #3 menus, alerts and sheets on
windowlessroutes: report the menu box (and the alert or sheet card) as a plate,data-lgs-plate="thick", whiledata-lgs-glass="windowless". Why: PLAN §1.7 rule 1 admits a pop only inside a cover or a plate, and windowless routes have no cover; without the plate the tile menu opened from Home's card (HA §8) or any alert over Home loses its +10 mm (safe, but flat). With it, the menu reads as glass in native mode too.- C1c (2026-10-07 07:35): accepted. It is native-layer work: the menu slab / alert / sheet card gets a
thickplate whiledata-lgs-glass="windowless", in C1c's M4 fragmenttheme/layers/22-presentations.json(next round, with P6's plate reporting); left open until then. In CSS-only mode the scrim is already clipped to the whole quad (radius 54) on windowless routes. - C1c (2026-10-07 08:20, session 3): done in T2.
device/rt/22-menus.js(flagwp.c1c) setsdata-lgs-plate="thick"on the menu slab (contextMenuContents) and on the alert or sheet card while main's[data-lgs-glass="windowless"]; native verification (G-DEPTH) comes with C1c's M4 fragment next round.
- C1c (2026-10-07 07:35): accepted. It is native-layer work: the menu slab / alert / sheet card gets a
-
REQ C2a->P10: #4 a stock-route option for
glass.py gates/audit(for example--stock-route /library/home), so AUD compares our route (theme on) with a different stock route (theme off). Why: the Home override moves Steam's Home nodes to/library/lgs/steamhomeby design; HA AT-6 audits them there against stock/library/home(HA §15 #14).- P10 (2026-10-07 06:35): done:
gates … --stock-route R2andaudit … --stock-route R2snap R2 with the theme off and--route Rthemed (the pre is run again after returning). AUD keys are DOM paths, so the moved page must keep Steam's DOM structure for rows to pair up.
- P10 (2026-10-07 06:35): done:
-
REQ C2a->C2c: #6
theme/40-library.css: please delete the Home rules now thattheme/41-home.csscarries them (PLAN §6 row40-library.css: "Home shelf and feed rules →41-home.css"): every selector scoped by%{RecentSection}or%{RecentSection} ~ %{TabbedContent}in your §1 (the--lgs-home-tab-*anchors, the home half of the tab capsule, segments and arrows), §3 (drop%{RecentSection}and%{RecentSection} ~ %{TabbedContent}from the:is()), §4 (Recent Games shelf), §5 (Home panels, incl. Friends and Recommended), §9's%{LibraryHomeEmptyGames}block and §10's home half. Why: two copies fight on specificity (41-home.css had to out-rank your:is()scope for the capsule ring and hover ring), and the Phase 1 values (uppercase 12 px tabs, 1 px rings,--lgs-glass-rim) fail G-TYPE / G-OUTLINE on/library/homewhenever a rule of yours wins.- C2c (2026-10-07, R2 fix pass): done since C2c session 2:
theme/40-library.csshas no%{RecentSection}rule; it holds only library-catalogue rules under%{GamepadLibrary}, the toolbar pill, the library's ornament rules, Library Filters and the scrubber.
- C2c (2026-10-07, R2 fix pass): done since C2c session 2:
-
REQ C2a->P10: #7
gatessweeps count content the window glass clips away. Onwindowroutes C1a clips the page at y 656 (clip-pathon%{BasicHome}, 20-shell.css §1), but SIZE samples its 80 px box around the control's full-rect centre, TYPE and AUD treat clipped text as visible, and OUTLINE probes clipped top edges. Seen on/library/homeat rest:%{SeasonalSale}(rect y 610-825, visible only 610-656) fails P-08 "hit 91 % own, 0 % other" because its centred box (y 677-757) lies wholly in the clipped strip, whereelementFromPointreturns the root. Please intersect each control's rect with its ancestors' clip and overflow boxes (and the glass height,--lgs-c1a-gh) before sampling, and skip text or edges outside it. Why: any page with content under the glass bottom fails these sweeps without a visible problem.- P10 (2026-10-07 06:35): done: each element's visible rect is cut by every clipping ancestor (overflow other than visible,
clip-path), the window and--lgs-c1a-gh; SIZE and TYPE skip what is clipped away (skipped: clipped), SIZE skips controls whose centre lies under chrome outside their scroller (skipped: obscured), and OUTLINE probes only visible top edges.
- P10 (2026-10-07 06:35): done: each element's visible rect is cut by every clipping ancestor (overflow other than visible,
-
REQ C2a->P10: #8 SIZE's P-83 rule ("text controls are capsules") flags content cards:
%{RecentlyCompletedItem}(300 x 106, a game icon<img>, name and size, radius 20 like every content card) fails "text control radius 20 < 0.45 x height 106". Thearttest only exempts icon-only controls. Please treat a control that contains an<img>/<video>or aurl()background and is >= 100 px tall as content (VP P-45: content is not glass and keeps its card radius), or add an exemption id for content cards that areas can tag. Why: P-83 is about buttons; a 106 px capsule-ended card would not be visionOS.- P10 (2026-10-07 06:35): done: P-83 skips content cards (an
img/video/pictureorurl()background and ≥ 100 px tall × m) and list rows (%{*GamepadDialogContent>Field},role=option|tab|row|listitem).
- P10 (2026-10-07 06:35): done: P-83 skips content cards (an
-
REQ C2a->P10: #9 follow-up to #7 (thanks, the clip-aware rects work for fully clipped items): a control that is only partly visible still fails P-08.
/library/homeat rest, pad and laser, 06:39:%{SeasonalSale}(rect y 610-825; visible y 610-656 under C1a's glass clip) "hit 91 % own, 0 % other over 1208x80". A target whose visible part is shorter than the 80 px box cannot meet P-08 by construction; it is scrolled partly out of view, and Steam's scroll guard (C1a,--lgs-guard-bottom612) brings it fully into view before it takes focus. Please skip (asskipped: partly visible) controls whose visible rect is shorter than the sampling box, or sample only inside the visible rect. Why: the last row of every scrolled page straddles the glass bottom.- P10 (2026-10-07 08:26): done: (1) a control whose visible part is shorter (or narrower) than SIZE's 80 px box is
skipped: partly visible: P-08 not sampled(P-80/P-83 still judged); (2) the root cause on/library/home: C1a's--lgs-c1a-ghnow lives on%{BasicUiRoot}, so the lab now resolves the clipping ancestor'sclip-path: inset(... calc(100% - 656px) ...)itself. Live 08:20 (gates main --route /library/home --mode pad): SIZE PASS,%{SeasonalSale}skipped (obscured). contracts/lab.md §4 sweep scope.
- P10 (2026-10-07 08:26): done: (1) a control whose visible part is shorter (or narrower) than SIZE's 80 px box is
-
REQ C2a->C1b: #5 Software cell details, to confirm in your spec (HA §6 follows them; tell me if you differ): (a) the cell shows the best program that is not already the Top Hit, and is absent when none is left ("vlc": the program is the Top Hit and no cell repeats it); (b) the cell is one target: with one match
openlaunches, and when it reads "and N more"opengoes to Home › Apps with that program focused, through C2a'srt.home.reveal({section: 'apps', key})(exported by41-home.js); (c) a program as the Top Hit has no More circle (Steam has no menu for programs) and its status line is#AppType_2("Software"), which myrankreturns assubtitle; (d) with a program candidate attended, your cell declares only A "Open" and B, so the ornament is the quiet legend (p2_home-apps_search.png). (e), added in the R2 fix pass: the provider is built (device/rt/41-search-apps.js, live behindwp.c2awithwp.c1b; AT-13 row). Please callopen(candidate, ev, {slot: 'software', more: N})from the Software cell, N being the "and N more" count you draw: with N > 0 the provider opens Home › Apps with that program focused (rt.home.reveal), without the third argument (the Top Hit) it launches.rankalso returnsdata.matches(how many programs match).- C1b (2026-10-07, R2 fix pass): confirmed as written, and now built in the All summary (
device/rt/21-search.jsLgsAll): (a) the cell skips the program that is the Top Hit; (b) one target,open(c, ev, {slot: 'software', more: N})with N the other matches (yourdata.matches− 1 − the Top Hit),open(c, ev)for a program Top Hit; (c) no More circle, no X or ☰ on programs, the line is yoursubtitle; (d) a program declares only A and B. Live for "half" with--flags wp.c1b,wp.c2a: the cell reads "Half SBS Toggle · Software" beside Store (158) (C1b log, R2 fix pass). The provider getsctx.steamBest = {tier, appid}now.
- C1b (2026-10-07, R2 fix pass): confirmed as written, and now built in the All summary (
-
REQ C2a->C1a: #10 on
windowlessroutes (Home, folders), please drop the header's scroll-edge band:#header%{Profile>Header}::before(20-shell.css, the 124 px band withbackdrop-filter: blur(12px)) blurs the page's own top-row plates that sit under it: Home's section control and What's New (y 14-94), "View in Library" on folders, and in the low layout the top of the section track. Suggested:%{BasicUiRoot}[data-lgs-glass="windowless"] #header%{Profile>Header}::before { backdrop-filter: none; background: none; }. Why: a windowless route has no window and no scroller, so there is nothing for a scroll edge to fade (PLAN §1.2, the toolbar row's glass is plates); seen live 2026-10-07 08:20 (shots/p2_c2a_home_recent_circle.png: the "Recent" pill and What's New read blurred and dim). Steam's own page props cannot turn it off (Steam keeps--gamepadui-header-background-opacityat 1 on Home).- C1a answer (2026-10-07 08:15, session 4): done as suggested:
%{BasicUiRoot}[data-lgs-glass="windowless"] #header%{Profile>Header}::before { background: none; backdrop-filter: none; }intheme/20-shell.css§2 (synced 08:15). It applies whenever the shell's T2 setswindowless(yourglassMode('home')hook answering, folders,/invites).
- C1a answer (2026-10-07 08:15, session 4): done as suggested:
-
REQ C2a->P2: #11 (a)
ui.loc(token, ...args)returns the raw%1$sform: Steam'sLocalizeStringignores the extra arguments (live:loc('#Playtime_Total_Minutes', '3')gives "%1$s mins played all time"). Please substitute%N$sinloc(and so intext), or note in react.md §6 that callers format; C2a formats itself for now (homeFmtin41-home.js). (b) FYI, a finder you may want as a built-in: Steam's library app context menu (the capsule'sonMenuButtonrenders it): module with#GameAction_DismissPlayNext,#GameAction_ConfirmStopStreamingTitleandbFitToWindow; exports the menu component (sourcenavigator:+instance:) and its options ({bFitToWindow: true, strClassName: …LibraryContextMenu}); shown asshowContextMenu(<Menu overview client="mostavailable" launchSource={1000} bInGamepadUI ownerWindow/>, anchor, options()). 1 candidate on build 11094443 (module 43394). C2a uses it throughrt.react.findfor Home's tile menu.- P2 (2026-10-07 13:05, review R1 session): (a) done:
ui.loc(token, ...args)now fills%1$s...%9$sfrom its arguments (Steam's raw string otherwise; a placeholder without an argument stays), soui.texttoo when called throughloc;homeFmtkeeps working (it formats a string that has no placeholders left only when you pass args toloc). react.md v3 §6. (b) thanks, not made a built-in: every built-in finder adds an anchor search to the one scan all T3 callers pay for, and C2a is its only user; yourrt.react.findis the right place. If a second package needs it, send the spec and it becomes a named finder.
- P2 (2026-10-07 13:05, review R1 session): (a) done:
-
REQ C2a->P10: #12 SIZE: skip controls covered by an open transient expansion. Home's card (320 × 240, opened by attention after 0.8 s, HA §3.4) is meant to cover parts of its neighbours while it is open; SIZE then fails the neighbours on P-08 ("hit 82 % own, 8 % other (
lgs-home-more)", "90 % own, 0 % other": the card's body), live 08:05-08:10 in pad rest (gamepad focus opens the card) and laser card states. The card now carriesdata-lgs-transient(and is a child of its own cell, so the attended cell itself passes). Please treat a control whose sampling box meets a visible[data-lgs-transient]that is not its own descendant or ancestor asskipped: covered (transient), and sample the transient's own controls as usual. Why: a transient card or popover over a grid is a normal state (the gates run in states with focus), and its neighbours are not targets while it covers them.- P10 (2026-10-07 08:26): done as asked: a control whose 80 px sampling box meets a visible
[data-lgs-transient]that is neither its ancestor nor its descendant isskipped: covered (transient); the transient's own controls are judged. Checked live with a synthetic transient (P10.md, R1 REQ C2a #12). contracts/lab.md §4.
- P10 (2026-10-07 08:26): done as asked: a control whose 80 px sampling box meets a visible
-
REQ C2a->P10: #13 follow-up to #9: centre SIZE's 80 px sampling box on the control's visible rect, not its full rect.
/library/lgs/steamhome(What's New,window-full, glass to y 720), scroll 0, laser, CSS-only, 2026-10-07 08:31:%{SeasonalSale}(rect y 610-825, visible y 610-720 = 110 px, so #9's skip does not apply) fails P-08 "hit 91 % own, 0 % other over 1208x80": the box is centred on y 717, so its lower part lies below the window edge, where nothing can be pointed at. Why: a control whose visible part is taller than the box can always be hit inside it; sampling outside the visible part measures the off-screen strip.- P10 (2026-10-07 session 5): done. The P-08 box B = max(80, visible width) × 80 is centred on the control's
visible rect, and since session 5 the obscured test uses the same box, so a tall control whose visible part holds
B is sampled there instead of being skipped on its full rect. Live, your case (
gates main --route /library/lgs/steamhome --only size --flags wp.c2a,wp.p3,wp.c1a --mode laser, 13:30, scroll 0): SIZE PASS, 13 checked,%{SeasonalSale}sampled on its visible part (not skipped, no P-08 failure). Offline fixturetools/p2/test_gates_page.pycases 5 (a control cut by the window), 5b (a tall control cut by its scroller) and 4b (partly visible and unable to scroll clear: judged in place) pass. contracts/lab.md §4 SIZE and sweep scope.
- P10 (2026-10-07 session 5): done. The P-08 box B = max(80, visible width) × 80 is centred on the control's
visible rect, and since session 5 the obscured test uses the same box, so a tall control whose visible part holds
B is sampled there instead of being skipped on its full rect. Live, your case (
-
REQ C2a->P10: #14
pad-bfs: recover after anexit:edge. On/library/home(--flags wp.c2a,wp.p3,wp.c1a --mode pad, 09:05) Left on C1a's search capsule isexit:none; afterwardsFocusApplicationRoot(), B andL.gpTakeElall leave.gpfocusabsent in main (probesearch_probe.jsin C2a's scratch, 2026-10-07), so every later node isuntakeableand 5 of 18 targets are listed unreached although D-pad moves reach them (M3-N1). Please bring focus back into main after an exit (for example take the entry node through its nav tree's own window activation, or press B in the window that took focus), or record the exit and continue from the next queued node in a freshL.nav(R). Why: any route whose header row ends at a laser-only control has such an edge, and Steam's own Home has it too (stock: Left on the first capsule leaves main andL.root()does not bring focus back,l_probe2.js09:12), so G-PAD cannot pass on Home for either UI until the sweep recovers.- P10 (2026-10-07 sessions 4–5): done. Main has the gamepad only while Steam's active nav tree lives in main's
document; after an
exit:edge the sweep brings it back in steps, each counted only if main still has the gamepad 150 ms later: the opposite press, main's nav tree (FindNavTreeInWindow(main)→Activate(true)), the root, Steam's ownEnsureVROverlayVisible()with the root and Down + Up (aftervr-null-tree: the gamepad had left Steam's overlay), and lastNavigate(route, replace); a take that does not land activates main's tree and takes once more. Every exit is listed with how focus came back. Live on your Home (pad-bfs --route /library/home --flags wp.c2a,wp.p3,wp.c1a --mode pad --budget 200, 16:14): 26 nodes, 188 moves, 24 of 26 reached, 5 exits all back; the 2 left arelgs-home-play"Play" andlgs-home-more"Options" inside the attention card (yours to look at: the card's controls are not reached by D-pad); 1 irreversible move (Left from node 16 lands on node 3, Right goes to node 7;<P10 scratch>/s5/bfs_home_c2a.json). Stock Home (--stock, 15:55): 44 nodes, 36 of 72 unreached, the session 2 baseline exactly (feed avatars, offers below the fold), 7 exits all back byoverlay; your review's 4 of 46 was the sweep losing focus. Both runs took place while another agent's native session was on (the result saysnative: on); the sweep reads focus, not pixels. contracts/lab.md §4pad-bfs.
- P10 (2026-10-07 sessions 4–5): done. Main has the gamepad only while Steam's active nav tree lives in main's
document; after an
-
(withdrawn 09:15) REQ C2a->C1a: #15 Left from the search capsule leaving the main window: stock Steam does the same from the leftmost item of Home (it goes to the tab bar), so nothing to change.
-
REQ C2a->P10: #16
sgcheckR1 treats every pop as a square rectangle and ignores its own radius: Home's open card (pop 480 × 360 tex, r 54, over its own plate of the same rect and radius) fails "not covered at texture px (722, 476)", the pop's corner, which the rounded crop never draws (native session 09:23). Please sample only points inside the pop's own rounded rect (inside_rrect(x, y, pop)with the layer'srfrom the report). Why: any rounded pop over a plate of its own shape (Home cells, CC tiles, cards) fails R1 by construction; P6's reporter admitted the same pop under rule 1.- P10 (2026-10-07 session 4): done: R1 samples only points inside the pop's own rounded rect (its
rfrom the report, deflated with the pop by P6's 2 px;capsuletoo). New fixtures:sg_roundpop.json(your case: a 480 × 360 r 54 pop over its own plate, no cover) is clean;sg_roundpop_corner.json(a square pop over a rounded plate) andsg_roundpop_oversize.json(6 px larger than its plate) still FAIL R1. TL-4 16/16 PASS. The live re-check needs a native session (deferred while P7 is in its R1 fixes). contracts/lab.md §5.
- P10 (2026-10-07 session 4): done: R1 samples only points inside the pop's own rounded rect (its
-
REQ C2a->P8 (FYI P9, V1): #17 native mode draws a window-size grey cover on windowless Home. Native sessions 09:28 and 09:38 (
--flags wp.c2a,wp.p3,wp.c1a --mode pad, card open on cell 6): the report wasmode: "windowless",shapes: [], 18 plates (C1a's Back and search, C2a's section track, What's New, 13 discs, the card; ids stable), 4 mosaic bands covering every plate, one pop (home-card, dz 0.0407, non-interactive),errors: []. The headset view (hv --look, 14 s after the override settled; frame deleted) showed a grey rounded slab about 1280 × 656 behind the cells, no disc glass and no disc art (labels and page dots visible, row-3 labels hanging below the slab). Please check how the daemon and glassd handle a surface withshapes: [](it looks like Phase 1's whole-surface cover or thewindowshape is drawn) and whether plates and explicitmosaicbands reach glassd onwindowlesssurfaces. Why: Home is the windowless route the user asked for; until this is fixed native Home is a grey panel. C2a's CSS-only Home is unaffected.- P8 (2026-10-07 13:05-14:04 EDT, maintenance session 4; build 11094443): not reproducible with today's tree; two defects that draw such a slab are fixed. Six native sessions with your flags (
wp.c2a,wp.p3,wp.c1a,--mode pad,/library/home, the card open on cell 0):glassd.jsonmainshapes: []with your 18 plates and thehome-cardslab;glassd-out.jsonmaincover: 0,plates18; P7's dump: one cover node (glassd's backdrop region, all plates) and base pieces only inside your 4 bands, plus the card's pop and slab. Headset looks (hv --look --full, two or three fresh grabs; the window lifted and brought closer with a lab-only P7 override, cleared after; every frame looked at, then deleted on both machines): native Home frontal and at −20° is right (glass discs with their art and a bezel, labels, page dots, the top-row plates, the card at +15 mm, no window slab). Your 09:28 / 09:38 frames were single grabs taken before P10's fresh-frame fix (10:59), and the first one showed another page: they most likely showed an older state. Fixed: (1) P6's reporter sent your explicitdata-lgs-mosaicbands also when main had a cover (window/window-full), against reporter.md §2.3: the base then covered only the bands and the window glass hid everything else, i.e. a window-size slab with content missing. That state is real: another agent's session at 13:07:24 reported main with a 1920 × 1080 cover plus your 18 plates (your module leaving at its step's end). Bands are now reported only without a cover (RP-MO,wp/P6.md), and the daemon drops them next to a cover too (contracts/daemon.md§9). (2) Main is left out while the dashboard shows SteamVR's own page (REQ C6b->P8). Still open, P7's (REQ P8->P7 inwp/P7.md): athv --offaxis 20the art in the base pieces that the card's hole splits off goes behind the disc plates (the disc beside the card shows bare glass); −20 and frontal are fine. For you (FYI, no change asked): the card's rectangular crop carries the neighbour disc's corner to +15 mm, so Stardew Valley's disc shows a horizontal cut at the card's bottom edge; keep neighbours out of the card's rect or accept it. Evidence:wp/P8.md(session 4 rows). - P8 (2026-10-07 16:07-16:12 EDT, maintenance session 5; build 11094443; REQ C2a-R2->P8): confirmed on today's tree; closed. Two more native sessions with your flags (
wp.c2a,wp.p3,wp.c1a,--mode pad,/library/home, the card open on cell 0, "DolphinXR"). Every snapshot (16:07:46-16:12:14, six) shows the planned chain:glassd.jsonmainshapes: [], 18 plates and thehome-cardslab;glassd-out.jsonmaincover: 0,plates18,slabs1, nothing dropped; P7's dump: the cover node, 8 base pieces, and the card's pop (+0.0407) and slab. Headset looks (hv --look --full --grabs 3, fresh frames; the window brought into view with a lab-only P7 override,addMm [0, -200, 300], then[0, -520, 300], then none; every frame looked at, then deleted on both machines within a minute): native Home has glass discs with their art (Halo, Tomb Raider, Balatro, Robo Recall, Arizona Sunshine 2, Assassin's Creed Nexus, Into the Radius 2, Batman, Rez Infinite, the All Games folder), labels, page dots, the segmented control, the search capsule, the sidebar and Back, and the card with Play at +15 mm. No grey slab in any frame. With the reviewer's 13:21-13:30 runs that makes three independent sessions without it. Nothing was changed for it this session; the fixes are session 4's. Still open elsewhere: REQ P8->P7 (off-axis order) and your M1 (the card's crop carries neighbouring discs).
- P8 (2026-10-07 13:05-14:04 EDT, maintenance session 4; build 11094443): not reproducible with today's tree; two defects that draw such a slab are fixed. Six native sessions with your flags (
-
REQ C2a->C1a: #18 route map,
/library/lgs/folder/*: please make its defaultwindow-full(as forhome), andwindowlessonly while aglassMode('folder')hook answers.41-home.jsregistersglassMode('folder', () => live ? 'windowless' : null)since the R2 fix pass, so nothing changes while the module runs. Why: review R2 m16 (S2-R2): a folder history entry whilewp.c2ais off or its install failed renders Steam's library fallback (P2 drops unknown/library/lgs/routes) on a windowless, glass-less page; withwindow-fullit gets its window glass. Your R2 answer ("windowless in the map itself; a hook only overrides while one answers") keeps that case, because a module that is not installed cannot answer. -
REQ C2a->P4: #19 Reduce Motion (VP P-56): the illumination hook's
::afterand the edge's::before(03-material.css§E3,04-states.css) transition--lgs-focus(and--lgs-hover) on--lgs-ill-d-out/-d-inalso underprefers-reduced-motion: reduce, where P10'smotion --media reducelists them as "animates --lgs-focus under Reduce Motion" (C2a's card-close strip, 18:50). Please set those transitions to0s(or opacity-only) inside the reduce media query for every host. C2a setstransition: noneon its own discs' two pseudo-elements meanwhile (41-home.css D); tell C2a when the global rule lands so the local one can go. -
REQ C2a->C1b: #20 FYI (no change asked unless you want the pop).
theme/layers/41-home.jsonnow supersedes the legacycardrule behindwp.c2a(reporter §3.5 names C2c, C2a and C1b as its users). It lifted the focused poster, store capsule or search result by 0.008 units (2.95 mm, outside PLAN §1.7's set) with admission off, so on What's New it also popped a stale.gpfocusin laser mode and a feed card whose own rule admission had dropped (sgcheck R2 FAIL, native session 19:50). Withwp.c2aon, search results (%{GamepadSearch} %{ResultTemplate}) are therefore flat unless21-search.jsonpops them; PLAN §1.7 wants a focused search result at +15 (non-interactive,when: "attended"). -
REQ C2a->C2c: #21 FYI, the same supersede: with
wp.c2aon, the library's posters keep only yourlibrary-posterrule (behindwp.c2c); the legacy 2.95 mm lift is gone (also noted under your REQ-11 inC2c.md). -
REQ C2a->P10: #22 G-OUTLINE flags P4's raised-material rim light on a focused, lifted Home disc (Apps section, pad focus on a program cell, which has no card; edge ratio .388 on the left side, segments bright at both ends and dim in the middle, i.e. the conic rim, not a hairline). The same rim passes on every other P4 control. Please rule whether a P4 focus rim is exempt (as the E-BACK exemption) or name the ratio C2a must meet; C2a will not dim P4's focus light on its own.
-
REQ C2a->C1b: #23 AT-13 (
pAT13.js,--flags wp.c2a,wp.p3,wp.c1a,wp.c1b, 21:04): typing "half" gives Half-Life: Alyx on top with Play / Install, as specified; typing "vlc" shows no Software row (focus null, "quiet" legend) and A goes to/steamweb, although__LGS_RT.searchApps.rank('vlc')returns VLC media player at tier 1 in the same build. Please check that the Software cell queries providerc2a.programsfor short queries.
Requests to C2a, handled
- 2026-10-07 05:05, start of session 2:
grep -n "REQ [A-Za-z0-9]*->C2a:" docs/phase2/wp/*.md→ four open requests: C2c REQ-1, REQ-2; C1b #5, #6.- C2c REQ-1 (library text): merged into HA §0.2, §1.2 item 6, §1.3, §7 (with §7.1, §7.2), §8, §9, §10.4, §11, §12.2–§12.5, §12.9, §13, §14 (AT-6/AT-7 library parts as their own rows, AT-14, AT-15, the general filter-state rule), §15 #12, §16. Kept HA's Owner and Test columns in §12 (the ledger reads them), filled from C2c's tests. One correction: C2c's text says the retention table has 59 functions; it has 60 (53 from LA §A + 7 from SN §A), unchanged.
- C2c REQ-2 (
home-apps.css): removed thehl-*block and.ha-poster.is-lift; kept.ha-poster(base,img.port,.is-titlecard) andhome-apps.js's[data-app]fill. Braces balance (118/118). - C1b #5 (HA §6, §12.6, XC §2): HA §6 rewritten to C1b's announced interface: provider
c2a.programs,slots: ['tophit', 'software'],rankwith tiers 0–3,open, noprimary(S-C is declared by C1b's sheet); the Top Hit rule (strictly better tier); the Software cell (header#AppType_2, 300 × 84 at the start of the Store row, 56 px disc with the 48 px icon, name 24 Semibold, "and N more" English only, "+N" otherwise). HA-18 rewritten; §1.2, §1.3, §3.8, §12.6 S2, §12.7 P2, §13, AT-5(c), AT-13 updated. XC §2 rewritten (revision 3). - C1b #6 (
home-apps-search.html): redrawn as C1b's 960 × 500 sheet over the dimmed Library snapshot, with C1b's real data for "half" (C1b's recipe block and art helper copied unchanged), gamepad focus on the Software cell, the Top Hit at rest, and the quiet legend (A Open, B Back). Re-rendered and viewed (M0-R7). - The four request lines in
C2c.mdandC1b.mdare marked[x]with a one-line answer.
- 2026-10-07 05:25, end of session 2:
grep -n "REQ [A-Za-z0-9]*->C2a:" docs/phase2/wp/*.md→ the four requests above, all[x]; no new ones. - 2026-10-07, R2 fix pass (session 6):
grep -n "REQ [A-Za-z0-9-]*->C2a" docs/phase2/wp/*.md→ five open: the review's REQ C2a-R2->C2a (C2a-review-R2.md§5), C2c REQ-11, P6's literal-inset REQ, and the coordinator's two (R2-2/R2-3/R2-5 and R2-15).- C2a-R2->C2a (fix M1, M3–M15, m1–m16; answer REQ-11 and P6): see the Status and the evidence rows R2F-* and the AT rows of this pass; marked
[x]inC2a-review-R2.mdwith a pointer here. - Coordinator R2-2, R2-3, R2-5:
home-apps.md§7.1 (default hugging ornament, five slots as thelibFixedSlotsvariant), HA-11 and §8 Cancel 60, §0.5 rows §1.7/§1.10/§1.12, §15 #18 resolved; alsoxc-home-search.md§3. Answered incoordinator.md. - Coordinator R2-15:
home-apps.md§4 Labels row (the T1 fallback's full name on attention, PLAN-2b-4; no cut glyph), AT-12, §0.5's §1.16 row (E-GRID, E-GRID (labels)). Answered incoordinator.md. - C2c REQ-11 and P6's literal-inset REQ: answered in
C2c.mdandP6.md(the What's New track is on the tab row's::before, the arrows paint--lgs-raised-shadow,41-home.jsonsupersedestab-arrowbehindwp.c2a; native evidence N-SG rows).
- C2a-R2->C2a (fix M1, M3–M15, m1–m16; answer REQ-11 and P6): see the Status and the evidence rows R2F-* and the AT rows of this pass; marked
Decisions taken without the user (PLAN §1.17 rule: safe default, flag, note)
| Id | Decision | Safe default and flag | Why |
|---|---|---|---|
| D-C2a-1 | No LB/RB glyph badges on Home's section control (VP I-15) | Off, flag home.bumperBadges |
Steam's own VR tab rows show arrows, not bumper glyphs (INV-L §1.4); bumper delivery in VR is unproven (HA AT-3f) |
| D-C2a-2 | Home and folders hide Steam's footer exactly as Steam's Home does (FooterStore.HideFooter(), Steam's own call, never CSS); if the store is missing or Steam shows a footer anyway, the page drops to two honeycomb rows instead of hiding it |
Class lgs-home-footer, set by T3 from the store and the footer's live visibility |
PLAN §1.10 forbids hiding legends; the honeycomb's row 3 labels (y 646–672) would collide with an 84 px capsule at y 628 |
| D-C2a-3 | The Home card drops to 0 mm while its menu is open | None (P6's rule 6) | PLAN §1.7 rule 6; the table row that keeps +15 is contradictory (C2c REQ-7 to the coordinator) |
| D-C2a-4 | The Software cell shows the best program that is not already the Top Hit, and is one target: with N more matches, A opens Home › Apps with that program focused instead of launching | Behind wp.c2a |
One 80 px target per 300 × 84 cell; a cell that reads "and N more" promises more than one thing, so it goes to the full list (revision 2's rule, kept in C1b's spec) |
| D-C2a-5 | A label fades under the card or a name plate only when its text is covered, not its 200 px box | Always | A dimmed label that nothing covers reads as disabled (seen in p2_home-apps_apps.png) |
| D-C2a-6 | Steam's "Recent Games" title on its own Home no longer fades out 8 s after the last focus change (HeaderExit kept at opacity 1) |
Look only (opacity), no flag | A visionOS section title stays; it also keeps G-AUD deterministic (stock and themed snapshots of the 8 s timer differed: HIDDEN) |
| D-C2a-7 | Steam's Home in the toolbar fallback (no lgs-hdr-108): the shelf is padded by --lgs-hdr-pad (68) and the feed wrapper is 96 px shorter (height: calc(100% - 96px), the tabbed page max-height: 100%), so the parked tab row sits at y 96-200 instead of under Back and the search field |
Only under html:not(.lgs-hdr-108); recheck with C1a's CQ1 at M3 |
WN §3.2 rule 2 (areas pad their page roots); without it the parked row's segments overlapped the search field (SIZE P-08 83-100 % other) |
| D-C2a-8 | The store capsules' price bar keeps Steam's 12 px prices (uppercase and tracking removed, 17 px line box kept) | No flag | At 18 px Steam fits fewer friends' avatars into the bar: 6 avatar controls GONE (audit). A G-TYPE gap below the fold (not in the route-matrix states); a T3 card would fix it |
| D-C2a-9 | Low layout (C1a's search capsule, the default until its flag searchCircle): section track y 102–166 (not 96–160), rows 236 / 416 / 596, card top ≥ 178; a row-1 card covers row-2 discs by up to 62 px |
Only under lgs-home-low |
The capsule's 80 px hit box ends at y 94: segments at 96–160 overlapped it (SIZE P-08 "5 % other" on all three, live 07:56); the cells' boxes then had to start below the segments' hits. HA §3.1.1 updated |
| D-C2a-10 | The card is rendered inside its cell (a child of the focusable), not as a sibling | Always | The card is the cell's expanded state: a click on its body is the cell's activation and its hits are the cell's (SIZE P-08 had the open card at "0 % own" of its own cell). Play and More stop propagation |
| D-C2a-11 | The card's status line shows Steam's playtime string ("6.4 hrs played all time", #Playtime_Total_Hours) or "Not installed"; the Frame compatibility word is left out |
No flag | Steam's packed per-device category (steam_hw_compat_category_packed) is not decoded yet; showing a wrong word would mislead |
| D-C2a-13 | Up from a cell that Down from a top-row control reached returns to that control (one-step memory, as in the grid); otherwise Up from row 1 goes to the selected segment. Row ends and B stay Steam's: Left on the first item leaves the main window for the tab bar and B goes back in history, exactly as on Steam's own Home (stock probes l_probe2.js, b_probe.js, 09:10-09:15) |
Behind wp.c2a |
pad-bfs listed Down from "Collections" then Up to "Recent" as irreversible; with the memory: 0 irreversible. A session-5 trial that kept focus at the row ends and consumed B was reverted: stock does neither |
| D-C2a-12 | Gamepad glyph badges are text glyphs ("X", "≡", 18 px Bold in a 30 px disc), not Steam's glyph components | Gamepad mode only | Steam's glyph component is not found yet (VP P-27 wants it); 16 px failed G-TYPE. Kept in the R2 fix pass (review m9, a "should") |
| D-C2a-14 | The open card keeps 40 px from the window's left and right edges, and on cells left of x 400 its action row is mirrored (More leading, Play trailing) | Always | VP P-29 (must): Play's centre within 400 px of x 640 with any label up to 190 px; measured 36–379 px off centre on every game cell in both modes (review R2 M9) |
| D-C2a-15 | The card's CSS clip morph keeps P5's bounce-0 curve (review R2 M10 asked for b .20) | — | P5's lgs-morph contract and MO §6.4: a negative inset() overshoot is not dependable; glassd draws the token's 1.5 % overshoot of the glass in native mode. HA §3.4 and §11 now say so. Recorded as a dispute of that part of M10 |
| D-C2a-16 | Exits keep their nodes: the closing card transitions its clip back into the disc's rect (rest clip inset(-48px round 84px), room for its shadow) and is removed on transitionend; the closing name plate and a replaced grid stay as non-interactive copies until animationend (fallback timers 1.0–1.2 s) |
Always | Review R2 M10. A transition, because a context package owns no keyframe (P5); end events, so a paused or slowed animation (the lab's filmstrips, a busy device) keeps its node |
| D-C2a-17 | Home's download and update states read the client data Steam's own UI reads (selected_per_client_data.display_status; EDisplayStatus read live from Steam's enum module: 3, 6, 7, 18, 19, 22, 23 in progress, 20 update required) and show Steam's #DisplayStatus_<state> words |
— | Review R2 M13; Steam's own words, never ours (PLAN §1.15) |
| D-C2a-18 | The Windows segment shows only while SteamVR lists desktop windows; its label is "Windows" on an English UI only (Steam has no such token; its popup says "Add Desktop Window"), the window glyph otherwise | — | Review R2 M12; HA §3.2, §3.8 |
| D-C2a-19 | A dead end we handle requests FailedNav (Down on the bottom row, Right at the last page's row end, RB/LB and RT/LT at the ends) | Always | VP P-79 (should); Steam plays FailedNav for an unhandled press, and our handlers consume these presses |
| D-C2a-20 | Under Reduce Motion the discs' lift glow, focus light (P4's illumination pseudo-elements) and label colour change at once; only opacity fades | Reduce Motion only | VP P-56 as P10's motion --media reduce scores it; REQ C2a->P4 #19 asks for the global rule |
| D-C2a-21 | Under the open card, the covered parts of other discs and labels are cut away by a rectangular inset() clip that keeps each one's part beyond the card's rect + 2 px (the side that keeps the most of it; 2 px of anti-aliasing margin); labels whose measured text it covers also fade to .22 (D-C2a-5) |
Always | Review R2 M1: nothing shows through the CSS card, and its native crop at +15 mm carries only the card. A first version cut a rounded path() hole; Steam's texture in native mode then showed corrupted tiles and a misplaced row of labels under the card (native session 19:47, p2_c2a_r2f_native_card_tex.png), so the clip is rectangular |
New strings (PLAN §1.15)
HA §3.8 is the list. New in the R2 fix pass: "Windows" (the Windows segment; no Steam token, English UI only, else the window glyph); the folder plate's second line "N games" / "N collections with no games" (English UI only, else omitted). Steam's own, by token: #DisplayStatus_Downloading, _Installing, _Updating, _UpdatePaused, _UpdateQueued, _DownloadPaused, _DownloadQueued, _UpdateRequired (the card's status line). New since session 1: "Software" (#AppType_2, Steam's) as a program's status when it is the search Top Hit. "and N more" is C1b's string (English only). Strings without a Steam token, drawn only when the UI language starts with en: "Empty Collections", "Empty", "N collections with no games", "N games" (if no game-count token exists), "Show in Library" (if neither "View in Library" nor "Show in Library" exists).
Evidence
| Test | Command | Result | Files | Date | Steam build |
|---|---|---|---|---|---|
| M0-R1 | python tools/mockshot.py docs/phase2/mockups/home-apps-home.html shots/p2_home-apps_home.png |
Rendered (2 496 421 bytes); viewed. Fixed: the pointer proxy sat on the "P" of Play; moved to the capsule's trailing padding (laser to view (1040, 290), light spot at 90 % / 77 %). Verdict: 4-5-4 honeycomb, the card at (592, 98) 320 × 240 with Play at (616, 178) and More at (828, 178), the top row on y 54, page dots at (640, 696): as HA §3.1 and §3.4. Glass under the card's text measures L 81 / 82 / 86 (p10 / p50 / p90, PIL, 601 weights), inside 70–90 | shots/p2_home-apps_home.png |
2026-10-07 | n/a (mockup) |
| M0-R2 | python tools/mockshot.py docs/phase2/mockups/home-apps-home-t1.html shots/p2_home-apps_home-t1.png |
Rendered; viewed. CSS plates (black .58 + white .16 → .04), no pointer proxy, no pop; same pointer fix. The CSS plate under the card's text measures L 51 / 52 / 53: darker than native glass, as PLAN §1.2's recipe makes it; text contrast is higher, not lower | shots/p2_home-apps_home-t1.png |
2026-10-07 | n/a |
| M0-R3 | python tools/mockshot.py docs/phase2/mockups/home-apps-apps.html shots/p2_home-apps_apps.png |
Rendered; viewed. Fixed: the "Firewall" label was dimmed although the name plate does not cover its text (D-C2a-5) | shots/p2_home-apps_apps.png |
2026-10-07 | n/a |
| M0-R4 | python tools/mockshot.py docs/phase2/mockups/home-apps-collections.html shots/p2_home-apps_collections.png |
Rendered; viewed: 7 folders (the library sets, VR, Empty Collections attended with its two-line plate) in a dimmed room; labels legible | shots/p2_home-apps_collections.png |
2026-10-07 | n/a |
| M0-R5 | python tools/mockshot.py docs/phase2/mockups/home-apps-folder.html shots/p2_home-apps_folder.png |
Rendered; viewed: the VR folder in gamepad mode, Grimlord's card (Install, blue, with the X badge; More with the ≡ badge), cloud badges on 5 not-installed games, 3 page dots, peeks of rows 1 and 3. Rects: card (704, 284) 320 × 240; Install 163 wide; centres 160 apart; hits 29 px clear | shots/p2_home-apps_folder.png |
2026-10-07 | n/a |
| M0-R6 | python tools/mockshot.py docs/phase2/mockups/home-apps-depth.html shots/p2_home-apps_depth.png |
Rendered twice; viewed. Fixed: the plate count (≤ 18 of 32; the open card replaces its disc), the rule 6 note for a menu over Home, and a table cell that overflowed into the paragraph below | shots/p2_home-apps_depth.png |
2026-10-07 | n/a |
| M0-R7 | python tools/mockshot.py docs/phase2/mockups/home-apps-search.html shots/p2_home-apps_search.png |
Rendered twice; viewed. Redrawn (C1b #6). The first render showed the quiet legend's "Open" unreadable over the bright curtain (C1b's REQ #3 to C1a); C1a's shared builder gained the dim band during this session, and the second render reads clearly. Rects: sheet (160, 100) 960 × 500; the Software cell at sheet (32, 362) 300 × 84; store cards at 348 and 544; the quiet legend at y 628–712 in the margin | shots/p2_home-apps_search.png |
2026-10-07 | n/a |
| M0-G1 | python tools/mockshot.py <mockup> <scratch png> --rects <scratch json> for home-apps-home.html, -folder.html and -search.html (scratch files deleted) |
Home: Back (24, 24) 60; section track (412, 22) 456 × 64, segments 140 / 172 / 140 × 60, contiguous; What's New (973, 24) 203 × 60, right edge 1176; search (1196, 24) 60; cell 1 (204, 136) 200 × 180, disc 120 centred on (304, 196); dots centred on (640, 696); peek centred on x 1212. All as HA §3.1 | stdout only | 2026-10-07 | n/a |
| M2-A0 | python glass.py shot main p2_c2a_home_stock --route /library/home --theme off; ... p2_c2a_home_p1 --route /library/home (before any 41-home.css) |
Baseline viewed: Phase 1 look (uppercase 12 px feed tabs, ring on the featured capsule). Baseline gates (gates main --route /library/home --mode laser --json, 05:24): SIZE 14 fails (feed tabs 34 tall, arrows 32, C1a's search field), TYPE 5 (tabs, "NO PLAYTIME YET", Back), MOTION 1 (Steam's 20x outline pulse running at rest), AUD SHRUNK + CONTRAST on "Recent Games" |
shots/p2_c2a_home_stock.png, shots/p2_c2a_home_p1.png |
2026-10-07 | 11094443 |
| M2-A1 | python glass.py shot main p2_c2a_home_t1steam --route /library/home after each change (check-theme PASS, sync, reload) |
Viewed (also composited over the mockup room photo): the feed tabs are a recessed 64 track with the white pill and title-case 22 px labels; 60 px arrow circles; no ring on the capsule; "No playtime yet" in title case; the shelf starts below C1a's toolbar row | shots/p2_c2a_home_t1steam.png |
2026-10-07 | 11094443 |
| M2-G1 | python glass.py gates main --route /library/home --pre <pre_R0: What's New tab selected, scroll 0> --mode laser|pad --json --shot p2_c2a_home_R0_<mode>; the same with <pre_R1> (route-matrix state "focus on a shelf card": pad L.gpTake on capsule 2, laser L.hover on it) |
pad R0, pad R1, laser R1 (06:18-06:22) and laser R0 (06:27): MOTION, TYPE, OUTLINE, AUD PASS. SIZE: 1 fail in every run, %{SeasonalSale} P-08 "hit 91 % own, 0 % other": its centred 80 px box lies wholly in the strip below the glass that C1a clips at y 656 (gate defect, REQ C2a->P10 #7). Laser R0 at 06:18 and the scrolled laser runs at 06:28-06:30 also showed CONTRAST on every text: html.lgs-native was on (another agent's native session; 05-native.css zeroes the window tint), so those runs were not CSS-only. Re-run 06:33-06:37 with html checked before and after each step (no lgs-native): R0 laser, R0 pad, R1 laser, R1 pad: MOTION, TYPE, OUTLINE, AUD PASS; SIZE only the SeasonalSale item. After P10's clip-aware sweep (REQ #7, 06:35) the item still fails because it is only partly visible (REQ C2a->P10 #9) |
shots/p2_c2a_home_R0_laser.png, _R0_pad.png, _R1_laser.png, _R1_pad.png |
2026-10-07 | 11094443 |
| M2-G2 | As M2-G1 with <pre_WN> (feed scrolled 420, What's New): informative, not a matrix state |
pad (06:26), and laser + pad again at 06:34-06:36 (CSS-only checked): all five gates PASS. Fixed on the way: the parked tab row overlapped C1a's search field (SIZE P-08, D-C2a-7); RecentlyCompletedItem top edge ratio .999 (uniform lip) → P4's E3 hook, now 0.0; 6 friends' avatar controls GONE when prices grew to 18 px (D-C2a-8, reverted). Remaining: RecentlyCompletedItem P-83 (gate treats a content card as a text button, REQ C2a->P10 #8) |
shots/p2_c2a_home_WN_pad.png, _WN_laser.png |
2026-10-07 | 11094443 |
| M2-G3 | Gates with the Friends and Recommended feed tabs selected and scrolled (pre: click the tab through L.click, scroll 420 / 1250 + inner 900), both modes, 05:55-06:00 |
Known gaps, deep feed only (not in the route matrix): Steam's activity feed (shared with game pages: %{AppActivityDay}, %{EventHeadline} 44 tall, avatars 36, 13-15 px text), the store widgets (%{PersonalCalendarWidget} 13.6 px uppercase day names, 0.67 px Today underline, %{DiscoveryQueueWidgetCtn>AppName} 16 px) and the store capsules' 28 px friend avatars and 12 px prices. Not restyled in T1: growing them reflows Steam's measured layouts (seen with the prices); a T3 What's New card would. The selected feed tab was put back to What's New by every later pre |
shots/p2_c2a_feed_* |
2026-10-07 | 11094443 |
| M2-C1 | T3-node CSS with a static fixture: python glass.py js "<fixture.js>" builds the documented .lgs-home DOM (real recent-game names and Steam's portrait art) over a transparent root, reads rects, and removes itself inside the same lab lock (it wraps L.restore); rects compared with tools/mockshot.py docs/phase2/mockups/home-apps-home-t1.html --rects |
PASS (G-MOCK ±8): 49 mapped ids; cells 1-13, discs, labels, dots, peek, section track (412, 22, 456 x 64), segment fills (140 / 172 / 140 x 60 at y 24), What's New (973, 24, 203 x 60), card (592, 98, 320 x 240), More (828, 178, 60 x 60) all 0 px off; Play (616, 178) 120 x 60 against 115 (font, +5). Play hit 140 x 80 and More hit 80 x 80 do not overlap, centres 182 apart. Cleanup verified after each step (no fixture node, root style restored) | docs/phase2/wp/C2a-cmp.json (mapping for glass.py cmp once it lands) |
2026-10-07 | 11094443 |
| M2-C2 | python glass.py shot main p2_c2a_home_t1fixture --pre "<fixture.js>" --mode laser; _pad (cell 7 focused), _padcard (gamepad badges on Play and More); fixture2.js: p2_c2a_apps_t1fixture (Apps selected, gamepad focus on Collections, name plate), p2_c2a_folder_t1fixture (title, Show in Library focused, cloud badges) |
Viewed over the mockup room photos and side by side with the mockup (p2_cmp_c2a_home_t1.png): honeycomb, CSS plates, card, labels at .22 under the card, peek and dots match p2_home-apps_home-t1.png; differences are data only (fixture uses portrait crops, the T3 build uses hero + logo) and C1a's Back and search circles (hidden in the fixture). Fixed on the way: What's New sat off-screen (position forced by the shared plate rule) |
shots/p2_c2a_home_t1fixture.png, _pad.png, _padcard.png, shots/p2_c2a_apps_t1fixture.png, shots/p2_c2a_folder_t1fixture.png, shots/p2_cmp_c2a_home_t1.png |
2026-10-07 | 11094443 |
| M2-C3 | The T3-node sweeps on the fixture: python glass.py js "(window.__c2aFixtureMode='pad', <fixture3.js>)" --mode pad and --mode laser (fixture with Steam's Panel Focusable classes on cells, segments, What's New, Play and More; runs L.gates.size/type/outline on main, then removes itself and restores Steam's inline styles before returning) |
First run found a real bug: .lgs-home-grid (inset 0, later in the page) covered the top row, so segments and What's New took no hits (P-08 "0 % own"); fixed (pointer-events: none on the full-width grid and top-row containers, auto on cells and top-row controls; top row z-index: 10). Re-run 06:50, pad and laser: SIZE 17 controls 0 fails, TYPE 17 texts 0 fails, OUTLINE 5 glass 0 fails: PASS. With the card open, the two neighbours the card overlaps fail P-08 (82 % own, the card's Play or More on top): expected while a card covers them; to settle with P10's "obscured" rule at M3 |
docs/phase2/wp/C2a.md only (JSON in scratch) |
2026-10-07 | 11094443 |
| M2-F1 | python glass.py focus --png <p2_c2a_apps_t1fixture over the room photo, and over grey> --pair "P-14 focused vs rest segment=rect:870,50,1050,112:rect:660,50,800,112:40" (gamepad focus on "Collections" vs "Recent" at rest) |
PASS: dL +62.3 (lounge room), +65.7 (grey) | shots/p2_c2a_apps_t1fixture.png |
2026-10-07 | 11094443 |
| M2-P1 | python glass.py pad-bfs --route /library/home --pre <pre_R0> --max 60 --budget 200 --json --out <scratch> themed, then the same with --stock (informative: G-PAD is not an M2 gate) |
Parity with stock: both 44 nodes reached from the same entry (the featured capsule), unreached 36 = 36 (Steam's laser-only tab arrows, the 28 px friend avatars, items of the feed tabs not selected), irreversible 15 themed against 16 stock (Steam's geometric navigation); B does nothing at the Home root in both. Edge differences are only the tab row's ids (its rects changed). The Home feed tab was What's New afterwards (checked) | — | 2026-10-07 | 11094443 |
| M3-S1 | device/rt/41-home.js slice 1 (module home, deps react/input/attention, flag wp.c2a; work copy device/rt/_wip/41-home.js). python glass.py shot main p2_c2a_home_t3_laser --route /library/home --flags wp.c2a,wp.p3,wp.c1a --mode laser and p2_c2a_home_t3_pad (--mode pad, pre L.gpTake on cell 3, 1.6 s) |
Live: the override installs in 165 ms, 13 cells with Steam's real hero + logo art (monogram when both fail), C1a's map turns the route windowless, the low layout applies while the shell shows the search capsule (data-lgs-search="capsule": section control at y 96, rows 232/412/592). Laser at rest: no card. Pad: focus on Rise of the Tomb Raider opens the card after 0.8 s with Steam's own primary label ("Stream" on this device), X and menu glyph badges, neighbours' labels faded. After each step the module is off again and no .lgs-home node is left (checked). Open: Steam's footer still shows a quiet "Back" legend (Steam's root onCancel; "Select" is suppressed), the tile menu (More, menu button) only logs, D-pad page turning, honeycomb neighbours (geometric for now), non-English segment glyphs, folder and What's New routes untested, AT-1..AT-11 not run |
shots/p2_c2a_home_t3_laser.png, shots/p2_c2a_home_t3_pad.png |
2026-10-07 | 11094443 |
| M3-F1 | Probe glass.py js (#Footer and the footer store) on stock Home (--mode pad) and with --flags wp.c2a,wp.p3,wp.c1a; source read of Steam's footer (module 97502: return !B && location=="bottom" ? null : <div id="Footer">, B = FooterStore.BShowFooter(), hidden while m_iHideFooterCount > 0; module 5757's useHideFooter hook) |
Stock Home: no #Footer node. Slice 1 showed a quiet "Back" footer. Slice 2 calls R.nav.inst().FooterStore.HideFooter() while Home or a folder is mounted (unhide on unmount): no #Footer node on Home, folders and What's New (state().footer = "hidden"); lgs-home-footer (two rows) only if the store is missing or a footer shows anyway |
— | 2026-10-07 07:35 | 11094443 |
| M3-N1 | <s4/t_nav.js> --mode pad --flags wp.c2a,wp.p3,wp.c1a (D-pad and bumpers through FocusNavController.DispatchVirtualButtonClick) |
PASS (AT-3 a, c, d, e, honeycomb rule, one-step memory, top row): entry focus on cell 1 (c0); Right ×3 → c1, c2, c3; Right at row end → page 2 c0; Left → page 1 c3; Down → c7, Up → c3 (memory); Down → c7 → c12; Down at bottom stays; Up → c7 (memory); Right → c8; Up → c3 (clamped); Down → c8 (memory); Up from row 1 → the selected segment "Recent"; Right → Collections → Apps → What's New; Down → back to c3; RB → Collections (focus on its remembered cell), RB → Apps, RB at the end stays (What's New not in the cycle), LB → Collections → Recent (c3 remembered). Grid flow-children dropped: each cell's onMoveLeft/Right/Up/Down returns true when it moved focus (Steam's nav node, module 74562) |
— | 2026-10-07 07:38 | 11094443 |
| M3-M1 | <s4/t_menu_t3.js> --mode pad --flags wp.c2a,wp.p3,wp.c1a; Steam's menu found by source (rt.react.find: #GameAction_DismissPlayNext + #GameAction_ConfirmStopStreamingTitle + bFitToWindow, 1 candidate, module 43394: the component the capsule's onMenuButton renders, and its options) |
PASS (AT-4 menu part): ≡ on the DolphinXR cell opens Steam's own tile menu: Play, Add to Favorites, Add to, Manage, Developer, Properties..., Cancel (6 actions, as HA §8 counts); the card stays with is-menu-source while it is open; B closes it and focus returns to the cell. The card's More (synthetic laser click) opens the same 7 rows. Closed with B or L.restore(), never by an item. X on the cell and Play on the card log primary(3699252713) with mode: logged; the route never changed |
— | 2026-10-07 07:50 | 11094443 |
| M3-A8 | <s4/t_at8_pad.js> --mode pad, <s4/t_at8_laser.js> --mode laser (--flags wp.c2a,wp.p3,wp.c1a) |
AT-8 (a) PASS both modes: no card at 0.5 s, card at 1.5 s (pad) / 1.3 s (laser); (b) PASS: three pad moves 150 ms apart and a laser sweep at 45-50 ms per disc: no .lgs-dwell, no card, no plate; (c) PASS: pad card gone 333 ms after the next move, laser 333 ms after L.unhover() (≤ 0.3 s + 441 ms); (g) PASS: 40 ms into a laser hover the disc has scale: 1, no dwell; (f) see M3-M1/M3-C1 (Play logs primary, route unchanged); (e) in the low layout a row-1 card covers row-2 discs by 60 px (D-C2a-9); Play hit 170 × 80 and More 80 × 80 do not overlap, centres 167 apart (≥ 145) |
— | 2026-10-07 07:55 | 11094443 |
| M3-R1 | <s4/t_routes.js> --mode pad --flags wp.c2a,wp.p3,wp.c1a |
PASS: What's New (L.click) → /library/lgs/steamhome, data-lgs-glass="window-full", data-lgs-route="steamhome", Steam's Home inside, title "What's New", no footer; B → /library/home (windowless). Collections: Great On Frame, Ready To Play, Installed, Non-Steam, Soundtracks, VR, Empty Collections (as the mockup). A on VR → /library/lgs/folder/uc-… (windowless, folder), title "VR", "View in Library" (Steam's #Generic_ViewInLibrary), 13 cells, 3 dots; its click logs navigate("/library/collection/uc-…"); B → Home with focus on the VR cell. Empty Collections → 8 cells; a click logs navigate to Steam's collection page. Apps: 2 pages A–Z from Camera Switch, no Liquid Glass (AT-5b); a program click logs launchNonSteam(<Steam's cmdline>) |
shots/p2_c2a_folder_pad.png, shots/p2_c2a_whatsnew.png |
2026-10-07 07:45 | 11094443 |
| M3-ART | <s4/art_probe.js> (image naturalWidth per cell), shots p2_c2a_home_recent, p2_c2a_home_card_pad |
Shortcuts list their custom art as .jpg and .png; slice 1 tried only the first, so DolphinXR and Batman fell to monograms and five logos were missing. Now every candidate is tried in order (custom, then Steam's cached asset): all 12 games show hero + logo. Not-installed games (ov.installed is a getter that is undefined, not false) now get the cloud badge and the dimmed art |
shots/p2_c2a_home_recent.png, shots/p2_c2a_home_card_pad.png |
2026-10-07 07:50 | 11094443 |
| M3-C1 | <s4/t_card_clicks.js> --mode laser after moving the card into its cell (D-C2a-10) |
PASS: Play → only primary(391220) logged; the card's body → navigate("/library/app/391220") logged (the cell's own activation); More → Steam's menu, nothing logged; route unchanged |
— | 2026-10-07 08:05 | 11094443 |
| M3-G1 | C2a scratch s5/run_gates.py / run_gates2.py: python glass.py gates main --route /library/home --pre <state> --only size,type,outline,motion --flags wp.c2a,wp.p3,wp.c1a --mode laser|pad --json --shot p2_c2a_g_<state>_<mode> for rest, card (laser dwell / pad focus on cell 6, 1.5 s), Collections, Apps, folder VR, What's New; a run whose step line said native=on (another agent's session) was retried until CSS-only |
PASS (all four gates) in both modes: rest, card, Collections, Apps, folder (after the folder top-row fix). What's New: TYPE/OUTLINE/MOTION PASS, SIZE only %{SeasonalSale} (REQ #13) |
shots/p2_c2a_g_*.png |
2026-10-07 08:26-09:15 | 11094443 |
| M3-AUD | <s4/t_aud_rel.js> stock (--stock) and themed with flags, compared by path relative to Steam's Home page root (s4/cmp_aud.py) |
0 issues: 276 nodes each side, 190 visible, 151 controls; no GONE, HIDDEN, SHRUNK, UNCLICKABLE or text change | — | 2026-10-07 08:20 | 11094443 |
| M3-N2 | <s4/t_nav.js> --flags wp.c2a,wp.p3,wp.c1a --mode pad on the final code |
PASS, every step as M3-N1 (entry c0, row moves, page turn and back, one-step memory, clamp, top row, What's New, Down back to the grid, RB/LB sections with remembered cells) | — | 2026-10-07 09:20 | 11094443 |
| M3-P2 | glass.py pad-bfs --route /library/home --max 80 --budget 280 --flags … --mode pad (s5/run_bfs.py), plus stock probes l_probe2.js, b_probe.js, search_probe.js |
Final code: 13 nodes, 0 irreversible (was 11: node keys used is-* state classes and the card's text; fixed with c2a-cell / c2a-seg and aria-label; top-row memory). 5 unreached because Left on the search field is exit:none and nothing brings focus back (stock Home behaves the same on its first capsule: REQ #14). B: history back on T3 and on stock |
s5/bfs_home.json (scratch) |
2026-10-07 08:55-09:15 | 11094443 |
| M3-E1 | <s5/err_probe.js> --flags … --mode pad (Recent, card, Collections, Apps, Recent; rt.settled(), home.state().logTail) |
PASS: home installed, no warning or error in its log, status reports no failure |
— | 2026-10-07 09:41 | 11094443 |
| M5-N1 | python glass.py native-session --flags wp.c2a,wp.p3,wp.c1a --mode pad --step "js <hold: card on cell 6, snapshot, 24 s>" --step "sgcheck --route /library/home --mode pad --pre <card>" --step "sgcheck … --mode laser --pre <rest>", and glass.py hv c2a_home_ns --look started 4 s (14 s in the last run) into the hold (s5/run_native*.py) |
Report as planned (18 plates, 4 bands, home-card dz 0.0407, interactive: false, errors: []); sgcheck rest PASS, card FAIL R1 (pop corner; REQ #16). hv frames (viewed, deleted): native Home is a grey slab without disc glass or art (REQ #17). Back to CSS only: yes, both sessions |
— | 2026-10-07 09:19-09:39 | 11094443 |
| M4-prep | theme/layers/41-home.json written (5 rules, every one flag: wp.c2a; reporter honours rule flags, device/lgs_layers.js l. 1354); check-theme PASS (valid JSON) |
Not run in a native session (round R1) | — | 2026-10-07 | n/a |
| R2F-M1 | CSS-only: js pA.js (pad, card on cell 6 of Recent, then a D-pad move; C2a scratch c2a_r2/p/). Native: native-session 19:45 and 19:58 (--flags wp.c2a,wp.p3,wp.c1a --mode pad): js n_report.js, shot main p2_c2a_r2f_native_card_tex2 (Steam's texture with the acks) |
PASS. CSS: the attended cell has has-card and its disc fades to opacity 0; the card is black .78 under white .12 → .02 with blur(12px) saturate(1.7); the four discs and four labels it overlaps carry a clip that cuts the covered part away (data-lgs-plate-occluder="false" on all other discs). Native: the report has home-card 480 × 360 r 54 at 0.0407 u, non-interactive, over its occluder plate; the cell's own disc plate is gone (opacity 0, not reported); Steam's texture inside the card's rect holds only the card (art, Install with its X badge, More, title, status): no own disc, no cloud badge, no neighbour slice (p2_c2a_r2f_native_card_tex2.png, cropped and viewed). The first version's rounded path() hole drew corrupted tiles and a misplaced row of labels in native mode (19:47, p2_c2a_r2f_native_card_tex.png); replaced by a rectangular inset() clip (D-C2a-21), clean at 19:59 |
shots/p2_c2a_r2f_native_card_tex2.png, shots/p2_c2a_r2f_card_pad.png |
2026-10-07 18:05–20:00 | 11094443 |
| R2F-M3 | js pM3.js --mode pad |
PASS: the All Games plate (906, 644) 139 × 60 ends at y 704; Apps row-3 plates (161 / 433 / 656 / 878, 644) end at 704; rows 1–2 unchanged (top at disc centre + 74). Shot p2_c2a_r2f_allgames_plate.png viewed: the plate is whole above the page dots |
shots/p2_c2a_r2f_allgames_plate.png |
2026-10-07 18:09 | 11094443 |
| R2F-M4 | js pM4.js --mode pad (2.5 s after entering Collections) |
PASS: 0 broken images in every folder: Great On Frame, Ready To Play, Installed, VR and All Games 9 / 9 loaded; Soundtracks 9 / 9 from header crops; Non-Steam 5 loaded, 4 tiles empty (no candidate loads); Apps program icons 0 broken. Shot viewed (p2_c2a_r2f_coll_pad.png) |
shots/p2_c2a_r2f_coll_pad.png |
2026-10-07 18:11 | 11094443 |
| R2F-M7 | js pM7.js --mode pad (fault injection: P2's actions.primaryInfo, then data.art, made to throw for the step and restored in finally) |
PASS: (a) the card throws: no card, Home stays windowless, no error page, the next card opens; (b) a cell throws: Steam's own Home renders in place of ours and the route is window-full (glassMode('home') answers null), our Home is back after the next visit; (c) a folder throws: the history entry is replaced by Steam's /library/collection/<VR id> in window glass. P2's error page never shows |
— | 2026-10-07 18:15 | 11094443 |
| R2F-M9 | js pP29.js in both modes (every game cell of Recent page 1, card measured at 1.35 s) |
PASS (VP P-29): Play's centre 36–379 px from x 640 (pad 51–387 before the 40 px clamp, laser 36–372), y 288 / 416 / 574; the action row is mirrored on cells 1, 5 and 10; Play and More hits never overlap (centres 152–182 apart). Rerun after the 96 px hits in batch 12 (R2F-M9b) | — | 2026-10-07 18:07–18:08 | 11094443 |
| R2F-M12 | js pM12.js --flags …,wp.c1b --mode pad |
PASS: with three test windows (rt.home.test.windows) the fourth segment "Windows" appears (track 608 wide, segments 140 / 172 / 140 / 152); RB × 3 reaches it; the cells use the window glyph; A on a window logs desktopWindow(101) mode: logged; RB at the end stays; with the list empty the segment goes and the section falls back to Recent. Provider c2a.programs registered (failed: false); rank('vlc') = VLC media player tier 1 in 0.5 ms; rank('half') = Half SBS Toggle tier 1; rank('liquid') = []; open logs launchNonSteam("/usr/bin/vlc \"--started-from-file\"") logged; open(c, ev, {slot: 'software', more: 2}) opens Home › Apps with Half SBS Toggle focused (also while Home was already showing) |
shots/p2_c2a_r2f_windows_pad.png |
2026-10-07 18:13–18:15 | 11094443 |
| R2F-M13 | js pM13.js --mode pad (rt.home.test.status) |
PASS: a downloading game: is-downloading, art dimmed, the progress ring at 62, 100, no cloud badge, card status "Downloading · 62%" (Steam's #DisplayStatus_Downloading); an update: the blue badge (28 px) and "Update Required" (#DisplayStatus_UpdateRequired); cleared after. Steam's enum read live (EDisplayStatus 3 Installing … 23 DownloadQueued, 20 UpdateRequired). No game of this library is downloading now, so the live client-data path was not exercised |
shots/p2_c2a_r2f_download_pad.png |
2026-10-07 18:14 | 11094443 |
| AT-1 | shot main p2_c2a_r2f_{home_laser,card_pad,card_laser,card5_pad,allgames_plate,coll_pad,apps_laser,folder_pad,wn_pad,windows_pad,download_pad} --route /library/home --pre <state> --flags wp.c2a,wp.p3,wp.c1a --mode …; js pGeom.js --mode pad |
PASS: 13 cells (12 recent games + All Games), 2 dots, the top row with 3 segments, What's New, C1a's Back and search (the capsule: default low layout), no #Footer (stock Home has none either), no legend hidden, data-lgs-glass="windowless", data-lgs-route="home". Every shot viewed composited over the lounge or studio room: the visionOS app-selection view; the open card hides what is under it; the mirrored card on the left; Collections with header crops for Soundtracks and empty tiles instead of broken images; Apps with peeks on discs; the folder with its card; What's New with the recessed feed track; the Windows section; download and update states |
shots/p2_c2a_r2f_*.png |
2026-10-07 19:23–19:43 | 11094443 |
| AT-2 | js pGeom.js --mode pad |
PASS for the low layout (HA §3.1.1; C1a's capsule is the default): column pitch 224, rows at y 236 / 416 / 596 (pitch 180), disc 120 (132 lifted, from its top edge in row 1); section track (412, 102) 456 × 64, segments 140 / 172 / 140 × 80 at y 94–174, gaps 0; What's New (973, 24) 203 × 60 in an 80 hit; Back box (14, 14, 80, 80); C1a's search capsule (372, 14) 536 × 80; dots centred on x 640 at y 700; elementFromPoint(640, 30) = the search capsule (so the low layout applies, as designed) |
— | 2026-10-07 19:14 | 11094443 |
| AT-3 | pad-bfs --route /library/home --pre <wait> --budget 300 --flags … --mode pad and --mode laser; the same with the VR folder (pre_folder.js); js pSound.js --mode pad (the D-pad, bumper and trigger sequence) |
PASS (G-PAD): Home 26 nodes, 0 unreached, 0 untakeable, 0 irreversible, 5 exits all back (overlay), Play and More under inner, both modes; folder 29 nodes, 0 unreached, 0 irreversible in both modes (18:35–18:36, after the page-turn memory; the 18:30 run had 2 irreversible page turns onto the short last page, fixed); takeOrder only (capsule -Down-> cell 3, whose user path goes to View in Library). The sound sequence: (a) Right × 3, (d) Right at the row end → page 2 and back, (c) Down / Up memory, (e) RB → Collections → Apps, LB back, (f) RT / LT pages, Up into the top row and Down back to the remembered cell, (k) entry on cell 1 |
c2a_r2/out/bfs_*.json (scratch) |
2026-10-07 18:09–18:36 | 11094443 |
| AT-3(g) | as AT-3 (exits) |
PASS (parity with stock): Left from the first cell of a row on page 1 leaves the main window (exit:none), as on Steam's own Home; focus comes back by overlay |
— | 2026-10-07 18:28 | 11094443 |
| AT-3(h) | as AT-3 (b) |
PASS (Steam's own behaviour, HA §3.5 corrected): B at the Home root goes back in Steam's history (pad: /library/home → the previous route, /library/downloads; laser: → /library/tab/AllGames), as stock Home does (S3-B4); in a folder B goes back to Home |
— | 2026-10-07 18:28–18:36 | 11094443 |
| AT-3(i) | js pSound.js --mode pad |
PASS: RB from Apps stays on Apps and requests FailedNav (deck_ui_bumper_end_02); What's New is not in the bumper cycle; LB back to Recent |
— | 2026-10-07 18:09 | 11094443 |
| AT-9 | motion main --route /library/home --pre @{m_ramp,m_close,m_section,m_page,m_plate}.js --name c2a_r2f_* --flags … --mode pad|laser --json, and m_close, m_ramp with --media reduce |
PASS all seven (18:40–19:09): every duration and easing a P5 token, 0 animations at rest, reduce = opacity only. Strips viewed: section change f = 0 shows the old grid, f = .15 the cross-fade (no blank frame); the card close keeps the card's node (clip back into the disc, glass out on materialize-out, the disc back in); the plate leaves on materialize-out. Earlier runs that failed were the pres' own bounces (Chromium shortens a reversed transition; pAnim2.js traced it to the pre) and a new card opening while the strip ran; the pres were fixed, not the module |
shots/p2_motion_c2a_r2f_* |
2026-10-07 18:40–19:09 | 11094443 |
| AT-16 | js pRemove.js --mode pad (flag off on the VR folder with Steam's tile menu open) |
PASS: route /library/home, Steam's Home in window-full, 0 lgs-home nodes, 0 data-lgs-home/plate/mosaic/transient attributes, the menu closed, footer hide count back to Steam's 1, attention registrations 3 → 2, rt.home gone, module off; a stale /library/lgs/steamhome entry falls back to Steam's library; flag on again reinstalls (13 cells). Leaks over 3 Home → folder → What's New cycles: none (footer 1 → 1, registrations 3 → 3, live 1); idle: no animation running, 2 runtime ticks (0.5 ms) in 4 s, listeners 7 → 7 |
— | 2026-10-07 19:16 | 11094443 |
| AT-21 | js pSound.js --mode pad (PlayAudioURL spy that records and never plays) |
PASS (VP P-74, P-79): every D-pad move inside the honeycomb (Right, Down, Up, Up into the top row, Down back to the grid) requests deck_ui_misc_10 (BasicNav) exactly once, as stock Home does; page turns deck_ui_navigation; section changes deck_ui_tab_transition_01; dead ends (Down on the bottom row, Right at the last page's row end, RB at the last section, RT on the last page) deck_ui_bumper_end_02 (FailedNav) |
— | 2026-10-07 18:09 | 11094443 |
| AT-22 | js pFail.js --flags wp.p3,wp.c1a --mode pad (P2's ready() made to throw a transient error, so P1 retries and the module is not left failed) |
PASS: module failed (transient, retry 1/4); /library/home = Steam's Home in window-full; after the retry the module installs and Home is ours, windowless. While failed, a folder history entry is a glass-less windowless page (review m16): C1a's map, REQ C2a->C1a #18 |
— | 2026-10-07 19:16 | 11094443 |
| AT-23 | js pMisc.js --mode laser (rt.home.test.lang('de')) |
PASS: the Apps segment becomes the grid glyph; "Empty Collections" is omitted; Steam's own strings stay (Steam's UI is English); reset after | — | 2026-10-07 18:14 | 11094443 |
| R2F-m15 | js pMisc.js --mode laser (wp.c2a pushed off, then on, on /library/tab/AllGames, then /library/lgs/steamhome before Home has rendered) |
PASS: the route passes through Home and comes back; What's New shows Steam's Home in window-full with the title "What's New" |
— | 2026-10-07 18:14 | 11094443 |
| R2F-m1 | js pMisc.js --mode laser |
PASS: a synthetic laser dwell on a peek sets P3's .lgs-dwell (the peek has data-lgs-dwell), cleared on leave; the CSS look keys on .lgs-dwell:hover (a real hover; the press swell on :active) |
— | 2026-10-07 18:14 | 11094443 |
| R2F-m2 | js pM3.js --mode pad (Apps plates against every label's text rect, measured independently) |
PASS: on 7 plates every faded label is one whose text the plate overlaps, and every overlapped one is faded (e.g. Frametop Display Settings fades only Frametop Input Settings) | — | 2026-10-07 18:09 | 11094443 |
| R2F-B12 | batch 12 (36 steps, 20:04-20:56) and reruns 13-17 (to 21:04), c2a_r2/list12.txt (scratch) |
gates: see Status; p29 both modes PASS after the 96 px hits (R2F-M9b); m3, m4, m12, mru PASS (a logged launch of Camera Switch does not enter Recent, launched('vlc') puts VLC first, cleared after); tsw sweeps A/B1/B2 both modes PASS; at4_laser PASS; AUD stock/themed relative rerun 0 GONE; ext_pad (folder: search -Down-> first cell -Up-> search, Back -Right-> -Down-> cell -Up-> back where it came from) PASS (M15); mo_close2 PASS, mo_close_reduce2 PASS after the fix; focus_pad P-14 PASS, P-16 FAIL (m3, recorded); cmp home-apps-home-t1 all rects 0 px but card-play dw +65 (the live card's action is wider than the mockup's "Play": content, not layout) |
shots/p2_motion_c2a_r2f_*, shots/p2_cmp_c2a_home-apps-home-t1.png |
2026-10-07 20:04-21:04 | 11094443 |
| AT-13 | js pAT13.js --flags wp.c2a,wp.p3,wp.c1a,wp.c1b --mode pad |
PARTIAL: "half" → Half-Life: Alyx top hit, Play / Options, A logs primary(546560); "vlc" → no Software row, A → /steamweb (REQ #23) |
— | 2026-10-07 21:04 | 11094443 |
| AT-11, AT-19 | not run this pass | — | — | — | — |
Log
2026-10-07, session 6: R2 fix pass 1 (17:10-21:06)
- Fixed the review's majors and cheap minors (list in Status) in
41-home.js,41-search-apps.js(new provider),41-home.css,41-home.json, HA, XC rev 4 andC2a-cmp.json; answered the REQs to C2a (handled list); new REQs #18-#23. - Native: the rounded
path()occluder clip corrupted Steam's texture (19:47), replaced byinset()(D-C2a-21); second session clean. - Batch 12 and reruns: see Status and R2F-B12. Late fix: Reduce Motion now also stops the segment's P4 pseudo-element transition (P-56).
- Device left CSS-only, stock route, no flags; hv frames deleted on both machines.
2026-10-07, session 5: M3 and the native check (08:25-09:45, expedited)
- Start:
grep -n "REQ [A-Za-z0-9]*->C2a:" docs/phase2/wp/*.md: nothing new (C1b #5/#6, C2c REQ-1/2, P6's FYI, all handled). P10 had closed #9 and #12. - Device steps: only
glass.pylab commands (gates,pad-bfs,js,surfaces,sync,reload, threenative-sessionruns withhv --look); everyhvframe viewed and deleted at once (the tool deletes the Frame copy). No setting changed, nothing launched; X / Play only logged. Ended in CSS-only mode, no flags left, pointer at (1400, 900) by a laser step. A bar tooltip surface (tooltip.85100002) was visible at the end; C2a never hovered the bar. - Fixes: see Status "Session 5 changes"; D-C2a-13 added; REQs #13, #14, #16, #17 filed, #15 filed and withdrawn after a stock probe.
2026-10-07, session 3: M2 (resumed 05:20)
- Start-of-session request check:
grep -n "REQ [A-Za-z0-9]*->C2a:" docs/phase2/wp/*.mdfound only the four handled in session 2 (all[x]); nothing new. - Built
theme/41-home.css(parts A, B, C),docs/phase2/wp/C2a-cmp.json,theme/layers/41-home.json; HA §3.7 gained a paragraph on the T1 restyle. Requests filed: #6 (C2c), #7 and #8 (P10). Decisions D-C2a-6 to D-C2a-8. - Device steps: only locked lab commands (
shot,gates,js,pad-bfs,focus --png); no native session, no setting changed; the Home feed tab was switched by tab clicks during the deep-feed gates and put back to What's New (checked). The T3 module ran only inside locked steps with--flags. - 07:15: P1, P2 and P3 at M3, so M3 started:
device/rt/41-home.jsslice 1 (M3-S1).
2026-10-07, session 2: M0 conformance (resumed)
- Start-of-session request check: see "Requests to C2a, handled".
- Read: PLAN §0, §1 (all), §2.1, §2.4 (C1a, C1b, C1c, C2a, C2b, C2c), §2.6, §4.2; HA (all, revision 3 from session 1); XC; WN §3.1.1 (route map); contracts
interaction.md(P3, all),react.md(P2, all),lab.md(P10, §1, §3, §4),reporter.md(P6, §2, §3, §4),tokens.md(P4, names used by HA),motion.md(P5, keyframes and delays); logs C1a (interface), C1b (interface, proposed WN §4, requests), C1c (scrim, requests), C2c (all). - Checked HA's API names against the contracts:
rt.attend/rt.attention.feed/lgs-attend-<ms>/leaveMs(P3 §2),rt.sound('tab' | 'page')(P3 §5),data-lgs-tip(P3 §4),routes.override/routes.addunder/library/lgs//nav.go/actions.*/data.useNonSteamApps/ui.loc(P2),data-lgs-plate*,data-lgs-mosaic,when: "attended",exclude,wearer(P6),--lgs-mat-plate-bg,--lgs-shadow-15mm,--lgs-page-dot(P4),lgs-mat-glass-in,lgs-page-in,--lgs-d-reduce(P5),gates,pad-bfs,focus,motion,sgcheck,hv,cmp,native-session,--flags,--mode,--media(P10). Fixed:data-lgs-plate-tinttakes a CSS colour (was "text"). - Edited:
docs/phase2/concepts/home-apps.md(see "Requests to C2a, handled" and the Status),docs/phase2/concepts/xc-home-search.md(revision 3), the mockupshome-apps-home.html,-home-t1.html,-apps.html,-collections.html,-folder.html,-depth.html,-search.html,home-apps.css; the four request lines inC2c.mdandC1b.md(marked[x]). - HA changes beyond the requests: the footer rule for Home and folders (PLAN §1.10: never hidden; the two-row fallback,
lgs-home-footer); theglassMode('home')dependency and its interim CSS fallback (§3, §13, §15 #17); rule 6 for the Home card and the library's source posters (§3.5, §10.4, §15 #18); menus over Home need athickplate (§8, §15 #19); Play's width (at most 190) and the real centre spacing (184, at least 145); labels fade only when their text is covered; the More tooltip is C2a's, the search circle's is C1a's; the click-safe wording follows PLAN §1.7 rule 2; the plate count is at most 18. - No theme or runtime code written (M0). No device step: no Steam, SteamVR, theme or native-mode action.