-
Notifications
You must be signed in to change notification settings - Fork 23
Leader rejection #876
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Leader rejection #876
Conversation
|
Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). View this failed invocation of the CLA check for more information. For the most up to date status, view the checks section at the bottom of the pull request. |
|
Hi @clebouleau!
|
|
Hi @vivtsai!
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you mean to edit this file?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @jimbojw , no I think this was an unintended IDE auto-formatting change
jimbojw
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewed up to leadership_rejection.utils.ts. Have not yet reviewed beyond that file (alphabetically).
| `; | ||
| } | ||
|
|
||
| private renderLRCard() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here and elsewhere, it won't be immediately clear to the reader of the code that "LR" means "Leader Rejection". Recommend spelling it out everywhere. (The renderLRRankingCard() method below, createLRRankingStage(), LRRankingStagePublicData, etc.)
| </div>`; | ||
| const waitForAllParticipants = this.stage.progress.waitForAllParticipants; | ||
|
|
||
| console.debug( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here and elsewhere, are these logs intentionally left in?
| if (showWinner) { | ||
| const winnerProfile = this.cohortService.participantMap?.[winnerId]; | ||
| if (winnerProfile) { | ||
| winnerPretty = getParticipantInlineDisplay(winnerProfile); // 👈 magic happens here |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What magic happens?
| ${rankingWinner !== null | ||
| ? `Election winner's answer:` | ||
| : 'Your answer:'} | ||
| ? `Leader's answer:` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks like it would affect experiments other than Leader Rejection.
| winnerId, | ||
| ); | ||
| // Column for participant’s leader status | ||
| columns.push(leaderStatus); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In both branches of this if/else, the code pushes two columns. It's good that they're balanced. I'm a a little concerned though about the risk of adding columns for code that may not be expecting new columns. That is, I don't know what downstream code consumes the output of getRankingStageCSVColumns() but I'd want to make sure that that code is resilient to changing the returned number of columns. (I would hope that downstream code handles this fine, I just don't know for sure.)
| // k > 1 | ||
| const topId = candidateIds[0]; | ||
| const weights: Record<string, number> = {}; | ||
| const P1 = 0.6; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function uses some magic numbers (0.6, 0.4, rho). Recommendations:
- Name the default values as module (file) level constants.
- (Optional) Parameterize the function to accept these values, with defaults.
| * Compute geometric tail weights for candidates ranked by performance. | ||
| * Input: candidates sorted descending by performance. | ||
| */ | ||
| function computeWeights(candidateIds: string[]): Record<string, number> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Recommend giving this function a more expressive name to indicate the meaning of the weights being computed.
|
|
||
| /** | ||
| * Draws a winner given a prob distribution. | ||
| * We also allow passing in a seed for reproducibility, but here we just Math.random(). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see a seed parameter. Copy-paste error?
| } | ||
| } | ||
| // fallback in case of float precision | ||
| const lastId = Object.keys(weights)[Object.keys(weights).length - 1]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: Earlier, you generate a list of Object.entries() in order to loop through them. If you created this outside of the for loop and assigned it to a const, it'd still be in scope here and you could grab the last entry. This would give you the id without recomputing the Object.keys().
Description:
This PR introduces a new experimental template designed for a Leadership Rejection experiment. The goal of the experiment is to investigate how repeated experiences of rejection from leadership roles affect future leadership ambitions, and whether these dynamics differ by gender.
To implement this, I created a fully new template inspired by the existing Lost-at-Sea template: frontend/src/shared/templates/leader_rejection_template.ts
Key Features Added:
A new selection system to get leaders (compared to Condorcet elections):
To avoid rewriting the entire reveal/payout logic, I reused ranking stages but introduced a new ranking type that:
Custom reveal page for leadership status
A new reveal component shows each participant: their status (accepted, rejected, hypothetical).
New frontend file: frontend/src/components/stages/leader_status_reveal_view.ts
New survival task (Desert Scenario)
Added a new set of items, images, and expert solutions for a desert-survival task. Assets added under:
frontend/assets/survival_desert/
Main Files Added / Modified
Backend
functions/src/stages/leadership_rejection.utils.ts — full leader-selection logic & utilities.
utils/src/stages/ranking_stage.ts — new RankingType.LR
utils/src/stages/ranking_stage.validation.ts — validation schema for LR ranking.
utils/src/stages/reveal_stage.ts — support for LR reveal items.
utils/src/stages/reveal_stage.validation.ts — validation schema updates.
utils/src/utils/algebraic.utils.ts — extended helpers for leader-selection logic.
Frontend
frontend/src/shared/templates/leader_rejection_template.ts — new experiment template.
frontend/src/components/experiment_builder/stage_builder_dialog.ts — import LR metadata + card rendering.
frontend/src/components/stages/ranking_editor.ts — new ranking type added to editor UI.
frontend/src/components/stages/ranking_participant_view.ts — new info-only LR ranking view.
frontend/src/components/stages/reveal_summary_view.ts — LR reveal routing.
frontend/src/components/stages/leader_status_reveal_view.ts — new reveal page.
frontend/src/shared/file.utils.ts — export of leader selection outcome + status.
frontend/src/components/stages/payout_summary_view.ts temporarily replaced “Election winner’s answer” with “Leader’s answer” to avoid confusion.
Assets
frontend/assets/survival_desert/ — images + expert solution PDF.
Verifications:
Verified locally in emulator
All stages progress correctly