- 16/16 audit TDD green, real build AUDIT CLEAN (354 declarations, 0 off-token) - 6/6 non-blank Playwright captures; gallery mechanism (D-12) committed - tasks 1-2 complete; task 3 (blocking DSGN-02 approval) awaiting user verdict
172 lines
18 KiB
Markdown
172 lines
18 KiB
Markdown
---
|
||
phase: 01-design-tokens-rams-foundation
|
||
plan: 04
|
||
subsystem: ui
|
||
tags: [rams, design-tokens, audit, playwright, gallery, dsgn-02, d-12, d-13, d-14]
|
||
|
||
# Dependency graph
|
||
requires:
|
||
- phase: 01-design-tokens-rams-foundation plan 01 (wave 1)
|
||
provides: "theme/src/tokens.css (55 colors / 10 spacing / 4 fonts / 9 zero-radius tokens + 13 --type-* compound vars), theme/dist/rams.css build (npm run build --workspace theme), root audit/capture script delegates"
|
||
- phase: 01-design-tokens-rams-foundation plan 02 (wave 2)
|
||
provides: "theme/src/sheet.html + components.css (all-13 text-* helpers, pure var() component layer) — the audit's real-build integration target + the gallery's right-column capture; Playwright chromium-1248 installed"
|
||
- phase: 01-design-tokens-rams-foundation plan 03 (wave 3)
|
||
provides: "theme/basemap/index.html proof page (RAMS-BASEMAP-READY console signal) + committed screen.png fallback inputs per mockup screen"
|
||
provides:
|
||
- "Automated off-token audit (D-13): theme/scripts/audit.mjs — rendered-CSS scanner over dist + implementation pages (incl. <style> blocks, inline style attributes, used @layer utilities), hex/rgb()/hsl() literal token checks, font-family allowlist, zero-radius + circle-primitive adjudication, shadow/blur/glass ban, drift guards (exit 2: <40 color tokens, non-zero --radius-* token, missing token sheet/page/input); violations as file:line: declaration (exit 1); wired as `npm run audit`"
|
||
- "Audit TDD harness: theme/scripts/audit.test.mjs (16 checks / 8 groups, incl. real-build integration) — `npm run test --workspace theme`"
|
||
- "Playwright capture toolchain (D-14): theme/scripts/screenshot.mjs — real-browser captures of the sheet (390 fullPage), the 4 mockups via file:// (CDN network renders, committed screen.png fallback — mockups never edited, D-06), the basemap (READY-signal-gated); ≥10KB blank gate; wired as `npm run capture`"
|
||
- "DSGN-02 approval gallery (D-12): theme/gallery.html — the mechanism template every later UI phase extends (4 mockup-vs-sheet comparison rows + basemap direction row + token ledger of 13 typography specimens + 6 hero color swatches, names only per D-07 + approval scope strip); CDN-free, tokens-only"
|
||
- "6 regenerated captures under theme/screenshots/ (gitignored by policy): sheet-full.png, mockup-<screen>.png ×4, basemap-kl.png — all network renders, zero fallbacks needed"
|
||
affects: [every later UI phase (DSGN-02 gallery extension + `npm run audit`/`npm run capture` standing gates), 02-telegram-bot-worker (fidelity bar applies to bot-adjacent UI), 03-mini-app-shell, 05-guidance]
|
||
|
||
# Tech tracking
|
||
tech-stack:
|
||
added: [] (playwright@1.64.1 + chromium-1248 already installed by waves 1–2; screenshot.mjs/audit.mjs are node-builtins-only ESM)
|
||
patterns:
|
||
- "Rendered-vs-vocabulary scope adjudication: framework layers (@layer properties/theme/base, @property --tw-*) skipped; @layer utilities audited ONLY for classes used by implementation pages (mockup-compiled vocabulary is reference material per D-06) — later phases' off-token utility usage gets caught the moment their pages wear it"
|
||
- "Drift guards fail loud (exit 2) — no silent passes (T-1-07): token floor, radius-token invariant, missing registered page/token sheet/CSS input"
|
||
- "Evasion-proof evidence surface: <style> blocks + inline style=\"…\" attributes + rgb()/hsl() literals all checked, not just hex"
|
||
- "Capture fallback contract: failed/blank mockup capture → committed screen.png copied in (gallery refs stay stable; D-06 read-only mockups)"
|
||
- "Gallery-as-mechanism: one static page, extended per phase; token ledger + approval strip unchanged; `npm run audit` stays the automated evidence"
|
||
|
||
key-files:
|
||
created:
|
||
- theme/scripts/audit.mjs
|
||
- theme/scripts/audit.test.mjs
|
||
- theme/scripts/screenshot.mjs
|
||
- theme/gallery.html
|
||
modified:
|
||
- theme/package.json (audit + capture + test scripts)
|
||
|
||
key-decisions:
|
||
- "Rendered-CSS audit scope (D-13's own words: 'scans rendered CSS/classes'): dist compiles the mockup vocabulary 1:1 per wave-1's @source requirement — including utilities the design doc REJECTS (shadow-*, blur, backdrop-blur, bg-[#…]). Auditing raw dist would flag reference vocabulary no implementation page wears; the audit therefore filters @layer utilities to classes harvested from implementation pages (registry: IMPLEMENTATION_PAGES in audit.mjs — later phases append) and audits everything else implementation-owned fully. A used off-token utility (T7) or shadow utility still flags — proven by tests"
|
||
- "rounded-full adjudicated as circle primitive (the wave-1-anticipated call): design doc Shapes enumerates rect families (cards/buttons/banners/badges/containers) at absolute zero — mockups' circular signets (position puck, speed medallion, status dots, 11 uses) are drawn circles = spec geometry like the 18×18 checkbox. Audit sanctions exactly calc(infinity*1px) + its ≥1e30px minified form; 50% and every other non-zero radius stay flagged"
|
||
- "Token-hue + alpha sanctioned (8-digit hex whose 6-digit prefix is a token value — mockups' text-matte-black/60 family); Tailwind's own black (#000000xx) is NOT a token and stays flagged"
|
||
- "rgb()/rgba()/hsl()/hsl() literals audited too — hex is not the only literal form; var() references pass by construction"
|
||
- "how-to-verify's npx http-server replaced by the workspace's existing npm run basemap:preview (serves theme/ identically; no ad-hoc npx dependency — D-17 minimal tooling)"
|
||
- "Gallery rows use the full sheet capture per row (plan-allowed) + per-row compare notes naming the corresponding sheet sections — honest, complete, no opinionated crop mapping"
|
||
|
||
patterns-established:
|
||
- "DSGN-02 mechanism: extend theme/gallery.html with one comparison row per product screen; token ledger + approval strip unchanged; approval recorded in the phase SUMMARY"
|
||
- "Evidence gates as npm scripts: `npm run audit` (exit-code truth) + `npm run capture` (≥10KB blank gate) — CI-able in Phase 2's deploy pipeline (D-17)"
|
||
- "Implementation pages registry (audit.mjs IMPLEMENTATION_PAGES) is the rendered-surface contract — every page that renders Rams components must be registered there"
|
||
|
||
requirements-completed: [] # DSGN-02 pending — awaiting the blocking user-approval checkpoint (task 3); continuation records it on approval
|
||
|
||
# Metrics
|
||
duration: 12min (pre-checkpoint; started 2026-10-22T00:20:01Z, artifacts done 00:32:00Z)
|
||
completed: 2026-10-22
|
||
---
|
||
|
||
# Phase 01 Plan 04: Audit + Gallery + DSGN-02 Checkpoint Summary
|
||
|
||
**Automated off-token audit as a rendered-CSS scanner with drift guards and evasion-proof checks (16/16 TDD green, real build `AUDIT CLEAN — 354 declarations, 0 off-token values`), a committed Playwright capture toolchain producing 6/6 non-blank real-browser captures, and the DSGN-02 side-by-side approval gallery (mockup-vs-sheet rows + basemap direction + names-only token ledger) — the fidelity gate now awaiting the user's approval verdict**
|
||
|
||
> **STATUS: tasks 1–2 complete and committed; task 3 (DSGN-02 approval checkpoint, blocking) PENDING the user's verdict — resume signal: "approved" or a fix list. No later-phase work may rely on DSGN-02 until then.**
|
||
|
||
## Performance
|
||
|
||
- **Duration:** ~12 min pre-checkpoint (2026-10-22T00:20:01Z → 00:32:00Z)
|
||
- **Tasks:** 2/3 complete (task 3 = blocking checkpoint, pending user)
|
||
- **Files:** 4 created, 1 modified (+ this SUMMARY)
|
||
|
||
## Accomplishments
|
||
|
||
- **D-13 evidence, not assertion:** `npm run audit` exits 0 on the real build — 354 declarations checked across 4 inputs (97 rules audited, 298 compiled-vocabulary utility rules out of scope, 49 classes harvested from 3 implementation pages), zero off-token values; violations (when present) print as `file:line: declaration — reason`; drift conditions exit 2 loud (color-token floor 40, non-zero `--radius-*` token, missing token sheet / registered page / CSS input)
|
||
- **D-14 toolchain committed:** `npm run capture` → 6/6 non-blank captures — sheet-full.png (116KB, 390px fullPage), 4 mockup network renders via file:// (45–64KB, CDN Tailwind + fonts), basemap-kl.png (1.2MB, gated on the proof page's RAMS-BASEMAP-READY signal + 2s settle); fallback contract (committed screen.png) wired but not needed
|
||
- **D-12 gallery as durable mechanism:** theme/gallery.html (290 lines) — leading comment documents the per-phase extension pattern; 4 mockup-vs-sheet comparison rows with per-row family notes; basemap direction row; token ledger (13 typography specimens rendered in their own tokens + 6 hero color swatches — names only, zero numeric restatement per D-07); approval scope strip (fidelity bar + basemap direction in scope; interactive flows out of scope); CDN-free, built only from `dist/rams.css` + var()-only page shell
|
||
- **Audit covers the gallery itself:** gallery.html registered as an implementation page — its `<style>` block, inline style attributes, and class harvest are inside the evidence surface (that registration is what motivated closing the style-attribute evasion path)
|
||
|
||
## task Commits
|
||
|
||
Each task was committed atomically (TDD tasks have RED/GREEN pairs):
|
||
|
||
1. **task 1: Off-token audit script (D-13)** — `6a7c256` (test: RED, 13 failing checks) → `b39317d` (feat: GREEN, 13/13)
|
||
2. **task 2: Playwright capture script + gallery page (D-14, D-12)** — `9ba73f2` (test: RED for the style-attr evasion hole found while building the gallery) → `0b3eebf` (feat: GREEN, audit surface extension) → `b462936` (feat: capture toolchain + gallery + audit registry)
|
||
3. **task 3: DSGN-02 approval checkpoint** — blocking, PENDING user verdict (this report is the checkpoint delivery)
|
||
|
||
**Plan metadata:** (see final commit below — docs: SUMMARY)
|
||
|
||
## Files Created/Modified
|
||
|
||
- `theme/scripts/audit.mjs` (583 lines) — the D-13 audit: token-sheet parser (allowlist + drift guards), CSS block parser (layers/media/nesting, comment-stripping with line-preserving offsets), rendered-scope filter, declaration checks (hex/rgb/hsl literals, font families, radius incl. circle-primitive adjudication, box-shadow/backdrop-filter/blur ban, `--tw-*` plumbing skip), implementation-pages registry (class harvest + `<style>` + style-attribute audit)
|
||
- `theme/scripts/audit.test.mjs` (233 lines) — TDD harness: 16 checks / 8 groups (clean/dirty/drift-colors/drift-radius/real-build/components-layer/used-utilities/style-attributes), fixtures under /tmp/opencode
|
||
- `theme/scripts/screenshot.mjs` (191 lines) — D-14 capture tool: loopback static server (theme/ docroot, traversal-guarded), sheet/mockup/basemap captures, blank gate, screen.png fallback, per-capture log
|
||
- `theme/gallery.html` (290 lines) — the DSGN-02 mechanism page (see Accomplishments)
|
||
- `theme/package.json` — `"audit": "node ./scripts/audit.mjs ./dist/rams.css"`, `"capture": "node ./scripts/screenshot.mjs"`, `"test": "node ./scripts/audit.test.mjs"` (root delegates `audit`/`capture` verified resolving)
|
||
- `theme/screenshots/*` — 6 regenerated captures, gitignored by policy (re-run `npm run capture` after fresh checkout)
|
||
|
||
## Decisions Made
|
||
|
||
(See key-decisions in frontmatter for the full set — all within D-12/D-13/D-14 latitude.) The consequential ones:
|
||
|
||
- **Rendered-vs-vocabulary scope** — the plan's required behavior ("audit of theme/dist/rams.css (real build) → exit 0") collides with wave-1's own requirement that dist compile the mockup utility vocabulary 1:1 — which includes shadow/blur/glass/`bg-[#222222]` utilities the design doc rejects and the implementation never wears. D-13's own wording ("scans rendered CSS/classes") resolves it: the audit's unit of truth is what implementation pages render. Utilities-layer rules are audited exactly for harvested used classes; framework layers and `@property --tw-*` plumbing are skipped; everything implementation-owned is fully audited. Tests T5/T6/T7 lock all three behaviors.
|
||
- **Circle primitive adjudication** (wave-1's deferred call) — `rounded-full` sanctioned only as the full-circle primitive for signets; the audit quotes the design doc's Shapes enumeration (rect families at absolute zero) in its header; 50%/9999px/any other non-zero radius stays a violation.
|
||
- **Gallery serving** — the checkpoint how-to uses the workspace's existing preview server rather than `npx http-server` (equivalent docroot, one less ad-hoc package, D-17).
|
||
|
||
## Deviations from Plan
|
||
|
||
### Auto-fixed Issues
|
||
|
||
**1. [Rule 1 - Bug] Plan's task-2 verify command always exits 1 when the size checks pass**
|
||
- **Found during:** task 2 verification
|
||
- **Issue:** `for f in …; do [ "$(stat -c%s "$f")" -lt 10240 ] && exit 1; done && …` — when the test is false the compound `[ … ] && exit 1` leaves status 1; the for statement's last status propagates, breaking the `&&` chain on every passing run
|
||
- **Fix:** intent-correct loop (`if [ … ]; then exit 1; fi`); the substantive checks themselves were re-run and pass
|
||
- **Files modified:** none (verification command only)
|
||
- **Verification:** all 6 captures ≥ 10240B (45KB–1.2MB), gallery refs + audit verified → `GALLERY-TOOLS-OK`
|
||
- **Committed in:** n/a (verify-command fix, documented here)
|
||
|
||
**2. [Rule 2 - Missing critical] Inline `style="…"` attributes were an unaudited evasion path**
|
||
- **Found during:** task 2 (designing the gallery's swatches)
|
||
- **Issue:** the audit scanned `<style>` blocks but not style attributes — any page could pass `style="color: #00ff00"` with a CLEAN verdict, undermining the D-13 evidence (the gallery itself uses style-attribute values)
|
||
- **Fix:** TDD — RED `9ba73f2` (T8 proves the hole), GREEN `0b3eebf` (style attributes audited as rendered CSS, violations reported as `file:line: style attribute { prop: value }`)
|
||
- **Files modified:** theme/scripts/audit.mjs, theme/scripts/audit.test.mjs
|
||
- **Verification:** 16/16 tests green; real build still AUDIT CLEAN
|
||
- **Committed in:** `9ba73f2` + `0b3eebf`
|
||
|
||
**3. [Rule 3 - Tooling] Plan's how-to-verify server command replaced with the existing workspace server**
|
||
- **Found during:** task 3 checkpoint preparation
|
||
- **Issue:** `npx http-server theme -p 4444` pulls an ad-hoc npx package for a docroot the workspace already serves (`npm run basemap:preview --workspace theme` → theme/ on :8123) — against D-17's minimal-tooling spirit
|
||
- **Fix:** checkpoint instructions use the existing preview script; gallery + screenshots + basemap + dist CSS all verified 200 over it
|
||
- **Files modified:** none
|
||
- **Committed in:** n/a (checkpoint instructions)
|
||
|
||
---
|
||
|
||
**Total deviations:** 3 auto-fixed (1 bug, 1 missing critical, 1 tooling)
|
||
**Impact on plan:** All fix-level; no scope changes. The style-attribute extension made the D-13 evidence strictly stronger than the plan's letter.
|
||
|
||
## Issues Encountered
|
||
|
||
- **GREEN debug iterations (normal TDD, in-task):** (a) RADIUS_PROPS regex initially matched the `border:` shorthand (both optional groups skipped → bare `border` matched) — fixed to require the `-radius` suffix; (b) Tailwind v4.3.3 emits real `@property --tw-*` registration at-rules (unlayered, carrying the `#0000` default values) — added the rule-level plumbing skip alongside the declaration-level one. Both caught by the TDD harness before commit.
|
||
- **Mockup vocabulary provenance (investigated, not a bug):** dist's off-token literals (`#222222` from `bg-[#222222]`, `#000000xx` inside `.shadow-*` internals, `#1a1a1a99`-family token-hue+alpha from mockup `/60`-style utilities) all traced to mockup-derived compiled vocabulary or framework plumbing — none worn by implementation pages; the audit's scope adjudication handles them by design, with T7 proving a used off-token utility still flags.
|
||
- `.gitignore` already excluded `theme/screenshots/` (wave-1 entry) — verified, no change needed (plan asked to "ensure").
|
||
|
||
## Known Stubs
|
||
|
||
None in this plan's artifacts — the audit, capture script, and gallery are complete implementations. (The basemap's route vector remains wave-3's documented intentional placeholder for Phase 5; the gallery references it as such.)
|
||
|
||
## Threat Flags
|
||
|
||
None — no new trust surface beyond the plan's register: audit.mjs reads local files only (plan's boundary "audit.mjs → local files"); screenshot.mjs's static server is loopback-bound + traversal-guarded, and its CDN fetches are exactly the plan's boundary row "workstation browser → CDN Tailwind (mockup pages only)" (T-1-05 accept — only the captured mockup pages use CDN; the gallery itself is CDN-free per D-16). T-1-06 (gallery as durable committed mechanism) and T-1-07 (fail-loud drift guards, no silent passes) mitigations implemented and tested.
|
||
|
||
## User Setup Required
|
||
|
||
None — no external service configuration. For the checkpoint the user only serves the workspace and opens two URLs (see checkpoint instructions): `npm run capture` (only needed after a fresh checkout — captures are gitignored regenerated artifacts) then `npm run basemap:preview --workspace theme` → http://localhost:8123/gallery.html and /basemap/.
|
||
|
||
## Next Phase Readiness
|
||
|
||
- **Task 3 (this plan):** the continuation agent records the user's DSGN-02 verdict (resume signal "approved" or fix list) in this SUMMARY + REQUIREMENTS; on fix-list, iterate sheet/gallery/basemap per the listed aspects and re-present
|
||
- **Every later UI phase:** extend theme/gallery.html (one comparison row per new product screen), append pages to audit.mjs IMPLEMENTATION_PAGES, run `npm run capture` + `npm run audit` as the standing DSGN-02/DSGN-01 gates; CI wiring lands with Phase 2's deploy pipeline (D-17)
|
||
- **Fresh checkouts:** `npm run capture` regenerates theme/screenshots/ (gitignored); `npm run build --workspace theme` before audit
|
||
- STATE.md/ROADMAP.md updates deferred to the orchestrator (wave-parallel execution)
|
||
|
||
## Self-Check: PASSED
|
||
|
||
All 4 created + 1 modified files exist; all 5 task commit hashes verified in git log (6a7c256, b39317d, 9ba73f2, 0b3eebf, b462936); must-have markers verified (gallery.html 290 lines ≥ 80 + `screenshots/` ×10; package.json `audit` wired; audit.mjs → `tokens.css` ×5 + `rams.css` ×3; screenshot.mjs → `screenshots` ×4); no stub markers in the new artifacts.
|
||
|
||
---
|
||
*Phase: 01-design-tokens-rams-foundation*
|
||
*Completed: 2026-10-22 (tasks 1–2; DSGN-02 checkpoint pending)*
|