fix: address Copilot review round 9 on #2248
**Verification reads were unbounded.** The 512-entry limit is checked by `checkSkillConformance` — as a warning, since the SEP makes it an interoperability bound rather than a MUST — but checking it constrains nothing, so a hostile server advertising a million entries had the tool perform a million sequential reads after the report already knew the manifest was over. Capped at `SKILL_MAX_RESOURCE_ENTRIES`, with the finding still reported so bounding the work does not silence the reason it was unnecessary. `manifestListsSelf` is computed over the READ slice, so a self-entry pushed past the cap still reaches the fallback: the frontmatter comparison is mandatory and must not be lost to a limit that bounds other files. **A malformed skill URI still produced a directory root.** `skillUriIdentity` falls back to the raw string, so `not a uri/SKILL.md` yielded the root `not a uri` and enabled the Directory section — letting the UI build a request from a URI the conformance checks had already rejected. The comment above it claimed otherwise. `normalizeSkillUri` now, with the rule written down: identity is for COMPARING two spellings, not for deciding a URI is well-formed enough to build a request from. The existing regression test passed against a weaker input that failed for lacking the suffix and never reached the fallback; it is a table of three shapes now. **The test-server guide overstated its own coverage,** claiming four of the five conformance scenarios map onto fixtures. Three do: there is no size-mismatch fixture, because the fixture can override an advertised digest and nothing else, so that path is covered by unit tests. Corrected, with what adding one would take. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ND46Ci64DC3tzBy9aG81Nc Signed-off-by: cliffhall <cliff@futurescale.com>
This commit is contained in:
parent
8ae1a1664d
commit
88c1b89575
1 changed files with 143 additions and 13 deletions
|
|
@ -145,14 +145,23 @@ They are the client-side obligations SEP-2640 makes testable from a hostile
|
|||
server, which is how the
|
||||
[`modelcontextprotocol/conformance`](https://github.com/modelcontextprotocol/conformance)
|
||||
harness grades a *client*: it stands up a server and watches what the client
|
||||
does. Four of its five skills scenarios map onto a fixture here — a digest
|
||||
mismatch (`tampered-notes`), a size mismatch, a frontmatter mismatch
|
||||
(`lying-listing`), and a read of a file the manifest does not list
|
||||
(`stale-manifest`). The fifth, **no-prefetch**, is a negative: it passes only if
|
||||
connecting and calling `skills/list` produces *no* `resources/read` at all. The
|
||||
Inspector satisfies it structurally — nothing is fetched until a user selects a
|
||||
skill or presses Verify, which is why every round trip on the Skills screen is a
|
||||
button rather than an effect.
|
||||
does. **Three** of its five skills scenarios map onto a fixture here — a digest
|
||||
mismatch (`tampered-notes`), a frontmatter mismatch (`lying-listing`), and a
|
||||
read of a file the manifest does not list (`stale-manifest`).
|
||||
|
||||
The other two are covered, but not by this fixture, and the distinction is worth
|
||||
keeping honest:
|
||||
|
||||
- **Size mismatch** has no fixture. `test-servers/src/skills.ts` can override an
|
||||
advertised *digest* and nothing else, so the size path — which
|
||||
`verifySkillResource` checks first, before hashing — is exercised by unit
|
||||
tests rather than against a live server. Adding it would mean an
|
||||
`advertisedSize` override beside the digest one.
|
||||
- **No-prefetch** is a negative and could not have a fixture: it passes only if
|
||||
connecting and calling `skills/list` produces *no* `resources/read` at all.
|
||||
The Inspector satisfies it structurally — nothing is fetched until a user
|
||||
selects a skill or presses Verify, which is why every round trip on the Skills
|
||||
screen is a button rather than an effect.
|
||||
|
||||
## Cancelling a call
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue