Of course, the docs would need to be updated to something like: 'Use st() for strings that may be used by the installer before the container is created.' (Or the configuration and the db are checked, which is about the same).
Also it could be used (added back since it was removed) for some installer page texts. Now it should work as the new 'st' is more reliable, and has some more checks.)

The other options, for the *real* dx improvement would be checking for an existing cotainer inside 't', and fallback to 'st' or similar code when not available.... It won't looks so nice from inside because t() would need to be 'installer aware' too.

(But anyway, now I read what I've written, I think yes, let's go for the real DX improvement....)

Does st() do anything then? If there was no DIC, the .po files would not be read either since that is all moving to be accessed the via the DIC, right? So sounds like you can wrap things in st() but it would not do anything anyway(?).

This issue is the correct solution to this problem: Prepare the container early enough before anyone wants to translate anything at all. The current patch does in fact fix the problem.

Aside: I have no idea why PoStreamReader wants to translate its errors and at first glance it seems like a particularly bad idea. Especially since it's in \Drupal\Component it's not very nice to call get_t() randomly...

Aside: I have no idea why PoStreamReader wants to translate its errors and at first glance it seems like a particularly bad idea. Especially since it's in \Drupal\Component it's not very nice to call get_t() randomly...

Did not review each single line, but skimming through the file, there are no unrelated changes, use of $t, st and get_t are removed, t() is universally introduced and the functions themselves are removed. What's not to like? :)

Very nice, but the pre-bootstrap translation of installer interface doesn't seem to catch the default language, so doesn't actually translate the interface...

While I unfortunately didn't manage solving this in the given time, what I did is some refactoring, which I still wanted to share with you:

The early minimal container seems to be needed just in order to verify database settings? Then we probably don't need to install_register_translation_service() before. So we don't have to register it twice in minimal bootstraps.Also, corrected comments.

Also, while the container gets overwritten by the regular bootstrap, we don't have to recreate it again in minimal bootstrap.