TrustGraph
Portable, evidence-backed reputation profiles for developers, scored from GitHub, Stack Overflow, Devpost and peer verification.

Overview
TrustGraph builds a public reputation profile for a developer out of things that can be checked: GitHub repos and merged PRs, Stack Overflow answers, Devpost and Devfolio hackathons, talks, and confirmations from peers. Each profile gets a trust score with a breakdown, a timeline, an embeddable badge, and a recruiter-facing view. The frontend is Next.js 16 and the API is a Go service on Chi backed by MongoDB Atlas.
The problem
Resumes and LinkedIn profiles are self-reported, and the real signal about a developer is spread across a dozen platforms that nobody has time to cross-check. I wanted one profile where every claim points back to a source, the score explains itself, and a recruiter can search across those profiles instead of keyword-matching CVs.
What I built
- A Go API (Chi router, Clerk JWT middleware, API-key middleware for partners, admin middleware) exposing profiles, trust scores, onboarding, billing, peer verification, disputes and recruiter search under
/v1. - Connectors for GitHub, Stack Overflow, Devpost, Devfolio and LinkedIn that turn platform stats into typed evidence items (
merged_pr,open_source_impact,accepted_answer,hackathon_winand so on) on the profile. - A trust score in
trust_score.go: four weighted dimensions (evidence depth 0.35, consistency 0.25, peer verification 0.15, impact 0.25), with verified evidence weighted 1.4x, age decay down to a 0.6 floor, log-scaled points for stars and followers, and a cap on how many language items can count. - An enrichment agent that pulls web context through Tavily and Firecrawl and asks Gemini for structured JSON insights, falling back to an NVIDIA-hosted model if Gemini fails.
- Recruiter talent search that parses a free-text query into filters, scores indexed profiles, and can discover more candidates on the web, with saved candidates and async search runs.
- Background jobs: daily GitHub refresh, weekly Stack Overflow refresh and digest emails, score snapshots for history charts, and outbound webhooks when a score moves by 5 points or more.
- Shadow profiles seeded in batches from public GitHub rankings, which a person can later claim, plus an SVG badge at
/badge/{handle}.svgand an HTML embed widget.
Architecture
The Next.js app talks to a single Go API, which owns all scoring, third-party ingestion and persistence.
flowchart LR
subgraph client["Client"]
web["Next.js 16 app"]
embed["Badge and embed"]
end
subgraph server["Go API"]
router["Chi router and middleware"]
sync["Profile sync"]
score["Trust score engine"]
enrich["Enrichment agent"]
talent["Recruiter search"]
jobs["Background job runner"]
end
subgraph data["Data"]
db[("MongoDB Atlas")]
end
subgraph ext["External"]
clerk["Clerk"]
sources["GitHub, Stack Overflow, Devpost, Devfolio"]
ai["Gemini and NVIDIA LLMs"]
web2["Tavily and Firecrawl"]
stripe["Stripe"]
end
web -->|"JWT"| router
embed --> router
router --> sync
router --> talent
router --> enrich
sync --> sources
sync --> score
enrich --> ai
enrich --> web2
talent --> web2
jobs --> sync
router --> db
router --> clerk
router --> stripeSystem design
What happens when a signed-in user connects their GitHub account.
sequenceDiagram
participant U as User
participant F as Next.js app
participant A as Go API
participant C as Clerk
participant G as GitHub API
participant D as MongoDB
U->>F: Connect GitHub username
F->>A: POST v1 profiles connect github with JWT
A->>C: Verify session token
C-->>A: User id
A->>G: Fetch repos, merged PRs, languages
G-->>A: Stats
A->>A: Map stats to evidence items
A->>A: Recompute trust score and timeline
A->>D: Save profile and score snapshot
A-->>F: Updated profile
F-->>U: Score reveal
Note over A,D: Daily job repeats the fetch and fires a webhook if the score moves 5 or moreDecisions & trade-offs
- Go for the API instead of Next.js route handlers. The ingestion, scoring and scheduled refresh are long-running server work, and keeping them in one typed service was simpler than spreading them across serverless functions. The cost is two deployables and two languages.
- Clerk for auth, including GitHub sign-in, so I did not need a separate GitHub OAuth app. The GitHub username comes from the Clerk account and evidence is fetched with a server-side token.
- A hand-tuned, explainable score instead of a learned model. Every dimension and weight is in one file and the API returns positive and negative signals, which matters when the score is about a person. The weights are opinions and need real data to tune.
- Background jobs run in-process on tickers. Easy to reason about, but they only run while the server is up and would need a proper queue to scale out.
What I'd do next
- Move refresh and enrichment work onto a job queue so it can run across instances and retry cleanly.
- Calibrate the score weights against profiles where the outcome is known, instead of setting them by hand.
- Widen evidence beyond developers, which the professional segment selection in onboarding already anticipates.