kerfmaster pin list · The interface — recorded intent (build later)
recordStates what the code does today. Auditable against the code — this is the only type that can go stale.
Content last changed 2026-09-11 — computed from the item itself, not typed.
Built 2026-09-02 (Aristide '1st one'). Jordan "uses these a lot" — the Dimension tab is daily CAM-seat work. The governing idea, recorded in dims.py's docstring: a dimension on our canvas is a READOUT, never an input. On a customer print the callout governs (pdf-dims-govern) because the print is the customer's authority; inside kerfmaster the healed geometry IS the authority, so nothing is typed and nothing is stored as a number — the saved record is kind + pick points only, and EVERY read re-measures against the current geometry. A geometry edit moves every dimension live; a pick whose geometry left comes back flagged stale with the refusal words, never a silently frozen value (the -74 lesson generalized).
Engine dims.py: kinds h/v/a (2 picks), r/d (1 pick on an arc), ang (3 picks); picks snap to the geometry — nearest vertex OR arc centre within reach (whichever is closer — a click beside a hole's middle means the centre, not the semicircle seam), else the nearest point ON an edge; refusals raise DimInvalid in the module's own words (a radius pick on a line, a zero horizontal span, coincident picks, nothing within reach — the spot named). A diameter on a full CIRCLE counts its congruent twins at the 0.001" standard and reads print-style (2X ⌀0.5000). auto(prims) = MetaCam's Auto dimension in detect-and-report form: overall width + height on the TRUE extents (arc axis extremes included — the brick-3 bbox lesson) plus one diameter per distinct circle size, picks placed ON the geometry so they re-snap after any edit. Values stay doubles; text is 4-decimal display at the emit boundary.
Server: GET/POST /api/jobs/<id>/dims — annotation only, no stage record, no lock on downstream judgments; a bad dim is a plain 400 in the engine's words BEFORE anything is saved (the healedits pattern); a save replaces the list; every GET re-measures via remeasure(strict=False).
UI: 'Dimension' joins Tools/Checks/Heal-QC as the FOURTH brick-11 panel (tears off, docks, collapses, rides workspaces; pre-brick-27 layouts backfill its ground slot — docked right, collapsed strip); armed-click kinds with pick-progress, crosshair, Escape disarms; dims draw on the canvas with extension lines/arrowheads/value labels; per-dim remove + Clear all. Defect caught in the build: the new panel had no CSS width rule — it stretched and starved the canvas to zero width; the live verify's real-mouse click caught it.
Proven: test_dims.py 24 controls + app/verify_dims.js 13 live checks over the public URL (auto measures 4.0000/3.0000/⌀1.2000 on the scratch fixture, real-mouse diameter click snaps and measures, sketch edit re-measures both hole dims to ⌀1.5000, removed hole flags stale verbatim, persistence, refusal verbatim with nothing saved, nav209 untouched); all 16 prior suites green.
Honest limits: canvas annotation today — dimensions riding onto the delivered print pages (make_prints) is a later brick; v1 kind subset (baseline/continue/ordinate chains, smart dimension, callout/legend blocks stay recorded reference); snap reach 0.25" is a picking convenience, never a machine number.
Drag-to-place BUILT 2026-09-09 (Jordan's “do this” on the offered spec). Grab a dimension's value label on the canvas and drop it where you want it. The dim record gains an optional place — the dropped label position in part coordinates, 4-decimal at the record boundary — validated by the engine's own dims.norm_place (junk = plain 400 in its words, nothing saved; stale dims validated through the same function). PRESENTATION ONLY by construction: the picks stay anchored to the geometry and the value re-measures on every read, so a drag can never freeze a number — and a stale dim keeps its place so the drop survives a geometry edit. The dimension line FOLLOWS the drop: h/v lines move to the dropped height/offset with the label sliding along them; an aligned dim offsets perpendicular through the drop with dashed extension lines back to the anchors; radius/diameter run a leader from the arc edge to the label; an angular dim's arc radius follows the drop. Labels draw on top of everything so they win the grab (grab cursor on hover; armed pick/edit modes keep their clicks; a grab that never moves saves nothing); the drop saves through the same /dims door as every dim edit, and a dim with no place keeps the engine-default layout unchanged. Proven: test_dims 24→29 controls + app/verify_dimdrag.js 10 live real-mouse Playwright checks over the public URL (drag persists 4-decimal, survives a fresh page, value untouched, diameter leader form, junk-place refusal verbatim, click-without-move no-op, scratch fixture removed); verify_dims.js 13 re-run green (its tab=qc wait updated to the covering Geometry tab — the standing stale-verify precedent, tab-merge 2026-09-06). Honest limit: place is per dimension and free — no snap-to-alignment between labels; riding onto the delivered print pages stays the recorded later brick.
Armed-grab fix 2026-09-11 (Aristide's question after the Escape workaround worked): the dimension kind deliberately stays armed after a dim completes so several can be placed in a row, but the pointer gate made every armed click a pick — moving a just-placed dimension needed Escape first. Now the value-label grab wins over the pick whenever no pick sequence is mid-flight (a pick in progress keeps its clicks), and the armed crosshair survives mouse movement (it was being cleared by the hover-cursor expression). Client-only (app.js), proven by verify_dimarm.js — 12 live real-mouse checks including the mid-pick guard and a fresh-page round trip.
Aim feedback 2026-09-11 (Aristide: the pick should “magnetically attach” while hovering and leave a “trail” from the first pick; the only feedback was “pick 1 of 2” in the panel button, “which took me a few days to discover”). With a kind armed, the canvas now carries the whole state: a magnet marker (ring, plus crosshair ticks on a corner/center) at the exact point the pick will snap to — computed by a client MIRROR of the engine's dims.snap (nearest vertex or arc CENTER within the 0.25" reach, whichever is closer, else the nearest point ON an edge) as a picking aid only: the raw click still goes to the engine, whose own snap arithmetic stays the authority. A hint chip rides the cursor — “pick k of n — corner / circle center / on edge”, or the honest “no geometry within 0.25" — move closer” in warn color where the click would refuse; it clamps inside the canvas at the borders. Picks already taken draw as dot+ring markers with a dashed rubber-band trail to the live aim, so a mid-sequence operator sees exactly what they are measuring from. The aim is suppressed over a grabbable value label (the grab wins there), and clears on pan, Escape, disarm and leaving the canvas. Client-only (app.js), serves from disk — live immediately. Proven: app/verify_dimaim.js 12 NEW live real-mouse Playwright checks (vertex / center / edge-foot snap, honest out-of-reach state, snapped trail point on pick 1, live mid-sequence aim, trail cleared on save and Escape, label suppression, pointerleave) + verify_dimarm 12 / verify_dimdrag 10 re-run green.