magus v0.4.3 is out. See what's new
¶ View markdown source · ✎ Suggest an edit
22 min read

Development

magus gopher mascot

CI CD Go coverage Buzz coverage TypeScript coverage Go Reference

A fast, cross-platform task orchestrator for polyglot monorepos. One binary, no second toolchain to install. Targets are programs, not YAML.

Change a file and magus works out which projects it reaches, rebuilds only those, and caches every result so the same work never runs twice.

magus informs; it never decides. It hands you everything it knows about your repository (what a change reaches, which files are generated, where a symbol is used) and the call stays yours. It was built for humans, not for agents: agents drive it well anyway, because an interface legible to a person is legible to anything, and that ordering is the design.

Terminal recording: magus ls lists five projects, magus run ci runs lint, build and test across all of them reporting '0 cached, 5 ran', the same command run again reports '5 cached, 0 ran' having replayed every result from cache, and finally one file is edited and magus affected ci narrows to two projects, the edited library and the app that imports it, reporting '0 cached, 2 ran'.

One command, three runs: cold, fully cached, then narrowed to what a change reached.

Who this is for

Repos with more than one language, or CI that reruns work a change never reached. One project works too.

The tradeoff: you declare what each target reads and writes, and magus stops when a run disagrees. A few lines in a magusfile buy a build you can debug without knowing how magus works inside.

More: the knowledge graph, targets, agents, and the longer argument in I think our tools are the problem.

How it works

Five ideas carry most of the tool. Each has a deeper page; this is the short version.

Affected sets

magus keeps a dependency graph of your projects and knows which files each target reads. Change a file and magus affected <target> runs only the projects that change can reach, in dependency order. magus affected ci runs the full pipeline over that set, so CI does the least work a change requires and still catches breakage in a project you never opened. See CI.

Content-addressed caching

Every target declares its inputs and outputs. magus hashes the inputs, and if it has already seen that hash it replays the stored output instead of running the work again. The cache is a plain content-addressed store on disk (SHA-256): the input hash is the key, and the stored outputs are addressed by their own content hash, so a replay is a byte-for-byte reproduction of the recorded run.

The knowledge graph

Most tools that offer you a codebase graph are observers: a separate indexer scans the repo, infers the structure, and can be wrong in ways nothing warns you about. magus is not observing: it is the thing that builds the repo, so it already has to know every project, every target's declared inputs and outputs, and what a diff reaches, and getting any of that wrong breaks builds loudly. The graph is that same knowledge handed back: a byproduct of being the source of truth, never an inference about it. No LLM pass, no fuzzy linking; every edge traces to a declaration you can open.

magus query "kind=target lint" finds nodes, magus explain <node> shows a node's edges and what reaches it, and magus refs <symbol> lists where a symbol is defined and used from a SCIP index.1 The same graph answers "is this file generated," "what does my diff touch," and "how do these two things relate" without grepping. See the knowledge graph, including what this graph deliberately is not.

One vocabulary

magus names a thing once and reuses the name everywhere, in the CLI, the config, and the graph. A target is a unit of work such as build, test, or lint. A spell is a language adapter that supplies a target's operations (the go spell provides go-test; the buf spell provides buf-lint). A charm is a modifier applied to a run, like rw for read-write or cd for continuous delivery. An op is a single tool invocation. Learn the four words and the rest of the surface reads the same way.

There is a terminal UI. It stays out of your way

Terminal recording of an interactive magus session: a run draws a pinned box at the bottom of the terminal showing pool slots and a live count while ordinary output scrolls above it; a failing run pins its failures as a tree grouped by project, with the selected failure's captured test output shown in a second column beside it; tab swaps which of the two views is larger; and magus x opens a picker that searches the knowledge graph as the filter is typed.

A run pins its progress, failures group by project beside their output, and the picker searches the graph as you type.

The band at the bottom holds still while your output scrolls past it. Nothing is cleared, the alternate screen is never touched, and your scrollback survives - so selection, copy and paste keep working the way they always did. Every one of these surfaces degrades to plain text when there is no terminal to draw on.

