packages/api/services/scoring.py is the core AN Score engine.
-
Composite score calculation
- 17 dimensions (
I1-I7,F1-F7,O1-O3) - weighted composite with proportional redistribution for N/A dimensions
- one-decimal final score
- 17 dimensions (
-
Confidence model
- evidence count signal
- freshness decay signal (minutes → days)
- probe diversity signal (+ production telemetry bonus)
-
Tier assignment
L1:< 4.0L2:4.0 - 5.99L3:6.0 - 7.99L4:>= 8.0
-
Contextual explanation generation
- default deterministic explanation from strongest/weakest dimensions
- optional Claude Sonnet generation via Anthropic API (
ANTHROPIC_API_KEY) - normalized to single sentence and max char length (
score_explanation_max_chars)
-
Persistence + retrieval
- repository abstraction (
ScoreRepository) - legacy SQLAlchemy lineage writes to
services+an_scores - current product-facing Supabase surfaces read from
services+scores - canonical public read contract is
scores(seedocs/CANONICAL-SCORE-CONTRACT.md) - in-memory fallback for tests/dev resilience
- repository abstraction (
POST /v1/score: computes, persists, returns full score schemaGET /v1/services/{slug}/score: fetch latest score (or bootstrap from hand-scored fixtures)
rhumb score <service> reads GET /v1/services/{slug}/score and renders:
- selected headline mode (
--mode aggregate|execution|access) - aggregate recommendation + execution + access readiness lines
- confidence label
- explanation sentence
- category bars
- optional dimension breakdown (
--dimensions) - raw payload (
--json)
rhumb find <query> reads GET /v1/search and renders:
- ranked service matches with score/tier/confidence
- optional rationale lines (
why/reason/explanation) - raw payload (
--json) - result limit control (
--limit)