- 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
5.1 KiB
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 lintreportsraw-page-titleorraw-badgewith 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 lintreportspage-without-headernaming 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-copydoes not fire - WHEN a template renders "Preview — nothing saved yet"
- THEN
em-dash-copyfires
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/auditand the manifest does not list it - THEN
member-console lintreportsscreen-coveragenaming 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 screensruns 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 screensmarked changed and states that the sheet is ready for review