diff --git a/AGENTS.md b/AGENTS.md index 7341dfe..e48eb27 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -88,6 +88,25 @@ on fixable CRITICALs if you ever want a gate. Renovate already keeps the digest pins moving, so the usual fix for a finding is to let it bump the image, not to hand-edit a tag. +## Agent tooling + +`.claude/` is checked in, so every agent working here starts from the same +setup: + +- **`agents/stack-consistency-reviewer.md`** — reviews a diff for convention + drift across the stacks. With this many near-identical Compose files, drift is + the failure mode, not bugs. +- **`skills/new-stack/`** — scaffolds a stack and its central backup wiring from + `templates/`. It carries `disable-model-invocation: true`, so it runs only + when a person asks for it by name. +- **`skills/backup-preflight/`** — the bind-mount path preflight, before + deploying a backup change. +- **Hooks** (`settings.json`): a PreToolUse hook refuses to edit a real `.env` — + those are gitignored, so the edit would be invisible and unshippable; edit the + `.env.example` instead. A PostToolUse hook runs + `hooks/validate-compose.sh` on whatever was just written, so a broken Compose + file surfaces at the edit rather than at `make check`. + ## Compose stack conventions - Each application stack lives in its own directory under `eggenberg-services//`. diff --git a/README.md b/README.md index 2e2c05c..9fb4896 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,25 @@ # docker-stack -Services live in separate Compose stacks under `eggenberg-services/`. +Services live in separate Compose stacks under `eggenberg-services/`, deployed +to TrueNAS through Dockhand. Central backups live in `infrastructure/`. + +There is no build step and no application code here — the whole repository is +Compose files, `.env.example` files and the scripts that check them. + +## Getting started + +```bash +make tools # install the pinned toolchain from mise.toml +make hooks # install the git pre-commit hooks, once +make check # what a PR needs: hooks + compose config + conventions +``` + +`make help` lists every target. Day to day: `make stacks` lists them, +`make config STACK=jellyfin` prints a stack's fully resolved Compose config, +and `make up|down|restart|pull|logs STACK=` operate on one. + +**Tool versions live in `mise.toml` and nowhere else**, and CI installs from the +same file — so a hook that passes locally passes in CI. ## Services @@ -50,3 +69,40 @@ Before deploying backup changes, run `infrastructure/volume-backup/check-backup- - Add a dedicated `_backup` service to `infrastructure/volume-backup/docker-compose.yaml` that mounts the stack directory read-only under `/backup/_stack` and writes archives to `${BACKUP_ROOT}//` - Add `_STACK_HOST_PATH` to `infrastructure/volume-backup/backup.env.example` - Define an explicit default network named `_network`, replacing hyphens with underscores + +## Checks + +`make check` is the whole local gate, and it is what a pull request runs: + +| Step | What it catches | +| --- | --- | +| `make lint` | yamlfmt, shellcheck/shfmt, gitleaks, and `actionlint` + `zizmor` over the workflows | +| `make validate` | `docker compose config` per stack — an interpolation or schema error before it reaches the host | +| `make conventions` | `scripts/check-stack-conventions.sh`: the `_network` naming rule and `.env.example` coverage for every variable a Compose file reads | + +`.env.example` coverage is the one worth calling out: a variable referenced in a +Compose file but missing from `.env.example` deploys fine on the host that +already has it set and fails for everyone else. The check exists because that +happened. + +One required check gates a merge: **`pre-commit`**. The image CVE sweep +(`scan.yml`) is deliberately not required — it is path-filtered and advisory, +and a required check that does not run on every pull request blocks the merge +for good. It runs weekly and answers "which of my services is currently +exposed"; a new upstream CVE in somebody else's image is not something a commit +here can fix. `make scan` runs the same sweep locally, `make scan-strict` fails +on fixable criticals. + +## Agent tooling + +`.claude/` is checked in: a `stack-consistency-reviewer` agent for diffs, a +`new-stack` skill that scaffolds all five pieces listed above from templates, a +`backup-preflight` skill, and two hooks — one refuses to edit a real `.env` +(they are gitignored, so the edit would be invisible), the other validates a +Compose file as soon as it is written. [`AGENTS.md`](AGENTS.md) is the detailed +guide. + +## License and security + +MIT ([`LICENSE`](LICENSE)). To report a vulnerability, see +[`SECURITY.md`](SECURITY.md) — please do not open a public issue for one.