Search Apps Documentation Source Content File Folder Download Copy Actions Download State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

v0 source realm

Package jury is a commit-reveal adversarial review protocol for disputes over agent work.

Readme View source

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:

gno.land/r/moul/agents/jury/v0 dependency graph

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

Overview

Package jury is a commit-reveal adversarial review protocol for disputes over agent work.

The hard part of an agent economy is not paying agents — it is deciding what happens when an agent's output is disputed. This realm runs a small jury: a fixed panel of reviewers each *commit* to a hidden verdict, then *reveal* it. Commit-reveal means no juror can copy another's vote or be swayed after seeing the tally; every verdict is locked in blind.

The subject of a case is an opaque string — a receipt sequence, a claim id, an off-chain artifact hash — so this realm composes with the receipt and gnomem demos without depending on them.

Bonding and slashing (a juror stakes coins, loses them for provably bad verdicts) are the natural economic layer on top; this demo shows the mechanism without the money.

Constants 1

Functions 7

func Commit

crossing Action
1func Commit(cur realm, caseID uint64, commitment string)
source

Commit locks in a juror's hidden verdict. commitment must equal commit.Verdict(verdict, salt) — computed off-chain. When the last juror commits, the case advances to the reveal phase automatically.

func OpenCase

crossing Action
1func OpenCase(cur realm, subject string, jurors []address) uint64
source

OpenCase starts a dispute with a fixed panel of jurors. An odd panel size avoids ties; duplicates are rejected.

func Outcome

Action
1func Outcome(caseID uint64) string
source

Outcome returns the recorded outcome, or "" if the case is still open.

func Render

1func Render(path string) string
source

Render shows all cases, or one case's panel + tally at :<id>.

func Reveal

crossing Action
1func Reveal(cur realm, caseID uint64, verdict bool, salt string)
source

Reveal opens a juror's verdict. The (verdict, salt) must reproduce the commitment made earlier, or the reveal is rejected. When the last juror reveals, the case closes and the majority outcome is recorded.

func Get

Action
1func Get(caseID uint64) Case
source

Get returns a copy of a case (jurors flattened separately via Jury).

Types 3

type Case

struct
 1type Case struct {
 2	ID       uint64
 3	Subject  string // opaque reference to the disputed thing
 4	Opener   address
 5	Phase    Phase
 6	Jurors   []*Juror
 7	OpenedAt int64
 8	Outcome  string // "upheld" | "rejected" | "tie" once closed
 9	Yes      int
10	No       int
11}
source

Case is a single dispute under review by a fixed panel.

type Juror

struct
1type Juror struct {
2	Addr       address
3	Commitment string // commit.Verdict(verdict, salt)
4	Committed  bool
5	Revealed   bool
6	Verdict    bool // meaningful once Revealed
7	Height     int64
8}
source

Juror is one panelist and their (eventually revealed) verdict.

type Phase

ident
1type Phase string
source

Phase is a case's position in the commit-reveal lifecycle.

Imports 5

Source Files 4