Its hard for me to say how it is meant to be AFAIK, all implementations execute the goals in the order they appear after loading a file and a stand-alone program shall normally execute them in the same order as during loading but with the entire program being loaded. I (now) understand ISO doesn’t demand this ordering.
First of all, this means there is not just a single main(), but potentially a lot of them. This is a bit problematic. What if one doesn’t complete?
Another way to see them is as their name suggests: initialization steps that initialize some state that cannot be done statically. Compare to shared object linking where some defined entry point is called when the object it attached and detached from the process. This is exploited by e.g. C++ global constructors (if that is the right term). I guess there is no way to enforce, but these constructors are supposed to initialize things at runtime that cannot be done statically. For Prolog you can use it to generate some predicates at runtime, load or initialize some foreign resource, etc. The first can in most Prolog systems also be achieved using term_expansion/2, which has the advantage that the data is already precomputed in stand alone programs. The second is often better done lazily.
Another problem of initialization/1 is what needs to happen on dynamic reloading of the file in which they appear during development? Just re-running is often problematic (resource it needs to create already exists, etc.)
SWI-Prolog complicates these issues by providing lazy and concurrent loading of source files. For that reason it has initialization/2 for a while, where the second argument indicates when the goal should be executed. So far the available options cover nicely the use cases.