?

What you build

A private Slack channel where team members mention @rousseau with a repo path and a question. Rousseau checks out the workspace, runs read and grep from internal/tools/builtin/, and posts a reply with quoted line references. No public HTTP surface — Slack Socket Mode drives everything from outbound WebSocket.

Estimated time: 20 minutes assuming you already have Slack admin access to a workspace.

Prerequisites

  • Rousseau installed and a provider configured (see Quickstart).
  • Slack workspace admin.
  • A repository already checked out at some path under your $HOME — that becomes the "workspace" the bot can read/grep over.

Step 1: create a Slack app

Slack's Socket Mode is what makes this bot possible: your daemon opens an outbound WebSocket to Slack, no ingress required.

  1. Head to https://api.slack.com/apps and create a new app from scratch.
  2. Under Socket Mode, enable it and generate an app-level token with connections:write. Copy the xapp-... value.
  3. Under OAuth & Permissions, add these Bot Token Scopes:
    • chat:write
    • app_mentions:read
    • channels:history (or groups:history for private channels)
  4. Install the app to your workspace. Copy the Bot User OAuth Token — the xoxb-... value.
  5. Under Event Subscriptions, enable events and subscribe the bot to app_mention and message.channels (or message.groups).
  6. Invite the bot to the review channel: /invite @rousseau.

Step 2: configure rousseau

Add to ~/.config/rousseau/config.yaml. The relevant fields come from SlackConfig in internal/config/config.go:

provider: claudecli           # or anthropic — whatever you set in Quickstart

slack:
  app_token:  xapp-1-…
  bot_token:  xoxb-…
  bot_user_id: U0ROUSSEAU     # from https://api.slack.com/methods/auth.test
  reply_header: "*rousseau-agent*\n\n"
  allowlist:
    - U01ABC…                 # your Slack user IDs

agent:
  approver:
    mode: pattern
    default: deny
    allow:
      - {tool: read, match: ".*"}
      - {tool: grep, match: ".*"}
    # no bash, no write, no edit — read-only reviewer

The allowlist restricts who the router will accept messages from. The internal/transport/router.go router emits transport.rejected for any other sender.

Step 3: run the bridge

rousseau slack \
  --app-token "$SLACK_APP_TOKEN" \
  --bot-token "$SLACK_BOT_TOKEN" \
  --bot-user-id "$SLACK_BOT_USER_ID"

--bot-user-id prevents the bot from replying to its own messages. Structured logs from internal/transport/slack/client.go will show:

INFO slack.started
INFO slack.incoming from=U01ABC channel=C01REVIEW text="…"
INFO tool.execute name=read id=t_1
INFO tool.execute name=grep id=t_2

Step 4: try it

In the review channel:

@rousseau look under /home/seb/repos/acme-api and tell me
where request logging is set up

The claudecli provider (or Anthropic — whichever you chose) will call read and grep from internal/tools/builtin/ against the workspace bind mount. Because the approver runs pattern mode with only read and grep allowlisted, the model cannot write or shell out — even if a compromised prompt asks it to.

Step 5: harden

Pattern-mode approvers are regex over the JSON tool-input. To restrict read and grep to a specific project tree:

agent:
  approver:
    mode: pattern
    default: deny
    allow:
      - {tool: read, match: "\"path\":\"/home/seb/repos/acme-api/[^\"]*\""}
      - {tool: grep, match: "\"path\":\"/home/seb/repos/acme-api\""}

See Tutorial: Harden the approver for the full walkthrough of default: deny + audit.

Deploying under systemd

For anything beyond a laptop session, run the Slack bridge under the Podman Quadlet unit at docker/rousseau-agent.container — swap Exec=whatsapp --allow … for Exec=slack --app-token … --bot-token …. See Deployment for the full unit.

Related

Type to search 150+ pages. Ranking: BM25 with title/description boost.