Stop a comment from being able to take the room down
Resolving anchors ran between applying the document and declaring it synced, inside a promise nobody catches. Anything that threw while working out where a decision pointed skipped the emit, so the editor stayed locked for the rest of the session and the status chip said 'Loading' forever — with the rejection swallowed by the void connect() that started it. That is a comment failing to paint costing the room its plan. Anchors now resolve after sync, not before it, and the call is guarded at both sites. Highlights decorate the prose; they are not a precondition for having it. Guarded everything else on that path for the same reason: ThreadStore.refresh per thread and as a whole, since it also runs as a Lexical update listener where a throw skips the listener that syncs; QuestionnaireStore.anchors, which had identical exposure and predates this feature; marks.paint, which my own plan said to wrap and I did not; Service.open and commit()'s rebuild path, where a throw would fail plan:open or strand the room on a dead epoch. The per-thread guard was initially too narrow — it covered resolving a passage but not reading the snapshot, and a malformed entry is as likely as an unresolvable one. Widened, so one bad record costs one card. Wire.#receive fanned frames out in an unisolated loop, so the first handler to throw silenced every handler after it for that kind. A broken sidecar would have stopped the transcript arriving. A failed open now says so instead of claiming to still be loading, which is the difference between a bug somebody can report and one they cannot. Nine new tests, each verified by reinstating the fault it covers.
Parent63534cb
13 files changed+512-44
StackedSplit