Files
T
cgalo5758 408fa6f5a6 Add page anatomy parts and UI quality gate
- Add shared ui_*.html parts (pageHeader, sectionHeader, statusBadge,
  emptyState) parsed into every template set
- Add anatomy lint rules with a shrinking allowlist and screen-coverage
  check
- Add make screens capture harness with contact sheets and baseline diff
- Compose member and FedWiki regions server-side so pages arrive
  complete
- Rebuild Domains and Integrations on the parts as pilots
2026-08-30 04:05:31 -05:00

5.1 KiB
Raw Blame History

ui-quality-gate Specification

Purpose

TBD - created by archiving change page-anatomy. Update Purpose after archive.

Requirements

Requirement: Lint enforces the page anatomy

member-console lint SHALL fail on: raw-page-title (an <h1 in any template other than ui_page_header.html); raw-badge (class="badge or class='badge in any template other than ui_badge.html); raw-empty-state (a centered empty block, text-center py-N wrapping muted text, outside ui_empty_state.html and operator_list_controls.html); hx-confirm (any use); em-dash-copy (an em dash with a letter on either side inside a template text node; a text node that is exactly the em dash is the empty-value marker and exempt); heading-skip (within one template, a heading whose level is more than one deeper than the previous heading); load-fetch (hx-trigger containing load); and page-without-header (a template a handler names as a BodyTemplate, or a member root page, that does not render pageHeader). Violations in a template listed in internal/lint/anatomy_allowlist.txt SHALL be counted and reported as allowlisted, not failed. The allowlist SHALL only shrink: an entry whose template no longer exists or no longer violates SHALL fail the lint as stale, and the pilot pages and the ui_*.html parts SHALL NOT be listed.

Scenario: A new page built the old way fails

  • WHEN a template not on the allowlist renders <h1 class="h4"> or <span class="badge text-bg-success">
  • THEN member-console lint reports raw-page-title or raw-badge with the file and line and exits non-zero

Scenario: A page body without a header fails

  • WHEN a handler sets BodyTemplate = "operator_thing.html" and that template does not render {{ template "pageHeader" ... }}
  • THEN member-console lint reports page-without-header naming the template, unless it is allowlisted

Scenario: The allowlist cannot grow silently

  • WHEN an allowlisted template is rebuilt on the parts and no longer violates
  • THEN the lint fails as stale until its entry is removed

Scenario: The empty-value marker is not copy

  • WHEN a template renders as the whole content of a cell or value
  • THEN em-dash-copy does not fire
  • WHEN a template renders "Preview — nothing saved yet"
  • THEN em-dash-copy fires

Requirement: Every page route is captured

The screens manifest (test/e2e/screens/manifest.go) SHALL list every registered GET page route on the member and operator surfaces (excluding /partials/, /static/, /logout, /healthz, and redirect-only routes), each with a name, a path, a surface, and the role to log in as; routes with an instance parameter SHALL be listed with the seeded instance the walkthroughs use. member-console lint SHALL fail (screen-coverage) when a registered page route is missing from the manifest.

Scenario: A new route without a screen fails lint

  • WHEN a handler registers GET /operator/audit and the manifest does not list it
  • THEN member-console lint reports screen-coverage naming the route

Requirement: The capture harness produces contact sheets and a diff

make screens SHALL run the capture (go test ./test/e2e/screens -run TestScreens), which logs in through the identity provider like the walkthroughs, visits every manifest entry at 1600×1000 and at 390×844 with mobile emulation, saves a full-page PNG per entry and width under test/screens/out/, writes test/screens/out/<surface>.html listing every screen in rail order with both widths side by side, compares each PNG to test/screens/baseline/ when a baseline exists, and prints the names of the screens that changed and the screens with no baseline. make screens-accept SHALL copy out/ to baseline/. Both directories SHALL be gitignored. The harness SHALL skip, not fail, when the stack is not reachable, and SHALL fail when a manifest entry returns a non-200 status or renders the error page.

Scenario: A shell change shows on every sheet

  • WHEN a template shared by all pages changes and make screens runs against an accepted baseline
  • THEN the run prints every screen as changed and the sheets show the new rendering at both widths

Scenario: A broken route is caught

  • WHEN a manifest entry returns 404 or the styled error page
  • THEN the capture fails naming the entry

Requirement: A UI change is not done until its sheet is reviewed

docs/first-contact-ux-process.md SHALL state, and the verify skill SHALL carry as a step, that a change touching templates or app.css runs make screens before it is reported complete, that the changed screens are named in the report, and that the maintainer reviews the sheet against the neighbouring pages using the "Sameness" checklist (section H: same title size, same header slots, same list scaffold, same badge meaning, same empty state, same table density, at both widths) before the change is archived.

Scenario: The report names the changed screens

  • WHEN a change that edits a shared part is reported complete
  • THEN the report lists the screens make screens marked changed and states that the sheet is ready for review