← back to pin list

Brick 21: the part-list nest UI — Qty / Rotate / Bridge / Filler live over the proven pack engine; 2026-09-20 preview cards -- thumbnail + full name + X x Y per row, selected part large on canvas, sheet moved to the Nest tab

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-20 — computed from the item itself, not typed.

Built 2026-09-01 (Aristide 'E' — brick E of the approved execution plan). The ruled part-list columns (pin part-list-nest-columns, Jordan 2026-08-31) as a working screen over the proven engine (pin part-list-packer, 24 controls). Built on synthetic fixtures per the ruling that the LH-2.5 job was education only — Jordan's real test job is the first real fixture; the surface is ready for it.

The job kind: a part-list job (POST /api/jobs?partlist=1) has no source file — its rows REFERENCE healed jobs by id (several unique shapes, the part-by-part / Torongo form). Each part rides the normal upload/sketch pipeline first, so heal/QC gates stay per part; a part list cannot list a part list. GET/POST /api/jobs/<id>/partlist saves the list — a bad row (no such job, unhealed geometry, negative qty/bridge, a rotate step that does not divide 360) is a plain 400 in honest words, the nestseq pattern; saving over a packed layout DROPS it (a stale pack never keeps serving). POST /api/jobs/<id>/partnest packs through part_list_nest.pack: sampled TRUE outlines from each referenced job's own healed prims (never bounding boxes), bridge seed = tables.nest_gap (blank cell raises), standoff = tables.lead_len, sheet = the machine bed. Engine refusals — including the pack's own separate-arithmetic re-audit — land as a BLOCKED partnest stage in the engine's words (stage keys partlist/partnest so the generic dispatch marks the right tab dot).

The persisted report (partnest.json): asked BESIDE filled per row (filler extras named, never merged), excluded (qty 0), bridges ran+source (operator vs table), adjacencies with larger-governs required vs measured, the HUNT list (Jordan's regrouping lever — every column advance that paid a neighbour's larger bridge), used_x per sheet (the remnant slab boundary), audit slack over the ruled values.

UI: 'New part list' on the Jobs home; the job carries exactly two tabs. Part list tab: machine × material selects, per-row healed-job picker, qty, rotate select (locked / 0-180 / quarter turns — the ruled step storage), bridge unit-input whose placeholder is the table seed, filler checkbox, Save list + pack. Nest tab: canvas draws sheets side by side, every placement stroked from the referenced part's REAL healed Path2D placed by the engine's x/y/rot, filler placements half-tone, remnant slab tinted; drawer shows asked/filled, excluded, bridges, hunt rows, audit slack, Pack again.

Honest limits on-screen: lead/pierce envelopes are not reserved in the pack yet — part-by-part tools AFTER the nest (the ruled order), so the nest↔tooling loop flags a squeezed lead when the toolpath-after-nest brick lands; posting the sheet's program is a later brick.

Proven: test_part_list 24 engine controls untouched + app/verify_partlist.js NEW live over the public URL (14 checks, real controls, scratch sketch fixtures — nav209 untouched): the four columns end to end, larger-governs on all 16 adjacencies, filler 6 asked → 47 filled on ONE sheet (never opening a second), stale-on-edit, plain-400 rotate refusal, blocked-in-engine-words on an all-qty-0 list, a fresh page serving the persisted layout. test_tooling_doc 37 / test_rules 11 / test_sketch 21 / test_nestseq 12 green.