Skip to content

The MCP bridge's two platform-name sets are hand copies of the registry, and the pin that claims to hold them there cannot see a name that has LEFT it #13486

Description

@os-trump

Observation found while implementing #13350. No live drift exists today — all six names check out against the registry as of 7280f39e83. What is measured here is that the pin's guarantee is one direction narrower than the docblock's claim, so the drift would be silent if it ever happened.

Measured

packages/mcp/src/mcp-server-runtime.ts keeps two private literal sets:

PLATFORM_READ_ONLY_TOOL_NAMES   = list_objects, describe_object, query_records, get_record, aggregate_data
PLATFORM_DESTRUCTIVE_TOOL_NAMES = delete_field

Its docblock says of them:

Every name here is a tool the cloud AI runtime registers statically (PLATFORM_TOOLS_BY_PACKAGE in @objectstack/spec/system) … A sibling pin holds both sets to that registry, so the lists cannot drift back into folklore

The sibling pin is packages/mcp/src/mcp-tool-bridge-safety-annotations.test.ts, case "no tool outside PLATFORM_PROVIDED_TOOL_NAMES receives a hint it did not declare". It builds its bridged tools as [...PLATFORM_PROVIDED_TOOL_NAMES] plus a hardcoded stranger list, then asserts every annotated name is in the registry.

That direction is real and it is the useful one — a name added to a local set but never registered by the platform is caught. The other direction is not covered: if a name were removed from PLATFORM_TOOLS_BY_PACKAGE while staying in a local set, it would simply stop being one of the tools the test bridges. It is not in the registry, so it is not in platform; it is not in the hardcoded strangers list either; nothing drives it; annotated never contains it; the case stays green. Meanwhile safetyAnnotations would keep annotating it at runtime from a name the platform no longer registers — the exact "folklore" the sets exist to prevent.

Verified against the tree: all five read-only names and delete_field are present in PLATFORM_PROVIDED_TOOL_NAMES (size 30), so this is a gap in the guarantee, not a defect in the data.

Not the same shape as the world hint next to it

Worth recording because it explains why only these two sets are exposed. worldAnnotation (added by #13350) reads PLATFORM_PROVIDED_TOOL_NAMES directly, so its derivation and its pin share one source and a name leaving the registry simply stops being annotated — structurally immune. Only the two hand-copied safety sets carry this exposure.

Why it was not fixed in the #13350 PR

It fails the bounded-in-place test on the "mechanical, correct shape already pinned by existing evidence" condition. Closing it needs a design call that is not mechanical: either export the two private sets so a test can assert membership over their own contents (widening the module's surface for a test), or hard-code the six names in the test — which is a third hand list, i.e. the thing being complained about. Filed rather than guessed.

Suggested shape (not a decision)

Assert over the sets' own contents rather than over the registry's, so the iteration source is the thing that can drift. Whichever way the sets become reachable, the assertion is one line and the reverse control is free: drop a fabricated name into a set and the case must go red.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions