I think I sort of solved this myself.
To debug a full Karaf installation, I found a procedure here: How to make a local snapshot build
The result of my debugging/testing indicates that Karaf itself caches/stores installed bundles, and they are persisted “indefinitely”. This “cache” can be deleted by deleting the files in question, which is done during OH upgrade, for example. In such situations, bundles must be reinstalled, which is where OHs different “cache solutions” comes in to play.
When running the “demo app”, these bundles aren’t persisted, because a “fresh OSGi container” is built for every run. Every bundle must thus be “installed” during startup of the OSGi container, which explains the difference in behavior between Karaf and “demo app”.