connector-bluesky: reply in the thread the mention came from (finding 124) - #97
Merged
Merged
Conversation
An AT Protocol reply record carries both a parent ref and a root ref,
and clients group a thread by its ROOT. The `mention` trigger exposed
only the mentioned post's `uri`/`cid`, so a reply rule could only name
that post as both parent and root — correct for a top-level mention,
but for a mention nested inside a conversation it filed the reply as a
new thread instead of answering in place.
Jetstream already ships the mentioned post's full record, and a post
that is itself a reply names the conversation's real root in
`record.reply.root`. So resolve the root at classification time and
carry it in the payload — no second network call, and no read path to
add to a client that today only writes records.
- `firehose::thread_root()`: pure resolver — `record.reply.root` when
present and complete, else the post itself (a top-level post is the
root of its own thread; a partial ref falls back rather than emitting
a half-formed root).
- `gateway::route_jetstream_event()` emits `root_uri`/`root_cid`.
- `mention` trigger schema declares and requires them.
- `bluesky-mention-auto-ack` recipe roots at `${trigger.root_uri}` /
`${trigger.root_cid}` instead of the mentioned post.
Tests use the connector's mock-client pattern (new
`RecordingBlueskyClient` captures what `reply` sent): a reply to a
top-level mention roots at that post; a reply to a nested mention roots
at the thread's real root, not at the mention.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018M415coMKAv5V2xJQsaSf8
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The last open finding in the register. A reply record in this protocol names both its parent and the conversation's root, and clients group a thread by its root. The mention trigger handed downstream only the mentioned post, so a rule replying to a mention could name that post as both parent and root. Reply to a nested mention and the answer started its own thread instead of landing in the conversation.
The root travels in the payload rather than being fetched. The firehose already ships the mentioned post's whole record, and a post that is itself a reply names the conversation's root inside it, so the data was in hand; resolving it in the action would have meant adding a read path to a client that has none, a new trait method, and a network round-trip per reply. A pure helper returns the record's root when it is complete, and the post itself otherwise, since a top-level post is its own root and a half-formed reference should fall back rather than be passed on.
The trigger declares and requires the two new fields, and the builtin acknowledgement recipe passes them through. Every other consumer was checked: the chat source passes the payload through opaquely, the bot bridge already took a root explicitly, and the daemon's recipe test uses a different event. The connector reference documents the fields.
Tests run a real mention commit through the router into the reply action against a recording client: a top-level mention roots at itself, a nested mention roots at the conversation's root rather than at the mentioned post.
Verification: builds and clippy
-D warningsclean for both crates; 71 connector tests and 251 runtime tests green;cargo fmtclean.With this the register is closed: 128 of 128 findings landed, dropped, or verified.
🤖 Generated with Claude Code
https://claude.ai/code/session_018M415coMKAv5V2xJQsaSf8