diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index 9c466f88..59c2462a 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -60,7 +60,7 @@ representative at an online or offline event. Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at -[TODO: maintainer email] or conduct@vortexprotocol.io. +conduct@vortexprotocol.io. All complaints will be reviewed and investigated promptly and fairly. All community leaders are obligated to respect the privacy and security of the diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 52d8dc74..ae14bc29 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -14,6 +14,16 @@ All contributors and maintainers are expected to adhere to our [Code of Conduct] 4. **Browser storage**: Never touch `localStorage`/`sessionStorage` directly; register the key in `STORAGE_KEYS` and use the `storage` facade in `src/lib/storage.ts` (lint-enforced). 5. **Submit PR**: Open a pull request detailing your changes and referencing the closed issue (`Closes #N`). +## Good First Issue Mentors + +A maintainer can opt a good-first issue into having a mentor by adding `Mentor: ` to its entry in `issues.md`, next to `Good first issue: yes`: + +``` +- #14 Swap Sound Effects (Complexity: Trivial, Points: 50, Status: Open, Contributor: None, Good first issue: yes, Mentor: octocat) +``` + +The Wave Tracker then shows an "Ask @handle about this one" link to that person's GitHub profile on the issue's card. Mentoring is optional and informal: the mentor agrees to answer questions about that specific issue (scope, where to look in the code, review expectations) on a best-effort basis. They are not expected to write the change, and the link is not an in-app chat or scheduling system. Only add a mentor who has agreed to it, and remove the field if they can no longer help. The handle is not validated against GitHub when `issues.md` is parsed. + ## Reporting Conduct Issues -If you experience or witness unacceptable behavior, please contact the maintainers at `conduct@vortexprotocol.io` or `[TODO: maintainer email]`. +If you experience or witness unacceptable behavior, please contact the maintainers at `conduct@vortexprotocol.io`, the single conduct-reporting channel (also listed in the [Code of Conduct](./CODE_OF_CONDUCT.md)). diff --git a/docs/delegate-accountability.md b/docs/delegate-accountability.md new file mode 100644 index 00000000..1ff3bea6 --- /dev/null +++ b/docs/delegate-accountability.md @@ -0,0 +1,36 @@ +# Delegate accountability score + +The accountability score is a single 0-100 signal shown as a badge in the delegate directory +(`/governance/delegates`) and the voter-history page header (`/governance/voter/[address]`). It sits +alongside the raw `participationRate` and `proposalsVoted` stats and does not replace them. It is +informational only and must never gate an on-chain action. + +Implementation: `src/lib/delegateAccountability.ts` (`computeAccountabilityScore`), a pure function +with no fetching. + +## Formula + +Three components, each in the range 0-1: + +| Component | Weight | Definition | +| -------------- | ------ | ---------- | +| Participation | 0.5 | The delegate's `participationRate`. | +| Activity | 0.3 | Mean recency weight of the delegate's votes, where a vote of age `d` days weighs `0.5^(d / 90)` (90-day half-life). | +| Alignment | 0.2 | Share of votes (with a known outcome) that match the winning choice. | + +`score = round(100 * sum(weight_i * value_i) / sum(weight_i))` + +Components that cannot be computed are dropped and the remaining weights are renormalised: + +- No per-proposal vote history: only participation is used (the directory currently has no history). +- No votes with a known majority outcome: alignment is skipped. + +## Insufficient history + +If `max(vote history length, proposalsVoted) < 3`, no number is shown. The badge reads +"Insufficient history" so new delegates are neither flattered nor penalised. + +## Limitations + +Majority alignment is a descriptive signal, not a judgement: voting with a minority is legitimate. +It carries the lowest weight for that reason. diff --git a/issues.md b/issues.md index 76509b9e..b1197410 100644 --- a/issues.md +++ b/issues.md @@ -23,6 +23,9 @@ contributors dashboard). An issue is only labelled when it meets **all** of: WebSocket live-data layering. 4. **Bounded** — the expected result is concrete and easy to verify. +A labelled issue may optionally name a mentor with `Mentor: ` in its +entry; see "Good First Issue Mentors" in `CONTRIBUTING.md`. + When in doubt, an issue stays unlabelled: complexity tier alone isn't the test (some Trivial issues touch the signing path, and nothing here is labelled just to fill a quota). diff --git a/src/app/contributors/ContributorsPageClient.test.tsx b/src/app/contributors/ContributorsPageClient.test.tsx index fdf0458e..2fa63597 100644 --- a/src/app/contributors/ContributorsPageClient.test.tsx +++ b/src/app/contributors/ContributorsPageClient.test.tsx @@ -1,10 +1,18 @@ -import { describe, expect, it, vi } from "vitest"; +import { beforeEach, describe, expect, it, vi } from "vitest"; import { render, screen, within } from "@testing-library/react"; import userEvent from "@testing-library/user-event"; import { parseIssuesMarkdown } from "@/lib/issuesParser"; vi.mock("@/components/Nav", () => ({ Nav: () =>