diff --git a/AGENTS.md b/AGENTS.md index d189eb2..ba6d790 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,55 +1,65 @@ -# AGENTS.md — Rules for AI Agents +# Rules for coding agents -## Before Every Commit +Rules for coding agents working in this repository. `CONVENTIONS.md` defines the +architecture and `REPO_POLICIES.md` the repository standards. Both are copies of +shared documents and are not edited here. -1. **Format**: `make fmt` -2. **Check**: `make check` — the tests and the linter, which run in Docker, and - the format check: all passing, zero issues +## Before every commit -Never run `go test`, `golangci-lint` or `gofmt` directly; use the `make` -targets. +1. Run `make fmt`. +2. Run `make check`. It runs the tests and the linter in Docker, then the format + check. All three must pass with no findings. -No commit lands on main with lint errors, test failures, or formatting issues. +Never run `go test`, `golangci-lint` or `gofmt` directly. The scripts in +`script/` hold the flags and the Docker setup. -## Code Style +## Branches and pull requests -- Follow CONVENTIONS.md exactly — it defines the architecture -- All exported types, functions, methods, and vars must have doc comments -- All packages must have a package doc comment -- JSON tags use camelCase (not snake_case) -- No magic numbers — use named constants -- No inline error handling (`if err := ...; err != nil`) — use plain assignment -- Blank line before every `return` statement -- Blank line separating embedded fields from regular fields in structs -- Blank imports must have a justification comment +- Never commit to `main` or `next` directly. Every change is a pull request from + a feature branch into `next`. +- Only the owner merges `next` into `main`. +- A pull request that closes an issue has the title `Description (closes #N)`. +- One logical change per commit. +- Commit messages are in the imperative mood and short. -## Git Workflow +## Code style -- **Never commit directly to main** — all changes go on feature branches -- Merge to main only when ready and passing all checks -- PR titles: `Description (closes #N)` when closing an issue -- One logical change per commit -- Commit messages: imperative mood, concise +- Follow `CONVENTIONS.md`. +- Every package has a package doc comment. Every exported type, function, method + and variable has a doc comment. +- JSON tags are camelCase. The HTTP API's `last_id`, `pow_token` and + `hashcash_bits` stay as they are, each with a `//nolint:tagliatelle` comment. +- No magic numbers. Use named constants. +- No inline error handling such as `if err := f(); err != nil`. Assign the error + on its own line, then test it. +- A blank line before every `return`. +- A blank line between the embedded fields of a struct and its other fields. +- Every blank import has a comment saying why it is there. ## Architecture -- Dependency injection via Uber fx — all components are fx providers -- `internal/` for all application packages — one package per concern -- Handlers return `http.HandlerFunc` using the closure pattern -- Request/response structs defined inside handler closures -- Models embed `models.Base` for database access to relation methods -- Database migrations in `internal/db/schema/` — embedded via `go:embed` -- SQLite by default (pure Go driver: modernc.org/sqlite) +- The server uses `go.uber.org/fx` for dependency injection. Each of its + components is an `fx` provider, wired together in `cmd/neoircd/main.go`. +- Application packages live under `internal/`, one package per concern. + `pkg/irc` holds the IRC command names and numeric reply codes. +- A handler method returns an `http.HandlerFunc`. +- A request struct is defined inside the handler that decodes it. +- Database access goes through the methods of `db.Database`. +- The database migrations live in `internal/db/schema/` and are embedded with + `go:embed`. +- The database is SQLite, through the pure Go driver `modernc.org/sqlite`. ## Testing -- Table-driven tests preferred -- Use `testing.T` helpers, not assertion libraries -- Test files live next to the code they test -- `_test.go` suffix, same package for white-box testing +- Prefer table-driven tests. +- Use `testing.T` helpers, not assertion libraries. +- A test file lives next to the code it tests and ends in `_test.go`. +- Tests are in the package's external test package, such as `handlers_test`. + When a test needs an unexported name, an `export_test.go` file in the package + exposes it. ## Dependencies -- Required libraries are listed in CONVENTIONS.md §1 -- No new dependencies without justification -- Pure Go preferred (no CGO) +- The required libraries are listed in `CONVENTIONS.md` §1. +- No new dependency without a reason given in the pull request. +- Prefer dependencies written in pure Go, which build without cgo.