Agent OS — agent.spboucher.ai
A from-scratch agentic platform: you give an agent a mission in a project (a git repository on the host), it works in a sandbox, journals every step durably, asks before anything with an outside effect, and you follow and steer it from a web console (desktop and phone). No agent framework: its own orchestration, its own durable-execution kernel on PostgreSQL, the official Anthropic and OpenAI SDKs.
Scope today = phases 0–2: foundations, durable kernel, one agent per mission, two providers, file / shell / git tools in a Seatbelt sandbox, policy + durable approvals, live console. See What is not built.
Architecture
browser ──HTTPS/WSS──▶ Caddy (MacLustr Tunnel) ──▶ apps/server :8640 auth, REST, events WebSocket, static console
apps/worker claims runs, executes the engine, journals steps (no listener)
PostgreSQL 17 the only shared state: journal, queue, waits, events- The server never runs agent code; the worker never serves HTTP. They meet only in Postgres
(tables +
LISTEN/NOTIFYas a doorbell, slow-poll fallback). - Kernel (
@aos/kernel): deterministic replay over a step journal. Run logic is re-run from the top on every claim; steps with a recorded result return it, execution resumes at the first step without one. Leases with fencing tokens, durable waits (approvals, questions, timers), budgets, events, artifacts. - Engine (
@aos/engine): the agent loop as kernel run logic — model turn → tool batch → policy gate → journaled tool steps; done-criteria protocol; stall, budget and context governors; mission git branch. - Tools (
@aos/tools): read / list / search / edit / write,shell(macOS Seatbelt, fail closed), git status / diff / commit / push, control tools (ask_owner,propose_criteria,update_criteria,finish). - Providers (
@aos/providers): Anthropic Messages and OpenAI Responses adapters, native transcripts kept opaque and replayed verbatim, price table. - Server (
apps/server): Fastify, password + mandatory second factor (TOTP or passkey), CSRF, CSP with per-document script hashes, REST/api/v1, events WebSocket with cursor replay. Every kernel write goes throughkernel-adapter.ts. - Web (
apps/web): Next.js static export served by the server; live timeline merged by stepseq.
Design rationale (French): docs/ARCHITECTURE.md. Interface contract: docs/CONTRACT.md.
Repository layout
| Path | What |
|---|---|
packages/shared |
frozen vocabulary and browser DTOs (zod) |
packages/kernel |
durable execution on Postgres, migrate, migrate-cli |
packages/providers |
Anthropic / OpenAI adapters, catalogue, prices |
packages/tools |
tools, path safety, Seatbelt sandbox |
packages/engine |
agent loop, policy, approvals, criteria, governors |
apps/worker |
worker process (dist/main.js) |
apps/server |
HTTP/WS server (dist/main.js), see apps/server/README.md |
apps/web |
console (static export in out/), dev mock, Playwright suites e2e/ (mock) and e2e-real/ |
db/migrations |
SQL migrations, applied by the kernel's migrate |
scripts |
dev-up.sh, dev-down.sh, ci.sh |
deploy |
make-manifest.py (mld manifest), backup.sh, restore.sh |
docs |
ARCHITECTURE.md, CONTRACT.md, deployment.md, operations.md, security.md |
Development quick start
Requirements: macOS, Node ≥ 24 (tested on 26), pnpm, PostgreSQL 17 on the /tmp socket, git, and
~/.config/agent-os/dev.env (mode 0600) with ANTHROPIC_API_KEY=… and/or OPENAI_API_KEY=….
scripts/dev-up.sh # build all, create/migrate agent_os_dev, start worker + server
cat /tmp/aos-dev-data/setup-token # one-time token for the first-run page (never printed by the scripts)
open http://localhost:8640 # create the administrator, enrol TOTP or a passkey
scripts/dev-down.sh # stop both (database and /tmp/aos-dev-data are kept)dev-up.sh refuses to start twice, never echoes a key (the processes read the file named by
AOS_ENV_FILE themselves), uses data dir /tmp/aos-dev-data and workspace root /tmp/aos-dev-workspace,
and serves apps/web/out. scripts/dev-up.sh --worker starts only a worker (after a crash).
Do not run plain pnpm install; dependency changes follow the lock procedure of docs/CONTRACT.md §0.
Tests
scripts/ci.sh # build, typecheck, every unit suite (real Postgres, no model call), production web build
scripts/ci.sh --e2e # + Playwright against the dev mock, + the real end-to-end suite (real models, a few cents)- Unit suites create and drop their own
aos_test_<random>databases. apps/web/e2e/runs the static export againstdev/mock-server.mjs, a fixture that emits exactly the shapes of the real kernel / engine (build withNEXT_PUBLIC_E2E=1;ci.shdoes it).apps/web/e2e-real/is the acceptance test of phases 0–2: real server + worker + Postgres + real models through the browser. Its global setup resetsagent_os_dev,/tmp/aos-dev-dataand/tmp/aos-dev-workspace. Results of the last run:apps/web/e2e-real/last-run.json, screenshots inapps/web/e2e-real/screenshots/.- Opt-in live tests of single packages:
AOS_LIVE_TESTS=1 pnpm --filter @aos/providers test(and engine).
Deploy
Production runs on a MacLustr node through the cluster orchestrator mld (PM2, MacLustr Tunnel):
docs/deployment.md. First-run, updates, backup / restore, crash recovery: docs/operations.md.
Threat model, controls and known gaps: docs/security.md.
What is not built
Sub-agent orchestration (the data model supports run trees; the engine runs one agent), context
compaction (a run that fills ~90 % of the context window ends partial), long-term memory, remote
runners, MCP, web browsing, an egress proxy for network: open missions, a dedicated OS user for the
worker, replay of policy.decision events over REST. See the "Known gaps" list of docs/security.md.