README.md
Agent Jury — who checks the agents?
Paying agents is the easy part of an agent economy. The hard part is what happens when an agent's output is disputed: a patch that may be wrong, a research claim that may be fabricated, an oracle reading someone contests. Someone has to adjudicate — and if that someone is a single trusted party, you've just recreated the thing blockchains were supposed to remove.
This realm runs a small commit-reveal jury: a fixed panel of reviewers each lock in a hidden verdict, then reveal it. Because verdicts are committed blind, no juror can copy another's vote, and none can be swayed by watching the tally form.
The two phases
commit: each juror submits commit.Verdict(verdict, salt) ← hash, hides the vote
reveal: each juror submits (verdict, salt) ← must reproduce the hash
close: majority of revealed verdicts decides the outcome
The commitment scheme is shared with the other demos
(p/moul/agents/commit/v0), so a juror computes their commitment off-chain:
1commitment := commit.Verdict(true, "a-random-salt") // "I vote YES", hidden
2
3jury.Commit(cross(cur), caseID, commitment) // during commit phase
4// ...later...
5jury.Reveal(cross(cur), caseID, true, "a-random-salt") // reproduces it, or the reveal is rejected
When the last juror commits, the case auto-advances to reveal; when the last reveals, it closes and records the majority outcome. Dissenting jurors (those who voted against the majority) are marked in the render — minority reports stay visible, which matters when the minority turns out to be right.
Composability
A case's subject is just an opaque string — a receipt sequence from the receipt demo, a claim id from gnomem, a raw artifact hash. The jury doesn't import any of them; it adjudicates references. That's the point of small, single-purpose realms: they snap together without hard dependencies.
1id := jury.OpenCase(cross(cur), "receipt#7", []address{j1, j2, j3})
2// ... commit + reveal ...
3jury.Outcome(id) // "upheld" | "rejected" | "tie"
Browse cases at the realm root; each panel and tally is at :<id>.
1gno test .
What's missing (on purpose)
The mechanism is here; the money is not. A production jury bonds each juror (stake coins to serve) and slashes provably bad verdicts — that's what makes honest review the profitable strategy. It also wants juror selection (random or reputation-weighted, to resist packing) and an appeal path (a larger panel on challenge). All of those compose on top of this commit-reveal core; none of them change it.
The uncomfortable design truth: you can't prove a verdict is correct. You can make it blind, independent, and accountable — and that's what turns "one trusted adjudicator" back into "a protocol."
Part of moul/gno-contracts — moul's versioned gno.land contracts. See the repository for the full catalog, build/test tooling, and usage.
Dependency graph:

⚠️ Disclaimer: provided as-is, without warranty; not security-audited. Full disclaimer: DISCLAIMER.