# The Four Memory Tiers in ai-memory: Working, Episodic, Semantic, and Procedural

> Explore the four memory tiers in ai-memory Working Episodic Semantic and Procedural. Learn how they manage retention search ranking and lifecycle for your markdown pages.

- Repository: [Fabio Akita/ai-memory](https://github.com/akitaonrails/ai-memory)
- Tags: deep-dive
- Published: 2026-09-05

---

**The ai-memory system organizes every markdown page into one of four tiers—Working, Episodic, Semantic, or Procedural—that control retention, search ranking, and lifecycle management.**

The `ai-memory` Rust library implements a **tiered memory architecture** where each page's classification determines how long it persists and how prominently it surfaces in retrieval. This design mirrors human cognitive memory systems, balancing transient session data against durable knowledge assets.

## What Are Memory Tiers in ai-memory?

A **memory tier** is a categorical classification stored in a page's front-matter that signals its intended lifetime and purpose. The `Tier` enum, defined in [`crates/ai-memory-core/src/page.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-core/src/page.rs) at lines 22-31, uses `#[serde(rename_all = "snake_case")]` serialization so values appear lowercase in markdown front-matter (e.g., `tier: semantic`).

| Tier | Lifetime | Purpose | Example Use Case |
|------|----------|---------|----------------|
| **Working** | Session-only | Recent observations, temporary files | Scratch notes, debug logs from current run |
| **Episodic** | Days to weeks | Per-session summaries | What was explored in Tuesday's coding session |
| **Semantic** | Indefinite (default) | Canonical facts and preferences | Project architecture documentation |
| **Procedural** | Indefinite, auto-generated | Reusable patterns and workflows | Code snippets, CLI recipes extracted from many sessions |

When front-matter omits the tier field, the wiki layer in [`crates/ai-memory-wiki/src/wiki.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-wiki/src/wiki.rs) (lines 2050-2070) defaults to `Semantic`, ensuring pages don't silently degrade to ephemeral status.

## How Tiers Affect System Behavior

Tiers influence three core subsystems: retention decay, search ranking, and storage validation.

### Retention and Decay ([`decay.rs`](https://github.com/akitaonrails/ai-memory/blob/main/decay.rs))

The retention sweep in [`crates/ai-memory-store/src/decay.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-store/src/decay.rs) assigns **time-to-live (TTL)** values based on tier:

- **Working pages**: Short TTL, aggressively purged
- **Episodic pages**: Moderate TTL, expires after session relevance fades
- **Semantic and Procedural pages**: No expiration unless explicitly set via `expires_at`

This prevents knowledge base bloat while preserving valuable long-term content.

### Search Ranking ([`reader.rs`](https://github.com/akitaonrails/ai-memory/blob/main/reader.rs))

The ranking logic in [`crates/ai-memory-store/src/reader.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-store/src/reader.rs) (lines 225-235) applies a **multiplicative boost factor** during retrieval:

```rust
factor += match tier {
    Tier::Working => 0.1,
    Tier::Episodic => 0.5,
    Tier::Semantic => 1.0,
    Tier::Procedural => 1.2,  // Highest boost for reusable patterns
};

```

Higher tiers surface first, ensuring users find established knowledge over transient notes.

### Validation and Defaults ([`wiki.rs`](https://github.com/akitaonrails/ai-memory/blob/main/wiki.rs))

The wiki parser enforces tier integrity:

- Missing tier → defaults to `Semantic` ( conservative choice)
- Invalid tier string → parse error with clear message
- Valid tier → mapped to `Tier` enum variant via serde

## Using Memory Tiers in Practice

### Creating a Page with a Specific Tier

```rust
use ai_memory_core::page::{Tier, NewPage};
use ai_memory_core::ids::{WorkspaceId, ProjectId, PagePath};

let page = NewPage {
    workspace_id: WorkspaceId::new("default"),
    project_id: ProjectId::new("demo"),
    path: PagePath::new("notes/tuesday-session.md").unwrap(),
    title: "Tuesday Exploration Summary".into(),
    body: "Investigated async runtime options...".into(),
    tier: Tier::Episodic,  // ← Session-bound, will decay naturally
    frontmatter_json: serde_json::json!({ 
        "title": "Tuesday Exploration Summary" 
    }),
    pinned: false,
    links: vec![],
    author_id: None,
    expires_at: None,
    entities: vec![],
};

```

The `tier` field in `NewPage` drives all downstream storage and retrieval behavior.

### Front-Matter Configuration

```markdown
---
title: "Project Architecture"
tier: semantic        # ← lowercase per snake_case serialization

pinned: true
created: 2024-01-15
---

# Architecture Overview

This document describes the core system design...

```

The parser in [`crates/ai-memory-wiki/src/wiki.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-wiki/src/wiki.rs) (lines 2000-2060) reads `tier: semantic` and maps it to `Tier::Semantic`.

### Filtering Searches by Tier

```rust
let results = store.search_pages(
    "authentication",
    SearchOptions {
        required_tier: Some("procedural".into()),
        ..Default::default()
    },
);

```

This query restricts results to procedural patterns—ideal when seeking reusable code workflows rather than exploratory notes.

## Key Source Files for Memory Tiers

| File Path | Purpose |
|-----------|---------|
| [`crates/ai-memory-core/src/page.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-core/src/page.rs) | `Tier` enum definition, `NewPage` struct |
| [`crates/ai-memory-wiki/src/wiki.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-wiki/src/wiki.rs) | Front-matter parsing, tier validation and defaults |
| [`crates/ai-memory-store/src/reader.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-store/src/reader.rs) | Tier-based ranking factors, search filtering |
| [`crates/ai-memory-store/src/decay.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-store/src/decay.rs) | TTL computation per tier, retention sweeps |
| [`crates/ai-memory-store/src/writer.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-store/src/writer.rs) | Atomic persistence of tiered pages |

## Summary

- **Four tiers** organize ai-memory pages: Working, Episodic, Semantic, and Procedural
- **Tier** is front-matter metadata serialized with `snake_case` via serde
- **Retention** varies by tier: Working expires fastest, Semantic/Procedural persist indefinitely
- **Search ranking** boosts higher tiers, with Procedural receiving the strongest preference
- **Default tier** is Semantic when front-matter omits the field, preventing accidental data loss

## Frequently Asked Questions

### What happens if I don't specify a tier in my markdown front-matter?

The wiki layer defaults missing tiers to **Semantic** in [`crates/ai-memory-wiki/src/wiki.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-wiki/src/wiki.rs). This conservative default prevents valuable content from being treated as disposable session data.

### Can I change a page's tier after creation?

Yes—you can update the front-matter and rewrite the page via the store's writer. The `NewPage` struct in [`crates/ai-memory-core/src/page.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-core/src/page.rs) carries the tier field, and subsequent operations respect the new classification for ranking and retention.

### Why does Procedural get the highest search boost?

Procedural pages represent patterns extracted from many episodic clusters—the most reusable knowledge. The ranking factor of `1.2` in [`crates/ai-memory-store/src/reader.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-store/src/reader.rs) surfaces these workflows prominently when users search for solutions.

### How do I query only my recent session notes?

Use `SearchOptions` with `required_tier: Some("working".into())` or `"episodic".into()`. Combine with time-based filters if your store implementation supports temporal constraints in [`crates/ai-memory-store/src/reader.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-store/src/reader.rs).