Memory as File
August 5, 2026 · View on GitHub
ReMe's core idea is Memory as File, File as Memory.
Memory as File: long-term memory is not hidden in a black-box database. It lives in Markdown files, resource files, and index snapshots under the workspace. Users and agents can directly read, write, move, and delete those files.
File as Memory: each file is more than ordinary text. It is an indexable, linkable, and evolvable memory node. ReMe parses frontmatter, body chunks, and wikilink edges from files and organizes them into retrieval indexes and a graph.
In other words, files are both a human-readable interface and an operational interface for agents. Directory structure carries the memory layers, while Markdown syntax expresses content, metadata, and relationships.
Design Goals
ReMe represents memory as files not merely for convenient storage, but to give long-term memory several essential properties:
| Goal | Meaning |
|---|---|
| Readable | Users can open the workspace directly and read daily notes, digest nodes, and source material like ordinary notes. |
| Editable | Users and agents can correct, extend, move, or delete memory with file operations, without a specialized database client. |
| Traceable | Long-term conclusions in digest can point back to daily, resource, or session files from a Sources section. |
| Portable | The workspace is an ordinary directory. Markdown, JSONL, YAML, and resource files can be backed up, synchronized, versioned, or moved to other tools. |
| Indexable | Although the files are plain text, ReMe parses frontmatter, chunks, and wikilinks to build a retrieval index and file graph. |
| Collaborative | Humans judge and correct; agents organize, link, and retrieve. Both operate on the same files. |
ReMe memory is therefore neither a hidden database record nor a prompt fragment visible only to an LLM. It is first a file owned by the user and only then indexed by the system for retrieval.
Memory Layers
A ReMe workspace divides memory into four layers:
raw input -> session/ + resource/
working memory -> daily/
long memory -> digest/
system state -> metadata/
Each layer solves a different problem.
session/ and resource/ preserve raw input. Their purpose is to retain the original situation: conversations, agent
sessions, uploaded material, web pages, and reports remain intact as evidence for later verification.
daily/ is the lightly processed layer. It organizes the day's conversations and resources into more readable daily notes:
what happened, which conclusions were reached, which follow-up tasks remain, and where the source material lives. Daily does
not aim for final abstraction; it is closer to a workbench for the day.
digest/ is the deeply processed layer. It stores memory nodes that can be reused over time, such as user preferences,
project background, procedural experience, conceptual knowledge, and decision precedents. Digest should not merely copy
daily. It should merge recurring facts, methods, and relationships into more stable descriptions.
metadata/ is the system index layer. It stores runtime state such as the file catalog, chunk index, and graph snapshots.
Users normally do not edit this content manually. The actual editing surface is daily/, digest/, and, when necessary,
resource/.
These layers let ReMe preserve both the original situation and its abstraction: daily reconstructs what happened, while digest answers what remains reusable later.
Directory Layout
ReMe uses directories to express memory organization and layers. Source material first enters resource/ or session/,
then flows into daily/, and is finally integrated into digest/ by auto_dream.
The corresponding automatic flows are Auto Memory, Auto Resource, and Auto Dream. Use Memory Search to retrieve these files.
<workspace_dir>/
├── metadata/ # system index layer; persistent indexes, graph, catalogs; not a manual editing surface
├── session/ # raw input layer; original conversations and agent sessions
│ ├── dialog/
│ │ └── <session_id>.jsonl # conversation messages saved by auto_memory
│ ├── agentscope/
│ │ └── <session_id>.jsonl
│ └── claude_code/
│ └── <session_id>.jsonl
├── resource/ # raw input layer; original external material
│ └── YYYY-MM-DD/
│ └── <resource>.<ext>
├── daily/ # lightly processed layer; facts, conversation summaries, and resource interpretations by date
│ ├── YYYY-MM-DD.md # index page for the day
│ └── YYYY-MM-DD/
│ ├── <session_id>.md # daily note distilled from a conversation
│ ├── <resource_stem>.md # daily note distilled from a resource
│ └── interests.yaml # proactive interest topics generated by auto_dream
└── digest/ # deeply processed layer; reusable personal facts, procedures, and knowledge nodes
├── personal/
│ └── <memory>.md # user profile, preferences, and durable personal facts
├── procedure/
│ └── <memory>.md # procedures, methods, and operational experience
└── wiki/
└── <memory>.md # general knowledge, concepts, and decision precedents
Typical flows:
conversation
-> session/dialog/<session_id>.jsonl
-> daily/YYYY-MM-DD/<session_id>.md
-> digest/personal | digest/procedure | digest/wiki
external resource
-> resource/YYYY-MM-DD/<resource>.<ext>
-> daily/YYYY-MM-DD/<resource_stem>.md
-> digest/wiki | digest/procedure
The first two steps focus on recording and organizing; the final step focuses on long-term distillation. auto_memory and
auto_resource generate daily notes from raw input, and auto_dream extracts and integrates digest nodes from daily.
Markdown Format
ReMe favors Markdown for memory because it works well for human reading, agent editing, and programmatic parsing.
A typical memory file:
---
name: Solar Supply Chain Research
description: An end-to-end view from polysilicon to modules
tags: [new energy, solar]
---
# Conclusions
The solar supply chain consists of [[digest/wiki/polysilicon.md]], wafers, cells, and modules.
One major producer is [[digest/wiki/longi.md|LONGi]].
Frontmatter
Frontmatter is a YAML block at the beginning of a file, enclosed by ---:
---
name: Document name
description: Document description
source_conversation: [[session/dialog/abc.jsonl]]
---
The current code recognizes name and description explicitly. Other fields are preserved as additional metadata. The write
interface merges name, description, and metadata into frontmatter.
Treat frontmatter as a node-level summary and the body as evidence, explanation, and relationships. For example:
---
name: "User preference: documentation style"
description: The user prefers direct, engineering-oriented technical explanations with context but without unnecessary length.
kind: preference
confidence: observed
---
The user repeatedly asks documentation to explain motivation, boundaries, and examples while avoiding marketing language.
Apply this preference when following [[digest/procedure/technical-documentation.md]].
## Sources
- [[daily/2026-06-20/session-a.md]]
This has three benefits:
nameanddescriptionserve as lightweight summaries in lists, recall results, and agent decisions.- The body can carry fuller facts, conditions, counterexamples, and sources.
- Ordinary wikilinks can be parsed by the graph and maintained when files move.
Frontmatter is best for stable, short, structured fields; the body is best for explanations meant for people. Do not put long body text into YAML fields.
Wikilink
Wikilinks express relationships between files with [[...]]:
[[daily/2026-06-20/session.md]]
[[notes/example.md#L9]]
[[notes/example.md#L9-L10]]
[[notes/example.md#L9-L10,L15-L20]]
ReMe wikilinks use literal path semantics:
[[X]] -> target_path = "X"
ReMe does not append .md automatically, search by filename, or automatically resolve folder notes. Use complete
workspace-relative paths with their extensions.
Ordinary Markdown links such as [label](../wiki/example.md) do not create FileLink edges and are not rewritten by move or
retarget operations.
Anchors such as #L9, #L9-L10, and #L9-L10,L15-L20 remain ordinary target_anchor strings in the graph. The graph
parser does not validate line-anchor syntax, so values such as #L0, #L10-L9, and #L9, are also stored. The read job
does not interpret an anchor appended to path; use the separate 1-based, inclusive start_line and end_line arguments to
read a range, for example read(path="digest/wiki/solar.md", start_line=9, end_line=10).
Wikilinks support these behaviors:
body link -> create a FileLink
move a file -> rewrite [[old path]] in inbound edges by default
delete a file -> return remaining inbound edges so references can be cleaned up
search match -> expand inbound and outbound links to provide context
Parsed result:
FileLink
source_path = current file
target_path = notes/example.md
target_anchor = L9-L10,L15-L20
Older documents containing wrappers such as related:: [[path]],
- related:: [[path]], or [related:: [[path]]] remain readable. ReMe
ignores the surrounding text and indexes the inner [[path]] as an ordinary
link. After upgrading from a version that stored typed links, run reme reindex
once to rebuild the derived graph without the removed relationship field.
Sources and Relationships
The two most important link types in ReMe are source links and conceptual relationship links.
A Sources section records where a long-term memory came from:
## Sources
- [[daily/2026-06-20/session-a.md]]
- [[resource/2026-06-20/report.pdf]]
A conceptual relationship link explains which other long-term memories relate to the node. Weave it into natural prose:
This analysis extends [[digest/wiki/solar-supply-chain.md]], follows
[[digest/procedure/research-report-analysis.md]], and contrasts with
[[digest/wiki/central-inverter.md]].
Human and Agent Editing
Because memory is stored as files, users can edit the workspace directly, while agents can read and write the same files through ReMe's file tools. Both follow the same conventions:
| Operation | Guidance |
|---|---|
| Add memory | Write to the appropriate directory, use frontmatter for Markdown, and prefer complete workspace-relative wikilinks. |
| Edit a body | Preserve existing sources and important wikilinks. When correcting an old conclusion, explain how the new material changes the previous judgment. |
| Move a file | ReMe's move tool rewrites old paths in inbound edges by default. After a manual move, inspect inbound links again. |
| Delete a file | Check inbound links first. ReMe's delete tool returns source files that still point to the target, making dangling references easier to clean up. |
| Edit metadata | Use frontmatter for short fields. When the body changes substantially, update description as well. |
A practical rule is: an agent may rewrite the wording, but it must not lose evidence edges. In particular, Sources entries and existing digest-to-digest wikilinks are the basis for traceable and extensible long-term memory.
Path Semantics
All file tools and wikilinks use workspace-relative paths as their basic unit:
digest/wiki/solar.md
daily/2026-06-20/session-a.md
resource/2026-06-20/report.pdf
This creates a clear boundary: ReMe does not treat [[solar]] as a repository-wide title search and does not assume
Obsidian-style same-name resolution. [[digest/wiki/solar.md]] points to that exact path.
Recommended practices:
- Include
.mdwhen linking a Markdown file. - Use the complete source path when linking from digest to daily or resource.
- Rename or move files through ReMe's move tool whenever possible to avoid stale paths.
- Put external source material under
resource/YYYY-MM-DD/...and long-term abstractions underdigest/.... Do not put raw source material directly into digest.
Explicit path semantics sacrifice a little convenience when writing by hand, but provide predictability, portability, and automatic maintainability.
Memory Chunking
Memory chunking divides a file into retrievable fragments. ReMe does not split Markdown at fixed lengths by default; it tries to preserve semantic structure.
This section explains how files become retrieval chunks. For index updates, BM25, vector recall, and link expansion, see Memory Search.
Traditional RAG often uses fixed-window splitting:
Document
|
| every N tokens + overlap
v
chunk 1 | chunk 2 | chunk 3 | ...
This is simple, but it can cut headings, tables, code blocks, lists, and [[wikilinks]] in the middle. After a match, the
agent often sees only an isolated fragment without knowing its section or relationship to other memory nodes.
ReMe chunking is closer to splitting memory by file structure:
Markdown file
|
| frontmatter + headings + blocks + wikilinks
v
semantic chunks with document skeleton
Comparison:
traditional RAG chunk
= fixed-length text fragment + overlap
ReMe memory chunk
= section structure + body fragment + line range + wikilink relationship context
Markdown files use MarkdownFileChunker:
Markdown
|
| mistletoe AST
v
Document
└─ H1 section
├─ paragraph / list / table / code
└─ H2 section
└─ ...
|
v
FileChunk[]
Chunking rules:
1. Parse frontmatter first; send the body to the chunker separately.
2. Build a section tree from heading levels.
3. Prefer one complete section per chunk.
4. When a section is too long, recursively split its subsections and body blocks.
5. Repeat table headers when splitting tables.
6. Repeat the fence when splitting code blocks.
7. Pack lists by item.
8. Only then split greedily by line and add [Part X/N].
By default, every chunk includes its heading skeleton:
# Top-level heading
## Current section
Matched body fragment
## Following section heading
This lets the agent see not only an isolated paragraph but also its structural position in the source file.
Non-Markdown files use DefaultFileChunker by default. It splits by byte size and preserves a small overlap. For Markdown,
the chunker also avoids cutting [[wikilinks]] in the middle.