States¶
A state is a named piece of information that holds one value at a time
and changes over time: account.plan, customer.shipping_country,
project.release_channel. TypedMem keeps its current value, every value it
used to have, and where each value came from.
The old value isn't false. It is no longer current.
▶ See it happen in the Truth Through Time explorer
Facts change¶
Every block of output on this page is real. A test runs these commands on every commit and compares the output.
$ typedmem set account.plan Free --valid-from 2026-01-05 --source signup
account.plan = Free (new)
$ typedmem set account.plan Pro --valid-from 2026-04-01 --source billing
account.plan = Pro (was Free)
$ typedmem set account.plan Enterprise --valid-from 2026-09-01 --source billing
account.plan = Enterprise (was Pro)
$ typedmem get account.plan
Enterprise
$ typedmem history account.plan
Enterprise current source: billing
Pro previous source: billing
Free previous source: signup
$ typedmem history account.plan -v
Enterprise current since 2026-09-01 source: billing
Pro previous 2026-04-01 → 2026-09-01 source: billing
Free previous 2026-01-05 → 2026-04-01 source: signup
$ typedmem get account.plan --at 2026-06-15
Pro
get --at answers "what was current then?". Nothing is ever deleted.
Facts arrive late¶
TypedMem orders values by when they became true (--valid-from), not
by when they arrived. A record that describes the past goes into the past,
however late it arrives. If it repeats a value that is already known, its
source is added to that value:
$ typedmem set account.plan Free --valid-from 2026-01-05 --source signup
account.plan = Free (new)
$ typedmem set account.plan Enterprise --valid-from 2026-09-01 --source billing
account.plan = Enterprise (was Free)
$ typedmem set account.plan Pro --valid-from 2026-04-01 --source "support ticket"
account.plan: recorded Pro from 2026-04-01 as a past value; current is Enterprise
$ typedmem set account.plan Pro --valid-from 2026-04-01 --source "email from the customer"
account.plan: added source to historical value Pro (from 2026-04-01); current is Enterprise
A value with no --valid-from counts as true from now. TypedMem can
only know a record is old if the record says when it was true.
Sources disagree¶
When two values can't be put in time order, TypedMem doesn't pick one. That
happens when they start at the same moment, or when the later one comes from
a weaker source (--authority, default 1.0). get exits with code 3, and
Python's get raises StateConflict:
$ typedmem set account.plan Enterprise --valid-from 2026-09-01 --source billing
account.plan = Enterprise (new)
$ typedmem set account.plan Pro --valid-from 2026-09-01 --source crm
account.plan: CONFLICT: Pro disagrees with Enterprise; no current value
see: typedmem history account.plan
$ typedmem get account.plan
account.plan: CONFLICT, no current value
Pro conflict source: crm vs Enterprise
Enterprise conflict source: billing vs Pro
$ typedmem set account.plan Enterprise --valid-from 2026-09-10 --source "billing invoice"
account.plan = Enterprise (resolves conflict: Enterprise vs Pro)
A later value from a source at least as trusted settles the conflict. Authority alone never does: two claims about the same moment stay in conflict whatever their authority.
In Python¶
from datetime import datetime
from typedmem import AgentMemory, StateConflict
mem = AgentMemory(path="agent.db")
mem.set("account.plan", "Free", valid_from=datetime(2026, 1, 5), source="signup")
mem.set("account.plan", "Enterprise", valid_from=datetime(2026, 9, 1), source="billing")
mem.set("account.plan", "Pro", valid_from=datetime(2026, 4, 1), source="support ticket").outcome # 'past'
mem.get("account.plan") # 'Enterprise'
[e.value for e in mem.history("account.plan")] # ['Enterprise', 'Pro', 'Free']
mem.get("account.plan", as_of=datetime(2026, 6, 15)) # 'Pro'
mem.history(key) returns StateEntry objects (value, status,
valid_from, valid_to, sources, conflicts_with). They print as the
same table as the CLI.
The rules¶
| When a value arrives… | TypedMem | Outcome |
|---|---|---|
| nothing set yet | stores it | new |
| same value as the one in effect then | adds its source | unchanged |
| different, starts later, source not weaker | it becomes current; the old one becomes history | changed |
| different, starts earlier | stores it in history at its place in time | past |
| different, starts at the same moment, or later but from a weaker source | keeps both, and get refuses to pick |
conflict |
| starts in the future | keeps it, until its time | scheduled |
The full rules, including the invariant for what counts as a conflict, are in design note 0002.
Limits¶
- You name the key. TypedMem doesn't extract states from free text.
- One value per key. For things that hold several values at once, use ordinary memories.
- States order values by validity time and source authority only. They deliberately don't apply confidence or per-type rules ("ignore a less confident write", "always replace"). Use typed memories when those should decide.
- States are available in Python and the CLI. The HTTP server and the TypeScript client don't expose them yet.