Configuration
.copperhead/config.json
Section titled “.copperhead/config.json”Written by copperhead init. Every key is optional; the defaults below apply when a key is absent or the file does not exist.
{ "schematic": "hardware/board.kicad_sch", "board": "hardware/board.kicad_pcb", "docs": "docs/", "model": null, "maxTurns": 40, "maxRepairCycles": 5, "budgets": { "sleep_current_uA": 25 }}| Key | Default | Meaning |
|---|---|---|
schematic |
null |
Path to the .kicad_sch, relative to the repo root. ERC is skipped when null. |
board |
null |
Path to the .kicad_pcb. DRC is skipped when null. |
docs |
"docs/" |
The design docs directory: docs-as-memory. |
model |
null |
Default model. Overridden by --model and COPPERHEAD_MODEL. |
maxTurns |
40 |
Turn budget per run. |
maxRepairCycles |
5 |
ERC/DRC repair attempts before the run rolls back to the git snapshot. |
budgets |
{} |
Free-form hard constraints, surfaced verbatim into every run’s system prompt. |
There is also a generatedHashes key, maintained by copperhead. It records content hashes of the generated docs so init can tell an untouched file from a hand-edited one. Do not edit it by hand.
Budgets
Section titled “Budgets”Budgets are hard constraints, not hints. A change that would exceed one is refused with an explanation, rather than accepted and discovered later:
{ "budgets": { "sleep_current_uA": 25, "bom_cost_usd": 18.50 }}The names are yours. copperhead passes them through verbatim and expects the units to be in the key, as in sleep_current_uA.
.copperhead/constraints.json
Section titled “.copperhead/constraints.json”The constraint registry: machine-readable counterparts to the constraints stated in your design docs. Constraints are dual-written, to the doc and to the registry, and the sync-obligations ledger refuses to let a run commit if one was updated without the other.
Environment variables
Section titled “Environment variables”| Variable | Purpose |
|---|---|
OPENAI_API_KEY |
OpenAI credentials. |
ANTHROPIC_API_KEY |
Anthropic credentials. |
COPPERHEAD_MODEL |
Default model. Overrides config, overridden by --model. |
SYNAP_API_KEY |
Optional. Enables cross-run memory. Absent, copperhead behaves exactly as before and makes no Synap calls. |
SYNAP_USER_ID |
Optional memory scope. Defaults to your git config user.email. |
SYNAP_CUSTOMER_ID |
Optional memory scope. Defaults to copperhead; only matters on B2B Synap instances. |
A .env file in the working directory is read at startup, before any command resolves a model or a provider. A real environment variable always wins over the file. Copy .env.example to get started.
Keys are read from the environment only. copperhead never writes one to a config file, and redacts anything matching sk-[A-Za-z0-9_-]+ when writing transcripts and summaries. Keep .env out of git; the shipped .gitignore already excludes it.
Model selection
Section titled “Model selection”Resolved in strict precedence order:
- The
--modelflag COPPERHEAD_MODELmodelin.copperhead/config.jsongpt-5ifOPENAI_API_KEYis set, otherwiseclaudeifANTHROPIC_API_KEYis set
If none of these produce a model, the command exits with an error telling you the four ways to set one. check never needs a model, since it makes no LLM calls at all.
Files copperhead writes
Section titled “Files copperhead writes”| Path | Committed? | What it is |
|---|---|---|
docs/*.md |
Yes | Design docs. The agent’s memory and its output. |
.copperhead/config.json |
Yes | Configuration. |
.copperhead/constraints.json |
Yes | Constraint registry. |
.copperhead/README.md |
Yes | Self-describing docs for the above. |
.copperhead/runs/<ts>/ |
No | JSONL transcript plus a human-readable summary.md. Gitignored. |
Cross-run memory
Section titled “Cross-run memory”With SYNAP_API_KEY set, each run recalls relevant context from earlier runs, on this board and others, into the system prompt, then records its outcome, decisions, and refusals back.
In-repo docs and the KiCad files stay the source of truth. Recalled memory is advisory context layered on top, never a substitute for reading docs/.
It needs the optional @maximem/synap-js-sdk package and a Python 3.11+ runtime on the host, since the JS SDK drives a Python bridge as a subprocess. If either is missing, copperhead logs a line and continues without memory.