Import the R2 implementation spec into the repo
The plan was delivered as wp-suite-implementation-spec.zip and lived only in Downloads, so every "read CLAUDE.md first" instruction in it pointed at a file the repo did not have. Bring it in unchanged: CLAUDE.md, IMPLEMENTATION.md, and docs/waves/wave-0 through wave-9 plus backlog.md. UX-REVIEW-2026-08-14.md is committed alongside it. It is the review that produced F1-F6, S1-S13 and the A/B/C assessments, and item IDs throughout the wave files cite it, so it belongs under version control rather than sitting untracked in the working tree. No application code changes here. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
185
docs/waves/wave-1.md
Normal file
185
docs/waves/wave-1.md
Normal file
@@ -0,0 +1,185 @@
|
||||
# Wave 1 — Rendering defects and tooling
|
||||
|
||||
**Items:** `F1`, `F2` (interim), `F3`, `F4`, `F5` (interim), `S13`
|
||||
**Depends on:** wave 0
|
||||
**Why first:** none of these need a design decision, and `F1` and `F2` block all chrome work
|
||||
in wave 2.
|
||||
|
||||
Two tasks here are deliberately partial. `F2` gets a containment fix only because `B1` in
|
||||
wave 2 resolves it properly, and `F5` gets a one-line fix because `C3` in wave 3 removes the
|
||||
underlying cause. Do not over-build either.
|
||||
|
||||
---
|
||||
|
||||
### T1.1 — F1: Header project switcher is stale on every page
|
||||
|
||||
- **Items:** `F1`
|
||||
- **Depends on:** T0.1
|
||||
- **Blocks:** T2.1, T2.2
|
||||
- **Surface:** `html/`
|
||||
- **Files:** per file-map — the app bar/header component and whatever holds active-project state
|
||||
|
||||
**Problem:** The hero, the project picker and the create-user card all show the active
|
||||
project. The app bar still reads "Select a project". Two sources of truth for the same value,
|
||||
and the global one loses.
|
||||
|
||||
**Do:**
|
||||
|
||||
Find every place the active project is read or stored. There is more than one. Collapse them
|
||||
to a single source, and have the app bar subscribe to it rather than holding its own copy.
|
||||
Set the value on project selection and on page load, including a hard refresh and a
|
||||
deep-linked page.
|
||||
|
||||
**Do not:** introduce a state library. This is a single value with a small number of readers.
|
||||
|
||||
**Done when:**
|
||||
|
||||
- [ ] the app bar shows the active project on all 6 pages
|
||||
- [ ] value survives a hard refresh on every page
|
||||
- [ ] switching projects updates the app bar and the hero in the same interaction, with no reload
|
||||
- [ ] with no project selected, the app bar reads "Select a project" and the picker is reachable
|
||||
- [ ] exactly one code path writes active-project state; note its location in the PR
|
||||
|
||||
---
|
||||
|
||||
### T1.2 — F2 (interim): stop the app bar clipping at 390px
|
||||
|
||||
- **Items:** `F2` partial
|
||||
- **Depends on:** T1.1
|
||||
- **Blocks:** nothing (superseded by T2.2)
|
||||
- **Surface:** `html/`
|
||||
- **Files:** app bar styles
|
||||
|
||||
**Problem:** At 390px the nav wraps to three rows and clips. "Sign out" is cut in half and
|
||||
search is truncated. Field View runs at this width on tablets with gloved hands.
|
||||
|
||||
**Do:** The smallest change that guarantees no control is unreachable or visually cut. Allow
|
||||
the bar to scroll or stack rather than clip. This is triage, not a redesign — `T2.2` deletes
|
||||
this markup.
|
||||
|
||||
**Do not:** build a responsive menu, a hamburger, or an avatar dropdown. Wave 2 ships the
|
||||
existing drawer instead, and anything built here would be thrown away.
|
||||
|
||||
**Done when:**
|
||||
|
||||
- [ ] at 390px no nav control is clipped or unreachable on any of the 6 pages
|
||||
- [ ] "Sign out" is fully visible and tappable at 390px
|
||||
- [ ] search is either fully usable or deliberately hidden at this width, not truncated
|
||||
- [ ] no layout change at 1440px — screenshot diff against baseline is empty
|
||||
- [ ] the PR states this is interim and names `T2.2` as the real fix
|
||||
|
||||
---
|
||||
|
||||
### T1.3 — F3: Logo and project name collide in the SOP header
|
||||
|
||||
- **Items:** `F3`
|
||||
- **Depends on:** T1.1
|
||||
- **Blocks:** nothing
|
||||
- **Surface:** `html/`
|
||||
- **Files:** SOP wizard page and its header styles, `.header-left`
|
||||
|
||||
**Problem:** `.header-left` and the injected chrome compete for the same run of the bar and
|
||||
overlap.
|
||||
|
||||
**Do:** Give the two elements a defined relationship rather than letting both claim the same
|
||||
space. Verify with a long project name — "Micron EUV Cleanroom Enable 2667008" is the real
|
||||
one and it is what breaks things.
|
||||
|
||||
**Do not:** solve it by truncating the project name. `B2` in wave 2 owns truncation and
|
||||
needs a breakpoint plan, not a silent ellipsis.
|
||||
|
||||
**Done when:**
|
||||
|
||||
- [ ] no overlap at 390px, 768px, 1024px and 1440px
|
||||
- [ ] tested with the longest real project name
|
||||
- [ ] the logo remains fully visible at all four widths
|
||||
|
||||
---
|
||||
|
||||
### T1.4 — F4: Comments drawer renders off-screen over the header
|
||||
|
||||
- **Items:** `F4`
|
||||
- **Depends on:** T0.1
|
||||
- **Blocks:** nothing
|
||||
- **Surface:** `html/`
|
||||
- **Files:** standalone creator page and comments drawer styles
|
||||
|
||||
**Problem:** In the standalone creator, the comments drawer renders off-screen and over the
|
||||
header.
|
||||
|
||||
**Do:** Fix the positioning context and stacking. Check whether the drawer is positioned
|
||||
relative to the iframe or the parent — if the iframe boundary is implicated, note it in the
|
||||
PR because `T7.1` removes that boundary.
|
||||
|
||||
**Do not:** raise `z-index` until something happens to work. Identify the containing block
|
||||
first and say what it was in the PR.
|
||||
|
||||
**Done when:**
|
||||
|
||||
- [ ] the drawer opens fully on screen in the standalone creator at 390px and 1440px
|
||||
- [ ] the drawer does not cover the header
|
||||
- [ ] the drawer closes and reopens correctly, and scroll position is not lost
|
||||
- [ ] behavior is identical in the embedded and standalone creator
|
||||
|
||||
---
|
||||
|
||||
### T1.5 — F5 (interim): SOP wizard fields read as read-only
|
||||
|
||||
- **Items:** `F5` partial, `A3` partial
|
||||
- **Depends on:** T0.1
|
||||
- **Blocks:** nothing (completed by T3.4)
|
||||
- **Surface:** `html/`
|
||||
- **Files:** SOP wizard stylesheet
|
||||
|
||||
**Problem:** Wizard inputs render with a `#f4f4f4` fill and `#e0e0e0` border, which reads as
|
||||
disabled. Users do not type in them. The cause is that the wizard redeclares its own tokens
|
||||
and never sees `--cds-field: #ffffff`.
|
||||
|
||||
**Do:** Make the fields look editable. The minimal correct fix is to have the wizard consume
|
||||
the existing field token instead of its local override.
|
||||
|
||||
**Do not:** start token consolidation here. That is `T3.1`–`T3.3` and it is a separate,
|
||||
mechanical, whole-app change. Fix the field appearance only.
|
||||
|
||||
**Done when:**
|
||||
|
||||
- [ ] wizard inputs render with a white fill and a border visually consistent with inputs elsewhere
|
||||
- [ ] genuinely disabled inputs still look disabled and are distinguishable from enabled ones
|
||||
- [ ] no other component changes appearance — screenshot diff limited to the wizard
|
||||
- [ ] the PR notes that `T3.4` removes the underlying duplicate token
|
||||
|
||||
---
|
||||
|
||||
### T1.6 — S13: `server/seed_demo.py` cannot seed a running instance
|
||||
|
||||
- **Items:** `S13`
|
||||
- **Depends on:** T0.1
|
||||
- **Blocks:** nothing, but makes every later task's setup faster
|
||||
- **Surface:** `server/`
|
||||
- **Files:** `server/seed_demo.py`, and the smoke test for reference
|
||||
|
||||
**Problem:** Every `/api/` route requires a session and the script sends none, so it cannot
|
||||
seed a running instance. It predates the commit that taught the smoke test to sign in.
|
||||
|
||||
**Do:** Give the script the same authentication the smoke test uses. Reuse that code path
|
||||
rather than writing a second one.
|
||||
|
||||
**Do not:** add a bypass, a debug flag, or an unauthenticated seeding route to the server.
|
||||
The script authenticates like a client; the server does not get weaker.
|
||||
|
||||
**Done when:**
|
||||
|
||||
- [ ] `seed_demo.py` runs against a freshly started instance and exits 0
|
||||
- [ ] the seeded data is visible in the UI after running it
|
||||
- [ ] running it twice does not error or duplicate data, or it fails with a clear message
|
||||
- [ ] no new unauthenticated route exists — confirm by diff
|
||||
|
||||
---
|
||||
|
||||
## Wave 1 exit criteria
|
||||
|
||||
- [ ] `F1`, `F3`, `F4` fully resolved and confirmed against the wave 0 baseline screenshots
|
||||
- [ ] `F2` and `F5` contained, with their real fixes referenced (`T2.2`, `T3.4`)
|
||||
- [ ] `S13` fixed and seeding works
|
||||
- [ ] no new `<div onclick>`, no new raw hex values, no new `alert()` calls introduced
|
||||
- [ ] `F6` untouched — it is a structural problem fixed by section tabs in `T7.2`
|
||||
Reference in New Issue
Block a user