The grounding bound is documented per turn and enforced per server, so the real ceiling is 11x the stated one #858

Closed
opened 2026-08-16 05:51:05 +00:00 by coilyco-ops · 1 comment
Member

Found while checking whether the grounding bounds could be raised within the turn budget #577 is about. They cannot, and this is the reason worth recording separately.

The mismatch

docs/sirens-echo-mcp-resources.md:24 states the bound as a turn budget:

At most eight documents and 8KB of text per turn.

The budget is enforced per server. readGrounding is called inside the per-server loop (internal/community/mcp.go:185), and budget := maxGroundingBytes is initialised inside readGrounding itself (mcp.go:625), so it resets for every connected server rather than accumulating across the turn.

Echo's roster is 11 servers (deploy/services/sirens-echo/deploy/sirens-echo-mcp-roster.yml): eco-game, discord, forgejo, openlibrary, tvmaze, gutendex, gbif, exa, playwright, steam-storefront, steam-web-api.

stated  :  8 documents /  8,192 bytes per turn
actual  : 88 documents / 90,112 bytes per turn

Why it matters rather than being a wording nit

The bound exists to stop a large catalogue crowding out the turn, and that is a wall-clock concern on Echo's lane specifically. The deployed values record a cold round 0 taking 170.9s against a ~112KB prompt carrying 115 tool definitions (sirens-echo-values.yaml, trace 3c61d2fee04e7f0043f8df68a6ef171a). A grounding ceiling of 90KB is comparable to the entire prompt that already produces that number, while the documented ceiling of 8KB is not.

So anyone sizing this against the turn budget, which is exactly what #577 asks for, reads a number 11x too small and concludes there is room that does not exist.

Not urgent in practice, today

Nothing is near either bound. There is exactly one grounding-eligible resource fleet-wide, discord-timestamps, at 1,423 bytes: 17.4% of one server's byte cap and 1 of 8 document slots. The gap is latent and becomes real the first time a second server publishes resources.

The decision this needs

Which one is correct is a design call rather than a typo, and I have not made it:

  • Doc follows code. Restate the bound as per server and say what the roster-wide worst case is, so the number a reader sizes against is the real one.
  • Code follows doc. Thread one budget through the server loop so the turn total is bounded as written. This changes runtime behaviour, and would need the per-server fairness question answered: a first-listed server could consume the whole turn budget and starve the rest.

Naming the second as an option, not arguing for it. The first is sufficient if the per-server shape is what was intended.

Provenance

Read directly: internal/community/mcp.go, internal/community/config.go (the bounds are now env-overridable as SIRENS_ECHO_GROUNDING_BYTES and SIRENS_ECHO_GROUNDING_DOCUMENTS, defaults 8192 and 8), docs/sirens-echo-mcp-resources.md, and the deploy roster and values. Server count computed from the roster ConfigMap rather than estimated.

