pub struct Uid(pub u64);Expand description
A stable identity for one node, independent of where it sits.
§Why the tree needs one
Every other handle on a node in this system is its position: the trace
key (node/0/1), and therefore the trace address of every knob on it, and
therefore every lock, every remembered hand position, every selection. That
is fine until the structure moves. Insert one filter at the top of a chain
and every key below it shifts by one segment; delete a mixer branch and the
survivor is re-rooted; run one generation of refinement and the tree is
rebuilt from a trace with no memory of the object graph at all. Under
positional identity the only honest response to a structural edit is to
throw the UI’s state away — which is exactly what the workbench used to do,
with the comment “structure changed — locks cleared” — and that destroys the
loop the graph editor exists to serve: build a routing by hand, pin it, and
breed around it.
A Uid is minted once, travels with the node through clones, splices and
refinement, and is dropped only when the node itself is.
§It is deliberately invisible to the model
uid is UI identity, nothing else. It must never reach the generative
model, the featurizer, the compiler, or anything content-addressed, because
two patches that differ only in uids are the same patch and every one of
those systems is entitled to say so:
- Equality ignores it.
PartialEqhere istrueunconditionally, so the derivedPartialEqonAudioNode/PatchTreekeeps comparing patches by content. The engine’s pool dedup (self.pool.iter().any(|c| c.tree == end)) and refinement’s own “did this walk move at all” (current != *seed) are both that comparison, and both would break the moment a fresh uid could make two identical trees differ. - Hashing ignores it, for the same reason and so the two stay coherent.
- It is skipped in JSON when unset, and
auracle_features::cache::canonical_tree_jsonclears uids before hashing, so the render memo’s content address is byte-identical to what it was before uids existed. A cache key that moved with the UI’s bookkeeping would miss on every refinement step and invalidate every persisted row. - It is not a choice site.
crate::genomeneither encodes nor decodes it, soto_trace/from_traceround-trips carry no uid — which is whyPatchTree::inherit_uidsexists.
§Uid::NEW and settling
Construction sites write Uid::NEW (zero, “unset”) rather than minting
eagerly. The prior samples thousands of trees per refinement walk and all
but one are thrown away; minting there would burn identities for nothing and
make the counter’s value depend on how much search ran. Instead a tree is
settled — PatchTree::ensure_uids — at the few points where it becomes
something a person can point at: admitted to the pool, adopted onto the
bench, restored from a save. Everything before that is anonymous.
Tuple Fields§
§0: u64Implementations§
Source§impl Uid
impl Uid
Sourcepub fn observe(id: Uid)
pub fn observe(id: Uid)
Note that this identity already exists, so the mint never reissues it.
The counter is per process, and a restored session is the case that makes that a problem rather than a detail: a save carries the uids it was written with (that is the entire point — a hand-placed layout has to survive a reload), but a fresh page load starts the counter at 1. Insert one module into a restored patch and the mint would hand out an id that tree is already using, and two nodes would answer to one lock. So every identity the engine sees pushes the counter past itself, and a restore — which settles the whole bank on the way in — leaves it above every id in the save.