rcp.json registry.
The registry — rcp.json
string
required
A client-local label used to tag fused hits by origin (
meta.engine)."stdio" | "http"
required
With
command (stdio) or url (http).integer
default:"0"
Higher wins for Selector’s primary → secondary fallback.
float
default:"1.0"
Scales the engine’s contribution during fusion.
boolean
default:"false"
If
true, a connect/query failure fails the whole federated query instead of
being skipped.catalog capability: a registry
entry can point at an aggregator that enumerates further engines via
catalog/list.
Selector — pick one of many
When you have several backends but each query should hit exactly one, aSelector chooses it for you from the rcp.json registry. It connects
lazily — listing ten candidates opens zero connections until you call a
select_* method, and then only to the winner. There are three selection
policies:
Both
select_primary and select_capable give you priority + liveness
fallback for free: a multi-backend deployment stays up when a backend dies,
without the client writing any failover glue. priority in the registry (higher
wins) sets the order they’re tried.
Federation — fuse many
A federatedretrieve(query, k) fans out retrieve to every engine that
advertises it, concurrently. Engines lacking the capability are skipped (not an
error); a slow non-required engine is dropped after a client-side deadline so
one bad backend can’t stall the query.
Reciprocal Rank Fusion
The default and recommended fusion is RRF (Cormack et al. 2009), which needs only ranks — not comparable scores — so it is robust across heterogeneous engines:rank_engine(d) is the 1-based position of document d in that engine’s
list (engines that didn’t return d contribute nothing). The fused list is
sorted by descending RRF(d) and truncated to k.
Determinism & dedup
- Tie-breaking is deterministic: order by (1) higher fused score, then (2)
higher summed weight, then (3) lexicographically smaller stringified
id— a total order independent of engine response arrival. - Deduplication keys on the stringified
Hit.id. When two hits collapse, the fused hit SHOULD keep the richest body and mergemeta. Each fused hit carries its origin inmeta.engine.
The fusion primitive — rrf_fuse
You don’t need the full Federation facade to fuse. Every reference SDK exports
the fusion algorithm as a standalone, tested function over ranked lists you
already hold — a cache, a replay, two hand-issued retrieve calls — so no
adopter re-derives §16.3 (and re-derives it subtly wrong). All four are
byte-for-byte identical: same tie-break, same richest-body dedup, same origin
tagging in meta.engine and meta.fusedScore.
rrfK is 60 (rcp.RRF_K_DEFAULT / fusion::RRF_K_DEFAULT). The
live C++ Federation calls the very same rcp::fusion::rrf_fuse, so fan-out
fusion and held-list fusion agree exactly.
One command: fan out and fuse
examples/example_federation.py
is spec §16 made runnable in a single process — it spawns two genuinely
independent engine subprocesses (each its own corpus), fans one query out to
both, and fuses their rankings with rcp.rrf_fuse:
Federated capabilities
A client’s effective capability set over a federation is the union of its engines’ capabilities (it canembed if any engine can); its guaranteed set is
the intersection. A federated retrieve runs against the subset advertising
retrieve; a federated graph op against those advertising it. Reference SDKs
expose both a per-engine handle and a Federation facade.