Q: Why would installed packages have status "Remove"? While doing other maintenance tasks I noticed that dpkg -l listed about 90 packages with  status ri instead of expected ii.
I maintain packages solely with apt and aptitude and I haven't forced any packages but I regulary do apt install --no-install-recommends ... to avoid getting unneeded packages. I also try to carefully maintain the "automatically installed" flags and I have 2914 packages with status "automatically installed" (aptitude search '~i~M') and 422 packages with status "manually installed" (aptitude search '~i!~M').
What could be the reason for packages to have status Remove + Inst (ri) in dpkg -l listing when I haven't requested those packages to be removed? It seemed that the packages with this status were packages that I actually want to keep in the system. Could e.g. sudo apt dist-upgrade cause this without me noticing?
(I know that I can reinstall those packages with apt install --reinstall package-name to get status back to ii. I also often purge removed packages and aptitude search '~c' lists no packages.)
Additional details from another system with the same issue:
$ sudo apt dist-upgrade && sudo apt autoremove && dpkg -l | grep ^ri | wc -l
Reading package lists... Done
Building dependency tree       
Reading state information... Done
Calculating upgrade... Done
The following packages have been kept back:
  virtualbox-6.0
0 upgraded, 0 newly installed, 0 to remove and 1 not upgraded.
Reading package lists... Done
Building dependency tree       
Reading state information... Done
0 upgraded, 0 newly installed, 0 to remove and 3 not upgraded.
171

So dist-upgrade nor autoremove do not touch the 171 packages with ri status.
Example package with ri status:
$ dpkg -l ca-certificates-java
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name                                            Version                      Architecture                 Description
+++-===============================================-============================-============================-===================================================================================================
ri  ca-certificates-java                            20160321ubuntu1              all                          Common CA certificates (JKS keystore)

and additional info for the same package:
$ aptitude show ca-certificates-java
Package: ca-certificates-java            
State: installed
Automatically installed: no
Multi-Arch: foreign
Version: ...

$ aptitude why ca-certificates-java 
i   default-jre-headless   Depends openjdk-8-jre-headless
iBA openjdk-8-jre-headless Depends ca-certificates-java  

$ apt-mark showhold
virtualbox-6.0

Additional info after reading about possible causes:
As explained in answer https://askubuntu.com/a/802612/50254 the status of these packages can be fixed to match currently installed packages by running (note that the line feed after IFS is not a typo but this command requires setting IFS to single linefeed):
export IFS='
'
for i in $(dpkg -l |egrep '^[a-z]i.*' |awk '{print $2" install"}') ; do echo $i|dpkg --set-selections  ; done
unset IFS

The reason/cause for this problem is still unknown. The ri status is supposed to mean that dselect (old debian package manager nowadays completely replaced by apt) has used to mark package to be removed from the system and if you actually want to apply those selection states you can run apt-get dselect-upgrade. See man dpkg and section "INFORMATION ABOUT PACKAGES" for more information.
The apt install --reinstall package-name is also okay but it will do more than the minimum change to system to fix the problem.

A: disclaimer: i'm not a pro when it comes to distributions, so these are just my guesses by putting 1 and 1 multiple times together.
prologue
on an older Ubuntu machine i have one package with status ri, which is libllvm5.0 (and a bunch of other normal ii-packages like libllvm4.0 and libllvm6.0). the packages <= libllvm5.0 are marked as manually installed but libllvm6.0 is marked as automatically installed.
so my guess would be, that it was a dependency and got obsolete ether by upgrading or removing the dependent package.
explanation
going through your arguments/conditions one by one:

*

*i only use --no-install-recommends:
well, needed dependencies are installed nevertheless, else the program wouldn't work.

*autoremove does nothing to these packages:
well, kind of... i'm pretty sure all the ri-packages left alone by autoremove are marked as manually installed, although you have never installed it "separately". this is because after an initial setup a very few (if any?) packages are marked as automatically installed due to the fact that it isn't really possible to determine what packages you would have installed intentionally because this would vary from user to user. (so... a kind of "you have manually installed your OS".)

*could sudo apt dist-upgrade cause this?:
no and yes... sudo apt dist-upgrade on itself does not cause this, but with upgrading the whole system it is much more likely, that a bunch of (initially installed) packages will get obsolete.

to wrap up THE REASON: my guess would be that that these packages were installed by the initial setup, therefore marked as manually installed and then got obsolete by upgrading some packages or the whole distribution. and because they are marked as manually installed, they aren't touched by autoremove.
