Skip to content

feat(prototype): add per-screen states, test ids and picks-as-criteria to mockups #8775

Description

@kyle-sexton

Part of #8773

Problem

/prototype:explore-directions compares whole-page variants of one screen in their populated state, and its output is a reply template naming the winner and grafts. Three things a decider and an implementer need are missing:

  1. States per screen. Nothing asks for the key states a screen has (empty, loading, populated, error, validation, permission-limited) or makes them switchable in page. The switcher steps through variants only (plugins/prototype/skills/explore-directions/SKILL.md:97-102, bundled assets/variant-switcher.html).
  2. Proposed test ids. Nothing proposes stable data-testids in the markup or lists them in the captured answer.
  3. Picks as acceptance criteria. The answer is recorded as winner, losing directions and grafts (:253-265, context/discipline.md:44-57), not as UI acceptance criteria an implementation and its tests can be checked against.

Evidence

Verified on origin/main 31eafaa (prototype 0.14.0) with git show of SKILL.md, context/discipline.md and the switcher asset path. Already present, so not part of this change: synthetic data only and one data set shared by all variants (SKILL.md:108-113), the CSP (:117), per-variant declared direction (:134-143).

Variant count differs from the item: the skill builds 3 variants by default, never more than 5 (:171-173); the item asks for 2 to 3 per screen. The item's practice also spans several screens per mockup, where the skill scopes one screen ("one screen's layout", :42).

Proposed approach

In plugins/prototype/skills/explore-directions/SKILL.md and assets/variant-switcher.html:

  • Screens and states. Step 1's plan line names each screen, its variants and its enumerated states. The switcher gains a second axis (state) beside variant, keyboard-reachable, with the current state in its label. Keep the switcher's "chrome, not a contestant" rule.
  • Variant count. 2 to 3 variants per screen when a mockup covers several screens; keep 3 by default and 5 maximum for a single screen. Say why: more screens multiply the review cost.
  • Data defined once. Keep the existing rule; add that states derive from the one data set (an empty state filters it, an error state replaces a fetch result), so a grep for a data literal finds one definition.
  • Test ids. Each interactive or asserted element carries a proposed data-testid; the copy-out terminator (:103-104) lists them per screen and variant.
  • Acceptance criteria. Step 5 writes the captured decisions (winner or graft per screen, per-state behavior, test ids) as UI acceptance criteria in the durable answer, next to the losing-directions record the discipline already requires.

Visual test baseline: the item also wants the chosen variant and states to become the visual baseline the implementation is checked against. That collides with "nothing tracked is left" (SKILL.md:77) and discipline rule 6 (context/discipline.md:35) if the mockup itself is committed. Recommended: the baseline is screenshots the implementation's own tests capture from the built UI and compare against the chosen variant during review, not the mockup file committed to the repository. If a committed mockup is wanted instead, that is a decision for the review-mode child, which owns the persistence exception.

Acceptance criteria

  • Every screen has 2 or 3 variants (or 3 to 5 for a single-screen run) and an enumerated list of states, each reachable from the switcher. (Source check 3.)
  • Every variant renders the same synthetic data set; a grep for the data literals finds one definition. (Source check 4.)
  • data-testid proposals appear in the markup and in the captured answer, and the two lists match. (Source check 5.)
  • Step 5's durable answer includes UI acceptance criteria per screen, covering the chosen variant or graft, per-state behavior, and the test ids.
  • The switcher asset still runs under the CSP and from file://.
  • Eval cases in explore-directions/evals/evals.json cover a multi-screen run with states.

Constraints and gotchas

Context

Source: local handoff item 2026-10-06-ui-mockup-review-mode.md, "The practice to adopt" (shape per screen, fictional data, stable test ids, picks become acceptance criteria).

Activity

  1. added
    priority: mediumReal value, no hard deadline; normal backlog flow.
    work-class: scopedA briefed fix or small feature; blast radius bounded by the brief, tests exist.
    on Oct 21, 2026
  2. github-actions commented on Oct 21, 2026

    @github-actions
    Contributor

    Proposed work class: work-class: scoped
    Basis: automated intake triage; the lanes App applied this class.

    Size: Medium
    Complexity: Medium
    Uncertainty: Known
    Flags: none
    Blocked by: none

    Understood: extend /prototype:explore-directions with a per-screen state axis in the switcher, proposed data-testids listed in markup and in the captured answer, and Step 5 recording picks as UI acceptance criteria. The issue gives a concrete approach and a recommendation for the visual-baseline question, so nothing is missing. It asks for coordination with #6589, but that is not a blocker. I found no likely duplicates among the open issues.

    Automated triage, applied by the lanes App.

  3. github-actions commented on Oct 26, 2026

    @github-actions
    Contributor

    The triage sweep dispatched intake triage for this issue (attempt 1 of 2).

  4. added
    admission-deferredAdmitted but waiting for WIP room; the hourly work-unblock sweep labels it agent-ready.
    agent-readyFully specified and briefed; eligible for autonomous pickup from the frontier.
    and removed
    admission-deferredAdmitted but waiting for WIP room; the hourly work-unblock sweep labels it agent-ready.
    on Oct 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    agent-readyFully specified and briefed; eligible for autonomous pickup from the frontier.priority: mediumReal value, no hard deadline; normal backlog flow.status: readyTriaged, unblocked, and fully specified; eligible to pick up.work-class: scopedA briefed fix or small feature; blast radius bounded by the brief, tests exist.

    Fields

    No fields configured for Feature.

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions