Phase is how the last sync operation ended, in CD's own vocabulary: Running, Succeeded or Failed. It is never empty — an Application whose phase is empty has no operation at all and omits this whole object.
Revision is the commit this operation ATTEMPTED (operationState.syncResult). It differs from the Application's own revision exactly when the attempt did not land: revision is the last commit CD got applied, this is the last one it tried.