UAT requires prompt tuning, so the iteration system is M3; only the editing
UI is deferred.
- METADATA-105 now covers storage, append-only revisions, and recording the
revision used.
- METADATA-106 adds the REST revision interface (append, activate, read); no
prompt UI.
- METADATA-107 records the missing authentication as a later row; there is no
M4 yet, so the PoR carries it.
- PROMPTS.md owns the seed text as revision 0, the seed mechanism, and the
interface; sections renumbered after inserting them.
- DATA-MODEL.md §7 cites PROMPTS.md, adds content_hash, and states the
append-only rule.
- task_breakdown.md notes the S7 interface and the deferred auth.
155 requirements; both gates pass.
METADATA was ordered as it was written, not by topic, and used Call 1 /
Call 2 without defining them.
- Add a short METADATA preamble stating the inference flow: Call 1 vision
proposes taxonomy, the name and short description are deterministic, Call 2
writes the long description.
- Regroup the rows: taxonomy, then Call 1, then deterministic copy, then
Call 2, then cross-cutting.
- METADATA-70 said the deterministic name and short description were an
inference-off fallback; they are unconditional. It now covers only the
inference-off description.
- METADATA-81 folded into METADATA-80 (same rule, two strings).
- METADATA-45 now names the below-threshold outcome.
- METADATA-90 now states what the fact block drives.
153 requirements; check_requirements and check_coverage both pass.
Encode the recovered per-leaf title/short-description rule and the Call 2
input set into the point of record.
- REQUIREMENTS.md: METADATA-55 now produces the description only; METADATA-60
carries the ruled input set; METADATA-80 is the deterministic title; new
METADATA-81 is the deterministic spec-line short description; METADATA-85
selects the patterns; REVIEW-15 declares the primary before Call 2;
PUBLISH-55 carries an explicit name+SKU slug.
- CONTENT-WOO.md: per-leaf title and short-description catalog, slot order,
dimension placement, and the Cook Woods provenance.
- PROMPTS.md: Call 2 inputs and output; the deterministic patterns are cited,
not restated.
- CREATE.md, WOO-API.md, MILESTONES.md, task_breakdown.md updated to match.
Modeled on Cook Woods product-title form; the seven per-leaf prose templates
and Specialty cuts are parked in the M3 breakdown.
- DATA-MODEL.md: storage engine (stdlib sqlite3 + schema.sql, no ORM/migrations),
pragmas, per-test isolation.
- API.md: revision coupling, async job model, PUT check order, server-derived ready.
- PROMPTS.md: no prompt files ship; the DB is the only prompt source.
- docs/STRUCTURE.md: add a .planning/ registry (vision/roadmap/history/breakdown
roles), broaden the roadmap role, add enforcement items 8-10.
- tools/check_requirements.py: scan .planning/ too - every .planning/**.md must be
registered, registered files must exist, requirement rows rejected there.
- .planning/: PROJECT.md, ROADMAP.md, MILESTONES.md, and milestones/v0.5/M3/
{roadmap.md,task_breakdown.md}. M3 breakdown holds only the tasks; decisions live
in the contracts.
- docs/DEPLOYMENT.md: add the ops runbook (registered as ops).
- R1 soft delete: add deleted_at to slabs; exclude deleted rows from GETs
- R2 publish: terminal poll returns woo_product_id then the working row is
discarded; the app never deletes from WooCommerce (reworks PUBLISH-25)
- R3 prompts: SQLite is the point of record; file-based prompts superseded,
compose prompt mount removed
- R4 images: photo bytes are SQLite BLOBs; /images is a health probe + staging
Details recorded in .audit/m3-build-plan.md.
- PUBLISH: attempt-level failure wording, no image cap, failure triage rows
- METADATA: title rule is fallback-only (Call 2 not run)
- REVIEW: calculated widths/sqft/bdft not user mutable
- IDs now step by 5 per namespace; rule recorded in STRUCTURE.md
Reconciles the scattered requirements onto the owner-job namespaces.
- docs/REQUIREMENTS.md: 128 requirements across CAPTURE, METADATA, REVIEW,
PUBLISH, SETTINGS, APP, OPS, QUALITY
- docs/STRUCTURE.md: Test may be a path, a requirement ID, or - ;
a shipped path must exist
- tools/check_requirements.py: resolve test refs accordingly
- .audit/2026-09-18-reconciliation-decisions.md: full decision record plus
18 deferred rulings for the final cleanup pass
Gate: python tools/check_requirements.py -> PASS
Copy listing-copy/Woo payload spec from main. Lock {character} to the
primary Figure term name (Cathedral example). Lock categories[] to all
ready-set species and wood-category ids.
List the five locks from comparing CREATE.md to main technical docs
(categories payload, attributes shape, overlay upload, character
template source, server persistence).
Reorganize docs for humans: README map (goals / shipped / M3), PRODUCT
overview, and a specific CREATE.md that pulls Woo sync, metadata, pricing,
and inference requirements from main. Exit criteria is a slab submission-
ready for WooCommerce, proven with a SLAB-UAT-* draft. Add UAT-PRACTICE.
Add docs/CREATE.md as M3 SoT from Ty conversation (Woo attributes sync,
ready-set use, create, OpenAI Settings dependency). Point AGENTS/PRODUCT
here; mark main milestone splits obsolete for this branch.
Length dim already mask tip-to-tip (locked by test). Width labels move
axis-left off the wood via labelAt; font steps down to max(22, scale*1.0).
Inventory/overlay crop FILL 0.8→0.9; CAPTURE/PHOTOS docs match.
Lock Ty’s decisions: width stations start 6in from EXIF-oriented
photo bottom along the approved length axis; lineup is clean cal,
dimension overlay, then other batch PNGs in capture order.
sampleWidths used floor(L/6)+1 stations from t=0, so tapered tips
dominated min/max. Sample only interior stations at 6, 12, … ≤ L−6.
When L≤12 there is no interior span: every6In stays empty and
min/max/avg stay 0. CAPTURE.md Widths bullet matches.
sqft, bdft, scale, and inventory PNG are unchanged.
Product call for the WooCommerce redo. Calculate accepts
sources whose post-crop shorter side is at least 800px.
Warn copy and CAPTURE.md match. No upscale still holds.
Length axis keeps the approved mask, replaces Flip 180 with a ± angle
slider, and sets scale from wood span along the approved direction rather
than bbox.longSidePx. Widths still sample every 6 in perpendicular to that
axis.