Thanks for your insights. I am trying very hard to understand this stuff. I'm writing documentation and preparing presentations for two Moodle Moots in June. User context is the grayest area for me. However it is becoming clearer, thanks to these discussions.
...stop using system context in has_capability() completely and use user context instead so that you can override system context for each user separately
Yes, that would fix the problem with inheritance and make the model work the same way it does everywhere else. As long as User is nested under System, it should be possible to override System permissions in a User context.
The major problem we have now is IMO that capability definitions do not include context level where each capability is usable
Actually I think just the opposite. I think capabilities should not attempt to define where they are usable. Capabilities should be concerned only with actions. The same action may be possible in different contexts, and we should be able to control those actions using the same capability. For example, you can read blogs in a Course context or in a User context. IMO that calls for a single capability. A capability has no business telling us where it can and cannot be used.
It is a simple matter of separation of concerns. We need to separate the what from the where.
If I remember history, users wanted only relevant capabilities shown on override pages (I was one of them). Contextlevel was supposed to solve that problem. I realize now the "relevant capabilities" can be different, depending on context.
If we eliminate contextlevel, we need to document "where the capability is usable" by some other method. Ideally, Moodle should be self-documenting.
If we retain contextlevel (and fix it, assuming that's possible), then each capability is bound to an action in a particular context. So you need duplicate versions of capability to control the same action in different contexts. We already see examples of this: (user:readblogs, blog:view), (user:readposts, forum:view), (user:editprofile, user:editownprofile) and so-on. This solution will lead to an explosion of capabilities: many versions of the same capability having different names for use in different locations. This is not a manageable approach in the long run.