Bug Description
backend/retrain.py has two if __name__ == "__main__": blocks that both run
top-to-bottom, so trigger_model_reload() fires before main() retrains,
reloading the old model. The training logic is also broken:
- Import-time side effect:
df = pd.read_csv('dataset.csv') runs at module
import and crashes if the file is absent.
- Train/test leakage + double-fit: the vectorizer is fit on the train split,
then immediately re-fit on the entire df, and model.fit(X, y) retrains on top
of the split-trained model using raw string labels from the global df, not the
label_encoder-encoded combined labels used elsewhere.
- Inconsistent persistence: it
joblib.dumps the "final" artifacts and then
pickle.dumps different objects to the same paths, so what lands on disk
depends on line order.
Location: backend/retrain.py.
Steps to Reproduce
cd backend && python retrain.py.
- Observe the reload trigger firing before training, and inspect the held-out
accuracy vs. the actually-persisted model.
Expected Behavior
A deterministic pipeline: no import-time I/O; fit once on the train split for the
held-out metric; refit once on full combined data with consistent label encoding;
a single serialization path with atomic writes; reload triggered only after a
successful save.
Actual Behavior
Reload runs before training, the persisted model is the product of leaked/double
fits with mismatched labels, and artifacts are serialized twice inconsistently.
Screenshots
No response
Additional Information
Add tests/test_retrain.py using a tiny synthetic dataset + feedback CSV to assert
no leakage, label consistency, and artifact round-trip.
Bug Description
backend/retrain.pyhas twoif __name__ == "__main__":blocks that both runtop-to-bottom, so
trigger_model_reload()fires beforemain()retrains,reloading the old model. The training logic is also broken:
df = pd.read_csv('dataset.csv')runs at moduleimport and crashes if the file is absent.
then immediately re-fit on the entire
df, andmodel.fit(X, y)retrains on topof the split-trained model using raw string labels from the global
df, not thelabel_encoder-encodedcombinedlabels used elsewhere.joblib.dumps the "final" artifacts and thenpickle.dumps different objects to the same paths, so what lands on diskdepends on line order.
Location:
backend/retrain.py.Steps to Reproduce
cd backend && python retrain.py.accuracy vs. the actually-persisted model.
Expected Behavior
A deterministic pipeline: no import-time I/O; fit once on the train split for the
held-out metric; refit once on full combined data with consistent label encoding;
a single serialization path with atomic writes; reload triggered only after a
successful save.
Actual Behavior
Reload runs before training, the persisted model is the product of leaked/double
fits with mismatched labels, and artifacts are serialized twice inconsistently.
Screenshots
No response
Additional Information
Add
tests/test_retrain.pyusing a tiny synthetic dataset + feedback CSV to assertno leakage, label consistency, and artifact round-trip.