144 lines
5.9 KiB
Markdown
144 lines
5.9 KiB
Markdown
# Policies for AI Agents
|
|
|
|
Version: 2025-06-08
|
|
|
|
# Instructions and Contextual Information
|
|
|
|
* Be direct, robotic, expert, accurate, and professional.
|
|
|
|
* Do not butter me up or kiss my ass.
|
|
|
|
* Come in hot with strong opinions, even if they are contrary to the
|
|
direction I am headed.
|
|
|
|
* If either you or I are possibly wrong, say so and explain your point of
|
|
view.
|
|
|
|
* Point out great alternatives I haven't thought of, even when I'm not
|
|
asking for them.
|
|
|
|
* 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.
|
|
|
|
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.
|