Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 67 additions & 0 deletions plugins/memtrace-skills/INSTALLABLE-DIRECTIVE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# Installable directive: put the Memtrace reflex in the agent's context

> The plugin ships skills, commands, a hook, and an MCP server-instruction block. Two
> of those carry the "graph before grep" reflex only conditionally: the hook is
> scoped to indexed repos and can be opted out, and the injected MCP block can be
> truncated in a long session. To GUARANTEE the reflex is present, add the compact
> directive below to the agent's context, the same way you would add any standing
> instruction to `CLAUDE.md`. Do this AFTER installing the plugin (the directive
> names tools the plugin provides). It is optional but recommended.

## When to install it

- You want the memtrace-first reflex even where the hook is off (`MEMTRACE_ENFORCE=off`)
or absent (a build without the hook).
- You want the recall-before-edit and impact-before-edit reflexes stated once, in
context, rather than relying on each skill's description being ranked correctly.
- You run long sessions where the injected MCP block may be truncated.

## Form A: a block for `CLAUDE.md` (project or global)

Paste this into your project `CLAUDE.md`, or your global `~/.claude/CLAUDE.md`, under
a heading of your choice. It is plain guidance, no tool of its own.

```md
## Memtrace: graph before grep

In a repository Memtrace has indexed:

- Code discovery goes through the graph first. To locate a symbol, find callers, or
map a subsystem, call `find_code` / `find_symbol` / `get_symbol_context` before
`grep` / `rg` / `git grep`. A 0 result means broaden the query or reindex, not fall
back to grep.
- Blast radius before an edit. Before changing an existing symbol, call `get_impact`
(or the `/mt-preflight` command) rather than hunting references by hand.
- Recall before you remove. Before deleting or refactoring existing code you did not
just write, query decision memory (`recall_decision` / `why_is_this_here` /
`governing_contracts`, or `/mt-recall`) so a ban or contract is not silently broken.
- History from the graph. For what changed and when, prefer `get_evolution` /
`get_timeline` / `get_changes_since` over `git log` / `git diff`.

Unaffected: filename globbing (`find`, a name glob), config / data / docs, a plain or
piped single-file `grep`, and any path outside an indexed repo. This is about code
content, not text filtering.
```

## Form B: a rules file (for setups that use `~/.claude/rules/`)

Some setups load standing instructions from per-topic files instead of `CLAUDE.md`.
For those, save the SAME block above as `~/.claude/rules/memtrace.md` (drop the `##`
heading line if your loader adds its own). One topic per file; this file's topic is
the graph-before-grep reflex.

## Optional: let the installer offer it

A future `memtrace install` could OFFER (never silently write) to append Form A to a
`CLAUDE.md` the user names, or to drop Form B into `~/.claude/rules/`, with an explicit
prompt and an easy removal path. Writing to a user's `CLAUDE.md` or rules directory is
the user's decision, so an installer should present the block and let the user place
it, not modify config unprompted.

## Relationship to the other directive surfaces

This installable block is the always-in-context form of the same doctrine that
`MEMTRACE.md` states in full and that `SERVER-INSTRUCTIONS.md` injects via the MCP
server. Installing it is belt-and-suspenders: the hook enforces deterministically
Comment on lines +63 to +65
where it runs, the MCP block nudges each session, and this block guarantees the reflex
is in context regardless. All three are opt-out friendly.
73 changes: 73 additions & 0 deletions plugins/memtrace-skills/MEMTRACE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# MEMTRACE.md: the plugin's top-level directive (precursor)

> The doctrinal precursor of the memtrace/memfleet plugin. The skills, the four
> `/mt-*` commands, the enforce hook, and the MCP server-instruction block are the
> IMPLEMENTATIONS of the reflexes stated here. This file is the "why and when"; the
> skills are the "which tool". It is meant to ship with the plugin as its guidance
> doc, and to be adapted into an installable directive (see
> `INSTALLABLE-DIRECTIVE.md`) so the reflexes reach the agent's context.

## The one reflex

Inside a repository Memtrace has indexed, route CODE work through the graph BEFORE
raw text tools:

- code discovery (locate a symbol, find callers, map a subsystem) goes to
`find_code` / `find_symbol` / `get_symbol_context`, not `grep` / `rg` / `git grep`;
- blast radius before an edit goes to `get_impact`, not a manual reference hunt;
- change history and "what moved when" go to `get_evolution` / `get_timeline` /
`get_changes_since`, not `git log` / `git diff`;
- decision rationale (why does this exist, was this banned) goes to Cortex decision
memory, not a guess from the diff.

A 0 result from a graph tool means broaden the query or reindex, NOT fall back to
grep. Filename globbing (`find`, a name glob), config / data / docs, and paths
outside any indexed repo are UNAFFECTED: the reflex is about code content, not text
filtering.

