Docs
PATH FINDER
Reachability in two steps — SONAR then RESOLVER — with the normative rules on budgets, answer shape and logging.
DRAFT — the layer is specified; the SONAR step is trivially satisfied while a single member holds an index.
The two steps
- 01SonarWhich member holds this key?The network answers · ring 2
- 02ResolverWhat does this destination accept?The holder answers · ring 1
The Learn page explains why they stay apart. This page is the normative detail.
Composition is client-side
The two calls are chained by the caller, not by the network. A network MAY offer to relay step 2, and MUST declare it in its discovery document if it does.
A relaying network sees the destination's capability on top of every search: which rails a competitor supports, which assets, what limits, and how they change. That is not routing data. The default is therefore no relay, and the exception is published rather than silent.
Skipping step 1
/resolver/{key} MUST remain a route in its own right, callable without any credential. It is
the only complete path that requires membership of no network, and every claim about the protocol's
openness rests on it existing and being reachable.
Normative rules for SONAR
Constant-shape answers
An unknown key and a key that is known but not visible to the caller MUST produce identical responses — same status, same body shape, and no observable timing difference.
A route that distinguishes them is an oracle answering "is this person a customer of somebody" for any number worth trying. That answer alone is worth money to a scammer assembling a target list, before anyone learns which provider.
Reciprocity budgets
Search allowances MUST be computed from what a member contributes to the index, not as a requests-per-second ceiling.
{
"queries_per_registered_entry_per_month": 5,
"absolute_floor": 1000
}The threat is not a burst; it is a patient walk through the number space by a member, or by whoever holds a member's credential. A rate limit sets the pace of that walk. A budget ends it.
absolute_floor exists so that a member who has just joined and registered nothing is not stuck at
zero and unable to start.
Email takes its own budget. The threat there is not enumeration but replay of a breach list — hundreds of millions at once — and a budget tuned for slow enumeration is the wrong shape.
Logging
Every lookup MUST be recorded against the calling member, with the key, and MUST NOT record the identifier in the clear.
Retention MUST be declared in the discovery document. A credential without a log is a badge with no camera behind it.
Called server-side
SONAR MUST be called by a member's server, never from an end-user application. A credential shipped inside an app is public the moment someone opens the binary.
An application talks to its own backend, which talks to the directory. This is a real constraint on architecture, not a recommendation.
Batch
POST /sonar/lookup/batch is the contact-synchronisation shape and the only enumerative route in
the surface. It MUST be capped explicitly rather than inheriting the general budget.
A cap does not fix the underlying practice. Sending an entire address book on install exposes every contact a user has, most of whom will never be paid. Look a number up when someone actually wants to pay it: same functionality, orders of magnitude less exposure, and no cryptography involved. It is the highest-impact privacy measure in the protocol.
Holder confirmation
A network MAY require the holding member to co-sign, and declares this as
holder_confirmation: required | optional | none. required is recommended.
- 01AskCaller asks Sonar“It’s at member-b.”
- 02ConfirmNetwork asks member-bMember-b signs: yes, mine, for this requester.
- 03ReturnCaller receives bothThe answer, plus the holder’s signature.
What it buys: the answer no longer rests on the network's word alone; the member gets a per-request veto under its own policy; and the index may be stale without the answer being wrong.
What it costs: a second round trip, the holder having to be up, and a shift in who observes — the holder now learns someone is looking for its customer, which it did not before.
The confirmation signs the key, member, requester, timestamp and nonce. Never the capability — routing that through the network hands it precisely what the split withholds. Without the requester and nonce, the confirmation is replayable.
Network topologies
A network declares sonar_mode.
central — the network holds the index and answers. A member integrates in an afternoon, stores
nothing, synchronises nothing, reads fresh data. The network sees the searches.
broadcast — the member asks its peers in parallel, narrowed by declared coverage.
"coverage": {
"phone": ["+221", "+225"],
"reg": ["SN"],
"bank_account": ["FR", "BE"]
}Coverage is what makes broadcast viable: a Senegalese number reaches only members serving Senegal, cutting both traffic and exposure by an order of magnitude. It leaks nothing — "I serve Senegal" is on the member's marketing page.
Three further rules for broadcast:
The member fans out, not the network. If the network relays, it sees every search and so do the peers — the drawbacks of both modes at once.
Negative caching belongs to the caller. What is worth remembering is "nobody holds this key", which is the common and expensive case, and remembering it caller-side avoids the trip rather than just the computation.
Silence is ambiguous. A member that does not answer may not hold the key, or may be down. A peer that is down otherwise becomes a peer that says no, and its customers become quietly unreachable. Pair it with an independent liveness signal.
Broadcast is not the more private option, and it is routinely assumed to be. Asking fifty members tells forty-nine of them that someone is looking for a person, when one needed to know. Central concentrates observation in a party bound by the rulebook; broadcast spreads it among competitors who are not.
Why there is no feed mode
Published feeds, k-anonymity buckets and Bloom filters all founder on the same rock: to test a candidate against a list of hashes, the caller must compute the hash, which requires the pepper. Distributing the pepper is refused permanently — see Privacy.
Any design that has the caller search locally needs the pepper. That is a general rule, not a property of one scheme.