I'd like to reexamine the scope of this bug because it's a partial blocker for bug#49860 (IRCv3). You'll recall among its original goals were two overlapping concerns: a. Granular configuration of a local module's user options b. Persistence of a local module's data across reconnections One idea bandied about for addressing the first was to recommend and accommodate buffer-local options, that is, recommend that options in a local module's Custom group be explicitly declared buffer-local with the :local `defcustom' keyword and that they be given local bindings on module activation, thus initializing them with values from the current environment. While this is technically feasible, a few notable complications would need sorting out [1]. A complementary aspect addressing the second goal of convenient persistence was also previously floated and amounted to leveraging the `permanent-local' symbol property on a local module's own variables of interest to sustain them across reconnections. With local user options, this would likely involve the `permanent-only' argument to the :local `defcustom' keyword explained in (info "(elisp) Variable Definitions"). For the stated purpose of sustaining variables of interest across reconnection boundaries, this approach remains viable [2], at least for third party modules that don't know about the internal persistence mechanism [3]. So, in light of the new proposal for "scoped" configuration now officially on the table [4], it might behoove us to just pretend the granularity objective is henceforth solely the domain of that proposal's bug (bug#76019). That'll allow us, here, in this bug, to focus entirely on the second objective about persistence and to hopefully arrive at something worthy of some finality for 5.7. To that end, here's some related territory possibly worth exploring: 1. A public utility function to access the prior buffer's local variables during reconnection 2. A managed facility for declaring arbitrary persisted data with supporting CRUD operations 3. Optional helpers for an option's :set function that update persisted values in affected buffers or inform users to cycle the mode or restart the session 4. Documenting differences in how a local module's mode command variants behave with the various flavors of local modules, like session-wide, target-only, etc. 5. An advanced tutorial on how to write a local module using only the public API via a fully functional demo To get started, I've attached a PoC of a possible approach for point 2 (the CRUD thing). It turns out my having explored the idea some has led me to the opinion that it's probably better to stick to points 4 and 5 only and to let module authors deal with the rest. Basically, I'm not sure asking anyone to adopt yet another magical abstraction layer just to persist state is any less mentally taxing than asking them to wrangle it all themselves using lower level Emacs facilities, so long as we provide clear guidelines and examples with any necessary boilerplate. Of course, this observation disregards maintainability concerns, so we'd need to be pretty certain all related infrastructure is mostly here to stay (famous last words). More to come on this shortly. Thanks. [1] Possible complications with the :local `defcustom' keyword idea: . Most users are unfamiliar with buffer-local options. And, AFAICT, Customize doesn't itself prescribe how such an option's variable should be made buffer local nor how or whether relevant updates ought to be propagated across existing local bindings when the default value is updated. It would seem such concerns are the responsibility of the application. But these are *user* options, and users can't be bothered to learn the idiosyncrasies of each app just to configure it to behave as expected. They'll either move on or risk contending with unwelcome surprises. . The buffer-wise "scope" doesn't always align perfectly with contexts endemic to IRC, the most important being the connection-wise session, which spans multiple buffers (internally, those having the same `erc-networks--id'). Users on 29+ might be able to use `setopt' to update the value cleanly within a session, for example, in a server buffer, and have the change shared with all targets as well. But, users on 27 and 28 can't be expected to invoke the option's :set function outside of Custom buffers, although advanced users can manually apply updates via the module's explicit enable/disable command variants. . Modules oftentimes ignore the value of an option after initialization and instead use something derived from the original value and then progressively refined. Local modules also perform other initialization tasks based on the value of an option, such as subscribe to certain hooks. While buffer-local options may agree sufficiently with this pattern, so long as they're bound before module setup code runs in a new or reused buffer, the pattern dictates that a module capture a "snapshot" of an option's value anyway, so there's no reason to prefer buffer-local bindings over, say, more ephemeral and arguably easier to reason about `let' bindings. . Per-target options won't magically work when local in a target buffer because ERC often decides on target-related business with the server buffer current. Indeed, the target buffer in question may not even exist yet, which happens most often in response handlers, such as `erc-server-PRIVMSG'. Although this situation can be remedied, doing it in a backward compatible way seems a chore. [2] A local module's mode variable itself can't be `permanent-local' because the majority of setup it performs won't survive a major-mode reset, thus creating an "inconsistent state" during the crucial reinitialization period when modules inspect and even modify one another. It's then that they also need to possibly recall the original value of variables not owned by them or even ERC (and these definitely can't be made `permanent-local'). [3] The internal inter-session persistence mechanism consists mainly of a crude restoration ritual for transferring values from old buffers to new via the variables `erc--server-reconnecting' and `erc--target-priors'. These are bound at module initialization time to an alist containing the local variables of the "reassociated" buffer, if any. Aside from those symbol names not being great and there being no public interface, there's also no way to recover if something goes awry during (re)initialization: restarting the session from scratch won't work so long as module-managed local variables are still bound to unusable values in the old buffer. Basically, the offending local module must run its "disable body" somewhere: either in the old buffer, before reassociating, or in the new one upon failure. Clearly, a friendlier and ideally more robust user-facing solution is necessary. [4] https://debbugs.gnu.org/cgi/bugreport.cgi?bug=76019