So it seems like actually there are 3 different state roots, 1 for CheckTx, 1 for block processing, 1 for query
although from reading this, it seems like query and checkTx can share a state root, which is basically the state root for committed state
and that when a BeginBlock message comes in, the deliverTx state manager will begin a transaction, then it will wrap each deliverTx message in a withTransaction, so they all get committed to that transaction that BeginBlock opened, then at the Commit message you will close the transaction opened by BeginBlock, and sync the query state root and checkTx state root to this new commitment
it's basically the same as how most people use ethereum, you run all of your call methods against Latest, usually not Pending, and then this checkTx is sort of like running your transaction as a call
https://docs.tendermint.com/master/spec/abci/apps.html#state
from rocket chat: