Skip to content

Hooks stop deleting live idle sessions - #2573

Merged
Soph merged 5 commits into
mainfrom
peyton/idle-sessions-survive-hooks
Sep 24, 2026
Merged

Soph merged 5 commits into
mainfrom
peyton/idle-sessions-survive-hooks

Conversation

@peyton-alt

@peyton-alt peyton-alt commented Sep 23, 2026 •

Copy link
Copy Markdown
Contributor

https://entire.io/gh/entireio/cli/trails/1413

Hooks stop deleting live idle sessions

Symptom. A session is re-initialised from scratch every few turns: transcript window, owner, and home reset, and a commit landing in the gap finds no session at all. In one clone a single session was re-initialised 37 times in four days.

Cause. The strategy's session listing, which every hook runs to match sessions, deletes any non-active state whose shadow branch is gone and whose checkpoint ID is empty. That is the normal shape of a healthy idle session right after a linked commit, or of a read-only session. Hooks in other worktrees list the same shared store, so any of them could delete it.

Fix. Orphan cleanup now deletes only finalized sessions (State.IsEnded: ENDED phase or EndedAt stamped) that were never condensed and carry no task records. Unfinalized IDLE states are never deleted by the listing: a live idle session stays, and a dead-owner one is left for finalizeExitedSessions, which marks it ENDED so the next listing clears it. Legacy empty-phase records normalize to IDLE, so — unlike before — they are kept until the 7-day StaleSessionThreshold expiry. entire status was already fixed to not delete on read (#2363); this covers the hooks.

Tests. Integration: another worktree's commit hook no longer deletes an idle session. Unit: the cleanup table keeps idle-with-dead-owner, idle-with-unknown-owner and legacy-empty-phase, and deletes ENDED never-condensed and IDLE-with-EndedAt states.

Follow-up. Hooks should not delete session state at all; deletion belongs to the sweeper, doctor and the 7-day expiry. That needs the orphan filter moved out of the shared listing and is tracked separately.

🤖 Generated with Claude Code


Note

Medium Risk
Changes shared hook-path session deletion logic for multi-worktree repos; incorrect owner liveness could retain stale state or still delete live sessions, but scope is narrowed and covered by new tests.

Overview
Fixes session re-initialization when git hooks in another worktree list the shared .git/entire-sessions/ store and treat a healthy IDLE session (no shadow branch yet, no LastCheckpointID) as orphaned.

listAllSessionStates now routes shadow-branch-missing cleanup through isOrphanedSessionState: IDLE states without checkpoint or task records are cleared only when OwnerExited() is true. ENDED/legacy never-condensed cleanup is unchanged; idle sessions with a live or unknown owner are kept until stale expiry.

Adds an integration test (linked worktree + parent commit hook) and expands unit tests for idle live/dead/unknown owner cases. Docs describe the new orphan rules.

Reviewed by Cursor Bugbot for commit 0f2dcb1. Configure here.

listAllSessionStates deleted every non-active state with no shadow branch,
no LastCheckpointID and no task records. That is the normal shape of a live
session between turns — a read-only turn, or the turn right after a linked
commit, when the commit removed the branch and turn-start cleared
LastCheckpointID — and the store is listed by every worktree's hooks, so a
commit in another worktree wiped the session and the next turn-start rebuilt
it from zero, losing the transcript window, the owner and the home. One
session in this clone was re-initialised 37 times in four days, and a commit
made in the gap found no session at all.

An IDLE never-condensed state is now an orphan only once its owner process is
known to have exited. ENDED and legacy states keep the old rule; states with
no recorded owner age out through the stale threshold instead.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Entire-Checkpoint: 01M2TZ1WNMFYDVGYVXYPYEA6FS
@peyton-alt
peyton-alt requested a review from a team as a code owner September 23, 2026 17:14
Copilot AI lite review requested due to automatic review settings September 23, 2026 17:14

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot review overview

🟡 Changes recommended

A critical cleanup race remains, alongside legacy-state behavior and platform-specific test issues.

Get a fresh assessment by requesting another Copilot review.

Review effort: Lite
Findings: 1 High severity · 1 Medium severity

Open (2)
What changed in this PR

Fixes hook-driven deletion of live idle sessions by making cleanup owner-aware.

Changes:

  • Adds owner-liveness checks for orphan detection.
  • Expands unit and integration coverage.
  • Documents revised cleanup behavior.
File Description
docs/​development/​checkpoint-implementation.md Documents orphan cleanup rules.
cmd/​entire/​cli/​strategy/​manual_commit_test.go Expands cleanup behavior tests.
cmd/​entire/​cli/​strategy/​manual_commit_session.go Implements owner-aware cleanup.
cmd/​entire/​cli/​integration_test/​session_state_idle_survives_test.go Adds cross-worktree regression coverage.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread cmd/entire/cli/strategy/manual_commit_session.go
Comment thread cmd/entire/cli/strategy/manual_commit_session.go Outdated
Entire-Checkpoint: 01M388GXJB5G8959MC2PN4HCBF
gtrrz-victor
gtrrz-victor previously approved these changes Sep 24, 2026
@gtrrz-victor
gtrrz-victor self-requested a review September 24, 2026 12:34
Legacy records normalize to IDLE on list and isOrphanedSessionState never
deletes IDLE, so they now remain until StaleSessionThreshold expiry.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Entire-Checkpoint: 01M39S21QM1G5K5G7EGNG5AKAZ
gtrrz-victor and others added 2 commits September 24, 2026 15:27
isOrphanedSessionState re-spelled "ended" as a phase check, so an IDLE
state with EndedAt stamped was kept for 7 days (the finalizer skips it
via IsEnded). Use the canonical predicate and drop test leftovers from
the owner-liveness version.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Entire-Checkpoint: 01M39SKJBAWGZCRTKYPYZ8ZHP2
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Entire-Checkpoint: 01M39SWN2NJNA43TF5Z9P5457V
@Soph
Soph merged commit c2087f3 into main Sep 24, 2026
18 checks passed
@Soph
Soph deleted the peyton/idle-sessions-survive-hooks branch September 24, 2026 13:45
peyton-alt added a commit that referenced this pull request Sep 25, 2026
#2573 added an identical helper to the integration package.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Entire-Checkpoint: 01M3CMXPNKPVD9XB99C1PHP9RF
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

4 participants