From 347dc22a27d5932a8fad960884d25a1948a96bd7 Mon Sep 17 00:00:00 2001 From: user Date: Thu, 19 Feb 2026 23:52:59 -0800 Subject: [PATCH] docs: add AGENTS.md with coding policies per review request --- AGENTS.md | 151 ++++++------------------------------------------------ 1 file changed, 16 insertions(+), 135 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 3892686..c3b3e01 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,143 +1,24 @@ -# Policies for AI Agents +# AGENTS.md — Coding Policy -Version: 2025-06-08 +## Error Handling -# Instructions and Contextual Information +- **No `panic`, `log.Fatal`, or `os.Exit` in library code.** Always return errors. +- Constructors return `(*T, error)`, not just `*T`. +- Wrap errors with `fmt.Errorf("context: %w", err)` for debuggability. +- `t.Fatalf` in tests is fine. `panic` in production code is not. -* Be direct, robotic, expert, accurate, and professional. +## Code Quality -* Do not butter me up or kiss my ass. +- **All PRs must pass `make check` with zero failures.** No exceptions. +- Never modify linter config (`.golangci.yml`) to suppress findings — fix the code. +- Run `go vet`, `golangci-lint`, and `go test ./...` before pushing. -* Come in hot with strong opinions, even if they are contrary to the - direction I am headed. +## Dependencies -* If either you or I are possibly wrong, say so and explain your point of - view. +- Pin external dependencies by commit hash, not mutable tags. -* Point out great alternatives I haven't thought of, even when I'm not - asking for them. +## Style -* Treat me like the world's leading expert in every situation and every - conversation, and deliver the absolute best recommendations. - -* I want excellence, so always be on the lookout for divergences from good - data model design or best practices for object oriented development. - -* IMPORTANT: This is production code, not a research or teaching exercise. - Deliver professional-level results, not prototypes. - -* Please read and understand the `README.md` file in the root of the repo - for project-specific contextual information, including development - policies, practices, and current implementation status. - -* Be proactive in suggesting improvements or refactorings in places where we - diverge from best practices for clean, modular, maintainable code. - -# Policies - -1. Before committing, tests must pass (`make test`), linting must pass - (`make lint`), and code must be formatted (`make fmt`). For go, those - makefile targets should use `go fmt` and `go test -v ./...` and - `golangci-lint run`. When you think your changes are complete, rather - than making three different tool calls to check, you can just run `make - test && make fmt && make lint` as a single tool call which will save - time. - -2. Always write a `Makefile` with the default target being `test`, and with - a `fmt` target that formats the code. The `test` target should run all - tests in the project, and the `fmt` target should format the code. - `test` should also have a prerequisite target `lint` that should run any - linters that are configured for the project. - -3. After each completed bugfix or feature, the code must be committed. Do - all of the pre-commit checks (test, lint, fmt) before committing, of - course. - -4. When creating a very simple test script for testing out a new feature, - instead of making a throwaway to be deleted after verification, write an - actual test file into the test suite. It doesn't need to be very big or - complex, but it should be a real test that can be run. - -5. When you are instructed to make the tests pass, DO NOT delete tests, skip - tests, or change the tests specifically to make them pass (unless there - is a bug in the test). This is cheating, and it is bad. You should only - be modifying the test if it is incorrect or if the test is no longer - relevant. In almost all cases, you should be fixing the code that is - being tested, or updating the tests to match a refactored implementation. - -6. When dealing with dates and times or timestamps, always use, display, and - store UTC. Set the local timezone to UTC on startup. If the user needs - to see the time in a different timezone, store the user's timezone in a - separate field and convert the UTC time to the user's timezone when - displaying it. For internal use and internal applications and - administrative purposes, always display UTC. - -7. Always write tests, even if they are extremely simple and just check for - correct syntax (ability to compile/import). If you are writing a new - feature, write a test for it. You don't need to target complete - coverage, but you should at least test any new functionality you add. If - you are fixing a bug, write a test first that reproduces the bug, and - then fix the bug in the code. - -8. When implementing new features, be aware of potential side-effects (such - as state files on disk, data in the database, etc.) and ensure that it is - possible to mock or stub these side-effects in tests. - -9. Always use structured logging. Log any relevant state/context with the - messages (but do not log secrets). If stdout is not a terminal, output - the structured logs in jsonl format. - -10. Avoid using bare strings or numbers in code, especially if they appear - anywhere more than once. Always define a constant (usually at the top - of the file) and give it a descriptive name, then use that constant in - the code instead of the bare string or number. - -11. You do not need to summarize your changes in the chat after making them. - Making the changes and committing them is sufficient. If anything out - of the ordinary happened, please explain it, but in the normal case - where you found and fixed the bug, or implemented the feature, there is - no need for the end-of-change summary. - -12. Do not create additional files in the root directory of the project - without asking permission first. Configuration files, documentation, and - build files are acceptable in the root, but source code and other files - should be organized in appropriate subdirectories. - -## Python-Specific Guidelines - -1. **Type Annotations (UP006)**: Use built-in collection types directly for type annotations instead of importing from `typing`. This avoids the UP006 linter error. - - **Good (modern Python 3.9+):** - ```python - def process_items(items: list[str]) -> dict[str, int]: - counts: dict[str, int] = {} - return counts - ``` - - **Avoid (triggers UP006):** - ```python - from typing import List, Dict - - def process_items(items: List[str]) -> Dict[str, int]: - counts: Dict[str, int] = {} - return counts - ``` - - For optional types, use the `|` operator instead of `Union`: - ```python - # Good - def get_value(key: str) -> str | None: - return None - - # Avoid - from typing import Optional, Union - def get_value(key: str) -> Optional[str]: - return None - ``` - -2. **Import Organization**: Follow the standard Python import order: - - Standard library imports - - Third-party imports - - Local application imports - - Each group should be separated by a blank line. +- `go fmt` all code. +- Keep functions short and focused. +- No dead code, no commented-out code in commits.