It's for the sake of providing a &mut [u8] to the initialized region for callers that cannot work with &mut [MaybeUninit<u8>] for whatever reason, eg if they wanted to use this with a std::io::Read impl. In particlar, Read impls are discouraged but not prohibited from reading the content of the [u8] given to them, so calling them with a [MaybeUninit<u8>] transmuted into a [u8] is not generally safe.
Ah right, std::io::Read, I didn't think about that. And so it needs to explicitly track the initialized portion because otherwise calling .ensure_init() every time you want to do a read becomes expensive, that makes sense. And presumably this is also why the Buffer trait from this article cannot ever replace BorrowedBuf, because Buffer is not compatible with the Read trait without explicitly initializing the buffer every time (though I suppose it could still be added on top of BorrowedBuf if you add a new method init_len() that returns the length of the already-known-to-be-initialized prefix of parts_mut()).
EDIT: adding init_len() isn't good enough, we'd need an ensure_init() method too that returns a &mut [u8], and with those we could impl Buffer for BorrowedCursor, but if Read::read_buf() took this modified Buffer trait the default impl would be very inefficient when using a &mut [MaybeUninit<u8>] and that becomes a performance footgun.