
Security News
Happy Birthday, Shai-Hulud
It has been one year since Shai-Hulud made its first appearance on npm.
weavatrix-memory
Advanced tools
Bitemporal, evidence-carrying Rust memory and bounded context for Node.js and Bun
Bitemporal, evidence-carrying agent memory with a hard token budget — written in Rust, exposed to Node.js and Bun through Node-API.
It answers two different questions that most memory systems conflate: what was true at time T, and what did the agent know at time T. Every fact carries both axes plus the evidence behind it, so a wrong answer can be traced to the fact that caused it.
No LLM, no vector database, no network service, no async runtime, no external graph database.
npm install weavatrix-memory
# or
bun add weavatrix-memory
const { Memory } = require('weavatrix-memory')
const memory = new Memory({
knownAt: 20,
nodes: [
{ id: 'task:1', kind: 'task', label: 'Fix query' },
{ id: 'file:1', kind: 'file', label: 'query.js' },
],
facts: [{
id: 'fact:1',
source: 'task:1',
relation: 'depends_on',
target: 'file:1',
validFrom: 10,
recordedAt: 12,
agentId: 'agent:1',
sessionId: 'session:1',
evidence: [{ kind: 'test', source: 'query-suite' }],
}],
})
const context = memory.compileContext({
seeds: ['task:1'],
validAt: 20,
knownAt: 20,
tokenBudget: 2_000,
maxDepth: 2,
})
context.view // the facts and nodes that survived both time filters
context.graph // their projected provenance graph
context.receipt // exactly why this bundle looks the way it does
| Axis | Field | Question it answers |
|---|---|---|
| Valid time | validFrom, validUntil | When was this true in the world? |
| Known time | recordedAt | When did the system learn it? |
A query supplies both (validAt, knownAt). Asking "what did we believe last
Tuesday about the state of the repository last Monday" is a single query, not
a reconstruction.
All timestamps are integer Unix microseconds and must stay inside JavaScript's safe-integer range; a non-integer or out-of-range value is rejected, never rounded.
MemoryNode| Field | Type | Notes |
|---|---|---|
id | string | Stable identity. |
kind | string | Entity category. |
label | string | Human-readable name. |
repository, branch | string? | Scope, filterable at query time. |
attributes | Record<string, string>? |
MemoryFact| Field | Type | Notes |
|---|---|---|
id | string | |
source, target | string | Node ids. |
relation | string | Relation type; filterable at query time. |
validFrom | number | Start of valid time. |
validUntil | number? | Open-ended when omitted. |
observedAt | number? | |
recordedAt | number | Known time. |
agentId, sessionId | string | Who asserted it, in which session. |
confidence | number? | Basis points, 0 … 10000. |
evidence | Evidence[] | { kind, source, locator?, digest? } |
supersedes | string? | The fact this one replaces. |
MemoryInput{ nodes, facts, knownAt, sourcePosition? }
new Memory(input)Validates the whole projection up front: unknown node references, a confidence above 10,000 basis points, and malformed timestamps all throw here rather than at query time.
| Member | Returns | Notes |
|---|---|---|
nodeCount | number | |
factCount | number | |
view(validAt, knownAt) | MemoryView | { nodes, facts } after both time filters. |
graph(validAt, knownAt) | object | The projected provenance graph for that same instant. |
compileContext(request) | ContextBundle | See below. |
ContextRequest| Field | Type | Default | Effect |
|---|---|---|---|
seeds | string[] | required | Where the walk starts. |
validAt | number | required | Valid-time instant. |
knownAt | number | required | Known-time instant. |
tokenBudget | number | required | Hard ceiling. The compiler stops selecting facts before exceeding it. |
maxDepth | number | 2 | Traversal depth from the seeds. |
relations | string[] | all | Restricts which relations may be traversed. |
repositories, branches | string[] | all | Scope filters. |
ContextBundle{ view, graph, receipt }.
The receipt is the point. It states what the compiler did, so a context can be audited rather than guessed at:
| Field | Meaning |
|---|---|
validAt, knownAt, sourcePosition | The instant this bundle describes. |
estimator, tokenBudget, estimatedTokens | Which estimator ran, the ceiling, and what was actually spent. |
examinedFacts, selectedFacts | How much was considered versus kept. |
omittedByBudget | Facts dropped because the budget ran out. |
excludedByScope | Facts dropped by relation, repository, or branch filters. |
A context that is missing something always says which of the two reasons applies.
code | Cause |
|---|---|
InvalidArg | Unknown field, fact referencing an undeclared node, confidence above 10,000 basis points, timestamp that is not a safe integer, empty seed list. |
GenericFailure | Node or fact count exceeding the addressable range. |
| Runtimes | Node.js 18+ (Node-API 8), Bun 1.4+ |
| Platforms | Windows x64/arm64, macOS x64/arm64, glibc Linux x64/arm64 |
| Install script | none |
| Network at install | none |
| Runtime dependencies | none |
| Platform packages | none — all six bindings are in this one tarball |
benchmark/RESULTS.md is generated from the
weavatrix-benchmarks
harness.
There is no zero-network npm package that returns this contract, so the
comparison uses graphology as a topology-only floor — and it wins:
| Contract | Node 24 | Bun 1.3 |
|---|---|---|
| Depth-2 neighborhood node ids on a 10,000-node chain | graphology 20x faster | graphology 9x faster |
That row is published rather than hidden, and it is not a like-for-like result.
graphology performs the overlapping topology query and nothing else.
Weavatrix additionally filters valid time and known time, checks scope and
relations, enforces the token budget, selects evidence-carrying facts,
materializes the provenance graph and the receipt, crosses Node-API, and
serializes the bundle. A depth-2 walk on a chain also reaches only five nodes,
so the competitor's median sits at timer resolution: read it as "graphology
wins the topology-only query", not as a calibrated multiple.
The Rust repository separately keeps equal-contract comparisons against
agentic-memory, where the depth-2 context kernel at 100,000 nodes returned
the same result 26.1x faster — and where the bulk constructor lost by
1.68x. That losing row is published too.
Memory owns its repository, package, release evidence, and MIT license, and can be used entirely on its own.
Repository: Weavatrix/weavatrix-memory · Rust crate: crates.io/crates/weavatrix-memory · License: MIT
FAQs
Bitemporal, evidence-carrying Rust memory and bounded context for Node.js and Bun
The npm package weavatrix-memory receives a total of 27 weekly downloads. As such, weavatrix-memory popularity was classified as not popular.
We found that weavatrix-memory demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.

Security News
It has been one year since Shai-Hulud made its first appearance on npm.

Research
/Security News
Operators behind PolinRider used a compromised GitHub account to plant malware in four development versions of a Packagist package with 700,000+ downloads.

Security News
GitHub Actions now supports cache-mode, a least-privilege control on the Actions cache aimed at the cache poisoning technique behind recent compromises.