Skip to content

fix: bound automatic terminal recovery - #609

Merged
Jephuff merged 13 commits into
mainfrom
bound-terminal-recovery
Aug 11, 2026
Merged

fix: bound automatic terminal recovery#609
Jephuff merged 13 commits into
mainfrom
bound-terminal-recovery

Conversation

@Jephuff

@Jephuff Jephuff commented Aug 10, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • return typed tmux preparation results and require positive, machine-readable window absence before recreation
  • keep a two-attempt automatic recovery budget in AppState so SwiftUI reconstruction and unordered snapshots cannot reopen it
  • preserve recreation dedup across deletion races and suppress stale responses only after authoritative removal
  • verify grouped attachment before resetting recovery, while keeping manual Retry available for failed or exhausted recovery
  • render stable, failure-specific guidance and log terminal plus worktree recovery context

Root cause

Every tmux preparation failure was previously treated as a missing window. The coordinator then recreated the window, but its retry counter lived on the coordinator and reset whenever SwiftUI rebuilt the view, allowing an unbounded recreation storm. Follow-up review also identified that process spawn, unordered terminal snapshots, and deletion races were insufficient evidence for resetting or discarding persistent recovery state.

Design record

docs/specs/2026-08-11-bounded-terminal-recovery-design.md records the approved recovery design: evidence thresholds, UUID-scoped budget lifetime, attachment-positive reset, authoritative deletion versus observational snapshots, bounded tombstone TTL, diagnostics, and rejected alternatives.

Verification

  • focused bridge, budget, AppState, panel, archive, pre-session, and daemon deadline suites — 110 tests passed
  • scripts/swift-safe build
  • swiftlint --strict — zero violations across 687 files
  • full fenced suite — 5,454 tests run; recovery coverage passed, with nine unrelated host-specific rendering and transcript-estimator issues including one known issue
  • independent final diff audit — no actionable findings
  • scope audit found no new timers, raw sleeps, screen scraping, flags, migrations, RPCs, or PATH-policy changes

Dependencies

  • Based directly on main; this PR is independently mergeable.
  • The branch preserves the existing /usr/bin/env tmux and viewer executable-resolution contract.

@Jephuff
Jephuff marked this pull request as ready for review August 10, 2026 23:49
@tbd-claude-reviewer

This comment has been minimized.

@tbd-claude-reviewer

This comment has been minimized.

@Jephuff
Jephuff force-pushed the preserve-launch-path branch from 6e93e9d to d3af207 Compare August 11, 2026 03:06
@Jephuff
Jephuff force-pushed the bound-terminal-recovery branch from 07d6f99 to 31099c8 Compare August 11, 2026 03:20
@Jephuff
Jephuff changed the base branch from preserve-launch-path to main August 11, 2026 03:20
@cheapsteak

Copy link
Copy Markdown
Owner

#612 has a fix for the reviewer stuff, might need a rebase

@tbd-claude-reviewer

This comment has been minimized.

@tbd-claude-reviewer

This comment has been minimized.

@tbd-claude-reviewer

This comment has been minimized.

@tbd-claude-reviewer

This comment has been minimized.

@tbd-claude-reviewer

Copy link
Copy Markdown

✅ Looks good

Reviewed the tmux terminal-recovery rework (typed preparation outcomes, UUID-scoped recovery budget, deletion tombstones) against its own design spec (docs/specs/2026-08-11-bounded-terminal-recovery-design.md) and against repo conventions. No HIGH or MEDIUM findings survived merge.

A guard/safety-shaped premise audit confirmed the load-bearing claims hold: the 2-attempt budget can't be bypassed, the tmux-absence classifier fails closed on ambiguous probes, in-flight/deletion bookkeeping is paired up correctly on every branch (including via defer), the racing-response tests genuinely exercise the races they claim to, and the scope claims in the PR description (no new timers, RPCs, migrations, flags, or screen-scraping) check out. Convention checks (default-off flag, TUI screen-scraping, DB migration triple-update, spec presence, theory placement for the tuned constants) all passed — this narrows an already-existing automatic-recreation behavior rather than introducing a new one, and the new constants carry human-legible rationale in the spec.

0 findings were filtered out as invalid/persnickety during merge — the single minor item below is the only one either specialist raised.

Minor items
  • Sources/TBDApp/Terminal/TerminalPanelView.swift:697startTmuxClient re-checks isTornDown after the first await (prepareSession), matching its own documented double-check discipline, but not after the second await onMissingWindow() before feeding recovery guidance text into the terminal view. Low impact: authoritative budget/dedup state mutates unconditionally and correctly regardless; a torn-down view could still receive a stale UI write.
Finding dispositions
  • correctness-1 — kept (minor, low confidence; UI-only staleness, not state corruption)
Review diagnostics

No tool calls failed or were denied for either specialist. One environment note for workflow tuning: this checkout is a shallow clone with no common ancestor between origin/main and HEAD, so git diff origin/main...HEAD fails with "no merge base." Both the orchestrator and both specialists worked around this by using gh pr diff 609 --repo cheapsteak/tbd instead, which worked fine. Consider updating the standing instructions to recommend gh pr diff first in shallow-clone setups rather than as a fallback.

Posted by the claude-review check — the review of this PR's diff at patch-id 23b8811e8a3f8cbe3092ba2d94a53332632b79e9. A newer review comment supersedes this one.

@Jephuff
Jephuff merged commit 02a1a90 into main Aug 11, 2026
5 of 6 checks passed
@Jephuff
Jephuff deleted the bound-terminal-recovery branch August 11, 2026 18:37
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