From tla-claude-code
TLA+ formal verification — verify concurrency, race conditions, crash recovery, optimistic UI, and UX flows. Works from design docs or existing code.
How this skill is triggered — by the user, by Claude, or both
Slash command
/tla-claude-code:tlaThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Formalize concurrency guarantees into a TLA+ spec, verify with the TLC model checker, then either implement new code or validate existing code.
references/adversarial-review.mdreferences/backend-worker-pool.mdreferences/communication-style.mdreferences/community-specs.mdreferences/community-specs/Bakery/Bakery.tlareferences/community-specs/CheckpointCoordination/CheckpointCoordination.tlareferences/community-specs/DiningPhilosophers/DiningPhilosophers.tlareferences/community-specs/EWD840/EWD840.tlareferences/community-specs/EWD840/SyncTerminationDetection.tlareferences/community-specs/KeyValueStore/KeyValueStore.tlareferences/community-specs/LamportMutex/LamportMutex.tlareferences/community-specs/ReadersWriters/ReadersWriters.tlareferences/community-specs/SOURCE.mdreferences/community-specs/SimpleAllocator/SimpleAllocator.tlareferences/community-specs/SingleLaneBridge/SingleLaneBridge.tlareferences/community-specs/transaction_commit/TCommit.tlareferences/community-specs/transaction_commit/TwoPhase.tlareferences/examples/backend_worker_pool.pyreferences/examples/frontend_optimistic_ui.tsxreferences/examples/ux_checkout_flow.tsxFormalize concurrency guarantees into a TLA+ spec, verify with the TLC model checker, then either implement new code or validate existing code.
Path A (design-first): Design doc → Extract → Spec → Align → Model-Check → Implement. A counterexample means the design has a flaw.
Path B (code-first): Existing code → Reverse-Extract → Spec → Align → Model-Check → Validate/Fix. A counterexample means the code has a bug.
Both paths converge at the Modeling Brief and share Phases 2–4. One upfront prompt, then no interruptions until after verification. See README.md for the full workflow diagram.
On invocation, use a single AskUserQuestion with two questions. This is the only prompt before work begins.
Auto-detect hardware (never prompt — detect via sysctl or /proc/cpuinfo and save to memory on first run):
# macOS
cores=$(sysctl -n hw.ncpu); ram_bytes=$(sysctl -n hw.memsize); cpu=$(sysctl -n machdep.cpu.brand_string)
# Linux
cores=$(nproc); ram_bytes=$(grep MemTotal /proc/meminfo | awk '{print $2 * 1024}'); cpu=$(grep "model name" /proc/cpuinfo | head -1 | cut -d: -f2)
Question 1: "What are we working with?"
| Option | Description |
|---|---|
| I have a design doc | Path A — provide the path or paste the relevant section |
| I have existing code | Path B — provide the file path(s) with the concurrency logic |
| I have a UX flow to analyze | Path A variant — describe the screens/steps in the flow |
| I have a concern but no doc or code yet | Path A — describe what you're building and what could go wrong |
If the user selects "UX flow" and the description is ambiguous (could be screen flow OR component state), ask one clarifying question: "Is this about the order of screens in a flow, or about how components react to each other's state?" This determines which sub-pattern applies (see UX sub-patterns below).
Question 2: "How thorough should the analysis be?"
| Preset | What happens | Prompts remaining |
|---|---|---|
| Quick | 1 refinement cycle. Safety check only. No adversarial review. Results delivered as a report — no implementation. | 0 (report delivered, done) |
| Standard (Recommended) | Up to 3 cycles. Safety first, then asks whether to run liveness. No adversarial review. Asks docs-or-implement at the end. | 1–2 (liveness decision + docs/implement) |
| Thorough | Up to 5 cycles. Safety + liveness (no Stage 2 prompt — runs automatically). Adversarial review. Asks docs-or-implement at the end. | 1 (docs/implement only) |
After the user answers, proceed directly to Phase 1. No more prompts until after Phase 4.
Behavior by preset:
UX work splits into two sub-patterns with very different workflows:
| Sub-pattern | Trigger phrases | Has concurrency? | Workflow |
|---|---|---|---|
| Screen Flow | "simplify checkout", "too many steps", "reduce screens", "onboarding funnel" | No — deterministic navigation | Fast-path (see below) |
| Component State | "button updates after X", "form validates when Y", "modal blocks until Z", "enable after async" | Yes — async callbacks, render timing, interleaving | Normal concurrency workflow |
Screen Flow fast-path:
CHECK_DEADLOCK FALSE to the MC config automatically — terminal states (done, abandoned) have no enabled actions, which TLC reports as deadlock by defaultNotDone invariant trick directlyComponent State routes to the normal workflow. These have real concurrency: async callbacks interleaving with user actions, React render batching, state dependencies between components. They need safety invariants at minimum, possibly liveness ("button eventually enables after calendar select").
Path A (design-first):
Path B (code-first):
Argument $ARGUMENTS can be:
path/to/DESIGN.md (Path A)src/workers/pool.py (Path B)worker-pool, cache-invalidation, optimistic-updatesWorkerPool, OptimisticUI"can two users overwrite each other's edits?"# Option 1: TLA+ tools JAR (minimal)
# Download tla2tools.jar from https://github.com/tlaplus/tlaplus/releases
mkdir -p ~/tla && curl -L -o ~/tla/tla2tools.jar \
https://github.com/tlaplus/tlaplus/releases/latest/download/tla2tools.jar
# Option 2: VS Code extension (recommended for editing)
# Install "TLA+" extension by Jack Vanlightly — syntax highlighting + TLC integration
# Option 3: TLA+ Toolbox (full IDE)
# Download from https://github.com/tlaplus/tlaplus/releases
# Basic invocation
java -XX:+UseParallelGC -jar ~/tla/tla2tools.jar \
-config MC_YourSpec.cfg -workers auto -nowarning MC_YourSpec.tla
# With a verify.sh wrapper (recommended per project)
#!/bin/bash
SPEC=${1:-"all"}
TLA_JAR="path/to/tla2tools.jar"
JAVA_OPTS="-XX:+UseParallelGC"
java $JAVA_OPTS -jar "$TLA_JAR" -config "MC_${SPEC}.cfg" -workers auto -nowarning "MC_${SPEC}.tla"
TLC is CPU- and memory-intensive. Any modern laptop handles small models (2 actors, 3 resources) in seconds — this catches most design flaws. For hardware profiles, scaling guidelines, JVM tuning, and CI pipeline advice, see ${CLAUDE_SKILL_DIR}/references/system-requirements.md.
Use this when you have a design doc or feature spec but no code yet.
Parse the design doc and identify concurrency-relevant content.
| Question | Look for in design docs |
|---|---|
| Mutable state | DB rows, cache keys, in-memory variables, queues, UI state, localStorage |
| Concurrent actors | Worker threads, server processes, browser tabs, websocket connections, cron jobs, user sessions |
| Synchronization | DB locks, atomic operations, optimistic locking, version vectors, mutexes, channels |
| Failure modes | Crash recovery, network partition, rejected writes, stale reads, timeout, tab close |
Scan the pattern catalog (below) and identify which patterns apply. Most real systems combine 1-3 patterns.
Search your project for existing TLA+ specs:
find . -name "*.tla" -not -path "*/node_modules/*" | head -20
Build an inventory table:
| Spec | Location | Vars | Actions | Models |
|---|---|---|---|---|
| SpecName | path/to/Spec.tla | N | N | What it models |
If an existing spec covers the concern, extend it rather than creating a new one.
Write 2-3 paragraphs naming:
→ Proceed to Phase 2: Spec
Use this when you have a working implementation and want to formally verify it.
The goal is the same as 1A — produce a modeling brief — but the source material is code instead of a design doc. This is harder because code conflates what it does with how it does it. Your job is to extract the what and ignore the how.
For non-trivial codebases, spawn three agents in parallel to scan different aspects of the code simultaneously. Each agent returns structured findings that merge into the modeling brief.
All agents — detect language first: Before grepping, detect the project's languages from file extensions. Only grep for patterns matching detected languages. SQL patterns always apply.
find . -type f \( -name "*.py" -o -name "*.ts" -o -name "*.tsx" -o -name "*.go" -o -name "*.rs" -o -name "*.java" -o -name "*.cs" -o -name "*.rb" \) -not -path "*/node_modules/*" | sed 's/.*\.//' | sort -u
Grep patterns by language:
| Language | Agent 1: Shared state | Agent 2: Concurrency primitives | Agent 3: Error/crash paths |
|---|---|---|---|
| Python | global, threading.Lock, asyncio.Lock | asyncio.gather, queue, Pool | try/except, atexit, finally |
| TS/JS | useState, useRef, SharedWorker | Promise.all, BroadcastChannel | try/catch, finally |
| Go | sync.Map, chan | sync.Mutex, sync.WaitGroup, go func | recover(), defer |
| Java | ConcurrentHashMap, AtomicReference | synchronized, ReentrantLock, ExecutorService | try/catch, finally, @PreDestroy |
| Rust | Arc<Mutex>, static mut | tokio::join, mpsc::channel, RwLock | Result<, Drop, ? near mutations |
| C# | ConcurrentDictionary, Interlocked | Task.WhenAll, lock, SemaphoreSlim | try/catch, finally, Dispose |
| SQL (always) | UPDATE, INSERT, SELECT FOR UPDATE | BEGIN, COMMIT, ROLLBACK | SAVEPOINT |
Each agent returns a list of: {file, line, pattern_type, description}. Merge the results and use them as input to 1B.1–1B.4 below.
For small codebases (< 10 files involved), skip the agents and scan inline.
Catalog every piece of mutable state involved in the concurrent behavior (DB rows, cache keys, in-memory variables, queues, React state/refs). For each, note who writes it and who reads it.
Each code path that atomically modifies state becomes a TLA+ action: functions with DB writes, transaction boundaries, event handlers (onMessage, onSuccess, useEffect), cron ticks, error/crash paths. Watch for hidden non-atomicity: two DB writes without a transaction are two separate actions, even if they look like one function.
Look for implicit assumptions: if status == "claimed": process(job) implies jobs are only processed in claimed state. unique_together implies at most one holder. if (version !== expected) throw implies conditional writes. Also look for invariants the code should enforce but doesn't.
Scan for: check-then-act without lock, shared state without synchronization, try/catch that swallows errors and leaves state dirty, optimistic updates without rollback, fire-and-forget async. Each maps to a spec property to verify.
Same output as 1A.4 — the brief should be indistinguishable regardless of whether it came from a design doc or from code:
→ Proceed to Phase 2: Spec
Before writing the spec, spawn a background agent to read the relevant reference material and return a summary. This keeps the reference content out of the main context window.
Agent prompt: "Read ${CLAUDE_SKILL_DIR}/references/pattern-catalog.md and ${CLAUDE_SKILL_DIR}/references/<matched-example>.md. Also read ${CLAUDE_SKILL_DIR}/references/community-specs/<MatchedSpec>/<MatchedSpec>.tla if a community spec matches. Return: (1) the translation table entries that apply, (2) the abstraction guide entries that apply, (3) the key structural patterns from the worked example or community spec (Init, actions, invariants, fairness choices)."
Pick the worked example based on the matched pattern:
backend-worker-pool.mdfrontend-optimistic-ui.mdux-state-reduction.mdUse the agent's summary as a template while writing the spec. The main context never loads the full reference files.
Translate the modeling brief into TLA+. Properties first (TDD for specs).
ActionName(param) ==
/\ guard_predicate \* source state
/\ stateVar' = new_value \* target state
/\ UNCHANGED <<all, other, vars>> \* everything else
After writing any action, count: primed_count + unchanged_count = total_variable_count. This is the #1 source of TLC errors — a missing variable in UNCHANGED silently allows arbitrary state changes. Use tuple aliases (e.g., uiVars, serverVars) for brevity.
This is the most important technique in the workflow. Write the property that should hold before writing the action that makes it hold:
If a new property passes immediately, it's either too weak or already implied. Investigate before moving on.
The MC (model-checking) module is a thin wrapper that EXTENDS the main spec, declares small constants, and defines state constraints to keep the state space manageable.
| Component | Small model | Medium model |
|---|---|---|
| Workers/Actors/Users | 1-2 | 3 |
| Resources/Items | 2-3 | 4-5 |
| Time bound | 10-15 ticks | 20-25 ticks |
| Target runtime | <60s | <5min |
Start with the smallest model. Only increase if you suspect the small model hides bugs. TLA+ is about finding design flaws, not proving correctness at production scale — 2 users finding a bug means 200 users will too.
Screen Flow specs: Always add CHECK_DEADLOCK FALSE to the MC config. Terminal states (done, abandoned) have no enabled actions — TLC reports these as deadlock by default, which is a false positive. The deadlock is intentional: the user finished.
Write all spec files (.tla, .cfg) to a temp directory during the workflow:
mkdir -p /tmp/tla-$(date +%s)
At the end (Phase 5 transition), ask the user where to save them permanently. Suggest options based on what exists in their project:
feature/specs/ — next to the code they verifyspecs/ or tla/ at project rootDo not write to the project directory until the user confirms a location.
| Error | Cause | Fix |
|---|---|---|
TLC threw an unexpected exception | Syntax error in TLA+ | Check operator precedence; /\ binds tighter than you think |
Attempted to enumerate SUBSET | Unbounded set in \E x \in SUBSET S | Constrain the set or use a different formulation |
Variable X has no value in state | Missing from Init | Add initialization for every declared variable |
Deadlock reached | No action enabled in some state | Either add a Stutter action or verify the deadlock is expected |
State space too large | Too many actors or resources | Reduce MC constants; add a StateConstraint |
| Runs forever | State explosion from counters or sequences | Bound all numeric values and sequence lengths in MC |
Phases 2, 3, and 4 form a bounded feedback loop. The iteration budget was set by the thoroughness preset chosen in Getting Started:
| Preset | Cycles | Behavior |
|---|---|---|
| Quick | 1 pass | Spec → Align → Model-Check → done. No going back. Report all findings as a single deliverable. |
| Standard | Up to 3 cycles | Back-to-Spec allowed twice. After cycle 3, remaining issues reported as known limitations. |
| Thorough | Up to 5 cycles | After cycle 5, hard stop. If spec is still unstable, recommend splitting into smaller specs. |
Each phase has an exit checklist. The spec cannot advance until the gate passes. This prevents sloppy loops.
Phase 2 (Spec) exit gate:
Init assignmentprimed + UNCHANGED = total)StateConstraintPhase 3 (Align) exit gate:
Phase 4 (Model-Check) exit gate:
Each cycle: Spec → Align → Model-Check. If Align finds GAPs or Model-Check finds a spec bug, go back to Spec (costs 1 cycle). Real findings are reported and the loop continues. When the budget is exhausted, deliver a report with: verified properties, known findings, known limitations, and recommendation to split spec or increase budget if issues remain.
Key rule: Going back to Phase 2 costs one cycle from the budget. This prevents infinite refinement — each spec revision must be deliberate, not a "let me just tweak this."
Before spending a cycle to go back to Phase 2, verify the counterexample is actually a spec bug:
If all three are "yes," the counterexample is a real finding — report it, don't spend a cycle revising.
Verify the spec faithfully captures the source material. This phase typically takes 2-3 iterations.
The alignment process is the same for both paths — the only difference is what you're aligning against.
| Path A (design-first) | Path B (code-first) | |
|---|---|---|
| Align against | Design doc claims | Code behavior + implicit assumptions |
| "Gap" means | Spec is missing a design guarantee | Spec doesn't cover a code path |
| "Over-model" means | Design is under-specified | Spec models behavior the code doesn't have (flag as potential missing feature or dead code) |
Path A: For each design guarantee/claim, identify the corresponding TLA+ property. If a claim has no spec counterpart, the spec is incomplete.
Path B: For each code function that modifies shared state, identify the corresponding TLA+ action. For each assertion/constraint in the code, identify the corresponding invariant. If a code path has no spec counterpart, the spec is incomplete.
Path A: For each TLA+ action, identify the design doc section it models. Extra actions mean the spec is over-modeling.
Path B: For each TLA+ action, identify the code function it models. Extra actions might reveal defensive behavior the code is missing (good — the spec found a gap) or over-modeling (trim it).
Are the abstraction choices compatible with the failure modes?
Path A: If the design says "retry with backoff" but the spec omits retry counting, the spec may miss a starvation bug the design intended to prevent.
Path B: If the code has error handling for a failure mode but the spec doesn't model that failure, the spec can't verify the error handling is correct. Add the failure mode to the spec.
Build a table mapping each source claim (design doc) or code behavior (code path) to a spec property/action. Mark each as OK, GAP (missing from spec), SUSPECT (possible bug), or FLAG (needs human decision). Iterate until no GAPs remain.
The verification profile and check type are determined by the thoroughness preset from Getting Started:
| Preset | Hardware profile | Model size | Checks |
|---|---|---|---|
| Quick | Fast (4 workers, 4GB) | 2 actors, 2-3 resources | Safety only |
| Standard | Optimal (auto workers, 16GB) | 3 actors, 4-5 resources | Safety, then decide on liveness |
| Thorough | Max (auto workers, 50%+ RAM) | 4+ actors, 6+ resources | Safety + liveness (automatic) |
TLC runs two fundamentally different kinds of checks. They have different costs, different configs, and should be run separately.
Safety — "bad things never happen." Checked at every reachable state. If any state violates an invariant, TLC stops with the trace that got there. Fast — TLC evaluates invariants as it explores each state.
Liveness — "good things eventually happen." Checked over infinite behaviors (paths through the full state graph). TLC must build the complete state graph, then find strongly connected components (cycles) and verify no cycle violates the property. Expensive — same state space takes much longer.
| Safety | Liveness | |
|---|---|---|
| Properties | Invariants (INVARIANT) | Temporal (PROPERTY: <>, ~>, []<>) |
| How checked | Per-state | Over full state graph (SCC analysis) |
| Speed | Fast (evaluates inline) | Slow (needs complete graph + cycle detection) |
| Fairness needed? | No | Yes — without WF/SF, liveness is trivially violated (system can stutter forever) |
| Spec to use | Spec (no fairness) | FairSpec (with fairness assumptions) |
| Constraint type | CONSTRAINT (prunes states — fast, safe for invariants) | ACTION_CONSTRAINT (disables actions at bound — slower, safe for temporal properties) |
Why split configs: CONSTRAINT truncates traces, which can hide liveness counterexamples. ACTION_CONSTRAINT lets the system quiesce naturally at the bound without truncation. Always use separate MC configs for safety and liveness runs.
In plain language: Safety run answers "can anything go wrong?" Liveness run answers "does the system eventually make progress?" Run safety first (seconds to minutes). Only run liveness after safety passes (minutes to hours).
Quick: Run safety only. Display the pre-flight estimate, run TLC, report results. No prompts.
Standard: Run safety first. After it passes, compute the liveness estimate from the exact state count (see pre-flight estimate below). Then use AskUserQuestion — this is the only mid-workflow prompt:
Question: "Safety passed: {S:,} distinct states in {safety_time}. Liveness estimate: ~{liveness_estimate} on your {cores}-core {arch} ({B} branches). Proceed?"
| Option | What happens |
|---|---|
| Run liveness (~{liveness_estimate}) | Proceed with liveness config. |
| Reduce model first | Lower MaxTick, fewer actors, or split the spec. Re-estimate after. |
| Skip liveness | Safety is enough. Proceed to Phase 5. |
If liveness estimate > 20 min: suggest reducing. If > 60 min: strongly recommend reducing before running.
Thorough: Run safety, then run liveness automatically — no prompt. Both use separate configs (CONSTRAINT for safety, ACTION_CONSTRAINT for liveness).
When the user selects Optimal or Max, use a two-stage approach:
This way the user gets instant feedback from Fast while deeper verification runs in the background. If Fast already finds counterexamples, the user can start fixing without waiting for Optimal/Max to finish.
Background agent prompt: "Run TLC on <spec>.tla with MC constants: <larger model>. JVM flags: <profile flags>. Report: (1) pass or fail with counterexample traces, (2) distinct states explored, (3) wall-clock time, (4) any violations not present in the Fast run."
If Fast and Optimal/Max disagree (Fast passes, larger model fails), the larger model found a bug that only manifests with more actors — flag this to the user as a significant finding.
Apply the selected profile by adjusting the MC module constants and JVM flags:
# Fast — small model, quick iteration
java -Xmx4g -XX:+UseParallelGC -jar ~/tla/tla2tools.jar \
-config MC.cfg -workers 4 -nowarning MC.tla
# Optimal — medium model, full cores
java -Xmx16g -XX:+UseParallelGC -jar ~/tla/tla2tools.jar \
-config MC.cfg -workers auto -nowarning MC.tla
# Max — large model, maximum resources
java -Xmx<50% of RAM>g -XX:+UseG1GC -jar ~/tla/tla2tools.jar \
-config MC.cfg -workers auto -nowarning MC.tla
Adjust the MC module's constants to match the profile (e.g., MC_Workers == {w1, w2} for Fast, {w1, w2, w3} for Optimal). Report results with the profile used so the user can decide whether to step up.
Always estimate runtime before running TLC. Read ${CLAUDE_SKILL_DIR}/references/runtime-estimate.md for the full estimation procedure (hardware detection, safety estimate from MC constants, liveness estimate from state count, calibration after run).
Always display the estimate before running:
Safety estimate: ~15s on your 10-core Apple M1 Pro (16GB)
Model: 2 workers, 3 jobs, 7 state variables
Running...
Read the state trace bottom-up:
Sanity-check: temporarily remove a guard from an action. TLC should now find a violation. If it still passes, the property may be trivially true — the model is too constrained or the invariant too weak.
One action or property per change. Verify. Proceed. With small models TLC runs in <60s. If it fails, the bug is in the last change.
When Phase 4 passes, spawn a background adversarial review agent. Skip for Quick preset and Screen Flow specs. Read ${CLAUDE_SKILL_DIR}/references/adversarial-review.md for the full agent prompt and result handling.
After Phase 4 passes (and adversarial review completes, if run), use AskUserQuestion before proceeding.
Question: "The spec is verified. What next?"
| Option | What happens |
|---|---|
| Update docs, stop for review | Write or update the design doc (DESIGN.md) to reflect verified findings. Save the .tla spec alongside it. Stop here so the user can review before any code is written. |
| Implement from the spec | Proceed to Phase 5 — write new code (Path A) or fix existing code (Path B) based on the verified spec. |
Default to Update docs, stop for review if unsure. Writing code from an unreviewed spec is risky — the user may disagree with modeling choices that affect implementation.
.tla and MC files alongside the design doc/tla when ready to implement.Proceed to Phase 5A (new code) or 5B (fix existing code) below.
The spec passed. Now write code from it.
The spec either passed or found bugs. Now act on the results.
Deliver a confidence report (scope, state count, invariants verified). Generate test cases from the spec's actions — especially failure/recovery paths. Keep the .tla file alongside the code as living documentation.
For each counterexample: (1) map the TLC trace to code functions, (2) write a failing test that reproduces it, (3) fix the code (the spec's guard tells you what the fix is), (4) re-verify. See ${CLAUDE_SKILL_DIR}/references/examples/ for before/after code showing this process.
Full reference with all 15 patterns, design-to-spec translation table, and abstraction guide: ${CLAUDE_SKILL_DIR}/references/pattern-catalog.md
Community TLA+ specs mapped to each pattern (with links to source): ${CLAUDE_SKILL_DIR}/references/community-specs.md
During Phase 1 (Extract), scan the design doc or code for these phrases to identify which patterns apply:
| Domain | Patterns | Trigger Phrases |
|---|---|---|
| Backend | Transaction Commit, Resource Allocator, Failure Detector, Blocking Queue, Termination Detection, Checkpoint Coordination | "lock row", "pool dispatch", "heartbeat", "bounded queue", "all done", "crash recovery" |
| Both | Readers-Writers, Mutual Exclusion, Lifecycle State Machine, Cache Invalidation | "concurrent read/write", "only one X can", "must X before Y", "stale read" |
| Frontend | Optimistic Update, Multi-Tab Sync, Offline-First Sync, Real-Time Collaboration | "apply locally", "consistent across tabs", "sync on reconnect", "concurrent edits" |
| UX | Screen Flow | "checkout flow", "too many screens", "simplify the funnel" (deterministic — fast-path) |
| UX | Component State | "button updates after X", "enable when Y changes" (has concurrency — normal workflow) |
| Design/Code Pattern | TLA+ Construct |
|---|---|
| "Only one X can..." | Safety: Cardinality({x \in S : state[x] = "active"}) <= 1 |
| "Eventually every X gets Y" | Liveness: \A x \in X : <>(state[x] = "Y") |
| "If X crashes, Y recovers" | Crash action + recovery action, WF_vars(Recover) |
| "Apply locally, confirm later" | Separate localState / serverState; rollback on reject |
See ${CLAUDE_SKILL_DIR}/references/pattern-catalog.md for the complete translation table (14 entries) and abstraction guide.
Not every concurrency concern needs formal verification. Skip TLA+ when:
Use TLA+ when the cost of a concurrency bug is high (data corruption, lost writes, security holes) or when the team can't agree on whether the design is correct.
Reference files are loaded on demand — read the relevant file when the context calls for it, not all at once.
Read during Phase 1 (Extract) — pattern matching:
${CLAUDE_SKILL_DIR}/references/pattern-catalog.md — Read when matching the user's concern against patterns. Contains the full 15-pattern catalog, design-to-spec translation table, abstraction guide, and production lessons.${CLAUDE_SKILL_DIR}/references/community-specs.md — Read when the user's pattern has a community spec. Contains descriptions and real-world mappings. The actual .tla files are in ${CLAUDE_SKILL_DIR}/references/community-specs/<SpecName>/.Read during Phase 2 (Spec) — writing TLA+: Pick the worked example that matches the user's domain. Each has a full spec, MC module, and TLC walkthrough to use as a template:
${CLAUDE_SKILL_DIR}/references/backend-worker-pool.md — Read when the spec involves job queues, worker pools, crash recovery, DB locks, or bounded concurrency.${CLAUDE_SKILL_DIR}/references/frontend-optimistic-ui.md — Read when the spec involves optimistic updates, websocket sync, version conflicts, or client-server state divergence.${CLAUDE_SKILL_DIR}/references/ux-state-reduction.md — Read when the spec involves multi-step UX flows, checkout funnels, onboarding, or "how many screens does the user need?"Read during Phase 2 (Spec) — referencing community specs:
When the matched pattern has a community spec, read the .tla file from ${CLAUDE_SKILL_DIR}/references/community-specs/<SpecName>/. See ${CLAUDE_SKILL_DIR}/references/community-specs.md for the full index mapping patterns to specs. Source: tlaplus/examples (MIT License).
Read during Phase 5 (Implement/Fix) — companion code: Each worked example has a before/after code file showing the buggy version and the TLA+-informed fix. Use as a template when writing implementation code:
${CLAUDE_SKILL_DIR}/references/examples/backend_worker_pool.py — Python (asyncpg). Before: no row lock, no orphan recovery. After: SELECT FOR UPDATE, recovery cron. Includes test cases from TLC traces.${CLAUDE_SKILL_DIR}/references/examples/frontend_optimistic_ui.tsx — TypeScript (React). Before: no version check, ws clobbers optimistic state. After: useRef guard, baseVersion, deferred ws. Includes test scenarios.${CLAUDE_SKILL_DIR}/references/examples/ux_checkout_flow.tsx — TypeScript (React). Before: 11-screen flow. After: 7-screen flow with analytics validation against spec predictions.Read during Phase 4 (Model-Check):
${CLAUDE_SKILL_DIR}/references/system-requirements.md — Hardware tables, state space estimates, JVM tuning.${CLAUDE_SKILL_DIR}/references/runtime-estimate.md — Pre-flight estimation procedure, per-architecture throughput rates, calibration.${CLAUDE_SKILL_DIR}/references/adversarial-review.md — Agent prompt and result handling for Phase 4.5.Read when presenting results:
${CLAUDE_SKILL_DIR}/references/communication-style.md — Impact-first template, severity labels, examples.Present all findings impact-first, TLA+ detail second. Read ${CLAUDE_SKILL_DIR}/references/communication-style.md for the full template, severity labels, and examples. Key rule: "Liveness violation" means nothing to users. "Users get stuck in a loading state that never resolves" does.
After each phase, report: path (A/B), target, phase, matched patterns, spec name, state vars, actions, safety/liveness properties, alignment status, verification result (states explored, time, pass/fail with counterexample traces if any), and files changed.
npx claudepluginhub brianwu02/tla-claude-code --plugin tla-claude-codeGuides TLA+ formal verification of concurrent/distributed designs using PlusCal and TLC, complementing PBT for implementation. Use for protocol correctness and state risks.
Writes and refines TLA+ specs (.tla) and TLC configs (.cfg) from natural-language designs; runs model checking; summarizes results, counterexamples, and assumptions. For protocol/state machine validation.
Provides TLA+ templates, syntax guidance, type invariants, and best practices for specifying distributed systems and concurrent algorithms. Useful for formal design and verification with TLC.