baldart 3.18.0 → 3.18.1

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,31 @@ 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
+ ## [3.18.1] - 2026-05-25
9
+
10
+ Chiusura del debito tecnico introdotto da v3.18.0. Il release v3.18.0 ha annunciato che `/design-review` supporta un programmatic JSON output mode invocabile da `/e2e-review` per gating uniforme — ma l'implementazione era una sola nota nel frontmatter ("se invocato con `mode: programmatic` ritorna JSON") senza body command che la concretizzasse, senza schema vincolato, senza mode-detection deterministica, senza taxonomy mapping tra le severity Markdown (Blockers/High/Medium/Nitpicks) e le severity programmatic (critical/major/minor) del `visual-fidelity-verifier`. Il risultato: una feature half-implemented, parsable only in teoria. Questo PATCH la rende reale.
11
+
12
+ L'adversarial review del piano v3.19.0 (multi-viewport + interactive states + Phase 4b design judgment pass) ha esplicitamente identificato il problema: "`/design-review` programmatic JSON è vaporware in v3.18.0 — va prima implementato bene come release a sé". Questa release fa esattamente quello, separando la chiusura del debito dall'aggiunta di nuove feature, in modo che v3.19.0 (quando arriverà, post-dogfooding) possa appoggiarsi a un contratto programmatic stabile invece di costruirsi sopra una stub.
13
+
14
+ ### Fixed — `/design-review` dual-mode reale (Markdown ↔ JSON)
15
+
16
+ - **[framework/.claude/commands/design-review.md](framework/.claude/commands/design-review.md) riscritto** (frontmatter invariato, body completamente sostituito). Quattro sezioni nuove + workflow rivisto:
17
+ - **§ Invocation Modes**: documenta esplicitamente Mode A (interactive, Markdown — il comportamento storico) e Mode B (programmatic, JSON-only — il nuovo contratto). L'envelope JSON di input per Mode B è specificato verbatim: `{mode, card_id, route, viewport, dev_server_port, registry_paths: {index, tokens, components_dir}, ui_guidelines_path, features: {has_design_system, multi_tenant_theming}, tolerance}`. Il comando lo riceve passato dall'orchestratore `/e2e-review` quando Phase 4b sarà introdotta.
18
+ - **§ Programmatic output schema**: schema JSON di output vincolato, allineato verbatim a `framework/.claude/agents/visual-fidelity-verifier.md` § "Output Schema" per uniformità di parsing nell'aggregatore orchestratore. Campo `source: "design-review"` distingue le finding di questo command da quelle del verifier in modalità debug; i campi `findings[].severity`/`category`/`description`/`expected`/`actual`/`fix_hint`/`evidence`/`ds_drift_code`/`confidence` sono shape-identici. La deduplicazione cross-source avviene per `(route, category, ds_drift_code)` con precedenza al verifier quando duplicate (più strutturato).
19
+ - **§ Severity normalization (Markdown ↔ programmatic)**: tabella di mapping deterministica Blocker → `critical`, High → `major`, Medium → `minor`, Nitpick → DROP. Il drop dei Nitpick in modalità programmatic è deliberato (troppo noise per gating; restano nel report Markdown per uso interattivo).
20
+ - **§ Programmatic-mode category taxonomy**: enumera le 10 categorie ammesse in Mode B (`primitive-reinvented`, `primitive-missing-spec`, `token-bypass`, `component-stale`, `index-drift`, `authority-violation`, `brand-voice-drift`, `a11y-contrast`, `a11y-focus-visible`, `interactive-state-missing`) — sottoinsieme della tassonomia canonica del verifier adattato allo scope di design judgment di questo command. Categorie non in lista vanno emesse come stringhe libere in `gaps[]`, MAI come nuove categorie inventate (l'orchestratore non sa pesarle).
21
+ - **§ Workflow (both modes)**: passi 0–5 unificati per Mode A e Mode B, con la divergenza solo nel formato di output finale (passi 4 e 5). Mode B usa `dev_server_port` dall'envelope per costruire URL, salva screenshot in `/tmp/design-review/<route-slug>.png` per cross-reference dall'orchestratore.
22
+ - **§ Mode-detection contract**: regola deterministica anti-ambiguità — Mode B è triggered SOLO se l'input contiene la substring esatta `"mode": "programmatic"` (con quote, come appare nell'envelope JSON). Vietato auto-detection da contesto invocazione ("sto girando dentro a una skill") — produce silent Markdown leakage nel parser dell'orchestratore che rompe il gate. Su envelope malformato emette `{status: "error", source: "design-review", reason: "malformed_input_envelope", findings: []}` invece di fallback a Mode A (il fallback silenzioso bloccherebbe la card invece di segnalare).
23
+
24
+ ### Notes
25
+
26
+ - **Nessun cambio framework payload oltre al command.** Nessun nuovo agente, nessuna nuova skill, nessuna nuova chiave config, nessuna modifica a `/new` o `/e2e-review`. Solo il command `/design-review` viene reso effettivamente dual-mode come annunciato in v3.18.0. `/e2e-review` non lo invoca ancora — quella connessione (Phase 4b) viene rimandata a una future release post-dogfooding, sulla base di dati reali su quanto valore aggiunge la judgment pass sopra il `visual-fidelity-verifier`.
27
+ - **Backward compatibility totale per uso interattivo**: utenti che invocano `/design-review /merchant/dashboard` continuano a ricevere il Markdown report identico a v3.17.x e prima. Mode A è il default; Mode B è opt-in via envelope JSON esplicito.
28
+ - **Severity taxonomy in lockstep**: il body del command include una nota esplicita "quando aggiorni la taxonomy qui, aggiorna in lockstep `framework/.claude/agents/visual-fidelity-verifier.md` § Severity Taxonomy". Le due fonti restano allineate per evitare drift cross-source nell'aggregatore.
29
+ - **Versioning rationale.** PATCH (3.18.0 → 3.18.1): no new capability. Il contratto Mode B era già annunciato in v3.18.0; questa release rende l'annuncio reale. Decision tree CLAUDE.md: "Doc fix, script bugfix, perf, security patch with no behaviour change → PATCH" — qualifica perché la behavior change è solo per chi sta ancora costruendo l'integrazione (nessun consumer esistente la invoca programmatically oggi).
30
+ - **Verification** (manuale, no test suite): (1) `/design-review /merchant/dashboard` interattivo → Markdown identico al pre-3.18.1 (regression check Mode A); (2) input contenente `"mode": "programmatic"` → JSON-only output, no preamble, parsable da `JSON.parse()`; (3) envelope malformato → emette `{status: "error", reason: "malformed_input_envelope"}` senza fallback a Markdown; (4) campi `route`/`dev_server_port` mancanti dall'envelope → stesso errore; (5) finding di severity Nitpick → presente in Mode A, assente da Mode B `findings[]`.
31
+ - **Path post-3.18.1**: dogfooding di v3.18.0 + 3.18.1 per 1–2 settimane su feature UI reali. Sulla base di falsi positivi/negativi raccolti, decidere data-driven quali estensioni includere in v3.19.0 tra: multi-viewport (mobile/desktop/tablet), interactive states (hover/focus/active/disabled + opt-in loading/empty/error), Phase 4b design judgment pass che invoca `/design-review` in Mode B all'interno di `/e2e-review`. L'adversarial review ha esplicitamente sconsigliato il bundle v3.19.0 senza dati di dogfooding — questa release rispetta quella raccomandazione.
32
+
8
33
  ## [3.18.0] - 2026-05-25
