Concepts — how to think about Veracium¶
Veracium gives an agent durable, per-user memory. This page is the mental model;
api.md is the reference and mcp.md is the MCP setup.
The three things memory is for¶
Veracium distinguishes three recall targets, because each fails differently:
| target | example | how Veracium stores it |
|---|---|---|
| User model | "vegetarian", "employer is Acme" | typed graph edges |
| Interaction history | "on Tuesday the export failed" | dated episodes |
| Work knowledge | "the CLI export worked; svg-batchpack didn't" | typed graph edges |
Store of record: edges + episodes¶
The source of truth is two things:
- Edges — typed relational facts:
(subject, relation, object)with a note, e.g.user —has_pet→ "dog named Ollie". Entity-centric, queryable, and each carries provenance. - Episodes — dated one-sentence summaries of what happened in an interaction. Episodes supply narrative the graph can't ("what did we work on Tuesday?").
A curated wiki (a compact Markdown view) is compiled from edges + episodes and cached — but it is never the source of truth. If you delete the wiki cache, nothing is lost; it recompiles.
Why this shape: in the research behind Veracium, a typed graph won on provenance and entity recall, dated episodes supplied the narrative it lacked, and an LLM curator compiling the working view beat every flat store on both short and long histories.
Provenance and authorship — the security backbone¶
Every edge and episode records who authored the evidence it came from:
user— the user's own messages and sent mail. Trusted.third_party— received mail, external documents, tool output about the user. Untrusted: anyone in the world can put text here.system— Veracium's own derivations (e.g. consolidation).
This one field is the most important input you give Veracium. A received email that
says "per our agreement you owe $2,400" is a claim, not a fact — and because
you marked it third_party, Veracium stores it as a third_party_claim edge with
the claimant as subject, never as a fact about the user. Recall renders it under
an explicit never-assert flag, and the answer gate refuses to state it as true.
Content-type quarantine backs this up: obligation/debt/renewal claims from third parties are quarantined regardless of how plausible they look — the attack that gets past naive memory is the routine-looking invoice, not the absurd one.
Mixed provenance: derived_from¶
Authorship is per-event — but your event's text may embed content someone
else influenced. A system-authored triage verdict that quotes a received
email's subject, a summary derived from a third-party document: the event is
honestly yours, yet an attacker wrote parts of what it says. Declare that with
derived_from:
mem.remember(user, f"Triage classified the mail (subject: {subject!r}) as spam.",
author=EvidenceAuthor.SYSTEM, derived_from=EvidenceAuthor.THIRD_PARTY,
event_type="triage")
Trust is capped at the minimum of author and derived_from: nothing
extracted from such an event — no edge, and not the episode either — can reach
an assertable surface (the gate's GROUNDED block or the compiled wiki). The
classification history still shapes behavior through recall's unverified
channel; it just can't be asserted as fact. Provenance records both fields, so
the graph stays honest: authored by system, derived from third-party.
The rule of thumb: if any span of the event text was influenced by a party you wouldn't mark as the author, declare the lower-trust source. Without the declaration, Veracium trusts your voice — quoted attacker text and all.
Supersession — one current value, history retained¶
For functional facts (preference, employer, location, deadline) a new value supersedes the old one: at most one is "current", but the prior value is retained (soft-invalidated), so both "what does the user prefer now?" and "what did they prefer before?" are answerable. Re-stating a fact reinforces it (refreshes its validity) instead of duplicating.
Non-functional facts (pets, relatives, tools used) accumulate.
Volatility and lifecycle¶
Each fact has a volatility class — how long it's expected to hold:
permanent → durable (years) → slow (months) → transient (days) → ephemeral
mem.maintain(user_id) — the "overnight" job — uses it:
- transient/ephemeral facts past their lifetime lapse silently (nobody asks about a flu from three months ago);
- durable/slow facts past their lifetime are flagged possibly-stale (surfaced in recall, never silently dropped — "still at Acme?");
- cold episodes are consolidated into denser records, preserving first occurrences of failures, fixes, illnesses, and dated commitments.
A note on dates¶
Relative dates in ingested text ("due Friday", "next week") are resolved to
absolute dates during extraction. Veracium injects a weekday→date calendar
anchored to the event's date so the model copies dates rather than computing
them — far more reliable than freehand, and the prompt tells it to keep the
original wording when a date is neither stated nor on the calendar. But it is
still an LLM step: treat an absolute date stored in memory as an inference from
the source — high-confidence when the source stated an explicit date, lower when
it was relative. Always pass an accurate date= per event (the date it actually
occurred) so the calendar anchors correctly; the default is "today", which is
wrong for backfilled or dated content.
Recall and the abstention gate¶
mem.recall(user_id, query) assembles the curated wiki + a per-query subgraph and
partitions memory into grounded (verified, assertable) and unverified
(third-party claims/reports). mem.answer(user_id, query) adds the gate:
- answer only from grounded memory;
- never assert unverified claims as fact;
- say "I don't know" rather than guess.
The gate is why Veracium doesn't confabulate on a miss and doesn't get injected: a fact from the user's own sent email is answered; the same-shaped claim from a received email is refused. Provenance-by-authorship, doing its job.
What Veracium does not do¶
- It doesn't own your API keys or pick your model — you pass a
Completecallable. - It doesn't answer the user for you unless you call
answer();recall()just hands you grounded context to drop into your own prompt. - It isn't multi-user-leaky: memory is scoped by
user_id; one user's memory can never reach another's.