From 3ae44b636f5f55e9fe50e15fdfe7fe6ddfb6d1a9 Mon Sep 17 00:00:00 2001 From: Craig Jennings Date: Sun, 12 Jul 2026 21:03:02 -0500 Subject: docs(spec): component-generation spec reviewed, folded, and decomposed spec-review passed with three findings, all pre-agreed and folded in the same pass: the option-1 approval superseded the demand-gated extraction order (extraction now covers the full catalogue ungated, phases 1-2 swapped, decisions 4 and 8 re-scoped), the card-record refactor is now named in phase 1, and stale counts were refreshed (109 cards, R56). Lifecycle DRAFT -> READY -> DOING; phase tasks live under the Retro widget catalogue parent with the spec UUID stamped as :SPEC_ID:. --- .../specs/2026-07-12-component-generation-spec.org | 68 ++++++++++++++-------- 1 file changed, 43 insertions(+), 25 deletions(-) (limited to 'docs') diff --git a/docs/specs/2026-07-12-component-generation-spec.org b/docs/specs/2026-07-12-component-generation-spec.org index 5ee30df..95c4712 100644 --- a/docs/specs/2026-07-12-component-generation-spec.org +++ b/docs/specs/2026-07-12-component-generation-spec.org @@ -4,34 +4,36 @@ #+TODO: TODO | DONE #+TODO: DRAFT READY DOING | IMPLEMENTED SUPERSEDED CANCELLED -* DRAFT Widget component generation +* DOING Widget component generation :PROPERTIES: :ID: 3ac0d42c-db1a-4d21-bce4-e63785fef0ba :END: +- 2026-07-12 Sun @ 20:57:50 -0500 — READY → DOING: phases decomposed into todo.org tasks under "Retro widget catalogue" (=:SPEC_ID:= stamped); Phase 1 extraction starts now per the option-1 approval. +- 2026-07-12 Sun @ 20:57:50 -0500 — DRAFT → READY: spec-review passed (Ready; 3 findings — the option-1 supersession, the card-record refactor, stale counts — all accepted and folded same pass). - 2026-07-12 Sun @ 10:12:06 -0500 — drafted. ** Prototype iterations Per =claude-rules/ui-prototyping.md=, a non-trivial-UI spec carries its prototype evidence here. This spec's UI evidence is the [[file:../prototypes/panel-widget-gallery.html][panel widget gallery]] itself — the living catalogue is the prototype set, not a numbered iteration series: - *Research:* reference photos of period hardware (Berna 3 studio suite, aviation clusters, broadcast consoles, pedals, marine/telegraph instruments) filed in [[file:../../working/retro-stereo-widgets/references/][working/retro-stereo-widgets/references/]]; in-chat-pasted references have provenance noted in card notes and the 2026-07-11/12 session archive. -- *Iterations:* the gallery's git history is the iteration record — N-series base widgets, then reference-derived R01–R31 built and behaviorally verified card by card (commits 7fff507 through 52a43ec, 2026-07-12). 84 cards total, every one CDP-verified (drag tracking, click response, animation, zero console errors). -- *Final:* the gallery as of 52a43ec is the settled visual + behavioral spec each component port is judged against. +- *Iterations:* the gallery's git history is the iteration record — N-series base widgets, then reference-derived R01–R56 built and behaviorally verified card by card (7fff507 through the gallery-upgrades squash merge bc93388 and beyond, 2026-07-12). 109 cards as of the 2026-07-12 review, every one CDP-verified (drag tracking, click response, animation, zero console errors); the committed probe suite lives in =tests/gallery-probes/=. +- *Final:* the gallery at current =main= is the settled visual + behavioral spec each component port is judged against — it keeps growing, so a port is judged against its card as it stands, not a frozen SHA. * Metadata -| Status | draft | +| Status | doing | |----------+-----------------------------------| | Owner | Craig Jennings | |----------+-----------------------------------| -| Reviewer | (spec-review pending) | +| Reviewer | Claude Code (archsetup) | |----------+-----------------------------------| | Related | [[file:../../todo.org][todo.org — Retro widget catalogue]] | |----------+-----------------------------------| * Summary -The panel widget gallery (84 behaviorally-verified retro-instrument cards) is a spec, not yet a library. This document defines how gallery cards become reusable components for three real targets — web (vanilla JS, the gallery itself as first consumer), Emacs (svg.el), and waybar (GTK CSS) — driven by actual demand rather than porting all 84. +The panel widget gallery (109 behaviorally-verified retro-instrument cards as of the 2026-07-12 review) is a spec, not yet a library. This document defines how gallery cards become reusable components for three real targets — web (vanilla JS, the gallery itself as first consumer), Emacs (svg.el), and waybar (GTK CSS). The web library is extracted whole (a lossless transform of code that already exists); the Emacs and waybar ports are driven by actual demand rather than porting the full catalogue. * Problem / Context -The gallery grew card by card as a visual and behavioral catalogue: each card is a self-contained inline builder function inside one 2258-line HTML file. That was right for the collection phase — fast iteration, one canvas, one review surface. It is wrong for consumption: a waybar panel, an Emacs game, or a web UI that wants a VU meter today would have to copy-paste from the gallery's internals and hand-fork the styling. +The gallery grew card by card as a visual and behavioral catalogue: each card is a self-contained inline builder function inside one ~4300-line HTML file (as of the 2026-07-12 review; it still grows). That was right for the collection phase — fast iteration, one canvas, one review surface. It is wrong for consumption: a waybar panel, an Emacs game, or a web UI that wants a VU meter today would have to copy-paste from the gallery's internals and hand-fork the styling. The groundwork is already laid. Tokens are single-sourced in [[file:../prototypes/tokens.json][tokens.json]]; =gen_tokens.py= emits the gallery's =:root= CSS block, [[file:../prototypes/tokens-waybar.css][tokens-waybar.css]], and [[file:../prototypes/gallery-tokens.el][gallery-tokens.el]] (27 tests, 100% coverage). An svg.el proof widget ([[file:../prototypes/gallery-widget.el][gallery-widget.el]], the needle gauge, 10 ERT tests plus an rsvg-convert side-by-side render) proved the Emacs pipeline — the riskiest unknown — end to end. What's missing is the middle layer: parameterized, importable widgets per target, and a decision procedure for which widgets earn a port. @@ -43,14 +45,14 @@ The groundwork is already laid. Tokens are single-sourced in [[file:../prototype - Every port carries tests in its target's idiom (CDP behavioral for web, ERT + visual harness for Emacs, panel test suite for waybar). ** Non-Goals -- Porting all 84 cards. Most cards are catalogue entries; a port with no consumer is inventory nobody asked for. +- Emacs/waybar ports of the full catalogue. Most cards are catalogue entries; a scripted port with no consumer is inventory nobody asked for. (The web extraction is exempt — it transforms code that already exists.) - Shared rendering code across targets. Reuse lives in shared tokens and shared SVG geometry math, not shared code — each target renders in its own idiom (recorded architecture decision). - Framework wrappers (React or otherwise) ahead of a real framework consumer. - Level-2/3 codegen (widget-spec → renderer generation) in this spec's v1 — that's the Phase 5 decision point, deliberately after hand-porting experience exists. ** Scope tiers -- v1: demand inventory, web library extraction, Emacs ports of the demanded widgets, one waybar pilot panel, the Level-2 generator go/no-go. -- Out of scope: new widget collection (R-series closed), shared cross-target rendering code, interaction parity beyond each target's native idiom. +- v1: full web library extraction (with the card-record refactor), demand inventory for the scripted targets, Emacs ports of the demanded widgets, one waybar pilot panel, the Level-2 generator go/no-go. +- Out of scope: new widget collection as part of this work (the catalogue keeps growing on its own track — new cards land as =GW.*= calls once extracted), shared cross-target rendering code, interaction parity beyond each target's native idiom. - vNext (log to todo.org at hand-off): React/framework wrappers, Level-2/3 codegen if Phase 5 says go, ports beyond the demand matrix as consumers appear. * Design @@ -64,12 +66,12 @@ Waybar: no widget functions — waybar consumes =tokens-waybar.css= plus the ban ** For an implementer Three layers, already agreed: tokens (values) → widget spec (the gallery card: geometry, params, behavior) → per-target renderers. The card is the contract. A port re-reads the card's builder for geometry constants and behavioral rules (detent snapping, VU ballistics via the =vuDb()= law, exclusive-select), then re-expresses them natively. Geometry math (polar helpers, scale interpolation tables like =EDGE_SCALE=, =SEG14_MAP=) is copied deliberately per target and cross-checked by tests, not shared as a runtime dependency — the false-coupling judgment from the token work applies to code too. -Extraction order inside Phase 2: the card builders already share =svgEl=/=polar= helpers and document-scoped gradients/filters; lifting them means (a) moving each demanded builder into =widgets.js= behind a parameter object, (b) replacing its gallery card with a call, (c) re-running the existing CDP behavioral probes unchanged — the probes drive the rendered DOM, so a green re-run is the no-regression proof. +Extraction order inside Phase 1: the card builders already share =svgEl=/=polar=/=vuDb=/drag helpers and document-scoped gradients/filters; lifting them means (a) moving the shared engine and each builder into =widgets.js= behind a parameter object, (b) replacing its gallery card with a declarative card record (no / title / stage builder / options / readout / note / spec sheet incl. reference link / validation lamp) rendered by one =card()= path, (c) re-running the existing CDP behavioral probes unchanged — the probes drive the rendered DOM, so a green re-run is the no-regression proof. Batches of roughly 10-15 widgets keep each commit reviewable and the gallery working throughout. * Alternatives Considered ** Port everything to every target up front - Good, because the catalogue would be uniformly consumable. -- Bad, because ~84 × 3 ports is months of work with no consumer for most of it, and unconsumed ports rot silently. +- Bad, because ~109 × 3 ports is months of work with no consumer for most of it, and unconsumed ports rot silently. - Bad, because it front-loads the Level-2 codegen question before hand-port experience exists to answer it. ** Shared renderer core (one geometry engine, thin target adapters) @@ -101,11 +103,11 @@ Extraction order inside Phase 2: the card builders already share =svgEl=/=polar= - Consequences: easier — each target feels native; harder — behavioral parity is a per-port judgment, tested per target rather than shared. - Resolved live with Craig (2026-07-11). -** DONE Demand-driven porting -- Context: 84 cards, three targets, most cards have no consumer today. -- Decision: a widget is ported when the demand matrix names a real consumer (a waybar panel, an Emacs game/UI, a web surface); the matrix is Phase 1's deliverable and Craig approves it. -- Consequences: easier — effort lands where it's used; harder — the catalogue stays partially ported indefinitely, by design. -- Agreed in the 2026-07-12 outline. +** DONE Demand-driven porting (Emacs and waybar targets) +- Context: 109 cards (as of 2026-07-12 review), three targets, most cards have no Emacs or waybar consumer today. +- Decision: an *Emacs or waybar* port happens when the demand matrix names a real consumer (a waybar panel, an Emacs game/UI); the matrix is Phase 1's deliverable and Craig approves it. The *web* extraction is exempt: it is a lossless transform of code that already exists, so it covers the full catalogue (option-1 approval, 2026-07-12). +- Consequences: easier — port effort lands where it's used, and the web library is complete from day one; harder — the Emacs/waybar surface stays partially ported indefinitely, by design. +- Agreed in the 2026-07-12 outline; web-extraction exemption approved with the option-1 go-ahead (2026-07-12). ** DONE Gallery-as-spec - Context: the ui-prototyping rule wants working prototypes as design evidence. @@ -129,14 +131,25 @@ Extraction order inside Phase 2: the card builders already share =svgEl=/=polar= - Context: the gallery is a single self-contained =file://= HTML page; ES modules don't load over =file://=, and a React consumer doesn't exist yet. - Decision: =widgets.js= ships as a classic script exposing one namespace object (working name =GW=), loaded by the gallery via a relative =