Thread-ownership summoning now admits the five allowlisted agents with no mention, so decide whether an agent-to-agent exchange should self-sustain #998

Open
opened 2026-08-19 00:35:25 +00:00 by coilyco-ops · 0 comments
Member

Deferred deliberately by Kai when #750 was turned on. Filing so the question has a home rather than being decided under stream pressure.

What is now live

#750 landed as 7f764c8 and is deployed: all three lanes run image ef41b63, which contains it, and the Dowel pod rolled at 2026-08-19T00:20Z. So an ordinary message in a thread the service opened now summons a turn, with no mention and no reply.

summonedLocally gained one clause, state-only and costing no REST call:

if threadOwnedBy(session, message.ChannelID, botID) {
    return true, false
}

#750's resolved spec states the consequence and accepts it: any member's message in a service-owned thread summons, including two members talking to each other, with no expiry.

The question this issue holds

That spec reasons about members. The Dowel lane's counterparties include other builders' agents, and its access policy enumerates five of them:

agents:
  allow:
    - "1498881840763895978"  # wuf
    - "1499098442306293942"  # snow
    - "1510318381943754812"  # alpha
    - "1511831826581160047"  # manish-cc
    - "1512584144587067422"  # elf

Inside a Dowel-owned thread, a message from any of those five now summons a turn with no mention. Dowel answers in that thread. Whether that answer summons them back is decided by their harnesses, which this repository does not control and did not change.

So the shape to consider is an exchange that sustains itself with no human in it, in a thread nobody is addressing, on a lane already carrying a 32.9s median turn (#932).

What already bounds it, so this is not unbounded

  • The agent gate is an allowlist, not a wildcard. agent.go rejects message.Author.Bot unless PermitsAgent matches, and the schema has no wildcard, so an arbitrary bot in the guild is refused before any of this. The exposure is those five accounts, not every bot present.
  • Dowel's own messages are dropped before the gate, so it cannot summon itself directly.
  • Rate limits and the pending cap still apply, which #750 names as the reason it treated the member case as throttled rather than unbounded. The same brakes apply here.

That is why this is a question worth thinking about rather than an incident. It is throttled, scoped to five known accounts, and reversible.

Options, none chosen

  • Ignore other bot accounts in the thread-ownership summon path only, keeping mention and reply-to-own-message working for agents, so nothing an agent deliberately addresses to Dowel is lost. This is the narrowest version and the one that keeps agent-to-agent interaction, which is the point of the format.
  • Require a mention or a reply from an agent author in every case, leaving thread-ownership summoning human-only.
  • A per-thread turn budget, or a cap on consecutive agent-authored turns with no human message between them. Costs state the summon path does not currently keep.
  • Change nothing, and rely on the allowlist plus rate limits.

Fastest levers if it does misbehave

Not a plan, just so they are written down before they are needed: emptying agents.allow in sirens-dowel-access-policy.yml stops every agent turn on the lane, and reverting 7f764c8 returns summoning to mention-and-reply. Both are config or a revert rather than new code.

Worth knowing when this is picked up

Related: #750 is the behaviour, #932 is the latency that makes an extra turn expensive, and #992 covers the fact that a non-summoning message currently leaves no operator-visible trace, which is what would make a loop hard to characterise after the fact.

Deferred deliberately by Kai when #750 was turned on. Filing so the question has a home rather than being decided under stream pressure. ## What is now live #750 landed as `7f764c8` and is **deployed**: all three lanes run image `ef41b63`, which contains it, and the Dowel pod rolled at 2026-08-19T00:20Z. So an ordinary message in a thread the service opened now summons a turn, with no mention and no reply. `summonedLocally` gained one clause, state-only and costing no REST call: ```go if threadOwnedBy(session, message.ChannelID, botID) { return true, false } ``` #750's resolved spec states the consequence and accepts it: any member's message in a service-owned thread summons, including two members talking to each other, with no expiry. ## The question this issue holds That spec reasons about **members**. The Dowel lane's counterparties include **other builders' agents**, and its access policy enumerates five of them: ```yaml agents: allow: - "1498881840763895978" # wuf - "1499098442306293942" # snow - "1510318381943754812" # alpha - "1511831826581160047" # manish-cc - "1512584144587067422" # elf ``` Inside a Dowel-owned thread, a message from any of those five now summons a turn with no mention. Dowel answers in that thread. Whether that answer summons them back is decided by **their** harnesses, which this repository does not control and did not change. So the shape to consider is an exchange that sustains itself with no human in it, in a thread nobody is addressing, on a lane already carrying a 32.9s median turn (#932). ## What already bounds it, so this is not unbounded * **The agent gate is an allowlist, not a wildcard.** `agent.go` rejects `message.Author.Bot` unless `PermitsAgent` matches, and the schema has no wildcard, so an arbitrary bot in the guild is refused before any of this. The exposure is those five accounts, not every bot present. * **Dowel's own messages are dropped before the gate**, so it cannot summon itself directly. * **Rate limits and the pending cap still apply**, which #750 names as the reason it treated the member case as throttled rather than unbounded. The same brakes apply here. That is why this is a question worth thinking about rather than an incident. It is throttled, scoped to five known accounts, and reversible. ## Options, none chosen * Ignore other bot accounts in the **thread-ownership summon path only**, keeping mention and reply-to-own-message working for agents, so nothing an agent deliberately addresses to Dowel is lost. This is the narrowest version and the one that keeps agent-to-agent interaction, which is the point of the format. * Require a mention or a reply from an agent author in every case, leaving thread-ownership summoning human-only. * A per-thread turn budget, or a cap on consecutive agent-authored turns with no human message between them. Costs state the summon path does not currently keep. * Change nothing, and rely on the allowlist plus rate limits. ## Fastest levers if it does misbehave Not a plan, just so they are written down before they are needed: emptying `agents.allow` in `sirens-dowel-access-policy.yml` stops every agent turn on the lane, and reverting `7f764c8` returns summoning to mention-and-reply. Both are config or a revert rather than new code. ## Worth knowing when this is picked up Related: #750 is the behaviour, #932 is the latency that makes an extra turn expensive, and #992 covers the fact that a non-summoning message currently leaves no operator-visible trace, which is what would make a loop hard to characterise after the fact.
Sign in to join this conversation.
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#998
No description provided.