Proof of Trust GitLab
Version 0.2 · reference implementation

A blockchain whose consensus is paid in bits of information.

Proof of Trust replaces hashing work and locked capital with a strictly proper log score measured in Kullback–Leibler divergence. Voters cast probability distributions; the ones closer—literally in bits—to the truth earn trust. The rest spend it.

The one identity
\[ \Delta\,t_v \;=\; \alpha \;\bigl[\,\underbrace{\log q_v(y)}_{\text{voter's log score}} \;-\; \underbrace{\log p_m(y)}_{\text{market's log score}}\,\bigr] \;=\; \alpha\;\bigl[\,D_{\text{KL}}(\delta_y\|p_m) - D_{\text{KL}}(\delta_y\|q_v)\,\bigr] \]

A voter is paid, in trust, for every nat by which they beat the trust-weighted market, and taxed for every nat they fell short. Because the log score is strictly proper, the unique trust-maximizing strategy is to report your honest belief.

The problem

Existing consensus pays for security with the wrong thing.

01 / proof of work

Buy security with electricity

Miners race to invert a hash. The winner's "work" is trivially verifiable but wasteful by design — Bitcoin's security budget is denominated in terawatt-hours per year.

02 / proof of stake

Buy security with locked capital

Validators post a bond; misbehavior is slashed. But validators are paid to vote and not to be right about anything resolvable. The nothing-at-stake problem is a tax on the design.

03 / proof of trust

Buy security with information

Each voter publishes a probability distribution over candidate blocks. Scores are settled in KL bits against the realized outcome. Honesty is the unique expected-value maximum, so the cheapest way to earn trust is to know something true and say so.

System Security cost Finality rule "Work" unit
Proof of Work electricity heaviest cumulative hash hash preimages
Proof of Stake locked capital majority signature coin-years
Proof of Trust misreporting cost heaviest cumulative trust-weighted vote KL bits vs. market
How it works

The whole protocol is one identity in disguise.

  1. 1

    Propose

    Any participant can publish a candidate block — a merge commit of pull-request-shaped code changes.

  2. 2

    Vote

    Voters sign a distribution qv over the candidates at some height, plus a "none" slot. No binary approvals — probabilities.

  3. 3

    Fork-choice

    Weights W(B) = Σ tv·qv(B) determine canonicity. The heaviest candidate wins.

  4. 4

    Score

    After K confirmations the winner is known; every voter is credited the KL bits by which they beat the market.

What the chain actually accumulates

Bitcoin's chain accumulates cumulative work. Proof of Trust accumulates a dimensionless, noise-free quantity: the amount of evidence the market registered about which block was canonical at each height.

Information content at height h
\[ I_h \;=\; D_{\text{KL}}(p_m \,\|\, \text{Unif}) \;=\; \log n - H(p_m). \]

If voters agree strongly, \(I_h \approx \log n\). If they're undecided, \(I_h \approx 0\). A reorg at depth \(K\) requires matching \(\sum_{h} I_h\) cumulative bits.

Incentive compatibility, in one step

Let \(p^*\) be the voter's private belief. Their expected trust update is

\[ \mathbb{E}_{y\sim p^*}[\Delta t_v] \;=\; \alpha\,\bigl[\,\mathbb{E}_{p^*}\log q_v(y) \;-\; \mathbb{E}_{p^*}\log p_m(y)\,\bigr]. \]

The second term doesn't depend on \(q_v\); the first is maximized—by Gibbs' inequality—iff \(q_v = p^*\). Honest reporting uniquely maximizes expected trust gain.

A worked example

Three voters, two candidates, exact numbers.

Trust & votes

alice  10 000 mT  q = 0.90 / 0.05 / 0.05
bob     5 000 mT  q = 0.50 / 0.50 / 0.00
carol   5 000 mT  q = 0.10 / 0.85 / 0.05
                     A      B     none

Fork-choice tally

W(A) = 10000·0.9 +  5000·0.5 +  5000·0.1
     = 9000 + 2500 + 500
     = 12 000

W(B) =  500 + 2500 + 4250 = 7 250

→ canonical[1] = A

