Skip to content

Layer 101 — Episodic Cortex (vault that talks back)#28

Draft
slavazeph-coder wants to merge 12 commits into
mainfrom
claude/integrate-twitter-content-89Gbd
Draft

Layer 101 — Episodic Cortex (vault that talks back)#28
slavazeph-coder wants to merge 12 commits into
mainfrom
claude/integrate-twitter-content-89Gbd

Conversation

@slavazeph-coder

@slavazeph-coder slavazeph-coder commented May 8, 2026

Copy link
Copy Markdown
Owner

Summary

Cannibalizes breferrari/obsidian-mind (taxonomy + lifecycle hooks pattern) and the @cyrilxbt "second brain" architecture (Daily Brief / Weekly Synthesis prompts), but BrainSNN-native: every capture flows through Layer 4 firewall + Layer 29 affect decoder + Layer 87 genre classifier before it lands, and the merged region heatmap drives the 3D cortex instead of filing into a folder.

The thesis from the cyrilXBT post — "a second brain that never talks back is not a second brain" — is the layer's job: make the vault push insights back.

Rounds shipped

Round 1 — core layer

  • data/episodicTaxonomy.js — 8 episodic categories with regex triggers + per-category brain-region affinity vectors.
  • utils/episodicRouter.js — orchestrates classifier + firewall + affect + genre → merged region overlay.
  • utils/episodicMemory.js — persistent log, MiniLM embeddings, cosine findSimilar, union-find mineClusters, dedup, pin, export/import bundle. Synthesis insights save back as first-class captures (kind: 'insight').
  • utils/episodicSynthesis.jsdailyBrief() + weeklySynthesis() with local + Gemma paths; falls back to local on Gemma error.
  • components/EpisodicCortexPanel.jsx — capture form + 8-category filter + timeline + brief/synth cards + warm-embeddings.
  • utils/episodicDream.js — every 4 dream cycles, STDP-reinforces edges around clustered captures.
  • 4 MCP tools.

Round 2 — capture-anywhere + vault-talks-back loop

  • Auto-brief scheduler (episodicAutoBrief.js) — Daily Brief unlocks at >20h + ≥3 fresh captures; Weekly Synthesis every 6.5d with ≥4 in 7d. Banner surfaces when ready.
  • Streak counter (episodicStreak.js) — UTC-day capture streak with longest + totalDays persistence.
  • Decision drift detector (episodicDrift.js) — finds older decision captures contradicted by newer notes (valence flip ≥0.45 or incident shadow). Merged into the Synthesis card with a distinct red drift style.
  • Deep-link contract (episodicDeepLink.js) — ?capture=<text>, ?capture-url=<url>, ?capture-title=<title>. Drag-and-drop bookmarklet generator.
  • Connection graph (EpisodicGraph.jsx) — canvas-rendered cluster wheels along a top arc + singletons row.
  • Voice capture — Layer 59's Web Speech session piped into the draft (Chrome/Edge/Safari).
  • OCR capture — Layer 58's Tesseract.js wired to a file picker with progress %.
  • CSS theme — gradient title, pill row, streak tile, autobrief banner, graph host, drift card.

Round 3 — Ask the Vault + agent surface parity

  • Ask the Vault (episodicAsk.js) — natural-language Q&A over captures. Embeds the question, runs cosine retrieval (with trigram fallback), composes a deterministic local answer, optionally upgrades through Gemma with a system prompt that forces grounding in the BrainSNN signals.
  • Pin sort — pinned captures float to the top of the timeline.
  • Graph node click → scroll-to-card with cyan flash ring.
  • Background auto-run — opt-in checkbox (brainsnn_episodic_autorun_v1). Brief fires 45s after it unlocks; synthesis 60s.
  • MCP: episodic_ask + episodic_drift + episodic_consolidate (the consolidate tool reuses applyEpisodicSTDP so an agent can rehearse the episodic graph into brain weights without waiting for Dream Mode).
  • Hotkey ep jumps to Layer 101.

Round 4 — similar reveal + privacy budget

  • ≈ similar toggle on every capture card runs findSimilar inline with clickable scroll-to navigation.
  • Privacy Budget (Layer 86) tags the 5 episodic localStorage keys.

Round 5 — backlinks via @mentions and shared URLs

  • findBacklinks — pure lexical graph from a capture's mentions + URLs (no [[wikilink]] syntax required, derived automatically).
  • The similar reveal now merges cosine hits (≈) with backlinks (↔) into one deduped list, hover-tooltips showing what's shared.

