Skip to content

What is Legio?

Legio is a One Man Company framework — a coordinated team of autonomous AI agents built on the Claude Agent SDK (Python), organized like a Roman legion under Caesar's command.

A solo operator gets the output of an entire team — research, writing, coding, analysis — orchestrated through natural language via Telegram, with persistent context that survives restarts.

The Chain of Command

RoleLatin TermWhat It Does
YouCaesarThe human operator. Commands the system via Telegram.
OrchestratorLegatusRoutes messages, manages centuriones, responds when no specialist is needed. Holds its own Claude SDK session.
SpecialistCenturio (pl. centuriones)A task-specific agent. Each has a prompt file, MCP tools, and private notes. Created on demand.

When Caesar sends a message, the Legatus decides whether to respond directly or delegate to one or more centuriones based on @mentions. Centuriones work in parallel when multiple are addressed.

System Topology

How It Works

  1. Caesar sends a message in Telegram (free-form text or /command)
  2. Bot authenticates_caesar_filter verifies Telegram user ID + private chat
  3. OTP interception — if a destructive action is pending, the message is checked as a TOTP code first
  4. Legatus parses @mentions and routes accordingly
  5. If @mentionsdispatch to centuriones in parallel via asyncio.gather()
  6. If no @mentionsLegatus responds as the default voice using its own SDK session
  7. All messages (inbound + responses) are persisted to the Praetorium (SQLite)
  8. Responses are rendered from markdown to Telegram HTML via mistune v3
  9. Long responses are split at paragraph boundaries (4000-char limit per Telegram message)

Core Principles

Prompt Over Code

If behavior can be achieved through prompting, don't hard-code it. Code handles infrastructure, data models, and orchestration plumbing. Everything else — routing logic, response style, domain rules — belongs in prompts and edicta (standing orders).

Roman Vocabulary

Domain concepts use Latin terms. This creates an unambiguous vocabulary that can't be confused with generic programming terms:

ConceptLatinPluralMeaning
MessageNuntiusNuntiiImmutable frozen dataclass with UUID, sender, audience, timestamp
Message busPraetoriumSQLite-backed shared history with WAL mode and visibility rules
MemoryMemoriaPersistent filesystem storage (edicta, acta, commentarii)
WorkspaceCastraRuntime directory tree (prompts, data, configs)
Standing orderEdictumEdictaGlobal directive that all agents read before tasks
Shared knowledgeActumActaPublished outputs available to all agents
Private notesCommentariumCommentariiPer-centurio append-only journal
AuthorizationAuctoritasPending TOTP request for destructive actions

100% Test Coverage

Enforced via pytest --cov-fail-under=100. Every line of production code is tested. Security tests (@pytest.mark.security) run on every commit. Async tests use asyncio_mode = "strict".

Tech Stack

TechnologyRole
Python 3.11+Strict typing, X | None syntax, async/await throughout
Claude Agent SDKAgent orchestration via ClaudeSDKClient, MCP tool hosting via create_sdk_mcp_server
python-telegram-botCaesar's interface — handlers, filters, ApplicationBuilder
aiosqlitePraetorium message persistence with WAL mode and FOREIGN KEY constraints
mistune v3Markdown → Telegram HTML rendering with HTMLRenderer(escape=True)
pyotpTOTP-based authorization for destructive actions (timing-safe via hmac.compare_digest)
ruff30 rule families for linting — no print, no os.path, no bare except, security/bandit checks

Startup Flow

Project Stats

MetricValue
Pure production LOC~2,500
Test LOC~4,000
Test : Production ratio1.56 : 1
Test coverage100%
Source modules16 files across 3 packages
Ruff rule families30
Max file size350 pure code lines

Built with Roman discipline.