A concrete mainnet run may help make the integration case precise.
1. Select an SNS
ic-query resolves the deployed SNS catalog through SNS-W:
icq sns list --verbose
Abbreviated live output from 4 August 2026:
network: ic
sns_wasm_canister_id: qaa6y-5yaaa-aaaaa-aaafa-cai
sns_count: 53
source_endpoint: https://icp-api.io
ID NAME ROOT GOVERNANCE LEDGER
-- -------------- --------------------------- --------------------------- ---------------------------
1 Dragginz zxeu2-7aaaa-aaaaq-aaafa-cai zqfso-syaaa-aaaaq-aaafq-cai zfcdd-tqaaa-aaaaq-aaaga-cai
2 OpenChat 3e3x2-xyaaa-aaaaq-aaalq-cai 2jvtu-yqaaa-aaaaq-aaama-cai 2ouva-viaaa-aaaaq-aaamq-cai
3 unnamed-23ten 23ten-uaaaa-aaaaq-aaapa-cai 24scz-zyaaa-aaaaq-aaapq-cai 7ajy4-sqaaa-aaaaq-aaaqa-cai
...
For convenience the following commands select Dragginz by catalog ID:
SNS=1
The ID is only lookup/display metadata. The resulting evidence records and compares the stable Root, Governance, ledger, swap, index and SNS-W principals.
2. Exhaust the current neuron API
The existing command brackets a strict list_neurons walk with complete reads of:
get_running_sns_version;
- the nervous-system parameters; and
get_latest_reward_event.
It then reads all neuron pages and repeats those three reads. Any changed bracket, duplicate neuron ID, overlapping page, cursor regression, row-ceiling violation or missing API-exhaustion evidence rejects the checkpoint.
icq sns reward checkpoint "$SNS"
The live Dragginz result was:
network: ic
sns_id: 1
name: Dragginz
root_canister_id: zxeu2-7aaaa-aaaaq-aaafa-cai
governance_canister_id: zqfso-syaaa-aaaaq-aaafq-cai
collection_status: api_exhausted_observed
point_in_time_guaranteed: no
collection_started_at: 2026-08-04T10:56:30Z
collection_completed_at: 2026-08-04T10:58:21Z
page_count: 126
row_count: 12530
collection_row_ceiling: 200000
client_query_count: 134
reward_event_end_timestamp_seconds: 1785801600
reward_event_round: 20749
reward_event_distributed: 0.00
aggregate_unstaked_maturity: 0.00
aggregate_staked_maturity: 0.00
aggregate_combined_maturity: 0.00
This is a useful real example of the missing evidence:
- Governance successfully settled a specific reward event.
- The complete neuron API contained 12,530 neurons.
- Native maturity distribution was zero.
- Consequently, all observed maturity totals were zero.
- The existing API therefore provides no way to reconstruct the relative participation allocation after settlement.
The ballots have gone, and maturity deltas contain no information from which the per-neuron proportions can be recovered.
3. Existing positive-reward reconciliation
For an appropriately configured SNS with a positive native reward distribution, the current workaround is:
SNS=1
BEFORE=dragginz-before.json
icq sns reward checkpoint "$SNS" --json > "$BEFORE"
BEFORE_EVENT="$(
jq -er '.reward_event_after.end_timestamp_seconds' "$BEFORE"
)"
printf 'before reward event: %s\n' "$BEFORE_EVENT"
# Run after the immediate next reward event has settled.
icq sns reward checkpoint "$SNS" --json > "$AFTER"
AFTER_EVENT="$(
jq -er '.reward_event_after.end_timestamp_seconds' "$AFTER"
)"
printf 'after reward event: %s\n' "$AFTER_EVENT"
test "$AFTER_EVENT" -gt "$BEFORE_EVENT"
icq sns reward diff "$BEFORE" "$AFTER" --json > "$DIFF"
jq '{
allocation_status,
before_event: .before.reward_event_end_timestamp_seconds,
after_event: .after.reward_event_end_timestamp_seconds,
distributed_e8s_equivalent,
aggregate_maturity_delta_e8s_equivalent,
summed_neuron_maturity_delta_e8s_equivalent,
aggregate_reconciled,
per_neuron_reconciled,
row_count: (.rows | length),
invalid_reasons
}' "$DIFF"
A positive allocation is accepted only if:
sum(per-neuron maturity deltas)
== aggregate maturity delta
== reward_event.distributed_e8s_equivalent
It also requires non-negative explained deltas, stable canister identity, an immediate-successor reward event, no missing neurons, and no maturity conversion during the observation interval.
This is useful verification, but it is necessarily an inference from minted maturity. It cannot recover participation when the native reward purse is zero, as the live Dragginz event demonstrates.
4. Flow enabled by the proposed Governance evidence
The proposed field would replace that inference with the exact value Governance already computes during settlement.
For reward event E and neuron i, retain:
E = reward_event_end_timestamp_seconds
w_i = exact pre-purse participation weight calculated for neuron i
An API-exhausted collector can then:
- Read and retain the complete latest reward event and running Governance version.
- Exhaust
list_neurons.
- Select each neuron’s weight tagged with exactly
E.
- Reject a missing weight, duplicate neuron, mixed event timestamp or unstable bracket.
- Calculate with checked integer arithmetic:
W = sum(w_i)
- Reconcile
W with an authoritative event-level total participation weight, if that total is exposed.
- Atomically publish rows of:
reward_event_end_timestamp_seconds
neuron_id
participation_weight
total_participation_weight
- Let an external reward system distribute a separate pool
P proportionally:
neuron_payout_i = floor(P * w_i / W)
The payout system must separately define deterministic remainder handling and an authenticated beneficiary or claim mechanism. Neuron permissions do not identify a canonical payment beneficiary.
Most importantly, this works when:
reward_event.distributed_e8s_equivalent = 0
because w_i and W describe voting participation before the native reward purse is applied.
The live Dragginz example would therefore change from “12,530 zero maturity rows with no recoverable allocation” into a directly collectable, event-labelled participation allocation—without retaining any ballots and without polling proposal deadlines.
Tagging every value with reward_event_end_timestamp_seconds also makes mixed-event pagination detectable. A small bounded history would make collection more operationally robust: the Dragginz walk above required 126 pages and approximately 111 seconds, while a latest-only value must always be collected before the following reward event replaces it.
This is a narrow settlement artifact rather than permanent ballot history. It directly addresses the zero-to-round_duration_seconds ballot collection window documented in the [2022 discussion](https://forum.dfinity.org/t/sns-proposal-ended-ballot-information/17300), while avoiding the storage and governance-transparency questions involved in retaining every ballot.