I'm OK, for now, with the code as it stands. I'll add some comments because the rationale is non-trivial:

Before this changeset, there was a very good reason for the automatic 10% markdown on IndexScans. It was how the LT/LTE IndexScan got preferred over a SeqScan. Now that the endExpression check gives LT/LTE scans the same discount as GT/GTE scans, there are no IndexScans that actually require the 10% markdown. The closest we come to it are the for-order-only IndexScans, but, as you point out, they win anyway by not requiring an ORDER BY and the new for-determinism-only IndexScans that win by eliminating the equivalent SeqScan from the running.

So, even though it currently makes no real difference, I slightly prefer giving IndexScans an extra edge at least for the local cost in stats.incrementStatistic(0, StatsField.TUPLES_READ, ...)".

I'm a little more friendly to the idea of "evening the playing field" for parent nodes of IndexScan vs. SeqScan via identical m_estimatedOutputTupleCount.