Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions docs/developers/qwen-serve-protocol.md
Original file line number Diff line number Diff line change
Expand Up @@ -796,19 +796,21 @@ Runtime actions are strict-gated `POST` requests to
worker owned by the resolved workspace.

Pairing management is available only for instances configured with the
`pairing` sender policy:
`pairing` sender policy or group policy:

- `GET .../channels/:name/pairing-requests`
- `POST .../channels/:name/pairing-requests/approve` with `{ "code": "..." }`
- `GET .../channels/:name/pairing-approvals`
- `DELETE .../channels/:name/pairing-approvals` with
`{ "senderId": "..." }`
either `{ "senderId": "..." }` or `{ "groupId": "..." }`

All pairing routes require a bearer token and use `Cache-Control: no-store`.
Requests, approvals, and revocations are scoped to the selected Channel
instance and workspace. The approvals snapshot contains sender IDs because the
allowlist does not persist sender display names. Revoking an unknown sender
returns `404 channel_pairing_approval_not_found`.
instance and workspace. Pending requests include a typed user or group subject;
group requests also retain the sender who initiated the request. Approval
snapshots contain `senderIds` and `groupIds` because allowlists do not persist
display names. Revoking an unknown user or group returns
`404 channel_pairing_approval_not_found`.

### Channel delivery and Notify

Expand Down
6 changes: 4 additions & 2 deletions docs/users/features/channels/dingtalk.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,9 +115,10 @@ Every target must set `isGroup` explicitly. For a direct message, `chatId` is th

DingTalk bots work in both DM and group conversations. To enable group support:

1. Set `groupPolicy` to `"allowlist"` or `"open"` in your channel config
1. Set `groupPolicy` to `"allowlist"`, `"pairing"`, or `"open"` in your channel config
2. Add the bot to a DingTalk group
3. @mention the bot in the group to trigger a response
4. If using `groupPolicy: "pairing"`, approve the group's pairing request once before responses start

