Profile Reference¶
--profile prints a per-call breakdown of a review: where the time went, what
each lens spent, and what it produced. --profile-json PATH writes the same
data as JSON.
Parse the JSON, not the table. The table's layout is not a contract and may
be restyled; the JSON payload carries a schema_version precisely so it can be
pinned against.
Which stream the table uses¶
The table goes to stdout for a human-format review, and to stderr when
the findings themselves are machine-readable (--format json, --format agent,
--json). stdout carries the deliverable, so it stays parseable — the same rule
the billable-token footer follows.
--profile-json writes to a file, so it never collides with either stream
whatever the output format is. An unwritable path is logged and skipped: a
review that produced findings is not lost to a diagnostic file.
The table's columns¶
| column | meaning |
|---|---|
call |
the lens id, or a stage label like reflect, triage, repair:<lens> |
batch |
which batch of files the call covered |
tries |
requests actually issued, including adapter retries |
elapsed |
wall time for the call |
in_tok |
prompt tokens |
out_tok |
completion tokens |
think_tok |
reasoning tokens, when the route reports them |
think_% |
reasoning tokens as a share of the max_tokens ceiling |
cache_rd |
prompt-cache tokens read |
cache_wr |
prompt-cache tokens written |
findings |
findings parsed from this call |
error |
the failure reason, when the call failed |
The models: line¶
A run whose calls were all answered by the same model says nothing. When a
second model answered any of them — fallback_model, whether the engine
escalated a truncation to it or the adapter switched on its own — a summary line
under the table names each model and how many calls it took:
models: luna (7 calls), sonnet (1 call)
There is no per-call model column: it would repeat one string down the whole
table. The per-call value is in the JSON payload and in the structured
provider call log line, omitted where the adapter reports no model.
What - means¶
A dash is unknown, never zero.
think_tok is a dash when the route reported no reasoning breakdown. That is
deliberate: 0 would assert the model did no thinking, and nobody said that.
think_% is a dash when there is no ceiling to be a share of, and findings is
a dash for a call that does not produce review findings at all — distinct from a
call that produced none, which shows 0.
This is the distinction that breaks naive parsers: int(row["think_tok"])
raises on a dash. In the JSON payload the same value is null.
The JSON payload¶
{
"schema_version": 1,
"wall_seconds": 12.4,
"total_tokens": 41231,
"returned_findings": 3,
"stages": [{"name": "redact", "elapsed": 0.01}],
"calls": [
{
"label": "security",
"batch": 1,
"attempts": 1,
"elapsed": 8.2,
"input_tokens": 36918,
"output_tokens": 1286,
"reasoning_tokens": null,
"reasoning_share": null,
"output_ceiling": null,
"cache_read_tokens": 0,
"cache_creation_tokens": 0,
"findings": 2,
"error": null
}
]
}
Notes:
reasoning_tokens,reasoning_share,output_ceiling,findingsanderrorarenullwhen unknown or absent — the JSON counterpart of the table's-.reasoning_shareis the raw ratio the table rounds intothink_%.total_tokensisinput + outputacross all calls. Cache counters are deliberately excluded: routes disagree on whether a cached read is already inside the prompt count, so adding them would double-count on some and not others.returned_findingsis the count after the whole pipeline, which may be lower than the calls' parsed total once dedupe, reflection and filtering have run.
Stability¶
schema_version is bumped when the payload's shape changes in a way a pinned
consumer would notice. Adding a field is not such a change; removing one or
altering what it means is.