- best-practices/v1: replace 9 stale symlinks (into planning/v1) with real files synced byte-identical from the canonical best-practices project; add INDEX.md, scripting.md, mechanical-test-generation.md (canonical had drifted heavily, e.g. api-design.md 463->807 lines) - planning/v1: delete duplicated best-practices/ copy (requires: inheritance confirmed via spec/harness.md HC-1/HC-7) - scripts/sync-best-practices.sh: idempotent re-sync from canonical checkout - code-methodology/v1: INDEX.md + scripting.md references now resolve; point test-writing tasks at mechanical-test-generation.md - spec-writing/v1: worked spec exemplar (module layout table, Why: lines, exact error messages, parametrize pattern table) + CLAUDE.md pointer + mount entry
113 lines
4.4 KiB
Markdown
113 lines
4.4 KiB
Markdown
# Code Methodology Context
|
|
|
|
## Best Practices Review
|
|
|
|
Before starting any task:
|
|
|
|
1. Check if `/workspace/best-practices/INDEX.md` exists
|
|
2. If it exists, read it to see available topics
|
|
3. Identify relevant topics for the current task:
|
|
- Python task → read `test-driven-development.md`, `spec-driven-development.md`
|
|
- Kubernetes task → read `kubernetes.md`
|
|
- Shell scripts → read `scripting.md`
|
|
- Writing tests mechanically from a spec (test-writer role, or any task deriving
|
|
test files directly from spec requirements) → read `mechanical-test-generation.md`
|
|
4. Read the relevant topic files from `/workspace/best-practices/`
|
|
5. Apply those practices to your work
|
|
|
|
If `/workspace/best-practices/` doesn't exist, proceed without — it's not mandatory.
|
|
|
|
## Spec-Driven Development Workflow
|
|
|
|
1. **Read the spec** — Read relevant files in `spec/` before writing any code
|
|
2. **Write tests first** — Create test cases from spec requirements before implementing (see `/workspace/best-practices/test-driven-development.md` and `/workspace/best-practices/spec-driven-development.md` if available)
|
|
3. **Implement iteratively** — Build implementation to satisfy tests and spec
|
|
4. **Write session log** — Document what was accomplished, decisions made, and gotchas discovered
|
|
|
|
## Conventions
|
|
|
|
- **Python 3.12+** with type hints throughout
|
|
- **Pydantic v2** for all data models and settings
|
|
- **pytest** for testing with clear, descriptive test names
|
|
- **Structured JSON logging** for all output
|
|
- **Configuration via environment variables** — no hardcoded config
|
|
- **No shell scripts inside containers** — use Python for error handling
|
|
|
|
## Code Quality Rules
|
|
|
|
- Do not add features, refactor code, or make improvements beyond what was asked
|
|
- Validate inputs at system boundaries only, trust internal interfaces
|
|
|
|
## Agent Safety Rules
|
|
|
|
These rules exist because container agents have repeatedly made these mistakes in production runs.
|
|
|
|
### Python Module Safety
|
|
|
|
Never call `sys.exit()` at module level or inside `except ImportError` blocks. This causes import
|
|
failures in other modules that import this one. Use a flag pattern instead:
|
|
|
|
```python
|
|
_HAS_OPENAI = True
|
|
try:
|
|
import openai
|
|
except ImportError:
|
|
_HAS_OPENAI = False
|
|
```
|
|
|
|
Check the flag at call time:
|
|
|
|
```python
|
|
def use_openai():
|
|
if not _HAS_OPENAI:
|
|
raise RuntimeError("openai is not installed")
|
|
...
|
|
```
|
|
|
|
### Pydantic Validators
|
|
|
|
- Use `@model_validator(mode='after')` when validation needs cross-field access or must fire for
|
|
default values
|
|
- `@field_validator` only fires when a field is **explicitly provided** — it will not run for
|
|
fields that fall back to their default
|
|
|
|
### File Editing Policy (CRITICAL)
|
|
|
|
**NEVER use the Write tool on any file that already exists in /project.**
|
|
|
|
This is the single most important rule. Container agents have repeatedly destroyed complex source
|
|
files (1000+ lines) by writing new minimal stub versions. The effects are catastrophic and hard
|
|
to detect because the task still "succeeds" (exit 0).
|
|
|
|
The correct workflow for modifying any existing file:
|
|
1. **Read** the file first (Read tool)
|
|
2. **Edit** with targeted changes (Edit tool) — ONLY the specific function, class, or field
|
|
3. **Never** rewrite an entire file from scratch with Write
|
|
4. **Never** "simplify" or "restructure" a file unless that is the explicit task
|
|
|
|
The Write tool is ONLY for creating brand-new files that do not yet exist.
|
|
|
|
Other file management rules:
|
|
- Never create backup copies of files or directories before modifying them
|
|
- Edit files in place — do not create paths ending in `_orig`, `_old`, `_bak`, or `_backup`
|
|
- Do not rename existing files or directories before modifying them
|
|
- In automated runs there is no one to clean up junk directories
|
|
|
|
### Async Test Patterns
|
|
|
|
- Test functions for async code must be `async def` decorated with `@pytest.mark.asyncio`
|
|
- A sync `def test_` function that calls an async function receives a coroutine object, not the
|
|
result — the test will silently pass without executing the async logic
|
|
|
|
## Session Logging
|
|
|
|
Write a session log to `/project/memory/log/<date>.<time>.md` (e.g., `2026-03-24.041500.md`) with:
|
|
|
|
- **Summary**: One paragraph of what was accomplished
|
|
- **Decisions**: Key choices made and reasoning
|
|
- **Gotchas**: Issues discovered with topic tags (e.g., `[python]`, `[docker]`)
|
|
- **Open Questions**: Unresolved items for follow-up
|
|
- **Process Notes**: What worked well, areas for improvement
|
|
|
|
Omit empty sections.
|