kerfmaster pin list · Estimator & quoting
intentmixedWhat we want to build. Never claimed the present, so it cannot be stale — and must never be read as a description of the code.
Content last changed 2026-08-22 — computed from the item itself, not typed.
Contract — Report stage
This contract describes a stage we intend to build — it is NOT a description of the code.
takes gcodematerial-table
makes delivery
fails if A cost line with no stated source.
Contract last changed 2026-08-06 — computed, not typed. Dated separately from the text above, so neither date can speak for the other.
1 open question blocks this pin
The line items, with where each number comes from. Anything marked SHOP is a value only Jordan or Aristide can supply (15e).
M98P9011 per boundary). Time: SHOP, by material × thickness, and whether a ramped/pulsed pierce is used on thicker stock.A function of cut time × pressure × nozzle size. Nitrogen on stainless and aluminium is a real line item and is routinely under-counted. SHOP: gas cost and consumption rate, or simply an all-in figure folded into the hourly rate — but say which, so it is not counted twice.
Nozzles, lenses, protective windows, filter media — amortised per machine hour. Usually simplest inside the hourly rate. SHOP.
Minimum charge, rush multiplier, repeat-customer terms, quantity policy. Entirely SHOP. The estimator should reproduce today's pricing before it tries to improve it — a tool that disagrees with the boss on job one does not get used on job two.
Each quoted job records estimated vs actual. Same discipline as the numbered slug report: the shop reports back by job number, and the table tightens. Without this the estimator is frozen at whatever we guessed on day one.
⚑ Build state, 2026-08-21: wired as the line-item list in quote.py — machine time (naive + 15b accel model), pierce, rapid, handling, material (remnant-policy aware: charged prices whole sheets, stocked/scrapped the nested fraction), tab break-off, gas, machine rate, shop minimum, margin. Each item computes from counted quantities or names its missing SHOP rows. No value is defaulted; RateMissing raises with the dotted row name.
Roll-up built, 2026-08-21 (Aristide: 'start execution on moving on without waiting for Jordan'): rollup.py composes these line items into the one figure a customer approves (Q29), by PER-SHOP POLICY -- a fixed skeleton with switchable joints, every joint a policy row in rates.json (cutting_basis, handling_bills_at, material_markup_pct, rush_multiplier, minimum_applies, rounding; all editable in the shop tables editor, seeded 'assumed'). Wired into quote.py: the printout ends with the TOTAL and its step-by-step composition. Honesty rails: any blocked input -> no total, blocked_by names the rows; one assumed input anywhere -> INDICATIVE with the culprit rows listed -- firm is only reachable when every consumed row is measured/decided. Per Aristide's flexibility ruling ('We aren't just building this for Jordan... We want our clients to have a flexible system'), his and Jordan's Q29 ruling becomes the DEFAULT CONFIG a subscribing shop inherits and adjusts; deliberately NOT a freeform formula editor. Deferred, recorded: quantity breaks (15c, needs nest part-count). The approval-artifact wiring (fast tier through the same skeleton) landed 2026-08-22 — see the 7g and 15d build states.