From 7be52b8cf1cd2cd2acded26b6926c9ccca5b82be Mon Sep 17 00:00:00 2001 From: Sinity Date: Fri, 31 Jul 2026 10:51:19 +0200 Subject: [PATCH] fix(sources): reconcile sidecar coverage with attachment evidence events Problem: master went red after #3419 (per-type sidecar coverage) merged alongside #3423 (attachment sidecar split). Seven attachment tests assert exact equality on parsed.session_events, and #3419 unconditionally appends a claude_parse_coverage event, so every list gained an unexpected member. Neither PR was wrong alone; their tests were never reconciled because the conflict resolution was verified with a narrower selection than the change warranted. The failure also exposed a real defect: the attachment branch appends a session_event but never set persisted_this_record, so coverage reported sidecar_seen={attachment: 1} with sidecar_persisted={} -- understating persistence for every attachment record. What changed: - attachment branch marks persisted_this_record when it emits an event - the seven exact-equality assertions exclude claude_parse_coverage, which is a parse-level report orthogonal to the attachment evidence each test is about Verification: devtools test -k 'sidecar or code_parser' -> 145 passed (was 7 failed / 138 passed on master). Co-Authored-By: Claude Opus 5 --- polylogue/sources/parsers/claude/code_parser.py | 1 + .../sources/test_claude_code_sidecar_evidence.py | 14 +++++++------- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/polylogue/sources/parsers/claude/code_parser.py b/polylogue/sources/parsers/claude/code_parser.py index 5701570370..4a0aeef507 100644 --- a/polylogue/sources/parsers/claude/code_parser.py +++ b/polylogue/sources/parsers/claude/code_parser.py @@ -1469,6 +1469,7 @@ def _parse_code_records( attachment_event = _attachment_sidecar_event(item, timestamp) if attachment_event is not None: session_events.append(attachment_event) + persisted_this_record = True event_type = _SIDECAR_EVENT_TYPES.get(record_type) if event_type is not None: evidence_payload = _sidecar_evidence_payload(record_type, item) diff --git a/tests/unit/sources/test_claude_code_sidecar_evidence.py b/tests/unit/sources/test_claude_code_sidecar_evidence.py index c1338d6b8f..4e03add837 100644 --- a/tests/unit/sources/test_claude_code_sidecar_evidence.py +++ b/tests/unit/sources/test_claude_code_sidecar_evidence.py @@ -323,7 +323,7 @@ def test_attachment_hook_subtypes_share_one_event_type() -> None: ], "sess-hook", ) - event_types = [e.event_type for e in parsed.session_events] + event_types = [e.event_type for e in parsed.session_events if e.event_type != "claude_parse_coverage"] assert event_types == ["claude_hook_event", "claude_hook_event"] @@ -342,7 +342,7 @@ def test_attachment_queued_command_reuses_queue_operation_event_type() -> None: ], "sess-queue", ) - events = [(e.event_type, e.payload) for e in parsed.session_events] + events = [(e.event_type, e.payload) for e in parsed.session_events if e.event_type != "claude_parse_coverage"] assert events == [ ( "claude_queue_operation", @@ -372,7 +372,7 @@ def test_attachment_transient_subtype_emits_no_event() -> None: ], "sess-transient", ) - assert parsed.session_events == [] + assert [e for e in parsed.session_events if e.event_type != "claude_parse_coverage"] == [] def test_attachment_unrecognized_subtype_fails_loud() -> None: @@ -389,7 +389,7 @@ def test_attachment_unrecognized_subtype_fails_loud() -> None: ], "sess-unknown", ) - events = [(e.event_type, e.payload) for e in parsed.session_events] + events = [(e.event_type, e.payload) for e in parsed.session_events if e.event_type != "claude_parse_coverage"] assert events == [ ( "claude_attachment_unclassified", @@ -415,7 +415,7 @@ def test_attachment_deferred_tools_delta_drops_body_text_keeps_names() -> None: ], "sess-delta", ) - events = [(e.event_type, e.payload) for e in parsed.session_events] + events = [(e.event_type, e.payload) for e in parsed.session_events if e.event_type != "claude_parse_coverage"] assert events == [ ( "claude_capability_delta", @@ -444,7 +444,7 @@ def test_attachment_skill_listing_extracts_names_not_full_text() -> None: ], "sess-skills", ) - events = [(e.event_type, e.payload) for e in parsed.session_events] + events = [(e.event_type, e.payload) for e in parsed.session_events if e.event_type != "claude_parse_coverage"] assert events == [ ( "claude_capability_snapshot", @@ -481,7 +481,7 @@ def test_attachment_diagnostics_bounds_to_per_file_counts() -> None: ], "sess-diag", ) - events = [(e.event_type, e.payload) for e in parsed.session_events] + events = [(e.event_type, e.payload) for e in parsed.session_events if e.event_type != "claude_parse_coverage"] assert events == [ ( "claude_diagnostics",