ADR-018: sysexits Exit Codes

Status

Accepted

Supersedes the exit-code note in ADR-002 (the “exit status 2 (usage error)” clause). ADR-002’s remaining I/O-separation and flag-constraint decisions stay in force.

Date

2026-08-05

Context

ADR-002 defined strict UNIX/GNU CLI conventions and stated that the Tier-3 ambiguous-install fallback fails with “exit status 2 (usage error)”. In practice stamp exited 1 for every failure — the Exit* sysexits constants were defined in root.go but never wired. Consequences:

Decision

Adopt BSD sysexits.h codes (shipped by glibc on Linux) for error categories, with 1 as the catchall for unclassified failures.

Mechanism

Mapping

Category Code Constant
ErrUsage (bad flag/argument) 64 EX_USAGE
ErrData (corrupt input) 65 EX_DATAERR
ErrNoInput (referenced input absent) 66 EX_NOINPUT
ErrUnavailable (manager/resource absent) 69 EX_UNAVAILABLE
ErrCanTCreate (cannot create output) 73 EX_CANTCREAT
ErrConfig (unconfigured/misconfigured) 78 EX_CONFIG
unclassified 1 (POSIX catchall)

Backup/rotation failures on reconcile and init are non-fatal (warning to stderr, exit 0).

Alternatives Considered

Keep ADR-002’s “exit status 2” for usage errors

Call os.Exit(code) at each error site

Classify by matching error strings at the boundary

Consequences