Let me rephrase your questions a bit.
What section of the spec defines this behaviour?
Section 8.7.1 states that the statement of an "if" is an "embedded statement".
The beginning of section 8 states that an embedded statement can be a block or an empty, expression, selection, iteration, jump, try, checked, unchecked, lock, using or yield statement, but not a labeled statement or a declaration statement.
Why not allow declaration statements?
The original language notes do not address this specific point, but we can make some educated guesses. Your conjecture is a good one; doing so would make it hard to reason about the scope of the declared local. If we allowed it then we'd have to decide whether the "if" implicitly creates a local variable declaration scope even without the block:
if (x) int y = M();
else string y = N();
Is this a redeclared local variable error? Or does each branch of the conditional produce its own local variable declaration space?
What about this?
if(x) int y = M();
else y = N();
Q(y);
Is y in scope outside of the consequence? If so, is it definitely assigned by the time it gets to Q(y)?
I don't have a strong intuition for what the right thing to do here is. No matter which we picked, it seems likely that half the people would think that we chose the wrong one. Far better to instead make the whole think illegal and require braces if you want to introduce a new local variable declaration space.
And now some questions you didn't ask:
What about switch blocks? Do the same rules apply?
No. Read this:
http://blogs.msdn.com/ericlippert/archive/2009/08/13/four-switch-oddities.aspx
What happens if I declare a local variable legally but only ever assign to it, as in my example with the block in the consequence of the conditional?
Sometimes you get a warning. Sometimes you don't.
How does the compiler decide whether to give a warning or not?
Read this:
http://blogs.msdn.com/ericlippert/archive/2007/04/23/write-only-variables-considered-harmful-or-beneficial.aspx