You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

4.0 KiB

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-triagewontfix). 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:
    $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.

Sibling symptom — Error: HTTP客户端等待超时 (HTTP client wait timeout). Same root cause (relayed provider over 127.0.0.1), different failure point: instead of the stream being truncated mid-flight, the client gives up waiting for the response (read timeout expires before first bytes / before completion). Leans toward one over-heavy turn — upstream generates too slowly and the client read-timeout fires first, or the forwarder's idle timeout is shorter than generation time. Same avoidance rules below; add: keep single turns small so first-byte latency stays under the client timeout, and prefer a retry.

Sibling symptom — Error: DNS解析异常 (DNS resolution failure). Same relay chain, but the earliest failure point: the request never even connected — the relay/upstream hostname could not be resolved (DNS query timed out / no answer / transient resolver hiccup). Unlike the two above this is not correlated with turn size — the request was never sent, so trimming the turn or /compact does nothing. Likely causes: local DNS resolver / hosts jitter, a VPN/proxy switch mid-session, the relay's own domain temporarily unresolvable upstream, or a brief network drop. The only effective recovery is retry (jitter self-heals); if it persists, check network / DNS / VPN — it is an environment/network fault, not something a repo change can fix.

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.