More detailed specifications and English explanations of path finding weather client-specified or server-provided is here https://wiki.ripple.com/Payment_paths
Thanks. So reading that I conclude the path finding is actually what I would call "client-determined", which of course is what makes the most sense. To me server-determined would be the Ripple nodes trying to solve the problem between ledger closes, which would be a computationally demanding process. It makes far more sense for the entity interested in such a transaction (or another entity helping them out) to solve the path finding problem with the most recent state of the ledger, then crafting the transaction (with appropriate limits on conversion costs) to submit to the network. I still call it "client-determined" even when the light client delegates that task to one or more servers with full access to the most recent database and then chooses the best result.
Within a single ledger context the transactions are ordered by impossible-to-know-ahead-of-time-yet-fully-deterministic algorithm:
lexicographic ordering based on the transaction hash.
To me this isn't quite good enough to satisfy the "impossible-to-know-ahead-of-time". A Ripple node has the opportunity to front run an order it has in its queue by adjusting a small insignificant parameter in the transaction such that its transaction hash lexicographically precedes the hash of the target transaction. It shouldn't be too hard to iterate this nonce to achieve this result before the ledger closes (in 50% of cases, there is a 50% chance or better of success for each iteration, meaning that for these 50% of cases after only 7 iterations there is a greater than 99% chance of obtaining the desired front running transaction).
Assuming we don't want to give up on limit orders to prevent front running (as BitShares currently does), there are a few solutions to this problem. One is to just include these market orders in one ledger close but only act on them in the very next ledger close. The order in which the market orders of the previous ledger are processed depends on the ledger hash of the previous closed ledger, for example lexicographical ordering based on hash(hash(transaction) || hash(previous ledger)). Since no one can know for sure what that hash of the closed ledger will be until the ledger has actually closed, no one can know for sure what order the submitted market orders will be processed, and thus there is a chance that the front running will not lead to guaranteed profits.
The other solution that I discuss
here, is to separate these market orders into two stages: a commitment to the order and then the actual order that must be submitted within a specific narrow time interval after the commitment transaction. I prefer this solution more because the front runner doesn't have any information about what front running order to construct until it is too late. Thus any attempt at front running would really just be a shot in the dark, whereas with the previous solution they at least knew the transaction to craft that would give them some (albeit <50%) probability of success.