## The family map (what fires when)

The plugin's skills group into intent families. Reach for the family, not the tool
name; a router skill picks the leaf.

| Family | When it fires | Entry |
|---|---|---|
| Discovery and structure | locate code, traverse a symbol's edges, map a repo, run graph algorithms, see the API surface | `memtrace-first` (router) then search / relationships / codebase-exploration / graph / api-topology |
| Pre-edit safety and impact | what breaks if I change this; a gate before editing one symbol; a risk-rated plan for a multi-symbol change | impact -> preflight -> change-impact-analysis (a ladder by scope) |
| History and temporal | what changed over a range, one episode's diff, historical coupling, root-cause a failure, catch up at session start | evolution / episode-replay / cochange / incident-investigation / session-continuity / daily |
| Decision memory | why does this exist, was this decided or banned, a symbol's lineage, whether a decision held, where it was implemented | `memtrace-decision-memory` (router over recall_decision / why_is_this_here / governing_contracts / verify_intent / get_arc) |
| Docs | how does Memtrace work, install or config, what a tool does, read a docs page | `memtrace-docs` (router over search_docs / ask_docs / read_doc) |
| Fleet coordination | more than one agent shares a repo and branch: declare intent, record edits, resolve a conflict | `memtrace-fleet` (concept) then the publish-intent / record-episode / resolve leaves |
| Code health and quality | dead code and complexity hotspots, a refactor plan, a GitHub PR review, empirical style norms | quality / refactoring-guide / code-review / style-fingerprint |
| Indexing and lifecycle | index a repo once, or watch it for live re-index | index / continuous-memory |

## The load-bearing reflexes

1. Graph before grep, in an indexed repo, for code content.
2. Recall before you remove: before deleting or refactoring existing code you did not
just write, query decision memory (`recall_decision` / `why_is_this_here` /
`governing_contracts`) so a ban or contract is not silently broken.
3. Blast radius before you edit: `get_impact` on a single symbol, a bundled preflight
on one symbol, a risk-rated plan for a multi-symbol change.
4. Catch up from anchors, not from `git log`: session-continuity and the daily
briefing diff the graph at save granularity across sessions.
5. Fleet first on a shared branch: when more than one agent works the same repo and
branch, declare a typed intent before editing.

## The layers that carry this

- SKILLS: per-intent routing (the family map above), one skill per shape.
- COMMANDS: `/mt-onboard`, `/mt-preflight`, `/mt-recall`, `/mt-impact` as one-keystroke
entries into the most common workflows.
- HOOK: a deterministic PreToolUse gate redirects raw recursive code search to the
graph inside an indexed repo, and fails open on anything ambiguous (plain grep, a
filename glob, a path outside any indexed repo, the daemon down, or the opt-out
flag).
- MCP server-instructions: the always-injected form of reflex 1, leading with the
routing doctrine rather than a version banner (see `SERVER-INSTRUCTIONS.md`).
Comment on lines +66 to +67
- INSTALLABLE directive: the same reflexes as a block a user adds to their `CLAUDE.md`
or a rules file after installing the plugin, so the doctrine is present in context
even where the hook is off or absent (see `INSTALLABLE-DIRECTIVE.md`).

Opt-out is always available: `MEMTRACE_ENFORCE=off` disables the hook; the reflexes
stay advisory.
50 changes: 50 additions & 0 deletions plugins/memtrace-skills/commands/mt-impact.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
---
description: Compute the blast radius of a planned change to a symbol via the graph
argument-hint: "<symbol> [repo_id]"
allowed-tools: ["ToolSearch", "mcp__memtrace__list_indexed_repositories", "mcp__memtrace__find_symbol", "mcp__memtrace__get_impact", "mcp__memtrace__get_symbol_context"]
---

# mt-impact: blast radius for a planned change

Compute what a change to one symbol will touch, from the AST graph, in three calls. Do
NOT hand-grep references: a raw search returns line hits with no caller graph or
cross-repo edge, so it undercounts the true blast radius.

## Parameters

`$ARGUMENTS` is `<symbol> [repo_id]`. The first token is the target symbol name
(required); the optional second token is a `repo_id`.

## Behavior

0. Preload the deferred tool schemas:
```
ToolSearch(query="select:mcp__memtrace__find_symbol,mcp__memtrace__get_impact,mcp__memtrace__get_symbol_context,mcp__memtrace__list_indexed_repositories")
```
1. Parse inputs. If the first token is missing, ask for the symbol and stop. Resolve
`repo_id` from the second token if present, else via `list_indexed_repositories`
matched against the current working directory. Flag a `path: null` stub: impact from
a stale index undercounts.
2. Run, in order:
- `find_symbol(name=<target>, repo_id=<repo_id>)` - pin the exact symbol id. If
ambiguous, list matches and ask which one; do not guess.
- `get_impact` - the transitive impact set: direct plus indirect callers (who breaks
if the contract changes) and downstream dependents. Note cross-repo HTTP edges if
present.
- `get_symbol_context` - the symbol's role: its community, the processes it
participates in, and its immediate neighbors. This turns a raw count into a risk
story.
3. Report: the direct caller count, the total transitive impact size, the highest-risk
callers by name, any cross-repo edge, and the community or processes the symbol sits
in. Close with a one-line risk read (LOW / MEDIUM / HIGH) and, if HIGH, the callers to
update in the same change.

