diff --git a/api-reference/error-codes.mdx b/api-reference/error-codes.mdx
index d3cee2b..be1a379 100644
--- a/api-reference/error-codes.mdx
+++ b/api-reference/error-codes.mdx
@@ -3,7 +3,7 @@ title: Error codes
description: API error response fields and stable error codes.
type: reference
audience: user
-verified: 2026-09-21
+verified: 2026-09-24
executable: false
---
@@ -122,9 +122,9 @@ A conflict response also contains `current_state`. Some errors contain `user_mes
| Code | HTTP | Title | Why and fix | Prevent |
|---|---|---|---|---|
-| `UZ-SLK-010` | 401 | Invalid Slack signature | The Slack signature did not verify. The Slack app's signing secret must match the one vaulted at slack-app/signing_secret. | Keep Slack app credentials, permissions, and clocks current. |
-| `UZ-SLK-011` | 401 | Stale Slack timestamp | The Slack timestamp is more than 5 minutes off. That means a replay or clock skew. | Keep Slack app credentials, permissions, and clocks current. |
-| `UZ-SLK-020` | 200 | Slack team not installed | This Slack team has no connector install; the event is acknowledged and ignored. Re-run Connect Slack from the dashboard. | Keep Slack app credentials, permissions, and clocks current. |
+| `UZ-SLK-010` | 401 | Invalid Slack signature | **Retired.** A Slack delivery whose signature does not verify now returns [`UZ-WH-010`](#UZ-WH-010), like every other signed delivery. | Keep the Slack app's signing secret matched with the one `agentsfleet` holds. |
+| `UZ-SLK-011` | 401 | Stale Slack timestamp | **Retired.** A Slack delivery more than 5 minutes old now returns [`UZ-WH-011`](#UZ-WH-011). | Keep service clocks synchronized. |
+| `UZ-SLK-020` | 200 | Slack team not installed | **Retired.** A mention from a Slack team with no connector install returns `200` with `{"ignored": "team_not_mapped"}` and starts no run. Connect Slack again from **Settings → Integrations**. | Keep Slack connected to the workspace that owns the channel's fleets. |
| `UZ-SLK-022` | 502 | Slack token exchange failed | The Slack OAuth code could not be exchanged for a bot token. Retry the connect flow; if it continues, check the Slack app credentials. | Keep Slack app credentials, permissions, and clocks current. |
| `UZ-SLK-030` | 502 | Slack answer post failed | The answer could not be posted to Slack: missing chat:write, a 429, or an outage. It retries with backoff; the run does not fail. | Keep Slack app credentials, permissions, and clocks current. |
diff --git a/changelog.mdx b/changelog.mdx
index 083e47e..4e8863d 100644
--- a/changelog.mdx
+++ b/changelog.mdx
@@ -7,6 +7,37 @@ description: "Stay up to date with the latest agentsfleet product updates, new f
agentsfleet is in **stealth-mode testing** and pre-production. APIs and agent behavior may change between releases without long deprecation windows. Email [agentsfleet@agentmail.to](mailto:agentsfleet@agentmail.to) if you want a hand calibrating an agent or to join as a design partner.
+
+ ## Mention a fleet in Slack and it answers in the thread
+
+ A fleet attached to a Slack channel now answers when someone mentions `agentsfleet` there, and posts its answer as a reply in the same thread. Until now the Slack route acknowledged every mention and dropped it. [Answer mentions in Slack](/fleets/slack) walks through the setup.
+
+ ## What's new
+
+ - **Attach a fleet at install** — `--slack-channel ` writes a `mention` trigger for that channel into the fleet's `TRIGGER.md`. One fleet answers in one channel.
+ - **The fleet reads the thread** — it sees the first message and the latest 19 replies, each cut at 2,000 characters and 16,000 in total. In a private channel, or when Slack takes longer than 1.5 seconds, it answers from the mention alone.
+ - **Name a fleet to pick it** — start the message with a fleet's name when the channel has several. An unnamed mention with several candidates gets a notice that lists their names.
+ - **Each channel gets its own fleet** — the first mention no attached fleet takes creates `slack-channel--`. It has no tools, a budget of 1.00 dollars a day, and memory scoped to the channel. It replies with the command that attaches a fleet.
+ - **The fleet page shows the channel** — a fleet attached to a channel lists a **Chat mention** trigger with its channel identifier.
+ - **Write fleets answer only when named** — a fleet with `repository_access: write` opens at most one draft pull request per mention. The fleet cannot merge that pull request, mark it ready for review, or change a workflow.
+ - **Fleets read their Continuous Integration (CI) runs** — a GitHub-bound fleet's token now reads workflow runs and jobs (`actions: read`), and check-run annotations (`checks: read`) where the GitHub App installation holds that permission. A permission the installation lacks is left out of the token, and the mint still succeeds.
+
+ ## API reference
+
+ - **`POST /v1/workspaces/{workspace_id}/fleets`** — accepts an optional `slack_channel_id`, such as `C0123456789`, and adds the `mention` trigger for that channel.
+ - **`POST /v1/connectors/slack/events`** — answers `200` with `{"event_id": "", "replayed": false}` for an accepted mention, and `{"ignored": ""}` otherwise: `unreadable_body`, `bot_message`, `team_not_mapped`, or `unsupported_event`.
+ - **Slack signature errors** — a bad signature returns `401` `UZ-WH-010` and a stale timestamp `UZ-WH-011`, as every signed route does. The error registry now marks `UZ-SLK-010`, `UZ-SLK-011`, and `UZ-SLK-020` retired.
+
+ ## Bug fixes
+
+ - **An answer with nowhere to go is no longer queued** — an answer from a scheduled run, a steer, or a GitHub review was queued for its model provider, which is not a place to post, and then dropped. Only an event with a reply destination, such as a Slack thread, now owes a delivery.
+
+ ## CLI
+
+ - **`agentsfleet install --library --slack-channel `** — attaches the new fleet to one Slack channel. An identifier that is not `C` or `G` followed by at least eight upper-case letters or digits fails before any request: `must be a Slack channel ID: C or G, then upper-case letters and digits`.
+
+
+
## A Fleet library row shows where its bundle came from
diff --git a/cli/agentsfleet.mdx b/cli/agentsfleet.mdx
index 7be5e58..7bd23d2 100644
--- a/cli/agentsfleet.mdx
+++ b/cli/agentsfleet.mdx
@@ -3,7 +3,7 @@ title: Command reference
description: Commands available in the agentsfleet command-line client.
type: reference
audience: user
-verified: 2026-09-21
+verified: 2026-09-24
executable: false
---
@@ -105,7 +105,7 @@ Write these after `login`. Only `agentsfleet login` reads them.
| `agentsfleet library create --template ` | Onboards a workspace library entry from a built-in template. |
| `agentsfleet library list` | Lists only the entries this workspace onboarded, with the identifier each removal names. |
| `agentsfleet library delete ` | Removes one entry this workspace onboarded. Fleets installed from it keep running. |
-| `agentsfleet install --library ` | Installs one library entry. |
+| `agentsfleet install --library ` | Installs one library entry. `--slack-channel ` also attaches the fleet to one Slack channel, so it answers mentions there. |
| `agentsfleet fleet show ` | Shows one fleet. |
| `agentsfleet fleet update --from ` | Updates a fleet from a local bundle. |
| `agentsfleet list` | Lists fleets in the active workspace. `--starting-after ` fetches the next page. |
diff --git a/docs.json b/docs.json
index c9ac9d8..e13166d 100644
--- a/docs.json
+++ b/docs.json
@@ -61,6 +61,7 @@
"fleets/secrets",
"fleets/model-providers",
"fleets/connectors",
+ "fleets/slack",
"fleets/webhooks",
"fleets/authoring",
"fleets/tools",
diff --git a/fleets/authoring.mdx b/fleets/authoring.mdx
index 18407d9..7edebd9 100644
--- a/fleets/authoring.mdx
+++ b/fleets/authoring.mdx
@@ -3,7 +3,7 @@ title: Author a fleet
description: Create the two files that define a fleet.
type: how-to
audience: user
-verified: 2026-09-19
+verified: 2026-09-24
executable: false
---
@@ -51,6 +51,9 @@ Create an empty directory. Choose a lowercase fleet name with letters, numbers,
---
```
+ To have the fleet answer mentions in a Slack channel, add a `mention` trigger.
+ [Answer mentions in Slack](/fleets/slack) shows its fields.
+
3. Put the files in a GitHub repository.
`SKILL.md` must be at the repository root. `TRIGGER.md` is optional when the default manual trigger is enough.
@@ -125,3 +128,4 @@ Delete a workspace library entry with `DELETE /v1/workspaces/{workspace_id}/libr
- [Tools](/fleets/tools)
- [Webhooks](/fleets/webhooks)
- [Secrets](/fleets/secrets)
+- [Answer mentions in Slack](/fleets/slack)
diff --git a/fleets/connectors.mdx b/fleets/connectors.mdx
index 4c119b6..9d00b2f 100644
--- a/fleets/connectors.mdx
+++ b/fleets/connectors.mdx
@@ -3,7 +3,7 @@ title: Connect a provider
description: Connect a workspace to GitHub, Slack, Zoho Desk, Jira, or Linear.
type: how-to
audience: user
-verified: 2026-07-12
+verified: 2026-09-24
executable: false
---
@@ -31,6 +31,10 @@ You need administrator access to the workspace and provider account. Supported p
The workspace owns the connector. Each fleet needs a separate approved grant before it can use the connection.
+A connected Slack workspace also lets a fleet answer mentions in a channel. Posting that answer needs no grant, because `agentsfleet` posts it itself. See [Answer mentions in Slack](/fleets/slack).
+
+A fleet that answers in Slack and also calls another provider still needs that provider's approved grant. For example, it needs a GitHub grant to open a draft pull request.
+
## Verify it works
```bash
@@ -63,4 +67,5 @@ Remove any fleet integration grants that should no longer use the provider. Revo
- [Secrets](/fleets/secrets)
- [Webhooks](/fleets/webhooks)
+- [Answer mentions in Slack](/fleets/slack)
- [Error registry](/api-reference/error-codes)
diff --git a/fleets/install.mdx b/fleets/install.mdx
index 24df596..edfa850 100644
--- a/fleets/install.mdx
+++ b/fleets/install.mdx
@@ -3,7 +3,7 @@ title: Install a fleet
description: Install a fleet from your workspace library.
type: how-to
audience: user
-verified: 2026-09-19
+verified: 2026-09-24
executable: false
---
@@ -59,6 +59,10 @@ Sign in and select a workspace. Save every secret required by the library entry.
The requirement lines come first, so you see what the fleet was granted
before you see that it is live.
+ Add `--slack-channel ` to have the fleet answer mentions in one
+ Slack channel. [Answer mentions in Slack](/fleets/slack) covers the channel
+ identifier (ID) and how a mention picks a fleet.
+
3. Register each printed webhook URL with its provider.
For GitHub, open **Repository settings → Webhooks → Add webhook**. Use the matching workspace webhook secret.
@@ -126,3 +130,4 @@ agentsfleet delete
- [Fleet library](/fleets/library)
- [Secrets](/fleets/secrets)
- [Run and control a fleet](/fleets/running)
+- [Answer mentions in Slack](/fleets/slack)
diff --git a/fleets/slack.mdx b/fleets/slack.mdx
new file mode 100644
index 0000000..3016ddf
--- /dev/null
+++ b/fleets/slack.mdx
@@ -0,0 +1,156 @@
+---
+title: Answer mentions in Slack
+description: Attach a fleet to a Slack channel so it answers when someone mentions agentsfleet there.
+type: how-to
+audience: user
+verified: 2026-09-24
+executable: false
+---
+
+# Answer mentions in Slack
+
+## What this does
+
+A fleet attached to a Slack channel answers when someone mentions the `agentsfleet` app in that channel. The fleet reads the thread, runs once, and posts its answer as a reply in the same thread.
+
+Slack sometimes delivers one mention twice. The second delivery starts no second run.
+
+## Before you begin
+
+Connect Slack to your workspace at **Settings → Integrations**. See [Connect a provider](/fleets/connectors) for the full procedure.
+
+Invite the `agentsfleet` Slack app to the channel. The app receives mentions only in channels it belongs to.
+
+Find the channel identifier (ID) in Slack. Open the channel's details and copy **Channel ID** from the bottom of the **About** tab. It starts with `C` for a public channel or `G` for a private one.
+
+## Steps
+
+1. Install a fleet and attach it to the channel.
+
+ `` comes from `agentsfleet library`. `` is the channel ID you copied.
+
+ ```bash
+ agentsfleet install --library --slack-channel
+ ```
+
+ ```text
+
+ ✓ is live.
+ Fleet ID:
+ ```
+
+ `agentsfleet` adds a `mention` trigger for that channel to the fleet's `TRIGGER.md`. To write the same trigger yourself, add the `mention` entry below to the `triggers` list under `x-agentsfleet` in the fleet's existing `TRIGGER.md`. The example shows where that list sits, so keep a single `x-agentsfleet` block:
+
+ ```yaml
+ x-agentsfleet:
+ triggers:
+ - type: mention
+ source: slack
+ channels:
+ - C0123456789
+ ```
+
+ One fleet answers in one channel. To answer in a second channel, install a second fleet.
+
+2. Mention the app in the channel and ask your question.
+
+ ```text
+ @agentsfleet why did the last deploy fail?
+ ```
+
+ The fleet reads the thread you asked from and replies in that thread.
+
+3. Start with the fleet's name when the channel has more than one fleet.
+
+ ```text
+ @agentsfleet ci-responder why did the build fail?
+ ```
+
+ Case does not matter. A `:` or `,` right after the name is ignored.
+
+A mention that names no fleet goes only to a fleet that is running and has no `repository_access: write` in its `TRIGGER.md`. The table shows which fleet answers a mention.
+
+| The channel has | The mention names a fleet | Who answers |
+|---|---|---|
+| No attached fleet | No | The channel's own fleet, described below |
+| One running fleet without write access | No | That fleet |
+| Several running fleets without write access | No | Nobody. A notice lists the fleets' names. |
+| Attached fleets, none running without write access | No | Nobody. A notice asks you to name one. |
+| Any attached fleet | Yes | The named fleet. A paused fleet sends the paused notice. |
+
+A fleet whose `TRIGGER.md` declares `repository_access: write` answers only when a mention names it. From one mention it can open at most one draft pull request. It cannot merge the pull request, mark it ready for review, or change a workflow.
+
+### The channel's own fleet
+
+`agentsfleet` creates one fleet per channel the first time a mention reaches no attached fleet or needs a notice. Its name is `slack-channel--`, in lower case.
+
+This fleet answers from a model with no tools and no network access. Its budget is `daily_dollars: 1.00`, so it spends at most 1.00 dollars a day. When you ask for something it cannot reach, it replies with the install command that attaches a fleet to this channel.
+
+Its memory belongs to the channel, and no other fleet reads it. It also posts the channel's notices.
+
+## Verify it works
+
+1. Mention the app in the channel.
+
+2. Check that a reply from the fleet appears in the same thread.
+
+3. Open the fleet in the dashboard. Its trigger card reads **Chat mention** with the channel ID.
+
+4. List the fleet's events. `` comes from the install output.
+
+ ```bash
+ agentsfleet events
+ ```
+
+ ```text
+
+ ```
+
+## Common problems
+
+A notice replaces an answer when `agentsfleet` cannot pick one fleet. Each notice names the next step.
+
+| Notice starts with | Why | What to do |
+|---|---|---|
+| `Several fleets answer in this channel` | The mention named no fleet, and more than one could answer. | Start the message with one of the listed names. |
+| `The fleets attached here answer only when named` | Every attached fleet has repository write access or is paused. | Start the message with one of the listed names. |
+| ` is paused and cannot answer` | The named fleet is paused. | Run the `agentsfleet resume` command the notice prints. |
+
+A notice appears 30 to 60 seconds after the mention.
+
+The fleet reads the first message of the thread and the latest 19 replies. It cuts each message at 2,000 characters and the whole thread at 16,000.
+
+In a private channel, the fleet sees only your mention. The Slack app cannot read private channel history. The fleet also answers from the mention alone when Slack does not return the thread within 1.5 seconds.
+
+If Slack loses its reply to a posted answer, `agentsfleet` checks the thread before it posts again. The answer appears once. In a private channel `agentsfleet` cannot check, so the answer can appear twice.
+
+A fleet you install under the name `slack-channel--` with its own `TRIGGER.md` is never used as the channel's own fleet. While it holds that name, a mention that needs the channel's own fleet starts no run. Rename or delete that fleet.
+
+A skill you install under that name without a `TRIGGER.md` matches the channel's own fleet exactly. It answers in that fleet's place.
+
+A mention from a bot, an edited message, or the app's own reply starts no run.
+
+A mention from a Slack workspace that is not connected to an `agentsfleet` workspace starts no run. Connect Slack again from **Settings → Integrations**.
+
+## Remove or undo
+
+To detach a fleet from the channel, remove the `mention` trigger from its `TRIGGER.md`. Then update the fleet from your local bundle. `` is the bundle directory.
+
+```bash
+agentsfleet fleet update --from
+```
+
+```text
+
+```
+
+To remove the channel's own fleet, run `agentsfleet kill ` and then `agentsfleet delete `. Deleting it also deletes the channel's memory. The next mention that needs it creates a new one.
+
+Between the two commands, the channel fleet is killed, and a mention that needs it gets no answer. A channel fleet you stop instead of killing answers with the paused notice until you resume it.
+
+## Related pages
+
+- [Connect a provider](/fleets/connectors)
+- [Install a fleet](/fleets/install)
+- [Author a fleet](/fleets/authoring)
+- [Run and control a fleet](/fleets/running)