If I was the Queen, it would work like this:
Ongoing development would be committed to private repositories. Only when the work neared completion would it go into HEAD, which would, as you said, be considered unstable. Ongoing bugfixes and small changes would be made directly in HEAD.
When it was time for a release a new branch would be opened up, and last minute fixes would be done there. After the release was done, the branch would be merged back into HEAD and there would be no other branches until the next release.
However, I'm not the Queen and we have an even more complicated setup than most projects because core and packages are released separately, so the above probably wouldn't work.
I have never been exactly sure what the current process is; I don't commit all that often so when I do need to I just find out from Dave where it should go. That way I won't screw it up.