The relationship
Claude Agent SDK manages agent loops: tool selection, message passing, streaming, multi-turn context, subagent handoffs. These are execution concerns. Mneme does not touch any of them.
What Mneme does is sit at the boundary between your agent's intentions and your codebase. Before a file write lands, Mneme checks the proposed content against your recorded decisions. After a workflow completes, Mneme can verify the output against the full invariant set. The relationship is infrastructure-shaped: the SDK runs agents; Mneme is what the agents answer to architecturally.
Execution layer
- Agent loop and tool dispatch
- Multi-turn context and streaming
- Subagent orchestration and handoffs
- Tool schema definition and calling
- Retry and error handling within the loop
- Session lifecycle management
Enforcement layer
- Architectural decision corpus (project_memory.json)
- Pre-execution governance checks
- Deterministic keyword retrieval for guidance (top-3, no embeddings); typed literal rules enforced corpus-wide
- Structured PASS / WARN / FAIL verdicts with decision IDs
- Post-execution verification against invariant set
- CI-gateable enforcement trace output
Mneme is not "another agent." It does not call the model. It does not generate text. It scores proposed changes against a pre-registered decision corpus and returns a verdict. The agents answer to it; it does not answer to the agents.
How the integration works
Mneme ships a native adapter for the Claude Agent SDK: MnemeAgentSdk, in the mneme-hq package. It registers on two SDK lifecycle hooks and implements no governance logic of its own — retrieval and enforcement are the same deterministic machinery the CLI uses.
Claude Agent SDK
|
+- UserPromptSubmit
| |
| v
| DecisionRetriever (existing)
| |
| v
| relevant decisions injected as additionalContext
|
+- PreToolUse
|
v
Write / Edit / MultiEdit
|
v
mneme check
|
v
allow / deny / visible unevaluated
Guidance. When your task prompt is submitted, Mneme retrieves the decisions relevant to that task and injects them into the model's context before any work starts. The model begins from your recorded architecture instead of training defaults.
Enforcement. Before a Write, Edit, or MultiEdit reaches disk, the adapter reconstructs exactly what the edit introduces and evaluates it via mneme check, passing the real target path separately for typed-rule applicability. A trusted PASS allows. In strict mode, trusted WARN/FAIL results deny the mutation with the Mneme reason attached — enough for the model to revise its approach without human intervention. In warn mode, the mutation is not blocked; the warning is injected into agent context. Operational or incomplete evaluations fail open visibly as UNEVALUATED. Shell commands are not governed: their file mutations cannot be reconstructed reliably, so they are out of scope rather than falsely claimed as covered.
Wiring it into your application is three lines:
from claude_agent_sdk import ClaudeAgentOptions
from mneme.integrations.agent_sdk import MnemeAgentSdk
mneme = MnemeAgentSdk(project_dir=".")
options = ClaudeAgentOptions(
cwd=".",
hooks=mneme.hooks(),
permission_mode="acceptEdits",
)
Fail-open, but never silently. If the check subprocess fails, times out, or returns an unparseable verdict, the mutation proceeds — a broken governance layer must not lock an agent workflow. But the outcome is never reported as PASS: the adapter injects an explicit unevaluated marker into the agent's context stating that this specific mutation was not checked. Only a complete, trusted verdict can allow or deny.
A proven end-to-end run
This is not a hypothetical wiring diagram. The following loop was executed against a live Claude Agent SDK session with an isolated decision corpus whose single rule is "Use SQLite for local storage" (store_001, forbidding psycopg2):
The full evidence trail — deterministic tests, the live session transcript, and the trace separating context injection from enforcement — is public:
- PR #293 — the integration implementation and evidence record
- docs/integrations/agent-sdk.md — architecture and policy reference
- examples/claude-agent-sdk/ — runnable demo (deterministic mode needs no API key)
Post-execution verification
Pre-execution checks stop violations before they land. Post-execution verification catches what slipped through — partial matches, composite violations, or changes that look compliant per-file but drift when read as a whole. Run a verification pass after your agent workflow completes:
import subprocess, json, sys
def verify_outputs(changed_files: list[str]) -> list[dict]:
violations = []
for path in changed_files:
result = subprocess.run(
["mneme", "check",
"--memory", ".mneme/project_memory.json",
"--input", path,
"--query", f"audit {path}",
"--mode", "strict",
"--json"],
capture_output=True,
text=True,
timeout=10,
)
try:
verdict = json.loads(result.stdout)
if verdict.get("verdict") in ("FAIL", "WARN"):
violations.append({"file": path, **verdict})
except Exception:
pass
return violations
violations = verify_outputs(agent_output_files)
if any(v["verdict"] == "FAIL" for v in violations):
print(json.dumps(violations, indent=2), file=sys.stderr)
sys.exit(1)
The --json flag is what makes json.loads(result.stdout) work: it suppresses the human-readable report and emits only the machine-readable verdict payload. The post-execution pass uses --mode strict: a WARN verdict stays a warning — it is not reclassified as FAIL — but strict mode makes it exit non-zero (exit 1), so any warning fails the gate. Pairing warn-in-hook with strict post-execution verification gives you a two-stage gate: guide the agent while it works, then enforce cleanly when it finishes.
A post-execution enforcement trace:
Enforcement traces in long-running workflows
For autonomous agent workflows that run unattended — scheduled coding tasks, remediation loops, multi-step refactors — the enforcement trace is your primary audit artifact. A governance check that returns PASS is not just a green light; it is a timestamped record that the proposed change was evaluated against the current corpus and found compliant. This matters in three contexts:
- Audit trail. When a long-running workflow produces a diff, you need to know which decisions were in scope at the time the change was generated, not just whether the final output passes today's corpus. The structured trace output (JSON per check, with decision IDs and scores) gives you this.
- CI gates. A governance trace written to a file or stdout can be consumed by your CI pipeline. If any file in the agent's output has a FAIL verdict in the trace, the pipeline fails. This is not a soft advisory — it is a hard gate.
- Remediation loop signal. For autonomous loops where the agent is expected to self-correct, the decision id in a FAIL verdict is the signal. The agent reads which decision was violated, retrieves the rationale from the corpus, and reformulates the change. The loop terminates when the post-execution pass is clean, not when the agent decides it is done.
Deterministic retrieval matters here. Mneme uses keyword scoring, not embeddings. The same query against the same corpus returns the same top-K decisions every time. This means enforcement traces are reproducible: if you re-run a check against the same content and corpus, you get the same verdict. Embedding-based retrieval cannot make this guarantee.
CI integration
Add a governance gate step in your agent workflow's CI configuration. The step runs after your agent produces output and before the PR is opened or the deploy proceeds:
name: agent-governance-gate
on: [push, pull_request]
jobs:
governance:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Mneme
run: pip install mneme-hq
- name: Run agent workflow
run: python scripts/agent_workflow.py
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
- name: Governance gate
run: |
set -e
for f in $(git diff --name-only HEAD~1 -- '*.py' '*.js' '*.ts'); do
mneme check \
--memory .mneme/project_memory.json \
--input "$f" \
--query "audit $f" \
--mode strict
done
shell: bash
The --mode strict flag means any WARN in the trace causes a non-zero exit and fails the step, giving you a per-run record of which files were evaluated and what the verdicts were. Use --mode warn during development iterations to surface signals without blocking merges.
For the maintained GitHub Actions workflow with finer-grained control over which file patterns trigger governance checks, see the GitHub Actions integration page.
FAQ
Is Mneme itself an agent inside the SDK?
UserPromptSubmit injects the decisions relevant to your task before work starts, and PreToolUse evaluates proposed Write, Edit, or MultiEdit mutations and returns the appropriate allow, deny, warning, or visible unevaluated outcome according to Mneme's configured mode — strict mode denies on trusted WARN/FAIL; warn mode injects the warning without blocking. The agents answer to it architecturally; it is not one of them.Does the governance hook add meaningful latency to agent tool calls?
What if my agent uses non-file tools — API calls, shell commands?
mneme check) and a CI gate on the resulting diff are the backstop for anything outside the governed tools. Relevant decisions are still injected as context for every task, so the model reasons from your corpus regardless of which tool it reaches for.