Skip to content

fix(builtins): --help must exit 0 for help, break, and continue#150

Closed
thieman wants to merge 3 commits intomainfrom
thieman/fix-help-exit-codes
Closed

fix(builtins): --help must exit 0 for help, break, and continue#150
thieman wants to merge 3 commits intomainfrom
thieman/fix-help-exit-codes

Conversation

@thieman
Copy link
Copy Markdown
Collaborator

@thieman thieman commented Mar 25, 2026

Problem

RULES.md requires: "When --help is passed: Print a usage line to stdout, set exit code 0 and return."

Three builtins violated this:

P-1: help --help exited with code 1

The help builtin's --help path returned Code: 1. Should be 0.

P-2: break --help and continue --help exited with code 2

Both builtins returned exit code 2 when --help was passed. Should be 0.

Fix

All three builtins now return builtins.Result{} (exit code 0) on the --help path. Help output continues to go to stdout.

Also updated existing scenario tests for break_help and continue_help (in tests/scenarios/shell/for_clause/break_cont/) to reflect the corrected exit code, and added skip_assert_against_bash: true since bash's built-in break/continue don't support --help. New cmd/break/ and cmd/continue/ scenario directories added with help_flag.yaml tests.

Test plan

  • help --help exits 0 with usage printed to stdout
  • break --help exits 0 with usage printed to stdout
  • continue --help exits 0 with usage printed to stdout
  • Normal operation of all three commands is unchanged
  • go test ./tests/... -run TestShellScenarios passes

🤖 Generated with Claude Code

…inue

Per RULES.md: when --help is passed, commands must set exit code 0.

- help --help: was exiting 1, now exits 0
- break --help: was exiting 2, now exits 0
- continue --help: was exiting 2, now exits 0

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown
Collaborator Author

@thieman thieman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Summary

This PR fixes --help exit codes for three builtins (break, continue, help), all of which were returning non-zero on --help despite RULES.md requiring exit 0. The changes are focused, correct, and do not touch any security-sensitive code paths.

Overall assessment: safe to merge, with one P2 finding (pre-existing RULES.md violation surfaced by this change) and two P3 observations.


Bash compatibility verification

Bash exits 2 for --help on all three builtins (break --help, continue --help, help --help). The PR diverges intentionally to satisfy the RULES.md requirement of exit 0 for --help. All affected scenario tests now carry skip_assert_against_bash: true, which is the correct mechanism for documenting intentional divergence.


Coverage Summary

Code path Scenario test Go test Status
break --help exits 0 (outside loop) tests/scenarios/cmd/break/help_flag.yaml Covered
break --help exits 0 (inside loop) tests/scenarios/shell/for_clause/break_cont/break_help.yaml Covered
continue --help exits 0 (outside loop) tests/scenarios/cmd/continue/help_flag.yaml Covered
continue --help exits 0 (inside loop) tests/scenarios/shell/for_clause/break_cont/continue_help.yaml Covered
help --help exits 0 tests/scenarios/cmd/help/help_flag.yaml Covered
break -h / continue -h (short form) Not covered (pre-existing gap)

Coverage status: Adequate for the changes in this PR. The -h short-form gap is pre-existing and noted as a P2 finding.


Findings

# Priority File Finding
1 P2 Badge builtins/break/break.go:45, builtins/continue/continue.go:45 -h short form not handled; RULES.md requires both -h and --help
2 P3 Badge builtins/break/break.go, builtins/continue/continue.go Package doc comments do not mention --help exit code
3 P3 Badge tests/scenarios/cmd/break/help_flag.yaml, tests/scenarios/cmd/continue/help_flag.yaml stdout_contains check is very loose; would not catch help output being silently swapped

Positive observations

  • The fix is minimal and surgical — only the exit code return values are changed, no logic restructuring.
  • All three affected scenario tests correctly add skip_assert_against_bash: true to document intentional bash divergence.
  • The package doc comment in builtins/help/help.go is correctly updated to reflect the new exit code semantics.
  • No security-sensitive code paths (sandbox, file access, command execution) are touched.
  • No new imports introduced.

