]> quire.kejadlen.dev Git - quire.git/commitdiff
Align docs with code after accuracy audit
authorAlpha Chen <alpha@kejadlen.dev>
Sun, 26 Apr 2026 21:52:47 +0000 (21:52 +0000)
committerAlpha Chen <alpha@kejadlen.dev>
Mon, 27 Apr 2026 01:34:37 +0000 (18:34 -0700)
The audit found docs claiming `quire new` (CLI is `quire repo new`),
git 2.36+ (Dockerfile builds 2.54), and a stale fennel.md describing
a once-per-process Fennel that the code constructs per-call. README's
"Design phase" status also undersold actual progress.

Assisted-by: Claude Opus 4.7 via Claude Code
README.md
docs/PLAN.md
docs/fennel.md
docs/host/README.md

index 4b2f823a1294ad4f8aae3dc544bed84771253721..e5fef318f51b45d1c39a279ce25fa49d71dbe752 100644 (file)
--- a/README.md
+++ b/README.md
@@ -8,7 +8,7 @@ Named after the old bookbinding term: a gathering of folded leaves, sewn togethe
 
 A Rust binary that runs in a Docker container, fronted by the host's sshd and a TLS-terminating reverse proxy. It gives you:
 
-- **Git hosting over SSH**, via the host's sshd dispatching into the container. Explicit repo creation (`ssh git@host quire new <name>`).
+- **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.
 - **Automatic mirroring to GitHub** on push, when configured per-repo. Each repo carries its own deploy key — no agent socket to plumb across the host/container boundary.
 - **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.
@@ -45,4 +45,4 @@ Host-side config (sshd_config block, Caddyfile, docker-compose file) lives on th
 
 ## Status
 
