# Your AI assistant forgets everything between sessions — here's how I fixed that

> A colleague of mine built a system he calls Project Brains. The AI reads the context file first and starts every conversation already knowing what it needs to know. His core insight is that AI assistants become dramatically more useful when they have structured context to work from, not just raw files. So I built a system that captures those decisions automatically for my workflow, and makes them available in every future session.

_Published March 7, 2026 · https://marcioflorindo.com/blog-brain-system.html_

A colleague built a system he calls "Project Brains": per-project folders with a living `CONTEXT.md` at the center, covering status, stakeholders, decisions, and open questions, with supporting directories for artifacts, research, and meeting notes. The AI reads the context file first and starts every conversation already oriented. His core insight is that AI assistants become dramatically more useful when they have structured context to work from, not just raw files.

That idea stuck with me, but I kept running into a different problem. Not project context, but workflow context. The kind of knowledge that accumulates across sessions: which API endpoint actually works for date-filtered queries, how to name Git branches, what tone to use in documentation, where local data lives on disk. Every time I started a new session in [OpenCode](https://opencode.ai/), I was re-explaining decisions I had already made.

So I built a system that captures those decisions automatically and makes them available in every future session. I call the update command `/brain-update`, because the metaphor fits.

Here's where the two approaches diverge in practice:

| Aspect | Project Brains | This system |
|--------|---------------|-------------|
| Scope | Per-project | Per-user (cross-project) |
| Captures | Project state and decisions | Workflow knowledge and conventions |
| Maintenance | Manual (update after events) | Semi-automated (scan + propose + confirm) |
| Growth control | Discipline-based | Structural (cap, budget, age review) |
| AI access | Point AI to project folder | Auto-injected every session |

## The problem: session amnesia

AI coding assistants have no memory between sessions. This is fine when every conversation is self-contained, but it falls apart for ongoing work. As a technical writer I have a specific way of querying issue trackers, a preferred branch naming convention, a set of custom commands with their own quirks, and a collection of workarounds for tools that don't behave as documented.

OpenCode has a file called `AGENTS.md` that gets injected into every conversation; it's the closest thing to persistent memory. I use it to store role context, repository paths, tool preferences, and pointers to my custom commands. It works well for the basics.

But `AGENTS.md` has a scaling problem. Every decision I wanted to persist meant editing that file. After a few weeks, the file would get bloated, and long context files are counterproductive, as the AI has to process all of it every time, and the important bits get diluted by the less important bits. I needed a way to capture decisions without bloating the one file the AI reads on startup.

## What a "brain" looks like in my setup

The solution is a three-tier structure:

```
~/.config/opencode/
├── AGENTS.md                    # Tier 1: compact global context (~1,500 token budget)
└── decisions/
    ├── INDEX.md                 # Tier 2: one-line summary of every active decision
    ├── 2026-02-15-api-date-query-workaround.md
    ├── 2026-03-04-blog-tone-preferences.md
    ├── 2026-03-04-plugin-architecture.md
    ├── ... (20 decision files)
    └── archive/                 # Retired decisions
```

**Tier 1** is `AGENTS.md`. It has a strict token budget (around 1,500 tokens) and contains only the things the AI needs in every session: who I am, what repos I work in, what tools I use, and a pointer to the decision index. If something doesn't need to be in every conversation, it doesn't belong here.

**Tier 2** is `INDEX.md`, an auto-generated table with a one-line summary of every active decision. The AI reads this when it needs to check whether something has already been decided. It looks like this:

| Date | Decision | Category | Summary |
|------|----------|----------|---------|
| 2026-02-15 | **api-date-query-workaround** | workaround | Use the search endpoint with raw query syntax for date-filtered requests. |
| 2026-03-04 | **blog-tone-preferences** | preference | Blog posts should use invitational tone: "here's what worked for me." |

**Tier 3** is the individual decision files. Each one captures the context, the decision itself, what alternatives were considered, and how to revert it. Here's a real example:

```markdown
# Use search endpoint instead of list endpoint for date queries

**Date:** 2026-02-15
**Category:** workaround
**Applies to:** any command that queries issues by date

## Context
The list endpoint has a known issue where date-filtered queries return no results.

## Decision
Always use the search endpoint with raw query syntax for any request that filters by date.

## Alternatives considered
- List endpoint with `fromDate`/`toDate` parameters — returns empty results, do not use.

## Revert instructions
If the list endpoint's date filtering is fixed, switch back to it.
```

This is a workaround I discovered after wasting time debugging empty API responses. Without the decision file, every future session would risk using the broken endpoint and getting empty results. With it, the AI checks the index, sees the workaround exists, and uses the right approach without me having to say anything.

## The automated part: /brain-update

My colleague maintains his project brains manually ("update after significant events") and that works well for project-level context that changes after meetings and key decisions. But workflow decisions happen constantly, often as throwaway remarks in the middle of building something. "Use this API instead of that one." "Name branches this way." "Don't load skills during research." I was probably never going to remember to manually log all of these.

So I built a command that does it for me. `/brain-update` scans recent OpenCode sessions by querying the local SQLite database where session data is stored. It reads through user messages looking for decisions, conventions, workarounds, and discoveries. Then it applies a quality gate: every finding must pass at least one of three tests:

| Test | Question |
|------|----------|
| **Recurrence** | Will this affect future sessions? |
| **Action** | Does this change how we do something? |
| **Durability** | Still true in 3 months? |

Findings that fail all three get silently discarded. This is the part that matters the most to me, I think. After testing the command for a while, I realized there was a risk that the system would fill up with one-off observations and session-specific context that doesn't generalise. The gate keeps the signal-to-noise ratio high.

What survives the gate gets proposed as new decision files, updates to existing decisions, or, rarely, changes to `AGENTS.md` itself. The command shows me what it found and asks whether to write, pick selectively, or skip. It never writes without confirmation.

After writing, it regenerates `INDEX.md` automatically and updates a cache timestamp so the next run knows where to start scanning.

## The compaction hook

There's one more piece. OpenCode compacts long sessions to save context; it summarises the conversation so far and continues from the summary. The problem is that decisions discussed early in a session can get lost during compaction if the summary doesn't preserve them.

I wrote a small plugin (about 25 lines of TypeScript) that hooks into the compaction process and injects a single instruction: "If any decisions, conventions, or workarounds were discussed in this session, preserve them in the summary." That's it. The plugin doesn't extract decisions or write files. It just makes sure the compaction summary retains the raw material that `/brain-update` will later pick up.

## Growth controls

A decision log that grows without bounds eventually becomes as useless as no decision log at all. The system has several controls to prevent context rot:

- **Token budget on AGENTS.md**: Before proposing any addition, `/brain-update` runs a word count and warns if the change would exceed ~1,500 tokens. This forces decisions into their own files rather than inflating the global context.
- **Active decision cap**: At 30 decision files, the command stops and asks you to archive before continuing. At 25, it triggers housekeeping by flagging stale decisions by age.
- **Age-based review**: Workarounds and discoveries are flagged after 60 days (bugs get fixed, information changes). Conventions and preferences get a 90-day review period.
- **Archive, don't delete**: Old decisions move to `decisions/archive/` rather than being deleted. The reasoning trail is preserved, but the AI no longer loads them into active context.

Right now I have 20 active decisions. That feels about right: enough to be useful, few enough that the index is scannable.

## What I've learned

A few observations from building and using this over the past few weeks:

**Less is more, if it's structured.** Twenty well-formatted decision files with clear categories and revert instructions are worth more than a single massive context file with everything dumped in.

**Decision logs compound.** Every workaround I document now is a future session that doesn't waste time rediscovering it. If the AI knows all my preferences around writing documentation, I don't have to constantly tell it about them. Small individually, but it adds up.

**The quality gate matters more than you'd think.** My first version didn't have one. It captured everything, including things like "the user asked about X" and "we discussed option A vs B" that weren't actually decisions. The noise made the whole system less trustworthy. Adding the three-test gate was the single biggest improvement.

## Try it yourself

My system is self-bootstrapping. I don't need anything beyond OpenCode and a few markdown files. My suggestion is that you vibe code something similar. Here's the minimum to get started:

1. **Create `~/.config/opencode/AGENTS.md`** with your role context: who you are, what repos you work in, what tools you use. Keep it under 1,500 tokens.
2. **Create `~/.config/opencode/decisions/`** as an empty directory.
3. **Build a `/brain-update` command** that scans your recent sessions (OpenCode stores them in a local SQLite database at `~/.local/share/opencode/opencode.db`), extracts decisions from user messages, applies a quality gate, and proposes new decision files.

The command itself is a markdown file in `.opencode/commands/`; it's instructions for the AI, not compiled code. The AI does the scanning, extraction, and writing. You just review and confirm.

Run `/brain-update` after a few sessions of real work. See what it finds. The quality gate means it won't propose anything unless the decisions actually matter. And if it proposes something wrong, you just say "skip" and move on. Or if you find something you need to fine tune, just tell the AI and improve it.
