docs(#15): mask is load-bearing; inline knobs, live re-run, U2Net deferred

TECH-SPEC states BG removal defines the measurement footprint and silent
corruption failure mode. Four knobs stay on capture with live overlay on the
source photo. POC is client-side only; U2Net try-harder deferred, not deleted.
ARCHITECTURE swimlane and clarifications match.
This commit is contained in:
2026-09-02 00:32:49 +00:00
parent 7b7ed712c2
commit be221433ea
2 changed files with 54 additions and 21 deletions
+26 -8
View File
@@ -173,19 +173,37 @@ ready → publishing → published.
## 7. Taxonomy cache (manufactured last-modified)
Woo category/tag/attribute `date_modified` is not a reliable client cache key (the store does not bump it for every edit we care about). FastAPI **manufactures** a `taxonomy_updated_at` timestamp:
Woo REST exposes **no usable last-modified** on categories, attributes, or tags
(only products carry `date_modified`). The client never talks to Woo. FastAPI is
the sole freshness source and **manufactures** one anchor timestamp
(`taxonomy_updated_at` / `cache_anchor`).
- Bump **only** when a stored-subset row actually changes (species/wood-category leaves, five attributes + terms, `fig-*`/`feat-*` tags).
- A no-op sync (same rows) **does not** bump.
- Client re-pulls if the returned anchor is newer than its snapshot.
- Anchor bumps **only** when a row-level change is detected in the **stored
subset** of cache fields (whatever columns the cache tables actually keep:
species/wood-category leaves, five attributes + terms, `fig-*`/`feat-*` tags).
Scope is schema-driven: adding a cache column later automatically includes it.
- Spelling/name edits, additions, and deletions all bump. Diff must catch missing
rows (deletions), not only changed rows.
- A no-op sync (stored subset unchanged) **does not** bump, so the client does
not churn.
- 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.
**Triggers**
1. `POST /api/v1/settings/test-woo` always runs a taxonomy resync after a successful connection test.
2. Publish path: opportunistic resync if the last successful bump is older than **1 hour**.
3. Optional: app launch and a Settings “Refresh taxonomy” control.
1. `POST /api/v1/settings/test-woo` **always** resyncs taxonomy after a successful
connection test (unlocks the species list).
2. Publish / product submit: opportunistic resync if the last successful sync is
older than **1 hour**; bump anchor only if the stored subset changed.
3. Optional: app launch check (sync only if stale) and a Settings “Refresh
taxonomy” control. Not required for POC.
4. Do **not** sync on every screen navigation.
Species pickers and Call 1 option lists are **exactly** this cached set. No hardcoded mill list.
Species pickers and Call 1 option lists are **exactly** this cached set. No
hardcoded, invented, or fallback species list. A new Woo species is selectable
only after the next sync that lands it in the cache.
## 8. Shared validation module
+28 -13
View File
@@ -32,9 +32,14 @@ Inference, Woo payload, API, and schema live in other docs.
- bdft is never rounded up to whole board feet.
- Pixel→inch scale is an implementation detail. Users never see pixels.
## 3. Background removal
## 3. Background removal (load-bearing)
The user must see where the cut will land and be able to fix it. Edge quality is the foundation of sqft and bdft.
Background removal is the **load-bearing phase** of the image pipeline. The mask
defines the slab's pixel footprint. Length axis, 6" width samples, sqft, and bdft
all derive from that footprint. A clipped or over-inclusive mask silently shifts
the bounding rectangle and width samples with no later numeric check to catch it.
The user's eye on the overlay is the only validator. There is no confidence score
and no auto-gate on mask quality.
### 3.1 Auto-detect sheet
1. Sample a 2–5% strip on all four borders.
@@ -44,14 +49,19 @@ The user must see where the cut will land and be able to fix it. Edge quality is
5. Else prompt: pick green or black.
### 3.2 Visual feedback (required)
- Overlay the mask on the photo (what will be removed vs kept).
- Show the slab edge clearly — that edge is the measurement boundary.
- Overlay the mask on the **source photo** (included vs excluded pixels), not only
a cropped result.
- Show the slab edge clearly. That edge is the measurement boundary.
- User confirms the edge before length / area run.
### 3.3 Capture knobs (inline, live, persisted)
Factory values live in code. If the user changes them, the new values persist in localStorage until reset (Settings).
Factory values live in code. If the user changes them, the new values persist in
localStorage until reset-to-default.
All four knobs are **on the capture screen next to the overlay**, not in Settings. Changing any knob **immediately re-runs** §3.4 on the current photo and refreshes the overlay on the source image. No apply/save step. No server round trip in POC.
All four knobs are **on the capture screen next to the overlay**, not behind a
Settings navigation. Changing any knob **immediately re-runs** §3.4 on the current
photo and refreshes the overlay on the source image. No apply/save step. No server
round trip for mask tuning in POC.
1. **Sheet** — auto / green / black.
2. **Sensitivity** — one slider; tighter vs looser detection (green: HSV range width; black: brightness cutoff).
@@ -61,7 +71,11 @@ All four knobs are **on the capture screen next to the overlay**, not in Setting
### 3.4 Algorithms
- **Green:** chroma-key in HSV. Border flood-fill so only sheet pixels connected to the image edge are removed (protects green-ish grain inside the slab).
- **Black:** grayscale threshold. Same flood-fill (protects dark grain).
- **Fallback (POC):** retake. U2Net matting is last resort **post-POC** (one photo in, mask out; sliders still apply). Do not implement in Gate C.
- **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.
- Morphological close, then feather per the setting.
### 3.5 Edge quality
@@ -212,10 +226,11 @@ Price 12.345 → **12.35**.
| Topic | Doc |
|---|---|
| Call 1 / Call 2 prompts, taxonomy mapping | Content / Woo |
| Woo payload, publish, duplicate SKU | Content / Woo, OpenAPI |
| SQLite tables, status machine | Data Model |
| HTTP contract | OpenAPI |
| Client vs server topology | Architecture |
| Auto-dimension overlay, figure-weighted price | Impl plan (v1.5) |
| Call 1 / Call 2 prompts, taxonomy mapping | PROMPTS, CONTENT-WOO |
| Portable Call 1→Call 2 context (full resend default) | ARCHITECTURE §9, PROMPTS |
| Woo payload, publish, 409/422 recovery | CONTENT-WOO, OPENAPI |
| SQLite tables, status machine | DATA-MODEL |
| HTTP contract, taxonomy `cache_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) |