Wenn ein Subagent fertig war, kaperte er den Chat

Du bittest Hermes in Telegram, zwei subagent zum Recherchieren loszuschicken, und gehst Kaffee machen. Als du zurückkommst, ist der Bericht des subagent nie angekommen — dafür ist deine ursprüngliche Unterhaltung „beendet“, und jede Nachricht, die du im selben Fenster schreibst, wird jetzt vom subagent beantwortet, als hätte sich etwas still auf deinen Platz gesetzt.
Das ist keine Einbildung. Das Kind hat sich den Chat wirklich genommen.
Das seltsame Symptom
Ein subagent, der mit delegate_task gestartet wird und einen Hintergrundprozess startet — oder einen langen Vordergrundbefehl, der in den Hintergrund befördert wird, sobald er lange genug läuft — meldet beim Beenden eine Fertigstellung. Genau da ging es schief:
- Deine echte Unterhaltung wurde als
session_switchbeendet, einem user boundary-Ereignis; - Die Chat-Route wurde auf das eigene Ausführungs-Transcript des Kindes verschoben;
- Also wurde das Delegationsergebnis des Elternprozesses bei seinem Eintreffen als terminal verworfen — du hast den Bericht nie gesehen;
- Deine nächste Nachricht in diesem Fenster beantwortete das Kind statt deiner session.
Derselbe Bug wurde auf Discord (DMs, Threads und Channels, unter macOS und Windows), Telegram (DMs und Gruppen), Slack, Zulip und Feishu gemeldet.
Wie eine Fertigstellung den Chat übernahm
Die Kurzfassung: Das System legte die Fertigstellung unter dem falschen Eigentümer ab.
Ein Hintergrundprozess, der innerhalb eines delegate_task-Kindes gestartet wird, trägt die session id des Kindes selbst als seinen completion pin ein. Wenn er fertig ist, sieht der completion resolver des gateway einen lebenden Pin, der auf eine session zeigt, und behandelt diese session als Eigentümer des Chats. Der nächste Schritt ist switch_session: Die Chat-Route wandert auf das Ausführungs-Transcript des Kindes, und die echte Unterhaltung endet als user boundary. Ein user boundary ist terminal — an diesem Punkt gilt das noch laufende Delegationsergebnis des Elternprozesses als zu einer beendeten Unterhaltung gehörend und wird verworfen.
Anders gesagt: Der Prozesshinweis des Kindes sollte die Person erreichen, die die Arbeit delegiert hatte, und stattdessen suchte er das Kind, an das delegiert worden war. Ein falscher Verweis, und die ganze Kette kippte in die falsche Richtung.
Der Fix: eine Fertigstellung gehört der Person, nicht dem Kind
Die Regel, die der Fix etabliert, ist einfach: Eine gepinnte Fertigstellung gehört der menschlich adressierten session — der, die über model_config._delegate_from erreicht wird. Die Chat-Route wandert nie auf ein Kind.
Mechanisch:
- Das Eigentum wird einmal nachgewiesen, bevor zugestellt wird, und danach an den resolver übergeben. Der resolver liest das Eigentum nur dann neu, wenn die Route nach diesem Nachweis verschoben wurde;
- Unklares Eigentum wird erneut versucht statt geraten: vor dem admission kostet ein Retry keinen Zustellversuch; nach dem admission wandert die Fertigstellung zurück in die delivery queue;
- User boundaries bleiben auf jedem Hop terminal, ein Retry kann eine beendete Unterhaltung also nie wiederbeleben.
Auch die Prozesshinweise der Kinder wurden angepasst: Sie folgen jetzt delegation.surface_child_process_notifications (standardmäßig aus, wie die Delegations-Docs immer schon sagten) und werden in dem profile zugestellt, dem die session gehört, einschließlich der rohen api_server-session eines bereitgestellten profile. Ein process_manage-Handoff mittendrin macht den Hinweis wieder zu dem des Elternprozesses.
Warum der Fix im gateway liegt und nicht in einer Plattform
Jeder platform adapter macht genau eine Aufgabe: zwischen seinem Dienst und dem gemeinsamen Nachrichtenformat des gateway übersetzen. Welche session einen Chat besitzt, entscheidet sich danach im gemeinsamen gateway-Code — ein session store, indiziert über den routing key des Chats, ein completion resolver, ein switch_session.
Die Fertigstellung eines Kindes läuft auf jeder Plattform diesen Weg, also hat jede Plattform die Übernahme, und die Reparatur gehört in den gemeinsamen Code statt in einen einzelnen adapter. Deshalb enthält diese Änderung keinen plattformspezifischen Patch.
Was sich nicht geändert hat
- user boundary-Ereignisse bleiben terminal; ihre Semantik wurde nicht gelockert;
- Prozessbenachrichtigungen von Kindern bleiben standardmäßig unterdrückt: Das konsolidierte Ergebnis des Kindes ist das Ergebnis, der laufende Kommentar nicht. Setze
delegation.surface_child_process_notifications: true, um sie zu erhalten — mit subagent-Zuordnung; - Delegationsergebnisse selbst wurden nie unterdrückt — es geht hier darum, ob sie tatsächlich zugestellt werden können;
- Die Änderung ist ein salvage rebuild von #132827, der die Commits der ursprünglichen Beitragenden mit intakter Urheberschaft beibehält.
Status und Upgrade
Dieser Fix (PR #136225, mit Label P1) wurde am 2026-10-11 in main gemergt. Der aktuelle Tag, v0.21.6 vom 8. Oktober, enthält ihn nicht; das nächste Release wird es tun.
So prüfst du es nach dem Upgrade nach — delegiere in Discord oder Telegram einen subagent, der einen Befehl ausführt, der zu einem Hintergrundprozess wird, und beobachte, was beim Beenden passiert:
- Das Ergebnis des Kindes sollte in deiner ursprünglichen Unterhaltung landen;
- Deine nächste Nachricht sollte von deiner eigenen session beantwortet werden, nicht vom Kind;
- Mit aktiviertem
delegation.surface_child_process_notificationserscheint der Prozesshinweis in derselben Unterhaltung mit subagent-Zuordnung.
Zum Schluss
Das ist der klassische Bug nach dem Muster „sieht aus, als hätte das Modell den Verstand verloren, ist in Wahrheit ein Buchhaltungsfehler“: Der Fertigstellungshinweis adressierte den falschen Empfänger, das Eigentum am Chat wurde übergeben, und jeder weitere Turn lief schief. Mit dem Fix kann ein lang laufender Hintergrundjob die Unterhaltung, die ihn gestartet hat, nicht mehr ersetzen — eine Grenze, die in Multiplattform- und Mehrbenutzer-Deployments mit mehreren gleichzeitig laufenden subagent am wichtigsten ist.
Weiterlesen: Live-Orchestrierung von subagent behandelt das Steuern von Kindern während sie laufen, der Leitfaden zu session-Grenzen erklärt, wo eine Unterhaltung beginnt und endet, und Selbstheilung von Gateway-Plattformen ist der andere Wiederherstellungspfad, wenn eine Plattformverbindung schiefgeht.