feat(reviews): ui-reviewer agent + visual gate for UI PRs (bookshelf-g3y8) #624
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "bd-bookshelf-g3y8"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Adds a
ui-revieweragent that Reads a rendered screenshot and judges spacing/alignment/typography/token consistency + canonical-component reuse, reporting per review-standard. Documents the UI-PR convention in review-standard.md (screenshot gate + dispatch ui-reviewer alongside code+security on templates/static-css PRs). Registers the agent in CLAUDE.md.Closes the recurring gap where diff-review + unit tests pass but the rendered UI is visually off or re-invents canonical components (#603 bespoke modal classes, #622 hand-rolled email modals).
Files: .claude/agents/ui-reviewer.md (new), .claude/rules/review-standard.md, CLAUDE.md. Docs/config only — no Go change.
Closes bead bookshelf-g3y8 on merge.
Security Review — bookshelf-g3y8 / PR #624
DOCS/CONFIG-ONLY PR: adds
.claude/agents/ui-reviewer.md, a UI-review section in.claude/rules/review-standard.md, and a one-line CLAUDE.md agents-list entry. No application code in this diff.Bash tool grant — The agent is granted
Bash. The only documented use is: read the Forgejo API token via an awk one-liner (identical to every other agent in the project),curl -sk -L -H "Authorization: token $TOKEN"to download a screenshot from the project's own Forgejo instance (git.zombor.net) into/tmp/uirev.png, then pass that file toRead. The token is used solely as an Authorization header; it is never echoed, logged, or posted anywhere. No destructive commands (nogit reset, norm -rf, nomigrate-down, no secret-dumping). Thegrepin Step 3 targets changed template/CSS files only.Secret/credential handling — No instruction to surface credentials in PR comments or logs. Token stays in a shell variable scoped to the curl invocation. Pattern is identical to the existing code-reviewer/merge-supervisor agents.
Existing security controls —
review-standard.mdadds a third parallel agentalongside(not instead of) code+security reviews. All existing orchestrator reaction rules (blocker/major/minor thresholds, auto-fix on MAJOR, CI-green gate) are preserved verbatim. No rule is weakened or bypassed.No application code — Zero Go, SQL, HTML templates, CSS, or CI workflow changes in the diff. Attack surface is nil.
REVIEW VERDICT: 0 blocker, 0 major, 0 minor
CODE REVIEW: APPROVED (1 minor)
Phase 0: DEMO Verification
This is a docs/config-only PR with no DEMO block — confirmed correct for this PR type. Proceeding directly to content review.
Phase 1: Front-matter format consistency
ui-reviewer.mdfront-matter:Compared against
code-reviewer.md(name/description/model/tools) andmerge-supervisor.md(name/description/model/tools): structure is identical.model: sonnetis consistent with the project dispatch convention (dispatch-model-sonnet.md). Tools listed (Read/Glob/Grep/Bash) match the agent's described process — Read for viewing PNGs, Bash for thecurldownload, Grep for source-level checks. NoWrite/Edittools included, which is correct per the "NEVER write or edit code" anti-rubber-stamp rule.Phase 2: Content, references, and factual accuracy
Referenced files/classes verified to exist:
templates/partials/modal_shell.html— exists (findconfirmed).modal-overlay,.modal-dialog,.modal-header,.modal-body,.modal-footer— all defined instatic/css/main.css.metadata-field,.metadata-field-input— defined instatic/css/main.css.btn,.btn-primary,.btn-small,.btn-ghost— defined instatic/css/main.css--space-*tokens (--space-1through …) — defined instatic/css/main.css--fg-muted,--borderCSS variables — defined instatic/css/main.cssOne factual inaccuracy found:
[MINOR]
.claude/agents/ui-reviewer.md:55—.btn-secondarylisted as a canonical class but does not existui-reviewer.mdline 55 listsButtons MUST use .btn/.btn-primary/.btn-secondary/.btn-small/.btn-ghost. Greppingstatic/css/main.cssand all templates shows no.btn-secondarydefinition — the actual classes are.btn(base),.btn-primary(alias for.btn),.btn-small/.btn-sm,.btn-ghost,.btn-icon,.btn-danger-ghost. A ui-reviewer following this list might flag uses of the real classes as non-canonical or incorrectly accept a truly invented.btn-secondary. Fix: remove.btn-secondaryfrom the list (or replace with.btn-smas the alias for.btn-small).Process consistency with review-standard.md:
The agent's output format uses
[BLOCKER]/[MAJOR]/[MINOR]+file:line+REVIEW VERDICT: <B> blocker, <M> major, <m> minor— exactly matching the required format inreview-standard.md. Severity guidance in the new section (bespoke component = MAJOR; inline style= = MAJOR; unreachable control = BLOCKER; polish nits = MINOR) does not contradict the existing severity definitions — it is a narrowing/specialization for the UI domain, not a redefinition.review-standard.md UI review section:
The new section correctly references all four memories:
post-ui-screenshots-in-pr,ui-reuse-canonical-components,ui-interactive-needs-browser-test, andorchestrator-eyeball-ui-screenshots. The statement that the orchestrator dispatches theui-revieweragent alongside (not instead of) code+security reviews is consistent with the existing "three parallel agents" convention. The section does not override or contradict any existing orchestrator reaction rules.CLAUDE.md agents list:
The new entry reads:
ui-reviewer — visual review of a rendered screenshot (spacing, alignment, canonical-component reuse) for template/CSS PRs; dispatch alongside code+security review (see .claude/rules/review-standard.md → UI review). This is accurate, concise, and consistent with the existing two-agent list entries in style.REVIEW VERDICT: 0 blocker, 0 major, 1 minor
22e2e910d85d432c438d