Repository navigation
fix(tui/audit): scope delete-all to the active filter and export every matching row - #169
Merged
codeyevsky merged 3 commits intoOct 27, 2026
Merged
Conversation
… row "X" promised "delete ALL matched entries, every one of the N" and then called ClearLocalLog(), which empties the whole file: a user who filtered the view lost entries that were never on screen. Deletion now runs through the same client.AuditQuery the view used, so only the visible subset is removed. "E" asked Audit.List for 10_000 rows, but List clamps Limit to 1000, so every export above 1000 matching entries was cut off with no warning. The export now walks pages of client.MaxAuditPage until the matching set is complete, and says so explicitly if the 120s budget ends first. The filter lives in one place: AuditQuery.Matches() is what List uses, and the TUI applies it to raw log lines via AuditEntryFromLocalLine(), so the view and the bulk actions cannot drift apart again. Signed-off-by: Turgay Nalbant <182372382+tnalbant@users.noreply.github.com>
Routing every delete through the query predicate also kept lines that no longer parse, so an unfiltered "X" left corrupted rows behind while still reporting that the whole log was deleted. With no filter active, keep the previous ClearLocalLog() path; the predicate is only for a narrowed view, where a line that cannot be parsed cannot match the filter anyway. Signed-off-by: Turgay Nalbant <182372382+tnalbant@users.noreply.github.com>
codeyevsky
approved these changes
Oct 27, 2026
qarademir
approved these changes
Oct 27, 2026
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.
What this fixes
Two silent scope bugs in the audit view, both from #145:
X(delete all) ignored the active filter. The confirmation saysX = delete ALL matched entries, every one of the 3!and then calledtui.ClearLocalLog(), which empties the whole file. Filtering the view down toone agent or one DLP signal and pressing
Xdeleted entries that were never onscreen.
E(export all) stopped at 1000 rows without saying so. It askedAudit.ListforLimit: 10_000, butAudit.Listclamps the limit to 1000, so1105 matching entries produced a 1000-row file reported as
✓ exported 1000 rows.How
client.AuditQuery.Matches()— the filter that used to be inlined inAudit.Listis now a single method.Listuses it, and so do the bulk actions.Limit/Offsetare deliberately excluded: they window the result, they do notselect entries.
client.AuditEntryFromLocalLine()decodes one raw local-log line into the sameAuditEntryshapeListreturns, so the TUI can apply that exact filter whilerewriting the file.
tui.DeleteLocalLogMatching(predicate)deletes only the accepted lines, throughthe same lock-and-rewrite path
DeleteLocalEntryuses. Lines that do not parseare kept; a nil predicate deletes nothing.
doDelete("all")passesp.query(); panel state is read before the commandgoroutine starts, like the existing
gencapture.doExport("all")walks pages ofclient.MaxAuditPageuntil the matching set iscomplete, and reports
exported N of M matching rows (timed out)if the existing120s budget ends first instead of pretending the file is complete.
client.MaxAuditPageis the new named constant for the 1000-row clamp, so thenumber is not duplicated in the TUI.
Xstill clears the whole log and saysso.
Verification
Both tests fail on the parent commit and pass with the change:
TestDoDeleteAllOnlyDeletesEntriesMatchingTheActiveFilterTestDoExportAllExportsEveryMatchingRowPastTheClientPageLimit✓ exported 1000 rowsof 1105packages/tui:go test -count=1 ./...→ all four packages ok;go test -race ./audit/ .ok;go vet ./...clean.packages/core:go test -count=1 ./client/→ 100 tests pass;go vet ./client/clean.DeleteLocalLogMatchingkeeps lines it cannot parse and deletes nothing for a nil predicate;AuditQuery.Matchesignores the paging window.gofmtintroduces no formatting changes in the touched files.Not related to this change, for transparency:
packages/core/configandpackages/core/healthfail on macOS with chmod/immutable-flag assertions(
TestLockFileThenUnlockFileRoundTrip,TestWriteProtectedFileOverLockedFileUnlocksRewritesAndRelocks,TestLockPathCheckLockUnlockPathOnFile,TestLockPathAndUnlockPathOnDirectory,TestProtectedCheckChmodOnlyLock). The same five failures reproduce on a cleancheckout of b2b4a54, and neither package is touched here.
Closes #145
AI assistance
Implemented with AI assistance (Hermes agent) at my direction, including the tests
above run against both revisions. I reviewed the change and the evidence above
before submitting it.