Files
SlabUploader/AGENTS.md
T
grokbot_ty 369d404c29 docs: env-agnostic deploy (APP_HOSTNAME, inventory, Caddy order)
DEPLOYMENT is host-variable: APP_HOST/APP_HOSTNAME/ports, inventory
worksheet, corrected Caddy handle /api/* before frontend. Drop RemBG
and output_px 1000 as deploy SoT. AGENTS §9, README, IMPL host wording
match. Historical .201 lab is a non-normative callout only.
2026-09-01 05:26:45 +00:00

152 lines
7.6 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 and rewritten Gate C / Phase 1–2 / Phase 6 sections are authoritative. Implement only Phase 0 plus sections marked rewritten. Do not implement deferred stubs (offline PWA, OCR, ruler) or any leftover server happy-path pipeline language.
6. **PRD / README** — product intent only; do **not** implement lines that contradict TECH-SPEC, ARCHITECTURE, or this file
Known stale / do-not-implement without rewrite:
- PRD FR17 “Tags: fig-* only” → **wrong**. Locked model is `fig-*` (1+) + `feat-*` (0+). See DATA-MODEL.
- PRD FR19 / overview “species and wood category” pricing → **wrong**. Species `$/bdft` only. Category-weighted pricing is deferred (v1.5).
- PRD FR40 “server-side processing” and NFR “server normalization” → **wrong**. Client owns happy-path measure/crop; server stores drafts and runs U2Net on demand only.
- PRD FR42 / deploy bullets hard-coding `.201` → superseded by env-agnostic DEPLOYMENT (inventory + `APP_HOSTNAME`).
- Older “creds client-side” decision → **wrong**. Server AES-GCM only; never browser storage for secrets (PRD D15 already corrected; keep this lock).
- PRD / README offline-first PWA / OCR / ruler → superseded by hybrid + online-only MVP.
- CONTENT-WOO / DEPLOYMENT older “pending” create default → 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 through TV-10** (including TV-10 Rounding). Client (or shared pure modules the client uses) is authoritative for math; server **stores** client-sent numbers — does not recompute as SoT. Depth: `docs/TECH-SPEC-PIPELINE.md`.
---
## 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: inventoried Docker host. Docker Compose (`frontend` + `fastapi`) + Caddy → `https://${APP_HOSTNAME}` (LAN/Tailscale).
- Fill `deploy/INVENTORY.md` before binding ports or merging Caddy (co-resident apps can collide; bolt.diy is one example).
- Health: `GET https://${APP_HOSTNAME}/api/health`.
- Inference is a remote configurable endpoint, not on the app host by default.
- Historical lab IP/hostname examples in older notes are non-normative.