TGMS

An agent-native bi-temporal graph store. Thirteen verified temporal operators exposed as tools — typed, deterministic, cost-guarded — and a Planner–Executor–Verifier loop that machine-checks every claim in an answer against the execution trace that produced it.
v0.4.0 · four frozen domains incl. an equal-information SQL baseline · 110-question independent coverage study · validated on two GPU clusters, four model scales, three model families · unsupported-claim rate 0.000 in every configuration measured
0.14 → 0.63 as models scale · baselines flat
The operator-backed advantage grows with model capability (Qwen2.5 7B→32B, frozen test split) while RAG and text-to-Cypher never exceed 0.28 — and giving RAG its intended k=20 context made it worse.
0.90 vs 0.00 latest-state systems
Correction probes — “as of transaction time T, what did we believe?” — 0.897 on CollegeMsg, 0.846 on email-EU. Snapshot and RAG systems cannot express the question.
7.8% → 0.000 unsupported claims
Raw model answers carry 7.8% unsupported claims; trace-grounded gating removes every one, costing a single point of exact match.

Why two kinds of time?

Every fact carries valid time (when it held in the world) and transaction time (when the store believed it). That separates evolution — “the edge ended” — from correction — “we were wrong.” Agents can then answer belief-state questions deterministically, no LLM required for the time travel itself:
# same entity, same operators — only as_of_tt differs
entity_history(uid="n605", as_of_tt=BEFORE_CORRECTION)  # → 1 version
entity_history(uid="n605")                              # → 3 versions
And every answer is auditable. The trace viewer renders the plan DAG, per-operator cards (args, rows, latency, result digests), and each claim badged by the verifier:
$ tgms ask "How many nodes can n9 reach in May?" \
    --store stores/collegemsg --model openai/Qwen/... \
    --html trace.html
claims: c1 count=343 → verified ✓  (evidence: s1)
verified weakly supported unsupported — see a real rendered trace

Quick use cases

1 · Verified operators, no LLM needed
Time-respecting reachability, δ-motifs, snapshot diffs, bursts, Allen interval joins — deterministic, bounded, oracle-tested (500 randomized cases per operator).
$ uv run tgms call temporal_reachability '{"src": "n9",
    "window": {"t_a": 1082040961000000, "t_b": 1088000000000000}}' \
    --store stores/collegemsg
{"rows": [...], "rows_total": 343, "result_digest": "9c4f…"}
2 · Hand the toolbox to any MCP agent
The tool server is stateless and read-only: attach Claude Desktop/Code or any MCP client and it gets the whole verified algebra against a shared temporal store.
$ tgms serve --store stores/collegemsg
# any MCP client now sees 13 typed temporal tools,
# each with schemas, cost hints, and output contracts
3 · Investigations with an evidence trail
“Among accounts reachable from X in February, how many cyclic temporal triangles closed within a day?” — reachability feeds motif counting via plan refs; arithmetic runs in a compute operator, never in the LLM.
s1 resolve_entities → s2 temporal_reachability
   → s3 count_temporal_motifs(node_filter=$s2.rows[*].uid)
answer: 14 · claim c1 verified against s3’s digest
4 · Audit under revision
Knowledge bases get corrected. Reproduce exactly what the system believed when a decision was made — results pinned to a past belief state are byte-identical forever (a tested metamorphic property, not a promise).
$ uv run tgms eval c2 --store … --suite …   # verifier acceptance
detection 500/500 · false positives 0 · accepted: true

How it works

1 · PlanThe LLM emits a small JSON DAG of operator calls. A static verifier enforces grounding (no invented identifiers), output contracts (no invented result fields), temporal sanity, and cost — with structured repair payloads.
2 · ExecuteA deterministic executor runs the DAG over the bi-temporal store; results are content-addressed; truncation taints dependents. Re-execution reproduces identical digests.
3 · VerifyA reporter writes the answer; every count, entity, ordering, and pattern claim is machine-checked against the trace. Unsupported claims never ship.
typed-answer accuracy · Qwen2.5-14BTGMSbi-temporal SQLtext-to-Cypherstatic-RAG
CollegeMsg (94 tasks × 3 seeds)0.4080.2840.1520.064
email-EU (94 tasks)0.3090.2660.1060.053
synthetic patterns (102 tasks)0.3140.2650.1570.029
Bitcoin-OTC trust network (94 tasks)0.3090.3400.1600.085
correction probes (three domains)0.85–0.920.85–0.920.0000.000
CollegeMsg @ Qwen2.5-32B (H100)0.6280.2770.074
Frozen test splits (SHAs recorded before measurement). The bi-temporal SQL baseline writes SQL against the same version store TGMS uses — equal information, different interface: it matches TGMS on belief-state probes and on flat schemas, and trails by +0.124 (CI [+0.07,+0.18]) where computation composes. A 110-question independent study puts current operator coverage at 10/110, with grouped aggregation the dominant gap. Emitted unsupported-claim rate is 0.000 in every configuration measured. Every number carries determinism receipts — full report.

Get started

git clone https://github.com/zxf-work/tgms && cd tgms
uv sync --extra agent
make test                        # 81 tests: property, oracle, metamorphic
uv run tgms replay benchmarks/frozen-v1/collegemsg.eventlog.jsonl \
    --store stores/collegemsg     # byte-identical frozen-campaign store
bash scripts/run_webapp.sh       # interactive guided demo → localhost:8080
Works fully offline for operators, task suites, and the verifier; point --api-base at any OpenAI-compatible endpoint (e.g. vLLM) for the agent loop. Apache-2.0.