Oh yes, interesting! And I do see the advantages of the betrayal framing.
How would you handle an opponent whose proving ability is simply too weak — one that often can’t establish that anyone cooperates? It never defects on someone it knows cooperates, so it counts as fair in your sense, but only because it’s never in a position to betray anyone in the first place. So I’d certify it and cooperate, and it would defect on me. Old-style fairness seems to fail safe here instead, since it asks whether the opponent actually cooperates rather than what they’d do if they knew.
This reads to me as a more elegant way of expressing what I was looking to do: it needs no source access, so there is no rewrite pass needed and nothing to obfuscate. I also think it will extend to strategies that do not simulate, resolving one of my blockers.
However, I do not think it addresses niceness without recognition. You learn what your opponent plays if it knows you will cooperate, but in real play it may not determine this, and act differently.
There are also issues with detecting that you are being simulated: a lookup will return much faster than a simulation. You may also need to enforce that strategies cannot run judge.run(opponent, fresh_copy(self)) or such.