Another problem related to NeumannValue and formal form of PDE. As discussed in e.g. this post, to properly set the NeumannValue, we need to check the underlying formal form:
NDSolve`FEM`GetInactivePDE@
First@NDSolve`ProcessEquations[{diffusePde, ic}, rho, {x, -rWall, rWall}, {t, 0, 100}]

So NDSolve internally doesn't transform the PDE to the form in your mind. You're expecting something like
$$\frac{\partial \rho}{\partial t}=\frac{\partial}{\partial x}\left(D_t\frac{\partial\rho}{\partial x}-v_0\rho\right)$$
right? This form is also allowed by FiniteElement method, but we need to help it a bit with Inactive (Related examples can be found in tutorial NeumannValue and Formal Partial Differential Equations):
With[{rho = rho[x, t]},
diffusePdeInactive =
D[rho, t] ==
Inactive[Div][
Subscript[D, t] Inactive[Grad][rho, {x}] - Inactive[Times][{v0[x]}, rho], {x}];]
I've omitted NeummanValue in the code, because Neumann 0 condition is the default setting of FiniteElement method.
Let's again check the underlying formal PDE:
NDSolve`FEM`GetInactivePDE@
First@NDSolve`ProcessEquations[{diffusePdeInactive, ic},
rho, {x, -rWall, rWall}, {t, 0, 100}]

As we can see, the $v_0 \rho$ term is in the desired position. Alternatively we can check the $\alpha$ term with:
state = First@
NDSolve`ProcessEquations[{diffusePdeInactive, ic},
rho, {x, -rWall, rWall}, {t, 0, 100}];
data = state["FiniteElementData"]["PDECoefficientData"];
data["ConservativeConvectionCoefficients"]
(* {{{{1}}}} *)
In contrast:
state = First@
NDSolve`ProcessEquations[{diffusePdeInactive, ic} // Activate,
rho, {x, -rWall, rWall}, {t, 0, 100},
Method -> {"MethodOfLines", "SpatialDiscretization" -> "FiniteElement"}];
data = state["FiniteElementData"]["PDECoefficientData"];
data["ConservativeConvectionCoefficients"]
(* {{{{0}}}} *)
Now the integral conserves:
usol2 =
NDSolveValue[{diffusePdeInactive, ic}, rho, {x, -rWall, rWall}, {t, 0, 100}];
Table[NIntegrate[usol2[x, t], {x, -rWall, rWall}], {t, 0, 1, 0.1}]
(*
{3.98942, 3.98942, 3.98942, 3.98944, 3.98943,
3.98943, 3.98943, 3.98943, 3.98943, 3.98943, 3.98943}
*)
Alternatively, we can live with the default formal PDE. In this case we need to adjust the NeumannValue to
With[{rho = rho[x, t]},
diffusePde3 =
D[rho, t] + D[rho v0[x] - Subscript[D, t] D[rho, x], x] ==
NeumannValue[v0[x] rho, x == rWall] + NeumannValue[-v0[x] rho, x == -rWall]];
usol3 =
NDSolveValue[{diffusePde3, ic}, rho, {x, -rWall, rWall}, {t, 0, 100}];
Table[NIntegrate[usol3[x, t], {x, -rWall, rWall}], {t, 0, 1, 0.1}]
(* {3.98942, 3.98942, 3.98942, 3.98944, 3.98943, 3.98943, 3.98943, 3.98943,
3.98943, 3.98943, 3.98943} *)
But since setting the NeumannValue is so troublesome, why not the good old TensorProductGrid?:
With[{rho = rho[x, t]},
pdeold = D[rho, t] + D[rho v0[x] - Subscript[D, t] D[rho, x], x] == 0;
bc = rho v0[x] - Subscript[D, t] D[rho, x] == 0 /. {{x -> -rWall}, {x -> rWall}};]
usolold =
NDSolveValue[{pdeold, ic, bc}, rho, {x, -rWall, rWall}, {t, 0, 100}];
Table[NIntegrate[usolold[x, t], {x, -rWall, rWall}], {t, 0, 1, 0.1}]
(* {3.98942, 3.98942, 3.98942, 3.98942, 3.98942,
3.98942, 3.98942, 3.98942, 3.98942, 3.98942, 3.98942} *)