Skip to content

refactor(cli): convert beads verdict os.Exit calls to typed exit-error (ag-x22j #beads-exit-as-typed-error)#769

Merged
boshu2 merged 2 commits into
mainfrom
refactor/ag-x22j-beads-exit-error
Jun 6, 2026
Merged

refactor(cli): convert beads verdict os.Exit calls to typed exit-error (ag-x22j #beads-exit-as-typed-error)#769
boshu2 merged 2 commits into
mainfrom
refactor/ag-x22j-beads-exit-error

Conversation

@boshu2
Copy link
Copy Markdown
Owner

@boshu2 boshu2 commented Jun 6, 2026

What

ao beads verify|lint|audit used exit-code-as-verdict but signalled it by calling os.Exit(1) inside RunE. os.Exit skips deferred cleanup (temp files, lock release) and kills the test binary, so the verdict branches were untestable.

This converts the 3 sites to return a typed *beadsExitError, which Execute() maps to the process exit code at the single root exit point — the established CLI idiom (mirrors gateExitError in validate.go and doctorExitError in doctor_surface.go).

Sites converted

  • runBeadsVerify (beads.go) — stale citations → exit 1
  • runBeadsLint (beads.go) — stale beads → exit 1
  • runBeadsAudit (beads_audit_cluster.go) — --strict + flagged → exit 1

How

  • New beadsExitError{code} type (Error() empty, ExitCode()), since the verdict text already went to stdout.
  • The returning RunE sets cmd.SilenceErrors (nil-guarded) so cobra prints no spurious Error: line; genuine errors returned elsewhere in those commands still print normally.
  • Execute() gains a beadsExitError branch before the generic fallback.

Evidence

  • cli/cmd/ao/beads_exit_test.go — pins the verdict contract: verify + lint stale → *beadsExitError exit 1 + SilenceErrors; clean → nil; nil-cmd no panic.
  • cd cli && go build ./... && go vet ./cmd/ao/ clean; gofmt -l clean.
  • Full go test ./cmd/ao/9314 passed.

Bead

ag-x22j (P3, child of the Go idiomatic audit ag-tcf0). No more os.Exit outside main/root in the beads command paths.

Closes-scenario: ag-x22j#beads-exit-as-typed-error
Bounded-context: BC5-Runtime
Evidence: cli/cmd/ao/beads_exit_test.go

…r (ag-x22j #beads-exit-as-typed-error)

The `ao beads verify|lint|audit` commands called os.Exit(1) mid-RunE to
signal a stale/flagged verdict. os.Exit skips deferred cleanup (temp files,
lock release) and kills the test binary, leaving those verdict paths
untestable.

Introduce a typed *beadsExitError that the command returns (mirroring
gateExitError/doctorExitError); Execute() maps it to the process exit code at
the single root exit point. The returning RunE sets cmd.SilenceErrors so cobra
emits no spurious "Error:" line, while genuine errors elsewhere in those
commands still print normally. A nil-cmd guard keeps direct callers/tests safe.

Adds beads_exit_test.go pinning the verdict contract (verify + lint stale ->
*beadsExitError exit 1 + SilenceErrors; clean -> nil; nil-cmd no panic).

Closes-scenario: ag-x22j#beads-exit-as-typed-error
Bounded-context: BC5-Runtime
Evidence: cli/cmd/ao/beads_exit_test.go
@github-actions github-actions Bot added the cli label Jun 6, 2026
@boshu2 boshu2 merged commit 2254355 into main Jun 6, 2026
15 of 16 checks passed
@boshu2 boshu2 deleted the refactor/ag-x22j-beads-exit-error branch June 6, 2026 14:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant