Skip to content

connector-bluesky: reply in the thread the mention came from (finding 124) - #97

Merged
radicalkjax merged 1 commit into
mainfrom
connector-bluesky/reply-roots
Sep 7, 2026
Merged

connector-bluesky: reply in the thread the mention came from (finding 124)#97
radicalkjax merged 1 commit into
mainfrom
connector-bluesky/reply-roots

Conversation

@radicalkjax

Copy link
Copy Markdown
Member

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 warnings clean for both crates; 71 connector tests and 251 runtime tests green; cargo fmt clean.

With this the register is closed: 128 of 128 findings landed, dropped, or verified.

🤖 Generated with Claude Code

https://claude.ai/code/session_018M415coMKAv5V2xJQsaSf8

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
@radicalkjax
radicalkjax merged commit c984eec into main Sep 7, 2026
32 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant