Python 3.10+ · zero runtime dependencies

An agent harness
small enough
to audit.

Argus connects a language model to a confined workspace, explicit approvals, and crash-tolerant sessions. Read every boundary. Change any of them.

from source pip install git+https://github.com/PRINCE2-AI/Argus.git

Six providers · four languages · 102 offline tests · MIT

argus — read-only demo
$ argus --prompt "audit src/" --mode read-only
Argus 0.2.0 · gemini/gemini-3.1-pro-preview · mode=read-only
workspace /workspace/argus · policy 20 deny patterns
[tool] list_files {"pattern":"src/**"}
src/loop.py
src/security.py
src/tools.py
[tool] grep {"regex":"TODO|FIXME"}
src/tools.py:42 · add timeout budget
[tool] write_file {"path":"src/tools.py"}
BLOCKED · read-only policy blocks this tool
$

Illustrative transcript. Tool output is truncated.

6 model providers
102 offline tests
4 interface languages
0 runtime dependencies

01 — The boundary is the product

Small surface. Hard edges.

Argus is deliberately boring where it matters: one loop, one policy gate, one session format. The interesting parts are the edges.

01

Boundary-first tools

Every filesystem call resolves through a realpath jail. .env, .git, and .argus are blocked by name, not by convention.

02

Modes that mean something

read-only, safe, yolo. Safe asks. Headless runs deny instead of guessing. Deterministic deny patterns still apply in YOLO.

03

Sessions that survive

Append-only JSONL with torn-tail tolerance, interrupted-call repair, and compaction markers. Resuming is a first-class path, not an afterthought.

04

One loop, six providers

Gemini, Anthropic, OpenAI, OpenRouter, Groq, and Ollama. Tool IDs, thought signatures, and content blocks normalize at the edge.

05

Zero runtime dependencies

Python standard library only. Install it, read it, vendor it, or embed it. There is no framework underneath to learn or fight.

06

Tests without a model

A scripted provider drives the loop. The offline suite verifies safety, persistence, repair, and every adapter. CI covers Python 3.10–3.13.

02 — Provider neutral

Six providers.
One message format.

Tool-call IDs, Gemini thought signatures, Anthropic content blocks, and reasoning-model parameters stay at the edge. The loop never learns a vendor's dialect.

  • Provider-specific keys, base URLs, and model defaults
  • Usage normalized into input, output, and total tokens
  • Safety blocks and malformed responses raise clear errors
  • Ollama never inherits a cloud API key
Provider reference
Default model gemini-3.1-pro-preview
API key GEMINI_API_KEY

Default when no provider is configured. Gemini 3 thought signatures round-trip through the neutral message format.

shell
argus --provider gemini --prompt "Review tools.py"

Cloud providers also accept ARGUS_API_KEY as a fallback. Pass --model to override the default.

Default mode. Mutating tools need an interactive approval. In a headless run, they are denied unless you pass --yes.

Deny patterns remain active in every mode.

03 — Safety as code

Three modes.
Zero ambiguity.

Approval is a code path, not a prompt instruction. Every tool call crosses the same Policy before it can touch the workspace.

  • Path jail — realpath confinement for every filesystem tool
  • Deny list — destructive shell semantics, independent of mode
  • Headless denial — no approver means no silent mutation
  • Fail closed — optional Jev review blocks when uncertain

Argus is not an OS sandbox. Run untrusted tasks in a container or VM.

Read the safety model

04 — Architecture

The whole request path, visible.

A small composition layer, one turn loop, and boundaries you can name. Nothing important happens in a place you cannot read.

Front door
CLI · Python API interactive · headless · fleet
Harness
Agent loop turn · tools · wrap-up
Context
Memory
Skills
Boundaries
Provider adapter6 wire formats
Policy gatemodes · deny rules
Workspace tools6 confined actions
Every assistant and tool message
append-only JSONL.argus/sessions
torn tailrepaircompaction
Turn mechanics, session repair, and provider contracts are documented in depth. Architecture notes

05 — Durable sessions

The crash is the test.

Agent work is long-running and failure-prone. Argus appends each message as it happens, then earns the right to resume when the process disappears.

  • A torn final line is ignored, not fatal
  • Interrupted tool calls are paired and repaired
  • Old duplicate tool rows are removed on load
  • Compaction summaries are marked and restored
Session reference
.argus/sessions/172...-validate-handler.jsonl
user{"role":"user","text":"Add validation to the handler"}
assistant{"role":"assistant","tool_calls":[{"id":"call_7f1","name":"read_file","args":{"path":"src/api.py"}}]}
tool{"role":"tool","call_id":"call_7f1","text":"1\tdef handler(request): ..."}
user{"role":"user","text":"[Conversation so far, compacted] ...","meta":{"compaction":true}}
assistant{"role":"assistant","text":"Validation added and verified."}
Session excerpt · illustrative argus --resume

06 — Evidence, not adjectives

102 tests. No network. No credentials.

A scripted provider exercises the same loop the CLI uses. Safety checks, provider translation, crash repair, compaction, memory, skills, and fleet ordering all run offline.

$ python -m unittest discover -s tests
Ran 102 tests in 0.71s
OK
CI 3.103.113.123.13

Read the whole request path

Start with the boundary.
Then make it yours.