@tekyzinc/gsd-t 2.67.10 → 2.68.11
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 +24 -0
- package/commands/gsd-t-design-decompose.md +126 -22
- package/package.json +1 -1
- package/templates/stacks/design-to-code.md +36 -6
- package/templates/widget-contract.md +55 -21
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,30 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to GSD-T are documented here. Updated with each release.
|
|
4
4
|
|
|
5
|
+
## [2.68.11] - 2026-04-05
|
|
6
|
+
|
|
7
|
+
### Changed (widget-contract template)
|
|
8
|
+
- **Alignment column in Card Chrome Slots** — every slot now requires explicit alignment (left/center/right) extracted from Figma. Incorrect legend alignment was the #2 cause of "looks off" results.
|
|
9
|
+
- **Internal Element Layout section (MANDATORY)** — new section replacing the flat layout table. Documents: body_layout (flex-row/column/grid), body_justify, body_align, body_gap, chart_width/height, legend_width, footer_legend_justify, header_to_body_gap, body_to_footer_gap. These are the exact values that control spacing and sizing of elements within a widget card.
|
|
10
|
+
- **Verification checklist expanded** — now checks: chrome alignment, internal layout, inter-element spacing, element sizing, legend alignment, card container values (6 new items).
|
|
11
|
+
|
|
12
|
+
### Why
|
|
13
|
+
BDS Analytics comparison revealed consistent intra-widget layout errors: legends left-aligned instead of centered, inconsistent spacing between chart and legend, wrong element sizing within cards. The widget contract template had a Layout section but it specified only container-level properties (padding, border, gap) — not how elements were sized, spaced, and aligned WITHIN the card body. These new fields close that gap.
|
|
14
|
+
|
|
15
|
+
## [2.68.10] - 2026-04-05
|
|
16
|
+
|
|
17
|
+
### Changed (gsd-t-design-decompose)
|
|
18
|
+
- **Node-level Figma decomposition (MANDATORY)** — Step 1 now requires `get_metadata` to map page tree, then `get_design_context` on EACH widget node individually. No more classifying from page screenshots alone. Extracted text content (titles, subtitles, column headers, legend items) becomes mandatory data inventory column.
|
|
19
|
+
- **Classification reasoning (MANDATORY)** — Step 2 now requires written decision-tree walkthrough for every chart element: "I see [description]. Decision tree: [walkthrough]. Classification: [entry]. Confidence: [HIGH/MEDIUM/LOW]". Low/medium confidence entries flagged for human review.
|
|
20
|
+
- **Human contract review checkpoint** — Step 5 now presents classification reasoning table + data inventory alongside decomposition summary. User reviews chart type assignments and text content before contracts are written. 5-minute gate that catches misclassification before it propagates.
|
|
21
|
+
- **Contract-vs-Figma verification gate (MANDATORY)** — New Step 6.5 re-reads each Figma node after contracts are written and produces a mismatch report. Catches: wrong chart types, hallucinated column headers, missing elements, invented data models. Mismatches must be fixed before proceeding to build.
|
|
22
|
+
|
|
23
|
+
### Changed (design-to-code stack rule)
|
|
24
|
+
- **Visual verification against FIGMA, not just contracts** — Section 15 now requires the Design Verification Agent to compare the built screen against the original Figma screenshot (Target 2), not just against design contracts (Target 1). This closes the gap where wrong contracts produce wrong code that still scores 50/50 against itself.
|
|
25
|
+
|
|
26
|
+
### Why
|
|
27
|
+
Post-validation comparison of the built BDS Analytics screen against the original Figma design revealed: wrong chart types (donuts instead of stacked bars in Member Segmentation), hallucinated column headers (Video Playlist), invented data models (Tool Engagement). All scored 50/50 against their contracts — because the contracts were wrong. The contracts→code pipeline is airtight; the Figma→contracts pipeline was unverified. These changes close that gap at four layers: node-level extraction, classification reasoning, human review, and contract-vs-Figma gate.
|
|
28
|
+
|
|
5
29
|
## [2.67.10] - 2026-04-05
|
|
6
30
|
|
|
7
31
|
### Added (design-chart-taxonomy)
|
|
@@ -38,33 +38,84 @@ Run these checks, log results to user inline:
|
|
|
38
38
|
- Keep the taxonomy in working memory while classifying — every element you identify MUST be matched against it
|
|
39
39
|
- **Filename rule**: the element contract filename MUST match the taxonomy name exactly (`chart-bar-vertical-single.contract.md`, not `bar-vertical-single.contract.md`). Shortened aliases are FORBIDDEN — they create taxonomy drift and make link-integrity checks fail. If an existing legacy contract uses a shortened name, prefer renaming it to the taxonomy name over creating a parallel file.
|
|
40
40
|
|
|
41
|
-
## Step 1: Survey the Design
|
|
41
|
+
## Step 1: Survey the Design — Node-Level Figma Decomposition (MANDATORY)
|
|
42
42
|
|
|
43
|
-
|
|
43
|
+
> **⚠ This is the highest-leverage step in the entire workflow.** Most design-to-code errors originate here — the agent glances at a page screenshot, guesses chart types, and writes contracts from wrong assumptions. The fix is STRUCTURED NODE-LEVEL EXTRACTION, not "look harder."
|
|
44
44
|
|
|
45
|
-
|
|
45
|
+
### 1a. Map the page tree
|
|
46
46
|
|
|
47
|
-
|
|
47
|
+
Call `get_metadata` on the page/frame to get the full node tree. This returns the Figma component hierarchy — every group, frame, and component instance as named nodes with IDs.
|
|
48
48
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
49
|
+
### 1b. Identify widget-level nodes
|
|
50
|
+
|
|
51
|
+
From the metadata tree, identify every distinct visual group (card, widget, section). These are typically direct children of a page frame or section frame. List them:
|
|
52
|
+
|
|
53
|
+
```
|
|
54
|
+
Node tree for page "Analytics":
|
|
55
|
+
├── stat-card-campaign (id: 123:456)
|
|
56
|
+
├── stat-card-visitors (id: 123:457)
|
|
57
|
+
├── most-popular-tools-card (id: 123:458)
|
|
58
|
+
├── number-of-tools-card (id: 123:459)
|
|
59
|
+
├── ...
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### 1c. Call `get_design_context` on EACH widget node individually (MANDATORY)
|
|
63
|
+
|
|
64
|
+
**Do NOT skip this.** Do NOT classify from the page screenshot alone. For each widget node identified in 1b:
|
|
65
|
+
|
|
66
|
+
1. Call `get_design_context` with the specific node ID
|
|
67
|
+
2. Record the returned: component type, code hints, text content, layout properties
|
|
68
|
+
3. Extract EVERY text string visible in the node (titles, subtitles, labels, column headers, legend items, axis labels, KPI values)
|
|
69
|
+
|
|
70
|
+
> **⚠ Figma MCP size guard**: `get_design_context` on a full-page frame (e.g., a 390×3372px mobile screen) can return 250KB+ and be auto-saved to a tool-results file. **Never call it on the full page.** Call it on each leaf card/component node individually (typically < 100KB each). If you must inspect a large frame, use `excludeScreenshot: true` to halve the payload.
|
|
71
|
+
|
|
72
|
+
**Anti-pattern**: Looking at a page screenshot and writing "I see a donut chart" without calling `get_design_context` on that specific node. The MCP returns structured data about the component — use it.
|
|
56
73
|
|
|
57
|
-
|
|
74
|
+
### 1d. Produce the flat inventory table WITH data inventory
|
|
58
75
|
|
|
59
|
-
|
|
76
|
+
| # | Element on Design | Figma Node ID | Appears On Pages | Text Content Extracted | Visual Variant |
|
|
77
|
+
|---|-------------------|---------------|------------------|----------------------|----------------|
|
|
78
|
+
| 1 | Donut chart with center label | 123:458 | Overview, Analytics | Title: "Most Popular Tools", Subtitle: "Which tools members interact with most", Center: "485", Center sub: "Total Interactions", Legend: ["Steps to Stay Covered 30%", "Broker Contact 21%", ...] | chart-donut |
|
|
79
|
+
| 2 | Stacked bar with KPI header | 123:459 | Analytics | Title: "Number of Tools", Subtitle: "How many tools members interact with", KPI: "2.4", KPI sub: "Avg tools per member", Legend: ["1 Tool", "2 Tools", "3 Tools", "4+ Tools"], Labels: ["{num}%", ...] | chart-bar-stacked-horizontal-percentage |
|
|
80
|
+
| ... | | | | | |
|
|
81
|
+
|
|
82
|
+
**Rules**:
|
|
83
|
+
- Distinct visual variants = distinct rows. A horizontal stacked bar and a vertical stacked bar are TWO rows.
|
|
84
|
+
- The "Text Content Extracted" column is MANDATORY. Every text string visible in the Figma node MUST be listed. This kills hallucinated column headers and invented data models.
|
|
85
|
+
- If `get_design_context` is unavailable (no Figma MCP), extract text from the screenshot with maximum care and flag "⚠ extracted from screenshot, not MCP — verify manually".
|
|
86
|
+
|
|
87
|
+
## Step 2: Classify Each Element — Show Your Reasoning (MANDATORY)
|
|
60
88
|
|
|
61
89
|
For each row in the inventory, assign:
|
|
62
90
|
|
|
63
|
-
- **Category** — chart / legend / axis / card / table / control / atom / typography / layout
|
|
91
|
+
- **Category** — chart / legend / axis / card / table / list / control / atom / typography / layout
|
|
64
92
|
- **Element name** — **MUST come from `templates/design-chart-taxonomy.md`** (closed set). If no match found, STOP and ask user to extend the taxonomy with rationale.
|
|
65
93
|
- **Reuse count** — how many times does it appear across the entire design?
|
|
66
94
|
- **Owner layer** — element / widget-internal / page-internal
|
|
67
95
|
|
|
96
|
+
### Classification reasoning (MANDATORY — show your work)
|
|
97
|
+
|
|
98
|
+
For EACH chart/visualization element, you MUST walk the taxonomy decision tree and document your reasoning. This is not optional — skipping this step is how donut charts get classified as stacked bars and vice versa.
|
|
99
|
+
|
|
100
|
+
**Required format for each element:**
|
|
101
|
+
|
|
102
|
+
```
|
|
103
|
+
Element #2: node 123:459 "Number of Tools"
|
|
104
|
+
I SEE: A horizontal bar that fills full width, divided into 4 colored segments
|
|
105
|
+
with percentage labels above each segment. Legend below: "1 Tool", "2 Tools",
|
|
106
|
+
"3 Tools", "4+ Tools". Single bar, not multiple bars per category.
|
|
107
|
+
DECISION TREE:
|
|
108
|
+
- Is it a bar chart? YES — has rectangular segments
|
|
109
|
+
- Stacked or grouped? STACKED — segments touch, share one bar
|
|
110
|
+
- Horizontal or vertical? HORIZONTAL — bar extends left to right
|
|
111
|
+
- Percentage or absolute? PERCENTAGE — single bar, segments sum to 100%,
|
|
112
|
+
labels show {num}%
|
|
113
|
+
CLASSIFICATION: chart-bar-stacked-horizontal-percentage
|
|
114
|
+
CONFIDENCE: HIGH — matches taxonomy distinguisher exactly
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
**If confidence is LOW or MEDIUM**, flag it for human review in Step 5.
|
|
118
|
+
|
|
68
119
|
### Visual distinguisher decision rules (consult taxonomy)
|
|
69
120
|
|
|
70
121
|
Before naming an element, apply the visual distinguisher rules from the taxonomy:
|
|
@@ -72,9 +123,12 @@ Before naming an element, apply the visual distinguisher rules from the taxonomy
|
|
|
72
123
|
- **Bar chart?** → is it stacked/grouped, horizontal/vertical, percentage/absolute? These are ALL distinct element contracts.
|
|
73
124
|
- **Circular?** → pie vs donut (hole in center?) vs gauge (partial arc?)
|
|
74
125
|
- **Line?** → single vs multi, stepped vs smooth, with area or without
|
|
126
|
+
- **Table vs list?** → columns aligned across rows with header = table; self-contained rows = list
|
|
75
127
|
|
|
76
128
|
**Anti-pattern to avoid**: "it has bars so it's a bar chart" → WRONG. The failure mode is picking `chart-bar-grouped-vertical` when the design is `chart-bar-stacked-horizontal-percentage`. These render completely differently with completely different data bindings.
|
|
77
129
|
|
|
130
|
+
**Anti-pattern to avoid**: "it has circles so it's a donut" → WRONG. A pair of stacked vertical bar charts side-by-side is NOT two donut charts, even if the bars have rounded segments. LOOK AT THE ACTUAL SHAPE.
|
|
131
|
+
|
|
78
132
|
**Promotion rule**: an item becomes an **element contract** if:
|
|
79
133
|
- It appears ≥2 times across the design, OR
|
|
80
134
|
- It has non-trivial visual spec (≥5 distinct spec properties), OR
|
|
@@ -110,15 +164,15 @@ Each page/screen in the design becomes a page contract. Document:
|
|
|
110
164
|
- Global layout (header, sidebar, main)
|
|
111
165
|
- Route + auth guards
|
|
112
166
|
|
|
113
|
-
## Step 5: Confirm Decomposition With User
|
|
167
|
+
## Step 5: Confirm Decomposition With User — Contract Review Checkpoint
|
|
114
168
|
|
|
115
|
-
Present the full hierarchy summary:
|
|
169
|
+
Present the full hierarchy summary WITH classification reasoning:
|
|
116
170
|
|
|
117
171
|
```
|
|
118
172
|
DECOMPOSITION SUMMARY
|
|
119
173
|
─────────────────────
|
|
120
174
|
Elements: 14 contracts
|
|
121
|
-
Charts: 4 (chart-donut, chart-bar-stacked-horizontal, chart-line, chart-sparkline)
|
|
175
|
+
Charts: 4 (chart-donut, chart-bar-stacked-horizontal-percentage, chart-line-single, chart-sparkline-line)
|
|
122
176
|
Legends: 2 (legend-vertical-right, legend-horizontal-bottom)
|
|
123
177
|
Cards: 2 (stat-card, stat-card-with-delta)
|
|
124
178
|
Tables: 1 (table-dense)
|
|
@@ -132,18 +186,33 @@ Pages: 3 contracts
|
|
|
132
186
|
dashboard-overview, analytics-detail, settings
|
|
133
187
|
|
|
134
188
|
Total: 23 contracts (vs. flat: ~57 elements in single file)
|
|
135
|
-
|
|
136
|
-
Cost estimate:
|
|
137
|
-
- Decomposition effort: ~{N} hours to write all contracts
|
|
138
|
-
- Verification: elements verified once, reused everywhere → no drift
|
|
139
|
-
- Implementation: widgets become assembly, not reinvention
|
|
140
189
|
```
|
|
141
190
|
|
|
191
|
+
**Then present the classification reasoning table** (from Step 2) as a condensed review:
|
|
192
|
+
|
|
193
|
+
| # | Widget/Element | Classified As | Key Reasoning | Confidence |
|
|
194
|
+
|---|----------------|---------------|---------------|------------|
|
|
195
|
+
| 1 | Most Popular Tools body | chart-donut | Circle with center hole + center label "485" + 5 colored segments | HIGH |
|
|
196
|
+
| 2 | Number of Tools body | chart-bar-stacked-horizontal-percentage | Single horizontal bar, 4 segments summing to 100%, {num}% labels | HIGH |
|
|
197
|
+
| 3 | Member State chart | chart-bar-stacked-vertical | Multiple stacked vertical bars, 2 groups side-by-side, percentage labels | MEDIUM — verify |
|
|
198
|
+
| ... | | | | |
|
|
199
|
+
|
|
200
|
+
**Highlight any MEDIUM/LOW confidence entries** — these are the misclassification risks.
|
|
201
|
+
|
|
202
|
+
**Present the data inventory** for each widget — the user can quickly spot if column headers or labels were hallucinated:
|
|
203
|
+
|
|
204
|
+
| Widget | Title | Subtitle | Data Labels |
|
|
205
|
+
|--------|-------|----------|-------------|
|
|
206
|
+
| Video Playlist | "Video Playlist" | (none) | Columns: Video, Viewed, Clicked Thumbnail, Clicked CTA, Avg. Seconds Watched |
|
|
207
|
+
| Tool Engagement | "Tool Engagement" | (none) | Tabs: [Your 2026 Plan Options, ...], Stats: "487 Total members who viewed", "300 Total members who clicked CTA" |
|
|
208
|
+
|
|
142
209
|
Ask user: "Proceed with this decomposition? [y/n/edit]"
|
|
143
210
|
- **y** → Step 6
|
|
144
211
|
- **n** → abort
|
|
145
212
|
- **edit** → accept user revisions to the hierarchy, re-present
|
|
146
213
|
|
|
214
|
+
> **Why this checkpoint matters**: The 13-task validation (v2.59–v2.67) proved contracts→code is airtight. But Figma→contracts was unverified — misclassifications at this step propagate through the entire build uncaught. This 5-minute review catches: wrong chart types, hallucinated data models, missing elements, wrong labels.
|
|
215
|
+
|
|
147
216
|
## Step 6: Write Contracts
|
|
148
217
|
|
|
149
218
|
Create the directory structure:
|
|
@@ -204,6 +273,41 @@ element contract > widget contract > page contract
|
|
|
204
273
|
Widgets and pages reference elements by name. They CANNOT override element visual spec. To customize, create a new element variant.
|
|
205
274
|
```
|
|
206
275
|
|
|
276
|
+
## Step 6.5: Contract-vs-Figma Verification Gate (MANDATORY)
|
|
277
|
+
|
|
278
|
+
After writing all contracts but BEFORE proceeding to partition or build, verify that each contract accurately represents the Figma design. This gate catches errors that would otherwise propagate through the entire build.
|
|
279
|
+
|
|
280
|
+
### For each widget contract:
|
|
281
|
+
|
|
282
|
+
1. **Re-read the Figma node** — call `get_design_context` (or re-examine the screenshot) for the specific widget node
|
|
283
|
+
2. **Compare the contract's claimed structure against the actual Figma node:**
|
|
284
|
+
|
|
285
|
+
| Check | What to verify | Failure mode it prevents |
|
|
286
|
+
|-------|---------------|------------------------|
|
|
287
|
+
| Chart type | Contract's element name matches the actual visual pattern | Donut classified as stacked bar (or vice versa) |
|
|
288
|
+
| Data labels | Contract's Test Fixture labels match the Figma text exactly | Hallucinated column headers, invented metrics |
|
|
289
|
+
| Element count | Number of sub-elements in contract matches Figma | Missing legends, extra charts, wrong layout |
|
|
290
|
+
| Text content | Every title, subtitle, label, legend item matches Figma verbatim | "Engagement per video" subtitle that doesn't exist in Figma |
|
|
291
|
+
| Layout structure | Widget's claimed layout matches Figma arrangement | Side-by-side classified as stacked, 2 charts classified as 1 |
|
|
292
|
+
|
|
293
|
+
3. **Produce a contract-vs-Figma mismatch report:**
|
|
294
|
+
|
|
295
|
+
```
|
|
296
|
+
CONTRACT-VS-FIGMA VERIFICATION
|
|
297
|
+
───────────────────────────────
|
|
298
|
+
✅ most-popular-tools-card: chart-donut — MATCHES Figma node 123:458
|
|
299
|
+
✅ number-of-tools-card: chart-bar-stacked-horizontal-percentage — MATCHES
|
|
300
|
+
❌ member-state-card: chart-donut — MISMATCH: Figma shows stacked vertical bars, not donuts
|
|
301
|
+
→ Fix: reclassify as chart-bar-stacked-vertical, rewrite element contract
|
|
302
|
+
❌ video-playlist-table: columns [Title, Duration, Views, Watch Time, Completion]
|
|
303
|
+
— MISMATCH: Figma shows [Video, Viewed, Clicked Thumbnail, Clicked CTA, Avg. Seconds Watched]
|
|
304
|
+
→ Fix: update Test Fixture column headers
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
4. **If ANY mismatches found**: fix the contracts BEFORE proceeding. Do not build from wrong contracts.
|
|
308
|
+
|
|
309
|
+
> **Why this gate exists**: The two-terminal validation (tasks 001-013) proved the system produces 50/50 scores when contracts are correct — but also revealed that scoring code-vs-contract doesn't catch contract-vs-Figma errors. This gate closes that gap.
|
|
310
|
+
|
|
207
311
|
## Step 7: Wire Into Partition
|
|
208
312
|
|
|
209
313
|
If `.gsd-t/domains/` exists (project is already partitioned), append to relevant domain's `scope.md`:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tekyzinc/gsd-t",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.68.11",
|
|
4
4
|
"description": "GSD-T: Contract-Driven Development for Claude Code — 51 slash commands with headless CI/CD mode, graph-powered code analysis, real-time agent dashboard, execution intelligence, task telemetry, doc-ripple enforcement, backlog management, impact analysis, test sync, milestone archival, and PRD generation",
|
|
5
5
|
"author": "Tekyz, Inc.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -462,11 +462,30 @@ MANDATORY:
|
|
|
462
462
|
|
|
463
463
|
---
|
|
464
464
|
|
|
465
|
-
## 15. Visual Verification
|
|
465
|
+
## 15. Visual Verification — Against FIGMA, Not Just Contracts
|
|
466
466
|
|
|
467
|
-
**Visual verification is handled by a dedicated Design Verification Agent**, spawned automatically by `gsd-t-execute` (Step 5.25) after all domain tasks complete.
|
|
467
|
+
**Visual verification is handled by a dedicated Design Verification Agent**, spawned automatically by `gsd-t-execute` (Step 5.25) after all domain tasks complete.
|
|
468
468
|
|
|
469
|
-
|
|
469
|
+
### Critical distinction: TWO verification targets
|
|
470
|
+
|
|
471
|
+
The verification agent compares the built frontend against **TWO sources** — not just one:
|
|
472
|
+
|
|
473
|
+
```
|
|
474
|
+
VERIFICATION TARGETS:
|
|
475
|
+
├── TARGET 1: Built screen vs DESIGN CONTRACTS
|
|
476
|
+
│ Does the code match the contract's claimed values?
|
|
477
|
+
│ (This is what the 13-task validation proved works — airtight.)
|
|
478
|
+
│
|
|
479
|
+
└── TARGET 2: Built screen vs FIGMA DESIGN (MANDATORY — this is new)
|
|
480
|
+
Does the BUILT SCREEN match the ORIGINAL FIGMA SCREENSHOT?
|
|
481
|
+
This catches: contracts that were wrong to begin with,
|
|
482
|
+
chart type misclassification, hallucinated data, missing elements.
|
|
483
|
+
(This is what was missing — and what caused the BDS failures.)
|
|
484
|
+
```
|
|
485
|
+
|
|
486
|
+
**Target 2 is the critical addition.** Verifying code-vs-contract is necessary but not sufficient. If the contract said "donut" when Figma showed a stacked bar, the code will faithfully build a donut, the contract verification will say MATCH, and the screen will be WRONG.
|
|
487
|
+
|
|
488
|
+
### Verification agent workflow
|
|
470
489
|
|
|
471
490
|
```
|
|
472
491
|
SEPARATION OF CONCERNS:
|
|
@@ -475,13 +494,24 @@ SEPARATION OF CONCERNS:
|
|
|
475
494
|
│ Do NOT open a browser or attempt visual comparison yourself
|
|
476
495
|
│
|
|
477
496
|
└── DESIGN VERIFICATION AGENT (Step 5.25 of gsd-t-execute):
|
|
478
|
-
Open browser → screenshot
|
|
479
|
-
|
|
480
|
-
|
|
497
|
+
1. Open browser → screenshot built page at each breakpoint
|
|
498
|
+
2. Get Figma screenshot (via MCP get_screenshot or saved reference image)
|
|
499
|
+
3. SIDE-BY-SIDE comparison: built screenshot vs Figma screenshot
|
|
500
|
+
4. For EACH widget/section on the page:
|
|
501
|
+
a. What chart type does the FIGMA show? (look at the Figma screenshot)
|
|
502
|
+
b. What chart type did the CODE build? (look at the built screenshot)
|
|
503
|
+
c. Do they match? Not "does code match contract" — does CODE match FIGMA?
|
|
504
|
+
5. Check every text label: does the built screen show the same titles,
|
|
505
|
+
subtitles, column headers, legend items, KPI values as the Figma?
|
|
506
|
+
6. Produce structured comparison table (30+ rows):
|
|
507
|
+
| Element | Figma Shows | Built Shows | MATCH/DEVIATION |
|
|
508
|
+
7. Fix deviations → re-verify → artifact gate enforces completion
|
|
481
509
|
```
|
|
482
510
|
|
|
483
511
|
The verification agent enforces the **FAIL-BY-DEFAULT** rule: every visual element starts as UNVERIFIED. The only valid verdicts are MATCH (with proof) or DEVIATION (with specifics). "Looks close" and "appears to match" are not verdicts. An artifact gate in the orchestrator blocks completion if the comparison table is missing or empty.
|
|
484
512
|
|
|
513
|
+
> **Why "vs Figma" matters**: The two-terminal validation (v2.59–v2.67, 13 tasks, all 50/50) proved contracts→code is reliable. But when the BUILT screen was compared to the ACTUAL Figma design, major deviations emerged: wrong chart types (donuts instead of stacked bars), hallucinated column headers, invented data models — all of which scored 50/50 against their (wrong) contracts. Verifying against Figma, not just contracts, is the fix.
|
|
514
|
+
|
|
485
515
|
---
|
|
486
516
|
|
|
487
517
|
## 16. Anti-Patterns
|
|
@@ -19,18 +19,20 @@ Composition of elements + data binding + layout. Widgets SELECT and POSITION ele
|
|
|
19
19
|
|
|
20
20
|
Every widget is a card with consistent chrome. Missing chrome is the #1 cause of "looks off" verification results. Document EVERY slot, even if empty.
|
|
21
21
|
|
|
22
|
-
| Slot | Element Contract (or N/A) | Content / Behavior |
|
|
23
|
-
|
|
24
|
-
| `title` | heading-h3 | {exact title text from design} |
|
|
25
|
-
| `subtitle` | text-caption or N/A | {exact subtitle text — "Which tools members interact with most."} |
|
|
26
|
-
| `header_right_control` | select-dropdown, button-ghost, or N/A | {e.g., "Members ▼" filter dropdown in card header} |
|
|
27
|
-
| `kpi_header` | stat-card-kpi-large or N/A | {e.g., "2.4" + "Avg tools per member" shown above chart} |
|
|
28
|
-
| `body` | {primary element, e.g., chart-donut} | {main visual} |
|
|
29
|
-
| `body_sidebar` | {e.g., legend-vertical-right or N/A} | {element positioned alongside body} |
|
|
30
|
-
| `footer` | {e.g., text-caption or N/A} | {e.g., "Last updated: ..."} |
|
|
31
|
-
| `footer_legend` | {e.g., legend-horizontal-bottom or N/A} | {legend below body} |
|
|
32
|
-
|
|
33
|
-
**
|
|
22
|
+
| Slot | Element Contract (or N/A) | Content / Behavior | Alignment |
|
|
23
|
+
|-------------------------|------------------------------------------|--------------------------------------------------|-----------------|
|
|
24
|
+
| `title` | heading-h3 | {exact title text from design} | {left / center} |
|
|
25
|
+
| `subtitle` | text-caption or N/A | {exact subtitle text — "Which tools members interact with most."} | {left / center} |
|
|
26
|
+
| `header_right_control` | select-dropdown, button-ghost, or N/A | {e.g., "Members ▼" filter dropdown in card header} | right |
|
|
27
|
+
| `kpi_header` | stat-card-kpi-large or N/A | {e.g., "2.4" + "Avg tools per member" shown above chart} | {left / center} |
|
|
28
|
+
| `body` | {primary element, e.g., chart-donut} | {main visual} | {center / left} |
|
|
29
|
+
| `body_sidebar` | {e.g., legend-vertical-right or N/A} | {element positioned alongside body} | {left / center} |
|
|
30
|
+
| `footer` | {e.g., text-caption or N/A} | {e.g., "Last updated: ..."} | {left / center} |
|
|
31
|
+
| `footer_legend` | {e.g., legend-horizontal-bottom or N/A} | {legend below body} | {center / left} |
|
|
32
|
+
|
|
33
|
+
**Rules**:
|
|
34
|
+
- If the design shows it, document it. If the design doesn't show it, write "N/A". Do NOT leave blank.
|
|
35
|
+
- The **Alignment** column is MANDATORY. Incorrect alignment (left vs center) is the #2 cause of "looks off" results after missing chrome. Extract alignment from the Figma node — do not default to left.
|
|
34
36
|
|
|
35
37
|
## Elements Used (body composition)
|
|
36
38
|
|
|
@@ -46,25 +48,52 @@ Every widget is a card with consistent chrome. Missing chrome is the #1 cause of
|
|
|
46
48
|
```
|
|
47
49
|
┌──────────────────────────────────────────────┐
|
|
48
50
|
│ {title} [{filter}] │
|
|
51
|
+
│ {subtitle} │
|
|
49
52
|
├──────────────────────────────────────────────┤
|
|
50
53
|
│ │ │
|
|
51
54
|
│ {chart} │ {legend} │
|
|
52
55
|
│ │ │
|
|
56
|
+
├──────────────────────────────────────────────┤
|
|
57
|
+
│ {footer_legend} │
|
|
53
58
|
└──────────────────────────────────────────────┘
|
|
54
59
|
```
|
|
55
60
|
|
|
61
|
+
### Card Container
|
|
62
|
+
|
|
56
63
|
| Property | Value |
|
|
57
64
|
|--------------------|-----------------------------------------------------|
|
|
58
65
|
| container_width | {100% of parent / fixed 480px} |
|
|
59
66
|
| container_height | {auto / fixed 320px} |
|
|
60
|
-
| padding | {
|
|
61
|
-
|
|
|
62
|
-
|
|
|
63
|
-
|
|
|
64
|
-
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
67
|
+
| padding | {16px — extract exact value from Figma} |
|
|
68
|
+
| background | {#ffffff} |
|
|
69
|
+
| border | {1px solid #e2e8f0} |
|
|
70
|
+
| border_radius | {8px} |
|
|
71
|
+
| shadow | {none / 0 2px 8px rgba(0,0,0,0.1)} |
|
|
72
|
+
|
|
73
|
+
### Internal Element Layout (MANDATORY — the "looks off" killer)
|
|
74
|
+
|
|
75
|
+
This section specifies how elements are sized, spaced, and aligned WITHIN the card body. Missing or wrong values here produce the "spacing inside widgets" and "legends incorrectly aligned" class of errors.
|
|
76
|
+
|
|
77
|
+
| Property | Value |
|
|
78
|
+
|-----------------------------|------------------------------------------------------------|
|
|
79
|
+
| header_to_body_gap | {16px — gap between title/subtitle row and body content} |
|
|
80
|
+
| body_layout | {flex-row / flex-column / grid} |
|
|
81
|
+
| body_justify | {center / flex-start / space-between} |
|
|
82
|
+
| body_align | {center / flex-start / stretch} |
|
|
83
|
+
| body_gap | {24px — gap between body element and sidebar element} |
|
|
84
|
+
| chart_width | {180px / 60% of body / auto} |
|
|
85
|
+
| chart_height | {180px / auto} |
|
|
86
|
+
| chart_align_self | {center / flex-start} |
|
|
87
|
+
| legend_width | {auto / 40% of body} |
|
|
88
|
+
| legend_align_self | {center / flex-start} |
|
|
89
|
+
| body_to_footer_gap | {16px — gap between body and footer/footer_legend} |
|
|
90
|
+
| footer_legend_justify | {center / flex-start — EXTRACT FROM FIGMA, do not default} |
|
|
91
|
+
|
|
92
|
+
**Rules**:
|
|
93
|
+
- Extract EVERY value from the Figma node — do not approximate.
|
|
94
|
+
- `footer_legend_justify` is critical: center-aligned legends look completely different from left-aligned. Check the Figma.
|
|
95
|
+
- `body_layout` + `body_justify` + `body_align` together define whether the chart is centered in its card, left-aligned, or stretched. Get this wrong and every widget "looks off."
|
|
96
|
+
- These values are WIDGET-OWNED — they describe how the widget positions its elements, not the elements' internal specs (which live in element contracts).
|
|
68
97
|
|
|
69
98
|
## Data Binding
|
|
70
99
|
|
|
@@ -154,7 +183,12 @@ The widget harness page (`/design-system/{widget-name}`) renders ONE widget inst
|
|
|
154
183
|
Widget-level verification runs AFTER all referenced elements pass their own verification. Widget verification only checks composition — element internals are out of scope.
|
|
155
184
|
|
|
156
185
|
- [ ] All referenced elements present and correctly slotted
|
|
157
|
-
- [ ]
|
|
186
|
+
- [ ] Card chrome alignment matches design (title left/center, legend center/left, etc.)
|
|
187
|
+
- [ ] Internal element layout matches design (body_layout, body_justify, body_align)
|
|
188
|
+
- [ ] Inter-element spacing matches design (header_to_body_gap, body_gap, body_to_footer_gap)
|
|
189
|
+
- [ ] Element sizing matches design (chart_width, chart_height, legend_width)
|
|
190
|
+
- [ ] Legend alignment matches design (footer_legend_justify: center vs left)
|
|
191
|
+
- [ ] Card container values match design (padding, border, radius, shadow)
|
|
158
192
|
- [ ] Responsive breakpoints adapt as specified
|
|
159
193
|
- [ ] Data binding produces correct element inputs (spot-check with sample data)
|
|
160
194
|
- [ ] Inter-element interactions fire (hover sync, click propagation)
|