Command reference
oko failures scan
Reads every harness transcript on this machine written since the last pass started, keeps each call that failed, timed out or was refused, and records a defect for each failed product command — so a failure is never only in a transcript. The standing routine call-failures (action `failures`) runs it every minute under Stado; nobody needs to run it by hand.
Invocation#
oko failures scan [--since TIME] [--json]Inputs and options#
- The transcripts are the ones `oko telemetry` reads: every harness root of the agent catalogue (OMP, Claude Code, Codex and the others it declares). Each transcript is read from the byte its last reading stopped at; a call asked before that byte and answered after it waits as pending; a transcript shorter than where its reading stopped was rewritten and is read again from its start, its failures matched by id so none is kept twice.
- A call is kept when its harness marks the result an error: OMP's `isError`, Claude Code's `is_error`, a Codex shell result whose `metadata.exit_code` is not zero. It is timed out when OMP's `details.timedOut` says so; refused when the error states no exit where the harness states one for a call that ran — OMP's empty `details`, a Claude Code result without its opening `Exit code N` line (a hook or the permission check answered first); and failed otherwise, with the exit status the harness states.
- The line that says what failed is the product's failure primitive line (`failure_point=… error_code=… detail=…`) when the output has one, else its last `Error: ` line, else its last line other than the harness's own exit notice (OMP's `Command exited with code N`, Claude Code's `Exit code N`).
- --since TIME (RFC 3339) reads transcripts changed since then instead of since the last pass; without a last pass and without --since, the pass reads what is written from now on. On the first pass, what --since reads from before the pass started is kept and held as answered before the intake started.
- The register is OKO_CALL_FAILURES_REGISTER, else call-failures.json beside the defect register (`<defects>.call-failures.json` when OKO_DEFECT_REGISTER moves it); each call's whole output is kept, owner only, in the call-failures directory beside it (`oko failures location`).
Output and state effect#
- The command path of a shell call is the last command of its line whose program a product of Stado's catalog installs (`stado product catalog --json`, its ids and installed binaries), with its leading command words: `stado host gates`, `oko defects record`. That product owns the failure.
- A failed or timed-out product command answered after the intake started is recorded as a defect of its product through the defect register, written unsorted (`written unsorted by Oko: …`): its title `` `<path>` failed: <line> `` (or `ran past its harness's limit`), its surface the command path, its evidence the session, transcript, time, command, exit status, line and where the whole output is kept, and its completion criterion that the command no longer fails this way on an installed revision. A later failure with the same command path and line in the same session is linked to that defect; one in another session is recorded again, which the defect register keeps as an observation of the open defect; one whose defect was withdrawn is linked to it.
- Prints `read <n> transcripts since <time>: <n> failed calls kept, <n> linked to defects`, then `which product a command belongs to is not known this pass: <cause>` when Stado's catalog did not answer, and `unread: <cause>` per transcript not read. --json prints {register, since, transcripts, failures, defects, catalog, unread}.
- The failed product commands since the progress window's start also enter the failure stream of `oko work progress` as `product-command` events about their defect, charged to no session, so the work queue weighs a defect by how many failures it carries.
Refusals and safe exits#
- Kept and recorded as no defect, each with its cause on the failure: a refused call (`a gate refused the call before its tool ran; the refusal is the gate's answer, not a product's failure`); a failure answered before the register's first pass (`it was answered before the intake started at <time>; `oko failures defect <id>` records it`); a command no catalog product installs (`no program of Stado's product catalog ran it`); a declared answer (`oko failures designed`).
- Kept and tried again on the next pass: Stado's catalog did not answer (`which product's program ran it is not known yet: Stado's product catalog did not answer: <cause>`), and the defect register refused the record (`the defect register refused it: <cause>`).
- A --since that is no RFC 3339 time and any other flag (exit 2); an unreadable register refuses with its path and cause.