Skip to content

fix(cli): make validation failures consistently return exit code 2 #88

@danielewood

Description

@danielewood

Summary

Validation-failure semantics are inconsistent with documented CLI contract, causing some validation outcomes to return generic error exit code 1 instead of validation exit code 2.

Underlying problems covered by this issue:

  1. bundle chain verification failures return generic errors (1) instead of validation failures (2).
  2. bundle --key mismatch returns generic error (1) instead of validation failure (2).
  3. inspect with only expired certs and default filtering returns generic error (1) instead of validation failure (2).

Why this matters

Automation relies on stable exit semantics. Mixing 1 and 2 for validation outcomes breaks scripts and policy gates.

Evidence

  • Contract docs for exit codes: README.md:292
  • Bundle chain error path: cmd/certkit/bundle.go:109
  • Bundle key mismatch path: cmd/certkit/bundle.go:195
  • Inspect expired-filter error path: cmd/certkit/inspect.go:60
  • Main maps non-validation errors to exit 1: cmd/certkit/main.go:29

Acceptance criteria

  • All validation outcomes listed in CLI contract return ValidationError and exit code 2.
  • bundle and inspect paths above are aligned with verify semantics.
  • Regression tests assert exit codes for chain invalid, key mismatch, and expired validation scenarios.

Suggested approach

  • Normalize these paths to return *internal.ValidationError consistently.
  • Add table-driven command-level tests that assert exit code behavior for documented validation cases.

Dedupe notes

Checked existing issues before creating:

  • gh issue list --state open --limit 200 --json number,title,url,labels -> no open issues
  • gh search issues "is:open repo:sensiblebit/certkit" --limit 100 --json number,title,url,state -> no matches
    Classified as: new.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workinggoPull requests that update go code

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions