# How ai‑memory Handles Pinned Pages and Their Exemption from Decay

> Discover how ai-memory protects pinned pages from decay. Learn how to exempt vital content from automatic sweeps using pinned: true in front-matter.

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

---

**In ai‑memory, pages marked with `pinned: true` in their front‑matter are completely exempt from the automatic decay and forget sweeps that remove stale content.**

The **ai‑memory** wiki system implements a tiered memory model where most pages fade over time unless accessed, but critical content can be preserved indefinitely through a simple metadata flag. This article examines how pinned pages are defined, stored, and protected from deletion during periodic cleanup operations.

## How Pinned Status Is Defined and Stored

A page becomes pinned through **front‑matter metadata** in its Markdown file. When you create or edit a page, add the YAML front‑matter:

```yaml
---
title: Critical Documentation
pinned: true
---

```

This flag flows through the write path in [`crates/ai-memory-wiki/src/wiki.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-wiki/src/wiki.rs). The `Wiki::write_page` method parses the front‑matter, merges it with any explicit `pinned` value in the `WritePageRequest`, and persists the result to `PageMeta.pinned`. According to the source, this occurs at lines 560, 1185, 1297, and 1575 of [`wiki.rs`](https://github.com/akitaonrails/ai-memory/blob/main/wiki.rs).

The **store** crate then makes this flag queryable for decay decisions. As noted in [`crates/ai-memory-store/src/reader.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-store/src/reader.rs), the `pinned` field is stored as a boolean in the page metadata table with the explicit semantic: *"Pinned flag — true means 'never decay'"*.

## The Decay Candidate Query Excludes Pinned Pages

The protection mechanism operates during the **memory forget sweep**, a periodic background task that identifies stale pages for soft deletion. The sweep delegates candidate selection to `Reader::decay_candidates` in the store crate.

The query constructing this candidate list **explicitly filters out pinned pages**. The implementation skips any row where `pinned = true`, ensuring these pages never enter the decay pipeline. Consequently:

- Pinned pages are **never soft‑deleted for decay** via `soft_delete_for_decay_if_latest`
- Pinned pages are **never hard‑deleted** in subsequent cleanup phases
- Pinned pages **bypass all decay‑related operations** entirely

This design is documented in [`docs/ARCHITECTURE.md`](https://github.com/akitaonrails/ai-memory/blob/main/docs/ARCHITECTURE.md): *"Pinned pages (`pinned: true` in frontmatter) are exempt from all decay paths."*

## Automatic Pinning for Slot Pages

ai‑memory provides a special namespace for editable content sections. Pages under the `_slots/` path—used for persona definitions, project context, and other user‑maintained configuration—receive **automatic pinned status** without requiring explicit front‑matter.

The test `slot_pages_are_pinned_automatically` in [`wiki.rs`](https://github.com/akitaonrails/ai-memory/blob/main/wiki.rs) verifies this behavior. This ensures that structural, frequently‑edited content survives regardless of how the decay algorithm weights access patterns.

## Practical Examples

### Creating a Pinned Page via the Rust API

```rust
use ai_memory_wiki::{PagePath, Wiki, WritePageRequest};

let path = PagePath::new("architecture/decisions.md").unwrap();
let req = WritePageRequest {
    path: path.clone(),
    body: "This record must persist indefinitely.".to_string(),
    meta: serde_json::json!({ 
        "title": "Architecture Decision Record", 
        "pinned": true 
    }),
    ..Default::default()
};
wiki.write_page(req).await?;

```

### Querying with Pinned Page Visibility

```bash

# List all matching pages, including pinned

ai_memory query "architecture" --include-pinned

```

### Verifying Decay Immunity Programmatically

```rust
// Decay candidates never contain pinned pages
let candidates = store.reader.decay_candidates(workspace, project).await?;
assert!(
    candidates.iter().all(|c| !c.pinned),
    "Pinned pages must not appear in decay candidates"
);

```

## Key Implementation Files

| File | Purpose |
|------|---------|
| [`crates/ai-memory-wiki/src/wiki.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-wiki/src/wiki.rs) | Parses front‑matter, handles `write_page`, manages `PageMeta.pinned` |
| [`crates/ai-memory-store/src/reader.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-store/src/reader.rs) | Implements `decay_candidates` with pinned‑page exclusion |
| [`docs/ARCHITECTURE.md`](https://github.com/akitaonrails/ai-memory/blob/main/docs/ARCHITECTURE.md) | Documents pinned‑page exemption from decay |
| [`crates/ai-memory-wiki/src/wiki.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-wiki/src/wiki.rs) (test section) | Validates automatic pinning for `_slots/` pages |

## Summary

- **Definition**: Set `pinned: true` in YAML front‑matter, or use the `_slots/` namespace for automatic pinning.
- **Persistence**: The flag is stored in `PageMeta.pinned` and written through [`wiki.rs`](https://github.com/akitaonrails/ai-memory/blob/main/wiki.rs).
- **Protection**: `Reader::decay_candidates` explicitly excludes pinned pages from all decay operations.
- **Result**: Pinned content remains on‑disk indefinitely, immune to automatic cleanup.

## Frequently Asked Questions

### What happens if I pin a page after it has already been soft‑deleted?

The decay system operates on the latest revision's pinned status. If you restore and pin a previously decayed page, subsequent sweeps will exclude it from candidate selection based on the new metadata.

### Can pinned pages still be manually deleted?

Yes. The pinned flag only prevents **automatic** decay. Manual deletion through `Wiki::delete_page` or direct filesystem operations remains unrestricted.

### Is there a performance cost to having many pinned pages?

Minimal. The pinned check adds a simple `WHERE pinned != true` clause to the decay candidate query. Since pinned pages are excluded from the result set, they actually reduce the processing burden during forget sweeps.

### How do I programmatically check if a page is pinned?

Query the `PageMeta` struct returned by read operations. The `pinned` field is a public boolean:

```rust
let meta = wiki.read_page(&path).await?.meta;
if meta.pinned {
    println!("Page is protected from decay");
}

```