J300: host-removal confirmation is badly designed (wrong anchor, sentence button, legible glass) #391
Open
opened 2026-11-06 12:14:26 +00:00 by kayg
·
17 comments
No Branch/Tag specified
main
j470b-server-mesh-rejoin
mesh-compat-382
j444b-d381-key-wins-flood
j461b-macos-utun-reader-thread
j475b-remove-host-motion
fix-reconnect-new-link
j481-d380
dev
j479-mesh-soak
fix/j476-host-facts
j475-motion-pill-split
j470-mac-node-join
root-upgrade-d376
j474-review-merge
latency-targets-120hz
nightly-suite-shards
gotatun-pin-j469
macos-utun-reader-thread
fix-flood-echo-stall
wip/j416
motion-fast-ease-out
mesh-addhost-j259
takeover-close-terminals-d368
kbd-instant-followups
fix-trust-key-double-click
nightly-suite-partial-report
appwin-icons-j207
rusqlite-slice1
swipe-content-first-d374
mesh-mtu-381
addhost-instant-open
glass-contrast-d365-mock
glass-contrast-d365
signout-followups-442
fix-startup-toast-red
research-gotatun-matrix-j317
themes-sync-j304
fix-load-flakes
fix-nix-zig-patch
fix-compute01-browser-baseline
ratchet-size-baseline-419
predict-auto-d130
revoke-coverage-d367
nightly-suite-queue-timeout
nightly-browser-suite
fix-rustsec-2026-0459
fonts-ioskeley-obel
log-retention-d375
fix-kbd-no-anim-427
fix-dev-red-specs-2
takeover-proof-305-j205
wip/j410-server-pump
ui-consistency-d372
fix-osc52-clipboard
libghostty-vt-1.0
forget-retired-host-d369
j404-merge-426
fix-setup-lock-race
fix-touch-select-426
revoke-access-report-ui
fix-predictive-echo-specs
fix-selinux-agent-exec
wip/j395-checkpoint2
wip/j395
j391-review-scratch
ui-consistency-j195-deferred-rebased
fix-rustc-paths-421
decisions-wording-341
fix-install-suite-red
fix-dev-rtt-specs
fix-pending-removal-align
fix-privileged-skip
fix-install-suite-404
review-j368
mesh-dns-j254
revoke-access-report-d356b
revoke-privilege-round5
fix-removal-confirm
review-j360
gotatun-rotation-367
deps-refresh-340
review-j354
review-J351
review-j350
addhost-takeover-d359
revoke-report-items-347
revoke-end-sessions-d362
review-j348
size-mesh-ssh-346
size-trim-337
revoke-access-diff-d356
j259-pre-rebase-b06c5a6
j305-ended-at-start-spec
addhost-sudo-consent
fix-layout-real-specs-411
fix-shell-open-411
fix-console-hosts-373
fix-shell-exit
fuzz-host-name-353
fix-host-details-410
macos-filter-j197
research-gotatun-tricks
revoke-p3-j216l
stale-state-pill
revoke-followups-j216k
revoke-progress-j216e
backup/macos01-20261106/lume/j197
backup/macos01-20261106/lume/appwin-icons-j207-stash0
backup/macos01-20261106/claude/stash-0
backup/macos01-20261106/claude/stash-1
backup/macos01-20261106/claude/J80-macos-s1
backup/macos01-20261106/claude/J80
backup/macos01-20261106/claude/J80-slice1-20261102
backup/macos01-20261106/claude/J16b-appwin-on-dev
backup/macos01-20261106/claude/appwin-launch-idle-146
backup/macos01-20261106/claude/J80-s1-run
wip/j259
trust-285-p3c
runtime-lock-j216f
mesh-ssh-p3-j175
tun-proof-p3b
trust-285-p3
terminal-polish-j271
tun-proof-p3
ssh-install-flakes-j216i
fuzz-fixes-j264
trust-285-a
trust-285-b
restart-oversized-fixture-j198
backup/macos01-20261106/lume/appwin-icons-j207
restart-bound-j216h
up-preflight-p3-j198
backup/macos01-20261106/lume/j251
up-preflight-j198
wip/up-preflight-j198-j245-p2
wip/up-preflight-j198-j245-p1
agent-fsync-offloop-j196
wip/up-preflight-j198-j245
settings-offscreen-j231
wip/up-preflight-j198-j226-inspection
wip/j103f
themes-j206
wip/up-preflight-j198-j226
flakes-j216c
backup/macos01-20261106/claude/j197
flakes-j216b
backup/macos01-20261106/claude/j197-red
wip/up-preflight-j198-review
flakes-j216
backup/macos01-20261106/claude/appwin-icons-j207
engineering-j208b
appwin-mock-j209
toast-stack-j165
engineering-j208
decisions-d351
decisions-d350
decisions-d349
appearance-presets-mock-j129
decisions-d348
docs-audit-spec
doc-coverage-baseline-raise
decisions-d347
decisions-d346b
decisions-d346
j88h-profile
ui-consistency-j195-deferred
ui-consistency-j195
engineering-practices-j194
preferred-login-ui-j166
signin-pools-263-j174
macos-node-265-s1
decisions-d345
decisions-d344
proxy-cgroup-j164
verify-quick-fuzz-329
proxy-start-io-j168
timing-flakes-j163
up-263-s1
mcp-events-j147
verify-quick-fuzz-j158
proxy-p3-j159
agent-resource-j157-detect
wip/j103d-final
remote-cancel-hang-j155
proxy-traefik-281-j62d
j149-verify-quick
proxy-traefik-281-j62b
j150-drop-unnamed
wip/j79d-red-r4
wip/j103d-d332
rootless-toast-j142
wip/j103d-head
wip/j103d
j125c-mcp
macos-build-j136
backup/macos01-20261106/claude/j136
wip/j79d-red-cli
wip/j79d-red-server
j121-link-liveness
j118c-tracer-failures
wip/j79c-head
release-desktop-j131
j124c-signed-macos
wip/j79c-red-p3
wip/j79c-red-p23
wip/j79c-red-p22
merge-j128-check
perf-deferred-j128
sidebar-toggle-260
j127-shortcut-changed-dot
j125-mcp
j118-tracer-failures
j126-account-summary
settings-sections-mock-j92
j120-pinch-lock
sidebar-292
backup/macos01-20261106/claude/j120
taste-2026-11-03
row-actions-242-215
backup/macos01-20261106/claude/stash-0-untracked
backup/macos01-20261106/claude/J80-265-s1-run
backup/macos01-20261106/claude/J80-macos-s1-20261102
j112-canvas-commands
ui-no-overshoot-scroll
fix-recovery-restart
backup/macos01-20261106/claude/stash-1-untracked
taste-2026-11-02
size-baseline-ratchet
machine-cards-structure-j108
j109-boot-copy-mockups
fix-dev-red
wip/up-263-s1
j95b-settings-rows
proxy-traefik-281
j95-option-rows
docs-human-j91
docs-keys-palette
fix-flood-1013-270-j38d
mesh-ssh-s1
mesh-ssh-s0
addhost-d291-tunnel
test-stability-load
mesh-relay-220
repro-296
shim-thp-off-24
mesh-pins-258-v2
mesh-dns
signin-d311-merged
docs-pages
ui-size-283
fix-ui-batch-specs
wip/j12b-edge-update
gate-on-arm
fix-rename-sync-293
trust-285-j60b
fix-focus-ring-clip
integ-ui-1101
edge-update-v2
signin-d311
taste-2026-11-01
layout-per-tab-250
ui-approved-splitopt-224
ui-approved-splitopt-224-on-dev
icon-text-centre-282
ui-approved-189-212-216
research-reverse-proxy
transfer-budget-320
review-mesh-pins-258-r2
sidebar-pill-259
review-mesh-relay-220
wip/j12-edge-update-v2
nix-package
status-crash-loop-237
fix-dev-test-failures
fix-fixture-socket-path
wip/mesh-relay-220-pre-dev-advance-rebase
fix-canvas-side-clip
research-head-to-head
frosted-real-256
review-mesh-pins-258
wip/mesh-relay-220-pre-final-rebase
review-layout-per-tab-250-r2
broad-suite-triage
nix-devshell
review-status-crash-loop-237-r3
wip/nix-devshell-pre-p3
taste-frosted-real
wip/code-serve-demo-2026-10-30
wip/code-serve-glass-2026-10-30
wip/code-serve-clusters-2026-10-30
wip/code-merge-release94-dev-2026-10-30
wip/rproxy-delta-scratch-2026-10-30
wip/stale-note-257-staged-2026-10-30
wip/d241-size-staged-2026-10-30
review-broad-suite-207
wip/mesh-pins-258-pre-split
wip/mesh-relay-220-pre-rebase
mesh-measure-220
plan-211-update
review-edge-autoupdate-r3
perf24-reconnect
review-stale-note-r2
release-prod-live
d241-shell-marker
review-mesh-pins-server-258
review-revocation-r3
review-setup-token-r2
review-sync-journal-r3
wip/review-mesh-pins-258-prune-review-1995fee46
frosted-scroll-256
sync-journal-r3
revocation-per-account-wip
review-tokio-asyncfd-0386
review-sync-p3s
wip/stash-8by64-stash0-2026-10-30
mesh-drag-r2
setup-token-data-wip
release-9-4
auth-busy-1013
mesh-view-overlap
sync-p3s
review-auth-busy-wake
review-readd-r8-wip
mesh-drag-bounds
audit-auth-93
app-windows-stream-start
review-authority-cap-r3
app-windows-r7-measure
readd-minimal-r6
readd-minimal-r5
app-windows-r7-soak
readd-minimal-r4
app-windows-r7
app-windows-r6
readd-minimal-r3
readd-minimal-r2
readd-minimal
merge-release8-dev
review-busy-page-liveness-r2
review-busy-page-liveness
mesh-view-trim
review-authority-read-retry-r2
review-remove-uninstall-r2
release-retry-reattach
release-retry
review-remove-uninstall
review-authority-read-retry
app-windows-ship
mesh-autoswitch-p2
mesh-ssh
mesh-relay
mesh-macos-node
screen-and-control
session-labels
review-real-logins-r5
review-real-logins-r4
review-real-logins-r3
shim-memory-r2
review-real-logins-r2
shim-memory
shadow-addhost-instant
shadow-real-logins
shadow-same-session-flood
shadow-prod-perf-fix
hosts-from-server
app-windows-real
app-windows-transport
release-prod-6w
mesh-policy-verify
quiet-close-toast
dev-merge-r4
review-mesh-agent-transport
review-app-windows-transport
settings-roundtrip
review-release-pipeline-r4
mesh-agent-transport
ended-strip-fix
review-audit-ca-update-d244
settings-rows
phone-width
signout-clear
fix-restart-tests
dev-merge-rp
signer-hardening
review-audit-ca-update
terminal-fidelity
review-audit-ca-update-wip
mesh-integrate
review-mesh-agent-transport-515d3712
review-mesh-dataplane-feec1988
mesh-dataplane
signout
research-canvas-node
wip/review-renderer-cost
wip/review-terminal-fidelity
padlock-glyph
review-release-pipeline-2e95b689
phone-polish
sidebar-polish
inbox-generic
review-mesh-dataplane-378d4055
prod-batch
ui-inbox
ui-ca-unlock
ui-machine-sections
review-mesh-dataplane-a5f744fb
tls-session-prod
session-bounds-prod
fix-dead-session
session-bounds
tls-session
palette-polish
shortcuts-d222
research-appmeta
phone-gutter
ui-centre-button
wip/ui-centre-button
wip/tls-session
review-addhost-breakit
ui-platform
renderer-cost
remote-agents
mesh-api
ssh-bootstrap
prod-hotfix2
prod-fixes
review-remote-agents
review-mesh-dataplane
session-life
research-browser
review-mesh-api
research-capture
review-mesh-api-round3
review-mesh-api-round1
gate-stability
review-gate-stability
review-relay-direct
review-mesh-api-findings
proto-sessions
font-picker
proto-addhost
proto-windows
mesh-core
latency-gate
research-bsd
research-discovery
keytray-mods
mock-core
ui-tweaks
fix-motion-sel
fix-motion
integrate2
fix-robust
t-web
t-server
vt-ghostty
fix-snap-echo
t-web-auth
review-vt2
t-agent
lane-protocol
lane-shim
lane-auth
s1-base
s1-contracts
s1-workspace
No results found.
No labels
launch-qa
Milestone
Clear milestone
No items
No milestone
Projects
Clear projects
No items
No project
Assignees
Clear assignees
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#391
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
J300: the host-removal confirmation is badly designed (owner, production
74b9c4d80)Owner reaction: "wtf?" and "it's just that the removal design is really bad!"
Screenshot (attached below): terminal window on host
sshopen, "Remove code?" shown anchored to thesshwindow's machine pill.What is wrong:
codebut points at thesshwindow's pill.Plan (redesign, not a patch), TASTE row "A confirmation belongs to what it acts on":
mountConfirmTipcaps and never wraps a button label past the edge.Branch
fix-removal-confirmfrom origin/dev (base5f529c3c8). Estimate: ~2 h.Started. Branch
fix-removal-confirm, base5f529c3c86(origin/dev). Worktree on code: ~/Developer/Worktrees/infraternal-j300. Builds and browser specs go to compute01 through build-slot.Finding: the palette path (
palette-actions.on-demand.tskindremovehost) anchors toactive?.card.pill, the focused window, not the removed host.host-removal.on-demand.tspasses the server actionlabel(a description) asconfirmLabel.Progress (head 2f59e6a86 on
fix-removal-confirm, pushed).verify quickis queued on compute01 (build-slot position 9); result follows.Evidence (compute01
~/.cache/codex-scratch/j300/, local copies /tmp/j300/shots on the control host):red.log, 12 of 12 fail, first assertiondata-sideisbottom(anchored to the focused window's pill) instead ofcenter.host-removal-confirm.spec.ts, 12 tests (1440x900, 393x852, 375x667 x ink/paper x overview/dense terminal): the 6 overview cases passed in run7 (57.6s), the 6 dense cases passed in run9 (1.4m). Screenshots inevidence/removal-confirm/*.png.What changed: palette removal passes no anchor, so the shared
mountConfirmTipcentres it (no tail). Buttons are "Remove " and "Keep", side by side, labels capped at 28 chars with an ellipsis inside the button. Confirmation blur is 32 px at every card level. The server action's description is no longer used as a button.Caveats: the spec asserts the blur from the computed
backdrop-filter, not by reading pixels. On desktop the dense capture mostly covers empty terminal rows, so no text sits directly behind the card there.Correction and status. The pushed head is
d5edf50b1790c089a3a75586cda7f138a37d1a33(the earlier comment's 2f59e6a86 is the same commit rebased onto the VM's origin/dev).verify quickrun 1 (~claude/.cache/codex-scratch/j300/quick.log): FAIL on one row, "doc comments on diff" (8 touched items without a D345 comment); every other row printed PASS (scope guard, migration names, Nix Cargo vendoring, fmt, doc coverage ratchet, shape lints, fixed test waits). Fixed in the second commit (comments only). Rerun is queued asquick2.log.Blocked: compute01 is at 21 GB free (floor 25 GB), so build-slot is holding every queued job, mine included (13 queued). My own footprint is about 1 GB. Other jobs' targets are the cause; I did not touch them. I will keep polling.
Finished. Head
d5edf50b1790c089a3a75586cda7f138a37d1a33onfix-removal-confirm(pushed, two commits on origin/dev5f529c3c8: the redesign, then comments the doc gate asked for). Not merged.scripts/verify quick(compute01,~claude/.cache/codex-scratch/j300/quick2.log), verbatim:Not run:
scripts/verify fast(the task asked forquick). Spec:host-removal-confirm.spec.ts, 12 tests, red on origin/dev (12/12), green on the branch (6 overview in run7, 6 dense in run9). Screenshots: compute01~/.cache/codex-scratch/j300/evidence/removal-confirm/and /tmp/j300/shots on the control host. Caveats: blur is asserted from computedbackdrop-filter, not by reading pixels; on desktop the dense capture mostly covers empty terminal rows. OthermountConfirmTipcallers already use short verbs; the new 28-character cap and ellipsis inside the button protect them all.J313 review of
fix-removal-confirm@d5edf50b1: REQUEST CHANGESMethod: production tracer build on compute01 (worktree
~claude/worktrees/j313, port 4813, DPR 2). Scratch-only patch to the test double, not for merge: every host shows a 70-linels -la, and__j313exposes the canvas context. Spectest/j313-review.spec.ts, 18 of 19 checks ran, log~claude/j313-run.log, shots~claude/j313-shots/(24 PNGs, copy at /tmp/j313/shots on the control host). I also looked at all 12 of J300's shots.1. BLOCKER: text is still legible behind the card on desktop (the owner's third complaint is not fixed).
Owner's case: dense
ls -lain host A's windows, "Remove a host" for host B from ⌘K at 1440×900. The card sits centred over the nix-cache window. In the 2× crops (A-palette-desktop-ink-crop.png,A-palette-desktop-paper-crop.png) I can read rows behind the card: "-rwxr-xr-x. 4 root root 16709 Nov", ".bash_his", ".bashrc.b", "infraternal", "authorize", and "-rw-r--r--. 3 root root 157…" under the Keep button. The same ghosting shows in the pill-anchored shotC-pill-desktop-ink.png("100 Nov", "1077 Nov", "lrwxrwxrwx"). Computedbackdrop-filterisblur(32px) saturate(1.6)on the tip, so J300's spec passes, but pixels show the blur does not reach the terminal text. Likely the terminal text is drawn on a layer outside the tip's backdrop root, or an ancestor stops it. This is what J300 flagged as unverified, and it fails. TASTE "Glass shows colour, never legible text" is violated in ink and paper. Fix: find why the backdrop does not blur the terminal layer (or give the confirmation an opaque or near-opaque fill over text-dense content), and make the spec read pixels (screenshot crop vs a reference) instead of the computed style.2. Phone: not proven either way. At 393×852 and 375×667 the focused window is
build-01, whose screen stays at an empty$in the double, so there is still no text behind the card on phone (my dense patch did not reach that window). Layout is fine in all 12 phone shots (centred, 9 px insets, both buttons inside, no tail). The ghosting finding from #1 will apply there once text is behind it.3. Long names: the 28-char truncation cuts badly.
infraternal-dev-02-std.vpn.kayg.orgrenders the button as "Remove infraternal-dev-02-s…" (B-long-phone-paper.png, all 6 long-name shots the same). It cuts the identifying "std" and ".vpn.kayg.org", so two similar hosts would look the same. The title already shows the full name and wraps cleanly (Remove infraternal-dev-02-/std.vpn.kayg.org?). Recommend: button "Remove" plus "Keep", name only in the title (the title says what is being removed, which also removes the repeated name). Keep the 28-char cap as a safety net inmountConfirmTip, but the host-removal button should not rely on it. The button'saria-labelkeeps the full text today; keep that.4. Anchoring from the host's own pill: OK. With the removed host's own window pill as anchor (nix-cache while another window is focused),
data-side="bottom", the tail points at that pill, and it is clear of the focused window's pill (C-pill-*, 6 shots). Caveat: I calledhostRemoval.remove(…, pill)directly. I did not drive the real sidebar row action or the machine-details "Remove host" button, which were not exercised.5. Keyboard. Initial focus is "Keep". Tab goes Keep → "Remove edge-arm" → out of the popover to the page behind (not trapped; same as the other confirmations, noting it). Escape closes it with no removal and no toast. Enter immediately after opening: my spec step failed on a bug of mine (the second palette open), so I did not observe it. Because focus starts on Keep, Enter means Keep, so an accidental Enter cannot remove. Untested, not observed to fail.
Also fine: centred within ±1 px, no tail from ⌘K, Keep and Remove on one centre line, both inside the box, no clipping at 375 px, 12 of J300's shots look right on layout.
Needs before approval: fix #1 with a pixel-level check over dense text on desktop, recommend change for #3, and put real text behind the card on phone for #2.
Round 2 status (J300), head
775d8ffdc56ac55cbaf17dfb6f00392347a0cd60onfix-removal-confirm, pushed. Not merged.Approach changed after J313's review (comment 82668), as the orchestrator directed: the confirmation is now a solid card, not glass.
mountConfirmTipfills with--overlay-solidand drops the backdrop filter at every transparency setting, including reduced transparency. All confirmations get it.host-removal-confirm.spec.tswrites a dense listing into the live terminal and the preview windows, then compares screenshots with and without the terminal stage: no pixel inside the card may change (inset 8 px, delta over 7 of 255), while more than 2000 pixels around it do. It also covers Enter right after opening (focus starts on Keep, so the host stays).Evidence so far (compute01
~/.cache/codex-scratch/j300/):r2d.logrun before the tolerance change plus theevidence/removal-confirm/*.pngset I looked at: 6 screenshots (1440x900, 393x852, 375x667, ink and paper), dense text all around, solid card, nothing readable inside it, including over the live terminal on phone.red2.log): paper fails at all three sizes (58468, 40229 and 38039 pixels changed inside the card). Ink passed at the old threshold, which is why I lowered it to 7.Not finished: the red and green rerun at the final threshold, and
verify quick. The firstverify quickof this round failed the tracer typecheck row on my spec (array destructuring under noUncheckedIndexedAccess); fixed in this head. All of those were queued on compute01 when its maintenance froze build-slot; the restart will cut them, so that is not a test failure. I will resubmit once, in the foreground, after the orchestrator posts that compute01 is back.Open for the owner: TASTE row "Floating cards are clearly translucent" still lists confirmations among the glass cards; it needs an amendment, which I have not edited.
Round 2 results at the final threshold (head
775d8ffdc; on compute01 the same three commits sit on origin/devfba745051). The compute01 restart did cut the earlier queued runs; these are the resubmitted ones.Red/green of the pixel spec (
host-removal-confirm.spec.ts, 7 tests; per-pixel delta over 7 of 255 counts, inside the card inset 8 px):~claude/.cache/codex-scratch/j300/r3a.log, second half).blur(32px)(~claude/.cache/codex-scratch/j300/red2.log): 6 of the 6 size/theme cases fail, in ink and in paper. Pixels changed inside the card: desktop ink 28078, desktop paper 58701, phone ink 6956, phone paper 40461, small-phone ink 1196, small-phone paper 38251. The Enter test passes in red, as it should (it does not depend on the fill). So ink is caught too; no further tightening was needed.Screenshots, production build, dense
ls -lain the live terminal and every preview window, card started from the palette (attached below; alsocompute01:~/.cache/codex-scratch/j300/evidence/removal-confirm/). I looked at all six: card centred, tail-less, "Keep" and "Remove" side by side inside it, full host name in the title, solid card in both themes, no terminal text readable inside it, including over the live terminal on phone.verify quickis still waiting in the build-slot queue (position 18 for over an hour); result follows.Finished round 2. Head
775d8ffdc56ac55cbaf17dfb6f00392347a0cd60onfix-removal-confirm(pushed, not merged).scripts/verify quickon compute01 (~claude/.cache/codex-scratch/j300/quick5.log, tree = these three commits on origin/devfba745051), verbatim:Not run:
verify fast(the task asked for quick). Red/green and screenshots are in the previous comment. The TASTE row "Floating cards are clearly translucent" is untouched.J300
verify faston head775d8ffdc56ac55cbaf17dfb6f00392347a0cd60(exact commit, base37c93637e; compute01,nix develop -c cargo --version= cargo 1.99.0 first; log~claude/.cache/codex-scratch/j300/fast1.log). Result: FAIL, one row:test(exit 101). Every other row PASS or SKIP (privileged integration SKIP: no install/proxy/mesh/shim change). Verbatim:Both failures are
Elapsedtimeouts ininfraternal-agentremote_client::server_pathtests (timing-sensitive, run with all 5 slots busy). My diff is tracer UI andpackages/uionly (7 files, no Rust). I am running exactly those two tests on unmodified origin/devfba745051to prove they fail without my change; the result follows. I have not changed the branch.J335 review of
fix-removal-confirm@775d8ffdc5(round 2): REQUEST CHANGESThe owner's three complaints are fixed in pixels. Two existing browser specs now fail because of the change, though, and J300 only ran
verify quick, so nobody saw them.Method: production tracer build on compute01 through build-slot (worktrees
~claude/worktrees/j335= branch,j335-base= origin/devfba745051;nix develop … cargo --versionchecked first). DPR 2. Phone sizes run in a touch context (hasTouch,isMobile, sopointer: coarseis true; J300's spec runs phone sizes with a mouse). Densels -lain the live terminal and every preview window. Scratch specj335-review.spec.ts(not for merge), logs and metrics incompute01:~/.cache/codex-scratch/j335/evidence/(run-branch.log,run-base.log,run-existing.log,run-existing-base.log,metrics-{branch,base}.jsonl, 56 PNGs). Spec result: 21 of 27 passed on both branch and base; the 6 red are my "details popover" step (a harness bug of mine, never reached the card), so the machine-details "Remove host" button is not exercised.Findings
P1. The change turns two existing browser specs red (they pass on origin/dev).
add-host-prototype.spec.ts:240"the shared confirmation is compact, icon-only and quiet on open": expects the confirmation to share the card material, gotrgb(30,31,33)/noneagainstrgba(28,28,30,0.7)/blur(8px) saturate(1.6).mesh.spec.ts:1226"every glass surface of the Mesh view blurs…":expect(blur(tip)).toBeGreaterThanOrEqual(16), got 0.Both encode the old translucent rule, so they need updating together with the TASTE decision (below). Proof they pass on base:
run-existing-base.log(3 passed, which includes both); fail on branch:run-existing.log. Ten other failures in that run (startup-demo ×6, sign-out ×2, mesh:360, sessions-canvas:171) fail identically on origin/dev, so they are not from this change.P2. Escape on a palette-started removal drops focus to
<body>. A centred card has a detachedspanas anchor, soclose(true)skipsanchor.focus()(anchor.isConnectedfalse). Measured:F-focus-after-escape→BODY. From the sidebar the same Escape returns to the host row (LI|h:edge-arm,E-focus-after-escape). A keyboard user who opened ⌘K from the terminal loses the terminal. Fix: rememberdocument.activeElementat mount and restore it when centred.P2. Spec teeth are uneven. J300's own red run (
red2.log) caught small-phone ink with only 1196 changed pixels, and the "teeth" check (outside > 2000) counts the whole screen, not the strip behind the card. A card placed over a blank part of the terminal would pass a translucent fill too. It did not pass vacuously here (6 of 6 red; I read the pictures: dense text sits right behind the card in all 6), but the ink margin on small phones is thin. Suggest requiring changed pixels in a band around the card (e.g. 40 px) and not only anywhere. Also: the spec's phone cases use a mouse context, so the 44 px touch target is not tested by it. I measured it: 44×44 px on all phone buttons (below).P3. Centred card is 625 px wide on desktop (anchored ones are 374–487 px), because the centred branch sets
maxWidth = innerWidth − 18and overrides the CSS cap, so the effect line runs on one long line. It looks like a banner, not a compact question (branch-A-palette-desktop-ink.png). Cap it at the same width as anchored cards.P3. Enter right after opening is only partly observed. J300's spec covers Enter once the Keep button has focus. In my probe (Enter pressed 0, 16 and 60 ms after the card opened) the host was never removed (
F-immediate-enter,removedToast: 0), but the card also stayed open in all three, so I could not show "Enter keeps" for the unfocused window. Safe, not fully proven.P3. Tab leaves the card (Keep → Remove → page): not trapped, same as the other confirmations. Screen reader:
dialog "Remove edge-arm"with paragraph, paragraph, buttons "Keep" and "Remove" (G-aria); the title and effect are not wired witharia-labelledby/aria-describedby. Fine, noting only.Checks
metrics-branch.jsonl, labelA-palette). Centred, no tail, solid: inkrgb(30,31,33), paperrgb(252,252,252),backdrop-filter: none, at 1440×900, 393×852 and 375×667. Title carries the full name, buttons are "Keep" and "Remove", both inside the box, nothing clipped, no readable text inside the card in any of the 6 shots. Touch: Keep and Remove are 44 px high (60 and 78 px wide) on both phones; cards are 375 and 357 px wide (9 px insets). Desktop buttons are 30.8 px (mouse), fine. Anchored to the host's row: from the sidebar (Deleteon theedge-armcaption) the tail points at that caption and the card is clear of the focused window (E-sidebar,side: bottom).mountConfirmTipcallers; all take the solid fill): end session (C-end-*), sign out of this device (D-signout-*), mesh grant move/remove, sidebar remove. Captured end session and sign out at 3 sizes × 2 themes: opaque, anchored to the pill or row, inside the window, icon buttons 44×44 on phone, focus ring preserved on Keep (the existing tests for sign-out touch targets, mesh copy and sidebar Escape all pass on the branch). Not captured by me: add-host and setup-pill confirmations, the settings "Revoke", startup notice (their existing specs pass except startup-demo, which fails identically on base). Access-level "full access" panes use.ui-confirm-bar, not the popover, so they are unchanged.host-removal-confirm.spec.ts7 of 7 pass inrun-existing.log). I did not rerun J300's red (it reverts the fill); I readred2.logand the paper pictures instead: paper reds are large (38–58k px), ink small-phone is 1196 (see P2).rgba(251,251,251,0.78)+ blur 8 px, paper) the row text "785 Nov / 6:16 / 7:17" ghosts through the card edge and beside the buttons (base-A-palette-desktop-paper-crop.png), which is what the owner complained about; on the branch nothing shows through (branch-A-palette-desktop-paper-crop.png). The cost: the card no longer matches the machine popover and add-host card, which stay glass. Two TASTE rows now disagree with the code: row "Floating cards are clearly translucent" still names confirmations, and "A confirmation belongs to what it acts on" still says "the popover's glass hides the terminal text". The owner decides; I did not edit TASTE.Screenshots attached: branch desktop ink/paper, phone ink, small-phone paper, sidebar-anchored, end session on phone, and base desktop paper/phone ink for the comparison.
Verdict: REQUEST CHANGES (P1: update the two stale specs together with the TASTE amendment; P2: restore focus when centred, tighten the spec's teeth).
Follow-up on the
verify fastfailure (previous comment). The branch changes no Rust, so I tested whether the two failinginfraternal-agenttests fail on unmodified origin/dev (fba745051):--features remote(~claude/.cache/codex-scratch/j300/base2.log): both pass,2 passed; 0 failed ... finished in 1.34s. (A first attempt without--features remotematched 0 tests and proves nothing;base1.log.)base3.log):284 passed; 0 failed; 23 ignoredon each of the three runs (46 s, 59 s, 72 s).So I could not reproduce the failure on origin/dev. It is not proven pre-existing, and I am not calling it one. The failing run was on a tree based on
37c93637e, older than dev, on a loaded machine.Because
fastfailed, I changed the branch once, as allowed: merged origin/dev into it (clean merge,775d8ffdcstays an ancestor, so J335's review target is intact). New headf9c86fe8c1086b2f83dafc846cd59d6bf3f27b9a. The merge brings one tracer file I did not touch (terminal-refusal.ts, 2 lines) and Rust changes from dev.verify fastis rerunning on the merged head, in the foreground through build-slot; result follows. If it fails the same two tests again on the merged head, I will say so and report it as unexplained rather than waving it off.J300 round 3: the removal confirmation stays glass, and no text behind it is legible. Head
af611ef1957598fa82944662a7d366fb89f65ae5onfix-removal-confirm(pushed, not merged;f9c86fe8c, the commit J335 reviewed plus the dev merge, is still its ancestor). Owner: "Keep glass, fix contrast".What was really wrong (this is not a tuning problem). I measured the material over a dense
ls -lain a production build. A card's ownbackdrop-filterfades at the edges of its box, so the unblurred page shows through, and on a ~118 px card that edge zone is most of the card. More blur makes it worse:blur(32px)correlated 0.72 with the unblurred text,blur(8px)0.41, andblur(64px)0.88. No CSS variant on the card itself (no saturate, square corners, own layer, will-change, no shadow or border) changed anything, so stronger blur or tint in the shared material cannot satisfy "no glyph legible". The same blur on an oversized layer clipped to the card correlates about 0 at every strength. Probe outputs:dev-02:~/.cache/codex-scratch/j300/probe{3,4,5}.log(PROBE lines).Change (3 commits,
be8a872d9-equivalent after a fixup rebase):packages/ui: new sharedglass-bed.tsplus.ui-glass-bedin the sharedstyles.css: an oversized, clipped, 32 px blurred layer under the card (about 1.5 terminal lines). The card keeps its own translucent material on top, so it is still glass and colour shows. Off when the card has no blur (Solid level, reduced transparency).mountConfirmTipuses it; the opaque--overlay-solidchange is reverted. Also in the shared confirmation:aria-labelledby/aria-describedby, a centred card obeys the stylesheet width cap (374 px at the desktop root size, was a 625 px banner), and a centred card returns focus.binding.focusasreturnFocus(not on touch).host-removal-confirm.spec.ts+glyph-legibility.ts+removal-fixture.ts.The spec measures pixels, not computed styles. It high-passes the card's region with and without the card and bed (card's own text masked out) and correlates them: about 0 means the glass turned text into colour and shape, toward 1 means strokes survive. It also requires stroke energy behind the card above a floor (about 50 against a limit of 6 here), so a card over blank terminal cannot pass vacuously. 3 viewports x ink/paper x Solid, Tinted, Clear, Frosted; phones run as touch devices (44 px targets asserted).
dev-02 ~/.cache/codex-scratch/j300/final.log): 25 of 25 pass; correlation at most 0.089 in all 24 legibility cases (0.000 Solid; Frosted 0.066 desktop ink, 0.088 phone ink, 0.058 small-phone ink).red.log): 17 fail: 16 of the 18 translucent cases at correlation 0.40 to 0.78 (desktop ink Tinted 0.413, desktop paper Tinted 0.399, phone ink Tinted 0.449, Frosted 0.67 to 0.78), plus the focus test. The two small-phone Tinted cases measure 0.14 and 0.10 on today's material and pass; the threshold is 0.2, so they are not claimed as caught.BODYbefore the change (green.logof the earlier run: "focus is on BODY#."), on the clicked terminal after; Enter right after opening and again once Keep is focused never removes the host.J335's two stale specs (
add-host-prototype.spec.ts:240,mesh.spec.ts:1226) pass again with the card translucent:dev-02 named.log:2 passed.Screenshots, production build, dense listing in the live terminal and every preview window, lowest transparency (Solid) and highest (Frosted), ink and paper, 1440x900, 393x852, 375x667 at 2x. I looked at all 12, plus Tinted desktop paper and Solid/Frosted phones: the Frosted ones show colour and shape through the card and no readable character; Solid is a plain opaque card; Keep and Remove side by side, inside the box, full host name in the title; layout unchanged from round 2. Attached below (all 24 PNGs live in
dev-02:~/.cache/codex-scratch/j300/evidence-f/removal-confirm/, since deleted with my worktree; the 12 attached here are the record).verify quickon dev-02 (~claude/.cache/codex-scratch/j300/quick7.log), verbatim:(An earlier run of the same head failed "doc comments on diff" for two items; fixed in the commits above.)
Not done / for the orchestrator:
verify fastnot run this round (task asked for quick). The round-2fastruns had a different, unexplained timing failure; see the earlier comments.attachGlassBed(card)in one call, each with its own check. I did not change them. Worth a decision.J344 review of
fix-removal-confirm@af611ef195(round 3, vs origin/devaf033d0b4): REQUEST CHANGESThe bed does what the owner asked for in the card's interior: no character is legible at any level, and colour and shape still show through. Two things stop me approving. A faint but readable trace of text survives in the card's outer rim at Clear and Frosted. J300's spec cannot see that rim, so "no readable character" is slightly overstated. No P1.
Method: production tracer build on dev-02 through build-slot (worktrees
~claude/worktrees/j344= branch,j344-base= origin/dev). DPR 2. Phone sizes are touch contexts. Densels -lain the live terminal and every preview window. My scratch specj344-review.spec.tsis not for merge. Everything is indev-02:~/.cache/codex-scratch/j344/(logsr1..r5*.log,ev-r*/j344/{shots.jsonl,focus.jsonl,perf.jsonl,others.jsonl}, about 280 PNGs). I did not runverify.Findings
P2. Faint, readable text remains in the card's outer ~12 px rim at Clear and Frosted.
Zooms:
edge-sheet.png(desktop ink Frosted, right edge) andcorner-sheet.png(phone ink Frosted, bottom rim). Top = with bed, middle = bed hidden, bottom = the page without the card. In the phone crop a faint "2 1" and the tops of "Nov" are readable inside the rim. They are low contrast but characters.Pixel numbers (my metric, a 3–8 px ring just inside the card edge, high-pass correlation with the page behind): without the bed 0.85–0.94 (desktop, small phone) and 0.41–0.49 (phone). With the bed 0.24–0.29 on desktop and small-phone ink Clear and Frosted, 0.10–0.15 on phone, and 0.03–0.12 on Tinted. Stroke energy in the ring falls about 97% (desktop ink Frosted 16.3 → 0.49), so the bed works, but a trace is left where a text row straddles the card edge.
J300's inner region starts 8 px inside the card, so the spec never looks at this band. Suggest: measure a ring band too (without the bed it is 0.85+, so a threshold near 0.5 separates cleanly), then find why the rim leaks (my guess: the card's own backdrop blur, still 32 px at Frosted, re-reads the unblurred page at its edge). Possibly the card should drop its own blur where the bed provides it.
P2. The spec cannot tell glass from opaque, and its red/green split rests on the inner region only.
Delete, pill) is not pixel-checked. In my sidebar-started captures only 3.5–29 stroke energy sits behind the card (mostly sidebar blank), so my sidebar numbers prove little too. I read the pictures: no readable text, but this case has no real test.P3. The confirmation is no longer the same material as the other cards. Its effective blur is the bed's 32 px at every level (Tinted is 8 px on the machine popover and add-host card), and the saturation stacks twice (bed and card both
saturate(1.6)). TASTE says "one shared material, tuned once, never per card". Fine if the owner accepts it for small cards, but it should be stated in TASTE. I did not capture a side-by-side over colour.P3. Over a monochrome terminal the levels look almost the same. On ink, Tinted, Clear and Frosted are barely distinguishable from Solid (
levels-phone-ink.png,levels-small-phone-ink.png). On paper Clear and Frosted are visibly greyer. Over coloured content the glass is clearly there and the levels differ (sheets-colour-desktop-ink.png,colour-trio.png). That is the nature of fog from white text on black, not a bug, but the owner's old line "I genuinely can't see the difference between the 4" can come back on a dense plain terminal.P3. Tab leaves the card (Keep → Remove → page). Not trapped, same as the other confirmations; unchanged from J335's note.
Checks
levels-*.png, 2×2 grids: Solid top-left, Tinted top-right, Clear bottom-left, Frosted bottom-right). No whole character is legible inside the card at any level; Solid is a plain opaque card; buttons sit side by side inside the box; the full host name is in the title. Visibly glass: yes over colour (middle panel ofcolour-trio.pngshows the card taking the warm tint of the blocks behind, no text), marginal over a plain monochrome listing (P3 above). Not effectively opaque: with colour behind, shape correlation is 0.3–0.5 at the three glass levels. Edge rim: see the first P2.perf.jsonlinev-r3-perf-branchandev-r4-base). At 1× CPU, p95 frame 16.7–16.8 ms and zero dropped frames in all variants. At 4× CPU throttle: bed 5 single 33 ms frames out of 2398, bed hidden 0 of 2296, origin/dev (anchored card) 4 of 2406. So no measurable jank versus origin/dev; the 0 vs 5 gap is within what base also shows. Median RasterTask about 2.0–2.2 ms with the bed against about 1.5–1.8 ms on base at 1×; Paint, Layerize, UpdateLayer equal. No long tasks. Caveat: this is not a phone GPU, and I did not measure on a real device.focus.jsonl): palette-started with the terminal focused: Escape returns to#terminal-host(Terminal input); clicking Keep also returns there. Sidebar-started (Deleteon theedge-armcaption): the card is anchored (data-side=bottom), initial focus Keep, Escape returns to theLI.bm-row[data-id=h:edge-arm]. On both phones (touch, nothing focused) Keep tap and Escape leave focus onBODY, not on an input, so no keyboard is summoned. Tab: Keep → Remove → BODY → the page (not trapped; P3).dialogis named by its title ("Remove edge-arm?") and described by its effect line ("Revoke its access, forget its SSH key and uninstall the infraternal agent.") througharia-labelledbyandaria-describedby. Touch targets: Keep 60×44 and Remove 78×44 on both phones. Width cap: 374 px on desktop at root font 17.6 px (21.25 rem), 340 px on the phones.add-host-prototype.spec.ts:240andmesh.spec.ts:1226pass. J300's own spec file runs 25 of 25 green and its Escape/Enter test passes:r1-specs.log,27 passed (4.0m). The correlations match J300's (max 0.089; my own run of the same cases gives max 0.094).others.jsonl, 40 captures at Tinted and Frosted, ink and paper, 3 sizes). Correlation uses the whole card minus its own text.toast-desktop-ink-frosted.png,toast-phone-paper-frosted.png). Worst of the four; tiny card.machine-desktop-paper-frosted.png: "lan-links.c", "authorized_key", "-rw-r--r--. 2 root root 10649 Nov 6" readable). Frosted phone sizes 0.15–0.24 inside.tooltip-desktop-paper-frosted.png); corr numbers are meaningless there. Over terminal text it has the same edge zone; not captured on touch (long press), say so.addhost-desktop-ink-frosted.png; 0.1–1.2 energy behind).So J300's claim holds for the toast and the machine popover; the tooltip and add-host card could not be shown with this fixture.
Screenshots (attached)
levels-desktop-ink/paper,levels-phone-ink/paper,levels-small-phone-ink/paper(the 24 level cases as six 2×2 sheets),edge-sheet,corner-sheet,sheets-colour-desktop-ink,sheets-colour-phone-paper,colour-trio,sidebar-phone-ink-frosted, and the origin/dev cardstoast-desktop-ink-frosted,toast-phone-paper-frosted,machine-desktop-paper-frosted,tooltip-desktop-paper-frosted,addhost-desktop-ink-frosted.Not done: no real-device or Mac GPU frame measurement; no
verifyrun (reviewers don't); product (non-test-double) path not exercised.Verdict: REQUEST CHANGES. Fix and prove: the rim trace (P2) and add a ring check to the spec (P2). The rest is P3 for the owner. Head reviewed:
af611ef1957598fa82944662a7d366fb89f65ae5.J300 round 4 (J344's findings). Head
eee0ed2a9c4f1fafbf8a28287e5f75c877a03cbfonfix-removal-confirm(pushed, not merged):654e2034dplus a merge of origin/dev (37 commits). Material commit604baef3b, spec commit654e2034d. Toast and machine popover untouched, as asked.P2 edge trace. The bed reached 2 blur radii; a CSS blur's radius is a standard deviation and its kernel runs to about 3, so the bed's own edge fade sat inside the blur. It now reaches 3. I measured whether more helps: 6 gives rim 0.13 against 0.14, removing the card's own filter makes the rim worse (0.21), unclipping the bed changes nothing (probe logs
dev-02:~/.cache/codex-scratch/j300/rim.log). So 3 is enough; a small residual remains at Frosted on phones (rim correlation up to 0.25 sidebar, 0.15 palette; 0.00 to 0.02 on desktop), visually no readable character in the crops.P2 spec. It now measures the whole card inside its rounded corners, the outer 14 px rim separately, and the inner part. Thresholds: whole card < 0.15, rim < 0.3, text energy behind the card > 30 (palette cases; measured 47 to 55). It also photographs the card over a coloured block and requires colour/shape correlation > 0.4 at Tinted, Clear and Frosted (measured 0.63 to 0.98) and < 0.2 at Solid (measured 0.08). It adds the sidebar-started anchored card at Tinted and Frosted on 3 viewports and both themes. 37 tests: 24 palette + 12 sidebar + focus/Enter; phones are touch contexts.
P3 material. The bed now takes its blur from the card's own computed per-level value (8, 24, 32 px for Tinted, Clear, Frosted) and adds no saturation, so there is one material in
packages/uiand no fixed 32 px.Red/green (
dev-02 ~/.cache/codex-scratch/j300/):final4.log: 37 of 37 pass on the merged head (also 37 of 37 on654e2034d,r4-host-removal-confirm.log).r4-nobed.log): 28 of 37 fail. Small-phone Tinted whole-card correlation 0.427 ink, 0.420 paper (it was 0.161 and 0.123 in the inner region alone, which is why the old spec missed it). The 9 that pass are the 6 Solid cases, the focus test, and sidebar phone Tinted (0.143 ink, 0.047 paper, below 0.15): on phones the sidebar card sits mostly over the sidebar's blank rows, so the sidebar cases do not catch a missing bed there. The palette cases do.r4-opaque.log): 30 of 37 fail, all on the new colour check ("the card is glass: colour and shape from behind show through"); text checks pass for it, as they should.add-host-prototype.spec.ts:240,mesh.spec.ts:1226): 2 passed (named4.log).Screenshots (production build, dense listing in the live terminal and previews): 2x2 sheets of Solid, Tinted, Clear, Frosted (the 24 cases as 6 sheets), the same over the coloured block (6 sheets, glass visibly takes the colours at Tinted to Frosted, Solid is flat), and the sidebar-started card (6 sheets, Tinted left and Frosted right). I looked at all 6 text sheets, the desktop-ink and phone-paper colour sheets, and the desktop-paper and phone-ink sidebar sheets. No readable character inside the card anywhere. Attached below.
verify quickon dev-02, on the merged head (quick9.log), verbatim:verify faston compute01 (~claude/.cache/codex-scratch/j300/fast3.log, launcher checked first: cargo 1.99.0): FAIL, one row:test(exit 101); every other row PASS (privileged integration SKIP). The one failing test ishelper::startup_recovery_tests::delta_before_startup_keyframe_requests_repair_before_deliveryininfraternal-plugin-desktop(helper.rs:510: "startup delta must trigger a repair keyframe: Disconnected"). This branch changes no Rust. I am running it repeatedly on origin/dev21b3c84ceand on this head to see whether it fails without my change; result follows. I have not claimed it pre-existing.Note: while cleaning a queued job I once ran
pkill -fover ssh and killed my own session (it only hit my own shell; nothing else); I used exact PIDs after that.J300 round 4,
verify fastresult oneee0ed2a9c4f1fafbf8a28287e5f75c877a03cbf: FAIL on thetestrow, three times, a different Rust test each time; not a pass, and I am not calling it one. Branch changes 12 TS/CSS files (apps/tracer,packages/ui) and no Rust (git diff --name-only origin/dev...HEAD -- crates Cargo.*is empty).~claude/.cache/codex-scratch/j300/)testfast3.loginfraternal-plugin-desktophelper::startup_recovery_tests::delta_before_startup_keyframe_requests_repair_before_delivery("startup delta must trigger a repair keyframe: Disconnected")fast4.loginfraternal-plugin-sshtests/install.rs("Setup is already running on this host"); suite took 308 s, load average 33testfast5.log, fresh state root/tmp/j300uinfraternal-plugin-sshtests/previous_attempt_shell.rsshared_ownership_shell_preserves_recovery_and_refusal_invariants(failed after 145 s), load 12 to 33testFinal table of run 3 (
fast5-table.txt), non-PASS rows only:test FAIL (101),privileged integration SKIP. The earlier run on775d8ffdc(fast1.log) also failedteston two differentinfraternal-agenttiming tests (Elapsed).What I could and could not show:
21b3c84ceand on this head (desk2.log);infraternal-plugin-ssh --test install107 passed, 0 failed in 22 s on origin/dev6b1bdb81band 107 of 107 on this head, twice each, with a fresh state root (ssh.log). Earlier, the agent suite passed three times on origin/dev and the two named tests passed alone (base2.log,base3.log).verify faston unmodified origin/dev, so I cannot say a greenfastis achievable on this machine right now. The pattern (different test each time, all timing or process-race tests in crates this branch does not touch, failures after minutes on a machine at load 12 to 33) fits load, but it is a pattern, not proof.fast; it ran 37 of 37 green on dev-02 on the merged head (final4.log).Needs the orchestrator: a
verify fastthat runs on an idle compute01 or on unmodified origin/dev for comparison; I stopped after three runs to stop taking build slots. All my scratch worktrees and targets on both VMs are deleted.J355 review of
fix-removal-confirm@eee0ed2a9c(round 4, vs origin/dev027a3a78b): APPROVEPalette-started card: no character is legible anywhere at any level, rim included. Material is the same as the machine popover. No dropped frames versus dev. Two P2 follow-ups, neither blocking; the owner may still want them first.
Method: production tracer on dev-02 through build-slot (worktrees
~claude/worktrees/j355= branch,j355-base= origin/dev; both removed with my targets afterwards). DPR 2, phones are touch contexts. I reused J344's scratch harness plus a new side-by-side part (dev-02:~/.cache/codex-scratch/j355/j355-review.spec.ts, not for merge). Evidence:~/.cache/codex-scratch/j355/ev-a2-shots/j355/{shots.jsonl,focus.jsonl,others.jsonl,shots/,full/},ev-b-perf-branch,ev-c-perf-base; sheets inev-a2-shots/sheets/. 86 capture tests passed (a2-shots.log), 16+8 perf cells. I did not runverifyand did not re-run J300's own spec (J344 reproduced the previous version; I ran my own pixel checks instead).Findings
P2. Sidebar-started card on a phone still leaks a sliver at its rim; the spec's 14 px band is too wide to see it. My ring metric (3–8 px just inside the edge, high-pass correlation with the page behind) gives sidebar phone Frosted 0.71 ink, 0.41 paper with the bed (0.91/0.76 without), against 0.00 on sidebar desktop and 0.01–0.14 on every palette-started case (J344 saw 0.24–0.29 on desktop in round 3, so the fix works there). Visually (
rim-zoom-sidebar-phone-ink.png, top = with bed): one or two glyph fragments ("8", "-") sit on the card's left border and the page's own text straddles the bottom border. Nothing is readable as a word. Energy behind that ring is only 3.5–4.4 (the sidebar's blank rows), so part of the correlation is the card's own border/antialiasing on a near-empty ring, which is why I rate it P2 and not P1. J300 already reports 0.25 for this case; the spec threshold (rim < 0.3 over 14 px) passes it. Suggest: measure a thinner outer ring (3–8 px) too, or raise the sidebar floor, so the check can see it; consider whether the anchored phone card needs a bed reach above 3σ. I did not test that.P2. Spec honesty: mostly honest, two holes. (a) The ring above. (b) Sidebar-started phone Tinted does not catch a missing bed (J300 says so: 0.143 / 0.047 vs 0.15 limit). The palette cases (24) do catch it (small-phone Tinted 0.42 without bed), and the colour check makes an opaque card fail, so palette coverage is enough for the centred card. The anchored card is covered only at Tinted/Frosted, and on phones only weakly, so the anchored phone card is the least protected path. J300's 37/37, 28/37 (no bed) and 30/37 (opaque) are plausible; I reproduced the bed-off/on difference with my own metric (ring 0.43–0.94 without bed, 0.01–0.14 with).
P3. The confirmation shows slightly less colour than the machine popover. Same blur per level and one saturate (
blur(8px)/blur(24px)/blur(32px) saturate(1.6)on machine popover and confirmation alike; the palette is its larger-size level, 30.8 px at Tinted). But the bed's blur stacks under the card's own, so low-frequency colour correlation is a bit lower: Tinted desktop ink 0.68 vs 0.91 machine, Clear 0.54 vs 0.72, Frosted 0.49 vs 0.69. Over coloured content the three read as one family (sbs-*.png); over a plain white-on-black listing the confirmation looks nearly opaque at all levels (text-phone-ink.png). Stated for the owner, not a defect.P3. Tab leaves the card (Keep → Remove → page), unchanged from earlier rounds.
Checks
ev-b-perf-branch/j355/perf.jsonl,ev-c-perf-base/j355/perf.jsonl). 1× CPU: p95 16.7–16.8 ms and 0 frames over 20 ms in every cell on branch (bed and no bed) and on origin/dev. 4× CPU: branch with bed 1–2 frames over 20 ms per cell (none over 33.4 ms; one single 33.3 ms in four of the cells), no bed 0, origin/dev 1 per cell (one over 33.4). Median RasterTask with the bed 2.1–2.4 ms against 1.6–2.0 on dev. No long tasks. Not a phone GPU; no real-device frame trace.focus.jsonl): palette-started, Escape and Keep click return focus to the terminal; open focus lands on Keep;role=dialog,aria-labelledby= "Remove edge-arm?",aria-describedby= the effect line; sidebar-started card is anchored (data-side=bottom) and Escape returns to the host row. Phones: Keep 60×44, Remove 78×44, card 340 px; nothing summons the keyboard. Desktop card 374 px at root 17.6 px.Not done: no real iPhone or Mac GPU capture; the add-host card and tooltip were not re-captured (unchanged); J300's spec not re-run by me.
Head reviewed:
eee0ed2a9c4f1fafbf8a28287e5f75c877a03cbf. Verdict: APPROVE (two P2 follow-ups for the sidebar phone rim and the spec's ring width).J300: dev merged, conflict resolved. Head
d955e29c77ac0837f8f3c00736cdd368ecb09188onfix-removal-confirm(pushed, not merged). On top ofeee0ed2a9(J355 approved).Conflict (only
apps/tracer/src/canvas/host-removal.on-demand.ts, the import block): kept both sides. #409's outbox flow,ICON_INFOinfo-mark toast ("It uninstalls infraternal as soon as it connects"), the pending/removed messages and theResultdoc are untouched; the file's diff against origin/dev is now only my confirmation call (confirmHostRemoval(name, anchor, onConfirm, returnFocus), plain "Remove", focus return). #409's "Left ... because infraternal didn't create it here" text is server-side (crates/infraternal/src/host_remove.rs,crates/plugins/remote/src/lib.rs); this branch changes no Rust.One test change you should know about:
pending-removal-command.spec.ts:44(a #409 spec) clicked a button named exactly "Remove host", the old sentence-style label the owner rejected. The button is "Remove" now, so that locator became{ name: "Remove", exact: true }; nothing else in that spec changed.On dev-02, on this head (
quick10.log,r5-*.log):verify quick: PASS, verbatim below.host-removal-confirm.spec.ts: 37 passed.pending-removal-command.spec.ts: 4 passed (includes the info-mark toast and "Copy command" fallback).add-host-prototype.spec.ts:240,mesh.spec.ts:1226): 2 passed.verify fastnot run by me this time, as you said you will. Earlierfastfailures were three different Rust tests I could not reproduce (see my previous comment); this merge adds no Rust either.