Consultation v2 — Product Scope Document

Consultation v2 — Product Scope Document

1. Overview

Product Name: Consultation v2

Purpose: Decentralized governance platform for Radix community decision-making, replacing the Foundation-dependent v1 system before 2026 wind-down.

Components:

  1. Consultation dApp — TanStack Start web app for creating/voting/viewing governance items
  2. Vote Collector — Node.js CLI for calculating vote results from on-ledger data

Core Flow:

Anyone creates TC → Community votes For/Against →
If passes (quorum + majority) → Admin promotes to RFP →
Community votes on options → Winner determined

Tech Stack:

  • dApp: TanStack Start, Radix dApp Toolkit, PostgreSQL
  • Vote Collector: Node.js, Radix Gateway API, PostgreSQL
  • On-ledger: Scrypto components
  • Network: Configurable (Stokenet / Mainnet)

2. Users & Permissions

Role Identification Capabilities
Visitor No wallet connected View active votes, view results
Voter Wallet connected (any account) Above + create TCs, cast votes
Admin Holds owner badge Above + promote TC → RFP, update GovernanceParameters

Authentication:

  • Radix Wallet Connect via dApp Toolkit
  • Account-based identity

Voting Power:

  • Determined by LSU holdings at voting start snapshot
  • LSU converted to XRD equivalent using validator redemption rates
  • 1 XRD equivalent = 1 voting power unit

Vote Constraints:

  • One vote per account per TC/RFP
  • Votes are final — cannot change after casting
  • Must connect wallet to vote

3. Governance Items

3.1 Temperature Check (TC)

Field Description
title Short title for the TC
description Full description/rationale
vote_options For / Against (binary)
attachments Supporting files
rfc_url Link to RadixTalk RFC discussion
quorum Min participation required (from GovernanceParameters)
approval_threshold % For votes needed to pass
max_selections For future RFP phase (stored for promotion)
start Voting start instant (snapshot taken here)
deadline Voting end instant
elevated_proposal_id Links to RFP if promoted (null until promoted)

TC Lifecycle:

Created → Voting Open → Deadline Reached →
  → Passed (quorum met + majority For) → Can be promoted to RFP
  → Failed (quorum not met OR majority Against) → Archived

3.2 Request for Proposal (RFP)

Field Description
title Inherited from TC
description Inherited from TC
vote_options Multiple options (defined by admin at promotion)
attachments Inherited + additional from admin
rfc_url Inherited from TC
quorum From GovernanceParameters
approval_threshold % needed to win
max_selections How many options voter can select (usually 1)
start Voting start instant (new snapshot)
deadline Voting end instant
temperature_check_id Links back to originating TC

RFP Lifecycle:

Promoted from TC → Voting Open → Deadline Reached →
  → Winner (option with most votes if quorum met) → Executed
  → No quorum → Failed

4. Consultation dApp Features

4.1 Pages

Page Route Description
Home / Active votes + recent results
TC Detail /tc/:id TC info, tally, voters, vote/promote actions
RFP Detail /rfp/:id RFP info, options tally, voters, vote action
Create TC /tc/new Form to create new TC

4.2 Home Page

  • Active Votes — Open TCs and RFPs, sorted by deadline (soonest first)
  • Recent Results — Completed votes with pass/fail, sorted by end date
  • Each item: title, type (TC/RFP), status, deadline, participation %

4.3 TC Detail Page

  • Header: title, description, rfc_url link, attachments
  • Status: voting open/closed, time remaining
  • Tally: For vs Against (count + voting power)
  • Progress: quorum %, approval threshold
  • Voter list: account, vote, voting power
  • Voter Action: Vote For / Against (if connected + not voted + open)
  • Admin Action: Promote to RFP (if admin + passed + not promoted)

4.4 RFP Detail Page

  • Header: title, description, rfc_url link, attachments
  • Status: voting open/closed, time remaining
  • Options: each option’s count + voting power
  • Progress: quorum %
  • Voter list: account, selected option(s), voting power
  • Voter Action: Select option + Submit (if connected + not voted + open)
  • Link to originating TC

4.5 Create TC Page

  • Form: title, description, rfc_url, attachments, max_selections
  • Submit via wallet transaction

5. Vote Collector

5.1 Purpose

Node.js CLI that calculates vote results by:

  1. Reading votes from on-ledger governance contract state
  2. Fetching LSU holdings for each voter at snapshot time
  3. Converting LSU → XRD voting power via validator redemption rates
  4. Storing calculated results in PostgreSQL

5.2 Data Flow

┌─────────────────┐     ┌─────────────────┐     ┌─────────────────┐
│  Radix Gateway  │────▶│  Vote Collector │────▶│   PostgreSQL    │
│      API        │     │     (Node.js)   │     │                 │
└─────────────────┘     └─────────────────┘     └─────────────────┘

5.3 Inputs (from Radix Gateway)

Data Source
TC/RFP details Governance component state
Votes Governance component KVStore
Voter LSU holdings Account fungible resources at snapshot
LSU → XRD rate Validator component state

5.4 Outputs (to PostgreSQL)

Table Contents
tc_results TC id, status, total_for, total_against, quorum_met, passed
rfp_results RFP id, status, winning_option, quorum_met
voter_power vote_id, account, vote_choice, voting_power

5.5 Invocation

# Calculate results for specific TC
vote-collector tc <tc_id>

# Calculate results for specific RFP
vote-collector rfp <rfp_id>

5.6 Configuration

Env Var Description
NETWORK stokenet or mainnet
GATEWAY_URL Radix Gateway API endpoint
GOVERNANCE_COMPONENT Component address
DATABASE_URL PostgreSQL connection string

6. Success Criteria

6.1 Functional Requirements

Requirement Acceptance
Create TC User can submit TC via wallet transaction, appears on home page
Vote on TC User can cast For/Against vote, vote recorded on-ledger
TC Results Vote Collector calculates correct totals with LSU-weighted power
Promote TC Admin can promote passed TC to RFP with defined options
Vote on RFP User can select option, vote recorded on-ledger
RFP Results Vote Collector calculates correct totals with LSU-weighted power
View Results dApp displays accurate tallies from PostgreSQL

6.2 Non-Functional Requirements

Requirement Target
Network support Stokenet and Mainnet via config
Wallet support Radix Wallet via dApp Toolkit
Data accuracy Vote power matches on-ledger LSU at snapshot
Transparency All votes publicly visible with voter + power

7. Out of Scope (v1)

Item Reason
Vote delegation Exists in contract, not exposed in dApp v1
Admin page for GovernanceParameters Managed outside dApp
Real-time vote updates On-demand calculation only
Vote change/revocation Votes are final by design
Comment/discussion on votes Use rfc_url to RadixTalk instead

8. Open Questions

Question Impact Notes
Voting power mechanism Core calculation Currently assuming LSU → XRD
Spam protection for TCs UX / governance quality Anyone can create — may need lock amount or rate limiting later
Attachment storage dApp Where do TC/RFP attachments live? On-ledger (expensive) or off-chain ( S3)?
2 Likes

Looking good xStelea! May I propose an Abstain option?

It lets voters signal participation without forcing a For/Against position, which reduces noisy votes and makes quorum a better measure of engagement imo.

I would say:
• Abstain counts toward quorum
• Abstain does not count toward approval threshold / majority

To prevent Abstain votes making it harder to pass a TC, while still measuring engagement on a TC.

6 Likes

We still don’t have an official community-votes decisions on what should be used for voting power.
I believe Adam said FND will put that up for voting very soon - next consultation, I believe.

It’s highly probable that both XRD and Validator Staking LSUs will both be selected as valid voting power assets, so in that sense, the wording in the current proposal might become inadequate after we have that result … and you may need to revise parts of the code to properly account for what gets selected?

In any case, if the Validator Staking LSUs do become a valid voting power asset - they need to be filtered against valid running validators in the set, in my view.
The reasoning behind using these LSUs is related to them representing a form of commitment to Radix, a sort of proof-of-support. That is only true if the stake is being actively used, i.e., in the validator set that’s participating in consensus.

That might pose a challenge, since we’ll need to capture that for snapshot time and it can change meanwhile.
I believe that the snapshot “module” needs to include that information, so that the calculation module is able to do the filtering. It’s all perhaps just code and techy, but I believe it should be reflected enough in the proposal.

hello, who and how can decide the

approval_threshold % For votes needed to pass ?

what is the schedule of the LSU counter from start to end ? once a day , once an hour ?

Sounds like a good addition. @octo should be an easy add to the blueprint

1 Like

