Normally a Binding from the main CpsScript is shared with those from scripts created via load, because InvokerHelper.createScript links them to the binding defined in CpsGroovyShell.context.
After the build is resumed from disk, each time SerializableScript.readResolve is called, it uses a distinct Binding with the same variables as in the original program. So the main script and any scripts already loaded are OK, or at least have the same bindings as they did before; presumably subsequent changes to the main script's bindings would no longer be visible to loaded scripts. The more visible problem is that the shell's binding is now empty (because it is a fresh instance from CpsFlowExecution.parseScript), so the next time load is called, that new script gets a clone of an empty binding—so it only gets a DSL bound via CpsScript.$initialize, nothing more.
Making SerializableScript save the original Binding to the stream is not an option, since Binding is not Serializable.
You would think that reparse could somehow track the bindings in the Script it returns, but in fact this instance is discarded—only its Class is used, since the actual instance is produced by deserialization.
You might then think that CpsFlowExecution.loadProgramAsync could make sure that the context of the shell got linked to the binding of the main script (and ideally the same for previously loaded scripts, too). But after deserialization, we only have a CpsThreadGroup, and it is not obvious how to find the CpsScript instance(s) associated with it: they are held implicitly somewhere in the Continuation.
Kohsuke Kawaguchi help!