Files
SlabUploader/.planning/milestones/v0.5/M4/tasks.md
T
Ty 6fb92362a4 docs(m4): M4 goals + task breakdown
Goals: polish M3 + #99 tape-line, human-driven taxonomy review
(thumb-first UI, Call 1 deferred), Call 2 inference refinement,
real SLAB-UAT-* Woo draft exit.

Tasks: 9-task / 5-phase breakdown with detail bar (skills, starting
point, verification, sequence, stop condition, evidence boundary per
task). Kickoff decisions folded in: full polish wave (#91-#100 minus
#96), tape-line confined to calibration step, single-slab multi-photo
exit walk.
2026-09-24 13:44:53 -07:00

189 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# M4 Task Breakdown
Companion to `goals.md` (accepted direction). Detail bar per task: goal, skills,
starting point, verification, sequence, stop condition, evidence boundary.
Phase order: P0 (requirements first) → P1 (G1 polish + #99, parallel-safe) → P2 (G2
review-UI, wireframe-gated) → P3 (G3 Call 2) → P4 (G4 exit walk). Ty owns every gate
exit (QUALITY-30); agents record raw evidence, never declare green.
---
## P0 — Requirements baseline (must land before code it enables)
### T1. Requirements delta for M4
- **Goal:** G2/G4 (unblocks G3). **IDs:** REQS (whole doc), REQS-30. **Issues:** —.
- **Skills:** `document-to-action-items` (extract obligations), `ocr-and-documents`
(read current REQUIREMENTS.md), OMH `omh-routing` (evidence boundaries).
- **Starting point:** `docs/REQUIREMENTS.md` (current), `goals.md` requirements-delta
section.
- **Work:** add rows for the human-pick flow (REVIEW-*, CAPTURE-*, METADATA-*), the
Call 2 taxonomy-input row, and the `SLAB-UAT-*` exit-walk row; note the Call 1
deferral (METADATA-40/45/55) and drop #96; keep the "draft only" PUBLISH-40 invariant;
confirm #99 is tracked. Every new/changed row is the gate for the code that implements it.
- **Verification:** `python tools/check_requirements.py` exit 0; coverage matrix
consistent.
- **Sequence:** first task of the sprint.
- **Stop:** rows merged + gate green. **Evidence:** runner output.
### T2. #99 tape-line calibration (folded into G1)
- **Goal:** G1. **IDs:** CAPTURE (dimensions), REQS-50. **Issues:** #99.
- **Skills:** `systematic-debugging` (verify the prototype assumption),
`wireframe-review-iteration` (reference the overlay interaction), `svelte-core-bestpractices`.
- **Starting point:** `frontend/src/capture/TapePrototype.svelte` + `?tape-prototype`
sandbox on the `m4` branch; `docs/design/issue-99-tape-line-overlay.html` (approved
wireframe); `frontend/src/png/crop.ts` (projection logic).
- **Work:** promote the prototype to the shipped calibration path (owner drags both
ticks), adopt the as-built length model (maskSpanAlong projection), delete the
sandbox + query-param gating, keep `crop_fill` (already landed in 818874e).
**Scope (Ty confirmed):** confined to the calibration step — the photos-ready
lineup (CAPTURE-130) stays as-is; #99 does not touch it.
- **Verification:** unit tests in `frontend/src/png/*` (tape geometry), `tsc --noEmit`,
manual calibration on one slab at 375px.
- **Sequence:** parallel with T3–T5; no dependency on T1.
- **Stop:** prototype shipped, `?tape-prototype` removed, tests green.
**Evidence:** test output + a 375px capture of the calibration drag.
---
## P1 — M3 polish (G1), parallel-safe once T1 lands
### T3. Polish wave (full set #91–#100)
- **Goal:** G1. **IDs:** UX (various). **Issues:** all of #91–#100 — #91 (photo-picker
look/feel), #92 (photo filenames on submit), #93 (capture gated on tested Woo
connection), #94 (review layout), #97 (settings), #98 (publish), #100 (UX general).
**Excluded:** #96 (drops with Call 1). Ty confirmed: full polish wave, no triage.
- **Skills:** `svelte-core-bestpractices`, `omh-frontend` (component states),
`omh-visual-qa` (rendered evidence per screen).
- **Starting point:** the live screens named in each issue; `frontend/src/create/*`.
- **Work:** per-issue fixes. Each is a small, individually-verifiable unit; sequence
by dependency (e.g. #93 gate before #98 publish flow touches it).
- **Verification:** per-issue acceptance (capture at 375/768/1280, or the named
behavior), full suite green.
- **Sequence:** after T1; independent of T2.
- **Stop:** each issue's acceptance captured. **Evidence:** captures + test run.
---
## P2 — Human-driven taxonomy review + thumb-first UI (G2)
### T4. Wireframe (design gate)
- **Goal:** G2. **IDs:** REVIEW-*, UX (phone). **Issues:** #100 (UX).
- **Skills:** `sketch` (variants) + `wireframe-review-iteration` (paradigms, serve on
LAN IP, iterate on Ty's feedback) → `omh-frontend` + `omh-design-quality-gate`
(lock the chosen variant).
- **Starting point:** `docs/design/issue-99-tape-line-overlay.html` (approved overlay
wireframe, 2026-09-24) for the visual language + the interaction model.
- **Work:** 2–3 HTML variants of the thumb-first review flow. Standing paradigms:
*no tap-bubble chip clouds for long lists → collapsible searchable checklist*;
leftmost-kept-is-primary for wood (primary + optional secondaries); AI-assist
labeled as "suggested, confirm"; every metadata requirement present (primary
wood-category required, secondaries optional).
- **Verification:** Ty reviews the served variants and accepts one (375/768/1280).
- **Sequence:** before T5/T6. **Stop:** Ty accepts a variant.
**Evidence:** the accepted `docs/design/*` file + Ty's acceptance.
### T5. Review-UI implementation
- **Goal:** G2. **IDs:** REVIEW-*, CAPTURE-*. **Issues:** #100.
- **Skills:** `svelte-core-bestpractices`, `svelte-code-writer` (Svelte 5 lookups),
`omh-frontend`, `omh-visual-qa`, `omh-accessibility-audit` (keyboard, 44px targets,
contrast, 320px reflow).
- **Starting point:** accepted T4 wireframe; `frontend/src/create/review/Review.svelte`
(current single-column form); the M3 `MultiSelect.svelte` pattern (reused, not the
tap-bubble pattern).
- **Work:** replace the review form with the accepted thumb-first flow; primary
wood-category + optional secondaries; remove the "Suggest with AI" bar (#96 drops
with Call 1); keep all metadata requirements present and editable.
- **Verification:** `tsc --noEmit`; `omh-visual-qa` at 375/768/1280 (PASS);
`omh-accessibility-audit` (keyboard-reachable, 44px, contrast, 320px reflow);
full suite green with inference on **and** off (QUALITY-20).
- **Sequence:** after T4 accepted. **Stop:** flow renders, all requirements present,
audits pass. **Evidence:** captures + audit output.
### T6. Taxonomy → title/shortdesc (server-side)
- **Goal:** G2. **IDs:** METADATA-*. **Issues:** —.
- **Skills:** `systematic-debugging` (verify the title/shortdesc builders),
`evidence-based-code-review`.
- **Starting point:** the title/short description builders in `backend/` (review.py /
publish.py path); the new human-pick fields from T5.
- **Work:** ensure title + short description are built from the human-picked primary
wood + form (not from the removed Call 1). Confirm the server_description
(inference-off) path stays intact.
- **Verification:** unit tests for title/shortdesc from human picks; inference-off
path covered. **Sequence:** with/after T5. **Stop:** tests green.
**Evidence:** test output.
---
## P3 — Refine Call 2 long description (G3)
### T7. Wire human-picked taxonomy into the Call 2 prompt
- **Goal:** G3. **IDs:** METADATA-*. **Issues:** —.
- **Skills:** `systematic-debugging`, `evidence-based-code-review`,
`local-llm-benchmarking` (endpoint behavior), `omh-ask` (prompt-engineering consult
if the owner wants an external pass).
- **Starting point:** `backend/inference.py` `call2` (line 467) — the prompt today is
the **dimension fact block + brand voice + geo only; taxonomy is NOT in the prompt**.
`CALL2_SEED` (line 112), `_active_prompt`, `brand_voice`/`geo_context` settings.
- **Work:** add the human-picked primary/secondary wood + form to the Call 2 fact
block so the long description is grounded in what the owner picked; keep the
"invent no numbers" constraint; keep the dimension block exact.
- **Verification:** `test_inference.py` updated for the new input; a recorded call2
with a known taxonomy set shows the wood/form in the output. **Sequence:** after T5
(needs the human-pick data shape). **Stop:** test passes + sample output grounded.
**Evidence:** test output + a sample Call 2 response.
### T8. Exit-walk quality gate
- **Goal:** G3. **IDs:** QUALITY-105/110. **Issues:** —.
- **Skills:** `omh-verification-gate` (record the gate), `omh-visual-qa`.
- **Starting point:** `deploy/uat_walk.sh`; the refined Call 2 from T7.
- **Work:** Ty reads the Call 2 long description on the exit walk for 2–3 real slabs;
pass = "sounds like a good product description." This is the only proof that counts
for the Call 2 quality claim.
- **Verification:** Ty's judgment on 2–3 outputs, recorded. **Sequence:** after T7.
**Stop:** Ty passes the gate. **Evidence:** Ty's recorded judgment.
---
## P4 — Exit: real Woo draft (G4)
### T9. `SLAB-UAT-*` draft submission + walk
- **Goal:** G4. **IDs:** PUBLISH-*, QUALITY-105/110. **Issues:** —.
- **Skills:** `omh-deploy-and-monitor` (release checklist + monitor),
`omh-verification-gate`, `docker-uat-deploy` (if the UAT host needs staging).
- **Starting point:** `backend/publish.py` (draft create path), the Woo mock
(`test_integration_woo_mock.py`) for the PUBLISH-5 sequence, `deploy/uat_walk.sh`.
- **Work:** run the full create → review (human pick) → Call 2 → publish path on the
real store, producing **one** `SLAB-UAT-*` draft; walk it (draft only, PUBLISH-40);
confirm the draft matches the ready set. **Shape (Ty confirmed):** single slab, and
the draft carries **multiple photos** of that slab — not a QUALITY-110 pair.
- **Verification:** `deploy/uat_walk.sh` on the real store; draft present in Woo with
the correct fields — including **multiple photos** on the single `SLAB-UAT-*` draft;
full suite green inference on **and** off (QUALITY-20).
- **Sequence:** last; after T3–T8. **Stop:** real draft matches the ready set + Ty
passes the walk. **Evidence:** store screenshot + walk transcript + suite output.
---
## Dependency map
```
T1 ──┬─ T3 (polish)
├─ T4 ─ T5 ─┬─ T6
│ └─ T7 ─ T8 ─ T9
└─ T2 (tape-line, parallel)
T9 is the milestone exit.
```
- T2 is independent of T1 (prototype already on `m4`).
- T4 must be accepted before T5.
- T7 needs T5's data shape; T8/T9 need T7.
- Nothing in P2/P3 blocks T2/T3 (polish + tape-line ship independently).
## Resolved at kickoff (deep-interview, 2026-09-24)
- **Polish scope:** full wave — all of #91–#100, no triage (only #96 drops with Call 1).
- **Tape-line scope:** confined to the calibration step; photos-ready lineup
(CAPTURE-130) untouched.
- **Exit-walk shape:** single slab; the `SLAB-UAT-*` draft carries multiple photos of
that slab (not a QUALITY-110 pair).