spb/worthdoing Public
Autonomous investigation agent that discovers, challenges, and ranks things genuinely worth doing — Claude + Firecrawl, Next.js 16, PostgreSQL
TypeScript 91.5%
SQL 5.8%
CSS 2.2%
1/**2 * WorthDoing.ai3 * Author: Simon-Pierre Boucher4 * Contact: contact@spboucher.ai5 * File: src/lib/agent/scoring.ts6 * Description: Worth Score computation — evidence-weighted aggregate with separate evidence-confidence figure.7 */89export type DimensionScore = {10 dimension: "demand" | "neglectedness" | "feasibility" | "why_now" | "impact" | "competition" | "risk";11 score: number; // 0..100, higher = better for the opportunity (risk scored as "risk manageability")12 confidence: number; // 0..1 — how well the evidence supports this score13};1415const WEIGHTS: Record<DimensionScore["dimension"], number> = {16 demand: 0.22,17 neglectedness: 0.16,18 feasibility: 0.16,19 why_now: 0.14,20 impact: 0.18,21 competition: 0.08,22 risk: 0.06,23};2425/**26 * Worth Score = weighted mean of dimension scores (weights renormalized over27 * the dimensions actually provided). Evidence confidence is the same weighted28 * mean over per-dimension confidences — reported separately, never blended in:29 * a 93 backed by 41% confidence must look different from an 84 backed by 91%.30 */31export function computeWorthScore(scores: DimensionScore[]): {32 worthScore: number;33 evidenceConfidence: number;34} {35 const totalWeight = scores.reduce((sum, s) => sum + WEIGHTS[s.dimension], 0);36 if (totalWeight === 0) return { worthScore: 0, evidenceConfidence: 0 };37 let worth = 0;38 let conf = 0;39 for (const s of scores) {40 const w = WEIGHTS[s.dimension] / totalWeight;41 worth += w * s.score;42 conf += w * s.confidence;43 }44 return {45 worthScore: Math.round(worth * 10) / 10,46 evidenceConfidence: Math.round(conf * 1000) / 1000,47 };48}49