Why deeper than Obsidian

Obsidian / obsidian-mind Layer 101 — Episodic Cortex
Embeddings Plugin-required Default — MiniLM in-browser
Manipulation-aware No Layer 4 pressure score per capture
Affect-tagged No 12-affect Russell circumplex per capture
Brain-region mapping No Every capture lights up the 3D cortex
Idle consolidation Manual weekly review STDP rehearsal during Dream Mode
Connection physics Graph plugin Inter-region weight reinforcement
Q&A grounding Plugin Native Ask the Vault with BrainSNN signals
Auto-scheduling N8N (server) Browser-native auto-brief + auto-run
Agent integration Per-plugin 7 MCP tools out of the box
Decision drift Manual Detected from valence flips + incident shadows

Test plan

  • Drop captures into the panel, verify each lights up the 3D brain
  • Capture variants of all 8 categories, verify primary classification
  • Daily Brief with ≥3 captures renders connections + pattern + question
  • Weekly Synthesis with ≥4 captures renders thesis + contradictions + drifts + gaps + action
  • "Save as insight" round-trips back into the timeline
  • "Warm embeddings" loads MiniLM, then connections shift from trigram to cosine
  • Idle for 30s+ → Dream Mode → captures gain ◐N markers, brain weights drift
  • Ask the Vault returns top hits with click-to-scroll
  • ≈ similar reveal shows cosine + backlink matches deduped
  • Auto-brief banner surfaces when conditions met; auto-run toggle persists
  • Voice capture (Chrome/Edge): button turns red, transcript piped to draft
  • OCR capture: file picker → progress % → text + auto-title in draft
  • Bookmarklet: drag to bookmarks bar, run on any page → opens ?capture=…
  • Hotkey ep jumps to Layer 101 panel
  • MCP relay: all 7 episodic tools dispatch
  • Privacy Budget shows 5 episodic keys tagged with Layer 101
  • Build: vite build ✓ (922 modules, clean)
  • Export bundle → wipe → import bundle round-trips

File map

+ brainsnn-r3f-app/src/data/episodicTaxonomy.js
+ brainsnn-r3f-app/src/utils/episodicRouter.js
+ brainsnn-r3f-app/src/utils/episodicMemory.js
+ brainsnn-r3f-app/src/utils/episodicSynthesis.js
+ brainsnn-r3f-app/src/utils/episodicDream.js
+ brainsnn-r3f-app/src/utils/episodicAutoBrief.js
+ brainsnn-r3f-app/src/utils/episodicStreak.js
+ brainsnn-r3f-app/src/utils/episodicDrift.js
+ brainsnn-r3f-app/src/utils/episodicDeepLink.js
+ brainsnn-r3f-app/src/utils/episodicAsk.js
+ brainsnn-r3f-app/src/components/EpisodicCortexPanel.jsx
+ brainsnn-r3f-app/src/components/EpisodicGraph.jsx
~ brainsnn-r3f-app/src/App.jsx                # mount panel + dream coupling
~ brainsnn-r3f-app/src/utils/layerCatalog.js  # Layer 101 entry
~ brainsnn-r3f-app/src/utils/mcpBridge.js     # 7 MCP tools
~ brainsnn-r3f-app/src/utils/hotkeys.js       # 'ep' chord
~ brainsnn-r3f-app/src/utils/privacyBudget.js # 5 keys tagged
~ brainsnn-r3f-app/src/styles/global.css      # theme block
~ .ai-memory/MEMORY.md                        # Layer 101 records (rounds 1-3)

12 new files, 5 rounds, ~3700 lines total.

https://claude.ai/code/session_01V5jAHiMiD5biJm3MJKNPfr

claude added 12 commits May 8, 2026 01:20
Cannibalized from breferrari/obsidian-mind (taxonomy + lifecycle hooks)
and @cyrilxbt's "second brain" architecture (Daily Brief / Weekly
Synthesis prompts), but BrainSNN-native: every capture flows through
the Layer 4 firewall, Layer 29 affect decoder, and Layer 87 genre
classifier before landing — and the merged region heatmap drives the
3D cortex instead of just filing into a folder.

What ships:
- 8-category episodic taxonomy with regex triggers + per-category
  brain-region affinity (decision/insight/question/artifact/win/
  project/person/incident).
- routeCapture() pipeline + persistent episodic memory store with
  on-demand MiniLM embeddings (Layer 24), cosine findSimilar, and
  union-find cluster mining.
