Files
Project-SDE-WP-Suite/docs/waves/wave-5.md
n.siegfried 7893a56ea2 Wave 5 exit - record what shipped and where the counts landed
First field-visible wave. Waves 1-4 moved almost nothing on screen; every page
in this one looks different.

Baseline counts, against wave 0
  <div onclick>              12 -> 2    (T5.1 took exactly ten)
  native dialogs app-wide    79 -> 64   (T5.1 2, T5.2 1, T5.8 13)
  ...in the SOP wizard       14 -> 0
  ...in the creator          43 -> 43   wave 7's
  colour literals outside theme-light.css   0 -> 0, held
  SOP wizard steps           10 -> 12   (T5.4 Locations, T5.5 Sections)

Six probes now cover this wave, 399 checks between them, each written because
its task's done-when could not be checked by anything that already existed.

Screenshots re-captured at 390 and 1440 across all seven pages. One overflow,
the known creator@390 (BL-001), unchanged. The two beforeunload log lines on
sop@1440 and creator@1440 are present at wave 4 too - captured both sides during
T5.1 rather than assuming.

BL-010 is honestly unchanged: every rule wave 5 added consumes --wp-s*, and none
of the 829 pre-existing spacing/type/radius literals were converted, because
none of the pages carrying them were re-laid-out here. T7.1 still owns it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-16 14:05:16 -05:00

13 KiB
Raw Permalink Blame History

Wave 5 — Launcher and SOP wizard

Items: A4, B3, S9, S1 (wizard), CR-005, CR-006, CR-002, CR-016 Depends on: wave 4 merged Why here: CR-006 is the enabler for every removal request in the plan. Building it before CR-002 and CR-016 means nothing gets deleted that another project may need.

First field-visible wave. Everything before this was prerequisites.


T5.1 — A4 + S9: Vertical stepper with real buttons

  • Items: A4, S9
  • Depends on: T3.4, T3.5, T2.2
  • Blocks: T5.4, T5.5
  • Surface: html/
  • Files: SOP wizard step rail

Problem: The step rail is 10 <div> elements with onclick, so it is unreachable by keyboard. There is also an orphaned "1 / 10" counter doing the job a stepper should do.

Do: Rebuild the rail as a vertical stepper showing all 10 steps, which is complete, which is current, and which are not yet reachable. Every step is a real <button>. Retire the "1 / 10" counter.

Per C1, this is the moment to make it accessible — it is being rebuilt anyway.

Do not: ship a single <div onclick> in the replacement. The app-wide count from wave 0 must go down by 10.

Done when:

  • all 10 steps are <button> elements
  • the rail is fully operable by keyboard: tab, arrow keys, enter and space
  • current step is exposed with aria-current
  • completed, current and unavailable states are distinguishable without relying on color alone
  • the "1 / 10" counter is gone
  • app-wide <div onclick> count dropped by 10 versus the wave 0 baseline

T5.2 — B3: Launcher empty state, then remove the picker card

  • Items: B3
  • Depends on: T4.1
  • Blocks: T5.3
  • Surface: html/
  • Files: launcher, project picker card

Problem: The proposal removes the project-picker card, but the first-run empty state lives inside it. A header dropdown is the wrong home for "create your first project".

Do: Build an explicit first-run empty state on the launcher: no projects yet, here is how to create one, here is the sample project. Only once that exists, remove the picker card. Order matters — removing the card first strands new users.

Done when:

  • a brand-new account with zero projects sees a clear path to create one
  • the sample project remains discoverable from the empty state
  • the picker card is removed only after the empty state ships
  • switching projects still works from the header for users who have projects

T5.3 — B4 surface: pipeline strip

  • Items: B4 UI half
  • Depends on: T4.1, T5.2
  • Blocks: nothing
  • Surface: html/
  • Files: launcher

Do: Build the four-cell pipeline strip against the server aggregates from T4.1. Each cell links through to the filtered list, using the URL state from T4.2.

Do not: ship it against localStorage. That is the specific thing B4 warns about.

Done when:

  • every number comes from a server endpoint
  • each cell links to a filtered view via a shareable URL
  • a project with zero work packages renders a sensible empty state, not four zeros that look broken
  • the strip announces updates via aria-live if it refreshes in place

