Leiden partitions change from 1e-9 weight noise; attribute drift by cross-feeding stages
To find which step makes a single-cell pipeline differ between library versions, save every stage (scaled matrix, PCA, kNN connectivities, labels) and re-run version B with one stage injected from version A. On scanpy PBMC3k (2021-2026 releases), all Leiden steps up to leidenalg 0.10.2 returned identical labels on an identical graph, so the whole cross-version drift came from float-level PCA noise flipping 1-4 kNN edges. On a fixed graph, multiplying weights by (1+1e-9*N(0,1)) changed the partition in 10/10 replicates (a pure float64 cast changed nothing), and dropping 1 of ~21k edges changed it in 9/30. Treat a Leiden run on another machine or version as a fresh seed draw, and report cluster counts over seeds rather than one run. leidenalg 0.12/igraph 1.0 is a genuine algorithmic change: it partitions the same graph differently.
Reproduced on PBMC3k (scanpy 1.12.5, leidenalg 0.10.2, igraph 0.11.9; tutorial pipeline, n_neighbors=10, n_pcs=40, which gives 2638 cells, 20,976 edges and 8 clusters). Leiden is called directly on obsp['connectivities'] with RBConfiguration, resolution 1, n_iterations=-1. I compared partitions with ARI<1, not array_equal, because a seed change alone often only permutes labels; here the two counts agreed. Same weights repeated: identical. A float32 round-trip: no change. Weights x(1+1e-9*N(0,1)): changed in 5/10, 9/20 and 13/20 for three noise streams, with ARI down to 0.70. Per Leiden seed the rate was 8/10, 3/10 and 3/10, so 10/10 is plausible for some seeds but is not the typical rate. Dropping 1 edge: 6/30, min ARI 0.72. The effect depends on the data. On synthetic graphs (8 Gaussian blobs in 30-D, 2700 points, kNN 15, both exp(-d/sigma) and UMAP-style weights with ~2.4k exact 1.0 ties), 1e-9 noise changed nothing in 0/10, on leidenalg 0.10.2 and 0.12.0 alike, even where single-edge drops did. So it is PBMC's ambiguous boundaries that make Leiden chaotic, not exact weight ties. Your advice to report over seeds is the right one.