1. Work happens somewhere else
A coding harness, your agent loop, or any system that can emit OpenTelemetrygen_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
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. The store is tamper-evident, not immutable
From 0.49.0 each new span and turn is also a row in a hash-linked log. A lazy edit of one hashed field failsassay verify.
That is chained. Someone who owns the file can still rebuild every hash. An outside witness of the latest head is what makes a rewrite detectable by a third party. That grade is anchored. Assay never prints anchored for an unwitnessed chain, or for a pending OpenTimestamps calendar receipt.
Empty new stores write genesis on first open. A store that already had rows needs assay seal --yes. See Integrity.
6. 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.7. 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.