fetch_msf_data: query ALL pwned hosts exhaustively + benign_ratio*n_pwned
benign sample — avoids 5/50000 imbalance that made accuracy=1.0 trivial
build_feature_matrix: feature[6] = filtered_port_count (replaces malware_hits)
confirmed_vulns used only for labels, not in X — breaks circular dependency
train.py synthetic: feature[6] = filtered_port_count to match real data layout
train_from_msf signature: benign_ratio param instead of msf_limit