desktop[ library ]communitycoursesorbits / membership
<- back to librarymemory_
[ notebook ]2026-08-06

Active Brain: memory that watches the whole session

Active Brain: memory that watches the whole session

The count from my own bench this week: one memory system that only woke up on the first prompt, three coding seats that never got mid-session help, and zero useful interruptions when I was actually stuck.

Session start was solved. Mid-session was not.

I already had a Cortex: durable notes, indexed, recalled when a chat opens. That first pack is gold. Then the conversation moves. I pivot. I rephrase the same bug four times. I invent a fix that contradicts a decision from last month. The model has no idea any of that history exists, because nothing is watching after turn one.

So I designed Active Brain.

First prompt is boot. Active Brain is attention. Silence is the feature.

The goal, before the mechanism

The goal is not "more memory injected more often." The goal is fuller reasoning and more creative problem-solving while the session is live, without training me to ignore the system.

Every always-on inject I have tried dies the same death:

  • Context floods. The useful line is buried under nine mediocre ones.
  • Banner blindness. After three noisy turns I stop reading the banner.
  • Wrong moment. The model needed the past fix on turn twelve, not turn one.

Active Brain is attention with manners. It watches the session. It offers curated locations from the knowledge system only when the bar clears. Most of the time it says nothing.


What it offers (and what it refuses)

When it speaks, the surface is short and typed:

KindJob
Past fixWe solved this error shape before
AnalogousSame structure, different domain
ContradictsAn earlier decision says otherwise
TangentA dormant link worth testing

Each line carries a one-line why. Chunk handles point back into the knowledge system for depth. No essay in the chat. No second agent arguing with me.

Hard refuses:

  • No full context pack every turn
  • No writes into the knowledge store from the observer path
  • No inject into background worker sessions
  • No model call, embed, or store query on the hot path
  • No skip-lines, no "0 hits", no fire below the confidence floor

Silence is the default state. That is not a bug. That is the product.


Architecture: dumb hot path, smart off-thread

Prompt hook (every turn, boring)

  1. Kill switch off? Exit quiet.
  2. Is this a background worker session? Exit quiet.
  3. Read one small pre-built offer cache for this session.
  4. Check freshness (built within the last few turns / minutes).
  5. Check confidence, session budget, minimum gap, token ceiling.
  6. Print the offer, or print nothing.

Always fail closed to silence. Always cheap. Always exit clean so a broken watcher never wedges the chat.

Background daemon (all intelligence lives here)

Lifecycle: spawned when needed, singleton, self-exits after session idle, global kill file, liveness canary in a soak log (so silent death is detectable).

Loop:

  1. Tail the recent session exchange
  2. Embed recent turns (local) and update a session topic vector (EMA)
  3. Evaluate triggers
  4. On trigger, run retrieval + reason, then atomic-write the offer cache
  5. Log the would-fire decision

The knowledge store opens read-only from this path. Structural write-proofing, not hope.

Triggers: drift and stall

Drift. Cosine similarity between the current turn embedding and the session centroid falls below a threshold. New subtopic. Fresh retrieval pack.

Stall. The last N turns are all too similar. Stuck. Wander pack with a flow-repair guard: repeated similar user prompts can be rephrasing a demand, not stuckness. Do not "help" by derailing a human who is insisting.

Cooldown between candidate builds. Thresholds live in config per mode so soak can tune without code rewrites.

Retrieval as creativity mechanism

Multi-query retrieve with a small k. Score for sufficiency. Cap chunks per region. Force at least one chunk from outside the dominant region.

That forced cross-region collision is the creativity move. The model is not asked to "be more creative." The pack is built so the next thought has something foreign and load-bearing to collide with.

Tangent via a wander step is garnish: one wildcard per offer, never the engine. Session dedup so the same chunk is not re-offered until the FIFO window forgets it.

Offer format (skimmable)

[BRAIN - drift: new subtopic]
Past fix      id:4182  why: solved same error in mesh work
Analogous     id:9910  why: same shape, different domain
Contradicts   id:2201  why: earlier decision says otherwise
Tangent       id:5543  why: dormant link worth testing

Hard line cap. Bold anchors. No em dashes. Ids are recall handles for depth tools, not essays.


How I use it

I run one knowledge system behind the coding seats I type into. Cortex still handles boot. Active Brain is mid-session attention for the advisor seat.

When I pivot topics, drift should fire a pack from the new region. When I loop the same bug, stall should surface a past fix or a contradiction instead of letting the model invent a third wrong theory. When I am deep in one cluster, the forced outsider chunk is the creative jolt.

I do not want a second chat. I want a quiet colleague with good timing.


Phase 0: ship silence first

I am shipping Active Brain as log-only soak before any chat output.

The daemon runs fully. The hook evaluates gates and logs would_fire. Zero lines in the chat for days. The soak log is append-only JSONL with rotation. No per-turn writes into the knowledge store.

Pass gates that matter:

  1. Hook read stays fast; always exits clean; zero exceptions
  2. Zero writes into the knowledge store (structural read-only)
  3. Would-fire rate in a sane band of evaluated turns (not spam, not dead)
  4. Daemon liveness canary every cycle; no orphan process files
  5. I label a sample of would-fires myself. Pass only if most are useful. That is the only true usefulness metric. Proxy metrics (region match, non-null hypothesis rate) were killed in design as unmeasurable mush
  6. Transcript availability proven per seat. If a seat only exposes the user prompt, stall detection degrades and must be re-validated before print is enabled

Only after Phase 0 does anything print. Opt-in per mode first, then default-on with the kill switch still live. If the reasoner quality fails labels, ship triggers + retrieval without the reasoner. Ambition yields to measured usefulness.


How you can build your own

You do not need my harness. You need the contract.

1. Separate boot from attention

First-prompt inject is a library card. Mid-session attention is a different product. If you mash them into one always-on dump, you get flood and blindness.

2. Canonical notes, derived observer

Your notes and decisions stay in a store you already trust. The observer never owns that store. Read-only from the watcher path. Kill switch on the wall.

3. Precompute offers off the hot path

Background loop:

  • embed recent turns
  • maintain a session centroid
  • detect drift and stall
  • retrieve diverse memories (force one outsider)
  • write one-line reasons
  • atomic-write a tiny cache file

4. Make the prompt hook stupid

On each user prompt: read cache, check freshness + confidence + budget, print or silence. No search. No embed. No model. Fail closed.

5. Budget the seat

Per-session max offers. Minimum gap between offers. Token ceiling as a fraction of the window. Freshness TTL so a pivot does not print a pack built for the previous topic.

6. Default silence

No skip lines. No zero-hit banners. If the bar fails, print nothing. Silence trains trust. Noise trains scroll-past.

7. Log-only soak before print

Run for days. Log would-fire. Label samples yourself. Do not enable chat output until your own labels clear a hard bar (I use seventy percent useful on a sample of fifty). Your taste is the metric.

8. Guard the failure family

Singleton process with a lock. Logs not thrown away. Idle self-exit. Global kill file. Never let a silent orphan claim the seat. Worker sessions stay off the inject path entirely.

Starter shape (any stack)

notes/                  # your canonical durable notes
observer/
  daemon.py             # embed, trigger, retrieve, write cache
  hook.py               # read cache only; print or silence
  offer_cache/          # session-keyed tiny JSON
  soak.jsonl            # would_fire decisions
  KILL                  # presence = observer off

Wire hook.py to your harness prompt event. Wire daemon.py to transcript tail or prompt delta. Start with log-only. Label. Then print.


Design method (how this was locked)

Active Brain was designed with the same swarm discipline I use for hard systems work: independent discovery lenses, three competing approaches, adversarial judges, then a hybrid.

What survived:

  • Skeleton: async daemon + cache reader hook (intelligence off the hot path)
  • Triggers: drift and stall with flow-repair on stall
  • Engine: multi-region retrieve + one-line reasons, reasoner optional if labels fail

What died:

  • Full context packs per turn
  • Hot-path model calls
  • Proxy usefulness metrics without human labels
  • "Helpful" skip-lines when nothing fires

Kill-with-salvage again. The safe idea was "inject more memory." The useful idea was "watch, precompute, and mostly stay quiet."


Active Brain sits between Cortex and the live seat. Cortex stores and boots. Active Brain attends. Generative Memories expand what the store can learn from roads not taken.


Principle

First prompt is boot. Active Brain is attention. Silence is the feature.

If your memory only speaks when the chat opens, you built a library card. If it watches the whole session and mostly stays quiet, you built a collaborator with manners.

Build the watcher. Measure would-fire. Earn the right to speak.

[ comments ]

guests welcome. members show first in the list

no comments yet. start the thread_