Reference
Exit codes
Five codes, spoken by every verb. The distinction that matters in scripts and CI: 3 means the tree is unsound, 4 means the tool understood you perfectly and is refusing.
Every rcf verb exits with one of five codes. CI steps and scripts can branch on them safely; the codes are part of the CLI's contract.
0: success
The verb did its job. Note that for the audit and validate verbs, "success" describes the run, not necessarily a clean bill of health in every mode: a clean rcf define validate exits 0, and so does a plain rcf audit coverage that reports gaps, because reporting is its job. It is --strict that turns a gap into a refusal.
1: unexpected failure
The crash class: an input/output failure or an error the verb did not anticipate, a file that cannot be read, a filesystem that refuses a write. If you meet a 1 reproducibly, that is a bug report worth filing.
2: usage
The command line itself is wrong: a misspelled verb, a missing argument, a flag the verb does not take. Also returned when a verb cannot run where it was invoked, such as a tree verb outside an initialised project, or when rcf init finds an existing config file it cannot parse and refuses to modify it.
3: the tree is unsound
Structural failure in the documents: a schema violation, a reference that resolves to nothing, or a required piece of the chain that is absent. rcf define validate exits 3 and lists the issues whenever the tree is broken. The same code backs refusals that are really soundness findings, such as marking a work item complete while an in-scope acceptance criterion has no source file recorded against it.
4: refused
The tool understood the request completely and is declining it, by design. The lifecycle refuses backward transitions (a work item cannot slide from inProgress back to notStarted); the everyday mark command refuses to write verified, which only the finalise gate may do; and rcf audit coverage --strict refuses while any acceptance criterion in scope lacks a test whose pointer resolves. A 4 is never a malfunction: it is the referee doing its job, and the right response is to change the work, not the command.
All five behaviours above are checked against rcf-lite as installed in this site's own build tree. The forward-only lifecycle behind the refusal examples is explained in the five-stage build cycle.