- Synthesis engine: dailyBrief() returns connections / pattern /
  question; weeklySynthesis() returns thesis / contradictions /
  knowledge gaps / one action. Local deterministic path uses the
  pre-computed BrainSNN signals; Gemma path layers a system prompt
  that forces the LLM to reference those signals; falls back on
  any error.
- EpisodicCortexPanel: capture form, 8-category filter pills,
  search, recent timeline, brief + synthesis cards, warm-embeddings
  button, export/import bundle, wipe.
- episodicDream.js subscribes to Layer 26's dream phase and every
  4 cycles runs consolidationPass over the last 30d of captures —
  STDP-reinforces every connectome edge touching the cluster's
  dominant region. Captures gain a ◐N consolidation counter.
- 4 new MCP tools (episodic_capture / episodic_brief /
  episodic_synthesis / episodic_list) so Claude Code / Codex
  agents on the WS relay can drive the layer programmatically.

Why deeper than Obsidian: connections aren't a graph plugin —
they are the physics of the cortex. Embedded out of the box,
manipulation-pressure-scored before they pollute the vault,
affect-tagged, region-mapped, and STDP-rehearsed during idle
Dream Mode.

https://claude.ai/code/session_01V5jAHiMiD5biJm3MJKNPfr
Adds the missing surfaces that turn the layer from a panel into a
loop:

- episodicAutoBrief.js — persisted scheduler. Daily Brief unlocks
  at >20h since last + ≥3 fresh captures; Weekly Synthesis at
  every 6.5d with ≥4 captures in 7d. Banner surfaces in the panel
  the moment conditions are met; recordBrief/recordSynthesis
  persist 12-deep history.
- episodicStreak.js — UTC-day capture streak with longest +
  totalDays persistence. Renders as a streak chip next to the
  Timeline header.
- episodicDrift.js — decision-drift detector. For every decision
  >3d old, finds newer captures with cosine ≥0.34 + valence flip
  ≥0.45 or incident shadow; ranks by similarity × |valence Δ|
  × log(daysApart). Merged into the Synthesis card under
  Contradictions with a distinct red "drift" card style.
- episodicDeepLink.js — ?capture / ?capture-url / ?capture-title
  URL contract + bookmarklet source. Panel consumes deep-link on
  mount, applies the capture to the brain, and strips the params
  from the URL bar. The "↗ Capture to BrainSNN" drag-target
  surfaces in the panel footer.
- EpisodicGraph.jsx — canvas connection graph. Cluster wheels
  along a top arc, singletons along the bottom row, hover-tooltip
  on each node, ResizeObserver-aware. Renders inline above the
  timeline.
- Voice capture (Layer 59 hook) — 🎙 button live-transcribes into
  the draft via Web Speech API; turns red while listening.
- OCR capture (Layer 58 hook) — ◳ image-pick opens Tesseract.js,
  progress % renders inline, extracted text + auto-title append
  to the draft.
- styles/global.css — full Episodic Cortex theme block (gradient
  title, pill row, streak tile, autobrief banner, graph host,
  drift card).

Build: 921 modules, clean.

https://claude.ai/code/session_01V5jAHiMiD5biJm3MJKNPfr
- episodicAsk.js — natural-language Q&A over captures. Embeds the
  question (MiniLM with trigram fallback), runs cosine retrieval,
  composes a deterministic local answer from the hits' categories
  + pressure + top hit. Optional Gemma upgrade with a system
  prompt that forces grounding in the retrieved captures and
  references the BrainSNN signals already attached to each.
- Panel: "Ask the vault" card with question input + answer +
  ranked clickable hits that scroll-to-capture in the timeline.
- Pin sort — pinned captures float to the top of the timeline.
- EpisodicGraph onNodeClick wired through; clicking a node now
  scrolls the matching capture card into view + flashes a cyan
  ring (same focusCapture helper).
- Background auto-run — opt-in checkbox in the autobrief banner;
  persists via brainsnn_episodic_autorun_v1. When on, brief/synth
  fire 45-60s after they unlock.
- MCP tools: episodic_ask, episodic_drift, episodic_consolidate.
  The consolidate tool reuses applyEpisodicSTDP so an agent can
  consolidate the episodic graph into the brain weights without
  waiting for idle Dream Mode.
- hotkeys.js — 'ep' chord jumps to Layer 101.

Build: 922 modules, clean.

