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

Unix survives at the verb, not the binary

One tool that does one thing extremely well does not survive contact with a monorepo, and magus does not claim the lineage: a monorepo build tool has to understand several languages, every project in the tree, caching, scheduling, and what a change reaches. That is already many things. What survives the translation is the discipline, relocated to the verb. Each verb answers one question, deterministically, from declared sources, and stops. Output reads at a terminal and parses in a pipe (-o name, -o json, -o template=; the pipe is for people, and the agent guard routes an agent to -o instead, because a pipe replaces the exit status and a failing gate then reads as 0). A non-zero exit means what it has meant for fifty years. Everything magus draws degrades to plain text when there is no terminal to draw on, and the pinned band never takes the screen, the alternate buffer, or your scrollback. Composition happens where a monorepo needs it (in the graph, through ctx.needs), not by pretending the binary can be smaller than the problem.

The scope test governs what a verb may be, and the one-vocabulary rule (target, spell, charm, op, each named once and reused everywhere) keeps the command set predictable. That prevents the failure in both directions: claiming a minimalism the tool cannot carry, and the house dialect with no rule you can hold in your head, the one that makes users look things up forever and then teaches their agents the same confusion.

The discipline reaches the code too:

  • A main package only wires. A command parses its flags, builds its dependencies, calls a package and prints the result. Logic that computes belongs in the package that owns its data, where a test and a second caller can reach it.
  • One file until it is long. A concept stays in one file until that file passes 1500 lines; only then does R_<topic>.go earn a place beside R.go. A platform build, generated output and a test are their own files at any size.

Enforced by

  • The scope test, applied in review to every new verb.
  • The main-logic conformance metric fails a main-package function that computes without calling another workspace package; the ratchet (hack/policy/conformance.jsonl) lists the ones that predate it.
  • The file-split conformance metric fails a concept sibling that would fit in its root at 1500 lines or fewer, and moves with the file-lines ceiling.
  • The agent guard denies piping magus output and names the -o form instead.

Good

Ask the verb for the shape you want; the exit status stays the verb's.

magus affected ci --plan -o json
magus ls -o name

Bad

magus run test . | tail -n 20

tail exits 0 whatever the tests did, so a failing gate reads as a pass in CI and to an agent.

See also

designprinciplecliunix
Last updated (2df714e8)
Glossary

Workspace

The magus root directory that owns a set of projects and shared config; the unit magus operates over. Workspace in full.

Project

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

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. Target in full.

Op

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

Spell

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

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. Charm in full.

Affected

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

CI

An ordinary target you compose yourself with ctx.needs; magus does not hardcode its stages. It is the anchor magus affected ci keys off, and ci strips the rw charm. CI in full.

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. Scope test in full.

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. One-vocabulary rule in full.

Agent

A model working through an agent host such as Claude Code, Codex, Cursor or OpenCode. magus treats an agent as one more caller of its CLI, MCP tools and console, held to the same checks as a person. Agent in full.

Tool

An action a model can call through its host: a name, a description, a typed input and a result. magus serves its tools over MCP, each a read of the workspace model or a run of the CLI it already has. Tool in full.

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. Run in full.

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.