Artifact de3e852c306fc6f2e6b527c314df1762b6a73b5220c1e010bad0778e6bb03fdd:
- File docs/hosting.md — part of check-in [a4b1ccf8ff] at 2026-09-13 00:01:20 on branch owner-ops — mirror.writes and chatbridge to the repository owner; reindex stays forge-side (user: dmestas, size: 7691) [annotate] [blame] [check-ins using] [more...]
Hosting a repository
Anyone with an account may create a repository, and anyone may
mirror a repository that is open to being mirrored. Creating one
(repo.add, the New repository form at /new) needs only a
signed-in account, not a site admin: the creator is granted admin on
the repository in the same operation, which is where ownership starts.
Two limits come with that open door — a short list of names the forge
keeps for its own routes, and a per-account quota (25 by default,
--repo-quota to change it; a site admin is never subject to it).
The principle the rest of this document, and the op registry's own
gatings, follow: a site admin administers the forge — accounts,
invites, the ops registry's own introspection — and nothing more. A
repository, mirrored or not, belongs to whoever created it, and every
decision about that repository is theirs: visibility, description,
roles, protected branches, webhooks, its bucket, its mirror configuration
(mirror.writes included — reconciling a fork is the owner's business),
and deleting it. A fleet belongs to the fleet's own owner the same
way — /fleet and its settings are unchanged by any of this. The one
thing that stays with the forge even though it touches a repository is
performance and the resources the machine shares: a mirror's pull
interval and the floor under it, the per-account repository quota,
storage and archive caches, CI worker capacity, rate limits, and the
exception panel — these protect the machine, not permission, and a site
admin is exempt from them rather than singled out by them.
A repository on quarry is in one of four postures. The posture is
chosen once, on the New repository form, and can be changed later from
/fleet or the mirror.* ops. It decides who owns the history and
which surfaces the forge offers. Everything else — visibility, chat,
protected branches, whether the repository may itself be mirrored — is
a setting that applies on top of whichever posture the repository is in.
The four postures
1. Native (start empty)
Quarry is the source of truth from the first push. Every surface is open: push with zit, land branches through landings, run CI, file tickets, edit the wiki and notes, post in the forum, chat. Trunk protection, auto-land and the gate tripwire all apply.
Nothing exists until somebody pushes, so an empty repository shows quick-start commands in place of a timeline. That is the only limitation.
2. Import and own
Clone an existing zit or Fossil server once, then cut the cord. From then on the repository behaves exactly like a native one; the badge beside its name reads forked from <host> and the upstream URL is kept only as provenance.
Implications:
- The upstream keeps moving without you. Nothing merges back, in either direction, unless you do it by hand.
- You can re-attach later from
/fleet. Re-attaching merges whatever the upstream did in the meantime on top of local history, which can conflict like any other merge.
3. Mirror
Clone and keep pulling on an interval. Quarry pulls and never pushes.
The interval is floored at 60 seconds: these upstreams are other
people's servers, and the floor is a courtesy the form cannot opt out
of. --mirror-tick (default 1m) is how often due-ness is evaluated,
not how often anything is pulled.
By default a mirror refuses local writes — push, tickets, wiki, forum — because a write landing on a tracking store forks it by accident. The repository pages therefore hide the Landings, CI and Chat tabs and point readers at the upstream's own write surfaces.
Two hard limits before you rely on one:
- The store needs a working checkout.
zit pulloperates on a working directory, so a genuinely bare store cannot be mirrored. Stores created byzit cloneorzit import-fossilcarry one; this bites only hand-built bare stores. - The upstream must allow anonymous clone. Some Fossil servers
serve a browsable timeline while refusing sync (
sqlite.org/lemonis one), andfossil cloneexits 0 on that refusal. Check for the repository, not the exit status.
A failing mirror shows a red badge with the failure count on /fleet
and on the repository page. A pull that brings nothing new does not
re-index and is not logged.
4. Mirror that accepts writes
The repository's own admin can flip a mirror to accept local writes
(mirror.writes, or the switch on /fleet) — reconciling the fork this
creates is that admin's business, not the forge operator's. The
repository still tracks the upstream,
so it now has two write heads: the next scheduled pull merges upstream
on top of whatever landed locally. Landings, CI and Chat stay hidden
while the repository tracks.
This is a transition state, not somewhere to live. When the upstream is done being the upstream, detach — that turns the repository into posture 2 cleanly and stops the pulls.
Open to being mirrored
A repository says, on its own side, whether OTHER PEOPLE may keep a
copy that follows it — the mirrorable setting, one line in the
repository's own settings, admin-only to change. Open by default: a
public repository allows it until an admin says otherwise, the same
reasoning visibility uses. A private repository is never mirrorable,
regardless of this setting — mirroring is "may other people keep a
copy", and a private repository has already answered no to "may other
people see this at all". That veto is enforced where it matters, not
merely assumed: the sync endpoint refuses a clone or pull of a
repository that is private or not mirrorable, the same
invisible-not-forbidden way every other refusal here works — a
stranger cannot tell "not mirrorable" from "not there".
Turning mirrorable off does not touch a mirror someone already made; it only refuses a NEW clone or pull from here on. It has no effect on which upstreams THIS repository may itself track — that is what the four postures below decide.
Settings that cut across every posture
- Private. Only accounts holding a role on the repository can see that it exists. Everything else is readable by anonymous by default, per the repository's Fossil capability letters (RFC 0004).
- Chat. A per-repository switch in settings. Off on mirrors regardless of the switch. When off, the Chat tab and the entry in the chat side rail disappear for everyone.
- Protected branches. An owner plus required checks on trunk
(RFC 0007). A store-level
zit landing acceptcan still walk past the forge; the gate tripwire on the CI page reports every check-in that reached a protected branch outside a landing. - Fossil chat bridge. A mirror of a Fossil server can bridge one
channel to that server's chat. The upstream needs a login with the
Ccapability andhttp_authentication_okset. No edits or mentions cross, and each Fossil server is its own chat — see running.md. - Fossil clients. A repository cloned from Fossil advertises a
fossil clonecommand alongside the zit one; the wire format is shared, so readers who already have fossil need not install anything.
Operational notes
- A store dropped into the data directory is served as starting, with a 503 page that refreshes itself, until its index is built. A large import does not block the rest of the forge.
- Pulls take the store's single-writer lease, so several nodes can serve one store safely.
- The exit hatch is the same in every posture:
zit clone. Nothing is held hostage in the index, whichquarry reindexrebuilds from the store at any time.