AI execution kernel · open source · BSD-3-Clause

The AI execution kernel for deterministic, policy‑gated workflows.

Praxec composes pluggable capabilities — MCP tools, CLIs, services, scripts, and native modules — while constraining LLMs to bounded execution contexts.

two tools, fixed11 executor kindsvalidated transitions
kernel boundary — release.yaml
workflows:
  release:
    initialState: review
    states:
      review:
        transitions:
          run_checks:
            target: verified
            executor: { kind: cli, command: just ci }   # a CLI is a capability
      verified:
        transitions:
          approve:
            actor: human                    # so is a person
            target: approved
      approved:
        transitions:
          publish:
            target: live
            executor: { kind: rest, connection: deploys }  # so is a service

the inversion

The workflow chooses. The kernel enforces.

Most agent systems hand the model a list of tools and a prompt full of rules, then hope. Praxec turns that inside out: the workflow declares which capabilities each step may use, the kernel grants bounded access, and every result is validated before the state moves.

most agent systems → praxec
Most agent systemsPraxec
LLM chooses toolsWorkflow chooses capabilities
Prompt governs behaviorKernel enforces transitions
Tool list grows with complexityCapability surface stays controlled
Agent is the orchestratorWorkflow engine is primary
Best-effort guardrailsValidated state transitions

A rule that lives in prose is a rule the model can talk itself out of. A rule that lives in the kernel isn't up for debate.Read the full mechanism →

the execution loop

Four steps, every time

Every unit of work runs the same cycle. It's the same loop whether the capability is a shell command, an HTTP call, a human approval, or an LLM turn.

  1. Workflow selects

    The current state declares which transitions exist and which capability each one uses. Nothing else is on the menu.

    declared in yaml
  2. Kernel grants

    Guards, actor rules, and input schemas run first. Access is scoped to this one step — not a standing permission.

    bounded access
  3. Capability executes

    A CLI, a service, a script, a person, or a model does the work — with timeouts, retries, and fallbacks declared alongside it.

    any executor kind
  4. Kernel validates

    Output is checked against the declared schema before the state transition commits. Bad results don't advance the workflow.

    then, and only then, transition

the capability model

Anything that does work is a capability

A capability is a typed unit of work. Behind it sits one of eleven executor kinds — MCP is one transport among many, not the whole story:

  • cli
  • script
  • rest
  • mcp
  • human
  • llm
  • agent
  • workflow
  • parallel
  • pipeline
  • noop
the model's view

Two tools, no matter what

The model sees exactly two tools — praxec.query to read and discover, praxec.command to act. Everything routes through them. Wire in one capability or five hundred; the tool list never grows.

discovery

Links, not lists

Every response hands back the legal next moves as links, with arguments prefilled. The model navigates the workflow the way a browser navigates the web — it never needs a catalog of everything.

bounded contexts

LLMs stay inside the boundary

When a step is LLM-driven, the transitions legal at that stateare the model's tool list — with per-turn caps on iterations, time, tokens, and cost. Injecting extra tools isn't a config option.

See every executor kind →

on the wire

What a refused move actually looks like

The agent is in review. Checks haven't run. It reaches forpublish anyway — and finds the move isn't there:

wire trace — refusal + recovery
→ praxec.command { "transition": "publish" }      # tries to skip ahead

← { "result": { "status": "rejected" },
    "error":  { "code": "INVALID_TRANSITION" },
    "links":  [ { "rel": "run_checks" } ] }     # the legal move, handed back

Not discouraged — unreachable. And the refusal hands back the one legal move, so the agent recovers on its own: run the checks, and only then does publish appear. Every attempt, including this refused one, lands in the audit log.

built for production

The boring parts are the point

Deterministic execution needs unglamorous machinery. It's all here.

praxec check

Static config validation that fails CI on unreachable states, dead ends, and schema errors — before anything runs.

px doctor

Preflight for the runtime: provider keys, model bindings, and script references verified before a workflow walks.

Durable stores

Memory, file, or SQLite — including multi-process SQLite on one host with optimistic locking. No external services.

Audit & replay

Every action emits a structured JSON event — including the refused ones. Route to file, stdout, or your observability stack.

Hot reload

Send SIGHUP and the kernel validates the new config first, then swaps. In-flight workflows continue uninterrupted.

Navigable state

Discovery is HATEOAS all the way down — query any workflow and get its live state plus the legal moves from here.

The full production story →

get started

Running in two commands

terminal
$ curl -fsSL https://raw.githubusercontent.com/praxec/praxec/main/install.sh | bash
$ praxec init --with-starter-packs --yes     # scaffold config, wire packs + editor, verify readiness

praxec is the kernel — an MCP server you wire into Claude Code, Cursor, or any agent host. init --with-starter-packs --yesscaffolds a working gateway.yaml and models.yaml, wires the starter packs and your editor's MCP config, and finishes with a doctor readiness check — restart your editor andpraxec.query / praxec.command appear.

Want the mechanism first, or a different editor/pack setup?See the fast path and every flag →