Skip to content

Installing Majordomus

installing the tool: the one-line installer, pinning a version, choosing where it goes, the supported platforms, upgrading, uninstalling, CI use, the security model and troubleshooting

Rendered from docs/INSTALL.md — the same Markdown GitHub shows.

Quick install

curl -fsSL https://majordomus.dev/install.sh | sh

Then, in the repository you want supervised:

majordomus init

init adds what the layer needs and leaves what the repository already has alone. The one exception is a README.md that does not mention AGENTS.md: init appends a short paragraph naming it, because doctor fails a README that cannot lead a reader to the agent bootstrap. init lists the paragraph with everything else it created. It creates no README where there is none, and a personal layer leaves the project's README alone.

Install and initialise in one command

curl -fsSL https://majordomus.dev/install.sh | sh -s -- --init

--init runs majordomus init in the current directory using the executable that was just installed, by its absolute path, so it does not depend on your PATH having been reloaded. If installation succeeds and initialisation fails, the installer says so in those words and leaves the working installation in place.

Personal mode

curl -fsSL https://majordomus.dev/install.sh | sh -s -- --personal

For using the tool as your own in a repository other people share: your team's, a client's, an open-source project's. --personal runs majordomus init --personal in the current directory. It creates the same layer a plain init creates and changes nothing the repository shares.

  • No tracked file is changed and nothing is added to .gitignore. The layer is covered by a marked block in the git directory's info/exclude, a file git never commits, pushes or clones.
  • majordomus init --personal reads git status before it writes and exits 10 unless it reads the same afterwards. The installer then compares the status again by itself and prints Verified (personal).
  • majordomus update and majordomus capture install cover each file before they write it and leave a file the project already tracks alone. majordomus doctor re-verifies the cover on every run.
  • The layer is this checkout's. It does not travel with a clone, a push or a stash.

When the trial has made its case, hand the layer to the team:

majordomus init --extend --shared

It removes the cover, adds the two .gitignore lines a plain init adds, and prints what is now the repository's to commit. It commits nothing; that step is yours. A file that is one person's by its own name, such as CLAUDE.local.md, stays covered and stays yours.

To stop instead, delete the block between # >>> majordomus personal >>> and # <<< majordomus personal <<< and the files it lists.

Personal mode keeps a layer apart from what a repository shares. It is not access control, and it is not a way around an organisation's rules about tools. The decision is ADR 0145; PERSONAL_MODE.md is the whole account: what it is for, what stays visible, and the way from a personal layer to a shared one.

Verify

majordomus --version
majordomus doctor

doctor reports whether the layer resolves, whether every enforcement it claims is actually wired, and which hook lines are still missing.

What it does to your machine

Nothing outside two places, and never as root:

$HOME/.local/share/majordomus/versions/<version>/    the release, unpacked
$HOME/.local/bin/majordomus                    a launcher
$HOME/.local/bin/majordomus-mcp                a launcher for the MCP server

The launchers are two-line shell scripts that exec the versioned tree. No shell profile is edited, no package manager is invoked, and sudo is never run: if a directory is not writable the installer says which one and stops.

Supported platforms

PlatformArchitecturelibcRust targetStatus
macOSARM64—aarch64-apple-darwinsupported
macOSx86_64—x86_64-apple-darwinsupported
Linuxx86_64glibcx86_64-unknown-linux-gnusupported
Linuxx86_64muslx86_64-unknown-linux-muslsupported
LinuxARM64glibcaarch64-unknown-linux-gnusupported
LinuxARM64muslaarch64-unknown-linux-muslsupported
Windowsx86_64—x86_64-pc-windows-msvcunavailable

That table is generated from share/distribution.yaml, which is the one place a platform is declared. The installer resolves your machine to a row of it from uname -s, uname -m and, on Linux, the C library it finds; the release build matrix is generated from the same rows, so a platform listed here is a platform a release actually built.

