mirror of
https://github.com/multica-ai/multica.git
synced 2026-08-13 19:43:27 +02:00
Two hang fields cost something and told us nothing, so both go. HANG STACK CAPTURE. Shipped in v0.4.13, flag published since v0.4.14, on in production — and every stack it produced was a single entry frame with an empty url. `Debugger.pause` lands on the next JS statement boundary, so when the block is in native code (layout, paint, GC, sync IPC) or the pause dispatches just after the block clears, the frame we get is the next function to run, not the one that blocked. It also only fires for hard hangs, so it sampled a fraction of a signal that was already useless. The price was a CDP debugger channel held open on every renderer for the whole session. The server key goes with it, and that is the part that matters for already-installed clients: v0.4.13–v0.4.18 are fail-closed on this flag, so no longer publishing `desktop_hang_stack_capture` is what makes them stop attaching a debugger. keys_test now pins the key as unpublished — re-adding it would put a flag flip back within reach of a fleet that still can't produce a usable stack. `recovered`. Hardcoded `false` at the only site that sets it. A recovered hang has its breadcrumb cleared and is reported by the in-thread watchdog instead, so the field could never be anything else. A machine upgrading from v0.4.18 can still have a breadcrumb on disk whose context holds a captured stack. `buildFreezeEventProps` builds props by whitelist, so it drops on its own — pinned by a test, since nothing sanitizes frames anymore. What stays: the longtask watchdog, the main-unresponsive breadcrumb with its bucketed route, client_crash, and $exception. Those are the signals carrying the analysis in MUL-5345. Co-authored-by: Claude Opus 5 <noreply@anthropic.com> Co-authored-by: multica-agent <github@multica.ai>