JamJet · Agent Action Control Prove what every agent was allowed to do

Prove every
agent action.

It starts with a runtime that keeps agents alive. When a worker dies, JamJet replays the event log and resumes from the failed step: no lost progress, no duplicate side effects. Every action it takes is then policy-checked and signed onto a receipt anyone can verify.

Durable by default Kill the worker mid-run. The agent still finishes.
jamjet · crash recovery
$ jamjet run analyst-pipeline
▸ Starting execution exec_a4b2…
▸ [Plan]      ✓ completed  420ms
▸ [Analyze]   running…
▸ Worker SIGTERM received
▸ Lease expired · scheduler reclaiming
▸ Restored exec_a4b2 from checkpoint
▸ [Analyze]   ✓ resumed and completed  890ms
▸ [Decision]  ✓ completed  650ms
▸ Receipt emitted · hash c8b1c4f5…
▸ Execution complete · 4/4 nodes · 0 events lost

SIGTERM lands on the Analyze step. The scheduler reclaims the lease, restores from the last checkpoint, and the run completes with zero events lost and a signed receipt.

Not another agent framework. The action-control layer that sits underneath them. Keep LangGraph, CrewAI, Claude Code, MCP, OpenAI Agents SDK, or Spring AI. Add JamJet where tool calls need policy, approval, and audit.

From the lab behind the Engram memory benchmarks and the AIP agent-identity work — see research.

Engram · 88.8% on LongMemEval-S (proxy benchmark) · AIP · agent identity + delegation chains (arXiv draft) · AgentBoundary v0.1 · open spec for AI action proof · public

Already shipping in production? Try JamJet Cloud free.

$ pip install jamjet
What just happened

Three moments on that tape.
Three things JamJet did.

  1. blocked BLOCKED It tried to drop a users table.

    db.drop_user hit a destructive-data policy and never executed. The attempt is recorded, not lost.

  2. recovered RESUMED The Analyze worker crashed.

    The scheduler reclaimed the lease and resumed from the last checkpoint. Completed steps stayed completed. Zero events lost.

  3. signed HELD A merge to production waited for a human.

    github.merge required approval. Once a person said yes, the action ran and was sealed into a receipt anyone can verify.

How a call gets on the tape
merge.py
from jamjet import gate

@gate("github.merge", require_approval=True)
def merge_pr(repo: str, pr: int) -> str:
    return github.merge(repo, pr)
pip install jamjet · one decorator puts the call on the tape, with the same policy across Claude Code, MCP, OpenAI Agents SDK, Spring AI

Every action passes the gate.

@gate is the decorator in your code. These are the demos: watch the policy engine block, hold, and recover six kinds of trouble, with a receipt for each.

Open the playground →
Why we built it

Most of what breaks an AI agent in the real world isn’t model quality. It’s the boring stuff: a worker dies, a tool gets called wrong, a budget runs out, an audit team asks what happened. We built JamJet so the dangerous call gets blocked, the crashed run resumes, and every action ends as a signed receipt. You keep LangGraph or CrewAI or whatever already works.

The runtime sits between your agent and everything it touches. Models, tools, memory, other agents: every interaction passes through a layer that can block, wait, record, and resume. Open source. Apache 2.0. Cloud-neutral.

How it fits with what you use →

Every source the recorder captures

Wherever your agents already run.
One gate, seven doors.

One policy.yaml in ~/.jamjet/. Every adapter below loads it and emits conformant audit JSONL. Run jamjet audit show to tail every decision, from every source, on one tape.

We respect the platforms we plug into. Claude Code gave developers a hook point. JamJet gives that hook point a policy engine, approval flow, and audit trail, and carries the same rules to OpenAI Agents SDK, MCP, and your own code.

Ship log

every other Friday, no skips · written by whoever built it Full log →
Jun 12

Approvals shipped end to end: park on a human gate, survive kill -9, resume on approve. Runtime crates 0.4.0, jamjet 0.10.2 on PyPI with new jamjet approvals and jamjet approve commands, YAML policy blocks now compile straight into runtime policy.

runtime
Jun 12

Field notes got a taxonomy: five categories, filter pills, and a worth-your-time shelf. The Gate now takes free-form tool calls, so you can invent your own and watch the policy decide.

