/ brain-report / brain-whitepaper
White paper · v1.0

A self-correcting personal memory system for one operator with real money on the line.

The Volia Brain is a local-first knowledge layer that ingests, embeds, decays, and counterfactually audits its own beliefs. It runs on a 30B-parameter local LLM, holds a Bayesian α/β posterior on every claim, scores its own forecasts with Brier loss, and vetoes real trades on a $40 live wallet when fresh evidence contradicts a strategy. This document explains how it is built, what works today, and what does not.

v1.0 · last updated 2026-05-01 Read time ~15 min Investor & engineer-readable → comparison report → live status

01Abstract

Personal-knowledge tools optimise for capture. The Volia Brain optimises for being wrong less often.

It is a single-operator memory system built around a vault of 457 markdown notes, indexed as 550 embedding chunks in a local sqlite-vec store, with a parallel Bayesian claim ledger (322 open claims across 15 domains) that tracks belief strength with per-domain time decay. Auto-promotion of new findings is gated by a CoIn-style counterfactual abduction loop modelled after arXiv:2502.11008. The brain seeds its own falsifiable predictions and grades them with Brier loss. It tails the JSONL output of two real-money trading bots and writes approve/warn/veto verdicts in real time, with five hard gates between paper and live.

The differentiator is not the stack. It is that every claim, every forecast, and every trade verdict is auditable, and a wrong one is recorded as a kill, not buried. The KILL_LIST.md file has 11 dead strategies on it. That is a feature.

02Motivation

Notion AI, Mem, and the long tail of "second brain" SaaS products solve a different problem. They are capture and recall layers for knowledge workers whose worst-case outcome is forgetting an idea. The operator behind this system has a different worst case: re-running a strategy that already cost him money. Three months of runway. A live wallet. A father who manages other people's capital. Forgetting is not the bottleneck — re-believing is.

The systems we evaluated all share one structural failure: they treat older notes the same as fresher ones, and they have no way to mark a belief as disproven. Obsidian is a filing cabinet. Claude's hosted memory is opaque, lossy, and resets often enough that we do not trust it for anything load-bearing. Mem ranks by recency and tags. None of them ask the question that matters: "is this claim still supported by fresh evidence?"

We built the brain because the alternative was watching a notes app politely re-suggest the BTC anti-correlation hypothesis we had already killed three times.

03System overview

The brain is structured as a unidirectional pipeline from raw capture to acted-on verdict. Every box is a real subsystem with a real file path. Nothing in this diagram is forward-looking.

