Audit: ./src/memory
Scope: 10 files audited for bugs, security vulnerabilities, and performance issues.
Date: 2026-06-22
Summary
The memory module is a well-structured, mostly clean codebase handling context loading, profile management, ephemeral memory expiration, and garbage collection. No critical security vulnerabilities or data loss risks found. The primary concerns are synchronous I/O blocking the event loop and a couple of minor bugs.
Findings
| File |
Type |
Severity |
Summary |
loadMemories.js |
bug |
medium |
TOCTOU race condition: fileExists() check followed by readFile() without try/catch — file could be deleted between check and read |
gc.js |
bug |
low |
Rate-limited response returns hourCalls: maxGcPerHour (the limit) instead of actual hourCalls count |
gc.js |
performance |
low |
Duplicate pruning logic at lines 26-32 and 51-57 — identical code blocks, second is redundant |
context.js |
performance |
low |
Uses readdirSync + readFileSync — blocks event loop on every context load |
reader.js |
performance |
low |
readFileSync blocks event loop for frontmatter parsing |
prompts.js |
performance |
low |
readFileSync blocks event loop for system prompt loading |
retention.js |
performance |
low |
All synchronous fs operations (readdirSync, statSync, unlinkSync) |
retention.js |
performance |
low |
enforceMaxEntries loads all file stats into memory at once — problematic with very large directories |
writer.js |
performance |
low |
writeFileSync blocks event loop |
writer.js |
bug |
low |
escapeYamlString only escapes \, ", \n — incomplete for YAML double-quoted scalars (missing tab, control chars) |
context.js |
code-smell |
low |
loadAndFormatProfile constructs path via join(fullPath, "..", "..", "memory", "context", "profile.md") — fragile, assumes specific directory nesting |
context.js |
code-smell |
low |
Bare catch blocks with no error logging |
Notes
- No security vulnerabilities found — no hardcoded secrets, XSS vectors, or injection risks
- No critical bugs — all issues are low/medium severity
- The module would benefit from async fs operations (
fs/promises) to avoid blocking the event loop, especially in a server context
- The TOCTOU race in
loadMemories.js is the most actionable finding — wrapping readFile in try/catch would eliminate it
Audit: ./src/memory
Scope: 10 files audited for bugs, security vulnerabilities, and performance issues.
Date: 2026-06-22
Summary
The memory module is a well-structured, mostly clean codebase handling context loading, profile management, ephemeral memory expiration, and garbage collection. No critical security vulnerabilities or data loss risks found. The primary concerns are synchronous I/O blocking the event loop and a couple of minor bugs.
Findings
loadMemories.jsfileExists()check followed byreadFile()without try/catch — file could be deleted between check and readgc.jshourCalls: maxGcPerHour(the limit) instead of actualhourCallscountgc.jscontext.jsreaddirSync+readFileSync— blocks event loop on every context loadreader.jsreadFileSyncblocks event loop for frontmatter parsingprompts.jsreadFileSyncblocks event loop for system prompt loadingretention.jsreaddirSync,statSync,unlinkSync)retention.jsenforceMaxEntriesloads all file stats into memory at once — problematic with very large directorieswriter.jswriteFileSyncblocks event loopwriter.jsescapeYamlStringonly escapes\,",\n— incomplete for YAML double-quoted scalars (missing tab, control chars)context.jsloadAndFormatProfileconstructs path viajoin(fullPath, "..", "..", "memory", "context", "profile.md")— fragile, assumes specific directory nestingcontext.jscatchblocks with no error loggingNotes
fs/promises) to avoid blocking the event loop, especially in a server contextloadMemories.jsis the most actionable finding — wrappingreadFilein try/catch would eliminate it