Workflow engine for AI agents

Your agent’s “Do NOT” list is a list of scars.

Every rule in it exists because the agent invented a failure once. Realm replaces the rules with structure — wrong behaviour becomes impossible, not prohibited.

The agent calls Realm. Every other tool calls the agent.

The inversion

Most platforms call the model. Realm gets called by it.

01Your agentClaude · GPT ·any MCP client02Realmstate machineState guardValidates every submissionagainst the step’s schemaexecute_step()task + json schemavalid03State advancesevidence hashrecordedinvalid ·unapprovedRefusedstate unchanged— retry01Your agentClaude · GPT · any MCP clientexecute_step()task + json schema02Realmstate machineState guardValidates every submissionagainst the step’s schemavalidinvalid ·unapproved03State advancesevidence hashrecordedRefusedstateunchanged— retry

Structure, not instruction

A prompt rule is a request. A state machine is a constraint. Only one of them survives contact with a model having a bad day.

What that buys you

Order is enforced

A step cannot run before its dependencies. Not by instruction — by the state machine.

Output is schema-checked

An answer that breaks its step's schema is rejected at the boundary. It never enters the run.

Gates stop the run

Critical steps pause until the gate is answered, and the answer goes on the record.

Evidence, not logs

Every step that finishes leaves a record of what it returned. For client work, that record is the deliverable.

See it run

Step through a real run, decision by decision

Every step records what it returned, a hash of it, and when. Not a log that something ran: a record of what Realm accepted at each step.

The agent starts a run. Realm fetches the pull request itself.

The first step is marked auto, so the engine runs it and no model is involved. The agent only learns what comes next.

Agent calls

{
  "tool": "start_run",
  "workflow_id": "pr-review",
  "params": {
    "repo": "acme/payments-api",
    "pr_number": 42
  }
}

Realm answers

{
  "status": "ok",
  "context_hint": "Step 'fetch_pr' completed. 1 step(s) now available.",
  "run_phase": "running"
}

What the step fetched — Retry failed charge webhooks, 3 files

--- src/webhooks/retry.ts
@@ -12,14 +12,22 @@ export async function deliverWebhook(event: ChargeEvent): Promise<void> {
-  await post(event.endpoint, event.payload);
+  for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {
+    try {
+      await post(event.endpoint, event.payload);
+      return;
+    } catch (err) {
+      await sleep(1000);
+    }
+  }
 }

Evidence recorded for fetch_pr · hash 625650d8cdad…

Agent calls

Realm answers

Full reply

Evidence recorded for fetch_pr · hash

1 of 5

Recorded on 2026-10-08 from two real runs of examples/08-pr-review on Realm 0.46.0, driven over MCP; the reviewer answered with the CLI. The two runs differ only in the reviewer's answer; the refusals come from the first. GitHub was a local stand-in server, so nothing was posted. Long text is shortened with “…”.

What is swapped

To run in your browser, a few parts that need a server are replaced. Realm's own decisions — what it accepts, refuses and records — are unchanged.

  • process: argv [], env {}, platform "browser", stderr.write a no-op.
  • Buffer: only byteLength, through TextEncoder; every other member throws and is logged.
  • global and setImmediate: throw, logged.
  • fetch: the GitHub stand-in, which throws naming the method and URL for anything off its routes.
  • crypto: sha256 from @noble/hashes, plus Web Crypto.
  • Every other Node built-in and the npm package proper-lockfile: stubs that throw.
  • The MCP SDK at 1.31.0 in place of the version realm-mcp 0.46.0 pins exactly (security fix GHSA-6qxp-vccf-f47h).
  • Runs: InMemoryStore (realm-testing). Workflows: a hand-made in-memory store holding this one workflow.
  • Traces: InMemoryTraceBufferStore, Realm's own in-memory trace store. Failed attempts: not written to a file; refusals are still counted in the run.

Try it

Nothing to sign up for

# install the CLI and the model SDK it calls (Anthropic here)
npm install -g @sensigo/realm-cli @anthropic-ai/sdk

# create a starter workflow, then let a model drive it
# (needs ANTHROPIC_API_KEY in your environment)
realm workflow init my-workflow
realm agent --workflow ./my-workflow --provider anthropic --model claude-sonnet-5-5

Runs locally. Apache‑2.0, published on npm; evidence is written to your own machine.