CAPTURE INDEX REASON ACT Vault filesystem ~/vault/**.md · 457 files Drop-zone & voice Desktop/brain-inbox · launchd Bot history.jsonl delta_sniper · sniper · meme Edit attribution Claude Edit/Write hook RSS · X · iMessage brain-ingest/* crons sqlite-vec · index.db 550 chunks · 768-dim nomic-embed-text Claim ledger · claims 322 claims · α/β half-life by domain Edit / verdict logs edit_log · verdicts.db RAG & distillation qwen3-coder:30b · deepseek-r1:8b CoIn counterfactual gate 3-CF abduction · plausibility ≥7 = HOLD Cross-domain promote cosine ≥0.85 · ≥3 sources Brier scorer held-out predictions · weekly Bot oversight veto 5 gates · ≥60% acc · ≥50 verdicts paper / live (env-gated) PERMANENT_FINDINGS 12 entries · canonical truth KILL_LIST 11 dead strategies + post-mortems DPO / LoRA dataset weekly mlx_lm fine-tune verdict outcomes feed back into claim α/β
Volia Brain · v1.0 · all paths verified 2026-05-01

Capture is multi-channel. Reasoning happens locally on Apple Silicon via Ollama. Action is gated. The only outbound network calls during reasoning are optional — the entire memory + retrieval + promotion pipeline runs offline. This is a deliberate constraint, not a marketing line: the operator's cost ceiling for the brain is zero per inference, because the alternative is paying API rates for every re-read of the same vault.

04Memory & retrieval

Vault on disk is the source of truth. The index is a derived view that can be rebuilt from scratch in under a minute.

Storage layout

The vault sits at /Users/neo/vault/ and is organised by purpose, not topic:

  • memory/ — canonical long-term memory. Includes PERMANENT_FINDINGS.md (137 lines · 12 entries), KILL_LIST.md (98 lines · 11 dead strategies), HYPOTHESES_ACTIVE.md (4 active strategies, each with explicit kill and double-down criteria).
  • live/ — auto-refreshed state. NOW.md, BOT_STATUS.md, DECAYED_BELIEFS.md, BRAIN_PREDICTIONS.md, BRAIN_VERDICTS.md. Scripts rewrite these. Manual edits are overwritten.
  • learning/ — distilled web/agent captures, organised by domain (polymarket/, crypto/, security-pentest/, stocks/, business-dropshipping/, etc.).
  • hypotheses/ — one file per testable idea, each with a kill-criterion in frontmatter.

Ingestion

Five capture channels feed the vault: a launchd-watched drop zone at ~/Desktop/brain-inbox/ that auto-distills any URL, PDF, or text file in under 30 seconds; voice memos via the com.neo.brain.daemon plist; bot trade logs from a London VPS; an edit-attribution hook that records every Claude Code Edit/Write as a structured decision in edit_log (190 rows as of writing); and content crons for RSS, X/Twitter, iMessage, and calendar (40+ entries in crontab).

Embedding & retrieval

Embeddings are computed by nomic-embed-text (768-dim, served by local Ollama). Vectors are stored as raw BLOB columns in a single sqlite-vec database at brain-system/index.db. The schema is intentionally minimal:

CREATE TABLE memories (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  path TEXT NOT NULL,
  namespace TEXT,
  type TEXT,
  title TEXT,
  content TEXT,
  chunk_idx INTEGER DEFAULT 0,
  mtime REAL,
  embedded_at REAL,
  embedding BLOB,
  UNIQUE(path, chunk_idx)
);

Retrieval is hybrid. A query is embedded, then cosine-scored against all 550 chunks; the top-k are re-ranked by (cosine × effective_confidence × recency). The implementation lives in brain-system/cmd/ask.py. There is no external vector DB and no Pinecone bill.

Distillation

Two local models split the work. qwen3-coder:30b (DISTILL_MODEL) handles long-context summarisation and PERMANENT_FINDING synthesis. deepseek-r1:8b (FAST_MODEL) handles low-latency reasoning, including the counterfactual gate. Both run on-device; no per-token cost.

05Confidence & decay

A claim is not a string. It is a Beta posterior over a yes/no question, with a half-life.

Every memory file is parsed for a canonical claim sentence (frontmatter claim: field, else the H1 of the body). The sentence is normalised, SHA-256 fingerprinted, and stored in the claims table with α=1, β=1 prior plus +1 successful evidence. Subsequent observations of the same fingerprint update α (positive) or β (if the source frontmatter says evidence_polarity: negative). The math, in brain-system/lib/core.py:

# effective_confidence = decayed mean of Beta(α, β)
f = exp(-Δdays / half_life_days)
# Pull α and β toward the prior (1,1) by f
α' = 1 + f·(α - 1)
β' = 1 + f·(β - 1)
return α' / (α' + β')

Half-lives are per domain, not global, because a polymarket regime read decays much faster than a security-engineering fact:

DomainHalf-life (days)Open claims
polymarket1413
crypto3033
security-pentest6038
stocks9013
general (default)9054
business-dropshipping12015
software-engineering1809
dashboards-websites1805

A nightly Bayesian backfill (brain bayes, run by cron at 04:00 CT) walks every file modified in the last 24h, fingerprints the claim, and updates α/β. A weekly decay pass (brain decay, Sunday 04:00) writes live/DECAYED_BELIEFS.md for any claim whose effective confidence has fallen below 0.35. As of 2026-05-01 there are 22 decayed beliefs queued for review.

Concrete example. The "BTC anti-correlation" hypothesis (trade opposite the crowd) contributed to the 2026-03-24 → 03-27 drawdown. When the underlying API contamination was discovered — Polymarket's ?asset_id= endpoint was returning all markets mixed (NBA, Biden, crypto) instead of just the requested one — the hypothesis was added to KILL_LIST.md with the post-mortem "Root cause: contaminated API data. Once ?market= fix landed the signal vanished. Finding was an artefact." The original claim's α/β posterior collapsed; the kill entry preserves the lesson permanently. This is the loop the brain exists to run.

06Cross-domain learning & the counterfactual gate

Once individual claims are scored, the brain looks for clusters of corroborating evidence that justify promoting a finding to the canonical PERMANENT_FINDINGS.md file. Promotion is a two-stage gate.

Stage 1 — clustering

brain-system/cmd/promote_cross.py computes pairwise cosine similarity over all first-chunk embeddings of vault/learning/* and vault/memory/*. Any cluster with ≥3 memories AND ≥3 distinct source URLs at cosine ≥ 0.85 is a candidate. The threshold is an explicit constant COSINE_THRESHOLD = 0.85. We have observed real clusters of seven sources at this threshold (e.g. the BTC 5-minute latency-arb cluster promoted 2026-04-29). We have not yet lowered the threshold experimentally — that is on the roadmap (§12).

Stage 2 — counterfactual abduction (CoIn)

Correlation is not enough. The brain-system/cmd/promote_counterfactual.py module implements a CoIn-style abduction loop modelled after arXiv:2502.11008 (CounterBench). Reported baseline: even o3 hovers near 50% on counterfactual reasoning; CoIn-style abduction loops raise that to ~89.9%.

Before promotion, the brain runs two cheap structural checks on the cluster:

  1. Source diversity. Reject if >50% of source URLs share a domain (echo chamber), or if <2 distinct source-types appear (e.g. all 7 are tweets). The thresholds are DOMAIN_DIVERSITY_MAX_RATIO = 0.5 and MIN_SOURCE_TYPES = 2.
  2. LLM abduction. Pass the cluster to deepseek-r1:8b with a structured prompt: "generate 3 counterfactuals where this cluster could exist even if the claim is false, rate plausibility 0–10." If max plausibility ≥ 7, the gate returns HOLD and writes the concern to live/INBOX.md; the finding is not auto-promoted.

The synthetic test case shipped in the codebase reconstructs the contaminated ?asset_id= cluster from March: 5 memories, all citing the same broken Polymarket endpoint, all reporting "BTC crowd anti-correlation" with high confidence. The diversity check alone catches it (single domain, single source-type) — no LLM call required. This is the failure mode the gate was designed for, and it caught the historical case retroactively.

Two of the auto-promoted findings in PERMANENT_FINDINGS.md currently carry an explicit [REVIEW: counterfactual concern …] annotation, written by the audit pass: the BTC latency-arb cluster (7 sources but all from astralcodexten.com) and the dropshipping supplier-vetting cluster (2 of 3 sources from oberlo.com). The brain flagged both as domain monoculture after promotion. The annotations are advisory; the audit does not delete or rewrite the claim.

Honest note on the cosine threshold. The original design contemplated lowering the cosine threshold from 0.85 to 0.65 after observing an empirical cluster maximum near 0.798, which would surface dozens more cross-domain pairs. That change is not in the live code. The current COSINE_THRESHOLD = 0.85 still fires, just sparingly. We will not characterise an unshipped change as shipped.

07Calibration via Brier scoring

A second brain that does not grade itself is a diary wearing a lab coat.

Once a week, the brain seeds 10 falsifiable predictions drawn from its own canonical findings. Each one takes the shape "By date D, will fresh evidence in the brain still support claim C?" with a stated confidence between 0 and 1. The predictions live in live/BRAIN_PREDICTIONS.md, are managed by brain-system/cmd/brain_brier.py, and are resolved automatically by a daily cron (0 4 * * *) that re-checks fresh evidence for each open prediction.

Resolved predictions are scored with the standard Brier loss BS = (p − o)2 where o ∈ {0, 1}, then bucketed by stated confidence for calibration. Current state, dated 2026-05-01:

7
predictions resolved
7
predictions open
0.491
Brier score (overall)
Confidence binNMean statedActual yes-rate
0.5–0.620.5960.0
0.6–0.710.6230.0
0.8–0.930.8820.0
0.9–1.010.9281.0

The headline reading: at this tiny sample (N=7) the brain has been systematically over-confident. Three predictions in the 0.8–0.9 band all resolved no. One in the 0.9+ band resolved correctly. Brier 0.491 is barely better than chance (0.25 = perfect random forecaster on 50/50 events). We are publishing this not because it is good but because it is the truth, and the existence of the table is the point. A notes app cannot show this graph because it has nothing to compare a forecast to.

With weekly seeding (10 new predictions every Sunday), the held-out set will reach N≈50 by mid-June, which is the first sample size at which calibration claims start to mean anything. We will publish the same table at every order of magnitude.

08Trade oversight — the brain in the trade loop

The most aggressive thing the brain does is veto real money. Two trading bots — delta_sniper and sniper — each emit a JSON event to history.jsonl on every entry. A tailer process pipes those events into brain-system/cmd/bot_oversight.py, which embeds the event, runs vector retrieval over PERMANENT_FINDINGS + KILL_LIST, asks deepseek-r1:8b for a verdict, and writes the result to verdicts.db + live/BRAIN_VERDICTS.md. Verdicts are one of approve / warn / veto, with a confidence and cited memory slugs.

Five gates between paper and live

Live mode does not flip with a config toggle. It requires all of the following:

  1. Environment variable BRAIN_OVERSIGHT_LIVE=1 set in the launchd plist (not just shell).
  2. Bot id present in the whitelist file /Users/neo/vault/config/brain-oversight-live-bots.txt.
  3. Last 50 verdicts show ≥60% accuracy against bot trade outcomes.
  4. Per-bot dollar cap on any single veto (default $5, env-overridable).
  5. Bot scope is hard-coded: only delta_sniper and sniper; unknown ids raise.

If any gate fails, the system falls back to paper for that event. Code reference: MIN_LIVE_ACCURACY = 0.60, LIVE_ACCURACY_WINDOW = 50, ALLOWED_BOTS = {"delta_sniper", "sniper"}.

The system catching its own failure

Between 2026-04-25 and 2026-05-01 the oversight tailers were silently broken with ModuleNotFoundError: No module named 'brain_system'. The veto path was non-functional for six days. This was discovered not by the operator but by the brain oversight audit cron at 23:00 CT, which flags discrepancies between the bots' history.jsonl and the verdicts table. That is the system working. A blind veto would have been worse than no veto — silent failure caught by an automated audit is exactly what we instrumented for.

The verdict log itself is currently small — 2 verdicts in verdicts.db, 0 with a resolved outcome. The pipeline is freshly back online as of 2026-05-01 with the live-mode flip. The honest summary: this is the lowest-N, highest-stakes part of the brain. Every claim about its accuracy is conditional on the next 50 verdicts.

09Self-healing hooks

Anything that runs on every Claude Code invocation — distillation, edit attribution, identity injection — is wrapped in the @hook_safe(name) decorator from brain-system/lib/hook_safe.py. The decorator does three things:

  1. Crash isolation. The hook's main() always returns an int and never raises. A traceback is logged to live/HOOK_CRASHES.md.
  2. Lock TTL. A lock file prevents concurrent invocations. LOCK_TTL_SECONDS = 24·3600 means a 24-hour-old lock self-heals on the next call.
  3. Auto-disable on repeated crash. A daily watchdog (brain-system/cmd/hook_watchdog.py, 11:00 CT) clears stale locks and disables hooks that have crashed repeatedly within 24 hours. The hook quietly comes back online the next day after the cooldown.

This is unglamorous, but it is the difference between a hook system that works for one week and one that works for a year. live/HOOK_CRASHES.md currently logs three entries from a deliberate crash test on 2026-04-30 (the test verified the decorator caught and recorded the synthetic RuntimeError).

Eight launchd plists live under ~/Library/LaunchAgents/com.neo.brain*: brain.daemon, brain-capture, brain-maintenance, brain-morning-play, brain-oversight, brain-pr-watcher, brain-study, brain-sync, brain-tunnel. Plus 71 cron entries spread across distinct minutes to avoid Ollama queue contention.

10Evidence to date

Numbers below are pulled fresh from the brain's own indexes on 2026-05-01:

457
markdown files in vault
550
embedding chunks indexed
322
tracked claims (α/β)
15
domains with claims
12
PERMANENT_FINDINGS entries
11
KILL_LIST entries (post-mortems)
4
active hypotheses (with kill criteria)
22
currently decayed beliefs
190
attributed code edits
7 / 7
Brier predictions (resolved / open)
71
brain cron jobs
8
brain launchd daemons

Two real-world cases the brain has caught:

  • Cap operator bug. direction_entry_caps compared with > instead of >=, allowing $0.81 fills under a $0.80 cap. Three losing entries (one ETH-UP -$29.16). Surfaced via the edit-attribution hook + post-mortem in PERMANENT_FINDINGS.md §2; fixed 2026-04-22.
  • Wrong wallet, wrong strategy. Last 500 trades of the elite wallet we were copying (0xce2f…) are 497 BUYs / 3 SELLs with 96% in $0.40–$0.65. Our bot was filling 45% above $0.75 — buying their exit liquidity. Captured as PERMANENT_FINDINGS §4, killed the structure of the v1 sniper.

11Limits & open problems

We are unsentimental about what does not yet work.

  • Brier sample is too small to mean anything. N=7 resolved is below any calibration-statistics floor. The 0.491 score and the 0/3 result in the 0.8–0.9 bin are not yet actionable; we publish them only because hiding them would defeat the purpose. Expect the first meaningful read at N≈50 (~mid-June).
  • LoRA fine-tune has not shipped a beneficial adapter. The pipeline is wired (brain-system/lora/): lora-prepare-dataset.sh at 23:00 CT builds a DPO JSONL from KILL_LIST/PERMANENT_FINDINGS preference pairs; lora-train.sh runs mlx_lm 0.31.3 on Sundays at 21:00 CT into lora/adapters/<ISO-week>/. As of 2026-05-01, lora/adapters/ is empty and the most recent dataset (dpo-2026-W18.dryrun.jsonl, 13.7KB) is a dry-run. No adapter has been promoted to active yet because we have not validated that any of them improves task-specific outputs vs. the base model.
  • Persona drift detection has zero ground truth. The pipeline samples Claude outputs daily and compares them to a baseline persona, but we have not yet established what "drifted" means quantitatively. Currently advisory only.
  • Cross-domain promotion has fired sparingly. Two clusters auto-promoted in 2026-04 at the 0.85 threshold; both received [REVIEW: counterfactual concern] annotations for source-domain monoculture. Lowering the threshold to surface more pairs is on the roadmap but has not been validated against false-positive rate.
  • Mobile UX of the live /brain graph is poor. The force-directed graph at /brain renders 1626 nodes / 610+ edges and is unreadable on a phone. Rebuild is in progress.
  • The vault can become the work. The blueprint at vault/memory/BRAIN_BLUEPRINT.md is explicit about this: every brain feature must justify itself in dollars-saved or decisions-clarified inside 30 days, or it gets deleted. Two skills have already been removed under that rule.

12Roadmap

Next 7 days

  • Fix the brain_system import path so oversight tailers stop silently failing on the VPS.
  • Get the next 50 oversight verdicts in (paper mode) so the live-flip accuracy gate has a real sample.
  • Ship one DPO-trained LoRA adapter and A/B-test it against the base model on a held-out set of 30 prompts.

Next 30 days

  • Lower the cross-domain cosine threshold experimentally to 0.65, measure false-positive rate against the counterfactual gate's HOLD output.
  • Reach Brier sample N≈50; publish the calibration table at that order of magnitude.
  • Rebuild /brain graph with a mobile-first physics tier (≤200 visible nodes on phone).

Next 90 days

  • Open the schema. Ship a self-host kit so other one-operator funds and trading shops can run their own brain. Same primitives, separate vault.
  • Train a persona-drift classifier on 90 days of session transcripts; replace the advisory pipeline.
  • Expand bot oversight from 2 bots to the full set of 4 active strategies, with per-bot whitelists and per-bot dollar caps.

13Glossary

RAGRetrieval-Augmented Generation. Fetch relevant chunks from a vector index, paste them into an LLM prompt, then generate.
CoInCounterfactual abduction loop (after CounterBench, arXiv:2502.11008). Generate plausible counterfactuals where the cluster could exist even if the claim is false; if any are plausible, hold promotion.
α / β posteriorBayesian Beta distribution over the truth of a claim. α counts confirming observations, β counts disconfirming. The mean α/(α+β) is the brain's current belief; we apply per-domain time decay before reading it.
Brier scoreMean squared error between stated probability and observed outcome (0 or 1). 0 = perfect, 0.25 = chance on 50/50 events, 1.0 = maximally wrong. The standard scoring rule for forecasters.
DPODirect Preference Optimisation. Train on (preferred, rejected) pairs without an explicit reward model. We synthesise pairs from KILL_LIST (rejected) and PERMANENT_FINDINGS (preferred).
LoRALow-Rank Adaptation. Tune a small adapter on top of a frozen base model. Cheap, reversible, swappable. Our base is qwen3-coder:30b.
Edit attributionA Claude Code post-tool hook that records every Edit/Write as a structured row in edit_log with file path, byte delta, before/after SHA, snippet, and session id.
Veto / approve / warnThree-state output of the bot oversight pipeline. Veto blocks the trade in live mode; warn logs a concern; approve is the no-op default.
Kill criterionA pre-committed threshold ("if WR < X over N trades, abandon") attached to every active hypothesis. Forces the strategy to be falsifiable before it is deployed.