# Agents Guidance for AI agents working in this repo. ## Agent skills ### Issue tracker Issues and specs live as markdown files under `.scratch/`. See `docs/agents/issue-tracker.md`. ### Triage labels Five canonical roles, each label string equal to its name (`needs-triage` … `wontfix`). See `docs/agents/triage-labels.md`. ### Domain docs Multi-context: root `CONTEXT-MAP.md` points at one `CONTEXT.md` per `crm-{域}` module. See `docs/agents/domain.md`. ## Coding standards ### Source file encoding All `.java` source files **must be UTF-8 without BOM** (no `EF BB BF` byte prefix). - Maven's `javac` fails on BOM with `illegal character: '\uFEFF'`; IntelliJ IDEA tolerates BOM, so IDE-only compilation masks the problem until `mvn compile`. - If `mvn compile` reports `illegal character: '\uFEFF'`, a tool has written the file with BOM. Strip it before retrying: ```powershell $b = [IO.File]::ReadAllBytes('path/to/File.java') if ($b[0] -eq 0xEF -and $b[1] -eq 0xBB -and $b[2] -eq 0xBF) { [IO.File]::WriteAllBytes('path/to/File.java', $b[3..($b.Length-1)]) } ``` - Run a full BOM scan across all `*.java` files after bulk edits (Write/SearchReplace) and before `mvn compile`. ## Tooling / harness ### Stream dropouts (`Error: Stream ended without finish_reason`) The LLM's streamed (SSE) response was cut off before the terminal `finish_reason` event. It is **not** a bug in your code or in a tool — it is the upstream/relay dropping the connection mid-generation. This repo runs through a relayed provider (`PI_PROVIDER=new-provider`, `PI_MODEL=claude-opus-4-8`, forwarded via `127.0.0.1`), which makes dropouts more likely on large single turns. **Most common triggers, worst first:** - **Oversized single turn** — reading several long files at once (e.g. both `crm-lead/CONTEXT.md` + `crm-opportunity/CONTEXT.md`) then immediately doing a large write. The turn right after a big context dump drops most often. - **One huge output** — emitting a large file (a full HTML report, hundreds of lines) in a single `write`. - **Network / relay idle timeout** — the local forwarder or an nginx/VPN layer closing an idle SSE long-connection. **How to avoid it:** - Read large files with `offset`/`limit` in chunks; do not inhale whole long docs in one call. - Write large files in small steps: `write` a skeleton, then append with successive `edit` calls, instead of one giant `write`. - `/compact` or start a fresh session when the conversation history has grown large. - Deterministic recovery is usually just **retry** — if the same action succeeds on a retry, it was relay jitter, not a real failure.