https://claude.ai/code/session_01V5jAHiMiD5biJm3MJKNPfr
- CaptureCard gains a "≈ similar" toggle that runs findSimilar()
  inline and lists the top-3 matches as clickable scroll-to
  buttons. Uses MiniLM cosine when warm, trigram fallback
  otherwise.
- privacyBudget.js (Layer 86) — tag the 5 episodic localStorage
  keys (captures, embeddings cache, auto-brief schedule, streak,
  autorun toggle) so the Privacy Budget audit shows the bytes
  attributable to Layer 101.

Build: 922 modules, clean.

https://claude.ai/code/session_01V5jAHiMiD5biJm3MJKNPfr
- episodicMemory.findBacklinks(captureId): pure lexical graph
  derived from the routed capture's @mentions + URLs. Mirrors
  Obsidian's wikilink backlinks but built automatically — no
  manual [[link]] syntax.
- "≈ similar" reveal now merges cosine hits (≈) and backlinks (↔)
  into a single deduped list, with a hover-tooltip showing what
  link they share. Works without embeddings — pure URL/mention
  matching surfaces the graph immediately.

Build: clean.

https://claude.ai/code/session_01V5jAHiMiD5biJm3MJKNPfr
Defensive guards, perf gates, accessibility, and storage hygiene.
No new features.

Memory store:
- 50KB per-capture text cap + 200-char title cap, applied at addCapture
  and at importEpisodicBundle entry points.
- kind / source allowlists so only known values land on records.
- importEpisodicBundle now validates version + per-item shape (text,
  ts, id, hash). Returns {imported, rejected} so the panel can show
  partial-import telemetry.
- saveEmbeddings is debounced (8s) so a batch of captures doesn't
  serialize ~1MB on every addCapture.
- clearAllCaptures wipes the embeddings key synchronously rather
  than waiting for the debounce.
- localStorage quota errors now log a throttled console.warn instead
  of silently failing.
- lexicalJaccard caps trigram input at 4KB and consolidates around a
  single lexTrigrams helper to halve allocations on the fallback
  similarity path.

Synthesis:
- dailyBrief / weeklySynthesis wrap every section in try/catch so a
  single bad regex or malformed capture renders a partial brief
  instead of a blank one.
- localKnowledgeGaps caps orphan-candidate work to top-8 by pressure
  before calling findSimilar, so the worst case is O(8N) instead of
  O(N^2).

Router:
- collectEvidence + extractAll guard against zero-width regex matches
  with lastIndex bumps and a hard safety counter so a future regex
  bug can't infinite-loop the classifier.

Ask the Vault:
- 4KB cap on per-capture trigram input; embed failure logs and
  falls through to lexical instead of crashing.

Dream coupling:
- Subscribe callback wrapped in try/catch so a transient failure
  in consolidationPass / setState / markConsolidated doesn't tear
  down the dream subscription. Per-id markConsolidated is also
  guarded.

Panel:
- Voice session is stopped on panel unmount so the mic cannot stay
  hot if the panel is unmounted while listening.
- Auto-brief readiness now refreshes on a 60s interval so a panel
  left open across the cooldown window catches up without waiting
  for the next capture.
- role="status" / aria-live="polite" on the autobrief banner;
  role="tablist" + aria-selected on category filter chips;
  aria-pressed + aria-label on the voice button; richer aria-label
  on the connection graph.

Build: clean.

https://claude.ai/code/session_01V5jAHiMiD5biJm3MJKNPfr
- episodicPII.js: regex pass on every routeCapture for emails,
  phone numbers, common API-key prefixes (sk-, ghp_, github_pat_,
  xox-, AKIA, AIza, hf_, sk_live_/test_/pk_live_), SSN-shape, IPv4,
  and long base64-ish blobs (60+ chars, post URL strip). Conservative
  bias toward false positives — false negatives leak secrets.
- routeCapture exposes a compact pii summary {total, first, kinds}
  on every record so cards and stats can render without re-scanning.
- CaptureCard: red 🔒 PII chip with the first detected kind +
  hover-tooltip listing all detected kinds.
- captureStats includes withPII count; the timeline header shows
  "🔒 N flagged for PII" when any captures match.
- episodic_list MCP tool returns piiFlags per capture so agents can
  filter or refuse to forward sensitive content.
- redactPII helper exported for future inline redaction action.
- styles: focus-visible outline pass for every button / input /
  textarea / anchor inside the panel; aria-selected tab bolds;
  prefers-reduced-motion drops the card hover transition.

