warnings is the last key in the response, so a truncating consumer destroys the caveats first and the rows arrive looking complete #304
Labels
No labels
burndown-2026-06
headless
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/eco-app#304
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
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?
Filed by Darren (director seat) at Kai's direction, 2026-08-15. Cross-cutting finding from coilyco-gaming/sirens-echo#449, filed on every MCP server in the portfolio. This repo is the confirmed instance rather than a speculative audit — the ordering was measured here.
The failure, concretely
Echo told a member:
The tool result it built that from carried its own caveat:
The surface said it searched 528 of 22,933 rows. The reply said none exists. It cost a day of investigation into a query path that was fine.
The mechanism, measured on this server
The consuming harness bounds tool results at a byte cap with a head slice — keep the front, discard the tail, append a byte-count notice:
This server's live response, fetched read-only during the #449 investigation, in key order:
So whenever an eco response exceeds the cap, its warnings are the first thing removed, deterministically. Not plausible, guaranteed by the ordering plus the slice direction. A truncated eco result reaches the model as rows with no caveat.
Two things make it worse than an ordinary truncation bug:
To be exact about scope: on the originating turn nothing was truncated. The filtered response was a few hundred bytes and the model saw the caveat and discarded it, which is a doctrine defect that stays open on sirens-echo#449. This issue is the other cause — the large-response case, which needs no model misbehaviour at all.
Relationship to the invariants already filed here
#266 (null never zero) and #267 (
limitbounds every array, truncation always warns) already cover three of the four rules from the other direction, and #267 is the reason this is tractable:get_crafting_atlasreturns roughly 45 KB atlimit=1becauselimitbounds one array of six. Those are the responses that overrun a consumer cap in the first place.Rule 1 is the new one and has no home yet:
If #267 lands and every array is bounded, responses arrive under the cap, nothing is cut, and the warnings survive because nothing removed them. That attacks it at the source. Rule 1 is the belt to that suspenders: it holds even when a response is large for a reason nobody anticipated, and it does not require the harness to learn what a warning means across servers that share no schema.
What to do here
warnings, and any other coverage or provenance field, ahead of the bulk payload in every tool response. Python dicts preserve insertion order andjson.dumpsfollows it, so this is a construction-order change rather than a schema change.fetchedAtISO,live,totalOffersandtotalStores, which already lead and should stay leading.Acceptance
Source: coilyco-gaming/sirens-echo#449 and its seven-comment thread, which establishes the head-slice mechanism and the per-profile cap difference. Related: #266, #267. The consumer-side doctrine half stays open on sirens-echo#449 and is not what this issue asks for.
headlessexist in this repo, one repo-scoped and one org-scoped, so the dispatch gate's vocabulary is ambiguous here #305headlessexist in this repo, one repo-scoped and one org-scoped, so the dispatch gate's vocabulary is ambiguous here #305