Problem
The trending algorithm currently uses 5 signals (rating, price change, TVL, continuation rate, recency) but none account for the author's reputation. A story by a well-established author with thousands of followers should rank higher than an identical story by an anonymous wallet, all else being equal.
Requirements
1. Build a composite author reputation score
Using data already in the users table, compute a normalized reputation score (0–1) from these inputs:
| Signal |
Source column |
Notes |
| Farcaster followers |
follower_count |
Log-scaled, larger following = more credible |
| X/Twitter followers |
x_followers_count |
Log-scaled, same logic |
| X verified |
x_verified |
Boolean bonus — verified accounts are more trustworthy |
| Neynar Score |
neynar_score |
Already 0–1 range from Neynar API |
| Quotient Score |
quotient_score |
Decimal score from Quotient Protocol |
Suggested formula (T3 can refine):
function computeAuthorReputation(user: UserRow | null): number {
if (!user) return 0; // anonymous wallet, no reputation data
// Farcaster followers (log-scaled, 0-1)
const fcFollowers = user.follower_count ?? 0;
const fcSignal = Math.min(1, Math.log10(1 + fcFollowers) / 5); // 100k followers → 1.0
// X followers (log-scaled, 0-1)
const xFollowers = Number(user.x_followers_count ?? 0);
const xSignal = Math.min(1, Math.log10(1 + xFollowers) / 5);
// X verified bonus
const xVerifiedBonus = user.x_verified ? 0.15 : 0;
// Neynar score (already ~0-1)
const neynarSignal = Number(user.neynar_score ?? 0);
// Quotient score (normalize — typical range ~0-100?)
const qScore = Number(user.quotient_score ?? 0);
const quotientSignal = Math.min(1, qScore / 100);
// Weighted composite
return Math.min(1,
fcSignal * 0.30 +
xSignal * 0.25 +
xVerifiedBonus +
neynarSignal * 0.15 +
quotientSignal * 0.15
);
}
2. Integrate into trending algorithm
Add as the 6th signal in computeTrendScore(). Rebalance weights:
| Signal |
Current Weight |
New Weight |
| Bayesian rating |
0.25 |
0.20 |
| 24h price change |
0.20 |
0.15 |
| TVL |
0.20 |
0.15 |
| Continuation rate |
0.15 |
0.15 |
| Recency |
0.20 |
0.15 |
| Author reputation |
— |
0.20 |
3. Data fetching
- In
fetchCandidatesAndRatings() or getTrendingStorylines(), batch-fetch user data for all candidate storyline writers
- Use
writer_address → look up in users table by primary_address or verified_addresses
- Single query for all candidates, not N+1
4. Graceful degradation
- If author has no user record → reputation = 0 (not penalized beyond that)
- If some fields are null (e.g., no X account) → those sub-signals contribute 0
- Stories should still be rankable purely on content/market signals even with zero reputation
Files to modify
lib/ranking.ts — add computeAuthorReputation(), update computeTrendScore() weights, batch-fetch users
- Possibly
lib/supabase.ts if new type helpers needed
Branch
task/579-author-reputation-trending
Acceptance criteria
Problem
The trending algorithm currently uses 5 signals (rating, price change, TVL, continuation rate, recency) but none account for the author's reputation. A story by a well-established author with thousands of followers should rank higher than an identical story by an anonymous wallet, all else being equal.
Requirements
1. Build a composite author reputation score
Using data already in the
userstable, compute a normalized reputation score (0–1) from these inputs:follower_countx_followers_countx_verifiedneynar_scorequotient_scoreSuggested formula (T3 can refine):
2. Integrate into trending algorithm
Add as the 6th signal in
computeTrendScore(). Rebalance weights:3. Data fetching
fetchCandidatesAndRatings()orgetTrendingStorylines(), batch-fetch user data for all candidate storyline writerswriter_address→ look up inuserstable byprimary_addressorverified_addresses4. Graceful degradation
Files to modify
lib/ranking.ts— addcomputeAuthorReputation(), updatecomputeTrendScore()weights, batch-fetch userslib/supabase.tsif new type helpers neededBranch
task/579-author-reputation-trendingAcceptance criteria