Core math primitives
FHRR represents each key and value as a unit-magnitude complex vector of dimension D=16384. Every element has the forme^(iθ) — a point on the unit circle in the complex plane. The phase angle θ carries all the information.
Four operations in src/nuggets/core.ts form the foundation:
bind
bind(a, b) combines two vectors into a single bound pair by adding their phases element-wise. In split-complex form (re/im arrays), this is equivalent to element-wise complex multiplication:
unbind
unbind(memory, key) recovers the value vector from a memory superposition by subtracting the key’s phase element-wise. This is the conjugate multiplication of key:
orthogonalize
orthogonalize(keys, iters, step) nudges a set of randomly generated keys away from each other in complex space, then projects back onto the unit circle. This reduces interference between facts stored in the same bank:
sharpen
sharpen(z, p) raises the magnitude of each recovered vector element to the power p, increasing contrast in noisy superpositions. For clean unit-magnitude keys p=1.0 is a no-op, but recovered memories carry magnitudes that encode evidence strength:
p makes the top candidate stand out more sharply against near-misses.
How facts are stored
EachNugget instance holds:
- A list of
Factobjects (key, value, hit count) stored in<name>.nugget.json - A set of banks (default: 4) and ensembles (default: 1) built in memory at runtime
remember(key, value), Nuggets:
- Adds or updates the fact in the
_factsarray - Mirrors the fact into the note graph as a
"fact"kind note - Marks the memory as
_dirtyso the next recall triggers a rebuild - Auto-saves to disk if
autoSaveis enabled
Vectors are never stored on disk. The
.nugget.json file only contains the raw key/value strings. FHRR vectors are regenerated from deterministic seeds on every rebuild, which is what keeps files compact.Banks and ensembles
Facts are distributed across banks in round-robin order. Each bank stores its own superposition memory vector. Multiple ensembles can be used to reduce variance in recall (the default is 1). During recall, each bank’s memory is unbound independently and the similarity scores are summed across banks before the final softmax step.Regenerated vectors
Keys are generated deterministically from the nugget’s name using the Mulberry32 PRNG seeded with a hash of the name. This means:- The same nugget always regenerates identical keys
- A nugget loaded from disk rebuilds exactly the same FHRR structure
- No vector data needs to be serialized
The recall algorithm
When you callrecall(query), Nuggets runs a three-stage process:
Tag resolution
The query string is matched against stored fact keys in order of strictness:
- Exact match — lowercase equality
- Substring match — the query is contained in the key, or the key is contained in the query
- Fuzzy match — a sequence match ratio is computed between the query and each key; the best scoring key above the threshold (default: 0.55) is used
{ found: false }.Decode
For the resolved key position The
pos, the memory is unbound in two steps:sentKey encodes the sentence context and roleKeys[pos] encodes the position within the bank. The recovered vector is then passed through sharpen and corvacsLite (a soft magnitude limiter) to clean up the noisy superposition.Softmax scoring
The recovered vector is compared against every known vocabulary vector using cosine similarity. The similarities are summed across all banks and ensembles, then passed through a softmax with temperature T=0.9. The vocabulary word with the highest probability is returned as the answer.The result also includes:
confidence— the top probabilitymargin— the gap between the top and second probabilityfound— whether the key was resolved
Capacity
The practical capacity of a single nugget is approximately:status() method reports capacity_used_pct. At 80% usage you get a warning; at 90% a critical alert.