Skip to content

fix(remote): verdeckten Besitzer eines Daemon-PTYs nicht mehr als Sackgasse behandeln - #534

Merged
iret77 merged 1 commit into
mainfrom
fix/daemon-claim-hidden-owner
Oct 8, 2026
Merged

iret77 merged 1 commit into
mainfrom
fix/daemon-claim-hidden-owner

Conversation

@iret77

@iret77 iret77 commented Oct 8, 2026 •

Copy link
Copy Markdown
Collaborator

Problem

Vorfall am 2026-10-08: Eine laufende Daemon-Session auf devhost mit einer aktiven Claude-Instanz war für den Nutzer nicht mehr erreichbar. „In neuem Tab öffnen“ in der Sidebar löste beim Daemon kein Attach aus. Stattdessen kam mehrfach der Toast

Dieses Remote-PTY ist bereits geöffnet, aber der vorhandene Tab konnte nicht fokussiert werden.

Der einzige Ausweg war ein App-Neustart bzw. das Fortsetzen der Konversation in einer neuen Session.

Bestätigte Ursache (Undo-Close-Frist):

  • remove_tab legt die Pane-Group eines geschlossenen Tabs in den UndoCloseStack. Die Panes werden nur HiddenForClose gelöst.
  • Claim und Verbindung werden erst bei DetachType::Closed freigegeben (terminal_pane.rs, daemon_tty/terminal_manager.rs).
  • focus_daemon_claim_owner durchsucht nur workspace.tabs und landet 60 s lang im Toast. Das passt zum Daemon-Log: Die Verbindungen der geschlossenen Tabs lebten genau bis zum Ende der Frist.
  • Geschlossene Fenster verhalten sich genauso, weil on_window_closed den Workspace aus der Registry nimmt.

Nicht rekonstruiert: In der ersten Runde zeigte der einzige sichtbare Pane der Session „Wiederherstellung der Remote-Sitzung abgebrochen“, während eine Verbindung unsichtbar am PTY hing und sich nach Abbruch sofort neu anhängte (replay 0 bytes). Im Cancel- und Replace-Pfad wurde kein Leck gefunden. Der Rückfallweg unten deckt diesen Fall ab, aber nur, wenn der Nutzer über die Sidebar oder „Erneut versuchen“ handelt.

Änderung

  • UndoCloseStack: Kann einen geschlossenen Tab finden und herausnehmen, der eine bestimmte Terminal-View hält (has_…/take_closed_tab_with_terminal_view).
  • focus_daemon_claim_owner: Öffnet einen solchen Tab wieder (restore_closed_tab) und fokussiert ihn, statt den Toast zu zeigen.
  • Unerreichbarer Besitzer: Gemeint ist ein Besitzer, den weder ein offener Tab noch ein wiederherstellbarer Tab noch ein registrierter Workspace hält. Für ihn gilt:
    • Sidebar-Pfad und „Erneut versuchen“ geben seinen Claim frei und trennen nur seine Verbindung (deregister_session(conn, false)). Das PTY auf dem Daemon läuft weiter.
    • Danach wird neu geöffnet.
    • „Erneut versuchen“ degradiert den Pane in diesem Fall nicht mehr.
  • Vorsichtig bei der Erreichbarkeit:
    • PaneGroup::holds_terminal_view prüft alle Einträge des Pane-Stacks, auch verdeckte Views und Panes, die zum Rückgängigmachen zurückgehalten werden.
    • Ein Workspace, der gerade aktualisiert wird, zählt als erreichbar.
    • Eine ungebundene Reservierung (Oberfläche öffnet noch) zählt ebenfalls als erreichbar.

Bewusst so entschieden:

  • Ein Fenster in der Undo-Frist wird zurückgezogen, nicht wiederhergestellt.
  • Diese Pfade zeigen weiterhin den Toast: Startup claimed_elsewhere, index_opened_daemon_session und das Adopt-Reservierungsrennen.

Tests

