Phase C: Wire ML confidence scores into the FenLiu review UI #64
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
FenLiu has a trained XGBoost classifier (Phase B complete) that predicts approval probability for Fediverse posts. Phase C wires that model into the running web app so the reviewer can see ML confidence scores alongside the existing spam score, and so the review queue can be sorted by model uncertainty.
The 110-day checkpoint analysis (2026-07-03) confirmed the model is ready: 86.1% CV accuracy, +24.9 pp margin over the spam_score heuristic (which has degraded to 61.2% due to Bluesky bridge traffic). The 90-day data minimum is met.
Scope:
ml_confidence_score REALcolumn topostsMLInferenceServicesingleton — loads model at startup, scores posts at fetch timeOut of scope: per-stream model thresholds, hot-swap reload, auto-filtering.
Exploration findings (2026-07-03):
save_fetched_postsinservices/post_storage.pyis where spam scoring runs — ML scoring slots in right aftercalculate_spam_scoreon the samepost_datadict.StreamSchedulerinservices/scheduler.pyuses APScheduler'sAsyncIOScheduler— a cron job at 2am fits the existing pattern cleanly.load_artifacts()/transform()intraining/model.pyandtraining/features.pyare the inference entry points._render_post_rowinliveviews.py:1388renders the spam score badge — ML badge goes alongside it.Postmodel has noml_confidence_scorecolumn yet; Alembic migration needed.liveviews.pywith a guard at line 494:{"created_at", "spam_score"}.Plan of attack:
ml_confidence_score REALnullable column toposts, add toPostmodel.MLInferenceService— newservices/ml_inference.pysingleton;load()at startup inmain.pylifespan; graceful degradation when artifacts absent.save_fetched_postscallsml_inference_service.score_post(post_data)and writes result todb_post.ml_confidence_score.ml_confidence_min/ml_confidence_maxfilter inputs.ml_uncertaintysort option (abs(ml_confidence_score - 0.5) ASC, NULLs last); becomes default when model loaded._retraining_jobcron at 2am inStreamScheduler; saves.prevrollback artifacts; skips if < 500 rows.Branch:
feat/phase-c-ml-integration