Non-goals

  • No remote execution. magus caches results and shares them. It does not run your work on someone else's machine.
  • No toolchain management. magus compares what ran against what you declared and stops. It will not select, install or switch a version.
  • No hermetic sandbox. The sandbox is a supply-chain defense, off by default, with no kernel layer on macOS. It will not fail a build on an undeclared read.
  • No container isolation. Steps run on the host. The container charm changes what a target produces, not where it runs.
  • Small ecosystem. magus is young and mostly one person's work, so you will hit behavior nobody has hit before you. It is one Go binary and one Buzz file, both of which you can read.

Scope says why each line is there; Sandbox covers the third.

Getting started

Install

magus ships as a single self-contained binary, so there is no second toolchain to install.

curl --proto '=https' --tlsv1.2 -sSf https://eli.gladman.cc/magus/install -o install.sh
less install.sh
sh install.sh

Reviewing the downloaded script before executing it lets you audit the URL, verification, and installation steps instead of piping an unreviewed network response directly to your shell. See the Install guide for platform details, verification, and updates.

A first look

magus targets are written in Buzz, a small typed scripting language it embeds. A magusfile.buzz at the repo root declares your targets as exported functions: each one composes operations from the spells you bind:2

import "magus";
import "magus/spell/go";

magus\project({ "spells": [go] });

// Every exported function is a runnable target. It receives a magus\Context,
// the handle it uses to declare what it needs and hands to every op it runs.
// magus caches each target's result and runs it only when a change reaches
// this project.
export fun build(ctx: magus\Context, args: [str]) > void { go["go-build"](ctx); }
export fun test(ctx: magus\Context, args: [str])  > void { go["go-test"](ctx); }
export fun lint(ctx: magus\Context, args: [str])  > void { go["golangci-lint"](ctx); }

// format is read-only by default: go-fmt reports files that need formatting, and
// go-mod-tidy runs with --diff so it fails if go.mod/go.sum have drifted. They take
// DIFFERENT write charms, because they are not the same risk. gofmt is offline, so
// the same tree always yields the same bytes: `magus run format:rw` rewrites the
// code. Tidy resolves against the module proxy, so what it writes depends on what
// upstream serves today; that is a second, deliberate ask:
//   magus run format:rw          formatting only; go mod tidy still just reports
//   magus run format:rw,update   also let go mod tidy amend go.mod and go.sum
export fun format(ctx: magus\Context, args: [str]) > void {
    go["go-fmt"](ctx);
    go["go-mod-tidy"](ctx);
}

// 'ci' is the anchor `magus affected ci` keys off: it composes the pipeline
// by declaring the targets it needs.
export fun ci(ctx: magus\Context, args: [str]) > void {
    ctx.needs(build, test, lint, format);
}

Point magus at that repo and each command returns an answer and stops:

magus ls                                  # which projects exist
magus run test                            # run a target, cache the result
magus affected ci                         # the pipeline, over only what your diff reaches
magus query "kind=spell"                  # what the graph knows
magus describe file docs/gen/index.html   # is this file generated, and by what

Nothing here plans a workflow or decides for you. magus describe file tells you a path is a generated output so you skip its diff; magus affected ci tells you which projects a change reaches so you run no more than that.

Architecture

One process (magus server start) exposes the workspace through two standing listeners, one per audience, and every browser page is a separate static asset; the binary serves no HTML. A third listener is raised only on demand: "share to phone" opens a time-boxed LAN listener that serves the read-only console to a phone on the same network, then tears itself down.

Four figures, one subject each. They were one flowchart until it carried roughly thirty-five boxes, which is the point at which a diagram stops being read and starts being skipped.

The HTTP surface

Agents and the console share one guarded front door: a DNS-rebind check, a bearer token and a CORS policy sit in front of /mcp, /api/v1, the Connect services and the share endpoint. The health endpoints are the deliberate exception, so a probe never needs a credential.

The HTTP surface, and the one route without a guardAgents and the console reach /mcp, the /api/v1 read views, the review and plan routes and eleven typed Connect services through the DNS-rebind, bearer-token and CORS guard. POST /api/v1/diff/session carries the human half of a paired review and POST /api/v1/share opens the LAN listener; both are loopback only. The health endpoints answer probes directly, with no authentication.MAGUS SERVERThe HTTP surface, and the one route without a guardUNGUARDEDCLIENTAI agentsClaude Code, IDECLIENTConsole PWAdashboard, reviewCLIENTkubeletscripts, probesGATEGuardrebind + token + CORS/mcpagent tools, SSE/api/v1 read viewsgraph, events, insight, outputs/api/v1 review + plansdiff, session, plan, reviewConnect RPCeleven typed services/livez /readyzno authenticationAUTHENTICATEDOPEN TO ANY CALLER

The local path

A CLI invocation never goes over HTTP. It dispatches across a private unix domain socket into the concurrency pool and the three registries the server keeps warm. Sharing a graph is the one case that spawns a separate short-lived loopback server.

How a local command reaches the serverThe magus CLI dispatches over a private unix domain socket into the concurrency pool, the workspace registry and the run registry; shared services go to the broker. Sharing a graph spawns a separate short-lived loopback server.MAGUS SERVERHow a local command reaches the serverDISPATCHSPAWNSSHELLmagus CLIrun, status, queryIPCUnix socket0700, internal/procConcurrency poolWorkspace registrygraph, SCIP, cacheRun registrylive runsBroker clientshared servicesLoopback servergraph export --openSHARED SERVER STATESPAWNED ON DEMAND

What keeps it warm

File watchers, the SCIP auto-indexer and a coalesced graph-build job all exist to keep one thing current: the workspace registry, which holds the server's only warm copy of the knowledge graph.

What keeps the warm workspace currentFile changes drive the watchers and the SCIP auto-indexer; a magus run queues a coalesced graph-build job. All three write into the workspace registry, which is the server's single warm copy of the knowledge graph.MAGUS SERVERWhat keeps the warm workspace currentQUEUESINVALIDATESYMBOLSREBUILDINPUTSource filesmagusfiles, codeINPUTmagus runany invocationJOBFile watchersinternal/file/watchJOBSCIP indexersymbol indexJOBGraph buildcoalesced, asyncSTATEWorkspace registrythe warm graphOUTSIDE THE SERVERTHE ONE WARM COPY

Sharing to a phone

The LAN listener is the only part of magus a second machine can reach. It is minted by a loopback-only endpoint, time-boxed (fifteen minutes by default), carries a read-only token, and serves no MCP, share or mutating route at all.

The only listener a second machine can reachSharing from the dashboard posts to a loopback-only endpoint, which mints a time-boxed read-only token and opens an ephemeral LAN listener. The listener serves four JSON read routes and the read Connect services, and nothing else: the graph, the diff routes, the derived plan, the job store, /mcp and job control stay loopback only.MAGUS SERVERThe only listener a second machine can reachSHAREMINTS TOKENREAD-ONLYSERVESSERVESPWAConsoledashboardROUTE/api/v1/shareloopback + bearerEPHEMERALLAN listener15m, read-only tokenCLIENTPhone on the LANsame-origin viewerShared read routesevents, insight, outputs, outputShared Connect readsstatus, activity, metrics, insightNever on a sharegraph, diff, plan, job, /mcpREACHABLE OFF-MACHINESERVED ON A SHARELOOPBACK ONLY
How to read the diagram

