Files

85 KiB
Raw Permalink Blame History

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, _wip identical, 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-bfs What's New truncated at budget (Steam's feed, 340 moves), not a defect of ours.
  • Native: two native-session runs (19:45, 19:58): all four sgcheck states 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 launches mode: 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 laser and --mode pad on 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/steamhome against stock /library/home by relative DOM path: 190 visible items, 151 controls, 0 GONE / HIDDEN / SHRUNK / UNCLICKABLE / TEXT (M3-AUD; gates --stock-route keys 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-bfs 13 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 home installed, 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 primary through 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 as aria-label and a stable first class c2a-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-session runs, 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 pop home-card at +15 mm (dz 0.0407), interactive: false, no errors; at rest no pops (sgcheck PASS). sgcheck with 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. Three hv --look frames (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 with shapes: [], 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; _wip copies identical. device/rt/41-search-apps.js not written: C1b's 21-search.js appeared 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.c1a and --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 (P2 loc arguments), #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 it windowless only when C2a's hook answers. 41-home.js will register __LGS_RT.shell.glassMode('home', () => live ? 'windowless' : null) (the hook WN §3.1.1 already offers C5a and C3b); with null, or no hook registered, use window-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 say windowless and Steam's Home feed would float over the room with no glass (HA §3, §3.7, AT-22). /library/lgs/folder/* can stay unconditionally windowless (those routes exist only while the override runs). C1a answer (2026-10-07, session 2): adopted (WN §3.1.1): /library/home is windowless only while your hook answers; with null, a throwing hook or none, it is window-full. Hook: __LGS_RT.shell.glassMode('home', fn) → {remove()}; call __LGS_RT.shell.refreshGlass() if live changes after the route settled. Folders stay windowless.

  • REQ C2a->C1a: #2 on every windowless route (Home, folders, /invites, CC-M), tag Steam's Back circle and the search circle as plates: data-lgs-plate="liquid" with stable ids (suggested shell-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 from 41-home.js (HA §10.2). C1a answer: adopted (WN §3.2 "Windowless routes"): on every windowless route the shell's T2 tags the Back circle data-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 windowless routes: report the menu box (and the alert or sheet card) as a plate, data-lgs-plate="thick", while data-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 thick plate while data-lgs-glass="windowless", in C1c's M4 fragment theme/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 (flag wp.c1c) sets data-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.
  • 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/steamhome by design; HA AT-6 audits them there against stock /library/home (HA §15 #14).

    • P10 (2026-10-07 06:35): done: gates … --stock-route R2 and audit … --stock-route R2 snap R2 with the theme off and --route R themed (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.
  • REQ C2a->C2c: #6 theme/40-library.css: please delete the Home rules now that theme/41-home.css carries them (PLAN §6 row 40-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/home whenever a rule of yours wins.

    • C2c (2026-10-07, R2 fix pass): done since C2c session 2: theme/40-library.css has no %{RecentSection} rule; it holds only library-catalogue rules under %{GamepadLibrary}, the toolbar pill, the library's ornament rules, Library Filters and the scrubber.
  • REQ C2a->P10: #7 gates sweeps count content the window glass clips away. On window routes C1a clips the page at y 656 (clip-path on %{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/home at 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, where elementFromPoint returns 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.
  • 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". The art test only exempts icon-only controls. Please treat a control that contains an <img>/<video> or a url() 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/picture or url() background and ≥ 100 px tall × m) and list rows (%{*GamepadDialogContent>Field}, role=option|tab|row|listitem).
  • 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/home at 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-bottom 612) brings it fully into view before it takes focus. Please skip (as skipped: 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-gh now lives on %{BasicUiRoot}, so the lab now resolves the clipping ancestor's clip-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.
  • 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 open launches, and when it reads "and N more" open goes to Home › Apps with that program focused, through C2a's rt.home.reveal({section: 'apps', key}) (exported by 41-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 my rank returns as subtitle; (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 behind wp.c2a with wp.c1b; AT-13 row). Please call open(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. rank also returns data.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.js LgsAll): (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 (your data.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 your subtitle; (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 gets ctx.steamBest = {tier, appid} now.
  • REQ C2a->C1a: #10 on windowless routes (Home, folders), please drop the header's scroll-edge band: #header%{Profile>Header}::before (20-shell.css, the 124 px band with backdrop-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-opacity at 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; } in theme/20-shell.css §2 (synced 08:15). It applies whenever the shell's T2 sets windowless (your glassMode('home') hook answering, folders, /invites).
  • REQ C2a->P2: #11 (a) ui.loc(token, ...args) returns the raw %1$s form: Steam's LocalizeString ignores the extra arguments (live: loc('#Playtime_Total_Minutes', '3') gives "%1$s mins played all time"). Please substitute %N$s in loc (and so in text), or note in react.md §6 that callers format; C2a formats itself for now (homeFmt in 41-home.js). (b) FYI, a finder you may want as a built-in: Steam's library app context menu (the capsule's onMenuButton renders it): module with #GameAction_DismissPlayNext, #GameAction_ConfirmStopStreamingTitle and bFitToWindow; exports the menu component (source navigator: + instance:) and its options ({bFitToWindow: true, strClassName: …LibraryContextMenu}); shown as showContextMenu(<Menu overview client="mostavailable" launchSource={1000} bInGamepadUI ownerWindow/>, anchor, options()). 1 candidate on build 11094443 (module 43394). C2a uses it through rt.react.find for Home's tile menu.

    • P2 (2026-10-07 13:05, review R1 session): (a) done: ui.loc(token, ...args) now fills %1$s ... %9$s from its arguments (Steam's raw string otherwise; a placeholder without an argument stays), so ui.text too when called through loc; homeFmt keeps working (it formats a string that has no placeholders left only when you pass args to loc). 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; your rt.react.find is the right place. If a second package needs it, send the spec and it becomes a named finder.
  • 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 carries data-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 as skipped: 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 is skipped: 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.
  • 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 fixture tools/p2/test_gates_page.py cases 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.
  • REQ C2a->P10: #14 pad-bfs: recover after an exit: edge. On /library/home (--flags wp.c2a,wp.p3,wp.c1a --mode pad, 09:05) Left on C1a's search capsule is exit:none; afterwards FocusApplicationRoot(), B and L.gpTakeEl all leave .gpfocus absent in main (probe search_probe.js in C2a's scratch, 2026-10-07), so every later node is untakeable and 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 fresh L.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 and L.root() does not bring focus back, l_probe2.js 09: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 own EnsureVROverlayVisible() with the root and Down + Up (after vr-null-tree: the gamepad had left Steam's overlay), and last Navigate(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 are lgs-home-play "Play" and lgs-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 by overlay; 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 says native: on); the sweep reads focus, not pixels. contracts/lab.md §4 pad-bfs.
  • (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 sgcheck R1 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's r from 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 r from the report, deflated with the pop by P6's 2 px; capsule too). 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) and sg_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.
  • 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 was mode: "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 with shapes: [] (it looks like Phase 1's whole-surface cover or the window shape is drawn) and whether plates and explicit mosaic bands reach glassd on windowless surfaces. 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.json main shapes: [] with your 18 plates and the home-card slab; glassd-out.json main cover: 0, plates 18; 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 explicit data-lgs-mosaic bands 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 in wp/P7.md): at hv --offaxis 20 the 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.json main shapes: [], 18 plates and the home-card slab; glassd-out.json main cover: 0, plates 18, slabs 1, 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).
  • REQ C2a->C1a: #18 route map, /library/lgs/folder/*: please make its default window-full (as for home), and windowless only while a glassMode('folder') hook answers. 41-home.js registers glassMode('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 while wp.c2a is off or its install failed renders Steam's library fallback (P2 drops unknown /library/lgs/ routes) on a windowless, glass-less page; with window-full it 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 ::after and the edge's ::before (03-material.css §E3, 04-states.css) transition --lgs-focus (and --lgs-hover) on --lgs-ill-d-out / -d-in also under prefers-reduced-motion: reduce, where P10's motion --media reduce lists them as "animates --lgs-focus under Reduce Motion" (C2a's card-close strip, 18:50). Please set those transitions to 0s (or opacity-only) inside the reduce media query for every host. C2a sets transition: none on 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.json now supersedes the legacy card rule behind wp.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 .gpfocus in laser mode and a feed card whose own rule admission had dropped (sgcheck R2 FAIL, native session 19:50). With wp.c2a on, search results (%{GamepadSearch} %{ResultTemplate}) are therefore flat unless 21-search.json pops 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.c2a on, the library's posters keep only your library-poster rule (behind wp.c2c); the legacy 2.95 mm lift is gone (also noted under your REQ-11 in C2c.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 provider c2a.programs for 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 the hl-* block and .ha-poster.is-lift; kept .ha-poster (base, img.port, .is-titlecard) and home-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'], rank with tiers 0–3, open, no primary (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.md and C1b.md are 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] in C2a-review-R2.md with a pointer here.
    • Coordinator R2-2, R2-3, R2-5: home-apps.md §7.1 (default hugging ornament, five slots as the libFixedSlots variant), HA-11 and §8 Cancel 60, §0.5 rows §1.7/§1.10/§1.12, §15 #18 resolved; also xc-home-search.md §3. Answered in coordinator.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 in coordinator.md.
    • C2c REQ-11 and P6's literal-inset REQ: answered in C2c.md and P6.md (the What's New track is on the tab row's ::before, the arrows paint --lgs-raised-shadow, 41-home.json supersedes tab-arrow behind wp.c2a; native evidence N-SG rows).

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 and C2a-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 by inset() (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.py lab commands (gates, pad-bfs, js, surfaces, sync, reload, three native-session runs with hv --look); every hv frame 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/*.md found 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.js slice 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.add under /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-tint takes 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 mockups home-apps-home.html, -home-t1.html, -apps.html, -collections.html, -folder.html, -depth.html, -search.html, home-apps.css; the four request lines in C2c.md and C1b.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); the glassMode('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 a thick plate (§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.