Sidebar account pill drifts up from the bottom; rename Mesh hosts by double-tap #259

Open
opened 2026-10-30 13:03:02 +00:00 by kayg · 13 comments
Owner

Owner report, 2026-10-30 (production 9.5, Aside / Chromium on an M2 Max, desktop): the account pill (avatar, name, settings gear) at the bottom of the Views sidebar moved gradually up to about a third of the way down the screen, directly under the Settings group. The sidebar panel still reaches the bottom of the window, with empty space below the pill. Screenshot in the owner thread.

Expected: the pill stays pinned at the bottom of the sidebar at every window height and sidebar content length, without moving over time. Find out what moved it ("gradually" points to a layout or height transition that runs or re-runs, or a height computed once and then animated) and fix the cause.

Related request in the same message: rename a Mesh host by double-tapping (double-clicking) its name, in the Mesh view and the Views tree (the mesh API already has mesh.node.rename).

Owner report, 2026-10-30 (production 9.5, Aside / Chromium on an M2 Max, desktop): the account pill (avatar, name, settings gear) at the bottom of the Views sidebar **moved gradually** up to about a third of the way down the screen, directly under the Settings group. The sidebar panel still reaches the bottom of the window, with empty space below the pill. Screenshot in the owner thread. Expected: the pill stays pinned at the bottom of the sidebar at every window height and sidebar content length, without moving over time. Find out what moved it ("gradually" points to a layout or height transition that runs or re-runs, or a height computed once and then animated) and fix the cause. Related request in the same message: **rename a Mesh host by double-tapping (double-clicking) its name**, in the Mesh view and the Views tree (the mesh API already has `mesh.node.rename`).
Author
Owner

Design sub-agent start. Branch sidebar-pill-259, base f9d0a9a8f (origin/dev). Plan: reproduce pill drift in a production build, fix the cause with a failing browser test first, then inline Mesh host rename (double-click/tap) + palette entry.

Design sub-agent start. Branch sidebar-pill-259, base f9d0a9a8f (origin/dev). Plan: reproduce pill drift in a production build, fix the cause with a failing browser test first, then inline Mesh host rename (double-click/tap) + palette entry.
Author
Owner

Finished (design sub-agent). Branch sidebar-pill-259, head e8c969d006, base f9d0a9a8f. Pushed, not merged.

Pill root cause. The footer is pushed down by margin-top:auto, but .ui-inbox ~ .ui-sidebar-foot { margin-top: 0 } matched the inbox card even after it was hidden (display:none, still in the DOM), so nothing pushed the pill down. Reproduced in a production build at 1773x2000: pill gap to the panel bottom 1090 px (expected 8); at 1440x900 the tall tree masks it. Fix: match only .ui-inbox:not([hidden]). Test sidebar-foot-pin.spec.ts samples the gap every frame (tree open/collapsed, inbox shown/gone, idle + hidden/visible, both sizes): failed before, passes after.

Rename. Shared packages/ui inline-rename.ts (session manager migrated to it), double click/tap on Mesh card + Views tree, palette "Rename " (meshes up to 40 hosts, the size drawn as cards), mesh.node.rename via api.ts renameNode (not optimistic: name is identity; refusal gives a plain sentence + old name back). Phone: sidebar close waits 360 ms after a tap on a host so the second tap can land.

Evidence (production build): card-editing-desktop-ink.png
card-editing-desktop-paper.png
card-editing-phone-ink.png
pill-desktop-ink.png
pill-desktop-paper.png
pill-phone-ink.png
refused-duplicate-desktop-ink.png
tree-editing-desktop-ink.png
tree-editing-phone-ink.png

Checks. bun unit tests mesh: 44 pass; palette-actions pass alone. Browser: sidebar-foot-pin, mesh-rename (10), inbox, mesh.spec, sessions-canvas, core-screen: 101 pass, 3 fail: core-screen:151 and sessions-canvas:330 fail identically on a clean origin/dev checkout; core-screen:254 timed out under 2 workers and passes alone on my branch. scripts/verify iterate (arm64): fmt/clippy/CLI compile-out/artifact gate PASS; Rust test FAIL in infraternal-plugin-ssh --test install (interrupted_rollback_never_deletes_already_restored_state_on_retry, streaming::decoded_image_and_hash_advance_before_the_transfer_tail_is_released), cargo-deny not installed: no Rust file changed. x86 verify fast left to the orchestrator. Known: bun test src/canvas run together shows 4 matchMedia "readonly property" errors, same on baseline.

Bundle (gzip, concatenated js+css+html of apps/tracer/dist): 489024 -> 491855 B, +2831 B.

