Doramagic Project Pack · Human Manual

commonplace

Commonplace operates as a flat directory of Markdown files with YAML frontmatter. Each note is a plain .md file, and embeddings are stored in .embedding sidecar files generated locally usi...

Introduction to Commonplace

Related topics: Quick Start Guide, System Architecture, Memory Data Model

Section Related Pages

Continue reading this section for the full explanation and source context.

Section Key Components

Continue reading this section for the full explanation and source context.

Section Memory Types

Continue reading this section for the full explanation and source context.

Section Memory File Format

Continue reading this section for the full explanation and source context.

Related topics: Quick Start Guide, System Architecture, Memory Data Model

Introduction to Commonplace

Commonplace is a local-first personal knowledge management system that functions as an MCP (Model Context Protocol) server. It enables AI agents to persistently store, retrieve, and reason about notes using semantic search, all without requiring external API calls or cloud services. Sources: README.md

Overview

Commonplace operates as a flat directory of Markdown files with YAML frontmatter. Each note is a plain .md file, and embeddings are stored in .embedding sidecar files generated locally using transformers.js. This architecture ensures that:

  • Notes are human-readable and portable — since memories are plain Markdown files, they can be edited, backed up, or version-controlled using standard tools.
  • Embeddings are derived, not the source of truth.embedding files are regenerable from .md files at any time and may be deleted or rebuilt without data loss. Sources: CLAUDE.md

Architecture

graph TD
    subgraph "MCP Client Layer"
        A["Claude Code / AI Agent"]
    end
    
    subgraph "MCP Server Layer"
        B["commonplace MCP Server<br/>stdio interface"]
    end
    
    subgraph "Store Layer"
        C["MemoryStore<br/>src/store/memory-store.ts"]
        D["MemoryGraph<br/>Graph relationships"]
        E["Embedder<br/>transformers.js + bge-base-en-v1.5"]
    end
    
    subgraph "Filesystem Layer"
        F["COMMONPLACE_USER_DIR<br/>~/.commonplace"]
        G["COMMONPLACE_PROJECT_DIR<br/>.commonplace"]
    end
    
    A -->|"MCP Protocol"| B
    B --> C
    C --> D
    C --> E
    C --> F
    C --> G
    
    F -.->|"user scope"| C
    G -.->|"project scope"| C

Key Components

ComponentFileResponsibility
MCP Serversrc/server/handlers.tsHandles MCP protocol communication, registers tools
MemoryStoresrc/store/memory-store.tsManages CRUD operations, scanning, searching
MemoryGraphsrc/store/memory-store.tsIn-memory graph for relations and mentions
Embeddersrc/store/embedder.tsLocal embedding generation via transformers.js
Memory I/Osrc/store/memory.tsParses/serializes .md files with YAML frontmatter
Atomic Writesrc/store/atomic-write.tsSafe file writes to prevent corruption
Mentionssrc/store/mentions.tsExtracts [[name]] references from body content

Memory Model

Memory Types

Memories are classified into a four-element taxonomy defined at Sources: README.md

TypePurposeExample
userPersonal rules, preferences, identity facts about the human operatorCoding style preferences, work schedule
feedbackCorrections and lessons learned from prior agent behavior"Don't shrink scope unilaterally"
projectPer-project context like architecture notes, repo conventionsAPI conventions, decision records
referenceDurable, neutral knowledge: API shapes, formulas, citationsLibrary documentation, formulas

Memory File Format

A memory is a Markdown file with YAML frontmatter:

Source: https://github.com/rickbassham/commonplace / Human Manual

Quick Start Guide

Related topics: Introduction to Commonplace, MCP Tool Reference

Section Related Pages

Continue reading this section for the full explanation and source context.

Section From Source

Continue reading this section for the full explanation and source context.

Section Build the Project

Continue reading this section for the full explanation and source context.

Section Memory Types

Continue reading this section for the full explanation and source context.

Related topics: Introduction to Commonplace, MCP Tool Reference

Quick Start Guide

Welcome to Commonplace — a persistent, embeddable memory system for AI agents that operates on plain markdown files with YAML frontmatter.

Prerequisites

Before getting started, ensure your environment meets the following requirements:

RequirementVersionNotes
Node.js20 or 22CI runs on both versions
pnpmlatestPackage manager for this project
Claude CodecompatibleFor MCP tool integration

Sources: CONTRIBUTING.md:1-20

Installation

From Source

Clone the repository and install dependencies:

git clone https://github.com/rickbassham/commonplace.git
cd commonplace
pnpm install

Build the Project

make build

This compiles the TypeScript source and prepares the CLI binary.

Sources: CONTRIBUTING.md:22-30

Core Concepts

Memory Types

Every memory in Commonplace has a type field that categorizes its content:

TypePurposeExample
userPersonal rules, preferences, identity factspreferred_code_style, keyboard_shortcuts
feedbackCorrections and lessons learneddont_shrink_scope_unilaterally, verify_api_response
projectPer-project context, architecture, conventionsmonorepo_structure, db_schema_notes
referenceDurable neutral knowledge, API docsopenapi_spec_location, rate_limit_formulas

Sources: README.md:1-20

Memory Scopes

Commonplace supports two parallel memory stores:

graph TD
    A[Claude Code Session] --> B{Scope Selection}
    B -->|user| C[User Store]
    B -->|project| D[Project Store]
    C --> E[~/.commonplace/memory]
    D --> F[COMMONPLACE_PROJECT_DIR<br/>or<br/>.commonplace/memory]
    
    style C fill:#e1f5fe
    style D fill:#fff3e0
ScopeLocationUse Case
user~/.commonplace/memory (default)Cross-project memories, personal preferences
projectProject root .commonplace/memoryRepository-specific context

Sources: README.md:45-70

Memory File Structure

Each memory is stored as a markdown file with YAML frontmatter:

Sources: CONTRIBUTING.md:1-20

System Architecture

Related topics: Project Structure, Embedding System, Memory Store

Section Related Pages

Continue reading this section for the full explanation and source context.

Section Data Structure

Continue reading this section for the full explanation and source context.

Related topics: Project Structure, Embedding System, Memory Store

System Architecture

Overview

Commonplace is a persistent memory system for AI agents that stores contextual knowledge as markdown files with YAML frontmatter. The system provides semantic search across memories using embeddings, a graph-based relationship model for linking related memories, and a dual-store architecture supporting both user-level and project-level contexts.

