Two review nits:
1. Narrow the import-arm catch in _mark_sdk_wedged and
_clear_sdk_wedge_on_success to (ImportError, ModuleNotFoundError).
The bare `except Exception:` would have masked an AttributeError /
TypeError from a runtime_wedge API rename — silently degrading the
mirror to "no-op" and making heartbeat + the smoke gate (#131)
blind to claude-code wedges. The structural snapshot test in
molecule-core (task #169) catches the rename at PR-time. Older
runtimes that don't ship runtime_wedge at all still hit ImportError
and silently no-op — the local sticky flag still gates is_wedged()
inside this module so internal callers keep working.
2. Add mirror-CALL-failure injection tests. The recorder used by the
original tests never raised, so the inner try around
_mark_runtime_wedged(reason) (and the symmetric clear) wasn't
pinned. New tests inject a recorder whose mark/clear raise on call,
then assert: (a) the call attempt was recorded, (b) the local
sticky flag stayed correct, (c) the failure was logged at ERROR.
Pins both the contract ("mirror is best-effort, local is source of
truth") AND the operator-visible signal (an ERROR log line is the
only way to see a silent mirror regression).
Regression-injection-checked: removing the call-side try arm makes
both new tests fail with clear messages. Tests: 7 in
test_runtime_wedge_mirror.py, 45 across the whole tests/ tree.
The local _sdk_wedged_reason flag was only observed inside this module
— heartbeat reads runtime_wedge.is_wedged() (universal cross-cutting
holder) and so does the new boot-smoke gate from molecule-core PR
#2473 / task #131. Without the mirror, a wedged claude-code workspace
stayed green-dot on the canvas while every chat hung, AND the
publish-image gate could not catch PR-25-class init wedges before
the broken image shipped to GHCR.
_mark_sdk_wedged now mirrors into runtime_wedge.mark_wedged, and
_clear_sdk_wedge_on_success mirrors into runtime_wedge.clear_wedge.
Both are best-effort — older runtimes that don't ship runtime_wedge
silently no-op the mirror, so a template pinned to an older runtime
still boots. Mirror exceptions are logged but don't suppress the
local sticky flag, so internal callers (retry loop, cancel handler)
see consistent state regardless of the universal-side outcome.
Tests cover: mark mirrors with reason, first-call-wins propagates,
clear mirrors, no-op when not wedged, ImportError-resilience.
Regression-injection-checked: silencing the mirror branch fails the
mark+first-wins tests at unit-test time with a clear message naming
the missing runtime_wedge call.