remove tally_method tag, add value_maximum tag, rewrite affected sections to reflect revised poll attributes

This commit is contained in:
toadlyBroodle 2023-03-05 19:00:46 +09:00
parent 9ce8a868a3
commit f292a7e920

60
69.md
View File

@ -2,27 +2,25 @@
`draft` `optional` `author:toadlyBroodle` `draft` `optional` `author:toadlyBroodle`
A poll note is a [nostr event](01.md) (kind `6969`) for conducting paid polls. A poll presents two or more voting options, which participants my vote on by sending regular [zap events](57.md) which include an additional `poll_option` vote tag. Poll results may be blinded, until after users have voted. Polls may specify a `closed_at` time, after which results should be unblinded, closed to new votes, and the tally considered final. Poll options may be tallied by either satoshi `value` or vote `count`. Polls may additionally specify a `value_minimum` to include votes in the tally and a `consensus_threshold` for assessing the state of consensus. A poll note is a [nostr event](01.md) (kind `6969`) for conducting paid polls. A poll presents two or more voting options, which participants my vote on by sending regular [zap events](57.md) which include an additional `poll_option` vote tag. Poll results should be blinded, until after users have voted. Polls should specify a `closed_at` time, after which results be unblinded, closed to new votes, and the tally considered final. Polls may specify either `value_maximum` or `value_minimum` satoshi valuations for determining which zaps are included in the tally. Polls may also specify a `consensus_threshold` for assessing the state of consensus.
## Purpose ## Purpose
The purpose of poll notes is to conduct quantitative public opinion polls over nostr by requiring voters pay to participate. By tying vote amounts and counts to real satoshi valuations, nostr polls intend to provide superior signal compared to other free polling models. Imposing real monetary costs on participants should also discourage attempts at fraudulent result manipulation, by automated or other means. The purpose of poll notes is to conduct quantitative public opinion polls over nostr by requiring voters pay to participate. By tallying results to real satoshi valuations, nostr polls intend to provide superior signal compared to other free polling models. Imposing real monetary costs on participants should also discourage attempts at fraudulent result manipulation, by automated or other means.
Distinct `value` and `count` `tally_method`s are defined to enable two different polling types. Polls tallied by total zapped `value` allow for weighting of votes by their associated satoshi valuations, while polls tallyied by `count` force an equal weighting of all votes, regardless of their satoshi amounts (provided they meet the `value_minimum`, when specified). By including a `value_maximum` limit, polls can reduce the likelihood of 'whale' votes discounting many smaller 'shrimp' votes. Likewise, by including a `value_minimum` limit, polls can make automated vote flooding attacks prohibitively expensive. However, both limits remain optional to allow for freedom in poll design.
Both `tally_method` types have their own strengths and weaknesses: `value` polls may encourage larger bidding-style submissions and are resilient against a single entity submitting repeated low-value votes, however, they also allow for a single 'whale' voter to discount many smaller 'shrimp' voters; while `count` polls may encourage increased voter participation, by enforcing an equal weighting of all votes, but are more susceptible to repeated voter count manipulations. A careful balancing of all poll attributes should enable pollers to conduct polls with meaningful and valuable outcomes.
A careful balancing of all poll attributes should enable pollers to design and conduct polls with meaningful and valuable outcomes.
## Poll format ## Poll format
A poll event: A poll event:
* MUST contain a primary description string, specified in the `content` field * MUST contain a primary description string, specified in the `content` field
* MUST contain a predefined list of voting options, defined in a `poll_options` tag * MUST contain a `poll_options` tag, containing a serialized key-value array of vote options, formatted as below
* MUST include at least 2 voting options, each with its own unique description string * MUST include at least 2 voting options, each with its own unique description string
* MUST specify a primary `tally_method`: either `value` OR `count`
* SHOULD specify a `closed_at` time: * SHOULD specify a `closed_at` time:
* a `closed_at` value of less than or equal to the `created_at` field indicates a poll SHOULD NOT be closed. * a `closed_at` value of less than or equal to the `created_at` field indicates a poll SHOULD NOT be closed.
* MAY specify a `value_maximum` satoshi value for zapped votes to be included in the tally
* MAY specify a `value_minimum` satoshi value for zapped votes to be included in the tally * MAY specify a `value_minimum` satoshi value for zapped votes to be included in the tally
* MAY include a `consensus_threshold` (0-100), representing a percentage threshold for any single vote option to achieve poll consensus * MAY include a `consensus_threshold` (0-100), representing a percentage threshold for any single vote option to achieve poll consensus
* a `consensus_threshold` of '0' indicates no threshold is specified. * a `consensus_threshold` of '0' indicates no threshold is specified.
@ -37,8 +35,8 @@ A poll event:
["e", <32-bytes hex of the id of another event>, <recommended relay URL>], ["e", <32-bytes hex of the id of another event>, <recommended relay URL>],
["p", <32-bytes hex of the key>, <recommended relay URL>], ["p", <32-bytes hex of the key>, <recommended relay URL>],
["poll_options", "[[0, 'poll option 0 description string'], [1, 'poll option 1 description string'], [<n>, 'poll option <n> description string']]"], ["poll_options", "[[0, 'poll option 0 description string'], [1, 'poll option 1 description string'], [<n>, 'poll option <n> description string']]"],
["tally_method", "value"||"count"], ["value_maximum", "maximum satoshi value for inclusion in tally"],
["value_minimum", "minimum satoshi value to vote"], ["value_minimum", "minimum satoshi value for inclusion in tally"],
["consensus_threshold", "required percentage to attain consensus <0..100>"], ["consensus_threshold", "required percentage to attain consensus <0..100>"],
["closed_at", "unix timestamp in seconds"], ["closed_at", "unix timestamp in seconds"],
], ],
@ -53,7 +51,7 @@ Poll options are voted on by sending [zap events](57.md) (to the original poll e
The zap request event (kind `9734`): The zap request event (kind `9734`):
* MUST include exactly 1 `poll_option` tag * MUST include exactly 1 `poll_option` tag
* MUST reference the vote option by its corresponding integer `n`, chosen from the original poll event's list of predefined `polling_options` * MUST reference the vote option by its corresponding integer `n`, chosen from the original poll event's key-value array of predefined `polling_options`
```json ```json
"tags": [ "tags": [
@ -68,38 +66,28 @@ The zap request event (kind `9734`):
To avoid ambiguity of results, strict adherence to the following rules is vital when tallying and rendering poll outcomes. To avoid ambiguity of results, strict adherence to the following rules is vital when tallying and rendering poll outcomes.
A tallying client: A tallying client:
* MUST clearly indicate the `tally_method` and `value_minimum` (if specified) to potential participants before vote submission * MUST clearly indicate the `value_maximum` and `value_minimum` (when specified) to participants before they vote
* MUST tally poll results according to the primary `tally_method` specified: * MUST ONLY include full satoshi value amounts in option tallies from all eligible zaps, according to the following criteria:
* when tallying by `value`, clients: * if a `value_maximum` is specified, clients:
* MUST include full satoshi values from all relevant zap events * MUST include zap amounts less than or equal to `value_maximum` in the tally
* MUST include multiple zap events from single users * MUST NOT include zap amounts greater than `value_maximum` in the tally
* MUST treat the vote option with the highest satoshi value as the winning option
* when tallying by `count`, clients:
* MUST ONLY count the most recent zap from a unique user as 1 vote
* MUST NOT include zapped satoshi values in the tally
* MUST NOT count votes from anonymous users
* MUST treat the vote option with the most unique votes as the winning option
* if a `value_minimum` is specified, clients: * if a `value_minimum` is specified, clients:
* MUST ONLY include zaps exceeding the satoshi `value_minimum` in the tally * MUST include zap amounts equal or greater than `value_minimum` in the tally
* when a `closed_at` time is specified, clients: * MUST NOT include zap amounts less than `value_minimum` in the tally
* MUST NOT include late votes received after `closed_at` time * if a valid `closed_at` time is specified, clients:
* SHOULD publicly blind results until after a user's vote has been received * MUST NOT tally late votes received after `closed_at` time
* SHOULD publicly display results after the `closed_at` time has passed
* when a `closed_at` time is NOT specified (is less than or equal to `created_at`), clients:
* MUST include all votes in tallies
* MUST treat the most recent tally as the definitive outcome
After the above rules are applied and clearly rendered, a tallying client: Additionally, a tallying client:
* MUST display the distribution percentages, from the total, for each vote option * MUST display the distribution percentages, from the tally total, for each vote option tally
* if a non-zero `consensus_threshold` is specified, clients: * MUST display the `consensus_threshold` (if specified) relative to the winning vote percentage
* MUST indicate the state of consensus by displaying its value relative to the final percentage of the winning vote * SHOULD publicly blind results until after a user's vote has been received
* MAY display the secondary tally method result, for statistical purposes, along with other associated poll metrics and comments * SHOULD publicly display results after the `closed_at` time has passed (if specified)
* MAY display the counts of zap events received for each option, along with other poll statistics
Strict adherence to these requirements should enable a standardized means of quantitatively assessing the distribution of opinion regarding a poll's content amongst poll participants, determining a winning outcome, and possibly achieving consensus. However, until this protocol is further tested, refined, and proven robust, polls should probably not be considered authoritative nor binding. Strict adherence to these requirements should enable a standardized means of quantitatively assessing the distribution of opinion regarding a poll's content amongst poll participants, determining a winning outcome, and possibly achieving consensus. However, until this protocol is further tested, refined, and proven robust, polls should probably not be considered authoritative nor binding.
## TODO ## TODO
* refine NIP#69 based RFC feedback * refine NIP#69 based RFC feedback
* implement polls in 1 relay
* implement polls in 2 clients * implement polls in 2 clients
* merge with nostr-protocol/NIPs * merge with nostr-protocol/NIPs