docs: purge scope-out sections; affirmative plan only

This commit is contained in:
2026-09-07 02:22:34 +00:00
parent 80af35721f
commit a06a4a0123
12 changed files with 70 additions and 79 deletions
+3 -5
View File
@@ -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.
---
+1 -1
View File
@@ -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
+3 -3
View File
@@ -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.
+10 -10
View File
@@ -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.
+3 -3
View File
@@ -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
+4 -4
View File
@@ -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
+14 -15
View File
@@ -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.
+1 -1
View File
@@ -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).
+3 -3
View File
@@ -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.
+11 -12
View File
@@ -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 |
+8 -8
View File
@@ -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.
---
+9 -14
View File
@@ -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