Document github.mirror-token and per-repo config.fnl schema
mirror-token uses kebab-case (not underscore) — the serde rename_all
means :mirror_token is silently ignored. Docs now call this out
explicitly and document both the global and per-repo mirror keys.
Also corrects README: mirroring is server-side on push, not a CI job.
https://claude.ai/code/session_018kJq4XvfvCe7XgnFGXXiKQ
diff --git a/README.md b/README.md
index c308fae..a89f0af 100644
--- a/README.md
+++ b/README.md
@@ -10,7 +10,8 @@ A Rust binary that runs in a Docker container, fronted by the host's sshd and a
- **Git hosting over SSH**, via the host's sshd dispatching into the container. Explicit repo creation (`ssh git@host quire repo new <name>`).
- **A read-only web view** for browsing README, tree, history, blame, diffs, and refs.
-- **Fennel-based CI** (Fennel is a Lisp that compiles to Lua), with pipelines defined in `.quire/ci.fnl`. Mirroring to GitHub is expressed as an ordinary CI job that shells out `git push` with a token from the global secrets map. Unsandboxed by default since every pipeline is code I've written; a bubblewrap-based opt-in is available for the day quire ever runs code I haven't.
+- **Fennel-based CI** (Fennel is a Lisp that compiles to Lua), with pipelines defined in `.quire/ci.fnl`. Unsandboxed by default since every pipeline is code I've written; a bubblewrap-based opt-in is available for the day quire ever runs code I haven't.
+- **Automatic GitHub mirroring** on every push. Set `:github :mirror` in `.quire/config.fnl` and `:github :mirror-token` in the global config; quire force-pushes each updated ref to the mirror URL independently of CI.
- **Email notifications** for CI failures and recoveries. SMTP via `msmtp`; plain text; per-repo config for what to send and to whom.
No issues, no PRs, no user management, no webhooks. Use the GitHub mirror for the social stuff; quire is your forge.
diff --git a/docs/config.md b/docs/config.md
index 55311bd..5dc440d 100644
--- a/docs/config.md
+++ b/docs/config.md
@@ -10,11 +10,14 @@ Lives at `/var/quire/config.fnl` on the bind-mounted volume.
Operator-created. Read once at launch; a server restart is required to
pick up changes.
-| Key | Type | Required | Purpose |
-|----------------------|----------------|----------|----------------------------------------------------------|
-| `:port` | integer | no | TCP port the HTTP server binds to (on `0.0.0.0`). Default: `3000`. |
-| `:sentry :dsn` | `SecretString` | no | Sentry DSN for error reporting from both `quire` and `quire-ci`. Omit to disable. |
-| `:secrets` | table | no | Named secrets exposed to `ci.fnl` jobs as `(secret :name)`. |
+| Key | Type | Required | Purpose |
+|---------------------------|----------------|----------|----------------------------------------------------------|
+| `:port` | integer | no | TCP port the HTTP server binds to (on `0.0.0.0`). Default: `3000`. |
+| `:sentry :dsn` | `SecretString` | no | Sentry DSN for error reporting from both `quire` and `quire-ci`. Omit to disable. |
+| `:secrets` | table | no | Named secrets exposed to `ci.fnl` jobs as `(secret :name)`. |
+| `:github :mirror-token` | `SecretString` | no | Token used to authenticate pushes to per-repo GitHub mirrors. Required for mirroring to work; omit to disable. |
+
+Note: key names use hyphens, not underscores (e.g. `:mirror-token`, not `:mirror_token`).
Minimal (no Sentry, no secrets):
@@ -38,11 +41,26 @@ the server from starting.
Files quire reads from a checked-in `.quire/` directory in the working
tree:
-- `.quire/ci.fnl` — pipeline definition (jobs, image, mirror).
+- `.quire/ci.fnl` — pipeline definition (jobs, image).
- `.quire/Dockerfile` — image built per run when the CI executor is
`docker` and no other image is supplied.
-- `.quire/config.fnl` — reserved for future use (notifications,
- visibility settings, etc.); not yet read.
+- `.quire/config.fnl` — per-repo settings; read at the pushed commit's
+ SHA on every push.
+
+### `.quire/config.fnl` schema
+
+| Key | Type | Required | Purpose |
+|----------------------|--------|----------|----------------------------------------------------------------|
+| `:github :mirror` | string | no | HTTPS URL to mirror every pushed ref to (e.g. `"https://github.com/user/repo.git"`). Requires `:github :mirror-token` in the global config. |
+
+Example:
+
+```fennel
+{:github {:mirror "https://github.com/user/repo.git"}}
+```
+
+The file is read via `git show <new-sha>:.quire/config.fnl`, so changes
+take effect on the push that includes the commit updating the file.
## SecretString values