diff --git a/README.md b/README.md index aceb7b4..73828d7 100644 --- a/README.md +++ b/README.md @@ -97,7 +97,7 @@ OSSRank must stay honest: - Use official GitHub APIs only; never scrape GitHub HTML. - Treat GitHub profile location text as unverified free text. -- Rank observed public signals, not private contributions. V1 contributor pages prioritize one-year GitHub GraphQL commit totals, one-year public pull request totals, repository count, and followers. +- Rank observed public signals, not private contributions. Contributor pages prioritize one-year GitHub GraphQL commit totals, one-year public pull request totals, repository count, and followers. Raw commit totals stay visible, but ranking uses a per-user burst-adjusted commit signal when a short anomalous daily spike exceeds that contributor's adaptive baseline cap. - Preserve last-known-good data when refreshes fail. - Keep the product flow simple: choose a country, view contributors, sort by commits/public PRs/repos/followers, or view the single projects page. - Avoid claims of complete global coverage, endorsement, nationality, employment status, or identity attributes. diff --git a/package.json b/package.json index 619c922..008807e 100644 --- a/package.json +++ b/package.json @@ -9,12 +9,13 @@ "refresh:fixtures": "tsx scripts/refresh-fixtures.ts", "validate:data": "tsx scripts/validate-data.ts data/latest", "build": "tsx scripts/build-site.ts --data data/latest --history data/history --out dist && pnpm run build:cli", - "test": "pnpm run check && pnpm run refresh:fixtures && pnpm run validate:data && pnpm run build && pnpm run smoke:cli", + "test": "pnpm run test:burst && pnpm run check && pnpm run refresh:fixtures && pnpm run validate:data && pnpm run build && pnpm run smoke:cli", "dev": "pnpm run build && npx --yes serve dist", "deploy:cloudflare": "pnpm run build && wrangler pages deploy dist --project-name ossrank", "build:cli": "tsc -p tsconfig.cli.json && node scripts/fix-cli-shebang.cjs", "smoke:cli": "pnpm run build:cli && node dist-cli/cli.js rank contributors --input fixtures/contributors.json --limit 2 --format table && node dist-cli/cli.js token-check --token demo && ! node dist-cli/cli.js rank contributors --input fixtures/contributors.json --limit nope", - "refresh:live": "tsx src/cli.ts refresh --mode live --limit ${OSSRANK_LIMIT:-20}" + "refresh:live": "tsx src/cli.ts refresh --mode live --limit ${OSSRANK_LIMIT:-20}", + "test:burst": "tsx scripts/verify-burst-adjustment.ts" }, "dependencies": {}, "devDependencies": { diff --git a/scripts/build-site.ts b/scripts/build-site.ts index 12ba6a2..cf396ec 100644 --- a/scripts/build-site.ts +++ b/scripts/build-site.ts @@ -1,7 +1,7 @@ import { mkdir, readFile, readdir, rm, writeFile, cp } from 'node:fs/promises'; import { dirname, join } from 'node:path'; import { escapeHtml } from '../src/lib/html.js'; -import { legitimacyScore, momentumScore } from '../src/lib/ranking.js'; +import { contributorCommitSignal, legitimacyScore, momentumScore } from '../src/lib/ranking.js'; import type { Manifest, ManifestShard, RankedContributor, RankedProject, RankingSnapshot } from '../src/lib/types.js'; const args = new Map(); @@ -138,9 +138,17 @@ function rankMovementBadge(entry: RankedContributor): string { return `↓${down}`; } +function commitMetric(entry: RankedContributor): string { + const raw = entry.observed_public_commits ?? entry.public_contributions; + const adjusted = contributorCommitSignal(entry); + if (!entry.contribution_burst_adjustment) return `${raw.toLocaleString()}`; + const adjustment = entry.contribution_burst_adjustment; + return `${adjusted.toLocaleString()}raw ${raw.toLocaleString()} · burst-adjusted`; +} + function contributorTable(snapshot: RankingSnapshot): string { const rows = [...snapshot.entries].sort((a, b) => a.rank - b.rank); - return `
${rows.map((entry) => ``).join('')}
RankMovementUsernameLocationDiscovery
#${entry.rank}${rankMovementBadge(entry)}${escapeHtml(entry.name ?? 'Public GitHub profile')}${(entry.observed_public_commits ?? 0).toLocaleString()}${(entry.observed_public_pull_requests ?? 0).toLocaleString()}${(entry.public_repos ?? 0).toLocaleString()}${entry.followers.toLocaleString()}${escapeHtml(entry.location ?? 'Unknown')}${escapeHtml(entry.location_confidence ?? 'unknown')}${statusPill(entry.discovered_by_query ?? 'query', 'source')}