Compute all derived properties and add them to UGM nodes, stamping each written value (see the class doc).
The current version of a definition, or undefined for a name this engine has never defined.
Stamps in ugm that are STALE: written by a definition this engine
currently holds, at a version older than that definition's current
one. A stamp from a name the engine no longer defines is not stale
(there is no current rule to be behind), only orphaned; it stays in
ugm.listDerivations() until a source write or clearDerivation
removes it.
Recompute ONE definition, by name, over every node. The way to
refresh the values listStale reports after a define changed the
rule. A name this engine does not define is a no-op.
Computes derived numeric properties from expressions over each node's numeric properties. Expressions are parsed by the toolkit's own numeric language (
./expression), which has no member access, assignment, function definition, or strings; it replaced expr-eval, whose 2.0.2 release has unpatched code-execution and prototype-pollution advisories (GHSA-mpfx-v932-r2fv). Treat an expression as code all the same: a host that stores expressions and shows them to other users should validate who may write them.Provenance (issue #17): every value the engine writes is stamped in the UGM's derivation registry (
ugm.getDerivation(nodeId, name)) with the definition's name asdefinitionId, the definition's current version, the write time and the expression text. The value itself stays a plain property, so nothing downstream changes shape; the stamp is what lets the table, the inspector and the JSON export tell a computed value from a measured one.Versions are per definition name and monotonic for the engine's lifetime: a new name starts at 1,
definewith a different expression for an existing name increments it, and a re-definition with the same expression keeps it (the rule did not change, so the values are not stale).removekeeps the counter, so a name defined again later continues from where it left off and the old stamps read as stale rather than current.