docs(#9): Call 1 confidence gate ≥0.7 prefill, <0.7 empty + mandatory gate

Pin threshold rules: above pre-populates mutable fields; below leaves empty and
blocks ready until species + ≥1 figure are set. Manual authoritative; assist-only.
Also completes CONTENT-WOO Call 1 primary pre-fill (#8).
This commit is contained in:
2026-09-02 00:28:56 +00:00
parent 2f87e09c16
commit 8c88c97c1a
5 changed files with 88 additions and 45 deletions
+16 -6
View File
@@ -123,6 +123,7 @@ flowchart TB
2. Inference endpoint base URL + API key. Stored encrypted. Server proxies all
inference calls.
3. AES master key. Env var on server (`SLAB_AES_KEY`), never in the DB.
4. `WOO_BASE_URL` env (compose). HTTPS only. Not user-editable; Settings displays it read-only.
**Browser-side (no secrets):**
1. User preferences: sheet mode, sensitivity, edge offset, feather. Persisted in localStorage, reset-to-default available.
@@ -130,10 +131,11 @@ flowchart TB
3. Taxonomy snapshot (categories, attributes, tags). Read from server. No auth needed.
**Flow:**
1. Operator creates a low-privilege WP user on the store (HTTPS required for
Application Passwords UI). Generates an application password under
Users → Profile.
2. User enters that username + application password in Settings UI on the phone.
1. Deploy sets `WOO_BASE_URL` (`https://`) in compose. Operator creates a
low-privilege WP user on that store (HTTPS required for Application
Passwords UI). Generates an application password under Users → Profile.
2. User enters that username + application password in Settings UI
(store URL shown read-only from env).
3. Browser POSTs them to `/api/v1/settings` on FastAPI. Server encrypts with
AES-GCM and stores ciphertext only.
4. Server syncs taxonomy from Woo, caches in SQLite.
@@ -153,9 +155,17 @@ any → failed (with error)
1. **draft** — user took photos, no mask confirmed yet.
2. **calibrated** — user confirmed the BG edge, confirmed length axis, entered length/thickness/SKU. Client computed sqft/bdft/widths. Draft uploaded to server.
3. **ready** — all mandatory fields populated (species, wood category, edge type, figure, grade, thickness, price, title/desc/short desc, at least one photo). Values can come from Call 1, manual entry, or a mix. Inference is optional; the user can fill everything by hand and go straight to ready.
3. **ready** — all mandatory fields populated (species, wood category, edge type,
figure, grade, thickness, price, title/desc/short desc, at least one photo).
Values can come from Call 1 (≥ threshold pre-fill the user kept), manual
entry, or a mix. **Review gate:** if Call 1 returned below-threshold for a
field, that field stays empty until the user fills it. At minimum **species**
and **≥1 figure attribute** must be set before ready. Inference is optional;
with inference OFF the user fills everything by hand.
4. **publishing** — Woo create in flight. Poll for result.
5. **published** — Woo product created, woo_product_id stored. Images purged.
6. **failed** — pipeline, inference, or publish error. Error detail stored. Retry available.
Call 1 and Call 2 are assist-only. They do not gate the flow. If the user skips inference, the path is: calibrated → ready → publishing → published.
Call 1 and Call 2 are assist-only. They do not gate publish. Low-confidence Call 1
results do not auto-fill. If the user skips inference, the path is: calibrated →
ready → publishing → published.
+29 -14
View File
@@ -60,7 +60,7 @@ and the final stored content.
## 2. WooCommerce integration (FR24–28)
### 2.1 Auth & client
- REST v3 surface unchanged: `GET/POST/PATCH/DELETE {woo_base_url}/wp-json/wc/v3/…`
- REST v3 surface unchanged: `GET/POST/PATCH/DELETE {WOO_BASE_URL}/wp-json/wc/v3/…`
- 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
@@ -76,7 +76,8 @@ and the final stored content.
- Rotation: revoke the application password in the WP user profile, enter a new
one in Settings UI, then `POST /api/v1/settings/test-woo`.
- Client: `httpx` with timeouts (connect 10s, read 60s for image-heavy create).
- `woo_base_url` default: `https://www.whidbeywoodstore.com`.
- Store URL is **`WOO_BASE_URL`** from Docker Compose / host `.env` (HTTPS only).
FastAPI refuses `http://` at startup. Not a Settings field; UI shows it read-only.
### 2.2 Taxonomy sync (FR25)
`POST /api/admin/taxonomy/sync` pulls, in order:
@@ -86,19 +87,33 @@ and the final stored content.
Rebuilds the cache table (delete + insert, single transaction). Returns counts.
Failure → `502 woo_error`; previous cache retained (never delete-then-fail).
### 2.3 Auto-assign taxonomy (FR26)
- **Categories**: species leaf category (1 required) plus wood-category leaf ids (1+).
Match by name against the synced Woo category cache (case-insensitive, trimmed).
No match → user override in review, or empty (Woo required-field validation surfaces it).
- **Tags**: `fig-*` only for figure tags (1+ required) and `feat-*` only for feature tags
(0+). Call 1 free-text observations (character / inclusions / voids / checks) map to
existing Woo `feat-*` tags. Do not invent generic character or species product tags.
WooCommerce is authoritative for tag definitions.
### 2.3 Taxonomy assignment (FR26)
**Primary source when inference is on and confidence ≥ threshold (default 0.7):**
Call 1 vision results pre-fill the review screen for species, wood categories,
edge type, figure, grade, and mapped `fig-*` / `feat-*` tags (character /
inclusions / voids / checks → existing `feat-*`). All pre-filled values are
mutable. The user confirms or overrides; manual entry always wins.
**Below threshold:** those fields stay empty. The review screen gates continue
until the user manually selects at least **species** and **one figure attribute**
(and the rest of the ready mandatory set). Do not auto-fill below-threshold
guesses. Full rules: AGENTS §6.
**Deterministic name-matching** resolves Call 1 names (or manual picks) to synced
Woo IDs case-insensitive, trimmed. No match → empty; user picks in review. Woo
required-field validation still surfaces gaps 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.
- **Attributes**: the five locked Woo attributes only — Edge Type, Figure, Grade,
Thickness, Moisture — using term ids from the cache. Do not publish species, character,
length, or free-text thickness as product attributes. Missing attributes are skipped,
not created (v1: no attribute creation).
- Every assignment is overridable in the review screen (FR26).
Thickness, Moisture — using term ids from the cache. Do not publish species,
character, length, or free-text thickness as product attributes. Missing
attributes are skipped, not created (v1: no attribute creation).
Call 1 is assist-only and never gates publish. Inference OFF → full manual path.
### 2.4 Product create payload (FR27)
`POST /products` — body (only non-null fields sent):
+15 -6
View File
@@ -161,8 +161,10 @@ Deliverables:
- Show client-processed transparent PNGs (and originals while retained). No server
re-crop UI as SoT.
- Inference UI (only meaningful after Gate C and when `inference_enabled`): Call 1
results with confidence; manual confirm required below threshold **0.7**
(configurable). "Generate text" triggers Call 2; never auto.
results with confidence. **≥ 0.7** (configurable default) → pre-fill mutable
fields. **< 0.7** → leave empty; block continue until species + ≥1 figure
(and other mandatories) are set by hand. "Generate text" triggers Call 2;
never auto.
- Publish button (online-only), poll `publishing` → `published` | `failed`, surface
error detail from sync_log.
- Settings UI: WP username + application password + test-woo, inference endpoint +
@@ -226,8 +228,11 @@ Deliverables:
- Call 1 (vision) proxy: **all inventory photos** downscaled to 1024 + Woo taxonomy
snapshot + user metadata; OpenAI-compatible endpoint; model constrained to cached
taxonomy; confidence threshold **0.7** (configurable; relocate from older PRD FR22a).
Auto-run on calibrated create only if `inference_enabled`. Not top-down-only.
taxonomy; confidence threshold **0.7** (configurable default; not a POC Settings
slider). Auto-run on calibrated create only if `inference_enabled`. Not top-down-only.
- Apply AGENTS §6 gate: ≥ threshold → pre-fill mutable species/categories/attributes/
tags; < threshold → empty fields + review gate requiring species + ≥1 figure
before ready.
- Call 2 (text) proxy: never auto. User taps Generate text. LLM prose only; templates
inject deterministic numbers. See `docs/PROMPTS.md`.
- `test-inference` endpoint (vision capability check) before Call 2 is allowed.
@@ -236,8 +241,12 @@ Deliverables:
Acceptance:
- Local vision model configured: taxonomy suggestions appear with confidence; below
0.7 → manual confirm required.
- Local vision model configured: ≥ 0.7 fields pre-fill and remain editable; user
override sticks.
- Below 0.7: fields stay empty; UI blocks continue/ready until species and ≥1
figure attribute are set manually (asserted in integration or UI test).
- No doc/code path auto-fills below-threshold guesses or treats inference as a
publish gate.
- Inference OFF: app works end-to-end; tests assert zero calls to the inference endpoint.
- Audit payloads present after a call; prompt file edits apply without server restart.
- Gate C path remains green with inference OFF.
+11 -4
View File
@@ -95,10 +95,17 @@ Return valid JSON matching this schema:
duplicate them.
- **Pre-population (when `inference_enabled`):** Call 1 results are the primary
source that fills the review screen for species, character, wood categories,
figure/edge/grade attributes, and mapped `fig-*`/`feat-*` tags. The user
confirms or overrides. Manual entry always wins. Call 1 does not gate publish.
- Confidence threshold behavior (≥0.7 pre-fill vs <0.7 empty + gate) is locked
in AGENTS §6.
figure/edge/grade attributes, and mapped `fig-*`/`feat-*` tags.
- **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
low-confidence guess as a default.
- Before the slab can leave review toward ready/publishable, the user must
have **species** and **≥1 figure attribute** set (manually if Call 1 left
them empty), plus the rest of the mandatory ready set.
- Manual entry always wins. Call 1 is assist-only and does not gate publish.
Full suite must pass with inference OFF. Canonical lock: AGENTS §6.
---