It's because of TCP guaranteeing order.
The verack is sent first, so the other node will receive that first. If they like the version and verack, then they can send their own verack indicating readiness to receive further messages. If not, they will just kill the connection. The protocol is not violated by sending the alert immediately after the verack and nothing bad happens.
The alert message in this instance is a special message. It is part of the old P2P alert system that has since been deprecated and removed. The alert message is only sent to old nodes that indicate that they still have the alert system. It is being sent immediately after connecting because that alert message will cause the "Alert Key Compromised" message to be displayed on nodes that still have the alert system.
However sending messages immediately after verack before receiving the other node's verack is a common thing to do. There are a couple of other messages that are not responses to anything and can just be sent immediately after verack. You should see this same behavior with the sendheaders message.
i am also wondering why bitcoin core nodes can't recognize a message if it has preceding garbage bytes (random bytes before the magic) but they are fine if it is after it. what's the point of magic then if it isn't used as the message start marker?
Because it is expecting only messages in discrete chunks. TCP generally gives it the messages in a single recv(). It is expecting the magic bytes at the beginning. If someone is sending garbage, then it wants to just disconnect as fast as possible because that could be a DoS attack. However garbage at the end of the message is fine because the message itself is self descriptive in size and garbage after the message can be discarded.
The magic bytes are not a start marker. They are an unique identifier.