Files
msd-core/gsd-core/references/ui-consideration-probe.md
Tom Boucher 5e729445d3 fix(#4657): give the ui consideration probe a text_en language channel (#4804)
* test(#4657): add failing-first coverage for the ui probe's text_en channel

Mirrors the #3717/#4156 test shape onto the UI adapter: a failing-first
proposeConsiderations regression (Danish text + English text_en must classify
as its English equivalent, not land in the #1110 unclassified sentinel),
proposeElements/analyzeCoverage/CLI end-to-end pairs, fail-closed text_en
validation cases (empty/whitespace/non-string, unconditional under an
elements override), a ui-phase.md Step 9.5 workflow-prose contract test, a
reference-doc Inputs parity test, and a fast-check property proving any
cue-matching prose classifies identically under a cue-free Danish rendering
plus text_en. All new assertions are RED until src/ui-consideration-probe.cts
and the workflow/reference docs are updated.

* fix(#4657): give the ui consideration probe a text_en language channel

Element gains an optional text_en; classifyElement's own signature stays
untouched (a locked, directly-tested export) and the text_en ?? text
selection is pushed to the two classification call sites (proposeConsiderations,
proposeElements) instead. text_en is validated fail-closed: an empty or
whitespace-only value throws rather than silently winning the ?? fallback and
degrading classification to zero kinds.

Mirrors #3717/#4156 onto the UI adapter: ui-phase.md Step 9.5 gains the
Non-English projects section (mirroring spec-phase Step 5.5) and the
ELEMENTS_JSON shape comment documents the field with both zero-applicable
guard arms named; the reference doc's Inputs section, the PROBE.ui CONTEXT
predicate (with both derived indexes regenerated), and the nav-override
test expectation stay in sync. The ui-phase contract test carries the
site-scoped allow-test-rule marker and its cluster is registered in the
test-file-count allowlist ratchet.

Emitted-Drift-Ack-Growth: ui-phase.md — Non-English text_en section, ELEMENTS_JSON shape comment, and two-arm guard wording (#4657)

* docs(#4657): backfill changeset PR number

---------

Co-authored-by: sim <sim@local>
2026-09-16 13:46:40 -04:00

5.7 KiB
Raw Blame History

UI-Consideration Probe — Spec-Completeness Reference

The third adapter of the shared probe-core resolution model (ADR-550 Decision 7), on the UI element/state axis. It surfaces the shape-rooted UI state considerations a UI-SPEC must resolve before a dimension may PASS — the visual analog of the requirement-side edge-probe, reusing its exact lifecycle, validators, and plan-phase lift (see edge-probe.md for the shared status×verification model — this doc does not re-argue it).

Axis boundary (this is a MIXED axis). This compiled taxonomy covers ONLY the finite, project-independent shape-rooted content/robustness states. The open, domain/UX-dependent considerations — real-time/offline/optimistic-UI, deep accessibility (WCAG breadth), internationalization / RTL depth, and emerging interaction paradigms — are open-ended and are prose-owned in the companion domain-probes.md technology/UX bank, NOT here. Forcing them into a closed compiled taxonomy is the wrong model.

Inputs

A list of UI elements, each a { id, text, text_en?, elements? } record where text is the researcher-authored description, elements is an optional author-supplied override of the element classification, and text_en is an optional English translation of text (#4657). The element cues are English word-boundary patterns, so a non-English text (a project running with response_language set) classifies to zero kinds unless text_en carries a faithful English rendering — engine input, never user-facing output; text itself keeps the UI-SPEC's own language and is never translated. The six element kinds are: form, list-collection, nav, media, interactive-control, static-content. When elements is absent, a heuristic classifier proposes kinds from the prose (text_en ?? text, propose-then-confirm) — the author may correct the kind.

Taxonomy (8 categories)

Closed and small by design: the finite, project-independent content/robustness states every UI surface must account for. Growth toward open UX topics happens in domain-probes.md, not by bloating this closed core.

id name applies to element kinds consideration question
empty Empty / no data form, list-collection, media What is shown when there is no data — zero items, an unfilled form, or absent media?
loading Loading / in-flight form, list-collection, media, nav, interactive-control What is shown while data or content is still loading (skeleton, spinner, progressive reveal)?
error Error / failure form, list-collection, media, nav, interactive-control What is shown when the load or submit fails (message, retry affordance, partial fallback)?
populated Populated / happy path list-collection, media What does the normal populated (happy-path) state look like at a typical volume of content?
partial Partial / incomplete form, list-collection What is shown for partial or incomplete data — some fields or rows present, others missing?
overflow Overflow / truncation list-collection, nav, static-content What happens when content exceeds its container — scroll, clip, wrap, or truncate?
zero-one-many Zero / one / many list-collection How does the layout read at zero, one, and many items (singular vs plural copy, spacing)?
long-text Long text form, static-content, interactive-control, nav What happens with unusually long text — truncation, wrapping, ellipsis, or reflow?

Relevance filter + resolution states

The probe reuses the edge-probe rails verbatim (ADR-550 Decision 7 — see edge-probe.md for the full model):

  1. Relevance filter first. Classify each element's kind(s), then raise only the categories whose applies to element kinds intersect. A static label is never asked about loading or empty state — that is what makes an unresolved consideration meaningful.
  2. Dismissal requires a reason string. Silence is not a resolution; the reason is the audit trail.
  3. Zero-classification surfaces one unclassified candidate (#1110). An element whose prose matched no kind cue yields exactly one soft unclassified — review manually item (category: "unclassified", status: "unresolved") — never a silent drop, never a guessed kind. unclassified is a review signal, not a ninth taxonomy category; an explicit elements: [] opt-out stays silent.

Each raised consideration carries the shared two orthogonal axes — status (resolved | dismissed | unresolved) and, when resolved, a verification tier (explicit | backstop). A backstop consideration lifts into must_haves.truths and, at verify time, is confirmed only by explicit evidence (a wired held-out/property test) or routes to insufficient_spec → human_needed — never a silent pass (the honest-verifier disposition, #1154). See honest-verifier.md.

Closed / open boundary

The 8 ids above are the closed, compiled subset — finite and project-independent, so a compiled taxonomy is legitimate (the same property that makes edge-probe's data-shape taxonomy closed). The open subset is prose-owned in domain-probes.md: real-time/offline/optimistic-UI, deep accessibility (WCAG breadth), i18n / RTL depth, and emerging interaction paradigms (gesture/voice/reduced-motion/print) are open-ended and cue-triggered — they do not belong in this closed taxonomy. This probe complements the gsd-ui-checker seven quality dimensions (it adds a state-coverage axis); it does not change the BLOCK/FLAG/PASS enum or the dimensions themselves.