Skip to content

fix(gui): show the connections "impaired?" column as a session-long record#37

Merged
donislawdev merged 1 commit into
masterfrom
fix/impaired-column-session-record
Jul 22, 2026
Merged

fix(gui): show the connections "impaired?" column as a session-long record#37
donislawdev merged 1 commit into
masterfrom
fix/impaired-column-session-record

Conversation

@donislawdev

Copy link
Copy Markdown
Owner

What & why

Targeting a process (e.g. chrome.exe) showed a connections table where the large
majority 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::_renderengine.in_scope_now
core.in_scopelocal_port in target_ports). A closed or idle flow's ephemeral port
has left the socket table, so the live test returns False for every connection that is no
longer 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_conn keeps the per-flow scoped flag sticky
    (c["scoped"] = c["scoped"] or bool(scoped)) — a session-long "was ever in impairment
    scope"
    record.
  • conns.py::_render reads that stored flag instead of the live lookup.
  • The live "in scope now" signal is unchanged: it is the row highlight (_tag_of,
    still via in_scope), so narrowing chrome→firefox drops the highlight without erasing the
    record.

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 CSV
export
(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

  • new tests/test_engine.py::test_scoped_is_a_sticky_session_record — three packets on
    one flow (in scope, then twice out) keep the flag True; a never-scoped flow stays
    False. Driven straight through _log_conn, no thread timing.
  • rewrote tests/test_conns_columns.py::test_connection_columns_tag_and_footer — an
    out-of-current-target row now asserts column "yes" (stored record) with no highlight
    tag (live), locking the two-signal split.
  • tests/test_conns_export.py and test_engine.py::test_connection_records_scope_and_dropped
    were already consistent with the stored flag and pass unchanged.
  • Full suite green.

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.py documents the
race). Closing that at the source with the WinDivert FLOW/SOCKET layer is Chunk 2,
tracked separately.

🤖 Generated with Claude Code

…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>
@donislawdev
donislawdev merged commit 2d21d5c into master Jul 22, 2026
8 checks passed
@donislawdev
donislawdev deleted the fix/impaired-column-session-record branch July 22, 2026 18:49
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.

1 participant