At risk of being late to the party (the
pull request to put this in the "approved" category arrived right after the beginning of my leave), I think this plan is reasonable, although I do lament the necessity of native.existing_rules() and I wish we could make package loading stateless, but that horse has probably left the barn.
Do I understand correctly that your dict re-implementation would omit all the methods that mutate the data structure and only leave get()/keys()/values()/items() and the operators that act on Dict? If so, go ahead -- it's a reasonably narrow interface and if someone really wants to mutate the resulting data structure, I'd much rather they change their code than we introduce the copy-on-write mechanism you mentioned in the design doc.
I wonder if we could come up with a mechanism that makes the use of native.{existing_rule,existing_rules} less comfortable so that only people who really need it use it. It's a necessary wart, but still a wart, so I'd much rather it sees as little use as possible.