1 Commits
Author SHA1 Message Date
clawbot 2f00ed18fd Rewrite AGENTS.md sentence by sentence
check / check (push) Canceled after 0s
Rewrite the agent rules from scratch, as a newcomer would read them,
with one idea per sentence and every file name and command in
backticks. Drop the rule that models embed `models.Base`, which no
package in the repository has, and the statement that tests share
their package: nearly every test is in an external test package with
an `export_test.go` beside it. State the branch workflow in use: pull
requests target `next` and only the owner merges `next` into `main`.
Record the three snake_case JSON tags the HTTP API keeps.

Part of #190.

Model: fable-5-1
2026-10-27 12:51:02 +00:00
+47 -38
View File
@@ -1,55 +1,64 @@
# 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` ## Before every commit
2. **Check**: `make check` — the tests and the linter, which run in Docker, and
the format check: all passing, zero issues
Never run `go test`, `golangci-lint` or `gofmt` directly; use the `make` 1. Run `make fmt`.
targets. 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 `make` targets
hold the flags and the Docker setup.
## Code Style ## Branches and pull requests
- Follow CONVENTIONS.md exactly — it defines the architecture - Never commit to `main` or `next` directly. Every change is a pull request from
- All exported types, functions, methods, and vars must have doc comments a feature branch into `next`.
- All packages must have a package doc comment - Only the owner merges `next` into `main`.
- JSON tags use camelCase (not snake_case) - A pull request that closes an issue has the title `Description (closes #N)`.
- No magic numbers — use named constants - One logical change per commit.
- No inline error handling (`if err := ...; err != nil`) — use plain assignment - Commit messages are in the imperative mood and short.
- Blank line before every `return` statement
- Blank line separating embedded fields from regular fields in structs
- Blank imports must have a justification comment
## Git Workflow ## Code style
- **Never commit directly to main** — all changes go on feature branches - Follow `CONVENTIONS.md`.
- Merge to main only when ready and passing all checks - Every package has a package doc comment. Every exported type, function, method
- PR titles: `Description (closes #N)` when closing an issue and variable has a doc comment.
- One logical change per commit - JSON tags are camelCase. The HTTP API's `last_id`, `pow_token` and
- Commit messages: imperative mood, concise `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 ## Architecture
- Dependency injection via Uber fx — all components are fx providers - Dependency injection uses Uber `fx`. Every component is an `fx` provider,
- `internal/` for all application packages — one package per concern wired together in `cmd/neoircd/main.go`.
- Handlers return `http.HandlerFunc` using the closure pattern - Application packages live under `internal/`, one package per concern.
- Request/response structs defined inside handler closures `pkg/irc` holds the IRC command names and numeric reply codes.
- Models embed `models.Base` for database access to relation methods - A handler method returns an `http.HandlerFunc`.
- Database migrations in `internal/db/schema/` — embedded via `go:embed` - A request struct is defined inside the handler that decodes it.
- SQLite by default (pure Go driver: modernc.org/sqlite) - Database access goes through the methods of `db.Database`.
- The database schema lives in `internal/db/schema/` and is embedded with
`go:embed`.
- The database is SQLite, through the pure Go driver `modernc.org/sqlite`.
## Testing ## Testing
- Table-driven tests preferred - Prefer table-driven tests.
- Use `testing.T` helpers, not assertion libraries - Use `testing.T` helpers, not assertion libraries.
- Test files live next to the code they test - A test file lives next to the code it tests and ends in `_test.go`.
- `_test.go` suffix, same package for white-box testing - Tests are in the package's external test package, such as `handlers_test`. An
`export_test.go` file in the package itself exposes what the tests need.
## Dependencies ## Dependencies
- Required libraries are listed in CONVENTIONS.md §1 - The required libraries are listed in `CONVENTIONS.md` §1.
- No new dependencies without justification - No new dependency without a reason given in the pull request.
- Pure Go preferred (no CGO) - Prefer pure Go. No cgo.