Files
Arah2/.planning/phases/01-design-tokens-rams-foundation/01-04-SUMMARY.md
T
araharah-executor c3d802a646 docs(01-04): audit + capture + gallery plan summary — DSGN-02 checkpoint pending
- 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
2026-10-22 08:33:26 +08:00

172 lines
18 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
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)*