Last week, I wrote How I stopped re-explaining my repo when switching between Claude Code, Codex, and Cursor, where I introduced Vicem — a zero-dependency tool that packs your active session into a single .vicem/BATON.md checkpoint when you hit Claude Code's 5-hour quota or want a second opinion from Codex.
In the comments on that post, Odinaka Robert Nnamani (@robertpaschal) summed up the philosophy better than I did:
"Dumping the whole repo history was never the point. One checkpoint that says what is next beats a wall of context."
At the end of that first post, I asked: "What context do you wish carried over automatically when you bounce between agents?"
Over the next week, developers across Dev.to and Reddit (r/ClaudeCode, r/ChatGPTCoding, r/mcp, r/cursor) stress-tested the baton workflow on real debugging sessions—and exposed four blind spots that a simple git diff + task summary checkpoint completely misses.
Here is what broke in practice, and how I engineered Vicem v1.2.0 (still 0 npm dependencies and 0 network calls) to fix all four.
RAKKUNN
/
vicem
Zero-dependency AI agent context baton & diet suite. Hand off sessions between Claude Code, Codex, Gemini, and Cursor with 80% fewer tokens.
Vicem — Diet the Context, Pass the Baton
Hit Claude Code's 5-hour quota mid-feature? Or watching Cursor / Codex slow to a crawl after 150k tokens of context rot?
Vicem compacts your active coding session by 80–99% (via deterministic AST code skeletonization + lossless MCP on-demand rehydration) and hands off a clean
.vicem/BATON.mdacross Claude Code, Cursor, Codex CLI, Gemini CLI, Windsurf, Antigravity IDE, and Web AI in 3 seconds — with0npm dependencies and0network calls.⭐ Tip: Click Star (top-right) to bookmark this repo for the next time your coding agent hits a 5-hour quota limit or context rot.
🎬 15s Relay Overview — Watch in 1080p60 with sound (MP4) · All Links & Quick Copy
⚡ 10-Second Quick Start (npx — Zero Install)
1. Run the Local Handoff GUI or Pass a Baton Immediately
# Launch the local Handoff GUI (3-step guided handoff,…
Blind Spot #1: git diff Only Shows Surviving Code (So the Next Agent Repeats Your Dead Ends)
The #1 complaint from developers switching agents mid-bugfix was:
"I spent 30 minutes in Claude Code proving that a regex patch in
middleware.tsbreaks edge-case cookies, so I reverted it. Then I hit my quota, switched to Codex, and Codex immediately wrote the exact same broken regex."
Why does this happen?
Because git diff has survivorship bias.
When you try an approach, run npm test, watch it fail (exit code 1), and git checkout or undo the edit, your working tree is clean again. When the next agent arrives and inspects git status and git diff, every trace of your 30-minute failed experiment has vanished.
The Fix in v1.2.0: Causal Extraction of Failed Attempts & Guardrails
While git diff forgets reverted experiments, your local agent transcript (~/.claude/projects/*.jsonl, ~/.codex/sessions/*.jsonl, Cursor's SQLite state, Gemini CLI logs) still has the full crime scene.
In Vicem v1.2.0, I built a deterministic causal state machine inside DeterministicTaskExtractor that scans the local transcript for Edit/Write → Non-Zero Exit Command → Re-edit/Revert chains:
-
Track
PendingEdit(file): Record when the agent modifies a file viaEdit,Write,MultiEdit, orapply_patch. -
Bind
CommandFailure(cmd, exitCode): If a subsequent test/build command exits non-zero or emits a stack trace, link that failure to the pending file edit. -
Classify Outcome:
- If the agent subsequently re-edits or reverts that file, record it as
[88% | REVERTED/AVOIDED]. - If the session ends with the failure still active, record it as
[95% | UNRESOLVED]. - If the user explicitly stated a negative rule ("never touch
legacy-auth.js", "do not add dependencies"), pin it at[100% | CONSTRAINT].
- If the agent subsequently re-edits or reverts that file, record it as
Now, .vicem/BATON.md includes a dedicated minefield map right above the code diff:
### Failed Attempts & Guardrails (Do Not Retry)
- [100% | CONSTRAINT] Never add external npm dependencies or network calls; keep vicem.mjs <= 240 KiB.
- [95% | UNRESOLVED] `node --test test/phase8.test.mjs` -> Artifact size 246,044B exceeded 245,760B limit.
- [88% | REVERTED/AVOIDED] Edited `src/auth/middleware.ts` -> `npm test` failed (exit 1: cookie race) -> had to revert `src/auth/middleware.ts`.
The incoming agent knows what not to try before it writes a single line of code.
Blind Spot #2: How Do You Score What Deserves to Stay in the Checkpoint?
If a checkpoint is supposed to beat a wall of context, it needs a strict token budget.
But how do you rank a 1-line architectural constraint from 40 minutes ago against a 200-line test log from 10 seconds ago?
If you rely on naive LLM /compact summarization, recent research shows a brutal failure mode called The Compaction Cliff (CIKM 2026, arXiv:2608.22752):
- After 1 round of
/compact, only 53% of explicit safety rules survive. - After 5 rounds, 90% of rules are wiped out because uniform summarization compresses rules and episodic logs at the same rate.
The Fix in v1.2.0: A 0–100% Context Salience Percentile Engine
Instead of uniform compression, Vicem v1.2.0 introduces ContextSalienceEngine. Every candidate piece of context is scored on a normalized 0.00–1.00 scale and rendered as a 0%–100% percentile based on Value-per-Token Density:
W_category(i) × Validity(i) × exp(-λ · Δt_i)
Density(i) = ------------------------------------------------------
log2( Tokens(i) + 2 )
// From ContextSalienceEngine in vicem.mjs
class ContextSalienceEngine {
static toPercentile(score01) {
const clamped = Math.max(0, Math.min(1, Number(score01) || 0));
return Math.round(clamped * 100);
}
static computeDensityScore({ baseWeight = 0.5, validity = 1.0, recencyDecay = 1.0, tokenCost = 32 }) {
const raw = (baseWeight * validity * recencyDecay) / Math.log2(Math.max(2, tokenCost + 2));
return Math.max(0.05, Math.min(1.0, Number((raw * 2.2).toFixed(2))));
}
}
-
Hard User Constraints (
100%): Bypass temporal decay (exp(-λ·Δt) = 1.0). A short 15-token constraint has huge value-per-token density and stays pinned at100%. -
Unresolved Failures (
95%) & Reverted Attempts (88%): Preserved in the baton header. -
Modified Functions & Stack-Trace Targets (
75%–94%): Prioritized in the architectural context. -
Untouched Helper Functions (
5%–45%): Folded into 1-line AST signatures ({ /* ... */ }) and indexed in.vicem/ledger.json.
Blind Spot #3: Rehydrating a Single Function Without Its Call Graph (or After Disk Edits)
In v1.1, Vicem introduced AST Code Skeletonization: collapsing unchanged function bodies into /* ... */ while storing the original code in .vicem/ledger.json for on-demand MCP restoration.
Two edge cases immediately came up from MCP users:
- "If the agent rehydrates
parseCFamily(), it immediately realizes it also needsclassifyCBlockHeader()andfindBalancedBraces(), costing 3 separate MCP tool round-trips." - "What if I manually edited the file in Cursor 2 minutes after generating the baton? Won't the ledger serve a stale snapshot?"
The Fix in v1.2.0: 1-Hop Call-Graph Indexing + Live Disk AST Rehydration
First, CodeSkeletonizer.annotateSymbolGraphAndSalience now builds a 1-hop intra-file call graph (calls and called-by) for every skeletonized function and prints it directly in the baton's Rehydration Index:
## 6. Diet Ledger & Rehydration Index
If you need the full implementation of any skeletonized symbol (`/* ... */` or `pass`), call MCP tool `vicem_rehydrate(file_path, symbol_name)`:
- `vicem.mjs` :: `classifyCBlockHeader` (lines 1146-1186) [33% | calls: stripNestedParens | called-by: parseCFamily, findUniqueSymbolSpanInFile]
- `vicem.mjs` :: `parseCFamily` (lines 1204-1277) [31% | calls: findBalancedBraces, classifyCBlockHeader, findSignatureStartIdx | called-by: skeletonize]
Second, the MCP tool vicem_rehydrate now supports:
-
include_callees: true(or comma-separated symbol batches) to restore a function and its 1-hop intra-file callees in a single MCP call. -
Live Disk Drift Detection: When
vicem_rehydrateruns, it checks if the file on disk has changed since the baton snapshot. If it has, Vicem runs a live AST pass on the current file on disk (for both C-family and Python files) and returns both the snapshot and the updated implementation:
// --- [LIVE DISK IMPLEMENTATION (Updated Since Baton Snapshot)] ---
static classifyCBlockHeader(headerText) {
// Freshly extracted from current disk state
}
Blind Spot #4: MCP Resources & Security Verification
In v1.1, agents had to call a tool to read the baton. In v1.2.0, Vicem's stdio MCP server (npx -y vicem-cli mcp) also exposes native MCP Resources (resources/list and resources/read) with automatic SecretRedactor scrubbing:
-
vicem://baton/current— Live.vicem/BATON.mdhandoff state -
vicem://ledger/index— Compact symbol index with salience percentiles and 1-hop call edges -
vicem://salience/report— Ranked salience breakdown of the current repository state
And because security-conscious teams rightly ask "What does this MCP server touch?", Vicem v1.2.0 has now been independently reviewed and listed across:
- 🛡️ HOL Guard Extension Catalog (
mcp.vicem) — Officially reviewed permission surface - 🅰️ Glama MCP Directory — Grade A across Security, License, and Quality
- 🌐 MCP.so & mcpservers.org
Real Dogfooding Numbers: Packing v1.2.0 Itself
We dogfood Vicem on its own codebase (AGENTS.md in the repo root is an actual Vicem baton). Here is the exact receipt from handing off the v1.2.0 branch from Claude Code to Antigravity IDE:
| Metric | Raw Session State |
.vicem/BATON.md (v1.2.0) |
Result |
|---|---|---|---|
| Context Size | 68,387 tokens |
3,430 tokens |
-95.0% (-64,957 tokens) |
| Hard Constraints Retained | 4 / 4 | **4 / 4 (`[100% | CONSTRAINT]`)** |
| Indexed Symbols (1-Hop Graph) | 112 functions | 112 in .vicem/ledger.json |
Lossless on-demand restore |
| Baton Build Time | — | 68ms |
Pure local Node.js |
| npm Dependencies / Network | — | 0 / 0 |
100% offline execution |
Try v1.2.0 in 10 Seconds
We also shortened the CLI commands in v1.2.0 via the vicem-cli package (Node.js >= 22.5.0):
# 1. Open the local 3-step Handoff & Diet Studio GUI (127.0.0.1 only)
npx -y vicem-cli gui
# 2. Or hand off your active session directly to Codex, Claude Code, or Cursor
npx -y vicem-cli codex
npx -y vicem-cli claude
npx -y vicem-cli cursor
# 3. Or register as a local stdio MCP server
claude mcp add vicem -- npx -y vicem-cli mcp
- GitHub Repository (MIT): https://github.com/RAKKUNN/vicem
- Zero-Install Browser Sandbox: https://rakkunn.github.io/vicem/
RAKKUNN
/
vicem
Zero-dependency AI agent context baton & diet suite. Hand off sessions between Claude Code, Codex, Gemini, and Cursor with 80% fewer tokens.
Vicem — Diet the Context, Pass the Baton
Hit Claude Code's 5-hour quota mid-feature? Or watching Cursor / Codex slow to a crawl after 150k tokens of context rot?
Vicem compacts your active coding session by 80–99% (via deterministic AST code skeletonization + lossless MCP on-demand rehydration) and hands off a clean
.vicem/BATON.mdacross Claude Code, Cursor, Codex CLI, Gemini CLI, Windsurf, Antigravity IDE, and Web AI in 3 seconds — with0npm dependencies and0network calls.⭐ Tip: Click Star (top-right) to bookmark this repo for the next time your coding agent hits a 5-hour quota limit or context rot.
🎬 15s Relay Overview — Watch in 1080p60 with sound (MP4) · All Links & Quick Copy
⚡ 10-Second Quick Start (npx — Zero Install)
1. Run the Local Handoff GUI or Pass a Baton Immediately
# Launch the local Handoff GUI (3-step guided handoff,…Huge thanks to everyone who commented on the first post and reported edge cases. If you bounce between Claude Code, Codex, Cursor, or Gemini CLI, drop a ⭐ Star on RAKKUNN/vicem so you have it ready the next time an agent hits a 5-hour quota wall—and let me know in the comments what else your ideal handoff checkpoint would capture!


Top comments (0)