feat(security_guard): #347 PR 3 — Alt+Shift+W warn-event dump#370
Merged
Conversation
Closes the optional polish item from #347's PR plan. Adds an explicit action + binding for surfacing the warn buffer that WarnSubscriber accumulates in the background. | What | Where | |---|---| | New `Action.security_guard_show_warnings` | src/keymap.zig | | Default binding `Alt+Shift+W` (legacy `\x1bW` + kitty kbd `\x1b[87;4u`) | src/defaults.zig | | `WarnSubscriber.clear()` — lock + free events; preserves `dropped_total` (audit counter) | src/modules/security_guard/warn_subscriber.zig | | `security_guard.onAction` — snapshot, render one line per event into the sink, call `sub.clear()` | src/modules/security_guard.zig | | Proxy switch case — dispatches to module + swallows the meta keystroke | src/proxy.zig | Render-and-clear is the deliberate semantic: - the operator has the scrollback record; - the `⚠ N` statusbar segment goes away; - subsequent kernel events re-arm it; - no alt-screen overlay that would compete with vim/htop/etc. Event format: ``` atty security_guard: 2 warn events <sec>.<ms> pid=<P> ppid=<PP> comm=<C> argv0=<A> ... ``` Empty buffer / no subscriber → one-line notice instead of silent swallow, so the user knows the keystroke registered. 5 new tests: clear() preserves dropped_total; warn-dump renders events + clears + returns consumed; empty-buffer notice; no- subscriber notice; onAction returns false for unrelated actions. 1112/1112 unit tests pass; ReleaseSafe binary builds clean. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
… trunc marker - The previous header text pointed operators at `atty-guard session list` for the dropped-event count, but that CLI doesn't surface warn-event drops (it only knows about atoms / urls / trust). Inline the count instead so the operator sees it immediately: `N warn events (M dropped this session)`. - Symmetric `…` truncation marker on `comm` — matches the argv0 path. Linux caps comm at 16 bytes so this never fires in practice, but a daemon-side bug producing a longer comm shouldn't lose tail bytes silently. 1112/1112 tests still pass. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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
Closes the optional polish item from #347's PR plan. Adds an explicit action + binding for surfacing the warn buffer that `WarnSubscriber` accumulates in the background.
Pieces
Why render-and-clear, not an interactive overlay
The issue's pinned plan proposed an interactive picker with per-event detail + dismiss-one / dismiss-all. After implementation thought:
If someone needs per-event dismiss later, the surface is small (add another action that pops a specific index) and the kernel of work — the `clear()` method, the dump format — is already in place.
Event format
```
atty security_guard: 2 warn events
. pid=
ppid= comm= argv0=
...
```
Empty buffer / no subscriber attached → one-line notice instead of silent swallow, so the keystroke is visibly registered.
Tests
Test plan
🤖 Generated with Claude Code