Files
guard/AGENTS.md
T
abrown38andClaude Opus 5.5 941d4fb10d Release setup: tarballs, Gitea workflow, apt registry
make dist builds tarballs for linux/amd64 and linux/arm64. A pushed v*
tag runs .gitea/workflows/release.yml, which checks the tag against
VERSION and the CHANGELOG, tests, builds the tarballs and the .debs
(amd64, arm64) and publishes them with scripts/gitea-release.sh: a Gitea
release, and the .debs in the Debian registry (stable, or testing for a
release candidate). As in Housecarl and Steward; no cli-dist, Guard is
Linux only. docs/development.md has the steps, docs/install.md the apt
source.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 16:44:58 +01:00

61 lines
2.5 KiB
Markdown

# Working on Guard
Notes for coding agents (and people) changing this repository.
Guard watches logs and bans misbehaving addresses in Housecarl's ban
lists (`../housecarl`, its docs/bans.md). It is the fourth of a set with
Jarl (`../jarl`), Steward (`../steward`) and Housecarl, and copies their
ways: Go, `CGO_ENABLED=0`, one YAML file, the same release process. It
has no web UI and no database: bans are shown by Housecarl.
## Layout
* `cmd/guard`: the one binary (cobra): `run` is the daemon, the rest are
tools.
* `internal/config`: guard.yaml, with `presets.yaml` and `example.yaml`
embedded. A watch's preset is resolved here (`Watch.resolve`).
* `internal/match`: patterns with `<IP>`; `Group` (IPv6 by prefix).
* `internal/source`: files (polled tail -F), the journal (journalctl
subprocess, `GUARD_JOURNALCTL` for tests), Housecarl's log.
* `internal/bounty`: per-watch counts within a window.
* `internal/daemon`: lines → matches → bounties → bans, the retry queue,
the status socket, `never_ban`.
* `internal/housecarl`: the API client (ban lists, bans, the log).
* `internal/state`: the JSON state file.
## Ground rules
* **Never trust a client's text for the address.** Preset patterns put
`<IP>` where the program writes the address, after anything a client
chose, anchored at the line's end where the format allows. Every
preset has sample lines in `testdata/presets/NAME.txt` (the address
to find, or `-`), including an attempt to plant an address;
`TestPresets` runs them.
* **No timestamp parsing.** Lines count when read (the journal's and
Housecarl's carry their own time).
* **Never ban on spoofable evidence by default**: UDP sources can be
faked (`housecarl-drops` is TCP unless told otherwise; no preset for
BIND's UDP refusals).
* **Every user-visible change updates `CHANGELOG.md`** under
`## [Unreleased]`, and the matching `docs/` page.
* `make test` runs `go vet`, a `gofmt -l` check and the tests.
## Testing
```sh
make test
make e2e # with ../housecarl's lab: needs Docker (DOCKER_HOST=unix:///var/run/docker.sock here)
```
## Git and releases
As in Housecarl: commit only when asked, never push; branches
`dev-X.Y.Z`; a release is a commit "Release X" setting `VERSION`, with
the annotated tag `vX` ("Guard X"). Pushing the tag runs
`.gitea/workflows/release.yml` (docs/development.md, "Releasing").
## Shell hygiene
Never kill processes by pattern (`pkill -f`): the pattern matches the
shell running it. Find the PID and kill that.