Howard,
Cool -- I'm happy to set up the branch for you, well tagged and tidy, if you want. Then all you need to do is a checkout to a separate dirrectory or "switch" an existing checkout to the branch. Both trivial operations. Let me know if you want me to do this (and then I'll later be better prepared to help you to merge it into HEAD). (edit: I see you've got it done)
Now, with regards to the stuff we're discussing...
Classes
If you're after self-documenting code, we can have manual auth be the 'reference' and make sure it has all the API methods, even if commented out, with generous comment blocks.
Using base classes + inheritance backfires often, and this is a textbook scenario. This is an API that grows organically, and that tolerates (and even encourages) people to maintain their private plugins, like those that interoperate with UglyLegacyStudentMgmtSystem. I maintain a few of them.
So, we define the API today, and provide 'default' methods in the base class, which doubles up as 'manual/internal enrolment'. So 100 plugins are written against it, that count on the current API behaviour, 20 of those are official, 80 'private', local customizations.
Now, in 1.8, we decide to grow the API adding a new series of methods. Normally, when you're growing an API like this, you add methods that are optional so it's backwards-compatible (or forward-compatible, depending on where you are standing). But with a strategy of "it's always in the base class" we're fsck'ed.
We will add them to the base class, because (a) the code expects them, (b) for self-documentation, and (c) because it implements 'manual auth' which can truly make good use of them. And as soon as we do that, all the plugins will magically do the same thing that the base class does even if it doesn't make any sense at all and breaks them badly.
The workaround usually involves adding more methods to the API, where each module reports what it knows how to do, or what 'features' it has, and is generally awful, because you check whether you should call the method before you call it, lest inheritance does its job. Oh my!.
So, the best way is to have manual as a normal class, have no base class, and wrap calls to methods that are optional in the API with method-exists().
This is important, and is something I'll have to get around to fixing in the enrolment plugin architecture, but it hasn't been a problem so far (because we haven't changed the API... but we're about to )
Inheritance is tricky business, and defines an 'internal' API between base class and subclass that is full of funny interactions. All good for an in-house project, but hell for this loosely organized tribe.
(In other words, inheritance is too tighly coupled, we need loose coupling for a plugin API).
Edited for clarity and typos.