Author SHA1 Message Date
clawbot 4e960a61ee Start test servers on a port the system picks (closes #211)
check / check (push) Canceled after 0s
The internal/server and internal/ircserver tests picked a port by
opening a listener, reading its port and closing it. They then started
a server on that number. Another process could take the port in
between, and a test failed with "address already in use".

The IRC server tests now start the server on 127.0.0.1:0 and read the
port back from its listener. The HTTP server tests start the app with
port 0. The HTTP server now keeps the listener it binds, so the stop
test sends its long poll to the port the app was given.

Model: opus-5-5
2026-10-27 12:16:02 +00:00
+38 -56
View File
@@ -1,73 +1,55 @@
# Rules for coding agents # AGENTS.md — Rules for AI Agents
This file holds the rules for coding agents working in this repository. ## Before Every Commit
`CONVENTIONS.md` defines the architecture. `REPO_POLICIES.md` defines the
repository standards. Both are copies of shared documents. Do not edit them
here.
## Before every commit 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
1. Run `make fmt`. Never run `go test`, `golangci-lint` or `gofmt` directly; use the `make`
2. Run `make check`. It runs the tests and the linter in Docker, then the format targets.
check. All three must pass with no findings.
Never run `go test`, `golangci-lint` or `gofmt` directly. Use the `make` targets No commit lands on main with lint errors, test failures, or formatting issues.
instead, such as `make test` and `make lint`.
## Branches and pull requests ## Code Style
- Never commit to `main` or `next` directly. Every change is a pull request from - Follow CONVENTIONS.md exactly — it defines the architecture
a feature branch into `next`. - All exported types, functions, methods, and vars must have doc comments
- Only the owner merges `next` into `main`. - All packages must have a package doc comment
- A pull request that closes an issue has the title `Description (closes #N)`. - JSON tags use camelCase (not snake_case)
- One logical change per commit. - No magic numbers — use named constants
- Commit messages are in the imperative mood and short. - 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
## Code style ## Git Workflow
- Follow `CONVENTIONS.md`. - **Never commit directly to main** — all changes go on feature branches
- Outside test files, every package has a package doc comment. - Merge to main only when ready and passing all checks
- Outside test files, every exported type, function and variable has a doc - PR titles: `Description (closes #N)` when closing an issue
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.
- Prefer named constants to magic numbers. The `mnd` linter checks for them
outside test files.
- No inline error handling such as `if err := f(); err != nil`. Assign the error
on its own line, then test it.
- A `return` that follows another statement in its block has a blank line before
it.
- A blank line between the embedded fields of a struct and its other fields.
- Outside test files, every blank import has a comment saying why it is there.
## Architecture ## Architecture
- The server uses `go.uber.org/fx` for dependency injection. - Dependency injection via Uber fx — all components are fx providers
`cmd/neoircd/main.go` lists its `fx` providers, such as `db.New` and - `internal/` for all application packages — one package per concern
`handlers.New`. - 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
- The `web` package embeds the built web client. - Database migrations in `internal/db/schema/` — embedded via `go:embed`
- Each exported `Handle…` method of `Handlers` returns an `http.HandlerFunc`. - SQLite by default (pure Go driver: modernc.org/sqlite)
- A request struct is defined inside the method that decodes it.
- The server uses the database only 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 ## Testing
- Prefer table-driven tests. - Table-driven tests preferred
- Use `testing.T` helpers, not assertion libraries. - Use `testing.T` helpers, not assertion libraries
- A test file lives next to the code it tests and ends in `_test.go`. - Test files live next to the code they test
- The linter requires each test file to be in the package's external test - `_test.go` suffix, same package for white-box testing
package, such as `handlers_test`. It allows `export_test.go` and files ending
in `_internal_test.go` in the package itself.
- An `export_test.go` file gives the external tests access to the package's
unexported code.
## Dependencies ## Dependencies
- The required libraries are listed in `CONVENTIONS.md` §1. - Required libraries are listed in CONVENTIONS.md §1
- No new dependency without a reason given in the pull request. - No new dependencies without justification
- Prefer dependencies written in pure Go, which build without cgo. - Pure Go preferred (no CGO)