Add SessionCoordinatorPresent aliases, HC protocol-face naming, and abstract durable intent/path-mismatch refuse invariants for FM1/FM4/FM5. TLC green at 395837 generated / 110013 distinct / depth 49.
2120 lines
85 KiB
Text
2120 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 (DR-M3 vocabulary).
|
||
|
||
Product names SessionCoordinatorPresent and Session Coordinator ID alias the
|
||
existing multi-process predicates and DomainCoordinatorIdentity fixture (SC1–SC3).
|
||
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
|
||
\* DR-M3 generation-document decision lifecycle (abstract; not typed redb tables).
|
||
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])
|
||
|
||
\* Multi-process Session Coordinator product vocabulary (saga 18 SC1–SC3).
|
||
\* 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)
|
||
|
||
\* SC3: one logical SC 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]
|
||
\* Durable sandbox Intent is recorded with the generation document before the
|
||
\* external sandbox create completes (DR-M3 intent-before-create).
|
||
/\ 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 (DR-M3).
|
||
/\ (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 (SC6 unpublished leftovers).
|
||
/\ 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 / mismatch refuse (DR-M3 / FM4 abstract)
|
||
|
||
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")
|
||
|
||
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)
|
||
|
||
\* DR-M3 / FM4: Ready sandbox implies durable sandbox Intent was recorded.
|
||
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
|
||
/\ 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")
|
||
|
||
=============================================================================
|