Skip to content
quarry Artifact [e3f9ec766c]
Login

Artifact [e3f9ec766c]

Artifact e3f9ec766c3c649a3e04067c502e65719cb3523e6a87bf70f942cd1f96bf2bdc:


# 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.