30-second answer

Three codes, and the distinction between 1 and 2 is the one that matters in a pipeline.

CodeMeaning
0The command did what it was asked
1The command ran, and the result was negative
2The engine refused to run, or refused to answer

Why 1 and 2 are not the same failure

1 is a result. Rules failed under --fail-on. An assessment did not verify. doctor found something wrong. A collection reached the tenant and failed. In every case the engine did its job and the answer was negative.

2 is a refusal. An argument was missing, a document was not what the command expects, or producing an answer would have meant claiming something the evidence does not support. Nothing was decided.

A pipeline that treats them the same will page somebody about a governance regression when the real problem is a typo in a path. Worse, it will treat a refusal as a clean run when the exit code is inverted somewhere.

Per command

Command1 means2 means
collectThe collection ran and failed. Nothing was written to the tenantA missing argument, or a preflight problem locally
evaluate--fail-on was metEvidence did not match the schema
assessNot usedNo evidence documents, bad evidence, or a manifest that could not be assembled honestly
verifyThe assessment does not verifyThe file is not an assessment
diffA rule left pass, with --fail-on-regressionA document is not an assessment
validateRules have problemsNot used
doctorThe installation has problemsNot used
show-ruleNot usedNo rule with that identifier
reportNot usedThe document cannot be rendered

What to set in CI

evaluate --fail-on unresolved is the strict setting: it counts unknown, invalid-evidence and error alongside fail, so a build cannot go green on evidence the engine could not read.

--fail-on fail counts only outright failures, and leaves unknown for a human to chase.

Neither of them makes 2 less serious. A 2 in a pipeline means the run did not happen.