fix: tighten group elevated targeting
This commit is contained in:
@@ -7,7 +7,7 @@ read_when:
|
||||
|
||||
Goal: let Clawd sit in WhatsApp groups, wake up only when pinged, and keep that thread separate from the personal DM session.
|
||||
|
||||
Note: `routing.groupChat.mentionPatterns` is now used by Telegram/Discord/Slack/iMessage as well; this doc focuses on WhatsApp-specific behavior.
|
||||
Note: `routing.groupChat.mentionPatterns` is now used by Telegram/Discord/Slack/iMessage as well; this doc focuses on WhatsApp-specific behavior. For multi-agent setups, you can override per agent with `routing.agents.<agentId>.mentionPatterns`.
|
||||
|
||||
## What’s implemented (2025-12-03)
|
||||
- Activation modes: `mention` (default) or `always`. `mention` requires a ping (real WhatsApp @-mentions via `mentionedJids`, regex patterns, or the bot’s E.164 anywhere in the text). `always` wakes the agent on every message but it should reply only when it can add meaningful value; otherwise it returns the silent token `NO_REPLY`. Defaults can be set in config (`whatsapp.groups`) and overridden per group via `/activation`. When `whatsapp.groups` is set, it also acts as a group allowlist (include `"*"` to allow all).
|
||||
|
||||
@@ -100,6 +100,7 @@ Group messages require a mention unless overridden per group. Defaults live per
|
||||
Notes:
|
||||
- `mentionPatterns` are case-insensitive regexes.
|
||||
- Surfaces that provide explicit mentions still pass; patterns are a fallback.
|
||||
- Per-agent override: `routing.agents.<agentId>.mentionPatterns` (useful when multiple agents share a group).
|
||||
- Mention gating is only enforced when mention detection is possible (native mentions or `mentionPatterns` are configured).
|
||||
- Discord defaults live in `discord.guilds."*"` (overridable per guild/channel).
|
||||
|
||||
|
||||
@@ -186,4 +186,8 @@ Starting with v2026.1.6, each agent can have its own sandbox and tool restrictio
|
||||
- **Resource control**: Sandbox specific agents while keeping others on host
|
||||
- **Flexible policies**: Different permissions per agent
|
||||
|
||||
Note: `agent.elevated` is **global** and sender-based; it is not configurable per agent.
|
||||
If you need per-agent boundaries, use `routing.agents[id].tools` to deny `bash`.
|
||||
For group targeting, you can set `routing.agents[id].mentionPatterns` so @mentions map cleanly to the intended agent.
|
||||
|
||||
See [Multi-Agent Sandbox & Tools](/multi-agent-sandbox-tools) for detailed examples.
|
||||
|
||||
@@ -319,6 +319,7 @@ Group messages default to **require mention** (either metadata mention or regex
|
||||
- **Metadata mentions**: Native platform @-mentions (e.g., WhatsApp tap-to-mention). Ignored in WhatsApp self-chat mode (see `whatsapp.allowFrom`).
|
||||
- **Text patterns**: Regex patterns defined in `mentionPatterns`. Always checked regardless of self-chat mode.
|
||||
- Mention gating is enforced only when mention detection is possible (native mentions or at least one `mentionPattern`).
|
||||
- Per-agent override: `routing.agents.<agentId>.mentionPatterns` (useful when multiple agents share a group).
|
||||
|
||||
```json5
|
||||
{
|
||||
@@ -331,6 +332,18 @@ Group messages default to **require mention** (either metadata mention or regex
|
||||
}
|
||||
```
|
||||
|
||||
Per-agent override (takes precedence when set, even `[]`):
|
||||
```json5
|
||||
{
|
||||
routing: {
|
||||
agents: {
|
||||
work: { mentionPatterns: ["@workbot", "\\+15555550123"] },
|
||||
personal: { mentionPatterns: ["@homebot", "\\+15555550999"] }
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Mention gating defaults live per provider (`whatsapp.groups`, `telegram.groups`, `imessage.groups`, `discord.guilds`). When `*.groups` is set, it also acts as a group allowlist; include `"*"` to allow all groups.
|
||||
|
||||
To respond **only** to specific text triggers (ignoring native @-mentions):
|
||||
|
||||
@@ -23,6 +23,7 @@ and process access when the model does something dumb.
|
||||
Not sandboxed:
|
||||
- The Gateway process itself.
|
||||
- Any tool explicitly allowed to run on the host (e.g. `agent.elevated`).
|
||||
- **Elevated bash runs on the host and bypasses sandboxing.**
|
||||
|
||||
## Modes
|
||||
`agent.sandbox.mode` controls **when** sandboxing is used:
|
||||
|
||||
@@ -162,7 +162,7 @@ Also consider agent workspace access inside the sandbox:
|
||||
- `workspaceAccess: "ro"` mounts the agent workspace read-only at `/agent` (disables `write`/`edit`)
|
||||
- `workspaceAccess: "rw"` mounts the agent workspace read/write at `/workspace`
|
||||
|
||||
Important: `agent.elevated` is an explicit escape hatch that runs bash on the host. Keep `agent.elevated.allowFrom` tight and don’t enable it for strangers.
|
||||
Important: `agent.elevated` is a **global**, sender-based escape hatch that runs bash on the host. Keep `agent.elevated.allowFrom` tight and don’t enable it for strangers. See [Elevated Mode](/tools/elevated).
|
||||
|
||||
## Per-agent access profiles (multi-agent)
|
||||
|
||||
|
||||
@@ -114,6 +114,7 @@ Look for `AllowFrom: ...` in the output.
|
||||
**Check 2:** For group chats, is mention required?
|
||||
```bash
|
||||
# The message must match mentionPatterns or explicit mentions; defaults live in provider groups/guilds.
|
||||
# Multi-agent: `routing.agents.<agentId>.mentionPatterns` overrides global patterns.
|
||||
grep -n "routing\\|groupChat\\|mentionPatterns\\|whatsapp\\.groups\\|telegram\\.groups\\|imessage\\.groups\\|discord\\.guilds" \
|
||||
"${CLAWDBOT_CONFIG_PATH:-$HOME/.clawdbot/clawdbot.json}"
|
||||
```
|
||||
|
||||
@@ -169,6 +169,14 @@ The filtering order is:
|
||||
Each level can further restrict tools, but cannot grant back denied tools from earlier levels.
|
||||
If `routing.agents[id].sandbox.tools` is set, it replaces `agent.sandbox.tools` for that agent.
|
||||
|
||||
### Elevated Mode (global)
|
||||
`agent.elevated` is **global** and **sender-based** (per-provider allowlist). It is **not** configurable per agent.
|
||||
|
||||
Mitigation patterns:
|
||||
- Deny `bash` for untrusted agents (`routing.agents[id].tools.deny: ["bash"]`)
|
||||
- Avoid allowlisting senders that route to restricted agents
|
||||
- Disable elevated globally (`agent.elevated.enabled: false`) if you only want sandboxed execution
|
||||
|
||||
---
|
||||
|
||||
## Migration from Single Agent
|
||||
|
||||
@@ -138,6 +138,7 @@ Example “single server, only allow me, only allow #help”:
|
||||
Notes:
|
||||
- `requireMention: true` means the bot only replies when mentioned (recommended for shared channels).
|
||||
- `routing.groupChat.mentionPatterns` also count as mentions for guild messages.
|
||||
- Multi-agent override: `routing.agents.<agentId>.mentionPatterns` takes precedence.
|
||||
- If `channels` is present, any channel not listed is denied by default.
|
||||
|
||||
### 6) Verify it works
|
||||
|
||||
@@ -68,6 +68,7 @@ Groups:
|
||||
- `imessage.groupPolicy = open | allowlist | disabled`.
|
||||
- `imessage.groupAllowFrom` controls who can trigger in groups when `allowlist` is set.
|
||||
- Mention gating uses `routing.groupChat.mentionPatterns` (iMessage has no native mention metadata).
|
||||
- Multi-agent override: `routing.agents.<agentId>.mentionPatterns` takes precedence.
|
||||
|
||||
## How it works (behavior)
|
||||
- `imsg` streams message events; the gateway normalizes them into the shared provider envelope.
|
||||
|
||||
@@ -93,4 +93,5 @@ Provider options:
|
||||
|
||||
Related global options:
|
||||
- `routing.groupChat.mentionPatterns` (Signal does not support native mentions).
|
||||
- Multi-agent override: `routing.agents.<agentId>.mentionPatterns` takes precedence.
|
||||
- `messages.responsePrefix`.
|
||||
|
||||
@@ -251,6 +251,7 @@ Slack tool actions can be gated with `slack.actions.*`:
|
||||
|
||||
## Notes
|
||||
- Mention gating is controlled via `slack.channels` (set `requireMention` to `true`); `routing.groupChat.mentionPatterns` also count as mentions.
|
||||
- Multi-agent override: `routing.agents.<agentId>.mentionPatterns` takes precedence.
|
||||
- Reaction notifications follow `slack.reactionNotifications` (use `reactionAllowlist` with mode `allowlist`).
|
||||
- Bot-authored messages are ignored by default; enable via `slack.allowBots` or `slack.channels.<id>.allowBots`.
|
||||
- For the Slack tool, reaction removal semantics are in [/tools/reactions](/tools/reactions).
|
||||
|
||||
@@ -66,6 +66,7 @@ group messages, so use admin if you need full visibility.
|
||||
## How it works (behavior)
|
||||
- Inbound messages are normalized into the shared provider envelope with reply context and media placeholders.
|
||||
- Group replies require a mention by default (native @mention or `routing.groupChat.mentionPatterns`).
|
||||
- Multi-agent override: `routing.agents.<agentId>.mentionPatterns` takes precedence.
|
||||
- Replies always route back to the same Telegram chat.
|
||||
- Long-polling uses grammY runner with per-chat sequencing; overall concurrency is capped by `agent.maxConcurrent`.
|
||||
|
||||
@@ -279,5 +280,6 @@ Provider options:
|
||||
|
||||
Related global options:
|
||||
- `routing.groupChat.mentionPatterns` (mention gating patterns).
|
||||
- `routing.agents.<agentId>.mentionPatterns` overrides for multi-agent setups.
|
||||
- `commands.native`, `commands.text`, `commands.useAccessGroups` (command behavior).
|
||||
- `messages.responsePrefix`, `messages.ackReaction`, `messages.ackReactionScope`.
|
||||
|
||||
@@ -170,6 +170,7 @@ Recommended for personal numbers:
|
||||
- `whatsapp.groups` (group allowlist + mention gating defaults; use `"*"` to allow all)
|
||||
- `whatsapp.actions.reactions` (gate WhatsApp tool reactions).
|
||||
- `routing.groupChat.mentionPatterns`
|
||||
- Multi-agent override: `routing.agents.<agentId>.mentionPatterns` takes precedence.
|
||||
- `routing.groupChat.historyLimit`
|
||||
- `messages.messagePrefix` (inbound prefix)
|
||||
- `messages.responsePrefix` (outbound prefix)
|
||||
|
||||
@@ -10,6 +10,14 @@ read_when:
|
||||
- Directive forms: `/elevated on`, `/elevated off`, `/elev on`, `/elev off`.
|
||||
- Only `on|off` are accepted; anything else returns a hint and does not change state.
|
||||
|
||||
## What it controls (and what it doesn’t)
|
||||
- **Global availability gate**: `agent.elevated` is global (not per-agent). If disabled or sender not allowlisted, elevated is unavailable everywhere.
|
||||
- **Per-session state**: `/elevated on|off` sets the elevated level for the current session key.
|
||||
- **Inline directive**: `/elevated on` inside a message applies to that message only.
|
||||
- **Groups**: In group chats, elevated directives are only honored when the agent is mentioned.
|
||||
- **Host execution**: elevated runs `bash` on the host (bypasses sandbox).
|
||||
- **Tool policy still applies**: if `bash` is denied by tool policy, elevated cannot be used.
|
||||
|
||||
## Resolution order
|
||||
1. Inline directive on the message (applies only to that message).
|
||||
2. Session override (set by sending a directive-only message).
|
||||
|
||||
@@ -43,6 +43,7 @@ Notes:
|
||||
- Returns `status: "running"` with a `sessionId` when backgrounded.
|
||||
- Use `process` to poll/log/write/kill/clear background sessions.
|
||||
- If `process` is disallowed, `bash` runs synchronously and ignores `yieldMs`/`background`.
|
||||
- `elevated` is gated by `agent.elevated` (global sender allowlist) and runs on the host.
|
||||
|
||||
### `process`
|
||||
Manage background bash sessions.
|
||||
|
||||
@@ -7,7 +7,9 @@ read_when:
|
||||
# Slash commands
|
||||
|
||||
Commands are handled by the Gateway. Send them as a **standalone** message that starts with `/`.
|
||||
Inline text like `hello /status` is ignored.
|
||||
Inline text like `hello /status` is ignored for commands.
|
||||
|
||||
Directives (`/think`, `/verbose`, `/reasoning`, `/elevated`) are parsed even when inline and are stripped from the message before the model sees it.
|
||||
|
||||
## Config
|
||||
|
||||
|
||||
Reference in New Issue
Block a user