Skip to main content

Ludus

Ludus Magnus is the multi-agent software arena — it defines agents, their behavior, and how they are deployed. The name comes from the Ludus Magnus, the great training school adjacent to the Roman Colosseum. Multiple agent roles (Product Manager, Architect, Engineering Manager, Developers, DevOps, QA) collaborate across multiple software projects, coordinated by OpenClaw and communicating internally via the Beads protocol — a git-backed, DAG-based task and messaging system optimized for AI agents.

Agent Quick Reference

Key files: ludus/agents/*/ROLE.yaml, ludus/agents/agent-map.json, ludus/containers/Dockerfile.* Commands: just deploy-agents, just deploy-full, just status, just images-build Last verified: 2026-04-01

1. Vision — Two Tracking Systems

SystemPurposeLifecycleAnalogy
BeadsInternal agent coordination & communicationEphemeral — clean up after completionSlack / coffee machine chat
GitHub IssuesOfficial project tracking, external documentationPermanent — part of the project recordJira / ticket system

No automatic sync between the two. Agents reference GitHub Issues in beads manually where needed (e.g., "see GH#42").

2. Roles

RoleRepo Checkout?Beads UsageGitHub Usage
Product ManagerNoCreates epics, prioritizes, assignsCreates issues
ArchitectSometimes (read-only)Design decisions, reviewsComments on PRs
Engineering ManagerNoStatus overview, assignments, escalationsReads issues
DeveloperYes (1-2 repos)Tasks, results, questionsCreates/closes issues, PRs
DevOpsYes (ludus)Deployment tasks, incidentsCreates issues (ludus)
QAYes (read-only)Bug reports, test resultsCreates issues
Key constraint

Roles like PM and Engineering Manager have no code repo checkout but need full Beads access. This drives the shared-intercom topology decision below.

3. Topology — Shared Intercom Clone

A local intercom directory lives on the host and is bind-mounted into every agent container at /mnt/intercom/. All agents share one Dolt database — changes are immediately visible, no import/export needed. The intercom does not use a git remote; it is initialised in-place via ludus ops intercom bootstrap (which runs bd init).

Host (ludus host):
/home/openclaw/b4arena/intercom/ ← local directory (no git remote)
└── .beads/ ← single shared Dolt database

Container (any agent, bind-mounted):
/mnt/intercom/.beads/ ← same database

Environment Variables

BEADS_DIR and BD_ACTOR are injected via docker.env, so bd works from any directory inside the container.

Constraint — Serialized Execution

Dolt is not safe for concurrent access. The watcher must serialize agent wake-ups — only one agent active at a time.

Benefits

  1. Immediate visibility — no sync delay between agents
  2. Simple agent code — agents just use bd, no sync scripts to call
  3. Container independence — containers are ephemeral, workspace data persists on host
  4. Zero scaling cost — new agents get access via bind mount

3b. Sandbox Container Architecture

All agents (including main) run their shell commands inside Docker containers managed by OpenClaw's sandbox system. The gateway runs on the host; only tool execution is containerized.

Ownership Split

ConcernOwnerManaged via
Docker CE installed + runningludus CLIludus ops provision
OpenClaw gateway (port, auth, channels, logging)ludus CLIludus ops provision
Agent defaults (agents.defaults.model)ludus CLIludus ops provision
systemd, firewall, secrets (env file, PEM)ludus CLIludus ops provision
All agent registrationb4arena/just register
All sandbox config (defaults + per-agent)b4arena/just sandbox-configure
Sandbox Docker imagesb4arena/just images-build
Agent workspace syncb4arena/just sync (mutagen + rsync)

Image Layers

All images are built on the ludus host via just images-build (no local Docker needed).

Per-Agent Sandbox Config

PropertyDefaultmainforge
imageb4arena-base:latest(default)b4arena-dev:latest
memory2g2g2g
cpus1.02.04.0
networkbridgebridgebridge
workspaceAccessrwrwrw

Global defaults are set via agents.defaults.sandbox.*, per-agent overrides via agents.list[].sandbox.*. Most agents (priya, atlas, rio, helm, indago, glue, etc.) use defaults.

Network access

All agents require network=bridge because they need outbound HTTPS access to GitHub (for code repo operations and gh CLI). The intercom git sync runs on the host between agent sessions, not inside containers.

Environment Variables

Env vars are injected into containers via agents.defaults.sandbox.docker.env (defaults) and per-agent agents.list[].sandbox.docker.env (overrides, merged on top):

VariableSourceValue
BEADS_DIRDefault docker.env/mnt/intercom/.beads
BD_ACTORPer-agent docker.envAgent-specific (e.g., main-agent, forge-agent)
Env var naming

_TOKEN, _KEY, _SECRET patterns are stripped by the sanitizer — do not use these in env var names. GitHub auth is handled via bind-mounted credential files (not env var injection): the host env file is mounted at /etc/openclaw/env inside the container, where gh-wrapper.sh sources it to obtain GitHub App credentials for token generation.

Container Lifecycle

  • Mode: all — every session (including main) runs in a container
  • Scope: agent — one container per agent, reused across sessions
  • Workspace access: rw — containers bind-mount the host workspace directly (agent file changes persist on host)
  • Beads access: All agents share a single Dolt database at /mnt/intercom/.beads (bind-mounted from host, bootstrapped once via ludus ops intercom bootstrap)
  • Creation: Containers are created eagerly at agent run start, before the first LLM token
  • Reuse: Containers are reused if config hash matches; recreated if config changes
  • Pruning: Auto-pruned after 24h idle or 7 days total age

Deploy Commands

just images-build       # Build all 4 image layers on the ludus host
just sandbox-configure # Set sandbox defaults + per-agent overrides
just deploy # Full deploy: sync + register + sandbox-configure
just deploy-full # First-time: images-build + deploy

4. Four-Tier Execution Framework

Based on the Token-Saving Patterns research: Tokens are compute budget. Every token spent on a task that doesn't require reasoning is wasted.

TierDescriptionTokensBeads Operations
1 — System CronDeterministic scripts, zero reasoning0bd ready --json, bd mail --unread --json, notification formatting
2 — LLM CronTasks requiring interpretationYes (isolated)Complex comment composition, status reports
3 — HeartbeatMultiple lightweight checks sharing contextYes (shared)Beads check as one heartbeat item
4 — Pull HeartbeatAgent self-serves from async work queuesYes (reasoning)Triage, prioritize, dispatch

The Intern Test

"If given to an intern, would they need judgment or just follow a checklist?"

Checklist = Tier 1 (shell script). Judgment = Tier 4 (LLM agent).

Tier Classification for Common Operations

OperationTierTokens?
Poll for new beads1No
Format notification summary1No
Claim a well-defined task1No
Route by label match1No
Triage: which beads are urgent?4Yes
Execute a task (code, analysis)4Yes
Write a comment on a bead2/4Yes
Create a new bead from findings2Yes

5. Notification Flow

Architecture

┌─────────────────────────────────────────────────────────┐
│ Tier 1: Beads Watcher (system cron, every 2 min) │
│ │
│ Pure shell. Zero tokens. Zero LLM involvement. │
│ │
│ for each label in agent-map.json: │
│ bd ready --label <label> --json → collect bead IDs │
│ │
│ ├─ label "dev" → WAKE forge (with bead IDs) │
│ ├─ label "mgr" → WAKE rio (with IDs) │
│ ├─ label "main" → WAKE main (with bead IDs) │
│ └─ no label match → WAKE main (triage) │
└───────────────────────────────┬─────────────────────────┘
│ (only when work exists)

┌─────────────────────────────────────────────────────────┐
│ Tier 4: Agent Wake-Up (tokens start here) │
│ │
│ Agent reads bead details via bd CLI │
│ → Claims task: bd update <id> --claim (atomic) │
│ → Executes work │
│ → Writes results: bd update, bd comment │
│ → Optionally creates/closes GitHub Issues │
└─────────────────────────────────────────────────────────┘

Wake-Up Mechanisms

MethodToken CostUse Case
openclaw agent --agent X --message "..." --jsonYes (full turn)Primary. Triggers a full agent turn via gateway.
openclaw agent --local --agent X --message "..."Yes (full turn)Embedded mode, no gateway needed.
POST /hooks/wake0 (until agent wakes)Remote triggers (CI/CD).
Dispatch note

openclaw system event was originally planned but does not exist as a CLI command. The dispatcher (beads-notify.sh) uses openclaw agent --message directly.

6. Agent Identity

Convention: agentId maps to BD_ACTOR + labels

Each OpenClaw agent uses two identity mechanisms in bd:

  • Actor (BD_ACTOR): Identifies who performs actions (audit trail, commit attribution)
  • Labels: Identifies what kind of work an agent handles (routing, filtering via bd ready --label)
Agent "pm"
├── SOUL.md → personality & communication style
├── IDENTITY.md → "I am the Product Manager"
├── BD_ACTOR=pm → audit trail identity
└── labels: pm → watcher routes beads with label "pm" to this agent

Agent "dev-fe"
├── SOUL.md → personality & communication style
├── IDENTITY.md → "I am a Frontend Developer"
├── BD_ACTOR=dev-fe → audit trail identity
└── labels: dev, frontend → watcher routes matching beads here

Actor Resolution Order (bd CLI)

  1. --actor flag (per-command override)
  2. BD_ACTOR environment variable
  3. BEADS_ACTOR environment variable
  4. git config user.name
  5. $USER environment variable
  6. "unknown" fallback

Work Discovery

Agents find their work via label filtering, not actor matching:

bd ready --label dev --json          # What's ready for dev role?
bd ready --label pm --json # What's ready for PM role?
bd ready --unassigned --json # Unclaimed work across all roles

7. Architecture Decisions

#DecisionRationale
AD-1Watcher: System cron now, plugin laterSimplest tier. 15 lines of Bash suffices for prototype. Plugin only when dynamic agent list or lifecycle management is needed.
AD-2Identity: BD_ACTOR + label routingActor for audit trail, labels for work routing. Aligned with bd CLI identity resolution.
AD-3Human UX: Dashboard + ChannelDashboard (bdui/beads-dashboard) for overview. OpenClaw channels (Telegram/Slack) for quick interaction. Both come "for free".
AD-4Topology: Shared intercom cloneSingle Dolt database on host, bind-mounted into all containers. Agents use bd directly — no import/export. Watcher serializes execution and handles GitHub sync.
AD-5Interface: CLI bd via exec toolSimplest start. All community patterns built on CLI. MCP server only if OpenClaw gains native MCP client support.
AD-6Dispatch: Tier 1 label routingZero tokens for routing. No agent ever polls. Watcher reads bd ready --json, groups by label, wakes the right agent.
AD-7Beads vs. GitHub: Separate worldsBeads = internal Slack. GitHub Issues = official tickets. No sync. Manual references where needed.
AD-8Sandbox: all agents containerized, ludus-ownedAll agents (including main) run in Docker sandbox containers. Custom images extend OpenClaw base with bd CLI. ludus ops provision handles Docker CE + gateway; Ludus owns all agent registration, sandbox config, and images.

8. Implementation Phases

Phase 1: Shell Prototype (M1-M5)

Validate Beads workflows without OpenClaw dependency. Each milestone is a shell script that passes or fails.

MilestoneGoalValidation
M1Beads repo + two rolesbd ready --label dev --json shows correct beads
M2Watcher routes by labelWatcher outputs WAKE dev for labeled beads
M3Simulated agent loopEnd-to-end: create, watch, claim, close
M4Agent-to-agent commsComments (questions/answers) + follow-up beads (delegation). bd mail skipped (requires Gas Town).
M5Multi-project labelsRouting by project + role label combination

Phase 2: OpenClaw Integration (M6)

  • beads-notify.sh dispatcher handles notify-and-pull wake-ups
  • WAKE lines mapped via label lookup in agents/agent-map.json to openclaw agent CLI calls
  • Agents use SOUL.md for personality + bd CLI via exec tool for bead lifecycle
  • 19 acceptance tests with mocked openclaw CLI (no LLM tokens in CI)

Phase 3: Production Readiness

  • Community dashboard deployment
  • Langfuse/OTel integration for token tracking
  • Natural language Beads interaction via OpenClaw channels
  • Beads data retention policy (ephemeral cleanup)

References