Windows x86_64 (x86_64-pc-windows-msvc) — The command a person runs is bash: bin/majordomus and lib/*.sh are POSIX shell, and the archive carries them beside the executable. Until that half has a Windows answer, publishing a Windows archive would ship an executable nothing can drive.

Choosing where it goes

curl -fsSL https://majordomus.dev/install.sh | sh -s -- --install-dir "$HOME/bin"
curl -fsSL https://majordomus.dev/install.sh | sh -s -- --prefix "$HOME/opt/majordomus"

or, equivalently:

MAJORDOMUS_INSTALL_DIR="$HOME/bin" curl -fsSL https://majordomus.dev/install.sh | sh

Pinning a version

curl -fsSL https://majordomus.dev/install.sh | sh -s -- --version v0.30.2

A pinned installation resolves https://majordomus.dev/releases/v0.30.2.json, which names the exact artifact and its sha256 digest, and therefore installs the same bytes every time. An unpinned installation resolves https://majordomus.dev/releases/latest.json, which is the latest stable release and moves forward as releases are published. Use the pinned form in CI.

Using it in CI

curl -fsSL https://majordomus.dev/install.sh | sh -s -- --version v0.30.2
export PATH="$HOME/.local/bin:$PATH"
majordomus --version

The installer needs no interaction and asks none: everything it does is decided by its arguments and environment. Pin the version so that a new release cannot change a build that used to pass.

Upgrading and reinstalling

Run the same command again. The installer is idempotent:

  • the same version already installed — it says so and exits 0;
  • an older version installed — it upgrades, and the previous installation keeps working until the moment the launcher is replaced;
  • a newer version installed and no version pinned — it refuses to move you backwards, and says how to do it anyway (--force, or --version).

Uninstalling

rm -f $HOME/.local/bin/majordomus $HOME/.local/bin/majordomus-mcp
rm -rf $HOME/.local/share/majordomus

That is the whole of it. It removes the tool. It does not remove any repository's .ai/ directory: your policy, rules, decisions, plan and history are the repository's, not the tool's, and no command of this project deletes them.

Releases

ReleasePublishedChannelArtifactsMetadata
v1.0.0-alpha.52026-10-22prerelease6v1.0.0-alpha.5.json
v1.0.0-alpha.42026-10-21prerelease6v1.0.0-alpha.4.json
v1.0.0-alpha.22026-10-21prerelease6v1.0.0-alpha.2.json
v1.0.0-alpha.12026-10-20prerelease6v1.0.0-alpha.1.json
v0.30.2 (latest)2026-10-19stable6v0.30.2.json
v0.30.12026-10-19stable6v0.30.1.json
v0.30.02026-10-18stable6v0.30.0.json
v0.29.02026-10-17stable6v0.29.0.json
v0.28.02026-10-17stable6v0.28.0.json
v0.27.02026-10-16stable6v0.27.0.json
v0.26.02026-10-14stable6v0.26.0.json
v0.25.02026-10-14stable6v0.25.0.json
v0.24.12026-10-14stable6v0.24.1.json
v0.23.02026-10-13stable6v0.23.0.json
v0.22.02026-10-13stable6v0.22.0.json
v0.21.02026-10-12stable6v0.21.0.json
v0.20.02026-10-10stable6v0.20.0.json
v0.19.12026-10-10stable6v0.19.1.json
v0.19.02026-10-09stable6v0.19.0.json
v0.18.02026-10-09stable6v0.18.0.json
v0.17.02026-10-08stable6v0.17.0.json
v0.16.02026-10-08stable6v0.16.0.json
v0.15.02026-10-07stable6v0.15.0.json
v0.14.02026-10-06stable6v0.14.0.json
v0.13.22026-10-06stable6v0.13.2.json
v0.13.12026-10-04stable6v0.13.1.json
v0.13.02026-10-04stable6v0.13.0.json
v0.12.02026-10-03stable6v0.12.0.json
v0.11.02026-10-02stable6v0.11.0.json
v0.10.02026-09-29stable6v0.10.0.json
v0.9.02026-09-25stable6v0.9.0.json
v0.8.02026-09-20stable6v0.8.0.json
v0.7.02026-09-15stable6v0.7.0.json
v0.6.02026-09-12stable6v0.6.0.json
v0.5.02026-09-11stable6v0.5.0.json
v0.3.12026-09-08stable6v0.3.1.json

Each release publishes one archive per supported target plus a SHA256SUMS file, and its metadata is served as JSON beside the installer. The installer resolves a release from that JSON, never from GitHub's API or HTML, so a change in GitHub's pages cannot break an installation. The one call to GitHub it can make is the optional provenance check below, through the GitHub CLI.

Security model

What is protected, and how:

  • The metadata is fetched over HTTPS, with redirects restricted to HTTPS. A base URL that is not HTTPS is refused unless two explicit environment variables say otherwise, which exists so the installer's own tests can serve fixtures.
  • The artifact is verified before it is unpacked. The metadata carries a sha256 digest and a size; the installer checks both and, on a mismatch, discards the download and stops. There is no "warn and continue".
  • The artifact URL is checked against the project's own release host before anything is fetched from it, and every value read out of the metadata is matched against the shape it must have. Nothing read over the network reaches a command line, a path or the shell.
  • The archive is inspected before extraction. Absolute paths, .. traversal, symbolic and hard links, devices, and any entry outside the archive's own directory are refused by name and nothing is unpacked.
  • The installation is atomic. The new tree is unpacked beside the old one and its executable is run once, from a temporary location, to prove it reports the version that was resolved. Only then is the launcher replaced, by a rename. Any failure before that leaves the previous installation exactly as it was.
  • Nothing is elevated. sudo appears nowhere in the installer.

What remains trusted: GitHub Pages serving the metadata, GitHub Releases serving the artifacts, and the release pipeline that produced both. Checksums bind the artifact to the metadata; they do not, on their own, prove who wrote the metadata. That is what provenance is for: every release archive since v0.20.0 is attested by the release workflow (earlier ones carry their checksums only), and where the GitHub CLI is installed and signed in the installer asks it whether this archive was built by this repository's workflow. The closing report says which it verified — provenance (…) and checksum, or checksum only with the reason. MAJORDOMUS_REQUIRE_PROVENANCE=1 installs nothing short of verified provenance. By hand: gh attestation verify <archive> --repo <repository>. What each path verifies is in docs/DISTRIBUTION.md.

Reading it before running it

curl … | sh runs a script you have not read. If you would rather read it first:

curl -fsSL https://majordomus.dev/install.sh -o install-majordomus.sh
less install-majordomus.sh
sh install-majordomus.sh

The installer is one file with no dependencies beyond curl or wget, tar, and one of sha256sum or openssl. Its top half is generated from the distribution model and its bottom half is behaviour; both are reviewed in this repository and linted by shellcheck in CI.

Troubleshooting

majordomus: command not found after installing. The launcher directory is not on your PATH. The installer prints the exact line to add; it does not edit your shell profile.

"does not provide a prebuilt binary for". Your machine resolved to no supported target. The message names what was detected and lists what is supported. There is no automatic fallback to building from source: that would need the toolchain this installer promises not to require.

"the downloaded archive does not match its digest". Stop. Nothing was installed. Run it again; if it happens twice, the artifact or the metadata is wrong and forcing it would be the wrong response.

Behind a proxy. curl and wget read the usual https_proxy environment; the installer adds nothing of its own.

Seeing what it would do.

curl -fsSL https://majordomus.dev/install.sh | sh -s -- --dry-run
curl -fsSL https://majordomus.dev/install.sh | sh -s -- --verbose

--dry-run resolves the platform, the release and every path, prints them, and changes nothing.

Building from source

For contributors, not for installation. The repository's own tooling is documented in CONTRIBUTING.md:

git clone https://github.com/korczis/prismatic-majordomus majordomus
cd majordomus
cargo build --release --manifest-path apps/majordomus-cli/Cargo.toml

The shell tool needs no build at all: bin/majordomus runs from a checkout. Use the installer for everything else — a source checkout is a development environment, not an installation.

How this works underneath

The architecture, the trust path, the release procedure and how to add a platform are in DISTRIBUTION.md.

Claims this document defines

Each links to its own page with implementation, test and where it is used.

Searches the titles and descriptions of every page this site publishes.