Reusable method for the WATCH-triggered "fresh MCP/AI advisory -> variant/incomplete-fix within the dup window" lane. Distilled from 3 parity passes this session (redirect-clamp, bearer-audience, cross-client transport-reuse) across the official SDK family. Source/local only; no-auto-submit; operator files.
A fresh advisory lands on ONE MCP SDK (python/TS usually lead, since they are the reference impls). The sibling SDKs may share the bug un-ported = fresh, in-dup-window, undisclosed parity gap. This is one of the two realistic receipt paths left on the (otherwise saturated) MCP surface.
Confirm the seed advisory's publish date is within ~45d (the dup window). "Not in my catalog" != "fresh" - CVE-2026-25536 (cross-client leak) was new to my catalog but 8mo old = swept = WALK. Cheap date checks: gh api advisories/<GHSA> (published_at), or curl -s https://cveawg.mitre.org/api/cve/<CVE> (datePublished). If stale, STOP - the fix-wave has propagated and EV ~ 0.
Pin what the correct behavior is, at file:line/PR, in the fixed SDK. You are looking for the precise invariant the fix added (e.g. "token.resource must == server's own resource URL", "redirect must be same-origin before replaying POST body", "request-id map must be per-connection scoped"). The sibling is a candidate only if it lacks THIS specific invariant.
The single biggest EV filter. For each sibling SDK, determine whether it OWNS the vulnerable primitive or DELEGATES it: - Re-implementers (own the sink) = where parity bugs live. Observed: go-sdk, python-sdk, typescript-sdk ship their own server bearer middleware / transport / redirect handling. - Delegators (hand the primitive to the host framework) = almost always N/A, not a bug. Observed: csharp-sdk (forwards to ASP.NET Core JwtBearer), rust-sdk/rmcp (no server bearer auth; client-only OAuth), kotlin-sdk (Ktor Authentication plugin), mark3labs/mcp-go (forwards raw Authorization to the app). Rule of thumb from 3 passes: csharp/rust/kotlin/mcp-go WALK by delegation; go-sdk is the recurring re-implementer candidate; swift varies (fixed the bearer-audience check itself). Check, do not assume - but start by asking "does this SDK even own the sink?".
HAS-CHECK (safe) / MISSING-CHECK (candidate) / NO-OWNED-SINK=delegates (N/A) / ALREADY-FIXED-OR-DISCLOSED / BY-DESIGN. Read the actual function body; never infer from a tool/endpoint/struct name (anti-overclaim floor). Tell for a real candidate: the SDK ships the middleware/contract but the data structure cannot even EXPRESS the missing field (e.g. go-sdk TokenInfo has no Resource/Aud field), and sometimes the fix helper EXISTS but is unwired (go-sdk oauthex.MatchesResource).
Per candidate SDK, search its repo OPEN+CLOSED issues + open/merged PRs + its GHSA list (gh api repos/<org>/<repo>/security-advisories) + CVE + web, BY CLASS (the aud/resource/redirect/request-id terms), not just the GHSA id. A GHSA-empty result is NOT enough. During an active fix-wave, advisories land fast - re-verify at SEND time too (staging-to-file latency is a dup window). Any doubt -> "POSSIBLE-DUP, verify issues".
Parity bugs are usually deployment-conditional (bearer-audience needs shared-AS multi-resource; cross-client needs shared-instance reuse). State the precondition and downgrade honestly (Medium, not reflexive High). Red-team the by-design counter: a re-implementer can argue "that validation is the app's/callback's job" - it is only an SDK bug if the SDK ships the middleware+contract AND the reference SDKs (python/TS) decided it IS the SDK's responsibility (the parity argument). Surface this crux in the report; let the operator weigh it.