Skip to content

Concepts

the vocabulary, and the two outcomes people confuse

Rendered from docs/CONCEPTS.md — the same Markdown GitHub shows.

The vocabulary, in ordinary engineering language. Everything Majordomus prints, and every file it writes, uses these words and no others.

TermMeaningWhere it lives
policythe one canonical, provider-neutral operating policy.ai/repo/policy.yaml
profilea named bundle fixing capability class, effort, verbosity, presentation, context toggles, verification, checkpoint interval, and output contract for a task class.ai/repo/profiles/<name>.yaml
projectiona provider-specific instruction file generated from the policy, headed with a stamp naming the command that regenerates it, the policy hash and the hash of its own contentCLAUDE.md, AGENTS.md, GEMINI.md, or any target the policy names
stampthe first line of a generated file, or the begin marker of a generated region: the policy hash it was rendered from and the hash of the content it covers; content that differs from its stamp was hand-edited<!-- generated by \majordomus update` ... (policy ..., content ...) -->`
taskthe one active unit of work in a checkout.ai/local/state/current.yaml
sessionone execution episode of one worker: it opens, it may touch several tasks, and it closes into an immutable record that references what the episode produced and copies none of it.ai/local/state/session-current.yaml while open, .ai/repo/sessions/ once closed
envelopewhat a closed session record is: identity, a temporal boundary, and references — never a copy of the records it names.ai/repo/sessions/<file>.md
scopethe normalised set of repository paths a task may touch, or that a context document applies to; and, for the repository as a whole, what a worker reads of it and what it never reads, declared once, out over in, a path matching nothing outscope: in the task record; scope: and paths: in a context document; .ai/repo/scope.yaml, read by scope and majordomus://scope
claimthe same scope, seen from another worktree; overlap is reported, never blockedreported by start and check --overlap
use casea task a person performs with the tool, as one object: the commands, rules, claims, responsibilities and applications it names, and a scenario the tool executes against itself; its maturity is observed from the evidence, never written.ai/repo/use-cases/<id>.md, usecase, majordomus://use-case/<id>, /use-cases/<id>/
applicationa context the tool suits: when it fits, when it does not, and the use cases it composes.ai/repo/applications/<id>.md
checkpointa compact progress record inside an active task, capped by policy so that it stays quotable rather than becoming a report; also updates checkpoint_at, from which staleness is measured.ai/local/state/checkpoints/, checkpoint, check --checkpoint
handoveran append-only continuation record with computed front matter and required sections, written when a worker stops.ai/local/state/handovers/
decisionwhat was decided, why, what was rejected, and which task decided it; superseded by a later entry naming it, never edited.ai/local/state/decisions.md
open questionsomething unresolved, recorded as state rather than prose; any entry naming the active task refuses finish --outcome completed.ai/local/state/open-questions.md
rulea portable Markdown document with YAML front matter: identity, class, dependencies, and for the ones the tool enforces an x-majordomus block; the effective set is the vendored baseline plus the repository's own.ai/repo/rules/vendor/majordomus/rules/*.md, .ai/repo/rules/project/*.md, read by rules list
doctrinea rule the tool enforces: its x-majordomus block names the validator that decides it, the commands that run it, and the tests that prove it; blocking stops a command, advisory reports and does notthe resolved rule set, read by doctrine, check --rule, and every enforcing command
validatorthe function that decides one doctrine; it reports findings and never decides their level, because the doctrine's class does thatmj_validate_<name> in lib/
history eventone line of the ledger: what happened, when, for which task, at which head.ai/local/state/ledger.jsonl, read by history
contextthe assembled briefing for whoever works next: durable state in authority order, within a line budget, with every exclusion namedprinted by context; never stored
context documenta Markdown file under the .ai/ tree whose front matter declares schema: context/v1 and kind: context: an identity that survives a move, a scope (its directory, its subtree, or listed paths), the providers and audience it addresses, and how it composes with its ancestors.ai/**/README.md; the file names the manifest's context.documents requires
effective contextthe documents that apply to one path, computed: the ancestor chain admitted by each document's scope, least specific first, then order, then path; filtered by provider, audience and status; superseded documents dropped, final ones never supersededcontext resolve <path>; context explain says why
authority ordergit, then task and profile, then blockers, then authored records, then history — the order sections appear in and the reverse of the order they are dropped incontext
skilla provider-neutral procedure for one bounded kind of work: front matter under the skill schema over a body with a purpose, a procedure and an output contract; discovered by the source class skill, never registered, loaded only when the task is about it.ai/repo/skills/<id>/SKILL.md, skills
working contextthe bounded context of one execution episode: what the builder resolved at the moment the episode opened, frozen, over a section for the worker's own notes about the work. Local and stays local — it names one machine and it is a snapshot re-resolving would not reproduce — and never a transcript.ai/local/session-contexts/<stamp>--<session-id>.md, session context
prompt asseta small, versioned, provider-neutral framing in the repository, rendered against a closed set of state tokens.ai/repo/prompts/<name>.md, prompt
record resolutionchoosing the right prior record: same worktree and branch, else same branch, else nothing — never repository-widehandover --resolve, checkpoint --show, context
outcomeone of active, completed, partial, blocked, no_match, failed, handed_over; the only field a command changes after startoutcome: in the task record
finish contractthe checklist finish evaluates before accepting completed; every line printed pass or failverification.finish_requires in the policy
ledgerappend-only events written only by Majordomus; retention-capped.ai/local/state/ledger.jsonl
wiredan enforcement whose executable resolves and is invoked, without a swallowed exit code, by the hook or CI file the policy nameschecked by doctor
drifta deterministic disagreement between policy, projection, state, and gitreported by watch
divergence labelexact, advanced, diverged, different_context: how a recorded head relates to the current onecomputed at read time from git
capability classfast, standard, strong, strongest; never a vendor model namecapability: in a profile
effortlow, medium, high, xhigh, max; reasoning depth, independent of everything elseeffort: in a profile
verbosityterse, concise, detailed; how much the worker says, independent of how hard it thinksverbosity: in a profile
presentationmachine, engineering, summary; the final layer, chosen by the profilepresentation: in a profile
capabilityone thing the Rust executable exposes: a typed query with one handler, or a declarative object of the layer read as a resource; defined once, with a canonical id, and projected to MCP, HTTP, OpenAPI, the command line and the generated referenceapps/majordomus-cli/src/capability/, majordomus capabilities list
executionone call of one capability that was given an identity so that it can be watched rather than waited for: a lifecycle, an input as it was stored, typed events, and an output or an error. It lives in the process that accepted it and does not outlive itmajordomus run, majordomus executions, /api/v1/executions*, /cockpit/executions
execution eventone typed fact about an execution — created, started, a step, progress, a log line, a diagnostic, cancelled, completed, failed — in an envelope with a protocol version and a dense sequence number; the same value whether it is read over the live channel, over HTTP or on the command linemajordomus executions events, GET /events

