ResumeResult

sealed interface ResumeResult

How a resume attempt turned out — on either side of the protocol.

The two sides see disjoint halves of this hierarchy, and the halves are named so the compiler can enforce it (#2364):

Why the split is typed rather than documented. Both surfaces used to return the whole hierarchy, so a consumer could — and the agent cookbook did — write a when over Room.resume(token) with arms for WindowNotYetOpen and TokenInvalid, which are host verdicts a joiner can never receive. It compiled, so nothing caught it; @sample compilation proves a branch typechecks, never that it is reachable. Narrowing the two return types makes that same when a compile error.

Inheritors

Types

Link copied to clipboard
sealed interface HostVerdict : ResumeResult

The half a host renders: what JoinerReconnectController.tryResume decided about its own window state. Travels to the joiner as a RejectCode, not as one of these values.

Link copied to clipboard
sealed interface JoinerOutcome : ResumeResult

The half a joiner observes from us.tractat.kuilt.session.Room.resume: the host's answer (Success / Refused), its silence (TimedOut), or the local room having nothing left to resume onto (WindowClosed).

Link copied to clipboard
data class Refused(val message: String, val code: RejectCode) : ResumeResult.JoinerOutcome

The host answered, and said no — an AdmitMessage.Reject carrying its raw message and structured code (#2364).

Link copied to clipboard

The token was valid and the window was open. Peer is now resumed.

Link copied to clipboard

No verdict — neither ResumeAck nor Reject — arrived within HeartbeatConfig.resumeTimeout.

Link copied to clipboard
data class TokenInvalid(val reason: String) : ResumeResult.HostVerdict

The token failed structural validation. reason describes the failure.

Link copied to clipboard

There is no window to resume onto, and no host refusal was involved.

Link copied to clipboard

No window has opened for this peer yet.