T5.4 — CR-005: Upload building / floor / sector lists at SOP setup

  • Items: CR-005
  • Depends on: T5.1
  • Blocks: T6.3
  • Surface: server/ + html/
  • Files: SOP wizard, server API, schema

Intent: The location taxonomy differs per project. On Micron, floors within B100 behave like separate buildings, so floor and sector are the unit of both execution and cost tracking. Configure it once per SOP rather than hard-coding it.

Do: A wizard step accepting a bulk upload (CSV or paste) of Building / Floor / Sector values, with the hierarchy preserved. Editable after import: add, rename, deactivate. Store as structured codes, not display strings — CR-018 needs to group by them.

Deactivating a value hides it from new work packages without breaking existing ones that reference it.

Do not: hardcode floor or building names. The B100 list has not been supplied yet (see IMPLEMENTATION.md section 8). Seed with obviously-fake sample values.

Done when:

  • CSV upload and paste both work and report rejected rows with reasons
  • duplicates are detected and reported rather than silently merged
  • values are editable after import
  • deactivating a value hides it from new work packages; an existing work package referencing it still renders
  • values are stored as codes suitable for grouping
  • no guessed real-world floor names exist anywhere in the code

T5.5 — CR-006: Section toggles

  • Items: CR-006
  • Depends on: T5.1
  • Blocks: T5.6, T5.7, T7.2
  • Surface: server/ + html/
  • Files: SOP wizard, work package renderer, PDF export, creator

Intent: This is the structural fix behind most removal requests in the plan. Rather than deleting fields globally, each project turns on only the sections it uses. It is what lets Micron drop Kitting and Assets while another project keeps them.

Do: In the SOP creation tool, list every work package section with an on/off toggle: General Information, Location, Scope of Work, Assets, Materials, Kitting, Drawings and Attachments, Constraints, QA/QC, Closeout. Default all on for a new SOP.

A section toggled off does not render in the creation form, the detail view, or the PDF export. Data already captured is retained, and toggling back on restores it intact.

Do not: delete data on toggle-off. Ever. And note X4: the creator is an iframe child until T7.1, so toggle propagation into the creator may need revisiting in wave 7 — test it and say what you found.

Done when:

  • all 10 sections are toggleable
  • a section toggled off is absent from the form, the detail view and the PDF export
  • toggling off then on restores prior data with no loss
  • new SOPs default to all sections on
  • toggle state propagates into the creator, or the PR documents exactly where it does not and why

T5.6 — CR-002: Remove Acumatica Cost Code and Task

  • Items: CR-002
  • Depends on: T5.5
  • Blocks: nothing
  • Surface: html/ + server/
  • Files: work package form, detail view, PDF export

Intent: The team concluded these are noise on a field work package. Cost codes are effectively constant and the Acumatica task mapping is a PM concern. The cost visibility they actually want is by building and floor, which is CR-004 and CR-018.

Do: Hide both fields from the form, the detail view and the PDF export, using the section or field toggle mechanism from T5.5. Retain the data and the model.

Do not: drop the columns or delete the data. Another project may need these fields, and that is what the toggles are for.

Done when:

  • neither field appears in the form, detail view or PDF export for the Micron EUV SOP
  • existing records still hold their values; confirm by querying
  • the fields can be re-enabled for another SOP without a code change
  • no schema migration drops data

T5.7 — CR-016: Assets section off for Micron EUV

  • Items: CR-016
  • Depends on: T5.5
  • Blocks: nothing
  • Surface: configuration
  • Files: SOP configuration for Micron EUV

Intent: Asset content duplicates the database Clinton's team maintains. Integration is deferred, so the section comes out in the interim.

Do: Toggle Assets off for the Micron EUV SOP. Leave the section and its data model in the application so the eventual database integration has somewhere to land.

Done when:

  • Assets does not render for Micron EUV in the form, detail view or export
  • the section and model remain in the codebase
  • another SOP can enable Assets and it works

T5.8 — S1 (wizard): Inline validation

  • Items: S1 wizard half
  • Depends on: T5.1
  • Blocks: nothing
  • Surface: html/
  • Files: SOP wizard validation, wp-creation-app.js:1144 for the pattern to replace