The two outcomes people confuse

no_match means the work was done and the thing sought does not exist. failed means the work could not be done.

"We searched and found nothing" and "the source could not be searched" look alike in a transcript. A supervisor that cannot tell them apart cannot decide whether to retry, escalate, or accept. The typed field decides; prose never does.

Two words that are one word

task is the active unit of work in a checkout, and nothing else. A capability that takes long enough to watch is not "a task": it is a capability whose handler reports as it goes and stops when it is asked to, and one call of it is an execution. The word was available and was not taken, because a vocabulary with one word for two things is the thing this table exists to prevent.

What is deliberately not a concept

No agent, persona, role, tier, or registry or catalogue of workers. A supervisory tool that adds nouns becomes the thing it supervises. The only actor Majordomus knows is owner, a free-form string on the task record. The capability registry of the Rust executable indexes the tool's own surface, never a worker, and is derived from the layer and the code on every start.

Task, session, handover: three objects, three questions

They overlap in time and are easy to collapse into one, and each collapse loses something specific.

A task answers what is being worked on, under what constraints, within which paths. It is scoped, it has a profile, and it outlives the worker: a task begun on Tuesday can be continued on Thursday by somebody else.

A session answers what one worker did between sitting down and stopping. It is not scoped and it constrains nothing. It may span several tasks, and one task may be spanned by several sessions. It is the only object that can answer which work happened together and in what order.

A handover answers what the next person needs in order to continue this work. It is authored, deliberate, rare, and it has required sections.

Collapse the session into the task and you lose the episode: two decisions recorded an hour apart under different tasks look unrelated, because nothing records that one worker made both in one sitting. Collapse the session into the handover and you get a transcript — a narrative of an episode rather than a set of pointers to what it produced, which is the failure mode this whole design exists to avoid. Collapse the task into the session and scope becomes meaningless, because an episode does not have one.

The two records people confuse

checkpoint and handover look alike — both are append-only Markdown with computed front matter — and treating them as one thing costs you both.

A checkpoint is written often and read whole. It says what was true a few minutes ago and what comes next, in a few lines, so that the next briefing can quote it verbatim. The policy caps its length, and a body over the cap is refused rather than truncated.

A handover is written rarely and read deliberately. It has required sections, it is refused if any is empty, and it is the package another worker resumes from.

The cap is what keeps them distinct. Without it, checkpoints grow into reports, reports are too long to include in a briefing, and the briefing degrades to a pointer — which is where the tool started before either record existed.

Absence is a concept

No relevant handover. is an answer, not a failure. Resolution considers the same worktree and branch, then the same branch, then stops. A record from an unrelated branch is never offered, because a worker cannot tell that borrowed context is wrong until it has acted on it. Absence is better than incorrect memory.

What is deliberately not a concept, still

No agent, persona, role, tier, registry, or catalogue of prompts. prompts/ holds a few reusable framings, not a library; nothing ranks them, and nothing loads one unless asked. No summariser, no embedding, no vector store, no transcript. Majordomus stores, validates, resolves, projects and verifies. It never calls a model.

Claims this document defines

Each links to its own page with implementation, test and where it is used.