Skip to content
quarry Artifact [a4e6f9aac7]
Login

Artifact [a4e6f9aac7]

Artifact a4e6f9aac7a4e3d7eb2088448bc8a46f1b26a51b08f698513d1968eda78ed150:


Landings

A branch is finished. There is no way to say so.

That is the gap a landing fills. zit can create the branch, commit to it, merge trunk into it and merge it back — but the act of proposing that it land leaves no trace: nothing to review, nothing to comment on, nothing to accept or reject, nothing for CI to fire on. The work goes from "on a branch" to "on trunk" with no event in between.

This is not a pull request

GitHub's pull request is a bazaar mechanism. It exists because a stranger cannot write to your repository, so they fork it and request that you pull. Every piece of its ceremony descends from that premise: the fork, the head/base repository pair, the frozen commit range.

Inside a cathedral that premise does not hold. Anyone with the check-in capability can already push a branch, and the branch is already in the store. Nothing needs to be transported, filtered or quarantined, because there is no trust boundary to cross.

So the artifact is not a request to transfer commits. It is a decision record about a branch that is already here, and the name follows the direction the work actually moves: nobody requests a pull; the branch lands.

What a landing is made of

No new artifact type. This is the constraint the whole feature hangs from, and zit states it as a rule rather than a habit: if the implementation reaches for a new card, the design is wrong.

A landing is three ordinary fossil artifacts:

part artifact
the record a forum thread whose root body opens with a marker
every comment and state change a reply in that thread
the outcome a raw tag on the check-in that landed

The root body carries the header:

zit-landing: 1
branch: <name>
target: <name>

<the author's message>

and a transition is a reply whose body opens with zit-landing-state: X, where X is one of open, accepted, rejected.

Why it matters: clone a repository carrying landings with stock fossil and it sees forum threads and tagged check-ins. Fully readable, merely not actionable. That is the correct failure mode, and it is why no wire-protocol extension and no compatibility break were needed.

The lifecycle

Open

zit landing open --branch feat/x --to trunk -m "why this should land"

or New landing on the forge's landings page, which offers the branches that exist rather than a text field that accepts a typo, and defaults the target to the repository's own default branch. --to defaults to trunk on the command line. Either way this mints the thread root and leaves the branch unmerged; zit refuses a second open landing on the same branch by name.

On a mirror the control names the upstream instead: a tracking store takes no local writes, so proposing there would fork it by accident.

Discuss

Replies in the thread, from the CLI or the record's page. The page renders them as a discussion; markdown previews through the same composer the wiki and forum use.

CI

Opening a landing is an event a pipeline can fire on, as is a new check-in on a branch with an open landing — the intended workflow keeps merging the target into the branch and testing there.

Accept, or reject

zit landing accept <id>     # merge to the target, settle the record
zit landing reject <id> -m  # settle it, merge nothing

The order is the contract. Accept merges and commits first, then writes the outcome tag and the transition reply. A failure after the merge leaves merged work under a still-open landing, which one command settles. The reverse order would leave an accepted record over an unmerged branch — a lie in a log that cannot retract one.

What the forge adds

Quarry reads landings out of its own index rather than the store: the record is a reading of forum posts, recomputed whenever any post in a thread folds, so a reply indexed before its root converges on the same answer.

Who may accept. Accept writes a merge check-in, so it requires fossil's i — Write/check-in. Everything else about a landing is a forum artifact, so opening, commenting and rejecting require 3 (WrForum). Rejecting merges nothing and therefore needs nothing more than the capability to speak.

There is deliberately no rule against accepting your own landing. Inside a cathedral the author already holds the commit bit, and a required second reviewer is a policy fossil has no capability letter for; inventing one would be quarry policy wearing fossil's clothes.

Tickets a record touches. A landing's message may say what it does about tickets, in two verbs:

closes ae12f3      accepting the landing closes that ticket
addresses ae12f3   the landing works on that ticket, and finishes nothing

fixes and resolves are spelled differently and mean closes. The reference must follow the verb immediately — "this closes the gap that ae12f3 describes" declares nothing, because the token is four words away. Cross-repository references are shown but never acted on: a landing here has no business settling work in another store.

Both verbs LINK: the ticket page lists every landing and thread that named it, with the landing's state, so a reader sees "something landed for this" without opening anything. Only closes acts, and only once — a ticket somebody already resolved keeps their resolution. The chip the reader sees is produced by the same parser the accept path acts on, so there is no way to write a reference that acts without appearing, or appears without acting.

The declaration may sit in the title or the body; the title is where one-line landings put it.

A moving branch. The record references the branch, never a frozen range, because the intended workflow keeps committing to it after the record is opened. So the diff is computed at view time, and a landing page shows a bounded summary with a link to the whole change.

Work nobody proposed. The landings page also reports the blind spot of its own queue: branch tips that are finished and going nowhere. A branch qualifies when it is an open leaf, is not the target, and no open landing names it — and, last, when the store says its work is not already in the target.

That last question is the one the first three cannot answer. Landing a branch normally closes it, so the leaf test covers the usual case; a branch landed and left open still got the offer, and taking it opened a record that said merges up-to-date on arrival — an empty landing in the queue and a wasted trip. It is asked last because it is the only one that costs a zit subprocess, memoised on the pair of tips so a page pays once per push, and capped per listing so a store with dozens of open leaves cannot turn one page view into dozens of subprocesses. Rows past the cap are reported unprobed.

A probe that cannot run answers not landed. The check exists to withhold an offer, and withholding one because a subprocess failed would hide real stranded work behind an infrastructure fault.

Conflicts are read, never discovered. A forge must never learn whether a branch merges by attempting the merge, because on a server the attempt is the damage. Quarry asks the store (zit landing show), which answers merges clean, up-to-date, or conflict (N) with the paths. A conflicted landing renders as blocked, names the files, and disables accept rather than offering a control that would fail. The answer is memoised on the pair of check-in tips, so a push invalidates it by producing a different key.

What a landing is not

It is not a takedown, and it is not an outside-contribution path. A landing assumes the branch is already in the store. Accepting one does not unpublish anything a peer already holds, and no state here reaches across the trust boundary that bundles and imports exist for.

Sources