The dangerous change is the one nobody made on purpose. Three kinds are watched,
and they are watched differently because they fail differently.
An MCP server that was benign and turned malicious between two listTools()
calls. The SDK hashes the manifest, so a changed tool surface is detected on the
next session rather than discovered afterwards.
A digest catches a server that changed. It cannot catch a server that was
malicious the first time anybody saw it, because the first manifest becomes the
baseline, whatever it says.
Two detections work without a baseline, and both need the whole workspace in
view rather than one session, which is why they live in the platform and not in
an SDK:
Typosquatting. github-mcp sitting beside the real github_mcp, or a name
using an en dash where the real one uses a hyphen. That is a relationship
between servers, so it can only be computed where every server is visible.
Capability incidents. A tool whose declared capability does not match what
it is doing.
Models: provenance binding
The model an agent runs on is reported by the SDK and bound into the record. A
version change is visible without anybody filing a ticket about it, and a
certificate pins the provenance version it was issued
against, so a model change invalidates the clearance rather than quietly
outliving it.
Behaviour: the one that used to be invisible
An agent whose model version and tool manifest are both unchanged, but whose
decisions have shifted.
That is what a prompt edit or a new retrieval corpus produces without touching
anything else. It was the gap: two kinds of drift detected, and the one that a
change-management process is least likely to catch was not.
See Behaviour.
Why three mechanisms rather than one
Because a single “has this agent changed” flag would be true constantly and
actionable never. Tools, model and behaviour have different owners, different
remedies and different urgency, and the point of separating them is that the
alert tells you which conversation to have.