Bigger indexes come from absorbing, never mutating: absorb appends every donor in turn, keeping its graph and linking it in across the appended part, and a donor the library consumed refuses every later verb with Status.Uninitialized.
A donor it did not absorb, like one of another scalar refused with Status.ConfigMismatch, stays a live index you still own, though its entries may already have moved.
A deferred absorb holds its donors until it is final, so meanwhile they refuse every verb and no other absorb can name them.
index.on(executor).absorb([shard]);
split is the inverse: it hands graph-local parts of the index to empty receivers of the same configuration, one part each, keeping their edges and leaving the index empty but live.
Both answer the closing refines’ report, as refine does.