Excellent point!
As you note one workaround is don't reuse addresses— always good advice and here it doesn't have to be "phased out" in general but just by participants— but it's always better to be secure even if software is used dumbly.
I can suggest a trivial protocol addition that solves this without making the CJ transactions distinguishable or degrading privacy, but my solutions have some overhead. I'm curious if anyone can come up with a better way of doing it that doesn't have the overhead.
The general idea is that the merging party can just make a list (blindly) mapping their inputs to outputs, give the list to all players, and commit to the list so that all players know they got the same list.
Here is how it works:
The merging party makes a list with an entry for each output in the transaction. The entries have a nonce provided by each user either when they provide their input (or submitted their blindsigned tokens if blind signed tokens are in use). When they ask the users to sign they give the users the list and the users check and see that they are the credited party for every output they think they should be. Because they are just nonces they don't deanonymize users.
But to prevent the merging party from giving a different list to each user they must commit to it. I have two way to accomplish that:
The first is that we could require that a particular index in the outputs pay to an address which commits to the list: The merging party computes a new public key as an existing pubkey plus the H(list)*G, like a
pay to contract, and a previously designated output pays to the resulting address. Given the list and original public key, everyone can check that that output commits to the same list. (And if two different users are given different lists, their signatures will not be merge-able since they would have signed different outputs).
(This designed output could belong to the merger or players could volunteer to have their output address placed in the designated position and to instead receive their payment at a pay-to-commit address. This is a little lame though, because it requires that there be at least one player that will tolerate receiving coins at a non-deterministic key.)
The second way to commit that I've come up with is to add an additional round to the protocol where you make a dummy transaction modified so that it won't ever be valid, e.g. using the list hash as an addition vin. Everyone signs this transaction and then only once they've seen this commitment signed by all the inputs will they sign the real transaction.
Needing an extra communications round or a non-deterministic output is kinda weak. Can better be done?