nerdsane/temper/temper-openclaw
Claude Code and agent skill by nerdsane/temper
- community
Checking that the SKILL.md file is still in the repository.
Install
npx vskill@latest install nerdsane/temper/temper-openclawSKILL.md
Temper — Your Organizational Backbone
Temper is where durable state lives. When you need to decide whether to handle something locally or route it through Temper, the test is simple: does this thing have a lifecycle? If it moves through stages, if someone might ask "what's the status?", if it matters tomorrow — it belongs in Temper.
Anything that has states and transitions — proposals, tasks, sessions, content jobs, incidents, deployments — belongs in Temper. Not a markdown file. Not a JSON blob. A verified state machine that enforces legal transitions, stores event history, and survives restarts.
The mental model:
- Temper state is permanent. Create entities, fire actions, query state. This is your organizational backbone.
- UIs are ephemeral. Build one when you need to show something to a human. Serve it, DM the URL, let it die when you're done. Next time, rebuild from Temper state — the data is still there.
- Don't track state in markdown. If you're writing "Status: In Progress" in a .md file, that's a state machine pretending to be text. Make it real.
- Route through Temper when it has a lifecycle. Anything that moves through stages becomes a capability you can evolve, compose with other tools, and share across agents. A shell script is a dead end — a Temper entity is a building block that gets better over time.
Anything that moves belongs here.
Getting Temper
Prerequisites
| Dependency | Install | Why | ||
|---|---|---|---|---|
| Rust | `curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs \ | sh` | Temper is Rust | |
| Z3 | brew install z3 (macOS) / apt install libz3-dev (Linux) | L0 spec verification | ||
| Python 3 | Pre-installed on most systems | Proxy server (serve.py) |
Build
Z3 must be on the linker path or the final link fails. Set these before building:
If you see ld: library 'z3' not found — you skipped the env vars. Set them and retry.
Storage — Turso (local file, zero config)
Temper uses Turso/libSQL as its storage backend. For local use, no env vars are needed. Temper defaults to ~/.local/share/temper/agents.db and creates it on first run:
That's it. No credentials, no account, no config file.
Override the path if you want a different location (e.g. a shared workspace db):
Remote Turso (cloud, optional) requires both vars:
No Postgres to manage. No Redis to manage. Just a file.
Verify It Works
What Temper Is
A Rust state machine backend. You define entities with states, actions, guards, and effects in IOA TOML. Temper gives you:
- OData API — CRUD, bound actions (state transitions), SSE events
- Turso persistence — state survives restarts via libSQL event log; all three backends (Turso, Redis, Postgres) support hydration on restart
- Verification cascade — L0-L3 model checking at load time; illegal specs don't start
- Multi-tenant — one server, many apps, isolated by
X-Tenant-Id - OpenClaw plugin — real-time two-way connection for any OpenClaw agent (SSE → signal files → heartbeat wake)
When to Use This
- You need state that survives restarts (not a JSON file, not markdown)
- You have a workflow with defined states and transitions (proposals, content pipeline, task queue, releases)
- You want verified transitions — illegal moves return 409, not silent corruption
- You want a UI that reflects live state and lets your human interact
- Multiple agents need to share state or hand off work
1. Write a Spec
Create apps/{your-app}/specs/{entity}.ioa.toml:
Spec Reference
Actions — kind = "input" (human/dashboard-triggerable) vs kind = "internal" (agent-only). Both are callable via the OData API; the distinction is primarily for dashboard button rendering.
State variable types — only two are valid:
bool—initial = "false"orinitial = "true"counter—initial = "0"(integer, supports+=/-=/=effects and comparisons in guards)
int, string, float, and any other type will pass L0-L3 verification silently but the entity set will not register at runtime. Store text/numeric data via action params (they become entity fields automatically). Use state variables only for values that drive guards and invariants.
Guards — one expression checked before the transition fires, e.g. guard = "is_assigned && items > 0":
flag/!flag— boolean checkscount > 3,count <= limit— counter comparisons&&,||,!,=>,in [...], single-quoted strings — seedocs/predicates.md
`to` is required on every action, including self-loops. A self-loop that keeps the entity in the same state needs to = "SameState" explicitly:
Effects — effect is a list of statements applied on success, e.g. effect = ["items += 1", "is_assigned = true"]:
flag = true/flag = false/flag = params.p— set booleancount += 1/count -= 1(stops at 0) /count = params.p— counter arithmetic;params.pis action parameterpschedule('Action', 3600)— dispatch an action on this entity later; seedocs/predicates.md#effectsfor lists andspawn
Nothing is implied by an action's name: an AddItem with no effect changes only status. Old forms ("set var true", "increment var", [[integration]]) fail to load; run temper migrate-predicates <files> to convert them.
Invariants — one assert expression, proven by verification in every reachable state; use status in [...] => ... to scope it to some states. Invariants may only read status, bool and counter variables; rules about text fields belong in [[field_invariant]], which is checked on writes.
Integrations (WASM) — when your app needs external API calls (payments, email, notifications), add a kind = "wasm" entry under the action's [[action.triggers]]:
The WASM module is a Rust cdylib compiled to wasm32-unknown-unknown and uploaded via POST /api/wasm/modules/{name}. See the developer skill (.claude/skills/temper-developer.md) for the full WASM module template.
Built-in module: `http_fetch` — for simple HTTP integrations, use the pre-compiled http_fetch module instead of writing custom WASM. Configure it directly on the trigger:
The http_fetch module reads url, method, and body from the trigger's config, makes the HTTP call via the host, and returns {"status_code": "200", "body": "..."} as callback params. URL templates support {param} substitution from action params.
Terminal states — list them in [automaton] (terminal = ["Done"]); verification then checks that no action leaves them. Entities in terminal states can't move, so design them intentionally.
L0–L3 Verification
At startup, Temper verifies every spec:
- L0 — Z3 SMT: all guards satisfiable, invariants inductive, no dead states
- L1 — Model check: full state space reachability, no deadlocks
- L2 — Simulation: random action sequences, invariant holds across seeds
- L3 — Property tests: 100 random runs, bounded depth
If verification fails, the server won't start. Fix the spec first.
2. Start the Server
One step, every session:
The --observe flag auto-starts the Observe UI at the Observe UI. This is where humans approve or deny governance decisions (see Governance section below).
That's it. Temper auto-reloads your specs on startup — if you've called load-dir before, your entity types come back automatically. Your data was never gone (it's in the DB). No extra steps.
Verify it's serving your app:
First Time Only — Register Your App
The first time you run (new machine, new app), register your specs once:
Temper persists this mapping to ~/.local/share/temper/specs-registry.json. After that, every restart auto-loads — you never call this again unless you're adding a new app or changing your specs on disk.
Re-calling load-dir is safe and hot-swaps specs — existing entities keep their current state, the new spec takes effect immediately. Use it to iterate on specs without losing data.
⚠️ Spec changes are hot-reloads, not PRs. The activation path for spec changes is:
- Edit the
.ioa.toml/.csdl.xmlfile - Call
load-dir(orsubmit_specsvia MCP) - Verification runs → spec takes effect immediately
Git-commit for version tracking. But do NOT create pull requests for spec-only changes. PRs are for Temper platform code (Rust). Specs are your tools — you iterate on them live.
3. Use the OData API
Base URL: <TEMPER_URL>/tdata Required header: X-Tenant-Id: {your-app}
Action URL Format — Read This First
Firing an action on an entity:
The `Temper.` prefix is mandatory. This is OData bound action syntax. Without it, you get 404.
This is the start of the file. Read the full SKILL.md on GitHub.
Security
- Security scanPassed, 90 of 100Pattern checks on the skill's files.
- Model reviewPassed
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingskills/temper-openclaw/SKILL.md
Popularity
- Repository stars
- 46
- Repository forks
- 10
- 7-day trend score
- 19
Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/nerdsane/temper/temper-openclaw)