Skip to content

Hooks

Hooks are the secret sauce: they let PLUR run without the agent ever calling a tool. The agent walks into a conversation with relevant engrams already in context; it walks out with new engrams already captured. No prompt nudging, no manual saves.

Different runtimes have different hook surfaces. Here’s what PLUR uses in each.

Installed by npx @plur-ai/mcp init or plur init. Writes to ~/.claude/settings.json (global) or .claude/settings.json (project).

Claude Code eventPLUR action
SessionStartCall plur_session_start with task description. Inject top-N engrams into the system prompt.
UserPromptSubmitScan the user message for correction patterns. Stage candidate engrams.
StopCall plur_session_end. Write the episode, promote stable candidates.

The hook binary itself is ~/.plur/bin/plur-claude-hook, installed by plur init. To inspect what’s in settings.json:

Terminal window
cat ~/.claude/settings.json | jq '.hooks'

Expected shape:

{
"hooks": {
"SessionStart": [{ "type": "command", "command": "~/.plur/bin/plur-claude-hook session-start" }],
"UserPromptSubmit": [{ "type": "command", "command": "~/.plur/bin/plur-claude-hook prompt" }],
"Stop": [{ "type": "command", "command": "~/.plur/bin/plur-claude-hook session-end" }]
}
}

When .plur.yaml is present in the project root, hooks read it on session start and tag every engram captured during that session with the configured scope and domain. Without .plur.yaml, engrams default to scope: global.

Remove the line from settings.json. To re-enable later, re-run plur init. The hook is idempotent — it won’t duplicate entries.

@plur-ai/claw implements seven hooks via OpenClaw’s ContextEngine plugin slot:

HookPLUR action
bootstrapOpen the local engram store; warm the index.
ingestScan incoming content for correction patterns; stage candidates.
assemble (required)Inject relevant engrams into the assembled system prompt.
compact (required)Prioritise pinned/locked engrams when context fills; spill the rest.
afterTurnCapture the turn as an episode; check for learnings.
prepareSubagentSpawnHand the subagent a scoped engram bundle so it inherits memory.
onSubagentEndedMerge subagent learnings back into the parent store.

Most ContextEngine plugins implement only assemble and compact and miss the loop. PLUR’s claw plugin implements all seven — that’s what makes the integration “deep”. See OpenClaw adapter.

Three lifecycle hooks pick up automatically once plur-hermes is installed:

Hermes hookPLUR action
pre_llm_callInject relevant memories into the upcoming LLM call.
post_llm_callExtract corrections, preferences, and insights from the response.
on_session_endWrite the episode timeline. Promote stable candidates.

These mirror the OpenClaw triad of assemble / afterTurn / lifecycle-end. See Hermes adapter.

What “automatic capture” actually does

Section titled “What “automatic capture” actually does”

The capture step (UserPromptSubmit / ingest / post_llm_call) scans for these patterns by default:

  • “no, actually …”
  • “from now on …”
  • “the way we do X here is …”
  • “don’t … instead …”
  • “always …” / “never …”
  • “correction:” / “clarification:”

Pattern matches stage candidate engrams — not active ones. Candidates need to recur (default 3 times) or be explicitly promoted before they enter the injection pool. This avoids polluting recall with one-off frustrations.

You can customise patterns in ~/.plur/config.yaml:

capture:
correction_patterns:
- default
- "(?i)never\\s+do\\s+"
- "(?i)always\\s+prefer\\s+"
auto_promote_after: 3

What “automatic injection” actually does

Section titled “What “automatic injection” actually does”

On session start (or assemble / pre_llm_call), the hook calls plur_inject with:

  • The task description (if available — Claude Code passes the first user message).
  • The current scope (read from .plur.yaml or session config).
  • A budget (default: 12 engrams, ~2 KB of system prompt).

The returned engrams are prepended to the system prompt as a structured block:

## DIRECTIVES
[ENG-2026-0325-021] ...
## CONSTRAINTS
[ENG-2026-0503-061] ...
## ALSO CONSIDER
[ENG-2026-0101-019] ...

This is the format every PLUR-aware agent recognises. The same pattern works in Claude Code, OpenClaw, Hermes, and custom adapters.

If hooks aren’t firing:

Terminal window
plur doctor # full diagnostic
tail -f ~/.plur/episodes.jsonl # watch for events
ls -la ~/.plur/bin/ # confirm hook binary present
cat ~/.claude/settings.json | jq '.hooks' # confirm registration

If plur_inject is being called but engrams aren’t appearing in context, check the embedder:

Terminal window
plur status | grep -i embed

bge-m3 is the default; first-run download is ~500 MB. Without it, hybrid recall falls back to BM25-only.