ARCNM

Concepts

Audit & provenance

Every quote is re-derivable: cost broken down to the line item, the lot-size curve behind it, drivers ranked by contribution, and the machine it was priced on.

ARCNM quotes are defensible. Every quote comes back with the cost broken down to the line item, the lot-size curve behind it, the cost drivers ranked by contribution, the machine it was priced on and why, and a prediction interval around the number. When a procurement team asks "how did this part get to €12.84?", you answer in 30 seconds, not a week.


What a quote carries

GET /api/v1/calculations/{id} returns the result plus an analytics object with the audit detail. The stable top-level fields (unit_cost, total_cost, setup_cost, currency, status, timestamps) are documented in the Calculations reference; the analytics object carries the breakdown below.

analytics is informational — treat its keys as illustrative and don't hardcode the exact shape. The stable top-level fields are the contract.

{
  "id": "9d3f…",
  "status": "succeeded",
  "unit_cost": 12.84,
  "currency": "EUR",
  "analytics": {
    "cost_decomposition": { /* per-unit cost, line by line */ },
    "time_breakdown":     { "setup_time_s": 42.0, "cycle_time_s": 18.5, "unit_time_s": 19.2 },
    "lot_size_curve":     { "points": [ /* … */ ], "breakpoints": [ /* … */ ] },
    "unit_cost_interval": { "lo": 12.20, "hi": 13.50 },
    "selection":          { "machine_name": "…", "rationale_text": "…" },
    "extraction":         { "feature_count": 23, "pmi_count": 14, "dfm_issue_count": 1, "fusion_conflict_count": 0 },
    "cost_drivers":       { "drivers": [ /* … */ ] },
    "review":             { "needs_human_review": false, "reasons": [ ] }
  }
}

Cost decomposition

cost_decomposition splits the unit cost into the line items that make it up — material_cost, machine_cost, labour_cost, programming_cost, tooling_cost, inspection_cost, finishing_cost — then direct_unit_cost and the overhead_var / overhead_fixed on top. See Cost & lot size.

Lot-size curve

lot_size_curve.points gives the modelled unit cost (unit_cost, in the curve's currency) at each quantity; breakpoints flags the quantities where the unit cost changes slope, each with a plain-language rationale ("setup amortises across the lot at n=50"). A 1-off and a 1000-off can even pick different machines — the breakpoints are where that happens. See Cost & lot size.

Cost drivers

cost_drivers.drivers ranks the features that drive the unit cost. Each carries a rank, the feature_kind (e.g. pocket, hole), a human label, the cost and cost_share it contributes, and reasons. Feed it straight back to your designers as value-engineering: "the four M3 tapped holes are 38% of the cost — relax them and the part drops to €9.10."

Machine selection

selection.machine_name is the machine the part was priced on; selection.rationale_text is the plain-language reason it was chosen.

Prediction intervals

Every quote carries a unit_cost_interval — a lo/hi band the true cost is expected to fall within. It tightens as an environment accumulates calibration evidence (see Calibration & environments). Use the half-width (hi - lo) / 2 to set a margin buffer, or trigger a re-quote when it's too wide for the customer.

Extraction summary & review flags

extraction reports the headline counts a buyer acts on — feature_count, pmi_count, dfm_issue_count, and fusion_conflict_count (how many fields the 3D model and the 2D drawing disagreed on). review.needs_human_review is true when the extraction or the price warrants a human look, with reasons in plain language — gate your auto-accept on it. See Extraction.


Immutability

Every successful calculation row is append-only:

  • The analytics field is read-only after the quote completes.
  • Re-running the same part_revision_id + costing_environment_id + lot_size + material is not idempotent — it creates a new Calculation row with a new id, so calibration changes stay visible.
  • The previous row stays accessible by id forever.

For "the price as it was on 2026-05-28" queries, persist the calculation_id in your ERP and re-fetch from us — we keep them.