How it works
Every part is named for a crew role or a place on a ship at muster. The names are the same in the packages and on the command line.
The parts
One module, three process types
Muster builds three process types from one module and one version. The web process runs intake, the ops pages, health, metrics and the seat API. The worker runs the leader ticker, the shadow runner, the settings loop and the tally loop. Work that must run once holds a leader lease, so a second worker waits.
The client runs the seat runner and the tool call guard. It links no database package and holds no database credential. A rule in the tests fails the build if it does.
The roll: the event log
Events are appended and never updated or deleted, and database triggers refuse both. Each event has a source, a delivery id, a type and a schema version. The pair of source and delivery id is unique, so a redelivered event does nothing. Secrets are redacted from a payload before it is stored.
The gangway verifies and dedupes each webhook before it is recorded. The roll also keeps derived tables, which Rebuild can derive again from the log.
The bridge: a pure decision core
Reduce(state, event) returns the new state and orders. It does no input or output, reads no clock and draws no random number. It imports only the standard library, so it is tested by replaying recorded events.
Every order names the event that caused it and carries a rule name and a plain explanation. The classes of rule are dispatch, hold, precondition, cancel, operator request, issue intake and settings.
The signalman and the executor
The signalman applies orders to the tracker and the forge through ports. Each effect carries an idempotency key made from the order alone, so a retry never repeats it. A failed effect is kept, retried with backoff and parked after a set number of tries.
The executor is off by default. An order is sent only when its switch is on, its ticket is on the allow list, all-stop is not set, the spend brake allows it and no other executor holds it.
The bosun, berths and seats
The bosun supervises agent runs. A seat is one hand that runs one agent run. It claims a run through a lease, sends heartbeats, fetches its role bundle and reports the end. Berths are the work tables and leases, with one row for each role and ticket generation.
An expired lease can be claimed again. A failed attempt retries with backoff, and a row past its attempt cap is dead lettered. The seat API runs inside serve.
Roles: files that direct an agent
Roles resolve in layers when a run is claimed: project, then install, then base. The base set is embedded in the binary with ten roles: implementer, reviewer, investigator, db-engineer, docs-writer, infra-engineer, release-manager, security, sre and triager. A read only role never lists the edit or write tools.
A layer only adds. It cannot remove or weaken a safety rule or raise a sandbox tier. The project layer is read from the .muster folder of the repository.
Direction: a studio will let you edit roles and rulesets in the app. A role will extend a base role, and a ruleset will apply to all repositories, one repository or one role. A compiler will turn them into a committed, hashed .muster tree that reaches each repository only as a reviewed pull request, with the safety core still last and unweakened.
$ muster roles list
implementer Shipwright build
reviewer Surveyor read-only
Ports: four kinds of outside system
Muster talks to an issue tracker, a code forge, a model provider and an agent runtime. Each sits behind a small interface in internal/ports. The core never imports a vendor client. Every write takes an idempotency key, errors are typed, and each adapter has an in memory fake.
All traffic goes through one shared HTTP client with a timeout, retry with jitter, an ETag cache and a request budget. More on the ports.
Skiff: the worker image
The skiff is the worker image. muster skiff assemble turns a lockfile into an OCI image layout. Every file is pinned by digest, the same inputs give the same bytes, and the image holds no scripts or credential files. The seat loop claims one run, runs the agent runtime on it, reports and exits.
Shadow mode and the tally
Every five seconds the leader folds the roll's new events through the bridge and records the orders. Nothing goes to the tracker or the forge. Each recorded order has its cause, its rule, an explanation and an executed flag.
The tally reads the outside world, counts it against the roll and reports drift as events. It never edits state directly.
A real event
These are two event payloads, copied from the frozen shape files that the tests replay. The first is a review verdict from a reviewer run. The second is a ticket opened with a role label. The ticket key T-1 is a fixture.
{"ticket":"T-1","verdict":"changes_requested","generation":1}
{"ticket":"T-1","labels":["role:implementer"]}
The roll wraps each payload with its source, delivery id, type and schema version. A payload change needs an upcaster, a new shape file and a registry bump, and old shape files are never edited.
The record of why
The tagline says receipts: every order keeps its cause, and the whole trail from event to effect is on the gates page.