# Priced-quote compute engine

This reference is the **compute core** for a structured, priced quote: it turns a job (the items the
owner selected, with their measurements or counts) into priced figures — line prices, group
subtotals, and a final total — computed by **this owner's own pricing method**.

It carries no items, no units, no rates, no margins, no overheads, no taxes, and no roll-up sequence.
Every such value and rule is the owner's, captured as data. A trade pricing by the square metre, a
caterer pricing by the head, and a printer pricing by per-unit break are all priced by the same
approach — only their captured method differs.

The compute engine itself is **not shipped**. You generate a small bespoke engine for this owner the
first time they need a priced quote, and regenerate it whenever their business changes. The captured
method is data the engine reads. Both persist in the owner's workspace and are re-run on demand.

## When this path applies

Use this for a **priced quote computed from the owner's method** — measured or counted work that has
to be priced the way this owner prices it, then totalled. This is distinct from the simple
photo-to-quote / chat-to-quote flow in `references/quoting.md`, which formats a quote the owner has
already priced. If the owner has already worked out the numbers, stay in `quoting.md`. Come here when
the numbers have to be **computed**.

**Precondition:** a captured method for this owner must exist. Its *content* (the owner's items,
rules, dials, roll-up, and past-job fixtures) is produced and maintained by the method-capture flow —
Task 659 — which populates the method/job shape **this reference defines** below. If no captured method
exists, capture it first; do not invent rates or rules here.

## Where the engine and method live

The agent runs in the owner's workspace (the spawn cwd, `$ACCOUNT_DIR`). Keep the engine and the
captured method together under a `quoting/` subdirectory there, addressed by relative path:

- the **method** — the owner's items, dials, and roll-up, as data;
- the **engine** — the bespoke script that reads a method and a job and prices it;
- the owner's **past jobs**, each with the figures they actually issued, used to verify the engine.

These persist across sessions, are edited when the business changes, and are the engine's only inputs.
Nothing about the owner's business lives in this reference or in the plugin.

## The method shape (owner data)

This section is the authoritative definition of the method/job shape; the method-capture flow (Task
659) fills it with one owner's content. The method describes how this owner prices. For each
**priceable item** it records:

- what the item is (an identifier, a human label, a unit);
- **how a quantity arises** — the item's own rule for turning a measurement into a quantity (for
  example, an area from supplied dimensions, a length, a volume), or that the item carries **no
  measurement rule** because it is counted or taken as a single unit. This is the item's *default*
  quantity rule; a quantity entered on the job line always overrides it (see the job shape);
- **how a line price is computed** — the owner's own rule for that item, in whatever form their
  history shows it takes;
- which **group** the line rolls into (the owner's own section headings);
- whether the item is **standing-rule priced** (a rule fixes its price) or **judgement priced** (the
  owner sets the price per job) — so the quote flow knows when it must ask the owner for a figure
  rather than computing one.

Alongside the items the method holds:

- named **dials** — the owner's own scalars that their rules reference (a labour day-rate, a margin
  multiplier, a percentage — whatever their method uses, named by them);
- the **roll-up** — an ordered list of steps applied above the line items to reach the final total.
  Each step names its rule, the prior figures it reads, and the label of the figure it produces. This
  is whatever sequence the owner actually applies. It is **not** a fixed margin-then-overhead-then-tax
  chain: an owner may apply an overhead, a contingency, a discount, a tax, or nothing, in their own
  order. The engine implements exactly the step kinds this owner's roll-up uses, and no others.

## The job shape (per quote)

A job is the work selected for one quote: a list of lines, each naming an item and supplying **either**
measurements **or** a directly-entered quantity, plus — for a judgement-priced item — the price the
owner set for this line. The quantity source is decided per line by precedence: a quantity entered on
the line is used as-is; otherwise the engine derives the quantity from the line's measurements via the
item's measurement rule. An item with no measurement rule therefore requires an entered quantity (or
its single-unit default). The job also carries the header the issued quote needs (who it is for, the
address, the reference).

## What the generated engine must do

The engine reads one method and one job and produces the priced result. It must:

1. **Resolve each line's quantity** — an entered quantity takes precedence; otherwise derive it from
   the line's measurements via the item's measurement rule — and record which source was used.
2. **Resolve each line's price** — by the item's own rule, or by the per-line figure the owner gave for
   a judgement item — and record which was used.
3. **Group** the priced lines under the owner's own headings.
4. **Run the roll-up** steps in their defined order to reach the final total.
5. **Emit observability** so a wrong figure is diagnosable from the log, not just the document: per
   line, the resolved quantity and its source (measurement-derived vs entered) and the price rule
   applied and its source (item rule vs per-line override); and each roll-up step with its result.
6. **Reconcile** the sum of the group subtotals against the running line-item total and report it as an
   explicit pass/fail — not a silent assumption.
7. **Verify** on demand: given one of the owner's own past jobs, compare every computed figure
   (line, group, final) against the figures the owner actually issued and report each as a match or
   a mismatch.

## Expressiveness — bounded by the owner's history

Build the engine to support **exactly** the quantity, pricing, and roll-up forms the owner's own
history exercises — discovered when their method was captured. Do not add quantity bases, price-rule
forms, or roll-up step kinds the owner does not use. Unused generality is a liability: it is untested
against their figures and invites a wrong quote later. If a new job needs a form the method has never
expressed, that is a change to the captured method (and a re-verification), not a guess made here.

## Acceptance — reproduction of the owner's own figures

The engine is correct only when it **reproduces the owner's own past jobs** — line prices, group
subtotals, and final totals — to the owner's own precision. The fixtures are that owner's
history, supplied with their method; there are no built-in figures to test against. Reproducing their
history, not parsing cleanly, is the signal that the engine prices the way they do. Verify on every
generate and every method change; a reproduction failure blocks issuing a computed quote.

## Boundaries

- **Capturing and maintaining** the content of the method (items, rules, dials, roll-up, past-job
  fixtures) is the method-capture flow — Task 659; it populates the shape this reference defines. This
  reference consumes that method; it does not build it.
- **Rendering** the priced result into the documents the owner issues (internal view, client
  breakdown, branded quote) is Task 658. Those documents are printed to PDF through the existing
  `browser-pdf-save` path (see `references/invoicing.md`); this compute reference produces only the
  figures, not the documents.