The architecture is designed around the principle that markdown files are the source of truth.embedding sidecar files are derived and regenerable at any time. Sources: CLAUDE.md

Core Components

ComponentFilePurpose
MemoryStoresrc/store/memory-store.tsCentral store managing in-memory index, file I/O, search, and graph edges
Memory I/Osrc/store/memory.tsYAML frontmatter parsing, serialization, content hashing
Atomic Writesrc/store/atomic-write.tsSafe file writes via temp-file + rename pattern
Mentions Extractorsrc/store/mentions.tsExtracts [[name]] references from memory bodies
MCP Serversrc/server/handlers.tsTool handlers exposing memory operations via Model Context Protocol
CLI Entrysrc/index.tsCommand-line interface dispatcher

Memory Model

Data Structure

Each memory is a markdown file with the following structure:

Source: https://github.com/rickbassham/commonplace / Human Manual

Project Structure

Related topics: System Architecture, Memory Store

Section Related Pages

Continue reading this section for the full explanation and source context.

Section MemoryStore (src/store/memory-store.ts)

Continue reading this section for the full explanation and source context.

Section Memory I/O (src/store/memory.ts)

Continue reading this section for the full explanation and source context.

Related topics: System Architecture, Memory Store

Project Structure

Overview

Commonplace is a personal knowledge management system designed for AI agents operating via Claude Code. It provides persistent memory storage through markdown files with YAML frontmatter, vector embeddings for semantic search, and a graph structure for tracking relationships between memories.

The project is structured as a Node.js CLI application with an MCP (Model Context Protocol) server component. Sources: src/index.ts:1-25

Directory Layout

commonplace/
├── src/
│   ├── index.ts              # CLI entry point and dispatcher
│   ├── bin/
│   │   ├── boot.ts           # Boot process for MCP server
│   │   └── commonplace-mcp.ts # MCP server stdio interface
│   ├── cli/
│   │   ├── migrate.ts         # Migration command implementation
│   │   └── graph.ts           # Graph query command
│   ├── server/
│   │   └── server.ts          # MCP protocol server
│   ├── store/
│   │   ├── memory-store.ts    # Core memory management
│   │   ├── memory.ts          # Memory I/O and serialization
│   │   ├── atomic-write.ts    # Atomic file operations
│   │   └── mentions.ts        # [[name]] mention extraction
│   └── embedder/
│       └── index.ts           # Vector embedding generation
├── package.json
└── tsconfig.json

Entry Points

The project declares two bin entries in package.json:

Bin NameTargetPurpose
commonplacedist/index.jsHuman-readable CLI output for migrate and graph commands
commonplace-mcpdist/bin/commonplace-mcp.jsStdio MCP server for AI tool integration

Sources: src/index.ts:25-40

The deliberate separation ensures the MCP server's JSON-RPC framing is never polluted by CLI output. Sources: src/index.ts:42-45

CLI Dispatcher

The main CLI entry point (src/index.ts) acts as a subcommand router. It supports two primary command paths:

  1. commonplace migrate — Detect known external memory sources and import memories
  2. commonplace migrate <dir> — Rebuild sidecars for an existing memory directory
  3. commonplace graph — Query memory relationship graph Sources: src/index.ts:54-77
graph TD
    A[commonplace CLI] --> B{Subcommand?}
    B -->|graph| C[graphMain]
    B -->|migrate| D{Args?}
    D -->|detect mode| E[detectImportSources]
    D -->|import mode| F[runImportFromClaudeCode]
    D -->|rebuild mode| G[migrateMain]

The dispatcher uses lazy embedder instantiation — the Embedder (which triggers model loading) is only constructed when migrateMain decides to run after argument parsing succeeds. Sources: src/index.ts:63-69

Core Modules

MemoryStore (`src/store/memory-store.ts`)

The MemoryStore class is the central orchestration component for memory management. It maintains:

  • An in-memory index of all loaded memories
  • A directory watcher for detecting changes
  • An optional MemoryGraph for relationship tracking
  • A lazy embedder factory for generating vector embeddings

Key responsibilities include scanning directories, managing embedding sidecars, handling atomic writes, and processing graph edges. Sources: src/store/memory-store.ts:1-50

The store implements a lazy-scanning pattern where the directory is scanned on first access, and subsequent operations use the cached in-memory index with mtime-based invalidation. Sources: src/store/memory-store.ts:150-180

Memory I/O (`src/store/memory.ts`)

The memory.ts module handles the serialization and deserialization of individual memory files. Each memory consists of:

YAML Frontmatter:

Sources: src/index.ts:25-40

Memory Data Model

Related topics: Memory Types Taxonomy, Memory Store, Embedding System

Section Related Pages

Continue reading this section for the full explanation and source context.

Section Type Constraints

Continue reading this section for the full explanation and source context.

Section TypeScript Interface

Continue reading this section for the full explanation and source context.

Section Frontmatter Schema

Continue reading this section for the full explanation and source context.

Related topics: Memory Types Taxonomy, Memory Store, Embedding System

Memory Data Model

The Memory Data Model is the core abstraction in Commonplace—a local-first knowledge management system that persists memories as plain Markdown files with typed YAML frontmatter. Each memory represents a discrete unit of knowledge, preference, or context that the agent can recall, search, and link to other memories.

Overview

Memories are the atomic units of the Commonplace system. They are stored as .md files on disk where each file contains:

  1. YAML frontmatter carrying typed metadata
  2. Markdown body containing the actual knowledge content

The design philosophy treats the markdown file as the source of truth. Derived artifacts (such as .embedding sidecars) can be regenerated from the markdown at any time. Sources: CLAUDE.md

graph LR
    A[Memory Input] --> B[YAML Frontmatter]
    A --> C[Markdown Body]
    B --> D[.md File]
    C --> D
    D --> E[.embedding Sidecar]
    D --> F[Search Index]
    D --> G[Graph Edges]

Memory Types

Commonplace defines a four-element taxonomy for categorizing memories. Every memory must declare its type in the frontmatter. Sources: README.md

TypeDescriptionUse Case
userPersonal rules, preferences, and identity facts about the human operatorStoring user preferences, communication style, work habits
feedbackCorrections and lessons learned from prior agent behaviorPersistent course-corrections, things that didn't work
projectPer-project contextArchitecture notes, repo conventions, decisions that bind to one codebase
referenceDurable, neutral knowledgeAPI shapes, formulas, citations, lookup-by-meaning content

Type Constraints

