Phase 2.4b: fix dominant_signal — FOUNDATIONAL driven by centrality+coherence not age
Browse files- src/reliability.py +16 -5
src/reliability.py
CHANGED
|
@@ -155,11 +155,22 @@ Return ONLY the JSON array."""
|
|
| 155 |
return [_compute_recency(p.year) for p in papers]
|
| 156 |
|
| 157 |
|
| 158 |
-
def _dominant_signal(score: float, centrality: float, recency: float) -> str:
|
| 159 |
-
"""
|
| 160 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 161 |
return "FOUNDATIONAL"
|
| 162 |
-
|
|
|
|
| 163 |
return "CURRENT"
|
| 164 |
elif score >= THRESHOLD_DECLINING_LOW:
|
| 165 |
return "DECLINING"
|
|
@@ -225,7 +236,7 @@ def score_papers(papers: list, query: str, use_llm: bool = True) -> dict[str, Re
|
|
| 225 |
co = coherences[i] if i < len(coherences) else r
|
| 226 |
|
| 227 |
score = W_CENTRALITY * c + W_RECENCY * r + W_COHERENCE * co
|
| 228 |
-
dominant = _dominant_signal(score, c, r)
|
| 229 |
reason = _build_reason(dominant, c, r, co, getattr(p, "year", None))
|
| 230 |
|
| 231 |
results[p.paper_id] = ReliabilityScore(
|
|
|
|
| 155 |
return [_compute_recency(p.year) for p in papers]
|
| 156 |
|
| 157 |
|
| 158 |
+
def _dominant_signal(score: float, centrality: float, recency: float, coherence: float) -> str:
|
| 159 |
+
"""
|
| 160 |
+
Classify dominant signal for explainability.
|
| 161 |
+
|
| 162 |
+
FOUNDATIONAL: high centrality + high coherence — trusted regardless of age
|
| 163 |
+
CURRENT: recent + reliable — recently published and well-supported
|
| 164 |
+
DECLINING: mixed signals — some reliability but losing relevance
|
| 165 |
+
SUPERSEDED: low reliability overall — likely outdated
|
| 166 |
+
"""
|
| 167 |
+
# Foundational: highly cited AND content is still coherent with consensus
|
| 168 |
+
# Age is irrelevant for foundational papers — that's the point.
|
| 169 |
+
# When coherence=0.0 (LLM off, recency proxy for old paper), centrality alone qualifies.
|
| 170 |
+
if centrality >= THRESHOLD_FOUNDATIONAL_CENTRALITY and (coherence >= 0.65 or coherence == 0.0):
|
| 171 |
return "FOUNDATIONAL"
|
| 172 |
+
# Current: recent paper with good reliability
|
| 173 |
+
elif recency >= THRESHOLD_CURRENT_RECENCY and score >= THRESHOLD_CURRENT_RELIABILITY:
|
| 174 |
return "CURRENT"
|
| 175 |
elif score >= THRESHOLD_DECLINING_LOW:
|
| 176 |
return "DECLINING"
|
|
|
|
| 236 |
co = coherences[i] if i < len(coherences) else r
|
| 237 |
|
| 238 |
score = W_CENTRALITY * c + W_RECENCY * r + W_COHERENCE * co
|
| 239 |
+
dominant = _dominant_signal(score, c, r, co)
|
| 240 |
reason = _build_reason(dominant, c, r, co, getattr(p, "year", None))
|
| 241 |
|
| 242 |
results[p.paper_id] = ReliabilityScore(
|