# leather
[releases](https://github.com/TGPSKI/leather/releases) | [changelog](CHANGELOG.md) | [pkg.go.dev](https://pkg.go.dev/github.com/TGPSKI/leather) | [leather.sh](https://leather.sh) | [pate.sh](https://pate.sh)
**Local agent infrastructure in one stdlib-only Go binary.**
Leather runs declarative agents on your workstation, server, or Raspberry Pi: scheduled jobs, one-shot runs, webhook-driven workflows, tool calling, and auditable outputs.
No Python stack. No hosted control plane. No broker, telemetry, or dependency pile.
```bash
cat > summarizer.agent.md <<'EOF'
---
name: summarizer
---
You are a concise planning assistant. Output bullet points only.
EOF
leather validate --agent-dir .
leather run summarizer.agent.md
```
## See it run
Seventeen demos in [examples/](examples/), each one `make` target away.
Example 02: scheduled agent
```bash
cp examples/env.example examples/.env
$EDITOR examples/.env
make example-02
```
Example 06: multi-agent curing + devtools UI
```bash
make example-06
```
## Measured, not asserted
Two claims carry this project, each with its evidence one click away:
- **The runtime doesn't get in the way.** The same code path runs a profiled
100-webhook burst — 500 LLM calls, 965K tokens, five fan-out/fan-in
stages — end to end in 190s at 6.5% avg host CPU and no measurable IO
pressure. Leather isn't the bottleneck; the model is.
→ [examples/11-high-volume-ci](examples/11-high-volume-ci/#measured-at-scale-100-webhook-full-system-profile)
- **The runtime is where the accuracy lives.** The same frozen 4B model spans
**62.4% → 81.6%** on a 250-issue gold corpus depending only on the design
around it — a 22-arm × 2-rig ablation with paired per-issue verdicts and a
measured noise floor. The floor isn't the bare model; it's a bad harness.
→ findings in plain language:
[examples/14-sig-triage](examples/14-sig-triage/) · every cell and verdict:
[matrix](examples/14-sig-triage/eval/results/MATRIX.md) /
[verdicts](examples/14-sig-triage/eval/results/VERDICTS.md) · raw run
archives committed — auditable without a GPU
## What it does
| | |
|---|---|
| **Agents** | `*.agent.md` — Markdown front and a system prompt with 0-N turns and variable support.|
| **Tools** | Skills, toolsets, MCP server support, and [`shell-mcp`](examples/03-shell-skill/) (`make build-shell-mcp`) for turning shell commands into agent tools. |
| **Curings** | Bind agents to queues for flexible multi-stage routing. |
| **Queues** | Filesystem FIFO — configurable depth, backpressure, concurrency, dead-letter routing, and single-use parameterized queues. |
| **Workers** | Goroutines with hooks into queues. |
| **Tannery** | Pipelines connecting agents, curings, workers, and artifacts, with fan-in / fan-out routing. |
| **DevTools** | Stdlib-JS UI with session timeline, event inspector, curing flow diagram, and live SSE. |
| **Notifications** | Telegram and Signal backends. |
## Build one
A complete agent:
```markdown
---
name: summarizer
---
You are a concise planning assistant. Output bullet points only.
```
A schedule for it (`*.lifecycle.yaml`, optional):
```yaml
agent: summarizer
schedule: "0 9 * * *"
model: llama3
prompt: Summarize the three most important things to do today.
```
Run it:
```bash
leather validate # check everything parses
leather run ~/.leather/agents/summarizer.agent.md # run once
leather serve --pretty --stats # run on schedule
```
Chaining two agents behind a webhook — one triages, one reviews, an artifact
comes out the other end — is the same primitives composed: see the
[GUIDE.md: two-agent pipeline recipe](docs/GUIDE.md#recipe-two-agent-pipeline) and
[examples/06-multi-agent-curing](examples/06-multi-agent-curing/).
## Install
From source:
```bash
git clone https://github.com/TGPSKI/leather
cd leather
make build && make build-shell-mcp
make install
```
With `go install`:
```bash
go install github.com/TGPSKI/leather/cmd/leather@latest
go install github.com/TGPSKI/leather/cmd/shell-mcp@latest
```
**Verify the install** — no LLM endpoint required:
```bash
leather --version # prints version
make example-01 # runs a mock-LLM example end-to-end
```
## Model and endpoint
Every command above needs a model and an LLM endpoint from somewhere. All
three forms set the same values — flag wins over env var, env var wins over
`config.yaml`:
```bash
# flag
leather run agent.md --model llama3 --llm-endpoint http://localhost:11434
```
```bash
# env var
export LEATHER_MODEL=llama3
export LEATHER_LLM_ENDPOINT=http://localhost:11434
```
```yaml
# config.yaml
model: llama3
llm_endpoint: http://localhost:11434
```
`leather` speaks the OpenAI Chat Completions API, so cloud endpoints work the
same way. The bearer token resolves inline value → `pass` → env var, in that
order:
```bash
export LEATHER_LLM_API_KEY="sk-..."
leather serve --llm-endpoint https://api.openai.com --model gpt-4o-mini
```
```yaml
# config.yaml + unix pass
llm_endpoint: https://api.openai.com
model: gpt-4o-mini
llm_api_key:
pass: openai/api-key # `pass show openai/api-key`
env: OPENAI_API_KEY # fallback when pass is empty or unavailable
```
## Go deeper
Pick your path by the question you're asking; each row starts approachable
and descends as far as you want to go.
| you want to… | start here | then |
|---|---|---|
| **build** an agent, pipeline, or tool | [docs/GUIDE.md](docs/GUIDE.md) — every file format, plus a recipe for each pattern above | [examples/](examples/) (17 runnable demos) · [docs/CONVENTIONS.md](docs/CONVENTIONS.md) (env-var reference) · [docs/TEMPLATES.md](docs/TEMPLATES.md) |
| **check** the claims above | [examples/14-sig-triage](examples/14-sig-triage/) — findings in plain language | [matrix](examples/14-sig-triage/eval/results/MATRIX.md) / [verdicts](examples/14-sig-triage/eval/results/VERDICTS.md) → [experiment design](examples/14-sig-triage/eval/README.md) → [claim ledger](examples/14-sig-triage/eval/results/verification.md) → [raw archives](examples/14-sig-triage/eval/results/runs/) |
| **see** a real deployment | [docs/REFERENCE-TANNERY.md](docs/REFERENCE-TANNERY.md) — six agents, four queues, running unattended, with measured run records and an honest A/B against a frontier control | the system itself: [TGPSKI/catnip/tannery](https://github.com/TGPSKI/catnip/tree/2033b0d9c8d5739995e2aec4087130babcce699d/tannery) |
| **understand** the internals | [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) — package layout and data flow | [docs/modules/](docs/modules) (per-package) · [docs/GLOSSARY.md](docs/GLOSSARY.md) |
| **contribute** (human or agent) | [AGENTS.md](AGENTS.md) — the routing table | [.subagents/](.subagents) domain guides · [CHANGELOG.md](CHANGELOG.md) |
## History
| Date | Event |
|---|---|
| 2026-05-21 | Repository created |
| 2026-06-01 | v0.1.0 "napa", first public release; `c09d184` is the first commit in this history |
| 2026-06-05 | v0.2.0 "weathered" |
| 2026-07-05 | v0.4.0 "vegan leather" |
| 2026-07-29 | v0.5.0 "alligator": [examples/14-sig-triage](examples/14-sig-triage/) and its eval campaign |
| 2026-08-09 | v0.5.3; [docs/REFERENCE-TANNERY.md](docs/REFERENCE-TANNERY.md) |
| 2026-09-07 | v0.5.4; releases archived on Zenodo from this version on, concept DOI [10.5281/zenodo.22637735](https://doi.org/10.5281/zenodo.22637735) |