fix(plugin): prevent sub-agent infinite loop on session lifecycle calls#129
fix(plugin): prevent sub-agent infinite loop on session lifecycle calls#129jzambrano12 wants to merge 1 commit intoGentleman-Programming:mainfrom
Conversation
Sub-agents (Explore, etc.) inherit the engram memory protocol and interpret their task completion as a session close, entering an infinite loop of mem_session_summary → mem_context → mem_session_summary calls. With bypassPermissions enabled, sessions hang for up to 1 hour. Add "SUB-AGENT SCOPE" sections to the injected protocol text in session-start.sh, post-compaction.sh, and memory/SKILL.md that explicitly tell sub-agents to skip session lifecycle tools (mem_session_start, mem_session_end, mem_session_summary). Scope SESSION CLOSE and AFTER COMPACTION headers as TOP-LEVEL AGENT ONLY so the mandatory language no longer applies to delegated tasks. Closes Gentleman-Programming#128
Includes PR Gentleman-Programming#129 sub-agent scope guards. Ensures server running, creates session, imports git-synced chunks, injects memory protocol with PROACTIVE SAVE, SEARCH MEMORY, SUB-AGENT SCOPE, and SESSION CLOSE (TOP-LEVEL AGENT ONLY) sections. 5 Pester tests verifying protocol output content.
- post-compaction.ps1: protocol re-injection with PR Gentleman-Programming#129 scope guards - session-stop.ps1: session end REST call - subagent-stop.ps1: passive capture POST - user-prompt-submit.ps1: first-message ToolSearch + save nudge timer 10 Pester tests covering protocol output, exit codes, first-message detection, and second-message empty response.
Alan-TheGentleman
left a comment
There was a problem hiding this comment.
Review
Buen fix, pragmático y de bajo riesgo para un bug real y doloroso. El approach textual es la solución correcta dado que Claude Code no expone un mecanismo programático para distinguir sub-agentes en hooks.
Lo bueno
- No rompe funcionalidad de agentes top-level
- POSIX compatible, heredocs con comillas simples — sin riesgo de injection
- La sección en SKILL.md es la más clara y detallada de las tres
Observaciones
1. CLAUDE.md no se actualiza (MEDIUM)
El CLAUDE.md del usuario puede tener una copia del protocolo con "SESSION CLOSE PROTOCOL (mandatory)" SIN el scope de TOP-LEVEL AGENT ONLY. Un sub-agente que herede ese CLAUDE.md ve instrucciones conflictivas: SKILL.md dice "no lo hagas si sos sub-agente", CLAUDE.md dice "es mandatory". El fix está incompleto sin documentar esto — al menos una nota en el PR body o README explicando que los usuarios que tienen el protocolo copiado en su CLAUDE.md necesitan agregar el scope manualmente.
2. "You MAY call mem_save once" — el "once" es restrictivo (MEDIUM)
Un sub-agente que descubre dos cosas importantes debería poder guardar las dos. Sugerencia: cambiar "once" por "sparingly" o "only for genuinely new discoveries".
3. Ubicación de la sección SUB-AGENT en SKILL.md (LOW)
Está entre "WHEN TO SEARCH MEMORY" y "SESSION CLOSE". Consideraría moverla más arriba, inmediatamente después de "AVAILABLE TOOLS", para que sea lo primero que lea un sub-agente antes de procesar el resto del protocolo.
4. Sugerencia a futuro
Considerar una solución programática complementaria: que el orquestador pase ENGRAM_AGENT_ROLE=sub-agent como env var y que session-start.sh condicione el texto inyectado según eso. Sacaría la responsabilidad del LLM. No es necesario para este PR, pero sería el fix definitivo.
Veredicto
Se puede mergear con los ajustes de los puntos 1 y 2. No son blockers pero mejoran significativamente la robustez.
Closes #128
Summary
session-start.sh,post-compaction.sh, andmemory/SKILL.mdthat tell sub-agents to skip session lifecycle tools (mem_session_start,mem_session_end,mem_session_summary)SESSION CLOSEandAFTER COMPACTIONheaders asTOP-LEVEL AGENT ONLYso the mandatory language no longer applies to delegated tasksmem_save(once) andmem_search/mem_contextas neededChanges
plugin/claude-code/scripts/session-start.shplugin/claude-code/scripts/post-compaction.shplugin/claude-code/skills/memory/SKILL.mdTest plan
go test ./...— 596 tests pass, no regressionsbypassPermissions, trigger an Explore sub-agent, confirm it no longer loops onmem_session_summarymem_session_summaryon session closemem_savefor important discoveriesChecklist
Co-Authored-Bytrailers