Skip to content

fix(stage-router): don't let an exit line inside a read file fail the read - #964

Open
harshitwandhare wants to merge 2 commits into
NVIDIA-NeMo:mainfrom
harshitwandhare:fix/codex-read-exit-status
Open

harshitwandhare wants to merge 2 commits into
NVIDIA-NeMo:mainfrom
harshitwandhare:fix/codex-read-exit-status

Conversation

@harshitwandhare

@harshitwandhare harshitwandhare commented Oct 10, 2026 •

Copy link
Copy Markdown

#906 stops error text inside a file read from counting as a failure. A read still counts when the read itself failed. Deciding that ran has_nonzero_exit_status over the whole result, including the content that was read. So a log with an exit line in it turns the read back into a failure, and then every error pattern in the log counts as well. This happens for Codex exec_command results and for Hermes terminal results.

Measured on main at fc64565a with a probe test that prints ToolSignals::from_request(..).severity:

Read Status the harness reported Content Severity
Codex cat run.log Process exited with code 0 header a Python traceback 0.0
Codex cat run.log same the same traceback plus a line Process exited with code 1 1.0
Codex tail -n 20 test.log same a go test failure log that contains exit status 1 0.3
Hermes cat run.log "exit_code": 0 a Python traceback 0.0
Hermes cat run.log same the same traceback plus Process exited with code 1 1.0
Hermes tail -n 20 test.log same the go test log with exit status 1 0.3

A failing test run started with plain go test, no package arguments, prints exit status 1. go test ./... and go test . leave that line out. So reading a log saved from a plain go test run is enough to hit this.

Fix

Hermes puts the status in exit_code, which #949 already reads. Codex puts it in a header before Output:, the shape this file's tests already use. For a read, the status now comes from the Hermes fields when the result has them, otherwise from the Codex header. A result with neither is scanned whole, as before.

Verified

  • codex_read_status_comes_from_the_header fails on main with left: 1.0, right: 0.0 and passes with the fix. It also checks that a read whose header says code 1 still counts.
  • hermes_read_status_comes_from_exit_code fails on df7b35f8 (the Codex commit alone) with left: 1.0, right: 0.0 and passes at 59567134. It also checks that "exit_code": 1 still counts.
  • cargo test -p switchyard-libsy --lib tool_signals: 80 passed at 59567134.
  • cargo test --workspace --locked at 59567134: 962 passed, 0 failed over 40 binaries. Prefill-router tests 68 / 0. cargo fmt --all --check and both clippy runs with -D warnings are clean. Rust only, so the Python gates were not re-run.
  • With the fix, the probe reads 0.0 for every row above, and failed Hermes reads ("exit_code": 1) still score 1.0 and 0.3 as on main.

Not changed

Results from the Bash tool have neither, so the same cat run.log through Bash still scores 1.0. This file's tests model a failed Bash read with is_error, so the text scan may not be needed there. I don't know whether every harness without a status field sets is_error, so I left that case alone. I can follow up if you want it handled.

@harshitwandhare
harshitwandhare requested a review from a team as a code owner October 10, 2026 23:19
@coderabbitai

coderabbitai Bot commented Oct 10, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository: NVIDIA-NeMo/Switchyard/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Enterprise
  • Run ID: 599d4359-b7ae-4dd8-b417-56a2975a888f



📥 Commits

Reviewing files that changed from the base of the PR and between fc64565 and 6a5608a.




📒 Files selected for processing (1)
  • crates/libsy/src/algorithms/util/tool_signals.rs



Included review availability: This review used your included allowance. Your plan provides up to 12 included reviews per hour; 11 remain after this review.





Walkthrough

Retrieved shell-result exit-status detection now checks the header before Output: when present. A regression test covers zero and nonzero header statuses when the output contains a traceback and a nonzero-looking exit line.

Changes

Retrieved shell status handling

Layer / File(s) Summary
Status selection and regression test
crates/libsy/src/algorithms/util/tool_signals.rs
Retrieved results use the pre-Output: header for nonzero exit-status detection when available. Structured failure checks remain unchanged. The test checks that header status 0 yields severity 0 and status 1 yields CRITICAL, despite nonzero-looking text in the output.

Priority: ⬇️ Low

Estimated code review effort: 2 (Simple) | ~8 minutes

Merge Risk: ⚪ Minimal · up to 6a560

No actionable merge-blocking issue is established by the reviewed change.

Pre-merge checks | Passed 4 | Failed 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 75.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 4 functions across 1 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly describes the main change: exit-status text inside a read file must not fail the read.

  • Fix all pre-merge checks with AI
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

A rabbit checks the status line,
Before the output hops in view.
A zero stays a zero still,
Though exit-like words pass through.
A one rings out as failure,
Then carrots mark the test as true.

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

Signed-off-by: Harshit Wandhare <harshitwandhare45@gmail.com>
@harshitwandhare
harshitwandhare force-pushed the fix/codex-read-exit-status branch from 6a5608a to df7b35f Compare October 11, 2026 01:59
Signed-off-by: Harshit Wandhare <harshitwandhare45@gmail.com>
@harshitwandhare harshitwandhare changed the title fix(stage-router): read a Codex read's exit status from its header fix(stage-router): don't let an exit line inside a read file fail the read Oct 11, 2026
@harshitwandhare

Copy link
Copy Markdown
Author

Pushed 59567134 for the same problem in Hermes terminal results. Hermes reports a read's status in exit_code, and the check from #949 reads that field, but the text scan still ran over the whole JSON. So cat run.log with "exit_code": 0 scored 1.0 when the log had a Process exited with code 1 line, and a Go log with exit status 1 scored 0.3. Now the fields decide when they are present, and the text is only scanned when they are not.

The new test hermes_read_status_comes_from_exit_code fails on df7b35f8 with left: 1.0, right: 0.0 and passes at 59567134. I updated the title and description to cover both, with the gates re-run at the new head.

This branch has not been deployed

No deployments
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