Files
pad/internal/server
xarmian 793fad959c docs(mcp): the reason given for the protocol restriction was false — replace it with the true one (TASK-2977) (#1312)
TASK-2977 step 1 restricted the remote transport to the handshake era
and gave this reason: pad_set_workspace pins a session default workspace
that the stateless era has nowhere to keep, so pad "is not known to be
able to serve" that era. It is plausible and it is false for THIS
transport, and I wrote it reasoning from the tool's purpose rather than
from its remote behaviour.

cmd/pad builds the cloud dispatcher with a SHARED workspace state whose
ResolveDefault() returns "" by construction — BUG-1865, the cross-user
workspace bleed — so the pin is recorded and never consulted here.
Resolution on /mcp is the explicit workspace argument, else a default
derived per request from the caller's own OAuth identity and token
allow-list. Every input comes from the request. This transport has been
stateless with respect to workspace resolution since that bug was fixed,
and the fix for a cross-user bug turns out to be most of the work a
stateless era would need.

THE TRUE REASON IS BETTER AND WAS ONE FILE AWAY. The
mcp-active-sessions gauge is keyed on the Mcp-Session-Id header, and the
generate-only session-id manager at this transport's call site exists so
that header is always minted and the gauge stays observable (PR #400
round 1). SEP-2567 REMOVES session IDs in 2026-07-28 — a server serving
that revision never mints or echoes one — so in that era nothing pad
mints is available to key on.

Ruled day 62: that is an accepted cost, not a blocker, and it is
recorded where the key is CHOSEN rather than only where the era is
refused — middleware_mcp_session.go now carries the obligation on
whoever opens that era to re-key the gauge first, and says why the era's
arrival is exactly the moment a silently-flat gauge gets read as "no MCP
traffic" instead of "no measurement".

The superseded reason is kept in the comment as superseded, four lines
of it, because the false reason is the PLAUSIBLE one: the next person to
reason about the stateless era from pad_set_workspace's name will reach
for it, and the comment now meets them with the shared-state mechanism
instead.

TWO CODEX ROUNDS, TWO FINDINGS, both about this change's own prose and
both verified in the code before accepting:

  - The server-package comment named mcp.ServedProtocolVersions as a
    symbol. It is not reachable from there — internal/mcp imports
    internal/server and not the reverse, which is also why the transport
    reaches the router as a plain http.Handler. Named by path now, with
    the direction stated.

  - "Modern-era traffic would be invisible to the gauge" was
    OVERSTATED, which is this unit's own defect class arriving inside
    the fix for it. trackMCPSession resolves the id from the response
    header and FALLS BACK to the request header, so a modern-era client
    that volunteers an Mcp-Session-Id is still tracked. The accurate
    claim, now in both files: the gauge stops depending on anything pad
    mints and starts depending on whether clients keep sending a header
    the spec removed — under-counting by a margin nobody controls,
    rather than a flat zero.

Comment-only; no behaviour changes. The restriction, its four tests and
the derived version set are untouched.

Claude-Session: https://claude.ai/code/session_01GqaEDuCtRiSJfa7eppWecn
2026-09-09 20:35:44 -04:00
..