Memory CI for coding agents

Your agent said it wouldn't do that again. Next session, it did.

The rule was in CLAUDE.md. It was acknowledged. Then it was silently dropped at 100k tokens, went quiet after compaction, and the same withdrawn number came back in the next edit. memory-pulse keeps a causal ledger in your repo, prints corrections first in every session, and enforces them: a guard checks each edit before it lands, and one that writes a withdrawn value back is blocked, with the ledger line that retired it. Four MCP tools, ~670 tokens of definitions, no database of your memory anywhere.

/plugin marketplace add t-crew/memory-pulse /plugin install memory-pulse@memory-pulse

Plugin: the four tools, a SessionStart brief, the PreToolUse guard and a skill — ~120 tokens always-on (Claude Code's own estimate, 2026-09-01).

codex plugin marketplace add t-crew/memory-pulse codex plugin add memory-pulse@memory-pulse

Then /hooks inside Codex to trust the two hooks — Codex runs no hook you have not reviewed.

claude mcp add memory-pulse -- npx -y memory-pulse npx memory-pulse install-hook

Any stdio MCP client (Cursor and the rest): npx -y memory-pulse. install-hook adds the brief + guard hooks; --codex targets Codex.

Claude CodeCodex CLICursorany MCP clientGitHub Actions
codex exec · 2026-09-01
$ codex exec "write pricing.md: price is $49"hook: SessionStart  CORRECTIONS (1) — read before quoting any number:  ! price-49-launched -> price-corrected-to-29 — WTP is $29hook: PreToolUse   apply_patch  pricing.mdhook: PreToolUse Blockedmemory-pulse guard: blocked.  pricing.md:  • "$49" was withdrawn at ledger t2:    price-49-launched -> price-corrected-to-29 — use $29Use the corrected value (a comparison naming both goesthrough), record a new correction, or record an override.
pricing.md was not written.
From a Codex CLI 0.151 run against a two-event ledger (lines reflowed to fit). The same ledger blocked the same edit in Claude Code 2.1 the same night (PreToolUse:Write hook error). Ledger t824, t829.
~670tokens
for all four tool definitions
enforced by a test that fails the build past ~1k
0wrong top answers
across 351 causes on our recall benchmark
when it isn't confident it returns nothing · cert_c71bba29493a
1.0precision
guard: 0 false blocks on 931 real edits
60 reintroductions, 871 negatives incl. 694 real notes · guard-eval 2026-09-01
1.7ms p95
local guard check at 1,000 events
the hook runs on every edit; you will not feel it

Try the guard. The memory is the thing on the left.

This is the whole mechanism, in your browser: a ledger you can read and edit, an edit the guard checks against it, and one of three verdicts. Same deterministic rule the hook runs on every Edit, Write and apply_patch — no model, nothing leaves this page.

ledger what the agent is held to .memory-pulse/events.jsonl
edit what the agent is about to write pricing.md

Type into the edit and the verdict follows. Put the replacement beside the old value and it goes through — a comparison is not a reintroduction. Record a correction of your own and the guard holds the edit to it immediately. In the hook, blocked exits 2 and the agent sees exactly this text.

The failure everyone is reporting

Every vendor ships memory as context. Developers keep finding the same thing: context is not compliance.

“The one rule whose remedy was mechanical — a test in the repository that fails when the banned pattern appears — has not regressed since.”

“The memory system becomes write-only — data goes in but doesn't reliably influence behavior.”

“Agreeing with a rule is not complying with it.”

“An uncited memory is an assertion the model has to either trust or ignore. A cited one is evidence it can weigh.”

Quotes are from public issue trackers, linked; none of these people are memory-pulse users. That is the point: the remedy they converged on — a mechanical check — is what this is.

How it works

A loop, not a store. The ledger is the record; the brief and the guard are how it acts on your agent — and a blocked edit is the next correction, so the loop closes.

1 remember

Record what happened, as cause → effect

Findings, decisions, dead ends — one event per fact, in .memory-pulse/events.jsonl in your repo. A correction lists the exact withdrawn terms and their replacement. Writes are local and work offline.

2 pulse

Re-enter through the ledger, corrections first

At session start the hook prints a salience-ranked brief: the CORRECTIONS block first, at every brief size, then the causal chain and recent events — ~99% smaller than reading the history in.

3 guard

Block the edit that writes the old value back

Before each Edit / Write / apply_patch, the guard checks what the change introduces against the withdrawn terms and your declared invariants. Blocked edits cite the ledger line; a comparison that names the replacement goes through.

Memory CI: three verdicts, never a green badge on nothing

Showing an agent a correction is measurably not enough — agents re-violate corrections they were just shown (TRACE, arXiv 2606.13174: more than half, with a memory tool installed). So every check answers one of three ways, and the empty case is loud.

verified

The change agrees with the ledger

It cites which recorded events bear on the edit — evidence, named.

blocked

It writes a withdrawn value back

The verdict names the ledger line and date that retired the term, and the replacement to use. Exit 2 in a hook; a failing check on a PR.

no evidence

The ledger has nothing to say

Reported as exactly that — never as a pass. Silent in the hook (a hook that nags on every edit livelocks the agent), loud under check --ci, neutral on a PR.

memory-ci — failed · pull request #1 on t-crew/memory-pulse · 2026-09-01

memory-pulse: blocked — 1 withdrawn value(s) reintroduced

This change writes back a value the ledger retired, or trips a declared invariant. The verdict cites the line that binds:

  • "published as 0.1.8" was withdrawn at ledger t1: client-0.1.9-published -> versions-0.1.6-to-0.1.8-never-existed-on-npm — use 0.1.9
- uses: t-crew/memory-pulse@v0
  with:
    ledger: .memory-pulse/events.jsonl

What your agent gets

Four terse tools over the ledger, plus the assurance layer around them.

remembertool

Record findings and corrections to the local ledger. Works offline. A correction never decays and always surfaces first — a withdrawn number can't get quoted three sessions later.

pulsetool

Re-enter a project: a salience-ranked brief of what happened, corrections first, sized to a budget you pick.

recalltool

What caused X? What did X cause? Every answer carries a confidence and the recorded links verbatim; when it isn't confident enough it returns nothing.

executetool

Run JS against memory in a sandbox. Only the return value enters context; the corpus it read stays outside.

guardhook

Blocks an Edit, Write or apply_patch that reintroduces a withdrawn value; checks each file in a patch under its own path, so overrides and invariants keep their scope.

memory safetyat write and read

Memory may inform your agent, never instruct it. A note that reads like an instruction is held back at the write and at the read — reported, never rendered into context. Deterministic checks you can read, not a model.

drift alertssigned capsule

A memory that quietly changed is worse than one that forgot. The signed capsule beside your ledger notices lost corrections, a shrinking ledger, or a usage shape that jumps — and the next brief says so.

exactthe ledger layer

Recall is deterministic — the same ledger gives the same brief, every time — and a weak read never hides a correction.

Measured on our own ledger

We run it on the 767-event, 1.08 MB ledger of the project that builds it (pinned run cert_c71bba29493a). Ratios scale with ledger size — a ten-event ledger has nothing to compress, and the brief says so.

124chars
returned by an execute cross-reference against the 1,080,983-char ledger
the intermediates never touched context
~99%smaller
re-entry brief at the smallest tier vs reading the ledger in
character counts exact; token counts estimated at 3.8 chars/token
50–67ktokens
what a typical 5–10 server MCP setup costs before your first prompt
independent measurement — the tax this was built against

What runs where

Structural privacy: the hosted engine keeps no database of your memory. State arrives in the request and leaves in the response.

Your ledgera local file — .memory-pulse/events.jsonl. Commit it, grep it, delete it.
Writeslocal, offline, free forever.
Readsevents go to the engine over TLS; the answer comes back; the request is forgotten. No database of your memory exists on our side.
Persistencestate rides in the request and the signed capsule you keep — nothing to migrate, nothing to leak, nothing to back up on our side.
The clientone file, zero dependencies, MIT — read it. The plugin hooks run that file, so what enforces your corrections is exactly the version you installed.

Reading this as an agent?

This site is built for the reader that installs it. Every page negotiates to Markdown, the site is mapped without parsing HTML, and the server card tells your client how to connect — the same courtesies the product extends to your agent.

# this page, as Markdown
curl -H "Accept: text/markdown" https://pulse.strategic-innovations.ai/
# the map
curl https://pulse.strategic-innovations.ai/llms.txt
# how to connect
curl https://pulse.strategic-innovations.ai/.well-known/mcp.json
  • llms.txt — what memory-pulse is, in the order an agent should read it
  • MCP server card — package, transport, tools, the hosted engine
  • API catalog (RFC 9727) — the engine's endpoints, including the keyless verify
  • robots.txt with Content Signals — search and AI input allowed, training declined
  • Unknown paths return 404, not the homepage — a /.well-known/ hit here is real or it is nothing

Questions people ask before installing

Short answers first; the sections above carry the detail and the measurements.

What is memory-pulse?

memory-pulse is causal project memory for coding agents. It keeps a ledger of cause → effect events in your repo, prints corrections first at every session start, and runs a guard hook that blocks an Edit, Write or apply_patch reintroducing a withdrawn value — citing the ledger line that retired it. Four MCP tools, about 670 tokens of definitions.

Which agents and editors does it work with?

Claude Code and Codex CLI as plugins (SessionStart brief plus PreToolUse guard), Cursor and any stdio MCP client via npx -y memory-pulse, and GitHub Actions as Memory CI, which fails a pull request that writes a withdrawn value back. One client file, MIT licensed, zero dependencies.

How is this different from Mem0, Zep or CLAUDE.md?

Those show memory to the agent; memory-pulse also enforces it. Agents re-violate corrections they were just shown (TRACE, arXiv 2606.13174: more than half, with a memory tool installed), so the guard checks each edit before it lands. Your ledger stays in your repo; the hosted engine keeps no database of your memory. The compare page covers when not to pick us.

Where does my memory live, and what does the engine store?

Your ledger is a local JSONL file in your repo: .memory-pulse/events.jsonl. Writes are local, offline and free. Reads send events to the engine over TLS, the answer comes back, and the request is forgotten. The engine stores license keys and usage counters only — no ledger content, structurally.

What does it cost?

Free: ledgers up to 500 events, 200 reads a day, no account. Pro: $19 a month, ledgers to 20,000 events, unlimited reads, signed check receipts for Memory CI. Enterprise: $79 a month, ledgers to 250,000 events, 10 revocable team seat keys and ledger-integrity receipts with keyless verification. 14-day refund.

What happens when the ledger has nothing to say about an edit?

The verdict is no evidence, reported as exactly that — never as a pass. It is silent in the hook, because a hook that nags on every edit livelocks the agent, loud under check --ci, and neutral on a pull request. The three verdicts are verified, blocked and no evidence.

Pricing

Local writes are free forever on every tier. Reads are what the engine does for you.

Free
$0
  • ledgers up to 500 events
  • 200 reads / day
  • no account, no key
  • local writes: unlimited
Install
Pro
$19/mo
  • ledgers to 20,000 events
  • unlimited reads
  • signed check receipts for Memory CI
  • one env var to activate · cancel any time
Go Pro
Enterprise
$79/mo
  • ledgers to 250,000 events
  • 10 team seat keys, revocable, one subscription
  • ledger-integrity receipts: certify a ledger, verify it from anywhere
  • cancel any time
Go Enterprise

Receipts are hash-chained and HMAC-signed by the engine; verification is a free, keyless endpoint, so an auditor never needs our permission — or your key — to check one. Receipts show nothing was substituted: a substituted, deleted, reordered or truncated event fails by name. 14-day no-questions refund; cancellation reads "lapsed", never silent.