docs: purge scope-out sections; affirmative plan only
This commit is contained in:
@@ -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.
|
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.
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
# Deploy inventory worksheet
|
# Deploy inventory worksheet
|
||||||
|
|
||||||
Fill this at **Gate B** on the designated host before any port bind or Caddy merge.
|
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
|
## Host
|
||||||
|
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ flowchart TB
|
|||||||
## 3. Clarifications
|
## 3. Clarifications
|
||||||
|
|
||||||
1. **Happy path** stays on the phone through PNG + numbers. FastAPI is idle until the user has a confirmed mask.
|
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.
|
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
|
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
|
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
|
- 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
|
the **full** taxonomy cache. One timestamp governs categories, attributes, and
|
||||||
tags together.
|
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**
|
**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.
|
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`.
|
`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.
|
Per-slab thread on the **server** (client does not hold provider IDs). Best-effort delete on publish / abandon / fail; log and continue.
|
||||||
|
|
||||||
|
|||||||
+10
-10
@@ -54,7 +54,7 @@ and the final stored content.
|
|||||||
- Auth is **WordPress Application Passwords**, not WooCommerce consumer keys
|
- Auth is **WordPress Application Passwords**, not WooCommerce consumer keys
|
||||||
(`ck_`/`cs_`) and not the user's login password.
|
(`ck_`/`cs_`) and not the user's login password.
|
||||||
- Create a **dedicated low-privilege WordPress user** (shop manager, or a custom
|
- 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
|
- Generate the application password under **Users → Profile → Application
|
||||||
Passwords**. WordPress requires **HTTPS** for that UI; the store must already
|
Passwords**. WordPress requires **HTTPS** for that UI; the store must already
|
||||||
be on TLS (Caddy enforces HTTPS on the app side too).
|
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,
|
**Manufactured stamps.** Woo REST has **no** usable last-modified on categories,
|
||||||
attributes, or tags. FastAPI persists `taxonomy_last_sync_at` (every successful
|
attributes, or tags. FastAPI persists `taxonomy_last_sync_at` (every successful
|
||||||
pull) and `taxonomy_anchor` (bump only when stored-subset hash changes, including
|
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
|
deletions). Client re-pulls the full taxonomy iff the anchor advanced. No Woo-side
|
||||||
invent a Woo-side taxonomy timestamp. Do not sync per navigation.
|
taxonomy timestamp; no per-navigation sync.
|
||||||
|
|
||||||
**Triggers:** (1) successful `test-woo` **always** resyncs; (2) publish if
|
**Triggers:** (1) successful `test-woo` **always** resyncs; (2) publish if
|
||||||
`now - taxonomy_last_sync_at > 1 hour` then reconcile (bump only on real change);
|
`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
|
**Species exclusivity.** UI pickers, pricing seeds, and Call 1 species lists are
|
||||||
**exactly** the synced species-category leaves. No hardcoded, invented, or fallback
|
**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,
|
SKU, length, thickness, price, species, wood category, edge type, figure,
|
||||||
grade, thickness band, moisture, fig-* tags, and inventory PNG(s). Species
|
grade, thickness band, moisture, fig-* tags, and inventory PNG(s). Species
|
||||||
plus one figure is not enough. Presentation: `docs/UX.md`.
|
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
|
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
|
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:
|
Field rules:
|
||||||
- **Categories**: species leaf (1 required) plus wood-category leaf ids (1+).
|
- **Categories**: species leaf (1 required) plus wood-category leaf ids (1+).
|
||||||
- **Tags**: `fig-*` (1+ required) and `feat-*` (0+). Do not invent generic
|
- **Tags**: `fig-*` (1+ required) and `feat-*` (0+). Only documented
|
||||||
character or species product tags. Woo is authoritative for tag definitions.
|
character or species product tags are used. Woo is authoritative for tag definitions.
|
||||||
- **Attributes**: the five locked Woo attributes only — Edge Type, Figure, Grade,
|
- **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
|
character, length, or free-text thickness as product attributes. Missing
|
||||||
attributes are skipped, not created (v1: no attribute creation).
|
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:
|
For reliability the server:
|
||||||
1. For each customer-facing inventory photo in `seq` order (processed transparent PNGs
|
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
|
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).
|
2. Reference those `source_url` values in `images` (≤5 inventory photos).
|
||||||
3. Only `kind=inventory` photos. Calibration photos do not exist in this design.
|
3. Only `kind=inventory` photos. Calibration photos do not exist in this design.
|
||||||
|
|
||||||
**Status** comes from Settings `woo_create_status` (`draft` or `publish`, default
|
**Status** comes from Settings `woo_create_status` (`draft` or `publish`, default
|
||||||
`draft`). Practice SKUs `SLAB-UAT-*` are always created as drafts, even if Settings
|
`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
|
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."
|
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.
|
The force-draft rule is in `AGENTS.md`. This file only owns the payload and the steps.
|
||||||
|
|||||||
+3
-3
@@ -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)
|
- `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
|
Sheet/slider prefs (`sheet_mode`, sensitivity, edge offset, feather) persist in client
|
||||||
settings keys in POC. Client localStorage is source of truth (AGENTS §4 / ARCHITECTURE §5).
|
localStorage only. Client localStorage is source of truth (AGENTS §4 / ARCHITECTURE §5).
|
||||||
Optional server sync of those prefs is out of scope for POC.
|
Server sync of these prefs is deferred post-POC.
|
||||||
|
|
||||||
**Prompt files** — not in the settings table. Shipped as text files in
|
**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
|
`backend/app/prompts/` (repo), bind-mounted read-only to `/app/prompts/` in the
|
||||||
|
|||||||
+4
-4
@@ -6,15 +6,15 @@ Status: SPEC · env-agnostic · 2026-09-01 · SlabUploader
|
|||||||
Variables: `APP_HOST`, `APP_HOSTNAME`, `FRONTEND_PORT`, `FASTAPI_PORT`.
|
Variables: `APP_HOST`, `APP_HOSTNAME`, `FRONTEND_PORT`, `FASTAPI_PORT`.
|
||||||
Health URL: `https://${APP_HOSTNAME}/api/health`.
|
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.
|
> 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.
|
> 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
|
**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.
|
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):
|
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
|
1. Store must already be on **HTTPS**. WordPress will not offer Application
|
||||||
Passwords over plain HTTP.
|
Passwords over plain HTTP.
|
||||||
2. Create a dedicated low-privilege WordPress user (shop manager, or custom role
|
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
|
3. Sign in as that user → **Users → Profile → Application Passwords** → generate
|
||||||
a password for "SlabUploader".
|
a password for "SlabUploader".
|
||||||
4. Enter the username + application password in the app Settings UI. FastAPI
|
4. Enter the username + application password in the app Settings UI. FastAPI
|
||||||
|
|||||||
+14
-15
@@ -2,12 +2,11 @@
|
|||||||
|
|
||||||
Status: SPEC · Gate A freeze 2026-08-31 · hybrid rewrite complete 2026-09-01 · SlabUploader
|
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
|
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.
|
||||||
implement offline PWA, OCR, ruler, or any server happy-path measure/crop as SoT.
|
|
||||||
|
|
||||||
The build plan a professional (or a fresh Hermes session) executes against. Each phase
|
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
|
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.
|
execution output in the PR/commit message + docs updated.
|
||||||
|
|
||||||
Ground rules (from AGENTS.md):
|
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**).
|
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,
|
- 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
|
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).
|
- `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,
|
- 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).
|
TV-8 pricing, TV-10 rounding).
|
||||||
- Fixture photo set for Ty Gate B review.
|
- 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.
|
- 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).
|
- 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`). No mock, seed, hardcoded, or fallback species list in this phase or 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`).
|
||||||
- Inference Call 1/2, LoRA.
|
- Inference Call 1/2, LoRA: Phase 5.
|
||||||
- Offline PWA, IndexedDB sync, OCR, ruler.
|
- Offline PWA, IndexedDB sync, OCR, ruler: Phase 2 (deferred stub).
|
||||||
- Fake upscale / inventing pixels.
|
- Fake upscale / inventing pixels: undersized source warns and requires retake.
|
||||||
|
|
||||||
Deliverables:
|
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)
|
## 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.
|
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
|
- Workbox service worker, IndexedDB draft sync, airplane-mode capture
|
||||||
- Tesseract.js OCR for SKU
|
- 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 |
|
| 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
|
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.
|
- `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.
|
- 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.
|
- 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
@@ -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.
|
- `DELETE /api/v1/slabs/{id}` → `204`. Soft: only unpublished drafts. Published slabs cannot be deleted from the app.
|
||||||
|
|
||||||
### Photo operations
|
### 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.
|
- Returns `202` `{ mask_url: "..." }`. Client uses the mask to re-compute area/widths locally.
|
||||||
- `404` if photo not found.
|
- `404` if photo not found.
|
||||||
- `GET /api/v1/slabs/{id}/photos/{pid}/original` → `image/*` (original, while retained).
|
- `GET /api/v1/slabs/{id}/photos/{pid}/original` → `image/*` (original, while retained).
|
||||||
|
|||||||
+3
-3
@@ -100,7 +100,7 @@ Return valid JSON matching this schema:
|
|||||||
- **Confidence gate (default threshold 0.7):**
|
- **Confidence gate (default threshold 0.7):**
|
||||||
- Field confidence **≥ threshold** → pre-populate that field (mutable;
|
- Field confidence **≥ threshold** → pre-populate that field (mutable;
|
||||||
user may clear or change it).
|
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.
|
low-confidence guess as a default.
|
||||||
- Call 1 does not define the ready gate. Species + figure (or any vision
|
- 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
|
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
|
You are a professional product copywriter for premium, one-of-a-one wood
|
||||||
slabs. Write compelling, natural-sounding descriptions. Use the brand voice
|
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)
|
### User prompt (assembled at runtime)
|
||||||
@@ -160,7 +160,7 @@ Write:
|
|||||||
2. A paragraph describing the character, grain, color, and use cases
|
2. A paragraph describing the character, grain, color, and use cases
|
||||||
3. A call to action
|
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
|
dimensions — those are handled by the template. Focus on the beauty and
|
||||||
versatility of the slab.
|
versatility of the slab.
|
||||||
|
|
||||||
|
|||||||
+11
-12
@@ -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.
|
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.
|
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.
|
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.
|
- 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.
|
- 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.
|
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)
|
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
|
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
|
standard fetch to the app API. Only APIs listed here are used; update this section before adding new ones.
|
||||||
section.
|
|
||||||
|
|
||||||
## 2. Units and rounding
|
## 2. Units and rounding
|
||||||
|
|
||||||
@@ -91,9 +90,9 @@ round trip for mask tuning in POC.
|
|||||||
- **Black:** grayscale threshold. Same flood-fill (protects dark grain).
|
- **Black:** grayscale threshold. Same flood-fill (protects dark grain).
|
||||||
- **POC path:** client-side only (sheet detect + four knobs). If the edge is still
|
- **POC path:** client-side only (sheet detect + four knobs). If the edge is still
|
||||||
wrong after tuning, **retake**.
|
wrong after tuning, **retake**.
|
||||||
- **Post-POC fallback (deferred, not deleted):** U2Net matting on one photo via
|
- **Post-POC fallback (deferred, contract preserved):** U2Net matting on one photo via
|
||||||
FastAPI. Mask returns; knobs still apply on the client. Do not ship the control
|
FastAPI. Mask returns; knobs still apply on the client. The U2Net control is not
|
||||||
in Gate C / first listing. Do not remove the contract from architecture.
|
shipped in Gate C / first listing. The contract stays in the architecture for post-POC.
|
||||||
- Morphological close, then feather per the setting.
|
- Morphological close, then feather per the setting.
|
||||||
|
|
||||||
### 3.5 Edge quality
|
### 3.5 Edge quality
|
||||||
@@ -153,7 +152,7 @@ Applies to every inventory photo of the slab (first photo and the rest).
|
|||||||
configurable in settings).
|
configurable in settings).
|
||||||
- Transparent **PNG only**.
|
- Transparent **PNG only**.
|
||||||
- Slab centered. **80% fill at the extremes** (widest and tallest points of the slab). Extra margin where the slab is narrower.
|
- 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).
|
- Original + processed kept while draft/retry; both purged after successful publish (server storage; see Data Model).
|
||||||
|
|
||||||
## 6. Pricing
|
## 6. Pricing
|
||||||
@@ -187,7 +186,7 @@ GREEN_SAT_MIN = 40
|
|||||||
GREEN_VAL_MIN = 40
|
GREEN_VAL_MIN = 40
|
||||||
BLACK_THRESH = 30
|
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
|
## 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.
|
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
|
### 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
|
### TV-8 Pricing
|
||||||
bdft 0.96, species $12.50/bdft → rec **12.00**.
|
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.
|
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.
|
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 |
|
| Call 1 / Call 2 prompts, taxonomy mapping | PROMPTS, CONTENT-WOO |
|
||||||
| Portable Call 1→Call 2 context (full resend default) | ARCHITECTURE §9, PROMPTS |
|
| 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 |
|
| HTTP contract, taxonomy `taxonomy_anchor` | OPENAPI |
|
||||||
| Client vs server topology, validation module | ARCHITECTURE |
|
| Client vs server topology, validation module | ARCHITECTURE |
|
||||||
| Auto-dimension overlay, figure-weighted price | IMPL-PLAN (v1.5) |
|
| 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 |
|
||||||
|
|||||||
@@ -7,14 +7,14 @@ Follow the sections in order. Each one names what you do, what you should see, a
|
|||||||
lives.
|
lives.
|
||||||
|
|
||||||
**Inference is OFF for this walk.** The optional ON path is only valid after Gate C is green and
|
**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
|
## 1. Host and deploy preconditions
|
||||||
|
|
||||||
Before this walk, the app must already be on the inventoried host. This section only checks that.
|
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
|
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.
|
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
|
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.
|
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
|
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.
|
role with product create/edit plus media upload is enough.
|
||||||
3. **Generate the password.** Sign in as that user. Go to **Users → Profile → Application
|
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
|
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
|
## 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.
|
the walk.
|
||||||
|
|
||||||
- **SKU prefix `SLAB-UAT-*`.** Every practice listing uses a SKU that starts with `SLAB-UAT-`.
|
- **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
|
- **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.
|
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
|
- **`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.
|
`SLAB-UAT-*` rule still forces a draft.
|
||||||
- **Customers never see practice listings.** A Woo draft is hidden from the storefront. If you
|
- **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.
|
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.
|
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
|
1. You are on the review screen. Fill every required field. Inference is OFF, so everything starts
|
||||||
empty.
|
empty.
|
||||||
2. **Species.** Pick exactly one from the synced store list. The list came from `test-woo`.
|
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.
|
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
|
4. **Edge type, figure, grade.** Pick from the synced lists. At least one figure, at least one
|
||||||
grade.
|
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
|
**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
|
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.
|
is gated on your review of one real listing.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
+9
-14
@@ -46,7 +46,7 @@ There are no calibration photos in this design. Only inventory photos exist.
|
|||||||
### Mask overlay and four knobs
|
### Mask overlay and four knobs
|
||||||
|
|
||||||
The app removes the background sheet and draws the mask as an overlay on the source photo, showing
|
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
|
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
|
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.
|
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.
|
for which classes of client are in scope.
|
||||||
|
|
||||||
Unsupported browser behavior: hard stop. Show a clear message that this browser is not supported,
|
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.
|
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
|
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`
|
calls for draft upload, review, and publish. Depth for APIs stays in `docs/TECH-SPEC-PIPELINE.md`
|
||||||
and `docs/OPENAPI.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:
|
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
|
||||||
- No photo-quality checker and no banner over the photo telling the owner it is bad. The overlay edge
|
hand. Length is entered by hand; the browser derives its own pixel-to-inch scale. The browser owns
|
||||||
plus the owner's eye is the only gate.
|
the happy path for measuring and cropping. The U2Net one-photo contract stays in the architecture
|
||||||
- No OCR of a printed SKU label. SKU is typed by hand.
|
for later. Capture is online only.
|
||||||
- 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.
|
|
||||||
|
|
||||||
## Where each job lives
|
## Where each job lives
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user