stella CLI — exit-code convention
This is the one table CI authors need. It defines the CLI-wide exit-code convention and records which command families conform to it today versus which are scheduled for the P2 migration wave.
The convention (canonical triad)
Adopted from stella sbom check and encoded in src/Cli/StellaOps.Cli/Commands/CliExitConvention.cs:
| Code | Meaning | CI action |
|---|---|---|
0 | Ok — success, no actionable findings. | proceed |
1 | Findings — the command ran successfully but produced actionable findings / a policy breach (a gate that says “no”, vulnerabilities at or above a threshold). This is not an error. | stop (or override per policy) |
2 | UsageError — the command could not be completed: bad arguments, missing/invalid input, I/O or network failure, unparseable response. | fix invocation / environment |
10–98 | Family extension band — family-specific outcomes and granular error causes, documented per family below. | see family row |
99 | UnknownError — unexpected/unhandled failure. | investigate |
System.CommandLine parser failures are normalized at the process invocation boundary to UsageError (2). This includes missing required arguments/options and malformed or unknown arguments. The parser still prints its normal diagnostic and usage text. --help and --version remain successful (0), and exit codes returned by valid command handlers are not remapped.
Rule of thumb for a CI author who only needs pass/fail: key on exit == 0 (ok) vs exit != 0 (attention needed). Read the family band only when you need to branch on the specific cause.
Conforming families (first wave)
| Family | Command(s) | 0 | 1 | 2 | Family band (10–99) |
|---|---|---|---|---|---|
sbom check (reference) | stella sbom check | ok | findings ≥ --fail-on | usage/IO error | — |
| Gate | stella gate evaluate | pass | block (findings) | input/usage error | 10 warn (advisory), 11 network, 12 policy-eval, 99 unknown |
| Score gate | stella gate score evaluate, … batch | pass | block (findings) | input/usage error | 10 warn (advisory), 11 network, 12 policy-eval, 99 unknown |
The gate/score process exit code is derived from the gate outcome (GateExitCodes.FromStatusName / ScoreGateExitCodes.FromActionName), so the CLI presents a convention-compliant code regardless of the numeric code the policy engine returns. A gate warn is advisory and exits 10 (non-blocking); a block exits 1.
Breaking change (call out in release notes). For
gate/scorethe block code moved2 → 1, the input-error code moved10 → 2, andwarnmoved1 → 10. CI scripts that testedexit == 2for “blocked” must switch toexit == 1. See the sprintSPRINT_20260703_002Decisions & Risks for theSTELLA_LEGACY_EXIT_CODESdiscussion.
Non-conforming families (deferred to the P2 CLI wave)
These still use their historical schemes. They are documented here so CI authors know the current reality; migrating them onto the triad is the P2 batch (see the sprint Decisions & Risks). Values below are the current registered codes.
CliExitCodes — general CLI (src/Cli/StellaOps.Cli/Commands/CliExitCodes.cs)
0 success · 1 input-file-not-found · 2 missing-required-option · 3 service-not-configured · 4 signing-failed · 5 verification-failed · 6 policy-violation · 7 file-not-found · 8 general-error · 9 not-implemented · 99 unexpected · 100 doctor-failed · 101 doctor-warning.
ChangeTraceExitCodes — stella change-trace (ChangeTraceExitCodes.cs)
0 success (risk-down/neutral) · 1 error · 2 risk-up · 3 inconclusive · 4 file-not-found · 5 validation-failed · 6 service-unavailable.
DriftExitCodes — reachability drift (DriftExitCodes.cs)
Benign: 0 no-change · 1 info-drift · 2 hardening. Blocking (IsBlocking): 3 KEV-reachable · 4 affected-reachable · 5 policy-blocked · 6 hardening-regression. Errors: 10 input · 11 analysis · 12 storage · 13 policy · 14 network · 99 unknown. (Not yet wired to a live scan drift command — the constants are documented here and in the class doc.)
OfflineExitCodes — stella offline … (OfflineExitCodes.cs)
0 success · 1 file-not-found · 2 checksum-mismatch · 3 signature-failure · 4 format-error · 5 DSSE-verify-fail · 6 Rekor-verify-fail · 7 import-failed · 8 version-non-monotonic · 9 policy-denied · 10 selftest-fail · 11 validation-failed · 12 verification-failed · 13 policy-load-failed · 130 cancelled (SIGINT).
ProofExitCodes — stella proof … (Proof/ProofExitCodes.cs)
0 success · 1 policy-violation · 2 system-error · 3 verification-failed · 4 trust-anchor-error · 5 Rekor-verify-fail · 6 key-revoked · 7 offline-mode-error · 8 input-error.
P2 migration batch (deferred)
Converge the five non-conforming families above onto CliExitConvention in a later wave: map each family’s success→0, findings/policy-breach→1, usage/IO error→2, and move the remaining codes into the 10–99 family band. This is deliberately deferred because those changes are breaking for existing CI scripts and warrant a coordinated release-notes pass (and a decision on the STELLA_LEGACY_EXIT_CODES escape hatch). Tracked in SPRINT_20260703_002 Decisions & Risks.
