- Mount best-practices context at /workspace/best-practices/ (was /opt/harness/context/best-practices/) for consistent agent access - Fix /workspace/working/ → /workspace/project/ in all CLAUDE.md files (planning, spec-writing, security-review, code-methodology, qwen-code-methodology, test-writing) - Update best-practices path references in all CLAUDE.md files to /workspace/best-practices/ Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
111 lines
5.2 KiB
Markdown
111 lines
5.2 KiB
Markdown
# Code Methodology — Qwen3.6 (Python)
|
|
|
|
You are running on **Qwen3.6-27B** via the agentic tool-calling runner. Thinking mode is on by default — your `<think>` blocks are part of normal output, not something to be scaffolded.
|
|
|
|
## Hard rules (violations fail the task)
|
|
|
|
1. **NEVER use the `Write` tool on a file that already exists.** Read first, then `Edit` for targeted changes. `Write` is only for creating new files that do not yet exist.
|
|
2. **Only modify files directly required by the task.** Do not refactor adjacent code, fix unrelated tests, or upgrade dependencies. Before committing, run `git diff --name-only HEAD` — if any unexpected file appears, revert it with `git checkout <file>`.
|
|
3. **NEVER delete existing functions, classes, or imports.** Only ADD new code. Append new functions after the last existing one. If you need to change behavior, add a new function — do not remove the old one.
|
|
4. **Verify you haven't deleted lines before committing:**
|
|
```bash
|
|
git diff HEAD | grep '^-[^-]' | grep -v '^\-\-\-' | head -20
|
|
```
|
|
If this shows deleted non-blank lines from existing code, you have broken something — revert and try again with a targeted `Edit`.
|
|
5. **Only run the specific test file for your change.** Never run the full test suite.
|
|
```
|
|
python -m pytest tests/test_<module>.py -v --tb=short -x
|
|
```
|
|
6. **Do not create backup copies** (`*_orig`, `*_old`, `*_bak`, `*_backup`).
|
|
7. **Do not rename existing files before modifying them.**
|
|
8. **When the task is done, respond with plain text and stop.** Do not call any tool to signal completion. There is no "finish", "done", or "report" tool — emitting one wastes a turn and the runner will treat it as more work.
|
|
|
|
## How to work
|
|
|
|
1. Read the task. Identify the spec requirement ID if one is referenced; implement exactly that requirement.
|
|
2. Read the files mentioned in the task before changing them.
|
|
3. Find an existing similar file. Copy its structure. Change only what your task requires.
|
|
4. Make small steps. After each, run the single test file from rule 3.
|
|
5. When tests pass, write a short summary as plain text. Stop.
|
|
|
|
## When you get stuck
|
|
|
|
If the same error appears 3 times:
|
|
|
|
- Stop trying the same fix.
|
|
- Reread the error message once.
|
|
- Ask: "Am I editing the right file?" "Should I mock this instead of debugging the environment?"
|
|
- Try a completely different approach.
|
|
|
|
If a directory or file does not exist where you expect it: do not debug the environment. Mock it or create a test fixture.
|
|
|
|
## Best practices
|
|
|
|
This container has cross-project best practices mounted at `/workspace/best-practices/`. **For any non-trivial Python task, read the relevant topic file before writing code.**
|
|
|
|
- `/workspace/best-practices/python-patterns.md` — Pydantic v2 validators, `threading.Lock` vs `RLock`, `extra='ignore'` silent drops, subprocess mocking, `model_validator`, packaging
|
|
- `/workspace/best-practices/test-driven-development.md` — for tasks that involve writing tests
|
|
- `/workspace/best-practices/spec-driven-development.md` — when a `spec/` file is referenced
|
|
- `/workspace/best-practices/security-architecture.md` — for anything touching auth, credentials, or external boundaries
|
|
- `/workspace/best-practices/BESTPRACTICES.md` — index of all topics
|
|
|
|
## Python conventions (this codebase)
|
|
|
|
- Python 3.12+ with type hints
|
|
- Pydantic v2 for data models — use `@model_validator(mode='after')` for cross-field validation; `@field_validator` does **not** fire for default values
|
|
- pytest for tests; async tests must be `async def` with `@pytest.mark.asyncio` (a sync `def test_*` calling async code silently passes without executing)
|
|
- Structured JSON logging
|
|
- Configuration via environment variables — no hardcoded config
|
|
|
|
## Python safety rules
|
|
|
|
### Module imports
|
|
Never call `sys.exit()` at module level or inside `except ImportError`. Use a flag:
|
|
|
|
```python
|
|
_HAS_OPENAI = True
|
|
try:
|
|
import openai
|
|
except ImportError:
|
|
_HAS_OPENAI = False
|
|
```
|
|
|
|
Check the flag at call time, not at import time.
|
|
|
|
### Threading
|
|
`threading.Lock` is non-reentrant — same-thread re-acquisition deadlocks silently. When in doubt, use `threading.RLock`.
|
|
|
|
### Pydantic gotcha
|
|
After adding a field to a shared model, every Protocol implementation and every `_to_row` / `_row_to_*` mapping must learn the new field, or it will silently round-trip as `None` in the implementation you missed.
|
|
|
|
## Tool-calling notes
|
|
|
|
- Use the standard tools provided. Don't invent tool names.
|
|
- Tool arguments must be valid JSON. If you get an "invalid JSON" error back, re-read the schema and try once more with the corrected shape.
|
|
- You can call multiple tools in one turn (parallel) when their results are independent. Don't batch sequentially-dependent calls — wait for the prior result first.
|
|
|
|
## Session log
|
|
|
|
Before stopping, write a short log to `/project/memory/log/<date>.<time>.md` (e.g. `2026-04-25.143000.md`):
|
|
|
|
```markdown
|
|
# Session Log — YYYY-MM-DD
|
|
|
|
## Summary
|
|
One paragraph of what was accomplished.
|
|
|
|
## Decisions
|
|
- Key choices and reasoning
|
|
|
|
## Gotchas Discovered
|
|
- [python] description of the gotcha
|
|
|
|
## Open Questions
|
|
- Anything unresolved
|
|
|
|
## Process Notes
|
|
- What worked, what was slow
|
|
```
|
|
|
|
Omit empty sections. Tag gotchas with a topic prefix (`[python]`, `[pydantic]`, etc.) so they can be routed during reflection.
|