This repository has been archived on 2026-08-04. You can view files and clone it, but cannot push or open issues or pull requests.
orchestrator/agent-team/slack/README.md
Adam Moussa b6a12af477
docs(agent-team): slack app is now workspace-level A0BCC7TTU66 (org app deleted) (#27)
The org-owned app A0BC7AT8NUD (created via the org config token) connected its
Socket Mode socket but received ZERO workspace Events API events, so the
clarifier never heard answers. Root cause: Socket Mode event delivery only works
for WORKSPACE-LEVEL apps. Recreated from the dashboard scoped to the Sea Haven
Industries workspace -> A0BCC7TTU66 (bot @agentteam2); events now deliver and the
live human gate works end to end. Old org app deleted.

Updates the slack/ README: new app id/bot, a hard-lesson callout (must be
workspace-level, never org-owned), the real-envelope answer-matching note, and a
corrected dashboard setup/update flow.
2026-06-22 15:47:24 -04:00

72 lines
3.9 KiB
Markdown

# agent-team Slack app
Dedicated Slack app backing the Plane-2 clarifier human-gate (Socket Mode).
Kept separate from the webhook-only **Tech Notifications** app (`A0ARYQZU3KJ`)
that the nightly secrev sweep uses, to isolate the two-way bot's trust surface.
| Field | Value |
|---|---|
| App name | Sea Haven agent-team |
| App ID | `A0BCC7TTU66` |
| Bot | `agent-team` (handle `@agentteam2`) · user id `U0BCFSJ7SUC` |
| Scope | **Workspace-level** app, installed to **Sea Haven Industries** (`T0A46CP6QR3`) |
| Manifest | [`agent-team-manifest.json`](./agent-team-manifest.json) (source of truth) |
| Settings | https://api.slack.com/apps/A0BCC7TTU66 |
> ## ⚠️ Must be a WORKSPACE-LEVEL app (hard lesson, 2026-06-22)
> Socket Mode event delivery only works for **workspace-level** apps. An
> **org-owned** app (one created via the Enterprise **org/config token** /
> `apps.manifest.create`, even when workspace-granted with
> `--org-workspace-grant`) **connects the socket but receives ZERO workspace
> Events API events** — outbound `chat.postMessage` works, but inbound
> `message`/`app_mention` are never delivered, so the clarifier never hears
> answers. The first build hit exactly this with the now-deleted org app
> `A0BC7AT8NUD`. **Create this app from the dashboard** (api.slack.com/apps →
> Create New App → From manifest) and **pick the *workspace* "Sea Haven
> Industries" as the dev workspace**, NOT the Enterprise org. Then a normal
> *Install to Workspace* works (no org-grant dance). Do **not** recreate it via
> the org config token.
## Why these scopes (verified against the code)
`agent_team/transport/slack_listener.py` subscribes over Socket Mode to
`message`, `app_mention`, and Block Kit `block_actions`; `slack_live.py` posts
questions via `chat.postMessage`. Inbound message/app_mention arrive as the
Events API envelope `{"type":"event_callback","event":{...}}` and a free-text
thread reply is matched to its question by `thread_ts == channel_ref` (see
`find_open_question_by_channel_ref`).
| Capability | Scope / setting | Why |
|---|---|---|
| Post clarifier questions | `chat:write` | `slack_live.py` `chat.postMessage` |
| Hear thread replies | `channels:history` / `groups:history` + `message.channels`/`message.groups` | `@app.event("message")` |
| Hear DM replies | `im:history` + `message.im` | DM answer path |
| Hear @mentions | `app_mentions:read` + `app_mention` | `@app.event("app_mention")` |
| Block Kit answers | `interactivity.is_enabled` | `@app.action(...)` |
| Inbound WebSocket | `socket_mode_enabled` + app-level token w/ `connections:write` | VPN-only box, no public HTTPS endpoint |
Inbound auth is NOT scope-based: AUTHZ-01 (`AGENT_TEAM_SLACK_OWNER_IDS`) gates
the *sender* and fails closed. Socket membership alone is never authorization.
## Setup (operator, in browser — secrets never echoed)
1. **Create the app** — api.slack.com/apps → *Create New App* → *From an app
manifest* → **pick workspace "Sea Haven Industries"** → paste
`agent-team-manifest.json`.
2. **Install to Workspace** → copy the **Bot User OAuth Token** (`xoxb-`) →
`SLACK_BOT_TOKEN`.
3. **Basic Information → App-Level Tokens → Generate** with scope
`connections:write` → `SLACK_APP_TOKEN`.
4. **Channel** — `/invite @agentteam2` into the clarifier channel; its `C0…` id
→ `SLACK_CHANNEL_ID`.
5. **Owner allowlist** — `AGENT_TEAM_SLACK_OWNER_IDS` = Adam's Slack user id
(`U0A3SC48T47`), comma-separated if more than one. Fails closed if empty.
All five land in `~/secrev.env` on the box (mode 600), never shell history.
## Updating the app from the manifest
Edit `agent-team-manifest.json`, then in the dashboard (App Manifest tab) paste
the updated manifest, or use `apps.manifest.update` with an app **config token
scoped to the workspace app** (the org config token can read/manage it as org
owner, but keep the app workspace-level — do not re-create it org-owned).