feat(filter): reduce observed agent confusion in git diff/status/log#320
Merged
feat(filter): reduce observed agent confusion in git diff/status/log#320
Conversation
Three related fixes informed by analysing ~54k tokf events from local
tracking.db. Each addresses a distinct retry-burst pattern where the
model thrashes through flag variations trying to "escape" the filter.
git/diff
- Forced --stat had no escape hatch, so models repeatedly tried
--no-stat, -p, --no-pager, etc. (240+ workaround flags across the
dataset; biggest single burst: 51 calls in 3m41s).
- Added passthrough_args for the output-format flags the model already
reaches for: -p/--patch, --no-stat, -U<n>, --name-only/--name-status,
--numstat, --shortstat, --raw.
git/status
- Porcelain default (-unormal) collapsed untracked directories to
"?? newdir/", so models couldn't see files they had just created and
would loop. Run override now uses
`git status --porcelain=v1 -b -uall --find-renames` so every untracked
file appears individually and renames render as "R old -> new" instead
of D + ?? on separate lines.
- Branch-line replace rules now always communicate upstream sync state
([synced], [ahead N], [behind N], (no upstream)). Previously the
upstream was stripped when in sync, leaving the model unable to tell
whether commits had been pushed.
git/log
- Empty output was indistinguishable from filter-induced suppression —
models would burn 10–40 calls cycling through --all, --diff-filter=A,
--follow, --grep, --source, '-- pathspec' variants trying to escape a
non-existent filter. Added an `on_empty` hint that points at the most
likely causes (untracked pathspec, missing --all, missing --follow).
- Added passthrough for output-format flags incompatible with
--oneline -n 20: --name-only, --name-status, --shortstat, --dirstat,
-L (line-history). Other flags (--all, --follow, --diff-filter,
--grep, -S, -G, --author, --since) compose fine with the override.
Tests
- New regression cases:
git/status_test/untracked_in_new_dir.toml (-uall)
git/status_test/rename_detected.toml (--find-renames)
- Updated existing fixtures for the new branch-line markers:
git/status_test/{clean,normal,local_only_branch}.toml
- Updated git/log_test/empty.toml to assert the on_empty hint.
- test_deserialize_git_{diff,status,log} unit tests in
crates/tokf-cli/src/config/types.rs assert the new fields,
passthrough_args entries, and prefix-matching behaviour for flags
like -U3, --patch-with-stat, -L1,10:src/main.rs.
Verified
- cargo run -p tokf -- verify --scope stdlib -> 134/134 passed
- cargo test --workspace -> 1965 passed, 0 failed
- cargo clippy --workspace --all-targets -- -D warnings -> clean
- cargo fmt --check -> clean
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Contributor
Filter Verification ReportChanged Filters
All Filters Summary✅ 134/134 test cases passed across 49 filters Generated by |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Three related fixes informed by analysing ~54k tokf events from local
tracking.db. Each addresses a distinct retry-burst pattern where an agent thrashes through flag variations trying to "escape" a filter.git/diff— addedpassthrough_argsso the model can get-p/--patch/--no-stat/-U<n>/--name-only/--name-status/--numstat/--shortstat/--rawcontent out of the forced--statoverride. The previous behaviour caused 51-call retry bursts (model trying every workaround it knew, includinggit --no-pager diff).git/status—runoverride now uses--porcelain=v1 -b -uall --find-renamesso untracked files in newly-created directories appear individually (instead of?? new_dir/) and renames render asR old -> new(instead ofD old+?? newlooking unrelated). Branch-line replace rules now always communicate upstream sync state:[synced],[ahead N],[behind N],(no upstream)— previously the upstream was stripped when in sync, so the model couldn't tell whether commits had been pushed.git/log— empty output now emits anon_emptyhint pointing at the most likely causes (untracked pathspec, missing--all, missing--follow) instead of nothing. Previously the model would burn 10–40 calls cycling through--all,--diff-filter=A,--follow,--grep,--source,'-- pathspec'variants trying to escape a non-existent filter — when the actual answer was "the file is untracked, rungit ls-files". Also added passthrough for output-format flags incompatible with--oneline -n 20:--name-only,--name-status,--shortstat,--dirstat,-L.Evidence (from
tracking.db, 2026-02-18 → 2026-04-08)git/diff-p,--no-stat,git --no-pager diff,--no-index /dev/null <file>)git/status?? new_dir/collapses path of just-created filegit/log--all,--diff-filter=A,--source,--follow, pathspecs; gets empty back; can't tell whyAcross the dataset,
git/diffcalls contained 86 explicit--no-stat, 127-p/--patch, and 27--no-pagerworkaround flags — clear "I am trying to escape your filter" signals from agents.Test plan
cargo run -p tokf -- verify git/diff --scope stdlib→ 4/4 passedcargo run -p tokf -- verify git/status --scope stdlib→ 9/9 passed (incl. 2 new regression tests for-ualland--find-renames)cargo run -p tokf -- verify git/log --scope stdlib→ 2/2 passed (empty test now asserts theon_emptyhint)cargo run -p tokf -- verify --scope stdlib→ 134/134 passedcargo test --workspace→ 1965 passed, 0 failed, 166 ignoredcargo clippy --workspace --all-targets -- -D warnings→ cleancargo fmt --check→ cleanbash scripts/generate-readme.sh→ README up to date with new docs rowsFiles
Filters
crates/tokf-cli/filters/git/diff.toml— addedpassthrough_argscrates/tokf-cli/filters/git/status.toml— newrunoverride + newreplacerulescrates/tokf-cli/filters/git/log.toml— addedpassthrough_args+on_emptyhintTests
crates/tokf-cli/filters/git/status_test/untracked_in_new_dir.toml(new)crates/tokf-cli/filters/git/status_test/rename_detected.toml(new)crates/tokf-cli/filters/git/status_test/{clean,normal,local_only_branch}.toml(updated for new branch markers)crates/tokf-cli/filters/git/log_test/empty.toml(assertson_emptyhint)crates/tokf-cli/src/config/types.rs—test_deserialize_git_{diff,status,log}updated to assert new fields, passthrough entries, and prefix-matching behaviour for-U3,--patch-with-stat,-L1,10:src/main.rsDocs
docs/getting-started.md— stdlib filter table entries forgit/diff,git/status,git/logREADME.md— regeneratedFollow-up (separate work)
[tree]filter transform for path-list outputs (would further reduce tokens forgit/statusandgit/diff --name-onlyonce landed). Filed but not implemented in this PR.🤖 Generated with Claude Code