# 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).