Skip to content

fix(team-mode): remove members from state.json on idle auto-cleanup - #371

Open
Million-mo wants to merge 2 commits into
mainfrom
fix/team-idle-cleanup-state-json-leak
Open

fix(team-mode): remove members from state.json on idle auto-cleanup#371
Million-mo wants to merge 2 commits into
mainfrom
fix/team-idle-cleanup-state-json-leak

Conversation

@Million-mo

Copy link
Copy Markdown
Collaborator

Problem

In team mode, when the lead goes idle for longer than idle_timeout (default 300s), the idle auto-cleanup (_schedule_member_cleanup) closes member sessions but does not remove them from state.json's members dict. Since team_add_member counts members from state.json to enforce max_members, the freed sessions still occupy capacity slots and subsequent team_add_member calls are incorrectly rejected with "Team exceeds max_members".

This means: after the lead returns from idle and tries to add new members, the old members' slots are still counted even though their sessions are gone.

Root Cause

_schedule_member_cleanup (team_comm_capability.py) closed sessions and cleared team_member_sessions metadata, but never touched state.json. Compare with _schedule_ephemeral_cleanup, which correctly pops members from state.json before closing — that path works fine.

Fix

  1. _schedule_member_cleanup now accepts team_id and base_dir parameters.
  2. After closing member sessions, calls new _remove_members_from_state helper that reads state.json, pops members whose session_id is in the closed set, and atomically writes back — mirroring the _schedule_ephemeral_cleanup pattern.
  3. team_create passes team_id and base_dir to the cleanup scheduler.

Test

New regression test test_idle_cleanup_frees_state_json_slots_for_add_member:

  • Creates a team at max_members=2 (full capacity)
  • Verifies team_add_member fails before cleanup (expected)
  • Triggers idle auto-cleanup (short timeouts)
  • Asserts members are removed from state.json
  • Asserts team_add_member succeeds after cleanup (slot freed)

All 333 existing team-mode tests + 124 delegation tests pass.

Files Changed

  • src/wolfharness/capabilities/team_comm_capability.py — fix + new helper
  • tests/team_mode/test_integration_session.py — regression test
  • changelog/unreleased/2026-08-14-team-idle-cleanup-state-json.md — changelog

The idle auto-cleanup (_schedule_member_cleanup) closed member sessions
but left them in state.json's members dict. Since team_add_member counts
members from state.json to enforce max_members, the freed sessions still
occupied capacity slots and subsequent team_add_member calls were
incorrectly rejected with 'Team exceeds max_members'.

Add _remove_members_from_state helper that pops members whose session
IDs match the closed set, mirroring the existing _schedule_ephemeral_cleanup
pattern. Pass team_id and base_dir from team_create to the cleanup scheduler.

Includes regression test that creates a team at max_members capacity,
triggers idle cleanup, and verifies team_add_member succeeds afterward.
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