lazaret/docs/protocol/Lazaret.tla
ms2k 697aada29e Check host coordinator domain ownership
Add a TLC-checked invariant requiring any Host Coordinator process record to belong to a non-absent, lock-held Domain. Include the invariant in the aggregate safety operator and remove journal-only markers from protocol model comments so the model remains grounded in product vocabulary.
2026-07-10 01:42:26 +09:00

2124 lines
85 KiB
Text

------------------------------ MODULE Lazaret ------------------------------
EXTENDS Naturals, FiniteSets, Sequences, TLC
(***************************************************************************
Application-wide protocol model for Lazaret.
The model covers Domain startup under a multi-process Session Coordinator
realized as Host Coordinator, Runtime Supervisor, and attached runsc; ordered
resource preparation owned by the supervisor; Host Coordinator lifetime lease;
role-separated runtime identity tuples; sandbox launch isolation; Client Session
registration; host escalation; correlated result delivery; terminal ownership;
failure; lease-driven teardown; recovery; and abstract durable generation-document
intent with mismatch refuse.
Product names SessionCoordinatorPresent and Session Coordinator ID alias the
multi-process predicates and DomainCoordinatorIdentity fixture.
Cryptographic algorithms, serialization, container commands, filesystems, typed
redb tables, and network packet handling are refinement boundaries.
***************************************************************************)
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"
}
MountStates == {"Unmounted", "Mounted"}
ResourceStates == {"Stopped", "Ready", "Failed"}
PhysicalProcessStates == {"Absent", "Alive", "Stopped", "Dead"}
RuntimeCausalEdgeStates == {"Unarmed", "Armed"}
SupervisorLeaseStates == {"Unarmed", "Held", "Lost"}
MaxDomainGeneration == 4
DurableDecisions == {"None", "Preparing", "Published", "Clean"}
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,
stateAnchorState,
sidecarState,
sandboxState,
trustReady,
lockOwner,
published,
registered,
connected,
sessionPhase,
terminalRoute,
connectionState,
activeRequest,
requestPhase,
approvalSource,
approvedCommand,
hostRunning,
domainLockHeld,
hostCoordinatorProc,
runtimeSupervisorProc,
attachedRunscProc,
runtimeCausalEdge,
supervisorLease,
runtimeFaultsRemaining,
domainGeneration,
durableDecision,
durableSandboxIntent,
pathMismatch
vars == <<
domainPhase,
stateAnchorState,
sidecarState,
sandboxState,
trustReady,
lockOwner,
published,
registered,
connected,
sessionPhase,
terminalRoute,
connectionState,
activeRequest,
requestPhase,
approvalSource,
approvedCommand,
hostRunning,
domainLockHeld,
hostCoordinatorProc,
runtimeSupervisorProc,
attachedRunscProc,
runtimeCausalEdge,
supervisorLease,
runtimeFaultsRemaining,
domainGeneration,
durableDecision,
durableSandboxIntent,
pathMismatch
>>
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"
HostCoordinatorAlive(d) == hostCoordinatorProc[d] = "Alive"
HostCoordinatorPresent(d) == ProcessPresent(hostCoordinatorProc[d])
RuntimeSupervisorAlive(d) == runtimeSupervisorProc[d] = "Alive"
\* published means the generation is committed for authenticated join when the
\* Host Coordinator is responsive. Admission always requires HostCoordinatorAlive.
RegistrationAdmissible(d) ==
/\ d \in published
/\ domainPhase[d] = "Ready"
/\ HostCoordinatorAlive(d)
RuntimeLogicalAuthorityPresent(d) ==
\/ HostCoordinatorPresent(d)
\/ ProcessPresent(runtimeSupervisorProc[d])
\/ ProcessPresent(attachedRunscProc[d])
\* Constitutive processes: Host Coordinator (protocol face), Runtime Supervisor,
\* attached runsc. Present = Alive or Stopped; Dead/Absent do not count.
SessionCoordinatorPresent(d) == RuntimeLogicalAuthorityPresent(d)
SessionCoordinatorAbsent(d) == ~SessionCoordinatorPresent(d)
\* SandboxRunning(d) ≜ sandboxState[d] = "Ready"
\* Coupling: SandboxRunning(d) ⇒ SessionCoordinatorPresent(d)
\* One logical Session Coordinator ID per instance; fixture DomainCoordinatorIdentity is not
\* reminted on domainGeneration. HC alone serves session-control Protocol Identity.
SessionCoordinatorIdentity(d) == DomainCoordinatorIdentity[d]
SessionCoordinatorProtocolFaceAlive(d) == HostCoordinatorAlive(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"
/\ supervisorLease[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)
/\ HostCoordinatorAlive(d)
/\ 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}
FailOpenSessionsAndRequests(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)
Init ==
/\ domainPhase = [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"]
/\ supervisorLease = [d \in Domains |-> "Unarmed"]
/\ runtimeFaultsRemaining = [d \in Domains |-> 2]
/\ domainGeneration = [d \in Domains |-> 0]
/\ durableDecision = [d \in Domains |-> "None"]
/\ durableSandboxIntent = [d \in Domains |-> FALSE]
/\ pathMismatch = [d \in Domains |-> FALSE]
(***************************************************************************
Domain and Session lifecycle
Startup ownership:
Host Coordinator: Domain lock, trust anchor, publication, protocol.
Runtime Supervisor: State Anchor, Network Sidecar, causal edge, runsc.
***************************************************************************)
StartNewDomain(s) ==
LET d == Dom(s) IN
/\ sessionPhase[s] = "New"
/\ ConfigSafe[d]
/\ domainPhase[d] = "Absent"
/\ RuntimeGenerationAbsent(d)
/\ domainGeneration[d] < MaxDomainGeneration
/\ domainPhase' = [domainPhase EXCEPT ![d] = "Starting"]
/\ domainGeneration' = [domainGeneration EXCEPT ![d] = @ + 1]
/\ lockOwner' = [lockOwner EXCEPT ![d] = s]
/\ domainLockHeld' = [domainLockHeld EXCEPT ![d] = TRUE]
/\ hostCoordinatorProc' = [hostCoordinatorProc EXCEPT ![d] = "Alive"]
/\ sessionPhase' = [sessionPhase EXCEPT ![s] = "Waiting"]
/\ durableDecision' = [durableDecision EXCEPT ![d] = "None"]
/\ durableSandboxIntent' = [durableSandboxIntent EXCEPT ![d] = FALSE]
/\ pathMismatch' = [pathMismatch EXCEPT ![d] = FALSE]
/\ UNCHANGED <<
stateAnchorState, sidecarState, sandboxState, trustReady, published,
registered, connected, terminalRoute, connectionState, activeRequest,
requestPhase, approvalSource, approvedCommand, hostRunning,
runtimeSupervisorProc, attachedRunscProc, runtimeCausalEdge,
supervisorLease, runtimeFaultsRemaining
>>
StartReadySession(s) ==
LET d == Dom(s) IN
/\ sessionPhase[s] = "New"
/\ RegistrationAdmissible(d)
/\ SessionFingerprint[s] = DomainFingerprint[d]
/\ sessionPhase' = [sessionPhase EXCEPT ![s] = "Registering"]
/\ connectionState' = [connectionState EXCEPT ![s] = "Connected"]
/\ UNCHANGED <<
domainPhase, stateAnchorState, sidecarState,
sandboxState, trustReady, lockOwner, published, registered, connected,
terminalRoute, activeRequest, requestPhase, approvalSource,
approvedCommand, hostRunning, domainLockHeld, hostCoordinatorProc,
runtimeSupervisorProc, attachedRunscProc, runtimeCausalEdge,
supervisorLease, runtimeFaultsRemaining,
domainGeneration,
durableDecision, durableSandboxIntent, pathMismatch
>>
WaitForDomain(s) ==
LET d == Dom(s) IN
/\ sessionPhase[s] = "New"
/\ domainPhase[d] \in {"Starting", "Stopping"}
/\ sessionPhase' = [sessionPhase EXCEPT ![s] = "Waiting"]
/\ UNCHANGED <<
domainPhase, stateAnchorState, sidecarState,
sandboxState, trustReady, lockOwner, published, registered, connected,
terminalRoute, connectionState, activeRequest, requestPhase,
approvalSource, approvedCommand, hostRunning, domainLockHeld,
hostCoordinatorProc, runtimeSupervisorProc, attachedRunscProc,
runtimeCausalEdge, supervisorLease, runtimeFaultsRemaining,
domainGeneration,
durableDecision, durableSandboxIntent, pathMismatch
>>
RestartWaitingDomain(s) ==
LET d == Dom(s) IN
/\ sessionPhase[s] = "Waiting"
/\ ConfigSafe[d]
/\ domainPhase[d] = "Absent"
/\ RuntimeGenerationAbsent(d)
/\ domainGeneration[d] < MaxDomainGeneration
/\ domainPhase' = [domainPhase EXCEPT ![d] = "Starting"]
/\ domainGeneration' = [domainGeneration EXCEPT ![d] = @ + 1]
/\ lockOwner' = [lockOwner EXCEPT ![d] = s]
/\ domainLockHeld' = [domainLockHeld EXCEPT ![d] = TRUE]
/\ hostCoordinatorProc' = [hostCoordinatorProc EXCEPT ![d] = "Alive"]
/\ durableDecision' = [durableDecision EXCEPT ![d] = "None"]
/\ durableSandboxIntent' = [durableSandboxIntent EXCEPT ![d] = FALSE]
/\ pathMismatch' = [pathMismatch EXCEPT ![d] = FALSE]
/\ UNCHANGED <<
stateAnchorState, sidecarState, sandboxState, trustReady, published,
registered, connected, sessionPhase, terminalRoute, connectionState,
activeRequest, requestPhase, approvalSource, approvedCommand,
hostRunning, runtimeSupervisorProc, attachedRunscProc,
runtimeCausalEdge, supervisorLease, runtimeFaultsRemaining
>>
CreateTrustAnchor(d) ==
/\ domainPhase[d] = "Starting"
/\ HostCoordinatorAlive(d)
/\ ~trustReady[d]
/\ CoordinatorCertificateValid[d]
/\ trustReady' = [trustReady EXCEPT ![d] = TRUE]
/\ UNCHANGED <<
domainPhase, stateAnchorState, sidecarState,
sandboxState, lockOwner, published, registered, connected,
sessionPhase, terminalRoute, connectionState, activeRequest,
requestPhase, approvalSource, approvedCommand, hostRunning,
domainLockHeld, hostCoordinatorProc, runtimeSupervisorProc,
attachedRunscProc, runtimeCausalEdge, supervisorLease,
runtimeFaultsRemaining,
domainGeneration,
durableDecision, durableSandboxIntent, pathMismatch
>>
StartRuntimeSupervisor(d) ==
/\ domainPhase[d] = "Starting"
/\ HostCoordinatorAlive(d)
/\ trustReady[d]
/\ runtimeSupervisorProc[d] = "Absent"
/\ supervisorLease[d] = "Unarmed"
/\ runtimeSupervisorProc' = [runtimeSupervisorProc EXCEPT ![d] = "Alive"]
/\ supervisorLease' = [supervisorLease EXCEPT ![d] = "Held"]
/\ UNCHANGED <<
domainPhase, stateAnchorState, sidecarState,
sandboxState, trustReady, lockOwner, published, registered, connected,
sessionPhase, terminalRoute, connectionState, activeRequest,
requestPhase, approvalSource, approvedCommand, hostRunning,
domainLockHeld, hostCoordinatorProc, attachedRunscProc,
runtimeCausalEdge, runtimeFaultsRemaining,
domainGeneration,
durableDecision, durableSandboxIntent, pathMismatch
>>
MountStateAnchor(d) ==
/\ domainPhase[d] = "Starting"
/\ HostCoordinatorAlive(d)
/\ RuntimeSupervisorAlive(d)
/\ supervisorLease[d] = "Held"
/\ stateAnchorState[d] = "Unmounted"
/\ stateAnchorState' = [stateAnchorState EXCEPT ![d] = "Mounted"]
/\ UNCHANGED <<
domainPhase, sidecarState, sandboxState, trustReady,
lockOwner, published, registered, connected, sessionPhase,
terminalRoute, connectionState, activeRequest, requestPhase,
approvalSource, approvedCommand, hostRunning, domainLockHeld,
hostCoordinatorProc, runtimeSupervisorProc, attachedRunscProc,
runtimeCausalEdge, supervisorLease, runtimeFaultsRemaining,
domainGeneration,
durableDecision, durableSandboxIntent, pathMismatch
>>
StartSidecar(d) ==
/\ domainPhase[d] = "Starting"
/\ HostCoordinatorAlive(d)
/\ RuntimeSupervisorAlive(d)
/\ supervisorLease[d] = "Held"
/\ stateAnchorState[d] = "Mounted"
/\ trustReady[d]
/\ SidecarCertificateValid[d]
/\ sidecarState[d] = "Stopped"
/\ sidecarState' = [sidecarState EXCEPT ![d] = "Ready"]
/\ UNCHANGED <<
domainPhase, stateAnchorState, sandboxState,
trustReady, lockOwner, published, registered, connected, sessionPhase,
terminalRoute, connectionState, activeRequest, requestPhase,
approvalSource, approvedCommand, hostRunning, domainLockHeld,
hostCoordinatorProc, runtimeSupervisorProc, attachedRunscProc,
runtimeCausalEdge, supervisorLease, runtimeFaultsRemaining,
domainGeneration,
durableDecision, durableSandboxIntent, pathMismatch
>>
ArmRuntimeCausalEdge(d) ==
/\ domainPhase[d] = "Starting"
/\ HostCoordinatorAlive(d)
/\ RuntimeSupervisorAlive(d)
/\ supervisorLease[d] = "Held"
/\ stateAnchorState[d] = "Mounted"
/\ sidecarState[d] = "Ready"
/\ attachedRunscProc[d] = "Absent"
/\ runtimeCausalEdge[d] = "Unarmed"
/\ runtimeCausalEdge' = [runtimeCausalEdge EXCEPT ![d] = "Armed"]
/\ UNCHANGED <<
domainPhase, stateAnchorState, sidecarState,
sandboxState, trustReady, lockOwner, published, registered, connected,
sessionPhase, terminalRoute, connectionState, activeRequest,
requestPhase, approvalSource, approvedCommand, hostRunning,
domainLockHeld, hostCoordinatorProc, runtimeSupervisorProc,
attachedRunscProc, supervisorLease, runtimeFaultsRemaining,
domainGeneration,
durableDecision, durableSandboxIntent, pathMismatch
>>
StartSandbox(d) ==
/\ domainPhase[d] = "Starting"
/\ HostCoordinatorAlive(d)
/\ RuntimeSupervisorAlive(d)
/\ supervisorLease[d] = "Held"
/\ runtimeCausalEdge[d] = "Armed"
/\ sidecarState[d] = "Ready"
/\ sandboxState[d] = "Stopped"
/\ attachedRunscProc[d] = "Absent"
/\ SandboxIsolationSafe[d]
/\ SandboxCertificateValid[d]
/\ ~durableSandboxIntent[d]
/\ ~pathMismatch[d]
\* Intent and external creation are one abstract step here; implementations
\* must persist Intent before the resource can outlive the caller.
/\ durableSandboxIntent' = [durableSandboxIntent EXCEPT ![d] = TRUE]
/\ durableDecision' = [durableDecision EXCEPT ![d] = "Preparing"]
/\ sandboxState' = [sandboxState EXCEPT ![d] = "Ready"]
/\ attachedRunscProc' = [attachedRunscProc EXCEPT ![d] = "Alive"]
/\ UNCHANGED <<
domainPhase, stateAnchorState, sidecarState,
trustReady, lockOwner, published, registered, connected, sessionPhase,
terminalRoute, connectionState, activeRequest, requestPhase,
approvalSource, approvedCommand, hostRunning, domainLockHeld,
hostCoordinatorProc, runtimeSupervisorProc, runtimeCausalEdge,
supervisorLease, runtimeFaultsRemaining,
domainGeneration,
pathMismatch
>>
PublishDomain(d) ==
/\ domainPhase[d] = "Starting"
/\ HostCoordinatorAlive(d)
/\ RuntimeSupervisorAlive(d)
/\ supervisorLease[d] = "Held"
/\ stateAnchorState[d] = "Mounted"
/\ sidecarState[d] = "Ready"
/\ sandboxState[d] = "Ready"
/\ trustReady[d]
/\ durableSandboxIntent[d]
/\ domainPhase' = [domainPhase EXCEPT ![d] = "Ready"]
/\ lockOwner' = [lockOwner EXCEPT ![d] = NoSession]
/\ published' = published \cup {d}
/\ durableDecision' = [durableDecision EXCEPT ![d] = "Published"]
/\ UNCHANGED <<
stateAnchorState, sidecarState, sandboxState, trustReady, registered,
connected, sessionPhase, terminalRoute, connectionState,
activeRequest, requestPhase, approvalSource, approvedCommand,
hostRunning, domainLockHeld, hostCoordinatorProc, runtimeSupervisorProc,
attachedRunscProc, runtimeCausalEdge, supervisorLease,
runtimeFaultsRemaining,
domainGeneration,
durableSandboxIntent, pathMismatch
>>
AdvanceWaitingSession(s) ==
LET d == Dom(s) IN
/\ sessionPhase[s] = "Waiting"
/\ RegistrationAdmissible(d)
/\ SessionFingerprint[s] = DomainFingerprint[d]
/\ sessionPhase' = [sessionPhase EXCEPT ![s] = "Registering"]
/\ connectionState' = [connectionState EXCEPT ![s] = "Connected"]
/\ UNCHANGED <<
domainPhase, stateAnchorState, sidecarState,
sandboxState, trustReady, lockOwner, published, registered, connected,
terminalRoute, activeRequest, requestPhase, approvalSource,
approvedCommand, hostRunning, domainLockHeld, hostCoordinatorProc,
runtimeSupervisorProc, attachedRunscProc, runtimeCausalEdge,
supervisorLease, runtimeFaultsRemaining,
domainGeneration,
durableDecision, durableSandboxIntent, pathMismatch
>>
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, stateAnchorState, sidecarState,
sandboxState, trustReady, lockOwner, published, registered, connected,
activeRequest, requestPhase, approvalSource, approvedCommand,
hostRunning, domainLockHeld, hostCoordinatorProc, runtimeSupervisorProc,
attachedRunscProc, runtimeCausalEdge, supervisorLease,
runtimeFaultsRemaining,
domainGeneration,
durableDecision, durableSandboxIntent, pathMismatch
>>
RegisterSession(s) ==
LET d == Dom(s) IN
/\ sessionPhase[s] = "Registering"
/\ connectionState[s] = "Connected"
/\ RegistrationAdmissible(d)
/\ 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, stateAnchorState, sidecarState,
sandboxState, trustReady, lockOwner, published, connectionState,
activeRequest, requestPhase, approvalSource, approvedCommand,
hostRunning, domainLockHeld, hostCoordinatorProc, runtimeSupervisorProc,
attachedRunscProc, runtimeCausalEdge, supervisorLease,
runtimeFaultsRemaining,
domainGeneration,
durableDecision, durableSandboxIntent, pathMismatch
>>
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 @]
/\ 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,
supervisorLease, runtimeFaultsRemaining,
domainGeneration,
durableDecision, durableSandboxIntent, pathMismatch
>>
BeginTeardown(d) ==
/\ domainPhase[d] = "Ready"
/\ HostCoordinatorAlive(d)
/\ Interested(d) = {}
/\ registered[d] = {}
/\ connected[d] = {}
/\ domainPhase' = [domainPhase 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, supervisorLease,
runtimeFaultsRemaining,
domainGeneration,
durableDecision, durableSandboxIntent, pathMismatch
>>
StopSandbox(d) ==
/\ domainPhase[d] = "Stopping"
/\ HostCoordinatorAlive(d)
/\ RuntimeSupervisorAlive(d)
/\ supervisorLease[d] = "Held"
/\ sandboxState[d] = "Ready"
/\ sandboxState' = [sandboxState EXCEPT ![d] = "Stopped"]
/\ attachedRunscProc' = [attachedRunscProc EXCEPT ![d] = "Absent"]
/\ runtimeCausalEdge' = [runtimeCausalEdge EXCEPT ![d] = "Unarmed"]
/\ UNCHANGED <<
domainPhase, stateAnchorState, sidecarState,
trustReady, lockOwner, published, registered, connected, sessionPhase,
terminalRoute, connectionState, activeRequest, requestPhase,
approvalSource, approvedCommand, hostRunning, domainLockHeld,
hostCoordinatorProc, runtimeSupervisorProc, supervisorLease,
runtimeFaultsRemaining,
domainGeneration,
durableDecision, durableSandboxIntent, pathMismatch
>>
StopSidecar(d) ==
/\ domainPhase[d] = "Stopping"
/\ HostCoordinatorAlive(d)
/\ RuntimeSupervisorAlive(d)
/\ supervisorLease[d] = "Held"
/\ sandboxState[d] = "Stopped"
/\ sidecarState[d] = "Ready"
/\ sidecarState' = [sidecarState EXCEPT ![d] = "Stopped"]
/\ UNCHANGED <<
domainPhase, stateAnchorState, sandboxState,
trustReady, lockOwner, published, registered, connected, sessionPhase,
terminalRoute, connectionState, activeRequest, requestPhase,
approvalSource, approvedCommand, hostRunning, domainLockHeld,
hostCoordinatorProc, runtimeSupervisorProc, attachedRunscProc,
runtimeCausalEdge, supervisorLease, runtimeFaultsRemaining,
domainGeneration,
durableDecision, durableSandboxIntent, pathMismatch
>>
UnmountStateAnchor(d) ==
/\ domainPhase[d] = "Stopping"
/\ HostCoordinatorAlive(d)
/\ RuntimeSupervisorAlive(d)
/\ supervisorLease[d] = "Held"
/\ sandboxState[d] = "Stopped"
/\ sidecarState[d] = "Stopped"
/\ stateAnchorState[d] = "Mounted"
/\ stateAnchorState' = [stateAnchorState EXCEPT ![d] = "Unmounted"]
/\ UNCHANGED <<
domainPhase, sidecarState, sandboxState, trustReady,
lockOwner, published, registered, connected, sessionPhase,
terminalRoute, connectionState, activeRequest, requestPhase,
approvalSource, approvedCommand, hostRunning, domainLockHeld,
hostCoordinatorProc, runtimeSupervisorProc, attachedRunscProc,
runtimeCausalEdge, supervisorLease, runtimeFaultsRemaining,
domainGeneration,
durableDecision, durableSandboxIntent, pathMismatch
>>
GracefulSupervisorExit(d) ==
/\ domainPhase[d] = "Stopping"
/\ HostCoordinatorAlive(d)
/\ RuntimeSupervisorAlive(d)
/\ supervisorLease[d] = "Held"
/\ sandboxState[d] = "Stopped"
/\ sidecarState[d] = "Stopped"
/\ stateAnchorState[d] = "Unmounted"
/\ attachedRunscProc[d] = "Absent"
/\ runtimeCausalEdge[d] = "Unarmed"
/\ runtimeSupervisorProc' = [runtimeSupervisorProc EXCEPT ![d] = "Dead"]
/\ supervisorLease' = [supervisorLease EXCEPT ![d] = "Unarmed"]
/\ UNCHANGED <<
domainPhase, stateAnchorState, sidecarState,
sandboxState, trustReady, lockOwner, published, registered, connected,
sessionPhase, terminalRoute, connectionState, activeRequest,
requestPhase, approvalSource, approvedCommand, hostRunning,
domainLockHeld, hostCoordinatorProc, attachedRunscProc,
runtimeCausalEdge, runtimeFaultsRemaining,
domainGeneration,
durableDecision, durableSandboxIntent, pathMismatch
>>
FinishTeardown(d) ==
/\ domainPhase[d] = "Stopping"
/\ HostCoordinatorAlive(d)
/\ stateAnchorState[d] = "Unmounted"
/\ sidecarState[d] = "Stopped"
/\ sandboxState[d] = "Stopped"
/\ supervisorLease[d] = "Unarmed"
/\ ~ProcessPresent(runtimeSupervisorProc[d])
/\ attachedRunscProc[d] = "Absent"
/\ runtimeCausalEdge[d] = "Unarmed"
/\ ~pathMismatch[d]
/\ domainPhase' = [domainPhase 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"]
/\ supervisorLease' = [supervisorLease EXCEPT ![d] = "Unarmed"]
/\ durableDecision' = [durableDecision EXCEPT ![d] = "Clean"]
/\ durableSandboxIntent' = [durableSandboxIntent EXCEPT ![d] = FALSE]
/\ pathMismatch' = [pathMismatch EXCEPT ![d] = FALSE]
/\ UNCHANGED <<
stateAnchorState, sidecarState, sandboxState, published, registered,
connected, sessionPhase, terminalRoute, connectionState,
activeRequest, requestPhase, approvalSource, approvedCommand,
hostRunning, runtimeFaultsRemaining,
domainGeneration
>>
(***************************************************************************
Host escalation protocol
All coordinator-side request progress requires a responsive Host Coordinator.
***************************************************************************)
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, stateAnchorState, sidecarState,
sandboxState, trustReady, lockOwner, published, registered, connected,
sessionPhase, terminalRoute, connectionState, approvalSource,
approvedCommand, hostRunning, domainLockHeld, hostCoordinatorProc,
runtimeSupervisorProc, attachedRunscProc, runtimeCausalEdge,
supervisorLease, runtimeFaultsRemaining,
domainGeneration,
durableDecision, durableSandboxIntent, pathMismatch
>>
AutoApprove(r) ==
LET d == ReqDomain(r) IN
/\ requestPhase[r] = "Verified"
/\ HostCoordinatorAlive(d)
/\ AutoRuleMatches[r]
/\ ~CommandRequiresShell[RequestCommand[r]]
/\ requestPhase' = [requestPhase EXCEPT ![r] = "Approved"]
/\ approvalSource' = [approvalSource EXCEPT ![r] = "AutoRule"]
/\ approvedCommand' = [approvedCommand EXCEPT ![r] = RequestCommand[r]]
/\ UNCHANGED <<
domainPhase, stateAnchorState, sidecarState,
sandboxState, trustReady, lockOwner, published, registered, connected,
sessionPhase, terminalRoute, connectionState, activeRequest,
hostRunning, domainLockHeld, hostCoordinatorProc, runtimeSupervisorProc,
attachedRunscProc, runtimeCausalEdge, supervisorLease,
runtimeFaultsRemaining,
domainGeneration,
durableDecision, durableSandboxIntent, pathMismatch
>>
QueuePrompt(r) ==
LET d == ReqDomain(r) IN
/\ requestPhase[r] = "Verified"
/\ HostCoordinatorAlive(d)
/\ ~(AutoRuleMatches[r] /\ ~CommandRequiresShell[RequestCommand[r]])
/\ requestPhase' = [requestPhase EXCEPT ![r] = "AwaitingApproval"]
/\ UNCHANGED <<
domainPhase, stateAnchorState, sidecarState,
sandboxState, trustReady, lockOwner, published, registered, connected,
sessionPhase, terminalRoute, connectionState, activeRequest,
approvalSource, approvedCommand, hostRunning, domainLockHeld,
hostCoordinatorProc, runtimeSupervisorProc, attachedRunscProc,
runtimeCausalEdge, supervisorLease, runtimeFaultsRemaining,
domainGeneration,
durableDecision, durableSandboxIntent, pathMismatch
>>
BeginPrompt(r) ==
LET s == ReqSession(r)
d == ReqDomain(r)
IN
/\ requestPhase[r] = "AwaitingApproval"
/\ HostCoordinatorAlive(d)
/\ sessionPhase[s] = "Attached"
/\ activeRequest[s] = r
/\ sessionPhase' = [sessionPhase EXCEPT ![s] = "Prompting"]
/\ terminalRoute' = [terminalRoute EXCEPT ![s] = "Prompt"]
/\ UNCHANGED <<
domainPhase, stateAnchorState, sidecarState,
sandboxState, trustReady, lockOwner, published, registered, connected,
connectionState, activeRequest, requestPhase, approvalSource,
approvedCommand, hostRunning, domainLockHeld, hostCoordinatorProc,
runtimeSupervisorProc, attachedRunscProc, runtimeCausalEdge,
supervisorLease, runtimeFaultsRemaining,
domainGeneration,
durableDecision, durableSandboxIntent, pathMismatch
>>
DeveloperApprove(r, cmd) ==
LET s == ReqSession(r)
d == ReqDomain(r)
IN
/\ requestPhase[r] = "AwaitingApproval"
/\ HostCoordinatorAlive(d)
/\ 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, stateAnchorState, sidecarState,
sandboxState, trustReady, lockOwner, published, registered, connected,
sessionPhase, terminalRoute, connectionState, activeRequest,
hostRunning, domainLockHeld, hostCoordinatorProc, runtimeSupervisorProc,
attachedRunscProc, runtimeCausalEdge, supervisorLease,
runtimeFaultsRemaining,
domainGeneration,
durableDecision, durableSandboxIntent, pathMismatch
>>
DeveloperDeny(r) ==
LET s == ReqSession(r)
d == ReqDomain(r)
IN
/\ requestPhase[r] = "AwaitingApproval"
/\ HostCoordinatorAlive(d)
/\ sessionPhase[s] = "Prompting"
/\ ApprovalIdentityTupleMatches(r)
/\ requestPhase' = [requestPhase EXCEPT ![r] = "DenialPending"]
/\ sessionPhase' = [sessionPhase EXCEPT ![s] = "Attached"]
/\ terminalRoute' = [terminalRoute EXCEPT ![s] = "Sandbox"]
/\ UNCHANGED <<
domainPhase, stateAnchorState, sidecarState,
sandboxState, trustReady, lockOwner, published, registered, connected,
connectionState, activeRequest, approvalSource, approvedCommand,
hostRunning, domainLockHeld, hostCoordinatorProc, runtimeSupervisorProc,
attachedRunscProc, runtimeCausalEdge, supervisorLease,
runtimeFaultsRemaining,
domainGeneration,
durableDecision, durableSandboxIntent, pathMismatch
>>
StartHostExecution(r) ==
LET s == ReqSession(r)
d == ReqDomain(r)
IN
/\ requestPhase[r] = "Approved"
/\ HostCoordinatorAlive(d)
/\ 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, stateAnchorState, sidecarState,
sandboxState, trustReady, lockOwner, published, registered, connected,
connectionState, activeRequest, approvalSource, approvedCommand,
domainLockHeld, hostCoordinatorProc, runtimeSupervisorProc,
attachedRunscProc, runtimeCausalEdge, supervisorLease,
runtimeFaultsRemaining,
domainGeneration,
durableDecision, durableSandboxIntent, pathMismatch
>>
CompleteHostExecution(r) ==
LET s == ReqSession(r)
d == ReqDomain(r)
IN
/\ requestPhase[r] = "Executing"
/\ HostCoordinatorAlive(d)
/\ r \in hostRunning
/\ requestPhase' = [requestPhase EXCEPT ![r] = "CompletionPending"]
/\ hostRunning' = hostRunning \ {r}
/\ sessionPhase' = [sessionPhase EXCEPT ![s] = "Attached"]
/\ terminalRoute' = [terminalRoute EXCEPT ![s] = "Sandbox"]
/\ UNCHANGED <<
domainPhase, stateAnchorState, sidecarState,
sandboxState, trustReady, lockOwner, published, registered, connected,
connectionState, activeRequest, approvalSource, approvedCommand,
domainLockHeld, hostCoordinatorProc, runtimeSupervisorProc,
attachedRunscProc, runtimeCausalEdge, supervisorLease,
runtimeFaultsRemaining,
domainGeneration,
durableDecision, durableSandboxIntent, pathMismatch
>>
TimeoutRequest(r) ==
LET s == ReqSession(r)
d == ReqDomain(r)
IN
/\ requestPhase[r] \in {"Verified", "AwaitingApproval", "Approved", "Executing"}
/\ HostCoordinatorAlive(d)
/\ activeRequest[s] = r
/\ requestPhase' = [requestPhase EXCEPT ![r] = "TimeoutPending"]
/\ sessionPhase' = [sessionPhase EXCEPT ![s] = "Attached"]
/\ terminalRoute' = [terminalRoute EXCEPT ![s] = "Sandbox"]
/\ hostRunning' = hostRunning \ {r}
/\ UNCHANGED <<
domainPhase, stateAnchorState, sidecarState,
sandboxState, trustReady, lockOwner, published, registered, connected,
connectionState, activeRequest, approvalSource, approvedCommand,
domainLockHeld, hostCoordinatorProc, runtimeSupervisorProc,
attachedRunscProc, runtimeCausalEdge, supervisorLease,
runtimeFaultsRemaining,
domainGeneration,
durableDecision, durableSandboxIntent, pathMismatch
>>
CancelRequest(r) ==
LET s == ReqSession(r)
d == ReqDomain(r)
IN
/\ requestPhase[r] \in {
"Verified", "AwaitingApproval", "Approved", "Executing"
}
/\ HostCoordinatorAlive(d)
/\ 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, stateAnchorState, sidecarState,
sandboxState, trustReady, lockOwner, published, registered, connected,
connectionState, activeRequest, approvalSource, approvedCommand,
domainLockHeld, hostCoordinatorProc, runtimeSupervisorProc,
attachedRunscProc, runtimeCausalEdge, supervisorLease,
runtimeFaultsRemaining,
domainGeneration,
durableDecision, durableSandboxIntent, pathMismatch
>>
FailHostExecution(r) ==
LET s == ReqSession(r)
d == ReqDomain(r)
IN
/\ requestPhase[r] = "Executing"
/\ HostCoordinatorAlive(d)
/\ 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, stateAnchorState, sidecarState,
sandboxState, trustReady, lockOwner, published, registered, connected,
connectionState, activeRequest, approvalSource, approvedCommand,
domainLockHeld, hostCoordinatorProc, runtimeSupervisorProc,
attachedRunscProc, runtimeCausalEdge, supervisorLease,
runtimeFaultsRemaining,
domainGeneration,
durableDecision, durableSandboxIntent, pathMismatch
>>
DeliverResult(r) ==
LET s == ReqSession(r)
d == ReqDomain(r)
IN
/\ requestPhase[r] \in PendingResultPhases
/\ HostCoordinatorAlive(d)
/\ activeRequest[s] = r
/\ connectionState[s] = "Connected"
/\ sessionPhase[s] = "Attached"
/\ requestPhase' = [requestPhase EXCEPT
![r] = DeliveredResultPhase(@)]
/\ activeRequest' = [activeRequest EXCEPT ![s] = NoRequest]
/\ UNCHANGED <<
domainPhase, stateAnchorState, sidecarState,
sandboxState, trustReady, lockOwner, published, registered, connected,
sessionPhase, terminalRoute, connectionState, approvalSource,
approvedCommand, hostRunning, domainLockHeld, hostCoordinatorProc,
runtimeSupervisorProc, attachedRunscProc, runtimeCausalEdge,
supervisorLease, runtimeFaultsRemaining,
domainGeneration,
durableDecision, durableSandboxIntent, pathMismatch
>>
(***************************************************************************
Failure, Host Coordinator lease loss, and recovery
Hard Host Coordinator loss withdraws publication and marks the generation
Failed without itself stopping the sandbox. The surviving Runtime Supervisor
observes supervisorLease = Lost and performs ordered teardown, then exits.
External recovery begins only after the supervisor is no longer present.
***************************************************************************)
FailDomain(d) ==
/\ domainPhase[d] \in {"Starting", "Ready", "Stopping"}
/\ domainPhase' = [domainPhase EXCEPT ![d] = "Failed"]
/\ trustReady' = [trustReady EXCEPT ![d] = FALSE]
/\ lockOwner' = [lockOwner EXCEPT ![d] = NoSession]
/\ published' = published \ {d}
/\ FailOpenSessionsAndRequests(d)
/\ UNCHANGED <<
stateAnchorState, sidecarState, sandboxState, approvalSource,
approvedCommand, domainLockHeld, hostCoordinatorProc,
runtimeSupervisorProc, attachedRunscProc, runtimeCausalEdge,
supervisorLease, runtimeFaultsRemaining,
domainGeneration,
durableDecision, durableSandboxIntent, pathMismatch
>>
HardLoseHostCoordinator(d) ==
/\ domainPhase[d] \in {"Starting", "Ready", "Stopping"}
/\ HostCoordinatorPresent(d)
/\ ConsumeRuntimeFault(d)
/\ domainPhase' = [domainPhase EXCEPT ![d] = "Failed"]
/\ trustReady' = [trustReady EXCEPT ![d] = FALSE]
/\ lockOwner' = [lockOwner EXCEPT ![d] = NoSession]
/\ published' = published \ {d}
/\ FailOpenSessionsAndRequests(d)
/\ hostCoordinatorProc' = [hostCoordinatorProc EXCEPT ![d] = "Dead"]
/\ supervisorLease' = [supervisorLease EXCEPT
![d] = IF supervisorLease[d] = "Held" THEN "Lost" ELSE @]
/\ UNCHANGED <<
stateAnchorState, sidecarState, sandboxState, approvalSource,
approvedCommand, domainLockHeld, runtimeSupervisorProc,
attachedRunscProc, runtimeCausalEdge,
domainGeneration,
durableDecision, durableSandboxIntent, pathMismatch
>>
HardLoseRuntimeSupervisor(d) ==
/\ domainPhase[d] \in {"Starting", "Ready", "Stopping", "Failed"}
/\ ProcessPresent(runtimeSupervisorProc[d])
/\ ConsumeRuntimeFault(d)
/\ domainPhase' = [domainPhase EXCEPT ![d] = "Failed"]
/\ trustReady' = [trustReady EXCEPT ![d] = FALSE]
/\ lockOwner' = [lockOwner EXCEPT ![d] = NoSession]
/\ published' = published \ {d}
/\ FailOpenSessionsAndRequests(d)
/\ runtimeSupervisorProc' = [runtimeSupervisorProc EXCEPT ![d] = "Dead"]
/\ attachedRunscProc' = [attachedRunscProc EXCEPT
![d] = IF runtimeCausalEdge[d] = "Armed"
/\ ProcessPresent(attachedRunscProc[d])
THEN "Dead"
ELSE @]
/\ sandboxState' = [sandboxState EXCEPT
![d] = IF runtimeCausalEdge[d] = "Armed" THEN "Stopped" ELSE @]
/\ runtimeCausalEdge' = [runtimeCausalEdge EXCEPT ![d] = "Unarmed"]
/\ supervisorLease' = [supervisorLease EXCEPT ![d] = "Unarmed"]
/\ UNCHANGED <<
stateAnchorState, sidecarState, approvalSource, approvedCommand,
domainLockHeld, hostCoordinatorProc,
domainGeneration,
durableDecision, durableSandboxIntent, pathMismatch
>>
HardLoseAttachedRunsc(d) ==
/\ domainPhase[d] \in {"Starting", "Ready", "Stopping", "Failed"}
/\ ProcessPresent(attachedRunscProc[d])
/\ ConsumeRuntimeFault(d)
/\ domainPhase' = [domainPhase EXCEPT ![d] = "Failed"]
/\ trustReady' = [trustReady EXCEPT ![d] = FALSE]
/\ lockOwner' = [lockOwner EXCEPT ![d] = NoSession]
/\ published' = published \ {d}
/\ FailOpenSessionsAndRequests(d)
/\ attachedRunscProc' = [attachedRunscProc EXCEPT ![d] = "Dead"]
/\ sandboxState' = [sandboxState EXCEPT ![d] = "Stopped"]
/\ runtimeCausalEdge' = [runtimeCausalEdge EXCEPT ![d] = "Unarmed"]
/\ UNCHANGED <<
stateAnchorState, sidecarState, approvalSource, approvedCommand,
domainLockHeld, hostCoordinatorProc, runtimeSupervisorProc,
supervisorLease,
domainGeneration,
durableDecision, durableSandboxIntent, pathMismatch
>>
StopHostCoordinatorProcess(d) ==
/\ domainPhase[d] \in {"Starting", "Ready", "Stopping", "Failed"}
/\ hostCoordinatorProc[d] = "Alive"
/\ ConsumeRuntimeFault(d)
/\ hostCoordinatorProc' = [hostCoordinatorProc EXCEPT ![d] = "Stopped"]
/\ UNCHANGED <<
domainPhase, stateAnchorState, sidecarState,
sandboxState, trustReady, lockOwner, published, registered, connected,
sessionPhase, terminalRoute, connectionState, activeRequest,
requestPhase, approvalSource, approvedCommand, hostRunning,
domainLockHeld, runtimeSupervisorProc, attachedRunscProc,
runtimeCausalEdge, supervisorLease,
domainGeneration,
durableDecision, durableSandboxIntent, pathMismatch
>>
ResumeHostCoordinatorProcess(d) ==
/\ hostCoordinatorProc[d] = "Stopped"
/\ hostCoordinatorProc' = [hostCoordinatorProc EXCEPT ![d] = "Alive"]
/\ UNCHANGED <<
domainPhase, stateAnchorState, sidecarState,
sandboxState, trustReady, lockOwner, published, registered, connected,
sessionPhase, terminalRoute, connectionState, activeRequest,
requestPhase, approvalSource, approvedCommand, hostRunning,
domainLockHeld, runtimeSupervisorProc, attachedRunscProc,
runtimeCausalEdge, supervisorLease, runtimeFaultsRemaining,
domainGeneration,
durableDecision, durableSandboxIntent, pathMismatch
>>
StopRuntimeSupervisorProcess(d) ==
/\ runtimeSupervisorProc[d] = "Alive"
/\ ConsumeRuntimeFault(d)
/\ runtimeSupervisorProc' = [runtimeSupervisorProc EXCEPT ![d] = "Stopped"]
/\ UNCHANGED <<
domainPhase, stateAnchorState, sidecarState,
sandboxState, trustReady, lockOwner, published, registered, connected,
sessionPhase, terminalRoute, connectionState, activeRequest,
requestPhase, approvalSource, approvedCommand, hostRunning,
domainLockHeld, hostCoordinatorProc, attachedRunscProc,
runtimeCausalEdge, supervisorLease,
domainGeneration,
durableDecision, durableSandboxIntent, pathMismatch
>>
ResumeRuntimeSupervisorProcess(d) ==
/\ runtimeSupervisorProc[d] = "Stopped"
/\ runtimeSupervisorProc' = [runtimeSupervisorProc EXCEPT ![d] = "Alive"]
/\ UNCHANGED <<
domainPhase, stateAnchorState, sidecarState,
sandboxState, trustReady, lockOwner, published, registered, connected,
sessionPhase, terminalRoute, connectionState, activeRequest,
requestPhase, approvalSource, approvedCommand, hostRunning,
domainLockHeld, hostCoordinatorProc, attachedRunscProc,
runtimeCausalEdge, supervisorLease, runtimeFaultsRemaining,
domainGeneration,
durableDecision, durableSandboxIntent, pathMismatch
>>
StopAttachedRunscProcess(d) ==
/\ attachedRunscProc[d] = "Alive"
/\ ConsumeRuntimeFault(d)
/\ attachedRunscProc' = [attachedRunscProc EXCEPT ![d] = "Stopped"]
/\ UNCHANGED <<
domainPhase, stateAnchorState, sidecarState,
sandboxState, trustReady, lockOwner, published, registered, connected,
sessionPhase, terminalRoute, connectionState, activeRequest,
requestPhase, approvalSource, approvedCommand, hostRunning,
domainLockHeld, hostCoordinatorProc, runtimeSupervisorProc,
runtimeCausalEdge, supervisorLease,
domainGeneration,
durableDecision, durableSandboxIntent, pathMismatch
>>
ResumeAttachedRunscProcess(d) ==
/\ attachedRunscProc[d] = "Stopped"
/\ attachedRunscProc' = [attachedRunscProc EXCEPT ![d] = "Alive"]
/\ UNCHANGED <<
domainPhase, stateAnchorState, sidecarState,
sandboxState, trustReady, lockOwner, published, registered, connected,
sessionPhase, terminalRoute, connectionState, activeRequest,
requestPhase, approvalSource, approvedCommand, hostRunning,
domainLockHeld, hostCoordinatorProc, runtimeSupervisorProc,
runtimeCausalEdge, supervisorLease, runtimeFaultsRemaining,
domainGeneration,
durableDecision, durableSandboxIntent, pathMismatch
>>
\* Surviving Host Coordinator health kill of an unresponsive or leftover runtime.
HostCoordinatorTerminateUnresponsiveRuntime(d) ==
/\ domainPhase[d] \in {"Starting", "Ready", "Stopping", "Failed"}
/\ HostCoordinatorAlive(d)
/\ supervisorLease[d] \in {"Held", "Unarmed"}
/\ \/ runtimeSupervisorProc[d] = "Stopped"
\/ attachedRunscProc[d] = "Stopped"
\/ /\ domainPhase[d] = "Failed"
/\ (ProcessPresent(runtimeSupervisorProc[d])
\/ ProcessPresent(attachedRunscProc[d]))
/\ domainPhase' = [domainPhase EXCEPT ![d] = "Failed"]
/\ trustReady' = [trustReady EXCEPT ![d] = FALSE]
/\ lockOwner' = [lockOwner EXCEPT ![d] = NoSession]
/\ published' = published \ {d}
/\ FailOpenSessionsAndRequests(d)
/\ runtimeSupervisorProc' = [runtimeSupervisorProc EXCEPT
![d] = IF ProcessPresent(runtimeSupervisorProc[d]) THEN "Dead" ELSE @]
/\ attachedRunscProc' = [attachedRunscProc EXCEPT
![d] = IF ProcessPresent(attachedRunscProc[d]) THEN "Dead" ELSE @]
/\ sandboxState' = [sandboxState EXCEPT ![d] = "Stopped"]
/\ runtimeCausalEdge' = [runtimeCausalEdge EXCEPT ![d] = "Unarmed"]
/\ supervisorLease' = [supervisorLease EXCEPT ![d] = "Unarmed"]
/\ UNCHANGED <<
stateAnchorState, sidecarState, approvalSource, approvedCommand,
domainLockHeld, hostCoordinatorProc, runtimeFaultsRemaining,
domainGeneration,
durableDecision, durableSandboxIntent, pathMismatch
>>
\* Ordered Runtime Supervisor teardown after Host Coordinator hard loss.
LeaseTeardownStopSandbox(d) ==
/\ domainPhase[d] = "Failed"
/\ supervisorLease[d] = "Lost"
/\ RuntimeSupervisorAlive(d)
/\ sandboxState[d] = "Ready"
/\ sandboxState' = [sandboxState EXCEPT ![d] = "Stopped"]
/\ attachedRunscProc' = [attachedRunscProc EXCEPT
![d] = IF ProcessPresent(attachedRunscProc[d]) THEN "Dead" ELSE "Absent"]
/\ runtimeCausalEdge' = [runtimeCausalEdge EXCEPT ![d] = "Unarmed"]
/\ UNCHANGED <<
domainPhase, stateAnchorState, sidecarState,
trustReady, lockOwner, published, registered, connected, sessionPhase,
terminalRoute, connectionState, activeRequest, requestPhase,
approvalSource, approvedCommand, hostRunning, domainLockHeld,
hostCoordinatorProc, runtimeSupervisorProc, supervisorLease,
runtimeFaultsRemaining,
domainGeneration,
durableDecision, durableSandboxIntent, pathMismatch
>>
LeaseTeardownStopSidecar(d) ==
/\ domainPhase[d] = "Failed"
/\ supervisorLease[d] = "Lost"
/\ RuntimeSupervisorAlive(d)
/\ sandboxState[d] = "Stopped"
/\ sidecarState[d] = "Ready"
/\ sidecarState' = [sidecarState EXCEPT ![d] = "Stopped"]
/\ UNCHANGED <<
domainPhase, stateAnchorState, sandboxState,
trustReady, lockOwner, published, registered, connected, sessionPhase,
terminalRoute, connectionState, activeRequest, requestPhase,
approvalSource, approvedCommand, hostRunning, domainLockHeld,
hostCoordinatorProc, runtimeSupervisorProc, attachedRunscProc,
runtimeCausalEdge, supervisorLease, runtimeFaultsRemaining,
domainGeneration,
durableDecision, durableSandboxIntent, pathMismatch
>>
LeaseTeardownUnmountStateAnchor(d) ==
/\ domainPhase[d] = "Failed"
/\ supervisorLease[d] = "Lost"
/\ RuntimeSupervisorAlive(d)
/\ sandboxState[d] = "Stopped"
/\ sidecarState[d] = "Stopped"
/\ stateAnchorState[d] = "Mounted"
/\ stateAnchorState' = [stateAnchorState EXCEPT ![d] = "Unmounted"]
/\ UNCHANGED <<
domainPhase, sidecarState, sandboxState, trustReady,
lockOwner, published, registered, connected, sessionPhase,
terminalRoute, connectionState, activeRequest, requestPhase,
approvalSource, approvedCommand, hostRunning, domainLockHeld,
hostCoordinatorProc, runtimeSupervisorProc, attachedRunscProc,
runtimeCausalEdge, supervisorLease, runtimeFaultsRemaining,
domainGeneration,
durableDecision, durableSandboxIntent, pathMismatch
>>
LeaseTeardownSupervisorExit(d) ==
/\ domainPhase[d] = "Failed"
/\ supervisorLease[d] = "Lost"
/\ RuntimeSupervisorAlive(d)
/\ sandboxState[d] = "Stopped"
/\ sidecarState[d] = "Stopped"
/\ stateAnchorState[d] = "Unmounted"
/\ runtimeSupervisorProc' = [runtimeSupervisorProc EXCEPT ![d] = "Dead"]
/\ attachedRunscProc' = [attachedRunscProc EXCEPT
![d] = IF attachedRunscProc[d] \in {"Alive", "Stopped"} THEN "Dead" ELSE @]
/\ runtimeCausalEdge' = [runtimeCausalEdge EXCEPT ![d] = "Unarmed"]
/\ supervisorLease' = [supervisorLease EXCEPT ![d] = "Unarmed"]
/\ UNCHANGED <<
domainPhase, stateAnchorState, sidecarState,
sandboxState, trustReady, lockOwner, published, registered, connected,
sessionPhase, terminalRoute, connectionState, activeRequest,
requestPhase, approvalSource, approvedCommand, hostRunning,
domainLockHeld, hostCoordinatorProc, runtimeFaultsRemaining,
domainGeneration,
durableDecision, durableSandboxIntent, pathMismatch
>>
\* After HC hard loss, a stopped RS cannot run userspace lease teardown.
\* An external reaper may kill the stopped supervisor and apply the causal edge.
\* It does not clear sidecar or State Anchor; those remain for recovery.
ExternalReapStoppedSupervisorAfterHcLoss(d) ==
/\ domainPhase[d] = "Failed"
/\ supervisorLease[d] = "Lost"
/\ runtimeSupervisorProc[d] = "Stopped"
/\ runtimeSupervisorProc' = [runtimeSupervisorProc EXCEPT ![d] = "Dead"]
/\ attachedRunscProc' = [attachedRunscProc EXCEPT
![d] = IF ProcessPresent(attachedRunscProc[d]) THEN "Dead" ELSE @]
/\ sandboxState' = [sandboxState EXCEPT
![d] = IF runtimeCausalEdge[d] = "Armed" \/ sandboxState[d] = "Ready"
THEN "Stopped"
ELSE @]
/\ runtimeCausalEdge' = [runtimeCausalEdge EXCEPT ![d] = "Unarmed"]
/\ supervisorLease' = [supervisorLease EXCEPT ![d] = "Unarmed"]
/\ UNCHANGED <<
domainPhase, stateAnchorState, sidecarState,
trustReady, lockOwner, published, registered, connected, sessionPhase,
terminalRoute, connectionState, activeRequest, requestPhase,
approvalSource, approvedCommand, hostRunning, domainLockHeld,
hostCoordinatorProc, runtimeFaultsRemaining,
domainGeneration,
durableDecision, durableSandboxIntent, pathMismatch
>>
\* New recovery principal after total HC hard loss and runtime reaps.
BootstrapRecoveryCoordinator(d) ==
/\ domainPhase[d] = "Failed"
/\ hostCoordinatorProc[d] = "Dead"
/\ supervisorLease[d] = "Unarmed"
/\ ~ProcessPresent(runtimeSupervisorProc[d])
/\ ~ProcessPresent(attachedRunscProc[d])
/\ runtimeCausalEdge[d] = "Unarmed"
/\ registered[d] = {}
/\ connected[d] = {}
/\ hostRunning \cap RequestsForDomain(d) = {}
/\ domainPhase' = [domainPhase EXCEPT ![d] = "Recovering"]
/\ 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, supervisorLease,
runtimeFaultsRemaining,
domainGeneration,
durableDecision, durableSandboxIntent, pathMismatch
>>
BeginRecovery(d) ==
/\ domainPhase[d] = "Failed"
/\ HostCoordinatorAlive(d)
/\ supervisorLease[d] = "Unarmed"
/\ ~ProcessPresent(runtimeSupervisorProc[d])
/\ ~ProcessPresent(attachedRunscProc[d])
/\ runtimeCausalEdge[d] = "Unarmed"
/\ registered[d] = {}
/\ connected[d] = {}
/\ hostRunning \cap RequestsForDomain(d) = {}
/\ domainPhase' = [domainPhase EXCEPT ![d] = "Recovering"]
/\ domainLockHeld' = [domainLockHeld EXCEPT ![d] = TRUE]
/\ UNCHANGED <<
stateAnchorState, sidecarState, sandboxState, trustReady, lockOwner,
published, registered, connected, sessionPhase, terminalRoute,
connectionState, activeRequest, requestPhase, approvalSource,
approvedCommand, hostRunning, hostCoordinatorProc,
runtimeSupervisorProc, attachedRunscProc, runtimeCausalEdge,
supervisorLease, runtimeFaultsRemaining,
domainGeneration,
durableDecision, durableSandboxIntent, pathMismatch
>>
RecoverSandbox(d) ==
/\ domainPhase[d] = "Recovering"
/\ HostCoordinatorAlive(d)
/\ runtimeCausalEdge[d] = "Unarmed"
/\ ~ProcessPresent(runtimeSupervisorProc[d])
/\ ~ProcessPresent(attachedRunscProc[d])
/\ ~pathMismatch[d]
/\ \/ sandboxState[d] # "Stopped"
\/ attachedRunscProc[d] = "Dead"
\* Exact-owned Ready sandbox cleanup requires durable intent.
/\ (sandboxState[d] # "Stopped" => durableSandboxIntent[d])
/\ sandboxState' = [sandboxState EXCEPT ![d] = "Stopped"]
/\ attachedRunscProc' = [attachedRunscProc EXCEPT ![d] = "Absent"]
/\ UNCHANGED <<
domainPhase, stateAnchorState, sidecarState,
trustReady, lockOwner, published, registered, connected, sessionPhase,
terminalRoute, connectionState, activeRequest, requestPhase,
approvalSource, approvedCommand, hostRunning, domainLockHeld,
hostCoordinatorProc, runtimeSupervisorProc, runtimeCausalEdge,
supervisorLease, runtimeFaultsRemaining,
domainGeneration,
durableDecision, durableSandboxIntent, pathMismatch
>>
RecoverSidecar(d) ==
/\ domainPhase[d] = "Recovering"
/\ HostCoordinatorAlive(d)
/\ sandboxState[d] = "Stopped"
/\ attachedRunscProc[d] = "Absent"
/\ runtimeCausalEdge[d] = "Unarmed"
/\ ~ProcessPresent(runtimeSupervisorProc[d])
/\ sidecarState[d] # "Stopped"
/\ sidecarState' = [sidecarState EXCEPT ![d] = "Stopped"]
/\ UNCHANGED <<
domainPhase, stateAnchorState, sandboxState,
trustReady, lockOwner, published, registered, connected, sessionPhase,
terminalRoute, connectionState, activeRequest, requestPhase,
approvalSource, approvedCommand, hostRunning, domainLockHeld,
hostCoordinatorProc, runtimeSupervisorProc, attachedRunscProc,
runtimeCausalEdge, supervisorLease, runtimeFaultsRemaining,
domainGeneration,
durableDecision, durableSandboxIntent, pathMismatch
>>
RecoverStateAnchor(d) ==
/\ domainPhase[d] = "Recovering"
/\ HostCoordinatorAlive(d)
/\ sandboxState[d] = "Stopped"
/\ attachedRunscProc[d] = "Absent"
/\ runtimeCausalEdge[d] = "Unarmed"
/\ ~ProcessPresent(runtimeSupervisorProc[d])
/\ sidecarState[d] = "Stopped"
/\ stateAnchorState[d] = "Mounted"
/\ stateAnchorState' = [stateAnchorState EXCEPT ![d] = "Unmounted"]
/\ UNCHANGED <<
domainPhase, sidecarState, sandboxState, trustReady,
lockOwner, published, registered, connected, sessionPhase,
terminalRoute, connectionState, activeRequest, requestPhase,
approvalSource, approvedCommand, hostRunning, domainLockHeld,
hostCoordinatorProc, runtimeSupervisorProc, attachedRunscProc,
runtimeCausalEdge, supervisorLease, runtimeFaultsRemaining,
domainGeneration,
durableDecision, durableSandboxIntent, pathMismatch
>>
FinishRecovery(d) ==
/\ domainPhase[d] = "Recovering"
/\ HostCoordinatorAlive(d)
/\ stateAnchorState[d] = "Unmounted"
/\ sidecarState[d] = "Stopped"
/\ sandboxState[d] = "Stopped"
/\ attachedRunscProc[d] \in {"Absent", "Dead"}
/\ runtimeSupervisorProc[d] \in {"Absent", "Dead"}
/\ ~ProcessPresent(runtimeSupervisorProc[d])
/\ ~ProcessPresent(attachedRunscProc[d])
/\ supervisorLease[d] = "Unarmed"
/\ runtimeCausalEdge[d] = "Unarmed"
/\ domainPhase' = [domainPhase 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"]
/\ supervisorLease' = [supervisorLease EXCEPT ![d] = "Unarmed"]
/\ durableDecision' = [durableDecision EXCEPT ![d] = "Clean"]
/\ durableSandboxIntent' = [durableSandboxIntent EXCEPT ![d] = FALSE]
\* Drop generation-document observation of path leftovers; physical foreign
\* leftovers remain outside the model.
/\ pathMismatch' = [pathMismatch EXCEPT ![d] = FALSE]
/\ UNCHANGED <<
stateAnchorState, sidecarState, sandboxState, published,
registered, connected, sessionPhase, terminalRoute, connectionState,
activeRequest, requestPhase, approvalSource, approvedCommand,
hostRunning, runtimeFaultsRemaining,
domainGeneration
>>
(***************************************************************************
Durable generation document and mismatch refuse
pathMismatch abstracts wrong-owner or missing-intent observation at the
deterministic sandbox path. Refuse leaves the claim in place; recovery never
adopts a mismatched path into sandboxState.
***************************************************************************)
ObservePathMismatch(d) ==
/\ domainPhase[d] \in {"Failed", "Recovering"}
/\ sandboxState[d] = "Stopped"
/\ attachedRunscProc[d] = "Absent"
/\ ~pathMismatch[d]
/\ pathMismatch' = [pathMismatch EXCEPT ![d] = TRUE]
/\ UNCHANGED <<
domainPhase, stateAnchorState, sidecarState,
sandboxState, trustReady, lockOwner, published, registered, connected,
sessionPhase, terminalRoute, connectionState, activeRequest,
requestPhase, approvalSource, approvedCommand, hostRunning,
domainLockHeld, hostCoordinatorProc, runtimeSupervisorProc,
attachedRunscProc, runtimeCausalEdge, supervisorLease,
runtimeFaultsRemaining, domainGeneration,
durableDecision, durableSandboxIntent
>>
\* Wrong-owner / missing-intent refuse: fail closed, do not delete or adopt.
RefusePathMismatchCleanup(d) ==
/\ domainPhase[d] \in {"Failed", "Recovering"}
/\ HostCoordinatorAlive(d)
/\ pathMismatch[d]
/\ UNCHANGED vars
DomainServiceProgress(d) ==
\/ CreateTrustAnchor(d)
\/ StartRuntimeSupervisor(d)
\/ MountStateAnchor(d)
\/ StartSidecar(d)
\/ ArmRuntimeCausalEdge(d)
\/ StartSandbox(d)
\/ PublishDomain(d)
\/ BeginTeardown(d)
\/ StopSandbox(d)
\/ StopSidecar(d)
\/ UnmountStateAnchor(d)
\/ GracefulSupervisorExit(d)
\/ FinishTeardown(d)
\/ HostCoordinatorTerminateUnresponsiveRuntime(d)
\/ LeaseTeardownStopSandbox(d)
\/ LeaseTeardownStopSidecar(d)
\/ LeaseTeardownUnmountStateAnchor(d)
\/ LeaseTeardownSupervisorExit(d)
\/ ExternalReapStoppedSupervisorAfterHcLoss(d)
\/ BootstrapRecoveryCoordinator(d)
\/ BeginRecovery(d)
\/ RecoverSandbox(d)
\/ RecoverSidecar(d)
\/ RecoverStateAnchor(d)
\/ FinishRecovery(d)
RuntimePhysicalInterleaving(d) ==
\/ HardLoseHostCoordinator(d)
\/ HardLoseRuntimeSupervisor(d)
\/ HardLoseAttachedRunsc(d)
\/ StopHostCoordinatorProcess(d)
\/ ResumeHostCoordinatorProcess(d)
\/ StopRuntimeSupervisorProcess(d)
\/ ResumeRuntimeSupervisorProcess(d)
\/ StopAttachedRunscProcess(d)
\/ ResumeAttachedRunscProcess(d)
\/ ObservePathMismatch(d)
\/ RefusePathMismatchCleanup(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 :
DomainServiceProgress(d) \/ FailDomain(d))
\/ (\E d \in Domains :
RuntimePhysicalInterleaving(d))
\/ (\E r \in Requests :
ReceiveEscalation(r) \/ RequestProgress(r))
\* Resume transitions are enabled but not weakly fair: permanent stop is a
\* modeled stuck state for safety, not a guaranteed progress path.
Spec ==
/\ Init
/\ [][Next]_vars
/\ \A d \in Domains : WF_vars(DomainServiceProgress(d))
/\ \A s \in Sessions : WF_vars(SessionProgress(s))
/\ \A r \in Requests : WF_vars(RequestProgress(r))
(***************************************************************************
Safety properties
***************************************************************************)
TypeOK ==
/\ domainPhase \in [Domains -> DomainPhases]
/\ 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]
/\ supervisorLease \in [Domains -> SupervisorLeaseStates]
/\ runtimeFaultsRemaining \in [Domains -> 0..2]
/\ domainGeneration \in [Domains -> 0..MaxDomainGeneration]
/\ durableDecision \in [Domains -> DurableDecisions]
/\ durableSandboxIntent \in [Domains -> BOOLEAN]
/\ pathMismatch \in [Domains -> BOOLEAN]
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"
/\ HostCoordinatorPresent(d)
/\ RuntimeSupervisorAlive(d) \/ runtimeSupervisorProc[d] = "Stopped"
/\ stateAnchorState[d] = "Mounted"
/\ sidecarState[d] = "Ready"
/\ sandboxState[d] = "Ready"
/\ trustReady[d]
/\ supervisorLease[d] = "Held"
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])
/\ supervisorLease[d] \in {"Held", "Lost"}
SandboxRunningImpliesCoordinatorPresent ==
\A d \in Domains :
sandboxState[d] = "Ready" => SessionCoordinatorPresent(d)
PublishedRuntimeAuthorityPresent ==
\A d \in published :
/\ SessionCoordinatorPresent(d)
/\ HostCoordinatorPresent(d)
SupervisorLeaseConsistency ==
\A d \in Domains :
/\ (supervisorLease[d] = "Unarmed" =>
~ProcessPresent(runtimeSupervisorProc[d]))
/\ (supervisorLease[d] = "Held" =>
/\ HostCoordinatorPresent(d)
/\ ProcessPresent(runtimeSupervisorProc[d]))
/\ (supervisorLease[d] = "Lost" =>
/\ hostCoordinatorProc[d] = "Dead"
/\ ProcessPresent(runtimeSupervisorProc[d]))
/\ (ProcessPresent(runtimeSupervisorProc[d]) =>
supervisorLease[d] \in {"Held", "Lost"})
RuntimeResourceOwnership ==
\A d \in Domains :
domainPhase[d] \in {"Starting", "Ready", "Stopping"} =>
/\ (stateAnchorState[d] = "Mounted" =>
ProcessPresent(runtimeSupervisorProc[d]))
/\ (sidecarState[d] = "Ready" =>
ProcessPresent(runtimeSupervisorProc[d]))
/\ (sandboxState[d] = "Ready" =>
/\ ProcessPresent(runtimeSupervisorProc[d])
/\ supervisorLease[d] = "Held")
CoordinatorPhysicalConsistency ==
\A d \in Domains :
/\ (domainPhase[d] = "Absent" <=> hostCoordinatorProc[d] = "Absent")
/\ (domainPhase[d] \in {"Starting", "Ready", "Stopping"} =>
HostCoordinatorPresent(d))
/\ (domainPhase[d] = "Recovering" => HostCoordinatorAlive(d))
/\ (hostCoordinatorProc[d] = "Dead" => domainPhase[d] = "Failed")
HostCoordinatorRequiresDomainOwnership ==
\A d \in Domains :
hostCoordinatorProc[d] # "Absent" =>
/\ domainPhase[d] # "Absent"
/\ domainLockHeld[d]
ExclusiveBootstrapOwnership ==
\A d \in Domains : lockOwner[d] # NoSession =>
/\ domainPhase[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]]
/\ HostCoordinatorPresent(ReqDomain(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" =>
/\ domainPhase[d] # "Absent"
/\ domainLockHeld[d]
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"
/\ attachedRunscProc[d] \in {"Absent", "Dead"})
/\ (stateAnchorState[d] = "Unmounted" =>
/\ sandboxState[d] = "Stopped"
/\ attachedRunscProc[d] \in {"Absent", "Dead"}
/\ sidecarState[d] = "Stopped")
OrderedLeaseTeardown ==
\A d \in Domains :
(domainPhase[d] = "Failed" /\ supervisorLease[d] = "Lost") =>
/\ (sidecarState[d] = "Stopped" => sandboxState[d] = "Stopped")
/\ (stateAnchorState[d] = "Unmounted" =>
/\ sandboxState[d] = "Stopped"
/\ sidecarState[d] = "Stopped")
NoVanishPresentRuntime ==
\A d \in Domains :
/\ (runtimeSupervisorProc[d] = "Absent" =>
supervisorLease[d] = "Unarmed")
/\ (domainPhase[d] = "Recovering" =>
/\ HostCoordinatorAlive(d)
/\ supervisorLease[d] = "Unarmed"
/\ ~ProcessPresent(runtimeSupervisorProc[d])
/\ ~ProcessPresent(attachedRunscProc[d]))
DomainGenerationBounds ==
\A d \in Domains :
/\ domainGeneration[d] \in 0..MaxDomainGeneration
/\ (domainPhase[d] # "Absent" => domainGeneration[d] > 0)
DurableIntentBeforeSandboxReady ==
\A d \in Domains :
sandboxState[d] = "Ready" => durableSandboxIntent[d]
\* Published generation document decision tracks authenticated publication.
DurableDecisionPublicationConsistent ==
\A d \in Domains :
/\ (d \in published => durableDecision[d] = "Published")
/\ (durableDecision[d] = "Published" => durableSandboxIntent[d])
\* pathMismatch blocks exact-owned sandbox cleanup (wrong-owner / missing-intent).
\* RefusePathMismatchCleanup stutters; RecoverSandbox requires ~pathMismatch.
PathMismatchNotAdopted ==
\A d \in Domains :
pathMismatch[d] => sandboxState[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
/\ SupervisorLeaseConsistency
/\ RuntimeResourceOwnership
/\ CoordinatorPhysicalConsistency
/\ HostCoordinatorRequiresDomainOwnership
/\ NoVanishPresentRuntime
/\ OrderedLeaseTeardown
/\ DomainGenerationBounds
/\ DurableIntentBeforeSandboxReady
/\ DurableDecisionPublicationConsistent
/\ PathMismatchNotAdopted
/\ ExclusiveBootstrapOwnership
/\ TeardownNotJoinable
/\ RegisteredSessionsConnected
/\ AttachedSessionsValid
/\ AuthenticatedRequestsOnly
/\ RuntimeRoleIdentitySeparation
/\ RegisteredSessionIdentityUniqueness
/\ LiveRequestIdentityAuthorized
/\ DeveloperApprovalAuthenticated
/\ HostExecutionAuthorized
/\ AutoApprovalNoShell
/\ TerminalIsolation
/\ NoOrphanHostProcess
/\ StateAnchorOwnership
/\ FailedDomainIsolation
/\ OrderedFailureRecovery
/\ ResultDeliveryStateConsistent
(***************************************************************************
Liveness properties.
Permanent Host Coordinator stop is an allowed safety-stuck state: progress
obligations are discharged by resolution or by permanent unresponsiveness.
***************************************************************************)
SessionEventuallyResolves ==
\A s \in Sessions :
sessionPhase[s] = "New" ~>
\/ sessionPhase[s] \in {"Attached", "Closed", "Failed"}
\/ <>[](hostCoordinatorProc[Dom(s)] = "Stopped")
RequestEventuallyResolves ==
\A r \in Requests :
requestPhase[r] = "Verified" ~>
\/ requestPhase[r] \in TerminalRequestPhases
\/ <>[](hostCoordinatorProc[ReqDomain(r)] = "Stopped")
PromptEventuallyRestoresTerminal ==
\A s \in Sessions :
sessionPhase[s] \in {"Prompting", "HostExecuting"} ~>
\/ terminalRoute[s] \in {"Sandbox", "Detached"}
\/ <>[](hostCoordinatorProc[Dom(s)] = "Stopped")
EmptyDomainEventuallyStops ==
\A d \in Domains :
(<>[](Interested(d) = {} /\ HostCoordinatorAlive(d)
/\ runtimeSupervisorProc[d] # "Stopped"
/\ attachedRunscProc[d] # "Stopped")) =>
<>(domainPhase[d] = "Absent")
FailedDomainEventuallyRecovers ==
\A d \in Domains :
domainPhase[d] = "Failed" ~>
\/ domainPhase[d] = "Absent"
\/ <>[](hostCoordinatorProc[d] = "Stopped")
=============================================================================