What's new
v0.2.0 bundles three feature lines that all landed in this release cycle. Everything is additive — schemaVersion is not bumped, existing graphs load unchanged, and tools called without the new parameters behave exactly as before.
🕰 Bi-temporal model
Every node can now record when the fact was true in the world (occurred_at, since, until) independently of when the node was last written (updated). This unlocks "as-of" queries — "what did we know about the server in March?" — and lets supersedes automatically close the validity interval of the older node so the two never overlap in time.
New fields on every node (all optional ISO YYYY-MM-DD):
occurred_at— when the underlying fact happenedsince/until— half-open validity interval[since, until)
New helpers exported from @litopys/core: resolveOccurredAt, isValidAsOf, eventDateFromId, isIsoDate.
MCP tool changes:
litopys_searchandlitopys_relatedaccept an optionalas_of: "YYYY-MM-DD"filterlitopys_createacceptsoccurred_at,since,untillitopys_linkwithrelation_type: "supersedes"auto-closes the target'suntilwhen unset (returnsauto_closed: { node, until }on success,warningsif the target was already tombstoned)
New CLI: litopys check --fix-temporal [--dry-run] — idempotent backfill of occurred_at on existing nodes (event ids with a date prefix get the prefix; everything else falls back to updated).
Docs: docs/temporal-model.md
🧹 litopys evolve — graph maintenance
A new subcommand for keeping an aging graph clean. Two passes, both runnable in one invocation.
--archive-tombstoned [--older-than 365] [--dry-run]
Moves nodes whose until lies more than N days in the past (default 365) into <graph>/archive/<original-subdir>/, preserving structure. Every move is logged as one JSON line in <graph>/archive/manifest.jsonl ({id, archived_at, original_path, until}) so the action is auditable and theoretically reversible. Files under archive/ are never re-scanned, so repeated runs are no-ops. Uses atomic rename(2) per file.
--auto-merge [--min-similarity 0.95] [--dry-run]
Walks the quarantine directory for merge-proposal files, reads each proposal's detectedBy: "similar:<score>" provenance, and accepts every proposal at or above the threshold via the existing acceptMergeProposal code path. Manual proposals (detectedBy: "manual") are never touched. Per-file errors (missing node, type conflict) are captured and reported, not thrown.
Combined: litopys evolve --archive-tombstoned --auto-merge — a single command for a maintenance cron.
Docs: docs/memory-evolution.md
📏 @litopys/bench — benchmark harness
A new workspace package for running Litopys against memory-benchmark datasets and producing a comparable report. Designed so future LongMemEval / LOCOMO adapters plug in without changing the harness.
What it does:
- Spins up an isolated graph in a temp directory (no pollution of
~/.litopys) - Feeds each session through the configured extractor
- Runs each question through
litopys_search+litopys_related, scores against expected node ids - Records per-query latency
- Emits a JSON report and a Markdown summary
Metrics: recall@k, precision@k, mean latency.
Mock extractor ships in the same release (LITOPYS_EXTRACTOR_PROVIDER=mock) — deterministic, network-free, lets the harness (and CI) run without API keys.
New CLI: litopys bench [--dataset <name>] [--limit N] [--output bench-report.json]. Ships with a built-in synthetic dataset of 15 questions.
Sample run on the built-in synthetic:
Provider: mock
Total questions: 15
Recall@5: 0.9778
Precision@5: 0.3200
Mean latency: 4.00ms
The low precision@5 is an artifact of the synthetic dataset — most questions have 1–3 expected ids while k = 5, so empty slots count as misses by the standard convention. The harness exists primarily to enable real industry-dataset adapters as a follow-up.
Docs: docs/benchmark.md
Other changes
@litopys/mcpnow re-exports the public type aliases (SearchHit,LinkResult,ToolResult,ToolOk,ToolErr) so external packages can type their pipelines without reaching into internal paths.
Tests
- Baseline (v0.1.4): 481 / 481
- After this release: 613 / 613 (+132 across new test files)
- Coverage on new code: archive 97.6%, auto-merge 95.9%, evolve 95.0%, bench package ~95%+
Upgrade notes
- No migration required. All new fields are optional, all new tools are additive, no public APIs changed.
- Recommended: after upgrading, run
litopys check --fix-temporalonce to backfilloccurred_aton existing nodes (idempotent, dry-run available).
Install / upgrade
curl -fsSL https://raw.githubusercontent.com/litopys-dev/litopys/main/install.sh | shOr pin to this version:
curl -fsSL https://raw.githubusercontent.com/litopys-dev/litopys/main/install.sh | VERSION=v0.2.0 shFull changelog: v0.1.4...v0.2.0