Skip to main content
OrchestKit v6.7.1 — 67 skills, 38 agents, 77 hooks with Opus 4.6 support
OrchestKit

Memory Bridge and Context Injection

How OrchestKit injects past decisions into every prompt, captures new decisions automatically, and syncs memory across sessions through the knowledge graph.

The Memory Pipeline

OrchestKit maintains memory across sessions through a pipeline of hooks that capture, store, load, and inject context. The system follows a graph-first architecture: the knowledge graph (via MCP) is always available with zero configuration.

Session N                                   Session N+1
---------                                   -----------
User prompt                                 SessionStart
    |                                           |
    v                                           v
capture-user-intent  --->  decisions.jsonl  --->  memory-context-loader
    |                      graph-queue.jsonl       (once, first prompt)
    v                                                  |
memory-context  --->  search graph  --->  additionalContext injected
(every prompt)        for past decisions  into Claude's context
    |
    v
Stop (fire-and-forget)
    |
    +--> graph-queue-sync (flush to graph)
    +--> auto-remember-continuity

Memory Context Loader (First Prompt)

Hook: prompt/memory-context-loader Event: UserPromptSubmit (once: true) Purpose: Load recent project decisions as context on the first prompt of every session.

This hook reads from .claude/memory/decisions.jsonl -- a file written by the capture-user-intent hook during previous sessions. Each line is a JSON record containing a decision or preference:

{
  "id": "dec_abc123",
  "type": "decision",
  "content": {
    "what": "Use cursor-based pagination for the orders API",
    "why": "Offset pagination causes timeouts on tables with 1M+ rows"
  },
  "entities": ["cursor-pagination", "orders-api"],
  "metadata": {
    "timestamp": "2026-01-15T10:30:00Z",
    "confidence": 0.85,
    "category": "api",
    "project": "myproject"
  }
}

The hook loads the last 10 decisions, formats them as markdown, and injects them via additionalContext:

## Recent Project Decisions

- **[Decision]** Use cursor-based pagination for the orders API _(because: Offset pagination causes timeouts on tables with 1M+ rows)_ [cursor-pagination, orders-api]
- **[Preference]** Use Tailwind CSS for all new components [frontend, tailwind]
- **[Decision]** PostgreSQL 16 for the analytics database _(because: Need JSONB and vector support)_ [PostgreSQL, analytics]

_For deeper graph traversal: use mcp__memory__search_nodes or mcp__memory__open_nodes_

Budget Awareness

The context loader caps output at 3,000 characters to avoid consuming too much of the context window. If there are more decisions than fit within the budget, it truncates with a hint:

- _(additional decisions available via mcp__memory__search_nodes)_

Memory Context (Every Prompt)

Hook: prompt/memory-context Event: UserPromptSubmit (every prompt) Purpose: Search the knowledge graph for context relevant to the current prompt.

Unlike the context loader (which runs once and injects recent decisions), this hook runs on every prompt and performs keyword-based relevance detection.

Trigger Detection

The hook checks the prompt against two keyword lists:

Memory triggers (suggest memory search would be valuable): add, implement, create, build, design, refactor, update, modify, fix, change, continue, resume, remember, previous, last time, before, earlier, pattern, decision, how did we, what did we

Graph triggers (suggest relationship queries): relationship, related, connected, depends, uses, recommends, what does.*recommend, how does.*work with

How It Works

Skip check. If the prompt is shorter than 20 characters, or contains no trigger keywords, the hook returns silently.

Extract search terms. Stopwords are removed and the prompt is reduced to 5 key terms.

Build context hint. The hook constructs a system message telling Claude how to search:

[Memory Context] For relevant past project decisions,
use mcp__memory__search_nodes with query="cursor pagination orders"

Add relationship hints (if graph triggers detected):

For relationships: mcp__memory__open_nodes on found entities
| Graph traversal available

Add agent context (if an agent is active):

Agent context: database-engineer

The hook does not execute the graph search itself -- it provides Claude with the instruction to do so. This keeps the hook fast (under 10ms) while giving Claude the information it needs to decide whether to query memory.

Global vs Project Scope

If the prompt starts with @global or mentions "cross-project" or "all projects", the hook switches to global scope:

[Memory Context] For relevant past cross-project decisions...

Capture User Intent (Every Prompt)

Hook: prompt/capture-user-intent Event: UserPromptSubmit (fire-and-forget via silent runner) Purpose: Extract decisions and preferences from user prompts automatically.

This hook listens for decision signals in the user's natural language:

