Skip to content

fix: scope the machine-global mode flag by project so concurrent sessions stop clobbering each other (#662) - #711

Open
ousamabenyounes wants to merge 1 commit into
DietrichGebert:mainfrom
ousamabenyounes:fix/issue-662
Open

fix: scope the machine-global mode flag by project so concurrent sessions stop clobbering each other (#662)#711
ousamabenyounes wants to merge 1 commit into
DietrichGebert:mainfrom
ousamabenyounes:fix/issue-662

Conversation

@ousamabenyounes

@ousamabenyounes ousamabenyounes commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Summary

Fix #662

Live ponytail mode lives in one machine-global .ponytail-active file, so two Claude Code sessions in different repos clobber each other:

  1. Repo A configured full writes the flag; a concurrent repo B configured off then injects the ruleset into every subagent it spawns, despite being off.
  2. Starting a session in repo B calls clearMode(), deleting the flag out from under repo A's still-running session — A's subagents silently stop receiving the ruleset.

Fix — attribute the flag to its writer. setMode() records the writing project in a .ponytail-active.owner sidecar keyed by CLAUDE_PROJECT_DIR (which Claude Code sets per session). Two changes use it:

  • clearMode() refuses to delete a flag owned by a different project — fixes consequence 2.
  • The SubagentStart hook ignores the flag only when this repo defaults off and doesn't own it — fixes consequence 1.

Ownership only whitelists: an explicit /ponytail opt-in in an otherwise-off repo owns the flag and still injects, so a legitimately-active session is never suppressed. Unknown project (non-Claude hosts, which use their own per-host state dir anyway) falls back to the legacy unscoped behavior, and runtime /ponytail toggles keep driving subagents unchanged.

Test verification (RED → GREEN)

New assertions in tests/hooks.test.js cover: an off repo ignores a foreign flag, a self-owned opt-in still injects, clearMode won't delete a foreign flag, and a same-repo off session still clears its own.

RED — both hooks at unmodified main, new tests applied:

# AssertionError [ERR_ASSERTION]: an off repo must ignore another repo's active flag (#662)
#     at tests/hooks.test.js:378
# pass 0
# fail 1

GREEN — full suite with the fix:

# tests 107
# pass 106
# fail 1   (pre-existing: "csv: correct pandas one-liner" needs `pip install pandas`, which CI installs)

node scripts/check-rule-copies.js and node scripts/check-versions.js both pass.

Files changed

File Change
hooks/ponytail-runtime.js .ponytail-active.owner sidecar; owner-aware clearMode; ownedByCurrentProject
hooks/ponytail-subagent.js ignore a foreign flag when this repo defaults off and doesn't own it
tests/hooks.test.js 4 ownership scenarios for concurrent cross-repo sessions

…ions don't clobber it (DietrichGebert#662)

Live mode lives in one machine-global .ponytail-active file, so two Claude
Code sessions in different repos step on each other: one writing 'full' leaks
the ruleset into a repo configured off, and starting an off session
clearMode()s the flag out from under a still-running one.

Record which project wrote the flag in a .ponytail-active.owner sidecar keyed
by CLAUDE_PROJECT_DIR:
- clearMode() refuses to delete a flag owned by another project.
- the SubagentStart hook ignores the flag only when this repo defaults off and
  doesn't own it — ownership whitelists an explicit /ponytail opt-in, it never
  suppresses a legitimately-active session.

Unknown project (non-Claude hosts) falls back to the legacy unscoped behavior.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@ousamabenyounes ousamabenyounes changed the title fix: honor session env default over clobbered mode flag in subagent hook (#662) fix: scope the machine-global mode flag by project so concurrent sessions stop clobbering each other (#662) Aug 12, 2026
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.

Mode flag is one machine-global file — concurrent sessions in different repos overwrite each other's mode

1 participant