Problem: Validation is alert()-only and validateStep guards only steps 1, 5 and 6, while the markup marks required fields throughout. The message "Subject and WP Type are required" names no field, highlights nothing and scrolls nowhere.

Do: Inline validation on every step that has required fields. Errors appear at the field, the first invalid field receives focus, and the message says what is wrong. Announce via the aria-live region from T4.5. Remove the wizard's alert() calls.

Do not: add a native alert(), confirm() or prompt() anywhere. The app-wide count from wave 0 must go down.

Done when:

  • every step with required fields validates them
  • each error renders at its field and is associated via aria-describedby
  • submitting an invalid step focuses and scrolls to the first error
  • errors announce to screen readers
  • the wizard's native dialog count is 0; record the new app-wide count

Wave 5 exit criteria

  • the stepper is keyboard operable and <div onclick> count dropped by at least 10 — 12 → 2, exactly ten, and the two survivors are wave 7's and wave 9's
  • section toggles work end to end, including the export
  • Acumatica fields and Assets are hidden by configuration, with no data deleted
  • the wizard has no alert() calls left — 0, raw and comment-stripped
  • first-run users can create a project

Wave 5 exit — what shipped, and what it cost

First field-visible wave. Everything before this was prerequisites, and the difference shows: waves 14 moved almost nothing on screen, and every page in this one looks different.

The tasks

Task Items What landed
T5.1 A4 S9 Vertical stepper, ten real <button>s, keyboard operable, states in words
T5.2 B3 First-run empty state, then the picker card removed; switching moved to the app bar
T5.3 B4 UI Four-cell pipeline strip, every number from the server, every cell a shareable link
T5.4 CR-005 Per-project Building / Floor / Sector taxonomy — new table, four routes, step 11
T5.5 CR-006 Section toggles, shared registry, form + detail view + export
T5.6 CR-002 Acumatica cost code and task, hidden by field toggle
T5.7 CR-016 Assets off for Micron EUV, by configuration
T5.8 S1 wizard Inline validation on five steps; thirteen native dialogs retired

Baseline counts

Metric Wave 0 End of wave 5 Moved by
<div onclick> 12 2 T5.1
native dialogs app-wide 79 64 T5.1 (2), T5.2 (1), T5.8 (13)
…of those, in the SOP wizard 14 0 T5.8
…of those, in the creator 43 43 wave 7
colour literals outside theme-light.css 0 0 held
SOP wizard steps 10 12 T5.4, T5.5

Probes added

Five, each written because its task's done-when could not be checked by anything that already existed. Run them one at a time.

python tests/stepper_check.py       # A4/S9    71 checks
python tests/launcher_check.py      # B3       58 checks (two seeded databases)
python tests/pipeline_check.py      # B4 UI    43 checks
python tests/locations_check.py     # CR-005   58 checks
python tests/sections_check.py      # CR-006/CR-002/CR-016   88 checks
python tests/validation_check.py    # S1       81 checks

The four things the probes caught that a review would not have

  1. T5.1 — the rail did not track the form. Fill step 1 and every step ahead stayed padlocked until you navigated. A rail that lies about the form is worse than the strip it replaced, because that one at least lied consistently.
  2. T5.2f_items.py's F1 went INCONCLUSIVE, not FAIL. Its probe drove the picker card's <select>, which B3 deleted. It refused to guess, which is the behaviour f_items exists for.
  3. T5.3 — a pipeline link landed on "complete the SOP first". Not the strip's fault: browser_check's fixture stores a SOP shape production never writes. Logged as BL-018.
  4. T5.6 — a probe reported the cost code being eaten by a section toggle. It was not; the probe used an invented code and wp_cost is a <select> that silently drops an unknown value. That silent drop is real, is not this wave's, and is BL-019.

Open, carried into wave 6 and beyond

  • BL-010 (raw spacing and type values) is unchanged. Every rule wave 5 added consumes --wp-s*; none of the 483/281/65 pre-existing literals were converted, because none of the pages carrying them were re-laid-out here. T7.1 still owns it.
  • X4 is resolved rather than deferred — see T5.5's commit. The SOP-borne propagation path is unaffected by B7; the live hand-off across the frame is what T7.1 removes.
  • BL-018 (the WP tab's gate is the last localStorage-derived status) is the one finding in this wave that is a real user-facing weakness rather than a test artefact.