Docs / The method / Axial coding
Axial coding
Axial coding is the consolidation pass. Dozens of individual observations become a handful of named failure modes with defined boundaries, which is the vocabulary the rest of the product measures with.
What an axial code is
An axial code is a named failure mode. It is the unit everything after this point is built on: monitoring watches axial codes, the dashboard charts axial codes, the report is organised by axial codes.
A complete axial code has:
- A name that a colleague who was not in the room could apply correctly.
- A scope, meaning an explicit statement of what is in and what is out.
- The open codes assigned to it, which are the cases the name has to cover.
How it works in the product
The Axial coding view splits into Suggested axial codes and Confirmed axial codes. Zoroval classifies each approved open code against the vocabulary you already have, and reuse is the default: it selects an existing confirmed code where one captures the same underlying failure, falls back to a pending suggestion where that fits instead, and proposes a new code only when neither does. Ambiguous open codes are returned for review rather than forced into a category. You decide what survives.
- Review the suggestionsEach suggestion arrives with the open codes that produced it, so you can read the underlying evidence before deciding anything. Traces are marked
Needs axial codinguntil their codes have been placed. - Confirm, reject, or re-scopeConfirm a grouping that matches a real failure. Reject one that does not. Most of the value is in the third option: keep the grouping but rewrite the name so the boundary is explicit.
- Pick or type a codeAssign individual open codes to a confirmed axial code, either by picking an existing one or typing a new one. Rejected suggestions can be restored later if the same pattern comes back.
- Stop at a short listA first taxonomy of five to twelve confirmed codes is healthy. Thirty means the boundaries are too fine to hold, and nobody will remember them.
Naming, and the scope trap
The name is not a label, it is the definition. Everything downstream, including the judge, works from it.
| Weak name | Stronger name | What changed |
|---|---|---|
| Bad output | Answered in prose where the response contract requires JSON | Names the observable condition, so two people label it the same way. |
| Hallucination | Cited an external source with no supporting material in the trace | Bounds it to something checkable from the trace alone. |
| Token efficiency bad | Token efficiency bad, image prompt only | Carries its own scope, so the scope cannot be quietly dropped. |
A code whose scope lives in someone's head rather than in its name will drift. The qualifier gets quietly dropped, the code starts firing on cases it was never meant to cover, and the rate climbs. It looks exactly like a regression in your agent, and it is not.
The fix is in the name. Write the boundary into it, so a case that looks similar but sits outside the scope is visibly outside it.
When a code is ready to monitor
- Two people can apply the name to the same ten traces and agree.
- Its scope is written into the name, not carried in somebody's head.
- Its evidence points at real operations, not at framework wrappers.
- Somebody on the team would change something if the rate went up.
Codes that fail one of these are worth keeping in the taxonomy as vocabulary. They are just not worth spending a monitoring slot on. See Monitoring.