Skip to content

command_output: explain the 128+N exit codes a host's pipefail surfaces - #56

Merged
senamakel merged 1 commit into
tinyhumansai:mainfrom
sanil-23:pr/exit-code-hints
Oct 8, 2026
Merged

senamakel merged 1 commit into
tinyhumansai:mainfrom
sanil-23:pr/exit-code-hints

Conversation

@sanil-23

@sanil-23 sanil-23 commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

exit_code_hint covered 127 and 126, so every other status reached the model
as a bare number. That left the signal codes unexplained, and a host that
wraps commands in set -o pipefail produces them constantly: piping a large
output into a reader that closes early (| head, | grep -q,
| sed -n '1,Np') kills the writer with SIGPIPE, and the pipeline reports 141
even though the reader got everything it asked for. In one agent run, 9 of 44
recorded command failures were this, indistinguishable from real ones.

Explain the four conventional statuses, which need opposite responses:

141 SIGPIPE the output above is what the reader accepted and is usually
complete; treat it as data, not an error
137 SIGKILL killed by the OOM killer or a hard timeout; an unchanged retry
is killed again
143 SIGTERM stopped before finishing, so the output is partial
139 SIGSEGV a fault in the program or its input, not in the invocation

Only these and the two existing codes are annotated. An adjacent-looking
status (138, 140, 142) is not a convention and is left alone, as is any
application's own exit code.

(cherry picked from commit 6daae62750c16a6e3e8671273a5e7571a760e85b)

🤖 Generated with Claude Code

…surfaces

`exit_code_hint` covered 127 and 126, so every other status reached the model
as a bare number. That left the signal codes unexplained, and a host that
wraps commands in `set -o pipefail` produces them constantly: piping a large
output into a reader that closes early (`| head`, `| grep -q`,
`| sed -n '1,Np'`) kills the writer with SIGPIPE, and the pipeline reports 141
even though the reader got everything it asked for. In one agent run, 9 of 44
recorded command failures were this, indistinguishable from real ones.

Explain the four conventional statuses, which need opposite responses:

  141 SIGPIPE  the output above is what the reader accepted and is usually
               complete; treat it as data, not an error
  137 SIGKILL  killed by the OOM killer or a hard timeout; an unchanged retry
               is killed again
  143 SIGTERM  stopped before finishing, so the output is partial
  139 SIGSEGV  a fault in the program or its input, not in the invocation

Only these and the two existing codes are annotated. An adjacent-looking
status (138, 140, 142) is not a convention and is left alone, as is any
application's own exit code.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
(cherry picked from commit 6daae62750c16a6e3e8671273a5e7571a760e85b)
@tinysweeper

tinysweeper Bot commented Oct 8, 2026 •

Copy link
Copy Markdown

Tiny Sweeper review

Tiny Sweeper reviewed this change across 6 lane(s) and found 1 active actionable finding(s). Detailed lane evidence and any incomplete work are listed below.

State: Changes requested
Priority: high
Reviewed head: 2f2b698d0e06
Updated: 1791440183 (Unix time)

Review snapshot

Change surface Files Review signal Count
Production 1 Active findings 1
Tests 1 Noted findings 0
Documentation 0 Resolved findings 0
Configuration 0 Pending checks/questions 0

Completeness: Complete
Test assessment: No supported feature-to-test mapping was available; this does not mean tests are absent or passed.

What changed

The review could not produce a supported behavioral summary; inspect the cited changed surface and lane details below.

Features

None identified with supported citations.

Tests

No supported feature-to-test mapping was produced. Test execution is not inferred.

Findings

  • high · critique · Do not infer signals from exit codes alone — `render_command_failure` receives only an integer exit code, so it cannot distinguish a shell's `128 + signal` result from an application that deliberately exits with the same valu (crates/tinytools/src/command\_output/mod\.rs:53)

Before merge

  • Address Do not infer signals from exit codes alone (crates/tinytools/src/command\_output/mod\.rs).

How this fits together

flowchart LR
  n0["render_command_failure"]:::impacted
  n1["command_failure"]:::impacted
  n1 -->|calls| n0
  classDef changed fill:#0d4429,stroke:#238636,color:#e6edf3
  classDef impacted fill:#161b22,stroke:#6e7681,color:#c9d1d9
  classDef flagged fill:#5a1e02,stroke:#d93f0b,color:#ffffff
  classDef blocking fill:#67060c,stroke:#f85149,color:#ffffff
Loading
Agent review details

