# ringagent — harness playbook (self-improving ring eval)

> **Current architecture (iteration ~70):** the model supplies SPECS ONLY;
> `harness/ringcli.py` + `authored/_templates.py` (STYLE table) +
> `authored/_parts.py` build deterministically. Improve by editing the kit or
> STYLE constants, never per-design geometry. Judge renders are colored
> (harness/render.py) with a head close-up; 3-of-5 vote majority; references
> vision-verified. The sections below describe the older loop — kept for the
> hard rules, which still apply (proportional geometry, one improvement per
> cycle, never present a failed build).

You are driving a **grounded, self-improving CAD eval**. The job: make our
parametric ring builder produce rings that match how real rings look.

The loop (one cycle):
1. **Gen + build** a batch of random requests — `.cad-venv/bin/python scripts/eval_loop.py --n <k>`.
   It builds each through `scripts/design.py` (the one true build path), renders a
   front preview `<...>.png` + a 360 turntable `<...>-360.png`, runs the manifold
   gate, and writes `artifacts/eval-dashboard/results.json`. Its stdout lists
   `judge_these` (name, query, preview, turntable).
2. **Look online** for each: `.cad-venv/bin/python scripts/find_reference.py --name <name> --query "<query>"`.
   Downloads a real product photo to `artifacts/eval-dashboard/refs/<name>.*` and
   records it on the design. (Fallback: search yourself, then `scripts/fetch_reference.py --name <name> --image-url <url> --page-url <url> --source <site>`.)
3. **Judge the match** — look at the WEB REFERENCE and OUR BUILD images and score
   how well our build matches the reference's *proportions* (band thickness, stone
   dominance, prong/halo/accent style, profile height). Record with
   `scripts/eval_judge.py --name <name> --score <0..1> --verdict "..." --diff "..."`.
4. **Self-improve** — find the most common, highest-impact geometry gap across the
   round's `match.diffs` and edit the parametric geometry to close it. Re-run; the
   match scores should climb cycle over cycle.

## Where the geometry lives (what you may edit to self-improve)
- `ringkit/settings.py` — archetype composition (solitaire / three_stone / halo):
  seating heights, prong height, side-stone graduation, halo placement.
- `ringkit/build.py` — `RingSpec` defaults (e.g. band width/thickness), assembly.
- `ringkit/elements.py` — primitives: `basket`, `prong_set`, `bezel`, `halo`.
- `ringkit/gems.py` — gem crown/table proportions.

## Hard rules (do not break these — they are the contract)
- **Never hardcode sizing or stone numbers.** Ring size → diameter comes from
  `ringkit.sizing`; carat → stone dims from `ringkit.stones`. Always build via
  `scripts/design.py`. Tune *geometry relationships*, not absolute mm/carat literals.
- **Keep everything proportional** to the stone's own dims (depth, girdle, footprint)
  or the band — so a change generalizes across cuts/carats, it is not fitted to one
  example. Prefer deriving from existing constants (e.g. the gem crown fraction in
  `ringkit/gems.py`) over inventing new magic numbers.
- **The manifold gate is law.** After any edit, the gate must still PASS and the
  tests must stay green:
  - `.cad-venv/bin/python -m pytest -q`
  - `.cad-venv/bin/python scripts/design.py --name selfcheck --standard US --size 6 --cut round --carat 1.5 --archetype solitaire --no-store --render` (expect `"gate": "PASS"`)
  If an edit breaks either, fix it or revert. Never present/keep a failed-gate build.
- **One improvement per cycle.** Make the single highest-impact change, verify, and
  let the next cycle measure it. Don't shotgun many edits at once.

## Known gaps vs real references (starting backlog, confirm against the images)
- Our **bands are too thick** vs the petite bands on real rings.
- Our **halos read loose/spiky**; real halos are a tight, fine pavé frame.
- Our **three-stone side stones are too large** and sit in chunky "bucket" baskets;
  real ones are small round accents on minimal prongs.
- Real bands often have **pavé**; ours are plain (bigger change — note, don't force).

Environment: CadQuery venv at `.cad-venv`. The dashboard (`viewer/eval.html`,
served by `scripts/serve.py` on :8770) shows reference vs build side by side.