Comment thread builtins/break/break.go Outdated
Comment thread tests/scenarios/cmd/break/help_flag.yaml Outdated
Comment thread tests/scenarios/cmd/continue/help_flag.yaml Outdated
…tions

- Add -h as an alias for --help in break and continue run() functions
- Tighten stdout_contains in help_flag.yaml from generic command name
  to the specific usage line ("break: break [n]" / "continue: continue [n]")
- Add help_flag_short.yaml scenario tests for -h short form for both commands

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@thieman
Copy link
Copy Markdown
Collaborator Author

thieman commented Mar 25, 2026

@codex review this PR

Copy link
Copy Markdown
Collaborator Author

@thieman thieman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Summary

This PR fixes the exit code returned by break --help, continue --help, and help --help — all three now return 0 instead of 1 or 2. It also adds -h as a short alias for --help in break and continue, and adds new scenario tests.

The changes are small, clean, and well-structured. No security or correctness issues found.

Overall assessment: needs minor discussion — one P2 finding about intentional bash divergence not being documented per project policy.

# Priority File Finding
1 P2 Badge builtins/break/break.go:47, builtins/continue/continue.go:47, builtins/help/help.go:47 Exit code 0 for --help diverges from bash (which returns 2); skip_assert_against_bash: true added without documenting intentional divergence
2 P3 Badge tests/scenarios/shell/for_clause/break_cont/break_help.yaml Scenario tests that were previously bash-compatible now have skip_assert_against_bash: true; could instead test via cmd/break/ scenarios only

Coverage table

Code path Scenario test Go test Status
break --help exits 0 tests/scenarios/cmd/break/help_flag.yaml Covered
break -h exits 0 tests/scenarios/cmd/break/help_flag_short.yaml Covered
continue --help exits 0 tests/scenarios/cmd/continue/help_flag.yaml Covered
continue -h exits 0 tests/scenarios/cmd/continue/help_flag_short.yaml Covered
help --help exits 0 tests/scenarios/cmd/help/help_flag.yaml Covered
break --help inside loop (loop continues) tests/scenarios/shell/for_clause/break_cont/break_help.yaml Covered
continue --help inside loop tests/scenarios/shell/for_clause/break_cont/continue_help.yaml Covered

Positive observations

  • The change is minimal and surgical — only the return codes and short alias are modified.
  • New scenario files correctly use stdout_contains (not exact match) for help text, which is robust against minor text changes.
  • Both --help and -h are now consistently handled, matching the convention used by other builtins.
  • Existing loop-context scenarios are updated to match the new behavior.

Comment thread builtins/break/break.go
Comment thread builtins/continue/continue.go
Comment thread builtins/help/help.go
Comment thread tests/scenarios/shell/for_clause/break_cont/break_help.yaml
@thieman
Copy link
Copy Markdown
Collaborator Author

thieman commented Mar 25, 2026

Iteration 1 self-review result: 3 findings (0x P0, 0x P1, 2x P2, 1x P3).

Summary: The PR is clean from a security and correctness standpoint. The main concern is that exit code 0 for break --help, continue --help, and help --help diverges from bash (which returns exit code 2), and this divergence is masked by skip_assert_against_bash: true without being explicitly documented as intentional per project policy. P3 note about removing bash-compat verification on the loop-context scenario.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f68d52d6c6

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread builtins/help/help.go
…bash divergence

- Update TestHelpFlagPrintsUsage to assert exit code 0 (was 1) to match
  the implementation change in this PR (help --help now exits 0 per RULES.md)
- Add explanatory comments to all skip_assert_against_bash: true scenario
  files documenting the intentional divergence from bash exit code 2, citing
  RULES.md as the authority for exit code 0 on --help

Fixes: chatgpt-codex-connector[bot] finding that Go test still expected exit 1
Addresses: self-review P2 findings about undocumented bash divergence

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@thieman thieman closed this Mar 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant