baldart 4.60.0 → 4.61.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,23 @@ All notable changes to BALDART will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [4.61.0] - 2026-06-22
9
+
10
+ **UI design-quality critic — a separate, rigorous reviewer for *"is this good design?"*, distinct from the existing *"does it match the mockup?"* check.** Born from the observation that implemented UIs were often poor despite the full `ui-expert` + `/e2e-review` machinery. Root cause, confirmed by exploration: every existing UI verification checks **fidelity / conformance**, not **intrinsic quality** — `visual-fidelity-verifier` asks only whether the render matches the mockup (and never reads source, never judges aesthetics), `code-reviewer`'s design-system steward is mechanical (token/primitive compliance), and the only agent judging quality (`ui-expert`) is *also the implementer*, so it grades its own work. The generator-grades-itself antipattern is exactly what the critic-in-the-loop research (vision-guided iterative refinement; rubric-based LLM-as-judge with per-dimension calibration) identifies as the failure mode. This release adds the missing layer: a separate critic that judges the rendered output against a scientific rubric, in the existing bounded self-heal loop.
11
+
12
+ **MINOR** — adds one agent (`ui-quality-critic`) + one SSOT rubric section + `/e2e-review` Phase 4b wiring. **No new `baldart.config.yml` key** (gates reuse `features.has_e2e_review` + `features.has_design_system` + `features.e2e_review.fidelity_tolerance` + `max_self_heal_iterations`), so the schema-change propagation rule does NOT apply. Additive: with `features.has_e2e_review: false` (or no screenshots) the new phase is skipped and every path is byte-identical to v4.60.0.
13
+
14
+ ### Added
15
+
16
+ - **`framework/.claude/agents/ui-quality-critic.md`** — new stateless multimodal agent (`model: opus`). Judges **intrinsic design quality** of a rendered UI screenshot against a fixed 10-dimension rubric (visual hierarchy, typographic rhythm, spacing rhythm, color/contrast harmony, density consistency, composition/balance, state & affordance completeness, motion quality, polish/AI-generic smell, brand coherence), each with explicit *excellent vs poor* calibration anchors. Emits a severity-tagged JSON report + per-dimension scores + region-anchored findings (`source: "design-quality"`). Inherits `visual-fidelity-verifier`'s anti-bias discipline (never reads source code), adds an explicit *never grades its own design* rule, grounds every numeric threshold in the existing Reference Tables (never invents numbers), and reuses the canonical severity taxonomy so its findings flow through the same gate.
17
+ - **`framework/agents/design-system-protocol.md` § "Design Quality Rubric"** — new SSOT section owning the 10 dimensions, their weights (sum 1.00), and the dimension→severity mapping. The per-dimension anchors live in the agent body; the dimension list/weights/mapping live here so they cannot drift across consumers. Not gated on `features.has_design_system` (quality is judged on every surface; thresholds ground in the project's `tokens-reference.md` when present, the Reference Tables otherwise).
18
+
19
+ ### Changed
20
+
21
+ - **`framework/.claude/skills/e2e-review/SKILL.md`** — new **Phase 4b — Design Quality Critique**: invokes `ui-quality-critic` on every route with a screenshot (including no-mockup `skip` routes; no pixel-diff pre-filter — quality is not pre-filterable). Findings join Phase 5's `findings[]` under the same tolerance filter; Phase 5b's bounded self-heal loop now **routes `design-quality` (and UI-presentation `visual`) fixes to `ui-expert`** (the UI domain owner) and functional/structural fixes to `coder`. Report schema gains a `quality` block (`quality_score_avg`, `weakest_dimensions`). Orchestrator overview, Interaction, and Failure-Modes sections updated (added `quality_critic_protocol_violation` + non-converging-quality-loop diagnostics).
22
+ - **`framework/.claude/agents/visual-fidelity-verifier.md`** — added an explicit scope boundary vs `ui-quality-critic` (fidelity/conformance vs intrinsic quality) so the two never overlap.
23
+ - **`framework/.claude/agents/REGISTRY.md`**, **`README.md`** (agent count 29→30 + inventory entry), **`CLAUDE.md`** (agent count + new convention bullet) — kept in sync.
24
+
8
25
  ## [4.60.0] - 2026-06-21
9
26
 
10
27
  **`/new` cost + autonomy release — born from a forensic post-mortem of a real `-full` epic run** (224M orchestrator cache_read over 543 turns, context grown to ~670k, 9 improvised on-context fix agents, Codex completing only 2/7 reviews). The dominant cost is mechanical — turn-count × monotonically-growing context, confirmed against Anthropic's current prompt-caching docs — and the back half of the run was the expensive half because the final-review fix cascade and the deploy phase ran ON the orchestrator context at ~670k/turn. Two adversarial review passes shaped and verified the change set (several proposed items were refuted as already-shipped or redundant; four blockers found in pre-release review were fixed before tagging).
package/README.md CHANGED
@@ -85,7 +85,7 @@ No additional activation steps needed — once installed, Claude Code (and Codex
85
85
  - **agents/**: 25 domain modules (architecture, workflows, testing, security, card-schema, i18n-protocol, return-contract-protocol, etc.)
86
86
  - **Routing**: If you touch X, read Y - minimize context loading
87
87
 
88
- ### AI Agents (29 specialized agents)
88
+ ### AI Agents (30 specialized agents)
89
89
 
90
90
  **Core (required for every project)**
91
91
  1. **codebase-architect**: MANDATORY before planning/implementation - understands codebase structure
@@ -108,20 +108,21 @@ No additional activation steps needed — once installed, Claude Code (and Codex
108
108
  16. **hyper-gamification-designer**: Game mechanics, retention loops, economy balance
109
109
  17. **remotion-animator-orchestrator**: Video/motion graphics with Remotion
110
110
  18. **visual-fidelity-verifier** (v3.18.0): Stateless multimodal worker auto-invoked by `/e2e-review` Phase 4 — compares an implemented UI route against its mockup (or design-system spec) and returns a severity-tagged JSON report. Never reads source code (anti assertion-fitting bias), never edits, never declares done
111
+ 19. **ui-quality-critic** (v4.61.0): Stateless multimodal worker auto-invoked by `/e2e-review` Phase 4b — judges the **intrinsic design quality** of an implemented UI (10-dimension scientific rubric: hierarchy, rhythm, color, density, composition, states, motion, polish, brand) and returns a severity-tagged JSON report + per-dimension scores. The design twin of `code-reviewer`, the quality complement of `visual-fidelity-verifier` (needs no mockup). Never reads source, never grades its own design; fixes route to `ui-expert` in the bounded self-heal loop
111
112
 
112
113
  **Product & Marketing**
113
- 19. **onboarding-architect-lead**: User onboarding flow design and experimentation
114
- 20. **marketing-conversion-strategist**: High-converting copy and messaging
115
- 21. **seo-analytics-strategist**: SEO strategy, metadata, GA4/GTM event planning
116
- 22. **email-deliverability-architect**: Transactional/informational email design + SPF/DKIM/DMARC
117
- 23. **website-orchestrator**: Multi-agent website development coordination
114
+ 20. **onboarding-architect-lead**: User onboarding flow design and experimentation
115
+ 21. **marketing-conversion-strategist**: High-converting copy and messaging
116
+ 22. **seo-analytics-strategist**: SEO strategy, metadata, GA4/GTM event planning
117
+ 23. **email-deliverability-architect**: Transactional/informational email design + SPF/DKIM/DMARC
118
+ 24. **website-orchestrator**: Multi-agent website development coordination
118
119
 
119
120
  **Specialized**
120
- 24. **hybrid-ml-architect**: ML/DL system design (recommenders, ranking, embeddings)
121
- 25. **legal-counsel-gdpr**: GDPR compliance, privacy policies, data governance
122
- 26. **deep-human-insight**: Psychological / sociological analysis for B2C UX and adoption
123
- 27. **skill-improver**: Weekly auto-improvement of skills/agents based on review/QA findings
124
- 28. **i18n-translator** (v4.52.0): Context-aware label translation into native locale files (Sonnet, low-effort, flag-not-guess) — invoked by `/i18n` + the `i18n-align` routine
121
+ 25. **hybrid-ml-architect**: ML/DL system design (recommenders, ranking, embeddings)
122
+ 26. **legal-counsel-gdpr**: GDPR compliance, privacy policies, data governance
123
+ 27. **deep-human-insight**: Psychological / sociological analysis for B2C UX and adoption
124
+ 28. **skill-improver**: Weekly auto-improvement of skills/agents based on review/QA findings
125
+ 29. **i18n-translator** (v4.52.0): Context-aware label translation into native locale files (Sonnet, low-effort, flag-not-guess) — invoked by `/i18n` + the `i18n-align` routine
125
126
 
126
127
  REGISTRY.md is the single source of truth for agent routing and capabilities.
127
128
 
package/VERSION CHANGED
@@ -1 +1 @@
1
- 4.60.0
1
+ 4.61.0
@@ -25,6 +25,7 @@ Quick-reference for all custom agents. Use this to route tasks to the right spec
25
25
  | **i18n-translator** | Localization | Translate user-facing labels into the maintained target languages (invoked by `/i18n` + the `i18n-align` routine). Gated on `features.has_i18n`. | Context-aware translation using the per-key registry context, ICU/placeholder preservation, glossary adherence; bounded "flag-not-guess" self-healing (`needs-attention`) | Yes (writes native locale files ONLY — never app code, never the registry) | Native locale files, optional bulk backends (lingo.dev/languine) |
26
26
  | **ui-expert** | Design | Design, implement, and review UI/UX | Mobile-first, accessibility, registry-first protocol gate (when `features.has_design_system: true`) — BLOCKING reads on `${paths.design_system}/INDEX.md` + `tokens-reference.md` + `components/<Name>.md` per `framework/agents/design-system-protocol.md`, Component Discovery cascade before any design | Yes (generates UI / HTML mockups in `ui-design` Step C; a separate fresh instance acts as design-quality evaluator in Step D) | ui-ux-pro-max, Playwright |
27
27
  | **visual-fidelity-verifier** | Design | Compare an implemented UI route against its mockup (or design-system spec) and return a severity-tagged JSON report. Auto-invoked by `/e2e-review` skill (Phase 4) — never spawned ad-hoc. Stateless. Strict severity taxonomy (Critical / Major / Minor) — never reads source code (anti assertion-fitting bias), never edits, never declares done. | Visual diff, severity taxonomy, design-system compliance check via registry cascade | No | Vision (multimodal), Read (screenshots + registry only), Playwright screenshots passed in by orchestrator |
28
+ | **ui-quality-critic** | Design | Judge the **intrinsic design quality** of an implemented UI screenshot against a scientific 10-dimension rubric (hierarchy, typographic & spacing rhythm, color/contrast, density, composition, states, motion, polish, brand) and return a severity-tagged JSON report + per-dimension scores. The design twin of `code-reviewer`; the fidelity complement of `visual-fidelity-verifier` (quality vs conformance — needs no mockup). Auto-invoked by `/e2e-review` (Phase 4b) — never spawned ad-hoc. Stateless, never reads source (anti assertion-fitting bias), never grades its own design, never edits, never declares done. Fixes route to `ui-expert`. Return Contract: JSON (already COMPACT). | Design-quality critique, rubric scoring, calibration anchors per dimension | No | Vision (multimodal), Read (screenshots + registry/guidelines only) |
28
29
  | **visual-designer** | Design | Generate visual assets via Kie.ai | Illustrations, icons, hero images | Yes | Kie.ai API, WebP optimization |
29
30
  | **motion-expert** | Design | Design animations and micro-interactions | Transitions, timing, easing | No | Animation specs, a11y fallbacks |
30
31
  | **hyper-gamification-designer** | Design | Analyze game features and retention mechanics | Progression, reward loops | No | MDA analysis, economy balance |
@@ -0,0 +1,287 @@
1
+ ---
2
+ name: ui-quality-critic
3
+ description: "Judge the intrinsic design quality of an implemented UI screenshot against a scientific rubric (hierarchy, rhythm, balance, polish) and return a severity-tagged JSON report with per-dimension scores. Stateless multimodal worker invoked by the /e2e-review skill — never edits code, never reads source, never declares done. Single responsibility: design-quality critique (NOT mockup fidelity — that is visual-fidelity-verifier)."
4
+ model: opus
5
+ color: purple
6
+ ---
7
+
8
+ You are the **UI Quality Critic**. You exist for one purpose: look at a rendered
9
+ UI screenshot and judge whether it is *good design* — not whether it matches a
10
+ mockup. You score it against a fixed, scientific rubric and return a
11
+ deterministic, severity-tagged JSON report.
12
+
13
+ You are the design-quality twin of `code-reviewer`: where `code-reviewer` judges
14
+ whether code is correct, you judge whether a screen is well-designed. You are
15
+ the input-side complement of `visual-fidelity-verifier`: it answers *"does the
16
+ render match the intended mockup?"* (fidelity / conformance); you answer *"is
17
+ this good design, on its own merits?"* (intrinsic quality). Both are needed — a
18
+ render can be pixel-faithful to a mediocre mockup, or have no mockup at all, and
19
+ still be poor design. That gap is your job.
20
+
21
+ You are stateless. You do not iterate. You do not fix. You report what you see
22
+ against the rubric, with a structured severity tag and an actionable fix hint
23
+ per finding. The orchestrating skill (`/e2e-review`) runs the bounded
24
+ critic→fix loop and decides what to do with your output.
25
+
26
+ ## Project Context
27
+
28
+ **Reads from `baldart.config.yml`:**
29
+ `paths.design_system`, `paths.ui_guidelines`, `identity.design_philosophy`,
30
+ `identity.audience_segments`, `features.has_design_system`,
31
+ `features.e2e_review.fidelity_tolerance`.
32
+
33
+ **Gated by features:** `features.has_e2e_review`. The agent refuses to run when
34
+ `false` — it exists only to support the `/e2e-review` skill. The quality
35
+ critique itself does **not** require a mockup and does **not** require a design
36
+ system: when `features.has_design_system: false` it judges against
37
+ `${paths.ui_guidelines}` + the universal rubric below; when `true` it
38
+ additionally grounds numeric thresholds in the registry.
39
+
40
+ **On missing/empty keys:** report the gap in the output JSON `gaps[]` and judge
41
+ against the universal rubric (the numeric tables in
42
+ `framework/agents/design-system-protocol.md` are project-independent). Do not
43
+ assume project-specific defaults. See `framework/agents/project-context.md` § 3.
44
+
45
+ ## Hard Prohibitions (non-negotiable)
46
+
47
+ - **NEVER read application source code** (`.tsx`, `.ts`, `.css`, `.scss`,
48
+ `.jsx`, `.js` under `${paths.components_root}` or `${paths.app_dir}`). Reading
49
+ the implementation creates assertion-fitting bias — you would rationalize what
50
+ the code *intends* instead of judging what the screen *shows*. You critique
51
+ the rendering, period. (Same discipline as `visual-fidelity-verifier`.)
52
+ - **NEVER grade your own design.** You did not produce this UI. If the
53
+ orchestrator's payload reveals that the same agent both implemented and is
54
+ reviewing, flag `self_review_conflict` in `gaps[]` and proceed — the whole
55
+ point of a separate critic is that the generator never evaluates its own
56
+ output.
57
+ - **NEVER edit any file.** You produce a JSON report only. The orchestrator
58
+ delegates fixes to a separate `ui-expert` agent in the self-heal loop.
59
+ - **NEVER invent numbers.** Every numeric threshold you cite (type ratio,
60
+ contrast target, spacing step, density row-height, motion duration) MUST come
61
+ verbatim from `framework/agents/design-system-protocol.md` § "Reference
62
+ Tables" or the project's `tokens-reference.md`. If you cannot ground a number,
63
+ describe the issue qualitatively and lower the finding's confidence.
64
+ - **NEVER declare a task "done" or "passed".** You return findings + scores. The
65
+ gate logic lives in `/e2e-review` — it decides pass / block / loop / override.
66
+
67
+ ## Input Contract
68
+
69
+ The orchestrator (`/e2e-review`) invokes you with this JSON payload:
70
+
71
+ ```json
72
+ {
73
+ "card_id": "FEAT-XXXX",
74
+ "route": "/dashboard",
75
+ "viewport": { "width": 1440, "height": 900 },
76
+ "implementation_screenshot_path": "/abs/path/to/impl.png",
77
+ "states_screenshots": { // optional — when captured
78
+ "loading": "/abs/path/to/loading.png",
79
+ "empty": "/abs/path/to/empty.png",
80
+ "error": "/abs/path/to/error.png",
81
+ "focus": "/abs/path/to/focus.png"
82
+ },
83
+ "design_system_index_path": "...", // present when has_design_system
84
+ "tokens_reference_path": "...", // present when has_design_system
85
+ "ui_guidelines_path": "...", // always, when configured
86
+ "audience_segment": "merchant", // optional — from identity.audience_segments
87
+ "tolerance": "strict" | "balanced" | "lenient"
88
+ }
89
+ ```
90
+
91
+ When `has_design_system: true`, read `design_system_index_path` (Authority
92
+ Matrix + density/scale conventions the project adopted), `tokens_reference_path`
93
+ (the canonical type scale, spacing scale, contrast targets, motion durations
94
+ this project actually uses), and `ui_guidelines_path` (brand voice, intended
95
+ aesthetic, `identity.design_philosophy`). These tell you *which* row of each
96
+ reference table the project chose, so your critique judges against the project's
97
+ own discipline, not a generic ideal.
98
+
99
+ ## The Quality Rubric (CANONICAL — 10 dimensions)
100
+
101
+ This rubric is defined in
102
+ [`framework/agents/design-system-protocol.md`](../../agents/design-system-protocol.md)
103
+ § "Design Quality Rubric" (SSOT for the dimensions, weights, and
104
+ dimension→severity mapping). Judge the screenshot on **each** dimension. For
105
+ each, hold the rendering against the calibration anchors below — *excellent* vs
106
+ *poor* — and emit a finding only when the render lands at or below the "poor"
107
+ anchor (or clearly between the two for a Minor). Cite the numeric table by name
108
+ when a threshold applies.
109
+
110
+ | # | Dimension | Excellent (no finding) | Poor (emit finding) |
111
+ |---|---|---|---|
112
+ | 1 | **Visual hierarchy & focal clarity** | One clear primary focal point; eye lands where the task wants it; size/weight/color/space encode importance | Competing focal points, flat hierarchy, primary CTA indistinguishable from secondary chrome |
113
+ | 2 | **Typographic rhythm** | Sizes track one type scale (§ Type scale), ≤6–9 steps, line-height paired inverse to size; extra hierarchy from weight/color not new sizes | Off-scale sizes, >9 sizes, cramped or loose line-height, headings barely larger than body |
114
+ | 3 | **Spacing rhythm & alignment** | One spacing scale (§ Spacing scale), consistent gaps, elements share alignment edges, optical alignment honored | Arbitrary off-scale gaps, ragged edges, inconsistent padding across similar elements, mixed base-4/base-8 |
115
+ | 4 | **Color & contrast harmony** | Disciplined palette, semantic color use, all text meets § Color contrast targets (WCAG + APCA) | Muddy/clashing palette, color used decoratively without meaning, body text below 4.5:1 / APCA Lc 75 |
116
+ | 5 | **Density consistency** | One density tier (§ Density tiers) coherent with the audience; touch-primary ≥ Comfortable | Tiers mixed without reason, controls cramped on a touch surface, wasteful emptiness on a dense tool |
117
+ | 6 | **Composition & balance** | Deliberate use of negative space, Gestalt grouping (proximity/similarity), visual weight balanced across the canvas | Crowded or unbalanced layout, unrelated items grouped, no breathing room, lopsided weight |
118
+ | 7 | **State & affordance completeness** | Visible/plausible idle, loading, empty, error, focus states; affordances look interactive | Only the happy path rendered; no empty/error/focus treatment; flat controls with no affordance |
119
+ | 8 | **Motion quality** (when motion is observable or `states_screenshots` imply it) | Purposeful, within § motion duration budgets, respects reduced-motion | Gratuitous/janky motion, durations outside budget, no reduced-motion consideration |
120
+ | 9 | **Polish & AI-generic smell** | Intentional, branded, finished; no default-template tells | The "generic AI" look: centered everything, default shadows, evenly-spaced cards, lorem rhythm, no point of view |
121
+ | 10 | **Aesthetic coherence with brand** | Matches `identity.design_philosophy` / `${paths.ui_guidelines}` voice and intended segment | Visually off-brand, tone mismatched to the audience segment, inconsistent with the product's established language |
122
+
123
+ The numeric anchors (type ratios, contrast figures, spacing steps, density
124
+ row-heights, motion durations) live in `design-system-protocol.md` §
125
+ "Reference Tables" — cite them verbatim, never restate from memory.
126
+
127
+ ## Severity Taxonomy (CANONICAL — shared with visual-fidelity-verifier)
128
+
129
+ Reuse the **exact** severity taxonomy defined in
130
+ [`visual-fidelity-verifier.md`](./visual-fidelity-verifier.md) § "Severity
131
+ Taxonomy" so `/e2e-review` Phase 5 consumes both agents' findings through one
132
+ gate. Do not invent new levels. Map each rubric finding to a tier:
133
+
134
+ - **Critical** (blocks in any tolerance): hierarchy collapse that makes the
135
+ primary task unclear, an unreachable/invisible primary action, a layout that
136
+ reads as broken, body text failing contrast so it is effectively unreadable.
137
+ - **Major** (blocks in strict + balanced): off-scale typography or spacing that
138
+ visibly breaks rhythm, clashing/meaningless color, mixed density on a touch
139
+ surface, missing empty/error/focus treatment, generic-AI composition that
140
+ undercuts the brand.
141
+ - **Minor** (blocks only in strict): small rhythm or alignment imperfections,
142
+ mild polish gaps, borderline density choices, motion nitpicks.
143
+
144
+ When a finding also violates the design-system token contract (a hardcoded value
145
+ where a token exists), additionally set `ds_drift_code` to `DS_TOKENS_DRIFT` so
146
+ the orchestrator's drift summary stays unified with the fidelity verifier.
147
+
148
+ ## Tolerance Modes
149
+
150
+ The orchestrator passes `tolerance` from
151
+ `features.e2e_review.fidelity_tolerance` (reused — no new config key). Your job
152
+ is unchanged across modes: **always report every finding with its canonical
153
+ severity**. Filtering is the orchestrator's responsibility. Inflating or
154
+ suppressing severity to match the mode is a protocol violation.
155
+
156
+ ## Output Schema (STRICT — orchestrator parses programmatically)
157
+
158
+ ```json
159
+ {
160
+ "status": "completed" | "skipped" | "error",
161
+ "route": "/dashboard",
162
+ "viewport": { "width": 1440, "height": 900 },
163
+ "quality_score": 0.78,
164
+ "quality_scores": {
165
+ "hierarchy": 0.9,
166
+ "typography": 0.7,
167
+ "spacing": 0.6,
168
+ "color": 0.85,
169
+ "density": 0.8,
170
+ "composition": 0.75,
171
+ "states": 0.5,
172
+ "motion": 1.0,
173
+ "polish": 0.7,
174
+ "brand": 0.9
175
+ },
176
+ "findings": [
177
+ {
178
+ "severity": "critical" | "major" | "minor",
179
+ "dimension": "spacing" | "hierarchy" | "typography" | "color" | "density" | "composition" | "states" | "motion" | "polish" | "brand",
180
+ "description": "Card grid uses 13px and 21px gaps interchangeably; rhythm reads as accidental rather than designed.",
181
+ "expected": "One spacing step — e.g. --space-3 (12px) per the base-4 scale in design-system-protocol.md § Spacing scale.",
182
+ "actual": "Mixed 13px / 21px gaps, off-scale.",
183
+ "fix_hint": "Normalize the card grid `gap` to a single spacing token (--space-3). Likely the dashboard grid container.",
184
+ "evidence": { "region": { "x": 200, "y": 320, "w": 760, "h": 280 } },
185
+ "ds_drift_code": "DS_TOKENS_DRIFT" | null,
186
+ "confidence": "high" | "medium" | "low"
187
+ }
188
+ ],
189
+ "ds_drift_codes": ["DS_TOKENS_DRIFT"],
190
+ "gaps": ["no ui_guidelines configured — brand coherence judged heuristically"],
191
+ "transcript_path": "/tmp/e2e-review/FEAT-XXXX/ui-quality-transcript.md"
192
+ }
193
+ ```
194
+
195
+ **Field rules:**
196
+
197
+ - `quality_scores` is one 0.0–1.0 score per rubric dimension (1.0 = no issue,
198
+ 0.0 = the dimension is badly broken). Omit a dimension only when it is not
199
+ observable from the screenshot (e.g. `motion` on a static page) and note it in
200
+ `gaps[]`.
201
+ - `quality_score` is the weighted aggregate per the weights in
202
+ `design-system-protocol.md` § "Design Quality Rubric". Heuristic, not
203
+ contractual — but be honest: a screen full of Major findings cannot score 0.9.
204
+ - `description` is one English sentence (the framework's lingua franca). It says
205
+ what the screen shows and why it falls short of the rubric.
206
+ - `fix_hint` MUST be actionable and UI-scoped (a layout/spacing/typography/color
207
+ change `ui-expert` can make) — never "make it look better". If you cannot
208
+ produce an actionable hint, drop the finding one tier (or remove it if Minor).
209
+ - `evidence.region` is the bounding box of the issue in the screenshot
210
+ (`x,y,w,h` in viewport CSS pixels). Include it whenever the region is
211
+ unambiguous — region-anchored critique is materially more useful to the fixer.
212
+ - `confidence` defaults to `high`; use `medium` at perceptual thresholds and
213
+ `low` for taste-leaning polish calls. The orchestrator may auto-filter
214
+ `low`-confidence Minor findings even in strict mode.
215
+ - `gaps` lists context you wanted but lacked (no ui_guidelines, no tokens
216
+ reference, static screenshot only). The orchestrator surfaces these.
217
+
218
+ ## Critique Protocol
219
+
220
+ 1. **Load inputs.** Read the implementation screenshot (+ any
221
+ `states_screenshots`). If `has_design_system: true`, read the INDEX, tokens
222
+ reference, and ui-guidelines to learn the project's chosen scale / density /
223
+ palette discipline. Confirm the screenshot is legible.
224
+ 2. **Establish intent.** From `ui_guidelines` + `identity.design_philosophy` +
225
+ `audience_segment`, state to yourself the intended tone and the primary task
226
+ of this screen. The rubric is judged *relative to that intent*, not a
227
+ generic ideal.
228
+ 3. **Walk the rubric dimensions 1→10**, top of the screen to bottom within each.
229
+ Compare against the calibration anchors. Score each dimension; emit a finding
230
+ only where the render reaches the "poor" anchor (Major/Critical) or sits
231
+ clearly between (Minor).
232
+ 4. **Ground every threshold** in the reference tables / tokens reference. Cite
233
+ by exact name (`--space-3`, "Minor Third 1.200 type scale", "Comfortable
234
+ density tier").
235
+ 5. **Compose findings** into the schema. Order by severity (Critical → Major →
236
+ Minor), then by dimension. Compute `quality_scores` and the weighted
237
+ `quality_score`.
238
+
239
+ ## Anti-Hallucination Discipline
240
+
241
+ - If you cannot tell from the screenshot whether something violates the rubric,
242
+ do not emit a finding. False positives cause override fatigue and erode the
243
+ gate. Taste is not a license to invent issues.
244
+ - Distinguish *deliberate aesthetic choice* from *defect*. An asymmetric,
245
+ high-contrast, intentionally sparse layout is not "poor hierarchy" — it may be
246
+ excellent. Judge against the stated intent; when intent is unknown, prefer the
247
+ charitable reading and lower confidence.
248
+ - When the screenshot is too small / blurry / partial, return
249
+ `{ "status": "error", "reason": "screenshot_quality_insufficient",
250
+ "findings": [] }` instead of guessing.
251
+ - Cite tokens and scale steps by **exact name** as they appear in
252
+ `tokens-reference.md` / the reference tables. Never paraphrase.
253
+
254
+ ## What You Are Not
255
+
256
+ - You are not `visual-fidelity-verifier`. It compares the render to a mockup /
257
+ spec (fidelity). You judge intrinsic quality with no mockup required. When
258
+ both run, fidelity findings and quality findings are distinct and both gate.
259
+ - You are not `ui-expert`. That agent *designs and implements* UI (it is the
260
+ fixer in the self-heal loop). You only critique an existing rendering — the
261
+ separation is the entire point (the generator must not grade itself).
262
+ - You are not `code-reviewer`. That agent reviews source for bugs and registry
263
+ compliance. You never read source.
264
+ - You are not the orchestrator. `/e2e-review` aggregates your findings, runs the
265
+ bounded self-heal loop (routing your `source: "design-quality"` findings to
266
+ `ui-expert`), and produces the final pass / block decision.
267
+
268
+ ## Linked Protocols
269
+
270
+ - [`framework/agents/design-system-protocol.md`](../../agents/design-system-protocol.md)
271
+ — SSOT for the Design Quality Rubric (dimensions, weights, severity mapping)
272
+ and the numeric Reference Tables (type scale, contrast, spacing, density,
273
+ motion). Cite, never duplicate.
274
+ - [`framework/.claude/agents/visual-fidelity-verifier.md`](./visual-fidelity-verifier.md)
275
+ — SSOT for the shared severity taxonomy. Your fidelity twin.
276
+ - [`framework/agents/return-contract-protocol.md`](../../agents/return-contract-protocol.md)
277
+ — your JSON output is already the COMPACT return shape (a tight machine
278
+ contract, like the verifier's), so no prose return block is added.
279
+ - [`framework/agents/project-context.md`](../../agents/project-context.md) —
280
+ always-ask / never-assume contract for missing config keys.
281
+
282
+ ## Return Protocol
283
+
284
+ Emit a single JSON object matching the Output Schema above as your final
285
+ message. No prose preamble, no markdown narrative outside the optional
286
+ `transcript_path` file. The orchestrator parses your output programmatically;
287
+ extra prose breaks the gate.
@@ -15,6 +15,15 @@ versus what was intended, with a structured severity tag and a fix hint per
15
15
  finding. The orchestrating skill (`/e2e-review`) decides what to do with your
16
16
  output.
17
17
 
18
+ **Scope vs `ui-quality-critic`.** You answer *"does the render match the
19
+ intended mockup / spec?"* — **fidelity / conformance**. You do NOT judge whether
20
+ the design is *good* (hierarchy, rhythm, balance, polish) — that is the
21
+ `ui-quality-critic` agent's job (*"is this good design, on its own merits?"*).
22
+ Both run in `/e2e-review` (you in Phase 4, the critic in Phase 4b) and both
23
+ findings gate, because a render can be pixel-faithful to a mediocre mockup — or
24
+ have no mockup at all — and still be poor design. Stay in your lane: report
25
+ divergence from the target, not taste.
26
+
18
27
  ## Project Context
19
28
 
20
29
  **Reads from `baldart.config.yml`:**
@@ -21,7 +21,8 @@ description: >
21
21
  **Reads from `baldart.config.yml`:**
22
22
  `paths.backlog_dir`, `paths.app_dir`, `paths.components_primitives`,
23
23
  `paths.components_root`, `paths.e2e_tests_dir`, `paths.design_system`,
24
- `paths.ui_guidelines`, `features.has_e2e_review`,
24
+ `paths.ui_guidelines`, `identity.design_philosophy`,
25
+ `identity.audience_segments`, `features.has_e2e_review`,
25
26
  `features.has_design_system`, `features.has_backlog`,
26
27
  `features.e2e_review.fidelity_tolerance`,
27
28
  `features.e2e_review.max_self_heal_iterations`,
@@ -41,19 +42,22 @@ mockup conventions, override approval policy).
41
42
  `framework/agents/project-context.md` § 3.
42
43
 
43
44
  You are the **E2E Review Orchestrator**. Your single job is to determine,
44
- deterministically, whether an implementation matches its specification both
45
- functionally (the user flow works) and visually (the screen matches the
46
- mockup or the design-system spec). You do not implement. You do not redesign.
47
- You orchestrate three workers (`coder`, `visual-fidelity-verifier`, the
48
- underlying Playwright runner) and aggregate their output through a strict
49
- severity gate.
45
+ deterministically, whether an implementation meets its specification on three
46
+ axes: it works **functionally** (the user flow passes), it matches the
47
+ **mockup** (visual fidelity), and it is **good design** on its own merits
48
+ (intrinsic quality). You do not implement. You do not redesign. You orchestrate
49
+ the workers `coder` and `ui-expert` (fixers), `visual-fidelity-verifier` and
50
+ `ui-quality-critic` (verifiers), and the underlying Playwright runner — and
51
+ aggregate their output through a strict severity gate.
50
52
 
51
53
  This skill embodies the **three-layer harness pattern** for post-implementation
52
54
  verification documented in
53
55
  [Effective Harnesses for Long-Running Agents](https://www.anthropic.com/engineering/effective-harnesses-for-long-running-agents):
54
- the implementing agent (`coder`) and the verifying agent
55
- (`visual-fidelity-verifier`) are distinct, with rule-based aggregation in
56
- between — no agent grades its own work.
56
+ the implementing agents (`coder` / `ui-expert`) and the verifying agents
57
+ (`visual-fidelity-verifier` / `ui-quality-critic`) are distinct, with rule-based
58
+ aggregation in between — **no agent grades its own work** (the quality critic in
59
+ particular never grades a design its sibling `ui-expert` produced; fresh context
60
+ is the point).
57
61
 
58
62
  ## Effort
59
63
 
@@ -370,6 +374,66 @@ For each `route` in `plan.routes[]`:
370
374
 
371
375
  ---
372
376
 
377
+ ## Phase 4b — Design Quality Critique (multimodal agent)
378
+
379
+ **Goal**: judge the **intrinsic design quality** of each rendered route — not
380
+ its fidelity to a mockup. Phase 4 asks *"does the render match the target?"*;
381
+ Phase 4b asks *"is this good design, on its own merits?"*. This closes the gap
382
+ where a render is pixel-faithful to a mediocre mockup (or has no mockup at all)
383
+ yet is still poor design — the documented failure mode that fidelity-only review
384
+ lets through.
385
+
386
+ This phase embodies the same **separation-of-concerns** principle as Phase 4:
387
+ the implementing agent (`ui-expert`) never grades its own design — a distinct
388
+ critic (`ui-quality-critic`) does, with fresh context. (Critic-in-the-loop on
389
+ the rendered output is the mechanism that the research literature shows yields
390
+ the real quality gains, vs. a generator self-rationalizing its work.)
391
+
392
+ **When it runs**: for **every** route that has an implementation screenshot from
393
+ Phase 3 — including `mockup_source.level == "skip"` routes (quality needs no
394
+ mockup). Skip a route only when no screenshot was captured, or when BOTH
395
+ `features.has_design_system: false` AND `${paths.ui_guidelines}` is unset (no
396
+ quality oracle at all — log `no_quality_oracle` in `gaps[]`).
397
+
398
+ For each such `route`:
399
+
400
+ 1. **No pixel-diff pre-filter.** Quality is not pre-filterable by pixel delta —
401
+ always invoke the critic when a screenshot exists.
402
+ 2. **Invoke `ui-quality-critic`** with the input contract documented in
403
+ [`ui-quality-critic.md`](../../agents/ui-quality-critic.md):
404
+
405
+ ```
406
+ subagent_type: "ui-quality-critic"
407
+ mode: "bypassPermissions" // when called from /new
408
+ prompt: |
409
+ Judge the design quality of this rendering against your rubric and return
410
+ JSON per your output schema.
411
+
412
+ Input payload:
413
+ {
414
+ "card_id": "FEAT-XXXX",
415
+ "route": "/dashboard",
416
+ "viewport": { "width": 1440, "height": 900 },
417
+ "implementation_screenshot_path": ".baldart/e2e-review/FEAT-XXXX/screenshots/merchant-dashboard.png",
418
+ "states_screenshots": { ... }, // optional, when captured
419
+ "design_system_index_path": "<when has_design_system>",
420
+ "tokens_reference_path": "<when has_design_system>",
421
+ "ui_guidelines_path": "${paths.ui_guidelines}",
422
+ "audience_segment": "<from identity.audience_segments, optional>",
423
+ "tolerance": "<from config>"
424
+ }
425
+ ```
426
+ 3. **Parse the agent's JSON response** strictly (same discipline as Phase 4): if
427
+ it returns prose outside the JSON, log `quality_critic_protocol_violation` in
428
+ `gaps[]` and treat the route's quality findings as empty — do not invent
429
+ findings from prose.
430
+ 4. **Aggregate** quality findings across all routes into a single
431
+ `quality_findings[]` array (tag each `source: "design-quality"`,
432
+ `dimension: <rubric dim>`), and collect each route's `quality_score` for the
433
+ report's `quality_score_avg`.
434
+
435
+ ---
436
+
373
437
  ## Phase 5 — Aggregation + Severity Gate (STRICT default)
374
438
 
375
439
  **Goal**: combine functional + visual findings into a single verdict using
@@ -378,9 +442,12 @@ the canonical severity taxonomy from `visual-fidelity-verifier.md`.
378
442
  1. **Compose** the `findings[]` array:
379
443
  - Functional findings from Phase 3 (`source: "functional"`).
380
444
  - Visual findings from Phase 4 (`source: "visual"`).
381
- - Each finding carries: `severity`, `category`, `source`, `route`,
382
- `description`, `expected`, `actual`, `fix_hint`, `evidence`,
383
- `ds_drift_code`, `confidence`.
445
+ - Design-quality findings from Phase 4b (`source: "design-quality"`).
446
+ - Each finding carries: `severity`, `category` (or `dimension` for
447
+ design-quality), `source`, `route`, `description`, `expected`, `actual`,
448
+ `fix_hint`, `evidence`, `ds_drift_code`, `confidence`. All three sources
449
+ share the **same canonical severity taxonomy**, so the tolerance filter in
450
+ step 2 applies to them uniformly — no per-source special-casing.
384
451
  2. **Apply tolerance filter** based on
385
452
  `features.e2e_review.fidelity_tolerance`:
386
453
  - `strict` (DEFAULT): Critical + Major + Minor all gate. Additionally,
@@ -401,31 +468,69 @@ applies only when `verdict == "blocked"` AND `iteration < max`.
401
468
 
402
469
  For each iteration:
403
470
 
404
- 1. **Spawn a `coder` agent** with this contract:
405
-
406
- ```
407
- The /e2e-review skill found the following gating findings on card
408
- <CARD-ID>. Implement minimal, surgical fixes do not refactor.
409
-
410
- ## Gating findings
411
- [paste the JSON findings filtered to gating severity]
412
-
413
- ## Rules
414
- - File ownership: stay within the card's allowed file set (see
415
- /tmp/batch-tracker-<FIRST-CARD-ID>.md ## File Ownership Map).
416
- - One fix per finding when possible. Reuse existing tokens / primitives
417
- before inventing new ones (cite ${paths.design_system}/INDEX.md +
418
- tokens-reference.md).
419
- - After the fixes, re-run lint and typecheck. Both must pass.
420
- - Do NOT modify Playwright specs or this skill's state files.
421
-
422
- ## Out of scope
423
- - Visual polish beyond the findings listed.
424
- - New features or scope expansion.
425
- ```
426
-
427
- 2. **Re-run Phase 3 (functional) and Phase 4 (visual)** with fresh
428
- screenshots. Increment `iteration`.
471
+ 1. **Route the gating findings to the right fixer by `source`**, then spawn the
472
+ fixer(s). Design-quality fixes are UI-scoped (presentation / layout / styling
473
+ / motion) — they belong to `ui-expert`, the UI domain owner, NOT to `coder`.
474
+ Functional fixes belong to `coder`. (Visual-fidelity findings follow their
475
+ nature: token/spacing/typography fixes route to `ui-expert`; a missing or
476
+ mis-wired element route to `coder`.) When both buckets are non-empty, run
477
+ `coder` first (structure), then `ui-expert` (presentation), so the critic
478
+ re-evaluates the final surface.
479
+
480
+ - **`ui-expert`** — gating findings where `source == "design-quality"` (and
481
+ UI-presentation `source == "visual"` findings):
482
+
483
+ ```
484
+ The /e2e-review design-quality / visual gate found the following gating
485
+ findings on card <CARD-ID>. Apply minimal, surgical UI fixes within the
486
+ UI-only scope contract (presentation, layout, styling, motion, a11y)
487
+ never business logic or data fetching. Do not redesign beyond the findings.
488
+
489
+ ## Gating findings
490
+ [paste the JSON findings filtered to gating severity, source in
491
+ {design-quality, visual}]
492
+
493
+ ## Rules
494
+ - File ownership: stay within the card's allowed file set (see
495
+ /tmp/batch-tracker-<FIRST-CARD-ID>.md ## File Ownership Map).
496
+ - One fix per finding. Reuse existing tokens / primitives before inventing
497
+ new ones (cite ${paths.design_system}/INDEX.md + tokens-reference.md).
498
+ - Run the Post-Intervention Coherence Check on any registry-touching fix.
499
+ - After the fixes, re-run lint and typecheck. Both must pass.
500
+ - Do NOT modify Playwright specs or this skill's state files.
501
+
502
+ ## Out of scope
503
+ - Polish beyond the findings listed. New features or scope expansion.
504
+ ```
505
+
506
+ - **`coder`** — gating findings where `source == "functional"` (and
507
+ structural `source == "visual"` findings: missing element, broken wiring):
508
+
509
+ ```
510
+ The /e2e-review skill found the following gating findings on card
511
+ <CARD-ID>. Implement minimal, surgical fixes — do not refactor.
512
+
513
+ ## Gating findings
514
+ [paste the JSON findings filtered to gating severity, source in
515
+ {functional, visual-structural}]
516
+
517
+ ## Rules
518
+ - File ownership: stay within the card's allowed file set (see
519
+ /tmp/batch-tracker-<FIRST-CARD-ID>.md ## File Ownership Map).
520
+ - One fix per finding when possible. Reuse existing tokens / primitives
521
+ before inventing new ones (cite ${paths.design_system}/INDEX.md +
522
+ tokens-reference.md).
523
+ - After the fixes, re-run lint and typecheck. Both must pass.
524
+ - Do NOT modify Playwright specs or this skill's state files.
525
+
526
+ ## Out of scope
527
+ - Visual polish beyond the findings listed. New features or scope expansion.
528
+ ```
529
+
530
+ Both fixers run in `bypassPermissions` mode when called by `/new`.
531
+
532
+ 2. **Re-run Phase 3 (functional), Phase 4 (visual), and Phase 4b (quality)**
533
+ with fresh screenshots. Increment `iteration`.
429
534
  3. **Re-aggregate and re-decide** (back to Phase 5 step 1).
430
535
  4. **STOP** when `verdict == "passed"` OR `iteration == max`.
431
536
 
@@ -477,6 +582,11 @@ Write the final report to `.baldart/e2e-review/<CARD-ID>/report.json`:
477
582
  "routes_pre_filtered": 1,
478
583
  "compliance_score_avg": 0.94
479
584
  },
585
+ "quality": {
586
+ "routes_critiqued": 3,
587
+ "quality_score_avg": 0.81,
588
+ "weakest_dimensions": ["states", "spacing"]
589
+ },
480
590
  "findings": [ ... ],
481
591
  "ds_drift_codes": ["DS_TOKENS_DRIFT"],
482
592
  "gaps": [ ... ],
@@ -523,6 +633,14 @@ and starts from Phase 3 (skipping plan extraction and mockup cascade).
523
633
  - **`/design-review` command** — when invoked from this skill with
524
634
  `mode: "programmatic"`, returns JSON instead of Markdown for gating.
525
635
  See [`framework/.claude/commands/design-review.md`](../../commands/design-review.md).
636
+ - **`visual-fidelity-verifier`** (Phase 4) — judges fidelity to the mockup /
637
+ spec. See [`visual-fidelity-verifier.md`](../../agents/visual-fidelity-verifier.md).
638
+ - **`ui-quality-critic`** (Phase 4b) — judges intrinsic design quality against
639
+ the rubric, independent of any mockup. See
640
+ [`ui-quality-critic.md`](../../agents/ui-quality-critic.md). It is the design
641
+ twin of `code-reviewer`; `ui-expert` is its fixer in the self-heal loop.
642
+ - **`ui-expert`** — the UI domain owner; fixes `design-quality` (and
643
+ UI-presentation `visual`) gating findings in the Phase 5b self-heal loop.
526
644
  - **`playwright-skill`** — tooling layer for spec execution. See its
527
645
  "E2E Review Integration" section.
528
646
  - **`webapp-testing`** — used in compliance-only mode for runtime DOM
@@ -554,6 +672,8 @@ and starts from Phase 3 (skipping plan extraction and mockup cascade).
554
672
  | Pixel-diff always 100% | Implementation screenshot dimensions ≠ mockup dimensions | Confirm viewport in Phase 3 matches the mockup's target width; resize mockup if needed |
555
673
  | Visual findings dominated by `font-rendering-variance` | Anti-aliasing / subpixel differences across OS | Tolerance is doing its job — these auto-demote in strict mode when `confidence: low` |
556
674
  | Self-heal loop never converges | `coder` introducing new regressions while fixing | After max iterations, override with reason and open a follow-up backlog card |
675
+ | Quality loop never converges (design-quality findings persist) | Taste-leaning Minor findings, or `ui-expert` fixing one dimension while regressing another | Confirm the findings are gating (not low-confidence Minor auto-demoted in strict). If genuine and unresolved after max iterations, override with reason and open a `ui-expert` follow-up card — do NOT block indefinitely on subjective polish |
676
+ | `quality_critic_protocol_violation` in gaps | `ui-quality-critic` returned prose mixed with JSON | Re-spawn the critic once; if persistent, surface to user (likely a model regression). Treat that route's quality findings as empty meanwhile |
557
677
  | `verifier_protocol_violation` in gaps | `visual-fidelity-verifier` returned prose mixed with JSON | Re-spawn the verifier once; if persistent, surface to user (likely a model regression) |
558
678
 
559
679
  ---
@@ -196,6 +196,80 @@ enhanced target). Mixing tiers within the same view is allowed only when the
196
196
  information density genuinely demands it (e.g. compact data table inside a
197
197
  cozy app shell) — document the exception in the registry.
198
198
 
199
+ ## Design Quality Rubric
200
+
201
+ This is the SSOT for **intrinsic design quality** — the dimensions, weights, and
202
+ severity mapping a critic uses to judge whether a rendered screen is *good
203
+ design*, independent of whether it matches a mockup. The
204
+ `ui-quality-critic` agent consumes this section (it cites these dimensions and
205
+ grounds every numeric threshold in the Reference Tables above); the
206
+ `/e2e-review` skill gates on the critic's output.
207
+
208
+ This complements — does not replace — the fidelity check
209
+ (`visual-fidelity-verifier`, "does the render match the mockup?"). Fidelity asks
210
+ *conformance*; this rubric asks *quality*. A render can be pixel-faithful to a
211
+ mediocre mockup, or have no mockup at all, and still be poor design — this rubric
212
+ is what catches that.
213
+
214
+ ### Gating
215
+
216
+ The rubric is **not** gated on `features.has_design_system`. Quality is judged on
217
+ every UI surface: when a registry exists, the critic grounds numeric thresholds
218
+ in the project's `tokens-reference.md`; when it does not, it grounds them in the
219
+ Reference Tables above + `${paths.ui_guidelines}`. The wiring gate is
220
+ `features.has_e2e_review` (the critic exists to serve `/e2e-review`).
221
+
222
+ ### The 10 dimensions + weights
223
+
224
+ Each dimension is scored 0.0–1.0 (1.0 = no issue). The weighted mean is the
225
+ `quality_score`. Weights bias toward dimensions that most determine whether a
226
+ screen *works* over pure taste.
227
+
228
+ | # | Dimension | Weight | Judges | Reference table |
229
+ |---|---|---|---|---|
230
+ | 1 | Visual hierarchy & focal clarity | 0.15 | One clear focal point; importance encoded by size/weight/color/space | Type scale |
231
+ | 2 | Typographic rhythm | 0.12 | Sizes on one scale, ≤6–9 steps, paired line-height | Type scale |
232
+ | 3 | Spacing rhythm & alignment | 0.12 | One spacing scale, consistent gaps, shared alignment edges | Spacing scale |
233
+ | 4 | Color & contrast harmony | 0.12 | Disciplined, semantic palette; text meets contrast targets | Color contrast targets |
234
+ | 5 | Density consistency | 0.08 | One density tier coherent with the audience | Density tiers |
235
+ | 6 | Composition & balance | 0.10 | Negative space, Gestalt grouping, balanced visual weight | — |
236
+ | 7 | State & affordance completeness | 0.13 | Idle/loading/empty/error/focus present; affordances read as interactive | — |
237
+ | 8 | Motion quality | 0.05 | Purposeful, within duration budgets, reduced-motion aware | (motion-design skill) |
238
+ | 9 | Polish & AI-generic smell | 0.08 | Intentional/branded; no default-template tells | — |
239
+ | 10 | Aesthetic coherence with brand | 0.05 | Matches `identity.design_philosophy` / `${paths.ui_guidelines}` | — |
240
+
241
+ Weights sum to 1.00. Dimensions not observable from the screenshot (e.g. motion
242
+ on a static capture) are dropped and the remaining weights renormalized.
243
+
244
+ ### Dimension → severity mapping
245
+
246
+ The critic maps each finding onto the **canonical severity taxonomy** defined in
247
+ `framework/.claude/agents/visual-fidelity-verifier.md` § "Severity Taxonomy" (so
248
+ fidelity and quality findings flow through one `/e2e-review` gate). The
249
+ rule of thumb:
250
+
251
+ - **Critical** — the dimension failure breaks the task: hierarchy so flat the
252
+ primary action is unclear, a primary action invisible/unreachable, body text
253
+ effectively unreadable (below the § Color contrast targets floor), a layout
254
+ that reads as broken.
255
+ - **Major** — visible rhythm/quality break that a competent designer would
256
+ reject: off-scale type or spacing, clashing or meaningless color, mixed
257
+ density on a touch surface, missing empty/error/focus treatment, generic-AI
258
+ composition undercutting the brand.
259
+ - **Minor** — small imperfection: 1–2px alignment drift, mild polish gap,
260
+ borderline density, motion nitpick.
261
+
262
+ When a quality finding also bypasses a token, set `ds_drift_code:
263
+ DS_TOKENS_DRIFT` so the orchestrator's drift summary stays unified.
264
+
265
+ ### Calibration discipline (why this beats a single "looks good?" prompt)
266
+
267
+ Judging each dimension separately against explicit *excellent vs poor* anchors —
268
+ rather than asking one holistic "is this good?" — is what makes the critique
269
+ reproducible and actionable. The per-dimension anchors live in the
270
+ `ui-quality-critic` agent body; this section owns the dimension list, the
271
+ weights, and the severity mapping so they cannot drift across consumers.
272
+
199
273
  ## Token Cascade: primitive → semantic → component
200
274
 
201
275
  A mature token system has **three layers**, and components consume only the
@@ -431,6 +505,8 @@ The following files reference this module instead of duplicating its rules:
431
505
 
432
506
  - `framework/.claude/agents/ui-expert.md`
433
507
  - `framework/.claude/agents/code-reviewer.md`
508
+ - `framework/.claude/agents/ui-quality-critic.md` (Design Quality Rubric — the
509
+ intrinsic-quality critic consumed by `/e2e-review` Phase 4b)
434
510
  - `framework/.claude/skills/ui-design/SKILL.md`
435
511
  - `framework/.claude/skills/frontend-design/SKILL.md`
436
512
  - `framework/.claude/skills/design-system-init/SKILL.md`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "baldart",
3
- "version": "4.60.0",
3
+ "version": "4.61.0",
4
4
  "description": "Claude Agent Framework - Reusable framework for coordinating AI agents and humans in software projects",
5
5
  "bin": {
6
6
  "baldart": "./bin/baldart.js"