Why use `update_add_htlc` when paying directly across a channel? If Alice opens a channel to Bob and sends a payment directly to Bob, the following messages are exchanged:
    +-------+                            +-------+
    |       |---- update_add_htlc ------&gt;|       |
    |       |---- commitment_signed ----&gt;|       |
    |       |                            |       |
    |       |&lt;--- revoke_and_ack --------|       |
    |       |&lt;--- commitment_signed -----|       |
    |       |                            |       |
    |       |---- revoke_and_ack -------&gt;|       |
    |       |                            |       |
    |   A   |                            |   B   |
    |       |                            |       |
    |       |&lt;--- update_fulfill_htlc ---|       |
    |       |&lt;--- commitment_signed -----|       |
    |       |                            |       |
    |       |---- revoke_and_ack -------&gt;|       |
    |       |---- commitment_signed ----&gt;|       |
    |       |                            |       |
    |       |&lt;--- revoke_and_ack --------|       |
    +-------+                            +-------+

(source: running lnd with TRACE logging and inspecting the logs)
Why is it necessary to use HTLCs at all, instead of just exchanging updated commitment transactions directly?
For example:
    +-------+                            +-------+
    |       |---- commitment_signed ----&gt;|       |
    |       |                            |       |
    |       |&lt;--- revoke_and_ack --------|       |
    |   A   |                            |   B   |
    |       |&lt;--- commitment_signed -----|       |
    |       |                            |       |
    |       |---- revoke_and_ack -------&gt;|       |
    +-------+                            +-------+
It is not necessary to use htlcs in the case of a direct payment. However as the protocol was designed with the idea to have a network of payment channels. This should allow multi hop atomicity of payments via htlcs.  For that the process with the htlcs to move forward the state in the channel operation protocol were necessary
I think from a design perspective it was cleaner to reuse this protocol for direct payments instead of implementing two protocols and make case distinctions