By default, the bot requires an @mention in group chats (`requireMention: true`). Set `"requireMention": false` for a specific group to make it respond to all messages. See [Group Chats](./overview#group-chats) for full details.

Expand Down Expand Up @@ -161,7 +162,8 @@ You can send photos and documents to the bot, not just text.

### Bot doesn't respond in groups

- Check that `groupPolicy` is set to `"allowlist"` or `"open"` (default is `"disabled"`)
- Check that `groupPolicy` is set to `"allowlist"`, `"pairing"`, or `"open"` (default is `"disabled"`)
- If using `"pairing"`, verify the group's pairing request has been approved
- Make sure you @mention the bot in the group message
- Verify the bot has been added to the group

Expand Down
6 changes: 4 additions & 2 deletions docs/users/features/channels/feishu.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,9 +121,10 @@ Then set the request URL in Feishu Open Platform to `http://<your-server>:9321`.

Feishu bots work in both DM and group conversations. To enable group support:

1. Set `groupPolicy` to `"allowlist"` or `"open"` in your channel config
1. Set `groupPolicy` to `"allowlist"`, `"pairing"`, or `"open"` in your channel config
2. Add the bot to a Feishu group
3. @mention the bot in the group to trigger a response
4. If using `groupPolicy: "pairing"`, approve the group's pairing request once before responses start

By default, the bot requires an @mention in group chats (`requireMention: true`). Set `"requireMention": false` for a specific group to make it respond to all messages.

Expand Down Expand Up @@ -170,7 +171,8 @@ Multiple users can send messages simultaneously in the same group chat. Each mes

### Bot doesn't respond in groups

- Check that `groupPolicy` is set to `"allowlist"` or `"open"` (default is `"disabled"`)
- Check that `groupPolicy` is set to `"allowlist"`, `"pairing"`, or `"open"` (default is `"disabled"`)
- If using `"pairing"`, verify the group's pairing request has been approved
- Make sure you @mention the bot in the group message
- Verify the bot has been added to the group

Expand Down
24 changes: 13 additions & 11 deletions docs/users/features/channels/github.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,17 +78,17 @@ Local `gh` authentication requires an HTTPS `baseUrl` so the daemon host credent

## Configuration Options

| Option | Default | Description |
| ------------------------- | ------------------------ | --------------------------------------------------------------------------------------------- |
| `token` | unset | Optional classic PAT with `notifications` scope; overrides local `gh` authentication |
| `useLocalGh` | `false` | Explicitly reuse the daemon host's account-wide GitHub CLI authentication |
| `pollInterval` | `60000` | Poll interval in ms |
| `baseUrl` | `https://api.github.com` | API base URL (for GHE) |
| `groupPolicy` | `"disabled"` | Must be `"open"` for notifications to flow |
| `senderPolicy` | `"allowlist"` | Who can trigger the bot |
| `groups.*.requireMention` | `true` | Require @mentions for ordinary comments; directed notification reasons still run |
| `blockStreaming` | `"off"` | Always forced to `"off"`; intermediate model chunks aren't published; `"on"` is not supported |
| `reasonFilter` | unset | Optional allowlist of GitHub notification reasons to process |
| Option | Default | Description |
| ------------------------- | ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| `token` | unset | Optional classic PAT with `notifications` scope; overrides local `gh` authentication |
| `useLocalGh` | `false` | Explicitly reuse the daemon host's account-wide GitHub CLI authentication |
| `pollInterval` | `60000` | Poll interval in ms |
| `baseUrl` | `https://api.github.com` | API base URL (for GHE) |
| `groupPolicy` | `"disabled"` | Must be `"open"`, `"allowlist"` with the repo (`owner/repo`) listed in `groups`, or `"pairing"` with the repo approved for notifications to flow |
| `senderPolicy` | `"allowlist"` | Who can trigger the bot |
| `groups.*.requireMention` | `true` | Require @mentions for ordinary comments; directed notification reasons still run |
| `blockStreaming` | `"off"` | Always forced to `"off"`; intermediate model chunks aren't published; `"on"` is not supported |
| `reasonFilter` | unset | Optional allowlist of GitHub notification reasons to process |

Use `reasonFilter` to drop noisy notification classes such as `ci_activity` or `state_change`. Do not use `reasonFilter: ["mention"]` as a replacement for `groups.*.requireMention`: GitHub's `mention` reason is sticky at the thread level, so real new @mentions can arrive later under `comment`, `subscribed`, `author`, or other reasons and would be skipped.

Expand All @@ -104,6 +104,8 @@ Always use `senderPolicy: "allowlist"` with explicit `allowedUsers` on public re

Allowlist and pairing entries follow the **username**, not the immutable account ID. If an allowlisted user renames their GitHub account, remove the stale entry — GitHub releases the old username for anyone else to claim, and the new holder would inherit the allowlist/pairing authorization.

Note that under `groupPolicy: "pairing"`, access is granted per repository: once a repository is approved, **any GitHub user** can drive the bot through that repository's issues and pull requests. All GitHub traffic is group traffic, so `senderPolicy` and `allowedUsers` do not gate members of an approved repository. Approvals are keyed by the repository full name (`owner/repo`), which changes on rename or transfer — revoke stale group approvals after any repository rename, transfer, or deletion.

## Mention Detection

The adapter detects mentions by scanning comment text and first-contact issue or PR bodies for `@bot-username` using a case-insensitive regex. It does not trust `reason: "mention"` alone because that value is sticky at the thread level. Other reasons select review, triage, followed-thread, or fallback prompts.
Expand Down
24 changes: 13 additions & 11 deletions docs/users/features/channels/gitlab.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,14 @@ For self-hosted instances, set `baseUrl`:

## Configuration Options

| Option | Default | Description |
| ------------------------ | ------------------------- | ---------------------------------------------------------- |
| `token` | (required) | PAT with `read_api` + `api` scopes |
| `pollInterval` | `60000` | Poll interval in ms |
| `baseUrl` | `https://gitlab.com` | GitLab instance URL |
| `action_prompt_template` | (required for processing) | Maps GitLab action names to metadata templates |
| `groupPolicy` | `"disabled"` | Must be `"open"`, or `"allowlist"` with the project listed |
| `senderPolicy` | `"allowlist"` | Who can trigger the bot |
| Option | Default | Description |
| ------------------------ | ------------------------- | ------------------------------------------------------------------------------------------------- |
| `token` | (required) | PAT with `read_api` + `api` scopes |
| `pollInterval` | `60000` | Poll interval in ms |
| `baseUrl` | `https://gitlab.com` | GitLab instance URL |
| `action_prompt_template` | (required for processing) | Maps GitLab action names to metadata templates |
| `groupPolicy` | `"disabled"` | Must be `"open"`, `"allowlist"` with the project listed, or `"pairing"` with the project approved |
| `senderPolicy` | `"allowlist"` | Who can trigger the bot |

## action_prompt_template

Expand Down Expand Up @@ -132,13 +132,15 @@ On a **public project**, setting `senderPolicy: "open"` allows **any GitLab user

Always use `senderPolicy: "allowlist"` with explicit `allowedUsers` on public projects.

Note that under `groupPolicy: "pairing"`, access is granted per project: once a project is approved, **any GitLab user** can drive the bot through that project's issues and merge requests. All GitLab traffic is group traffic, so `senderPolicy` and `allowedUsers` do not gate members of an approved project. Approvals are keyed by the project path (`owner/repo`), which changes on rename or transfer — revoke stale group approvals after any project rename, transfer, or deletion.

## Mention Detection

The adapter always sets `isMentioned = true` on dispatched envelopes, because GitLab has already determined the mention when creating the todo. The `action_prompt_template` config is the real event filter — only actions with a configured template are processed. The `@bot` mention is stripped from the message text before dispatch via `stripBotMention`.

### ⚠️ groupPolicy Must Be "open" or "allowlist"
### ⚠️ groupPolicy Must Be "open", "allowlist", or "pairing"

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Suggestion] This diff recommends groupPolicy: "pairing" here but leaves the unchanged Security section above still saying "Always use senderPolicy: \"allowlist\" with explicit allowedUsers on public projects" unconditionally. All GitLab envelopes are group envelopes (buildEnvelope hardcodes isGroup: true) and the pairing preflight early-return precedes the sender gate — so once a project is approved, senderPolicy/allowedUsers gate nothing on this adapter. — Failure scenario: an operator on a public GitLab project follows both pieces of advice in this file; after approving the project — the step this paragraph instructs — ANY GitLab user who @mentions the bot drives the agent in the operator's cwd, despite the allowlist. (The behavior is intended per overview.md; the defect is the same-file contradiction.) Suggested fix: add a pairing caveat to the Security section — under groupPolicy: "pairing" on GitLab, access is controlled per-project once approved; all GitLab traffic is group traffic, so senderPolicy/allowedUsers do not gate project members.