## Example

`/mt-impact parseConfig` computes blast radius for `parseConfig` in the cwd-resolved
repo. For a recorded-rationale check on top of the raw radius, chain into
`/mt-preflight` or `/mt-recall`.

## Restrictions

Read-only impact query: performs no edits and never touches the live index.
50 changes: 50 additions & 0 deletions plugins/memtrace-skills/commands/mt-onboard.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
---
description: Map an indexed repo via the Memtrace graph (communities, symbols, processes)
argument-hint: "[repo_id]"
allowed-tools: ["ToolSearch", "mcp__memtrace__list_indexed_repositories", "mcp__memtrace__list_communities", "mcp__memtrace__find_central_symbols", "mcp__memtrace__list_processes", "mcp__memtrace__get_service_diagram"]
---

# mt-onboard: structured repo overview from the graph

Build a structured architecture overview of an indexed repo from the Memtrace knowledge
graph. Do NOT reach for `Glob` / `find` / `tree` / `rg` to infer architecture: the graph
already carries communities, centrality, and execution flows in one pass.

## Parameters

`$ARGUMENTS` is an optional `repo_id`. When omitted, the command resolves the repo whose
indexed path matches the current working directory.

## Behavior

0. Preload the deferred tool schemas (the `mcp__memtrace__*` tools fail with
`InputValidationError` until their schema loads):
```
ToolSearch(query="select:mcp__memtrace__list_indexed_repositories,mcp__memtrace__list_communities,mcp__memtrace__find_central_symbols,mcp__memtrace__list_processes,mcp__memtrace__get_service_diagram")
```
1. Call `list_indexed_repositories`.
- If `$ARGUMENTS` is non-empty, use it verbatim as `repo_id`.
- Otherwise pick the entry whose `path` matches the current working directory. If the
match has `path: null` or `last_indexed_at: null`, the index is a stale stub: report
that and stop, since every downstream answer would come from stale data.
- If nothing matches the cwd and `$ARGUMENTS` is empty, list the candidate `repo_id`
values and ask which one, then stop.
2. Run, in order, each scoped to the resolved `repo_id`:
- `list_communities` - the main modules or subsystems.
- `find_central_symbols` - the highest-centrality symbols (read these first).
- `list_processes` - the main execution flows.
- `get_service_diagram` - how services or repos connect (cross-repo HTTP edges).
3. Synthesize a compact overview: scale (node/edge count from step 1's repo entry), the
top 3 to 5 communities, the 5 most central symbols, the main processes, and any
cross-service edges. Name the entry points a new contributor should read first. Do not
dump raw tool JSON.

## Example

`/mt-onboard` run inside an indexed repo's working directory returns a one-page
architecture map with no further input. `/mt-onboard backend-api` targets a specific
indexed `repo_id` instead of resolving from cwd.

## Restrictions

Read-only discovery command: issues no writes and never resets the index.
53 changes: 53 additions & 0 deletions plugins/memtrace-skills/commands/mt-preflight.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
---
description: Pre-edit safety check on a symbol (blast radius, co-change, decisions, churn)
argument-hint: "<symbol> [repo_id]"
allowed-tools: ["ToolSearch", "mcp__memtrace__list_indexed_repositories", "mcp__memtrace__find_symbol", "mcp__memtrace__get_impact", "mcp__memtrace__get_cochange_context", "mcp__memtrace__recall_decision", "mcp__memtrace__why_is_this_here", "mcp__memtrace__get_timeline"]
---

# mt-preflight: pre-edit safety on a symbol

Before modifying an existing symbol, gather blast radius, hidden coupling, recorded
rationale, and stability in one pass. Do NOT start editing a non-trivial existing
function without this: the graph knows the dependency edges, the git-episode co-change
partners, and any recorded ban that a diff read alone would miss.

## Parameters

`$ARGUMENTS` is `<symbol> [repo_id]`. The first token is the target symbol name
(required); the optional second token is a `repo_id`.

## Behavior

0. Preload the deferred tool schemas:
```
ToolSearch(query="select:mcp__memtrace__find_symbol,mcp__memtrace__get_impact,mcp__memtrace__get_cochange_context,mcp__memtrace__recall_decision,mcp__memtrace__why_is_this_here,mcp__memtrace__get_timeline,mcp__memtrace__list_indexed_repositories")
```
1. Parse inputs. If the first token is missing, ask for the symbol name and stop.
Resolve `repo_id` from the second token if present, else via
`list_indexed_repositories` matched against the current working directory. A
`path: null` / `last_indexed_at: null` match is a stale stub: flag it, results may be
incomplete.
2. Run, in order:
- `find_symbol(name=<target>, repo_id=<repo_id>)` - confirm the exact symbol id. If
several match, list them and ask which one.
- `get_impact` - transitive blast radius (upstream callers plus downstream
dependents). Highest-value probe; do not skip it.
- `get_cochange_context` - files or symbols that historically move with this one (the
hidden edits a diff would forget).
- `recall_decision(query=<target> + intent)` then `why_is_this_here(symbol=<target>)`
- any recorded decision, ban, or convention governing this code. A hit here can veto
the planned edit.
- `get_timeline` - recent modification history (recently churned code is less stable).
3. Emit a short risk verdict: LOW / MEDIUM / HIGH, with the caller count, the co-change
partners to touch together, any governing decision or ban (quoted), and whether the
symbol is stable or hot. If a ban or contract forbids the change, say so and stop
before editing.

## Example

`/mt-preflight parseConfig` checks the symbol `parseConfig` in the cwd-resolved repo.
`/mt-preflight parseConfig backend-api` scopes the same check to `repo_id: backend-api`.

## Restrictions

Read-only pre-flight: performs no edits and never touches the live index.
53 changes: 53 additions & 0 deletions plugins/memtrace-skills/commands/mt-recall.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
---
description: Recall decisions, bans, and conventions from Cortex memory before a refactor
argument-hint: "<query> [repo_id]"
allowed-tools: ["ToolSearch", "mcp__memtrace__list_indexed_repositories", "mcp__memtrace__recall_decision", "mcp__memtrace__why_is_this_here", "mcp__memtrace__governing_contracts", "mcp__memtrace__verify_intent"]
---

# mt-recall: decision-memory recall before delete / refactor / library re-pick

Do NOT infer why code exists from the diff or `git log`, and do NOT assume unfamiliar
code is safe to remove. Cortex decision memory records the bans, conventions, and
contracts that a text search cannot see; recall them first.

## Parameters

`$ARGUMENTS` is `<query> [repo_id]`. The query may be free text ("did we ban X", "why do
we use Y") or a symbol name. The optional trailing token, if it names an indexed repo,
is used as `repo_id`.

## Behavior

0. Preload the deferred tool schemas:
```
ToolSearch(query="select:mcp__memtrace__recall_decision,mcp__memtrace__why_is_this_here,mcp__memtrace__governing_contracts,mcp__memtrace__verify_intent,mcp__memtrace__list_indexed_repositories")
```
1. Parse inputs. If `$ARGUMENTS` is empty, ask what decision or symbol to check and stop.
Resolve `repo_id` from a trailing token that names an indexed repo, else via
`list_indexed_repositories` matched against the current working directory.
2. Recall, widening then narrowing:
- `recall_decision(query=<free text>, repo_id=<repo_id>)` - ranked decisions, bans, or
conventions matching the intent. Read the top hits; a ban here vetoes the planned
action.
- If the target is a specific symbol: `why_is_this_here(symbol=<name>)` - the decision
lineage that put it there.
- `governing_contracts(symbol=<name>)` - the invariants or contracts that bind the
symbol (what must not be broken).
- If a decision looks relevant, `verify_intent(decision_id=<id>)` - did that decision
actually hold, or was it violated (Held / ViolatedAt / CannotProve)? Requires a
`decision_id` from a prior step.
3. State plainly whether there is a recorded decision, ban, or contract touching this.
Quote it with its id. Give the go / no-go: proceed, proceed-with-constraint (name the
contract), or stop (a ban applies). Zero recall hits is not proof of absence: if the
index is a stale stub (`last_indexed_at: null`), say the recall is unreliable rather
than clearing the action.

## Example

`/mt-recall "did we ban global mutable state"` returns any matching decision with a
go/no-go verdict. `/mt-recall parseConfig backend-api` recalls decision lineage for that
symbol in `repo_id: backend-api`.

## Restrictions

Read-only recall: makes no edits and never resets the index.
28 changes: 28 additions & 0 deletions plugins/memtrace-skills/hooks/hooks.json.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"hooks": {
"PreToolUse": [
{
"matcher": "Grep|Bash",
"hooks": [
{
"type": "command",
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/memtrace-enforce-pretooluse.sh",
"timeout": 5000
}
]
}
],
"Stop": [
{
"matcher": ".*",
"hooks": [
{
"type": "command",
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/memtrace-enforce-stop.sh",
"timeout": 5000
}
]
}
]
}
}
Loading