Also coming from a formal software engineering background, I found Michael Ossman's SDR with HackRF(https://greatscottgadgets.com/sdr/) series very informative. It has "homework" sections and starts with very little in assumptions of your prior knowledge. You dont need a hackrf, any sdr, including $15 RTL stick will do for most things. Or you can use GR to follow along and you'll get quite a bit out even without an SDR. Sofar it doesn't go very deep, but he covers demodulation of FM and getting data off a Wireless Key Fob from a car, which uses OOK modulation, and he adds new lessons every now and then. This will not tell you when you need to use a particular type of filter, but its good at getting you thinking about the problem your trying to solve. You mentioned wanting to go lower in the protocol stack. Modern digital communications are usually complicated protocols utilizing several types of modulations. I would start with older or simpler protocols first, but either way this will involve knowledge of digital modulations. Most of the time people recommend starting from the analog side, but I find the digital side easier from a CS background. I would also start by familiarizing yourself with basic digital modulations OOK, ASK, FSK, PSK, then move onto their variants, such as MSK, QPSK, QAM, etc(https://en.wikipedia.org/wiki/Modulation#Digital_modulation_methods). GR has blocks for almost all the basic modulators and demodulators built in. Basically all of these are ways to map a stream of bits onto the communication medium. If you start with a stream of bits, ask yourself how each of the above modulations would get those bits from point a to point b. Try implementing them in GR. Setup something like <file in> -> <modulator> -> channel model -> < demodulator > -> <file out>. The key here is the channel model. Its an awesome learning tool because it will allow you to model some typical problems of communication systems. When you lower the signal-to-noise ratio, for example you'll find you may need to add new blocks to compensate for the loss of signal quality. If you ask these more pointed questions, such as which block would help compensate for X, the list, I'm sure, will be willing to help you along. Also, make sure you attach constellation and FFT sinks everywhere, then you can actually see the effects of various blocks on your data stream (The QT GUI sink has most built in). Normally with digital modulations you map bits to a symbol of some kind, these symbols are usually displayed in a constellation sink. Observe the effect of channel model parameters on the constellation plot of your data, and the integrity of your output file. Attach sliders to basically any parameter in any block and adjust them at run time to see the effect on your stream.
As to documentation, as Martin said, documentation is amazingly hard when you know the things involved. Think of typical code comments you've seen as a developer. How many times do you see Function X(param1, param2, param3); And above it a comment, #Does X on param1 and param2 using param3. Alot of GR blocks have some documentation, they usually state what the block does in math, which is great, if your coming from that background, but they dont include things like "You will probably need to use this block when your constellation looks like <this> or to correct for <that>." Even given that, the documentation on the blocks themselves is somewhat helpful. It is on the last tab in the properties window for all the blocks. The best person to contribute to the documentation is probably you. As you learn things, write it down, why you think it worked or didn't, and then revise as you go along and offer it up for inclusion in the wiki.