Skip to content

[Hackathon] Guillermo Weinmann: bonded_trust — a Sybil-resistant trust root#53

Open
moltpass wants to merge 2 commits into
projnanda:mainfrom
moltpass:hackathon/moltpass-bonded-root-trust
Open

[Hackathon] Guillermo Weinmann: bonded_trust — a Sybil-resistant trust root#53
moltpass wants to merge 2 commits into
projnanda:mainfrom
moltpass:hackathon/moltpass-bonded-root-trust

Conversation

@moltpass

@moltpass moltpass commented Jul 1, 2026

Copy link
Copy Markdown

[Hackathon] Guillermo Weinmann: bonded_trust — a Sybil-resistant trust root with a pluggable scarcity anchor

Summary

Stop fake-identity swarms from buying reputation for free. In an agent marketplace a Sybil can spin up 10,000 accounts that vouch for each other and ride the reputation they manufacture. bonded_trust makes a trust root cost a scarce resource you can't fake by minting — credits, proof-of-work, or a consensus grant — so free identities stay worthless no matter how many you create. A squirrel doesn't trust another squirrel because it says it has nuts; it trusts the one that actually stashed some.

The gap being filled here

The merged/open trust plugins (score_average, EigenTrust-style plugins, agent_receipts) ration influence among identities that already exist; none stops the free minting of identities. The EigenTrust submissions concede the boundary:

"if NEST's auth/identity layers fail upstream, no trust layer can save you."

NEST's did_key mints identities for free, so upstream has failed by default. bonded_trust covers that seam. It does not claim to beat Douceur's Sybil impossibility result (2002) — and it takes Douceur seriously: the resource must be genuinely scarce and verified, not self-asserted. So the plugin never trusts a self-declared bond.

Mechanism

  • Ledger-backed self-bond (defeats free minting). An identity's trust root is pinned at the untrusted floor (score 0.0) until it reserves a bond, and the reservation goes through a StakeLedger. If the agent can't afford it, no bond is recorded. A broke Sybil that sends bond:1000000 gets nothing.
  • Reporter-weighting (defeats wash-trading). Reports count in proportion to the reporter's bond; unbonded reporters carry zero weight; self-reports are ignored. Splitting a fixed budget across K identities buys the same influence as holding it in one.

The pluggable scarcity anchor (payments · PoW · consensus)

The plugin is agnostic about what makes the bond scarce — that's a StakeLedger you inject. Two ship in trust/stake_ledgers.py:

  • CreditBackedLedger — scarcity = the payments layer's finite credits.
  • ProofOfWorkLedger — scarcity = CPU: each bond unit needs a sha256 proof-of-work, so minting K identities costs K× the hashing. No payments layer, no trusted mint. Deterministic mining keeps traces reproducible.

A consensus-gated allocator (quorum grants budget) fits the same interface. The zero-arg default, SelfDeclaredLedger, grants any bond and is documented as simulation/test-only — mirroring hybrid_x25519's deterministic=False secure-default discipline.

Why it's materially different from the trust peers

The adversarial proof (same trace, different trust root)

The sybil_bond scenario runs 20 Sybils that actually bid bond:1000000 on empty wallets and cross-endorse, against 5 credit-funded honest traders. The trust plugin is load-bearing; the observer drives stake/report/score and broadcasts every score.

trust: score_average  →  Sybils score 1.0  →  FAIL (×3)
trust: bonded_trust    →  Sybils score 0.0  →  PASS (×3)

Three validators, all FAIL on the baseline and PASS on bonded_trust:

  • sybil_bond_no_free_trust — no unbonded Sybil above the floor.
  • sybil_bond_honest_trusted — honest traders rank strictly above Sybils (guards against a degenerate floor-everyone plugin).
  • sybil_bond_attempts_rejected — Sybils bid for bonds and were rejected (proves the defense is enforced, not assumed).

Honest boundaries (stated, not implied)

An attacker who spends real credits/work gains real influence; because the score is a bond-weighted mean, a reporter holding a bond majority can dominate a score's sign — that is intended ("most at stake, most say") and costs the whole budget. The guarantee is that influence is bounded by spent scarce resource, independent of identity count. A bonded-but-unendorsed agent scores 0.5 (staked, unproven) — reachable only by spending, never for free.

Artifacts

  • trust/bonded_trust.py — the plugin (registered as trust: bonded_trust), plus the StakeLedger interface and SelfDeclaredLedger default.
  • trust/stake_ledgers.pyCreditBackedLedger + ProofOfWorkLedger.
  • scenarios_builtin/sybil_bond.py + scenarios/sybil_bond.yaml (+ bundled copy).
  • validators.py — the three sybil_bond_* validators.
  • tests: adversarial + property tests (free-minting, wash-trading, self-vouch, unfunded-rejection, credit-split neutrality, PoW anchor, config guards) and an end-to-end FAIL/PASS proof across a 5-seed bank + byte-level determinism.

Determinism

Pure integer/float arithmetic over insertion-ordered dicts; PoW mining scans nonces in order. Same seed → identical trace (asserted via sha256). make ci-local green.

🤖 Generated with Claude Code

alphabet and others added 2 commits July 1, 2026 19:14
…t root

Trust layer. The merged/open trust plugins (score_average, EigenTrust-style plugins, agent_receipts) ration influence among identities that already exist; none stops the free minting of identities. The EigenTrust submissions concede it: "if NEST's auth/identity layers fail upstream, no trust layer can save you."

bonded_trust relocates the Sybil anchor out of the identity layer and into a SCARCE, LEDGER-BACKED stake. It doesn't beat Douceur (2002) — and takes it seriously: the resource must be genuinely scarce and verified, not self-asserted.

- Ledger-backed self-bond: a trust root is pinned at the floor (0.0) until the agent RESERVES a bond through a StakeLedger. A broke Sybil that sends bond:1000000 gets nothing. Total bond is bounded by the scarce supply, so splitting a budget across K identities buys no more influence than one.
- Reporter-weighting: reports count in proportion to the reporter's bond; unbonded reporters carry zero weight; self-reports are ignored.

Pluggable scarcity anchor (StakeLedger): payments credits (CreditBackedLedger), proof-of-work (ProofOfWorkLedger, sha256), or a consensus grant — all the same interface. SelfDeclaredLedger is the documented insecure default (test only).

Adversarial proof: the sybil_bond scenario has 20 Sybils ACTUALLY bid bond:1000000 on empty wallets and cross-endorse, vs 5 credit-funded honest traders. Three validators (no_free_trust, honest_trusted, attempts_rejected) FAIL under score_average, PASS under bonded_trust.

Hardened per an adversarial review: unbacked stake -> ledger-enforced; Sybils now attempt bonds (not assumed to abstain); removed weight_cap footgun; ignore self-vouches; reject min_bond=0; scoped the Douceur claim to the injected ledger.

Artifacts: trust/bonded_trust.py, trust/stake_ledgers.py, scenarios_builtin/sybil_bond.py + scenarios/sybil_bond.yaml (+ bundled copy), three sybil_bond validators, adversarial + property + PoW tests, 5-seed end-to-end proof + determinism. make ci-local green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adds three self-contained tests verifying bonded_trust clears the classic adversarial reputation properties — a self-vouching clique, self-promotion, and a distrusted reporter all fail to move a bonded agent — translated from EigenTrust's pre-trusted-seed anchor to bonded_trust's scarce bond.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants