What does whoever works next need to know? Read-only. Assembles durable state into one briefing and prints it. Nothing is persisted, no model is called, and the output is a projection: every line is recomputed from the records and git each time it runs.
Section order is authority order. Git first, because it is the only thing that cannot be stale; then the task and the profile that constrains it; then blockers, which change what may be accepted; then authored records; then event history last, because it is the weakest evidence about the present.
| Section | Source | Included when |
|---|---|---|
GIT | git | always |
TASK | state/current.yaml | a task is active and the profile's context.task is not false |
PROFILE | profiles/<name>.yaml | the task names a profile that exists |
CONTEXT DOCUMENTS | .ai/**/README.md (the context contract) | a task is active; the effective chain is listed for each of its scope paths |
OPEN QUESTIONS | state/open-questions.md | any unresolved entry names this task |
DECISIONS | state/decisions.md | context.decisions: true (this task) or context.architecture_notes: true (the repository) |
LATEST CHECKPOINT | state/checkpoints/ | a checkpoint resolves for this task |
LATEST COMPATIBLE HANDOVER | state/handovers/ | a handover resolves for this worktree and branch |
FILES TOUCHED IN SCOPE | git | context.relevant_files: true |
RECENT HISTORY | state/ledger.jsonl | context.recent_history_depth is above zero |
PROMPT | prompts/<name>.md | --prompt <name> was given |
This is the only code that reads a profile's context block, which is what makes those
fields state rather than documentation.
Budget. context.builder_budget_lines in the policy, or --budget-lines. When the
assembled text exceeds it, sections are dropped in a fixed order — history, files,
decisions, then the bodies of the checkpoint and the handover, which degrade to a pointer
rather than disappearing. Git, task, profile and blockers are never dropped. Every drop is
named under EXCLUDED with its reason, so an under-filled context is debugged from the
exclusion list instead of guessed at. Exit 10 if what cannot be dropped is already over
budget.
--for <provider> wraps the same body with a header naming the provider and its
always-loaded file. The body does not change: the canonical context is provider-neutral,
and a provider that needed different facts would be a different policy, not a different
rendering.
--json emits one object: git, task, sections[] (each with id, lines and
text), excluded[] (each with item and reason), and budget. The same selection as
the text form, because both are assembled once and rendered twice.
$ majordomus context
# Majordomus context — 2026-09-03T19:41:02Z
# a projection of durable state, not a source of truth: validate every line against git