Initial commit
Test / test (push) Successful in 7m5s
Release / gates (push) Successful in 7m28s
Release / build (amd64, freebsd) (push) Successful in 2m52s
Release / build (amd64, linux) (push) Successful in 2m46s
Release / build (arm64, freebsd) (push) Successful in 2m22s
Release / build (arm64, linux) (push) Successful in 2m38s
Release / build (loong64, linux) (push) Successful in 2m7s
Release / build (riscv64, linux) (push) Successful in 2m17s
Release / release (push) Successful in 1m0s

Assisted-by: GLM 5.3
This commit is contained in:
2026-09-29 10:03:32 +02:00
commit f8ed33df83
206 changed files with 44165 additions and 0 deletions
+149
View File
@@ -0,0 +1,149 @@
# Contributing
Contributions to **Volumen** are governed by the Contributor terms
below; submitting one means you accept them.
## Contributor terms
1. This project belongs to its owner alone. The owner decides what is
accepted, in what form and when; the decision is final and needs no
justification.
2. By submitting a contribution you assign to Petr Balvín
<opensource@petrbalvin.org> all present and future copyright and
related rights in it, worldwide, for the full term of the rights,
with the right to relicense and sublicense without restriction,
including under proprietary terms.
3. Where that assignment is not effective, it counts as a perpetual,
irrevocable, royalty-free licence with the same scope.
4. To the fullest extent permitted by law, you waive any right of
attribution and integrity in the contribution. The project names no
contributors and keeps no credits list.
5. By submitting you represent that the work is yours and that you
hold the rights to assign it as above.
## Development setup
Requirements: Go 1.27.1 (the version the `go` directive in `go.mod`
declares), [just](https://github.com/casey/just) for the recipes, Perl for
the scripted recipes (`just test` and `just fmt-check` are Perl, builtins
only), and gcc for the race detector, which `just race` and `just gates` run.
The build itself is pure Go with `CGO_ENABLED=0`.
```sh
git clone https://sourcedock.dev/petrbalvin/volumen.git
cd volumen
just build
just test
```
`just dev` serves the content directory `./posts` and the local
`config.toml` on <http://127.0.0.1:9091>; the config and the state files are
git-ignored. On a fresh checkout the first visit to `/admin` shows the
first-run wizard; it creates the developer's account with any password the
policy accepts. For a real install there is no bootstrap command: copy
`config.toml.example`, start the server, complete the wizard;
[docs/DEPLOYMENT.md](docs/DEPLOYMENT.md) has the full production setup.
The direct dependency set is fixed: scriptorium (Markdown, mathematics and
diagrams), bluemonday (sanitisation), interpres (TOML), `golang.org/x/crypto`
(scrypt) and `golang.org/x/text` (NFKC). A new third-party module needs a
justification that survives review.
## Workflow
1. Branch from `development`. Never commit directly to `main`, which is release-only.
2. Commit in [Conventional Commits](https://www.conventionalcommits.org/) form:
`type(scope): description`, subject line only, imperative mood, lowercase after the
colon, no trailing full stop. Allowed types: `feat`, `fix`, `docs`, `style`,
`refactor`, `perf`, `test`, `chore`, `ci`, `build`, `revert`.
3. One logical change per commit. A refactor, a behaviour change and a formatting pass
are three commits, never one.
4. Record every user-visible change in `CHANGELOG.md` under `## [development]`, using
the categories `Added`, `Changed`, `Fixed`, `Removed` and `Security`.
5. Add or update tests. Coverage stays at 80 percent or more; it is a hard gate.
6. Update the documentation when the public API, the configuration or the behaviour
changes: `README.md`, `docs/CONFIGURATION.md`, `docs/API.md` and
`docs/ARCHITECTURE.md` are the ones that move most often. A change to the command
line moves `docs/CLI.md` and `man/volumen.1` in the same commit as the flags it
documents.
7. Never commit while `just gates` is red; run it locally first.
8. Open a pull request against `development`.
Releases are cut by merging `development` into `main` and tagging `vX.Y.Z`. The release
workflow runs the gates at the tag, builds the portable matrix and publishes the release
with the notes it extracts from `CHANGELOG.md`;
[docs/DEVELOPMENT.md](docs/DEVELOPMENT.md) has the detail.
## Code style
`gofmt` and `go vet` run through `just fmt` and `just vet`, with zero diff and zero
warnings tolerated; `just vet` is `go vet` followed by `go fix -diff`. `just gates` is
the definition of done in one command, and the recipe file names what it contains.
Errors are checked explicitly, wrapped as `fmt.Errorf("context: %w", err)`, and nothing
panics outside `main`; diagnostics go through `log/slog`, never `fmt.Print` in library
code. Names, messages and comments are in British English. The recipe file holds the
commands.
Tests live next to the code in `*_test.go`, use `t.TempDir()` for fixtures and
`net/http/httptest` for the HTTP layer, and never start a real network server or reach
the internet. Table-driven tests where the cases are enumerable; run `just race` before
merging anything that shares state. Handlers live in `internal/httpapi` (public API) and
`internal/admin` (admin UI), with the middleware in `internal/web`; read the security
model in [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) before touching auth, uploads or
rendering.
New source files open with the project's two-line licence header, whose SPDX
identifier matches `LICENSE`. Configuration files, workflows and dotfiles do not carry
it.
## AI contribution policy
AI tools are welcome as productivity aids and are a normal part of modern software
development. What matters is that the contribution stays understandable, reviewable and
genuinely useful.
- **Disclose the assistance.** If AI helped draft any part of a commit, issue, pull
request or review, say so.
- **Commit messages carry exactly one trailer**, on the line after the subject:
```text
Assisted-by: MODEL
```
Name the model that did the work, spelled the way its maker spells it, for example
`GLM 5.3`, `DeepSeek V4.1 Flash` or `Qwen 3.8 Flash`. No `Co-Authored-By`, no
`Signed-off-by`, no other trailers, and no prose: the trailer is the disclosure.
- **Issues and pull requests** attribute the assistance in a comment, for example
`_Assisted-by: GLM 5.3_`. It does not belong in the pull request description.
- **Take responsibility.** You are accountable for the accuracy, completeness and
intent of everything you submit, whether or not AI produced it.
- **Review before marking ready.** Read the diff carefully, run it locally, and add the
tests it needs. Do not mark a pull request ready until you can defend every change in
it.
- **Quality over quantity.** Contributions that look like un-reviewed output, or whose
author cannot engage substantively during review, may be closed.
- **Preferred models.** Prefer open-weight models with transparent training data and
minimal output filtering.
AI assists. It does not replace judgement.
## Continuous integration
Workflows live in `.gitea/workflows/` and run on the project's own runners:
| Workflow | Trigger | What it does |
|---|---|---|
| Test | push or pull request to `development` | build, format check, vet, modernisation, the test suite with the coverage floor |
| Race | dispatched by hand | the suite under the race detector, as a second opinion after the local gate |
| Release | a `v*` tag | the same gates as Test, then the matrix build, the proven version and the release itself; the race detector runs locally in `just gates` before the tag is cut |
The local equivalent is `just gates`, which is the same set plus the race detector.
## Reporting bugs
Open an issue at `https://sourcedock.dev/petrbalvin/volumen/issues` with the
version (`volumen version`), the operating system and architecture, the exact command,
the full output, and the expected against the actual behaviour.
**Security issues do not go in the issue tracker.** Report them as
[SECURITY.md](SECURITY.md) describes.