Commit Graph

128 Commits

Author SHA1 Message Date
Ty 63b8879720 docs(design): add approved #99 tape-line overlay wireframe
Owner-approved design proposal for #99 (tape-line overlay replaces the axis
rectangle). Wireframe only - no production code.

Settles: the black ~2pt line is a fixed entity in the middle of the 3:4
rectangle; the slab alone pans/zooms/tilts so its long axis lands on the line;
the ticks belong to the line and L = tick to tick; crop % moves only the
overlay's ends ((1 - fill)/2 of the long axis in from the top and the bottom)
and never changes the aspect ratio.

The file header lists the wireframe scaffolding to scrub before this reaches the
production workflow (viewport switcher, coverage board, was/now pair, PROPOSAL
markers, in-stage tutorial labels, sample values, window.__wf debug hook).
2026-09-24 11:30:13 -07:00
Ty 8ee3da9dcf merge work/merge-89-90 into main (Create-string #89/#90 + PR #97 fixes)
Reconciles two independent lines of work that both touched Review.svelte,
MultiSelect.svelte, and the thickness band:

- main's PR #97 (client-side thicknessBand.ts + MultiSelect names/commit +
  syncSelects DOM race fix + box-sizing CSS)
- work/merge-89-90 (server-side thickness band in thickness_band.py,
  Create-string #89, metadata_locked dropped, photo strip, wood primary)

Canonical resolution: the band is SERVER-side (hidden from UI, sent to Woo
on publish), so the client-side thicknessBand.ts + read-only band display
are removed from Review.svelte; PR #97's syncSelects() and box-sizing CSS
are preserved (orthogonal fixes). MultiSelect takes selectedSummary from
woodPrimary.ts (names in closed state) + the ms-count testid + onDestroy
timer cleanup; duplicate close()/summary definitions dropped.

Gates: backend 117/117, unit 88/88, tsc clean, e2e 6/6 (m3-create +
photo-strip).
2026-09-21 11:59:36 -07:00
Ty bdd03afce4 fix(review): thickness band derived from thickness_in (#88); MultiSelect shows selected names + commits on toggle settle (#90)
#88 — thickness band is now display-only, derived deterministically from
thickness_in against the synced Woo thickness terms (TV-9 / QUALITY-95).
Replaces the <select> with a read-only div. New pure function
deriveThicknessTermId + 6 unit tests. Docs (UAT-PRACTICE, contracts/UX)
updated to reflect the band is not an owner control.

#90 — MultiSelect closed state now shows the selected option names
(truncated to 2 + +N) instead of just a count. onCommit prop wired so
multi-select changes persist + re-review immediately (250ms debounce,
flush on Done, cleanup on destroy). Single-select binds use string vars
(speciesSel/edgeSel/gradeSel) to fix the number/string mismatch with
<option value={id}>; a tick()-deferred syncSelects() keeps the DOM
option in sync after programmatic writes (AI prefill, reload hydrate)
that Svelte's own select_option would otherwise reset.
2026-09-21 09:56:44 -07:00
Ty 204bc5e960 fix(review): #90 thickness band omitted entirely (not read-only) 2026-09-21 02:49:47 -07:00
Ty 0329052d37 feat(review): #90 wood primary category + derived thickness band 2026-09-21 02:41:20 -07:00
Ty 41401a7266 fix(inference): #87 redact image bytes from inference_log
Log full text + image_ref (photo_id/seq/bytes) only; wire path still
sends data-URLs. Call 1/2 SELECT id+seq for refs. Cap is safety net
after redaction (METADATA-66).
2026-09-20 23:01:38 -07:00
Ty 7287a55707 fix(inference): #86 tighten Call 1 prompt and closed lists
Ship locked expert Call 1 seed: order cats before edge, species=best
confidence, mill-count edge rules, Wild for cookies/burl, multi figure,
feature_tag_ids only (no free-text bags, no grade). LISTS keys match the
seed; feat- prefix stripped for the model. Gate and review UI apply
feature_tag_ids. Seed auto-activates on deploy when still seed-authored.
2026-09-20 22:54:36 -07:00
Ty 81be17d5cd fix(inference): METADATA-35 fit Call 1/2 images to 1024 long edge
Downscale processed PNGs only on the inference send path (keep alpha, never
upscale). Stored inventory/Woo blobs unchanged. Adds Pillow + unit/e2e-style
tests; cite tests on METADATA-35.
2026-09-20 22:32:14 -07:00
Ty cec03c5bd3 fix(m3): AI-assist scope + confidence gate + grouped wood categories
- inference: _taxonomy_lists hands the model the synced species leaves + wood
  leaves + case-insensitive attribute terms (was furniture roots / empty)
- inference: CALL1_SEED pins exact flat schema + *_confidence keys, drops grade
- inference: _gate maps field->confidence key correctly (was species_id_confidence),
  reads nested shape as safety net, omits grade (METADATA-40)
- review.svelte: figure gets AI assist, grade dropped from AI (owner judgment)
- MultiSelect: grouped mode (parents non-selectable headers, selectable leaves)
- METADATA-40 updated: grade not suggested by Call 1
2026-09-20 21:47:36 -07:00
Ty 0eb2b0f697 feat(backend): S0 foundation (schema + stdlib sqlite3 db factory + health/meta + JSON logs)
- backend/db/schema.sql: all 12 tables from DATA-MODEL.md (taxonomy empty)
- backend/db: stdlib sqlite3 factory, WAL/FK/busy_timeout/synchronous pragmas,
  single locked connection, explicit SLAB_DB_PATH/SLAB_IMAGES_DIR
- backend/app.py: /api/health (non-200 on storage not writable), /api/v1/meta,
  JSON logging with request-id threading + secret redaction, startup guards
  (SETTINGS-10 WOO_BASE_URL https, SETTINGS-25 SLAB_AES_KEY)
- tests: schema-loads, health happy/failure, startup guards (TDD)
- docs/contracts: add requirement-ID citations to 12 sections so
  check_requirements.py passes (pre-existing gate debt)

Gates: check_requirements.py + check_coverage.py exit 0; pytest 5 passed
2026-09-19 15:34:15 -07:00
Ty b166e796ad tools(docs): require citations in citing docs
Two checks were added to catch drift between the point of record and the
docs that cite it.

- Check 11: a capability or contract doc must declare its IDs in a
  Requirements impact table, and may cite only those.
- Check 12: a section that makes a behavior claim must cite an ID in that
  section. External-shape sections are exempt.

CAPTURE.md and CREATE.md gained the impact-table rows the first check
requires. check_coverage is unchanged.
2026-09-19 13:17:37 -07:00
Ty 2d12cbcfbd docs(m3): rewrite CONTENT-WOO for clarity
The file repeated requirement IDs on nearly every line, carried defensive
negations, mixed 'description' with 'long description', and left a cross
reference and the payload shape incomplete.

- Cite requirement IDs once in the Requirements impact table.
- Name the seven leaves as the synced WooCommerce wood-category leaves.
- Keep the length ft/in split with the short-description pattern it serves.
- Use 'description' only, matching the Woo field.
- Complete the cross references with section pointers.
- Follow the Woo v3 product shape and add an example submission whose
  taxonomy values are placeholders, since the synced cache supplies them.
2026-09-19 13:17:37 -07:00
Ty 5a210c47b0 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.
2026-09-19 13:17:37 -07:00
Ty 35848fe0e6 Update docs/README.md 2026-09-19 19:32:15 +00:00
Ty f0f891f80e docs(m3): add the prompt revision interface, seed, and auth gap
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.
2026-09-19 12:29:08 -07:00
Ty d6aa79b593 docs(m3): regroup METADATA and remove the false fallback framing
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.
2026-09-19 12:10:11 -07:00
Ty 120e0be871 docs(m3): settle deterministic title and Call 2 design
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.
2026-09-19 11:36:03 -07:00
Ty 1dfff0b7c9 docs(deploy): correct host addresses and port-block rules
- LAN address 192.168.1.202 for ubudual5060; port block 10880-10889; :10880 off limits.
- Release process points at the new ops runbook.
2026-09-19 10:12:32 -07:00
Ty 2ba5428269 docs(m3): place create decisions in the contracts
- 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.
2026-09-19 10:12:32 -07:00
Ty 6435199f08 docs(structure): govern .planning/ and register the ops runbook
- 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).
2026-09-19 10:12:32 -07:00
Ty 63a99e8154 docs(m3): close create contract gaps (soft delete, publish poll, prompts, image volume)
- 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.
2026-09-19 09:28:53 -07:00
Ty 1391219e48 docs(structure): retire Phase 2 planning sections and trim AGENTS context 2026-09-18 21:10:46 -07:00
Ty 01aa4c52c3 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/.
2026-09-18 21:02:06 -07:00
Ty 84d7681c6f docs(phase2): coverage gate, migration TODOs, session handoff
- add tools/check_coverage.py and .audit/coverage ledger (schema + settings pilot)
- add coverage gap worklist and source-doc migration TODOs
- add session handoff; redirect stale resume points in AGENTS.md, docs/README.md, reconciliation record
- add rows: CAPTURE-41, CAPTURE-141, METADATA-66, PUBLISH-31, SETTINGS-51
2026-09-18 12:54:08 -07:00
Ty 1603467747 docs(requirements): apply owner corrections; space IDs by 5
- 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
2026-09-18 11:24:41 -07:00
Ty 238fcc4f15 docs(requirements): draft reconciled requirement set (128 rows, 8 namespaces)
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
2026-09-18 10:38:30 -07:00
Ty b42e3cb8ce docs(structure): add requirements contract, job namespaces, and enforcement gate
Phase 1 scaffold for the docs consolidation:

- docs/STRUCTURE.md: artifact registry, 8 owner-job ID namespaces, routing and change rules
- docs/REQUIREMENTS.md, docs/MILESTONES.md: normative schema, empty pending Phase 2 port
- docs/_templates/: requirement-row, capability, contract, adr
- docs/capabilities/, docs/contracts/: registered homes
- tools/check_requirements.py: enforces registry, IDs, and traceability
- AGENTS.md: coding paused banner + structure-contract routing rule
- README.md: pointers to the structure/requirements/milestones set

Additive only: no doc moves, no requirement text, no CI wiring yet.
2026-09-18 08:32:49 -07:00
grokbot_ty d754cac9ef docs(m3): bring CONTENT-WOO onto branch; lock character and categories
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.
2026-09-16 21:11:07 +00:00
grokbot_ty 40080aee3a docs(m3): lock Woo image order including dimension overlay
Calibration clean PNG is #1, dimension-overlay copy is #2, then other
inventory PNGs in capture/add order (max 5).
2026-09-16 21:07:12 +00:00
grokbot_ty eaf96d36e1 docs(m3): record open decisions blocking task breakdown
List the five locks from comparing CREATE.md to main technical docs
(categories payload, attributes shape, overlay upload, character
template source, server persistence).
2026-09-16 21:05:15 +00:00
grokbot_ty 22599c924f docs(m3): expand Create SoT for submission-ready exit
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.
2026-09-16 21:03:46 +00:00
grokbot_ty df40c4269f docs(m3): lock Create requirements on m3-ds
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.
2026-09-16 20:32:03 +00:00
grokbot_ty 9bc35f7edd fix(photos): overlay UAT nits + 90% crop fill (#67,#68)
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.
2026-09-15 21:46:58 +00:00
grokbot_ty ab5bdafbd8 docs(m2): #58 EXIF bottom + Photos-ready lineup order
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.
2026-09-15 21:04:16 +00:00
grokbot_ty 4ab68d6b68 docs(m2): lock Photos milestone — batch, calibrate, overlays
Record Ty's narrowed M2 scope on m2-ds: multi-photo batch, pick
calibration, reuse M1 mask/crop, lined-up inventory PNGs, and
axis-oriented dimension overlay copy. Not taxonomy or Woo create.
2026-09-15 20:37:46 +00:00
grokbot_ty eaedcb53dd fix(capture): drop first and last 6in from width samples
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.
2026-09-15 03:20:28 +00:00
grokbot_ty 44d428b6f4 fix(capture): lower inventory PNG floor to 800px
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.
2026-09-14 23:40:02 +00:00
grokbot_ty b328871549 fix(capture): rotate length-axis rectangle and scale from mask span
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.
2026-09-14 16:37:00 +00:00
Ty bb78e35ac3 docs: name crop as Calculate step — 3:4, 80% fill, transparent PNG 2026-09-14 14:16:41 +00:00
Ty 3bae76cea3 docs: Calculate runs measure after length and thickness 2026-09-11 15:16:14 +00:00
Ty 74bd8b2863 docs: restore Milestone 1 user/app use case 2026-09-11 15:14:00 +00:00
Ty 92c4f81640 docs: remove structure check that pins the old doc set 2026-09-11 15:11:23 +00:00
Ty 0f0bd71f35 docs: system seams for client capture vs server Woo 2026-09-11 15:02:56 +00:00
Ty daf03248c4 docs: runtime, one photo, empty mask, browsers 2026-09-11 15:02:47 +00:00
Ty 188905e778 docs: Milestone 1 states, display vs source pixels, mask controls 2026-09-11 14:53:33 +00:00
Ty ea4931e53f docs: state Milestone 1 has no inference URL 2026-09-11 14:43:58 +00:00
Ty 9ca4b4520d docs: CAPTURE.md is Milestone 1 only 2026-09-11 14:36:38 +00:00
Ty 53830dcb91 docs: PRD milestones with acceptance 2026-09-11 14:36:25 +00:00
Ty fd48105c99 docs: name device draft vs Woo draft in PRD 2026-09-11 14:33:19 +00:00
Ty 121ff7035e docs: Milestone 1 ends at step 8; separate device draft from Woo draft 2026-09-11 14:33:13 +00:00