Skip to content

Reject sessions only on required-feature mismatches, not unknown extensions #57

@nficano

Description

@nficano

negotiate adds every extension the client advertised but the runtime did not to the unsupported list at lib/src/main/kotlin/dev/arcp/runtime/CapabilityNegotiation.kt:30 (unsupported += proposed.extensions - supported.extensions.toSet()). ARCPRuntime.handleHandshake then routes any non-empty unsupported set into rejectUnsupported at lib/src/main/kotlin/dev/arcp/runtime/ARCPRuntime.kt:544, which sends SessionRejected with UNIMPLEMENTED and tears the transport down at lib/src/main/kotlin/dev/arcp/runtime/ARCPRuntime.kt:149. The effect is that a client that advertises any arcpx.* extension the runtime does not recognize cannot connect at all — including the optional vendor extensions whose entire point per RFC §21 is graceful degradation. The boolean-feature path at lib/src/main/kotlin/dev/arcp/runtime/CapabilityNegotiation.kt:97 correctly only marks features that the client requested but the runtime cannot satisfy; the extensions path mirrors that asymmetry incorrectly because extensions are optional by spec unless marked otherwise.

Fix prompt: In negotiate, stop appending unsupported extensions to the rejection list. Compute the negotiated extension set as the intersection (already done in negotiateExtensions) and silently drop extensions either side does not support. If a client wants to require an extension, it must request a corresponding boolean capability or send the extension's required messages, which will hit the existing classifyUnknown/Nack path. Add a negotiate unit test in lib/src/test/kotlin/dev/arcp/runtime/ (no such file exists yet) that asserts a client advertising arcpx.unknown.example.v1 against a runtime with no extensions yields a Capabilities.extensions == [] negotiated result and an unsupported.isEmpty(), and a separate test that confirms a streaming = true client against a runtime with streaming = false still appears in unsupported.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingseverity:highHigh severity issue

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions