Skip to content

Conversation

Doordashcon
Copy link
Contributor

@Doordashcon Doordashcon commented May 21, 2025

Ambassador Configurations

This PR implements the revised technical specification for the Ambassador Program. Key changes include:

Core Functionality

  1. Rank System

    • Added 7 ranks (0-6) with distinct voting powers:
      • Advocate (0): n/a
      • Associate (1): 1 vote
      • Lead (2): 3 votes
      • Senior (3): 6 votes
      • Principal (4): 10 votes
      • Global (5): 15 votes
      • Global (6): 21 votes
  2. Membership Management

    • Off-chain Identity verification
    • Offboarding:
      • Stepped Decay in achieved through bump which can be automated off-chain or through Task API.
      • Removal if necessary is achieved through OpenGov voting for all members / SeniorAmbassador for only AssociateAmbassador.
    • Promotion & Demotion:
      • Any ranked(i.e. I - VI) member can request promotion by submitting a referanda.
      • Demotion is achieved through OpenGov voting for all members / SeniorAmbassador for only AssociateAmbassador.
  3. Voting System

    • Rank-weighted voting for internal decisions.
    • Monthly voting schedule (last working day).

Treasury & Tipping

  • TREASURY origin and track.
  • Tip origin and track.

Implementations

  • Removed Ambassador Salary pallet
  • pallet-ranked-collective migration + unit testing

@Doordashcon Doordashcon marked this pull request as ready for review May 27, 2025 15:04
///
/// The value of 21 comes from the initial OpenGov proposal: <https://github.com/polkadot-fellows/runtimes/issues/264>
pub struct AmbassadorMemberCount;
impl MaybeConvert<Rank, MemberIndex> for AmbassadorMemberCount {
fn maybe_convert(rank: Rank) -> Option<MemberIndex> {
(rank == 3).then_some(21)
(rank == 6).then_some(21)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There isn't such a limit in the latest manifesto

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

noted

@@ -131,29 +124,16 @@ impl pallet_ranked_collective::Config<AmbassadorCollectiveInstance> for Runtime
#[cfg(feature = "runtime-benchmarks")]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you want to enable some promotion logic or wait for it until we have a smart contract?

#[cfg(feature = "runtime-benchmarks")]
type MinRankOfClass = tracks::MinRankOfClass;
type VoteWeight = Geometric;
type AddOrigin = OpenGovOrGlobalHead;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additional Ambassadors will not be able to join until Polkadot Hub is ready and Jesse can build a smart contract to allow the joining process

Should we maybe leave this blank?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AddOrigin & ExchangeOrigin can be?

pub type RootOrOpenGov = EitherOfDiverse<
	EnsureRoot<AccountId>,
	EnsureXcm<IsVoiceOfBody<GovernanceLocation, FellowshipAdminBodyId>>,
>;

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes reasonable.

type VoteWeight = Geometric;
type AddOrigin = OpenGovOrGlobalHead;
type ExchangeOrigin = OpenGovOrGlobalHead;
type MemberSwappedHandler = crate::AmbassadorCore;
type MaxMemberCount = ();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should limit this somehow since its running on a system chain. 512 or 1024 maybe? It can be increased in the future but with the current config it would allow one malicious HA to add millions of accounts and slow down the collectives chain.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did not consider this...

Considering the event of a malicious HA, adding members through OpenGov seems like a more general solution?

The limits can still be abused IMO.

Copy link
Member

@ggwpez ggwpez Aug 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additional Ambassadors will not be able to join until Polkadot Hub is ready and Jesse can build a smart contract to allow the joining process.

Maybe we just disable it for now? (from the gdoc manifesto)

// This list was created by collating community-submitted addresses from an off-chain document source
// https://docs.google.com/spreadsheets/d/1uE5nDKuMZDqlj9q2tvnk_tngyU1Cokl0tQKwSigvJLA/edit?gid=0#gid=0,
// then converting each Polkadot SS58 address to its raw public key (32-byte hex) using:
// `subkey inspect <SS58_ADDRESS>`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add something like this, i put it into the preimages pallet onchain now.

A batched call with two remarks has been persisted onto the Collectives Parachchain preimages.
Hash: `0xb6087d77d3b4b5966b9096b459283ea6f5617f4a96d1b4829191439f96fe3c6b` 
Transaction link: https://collectives-polkadot.subscan.io/extrinsic/7035411-2
Screenshot 2025-08-22 at 13 56 38

for _ in 0..desired_rank {
let _ = <RankedCollective<T, I> as RankedMembers>::promote(&who);
// 1 write to `IdToIndex` and `IndexToId` per promotion
weight.saturating_accrue(T::DbWeight::get().writes(2));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could also use the weights of the extrinsics but i dont mind.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Weights updated

}

/*
/// A `TryMorph` implementation which is designed to convert an aggregate `RuntimeOrigin`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we dont need it then you can delete it.

retention @ 11..=15 => retention - 8,
// A promotion vote; the track ID turns out to be 18 more than the minimum required
// rank.
promotion @ 21..=25 => promotion - 18,
Copy link
Member

@ggwpez ggwpez Aug 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think promotion and retention requires votes from the members one rank above - not two (like in the tech fellowship).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These configurations match the Tech Fellowship

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct, one rank above upwards as we only have 6 ranks.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahh I see

promotion @ 21..=25 => promotion - 18,
// A fast promotion vote; the track ID turns out to be 28 more than the minimum required
// rank.
fast_promote @ 31..=33 => fast_promote - 28,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you fix this? Please close the fixed ones.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pls review

Copy link
Member

@ggwpez ggwpez left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks generally good. I put some comments.

One more Q: Should we set the core-fellowship parameters in a migration as well?
Stuff like demotion_period (per rank)? Maybe the default zero values are sane - dont know. But it would need to be done otherwise by the ParamsOrigin.

@bkchr
Copy link
Contributor

bkchr commented Sep 10, 2025

This should go on chain as a completely separate release, so the community can vote on this properly.

@lucycldn
Copy link

This should go on chain as a completely separate release, so the community can vote on this properly.

Appreciate the point. Given the documented path to date, our reading of OpenGov is that a further on-chain vote isn’t required. I’ll share the timeline and reasoning in the Open Element channel for discussion.

@bkchr
Copy link
Contributor

bkchr commented Sep 10, 2025

Given the documented path to date, our reading of OpenGov is that a further on-chain vote isn’t required.

What documented path?

@lucycldn
Copy link

Given the documented path to date, our reading of OpenGov is that a further on-chain vote isn’t required.

What documented path?

There has been a miscommunication / understanding on process here and I am clarifying the Ambassador sentiment before responding on behalf. Ultimately, the Tech Fellowship is the final gatekeeper here, so if we need to have a separate release then are supportive.

/// - ...with an excess rank of 6 gets 21 votes.
pub struct Geometric;
impl Convert<Rank, Votes> for Geometric {
fn convert(r: Rank) -> Votes {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is causing the failing vote benchmark

@bkchr
Copy link
Contributor

bkchr commented Sep 12, 2025

the Tech Fellowship is the final gatekeeper here

I don't want to be a gatekeeper, but I also don't want to include things that are not wanted. As said, we can do a release that only contains these changes and then we let the voters decide.

Copy link

Review required! Latest push from author must always be reviewed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants