The attached shows one approach to the problem I described already,
namely scans of empty btrees that concurrently gain an initial root
page. This seems to fix the posted repro case if using a btree with
enable_seqscan=off, enable_bitmapscan=off. That's the variant I had
been working with, because it was simpler.
But that turns out to be only one problem hit by the repro.
Apparently there's a second bug, if you let it use bitmap heapscans.
Or perhaps I am misdiagnosing the above. It could be something like:
btgetbitmap not following the predicate lock protocol correctly (but
it looks OK at a glance), or bitmap heapscan not checking for
conflicts out comprehensively (xids on invisible tuples we scan), eg
not fetching heap tuples for some short cut reason somewhere. But
that's all I have time for today.