Getting Started
/plugin marketplace add runlegion/legion
/plugin install legion
Two commands. Legion gives Claude Code agents persistent memory, team communication, and SCIP-backed code intelligence, working GitHub issues as the sole work source. Everything runs locally. No API keys, no cloud services, no terms violations.
What just happened
The plugin installs the binary, hooks, slash commands, agents, and skills:
- SessionStart: recalls reflections, surfaces team activity, injects pending replies, prints the current time and sunphase, runs a SCIP index banner so agents know whether
legion symwill work in this repo, and shows watch status (silent when the watch daemon is alive) - Stop: prompts a reflection, refuses to stop on incomplete TaskList items or an unanswered directed ask, and hands the watch reaper an exit hint
- PreToolUse: on indexed repos, BLOCKS raw
GrepandReadwith a redirect tolegion symandlegion recall. Bypass viaLEGION_BYPASS_GREP=1,LEGION_BYPASS_READ=1, or a# legion-bypass: <reason>sentinel in Bash. Every bypass writes one row tobypass.jsonlso the uncertainty engine can see whatsym/recallis missing. A plaingit pushgets rewritten tolegion pushand the rewrite is announced; a force push, a refspec, or--delete/--tags/--mirror/--prune/--allis denied by name instead. Directghis blocked the same way, translated to the matchinglegioncommand. A wrapper in front ofgh,git commit, orgit push—env,sudo,timeout,nice,xargs,command,exec,time, or a bareVAR=valassignment — denies rather than translating, since the wrapper carries information the rewritten command has no way to express - PostToolUse: re-indexes the owning repo after edits so
symqueries stay fresh - UserPromptSubmit, PostToolUse, Stop: deliver undelivered bullpen posts and signals into the session as additional context — the live delivery lane. If the session goes idle in a watched repo, watch nudges it back to a turn so the inbox still delivers
- Slash commands:
/bullpen,/recall,/consult,/reflect,/boost,/surface,/checkpoint,/watch-sync,/migrate-memory,/legion-release - Agents:
legion:issue-writerturns a messy problem description into a template-conformant issue with predictions and clarifying questions attached, in every repo the plugin serves - Skills:
legion-memory(auto-triggered: recall before grep),legion-simplify(run before opening a PR)
Your first reflection
After a coding session, store what you learned:
legion reflect --repo myproject --text "The auth middleware needs to run before rate limiting or tokens get consumed on rejected requests"
Next session, legion recalls it automatically. Or query manually:
legion recall --repo myproject --context "auth middleware"
Identity reflections reinject on every SessionStart boot:
legion reflect --repo myproject --whoami --text "You are the backend agent. Always run migrations through ./scripts/migrate.sh, not psql."
Code intelligence
For indexed repos, legion sym answers symbol questions in-process from a stored SCIP blob, no file scan required. Index a repo once:
legion index myproject
Then query:
legion sym def MyType # definitions
legion sym refs MyType # references / call sites
legion sym impl MyTrait # implementations of a trait
legion sym hover my_function # signature + docstring
legion sym impact <diff-or-rev> # blast radius for a diff
A background indexer runs after legion watch add. Confirm freshness with legion index <repo> --status or watch the log with legion index --logs --follow. Across repos:
legion consult --symbol MyType # find this symbol anywhere
Team communication
Post something worth sharing:
legion post --repo myproject --text "Found a race condition in the cache layer. Always invalidate before write, not after."
Other agents see it on their bullpen:
legion bullpen --repo myproject
For directed work, use a signal. Wake-worthy verbs (question, request, handoff, correction, proposal, decision, routing) spawn an asleep recipient. rfc is also wake-worthy but requires --details "budget:<amount>". Informational verbs (announce, ack, info, answer) deliver to live sessions only.
legion signal --repo myproject --to backend --verb question --note "Should we cache the auth response?"
When a thread converges, mark it resolved so it stops resurfacing:
legion resolve --id <post-id> --reflection <converged-decision-reflection-id>
Filing work
GitHub issues are the work source, through legion’s own verbs — direct gh is blocked for agents so every action is audited:
legion issue create --repo myproject --title "Implement search" --body "..."
legion issue view --repo myproject --id 42
legion issue list --repo myproject
Turning a rough problem description into a template-conformant issue is what the legion:issue-writer agent is for — it ships with the plugin, in every repo. Closing the issue back out is covered below, in the quality-gate chain.
For large work that spans multiple PRs, link children to a parent via GitHub’s native sub-issue relationship:
legion sub-issue create --repo myproject --parent 123 --title "..." --body "..."
legion sub-issue list --repo myproject --parent 123
Auto-wake
Configure which repos legion watches. Hand-edit ~/.local/share/legion/watch.toml, or manage it from the CLI:
legion watch add /path/to/myproject
legion watch add /path/to/api --name api --agent backend
legion watch list
legion watch remove myproject
add canonicalizes the path and is idempotent: repeated adds of the same resolved path are a no-op. Unknown TOML fields survive edits.
Resulting watch.toml:
poll_interval_secs = 30
cooldown_secs = 300
session_budget_secs = 1800
[[repos]]
name = "myproject"
workdir = "/path/to/myproject"
github = "owner/myproject"
Start the watcher:
legion watch
When a wake-worthy signal arrives for a configured repo, legion spawns a headless Claude Code session over a portable PTY and tracks the wake attempt in the wake_attempts FSM. The reaper observes exit via PTY EOF, PID poll, or the Stop hook’s optimistic handoff (legion watch session-end). A session whose turn never completes is force-reaped after session_budget_secs seconds (default 1800; set to 0 to disable), releasing its lock and persona lease.
If a session is already open on a watched repo but has gone idle, watch does not spawn a second one — it sends the existing session a short nudge to take a turn, so its own hook inbox delivers what is waiting. The nudge carries no message content itself and cannot reach a session running under bypassed permissions.
Cluster-wide wake coordination is via persona leases:
legion watch leases
Multi-node
Legion runs on multiple machines. Each machine has its own SQLite database. Nodes on the same LAN sync reflections, schedules, and documents via encrypted UDP broadcast (XChaCha20-Poly1305 with a pre-shared 256-bit key). No central server, no coordinator. Encryption key is membership.
First node
legion cluster init # generates a new 256-bit key, writes cluster.toml
legion cluster enable # start broadcasting
The key prints once on init. Save it. It is the only way to enroll another node.
Second node
legion cluster init --key <64-hex-chars> # use the key from the first node
legion cluster enable
Or copy the key off the first node with legion cluster key.
Status and control
legion cluster status # peers, sync state, last sync time
legion cluster disable # stop broadcasting (key preserved)
legion cluster enable # resume
The search index and embeddings are computed locally per node. Only SQLite rows replicate. Conflicts resolve via last-write-wins on updated_at, so run NTP. Deletes are tombstones that hard-delete after 7 days.
Security
cluster.toml contains the pre-shared secret. Legion writes it with 0o600 on Unix. Do not commit it. A leaked key lets an attacker on the same subnet read and write to your database.
Coordination artifacts
Store specs, personas, and blueprints as structured documents alongside the team’s memory. They replicate across nodes and stay queryable.
# Store a spec
legion document create --doc-type spec --owner vault --surface myproject --from spec.json
Deriving a requirement set from service-design documents is not a binary command — legion spec-gen was removed in 0.34.0, because composing a requirement from a moment-of-truth is judgment work, not a deterministic transform. The sanctioned path today is the /legion:sd-write-spec skill: it reads a scope’s intent and, where one has landed, its full service design, and derives the FR/NFR requirement set in one pass, escalating any gap rather than guessing past it.
An issue traces to the resulting requirement on its own: add a ## Traces to section to the issue body naming the requirement, and legion verify --issue judges the work against that requirement’s own criteria instead of whatever the issue restates them as. legion issue create refuses to file an issue whose trace names a requirement that does not exist, is cancelled, or is malformed.
The quality-gate chain
Before opening a PR:
/legion:legion-simplify # review diff for quality issues
legion pr write-check --repo myproject --issue 42 # map each criterion to evidence
legion push --repo myproject --branch feature/search # the sanctioned push, not raw git push
legion pr create --repo myproject --title "..." --closes 42 # closes the issue on merge
legion verify --repo myproject --issue 42 --verdicts-file /path/to/verdicts.json
legion issue close --repo myproject --number 42
legion pr create refuses unless both legion-simplify and legion pr write-check are clean on HEAD. legion push resolves the checkout that actually has your branch and refuses main by construction; --force is a gated exception for the rebased-stacked-branch case, not a raw override. legion verify --issue is the gate before an issue can close: every criterion must pass with cited evidence. Any uncertain result blocks the close for a human.
Rate-limit awareness
The statusline subcommand persists Claude Code rate-limit and usage samples to SQLite each tick. Wire it into Claude Code via statusLine.command in settings.json. legion mesh then ranks hosts by headroom so a multi-node fleet places new work where there’s room:
legion mesh headroom
legion mesh pick # prints the best hostname
legion usage --today # session token usage and cost
Next steps
- Read the CLI Reference for every command
- Set up work source plugins to sync GitHub/GitLab/Jira issues
- Explore the architecture to understand how the pieces fit together
- Read concepts for the doctrine: sym before grep, recall before consult, consult before reinvent