• fix(#20): heid-bug-hunt fixups — admin-stream + bifrost hardening (slice-6)

    vh released this 2026-07-19 13:13:44 -07:00

    Cold spec-free panel (Gróa + Hulda + Regin, source-verified by Heid): the adapter's
    core re-wrap is sound, but 4 real hardening gaps the conformance CR couldn't see —
    all in failure-path normalization + open-world degrade, judged against the general
    ConnectFailed floor + the degrade-never-crash promise. All fixed:

    • [bug, 3/3] stream_admin_events never mapped ConnectFailed — the SDK admin-stream
      open raises it on a connect-time / auth-resolution failure (the general transport
      floor; confirmed in the SDK source), and stream_turn + the bifrost GET both catch
      it, and this endpoint's OWN comment claimed it did. An unmapped ConnectFailed escaped
      the web gen's except (Sse*) and aborted the SSE with no stream_error. Now mapped
      → SseConnectFailed, mirroring stream_turn.
    • [bug, 2/3] non-str type crashed the web filter — the re-wrap used ev.type or ""
      (falsy-only), so a truthy non-str type (123, a list) reached .startswith →
      AttributeError. Now ev.type if isinstance(ev.type, str) else "" (matches the
      admin_id/data isinstance guards — same container-type class as slice-5).
    • [robustness] _session_bifrost_endpoint did dict(bstate) on the open-world 200
      body — a non-mapping (list/scalar) → TypeError/500. Now degrades to {} (I introduced
      this in slice-6 by changing JSONResponse(bstate) → dict(bstate)).
    • [robustness] _admin_events_endpoint.gen allocated the transport + built _wt_client
      BEFORE the try/finally — a construction failure would leak the httpx transport. Moved
      _wt_client inside the try so the finally always closes it.

    Voided (Heid): Regin's dict(ev.data) TypeError — the isinstance(_, Mapping) guard
    already routes non-mappings to {} before dict().

    Added adapter tests (ConnectFailed→SseConnectFailed; non-str type→"") + a web test
    (non-mapping bifrost body → 200 {}). Suite 494 green; my code ruff-clean (13 E501/F841
    in test_web_server.py are PRE-EXISTING, HEAD-identical, untouched); mypy clean on wt.py.
    Live smoke re-run clean (real session.created event re-wrapped; bifrost 404 envelope).
    Patch bump 0.21.19 → 0.21.20.

    Downloads