Wave 7 prep - record the Aug 18 decisions as D1-D10 and amend the waves
Nick answered 21 questions at the wave 6 exit and 11 follow-ups. Seven answers are new build work, three amend acceptance criteria on tasks already scheduled, and two close questions without work. None of it had an item ID, so none of it could be built under CLAUDE.md's first rule. New items D1-D10 in docs/waves/decisions-2026-08-18.md. A new prefix rather than widened CR/F/S/A/B/C numbers - those are referenced in documents outside this repo and CLAUDE.md forbids reinterpreting them. Every D entry names the item it amends and quotes the criterion it replaces, so a reader of R2 can see what moved. D1 sample data returns to the creator B7, S7 T7.1 D2 QA distribution list configured in the SOP CR-014 T7.6 D3 side navigation and collapsible sections, not tabs F6 T7.2 D4 Urgent surfaces the audited override, never bypasses CR-003/A1 T7.3 D5 usage data moves to the admin console B7 T7.10 (new) D6 material list uploads at SOP configuration CR-013 T8.6 (new) D7 archived projects readable by project admins B3, C1 T9.8 (new) D8 5MB a file, 2GB a project, PDFs and images, one DB CR-007 T7.7 D9 Ready for QA appears in Field View CR-014 T7.6 D10 email switched on and off from the admin console CR-011/14 T7.6, T8.3 Two decisions were mine to make and are recorded as such. D3: the written F6 criterion (no view over two screen heights) and the answer (one long form with side nav) cannot both hold, so the criterion now reads 'at rest' and sections collapse by default - tabs hide sections a first-time author does not know exist. D8: keeping 5MB files in the same database means every encrypted backup carries them; splitting them out was rejected because a backup without the drawings cannot restore, so a 2GB per-project ceiling was approved instead. Also corrected, not amended: CLAUDE.md and IMPLEMENTATION.md X2 both cited wp-creation-app.js:1962-1972 as the protected logged-override path that T7.3 is forbidden to remove. Those lines are deletePackage() and clearSaved(). The path is confirmEarlyRelease() at :1002. Both documents now name it by function so the reference survives the T7.1 rewrite that is about to move it. Wave 9 gains T9.9, a sweep of the nine backlog entries that name wave 9 as their home. Left unscheduled they surface at T9.7, which has no room to fix anything. The four colour items in it (BL-004/005/008/009) are now approved work. T9.5's help-tip count corrected from 15 to 18 and dated: three were added during waves 5 and 6 by tasks reusing the component as designed, each unreachable for the same reason. Scheduling a broken component late makes every reuse cost more. Closed without work: the free-text location migration. Every location on record is sample data because no real list has been loaded, so there is nothing to migrate. Recorded with the condition that invalidates it - the first real project - so it is a decision rather than a surprise. Items: D1 D2 D3 D4 D5 D6 D7 D8 D9 D10 Task: T7.0 (wave 7 prep) Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,20 +1,29 @@
|
||||
# Wave 7 — The creator
|
||||
|
||||
**Items:** `B7`, `A1`, `CR-015`, `A2`, `A6`, `CR-014`, `CR-007`, `B6`, `S1` (creator), `F6`
|
||||
**Items:** `B7`, `A1`, `CR-015`, `A2`, `A6`, `CR-014`, `CR-007`, `B6`, `S1` (creator), `F6`,
|
||||
and from August 18: `D1`, `D2`, `D3`, `D4`, `D5`, `D8`, `D9`, `D10`
|
||||
**Depends on:** wave 6 merged, and `T4.2` (URL state) merged
|
||||
**Why last among the build waves:** most of it depends on the iframe decision, and `CR-014`
|
||||
depends on `X1`.
|
||||
|
||||
`T7.1` is the largest engineering item in the plan. Decided and approved: the iframe gets
|
||||
dissolved. Do it first — everything after it is cheaper on the far side.
|
||||
dissolved. Do it first - everything after it is cheaper on the far side.
|
||||
|
||||
**Read `docs/waves/decisions-2026-08-18.md` before starting.** Eight of its ten items land in
|
||||
this wave, four of them as changes to done-when lists written below. Where a task carries an
|
||||
`Amended` block, that block wins over the text above it.
|
||||
|
||||
**Read `docs/reference/creator-frame.md` before `T7.1`.** It is the measurement of the
|
||||
boundary: 21 colliding stylesheet selectors, 9 colliding script globals, 0 colliding markup
|
||||
ids, 28 cross-frame call sites, and the three questions no count can answer.
|
||||
|
||||
---
|
||||
|
||||
### T7.1 — B7: Dissolve the creator iframe
|
||||
|
||||
- **Items:** `B7`
|
||||
- **Items:** `B7`, `D1`
|
||||
- **Depends on:** T6.5
|
||||
- **Blocks:** T7.2 through T7.9
|
||||
- **Blocks:** T7.2 through T7.10
|
||||
- **Surface:** `html/`
|
||||
- **Files:** parent page hosting the creator, the creator itself, cross-frame messaging
|
||||
|
||||
@@ -32,6 +41,28 @@ reviewable as a structural change.
|
||||
**Do not:** bundle any other item into this task, and do not leave a dormant iframe path
|
||||
behind a flag.
|
||||
|
||||
**Amended August 18 (`D1`, `D5`).** `creator-frame.md` section 4 lists three questions this
|
||||
task has to settle. Two are now answered:
|
||||
|
||||
- **Does the creator get the app bar back?** Yes. It is the only page in `html/` that loads
|
||||
neither `wp-chrome.css` nor `wp-chrome.js`, and a page without the app bar is not a page.
|
||||
Expect to redo the wizard's layout arithmetic - `chromeHeight()`, `--wp-chrome-h`, the
|
||||
`embed-full` sizing.
|
||||
- **What happens to `body.embedded`?** It goes, and with it `.embed-hide`. The three controls
|
||||
it was hiding: the creator's own header stays hidden because the app bar replaces it; the
|
||||
**sample-data control becomes visible** (`D1`); the analytics button stays visible here and
|
||||
**moves to the admin console at `T7.10`** (`D5`). Do not delete it in this task - a task
|
||||
that both dissolves the frame and deletes a feature is two diffs.
|
||||
- **One sequence component or two?** Still open, and still this task's call. Nine of the 21
|
||||
colliding selectors are the sequence editor. The wizard authors the sequence and the creator
|
||||
renders it; confirmed August 18 that those stay two adjustable things, which argues for
|
||||
scoping rather than merging. If you scope, say so and leave `BL-015` open for wave 9.
|
||||
|
||||
**Do not** fold `BL-001`, `BL-006`, `BL-007` or `BL-013` into this diff. They are logged
|
||||
against this file and they are cheaper now than ever, and they are still separate items. What
|
||||
this task owes them is a **measurement**: record whether each still reproduces after the
|
||||
rebuild, so `T7.2` and `T9.5` inherit a fact rather than an assumption.
|
||||
|
||||
**Done when:**
|
||||
|
||||
- [ ] no iframe remains in the creator; grep confirms
|
||||
@@ -40,12 +71,16 @@ behind a flag.
|
||||
- [ ] `CR-006` section toggles propagate into the creator with no special-casing
|
||||
- [ ] browser back and forward still behave with the `T4.2` URL state
|
||||
- [ ] no cross-frame messaging code remains
|
||||
- [ ] the creator renders the standard app bar, and the wizard's chrome arithmetic still holds at 390px and 1440px
|
||||
- [ ] `body.embedded` and `.embed-hide` are gone; grep confirms
|
||||
- [ ] the sample-data control is visible and reachable on the creator (`D1`)
|
||||
- [ ] `BL-001`, `BL-006`, `BL-007` and `BL-013` are each re-measured after the rebuild and their entries updated with the result
|
||||
|
||||
---
|
||||
|
||||
### T7.2 — F6 + A4 pattern: Section tabs replace the 4,700px form
|
||||
### T7.2 — F6 + D3: Side navigation and collapsible sections replace the 4,700px form
|
||||
|
||||
- **Items:** `F6`
|
||||
- **Items:** `F6`, `D3`
|
||||
- **Depends on:** T7.1, T5.5, T3.5
|
||||
- **Blocks:** T7.9
|
||||
- **Surface:** `html/`
|
||||
@@ -58,24 +93,41 @@ jump links standing in for structure.
|
||||
group at a time. Respect the `CR-006` toggles: a section toggled off has no tab. Retire the
|
||||
jump links. Section identity belongs in the URL (`T4.2`) so a section is linkable.
|
||||
|
||||
**Amended August 18 (`D3`) - the answer is not tabs.** Asked to choose, the decision was one
|
||||
page with navigation down the side; asked about the height conflict that creates, the call was
|
||||
delegated. Adopted: **one page, persistent side navigation, sections collapsible, only the
|
||||
current one open by default, plus an `Expand all`.** Tabs were rejected because they hide
|
||||
sections a first-time author does not know exist. An uncollapsed long form was rejected
|
||||
because it is the 4,700px page `F6` exists to fix. The done-when list below is the amended
|
||||
one; it replaces four of the six entries as written.
|
||||
|
||||
`BL-013` is folded in here and only here: the creator's inputs have `outline: none` with a
|
||||
1.05:1 glow as their only focus cue, which is a standing `CLAUDE.md` violation on the page
|
||||
with the most form controls in the app. A rebuilt form ships the `T3.4` ring or it is not
|
||||
done.
|
||||
|
||||
**Done when:**
|
||||
|
||||
- [ ] no single view exceeds roughly two screen heights at 1440px
|
||||
- [ ] toggled-off sections have no tab
|
||||
- [ ] no single view exceeds roughly two screen heights at 1440px **at rest** - that is, in the default collapse state the page loads in
|
||||
- [ ] toggled-off sections have no entry in the side navigation
|
||||
- [ ] each section is addressable by URL and survives refresh
|
||||
- [ ] jump links are gone
|
||||
- [ ] tabs are keyboard operable and follow the tab pattern with `aria-selected` and arrow keys
|
||||
- [ ] the side navigation is keyboard operable and marks the current section with `aria-current`
|
||||
- [ ] each section header is a real `<button>` with `aria-expanded`, not a `<div>` with a click handler
|
||||
- [ ] `Expand all` and its inverse exist and are keyboard reachable
|
||||
- [ ] deep-linking to a collapsed section expands it
|
||||
- [ ] unsaved work is preserved when moving between sections (`T4.3`)
|
||||
- [ ] every focusable control on the page draws a ring of at least 3:1 against its background (`BL-013`)
|
||||
|
||||
---
|
||||
|
||||
### T7.3 — A1 + CR-015: Guarded transitions and the hold bug
|
||||
|
||||
- **Items:** `A1`, `CR-015`
|
||||
- **Items:** `A1`, `CR-015`, `D4`
|
||||
- **Depends on:** T7.1
|
||||
- **Blocks:** T7.4, T7.6
|
||||
- **Surface:** `server/` + `html/`
|
||||
- **Files:** status handling, constraint handling, `wp-creation-app.js:1962-1972`
|
||||
- **Files:** status handling, constraint handling, `confirmEarlyRelease()` in `wp-creation-app.js`
|
||||
|
||||
**This is one task, not two (`X2`).** The hold-not-clearing bug and the transition model are
|
||||
the same code. `CR-015` is the highest-severity item in the plan and it was reproduced live
|
||||
@@ -85,9 +137,15 @@ in front of the Micron team.
|
||||
derived from open constraints, which is why it goes stale.
|
||||
|
||||
**Do:** Model transitions explicitly. For each state, define the primary next action **plus
|
||||
an audited override**. "One legal next action" is too narrow — `wp-creation-app.js:1962-1972`
|
||||
contains a deliberate logged-override path for predecessors, and Issue (Hold) is a branch
|
||||
from several states, not a single linear step.
|
||||
an audited override**. "One legal next action" is too narrow - `confirmEarlyRelease()` in
|
||||
`wp-creation-app.js` is a deliberate logged-override path for predecessors, and Issue (Hold)
|
||||
is a branch from several states, not a single linear step.
|
||||
|
||||
**Corrected August 18.** This task's file list, `IMPLEMENTATION.md` `X2` and `CLAUDE.md` all
|
||||
cited `wp-creation-app.js:1962-1972` as the protected override path. Those lines are
|
||||
`deletePackage()` and `clearSaved()` - a different rule entirely. The path to preserve is
|
||||
`confirmEarlyRelease()`, called from the issue and release paths. All three documents now name
|
||||
it by function so the reference survives this rebuild.
|
||||
|
||||
Derive hold state from open constraints rather than storing it independently, or if it must
|
||||
be stored, recalculate it on every constraint change. Write every hold and release to the
|
||||
@@ -107,6 +165,17 @@ the symptom by recalculating on page load only.
|
||||
- [ ] a regression test covers the clear-last-constraint path specifically
|
||||
- [ ] the exact root cause is stated in the PR
|
||||
|
||||
**Amended August 18 (`D4`) - what `Urgent` does.** Asked whether an `Urgent` package should be
|
||||
issuable with an open constraint, the first answer was "maybe". The concern raised back was
|
||||
that a silent bypass destroys the delay-documentation use case that justifies the whole
|
||||
constraint workflow: a constraint log that can be shown to have been skipped stops supporting
|
||||
a notice of delay. Confirmed: **surface the audited path, do not add a new one.**
|
||||
|
||||
- [ ] an `Urgent` package with an open constraint offers `confirmEarlyRelease()` in the primary action position, not behind a secondary control
|
||||
- [ ] taking it still writes actor, timestamp and reason to history
|
||||
- [ ] no code path releases a constrained package without writing that entry; verify by grep and by driving it
|
||||
- [ ] a `Normal` or `High` package is unchanged - the override is no more prominent than it is today
|
||||
|
||||
**Why the history matters:** the delay-documentation use case is the business justification
|
||||
for the whole constraint workflow. If a constraint log can be shown to have been wrong, it
|
||||
stops supporting a notice of delay or a change order claim.
|
||||
@@ -161,8 +230,8 @@ They open it on a phone and need the answer without scrolling or clicking.
|
||||
|
||||
### T7.6 — CR-014: Ready for QA gate
|
||||
|
||||
- **Items:** `CR-014`
|
||||
- **Depends on:** T7.3, T4.2 (blocking dependency `X1`)
|
||||
- **Items:** `CR-014`, `D2`, `D9`, `D10`
|
||||
- **Depends on:** T7.3, T4.2 (blocking dependency `X1`), and the wave 5 SOP wizard for the `D2` field
|
||||
- **Blocks:** nothing
|
||||
- **Surface:** `server/` + `html/`
|
||||
- **Files:** status model, notification service, QA section
|
||||
@@ -183,15 +252,35 @@ reject; rejection returns the package to In Progress with a required comment.
|
||||
**Do not:** build the email with a link to the app root. That is the failure `X1` exists to
|
||||
prevent.
|
||||
|
||||
**Amended August 18 (`D2`, `D9`, `D10`).** Three answers change this task:
|
||||
|
||||
- **Who receives it.** Not "the QA rep and the QA/QC members named on the work package" -
|
||||
**the QA group, configured once during SOP setup as a dropdown of project members.** That
|
||||
makes the recipient list SOP configuration, so this task acquires a wizard field and a
|
||||
dependency on wave 5 that it did not have.
|
||||
- **Who hears about a rejection.** The **work package owner and the same distribution list**,
|
||||
not only the submitter.
|
||||
- **Where the state is visible.** The dashboard **and Field View**.
|
||||
- **Who turns email on.** An administrator, from `admin.html`. The gate is a stored setting,
|
||||
not an environment variable. It ships **off** and is verified against a capture sink; no
|
||||
real mail is sent from this branch.
|
||||
|
||||
**Done when:**
|
||||
|
||||
- [ ] the new state exists in the transition model, not beside it
|
||||
- [ ] entering it sends email to the QA rep and named QA/QC members
|
||||
- [ ] the QA distribution list is chosen in the SOP wizard from project members and persists
|
||||
- [ ] entering `Ready for QA` emails that list and nobody else
|
||||
- [ ] rejection emails the work package owner and the same list
|
||||
- [ ] the link in the email opens that specific work package, including for a signed-out recipient via login
|
||||
- [ ] a dashboard view or filter lists all packages in Ready for QA
|
||||
- [ ] Field View shows which packages are in `Ready for QA`, legibly at 390px, with something other than colour carrying the state (`D9`)
|
||||
- [ ] rejection returns to In Progress and requires a comment
|
||||
- [ ] the transition is written to history
|
||||
- [ ] email failure is logged and surfaced, not silent
|
||||
- [ ] the send path is exercised end to end against a capture sink, with the count of captured messages asserted
|
||||
- [ ] the default is off; an administrator can turn it on from `admin.html` and a non-administrator cannot (`D10`)
|
||||
- [ ] changing the setting is written to the audit log
|
||||
- [ ] no SMTP password appears anywhere outside the environment, and no customer IP appears in a message body
|
||||
|
||||
**Note:** QA currently runs off a comprehensive Excel questionnaire being migrated into
|
||||
CxAlloy. Integration with CxAlloy is explicitly out of scope. This gate is notification only.
|
||||
@@ -200,7 +289,7 @@ CxAlloy. Integration with CxAlloy is explicitly out of scope. This gate is notif
|
||||
|
||||
### T7.7 — CR-007: Upload drawings for offline access
|
||||
|
||||
- **Items:** `CR-007`
|
||||
- **Items:** `CR-007`, `D8`
|
||||
- **Depends on:** T7.2, T4.3 (blocking dependency `X8`)
|
||||
- **Blocks:** nothing
|
||||
- **Surface:** `server/` + `html/`
|
||||
@@ -221,14 +310,31 @@ Show file size limits and supported types in the UI before upload, not after fai
|
||||
**Do not:** build this before `T4.3`. Uploading into a form with no autosave risks losing
|
||||
both the upload and the surrounding work.
|
||||
|
||||
**Amended August 18 (`D8`) - the numbers.** `CR-007` says "show file size limits and supported
|
||||
types" without saying what they are. They are: **5MB a file, PDFs and images, stored in the
|
||||
same database as everything else.** Offline caching covers **only the packages assigned to
|
||||
the requesting user**, not the whole project.
|
||||
|
||||
The consequence was raised and settled rather than discovered later: files in the database
|
||||
means every encrypted backup carries them. Splitting them out was rejected - a backup that
|
||||
excludes the drawings is a backup you cannot restore from - so a **2GB per-project ceiling**
|
||||
was approved instead, with a warning at 80%.
|
||||
|
||||
**Done when:**
|
||||
|
||||
- [ ] PDF upload works and the file is retrievable
|
||||
- [ ] image upload works and the file is retrievable
|
||||
- [ ] links still work alongside uploads
|
||||
- [ ] attachments are included in export or download
|
||||
- [ ] an uploaded drawing opens on a tablet with the network disabled
|
||||
- [ ] offline caching covers the requesting user's assigned packages only; verify a package assigned to someone else is not cached
|
||||
- [ ] the description field persists and prints on the export
|
||||
- [ ] limits and supported types are stated before upload
|
||||
- [ ] a file over 5MB is refused before upload, naming the limit
|
||||
- [ ] a type outside PDF and image is refused before upload, naming the accepted types
|
||||
- [ ] a project at 80% of 2GB warns; at 2GB it refuses, naming the ceiling
|
||||
- [ ] the running project total is visible where uploads happen
|
||||
- [ ] both limits are enforced on the server, not only in the browser
|
||||
- [ ] upload failure is clear and recoverable, with no loss of surrounding form work
|
||||
- [ ] the whole flow works at 390px
|
||||
|
||||
@@ -287,11 +393,47 @@ errors is marked. Remove the creator's native dialogs.
|
||||
|
||||
---
|
||||
|
||||
### T7.10 — D5: Usage data moves to the admin console
|
||||
|
||||
- **Items:** `D5`
|
||||
- **Depends on:** T7.1
|
||||
- **Blocks:** nothing
|
||||
- **Surface:** `html/`
|
||||
- **Files:** `admin.html`, `admin.js`, `wp-creation-app.js`, `work-package-suite-app.js`
|
||||
|
||||
**Problem:** Usage analytics exists **twice**. `creator-frame.md` section 2b counts five of
|
||||
the nine colliding script globals as this one feature - `ANALYTICS_KEY`, `analyticsLoad`,
|
||||
`analyticsSave`, `downloadAnalytics`, `showAnalytics` - and records that the wizard's copy has
|
||||
no caller, because the button that opens it lives on the creator. Once the frame is gone, two
|
||||
implementations sit in one document.
|
||||
|
||||
**Do:** Keep one implementation and put its entry point in the admin console, where an
|
||||
operator-facing report belongs. Remove the analytics control from the creator and from the
|
||||
wizard. This is not a rewrite of what analytics collects - the same data, reached from one
|
||||
place instead of a button on a package-authoring screen.
|
||||
|
||||
**Do not:** change what is tracked, and do not leave the second implementation behind
|
||||
unreferenced. An unreferenced duplicate is what produced this item.
|
||||
|
||||
**Done when:**
|
||||
|
||||
- [ ] usage data is reachable from `admin.html`
|
||||
- [ ] no analytics control remains on the creator or the wizard; grep confirms
|
||||
- [ ] exactly one implementation of `analyticsLoad`/`analyticsSave`/`downloadAnalytics` survives; grep confirms
|
||||
- [ ] the data recorded before this task is still readable after it
|
||||
- [ ] the console entry point is behind the same role check as the rest of `admin.html`
|
||||
- [ ] the report is usable at 390px
|
||||
|
||||
---
|
||||
|
||||
## Wave 7 exit criteria
|
||||
|
||||
- [ ] no iframe; `F4` resolved structurally
|
||||
- [ ] `CR-015` fixed with a regression test and a stated root cause
|
||||
- [ ] hold state is derived, and history records every transition
|
||||
- [ ] the QA gate emails a working deep link
|
||||
- [ ] drawings upload and open offline on a tablet
|
||||
- [ ] the QA gate emails a working deep link, to the SOP-configured list, with the gate off by default
|
||||
- [ ] drawings upload and open offline on a tablet, inside the 5MB and 2GB limits
|
||||
- [ ] creator native dialog count is 0
|
||||
- [ ] the creator is a page: app bar, side navigation, collapsible sections, focus rings, at rest under two screen heights
|
||||
- [ ] `D1` through `D5`, `D8`, `D9` and `D10` are each satisfied or explicitly carried with a reason
|
||||
- [ ] no real email left this branch; the capture sink count is recorded
|
||||
|
||||
Reference in New Issue
Block a user