[BUG] BMAD custom-agent memory persistence has no enforcement mechanism
Description
BMAD version: bmad-builder v2.2.2
Repo: bmad-code-org/bmad-builder
Commit: 4a1422274a2acb0fb0ec0511753da6263948f072 (2026-08-31)
Channel: stable
Custom BMAD agents built via bmad-agent-builder (the bmb module) with a persistent "sanctum" (long-term memory across sessions) rely entirely on the model choosing, mid-conversation, to write to memory files. The scaffold this module generates provides no enforcement mechanism, no error, and no warning when that write never happens. A full session can end — window closed, /clear run, /compact run, or the user simply walking away — with zero trace left in the sanctum, and the agent has no way to know anything was lost.
The scaffold's own instructions are prose-only:
SKILL.md(generated): "Capture to your sanctum the moment something is worth keeping... don't wait for the end."references/memory-guidance.md(generated): "append key notes tosessions/YYYY-MM-DD.md... after each session."
Nothing in the generated scaffold, or in the Claude Code harness by default, checks whether these instructions were followed.
Steps to reproduce
- Use
bmad-agent-builder(bmb v2.2.2) to build any custom agent withagent_type = "memory"(a sanctum-backed agent), using the standard generated scaffold — no custom hooks added. - Wake the agent and have a substantive conversation (decisions, facts, context worth remembering).
- End the session without the agent proactively calling
Write/Editon any sanctum file. This requires no special action — it is the default outcome unless the model happens to write unprompted. - Wake the agent again in a new session and ask it about the prior conversation.
Expected behavior
Either:
- The scaffold prevents session end (or at least warns) when substantive conversation occurred and nothing was persisted to the sanctum, so the owner has a chance to capture it before it's gone, or
- At minimum, the agent surfaces on next wake that a prior session produced no memory artifact, so the owner knows to expect a gap.
Actual behavior
The session ends silently. On the next wake, the agent has no record the prior conversation happened at all — not "I don't recall the details," but a complete absence of any file, log entry, or reference to it anywhere in the sanctum. No error is raised at any point, by the scaffold or by Claude Code.
Confirmed by direct filesystem inspection of a real sanctum: sessions/ contained only the birth-session file; no session log or MEMORY.md reference existed for a conversation the owner confirmed had happened minutes earlier.
Screenshots
No response
Which module is this for?
BMad Builder (BMB) - Agent Builder Tool
BMad Version
6.12.0
Which AI IDE are you using?
Claude Code
Operating System
Windows
Relevant log output
No log output exists for the failure itself — that is the bug: the scaffold produces no signal when this happens. The following is log output from a **local, non-upstream workaround** (a `Stop` hook added after the fact, not part of the bmb-generated scaffold), included to show what detection looks like once instrumented, and to support the reproduction steps:
$ python stop_check.py
Gestalt woke this session but no sanctum file has been touched since (MEMORY.md, BOND.md, PERSONA.md, or sessions/*.md). Per memory-guidance.md, append a session log entry to sessions/YYYY-MM-DD.md (or update MEMORY.md/BOND.md directly) before actually stopping, or this session is lost.
EXIT_CODE: 2
Separately, while building that workaround, a second gap was found and confirmed against the Claude Code hooks reference: the `Stop` event only fires when the agent finishes generating a turn — it does not fire on `/clear` or `/compact`, both of which can discard conversation content outright. Investigating the alternative hook events (`PreCompact`, matchers `manual`/`auto`; `SessionEnd`, matcher `"clear"`) confirmed neither can block anything — exit code 2 / blocking JSON is only honored on pre-action events (`PreToolUse`, `UserPromptSubmit`, `Stop`, `SubagentStop`). By the time `PreCompact` or `SessionEnd` fires, the compact/clear has already committed, so no hook-based fix can prevent data loss through those two paths — only best-effort raw capture after the fact.
## Additional Notes (not required fields, included for triage)
- This is reproducible with any `agent_type = "memory"` agent generated by bmb v2.2.2's default scaffold — it is not specific to one agent's configuration.
- A working local mitigation exists (a `Stop` hook plus a `PreCompact`/`SessionEnd` raw-transcript-capture fallback), built and verified outside the bmb scaffold, on this machine only. Happy to share the scripts with the working group if useful as a reference implementation, but they are not a fix to the shipped module.
Confirm
- I've searched for existing issues
- I'm using the latest version
Source: bmad-code-org/BMAD-METHOD