feat: summon on a mention of a role this account holds #924

Merged
coilysiren merged 1 commit from issue-866-role-mention-summons into main 2026-08-17 19:11:23 +00:00
Member

A member who @s the agent's role is addressing the agent. Only a mention of the account itself summoned.

What changed

mentionsBot now also reads MentionRoles off the Gateway payload against the roles Discord reports for this account in that guild.

  • @everyone does not summon. Its role id is the guild's and every member holds it, so an announcement would otherwise address every agent in the channel. This is the one part with a real blast radius, and it has its own test.
  • No privileged intent. Discord delivers this account's own member on GuildCreate without GUILD_MEMBERS. A state miss falls back to one GuildMember REST read written back to state, so a guild costs at most one lookup and then none.
  • The quiet path stays quiet. A message with no role mention returns before any lookup, asserted by a test whose session would panic on a REST call.

The access-policy question, which is the one #127 is about

Nothing downstream changes. A role mention is a message in a channel: same access.Evaluate, same allowlist, same admission budget keyed on origin.Key(). That is what separates this from the slash-command path, which bypasses the mention gate by construction.

docs/access-policy.reference.yaml states that a reader must be able to enumerate every summon path from it rather than from the code, and it listed six. It now lists seven. Leaving it would have made that file read as authoritative while being incomplete, which is the failure #127 describes.

Tests

rolemention_test.go: a held role summons, another role does not, @everyone does not, and an ordinary message reads no member.

Mutation: removing the @everyone guard fails TestAnEveryoneMentionDoesNotSummon. Verified.

just gate PASS.

closes #866

A member who @s the agent's role is addressing the agent. Only a mention of the account itself summoned. ## What changed `mentionsBot` now also reads `MentionRoles` off the Gateway payload against the roles Discord reports for this account in that guild. * **`@everyone` does not summon.** Its role id is the guild's and every member holds it, so an announcement would otherwise address every agent in the channel. This is the one part with a real blast radius, and it has its own test. * **No privileged intent.** Discord delivers this account's own member on `GuildCreate` without `GUILD_MEMBERS`. A state miss falls back to one `GuildMember` REST read written back to state, so a guild costs at most one lookup and then none. * **The quiet path stays quiet.** A message with no role mention returns before any lookup, asserted by a test whose session would panic on a REST call. ## The access-policy question, which is the one #127 is about **Nothing downstream changes.** A role mention is a message in a channel: same `access.Evaluate`, same allowlist, same admission budget keyed on `origin.Key()`. That is what separates this from the slash-command path, which bypasses the mention gate by construction. `docs/access-policy.reference.yaml` states that a reader must be able to enumerate every summon path from it rather than from the code, and it listed six. It now lists seven. Leaving it would have made that file read as authoritative while being incomplete, which is the failure #127 describes. ## Tests `rolemention_test.go`: a held role summons, another role does not, `@everyone` does not, and an ordinary message reads no member. Mutation: removing the `@everyone` guard fails `TestAnEveryoneMentionDoesNotSummon`. Verified. `just gate` PASS. closes #866
feat: summon on a mention of a role this account holds
All checks were successful
ci / image-build (pull_request) Successful in 32s
ci / test (pull_request) Successful in 1m8s
ci / publish-echo-image (pull_request) Has been skipped
ci / publish-observed (pull_request) Has been skipped
e74a13f194
A member who @s the agent's role is addressing the agent, and only a mention
of the account itself summoned. mentionsBot now also reads MentionRoles off
the Gateway payload against the roles Discord reports for this account in that
guild.

@everyone does not summon. Its role id is the guild's and every member holds
it, so an announcement would otherwise address every agent in the channel.

No privileged intent. Discord delivers this account's own member on
GuildCreate without the members intent, and a state miss falls back to one
REST read written back to state, so a guild costs at most one lookup. A
message with no role mention makes no lookup at all.

Nothing downstream changes, which is what separates this from the slash
command path on #127. A role mention is a message in a channel and takes the
same access policy, allowlist, and admission budget a direct mention takes.

docs/access-policy.reference.yaml enumerates every summon path and now names
this one, or it would read as authoritative while being incomplete.

closes #866

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: Kai Siren <coilysiren@gmail.com>
Co-authored-by: Claude <noreply@anthropic.com>
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
coilyco-gaming/sirens-echo!924
No description provided.