How the headroom learn Command Mines Failed Sessions and Writes Corrections to CLAUDE.md

The headroom learn command scans your agent's conversation history for failed tool calls, uses an LLM to identify failure patterns, and writes structured corrections into a guarded marker block inside CLAUDE.md.

The chopratejas/headroom repository implements this as a multi-stage pipeline that turns raw session logs into actionable context for Claude Code. By mining errors from past interactions, the tool automatically generates recommendations that help the agent avoid repeating the same mistakes. Documentation in wiki/learn.md describes the full behavior and file format.

How the CLI Orchestrates the Learning Pipeline

The entry point lives in headroom/cli/learn.py. When you invoke headroom learn, the CLI first detects the target LLM via _detect_default_model and loads the correct learning plugin from the registry using auto_detect_plugins and get_plugin. Each plugin maps to a specific agent such as Claude, Codex, or Gemini, and plugin registration is handled in files like headroom/learn/plugins/claude.py.

For every discovered project, the CLI delegates to the scanner to collect raw sessions, then passes those sessions to the analyzer. The analyzer returns a ResultData object that contains the total failure count, a failure rate, and a list of Recommendation instances. Finally, the CLI invokes the plugin's writer via writer.write. If you omit the --apply flag, the command runs in dry-run mode and only prints what would be persisted.

How the Scanner Discovers Failed Sessions

Session extraction is handled by headroom/learn/scanner.py. Each plugin implements a scan_project method that walks the agent-specific data directory—for Claude Code this is typically ~/.claude/projects/*.jsonl.

The scanner parses each log into a Session object that captures the sequence of tool calls, their inputs, outputs, and error status. It also normalizes file paths through helpers such as _decode_project_path and _greedy_path_decode, ensuring the downstream analyzer receives a canonical representation of every project.

How the Analyzer Synthesizes Recommendations

Pattern recognition is performed by headroom/learn/analyzer.py. The SessionAnalyzer builds a prompt that describes the project, enumerates the collected sessions, and asks the model to identify recurring failure patterns such as wrong file paths, missing imports, or repeated retries.

The LLM responds with structured suggestions that the analyzer transforms into Recommendation objects. Each recommendation includes a section title, body content, an optional token-saving estimate, and a RecommendationTarget that points either to a context file or a memory file.

How the Writer Updates CLAUDE.md

Correction persistence is implemented in headroom/learn/writer.py. The abstract ContextWriter defines the contract, while concrete implementations such as ClaudeCodeWriter, CodexWriter, and GeminiWriter handle agent-specific file layouts.

For Claude Code, the writer creates or updates two files: CLAUDE.md for context and MEMORY.md for memory. Recommendations are inserted into a marker-delimited block that the writer guards from manual edits.

The Marker-Block Format

Inside CLAUDE.md, the writer injects content between these exact comment markers:

<!-- headroom:learn:start -->

## Headroom Learned Patterns

*Auto-generated by `headroom learn` on 2024-11-07 — do not edit manually*

### <section-title>

*~123 tokens/session saved*
<recommendation-body>

<!-- headroom:learn:end -->

This format makes it easy for both humans and the tool to locate managed sections.

Merging Without Data Loss

If CLAUDE.md already contains a headroom:learn block, the writer extracts existing recommendations via _parse_prior_recommendations. It then preserves any sections that were not regenerated and rewrites the block using _merge_into_file. This merge strategy guarantees that repeated runs never overwrite previously learned advice. When dry_run=False, the writer creates missing parent directories with mkdir(parents=True) and commits the merged content to disk.

Practical Usage Examples

Run a dry-run to preview what headroom learn would write without modifying any files:

headroom learn --agent claude

Apply the corrections permanently to CLAUDE.md:

headroom learn --agent claude --apply

You can also interact with the writer directly in Python:

from pathlib import Path
from headroom.learn.writer import ClaudeCodeWriter
from headroom.learn.models import Recommendation, RecommendationTarget, ProjectInfo

writer = ClaudeCodeWriter()
proj = ProjectInfo(
    project_path=Path("/home/user/my_project"),
    context_file=None,
    memory_file=None,
    data_path=Path("/home/user/.claude")
)

recs = [
    Recommendation(
        target=RecommendationTarget.CONTEXT_FILE,
        section="File-Path Corrections",
        content="Update imports to use `src/` instead of `../`.",
        estimated_tokens_saved=140
    )
]

result = writer.write(recs, proj, dry_run=False)
print(result.files_written)

The result.files_written list contains the paths that were updated, such as ~/.claude/CLAUDE.md.

Summary

  • The headroom learn command in chopratejas/headroom is a multi-stage pipeline that converts failed agent sessions into persistent corrections.
  • headroom/cli/learn.py orchestrates plugin detection, scanning, analysis, and writing.
  • headroom/learn/scanner.py parses agent-specific logs like ~/.claude/projects/*.jsonl into normalized Session objects.
  • headroom/learn/analyzer.py uses an LLM to produce structured Recommendation objects that target either context or memory files.
  • headroom/learn/writer.py injects recommendations into a guarded <!-- headroom:learn --> block inside CLAUDE.md and merges new advice without deleting old advice.

Frequently Asked Questions

What file does headroom learn update for Claude Code?

For Claude Code, the writer updates CLAUDE.md for context recommendations and MEMORY.md for memory recommendations. These files live in the agent's data directory, typically under ~/.claude.

Will headroom learn overwrite my existing CLAUDE.md content?

No. The writer in headroom/learn/writer.py calls _parse_prior_recommendations and _merge_into_file to merge new suggestions with existing ones. Any previously learned section that is not regenerated in the current run is preserved inside the marker block.

Which LLM powers the recommendation engine?

The analyzer in headroom/learn/analyzer.py sends a structured prompt to the LLM configured for your agent. The CLI detects the default model via _detect_default_model and loads the corresponding plugin, so the exact model depends on your headroom configuration.

How can I preview changes before writing to disk?

Omit the --apply flag. The default behavior is a dry-run that prints the planned updates without calling the writer with dry_run=False. You can also programmatically pass dry_run=True to the writer's write method to inspect the output.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →