My initial idea was that a number can we reused across different apps, so `admin.E001`, `customapp.E001` and `E001` are all valid. Now I agree that it would be great to avoid reusing numbers. Of course, we cannot avoid clashes between third-party apps, but we control contrib apps, so we can achieve partial success. 

Now we need to discuss how should we split 000-999 range? What about 000-199 for core errors (including compatibility and security), 200-299 for admin, 300-399 for rest of contrib, 400-599 -- reserve for future and 600-999 for third-party apps? An variation is to use 1000-9999 range for third-party apps and 000-999 for Django core and contrib. Now there are 50 core messages (errors or warnings), 68 admin messages, 3 auth messages and 7 contenttypes messages.

We can also ask third-party app developers to use random numbers from the 600-999 (or 1000-9999) range to make use of entire range so we avoid the situation when everybody uses numbers from the start of the range but the end of the range is used by nobody. This way we avoid as much clashes as possible.