Skip to content

[P0] capabilities doc falsely declares "adapt": true — no Adapt() exists anywhere in the crate #5

Description

@SoundMatt

What's wrong

rcp capabilities hardcodes "adapt": true (src/bin/rcp.rs:95), but the crate exports no Adapt()/adapt() function anywhere, and has no dependency on any relay/relay-rs crate to return relay::Node/relay::Caller types from in the first place:

$ grep -rin "fn adapt\b|relay::Node|relay::Caller" src/ Cargo.toml
(no matches)

Per RELAY spec §12.2: "adapt MUST be true if the package exports Adapt() per §10.3." §10.3 requires a concrete adapter function (Rust: something returning a relay::Node/relay::Caller-equivalent, using to_message()/from_message() internally). rust-RCP has none of this — src/adapt.rs implements an unrelated generic Adapter<M> trait for converting between Command/Response and an arbitrary external type M; it never touches relay::Message/relay::Node/relay::Caller.

Separately, the same capabilities doc hardcodes "optional_interfaces": [] (src/bin/rcp.rs:94) even though the crate does implement LoaningController (src/lib.rs:513, impl LoaningController for LoanPoolController in src/loan.rs:118) — an optional interface per spec §9/Appendix A that should be listed there (the RCP "loaning" feature flag hints at it, but optional_interfaces is the field the spec actually defines for this).

Evidence

Live binary output (built from this checkout):

$ ./target/debug/rcp capabilities
{
    ...
    "interfaces": ["Controller","Registry"],
    "optional_interfaces": [],
    "adapt": true
}

Why relay conform doesn't catch it

RELAY's own cmd/relay/conform.go:236-238 only emits a WARN when adapt=false (as a reminder Adapt() isn't exported); it has no way to statically verify a true claim. So this binary passes relay conform --strict cleanly (verified) while actively misreporting its capability set — which is exactly the kind of self-reported metadata that relay compare, relay probe, and relay interop (§11.2.1) trust to decide interchangeability and routing eligibility.

Expected per spec

"adapt" MUST be false until a real Adapt()/adapt() is implemented (§10.3/§12.2), and "optional_interfaces" MUST include "LoaningController" since it is implemented.

Suggested fix

Flip "adapt": true to "adapt": false in src/bin/rcp.rs:95 until a real adapter exists (tracked by the broader gap below), and populate "optional_interfaces" with ["LoaningController"] in src/bin/rcp.rs:94.


Filed from the RELAY ecosystem audit (2026-07-27), category: bug, severity: P0.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions