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.1.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.1-py3-none-any.whl (103.3 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: jaros-0.3.1.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.1.tar.gz
Algorithm Hash digest
SHA256 7014c830e2e312ccc2cac0a8b9ad27d6b015d118c6b28ad520a6acfb36e72592
MD5 dfa1ba958e89e60eeb868c567638f3e1
BLAKE2b-256 b438ec611400e81b2c7011ea0fd6bf94d9403e92b1ea9ffd9881e9ab7ec54f14

See more details on using hashes here.

File details

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

File metadata

  • Download URL: jaros-0.3.1-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.1-py3-none-any.whl
Algorithm Hash digest
SHA256 9797b04ceb080b80e5fb62dd136644ef3bcbec80c0a103ae40aa4f6001f0b5ee
MD5 8df0a62aed22fa2f8393773bc4d06bcc
BLAKE2b-256 1f393e6b1a42b819b8ce83a83097c8e5112ea6fc6c705df54dd7f4ce9975de31

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