Sign in

Search issue titles and bodies, change requests and comments. Private repositories you cannot read are not included.

vole
Clone

Read only, no credentials:

https://rodent.software/git/vole.git

Write over SSH with a registered key:

git clone ssh://git@0.0.0.0:2222/vole.git

A free and open-source forge that lives in your Git repo.

Docs: rewrite the README and organize the guides

520470e19cd906bd6fff987e2d132d793ce56486 · Keenan Nemetz · 16d ago · parent c5902451

Docs: rewrite the README and organize the guides

Replace the long README with a landing page, split feature details into focused guides, and remove the roadmap and spike notes. Update comments that referenced them.

docs/architecture.md +105

@@ -0,0 +1,105 @@
1 # Architecture and design
2
3 This page is for people who want to understand how Vole works and why it makes
4 the choices it does. If you only want to use Vole, the guides are enough.
5
6 The goal is not novelty. The goal is a forge that stays understandable, works on
7 hardware you control, and keeps the important parts in Git.
8
9 Vole is built for one team on one server. It does not try to be a hosted service,
10 and it does not connect to other Vole instances. That keeps the design small.
11
12 ## Trust: your key is your identity
13
14 Vole uses one rule everywhere:
15
16 > Your SSH key proves who you are. Vole checks every change before accepting it,
17 > and records the decision in `data/audit.log`.
18
19 There is no second login system for writes. The web interface is read-only.
20 Approvals, comments, and CI results all belong to the account whose key pushed
21 them.
22
23 Vole does not require or check Git commit signatures. A signature would only
24 repeat what the SSH connection already established, and it cannot reliably prove
25 who authored a commit. Vole would rather keep one clear path than add a second
26 one that can disagree with the first.
27
28 ## What that means
29
30 On the server, Vole can show a complete history of who pushed what. A clone of a
31 repository, by itself, cannot prove who pushed a commit. The instance promises a
32 complete record; it does not promise offline proof.
33
34 That trade-off is wrong if you plan to mirror the repository somewhere controlled
35 by someone else. For a team running its own forge, it keeps the system simple and
36 auditable.
37
38 ## Where data lives
39
40 | Data | Where it lives | Rebuildable? |
41 |---|---|---|
42 | Repositories | `data/repos/<name>.git` | It is the source |
43 | Issues, requests, approvals, release pointers, CI records | The `vole` branch in each repository | It is the source |
44 | Accounts, SSH keys, access rules, locks | `data/users.db` | No; back it up |
45 | Web/search index | `data/index.db` | Yes, with `vole index rebuild` |
46 | CI queue and run index | `data/runs.db` | Partly; in-progress work is lost |
47 | LFS files, CI logs, build artifacts | `data/lfs/` | No; stored by content |
48 | Privileged-action history | `data/audit.log` | It is the record |
49 | SSH host key | `data/ssh_host_ed25519_key` | No; it is the secret |
50
51 Git holds the project history. SQLite holds the user database, the CI queue, and
52 generated indexes. Anything that can be rebuilt comes from Git or stored files.
53 Anything that cannot be rebuilt is small and easy to back up.
54
55 The `vole` branch contains:
56
57 ```text
58 issues/<ulid>/issue.md
59 issues/<ulid>/comments/<ulid>.md
60 requests/<ulid>/request.md
61 requests/<ulid>/comments/<ulid>.md
62 requests/<ulid>/approvals/<account-id>.md
63 releases/<tag>/<artifact>
64 runs/<run-id>/<attempt>/...
65 ```
66
67 People write the issue and request files. Vole writes the run records. All of it
68 is checked when it is pushed.
69
70 ## Why these choices
71
72 | Choice | Reason |
73 |---|---|
74 | Use the Git command-line tool | Full push behavior and hooks without reimplementing Git |
75 | SSH for writes, HTTP for anonymous reads | One authenticated way to change data; reads stay simple |
76 | Check everything before accepting a push | One place for policy; the web has no writes to protect |
77 | Store metadata in Git, rules in SQLite | Project content travels with clones; local settings stay local |
78 | No web login | The web is read-only, so there is no password store or session to build |
79 | One program with separate serve and runner modes | Easy to deploy anywhere |
80 | Keep the host key as the only secret | No signing key to manage or leak |
81
82 ## Using Vole as a library
83
84 Vole is also a Go library. You can build tools that talk to an instance or embed
85 parts of Vole without running the `vole` command.
86
87 | Package | What it does |
88 |---|---|
89 | `client` | Talks to an instance: metadata writes, identity lookups, file transfer, reviews, and site deploys |
90 | `core/id`, `core/git`, `core/lfs` | Shared primitives and storage |
91 | `forge` | Instance setup and administration |
92 | `forge/config`, `forge/identity`, `forge/access`, `forge/repo`, `forge/index` | Settings, accounts, permissions, repositories, and search |
93 | `metadata` | Issues, requests, releases, comments, approvals, and validation |
94 | `ci` | Workflow validation and the job queue; `ci/agent` is the embeddable runner |
95 | `server` | Network listeners and web pages, with adapters for SSH, Git HTTP, sites, and hooks |
96
97 `cmd/vole` is only the command-line front end. Logic shared by more than one
98 caller lives in the packages above.
99
100 ## Scope
101
102 Vole is built for one team on one server. It does not support multiple tenants,
103 federation, container-isolated CI steps, custom domains with automatic
104 certificates, horizontal scaling, or a Kubernetes deployment story. These are not
105 part of Vole today.