Finished (design sub-agent). Branch sidebar-pill-259, head e8c969d006fcfe9bb45838e8daa49fe13ea700c1, base f9d0a9a8f. Pushed, not merged. **Pill root cause.** The footer is pushed down by margin-top:auto, but .ui-inbox ~ .ui-sidebar-foot { margin-top: 0 } matched the inbox card even after it was hidden (display:none, still in the DOM), so nothing pushed the pill down. Reproduced in a production build at 1773x2000: pill gap to the panel bottom 1090 px (expected 8); at 1440x900 the tall tree masks it. Fix: match only .ui-inbox:not([hidden]). Test sidebar-foot-pin.spec.ts samples the gap every frame (tree open/collapsed, inbox shown/gone, idle + hidden/visible, both sizes): failed before, passes after. **Rename.** Shared packages/ui inline-rename.ts (session manager migrated to it), double click/tap on Mesh card + Views tree, palette "Rename <host>" (meshes up to 40 hosts, the size drawn as cards), mesh.node.rename via api.ts renameNode (not optimistic: name is identity; refusal gives a plain sentence + old name back). Phone: sidebar close waits 360 ms after a tap on a host so the second tap can land. **Evidence** (production build): ![card-editing-desktop-ink.png](https://git.kayg.org/attachments/59546c3e-a516-4758-8dab-411bc7ef172c) ![card-editing-desktop-paper.png](https://git.kayg.org/attachments/757d8184-479d-44f8-9ef3-71f6931c5b00) ![card-editing-phone-ink.png](https://git.kayg.org/attachments/86791f95-60ca-4486-b8e2-b8ae9d49790b) ![pill-desktop-ink.png](https://git.kayg.org/attachments/070d1b5e-b30a-4654-bd45-aefa90e1e38b) ![pill-desktop-paper.png](https://git.kayg.org/attachments/24e566ab-4eff-463b-9451-4654ea040dad) ![pill-phone-ink.png](https://git.kayg.org/attachments/928fece6-5621-4f03-9cae-8869757c745a) ![refused-duplicate-desktop-ink.png](https://git.kayg.org/attachments/211e29ea-03f5-43c7-a0f3-73b55d2d7ff6) ![tree-editing-desktop-ink.png](https://git.kayg.org/attachments/7c347412-67de-45a6-898d-9d189963a050) ![tree-editing-phone-ink.png](https://git.kayg.org/attachments/36efbefe-bcb0-4089-b965-9283951636bc) **Checks.** bun unit tests mesh: 44 pass; palette-actions pass alone. Browser: sidebar-foot-pin, mesh-rename (10), inbox, mesh.spec, sessions-canvas, core-screen: 101 pass, 3 fail: core-screen:151 and sessions-canvas:330 fail identically on a clean origin/dev checkout; core-screen:254 timed out under 2 workers and passes alone on my branch. scripts/verify iterate (arm64): fmt/clippy/CLI compile-out/artifact gate PASS; Rust test FAIL in infraternal-plugin-ssh --test install (interrupted_rollback_never_deletes_already_restored_state_on_retry, streaming::decoded_image_and_hash_advance_before_the_transfer_tail_is_released), cargo-deny not installed: no Rust file changed. x86 verify fast left to the orchestrator. Known: bun test src/canvas run together shows 4 matchMedia "readonly property" errors, same on baseline. **Bundle (gzip, concatenated js+css+html of apps/tracer/dist):** 489024 -> 491855 B, +2831 B.
Author
Owner

Test sub-agent start (J17). Branch sidebar-pill-259 @ e8c969d00, rebasing onto origin/dev @ 42ab33035. Plan: rebase (keep the 9 commits atomic), production web build on infraternal-dev-01-compute01, screenshots (1690x1000, 1440x900 DPR 2, 393x852 DPR 3: pill before/after scroll, double-tap rename), bundle delta, x86 scripts/verify fast.

Test sub-agent start (J17). Branch `sidebar-pill-259` @ e8c969d00, rebasing onto origin/dev @ 42ab33035. Plan: rebase (keep the 9 commits atomic), production web build on infraternal-dev-01-compute01, screenshots (1690x1000, 1440x900 DPR 2, 393x852 DPR 3: pill before/after scroll, double-tap rename), bundle delta, x86 `scripts/verify fast`.
Author
Owner

Test sub-agent (J17) interim report. Branch sidebar-pill-259 rebased onto origin/dev @ 42ab33035 (clean, no conflicts; dev moved by 3 commits, none in the touched files). New head d7b6999096 (9 commits, same order and messages), pushed with --force-with-lease. The old head e8c969d00 is replaced.

Screenshots are from a production build (bun run build.ts, served through the test latency proxy, mock Mesh with ?mock=1&proto=clusters), headless Chromium 151 via nix on infraternal-dev-02-std (arm64): the x86 box was down at the time and the screenshots do not depend on the CPU. Ink theme. The pill is shown in the state that used to break it: the inbox card has come and gone. Not judged by me; for the orchestrator and owner to review.

Pill gap to the panel bottom (px, sidebar bottom edge minus pill bottom edge), measured at four moments per size: before scroll, tree scrolled to the end, back at the top, after 3 s idle:

size before after scroll back idle tree scroll range
1690x1000, DPR 2 9 9 9 9 none: the whole tree fits, so scrolling is a no-op here
1440x900, DPR 2 9 9 9 9 19 px
393x852, DPR 3 9 9 9 9 609 px

Things I noticed (not fixed, for the orchestrator to judge):

  1. At 1690x1000 the Views tree is shorter than the panel, so there is no real "after scroll" there. The two shots are the same picture on purpose. The drift the owner saw is covered by sidebar-foot-pin.spec.ts (1773x2000).
  2. The first phone capture had the toast "Host connections unlocked" sitting over the pill; the toast is the shared one in its standard place. I waited it out in the final captures.
  3. Phone, double-tap on the Mesh card: the green status dot sits on top of the last letter of the selected name inside the field (rename-phone393-2-card-editing.png). It reads as a slight overlap; the desktop field does not show it.

Pill, before / after a scroll / back at top and idle
1690x1000 DPR 2: pill-d1690-1-before-scroll.png pill-d1690-2-after-scroll.png pill-d1690-3-back-and-idle.png

1440x900 DPR 2: pill-d1440-1-before-scroll.png pill-d1440-2-after-scroll.png pill-d1440-3-back-and-idle.png

393x852 DPR 3: pill-phone393-1-before-scroll.png pill-phone393-2-after-scroll.png pill-phone393-3-back-and-idle.png

Double-click / double-tap rename (1: card before, 2: field open, 3: card saved as build-09; 4: Views tree before, 5: field open on nix-cache, 6: saved as nix-store)

1690x1000 DPR 2 (double click):
rename-d1690-1-card-before.png rename-d1690-2-card-editing.png rename-d1690-3-card-saved.png rename-d1690-4-tree-before.png rename-d1690-5-tree-editing.png rename-d1690-6-tree-saved.png

1440x900 DPR 2 (double click):
rename-d1440-1-card-before.png rename-d1440-2-card-editing.png rename-d1440-3-card-saved.png rename-d1440-4-tree-before.png rename-d1440-5-tree-editing.png rename-d1440-6-tree-saved.png

393x852 DPR 3 (double tap):
rename-phone393-1-card-before.png rename-phone393-2-card-editing.png rename-phone393-3-card-saved.png rename-phone393-4-tree-before.png rename-phone393-5-tree-editing.png rename-phone393-6-tree-saved.png

Bundle (gzip -9 of all js+css+html under dist, concatenated; origin/dev 42ab33035 vs head d7b699909; same bun.lock):

build origin/dev head delta
production (no preview flag) 489777 B 491916 B +2139 B
with INFRATERNAL_CLUSTERS_PREVIEW=1 529772 B 532896 B +3124 B
main.js alone: 38208 -> 38211 B gzip (+3 B): the rename code is in lazy chunks. Under 16 KiB (D243): fine.

x86 scripts/verify fast on compute01 (head d7b699909), run 1 (50 min):

| fmt                       | PASS         |
| VT native fmt             | PASS         |
| CLI plugin compile-out    | PASS         |
| clippy                    | PASS         |
| SSH runtime test helper   | PASS         |
| real-binary fixture paths | PASS         |
| test                      | FAIL (101)   |
| SSH inode reuse fixture   | PASS         |
| shim process-per-user     | PASS         |
| cargo-deny                | PASS         |
| static builds             | PASS         |

The one failure is infraternal --test replay_size_review: ValueError: test state path is too long for an AF_UNIX socket after fallback: 108 bytes (scripts/agent_fixture.py:67). The fixture's socket path is $HOME/.cache/codex-scratch/infraternal/rr257<pid>/sessions/<32 chars>.upstream = 102 bytes + the pid, and the limit is < 108, so it fails for user claude whenever the test process pid has 6 digits (compute01's pids passed 100000 after its busy hours). This branch changes no file under crates/, scripts/ or Cargo.*. Re-running the full gate with INFRATERNAL_AGENT_TEST_STATE_ROOT=/tmp/j17st (the fixture's own documented override); it is queued behind other jobs' build slots, and I will post its output verbatim.

Test sub-agent (J17) interim report. Branch `sidebar-pill-259` rebased onto origin/dev @ 42ab33035 (clean, no conflicts; dev moved by 3 commits, none in the touched files). New head **d7b6999096e48d26534ecca5d5cb001e41045f17** (9 commits, same order and messages), pushed with `--force-with-lease`. The old head e8c969d00 is replaced. **Screenshots** are from a production build (`bun run build.ts`, served through the test latency proxy, mock Mesh with `?mock=1&proto=clusters`), headless Chromium 151 via nix on infraternal-dev-02-std (arm64): the x86 box was down at the time and the screenshots do not depend on the CPU. Ink theme. The pill is shown in the state that used to break it: the inbox card has come and gone. Not judged by me; for the orchestrator and owner to review. **Pill gap to the panel bottom** (px, sidebar bottom edge minus pill bottom edge), measured at four moments per size: before scroll, tree scrolled to the end, back at the top, after 3 s idle: | size | before | after scroll | back | idle | tree scroll range | |---|---|---|---|---|---| | 1690x1000, DPR 2 | 9 | 9 | 9 | 9 | none: the whole tree fits, so scrolling is a no-op here | | 1440x900, DPR 2 | 9 | 9 | 9 | 9 | 19 px | | 393x852, DPR 3 | 9 | 9 | 9 | 9 | 609 px | **Things I noticed (not fixed, for the orchestrator to judge):** 1. At 1690x1000 the Views tree is shorter than the panel, so there is no real "after scroll" there. The two shots are the same picture on purpose. The drift the owner saw is covered by `sidebar-foot-pin.spec.ts` (1773x2000). 2. The first phone capture had the toast "Host connections unlocked" sitting over the pill; the toast is the shared one in its standard place. I waited it out in the final captures. 3. Phone, double-tap on the Mesh card: the green status dot sits on top of the last letter of the selected name inside the field (`rename-phone393-2-card-editing.png`). It reads as a slight overlap; the desktop field does not show it. **Pill, before / after a scroll / back at top and idle** 1690x1000 DPR 2: ![pill-d1690-1-before-scroll.png](https://git.kayg.org/attachments/445d97a9-c4ed-4172-9e8f-2e45af7ac858) ![pill-d1690-2-after-scroll.png](https://git.kayg.org/attachments/33467db5-5922-4a3a-b5b6-d068e9a0a26d) ![pill-d1690-3-back-and-idle.png](https://git.kayg.org/attachments/51397e2a-8aff-4db1-b777-f91405009c9e) 1440x900 DPR 2: ![pill-d1440-1-before-scroll.png](https://git.kayg.org/attachments/86dbe7f1-d58c-45e0-8816-27acdfafb698) ![pill-d1440-2-after-scroll.png](https://git.kayg.org/attachments/f176ea65-f6b9-4aa8-80f2-e2804d4a7a29) ![pill-d1440-3-back-and-idle.png](https://git.kayg.org/attachments/4ece8273-bc89-45f6-ac71-35d77aa558a5) 393x852 DPR 3: ![pill-phone393-1-before-scroll.png](https://git.kayg.org/attachments/0cef50b1-224c-4726-b046-eb7c3450253a) ![pill-phone393-2-after-scroll.png](https://git.kayg.org/attachments/0f8c770d-0fff-45ce-8d13-334808b9b97a) ![pill-phone393-3-back-and-idle.png](https://git.kayg.org/attachments/be610d96-70e8-43d9-a48e-ca5c863b53ba) **Double-click / double-tap rename** (1: card before, 2: field open, 3: card saved as build-09; 4: Views tree before, 5: field open on nix-cache, 6: saved as nix-store) 1690x1000 DPR 2 (double click): ![rename-d1690-1-card-before.png](https://git.kayg.org/attachments/7c983538-cb4a-45d6-b651-958673c4c393) ![rename-d1690-2-card-editing.png](https://git.kayg.org/attachments/69002780-ebf4-470c-86c7-3d5ba5dc7789) ![rename-d1690-3-card-saved.png](https://git.kayg.org/attachments/204485c0-5a98-469d-ab01-43f25c74fbc5) ![rename-d1690-4-tree-before.png](https://git.kayg.org/attachments/6cc393cd-6841-48ba-9232-02503f35f599) ![rename-d1690-5-tree-editing.png](https://git.kayg.org/attachments/b2c1b831-ba9c-4e1e-94e5-6e005a42eaa0) ![rename-d1690-6-tree-saved.png](https://git.kayg.org/attachments/12dcf02a-aa61-4900-ba86-33c72e3809c0) 1440x900 DPR 2 (double click): ![rename-d1440-1-card-before.png](https://git.kayg.org/attachments/a0293fc4-eea8-4882-ba1a-64575595caf6) ![rename-d1440-2-card-editing.png](https://git.kayg.org/attachments/54c4bbb8-7bb1-4bb3-a43c-011fb9d9f624) ![rename-d1440-3-card-saved.png](https://git.kayg.org/attachments/7d771342-38f6-4c80-8cc5-ff40b42df53f) ![rename-d1440-4-tree-before.png](https://git.kayg.org/attachments/55712caa-657a-45c9-bc85-8309f0ababdc) ![rename-d1440-5-tree-editing.png](https://git.kayg.org/attachments/6c615fd4-9a00-430c-9995-51bf81564d1c) ![rename-d1440-6-tree-saved.png](https://git.kayg.org/attachments/a24c3c21-2ba1-4a0e-b549-aeab36565b87) 393x852 DPR 3 (double tap): ![rename-phone393-1-card-before.png](https://git.kayg.org/attachments/bbf292c8-dc69-4198-8c1a-3ad1f5adc300) ![rename-phone393-2-card-editing.png](https://git.kayg.org/attachments/38b4d77f-6e4d-4f37-ab2d-8d4eddefdfb2) ![rename-phone393-3-card-saved.png](https://git.kayg.org/attachments/5fe022a0-fd86-496d-9b23-a9c29861c1c6) ![rename-phone393-4-tree-before.png](https://git.kayg.org/attachments/80e77bd3-b281-4063-aa54-3a72679177a5) ![rename-phone393-5-tree-editing.png](https://git.kayg.org/attachments/d4806e86-1e25-407e-8304-533e7069d29e) ![rename-phone393-6-tree-saved.png](https://git.kayg.org/attachments/90f3bbd6-3273-44d5-abe7-0814508c6851) **Bundle** (gzip -9 of all js+css+html under `dist`, concatenated; origin/dev 42ab33035 vs head d7b699909; same `bun.lock`): | build | origin/dev | head | delta | |---|---|---|---| | production (no preview flag) | 489777 B | 491916 B | **+2139 B** | | with `INFRATERNAL_CLUSTERS_PREVIEW=1` | 529772 B | 532896 B | **+3124 B** | `main.js` alone: 38208 -> 38211 B gzip (+3 B): the rename code is in lazy chunks. Under 16 KiB (D243): fine. **x86 `scripts/verify fast`** on compute01 (head d7b699909), run 1 (50 min): ``` | fmt | PASS | | VT native fmt | PASS | | CLI plugin compile-out | PASS | | clippy | PASS | | SSH runtime test helper | PASS | | real-binary fixture paths | PASS | | test | FAIL (101) | | SSH inode reuse fixture | PASS | | shim process-per-user | PASS | | cargo-deny | PASS | | static builds | PASS | ``` The one failure is `infraternal --test replay_size_review`: `ValueError: test state path is too long for an AF_UNIX socket after fallback: 108 bytes` (scripts/agent_fixture.py:67). The fixture's socket path is `$HOME/.cache/codex-scratch/infraternal/rr257<pid>/sessions/<32 chars>.upstream` = 102 bytes + the pid, and the limit is < 108, so it fails for user `claude` whenever the test process pid has 6 digits (compute01's pids passed 100000 after its busy hours). This branch changes no file under `crates/`, `scripts/` or Cargo.*. Re-running the full gate with `INFRATERNAL_AGENT_TEST_STATE_ROOT=/tmp/j17st` (the fixture's own documented override); it is queued behind other jobs' build slots, and I will post its output verbatim.
Author
Owner

Finish (test sub-agent J17). Branch sidebar-pill-259, head d7b6999096, rebased onto origin/dev @ 42ab33035, pushed (not merged). Screenshots, gap measurements and bundle delta are in the previous comment.

x86 scripts/verify fast is NOT green yet: pending. Verbatim result of run 1 on infraternal-dev-01-compute01 (head d7b699909, real 49m53.007s):

| fmt                       | PASS         |
| VT native fmt             | PASS         |
| CLI plugin compile-out    | PASS         |
| clippy                    | PASS         |
| SSH runtime test helper   | PASS         |
| real-binary fixture paths | PASS         |
| test                      | FAIL (101)   |
| SSH inode reuse fixture   | PASS         |
| shim process-per-user     | PASS         |
| cargo-deny                | PASS         |
| static builds             | PASS         |

Static builds on x86_64-unknown-linux-musl and aarch64-unknown-linux-musl: size delta +0 bytes against the caps (21431472 and 19605896 bytes).

The only failing test is infraternal --test replay_size_review (adopted_raw_and_snapshot_replays_keep_pre_resize_geometry), verbatim:

ValueError: test state path is too long for an AF_UNIX socket after fallback: 108 bytes
  File ".../scripts/agent_fixture.py", line 67, in fixture_state

Cause: fixture_state builds $HOME/.cache/codex-scratch/infraternal/rr257<pid>/sessions/<32 chars>.upstream (102 bytes plus the pid) and rejects >= 108, so for user claude it fails whenever the pid has 6 digits (compute01 passed pid 100000 after its busy hours). This branch changes nothing under crates/, scripts/ or Cargo.* (git diff --name-only origin/dev...HEAD lists only apps/tracer and packages/ui files), so the failure is not from this change. I have not yet run it on unmodified origin/dev, so I am not claiming that as proven.

Re-run: not done. I queued the full gate again with the fixture's documented override INFRATERNAL_AGENT_TEST_STATE_ROOT=/tmp/j17st, but compute01's build slots stayed full (4 of 4) for 80 minutes (18:16 to 19:37 CET), so it never started and I cancelled it rather than leave it running unattended. To finish: in ~/worktrees/j17-sidebar-pill on compute01 run
~/infraternal-ops/build-slot env INFRATERNAL_AGENT_TEST_STATE_ROOT=/tmp/j17st nix develop git+file:///home/claude/infraternal?ref=nix-devshell -c scripts/verify fast
(the other 10 rows already passed; the build cache is warm, so only the test row and the static builds are expensive).

Separate finding for the owner/orchestrator: scripts/agent_fixture.py can fail on any host whose pids have 6 digits and whose home directory is /home/claude; its fallback is the same path, so the "fallback" does not help. A shorter default root (for example under /tmp) would fix it. I did not change it: it is outside this job.

Other facts

  • Correction to what I first wrote here: the gate runs cargo test --workspace --locked without --no-fail-fast, so cargo stopped at the failing replay_size_review binary and every test binary after it did not run in run 1. The x86 test row is therefore incomplete, not "only one failure". The first design pass reported 2 failures in infraternal-plugin-ssh --test install on arm64 (also with no Rust change on this branch); whether they reproduce on x86 is unknown until the re-run gets past this fixture.
  • Screenshot scaffolding (not committed): apps/tracer/test/j17-captures.spec.ts, untracked in ~/worktrees/j17-sidebar-pill on both VMs; run with PLAYWRIGHT_BROWSERS_PATH pointing at a revision shim of the nix browsers (nixpkgs ships Playwright 1.64.1 browsers, the repo pins 1.61.1).
  • Cleanup: my queued gate run was stopped by PID; /tmp/j17st and my /tmp/j17-dist-* builds removed. Worktrees ~/worktrees/j17-sidebar-pill (both VMs) and ~/worktrees/j17-base (dev-02) remain.
Finish (test sub-agent J17). Branch `sidebar-pill-259`, head **d7b6999096e48d26534ecca5d5cb001e41045f17**, rebased onto origin/dev @ 42ab33035, pushed (not merged). Screenshots, gap measurements and bundle delta are in the previous comment. **x86 `scripts/verify fast` is NOT green yet: pending.** Verbatim result of run 1 on infraternal-dev-01-compute01 (head d7b699909, `real 49m53.007s`): ``` | fmt | PASS | | VT native fmt | PASS | | CLI plugin compile-out | PASS | | clippy | PASS | | SSH runtime test helper | PASS | | real-binary fixture paths | PASS | | test | FAIL (101) | | SSH inode reuse fixture | PASS | | shim process-per-user | PASS | | cargo-deny | PASS | | static builds | PASS | ``` Static builds on x86_64-unknown-linux-musl and aarch64-unknown-linux-musl: size delta +0 bytes against the caps (21431472 and 19605896 bytes). The only failing test is `infraternal --test replay_size_review` (adopted_raw_and_snapshot_replays_keep_pre_resize_geometry), verbatim: ``` ValueError: test state path is too long for an AF_UNIX socket after fallback: 108 bytes File ".../scripts/agent_fixture.py", line 67, in fixture_state ``` Cause: `fixture_state` builds `$HOME/.cache/codex-scratch/infraternal/rr257<pid>/sessions/<32 chars>.upstream` (102 bytes plus the pid) and rejects >= 108, so for user `claude` it fails whenever the pid has 6 digits (compute01 passed pid 100000 after its busy hours). This branch changes nothing under `crates/`, `scripts/` or Cargo.* (`git diff --name-only origin/dev...HEAD` lists only apps/tracer and packages/ui files), so the failure is not from this change. I have not yet run it on unmodified origin/dev, so I am not claiming that as proven. **Re-run: not done.** I queued the full gate again with the fixture's documented override `INFRATERNAL_AGENT_TEST_STATE_ROOT=/tmp/j17st`, but compute01's build slots stayed full (4 of 4) for 80 minutes (18:16 to 19:37 CET), so it never started and I cancelled it rather than leave it running unattended. To finish: in `~/worktrees/j17-sidebar-pill` on compute01 run `~/infraternal-ops/build-slot env INFRATERNAL_AGENT_TEST_STATE_ROOT=/tmp/j17st nix develop git+file:///home/claude/infraternal?ref=nix-devshell -c scripts/verify fast` (the other 10 rows already passed; the build cache is warm, so only the test row and the static builds are expensive). **Separate finding for the owner/orchestrator:** `scripts/agent_fixture.py` can fail on any host whose pids have 6 digits and whose home directory is `/home/claude`; its fallback is the same path, so the "fallback" does not help. A shorter default root (for example under `/tmp`) would fix it. I did not change it: it is outside this job. **Other facts** - **Correction to what I first wrote here:** the gate runs `cargo test --workspace --locked` without `--no-fail-fast`, so cargo stopped at the failing `replay_size_review` binary and every test binary after it did not run in run 1. The x86 `test` row is therefore incomplete, not "only one failure". The first design pass reported 2 failures in `infraternal-plugin-ssh --test install` on arm64 (also with no Rust change on this branch); whether they reproduce on x86 is unknown until the re-run gets past this fixture. - Screenshot scaffolding (not committed): `apps/tracer/test/j17-captures.spec.ts`, untracked in `~/worktrees/j17-sidebar-pill` on both VMs; run with `PLAYWRIGHT_BROWSERS_PATH` pointing at a revision shim of the nix browsers (nixpkgs ships Playwright 1.64.1 browsers, the repo pins 1.61.1). - Cleanup: my queued gate run was stopped by PID; `/tmp/j17st` and my `/tmp/j17-dist-*` builds removed. Worktrees `~/worktrees/j17-sidebar-pill` (both VMs) and `~/worktrees/j17-base` (dev-02) remain.
Author
Owner

Test sub-agent (J17b) start. Fixing the rename field sitting under the status dot (found in J17's rename-phone393-2-card-editing.png). Branch sidebar-pill-259 @ d7b6999096 (rebased on origin/dev @ 42ab33035). Plan: failing-first browser spec (field box vs dot/mark/actions boxes at 1440x900 and 393x852, short/usual/long names, card and Views tree), then the fix in placeOverName (packages/ui/src/inline-rename.ts), then before/after captures with J17's spec. Cause so far: the field is max(name + 12, 120) px wide from the name's left edge, so on a card whose name is narrower than 120 px it runs past the name over the dot and into the actions.

Test sub-agent (J17b) start. Fixing the rename field sitting under the status dot (found in J17's `rename-phone393-2-card-editing.png`). Branch `sidebar-pill-259` @ d7b6999096e48d26534ecca5d5cb001e41045f17 (rebased on origin/dev @ 42ab33035). Plan: failing-first browser spec (field box vs dot/mark/actions boxes at 1440x900 and 393x852, short/usual/long names, card and Views tree), then the fix in `placeOverName` (`packages/ui/src/inline-rename.ts`), then before/after captures with J17's spec. Cause so far: the field is `max(name + 12, 120)` px wide from the name's left edge, so on a card whose name is narrower than 120 px it runs past the name over the dot and into the actions.
Author
Owner

Finish (test sub-agent J17b). Branch sidebar-pill-259, head 86f494e7d6 (J17's 9 commits + 2), pushed, not merged. Base unchanged: origin/dev @ 42ab33035. I did NOT run the full scripts/verify fast (queued separately, as ordered); gate for this change below.

Bug (J17's finding 3): at 393x852 the green status dot sat over the last letter of the name in the open rename field. Cause: placeOverName made the field max(name + 12, 120) px wide from the name's left edge, so for any name narrower than 120 px the field ran past the name, over the dot and into the header action. Measured on the old code: the field's right edge was 25 px past the pill's, at both 1440x900 (748 vs 722.4) and 393x852 (279 vs 253.4).

Commits

  • f4f4ca3ea test: the rename field must not sit under the status dot (#259). Written first; it fails on the previous head (output above: "field ends inside the pill", Expected <= 722.42 / <= 253.42, Received 748 / 279). At 1440x900 (double click) and 393x852 DPR 3 (double tap), for a usual name (build-01), a 36-character name and a two-letter name, it asserts the field's box shares no area with the machine mark, the status dot, the session name or the header actions, stays inside the pill, and that every name that fits opens whole (no scrolling before typing). It also checks the Views tree row at both sizes.
  • 86f494e7d ui: the inline rename field stays inside the name's own box (#259). packages/ui/src/inline-rename.ts only (+40/-5). The field never reaches past the name's box by more than its 4 px padding, so it cannot cover what the surface draws a gap after the name (mark, dot, note, actions). The dot stays shown and in place: nothing is hidden. Two cases need more: a name narrower than its own text in the field (a two-letter host; a phone, where the field is 16 px against the name's smaller type) has its hidden box widened to the field's measured text width (at least 72 px), so the pill grows a few px and its neighbours follow, never covered; a long, ellipsized name makes the field stop where the nearest clipping ancestor stops, so it never leaves the pill (it scrolls its text like any field). Rejected alternatives are in the commit message (hiding the dot, a fixed width, a constant widening: the last one is what the spec caught on the long name).
  • The tree's field goes through the same helper; its rows carry no mark or note for Mesh hosts, and the spec confirms the field stays inside its row and clear of any mark or note.

Gate (dev-02-std aarch64, through build-slot; browser = nix chromium 151 via J17's playwright shim)

  • bun x tsc --project tsconfig.json (apps/tracer): EXIT=0.
  • Before the fix, test/mesh-rename.spec.ts -g status.dot: 2 failed (the two new tests).
  • After the fix, whole test/mesh-rename.spec.ts: 12 passed (1.5m), EXIT=0. And together with J17's capture spec: 18 passed (2.9m), EXIT=0.
  • Logs on dev-02-std: ~/j17b-logs/{fail2,pass4,pass6,tsc}.log; screenshots ~/j17b-evidence/.

Screenshots (production build, ink theme, headless Chromium; not judged by me). Attached to this comment: before-rename-phone393-2-card-editing.png / after-rename-phone393-2-card-editing.png (the dot is clear in the "after"; the pill is a few px wider and the action button moved right by the same amount), before-rename-d1440-2-card-editing.png / after-rename-d1440-2-card-editing.png, after-rename-phone393-5-tree-editing.png, after-rename-d1440-5-tree-editing.png, and the new cases field-clear-{1440x900,393x852}-{usual,short,long}-name.png.

For the owner/orchestrator to judge: (1) with a two-letter name the pill grows to hold a 72 px field, so a card's pill visibly widens while renaming (the empty part of the field shows as the tinted box); the alternative is a field the width of the name. (2) A long name shows its start (selected) truncated by the pill, not the whole name; nothing is covered. (3) I did not add the new cases to the tree's long names: the tree rows are far wider than any Mesh name.

Cleanup: no processes of mine left; the VM worktree ~/worktrees/j17-sidebar-pill holds the same tree as the branch plus J17's untracked capture spec; no Rust target was built.

Finish (test sub-agent J17b). Branch `sidebar-pill-259`, head **86f494e7d6dcb3ff2352e41108fe2461f3169502** (J17's 9 commits + 2), pushed, not merged. Base unchanged: origin/dev @ 42ab33035. I did NOT run the full `scripts/verify fast` (queued separately, as ordered); gate for this change below. **Bug (J17's finding 3):** at 393x852 the green status dot sat over the last letter of the name in the open rename field. Cause: `placeOverName` made the field `max(name + 12, 120)` px wide from the name's left edge, so for any name narrower than 120 px the field ran past the name, over the dot and into the header action. Measured on the old code: the field's right edge was 25 px past the pill's, at both 1440x900 (748 vs 722.4) and 393x852 (279 vs 253.4). **Commits** - `f4f4ca3ea` test: the rename field must not sit under the status dot (#259). Written first; it fails on the previous head (output above: "field ends inside the pill", Expected <= 722.42 / <= 253.42, Received 748 / 279). At 1440x900 (double click) and 393x852 DPR 3 (double tap), for a usual name (build-01), a 36-character name and a two-letter name, it asserts the field's box shares no area with the machine mark, the status dot, the session name or the header actions, stays inside the pill, and that every name that fits opens whole (no scrolling before typing). It also checks the Views tree row at both sizes. - `86f494e7d` ui: the inline rename field stays inside the name's own box (#259). `packages/ui/src/inline-rename.ts` only (+40/-5). The field never reaches past the name's box by more than its 4 px padding, so it cannot cover what the surface draws a gap after the name (mark, dot, note, actions). The dot stays shown and in place: nothing is hidden. Two cases need more: a name narrower than its own text in the field (a two-letter host; a phone, where the field is 16 px against the name's smaller type) has its hidden box widened to the field's measured text width (at least 72 px), so the pill grows a few px and its neighbours follow, never covered; a long, ellipsized name makes the field stop where the nearest clipping ancestor stops, so it never leaves the pill (it scrolls its text like any field). Rejected alternatives are in the commit message (hiding the dot, a fixed width, a constant widening: the last one is what the spec caught on the long name). - The tree's field goes through the same helper; its rows carry no mark or note for Mesh hosts, and the spec confirms the field stays inside its row and clear of any mark or note. **Gate (dev-02-std aarch64, through build-slot; browser = nix chromium 151 via J17's playwright shim)** - `bun x tsc --project tsconfig.json` (apps/tracer): `EXIT=0`. - Before the fix, `test/mesh-rename.spec.ts -g status.dot`: `2 failed` (the two new tests). - After the fix, whole `test/mesh-rename.spec.ts`: `12 passed (1.5m)`, `EXIT=0`. And together with J17's capture spec: `18 passed (2.9m)`, `EXIT=0`. - Logs on dev-02-std: `~/j17b-logs/{fail2,pass4,pass6,tsc}.log`; screenshots `~/j17b-evidence/`. **Screenshots** (production build, ink theme, headless Chromium; not judged by me). Attached to this comment: `before-rename-phone393-2-card-editing.png` / `after-rename-phone393-2-card-editing.png` (the dot is clear in the "after"; the pill is a few px wider and the action button moved right by the same amount), `before-rename-d1440-2-card-editing.png` / `after-rename-d1440-2-card-editing.png`, `after-rename-phone393-5-tree-editing.png`, `after-rename-d1440-5-tree-editing.png`, and the new cases `field-clear-{1440x900,393x852}-{usual,short,long}-name.png`. **For the owner/orchestrator to judge:** (1) with a two-letter name the pill grows to hold a 72 px field, so a card's pill visibly widens while renaming (the empty part of the field shows as the tinted box); the alternative is a field the width of the name. (2) A long name shows its start (selected) truncated by the pill, not the whole name; nothing is covered. (3) I did not add the new cases to the tree's long names: the tree rows are far wider than any Mesh name. Cleanup: no processes of mine left; the VM worktree `~/worktrees/j17-sidebar-pill` holds the same tree as the branch plus J17's untracked capture spec; no Rust target was built.
Author
Owner

Design sub-agent (J54) start. Owner review feedback of 2026-11-01 (rename pill overlapping the → pill, "detached" as an icon, what ✓/✗ mean, a live preview). Branch sidebar-pill-259 rebased onto origin/dev @ f4b61cd6c (11 commits, clean), new head 9fe1b7041 before my changes (old head 86f494e7d). Not pushed yet.

Plan: (1) failing-first spec for the → pill (and every neighbour) at 1440x900 and 393x852, then fix; (2) the sidebar's "detached" text becomes an icon with a tooltip "Detached"; (3) explain ✓/✗ from the code; (4) a live production-build preview on infraternal-dev-02-std (10.69.69.117); (5) screenshots and a short video at both sizes.

First reading of the owner's screenshot (it is from the first head, e8c969d00): the tinted field runs from the name to past the pill's right edge and sits under the → circle. J17b's fix narrowed the field to the name, but a short name grows the pill by up to 72px and I have to check on the current head that the → circle really moves with it and never overlaps. That is what the new spec measures.

Design sub-agent (J54) start. Owner review feedback of 2026-11-01 (rename pill overlapping the → pill, "detached" as an icon, what ✓/✗ mean, a live preview). Branch `sidebar-pill-259` rebased onto origin/dev @ f4b61cd6c (11 commits, clean), new head 9fe1b7041 before my changes (old head 86f494e7d). Not pushed yet. Plan: (1) failing-first spec for the → pill (and every neighbour) at 1440x900 and 393x852, then fix; (2) the sidebar's "detached" text becomes an icon with a tooltip "Detached"; (3) explain ✓/✗ from the code; (4) a live production-build preview on infraternal-dev-02-std (10.69.69.117); (5) screenshots and a short video at both sizes. First reading of the owner's screenshot (it is from the first head, e8c969d00): the tinted field runs from the name to past the pill's right edge and sits under the → circle. J17b's fix narrowed the field to the name, but a short name grows the pill by up to 72px and I have to check on the current head that the → circle really moves with it and never overlaps. That is what the new spec measures.
Author
Owner

Design sub-agent (J54) progress. Branch sidebar-pill-259 rebased onto origin/dev @ f4b61cd6c, pushed (force-with-lease; old head 86f494e7d replaced).

1. The rename pill and the → pill. The owner's screenshot is from the first head (e8c969d00): the tinted field ran from the name to past the pill's right edge, under the round → connector. J17b's fix already narrowed the field to the name's box, and a short name's pill widens by a few px with the → pill following. I did not take that on trust: the old spec only compared the field with the → button inside the actions pill, but on a Mesh card the → is its own button (.cl-port), so nothing compared the field or the widened name pill with it. The spec now does (field, name pill, → pill; none share area, the → pill starts after the name pill and stays inside the card) at 1440x900 and 393x852 for a usual, a 36-character and a two-letter name. Failing-first: on the code before J17b it fails ("field ends inside the pill", expected <= 253.42, received 279 at 393x852; 748 vs 722.42 at 1440x900), i.e. the field ended 18 px past where the → pill starts (pill right 253 + 8 gap = 261). On the current head it passes, so there is no further code change needed for this: the → pill moves aside by itself. Measured live on the production build with a two-letter name: gap pill→ pill is 6 px at both sizes, the field ends before the → pill.

2. "Detached" is now an icon (commit "sidebar: a detached session shows an icon, not the word"). Failing spec first, then the change. Small chain-with-a-gap icon in the right-hand slot, 16 px (18 on touch), 1.5 stroke, role=img, accessible label and warm tooltip "Detached". The hollow dot stays. The palette hint and a window's label still use the word (search text, window header).

3. Ticks and crosses. Plain-words explanation and a proposal are in the final report below; code: session-tree.on-demand.ts, branched.ts, .ui-mark in packages/ui/styles.css. They had no tooltip (TASTE: no icon without a tooltip), so they now have one in plain words ("Finished successfully", "Failed", "New output"; on exited rows with the exit code). Semantics unchanged. A review flag ?marks=words (preview builds only) shows the alternative treatment live.

4. Live preview and screenshots/videos follow in the next comment.

Design sub-agent (J54) progress. Branch `sidebar-pill-259` rebased onto origin/dev @ f4b61cd6c, pushed (force-with-lease; old head 86f494e7d replaced). **1. The rename pill and the → pill.** The owner's screenshot is from the first head (e8c969d00): the tinted field ran from the name to past the pill's right edge, under the round → connector. J17b's fix already narrowed the field to the name's box, and a short name's pill widens by a few px with the → pill following. I did not take that on trust: the old spec only compared the field with the → *button inside the actions pill*, but on a Mesh card the → is its own button (`.cl-port`), so nothing compared the field or the widened name pill with it. The spec now does (field, name pill, → pill; none share area, the → pill starts after the name pill and stays inside the card) at 1440x900 and 393x852 for a usual, a 36-character and a two-letter name. Failing-first: on the code before J17b it fails ("field ends inside the pill", expected <= 253.42, received 279 at 393x852; 748 vs 722.42 at 1440x900), i.e. the field ended 18 px past where the → pill starts (pill right 253 + 8 gap = 261). On the current head it passes, so there is no further code change needed for this: the → pill moves aside by itself. Measured live on the production build with a two-letter name: gap pill→ pill is 6 px at both sizes, the field ends before the → pill. **2. "Detached" is now an icon** (commit "sidebar: a detached session shows an icon, not the word"). Failing spec first, then the change. Small chain-with-a-gap icon in the right-hand slot, 16 px (18 on touch), 1.5 stroke, `role=img`, accessible label and warm tooltip "Detached". The hollow dot stays. The palette hint and a window's label still use the word (search text, window header). **3. Ticks and crosses.** Plain-words explanation and a proposal are in the final report below; code: `session-tree.on-demand.ts`, `branched.ts`, `.ui-mark` in packages/ui/styles.css. They had no tooltip (TASTE: no icon without a tooltip), so they now have one in plain words ("Finished successfully", "Failed", "New output"; on exited rows with the exit code). Semantics unchanged. A review flag `?marks=words` (preview builds only) shows the alternative treatment live. **4. Live preview** and screenshots/videos follow in the next comment.
Author
Owner

Design sub-agent (J54) finish. Branch sidebar-pill-259, head 66d25769da, rebased onto origin/dev @ f4b61cd6c, pushed (not merged).

Live preview for the owner

http://10.69.69.117:47654/?mock=1&proto=clusters&scene=6&theme=ink&bg=none (production web build of this head, mock server, on infraternal-dev-02-std, mesh address only; signed in as the mock owner automatically; reload resets the mock).

What to try (it is a real build, so scroll and double-click for yourself):

  1. Rename. The page opens on the Mesh view. Double-click (phone: double-tap) build-01's name on its card. Type a very short name such as db, Enter, then double-click db again: the name pill grows a few pixels and the round → button moves right with it, never under it. Escape cancels.
  2. Sidebar scroll, pill stays put. Open the sidebar, scroll the list: the account pill at the bottom stays 9 px from the panel's bottom edge (measured on every frame: min 9, max 9). Long list: add &mesh=40 and use the Mesh view (http://10.69.69.117:47654/?mock=1&proto=clusters&scene=6&mesh=40&theme=ink&bg=none); on a desktop window 900 px tall the list barely overflows, so shrink the browser window to ~560 px high or open it on a phone.
  3. Detached icon + what the ticks mean. http://10.69.69.117:47654/?mock=1&proto=clusters&scene=3&sessions=2&theme=ink&bg=none, open the sidebar, look at Console. Hover (long-press on a phone) the little chain icon, the ✓, the ✗ and the dot: each has a tooltip.
  4. Mockup of a clearer ✓/✗ treatment: the same URL with &marks=words (exited rows read "finished" / "failed · 1" instead of "0" / "1").

What the ticks and crosses mean (read from the code)

They appear only on session rows under Console in the sidebar (session-tree.on-demand.ts, drawn by .ui-mark):

  • On an exited session (hollow square; its command ended): ✓ and the number 0 = it ended normally (exit code 0); ✗ and 1 (or any other number) = it ended with an error, the number is the program's exit code.
  • On a detached session (hollow circle: still running, no window showing it): ✓ = a command in it finished fine while you were not looking; ✗ = a command in it failed; a blue dot = it printed new output.
  • The chain icon at the right of a detached row is the "Detached" note that used to be the word.
    They were unclear because the picture, the bare number and the shape of the dot each carried a bit of the meaning and none had a tooltip. Semantics are unchanged. What I changed for real: every one now has a warm tooltip in plain words ("Finished successfully", "Failed", "New output"; on exited rows "Failed, exit code 1"). What I propose as a mockup (needs your yes, D162): exited rows say "finished" / "failed · 1" in words (flag &marks=words), screenshots below. If you prefer, we could also drop the number and keep only ✓/✗.

Fixes

  1. Rename vs the → pill. Your screenshot is from the first head (e8c969d00). J17b had already limited the field to the name's box; what was missing was a check against the → button itself (on a Mesh card it is its own button, .cl-port, not part of the header actions, so the old spec never compared with it). The spec now checks field, widened name pill and → button at 1440x900 and 393x852 for a usual, a 36-character and a two-letter name. Failing-first on the pre-fix code: "field ends inside the pill", 279 > 253.42 at 393x852 and 748 > 722.42 at 1440x900 (the → button starts at 261 / 730). On this head it passes. Measured live with db: gap name pill → → button 6 px at both sizes, field ends before it.
  2. "Detached" is an icon, accessible label and tooltip "Detached", reusing the shared icon set (new ICON_DETACHED in packages/ui/src/icons.ts, drawn by the shared icon()); TASTE rows "Icons over text", "no icon without a tooltip".

Commits (new ones on top of J17/J17b)

  • 85cb920ee test: the rename field and the widened name pill never overlap the → pill
  • 648cc7774 test: a detached session ... shows an icon (fails first)
  • 44b3256f1 sidebar: a detached session shows an icon, not the word
  • e60f12434 test: tick, cross and dot explain themselves in a tooltip (fails first)
  • 66d25769d sidebar: the tick, cross and dot get a tooltip in plain words (+ ?marks=words review flag, preview builds only)

Gate (dev-02-std aarch64, no Rust file changed on this branch)

  • Browser: test/mesh-rename.spec.ts, test/sessions-canvas.spec.ts, test/sidebar-foot-pin.spec.ts (head 66d25769d): 37 passed, 1 failed, 3 skipped (opt-in capture tests that only run with their env flags). The one failure, sessions-canvas.spec.ts:370 another device typed last… (.cl-sx-badge expected 0, received 1), fails identically on unmodified origin/dev f4b61cd6c (line 330 there): not from this branch.
  • Typecheck + unit tests of the "Tracer compiler, precompression and bundle transfer budget" row of scripts/verify fast (line read from the script): tsc clean, bun tests 368 + 105 + 17 pass, 0 fail, then it fails on the JavaScript transfer budget (D188), critical class:
JavaScript transfer, critical: identity=992041 gzip=307714/307200 brotli=256408/256000 bytes
error: production critical-path JavaScript exceeds the compressed transfer budget

origin/dev f4b61cd6c measures gzip=306074 brotli=254929 (passes). At 85cb920ee, i.e. before any of my code changes, it is already gzip=307556 brotli=256213: the rename work of J17/J17b adds +1482 B gzip to the critical path (J17's "main.js +3 B" looked at the wrong chunk). My icon and tooltips add +158 B gzip / +195 B brotli. So the branch does not pass the transfer gate. I did not raise the cap (owner's call) and did not move the rename code into an on-demand chunk: on an iPhone the field must be focused inside the double-tap's gesture for the keyboard to open, so a lazy chunk needs a preload-on-first-touch design of its own. Needs a decision: raise the critical cap by about 1.2 KiB (D188), or a follow-up job to make beginInlineRename/placeOverName on-demand with a preload.

  • Full scripts/verify fast (Rust rows, static builds) NOT run by me: the VM had 11 GB free (the 25 GB build-slot floor never opens; now 43 GB after another job cleaned up) and the change is web-only. The orchestrator's separate x86 run of the J17 head still stands; this head changes only apps/tracer and packages/ui.

Screenshots (production build, ink, headless Chromium; not judged by me)

Rename, desktop 1440x900 DPR 2: d1440-rename-1-before.png d1440-rename-2-editing-usual-name.png d1440-rename-3-saved-short-name.png d1440-rename-4-editing-short-name.png

Rename, phone 393x852 DPR 3: phone393-rename-1-before.png phone393-rename-2-editing-usual-name.png phone393-rename-3-saved-short-name.png phone393-rename-4-editing-short-name.png

Pill before / scrolled to end / back, phone (tree scrolls 341 px): phone393-pill-1-before-scroll.png phone393-pill-2-scrolled-to-end.png phone393-pill-3-back-at-top.png

Pill, desktop 1440x560 (tree scrolls 187 px; at 1440x900 it fits whole): d1440short560-pill-1-before-scroll.png d1440short560-pill-2-scrolled-to-end.png d1440short560-pill-3-back-at-top.png

Pill, desktop 1440x900 (no overflow, for completeness): d1440-pill-2-scrolled-to-end.png

Detached icon and tooltips, desktop: d1440-sessions-1-detached-icon.png d1440-sessions-2-detached-tooltip.png d1440-sessions-3-cross-tooltip.png

Detached icon, phone: phone393-sessions-1-detached-icon.png

Mockup &marks=words: phone393-marks-words.png d1440-marks-words.png

Videos (frames of the real page, about 28 fps; the browser's own video encoder produced nothing in this nix build, so they are stitched screenshots): 1440x900 rename and scroll, 393x852, 1440x560 with a scrolling list.

Numbers per frame while scrolling (pill gap to the panel bottom, min / max over the scroll): phone 9.00 / 9.00, 1440x560 9.00 / 9.00 (and back), idle 9.00.

Cleanup / left running

  • The live preview server is left running on purpose: PID in ~/j54-logs/preview.pid on infraternal-dev-02-std (bun mock-server, port 47654, bound to 10.69.69.117). Stop it by PID when the owner is done. Rebuild: ~/j54-logs/preview-build.sh then ~/j54-logs/preview-serve.sh in worktree ~/worktrees/j54-preview (the mock server there carries the orchestrator's uncommitted bind/always-auth patch, ~/j54-logs/preview-bind.patch).
  • Worktrees ~/worktrees/j54 and j54-preview remain; logs ~/j54-logs/, evidence ~/j54-evidence/j54/. No Rust target built. The Playwright runs did not go through build-slot (its disk floor was not met); each ran one worker at nice 10.
Design sub-agent (J54) finish. Branch `sidebar-pill-259`, head **66d25769dad836eb5cd445bb53926d1919d051ae**, rebased onto origin/dev @ f4b61cd6c, pushed (not merged). ## Live preview for the owner **http://10.69.69.117:47654/?mock=1&proto=clusters&scene=6&theme=ink&bg=none** (production web build of this head, mock server, on infraternal-dev-02-std, mesh address only; signed in as the mock owner automatically; reload resets the mock). What to try (it is a real build, so scroll and double-click for yourself): 1. **Rename.** The page opens on the Mesh view. Double-click (phone: double-tap) `build-01`'s name on its card. Type a very short name such as `db`, Enter, then double-click `db` again: the name pill grows a few pixels and the round → button moves right with it, never under it. Escape cancels. 2. **Sidebar scroll, pill stays put.** Open the sidebar, scroll the list: the account pill at the bottom stays 9 px from the panel's bottom edge (measured on every frame: min 9, max 9). Long list: add `&mesh=40` and use the **Mesh view** (`http://10.69.69.117:47654/?mock=1&proto=clusters&scene=6&mesh=40&theme=ink&bg=none`); on a desktop window 900 px tall the list barely overflows, so shrink the browser window to ~560 px high or open it on a phone. 3. **Detached icon + what the ticks mean.** `http://10.69.69.117:47654/?mock=1&proto=clusters&scene=3&sessions=2&theme=ink&bg=none`, open the sidebar, look at Console. Hover (long-press on a phone) the little chain icon, the ✓, the ✗ and the dot: each has a tooltip. 4. **Mockup of a clearer ✓/✗ treatment:** the same URL with `&marks=words` (exited rows read "finished" / "failed · 1" instead of "0" / "1"). ## What the ticks and crosses mean (read from the code) They appear only on **session rows under Console** in the sidebar (`session-tree.on-demand.ts`, drawn by `.ui-mark`): - On an **exited** session (hollow square; its command ended): ✓ and the number **0** = it ended normally (exit code 0); ✗ and **1** (or any other number) = it ended with an error, the number is the program's exit code. - On a **detached** session (hollow circle: still running, no window showing it): ✓ = a command in it finished fine while you were not looking; ✗ = a command in it failed; a blue dot = it printed new output. - The chain icon at the right of a detached row is the "Detached" note that used to be the word. They were unclear because the picture, the bare number and the shape of the dot each carried a bit of the meaning and none had a tooltip. Semantics are **unchanged**. What I changed for real: every one now has a warm tooltip in plain words ("Finished successfully", "Failed", "New output"; on exited rows "Failed, exit code 1"). What I propose as a mockup (needs your yes, D162): exited rows say "finished" / "failed · 1" in words (flag `&marks=words`), screenshots below. If you prefer, we could also drop the number and keep only ✓/✗. ## Fixes 1. **Rename vs the → pill.** Your screenshot is from the first head (e8c969d00). J17b had already limited the field to the name's box; what was missing was a check against the → button itself (on a Mesh card it is its own button, `.cl-port`, not part of the header actions, so the old spec never compared with it). The spec now checks field, widened name pill and → button at 1440x900 and 393x852 for a usual, a 36-character and a two-letter name. Failing-first on the pre-fix code: "field ends inside the pill", 279 > 253.42 at 393x852 and 748 > 722.42 at 1440x900 (the → button starts at 261 / 730). On this head it passes. Measured live with `db`: gap name pill → → button 6 px at both sizes, field ends before it. 2. **"Detached" is an icon**, accessible label and tooltip "Detached", reusing the shared icon set (new `ICON_DETACHED` in packages/ui/src/icons.ts, drawn by the shared `icon()`); TASTE rows "Icons over text", "no icon without a tooltip". ## Commits (new ones on top of J17/J17b) - 85cb920ee test: the rename field and the widened name pill never overlap the → pill - 648cc7774 test: a detached session ... shows an icon (fails first) - 44b3256f1 sidebar: a detached session shows an icon, not the word - e60f12434 test: tick, cross and dot explain themselves in a tooltip (fails first) - 66d25769d sidebar: the tick, cross and dot get a tooltip in plain words (+ `?marks=words` review flag, preview builds only) ## Gate (dev-02-std aarch64, no Rust file changed on this branch) - Browser: `test/mesh-rename.spec.ts`, `test/sessions-canvas.spec.ts`, `test/sidebar-foot-pin.spec.ts` (head 66d25769d): **37 passed, 1 failed, 3 skipped (opt-in capture tests that only run with their env flags)**. The one failure, `sessions-canvas.spec.ts:370 another device typed last…` (`.cl-sx-badge` expected 0, received 1), **fails identically on unmodified origin/dev f4b61cd6c** (line 330 there): not from this branch. - Typecheck + unit tests of the "Tracer compiler, precompression and bundle transfer budget" row of `scripts/verify fast` (line read from the script): tsc clean, bun tests 368 + 105 + 17 pass, 0 fail, **then it fails on the JavaScript transfer budget (D188), critical class**: ``` JavaScript transfer, critical: identity=992041 gzip=307714/307200 brotli=256408/256000 bytes error: production critical-path JavaScript exceeds the compressed transfer budget ``` origin/dev f4b61cd6c measures gzip=306074 brotli=254929 (passes). At 85cb920ee, i.e. **before any of my code changes**, it is already gzip=307556 brotli=256213: the rename work of J17/J17b adds +1482 B gzip to the critical path (J17's "main.js +3 B" looked at the wrong chunk). My icon and tooltips add +158 B gzip / +195 B brotli. So the branch **does not pass the transfer gate**. I did not raise the cap (owner's call) and did not move the rename code into an on-demand chunk: on an iPhone the field must be focused inside the double-tap's gesture for the keyboard to open, so a lazy chunk needs a preload-on-first-touch design of its own. Needs a decision: raise the critical cap by about 1.2 KiB (D188), or a follow-up job to make `beginInlineRename`/`placeOverName` on-demand with a preload. - **Full `scripts/verify fast` (Rust rows, static builds) NOT run by me**: the VM had 11 GB free (the 25 GB build-slot floor never opens; now 43 GB after another job cleaned up) and the change is web-only. The orchestrator's separate x86 run of the J17 head still stands; this head changes only apps/tracer and packages/ui. ## Screenshots (production build, ink, headless Chromium; not judged by me) Rename, desktop 1440x900 DPR 2: ![d1440-rename-1-before.png](https://git.kayg.org/attachments/57cfd1d2-7fce-49ce-847e-3ebfabc7abd9) ![d1440-rename-2-editing-usual-name.png](https://git.kayg.org/attachments/ed8a1cb7-3f03-4f84-bbf6-81b39b3607d0) ![d1440-rename-3-saved-short-name.png](https://git.kayg.org/attachments/4d4d4fa0-4373-48ef-877c-1a88aa3f6352) ![d1440-rename-4-editing-short-name.png](https://git.kayg.org/attachments/c2518e82-36b4-46e4-801f-e13baeabc32d) Rename, phone 393x852 DPR 3: ![phone393-rename-1-before.png](https://git.kayg.org/attachments/6b11e5d6-d6d2-4a94-9fad-8085a87f88e5) ![phone393-rename-2-editing-usual-name.png](https://git.kayg.org/attachments/32bd196c-c5f9-4771-9461-2216823818a4) ![phone393-rename-3-saved-short-name.png](https://git.kayg.org/attachments/6745016d-7f33-4ae6-b7ea-0a4828c8bddf) ![phone393-rename-4-editing-short-name.png](https://git.kayg.org/attachments/c37fee69-e85a-4d36-932d-e0e39be07af6) Pill before / scrolled to end / back, phone (tree scrolls 341 px): ![phone393-pill-1-before-scroll.png](https://git.kayg.org/attachments/a83cdf83-69a7-4bbe-bc62-5a79038c61a5) ![phone393-pill-2-scrolled-to-end.png](https://git.kayg.org/attachments/5b0ef783-a0bb-4a9b-99c6-3b5c4edaad24) ![phone393-pill-3-back-at-top.png](https://git.kayg.org/attachments/11a8a9d7-6420-421b-af4b-9c0a3c1d750a) Pill, desktop 1440x560 (tree scrolls 187 px; at 1440x900 it fits whole): ![d1440short560-pill-1-before-scroll.png](https://git.kayg.org/attachments/3a2d7d42-2402-4746-8b65-4216393889bb) ![d1440short560-pill-2-scrolled-to-end.png](https://git.kayg.org/attachments/3ea4425d-b514-4ba8-a8b1-fb2573bb1573) ![d1440short560-pill-3-back-at-top.png](https://git.kayg.org/attachments/80bc3617-d21a-46ce-b2d4-85d4c2c1626d) Pill, desktop 1440x900 (no overflow, for completeness): ![d1440-pill-2-scrolled-to-end.png](https://git.kayg.org/attachments/06945b52-3b26-42d2-b2de-8e2f54425cfe) Detached icon and tooltips, desktop: ![d1440-sessions-1-detached-icon.png](https://git.kayg.org/attachments/05420a56-197c-4fdd-ad51-3bc0851e8ca7) ![d1440-sessions-2-detached-tooltip.png](https://git.kayg.org/attachments/0d9b333e-f021-41e5-8ea0-0578f19f5d95) ![d1440-sessions-3-cross-tooltip.png](https://git.kayg.org/attachments/df998b95-aae6-48d2-87ed-7617cfd62249) Detached icon, phone: ![phone393-sessions-1-detached-icon.png](https://git.kayg.org/attachments/4b2f0290-9dc3-438e-83c9-320d0fef03d5) Mockup `&marks=words`: ![phone393-marks-words.png](https://git.kayg.org/attachments/bf0a15c7-9672-4b62-811a-3a6643c28280) ![d1440-marks-words.png](https://git.kayg.org/attachments/b8aa3d5d-d969-4d89-8b4f-1796ad275294) Videos (frames of the real page, about 28 fps; the browser's own video encoder produced nothing in this nix build, so they are stitched screenshots): [1440x900 rename and scroll](https://git.kayg.org/attachments/c3407968-62a5-47e4-9c1b-ce41b74f6649), [393x852](https://git.kayg.org/attachments/4a378c78-9ec8-488f-a69e-bf22a547e7d1), [1440x560 with a scrolling list](https://git.kayg.org/attachments/47420241-87ad-4917-94e2-e9309807d0f7). Numbers per frame while scrolling (pill gap to the panel bottom, min / max over the scroll): phone 9.00 / 9.00, 1440x560 9.00 / 9.00 (and back), idle 9.00. ## Cleanup / left running - The **live preview server is left running on purpose**: PID in `~/j54-logs/preview.pid` on infraternal-dev-02-std (bun mock-server, port 47654, bound to 10.69.69.117). Stop it by PID when the owner is done. Rebuild: `~/j54-logs/preview-build.sh` then `~/j54-logs/preview-serve.sh` in worktree `~/worktrees/j54-preview` (the mock server there carries the orchestrator's uncommitted bind/always-auth patch, `~/j54-logs/preview-bind.patch`). - Worktrees `~/worktrees/j54` and `j54-preview` remain; logs `~/j54-logs/`, evidence `~/j54-evidence/j54/`. No Rust target built. The Playwright runs did not go through build-slot (its disk floor was not met); each ran one worker at nice 10.
Author
Owner

J106 progress (2026-11-02). Branch row-actions-242-215 (pushed), head bfaf96155; typecheck (bun run check) clean on dev-02 at 15bfac3c5.

Done, one commit per concern:

  1. 33e91b0c9 merge of sidebar-pill-259 (#259, scope added by the owner) onto origin/dev 17d282a18. Conflicts: the two inline-rename.ts modules (dev's account card and #259's) are now one field: #259's beginInlineRename / placeOverName / onDoubleActivate; dev's inlineRename(target, …) stays as a thin wrapper over it (account card unchanged), .ui-rename-input became .ui-inline-rename. Data path of a rename stays dev's (#293).
  2. 08c1cef27 shared row-menu.ts + row-confirm.ts (+ Spring.fling, window menu opening at a point, danger row), ported from 97597e740.
  3. 7eefe5674 toolbar/row-actions.ts + tree wiring: right-click, long press, Shift+F10/menu key, trackpad/touch swipes, End asks in its row, Rename through BranchedMenu.rename(id) (the shared field), palette rows for the focused row.
  4. 79da821ac hover action pill, F2, Delete (#215).
  5. kv-list panel + 15bfac3c5 Access level row and consent (#215, D286).
  6. bfaf96155 Playwright specs (row-menu, row-gestures, row-ask, replacement-alignment, row-swipe-continuity, sidebar-rename-remove, access-level).

Missing backends (not invented):

  • End session: the product inventory has can.end = false (#100; no leg-A verb, contracts/wire.md: the server never signals a shim). The in-row End, the left swipe and Delete-on-a-session are built behind can.end; in the product they do not appear until #100 lands (the test double can end).
  • Privileged access: no server endpoint raises the agent's privileges with a once-used secret. The row and consent are built against Adapters.privilege (sessions/privilege.ts, a PrivilegeService); the product leaves it unset, so the "Access level" row does not show. The test double implements it (?privilege=<scenario>).
  • Host removal and host rename are real: removal uses adapters.hostRemoval (/remote/hosts/remove/*, passkey flow, so it asks in its own card, not in the row); a host renames through mesh.node.rename (#259), so only a host the Mesh knows has Rename.
  • The consent's ? goes to the Docs view when it exists; there is no "privileges" docs page yet.

One decision for the owner: on touch the #215 mockup revealed the action pill with a left swipe; #242 gives the left swipe to End/Close. I kept #242's swipes and the long-press menu on touch; the hover pill is pointer-only.

Next: run the new specs, production-build screenshots at DPR 2/3, scripts/verify fast.

**J106 progress** (2026-11-02). Branch `row-actions-242-215` (pushed), head `bfaf96155`; typecheck (`bun run check`) clean on dev-02 at `15bfac3c5`. Done, one commit per concern: 1. `33e91b0c9` merge of `sidebar-pill-259` (#259, scope added by the owner) onto `origin/dev` `17d282a18`. Conflicts: the two `inline-rename.ts` modules (dev's account card and #259's) are now **one** field: #259's `beginInlineRename` / `placeOverName` / `onDoubleActivate`; dev's `inlineRename(target, …)` stays as a thin wrapper over it (account card unchanged), `.ui-rename-input` became `.ui-inline-rename`. Data path of a rename stays dev's (#293). 2. `08c1cef27` shared `row-menu.ts` + `row-confirm.ts` (+ `Spring.fling`, window menu opening at a point, danger row), ported from `97597e740`. 3. `7eefe5674` `toolbar/row-actions.ts` + tree wiring: right-click, long press, Shift+F10/menu key, trackpad/touch swipes, End asks in its row, Rename through `BranchedMenu.rename(id)` (the shared field), palette rows for the focused row. 4. `79da821ac` hover action pill, F2, Delete (#215). 5. kv-list `panel` + `15bfac3c5` Access level row and consent (#215, D286). 6. `bfaf96155` Playwright specs (row-menu, row-gestures, row-ask, replacement-alignment, row-swipe-continuity, sidebar-rename-remove, access-level). **Missing backends (not invented):** - **End session**: the product inventory has `can.end = false` (#100; no leg-A verb, `contracts/wire.md`: the server never signals a shim). The in-row End, the left swipe and Delete-on-a-session are built behind `can.end`; in the product they do not appear until #100 lands (the test double can end). - **Privileged access**: no server endpoint raises the agent's privileges with a once-used secret. The row and consent are built against `Adapters.privilege` (`sessions/privilege.ts`, a `PrivilegeService`); the product leaves it unset, so the "Access level" row does not show. The test double implements it (`?privilege=<scenario>`). - **Host removal** and **host rename** are real: removal uses `adapters.hostRemoval` (`/remote/hosts/remove/*`, passkey flow, so it asks in its own card, not in the row); a host renames through `mesh.node.rename` (#259), so only a host the Mesh knows has Rename. - The consent's `?` goes to the Docs view when it exists; there is no "privileges" docs page yet. **One decision for the owner:** on touch the #215 mockup revealed the action pill with a left swipe; #242 gives the left swipe to End/Close. I kept #242's swipes and the long-press menu on touch; the hover pill is pointer-only. Next: run the new specs, production-build screenshots at DPR 2/3, `scripts/verify fast`.
Author
Owner

J106 finish. Branch row-actions-242-215, head 82c54c678, pushed (base origin/dev 17d282a18, merged with dev 99668d8ab along the way). Built into the real product, no mock flag. Evidence screenshots (production build, DPR 2 and 3) are in the two comments above on #242 and #215.

What is built

  • #259 brought in as the base: merge of sidebar-pill-259; the two inline-rename.ts modules (dev's and #259's) are now one field (#259's beginInlineRename; dev's inlineRename is a thin wrapper, .ui-rename-input is gone). Rename's data path is dev's (#293).
  • #242: right-click, long press, Shift+F10 / menu key, trackpad sideways scroll, left and right swipes; End asks in its own row starting at the label's x; the continuous right swipe; every action of the focused row is a palette row. Escape closes a revealed row or the question first.
  • #215: hover pill (Rename, End/Remove; pointer only), double click and double tap rename (through the shared field), F2, Delete, remove host; "Access level" row and the consent from a window's pill → Host tab; palette "Allow full access on ".
  • Row actions, menu, swipes and pill load with the sidebar (on-demand chunk), not with the canvas.

Missing backends (not invented, see earlier comment): End session (inventory can.end is false, #100): End, the left swipe and Delete-on-a-session do not appear in the product until it lands; privileged access (no server endpoint): the row and consent exist behind Adapters.privilege, unset in the product; host rename works only for hosts the Mesh knows (mesh.node.rename); host removal uses the existing passkey flow (its own card, not in-row). The consent's "?" goes to the Docs view; there is no privileges docs page yet.

For the owner: on touch #215's mockup revealed the pill with a left swipe, #242 gives the left swipe to End/Close: I kept #242's swipes and the long-press menu on touch; the pill is hover-only.

Tests (Playwright, production build, test double; desktop 1440×900 and phone 393×852): row-menu, row-gestures, row-ask, replacement-alignment (≤ 0.5 px, DPR 2 and 3), row-swipe-continuity, sidebar-rename-remove, access-level, plus #259's mesh-rename adapted to dev. Last full set (head 91440dc79): 94 passed, 4 failed: 3 in sessions-canvas.spec.ts (lines 170, 370, 479) fail identically on unmodified origin/dev 17d282a18 (measured: 3 failed / 19 passed there), and the 4th (double click on an exited session whose list re-sorts) was fixed afterwards; sidebar-rename-remove.spec.ts on 82c54c678: 10 passed.

Gate: scripts/verify fast does NOT pass: one failure, the deferred JavaScript budget. The full gate ran on 8c548ce0c (dev-02); since then only TypeScript changed (git diff 8c548ce0c HEAD -- crates Cargo.toml Cargo.lock scripts is empty). Rust part, verbatim:

| Rust gate                 | Result       |
+---------------------------+--------------+
| fmt                       | PASS         |
| VT native fmt             | PASS         |
| CLI plugin compile-out    | PASS         |
| clippy                    | PASS         |
| SSH runtime test helper   | PASS         |
| real-binary fixture paths | PASS         |
| test                      | PASS         |
| SSH inode reuse fixture   | PASS         |
| shim process-per-user     | PASS         |
| cargo-deny                | PASS         |
| gate architecture         | PASS         |
| static builds             | PASS         |
+---------------------------+--------------+
x86_64: size 22422864 bytes; baseline 22418256; delta +4608 bytes (report only, D243 amended 2026-11-01)
aarch64: size 20454096 bytes; baseline 20453280; delta +816 bytes (report only)

TypeScript part re-run on the final head (82c54c678, tsc and every bun test group: 0 fail), then:

JavaScript transfer, critical: identity=1006850 gzip=313843/327680 brotli=261710/273408 bytes
JavaScript transfer, deferred: identity=179031 gzip=62025/61440 brotli=54702/55296 bytes
JavaScript transfer, onDemand: identity=304405 gzip=121081/20480 brotli=107917/18432 bytes
JavaScript transfer, onDemand largest chunk chunk-f7w4g32v.js: gzip=15464/20480 brotli=13803/18432 bytes (class total gzip=121081 brotli=107917, not limited)
error: production deferred JavaScript exceeds its compressed transfer budget

Measured against dev (99668d8ab, same command): critical 311,046 gzip, deferred 61,276 (164 B under its cap), onDemand 109,459. Before I moved the row code on demand the deferred class was 68,009; now it is 62,025, i.e. 585 B gzip over the 60 KiB cap (brotli is under). By the source diff the rest is the Mesh host rename of #259 and the tree's rename routing; I did not measure it per module, and I did not touch the gate. Needs the orchestrator/owner: ratchet the deferred cap (D188 rule: measured size rounded up to a KiB plus a margin) or tell me what to cut.

Commits (oldest first):

82c54c678 test(tracer): the rename double click aims at the name, as a person does (#215)
03701a66c ui: a double click is still one when the second release lands on the gap the rebuilt list left (#259, #215)
91440dc79 details: the consent pane stays in view while it grows into the popover (#215)
86ad8dc65 ui: a double click renames the row the first press was on, even if the list re-sorted under the pointer (#259, #215)
73f0710cc perf: the row menu, swipes and hover pill load with the sidebar, not with the canvas (D188, #242, #215)
8e0150821 sidebar: the pill ends a session with the stop square, and hides while the name is being edited (#215)
2f4ab7945 details: the consent pane spans the whole row and is brought into view when it opens (#215)
a61603233 ui: a double click renames even when the first click rebuilt the list (#259, #215)
8c548ce0c sidebar: the hover pill sits left of a row's marks and notes, which keep their tooltips (#215, #259)
1f041d24f Merge origin/dev (99668d8ab) into row-actions-242-215
30094bf01 test(tracer): opt-in review captures of the row menu, swipes, rename and consent (#242, #215)
2fe75432f test(tracer): #259's rename checks follow dev's connection icon and the renamable sessions (#259, #212, #215)
fa3131756 ui: a rename field takes the free room after a name that a clip cuts short (#259, #215)
99668d8ab Merge decisions-2026-11-02: D163 GotaTun on Linux, D317 docs structure
1d8af5c4a decisions: D163 Linux engine is GotaTun; D317 user docs structure
cdff83eb0 Merge taste-2026-11-02: owner review rows from 2026-11-02
9ef53bbb9 taste: windows start at the layout's size and never overlap
d67670c56 taste: descriptions say what a thing does, not what state it is in
d251c0ad8 taste: content sits inside its container with an even inset
69ba50588 taste: Settings rows scroll as a whole, not window by window
203fd67d3 taste: pill menus centre on their pill; no dead buttons
4c8e22611 taste: windows keep their natural width and the canvas scrolls; popovers follow their anchor
a479a8760 Merge size-baseline-ratchet: static size baselines match current dev (D243)
a8926703a verify: ratchet the static size baselines to the current dev measurement (D243)
c85e53e54 ui: a rename field on a fine pointer types in the size of the name it replaces (#259, #215)
3213ae21a palette: "Allow full access on <host>" opens the machine's consent (#215, D286)
3f2c9aeab test(tracer): every gesture and key of the sidebar's row menu, swipes, rename and consent (#242, #215)
0a4dd245b details: an "Access level" row and a consent that asks before the agent gets full access (#215, D286)
fea95e752 ui: a key/value row can carry a pane that opens under it (#215, D160)
5784444f1 sidebar: an action pill on hover, F2 renames and Delete removes the focused row (#215)
1b3992370 sidebar: right-click, long press, Shift+F10 and swipes on rows; End asks in its row (#242, D309)
a6498b99c ui: one row menu and swipe component, and the in-row question, for every list of rows (#242, D309)
294042b56 Merge fix-dev-red: dev green again after #291 (#307)
d7984ca7d ui: the anchored popover opens at a point, the window menu gets a danger row
9919b28b1 ui: a spring can be flung, so a released drag carries on from the finger's speed (#242, D70)
33e91b0c9 Merge sidebar-pill-259: rename Mesh hosts in place, detached icon, pinned account pill (#259)
502d0fc7e Stabilize clean shim exit observation under load #307
f15a74866 Fix J96 server test regressions after #291
66d25769d sidebar: the tick, cross and dot on a session row get a tooltip in plain words (#259)
e60f12434 test: the sidebar's tick, cross and dot explain themselves in a tooltip (#259)
44b3256f1 sidebar: a detached session shows an icon, not the word (#259)
648cc7774 test: a detached session in the sidebar shows an icon with a "Detached" tooltip (#259)
85cb920ee test: the rename field and the widened name pill never overlap the → pill (#259)
9fe1b7041 ui: the inline rename field stays inside the name's own box (#259)
c747d9fbb test: the rename field must not sit under the status dot (#259)
e86c2baf2 test: opt-in review captures of the pinned sidebar pill (#259)
845aa3e2c test: browser spec for renaming Mesh hosts in place (#259)
126c97190 palette: "Rename <host>" for the Mesh's hosts (#259)
16756de44 sidebar: rename a Mesh host by double click or double tap in the Views tree (#259)
cae06fe17 mesh: rename a host by double click or double tap on its card (#259)
ce31a7b52 ui: field placed over a name, and a double tap that survives a rebuilt list (#259)
e3d803ff2 mesh: rename a host through mesh.node.rename in the Mesh API adapter (#259)
711032f75 ui: one inline-rename field and one double-tap gesture for every in-place rename (#259)
0172555f7 sidebar: the account pill stays pinned once the inbox card has come and gone (#259)

VM cleanup: my Rust and tracer build dirs on dev-02 are deleted; worktrees ~/worktrees/j106* remain until the orchestrator prunes them.

**J106 finish.** Branch `row-actions-242-215`, head **`82c54c678`**, pushed (base `origin/dev` `17d282a18`, merged with dev `99668d8ab` along the way). Built into the real product, no mock flag. Evidence screenshots (production build, DPR 2 and 3) are in the two comments above on #242 and #215. **What is built** - #259 brought in as the base: merge of `sidebar-pill-259`; the two `inline-rename.ts` modules (dev's and #259's) are now one field (#259's `beginInlineRename`; dev's `inlineRename` is a thin wrapper, `.ui-rename-input` is gone). Rename's data path is dev's (#293). - #242: right-click, long press, Shift+F10 / menu key, trackpad sideways scroll, left and right swipes; End asks in its own row starting at the label's x; the continuous right swipe; every action of the focused row is a palette row. Escape closes a revealed row or the question first. - #215: hover pill (Rename, End/Remove; pointer only), double click and double tap rename (through the shared field), F2, Delete, remove host; "Access level" row and the consent from a window's pill → Host tab; palette "Allow full access on <host>". - Row actions, menu, swipes and pill load with the sidebar (on-demand chunk), not with the canvas. **Missing backends (not invented, see earlier comment):** End session (inventory `can.end` is false, #100): End, the left swipe and Delete-on-a-session do not appear in the product until it lands; privileged access (no server endpoint): the row and consent exist behind `Adapters.privilege`, unset in the product; host rename works only for hosts the Mesh knows (`mesh.node.rename`); host removal uses the existing passkey flow (its own card, not in-row). The consent's "?" goes to the Docs view; there is no privileges docs page yet. **For the owner:** on touch #215's mockup revealed the pill with a left swipe, #242 gives the left swipe to End/Close: I kept #242's swipes and the long-press menu on touch; the pill is hover-only. **Tests** (Playwright, production build, test double; desktop 1440×900 and phone 393×852): `row-menu`, `row-gestures`, `row-ask`, `replacement-alignment` (≤ 0.5 px, DPR 2 and 3), `row-swipe-continuity`, `sidebar-rename-remove`, `access-level`, plus #259's `mesh-rename` adapted to dev. Last full set (head `91440dc79`): 94 passed, 4 failed: 3 in `sessions-canvas.spec.ts` (lines 170, 370, 479) fail identically on unmodified `origin/dev` `17d282a18` (measured: 3 failed / 19 passed there), and the 4th (double click on an exited session whose list re-sorts) was fixed afterwards; `sidebar-rename-remove.spec.ts` on `82c54c678`: 10 passed. **Gate: `scripts/verify fast` does NOT pass: one failure, the deferred JavaScript budget.** The full gate ran on `8c548ce0c` (dev-02); since then only TypeScript changed (`git diff 8c548ce0c HEAD -- crates Cargo.toml Cargo.lock scripts` is empty). Rust part, verbatim: ``` | Rust gate | Result | +---------------------------+--------------+ | fmt | PASS | | VT native fmt | PASS | | CLI plugin compile-out | PASS | | clippy | PASS | | SSH runtime test helper | PASS | | real-binary fixture paths | PASS | | test | PASS | | SSH inode reuse fixture | PASS | | shim process-per-user | PASS | | cargo-deny | PASS | | gate architecture | PASS | | static builds | PASS | +---------------------------+--------------+ x86_64: size 22422864 bytes; baseline 22418256; delta +4608 bytes (report only, D243 amended 2026-11-01) aarch64: size 20454096 bytes; baseline 20453280; delta +816 bytes (report only) ``` TypeScript part re-run on the final head (`82c54c678`, `tsc` and every `bun test` group: 0 fail), then: ``` JavaScript transfer, critical: identity=1006850 gzip=313843/327680 brotli=261710/273408 bytes JavaScript transfer, deferred: identity=179031 gzip=62025/61440 brotli=54702/55296 bytes JavaScript transfer, onDemand: identity=304405 gzip=121081/20480 brotli=107917/18432 bytes JavaScript transfer, onDemand largest chunk chunk-f7w4g32v.js: gzip=15464/20480 brotli=13803/18432 bytes (class total gzip=121081 brotli=107917, not limited) error: production deferred JavaScript exceeds its compressed transfer budget ``` Measured against dev (`99668d8ab`, same command): critical 311,046 gzip, deferred **61,276** (164 B under its cap), onDemand 109,459. Before I moved the row code on demand the deferred class was 68,009; now it is 62,025, i.e. **585 B gzip over the 60 KiB cap** (brotli is under). By the source diff the rest is the Mesh host rename of #259 and the tree's rename routing; I did not measure it per module, and I did not touch the gate. **Needs the orchestrator/owner: ratchet the deferred cap (D188 rule: measured size rounded up to a KiB plus a margin) or tell me what to cut.** Commits (oldest first): ``` 82c54c678 test(tracer): the rename double click aims at the name, as a person does (#215) 03701a66c ui: a double click is still one when the second release lands on the gap the rebuilt list left (#259, #215) 91440dc79 details: the consent pane stays in view while it grows into the popover (#215) 86ad8dc65 ui: a double click renames the row the first press was on, even if the list re-sorted under the pointer (#259, #215) 73f0710cc perf: the row menu, swipes and hover pill load with the sidebar, not with the canvas (D188, #242, #215) 8e0150821 sidebar: the pill ends a session with the stop square, and hides while the name is being edited (#215) 2f4ab7945 details: the consent pane spans the whole row and is brought into view when it opens (#215) a61603233 ui: a double click renames even when the first click rebuilt the list (#259, #215) 8c548ce0c sidebar: the hover pill sits left of a row's marks and notes, which keep their tooltips (#215, #259) 1f041d24f Merge origin/dev (99668d8ab) into row-actions-242-215 30094bf01 test(tracer): opt-in review captures of the row menu, swipes, rename and consent (#242, #215) 2fe75432f test(tracer): #259's rename checks follow dev's connection icon and the renamable sessions (#259, #212, #215) fa3131756 ui: a rename field takes the free room after a name that a clip cuts short (#259, #215) 99668d8ab Merge decisions-2026-11-02: D163 GotaTun on Linux, D317 docs structure 1d8af5c4a decisions: D163 Linux engine is GotaTun; D317 user docs structure cdff83eb0 Merge taste-2026-11-02: owner review rows from 2026-11-02 9ef53bbb9 taste: windows start at the layout's size and never overlap d67670c56 taste: descriptions say what a thing does, not what state it is in d251c0ad8 taste: content sits inside its container with an even inset 69ba50588 taste: Settings rows scroll as a whole, not window by window 203fd67d3 taste: pill menus centre on their pill; no dead buttons 4c8e22611 taste: windows keep their natural width and the canvas scrolls; popovers follow their anchor a479a8760 Merge size-baseline-ratchet: static size baselines match current dev (D243) a8926703a verify: ratchet the static size baselines to the current dev measurement (D243) c85e53e54 ui: a rename field on a fine pointer types in the size of the name it replaces (#259, #215) 3213ae21a palette: "Allow full access on <host>" opens the machine's consent (#215, D286) 3f2c9aeab test(tracer): every gesture and key of the sidebar's row menu, swipes, rename and consent (#242, #215) 0a4dd245b details: an "Access level" row and a consent that asks before the agent gets full access (#215, D286) fea95e752 ui: a key/value row can carry a pane that opens under it (#215, D160) 5784444f1 sidebar: an action pill on hover, F2 renames and Delete removes the focused row (#215) 1b3992370 sidebar: right-click, long press, Shift+F10 and swipes on rows; End asks in its row (#242, D309) a6498b99c ui: one row menu and swipe component, and the in-row question, for every list of rows (#242, D309) 294042b56 Merge fix-dev-red: dev green again after #291 (#307) d7984ca7d ui: the anchored popover opens at a point, the window menu gets a danger row 9919b28b1 ui: a spring can be flung, so a released drag carries on from the finger's speed (#242, D70) 33e91b0c9 Merge sidebar-pill-259: rename Mesh hosts in place, detached icon, pinned account pill (#259) 502d0fc7e Stabilize clean shim exit observation under load #307 f15a74866 Fix J96 server test regressions after #291 66d25769d sidebar: the tick, cross and dot on a session row get a tooltip in plain words (#259) e60f12434 test: the sidebar's tick, cross and dot explain themselves in a tooltip (#259) 44b3256f1 sidebar: a detached session shows an icon, not the word (#259) 648cc7774 test: a detached session in the sidebar shows an icon with a "Detached" tooltip (#259) 85cb920ee test: the rename field and the widened name pill never overlap the → pill (#259) 9fe1b7041 ui: the inline rename field stays inside the name's own box (#259) c747d9fbb test: the rename field must not sit under the status dot (#259) e86c2baf2 test: opt-in review captures of the pinned sidebar pill (#259) 845aa3e2c test: browser spec for renaming Mesh hosts in place (#259) 126c97190 palette: "Rename <host>" for the Mesh's hosts (#259) 16756de44 sidebar: rename a Mesh host by double click or double tap in the Views tree (#259) cae06fe17 mesh: rename a host by double click or double tap on its card (#259) ce31a7b52 ui: field placed over a name, and a double tap that survives a rebuilt list (#259) e3d803ff2 mesh: rename a host through mesh.node.rename in the Mesh API adapter (#259) 711032f75 ui: one inline-rename field and one double-tap gesture for every in-place rename (#259) 0172555f7 sidebar: the account pill stays pinned once the inbox card has come and gone (#259) ``` VM cleanup: my Rust and tracer build dirs on dev-02 are deleted; worktrees `~/worktrees/j106*` remain until the orchestrator prunes them.
Author
Owner

J106 round 2 finish. Branch row-actions-242-215, head 5fa6334d7, pushed. Based on and merged with dev 816f9ab3e (J100 merged; also docs sections #311 and recovery #309). The cap is not raised: the code is cut.

Deferred JS (gzip bytes, bun run build && bun transfer-budget.ts)

dev 816f9ab3e this head
deferred 59,889 / 61,440 (brotli 52,786 / 55,296) 58,737 / 61,440 (brotli 51,856 / 55,296): headroom 2,703 B, brotli 3,440 B
critical 311,553 / 327,680 313,050
onDemand largest chunk 15,447 / 20,480 15,472

Per module, against dev 816f9ab3e (identity B / estimated gzip B: each module's share of its chunk by bytes in the output, from the bundler's metafile; head 9b3365e02, the last numbers are within 20 B of this head):

  • deferred: toolbar/tree.ts +495 / +170 (the hooks only: loader of the row actions, the openRename hook, the phone's close delay), sessions/live.ts +62 / +30, mesh/lazy.ts +40 / +15, mesh/index.ts +39 / +15, toolbar/palette.ts +36 / +18, model/reconcile.ts +27 / +13, views/world.ts -146 / -37, toolbar/viewlist.ts -2,092 / -693, pill-morph.ts -2,719 / -994 (both now on demand behind a thin hook).
  • critical: branched.ts +1,126 / +636, double-activate.ts (the gesture, new) +759 / +430, tooltip.ts +239 / +105, icons.ts +158 / +61, spring.ts +51 / +21, core-screen.ts +35 / +18 (13.2 KB under its cap).
  • on demand now (no longer in either class): the rename field (inline-rename.on-demand.ts), toolbar/row-rename.on-demand.ts, mesh/rename.on-demand.ts, toolbar/palette-hosts.on-demand.ts (remove host, allow full access, rename a Mesh host rows), toolbar/viewlist.on-demand.ts, and with them the row menu, swipes, pill and the in-row question.
    Merged with J100 alone (before J100 reached dev, ui-no-overshoot-scroll onto this branch): deferred 58,696.
    Lesson recorded in the commit message: a dynamic import from deferred code of a module that on-demand chunks also import statically is turned into a static link by the bundler and moves nothing, so every importer of an on-demand module has to be on demand too.

Behaviour notes. Right-click, swipes and the pill attach a few milliseconds after the sidebar first opens (#tree[data-rows="ready"]); a double click before that does nothing. The view list opens from the first tap (it waits for its small chunk if idle loading has not finished). The palette's host rows are fetched as the canvas comes up. The row swipe has no bounce now (J100's rule; it did not compile against the new spring type, found by merging).

Gate: scripts/verify fast exit 0 on 5fa6334d7 (dev-02), verbatim:

5fa6334d7 test(tracer): the typing check puts the focus back on the page instead of waiting for a textarea (#259)
| Rust gate                 | Result       |
+---------------------------+--------------+
| fmt                       | PASS         |
| VT native fmt             | PASS         |
| CLI plugin compile-out    | PASS         |
| clippy                    | PASS         |
| SSH runtime test helper   | PASS         |
| real-binary fixture paths | PASS         |
| test                      | PASS         |
| SSH inode reuse fixture   | PASS         |
| shim process-per-user     | PASS         |
| cargo-deny                | PASS         |
| gate architecture         | PASS         |
| static builds             | PASS         |
+---------------------------+--------------+

==> Compiler metadata generator checks
8452:PT_INTERP: absent; size: 22468304 bytes; baseline 22418256; delta +50048 bytes (report only, D243 amended 2026-11-01)
8488:PT_INTERP: absent; size: 20487864 bytes; baseline 20453280; delta +34584 bytes (report only, D243 amended 2026-11-01)
9617:JavaScript transfer, critical: identity=1005057 gzip=313050/327680 brotli=261034/273408 bytes
9618:JavaScript transfer, deferred: identity=168016 gzip=58737/61440 brotli=51856/55296 bytes
9619:JavaScript transfer, onDemand: identity=325049 gzip=130653/20480 brotli=116421/18432 bytes
9620:JavaScript transfer, onDemand largest chunk chunk-jvsymf4e.js: gzip=15472/20480 brotli=13810/18432 bytes (class total gzip=130653 brotli=116421, not limited)
9235: 517 pass 9236: 0 fail 9446: 107 pass 9447: 0 fail 9517: 17 pass 9518: 0 fail 9708: 39 pass 9709: 0 fail VERIFY_EXIT=0

(Earlier runs failed on this branch and were fixed, in order: a tsc error in the row spring vs the no-overshoot type; two unit tests (the palette rename test and a cubic-bezier overshoot in the swipe icon, caught by J100's no-overshoot.test.ts); a Rust vt_credit test and a 5 s unit test timeout on a loaded machine, each passing when rerun alone and in the next full run.)

Browser specs (production build, test double, 1440×900 / 393×852; last full run on 75078b6d7): 194 passed, 12 failed. Eleven fail identically on unmodified dev 816f9ab3e (measured there: canvas.spec 302, 345, 626; clusters.spec 702, 837; glass-ghost 4 cases; sessions-canvas 170 and the manager-on-demand check), and the twelfth, "another device typed last" (sessions-canvas), was a focus race that fails about half the runs on dev (5 of 9) and every run here; fixed in the spec (the focus probe shows build-01's textarea holding the focus while nix-cache is active) and passing 4 of 4 on 5fa6334d7. palette-polish (375×667) and mesh-rename desktop failed in some runs and pass in the final one; the palette label measured 57.866 px on dev as well.

Commits of this round (oldest first):

5fa6334d7 test(tracer): the typing check puts the focus back on the page instead of waiting for a textarea (#259)
75078b6d7 test(tracer): "typing takes the size over" types into the window it is about (#259)
433b2781b test(tracer): #259's tree rename checks wait for the row actions to attach (#259, #215)
8faf00970 palette: the host rows' chunk is fetched as the palette is installed, not at idle (D188, #215)
b0cea3b72 test(tracer): the row-menu right-click check waits for the menu before Escape (#242)
1da414c09 test, ui: the palette rename test follows the Mesh rename module; the armed swipe icon eases without overshoot (#215, #242)
2690c3346 ui: the row spring is typed as a SpringConfig, so it compiles against the no-overshoot spring (#242)
9b3365e02 Merge origin/dev (816f9ab3e, J100 merged) into row-actions-242-215
816f9ab3e Merge ui-no-overshoot-scroll: no elastic overshoot; wheel scrolls the content under it (#308, D275)
fae83a7b1 sidebar: row actions announce when they are attached; the palette's host rows load promptly (D188, #242, #215)
b5099e3be Merge docs/j114-sections: user docs in D317 sections (#311)
79a43ae3c ui: the row spring states `bounce: 0`, which both the current and the no-overshoot spring types accept (#242)
0ef98fea8 docs: one heading per setting, with its default and range only in its quick facts (#311, D317)
7dd462e9e docs: sections, nested addresses, redirects and a check for "?" targets (#311, D317)
4b40ac8b4 tracer: moving a window and the free canvas's gestures load on demand (D188, #308)
187f81759 Merge origin/dev (92ee8d5ea) into row-actions-242-215
3464c4e13 ui: the row swipe settles without a bounce (#242, TASTE "No overshoot, ever")
3b05ee668 perf: the view list and its pill morph load on demand behind a thin hook (D188)
59f6f46e2 perf: the rename field, the tree's rename routing, the Mesh host rename and the host rows of the palette load on demand (D188, #215, #259)
92ee8d5ea Merge fix-recovery-restart: account recovery always waits 24 measured hours (#309, D25)
77616905a Checkpoint measured recovery progress each minute and at shutdown (#309)
52ad241ae Confirm recovery countdown readiness with server status (#309, D25)
c56854dbb tracer: wheel specs and TASTE rule for the wheel over docs pages and terminals (D275, #308)
7788d5bd8 tracer: a vertical wheel scrolls the content under the pointer; no elastic bump at the ends (D275, #308)
c400f6f94 taste: no overshoot, ever (#308)
214f4eea4 tracer: a unit check rejects springs and easings that overshoot (#308)
7dd27c0b7 ui: every spring is critically damped and every curve ends without overshoot (#308)
716183781 Send recovery completion notice in revoked socket teardown (#309)
3b0123b4b Measure recovery waits with persisted monotonic uptime (#309, D25)
8440d50e9 Restart expired recovery with fresh safety deadlines (#309)

VM: my ~/worktrees/j106* worktrees and targets on dev-02 are pruned.

**J106 round 2 finish.** Branch `row-actions-242-215`, head **`5fa6334d7`**, pushed. Based on and merged with dev `816f9ab3e` (J100 merged; also docs sections #311 and recovery #309). The cap is not raised: the code is cut. **Deferred JS (gzip bytes, `bun run build && bun transfer-budget.ts`)** | | dev 816f9ab3e | this head | |---|---|---| | deferred | 59,889 / 61,440 (brotli 52,786 / 55,296) | **58,737** / 61,440 (brotli 51,856 / 55,296): headroom **2,703 B**, brotli 3,440 B | | critical | 311,553 / 327,680 | 313,050 | | onDemand largest chunk | 15,447 / 20,480 | 15,472 | Per module, against dev 816f9ab3e (identity B / estimated gzip B: each module's share of its chunk by bytes in the output, from the bundler's metafile; head `9b3365e02`, the last numbers are within 20 B of this head): - **deferred:** `toolbar/tree.ts` +495 / +170 (the hooks only: loader of the row actions, the `openRename` hook, the phone's close delay), `sessions/live.ts` +62 / +30, `mesh/lazy.ts` +40 / +15, `mesh/index.ts` +39 / +15, `toolbar/palette.ts` +36 / +18, `model/reconcile.ts` +27 / +13, `views/world.ts` -146 / -37, **`toolbar/viewlist.ts` -2,092 / -693, `pill-morph.ts` -2,719 / -994** (both now on demand behind a thin hook). - **critical:** `branched.ts` +1,126 / +636, `double-activate.ts` (the gesture, new) +759 / +430, `tooltip.ts` +239 / +105, `icons.ts` +158 / +61, `spring.ts` +51 / +21, `core-screen.ts` +35 / +18 (13.2 KB under its cap). - **on demand now (no longer in either class):** the rename field (`inline-rename.on-demand.ts`), `toolbar/row-rename.on-demand.ts`, `mesh/rename.on-demand.ts`, `toolbar/palette-hosts.on-demand.ts` (remove host, allow full access, rename a Mesh host rows), `toolbar/viewlist.on-demand.ts`, and with them the row menu, swipes, pill and the in-row question. Merged with J100 alone (before J100 reached dev, `ui-no-overshoot-scroll` onto this branch): deferred 58,696. Lesson recorded in the commit message: a dynamic import from deferred code of a module that on-demand chunks also import statically is turned into a static link by the bundler and moves nothing, so every importer of an on-demand module has to be on demand too. **Behaviour notes.** Right-click, swipes and the pill attach a few milliseconds after the sidebar first opens (`#tree[data-rows="ready"]`); a double click before that does nothing. The view list opens from the first tap (it waits for its small chunk if idle loading has not finished). The palette's host rows are fetched as the canvas comes up. The row swipe has no bounce now (J100's rule; it did not compile against the new spring type, found by merging). **Gate: `scripts/verify fast` exit 0** on `5fa6334d7` (dev-02), verbatim: ``` 5fa6334d7 test(tracer): the typing check puts the focus back on the page instead of waiting for a textarea (#259) | Rust gate | Result | +---------------------------+--------------+ | fmt | PASS | | VT native fmt | PASS | | CLI plugin compile-out | PASS | | clippy | PASS | | SSH runtime test helper | PASS | | real-binary fixture paths | PASS | | test | PASS | | SSH inode reuse fixture | PASS | | shim process-per-user | PASS | | cargo-deny | PASS | | gate architecture | PASS | | static builds | PASS | +---------------------------+--------------+ ==> Compiler metadata generator checks 8452:PT_INTERP: absent; size: 22468304 bytes; baseline 22418256; delta +50048 bytes (report only, D243 amended 2026-11-01) 8488:PT_INTERP: absent; size: 20487864 bytes; baseline 20453280; delta +34584 bytes (report only, D243 amended 2026-11-01) 9617:JavaScript transfer, critical: identity=1005057 gzip=313050/327680 brotli=261034/273408 bytes 9618:JavaScript transfer, deferred: identity=168016 gzip=58737/61440 brotli=51856/55296 bytes 9619:JavaScript transfer, onDemand: identity=325049 gzip=130653/20480 brotli=116421/18432 bytes 9620:JavaScript transfer, onDemand largest chunk chunk-jvsymf4e.js: gzip=15472/20480 brotli=13810/18432 bytes (class total gzip=130653 brotli=116421, not limited) 9235: 517 pass 9236: 0 fail 9446: 107 pass 9447: 0 fail 9517: 17 pass 9518: 0 fail 9708: 39 pass 9709: 0 fail VERIFY_EXIT=0 ``` (Earlier runs failed on this branch and were fixed, in order: a `tsc` error in the row spring vs the no-overshoot type; two unit tests (the palette rename test and a `cubic-bezier` overshoot in the swipe icon, caught by J100's `no-overshoot.test.ts`); a Rust `vt_credit` test and a 5 s unit test timeout on a loaded machine, each passing when rerun alone and in the next full run.) **Browser specs** (production build, test double, 1440×900 / 393×852; last full run on `75078b6d7`): 194 passed, 12 failed. Eleven fail identically on unmodified dev `816f9ab3e` (measured there: `canvas.spec` 302, 345, 626; `clusters.spec` 702, 837; `glass-ghost` 4 cases; `sessions-canvas` 170 and the manager-on-demand check), and the twelfth, "another device typed last" (`sessions-canvas`), was a focus race that fails about half the runs on dev (5 of 9) and every run here; fixed in the spec (the focus probe shows build-01's textarea holding the focus while nix-cache is active) and passing 4 of 4 on `5fa6334d7`. `palette-polish` (375×667) and `mesh-rename` desktop failed in some runs and pass in the final one; the palette label measured 57.866 px on dev as well. Commits of this round (oldest first): ``` 5fa6334d7 test(tracer): the typing check puts the focus back on the page instead of waiting for a textarea (#259) 75078b6d7 test(tracer): "typing takes the size over" types into the window it is about (#259) 433b2781b test(tracer): #259's tree rename checks wait for the row actions to attach (#259, #215) 8faf00970 palette: the host rows' chunk is fetched as the palette is installed, not at idle (D188, #215) b0cea3b72 test(tracer): the row-menu right-click check waits for the menu before Escape (#242) 1da414c09 test, ui: the palette rename test follows the Mesh rename module; the armed swipe icon eases without overshoot (#215, #242) 2690c3346 ui: the row spring is typed as a SpringConfig, so it compiles against the no-overshoot spring (#242) 9b3365e02 Merge origin/dev (816f9ab3e, J100 merged) into row-actions-242-215 816f9ab3e Merge ui-no-overshoot-scroll: no elastic overshoot; wheel scrolls the content under it (#308, D275) fae83a7b1 sidebar: row actions announce when they are attached; the palette's host rows load promptly (D188, #242, #215) b5099e3be Merge docs/j114-sections: user docs in D317 sections (#311) 79a43ae3c ui: the row spring states `bounce: 0`, which both the current and the no-overshoot spring types accept (#242) 0ef98fea8 docs: one heading per setting, with its default and range only in its quick facts (#311, D317) 7dd462e9e docs: sections, nested addresses, redirects and a check for "?" targets (#311, D317) 4b40ac8b4 tracer: moving a window and the free canvas's gestures load on demand (D188, #308) 187f81759 Merge origin/dev (92ee8d5ea) into row-actions-242-215 3464c4e13 ui: the row swipe settles without a bounce (#242, TASTE "No overshoot, ever") 3b05ee668 perf: the view list and its pill morph load on demand behind a thin hook (D188) 59f6f46e2 perf: the rename field, the tree's rename routing, the Mesh host rename and the host rows of the palette load on demand (D188, #215, #259) 92ee8d5ea Merge fix-recovery-restart: account recovery always waits 24 measured hours (#309, D25) 77616905a Checkpoint measured recovery progress each minute and at shutdown (#309) 52ad241ae Confirm recovery countdown readiness with server status (#309, D25) c56854dbb tracer: wheel specs and TASTE rule for the wheel over docs pages and terminals (D275, #308) 7788d5bd8 tracer: a vertical wheel scrolls the content under the pointer; no elastic bump at the ends (D275, #308) c400f6f94 taste: no overshoot, ever (#308) 214f4eea4 tracer: a unit check rejects springs and easings that overshoot (#308) 7dd27c0b7 ui: every spring is critically damped and every curve ends without overshoot (#308) 716183781 Send recovery completion notice in revoked socket teardown (#309) 3b0123b4b Measure recovery waits with persisted monotonic uptime (#309, D25) 8440d50e9 Restart expired recovery with fresh safety deadlines (#309) ``` VM: my `~/worktrees/j106*` worktrees and targets on dev-02 are pruned.
Sign in to join this conversation.
No labels
launch-qa
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
kayg/infraternal#259
No description provided.