# quarry
A forge for Fossil repositories. Quarry hosts many repositories at once
and gives each one a timeline, wiki, tickets, forum, chat, landings and
CI. It stores and syncs them through [zit](https://fossil.craftdesign.group/zit/),
a reimplementation of Fossil, so both clients work against it unchanged:
```sh
fossil clone https://zeitforge.app/r/quarry quarry.fossil
zit clone https://zeitforge.app/r/quarry quarry.zit
```
The two clients share Fossil's sync protocol, so clone, pull, push and
unversioned files (`fossil uv sync`, `clone -u`) behave the same from
either. [zeitforge.app](https://zeitforge.app) runs it.
## What a repository gets
- **Fossil's own content, browsable:** timeline, check-ins, diffs, files,
embedded docs, wiki, tickets, forum, technotes. Links in imported
content that point at Fossil's URLs (`/info/<hash>`, `/tktview`,
`/wiki?name=`, …) resolve to quarry's pages
([docs/fossil-paths.md](docs/fossil-paths.md)).
- **Fossil's users, unchanged:** a hosted Fossil repository brings its
users and their capability letters with it, and the letters are
quarry's permission model (RFC 0004). Fossil clients authenticate the
way they always have.
- **Landings:** propose a branch onto another, review it, accept it
([docs/landings.md](docs/landings.md)). Protected branches are enforced
at the sync front, so a refused push never reaches the store
(RFC 0007).
- **CI:** workflows written as YAML under `ci/`, run on dagnats runners,
reported on landings and check-ins, with environments whose secrets
only reviewed code can reach (RFC 0009, 0019).
- **Chat, mentions and an inbox:** live chat per repository and team,
mentions from chat and the forum, notifications in-app, by email and
by browser push (RFC 0011). A Fossil server's own chat can be bridged
in.
- **Teams:** user-owned places that hold repositories, grant roles and
gather their chat and tickets (RFC 0018).
- **Attachments and releases:** files on tickets, wiki, technotes and
forum posts, and unversioned files and release downloads, with the
bytes in the repository's own bucket (RFC 0016, 0020).
- **A git mirror out:** a public repository's trunk pushed to GitHub or
any Git host after each move (RFC 0022).
- **An API for everything the pages do:** every page is built on the same
ops as `/api/v1` ([docs/api.md](docs/api.md)), and agent accounts hold
scoped tokens of their own (RFC 0021).
## Bringing a repository
A repository starts empty, is imported from Fossil and owned here, or
mirrors an upstream Fossil server on an interval (read-only by default)
([docs/hosting.md](docs/hosting.md)). Anyone with an account may create
one.
Quarry holds no hostage bytes. Everything durable lives in the
repositories' own artifacts or their buckets; every quarry index is
derived and rebuilt from them. A repository taken elsewhere takes
everything with it.
## Running it
```sh
quarry serve --addr 127.0.0.1:8950 --data ./data --repo quarry=$HOME/quarry
```
The full stack is quarry, zit, notify and dagnats. Quarry runs zit for
every read and write, so the zit version is part of quarry's behaviour:
pin it (`ZIT_VERSION` in `scripts/build-linux.sh`). Running by hand, with
compose, and the fleet admin's work: [docs/running.md](docs/running.md).
## Working on it
- Spec: [docs/rfcs/0001-quarry-forge.md](docs/rfcs/0001-quarry-forge.md);
every RFC, grouped and with its status: [docs/rfcs/README.md](docs/rfcs/README.md)
- This repository is a zit repository, landed on zeitforge.app like any
other: quarry has been built on quarry from the first commit.
- `make check` runs the local gates CI runs: gofmt, vet, test, the race
detector on the concurrency-bound packages, and build. The tests
include the structural assertion that only `internal/ops` touches the
data planes.