60469422af
PHASE 0 — the order proposed E1 + E9 as Wave-1 and told me to follow the
audit if it disagreed. It disagrees: E9 calibration curve is WAVE D3,
gated on MODEL work ("resolve n>=20 vs N30, accrue buckets"), and E1
movement strip is WAVE D6, a large surface build. E9's gate is live right
now -- calibration is WITHDRAWN at 0 eligible dates, so the curve could
only render its empty state today. Building it would ship a component
whose entire purpose is unavailable.
PHASE 1 — three of the five real Wave D1 items were ALREADY DONE, and the
2026-07-31 audit has aged:
D1 glyph library audit: 38/83 wired (46%)
now: COMPLETE for everything wireable -- 39 of 83
designed glyphs map to a real archetype, all 39
are wired, colours match the registry exactly
(0 disagreements).
A1 card token audit: BUILT-BUT-DRIFTED, "in only 1 file"
now: BUILT-TO-SPEC -- it IS the --bg-1 token,
consumed by 32 files. The audit counted literal
hex, which is what a correctly tokenised value
looks like.
B1 boundary blue audit: PARTIAL, hex in 2 files
now: BUILT -- --priced-out/#8fb2de is a token with a
documented colour law, 4 consumers.
The 44 unwired glyphs are NOT a wiring gap: they have no backend
archetype, so wiring them means inventing 44 archetypes to consume
artwork -- the fabrication this programme refuses. That is the 41-vs-74
scope question and it is Kev's call. Separately, 2 registry archetypes
have NO designed glyph (DUAL THREAT, PAINT BOSS) -- a design gap.
PHASE 2 — what was genuinely absent is now built. web/src/lib/motion.js:
nudge() capped at 180ms so it reads as acknowledgement rather than
latency; bootStagger capped at 240ms because uncapped, row 40 waits 1.1s
and the stagger BECOMES the latency it exists to disguise; rowHover
returns handlers not CSS so touch cannot stick a hover state; and
revealOnIntersect returns an unobserve in every path and reveals
IMMEDIATELY when there is no IntersectionObserver or motion is reduced --
content is never hidden behind a capability check.
Reduced motion is honoured, not softened. The sharpest of the 10 tests:
bootStagger under reduced motion returns opacity 1, not merely delay 0 --
if the CSS animation supplies the opacity, skipping it leaves the row
invisible forever.
PHASE 3 — the reachability guard gains a PRIMITIVES section: a module
built to be embedded must declare its exports AND name its intended
consumers, because a primitive imported by nothing is the same
built-but-unread class as an unmounted component.
WAVE-2 UNGATED: F9-F11 offseason hub, F5 article media, E10/E12 Report,
E1 movement strip. GATED: E9 + E15 on model, E16/F8 on the resolution tail
and the card-system reconciliation, E2/E6 on licensing, E13 on another
order.
Read-only throughout; serving fingerprint unchanged; accrual clock
unchanged at 0 eligible dates.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W1sivYNqY2TS5ftykmHBU9
85 lines
4.7 KiB
Markdown
85 lines
4.7 KiB
Markdown
# Wave D1 — and why E1/E9 were not it
|
||
|
||
## PHASE 0 — the audit's actual wave order
|
||
|
||
The order proposed E1 + E9 as Wave-1 primitives and instructed me to follow the
|
||
audit if it disagreed. **It disagrees.**
|
||
|
||
| item | the audit's placement |
|
||
|---|---|
|
||
| **E9 calibration curve** | **WAVE D3 — gated on MODEL work**: *"resolve n≥20 vs N30, accrue buckets"* |
|
||
| **E1 movement strip** | **WAVE D6 — large surface builds**, alongside crown / disagreement axis / SPLIT |
|
||
|
||
**Neither is Wave 1.** And E9's gate is live right now: calibration is
|
||
**withdrawn** (`CALIBRATION_DEPLOYED = []`) at **0 eligible dates**, so a
|
||
calibration curve today could only render its empty state. Building it now would
|
||
produce a component whose entire purpose is unavailable.
|
||
|
||
**WAVE D1, per the audit:** glyph library · card token + `vy-glitch` naming ·
|
||
`nudge()`/boot-stagger/row-hover/IntersectionObserver · boundary-channel blue ·
|
||
team-gradient chips + READ-FAB.
|
||
|
||
## PHASE 1 — three of the five Wave D1 items were already done
|
||
|
||
Checked rather than assumed, and the audit (2026-07-31) has aged:
|
||
|
||
| item | audit said | measured now |
|
||
|---|---|---|
|
||
| **D1 glyph library** | PARTIAL — 38 of 83 wired (46%) | **COMPLETE for everything wireable.** 83 designed glyphs, 41 registry archetypes, **39 map — and all 39 are wired, with colours matching the registry exactly (0 disagreements).** |
|
||
| **A1 card token `#0E0E14`** | BUILT-BUT-DRIFTED — "in only 1 file" | **BUILT-TO-SPEC.** It is the `--bg-1` token in `globals.css`, consumed by **32 files** via `var(--bg-1)`. The audit counted literal hex occurrences, which is what a *correctly tokenised* value looks like. |
|
||
| **B1 boundary channel** | PARTIAL — hex in 2 files | **BUILT.** `--priced-out: #8fb2de` + `--priced-out-dim` are tokens with a documented colour law in `globals.css`, consumed by 4 files. |
|
||
|
||
**The 44 unwired glyphs are not a wiring gap.** They have no backend archetype —
|
||
wiring them would mean **inventing 44 archetypes to consume artwork**, which is
|
||
the fabrication this programme refuses. That is the 41-vs-74 scope question, and
|
||
it is Kev's call, not a build task. Separately, **2 registry archetypes have no
|
||
designed glyph** (`DUAL THREAT`, `PAINT BOSS`) — a design gap, not a code one.
|
||
|
||
## PHASE 2 — what was genuinely absent, and is now built
|
||
|
||
`web/src/lib/motion.js` — the four primitives, all previously 0 files:
|
||
|
||
| primitive | the rule it enforces |
|
||
|---|---|
|
||
| **E17 `nudge()`** | ≤180ms. Confirms an action *registered* without claiming it finished — a long pulse reads as latency, the opposite of a perceived-speed primitive. |
|
||
| **E18 `bootStagger()`** | **capped at 240ms.** Uncapped, row 40 waits 1.1s and the stagger *becomes* the latency it exists to disguise. |
|
||
| **E27 `rowHover()`** | returns handlers, not CSS — so a tap on touch cannot stick a hover state that never clears. |
|
||
| **E28 `revealOnIntersect()`** | returns an unobserve fn in every path, and **reveals IMMEDIATELY** without IntersectionObserver or under reduced motion. Content is never hidden behind a capability check. |
|
||
|
||
**Reduced motion is honoured, not softened** — every primitive skips outright,
|
||
and server-side assumes reduced. 10 tests, the sharpest being that
|
||
`bootStagger` under reduced motion returns `opacity: 1` and not merely
|
||
`delay: 0`: if the CSS animation supplies the opacity, skipping the animation
|
||
without forcing it leaves the row invisible forever.
|
||
|
||
## PHASE 3 — guard registration and Wave-2 readiness
|
||
|
||
The reachability guard now carries a **PRIMITIVES** section: a module built to be
|
||
embedded must declare its exports *and name its intended consumers*. A primitive
|
||
imported by nothing is the same built-but-unread class as an unmounted
|
||
component. 24 checks green.
|
||
|
||
### Wave-2 readiness
|
||
|
||
**Ungated — design complete, no blocker:**
|
||
- **F9/F10/F11 offseason hub** (Wave D6) — the largest, fully spec'd
|
||
- **F5 article media** (Wave D6) — hero + figure system fully spec'd
|
||
- **E10/E12 The Report email + `/report` archive** — design exists
|
||
- **E1 movement strip** (Wave D6) — spec'd, absent, now has its motion primitives
|
||
|
||
**Gated, and by what:**
|
||
| item | gate |
|
||
|---|---|
|
||
| E9 calibration curve | **model** — calibration withdrawn, 0 eligible dates |
|
||
| E15 Price Triplet MODEL leg | **model** — EV layer |
|
||
| E16 share cards + F8 crops | **resolution tail** *and* the card-system reconciliation |
|
||
| E2 BookChip tiles / E6 push-to-book | **licensing / affiliate approval** |
|
||
| E13 Scanner S6 | another build order |
|
||
|
||
**The card-system reconciliation** (content-engine 1080×1350 vs E16's five
|
||
masters) gates E16/F8 and should be settled with the social chat, since off-site
|
||
posts and on-site share cards are one system.
|
||
|
||
Isolated throughout: read-only, no serving or model change, **accrual clock
|
||
unchanged at 0 eligible dates**.
|