From 65c85107b69f5e2c20744f844a41d6e5eaa1d030 Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 17 May 2026 02:44:23 +0000 Subject: [PATCH] =?UTF-8?q?revert:=20restore=20audit-log=20kill=20switch?= =?UTF-8?q?=20=E2=80=94=20async=20redesign=20didn't=20help?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit User pulled d9e32e5 (async-writer audit log + re-enabled diagnostics sidebar) and still sees blank pages. The synchronous-write theory from the previous round was at most a partial explanation; something ELSE in the audit-log code path is also taking the page render down on the user's machine. Restore the kill switch so the user has a working app while we diagnose: - ``src/audit.py``: ``_DISABLED = True`` re-introduced at module top, each of ``log_event`` / ``log_session_start`` / ``log_page_open`` / ``flush_audit_log`` early-returns. The async writer thread is never started. - ``hide_streamlit_chrome``: ``_render_diagnostics_sidebar()`` call re-gated behind ``if False:``. The async writer code stays in place — easier to flip the flag back when we identify the real cause than to rewrite a third time. The shutdown-flush call in ``shutdown_app`` also stays; it early-returns on the kill switch and is harmless. Diagnostic plan for the next session: ask the user for the launcher terminal output (the new stderr "DataTools audit: writes failing..." message would tell us if the writer thread DID start and DID fail), and whether ``~/.datatools/logs/`` is being created at all. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/audit.py | 17 +++++++++++++++++ src/gui/components/_legacy.py | 23 ++++++++++++----------- 2 files changed, 29 insertions(+), 11 deletions(-) diff --git a/src/audit.py b/src/audit.py index 5c4956c..67daeed 100644 --- a/src/audit.py +++ b/src/audit.py @@ -55,6 +55,15 @@ _LOG_PATH: Path | None = None _SESSION_ID: str | None = None _SESSION_STARTED: bool = False +# RESTORED kill switch — the async-writer redesign still triggers the +# blank-pages symptom on the user's machine despite no synchronous +# file I/O on the request path. Cause is not yet identified; keep all +# log_* calls as no-ops while we diagnose so the GUI keeps working. +# Diagnostic plan: ask the user for the launcher terminal output AND +# whether anything appears in ``~/.datatools/logs/`` at all — that +# bisects "writer thread starts" from "writer thread can't write." +_DISABLED: bool = True + # Bounded in-memory queue. ``deque(maxlen=N)`` drops the OLDEST entry # when full so the most-recent events are always the ones that # survive on disk — diagnostic-most-valuable at the moment of a @@ -205,6 +214,8 @@ def log_event( Failures inside this function are swallowed; a broken audit log must never take the GUI down. """ + if _DISABLED: + return try: try: ts = datetime.now(tz=timezone.utc).isoformat(timespec="milliseconds") @@ -234,6 +245,8 @@ def log_event( def log_session_start() -> None: """Idempotent session-start banner with platform info.""" + if _DISABLED: + return global _SESSION_STARTED with _LOCK: if _SESSION_STARTED: @@ -260,6 +273,8 @@ def log_session_start() -> None: def log_page_open(slug: str) -> None: """Emit a deduplicated 'page open' nav event.""" + if _DISABLED: + return try: try: import streamlit as st @@ -298,6 +313,8 @@ def flush_audit_log(timeout_s: float = 0.5) -> None: stuck disk can never delay shutdown — events still in the queue when the timer expires are dropped. """ + if _DISABLED: + return global _SHUTDOWN_REQUESTED deadline = time.monotonic() + max(0.0, timeout_s) with _QUEUE_COND: diff --git a/src/gui/components/_legacy.py b/src/gui/components/_legacy.py index 8de67af..69f79ee 100644 --- a/src/gui/components/_legacy.py +++ b/src/gui/components/_legacy.py @@ -158,17 +158,18 @@ def hide_streamlit_chrome(*, gate_license: bool = True) -> None: require_license_or_render_activation, ) render_license_status_sidebar() - # Diagnostics sidebar re-enabled now that the audit log is async - # and ``audit_log_path()`` is a pure path computation (no mkdir - # on the request path). Still wrapped in try/except defensively; - # a render error here prints to stderr instead of taking down - # the page body. - try: - _render_diagnostics_sidebar() - except Exception: - import traceback, sys - print("DataTools: diagnostics sidebar render failed:", file=sys.stderr) - traceback.print_exc() + # Diagnostics sidebar is DISABLED — the async-writer redesign + # didn't actually fix the blank-pages symptom on the user's + # machine. The sidebar calls ``audit_log_path()`` which is pure + # now, so the failure mode must be elsewhere; keep this off + # while we diagnose so the user has a working GUI. + if False: + try: + _render_diagnostics_sidebar() + except Exception: + import traceback, sys + print("DataTools: diagnostics sidebar render failed:", file=sys.stderr) + traceback.print_exc() if gate_license: require_license_or_render_activation()