------------------------------ MODULE Lazaret ------------------------------ EXTENDS Naturals, FiniteSets, Sequences, TLC (*************************************************************************** Application-wide protocol model for Lazaret. The model covers Domain startup, ordered resource preparation, role-separated runtime identity tuples, sandbox launch isolation, Client Session registration, host escalation, correlated result delivery, terminal ownership, failure, and teardown. Cryptographic algorithms, serialization, container commands, filesystems, and network packet handling are refinement boundaries validated by implementation tests rather than modeled internally. ***************************************************************************) CONSTANTS Domains, Sessions, Requests, Commands, Identities, SessionAnchors, NoSession, NoRequest, NoCommand, NoApproval, SessionDomain, SessionFingerprint, DomainFingerprint, DomainCoordinatorIdentity, DomainSidecarIdentity, DomainSandboxIdentity, SessionCliIdentity, SessionAnchorIdentity, CoordinatorCertificateValid, SidecarCertificateValid, SandboxCertificateValid, CliCertificateValid, ConfigSafe, SandboxIsolationSafe, RequestSession, RequestCommand, RequestSandboxIdentity, RequestCliIdentity, RequestSessionAnchor, RequestCredentialValid, RequestSignatureValid, ApprovalCliIdentity, ApprovalSessionAnchor, ApprovalSignatureValid, ApprovalCommand, AutoRuleMatches, CommandRequiresShell, CommandContentSafe, D1, S1, S2, R1, R2, R3, ExactCmd, PromptCmd, ShellCmd, EditedCmd ASSUME /\ IsFiniteSet(Domains) /\ IsFiniteSet(Sessions) /\ IsFiniteSet(Requests) /\ IsFiniteSet(Commands) /\ IsFiniteSet(Identities) /\ IsFiniteSet(SessionAnchors) /\ Domains # {} /\ Sessions # {} /\ Requests # {} /\ NoSession \notin Sessions /\ NoRequest \notin Requests /\ NoCommand \notin Commands /\ SessionDomain \in [Sessions -> Domains] /\ SessionFingerprint \in [Sessions -> STRING] /\ DomainFingerprint \in [Domains -> STRING] /\ DomainCoordinatorIdentity \in [Domains -> Identities] /\ DomainSidecarIdentity \in [Domains -> Identities] /\ DomainSandboxIdentity \in [Domains -> Identities] /\ SessionCliIdentity \in [Sessions -> Identities] /\ SessionAnchorIdentity \in [Sessions -> SessionAnchors] /\ CoordinatorCertificateValid \in [Domains -> BOOLEAN] /\ SidecarCertificateValid \in [Domains -> BOOLEAN] /\ SandboxCertificateValid \in [Domains -> BOOLEAN] /\ CliCertificateValid \in [Sessions -> BOOLEAN] /\ ConfigSafe \in [Domains -> BOOLEAN] /\ SandboxIsolationSafe \in [Domains -> BOOLEAN] /\ RequestSession \in [Requests -> Sessions] /\ RequestCommand \in [Requests -> Commands] /\ RequestSandboxIdentity \in [Requests -> Identities] /\ RequestCliIdentity \in [Requests -> Identities] /\ RequestSessionAnchor \in [Requests -> SessionAnchors] /\ RequestCredentialValid \in [Requests -> BOOLEAN] /\ RequestSignatureValid \in [Requests -> BOOLEAN] /\ ApprovalCliIdentity \in [Requests -> Identities] /\ ApprovalSessionAnchor \in [Requests -> SessionAnchors] /\ ApprovalSignatureValid \in [Requests -> BOOLEAN] /\ ApprovalCommand \in [Requests -> Commands] /\ AutoRuleMatches \in [Requests -> BOOLEAN] /\ CommandRequiresShell \in [Commands -> BOOLEAN] /\ CommandContentSafe \in [Commands -> BOOLEAN] DomainPhases == { "Absent", "Starting", "Ready", "Stopping", "Failed", "Recovering" } CoordinatorStates == {"Absent", "Starting", "Ready", "Stopping", "Failed"} MountStates == {"Unmounted", "Mounted"} ResourceStates == {"Stopped", "Ready", "Failed"} PhysicalProcessStates == {"Absent", "Starting", "Alive", "Stopped", "Dead"} RuntimeCausalEdgeStates == {"Unarmed", "Armed"} SessionPhases == { "New", "Waiting", "Registering", "Attached", "Prompting", "HostExecuting", "Closed", "Failed" } TerminalRoutes == {"Detached", "Sandbox", "Prompt", "HostProcess"} ConnectionStates == {"Disconnected", "Connected"} RequestPhases == { "Unused", "Verified", "AwaitingApproval", "Approved", "Executing", "CompletionPending", "DenialPending", "TimeoutPending", "CancellationPending", "FailurePending", "Completed", "Denied", "TimedOut", "Cancelled", "Failed" } ApprovalSources == {NoApproval, "AutoRule", "Developer"} PendingResultPhases == { "CompletionPending", "DenialPending", "TimeoutPending", "CancellationPending", "FailurePending" } TerminalRequestPhases == {"Completed", "Denied", "TimedOut", "Cancelled", "Failed"} DeliveredResultPhase(p) == CASE p = "CompletionPending" -> "Completed" [] p = "DenialPending" -> "Denied" [] p = "TimeoutPending" -> "TimedOut" [] p = "CancellationPending" -> "Cancelled" [] p = "FailurePending" -> "Failed" (*************************************************************************** Finite fixture operators used by Lazaret.cfg. The protocol itself depends only on the abstract constants above; other TLC configurations may override them with different finite operators. ***************************************************************************) DomainsFixture == {D1} SessionsFixture == {S1, S2} RequestsFixture == {R1, R2, R3} CommandsFixture == {ExactCmd, PromptCmd, ShellCmd, EditedCmd} IdentitiesFixture == { "coordinator-1", "sidecar-1", "sandbox-1", "sandbox-other", "cli-1", "cli-2" } SessionAnchorsFixture == {"anchor-1", "anchor-2"} SessionDomainFixture == (S1 :> D1) @@ (S2 :> D1) SessionFingerprintFixture == (S1 :> "config-a") @@ (S2 :> "config-a") DomainFingerprintFixture == D1 :> "config-a" DomainCoordinatorIdentityFixture == D1 :> "coordinator-1" DomainSidecarIdentityFixture == D1 :> "sidecar-1" DomainSandboxIdentityFixture == D1 :> "sandbox-1" SessionCliIdentityFixture == (S1 :> "cli-1") @@ (S2 :> "cli-2") SessionAnchorIdentityFixture == (S1 :> "anchor-1") @@ (S2 :> "anchor-2") CoordinatorCertificateValidFixture == D1 :> TRUE SidecarCertificateValidFixture == D1 :> TRUE SandboxCertificateValidFixture == D1 :> TRUE CliCertificateValidFixture == (S1 :> TRUE) @@ (S2 :> TRUE) ConfigSafeFixture == D1 :> TRUE SandboxIsolationSafeFixture == D1 :> TRUE RequestSessionFixture == (R1 :> S1) @@ (R2 :> S2) @@ (R3 :> S1) RequestCommandFixture == (R1 :> ExactCmd) @@ (R2 :> PromptCmd) @@ (R3 :> ShellCmd) RequestSandboxIdentityFixture == (R1 :> "sandbox-1") @@ (R2 :> "sandbox-1") @@ (R3 :> "sandbox-other") RequestCliIdentityFixture == (R1 :> "cli-1") @@ (R2 :> "cli-2") @@ (R3 :> "cli-1") RequestSessionAnchorFixture == (R1 :> "anchor-1") @@ (R2 :> "anchor-2") @@ (R3 :> "anchor-1") RequestCredentialValidFixture == (R1 :> TRUE) @@ (R2 :> TRUE) @@ (R3 :> TRUE) RequestSignatureValidFixture == (R1 :> TRUE) @@ (R2 :> TRUE) @@ (R3 :> TRUE) ApprovalCliIdentityFixture == (R1 :> "cli-1") @@ (R2 :> "cli-2") @@ (R3 :> "cli-1") ApprovalSessionAnchorFixture == (R1 :> "anchor-1") @@ (R2 :> "anchor-2") @@ (R3 :> "anchor-1") ApprovalSignatureValidFixture == (R1 :> TRUE) @@ (R2 :> TRUE) @@ (R3 :> TRUE) ApprovalCommandFixture == (R1 :> ExactCmd) @@ (R2 :> EditedCmd) @@ (R3 :> ShellCmd) AutoRuleMatchesFixture == (R1 :> TRUE) @@ (R2 :> FALSE) @@ (R3 :> TRUE) CommandRequiresShellFixture == (ExactCmd :> FALSE) @@ (PromptCmd :> FALSE) @@ (ShellCmd :> TRUE) @@ (EditedCmd :> FALSE) CommandContentSafeFixture == (ExactCmd :> TRUE) @@ (PromptCmd :> TRUE) @@ (ShellCmd :> TRUE) @@ (EditedCmd :> TRUE) VARIABLES domainPhase, coordinatorState, stateAnchorState, sidecarState, sandboxState, trustReady, lockOwner, published, registered, connected, sessionPhase, terminalRoute, connectionState, activeRequest, requestPhase, approvalSource, approvedCommand, hostRunning, domainLockHeld, hostCoordinatorProc, runtimeSupervisorProc, attachedRunscProc, runtimeCausalEdge, runtimeFaultsRemaining vars == << domainPhase, coordinatorState, stateAnchorState, sidecarState, sandboxState, trustReady, lockOwner, published, registered, connected, sessionPhase, terminalRoute, connectionState, activeRequest, requestPhase, approvalSource, approvedCommand, hostRunning, domainLockHeld, hostCoordinatorProc, runtimeSupervisorProc, attachedRunscProc, runtimeCausalEdge, runtimeFaultsRemaining >> Dom(s) == SessionDomain[s] ReqSession(r) == RequestSession[r] ReqDomain(r) == Dom(ReqSession(r)) IsTerminalRequest(r) == requestPhase[r] \in TerminalRequestPhases ProcessPresent(state) == state \in {"Alive", "Stopped"} ProcessResponsive(state) == state = "Alive" RuntimeLogicalAuthorityPresent(d) == \/ ProcessPresent(hostCoordinatorProc[d]) \/ ProcessPresent(runtimeSupervisorProc[d]) \/ ProcessPresent(attachedRunscProc[d]) RuntimeAuthorityResponsive(d) == \/ ProcessResponsive(hostCoordinatorProc[d]) \/ ProcessResponsive(runtimeSupervisorProc[d]) \/ ProcessResponsive(attachedRunscProc[d]) RuntimeGenerationAbsent(d) == /\ ~domainLockHeld[d] /\ hostCoordinatorProc[d] = "Absent" /\ runtimeSupervisorProc[d] = "Absent" /\ attachedRunscProc[d] = "Absent" /\ runtimeCausalEdge[d] = "Unarmed" ConsumeRuntimeFault(d) == /\ runtimeFaultsRemaining[d] > 0 /\ runtimeFaultsRemaining' = [runtimeFaultsRemaining EXCEPT ![d] = @ - 1] RuntimeIdentityTupleAuthorized(d) == /\ trustReady[d] /\ domainPhase[d] = "Ready" /\ d \in published /\ sidecarState[d] = "Ready" /\ sandboxState[d] = "Ready" /\ RuntimeLogicalAuthorityPresent(d) /\ CoordinatorCertificateValid[d] /\ SidecarCertificateValid[d] /\ SandboxCertificateValid[d] /\ Cardinality({ DomainCoordinatorIdentity[d], DomainSidecarIdentity[d], DomainSandboxIdentity[d] }) = 3 RuntimeIdentityTupleReady(d) == /\ RuntimeIdentityTupleAuthorized(d) /\ hostCoordinatorProc[d] = "Alive" /\ RuntimeAuthorityResponsive(d) SessionIdentityTupleRegistered(s) == /\ s \in registered[Dom(s)] /\ s \in connected[Dom(s)] /\ CliCertificateValid[s] RequestIdentityTupleMatches(r) == LET s == ReqSession(r) d == ReqDomain(r) IN /\ RequestSandboxIdentity[r] = DomainSandboxIdentity[d] /\ RequestCliIdentity[r] = SessionCliIdentity[s] /\ RequestSessionAnchor[r] = SessionAnchorIdentity[s] ApprovalIdentityTupleMatches(r) == LET s == ReqSession(r) IN /\ ApprovalCliIdentity[r] = SessionCliIdentity[s] /\ ApprovalSessionAnchor[r] = SessionAnchorIdentity[s] \* This predicate abstracts verification over the request ID, decision, and \* exact approved command bytes, not merely verification of any signature by \* the registered key. /\ ApprovalSignatureValid[r] Interested(d) == { s \in Sessions : Dom(s) = d /\ sessionPhase[s] \in { "Waiting", "Registering", "Attached", "Prompting", "HostExecuting" } } RequestsForDomain(d) == {r \in Requests : ReqDomain(r) = d} Init == /\ domainPhase = [d \in Domains |-> "Absent"] /\ coordinatorState = [d \in Domains |-> "Absent"] /\ stateAnchorState = [d \in Domains |-> "Unmounted"] /\ sidecarState = [d \in Domains |-> "Stopped"] /\ sandboxState = [d \in Domains |-> "Stopped"] /\ trustReady = [d \in Domains |-> FALSE] /\ lockOwner = [d \in Domains |-> NoSession] /\ published = {} /\ registered = [d \in Domains |-> {}] /\ connected = [d \in Domains |-> {}] /\ sessionPhase = [s \in Sessions |-> "New"] /\ terminalRoute = [s \in Sessions |-> "Detached"] /\ connectionState = [s \in Sessions |-> "Disconnected"] /\ activeRequest = [s \in Sessions |-> NoRequest] /\ requestPhase = [r \in Requests |-> "Unused"] /\ approvalSource = [r \in Requests |-> NoApproval] /\ approvedCommand = [r \in Requests |-> NoCommand] /\ hostRunning = {} /\ domainLockHeld = [d \in Domains |-> FALSE] /\ hostCoordinatorProc = [d \in Domains |-> "Absent"] /\ runtimeSupervisorProc = [d \in Domains |-> "Absent"] /\ attachedRunscProc = [d \in Domains |-> "Absent"] /\ runtimeCausalEdge = [d \in Domains |-> "Unarmed"] /\ runtimeFaultsRemaining = [d \in Domains |-> 2] (*************************************************************************** Domain and Session lifecycle ***************************************************************************) StartNewDomain(s) == LET d == Dom(s) IN /\ sessionPhase[s] = "New" /\ ConfigSafe[d] /\ domainPhase[d] = "Absent" /\ RuntimeGenerationAbsent(d) /\ domainPhase' = [domainPhase EXCEPT ![d] = "Starting"] /\ coordinatorState' = [coordinatorState EXCEPT ![d] = "Starting"] /\ lockOwner' = [lockOwner EXCEPT ![d] = s] /\ domainLockHeld' = [domainLockHeld EXCEPT ![d] = TRUE] /\ hostCoordinatorProc' = [hostCoordinatorProc EXCEPT ![d] = "Alive"] /\ sessionPhase' = [sessionPhase EXCEPT ![s] = "Waiting"] /\ UNCHANGED << stateAnchorState, sidecarState, sandboxState, trustReady, published, registered, connected, terminalRoute, connectionState, activeRequest, requestPhase, approvalSource, approvedCommand, hostRunning, runtimeSupervisorProc, attachedRunscProc, runtimeCausalEdge, runtimeFaultsRemaining >> StartReadySession(s) == LET d == Dom(s) IN /\ sessionPhase[s] = "New" /\ domainPhase[d] = "Ready" /\ d \in published /\ hostCoordinatorProc[d] = "Alive" /\ SessionFingerprint[s] = DomainFingerprint[d] /\ sessionPhase' = [sessionPhase EXCEPT ![s] = "Registering"] /\ connectionState' = [connectionState EXCEPT ![s] = "Connected"] /\ UNCHANGED << domainPhase, coordinatorState, stateAnchorState, sidecarState, sandboxState, trustReady, lockOwner, published, registered, connected, terminalRoute, activeRequest, requestPhase, approvalSource, approvedCommand, hostRunning, domainLockHeld, hostCoordinatorProc, runtimeSupervisorProc, attachedRunscProc, runtimeCausalEdge, runtimeFaultsRemaining >> WaitForDomain(s) == LET d == Dom(s) IN /\ sessionPhase[s] = "New" /\ domainPhase[d] \in {"Starting", "Stopping"} /\ sessionPhase' = [sessionPhase EXCEPT ![s] = "Waiting"] /\ UNCHANGED << domainPhase, coordinatorState, stateAnchorState, sidecarState, sandboxState, trustReady, lockOwner, published, registered, connected, terminalRoute, connectionState, activeRequest, requestPhase, approvalSource, approvedCommand, hostRunning, domainLockHeld, hostCoordinatorProc, runtimeSupervisorProc, attachedRunscProc, runtimeCausalEdge, runtimeFaultsRemaining >> RestartWaitingDomain(s) == LET d == Dom(s) IN /\ sessionPhase[s] = "Waiting" /\ ConfigSafe[d] /\ domainPhase[d] = "Absent" /\ RuntimeGenerationAbsent(d) /\ domainPhase' = [domainPhase EXCEPT ![d] = "Starting"] /\ coordinatorState' = [coordinatorState EXCEPT ![d] = "Starting"] /\ lockOwner' = [lockOwner EXCEPT ![d] = s] /\ domainLockHeld' = [domainLockHeld EXCEPT ![d] = TRUE] /\ hostCoordinatorProc' = [hostCoordinatorProc EXCEPT ![d] = "Alive"] /\ UNCHANGED << stateAnchorState, sidecarState, sandboxState, trustReady, published, registered, connected, sessionPhase, terminalRoute, connectionState, activeRequest, requestPhase, approvalSource, approvedCommand, hostRunning, runtimeSupervisorProc, attachedRunscProc, runtimeCausalEdge, runtimeFaultsRemaining >> MountStateAnchor(d) == /\ domainPhase[d] = "Starting" /\ coordinatorState[d] = "Starting" /\ hostCoordinatorProc[d] = "Alive" /\ stateAnchorState[d] = "Unmounted" /\ stateAnchorState' = [stateAnchorState EXCEPT ![d] = "Mounted"] /\ UNCHANGED << domainPhase, coordinatorState, sidecarState, sandboxState, trustReady, lockOwner, published, registered, connected, sessionPhase, terminalRoute, connectionState, activeRequest, requestPhase, approvalSource, approvedCommand, hostRunning, domainLockHeld, hostCoordinatorProc, runtimeSupervisorProc, attachedRunscProc, runtimeCausalEdge, runtimeFaultsRemaining >> CreateTrustAnchor(d) == /\ domainPhase[d] = "Starting" /\ coordinatorState[d] = "Starting" /\ hostCoordinatorProc[d] = "Alive" /\ ~trustReady[d] /\ CoordinatorCertificateValid[d] /\ trustReady' = [trustReady EXCEPT ![d] = TRUE] /\ UNCHANGED << domainPhase, coordinatorState, stateAnchorState, sidecarState, sandboxState, lockOwner, published, registered, connected, sessionPhase, terminalRoute, connectionState, activeRequest, requestPhase, approvalSource, approvedCommand, hostRunning, domainLockHeld, hostCoordinatorProc, runtimeSupervisorProc, attachedRunscProc, runtimeCausalEdge, runtimeFaultsRemaining >> StartSidecar(d) == /\ domainPhase[d] = "Starting" /\ hostCoordinatorProc[d] = "Alive" /\ stateAnchorState[d] = "Mounted" /\ trustReady[d] /\ SidecarCertificateValid[d] /\ sidecarState[d] = "Stopped" /\ sidecarState' = [sidecarState EXCEPT ![d] = "Ready"] /\ UNCHANGED << domainPhase, coordinatorState, stateAnchorState, sandboxState, trustReady, lockOwner, published, registered, connected, sessionPhase, terminalRoute, connectionState, activeRequest, requestPhase, approvalSource, approvedCommand, hostRunning, domainLockHeld, hostCoordinatorProc, runtimeSupervisorProc, attachedRunscProc, runtimeCausalEdge, runtimeFaultsRemaining >> StartRuntimeSupervisor(d) == /\ domainPhase[d] = "Starting" /\ hostCoordinatorProc[d] = "Alive" /\ sidecarState[d] = "Ready" /\ runtimeSupervisorProc[d] = "Absent" /\ runtimeSupervisorProc' = [runtimeSupervisorProc EXCEPT ![d] = "Alive"] /\ UNCHANGED << domainPhase, coordinatorState, stateAnchorState, sidecarState, sandboxState, trustReady, lockOwner, published, registered, connected, sessionPhase, terminalRoute, connectionState, activeRequest, requestPhase, approvalSource, approvedCommand, hostRunning, domainLockHeld, hostCoordinatorProc, attachedRunscProc, runtimeCausalEdge, runtimeFaultsRemaining >> ArmRuntimeCausalEdge(d) == /\ domainPhase[d] = "Starting" /\ hostCoordinatorProc[d] = "Alive" /\ runtimeSupervisorProc[d] = "Alive" /\ attachedRunscProc[d] = "Absent" /\ runtimeCausalEdge[d] = "Unarmed" /\ runtimeCausalEdge' = [runtimeCausalEdge EXCEPT ![d] = "Armed"] /\ UNCHANGED << domainPhase, coordinatorState, stateAnchorState, sidecarState, sandboxState, trustReady, lockOwner, published, registered, connected, sessionPhase, terminalRoute, connectionState, activeRequest, requestPhase, approvalSource, approvedCommand, hostRunning, domainLockHeld, hostCoordinatorProc, runtimeSupervisorProc, attachedRunscProc, runtimeFaultsRemaining >> StartSandbox(d) == /\ domainPhase[d] = "Starting" /\ hostCoordinatorProc[d] = "Alive" /\ runtimeSupervisorProc[d] = "Alive" /\ runtimeCausalEdge[d] = "Armed" /\ sidecarState[d] = "Ready" /\ sandboxState[d] = "Stopped" /\ attachedRunscProc[d] = "Absent" /\ SandboxIsolationSafe[d] /\ SandboxCertificateValid[d] /\ sandboxState' = [sandboxState EXCEPT ![d] = "Ready"] /\ attachedRunscProc' = [attachedRunscProc EXCEPT ![d] = "Alive"] /\ UNCHANGED << domainPhase, coordinatorState, stateAnchorState, sidecarState, trustReady, lockOwner, published, registered, connected, sessionPhase, terminalRoute, connectionState, activeRequest, requestPhase, approvalSource, approvedCommand, hostRunning, domainLockHeld, hostCoordinatorProc, runtimeSupervisorProc, runtimeCausalEdge, runtimeFaultsRemaining >> PublishDomain(d) == /\ domainPhase[d] = "Starting" /\ coordinatorState[d] = "Starting" /\ hostCoordinatorProc[d] = "Alive" /\ RuntimeAuthorityResponsive(d) /\ stateAnchorState[d] = "Mounted" /\ sidecarState[d] = "Ready" /\ sandboxState[d] = "Ready" /\ trustReady[d] /\ domainPhase' = [domainPhase EXCEPT ![d] = "Ready"] /\ coordinatorState' = [coordinatorState EXCEPT ![d] = "Ready"] /\ lockOwner' = [lockOwner EXCEPT ![d] = NoSession] /\ published' = published \cup {d} /\ UNCHANGED << stateAnchorState, sidecarState, sandboxState, trustReady, registered, connected, sessionPhase, terminalRoute, connectionState, activeRequest, requestPhase, approvalSource, approvedCommand, hostRunning, domainLockHeld, hostCoordinatorProc, runtimeSupervisorProc, attachedRunscProc, runtimeCausalEdge, runtimeFaultsRemaining >> AdvanceWaitingSession(s) == LET d == Dom(s) IN /\ sessionPhase[s] = "Waiting" /\ domainPhase[d] = "Ready" /\ d \in published /\ hostCoordinatorProc[d] = "Alive" /\ SessionFingerprint[s] = DomainFingerprint[d] /\ sessionPhase' = [sessionPhase EXCEPT ![s] = "Registering"] /\ connectionState' = [connectionState EXCEPT ![s] = "Connected"] /\ UNCHANGED << domainPhase, coordinatorState, stateAnchorState, sidecarState, sandboxState, trustReady, lockOwner, published, registered, connected, terminalRoute, activeRequest, requestPhase, approvalSource, approvedCommand, hostRunning, domainLockHeld, hostCoordinatorProc, runtimeSupervisorProc, attachedRunscProc, runtimeCausalEdge, runtimeFaultsRemaining >> RejectConfigurationMismatch(s) == LET d == Dom(s) IN /\ sessionPhase[s] \in {"New", "Waiting"} /\ domainPhase[d] = "Ready" /\ SessionFingerprint[s] # DomainFingerprint[d] /\ sessionPhase' = [sessionPhase EXCEPT ![s] = "Failed"] /\ terminalRoute' = [terminalRoute EXCEPT ![s] = "Detached"] /\ connectionState' = [connectionState EXCEPT ![s] = "Disconnected"] /\ UNCHANGED << domainPhase, coordinatorState, stateAnchorState, sidecarState, sandboxState, trustReady, lockOwner, published, registered, connected, activeRequest, requestPhase, approvalSource, approvedCommand, hostRunning, domainLockHeld, hostCoordinatorProc, runtimeSupervisorProc, attachedRunscProc, runtimeCausalEdge, runtimeFaultsRemaining >> RegisterSession(s) == LET d == Dom(s) IN /\ sessionPhase[s] = "Registering" /\ connectionState[s] = "Connected" /\ domainPhase[d] = "Ready" /\ d \in published /\ hostCoordinatorProc[d] = "Alive" /\ SessionFingerprint[s] = DomainFingerprint[d] /\ CliCertificateValid[s] /\ registered' = [registered EXCEPT ![d] = @ \cup {s}] /\ connected' = [connected EXCEPT ![d] = @ \cup {s}] /\ sessionPhase' = [sessionPhase EXCEPT ![s] = "Attached"] /\ terminalRoute' = [terminalRoute EXCEPT ![s] = "Sandbox"] /\ UNCHANGED << domainPhase, coordinatorState, stateAnchorState, sidecarState, sandboxState, trustReady, lockOwner, published, connectionState, activeRequest, requestPhase, approvalSource, approvedCommand, hostRunning, domainLockHeld, hostCoordinatorProc, runtimeSupervisorProc, attachedRunscProc, runtimeCausalEdge, runtimeFaultsRemaining >> DisconnectSession(s) == LET d == Dom(s) r == activeRequest[s] leaderLost == lockOwner[d] = s /\ domainPhase[d] = "Starting" IN /\ sessionPhase[s] \in { "Waiting", "Registering", "Attached", "Prompting", "HostExecuting" } /\ registered' = [registered EXCEPT ![d] = @ \ {s}] /\ connected' = [connected EXCEPT ![d] = @ \ {s}] /\ sessionPhase' = [sessionPhase EXCEPT ![s] = "Closed"] /\ terminalRoute' = [terminalRoute EXCEPT ![s] = "Detached"] /\ connectionState' = [connectionState EXCEPT ![s] = "Disconnected"] /\ activeRequest' = [activeRequest EXCEPT ![s] = NoRequest] /\ requestPhase' = [q \in Requests |-> IF r # NoRequest /\ q = r /\ ~IsTerminalRequest(q) THEN "Cancelled" ELSE requestPhase[q]] /\ hostRunning' = IF r = NoRequest THEN hostRunning ELSE hostRunning \ {r} /\ domainPhase' = [domainPhase EXCEPT ![d] = IF leaderLost THEN "Failed" ELSE @] /\ coordinatorState' = [coordinatorState EXCEPT ![d] = IF leaderLost THEN "Failed" ELSE @] /\ trustReady' = [trustReady EXCEPT ![d] = IF leaderLost THEN FALSE ELSE @] /\ lockOwner' = [lockOwner EXCEPT ![d] = IF leaderLost THEN NoSession ELSE @] /\ published' = IF leaderLost THEN published \ {d} ELSE published /\ UNCHANGED << stateAnchorState, sidecarState, sandboxState, approvalSource, approvedCommand, domainLockHeld, hostCoordinatorProc, runtimeSupervisorProc, attachedRunscProc, runtimeCausalEdge, runtimeFaultsRemaining >> BeginTeardown(d) == /\ domainPhase[d] = "Ready" /\ hostCoordinatorProc[d] = "Alive" /\ Interested(d) = {} /\ registered[d] = {} /\ connected[d] = {} /\ domainPhase' = [domainPhase EXCEPT ![d] = "Stopping"] /\ coordinatorState' = [coordinatorState EXCEPT ![d] = "Stopping"] /\ published' = published \ {d} /\ UNCHANGED << stateAnchorState, sidecarState, sandboxState, trustReady, lockOwner, registered, connected, sessionPhase, terminalRoute, connectionState, activeRequest, requestPhase, approvalSource, approvedCommand, hostRunning, domainLockHeld, hostCoordinatorProc, runtimeSupervisorProc, attachedRunscProc, runtimeCausalEdge, runtimeFaultsRemaining >> StopSandbox(d) == /\ domainPhase[d] = "Stopping" /\ RuntimeAuthorityResponsive(d) /\ sandboxState[d] = "Ready" /\ sandboxState' = [sandboxState EXCEPT ![d] = "Stopped"] /\ attachedRunscProc' = [attachedRunscProc EXCEPT ![d] = "Absent"] /\ runtimeCausalEdge' = [runtimeCausalEdge EXCEPT ![d] = "Unarmed"] /\ UNCHANGED << domainPhase, coordinatorState, stateAnchorState, sidecarState, trustReady, lockOwner, published, registered, connected, sessionPhase, terminalRoute, connectionState, activeRequest, requestPhase, approvalSource, approvedCommand, hostRunning, domainLockHeld, hostCoordinatorProc, runtimeSupervisorProc, runtimeFaultsRemaining >> StopSidecar(d) == /\ domainPhase[d] = "Stopping" /\ sandboxState[d] = "Stopped" /\ sidecarState[d] = "Ready" /\ sidecarState' = [sidecarState EXCEPT ![d] = "Stopped"] /\ UNCHANGED << domainPhase, coordinatorState, stateAnchorState, sandboxState, trustReady, lockOwner, published, registered, connected, sessionPhase, terminalRoute, connectionState, activeRequest, requestPhase, approvalSource, approvedCommand, hostRunning, domainLockHeld, hostCoordinatorProc, runtimeSupervisorProc, attachedRunscProc, runtimeCausalEdge, runtimeFaultsRemaining >> UnmountStateAnchor(d) == /\ domainPhase[d] = "Stopping" /\ sandboxState[d] = "Stopped" /\ sidecarState[d] = "Stopped" /\ stateAnchorState[d] = "Mounted" /\ stateAnchorState' = [stateAnchorState EXCEPT ![d] = "Unmounted"] /\ UNCHANGED << domainPhase, coordinatorState, sidecarState, sandboxState, trustReady, lockOwner, published, registered, connected, sessionPhase, terminalRoute, connectionState, activeRequest, requestPhase, approvalSource, approvedCommand, hostRunning, domainLockHeld, hostCoordinatorProc, runtimeSupervisorProc, attachedRunscProc, runtimeCausalEdge, runtimeFaultsRemaining >> FinishTeardown(d) == /\ domainPhase[d] = "Stopping" /\ stateAnchorState[d] = "Unmounted" /\ sidecarState[d] = "Stopped" /\ sandboxState[d] = "Stopped" /\ domainPhase' = [domainPhase EXCEPT ![d] = "Absent"] /\ coordinatorState' = [coordinatorState EXCEPT ![d] = "Absent"] /\ trustReady' = [trustReady EXCEPT ![d] = FALSE] /\ lockOwner' = [lockOwner EXCEPT ![d] = NoSession] /\ domainLockHeld' = [domainLockHeld EXCEPT ![d] = FALSE] /\ hostCoordinatorProc' = [hostCoordinatorProc EXCEPT ![d] = "Absent"] /\ runtimeSupervisorProc' = [runtimeSupervisorProc EXCEPT ![d] = "Absent"] /\ attachedRunscProc' = [attachedRunscProc EXCEPT ![d] = "Absent"] /\ runtimeCausalEdge' = [runtimeCausalEdge EXCEPT ![d] = "Unarmed"] /\ UNCHANGED << stateAnchorState, sidecarState, sandboxState, published, registered, connected, sessionPhase, terminalRoute, connectionState, activeRequest, requestPhase, approvalSource, approvedCommand, hostRunning, runtimeFaultsRemaining >> (*************************************************************************** Host escalation protocol ***************************************************************************) ReceiveEscalation(r) == LET s == ReqSession(r) d == ReqDomain(r) IN /\ requestPhase[r] = "Unused" /\ sessionPhase[s] = "Attached" /\ activeRequest[s] = NoRequest /\ s \in registered[d] /\ s \in connected[d] /\ RuntimeIdentityTupleReady(d) /\ SessionIdentityTupleRegistered(s) /\ RequestIdentityTupleMatches(r) /\ RequestCredentialValid[r] /\ RequestSignatureValid[r] /\ requestPhase' = [requestPhase EXCEPT ![r] = "Verified"] /\ activeRequest' = [activeRequest EXCEPT ![s] = r] /\ UNCHANGED << domainPhase, coordinatorState, stateAnchorState, sidecarState, sandboxState, trustReady, lockOwner, published, registered, connected, sessionPhase, terminalRoute, connectionState, approvalSource, approvedCommand, hostRunning, domainLockHeld, hostCoordinatorProc, runtimeSupervisorProc, attachedRunscProc, runtimeCausalEdge, runtimeFaultsRemaining >> AutoApprove(r) == /\ requestPhase[r] = "Verified" /\ AutoRuleMatches[r] /\ ~CommandRequiresShell[RequestCommand[r]] /\ requestPhase' = [requestPhase EXCEPT ![r] = "Approved"] /\ approvalSource' = [approvalSource EXCEPT ![r] = "AutoRule"] /\ approvedCommand' = [approvedCommand EXCEPT ![r] = RequestCommand[r]] /\ UNCHANGED << domainPhase, coordinatorState, stateAnchorState, sidecarState, sandboxState, trustReady, lockOwner, published, registered, connected, sessionPhase, terminalRoute, connectionState, activeRequest, hostRunning, domainLockHeld, hostCoordinatorProc, runtimeSupervisorProc, attachedRunscProc, runtimeCausalEdge, runtimeFaultsRemaining >> QueuePrompt(r) == /\ requestPhase[r] = "Verified" /\ ~(AutoRuleMatches[r] /\ ~CommandRequiresShell[RequestCommand[r]]) /\ requestPhase' = [requestPhase EXCEPT ![r] = "AwaitingApproval"] /\ UNCHANGED << domainPhase, coordinatorState, stateAnchorState, sidecarState, sandboxState, trustReady, lockOwner, published, registered, connected, sessionPhase, terminalRoute, connectionState, activeRequest, approvalSource, approvedCommand, hostRunning, domainLockHeld, hostCoordinatorProc, runtimeSupervisorProc, attachedRunscProc, runtimeCausalEdge, runtimeFaultsRemaining >> BeginPrompt(r) == LET s == ReqSession(r) IN /\ requestPhase[r] = "AwaitingApproval" /\ sessionPhase[s] = "Attached" /\ activeRequest[s] = r /\ sessionPhase' = [sessionPhase EXCEPT ![s] = "Prompting"] /\ terminalRoute' = [terminalRoute EXCEPT ![s] = "Prompt"] /\ UNCHANGED << domainPhase, coordinatorState, stateAnchorState, sidecarState, sandboxState, trustReady, lockOwner, published, registered, connected, connectionState, activeRequest, requestPhase, approvalSource, approvedCommand, hostRunning, domainLockHeld, hostCoordinatorProc, runtimeSupervisorProc, attachedRunscProc, runtimeCausalEdge, runtimeFaultsRemaining >> DeveloperApprove(r, cmd) == LET s == ReqSession(r) IN /\ requestPhase[r] = "AwaitingApproval" /\ sessionPhase[s] = "Prompting" /\ ApprovalIdentityTupleMatches(r) /\ cmd \in Commands /\ cmd = ApprovalCommand[r] /\ requestPhase' = [requestPhase EXCEPT ![r] = "Approved"] /\ approvalSource' = [approvalSource EXCEPT ![r] = "Developer"] /\ approvedCommand' = [approvedCommand EXCEPT ![r] = cmd] /\ UNCHANGED << domainPhase, coordinatorState, stateAnchorState, sidecarState, sandboxState, trustReady, lockOwner, published, registered, connected, sessionPhase, terminalRoute, connectionState, activeRequest, hostRunning, domainLockHeld, hostCoordinatorProc, runtimeSupervisorProc, attachedRunscProc, runtimeCausalEdge, runtimeFaultsRemaining >> DeveloperDeny(r) == LET s == ReqSession(r) IN /\ requestPhase[r] = "AwaitingApproval" /\ sessionPhase[s] = "Prompting" /\ ApprovalIdentityTupleMatches(r) /\ requestPhase' = [requestPhase EXCEPT ![r] = "DenialPending"] /\ sessionPhase' = [sessionPhase EXCEPT ![s] = "Attached"] /\ terminalRoute' = [terminalRoute EXCEPT ![s] = "Sandbox"] /\ UNCHANGED << domainPhase, coordinatorState, stateAnchorState, sidecarState, sandboxState, trustReady, lockOwner, published, registered, connected, connectionState, activeRequest, approvalSource, approvedCommand, hostRunning, domainLockHeld, hostCoordinatorProc, runtimeSupervisorProc, attachedRunscProc, runtimeCausalEdge, runtimeFaultsRemaining >> StartHostExecution(r) == LET s == ReqSession(r) d == ReqDomain(r) IN /\ requestPhase[r] = "Approved" /\ activeRequest[s] = r /\ s \in connected[d] /\ sessionPhase[s] \in {"Attached", "Prompting"} /\ CommandContentSafe[approvedCommand[r]] /\ requestPhase' = [requestPhase EXCEPT ![r] = "Executing"] /\ sessionPhase' = [sessionPhase EXCEPT ![s] = "HostExecuting"] /\ terminalRoute' = [terminalRoute EXCEPT ![s] = "HostProcess"] /\ hostRunning' = hostRunning \cup {r} /\ UNCHANGED << domainPhase, coordinatorState, stateAnchorState, sidecarState, sandboxState, trustReady, lockOwner, published, registered, connected, connectionState, activeRequest, approvalSource, approvedCommand, domainLockHeld, hostCoordinatorProc, runtimeSupervisorProc, attachedRunscProc, runtimeCausalEdge, runtimeFaultsRemaining >> CompleteHostExecution(r) == LET s == ReqSession(r) IN /\ requestPhase[r] = "Executing" /\ r \in hostRunning /\ requestPhase' = [requestPhase EXCEPT ![r] = "CompletionPending"] /\ hostRunning' = hostRunning \ {r} /\ sessionPhase' = [sessionPhase EXCEPT ![s] = "Attached"] /\ terminalRoute' = [terminalRoute EXCEPT ![s] = "Sandbox"] /\ UNCHANGED << domainPhase, coordinatorState, stateAnchorState, sidecarState, sandboxState, trustReady, lockOwner, published, registered, connected, connectionState, activeRequest, approvalSource, approvedCommand, domainLockHeld, hostCoordinatorProc, runtimeSupervisorProc, attachedRunscProc, runtimeCausalEdge, runtimeFaultsRemaining >> TimeoutRequest(r) == LET s == ReqSession(r) IN /\ requestPhase[r] \in {"Verified", "AwaitingApproval", "Approved", "Executing"} /\ activeRequest[s] = r /\ requestPhase' = [requestPhase EXCEPT ![r] = "TimeoutPending"] /\ sessionPhase' = [sessionPhase EXCEPT ![s] = "Attached"] /\ terminalRoute' = [terminalRoute EXCEPT ![s] = "Sandbox"] /\ hostRunning' = hostRunning \ {r} /\ UNCHANGED << domainPhase, coordinatorState, stateAnchorState, sidecarState, sandboxState, trustReady, lockOwner, published, registered, connected, connectionState, activeRequest, approvalSource, approvedCommand, domainLockHeld, hostCoordinatorProc, runtimeSupervisorProc, attachedRunscProc, runtimeCausalEdge, runtimeFaultsRemaining >> CancelRequest(r) == LET s == ReqSession(r) IN /\ requestPhase[r] \in { "Verified", "AwaitingApproval", "Approved", "Executing" } /\ activeRequest[s] = r /\ connectionState[s] = "Connected" /\ requestPhase' = [requestPhase EXCEPT ![r] = "CancellationPending"] /\ sessionPhase' = [sessionPhase EXCEPT ![s] = "Attached"] /\ terminalRoute' = [terminalRoute EXCEPT ![s] = "Sandbox"] /\ hostRunning' = hostRunning \ {r} /\ UNCHANGED << domainPhase, coordinatorState, stateAnchorState, sidecarState, sandboxState, trustReady, lockOwner, published, registered, connected, connectionState, activeRequest, approvalSource, approvedCommand, domainLockHeld, hostCoordinatorProc, runtimeSupervisorProc, attachedRunscProc, runtimeCausalEdge, runtimeFaultsRemaining >> FailHostExecution(r) == LET s == ReqSession(r) IN /\ requestPhase[r] = "Executing" /\ activeRequest[s] = r /\ connectionState[s] = "Connected" /\ requestPhase' = [requestPhase EXCEPT ![r] = "FailurePending"] /\ sessionPhase' = [sessionPhase EXCEPT ![s] = "Attached"] /\ terminalRoute' = [terminalRoute EXCEPT ![s] = "Sandbox"] /\ hostRunning' = hostRunning \ {r} /\ UNCHANGED << domainPhase, coordinatorState, stateAnchorState, sidecarState, sandboxState, trustReady, lockOwner, published, registered, connected, connectionState, activeRequest, approvalSource, approvedCommand, domainLockHeld, hostCoordinatorProc, runtimeSupervisorProc, attachedRunscProc, runtimeCausalEdge, runtimeFaultsRemaining >> DeliverResult(r) == LET s == ReqSession(r) IN /\ requestPhase[r] \in PendingResultPhases /\ activeRequest[s] = r /\ connectionState[s] = "Connected" /\ sessionPhase[s] = "Attached" /\ requestPhase' = [requestPhase EXCEPT ![r] = DeliveredResultPhase(@)] /\ activeRequest' = [activeRequest EXCEPT ![s] = NoRequest] /\ UNCHANGED << domainPhase, coordinatorState, stateAnchorState, sidecarState, sandboxState, trustReady, lockOwner, published, registered, connected, sessionPhase, terminalRoute, connectionState, approvalSource, approvedCommand, hostRunning, domainLockHeld, hostCoordinatorProc, runtimeSupervisorProc, attachedRunscProc, runtimeCausalEdge, runtimeFaultsRemaining >> (*************************************************************************** Failure and recovery ***************************************************************************) FailDomain(d) == /\ domainPhase[d] \in {"Starting", "Ready", "Stopping"} /\ domainPhase' = [domainPhase EXCEPT ![d] = "Failed"] /\ coordinatorState' = [coordinatorState EXCEPT ![d] = "Failed"] /\ trustReady' = [trustReady EXCEPT ![d] = FALSE] /\ lockOwner' = [lockOwner EXCEPT ![d] = NoSession] /\ published' = published \ {d} /\ registered' = [registered EXCEPT ![d] = {}] /\ connected' = [connected EXCEPT ![d] = {}] /\ sessionPhase' = [s \in Sessions |-> IF Dom(s) = d /\ sessionPhase[s] \notin {"New", "Closed"} THEN "Failed" ELSE sessionPhase[s]] /\ terminalRoute' = [s \in Sessions |-> IF Dom(s) = d THEN "Detached" ELSE terminalRoute[s]] /\ connectionState' = [s \in Sessions |-> IF Dom(s) = d THEN "Disconnected" ELSE connectionState[s]] /\ activeRequest' = [s \in Sessions |-> IF Dom(s) = d THEN NoRequest ELSE activeRequest[s]] /\ requestPhase' = [r \in Requests |-> IF ReqDomain(r) = d /\ requestPhase[r] # "Unused" /\ ~IsTerminalRequest(r) THEN "Failed" ELSE requestPhase[r]] /\ hostRunning' = hostRunning \ RequestsForDomain(d) /\ UNCHANGED << stateAnchorState, sidecarState, sandboxState, approvalSource, approvedCommand, domainLockHeld, hostCoordinatorProc, runtimeSupervisorProc, attachedRunscProc, runtimeCausalEdge, runtimeFaultsRemaining >> HardLoseHostCoordinator(d) == /\ domainPhase[d] \in {"Starting", "Ready", "Stopping"} /\ ProcessPresent(hostCoordinatorProc[d]) /\ ConsumeRuntimeFault(d) /\ domainPhase' = [domainPhase EXCEPT ![d] = "Failed"] /\ coordinatorState' = [coordinatorState EXCEPT ![d] = "Failed"] /\ trustReady' = [trustReady EXCEPT ![d] = FALSE] /\ lockOwner' = [lockOwner EXCEPT ![d] = NoSession] /\ published' = published \ {d} /\ registered' = [registered EXCEPT ![d] = {}] /\ connected' = [connected EXCEPT ![d] = {}] /\ sessionPhase' = [s \in Sessions |-> IF Dom(s) = d /\ sessionPhase[s] \notin {"New", "Closed"} THEN "Failed" ELSE sessionPhase[s]] /\ terminalRoute' = [s \in Sessions |-> IF Dom(s) = d THEN "Detached" ELSE terminalRoute[s]] /\ connectionState' = [s \in Sessions |-> IF Dom(s) = d THEN "Disconnected" ELSE connectionState[s]] /\ activeRequest' = [s \in Sessions |-> IF Dom(s) = d THEN NoRequest ELSE activeRequest[s]] /\ requestPhase' = [r \in Requests |-> IF ReqDomain(r) = d /\ requestPhase[r] # "Unused" /\ ~IsTerminalRequest(r) THEN "Failed" ELSE requestPhase[r]] /\ hostRunning' = hostRunning \ RequestsForDomain(d) /\ hostCoordinatorProc' = [hostCoordinatorProc EXCEPT ![d] = "Dead"] /\ UNCHANGED << stateAnchorState, sidecarState, sandboxState, approvalSource, approvedCommand, domainLockHeld, runtimeSupervisorProc, attachedRunscProc, runtimeCausalEdge >> HardLoseRuntimeSupervisor(d) == /\ domainPhase[d] \in {"Starting", "Ready", "Stopping", "Failed"} /\ ProcessPresent(runtimeSupervisorProc[d]) /\ ConsumeRuntimeFault(d) /\ domainPhase' = [domainPhase EXCEPT ![d] = "Failed"] /\ coordinatorState' = [coordinatorState EXCEPT ![d] = "Failed"] /\ trustReady' = [trustReady EXCEPT ![d] = FALSE] /\ lockOwner' = [lockOwner EXCEPT ![d] = NoSession] /\ published' = published \ {d} /\ registered' = [registered EXCEPT ![d] = {}] /\ connected' = [connected EXCEPT ![d] = {}] /\ sessionPhase' = [s \in Sessions |-> IF Dom(s) = d /\ sessionPhase[s] \notin {"New", "Closed"} THEN "Failed" ELSE sessionPhase[s]] /\ terminalRoute' = [s \in Sessions |-> IF Dom(s) = d THEN "Detached" ELSE terminalRoute[s]] /\ connectionState' = [s \in Sessions |-> IF Dom(s) = d THEN "Disconnected" ELSE connectionState[s]] /\ activeRequest' = [s \in Sessions |-> IF Dom(s) = d THEN NoRequest ELSE activeRequest[s]] /\ requestPhase' = [r \in Requests |-> IF ReqDomain(r) = d /\ requestPhase[r] # "Unused" /\ ~IsTerminalRequest(r) THEN "Failed" ELSE requestPhase[r]] /\ hostRunning' = hostRunning \ RequestsForDomain(d) /\ runtimeSupervisorProc' = [runtimeSupervisorProc EXCEPT ![d] = "Dead"] /\ attachedRunscProc' = [attachedRunscProc EXCEPT ![d] = IF runtimeCausalEdge[d] = "Armed" THEN "Dead" ELSE @] /\ sandboxState' = [sandboxState EXCEPT ![d] = IF runtimeCausalEdge[d] = "Armed" THEN "Stopped" ELSE @] /\ runtimeCausalEdge' = [runtimeCausalEdge EXCEPT ![d] = "Unarmed"] /\ UNCHANGED << stateAnchorState, sidecarState, approvalSource, approvedCommand, domainLockHeld, hostCoordinatorProc >> HardLoseAttachedRunsc(d) == /\ domainPhase[d] \in {"Starting", "Ready", "Stopping", "Failed"} /\ ProcessPresent(attachedRunscProc[d]) /\ ConsumeRuntimeFault(d) /\ domainPhase' = [domainPhase EXCEPT ![d] = "Failed"] /\ coordinatorState' = [coordinatorState EXCEPT ![d] = "Failed"] /\ trustReady' = [trustReady EXCEPT ![d] = FALSE] /\ lockOwner' = [lockOwner EXCEPT ![d] = NoSession] /\ published' = published \ {d} /\ registered' = [registered EXCEPT ![d] = {}] /\ connected' = [connected EXCEPT ![d] = {}] /\ sessionPhase' = [s \in Sessions |-> IF Dom(s) = d /\ sessionPhase[s] \notin {"New", "Closed"} THEN "Failed" ELSE sessionPhase[s]] /\ terminalRoute' = [s \in Sessions |-> IF Dom(s) = d THEN "Detached" ELSE terminalRoute[s]] /\ connectionState' = [s \in Sessions |-> IF Dom(s) = d THEN "Disconnected" ELSE connectionState[s]] /\ activeRequest' = [s \in Sessions |-> IF Dom(s) = d THEN NoRequest ELSE activeRequest[s]] /\ requestPhase' = [r \in Requests |-> IF ReqDomain(r) = d /\ requestPhase[r] # "Unused" /\ ~IsTerminalRequest(r) THEN "Failed" ELSE requestPhase[r]] /\ hostRunning' = hostRunning \ RequestsForDomain(d) /\ attachedRunscProc' = [attachedRunscProc EXCEPT ![d] = "Dead"] /\ sandboxState' = [sandboxState EXCEPT ![d] = "Stopped"] /\ runtimeCausalEdge' = [runtimeCausalEdge EXCEPT ![d] = "Unarmed"] /\ UNCHANGED << stateAnchorState, sidecarState, approvalSource, approvedCommand, domainLockHeld, hostCoordinatorProc, runtimeSupervisorProc >> StopHostCoordinatorProcess(d) == /\ domainPhase[d] \in {"Starting", "Ready", "Stopping", "Failed"} /\ hostCoordinatorProc[d] = "Alive" /\ ConsumeRuntimeFault(d) /\ hostCoordinatorProc' = [hostCoordinatorProc EXCEPT ![d] = "Stopped"] /\ UNCHANGED << domainPhase, coordinatorState, stateAnchorState, sidecarState, sandboxState, trustReady, lockOwner, published, registered, connected, sessionPhase, terminalRoute, connectionState, activeRequest, requestPhase, approvalSource, approvedCommand, hostRunning, domainLockHeld, runtimeSupervisorProc, attachedRunscProc, runtimeCausalEdge >> ResumeHostCoordinatorProcess(d) == /\ hostCoordinatorProc[d] = "Stopped" /\ hostCoordinatorProc' = [hostCoordinatorProc EXCEPT ![d] = "Alive"] /\ UNCHANGED << domainPhase, coordinatorState, stateAnchorState, sidecarState, sandboxState, trustReady, lockOwner, published, registered, connected, sessionPhase, terminalRoute, connectionState, activeRequest, requestPhase, approvalSource, approvedCommand, hostRunning, domainLockHeld, runtimeSupervisorProc, attachedRunscProc, runtimeCausalEdge, runtimeFaultsRemaining >> StopRuntimeSupervisorProcess(d) == /\ runtimeSupervisorProc[d] = "Alive" /\ ConsumeRuntimeFault(d) /\ runtimeSupervisorProc' = [runtimeSupervisorProc EXCEPT ![d] = "Stopped"] /\ UNCHANGED << domainPhase, coordinatorState, stateAnchorState, sidecarState, sandboxState, trustReady, lockOwner, published, registered, connected, sessionPhase, terminalRoute, connectionState, activeRequest, requestPhase, approvalSource, approvedCommand, hostRunning, domainLockHeld, hostCoordinatorProc, attachedRunscProc, runtimeCausalEdge >> ResumeRuntimeSupervisorProcess(d) == /\ runtimeSupervisorProc[d] = "Stopped" /\ runtimeSupervisorProc' = [runtimeSupervisorProc EXCEPT ![d] = "Alive"] /\ UNCHANGED << domainPhase, coordinatorState, stateAnchorState, sidecarState, sandboxState, trustReady, lockOwner, published, registered, connected, sessionPhase, terminalRoute, connectionState, activeRequest, requestPhase, approvalSource, approvedCommand, hostRunning, domainLockHeld, hostCoordinatorProc, attachedRunscProc, runtimeCausalEdge, runtimeFaultsRemaining >> StopAttachedRunscProcess(d) == /\ attachedRunscProc[d] = "Alive" /\ ConsumeRuntimeFault(d) /\ attachedRunscProc' = [attachedRunscProc EXCEPT ![d] = "Stopped"] /\ UNCHANGED << domainPhase, coordinatorState, stateAnchorState, sidecarState, sandboxState, trustReady, lockOwner, published, registered, connected, sessionPhase, terminalRoute, connectionState, activeRequest, requestPhase, approvalSource, approvedCommand, hostRunning, domainLockHeld, hostCoordinatorProc, runtimeSupervisorProc, runtimeCausalEdge >> ResumeAttachedRunscProcess(d) == /\ attachedRunscProc[d] = "Stopped" /\ attachedRunscProc' = [attachedRunscProc EXCEPT ![d] = "Alive"] /\ UNCHANGED << domainPhase, coordinatorState, stateAnchorState, sidecarState, sandboxState, trustReady, lockOwner, published, registered, connected, sessionPhase, terminalRoute, connectionState, activeRequest, requestPhase, approvalSource, approvedCommand, hostRunning, domainLockHeld, hostCoordinatorProc, runtimeSupervisorProc, runtimeCausalEdge, runtimeFaultsRemaining >> BeginRecovery(d) == /\ domainPhase[d] = "Failed" /\ registered[d] = {} /\ connected[d] = {} /\ hostRunning \cap RequestsForDomain(d) = {} /\ domainPhase' = [domainPhase EXCEPT ![d] = "Recovering"] /\ coordinatorState' = [coordinatorState EXCEPT ![d] = "Stopping"] /\ domainLockHeld' = [domainLockHeld EXCEPT ![d] = TRUE] /\ hostCoordinatorProc' = [hostCoordinatorProc EXCEPT ![d] = "Alive"] /\ UNCHANGED << stateAnchorState, sidecarState, sandboxState, trustReady, lockOwner, published, registered, connected, sessionPhase, terminalRoute, connectionState, activeRequest, requestPhase, approvalSource, approvedCommand, hostRunning, runtimeSupervisorProc, attachedRunscProc, runtimeCausalEdge, runtimeFaultsRemaining >> RecoverSandbox(d) == /\ domainPhase[d] = "Recovering" /\ sandboxState[d] # "Stopped" /\ sandboxState' = [sandboxState EXCEPT ![d] = "Stopped"] /\ attachedRunscProc' = [attachedRunscProc EXCEPT ![d] = "Dead"] /\ runtimeCausalEdge' = [runtimeCausalEdge EXCEPT ![d] = "Unarmed"] /\ UNCHANGED << domainPhase, coordinatorState, stateAnchorState, sidecarState, trustReady, lockOwner, published, registered, connected, sessionPhase, terminalRoute, connectionState, activeRequest, requestPhase, approvalSource, approvedCommand, hostRunning, domainLockHeld, hostCoordinatorProc, runtimeSupervisorProc, runtimeFaultsRemaining >> RecoverSidecar(d) == /\ domainPhase[d] = "Recovering" /\ sandboxState[d] = "Stopped" /\ sidecarState[d] # "Stopped" /\ sidecarState' = [sidecarState EXCEPT ![d] = "Stopped"] /\ UNCHANGED << domainPhase, coordinatorState, stateAnchorState, sandboxState, trustReady, lockOwner, published, registered, connected, sessionPhase, terminalRoute, connectionState, activeRequest, requestPhase, approvalSource, approvedCommand, hostRunning, domainLockHeld, hostCoordinatorProc, runtimeSupervisorProc, attachedRunscProc, runtimeCausalEdge, runtimeFaultsRemaining >> RecoverStateAnchor(d) == /\ domainPhase[d] = "Recovering" /\ sandboxState[d] = "Stopped" /\ sidecarState[d] = "Stopped" /\ stateAnchorState[d] = "Mounted" /\ stateAnchorState' = [stateAnchorState EXCEPT ![d] = "Unmounted"] /\ UNCHANGED << domainPhase, coordinatorState, sidecarState, sandboxState, trustReady, lockOwner, published, registered, connected, sessionPhase, terminalRoute, connectionState, activeRequest, requestPhase, approvalSource, approvedCommand, hostRunning, domainLockHeld, hostCoordinatorProc, runtimeSupervisorProc, attachedRunscProc, runtimeCausalEdge, runtimeFaultsRemaining >> FinishRecovery(d) == /\ domainPhase[d] = "Recovering" /\ stateAnchorState[d] = "Unmounted" /\ sidecarState[d] = "Stopped" /\ sandboxState[d] = "Stopped" /\ domainPhase' = [domainPhase EXCEPT ![d] = "Absent"] /\ coordinatorState' = [coordinatorState EXCEPT ![d] = "Absent"] /\ lockOwner' = [lockOwner EXCEPT ![d] = NoSession] /\ trustReady' = [trustReady EXCEPT ![d] = FALSE] /\ domainLockHeld' = [domainLockHeld EXCEPT ![d] = FALSE] /\ hostCoordinatorProc' = [hostCoordinatorProc EXCEPT ![d] = "Absent"] /\ runtimeSupervisorProc' = [runtimeSupervisorProc EXCEPT ![d] = "Absent"] /\ attachedRunscProc' = [attachedRunscProc EXCEPT ![d] = "Absent"] /\ runtimeCausalEdge' = [runtimeCausalEdge EXCEPT ![d] = "Unarmed"] /\ UNCHANGED << stateAnchorState, sidecarState, sandboxState, published, registered, connected, sessionPhase, terminalRoute, connectionState, activeRequest, requestPhase, approvalSource, approvedCommand, hostRunning, runtimeFaultsRemaining >> DomainProgress(d) == \/ MountStateAnchor(d) \/ CreateTrustAnchor(d) \/ StartSidecar(d) \/ StartRuntimeSupervisor(d) \/ ArmRuntimeCausalEdge(d) \/ StartSandbox(d) \/ PublishDomain(d) \/ BeginTeardown(d) \/ StopSandbox(d) \/ StopSidecar(d) \/ UnmountStateAnchor(d) \/ FinishTeardown(d) \/ BeginRecovery(d) \/ RecoverSandbox(d) \/ RecoverSidecar(d) \/ RecoverStateAnchor(d) \/ FinishRecovery(d) \/ ResumeHostCoordinatorProcess(d) \/ ResumeRuntimeSupervisorProcess(d) \/ ResumeAttachedRunscProcess(d) RuntimePhysicalInterleaving(d) == \/ HardLoseHostCoordinator(d) \/ HardLoseRuntimeSupervisor(d) \/ HardLoseAttachedRunsc(d) \/ StopHostCoordinatorProcess(d) \/ ResumeHostCoordinatorProcess(d) \/ StopRuntimeSupervisorProcess(d) \/ ResumeRuntimeSupervisorProcess(d) \/ StopAttachedRunscProcess(d) \/ ResumeAttachedRunscProcess(d) SessionProgress(s) == \/ StartNewDomain(s) \/ StartReadySession(s) \/ WaitForDomain(s) \/ RestartWaitingDomain(s) \/ AdvanceWaitingSession(s) \/ RejectConfigurationMismatch(s) \/ RegisterSession(s) RequestProgress(r) == \/ AutoApprove(r) \/ QueuePrompt(r) \/ BeginPrompt(r) \/ (\E cmd \in Commands : DeveloperApprove(r, cmd)) \/ DeveloperDeny(r) \/ StartHostExecution(r) \/ CompleteHostExecution(r) \/ TimeoutRequest(r) \/ CancelRequest(r) \/ FailHostExecution(r) \/ DeliverResult(r) Next == \/ (\E s \in Sessions : StartNewDomain(s) \/ StartReadySession(s) \/ WaitForDomain(s) \/ RestartWaitingDomain(s) \/ AdvanceWaitingSession(s) \/ RejectConfigurationMismatch(s) \/ RegisterSession(s) \/ DisconnectSession(s)) \/ (\E d \in Domains : DomainProgress(d) \/ FailDomain(d)) \/ (\E d \in Domains : RuntimePhysicalInterleaving(d)) \/ (\E r \in Requests : ReceiveEscalation(r) \/ RequestProgress(r)) Spec == /\ Init /\ [][Next]_vars /\ \A d \in Domains : WF_vars(DomainProgress(d)) /\ \A s \in Sessions : WF_vars(SessionProgress(s)) /\ \A r \in Requests : WF_vars(RequestProgress(r)) (*************************************************************************** Safety properties ***************************************************************************) TypeOK == /\ domainPhase \in [Domains -> DomainPhases] /\ coordinatorState \in [Domains -> CoordinatorStates] /\ stateAnchorState \in [Domains -> MountStates] /\ sidecarState \in [Domains -> ResourceStates] /\ sandboxState \in [Domains -> ResourceStates] /\ trustReady \in [Domains -> BOOLEAN] /\ lockOwner \in [Domains -> Sessions \cup {NoSession}] /\ published \subseteq Domains /\ registered \in [Domains -> SUBSET Sessions] /\ connected \in [Domains -> SUBSET Sessions] /\ sessionPhase \in [Sessions -> SessionPhases] /\ terminalRoute \in [Sessions -> TerminalRoutes] /\ connectionState \in [Sessions -> ConnectionStates] /\ activeRequest \in [Sessions -> Requests \cup {NoRequest}] /\ requestPhase \in [Requests -> RequestPhases] /\ approvalSource \in [Requests -> ApprovalSources] /\ approvedCommand \in [Requests -> Commands \cup {NoCommand}] /\ hostRunning \subseteq Requests /\ domainLockHeld \in [Domains -> BOOLEAN] /\ hostCoordinatorProc \in [Domains -> PhysicalProcessStates] /\ runtimeSupervisorProc \in [Domains -> PhysicalProcessStates] /\ attachedRunscProc \in [Domains -> PhysicalProcessStates] /\ runtimeCausalEdge \in [Domains -> RuntimeCausalEdgeStates] /\ runtimeFaultsRemaining \in [Domains -> 0..2] ConfigurationConfinement == \A d \in Domains : domainPhase[d] # "Absent" => ConfigSafe[d] SandboxNamespaceIsolation == \A d \in Domains : sandboxState[d] = "Ready" => SandboxIsolationSafe[d] OrderedNetworkStartup == \A d \in Domains : sandboxState[d] = "Ready" => sidecarState[d] = "Ready" PublishedDomainsReady == \A d \in published : /\ domainPhase[d] = "Ready" /\ coordinatorState[d] = "Ready" /\ stateAnchorState[d] = "Mounted" /\ sidecarState[d] = "Ready" /\ sandboxState[d] = "Ready" /\ trustReady[d] DomainLockLifetime == \A d \in Domains : /\ (domainPhase[d] = "Absent" => ~domainLockHeld[d]) /\ (domainPhase[d] # "Absent" => domainLockHeld[d]) /\ (~domainLockHeld[d] => RuntimeGenerationAbsent(d)) RuntimeCausalEdgeArmedBeforeSandbox == \A d \in Domains : sandboxState[d] = "Ready" => /\ runtimeCausalEdge[d] = "Armed" /\ ProcessPresent(attachedRunscProc[d]) RuntimeCausalEdgeOwnerPresent == \A d \in Domains : runtimeCausalEdge[d] = "Armed" => /\ domainLockHeld[d] /\ ProcessPresent(runtimeSupervisorProc[d]) SandboxRunningImpliesCoordinatorPresent == \A d \in Domains : sandboxState[d] = "Ready" => RuntimeLogicalAuthorityPresent(d) PublishedRuntimeAuthorityPresent == \A d \in published : RuntimeLogicalAuthorityPresent(d) ExclusiveBootstrapOwnership == \A d \in Domains : lockOwner[d] # NoSession => /\ domainPhase[d] = "Starting" /\ coordinatorState[d] = "Starting" /\ sessionPhase[lockOwner[d]] = "Waiting" TeardownNotJoinable == \A d \in Domains : domainPhase[d] \in {"Stopping", "Failed", "Recovering"} => /\ d \notin published /\ registered[d] = {} /\ connected[d] = {} RegisteredSessionsConnected == \A d \in Domains : registered[d] \subseteq connected[d] AttachedSessionsValid == \A s \in Sessions : sessionPhase[s] \in {"Attached", "Prompting", "HostExecuting"} => /\ s \in registered[Dom(s)] /\ s \in connected[Dom(s)] /\ domainPhase[Dom(s)] = "Ready" /\ SessionFingerprint[s] = DomainFingerprint[Dom(s)] AuthenticatedRequestsOnly == \A r \in Requests : requestPhase[r] # "Unused" => /\ RequestCredentialValid[r] /\ RequestSignatureValid[r] /\ RequestIdentityTupleMatches(r) RuntimeRoleIdentitySeparation == /\ \A d \in Domains : Cardinality({ DomainCoordinatorIdentity[d], DomainSidecarIdentity[d], DomainSandboxIdentity[d] }) = 3 /\ \A s \in Sessions : LET d == Dom(s) IN SessionCliIdentity[s] \notin { DomainCoordinatorIdentity[d], DomainSidecarIdentity[d], DomainSandboxIdentity[d] } RegisteredSessionIdentityUniqueness == \A s1, s2 \in Sessions : /\ s1 # s2 /\ s1 \in registered[Dom(s1)] /\ s2 \in registered[Dom(s2)] => /\ SessionCliIdentity[s1] # SessionCliIdentity[s2] /\ SessionAnchorIdentity[s1] # SessionAnchorIdentity[s2] LiveRequestIdentityAuthorized == \A r \in Requests : requestPhase[r] \notin {"Unused"} \cup TerminalRequestPhases => /\ RuntimeIdentityTupleAuthorized(ReqDomain(r)) /\ SessionIdentityTupleRegistered(ReqSession(r)) DeveloperApprovalAuthenticated == \A r \in Requests : approvalSource[r] = "Developer" => /\ ApprovalCliIdentity[r] = SessionCliIdentity[ReqSession(r)] /\ ApprovalSessionAnchor[r] = SessionAnchorIdentity[ReqSession(r)] /\ ApprovalSignatureValid[r] /\ approvedCommand[r] = ApprovalCommand[r] HostExecutionAuthorized == \A r \in hostRunning : /\ requestPhase[r] = "Executing" /\ approvalSource[r] \in {"AutoRule", "Developer"} /\ approvedCommand[r] \in Commands /\ CommandContentSafe[approvedCommand[r]] AutoApprovalNoShell == \A r \in Requests : approvalSource[r] = "AutoRule" => /\ approvedCommand[r] = RequestCommand[r] /\ ~CommandRequiresShell[approvedCommand[r]] TerminalIsolation == \A s \in Sessions : sessionPhase[s] = "Prompting" => terminalRoute[s] = "Prompt" NoOrphanHostProcess == \A r \in hostRunning : LET s == ReqSession(r) IN /\ activeRequest[s] = r /\ sessionPhase[s] = "HostExecuting" /\ connectionState[s] = "Connected" StateAnchorOwnership == \A d \in Domains : stateAnchorState[d] = "Mounted" => coordinatorState[d] \in {"Starting", "Ready", "Stopping", "Failed"} FailedDomainIsolation == \A d \in Domains : domainPhase[d] \in {"Failed", "Recovering"} => /\ d \notin published /\ registered[d] = {} /\ connected[d] = {} /\ ~trustReady[d] /\ hostRunning \cap RequestsForDomain(d) = {} OrderedFailureRecovery == \A d \in Domains : domainPhase[d] = "Recovering" => /\ (sidecarState[d] = "Stopped" => sandboxState[d] = "Stopped") /\ (stateAnchorState[d] = "Unmounted" => /\ sandboxState[d] = "Stopped" /\ sidecarState[d] = "Stopped") ResultDeliveryStateConsistent == /\ \A r \in Requests : requestPhase[r] \in PendingResultPhases => LET s == ReqSession(r) IN /\ activeRequest[s] = r /\ connectionState[s] = "Connected" /\ sessionPhase[s] = "Attached" /\ r \notin hostRunning /\ \A r \in Requests : requestPhase[r] \in TerminalRequestPhases => /\ activeRequest[ReqSession(r)] # r /\ r \notin hostRunning Safety == /\ TypeOK /\ ConfigurationConfinement /\ SandboxNamespaceIsolation /\ OrderedNetworkStartup /\ PublishedDomainsReady /\ DomainLockLifetime /\ RuntimeCausalEdgeArmedBeforeSandbox /\ RuntimeCausalEdgeOwnerPresent /\ SandboxRunningImpliesCoordinatorPresent /\ PublishedRuntimeAuthorityPresent /\ ExclusiveBootstrapOwnership /\ TeardownNotJoinable /\ RegisteredSessionsConnected /\ AttachedSessionsValid /\ AuthenticatedRequestsOnly /\ RuntimeRoleIdentitySeparation /\ RegisteredSessionIdentityUniqueness /\ LiveRequestIdentityAuthorized /\ DeveloperApprovalAuthenticated /\ HostExecutionAuthorized /\ AutoApprovalNoShell /\ TerminalIsolation /\ NoOrphanHostProcess /\ StateAnchorOwnership /\ FailedDomainIsolation /\ OrderedFailureRecovery /\ ResultDeliveryStateConsistent (*************************************************************************** Liveness properties. TLC configurations may check these separately from the safety sweep when the state space grows. ***************************************************************************) SessionEventuallyResolves == \A s \in Sessions : sessionPhase[s] = "New" ~> sessionPhase[s] \in {"Attached", "Closed", "Failed"} RequestEventuallyResolves == \A r \in Requests : requestPhase[r] = "Verified" ~> requestPhase[r] \in TerminalRequestPhases PromptEventuallyRestoresTerminal == \A s \in Sessions : sessionPhase[s] \in {"Prompting", "HostExecuting"} ~> terminalRoute[s] \in {"Sandbox", "Detached"} EmptyDomainEventuallyStops == \A d \in Domains : (<>[](Interested(d) = {})) => <>(domainPhase[d] = "Absent") FailedDomainEventuallyRecovers == \A d \in Domains : domainPhase[d] = "Failed" ~> domainPhase[d] = "Absent" =============================================================================