You work in a repository other people share: your team's, a client's, an open-source
project's. You want your own agent sessions supervised in it today, on real work. A plain
init would add a directory, three files at the root and a line in the README — a change
to what everyone shares, which is a proposal, and you have nothing to propose yet.
A team adopts a tool on evidence. Personal mode is how one person gathers it without
asking anyone to change anything first.
setup: bare
given:
- 'a shared repository with no AI layer'
steps:
- id: init
run: ['init', '--personal']
note: 'the same layer a plain init makes; the difference is whose it is'
expect:
exit: 0
stdout_contains: ['^OK personal', 'personal: this layer is yours; nothing the repository shares was changed']
files_exist: ['.ai/repo/policy.yaml', '.ai/manifest.yaml']
- id: update
run: ['update']
note: 'the provider files at the root are covered before they are written'
expect:
exit: 0
files_exist: ['AGENTS.md', 'CLAUDE.md']
- id: doctor
run: ['doctor']
note: 'doctor holds the layer to its claim on every run; the two hook lines are still yours to add, which is the one thing its exit code is about'
expect:
exit: 10
stdout_contains: ['^OK personal', 'not asked to name AGENTS.md']
- id: share
run: ['init', '--extend', '--shared']
note: 'the trial made its case: the cover is removed and the layer is the repository''s to commit — by you, when you choose to'
expect:
exit: 0
stdout_contains: ['shared: the cover is removed', 'git add .ai/']
then:
- 'until the last step, git status read the same as before the first one'
- 'the tracked .gitignore and README.md were untouched until the layer was shared'
- 'nothing was committed by the tool at any step'
curl -fsSL https://majordomus.dev/install.sh | sh -s -- --personal
or, with the tool already installed:
majordomus init --personal
init --personal reads git status before it writes anything, covers .ai/ in the
repository's own exclude file, creates the layer, and exits 10 unless the status reads the
same afterwards. The installer then compares the status itself, having written none of it.
majordomus update and majordomus capture install cover each file before they write it,
and leave a file the project already tracks alone — a CLAUDE.md the project commits is
the project's.
When you want the team to have it:
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.
To stop instead: delete the block between # >>> majordomus personal >>> and
# <<< majordomus personal <<< in .git/info/exclude and remove the files it lists.
Your sessions are supervised — scoped tasks, a finish contract, handovers — in a repository
whose shared state is exactly what it was. The layer is yours and this machine's: it does
not travel with a clone, a push or a stash.
What you learn is what the team would get, because the layer is the ordinary one; and the
step from "mine" to "ours" is one command and a commit you make yourself.
Which files are covered is not a list anyone maintains. The layer is one pattern, and
every other entry is the path a writer was about to write, taken from the policy's
projection targets and the provider adapters at the moment of writing.
Personal mode is not access control and not a way around an organisation's rules about
tools; whether a tool may be used on a codebase is the organisation's decision.
-
the same layer a plain init makes; the difference is whose it is
created
.ai/README.md
.ai/manifest.yaml
.ai/repo/README.md
.ai/repo/policy.yaml
.ai/repo/scope.yaml
.ai/repo/profiles/
.ai/repo/prompts/
.ai/repo/profiles/README.md
.ai/repo/prompts/README.md
.ai/repo/rules/README.md
.ai/repo/rules/project/README.md
.ai/repo/rules/vendor/majordomus/
.ai/repo/knowledge/
.ai/repo/knowledge/curated/README.md
.ai/repo/knowledge/candidates/README.md
.ai/repo/workflows/
.ai/repo/skills/
.ai/repo/adrs/
.ai/repo/use-cases/
.ai/repo/applications/
.ai/repo/why/
.ai/repo/features/
.ai/repo/sessions/README.md
.ai/repo/deployments/README.md
.ai/repo/project/README.md
<repo>/.git/info/exclude:/.ai/
scope: no stack recognised at the root (looked for mix.exs, Cargo.toml); seeded only the entries every repository shares; add your own to .ai/repo/scope.yaml
OK personal .ai/ — tracked nowhere, ignored through <repo>/.git/info/exclude, and absent from git status (1 path(s) covered)
personal: this layer is yours; nothing the repository shares was changed. The cover is <repo>/.git/info/exclude
personal: it stays on this machine. To propose it to the team: majordomus init --extend --shared
local state: .ai/local/state/ (ignored by git; this checkout's own)
next: majordomus update # generate the provider instruction files named in the policy
next: majordomus doctor # verify nothing is declared that is not wired
hooks are not installed by init; add these two lines yourself, doctor verifies them:
pre-commit: majordomus doctor || exit $?
pre-push: majordomus finish --check || exit $?
- exit 0
- stdout_contains /^OK personal/
- stdout_contains /personal: this layer is yours; nothing the repository shares was changed/
- file_exists .ai/repo/policy.yaml
- file_exists .ai/manifest.yaml
-
the provider files at the root are covered before they are written
create AGENTS.md
create CLAUDE.md
create GEMINI.md
generated 3 target(s) from policy c70f672d1b5f; each carries its own stamp
- exit 0
- file_exists AGENTS.md
- file_exists CLAUDE.md
-
doctor holds the layer to its claim on every run; the two hook lines are still yours to add, which is the one thing its exit code is about
OK knowledge graph — buildable here: 0 node(s), 0 edge(s), compiled into a temporary file and removed; no stored index to go stale
OK knowledge records — 0 record(s) valid against knowledge/v1; every reference resolves [reproduce: majordomus knowledge check]
OK knowledge candidates — 0 await review, cap 40
OK layout .ai/manifest.yaml — schema ai-repository/v1
OK layout .ai/repo/scope.yaml — version 1; 14 in pathspec(s); every key is one the schema declares
OK layout .ai/local/ — ignored, and nothing under it is tracked
OK personal .ai/ — tracked nowhere, ignored through <repo>/.git/info/exclude, and absent from git status (7 path(s) covered)
OK layout .ai/ — every section the manifest names exists; the layer is readable without the tool
OK layout .ai/repo/prompts — present
OK layout .ai/local/state/handovers — present, 0 record(s)
OK layout .ai/local/state/checkpoints — present, 0 record(s)
OK records ledger.jsonl — every line is a well-formed event
OK policy 39 key(s) — every policy value the code reads is declared, with no reader-side default
INFO bootstrap README.md — not asked to name AGENTS.md: the layer is personal, and the README is the project's
OK bootstrap 3 projection(s) — each points at .ai/README.md, carries no rule of its own and names only rules in force
OK catalogue 0 use case(s), 0 application(s) — every command, doctrine, claim, responsibility, category, setup and cross-reference resolves, both directions
OK context .ai/ — 19 context document(s) carry the contract; ids unique, references resolve, no final document superseded, no cycle [reproduce: majordomus context validate]
OK policy .ai/repo/policy.yaml — parsed, version 1
OK profiles 4 files — parsed; default 'implementation' exists
INFO adr .ai/repo/adrs/ — no decisions; nothing to validate
OK records decisions.md — every entry is attributable
INFO project .ai/repo/project — no canonical project model here; nothing to validate
OK command surface — 30 public command(s), reconciled against the dispatch table [reproduce: majordomus doctor]
OK doctrine 50 of 61 rule(s) carry a validator — validator, dispatch, propagation, test and CI resolve for every one of the 50; the remaining 11 declare no validator and this check does not examine them
FAIL wiring doctor-on-commit — hook .git/hooks/pre-commit does not exist [reproduce: ls -l .git/hooks/pre-commit]
FAIL wiring finish-on-push — hook .git/hooks/pre-push does not exist [reproduce: ls -l .git/hooks/pre-push]
OK command coverage — every public command is exercised and refuted [reproduce: bash test/run.sh 31_command_coverage]
OK resolver handovers — no record for this worktree and branch (absence, not a stale match) [reproduce: majordomus handover --resolve]
OK lifecycle activity — 0 episode(s) opened here; too few to judge whether the writers stopped
OK knowledge wiring — the close path and the compaction adapter call the deriver
OK knowledge deriver — no episode has closed here; nothing to judge
INFO project .ai/repo/project — no canonical project model here; nothing to validate
OK projection AGENTS.md — content matches its stamp
OK projection CLAUDE.md — content matches its stamp
OK projection GEMINI.md — content matches its stamp
OK budget AGENTS.md — 42 lines, budget 150
OK links AGENTS.md — all references resolve
OK counts AGENTS.md — no hardcoded counts
OK context builder — 21 lines, budget 300 [reproduce: majordomus context]
OK capture share/schemas/majordomus/capture/capture.v1 — 2 file(s) describe majordomus.capture/v1 at the path the identifier derives: the record as JSON Schema, the document as protobuf
OK capture .ai/local/prompts — ignored and untracked
OK capture .ai/local/prompts — no records yet; the archive is empty
OK capture .ai/local/prompts — every prompt is present as all three: the record, the Markdown and the YAML
OK prompts .ai/local/prompts — the archive and every record in it are readable by their owner only
OK prompts .ai/local/prompts — no records yet; the archive is empty
OK prompt 4 asset(s) — front matter valid, every token known
OK records open-questions.md — every entry parses
OK retention ledger — 1 lines, cap 5000
OK retention handovers — 0 files, cap 200
OK retention checkpoints — 0 files, cap 500
OK retention sessions — 0 records, cap 500
INFO project .ai/repo/project — no canonical project model here; nothing to validate
OK rules .ai/repo/rules/vendor/majordomus — every file matches the manifest (1 (0.29.0))
OK rules 61 rule(s) — resolve in one deterministic order; vendored baseline plus project rules, no override — 51 carry a validator, 10 are normative text this tool does not check
OK rules blocking — all 44 blocking rule(s) carry a validator
OK schema rules — 61 rule(s) resolve in one order: the vendored baseline in manifest order, then the project's, as a dependency graph
OK schema share/kinds.yaml — 36 kind(s); every one that carries metadata declares a schema
OK schema share/schemas — 53 schema(s), each valid JSON and each applied — by a kind, through an allow-list the tool reads, by a validator that names it, or as a generated document's contract (15)
OK records 0 record(s) — every changed_files names work, not generated or local state
OK session .ai/local/session-contexts — ignored and untracked
OK session .ai/local/session-contexts — no working contexts yet; the store is empty
INFO skill .ai/repo/skills/ — no skills; nothing to validate
INFO use-case 30 advisory gap(s) — not covered by an active use case, and the policy does not require it: command:init command:update command:doctor command:watch command:start command:context command:checkpoint command:handover command:check command:finish command:history command:decision command:question command:prompt command:evidence command:skills command:capture command:search command:doctrine command:plan command:version command:session command:knowledge command:adr command:usecase command:rules command:migrate command:recover command:bench command:archive [reproduce: majordomus usecase coverage]
OK use-case 0 of 30 target(s) covered — every public command the policy requires is named and run by an active use case (policy use_cases.coverage)
INFO env - — bash <version>, git <version>, jq <version>, shellcheck present
WARN clone unpushed — commits on no remote: main(2) — work on one disk is invisible to every other session and cannot be integrated [reproduce: git push -u origin <branch>]
OK clone uncommitted — no linked worktree, so no uncommitted work can sit in one
· reasoning <decided by the advisors and the executable of the recording machine>
· budget doctor — <timed against the policy budget>
doctor: 2 failure(s)
- exit 10
- stdout_contains /^OK personal/
- stdout_contains /not asked to name AGENTS.md/
-
the trial made its case: the cover is removed and the layer is the repository's to commit — by you, when you choose to
created
.gitignore:.ai/local/
.gitignore:.ai/repo/**/.tmp.*
shared: the cover is removed; these paths are now the repository's to commit, when you choose to:
git add .ai/
git add AGENTS.md
git add CLAUDE.md
git add GEMINI.md
git add .gitignore
shared: .ai/local/ stays this checkout's own, as in every layer
local state: .ai/local/state/ (ignored by git; this checkout's own)
next: majordomus update # generate the provider instruction files named in the policy
next: majordomus doctor # verify nothing is declared that is not wired
hooks are not installed by init; add these two lines yourself, doctor verifies them:
pre-commit: majordomus doctor || exit $?
pre-push: majordomus finish --check || exit $?
- exit 0
- stdout_contains /shared: the cover is removed/
- stdout_contains /git add .ai//
The chain from this page to the code: the use case names commands, rules and claims; each rule is dispatched from the registry and each claim names the test that proves it; the scenario above executed the commands. Nothing in this chain is prose about intent.
Computed from what they share: claims, rules, commands, category, applications. Nobody maintains this list.