Repository navigation
feat(review-desk): Let people act on Review items - #2462
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This comment has been minimized.
This comment has been minimized.
f47dbc1 to
ae34774
Compare
ae34774 to
bbfdfa1
Compare
bbfdfa1 to
db5091c
Compare
Add the review desk API: list, count, read, and act on Review items. A person can take, submit, complete, or dismiss an item. The first close wins for every assignee. Each person action sends a web Message from that person to every open linked Conversation. An agent close sends an Event to the other linked Conversations. Refs #2401 Co-Authored-By: David Cramer <david@sentry.io> Co-Authored-By: David Cramer <david@sentry.io>
Co-Authored-By: David Cramer <david@sentry.io>
Co-Authored-By: David Cramer <david@sentry.io>
…ublic items Co-Authored-By: David Cramer <david@sentry.io>
db5091c to
43eb5fd
Compare
|
2 screenshot changes — 2 changed · 0 added · 0 removed Review screenshots in Frameshift
|
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 43eb5fd. Configure here.
| if (acceptsWebMessages(args.conversationId, conversation?.destination)) { | ||
| // A person action comes from that person, like a reply in Slack. | ||
| await appendAndEnqueueWebMessage( | ||
| { | ||
| actor: webActorFromEmail(args.change.user.email, { | ||
| ...(args.change.user.displayName | ||
| ? { fullName: args.change.user.displayName } | ||
| : undefined), | ||
| }), | ||
| conversationId: args.conversationId, | ||
| idempotencyKey: key, | ||
| message: args.text, | ||
| }, | ||
| { nowMs: args.nowMs, queue: args.queue }, | ||
| ); | ||
| return; | ||
| } | ||
| } |
There was a problem hiding this comment.
Person review actions start credentialed web turns in conversations the actor never joined
Person take/submit/complete/dismiss posts a web Message as the actor into every linked conversation that accepts web input, with no participant check, so a public item assigned to a victim (always linked to the creating conversation) starts a Turn under the victim’s web actor and credentials there. Send non-participant linked conversations on the event path instead, and only use person-authored web Messages when the actor is a participant.
Evidence
sendOne()callsappendAndEnqueueWebMessage()withwebActorFromEmail(change.user.email)for every open linked conversation whereacceptsWebMessages()is true, including Slack andlocal:webdestinations.- Unlike
appendConversationMessageForViewer(), this path never checksisParticipant/ conversation access for the acting user. - Web mailbox messages become Turns under that web actor;
credentialContextForActor(actor)attaches that actor’s user token slot for tool auth. - Public review items may assign any user email, and
addReviewItemalways links the creating conversation, so a hostile public item makes the victim’s action enqueue a credentialed turn (and any submit answer text) into the attacker’s conversation.
Identified by Warden · security-review · UT4-ZXD
Part 3 of the review desk stack for #2401. Stacked on #2462. - **Nav:** "Review desk" is the first nav item after Conversations. It shows the count of open items assigned to the viewer as a User (`/api/review-items/count`, refreshed every minute). Unassigned items do not count. - **Page (`/review`):** item list on the left, selected item on the right (`?item=<id>`). Mine / Everyone / All views, an Open / Archived filter that uses the same views, and search. The list groups items into "Needs an answer", "Notices", and "Blocked Automations". Blocked Automations come from the viewer's Automations with status `blocked`; they are not stored as items. Unassigned items show only in All, with an "Unassigned" label. - **Selected item:** title, body, subject, linked Conversations, who added it (Conversation and Automation), assignees, and the actions. An assignee can take, submit, complete, or dismiss. An archived item shows who closed it, when, and the answer. - **Shared form:** the `requestUserInput` form moves from `UserInputRequestCard` into `components/UserInputForm.tsx`. The transcript card still sends the formatted answer as a message. The review desk submits the structured answer. `ReviewItemActions` will also back the transcript card and side panel in the next PR. No new automated tests: the page is UI composition over the API that #2462 tests. Visual QA follows on the top PR. <!-- junior-request-attribution:start --> via **David Cramer**. <!-- junior-request-attribution:end --> <!-- junior-session-footer:start --> <!-- junior-conversation-id:slack%3AC0AHB7N2JCR%3A1793326028.695969 --> -- [View Session](https://junior-prod.sentry.dev/conversations/slack%3AC0AHB7N2JCR%3A1793326028.695969) [[Sentry]](https://sentry.sentry.io/explore/conversations/slack%3AC0AHB7N2JCR%3A1793326028.695969/?project=4510944073809921) <!-- junior-session-footer:end --> --------- Co-authored-by: sentry-junior[bot] <264270552+sentry-junior[bot]@users.noreply.github.com> Co-authored-by: David Cramer <david@sentry.io>

Part 2 of the review desk stack for #2401. Stacked on #2460.
Adds the review desk API and the person actions on Review items:
GET /api/review-itemslists items with the Mine / Everyone / All views, the archived filter, a Conversation filter, and text search.GET /api/review-items/countreturns the open items assigned to the viewer as a User (the nav count).GET /api/review-items/:idreads one item.POST /api/review-items/:id/actionsdoestake,submit,complete, ordismiss. The first close wins for every assignee and records who closed it. An action item needs an answer, so it cannot be completed. A retry of the same close succeeds and resends any missing messages.updateReviewItem) sends an Event to the other open linked Conversations, and the Event says it does not give user approval.acceptsWebMessagesmoves intoweb-input.tsso the dashboard append route and the review desk share one rule.Tests:
tests/integration/api/review-items/actions.test.ts(first-submit-wins, retry idempotency, take on Everyone, views, count) and the agent-close fan-out inreview-item-tools.test.ts.via David Cramer.
--
View Session [Sentry]