feat: bound untrusted summons and serve multiple Discord contexts #82
No reviewers
Labels
No labels
move-to-repo
coilyco-bridge-deploy
move-to-repo
coilyco-flight-deck-agent-compose
move-to-repo
coilyco-gaming-eco-app
move-to-repo
coilysiren-inbox
move-to-repo
unknown
🔒⚠️📦⚠️🔒 SANDBOXED 🔒⚠️📦⚠️🔒
autonomy
async-consult
autonomy
epic
autonomy
headless
autonomy
live-collab
c#
priority
P0
priority
P1
priority
P2
priority
P3
priority
P4
role/ai
role/creator
role/design
role/director
role/engineer
role/exec
role/human
role/ops
role/qa
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
coilyco-gaming/sirens-echo!82
Loading…
Reference in a new issue
No description provided.
Delete branch "sirens-deep-admission-hardening"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Sirens Deep is being deployed into a Discord guild whose members the operator does not moderate. Three things blocked that, and a fourth set of defects surfaced while reading.
The deploy blocker
agent/sirens-deep.yamlhaschannel: "", andLoadConfigrequiredChannel == "#bots"whenever Discord was enabled. Sirens Deep could not start on Discord at all. The channel field is now the prompt's boundary label, and routing moves toDISCORD_CHANNEL_IDwhere deployment already owns it.Admission control
Every accepted turn costs an Agent Proxy completion and up to six MCP rounds, and nothing bounded it. The runtime queued every summon behind one execution slot with no bound, so a flood grew process memory and answered conversations that had moved on.
Adds per-user, per-context, and global token buckets plus a bounded pending queue at the shared turn boundary, so Discord and HTTP are governed by one policy.
3/30sper user,10/10sper guild,20/5sglobal, 8 pending - sized for a guild the operator does not moderate, and each tier is env-tunable oroff.Multiple Discord contexts
Scope was a single channel ID. It is now a channel list plus an optional guild allowlist, with opt-in direct messages, served by one process and one token. Each guild is one admission context, so one guild cannot spend another's budget. Every ID is validated as a snowflake at startup, so a channel name in place of an ID fails loudly.
HTTP authentication
POST /v1/turnwas unauthenticated and the deployment binds it to0.0.0.0. A shared secret is now required whenever the listener is not loopback, derived from the bind address rather than left to the operator to remember. Health routes stay open.Defects found while reading
QUEUE_TIMEOUTnow covers the wait andREQUEST_TIMEOUTstarts once the slot is held.Verification
pre-commit run --all-filesexit 0 across 23 hooks,go vet,go test -race ./..., andsirens-echo-policy-checkall pass. New unit coverage for the limiter (burst, refill, per-guild isolation, no-charge-on-later-denial, queue shedding and release, notify throttling, LRU bound), scope resolution across guilds and DMs, and the HTTP auth and admission edges.ward exec eval-echoagainst the real Agent Proxy has not been run and is the remaining gate.Note for review
X-Ward-Target-Repo: coilyco-gaming/sirens-echostays hard-coded inproxy.go, so turns from a foreign guild are attributed to this repo in the Agent Proxy audit trail. Left as-is deliberately, flagged as a decision rather than a default.New docs:
sirens-echo-admission.md,sirens-echo-contexts.md,sirens-echo-http.md. The repo's 80-line doc cap pushed the HTTP entrypoint out ofsirens-echo.mdinto its own page.