memtrace 0.1.27 → 0.1.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +53 -20
- package/package.json +4 -4
- package/skills/commands/memtrace-cochange.md +73 -0
- package/skills/commands/memtrace-evolution.md +13 -0
- package/skills/workflows/memtrace-episode-replay.md +100 -0
- package/skills/workflows/memtrace-incident-investigation.md +28 -7
- package/skills/workflows/memtrace-session-continuity.md +98 -0
package/README.md
CHANGED
|
@@ -35,12 +35,12 @@ That's it. Claude picks up the skills and MCP tools automatically.
|
|
|
35
35
|
|
|
36
36
|
## Why Memtrace Exists
|
|
37
37
|
|
|
38
|
-
|
|
38
|
+
Good code intelligence tools already exist. GitNexus and CodeGrapherContext build AST-based graphs with symbol relationships, and they work well for understanding what's in your codebase *right now*.
|
|
39
39
|
|
|
40
|
-
Memtrace is a **bi-temporal episodic structural knowledge graph**. It
|
|
40
|
+
Memtrace is a **bi-temporal episodic structural knowledge graph**. It builds on that same AST foundation and adds two dimensions:
|
|
41
41
|
|
|
42
42
|
- **Temporal memory** — every symbol carries its full version history. Agents can reason about *what changed*, *when it changed*, and *how the architecture evolved* — not just what exists today. Six scoring algorithms (impact, novelty, recency, directional, compound, overview) let agents ask different temporal questions.
|
|
43
|
-
- **Cross-service API topology** — Memtrace maps HTTP call graphs between repositories, detecting which services call which endpoints
|
|
43
|
+
- **Cross-service API topology** — Memtrace maps HTTP call graphs between repositories, detecting which services call which endpoints across your architecture.
|
|
44
44
|
|
|
45
45
|
On top of that, the structural layer is comprehensive:
|
|
46
46
|
|
|
@@ -48,7 +48,7 @@ On top of that, the structural layer is comprehensive:
|
|
|
48
48
|
- **Relationships are edges** — `CALLS`, `IMPLEMENTS`, `IMPORTS`, `EXPORTS`, `CONTAINS`
|
|
49
49
|
- **Community detection** — Louvain algorithm identifies architectural modules automatically
|
|
50
50
|
- **Hybrid search** — Tantivy BM25 + vector embeddings + Reciprocal Rank Fusion, all on top of the graph
|
|
51
|
-
- **Rust-native** — compiled binary, no Python/JS runtime overhead,
|
|
51
|
+
- **Rust-native** — compiled binary, no Python/JS runtime overhead, sub-15ms average query latency
|
|
52
52
|
|
|
53
53
|
The agent doesn't just search your code. It *remembers* it.
|
|
54
54
|
|
|
@@ -58,15 +58,15 @@ All benchmarks run on the same machine, same codebase, same queries. No cherry-p
|
|
|
58
58
|
|
|
59
59
|
### Does it find the right thing?
|
|
60
60
|
|
|
61
|
-
<img alt="Search accuracy: Memtrace
|
|
61
|
+
<img alt="Search accuracy: Memtrace 97.3% vs ChromaDB 89.6% vs GitNexus 12.8%" src="https://raw.githubusercontent.com/syncable-dev/memtrace-public/main/assets/benchmarks/search-accuracy.svg" width="720"/>
|
|
62
62
|
|
|
63
63
|
### How fast?
|
|
64
64
|
|
|
65
|
-
<img alt="Search latency: Memtrace
|
|
65
|
+
<img alt="Search latency: Memtrace 13.4ms vs ChromaDB 60.6ms vs GitNexus 172.7ms vs CodeGrapher 510.5ms" src="https://raw.githubusercontent.com/syncable-dev/memtrace-public/main/assets/benchmarks/search-latency.svg" width="720"/>
|
|
66
66
|
|
|
67
67
|
### How much context does it save?
|
|
68
68
|
|
|
69
|
-
<img alt="Token usage: Memtrace
|
|
69
|
+
<img alt="Token usage: Memtrace 319K vs ChromaDB 1.91M — 83% reduction" src="https://raw.githubusercontent.com/syncable-dev/memtrace-public/main/assets/benchmarks/token-context.svg" width="720"/>
|
|
70
70
|
|
|
71
71
|
### How long to set up?
|
|
72
72
|
|
|
@@ -77,15 +77,15 @@ All benchmarks run on the same machine, same codebase, same queries. No cherry-p
|
|
|
77
77
|
|
|
78
78
|
<br/>
|
|
79
79
|
|
|
80
|
-
Mem0 and Graphiti are
|
|
80
|
+
Mem0 and Graphiti are strong conversational memory engines designed for tracking entity knowledge (e.g. `User -> Likes -> Apples`). They excel at that. For code intelligence specifically, the tradeoff is that they rely on LLM inference to build their graphs — which adds cost and time when processing thousands of source files.
|
|
81
81
|
|
|
82
|
-
**Graphiti** processes data through `add_episode()`, which triggers multiple LLM calls per episode — entity extraction, relationship resolution, deduplication. At ~50 episodes/minute ([source](https://github.com/getzep/graphiti)), ingesting 1,500 code files takes **1–2 hours**.
|
|
82
|
+
**Graphiti** processes data through `add_episode()`, which triggers multiple LLM calls per episode — entity extraction, relationship resolution, deduplication. At ~50 episodes/minute ([source](https://github.com/getzep/graphiti)), ingesting 1,500 code files takes **1–2 hours**.
|
|
83
83
|
|
|
84
|
-
**Mem0** processes data through `client.add()`, which queues async LLM extraction and conflict resolution per memory item ([source](https://mem0.ai)). Bulk ingestion with `infer=True` (default) means every file passes through an LLM
|
|
84
|
+
**Mem0** processes data through `client.add()`, which queues async LLM extraction and conflict resolution per memory item ([source](https://mem0.ai)). Bulk ingestion with `infer=True` (default) means every file passes through an LLM pipeline. Throughput is bounded by your LLM provider's rate limits.
|
|
85
85
|
|
|
86
|
-
**Both** accumulate $10–50+ in API costs
|
|
86
|
+
**Both** accumulate $10–50+ in API costs for large codebases because every relationship is inferred rather than parsed.
|
|
87
87
|
|
|
88
|
-
**Memtrace indexes 1,500 files in 1.2–1.8 seconds for $0.00
|
|
88
|
+
**Memtrace takes a different approach:** it indexes 1,500 files in 1.2–1.8 seconds for $0.00 — no LLM calls, no API costs, no rate limits. Native Tree-sitter AST parsers resolve deterministic symbol references (`CALLS`, `IMPLEMENTS`, `IMPORTS`) locally. The tradeoff is that Memtrace is purpose-built for code — it doesn't handle conversational entity memory the way Mem0 and Graphiti do.
|
|
89
89
|
|
|
90
90
|
</details>
|
|
91
91
|
|
|
@@ -94,7 +94,7 @@ Mem0 and Graphiti are excellent conversational memory engines for tracking entit
|
|
|
94
94
|
|
|
95
95
|
<br/>
|
|
96
96
|
|
|
97
|
-
GitNexus and CodeGrapherContext both build AST-based code graphs with structural relationships —
|
|
97
|
+
GitNexus and CodeGrapherContext both build AST-based code graphs with structural relationships — solid tools in the same space. Memtrace shares that foundation and extends it with temporal memory, API topology, and a Rust runtime:
|
|
98
98
|
|
|
99
99
|
| Capability | Memtrace | GitNexus | CodeGrapher |
|
|
100
100
|
|:-----------|:---------|:---------|:------------|
|
|
@@ -105,10 +105,14 @@ GitNexus and CodeGrapherContext both build AST-based code graphs with structural
|
|
|
105
105
|
| Community detection (Louvain) | **Yes** | Yes | No |
|
|
106
106
|
| Hybrid search (BM25 + vector + RRF) | **Yes — Tantivy + embeddings** | No | BM25 + optional embeddings |
|
|
107
107
|
| Language | **Rust (compiled binary)** | JavaScript | Python |
|
|
108
|
-
|
|
|
109
|
-
|
|
|
108
|
+
| Search accuracy (1K queries) | **97.3%** | 12.8% | 0%* |
|
|
109
|
+
| Query latency (1K queries) | **13.4 ms avg** | 172.7 ms avg | 510.5 ms avg |
|
|
110
|
+
| Tokens per query | **319 avg** | 254 avg | 23 avg |
|
|
111
|
+
| Index time (1,500 files) | **1.5 sec** | 10.5 sec | ~3.5 min |
|
|
110
112
|
|
|
111
|
-
|
|
113
|
+
*CGC's 0% reflects an output format mismatch — it returns symbol names without file paths, so our Acc@1 evaluator can't match them. CGC likely finds relevant symbols; the metric just can't confirm it. All numbers from [live benchmark](https://github.com/syncable-dev/memtrace-public/tree/main/benchmarks) on the same machine, same codebase, same 1,000 queries.
|
|
114
|
+
|
|
115
|
+
The latency difference is primarily Rust vs. interpreted runtimes, and Memgraph's Bolt protocol vs. HTTP/embedding pipelines. The feature difference is temporal memory and API topology — dimensions Memtrace adds on top of the shared AST-graph foundation.
|
|
112
116
|
|
|
113
117
|
</details>
|
|
114
118
|
|
|
@@ -205,11 +209,28 @@ Six scoring algorithms for different temporal questions:
|
|
|
205
209
|
|
|
206
210
|
Uses **Structural Significance Budgeting** to surface the minimum set of changes covering ≥80% of total significance.
|
|
207
211
|
|
|
212
|
+
## Compatibility
|
|
213
|
+
|
|
214
|
+
| Editor / Agent | MCP Tools (25+) | Skills (12) | Install |
|
|
215
|
+
|:---------------|:---------------:|:-----------:|:--------|
|
|
216
|
+
| **Claude Code** | ✅ | ✅ | `npm install -g memtrace` — fully automatic |
|
|
217
|
+
| **Claude Desktop** | ✅ | ✅ | Automatic — shared with Claude Code |
|
|
218
|
+
| **Cursor** | ✅ | Coming soon | Add MCP server manually |
|
|
219
|
+
| **Windsurf** | ✅ | Coming soon | Add MCP server manually |
|
|
220
|
+
| **VS Code (Copilot)** | ✅ | — | Add MCP server manually |
|
|
221
|
+
| **Cline / Roo Code** | ✅ | — | Add MCP server manually |
|
|
222
|
+
| **Codex CLI** | ✅ | Coming soon | Add MCP server manually |
|
|
223
|
+
| **Any MCP client** | ✅ | — | Add MCP server manually |
|
|
224
|
+
|
|
225
|
+
> **MCP tools** work with any editor or agent that supports the [Model Context Protocol](https://modelcontextprotocol.io). **Skills** are Claude-specific workflow prompts that teach the agent *how* to chain tools — they require Claude Code or Claude Desktop.
|
|
226
|
+
|
|
208
227
|
## Setup
|
|
209
228
|
|
|
210
|
-
### Claude Code
|
|
229
|
+
### Claude Code + Claude Desktop
|
|
230
|
+
|
|
231
|
+
`npm install -g memtrace` handles everything automatically — binary, 12 skills, MCP server, plugin, and marketplace all register in one command for both Claude Code and Claude Desktop.
|
|
211
232
|
|
|
212
|
-
|
|
233
|
+
For manual setup:
|
|
213
234
|
|
|
214
235
|
```bash
|
|
215
236
|
claude plugin marketplace add syncable-dev/memtrace
|
|
@@ -217,9 +238,9 @@ claude plugin install memtrace-skills@memtrace --scope user
|
|
|
217
238
|
claude mcp add memtrace -- memtrace mcp -e MEMGRAPH_URL=bolt://localhost:7687
|
|
218
239
|
```
|
|
219
240
|
|
|
220
|
-
###
|
|
241
|
+
### Other Editors (Cursor, Windsurf, VS Code, Cline)
|
|
221
242
|
|
|
222
|
-
|
|
243
|
+
After `npm install -g memtrace`, add the MCP server to your editor's config:
|
|
223
244
|
|
|
224
245
|
```json
|
|
225
246
|
{
|
|
@@ -233,6 +254,18 @@ Skills and plugins are shared between Claude Code and Claude Desktop — both ac
|
|
|
233
254
|
}
|
|
234
255
|
```
|
|
235
256
|
|
|
257
|
+
<details>
|
|
258
|
+
<summary>Config file locations by editor</summary>
|
|
259
|
+
|
|
260
|
+
| Editor | Config file |
|
|
261
|
+
|:-------|:------------|
|
|
262
|
+
| **Cursor** | `.cursor/mcp.json` in your project root |
|
|
263
|
+
| **Windsurf** | `~/.codeium/windsurf/mcp_config.json` |
|
|
264
|
+
| **VS Code (Copilot)** | `.vscode/mcp.json` in your project root |
|
|
265
|
+
| **Cline** | Cline MCP settings in the extension panel |
|
|
266
|
+
|
|
267
|
+
</details>
|
|
268
|
+
|
|
236
269
|
### Uninstall
|
|
237
270
|
|
|
238
271
|
```bash
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "memtrace",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.29",
|
|
4
4
|
"description": "Code intelligence graph — MCP server + AI agent skills + visualization UI",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"mcp",
|
|
@@ -31,9 +31,9 @@
|
|
|
31
31
|
"preuninstall": "node uninstall.js"
|
|
32
32
|
},
|
|
33
33
|
"optionalDependencies": {
|
|
34
|
-
"@memtrace/darwin-arm64": "0.1.
|
|
35
|
-
"@memtrace/linux-x64": "0.1.
|
|
36
|
-
"@memtrace/win32-x64": "0.1.
|
|
34
|
+
"@memtrace/darwin-arm64": "0.1.20",
|
|
35
|
+
"@memtrace/linux-x64": "0.1.20",
|
|
36
|
+
"@memtrace/win32-x64": "0.1.20"
|
|
37
37
|
},
|
|
38
38
|
"engines": {
|
|
39
39
|
"node": ">=18"
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: memtrace-cochange
|
|
3
|
+
description: "Use when the user asks what tends to change together with a symbol, what other code moves when this moves, historical coupling, blast awareness before modifying a symbol, or wants to find hidden dependencies not visible in the call graph"
|
|
4
|
+
allowed-tools:
|
|
5
|
+
- mcp__memtrace__get_cochange_context
|
|
6
|
+
- mcp__memtrace__find_symbol
|
|
7
|
+
- mcp__memtrace__get_impact
|
|
8
|
+
user-invocable: true
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Overview
|
|
12
|
+
|
|
13
|
+
Find symbols that historically co-change with a target symbol — ranked by co-occurrence frequency across all episodes. This surfaces **behavioral coupling** that the static call graph cannot see.
|
|
14
|
+
|
|
15
|
+
`get_impact` answers "who calls this?" (structural).
|
|
16
|
+
`get_cochange_context` answers "what always moves when this moves?" (historical).
|
|
17
|
+
|
|
18
|
+
They are complementary. A symbol with no direct callers can still have strong cochange partners if it's always modified alongside another in every commit.
|
|
19
|
+
|
|
20
|
+
## Steps
|
|
21
|
+
|
|
22
|
+
### 1. Identify the target symbol
|
|
23
|
+
|
|
24
|
+
Use `find_symbol` if you need the exact name. The tool matches by `name` field.
|
|
25
|
+
|
|
26
|
+
### 2. Call `get_cochange_context`
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
get_cochange_context(
|
|
30
|
+
repo_id: "...",
|
|
31
|
+
symbol: "execute", // exact symbol name
|
|
32
|
+
limit: 20 // default 20, increase for broader view
|
|
33
|
+
)
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### 3. Interpret results
|
|
37
|
+
|
|
38
|
+
The response contains `cochanges[]`, each with:
|
|
39
|
+
- `name` — symbol name
|
|
40
|
+
- `kind` — Function / Method / Class / Struct
|
|
41
|
+
- `file_path` — where it lives
|
|
42
|
+
- `cochange_count` — how many episodes it shared with the target
|
|
43
|
+
|
|
44
|
+
```
|
|
45
|
+
High cochange_count = strong historical coupling
|
|
46
|
+
→ If you modify the target, you will likely need to touch this too
|
|
47
|
+
→ Or it may be the real root cause you should investigate first
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### 4. Cross-reference with call graph
|
|
51
|
+
|
|
52
|
+
For the top cochange partners, optionally run `get_impact` to see if the coupling is also structural:
|
|
53
|
+
|
|
54
|
+
| Structural coupling | Historical coupling | Interpretation |
|
|
55
|
+
|---|---|---|
|
|
56
|
+
| Yes | Yes | Core architectural dependency — highest risk |
|
|
57
|
+
| No | Yes | Hidden coupling — only visible through history |
|
|
58
|
+
| Yes | No | Called frequently but changed independently — lower risk |
|
|
59
|
+
|
|
60
|
+
## When to Use
|
|
61
|
+
|
|
62
|
+
- **Before modifying a symbol** — get blast awareness beyond what `get_impact` shows
|
|
63
|
+
- **Incident investigation** — when `get_impact` doesn't explain the blast radius, check cochange history
|
|
64
|
+
- **Code review** — verify that a PR touched all historically-coupled partners
|
|
65
|
+
- **Refactoring** — discover implicit coupling before extracting a module
|
|
66
|
+
|
|
67
|
+
## Common Mistakes
|
|
68
|
+
|
|
69
|
+
| Mistake | Reality |
|
|
70
|
+
|---------|---------|
|
|
71
|
+
| Only using `get_impact` for blast radius | Structural coupling misses behavioral coupling — always pair with cochange |
|
|
72
|
+
| Ignoring low-`in_degree` cochange partners | A rarely-called utility with high cochange_count is a strong coupling signal |
|
|
73
|
+
| Using cochange as a dependency map | It's not a dependency graph — it's a change correlation. Two symbols can cochange without any direct relationship. |
|
|
@@ -6,6 +6,7 @@ allowed-tools:
|
|
|
6
6
|
- mcp__memtrace__get_timeline
|
|
7
7
|
- mcp__memtrace__detect_changes
|
|
8
8
|
- mcp__memtrace__list_indexed_repositories
|
|
9
|
+
- mcp__memtrace__get_changes_since
|
|
9
10
|
user-invocable: true
|
|
10
11
|
---
|
|
11
12
|
|
|
@@ -109,6 +110,17 @@ compound = 0.50×rank(impact) + 0.35×rank(novel) + 0.15×rank(recent)
|
|
|
109
110
|
- Impact-dominant but boosted by novelty and recency
|
|
110
111
|
- Best default when you don't have a specific hypothesis
|
|
111
112
|
|
|
113
|
+
## Auto-overview Safety
|
|
114
|
+
|
|
115
|
+
If a time window produces more than 500 candidates and mode is not `overview`, the query **automatically downgrades to overview mode** and returns `auto_overview: true`. This prevents timeouts on wide windows. When you see `auto_overview: true`:
|
|
116
|
+
- Narrow the window, OR
|
|
117
|
+
- Switch to `get_changes_since` (which handles this automatically), OR
|
|
118
|
+
- Use the `by_module` rollup to identify the specific area and query a tighter window
|
|
119
|
+
|
|
120
|
+
## Session-Aware Alternative
|
|
121
|
+
|
|
122
|
+
If you're resuming work after a break and don't know the right `from` timestamp, use `get_changes_since` instead — it accepts a `last_episode_id` anchor and never requires timestamp guessing.
|
|
123
|
+
|
|
112
124
|
## Common Mistakes
|
|
113
125
|
|
|
114
126
|
| Mistake | Reality |
|
|
@@ -117,3 +129,4 @@ compound = 0.50×rank(impact) + 0.35×rank(novel) + 0.15×rank(recent)
|
|
|
117
129
|
| Ignoring `budget_exhausted` flag | If true, there are more significant changes beyond what was returned — narrow the time window or use module rollup |
|
|
118
130
|
| Not checking `by_module` first | Module rollup is never truncated — scan it to identify which areas changed before diving into symbol-level |
|
|
119
131
|
| Using `recent` without setting `to` | The `to` timestamp is the reference point for proximity weighting — set it to the incident/event time |
|
|
132
|
+
| Guessing timestamps when resuming work | Use `get_changes_since` with a stored `session_anchor` instead — exact episode boundary, no guessing |
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: memtrace-episode-replay
|
|
3
|
+
description: "Use when an agent needs to understand why code looks the way it does, replay implementation steps between commits, find what was tried and reverted, understand a colleague's (or your past self's) reasoning, or avoid repeating a previously-abandoned approach"
|
|
4
|
+
allowed-tools:
|
|
5
|
+
- mcp__memtrace__get_episode_replay
|
|
6
|
+
- mcp__memtrace__get_timeline
|
|
7
|
+
- mcp__memtrace__find_symbol
|
|
8
|
+
- mcp__memtrace__list_indexed_repositories
|
|
9
|
+
user-invocable: true
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Overview
|
|
13
|
+
|
|
14
|
+
Replay the sub-commit implementation narrative for any symbol. Between any two commits, Memtrace recorded every file save as a `working_tree` episode. This tool surfaces that sequence — the attempts, the reversions, the iterative refinements — not just the final committed state.
|
|
15
|
+
|
|
16
|
+
**Git shows A→B. Episode replay shows every step in between.**
|
|
17
|
+
|
|
18
|
+
This is the only tool that can answer: "why does this code look like this?" without relying on commit messages or comments.
|
|
19
|
+
|
|
20
|
+
## Steps
|
|
21
|
+
|
|
22
|
+
### 1. Identify the symbol and time window
|
|
23
|
+
|
|
24
|
+
Use `find_symbol` to get the exact symbol name if needed. Determine the window:
|
|
25
|
+
- `from` — when to start (e.g. a few days before a confusing commit)
|
|
26
|
+
- `to` — when to end (usually the commit timestamp or now)
|
|
27
|
+
|
|
28
|
+
If you don't know the window, call `get_timeline` first to find when the symbol changed.
|
|
29
|
+
|
|
30
|
+
### 2. Call `get_episode_replay`
|
|
31
|
+
|
|
32
|
+
```
|
|
33
|
+
get_episode_replay(
|
|
34
|
+
repo_id: "...",
|
|
35
|
+
symbol: "execute",
|
|
36
|
+
from: "2026-04-10T00:00:00Z",
|
|
37
|
+
to: "2026-04-13T00:00:00Z",
|
|
38
|
+
include_working_tree: true, // false = commits only
|
|
39
|
+
compress: true // collapse identical-hash runs
|
|
40
|
+
)
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### 3. Read the narrative_hint sequence
|
|
44
|
+
|
|
45
|
+
Each episode has a `narrative_hint` — derived automatically from AST hash patterns:
|
|
46
|
+
|
|
47
|
+
| Hint | What it means |
|
|
48
|
+
|---|---|
|
|
49
|
+
| `committed` | A real git commit — the "public record" checkpoint |
|
|
50
|
+
| `pre_commit_finalization` | Last working_tree save before a commit — the final draft |
|
|
51
|
+
| `iterative_refinement` | 3+ consecutive working_tree saves — active development in progress |
|
|
52
|
+
| `attempted_and_reverted` | Hash returned to a prior state — something was tried and backed out |
|
|
53
|
+
| `no_change` | File was saved but this symbol didn't change |
|
|
54
|
+
| `working_tree_save` | A single file save with structural changes |
|
|
55
|
+
|
|
56
|
+
### 4. Reconstruct the implementation story
|
|
57
|
+
|
|
58
|
+
Read the sequence like a narrative:
|
|
59
|
+
|
|
60
|
+
```
|
|
61
|
+
committed ← "here's where we started"
|
|
62
|
+
working_tree_save ← "first attempt"
|
|
63
|
+
iterative_refinement ← "refining the approach"
|
|
64
|
+
attempted_and_reverted ← "tried X, it was wrong, backed out"
|
|
65
|
+
pre_commit_finalization← "final version before commit"
|
|
66
|
+
committed ← "here's what shipped"
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
The gap between `committed` entries is the implementation story.
|
|
70
|
+
|
|
71
|
+
### 5. Identify what to act on
|
|
72
|
+
|
|
73
|
+
| Pattern | Implication |
|
|
74
|
+
|---|---|
|
|
75
|
+
| `attempted_and_reverted` appears | There was a tried-and-abandoned approach — understand why before trying similar |
|
|
76
|
+
| Multiple `iterative_refinement` clusters | The author was unsure — this area may need extra care |
|
|
77
|
+
| No working_tree episodes (commits only) | Code was written elsewhere or pasted in — less implementation history available |
|
|
78
|
+
| Very short episode sequence | Straightforward change — low implementation complexity |
|
|
79
|
+
|
|
80
|
+
## When to Use
|
|
81
|
+
|
|
82
|
+
- **Before modifying unfamiliar code** — understand the intent, not just the current state
|
|
83
|
+
- **Post-session debugging** — replay what was tried during a broken session
|
|
84
|
+
- **Code review** — understand the reasoning behind non-obvious implementations
|
|
85
|
+
- **Avoiding dead ends** — check if the approach you're about to try was already attempted and reverted
|
|
86
|
+
|
|
87
|
+
## Compression
|
|
88
|
+
|
|
89
|
+
With `compress: true` (default), consecutive episodes with identical `ast_hash` are collapsed to first+last of the run. Cosmetic saves and whitespace-only edits are filtered out. Only structurally significant transitions are shown.
|
|
90
|
+
|
|
91
|
+
With `compress: false`, every single save is shown — useful when you want to see exact timing between saves.
|
|
92
|
+
|
|
93
|
+
## Common Mistakes
|
|
94
|
+
|
|
95
|
+
| Mistake | Reality |
|
|
96
|
+
|---------|---------|
|
|
97
|
+
| Only reading the final committed code | The commit shows *what*, the episode replay shows *why* — always check both for unfamiliar code |
|
|
98
|
+
| Ignoring `attempted_and_reverted` hints | These are the most valuable entries — they represent knowledge about what doesn't work |
|
|
99
|
+
| Using `include_working_tree: false` by default | Commits-only loses all the sub-commit narrative — only use this if you explicitly want commit-level granularity |
|
|
100
|
+
| Large windows with compress off | Very long histories produce noise; use `compress: true` unless you need exact save-by-save granularity |
|
|
@@ -11,6 +11,8 @@ allowed-tools:
|
|
|
11
11
|
- mcp__memtrace__find_symbol
|
|
12
12
|
- mcp__memtrace__analyze_relationships
|
|
13
13
|
- mcp__memtrace__list_indexed_repositories
|
|
14
|
+
- mcp__memtrace__get_cochange_context
|
|
15
|
+
- mcp__memtrace__get_episode_replay
|
|
14
16
|
user-invocable: true
|
|
15
17
|
---
|
|
16
18
|
|
|
@@ -75,6 +77,21 @@ Call `get_evolution` with mode `directional` to separate:
|
|
|
75
77
|
- **Removed symbols** — deleted code (potential missing functionality)
|
|
76
78
|
- **Modified symbols** — changed behaviour (potential regressions)
|
|
77
79
|
|
|
80
|
+
### 8. Check historical coupling (cochange)
|
|
81
|
+
|
|
82
|
+
For the primary suspect, call `get_cochange_context`:
|
|
83
|
+
- Which symbols historically co-change with this one?
|
|
84
|
+
- If the blast radius from `get_impact` doesn't explain the failure area, check cochange partners — the coupling may be behavioral, not structural.
|
|
85
|
+
|
|
86
|
+
**Decision:** If a cochange partner is in the failure area but has no direct call relationship to the suspect, it's a hidden dependency — investigate both.
|
|
87
|
+
|
|
88
|
+
### 9. Replay the sub-commit implementation history (if needed)
|
|
89
|
+
|
|
90
|
+
If the suspect's commit history doesn't explain the intent, call `get_episode_replay`:
|
|
91
|
+
- What was tried before the final committed state?
|
|
92
|
+
- Was any approach attempted and reverted in the same session?
|
|
93
|
+
- The `attempted_and_reverted` hint often explains why seemingly-correct code was changed to something subtler.
|
|
94
|
+
|
|
78
95
|
## Report: Root Cause Analysis
|
|
79
96
|
|
|
80
97
|
1. **Incident Timeline** — when it started, what was observed
|
|
@@ -86,13 +103,15 @@ Call `get_evolution` with mode `directional` to separate:
|
|
|
86
103
|
|
|
87
104
|
## Algorithm Selection Guide for Incidents
|
|
88
105
|
|
|
89
|
-
| Phase | Mode | Why |
|
|
90
|
-
|
|
91
|
-
| Initial triage | `recent` | Time-weighted ranking surfaces changes near the incident |
|
|
92
|
-
| Anomaly detection | `novel` | Catches unexpected changes to stable code |
|
|
93
|
-
| Scope assessment | `
|
|
94
|
-
|
|
|
95
|
-
|
|
|
106
|
+
| Phase | Tool / Mode | Why |
|
|
107
|
+
|-------|-------------|-----|
|
|
108
|
+
| Initial triage | `get_evolution` `recent` | Time-weighted ranking surfaces changes near the incident |
|
|
109
|
+
| Anomaly detection | `get_evolution` `novel` | Catches unexpected changes to stable code |
|
|
110
|
+
| Scope assessment | `get_impact` | Ranks by structural significance (blast radius) |
|
|
111
|
+
| Hidden coupling | `get_cochange_context` | Surfaces behavioral coupling not in the call graph |
|
|
112
|
+
| Direction analysis | `get_evolution` `directional` | Separates added/removed/modified |
|
|
113
|
+
| Sub-commit intent | `get_episode_replay` | Reveals what was tried before the committed state |
|
|
114
|
+
| Quick summary | `get_evolution` `overview` | Fast module-level scan before deep-diving |
|
|
96
115
|
|
|
97
116
|
## Common Mistakes
|
|
98
117
|
|
|
@@ -102,3 +121,5 @@ Call `get_evolution` with mode `directional` to separate:
|
|
|
102
121
|
| Only looking at the most recent commit | The root cause may be from an earlier change whose effects were delayed |
|
|
103
122
|
| Ignoring `novel` mode | Unexpected changes to stable code are often the root cause |
|
|
104
123
|
| Not checking blast radius overlap | A change is only a suspect if its blast radius reaches the failure area |
|
|
124
|
+
| Stopping at call graph analysis | `get_cochange_context` finds hidden coupling — symbols that move together without calling each other |
|
|
125
|
+
| Reading only committed code | `get_episode_replay` reveals tried-and-reverted approaches that explain the current implementation |
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: memtrace-session-continuity
|
|
3
|
+
description: "Use at the start of any session to check what changed since last time, when resuming work after a break, when an agent needs to orient itself without guessing timestamps, or when asked 'what changed while I was away'"
|
|
4
|
+
allowed-tools:
|
|
5
|
+
- mcp__memtrace__get_changes_since
|
|
6
|
+
- mcp__memtrace__list_indexed_repositories
|
|
7
|
+
- mcp__memtrace__get_evolution
|
|
8
|
+
user-invocable: true
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Overview
|
|
12
|
+
|
|
13
|
+
Session continuity for agents. Instead of guessing a time window and blindly running `get_evolution`, pass a `session_anchor` from your last session and get back exactly what changed — nothing more. The response returns a new anchor to persist for next time.
|
|
14
|
+
|
|
15
|
+
**Core principle:** Agents track a cursor, not a clock. Never guess timestamps.
|
|
16
|
+
|
|
17
|
+
## Steps
|
|
18
|
+
|
|
19
|
+
### 1. Find or bootstrap the session anchor
|
|
20
|
+
|
|
21
|
+
Look for a stored `session_anchor` from your last session:
|
|
22
|
+
|
|
23
|
+
```json
|
|
24
|
+
{
|
|
25
|
+
"last_episode_id": "ep_abc123",
|
|
26
|
+
"last_reference_time": "2026-04-13T10:43:00Z"
|
|
27
|
+
}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
If you have no anchor yet (first run), call `list_indexed_repositories`. Each repo now includes `last_episode_id`, `last_episode_time`, and `last_episode_type` — use `last_episode_id` as your bootstrap anchor.
|
|
31
|
+
|
|
32
|
+
### 2. Call `get_changes_since`
|
|
33
|
+
|
|
34
|
+
```
|
|
35
|
+
get_changes_since(
|
|
36
|
+
repo_id: "...",
|
|
37
|
+
last_episode_id: "ep_abc123" // preferred — exact episode boundary
|
|
38
|
+
// OR
|
|
39
|
+
last_reference_time: "2026-04-13T10:43:00Z" // fallback
|
|
40
|
+
)
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### 3. Interpret the response
|
|
44
|
+
|
|
45
|
+
| `status` | Meaning | Action |
|
|
46
|
+
|---|---|---|
|
|
47
|
+
| `no_changes` | Nothing changed since your anchor | Safe to proceed; store new anchor |
|
|
48
|
+
| `changes_detected` | Full symbol-level delta returned | Review `modified[]`, `added[]`, `removed[]` |
|
|
49
|
+
| `changes_detected_overview` | >500 candidates — module rollup only | Check `by_module` for affected areas |
|
|
50
|
+
| `error` | Bad anchor or unknown episode | Fall back to `last_reference_time` or re-index |
|
|
51
|
+
|
|
52
|
+
### 4. Decide whether changes are relevant
|
|
53
|
+
|
|
54
|
+
```
|
|
55
|
+
changes_detected
|
|
56
|
+
├── Check modified[]/added[]/removed[] — do any overlap with your current task?
|
|
57
|
+
│ ├── YES → understand what changed before proceeding
|
|
58
|
+
│ └── NO → safe to continue, update anchor
|
|
59
|
+
|
|
60
|
+
changes_detected_overview (large window)
|
|
61
|
+
├── Check by_module — does any changed module overlap with your task area?
|
|
62
|
+
│ ├── YES → get_evolution(mode: compound) scoped to that window for detail
|
|
63
|
+
│ └── NO → ignore, update anchor
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### 5. Always persist the returned anchor
|
|
67
|
+
|
|
68
|
+
Every response includes a new `session_anchor`. Store it for next session:
|
|
69
|
+
|
|
70
|
+
```json
|
|
71
|
+
{
|
|
72
|
+
"session_anchor": {
|
|
73
|
+
"last_episode_id": "ep_xyz789",
|
|
74
|
+
"last_reference_time": "2026-04-13T14:22:00Z"
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Auto-mode Selection
|
|
80
|
+
|
|
81
|
+
`get_changes_since` automatically picks the right mode so it never crashes:
|
|
82
|
+
|
|
83
|
+
| Candidate count | Mode selected | What you get |
|
|
84
|
+
|---|---|---|
|
|
85
|
+
| 0 | — | `no_changes` immediately |
|
|
86
|
+
| 1–499 | `compound` | Full symbol scoring |
|
|
87
|
+
| 500+ | `overview` | Module rollup only |
|
|
88
|
+
|
|
89
|
+
`candidate_count` in the response tells you what was found before selection.
|
|
90
|
+
|
|
91
|
+
## Common Mistakes
|
|
92
|
+
|
|
93
|
+
| Mistake | Reality |
|
|
94
|
+
|---------|---------|
|
|
95
|
+
| Using `get_evolution` with a guessed timestamp | `get_changes_since` uses an exact episode boundary — no guessing, no over-fetching |
|
|
96
|
+
| Discarding the returned `session_anchor` | Without it, next session reverts to timestamp guessing |
|
|
97
|
+
| Treating `changes_detected_overview` as too large to act on | `by_module` is complete — it tells you exactly which areas changed even in large windows |
|
|
98
|
+
| Calling this tool repeatedly within one session | Call once at session start; use the returned evolution result for the rest of the session |
|