What happens exactly when a chunk gets migrated? So, this is what MongoDB states:


  Independent of the secondaryThrottle setting, certain phases of the
  chunk migration have the following replication policy:
  
  
  MongoDB briefly pauses all application reads and writes to the
  collection being migrated, on the source shard, before updating the
  config servers with the new location for the chunk, and resumes the
  application reads and writes after the update. The chunk move requires
  all writes to be acknowledged by majority of the members of the
  replica set both before and after committing the chunk move to config
  servers.
  When an outgoing chunk migration finishes and cleanup occurs,
  all writes must be replicated to a majority of servers before further
  cleanup (from other outgoing migrations) or new incoming migrations
  can proceed.
  


Getting a real example: the first option "All queries on documents with productId value ranging between 18684 and 27851 will be routed to shard0000" would have been correct if the upper bound was 27850 instead?

If I understood it right, when I start the migration, if I try to run a query against documents ranging between the productId values 18684-27850, MongoDB already understands that it won't have to ask to shard0003 anymore, but instead it will have to ask for those documents to the NEW destination shard and thus redirect requests to shard0000.

So, I haven't actually tryed it, but I guess what you see is that, when you run the db.collection.find(), the cmd will "freeze" and after MongoDB successfully completed the chunk migration, it will retrieve the result set, is that right?
Yes and no! First config server copy all documents of moving chunk to destination server, then reading and writing is paused during time when chunk document is updated (one document, one value in that document), update is very fast process, so you don't actually notice anything. After that start cleanup at server where chunk was before.

So, you are very lucky if you managed to run collection.find() command just that moment when config server chunk collection is updated. And if you managed to do that, you probably cannot notice it or even measure that "slowness".