Import the outdated engines, but delete their pref so they show up as disabled. Clean up the old engines a little bit so they don't allocate unnecessarily and to not use syncCore.
Remove existing hardcoded engine list + prefs and build checkboxes based on registered engines. Engines that give null for enabled (instead of true/false) are considered disabled. Update base Engine enabled get/set to give null and allow setting.
Switch pretty much all references to cleartext in modules/engines/ to just use the record. Also clean up some references to null cleartext to use deleted. The only reference to cleartext is to iterate over that hash in bookmarks.
Switch cleartext properties to Uri that always takes a text spec, so eventually URI refers to nsIURI. GeneratorURIs seems to have been broken either way.. makeURI of an already URI and storing of a URI into cleartext. This landed with changes to keys, so the server wipe also handles the local name changes.
Add a couple Utils helper to create a pair of simple [gs]etters that use a hash property instead. Apply this to various records: WBORecord, {Priv,Pub}Key, Crypto{Meta,Wrapper}, and every engine's type records. Migrate by making sure key data exists (name change).
Set _recordObj for Bookmarks/History engines and override PlacesItem.decrypt to switch itself to the right type after CryptoWrapper decrypts the payload.
Get rid of the QueryInterface and just use instanceof while copying the logic of nsFormHistory::Notify to avoid divergent logic until satchel provides a notification.
Register the built-in engines on service start-up instead of from the overlay, and have Engines.register check if the engine has already been registered.
Add the remaining special top level folders and ignore them for certain behavior like getAllIDs and wipe. Have the tracker ignore changes to things in the tags folder.
Create a specialIds hash and use it to for getting weaveId/id, determine top level, if a folder is a root, getting all ids, wiping, and tracker ignoring.
Import engines to the Weave global object and use them to register engines, which checks if the arg is an array. To support handling of errors (unused), the engine is returned on register failure.
Expose a .deleted property that engines can set to true to store an even thinner deleted payload (empty string "" instead of "[null]") on the server. Handle deserializing of deleted records by setting the property. Note: Engines must set their payloads to something JSON-able if it's not a delete record.
Initialize unified client store from disk json and local prefs and update on pref changes + sync. Clean up client engine code (local vs inherited, alphabetical), and create a helper modify() to save snapshots.