.majordomus/policy.yaml is the source of truth for how AI workers operate in a repository. It names the always-loaded budget, the default profile, the finish contract, the handover sections, the retention caps, the enforcement that doctor reconciles, and the instruction files update generates. Everything below is read from the skeleton that majordomus init installs.
Canonical policy
The one provider-neutral file every generated instruction file derives from. Unknown keys are errors.
context
Always-loaded budget: 150 lines
Strategy minimum-sufficient. Transcript is state: false. The generated instruction file marked always-loaded fails doctor and update when over budget.
profiles
Default profile: implementation
Checkpoint interval default 15m; each profile may override it.
verification
Finish contract
Required for changes: true. Lines evaluated by finish: scope_respected, verification_ran, state_updated, no_open_blockers, note_present.
handover
Required sections
# Objective, # Current State, # Next Action; refused at write time if any is empty. Retention cap 200 files.
ledger
Append-only, capped at 5000 lines
Written only by Majordomus. doctor reports when the cap is exceeded; nothing is deleted.
enforcement
What doctor reconciles
doctor-on-commit—majordomus doctorwired bygit-hook:pre-commitfinish-on-push—majordomus finish --checkwired bygit-hook:pre-push
projections
AGENTS.md← agents always loadedCLAUDE.md← claude-codeGEMINI.md← gemini
Claims defined by this policy
- guaranteedThe always-loaded instruction file has a line budget with a failing check
- guaranteedThe append-only ledger and handover store have retention caps that are checked
- advisoryA profile sets how often a worker should checkpoint, and a stale task is reported
- guaranteedThe assembled context obeys a line budget, and every section it drops is named with its reason
The policy file as installed by majordomus init
# Majordomus canonical policy. Provider-neutral. Edit this file, then run
# `majordomus update` to regenerate the provider instruction files.
version: 1
context:
always_loaded_budget_lines: 150 # hard cap on the always-loaded projection
builder_budget_lines: 300 # hard cap on what `majordomus context` prints
recent_decisions: 5 # decisions offered to a worker, newest first
max_list_items: 20 # cap on any list inside the assembled context
strategy: minimum-sufficient
transcript_is_state: false
profiles:
default: implementation
checkpoint_interval_default: 15m
verification:
required_for_changes: true
finish_requires:
- scope_respected
- verification_ran
- state_updated
- no_open_blockers
- note_present
checkpoint:
max_body_lines: 40 # a checkpoint is a progress note, not a report
retention_max_files: 500
handover:
required_sections: [Objective, Current State, Next Action]
retention_max_files: 200
ledger:
retention_max_lines: 5000
# The provider's episode events do three things beyond drawing the boundary. The start event
# hands the worker a briefing on standard output, which the provider adds to the context it
# is about to build; the compaction event records a derived checkpoint, because a compaction
# discards the conversation while the work continues; the end event writes a derived
# continuation record when the task is still active.
session:
briefing_on_start: true
briefing_budget_lines: 60 # cap on what the start event injects, per episode
checkpoint_on_compact: true
handover_on_end: true
# `majordomus bench` samples every public command this many times after the warm-up runs;
# `bench --check` refuses a regression larger than these fractions of the baseline's
# p50, p95 and p99; doctor and watch report their own wall time against these budgets
# (WARN, never the exit code). Measured, not guessed: change a budget with a run.
benchmark:
samples: 10
warmup: 2
regression:
p50: 0.5
p95: 0.5
p99: 0.6
budget:
doctor_ms: 3000
watch_ms: 3000
# Use-case coverage: which gaps `doctor` reports and which it fails on. A fresh repository
# has no use cases yet, so nothing is required until it says so.
use_cases:
coverage:
commands: advisory
claims: advisory
mcp_tools: advisory
# Every entry here is reconciled by `majordomus doctor`: the path must resolve (on PATH,
# repo-relative, or absolute in the hook line), be executable, and be invoked by the
# artifact named in wired_by without its exit code being swallowed.
enforcement:
- name: doctor-on-commit
path: majordomus
args: [doctor]
wired_by: git-hook:pre-commit
- name: finish-on-push
path: majordomus
args: [finish, --check]
wired_by: git-hook:pre-push
# mode: file (the default) generates the whole target; mode: region generates only the
# text between the <!-- majordomus:begin --> and <!-- majordomus:end --> markers and
# leaves the rest of the file alone, which is how a repository that already has a
# hand-written CLAUDE.md adopts Majordomus without losing it.
projections:
- provider: agents
target: AGENTS.md
always_loaded: true
- provider: claude-code
target: CLAUDE.md
- provider: gemini
target: GEMINI.md