Inheritance has no place in production codebases—unless there is strict discipline, enforced by tooling, ensuring calls only go in one direction. This Liskov stuff has zero bearing.
Respectfully, I think you're throwing the baby out with the bathwater.
I read your story, and I can certainly empathize.
But just because someone has made a tangled web using inheritance doesn't mean inheritance itself is to blame. Show me someone doing something stupid with inheritance and I can demonstrate the same stupidity with composition.
I mean, base classes should not be operating on derived class objects outside of the base class interface, like ever. That's just poorly architected code no matter which way you slice it. But just like Dijkstra railing against goto, there is a time and a place for (measured, intelligent & appropriate) use.
Even the Linux kernel uses subclassing extensively. Sometimes Struct B really is a Struct A, just with some extra bits. You shouldn't have to duplicate code or nest structures to attain those ergonomics.
Anything can lead to a rube-goldberg mess if not handled with some common sense.
You are conflating two completely separate things.
The Liskov principle basically defines when you want inheritance versus when you don't. If your classes don't respect the Liskov principle, then they must not use inheritance.
The problems from your story relate to the implementation of some classes that really needed inheritance. The spaghetti you allude to was not caused by inheritance itself, if was caused by people creating spaghetti. The fact that child classes were calling parent class methods and then the parent class would call child class methods and so on is symptomatic of code that does too much, and of people taking code reuse to the extreme.
I've seen the same things happen with procedural code - a bunch of functions calling each other with all sorts of control parameters, and people adding just one more bool and one more if, because an existing function already does most of what I want, it just needs to do it slightly different at the seventh step. And after a few rounds of this, you end up with a function that can technically do 32 different things to the same data, depending on the combination of flags you pass in. And everyone deeply suspects that only 7 of those things are really used, but they're still afraid to break any of the other 25 possible cases with a change.
People piggybacking on existing code and changing it just a little bit is the root of most spaghetti. Whether that happens through flags or unprincipled inheritance or a mass of callbacks, it will always happen if enough people are trying to do this and enough time passes.