fix(input-required-result): report the capability check as untestable when nothing is requested (#442)

`input-required-result-capability-check` guarded its elicitation scan with
`isInputRequiredResult(result) && result.inputRequests`. When a server answered
without `inputRequests`, that arm was skipped, and the following
`isCompleteResult` arm is false by construction for an input_required result, so
nothing was recorded and the check passed. An empty `inputRequests` object passed
too: the arm was taken, but the loop had nothing to scan.

`inputRequests` is optional — a result carrying only `requestState` still
satisfies "at least one of inputRequests or requestState" — so such a server has
not violated "servers MUST NOT send an inputRequests that the client has not
declared support for in its capabilities". It has not exercised it either.
Reporting SUCCESS makes an unverified MUST read as green, which is the failure
mode #248 and #372 established should be reported as a failure instead.

So report it through `notTestable()` with `details.untestable`, matching the
convention in AGENTS.md and the call sites in stateless.ts, rather than claiming a
violation the server did not commit. Servers that legitimately have nothing to ask
for now go red on this check; per #248 the expected-failures baseline is the
escape hatch.

Adds the case to sep-2322-mrtr-broken-server so the existing MRTR negative suite
covers it. The fixture returns a conformant envelope (`requestState` present, no
input requests) rather than a bare one, so it isolates this check rather than also
tripping sep-2322-request-state-incomplete.

Verified against --spec-version 2026-07-28:

  everything-server            2/2 passed
  sep-2322-mrtr-broken-server  FAILURE  Not testable: server returned no
                               inputRequests, so the capability restriction
                               was never exercised

Refs #439

Co-authored-by: Marcus <238969485+marcus-kepler-92@users.noreply.github.com>
This commit is contained in:
marcus-kepler-92 2026-09-07 02:29:21 +08:00 • committed by GitHub
commit 48561a1aec
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -8,6 +8,11 @@
* 2. Returns InputRequiredResult on `tools/list` (unsupported method)
* 3. Accepts tampered requestState without integrity verification
*
* Plus one case that is not a violation at all:
*
* 4. Answers with a conformant input_required result that names no input
* request, leaving the capability check with nothing to verify.
*
* The conformance scenarios should emit FAILURE against this server.
*/
@ -54,6 +59,11 @@ handlers['tools/list'] = () => ({
name: 'test_input_required_result_tampered_state',
description: 'Test tool for tampered state',
inputSchema: { type: 'object' as const, properties: {} }
},
{
name: 'test_input_required_result_capabilities',
description: 'Test tool for client capability handling',
inputSchema: { type: 'object' as const, properties: {} }
}
]
});
@ -94,6 +104,16 @@ handlers['tools/call'] = (params) => {
};
}
case 'test_input_required_result_capabilities': {
// BUG 4: Conformant on its face — `requestState` satisfies "at least one
// of inputRequests or requestState" — but it names no input request, so
// the capability restriction under test is never exercised.
return {
resultType: 'input_required',
requestState: 'no-input-requested'
};
}
case 'test_input_required_result_tampered_state': {
if (inputResponses) {
// BUG 3: Accepts ANY requestState without verification