Skip to content

Repository files navigation

Lever

Lever

Homepage: lever.to

Containerised, jailed multi-agent orchestration. A single manager agent drives a fleet of worker agents, each in its own container, and the whole stack runs inside a jail so that a compromised or prompt-injected agent cannot read host secrets or reach your local network.

Lever is the orchestration and interface layer; Scion is the runtime engine underneath (containers, sessions, attach/resume, typed messaging). You talk to one tool, lever, and it drives Scion.

The threat model assumes the agent is hostile and lets the OS contain it: the bound is a single directory subtree and an allowlist of network endpoints, enforced by the operating system, not by the agent behaving. What that bound does and does not cover (e.g. data exfiltration over allowed internet egress) is in the security model.

The model

A project is a directory. You register a directory with Lever and every agent working on it gets that directory bind-mounted in place; no clones, no sync. The manager's workspace is the whole tree; each worker is confined to its own subdirectory, isolated from the manager and from its siblings. The manager dispatches work to workers, watches a typed event stream for progress and questions, and is the single thing a human talks to.

graph TB
    Hu([Human])

    subgraph host["Host (macOS) — outside the jail"]
        CLI[lever CLI]
        BK["Capability broker<br/>holds real credentials<br/>capabilities · /llm · /worker/* · brokered tools (/mcp/&lt;name&gt;/)"]
        TOOLS[first-party tools<br/>host subprocesses]
        TREE[("project tree<br/>on host disk")]
    end

    subgraph jail["Jail — OrbStack isolated machine (the containment boundary)"]
        HUB["Scion server + runtime<br/>(rootless containers)"]
        FW{{egress allowlist<br/>in the jail's netns}}
        subgraph cons["Agent containers"]
            CO["Manager<br/>whole-tree workspace"]
            GA["Worker A → workers/a/"]
            GB["Worker B → workers/b/"]
        end
    end

    Hu <-->|converses with| CO
    CLI -->|brings up / drives| HUB
    CO -->|"dispatch · capabilities · LLM · tools<br/>(mTLS via host.orb.internal)"| FW
    GA -->|capabilities · LLM · tools| FW
    GB -->|capabilities · LLM · tools| FW
    FW -->|"allowlisted: broker + model API"| BK
    BK --- TOOLS
    BK -->|"/worker/start → Scion (operator)"| HUB
    HUB --> CO
    HUB --> GA
    HUB --> GB
    TREE -.->|"bind-mount: whole tree"| CO
    TREE -.->|"bind-mount: workers/a only"| GA
    TREE -.->|"bind-mount: workers/b only"| GB
Loading

How it stays contained

The runtime and every agent run inside one jail: an OrbStack isolated machine (or a Lima VM) that shares none of the host's files and has its own network namespace. The lever binary and the capability broker (which holds the real credentials) run on the host; Scion's server, the container runtime, and all agents run inside the jail as rootless containers. The jail mounts only the project tree you choose and cannot route to the LAN; only an explicit allowlist of host ports and the model API is reachable. No fork of Scion is required; containment is enforced from outside it.

The jail is a contract, not one product. OrbStack and lima implement it. See containment backends and the security model.

Core + instance

lever.to ships the generic core: the orchestration engine, the manager role, jail provisioning, the project model, and these docs. Your own setup is an instance built on top (knowledge base, tools, workers, the manager's prompt/skills), consuming the lever binary as a dependency. See core vs instance.

Build & run

go install github.com/stevegeek/lever/cmd/lever@latest   # host `lever` onto your GOBIN/PATH
# — or from a clone (requires Go 1.26+):
make install              # build host `lever` → ~/.local/bin/lever (must be on PATH)
make lever-image          # build the agent image scionlocal/lever-claude:<arch>

cd path/to/my-instance && lever up        # bring up jail + scion + manager, attach the manager TTY
lever up path/to/my-instance/lever.yaml   # or pass an explicit config path
lever apply                               # headless; --dry-run prints the plan only

Runnable examples: hello-worker, assistant-demo, multi-project, two-agents-comms.

Build prerequisites for the agent image (scion's base image, arch tags, extending the image for an instance) are in install & build the image. Repository layout, binaries, and test targets are in CONTRIBUTING.md.

An instance is one lever.yaml at the instance root describing the manager and its workers. The root is not mounted; only the tree: subdirectory is bind-mounted into the jail. Commands with no config argument read ./lever.yaml from the current directory; there is no walk-up discovery. See config reference for every key.

Commands

The everyday surface: lever up (bring up and attach), lever apply (headless), lever attach, lever msg send, lever reload (apply config changes to a running instance), lever stop, lever destroy, lever init (scaffold operator skills), lever doctor. Inside the manager container, lever-manager agent|msg|watch dispatches and steers workers through the broker. Every command and flag is in the CLI reference.

Requirements

  • macOS on Apple Silicon with OrbStack, or Lima ≥ 2.0.0 (macOS or Linux). See containment backends.
  • Scion as the runtime engine, pinned in lever.yaml (the examples pin a supported commit). A Go toolchain on the host with scion.version:/scion.source:; none with scion.binary:. See config reference.
  • Docker, to build the agent image locally.
  • An LLM coding-agent harness (the agent image bakes Claude Code).

Documentation

Licence

MIT © Stephen Ierodiaconou.

About

Lever is a containerised multi-agent AI orchestration system with a host-side broker that manages permissions and access.

Topics

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages