tlaplus-spec-generator — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited tlaplus-spec-generator (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Automatically generate TLA+ specifications from program implementations for formal verification of distributed systems.
This skill transforms imperative programs (C/C++, Python) into declarative TLA+ specifications. It analyzes program structure to identify state variables, actions, and system behavior, then generates well-structured TLA+ modules suitable for model checking with TLC.
Generate TLA+ specification from source files:
# Single file
python3 scripts/generate_spec.py program.py -o Spec.tla
# Multiple files
python3 scripts/generate_spec.py server.py client.py protocol.py -o Protocol.tla
# With module name
python3 scripts/generate_spec.py distributed_system.c -o System.tla --module-name DistributedSystemThe generator automatically:
For distributed systems, specify the number of processes:
python3 scripts/generate_spec.py consensus.py -o Consensus.tla --processes 3This creates a constant N in the TLA+ spec representing the number of processes/nodes.
The generator produces two files:
1. Spec.tla - Complete TLA+ specification:
---- MODULE Spec ----
EXTENDS Naturals, Sequences, FiniteSets, TLC
CONSTANTS N \* Number of processes
VARIABLES
state,
messages,
committed
vars == <<state, messages, committed>>
TypeOK ==
/\ state \in [1..N -> {"Init", "Working", "Done"}]
/\ messages \in SUBSET Messages
/\ committed \in SUBSET Operations
Init ==
/\ state = [p \in 1..N |-> "Init"]
/\ messages = {}
/\ committed = {}
SendMessage(p, msg) ==
/\ state[p] = "Working"
/\ messages' = messages \cup {msg}
/\ UNCHANGED <<state, committed>>
Next ==
\/ \E p \in 1..N, msg \in Messages : SendMessage(p, msg)
Spec == Init /\ [][Next]_vars
====2. Spec_mapping.txt - Explanation of program-to-TLA+ mapping:
The generated spec is a starting point. Refine it by:
Create a TLC configuration file (Spec.cfg):
CONSTANTS
N = 3
SPECIFICATION Spec
INVARIANT TypeOKRun TLC model checker:
tlc Spec.tla -config Spec.cfgControl the level of abstraction:
# Low abstraction (more detail, larger state space)
python3 scripts/generate_spec.py program.py -o Spec.tla --abstraction low
# Medium abstraction (balanced, recommended)
python3 scripts/generate_spec.py program.py -o Spec.tla --abstraction medium
# High abstraction (minimal states, protocol-level)
python3 scripts/generate_spec.py program.py -o Spec.tla --abstraction highMedium abstraction (default):
Scenario: Implementing Raft or Paxos consensus algorithm.
Approach:
Scenario: Distributed system with processes communicating via messages.
Approach:
Scenario: Primary-backup or multi-master replication.
Approach:
Scenario: Implementing leader election algorithm.
Approach:
Extract only relevant functions:
python3 scripts/generate_spec.py system.py -o Spec.tla \
--focus-functions send_message receive_message commit_transactionExplicitly specify state variables:
python3 scripts/generate_spec.py system.py -o Spec.tla \
--track-vars state messages committed_ops leader_idGenerated specs need refinement. Common refinements:
1. Complete action preconditions:
\* Generated (incomplete)
SendMessage(p, msg) ==
/\ messages' = messages \cup {msg}
\* Refined (with precondition)
SendMessage(p, msg) ==
/\ state[p] = "Active" \* Precondition
/\ msg \notin messages \* No duplicates
/\ messages' = messages \cup {msg}
/\ UNCHANGED <<state, committed>>2. Add invariants:
\* Safety properties
SafetyInvariant ==
/\ \A p \in Procs : state[p] \in ValidStates
/\ Cardinality({p \in Procs : state[p] = "Leader"}) <= 1
\* Add to spec
INVARIANT TypeOK
INVARIANT SafetyInvariant3. Add liveness properties:
\* Eventually reach consensus
PROPERTY <>[](\A p \in Procs : state[p] = "Committed")
\* Every request is eventually processed
PROPERTY \A req \in Requests : [](Submitted(req) => <>Processed(req))4. Add fairness:
\* Weak fairness: continuously enabled actions eventually happen
Spec == Init /\ [][Next]_vars /\ WF_vars(ReceiveMessage)
\* Strong fairness: infinitely often enabled actions eventually happen
Spec == Init /\ [][Next]_vars /\ SF_vars(ElectLeader)SYMMETRY Permutations(Procs) to reduce state spaceState explosion: TLC runs out of memory or takes too long.
Deadlock detected: TLC finds states with no enabled actions.
Invariant violated: TLC finds counterexample.
Spec too abstract: Properties are trivially true.
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.