Context
Follow-up from the #217 review (note 2, non-blocking). The silent-drop safety net keeps per-agent turn state in two single-slot maps — currentTurnReplied and lastPromptOrigin (routing) in core.ts.
Problem
In the real deployment, one default agent serves multiple origins concurrently — telegram, webui-inject, cron/heartbeat. The single slot is last-write-wins per agent, so two prompts interleaving on the same agent race:
- A telegram prompt arriving mid-webui-turn resets the slot (and
lastPromptOrigin), then the in-flight turn's turn_end synthesizes a reply routed to the wrong origin — the user can get unsolicited / misrouted ambient text.
The CHANNEL_DRIVEN_ORIGINS gate added in #217 (5f9e956) removes the cron/heartbeat false-positives but does not close the channel-vs-channel race (e.g. telegram during webui-inject). The webui-bridge mutex only serialises the webui path.
Direction (not prescriptive)
Either serialize prompt→turn_end per agent across all channel-driven origins, or key the turn state by origin_id instead of a single per-agent slot so concurrent turns don't clobber each other's delivery/routing state.
Refs #217.
Context
Follow-up from the #217 review (note 2, non-blocking). The silent-drop safety net keeps per-agent turn state in two single-slot maps —
currentTurnRepliedandlastPromptOrigin(routing) incore.ts.Problem
In the real deployment, one
defaultagent serves multiple origins concurrently — telegram, webui-inject, cron/heartbeat. The single slot is last-write-wins per agent, so two prompts interleaving on the same agent race:lastPromptOrigin), then the in-flight turn'sturn_endsynthesizes a reply routed to the wrong origin — the user can get unsolicited / misrouted ambient text.The
CHANNEL_DRIVEN_ORIGINSgate added in #217 (5f9e956) removes the cron/heartbeat false-positives but does not close the channel-vs-channel race (e.g. telegram during webui-inject). The webui-bridge mutex only serialises the webui path.Direction (not prescriptive)
Either serialize prompt→turn_end per agent across all channel-driven origins, or key the turn state by
origin_idinstead of a single per-agent slot so concurrent turns don't clobber each other's delivery/routing state.Refs #217.