Gratos_Sandbox

by 623f9b12 · generation 1 · every generation passed the checker when published.

Ephemeral-environment (sandbox) lifecycle: environments are minted anonymous or owned; a background sweep deletes only aged anonymous ones, while owned environments persist until their owner deletes them. Checks that anonymous and owned sets stay disjoint and that no environment ever minted as owned is removed by the sweep.

Raw .tla Raw .cfg

Gratos_Sandbox.tla

MODULE Gratos_Sandbox

Sandbox lifecycle in gratos-multi after the ownership change.

POST /sandbox mints a sandbox: anonymous when the request carries no session (user_id NULL), owned when it does. AuthRPC.sweepSandboxes deletes only aged anonymous sandboxes (user_id IS NULL filter); owned ones persist until their owner deletes them via DELETE /sandboxes/:sid.

Checked property: OwnedNeverSwept — no sandbox that was ever owned is removed by the sweep. This is what the SQL filter must guarantee.

EXTENDS FiniteSets
CONSTANTS Ids
VARIABLES
liveAnon, anonymous sandboxes currently in the sandboxes table
liveOwned, owned sandboxes currently in the sandboxes table
ownedEver, ids that were ever minted as owned
swept ids removed by sweepSandboxes
vars ≜ ⟨liveAnon, liveOwned, ownedEver, swept
Init
liveAnon = {}
liveOwned = {}
ownedEver = {}
swept = {}

Sandbox ids are random 12-hex-char strings — modeled as never reused.

Fresh(id) ≜ id ∉ (liveAnonliveOwnedownedEverswept)
MintAnon(id) ≜
Fresh(id)
liveAnon = liveAnon ∪ {id}
UNCHANGEDliveOwned, ownedEver, swept
MintOwned(id) ≜
Fresh(id)
liveOwned = liveOwned ∪ {id}
ownedEver = ownedEver ∪ {id}
UNCHANGEDliveAnon, swept

sweepSandboxes: WHERE ... AND user_id IS NULL — anonymous rows only.

Sweep(id) ≜
idliveAnon
liveAnon = liveAnon \ {id}
swept = swept ∪ {id}
UNCHANGEDliveOwned, ownedEver

DELETE /sandboxes/:sid — owner removes an owned sandbox.

Delete(id) ≜
idliveOwned
liveOwned = liveOwned \ {id}
UNCHANGEDliveAnon, ownedEver, swept
Next
idIds :
MintAnon(id) ∨ MintOwned(id) ∨ Sweep(id) ∨ Delete(id)
SpecInit ∧ □[Next]vars
TypeOK
liveAnonIds
liveOwnedIds
ownedEverIds
sweptIds
DisjointliveAnonliveOwned = {}
OwnedNeverSweptsweptownedEver = {}

Gratos_Sandbox.cfg

SPECIFICATION Spec

Quiescence is legal: ids are modeled as never reused, so a state where every id has been minted and removed has no enabled action. That is the finite id pool running dry, not a stuck protocol.

CHECK_DEADLOCK FALSE
CONSTANTS
Ids = {s1, s2, s3}
INVARIANTS
TypeOK
Disjoint
OwnedNeverSwept

Generations

genchangesdistinct statesdepthpublishedraw
1 (latest) First publication to the hub; previously validated with Java TLC. Config now records CHECK_DEADLOCK FALSE: quiescence when the finite id pool is exhausted is legal, matching the CLI flag used in earlier Java runs. 125 7 2026-07-20 17:33:47 UTC .tla .cfg

Defend this spec

Ask an AI role-playing the spec's author to defend the design, dissertation-style. This site holds no AI keys: you grant a small revocable budget from your own tokenpony.dev balance (or any TPX provider you choose) and your browser talks to the model directly.

Loading…