Files

4.5 KiB

AGENTS.md — how changes are made in this repo

This file is read by AI agents (via opencode) and by human developers. Follow it.

What this repo is

A best-practices reference application — the canonical example the team builds and points to. It is a small but realistic multi-container app, built and run with docker-compose:

  • api — the HTTP service (the app's public surface).
  • worker — background/async job processor.
  • db — PostgreSQL, the shared datastore.

Everything is wired so the whole stack comes up with a single docker compose up. The point of this repo is that every part demonstrates how we like things done: clear structure, tests, and CI.

Golden rules

  • You may edit any file in this repo (app code, docker-compose.yml, .gitea/, tests, CI).
  • NEVER push to main, and NEVER merge a pull request. All work goes on a branch and becomes a PR that a human (or @pm under the autopilot label) merges. You do not have merge authority.
  • Never print, exfiltrate, or invent secret values. Reference secrets via env vars / compose environment:; never paste real secret values into comments, PRs, logs, or code. Config that references a secret is fine; the value is not.
  • Keep changes minimal and match the conventions already in the file you're editing.
  • Do the work on a branch — never paste code or diffs into the issue thread.
  • Because this is a reference repo, favor clarity over cleverness: small services, obvious names, comments where a newcomer would need them.

Project layout (target — grows as features land via issues)

docker-compose.yml        # the whole stack: api + worker + db
api/                      # the HTTP service (its own Dockerfile)
worker/                   # the background worker (its own Dockerfile)
db/                       # schema / migrations / init SQL
tests/                    # automated tests (unit + integration)
.gitea/workflows/         # CI (build, test) + the ai-agent caller

Add a service by giving it its own top-level directory and a service entry in docker-compose.yml.

Local run & tests

  • Run the stack: docker compose up --build — api, worker, and db should all come up healthy.
  • Tests: every change must keep the test suite green. Run tests the way CI does (e.g. via a docker compose run test service or the documented test command) before you consider work done.
  • Prefer integration tests through compose for cross-service behavior (api ↔ db, worker ↔ db) over mocking the whole world.
  • Give each service a healthcheck in compose and depend on it (depends_on: condition: service_healthy) so startup is deterministic.

CI

CI lives under .gitea/workflows/. It must, at minimum, build the images and run the tests on every PR. Keep CI green — a PR that breaks the build or tests is not ready for review. When adding a new service, extend CI to build and test it too.

Branches & pull requests

You start on branch ai/issue-<N> (N = the issue number).

Split independent changes into separate PRs so each is small and reviewable:

git checkout main
git checkout -b ai/issue-<N>-<short-slug>      # e.g. ai/issue-7-api-healthcheck
# make just that one change
git add -A && git commit -m "<what changed>" && git push -u origin HEAD
  • Only keep changes together on one branch if they genuinely must ship as a unit.
  • Commit and push incrementally so progress is visible on the branch.
  • Do not open pull requests yourself — the automation opens one PR per branch you push.

PR description

End your reply with a clean pull-request description wrapped EXACTLY between these markers. Everything before BEGIN_PR_DESCRIPTION is treated as working notes and discarded:

BEGIN_PR_DESCRIPTION
## Summary
<1-2 sentences: what changed and why>
## Changes
<short bullet list of the changes>
END_PR_DESCRIPTION

Do not paste full files or large diffs — the review happens in the PR diff.

Database changes & migrations

The datastore is Postgres, and docker compose up does not magically evolve a schema. For schema changes:

  • Put schema/migrations under db/ (e.g. db/migrations/NNNN-description.sql, applied in order).
  • Make migrations idempotent / forward-only and safe to re-run.
  • Never require a manual, undocumented step — a fresh docker compose up on an empty volume must produce a working schema.

When unsure

If the task is genuinely unclear or missing details you cannot reasonably assume, make no changes and reply with specific questions instead.