Slack and approvals
Orion reports into Slack and reads back exactly one thing: approvals. It runs no Slack listener, so you cannot command it from Slack.
Setting up the Slack app and its token is on Credentials.
A channel per projectβ
orion plan creates #orion-<slug>, sets the channel topic to the idea,
posts an opening message naming the workspace and the commands to drive it,
and turns on slack.enabled in the project's orion.json. For a repository
you adopted, add the slack block yourself.
Every stage failure, breaker trip, quota wait, budget checkpoint, CI failure and approval request for that project then lands in that channel.
If Slack is unreachable when a workspace is created, Orion says so and carries on; the workspace is usable without a channel.
Mentions only when someone must actβ
Orion @-mentions people only on messages that need action: blocked, failed, and approval requests.
A CI failure Orion will retry is posted as a heads-up with no mention
("KEY failed CI -- Orion will retry it"). Only the last one, when the retries
are spent, mentions the people in slack.mention ("KEY still fails CI after
N retries"). slack.mention takes Slack user IDs (U...); empty falls back
to slack.invite_users.
When approval is requiredβ
Approval is required when either of these holds:
| Landing mode | Approval required when | Otherwise |
|---|---|---|
Batch integration (collect.batch_integration, on for every project orion plan creates) | slack.merge_approvers names people | a green batch lands unattended |
| One pull request per ticket | slack.require_approval is true | Orion reports that checks pass and waits for a person to merge on GitHub |
When approval is required, Orion posts a request in the project's channel, mentioning the approvers, and checks that message on each watch sweep.
slack.merge_approvers accepts a Slack user ID (U...), a username, a
display name or an email address. An ID always works. Resolving a name needs
the users:read scope and an email needs users:read.email; without them
the request still sends and names the person, and the run says the mention
was lost.
With slack.merge_approvers empty, nobody can approve from Slack, and in
batch mode that is also what lets a green batch land with no approval at
all. Membership of the channel gives no one the right to approve.
How to approve or rejectβ
React to the request message, or reply in its thread.
| To | React with | Or reply |
|---|---|---|
| Approve | β
white_check_mark, βοΈ heavy_check_mark, π +1, shipit, π rocket | approve, approved, lgtm, ship it, merge it, go ahead |
| Reject | β x, β no_entry, π« no_entry_sign, π -1, β hand | reject, rejected, no, hold, stop, wait, do not merge, don't merge |
The rules:
- A rejection beats every approval.
- Only people listed in
slack.merge_approverscount. - Only reactions and replies on the request message itself count.
- Orion's own reactions never count.
Reading reactions needs the reactions:read scope; reading thread replies
needs channels:history (public channels) or groups:history (private).
After adding a scope, reinstall the app: an issued token does not gain new
scopes. The design is in
ADR 0033.
Without Slackβ
Approve from the terminal, or from the web dashboard,
once the project's orion.json sets collect.allow_local_approval:
orion approve KEY # approve
orion approve KEY --reject --reason "<why>" # reject
Rejecting always works, with or without that setting. The next collect pass acts on the decision.
What else needs approvalβ
The same approval vocabulary and approver list cover three things:
- merges, as above;
- recommendations, such as the database architect's choice of database (see Advisors and decisions);
- releases:
orion release shipasks in the project's channel and waits for a person before it merges the promotion (see Releasing a milestone).
Talking to Orion through Slackβ
Orion has no Slack listener, because a socket-mode app would be a
long-running process with tokens to protect. To make Orion conversational,
drive it from an interactive Claude session with a Slack MCP server
connected: you ask Claude, and Claude runs the orion commands and reports
back into the channel. This adds no service to run or secure.
Test itβ
orion slack test [KEY]
sends a real message and reports exactly what breaks.
Not documented yetβ
- How long an approval request waits before anything else happens. Orion checks it on each watch sweep; no timeout is documented.