docs(phase2): reconcile requirements and migrate capabilities/contracts

Surface-matrix sweep of every source doc; added nine missed behaviors (METADATA-115, REVIEW-50, APP-55/60/65, SETTINGS-45 mode, Generate-text availability, defaults-off). 153 requirements, 0 coverage gaps.

Migrated capabilities to docs/capabilities/ and contracts to docs/contracts/; added WOO-API, API, DATA-MODEL, PROMPTS, UX, TEST-SPEC. Populated MILESTONES; branch-neutral trunk docs; renamed umbrella term to Woo Slab Taxonomy. Archived reconciliation working records under .audit/archive/.
This commit is contained in:
2026-09-18 21:02:06 -07:00
parent a8cc2f7596
commit 01aa4c52c3
53 changed files with 3186 additions and 817 deletions
+118
View File
@@ -0,0 +1,118 @@
# Create capability
Status: SPEC · 2026-09-18 · Milestone M3.
Behavior and acceptance for turning a Photos-ready slab into a submitted WooCommerce product. This
doc cites requirement IDs; `docs/REQUIREMENTS.md` is the only normative text. Interface detail
lives in `docs/contracts/` (`API.md`, `WOO-API.md`, `DATA-MODEL.md`, `PROMPTS.md`, `UX.md`,
`CONTENT-WOO.md`).
## Requirements impact
| Requirement | Impact on this capability |
|---|---|
| REVIEW-5, REVIEW-10, REVIEW-15, REVIEW-20 | ready set, prose fields, primary category, inline nudges |
| 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-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-70, METADATA-75, METADATA-80, METADATA-85, METADATA-90, METADATA-95 | template fallback, non-blocking, prompt selection, fact block |
| METADATA-100, METADATA-105, METADATA-110, METADATA-115 | feat mapping, prompt storage, Generate text control, failure triage |
| 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-40, PUBLISH-45, PUBLISH-50, PUBLISH-55, PUBLISH-60 | images, lineup, meaning of published, payload, quantity |
| SETTINGS-5, SETTINGS-10, SETTINGS-15, SETTINGS-20, SETTINGS-25, SETTINGS-30, SETTINGS-35 | store URL, auth, crypto, inference config, rates |
| SETTINGS-40, SETTINGS-45, SETTINGS-50, SETTINGS-51, SETTINGS-55, SETTINGS-60, SETTINGS-65 | tests, taxonomy sync and anchor, create status |
| SETTINGS-70, SETTINGS-75, SETTINGS-80, SETTINGS-85, SETTINGS-90 | vision cap, secret masking, test-woo, URL reject, flags |
| APP-15, APP-20, APP-30, APP-35, APP-40, APP-45, APP-50, APP-55, APP-60, APP-65 | device draft, revisions, API base, envelope, health, logs, accessibility, redaction |
| QUALITY-20, QUALITY-35, QUALITY-50, QUALITY-90, QUALITY-95, QUALITY-105, QUALITY-110, QUALITY-120, QUALITY-125 | M3 test bar and exit evidence |
| OPS-40 | UAT host |
## 1. Review to ready
Review is reached from a Photos-ready draft. The owner fills or confirms every field; each empty
required field shows an inline nudge as they work, and the slab cannot reach `ready` until the
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`).
The owner declares one primary wood category and any secondary ones; the first selected is
primary (`REVIEW-15`). Price is the bdft times the species rate; with no rate it starts empty and
the owner must enter one; an override sticks (`REVIEW-25`). SKU is 3–24 alphanumeric and hyphen
(`REVIEW-45`). Title, short_description, and description are required and satisfy typed,
generated, or templated text (`REVIEW-10`); title and short_description warn past 60 and 160
characters (`REVIEW-50`). A picked id that vanished shows as no longer valid and is never
silently swapped (`REVIEW-35`).
## 2. Inference assist
Call 1 runs only when inference is enabled, after a calibrated draft uploads or on demand; it
sends the clean processed photos at 1024 px long edge or less plus user metadata and the synced
taxonomy, and returns suggestions constrained to those lists (`METADATA-35`, `METADATA-40`). At
or above the threshold (default 0.7) a field pre-fills and stays editable; below it the field
stays empty (`METADATA-45`). Typed values always win (`METADATA-50`). Free-text observations map
to synced `feat-*` tags only (`METADATA-100`).
Call 2 is user-triggered only and produces name, short_description, and description
(`METADATA-55`). It is a fresh request carrying the full Call 1 context and the literal dimension
fact block; the model never invents a dimension (`METADATA-60`, `METADATA-65`, `METADATA-90`).
The 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, deterministic templates produce the prose so create never lacks it
(`METADATA-70`); the fallback title uses the primary figure term with a hyphen separator
(`METADATA-80`). Prompts live in the database with all revisions (`METADATA-105`). Inference never
blocks create and never auto-publishes (`METADATA-75`); a runtime failure offers Retry when
recoverable or explains when it is not (`METADATA-115`).
## 3. Settings prerequisite
Store URL is env-only, HTTPS, read-only (`SETTINGS-5`, `SETTINGS-10`); the settings API rejects a
write to it (`SETTINGS-85`). Woo auth is a WordPress application password stored AES-GCM
(`SETTINGS-15`, `SETTINGS-20`). `SLAB_AES_KEY` is env-only (`SETTINGS-25`). Inference URL and key
are encrypted; flags, model, brand voice, and geo context are settings (`SETTINGS-30`); the flags
default off (`SETTINGS-90`). Species rates are one flat value per synced leaf (`SETTINGS-35`).
`woo_create_status` defaults to draft (`SETTINGS-65`).
test-woo returns ok and detail, fails closed on missing credentials or non-HTTPS, and always
resyncs taxonomy on success (`SETTINGS-80`, `SETTINGS-40`). test-inference returns ok, mode
(stateful, stateless, or fail), vision_capable, and detail; fail blocks Call 2 only
(`SETTINGS-45`). Taxonomy sync keeps only fig-* and feat-* tag families (`SETTINGS-51`), rebuilds
in one transaction, keeps the previous cache on failure (`SETTINGS-50`), and bumps the anchor only
on a real stored-subset change (`SETTINGS-55`). The client re-pulls when the anchor advances, and
publish refreshes when the last sync is over an hour old (`SETTINGS-60`).
## 4. Publish
The sequence validates the ready set, looks up the SKU and stops if it exists, refreshes taxonomy
when stale, resolves categories, tags, and attributes, uploads the processed PNGs, calls
`POST /products` per `docs/contracts/WOO-API.md`, then finalizes (`PUBLISH-5`). A `SLAB-UAT-*` SKU
always creates a draft (`PUBLISH-10`). A duplicate SKU blocks create with edit-SKU or
open-existing (`PUBLISH-15`). A stale value is a field-level error showing current options
(`PUBLISH-20`).
Success sets `woo_product_id`, purges photos, deletes the local row, and clears the device draft
(`PUBLISH-25`, `APP-15`). Failure keeps photos, writes `sync_log`, and shows a plain message on
the affected field with retry (`PUBLISH-30`); the failure is classified recoverable or
unrecoverable (`PUBLISH-36`, `PUBLISH-37`, `PUBLISH-38`) and never shows a raw code
(`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
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`).
## 5. Acceptance
- The full suite passes with inference disabled and asserts zero inference calls (`QUALITY-20`).
- Integration tests cover success, error, duplicate SKU, stale field, and taxonomy anchor against a
Woo mock (`QUALITY-35`).
- UI and end-to-end tests run against a Compose stack with mocked Woo (`QUALITY-50`).
- Vectors TV-8 (pricing) and TV-9 (thickness band) pass (`QUALITY-90`, `QUALITY-95`).
- The M3 exit evidence is a real `SLAB-UAT-*` Woo draft matching the reviewed ready set, with
inference off, plus test-woo and test-inference results (`QUALITY-110`).
- No raw status code, stack trace, or internal code reaches the owner (`QUALITY-120`); encrypted
credentials round-trip (`QUALITY-125`).
- Dishonest proxies are rejected (`QUALITY-105`).
## 6. Out of scope
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
is out of M3.