Give the elements that carry meaning something to say

The adapter is only worth having if the call sites exist, so this wires the
ten elements `UX_VERTICAL_SLICE.md` actually names and stops there. The
shell root is an application; the sidebar, its row list and the workspace
are named regions; every workspace panel is a pane carrying its label, its
execution target, its waiting state and whether it owns the keyboard; every
live terminal surface is a terminal; the command palette and the add-panel
chooser are dialogs; the footer's usage strip is a status. Seven elements
gained a stable GPUI id along the way, because an element worth naming to a
screen reader is an element worth keeping state on.

The other 137 divs are left alone deliberately. Fixed-width slots, meters,
chips, borders and painted terminal cell runs have no identity to hang a
node on, and publishing 80x24 nodes a frame would be a tree nobody can
navigate and a cost on every repaint.

No new strings were invented for the screen reader where the model already
had one. `describe()` labels each sidebar row -- that is its caller, so its
`#[allow(dead_code)]` is deleted rather than carried, as decision 0023
requires. The three words in a pane header's corner and the three words its
description leads with now come from one function. The two lines a pane
header prints about where it runs and what its process is doing moved out of
`pane_context` into `pane_header_lines`, because the pane's semantic node is
built one level up in `workspace_panel` and recomputing them there would
have meant two expressions that agree today and disagree after the first
edit. The add-panel chooser's heading and its accessible name are one
constant.

Four labels are new strings, because nothing on screen names these areas:
"Lumbridge", "Workspace", "Sidebar" and "Harness usage". Each is the name
the code and the docs already use for the thing it labels.

The scorecard's accessibility row now reads fail rather than a hedge. The
call sites are wired; the semantics are absent, because the adapter no-ops.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SPYebLiN2w4TqnHUYGdECq
This commit is contained in:
Metal Agent
2026-09-01 13:14:01 -07:00
co-authored by Claude Opus 5
parent 4b5d92249e
commit b6dc70f9fa
3 changed files with 137 additions and 36 deletions
+23 -1
View File
@@ -10,7 +10,7 @@ from macOS and Linux and the hard gates pass.
| Builds on Ubuntu | yes | conditional | pass |
| Builds on Omarchy/Arch | yes | pending | pending |
| Dependency/license closure permits Apache-2.0 distribution | yes | pending | pending |
| Keyboard navigation + AccessKit tree | yes | keyboard pass; current-GPUI semantics compile; platform AT pending | fail: no AccessKit integration at pinned revision |
| Keyboard navigation + AccessKit tree | yes | fail: keyboard passes and the call sites are wired, but the adapter no-ops on 0.2.2, so no accessibility tree is produced | fail: no AccessKit integration at pinned revision |
| IME and composed Unicode input | yes | framework API exists; end-to-end pending | editor API exists; end-to-end pending |
| Isolated system browser child | yes | pending | pending |
| Cold startup, p50/p95 | record | pending | pending |
@@ -66,6 +66,28 @@ accent, and a multi-codepoint emoji without splitting UTF-8. Three deterministic
tests pass. AT-SPI/OS IME on Linux and VoiceOver/IME on macOS remain end-to-end
gates.
### Where the adapter has got to, and what it does not do
`apps/lumbridge/src/a11y.rs` is the adapter decision 0017 promised and never
wrote, landed as the first stage of decision 0023. Ten elements now declare what
they mean — the shell root, the sidebar and its row list, every sidebar row,
the workspace region, every workspace pane, every live terminal surface, the
command palette, the add-panel chooser, and the footer's usage strip — using the
role, label, description, selected-state and stable-identity vocabulary the probe
proves exists at Zed `ce48461e`. `sidebar::model::describe`, written and tested
under decision 0017 and called by nothing for the whole life of that record, is
now what labels a sidebar row, and its `#[allow(dead_code)]` is deleted.
**The gate is still failed, and this work does not move it.** The adapter's
bodies take the value they are given and drop it, because published `gpui 0.2.2`
has no AccessKit dependency to hand it to. Nothing reaches AT-SPI or VoiceOver;
there is no accessibility tree to inspect. What has changed is that the four
facts `UX_VERTICAL_SLICE.md` requires — which pane, its selected state, its
execution target, its waiting state — are now derived in one tested place
instead of being absent from the code entirely, so stage 5 of decision 0023 is a
change to one file rather than a pass over the renderer. Eight unit tests cover
the derivation. None of them is an assistive-technology claim.
The pinned Floem revision has keyboard focus and editor IME plumbing but no
AccessKit dependency or semantic tree. That fails Lumbridge's accessibility
gate without a maintained framework fork or adapter. The provisional direction