Skip to content

feat(security_guard): #347 PR 3 — Alt+Shift+W warn-event dump#370

Merged
fentas merged 2 commits into
masterfrom
feat/347-pr3-warn-overlay
May 30, 2026
Merged

feat(security_guard): #347 PR 3 — Alt+Shift+W warn-event dump#370
fentas merged 2 commits into
masterfrom
feat/347-pr3-warn-overlay

Conversation

@fentas
Copy link
Copy Markdown
Owner

@fentas fentas commented May 30, 2026

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

What Where
New `Action.security_guard_show_warnings` variant `src/keymap.zig`
Default binding `Alt+Shift+W` (legacy `\x1bW` + kitty kbd `\x1b[87;4u`) `src/defaults.zig`
`WarnSubscriber.clear()` — locks, frees events, preserves `dropped_total` (audit counter) `src/modules/security_guard/warn_subscriber.zig`
`security_guard.onAction` — snapshot, render one line per event to the sink, call `sub.clear()` `src/modules/security_guard.zig`
Proxy switch case — dispatches to module + swallows the meta keystroke `src/proxy.zig`

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:

  • An alt-screen overlay would compete with vim / htop / less for the screen — atty's existing alt-screen handoff to TUIs is the whole reason `mouse_urls` / `mouse_links` are gated on `!shell_owns_input`.
  • Warn events are append-only audit data, not a workflow that needs in-place mutation. "Render once + dismiss-all" preserves the scrollback record AND clears the `⚠ N` segment so the user knows they've reviewed the batch.
  • New kernel events from the daemon re-arm the segment immediately — the buffer is reusable after clear.

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

  • `clear()` empties the buffer but preserves `dropped_total`; buffer reusable after.
  • `onAction` warn dump renders events + clears + returns consumed (with both pid=4242 and pid=4243 present in the sink output).
  • Empty-buffer notice.
  • No-subscriber notice (security_guard disabled).
  • `onAction` returns false for unrelated actions (`incognito_toggle`, `show_help`).

Test plan

  • `zig build test` — 1112/1112 (+5 new)
  • `zig fmt --check`
  • `zig build -Doptimize=ReleaseSafe` — 10.8 MB binary
  • Manual smoke (deferred — needs daemon with `--ebpf-mode=warn` + a warn-eligible process)

🤖 Generated with Claude Code

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>
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

… 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>
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

@fentas fentas merged commit a7ecc3b into master May 30, 2026
5 of 6 checks passed
@fentas fentas deleted the feat/347-pr3-warn-overlay branch May 30, 2026 06:11
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.

2 participants