SignalPatternExample
Decision"let's use X", "chose Y over Z", "going with X""Let's use PostgreSQL for the analytics DB"
Preference"I prefer X", "always use X""I prefer Tailwind over styled-components"
Problem"the issue is", "blocked by""The issue is that offset pagination times out"
Rationale"because X", "since X""...because we need JSONB support"

When a decision is detected, the hook:

  1. Creates a structured decision record with what, why, entities, confidence score, and category
  2. Appends it to .claude/memory/decisions.jsonl (via storeDecision)
  3. Queues a graph memory write to .claude/memory/graph-queue.jsonl
// The decision record structure
const record = createDecisionRecord({
  what: "Use PostgreSQL for analytics",
  why: "Need JSONB and vector support",
  entities: ["PostgreSQL", "analytics"],
  category: "database",
  confidence: 0.85,
});

storeDecision(record, projectDir);

The hook runs via the silent runner (run-hook-silent.mjs), meaning it produces no terminal output and does not block the prompt processing pipeline.

Queue-Based Memory Sync

Memory writes are not performed immediately during the session. Instead, they are queued to local JSONL files and flushed at session end via the fire-and-forget stop hooks.

Graph Queue

File: .claude/memory/graph-queue.jsonl Flushed by: stop/graph-queue-sync

Each queued entry describes an entity or relation to create in the knowledge graph:

{
  "action": "create_entity",
  "entity": {
    "name": "PostgreSQL",
    "entityType": "Technology",
    "observations": ["Selected for analytics database", "Chosen for JSONB and vector support"]
  },
  "timestamp": "2026-01-15T10:30:00Z"
}
{
  "action": "create_relation",
  "relation": {
    "from": "analytics-database",
    "to": "PostgreSQL",
    "relationType": "USES"
  },
  "timestamp": "2026-01-15T10:30:00Z"
}

At session end, the graph-queue-sync hook reads the queue and executes the operations against the knowledge graph MCP.

Memory in Subagents

When a subagent is spawned, the graph memory inject hook provides memory context:

Graph Memory Inject

Hook: subagent-start/graph-memory-inject Event: SubagentStart

Searches the knowledge graph for entities and relations relevant to the subagent's task, then injects them as additional context.

Memory Fabric Initializer

Hook: pretool/mcp/memory-fabric-init Event: PreToolUse (mcp__memory__*) (once: true)

On the first MCP memory tool call of the session, this hook initializes the memory fabric -- setting up the connection to the knowledge graph. It runs once and silently.

Memory Validator

Hook: pretool/mcp/memory-validator Event: PreToolUse (mcp__memory__*)

Validates knowledge graph operations before they execute, ensuring entity names are properly formatted and relation types follow the expected vocabulary.

The Three-Tier Memory Architecture

OrchestKit's hooks bridge three storage tiers:

TierStorageWritten ByRead By
1. Knowledge GraphMCP mcp__memory__*graph-queue-sync (stop)memory-context (prompt), graph-memory-inject (subagent)
2. Local JSONL.claude/memory/*.jsonlcapture-user-intent (prompt), memory-writermemory-context-loader (first prompt)
3. CC NativeMEMORY.mdHigh-confidence decisions (>= 0.7) auto-writtenClaude Code system prompt (automatic)

All three tiers require zero configuration and always work. CC Native memory (Tier 3) is written automatically for high-confidence decisions and persists even without OrchestKit installed.

Auto-Remember Continuity

Hook: stop/auto-remember-continuity (fire-and-forget)

At session end, this hook reviews the session's key decisions and ensures they are stored for the next session. It acts as a safety net -- if capture-user-intent missed a decision during the session, this hook catches it during the cleanup pass.

Profile Injector

Hook: prompt/profile-injector Event: UserPromptSubmit (once: true)

On the first prompt, this hook injects the user's profile context (project identity, team conventions, preferred tools) from .claude/context/identity.json. This is separate from memory -- it provides static configuration rather than learned decisions.

Summary: Which Hooks Touch Memory?

HookEventDirectionFrequency
memory-context-loaderUserPromptSubmitRead (JSONL)Once per session
memory-contextUserPromptSubmitRead hint (graph)Every prompt
capture-user-intentUserPromptSubmitWrite (JSONL + queues)Every prompt
graph-memory-injectSubagentStartRead (graph)Per subagent
memory-fabric-initPreToolUse (MCP)SetupOnce per session
memory-validatorPreToolUse (MCP)ValidatePer MCP call
graph-queue-syncStopWrite (graph)Once at exit
auto-remember-continuityStopWrite (all)Once at exit
profile-injectorUserPromptSubmitRead (config)Once per session
Edit on GitHub

Last updated on