@michaelcahill, if you recall there are 3 chunks of bulk-load code for historical reasons: there used to be a big chunk of btree bulk-load code that I removed almost entirely when I integrated bulk-load into reconciliation. The stubs that are left do little other than check the key-sort order (row-store), or count up the duplicates (variable-length column-store).
In short, we have 3 chunks of bulk-load code at the moment, the cursor layer, the reconciliation layer, and some random stuff in the middle. This branch puts most of the random stuff in the middle into the cursor layer.
This means the cursor layer owns checking the row-store key sort order (which feels reasonable to me), but also does the duplicate counting for variable-length column-store, which I'm less comfortable with.
Anyway, I thought this might be a way to simplify the layering, feel free to discard it if you disagree.