Model actor-attributed terminal recovery
This commit is contained in:
parent
55eed08db7
commit
3c00a6c59f
1 changed files with 187 additions and 13 deletions
|
|
@ -18,15 +18,16 @@ 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.
|
||||
durable Session Terminal and PTY lifecycle; 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 presence predicates and generation-scoped genCoordinatorId.
|
||||
Durable participant intent is multi-role; networkReady gates publication;
|
||||
preparedLowerLeased and helperProc refine physical ownership under RS.
|
||||
Cryptographic algorithms, serialization, container commands, filesystems, typed
|
||||
redb tables, and network packet handling remain refinement boundaries.
|
||||
redb tables, PTY descriptor identities, process identifiers, signal mechanics,
|
||||
and network packet handling remain refinement boundaries.
|
||||
***************************************************************************)
|
||||
|
||||
CONSTANTS
|
||||
|
|
@ -136,6 +137,7 @@ SessionPhases == {
|
|||
"HostExecuting", "Closed", "Failed"
|
||||
}
|
||||
TerminalRoutes == {"Detached", "Sandbox", "Prompt", "HostProcess"}
|
||||
SessionTerminalStates == {"Clean", "Intent", "Running", "ReleaseIntent"}
|
||||
ConnectionStates == {"Disconnected", "Connected"}
|
||||
RequestPhases == {
|
||||
"Unused", "Verified", "AwaitingApproval", "Approved", "Executing",
|
||||
|
|
@ -273,9 +275,13 @@ VARIABLES
|
|||
genSandboxId,
|
||||
networkReady,
|
||||
preparedLowerLeased,
|
||||
helperProc
|
||||
helperProc,
|
||||
sessionTerminalState,
|
||||
sessionPtyOpen,
|
||||
sessionExecPresent,
|
||||
sessionGuestKnown
|
||||
|
||||
vars == <<
|
||||
baseVars == <<
|
||||
domainPhase,
|
||||
stateAnchorState,
|
||||
sidecarState,
|
||||
|
|
@ -312,6 +318,15 @@ vars == <<
|
|||
helperProc
|
||||
>>
|
||||
|
||||
terminalVars == <<
|
||||
sessionTerminalState,
|
||||
sessionPtyOpen,
|
||||
sessionExecPresent,
|
||||
sessionGuestKnown
|
||||
>>
|
||||
|
||||
vars == <<baseVars, terminalVars>>
|
||||
|
||||
Dom(s) == SessionDomain[s]
|
||||
ReqSession(r) == RequestSession[r]
|
||||
ReqDomain(r) == Dom(ReqSession(r))
|
||||
|
|
@ -381,6 +396,14 @@ RuntimeGenerationAbsent(d) ==
|
|||
/\ ~preparedLowerLeased[d]
|
||||
/\ ~networkReady[d]
|
||||
|
||||
RuntimeAbsentForTerminal(d) ==
|
||||
/\ sandboxState[d] = "Stopped"
|
||||
/\ ~ProcessPresent(runtimeSupervisorProc[d])
|
||||
/\ ~ProcessPresent(attachedRunscProc[d])
|
||||
|
||||
SessionTerminalsClean(d) ==
|
||||
\A s \in Sessions : Dom(s) = d => sessionTerminalState[s] = "Clean"
|
||||
|
||||
ConsumeRuntimeFault(d) ==
|
||||
/\ runtimeFaultsRemaining[d] > 0
|
||||
/\ runtimeFaultsRemaining' =
|
||||
|
|
@ -493,6 +516,10 @@ Init ==
|
|||
/\ networkReady = [d \in Domains |-> FALSE]
|
||||
/\ preparedLowerLeased = [d \in Domains |-> FALSE]
|
||||
/\ helperProc = [d \in Domains |-> "Absent"]
|
||||
/\ sessionTerminalState = [s \in Sessions |-> "Clean"]
|
||||
/\ sessionPtyOpen = [s \in Sessions |-> FALSE]
|
||||
/\ sessionExecPresent = [s \in Sessions |-> FALSE]
|
||||
/\ sessionGuestKnown = [s \in Sessions |-> FALSE]
|
||||
|
||||
(***************************************************************************
|
||||
Domain and Session lifecycle
|
||||
|
|
@ -852,6 +879,97 @@ DisconnectSession(s) ==
|
|||
durableDecision, durableIntent, pathMismatch, genCoordinatorId, genSidecarId, genSandboxId, networkReady, preparedLowerLeased, helperProc
|
||||
>>
|
||||
|
||||
(***************************************************************************
|
||||
Session Terminal and PTY lifecycle
|
||||
|
||||
The model retains durable state plus abstract PTY, exec-client, and guest
|
||||
identity facts. Descriptor identities, PID reuse checks, and signal delivery
|
||||
remain physical refinements.
|
||||
***************************************************************************)
|
||||
|
||||
BeginSessionTerminal(s) ==
|
||||
LET d == Dom(s) IN
|
||||
/\ sessionPhase[s] = "Attached"
|
||||
/\ terminalRoute[s] = "Sandbox"
|
||||
/\ RegistrationAdmissible(d)
|
||||
/\ sessionTerminalState[s] = "Clean"
|
||||
/\ sessionTerminalState' = [sessionTerminalState EXCEPT ![s] = "Intent"]
|
||||
/\ sessionPtyOpen' = [sessionPtyOpen EXCEPT ![s] = TRUE]
|
||||
/\ sessionExecPresent' = [sessionExecPresent EXCEPT ![s] = TRUE]
|
||||
/\ sessionGuestKnown' = [sessionGuestKnown EXCEPT ![s] = FALSE]
|
||||
/\ UNCHANGED baseVars
|
||||
|
||||
CommitSessionTerminal(s) ==
|
||||
/\ sessionPhase[s] = "Attached"
|
||||
/\ terminalRoute[s] = "Sandbox"
|
||||
/\ HostCoordinatorAlive(Dom(s))
|
||||
/\ sessionTerminalState[s] = "Intent"
|
||||
/\ sessionPtyOpen[s]
|
||||
/\ sessionExecPresent[s]
|
||||
/\ sessionTerminalState' = [sessionTerminalState EXCEPT ![s] = "Running"]
|
||||
/\ sessionGuestKnown' = [sessionGuestKnown EXCEPT ![s] = TRUE]
|
||||
/\ UNCHANGED <<baseVars, sessionPtyOpen, sessionExecPresent>>
|
||||
|
||||
DisconnectCleanSession(s) ==
|
||||
/\ sessionTerminalState[s] = "Clean"
|
||||
/\ DisconnectSession(s)
|
||||
/\ UNCHANGED terminalVars
|
||||
|
||||
DisconnectLiveSessionTerminal(s) ==
|
||||
/\ sessionTerminalState[s] \in {"Intent", "Running"}
|
||||
/\ DisconnectSession(s)
|
||||
/\ sessionTerminalState' =
|
||||
[sessionTerminalState EXCEPT ![s] = "ReleaseIntent"]
|
||||
/\ UNCHANGED <<sessionPtyOpen, sessionExecPresent, sessionGuestKnown>>
|
||||
|
||||
CompleteSessionTerminal(s) ==
|
||||
/\ sessionTerminalState[s] = "Running"
|
||||
/\ DisconnectSession(s)
|
||||
/\ sessionTerminalState' =
|
||||
[sessionTerminalState EXCEPT ![s] = "ReleaseIntent"]
|
||||
/\ sessionExecPresent' = [sessionExecPresent EXCEPT ![s] = FALSE]
|
||||
/\ UNCHANGED <<sessionPtyOpen, sessionGuestKnown>>
|
||||
|
||||
ExitSessionTerminalBeforeGuestIdentity(s) ==
|
||||
/\ sessionTerminalState[s] = "Intent"
|
||||
/\ DisconnectSession(s)
|
||||
/\ sessionTerminalState' =
|
||||
[sessionTerminalState EXCEPT ![s] = "ReleaseIntent"]
|
||||
/\ sessionPtyOpen' = [sessionPtyOpen EXCEPT ![s] = FALSE]
|
||||
/\ sessionExecPresent' = [sessionExecPresent EXCEPT ![s] = FALSE]
|
||||
/\ UNCHANGED sessionGuestKnown
|
||||
|
||||
RetainFailedSessionTerminal(s) ==
|
||||
/\ sessionPhase[s] = "Failed"
|
||||
/\ sessionTerminalState[s] \in {"Intent", "Running"}
|
||||
/\ sessionTerminalState' =
|
||||
[sessionTerminalState EXCEPT ![s] = "ReleaseIntent"]
|
||||
/\ sessionPtyOpen' = [sessionPtyOpen EXCEPT ![s] = FALSE]
|
||||
/\ sessionExecPresent' = [sessionExecPresent EXCEPT ![s] = FALSE]
|
||||
/\ UNCHANGED <<baseVars, sessionGuestKnown>>
|
||||
|
||||
CleanKnownSessionTerminal(s) ==
|
||||
/\ sessionPhase[s] \in {"Closed", "Failed"}
|
||||
/\ sessionTerminalState[s] = "ReleaseIntent"
|
||||
/\ sessionGuestKnown[s]
|
||||
/\ HostCoordinatorAlive(Dom(s))
|
||||
/\ sessionTerminalState' = [sessionTerminalState EXCEPT ![s] = "Clean"]
|
||||
/\ sessionPtyOpen' = [sessionPtyOpen EXCEPT ![s] = FALSE]
|
||||
/\ sessionExecPresent' = [sessionExecPresent EXCEPT ![s] = FALSE]
|
||||
/\ sessionGuestKnown' = [sessionGuestKnown EXCEPT ![s] = FALSE]
|
||||
/\ UNCHANGED baseVars
|
||||
|
||||
BootstrapCleanSessionTerminalAfterRuntimeAbsence(s) ==
|
||||
/\ sessionPhase[s] \in {"Closed", "Failed"}
|
||||
/\ sessionTerminalState[s] = "ReleaseIntent"
|
||||
/\ ~sessionPtyOpen[s]
|
||||
/\ ~sessionExecPresent[s]
|
||||
/\ RuntimeAbsentForTerminal(Dom(s))
|
||||
/\ HostCoordinatorAlive(Dom(s))
|
||||
/\ sessionTerminalState' = [sessionTerminalState EXCEPT ![s] = "Clean"]
|
||||
/\ sessionGuestKnown' = [sessionGuestKnown EXCEPT ![s] = FALSE]
|
||||
/\ UNCHANGED <<baseVars, sessionPtyOpen, sessionExecPresent>>
|
||||
|
||||
BeginTeardown(d) ==
|
||||
/\ domainPhase[d] = "Ready"
|
||||
/\ HostCoordinatorAlive(d)
|
||||
|
|
@ -1970,6 +2088,17 @@ SessionProgress(s) ==
|
|||
\/ RejectConfigurationMismatch(s)
|
||||
\/ RegisterSession(s)
|
||||
|
||||
SessionTerminalProgress(s) ==
|
||||
\/ BeginSessionTerminal(s)
|
||||
\/ CommitSessionTerminal(s)
|
||||
\/ DisconnectCleanSession(s)
|
||||
\/ DisconnectLiveSessionTerminal(s)
|
||||
\/ CompleteSessionTerminal(s)
|
||||
\/ ExitSessionTerminalBeforeGuestIdentity(s)
|
||||
\/ RetainFailedSessionTerminal(s)
|
||||
\/ CleanKnownSessionTerminal(s)
|
||||
\/ BootstrapCleanSessionTerminalAfterRuntimeAbsence(s)
|
||||
|
||||
RequestProgress(r) ==
|
||||
\/ AutoApprove(r)
|
||||
\/ QueuePrompt(r)
|
||||
|
|
@ -1983,12 +2112,12 @@ RequestProgress(r) ==
|
|||
\/ FailHostExecution(r)
|
||||
\/ DeliverResult(r)
|
||||
|
||||
Next ==
|
||||
BaseNext ==
|
||||
\/ (\E s \in Sessions :
|
||||
StartNewDomain(s) \/ StartReadySession(s) \/ WaitForDomain(s) \/
|
||||
RestartWaitingDomain(s) \/ AdvanceWaitingSession(s) \/
|
||||
RejectConfigurationMismatch(s) \/
|
||||
RegisterSession(s) \/ DisconnectSession(s))
|
||||
RegisterSession(s))
|
||||
\/ (\E d \in Domains :
|
||||
DomainServiceProgress(d) \/ FailDomain(d))
|
||||
\/ (\E d \in Domains :
|
||||
|
|
@ -1996,14 +2125,23 @@ Next ==
|
|||
\/ (\E r \in Requests :
|
||||
ReceiveEscalation(r) \/ RequestProgress(r))
|
||||
|
||||
Next ==
|
||||
\/ /\ BaseNext
|
||||
/\ UNCHANGED terminalVars
|
||||
\/ (\E s \in Sessions : SessionTerminalProgress(s))
|
||||
|
||||
\* 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))
|
||||
/\ \A d \in Domains :
|
||||
WF_vars(DomainServiceProgress(d) /\ UNCHANGED terminalVars)
|
||||
/\ \A s \in Sessions :
|
||||
WF_vars(SessionProgress(s) /\ UNCHANGED terminalVars)
|
||||
/\ \A s \in Sessions : WF_vars(SessionTerminalProgress(s))
|
||||
/\ \A r \in Requests :
|
||||
WF_vars(RequestProgress(r) /\ UNCHANGED terminalVars)
|
||||
|
||||
(***************************************************************************
|
||||
Safety properties
|
||||
|
|
@ -2044,6 +2182,27 @@ TypeOK ==
|
|||
/\ preparedLowerLeased \in [Domains -> BOOLEAN]
|
||||
/\ helperProc \in [Domains -> HelperProcStates]
|
||||
/\ pathMismatch \in [Domains -> BOOLEAN]
|
||||
/\ sessionTerminalState \in [Sessions -> SessionTerminalStates]
|
||||
/\ sessionPtyOpen \in [Sessions -> BOOLEAN]
|
||||
/\ sessionExecPresent \in [Sessions -> BOOLEAN]
|
||||
/\ sessionGuestKnown \in [Sessions -> BOOLEAN]
|
||||
|
||||
SessionTerminalPhysicalConsistency ==
|
||||
\A s \in Sessions :
|
||||
/\ (sessionTerminalState[s] = "Clean" =>
|
||||
/\ ~sessionPtyOpen[s]
|
||||
/\ ~sessionExecPresent[s]
|
||||
/\ ~sessionGuestKnown[s])
|
||||
/\ (sessionTerminalState[s] = "Intent" =>
|
||||
/\ sessionPtyOpen[s]
|
||||
/\ sessionExecPresent[s]
|
||||
/\ ~sessionGuestKnown[s])
|
||||
/\ (sessionTerminalState[s] = "Running" =>
|
||||
/\ sessionPtyOpen[s]
|
||||
/\ sessionExecPresent[s]
|
||||
/\ sessionGuestKnown[s])
|
||||
/\ (sessionPtyOpen[s] => sessionTerminalState[s] # "Clean")
|
||||
/\ (sessionExecPresent[s] => sessionTerminalState[s] # "Clean")
|
||||
|
||||
ConfigurationConfinement ==
|
||||
\A d \in Domains : domainPhase[d] # "Absent" => ConfigSafe[d]
|
||||
|
|
@ -2353,6 +2512,7 @@ NetworkReadinessBoundToSandbox ==
|
|||
|
||||
Safety ==
|
||||
/\ TypeOK
|
||||
/\ SessionTerminalPhysicalConsistency
|
||||
/\ ConfigurationConfinement
|
||||
/\ SandboxNamespaceIsolation
|
||||
/\ OrderedNetworkStartup
|
||||
|
|
@ -2429,4 +2589,15 @@ FailedDomainEventuallyRecovers ==
|
|||
\/ domainPhase[d] = "Absent"
|
||||
\/ <>[](hostCoordinatorProc[d] = "Stopped")
|
||||
|
||||
PreIdentityExitEventuallyCleansAfterRuntimeAbsence ==
|
||||
\A s \in Sessions :
|
||||
/\ sessionPhase[s] = "Closed"
|
||||
/\ sessionTerminalState[s] = "ReleaseIntent"
|
||||
/\ ~sessionGuestKnown[s]
|
||||
/\ ~sessionPtyOpen[s]
|
||||
/\ ~sessionExecPresent[s]
|
||||
/\ RuntimeAbsentForTerminal(Dom(s))
|
||||
~> \/ sessionTerminalState[s] = "Clean"
|
||||
\/ <>[](~HostCoordinatorAlive(Dom(s)))
|
||||
|
||||
=============================================================================
|
||||
|
|
|
|||
Loading…
Reference in a new issue