Skip to content

Canonical policy

The one provider-neutral file every generated instruction file derives from. Unknown keys are errors.

.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.

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-commitmajordomus doctor wired by git-hook:pre-commit
  • finish-on-pushmajordomus finish --check wired by git-hook:pre-push
projections
  • AGENTS.md ← agents always loaded
  • CLAUDE.md ← claude-code
  • GEMINI.md ← gemini

Claims defined by this policy

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