# Listing copy and payload intent Status: SPEC · 2026-09-18. Owns how listing copy is produced and the intent of the create payload. The wire shape is `docs/contracts/WOO-API.md`; the create sequence is `docs/contracts/API.md`; prompts are `docs/contracts/PROMPTS.md`. ## Requirements impact | Requirement | Impact on this design | |---|---| | REVIEW-10, REVIEW-15, REVIEW-40, REVIEW-50 | required prose, primary category, editability, limits | | METADATA-40, METADATA-55, METADATA-60, METADATA-65, METADATA-66 | model scope, Call 2, context, dimension safety, logging | | METADATA-70, METADATA-75, METADATA-80, METADATA-85, METADATA-90, METADATA-95, METADATA-110 | template fallback, non-blocking, prompt selection, fact block, overlay exclusion, control | | PUBLISH-5, PUBLISH-10, PUBLISH-15, PUBLISH-20, PUBLISH-25, PUBLISH-30, PUBLISH-31, PUBLISH-40, PUBLISH-45, PUBLISH-50, PUBLISH-55, PUBLISH-60 | payload and create outcomes | | SETTINGS-30, SETTINGS-65 | brand voice and geo context; create status | | METADATA-10, METADATA-15, METADATA-30 | categories, attributes, tags on the payload | ## 1. Copy sources Titles and descriptions come from one of three sources (`REVIEW-10`): 1. **Typed** by the owner. 2. **Model** when Call 2 runs; the owner triggers it (`METADATA-55`). 3. **Template** as the fallback when Call 2 does not run (`METADATA-70`). The template guides style; when the model runs it writes the prose (`METADATA-80`). The model writes prose only and never touches a dimension; every number comes from the dimension fact block (`METADATA-60`, `METADATA-65`, `METADATA-90`). The dimension-overlay image is never sent (`METADATA-95`). The owner can edit any result (`REVIEW-40`). All text respects the field limits in `docs/contracts/WOO-API.md` §9 (`REVIEW-50`). The Generate text control appears only when content generation is enabled and the endpoint is reachable (`METADATA-110`); a failed generation never blocks create (`METADATA-75`). Every generation is logged (`METADATA-66`). ## 2. Default templates Placeholders use `{field}`; all math fields come from the deterministic pipeline, never the model (`METADATA-90`). **Title** (hyphen separator; `{character}` is the primary figure term name, `METADATA-80`): ``` {species} {length_ft}ft {length_in_remainder}in x {width_avg_in}in Wood Slab - {character} ``` `length_ft = floor(length_in / 12)`, `length_in_remainder = length_in mod 12` (1 dp). **Short description:** ``` {species} Slab - {character} ``` **Description** (multi-paragraph): ``` A one-of-a-one {character} {species} slab, {length_ft}ft {length_in_remainder}in long with an average width of {width_avg_in}in and {thickness_in}in thickness ({bdft} bdft). Each slab is naturally shaped; width varies along the length at {width_min_in}in to {width_max_in}in. Sold by the slab; dimensions as measured. {geo_sentence} ``` `geo_sentence` comes from Settings and is omitted when unset (`SETTINGS-30`). The primary wood category selects a specialized Call 2 prompt (`METADATA-85`). ## 3. Payload intent The exact wire shape is `docs/contracts/WOO-API.md`. Intent: - Only non-null fields are sent (`PUBLISH-55`). - `status` comes from `woo_create_status` (default draft); `SLAB-UAT-*` always draft (`SETTINGS-65`, `PUBLISH-10`). - Categories are the species leaf plus each wood-category leaf; attributes are the five locked attributes by synced term; tags are fig-* and feat-* (`METADATA-10`, `METADATA-15`, `METADATA-30`). Missing attributes or terms are skipped, never created (`METADATA-20`). - Images are the processed transparent PNGs in photos-ready order, with no cap (`PUBLISH-40`, `PUBLISH-45`). - `sold_individually` is true; each product is one slab (`PUBLISH-60`). - Create checks the SKU first and blocks on a duplicate (`PUBLISH-15`); a stale value is a field-level error (`PUBLISH-20`). Success purges photos and deletes the local row (`PUBLISH-25`); failure retains photos and logs (`PUBLISH-30`), including the orphaned-media cleanup note (`PUBLISH-31`). Published means the create succeeded, not that it is live (`PUBLISH-50`).