Repository navigation
feat(review-desk): Show Review items as Slack cards - #2468
Merged
Merged
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This comment has been minimized.
This comment has been minimized.
sentry-junior
Bot
force-pushed
the
feat/review-items-in-slack
branch
from
October 31, 2026 00:38
dfee6b7 to
cbd2988
Compare
sentry-junior
Bot
force-pushed
the
feat/review-items-in-slack
branch
from
October 31, 2026 01:59
e8d5ea4 to
22aa9e3
Compare
sentry-junior
Bot
force-pushed
the
feat/review-items-in-slack
branch
from
October 31, 2026 02:12
22aa9e3 to
98f887e
Compare
sentry-junior
Bot
force-pushed
the
feat/review-items-in-slack
branch
from
October 31, 2026 02:30
98f887e to
0b2dd7a
Compare
dcramer
force-pushed
the
feat/review-items-in-slack
branch
from
October 31, 2026 02:35
0b2dd7a to
b10c7f7
Compare
dcramer
force-pushed
the
feat/review-items-in-slack
branch
from
October 31, 2026 02:56
f97f4c1 to
e9f38e7
Compare
sentry-junior
Bot
force-pushed
the
feat/review-items-in-slack
branch
from
October 31, 2026 02:59
e9f38e7 to
a214bd1
Compare
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
There are 2 total unresolved issues (including 1 from previous review).
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit a214bd1. Configure here.
Post a card for each open Review item in its linked Slack threads and change it in place after each agent or person change. Card controls reuse the requestUserInput rendering: choice buttons, an Answer form, Done for a notice, and Dismiss. A click acts as the linked Junior User and reaches the thread as Slack input from that person. Co-Authored-By: David Cramer <david@sentry.io>
…hread Co-Authored-By: David Cramer <david@sentry.io>
…r click A card claim now stores when it started. A later sync takes over a claim that is older than one minute, so a crash or failed write no longer strands a thread without a card. The ts write only succeeds for the sync that still owns the claim. Slack card clicks use firstCloseOnly, so only the click whose conditional close wins adds input to the thread. Two fast clicks add one Turn. Co-Authored-By: David Cramer <david@sentry.io>
…aims A sync now posts the card, then inserts its row. When two syncs post in the same thread, the first row wins and the other sync deletes its card. A card whose row cannot be saved is deleted too. This removes the posting marker, the takeover timeout, and the rows that could stay stuck when a sync stopped. Co-Authored-By: David Cramer <david@sentry.io>
Card syncs of one item now run under withLock from chat/state/locks.ts. Two syncs cannot post two cards in one thread, and each sync reads the latest item, so the post-then-delete and re-read paths go away. syncReviewItemSlackCards takes an item id because it reads the item under the lock. Co-Authored-By: David Cramer <david@sentry.io>
Remove the copy of withLock and fenceLock from api/acp/state.ts. ACP now imports them from chat/state/locks.ts. Every ACP caller already passed its 10s TTL, so lock timing does not change. The shared helpers now take only the three lock operations, so ACP's narrow state type fits. The keep-alive extend now ignores a rejected call, as the ACP copy did, and the next fenceLock still catches a lost lock. Co-Authored-By: David Cramer <david@sentry.io>
…force A private item now links only to the Conversation that added it, so every linked thread can show its Slack card. Co-Authored-By: David Cramer <david@sentry.io>
Main now rejects parsing a Conversation id to find a Slack thread. An Automation run can own a Slack thread with an id that is not a Slack thread id. The card sync now gets the thread from resolveSlackReplyTarget and skips a Conversation without a thread. Cards are Block Kit controls that change in place, so the sync joins the raw-post rule ignores, like the requestUserInput controls. Co-Authored-By: David Cramer <david@sentry.io>
dcramer
force-pushed
the
feat/review-items-in-slack
branch
from
October 31, 2026 03:06
a214bd1 to
dea4ad1
Compare
…ate content off public items The agent tools read items as the Actor too. An assigned User could then read a private item, or an item of another workspace, from any Conversation, and the agent could copy it there. The tools now read as the Conversation. The review desk still shows assigned items. An agent can now change an item only in its workspace, and a public item only from a public Conversation, so a private run cannot write private content into a public item. Co-Authored-By: David Cramer <david@sentry.io>
Contributor
|
3 screenshot changes — 3 changed · 0 added · 0 removed Review screenshots in Frameshift
|
Slack cards now name their Conversation from the card row, so a click in a thread that an Automation run owns records Slack input in that run and excludes it from fan-out. Choice buttons carry their label, and a click on a stale card whose label the item no longer offers is rejected. A closed card puts its note and review desk link in separate context elements, so a long answer stays inside the Slack 3,000-character limit. A retry of a take, or of the same agent close, now sends the messages that a failed earlier attempt did not send. Each message has a key, so only the missing ones go. A private item that an Automation added can be assigned to the creator of that Automation. A fresh run often has no Actor and no people yet.
This comment has been minimized.
This comment has been minimized.
dcramer
approved these changes
Oct 31, 2026
This branch was successfully deployed
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.

Part 5 of the review desk stack for #2401. Stacked on #2466.
requestUserInputrendering: one button per option for a singlechoicefield, otherwise an Answer button that opens the same form. A notice shows Done. Every card shows Dismiss and links to the item on the review desk.junior_review_item_slack_cardsstores the message of each card. After every agent update or close and every person action (Slack, review desk, or Conversation card), each card changes in place. A closed card has no controls and shows who closed it and the answer.actOnReviewItemas that User, so the first action still closes the item everywhere. The thread of the card gets the action as Slack input from the person, like an answer torequestUserInput. The other linked Conversations get the usual messages (exceptConversationIdkeeps the thread from getting a second copy). A click on a closed or forbidden item gets an ephemeral note and refreshes the card.review_item.slack_card.sync.failed) and never fails the item change.Small refactors:
buildSlackUserInputFormtakes the callback id and metadata, so both forms share one builder.slackUserInputAnswerNotetakeswhotext instead of a Slack user id, because a Review item closer is a Junior User. The Slack input that a click makes moved tochat/ingress/slack-interaction-input.tsso both handlers build it the same way.Tests:
tests/integration/slack/review-item-card-webhook.test.tscovers the click flow (cards in two threads, first click closes both, a stale click does nothing) and a private item (card only in the adding thread, only an assignee can act).via David Cramer.
--
View Session [Sentry]