Skip to content
quarry Documentation
Login

Documentation

Summary

A repository's settings gain a Mirror to Git section. A repository admin gives a remote URL (an SSH URL such as [email protected]:owner/repo.git) and a branch name (default main). On enable the forge makes an ed25519 key pair for that repository, keeps the private half sealed, and shows the public half to add to the host as a deploy key with write access. After every change to trunk the forge runs zit git export with that key, which exports the new check-ins and pushes fast-forward only. The section shows the last pushed check-in, when, and the last error in words. Turning the mirror off stops pushing and discards the key. Only public repositories may be mirrored.

Decisions

Settled by the owner on 2026-10-15.

  1. Outbound only, now. This RFC pushes quarry repositories out. Following a Git upstream in (#358) is separate work.
  2. Any repository admin may set it up. The bar is a, the same as webhooks and environments, so an agent holding a (curator on quarry) may too.
  3. Public repositories only. A private repository cannot be mirrored, and a repository that becomes private stops pushing (see Private).
  4. Author email is zit's rule. A commit carries the author's contact email from the repository's user table, else [email protected]. No new account setting; a person who wants the host to link their commits adds a contact email.

The setting

One row per repository: remote URL, push branch (default main), enabled, the sealed private key, the public key, the last exported check-in, when it was pushed, the last error and when. The remote URL is validated as an SSH remote with no password in it (zit refuses a password in an autopush URL, and an HTTPS URL would need a credential this design does not keep). Every change is written to the repository's settings log with its actor and via, as the other settings are.

The key is made on first enable with crypto/ed25519, the private half sealed with the same sealer that holds sync secrets, and shown only as its OpenSSH public line. It is never shown again in private form, never logged, and never leaves the forge except as the file the push reads for the length of one run (written 0600 in a per-run temporary directory and removed after). Disabling the mirror deletes the key; enabling again makes a new one, which the admin adds to the host again.

When it pushes

After trunk moves, not on a timer. The trigger is the store's own fold noticing a new trunk tip, which covers a direct push, an accepted landing and a merge the forge writes, with one path. A run is queued per repository and coalesced: several trunk moves while a run is going make one more run, not several. Only the node holding the repository's write lease runs it, so a two-node forge never pushes twice.

A run is zit git export MIRROR --autopush URL --push-branch BRANCH against a Git repository the forge keeps under the repository's data directory, with GIT_SSH_COMMAND naming the per-run key file and IdentitiesOnly=yes. zit exports what is new and pushes fast-forward only.

A failure is recorded and retried with backoff (one minute, doubling to an hour); it never blocks the forge or the repository. The last error is put in words for the page: "the host refused the deploy key: check it is added with write access", "the remote's main has history this repository does not: it was not pushed", "the host could not be reached".

No force

The forge never force-pushes. If the remote branch has history the export did not write (a first enable onto a non-empty repository, or someone pushed to the mirror directly), the run refuses and says so, and the mirror stays enabled and keeps refusing until the remote is reset by hand. There is no "replace the remote" control in this RFC.

Private

Enabling is refused on a private repository. A mirrored repository that is made private stops pushing at once: the next run is not started, the status says "the repository is private, so the mirror is paused", and the key is kept so that making it public again resumes. Nothing already pushed is withdrawn, and the page says that too.

What the page shows

The section shows the remote, the branch, on or off, the public key with a copy control, and the status line: last pushed check-in (linked) and when, or the last error and when. The repository's About shows "Mirrored to " with a link while a mirror is on and current. No help-text paragraphs; the error sentences carry what a person needs.

Build order

Rung Work
1 The setting row, key making and sealing, the settings section (enable, disable, URL, branch, public key), the private-repository refusal, the settings-log rows
2 The run: trigger on a trunk-tip change, per-repository coalescing, lease holder only, the per-run key file, zit git export --autopush, status and error words, backoff
3 Pause on private, the About line
4 Move pikchr-studio to the setting and retire mirror-to-github, its timer and the gitmirror user on the host

Testing