Trust update

p_m(A) = 12000 / 20000 = 0.60
log p_m(A) ≈ −0.5108

alice  log(0.9) − log(0.6) = +0.4055 → +405 mT
bob    log(0.5) − log(0.6) = −0.1823 → −182 mT
carol  log(0.1) − log(0.6) = −1.7918 → −1 792 mT
Height 1 contributes about 0.400 bits of evidence to the chain. These numbers are asserted to the millitrust in crates/pot-git/tests/e2e.rs. Play with it yourself
Git-native

Your repo is the chain.

The canonical chain is literally refs/heads/main. Blocks are merge commits. Code changes are the commits merged in. Candidate blocks, pending votes, trust transfers, and prediction-market objects all live under the refs/pot/* namespace.

Gossip reduces to git push / git fetch. A fresh clone is a fully auditable replica. pot status reconstructs the state machine from the repository alone.

refs/heads/main refs/pot/candidates/* refs/pot/votes/* refs/pot/trust-txs/* refs/pot/markets/*
$ git log --graph --oneline --all
* cafe01d pot: block h=3 id=a7f21...
* 91fa802 pot: block h=2 id=15d23...
* 15d2327 pot: block h=1 id=15d23...         # canonical
| * ed953c3 pot: block h=1 id=ed953...         # orphaned candidate
|/
* 61a2cc0 pot: genesis
Git workflow

Replace vanilla git — without replacing git.

Proof of Trust does not fork git. It is git with an extra consensus layer on refs/heads/main and signed objects under refs/pot/*. You keep git commit, branches, and remotes; you add pot for canonicality, votes, and trust. No protocol changes are required for this workflow — the reference CLI already implements it.

You used to… With PoT…
git init pot init (new network) or clone a published snapshot (join)
feature branch + commits Same; commits are opaque until merged into a block
open a PR pot propose --merge <git-oid> → candidate under refs/pot/candidates/*
code review / LGTM pot vote with probabilities over competing candidates
merge PR to main pot advance (fork choice) or pot propose --canonical (trusted proposer)
git push / git fetch Same remotes; push refs/pot/* + main; optional pot-bootstrap for TCP gossip
CI / deploy on merge pot-deploy runs pot-deploy.toml hooks on each canonical tip (clients)

Solo or founder path

No competing candidates — promote directly to main.

$ git checkout -b feature/my-change
# edit, then:
$ git commit -m "my change"
$ pot propose --as founder \
      --merge "$(git rev-parse HEAD)" \
      --timestamp "$(date +%s)"
$ pot propose --as founder --canonical \
      --timestamp "$(date +%s)"

Multi-voter path

Competing proposals, trust-weighted fork choice, KL scoring after K confirmations.

$ pot propose --as alice --merge <oid>
$ pot propose --as bob   --merge <other-oid>
$ pot vote --as carol --height N \
      --candidates $A,$B --probs 0.7,0.25,0.05
$ pot advance
# K more canonical blocks, then:
$ pot finalize --verbose

Migrate an existing vanilla repo

Run pot init in a fresh directory, then import your tree as a single orphan commit and merge it once into block 1. Do not merge top-level directories one at a time — sequential single-directory merges overwrite earlier trees (see genesis guide §A.2).

$ git checkout --orphan code/monorepo
# rsync or copy your project tree, then:
$ git add . && git commit -m "import monorepo snapshot"
$ git checkout main
$ pot propose --as founder --canonical \
      --merge "$(git rev-parse code/monorepo)" \
      --timestamp "$(date +%s)"

Plain git still works

  • Local branches, git diff, git log, worktrees
  • A clone is a full audit replica
  • pot status replays state from the repo alone

Not yet transparent

  • git push alone does not advance main — run pot advance or --canonical propose
  • Optional git pot hooks install — advisory hooks + .git/pot/next.json for agents
  • Contested forks need trust-weighted voters (genesis endowment or earned KL margin)
  • Join an existing network via snapshot + bootstrap, not pot init on the monorepo root
Client ecosystem

Six single-purpose clients. One chain.

Every role you'd expect from a network—gossip, explorer, light audit, deployment— ships as a dedicated binary. All of them read and write the same git repository.

pot

umbrella CLI

Init, keygen, vote, transfer, propose, advance, finalize. Also delegates to the five dedicated clients.

pot init --k 2 --alpha 1000 \
    --endow alice=10000

pot-bootstrap

P2P gossip

TCP gossip daemon. Authenticated handshake, headers & block service, inventory-based propagation of every signed object.

pot-bootstrap --listen 0.0.0.0:8765 \
    --peers seed1.example:8765

pot-light

headers-only

Downloads only block headers; verifies the proposer signature and parent linkage back to genesis. Optional block audit.

pot-light sync --peer host:8765 \
    --chain-id 61a2cc0…

pot-market

prediction markets

Declare, bet on, and resolve arbitrary on-chain markets. Same strictly proper KL scoring as the core consensus rule.

pot-market declare --outcomes yes,no \
    --resolver alice --as bob

pot-web

explorer & UI

HTTP chain explorer, JSON API, optional signing endpoints for local vote/transfer/bet submission.

pot-web --listen 127.0.0.1:8080 \
    --unlock alice,bob

pot-deploy

canonical runner

Watches the canonical tip, checks out a detached git worktree, runs your pot-deploy.toml entrypoints on tip and finalization.

pot-deploy --repo /srv/pot
Quickstart

From zero chain to finalized KL scorein five minutes.

A single cargo build --release produces every client. The reference walkthrough reproduces the whitepaper's worked example on a real git repository.

  • One repo, any git server.
  • Canonical CBOR everything.
  • Ed25519 signatures throughout.
  • Deterministic replay.
zsh — /tmp/pot-demo
$ pot init --k 2 --alpha 1000 \
      --endow alice=10000 --endow bob=5000 --endow carol=5000
Initialized PoT repository at /tmp/pot-demo
  chain_id: 61a2cc0…
  generated keys: alice 651b… bob 01bf… carol e927…

$ pot propose --as alice --timestamp 1700000001
$ pot propose --as bob   --timestamp 1700000002
# two competing candidate blocks at height 1

$ pot vote --as alice --height 1 \
      --candidates $A,$B --probs 0.9,0.05,0.05
$ pot vote --as bob   --height 1 \
      --candidates $A,$B --probs 0.5,0.5,0
$ pot vote --as carol --height 1 \
      --candidates $A,$B --probs 0.1,0.85,0.05

$ pot advance
W(A) = 12 000 · W(B) = 7 250
canonical = A

$ pot propose --as alice --canonical --timestamp 1700000200
$ pot propose --as alice --canonical --timestamp 1700000300
$ pot finalize --verbose
voter alice q=0.90 margin=+0.4055 Δ=+405 mT
voter bob   q=0.50 margin=−0.1823 Δ=−182 mT
voter carol q=0.10 margin=−1.7918 Δ=−1792 mT
Deep dive

For the ones who want the proofs.

Common objections, answered.

Isn't any vote-weighted system vulnerable to Sybils?
Trust has to come from somewhere — either genesis endowment or a signed transfer. New identities only gain trust by beating the trust-weighted market. Spawning N shell voters who copy the market gets them nothing: their margin versus the market is ≤ 0 by construction.
What stops me from voting both sides of a fork?
You can, but it is not free. Whichever side ends up non-canonical, you pay exactly your KL divergence from the truth in that forecast. Uniform bets minimize the loss but also cap any gain; the expected outcome of double-voting is strictly worse than honestly reporting what you think.
Is the protocol conservation-preserving?
Not exactly. By Jensen's inequality the trust-weighted average voter underperforms the market log-score; the gap is a small "cost of disagreement" deflation on total trust when voters hold heterogeneous beliefs. A Kelly-style multiplicative variant that is zero-sum is future work.
Why git? Isn't that a weird choice?
A git repo is already an append-only, cryptographically-hashed, content-addressed DAG. Merge commits are natural block boundaries. Pull-request review was always an implicitly probabilistic ritual. The whole chain is just a series of code reviews made explicit.

Pay for security in the right currency.

Not energy. Not capital. Information.