As to the question of why standard error is not buffered and standard out is just think about it. Buffered output tends to be faster and more efficient so you might expect generally all I/O to be buffered.
In fact I can remember when I first started programming the company I worked with did not use the standard library functions for reading files (do not ask me why) but instead used low level functions provided by DOS. These functions where unbuffered. There has a noticeable difference in reading a file 1 byte at a time and reading a file 512 bytes (a disk sector) at a time because the disk had to read the 512 bytes anyway and extract the required byte so the 1 byte at a time method read 512 times as much data.
So the question becomes if buffer I/O is faster and more efficient why wouldn't you use it and the answer is simple. If your I/O is buffered then you have the possibility in the situation of the program crashing that you send something for transmission and it only gets as far as the buffer before the program crashes, that is it is never actually output. If the thing being sent is critical debug data that will allow you to identify the cause of the crash then that would be quite irritating. So it is often the case that you don't want diagnostic information buffered you want it output immediately (or at least as soon as possible).
So it becomes clear, standard in and standard out are designed for normal I/O and so use buffered operation (if possible) to gain the efficiencies of using a buffer. Standard Error, however, is designed for diagnostic information and so it uses unbuffered (or not fully buffered) operation to attempt to ensure that diagnostic messages are always displayed.