Skip to content

fix: recover failed worktree close teardown - #167

Merged
matej21 merged 11 commits into
refactorx/full-headlessfrom
fix/worktree-close-recovery
Jul 24, 2026
Merged

fix: recover failed worktree close teardown#167
matej21 merged 11 commits into
refactorx/full-headlessfrom
fix/worktree-close-recovery

Conversation

@neumie

@neumie neumie commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Stacked on #157 (refactorx/full-headless).

Summary

  • recover vanished before_worktree_remove hook terminals without timing out live hooks or leaving projects permanently stuck in closing state
  • fail closed when PTY or persistent-session teardown cannot be verified, preserving the checkout for retry
  • reconcile partial worktree removal, stale dtach/profile state, and replacement paths without deleting foreign data

Changes

Worktree close lifecycle

  • add a daemon watchdog that uses PTY generation/liveness rather than elapsed duration
  • atomically claim pending closes across OSC, PTY exit, and watchdog recovery for exactly-once resolution
  • clear closing state, fail the monitor, notify the user, and preserve the worktree when a hook terminal disappears
  • handle benign partial-removal residue while refusing to prune registrations if the original path was replaced

Terminal and session teardown

  • move potentially stuck PTY readers/children into bounded background reaping
  • add timeout-aware teardown flushing before destructive worktree operations
  • verify tmux, screen, psmux, and dtach session exits; retain retry handles when process state is indeterminate
  • reconcile orphaned profile-scoped sessions and account for Linux zombie processes

Runtime support

  • give headless/UI-owned mode a separate log file
  • replace per-pane terminal polling with activity events
  • add regression coverage for aliases, partial removal, OSC/exit races, session termination, profile sockets, and reaper uncertainty

Test plan

  • cargo fmt --all -- --check
  • cargo test -p okena-terminal -p okena-daemon-core -p okena-git -p okena-core -p okena-workspace
  • cargo test --bin okena log_rotation_tests
  • cargo clippy --workspace --all-targets -- -D warnings
  • Rust Analyzer diagnostics on the incident-critical files — no diagnostics
  • post-rebase diff-preservation audit against origin/refactorx/full-headless
  • independent read-only review — no blocking or major findings
  • GitHub Build workflow

neumie added 11 commits July 24, 2026 12:57
The single-binary daemon (`okena --headless [--ui-owned]`) reuses the same
src/main.rs logging init as the GUI, so both processes rotated and wrote the
same okena.log, clobbering each other's history. The standalone okena-daemon.log
tee only exists in the separate okena-daemon binary, so ui-owned mode produced
no daemon log at all. Pick the log filename before the rotate/create block: when
headless (or Linux --listen/--remote with no display), write okena-headless.log
with its own .1 rotation, leaving the GUI's okena.log legible.
Reconcile dtach sessions against authoritative post-lock workspace state, isolate named-profile sockets, and tear down verified descendant trees before removing their masters.
Route remote terminal activity through the existing doorbell and app-wide pane registry instead of per-pane 8 ms timers.
Preserve birth-marker validation while allowing a stopped dtach master to reap killed children after teardown verification.
@neumie
neumie requested a review from matej21 July 24, 2026 14:27
@matej21
matej21 merged commit a45b7be into refactorx/full-headless Jul 24, 2026
4 checks passed
@matej21
matej21 deleted the fix/worktree-close-recovery branch July 24, 2026 15:33
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