workspace/view_test.rs:

  • reopening_a_pty_owned_by_an_undo_closed_tab_restores_that_tab
  • sidebar_open_retires_a_pty_owner_no_tab_can_show
  • retry_claim_takes_over_only_from_an_unreachable_owner: Ein erreichbarer Besitzer ergibt Existing, ein verwaister Claimed.

Die Nebenwirkung deregister_session wird nicht geprüft. Die Testverbindung ist beim Manager nicht registriert.

Verifikation

  • rustfmt --check ist für die geänderten Hunks sauber. Die einzige Abweichung in view.rs besteht schon auf main.
  • git diff --check und script/check-v1-release-readiness --phase-a sind sauber.
  • Nicht kompiliert, das ist nach Projektregel lokal nicht erlaubt. Der PR-Check muss das bestätigen, besonders an diesen Stellen:
    • der &mut self-Aufruf im Match-Guard von claim_daemon_pty_retiring_unreachable_owner,
    • das Binding closed_item @ (ClosedItem::Window(_) | ClosedItem::Pane { .. }) in stack.rs,
    • die Coercion &mut ViewContext → &AppContext in daemon_claim_owner_is_reachable.
  • Die Tests laufen im nächsten freigegebenen ci-batch.
  • Kein VERSION-/CHANGELOG-Bump, wie bei fix(remote): Session nach Verbindungsabbruch automatisch wieder anhängen #518–fix(cockpit): Aufmerksamkeits-Zähler zählt Rückfragen und ungesehene Antworten #525.

Bezug

Behebt den Kern von #519, schließt das Issue aber nicht vollständig.

Erfüllt:

  • Liegt der Besitzer in einem per Undo geschlossenen Tab, wird genau dieser Tab wiederhergestellt und fokussiert.
  • Bei HiddenForClose werden Claims weiterhin nicht freigegeben, es entstehen keine doppelten Tabs.
  • Hält ein unerreichbarer Besitzer die Session, endet der Klick nicht mehr ohne Tab. Der Besitzer wird zurückgezogen, danach läuft die Übernahme neu.

Offen:

  • focus_existing_adopted_daemon_session gibt für erreichbare Besitzer weiter true zurück, auch wenn das Fokussieren scheitert.
  • Mehrere Fenster: Ein Fenster in der Undo-Frist wird zurückgezogen statt wiederhergestellt.
  • Der Ablauf der Undo-Frist ist nicht eigens getestet (undo_grace_expiry_releases_daemon_claim).

Weitere Bezüge: Die Anzeige „Wiederherstellung abgebrochen“ desselben Vorfalls betrifft #470 und #456. Das falsche Absturz-Banner behebt #532.

…kgasse behandeln

"In neuem Tab öffnen" in der Sidebar endete im Toast
workspace-remote-pty-already-open, sobald der Claim des PTYs von einer
Oberfläche gehalten wurde, die kein offener Tab zeigt:

- Ein geschlossener Tab bleibt während der Undo-Close-Frist (60 s) im
  UndoCloseStack; seine Panes werden nur HiddenForClose gelöst, Claim und
  Verbindung bleiben bestehen. focus_daemon_claim_owner durchsucht nur
  workspace.tabs und fand ihn nie.
- Eine Oberfläche, die lebt, aber in keinem Tab mehr steckt (geschlossenes
  Fenster in der Undo-Frist, verwaiste Oberfläche), hielt den Claim dauerhaft.

Jetzt öffnet focus_daemon_claim_owner einen solchen geschlossenen Tab wieder
und fokussiert ihn. Ist der Besitzer von keinem Tab erreichbar, geben der
Sidebar-Pfad (focus_existing_adopted_daemon_session) und "Erneut versuchen"
(retry_remote_restore) seinen Claim frei und trennen nur seine Verbindung –
das PTY auf dem Daemon läuft weiter – und öffnen das PTY dann neu, statt den
Pane zu degradieren bzw. den Toast zu zeigen.
@iret77
iret77 merged commit 408a878 into main Oct 8, 2026
1 check passed
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