457711bd78
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.
149 lines
7.1 KiB
Markdown
149 lines
7.1 KiB
Markdown
# 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:
|
||
|
||
1. **`docs/TECH-SPEC-PIPELINE.md`** — deterministic math, image prep, constants, test vectors
|
||
2. **`docs/ARCHITECTURE.md`** — hybrid topology, what-runs-where, secrets, status machine
|
||
3. This **`AGENTS.md`** — hard rules for agents
|
||
4. **`docs/DATA-MODEL.md`**, **`docs/OPENAPI.md`**, **`docs/CONTENT-WOO.md`**, **`docs/PROMPTS.md`**, **`docs/DEPLOYMENT.md`**
|
||
5. **`docs/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)
|
||
6. **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 `$/bdft` from 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_KEY` env 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`**, default **`draft`**
|
||
- 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 `draft` with **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 `.201` by default.
|