A snapshot: read at commit 707a04c7ce8 on 2026-10-18T00:06:01Z by majordomus 0.29.0. Nothing on this page is read again. See it live
docs/ADOPTION.md
Adoption
What it is
- URI
majordomus://document/docs/ADOPTION.md- Kind
document- Identity
docs/ADOPTION.md- Path
docs/ADOPTION.md- Provenance
- declared
- Media type
text/markdown- As a capability
- document.docs/ADOPTION.md
Front matter
{}Content
# Adoption
Majordomus sits around an existing workflow. Nothing is rewritten.
## Day one: one repository, one person
```bash
curl -fsSL https://majordomus.dev/install.sh | sh
cd <your project>
majordomus init # .ai/ with the policy, profiles, rules, prompts and workflows
majordomus update # CLAUDE.md, AGENTS.md, GEMINI.md generated from the policy
majordomus doctor # tells you exactly which hook lines are missing
```
Add the two hook lines `init` printed, then run `doctor` again.
### What the second run actually says
Not "nothing". A promise of zero was written here once and was wrong by 112 findings
([`ADOPTION_FIRST_RUN.md`](ADOPTION_FIRST_RUN.md) is the record), so this section is a
measurement instead: a `git init` repository with a README, one source file and one commit,
adopted by following the four commands above literally. Your own repository will differ in
the details and not in the shape.
```
FAIL bootstrap README.md — does not name AGENTS.md; a reader cannot find the agent bootstrap
WARN clone unpushed — commits on no remote: main(1)
INFO doctrine vendor evidence — v0.5.0 is a packaged distribution, so the tests, claims
and CI each rule cites are not here to read
INFO adr .ai/repo/adrs/ — no decisions; nothing to validate
INFO skill .ai/repo/skills/ — no skills; nothing to validate
...
OK ... 43 of them
```
Read it by verdict, because the three mean different things:
- **`FAIL` is yours, and there is normally one of it.** `update` wrote `AGENTS.md`; the
check asks that your `README.md` point a reader at it. One line fixes it, and then the
run is clean. Every other `FAIL` you see is about your repository too — a projection you
hand-edited, a hook that is present but not executable, an `.ai/local/` that got
committed — and each names the command that fixes it.
- **`WARN` is a fact about this checkout, not a defect.** A repository with no remote yet
reports `unpushed`; it stops as soon as you push. `doctor` also warns when it runs longer
than its budget, which on a loaded machine says something about the machine.
- **`INFO` is a check that had nothing to look at,** and is worth reading once so that you
know what is *not* being verified. `no decisions; nothing to validate` will stop the day
you write an ADR. `vendor evidence` is permanent and is explained below.
`majordomus doctor` exits `10` while any `FAIL` stands, which is what makes the `pre-commit`
line worth adding. `WARN` and `INFO` never fail the command.
So zero *is* reachable, and in the measured run it took one line — a sentence in `README.md`
naming `AGENTS.md`. After that edit the same command reports no failures and exits `0`, with
the two warnings and the informational lines still there and still not failures. That is the
promise this page used to make before the first `doctor`, and now makes after the first fix.
### Why `doctor` skips its own evidence in your repository
Each rule in the package carries the test case and the claim that prove it — `tests:
[test/cases/01_init.sh]`, and so on. Those are *our* evidence for *our* rule, they live in
the Majordomus source tree, and the release archive does not ship them: it carries `bin/`,
`lib/`, `libexec/`, `share/` and a `RELEASE.json` stamp. So an installed tool cannot read
them, says so once, and holds your repository to none of it. You are not expected to have a
`test/cases/`, a `docs/CLAIMS.yaml`, or a copy of our CI workflow, and nothing here will
ask you for one.
What is still checked in your repository is the half that travels with the tool: that every
rule names a validator that exists, that the command it is declared under really dispatches
it, and that a blocking rule can actually stop that command. A rule that is written down
but not wired is still reported here, exactly as it is at home.
Commit `.ai/repo/` and the generated files. `.ai/local/` is this checkout's own
state — the task record, ledger, checkpoints, handovers — and `init` ignores it; it never
travels through git, and a fresh clone starts without it.
From then on:
```bash
majordomus start "<task>" --scope <paths> [--profile <name>]
# ... the AI worker reads the generated instructions and works ...
majordomus check
majordomus finish --outcome completed --verify-command "<your test command>"
```
## A repository that already has a CLAUDE.md
Most repositories worth supervising already have hand-written instructions for their AI
tools. `mode: region` keeps them. Majordomus then owns only the text between two markers
and copies everything else through byte for byte:
```yaml
# .ai/repo/policy.yaml
projections:
- provider: claude-code
target: CLAUDE.md
mode: region
always_loaded: true
```
```bash
majordomus update # appends the region once; the rest of CLAUDE.md is untouched
majordomus doctor # hashes the region, and reports the host document's length
```
What that buys you: an edit outside the markers is the repository's own business and is
never reported as drift, while an edit inside them is caught exactly as a whole-file
projection would be. The budget, the link check and the count check all measure the
region, so every failure `doctor` reports can be fixed by editing the policy.
Malformed markers — unclosed, out of order, or repeated — are refused rather than
guessed at, and nothing is written.
## Hooks that are dispatchers
If `pre-commit` runs every executable in `pre-commit.d/`, put the invocation in a subhook
and leave the dispatcher alone. `doctor` looks in `<hook>.d/` as well and names the file
that carries it. A subhook that is present but not executable is reported as not wired,
because that is what the dispatcher does with it.
## Week one: adjust the policy, not the projections
Every rule the workers see comes from `.ai/repo/policy.yaml`, the profiles and the rules
under `.ai/repo/rules/`. Edit those, run `update`. If someone edits `CLAUDE.md` directly, `doctor` and `watch` say so,
and `update` refuses to overwrite until you look at the diff.
Typical first edits:
- lower `always_loaded_budget_lines` if the generated file is longer than you want
workers to read every session
- change `profiles.default` to `routine` for a maintenance-heavy repository
- add a project-specific verification requirement by adding a profile
## Several workers at once
Give each concurrent autonomous writer its own git worktree. `start` in each worktree
reports any scope that overlaps another worktree's active task. Nothing blocks; the
report is for the person deciding who works where.
With one worker, or workers that run strictly one after another, plain branches are
correct and worktrees are overhead. The README says so; believe it.
## Existing repository with history
The pre-push hook runs `finish --check`, which passes when no task is active. Nothing
about the repository's past is judged. Start supervising from the first `start`.
## Upgrading from the pre-`.ai` layout
Repositories set up before the `.ai/` layer kept everything under `.majordomus/`. Every
command refuses that layout and names the one that moves it:
```bash
majordomus migrate --dry-run # the whole plan, one line per file; writes nothing
majordomus migrate # git-moves the tracked half into .ai/repo/, moves the state
# into .ai/local/state/ after a verified byte-for-byte backup
# whose path it prints, re-stamps the projections, runs doctor
```
Nothing under `.majordomus/` that the migration does not recognise is deleted; it is
reported, and the directory stays until you move it by hand. A `.majordomus/bin/majordomus`
is a tool installation, not project data, and is left alone. See `CLI.md`.
## Removing Majordomus
Delete `.ai/`, the generated projections, and the two hook lines. For a region
projection, delete the marked block from the host document; everything around it was
never touched.
## What adoption does not require
- no server, account, token, or network access
- no change to how the AI tool is launched
- no runtime dependency beyond bash 3.2, git, and a checksum tool
- no buy-in from the whole team on day one; one repository, one person is enough to see
whether the finish contract catches anything