fix(terminal): keep the hidden clock running through transient background-measure windows (C1 review #5)

Whole-worktree background mounts (browser-automation bootstrap lease, mobile
mounts, agent wakes) open a ~3s self-clearing measure window that previously
deleted hiddenSince — every remount restarted the 30s hysteresis and the
45min retention TTL, so a periodically re-mounted force-parked worktree
never re-parked. The measure window still pauses parking/eviction verdicts
(all selectors skip measuring candidates); only the clock survives, so the
prior verdict resumes as soon as the window closes. Visible and
portal-holding worktrees still reset the clock.

Co-authored-by: Orca <help@stably.ai>
This commit is contained in:
Jinjing
2026-07-28 13:21:53 -07:00
co-authored by Orca
parent fbf80b54b3
commit 5c8f583f31
+10 -3
View File
@@ -887,10 +887,17 @@ function Terminal(): React.JSX.Element | null {
const shouldMeasureHiddenWorktree =
!isVisible && measurableBackgroundWorktreeIdsRef.current.has(worktreeId)
const hasActivityTerminalPortal = portalWorktreeIds.has(worktreeId)
if (isVisible || shouldMeasureHiddenWorktree || hasActivityTerminalPortal) {
if (isVisible || hasActivityTerminalPortal) {
terminalWorktreeHiddenSinceRef.current.delete(worktreeId)
} else if (!terminalWorktreeHiddenSinceRef.current.has(worktreeId)) {
terminalWorktreeHiddenSinceRef.current.set(worktreeId, nowMs)
} else if (!shouldMeasureHiddenWorktree) {
// Why measuring is excluded here but still pauses the verdicts below:
// the ~3s background-measure window (automation lease, mobile mount,
// agent wake) is transient — resetting hiddenSince would restart the
// 30s hysteresis AND the 45min retention TTL on every remount, so a
// periodically re-mounted force-parked worktree would never re-park.
if (!terminalWorktreeHiddenSinceRef.current.has(worktreeId)) {
terminalWorktreeHiddenSinceRef.current.set(worktreeId, nowMs)
}
}
retentionCandidates.push({