# Headroom Learn

Offline failure learning for coding agents. Analyzes past conversations, finds what went wrong, correlates it with what eventually worked, and writes specific project-level learnings that prevent the same mistakes next session.

## Quick Start

```bash
# See recommendations for current project (dry-run, no changes)
headroom learn

# Write recommendations to CLAUDE.md and MEMORY.md
headroom learn --apply

# Analyze a specific project
headroom learn --project ~/my-project --apply

# Analyze all projects
headroom learn --all --apply
```

## How It Works

```
Past Sessions → Plugin → Analyzer → Writer → Agent-native context file
                  │           │          │
                  │           │          └─ Writes marker-delimited sections
                  │           │             (replaced on re-run, not duplicated)
                  │           │
                  │           └─ LLM-based analysis: finds failure patterns,
                  │              success correlations, and actionable rules
                  │
                  └─ Plugin reads agent-specific logs:
                     • Claude Code: ~/.claude/projects/*.jsonl
                     • Codex:       ~/.codex/sessions/*.json
                     • Gemini CLI:  ~/.gemini/tmp/*/chats/session-*.json
```

### Success Correlation

The core innovation. Instead of cataloging failures ("Read failed 5 times"), Headroom finds what the model did to fix each failure:

- **Failed**: `Read axion-formats/src/main/java/.../FirstClassEntity.java`
- **Then succeeded**: `Read axion-scala-common/src/main/scala/.../FirstClassEntity.scala`
- **Learning**: "`FirstClassEntity` is at `axion-scala-common/`, not `axion-formats/`"

This produces specific, actionable corrections — not generic advice.

## What It Learns

### 1. Environment Facts → CLAUDE.md
Which runtime commands work vs fail.

```markdown
### Environment
- **Python**: use `uv run python` (not `python3` — modules not available outside venv)
```

### 2. File Path Corrections → CLAUDE.md
Wrong paths the model keeps guessing, with the correct locations.

```markdown
### File Path Corrections
- `axion-common/src/.../AxionSparkConstants.scala`
  → actually at `axion-spark-common/src/.../AxionSparkConstants.scala`
```

### 3. Search Scope → CLAUDE.md
Which directories to search in (narrow paths fail, broader ones work).

```markdown
### Search Scope
- Don't search `axion-model/` → use `axion/` (the repo root)
```

### 4. Command Patterns → CLAUDE.md
How commands should (and shouldn't) be run.

```markdown
### Command Patterns
- **user_prefers_manual**: User rejected gradle 18 times — show the command, don't execute
- **python_runtime**: Use `uv run python` not `python3` (ModuleNotFoundError)
```

### 5. Known Large Files → CLAUDE.md
Files that need `offset`/`limit` with Read.

```markdown
### Known Large Files
- `proxy/server.py` (~8000 lines) — always use offset/limit
```

### 6. Retry Prevention → MEMORY.md
Specific suggestions derived from actual corrections.

### 7. Permission Notes → MEMORY.md
Commands repeatedly rejected — model should suggest them to the user instead.

## Where Learnings Go

| Pattern | Claude Code | Codex | Gemini CLI |
|---------|-------------|-------|-----------|
| Environment, paths, commands | **CLAUDE.md** | **AGENTS.md** | **GEMINI.md** |
| Retry patterns, permissions | **MEMORY.md** | **instructions.md** | **GEMINI.md** |

Output files are agent-native: Claude Code uses CLAUDE.md/MEMORY.md, Codex uses AGENTS.md, Gemini uses GEMINI.md. The same learnings, written to the format each agent reads.

## Marker-Based Updates

Headroom manages a clearly-delimited section in each file:

```markdown
<!-- headroom:learn:start -->
## Headroom Learned Patterns
*Auto-generated by `headroom learn` — do not edit manually*
...
<!-- headroom:learn:end -->
```

On re-run, only the content between markers is replaced. Your existing file content is preserved.

## Architecture (Plugin System)

Headroom Learn uses a plugin architecture where each agent is a self-contained plugin:

```
Plugin Registry (auto-discovered)
├── ClaudeCodePlugin  →  Analyzer (LLM)  →  ClaudeCodeWriter  →  CLAUDE.md / MEMORY.md
├── CodexPlugin       →  Analyzer (LLM)  →  CodexWriter       →  AGENTS.md / instructions.md
├── GeminiPlugin      →  Analyzer (LLM)  →  GeminiWriter      →  GEMINI.md
└── (your plugin)     →  Analyzer (LLM)  →  (your writer)     →  (your file)
```

**Plugins** bundle scanning, detection, and writing for one agent. Built-in plugins are auto-discovered from `headroom.learn.plugins.*`. External plugins register via the `headroom.learn_plugin` entry point.

**The Analyzer** is shared — it uses an LLM (Sonnet, GPT-4o, or Gemini Flash) to find patterns. Same analysis for any agent.

### Adding Support for a New Agent

1. Create `headroom/learn/plugins/myagent.py`
2. Implement `LearnPlugin` + `ConversationScanner` (scanner + writer + detection)
3. Add `plugin = MyAgentPlugin()` at module scope
4. Done — `headroom learn --agent myagent` works automatically

Or install an external plugin: `pip install headroom-learn-cursor` (registers via entry point).

## CLI Reference

```
headroom learn [OPTIONS]

Options:
  --project PATH               Project directory (default: current directory)
  --all                        Analyze all discovered projects
  --apply                      Write recommendations (default: dry-run)
  --agent [auto|claude|codex|gemini]
                               Which agent to analyze (default: auto-detect)
  --model TEXT                 LLM for analysis (default: auto from API keys or CLI)
```

### Supported Agents

| Agent | Scanner | Writer | Output Files |
|-------|---------|--------|-------------|
| **Claude Code** | Reads `~/.claude/projects/*.jsonl` | ClaudeCodeWriter | CLAUDE.md, MEMORY.md |
| **OpenAI Codex** | Reads `~/.codex/sessions/*.json` | CodexWriter | AGENTS.md, instructions.md |
| **Gemini CLI** | Reads `~/.gemini/tmp/*/chats/session-*.json` | GeminiWriter | GEMINI.md |

## LLM Backend Selection

`headroom learn` needs an LLM to analyze your sessions. It picks one automatically using this priority:

| Priority | Source | Example |
|----------|--------|---------|
| 1 | `--model` flag | `headroom learn --model gpt-4o` |
| 2 | API key env var | `ANTHROPIC_API_KEY`, `OPENAI_API_KEY`, `GEMINI_API_KEY` |
| 3 | `HEADROOM_LEARN_CLI` env var | `export HEADROOM_LEARN_CLI=gemini` |
| 4 | Auto-detect installed CLIs | Checks PATH for `claude`, `gemini`, `codex` |

### Using without an API key

If you use Claude Code, Gemini CLI, or Codex via subscription (no raw API key), `headroom learn` can call them directly:

```bash
# Auto-detects claude in PATH — no API key needed
headroom learn

# Explicitly select a CLI backend
headroom learn --model gemini-cli

# Pin a CLI via environment variable
export HEADROOM_LEARN_CLI=codex
headroom learn
```

Valid values for `HEADROOM_LEARN_CLI`: `claude`, `gemini`, `codex`.

## Real-World Results

Tested on 67,583 tool calls across 23 projects:

| Metric | Value |
|--------|-------|
| Failure rate | 7.5% (5,066 failures) |
| Corrections extracted | 164 per project (avg) |
| Specific path corrections | 22 (axion project) |
| Search scope corrections | 24 (axion project) |
| Command patterns learned | 5 (axion project) |
| Estimated preventable waste | ~27 MB across corpus |
