Assay is a pipeline with a sealed store in the middle. Nothing in the pipeline edits a written record.

1. Work happens somewhere else

A coding harness, your agent loop, or any system that can emit OpenTelemetry gen_ai traces. Assay is not in that path.

2. Capture records two things

For each unit of work Assay writes:
  • a span — tokens, model, cost, principal, session, task
  • zero or more turns — the conversation lines, scrubbed then sealed
The join key is the sitting (session_id) and, when present, a span_ref from a turn to the span that paid for it. Re-delivery of the same producer event does not create a second span. Capture is safe to run on a timer.

3. Price is a stamp, not a guess

If Assay knows the model, the span carries integer micro-USD and a pricing version. If it does not know the model, the span has no cost. That is not $0.00. Totals keep the unpriced share visible. A later correction is a new row. The original span stays. Every read uses the latest correction when one exists. See Honesty and Pricing.

4. Conversation text has one road

Text reaches the store only after it is scrubbed of common secret shapes, then sealed. It does not land in metadata. It does not leave in a sync batch. It does not ride along in a label note. Search indexes messages and reasoning on the machine. Tool dumps are out of the index by default. See Privacy and Search.

5. Labels attach as overlays

The span is never rewritten. Type, objective, product, scope, valuation, and cost correction are append-only overlays. A reader picks one label per overlay by source rank: declared > judge > heuristic A label you type in the console is declared-family. It outranks a later guess. See Framing and Labelling.

6. Reads never re-invent the number

assay waste, assay roi, assay products, and the dashboard panels call the same reports. The screen is not a second implementation. A static snapshot stamps when it was captured and says the numbers do not update.

What takes money

Not every label is a dollar. Framing is the map. Short version:
  • Episode primary on the objective tree takes spend.
  • Touch does not.
  • Type groups whole-session spend. It is not a second tree.
  • Path product has two named readings: inclusive (upper bound) and weighted (partition).
  • Scope is where writes landed. It is not what the work was for.