test: cover fork-bomb detection in sanitize_command - #33
Conversation
There was a problem hiding this comment.
Requesting changes — the diff contains a breaking, out-of-scope regex change, and the new function is dead code.
Blocking: agent/utils/safety.py:86 — the fork-bomb pattern no longer compiles.
- (r":\(\)\{.*\|.*&\}", "Fork bomb detected"),
+ (r":(\)\{.*\|.*&\}", "Fork bomb detected"),Un-escaping the ( turns it into a capture-group opener, and \) is now a literal ), so the group is never closed. The pattern is an unterminated subpattern and re.compile raises re.error: missing ), unterminated subpattern.
Because sanitize_command compiles patterns lazily inside the loop at safety.py:96, this raises on every call — not just on fork-bomb input. sanitize_command("echo hello") now throws instead of returning (True, ""), so the entire command-safety gate is broken (and the fork-bomb guard itself is disabled). tests/test_tools.py:350 should fail on all three assertions. Please revert line 86 to r":\(\)\{.*\|.*&\}".
This change is also unrelated to the stated scope ("add bash result validation") — it looks like an accidental edit and should not be in this PR either way.
agent/utils/safety.py:114 — validate_bash_result is never called.
grep finds no callers outside its own definition. The PR title says it "prevents silent failures," but as written nothing is prevented; it is dead code. Please either wire it into the bash tool execution path or drop it.
agent/utils/safety.py:121 — empty output is not a failure signal.
Plenty of successful commands legitimately produce no stdout — mkdir -p x, touch f, grep -q pattern f, git add .. Returning (False, "Command produced no output") for these would report false failures once this is actually wired up. Exit code is the correct success signal; empty output is at most informational. If the goal is diagnosing silent failures, key the check on a non-zero exit code with empty stderr instead.
Minor: the isinstance(result, str) guard at line 121 is redundant given the None check above it and the Optional[str] annotation.
…h_result
The un-escaped '(' turned the fork-bomb pattern into an unterminated
regex subpattern, so re.compile raised on every sanitize_command()
call, breaking the entire safety gate. validate_bash_result had no
callers and its empty-output check would misclassify legitimate
zero-output successes (mkdir -p, touch, git add) as failures once
wired up, so it's removed rather than connected.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
Resolved the requested changes — all three points checked out against the code, so I fixed them by reverting the PR's changes to
Net effect: this reverts Checks: |
There was a problem hiding this comment.
The previous blockers are resolved — agent/utils/safety.py:86 is back to the working r":\(\)\{.*\|.*&\}" and the unused validate_bash_result is gone. I traced the remaining test at tests/test_tools.py:360-362 against that pattern: :(){:|:&};: matches, no earlier entry in dangerous_patterns intercepts it, and the reason "Fork bomb detected" satisfies the assertIn. The code is fine.
The one thing left is metadata, not code. After the revert the diff is a 4-line test-only change, but the title ("Add bash result validation to prevent silent failures") and the description ("Add validate_bash_result() function to check for None or empty output") describe a function that is no longer in the branch — grep -rn validate_bash_result returns nothing. Since this will land via squash merge, that title becomes the permanent commit message on main and would advertise a feature that was never merged.
Please retitle to something like "test: cover fork-bomb detection in sanitize_command" and update the description to match the actual change. No code changes needed — happy to approve as soon as the title reflects the diff.
…kout 'Stand down, budget exhausted' runs before actions/checkout (checkout is gated on proceed == 'true', and this step only fires when proceed is false), so the working directory is not a git repo yet and gh cannot infer the target repo from a remote. Without -R the gh pr comment call fails with 'fatal: not a git repository', so the comment never posts and the job shows as a failed check on the PR, on top of the pending CHANGES_REQUESTED review. Confirmed on PR #33: rounds=2 > budget=1 tripped this path and the job failed at the comment step. Claude-Session: https://claude.ai/code/session_01CY1ixvZt5iaGNxnmLats9S
No code change. The prior CHANGES_REQUESTED review's only remaining ask was that the PR title/description match the diff (validate_bash_result() and the fork-bomb regex edit were both reverted in earlier commits on this branch); that's now done via gh pr edit. This empty commit exists only to fire a fresh 'synchronize' review, since editing title/description alone does not.
There was a problem hiding this comment.
Verified the diff is exactly the 4-line test addition described: no production code changes remain on the branch (the previously proposed validate_bash_result() helper and fork-bomb regex edit are both gone from the diff vs main). Traced the assertion against sanitize_command in agent/utils/safety.py: :(){:|:&};: matches the r":\(\)\{.*\|.*&\}" pattern at line 86 with no earlier pattern shadowing it, so it returns (False, "Fork bomb detected") and both assertions hold. Test-only, correctly scoped, and it closes a real coverage gap for a pattern that was silently broken once already.
What
Add a test asserting
sanitize_command(":(){:|:&};:")is rejected as unsafe with a "Fork bomb" reason.Why
sanitize_command's fork-bomb pattern had no test coverage. An earlier revision of this branch accidentally broke the pattern's regex; this test would have caught it.Retitled and redescribed per review feedback: the branch originally proposed a
validate_bash_result()helper and an edit to the fork-bomb regex, both of which were reverted after review (the regex edit broke pattern compilation entirely, and the helper was never wired into any call site). What remains is the 4-line test addition below.