You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
AgentBuilderTool.cs:274 calls ResolveDeliveryTarget(conversationId, agentId) at agent creation time and freezes the resulting (receive_id, receive_id_type) primary+fallback pair into SkillRunnerOutboundConfig.LarkReceiveId{*,Fallback} (proto fields 22-25 of UserAgentCatalogEntry, 14-17 of SkillRunnerOutboundConfig).
Binding-failed becomes an observable failure surfaced to the user ("Bot is no longer in this chat — run /rebind to choose another."), not a silently-failing agent.
Plays well with #refactor-split-skill-runner: DailyReportRunGAgent queries LarkDeliveryResolver once per run; DailyReportSubscriptionGAgent doesn't carry physical address.
Acceptance
No lark_receive_id field on subscription state or readmodel.
Send time resolves current target every run; cross-app and chat-renamed scenarios work without recreating the agent.
When binding is gone, the user gets a structured "please /rebind" message; subscription is paused (not thrashing).
Test: rename the chat between two scheduled runs; second run still delivers.
Test: outbound bot removed from chat; subscription pauses with actionable error.
Symptom
AgentBuilderTool.cs:274callsResolveDeliveryTarget(conversationId, agentId)at agent creation time and freezes the resulting(receive_id, receive_id_type)primary+fallback pair intoSkillRunnerOutboundConfig.LarkReceiveId{*,Fallback}(proto fields 22-25 ofUserAgentCatalogEntry, 14-17 ofSkillRunnerOutboundConfig).Implementation: AgentBuilderTool.cs:1881.
Once frozen, any of the following permanently breaks delivery:
chat_idis unknown to the outbound app)The current escape hatch is
/delete-agent+ recreate, which is the architecture problem outsourced to the user.Architectural violations
The "local accident" here is "the chat topology at creation time = the chat topology at every future execution".
Proposed direction
OutboundConfig(per-subscription) holds only a logical reference:(platform, conversation_canonical_key, owner_lark_user_id).LarkDeliveryResolver(per-platform adapter) resolves the current physicalreceive_idat send time, querying current binding state (e.g. viaLarkUserGAgentfrom bug(daily): GitHub username binding shared across all Lark users of one bot — last writer wins #436's channel-user-binding direction).DailyReportRunGAgentqueriesLarkDeliveryResolveronce per run;DailyReportSubscriptionGAgentdoesn't carry physical address.Acceptance
lark_receive_idfield on subscription state or readmodel.Dependencies
/dailybinding causes cross-user data leakage #437 landsLarkUserGAgent-style channel-user identity. Can ship before, but resolver will need its own narrow binding store.Related