The docs for renderable arrays - https://drupal.org/node/930760 define #markup as:
The simplest property, this simply provides a markup string for #type => 'markup'
But, as per #2012818: Remove #type 'markup' this is both inaccurate and vague about what's really going on.
A better description of what #markup does, and this is *by design* according to @tim.plunkett, so we should update the docs accordingly:
"#markup defines a string of raw HTML that will be prepended to the rendered children of this renderable array, before #theme_wrappers are called, but only if #theme is not set. If #markup is set and #type is not set then #type will be set to 'markup' to ensure any relevant defaults are loaded from element_info()."
The reason for this is that #markup is intended as a fallback/default when there is no theme implementation available to process the renderable array.
The guiding principle here is that if #theme is set then it is theme()'s responsibility to render the array 100% so we should be clearer in the docs what falls in this "100%" and what doesn't - eg., pre_prender, post_render, prefix, suffix
As well as the d.o docs needing updates, there is no mention of #markup in the docblock of the drupal_render() function itself so we should add a paragraph there explaining its intended usage.