12 KiB
12 KiB
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), OMHomh-routing(evidence boundaries). - Starting point:
docs/REQUIREMENTS.md(current),goals.mdrequirements-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.pyexit 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) — AS-BUILT, shipped
- Goal: G1. IDs: CAPTURE-170, CAPTURE-175, CAPTURE-75. Issues: #99 (issue body still describes the superseded draggable-tick model — this entry is the as-built).
- Skills:
systematic-debugging,svelte-core-bestpractices,docker-uat-deploy(isolate-and-verify the review preview). - As-built: a fixed black centre line with two end ticks, drawn on the stage
fixture. The line is never an owner input — not draggable, not focusable, not
keyboard-nudgeable, and not part of the published pose. The source photo/slab is the
only thing that moves: drag to pan, wheel/pinch to zoom, the ↻ handle or arrow keys
(Shift = fine step) to tilt. The owner aligns the slab to the fixed line at the place
the tape measurement was taken. Typed Length is the real inches read off the tape, and
the fixed line represents that same length. Scale = fixed-line pixel span / declared
Length;
maskSpanAlongis not the scale source. The crop slider is the sole control of the line ends:crop_fill=90puts each end 5% from its corresponding edge. Calibration rotation applies to the calibration clean PNG + overlay only; batch siblings stay unrotated. - Superseded (do not restore): draggable ticks;
TapePrototype.svelteand the?tape-prototypesandbox (both deleted);frontend/src/png/crop.ts(removed in6000ac2— crop geometry now lives infrontend/src/capture/tapeLine.tscropEnds(fillPercent)); thesveltedragdependency (404s on npm, never added). The wireframedocs/design/issue-99-tape-line-overlay.htmllives on branchissue-99-tape-line-overlay(63b8879), not onm4. - Verification: unit tests in
frontend/src/capture/tapeLine.test.ts(ends fixed by the crop slider, never an owner input) +frontend/src/png/{inventory,overlay}.test.ts(calibration rotation reaches the calibration PNG/overlay only);tsc --noEmit;npm run build; e2efrontend/tests/e2e/tape-fixed-line.spec.ts(no tick drag; a tick drag behaves identically to a pan; ends follow the crop slider). - Sequence: parallel with T3–T5; no dependency on T1.
- Stop: SHIPPED. UAT-signed off by Ty 2026-09-25 on the M4 review preview
(
http://192.168.1.202:10883/?noload=1, builda756cf5, branchm4). - Evidence:
npm test102/102; requirements + coverage gates green; live e2e on the deployed preview (0°/20° rotation produces differing clean PNG + overlay bytes); render gate clean at 1440/768/375 with no overflow or clipped text; Ty's UAT sign-off. Not covered:svelte-checkstill reports its known 42-error baseline.
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); no AI-assist surface (Call 1 decommissioned); 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 M3MultiSelect.sveltepattern (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-qaat 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.pycall2(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_contextsettings. - 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.pyupdated 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.shon the real store; draft present in Woo with the correct fields — including multiple photos on the singleSLAB-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).