Why are `update_add_htlc` and `commitment_signed` separate messages? BOLT #2 indicates that a node will send one or more update_ messages before a subsequent commitment_signed.
Since it seems like sending a payment over a channel involves update_add_htlc followed by commitment_signed (without needing a response from the peer in between), why do these need to be two separate messages?
The  commitment_signed message is also used at other places to move forward channel state. The entire process is not only described in BOLT02 but also in Mastering lightning
https://github.com/lnbook/lnbook/blob/366a65b33045cbb9e95a3d4060005c240f1f1778/channel-operation.asciidoc
There you can see that after Alice sends and update_add_htlc message and a commitment_signed message Bob will later in the protocol also send a commitment_signed message so that Alice can also move forward her state. Remember Bob and Alice both have an asymmetrical version of the commitment transaction for each state and both need a signature from the other side. It would be strange if Bob replied with an update_add_htlc message to send over signatures even though he does not want to add an htlc.
So yes while signatures could have been included in the update_add_htlc message we still would have needed the  commitment_signed for Bob to reply. Also when stetteling htlcs the commitment_signed messages are needed again. I guess in that way it seems more reasonable to make the exchange of signatures explicit with its own message instead an reusing it. But of course that was a choice that could have been taken differently.