Skip to main content

A zero-infrastructure runtime that makes agent systems reproducible, testable, and capability-safe — a durable, replayable state machine orchestrating AI agents as lightweight threads.

Project description

Jaros

A zero-infrastructure runtime that makes agent systems reproducible, testable, and capability-safe by construction — a durable, replayable state machine that orchestrates AI agents as lightweight computing threads, not bloated microservices.

Jaros OS demo: boot, run a built-in agent + two agents + a custom tool, zero infra

Jaros is the runtime you reach for the day your agent leaves the demo — when non-determinism has made it impossible to reproduce, and ambient power has made it unsafe to ship. It delivers that without a server, a database, or a broker: just files and threads.

It works by decoupling non-deterministic AI reasoning from deterministic system execution. The LLM is an interchangeable application that may only propose inert, serializable Decision data; a deterministic execution plane decides whether and how each decision runs — and may reject it. This is the system's Prime Directive; every part of the codebase exists to serve it.


What sets Jaros apart

Most agent frameworks let the model drive: a tool call is a side effect. Jaros inverts it — the model writes recommendations on slips of paper; a deterministic clerk decides what actually happens. Four properties fall out of that design:

  • 🐝 Reproducible & accountable swarms — every accepted Decision is recorded in one ordered, hash-chained log tagged with its source agent, so replaying re-executes the whole hive to byte-identical state with zero model calls and attributes any failure to the exact agent and decision.
  • 🔁 Reproducible by replay — the only non-determinism is the model's output, recorded before any effect; replaying the log reconstructs the run to byte-identical state with no model call. Crash recovery is just replay.
  • 🔒 Capability-safe by construction — agents hold only the scoped handles the harness grants; a bug or bad decision cannot reach what it was never given, and every mediated action is audited.
  • 📦 Zero-infrastructure — no server, no database, no broker. The control plane is the file system; agents are threads in one process. A check_zero_infra guardrail fails the build if any code even imports a DB driver or broker.

One command replays a hive and names the culprit — and the agents really let the model decide (accept → DONE, reject → FAILED), yet replay reconstructs whatever the model chose with zero model calls:

A swarm replay: reconstruct the whole hive byte-identically with no model call, and attribute the bad handoff to the exact agent

→ The full story, with the model-driven decisions, the graduation-layer comparison, and the honest "is / is not": docs/why-jaros.md.


Quickstart

Install from PyPI and scaffold a ready-to-run node in two commands:

pip install jaros
jaros init --with-examples   # scaffolds ./.jaros-data with bundled example agents, tools, evals, schedules

jaros init --with-examples drops a library of example agents and tools straight into the data dir, so the daemon — and the console — have something to run immediately. Boot the node, then drive it from another shell; work enters only through the shared file system:

# boot the node (the OS) + the web console — discovers ./.jaros-data by default
jaros serve
#   Jaros node up.
#     data dir : .jaros-data
#     model    : default
#     console  : http://localhost:5500  (starting…)
#     Ctrl-C to stop. The log below shows events as they happen.

jaros serve brings up the web console by default (--no-console to skip) and stays quiet after the banner — it logs only meaningful events (a job completing or failing, a schedule firing), not a per-tick heartbeat.

# from another terminal: submit work + watch results, all over the shared FS
jaros submit system-health             # a bundled example agent
jaros submit advance --input '{}'      # the built-in agent
jaros watch                            # change-only: reprints status when it changes, one line per new result

Then the payoff — reconstruct the entire run from the recorded decisions, with no model call:

jaros replay
#   replayed 3 recorded decisions (3 applied) - model calls: 0
#     reconstructed state : DONE
#     byte-identical      : yes
#   reproducible: the recorded decisions reconstruct the run exactly, with no model call.

The whole loop from the CLI — submit work, check status, replay it byte-identically, and run the eval suite (real output, nothing faked):

A real Jaros CLI session: submit jobs, status, replay --json (0 model calls, byte-identical), and a green eval suite

Every command discovers the data dir automatically (./.jaros-data, or $JAROS_DATA_DIR, or --data-dir DIR to override). For the full day-one-to-production path (first agent → schedule → eval → replay → console → distributed Docker), see docs/getting-started.md.

Hacking on Jaros itself? Clone the repo and pip install -e ".[dev]" instead — every command works the same against a checkout, and pytest runs the suite plus the architecture guardrails.

Want to build your own agents? Point your coding agent (e.g. Claude Code) at agent-kit/, tell it to read what's there, and it learns the whole system and writes + verifies new Jaros agents for you. See Build an agent.


