I just came up with a far more problematic case too and wonder if documentation is enough. Maybe we should warn about potential problems more loudly.
Imagine the following case: insert into test_table (test) values (random()) where an insert rule propagates the changes faithfully to the next table. In short, all we are doing is inserting random numbers into different tables and generating them on each insert. In short, rules provide no guarantee of predictable behavior because queries can always mess with them.
Rules mess with queries. For data copying/archiving kinds of tasks, triggers are a better bet, like you suggested in your original post.
Let me put that a different way: rules can *only* be used where data integrity is not at stake. My own thinking is that it might be time to make an official recommendation that they are only safe for views.
NEW and OLD mean different things in a PL/pgSQL context and a Rules context. In PL/pgSQL NEW and OLD are values, in Rules (which specifically mess with queries) they are expressions. The fact that the same words mean different things in different contexts is a bit unfortunate but not as messy as say using "NEWEXPR" in the Rules context would be. Once you appreciate the difference, there's no confusion. Cheers, Stuart.