Skip to content

Relational trust

Trust in Quidnug is always a statement “observer O trusts target T at level L in domain D”, cryptographically signed by O. There is no global “what is Bob’s trust score”, only “from my perspective…” answers.

A signs a trust edge asserting it trusts B at level 0.9 in contractors.home. Direct query:

A ──0.9──► B ⇒ trust(A→B, contractors.home) = 0.9

Trust composes multiplicatively along paths:

A ──0.9──► B = 0.9
A ──0.9──► B ──0.8──► C = 0.72
A ──0.9──► B ──0.8──► C ──0.7──► D = 0.504

If multiple paths exist, Quidnug takes the max: a single strong recommendation beats many weak ones. This is a deliberate design choice, it makes reputation-gaming via flooding ineffective, and it matches how humans reason about trust (“one trusted friend’s endorsement counts more than ten random votes”).

The default traversal depth is 5 hops. You can cap lower for performance or raise it if your graph is sparse. Depth-bounded BFS is used for determinism.

Trust is always scoped to a domain. A doctor trusted in doctors.credentials.texas.medical-board.gov is not automatically trusted in oracles.price-feeds.ethereum.mainnet.

A trust transaction is a JSON object signed canonically. The signature is appended and the transaction anchored into a block. Canonical bytes are byte-identical across every SDK, see the integration guide.

{
"truster": "alice",
"trustee": "bob",
"trustLevel": 0.9,
"domain": "contractors.home",
"nonce": 1,
"timestamp": 1729400000,
"publicKey": "<hex>",
"signature": "<base64>"
}
Terminal window
curl "http://localhost:8080/api/trust/alice/bob?domain=contractors.home"

The first path component is the observer. If you change the observer, you change the answer, this is correct behavior, not a bug. See Proof-of-Trust consensus for how this shapes block acceptance.