RTK could emit more tokens than the underlying command on small inputs:
filters that add headers, summaries, re-indentation, or a tee hint, plus
synthetic no-result messages ("0 matches", "No stashes", "[docker] 0
containers") printed where the raw command emitted nothing. Both break the
Transparency principle and inflate tokens instead of saving them.
- core::guard::never_worse(raw, filtered) returns raw when the filtered form
has more tokens (reuses tracking::estimate_tokens), so RTK output is never
larger than the real command.
- runner::emit_guarded(filtered, hint, raw) composes body + tee hint, guards
the whole, prints, and returns what was shown so printed == tracked.
- run_captured_filter guards the run_filtered* family centrally; per-site
guards cover the remaining single-string filters.
- On empty raw, emit empty and preserve the exit code instead of a synthetic
no-result message (the messages were cosmetic with no dependents; #2461
reports the grep one as actively harmful).
- git stash show now propagates its exit code instead of masking a real
failure as Ok(0).
Resolves#2551.
test_needs_raw_fallback dropped the raw stdout prepend whenever every
parsed failure carried detail, but never checked the list was complete
against summary.failed. A run reporting 5 failures but parsing only 3
detailed blocks would silently lose the 2 unparsed failures.
Add a `failed_tests.len() < summary.failed` clause so the raw fallback is
kept when the structured section is numerically incomplete. Add a
regression test and fix an inconsistent existing fixture (failed: 5 with a
single parsed entry) that the new clause correctly flagged.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
On failing `dotnet test` runs the orchestrator prepended the full raw
stdout ahead of the filtered summary. The `Failed Tests:` section already
reproduces each failure (name + message + clipped stack) parsed from
TRX/console, so every failure was printed twice — inflating output +65%
vs raw, scaling linearly with failure count (issue #2501).
Gate the raw-stdout prepend behind `test_needs_raw_fallback`: skip it when
the structured section carries detail, keep it when the filter is blind
(no failures parsed, or a parsed failure has empty detail — e.g. a
self-closing <UnitTestResult> with no <ErrorInfo>, or a build failure /
crash where nothing reaches failed_tests).
Extracts two pure, unit-tested fns (`test_needs_raw_fallback`,
`compose_failure_output`) so the orchestration decision is covered without
running dotnet.
Closes#2501
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Separator lines (═══, ---) and an emoji status marker cost tokens
without adding signal for the LLM — RTK output must never add noise
over raw. Semantic labels are kept; the emoji is swapped for plain
monochrome unicode.
Replace all bare magic offset literals (e.g. 21 for cap=20) with named
constants (MAX_XXX + 1) so offsets stay in sync if caps change.
Fix compose_ps to tee pre-formatted lines instead of raw tab-separated
input, so tail -n +N gives the agent readable content.
All 13 affected modules updated: container, dotnet, gh, glab, go, lint,
pnpm, pytest, rubocop, cargo, aws. 1884 tests pass.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Separate warnings and errors into distinct sections.
- Ensure status line is emitted last for clarity.
- Maintain consistency with native `dotnet` output behavior.
The `ok` / `fail` verdict line was emitted at the top of the filtered
output, before errors and warnings. Consumers reading the tail of the
stream — `| tail -N`, IDE log followers, agent watch/monitor loops,
bounded-context-window readers — saw error noise followed by EOF with
no verdict anywhere near the end, silently breaking any agent loop that
gates the next step on build success.
Reorder `format_build_output`, `format_test_output`, and
`format_restore_output` to emit the body first, then the separator
(only when the body is non-empty), then the verdict header last,
matching native `dotnet` which ends with `Build succeeded.` or
`Build FAILED.`.
Add three regression tests using strict `output.lines().last()` plus a
`tail -5` inclusion assertion so future regressions that append a
trailing context line get caught.
Closes#1574
Signed-off-by: Artiom Tofan <arto@queue-it.com>
Fix seems counter intuitive but it helps a lot on my machine.
Before, I had 234 errors (23%) out of 1,000 tests run; now, I only have one (0.1%)
It's not totaly fixed but it reduce error a lot and avoids having one almost every time I test a PR.
Another way to completly fix it would be to use std::fs::set_times on old.trx to set each time in the past, but it requires unstable fs_set_times feature, so I'm not sure you'll agree with that
Signed-off-by: Nicolas Le Cam <niko.lecam@gmail.com>