Lock hybrid topology, Woo draft+SLAB-UAT-* UAT firebreak, client-authoritative TECH-SPEC math, and sequenced inference after Gate C. Supersede obsolete server-pipeline Phase 0 and flag Phase 2 offline/OCR/ruler as out of POC scope.
7.1 KiB
AGENTS.md — SlabUploader
Working contract for coding agents. Read before writing code.
Status: Gate A freeze · signed 2026-08-31 PT · SoT: Gitea Ty_Tech/SlabUploader on gitea-atd (not mirrors).
0. Doc precedence (hard)
When docs disagree, use this order until stale docs are rewritten:
docs/TECH-SPEC-PIPELINE.md— deterministic math, image prep, constants, test vectorsdocs/ARCHITECTURE.md— hybrid topology, what-runs-where, secrets, status machine- This
AGENTS.md— hard rules for agents docs/DATA-MODEL.md,docs/OPENAPI.md,docs/CONTENT-WOO.md,docs/PROMPTS.md,docs/DEPLOYMENT.mddocs/IMPL-PLAN.md— Phase 0 hybrid rewrite is authoritative; Phases 1+ TBD rewrite — do not implement old Phase 0–2 (server happy-path pipeline, offline PWA, OCR, ruler)- PRD / README — product intent only; do not implement lines that contradict TECH-SPEC or ARCHITECTURE
Known stale / do-not-implement without rewrite:
- PRD FR4
bdft = sqft × thickness / 12→ wrong. TECH-SPEC:bdft = sqft × thickness_in(no/12). - PRD decision 15 “creds client-side” → wrong. Server AES-GCM only; never browser storage for secrets.
- PRD / README “server does normalization / offline-first PWA / OCR / ruler” → superseded by hybrid + online-only MVP.
- IMPL-PLAN Phase 0–2 text that describes server
pipeline/CLI, ruler, offline PWA, Tesseract, OpenCV.js ruler → obsolete (Phase 0 rewritten 2026-08-31). - CONTENT-WOO / DEPLOYMENT smoke “pending” as default create → superseded: UAT uses Woo draft +
SLAB-UAT-*.
1. Topology (locked — hybrid)
Client (SvelteKit) owns the happy path:
- Capture 1–5 photos
- Sheet detect + chroma-key / black threshold + sliders (sensitivity, edge offset, feather)
- Mask overlay + user confirm before measurement
- Length axis overlay (rotate / confirm)
- sqft, bdft, 6" width samples
- 3:4 transparent PNG, 80% fill at extremes, shorter side ≥ 1600 when source allows
- Draft payload: originals + processed PNGs + length/thickness/SKU/sqft/bdft/widths
Server (FastAPI) owns:
- Store drafts / settings / taxonomy cache
- U2Net on demand only (“Try harder” / coverage failure) — one photo in, mask out; sliders still apply on client
- WooCommerce (taxonomy sync, SKU check, create product) — browser never calls Woo
- Inference proxy (Call 1 / Call 2) — keys never in browser
- Prompt files (server text files, read fresh)
Happy path never leaves the phone until the user continues after confirmed mask + numbers.
2. What NOT to build (early phases / MVP)
| Deferred / killed for early phases | Notes |
|---|---|
| Offline capture / PWA / IndexedDB sync | Online-only MVP |
| OCR (SKU) | Manual SKU entry |
| Ruler detection / OpenCV on client for scale | Manual length; scale = longest_axis_px / L |
| Server-side happy-path pipeline | No server chroma-key / crop / bdft math as SoT |
| Fake upscale / inventing pixels | Warn + retake if < 1600 after crop |
| LoRA / fine-tune | Deferred |
| Figure-/category-weighted pricing | v1.5 |
| Auto-dimension overlay | v1.5 |
| Bulk publish, staff roles, analytics, SKU update path | Non-goals |
3. Deterministic core (non-negotiable)
Encode TECH-SPEC exactly:
- bdft = sqft × thickness_in (identity: 1 sqft @ 1" = 1 bdft). No
/12. - Units: inches in 1/8" steps; sqft/bdft 2 decimals; price half-up 2 decimals.
- Manual length, thickness, SKU, price always win.
- Image prep: sheet/sliders → mask confirm → length axis confirm → 3:4 PNG / 80% fill / ≥1600px when source allows.
- No inventing pixels. No fake upscale. Undersized source → warn + retake; photo not publishable until retake.
- Pricing: species
$/bdftfrom Settings, seeded by Woo species sync;rec = bdft × price_per_bdft; user override sticks; missing rule → empty rec, manual allowed. - Port TECH-SPEC TV-1…TV-9 (TV-10 only after TECH-SPEC defines it). Client (or shared pure modules the client uses) is authoritative for math; server stores client-sent numbers — does not recompute as SoT.
4. Secrets & settings
Never in browser storage / JS bundles:
- Woo consumer key + secret
- Inference base URL + API key
- AES master key (
SLAB_AES_KEYenv only; never in DB or repo)
Server: AES-GCM at rest in SQLite for Woo + inference secrets. Settings UI POSTs to FastAPI; server encrypts. All Woo and inference calls are server-side.
Browser may persist (non-secret): sheet mode, sensitivity, edge offset, feather (localStorage OK; reset-to-default required).
5. Woo UAT & create status (Ty locked 2026-08-31)
- Store: PROD
www.whidbeywoodstore.com - Mid-phase UAT creates: Woo status draft, SKU prefix
SLAB-UAT-* - Settings field
woo_create_status:draft | publish, defaultdraft - Hard rule: if SKU matches
SLAB-UAT-*, force Woo draft even if Settings say publish - Final POC success: one real (non-UAT) SKU → Woo publish only after Ty review
- Duplicate SKU → stop, surface error; no edit-same-SKU in MVP
- After successful publish: purge originals + processed images on server
- Do not conflate with slab lifecycle status (below)
6. Inference (inside POC, sequenced)
- Feature-flagged; full suite must pass with inference OFF.
- Gate C claimable path: inference OFF; manual taxonomy + deterministic numbers + Woo draft path.
- Call 1 (vision) / Call 2 (text) only after Gate C is green, still inside overall POC before “done” — not post-POC.
- Call 1 auto only if
inference_enabled; Call 2 never auto-fires (user taps Generate text). - LoRA deferred. No numeric/dimension invention by LLM; templates inject deterministic numbers.
7. Slab status machine (app-internal only)
draft → calibrated → ready → publishing → published (or failed with detail).
- calibrated: mask + axis confirmed; length/thickness/SKU entered; client computed sqft/bdft/widths; draft uploaded.
- ready: mandatory fields filled (manual and/or Call 1); inference optional.
- Inference does not gate publish.
- Never confuse slab
draftwith Woo draft (woo_create_status).
8. Test & delivery expectations
- No feature without a passing test and shown execution output (PR/commit message).
- Deterministic core unit-tested before UI consumes it.
- One phase = reviewable, shippable increment; Ty exit-gates phases.
- Phase naming: Phase 0–6 stay delivery chapters. Phase 0 = Gates A+B. Gate C = early Phase 1 claimable publish slice.
- Do not write secrets, real Woo keys, or AES keys into the repo.
- Prefer fixing docs when code and locked decisions diverge — do not silently reintroduce
/12, offline, ruler, or server happy-path pipeline.
9. Deploy sketch (see DEPLOYMENT.md)
- Target:
.201, Docker Compose (frontend+fastapi) + Caddy →slab.tyubumini.local(LAN/Tailscale). - Inventory host ports/Caddy before binding (bolt.diy collision risk).
- Health:
GET /api/health. - Inference is a remote configurable endpoint, not on
.201by default.