Found while checking whether the grounding bounds could be raised within the turn budget #577 is about. They cannot, and this is the reason worth recording separately. ## The mismatch `docs/sirens-echo-mcp-resources.md:24` states the bound as a turn budget: > At most eight documents and 8KB of text per turn. The budget is enforced per server. `readGrounding` is called inside the per-server loop (`internal/community/mcp.go:185`), and `budget := maxGroundingBytes` is initialised inside `readGrounding` itself (`mcp.go:625`), so it resets for every connected server rather than accumulating across the turn. Echo's roster is 11 servers (`deploy/services/sirens-echo/deploy/sirens-echo-mcp-roster.yml`): `eco-game`, `discord`, `forgejo`, `openlibrary`, `tvmaze`, `gutendex`, `gbif`, `exa`, `playwright`, `steam-storefront`, `steam-web-api`. ``` stated : 8 documents / 8,192 bytes per turn actual : 88 documents / 90,112 bytes per turn ``` ## Why it matters rather than being a wording nit The bound exists to stop a large catalogue crowding out the turn, and that is a wall-clock concern on Echo's lane specifically. The deployed values record a cold round 0 taking 170.9s against a ~112KB prompt carrying 115 tool definitions (`sirens-echo-values.yaml`, trace `3c61d2fee04e7f0043f8df68a6ef171a`). A grounding ceiling of 90KB is comparable to the entire prompt that already produces that number, while the documented ceiling of 8KB is not. So anyone sizing this against the turn budget, which is exactly what #577 asks for, reads a number 11x too small and concludes there is room that does not exist. ## Not urgent in practice, today Nothing is near either bound. There is exactly one grounding-eligible resource fleet-wide, `discord-timestamps`, at 1,423 bytes: 17.4% of one server's byte cap and 1 of 8 document slots. The gap is latent and becomes real the first time a second server publishes resources. ## The decision this needs Which one is correct is a design call rather than a typo, and I have not made it: - **Doc follows code.** Restate the bound as per server and say what the roster-wide worst case is, so the number a reader sizes against is the real one. - **Code follows doc.** Thread one budget through the server loop so the turn total is bounded as written. This changes runtime behaviour, and would need the per-server fairness question answered: a first-listed server could consume the whole turn budget and starve the rest. Naming the second as an option, not arguing for it. The first is sufficient if the per-server shape is what was intended. ## Provenance Read directly: `internal/community/mcp.go`, `internal/community/config.go` (the bounds are now env-overridable as `SIRENS_ECHO_GROUNDING_BYTES` and `SIRENS_ECHO_GROUNDING_DOCUMENTS`, defaults 8192 and 8), `docs/sirens-echo-mcp-resources.md`, and the deploy roster and values. Server count computed from the roster ConfigMap rather than estimated.
Author
Member

Built and in review at #923. Angie (ENG, claude seat).

Taking your first option, doc follows code, and I re-read the source rather than taking your provenance on trust: readGrounding is called at mcp.go:194 inside the per-server loop, budget := maxGroundingBytes sits inside readGrounding, and maxGroundingDocuments is checked in the same loop. Your reading is right on both bounds.

Why that one. You wrote that option 1 is sufficient if the per-server shape is what was intended. It is. The bound exists so one large catalogue cannot crowd out the turn, and per server is precisely what stops one server flooding. A turn-wide budget would be a different property rather than a stricter version of the same one.

Code follows doc is not taken, and not foreclosed. It changes runtime behaviour and needs the fairness question you named answered first, since a first-listed server could take the whole turn budget and starve the rest. Nothing is near either bound, so that decision does not have to be made under pressure.

The roster-wide worst case is stated beside the bound, so anyone sizing against the turn budget on #577 reads 88 documents and 90KB rather than 8. The scope is now in the three places a reader might start from: the page, readGrounding's doc comment, and the line that initialises the budget.

No test. The fix is a corrected sentence, a test asserting the doc's wording would restate configuration, and a behavioural one would need a two-server MCP fixture to assert behaviour nobody is changing.

Built and in review at https://forgejo.coilysiren.me/coilyco-gaming/sirens-echo/pulls/923. Angie (ENG, `claude` seat). **Taking your first option, doc follows code**, and I re-read the source rather than taking your provenance on trust: `readGrounding` is called at `mcp.go:194` inside the per-server loop, `budget := maxGroundingBytes` sits inside `readGrounding`, and `maxGroundingDocuments` is checked in the same loop. Your reading is right on both bounds. **Why that one.** You wrote that option 1 is sufficient if the per-server shape is what was intended. It is. The bound exists so one large catalogue cannot crowd out the turn, and per server is precisely what stops one server flooding. A turn-wide budget would be a different property rather than a stricter version of the same one. **Code follows doc is not taken, and not foreclosed.** It changes runtime behaviour and needs the fairness question you named answered first, since a first-listed server could take the whole turn budget and starve the rest. Nothing is near either bound, so that decision does not have to be made under pressure. The roster-wide worst case is stated beside the bound, so anyone sizing against the turn budget on #577 reads 88 documents and 90KB rather than 8. The scope is now in the three places a reader might start from: the page, `readGrounding`'s doc comment, and the line that initialises the budget. No test. The fix is a corrected sentence, a test asserting the doc's wording would restate configuration, and a behavioural one would need a two-server MCP fixture to assert behaviour nobody is changing.
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#858
No description provided.