Files
SlabUploader/AGENTS.md
T
Dev Manager 457711bd78 docs: Gate A freeze — AGENTS.md + hybrid Phase 0
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.
2026-09-01 03:59:07 +00:00

149 lines
7.1 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.
# 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.