Filesystem Adapter

The default adapter. Stores memory as versioned JSON files on the local filesystem. No external dependencies required.

Table of Contents

  1. Installation
  2. Configuration
    1. YAML
    2. Programmatic
    3. Environment Variable
  3. On-Disk Layout
    1. JSON File Contents
  4. Write Safety
  5. Watch
  6. When to Use

Installation

Included with the main amfs package:

pip install amfs

Configuration

YAML

namespace: default
layers:
  primary:
    adapter: filesystem
    options:
      root: .amfs

Programmatic

from amfs_filesystem import FilesystemAdapter
from pathlib import Path

adapter = FilesystemAdapter(
    root=Path(".amfs"),
    namespace="default",
)

Environment Variable

export AMFS_DATA_DIR=/data/shared-memory

On-Disk Layout

Entries are stored as versioned JSON files organized by namespace, entity, and key:

.amfs/
└── default/                          ← namespace
    └── checkout-service/             ← entity_path
        └── retry-pattern/            ← key
            ├── v001_superseded.json   ← old version
            ├── v002_superseded.json   ← old version
            └── v003_current.json      ← active version

JSON File Contents

Each file contains a complete MemoryEntry:

{
  "amfs_version": "0.1.0",
  "entity_path": "checkout-service",
  "key": "retry-pattern",
  "version": 3,
  "value": {"pattern": "exponential-backoff", "max_retries": 5},
  "provenance": {
    "agent_id": "review-agent",
    "session_id": "abc-123",
    "written_at": "2025-06-15T10:30:00+00:00",
    "pattern_refs": ["retry-logic"]
  },
  "confidence": 0.85,
  "outcome_count": 0,
  "ttl_at": null,
  "embedding": null
}

Write Safety

The filesystem adapter uses two mechanisms for safe concurrent writes:

  1. Atomic rename — Writes go to a temporary .tmp file, then os.rename() atomically moves it into place. This is safe on POSIX systems even during crashes.

  2. Advisory file lockingflock() on a per-key lock file prevents concurrent writes from interleaving.


Watch

The filesystem adapter watches entity directories for changes and calls your callback when new versions appear.

def on_change(entry):
    print(f"{entry.key} changed")

handle = mem.watch("checkout-service", on_change)

When to Use

  • Local development
  • Single-machine setups
  • Quick prototyping
  • CI/CD pipelines (ephemeral memory)

For team sharing or multi-machine setups, use the Postgres adapter.