Skip to content

fix(plugin): prevent sub-agent infinite loop on session lifecycle calls#129

Open
jzambrano12 wants to merge 1 commit intoGentleman-Programming:mainfrom
jzambrano12:fix/subagent-session-loop
Open

fix(plugin): prevent sub-agent infinite loop on session lifecycle calls#129
jzambrano12 wants to merge 1 commit intoGentleman-Programming:mainfrom
jzambrano12:fix/subagent-session-loop

Conversation

@jzambrano12
Copy link
Copy Markdown

Closes #128

Summary

  • Add "SUB-AGENT SCOPE" sections to session-start.sh, post-compaction.sh, and memory/SKILL.md that 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
  • Sub-agents may still call mem_save (once) and mem_search/mem_context as needed

Changes

File Change
plugin/claude-code/scripts/session-start.sh Added SUB-AGENT SCOPE section, scoped SESSION CLOSE as TOP-LEVEL AGENT ONLY
plugin/claude-code/scripts/post-compaction.sh Added SUB-AGENT SCOPE section, scoped SESSION CLOSE and POST-COMPACTION as TOP-LEVEL AGENT ONLY
plugin/claude-code/skills/memory/SKILL.md Added SUB-AGENT / DELEGATED TASK SCOPE section, scoped SESSION CLOSE PROTOCOL and AFTER COMPACTION as TOP-LEVEL AGENT ONLY

Test plan

  • go test ./... — 596 tests pass, no regressions
  • Manual: start a Claude Code session with bypassPermissions, trigger an Explore sub-agent, confirm it no longer loops on mem_session_summary
  • Manual: verify top-level agent still calls mem_session_summary on session close
  • Manual: verify sub-agents can still call mem_save for important discoveries

Checklist

  • Commit messages follow conventional commit format
  • No Co-Authored-By trailers
  • Changes are limited to protocol text — no Go code or infrastructure changes

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
MattKotsenas added a commit to MattKotsenas/engram that referenced this pull request Mar 27, 2026
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.
MattKotsenas added a commit to MattKotsenas/engram that referenced this pull request Mar 27, 2026
- 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.
Copy link
Copy Markdown
Collaborator

@Alan-TheGentleman Alan-TheGentleman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Sub-agents enter infinite loop of session lifecycle calls (mem_session_summary)

2 participants