My request at this point is to officially and clearly document this as a substantial limitation of rules. It is not obvious that this is how rules are supposed to behave in this case, and even assuming that the current behavior is desired, it would be nice to let us know this :-)
It's documented. Section 35.3.1 of Postgresql 8.2 PDF docmentation, 2nd last paragraph: *** For any reference to NEW, the target list of the original query is searched for a corresponding entry. If found, that entry's expression replaces the reference. *** "expression" is the key term here. NEW.id is an expression, *not* a value. Cheers, Stuart.