In the previous chapter, Gating Logic, we established the rules for when the AI should "dream." One of the most important rules was the Session Gate: "Have enough new conversations happened?"
But how does the system actually count "new" conversations without reading everything from scratch? This process is called Session Discovery.
Imagine you are a mail clerk. You processed all the outgoing mail yesterday at 5:00 PM. Today, you need to check if there is enough mail to warrant a trip to the post office.
Session Discovery uses the "Fast Way." It scans the file system to find conversation transcripts that have changed since the last time the AI organized its memory.
To understand how we discover sessions, we need to understand three simple concepts:
sinceMs): The exact moment (in milliseconds) the last dream finished. This is our "5:00 PM yesterday."mtime) against the Baseline.Here is how the system decides which files are "new" and need processing.
The code for this logic lives in consolidationLock.ts. Even though the file is named "Lock," it also handles the utilities for checking timestamps.
Let's look at the function listSessionsTouchedSince. We will break it down into small steps.
First, we need to know which folder holds the conversation history.
import { getProjectDir } from '../../utils/sessionStorage.js'
import { getOriginalCwd } from '../../bootstrap/state.js'
// Get the directory where transcripts are saved
const dir = getProjectDir(getOriginalCwd())
Explanation: getOriginalCwd() finds the root of your project, and getProjectDir adds the path to the hidden .aide folder where transcripts live.
Next, we ask the file system for a list of all files in that directory.
import { listCandidates } from '../../utils/listSessionsImpl.js'
// Get a list of all session files with their stats (metadata)
// The 'true' argument tells it to fetch timestamps
const candidates = await listCandidates(dir, true)
Explanation: listCandidates does the heavy lifting. It returns an object for every file that includes its sessionId and its mtime (modification time).
This is the most critical part. We filter the list using simple math.
// Filter: Keep only files modified AFTER 'sinceMs'
// 'sinceMs' is the timestamp passed into the function
const newSessions = candidates.filter(c => c.mtime > sinceMs)
Explanation:
c.mtime is bigger than sinceMs, the file is newer. We keep it.c.mtime is smaller, the file is older. We ignore it.Finally, we just return the list of IDs (names) of the sessions we found.
// Extract just the IDs
return newSessions.map(c => c.sessionId)
When we combine those steps, we get the actual function used in the codebase:
export async function listSessionsTouchedSince(
sinceMs: number,
): Promise<string[]> {
const dir = getProjectDir(getOriginalCwd())
const candidates = await listCandidates(dir, true)
// Return IDs of files modified after the cutoff time
return candidates.filter(c => c.mtime > sinceMs).map(c => c.sessionId)
}
There is one tricky detail. The session you are currently using is also a file on the disk. Every time you type a message, that file gets updated.
Technically, the current session is "new" (modified just now). But we don't want to organize it yet because the conversation isn't finished! It's like trying to wash the clothes you are currently wearing.
In autoDream.ts, we handle this by explicitly removing the current session from the list:
// Inside autoDream.ts...
// Get the list of new files
let sessionIds = await listSessionsTouchedSince(lastAt)
// Get the ID of the session we are currently in
const currentSession = getSessionId()
// Filter it out!
sessionIds = sessionIds.filter(id => id !== currentSession)
This "Session Discovery" mechanism is what makes Auto-Dream lightweight.
Instead of reading megabytes of text history every time you press Enter, the system only does two cheap things:
Only when these cheap checks pass does it actually spin up the expensive AI process.
We now know when to run (Gating Logic) and what to process (Session Discovery).
However, there is still a major safety risk. What if two different "Night Watchmen" try to organize the files at the exact same time? They might overwrite each other's work!
To prevent this, we need a locking mechanism.
Next Chapter: Consolidation Lock & Timestamp
Generated by Code IQ