Write an append-only continuation record.
Record resolution — choosing which prior record is about the work happening here — is the same rule for handovers, checkpoints and context: same worktree and branch, else same branch, else nothing.
Input: the authored body on stdin. Required sections are the policy's
handover.required_sections as level-one headings, each with non-empty content;
template placeholders in angle brackets count as empty. Optional: # Completed,
# Decisions, # Verification, # Risks, # Open Work.
--derive composes the body instead of reading stdin, from the task record, the ledger,
git, the open questions and the newest checkpoint — each already written, already validated
and already identity-checked. It calls no model and makes no network request, which is what
makes it safe for a provider hook to run: a derived body can be wrong only if a record it
reads is wrong, and every one of those has its own gate. The policy's required sections are
emitted in the policy's order; a required section this generator cannot fill is refused by
name rather than written empty, because an empty section passes the section gate and tells
the next worker nothing. An authored body still says more than a derived one, and --derive
exists so that the absence of somebody willing to type is no longer the same thing as the
absence of a record.
Writes: one new file state/handovers/<utc-ts>--<branch-key>--<short-head>--<rand>.md,
mode 0600, created atomically (temp file, then hard link; retry with a new random
suffix on collision). Front matter is computed from git and from current.yaml; a body
that tries to set identity fields is rejected.
Never stages, commits, or modifies any other file except the task record's
checkpoint_at. Appends task.handed_over to the ledger. Prints the path.
--close additionally sets the task's outcome to handed_over, so that a new task may
start in this checkout; the old record is archived by that start. Without
--close the task stays active for the next session to continue.
The provider's SessionEnd event runs --derive --close when the task is still active, so
an episode that ends leaves a continuation record and not only the envelope of what it
produced. The two answer different questions: the session record indexes the episode, and a
handover is what the next worker resumes from.
Refuses (10) if a required section is missing or empty, or if the body contains
an identity field. Refuses (12) with no active task unless --no-task.
Resolve: majordomus handover --resolve finds the most relevant prior handover for
the current worktree and branch: same worktree and branch first, then same branch, never
a repository-wide fallback. Prints its git-state label and its body. No candidate is a
normal outcome and exits 0 with No relevant handover. --path prints the path
alone, for scripting; --no-task resolves without an active task.