Freeze the conformance requirement set per spec revision - #443
Open
felixweinberger wants to merge 1 commit into
Open
Freeze the conformance requirement set per spec revision#443felixweinberger wants to merge 1 commit into
felixweinberger wants to merge 1 commit into
Conversation
There is no way to answer "which scenarios must my implementation pass to conform to spec revision X". The suite accumulates scenarios continuously, so the set an implementation is measured against keeps growing after the revision has shipped, and it can drop below 100% while standing still. --spec-version does not answer it either: it filters on which revision a scenario targets, not on when the scenario became a requirement, so a scenario merged after a release is indistinguishable from one that existed at it. Add requirements/<revision>.yaml, naming the scenarios a revision requires, fixed when it shipped. `--requirements 2026-07-28` on the client, server and tier-check commands runs exactly that set, and `list --requirements` prints it. Passing no flag keeps today's behaviour of running everything, so the suite stays the place completeness lives. A requirement set covers the two roles the specification defines: an MCP server acting as an OAuth resource server, and an MCP client acting as an OAuth client. It covers no authorization-server scenarios, because the specification puts authorization server implementation beyond its own scope, so those scenarios serve people deploying an authorization server rather than implementations of MCP itself. A set that names an authorization section is rejected with that reason. Scenarios a revision runs without scoring go under not_scored, each with the leg that runs it and why it does not count. Extensions are optional by definition, and SEP-1730 says so; a scenario added after the revision shipped is one no implementation could have been passing. Both still run and both appear in the report with their reason, so a failing extension stays visible without moving a pass rate. Promoting an entry into the required lists stays a deliberate, reviewable change, which is how the suite grows without retroactively failing anyone. The 2026-07-28 set is generated from 0.2.0-alpha.10, published the day before that revision shipped, minus the scenarios pending in it. Reported scenario names are now canonical rather than the timestamped result-directory spelling, so a name in a report matches the same scenario in `list` and in a requirement set. This is the project's contract and lives here. It is the opposite of an expected-failures baseline, which lives in an implementation's own repository and records what that implementation knows it fails, so a baselined failure is still a failure against a requirement set.
commit: |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds
requirements/<revision>.yaml, a frozen list of the scenarios a specrevision requires, and a
--requirements <revision>flag that runs exactly thatset.
Motivation and Context
Today there is no way to answer "which scenarios must my implementation pass to
conform to the spec released on 2026-07-28". The suite accumulates scenarios
continuously, so the set an implementation is measured against keeps growing
after the revision has shipped.
typescript-sdk is the live case.
json-schema-2020-12-preservationmerged on2026-07-31 (#335), three days after the 2026-07-28 spec shipped and four days
after
0.2.0-alpha.10was published. typescript-sdk pins alpha.10, so it hasnever been able to run that scenario. On the same commit it passes 100% measured
against alpha.10 and less than 100% measured against
main.That matters because SEP-1730 puts Tier 1 at exactly 100% and relegates Tier 1 to
Tier 2 when any conformance test fails for four weeks. A scenario added after a
release starts a demotion clock against an implementation that did nothing wrong
and changed nothing.
--spec-versiondoes not solve this. It filters on which revision a scenariotargets, not on when the scenario became a requirement, so a post-release
addition tagged
[2025-11-25, 2026-07-28]is indistinguishable from one thatexisted at ship.
What this adds
--requirements <revision>on theclient,server,listandtier-checkcommands. It replaces
--suiteand--spec-version, and passing it witheither is an error rather than a silent precedence rule.
A requirement set covers the two roles the specification defines: an MCP server
acting as an OAuth resource server, and an MCP client acting as an OAuth
client. It covers no authorization-server scenarios, because the spec puts
authorization server implementation
beyond its own scope
("The implementation details of the authorization server are beyond the scope
of this specification"), so those scenarios serve people deploying an
authorization server rather than implementations of MCP itself. A set naming an
authorizationsection is rejected with that reason, since the scenarios carrya dated tag for every revision and so read as core spec at a glance.
Passing nothing keeps today's behaviour and runs everything, so the suite stays
the place completeness lives.
Scenarios a revision runs without scoring go under
not_scored, each carryingthe leg that runs it and why it does not count:
extensionadded-after-releaseBoth still run and both appear in the report with their reason, so a failing
extension stays visible without moving a pass rate. Promoting an entry into the
required lists stays a deliberate, reviewable change, which is how the suite
grows without retroactively failing anyone.
tier-checkreportsrequirements_revisionand scores both legs against theset, replacing the spec-version matrix with a plain required/passed summary.
The
2026-07-28set is generated from0.2.0-alpha.10, published the day beforethat revision shipped, minus the scenarios pending in that release (SEP-1730
scores "applicable required tests" only). Older revisions are deliberately not
manifested: reconstructing them means archaeology on version-bump commits for
much less value, and with no flag nothing changes.
A requirement set is this project's contract, which is why it lives here and why
--requirementstakes a revision rather than a path. It is the opposite of anexpected-failures baseline, which lives in an
implementation's own repository and records what that implementation knows it
fails. A baselined failure is still a failure against a requirement set, so the
two are independent inputs and both can be passed in the same run.
How Has This Been Tested?
Driven end to end against the typescript-sdk everything server at
main(cc4b41617):tier-check --requirements 2026-07-28reports Server 37/37 and Client 32/32,both 100%, alongside
Not scored (17 run, 14 failing), and conformance dropsoff the Tier 1 blocker list, leaving only
triageandp0_resolution. Withoutthe flag the same commit scores Client: Core 4/5, failing on the post-release
scenario.
server_conformancedoes appear in the blockers, with the 10 extensionfailures still held apart. The split suppresses the right failures and only
those.
server --requirements 2026-07-28runs 37 scenarios, 120 checks, 0 failed.list --requirements 2026-07-28prints the 69-scenario set plus what is runwithout being scored.
--spec-versionor--suite,an unknown revision, a path-shaped revision, and an empty value each exit 1
with a message naming the problem.
this build provides, so a rename or removal cannot silently shrink what
conformance means.
Breaking Changes
None. The flag is opt-in and the default path is unchanged.
Types of changes
Checklist
Additional context
Two things deliberately left out, happy to add either:
currently a comment in the file plus review. A test pinning each shipped file's
hash would enforce it, at the cost of a deliberate two-step when a set does
need amending.
2026-07-28draft classification.DRAFT_PROTOCOL_VERSIONis still
2026-07-28even though the spec repo has publishedschema/2026-07-28. Promoting it shifts theactivesuite for every SDK, so itbelongs in its own change. A requirement set does not depend on it either way.