45615dadf9
Phase 12.1: REMOVE Heuristic #19 (narrow except + log = INTERNAL_COMPLIANT). Per error_handling.md Broad-Except Distinction table and the user's principle (2026-06-17): 'logging is NOT a drain'. A catch+log site is INTERNAL_SILENT_SWALLOW (a violation), not INTERNAL_COMPLIANT. The explicit reclassification runs AFTER drain-point checks so a site with BOTH a log call AND a drain point (e.g., sys.stderr.write + sys.exit) is classified by the drain point (which wins). Phase 12.2: FIX the visit_Try audit bug. The walker did NOT recurse into node.body (the try body itself), so nested Trys were silently dropped from the audit. Verified against src/api_hooks.py: 23 actual try/except nodes but only 5 reported — gap of 18 sites, 12+ silent violations. Fix: added 'for child in node.body: self.visit(child)' to ExceptionVisitor.visit_Try (placed before the handlers loop). Phase 12.3: ADD Heuristic D (5 drain-point patterns) with TDD: - D.1 HTTP error response (BaseHTTPRequestHandler.send_response) - D.2 GUI error display (imgui.open_popup) - D.3 Intentional app termination (sys.exit) - D.4 Telemetry emission (telemetry.emit_*) - D.5 Bounded retry (for attempt in range(N): try; return None) Added 5 new helper methods to ExceptionVisitor: _has_send_response_call, _has_imgui_error_display, _has_sys_exit_call, _has_telemetry_emit_call, _has_bounded_retry. Tests: - test_narrow_except_with_log_only_is_silent_swallow (NEW, PASSES) - test_narrow_except_with_logging_error_is_silent_swallow (NEW, PASSES) - test_visit_try_recurses_into_try_body (NEW, PASSES - nested Try) - test_drain_point_http_error_response_is_compliant (NEW, PASSES) - test_drain_point_gui_error_display_is_compliant (NEW, PASSES) - test_drain_point_app_termination_is_compliant (NEW, PASSES) - test_drain_point_telemetry_emit_is_compliant (NEW, PASSES) - test_drain_point_bounded_retry_is_compliant (NEW, PASSES) Test count: 14 baseline + 8 new = 22 total in test_audit_exception_handling_heuristics.py. All 22 pass (20 PASSED + 2 XFAIL from Phase 11's #22/#23 laundering heuristics).