On a roll the old pod keeps serving its open Blazor circuits while it drains. The mesh's teardown then drains the I/O pool (IoPoolRegistry.DrainAll), and every read still in flight ends with a cooperative cancellation: TaskCanceledException: A task was canceled. The circuit is still open, so the cancellation reaches views that are not yet disposed. BlazorView.SurfaceError used to treat only the view's own disposal as teardown. It therefore logged the process's teardown at Error and showed the error modal.

Measured once (MeshWeaver#7020): during a roll of an AKS instance, three lines fail: ThreadChatView … Resolving the composer's context arrived within the same millisecond, from two ThreadChatViews of one circuit (areas Composer and Thread/1). They came from the old pod, while the roll's "Verify one generation" phase was running.

The fault is… while… SurfaceError does
anything the view is disposed, or it is an ObjectDisposedException Debug, no modal (unchanged)
a cooperative cancellation (CancellationClassifier.IsCooperativeCancellation) the portal hub is shutting down or the host has begun stopping (hub.IsLeaving()) Debug, no modal
a cooperative cancellation the host keeps running Error, the modal: a binding ended for no stated reason
a cancellation that expresses a timeout (a TimeoutException inside it) anything Error, the modal: an availability failure
a SyncStreamOwnerRefusedException at any depth (a stream that gave up re-subscribing to a ShuttingDown owner) the host is leaving Debug, no modal
a SyncStreamOwnerRefusedException the host keeps running Error, the modal: an owner that did not come back

The classifier is BlazorView.IsHostTeardownCancellation(error, hostLeaving). The probe is asked only for a cooperative cancellation. A hub whose scope is already disposed counts as leaving.

The same teardown, answered by routing (MeshWeaver#7575)

Not every read in flight is an I/O leaf. A read that needs a re-subscribe while the process is stopping is refused by that process's own router: Host is shutting down, cannot route to …. The sync stream rides that out on its bounded budget (see core's Doc/Architecture/RidingOutAShuttingDownAddress), and then ENDS with SyncStreamOwnerRefusedException so that its readers can re-read. On a terminating replica no re-read can be answered: the circuit dies with the pod, and its reconnect lands on a live replica. Measured once: in one second of a roll, a terminating pod logged 30 or more such faults across every view of its open circuits (CollaborativeMarkdownView, MarkdownEditorView, ThreadChatView, ButtonView, ContainerView and others), each at Error and each in the modal.

The classifier is BlazorView.IsHostTeardownRefusal(error, hostLeaving), and it uses the same probe. The same refusal on a host that keeps running stays fail-visible, because there it means an owner that never came back.

Every view that routes its onError through SurfaceError gets this arm, directly or through SurfaceReadError or the data-binding fault path. ThreadChatView's composer context chip is one of them.

Regression tests: HostTeardownCancellationTest.AReadCancelledByTheTeardownOfAStoppingHost_RaisesNoErrorModal and its control, AReadCancelledWhileTheHostKeepsRunning_StillRaisesTheErrorModal. Both bind a view to a leaf of a real IoPool and end it with a real Drain(). The control proves the silence is the probe-gated arm, not a fault that never arrived. OnlyACooperativeCancellationOnALeavingHost_IsHostTeardown pins the predicate's boundary. For the routing refusal: AReadRefusedByTheRouterOfAStoppingHost_RaisesNoErrorModal, its control AReadRefusedWhileTheHostKeepsRunning_StillRaisesTheErrorModal, and OnlyAnOwnerRefusalOnALeavingHost_IsHostTeardownRefusal.

Related: a node deleted under an open view is not a fault.