daocond.gno
1.78 Kb · 54 lines
1package daocond
2
3// Package daocond provides a stateless condition system for DAO voting.
4//
5// This model replaces complex event handlers. It works well for
6// small DAOs with few voters, with plans to add stateful models for
7// larger DAOs in the future.
8
9// Represents a voting requirement.
10type Condition interface {
11 // Checks if the condition is satisfied by the current votes.
12 Eval(ballot Ballot) bool
13 // Returns progress toward satisfying the condition (0.0 to 1.0).
14 Signal(ballot Ballot) float64
15
16 // Displays the condition as human-readable text.
17 // Example output: "[ 60% Members OR 2 admin ]"
18 Render() string
19 // Displays the condition with current vote counts.
20 // Example output: "[ 3/5 Members OR 1/2 admin ]"
21 RenderWithVotes(ballot Ballot) string
22}
23
24// Represents a collection of votes that can be evaluated against conditions.
25type Ballot interface {
26 // Records a vote from a specific voter.
27 Vote(voter string, vote Vote)
28
29 // Retrieves the vote from a specific voter.
30 Get(voter string) Vote
31 // Returns the total number of votes cast.
32 Total() int
33
34 // Iterate over all votes, calling fn for each voter/vote pair.
35 // If fn returns false, iteration stops.
36 // Useful for counting specific vote types or finding particular voters.
37 Iterate(fn func(voter string, vote Vote) bool)
38}
39
40// Represents a voting decision.
41type Vote string
42
43// Available vote options.
44//
45// Typed as Vote, not as untyped strings: an untyped constant assigns to a plain
46// string without complaint, so a caller could hold one in a string variable and
47// only discover the mismatch at a conversion. Typing them is a source-breaking
48// change for any such caller, which is why it has to happen before publication
49// rather than after.
50const (
51 VoteYes Vote = "yes"
52 VoteNo Vote = "no"
53 VoteAbstain Vote = "abstain"
54)