Repository navigation
Description
Junior does not start work when assigned to a GitHub issue, so requests have to be relayed through Slack. Support requesting Junior work directly from GitHub. Only a tag or mention from a person in Junior's trusted-people database may start a flow. Tags from untrusted people must not start one.
Security requirements
From a security review of this proposal:
- Deterministic gate before any run. Trust must be checked in code before a Run is created, not by the agent. Issue and comment Events today carry the author login only inside
trustedSummarytext, with no structured author field. Untrusted tags are dropped before any model call. - Match the immutable GitHub user id. Compare the webhook
sender.idwith a GitHub Identity linked to a User through the OAuth account-linking flow (providerSubjectIdis the numeric id fromGET /user). Never trust logins (rename/reuse), commit emails, or display names. Check the person who did the action (commenter or assigner), not the issue author. - Only the trusted comment is the instruction. Repos such as
getsentry/juniorare public, so the issue body and other comments are untrusted. They stay untrusted text, and action review judges against the trusted person's comment. Related: Audit actor/instruction provenance across plugins #773. - No private data in public output. Replies land on a GitHub issue that can be public, while Junior can read Slack, Notion, memory, and Sentry. Runs started from GitHub need limits on what they read or post publicly.
- Revocation applies. A linked GitHub Identity persists after the person leaves. Re-check the linked Slack account's workspace membership when a tag arrives, as Slack ingress does.
- Correct credentials. Issue and pull request writes use the GitHub App bot (Make Junior primary on GitHub issues and pull requests #780). Any delegated access belongs to the person who tagged Junior.
- Edited comments. Decide whether
issue_comment.editedcan trigger a flow; handle it explicitly.
Existing controls to keep: webhook HMAC verification, installation id check, bot self-filtering, and delivery-id idempotency.
Design
GitHub starts the work, and Slack is the home.
A tag on GitHub only starts work. The work runs in a private Slack DM with the person who wrote the tag. Replies do not go to GitHub, except when Junior uses its normal GitHub tools as the App bot.
Flow
- The GitHub webhook receives
issue_comment.created. Edited comments do not start work. - The plugin stops at once unless the comment mentions the App (
mentionsBot, feat(github): Add trusted sender and mention data to issue comments #2209). - The plugin asks core to start a run for the GitHub Identity with the webhook
sender.id. The plugin can only name an Identity of its own provider. - Core starts the run only when all of these are true. If one is false, core drops the request and does not call the model.
- A GitHub Identity with this numeric id is linked to a User through the OAuth linking flow.
- That User has exactly one Slack Identity in the bot's workspace.
- The Slack account is active (
users.info: not deleted, not a bot).
- Core opens the DM and starts a dispatch with delegated credentials that are bound to that DM (
private-direct-conversation). This contract already exists for plugin heartbeats.- Work that starts from a public repository is public work, even though Junior delivers it in a private DM. Step 4 adds this.
- Optional: the App bot replies "on it, details in Slack". Untrusted tags get no reply.
Instruction and context
- The trusted comment is the instruction of that person. Action review treats it like a Slack message from that person.
- The issue title, body, and other comments are untrusted context. This is the same rule as when a person pastes an issue link into Slack today.
- GitHub writes use the App bot and the same action review as today.
DM threads
- Each GitHub request is one top-level DM message. All work for that request stays in its thread.
- Later: a new trusted tag on the same issue continues the same thread.
Known gaps
- Dispatch runs turn off interactive sign-in today. If the person has not connected an account that the work needs, the run is blocked and reports it in the DM. Step 3 adds sign-in prompts in the person's DM.
- Dispatch input is a bot-authored message. Step 3 must give action review the provenance of the person.
Tracking
- Step 1: structured
senderId/senderLogin/mentionsBoton issue comment events (feat(github): Add trusted sender and mention data to issue comments #2209, merged) - Step 2: core
dispatchForIdentity, private-only (feat(dispatch): Start DM dispatches for linked provider identities #2217) - Step 3: trusted comment counts as the person's instruction for action review, and sign-in prompts in the person's DM (Audit actor/instruction provenance across plugins #773). This also covers the reverse case: a private DM run that writes to a public issue or PR.
- Step 4: store visibility on each Conversation, separate from the destination row, so public-origin work can be delivered in a private DM (issue: Store visibility on each Conversation #2380, PR: feat(conversations): Store visibility on each root Conversation #2382)
- Step 5: GitHub plugin webhook → step 2, pass repo visibility, optional "on it, details in Slack" reply
This body replaces the older design comment (#2207 (comment)).
via @BYK.
--
Activity
sentry-junior commentedon Oct 23, 2026
Design: GitHub starts the work, Slack is the home
A tag on GitHub only starts work. The work runs in a private Slack DM with the person who wrote the tag. Replies do not go to GitHub, except when Junior uses its normal GitHub tools as the App bot.
Flow
issue_comment.created. Edited comments do not start work.mentionsBot, feat(github): Add trusted sender and mention data to issue comments #2209).sender.id. The plugin can only name an Identity of its own provider.users.info: not deleted, not a bot).private-direct-conversation). This contract already exists for plugin heartbeats.Instruction and context
DM threads
Known gaps
Steps
senderIdandmentionsBoton issue comment Events.fix(github): Ignore quoted and code mentions of the App
fix(dispatch): Block native identity providers from Identity dispatch
feat(github): Add trusted sender and mention data to issue comments (#…