From 725516b4747369745597ca56ac950907bbc22781 Mon Sep 17 00:00:00 2001 From: Ahmed Allam Date: Wed, 9 Sep 2026 14:35:08 +0000 Subject: [PATCH] fix(tui): detect content-only report revisions in the sync fingerprint The update callback now fires before the in-memory report is replaced, so a snapshot taken on that notification can still show the old content. The periodic sync fingerprint tracks each report's updated_at as well as its id, so the next tick picks the revision up. --- strix/interface/tui/runtime.py | 4 +++- tests/test_go_tui_runtime.py | 15 +++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/strix/interface/tui/runtime.py b/strix/interface/tui/runtime.py index d398e5ab..80e0f50f 100644 --- a/strix/interface/tui/runtime.py +++ b/strix/interface/tui/runtime.py @@ -339,7 +339,9 @@ class GoTuiRuntime: if self.report_state is not None: usage = dict(self.report_state.get_total_llm_usage()) vulnerabilities = [ - report.get("id", index) if isinstance(report, dict) else index + (report.get("id", index), report.get("updated_at")) + if isinstance(report, dict) + else index for index, report in enumerate(self.report_state.vulnerability_reports) ] return json.dumps( diff --git a/tests/test_go_tui_runtime.py b/tests/test_go_tui_runtime.py index 05f81ece..3b27ef8a 100644 --- a/tests/test_go_tui_runtime.py +++ b/tests/test_go_tui_runtime.py @@ -19,6 +19,7 @@ from strix.config.settings import DEFAULT_MAX_TURNS from strix.interface.tui import runtime as go_tui from strix.interface.tui import sidecar from strix.interface.tui.runtime import GoTuiRuntime +from strix.report.state import ReportState def args() -> argparse.Namespace: @@ -1027,3 +1028,17 @@ async def test_prepare_and_start_runs_the_scan_after_preparation( assert order == ["preflight", "persist", "prepare", "telemetry", "state", "scan"] assert runtime.controller.scan_state == "running" + + +def test_sync_fingerprint_tracks_report_revisions(tmp_path: Path) -> None: + runtime = GoTuiRuntime(args()) + runtime.report_state = ReportState(run_name="test-run") + runtime.report_state.vulnerability_reports = [{"id": "vuln-0001", "title": "Old title"}] + runtime.report_state.get_run_dir = lambda: tmp_path # type: ignore[method-assign] + + before = runtime._runtime_sync_fingerprint() + runtime.report_state.vulnerability_reports[0].update( + {"title": "New title", "updated_at": "2026-09-09T10:00:00+00:00"} + ) + + assert runtime._runtime_sync_fingerprint() != before