Expand description
Content-addressed memoization of crate::featurize (design L0).
φ is a pure function of (term, spec) — that is the determinism contract
crate::render states — so any featurization the engine has already
performed can be replayed instead of re-rendered. That matters because the
engine performs the same featurization repeatedly and unavoidably:
fugue-ppl’s adaptive single-site MH executes the model twice per step, once to re-score the current trace — which is bit-identically the tree the previous step accepted. Every refinement step therefore renders one tree it has already rendered.Engine::insert_candidatere-featurizes the tree the refinement walk (or the edit bench) just featurized, to obtain the φ it admits it with.
Neither is a bug to be deleted — the first is inside a dependency’s kernel,
the second is the honest way to admit a candidate. A memo removes the cost
without touching either. It is exactly lossless: a hit returns the same
Features object the miss produced, so nothing downstream — least of all
the raw φ that enters the observation log — can tell the two apart.
§Keys
render_key is fnv1a128 over serde_json of the term and of the
phrase spec. FNV rather than DefaultHasher because DefaultHasher’s
output is explicitly not guaranteed stable across Rust releases, and this
key is meant to be persistable (design L2) — a toolchain bump must not
silently invalidate every stored row. serde_json is deterministic across
runs and platforms for these types: field order is the struct’s, and floats
round-trip exactly under the float_roundtrip feature the workspace pins.
§Persisting a row: the key is not enough
render_key addresses (term, spec), which is everything φ depends on
given a fixed featurizer. A stored row survives a reload only if the code
that would recompute it agrees, and the key cannot see that code: change the
normalizer, a descriptor’s formula, or the vet gate, and the same key now
names a different measurement.
RENDER_EPOCH is that missing coordinate, and cache_namespace
combines the two. Bumping the epoch orphans every stored row at once, which
is the intended and only correct response to φ moving — a persistent cache
whose invalidation is anything less than total is a cache that will one
day serve a number from a featurizer that no longer exists.
Structs§
- Cached
Features - Everything
featurizeproduces except the samples — the persistable unit, and what a memo hit returns. - Memo
Stats - Memo occupancy and hit accounting.
- Render
Memo - A bounded, content-addressed featurization memo.
Constants§
- DEFAULT_
AUDIO_ CAP - Audition buffers retained (~565 KB each at the default phrase) — enough for the current duel pair, the bench, and recent history, at ~7 MB.
- DEFAULT_
FEATURE_ CAP - Feature entries retained. A refinement generation is a few hundred featurizations; 2048 keeps a whole session’s worth of walks resident at ~2 MB.
- RENDER_
EPOCH - Generation of the featurizer itself.
Functions§
- cache_
namespace - The persistent cache’s namespace for one stimulus:
"e<epoch>:<spec hash>". - canonical_
tree_ json - The exact bytes a key is computed over for a term.
- featurize_
memo featurize, consultingmemofirst and populating it on a miss.- render_
key - Content address of one
(term, spec)featurization, 32 lowercase hex chars.