The type field is mandatory and validated against the allowed set. Attempting to save a memory with an invalid type throws an error:

if (!isMemoryType(memory.type)) {
  throw new Error(
    `memory.type must be one of ${MEMORY_TYPES.join(', ')}; got ${JSON.stringify(memory.type)}`,
  );
}

Sources: src/store/memory.ts:parseMemory

Memory Structure

TypeScript Interface

interface Memory {
  name: string;
  description: string;
  type: MemoryType;
  body: string;
  relations: Relation[];
  supersedes: string[];
}

Frontmatter Schema

Each memory file follows this YAML frontmatter structure:

Sources: src/store/memory.ts:parseMemory

Memory Types Taxonomy

Related topics: Memory Data Model, Memory Store, Semantic Search

Section Related Pages

Continue reading this section for the full explanation and source context.

Section User Type

Continue reading this section for the full explanation and source context.

Related topics: Memory Data Model, Memory Store, Semantic Search

Memory Types Taxonomy

Overview

The Memory Types Taxonomy is a four-element classification system that categorizes memories stored in Commonplace. Each memory carries a type field that determines its scope, purpose, and how it should be used by the AI agent. This taxonomy enables organized knowledge management across personal rules, learned corrections, project-specific context, and reference materials.

Memory types serve as the primary organizational primitive for the entire system. They appear in YAML frontmatter of markdown files, are validated at write time, and are used to filter search results and graph traversals. Source: README.md

The Four Memory Types

TypePurposeScopeTypical Content
userPersonal rules, preferences, and identity facts about the human operatorCross-projectOperating preferences, name, role, interaction style
feedbackCorrections and lessons learned from prior agent behaviorCross-projectPersistent course-corrections, mistake patterns
projectPer-project context specific to one codebaseSingle projectArchitecture notes, repo conventions, decisions
referenceDurable, neutral knowledgeCross-projectAPI shapes, formulas, citations, lookup knowledge

Source: README.md

User Type

The user type captures information about the human operating the AI agent. This includes personal rules, preferences, identity facts, and operational context that should persist across all projects. Memories of this type represent the agent's understanding of who it is working with and how that person prefers to be addressed or assisted.

Example frontmatter:

Source: https://github.com/rickbassham/commonplace / Human Manual

Memory Store

Related topics: Memory Data Model, Embedding System, Semantic Search

Section Related Pages

Continue reading this section for the full explanation and source context.

Section Memory Structure

Continue reading this section for the full explanation and source context.

Section File Format

Continue reading this section for the full explanation and source context.

Related topics: Memory Data Model, Embedding System, Semantic Search

Memory Store

The Memory Store is the core persistence layer of the Commonplace system. It manages the lifecycle of memory entries—markdown files with YAML frontmatter and binary embedding sidecars—providing atomic writes, concurrent access control, semantic search, and graph-based relationship tracking.

Overview

The Memory Store implements a local-first, file-based storage system where each memory is persisted as a .md file alongside a derived .embedding sidecar. It supports two independent stores (user and project) and exposes both low-level filesystem operations and high-level search/list functionality through an internal API consumed by the MCP server layer.

Key characteristics:

CharacteristicDescription
Storage modelLocal filesystem with markdown + sidecar files
ConcurrencyPer-memory advisory locking via proper-lockfile
AtomicityWrite-through-temp-and-rename pattern
SearchOffline semantic search using transformers.js + bge-base-en-v1.5
GraphIn-memory adjacency list for typed relationships
Mentions[[name]] extraction from body content

Sources: memory-store.ts:1-50

Architecture

graph TD
    subgraph "Memory Store Layer"
        MS[MemoryStore]
        G[MemoryGraph]
        ATOMIC[atomicWrite]
        LOCK[acquireNameLock]
    end
    
    subgraph "Persistence Layer"
        FS[FileSystem]
        MD[*.md Files]
        EMB[*.embedding Sidecars]
    end
    
    subgraph "Integration"
        HANDLERS[MCP Handlers]
        SEARCH[Search Handler]
    end
    
    MS --> G
    MS --> ATOMIC
    MS --> LOCK
    ATOMIC --> FS
    LOCK --> FS
    MS --> MD
    MS --> EMB
    HANDLER_FACTORIES[Handler Factories] --> MS
    SEARCH --> MS

The MemoryStore class owns the directory-scanning, file I/O, embedding caching, and mtime-based invalidation logic. It delegates locking to acquireNameLock, writes to atomicWrite, and maintains an optional MemoryGraph instance for relationship tracking.

Sources: memory-store.ts:50-120

Memory Data Model

Memory Structure

A memory consists of:

  1. YAML Frontmatter: Structured metadata
  2. Markdown Body: Arbitrary content containing [[name]] mention syntax
interface Memory {
  name: string;           // Filename stem, matches ^[a-z0-9_]+$
  description: string;    // Short human description
  type: MemoryType;       // 'user' | 'feedback' | 'project' | 'reference'
  body: string;           // Markdown content
  relations: Relation[];  // Typed graph edges (DAR-925)
  supersedes: string[];   // Names of superseded memories
}

interface Relation {
  to: string;             // Target memory name
  type: RelationType;     // 'builds-on' | 'related-to' | 'contradicts' | 'child-of'
}

Sources: memory.ts:1-80

File Format

Memory files use canonical markdown with YAML frontmatter:

Sources: memory-store.ts:1-50

Embedding System

Related topics: Memory Store, Semantic Search

Section Related Pages

Continue reading this section for the full explanation and source context.

Section Canonical Hash Inputs

Continue reading this section for the full explanation and source context.

Section SHA Scope Justification

Continue reading this section for the full explanation and source context.

Section Sidecar Schema

Continue reading this section for the full explanation and source context.

Related topics: Memory Store, Semantic Search

Embedding System

The embedding system in Commonplace transforms markdown memory content into vector representations stored as sidecar files, enabling semantic search across the memory store. It is designed to treat the .md source as the single source of truth, with embeddings as derived, regenerable artifacts.

Architecture Overview

The embedding pipeline consists of three primary layers:

  1. Memory Layer (src/store/memory.ts) — parses and serializes markdown with YAML frontmatter, computes canonical content hashes
  2. Store Layer (src/store/memory-store.ts) — orchestrates the scan/embed lifecycle, validates sidecar freshness, manages orphan cleanup
  3. Embedder Layer (src/embedder/index.ts) — generates vector embeddings via transformers.js
graph TD
    A[Markdown File] --> B[readMemory]
    B --> C[contentSha Computation]
    C --> D[Load Sidecar]
    D --> E{Sidecar Fresh?}
    E -->|Yes| F[Skip Embedding]
    E -->|No| G[Embedder.embed]
    G --> H[Serialize Sidecar]
    H --> I[atomicWrite]
    I --> J[.embedding Sidecar]
    C -.-> K[body text + frontmatter]
    F --> L[Use Existing Sidecar]

Content Hash (contentSha)

The canonical content hash is computed over a specific slice of the memory's data structure, deliberately excluding graph-related fields to prevent embedding invalidation when relationships change.

Canonical Hash Inputs

FieldIncludedRationale
type✅ YesMemory type affects semantic context
name✅ YesName is part of semantic identity
description✅ YesDescription is semantically meaningful
body✅ YesFull body content
relations❌ NoGraph edges are derived, not source
supersedes❌ NoGraph edges are derived, not source

Sources: src/store/memory.ts:contentSha function

The hash formula is:

sha256("${type}\n${name}\n${description}\n${body}")

This produces a 64-character lowercase hex string that uniquely identifies the semantic content of a memory.

SHA Scope Justification

The graph fields (relations, supersedes) are intentionally excluded per DAR-925 design decisions. Adding or removing graph edges must not invalidate existing embeddings because:

  • Embeddings are derived from semantic content, not graph topology
  • Forcing re-embedding on graph edits would create unnecessary API calls
  • The sidecar is explicitly marked as derived, not authoritative

Sidecar Format

Embeddings are stored in .embedding sidecar files alongside their corresponding .md files. The sidecar encodes sufficient metadata to validate freshness without re-reading the markdown.

Sidecar Schema

FieldTypePurpose
modelIdstringIdentifies the embedding model used
dimnumberEmbedding vector dimensionality
contentShastringHash of canonical content
embeddingnumber[]The vector data

Sources: src/store/sidecar.ts

Sidecar File Naming

Sidecar files follow the naming convention <name>.embedding where <name> matches the corresponding memory file <name>.md. This 1:1 correspondence enables orphan detection.

Scan Lifecycle

The MemoryStore.scan() method implements the complete embed lifecycle, checking each memory's sidecar for freshness and triggering regeneration when needed.

Freshness Criteria

A sidecar is considered fresh (reusable) when ALL of the following hold:

  1. The .embedding file exists
  2. It decodes successfully (magic + version + length checks pass)
  3. decoded.modelId === embedder.modelId
  4. decoded.dim === embedder.dim
  5. decoded.contentSha === contentSha(memoryAsRead)

Sources: src/store/memory-store.ts:scan method

If ANY criterion fails, the memory is re-embedded and the sidecar rewritten.

Scan Process

graph TD
    A[Start Scan] --> B[Read all .md files]
    B --> C{For each memory}
    C --> D{No sidecar?}
    D -->|Yes| E[Trigger embed]
    D -->|No| F{Decode passes?}
    F -->|No| E
    F -->|Yes| G{modelId match?}
    G -->|No| E
    G -->|Yes| H{dim match?}
    H -->|No| E
    H -->|Yes| I{contentSha match?}
    I -->|Yes| J[Skip - use existing]
    I -->|No| E
    C --> K[Orphan Cleanup]
    K --> L[Remove orphaned .embedding files]
    E --> M[Write new sidecar]
    J --> C
    M --> C

Orphan Cleanup

After processing all memories, scan performs a second directory walk to detect and remove orphan sidecars — .embedding files whose matching .md no longer exists. Orphans are reported via the ScanResult.orphaned field.

Sources: src/store/memory-store.ts:orphan cleanup

Atomic Write Strategy

Sidecar writes use an atomic write-temp-rename pattern to prevent corruption from partial writes.

Write Sequence

  1. Generate random tmp filename: <basename>.<8-hex-chars>.tmp
  2. Write data to tmp file
  3. Verify source and target are on same filesystem (dev match)
  4. Rename tmp file to target (atomic on same filesystem)

Sources: src/store/atomic-write.ts

Cross-Filesystem Guard

if (targetDirStat.dev !== tmpDirStat.dev) {
  throw new Error("refusing to rename across filesystems");
}

This guard ensures rename operations remain atomic, as rename(2) is not atomic across filesystem boundaries.

Integration Points

CLI Entry Point

The main CLI (src/index.ts) wires the embedder factory into the migrate command:

embedderFactory: () => new Embedder(resolveModelId(process.env)),

The lazy factory ensures the transformers.js model is only loaded when an actual embed call occurs, not during argument parsing.

Migrate Command

The commonplace migrate <dir> command exposes scan functionality as a standalone tool:

  • Re-embeds any .md whose sidecar is missing or stale
  • Cleans up orphaned sidecars
  • Optionally prunes dangling graph edges (--prune-dangling flag)

Sources: src/cli/migrate.ts:migrateScan

Configuration

Environment Variables

VariableDefaultPurpose
COMMONPLACE_EMBEDDING_MODELmodel-specificEmbedding model identifier

The resolveModelId() function reads the environment to determine which embedding model to instantiate.

Embedder Initialization

The Embedder class is instantiated with the resolved model ID. Model loading (transformers.js) occurs on first embed() call, not on construction, enabling lazy initialization.

Memory Types and Embedding

All four memory types are embeddable with identical treatment:

TypeDescriptionEmbedding Behavior
userPersonal rules and preferencesStandard
feedbackLessons from prior behaviorStandard
projectPer-project contextStandard
referenceDurable knowledgeStandard

Memory type is included in the content hash, so type changes trigger re-embedding.

Summary

The embedding system provides:

  • Semantic search via vector embeddings
  • Source-of-truth isolation with SHA-scoped content hashes
  • Automatic regeneration when content changes
  • Orphan cleanup for stale sidecars
  • Atomic writes for corruption prevention
  • Model portability validation through metadata checks

All embedding behavior is derived from markdown content; the .embedding files are regenerable artifacts that can be deleted and rebuilt via the migrate command at any time.

Sources: src/store/memory.ts:contentSha function

Graph Features

Related topics: Semantic Search, MCP Tool Reference

Section Related Pages

Continue reading this section for the full explanation and source context.

Section Core Components

Continue reading this section for the full explanation and source context.

Section Frontmatter Declaration

Continue reading this section for the full explanation and source context.

Related topics: Semantic Search, MCP Tool Reference

Graph Features

Overview

The Graph Features system provides a network-based view of memories, enabling relationships between notes to be tracked, queried, and visualized. Rather than treating each memory as an isolated entity, the graph layer exposes connections through authored relations in frontmatter, supersedes declarations, and automatic [[name]] mention extraction from body content.

The graph is not a separate data store—it derives from the same markdown files that form the memory corpus. Each .md file in a memory store may declare outgoing edges via its YAML frontmatter, and the in-memory MemoryGraph maintains an adjacency list for efficient traversal.

Sources: src/store/graph.ts:1-30

Architecture

graph TD
    subgraph "Memory Sources"
        UserStore["User Memory Store<br/>(~/.commonplace)"]
        ProjectStore["Project Memory Store<br/>(./.commonplace)"]
    end
    
    subgraph "Graph Layer"
        MemoryGraph["MemoryGraph"]
        AdjacencyList["Adjacency List<br/>(Map&lt;name, Edge[]&gt;)"]
    end
    
    subgraph "Edge Sources"
        Relations["relations[]<br/>frontmatter field"]
        Supersedes["supersedes[]<br/>frontmatter field"]
        Mentions["[[name]] mentions<br/>body extraction"]
    end
    
    UserStore --> MemoryGraph
    ProjectStore --> MemoryGraph
    MemoryGraph --> AdjacencyList
    Relations --> MemoryGraph
    Supersedes --> MemoryGraph
    Mentions --> MemoryGraph

Core Components

ComponentFilePurpose
MemoryGraphsrc/store/graph.tsIn-memory graph with adjacency list, edge management, and traversal
Edge / DanglingEdgesrc/store/graph.tsData models for directed edges
MemoryStoresrc/store/memory-store.tsPersists graph edges via frontmatter, maintains in-memory sync
mentions.tssrc/store/mentions.tsExtracts [[name]] tokens from body content
handlers.tssrc/server/handlers.tsMCP tool handlers for graph operations
graph.ts CLIsrc/cli/graph.tsCommand-line graph visualization

Sources: src/store/graph.ts:25-45

Edge Types

The graph supports a union of edge types drawn from three sources:

Edge TypeSourceDescription
related-torelations[] frontmatterGeneral-purpose association between memories
builds-onrelations[] frontmatterMemory that extends or depends on another
contradictsrelations[] frontmatterMemory that opposes or negates another
child-ofrelations[] frontmatterHierarchical parent-child relationship
supersedessupersedes[] frontmatterMemory that replaces or renders another obsolete
mentionsBody [[name]] extractionMemory references another by name in its body

Sources: src/store/graph.ts:15-25

Frontmatter Declaration

Memories declare outgoing edges in YAML frontmatter:

Sources: src/store/graph.ts:1-30

MCP Tool Reference

Related topics: Server Handlers, Semantic Search, Graph Features

Section Related Pages

Continue reading this section for the full explanation and source context.

Section memorysave

Continue reading this section for the full explanation and source context.

Section memorylist

Continue reading this section for the full explanation and source context.

Section memorydelete

Continue reading this section for the full explanation and source context.

Related topics: Server Handlers, Semantic Search, Graph Features

MCP Tool Reference

The Model Context Protocol (MCP) server exposes a set of tools that enable external clients—primarily Claude Code—to interact with the commonplace book. These tools provide CRUD operations for memories, semantic search, and graph management. The MCP stdio server acts as the bridge between the local embedding pipeline and any MCP-compatible client.

Sources: src/server/handlers.ts:1-25

Architecture Overview

The MCP server is implemented in src/server/ and wired to the memory store layer. Tool requests arrive via stdio JSON-RPC, are validated in handler functions, dispatched to the MemoryStore, and returned as JSON-serializable responses wrapped in MCP content blocks.

graph TD
    A[MCP Client<br/>Claude Code] --> B[stdio JSON-RPC]
    B --> C[server.ts<br/>CallToolRequest Dispatcher]
    C --> D[handlers.ts<br/>Tool Handlers]
    D --> E[MemoryStore]
    E --> F[memory.ts<br/>YAML + Embedding I/O]
    E --> G[graph.ts<br/>In-memory Graph]
    F --> H[.md Files<br/>+ .embedding Sidecars]

Sources: src/server/handlers.ts:17-23

Tool Categories

The MCP server exposes two categories of tools:

CategoryPurposeTools
Memory CRUDCreate, read, delete, and search memoriesmemory_save, memory_list, memory_delete, memory_search
Graph ManagementManage relationships between memoriesmemory_link, memory_unlink

Sources: README.md:1-50

Scope Model

Every tool accepts an optional scope argument that selects which memory store to address:

ScopeDescription
userCross-project memories stored in COMMONPLACE_USER_DIR
projectProject-specific memories stored in COMMONPLACE_PROJECT_DIR

When scope is omitted, reads merge across both stores and writes default to user.

Sources: src/server/handlers.ts:30-35

Memory Types

All memory tools operate on a four-element taxonomy defined in the store layer:

TypePurpose
userPersonal rules, preferences, and identity facts about the human operator
feedbackCorrections and lessons learned from prior agent behaviour; persistent course-corrections
projectPer-project context like architecture notes, repo conventions, and decisions
referenceDurable, neutral knowledge: API shapes, formulas, citations

Sources: src/store/memory.ts:1-30

Memory CRUD Tools

memory_save

Save a memory as a markdown file with YAML frontmatter and a derived embedding sidecar. Refuses to overwrite an existing entry; the contract is delete + save.

Input Schema:

ArgumentTypeRequiredDescription
namestringYesMemory name. Must match ^[a-z0-9_]+$. Becomes the filename stem.
type`user \feedback \project \reference`YesOne of the four memory types.
descriptionstringYesShort description used in search result summaries.
bodystringYesMarkdown content of the memory.
scope`'user' \'project'`NoWhich store to write to. Defaults to 'user'.

Sources: README.md:50-80

Validation: Arguments are validated manually at handler entry. The handler checks name against validateName, type against MEMORY_TYPES, and passes store errors through unchanged.

Sources: src/server/handlers.ts:40-55

memory_list

List all memories, optionally filtered by type.

Input Schema:

ArgumentTypeRequiredDescription
type`user \feedback \project \reference`NoFilter to memories of this type only.
scope`'user' \'project'`NoWhich store to query. Defaults to merging both stores.

Response: Returns an array of memory entries with name, type, description, and body fields.

Sources: src/server/handlers.ts:60-75

memory_delete

Delete a memory by name from the specified store.

Input Schema:

ArgumentTypeRequiredDescription
namestringYesName of the memory to delete.
scope`'user' \'project'`NoWhich store to delete from. Defaults to 'user'.

Sources: src/server/handlers.ts:80-95

Semantic search across all memories using local embeddings.

Input Schema:

ArgumentTypeRequiredDescription
querystringYesNatural language search query.
type`user \feedback \project \reference`NoFilter to memories of this type only.
limitnumberNoMaximum results to return. Defaults to DEFAULT_SEARCH_LIMIT.
scope`'user' \'project'`NoWhich store to search. Defaults to merging both stores.

Sources: src/server/handlers.ts:100-130

Response Enrichment: Search results include relations from connected memories and exclude notes marked as superseded. This is handled by MemoryGraph integration.

Sources: src/store/memory-store.ts:1-50

Graph Management Tools

Create a directed edge between two memories, establishing a typed relationship.

Input Schema:

ArgumentTypeRequiredDescription
fromstringYesSource memory name.
tostringYesTarget memory name.
type`RelationType \'supersedes'`YesRelationship type.
scope`'user' \'project'`NoWhich store contains both memories.

Relation Types:

TypeDescription
builds-onThe source memory builds upon the target
implementsThe source memory implements the target
relates-toGeneral relationship between memories
supersedesThe source memory supersedes the target

Behavior:

  • Throws if the edge already exists (no duplicate edges).
  • Updates the relations array in the source memory's YAML frontmatter.
  • Mutates the in-memory entry in place for consistency.
  • Refreshes the directory mtime baseline to avoid wasteful rescans.

Sources: src/store/memory-store.ts:200-280

graph LR
    A[memory: feedback_scope] -->|builds-on| B[memory: scope_management]
    A -->|supersedes| C[memory: old_feedback_v1]

Remove a directed edge between two memories.

Input Schema:

ArgumentTypeRequiredDescription
fromstringYesSource memory name.
tostringYesTarget memory name.
type`RelationType \'supersedes'`NoSpecific edge type to remove. If omitted, removes ALL edges from from to to.

Behavior:

  • No-op when the requested edge does not exist (no atomic write, no graph mutation).
  • Returns { ..., note: '<reason>' } for friendly messaging when edges don't exist.
  • When edges are removed, writes the source .md through atomicWrite, updates the in-memory entry in place, and calls MemoryGraph.removeEdge.

Sources: src/store/memory-store.ts:300-400

Validation Strategy

Tool argument validation is deliberately manual rather than schema-library-based:

  • Zero new dependencies for validation logic.
  • Rejection messages are tailored to name the offending field.
  • Store layer errors are passed through unchanged to preserve context.

Sources: src/server/handlers.ts:15-20

Response Format

All tool responses are JSON-serializable shapes wrapped in a single text content block by the MCP server's CallToolRequest dispatcher in server.ts. The dispatcher handles both the CRUD tools and graph tools uniformly.

Sources: src/server/handlers.ts:20-23

Environment Variables

The MCP server respects the following environment variables:

VariableDefaultDescription
COMMONPLACE_USER_DIR~/.commonplaceDirectory for user-scoped memories
COMMONPLACE_PROJECT_DIR<cwd>/.commonplaceDirectory for project-scoped memories
COMMONPLACE_EXTRACT_MENTIONS'true'Enable [[name]] mention extraction from body content

Sources: src/store/mentions.ts:1-30

MCP Server Binary

The MCP server is exposed as the commonplace-mcp binary, separate from the CLI's commonplace command. This separation ensures the MCP stdio framing channel is never polluted by CLI output.

Sources: src/index.ts:1-30

See Also

Sources: src/server/handlers.ts:1-25

Server Handlers

Related topics: MCP Tool Reference, System Architecture

Section Related Pages

Continue reading this section for the full explanation and source context.

Section Request Flow

Continue reading this section for the full explanation and source context.

Section Handler Factory Pattern

Continue reading this section for the full explanation and source context.

Section MemorySaveHandler

Continue reading this section for the full explanation and source context.

Related topics: MCP Tool Reference, System Architecture

Server Handlers

Overview

Server Handlers are the core request-processing layer in the Commonplace MCP server. They implement the MCP (Model Context Protocol) tool handlers that bridge the MCP client interface to the underlying MemoryStore persistence layer. Each handler is a factory function that produces an MCP-compatible request handler with consistent validation, error handling, and response shaping.

The handler system is designed around:

  • Factory pattern: Each handler is created via a factory function (e.g., createMemorySaveHandler, createMemoryListHandler) that encapsulates store access and validation logic.
  • Typed interfaces: All inputs and outputs use TypeScript interfaces exported from handlers.ts for compile-time safety.
  • Scope awareness: Handlers support both user and project scopes, allowing memories to be stored in different directories.
  • Graph integration: Handlers can optionally work with the MemoryGraph to enrich responses with relation data.

Architecture

Request Flow

graph TD
    A[MCP Request] --> B[Server dispatch]
    B --> C{Handler Factory}
    C --> D[createMemorySaveHandler]
    C --> E[createMemoryListHandler]
    C --> F[createMemorySearchHandler]
    C --> G[createMemoryDeleteHandler]
    C --> H[createMemoryLinkHandler]
    C --> I[createMemoryUnlinkHandler]
    D --> J[MemoryStore]
    E --> J
    F --> J
    G --> J
    H --> J
    I --> J
    J --> K[MemoryGraph]
    J --> L[File System]
    K --> M[Relation Enrichment]
    L --> N[.md + .embedding files]
    M --> O[MCP Response]
    N --> O

Handler Factory Pattern

Each handler follows the factory pattern documented in handlers.ts:

export const createMemorySaveHandler = (opts: CreateHandlerOptions) => {
  const { userStore, projectStore } = resolveStores(opts);
  return async (request: MemorySaveRequest): Promise<MemorySaveResult> => {
    // Validation and processing
  };
};

Sources: src/server/handlers.ts:1-50

Handler Types

MemorySaveHandler

Purpose: Creates or updates a memory note with YAML frontmatter and markdown body.

Factory: createMemorySaveHandler(options: CreateHandlerOptions)

Request Interface:

