Significant changes to Base.V1:

Here is what I have done:

InsertValue is the initial value that is set via normal means
UpdateValue is the same
InsertDefault is the default that will be put in the Insert data dictionary before validation
UpdateDefault is the same

The main difference is that *Value is set via normal means, same as if you had said:
User.Country = 'US'

But *Default is not validated or processed at all.  It is simply pulled into the INSERT or UPDATE dict before validation, so while they may be overritten during validation, they will never be validated.  For example:

class User_MNID:
    InsertDefault = SQL('nextval("seq")')

Because it skips all access control and validation, you can have special things like above that don't need to be accepted during normal operations.

Most of the time you should use InsertValue

--
The other change was that I deferred validation until the call to .Save().  I still need to build in callbacks that will allow larger validation to occur within a transaction, but for now, it is working nicely.

This means that whatever the user enters in the form will stay in _SetValueMap without modification.  Modification or conversion happens during .Save() and doesn't update the base object.  This means you could call .Save() more than once (assuming there was an Exception) and everything will work cleanly.

--
There was a signifcant problem with the dictionary size changing during iteration.  This was because in the Password.Validate, we were setting record.Password_Hash.  That caused the _SetValueMap to change, which raised a RuntimeError.

I fixed this by tracking any changes to _SetValueMap in a set and then while(len(myset)) > 0, set.pop().  It conveniently allowed me to re-validate any changed fields.

I also have a protection mechanism in place to prevent infinite loops (A.Validate sets B, B.Validate sets A).