If you add a new string in your app (for example String(localized: "contact_support_message", defaultValue: "Please contact support")), then later you change that default value and rebuild, the string catalog updates to match as expected.
But once that string is translated, changing the default value in code and rebuilding does not update the catalog. You seemingly have to go manually change the default value for English in the catalog to match the code (which marks the translation as Needs Review).
Is there a better way? Or is there a way to determine what strings have default values in code that do not match the catalog values to see if any were missed as wording was tweaked over time?
But once that string is translated
If by this you mean that it has translations in other languages, then Xcode is expected to update the value and mark translations as needing review automatically.
But if the source string itself is already marked as translated in the xcstrings file, then you are already in a conflicted state where there is a value in code and also a source value in the xcstrings. In that case, it is expected because Xcode will never change the value of a source string that is marked as translated in the source language. It is only allowed to do so if the state is new.
When such a string with a default value from code first appears in the String Catalog, it will have a state of new. The String Catalog Editor then prevents editing this string from the Catalog because the code defined the value and we don't want conflicting state.
But perhaps in your case something or someone went into the JSON and flipped it to translated. In that case, this is expected behavior due to invalid configuration.