Outcomes and reasons

Two outcomes, a closed set of reasons, and recovery on an axis of its own.

Two outcomes, not four

useful · not_useful

The response either gave the buyer what they wrote down before paying, or it did not.

Earlier releases had four labels — used, retried, discarded, failed — and three of them were answering a different question. Whether you retried, went elsewhere or gave up is what happened after a failure, not a third kind of outcome. Collapsing that back into two is what makes the arithmetic work: cost per useful result is spend divided by the count of useful, and everything spent reaching not_useful is waste, however it was recovered.

unlabeled is a third state but not an outcome. It is the state before a judgment, kept distinct so an unjudged call is never counted as a judgment either way.

Sending an old label is refused by name

The wire schema went from 1 to 2 at this change. A submission carrying used or discarded is told what replaced it rather than handed a bare "invalid option", and a "schema": 1 body is refused outright rather than read under the new vocabulary — the old labels do not map onto the new ones without inventing a reason nobody recorded.

Reasons

no_response · empty · malformed · wrong · stale · insufficient

Required on not_useful. Refused on useful — "it worked" is not a finding about anything, and storing one would be noise.

A closed set, so reasons aggregate across thousands of calls instead of each describing one.

ReasonThe response…
no_responsenever arrived
emptyarrived with nothing in it
malformedwas not the shape it promised
wrongwas well-formed and incorrect
stalewas correct once
insufficientwas correct and not enough to use

wrong, empty and malformed are kept apart deliberately. The difference between an endpoint that is broken and one that is lying is a different fact about a seller, and a single failure rate throws it away.

Recovery

none · retried_same · went_elsewhere · abandoned

What the buyer did next. Optional everywhere, and never an outcome: retrying and going elsewhere are both recovery from the same failure, and both cost money.

Keeping this on its own axis is what lets you ask the question that actually matters — not just how often an endpoint fails, but what its failures cost you in second attempts.

Notes

note is free text, up to 500 characters, alongside the code rather than instead of it. It carries the specifics without widening the closed set.

`note` and `taskClass` are published verbatim

Both are sent as written when review posting is on. Keep them generic; never put a customer name, an internal identifier, a prompt or a key in either. See Privacy.