critique

  • Conclusion: Failure
  • Scope reviewed: all assigned evidence
  • Lane summary: The added hints improve diagnostics for common signal-derived statuses, but they incorrectly treat exit-code conventions as definitive. Because an application can legitimately return 137, 139, 141, or 143 itself, the change can mislead callers into accepting failed output or skipping a needed retry; it is not safe to merge unchanged. _Code retrieval was unavailable (model: ladder embeddings returned 400 Bad Request: {"error":{"message":"unknown ladder vectors; known ladders are flash (also chat-v1, flash-v1), instant (also no-think, instant-v1), reasoning (also deepseek), max-reasoning (also max-reasoning-v1), deepseek-flash (also reasoning-v1, agentic-v1), deep (also luna), scribe, uncensored, vectors-oai3 (also embeddings-oai3-v1), vision (also vision-v1, multimodal-v1), image (also images-v1, image-v1), vi), so this review saw the diff alone._ _Memory was unavailable (model: cortex: v1/recall: error sending request for url (http://cortexdb:3141/v1/recall\)\), so this review ran without it._
  • Evidence: crates/tinytools/src/command\_output/mod\.rs — Do not infer signals from exit codes alone

security

  • Conclusion: Success
  • Scope reviewed: all assigned evidence
  • Lane summary: The change only adds explanatory exit-code hints and tests; it does not introduce a security issue. It looks safe to merge. _Code retrieval was unavailable (model: ladder embeddings returned 400 Bad Request: {"error":{"message":"unknown ladder vectors; known ladders are flash (also chat-v1, flash-v1), instant (also no-think, instant-v1), reasoning (also deepseek), max-reasoning (also max-reasoning-v1), deepseek-flash (also reasoning-v1, agentic-v1), deep (also luna), scribe, uncensored, vectors-oai3 (also embeddings-oai3-v1), vision (also vision-v1, multimodal-v1), image (also images-v1, image-v1), vi), so this review saw the diff alone._ _Memory was unavailable (model: cortex: v1/recall: error sending request for url (http://cortexdb:3141/v1/recall\)\), so this review ran without it._

tests

  • Conclusion: Success
  • Scope reviewed: all assigned evidence
  • Lane summary: The change extends `exit_code_hint` with four signal-convention codes, and the new tests exercise each one through the real render path with assertions that would fail if a hint were dropped or misplaced, including a negative test that adjacent codes stay uneditorialised. The tests earn their keep; the change looks sound. _Code retrieval was unavailable (model: ladder embeddings returned 400 Bad Request: {"error":{"message":"unknown ladder vectors; known ladders are flash (also chat-v1, flash-v1), instant (also no-think, instant-v1), reasoning (also deepseek), max-reasoning (also max-reasoning-v1), deepseek-flash (also reasoning-v1, agentic-v1), deep (also luna), scribe, uncensored, vectors-oai3 (also embeddings-oai3-v1), vision (also vision-v1, multimodal-v1), image (also images-v1, image-v1), vi), so this review saw the diff alone._ _Memory was unavailable (model: cortex: v1/recall: error sending request for url (http://cortexdb:3141/v1/recall\)\), so this review ran without it._

commits

  • Conclusion: Neutral
  • Scope reviewed: all assigned evidence
  • Lane summary: Nothing sensitive found in what this pull request commits.

description

  • Conclusion: Success
  • Scope reviewed: all assigned evidence
  • Lane summary: The PR adds signal-decode hints (141/137/143/139) to `exit_code_hint` with matching tests, and the body describes exactly that — the four codes, the pipefail motivation, and the deliberate exclusion of adjacent codes. The description matches the diff; no problems found. _Code retrieval was unavailable (model: ladder embeddings returned 400 Bad Request: {"error":{"message":"unknown ladder vectors; known ladders are flash (also chat-v1, flash-v1), instant (also no-think, instant-v1), reasoning (also deepseek), max-reasoning (also max-reasoning-v1), deepseek-flash (also reasoning-v1, agentic-v1), deep (also luna), scribe, uncensored, vectors-oai3 (also embeddings-oai3-v1), vision (also vision-v1, multimodal-v1), image (also images-v1, image-v1), vi), so this review saw the diff alone._ _Memory was unavailable (model: cortex: v1/recall: error sending request for url (http://cortexdb:3141/v1/recall\)\), so this review ran without it._

e2e

  • Conclusion: Neutral
  • Scope reviewed: all assigned evidence
  • Lane summary: No end-to-end harness in this repository: no e2e test files and no e2e workflow.
Evidence and run details
  • Models: gpt-5.6-luna, glm-5.3-flash
  • Spend: $0.001869
  • Tokens: 48064 input · 4329 output · 5973 cached · 0 embedding
Head State Pass summary
2f2b698d0e06 changes requested 1 active finding(s), 0 resolved finding(s) (at 1791440183)

tinysweeper 0.1.0

@coderabbitai

coderabbitai Bot commented Oct 8, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: a3b262b6-d097-46c8-bd16-4ea43f8aad24
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

@tinysweeper tinysweeper Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Requesting changes: 1 lane(s) blocking, worst finding is high.

Fix or reply to the findings below and push. The next review clears this automatically once they are gone — you should not need to dismiss anything by hand.

             $0.0019 · 48,064 in / 4,329 out · 5,973 cached (12%) · gpt-5.6-luna, glm-5.3-flash
critique:    $0.0010 · 19,979 in / 1,817 out · 2,626 cached (13%) · gpt-5.6-luna, glm-5.3-flash
security:    $0.0008 · 13,268 in / 999 out   · 3,155 cached (24%) · gpt-5.6-luna
tests:       $0.0000 · 5,599 in  / 206 out   · 64 cached (1%)     · glm-5.3-flash
description: $0.0000 · 5,317 in  / 93 out    · 64 cached (1%)     · glm-5.3-flash

restriction. This will not succeed on retry — report the blocker \
or request escalation instead of repeating the command"
}
141 => {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

priority high critique confident

Do not infer signals from exit codes alone

render_command_failure receives only an integer exit code, so it cannot distinguish a shell's 128 + signal result from an application that deliberately exits with the same value. For example, sh -c 'exit 141' reaches this arm without any SIGPIPE or early-closing reader, but the rendered message tells the agent to treat the output as usable rather than treating the command as failed. The same ambiguity applies to the newly added 137, 139, and 143 arms. Only emit these hints when the execution result preserves signal provenance, or remove the signal-specific hints from this formatter.

[RULE] ambiguous-exit-status ·

@senamakel senamakel self-assigned this Oct 8, 2026
@senamakel
senamakel merged commit e2bf1be into tinyhumansai:main Oct 8, 2026
11 of 12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants