Skip to content

Don't count a failing test run piped into tail as passed - #252

Merged
nasser1941 merged 2 commits into
mainfrom
fix/piped-checks
Nov 6, 2026
Merged

nasser1941 merged 2 commits into
mainfrom
fix/piped-checks

Conversation

@nasser1941

Copy link
Copy Markdown
Owner

Found while reading the failed build-cython-ext attempts on 0.61.0's gate run. One attempt ran the project's checks itself as python -m pytest -q 2>&1 | tail -40, while a test was failing. That command exits with tail's 0, so lcode took the checks as passed and never ran them. lcode -p --output json would also report them as passed.

What changes

When the model's run of the check has something after it that takes over the exit code (a pipe, ||, ;, & or another line), the exit code no longer counts. The run counts as passed only if its output shows a test summary with nothing failing (18 passed, or unittest's OK, and no 1 failed, 2 errors, FAILED or ERROR). Otherwise lcode runs the checks itself, as it does when the model hasn't run them.

A run with only redirections or && after it (pytest -q 2>&1, pytest -q && echo done) keeps its exit code, so nothing changes there.

Real test

A real model (qwen3.6-35b at 32K) on a small project with one failing test, asked to add a function and run the tests with exactly python -m pytest -q 2>&1 | tail -5:

0.61.0 from PyPI This branch
The model's command the piped one the piped one
lcode runs the checks itself No Yes, and they fail with exit code 1
The model gets the failure back No Yes
Its answer The failing test was already failing The same, with no extra edits

In this test the model saw the failure in its own output and reported it either way. The fix matters when it doesn't, and for what lcode records: on 0.61.0 the run counted as checks that passed.

The new tests cover a failing run through tail from start to finish with FakeOllama, and 20 command and output pairs. The full suite, ruff, basedpyright and mkdocs build --strict pass.

Left out on purpose

  • A narrower run still counts. python -m pytest -q tests/test_a.py contains the check's command, so it counts as the checks if it passes. Changing that would mean running a whole test suite again after many focused runs, which can take minutes on a big project, so it's a decision of its own.

This changes when the checks run and what the model is told, so it goes through the next gate before it ships, with #250.

🤖 Generated with Claude Code

nasser1941 and others added 2 commits November 6, 2026 12:52
`pytest -q | tail` exits with tail's 0 when tests fail. lcode read that as the checks passing, didn't run them, and
reported them as passed. A run whose exit code isn't the check's now counts only if its output shows a test summary
with nothing failing. Otherwise lcode runs the checks itself.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@nasser1941
nasser1941 merged commit fafe2f2 into main Nov 6, 2026
12 checks passed
@nasser1941
nasser1941 deleted the fix/piped-checks branch November 6, 2026 12:08
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