Operational guide for AI coding agents (Claude Code, Codex, Cursor, etc.) working in this repo. Humans should read CONTRIBUTING.md first — this file is a condensed, task-oriented overlay that assumes you already have it.
A single-binary book download manager (Readarr replacement) — Go 1.25 backend with an embedded React 19 SPA, SQLite via modernc.org/sqlite (no CGO), distroless container image. Architecture, feature surface, and deployment are documented in README.md and docs/DEPLOYMENT.md.
cmd/bindery/ entry point, migrate / proxy / reconcile / healthcheck subcommands
internal/api/ chi HTTP handlers — one file per resource, *_test.go alongside
internal/auth/ argon2id passwords, HMAC sessions, OIDC, proxy auth
internal/db/ sqlite repository layer + migrations (use db.OpenMemory in tests)
internal/{indexer,downloader,importer,metadata,recommender,scheduler,notifier}/
business logic by domain
internal/webui/ go:embed wrapper for web/dist
web/ React 19 + TS + Tailwind, Vite, vitest
charts/bindery/ Helm chart (image tag auto-bumped by CI)
docs/ deployment, ABS import, hardcover, calibre, roadmap
tests/{smoke,predeploy,abscontract,security}/
out-of-process suites
Use make help to discover targets. The ones agents need most:
| Task | Command |
|---|---|
| Build binary (embeds web) | make build |
| Run backend in dev | make dev |
| Run frontend dev server | make web-dev (proxy to backend on :8787) |
| Backend unit + integration tests | make test (race + coverage) |
| Frontend tests | make test-web |
| All linters | make lint |
| Go-only / web-only lint | make lint-go / make lint-web |
| HTTP smoke suite (real binary) | make smoke |
| ABS contract suite (slow) | make abs-contract |
| Local security scanners | make security |
| Helm chart lint | make helm-lint |
Before reporting work complete, run the relevant subset — see the testing skill for the full pre-PR matrix and pinned tool versions, or CONTRIBUTING.md §Running the full local check suite for the canonical reference.
Go
- Linter is
golangci-lint v2.11.4withgosec,revive,errorlint,bodyclose,noctx,rowserrcheck,sqlclosecheck,staticcheckenabled. Read.golangci.ymlbefore adding suppressions — many common warnings already have project-wide exclusions. - HTTP handlers go in
internal/api/<resource>.gowith a sibling<resource>_test.go. - DB access goes through
internal/db; do not opendatabase/sqlconnections elsewhere. - Outbound HTTP must use the SSRF-guarded clients in
internal/httpsec. Neverhttp.Getraw user-provided URLs. - Errors: wrap with
%w, compare witherrors.Is/As.
Frontend
- React 19 + TypeScript strict + Tailwind. ESLint 9 flat config in
web/eslint.config.js. - Pages live in
web/src/pages, shared components inweb/src/components, API client inweb/src/api. i18n keys inweb/src/i18n— every user-facing string flows throughuseTranslation.
Test patterns (db.OpenMemory, httptest, vitest + @testing-library/react) and the rule that tests are required for new handlers / domain logic / components-with-logic are documented in the testing skill.
- Migrations are forward-only. Add a new file in
internal/db/migrations/— never edit a migration that has shipped. - Schema drift in tests — tests run real migrations against
db.OpenMemory. If a migration fails, every test in the package fails; check there first. internal/webui/dist/is generated;make buildcopiesweb/dist/*into it beforego build. Don't commit changes to it;web/is the source of truth.- CHANGELOG.md is authored at release time only — see the
tag-releaseskill. Don't add[Unreleased]entries during feature work; CI only validates that a## [vX.Y.Z]section exists at tag time. - Helm
values.yamlimage digest is auto-bumped by CI with[skip ci]. Don't hand-edit the digest. - Secrets in source are blocked by gitleaks + GitHub Push Protection. Use the SQLite-backed settings store (configured at runtime) for any credential — see
internal/authandinternal/config. - The frontend talks to the backend over
/api/v1only (plus the*arr-compatible/api/queueand/opds/v1.2/). Auth rules per route live ininternal/api/auth.go`.
- Issue first for non-trivial work. Search existing issues; check
docs/ROADMAP.md. The README explicitly asks contributors to open an issue before starting anything substantial. - Branch from
main. Naming, scope vocabulary, and full message format are in thecommitsskill. - Implement — keep diffs narrow. CONTRIBUTING.md §"Pull request flow" is explicit: this project prefers tightening the diff over surrounding cleanup.
- Test as you go. The
testingskill covers patterns and the pre-PR matrix;smoke-testingcovers when to escalate to out-of-process suites. - Update docs as part of the commit:
docs/andREADME.mdare maintained at every commit (full matrix in thecommitsskill).CHANGELOG.mdis release-time only — leave it alone (seetag-release). - Commit and open the PR — see
commitsfor the message format and branch naming,prsfor the PR body skeleton, issue templates, and PR mechanics (draft → ready → squash-on-merge).
- Releases. Do not push tags (
v*) — that triggers GoReleaser + provenance signing. The maintainer cuts releases. Thetag-releaseskill drafts release artifacts (CHANGELOG section, version bump) for the maintainer to review before they tag. [skip ci]commits. Reserved for the deploy bot; human and agent commits must go through CI.- Security advisories. If you find a vulnerability, surface it to the user — do not file a public issue. The disclosure flow is in SECURITY.md.
- Force-push, history rewrites, branch deletion without explicit user instruction.
- Adding scrapers or undocumented APIs for metadata. The project is deliberately Goodreads-free; new sources must be documented public APIs (see README §"Metadata Sources").
The repo's .claude/skills/ directory holds task-triggered skills for Claude-format-aware agents (Claude Code, Copilot CLI, Codex CLI, Gemini CLI). Skills are conditional workflows; this AGENTS.md is the always-on baseline.
| Skill | Fires when |
|---|---|
testing |
Writing or running tests, before pushing — pre-PR matrix, pinned versions, test patterns, common failure modes |
smoke-testing |
Deciding whether to run an out-of-process suite — picks between make smoke, make abs-contract, make predeploy-smoke |
commits |
Picking a branch name, staging, or writing a commit message — branches, Conventional Commits format, doc-update gate |
prs |
Opening / updating a PR, responding to review, filing an issue — PR body skeleton, PR mechanics, issue templates |
tag-release |
Cutting a release — composing the ## [vX.Y.Z] CHANGELOG section and walking commits since the last tag (authoring only; maintainer pushes the tag) |
Non-Claude agents that can't auto-load SKILL.md files should read the bodies under .claude/skills/<name>/SKILL.md directly when a trigger condition fires.
- Full CI matrix, security checks, and local rehearsal commands: CONTRIBUTING.md
- Deployment / env vars / upgrade path: docs/DEPLOYMENT.md
- Roadmap and out-of-scope list: docs/ROADMAP.md
- Auth modes (multiuser / OIDC / proxy): docs/multi-user.md, docs/auth-oidc.md, docs/auth-proxy.md
- Vulnerability disclosure: SECURITY.md