sessions
Generated by the pinned ess generate --kind docs from ess. Structural validation establishes consistency; behaviour, storage and cross-record predicates remain implementation obligations.
Proposed supervising session lifecycle; timed enforcement remains a binding obligation.
connectors.sessions is one of connectors's bounded contexts. Back to the index.
Types
Binding
connectors.sessions.Binding is a record of four fields:
instance_ref—Stringconnection_ref—Stringadmitted_revision—Stringauthority_ref—String
CleanupDecision
connectors.sessions.CleanupDecision is one of released and unaccounted.
DataLease
connectors.sessions.DataLease is a record of three fields:
issued_at—Timestampeffective_expiry—Timestampsequence—Integer
GateDecision
connectors.sessions.GateDecision is one of allow, expired, revoked and unverified.
PeerShutdown
connectors.sessions.PeerShutdown is one of confirmed and unconfirmed.
Placement
connectors.sessions.Placement is one of local, direct and relay.
Profile
connectors.sessions.Profile is one of outbound and inbound_offer.
SessionId
connectors.sessions.SessionId wraps String and is not interchangeable with one: the whole value of naming it separately is the crossings the model then refuses.
TerminalActor
connectors.sessions.TerminalActor is one of adapter, application and host.
TerminalFact
connectors.sessions.TerminalFact is a record of three fields:
reason—connectors.sessions.TerminalReasonby—connectors.sessions.TerminalActoraccepted_at—Timestamp
TerminalReason
connectors.sessions.TerminalReason is one of remote_hangup, local_close, cancelled, rejected, expired, revoked, lease_expired, media_overload, media_incompatible, transport_lost and error.
Entities
An entity is what this context is about: something with an identity that outlives any one request, a shape, and a lifecycle. The lifecycle is exhaustive — a move that is not drawn below is a move this specification does not permit, and that is the only way it says so. Every move is labelled with the command that takes it, because a move nothing can trigger is refused rather than drawn.
Session
connectors.sessions.Session.
An instance is identified by session_id, a connectors.sessions.SessionId. The name is part of the model and not a convention: a view projects the identity under that name, so a projection inventing its own would disagree with the view.
It holds:
binding—connectors.sessions.Bindingprofile—connectors.sessions.Profileplacement—connectors.sessions.Placementstreams—List<String>data_lease—Optional<connectors.sessions.DataLease>, which may be absentterminal—Optional<connectors.sessions.TerminalFact>, which may be absent
It declares no relation to another entity, and no other entity names it.
No invariant is declared, so nothing here constrains an instance at rest.
Its state is a connectors.sessions.Session.State, one of Closed, Closing, Establishing, Lost, Offered and Ready. That enum is synthesised from the lifecycle rather than declared beside it, so the states a view's filter compares and the states drawn below cannot disagree.
An instance is created in Offered. Closed and Lost are terminal, so an instance may rest there forever. That is declared rather than inferred from having no way out: an entity that cannot leave a state is either finished or stuck, and only its author knows which.
Each move is taken by a declared command outcome, and a move nothing takes is refused as missing_causation rather than left as a state change nobody can trigger:
accept— taken byconnectors.sessions.AcceptOfferon itsacceptedoutcomeready— taken byconnectors.sessions.EstablishReadyon itsreadyoutcomepermit_data— taken byconnectors.sessions.PermitDataon itspermittedoutcomerenew— taken byconnectors.sessions.RenewDataLeaseon itsrenewedoutcomedeny_ready— taken byconnectors.sessions.EstablishReadyon itsauthority-terminatedoutcomedeny_data— taken byconnectors.sessions.PermitDataon itsauthority-terminatedoutcomedeny_renewal— taken byconnectors.sessions.RenewDataLeaseon itsauthority-terminatedoutcomebegin_close— taken byconnectors.sessions.BeginCloseon itsclosingoutcomeclose— taken byconnectors.sessions.FinishTeardownon itsclosedoutcomecleanup_lost— taken byconnectors.sessions.FinishTeardownon itslostoutcomecontinuity_lost— taken byconnectors.sessions.LoseContinuityon itslostoutcome
An instance is brought into existence by connectors.sessions.OfferSession on its offered outcome.
Illegal transitions are illegal by absence: no rule forbids them, there is simply no arrow, because a rule would be a second place for the same truth to live. A diagram cannot show an absence, so the pairs it does not connect are listed here, derived from the same transitions — anything named below is a move this specification does not permit.
Closedmay not becomeClosingClosedmay not becomeEstablishingClosedmay not becomeLostClosedmay not becomeOfferedClosedmay not becomeReadyClosingmay not becomeEstablishingClosingmay not becomeOfferedClosingmay not becomeReadyEstablishingmay not becomeClosedEstablishingmay not becomeOfferedLostmay not becomeClosedLostmay not becomeClosingLostmay not becomeEstablishingLostmay not becomeOfferedLostmay not becomeReadyOfferedmay not becomeClosedOfferedmay not becomeReadyReadymay not becomeClosedReadymay not becomeEstablishingReadymay not becomeOffered
One view projects it: SessionStates.
Views
A view is what the outside world is promised it can observe. Each one says which instances it contains and how soon it reflects a command that has already returned, because "you can read this" without "how soon" is the promise every flaky suite is built on.
SessionStates
connectors.sessions.SessionStates.
It reads Session.
It contains every instance of that entity: no filter narrows it, which is a decision somebody made and not a line somebody omitted.
It exposes:
session_id—connectors.sessions.SessionIdstate—connectors.sessions.Session.Stateterminal—Optional<connectors.sessions.TerminalFact>, which may be absent
It declares no order, so the rows come back in whatever order the implementation has, and two reads may disagree.
Read-your-writes: it is current the moment the command that changed it returns. A caller that has just created an invoice and cannot see it in here has been told a lie about what it did.
A generated scenario asserts it once, immediately after the command: a view promising this and not keeping the promise has to fail the suite rather than be retried until it passes.
Commands
AcceptOffer
connectors.sessions.AcceptOffer.
It takes:
session_id—connectors.sessions.SessionId
It has two outcomes.
accepted — The default branch, taken when no other outcome's condition matched. It moves a connectors.sessions.Session from Offered to Establishing, along the declared move accept. The instance is the one named by the input field session_id. It emits connectors.sessions.OfferAccepted. A test reaches it by constructing an input that satisfies no other outcome's condition.
wrong-state — Taken when the subject is resting in a state none of this command's moves start from — a connectors.sessions.Session in Closed, Closing, Establishing, Lost and Ready, which is what is left of the lifecycle once this command's own moves are taken away. The document lists none of it. No entity in this specification changes. It reports connectors.sessions.StateConflict, carrying state. It emits nothing. A test reaches it by driving an instance into one of those states and then issuing the command, because no input selects this branch.
BeginClose
connectors.sessions.BeginClose.
It takes:
session_id—connectors.sessions.SessionIdterminal—connectors.sessions.TerminalFactcutoff_due_at—Timestampteardown_due_at—Timestamp
It has two outcomes.
closing — The default branch, taken when no other outcome's condition matched. It moves a connectors.sessions.Session from Establishing, Offered and Ready to Closing, along the declared move begin_close. The instance is the one named by the input field session_id. It emits connectors.sessions.ClosingBegun. A test reaches it by constructing an input that satisfies no other outcome's condition.
wrong-state — Taken when the subject is resting in a state none of this command's moves start from — a connectors.sessions.Session in Closed, Closing and Lost, which is what is left of the lifecycle once this command's own moves are taken away. The document lists none of it. No entity in this specification changes. It reports connectors.sessions.StateConflict, carrying state. It emits nothing. A test reaches it by driving an instance into one of those states and then issuing the command, because no input selects this branch.
EstablishReady
connectors.sessions.EstablishReady.
It takes:
session_id—connectors.sessions.SessionIddecision—connectors.sessions.GateDecisionlease—connectors.sessions.DataLease
It has three outcomes.
ready — Taken when decision == allow holds of the input. It moves a connectors.sessions.Session from Establishing to Ready, along the declared move ready. The instance is the one named by the input field session_id. It emits connectors.sessions.SessionReady. A test reaches it by constructing an input that satisfies that condition.
authority-terminated — The default branch, taken when no other outcome's condition matched. It moves a connectors.sessions.Session from Establishing to Closing, along the declared move deny_ready. The instance is the one named by the input field session_id. It emits connectors.sessions.DataAuthorityTerminated. A test reaches it by constructing an input that satisfies no other outcome's condition.
wrong-state — Taken when the subject is resting in a state none of this command's moves start from — a connectors.sessions.Session in Closed, Closing, Lost, Offered and Ready, which is what is left of the lifecycle once this command's own moves are taken away. The document lists none of it. No entity in this specification changes. It reports connectors.sessions.StateConflict, carrying state. It emits nothing. A test reaches it by driving an instance into one of those states and then issuing the command, because no input selects this branch.
FinishTeardown
connectors.sessions.FinishTeardown.
It takes:
session_id—connectors.sessions.SessionIddecision—connectors.sessions.CleanupDecisionpeer_shutdown—connectors.sessions.PeerShutdown
It has three outcomes.
closed — Taken when decision == released holds of the input. It moves a connectors.sessions.Session from Closing to Closed, along the declared move close. The instance is the one named by the input field session_id. It emits connectors.sessions.LocalResourcesReleased. A test reaches it by constructing an input that satisfies that condition.
lost — The default branch, taken when no other outcome's condition matched. It moves a connectors.sessions.Session from Closing to Lost, along the declared move cleanup_lost. The instance is the one named by the input field session_id. It emits connectors.sessions.LocalCleanupUnaccounted. A test reaches it by constructing an input that satisfies no other outcome's condition.
wrong-state — Taken when the subject is resting in a state none of this command's moves start from — a connectors.sessions.Session in Closed, Establishing, Lost, Offered and Ready, which is what is left of the lifecycle once this command's own moves are taken away. The document lists none of it. No entity in this specification changes. It reports connectors.sessions.StateConflict, carrying state. It emits nothing. A test reaches it by driving an instance into one of those states and then issuing the command, because no input selects this branch.
LoseContinuity
connectors.sessions.LoseContinuity.
It takes:
session_id—connectors.sessions.SessionId
It has two outcomes.
lost — The default branch, taken when no other outcome's condition matched. It moves a connectors.sessions.Session from Closing, Establishing, Offered and Ready to Lost, along the declared move continuity_lost. The instance is the one named by the input field session_id. It emits connectors.sessions.ContinuityLost. A test reaches it by constructing an input that satisfies no other outcome's condition.
wrong-state — Taken when the subject is resting in a state none of this command's moves start from — a connectors.sessions.Session in Closed and Lost, which is what is left of the lifecycle once this command's own moves are taken away. The document lists none of it. No entity in this specification changes. It reports connectors.sessions.StateConflict, carrying state. It emits nothing. A test reaches it by driving an instance into one of those states and then issuing the command, because no input selects this branch.
OfferSession
connectors.sessions.OfferSession.
It takes:
binding—connectors.sessions.Bindingprofile—connectors.sessions.Profileplacement—connectors.sessions.Placementstreams—List<String>
It has one outcome.
offered — The default branch, taken when no other outcome's condition matched. It creates a connectors.sessions.Session, which starts in Offered. The new instance's identity is published as session_id on connectors.sessions.SessionOffered. It emits connectors.sessions.SessionOffered. A test reaches it by constructing an input that satisfies no other outcome's condition.
PermitData
connectors.sessions.PermitData.
It takes:
session_id—connectors.sessions.SessionIddecision—connectors.sessions.GateDecisiondirection—String
It has three outcomes.
permitted — Taken when decision == allow holds of the input. It moves a connectors.sessions.Session from Ready to Ready, along the declared move permit_data. The instance is the one named by the input field session_id. It emits connectors.sessions.DataPermitted. A test reaches it by constructing an input that satisfies that condition.
authority-terminated — The default branch, taken when no other outcome's condition matched. It moves a connectors.sessions.Session from Ready to Closing, along the declared move deny_data. The instance is the one named by the input field session_id. It emits connectors.sessions.DataAuthorityTerminated. A test reaches it by constructing an input that satisfies no other outcome's condition.
wrong-state — Taken when the subject is resting in a state none of this command's moves start from — a connectors.sessions.Session in Closed, Closing, Establishing, Lost and Offered, which is what is left of the lifecycle once this command's own moves are taken away. The document lists none of it. No entity in this specification changes. It reports connectors.sessions.StateConflict, carrying state. It emits nothing. A test reaches it by driving an instance into one of those states and then issuing the command, because no input selects this branch.
RenewDataLease
connectors.sessions.RenewDataLease.
It takes:
session_id—connectors.sessions.SessionIddecision—connectors.sessions.GateDecisionlease—connectors.sessions.DataLease
It has three outcomes.
renewed — Taken when decision == allow holds of the input. It moves a connectors.sessions.Session from Ready to Ready, along the declared move renew. The instance is the one named by the input field session_id. It emits connectors.sessions.DataLeaseRenewed. A test reaches it by constructing an input that satisfies that condition.
authority-terminated — The default branch, taken when no other outcome's condition matched. It moves a connectors.sessions.Session from Ready to Closing, along the declared move deny_renewal. The instance is the one named by the input field session_id. It emits connectors.sessions.DataAuthorityTerminated. A test reaches it by constructing an input that satisfies no other outcome's condition.
wrong-state — Taken when the subject is resting in a state none of this command's moves start from — a connectors.sessions.Session in Closed, Closing, Establishing, Lost and Offered, which is what is left of the lifecycle once this command's own moves are taken away. The document lists none of it. No entity in this specification changes. It reports connectors.sessions.StateConflict, carrying state. It emits nothing. A test reaches it by driving an instance into one of those states and then issuing the command, because no input selects this branch.
Events
ClosingBegun
connectors.sessions.ClosingBegun.
It carries:
session_id—connectors.sessions.SessionIdterminal—connectors.sessions.TerminalFactcutoff_due_at—Timestampteardown_due_at—Timestamp
Emitted by connectors.sessions.BeginClose on its closing outcome.
Nothing in this system reacts to it.
ContinuityLost
connectors.sessions.ContinuityLost.
It carries:
session_id—connectors.sessions.SessionId
Emitted by connectors.sessions.LoseContinuity on its lost outcome.
Nothing in this system reacts to it.
DataAuthorityTerminated
connectors.sessions.DataAuthorityTerminated.
It carries:
session_id—connectors.sessions.SessionIddecision—connectors.sessions.GateDecision
Emitted by connectors.sessions.EstablishReady on its authority-terminated outcome.
Emitted by connectors.sessions.PermitData on its authority-terminated outcome.
Emitted by connectors.sessions.RenewDataLease on its authority-terminated outcome.
Nothing in this system reacts to it.
DataLeaseRenewed
connectors.sessions.DataLeaseRenewed.
It carries:
session_id—connectors.sessions.SessionIdlease—connectors.sessions.DataLease
Emitted by connectors.sessions.RenewDataLease on its renewed outcome.
Nothing in this system reacts to it.
DataPermitted
connectors.sessions.DataPermitted.
It carries:
session_id—connectors.sessions.SessionIddirection—String
Emitted by connectors.sessions.PermitData on its permitted outcome.
Nothing in this system reacts to it.
LocalCleanupUnaccounted
connectors.sessions.LocalCleanupUnaccounted.
It carries:
session_id—connectors.sessions.SessionId
Emitted by connectors.sessions.FinishTeardown on its lost outcome.
Nothing in this system reacts to it.
LocalResourcesReleased
connectors.sessions.LocalResourcesReleased.
It carries:
session_id—connectors.sessions.SessionIdpeer_shutdown—connectors.sessions.PeerShutdown
Emitted by connectors.sessions.FinishTeardown on its closed outcome.
Nothing in this system reacts to it.
OfferAccepted
connectors.sessions.OfferAccepted.
It carries:
session_id—connectors.sessions.SessionId
Emitted by connectors.sessions.AcceptOffer on its accepted outcome.
Nothing in this system reacts to it.
SessionOffered
connectors.sessions.SessionOffered.
It carries:
session_id—connectors.sessions.SessionId
Emitted by connectors.sessions.OfferSession on its offered outcome.
Nothing in this system reacts to it.
SessionReady
connectors.sessions.SessionReady.
It carries:
session_id—connectors.sessions.SessionIdlease—connectors.sessions.DataLease
Emitted by connectors.sessions.EstablishReady on its ready outcome.
Nothing in this system reacts to it.
Errors
StateConflict
It carries:
state—connectors.sessions.Session.State
Reported by connectors.sessions.AcceptOffer on its wrong-state outcome.
Reported by connectors.sessions.BeginClose on its wrong-state outcome.
Reported by connectors.sessions.EstablishReady on its wrong-state outcome.
Reported by connectors.sessions.FinishTeardown on its wrong-state outcome.
Reported by connectors.sessions.LoseContinuity on its wrong-state outcome.
Reported by connectors.sessions.PermitData on its wrong-state outcome.
Reported by connectors.sessions.RenewDataLease on its wrong-state outcome.
Generated from connectors v1 · model digest e1e1672d0af4753cb8f2da6c0b22a7f6ae8ce9f7abc168f86169babdf1325787 · contract digest slice-sha256/2:ec004793a058bf5edc9ff32d85018846bef1611d44fc1835481ed72a8dfe0b1a. Do not edit this file; change the specification and regenerate it with ess generate.