production

Trust it with real work

A kernel earns its name by being boring under pressure. Praxec ships the machinery that makes deterministic execution hold up in production: validation before startup, preflight before runs, durable state, a replayable record, and reloads that can't brick you.

validate before anything runs

praxec check — broken configs fail CI, not prod

praxec check statically validates your entire config — a suite of named rules covering unreachable states, dead-end states, schema errors, dangling references, and namespace collisions. It exits 0 when everything resolves and 1 otherwise, so it drops straight into CI:

terminal — ci gate
$ praxec check --config gateway.yaml
error[unreachable_state]: state 'rollback' in workflow 'release'
  is not reachable from initialState 'review'
error[dead_end]: state 'waiting' declares no transitions and is not terminal
exit code 1   # errors abort startup — and fail your CI

Each error names the rule that fired, the workflow / state / transition that triggered it, and the expected shape — paste-fixable without spelunking. Your state machines get the same treatment as your code: verified before they ship.

preflight the runtime

px doctor — catch it before the workflow walks

Static validation can't tell you an API key is missing or a model id no longer resolves. That's the doctor's job. px doctor runs a preflight battery before a workflow walk: it probes provider API keys, re-checks model bindings against each provider's live catalog, resolves delegate references, and verifies external script URIs.

check proves the config is structurally sound;doctor proves the world around it is actually there. Together they mean a workflow that starts is a workflow that can finish.

durable state

Stores that match your deployment

StoreDurabilityBest for
memoryNone — lost on restartDevelopment and testing
fileOne JSON file per workflow, atomic-rename writesSimple single-server setups; easy to inspect and back up
sqliteBundled, WAL modeProduction — the only backend with durable governance state

SQLite needs no extra infrastructure: the database is a file you can back up, inspect, and move. Multiple processes on one host can share a single SQLite file in WAL mode — no networked store to operate. And every store enforces optimistic locking: writes carry an expectedVersion, stale writers are rejected with the current state attached, and no update is ever silently lost. Switching stores changes nothing else in your config.

audit & replay

A record of what happened — including what didn't

Every action emits a structured JSON event: workflow starts, executions, human approval requests, LLM invocations with token and cost accounting — and the refused moves, which are usually the ones you most want to see:

audit event — a refused move
{ "event_type": "transition.rejected",
  "workflow_id": "wf_01H…",
  "state": "unchecked",
  "attempted_transition": "ship",
  "error_code": "INVALID_TRANSITION",
  "correlation_id": "…" }

Route events to a file, stdout, or your observability stack. Because the trace is complete and structured, you can replay a run to see exactly what the agent attempted, what the kernel allowed, and why. Debugging stops being "read the transcript and guess."

operations

Hot reload, without the gamble

Send SIGHUP and the kernel reloads config with validate-then-swap: the new config is fully validated first, and only a valid config replaces the running one. A typo in the new file can't take down a working gateway. In-flight workflows continue uninterrupted:

terminal — validate-then-swap
$ kill -HUP $(pidof praxec)
# 1. new config is parsed and fully validated first
# 2. only a valid config is swapped in
# 3. in-flight workflows continue uninterrupted

Day-to-day inspection goes through the same surface the model uses: discovery is HATEOAS-navigable, so praxec.query gives you — or your dashboard — any workflow's live state and the legal moves from here. No side-channel admin API to learn.