Stop ignoring shared agent documents in .gitignore
This commit is contained in:
+1
-4
@@ -40,9 +40,6 @@ Thumbs.db
|
||||
# sqlmem cache (incl. WAL sidecars from disk-backed mode)
|
||||
cache.db*
|
||||
|
||||
# Agents
|
||||
AGENTS.md
|
||||
CLAUDE.md
|
||||
DESIGN_DOCUMENT_MODULE.md
|
||||
# Claude Code
|
||||
.claude/
|
||||
handover.md
|
||||
@@ -0,0 +1,101 @@
|
||||
# AI Agents - Project Rules
|
||||
|
||||
**Document Version:** v6 (independent, incremented on structural changes)
|
||||
|
||||
Language-agnostic rules for AI assistants (Claude Code, Cursor, Copilot, etc.).
|
||||
|
||||
Everything language-specific — package manager, formatter, linter, test framework,
|
||||
logging library, line length, project layout — lives in the matching design document:
|
||||
|
||||
| Project type | Design document |
|
||||
|--------------------|------------------------------|
|
||||
| Python application | `DESIGN_DOCUMENT.md` |
|
||||
| Python library | `DESIGN_DOCUMENT_MODULE.md` |
|
||||
| Rust application | `DESIGN_DOCUMENT.md` |
|
||||
| Rust library | `DESIGN_DOCUMENT_LIB.md` |
|
||||
| Godot | `DESIGN_DOCUMENT_GODOT.md` |
|
||||
|
||||
Where this file and a design document disagree, **the design document wins**.
|
||||
|
||||
## First-time setup
|
||||
|
||||
- **On first read of this file, immediately read all other `.md` files in the project root** (e.g. `PROJECT.md`, `CHANGELOG.md`, `DESIGN_DOCUMENT*.md`) to get full project context before starting any task.
|
||||
|
||||
## Language
|
||||
|
||||
- **Always write all documentation in English**
|
||||
|
||||
## Dependency Management
|
||||
|
||||
- **Always add and remove dependencies through the package manager CLI** — **never edit the manifest** (`pyproject.toml`, `Cargo.toml`, …) by hand
|
||||
- The exact commands are in the design document for the given language
|
||||
|
||||
## Project Structure
|
||||
|
||||
- Source code, tests and detailed documentation each have their own directory — the concrete layout is in the design document
|
||||
- Detailed documentation belongs in `docs/`, never in the project root
|
||||
- The project root holds only the core documents: `README.md`, `AGENTS.md`, `DESIGN_DOCUMENT*.md`, `PROJECT.md`, `CHANGELOG.md`
|
||||
- Entry points follow the language convention; a project may have several
|
||||
- The dependency/build directory (`.venv/`, `target/`, …) is tool-managed — do not copy it, do not generate it by hand
|
||||
|
||||
## Code
|
||||
|
||||
- **Always use static typing** — annotate every parameter and return value
|
||||
- Format and lint with the tools named in the design document
|
||||
- **Nothing is committed without a clean formatter, linter and test run**
|
||||
|
||||
## Testing
|
||||
|
||||
- Use the test framework named in the design document — never a second framework alongside it
|
||||
- Arrange-Act-Assert pattern
|
||||
- Test naming: `test_<action>_<context>`
|
||||
|
||||
## Logging
|
||||
|
||||
- Use the logging library named in the design document — **never `print()` (or its language equivalent) for debugging**
|
||||
- Never log secrets, passwords, tokens, or API keys
|
||||
|
||||
## Environment and Secrets
|
||||
|
||||
- Applications store secrets in `.env` and load them at runtime — **never commit `.env`**
|
||||
- Debug mode is driven by an `ENV_DEBUG=true/false` flag
|
||||
- Libraries do not read `.env` — configuration is passed in by the caller
|
||||
|
||||
## Git
|
||||
|
||||
- `.gitignore` must cover at least: the dependency/build directory, tool caches, and `.env`
|
||||
- **Commit the lock file for applications, do not commit it for libraries**
|
||||
- **Never commit shared documentation** (`AGENTS.md`, `DESIGN_DOCUMENT*.md`) — it comes from the documentation repository, not from the project
|
||||
- `README.md`, `PROJECT.md` and `CHANGELOG.md` **are committed** — they are project-specific
|
||||
|
||||
### Commit messages
|
||||
|
||||
- **Never sign commits with AI authorship** — no `Co-Authored-By: Claude` (or any other assistant), no "Generated with …" line, no tool name or emoji footer. The same applies to pull request descriptions and issue comments.
|
||||
- The commit author is the human running the tool; the message describes the change, nothing else
|
||||
- Single-line verbal style — "Add X", "Fix Y", "Refactor Z" — never a filename-style message
|
||||
- Written in English
|
||||
|
||||
## Versioning
|
||||
|
||||
- Follow semantic versioning (MAJOR.MINOR.PATCH)
|
||||
- **Always ask user before bumping version** — never increase version automatically
|
||||
- **Keep `CHANGELOG.md` updated** — document all significant changes as they are made
|
||||
- Update `CHANGELOG.md` **before** the version bump
|
||||
- The version source of truth is the project manifest (`pyproject.toml`, `Cargo.toml`, `project.godot`)
|
||||
|
||||
## Task Management
|
||||
|
||||
Tasks are **single-line comments in the code**, written with Todo Tree tags:
|
||||
|
||||
| Tag | Meaning |
|
||||
|----------|--------------------------------------------------|
|
||||
| `TODO:` | work still to be done |
|
||||
| `FIXME:` | something broken that must be repaired |
|
||||
| `BUG:` | a known defect, not fixed yet |
|
||||
| `HACK:` | temporary workaround, needs rewriting |
|
||||
| `NOTE:` | important context for whoever reads this next |
|
||||
|
||||
- **No checkboxes and no numbered task lists in documentation** — the code is the task list
|
||||
- `PROJECT.md` carries only cross-cutting tasks that have no single place in the code
|
||||
- If a tag already exists at a location in code, do not repeat it in `PROJECT.md`
|
||||
- **Update documentation** — when completing changes, update the relevant sections of `PROJECT.md` and `CHANGELOG.md`
|
||||
@@ -4,6 +4,9 @@ All notable changes to this project will be documented in this file.
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Changed
|
||||
- `.gitignore` — stopped ignoring the shared agent documents (`AGENTS.md`, `CLAUDE.md`, `DESIGN_DOCUMENT_MODULE.md`); the section now covers only the Claude Code working files (`.claude/`, `handover.md`).
|
||||
|
||||
---
|
||||
|
||||
## [1.17.0] - 2026-07-30
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
# CLAUDE.md
|
||||
|
||||
**Document Version:** v2 (independent, incremented on structural changes)
|
||||
|
||||
## First-time setup
|
||||
|
||||
**At the start of every new session, read all of the following files before doing anything else:**
|
||||
|
||||
- `CLAUDE.md` (this file)
|
||||
- `README.md`
|
||||
- `AGENTS.md`
|
||||
- `PROJECT.md`
|
||||
- `CHANGELOG.md`
|
||||
- `DESIGN_DOCUMENT*.md` (`DESIGN_DOCUMENT.md`, `DESIGN_DOCUMENT_MODULE.md`, `DESIGN_DOCUMENT_LIB.md` or `DESIGN_DOCUMENT_GODOT.md`)
|
||||
@@ -0,0 +1,262 @@
|
||||
# Python Library Development Guidelines
|
||||
|
||||
**Document Version:** v2
|
||||
|
||||
> **Note on Versioning:**
|
||||
> - This document version is independent — reused across projects
|
||||
> - **Project version** source of truth: `pyproject.toml` under `[project]`
|
||||
> - `CHANGELOG.md` uses project version from `pyproject.toml`
|
||||
|
||||
## Related Documents
|
||||
|
||||
- **README.md** — Project overview, public API description, installation and usage examples
|
||||
- **AGENTS.md** — Rules for AI assistants
|
||||
- **PROJECT.md** — Project goals and current state
|
||||
- **CHANGELOG.md** — Version history
|
||||
|
||||
### Documentation Organization
|
||||
|
||||
All detailed documentation of features and systems belongs in the `docs/` folder, not in the project root.
|
||||
|
||||
The root directory contains only the core documents: `README.md`, `AGENTS.md`, `DESIGN_DOCUMENT_MODULE.md`, `PROJECT.md`, `CHANGELOG.md`.
|
||||
|
||||
---
|
||||
|
||||
## 1. Code Style
|
||||
|
||||
- **PEP8** with 120-character lines (Ruff)
|
||||
- **4 spaces** indentation
|
||||
- **snake_case** functions/variables, **PascalCase** classes, **SCREAMING_SNAKE_CASE** constants
|
||||
- **Type hints** required on all functions
|
||||
- **Import order**: stdlib → third-party → local
|
||||
|
||||
---
|
||||
|
||||
## 2. SOLID Principles
|
||||
|
||||
- **SRP** — One class = one responsibility
|
||||
- **OCP** — Open for extension, closed for modification
|
||||
- **LSP** — Subclasses substitutable for parents
|
||||
- **ISP** — Small interfaces over large ones
|
||||
- **DIP** — Depend on abstractions
|
||||
|
||||
---
|
||||
|
||||
## 3. Dependency Injection
|
||||
|
||||
Pass dependencies via constructor. Never instantiate dependencies inside a class.
|
||||
|
||||
---
|
||||
|
||||
## 4. Protocols Over Inheritance
|
||||
|
||||
Prefer `typing.Protocol` and composition over class inheritance.
|
||||
|
||||
---
|
||||
|
||||
## 5. Data Classes
|
||||
|
||||
Use `@dataclass` for internal data structures, `pydantic.BaseModel` for data that requires validation.
|
||||
|
||||
---
|
||||
|
||||
## 6. Logging
|
||||
|
||||
This is a library. Libraries must **never configure logging sinks** — that is the responsibility of the consuming application.
|
||||
|
||||
### Usage in library code
|
||||
|
||||
```python
|
||||
from loguru import logger
|
||||
|
||||
def some_function() -> None:
|
||||
logger.debug("Detail message")
|
||||
logger.info("Milestone message")
|
||||
```
|
||||
|
||||
Always use the module-level `logger` from loguru directly. Never call `logger.add()` or `logger.remove()` inside library code.
|
||||
|
||||
### Behavior for consumers
|
||||
|
||||
Loguru has a default sink to `stderr` enabled. Consumers who also use loguru get library logs automatically in their configured sinks. Consumers who want to suppress or filter library logs use the package name as the identifier:
|
||||
|
||||
```python
|
||||
from loguru import logger
|
||||
|
||||
logger.disable("<package_name>") # suppress all
|
||||
logger.add(sys.stderr, filter={"<package_name>": "WARNING"}) # WARNING and above only
|
||||
logger.enable("<package_name>") # re-enable
|
||||
```
|
||||
|
||||
This must be documented in `README.md`.
|
||||
|
||||
### Rules
|
||||
|
||||
- Never call `logger.add()` inside library code — no file sinks, no stdout sinks
|
||||
- Never call `logger.remove()` inside library code
|
||||
- Never log secrets, passwords, tokens, or API keys
|
||||
- Never use `print()` inside library code — not for debugging, not for output
|
||||
|
||||
#### Log levels
|
||||
|
||||
| Level | When to use |
|
||||
|-------|-------------|
|
||||
| `DEBUG` | Per-item detail: individual operations, cache hits, internal state |
|
||||
| `INFO` | Significant milestones visible to the consuming application |
|
||||
| `WARNING` | Recoverable issues: fallback used, unexpected but non-fatal state |
|
||||
| `ERROR` | Failures the caller must know about — operation cannot continue |
|
||||
|
||||
---
|
||||
|
||||
## 7. Environment and Secrets
|
||||
|
||||
- Libraries do not use `.env` files or `python-dotenv`
|
||||
- Configuration is passed by the caller via arguments or constructor parameters
|
||||
- Never read `os.getenv()` inside library code unless explicitly documented as a supported configuration mechanism
|
||||
|
||||
---
|
||||
|
||||
## 8. Error Handling
|
||||
|
||||
Define specific exception types in `src/<package>/exceptions.py`. Use a fail-fast approach — surface errors early rather than silently continuing. All public exceptions must be exported from the top-level `__init__.py`.
|
||||
|
||||
---
|
||||
|
||||
## 9. Testing
|
||||
|
||||
- **pytest** only — no `unittest`, no `TestCase` classes, no `self.assert*`
|
||||
- Arrange-Act-Assert pattern
|
||||
- Test naming: `test_<action>_<context>`
|
||||
|
||||
---
|
||||
|
||||
## 10. Tooling
|
||||
|
||||
| Tool | Purpose |
|
||||
|------|---------|
|
||||
| **Ruff** | Formatting and linting |
|
||||
| **mypy** | Static type checking |
|
||||
| **pytest** | Testing |
|
||||
|
||||
Run before every commit:
|
||||
```bash
|
||||
poetry run ruff check
|
||||
poetry run mypy
|
||||
poetry run pytest
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 11. Poetry
|
||||
|
||||
```bash
|
||||
poetry install # Install all dependencies
|
||||
poetry add <pkg> # Add runtime dependency
|
||||
poetry add --group dev <pkg> # Add dev dependency
|
||||
poetry remove <pkg> # Remove dependency
|
||||
poetry run <cmd> # Run command in virtualenv
|
||||
poetry build # Build sdist and wheel into dist/
|
||||
poetry publish # Publish to PyPI
|
||||
```
|
||||
|
||||
Never edit `pyproject.toml` directly to add or remove dependencies.
|
||||
|
||||
### pyproject.toml configuration for a library
|
||||
|
||||
```toml
|
||||
[project]
|
||||
name = "your-library"
|
||||
version = "0.1.0"
|
||||
description = "Short description"
|
||||
requires-python = ">=3.x"
|
||||
dependencies = []
|
||||
|
||||
[tool.poetry]
|
||||
packages = [{include = "your_library", from = "src"}]
|
||||
|
||||
[build-system]
|
||||
requires = ["poetry-core>=2.0.0,<3.0.0"]
|
||||
build-backend = "poetry.core.masonry.api"
|
||||
```
|
||||
|
||||
Do **not** add `[tool.poetry.scripts]` — libraries have no entry points.
|
||||
|
||||
### poetry.lock
|
||||
|
||||
Do **not** commit `poetry.lock` for libraries. It is only committed for applications. Add `poetry.lock` to `.gitignore`.
|
||||
|
||||
---
|
||||
|
||||
## 12. Project Structure
|
||||
|
||||
```
|
||||
project/
|
||||
├── src/
|
||||
│ └── your_library/
|
||||
│ ├── __init__.py # Public API — export everything the caller needs
|
||||
│ ├── exceptions.py # All public exception types
|
||||
│ └── ... # Internal modules
|
||||
├── tests/ # Tests
|
||||
├── docs/ # Detailed documentation
|
||||
├── .venv/ # Virtual environment (managed by Poetry)
|
||||
└── pyproject.toml # Project config and dependencies
|
||||
```
|
||||
|
||||
- No entry point scripts in the project root — this is a library, not an application
|
||||
- `__init__.py` defines the public API; callers import from the top-level package only
|
||||
|
||||
---
|
||||
|
||||
## 13. Public API
|
||||
|
||||
- Everything intended for external use must be exported from `src/<package>/__init__.py`
|
||||
- Use `__all__` to explicitly declare the public surface
|
||||
- Internal modules are prefixed with `_` or kept unexported
|
||||
- Public API must be stable across patch versions; breaking changes require a major version bump
|
||||
|
||||
---
|
||||
|
||||
## 14. Distribution
|
||||
|
||||
Build and publish with Poetry:
|
||||
|
||||
```bash
|
||||
poetry build # Creates dist/*.tar.gz and dist/*.whl
|
||||
poetry publish # Publishes to PyPI (requires credentials)
|
||||
```
|
||||
|
||||
`dist/` is **not committed** to the repository — add it to `.gitignore`.
|
||||
|
||||
---
|
||||
|
||||
## 15. Versioning
|
||||
|
||||
- Follow **semantic versioning**: `MAJOR.MINOR.PATCH`
|
||||
- Version is defined in `pyproject.toml` under `[project]`
|
||||
- Always ask before bumping the version — never increment automatically
|
||||
- Update `CHANGELOG.md` before bumping the version
|
||||
- Breaking changes to the public API require a major version bump
|
||||
|
||||
---
|
||||
|
||||
## 16. Documentation and Task Management
|
||||
|
||||
- Keep `PROJECT.md` and `CHANGELOG.md` up to date when making changes
|
||||
- `README.md` must contain installation instructions and usage examples for the public API
|
||||
- Document architectural changes in this file or in `docs/`
|
||||
|
||||
### Task notation
|
||||
|
||||
Tasks are written as single-line comments directly in code, using the **Todo Tree** tags defined in `AGENTS.md` (`TODO`, `FIXME`, `BUG`, `HACK`, `NOTE`). `PROJECT.md` carries only cross-cutting tasks that have no single place in the code.
|
||||
|
||||
```python
|
||||
# TODO: extract this into a separate loader
|
||||
# FIXME: crashes on an empty file
|
||||
# BUG: rounding is off by one cent on negative amounts
|
||||
# HACK: temporary workaround until the API adds paging
|
||||
# NOTE: order matters here, the parser is stateful
|
||||
```
|
||||
|
||||
No other task format is used — **no checkboxes, no numbered lists in documentation**.
|
||||
|
||||
If a tag already exists at a specific location in code, do not repeat it in `PROJECT.md`.
|
||||
Reference in New Issue
Block a user