Repository navigation
Closed
Labels
area:fullstackEnd-to-end Host and Client implementationEnd-to-end Host and Client implementationneeds-triageMaintainer needs to evaluate this issueMaintainer needs to evaluate this issuescope:tracerHuman-testable implementation sliceHuman-testable implementation slice
Description
Parent: #1107 · ADR-0142
What to build
The narrowest end-to-end path: an already-connected Lark app, bound from the Bot's External identities entry, delivers DMs and group @mentions to that Bot's Inbox, and the Bot replies in the original conversation. There are no delivery targets, no conversation authorization and no reception switch.
- Host, Messaging:
- The Binding's account-level registration (today the Lark pairing control registration in
inbound.tsstartControl) becomes the reception owner for default traffic. - Dispatch order: control intake → active entry → default traffic → acknowledge without admission. The durable-block step before default traffic arrives with blocks in Conversation list: mute, rules, block that sticks, allow again #1109.
- The first admitted DM or mention commits an implicit entry in
messaging_grants(origin: 'implicit', conversation kind and ID from the authenticated event, no target ref or digest) in the same transaction as the Source Event and Inbox Admission. - Validity of implicit entries checks Binding, fingerprint and the conversation itself, instead of re-inspecting a saved target.
bridge_replyworks on sources admitted this way.
- The Binding's account-level registration (today the Lark pairing control registration in
- Schema (generation 61):
- Add
messaging_bindings.new_conversations(auto|ask). Existing and new rows getauto(Vain, 2026-10-07). - Add a partial unique index allowing one active entry per Binding, conversation kind and conversation ID.
- Existing Grants get
origin: 'explicit'and keep their behavior.
- Add
- Client:
- External identities: Bind identity becomes Bind app. The platform is fixed to Lark in this slice, and the dialog lists connected Lark apps.
- After the commit, the dialog shows the registration's real readiness (connecting / ready / unavailable).
- Each app row shows a conversation count and opens a read-only list of its conversations: name or ID, DM or group, last message time.
Acceptance criteria
- With a connected Lark app and no saved targets or Grants: Bind app → DM the app → one Source Event and Inbox Admission for that Bot →
bridge_replylands in the same DM. - @mention the app in a group it belongs to → Inbox → the reply lands in the same group or topic. An unmentioned group message is not admitted.
-
/pairin a DM is still handled by pairing and is not admitted. - Existing explicit Grants keep exactly their current behavior: collection, routes, policies, revisions.
- An existing Binding migrates to
autoand admits new DMs and mentions. A Binding switched toaskadmits nothing from new conversations. - Redelivery creates no duplicate entry or admission. Restart preserves entries and keeps admitting.
- Identity pause and unbind stop admission immediately. An unbound app's entries are invalidated.
- Migration test covers generation 60 → 61 with existing bindings, grants and revoked grants, plus the snapshot and refusal of older schema writers.
- Real Lark demonstration with the packaged Provider, DM and group, with sanitized screenshots. zh/en, light/dark before/after evidence of the Bind app dialog and the conversation list.
Blocked by
None.
Metadata
Metadata
Assignees
Labels
area:fullstackEnd-to-end Host and Client implementationEnd-to-end Host and Client implementationneeds-triageMaintainer needs to evaluate this issueMaintainer needs to evaluate this issuescope:tracerHuman-testable implementation sliceHuman-testable implementation slice
Type
Projects
- StatusShow more project fieldsDone
- StatusShow more project fieldsDone
Activity
feat(messaging): a bound Lark app admits its DMs and mentions to the …
feat(messaging): a bound Lark app admits its DMs and mentions to the …