You know what is embarrassing? Making the same mistake for the tenth time.

Last week, I typed docker-compose up instead of docker compose up. The command failed. I sighed. I corrected it. Three days later? Same thing. Same sigh. Same correction.

This is not just about typos. Developers repeat the same failed patterns constantly:

The AI agents we use are even worse. Claude Code, Codex, Cursor — they all make the same mistakes, over and over, because they have no long-term memory of what went wrong.

We are not learning from our failures. We are just repeating them.

The Solution: Learning via Negativa

What if your terminal learned from every failed command?

That is exactly what Terraphim’s Learning via Negativa system does. It captures every failed command, extracts the mistake pattern, and builds a knowledge graph that corrects you in real-time.

The name comes from the Latin “per negativa” — learning by knowing what is wrong. It is the pedagogical equivalent of “do not touch the hot stove” after you have already touched it.

Here is how it works:

You type "docker-compose up"
        |
Command fails (docker-compose is deprecated)
        |
Hook captures: command + error + context
        |
Knowledge graph maps: "docker-compose" -> "docker compose"
        |
Next time: Terraphim auto-replaces and suggests the correct command

The Technical Implementation

This is not a wrapper script or a hack. It is a native Rust system built into terraphim-agent that captures, stores, and corrects command mistakes.

1. The Capture Hook

The hook intercepts failed commands from your AI agent:

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FailedCommand {
    pub command: String,
    pub exit_code: i32,
    pub stderr: String,
    pub working_directory: String,
    pub timestamp: DateTime<Utc>,
    pub tags: Vec<String>,
}

pub async fn capture_failed_command(
    command: &str,
    exit_code: i32,
    stderr: &str,
    context: &CommandContext,
) -> Result<FailedCommand, CaptureError> {
    if exit_code == 0 {
        return Err(CaptureError::CommandSucceeded);
    }

    if is_test_command(command) {
        return Err(CaptureError::TestCommand);
    }

    let tags = extract_mistake_tags(command, stderr);

    let failed = FailedCommand {
        command: redact_secrets(command),
        exit_code,
        stderr: stderr.clone(),
        working_directory: context.cwd.clone(),
        timestamp: Utc::now(),
        tags,
    };

    store_learning(&failed).await?;

    Ok(failed)
}

The hook is fail-open by design — never blocks your workflow if capture fails.

2. Building the Correction Knowledge Graph

Once captured, mistakes become nodes in a knowledge graph that maps wrong to correct:

fn build_correction_thesaurus() -> Thesaurus {
    let mut thesaurus = Thesaurus::new("Command Corrections".to_string());

    // Docker corrections
    thesaurus.insert(
        NormalizedTermValue::new("docker-compose up".to_string()),
        NormalizedTerm::new(1, NormalizedTermValue::new("docker compose up".to_string())),
    );

    // Git corrections
    thesaurus.insert(
        NormalizedTermValue::new("git push -f".to_string()),
        NormalizedTerm::new(2, NormalizedTermValue::new("git push --force-with-lease".to_string())),
    );

    // Cargo corrections
    thesaurus.insert(
        NormalizedTermValue::new("cargo buid".to_string()),
        NormalizedTerm::new(3, NormalizedTermValue::new("cargo build".to_string())),
    );

    thesaurus
}

3. Real-Time Correction

# Without Learning via Negativa (old workflow)
$ docker-compose up
docker-compose: command not found
# You: sigh, retype, move on

# With Learning via Negativa
$ docker-compose up
# Terraphim intercepts, corrects, and shows:
Suggestion: Did you mean 'docker compose up'? (y/n)
# You: y, command executes correctly

Correction Results

We tested Learning via Negativa with common developer mistakes over a 30-day period:

Wrong CommandErrorCorrection Learned
docker-compose upcommand not founddocker compose up
git push -fremote: denied by protection policygit push --force-with-lease
cargo buiderror: no such subcommandcargo build
npm isntallcommand not foundnpm install
apt updatePermission deniedsudo apt update
git psuhgit: 'psuh' is not a git commandgit push

Knowledge Graph Growth

Week 1:  12 corrections captured
Week 2:  34 corrections captured (cumulative)
Week 3:  58 corrections captured (cumulative)
Week 4:  89 corrections captured (cumulative)

Top mistake categories:
  - Docker commands: 28%
  - Git commands: 24%
  - Cargo/Rust: 18%
  - npm/yarn: 15%
  - System commands: 15%

Why This Matters

Most AI tools have no memory. Claude Code is brilliant but stateless. Cursor remembers your files, not your mistakes. GitHub Copilot suggests code but forgets that docker-compose has been deprecated for two years.

Learning via Negativa gives your AI agent a memory for failure.

It transforms every error from a one-time annoyance into a permanent lesson. The more you use it, the smarter it gets. And because it is built on the knowledge graph architecture, it does not just match strings — it understands context.

You typed git push -f in a repo with protected branches? It learns that -f is wrong in that context. You use docker-compose in a project with a compose.yaml file? It learns the new syntax applies here.

This differs from the self-correction approach I wrote about earlier in an important way. That post covers the FINAL Bench and MetaCog scaffold — the mechanical system for catching and retrying failures. Learning via Negativa covers the philosophy: building a persistent memory from those failures so the same mistake never happens twice.

Getting Started

# Install terraphim-agent
cargo install terraphim-agent

# Install the learning hook for Claude Code
terraphim-agent learn install-hook claude

# Verify it is working
terraphim-agent learn list

# Query your mistakes anytime
terraphim-agent learn query "your mistake"

The Bigger Picture

Learning via Negativa is more than a feature — it is a philosophy. Every failure contains information. Every error message is feedback. The trick is capturing that signal instead of just ignoring the noise.

We have spent decades building systems that celebrate successes. It is time we built systems that learn from failures too.

Your terminal should remember what you keep getting wrong. That is not just smart — that is how humans actually learn.


Terraphim AI is a privacy-first, deterministic AI assistant built with Rust. Learn more.