FieldTypeRequiredDescription
namestringYesMemory identifier matching ^[a-z0-9_]+$
typeMemoryTypeYesOne of: user, feedback, project, reference
descriptionstringYesBrief description for search relevance
bodystringYesMarkdown content
scopeScopeNouser (default) or project

Response Interface:

export interface MemorySaveResult {
  saved: {
    name: string;
    type: MemoryType;
    description: string;
  };
  path: string;
  /** Which store the memory was written to (DAR-924) */
  scope: Scope;
}

Sources: src/server/handlers.ts:80-95

Validation:

  • Name must match NAME_PATTERN (^[a-z0-9_]+$)
  • Type must be one of MEMORY_TYPES
  • Scope is validated via validateScope() helper
  • Duplicate relations are deduplicated on write

Sources: src/store/memory.ts:1-50

MemoryListHandler

Purpose: Returns all memories from a store, optionally filtered by type and scope.

Factory: createMemoryListHandler(options: CreateHandlerOptions)

Request Interface:

FieldTypeRequiredDescription
typeMemoryTypeNoFilter by memory type
scopeScopeNoFilter by scope (user/project)

Response Interface:

export interface MemoryListResult {
  memories: Array<{
    name: string;
    type: MemoryType;
    description: string;
    /** Which store this entry came from */
    scope: Scope;
  }>;
}

Sources: src/server/handlers.ts:97-108

MemorySearchHandler

Purpose: Performs semantic search across memory embeddings using cosine similarity.

Factory: createMemorySearchHandler(options: CreateHandlerOptions)

Request Interface:

FieldTypeRequiredDescription
querystringYesNatural language search query
limitnumberNoMax results (default: 10)
typeMemoryTypeNoFilter by type
scopeScopeNoFilter by scope
expandbooleanNoInclude related memories (default: true)
expandTypesEdgeType[]NoWhich relation types to expand

Response Interface:

export interface MemorySearchMatch {
  name: string;
  type: MemoryType;
  description: string;
  body: string;          // Full body, never truncated
  score: number;         // Cosine similarity, 3 decimals
  relations: Relation[]; // Outgoing graph edges
}

Sources: src/server/handlers.ts:35-60

Expand Types Configuration:

TypeDefaultDescription
builds-onYesIncluded by default
related-toYesIncluded by default
mentionsNoRequires opt-in
supersedesNoRequires opt-in
contradictsNoRequires opt-in
child-ofNoRequires opt-in
export const DEFAULT_EXPAND_TYPES: readonly EdgeType[] = ['builds-on', 'related-to'] as const;

Sources: src/server/handlers.ts:20-30

Response Enrichment:

When expand is enabled, the handler enriches results by:

  1. Fetching direct matches from MemoryStore.search()
  2. For each match, query MemoryGraph for outgoing edges matching expandTypes
  3. Add expanded memories to response (marked with expanded: true)
  4. Exclude superseded memories unless explicitly requested

MemoryDeleteHandler

Purpose: Removes a memory from the store by name.

Factory: createMemoryDeleteHandler(options: CreateHandlerOptions)

Request Interface:

FieldTypeRequiredDescription
namestringYesMemory name to delete
scopeScopeNoScope hint for store resolution

Response Interface:

export interface MemoryDeleteResult {
  deleted: string;
  scope: Scope;
}

MemoryLinkHandler

Purpose: Creates a directed edge between two memories in the graph.

Factory: createMemoryLinkHandler(options: CreateHandlerOptions)

Request Interface:

FieldTypeRequiredDescription
fromstringYesSource memory name
tostringYesTarget memory name
typeRelationTypeYesEdge type
scopeScopeNoScope for operation

Relation Types:

TypeDescription
builds-onMemory extends or depends on another
related-toMemory has loose association
contradictsMemory refutes another
child-ofMemory is subordinate to another

Internal Behavior: The handler delegates to MemoryStore.linkEdge() which:

  1. Validates both memory names exist
  2. Adds the relation to the source memory's frontmatter
  3. If type is supersedes, also adds to supersedes list
  4. Writes updated markdown via atomic write
  5. Updates the in-memory MemoryGraph

Sources: src/store/memory-store.ts:1-50

MemoryUnlinkHandler

Purpose: Removes a directed edge between two memories.

Factory: createMemoryUnlinkHandler(options: CreateHandlerOptions)

Request Interface:

FieldTypeRequiredDescription
fromstringYesSource memory name
tostringYesTarget memory name
type`RelationType \'supersedes'`NoSpecific edge type to remove. Omit to remove all edges to target

Behavior:

  • No-op when the requested edge does not exist
  • When type is omitted, removes ALL edges from from -> to
  • Returns { relations, supersedes, note } describing the new state

Sources: src/store/memory-store.ts:100-150

Store Resolution

Handlers use the resolveStores helper to map request scopes to actual store instances:

const resolveStores = (opts: { store?: MemoryStore; userStore?: MemoryStore; projectStore?: MemoryStore }) => {
  const userStore = opts.userStore ?? opts.store;
  if (userStore === undefined) {
    throw new Error(`${toolName}: handler factory requires a userStore`);
  }
  return { userStore, projectStore: opts.projectStore };
};

Sources: src/server/handlers.ts:65-75

Scope System

The scope system allows memories to be stored in different locations:

ScopeDirectoryUse Case
userCOMMONPLACE_USER_DIRCross-project knowledge
projectCOMMONPLACE_PROJECT_DIRProject-specific facts

Validation:

const SCOPES = ['user', 'project'] as const;
type Scope = typeof SCOPES[number];

const isScope = (v: unknown): v is Scope =>
  typeof v === 'string' && (SCOPES as readonly string[]).includes(v);

Sources: src/server/handlers.ts:55-70

Server Initialization

The handlers are wired into the MCP server in server.ts:

graph LR
    A[MCP Server] --> B[registerTools]
    B --> C[MemorySaveHandler]
    B --> D[MemoryListHandler]
    B --> E[MemorySearchHandler]
    B --> F[MemoryDeleteHandler]
    B --> G[MemoryLinkHandler]
    B --> H[MemoryUnlinkHandler]

The main entry point (src/index.ts) dispatches to the server module:

if (argv[0] === 'graph') {
  const result = await graphMain({ argv, ... });
  return result.exitCode;
}

Sources: src/index.ts:1-30

Error Handling

All handlers follow consistent error handling patterns:

Error TypeCauseResponse
Validation errorInvalid input formatThrows with descriptive message
Not foundMemory doesn't existHandled by store methods
Duplicate edgeEdge already existsHandled by linkEdge
Store unavailableStore not initializedFactory throws on construction

