Skip to content

fix(channels,kernel): kill sidecar child on shutdown + forward async delegation result to channel#6267

Merged
houko merged 1 commit into
librefang:mainfrom
DaBlitzStein:fix/sidecar-zombie-shutdown
Jun 23, 2026
Merged

fix(channels,kernel): kill sidecar child on shutdown + forward async delegation result to channel#6267
houko merged 1 commit into
librefang:mainfrom
DaBlitzStein:fix/sidecar-zombie-shutdown

Conversation

@DaBlitzStein

Copy link
Copy Markdown
Contributor

Two fixes found and verified during live testing on proteo.

1. Sidecar zombie (channels: sidecar.rs)

The sidecar supervisor never killed the child process on shutdown — it just broke out of the spawn loop. This left orphaned Python processes that survived daemon restart, held the Telegram long-poll connection, and blocked the new sidecar from sending/receiving messages.

Fix: Before breaking the supervisor loop on shutdown/child-closed signals, lock the child guard and call — same pattern already used in the timeout path.

2. Async delegation result not forwarded to channel (kernel: task_registry.rs)

Async delegation callbacks arrived mid-turn via signal injection, but the delegation result was only surfaced inside the agent session. The wake-idle path already forwarded via , but the mid-turn injection path skipped this — the operator never saw the result on the channel unless the agent explicitly echoed it.

Fix: After mid-turn injection, also forward the completion text directly via to the agent's home channel. This fires immediately without waiting for the agent to process the signal.

Verification

  • Tested live on proteo with deannatroi → coder async delegation
  • Basic HTTP → Telegram delivery: works
  • Async delegation callback appears on Telegram: confirmed
  • Sidecar zombie after daemon restart: eliminated

…delegation result to channel

Two fixes found during live testing:

1. Sidecar supervisor never killed the child process on shutdown —
   it just break'd out of the spawn loop, leaving orphaned processes
   that survived daemon restart and held the Telegram long-poll
   connection, blocking the new sidecar from receiving messages.

2. Async delegation callbacks arrived mid-turn via TaskCompleted
   signal injection, but the delegation result was only surfaced
   inside the agent session — it was never forwarded to the channel.
   The wake-idle path already had this forward, but mid-turn
   injection skipped it. Now the completion text is sent directly
   via send_channel_message to the agent's home channel on every
   path (mid-turn and wake-idle).
@github-actions github-actions Bot added size/M 50-249 lines changed area/channels Messaging channel adapters area/kernel Core kernel (scheduling, RBAC, workflows) labels Jun 21, 2026
@houko
houko merged commit abbf899 into librefang:main Jun 23, 2026
33 checks passed
houko added a commit that referenced this pull request Jun 23, 2026
…channel (refs #6266) (#6286)

* fix(kernel): forward web-UI-initiated delegation results to the home channel (#6266)

PR #6267 forwards an async-delegation completion to the agent's home channel mid-turn, but only when the originating turn carries an inbound `chat_id`. A delegation started from a web-UI turn has no `chat_id` (the WS sender sets none and uses the canonical session), so the forward was skipped and the result surfaced only in the web-UI session — never on the agent's channel (the "responds in the web UI instead of forwarding to Telegram" symptom in #6266).

The mid-turn forward now resolves its destination as: the inbound `entry.chat_id` when present, else the home channel's configured `default_conversation`. A new optional `[[sidecar_channels]].default_conversation` names that fallback conversation. When neither is available the forward stays a no-op — it never guesses a recipient.

`resolve_agent_home_channel`'s contract is unchanged (the trigger-dispatch caller is unaffected); the fallback is a separate `resolve_agent_default_conversation` helper. The "session mixing" sub-claim in #6266 is left for reporter confirmation — web-UI and channel sessions are storage-distinct by construction.

* fix(changelog): split two-sentence CHANGELOG continuation onto separate lines

One sentence per line in CHANGELOG bullets per project prose rules.

Also collapses the redundant `let kernel_arc = arc;` in task_registry.rs
into the `if let Some(kernel_arc) = ...` binding directly.

* fix(kernel): default_conversation must use the home channel, not a later one

review follow-up: sidecar_default_conversation used find_map, so when an agent's first home channel (the one resolve_agent_home_channel picks) had no default_conversation it skipped ahead to a later channel's default. The forward would then pair the home channel with a different channel's conversation id and deliver to the wrong place. Switch to find().and_then() so it reads only the first agent-matching channel's default, and add a regression test.

---------

Co-authored-by: Evan <[email protected]>
Co-authored-by: Claude <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/channels Messaging channel adapters area/kernel Core kernel (scheduling, RBAC, workflows) size/M 50-249 lines changed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants