How would you assert dynamically that if an interval is reachable, its
owning string or buffer must be too?

You don't. You check it statically (by a human).

It's not enough for the variable holding the reference to the string
or buffer to be in scope: you have to be sure that the reference
isn't dead.

It should be: if it's in scope, it's not dead.

That's not the case.

In general, no, but in this specific case I think it always will.
E.g. because in order to be in the process of working on the intervals of
a buffer, that buffer needs to be not just reachable but buffer-live-p,
so you'd have to mess with buffer-alist before the buffer can be
reclaimed, which is highly unlikely to happen within the functions that
manipulate intervals.
For strings, the argument might not be as strong. Maybe code like
(ignore (propertize "foo" 'a 'b)) could lead to us working on an
unreachable string, so it could get GC'd while we manipulate its
intervals.
So for those cases, I guess the main safety argument we have is that we
will not call the GC while we're in the middle of manipulating struct
interval objects.

It's not just strings and buffers and intervals. What about cons cells?
There's nothing wrong with getting a cons from something, doing
something that might GC with its car, then doing something that might GC
with its cdr. There's nothing stopping the compiler from keeping a
pointer to the cdr instead of the car and indexing when it's time to
dereference the cons and get the cdr out of it.

It's legal for the compiler to emit code that does things like this.
That it hasn't happened yet is no guarantee that it won't in the future.

Let me ask again: we already have all the runtime data we need for more
conservative GC. Where is the resistance to the idea coming from?