site
Jun 12

The Gate is open: a playground where the real policy engine blocks, holds, and audits your tool calls, and you approve the held one yourself. Every verdict prints a receipt you can verify against the AgentBoundary spec.

site
What the recorder catches

Six failure modes.
Six gates.

Other tools observe what agents do. JamJet actively prevents unsafe behavior, recovers from failures, and creates audit evidence at the runtime layer.

  1. 01
    Lost progress

    A worker dies mid-run. JamJet replays the event log and resumes at the failed node.

  2. 02
    Unsafe tool

    An agent reaches for a tool it shouldn't. The 4-level policy hierarchy blocks the call before execution.

  3. 03
    Skipped approval

    A high-risk action waits for a human. The run survives restarts. The decision lands in audit.

  4. 04
    Runaway cost

    A reflection loop won't stop spending. The runtime halts the loop before it crosses the cap.

  5. 05
    Missing audit

    Compliance asks what happened. Every decision is in a signed, exportable evidence package.

  6. 06
    Forgotten context

    The agent forgets across sessions. Engram surfaces durable facts, not raw chat history.

The flight recorder

Replay the whole run.
Every call on one tape.

jamjet.recorder · research-pipeline 00:00 / 00:09
scheduler Plan Research Analyze Review Synthesize

ready

the tape · tool calls
  1. 14:22:01 fs.read_corpus ALLOW
  2. 14:22:02 web.fetch ALLOW
  3. 14:22:03 db.drop_user BLOCKED
  4. 14:22:06 github.merge REQUIRES APPROVAL

That's one agent run, played back. It read files. It tried to drop a users table: blocked. It crashed mid-analysis: recovered. It asked to merge to production: held for a human, then signed. Drag the scrubber: every call is policy-checked, recoverable, and written to a receipt anyone can verify, independent of your agent framework.

The difference

Why not just use logs?

Logs

  • what happened after the fact
  • unsigned
  • unstructured
  • agent-trusted

JamJet receipts

  • whether the action was allowed before it happened
  • signed, verifiable by anyone
  • conformant schema (AgentBoundary v0.1)
  • agent-independent

Tracing tools (LangSmith, Helicone, Langfuse) show you what your agent did. JamJet decides what it's allowed to do, and signs the receipt either way.

Production isn’t a milestone. It’s the moment your code has to defend itself.

— a thing every serious engineer has learned the hard way
Same runtime guarantees, two languages

Write Python or Java.
JamJet handles replay, policy, and recovery.

pipeline.py Python
from jamjet import task, workflow, approval

@task(model="claude-sonnet-4-6", max_cost=0.50)
async def analyze(data: dict) -> Report:
    """checkpointed, cost-capped"""

@workflow
async def pipeline(raw):
    report = await analyze(raw)     # crash-safe
    await approval(report)          # durable pause
    return await publish(report)
Pipeline.java Java
Agent analyst = Agent.builder()
    .name("analyst")
    .model("claude-sonnet-4-6")
    .strategy(Strategy.REFLECTION)
    .maxCost(0.50)                   // budget enforced
    .build();

WorkflowGraph pipeline = WorkflowGraph.builder()
    .node(analyst)                    // crash-safe
    .node(ApprovalGate.create())     // durable pause
    .node(publisher)
    .build();

Both compile to the same IR and run on the same Rust runtime. Java has its own native runtime too: zero sidecar, virtual threads, 8.9× faster than the REST sidecar in our benchmark.

When the team needs the cockpit

JamJet Cloud

The hosted control plane for agent runs. Trace timeline, policy violations, approval queue, cost guardrails, audit export, and hosted Engram across your team.

Need memory first?

Start with Engram.

Open-source memory for MCP-native AI agents. Fact extraction, conflict detection, hybrid retrieval, consolidation. Use it standalone with Claude, Cursor, or any MCP client.

We don’t replace your framework. We sit underneath it, like a seatbelt.

Every tool call passes through one checkpoint that can block, hold, record, or resume it.

— the design intent, in one sentence

Compared with: Temporal · Microsoft AGT · all integrations

Make agent runs
replayable, auditable,
and controlled.

$ pip install jamjet

Apache 2.0 · Cloud-neutral · Framework-neutral · Built in Rust, Python, and Java.