docs(m3): reconcile the remaining docs with the settled design

Docs written before this thread still carried the three-source copy model and
the Call 2 fields it implied.

- REQUIREMENTS.md REVIEW-10: title and short description are deterministic; the
  description comes from the model or the server.
- CREATE.md: primary category declared before Call 2; deterministic copy; the
  prompt revision interface; the slug; auth row in out-of-scope.
- API.md: infer-content inputs and result are the long description only.
- UAT-PRACTICE.md: the walk no longer tells the owner to leave copy for
  templates.
- README.md: the deploy section duplicated docs/DEPLOYMENT.md and
  deploy/INVENTORY.md; it now points at them.
- DEPLOYMENT.md: the prompt seed is stated per METADATA-105.

Both gates pass.
This commit is contained in:
2026-09-19 12:38:39 -07:00
parent 35848fe0e6
commit 5a210c47b0
6 changed files with 44 additions and 39 deletions
+2 -1
View File
@@ -33,7 +33,8 @@ If access is broken, fix it here before touching compose. Do not commit credenti
Precondition: the M3 scaffold exists on the branch being deployed — `frontend/Dockerfile`, Precondition: the M3 scaffold exists on the branch being deployed — `frontend/Dockerfile`,
`backend/Dockerfile`, and `deploy/.env` on the host. `main` currently `backend/Dockerfile`, and `deploy/.env` on the host. `main` currently
has `frontend/Dockerfile` only; `backend/` lands with M3 implementation. has `frontend/Dockerfile` only; `backend/` lands with M3 implementation.
Prompts live in SQLite (`docs/contracts/PROMPTS.md`); no prompt files ship with the image. Prompts live in SQLite with all revisions, seeded from the text in `docs/contracts/PROMPTS.md` §6 on
first run; no prompt files ship with the image (`METADATA-105`).
1. Push the branch to Gitea from the dev box. 1. Push the branch to Gitea from the dev box.
2. On the UAT host: 2. On the UAT host:
+5 -7
View File
@@ -48,14 +48,12 @@ Technical detail for Woo sync, metadata, pricing, and inference is in `docs/capa
| `capabilities/CAPTURE.md` | Milestone 1 Capture (shipped). | | `capabilities/CAPTURE.md` | Milestone 1 Capture (shipped). |
| `capabilities/PHOTOS.md` | Milestone 2 Photos (shipped). | | `capabilities/PHOTOS.md` | Milestone 2 Photos (shipped). |
| `capabilities/CREATE.md` | Milestone 3 Create. Read this before task breakdown or coding. | | `capabilities/CREATE.md` | Milestone 3 Create. Read this before task breakdown or coding. |
| `contracts/CONTENT-WOO.md` | Listing copy templates and Woo payload intent. | | `contracts/CONTENT-WOO.md` | Listing copy and payload intent; the deterministic title and short-description patterns. |
| `DEPLOYMENT.md` | Ops runbook: hosts, build, smoke checks, rollback. |
| `UAT-PRACTICE.md` | Human practice walk for a `SLAB-UAT-*` listing. Defers to `capabilities/CREATE.md` on conflict. | | `UAT-PRACTICE.md` | Human practice walk for a `SLAB-UAT-*` listing. Defers to `capabilities/CREATE.md` on conflict. |
| `archive/` | Historical only. Not M3 scope. | | `archive/` | Historical only. Not M3 scope. |
## Deploy reminders for this branch ## Deployment
- Dev-test env Docker: ubudual5060 `http://192.168.1.202:10881` (LAN) · `http://100.64.0.9:10881` (Tailscale) Hosts, ports, build and rollback steps, and the dev-test port block live in `docs/DEPLOYMENT.md`;
- Port block `10880`–`10889` is this project's; never bind `:10880` (Ty Node/SvelteKit) `deploy/INVENTORY.md` is the only source for what runs where. This map does not repeat them.
- Dev-test env binds `0.0.0.0` — reachable from any machine on `192.168.1.0/24`
- Store URL (`WOO_BASE_URL`) lives in compose / host `.env`
- Woo application password and inference URL live in encrypted Settings, not in compose
+1 -1
View File
@@ -88,7 +88,7 @@ The listing is built in two inference calls, both optional. Call 1 (vision) read
| ID | Requirement | Scope | Test | | ID | Requirement | Scope | Test |
|---|---|---|---| |---|---|---|---|
| REVIEW-5 | Submission-ready requires at least two images (clean first pic plus its dimension-overlay copy), SKU, length, thickness, computed widths and sqft and bdft, exactly one species leaf, at least one wood-category leaf, one Edge Type, at least one Figure, exactly one Grade, one Thickness band, one Moisture, and a price. | M3 | — | | REVIEW-5 | Submission-ready requires at least two images (clean first pic plus its dimension-overlay copy), SKU, length, thickness, computed widths and sqft and bdft, exactly one species leaf, at least one wood-category leaf, one Edge Type, at least one Figure, exactly one Grade, one Thickness band, one Moisture, and a price. | M3 | — |
| REVIEW-10 | Title, short_description, and description are required on the product and are satisfied by typed, generated, or templated text. | M3 | — | | REVIEW-10 | Title, short_description, and description are required on the product; title and short_description are assembled deterministically and the description is written by the model or the server. | M3 | — |
| REVIEW-15 | In review the owner declares one primary wood category and any secondary ones before Call 2 runs; primary drives the title and primary plus secondary drive the description; the default primary is the first category selected. | M3 | — | | REVIEW-15 | In review the owner declares one primary wood category and any secondary ones before Call 2 runs; primary drives the title and primary plus secondary drive the description; the default primary is the first category selected. | M3 | — |
| REVIEW-20 | Every empty required field shows an inline nudge as the owner works; the slab cannot reach ready until the full set is filled, and there is no single submit-time gap list. | M3 | — | | REVIEW-20 | Every empty required field shows an inline nudge as the owner works; the slab cannot reach ready until the full set is filled, and there is no single submit-time gap list. | M3 | — |
| REVIEW-25 | The price suggestion is bdft times the species rate from Settings; when no rate exists the price starts empty and the owner must enter one before create; the owner may override and the override sticks. | M3 | — | | REVIEW-25 | The price suggestion is bdft times the species rate from Settings; when no rate exists the price starts empty and the owner must enter one before create; the owner may override and the override sticks. | M3 | — |
+4 -2
View File
@@ -128,8 +128,10 @@ hard stop. Switch to a supported browser.
9. **Price.** A recommendation fills from the species $/bdft rule times board feet. You can 9. **Price.** A recommendation fills from the species $/bdft rule times board feet. You can
override it. If there is no rule for the species, the price starts empty. Type it. Publish override it. If there is no rule for the species, the price starts empty. Type it. Publish
is still allowed with a manual price. is still allowed with a manual price.
10. **Title and description.** You can type them, or leave them for templates at publish. 10. **Title and short description.** These are built for you from the primary wood category's
Templates inject the deterministic numbers. Generate text is OFF for this walk. pattern and the measurements. You can edit either before publish (`REVIEW-10`, `METADATA-80`).
11. **Description.** With Generate text OFF the server produces it (`METADATA-70`). When inference
is on you can trigger Generate text to have the model write it (`METADATA-55`).
Every empty required field shows an inline nudge where it sits. The slab cannot reach `ready` Every empty required field shows an inline nudge where it sits. The slab cannot reach `ready`
until the full set is filled. until the full set is filled.
+25 -24
View File
@@ -14,9 +14,9 @@ lives in `docs/contracts/` (`API.md`, `WOO-API.md`, `DATA-MODEL.md`, `PROMPTS.md
| REVIEW-25, REVIEW-30, REVIEW-35, REVIEW-40, REVIEW-45, REVIEW-50 | price, read-only math, stale picks, editability, SKU and caps | | REVIEW-25, REVIEW-30, REVIEW-35, REVIEW-40, REVIEW-45, REVIEW-50 | price, read-only math, stale picks, editability, SKU and caps |
| METADATA-5, METADATA-10, METADATA-15, METADATA-20, METADATA-25, METADATA-30 | synced taxonomy, cardinality, no term creation | | METADATA-5, METADATA-10, METADATA-15, METADATA-20, METADATA-25, METADATA-30 | synced taxonomy, cardinality, no term creation |
| METADATA-35, METADATA-40, METADATA-45, METADATA-50 | Call 1 inputs, results, confidence gate, precedence | | METADATA-35, METADATA-40, METADATA-45, METADATA-50 | Call 1 inputs, results, confidence gate, precedence |
| METADATA-55, METADATA-60, METADATA-65, METADATA-66 | Call 2, context, dimension safety, logging | | METADATA-55, METADATA-60, METADATA-65, METADATA-66 | Call 2, inputs, dimension safety, logging |
| METADATA-70, METADATA-75, METADATA-80, METADATA-85, METADATA-90, METADATA-95 | deterministic copy, inference-off path, pattern selection, fact block | | METADATA-70, METADATA-75, METADATA-80, METADATA-85, METADATA-90, METADATA-95 | deterministic copy, inference-off path, pattern selection, fact block |
| METADATA-100, METADATA-105, METADATA-110, METADATA-115 | feat mapping, prompt storage, Generate text control, failure triage | | METADATA-100, METADATA-105, METADATA-106, METADATA-107, METADATA-110, METADATA-115 | feat mapping, prompt storage, revision interface, Generate text control, failure triage |
| PUBLISH-5, PUBLISH-10, PUBLISH-15, PUBLISH-20 | create sequence, draft rule, duplicate, stale | | PUBLISH-5, PUBLISH-10, PUBLISH-15, PUBLISH-20 | create sequence, draft rule, duplicate, stale |
| PUBLISH-25, PUBLISH-30, PUBLISH-31, PUBLISH-35, PUBLISH-36, PUBLISH-37, PUBLISH-38 | success, failure, partial failure, triage | | PUBLISH-25, PUBLISH-30, PUBLISH-31, PUBLISH-35, PUBLISH-36, PUBLISH-37, PUBLISH-38 | success, failure, partial failure, triage |
| PUBLISH-40, PUBLISH-45, PUBLISH-50, PUBLISH-55, PUBLISH-60 | images, lineup, meaning of published, payload, quantity | | PUBLISH-40, PUBLISH-45, PUBLISH-50, PUBLISH-55, PUBLISH-60 | images, lineup, meaning of published, payload, quantity |
@@ -34,13 +34,13 @@ required field shows an inline nudge as they work, and the slab cannot reach `re
full set is filled (`REVIEW-5`, `REVIEW-20`). Widths, sqft, and bdft are read-only client math full set is filled (`REVIEW-5`, `REVIEW-20`). Widths, sqft, and bdft are read-only client math
(`REVIEW-30`); every other field stays editable until create (`REVIEW-40`). (`REVIEW-30`); every other field stays editable until create (`REVIEW-40`).
The owner declares one primary wood category and any secondary ones; the first selected is The owner declares one primary wood category and any secondary ones before Call 2 runs; the first
primary (`REVIEW-15`). Price is the bdft times the species rate; with no rate it starts empty and selected is primary (`REVIEW-15`). Price is the bdft times the species rate; with no rate it starts
the owner must enter one; an override sticks (`REVIEW-25`). SKU is 3–24 alphanumeric and hyphen empty and the owner must enter one; an override sticks (`REVIEW-25`). SKU is 3–24 alphanumeric and
(`REVIEW-45`). Title, short_description, and description are required and satisfy typed, hyphen (`REVIEW-45`). Title and short_description are assembled deterministically and the
generated, or templated text (`REVIEW-10`); title and short_description warn past 60 and 160 description is written by the model or the server (`REVIEW-10`, `METADATA-80`); title and
characters (`REVIEW-50`). A picked id that vanished shows as no longer valid and is never short_description warn past 60 and 160 characters (`REVIEW-50`). A picked id that vanished shows as
silently swapped (`REVIEW-35`). no longer valid and is never silently swapped (`REVIEW-35`).
## 2. Inference assist ## 2. Inference assist
@@ -51,19 +51,19 @@ or above the threshold (default 0.7) a field pre-fills and stays editable; below
stays empty (`METADATA-45`). Typed values always win (`METADATA-50`). Free-text observations map stays empty (`METADATA-45`). Typed values always win (`METADATA-50`). Free-text observations map
to synced `feat-*` tags only (`METADATA-100`). to synced `feat-*` tags only (`METADATA-100`).
Call 2 is user-triggered only and produces the product description (`METADATA-55`). It receives the Call 2 is user-triggered only and produces the long description (`METADATA-55`); the name and short
processed photos, the review-confirmed metadata, the primary and secondary wood categories, the description are already assembled from the primary wood category's patterns (`METADATA-80`,
parent-category path, the dimension fact block, and brand/geo context; the model never invents a `METADATA-85`). Call 2 receives the processed photos, the review-confirmed metadata, the primary and
dimension (`METADATA-60`, `METADATA-65`, `METADATA-90`). The Generate text control appears only secondary wood categories, the parent-category path, the dimension fact block, and brand/geo
when content generation is enabled and the endpoint is reachable (`METADATA-110`). All generation context; the model never invents a dimension (`METADATA-60`, `METADATA-65`, `METADATA-90`). The
is logged (`METADATA-66`). Generate text control appears only when content generation is enabled and the endpoint is reachable
(`METADATA-110`). All generation is logged (`METADATA-66`).
With inference off, the server produces the long description (`METADATA-70`). The name and short With inference off, the server produces the long description (`METADATA-70`). Prompts live in the
description are assembled from the primary wood category's patterns (`METADATA-80`, database with all revisions, and the revision used is recorded with each call; the revision
`METADATA-85`). Prompts live in the database with interface is REST only (`METADATA-105`, `METADATA-106`). Inference never blocks create and never
all revisions (`METADATA-105`). Inference never blocks create and never auto-publishes auto-publishes (`METADATA-75`); a runtime failure offers Retry when recoverable or explains when it
(`METADATA-75`); a runtime failure offers Retry when recoverable or explains when it is not is not (`METADATA-115`).
(`METADATA-115`).
## 3. Settings prerequisite ## 3. Settings prerequisite
@@ -98,7 +98,8 @@ unrecoverable (`PUBLISH-36`, `PUBLISH-37`, `PUBLISH-38`) and never shows a raw c
(`PUBLISH-35`). Partial failure leaves orphaned media with a cleanup note (`PUBLISH-31`). Images (`PUBLISH-35`). Partial failure leaves orphaned media with a cleanup note (`PUBLISH-31`). Images
upload as processed PNGs in photos-ready order with no cap (`PUBLISH-40`, `PUBLISH-45`). Published upload as processed PNGs in photos-ready order with no cap (`PUBLISH-40`, `PUBLISH-45`). Published
means the store create succeeded, not that it is live (`PUBLISH-50`). The payload is per means the store create succeeded, not that it is live (`PUBLISH-50`). The payload is per
`docs/contracts/WOO-API.md` (`PUBLISH-55`) and each product is one slab (`PUBLISH-60`). `docs/contracts/WOO-API.md` (`PUBLISH-55`) and each product is one slab (`PUBLISH-60`). The payload
carries an explicit slug: the sanitized product name plus the lowercased SKU (`PUBLISH-55`).
## 5. Acceptance ## 5. Acceptance
@@ -116,5 +117,5 @@ means the store create succeeded, not that it is live (`PUBLISH-50`). The payloa
## 6. Out of scope ## 6. Out of scope
Offline capture and U2Net matting (`CAPTURE-15`, `CAPTURE-165`), backup and restore (`OPS-30`, Offline capture and U2Net matting (`CAPTURE-15`, `CAPTURE-165`), backup and restore (`OPS-30`,
`OPS-35`), and cross-browser end-to-end verification (`QUALITY-115`). The V1 instrumentation work `OPS-35`), cross-browser end-to-end verification (`QUALITY-115`), and authentication for the prompt
is out of M3. revision interface (`METADATA-107`). The V1 instrumentation work is out of M3.
+7 -4
View File
@@ -137,16 +137,19 @@ taxonomy, and the user metadata. Returns `202`; the client polls. A failure or t
runtime failure rule (recoverable offers Retry, unrecoverable explains). runtime failure rule (recoverable offers Retry, unrecoverable explains).
### `POST /api/v1/slabs/{id}/infer-content` ### `POST /api/v1/slabs/{id}/infer-content`
Runs Call 2 on user action only. Fresh request carrying the full Call 1 context; no provider Runs Call 2 on user action only. Fresh request carrying the processed photos, the review-confirmed
thread id. Requires `test-inference` `ok`. Returns `202`; the client polls. The model writes prose metadata, the primary and secondary wood categories, the parent-category path, the dimension fact
only and never touches dimensions. block, and brand/geo context; no provider thread id and no raw Call 1 result. Requires
`test-inference` `ok`. Returns `202`; the client polls. The model writes the long description only
and never touches dimensions.
Call 1 result fields: `species_id`, `species_confidence`, `wood_category_ids`, Call 1 result fields: `species_id`, `species_confidence`, `wood_category_ids`,
`edge_type_term_id`, `figure_term_ids`, `figure_confidence`, `grade_term_id`, `grade_confidence`, `edge_type_term_id`, `figure_term_ids`, `figure_confidence`, `grade_term_id`, `grade_confidence`,
`character`, `inclusions`, `voids`, `checks`. Free-text observations map to synced `feat-*` tags `character`, `inclusions`, `voids`, `checks`. Free-text observations map to synced `feat-*` tags
only. only.
Call 2 result fields: `title`, `short_description`, `description`. Call 2 result field: `description`. The name and short description are assembled by the server from
the primary wood category's patterns, not returned by the call.
## 7. Publish ## 7. Publish