Spectre comes in two varieties, the generic branch avoidance "boundary check bypass", and the BTB poisoning one.
The solution to boundary check bypass is to just surrender and document branches as unsuitable for providing security boundaries. Going forward, "branch on out of bounds" is going to be replaced by using unconditional math to clamp access to the array boundary. In any case, this is of very marginal utility to an attacker, because it's only useful if there is some privileged information within an address space where the attacker gets to write code. Really only useful in JIT situations, and those will be quickly fixed in software.
The other half of spectre, the BTB poisoning, is much more scary, as it allows you to inject arbitrary code to an arbitrary process (or kernel!) running on the same CPU. (The limitation is that you only get to run until the branch reaches retirement, and you can only communicate with the rest of the world through cache timing.) This one will be hotfixed by retpolines in software, then fixed by ucode changes that provide options to flush the BTB, and in the long term fixed in hardware by tagging BTB entries better.