Items kept across threads and runs, by (Namespace, key): /memories/ files (StoreFileBackend) and semantic memory (F7). Its target is Transactional (C4).
The one mutation primitive is modify, a read-modify-write in the store's own transaction, serialisable within its namespace: the outcome already recorded for the effect's key, or the change decided against a StoreView and applied, bounds checked and (key, outcome) recorded with it. An edit therefore never loses a concurrent write, a check that spans keys cannot be raced, and a replay whose first attempt landed returns the first outcome before it re-reads anything. put and delete wrap it in ReplayGuard.transactional; a backend over the store uses modify the same way with its own keys.
ujson.Value is mutable, so a store copies every value it is given and every value it hands out. An implementation keeps its applied keys only until C4's guard forgets them, and never by age.
In one transaction, serialisable within ns, fenced by token (C4's AppliedKeys): a token older than the newest seen for effect.scope is refused with a Left and changes nothing; otherwise it becomes the newest, and then: if effect was applied, its recorded outcome and no write; otherwise change, decided against the namespace as it is now, which may refuse (Left: nothing written or recorded), then the namespace's and item's bounds, then the write and (effect, outcome) recorded together. An over-limit change is a BackendRefused. The newest token per scope is kept as long as the store keeps that thread's data: durably, in a real store.
In one transaction, serialisable within ns, fenced by token (C4's AppliedKeys): a token older than the newest seen for effect.scope is refused with a Left and changes nothing; otherwise it becomes the newest, and then: if effect was applied, its recorded outcome and no write; otherwise change, decided against the namespace as it is now, which may refuse (Left: nothing written or recorded), then the namespace's and item's bounds, then the write and (effect, outcome) recorded together. An over-limit change is a BackendRefused. The newest token per scope is kept as long as the store keeps that thread's data: durably, in a real store.
The outcome returned is the recorded one, decoded, so a first run and its replay return the same value. A's codec must be a pure function of its value: C4's guard encodes the outcome again for its journal, and a codec that answered differently would record two things.
Removes key from the applied-keys table, fenced by token as described above: Left if token is older than the newest token seen for key.scope; Right(()) if the key is not there.
Removes key from the applied-keys table, fenced by token as described above: Left if token is older than the newest token seen for key.scope; Right(()) if the key is not there.