The colors group the system by role, and each region is tagged with the Go package or project that owns it, so the diagram doubles as a code map: the runtime is the root module (cmd/magus plus internal/*), the browser console is the docs/ project, and the wire contracts are the proto/magus protobufs.

Green is the Unix domain socket, the local control plane: it dispatches magus run/magus affected into one shared concurrency pool, answers magus status, and adopts nested magus calls. Fast and private (0700); the local CLI and the liveness/readiness probes use it.

Orange is the HTTP server on mcp.address, for clients that cannot reach a Unix socket. It carries MCP for agents at /mcp, the read-only /api/v1 console routes, Connect services for metrics and the activity trail, and one bearer-gated job-control service for maintenance jobs (the server's only mutating surface). Its request and response types are the proto/magus protobufs, generated by buf and served over Connect/JSON.

Red is the guard chain every HTTP route but health passes through: a DNS-rebind host check, a bearer token (the cli token plus named connector tokens), and CORS scoped to the site and loopback origins.

Yellow is the health routes, left unguarded so a kubelet can probe them; they answer by querying the same socket. See container probes.

Purple is shared, warm server state: the knowledge graph and SCIP index in the workspace registry, plus the runs, services, metrics, and trail registries, and the graph's own declared inputs and exports.

Indigo is the background jobs that keep that state fresh without a foreground command: file watchers invalidate the warm graph and push an SSE event to the console, a throttled SCIP indexer keeps symbols current, and a branch switch fires the git hook, which submits one coalesced graph-build job over the socket.

Teal is the browser console, five static apps on the server, covered in The browser console below.

The graph itself is assembled from declared sources as shards (the magusfile registry, docs, @symbols from SCIP, @vcs from git history, CODEOWNERS). magus graph export -o json writes the graph data copied into the console's offline demo, and magus describe graph -o markdown writes the MAGUS.md routing index; live, the server serves the same graph byte-identical at /api/v1/graph.

Because the two listeners are separate, they can diverge: the socket can be healthy while the HTTP/MCP endpoint failed to bind, which is why magus status reports each one on its own line.

The browser console

magus is fully featured from the terminal, so everything here is optional. Alongside the CLI, the server can drive a set of read-only browser apps.

Want to see it first? Open the live demo: no install, no server. It fills the dashboard with synthesized activity, streams a build into the log viewer, and lets you jump between every app in demo mode. Everything below runs against your own server instead.

The apps

The apps ship as one console; each link below opens it on the matching app.

Dashboard
Dashboard
Pool, cache and server health, live
Graph Explorer
Graph Explorer
Targets, spells and their dependencies
Log Viewer
Log Viewer
Any run's captured output, streamed or replayed
Activity Trail
Activity Trail
What agents did, and when
Diff
Diff
Review the working tree, paired with an agent
The dashboard's work plan
Work plan
Who holds which lease, and where two of them overlap (press p)
The dashboard in Big Picture
Big Picture
The same dashboard with the console's own chrome gone, for a wall display (press b)
Diff on a phone
Diff, mobile
The file index folds to a rail; split view falls back to unified
Log Viewer on a phone
Log Viewer, mobile
The waterfall keeps its drawn size and scrolls, rather than shrinking its labels away
Dashboard on a phone
Dashboard, mobile
Tiles stack, the rail gives way to the launcher grid, and controls take a 44pt touch target
  • Dashboard shows live server health, the concurrency pool, running targets, cache activity, and the live lease plan.3
  • Graph Explorer navigates targets, spells, and their dependency graph (magus graph export --open).4
  • Log Viewer reads or streams any past run's captured output (magus query output <ref> --open).5
  • Activity Trail shows recent MCP calls, agent-command observations, background jobs, and config changes.6
  • Diff annotates the working tree's uncommitted changes (generated vs source, blast radius, coverage) and hosts the human half of a paired review.

How it stays on your machine

These are add-ons, not a runtime you depend on. Two decisions keep them that way.

The binary embeds no UI

magus never embeds a web server that ships a UI, and a released binary carries no pages: the console is a separate static site (rendered from docs/ at deploy time, hosted at eli.gladman.cc/magus, or self-hosted from any file server). What the server exposes over loopback is a small API: read-only views (/api/v1/...), one bearer-gated job-control service for maintenance jobs, and the MCP endpoint. It will also serve a console build you point it at on disk (console/gen, or MAGUS_CONSOLE_DIR) so you can host your own copy, but it ships none and 404s /console/ until one is built.

Your data never leaves the loopback

The hosted page talks only to 127.0.0.1/[::1], a loopback lock it enforces before any request, or it receives your graph inline through a URL fragment. Nothing is uploaded. You can drop the UI entirely: set console.enabled: false and the server runs fine without it, serving no browser API at all. See the Console reference.

Working with AI agents

A tighter feedback loop does more for an agent working in your code base than a larger model does, and most of that loop already exists: the build, test, lint, format, and cache scripts you wrote so developers could set up an environment. magus is the hookup. Those same scripts become what the agent runs, deterministic and fast.

magus treats an AI agent and a new teammate as the same kind of user: someone who cannot yet trust their guesses about the repo. It ships an agent surface built on the knowledge graph, so an agent asks magus instead of grepping and guessing.

  • Installable skills teach an agent to query the graph, run work through targets, and triage generated files. For Codex, run magus agent install .agents/skills and paste the always-on AGENTS.md block it prints. Claude Code uses .claude/skills; there is a setup page per host behind Agents.
  • The committed MAGUS.md is a routing index, regenerated from the graph, that points an agent at the exact query for a given question.
  • The MCP server the server exposes lets an agent call magus tools directly over the protocol rather than shelling out.7
  • The guard hook judges a command or a write before an agent runs it, from rules that live in the binary rather than in per-host integration code. The host-shaped wiring is a template you copy and own, so a host magus has never heard of gets the same rules, and one that changes its hook surface next month is your few-line edit instead of a magus release. Doctrine records why it works that way.

Full detail, including which tools exist and how to connect, is on the Agents page.

Documentation

Full docs live at eli.gladman.cc/magus.8 The major sections:

Inside a workspace, the entry point is the committed MAGUS.md: a generated routing index of the workspace's projects, targets, and the exact knowledge-graph queries that answer questions about them. Projects can carry their own (this repo commits one for docs/ and for each project under libs/), scoped to that project. They are generated by magus describe graph -o markdown via the generate target; regenerate them, never hand-edit.

Development

magus is built and tested by magus, so this repository is a magus workspace like any other. That means parts of the contributor reference are generated from the workspace's own graph rather than written, and can show things a hand-maintained page cannot:

  • Project catalogs: one page per project: every runnable target, what it depends on, which toolchains it drives, and a run-order diagram built from the real ctx.needs edges.
  • Workspace dependencies: the projects in dependency order, with each one's blast radius: how many projects a change there can reach. Read it before you touch libs/gopherbuzz.
  • Contributing guide: the conventions worth knowing before opening a pull request, including the benchmark-evidence rule for performance changes.
  • Configuration reference: the magus.yaml keys and the MAGUS_* environment inventory.

The architecture diagram above tags each runtime component with the package it lives in, which is the quickest map of where code goes.

Building from source

magus builds magus, so the binary comes out of a magus target like anything else in this workspace:

mise install              # the pinned Go, Node, and esbuild
magus run go-build .      # writes ./magus

go-build regenerates the compiled built-in spells before it links, so the binary never embeds stale bytecode. It is the target to use over build, which also runs the format and image stages.

Do not have a magus yet? Install a release and point it at your checkout: then every build after that is the command above.

Failing that, a clone with no magus and no release can bootstrap one with Go directly. This is the only place a raw go build (or go run) belongs, and only to produce the binary that runs everything after it:

GOEXPERIMENT=jsonv2 go run ./cmd/magus run go-build .   # bootstrap only

GOEXPERIMENT=jsonv2 is not optional: mise.toml sets it for this repository, so a build without it differs from every other build here and shows up later as generated-file drift that is not yours.

Running the tests

Run the tests through magus itself, since the whole point is that magus builds and tests magus:

magus run ci

  1. SCIP is Sourcegraph's code-index format. magus indexes on its own once a project uses the scip op, stores the index in the cache, and refreshes it in the background; the knowledge graph page covers the symbol layer and the @symbols shard. ↩︎

  2. Magusfiles are written in Buzz. You can run it in your browser, no install, at the Playground; the standard library modules are the API reference. ↩︎

  3. What the tiles mean, and the metrics behind them: Telemetry and the server page. ↩︎

  4. The same graph the CLI queries, drawn. See magus graph for the verbs and knowledge graph for the schema. ↩︎

  5. A run's output is addressed by a short reference ID, which is what <ref> is above. See output references. ↩︎

  6. The trail is the server's own record, kept in memory per workspace. See the server page. ↩︎

  7. Tool list, transport, and how to connect an agent: MCP. ↩︎

  8. Source: docs/. ↩︎

readme
Last updated (95680f58)
Earlier changes on this page (7)

Full history ↗ · Blame source ↗

Glossary

Glossary

The vocabulary that runs through the rest of the docs. Each entry is a short definition; follow the link for the page that covers the term in depth. Every term has its own anchor, so you can deep-link a single definition (for example glossary/#output-reference).

Core model

Workspace

The magus root directory that owns a set of projects and shared config; the unit magus operates over. See workspace.

Project

A directory magus recognizes as a unit of work (it has a magusfile); the unit of caching, scheduling, and dependency tracking. See workspace.

Magusfile

The magusfile.buzz that declares a project's targets (as export funs) and binds its spells. See targets.

Target

A named operation (build, test, ...) you invoke with magus run <target>; it may compose a spell's tool-native operations and depend on other targets. See targets.

Op

A single tool-native command a target composes (long form: operation); the middle of the work hierarchy (Spell to Op to Target). See operations.

Spell

A language/runtime adapter (e.g. go, md) that maps generic targets onto a toolchain's real commands. See spells.

Charm

An execution modifier attached with : (lint:rw) that changes how a target runs, not which one; the built-in rw flips a check-only target to mutate in place, and ci always strips it. See charms.

Ward

A coded diagnostic that inspects a resolved op and nudges or blocks an anti-pattern before it runs. See wards.

Module

A magus stdlib namespace a magusfile imports for host capabilities: filesystem, exec, vcs, and more. See the module reference.

Buzz

The language magusfiles are written in (the .buzz engine). See engines.

Engine

The interpreter a magusfile runs on; magus embeds the Buzz engine. See engines.

Execution and caching

Cache

The content-addressed store magus consults before running a target, so unchanged work is skipped. See cache.

Affected

The set of projects touched by a change; magus affected <target> runs a target only over them. See affected.

Sandbox

The restricted filesystem and environment a target runs in, so builds stay reproducible and side-effect-free. See sandbox.

Service

A long-running or shared process magus manages across runs, distinct from a one-shot target. See services.

Broker

The per-user background process that holds this host's capacity: the machine budget every run claims slots from, and the shared services runs keep warm. A run starts it on demand; broker: off in magus.yaml runs without one. See server.

Server

The background process a person starts with magus server start. It serves MCP, the console, background jobs and the warm knowledge graph, and adopts nested magus calls into one pool. See server.

CI

An ordinary magusfile-defined target you compose yourself with magus\needs - magus does not hardcode its stages. Magus.RunCI treats it specially only in that it strips the rw charm, it is the anchor magus affected ci keys off, and a selected scope with no project declaring it is a load error rather than a silent no-op. See targets.

Output reference

A short, shareable id (out1a2b3c, "ref" for short) for one target execution's captured output; it appears on each target's line, and magus query output out1a2b3c prints those exact bytes. In OpenTelemetry terms it corresponds to a span (one target execution) within its trace (the whole magus invocation). See output-refs.

Trace

OpenTelemetry's name for one whole magus invocation; every target it runs is a span beneath it. See telemetry.

Span

OpenTelemetry's name for one unit of work under a trace - a target execution, whose sub-operations are child spans. An output reference points at a span's captured output. See telemetry.

Pool

The concurrency pool: the shared set of slots that caps how many targets run in parallel on one machine. Its capacity defaults to MAGUS_CONCURRENCY, then 4 on GitHub-hosted runners, then min(NumCPU, 8); magus status and the dashboard report it live. See server.

Slot

One unit of the pool's capacity. A target acquires the slots it needs to run (most take one) and releases them when it finishes; the pool tracks capacity (total slots), running (acquired), and queued (blocked). See server.

Concurrency

How many targets run at once. It is bounded by the pool's capacity and set with --concurrency, MAGUS_CONCURRENCY, or the concurrency config key. See server.

Queued

A target that wants a slot while the pool is full; it blocks first-in-first-out until a slot frees. The dashboard colors a sample with queued > 0 accordingly. See server.

Pool mode

Which pool a run uses: server (one shared pool the server owns across every workspace and client) or proc (a per-process pool for a single one-off invocation). See server.

One-off

A single magus invocation that runs a target and exits, using a per-process pool; the opposite of the long-lived server or a service. See server.

Remote cache

A CI-only backend that shares content-addressed artifacts across runners: a cold machine replays a build another runner already did instead of rebuilding. Every remote artifact must be signed by a trusted key. See remote.

Snapshot

A point-in-time view of live state - the pool's occupancy or a tick of exported metrics - as opposed to accumulated history. See server.

Backfill

The recent history the server replays to a dashboard on connect, so its charts start populated instead of empty. It is served from a bounded ring buffer of the last few hundred samples. See server.

Telemetry and health

Latency

How long an operation takes. magus records latency as OpenTelemetry histograms per family - target execution, cache op, pool wait, and graph query - and reports each as a count, sum, and percentiles. See telemetry.

Percentile

A latency value at a given rank, interpolated from a histogram's buckets: p50 is the median, p95 and p99 are the tail that most latency budgets care about. See telemetry.

Health

The at-a-glance server state derived from the pool: healthy when the pool is reporting, degraded when it reports an error, down when there is no pool. The dashboard color-codes each state. See server.

Volatility

A target that fails once and passes on rerun is volatile, as opposed to a regression that started failing and stays failing. magus keeps per-target pass/fail history and a Wilson-score volatility rate to tell them apart and auto-retry the noise. See volatility.

Insight and knowledge

Knowledge graph

The queryable graph of a workspace's spells, targets, docs, and code relationships; query it with magus query/explain/path. See knowledge.

MAGUS.md

The committed routing index at a workspace root, regenerated from the knowledge graph: it lists every node and points at the exact query for a given question, so it is the entry point an agent reads first. See knowledge.

Insight

The reports magus derives over the graph and history (hotspots, affinity, ownership, trend, volatility, unreferenced). See insight.

Hotspot

An insight lens: edit frequency times complexity, the prime refactoring targets. The project view heat-colors the dependency graph by churn; --files ranks individual files. See insight.

Affinity

An insight lens: projects that change together (temporal coupling). A pair that co-changes without either declaring a dependency on the other is a candidate architectural smell. See insight.

Ownership

An insight lens: author concentration - the primary author and their share, the distinct-author count (the bus factor), and abandonment. See insight.

Trend

An insight lens: the recent half of the window against the earlier half. A positive delta is a rising hotspot; a negative one is cooling. See insight.

Diagnostic code

A stable MGSxxxx identifier attached to a magus warning or error, so it can be referenced and looked up; some are guardrails (see wards), others hard errors.

Design and scope

Two rules named often enough elsewhere to need a definition of their own.

Scope test

The question every proposed capability has to answer: does it read the model magus already had to build, or does it make magus learn something new about the world? Reads stay small; acquisitions are where a tool loses its shape. See scope.

One-vocabulary rule

Each concept gets one name, used everywhere: target, spell, charm, op. A second word for the same thing is a house dialect, and it costs every reader (and every agent) a lookup that never ends. See doctrine.

Sessions and leases

The vocabulary of magus watching work happen: who ran what, what an agent is blocked on, and which agent owns which paths. The policy behind these terms lives in doctrine.

Session

An agent host's conversation, by the id the host delivers to its hooks. magus never mints one: a record with no session is unattributed, and the OS user it carries says whose account ran it.

Invocation

One magus process's recorded facts - the targets it finished, their outcomes, the lease it acted as, and the session it ran in when a host delivered one - kept in a repo-scoped store every worktree shares. magus session lists them; the store prunes itself by last-fact age.

Window

The terminal a command runs in. It keys fire-once notices for a caller no host gave a session, and is never recorded as a session.

Attention request

A durable "an agent is blocked" record, opened when a magus session notify event carries the waiting or permission outcome and held until a person disposes it. magus session attention lists what is open. Nothing closes one on its own - see doctrine.

Dispose

The human act of closing an attention request: a judgment rendered, recorded with who and why. Distinct from resolving a review thread or a merge conflict - a disposition answers a request; it does not merge anything.

Job

The unit of delegated work, and one row of the job store: what an orchestrating agent handed out, with its goal, the checkpoint it was cut against, the paths it may write or must not touch, and the one check it runs. A job's holder is either a session, for work an orchestrator handed out, or the server, for its own maintenance. The store records; the agent guard is what reads those facts back when grading a write. See doctrine.

A job is not a run. magus run build web is a run, and no job exists for it. A job causes runs: its check executes as one, and a server job records the invocation of its last one. Jobs are listed with magus ls jobs and in the console's Jobs view; runs are listed in the Runs view.

Run

One target executing under one magus invocation, such as magus run test web or magus affected ci. A run keeps its captured output behind an output reference. Every magus run is a run whether or not any job asked for it; see Job for how the two relate.

Lease

The grant a holder takes on a job: the write and read paths that job declared, enforced in the checkout that took it with magus job exec. A job is the piece of work; a lease is permission over it.

Lease id

The short identifier a worker carries (the --lease flag, or the magus.lease member of the W3C BAGGAGE environment channel) so its runs, journal facts, and guard verdicts attribute to the job it holds. Letters, digits and -_./: only.

Spawn claim

What a spawning tool said about itself in the environment: TRACEPARENT (the W3C trace and the parent span this process runs under) and the magus.spawner baggage member (a label for whoever spawned it). magus records each verbatim beside the invocation's own minted span id, and no verdict reads any of them - the ancestry is a relation between recorded invocations, the way a process tree is a relation between pids.

Advisor

One read-only check from the advice suite: it reads the changeset through magus and writes one titled section of findings. The same advisors run as a pull request comment in CI and inside magus diff --impact locally.

Console

The vocabulary of the browser app. These terms name things you only meet in the console's UI, so they are defined here rather than left to be inferred from it.

Console

The browser app that reads a magus workspace: a tabbed, tiling page hosting the log viewer, graph explorer, dashboard, and activity trail. It is a separate static app, not something the server serves - the server exposes a loopback API it calls: read-only views plus one bearer-gated job-control service for maintenance jobs. See reference/console.

Console app

One of the console's applications (Runs, Log Viewer, Graph Explorer, Dashboard, Activity Trail, Settings). "App" rather than "page" because one is never a document you navigate to: it is mounted into a tab, or into a pane beside another one. Each is single-instance - opening one you already have focuses it instead of duplicating it.

The glossary term is two words on purpose. As a bare "App" the auto-linker matched every unrelated "app" in the docs - a ChatGPT desktop app, a Postgres app - and pointed each at this definition. See reference/console.

Pane

A split within a tab. Splitting divides the focused pane along its longer side, so the same action tiles side-by-side on a desktop and stacks on a phone; a tab with no split is a single pane. Drag the divider to re-weight the split. See reference/console.

Chord

A key combination bound to a console command, written mod+k - where mod is Cmd on macOS and Ctrl elsewhere, so one binding fits both. Every chord is rebindable (Settings > Keybindings), and a command remains reachable from the command bar whether or not it has one. See reference/console.

Command bar

The console's runner: one searchable list of every command and its chord, opened with mod+k. It is the discoverable route to any action - the menus and chords dispatch the same commands it does. See reference/console.

The URL that points an app at a running server. The server serves the console from its own loopback origin, so the link is that origin plus the app path and a bearer token in the fragment (http://127.0.0.1:7391/console/graph/#token=...). The server prints it; the console consumes the token, stores it, and strips it from the URL, so the secret never lingers in history or a copied link. The origin must be literal loopback - localhost and hostnames are rejected before any request. Without one, an app reads only what rides in the link itself. See reference/console.

See also

Conventions

Placeholders

Angle brackets mark a value you replace with your own - never type the brackets:

magus run <target>
magus completion <shell>    # e.g. bash, zsh, fish

<target>, <path>, <shell>, <name> and the like are stand-ins, not literal text.