Default ruleset
When no preset is configured for an installation, the system falls back to these in-memory defaults (lib/scoring/rules.ts):
{
basePoints: [
{ type: 'commit', points: 10 },
{ type: 'pr_merge', points: 50 },
{ type: 'review', points: 20 },
{ type: 'issue_open', points: 10 },
{ type: 'issue_close', points: 10 },
{ type: 'comment', points: 3 },
],
multipliers: [
{ kind: 'merged_pr_commit', factor: 1.2, appliesTo: ['commit'] },
{ kind: 'pr_linked_to_issue', factor: 1.1, appliesTo: ['pr_merge', 'commit'] },
{ kind: 'first_activity', factor: 1.5, appliesTo: ['commit', 'pr_merge', 'review', 'issue_open', 'issue_close', 'comment'] },
],
dailyQuotas: [
{ type: 'commit', limit: 4 },
{ type: 'comment', limit: 4 },
],
diminishingReturns: { weeklyThreshold: 9, decayFactor: 0.11, floorFraction: 0.2 },
zeroPointConditions: [
{ kind: 'self_review', enabled: true },
{ kind: 'self_merge', enabled: true },
{ kind: 'bot_activity', enabled: true },
{ kind: 'issue_closed_no_pr', enabled: true },
{ kind: 'pr_closed_no_merge', enabled: true },
],
spamPenalty: -12,
prClosedNoMergePenalty: -10,
}Key notes:
spamPenaltyandprClosedNoMergePenaltyare negative values — they’re subtracted from the total scorefirst_activityfires once per signal type per compute cycle (not per day)
Custom presets
Each installation can define multiple named presets, stored in the scoring_presets table (single consolidated migration). Here’s how they work:
- One active preset at a time — the active preset is used for leaderboard computation
- Default preset — created automatically on installation setup, cannot be deleted
- Non-active presets — can be freely created, edited, and deleted
- Scoped per installation — presets from one installation don’t leak into another
Switching between presets is instant because scores are pre-computed for all time periods when computed. See the Scoring Overview for the 3-phase pipeline (ingest → score → serve).
UI editor
The scoring rules page at /[organization]/leaderboards/scoring provides a structured form editor:
- View mode — cards showing base points, multipliers, daily quotas, diminishing returns, zero-point conditions, and penalties
- Edit mode — tabbed form controls:
- Points — signal type selector + number input per base point rule, add/remove rows
- Multipliers — factor input per multiplier, clickable badges to toggle applies-to signal types
- Quotas — daily quota table with add/remove, diminishing returns three-field grid
- Conditions — toggle switches per zero-point condition
- Penalties — two number inputs with helper text
- Create mode — same as edit mode with an additional preset name field
A preset selector and Set Active / Add / Delete buttons are available in the toolbar.
API endpoints
Get leaderboard scores
POST /api/{org}/leaderboard/score
GET /api/{org}/leaderboard/score| Param | Type | Default | Description |
|---|---|---|---|
scopeType | string | organization | organization, repository, or team |
scopeId | string | {org} | Repo name (org/repo) or team slug |
entityType | string | contributor | contributor, repository, or team |
from | ISO 8601 | — | Start date (inclusive) for signal window |
to | ISO 8601 | — | End date (inclusive) for signal window |
Response:
{
"entries": [
{
"userId": 12345,
"userLogin": "octocat",
"score": 342.5,
"breakdown": {
"commits": 120,
"pullRequests": 150,
"reviews": 60,
"issues": 20,
"comments": 9,
"penalties": -10
},
"rank": 1
}
],
"computedAt": "2026-05-18T12:00:00.000Z",
"cacheStatus": "fresh"
}When entityType=repository, userLogin is the repo name.
When entityType=team, userLogin is the team name.
Force sync
POST /api/{org}/leaderboard/syncAlways performs a full GitHub fetch (skips cache). Accepts the same scopeType, scopeId, entityType params.
Scoring rules CRUD
GET /api/{org}/leaderboard/rules?presetId={id}&presetName={name}
PUT /api/{org}/leaderboard/rulesReturns the full ScoringRuleset object (GET) or updates it (PUT, admin only). Query params filter by preset.
Preset management
GET /api/{org}/leaderboard/rules/presets
POST /api/{org}/leaderboard/rules/presets
PATCH /api/{org}/leaderboard/rules/presets
DELETE /api/{org}/leaderboard/rules/presets?presetId={id}Manage named ruleset presets per installation. PATCH updates a preset’s name or rules. DELETE removes a non-active preset (Default cannot be deleted).
Related
- Overview — architecture, pipeline, entity types
- Scoring Engine — signal types, algorithm, multipliers, quotas
- Reference — DB schema, types, module map