Build: clean.

https://claude.ai/code/session_01V5jAHiMiD5biJm3MJKNPfr
- rewriteCapture(id, text) in episodicMemory: replace a capture's
  text in-place and re-run routeCapture so classification, affect,
  regions, urls, mentions, hash, and pii summary stay consistent.
  Drops the stale embedding so the next retrieval re-embeds.
  Marks editedAt timestamp.
- Capture cards with PII flags get a "✂ redact" button that runs
  redactPII (typed placeholders <EMAIL_REDACTED>, <APIKEY_REDACTED>,
  etc) and rewrites the capture in place. Prompts confirmation
  because the original text is lost.
- tests/episodic.test.mjs — 16 smoke tests over the pure modules
  (episodicTaxonomy + episodicPII). Covers category structure,
  trigger firing on canonical phrases, PII detection across
  email/key/SSN/IP, empty-input + non-string defenses, hit caps,
  URL stripping, and redaction.
- package.json: `npm test` runs node --test against tests/*.test.mjs.

Build: clean. Tests: 16 pass / 0 fail.

https://claude.ai/code/session_01V5jAHiMiD5biJm3MJKNPfr
…e hint

- tests/episodicAutoBrief.test.mjs (12 tests): brief / synthesis
  trigger gates, fresh-capture filter, history persistence + cap,
  relative-timer formatting.
- tests/episodicStreak.test.mjs (13 tests): streak math edge cases —
  empty, single-today, multi-day consecutive, yesterday-grace, gap
  reset, multi-capture-same-day collapsing, longest persistence
  across calls, totalDays = distinct UTC days, label tier ladder.
- tests/_localStorage.mjs: in-memory shim so the auto-brief and
  streak modules run unmodified in node --test.
- npm test: 41 tests / 8 suites / 0 fail.

UX:
- Idle warmup — 12s after panel mount, if the user already has 5+
  captures, quietly initEmbeddings + ensureAllEmbeddings so the
  next Brief / Ask the Vault call uses cosine without the user
  pressing "Warm embeddings". Failures are silent; lexical
  fallback always works.
- Weak-signal hint — capture cards classified as `artifact` with
  score <0.18 (or 0 dominant categories) get an italic prompt to
  add a verb or @mention so the brain can place the note. Helps
  users learn how the classifier sees their writing.

Build: clean. Tests: 41 pass / 0 fail.

https://claude.ai/code/session_01V5jAHiMiD5biJm3MJKNPfr
- episodicSynthesis.callGemmaJson + episodicAsk.callGemmaAnswer
  now pass an AbortSignal.timeout (30s synthesis, 20s ask) so a
  hung Gemma request can no longer stall the brief or the Q&A
  forever. Falls through to the local path on abort.
- 4 new taxonomy tests: clusterFor mapping for each cluster,
  fallback for unknown ids, DEFAULT_REGIONS sum sanity, every
  category cluster id resolves.

Tests: 45 pass / 0 fail. Build clean.

https://claude.ai/code/session_01V5jAHiMiD5biJm3MJKNPfr
… tests

- Background auto-run timer now aborts the moment the user starts
  typing in the draft / title / ask boxes, so silent runs cannot
  interrupt active work. The 45s/60s clock restarts only after
  the inputs are clear.
- First-of-day capture pulse — handleCapture compares streak before
  and after addCapture; if today.current ticked up, render a 6-second
  green banner ("🌱 Streak started" or "🔥 N-day streak — kept alive")
  with the longest streak as a side note. Pure local state, no toast
  plumbing required.
- 5 more PII tests: GitHub PAT, AWS access key, Stripe live secret,
  North American phone formats, multi-kind total.

Tests: 50 pass / 0 fail. Build clean.

https://claude.ai/code/session_01V5jAHiMiD5biJm3MJKNPfr
- rewriteCapture now keeps the last 2 prior versions in priorTexts
  with timestamps, so a redact / re-route can be inspected. The
  orphan embedding for the previous hash is also dropped from the
  cache so rewrites don't accumulate dead vectors.
- MCP episodic_warm: agents can now request a MiniLM init +
  embed-all pass via the bridge (previously only a manual button
  in the panel). Returns {wasReady, readyNow, ok, done, total} so
  the agent can confirm the cache is warm before issuing
  episodic_ask / episodic_brief.

Build clean. Tests: 50 pass / 0 fail.

https://claude.ai/code/session_01V5jAHiMiD5biJm3MJKNPfr
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants