Skip to content

Make the sandbox name pattern per-supervisor, not a mutable global - #288

Merged
seanwevans merged 1 commit into
mainfrom
claude/supervisor-name-pattern
Aug 15, 2026
Merged

Make the sandbox name pattern per-supervisor, not a mutable global#288
seanwevans merged 1 commit into
mainfrom
claude/supervisor-name-pattern

Conversation

@seanwevans

Copy link
Copy Markdown
Owner

The problem

Supervisor.spawn declared global NAME_PATTERN, read it, and reset it to DEFAULT_NAME_PATTERN on every successful spawn:

def spawn(self, name, ...):
    global NAME_PATTERN
    ...
    pattern = NAME_PATTERN
    ...
    NAME_PATTERN = DEFAULT_NAME_PATTERN   # at the end of every spawn

Two problems:

  1. A caller who installed a custom pattern silently lost it after one sandbox, and two threads spawning concurrently raced over the value — one thread's reset could reject the other thread's legitimate name.
  2. The reset existed only to serve a test. tests/test_metrics.py rebound the module global and never restored it, relying on spawn to clean up. Production code was carrying a test affordance.

The change

Supervisor(name_pattern=...) — the rule belongs to the instance that enforces it, exposed as a .name_pattern property. When not given, the supervisor falls back to the module-level NAME_PATTERN at spawn time, so the documented global override still works for the process-wide supervisor. spawn no longer writes to it.

Restoration moves to where it belongs: the metrics test uses monkeypatch.setattr, which undoes itself.

Tests

Three new in tests/test_supervisor.py: a custom pattern is honored and rejects non-matching names; two supervisors keep independent patterns; and the regression itself — a custom global survives a spawn and is still honored on the next one.

Full suite 508 passed / 6 skipped (was 505). flake8 clean.

Note

I let black touch only the files this change edits. A newer black than the repo's pinned 23.9.1 wanted to reformat nogil.py, test_ebpf_contract.py, and test_thread_extra.py — unrelated, so I reverted those.


Generated by Claude Code

Supervisor.spawn declared `global NAME_PATTERN`, read it, and reset it to
DEFAULT_NAME_PATTERN on every successful spawn. Two problems:

* A caller that installed a custom pattern silently lost it after one
  sandbox, and two threads spawning concurrently raced over the value --
  one thread's reset could reject the other's legitimate name.
* The reset existed only so tests/test_metrics.py could rebind the global
  without restoring it. Production code was carrying a test affordance.

Add a name_pattern argument to Supervisor so the rule belongs to the
instance that enforces it, exposed as a .name_pattern property. When it is
not given the supervisor falls back to the module-level NAME_PATTERN at
spawn time, so the documented global override still works for the
process-wide supervisor -- but spawn no longer writes to it.

Restoration moves to where it belongs: the metrics test uses
monkeypatch.setattr, which undoes itself.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012ebvMQ3vLxdK3joymz6Feg
@seanwevans
seanwevans merged commit 0b32d39 into main Aug 15, 2026
18 checks passed
@seanwevans
seanwevans deleted the claude/supervisor-name-pattern branch August 15, 2026 21:00
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.

2 participants