RejectCode
Why a host refused a joiner's AdmitMessage.Hello or AdmitMessage.Resume.
The structured companion to AdmitMessage.Reject.reason, which stays free text for humans reading a log. Before this existed a consumer had to string-match the reason to tell a transient refusal from a permanent one — and the two most consequential cases were not even distinguishable in principle, because the host sent the same words for both.
Open hierarchy (interface, not enum), mirroring us.tractat.kuilt.core.discovery.DiscoveryKind: a module outside :kuilt-session can supply its own code without amending this file. A code kuilt does not recognise — including one from a newer build, or from a peer that sends none at all — decodes as Unknown.
retryable defaults to true, deliberately. Retrying is what the joiner did before typed codes existed, so an unrecognised code preserves that behaviour exactly; only a code that explicitly declares itself terminal changes it. The dangerous direction is the other one: treating an unknown refusal as terminal would break the fast-reconnect race, where a resume that arrives before the host's detector fires is rejected and a retry a moment later succeeds.
Samples
when (reason.code) {
// Terminal: the window closed, the credential can never validate here, or the two peers
// speak incompatible protocol versions (retrying a version you don't support is futile).
RejectCode.ResumeWindowExpired, RejectCode.ResumeTokenInvalid,
RejectCode.RoomMismatch, RejectCode.ProtocolMismatch,
-> false
// Transient: the host hasn't opened the window yet (the fast-reconnect race).
RejectCode.ResumeWindowNotYetOpen -> true
// Anything else, including a code this build has never heard of.
else -> reason.code.retryable
}Inheritors
Types
The joiner declared an admit-protocol version this host cannot speak — outside ProtocolVersion.MIN_SUPPORTED..ProtocolVersion.MAX_SUPPORTED (#1569). Terminal: retrying a version you don't support is futile; the peer must upgrade or downgrade its build. A joiner that sends no version (a peer predating the field) is admitted as legacy, so this code never fires for the additive case.
The token failed structural validation (wrong room). Terminal.
The reconnect window closed — it elapsed, or the token was already spent. Terminal.
No reconnect window is open for this peer yet — the fast-reconnect race: the joiner re-wove and resumed before the host's own liveness detector noticed the drop. Retryable, and the retry is what recovers the session.
The joiner named a room this host does not serve. Terminal.
A code this build does not know: a peer that predates typed codes (empty id), a newer build's addition, or another module's own code. Retryable — see the type KDoc.