Test an Agent's Reply Queue on One Thread Before It Answers Anyone
Four checks for the address a reply carries, the unit a queue dedupes on, the parent it re-reads, and the conditions that stop it

*Image: Social media apps by Theresepersonne, licensed under CC BY-SA 4.0.*
A reply is addressed to another post, and the address travels in the payload. Bluesky's post guide states that a reply post references both the immediate parent post and the original root post of the thread (Bluesky posts guide, captured 26 October 2026). Mastodon's create-status call takes one in_reply_to_id, described as the "ID of the status being replied to, if status is a reply" (Mastodon statuses API, captured 26 October 2026).
X's create-post request takes a reply object whose required field is in_reply_to_tweet_id, "The ID of the tweet being replied to" (X API create post, captured 26 October 2026). Two of those three surfaces ask the client for one pointer, and the third asks for two. All of them reference another record, and the surfaces differ in how much of the thread the queue has to hold itself.
A status can be deleted, and Mastodon documents DELETE /api/v1/statuses/:id for removing one. It can be edited, and the Status entity carries edited_at, the "timestamp of when the status was last edited," added in version 3.5.0 (Mastodon Status entity, captured 26 October 2026). A reply draft can wait in an approval queue while the post it answers changes underneath it.
A wrong reply is also public, addressed at a person, and attached to the account rather than to the tool that drafted it. A queue that stores enough to notice the change catches the failure before the send button appears.
The address the queue writes down
Bluesky asks for both ends of the thread, and each reference is a strong reference (Bluesky posts guide, captured 26 October 2026). AT Protocol defines that type as "A URI with a content-hash fingerprint," with required uri and cid fields (strongRef lexicon, captured 26 October 2026). The payload on that surface names the thread as well as the message.
Mastodon and X carry one pointer. Neither payload names the thread root, so a tool that wants a thread key has to store the root itself at discovery time. Mastodon's context endpoint shows the tree from the server side, returning the statuses "above and below this status in the thread," limited to 40 ancestors and 60 descendants at a maximum depth of 20 for unauthenticated requests (Mastodon statuses API, captured 26 October 2026).
The unit the queue dedupes on
Duplicates start at discovery, where a lane that finds conversations will surface several posts from one thread, sometimes from different people in it, sometimes from the same person twice. SMM Agent's home page describes reply operations as finding conversations, drafting responses, scoring risk, and keeping the human approval step visible (SMM Agent, captured 26 October 2026). Each draft produced that way is individually reasonable. Sent together, they read as a bot working a thread. A queue that stores only a parent id counts messages. A queue that stores the root counts conversations, which is what a person sees when they open a thread and find three replies from the same brand.
Ask what field the queue compares before you trust the dedupe setting. A parent-id key lets a thread collect one reply per parent. An author key silences a second, unrelated question from a regular. A key of account, thread root, author and a rolling window of a day or so covers both cases. Write the key into the runbook, so a later change to it shows up in review.
The parent check at send time
An approval that arrives an hour later needs a fresh read of the parent. Mastodon exposes GET /api/v1/statuses/:id for a single status and the context endpoint for the thread, which together answer whether the parent still exists, whether it changed, and whether someone else already answered. The edited_at field gives a change a timestamp to compare against the one the queue stored at draft time.
A Bluesky strong reference carries the same check in its shape. The cid is a content hash, so the reference names one version of the parent record. Compare the stored reference with the current record before sending. When the hashes differ, the post the agent read is not the post that is there now.
The rule at send time is to compare the stored reference with the current record and to send only when they match. When the reference is missing or changed, the queue holds the draft and puts it back in review. A reply into a thread whose premise changed produces an answer to a question that was already retracted, and that answer stays public with the account's name on it.
Visibility belongs in the same check. A Mastodon status carries its own visibility value, set to public, unlisted, private or direct on the create call. A queue replying into a private thread sets that field explicitly, then confirms the published reply's audience.
Stop conditions a good draft cannot override
Risk scoring ranks drafts, so the stop conditions below have to remove the send button on their own, outside the model's judgment, because the model is the thing being scored. Conditions worth hard-coding:
- The parent is gone, or it changed after the draft was written.
- The account already replied in this thread inside the window.
- The message asks about money: refunds, invoices, order changes, chargebacks.
- The message raises a legal dispute, a regulator, a journalist or a health claim.
- The message contains a threat, or asks to move to a private channel.
- A useful answer would need a fact the sources do not carry.
Most of these end in a human reply or in no reply, which is the right outcome for a queue that drafts at volume.
Approval is the last gate, and it has to bind the exact words. SMM Agent's posting docs separate the steps: agents create drafts first, intent defaults to draft, and publishing is a separate POST /api/posts/{id}/publish call against a saved post, which the page says to keep behind explicit user approval (SMM Agent posting docs, captured 26 October 2026). The same page states the schedule rules and the workspace scope of a bearer key. It does not state how the queue handles a second reply in the same thread, or whether it stores a thread root, so those stay questions for the tool rather than facts about it.
The test, on one thread
Use two accounts you control: one that the tool posts from, and one that plays the person in the thread.
- From the person account, post a top-level status.
- Still as the person account, reply to it twice. Those two replies are the parents a queue would answer.
- Put the thread in front of the tool the way your lane normally does, through its own discovery surface or a manual paste. The pages cited here document drafting and publishing, so treat intake as your tool's own feature.
- Count the drafts. One draft for the whole thread means the queue holds a thread-level key. Two drafts means it did not dedupe at the thread level.
- As the person account, edit the parent reply that the draft answers, the one the queue named when it drafted. Leave the draft sitting, then approve it and let the queue run its publish call.
- Read the log for three fields: the thread root, the parent id, and the parent timestamp or hash the tool compared at send time.
- Create a fresh draft on the same thread. This time delete the parent reply from the person account, approve the new draft, and let it publish. Record whether the call went out, failed, or was blocked before sending.
Each outcome gives you something to act on. Two drafts from one thread means the queue needs a thread-level key. A publish that goes out after the edit means nothing re-read the parent. A publish that goes out after the delete means the queue did not check the parent before sending. A blocked send with the parent's old timestamp in the log means the check exists and did its job.
Two questions remain that the test cannot answer on its own: which field the queue stores as the thread key, and what the queue does when that key no longer matches. Put both answers next to the reply runbook with the date you asked, and keep the log from step six with the thread root in it.
Ready to automate your social posting?
Join the waitlist for early access to SMMClaw.