This file is a bootstrap, not the rulebook. Read README.md for what this
repository is. The provider-neutral AI context and governance layer lives under
.ai/, and everything normative is there.
Before substantive planning, implementation, review or repository mutation:
- read
.ai/README.mdand follow its discovery protocol, - load the effective rules under
.ai/repo/rules/and resolve their dependencies, - load only the skills, workflows and knowledge the task is about,
- never load
.ai/local/implicitly; it is this checkout's own state and not context.
This repository is supervised by Majordomus. Run majordomus context before working,
take the task lifecycle from .ai/repo/workflows/task-lifecycle.md, and expect check
and finish to refuse work outside the task's scope. The default profile is
implementation; the checkpoint interval it sets is 15m.
Before working under a path, run majordomus context resolve <path> (or read the
README.md chain from .ai/ down to that directory): each document adds to its
ancestors and the nearest one does not replace them. A provider's own nested-file
loading is an optimisation; the Majordomus resolution is what applies.
This repository serves its .ai/ layer over MCP. The client configurations at the root
(.mcp.json for Claude Code, .gemini/settings.json for Gemini CLI, .codex/config.toml
for Codex) start bin/majordomus-mcp, which builds the Rust executable when it must and
runs majordomus mcp: one shared server per repository, Swagger UI at the URL it logs on
stderr, and every attached client visible to the others. Prefer its majordomus_* tools
to reading .ai/ by hand, and call majordomus_announce with your intent and the paths
you expect to touch, so that the other clients (Claude, Codex, Gemini, ...) can avoid
colliding with you. The surface is docs/MCP.md; just lists the recipes a person runs.
Never add or change an operation of the Rust executable by editing a transport
registry, an OpenAPI or Swagger definition, a benchmark inventory or a documentation
table: change the canonical capability! or module declaration under
apps/majordomus-cli/src/capability/builtin/ and run majordomus generate; a repeated
semantic definition across projections is a design defect (docs/CAPABILITIES.md, ADR 0004).
New repository automation is a typed or scripted capability (ADR 0069), not shell;
majordomus shell check refuses a shell unit .ai/repo/automation/ does not exempt.
Material engineering uncertainty is reasoned about through majordomus reasoning (ADR
0098, docs/REASONING.md): record the assessment with its evidence, let
scripts/advisor-consult ask whichever optional advisors the plan selects, settle a
disagreement with an experiment rather than a count, record the conclusion, and continue.
No advisor is needed; an absent one is reported state, never a reason to stop or to ask a
person what to do.
A capability you add or change has use cases: run majordomus usecase impact and the
scenarios it names, and close a coverage gap (majordomus usecase coverage) with a use
case that executes (.ai/repo/workflows/use-cases.md); finish refuses a required gap.
You are probably not alone. A server serves the checkout it was started in, and a linked
worktree is a checkout with a server of its own, so this repository has as many servers as
it has worktrees being worked in. The board, however, is the repository's:
majordomus_peers gathers every checkout's board and hands you every worker of this
repository, each stamped with the worktree it is working in (ADR 0044). Check complete —
false means a checkout could not be asked, and boards says which and why; a short board
is not proof that nobody is there. Announce what you are doing and the paths you expect to
touch, with majordomus_announce, before you start — and again whenever the connection is
re-established, because an announcement belongs to a connection and a worker that reconnects
keeps its work while losing its place on the board. A peer id (p1, p2) is a position on
one board, reassigned on reconnect and reused by every other board: never correlate a worker
across time by it — the checkout a peer carries is the durable half of its identity. Read
the board before you open a mandate and before you fan work out: two workers built the same
subsystem in one afternoon because neither looked first. A scope announced there is a claim,
not a lock, and check --overlap only reports; what refuses a change is the task's own scope,
at check, at finish and in the pre-push hook.
Sessions on other machines are reachable too when the repository enables the mesh (ADR
0067): linked runtimes replicate sessions, claims, handovers and reviews, and your board
announcements travel as advisory claims without you doing anything. When work must not
overlap across machines, claim it exclusively with majordomus_mesh_claim — a refusal
names the claim it meets — see who works where with majordomus_mesh_peers, hand work to
another machine with majordomus_mesh_handover_publish and take it with
majordomus_mesh_handover_consume, and ask for a review with majordomus_mesh_review_request.
Do not invent another coordination channel between sessions; the rule is
project.mesh-cooperation-is-authenticated and the manual is docs/MESH.md.
Follow what happens around you in one stream rather than polling each surface: majordomus monitor --follow --for <your names> (MCP majordomus_monitor, Cockpit /cockpit/monitor)
shows sessions, claims, handovers and reviews on every machine, the executor's merges and
GitHub's runs, with what names you first and the heartbeat noise folded away; --until merged --match '#<pr>' waits for one event and exits. The manual is docs/MONITOR.md.
Work moves through seats, and a seat is an exclusive mesh claim, never a name: one landing
seat lands every green head, alone, in combined tops merged pinned to the head CI judged; one
release seat releases whenever master holds landed work past the last tag; repair lanes merge
master into conflicting branches; a worker takes one issue to one pull request and lands its own
green head through the guarded lander's queue; at most five builders run on one machine
and none below 35 GiB free. A stale checkout or branch is preserved in a
refs/rescue/ ref and then brought current without asking. Who holds each seat is drawn on
/ui/mesh; the rule is project.the-cooperation-model-is-the-owners-word (ADR 0167).
Push what you have, early. A branch whose commits reach no remote is invisible to every
other worker, cannot be integrated by anyone but you, and is one disk away from being lost;
majordomus doctor names those branches.
Before implementing something new — a module, a command group, a document kind, a
generated artifact — run scripts/collision-check --new <paths> to see which other
branches already carry those paths, not only who the peer board says is working now: a
branch pushed before this session started carries no announcement and no less of a claim.
Announce with majordomus_announce once the paths are clear, and announce the
identifier you are about to allocate — an ADR number, a case number, an issue id —
not only the paths: a branch scan sees what was pushed, and the board is the only
thing that sees a number two sessions are taking in the same minute. The rule is
project.work-is-claimed-before-it-is-built.
Linked git worktrees of this repository live at <repository>-wt/<branch> — the primary
checkout's sibling named with -wt, then the branch name with its hierarchy kept — derived
from git and never chosen or registered; the primary checkout hosts the trunk. Before
implementing, run majordomus worktree to see which branch and worktree you are in and
whether that is where the branch belongs; start new work with majordomus worktree create <branch> and continue in the path it prints; bring a misplaced worktree home with
majordomus worktree migrate rather than continuing where you are. The pre-commit hook
refuses a feature branch committed from anywhere but its canonical worktree. The rule is
project.worktree-topology; the mechanism is docs/WORKTREES.md.
A .majordomus/ directory, if one exists, is an optional installation of the tool and not
repository context. Do not duplicate shared rules into this file: it is generated, and a
rule that exists here and nowhere else is a bug.