9
34
 
10
35
  The end-to-end review fase post-implementazione diventa un **gate deterministico e BLOCKING** invece di un assortimento di check advisory. Until v3.17.x, la chiusura di una card via `/new` attraversava tre fasi eterogenee tutte non-bloccanti sul fronte UI: Phase 2.5 (Implementation Completeness Check) validava solo card AC / PRD alignment / code quality / schema / artifacts senza alcun gate visivo o funzionale runtime; Phase 2.6 (E2E Testing) era *condizionale* (solo con `test_plan.e2e_required: true` o QA profile BALANCED/DEEP) e invocava `qa-sentinel` che per charter (`qa-sentinel.md:151-161`) esegue solo gate meccanici (lint/type/test/build/audit) — non test browser-based né design; Phase 2.7 (Visual Design Review) invocava `ui-expert` ma era esplicitamente marcata "advisory, non-blocking" (`new/SKILL.md:897` — "findings logged but do NOT block commit"). Le skill `webapp-testing` e `playwright-skill` esistevano ma non erano mai auto-invocate da `/new`. La routine `ds-drift` (`framework/routines/ds-drift.routine.yml`) girava settimanalmente, catturando il drift visivo 1–7 giorni dopo il merge. **Conseguenza concreta** lamentata dall'utente: doveva rifare manualmente la review schermata-per-schermata di ogni card UI, e i dettagli grafici dei mockup venivano regolarmente ignorati.
