Skip to main content

Module land

Module land 

Source
Expand description

Landing the winner: watch the pull request, fix what it complains about, and merge it.

Opening the pull request used to be where magi stopped and the operator started: watch the checks, read what the review bots found, push a fix, wait again, merge. That loop is mechanical, it takes an hour of wall-clock time per pull request, and doing it by hand six times in one session is how a queue that drains unattended stops being unattended. So it lives here.

§Shape

PrState is one observation of a pull request and decide is the whole policy as a pure function of it. Nothing in decide talks to gh, which is what makes “green with an unresolved comment is a fix, not a merge” an assertion in a test rather than a claim in a comment. land is the only part that performs I/O: observe, decide, act, repeat.

§What it refuses to do

Merging is the one irreversible thing magi can do to a repository, so the loop is built to stop rather than to guess:

  • A red pull request is never merged. When the budget runs out the pull request is left open with a comment naming what is still failing, because a magi that force-merges a red pull request is worse than one that stops.
  • A pull request whose checks cannot be read at all (gh reported no rollup) is not merged either. Landing is for repositories with CI; with no signal there is nothing to be green.
  • A pull request a human merged or closed underneath us is Step::Done - the person won, and their decision is not an error.

§Why --subject is not optional

A candidate branch holds one commit whose subject is magi: candidate A (uncommitted work), and gh pr merge --squash prefers a single commit’s message over the pull request title. Merging without merge_argv’s explicit --subject therefore writes a main history that says nothing about what landed. AGENTS.md records the trap; this module is where it is prevented.

Structs§

ExternalMerge
A pull request the operator merged outside of land::land’s own loop, found by asking GitHub about the run’s own winning branch rather than requiring the operator to go and find the URL themselves.
PrState
One observation of a pull request.
ReviewComment
One outstanding review comment, human or bot.

Enums§

Approval
What the owner’s answer to the approval question means.
Blocking
Whether a failing check actually stands between the pull request and main, according to the forge.
Checks
The aggregate verdict of a pull request’s checks.
PrLifecycle
Where a pull request is in its life.
Step
What the loop decided to do next. Pure, so the policy is testable.

Constants§

APPROVAL_NODE
Graph node recorded on the approval question.
APPROVE
The choice that lets the merge happen, verbatim as the owner taps it.
CHECKS_GRACE
How long the checks may stay unreadable before landing gives up on them.
DIFF_MAX_LINES
Unified diff lines carried in the panel before it is truncated.
HOLD
The choice that leaves the pull request open.
MARKER
Marker carried by every comment magi posts on a pull request.
POLL
How often the pull request is re-read while its checks are still running.
WAIT_CEILING
How long one wait may last before landing gives up on the checks finishing.

Functions§

approval
Read the owner’s answer, where None is an unanswered question.
approval_panel
The approval panel’s html: what is about to land, and the evidence for it.
branch_is_ancestor
Whether branch is, right now, an ancestor of base_branch in the local git graph — the weaker, URL-less signal that a branch landed somewhere.
correct_manual_merge
Confirm url is actually a merged pull request, then rewrite state’s status and merge exactly as the automatic land loop (land::land) would have written them had magi opened and merged this pull request itself.
decide
Decide the next step. No I/O.
find_external_merge
Ask GitHub whether this run’s winning candidate branch was actually merged somewhere land::land’s own loop never saw — the gap magi fold --merged exists to close, minus the operator having to find the URL by hand.
is_noise
Is this comment body machinery rather than a finding?
land
Run the loop against a real pull request until it merges or the budget runs out.
lifecycle
Read just a pull request’s lifecycle state - open, merged, or closed - with none of the checks/reviews/comments land itself needs to decide what to do next.
merge_argv
The argv magi merges with, minus the program name.
merge_subject
The squash subject to merge under.
parse_inline_comments
Parse gh api repos/{owner}/{repo}/pulls/<n>/comments into inline review comments. No I/O.
parse_pr
Parse gh pr view --json url,number,state,statusCheckRollup,reviews,comments output into a PrState. No I/O.