Skip to content

fix(ralph-loop): lazy-claim session_id for cross-session isolation#981

Open
carpenstreet-leo wants to merge 1 commit intoanthropics:mainfrom
carpenstreet-leo:fix/ralph-loop-session-isolation
Open

fix(ralph-loop): lazy-claim session_id for cross-session isolation#981
carpenstreet-leo wants to merge 1 commit intoanthropics:mainfrom
carpenstreet-leo:fix/ralph-loop-session-isolation

Conversation

@carpenstreet-leo
Copy link
Copy Markdown

Summary

  • CLAUDE_CODE_SESSION_ID env var is not available to plugin setup scripts, so ralph-loop state files are created with an empty session_id
  • This causes the stop hook to fire in all sessions within the same project, not just the one that started the loop
  • The stop hook already receives session_id via stdin JSON — this change adds a "lazy claim" on first invocation to bind the loop to the correct session

Root Cause

setup-ralph-loop.sh writes session_id: ${CLAUDE_CODE_SESSION_ID:-} but the env var is never set, resulting in session_id: (empty). The existing guard (-n "$STATE_SESSION") then fails, allowing every session's stop hook to match.

Fix

On first stop hook invocation, if the state file has no session_id but the hook input JSON does, write it into the state file ("lazy claim"). Subsequent invocations from other sessions see a mismatch and pass through (exit 0).

Test plan

  • Verified CLAUDE_CODE_SESSION_ID is not set in plugin script env
  • Verified stop hook stdin JSON contains valid session_id (UUID)
  • Tested lazy claim writes session_id into state file on first invocation
  • Other sessions in the same project no longer get blocked by the stop hook

🤖 Generated with Claude Code

CLAUDE_CODE_SESSION_ID env var is not available to plugin setup scripts,
so ralph-loop state files are created with an empty session_id. This
causes the stop hook to fire in ALL sessions within the same project,
not just the one that started the loop.

The stop hook already receives session_id via stdin JSON. This change
adds a "lazy claim" — on first stop hook invocation, if the state file
has no session_id, the hook writes the current session's ID into the
state file. Subsequent invocations from other sessions see a mismatch
and pass through.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
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.

1 participant