The built-in backend guard's principal answers errScopeUnavailable, not a
nil principal, when an admin personal token's stored scopes all fail to
resolve (a scope's plugin was removed). MCPDispatch passes it through and
dispatch maps it to the fixed tool error "pier: the token's scopes no longer
grant this route" instead of claiming the administrator's account is
unknown or deactivated; the listing check still treats it as a refusal, not
as a failed check.
- a path field must be required in the reflected schema (boot error), and
a missing value, an empty, . or .. segment, or a / inside one segment is
a tool error before dispatch (A-WR-01, A-WR-02)
- a failed guard dispatch logs its cause and answers a fixed tool text;
only an invalid token and an unknown or deactivated account keep their
own fixed texts (A-WR-08)
- path and query scalars decode with UseNumber, so integers above 2^53
keep their digits (A-IN-04)
- the dispatched request carries the outer Host, X-Forwarded-Proto and
X-Forwarded-Host (A-IN-05)
- an embedded struct on a GET or DELETE tool fails boot (A-IN-07)
- a dispatch whose guard list or principal kind contradicts the tool's
guard is refused (A-IN-08)
- modules/pier: Host contract, mcp.* config, catalog compiled from
pact.HasMCP (prefixing, route binding, guard resolution, schema
reflection, annotations), per-request identity through the published
verifier and resolvers, built-in backend guard provider, in-process
dispatch with the bouncer marker, per-identity SDK server with the
per-request re-filter, stateful session router with rehydration over a
memory store, audit lines
- modules/surf/pier_on.go: the summercms_mcp hook adapting the router to
pier.Host; the untagged hello binary carries no SDK
- go.mod: go-sdk v1.8.0 and jsonschema-go v0.4.3 (decision note committed
before this change)
- TestPierTracerSmoke: SDK client lists and calls acme_echo end to end
through surf's compiled guard chain; README and root table row