Skip to content

feat: v0.4.0 — security audit + UX pass#1

Merged
subinium merged 1 commit intomainfrom
release/v0.4.0
Apr 16, 2026
Merged

feat: v0.4.0 — security audit + UX pass#1
subinium merged 1 commit intomainfrom
release/v0.4.0

Conversation

@subinium
Copy link
Copy Markdown
Owner

Summary

  • Security audit pass: fixed 13 findings across the risk gate, content filter, and subprocess handling. Full changelog in CHANGELOG.md.
  • UX pass: added hey doctor, hey init <shell>, stdin prompts, EOF-aborts-confirm, stricter Warn prompts, stdout-not-TTY refusal, richer help and error messages.
  • 19 new unit tests for the risk gate.

Highlights

Before (v0.3) After (v0.4)
echo hi $(rm -rf ~) → Safe (bypass) Block
grep rm logfileBlock (false positive) Safe
hey foo < /dev/null → runs silently on EOF Aborts with aborted (no input)
hey foo | head → hangs forever Errors with --yes/--dry-run hint
sudo rm -rf / wrapped in sh -c and $(..) → Safe Block in all tested forms
/tmp/ait-codex-<pid>.txt (world-readable, symlink-attackable) tempfile::NamedTempFile (O_EXCL, 0600)
Codex prompt visible in ps auxww Piped via stdin
OpenRouter response body unbounded 1 MiB cap
ANSI escapes in model output printed verbatim (OSC-52 clipboard injection) Stripped before display
hey doctor missing New subcommand

Breaking changes

  • or shorthand for openrouter removed (it collided with the English preposition).
  • Backend subcommand matching is now case-sensitive lowercase.
  • Risk::Warn commands no longer run on blank Enter; explicit y required.
  • EOF on the confirm prompt aborts instead of running.
  • hey foo | head refuses without --yes / --dry-run.

Test plan

  • cargo clippy --all-targets -- -D warnings — clean
  • cargo test — 19/19 risk-gate tests pass
  • cargo build --release — clean
  • hey doctor renders the full diagnostic report
  • hey init zsh emits a valid zsh completion script
  • hey grep for rm in logs → Safe (was wrongly Block in v0.3)
  • hey foo | cat → errors with stdout-not-TTY hint
  • hey with no args → friendly empty-prompt error
  • sk-or-v1-**** key masking confirmed in hey doctor

Notes

  • Crate name stays ai-in-terminal; binary is hey.
  • cargo publish --dry-run succeeded for 0.4.0.

Security (13 findings):
- Risk gate rewrites subshells, process substitutions, and backticks as
  segments so inner destructive calls no longer bypass the Block gate.
- Block whitespace/IFS obfuscation, interpreter -c, decoded-shell pipes,
  truncate / :>file / cp /dev/null, destructive git plumbing.
- Fix rm false positive — only block when rm is a command-position first
  token; grep rm and find -name 'rm*' are Safe again.
- Expand content filter: GitHub fine-grained PATs, Stripe, SendGrid, HF,
  JWT, Google service account JSON, Azure, URL-embedded credentials.
- Codex tempfile -> tempfile::NamedTempFile with O_EXCL + 0600 + auto-drop;
  prompt passed via stdin instead of argv so it's not visible in ps.
- 1 MiB HTTP response size cap on OpenRouter + Anthropic direct API.
- Strip ANSI escapes from model/backend output before printing.
- hey doctor masks key body to the documented prefix only.

UX:
- hey doctor / hey init <shell> subcommands.
- Stdin prompt: echo ... | hey --yes.
- EOF on confirm aborts instead of running.
- Warn commands require explicit y; blank Enter aborts.
- Refuse silent hangs when stdout is not a TTY.
- Edit action copies command to clipboard and reports success/failure.
- Richer help + actionable error messages.
- Thinking animation erases wrapped lines cleanly on narrow terminals.

Breaking: or alias removed; backend matching is case-sensitive lowercase;
Warn no longer defaults to Yes; EOF aborts; piped stdout requires --yes or
--dry-run.

19 unit tests for the risk gate; clippy -D warnings clean.
@subinium subinium merged commit 223a0d9 into main Apr 16, 2026
1 check passed
@subinium subinium deleted the release/v0.4.0 branch April 16, 2026 16:27
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