package/VERSION CHANGED
@@ -1 +1 @@
1
- 3.18.0
1
+ 3.18.1
@@ -2,19 +2,140 @@
2
2
  description: Trigger the design-review subagent with MCP Playwright for the specified route.
3
3
  allowed-tools: Bash, Grep, LS, Read, WebFetch, TodoWrite, WebSearch, BashOutput, KillBash, ListMcpResourcesTool, ReadMcpResourceTool, mcp__playwright__browser_navigate, mcp__playwright__browser_click, mcp__playwright__browser_take_screenshot, mcp__playwright__browser_console_messages
4
4
  ---
5
- > **Invocation mode** — When invoked **interactively** by the user, produce the Markdown report described below (Blockers/High/Medium/Nitpicks). When invoked **programmatically** by the `/e2e-review` skill (input includes `"mode": "programmatic"`), return a single JSON object matching the `visual-fidelity-verifier` output schema (`framework/.claude/agents/visual-fidelity-verifier.md` § "Output Schema") so the orchestrator can parse it for gating. No prose preamble in programmatic mode.
6
5
 
7
- You are the design-review subagent. Ensure `npm run design-review` is running before continuing so Playwright MCP can expose `localhost:9221` to Claude. When the user invokes `/design-review`, do the following:
6
+ You are the design-review subagent. Ensure `npm run design-review` is running before continuing so Playwright MCP can expose `localhost:9221` to Claude.
7
+
8
+ ## Invocation Modes (since v3.18.1)
9
+
10
+ This command supports two output modes, detected from the input prompt:
11
+
12
+ ### Mode A — Interactive (default)
13
+
14
+ When the user invokes `/design-review` directly (input is a natural-language route reference, e.g. `/design-review /merchant/dashboard`), produce the **Markdown report** described in steps 1–5 below. Use the Blockers/High/Medium/Nitpicks template from `agents/design-review.md` § Report Template.
15
+
16
+ ### Mode B — Programmatic (invoked by `/e2e-review`)
17
+
18
+ When the input contains a JSON envelope with `"mode": "programmatic"` at any position (typical payload from `/e2e-review` Phase 4b), switch to **JSON-only output**. No prose preamble, no Markdown, no closing remarks — a single JSON object as the final message, parseable by `JSON.parse()` on the orchestrator side.
19
+
20
+ **Programmatic input envelope** (passed verbatim by `/e2e-review`):
21
+
22
+ ```json
23
+ {
24
+ "mode": "programmatic",
25
+ "card_id": "FEAT-XXXX",
26
+ "route": "/merchant/dashboard",
27
+ "viewport": { "width": 1440, "height": 900 },
28
+ "dev_server_port": 3000,
29
+ "registry_paths": {
30
+ "index": "docs/design-system/INDEX.md",
31
+ "tokens": "docs/design-system/tokens-reference.md",
32
+ "components_dir": "docs/design-system/components"
33
+ },
34
+ "ui_guidelines_path": "docs/references/ui-guidelines.md",
35
+ "features": {
36
+ "has_design_system": true,
37
+ "multi_tenant_theming": false
38
+ },
39
+ "tolerance": "strict"
40
+ }
41
+ ```
42
+
43
+ **Programmatic output schema** (MUST match this shape verbatim — `/e2e-review` Phase 5 aggregates this output alongside `visual-fidelity-verifier` findings, deduplicating by `(route, category, ds_drift_code)`):
44
+
45
+ ```json
46
+ {
47
+ "status": "completed" | "skipped" | "error",
48
+ "source": "design-review",
49
+ "route": "/merchant/dashboard",
50
+ "viewport": { "width": 1440, "height": 900 },
51
+ "findings": [
52
+ {
53
+ "severity": "critical" | "major" | "minor",
54
+ "category": "<category from taxonomy below>",
55
+ "description": "One-sentence description of what the design-review observed.",
56
+ "expected": "Brief reference to the design intent (token name, spec excerpt, guideline section).",
57
+ "actual": "Brief reference to what the rendered output shows.",
58
+ "fix_hint": "Actionable single-line hint. Never 'make it look right'.",
59
+ "evidence": {
60
+ "selector": "[data-testid='...']" | "css-selector",
61
+ "screenshot_path": "/tmp/design-review/<route-slug>.png"
62
+ },
63
+ "ds_drift_code": "DS_INDEX_DRIFT" | "DS_COMPONENT_STALE" | "DS_TOKENS_DRIFT" | null,
64
+ "confidence": "high" | "medium" | "low"
65
+ }
66
+ ],
67
+ "ds_drift_codes": ["DS_INDEX_DRIFT", "DS_TOKENS_DRIFT"],
68
+ "gaps": [
69
+ "Could not find registry spec for primitive `Badge` — flagged as DS_INDEX_DRIFT instead of comparing against spec."
70
+ ]
71
+ }
72
+ ```
73
+
74
+ #### Severity normalization (Markdown ↔ programmatic)
75
+
76
+ The interactive Markdown report uses Blockers/High/Medium/Nitpicks. In programmatic mode, normalize as follows for cross-source aggregation with `visual-fidelity-verifier`:
77
+
78
+ | Markdown tier | Programmatic `severity` | Notes |
79
+ |---|---|---|
80
+ | Blocker | `critical` | Layout broken, primary CTA unreachable, accessibility blocker, security exposure |
81
+ | High | `major` | Token bypass, reinvented primitive, spec divergence on visible prop, contrast failure |
82
+ | Medium | `minor` | Stale spec doc, cosmetic spacing drift, micro-misalignments |
83
+ | Nitpick | DROP | Do not emit in programmatic output — too noisy for gating |
84
+
85
+ #### Programmatic-mode category taxonomy
86
+
87
+ Use these categories (subset of the canonical taxonomy in `framework/.claude/agents/visual-fidelity-verifier.md` § "Severity Taxonomy", adapted for the design-judgment scope of this command). The orchestrator deduplicates findings across sources by `(route, category)`, so categories MUST match the canonical names verbatim:
88
+
89
+ - `primitive-reinvented` (Major) — reimplements a primitive that already exists in `INDEX.md`
90
+ - `primitive-missing-spec` (Major) — new primitive shipped without `components/<Name>.md`
91
+ - `token-bypass` (Major) — hardcoded color/spacing/shadow/radius where a token exists
92
+ - `component-stale` (Minor) — `components/<Name>.md` out of sync with the implemented primitive
93
+ - `index-drift` (Minor) — primitive used but missing from `INDEX.md`
94
+ - `authority-violation` (Major) — local override of a registry-authoritative decision (per Authority Matrix)
95
+ - `brand-voice-drift` (Minor) — microcopy/UI language drift from `${paths.ui_guidelines}` brand voice
96
+ - `a11y-contrast` (Major) — body text < 4.5:1 or focus indicator < 3:1
97
+ - `a11y-focus-visible` (Major) — interactive element with no equivalent focus indicator
98
+ - `interactive-state-missing` (Major) — hover/focus/active visually identical to idle on interactive primitive
99
+
100
+ When a finding does not match any of these categories, drop it from programmatic output rather than inventing a new category — the orchestrator's aggregator does not know how to weigh unknown categories. Surface it in the `gaps[]` array as a free-text note instead.
101
+
102
+ ---
103
+
104
+ ## Workflow (both modes)
105
+
106
+ When the user invokes `/design-review`, do the following (in both modes — only the final output format differs):
8
107
 
9
108
  0. **BLOCKING when `features.has_design_system: true`** — before opening the browser, execute the registry-first pre-work defined in `agents/design-system-protocol.md`:
10
109
  - Read `${paths.design_system}/INDEX.md` and the Authority Matrix for the surface under review.
11
110
  - Read `${paths.design_system}/tokens-reference.md`.
12
111
  - Read `${paths.design_system}/components/<Name>.md` for every primitive expected on the route.
13
- When the flag is `false`, skip the registry reads but flag the gap in the final report and recommend `/design-system-init`.
14
- 1. Start with the route or component specified (e.g., `/merchant/dashboard`) and open it in the MCP browser.
112
+ When the flag is `false`, skip the registry reads. In Mode A flag the gap in the final report and recommend `/design-system-init`. In Mode B add the gap to the `gaps[]` array of the JSON output.
113
+ 1. Start with the route or component specified (e.g., `/merchant/dashboard`) and open it in the MCP browser. In Mode B, use the `dev_server_port` from the input envelope to construct `http://localhost:<port><route>`.
15
114
  2. Follow the Quick Visual Check in `agents/design-review.md` and run Phases 0‑7 (interaction, responsiveness, polish, accessibility, robustness, code health, content/console).
16
- 3. Capture at least one full-page screenshot at 1440px and note console errors.
17
- 4. Report findings using the Markdown template listed in the same document (Blockers/High/Medium/Nitpicks).
18
- 5. **Include a `Design-System Conformance` section in the report** — primitives reused, primitives reinvented (HIGH), tokens bypassed (HIGH), spec drift (MEDIUM), new primitives proposed. Template in `agents/design-review.md` § Report Template.
115
+ 3. Capture at least one full-page screenshot at the viewport from the input (default 1440px) and note console errors. In Mode B save the screenshot at `/tmp/design-review/<route-slug>.png` and cite it in `evidence.screenshot_path`.
116
+ 4. **Mode A**: report findings using the Markdown template in `agents/design-review.md` (Blockers/High/Medium/Nitpicks). **Mode B**: assemble the JSON output described above, normalizing severity per the table.
117
+ 5. **Design-System Conformance section** — primitives reused, primitives reinvented (HIGH→major), tokens bypassed (HIGH→major), spec drift (MEDIUM→minor), new primitives proposed.
118
+ - **Mode A**: include as a top-level section in the Markdown report per `agents/design-review.md` § Report Template.
119
+ - **Mode B**: emit as `findings[]` entries with the appropriate categories from the taxonomy above, and populate `ds_drift_codes[]` with the deduplicated set.
120
+
121
+ ## Mode-detection contract (avoid silent misdetection)
122
+
123
+ The dual-mode design is deterministic only if the trigger is unambiguous. Apply these rules in order:
124
+
125
+ 1. If the input prompt contains the exact substring `"mode": "programmatic"` (with quotes, as it appears in the JSON envelope) → **Mode B**, JSON only.
126
+ 2. Else if the input is a route path or natural-language reference → **Mode A**, Markdown.
127
+ 3. **Never auto-detect from invocation context** (e.g., "I'm running inside a skill") — that is unreliable and produces silent Markdown leakage into the orchestrator's JSON parser, which breaks the gate.
128
+
129
+ In Mode B, if the JSON envelope is malformed (cannot be parsed) or required fields (`route`, `dev_server_port`) are missing, emit:
130
+
131
+ ```json
132
+ { "status": "error", "source": "design-review", "reason": "malformed_input_envelope", "findings": [] }
133
+ ```
134
+
135
+ Do not fall back to Mode A on input-envelope error — the orchestrator expects JSON and will fail the parse on Markdown, blocking the card silently.
136
+
137
+ ## Notes
19
138
 
20
- Document any blocking issues, regression risks, or accessibility gaps in the final response.
139
+ - Document any blocking issues, regression risks, or accessibility gaps in the final response (Mode A) or `findings[]` array (Mode B).
140
+ - Mode B is consumed by `/e2e-review` Phase 4b (when implemented in a future release) as the "design judgment pass" alongside the `visual-fidelity-verifier` agent's pixel-fidelity pass. The two are complementary: the verifier sees only the screenshot vs mockup; this command additionally reasons over the registry + Authority Matrix + brand voice.
141
+ - The output schema is kept aligned with `framework/.claude/agents/visual-fidelity-verifier.md` § "Output Schema" so the orchestrator can use a single parser for both sources. When updating the taxonomy here, update the verifier's taxonomy in lockstep.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "baldart",
3
- "version": "3.18.0",
3
+ "version": "3.18.1",
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"