Integration with MemoryStore

Handlers delegate to MemoryStore methods for all persistence operations:

HandlerStore Method
MemorySaveHandlerMemoryStore.save()
MemoryListHandlerMemoryStore.all()
MemorySearchHandlerMemoryStore.search()
MemoryDeleteHandlerMemoryStore.delete()
MemoryLinkHandlerMemoryStore.linkEdge()
MemoryUnlinkHandlerMemoryStore.unlinkEdge()

Sources: src/store/memory-store.ts:1-200

Mention Extraction

When a memory is saved, the body is scanned for [[name]] wiki-link syntax:

graph TD
    A[Memory Save] --> B[Extract mentions]
    B --> C{NAME_PATTERN test}
    C -->|pass| D[Add to MemoryGraph]
    C -->|fail| E[Skip]
    D --> F[edgesPruned count]

This extraction is controlled by the COMMONPLACE_EXTRACT_MENTIONS environment variable (default: enabled).

Sources: src/store/mentions.ts:1-60

Configuration

Handlers are configured via environment variables managed in DAR-913:

VariableDefaultEffect
COMMONPLACE_USER_DIR~/.commonplaceUser memory directory
COMMONPLACE_PROJECT_DIR./.commonplaceProject memory directory
COMMONPLACE_MODEL_IDXenova/bge-base-en-v1.5Embedding model
COMMONPLACE_EXTRACT_MENTIONStrueEnable [[name]] extraction

Sources: src/server/handlers.ts:1-50

Doramagic Pitfall Log

Source-linked risks stay visible on the manual page so the preview does not read like a recommendation.

medium README/documentation is current enough for a first validation pass.

The project should not be treated as fully validated until this signal is reviewed.

medium Project risk needs validation

The project should not be treated as fully validated until this signal is reviewed.

medium Maintainer activity is unknown

Users cannot judge support quality until recent activity, releases, and issue response are checked.

medium no_demo

The project may affect permissions, credentials, data exposure, or host boundaries.

Doramagic Pitfall Log

Doramagic extracted 8 source-linked risk signals. Review them before installing or handing real data to the project.

1. Capability assumption: README/documentation is current enough for a first validation pass.

  • Severity: medium
  • Finding: README/documentation is current enough for a first validation pass.
  • User impact: The project should not be treated as fully validated until this signal is reviewed.
  • Recommended check: Open the linked source, confirm whether it still applies to the current version, and keep the first run isolated.
  • Evidence: capability.assumptions | github_repo:1232879661 | https://github.com/rickbassham/commonplace | README/documentation is current enough for a first validation pass.

2. Project risk: Project risk needs validation

  • Severity: medium
  • Finding: Project risk is backed by a source signal: Project risk needs validation. Treat it as a review item until the current version is checked.
  • User impact: The project should not be treated as fully validated until this signal is reviewed.
  • Recommended check: Open the linked source, confirm whether it still applies to the current version, and keep the first run isolated.
  • Evidence: packet_text.keyword_scan | github_repo:1232879661 | https://github.com/rickbassham/commonplace | matched external service / cloud / webhook / database keyword

3. Maintenance risk: Maintainer activity is unknown

  • Severity: medium
  • Finding: Maintenance risk is backed by a source signal: Maintainer activity is unknown. Treat it as a review item until the current version is checked.
  • User impact: Users cannot judge support quality until recent activity, releases, and issue response are checked.
  • Recommended check: Open the linked source, confirm whether it still applies to the current version, and keep the first run isolated.
  • Evidence: evidence.maintainer_signals | github_repo:1232879661 | https://github.com/rickbassham/commonplace | last_activity_observed missing

4. Security or permission risk: no_demo

  • Severity: medium
  • Finding: no_demo
  • User impact: The project may affect permissions, credentials, data exposure, or host boundaries.
  • Recommended check: Open the linked source, confirm whether it still applies to the current version, and keep the first run isolated.
  • Evidence: downstream_validation.risk_items | github_repo:1232879661 | https://github.com/rickbassham/commonplace | no_demo; severity=medium

5. Security or permission risk: No sandbox install has been executed yet; downstream must verify before user use.

  • Severity: medium
  • Finding: No sandbox install has been executed yet; downstream must verify before user use.
  • User impact: The project may affect permissions, credentials, data exposure, or host boundaries.
  • Recommended check: Open the linked source, confirm whether it still applies to the current version, and keep the first run isolated.
  • Evidence: risks.safety_notes | github_repo:1232879661 | https://github.com/rickbassham/commonplace | No sandbox install has been executed yet; downstream must verify before user use.

6. Security or permission risk: no_demo

  • Severity: medium
  • Finding: no_demo
  • User impact: The project may affect permissions, credentials, data exposure, or host boundaries.
  • Recommended check: Open the linked source, confirm whether it still applies to the current version, and keep the first run isolated.
  • Evidence: risks.scoring_risks | github_repo:1232879661 | https://github.com/rickbassham/commonplace | no_demo; severity=medium

7. Maintenance risk: issue_or_pr_quality=unknown

  • Severity: low
  • Finding: issue_or_pr_quality=unknown。
  • User impact: Users cannot judge support quality until recent activity, releases, and issue response are checked.
  • Recommended check: Open the linked source, confirm whether it still applies to the current version, and keep the first run isolated.
  • Evidence: evidence.maintainer_signals | github_repo:1232879661 | https://github.com/rickbassham/commonplace | issue_or_pr_quality=unknown

8. Maintenance risk: release_recency=unknown

  • Severity: low
  • Finding: release_recency=unknown。
  • User impact: Users cannot judge support quality until recent activity, releases, and issue response are checked.
  • Recommended check: Open the linked source, confirm whether it still applies to the current version, and keep the first run isolated.
  • Evidence: evidence.maintainer_signals | github_repo:1232879661 | https://github.com/rickbassham/commonplace | release_recency=unknown

Source: Doramagic discovery, validation, and Project Pack records

Community Discussion Evidence

These external discussion links are review inputs, not standalone proof that the project is production-ready.

Sources 4

Count of project-level external discussion links exposed on this manual page.

Use Review before install

Open the linked issues or discussions before treating the pack as ready for your environment.

Community Discussion Evidence

Doramagic exposes project-level community discussion separately from official documentation. Review these links before using commonplace with real data or production workflows.

Source: Project Pack community evidence and pitfall evidence