The tokens used towards calculating vote power is extendable. I used LSU since it was mentioned in previous discussions. Aiming to get a scoped version of the dApp open sourced and iterative on further improvements.

1 Like

approval_threshold % For votes needed to pass ?

It’s decided by the holder of the owner badge.

what is the schedule of the LSU counter from start to end ? once a day , once an hour ?
Manually triggered in first version

That’s not difficult to do at the snapshot time I believe, just get the active validator set LSUs. People who want to keep engaged in voting have to be sure their validator doesn’t fall out of the set right before a snapshot, and voting power is set at snapshot time

1 Like

Btw … consultation is now open from FND regarding what assets should be considered as voting power.

I believe we’ll mostly use whatever comes out of this to do our first community-run consultation … that will probably be to confirm that exact same :slight_smile:

I made a mockup based on what Stelea suggested in the initial post. It might not be fully accurate but it’s a start and probably much easier to understand than reading so much text. At-least for me was.

You can find the code here, although i will probably update with new versions, but feel free to grab or modify. I used Google AI Studio to build, so you can copy and modify also yourself in Google studio.

I have also a Video of how it works but I’ll post it on telegram as I can’t figure out how to upload directly here.

2 Likes

Something like these ?

1 Like

Yes, this looks accurate

1 Like

This is a good start.

On the create temp check page

How would you display the different vote variants?

Single choice

Multi choice

Which input element to use to define the selection limit?

I would make that max selection field as a drop-down list selection. It works better on mobile.

I’m going to be the squeaky wheel about terminology / naming :slight_smile:

I believe RFP is the wrong term to use in our situation. An RFP is something someone submits out to industry to solicit proposals to come back.

An architectural firm would submit an RFP out to their contractor pool.

The architectural firm is at the top and it submits an RFP to those outside of it or below it who then submit proposals back in response to the RFP.

What we are doing is having everything start at the bottom or outside the DAO and move up to it.

RFC (request for comments) → TC (temperature check) → GP (governance proposal) or RDIP (radixdlt dao improvement proposal) or IP (improvement proposal)

For me personally if we use GP (governance proposal) it could be viewed as a proposal to change how governance is done.

I think we need a more general term that can encompass all types of things (ie what to fund, how to upgrade the protocol, how to change the governance structure, how to vote out people).

I think XYZ Improvement Proposal is in the right direction (where XYZ is some term we agree on). I believe we all will only vote and pass something that improves radixdlt.

Ideas

  • RadixDLT Enhancement Proposal (REP)
  • RadixDLT Advancement Proposal (RAP)
  • RadixDLT Improvement Proposal (RIP)
  • RadixDLT Proposal (RP)
  • Improvement Proposal (IP)
  • Proposal (P)
1 Like

Nothing can be more fitting than P (proposal) … but I’ll bet you someone is gonna come up with a subfield for type of proposal :joy:

1 Like

@xStelea I just used the consultation Dapp currently availbe, and I have a problem.

I have ledger accounts and I have to prove ownership of those accounts EVERYTIME I vote? That would make it harder to vote on the run (ledger doesn’t work mobile & deep linking setup). When I am offshore, I can’t install the connector to corporate PCs so that would obligate me to have my own notebook with me, understand?

Wouldn’t it be possible to link those accounts ONCE and after only sign with fingerprint tap?

Have been long wanting to define the ledger just for recovery but Idk what’s possible with MFA on mainnet atm, I know it’s far from complete. But voting is simpler, right? No risk of loosing assets!!!

That is very much doable, good suggestion.

I thought of it while creating the blueprints, but what would happen if many XRD votes abstain and the quorum is hit, 1 XRD votes for, and 0 against? Would that pass? Seemed a bit silly to me then, but maybe this is just a crazy edge case. Or is it actually good behaviour, and is the silliness just a wrong intuition?

Current consultation dApp: yes that would probably be possible through the use of Personas (it probably was, some time back? but we switched to account-based voting).

Future consultation dApp: that will be hard, one of the core requirements is for the consultation dApp to not rely on a central entity, which results in not being able to use a centralized database. In other words, we need all data on-ledger. For that, you’ll have to sign with the account that is voting. What will be possible though, is to delegate the vote of your Ledger-controlled account, to an account that isn’t controlled by a Ledger. You basically allow another account to vote for you (without having to move the XRD out of the Ledger-controlled account). I think that would suit your needs right?

yes, that does the job