From 5fe78da497ef651ae55c4ad66ec1ef71e0aa9a3b Mon Sep 17 00:00:00 2001 From: Marco Acierno Date: Mon, 5 Oct 2026 15:08:04 +0200 Subject: [PATCH 1/4] Update AI instructions --- AGENTS.md | 44 +++++++++++++++++++++++++++++++------------- 1 file changed, 31 insertions(+), 13 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 46eec2935e..19f166af8e 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -6,7 +6,7 @@ This file provides guidance to coding agents when working with code in this repo ### Backend (Django) -- **Local development**: `docker-compose up` (starts all services) +- **Local development**: `docker compose up` (starts all services) - **Run tests**: `cd backend && uv run pytest` or `DJANGO_SETTINGS_MODULE=pycon.settings.test uv run pytest` - **Single test**: `cd backend && uv run pytest path/to/test_file.py::test_function` - **Lint/format**: `cd backend && uv run ruff check` and `uv run ruff format` @@ -16,7 +16,7 @@ This file provides guidance to coding agents when working with code in this repo ### Frontend (Next.js) -- **Local development**: `cd frontend && pnpm dev` (or via docker-compose) +- **Local development**: `cd frontend && pnpm dev` (or via docker compose) - **Build**: `cd frontend && pnpm build` - **Tests**: `cd frontend && pnpm test` - **GraphQL codegen**: `cd frontend && pnpm codegen` (or `pnpm codegen:watch`) @@ -101,16 +101,34 @@ When working in `backend/api`: **IMPORTANT**: When running locally, all Python/Django commands must run inside Docker. The local virtual environment will not work. -Use `docker exec pycon-backend-1` (without `-t` flag for non-interactive/script usage, with `-it` for interactive terminal). - -- **Start services**: `docker-compose up` (starts all services) -- **Run tests**: `docker exec pycon-backend-1 uv run pytest -l -s -vvv` -- **Single test**: `docker exec pycon-backend-1 uv run pytest path/to/test_file.py::test_function -l -s -vvv` -- **Lint/format**: `docker exec pycon-backend-1 uv run ruff check` and `docker exec pycon-backend-1 uv run ruff format` -- **Type checking**: `docker exec pycon-backend-1 uv run mypy .` -- **Django management**: `docker exec pycon-backend-1 uv run python manage.py ` -- **Migrations**: `docker exec pycon-backend-1 uv run python manage.py makemigrations` and `docker exec pycon-backend-1 uv run python manage.py migrate` +- **Start services**: `docker compose up` (starts all services) +- **Run tests**: `docker compose exec backend uv run pytest -l -s -vvv` +- **Single test**: `docker compose exec backend uv run pytest path/to/test_file.py::test_function -l -s -vvv` +- **Lint/format**: `docker compose exec backend uv run ruff check` and `docker compose exec backend uv run ruff format` +- **Type checking**: `docker compose exec backend uv run mypy .` +- **Django management**: `docker compose exec backend uv run python manage.py ` +- **Migrations**: `docker compose exec backend uv run python manage.py makemigrations` and `docker compose exec backend uv run python manage.py migrate` **Troubleshooting**: If the backend container is not working: -1. Restart container: `docker restart pycon-backend-1` -2. If dependencies changed: Remove `backend/.venv` and rebuild with `docker-compose build --no-cache && docker-compose up` +1. Restart container: `docker compose restart backend` +2. If dependencies changed: Remove `backend/.venv` and rebuild with `docker compose build --no-cache && docker compose up` + +## Comments + +- A comment states a constraint the code cannot express and a reader would otherwise undo: an external quirk (OpenSearch, DRF, a library), a non-obvious invariant, a reason not to take the obvious shortcut. Nothing else. +- Never describe what the code did before, why it changed, or what it replaces. If the comment only makes sense to someone who saw the old code, delete it. It belongs in the commit message. Self-check before finishing: grep the diff for `used to|previously|before|no longer|already|now|instead of|pinned|this PR` in comment lines and delete or rewrite every hit. +- No ticket IDs, PR numbers, spec or plan file names in code or comments. +- One or two lines. A longer comment means the code or the name needs work. +- No section-divider comments (`# -- foo ---`), no narration (`# increment count`), no docstring that restates the function or class name. +- Docstrings only on public interfaces: API views, serializers used by the FE, functions exported for other apps. Private helpers get a name, not a docstring. + +### Writing tests + +- No comments and no docstrings in test files. The test name is the documentation. If a fixture needs explaining, rename the variable; if a class needs a docstring, split it or rename it. +- Test behaviour, never structure. Do not assert the shape of an OpenSearch query dict, the return value of a private method, or the internals of a filter object. Search behaviour is tested through `OpenSearchTCMixin` against a real index, asserting the ids returned. +- One layer per behaviour. Handler logic is tested through the search class; the view is tested only for what the view adds (status codes, error bodies, scope routing). Do not re-assert search results through the view. +- A test earns its place only if a plausible bug would fail it and no other test. Before adding one, name that bug. Delete tests that are implied by another test (`x is not None` when another test dereferences `x`; "is accepted" when another test already gets results through the same path). +- Assert complements together. `exists: true` and `exists: false`, or any pair of opposite directions, share fixtures and live in one test. +- Use `parameterized.expand` for cases that differ only in inputs. Do not write near-identical test methods. Do not use `self.subTest` unless there is no alternative. +- Do not add guard tests for pre-existing behaviour the change cannot affect. +- Extend the existing test module for a feature. Do not create a parallel `*_edge_cases` module or "pin" a test file as unmodifiable. From 9da7c4e4ad29f02bdae0e328d1027a1c567ac344 Mon Sep 17 00:00:00 2001 From: Marco Acierno Date: Mon, 5 Oct 2026 15:09:02 +0200 Subject: [PATCH 2/4] updates --- AGENTS.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 19f166af8e..7142c42a33 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -125,10 +125,10 @@ When working in `backend/api`: ### Writing tests - No comments and no docstrings in test files. The test name is the documentation. If a fixture needs explaining, rename the variable; if a class needs a docstring, split it or rename it. -- Test behaviour, never structure. Do not assert the shape of an OpenSearch query dict, the return value of a private method, or the internals of a filter object. Search behaviour is tested through `OpenSearchTCMixin` against a real index, asserting the ids returned. +- Test behaviour, never structure. - One layer per behaviour. Handler logic is tested through the search class; the view is tested only for what the view adds (status codes, error bodies, scope routing). Do not re-assert search results through the view. - A test earns its place only if a plausible bug would fail it and no other test. Before adding one, name that bug. Delete tests that are implied by another test (`x is not None` when another test dereferences `x`; "is accepted" when another test already gets results through the same path). - Assert complements together. `exists: true` and `exists: false`, or any pair of opposite directions, share fixtures and live in one test. -- Use `parameterized.expand` for cases that differ only in inputs. Do not write near-identical test methods. Do not use `self.subTest` unless there is no alternative. +- Use `pytest.mark.parametrize` for cases that differ only in inputs. Do not write near-identical test methods. - Do not add guard tests for pre-existing behaviour the change cannot affect. - Extend the existing test module for a feature. Do not create a parallel `*_edge_cases` module or "pin" a test file as unmodifiable. From 6ba8a5457b0773e85626b7cf5cb2b602dc3d0d8a Mon Sep 17 00:00:00 2001 From: Marco Acierno Date: Mon, 5 Oct 2026 15:09:57 +0200 Subject: [PATCH 3/4] update --- AGENTS.md | 1 - 1 file changed, 1 deletion(-) diff --git a/AGENTS.md b/AGENTS.md index 7142c42a33..82035240f2 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -126,7 +126,6 @@ When working in `backend/api`: - No comments and no docstrings in test files. The test name is the documentation. If a fixture needs explaining, rename the variable; if a class needs a docstring, split it or rename it. - Test behaviour, never structure. -- One layer per behaviour. Handler logic is tested through the search class; the view is tested only for what the view adds (status codes, error bodies, scope routing). Do not re-assert search results through the view. - A test earns its place only if a plausible bug would fail it and no other test. Before adding one, name that bug. Delete tests that are implied by another test (`x is not None` when another test dereferences `x`; "is accepted" when another test already gets results through the same path). - Assert complements together. `exists: true` and `exists: false`, or any pair of opposite directions, share fixtures and live in one test. - Use `pytest.mark.parametrize` for cases that differ only in inputs. Do not write near-identical test methods. From aa4e09edc4797ea5e3fd7e52af34a68f32371140 Mon Sep 17 00:00:00 2001 From: Marco Acierno Date: Mon, 5 Oct 2026 15:23:55 +0200 Subject: [PATCH 4/4] update --- AGENTS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AGENTS.md b/AGENTS.md index 82035240f2..ec8aee2f25 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -115,7 +115,7 @@ When working in `backend/api`: ## Comments -- A comment states a constraint the code cannot express and a reader would otherwise undo: an external quirk (OpenSearch, DRF, a library), a non-obvious invariant, a reason not to take the obvious shortcut. Nothing else. +- A comment states a constraint the code cannot express and a reader would otherwise undo: an external quirk (GraphQL, a library), a non-obvious invariant, a reason not to take the obvious shortcut. Nothing else. - Never describe what the code did before, why it changed, or what it replaces. If the comment only makes sense to someone who saw the old code, delete it. It belongs in the commit message. Self-check before finishing: grep the diff for `used to|previously|before|no longer|already|now|instead of|pinned|this PR` in comment lines and delete or rewrite every hit. - No ticket IDs, PR numbers, spec or plan file names in code or comments. - One or two lines. A longer comment means the code or the name needs work.