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
4.7 KiB
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 +
/reportarchive — 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.