I think the word principle is very good because it's not strict. It's much easier to come up with principles than categories, probably because of the built-in vagueness. Still, principles are descriptive regarding intention. That's exactly what I need here and now.
Two-Way Rules Checking: Optional (Possible) to Check Proactively, Mandatory (and Automatic) to Check Reactively
You should be able to check in advance (proactively) whether there will be a problem (for example, trying to persist the current changes) so that you can take corrective measures. That way, the programming model will be easier.
And if you fail to check in advance, there is no mercy, but you will learn (reactively) that there were problems via an exception.
All States, Even When in Error, Should be Savable
Users hate to learn from applications that they can't save the current changes because of errors. A friend of mine has compared it to not being allowed to save a word processing document if you have spelling errors.
All is a "big" word, but we will try to at least come close. We should try to avoid reaching those states that won't be persistable.
It's also important to think about what error means here. An order might be considered to be in error if it's too large. But until the user tries to submit the order it's not really an error, just a situation he needs to deal with before submitting. And he should be able to save that order before he submits it so he can continue working on it later on, to solve the problem and submit it then.
Rules Should Be Productive to Use
It should be productive to work with rules, both when consuming the rules and when defining the rules themselves.
The productivity for consuming rules will be addressed by making it possible to fetch metadata to be used for setting up the UI. That will cut the times you find problems when you check because the UI has helped so that some problems just won't happen. (Just watch out so you don't trust the UI to be all that is needed regarding rules checking.)
The productivity goal for defining rules might be reached with a small framework that lets you focus on the interesting parts of the rules, and the boilerplate code will be dealt with for you.
Rules Should Optionally be Configurable so that You Can Add Custom Rules
Some rules are scenario dependent while others are not, so it might be important not only to be able to declare all rules directly in the class definitions. Instead, you need to be able to add custom rules dynamically for certain use cases, but also during deployment as configuration information.
I think that the configuration aspect is particularly useful when you build products that will be used by many different customers. If you are building a system for a single customer, it's probably of less value.
Rules Should Be Located with State
Rules should at least be defined as closely as possible to the relevant Domain Model classes. By this I don't mean the implementation of the rules themselves but the declarations. We want encapsulation of the usage so that we easily get the "complete" picture of a Domain Model class by inspecting its class.
I think this principle helps another principle that could be called "Rules should be consistent." When the codebase reaches a certain size, there is a risk that the rules may interfere or even contradict each other. Having the rules together and together with the state should help to some degree with managing the rulebase.
Rules Should be Extremely Testable
We will spend a lot of time working with and testing the rules. For this reason, it's important to have a test-friendly design for the rules.
In reality, adding rules also creates problems with testing. You need to set up instances to correct states. You can write test helpers (such as private methods in the test fixture) for dealing with that, but it's still a hindrance.
The System Should Stop You from Getting into a Bad State
A good way of simplifying how to work with rules is to avoid the need for them when possible. One way of doing that is, for example, to work with creation methods that will set up the Domain Model objects in a valid state that can never be made invalid.