A Ref is always mutable and ScopedValue is immutable.
No this is a misunderstanding. The problem with putting a mutable value into a ScopedValue is one of data-races. If within the same dynamic scope two programs are writing to mutable the mutable content of a ScopedValue you can observe data-races. A mutable scoped value is something like ScopedValue(Ref(0)).
In your example the outer scope will always get the outer value and the inner scope will get the inner value, but you may see concurrency races if they share data.
ScopedValue are thread-safe, their contents may not be.