generated from mathias/template-go-web
feat(atlas): UX — plain node titles + mobile transition rows (re-review #1,#2)
Lap-2 review's top two findings: #1 Node titles were still jargon (the lap-1 disease one level down). Every node now has a plain_t ("var-go Oath" → "Definition of done", "Admission controller" → "Tamper-proof seal", …); Plain view leads with it and demotes the technical name to a dim in-card subtitle — mirrors the stage-head pattern. plain_t on every authored node is now guard-tested. #2 Transition labels lived only in the SVG spine (display:none <820px) with a hover-only rationale — invisible on phones. Added stacked-layout transition rows (HTML, always-visible, full sentence, no hover) shown on mobile; desktop header band scoped to ≥821px so mobile isn't stretched. build/vet/lint(0)/test green; desktop Plain screenshot-verified. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,236 @@
|
||||
# CAD Atlas — Fresh-Eyes UX Review, Lap 2
|
||||
|
||||
Reviewer role: fresh-eyes UX (not implementer). Second pass, judging the shipped
|
||||
progressive-disclosure sprint against the goal set in `UX-REVIEW.md`. This document
|
||||
critiques; it does not change code.
|
||||
|
||||
Sources reviewed:
|
||||
- `docs/UX-REVIEW.md` (the spec that was implemented — lap 1)
|
||||
- `internal/atlas/atlas.json` (authored data: `plain_title`, `plain`, `trans_label`,
|
||||
`trans` per stage; `plain` per node)
|
||||
- `internal/web/static/cad-atlas.html` (the renderer: Plain⇄Technical toggle, spine
|
||||
transition labels, legend, substrate/footer hidden in Plain)
|
||||
- `/tmp/ux5/home.png` (deployed Plain view, stages 00–04 in frame)
|
||||
|
||||
---
|
||||
|
||||
## 1. Verdict
|
||||
|
||||
**The sprint largely achieved the *phase* half of the success criterion and made a real
|
||||
dent in the *transition* half — but it does not fully clear the bar. Grade for a naive
|
||||
viewer: B / B+.**
|
||||
|
||||
Success criterion was: a viewer with no briefing can explain **every phase** AND **what
|
||||
advances work across every transition.**
|
||||
|
||||
- **Phases: pass.** This is the big win. The headline hierarchy works — big plain_title
|
||||
("Notice what's happening", "Why we're here", "Agents do the work"), a dim technical
|
||||
subtitle, and a jargon-free "what happens" sentence. A cold stakeholder can now narrate
|
||||
every column. This is a genuine, measurable improvement over lap 1, where every column
|
||||
was a mechanism name. Full marks here.
|
||||
|
||||
- **Transitions: partial.** The short spine labels ("Does it matter to us?", "Worth a
|
||||
session?", "Decision reached", "Sealed & agent-ready") convey the *gist* of each hop,
|
||||
which is a step-change from the blank arrows of lap 1. But three things hold it back
|
||||
from "can explain what advances work":
|
||||
1. The actual "what must be true to advance" sentence (`trans`) is **hover-only** (an
|
||||
SVG `<title>` tooltip). That is undiscoverable — nothing signals it's hoverable — and
|
||||
dead on touch devices. So the naive viewer gets the one-line theme, not the gate
|
||||
logic.
|
||||
2. The labels are **terse and grammatically mixed**: some are questions ("Does it matter
|
||||
to us?"), some are achieved-states ("Decision reached", "It's live"). A first-timer
|
||||
builds two different mental models — "is this the question asked here, or the answer
|
||||
reached?" — from one row.
|
||||
3. **They vanish on narrow screens.** All transition labels live inside `svg.spine`,
|
||||
which is `display:none` under 820px, and the stacked mobile layout renders no HTML
|
||||
fallback. The single biggest comprehension win of the sprint is absent on a phone.
|
||||
|
||||
- **The viewport undermines both.** The atlas is a 9-column horizontal scroll and a laptop
|
||||
shows ~stages 00–03. That means **stage 04, the one human gate — the thing the header
|
||||
literally advertises ("one human gate") — is off-screen on load**, along with execution,
|
||||
CI, deploy, and the loop. A first-timer cannot see the shape of the gated flow, cannot
|
||||
see that a human checkpoint exists, and gets no affordance that five more stages are to
|
||||
the right. The atlas's whole payoff — "see the auditable flow from signal to pod at a
|
||||
glance" — is not deliverable in the default viewport.
|
||||
|
||||
Net: the copy layer is excellent and the toggle is the right architecture. The remaining
|
||||
gap is structural (what's visible, and where the transition rationale lives), plus one
|
||||
stubborn copy residue (node titles). A naive viewer *can* explain the phases unprompted;
|
||||
they can explain the transitions only at a slogan level, and only for the half of the
|
||||
pipeline they happen to scroll to.
|
||||
|
||||
---
|
||||
|
||||
## 2. What works (the genuine wins)
|
||||
|
||||
- **Plain default + persisted toggle.** Right call, right default. Nothing was thrown
|
||||
away; Technical is the old atlas verbatim. Architecture matches the spec.
|
||||
- **Stage headline hierarchy.** plain_title dominant, technical title demoted to a dim mono
|
||||
subtitle, plain sentence underneath. Clean, scannable, correct visual weight.
|
||||
- **Transitions exist at all.** Even terse, the labelled arrows turn a row of boxes into a
|
||||
narrated flow. This was the #1 lap-1 miss and it shipped in the default layer.
|
||||
- **Density dropped in Plain.** Tags, risk chips, host ribbon and footer are all suppressed
|
||||
in Plain (`body.plain`), so the reading surface is airy and calm — a real contrast to the
|
||||
lap-1 wall of pills.
|
||||
- **Stage 06 no longer reads as empty.** An authored "Automated checks" node with plain copy
|
||||
now backstops the live CI generation, so the CI gate never looks like a no-op on a cold
|
||||
load. Directly fixes lap-1 punch-item 7.
|
||||
- **Feedback bus is honestly hedged.** Dashed violet + "partly manual today" in both the loop
|
||||
label and the legend. Matches the dogfooding-honesty discipline.
|
||||
- **The pulse gives direction.** The travelling dot is a low-cost "this flows left-to-right,
|
||||
then loops back" cue — helpful for orientation.
|
||||
|
||||
---
|
||||
|
||||
## 3. What's still weak (shipped Plain view)
|
||||
|
||||
**a. Node titles are still pure mechanism-jargon — the exact lap-1 disease, one level down.**
|
||||
The node *body* is now plain, but the node *title* — the first, boldest thing the eye lands
|
||||
on in a card — is untouched: "Applied AI Radar", "Intention substrate", "Admission
|
||||
controller", "var-go Oath", "Session-Dispatch bridge", "Executor + reviewer loop",
|
||||
"dma-cli · routing + scope", "assessor-loop ledger". The plain body can't fully rescue a
|
||||
card whose title already framed it as a mechanism. The stage head got the plain-title/tech-
|
||||
subtitle treatment; the node did **not** — an inconsistency that leaves each column half-
|
||||
translated. See §4.
|
||||
|
||||
**b. The transition rationale is hidden and fragile.** As in §1: `trans` is hover-only
|
||||
(undiscoverable, touch-dead) and the whole label layer disappears under 820px. The "what
|
||||
must be true to advance" — the governance content the atlas exists to show — is the least
|
||||
robustly delivered part of the whole thing.
|
||||
|
||||
**c. Horizontal scroll with no affordance = half the pipeline is invisible.** Nothing at the
|
||||
right edge signals "more stages this way" — no fade, no scrollbar cue, no "→ 04–08", no
|
||||
overview. A first-timer may reasonably believe the pipeline is five stages that end at "Write
|
||||
the work order". The marquee human gate and the entire execute→ship→loop arc are off-frame by
|
||||
default. This is the single largest comprehension barrier remaining.
|
||||
|
||||
**d. Transition-label attachment is weaker than specced.** Lap-1 §5 asked for **label chips
|
||||
sitting on the spine**; what shipped is floating 10px mono text ~9px above the arrow with no
|
||||
background. On the dark grid it reads, but it floats — the viewer has to mentally bind the
|
||||
text to the arrow beneath it. A chip (or a short leader) would make the label read as *of*
|
||||
the arrow, not near it.
|
||||
|
||||
**e. Gate treatment is cryptic.** Lap-1 §5 asked for a lock/shield glyph + stronger colour on
|
||||
the two real gates (04 human, 06 CI). What shipped is a "▸ " prefix + gold + bold on those two
|
||||
labels. A naive viewer will not read "▸" as "governance checkpoint"; the only real cue is
|
||||
"one of these labels is gold", which leans entirely on the legend. The two most important hops
|
||||
in the whole atlas deserve a glyph that says *stop / check*, not an arrowhead character.
|
||||
|
||||
**f. The legend doesn't match the colours actually on screen.** The KEY decodes green/amber/
|
||||
coral as CI run-states plus gold=gate + dashed=feedback. But in Plain the cards show **violet,
|
||||
blue, and coral pills** and **coloured/dashed borders** (council=violet, bridge=dashed-blue,
|
||||
oath=dashed-gold, executor=coral) that the KEY never explains — while the green/amber/coral CI
|
||||
states the KEY *does* explain are barely present in Plain. So the viewer sees a violet dot on
|
||||
"Intention substrate" and a dashed-gold box on "var-go Oath" with no way to decode them, and a
|
||||
legend describing states they can't see. Colour is carrying two unrelated meanings (authored
|
||||
semantics vs. live CI status) under one key. Either key every colour/border shown in Plain, or
|
||||
strip the decorative pills/borders in Plain so colour means only what the legend says.
|
||||
|
||||
**g. The technical subtitle is a wash — mild noise, mild help.** Under the plain_title sits
|
||||
`s.title`: sometimes near-plain ("Signals", "Strategic session"), sometimes pure jargon
|
||||
("TELOS", "Spec → Gitea issue", "PR → CI", "Execute · agentsquad"). For a naive viewer roughly
|
||||
half of these subtitles are undecodable filler directly under the headline; for a new engineer
|
||||
they're a useful canonical-name bridge without a mode-switch. Because it's dim and small the
|
||||
noise cost is low, so **keep it** — but note the *inconsistency*: the stage trusts the reader
|
||||
with a dim technical name under a plain headline, yet the node doesn't extend that same courtesy
|
||||
(§4). Apply the pattern uniformly.
|
||||
|
||||
**h. Unexplained accent colours on headlines.** plain_title is violet for TELOS/Loop and amber
|
||||
for the gate. Meaningful to the author, unkeyed for the viewer — a minor echo of problem (f).
|
||||
|
||||
**i. The feedback bus reads as a mystery line in-viewport.** The dashed violet return leg drops
|
||||
straight down out of the TELOS column, but its label ("What did we learn? · feedback bus")
|
||||
sits at the very bottom of a 9-column-wide canvas — off-screen for anyone who hasn't scrolled
|
||||
down and right. In the default view you see an unexplained dashed vertical line and no origin
|
||||
(stage 08 is off-frame right). The honesty hedge is good; the *legibility* of the loop in the
|
||||
first screen is poor.
|
||||
|
||||
---
|
||||
|
||||
## 4. Node-title question — recommendation: **add plain node titles; keep the technical name as a dim subtitle inside the card.**
|
||||
|
||||
Do **not** keep titles as-is, and do **not** simply swap in plain titles and delete the
|
||||
technical ones. Mirror the pattern the stage head already uses, one level down:
|
||||
|
||||
```
|
||||
[pill] Marks its own homework? No. ← plain_t (bold, primary)
|
||||
Executor + reviewer loop ← t (dim mono subtitle)
|
||||
One agent does the work; a second, ← plain (body, already shipped)
|
||||
independent agent reviews it …
|
||||
```
|
||||
|
||||
Reasoning for the mixed audience:
|
||||
|
||||
- **The title is the frame.** The eye reads title → body. A jargon title ("Admission
|
||||
controller", "var-go Oath") sets a mechanism frame that a plain body then fights against.
|
||||
This is precisely the lap-1 diagnosis ("every node names a *mechanism* rather than the
|
||||
*thing that happens to the work*") — it was fixed for stages and bodies but left standing in
|
||||
node titles. The job is half-done until titles get the same treatment.
|
||||
- **A naive viewer needs the plain title.** "Marks its own homework? No.", "Signed so tampering
|
||||
shows", "The one human yes/no", "A machine-checkable definition of done" — these are
|
||||
explainable at a glance; "dma-cli · routing + scope" is not.
|
||||
- **A new engineer still needs the canonical name.** "var-go Oath", "Ed25519 admission
|
||||
controller", "assessor-loop ledger" are the searchable terms that connect the picture to the
|
||||
code and the brain. Deleting them would help the stakeholder and hurt the engineer — the
|
||||
wrong trade for a "everyone" audience.
|
||||
- **Consistency is its own win.** Right now stage heads say "plain big / technical small" and
|
||||
nodes say "technical only". Two rules for the same card type is friction. One rule, applied
|
||||
at both levels, makes the whole atlas feel like one designed system and makes the toggle's
|
||||
mental model ("plain names up front, mechanisms one layer in") coherent.
|
||||
|
||||
Concretely: add an optional `plain_t` per node in `atlas.json`; in Plain render `plain_t` as
|
||||
the title and `t` as a `tech-sub`-style dim line (reuse the existing class); in Technical keep
|
||||
today's behaviour (`t` as title). Nodes without a `plain_t` fall back to `t`, so it's an
|
||||
incremental authoring task, not a big-bang rewrite.
|
||||
|
||||
---
|
||||
|
||||
## 5. Prioritized next punch list (top 6 by comprehension impact)
|
||||
|
||||
1. **Add plain node titles (`plain_t`), technical name demoted to a dim in-card subtitle.**
|
||||
Highest impact: the title is the first thing read and it's still the lap-1 jargon disease.
|
||||
Finishes the progressive-disclosure job the stages already got. (§3a, §4)
|
||||
|
||||
2. **Solve the horizontal-scroll blindness.** A first-timer must be able to tell the pipeline
|
||||
is nine stages and reach the human gate and the loop. Ship at least a right-edge fade +
|
||||
"→ stages 04–08" hint; ideally a "fit to width / overview" zoom toggle so the whole gated
|
||||
shape (and the one human gate the header promises) is visible at a glance. (§3c)
|
||||
|
||||
3. **Render transition labels in the stacked/narrow layout, and surface the `trans` sentence
|
||||
without a hover.** The labels currently die under 820px (they live only in the SVG) and the
|
||||
gate rationale is hover-only/touch-dead. Emit `trans_label` as an HTML element between
|
||||
stacked stages, and make the full `trans` reachable by click/tap (expandable), not just
|
||||
desktop hover. This is the "explain every transition" half of the success criterion. (§1, §3b)
|
||||
|
||||
4. **Give the two governance gates (04 human, 06 CI) a real glyph and make the feedback loop
|
||||
legible in-viewport.** Replace the "▸" prefix with a lock/shield on the gold gate labels so
|
||||
the checkpoints read as checkpoints; and attach a visible "What did we learn?" chip to the
|
||||
top of the feedback return leg near TELOS so the dashed line isn't a mystery in the first
|
||||
screen. (§3e, §3i)
|
||||
|
||||
5. **Reconcile the legend with the colours on screen in Plain.** Either key every pill/border
|
||||
meaning the Plain view shows (violet/blue/coral pills; council/bridge/oath borders) or drop
|
||||
the decorative pills/borders in Plain so colour means only the CI states the KEY describes.
|
||||
Today the legend and the canvas disagree. (§3f, §3h)
|
||||
|
||||
6. **Turn floating transition text into attached chips and normalise the grammar.** Give each
|
||||
label a small chip background so it reads as *on* the arrow, and pick one voice — all
|
||||
"what-must-be-true" states ("Mattered to us", "Decision reached", "Human said go", "All
|
||||
checks green", "It's live") reads more consistently than mixing questions and states. (§3d)
|
||||
|
||||
---
|
||||
|
||||
### Scorecard vs. lap-1 punch list
|
||||
|
||||
| Lap-1 item | Status |
|
||||
|---|---|
|
||||
| 1. Label every arrow | **Shipped** (desktop only; hover-only rationale; dies on mobile) |
|
||||
| 2. plain_what per stage + demoted title | **Shipped** — clean |
|
||||
| 3. Plain⇄Technical toggle, default Plain, persisted | **Shipped** — correct |
|
||||
| 4. Plain node primary text, `d` on demand | **Half** — bodies plain, **titles still jargon** (§4) |
|
||||
| 5. Distinguish the two gates (lock/shield) | **Weak** — "▸"+gold, no glyph |
|
||||
| 6. Legend keying colours + gate types | **Partial** — legend exists but doesn't match Plain colours |
|
||||
| 7. Fix stage-06 empty column | **Shipped** — authored fallback node |
|
||||
| 8. Honest feedback bus + suppress proper nouns in Plain | **Half** — bus honest; proper nouns still leak via node titles + tech-subs |
|
||||
</content>
|
||||
</invoke>
|
||||
Reference in New Issue
Block a user