中文说明

本 diff 在此处推荐 groupPolicy: "pairing",但上方未改动的 Security 一节仍无条件地要求“公开项目务必使用 senderPolicy: \"allowlist\" 并显式配置 allowedUsers”。GitLab 的所有 envelope 都是群 envelope(buildEnvelope 硬编码 isGroup: true),且 pairing 的 preflight 提前返回先于发送者门执行——因此项目一旦获批,senderPolicy/allowedUsers 在该 adapter 上不起任何拦截作用。失败场景:公开 GitLab 项目的运营者同时遵循本文件的两条建议;批准项目(即本段指导的步骤)后,任何 @ 机器人的 GitLab 用户都能在运营者的 cwd 中驱动 agent,allowlist 形同虚设。(该行为本身是 overview.md 记录的预期设计;缺陷是同一文件内的自相矛盾。)建议修复:在 Security 一节补充 pairing 说明——GitLab 上的 groupPolicy: "pairing" 批准后即按项目整体授权,且 GitLab 流量全部是群流量,senderPolicy/allowedUsers 不约束项目成员。

— qwen3.8-max via Qwen Code /review (v0.21.5)


`groupPolicy` must be set to `"open"`, or `"allowlist"` with the project explicitly listed, for todos to be processed. The default value `"disabled"` drops all mentions: todos are marked done and the cursor advances, but no dispatch occurs. A rejection is logged (`preflight rejected reason=group_disabled`) but the todo is still consumed. If your bot is not responding to mentions, check that `groupPolicy` is not `"disabled"`.
`groupPolicy` must be set to `"open"`, `"allowlist"` with the project explicitly listed, or `"pairing"` for todos to be processed. Under `"pairing"`, the first mention from an unapproved project creates a group pairing request; approve it once with `qwen channel pairing approve`, and todos from that project are dispatched from then on. The default value `"disabled"` drops all mentions: todos are marked done and the cursor advances, but no dispatch occurs. A rejection is logged (`preflight rejected reason=group_disabled`) but the todo is still consumed. If your bot is not responding to mentions, check that `groupPolicy` is not `"disabled"`.

## How It Works

Expand All @@ -151,7 +153,7 @@ The adapter uses GitLab's Todos API as the message source:
5. **Detect mention type** via `target_url` anchor:
- `#note_123` present → comment mention → text is `todo.body` (the comment)
- No anchor → description mention → text is the issue/MR description
6. **Dispatch** the envelope through `handleInbound` (requires `groupPolicy: "open"` or `"allowlist"` with the project listed)
6. **Dispatch** the envelope through `handleInbound` (requires `groupPolicy: "open"`, `"allowlist"` with the project listed, or `"pairing"` with the project approved)
7. **Advance cursor** and **mark todo done** (best-effort)

The cursor (`lastProcessedId`) advances regardless of dispatch success or failure. Failed dispatches post a ⚠️ error comment on the issue/MR and are not retried — the user can re-mention the bot to trigger a new todo.
Expand Down
Loading
Loading