Skip to content

Gc/topic scout improvement#3

Merged
ginaecho merged 6 commits into
mainfrom
gc/topic-scout-improvement
Jul 15, 2026
Merged

Gc/topic scout improvement#3
ginaecho merged 6 commits into
mainfrom
gc/topic-scout-improvement

Conversation

@ginaecho

Copy link
Copy Markdown
Owner

No description provided.

ginaecho and others added 6 commits July 15, 2026 06:21
Lead with positioning: Topic Scout is the reusable engine generalized
from EvaPaper. Add a "Why not just use Microsoft Scout?" section
explaining the core differentiator — a consistent, designed output
style (HTML dashboard + Markdown notes) and comparable per-topic
analytics that ship for free, so users spend tokens on research
judgment rather than reformatting each run. Document the house style,
agent-agnostic runtime, ownable git-native corpus, and a
template-gallery roadmap.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MEQUakx19LbZYaqKrcJjbj
Replace the hedged "general scouting assistants" framing with the
actual product: Microsoft Scout (June 2026, OpenClaw-based) is an
always-on Microsoft 365 work agent, not a research-paper tool — no
fixed research output format, no persistent topic corpus, no per-topic
analytics. Sharpen the comparison table and bottom line accordingly.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MEQUakx19LbZYaqKrcJjbj
build_dashboard.py now reads an optional `theme` block from topic.json
and renders the dashboard's palette, typography, and category colors
from it. Every key is optional and deep-merges over the defaults, so a
partial theme (or none) is always safe and the default broadsheet look
is unchanged.

- resolve_theme()/root_css() merge palette + fonts over DEFAULT_THEME
  and emit a :root{} custom-property block injected via __ROOT__.
- Convert hardcoded fonts (display/body), accent colors, and the
  editorial surfaces (panels, metric cells, bar tracks, wiki nav,
  buttons, table + chart gridlines) to CSS variables so palette
  overrides retint the whole layout — enabling coherent dark themes.
- The citation-graph module stays a fixed dark inset by design.
- category_colors drive taxonomy bars, the trend chart, and the graph.
- Document the theme block in README + topic.example.json.
- Tests: resolve_theme merge/fallback + end-to-end themed render.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MEQUakx19LbZYaqKrcJjbj
Replace the single opaque 0-10 LLM score with a transparent judging
pipeline, tunable from a `judging` block in topic.json.

- Blind the judge from the heuristic: scout_llm no longer passes the
  keyword score into the model prompt, so the cheap heuristic and the
  LLM stay independent signals (their agreement becomes a confidence
  measure instead of the model just echoing the heuristic).
- The judge now scores a rubric per candidate — topical_fit,
  evidence_match, rigor (0..1 each) and a boolean exclusion_hit — each
  scored independently rather than as one relative ranking.
- New judging.py combines the rubric deterministically in code: a
  weighted aggregate (weights from topic.json, normalized) with a gentle
  recency decay -> a 0..10 relevance_score. The model judges criteria;
  the math does the ranking, so every score is reproducible.
- Two-threshold band instead of one cutoff: exclusion_hit vetoes;
  score >= accept_hi AND heuristic/LLM agreement -> accept; score <=
  accept_lo -> reject; everything else (mid-score OR signal
  disagreement) -> uncertain, which stays in the review queue for a
  human. scout auto-accepts only verdict=accept.
- Candidates carry rubric, relevance_score, relevance_confidence, and
  relevance_verdict; the dashboard candidate cards surface the verdict
  and confidence.
- Offline/heuristic path is unchanged (no rubric -> raw threshold).
- Document the judging block in README + topic.example.json; tests for
  resolve_judging/recency/aggregate and an end-to-end verdict-band run.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MEQUakx19LbZYaqKrcJjbj
Add scripts/eval_metric.py + `make eval` to measure how well the free
deterministic relevance metric tracks the LLM judge (LLM score as ground
truth) on any labeled candidates.json, so scout runs can lean on the
cheap metric and call the LLM far less.

Rank-based, scale-free metrics (Spearman, ROC-AUC, precision@K, recall@K,
NDCG@K, top-K overlap) across several token-free scorers: the current
exact-phrase heuristic, TF-IDF cosine, BM25, IDF-weighted coverage, a
naive token-coverage baseline, and a hybrid gate. Plus a routing
analysis that reports how many LLM calls a zero-recall-loss prefilter
saves.

Findings on the bundled 540-paper corpus (docs/metric-vs-llm-eval.md):
- The cheap metric's clearly-off-topic bucket held 485/540 candidates
  and 0 of 8 relevant papers -> prefilter routing cuts ~90% of LLM calls
  (a hybrid gate ~94%) with full recall. This is the token lever.
- No cheap metric reproduces the LLM's fine 7-vs-10 ranking; keep the
  LLM for the shortlist + uncertainty band only.
- Naive token-coverage is worse than random (rewards adjacent-but-wrong
  neighbours) -> IDF-weight any lexical signal.

Pure-Python (no numpy/sklearn). Tests cover the rank statistics, routing
recall retention, and full-scorer evaluation. README documents the
strategy; report written to a tracked docs/ path.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MEQUakx19LbZYaqKrcJjbj
…eline

Turn the metric-vs-LLM analysis into an actual token saving: before any
LLM call, scout scores candidates with the free deterministic metric and
drops the obvious-off-topic tail, sending only survivors to the judge.

- select_for_llm() ranks by a cheap score and splits into (LLM pool,
  prefiltered) with a keep_min floor so a sparse topic never empties.
- Prefiltered candidates stay in candidates.json marked
  relevance_verdict="prefiltered" (no silent loss) and never auto-accept.
- Config via judging.prefilter in topic.json {enabled, scorer, threshold,
  keep_min}; CLI overrides --prefilter/--no-prefilter,
  --prefilter-score, --prefilter-scorer. On by default (current scorer,
  threshold 0 = "no positive topical evidence").
- cheap_scores() recomputes the deterministic score from raw fields
  (never trusts a stored relevance_score that may hold an LLM verdict),
  so the live gate and the eval routing analysis use identical logic.
- eval_metric --recommend/--write-topic auto-derives the highest
  zero-recall-loss threshold and writes judging.prefilter back into
  topic.json, calibrating the gate to the user's own corpus.
- scout_run records prefiltered_count; run output reports the saving.

On the 540-paper example: 485 dropped, 55 judged (~90% fewer LLM calls)
with all 8 relevant papers retained. Tests cover the gate split, the
disabled path, and a full scout run proving the LLM pool shrinks.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MEQUakx19LbZYaqKrcJjbj
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@ginaecho
ginaecho merged commit f409105 into main Jul 15, 2026
2 checks passed
@ginaecho
ginaecho deleted the gc/topic-scout-improvement branch July 15, 2026 06:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant