Describe the bug
src/seps/sep-2640.yaml is extracted against SEP commit a3e147ca2710, taken on 2026-08-25 while the CM vote was still open. The file's own provenance header says another pass is expected: "Because the SEP is mid-vote, expect one more pass at the CM-stamped head."
SEP-2640 was marked Accepted on 2026-09-03 (d6b31a03) and Final on 2026-09-11 (8075db4a). Four commits changed the SEP text after the extraction point, and the yaml has not moved since #330 merged. Three things are wrong as a result:
- Twelve rows quote sentences the SEP no longer contains. A copy-editing pass (
582d814a) replaced em-dashes with commas, colons and parentheses throughout. No requirement changed meaning, but the quoted text: no longer appears in the published document.
- One normative requirement has no row.
8079d781 added a paragraph to Skill Format: "In the event that the Agent Skills specification changes in a backwards incompatible way, clients MUST honor any backwards compatibility mechanisms provided by the Agent Skills specification and SHOULD continue to support the Agent Skills specification as it existed prior to any incompatible change." Neither half is declared.
- Two capability rows quote superseded wording.
fd72d3f1 reworded Capability Declaration: the declaration is now located in "the extensions field of their capabilities" rather than "their initialize response", and the resources-capability requirement is stated there outright instead of being derived from Dependencies. sep-2640-capability-declaration-inline and sep-2640-capability-requires-resources both still quote the old text.
Separately, and true before any of the above, the header's own coverage counts do not match the file.
To Reproduce
-
Fetch both revisions of the SEP:
gh api repos/modelcontextprotocol/modelcontextprotocol/contents/seps/2640-skills-extension.md?ref=a3e147ca2710 --jq .content | base64 -d > old.md
gh api repos/modelcontextprotocol/modelcontextprotocol/contents/seps/2640-skills-extension.md?ref=main --jq .content | base64 -d > new.md
-
Count rows whose text: no longer appears in the Final document:
python3 - <<'PY'
import yaml, re
norm = lambda s: re.sub(r'\s+', ' ', s).strip()
spec = norm(open('new.md').read())
old = norm(open('old.md').read())
rows = yaml.safe_load(open('src/seps/sep-2640.yaml'))['requirements']
drift = [r for r in rows if r.get('text')
and norm(r['text']) not in spec and norm(r['text']) in old]
print(len(drift), "rows quote the 08-25 text but not the Final text")
for r in drift: print(" ", r.get('check') or '[excluded]')
PY
-
Confirm the missing requirement: grep -c "backwards compatibility mechanisms" src/seps/sep-2640.yaml returns 0, while the same grep against new.md returns 1.
-
Compare the header's declared counts against a real run:
npm run build
# run the three server scenarios against any SDK, then:
npx tsx src/index.ts traceability --results <results-dir>
Expected behavior
- Every row's
text: quotes the SEP as published, so a reader can find the sentence a check is derived from. Step 2 should print 0.
- Every RFC 2119 requirement in the SEP has either a declared row or an
excluded: row saying why a harness cannot observe it.
- The header's coverage counts match what
traceability reports.
Logs
Step 2, against the yaml as it stands:
12 rows quote the 08-25 text but not the Final text
sep-2640-nested-skills-permitted
sep-2640-skills-list-entry-atomic
sep-2640-enumeration-scheme-uniform
sep-2640-host-disambiguate-listing-collision
sep-2640-entry-resources-required
sep-2640-resources-complete
sep-2640-resources-size-required
sep-2640-skills-get-entry-shape
sep-2640-skills-get-unknown-uri-invalid-params
sep-2640-host-no-prefetch
sep-2640-directory-read-invalid-params
[excluded] (stale-entry recovery presentation)
Header counts against a traceability run:
|
header claims |
actual |
| declared checks |
89 |
90 |
| excluded rows |
7 |
8 |
| emitted by the three server scenarios |
40 |
42 |
| untested |
49 |
48 |
Additional context
The four commits between the extraction point and Final are d6b31a03 (Accepted), 8075db4a (Final), fd72d3f1 (capability wording), 8079d781 (backward-compatibility requirement), plus 582d814a (copy-editing) and b6182df0 / f56f204f, which moved the design-history links from experimental-ext-skills to ext-skills/docs/archive.
One judgment call worth a maintainer's opinion: the two backward-compatibility halves both condition on a breaking revision of the Agent Skills specification that does not yet exist. There is nothing for a harness to present and nothing for a client to honor, so excluded: seems right, but untested checks are defensible if you would rather they stayed visible.
I have this written already as #511, which I opened before reading CONTRIBUTING.md's "open an issue first" — filing this after the fact rather than pretending the order was different. Happy to close either one if you would rather discuss before reviewing a diff.
On what this was and was not checked against. The change cannot move any implementation's score. Matching is r.check against the emitted check-ID set (src/traceability/index.ts:93); text: is carried into the manifest for display only; and the two added rows are excluded:, so they carry no check ID at all. No scenario file is touched.
So what I ran is a regression check, not the cross-implementation validation #330 needed: the three server scenarios against mcpkit examples/skills report 45 pass / 0 fail / 0 warn, unchanged before and after, confirming the yaml still parses and the scenarios still load. I also broke the fixture deliberately — a SKILL.md whose name no longer matches its URI's final segment — and watched the suite go red, then green on restore, which confirms it still grades rather than passing vacuously.
Happy to run it against the TypeScript, Go and C# SDKs as #330 was if you would rather see that, but I do not think it would tell you anything: with no check ID moving and no scenario changed, three more green runs are guaranteed by construction rather than earned. Say the word if you disagree — you know better than I do whether the suite has surprised you this way before.
One downstream effect. The two added excluded: rows change the row counts, so src/seps/traceability.json goes stale and the refresh workflow will open its usual follow-up PR. Nothing fails, but it is easier to expect than to explain.
Describe the bug
src/seps/sep-2640.yamlis extracted against SEP commita3e147ca2710, taken on 2026-08-25 while the CM vote was still open. The file's own provenance header says another pass is expected: "Because the SEP is mid-vote, expect one more pass at the CM-stamped head."SEP-2640 was marked Accepted on 2026-09-03 (
d6b31a03) and Final on 2026-09-11 (8075db4a). Four commits changed the SEP text after the extraction point, and the yaml has not moved since #330 merged. Three things are wrong as a result:582d814a) replaced em-dashes with commas, colons and parentheses throughout. No requirement changed meaning, but the quotedtext:no longer appears in the published document.8079d781added a paragraph to Skill Format: "In the event that the Agent Skills specification changes in a backwards incompatible way, clients MUST honor any backwards compatibility mechanisms provided by the Agent Skills specification and SHOULD continue to support the Agent Skills specification as it existed prior to any incompatible change." Neither half is declared.fd72d3f1reworded Capability Declaration: the declaration is now located in "theextensionsfield of their capabilities" rather than "theirinitializeresponse", and theresources-capability requirement is stated there outright instead of being derived from Dependencies.sep-2640-capability-declaration-inlineandsep-2640-capability-requires-resourcesboth still quote the old text.Separately, and true before any of the above, the header's own coverage counts do not match the file.
To Reproduce
Fetch both revisions of the SEP:
Count rows whose
text:no longer appears in the Final document:Confirm the missing requirement:
grep -c "backwards compatibility mechanisms" src/seps/sep-2640.yamlreturns 0, while the same grep againstnew.mdreturns 1.Compare the header's declared counts against a real run:
Expected behavior
text:quotes the SEP as published, so a reader can find the sentence a check is derived from. Step 2 should print0.excluded:row saying why a harness cannot observe it.traceabilityreports.Logs
Step 2, against the yaml as it stands:
Header counts against a traceability run:
Additional context
The four commits between the extraction point and Final are
d6b31a03(Accepted),8075db4a(Final),fd72d3f1(capability wording),8079d781(backward-compatibility requirement), plus582d814a(copy-editing) andb6182df0/f56f204f, which moved the design-history links fromexperimental-ext-skillstoext-skills/docs/archive.One judgment call worth a maintainer's opinion: the two backward-compatibility halves both condition on a breaking revision of the Agent Skills specification that does not yet exist. There is nothing for a harness to present and nothing for a client to honor, so
excluded:seems right, but untested checks are defensible if you would rather they stayed visible.I have this written already as #511, which I opened before reading
CONTRIBUTING.md's "open an issue first" — filing this after the fact rather than pretending the order was different. Happy to close either one if you would rather discuss before reviewing a diff.On what this was and was not checked against. The change cannot move any implementation's score. Matching is
r.checkagainst the emitted check-ID set (src/traceability/index.ts:93);text:is carried into the manifest for display only; and the two added rows areexcluded:, so they carry no check ID at all. No scenario file is touched.So what I ran is a regression check, not the cross-implementation validation #330 needed: the three server scenarios against mcpkit
examples/skillsreport 45 pass / 0 fail / 0 warn, unchanged before and after, confirming the yaml still parses and the scenarios still load. I also broke the fixture deliberately — aSKILL.mdwhosenameno longer matches its URI's final segment — and watched the suite go red, then green on restore, which confirms it still grades rather than passing vacuously.Happy to run it against the TypeScript, Go and C# SDKs as #330 was if you would rather see that, but I do not think it would tell you anything: with no check ID moving and no scenario changed, three more green runs are guaranteed by construction rather than earned. Say the word if you disagree — you know better than I do whether the suite has surprised you this way before.
One downstream effect. The two added
excluded:rows change the row counts, sosrc/seps/traceability.jsongoes stale and the refresh workflow will open its usual follow-up PR. Nothing fails, but it is easier to expect than to explain.