Web console

A TypeScript + React administrative and monitoring interface lives in console/ — submit jobs, install agents and custom tools, watch live status, browse the durable decision log, and replay it to byte-identical state from the browser. It's a host-side companion (a thin file-system bridge + SPA); the Jaros node itself stays serverless.

jaros serve starts it for you and prints the URL — open http://localhost:5500. The Overview is a glanceable NOC view with a live get-started checklist; every other page (State Machine, Reproducibility, Harness, Jobs, Agents, Schedules, Evaluations) introspects the real runtime over the file system.

Jaros Console — Overview

Want it on its own (first run, or pointed at a remote node's shared dir)? Install its deps once and run it standalone:

cd console && npm install
JAROS_DATA_DIR=/tmp/jaros-demo npm run dev        # then open http://localhost:5500

The full page gallery and a walkthrough of every page (with pictures) live in docs/console.md and the console README.


Build an agent

An agent is a ReasoningBoundary: data in → Decision data out, no side effects, no handles. Drop the module into the shared-FS agents/ folder and the daemon registers it at runtime.

import uuid
from jaros.core import create_decision

KIND = "greeter"  # the agent kind the daemon registers

class GreeterBoundary:
    def __init__(self, llm):
        self._llm = llm

    def decide(self, context) -> list:
        name = context.get("name", "world") if isinstance(context, dict) else "world"
        # Propose an inert decision; the executor (not the agent) acts on it.
        return [create_decision(
            id=f"greet-{uuid.uuid4().hex}",
            source="greeter",
            kind="advance",                       # built-in handler drives the state machine
            payload={"events": ["start", "complete"], "note": f"hello {name}"},
        )]

def build(llm):                                   # agent factory the daemon calls
    return GreeterBoundary(llm)

To bound an agent, restrict its capability grant at spawn time — a role is just a named bundle of capabilities. A custom tool extends what the system can do: drop a class exposing NAME, validate(), and execute() into tools/. See examples/tools/greet_tool.py and the full guide in docs/building-agents.md.

Or let a coding agent build it. Jaros is made to be extended by coding agents. Point yours — Claude Code, Cursor, or similar — at AGENTS.mdagent-kit/ and have it read what's there: the mental model, a skill per artifact, accurate API reference, and runnable templates that pass jaros eval unmodified. Tell it "read agent-kit/ and build me an agent that does X," and it will.


Run on Docker

The container is the boundary for the whole Jaros node; agents run as threads inside it — never one container per agent.

docker build -t jaros .
docker run -d --name jaros_os -v ${PWD}/.jaros-data:/data jaros   # one daemon = one node
jaros submit advance --input '{}'                                 # submit from the host, over the shared FS

Because the control plane is files only, scheduling needs no broker: any host-side cron can jaros submit, and several daemons can share one directory — each job is claimed by an atomic inbox → claimed rename (exactly-once in the happy path, at-least-once under failure via lease reclaim). The distributed walkthrough is in docs/getting-started.md.


Learn more

Jaros is developed spec-first under .jarify/: the Prime Directive holds the system intent, each EXT-00x spec decomposes one tenet into requirements/design/tasks, and code is traced back to requirements via index.json.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

jaros-0.3.2.tar.gz (114.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

jaros-0.3.2-py3-none-any.whl (103.3 kB view details)

Uploaded Python 3

File details

Details for the file jaros-0.3.2.tar.gz.

File metadata

  • Download URL: jaros-0.3.2.tar.gz
  • Upload date:
  • Size: 114.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.10

File hashes

Hashes for jaros-0.3.2.tar.gz
Algorithm Hash digest
SHA256 826effefd69026d5b2c1989b9aa02dd633c4213196873f2e31fec28454bf6f1d
MD5 369696e01fd22ca5a108e8d0c1f733bd
BLAKE2b-256 a9648ee111eda5aba82c38f03f5a1dffff663272b6d72cab1496a83576b3da38

See more details on using hashes here.

File details

Details for the file jaros-0.3.2-py3-none-any.whl.

File metadata

  • Download URL: jaros-0.3.2-py3-none-any.whl
  • Upload date:
  • Size: 103.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.10

File hashes

Hashes for jaros-0.3.2-py3-none-any.whl
Algorithm Hash digest
SHA256 977c0d57e41547937e788b25ea53cd355983054a5014793fae3f1460a0779f4c
MD5 fa3cc309d933e8bc539e3e76a7c65921
BLAKE2b-256 590f6e620e46ccfa4f20f3cb26be8be5af68d6dc01eb2371791013078907389a

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page