📝 Bug Description
The Pi plugin injects MEMORY_INSTRUCTIONS (and the post-compaction recovery notice) by returning { systemPrompt } from before_agent_start (plugin/pi/index.ts, still present on main, around L1961–1982).
Pi (0.87.1) turns a handler-returned systemPrompt into a run-scoped forceSystemPrompt (extensions/runner.js) and clears it when the run ends (agent-session.js, _runSystemPromptOptions = undefined). A turn started by pi.sendMessage(..., { triggerTurn: true }) while Pi is idle — for example a background subagent result — runs without before_agent_start, so that turn's system prompt reaches the provider without the Engram memory protocol.
- With most providers this is silent: the model just runs without the memory protocol.
- With
pi-claude-bridge the turn fails, because the bridge recorded the prompt including Engram's text and receives one that is an exact prefix of it.
The missing tail is exactly "\n\n" + MEMORY_INSTRUCTIONS (2673 chars), observed on two different prompts.
🔄 Steps to Reproduce
- Pi 0.87.1 with the Engram Pi plugin and
pi-claude-bridge, using a claude-bridge/* model.
- Launch any subagent in background mode (for example gentle-pi's
subagent_run with mode: "background") and let the parent turn end.
- When the result is delivered (
sendMessage with triggerTurn: true), the new turn fails.
✅ Expected Behavior
The memory protocol is present on every turn, including turns started by triggerTurn messages. No provider error.
❌ Actual Behavior
Error: prompt-capture: no capture for this 62770-char system prompt, and it embeds none of the 12 known.
Closest known match diverges at offset 62770 (65443-char key, last recorded at turn_start).
65443 − 62770 = 2673 = "\n\n" + MEMORY_INSTRUCTIONS.
Operating System
Linux (Arch/Manjaro)
Engram Version
2.2.1 (Pi plugin from a source checkout; the same code is on main)
Agent / Client
Other
📋 Relevant Logs
No response
💡 Additional Context
📝 Bug Description
The Pi plugin injects
MEMORY_INSTRUCTIONS(and the post-compaction recovery notice) by returning{ systemPrompt }frombefore_agent_start(plugin/pi/index.ts, still present onmain, around L1961–1982).Pi (0.87.1) turns a handler-returned
systemPromptinto a run-scopedforceSystemPrompt(extensions/runner.js) and clears it when the run ends (agent-session.js,_runSystemPromptOptions = undefined). A turn started bypi.sendMessage(..., { triggerTurn: true })while Pi is idle — for example a background subagent result — runs withoutbefore_agent_start, so that turn's system prompt reaches the provider without the Engram memory protocol.pi-claude-bridgethe turn fails, because the bridge recorded the prompt including Engram's text and receives one that is an exact prefix of it.The missing tail is exactly
"\n\n" + MEMORY_INSTRUCTIONS(2673 chars), observed on two different prompts.🔄 Steps to Reproduce
pi-claude-bridge, using aclaude-bridge/*model.subagent_runwithmode: "background") and let the parent turn end.sendMessagewithtriggerTurn: true), the new turn fails.✅ Expected Behavior
The memory protocol is present on every turn, including turns started by
triggerTurnmessages. No provider error.❌ Actual Behavior
65443 − 62770 = 2673 =
"\n\n" + MEMORY_INSTRUCTIONS.Operating System
Linux (Arch/Manjaro)
Engram Version
2.2.1 (Pi plugin from a source checkout; the same code is on
main)Agent / Client
Other
📋 Relevant Logs
No response
💡 Additional Context
event.systemPromptOptions.appendSystemPromptinstead of returning a replacementsystemPrompt; keep the current return only as a fallback whensystemPromptOptionsis absent (older Pi).