diff --git a/AGENTS.md b/AGENTS.md index 6c96349..084b2a6 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -89,13 +89,11 @@ Depth: `docs/ARCHITECTURE.md`. --- -## 2. Deferred and out of scope +## 2. Deferred work -The MVP is online-only, manual SKU entry, manual length (scale = longest_axis_px / L), and client-side measure/crop as source of truth. No server happy-path pipeline. No fake upscale; undersized source warns and requires retake. +The MVP is online-only. Measuring lives in the browser. Manual SKU entry, manual length, and client-side measure/crop are the source of truth. Undersized source warns and requires retake. The server stores client-sent numbers; there is no server happy-path pipeline for the deterministic core. -Full deferred inventory: `docs/ARCHITECTURE.md` §4 and `docs/IMPL-PLAN.md` Phase 2 (offline PWA, OCR, ruler). Phase 2 is a deferred stub only — do not implement. - -Post-POC items: LoRA / fine-tune, figure-/category-weighted pricing (v1.5), auto-dimension overlay (v1.5), bulk publish, staff roles, analytics, SKU update path. +Phase 2 is a deferred stub for offline PWA, OCR, and ruler detection. Post-POC items: LoRA / fine-tune, figure-/category-weighted pricing (v1.5), auto-dimension overlay (v1.5), bulk publish, staff roles, analytics, SKU update path. Depth: `docs/ARCHITECTURE.md` §4 and `docs/IMPL-PLAN.md` Phase 2. --- diff --git a/deploy/INVENTORY.md b/deploy/INVENTORY.md index eb4d0da..7234871 100644 --- a/deploy/INVENTORY.md +++ b/deploy/INVENTORY.md @@ -1,7 +1,7 @@ # Deploy inventory worksheet Fill this at **Gate B** on the designated host before any port bind or Caddy merge. -Do not assume a prior lab IP or hostname. See `docs/DEPLOYMENT.md`. +The host must be inventoried before any deployment. See `docs/DEPLOYMENT.md`. ## Host diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md index 206fb00..90a2ad4 100644 --- a/docs/ARCHITECTURE.md +++ b/docs/ARCHITECTURE.md @@ -79,7 +79,7 @@ flowchart TB ## 3. Clarifications 1. **Happy path** stays on the phone through PNG + numbers. FastAPI is idle until the user has a confirmed mask. -2. **Mask knobs** live on capture; each change re-runs client BG removal. Server U2Net “Try harder” is deferred from POC (keep the one-photo contract; do not ship the control). +2. **Mask knobs** live on capture; each change re-runs client BG removal. Server U2Net “Try harder” is deferred from POC. The one-photo contract stays in the architecture; the control is not shipped until post-POC. 3. **Draft upload** sends **originals + processed PNGs + length/thickness/SKU/sqft/bdft/widths**. Originals are needed if Call 1 or a later retry must not depend on the tab still being open. After successful Woo publish, server deletes both. 4. **Call 1** is server-side so the vision key never sits in the browser. Auto-run on slab create **only if** `inference_enabled` is true. If disabled, Call 1 @@ -192,7 +192,7 @@ hash changes, including deletions). - Client reads the anchor. If it advanced past the client's last value, re-pull the **full** taxonomy cache. One timestamp governs categories, attributes, and tags together. -- Do not invent a Woo-side taxonomy timestamp or a per-table anchor. +- `taxonomy_anchor` is app-managed; no Woo-side timestamp or per-table anchor is used. **Triggers** @@ -223,7 +223,7 @@ Two consumers: review UI and Call 2 prompt builder. Client caches the module. Providers differ. Default portable path: **resend the full Call 1 turn** (prompt + images metadata + assistant JSON) with Call 2. Opt into `previous_response_id` only after probe. `POST /api/v1/settings/test-inference` two-turn probe records `stateful | stateless | fail`. -**Fail blocks Call 2 enablement only** (Gate C inference-OFF still works). Never require `previous_response_id`. Do not ship a Call 2 that silently drops Call 1 context. +**Fail blocks Call 2 enablement only** (Gate C inference-OFF still works). Call 2 always carries the full Call 1 context; `previous_response_id` is optional after probe. Per-slab thread on the **server** (client does not hold provider IDs). Best-effort delete on publish / abandon / fail; log and continue. diff --git a/docs/CONTENT-WOO.md b/docs/CONTENT-WOO.md index 991492a..263fb44 100644 --- a/docs/CONTENT-WOO.md +++ b/docs/CONTENT-WOO.md @@ -54,7 +54,7 @@ and the final stored content. - Auth is **WordPress Application Passwords**, not WooCommerce consumer keys (`ck_`/`cs_`) and not the user's login password. - Create a **dedicated low-privilege WordPress user** (shop manager, or a custom - role with product create/edit + media upload). Do not reuse an admin account. + role with product create/edit + media upload). A dedicated low-privilege user, not the admin account, is used. - Generate the application password under **Users → Profile → Application Passwords**. WordPress requires **HTTPS** for that UI; the store must already be on TLS (Caddy enforces HTTPS on the app side too). @@ -81,12 +81,12 @@ cache retained (never delete-then-fail). **Manufactured stamps.** Woo REST has **no** usable last-modified on categories, attributes, or tags. FastAPI persists `taxonomy_last_sync_at` (every successful pull) and `taxonomy_anchor` (bump only when stored-subset hash changes, including -deletions). Client re-pulls the full taxonomy iff the anchor advanced. Do not -invent a Woo-side taxonomy timestamp. Do not sync per navigation. +deletions). Client re-pulls the full taxonomy iff the anchor advanced. No Woo-side +taxonomy timestamp; no per-navigation sync. **Triggers:** (1) successful `test-woo` **always** resyncs; (2) publish if `now - taxonomy_last_sync_at > 1 hour` then reconcile (bump only on real change); -(3) optional app launch / Settings refresh. If a picked id vanished after a refresh, show that field as no longer valid. Do not silently swap it. +(3) optional app launch / Settings refresh. If a picked id vanished after a refresh, show that field as no longer valid. The selection is not silently swapped. **Species exclusivity.** UI pickers, pricing seeds, and Call 1 species lists are **exactly** the synced species-category leaves. No hardcoded, invented, or fallback @@ -104,7 +104,7 @@ the submit list. Review will not continue until the full ready set is filled: SKU, length, thickness, price, species, wood category, edge type, figure, grade, thickness band, moisture, fig-* tags, and inventory PNG(s). Species plus one figure is not enough. Presentation: `docs/UX.md`. -Do not fill a low-confidence guess. +Low-confidence guesses are not filled. Names from vision or from typing match store ids case-insensitive, trimmed. No match leaves the field empty so they can pick from the list. The store will still @@ -113,10 +113,10 @@ reject a missing required field at publish. Field rules: - **Categories**: species leaf (1 required) plus wood-category leaf ids (1+). -- **Tags**: `fig-*` (1+ required) and `feat-*` (0+). Do not invent generic - character or species product tags. Woo is authoritative for tag definitions. +- **Tags**: `fig-*` (1+ required) and `feat-*` (0+). Only documented + character or species product tags are used. Woo is authoritative for tag definitions. - **Attributes**: the five locked Woo attributes only — Edge Type, Figure, Grade, - Thickness, Moisture — using term ids from the cache. Do not publish species, + Thickness, Moisture — using term ids from the cache. Species, character, length, or free-text thickness as product attributes. Missing attributes are skipped, not created (v1: no attribute creation). @@ -148,13 +148,13 @@ Vision only suggests. It never blocks publish. With vision off, everything is ty For reliability the server: 1. For each customer-facing inventory photo in `seq` order (processed transparent PNGs from the client TECH-SPEC path): `POST /media` with the **PNG bytes** → get attachment - `source_url`. Woo accepts `image/*`; keep alpha. Do not re-encode to JPEG and drop alpha. + `source_url`. Woo accepts `image/*`; keep alpha. JPEG re-encoding drops alpha and must not happen. 2. Reference those `source_url` values in `images` (≤5 inventory photos). 3. Only `kind=inventory` photos. Calibration photos do not exist in this design. **Status** comes from Settings `woo_create_status` (`draft` or `publish`, default `draft`). Practice SKUs `SLAB-UAT-*` are always created as drafts, even if Settings -say publish. Do not edit an existing SKU in this version. After a successful create, +say publish. Existing SKUs are not edited in this version. After a successful create, the server deletes the original and processed photos. A slab marked published in the app means the store create succeeded. That is not the same as WooCommerce "publish." The force-draft rule is in `AGENTS.md`. This file only owns the payload and the steps. diff --git a/docs/DATA-MODEL.md b/docs/DATA-MODEL.md index 989b78a..487db5e 100644 --- a/docs/DATA-MODEL.md +++ b/docs/DATA-MODEL.md @@ -190,9 +190,9 @@ Keys (server settings; secrets encrypted at rest): - `aspect_ratio` ('3:4'), `output_px` (1600), `output_px_min` (1600), `fill_target` (0.80) -Sheet/slider prefs (`sheet_mode`, sensitivity, edge offset, feather) are **not** server -settings keys in POC. Client localStorage is source of truth (AGENTS §4 / ARCHITECTURE §5). -Optional server sync of those prefs is out of scope for POC. +Sheet/slider prefs (`sheet_mode`, sensitivity, edge offset, feather) persist in client +localStorage only. Client localStorage is source of truth (AGENTS §4 / ARCHITECTURE §5). +Server sync of these prefs is deferred post-POC. **Prompt files** — not in the settings table. Shipped as text files in `backend/app/prompts/` (repo), bind-mounted read-only to `/app/prompts/` in the diff --git a/docs/DEPLOYMENT.md b/docs/DEPLOYMENT.md index 055333c..daf9655 100644 --- a/docs/DEPLOYMENT.md +++ b/docs/DEPLOYMENT.md @@ -6,15 +6,15 @@ Status: SPEC · env-agnostic · 2026-09-01 · SlabUploader Variables: `APP_HOST`, `APP_HOSTNAME`, `FRONTEND_PORT`, `FASTAPI_PORT`. Health URL: `https://${APP_HOSTNAME}/api/health`. -> Gate A freeze (2026-08-31): hybrid client owns measure/crop SoT. Do not scaffold a +> Gate A freeze (2026-08-31): hybrid client owns measure/crop SoT. Server-side measure/crop scaffolding is not done. > server ruler/pipeline as authoritative. Woo UAT = draft + `SLAB-UAT-*` on PROD. > Inference is **not** on the app host by default. It is a remote configurable endpoint. **Historical lab example (non-normative):** TyUBUMini at `192.168.1.201` with hostname -`slab.tyubumini.local` was one early candidate. Do not treat that IP or name as SoT. +`slab.tyubumini.local` was one early candidate. The inventory worksheet determines the host. Use the inventory worksheet. -## 1. Host inventory (do first — do not assume) +## 1. Host inventory (required before deployment) Before deploying, fill `deploy/INVENTORY.md` (hard rule: inventory before execute): @@ -128,7 +128,7 @@ catch-all. Put `handle /api/*` **before** the frontend `handle` block: 1. Store must already be on **HTTPS**. WordPress will not offer Application Passwords over plain HTTP. 2. Create a dedicated low-privilege WordPress user (shop manager, or custom role - with product create/edit + media upload). Do not reuse an admin login. + with product create/edit + media upload). Admin logins are not reused. 3. Sign in as that user → **Users → Profile → Application Passwords** → generate a password for "SlabUploader". 4. Enter the username + application password in the app Settings UI. FastAPI diff --git a/docs/IMPL-PLAN.md b/docs/IMPL-PLAN.md index c3a65f2..8634123 100644 --- a/docs/IMPL-PLAN.md +++ b/docs/IMPL-PLAN.md @@ -2,12 +2,11 @@ Status: SPEC · Gate A freeze 2026-08-31 · hybrid rewrite complete 2026-09-01 · SlabUploader -Phases 0–6 below are hybrid-aligned. Phase 2 remains a deferred stub only. Do not -implement offline PWA, OCR, ruler, or any server happy-path measure/crop as SoT. +Phases 0–6 below are hybrid-aligned. Phase 2 remains a deferred stub only; offline PWA, OCR, ruler, and server happy-path measure/crop as SoT are not implemented. The build plan a professional (or a fresh Hermes session) executes against. Each phase has: goal, deliverables, acceptance criteria (testable), and exit gate. Ordering is by -dependency. Do not skip ahead. Definition of done for every phase: code + tests + real +dependency. Definition of done for every phase: code + tests + real execution output in the PR/commit message + docs updated. Ground rules (from AGENTS.md): @@ -36,20 +35,20 @@ Scope — in: pricing rec from species $/bdft, 3:4 PNG / 80% fill / ≥1600 guard (**no upscale**). - FastAPI: app factory, logging, config, `GET /api/health`, SQLite + alembic skeleton, settings stub with AES-GCM round-trip (secrets never returned on GET), draft store stub - (accept client numbers + files — store only, do not recompute SoT). + (accept client numbers + files — store only, no server-side recompute of SoT). - `deploy/docker-compose.yml`, `Caddyfile.fragment`, `.env.example` (placeholders only). - Unit tests for TECH-SPEC **TV-1 through TV-10** (esp. TV-3 bdft, TV-6/7 crop/no-upscale, TV-8 pricing, TV-10 rounding). - Fixture photo set for Ty Gate B review. -Scope — out: +Phase 0 covers: -- Server happy-path pipeline / CLI that recomputes mask/crop/bdft as SoT. -- Real U2Net (stub OK; on-demand later). -- Woo create/publish and live taxonomy sync (Phase 1). Species offered in UI, pricing seeds, and Call 1 are **exactly** Woo-synced species-category leaves (CONTENT-WOO §2.2 / AGENTS §6 / DATA-MODEL `woo_categories`). No mock, seed, hardcoded, or fallback species list in this phase or later. -- Inference Call 1/2, LoRA. -- Offline PWA, IndexedDB sync, OCR, ruler. -- Fake upscale / inventing pixels. +- Server happy-path pipeline / CLI that recomputes mask/crop/bdft as SoT: client is authoritative; server stores client-sent numbers only. +- Real U2Net: stub OK; on-demand later. The one-photo server path stays in architecture. +- Woo create/publish and live taxonomy sync: Phase 1. Species offered in UI, pricing seeds, and Call 1 are **exactly** Woo-synced species-category leaves (CONTENT-WOO §2.2 / AGENTS §6 / DATA-MODEL `woo_categories`). +- Inference Call 1/2, LoRA: Phase 5. +- Offline PWA, IndexedDB sync, OCR, ruler: Phase 2 (deferred stub). +- Fake upscale / inventing pixels: undersized source warns and requires retake. Deliverables: @@ -140,11 +139,11 @@ Exit gate: Ty drives the API with curl through a full calibrated → ready cycle ## Phase 2 — Deferred: offline PWA / OCR / ruler (stub only) -**Deferred post-POC.** Do not implement for the online-only MVP. +**Deferred post-POC.** The online-only MVP does not implement offline capture. Capture UX for POC lives in early Phase 1 / Gate C (online hybrid). See AGENTS.md §2. -Out of scope until a later product decision reopens offline: +Offline PWA, OCR, and ruler detection are deferred to a later product decision: - Workbox service worker, IndexedDB draft sync, airplane-mode capture - Tesseract.js OCR for SKU @@ -321,7 +320,7 @@ Exit gate: Ty signs off on UAT results; v1 declared done. | Host port/Caddy collision with co-resident apps (e.g. bolt.diy) | deploy conflict | Phase 0/6 inventory worksheet before any port bind | Ruler detection is **deferred** with offline/OCR (Phase 2 stub). Manual length is -authoritative for POC. Do not treat ruler confidence as a POC risk row. +authoritative for POC. Ruler confidence is not a POC risk row. --- @@ -332,4 +331,4 @@ authoritative for POC. Do not treat ruler confidence as a POC risk row. - `pytest` + integration + UAT green; inference-off path green. - Deployed on the inventoried host (`APP_HOSTNAME` from `deploy/INVENTORY.md`), HTTPS, backed up, restore tested, runbook + key-rotation verified. - Repo on gitea-atd (`Ty_Tech/SlabUploader`) is source of truth; docs current. -- Do not treat `docs/archive/PRD-2026-08.txt` as implementation SoT. +- `docs/archive/PRD-2026-08.txt` is frozen history only; live docs are the implementation SoT. diff --git a/docs/OPENAPI.md b/docs/OPENAPI.md index 3013f0b..53a96e7 100644 --- a/docs/OPENAPI.md +++ b/docs/OPENAPI.md @@ -162,7 +162,7 @@ Sheet/slider prefs are client localStorage only in POC (not in SettingsView). - `DELETE /api/v1/slabs/{id}` → `204`. Soft: only unpublished drafts. Published slabs cannot be deleted from the app. ### Photo operations -- `POST /api/v1/slabs/{id}/u2net/{pid}` — **post-POC.** "Try harder." Server runs U2Net on this one photo, returns a better mask. Do not implement or expose in Gate C / first listing. Keep the contract; do not delete. +- `POST /api/v1/slabs/{id}/u2net/{pid}` — **post-POC.** "Try harder." Server runs U2Net on this one photo, returns a better mask. The contract is preserved but not implemented or exposed in Gate C / first listing. - Returns `202` `{ mask_url: "..." }`. Client uses the mask to re-compute area/widths locally. - `404` if photo not found. - `GET /api/v1/slabs/{id}/photos/{pid}/original` → `image/*` (original, while retained). diff --git a/docs/PROMPTS.md b/docs/PROMPTS.md index 9e417dc..5dc81e2 100644 --- a/docs/PROMPTS.md +++ b/docs/PROMPTS.md @@ -100,7 +100,7 @@ Return valid JSON matching this schema: - **Confidence gate (default threshold 0.7):** - Field confidence **≥ threshold** → pre-populate that field (mutable; user may clear or change it). - - Field confidence **< threshold** → leave empty. Do not show the model's + - Field confidence **< threshold** → leave empty. The model's low-confidence guess as a default. - Call 1 does not define the ready gate. Species + figure (or any vision subset) is assist/prefill only. Ready is the **full named set** in AGENTS §7 @@ -135,7 +135,7 @@ injected by deterministic templates. ``` You are a professional product copywriter for premium, one-of-a-one wood slabs. Write compelling, natural-sounding descriptions. Use the brand voice -provided. Do not invent measurements — use only the provided data. +provided. Measurements are not invented; only the provided data is used. ``` ### User prompt (assembled at runtime) @@ -160,7 +160,7 @@ Write: 2. A paragraph describing the character, grain, color, and use cases 3. A call to action -Keep the tone appropriate for a premium lumber buyer. Do not repeat the +Keep the tone appropriate for a premium lumber buyer. The dimensions — those are handled by the template. Focus on the beauty and versatility of the slab. diff --git a/docs/TECH-SPEC-PIPELINE.md b/docs/TECH-SPEC-PIPELINE.md index c727f74..9c21419 100644 --- a/docs/TECH-SPEC-PIPELINE.md +++ b/docs/TECH-SPEC-PIPELINE.md @@ -12,7 +12,7 @@ Inference, Woo payload, API, and schema live in other docs. 1. **Determinism** — same inputs → bit-identical outputs. No randomness, no timestamps in math, no network calls for the math. 2. **Manual entry is authoritative** — user-entered length, thickness, SKU, and price always win over any computed value. 3. **Fallback chain is explicit** — every computed value has a defined fallback; the system never silently guesses. - - BG removal: chroma-key / threshold → four knobs (sheet, sensitivity, edge offset, feather) live on capture → retake. U2Net last-resort is deferred from POC (do not delete from architecture). + - BG removal: chroma-key / threshold → four knobs (sheet, sensitivity, edge offset, feather) live on capture → retake. U2Net last-resort is deferred from POC; the contract stays in the architecture. - Length axis: min-area bounding rect → user rotate/confirm → retake if the photo is unusable. - Area: requires a single contiguous slab mask; broken mask → flag and retake. 4. **Units** — inches in 1/8" steps; sqft and bdft to 2 decimals; price half-up to 2 decimals. Those rounded values are what get stored. No sqin in the UI, tests, or product copy. @@ -33,8 +33,7 @@ update / switch link. No polyfill strategy in POC. Load-bearing client APIs for the deterministic path include canvas (or OffscreenCanvas where used) for mask overlay and knob re-run, image decode/crop/encode for 3:4 transparent PNG prep, and -standard fetch to the app API. Do not depend on APIs outside this inventory without updating this -section. +standard fetch to the app API. Only APIs listed here are used; update this section before adding new ones. ## 2. Units and rounding @@ -91,9 +90,9 @@ round trip for mask tuning in POC. - **Black:** grayscale threshold. Same flood-fill (protects dark grain). - **POC path:** client-side only (sheet detect + four knobs). If the edge is still wrong after tuning, **retake**. -- **Post-POC fallback (deferred, not deleted):** U2Net matting on one photo via - FastAPI. Mask returns; knobs still apply on the client. Do not ship the control - in Gate C / first listing. Do not remove the contract from architecture. +- **Post-POC fallback (deferred, contract preserved):** U2Net matting on one photo via + FastAPI. Mask returns; knobs still apply on the client. The U2Net control is not + shipped in Gate C / first listing. The contract stays in the architecture for post-POC. - Morphological close, then feather per the setting. ### 3.5 Edge quality @@ -153,7 +152,7 @@ Applies to every inventory photo of the slab (first photo and the rest). configurable in settings). - Transparent **PNG only**. - Slab centered. **80% fill at the extremes** (widest and tallest points of the slab). Extra margin where the slab is narrower. -- After crop, if the source has enough pixels, shorter side ≥ **1600 px**. If it cannot, warn and ask for a retake — do not invent pixels. +- After crop, if the source has enough pixels, shorter side ≥ **1600 px**. If it cannot, warn and ask for a retake. The source must supply enough pixels. - Original + processed kept while draft/retry; both purged after successful publish (server storage; see Data Model). ## 6. Pricing @@ -187,7 +186,7 @@ GREEN_SAT_MIN = 40 GREEN_VAL_MIN = 40 BLACK_THRESH = 30 ``` -Sensitivity, edge offset, and feather map onto these at runtime. Users do not edit the raw HSV numbers. +Sensitivity, edge offset, and feather map onto these at runtime. Users interact with the knobs, not the raw HSV numbers. ## 8. Test vectors @@ -213,7 +212,7 @@ One square end, one 45° cut. Length axis follows prevailing length, not the dia Slab centered in a 3:4 frame. At the widest and tallest points, fill = 0.80. PNG with alpha. Shorter side ≥ 1600 when the source allows. ### TV-7 Too-small source -After 80% crop, shorter side would be below 1600 and the source cannot supply it. Warn. Do not upscale from nothing. That photo is not publishable until retake. +After 80% crop, shorter side would be below 1600 and the source cannot supply it. Warn; no upscaling from nothing. That photo is not publishable until retake. ### TV-8 Pricing bdft 0.96, species $12.50/bdft → rec **12.00**. @@ -240,9 +239,9 @@ Price 12.345 → **12.35**. 7. 3:4 portrait is the PIP crop, configurable in settings. 8. Client does all of this math. Server stores the numbers the client sends. -## 10. Out of scope here (covered in other docs) +## 10. Cross-reference to other docs -| Topic | Doc | +| Topic | Depth doc(s) | |---|---| | Call 1 / Call 2 prompts, taxonomy mapping | PROMPTS, CONTENT-WOO | | Portable Call 1→Call 2 context (full resend default) | ARCHITECTURE §9, PROMPTS | @@ -251,4 +250,4 @@ Price 12.345 → **12.35**. | HTTP contract, taxonomy `taxonomy_anchor` | OPENAPI | | Client vs server topology, validation module | ARCHITECTURE | | Auto-dimension overlay, figure-weighted price | IMPL-PLAN (v1.5) | -| Offline capture | non-goal (online-only POC; see AGENTS) | +| Online-only capture (offline deferred) | AGENTS §2, ARCHITECTURE §4 | diff --git a/docs/UAT-PRACTICE.md b/docs/UAT-PRACTICE.md index 675eb9c..1ee4fe6 100644 --- a/docs/UAT-PRACTICE.md +++ b/docs/UAT-PRACTICE.md @@ -7,14 +7,14 @@ Follow the sections in order. Each one names what you do, what you should see, a lives. **Inference is OFF for this walk.** The optional ON path is only valid after Gate C is green and -the inference endpoint is already configured. Do not turn it on here. +the inference endpoint is already configured. Inference stays off here. --- ## 1. Host and deploy preconditions Before this walk, the app must already be on the inventoried host. This section only checks that. -Do not invent host IPs or hostnames. Read them from `deploy/INVENTORY.md`. +Host IPs and hostnames come from `deploy/INVENTORY.md`. 1. **Inventory is filled.** `deploy/INVENTORY.md` has `APP_HOST`, `APP_HOSTNAME`, ports, Caddy location, and the smoke results. It is the only source for what runs where on this host. @@ -41,7 +41,7 @@ Settings. 1. **Store is on HTTPS.** WordPress only offers Application Passwords over HTTPS. The store must already be on TLS. If it is not, stop and fix the store first. 2. **Dedicated low-privilege user.** Create or use a WordPress user that can create and edit - products and upload media. Do not reuse the store admin login. A shop manager role or a custom + products and upload media. The store admin login is not reused. A shop manager role or a custom role with product create/edit plus media upload is enough. 3. **Generate the password.** Sign in as that user. Go to **Users → Profile → Application Passwords**. Generate a password and label it "SlabUploader". Copy the password. WordPress @@ -61,7 +61,7 @@ the old password in the WP profile and entering a new one in Settings, then re-r ## 3. Practice build rules -These rules keep practice runs invisible to customers. They are locked. Do not change them for +These rules keep practice runs invisible to customers. They are locked. Changes are not made for the walk. - **SKU prefix `SLAB-UAT-*`.** Every practice listing uses a SKU that starts with `SLAB-UAT-`. @@ -69,12 +69,12 @@ the walk. - **Always a Woo draft.** A `SLAB-UAT-*` SKU creates a WooCommerce draft even if Settings say publish. Customers cannot open it. This is hard rule in `AGENTS.md` §5. - **`woo_create_status` defaults to draft.** The Settings field that controls create status - defaults to `draft`. For practice you do not need to change it. If it is `publish`, the + defaults to `draft`. Practice uses the default. If it is `publish`, the `SLAB-UAT-*` rule still forces a draft. - **Customers never see practice listings.** A Woo draft is hidden from the storefront. If you can see the product on the live store, something is wrong. -If a practice SKU is not `SLAB-UAT-*`, it is not a practice run. Do not publish a real SKU in +If a practice SKU is not `SLAB-UAT-*`, it is not a practice run. Real SKUs are not published in this walk. --- @@ -114,7 +114,7 @@ hard stop. Switch to a supported browser. 1. You are on the review screen. Fill every required field. Inference is OFF, so everything starts empty. 2. **Species.** Pick exactly one from the synced store list. The list came from `test-woo`. - Do not type a species that is not in the list. + Only species in the list may be typed. 3. **Wood categories.** Pick at least one from the synced list. 4. **Edge type, figure, grade.** Pick from the synced lists. At least one figure, at least one grade. @@ -207,7 +207,7 @@ After the walk, decide what to do with the Woo draft UAT product. **Real live publish is a separate step.** It is not part of this walk. A real product uses a non-UAT SKU (no `SLAB-UAT-` prefix) and is published only after you review it. That is a -different decision. Do not run it here. The name of that step is **final POC publish**, and it +different decision. That step is not run here. The name of that step is **final POC publish**, and it is gated on your review of one real listing. --- diff --git a/docs/UX.md b/docs/UX.md index 99d0e3d..b1bfc91 100644 --- a/docs/UX.md +++ b/docs/UX.md @@ -46,7 +46,7 @@ There are no calibration photos in this design. Only inventory photos exist. ### Mask overlay and four knobs The app removes the background sheet and draws the mask as an overlay on the source photo, showing -which pixels count as slab and which do not. The owner looks at that edge against the real wood. +which pixels count as slab and which do not. The owner reviews that edge against the real wood. This is the only quality check in the pipeline. There is no confidence score, no auto-gate, and no photo-quality checker. A clipped or over-inclusive mask shifts every downstream number with nothing later to catch it, so the eye on the overlay is what stands behind the measurement. @@ -208,26 +208,21 @@ Exact minimum version pins are still tracked under issue #4. The matrix above is for which classes of client are in scope. Unsupported browser behavior: hard stop. Show a clear message that this browser is not supported, -with a link to update or switch to a supported browser. Do not attempt a broken mask. No polyfill +with a link to update or switch to a supported browser. No polyfill strategy in this version. -Load-bearing client surfaces (do not silently drop): canvas-based mask overlay and live knob re-run, +Load-bearing client surfaces that must remain: canvas-based mask overlay and live knob re-run, image crop/prep to 3:4 transparent PNG, file/photo intake for inventory shots, and the online API calls for draft upload, review, and publish. Depth for APIs stays in `docs/TECH-SPEC-PIPELINE.md` and `docs/OPENAPI.md`. -## What this version does not show +## Deferred features -These are locked out for now; they do not appear on any screen: - -- No photo-quality checker and no banner over the photo telling the owner it is bad. The overlay edge - plus the owner's eye is the only gate. -- No OCR of a printed SKU label. SKU is typed by hand. -- No ruler or scale detection. Length is entered by hand; the browser derives its own pixel-to-inch - scale from that length and the confirmed axis. -- No server-side measuring or cropping as the source of truth. The browser owns the happy path. -- No U2Net "try harder" control in this version. It stays in the architecture for later. -- No offline capture, no airplane-mode flow. Online only. +Photo quality, OCR, ruler detection, server-side measuring, U2Net control, and offline capture are +deferred post-POC. The overlay edge plus the owner's eye is the only quality gate. SKU is typed by +hand. Length is entered by hand; the browser derives its own pixel-to-inch scale. The browser owns +the happy path for measuring and cropping. The U2Net one-photo contract stays in the architecture +for later. Capture is online only. ## Where each job lives