๐Ÿ”ฅ

infernoflow

v0.44.15

A local-first persistent memory layer for AI coding sessions. It captures the gotchas, decisions and dead-ends your code can't tell an agent โ€” and replays them into the next Cursor / Claude Code / Copilot session, so the same wrong turn never happens twice.

runtime deps 0 storage JSONL on disk protocol AMP (open) transports MCP ยท LMT ยท CLI telemetry none license MIT

The problem

Every AI session starts cold

You spend 90 minutes teaching an agent that your auth API returns 200 even on errors. Next session it writes if (response.ok) all over again. The model didn't get worse โ€” it has no memory. Code changes daily; what the system actually does under those edits โ€” the invariants, the constraints, the things that bit you last week โ€” code can't tell you.

Re-derivation

Each session re-reads the code and re-infers the obvious, burning tokens and wall-clock.

Repeated mistakes

The same wrong turn someone hit yesterday gets made again โ€” the gotcha never persisted.

Lost decisions

"Why opaque tokens, not JWTs?" โ€” the rationale lived in a chat that's gone.

System overview

Four layers, one disk file

Clients talk to infernoflow over several interchangeable transports; a small deterministic core reads and writes a single on-disk memory store and keeps the IDE rule files current. No service, no daemon, no network in the default path.

Clients โ€” AI agents
Claude Code
reads CLAUDE.md
Cursor
reads .cursorrules
GitHub Copilot
copilot-instructions.md
Windsurf
.windsurfrules
โ–ฒ   read / write   โ–ผ
Transports โ€” same six tools everywhere
MCP server
amp_* ยท infernoflow_*
VS Code LMT
#amp_write / #amp_read
CLI
log ยท ask ยท switch ยท bookmark
Rule files
injected, marker-managed
โ–ฒ     โ–ผ
Core engine โ€” deterministic, zero-dep
AMP writer / reader
lib/amp/io.mjs
Injection / refresh
ruleFiles.mjs
Learning profile
lib/learning/*
Git drift
lib/git/*
Clean-tree policy
cleanTree.mjs
โ–ฒ     โ–ผ
Storage โ€” plain files, git-tracked
.ai-memory/branches/*.jsonl
per-branch, travels via git
details/*.md
tier-2 rich bodies
global.jsonl
personal, gitignored
amp.json
config
The same six amp_* tools are exposed over MCP, VS Code LMT and as CLI aliases โ€” one product, one disk file, multiple transports. Pick whichever fits your setup; all paths write to the same .ai-memory/.

The loop

Capture โ†’ Link โ†’ Persist โ†’ Restore

infernoflow closes the cold-start loop in four stages. Most of it happens without you: the MCP-aware agent writes entries; the CLI and hooks back it up; the next session boots warm.

01
Capture
A gotcha, decision, failed attempt or pattern is worth saving. The AI calls amp_write; a Cursor prompt-hook backstops it deterministically.
โ†’
02
Link
Each moment becomes a structured AMP entry โ€” type, file:line, tags, timestamp, a stable AMP id.
โ†’
03
Persist
Entries land in branches/<branch>.jsonl (git-tracked) or global.jsonl (personal). Travels with the branch.
โ†’
04
Restore
Next session, the agent reads the rule files at boot โ€” the most relevant entries are already there. Warm start.

Data flow

The closed memory loop

How a single finding travels the whole system โ€” from the moment it surfaces to the next session that starts warm because of it.

THE MEMORY LOOP warm start, no cold derivation MCP boot / commit 1 You + AI work a gotcha / decision surfaces 2 Capture amp_write ยท MCP / hook 3 Persist .ai-memory/*.jsonl (git) 4 Refresh regenerate rule files 5 Rule files CLAUDE.md ยท .cursorrules 6 Next session AI reads at boot

Steps 1โ†’3 are capture (the AI writes, hooks back it up); 4โ†’6 are restore (the core regenerates the rule files, the next session reads them at boot). The green nodes are the durable on-disk state; the cyan nodes are what the agent reads and writes.

Data model โ€” the AMP protocol

Everything is a typed AMP entry

AMP (Agent Memory Protocol) is the vendor-neutral format at the core. One append-only JSONL record per memory, with a stable id so any AMP-Full client can reference it.

Entry schema

// one line in branches/<branch>.jsonl
{
  "id":    "amp_01KYVXSNMAWCQ9โ€ฆ",  // stable AMP id
  "type":  "gotcha",               // see types โ†’
  "msg":   "API returns 200 on errors",
  "file":  "server/src/api.ts",
  "line":  42,
  "tags":  ["auth","http"],
  "ts":    "2026-07-31T08:12:03Z",
  "agent": "infernoflow",          // who wrote it: user | infernoflow
  "detail": "amp_01KYโ€ฆ"            // optional โ†’ details/<id>.md
}

Entry types & retention

TypeMeaningAuto-prune?
gotchaAn invariant that bit younever
decisionA standing choice + rationalenever
patternHow things are done herenever
bookmarkNamed session resume pointnever
attemptA fix that failed30d
noteTransient observation30d
detectionAuto-detected signal30d

Rotation archives stale note/attempt/detection to archive/ โ€” invisible to reads, still on disk. The four durable types are the knowledge you logged infernoflow for.

Two-tier bodies

The lean index (msg + file:line) is what gets injected and stays cheap. A rich detail body lives in details/<id>.md, loaded on demand via readDetail() and never injected into rule files โ€” you pay for the body only when you open it.

Storage layout

One directory, git-native

.ai-memory/
โ”œโ”€โ”€ branches/
โ”‚   โ”œโ”€โ”€ main.jsonl          project truths (git-tracked)
โ”‚   โ””โ”€โ”€ feature-auth.jsonl  branch work (git-tracked)
โ”œโ”€โ”€ details/
โ”‚   โ””โ”€โ”€ amp_01KYโ€ฆ.md        tier-2 bodies (on demand)
โ”œโ”€โ”€ archive/
โ”‚   โ””โ”€โ”€ sessions-2026-07.jsonl  rotated-out
โ”œโ”€โ”€ global.jsonl            personal prefs (gitignored)
โ”œโ”€โ”€ handoff.md              generated by `switch`
โ””โ”€โ”€ amp.json                config

Why plain JSONL on disk

  • Git is the sync + merge engine. Branch memory travels with the branch; teammates inherit it on checkout.
  • merge=union on the branch JSONLs means concurrent commits from two machines merge cleanly โ€” no conflict resolution.
  • No lock-in. It's readable text; grep it, diff it, delete it. No SaaS to leave.
  • Append-only writes keep the working tree calm; rule files refresh only at MCP boot / explicit refresh.

Transports & integration

Same memory, every tool

ToolReads fromWrites via
Claude CodeCLAUDE.mdMCP (amp_write)
Cursor.cursorrulesMCP + beforeSubmitPrompt hook
GitHub Copilot (VS Code).github/copilot-instructions.mdVS Code LMT + MCP โ€” both wired
Windsurf.windsurfrulesMCP (manual wiring)

MCP tool surface

When the server is wired, the agent calls these directly. The six amp_* tools follow the AMP MCP spec โ€” vendor-neutral โ€” and are mirrored as CLI aliases name-for-name.

amp_writeamp_readamp_search amp_bookmarkamp_handoffamp_health infernoflow_status infernoflow_check infernoflow_context infernoflow_git_drift

Injection & refresh

Rule files stay current, and lean

The agent reads the IDE's own rule files at boot. infernoflow owns a marked-off block inside each; your manual edits outside the markers are never touched.

Marker-scoped, budget-bounded

<!-- infernoflow:start -->
๐Ÿ”ฅ gotcha @ api.ts:42 โ€” 200 on errors, check body
๐Ÿ”ฅ decision @ auth.ts โ€” opaque tokens, revocable
<!-- infernoflow:end -->

Injected content is paid for on every turn, so defaults are lean: 4 entries, 5 commits, 200-char truncation, a compact ~3-line protocol. Tunable in amp.json (maxEntries, protocolStyle, targets).

Refresh triggers

  • MCP server boot โ€” the canonical moment rule files regenerate from memory.
  • infernoflow refresh โ€” manual rebuild; --targets controls which files carry the block.
  • git post-commit hook โ€” keeps the block honest as work lands.
  • Content-hash guard โ€” only rewrites when content actually changed, so the tree stays clean.

Note: a running MCP server loads once at session start โ€” after an upgrade, quit & reopen the IDE. infernoflow doctor flags a runtime/CLI version mismatch.

Capture pipeline

The AI writes it โ€” with a deterministic backstop

1 ยท AI-driven

A protocol block in the rule files teaches the agent when to call amp_write: on a gotcha hit, a decision, a failed fix, a pattern.

2 ยท Hook backstop

A Cursor beforeSubmitPrompt hook scans your prompt for triggers (!!, retry, not working, bookmark this) and writes the entry deterministically when the AI doesn't.

3 ยท Transcript distillation

A bookmark with no note reads Claude Code's on-disk transcript, distills the last ~40 turns to markdown, stores it as context โ€” no model call.

Secret patterns (sk-, ghp_, -----BEGIN) are rejected at the AMP writer, so credentials never reach a git-tracked file.

The second product

Capability Contracts โ€” opt-in

One CLI, two products. Session Memory (the default, memory-first) is everything above. Capability Contracts is an opt-in layer for teams that want CI gates on what the system does, not just its code.

Session Memory ยท default

log ยท ask ยท switch ยท recap ยท status ยท bookmark ยท refresh
Mass-market, viral, zero-config. The whole loop above.

Capability Contracts ยท init --mode full

context ยท check ยท git-drift + inferno/ dir (capabilities.json, scenarios). CI gate via the infernoflow/action@v1 GitHub Action.

Branch model & sync

Memory that travels โ€” with the branch, and across machines

Branch-aware (team)

Captures on a feature branch travel with it via git. A teammate runs git checkout feature-auth; the JSONL is there, their MCP server boots, regenerates their rule files โ€” their AI is warm-started on your findings, no message sent.

Cross-machine (personal)

Personal preferences in global.jsonl follow you. Point at any OS-synced folder once โ€” infernoflow sync set ~/Dropbox/โ€ฆ โ€” and home โ†’ work โ†’ home just works. No infra to stand up; the OS does the sync.

Repository map

Components & build

bin/infernoflow.mjs      CLI router (~22 verbs)
lib/
โ”œโ”€โ”€ commands/           log, ask, switch, bookmark,
โ”‚                       context, check, doctor, โ€ฆ
โ”œโ”€โ”€ amp/io.mjs          AMP read/write core
โ”œโ”€โ”€ ruleFiles.mjs       injection / refresh
โ”œโ”€โ”€ learning/           profile, observe, adapt
โ”œโ”€โ”€ git/                drift detection
โ”œโ”€โ”€ ai/                 optional provider router
โ”œโ”€โ”€ adopters/           framework adopters
โ”œโ”€โ”€ mcpRuntime.mjs      MCP runtime stamp
โ””โ”€โ”€ ui/                 terminal output + prompts
vscode-extension/      companion extension
action/               GitHub Action v1
templates/            hooks, MCP server, CI
dist/                 esbuild output (committed)

Build & test

  • Bundler: node build.mjs โ€” esbuild, single pass into dist/.
  • Zero runtime deps: Node โ‰ฅ 18, no postinstall. npm i -g only copies files.
  • Tests: npm test runs the scripts/*-smoke.mjs chain end-to-end.
  • Extension: window-only in 0.7.9+ โ€” the CLI is the single canonical writer of rule files, so there's no race.

VS Code extension surface

Live sidebar (ranked by file), gotchas as Problems (yellow squigglies Copilot also sees), status-bar health score, keyboard-first logging (Ctrl+Alt+G/D/A/S/R). Registers amp_write/amp_read as VS Code Language Model Tools.

Security & privacy

Local-first by construction

๐Ÿšซ

No telemetry

No analytics, no error reporting, no install pings.

๐Ÿšซ

No postinstall

npm i -g infernoflow runs no code โ€” it copies files.

๐Ÿšซ

No network in default path

Every default command runs entirely on your machine.

โœ…

Project-scoped I/O

Reads/writes only inside .ai-memory/ and the three rule files at repo root.

โœ…

Marker-bounded edits

Auto-content is wrapped in markers; your edits outside are untouched.

โœ…

Secret rejection

Entries matching secret patterns are refused at capture.

The optional infernoflow ai setup wires a provider (Anthropic / OpenAI / Google / Ollama) for a few enrichment commands โ€” same trust model as using that provider directly. Off by default.

Design principles

What holds it together

๐Ÿ”’ Local-first, zero-dep

Plain files, no service, no runtime dependencies. The moat is that it's boring infrastructure โ€” set once, forget, like .gitignore.

๐Ÿ”Œ Vendor-neutral (AMP)

An open protocol, not a format lock. Any AMP-Full client needs only the six amp_* tool names.

โšก Transparent automation

One install, everything wired โ€” no separate setup steps, no manual rebuilds, no "now go install the other half".

๐ŸŽฏ It feeds agents, it isn't one

infernoflow never runs your coding agent. It's the memory Cursor / Claude / Copilot read โ€” that's the wedge, and it's deliberate.