fix(gui): show the connections "impaired?" column as a session-long record#37
Merged
Merged
Conversation
…ecord The "impaired?" column was recomputed live (local_port in target_ports), so a connection flipped to "no" the instant its socket closed. A browser closes hundreds of connections a minute, so a run that impaired all of Chrome looked like it caught almost nothing. The column now reads a sticky per-flow flag: once a flow has been in impairment scope it stays marked, for the life of the session's connection log. The live "in scope now" signal is unchanged - it is the row highlight, which still follows the current target - so narrowing chrome->firefox drops the highlight without erasing the record. Also fixes a coherence bug: the on-screen cell was live while the column's sort key (views.py) and the CSV export (gui/app.py) already read the stored flag, so the three disagreed. All three now read the one sticky flag. Tests: - new tests/test_engine.py::test_scoped_is_a_sticky_session_record - rewrote tests/test_conns_columns.py to lock the two-signal split (column = stored record, highlight = live target) Chunk 1 of 2 (display truth). The underlying port->PID resolution is still a periodic socket-table snapshot, so short-lived connections can still escape impairment; closing that with the WinDivert FLOW/SOCKET layer is Chunk 2. Co-Authored-By: Claude Opus 4.8 <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.
What & why
Targeting a process (e.g.
chrome.exe) showed a connections table where the largemajority of rows read "no" in the impaired? column, so the tool looked like it was
missing most of the traffic. It was not — the column was misreporting finished
connections.
The column was recomputed live (
conns.py::_render→engine.in_scope_now→core.in_scope→local_port in target_ports). A closed or idle flow's ephemeral porthas left the socket table, so the live test returns
Falsefor every connection that is nolonger open — which is most of them on a browser. A run that impaired all of Chrome
therefore rendered as a table full of "no".
The fix
engine._log_connkeeps the per-flowscopedflag sticky(
c["scoped"] = c["scoped"] or bool(scoped)) — a session-long "was ever in impairmentscope" record.
conns.py::_renderreads that stored flag instead of the live lookup._tag_of,still via
in_scope), so narrowing chrome→firefox drops the highlight without erasing therecord.
Two-signal design: the column is the audit trail (sticky); the row highlight is the
current target (live).
Coherence bug also fixed
The on-screen cell was live, while the column's sort key (
views.py) and the CSVexport (
gui/app.py) already read the stored flag — three call sites, two semantics.All three now read the one sticky flag, so the table, its sort order and the export agree.
Tests
tests/test_engine.py::test_scoped_is_a_sticky_session_record— three packets onone flow (in scope, then twice out) keep the flag
True; a never-scoped flow staysFalse. Driven straight through_log_conn, no thread timing.tests/test_conns_columns.py::test_connection_columns_tag_and_footer— anout-of-current-target row now asserts column "yes" (stored record) with no highlight
tag (live), locking the two-signal split.
tests/test_conns_export.pyandtest_engine.py::test_connection_records_scope_and_droppedwere already consistent with the stored flag and pass unchanged.
Scope
This is Chunk 1 of 2 (display truth). The underlying port→PID resolution is still a
periodic socket-table snapshot, so short-lived connections that open and close inside a
refresh window can still escape impairment (
tests/test_target_resolver.pydocuments therace). Closing that at the source with the WinDivert FLOW/SOCKET layer is Chunk 2,
tracked separately.
🤖 Generated with Claude Code