-Design phase. See `PLAN.md` for the build sequence and open questions.
+Early development. SSH dispatch, repo management, and Fennel config loading work; web view, CI, mirroring, and notifications are still ahead. See `PLAN.md` for the build sequence and open questions.
index 1b8f8607a1d450aee382d619685b23284ab09e19..6d21d75f1af8c5dc8a7d1ce92e7bb8c25b7bff04 100644 (file)
@@ -204,7 +204,7 @@ Keyboard navigation in the web UI. Atom feeds for recent commits (public, subjec
 - **Web visibility: public by default, per-repo opt-outs.** Repos are public (they go to GitHub anyway); CI logs require auth. Per-repo `(private true)` and `(public_runs true)` flags cover the exceptions.
 - **Trust the proxy-injected identity header.** `Remote-User` is trusted because the reverse proxy is the only ingress. Proxy must strip any client-supplied version before injecting its own — this is the security-critical invariant.
 - **Explicit repo creation, not implicit on first push.** `ssh git@host quire new <n>`. No magic, no shims parsing first pushes.
-- **Hooks via `hook.<n>.command` config.** Git 2.36+. No shim scripts on disk; `hook.<n>.command = /usr/local/bin/quire hook <n>`. Set at creation time.
+- **Hooks via `hook.<n>.command` config.** Git 2.54+ (the version we build into the container image). No shim scripts on disk; `hook.<n>.command = /usr/local/bin/quire hook <n>`. Set at creation time.
 - **Mirror push is synchronous in post-receive.** Slow GitHub = slow push. Worth it; silent drift is the worst outcome.
 - **No reverse-direction mirroring.** quire is the source of truth; GitHub is the replica.
 - **CI pipelines are Fennel macros, not data tables.** The whole point is real code. Shared steps can be factored into `.quire/lib/*.fnl` and `require`'d.
index a3b7283db2a5d17e9b116ff680e0064ceb98a326..abc193db6e0092dcb5e7d5d0437f5bd54b5261d1 100644 (file)
@@ -15,9 +15,9 @@ machinery later, but its design is out of scope here.
 - **Vendored Fennel compiler** — `fennel.lua` from upstream (BSD-3,
   single Lua file). Bundled via `include_str!`, registered into the VM
   as a module at construction.
-- **`Fennel` struct** — owns the `Lua` instance and a reference to the
-  loaded `fennel` module. Constructed once per process; `load_file` and
-  `load_string` are methods.
+- **`Fennel` struct** — owns a `Lua` instance with the Fennel compiler
+  registered as a Lua global. `load_file` and `load_string` are methods
+  that look the global up on each call.
 
 ## Decisions
 
@@ -34,9 +34,10 @@ A representative per-repo config:
                  :on [:ci-failed :mirror-failed]}}
 ```
 
-One `Fennel` per process, reused across loads. Hooks load 1–2 files;
-`quire serve` loads many. Avoids re-loading the compiler on each
-call. Cheap enough that tests construct freely.
+Today each call site (`Quire::global_config`, `Repo::config`)
+constructs a fresh `Fennel`. Cheap enough at current call volume.
+Reusing a single instance across loads is a planned optimization for
+when `quire serve` lands and starts loading per-request.
 
 `load_string` is the primitive; `load_file` wraps it. Per-repo config
 comes from `git show` stdout, not a path on disk, so the string form is
@@ -47,8 +48,9 @@ Errors flow through miette. Wrap `mlua::Error` with the source name
 and any line/column info Lua surfaces. Hook log lines should point at
 the offending file and line, not just "syntax error."
 
-New top-level `src/fennel.rs`. Used by the still-to-come
-`src/config/global.rs` and `src/config/repo.rs`.
+Lives in `src/fennel.rs`. Used by `Quire::global_config` and
+`Repo::config` in `src/quire.rs`, which also define the `GlobalConfig`
+and `RepoConfig` schemas.
 
 ## Contracts
 
@@ -65,13 +67,13 @@ impl Fennel {
 Errors: file-not-found, parse error, eval error, type mismatch — all
 `miette::Result` with named source labels where Lua provides them.
 
-## Out of scope
+## Related modules
 
-- `SecretString` / `!cmd` resolution — chunk 2. Fennel produces plain
-  strings; `SecretString` is a `serde` newtype that resolves on access.
-- `git show HEAD:.quire/config.fnl` plumbing — chunk 3.
-- Any `mirror`/`notifications`/`private` schema — defined when chunks 2
-  and 3 land.
+- `src/secret.rs` — `SecretString` wraps Fennel-loaded strings that
+  resolve from a file or shell command on access.
+- `src/quire.rs` — `Repo::config` reads per-repo Fennel via `git show
+  HEAD:.quire/config.fnl`; `Quire::global_config` reads the global
+  config from disk. Both define the schema structs they parse into.
 
 ## Test plan
 
index ce3f1bd0abb29c081cc18513c475e3b4341ed5af..1f56d8fb9594c07c968ebd0db8adbc638de0e214 100644 (file)
@@ -33,6 +33,7 @@ Reference configs for dispatching SSH connections into the quire container.
            --user "$(id -u git):$(id -g git)" \
            -e HOME=/tmp \
            -v /var/quire:/var/quire \
+           -p 127.0.0.1:3000:3000 \
            quire
 
    In a compose file, the equivalent is `user: "${QUIRE_UID}:${QUIRE_GID}"`
@@ -41,7 +42,7 @@ Reference configs for dispatching SSH connections into the quire container.
 
 5. Create a test repo inside the container:
 
-       docker exec quire-container quire new foo.git
+       docker exec quire-container quire repo new foo.git
 
 6. Test the dispatch path:
 
@@ -61,3 +62,7 @@ errors from git when the bind-mounted repo dir's host uid wouldn't
 otherwise match a container user. `HOME=/tmp` is set because the host
 uid has no `/etc/passwd` entry inside the container, and git needs a
 writable `HOME` for its config probing.
+
+The HTTP port (3000) is published to host loopback only. A reverse proxy
+on the host terminates TLS and reverse-proxies to it; nothing else
+should reach it directly.