Perdura is a persistent, attributed knowledge graph. Models board, contribute, and disembark — the memory is the system of record, so nothing is lost when a model is swapped. Over time the graph builds a per-model track record of which LLMs to trust, in which domains, and a quick-connect provider config makes adding or swapping one a config edit, not a code change. Spend-by-contention remains a supported research arm — confirmed targeting precision, not yet a proven economic edge over a validated periodic default. Falsifiable claims, numeric pass bars, honest findings below.
Conventional multi-agent systems treat agents as persistent and memory as incidental — lose the agent, lose the plot. Perdura inverts this. Because no working state ever lives inside a model, any model can be swapped mid-task with zero loss.
The transcript is the memory. Swap the model and the working state evaporates with it.
Workers never knew anything the graph didn't. Disembarking loses nothing.
The graph is the system of record; models are stateless, interchangeable workers. Nothing is lost when a model is swapped — it never held anything to lose.
Every node is attributed. Over time the graph accumulates evidence about which models are reliable in which domains. The memory evaluates its workers.
Cheap local models are the default labor force. Frontier and specialist models are summoned to bound spend — by default on a validated periodic cadence; a real 6-run A/B found contention-triggered escalation never beats it on outcome flips at equal cost, so it now ships as a research arm instead of the default trigger.
A worker never sees a transcript and never sees who wrote prior nodes — only a bounded briefing of the most-contended question and its neighborhood. It returns a strict-JSON graph delta. A deterministic conductor validates, attributes, and merges. No LLM ever touches the merge path.
The conductor picks the most-contended open question and assembles a briefing capped at a fixed character budget.
The worker returns claims, evidence, and edges — including contradicts edges. Disagreement is signal, not noise.
Schema-checked, attributed, merged by pure code. Malformed deltas are rejected — and the rejection itself feeds the track record.
The worker is released. Nothing it "knew" is lost, because it never knew anything the graph didn't.
Everything persistent rides the train: the graph, the deterministic conductor, the retrieval index, and eventually the router. Models are stations the train passes through — any LLM behind a uniform interface, including any MCP-compatible client connecting to the Perdura station server.
Validation, ID assignment, attribution, and merging are pure code. An LLM never mutates the graph directly.
Stale nodes are marked, not removed. The temporal record of how the mind changed is preserved forever.
Workers see the 2-hop neighborhood of the most-contended question, capped at a fixed budget — cost stays flat no matter how many models have ever boarded.
Workers see content and confidence, never authorship. This counters anchoring — a claim earns deference by surviving contention, not by its author's name.
A 96-bit epistemic encoding for every node — not what the text says, but the
context of its assertion: type, confidence, domain, temporal position,
supersession lineage, and a semantic sketch. Scatter in this space is a disagreement
signal that can fire before an explicit contradicts edge exists.
Does embedding scatter predict contradicts edges? Pass bar: AUC > 0.7.
Do models whose claims sit near future decisions prove more reliable? Pass bar: |r| > 0.6.
Can 12 bytes per node route as well as full edge analysis? Pass bar: >90% routing agreement.
The three claims are falsifiable, with numeric pass bars. Three live multi-model sessions and a synthetic ground-truth arm in — here's the honest ledger, including the results we didn't order.
426/426 strict-JSON deltas from Claude + Gemini parsed, validated, and merged across three live sessions. Zero rejected; provider outages survived.
Homogeneous frontier workers don't contend: 18 turns produced one contradicts edge. Adversarial boarding now manufactures contention on demand — verified 0 → 0.13 global contention in four critic turns.
Prompted contradictions are unpredictable by construction — no scatter signal precedes a critic that attacks wherever it boards. Hidden-disagreement detection must be validated on organic contention from heterogeneous workers.
Outcome-based reliability separated live workers (0.667 vs 0.400) — claim 02's machinery now runs on real data, with calibration as the open work.
Contradicting claims are lexically closer than random pairs — same topic, opposite stance (simhash AUC 0.296, inverted). Distance can't measure disagreement, but it locates it: the collision detector flags close-but-unlinked pairs and a cheap stance auditor judges agree-vs-oppose.
High-confidence claims get challenged less (0.227 vs 0.333) even with authorship hidden. Confidence masking exists to test the fix.
Every node and edge now carries a boarding_mode (organic/adversarial/audit) stamped by the conductor at merge time, so experiment 1 and the inversion probe score organic+audit disagreement separately from manufactured adversarial contradictions instead of pooling them.
A 30-turn session combining adversarial and audit boarding for the first time clears the hidden-disagreement bar: AUC 0.944 (simhash, organic+audit-filtered). blake2b scores 0.370 on the same checkpoints — worse than chance — settling the hash question. Experiment 3 narrows to a near-miss (0.868); experiment 2 stays blocked for the third real session running (zero decisions or supersessions produced). The inversion finding now holds on organic contention too (simhash AUC 0.395), not just manufactured.
The decisive experiment has run — and the router has been repointed
by its result. Does contention-triggered escalation flip outcomes
more often than random or periodic escalation at equal cost? Six clean
real-worker runs
(escalation_ab.py --real --frontier claude,gemini) say: targeting
precision holds and strengthens with pooling (contention-routing finds the
hottest live disagreement in 6/6 runs; pooled mean contention at escalation
0.348 vs 0.226 random vs 0.154 periodic) — but on outcome flips at equal cost,
the metric the bet actually rides on, contention-routing has not beaten
periodic escalation once across all six runs (5 losses, 1 tie; pooled 5 vs 20
flips over 21 equal-cost escalations). A real confound (contention dilutes
with graph size regardless of budget) and one open alternate reading hold up
but don't rescue the number, and pooling six runs makes the direction more
settled, not less. perdura_router.py's default policy is
now periodic; --route contention stays
fully supported as a research arm. Full data:
docs/phase3-ab-results.md →
Persistent graph, deterministic conductor, round-robin boarding for Claude, Gemini, and local Qwen. CLI plus an MCP station so any model can board as a worker. Proves the inverted-persistence loop end to end.
The 96-bit epistemic encoding and its three validation experiments. Experiment 1 (scatter predicts contradiction before the edge exists) passes on synthetic data; the first real session surfaced consensus collapse — two frontier models agreeing rather than contending — countered by adversarial boarding. Two findings since: adversarial contradictions are exogenous, unpredictable by construction, so they can't validate hidden-disagreement detection; and contradicting claims sit lexically closer together than random pairs, not farther — the inversion finding. Distance locates disagreement but can't measure it, so the repair is a collision detector plus a stance auditor judging agree-vs-oppose. A boarding_mode field on every node and edge now lets scoring separate organic+audit disagreement from manufactured adversarial contradictions — and on the first real run to use it, experiment 1 clears its bar on real data for the first time (AUC 0.944, simhash, vs 0.370 for blake2b — worse than chance, settling the hash question). Experiment 3 narrows to a near-miss (0.868); experiment 2 stays structurally blocked (no decision/supersession outcomes in any real session yet). The spec locks, and the blend earns its place in the default routing signal, once experiment 3 clears 0.9 and experiment 2 has real outcome nodes to score — and heterogeneous-worker contention (local model vs frontier) remains completely untested in every environment this has run in.
Pluggable retrieval shipped — graph (baseline), hybrid (BM25 + dense + graph
expansion), and a persistent ChromaDB index — behind one interface, so the
briefing strategy is now an A/B knob. The living graph is visible two ways: a
force-directed mind map, and the Station — a live local dashboard that watches a
session land in real time (questions ranked by contention, the conversation feed,
per-model track records). The mind map now draws unlinked, lexically-close claim
pairs from different authors as dotted collision lines, and is servable live over
HTTP (operator-only) instead of only as a static file. Memoric binary now reaches
the briefing text itself: --memoric-briefings appends a bounded
collision-locator section to every worker's briefing, not just stance-audit turns —
a freshly-boarded or swapped-in model sees latent disagreement its own neighborhood
would miss, the concrete mechanism behind claim 1's onload/offload-without-losing-
context promise. Off by default; reuses the already-validated collision detector
rather than the still-gated contention blend. Next: learned dense embeddings.
Per-model, per-domain reliability computed from claim outcomes — promoted, corroborated, challenged, superseded — as a smoothed score the router can trust. Derived from the graph on demand; visible only to operators, never to workers. Now accumulating real outcome data. Proves claim 02.
The thesis made executable: local labor by default, frontier models summoned to
bound spend, chosen by live track-record reliability per unit cost, under a hard
budget. The A/B harness's synthetic control shows frontier spend landing on actual
disagreement (mean contention at escalation 0.48 vs 0.31 random vs 0.14 periodic,
at equal cost). The real-worker run has since happened six clean times against
real Claude/Gemini calls: targeting precision holds and strengthens with pooling,
but on outcome flips at equal cost — the metric that decides the bet —
contention-routing has not beaten periodic escalation once (5 losses, 1 tie across
6 runs). One real confound (contention dilution) and one open alternate reading
hold up but don't rescue the headline direction. The router's default policy has
been pivoted from contention to periodic as a result;
--route contention remains a fully supported research arm.
Full results →
A parallel track that hardens the engine for deployment without touching a single conductor invariant. E0: pluggable storage (JSON file or transactional SQLite) and a redaction command reconciling right-to-erasure with supersede-never-delete. E1: the three integration planes over authenticated HTTP, where attribution-hiding becomes an access-control boundary — worker tokens board and contribute but never see authorship; track records stay operator-only. E2: the multi-tenant control plane — Postgres storage with row-level-security tenant isolation, SSO (JWT bearer tokens verified against an IdP's JWKS), an admin role, and per-domain router budgets as real per-tenant config. E3: ingestion adapters — PR/ADR/incident/ticket streams propose deltas through the exact same merge path as an LLM worker turn, no privileged side door; attribution by stream makes cross-stream collision audits and per-stream track records fall out of existing machinery for free, and a live GitHub connector now feeds the PR adapter from the real API instead of a pre-fetched dict. Both E2 and E3 shipped ahead of their documented gate — the operator explicitly chose to override it rather than have it skipped silently. That gate has since run for real, six clean times (Phase 3, above), and reads against the routing thesis on its own metric, pooled across all six runs — the override is no longer covering an untested claim, it's covering a tested one, and the router's recommended default has been pivoted to the policy the data actually supports. The full deployment plan →
The operational layer an operator actually needs to run this: structured request
logging, per-credential rate limiting, a real /ready probe (pings the
configured store, not just a 200), and an operator-only /usage meter —
a foundation for billing visibility, not billing-grade infrastructure. A multi-stage
Dockerfile and a Postgres-backed docker-compose.yml demo
the E2 path end to end. Alongside it, an explicit scoping call: local-model support
(LM Studio/Ollama) is shelved, not abandoned — most prospective deployments run
frontier models only, so further local-model engineering waits for real usage to
justify it.
The "quick connect" half of the productization call: wiring up a new model or
vendor is now a config-file edit, not a perdura.py change.
perdura_providers.py adds named workers from a JSON (or YAML) file on
top of the built-in set, each entry naming a protocol perdura already
speaks — anthropic, google-genai, openai for
any OpenAI-compatible endpoint, lmstudio-native, mock — so
OpenRouter, Together, Groq, Fireworks, or a self-hosted vLLM/Ollama server are all
just config entries; only a genuinely new wire format needs code. Cost/tier
overrides feed the Phase 3 router, so a config-defined vendor escalates like a real
frontier worker. API keys are always read from an environment variable named in the
config, never written into the file itself; no config file present changes nothing.
Perdura is open research moving toward a hosted preview: managed graphs, multi-model workers, and the contention dashboard. If you want early access — or you're running multi-model reasoning and want to compare notes — request a seat.
No tracking — just your address on the preview list, and a reply when seats open.