Secondly, client and server interfaces are not as symmetric as you indicate. Discourse has much more validation logic on the server than the client.
We generally "assume success", because the vast majority of requests do go through correctly. So if you submit a spam post for example, we'll show it in the client side view right away, but once the server asynchronously replies a failure, we'll display an error message and remove it. This can be jarring in the case of a failure as you'll see something appear then go away, but the vast majority of the time it doesn't happen.
The client side interface should do what it does best - display stuff quickly and avoid server round trips as much as possible.