# https://github.com/jmiaie/ompa 项目说明书

生成时间：2026-05-15 13:44:18 UTC

## 目录

- [Introduction to OMPA](#introduction)
- [Quick Start Guide](#quickstart)
- [Feature Comparison](#comparison)
- [Three-Layer Architecture](#three-layer-architecture)
- [Lifecycle Hooks](#lifecycle-hooks)
- [Vault System](#vault-system)
- [Palace System](#palace-system)
- [Knowledge Graph](#knowledge-graph)
- [Message Classification](#message-classification)
- [Python API Reference](#python-api)

<a id='introduction'></a>

## Introduction to OMPA

### 相关页面

相关主题：[Three-Layer Architecture](#three-layer-architecture), [Quick Start Guide](#quickstart)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [README.md](https://github.com/jmiaie/ompa/blob/main/README.md)
- [CHANGELOG.md](https://github.com/jmiaie/ompa/blob/main/CHANGELOG.md)
- [CONTRIBUTING.md](https://github.com/jmiaie/ompa/blob/main/CONTRIBUTING.md)
- [STABILITY.md](https://github.com/jmiaie/ompa/blob/main/STABILITY.md)
- [CLAUDE.md](https://github.com/jmiaie/ompa/blob/main/CLAUDE.md)
- [examples/mcp_desktop/README.md](https://github.com/jmiaie/ompa/blob/main/examples/mcp_desktop/README.md)
- [ompa/classifier.py](https://github.com/jmiaie/ompa/blob/main/ompa/classifier.py)
- [ompa/mcp_server.py](https://github.com/jmiaie/ompa/blob/main/ompa/mcp_server.py)
- [ompa/core.py](https://github.com/jmiaie/ompa/blob/main/ompa/core.py)
</details>

# Introduction to OMPA

OMPA (Obsidian-MemPalace-Agnostic) is a lightweight, framework-agnostic memory management system designed for AI agents. It provides persistent storage, semantic search, knowledge graph tracking, and a palace metaphor for organizing notes and memories across sessions.

## Overview

OMPA serves as a **second brain** for AI agents, enabling them to:

- Persist and retrieve information across sessions
- Classify and automatically route messages to appropriate storage locations
- Search vault contents using semantic similarity
- Track temporal knowledge graphs with validity windows
- Navigate a hierarchical palace structure (wings, rooms, drawers, halls, tunnels)

The project was renamed from "AgnosticObsidian" to OMPA in version 0.2.0, with backward compatibility preserved via an alias. 资料来源：[CHANGELOG.md:1-10]()

## Key Features

| Feature | Description |
|---------|-------------|
| **Dual-Vault Architecture** | Separate shared and personal vault storage with isolation modes |
| **Semantic Search** | Local embedding-based search using sentence-transformers |
| **Temporal Knowledge Graph** | SQLite-backed triples with validity windows |
| **Message Classification** | 15 message types with automatic routing |
| **Lifecycle Hooks** | 5 hooks for extending agent behavior |
| **MCP Server** | 15 tools exposed via Model Context Protocol |
| **CLI Interface** | 14 commands for vault operations |

## Architecture

OMPA follows a layered architecture with distinct responsibilities:

```mermaid
graph TD
    subgraph "OMPA Architecture"
        CLI[CLI<br>14 commands]
        MCP[MCP Server<br>15 tools]
        Core[Core Module<br>Ompa class]
        Vault[Vault<br>CRUD operations]
        Palace[Palace<br>Metadata layers]
        KG[Knowledge Graph<br>SQLite triples]
        Semantic[Semantic Index<br>Embeddings]
        Classifier[Classifier<br>15 message types]
        Hooks[Hook Manager<br>Lifecycle hooks]
    end
    
    CLI --> Core
    MCP --> Core
    Core --> Vault
    Core --> Palace
    Core --> KG
    Core --> Semantic
    Core --> Classifier
    Core --> Hooks
```

### Core Components

#### 1. Vault (`ompa/vault.py`)

The Vault layer handles file-based storage for notes. It provides:

- Brain/work/org/perf folder organization
- Note CRUD operations
- Orphan detection
- Path traversal protection
- UTF-8 encoding enforcement

资料来源：[README.md:47-56]()

#### 2. Palace (`ompa/palace.py`)

The Palace metadata layer provides hierarchical navigation:

- **Wings**: Top-level categories
- **Rooms**: Secondary divisions within wings
- **Drawers**: Tertiary storage units
- **Halls**: Cross-room connections
- **Tunnels**: Cross-wing shortcuts

#### 3. Knowledge Graph (`ompa/knowledge_graph.py`)

Temporal knowledge graph backed by SQLite:

- Triple storage: `(subject, predicate, object)`
- Validity windows: `valid_from` and `valid_to` timestamps
- Timeline queries for entity history
- Auto-population from vault wikilinks and frontmatter

#### 4. Classifier (`ompa/classifier.py`)

Message classification engine supporting 15 message types:

| Message Type | Description |
|--------------|-------------|
| `DECISION` | Architectural decisions, ADR records |
| `INCIDENT` | Bugs, outages, debugging events |
| `WIN` | Achievements, deployments, milestones |
| `ONE_ON_ONE` | Manager/peer check-ins |
| `MEETING` | Meeting notes and action items |
| `PROJECT_UPDATE` | Project status reports |
| `REFLECTION` | Retrospectives, learnings |
| `TODO` | Task items |
| `QUESTION` | Technical questions |
| `IDEA` | Brainstorming, proposals |
| `LEARNING` | New information acquired |
| `BLOCKER` | Impediments |
| `ARCHITECTURE` | System design discussions |
| `SECURITY` | Security-related events |
| `DATA` | Data-related events |

资料来源：[ompa/classifier.py:1-50]()

#### 5. Semantic Search (`ompa/semantic.py`)

Local semantic search using sentence-transformers:

- Lazy model loading (downloaded on first access)
- Incremental indexing (tracks file modification times)
- Cosine similarity scoring
- Optional feature via `pip install ompa[all]`

#### 6. Hooks (`ompa/hooks.py`)

Lifecycle hooks for extending OMPA behavior:

```mermaid
graph LR
    SS[session_start] --> CB[Hook execution]
    HM[handle_message] --> CB
    PT[post_tool] --> CB
    PC[pre_compact] --> CB
    ST[stop] --> CB
    
    CB --> HR[HookResult]
```

资料来源：[CONTRIBUTING.md:43-54]()

#### 7. MCP Server (`ompa/mcp_server.py`)

Model Context Protocol server exposing 15 tools:

```mermaid
graph TD
    MCP[JSON-RPC<br>stdin/stdout] --> Tools
    Tools --> ao_session_start
    Tools --> ao_classify
    Tools --> ao_search
    Tools --> ao_kg_query
    Tools --> ao_kg_add
    Tools --> ao_kg_stats
    Tools --> ao_palace_wings
    Tools --> ao_palace_rooms
    Tools --> ao_palace_tunnel
    Tools --> ao_validate
    Tools --> ao_wrap_up
    Tools --> ao_status
    Tools --> ao_orphans
    Tools --> ao_kg_populate
    Tools --> ao_init
```

资料来源：[CLAUDE.md:1-15]()

## Installation

### Package Options

```bash
# Core only (vault + palace + KG + CLI + MCP)
pip install ompa

# With local semantic search
pip install ompa[all]

# Development dependencies
pip install ompa[dev]
```

Requirements: Python 3.10+

资料来源：[README.md:36-44]()

### Quick Start

```bash
# Initialize vault
ao init

# Check vault health
ao status

# Start a session
ao session-start

# Classify a message
ao classify "We decided to go with Postgres"

# Search vault
ao search "authentication decisions"

# Query knowledge graph
ao kg-query Kai

# End session
ao wrap-up
```

## Dual-Vault Architecture

OMPA supports separating team/organization content from personal notes:

```python
from ompa import Ompa, DualVaultConfig, IsolationMode

config = DualVaultConfig(
    shared_vault="./team-vault",
    personal_vault="./private-vault",
    mode=IsolationMode.AUTO,
)
ao = Ompa(config=config)
```

### Isolation Modes

| Mode | Behavior |
|------|----------|
| `AUTO` | Content auto-classified to shared or personal vault based on message type |
| `STRICT` | Explicit `VaultTarget` routing required for all operations |
| `MANUAL` | Default vault configurable, explicit routing optional |

资料来源：[README.md:57-71]()

## Python API

### Core Class

```python
from ompa import Ompa

ao = Ompa(vault_path="./workspace")

# Lifecycle
context = ao.session_start()              # Returns ~2K token context string
hint = ao.handle_message("We won the enterprise deal!")
ao.post_tool("write", {"file_path": "work/active/auth.md"})
ao.wrap_up()                              # alias for stop()
ao.standup()                              # alias for session_start()

# Search
results = ao.search("authentication decisions", wing="Orion")

# Classification
classification = ao.classify(message)
routing_hint = ao.get_routing_hint(message)

# Knowledge graph
ao.kg.add_triple("Kai", "works_on", "Orion", valid_from="2025-06-01")
triples = ao.kg.query_entity("Kai")
timeline = ao.kg.timeline("Orion")
```

资料来源：[STABILITY.md:12-45]()

### Data Classes

```python
HookResult(hook_name, success, output, tokens_hint, error)
Classification(message_type, confidence, suggested_action, routing_hints)
SearchResult(path, content_excerpt, score, match_type)
Triple(subject, predicate, object, valid_from, valid_to, confidence, source_file)
```

## MCP Desktop Integration

OMPA integrates with AI coding assistants via MCP:

```json
{
  "mcpServers": {
    "ompa": {
      "command": "python",
      "args": ["-m", "ompa.mcp_server"],
      "env": {
        "OMPA_VAULT_PATH": "/absolute/path/to/vault"
      }
    }
  }
}
```

### Supported IDEs

| IDE | Configuration Location |
|-----|------------------------|
| Claude Desktop | `~/.claude/claude_desktop_config.json` |
| Cursor | `.cursor/mcp.json` |
| Windsurf | `.windsurf/mcp.json` |

资料来源：[examples/mcp_desktop/README.md:1-50]()

## Environment Variables

| Variable | Default | Description |
|----------|---------|-------------|
| `OMPA_VAULT_PATH` | `.` | Absolute path to vault |
| `OMPA_ENABLE_SEMANTIC` | `false` | Enable local semantic search |
| `OMPA_AGENT_NAME` | `agent` | Agent name (scopes KG entries) |
| `OMPA_SHARED_VAULT` | — | Shared vault path (dual-vault mode) |
| `OMPA_PERSONAL_VAULT` | — | Personal vault path (dual-vault mode) |
| `OMPA_ISOLATION_MODE` | `auto` | Isolation mode (dual-vault) |

## Project Structure

```
ompa/
├── core.py              # Ompa main class — lifecycle, hooks, dual-vault
├── vault.py             # Vault management (brain/work/org/perf)
├── palace.py            # Palace metadata (wings/rooms/drawers/halls/tunnels)
├── knowledge_graph.py   # Temporal KG (SQLite triples + validity windows)
├── hooks.py             # 5 lifecycle hooks + HookManager
├── classifier.py        # 15 message types with auto-routing
├── semantic.py          # Local semantic search (lazy model loading)
├── mcp_server.py        # MCP protocol server (15 tools)
├── config.py            # Dual-vault configuration
└── cli.py               # typer CLI (14 commands)
```

资料来源：[README.md:47-56]()

## Security Features

- **Path traversal protection**: All vault file operations resolve and boundary-check paths against vault root 资料来源：[CHANGELOG.md:23-26]()
- **UTF-8 encoding enforcement**: All vault file writes use UTF-8 explicitly
- **Security audit**: 8/10 rating with 59/59 tests passing

## API Stability

OMPA follows Semantic Versioning. The stable public API includes:

- `Ompa` core class and all public methods
- Data classes: `HookResult`, `Classification`, `SearchResult`, `Triple`
- CLI commands and MCP tools
- Sync backends and adapters

资料来源：[STABILITY.md:1-50]()

## Framework Compatibility

| Agent Framework | Integration Method |
|-----------------|-------------------|
| Claude Code | Python API + MCP server |
| OpenClaw | Python API + MCP server |
| Codex | Python API + MCP server |
| Gemini CLI | Python API + MCP server |
| LangChain | Python API + adapters |

## CLI Reference

| Command | Description |
|---------|-------------|
| `ao init` | Initialize a new vault |
| `ao status` | Health check and stats |
| `ao session-start` | Inject memory context |
| `ao classify <msg>` | Classify and route a message |
| `ao search <query>` | Semantic search |
| `ao orphans` | Detect orphaned notes |
| `ao wrap-up` | Session summary and save |
| `ao wings` | List palace wings |
| `ao rooms <wing>` | List rooms in a wing |
| `ao tunnel` | Create/traverse cross-wing tunnel |
| `ao kg-query <entity>` | Query knowledge graph |
| `ao kg-timeline <entity>` | Entity timeline |
| `ao kg-stats` | KG statistics |
| `ao validate` | Validate vault structure |
| `ao rebuild-index` | Rebuild semantic index |

资料来源：[README.md:18-37]()

---

<a id='quickstart'></a>

## Quick Start Guide

### 相关页面

相关主题：[Python API Reference](#python-api)

<details>
<summary>Relevant Source Files</summary>

以下源码文件用于生成本页说明：

- [README.md](https://github.com/jmiaie/ompa/blob/main/README.md)
- [CONTRIBUTING.md](https://github.com/jmiaie/ompa/blob/main/CONTRIBUTING.md)
- [examples/mcp_desktop/README.md](https://github.com/jmiaie/ompa/blob/main/examples/mcp_desktop/README.md)
- [CLAUDE.md](https://github.com/jmiaie/ompa/blob/main/CLAUDE.md)
- [STABILITY.md](https://github.com/jmiaie/ompa/blob/main/STABILITY.md)
- [pyproject.toml](https://github.com/jmiaie/ompa/blob/main/pyproject.toml)
</details>

# Quick Start Guide

OMPA (Obsidian-MemPalace-Agnostic) is a local-first memory management system for AI agents. It provides a dual-layer architecture combining a **Vault** for source-of-truth note storage with a **Palace** for retrieval acceleration, plus a temporal **Knowledge Graph** for entity tracking. This guide walks you through installation, vault initialization, CLI usage, Python API integration, and MCP server setup.

---

## Prerequisites

Before installing OMPA, ensure your environment meets the following requirements:

| Requirement | Version | Notes |
|-------------|---------|-------|
| Python | 3.10+ | Required for async/await support |
| pip | Latest recommended | For package installation |
| git | Any recent version | For source installation |
| Disk space | ~100MB minimum | +500MB if enabling semantic search |

资料来源：[README.md](https://github.com/jmiaie/ompa/blob/main/README.md)

---

## Installation

OMPA offers multiple installation options depending on your use case.

### Core Installation

The core package includes vault management, palace metadata, knowledge graph, CLI, and MCP server:

```bash
pip install ompa
```

资料来源：[README.md](https://github.com/jmiaie/ompa/blob/main/README.md)

### With Semantic Search

Install with local semantic search support (adds sentence-transformers and numpy):

```bash
pip install ompa[all]
```

> **Note:** First run downloads the `all-MiniLM-L6-v2` model (~90MB). Subsequent runs are instant. 资料来源：[examples/mcp_desktop/README.md](https://github.com/jmiaie/ompa/blob/main/examples/mcp_desktop/README.md)

### Development Installation

For contributing or modifying OMPA:

```bash
git clone https://github.com/jmiaie/ompa
cd ompa
pip install -e ".[dev,all]"
```

资料来源：[CONTRIBUTING.md](https://github.com/jmiaie/ompa/blob/main/CONTRIBUTING.md)

---

## Initializing the Vault

After installation, initialize your vault to create the required directory structure:

```bash
ao init
```

The vault structure is created with the following organization:

```
.vault/
├── brain/           # Brain notes (agent memory)
├── work/            # Work-related notes
├── org/             # Organizational notes
├── perf/            # Performance metrics
├── .palace/         # Palace metadata (internal)
│   ├── wings/
│   ├── rooms/
│   └── tunnels/
└── .kg/             # Knowledge graph (SQLite)
    └── knowledge.db
```

资料来源：[CLAUDE.md](https://github.com/jmiaie/ompa/blob/main/CLAUDE.md)

### Verify Vault Health

Check that everything is properly configured:

```bash
ao status
```

资料来源：[README.md](https://github.com/jmiaie/ompa/blob/main/README.md)

---

## CLI Command Reference

OMPA provides 14 CLI commands for vault operations. All commands are prefixed with `ao`.

### Session Lifecycle Commands

| Command | Description |
|---------|-------------|
| `ao session-start` | Inject memory context at session start (~2K token context) |
| `ao wrap-up` | Session summary and persist to vault |
| `ao stop` | Clean session shutdown |
| `ao status` | Vault health status and statistics |

### Note Management Commands

| Command | Description |
|---------|-------------|
| `ao classify <msg>` | Classify and route a message to the correct folder |
| `ao search <query>` | Semantic search across vault notes |
| `ao orphans` | Detect orphaned notes (broken wikilinks) |
| `ao init` | Initialize a new vault |
| `ao validate` | Validate vault structure integrity |

### Knowledge Graph Commands

| Command | Description |
|---------|-------------|
| `ao kg-query <entity>` | Query knowledge graph for entity |
| `ao kg-timeline <entity>` | Entity timeline view |
| `ao kg-stats` | Knowledge graph statistics |

### Palace Navigation Commands

| Command | Description |
|---------|-------------|
| `ao wings` | List palace wings |
| `ao rooms <wing>` | List rooms in a wing |
| `ao tunnel` | Create/traverse cross-wing tunnel |

### Index Management

| Command | Description |
|---------|-------------|
| `ao rebuild-index` | Rebuild the semantic index (skips unchanged files) |

资料来源：[README.md](https://github.com/jmiaie/ompa/blob/main/README.md)

---

## Python API Quick Start

### Basic Usage

```python
from ompa import Ompa

# Initialize with vault path
ao = Ompa(vault_path="./workspace")

# Start a session
context = ao.session_start()

# Classify and route a message
hint = ao.handle_message("We decided to go with Postgres")

# Use tools
ao.post_tool("write", {"file_path": "work/active/auth.md"})

# Clean shutdown
ao.stop()
```

### Semantic Search

```python
# Search with optional wing filter
results = ao.search("authentication decisions", wing="Orion")

# Each result contains: path, content_excerpt, score, match_type
for result in results:
    print(f"{result.path}: {result.score}")
```

### Knowledge Graph Operations

```python
# Add temporal triples
ao.kg.add_triple(
    "Kai", 
    "works_on", 
    "Orion", 
    valid_from="2025-06-01"
)

# Query entity history
triples = ao.kg.query_entity("Kai")

# Get entity timeline
timeline = ao.kg.timeline("Orion")
```

### Palace Navigation

```python
# Create a wing
ao.palace.create_wing("Orion")

# Create a room in a wing
ao.palace.create_room("Orion", "authentication")

# Create cross-wing tunnels
ao.palace.create_tunnel("Orion", "Pegasus", room="shared")
```

资料来源：[README.md](https://github.com/jmiaie/ompa/blob/main/README.md)

---

## MCP Server Integration

The MCP (Model Context Protocol) server enables OMPA tools to be used directly within AI coding assistants like Claude Desktop, Cursor, and Windsurf.

### Claude Desktop Setup

**Option 1: CLI (Recommended)**

```bash
claude mcp add ompa -- python -m ompa.mcp_server
```

**Option 2: Manual Configuration**

Edit `~/.claude/claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "ompa": {
      "command": "python",
      "args": ["-m", "ompa.mcp_server"],
      "env": {
        "OMPA_VAULT_PATH": "/absolute/path/to/your/vault"
      }
    }
  }
}
```

### Cursor / Windsurf Setup

Create `.cursor/mcp.json` in your project root:

```json
{
  "mcpServers": {
    "ompa": {
      "command": "python",
      "args": ["-m", "ompa.mcp_server"],
      "env": {
        "OMPA_VAULT_PATH": "${workspaceFolder}/.ompa-vault",
        "OMPA_ENABLE_SEMANTIC": "false"
      }
    }
  }
}
```

资料来源：[examples/mcp_desktop/README.md](https://github.com/jmiaie/ompa/blob/main/examples/mcp_desktop/README.md)

### Available MCP Tools

| Tool | Description |
|------|-------------|
| `ao_session_start` | Inject memory context |
| `ao_classify` | Classify and route message |
| `ao_search` | Semantic search |
| `ao_kg_query` | Query knowledge graph |
| `ao_kg_add` | Add knowledge triple |
| `ao_kg_stats` | KG statistics |
| `ao_palace_wings` | List wings |
| `ao_palace_rooms` | List rooms in wing |
| `ao_palace_tunnel` | Create/traverse tunnels |
| `ao_validate` | Validate vault |
| `ao_wrap_up` | Session summary |
| `ao_status` | Vault health |
| `ao_orphans` | Find orphaned notes |
| `ao_kg_populate` | Populate KG from vault |
| `ao_sync` | Sync vault |
| `ao_write` | Write note |
| `ao_export` | Export note |
| `ao_import` | Import note |
| `ao_init` | Initialize vault |

### Environment Variables

| Variable | Default | Description |
|----------|---------|-------------|
| `OMPA_VAULT_PATH` | `.` | Absolute path to vault |
| `OMPA_ENABLE_SEMANTIC` | `false` | Enable local semantic search |
| `OMPA_AGENT_NAME` | `agent` | Agent name (scopes KG entries) |
| `OMPA_SHARED_VAULT` | — | Shared vault path (dual-vault mode) |
| `OMPA_PERSONAL_VAULT` | — | Personal vault path (dual-vault mode) |
| `OMPA_ISOLATION_MODE` | `auto` | Isolation mode (auto/strict) |

### Verifying Connection

Once connected, ask your AI assistant:

> "Use the `ao_status` tool to check my OMPA vault health"

资料来源：[examples/mcp_desktop/README.md](https://github.com/jmiaie/ompa/blob/main/examples/mcp_desktop/README.md), [CLAUDE.md](https://github.com/jmiaie/ompa/blob/main/CLAUDE.md)

---

## Dual-Vault Mode

OMPA supports isolating team/organizational content from personal notes using a dual-vault architecture.

```python
from ompa import Ompa, DualVaultConfig, IsolationMode

config = DualVaultConfig(
    shared_vault="./team-vault",
    personal_vault="./private-vault",
    mode=IsolationMode.AUTO,
)

ao = Ompa(config=config)
```

### Isolation Modes

| Mode | Behavior |
|------|----------|
| `AUTO` | Content auto-classified to shared or personal vault based on message type |
| `STRICT` | Strict isolation, no cross-vault access |
| `MANUAL` | Explicit `VaultTarget` routing per operation |

### MCP Dual-Vault Configuration

```json
{
  "mcpServers": {
    "ompa": {
      "command": "python",
      "args": ["-m", "ompa.mcp_server"],
      "env": {
        "OMPA_SHARED_VAULT": "/path/to/shared-vault",
        "OMPA_PERSONAL_VAULT": "/path/to/personal-vault",
        "OMPA_ISOLATION_MODE": "auto"
      }
    }
  }
}
```

资料来源：[README.md](https://github.com/jmiaie/ompa/blob/main/README.md)

---

## Architecture Overview

```mermaid
graph TD
    A[AI Agent] --> B[OMPA Core]
    B --> C[Vault Layer]
    B --> D[Palace Layer]
    B --> E[Knowledge Graph]
    
    C --> C1[brain/]
    C --> C2[work/]
    C --> C3[org/]
    C --> C4[perf/]
    
    D --> D1[Wings]
    D --> D2[Rooms]
    D --> D3[Tunnels]
    
    E --> E1[SQLite DB]
    E --> E2[Temporal Triples]
    
    F[MCP Server] --> B
    F --> G[Claude Desktop]
    F --> H[Cursor]
    F --> I[Windsurf]
```

资料来源：[CLAUDE.md](https://github.com/jmiaie/ompa/blob/main/CLAUDE.md)

---

## Framework Compatibility

OMPA integrates with multiple AI agent frameworks:

| Agent Framework | Integration Method |
|-----------------|-------------------|
| Claude Code | Python API + MCP server |
| OpenClaw | Python API + MCP server |
| Codex | Python API + MCP server |
| Gemini CLI | Python API + MCP server |
| LangChain | Python API adapter |
| LlamaIndex | Python API adapter |

资料来源：[README.md](https://github.com/jmiaie/ompa/blob/main/README.md)

---

## Typical Session Workflow

```mermaid
graph LR
    A[Session Start] --> B[ao session-start]
    B --> C[Memory Context Injected]
    C --> D[Work Session]
    D --> E[ao classify]
    D --> F[ao search]
    D --> G[ao kg-query]
    E --> H[Notes Created]
    F --> H
    G --> H
    H --> I[Session End]
    I --> J[ao wrap-up]
    J --> K[Notes Persisted]
    K --> L[KG Updated]
```

1. **Start session**: `ao session-start` injects ~2K tokens of relevant context
2. **Classify messages**: `ao classify` routes content to appropriate folders
3. **Search**: `ao search` finds relevant past notes semantically
4. **Query KG**: `ao kg-query` retrieves entity relationships
5. **Wrap up**: `ao wrap-up` summarizes and persists everything

资料来源：[README.md](https://github.com/jmiaie/ompa/blob/main/README.md)

---

## Testing Your Installation

Run the test suite to verify everything works:

```bash
pytest tests/ -v
```

All 77+ tests should pass. Tests are located in `tests/test_ompa.py`.

资料来源：[CONTRIBUTING.md](https://github.com/jmiaie/ompa/blob/main/CONTRIBUTING.md)

---

## Next Steps

- **Explore CLI**: Run `ao --help` for all available commands
- **Configure MCP**: Set up your preferred AI assistant integration
- **Add message types**: Extend the classifier for custom routing 资料来源：[CONTRIBUTING.md](https://github.com/jmiaie/ompa/blob/main/CONTRIBUTING.md)
- **Add hooks**: Implement custom lifecycle hooks for your workflow
- **API stability**: Review [STABILITY.md](https://github.com/jmiaie/ompa/blob/main/STABILITY.md) for public API commitments

---

<a id='comparison'></a>

## Feature Comparison

### 相关页面

相关主题：[Introduction to OMPA](#introduction)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [README.md](https://github.com/jmiaie/ompa/blob/main/README.md)
- [CLAUDE.md](https://github.com/jmiaie/ompa/blob/main/CLAUDE.md)
- [STABILITY.md](https://github.com/jmiaie/ompa/blob/main/STABILITY.md)
- [CONTRIBUTING.md](https://github.com/jmiaie/ompa/blob/main/CONTRIBUTING.md)
- [examples/mcp_desktop/README.md](https://github.com/jmiaie/ompa/blob/main/examples/mcp_desktop/README.md)
- [ompa/classifier.py](https://github.com/jmiaie/ompa/blob/main/ompa/classifier.py)
- [ompa/mcp_server.py](https://github.com/jmiaie/ompa/blob/main/ompa/mcp_server.py)
- [ompa/core.py](https://github.com/jmiaie/ompa/blob/main/ompa/core.py)
</details>

# Feature Comparison

OMPA (Obsidian-MemPalace-Agnostic) is a memory management system for AI agents that provides persistent context injection, semantic search, temporal knowledge graphs, and palace-style memory navigation. This page compares the various features, components, and integration options available in the project.

## Architecture Overview

OMPA follows a dual-layer architecture where the **Vault** serves as the source of truth for notes, and the **Palace** provides retrieval acceleration through metadata organization.

```mermaid
graph TD
    A[Agent Session] --> B[Ompa Core]
    B --> C[Vault Layer]
    B --> D[Palace Layer]
    B --> E[Knowledge Graph]
    B --> F[Semantic Index]
    C --> G[brain/ work/ org/ perf/]
    D --> H[Wings → Rooms → Drawers]
    E --> I[SQLite Triples]
    F --> J[Local Embeddings]
```

资料来源：[CLAUDE.md](https://github.com/jmiaie/ompa/blob/main/CLAUDE.md)

## Core Components

### Package Structure

The codebase is organized into modular components, each handling a specific responsibility.

| Component | File | Purpose |
|-----------|------|---------|
| Core | `core.py` | Main class, lifecycle management, dual-vault support |
| Vault | `vault.py` | Note CRUD, folder structure, path traversal guards |
| Palace | `palace.py` | Wings/rooms/drawers metadata, tunnel navigation |
| Knowledge Graph | `knowledge_graph.py` | Temporal SQLite triples with validity windows |
| Semantic | `semantic.py` | Local embedding-based search with lazy model loading |
| Classifier | `classifier.py` | 15 message types with auto-routing |
| Hooks | `hooks.py` | 5 lifecycle hooks with HookManager |
| MCP Server | `mcp_server.py` | JSON-RPC protocol over stdin/stdout |
| CLI | `cli.py` | 14 typer commands |
| Config | `config.py` | DualVaultConfig, IsolationMode, VaultTarget |

资料来源：[README.md:70-83](https://github.com/jmiaie/ompa/blob/main/README.md)

## Installation Options

OMPA offers tiered installation to accommodate different use cases.

| Option | Command | Included Features |
|--------|---------|-------------------|
| Core | `pip install ompa` | Vault, palace, KG, CLI, MCP server |
| Full | `pip install ompa[all]` | Core + sentence-transformers + numpy (semantic search) |
| Dev | `pip install ompa[dev]` | Development dependencies |
| Source | `pip install -e ".[all]"` | Latest features from main branch |

资料来源：[README.md:52-60](https://github.com/jmiaie/ompa/blob/main/README.md)

### Environment Variables

| Variable | Default | Description |
|---|---|---|
| `OMPA_VAULT_PATH` | `.` | Absolute path to vault |
| `OMPA_ENABLE_SEMANTIC` | `false` | Enable local semantic search |
| `OMPA_AGENT_NAME` | `agent` | Agent name (scopes KG entries) |
| `OMPA_SHARED_VAULT` | — | Shared vault path (dual-vault mode) |
| `OMPA_PERSONAL_VAULT` | — | Personal vault path (dual-vault mode) |

资料来源：[examples/mcp_desktop/README.md](https://github.com/jmiaie/ompa/blob/main/examples/mcp_desktop/README.md)

## Dual-Vault Architecture

OMPA supports isolating team/organization content from personal or private notes through a dual-vault architecture.

### Isolation Modes

| Mode | Behavior |
|------|----------|
| `AUTO` | Content auto-classified to shared or personal vault based on message type |
| `MANUAL` | Explicit `VaultTarget` routing per operation |
| `STRICT` | Enforced separation with sanitization on export |

资料来源：[CHANGELOG.md:2026-04-10](https://github.com/jmiaie/ompa/blob/main/CHANGELOG.md)

### Configuration

```python
from ompa import Ompa, DualVaultConfig, IsolationMode

config = DualVaultConfig(
    shared_vault="./team-vault",
    personal_vault="./private-vault",
    mode=IsolationMode.AUTO,
)
ao = Ompa(config=config)
```

资料来源：[README.md:28-36](https://github.com/jmiaie/ompa/blob/main/README.md)

### Dual-Vault MCP Tools

| Tool | Purpose |
|------|---------|
| `ao_dual_vault_*` | Shared vault operations |
| Export | Cross-vault export with sanitization |
| Import | Cross-vault import |

资料来源：[CHANGELOG.md:2026-04-10](https://github.com/jmiaie/ompa/blob/main/CHANGELOG.md)

## Message Classification

The classifier categorizes incoming agent messages into 15 types with auto-routing.

### Message Types

| Type | Detected Patterns | Suggested Folder |
|------|-------------------|------------------|
| `DECISION` | ADR, agreed to, settled on, defer | org/decisions |
| `INCIDENT` | incident, outage, bug, crash, debug | work/incidents |
| `WIN` | won, shipped, launched, deployed | org/wins |
| `ONE_ON_ONE` | 1:1, check-in, feedback, career | personal/1on1 |
| `MEETING` | meeting, agenda, takeaways | work/meetings |
| `PROJECT_UPDATE` | project, initiative, blocked on | work/projects |
| `PERSON_INFO` | teammate, joined, role change | org/people |
| `QUESTION` | how do, what is, explain | brain/questions |
| `TASK` | task, todo, action item | work/tasks |
| `ARCHITECTURE` | architecture, design, ADR | org/architecture |
| `CODE` | function, class, PR, commit | work/code |
| `BRAIN_DUMP` | dump, stream, btw | brain/dumps |
| `WRAP_UP` | wrap up, end session | brain/sessions |
| `STANDUP` | standup, daily, morning | work/standups |
| `GENERAL` | Fallback for unmatched | brain/misc |

资料来源：[ompa/classifier.py](https://github.com/jmiaie/ompa/blob/main/ompa/classifier.py)

## CLI Commands

The `ao` CLI provides 14 commands for vault operations.

| Command | Description |
|---------|-------------|
| `ao init` | Initialize a new vault |
| `ao status` | Health check and statistics |
| `ao session-start` | Inject memory context (~2K tokens) |
| `ao classify <msg>` | Classify and route a message |
| `ao search <query>` | Semantic search |
| `ao orphans` | Detect orphaned notes |
| `ao wrap-up` | Session summary and save |
| `ao wings` | List palace wings |
| `ao rooms <wing>` | List rooms in a wing |
| `ao tunnel` | Create/traverse cross-wing tunnel |
| `ao kg-query <entity>` | Query knowledge graph |
| `ao kg-timeline <entity>` | Entity timeline |
| `ao kg-stats` | Knowledge graph statistics |
| `ao validate` | Validate vault structure |
| `ao rebuild-index` | Rebuild the semantic index |

资料来源：[README.md:42-57](https://github.com/jmiaie/ompa/blob/main/README.md)

## MCP Server Tools

The MCP server exposes 15 tools via JSON-RPC protocol over stdin/stdout.

### Tool List

| Tool | Category | Purpose |
|------|----------|---------|
| `ao_session_start` | Lifecycle | Session initialization |
| `ao_classify` | Classifier | Message classification |
| `ao_search` | Search | Semantic search in vault |
| `ao_kg_query` | KG | Entity query |
| `ao_kg_add` | KG | Add triple |
| `ao_kg_stats` | KG | KG statistics |
| `ao_kg_timeline` | KG | Entity timeline |
| `ao_kg_populate` | KG | Populate from vault |
| `ao_palace_wings` | Palace | List wings |
| `ao_palace_rooms` | Palace | List rooms |
| `ao_palace_tunnel` | Palace | Cross-wing navigation |
| `ao_validate` | Vault | Validate structure |
| `ao_wrap_up` | Lifecycle | Session wrap-up |
| `ao_status` | Vault | Health status |
| `ao_orphans` | Vault | Orphan detection |

资料来源：[ompa/mcp_server.py](https://github.com/jmiaie/ompa/blob/main/ompa/mcp_server.py)

### MCP Protocol Version

| Property | Value |
|----------|-------|
| Protocol Version | `2024-11-05` |
| Server Name | `ompa` |
| Transport | stdin/stdout JSON-RPC |

## Framework Compatibility

OMPA is designed to be framework-agnostic with no agent SDK dependencies.

| Agent Framework | Integration Method |
|---|---|
| Claude Code | Python API + MCP server |
| OpenClaw | Python API + MCP server |
| Codex | Python API + MCP server |
| Gemini CLI | Python API + MCP server |
| LangChain | Python API (adapters) |

资料来源：[README.md:88-94](https://github.com/jmiaie/ompa/blob/main/README.md)

### MCP Desktop Integration

| Desktop IDE | Configuration File |
|-------------|-------------------|
| Claude Desktop | `~/.claude/claude_desktop_config.json` |
| Cursor | `.cursor/mcp.json` |
| Windsurf | `.windsurf/mcp.json` |

资料来源：[examples/mcp_desktop/README.md](https://github.com/jmiaie/ompa/blob/main/examples/mcp_desktop/README.md)

## Lifecycle Hooks

OMPA provides 5 lifecycle hooks for extensibility.

| Hook | Trigger | Token Budget | Purpose |
|------|---------|--------------|---------|
| `session_start` | Session begin | 2000 | Context injection |
| `user_message` | Each user message | 100 | Pre-process hints |
| `post_tool` | After tool execution | 100 | Result capture |
| `pre_compact` | Before context compaction | 500 | Summary generation |
| `stop` | Session end | 200 | Persist and cleanup |

资料来源：[ompa/hooks.py](https://github.com/jmiaie/ompa/blob/main/ompa/hooks.py)

### Hook Data Structures

```python
HookResult(hook_name, success, output, tokens_hint, error)
HookContext(vault_path, session_id, timestamp, agent_name, memory)
```

资料来源：[STABILITY.md](https://github.com/jmiaie/ompa/blob/main/STABILITY.md)

## Knowledge Graph

### Data Model

```mermaid
graph LR
    A[Subject] -->|Predicate| B[Object]
    B -->|valid_from| C[Start Date]
    B -->|valid_to| D[End Date]
    B -->|confidence| E[Score]
    B -->|source| F[File]
```

### API Methods

| Method | Description |
|--------|-------------|
| `kg.add_triple()` | Add temporal triple |
| `kg.query_entity()` | Query entity relationships |
| `kg.timeline()` | Query entity history |
| `kg.populate_from_vault()` | Extract from notes |

资料来源：[ompa/core.py](https://github.com/jmiaie/ompa/blob/main/ompa/core.py)

## Semantic Search

### Features

| Feature | Description |
|---------|-------------|
| Incremental indexing | Tracks file modification times, re-embeds only changed notes |
| Lazy model loading | Model download deferred until first access |
| Local embeddings | No API calls required |

资料来源：[CHANGELOG.md:2026-04-08](https://github.com/jmiaie/ompa/blob/main/CHANGELOG.md)

## Stable APIs

The following APIs are guaranteed stable within major versions.

### Data Classes

```python
HookResult(hook_name, success, output, tokens_hint, error)
Classification(message_type, confidence, suggested_action, routing_hints)
SearchResult(path, content_excerpt, score, match_type)
Triple(subject, predicate, object, valid_from, valid_to, confidence, source_file)
SyncResult(success, backend, direction, files_changed, message, error, details)
```

资料来源：[STABILITY.md](https://github.com/jmiaie/ompa/blob/main/STABILITY.md)

### Enums

```python
MessageType      # 15 values: DECISION, INCIDENT, WIN, ...
IsolationMode    # AUTO, STRICT, MANUAL
VaultTarget      # SHARED, PERSONAL
```

## Security Features

| Feature | Implementation |
|---------|----------------|
| Path traversal protection | All vault file operations resolve and boundary-check paths |
| Dual-vault isolation | Content separation with sanitization |
| UTF-8 enforcement | Explicit encoding for all file writes |
| Security audit | 8/10 rating with 59/59 tests passing |

资料来源：[CHANGELOG.md:2026-04-11](https://github.com/jmiaie/ompa/blob/main/CHANGELOG.md)

## Python Version Requirements

| Version | Status |
|---------|--------|
| Python 3.10+ | Required |
| Earlier versions | Not supported |

资料来源：[README.md:65](https://github.com/jmiaie/ompa/blob/main/README.md)

---

<a id='three-layer-architecture'></a>

## Three-Layer Architecture

### 相关页面

相关主题：[Vault System](#vault-system), [Palace System](#palace-system), [Knowledge Graph](#knowledge-graph)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [ompa/core.py](https://github.com/jmiaie/ompa/blob/main/ompa/core.py)
- [ompa/vault.py](https://github.com/jmiaie/ompa/blob/main/ompa/vault.py)
- [ompa/palace.py](https://github.com/jmiaie/ompa/blob/main/ompa/palace.py)
- [ompa/knowledge_graph.py](https://github.com/jmiaie/ompa/blob/main/ompa/knowledge_graph.py)
- [ompa/classifier.py](https://github.com/jmiaie/ompa/blob/main/ompa/classifier.py)
- [ompa/config.py](https://github.com/jmiaie/ompa/blob/main/ompa/config.py)
- [ompa/cli.py](https://github.com/jmiaie/ompa/blob/main/ompa/cli.py)
</details>

# Three-Layer Architecture

OMPA implements a three-layer architecture designed for AI agent memory management. Each layer serves a distinct purpose while maintaining loose coupling through well-defined interfaces. This architecture separates storage (Vault), retrieval acceleration (Palace), and temporal relationship tracking (Knowledge Graph).

## Overview

The three layers work in concert to provide comprehensive memory capabilities for AI agents:

| Layer | Primary Role | Technology | Purpose |
|-------|--------------|------------|---------|
| **Vault** | Source of truth | File system (Markdown) | Persistent storage of notes and context |
| **Palace** | Retrieval acceleration | Metadata + indexing | Fast navigation through spatial metaphors |
| **Knowledge Graph** | Temporal relationships | SQLite | Track entity relationships over time |

资料来源：[README.md](https://github.com/jmiaie/ompa/blob/main/README.md)  
资料来源：[CLAUDE.md](https://github.com/jmiaie/ompa/blob/main/CLAUDE.md)

## Architecture Diagram

```mermaid
graph TB
    subgraph "Layer 1: Vault"
        V[Vault Manager]
        VF[Vault Folders<br/>brain/work/org/perf]
        VP[Path Traversal Guards]
    end
    
    subgraph "Layer 2: Palace"
        P[Palace Manager]
        PW[Wings/Rooms/Drawers]
        PT[Tunnels]
    end
    
    subgraph "Layer 3: Knowledge Graph"
        KG[Knowledge Graph]
        KGS[SQLite Triples]
        KGT[Temporal Validity Windows]
    end
    
    A[Agent/AI] --> C[Ompa Core]
    C --> V
    C --> P
    C --> KG
    
    V --> VF
    P --> PW
    KG --> KGS
    
    C --> CI[Classifier]
    CI --> VF
    
    style V fill:#e1f5fe
    style P fill:#fff3e0
    style KG fill:#e8f5e9
```

资料来源：[CLAUDE.md](https://github.com/jmiaie/ompa/blob/main/CLAUDE.md)

## Layer 1: Vault

The Vault layer serves as the source of truth for all memory content. Notes are stored as Markdown files with YAML frontmatter on the file system.

### Purpose and Scope

The Vault layer handles all CRUD operations for notes, enforces path security boundaries, and organizes content into logical folders based on message type classification. Every piece of information stored in OMPA ultimately lives in the Vault.

资料来源：[ompa/vault.py](https://github.com/jmiaie/ompa/blob/main/ompa/vault.py)

### Folder Structure

Notes are automatically routed to appropriate folders based on the `MessageType` classifier:

| Folder | Message Types | Content Category |
|--------|---------------|------------------|
| `brain/` | Brain-related | Core memories, session context |
| `work/` | Work-related | Professional decisions, projects |
| `org/` | Organization-related | Team information, processes |
| `perf/` | Performance-related | Metrics, evaluations |

资料来源：[CONTRIBUTING.md](https://github.com/jmiaie/ompa/blob/main/CONTRIBUTING.md)

### Security Features

All Vault file operations implement path traversal protection:

```python
def _safe_resolve(vault_root: str, file_path: str) -> Path:
    # Resolves path and validates it stays within vault boundary
    # Raises SecurityError if traversal detected
```

Path boundaries are checked before any file read or write operation, preventing unauthorized access to files outside the vault directory. 资料来源：[CHANGELOG.md](https://github.com/jmiaie/ompa/blob/main/CHANGELOG.md)

### Dual-Vault Mode

The Vault layer supports dual-vault isolation for separating personal and shared content:

```python
from ompa import DualVaultConfig, IsolationMode, VaultTarget

config = DualVaultConfig(
    shared_vault="./team-vault",
    personal_vault="./private-vault",
    mode=IsolationMode.AUTO,
)
```

**Isolation Modes:**

| Mode | Behavior |
|------|----------|
| `AUTO` | Content auto-classified based on message type |
| `MANUAL` | Explicit `VaultTarget` routing per operation |

资料来源：[README.md](https://github.com/jmiaie/ompa/blob/main/README.md)

## Layer 2: Palace

The Palace layer provides spatial organization and retrieval acceleration using the memory palace metaphor. It adds metadata structure on top of the Vault for fast navigation.

### Purpose and Scope

The Palace layer enables agents to navigate memories using spatial concepts (wings, rooms, drawers). This mirrors the ancient method of loci technique, proven effective for memory retrieval.

> "Verbatim storage: No summarization (proven 96.6% R@5 by MemPalace)"

资料来源：[CLAUDE.md](https://github.com/jmiaie/ompa/blob/main/CLAUDE.md)

### Palace Components

| Component | Description | Purpose |
|-----------|-------------|---------|
| **Wing** | Top-level organizational unit | Group related rooms |
| **Room** | Contains drawers and notes | Thematic organization |
| **Drawer** | Container within rooms | Fine-grained categorization |
| **Hall** | Cross-cutting collection | Shared resources |
| **Tunnel** | Connections between wings | Navigate across domains |

资料来源：[README.md](https://github.com/jmiaie/ompa/blob/main/README.md)

### Palace Operations

```python
# Create organizational structure
ao.palace.create_wing("Orion")
ao.palace.create_room("Orion", "decisions")
ao.palace.create_drawer("Orion", "decisions", "auth")

# Navigate with tunnels
ao.palace.create_tunnel("Orion", "Phoenix", room="shared")
```

### Relationship to Vault

The Palace layer does not store content directly—it maintains metadata references to Vault notes. This separation allows the Palace structure to evolve independently of note content.

```mermaid
graph LR
    V[Vault Notes] --> P[Palace Metadata]
    P --> P1[Wings/Rooms Index]
    P --> P2[Note References]
    
    S[Search Query] --> P
    P --> R[Matched Notes]
```

资料来源：[ompa/palace.py](https://github.com/jmiaie/ompa/blob/main/ompa/palace.py)

## Layer 3: Knowledge Graph

The Knowledge Graph layer maintains temporal relationships between entities using SQLite-backed triple storage.

### Purpose and Scope

The Knowledge Graph tracks facts about entities (subjects) and their relationships (predicates) to other entities (objects), with validity time windows for temporal queries.

> "Temporal KG: SQLite triples with validity windows"

资料来源：[CLAUDE.md](https://github.com/jmiaie/ompa/blob/main/CLAUDE.md)

### Data Model

Each triple consists of:

| Field | Type | Description |
|-------|------|-------------|
| `subject` | string | Source entity |
| `predicate` | string | Relationship type |
| `object` | string | Target entity |
| `valid_from` | datetime | Start of validity period |
| `valid_to` | datetime | End of validity period (nullable) |
| `source` | string | Origin of the fact |

### Knowledge Graph Operations

```python
# Add a fact with temporal validity
ao.kg.add_triple(
    subject="Kai",
    predicate="works_on",
    object="Orion",
    valid_from="2025-06-01"
)

# Query entity history
triples = ao.kg.query_entity("Kai")

# Get entity timeline
timeline = ao.kg.timeline("Orion")
```

### Temporal Queries

The Knowledge Graph supports querying state as of a specific point in time:

```python
# Query historical state
triples = ao.kg.query_entity("Kai", as_of="2025-07-15")
```

This enables agents to reason about past states of knowledge without needing to track version history manually.

## Layer Interactions

### Data Flow

```mermaid
sequenceDiagram
    participant A as Agent
    participant C as Ompa Core
    participant CL as Classifier
    participant V as Vault
    participant P as Palace
    participant KG as Knowledge Graph
    
    A->>C: handle_message("We decided...")
    C->>CL: classify(content)
    CL-->>C: Classification(WorkDecision)
    C->>V: save_note(WorkDecision)
    V-->>C: Note saved
    C->>P: update_structure(content)
    C->>KG: extract_entities(content)
    
    Note over C: Dual-vault routing<br/>applies if configured
```

### Content Lifecycle

1. **Ingestion**: Message arrives at `Ompa.handle_message()`
2. **Classification**: `Classifier` determines message type and routing
3. **Storage**: Note saved to appropriate Vault (shared or personal)
4. **Organization**: Palace metadata updated
5. **Relationship**: Entities extracted and added to Knowledge Graph

```mermaid
graph TD
    I[Ingest Message] --> C[Classify]
    C --> R{Routing Mode}
    R -->|AUTO| A[Auto-classify]
    R -->|MANUAL| M[Manual Target]
    A --> VT{Vault Target}
    M --> VT
    VT -->|Shared| VS[Write to Shared Vault]
    VT -->|Personal| VP[Write to Personal Vault]
    
    VS --> P[Update Palace]
    VP --> P
    P --> KG[Extract Entities]
    KG --> KGA[Add to KG]
```

### Search Integration

```mermaid
graph TD
    SQ[Search Query] --> C[Ompa Core]
    C -->|Semantic| SI[Semantic Index]
    C -->|Hybrid| H[Combine]
    C -->|KG| KGQ[KG Query]
    
    SI --> I[Incremental Index]
    H --> RE[Rank Results]
    KGQ --> RE
    
    RE --> R[Return Results]
```

The Semantic Index tracks file modification times and only re-embeds changed notes. 资料来源：[CHANGELOG.md](https://github.com/jmiaie/ompa/blob/main/CHANGELOG.md)

## Configuration

### Constructor Parameters

```python
from ompa import Ompa

ao = Ompa(
    vault_path="./workspace",           # Primary vault path
    agent_name="agent",                 # Scopes KG entries
    enable_semantic=True,              # Enable local semantic search
    embedding_backend=None,            # Custom embedding backend
    shared_vault_path=None,            # Dual-vault shared vault
    personal_vault_path=None,          # Dual-vault personal vault
    isolation_mode="strict",           # AUTO, MANUAL, or STRICT
)
```

### Environment Variables

| Variable | Default | Description |
|----------|---------|-------------|
| `OMPA_VAULT_PATH` | `.` | Absolute path to vault |
| `OMPA_ENABLE_SEMANTIC` | `false` | Enable local semantic search |
| `OMPA_AGENT_NAME` | `agent` | Agent name (scopes KG entries) |
| `OMPA_SHARED_VAULT` | — | Shared vault path (dual-vault mode) |
| `OMPA_PERSONAL_VAULT` | — | Personal vault path (dual-vault mode) |

资料来源：[examples/mcp_desktop/README.md](https://github.com/jmiaie/ompa/blob/main/examples/mcp_desktop/README.md)

## CLI Commands by Layer

| Command | Layer | Description |
|---------|-------|-------------|
| `ao init` | Vault | Initialize vault structure |
| `ao status` | Vault | Health check and stats |
| `ao classify <msg>` | Classifier | Classify and route message |
| `ao search <query>` | Palace/Semantic | Semantic search |
| `ao wings` | Palace | List palace wings |
| `ao rooms <wing>` | Palace | List rooms in wing |
| `ao tunnel` | Palace | Create/traverse tunnel |
| `ao kg-query <entity>` | Knowledge Graph | Query entity history |
| `ao kg-timeline <entity>` | Knowledge Graph | Entity timeline |
| `ao kg-stats` | Knowledge Graph | KG statistics |
| `ao orphans` | Vault | Detect orphaned notes |
| `ao validate` | Vault | Validate vault structure |
| `ao rebuild-index` | Palace/Semantic | Rebuild semantic index |

资料来源：[README.md](https://github.com/jmiaie/ompa/blob/main/README.md)

## Design Principles

The three-layer architecture adheres to the following principles documented in the project:

| Principle | Implementation |
|-----------|-----------------|
| **Lazy semantic loading** | `SemanticIndex._model` loaded on first access |
| **Framework-agnostic** | Pure Python, no agent SDK dependencies |
| **Verbatim storage** | No summarization—proven 96.6% R@5 on LongMemEval |
| **Path traversal guards** | All vault file ops resolve + boundary-check paths |
| **Context managers** | All SQLite connections use `with` for leak-free operation |

资料来源：[CLAUDE.md](https://github.com/jmiaie/ompa/blob/main/CLAUDE.md)

## See Also

- [API Stability](STABILITY.md) — Public API guarantees
- [MCP Server](ompa/mcp_server.py) — MCP protocol integration
- [CLI Reference](README.md) — Command reference
- [Contributing Guide](CONTRIBUTING.md) — Development setup

---

<a id='lifecycle-hooks'></a>

## Lifecycle Hooks

### 相关页面

相关主题：[Three-Layer Architecture](#three-layer-architecture), [Python API Reference](#python-api)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [ompa/hooks.py](https://github.com/jmiaie/ompa/blob/main/ompa/hooks.py)
- [ompa/core.py](https://github.com/jmiaie/ompa/blob/main/ompa/core.py)
- [CONTRIBUTING.md](https://github.com/jmiaie/ompa/blob/main/CONTRIBUTING.md)
- [CLAUDE.md](https://github.com/jmiaie/ompa/blob/main/CLAUDE.md)
- [STABILITY.md](https://github.com/jmiaie/ompa/blob/main/STABILITY.md)
</details>

# Lifecycle Hooks

## Overview

Lifecycle Hooks provide a plugin-based extensibility mechanism for the OMPA memory system. They allow developers to intercept and respond to key events during an agent session, such as session initialization, message handling, tool execution, context compaction, and shutdown.

Hooks operate as an event-driven layer between the `Ompa` core class and the underlying vault, knowledge graph, and palace subsystems. Each hook receives a `HookContext` containing session metadata and returns a `HookResult` with execution status and token budget information.

## Architecture

### Component Hierarchy

```mermaid
graph TD
    subgraph "Ompa Core"
        A[Ompa Instance] --> B[HookManager]
    end
    
    subgraph "Hook System"
        B --> C[SessionStartHook]
        B --> D[UserMessageHook]
        B --> E[PostToolHook]
        B --> F[PreCompactHook]
        B --> G[StopHook]
        B --> H[Custom Hooks]
    end
    
    subgraph "Hook Infrastructure"
        C --> I[HookContext]
        D --> I
        E --> I
        F --> I
        G --> I
        I --> J[HookResult]
    end
```

### Execution Flow

```mermaid
sequenceDiagram
    participant Agent
    participant Ompa as Ompa Core
    participant HookManager
    participant Hook as Concrete Hook
    
    Agent->>Ompa: session_start()
    Ompa->>HookManager: run_session_start(memory)
    HookManager->>HookContext: create context
    HookManager->>Hook: execute(context, **kwargs)
    Hook-->>HookManager: HookResult
    HookManager-->>Ompa: HookResult
    Ompa-->>Agent: context string (~2K tokens)
    
    Agent->>Ompa: handle_message(msg)
    Ompa->>HookManager: run_user_message(message)
    HookManager->>Hook: execute(context, message)
    Hook-->>HookManager: HookResult
```

## Core Data Models

### HookContext

Passed to every hook execution, providing runtime context.

| Parameter | Type | Description |
|-----------|------|-------------|
| `vault_path` | `Path` | Absolute path to the active vault |
| `session_id` | `str` | Session identifier in `YYYYMMDD_HHMMSS` format |
| `timestamp` | `datetime` | Session start time |
| `agent_name` | `str` | Name of the agent (default: `"agent"`) |
| `memory` | `dict` | Optional memory/context dictionary |

资料来源：[ompa/hooks.py:10-17]()

### HookResult

Return type from all hook executions.

| Parameter | Type | Description |
|-----------|------|-------------|
| `hook_name` | `str` | Name of the hook that produced this result |
| `success` | `bool` | Whether hook execution succeeded |
| `output` | `str` | Hook output (e.g., context string, summary) |
| `tokens_hint` | `int` | Estimated token count for LLM context |
| `error` | `str` | Optional error message if `success=False` |

资料来源：[ompa/hooks.py:19-23]()

### Hook (Base Class)

```python
class Hook(ABC):
    def __init__(self, name: str, token_budget: int = 200):
        self.name = name
        self.token_budget = token_budget
    
    @abstractmethod
    def execute(self, context: HookContext, **kwargs) -> HookResult:
        ...
```

资料来源：[ompa/hooks.py:3-12]()

## Default Hooks

OMPA ships with five built-in lifecycle hooks, each handling a specific phase of the agent session.

| Hook | Trigger | Token Budget | Purpose |
|------|---------|--------------|---------|
| `session_start` | `Ompa.session_start()` | 200 | Session initialization, context injection |
| `user_message` | `Ompa.handle_message()` | 50 | Message classification and routing |
| `post_tool` | `Ompa.post_tool()` | 50 | Tool execution logging |
| `pre_compact` | `Ompa.pre_compact()` | 200 | Context compression preparation |
| `stop` | `Ompa.stop()` / `Ompa.wrap_up()` | 200 | Session summary and persistence |

### SessionStartHook

Executes at session initialization. Collects vault statistics, knowledge graph status, and palace structure to build a ~2K token context for LLM injection.

```python
class SessionStartHook(Hook):
    def __init__(self):
        super().__init__("session_start", token_budget=200)
    
    def execute(self, context: HookContext, **kwargs) -> HookResult:
        # Collect brain notes count
        # Fetch KG stats (triple count)
        # Gather palace wing/room structure
        # Return context string for LLM injection
```

### StopHook

Executes during graceful shutdown. Generates a session summary, warns if the knowledge graph is empty, and persists state.

```python
class StopHook(Hook):
    def execute(self, context: HookContext, **kwargs) -> HookResult:
        lines = []
        lines.append(f"## Session {context.session_id} Summary")
        lines.append(f"Agent: {context.agent_name}")
        lines.append(f"Timestamp: {context.timestamp}")
        
        # KG health warning
        if kg_stats["triple_count"] == 0:
            lines.append("**WARNING:** KG is empty — run `ao kg-populate`")
        
        return HookResult(hook_name=self.name, success=True, output=output)
```

资料来源：[ompa/hooks.py:77-119]()

## HookManager

The `HookManager` class orchestrates hook registration and execution.

```python
class HookManager:
    def __init__(self, vault_path: str | Path, agent_name: str = "agent"):
        self.vault_path = Path(vault_path)
        self.agent_name = agent_name
        self.session_id = datetime.now().strftime("%Y%m%d_%H%M%S")
        self.timestamp = datetime.now()
        
        # Register default hooks
        self.hooks = {
            "session_start": SessionStartHook(),
            "user_message": UserMessageHook(),
            "post_tool": PostToolHook(),
            "pre_compact": PreCompactHook(),
            "stop": StopHook(),
        }
```

资料来源：[ompa/hooks.py:121-139]()

### Key Methods

| Method | Signature | Description |
|--------|-----------|-------------|
| `register_hook` | `register_hook(name: str, hook: Hook)` | Add or replace a hook |
| `unregister_hook` | `unregister_hook(name: str)` | Remove a hook |
| `run_session_start` | `run_session_start(memory=None)` | Execute session_start hooks |
| `run_user_message` | `run_user_message(message: str)` | Execute user_message hooks |
| `run_post_tool` | `run_post_tool(tool_name, tool_input)` | Execute post_tool hooks |
| `run_pre_compact` | `run_pre_compact(transcript: str)` | Execute pre_compact hooks |
| `run_stop` | `run_stop()` | Execute stop hooks |

## Integration with Ompa Core

The `Ompa` class exposes lifecycle methods that delegate to `HookManager`.

```mermaid
graph LR
    A[Ompa.session_start] --> B[HookManager.run_session_start]
    C[Ompa.handle_message] --> D[HookManager.run_user_message]
    E[Ompa.post_tool] --> F[HookManager.run_post_tool]
    G[Ompa.pre_compact] --> H[HookManager.run_pre_compact]
    I[Ompa.stop] --> J[HookManager.run_stop]
    
    B --> K[HookResult]
    D --> L[HookResult]
    F --> M[HookResult]
    H --> N[HookResult]
    J --> O[HookResult]
```

### Ompa Lifecycle Methods

| Method | Alias | Hook Triggered | Returns |
|--------|-------|-----------------|---------|
| `ao.session_start()` | `ao.standup()` | `session_start` | `HookResult` |
| `ao.handle_message(msg)` | — | `user_message` | `HookResult` |
| `ao.post_tool(name, input)` | — | `post_tool` | `HookResult` |
| `ao.pre_compact(transcript)` | — | `pre_compact` | `HookResult` |
| `ao.stop()` | `ao.wrap_up()` | `stop` | `HookResult` |

资料来源：[ompa/core.py](https://github.com/jmiaie/ompa/blob/main/ompa/core.py) (referenced in STABILITY.md)

## Custom Hooks

### Creating a Custom Hook

```python
from ompa.hooks import Hook, HookContext, HookResult

class MetricsHook(Hook):
    def __init__(self):
        super().__init__("metrics", token_budget=50)
    
    def execute(self, context: HookContext, **kwargs) -> HookResult:
        session_duration = datetime.now() - context.timestamp
        output = f"Session duration: {session_duration}"
        return HookResult(
            hook_name=self.name,
            success=True,
            output=output,
            tokens_hint=50
        )
```

### Registering Custom Hooks

```python
from ompa import Ompa

ao = Ompa("./workspace")
ao.hooks.register_hook("metrics", MetricsHook())
```

### Replacing Default Hooks

Override default hooks by registering with the same name:

```python
class CustomSessionStartHook(Hook):
    def __init__(self):
        super().__init__("session_start", token_budget=300)  # Higher budget
    
    def execute(self, context: HookContext, **kwargs) -> HookResult:
        # Custom session initialization
        return HookResult(
            hook_name=self.name,
            success=True,
            output="Custom context...",
            tokens_hint=300
        )

ao.hooks.register_hook("session_start", CustomSessionStartHook())
```

## Hook Execution Patterns

### Pattern: Always Execute

Hooks execute on every invocation unless an exception is raised:

```python
class PostToolHook(Hook):
    def execute(self, context: HookContext, **kwargs) -> HookResult:
        tool_name = kwargs.get("tool_name")
        tool_input = kwargs.get("tool_input", {})
        
        # Always log tool execution
        log_entry = f"[{context.session_id}] {tool_name}: {tool_input}"
        append_to_log(context.vault_path / "tools.log", log_entry)
        
        return HookResult(
            hook_name=self.name,
            success=True,
            output="Tool logged",
            tokens_hint=50
        )
```

### Pattern: Conditional Execution

Hooks can inspect context and conditionally produce output:

```python
class UserMessageHook(Hook):
    def execute(self, context: HookContext, **kwargs) -> HookResult:
        message = kwargs.get("message", "")
        
        if is_sensitive_content(message):
            return HookResult(
                hook_name=self.name,
                success=True,
                output="",  # No output for sensitive messages
                tokens_hint=0
            )
        
        # Normal processing for non-sensitive messages
        ...
```

## Configuration

### Token Budget

Each hook declares a `token_budget` indicating its expected output size for context window management:

| Budget | Use Case |
|--------|----------|
| 0-50 | Simple notifications, acknowledgments |
| 50-100 | Tool logs, message classifications |
| 200-300 | Session context, summaries |

### Agent Name Scoping

The `agent_name` parameter scopes knowledge graph entries and session identifiers:

```python
ao = Ompa(
    vault_path="./workspace",
    agent_name="coding-agent"
)

# HookContext will receive agent_name="coding-agent"
```

## API Stability

The hook system follows OMPA's semantic versioning policy. The following are considered stable:

- `Hook` base class (public interface)
- `HookContext` data class
- `HookResult` data class
- `HookManager.register_hook()` method

**Note:** Internal hook implementations (e.g., `*Hook` classes) may change. Use `HookManager.register_hook()` for custom hooks rather than subclassing internal implementations.

资料来源：[STABILITY.md](https://github.com/jmiaie/ompa/blob/main/STABILITY.md)

## CLI Integration

While hooks operate at the Python API level, they are invoked through CLI commands:

| CLI Command | Hook Invoked |
|-------------|--------------|
| `ao session-start` | `session_start` |
| `ao classify <msg>` | `user_message` |
| `ao wrap-up` | `stop` |
| `ao status` | `session_start` (read-only) |

## Error Handling

Hooks should return `HookResult` with `success=False` on failure:

```python
def execute(self, context: HookContext, **kwargs) -> HookResult:
    try:
        result = risky_operation()
        return HookResult(
            hook_name=self.name,
            success=True,
            output=str(result),
            tokens_hint=50
        )
    except Exception as e:
        logger.error("Hook %s failed: %s", self.name, e)
        return HookResult(
            hook_name=self.name,
            success=False,
            output="",
            error=str(e)
        )
```

The `HookManager` logs hook failures but continues execution of subsequent hooks.

---

<a id='vault-system'></a>

## Vault System

### 相关页面

相关主题：[Three-Layer Architecture](#three-layer-architecture), [Message Classification](#message-classification)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [ompa/vault.py](https://github.com/jmiaie/ompa/blob/main/ompa/vault.py)
- [ompa/core.py](https://github.com/jmiaie/ompa/blob/main/ompa/core.py)
- [ompa/config.py](https://github.com/jmiaie/ompa/blob/main/ompa/config.py)
- [ompa/semantic.py](https://github.com/jmiaie/ompa/blob/main/ompa/semantic.py)
- [ompa/knowledge_graph.py](https://github.com/jmiaie/ompa/blob/main/ompa/knowledge_graph.py)
- [examples/mcp_desktop/README.md](https://github.com/jmiaie/ompa/blob/main/examples/mcp_desktop/README.md)
</details>

# Vault System

## Overview

The Vault System is the core data persistence layer in OMPA (Obsidian-MemPalace-Agnostic). It provides structured storage for notes with a multi-category organization model, semantic indexing capabilities, and dual-vault isolation for separating personal and shared content.

**Primary Responsibilities:**
- Store and retrieve markdown notes with frontmatter metadata
- Enforce path traversal security boundaries
- Manage semantic search indices
- Support dual-vault architecture for content isolation
- Track knowledge graph relationships from note content

**资料来源：** [README.md](README.md)()

## Architecture

```mermaid
graph TD
    subgraph "Vault Layer"
        VAULT[Ompa.vault]
        BRAIN[Brain Notes]
        WORK[Work Notes]
        ORG[Org Notes]
        PERF[Performance Notes]
    end
    
    subgraph "Dual-Vault Mode"
        SHARED[Shared Vault]
        PERSONAL[Personal Vault]
        ISOLATION[IsolationMode]
    end
    
    subgraph "Index Layer"
        SEMANTIC[SemanticIndex]
        KG[KnowledgeGraph]
    end
    
    VAULT --> BRAIN
    VAULT --> WORK
    VAULT --> ORG
    VAULT --> PERF
    
    VAULT --> SEMANTIC
    VAULT --> KG
    
    VAULT --> SHARED
    VAULT --> PERSONAL
    SHARED --> ISOLATION
    PERSONAL --> ISOLATION
```

## Note Categories

The vault organizes notes into four primary categories based on content type and access patterns.

### Brain Notes

Personal knowledge, insights, and unstructured information. Brain notes form the foundation of the memory palace and are typically used for capturing ideas, learnings, and personal context.

**资料来源：** [ompa/vault.py](ompa/vault.py)()

### Work Notes

Notes related to professional activities, projects, and work-related decisions. These notes often contain sensitive business information.

**资料来源：** [ompa/vault.py](ompa/vault.py)()

### Org Notes

Organizational-level notes containing team decisions, processes, and shared knowledge that may be exported to the shared vault.

**资料来源：** [ompa/vault.py](ompa/vault.py)()

### Performance Notes

Time-bounded notes tracking performance metrics, goals, and accomplishments. These notes support the temporal knowledge graph features.

**资料来源：** [ompa/vault.py](ompa/vault.py)()

## Dual-Vault Architecture

The dual-vault architecture enables isolation between personal and shared content using `DualVaultConfig` and `IsolationMode`.

### Isolation Modes

| Mode | Behavior | Use Case |
|------|----------|----------|
| `AUTO` | Content auto-classified based on message type | Automated routing based on classifier results |
| `MANUAL` | Explicit `VaultTarget` routing per operation | User-controlled content placement |
| `STRICT` | Strict separation, no cross-vault operations | Maximum isolation requirements |

**资料来源：** [ompa/config.py](ompa/config.py)()

### Vault Targets

```mermaid
graph LR
    MSG[Message] --> CLASSIFY[Classifier]
    CLASSIFY --> TARGET{IsolationMode}
    TARGET -->|AUTO| AUTO[Auto-classify]
    TARGET -->|MANUAL| MANUAL[Manual VaultTarget]
    TARGET -->|STRICT| STRICT[Strict Mode]
    
    AUTO --> SHARED[Shared Vault]
    AUTO --> PERSONAL[Personal Vault]
    MANUAL --> SHARED
    MANUAL --> PERSONAL
```

### Configuration

```python
from ompa import Ompa, DualVaultConfig, IsolationMode

config = DualVaultConfig(
    shared_vault="./team-vault",
    personal_vault="./private-vault",
    mode=IsolationMode.AUTO,
)
ao = Ompa(config=config)
```

**资料来源：** [README.md](README.md)()

### Export/Sanitization

When exporting content from personal to shared vault, OMPA automatically sanitizes sensitive information:

- `sk-*` (OpenAI-style API keys)
- `AKIA*` (AWS access key IDs)
- `token:`, `password:`, `secret:`, `api_key:`, `api-key:` patterns

**资料来源：** [SECURITY_AUDIT.md](SECURITY_AUDIT.md)()

## Security: Path Traversal Protection

All vault file operations resolve and boundary-check paths against the vault root before proceeding. This prevents malicious or accidental file access outside the designated vault directory.

### Implementation

| Function | Purpose |
|----------|---------|
| `_safe_resolve(vault_root, user_path)` | Resolves path and validates boundaries |
| Path boundary checks | Raise `ValueError` if path escapes vault root |

**Flow:**
```mermaid
graph TD
    INPUT[User Path Input] --> RESOLVE[_safe_resolve]
    RESOLVE --> CHECK{Within Vault Root?}
    CHECK -->|Yes| PROCEED[Proceed with Operation]
    CHECK -->|No| REJECT[Raise ValueError]
```

**资料来源：** [CHANGELOG.md](CHANGELOG.md)(), [SECURITY_AUDIT.md](SECURITY_AUDIT.md)()

## Note Storage Format

Notes are stored as Markdown files with YAML frontmatter.

### Frontmatter Structure

```yaml
---
date: 2025-06-01
tags: [tag1, tag2]
vault: shared  # or "personal"
---
```

**Content follows frontmatter**

**资料来源：** [ompa/core.py](ompa/core.py)()

### File Naming

When creating notes automatically, the system:
1. Uses the classifier to determine the appropriate folder
2. Sanitizes content for filename generation
3. Creates a kebab-case filename from the first 40 characters

**资料来源：** [ompa/core.py](ompa/core.py)()

## Semantic Index

The `SemanticIndex` class provides local semantic search capabilities using sentence transformers.

### Lazy Initialization

The embedding model is not loaded until first access, preventing unnecessary downloads during import.

**资料来源：** [CHANGELOG.md](CHANGELOG.md)()

### Incremental Updates

The semantic index tracks file modification times and only re-embeds changed notes during rebuilds.

```mermaid
graph TD
    REBUILD[Rebuild Index] --> CHECK{File Changed?}
    CHECK -->|Modified| RE_EMBED[Re-embed Content]
    CHECK -->|Unchanged| SKIP[Skip File]
    RE_EMBED --> UPDATE[Update Index]
```

**资料来源：** [CHANGELOG.md](CHANGELOG.md)()

## Knowledge Graph Integration

The vault integrates with the temporal knowledge graph through automatic population from note content.

### Population Sources

| Source | Description |
|--------|-------------|
| Frontmatter tags | Extracted as entities |
| Folder paths | Used for context |
| Wikilinks `[[...]]` | Resolved as entity relationships |

**资料来源：** [CHANGELOG.md](CHANGELOG.md)()

### Triple Extraction

Notes automatically contribute triples to the knowledge graph with:
- Subject: Extracted entity
- Predicate: Relationship type
- Object: Related entity
- Validity window: Based on note dates

**资料来源：** [ompa/knowledge_graph.py](ompa/knowledge_graph.py)()

## CLI Commands

### Vault Operations

| Command | Description |
|---------|-------------|
| `ao init` | Initialize a new vault with required structure |
| `ao status` | Display vault health check and statistics |
| `ao validate` | Validate vault structure integrity |
| `ao orphans` | Detect notes with broken wikilinks |
| `ao rebuild-index` | Rebuild the semantic search index |

**资料来源：** [README.md](README.md)()

### Index and Search

| Command | Description |
|---------|-------------|
| `ao search <query>` | Perform semantic search across notes |
| `ao kg-query <entity>` | Query knowledge graph for entity |
| `ao kg-stats` | Display knowledge graph statistics |

**资料来源：** [README.md](README.md)()

## Environment Variables

| Variable | Default | Description |
|----------|---------|-------------|
| `OMPA_VAULT_PATH` | `.` | Absolute path to vault |
| `OMPA_SHARED_VAULT` | — | Shared vault path (dual-vault mode) |
| `OMPA_PERSONAL_VAULT` | — | Personal vault path (dual-vault mode) |
| `OMPA_ENABLE_SEMANTIC` | `false` | Enable local semantic search |

**资料来源：** [examples/mcp_desktop/README.md](examples/mcp_desktop/README.md)()

## MCP Server Integration

The vault is accessible through MCP (Model Context Protocol) tools when integrated with AI assistants.

### Available Tools

```python
ao_init         # Initialize vault
ao_status       # Health check
ao_write        # Write note to vault
ao_export       # Export between vaults
ao_import       # Import into vault
ao_orphans      # Detect orphaned notes
ao_validate     # Validate structure
```

**资料来源：** [ompa/mcp_server.py](ompa/mcp_server.py)()

## Encoding and Storage

All vault file writes explicitly enforce UTF-8 encoding to ensure cross-platform compatibility and proper handling of international characters.

**资料来源：** [CHANGELOG.md](CHANGELOG.md)()

## Class Hierarchy

```mermaid
classDiagram
    class Vault {
        +vault_path: str
        +notes: list~Note~
        +create_note()
        +read_note()
        +update_note()
        +delete_note()
        +list_notes()
    }
    
    class Note {
        +path: Path
        +frontmatter: dict
        +content: str
        +save()
        +load()
    }
    
    class SemanticIndex {
        +_model: EmbeddingModel
        +embed()
        +search()
        +rebuild()
    }
    
    class KnowledgeGraph {
        +add_triple()
        +query_entity()
        +populate_from_vault()
    }
    
    Vault --> Note
    Vault --> SemanticIndex
    Vault --> KnowledgeGraph
```

## Workflow: Session Lifecycle

```mermaid
graph TD
    START[Session Start] --> CONTEXT[ao.session_start]
    CONTEXT --> CLASSIFY[Message Classification]
    CLASSIFY --> HANDLE[ao.handle_message]
    HANDLE --> WRITE[Write to Vault]
    WRITE --> INDEX[Update Semantic Index]
    INDEX --> KG[Update Knowledge Graph]
    KG --> TOOL[Post-tool Hook]
    TOOL --> WRAP[ao.wrap_up]
    WRAP --> STOP[ao.stop]
```

**资料来源：** [ompa/core.py](ompa/core.py)(), [README.md](README.md)()

## Related Documentation

- [Core System](ompa/core.py) — Main Ompa class integrating vault
- [Classifier System](ompa/classifier.py) — Message classification and routing
- [Knowledge Graph](ompa/knowledge_graph.py) — Temporal triple storage
- [Semantic Search](ompa/semantic.py) — Local embedding-based search
- [MCP Server](ompa/mcp_server.py) — Protocol integration for AI assistants

---

<a id='palace-system'></a>

## Palace System

### 相关页面

相关主题：[Three-Layer Architecture](#three-layer-architecture), [Vault System](#vault-system)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [ompa/palace.py](https://github.com/jmiaie/ompa/blob/main/ompa/palace.py)
- [ompa/core.py](https://github.com/jmiaie/ompa/blob/main/ompa/core.py)
- [ompa/mcp_server.py](https://github.com/jmiaie/ompa/blob/main/ompa/mcp_server.py)
- [ompa/cli.py](https://github.com/jmiaie/ompa/blob/main/ompa/cli.py)
- [README.md](https://github.com/jmiaie/ompa/blob/main/README.md)
- [CLAUDE.md](https://github.com/jmiaie/ompa/blob/main/CLAUDE.md)
</details>

# Palace System

The Palace System is a metadata layer within OMPA (Obsidian-MemPalace-Agnostic) that provides retrieval acceleration for information stored in the vault. It operates on top of the Vault layer, which serves as the source of truth for all notes, to enable efficient navigation and traversal of memory structures.

## Overview

The Palace System implements a spatial metaphor for organizing and accessing notes, inspired by the memory palace technique. It provides hierarchical organizational structures (wings, rooms, drawers, halls) and traversal mechanisms (tunnels) that allow agents to navigate complex information spaces efficiently.

The system follows the architecture decision that the Vault serves as the source of truth while the Palace provides retrieval acceleration. This dual-layer design ensures data persistence alongside fast access patterns.

资料来源：[CLAUDE.md:3]()

## Architecture

```mermaid
graph TD
    subgraph OMPA["OMPA Core"]
        subgraph VaultLayer["Vault Layer"]
            V[Vault - Source of Truth]
        end
        subgraph PalaceLayer["Palace Layer - Retrieval Acceleration"]
            W[Wings]
            R[Rooms]
            D[Drawers]
            H[Halls]
            T[Tunnels]
        end
    end
    U[User/Agent] --> API
    API[CLI / MCP / Python API]
    API --> PalaceLayer
    PalaceLayer --> VaultLayer
```

### Core Components

| Component | Purpose | Storage |
|-----------|--------|---------|
| Wings | Top-level organizational units | SQLite metadata |
| Rooms | Sub-categories within wings | SQLite metadata |
| Drawers | Fine-grained containers | SQLite metadata |
| Halls | High-traffic connection paths | SQLite metadata |
| Tunnels | Cross-wing navigation shortcuts | SQLite metadata |

资料来源：[README.md:1]()

## Palace Metadata Storage

The Palace System uses SQLite for storing all metadata, with connections managed via context managers to prevent leaks. All temporal data supports validity windows, allowing the system to track how structures evolve over time.

```python
# Temporal KG with validity windows
# From ompa/knowledge_graph.py pattern
```

The architecture follows lazy semantic loading principles, where palace structures are initialized on first access rather than at import time.

资料来源：[CLAUDE.md:3]()

## Wing Management

Wings represent the top-level organizational units in the Palace System. Each wing can contain multiple rooms and serves as a primary navigation anchor.

### Creating Wings

```python
ao.palace.create_wing("Orion")
```

### Listing Wings

```python
wings = ao.palace.list_wings()
```

### Wing Operations via CLI

```bash
ao wings  # List all palace wings
```

资料来源：[README.md:1]()
资料来源：[ompa/cli.py](https://github.com/jmiaie/ompa/blob/main/ompa/cli.py)

## Room Management

Rooms are sub-categories that belong to specific wings. They provide a second level of hierarchy for organizing palace structures.

### Listing Rooms in a Wing

```python
rooms = ao.palace.list_rooms("Orion")
```

### Room Operations via CLI

```bash
ao rooms <wing>  # List rooms in a specific wing
```

资料来源：[README.md:1]()

## Tunnel System

Tunnels enable cross-wing navigation, creating shortcuts between different wings of the palace. This allows agents to traverse between seemingly unrelated areas efficiently.

### Creating Tunnels

```python
ao.palace.create_tunnel(wing_a, wing_b, room="shared")
```

### Tunnel Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| wing_a | str | Yes | Source wing identifier |
| wing_b | str | Yes | Target wing identifier |
| room | str | No | Room through which tunnel passes (default: "shared") |

### CLI Tunnel Command

```bash
ao tunnel  # Create/traverse cross-wing tunnel
```

资料来源：[README.md:1]()

## MCP Server Integration

The Palace System is exposed via the MCP (Model Context Protocol) server, allowing integration with AI agents like Claude Code, Cursor, and Windsurf.

### Available MCP Tools

| Tool Name | Function | Source |
|-----------|----------|--------|
| `ao_palace_wings` | List all palace wings | mcp_server.py:70-73 |
| `ao_palace_rooms` | List rooms in a wing | mcp_server.py:75-79 |
| `ao_palace_tunnel` | Create tunnel between wings | mcp_server.py:81-89 |

### MCP Configuration

```json
{
  "mcpServers": {
    "ompa": {
      "command": "python",
      "args": ["-m", "ompa.mcp_server"],
      "env": {
        "OMPA_VAULT_PATH": "/path/to/vault"
      }
    }
  }
}
```

资料来源：[examples/mcp_desktop/README.md:1]()

## CLI Commands

The Palace System can be accessed through the `ao` CLI utility:

```bash
# List all palace wings
ao wings

# List rooms in a specific wing
ao rooms <wing>

# Create or traverse a tunnel
ao tunnel
```

资料来源：[README.md:1]()

## Integration with Core OMPA

The Palace System is instantiated as part of the main `Ompa` class:

```python
from ompa import Ompa

ao = Ompa(vault_path="./workspace")
# Palace is available at ao.palace
wings = ao.palace.list_wings()
```

The `Ompa` class manages the lifecycle of the Palace instance, ensuring it shares the same vault path and configuration.

资料来源：[ompa/core.py:1]()

## Statistics and Monitoring

The Palace System provides statistics about its current state:

```python
# Via Python API
stats = ao.palace.stats()

# Via MCP
result = ao_palace_stats(vault_path)

# Via CLI (combined with vault and KG stats)
ao status
```

The status command returns a combined view of vault health, palace metadata, and knowledge graph statistics.

资料来源：[ompa/mcp_server.py:70-73]()

## Data Flow

```mermaid
sequenceDiagram
    participant User
    participant CLI
    participant MCP
    participant Ompa
    participant Palace
    participant Vault
    participant SQLite
    
    User->>CLI: ao wings
    CLI->>Ompa: list_wings()
    Ompa->>Palace: list_wings()
    Palace->>SQLite: Query wings metadata
    SQLite-->>Palace: Wing list
    Palace-->>Ompa: Wing list
    Ompa-->>CLI: Wing list
    CLI-->>User: Display wings
    
    User->>MCP: ao_palace_rooms(wing="Orion")
    MCP->>Ompa: list_rooms("Orion")
    Ompa->>Palace: list_rooms()
    Palace->>SQLite: Query rooms WHERE wing="Orion"
    SQLite-->>Palace: Room list
    Palace-->>Ompa: Room list
    Ompa-->>MCP: Room list
    MCP-->>User: Display rooms
```

## Design Principles

1. **Vault + Palace Dual-Layer**: The vault serves as the source of truth while the palace provides retrieval acceleration
2. **Context Managers**: All SQLite connections use `with` statements for leak-free operation
3. **Lazy Initialization**: Palace structures are loaded on first access rather than at import time
4. **Temporal Support**: Palace metadata supports validity windows for tracking structural changes over time

资料来源：[CLAUDE.md:3]()

## See Also

- [Vault System](vault.md) - Source of truth layer
- [Knowledge Graph](knowledge_graph.md) - Temporal triple storage
- [Classifier](classifier.md) - Message type classification and routing
- [MCP Server Setup](examples/mcp_desktop/README.md) - Agent integration guide

---

<a id='knowledge-graph'></a>

## Knowledge Graph

### 相关页面

相关主题：[Three-Layer Architecture](#three-layer-architecture), [Palace System](#palace-system)

<details>
<summary>Relevant Source Files</summary>

以下源码文件用于生成本页说明：

- [ompa/knowledge_graph.py](https://github.com/jmiaie/ompa/blob/main/ompa/knowledge_graph.py)
- [ompa/mcp_server.py](https://github.com/jmiaie/ompa/blob/main/ompa/mcp_server.py)
- [ompa/core.py](https://github.com/jmiaie/ompa/blob/main/ompa/core.py)
- [README.md](https://github.com/jmiaie/ompa/blob/main/README.md)
- [CLAUDE.md](https://github.com/jmiaie/ompa/blob/main/CLAUDE.md)
- [examples/mcp_desktop/README.md](https://github.com/jmiaie/ompa/blob/main/examples/mcp_desktop/README.md)
</details>

# Knowledge Graph

The Knowledge Graph (KG) is a core temporal data storage component in OMPA that maintains structured relationships between entities using SQLite-backed triple storage. It enables agents to query historical information, track entity validity windows, and maintain a persistent memory of facts across sessions.

## Overview

The Knowledge Graph stores facts as **triples** (subject, predicate, object) with temporal validity windows, allowing queries like "What was the state of X at time Y?" or "Show me all relationships involving entity Z."

| Property | Value |
|----------|-------|
| Storage Backend | SQLite |
| Data Model | RDF-like triples with validity windows |
| Temporal Support | `valid_from` / `valid_to` timestamps |
| Location | `~/.ompa/knowledge_graph.db` |
| Population | Auto-populates from vault notes and wikilinks |

资料来源：[CLAUDE.md](https://github.com/jmiaie/ompa/blob/main/CLAUDE.md)

## Architecture

```mermaid
graph TD
    A[Vault Notes] --> B[populate_from_vault]
    C[User Message] --> D[add_triple]
    B --> E[(SQLite DB)]
    D --> E
    E --> F[query_entity]
    E --> G[timeline]
    E --> H[get_predicates]
    E --> I[stats]
    F --> J[Triple Results]
    G --> K[Timeline View]
    I --> L[Statistics]
```

The KG operates as a layer above the vault, extracting structured data from unstructured notes and providing temporal query capabilities.

资料来源：[ompa/core.py:1-50](https://github.com/jmiaie/ompa/blob/main/ompa/core.py)

## Core Data Model

### Triple Structure

Each fact in the Knowledge Graph is stored as a triple with temporal metadata:

| Field | Type | Description |
|-------|------|-------------|
| `subject` | str | Entity name (e.g., "Kai", "Orion") |
| `predicate` | str | Relationship type (e.g., "works_on", "owns") |
| `object` | str | Target entity or value |
| `valid_from` | datetime | Start of validity period (nullable) |
| `valid_to` | datetime | End of validity period (nullable) |
| `source` | str | Note path that contained this fact |

### Temporal Validity Windows

The KG supports temporal reasoning through validity windows:

- **Point-in-time facts**: Both `valid_from` and `valid_to` set
- **Current facts**: Only `valid_from` set (open-ended)
- **Historical facts**: Both timestamps set to past dates

This enables queries like retrieving the state of relationships at any past point.

资料来源：[ompa/knowledge_graph.py](https://github.com/jmiaie/ompa/blob/main/ompa/knowledge_graph.py)

## KnowledgeGraph API

### Constructor

```python
class KnowledgeGraph:
    def __init__(self, vault_path: str = "~/.ompa"):
        self.db_path = Path(vault_path) / "knowledge_graph.db"
```

Initializes the KG with a database path under the OMPA config directory. The SQLite database is created automatically on first access.

资料来源：[ompa/knowledge_graph.py](https://github.com/jmiaie/ompa/blob/main/ompa/knowledge_graph.py)

### add_triple

Adds a new fact to the knowledge graph:

```python
def add_triple(
    self,
    subject: str,
    predicate: str,
    object_: str,
    valid_from: str | None = None,
    source: str | None = None,
) -> Triple:
```

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `subject` | str | Yes | Source entity |
| `predicate` | str | Yes | Relationship verb |
| `object_` | str | Yes | Target entity/value |
| `valid_from` | str | No | ISO date string for start validity |
| `source` | str | No | Source note path |

**Example:**
```python
kg.add_triple(
    subject="Kai",
    predicate="works_on",
    object_="Orion",
    valid_from="2025-06-01",
    source="brain/people/Kai.md"
)
```

资料来源：[ompa/knowledge_graph.py](https://github.com/jmiaie/ompa/blob/main/ompa/knowledge_graph.py)

### query_entity

Retrieves all triples involving a specific entity:

```python
def query_entity(self, entity: str) -> list[Triple]:
```

Returns all triples where the entity appears as subject or object. Results are ordered by validity window.

### timeline

Gets temporal history for an entity:

```python
def timeline(self, entity: str) -> list[dict]:
```

Returns a chronological view of all facts involving the entity, including temporal metadata for each relationship.

### get_predicates

Lists all relationship types in the graph:

```python
def get_predicates(self, subject: str | None = None) -> list[str]:
```

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `subject` | str | No | Filter predicates by subject |

### stats

Returns knowledge graph statistics:

```python
def stats(self) -> dict:
```

Returns:
| Stat | Description |
|------|-------------|
| `total_triples` | Total number of stored facts |
| `unique_subjects` | Count of unique source entities |
| `unique_predicates` | Count of unique relationship types |
| `unique_objects` | Count of unique target entities |

### populate_from_vault

Scans existing vault notes and extracts structured facts:

```python
def populate_from_vault(self, vault_path: str) -> dict:
```

Extracts entities from:
- Frontmatter tags
- Folder paths
- `[[wikilinks]]` cross-references

This enables automatic KG initialization from existing note content.

资料来源：[README.md](https://github.com/jmiaie/ompa/blob/main/README.md)

## MCP Server Integration

The Knowledge Graph is exposed through MCP tools for agent integration:

```mermaid
graph LR
    A[MCP Client] -->|ao_kg_add| B[Add Triple]
    A -->|ao_kg_query| C[Query Entity]
    A -->|ao_kg_stats| D[Get Stats]
    A -->|ao_kg_populate| E[Populate from Vault]
    B --> F[KnowledgeGraph]
    C --> F
    D --> F
    E --> F
```

### Available MCP Tools

| Tool | Parameters | Description |
|------|------------|-------------|
| `ao_kg_add` | `subject`, `predicate`, `object_`, `valid_from?`, `source?` | Add a fact |
| `ao_kg_query` | `entity` | Query entity relationships |
| `ao_kg_stats` | — | Get KG statistics |

资料来源：[ompa/mcp_server.py:1-50](https://github.com/jmiaie/ompa/blob/main/ompa/mcp_server.py)

### MCP Tool Implementation

```python
def ao_kg_add(arguments: dict, vault_path: str = ".") -> dict:
    """Add a triple to the knowledge graph."""
    ao = Ompa(vault_path=vault_path, enable_semantic=False)
    ao.kg.add_triple(
        subject=arguments["subject"],
        predicate=arguments["predicate"],
        object_=arguments["object"],
        valid_from=arguments.get("valid_from"),
        source=arguments.get("source"),
        vault_path=vault_path,
    )
    return {"success": True, "added": f"{subject} --{predicate}--> {object_}"}

def ao_kg_stats(vault_path: str = ".") -> dict:
    """Get knowledge graph statistics."""
    ao = Ompa(vault_path=vault_path, enable_semantic=False)
    return ao.kg.stats()
```

资料来源：[ompa/mcp_server.py:50-100](https://github.com/jmiaie/ompa/blob/main/ompa/mcp_server.py)

## Usage Examples

### Python API

```python
from ompa import Ompa

ao = Ompa(vault_path="./workspace")

# Add facts
ao.kg.add_triple("Kai", "works_on", "Orion", valid_from="2025-06-01")
ao.kg.add_triple("Orion", "has_status", "active")
ao.kg.add_triple("Kai", "reports_to", "Sarah")

# Query entity
triples = ao.kg.query_entity("Kai")
# Returns: [Triple(subject='Kai', predicate='works_on', object_='Orion', ...), ...]

# Get timeline
timeline = ao.kg.timeline("Kai")
# Returns chronological history of all Kai-related facts

# Get statistics
stats = ao.kg.stats()
# Returns: {'total_triples': 3, 'unique_subjects': 2, 'unique_predicates': 3, ...}
```

### CLI Usage

```bash
# Query entity in knowledge graph
ao kg-query Kai

# Get entity timeline
ao kg-timeline Orion

# Get knowledge graph statistics
ao kg-stats
```

### MCP Integration

In Claude Desktop or Cursor, the KG tools are available as:

```json
{
  "mcpServers": {
    "ompa": {
      "command": "python",
      "args": ["-m", "ompa.mcp_server"],
      "env": {
        "OMPA_VAULT_PATH": "/absolute/path/to/vault"
      }
    }
  }
}
```

资料来源：[examples/mcp_desktop/README.md](https://github.com/jmiaie/ompa/blob/main/examples/mcp_desktop/README.md)

## Relationship to Other Components

```mermaid
graph TD
    subgraph OMPA Core
        A[Ompa Class] --> B[KnowledgeGraph]
        A --> C[Vault]
        A --> D[SemanticIndex]
        A --> E[Palace]
    end
    
    B --> F[(SQLite DB)]
    C --> G[Markdown Notes]
    D --> H[Sentence Embeddings]
    E --> I[Metadata Cache]
    
    J[MCP Server] --> B
    J --> C
    J --> D
    J --> E
```

| Component | Relationship | Data Flow |
|-----------|--------------|-----------|
| **Vault** | Source of truth | KG populates from vault wikilinks and tags |
| **SemanticIndex** | Companion retrieval | KG + Index together enable hybrid search |
| **Palace** | Metadata layer | Palace stores spatial metadata for navigation |
| **Classifier** | Auto-tagging | Classifier helps route content to vault locations |

The Knowledge Graph complements the vault by adding structure to unstructured note content.

资料来源：[ompa/core.py:1-100](https://github.com/jmiaie/ompa/blob/main/ompa/core.py)

## Security Considerations

- **Path traversal guards**: All vault file operations resolve and boundary-check paths
- **SQLite isolation**: Each KG instance uses separate database file
- **Source tracking**: Every triple records its source note for auditability

资料来源：[CHANGELOG.md](https://github.com/jmiaie/ompa/blob/main/CHANGELOG.md)

## Changelog

| Version | Date | Change |
|---------|------|--------|
| 0.4.0 | 2026-04-10 | Added `populate_from_vault()` for auto-extraction |
| 0.3.0 | 2026-04-08 | Initial KG implementation with temporal windows |
| 0.3.1 | 2026-04-09 | Bug fixes in wikilink resolution |

资料来源：[CHANGELOG.md](https://github.com/jmiaie/ompa/blob/main/CHANGELOG.md)

---

<a id='message-classification'></a>

## Message Classification

### 相关页面

相关主题：[Vault System](#vault-system), [Python API Reference](#python-api)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [ompa/classifier.py](https://github.com/jmiaie/ompa/blob/main/ompa/classifier.py)
- [ompa/core.py](https://github.com/jmiaie/ompa/blob/main/ompa/core.py)
- [CLAUDE.md](https://github.com/jmiaie/ompa/blob/main/CLAUDE.md)
- [CONTRIBUTING.md](https://github.com/jmiaie/ompa/blob/main/CONTRIBUTING.md)
- [STABILITY.md](https://github.com/jmiaie/ompa/blob/main/STABILITY.md)
</details>

# Message Classification

Message Classification is a core feature of OMPA that automatically categorizes incoming messages into 15 distinct types and routes them to appropriate locations within the vault structure. This system enables intelligent, automated memory management for AI agents working across different contexts.

## Overview

The classifier uses regex pattern matching to identify message types based on linguistic cues, then provides routing hints to guide content placement. It integrates deeply with the vault architecture, suggesting target folders and actions for each classified message type.

资料来源：[ompa/classifier.py:1-50]()

## Architecture

```mermaid
graph TD
    A[Incoming Message] --> B[Classifier.classify]
    B --> C{Pattern Matching}
    C -->|Decision| D[MessageType.DECISION]
    C -->|Incident| E[MessageType.INCIDENT]
    C -->|Meeting| F[MessageType.MEETING]
    C -->|Win| G[MessageType.WIN]
    C -->|...| H[Other Types]
    
    D --> I[Routing Hints]
    E --> I
    F --> I
    G --> I
    H --> I
    
    I --> J[Suggested Folder]
    I --> K[Suggested Action]
    
    J --> L[Vault Storage]
    K --> M[Knowledge Graph]
```

资料来源：[ompa/classifier.py:60-120]()

## Message Types

OMPA defines 15 distinct `MessageType` values for classifying different kinds of agent communications:

| Message Type | Purpose | Suggested Folder |
|--------------|---------|------------------|
| `DECISION` | Architectural or team decisions | `brain/` |
| `INCIDENT` | Outages, bugs, failures, debugging | `work/incidents/` |
| `WIN` | Achievements, successes, milestones | `perf/` |
| `ONE_ON_ONE` | Manager/peer check-ins | `work/1-1/` |
| `MEETING` | Meeting notes and takeaways | `work/meetings/` |
| `PROJECT_UPDATE` | Project status changes | `work/active/` |
| `PERSON_INFO` | Team member information | `org/people/` |
| `QUESTION` | Clarifying questions | `brain/questions/` |
| `TASK` | Action items and todos | `work/tasks/` |
| `ARCHITECTURE` | System design decisions | `brain/architecture/` |
| `CODE` | Code-related discussions | `work/code/` |
| `BRAIN_DUMP` | Stream of consciousness notes | `brain/dumps/` |
| `WRAP_UP` | Session end summaries | `brain/sessions/` |
| `STANDUP` | Daily standup entries | `work/standups/` |
| `GENERAL` | Uncategorized content | `brain/` |

资料来源：[ompa/classifier.py:1-30]()
资料来源：[CLAUDE.md:1-20]()

## Pattern Matching System

The classifier uses regex patterns to identify message types. Each `MessageType` has an associated list of regex patterns:

```python
PATTERNS = {
    MessageType.DECISION: [
        r"\b(decided|decision|made a choice|going with|settled on|agreed to)\b",
        r"\b(defer|postpone|push to|revisit)\b.*\b(Q\d|quarter|sprint)\b",
        r"(?:ADR|decision record)",
    ],
    MessageType.INCIDENT: [
        r"\b(incident|outage|bug|crash|failure|error|broken)\b",
        r"\b(debug|root cause|RCA|mitigation|hotfix)\b",
        r"(?:on-call|pagerduty|statuspage)",
    ],
    MessageType.WIN: [
        r"\b(won|praised|success|achieved|shipped|launched|deployed)\b",
        r"\b(great work|nice job|excellent|well done)\b",
        r"\b(milestone|feature complete|released)\b",
    ],
    # ... additional patterns
}
```

资料来源：[ompa/classifier.py:30-100]()

### Pattern Priority

Patterns are evaluated in order, and the first matching pattern determines the message type. This allows for specific patterns to take precedence over general ones.

## Routing Hints

Each message type includes `ROUTING_HINTS` that provide guidance on how to handle classified content:

```python
ROUTING_HINTS = {
    MessageType.DECISION: [
        "This is a decision. Record it in brain/Key Decisions.md",
        "Update relevant project notes with the decision",
        "Add to Decision Log if formal ADR needed",
    ],
    MessageType.INCIDENT: [
        "Create incident note in work/incidents/",
        "Run /om-incident-capture for structured capture",
        "Update brain/Gotchas.md with lessons learned",
    ],
    MessageType.WIN: [
        "Add to perf/Brag Doc.md immediately",
        "This is a win worth capturing for performance review",
        "Update relevant competency notes with evidence",
    ],
    # ... additional hints
}
```

资料来源：[ompa/classifier.py:100-180]()

## Classification API

### Core Classification Method

```python
from ompa.classifier import Classifier, Classification

classifier = Classifier()
result: Classification = classifier.classify("We decided to go with Postgres")
```

### Return Type

The `classify()` method returns a `Classification` object containing:

| Field | Type | Description |
|-------|------|-------------|
| `message_type` | `MessageType` | The identified message type |
| `confidence` | `float` | Confidence score (0.0 - 1.0) |
| `routing_hints` | `List[str]` | Actionable suggestions |
| `suggested_folder` | `str` | Target folder for storage |

资料来源：[ompa/classifier.py:120-150]()
资料来源：[STABILITY.md:10-20]()

## Dual-Vault Integration

When running in dual-vault mode, the classifier also supports content classification for vault routing:

```python
from ompa.config import DualVaultConfig, IsolationMode

config = DualVaultConfig(
    shared_vault="./team-vault",
    personal_vault="./private-vault",
    mode=IsolationMode.AUTO,
)

target = config.classify_content(content, tags=tags, file_path=path)
```

资料来源：[ompa/core.py:50-80]()

### Classification Factors

Content is classified to shared or personal vaults based on:

1. **Content analysis** - Keywords indicating personal vs. work content
2. **Tags** - Frontmatter tags that may indicate classification
3. **File path** - Existing location hints in vault structure

## Adding Custom Message Types

To extend the classifier with new message types, follow this process:

### Step 1: Add Enum Value

```python
# ompa/classifier.py
class MessageType(str, Enum):
    # ... existing types
    YOUR_NEW_TYPE = "your_new_type"
```

### Step 2: Add Regex Patterns

```python
PATTERNS[MessageType.YOUR_NEW_TYPE] = [
    r"\b(keyword1|keyword2)\b",
    r"\b(phrase pattern)\b",
]
```

### Step 3: Add Routing Hints

```python
ROUTING_HINTS[MessageType.YOUR_NEW_TYPE] = [
    "Action hint 1",
    "Action hint 2",
]
```

### Step 4: Add Folder Mapping

```python
FOLDER_MAP[MessageType.YOUR_NEW_TYPE] = "brain/your-type/"
```

### Step 5: Add Tests

```python
# tests/test_ompa.py
class TestClassifier:
    def test_your_new_type(self):
        # Add test cases
```

资料来源：[CONTRIBUTING.md:20-40]()

## CLI Integration

The classifier is accessible via the CLI:

```bash
# Classify a single message
ao classify "We decided to go with Postgres"

# Classify with context
ao classify "The deployment failed with a timeout error"
```

## MCP Tools

The following MCP tools expose classification functionality:

| Tool | Purpose |
|------|---------|
| `ao_classify` | Classify a message and return routing hints |

资料来源：[ompa/mcp_server.py:1-30]()

## Confidence Scoring

The classifier assigns confidence scores based on:

1. **Pattern match count** - More pattern matches = higher confidence
2. **Pattern specificity** - More specific patterns score higher
3. **Keyword density** - Higher density of type-specific keywords

Confidence is normalized to a 0.0-1.0 range for downstream processing.

## Extensibility Points

The classification system can be extended through:

1. **Custom patterns** - Add regex patterns per message type
2. **Custom routing hints** - Extend action suggestions
3. **Custom folders** - Define target locations per type
4. **Hook integration** - Execute hooks on classification events

资料来源：[CLAUDE.md:30-50]()

## Data Flow

```mermaid
sequenceDiagram
    participant User
    participant CLI as CLI/API
    participant Classifier
    participant Vault
    participant KG as Knowledge Graph
    
    User->>CLI: ao classify "message"
    CLI->>Classifier: classify(message)
    Classifier->>Classifier: Pattern matching
    Classifier-->>CLI: Classification result
    CLI-->>User: Type + routing hints
    
    User->>CLI: ao handle_message "message"
    CLI->>Classifier: classify(message)
    Classifier-->>CLI: Classification + folder
    CLI->>Vault: Save to suggested folder
    CLI->>KG: Add extracted entities
    Vault-->>CLI: Note saved
    KG-->>CLI: Triples added
```

This comprehensive classification system enables OMPA to automatically organize agent communications, maintain structured memory, and provide intelligent routing for all types of work content.

---

<a id='python-api'></a>

## Python API Reference

### 相关页面

相关主题：[Lifecycle Hooks](#lifecycle-hooks)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [ompa/core.py](https://github.com/jmiaie/ompa/blob/main/ompa/core.py)
- [ompa/__init__.py](https://github.com/jmiaie/ompa/blob/main/ompa/__init__.py)
- [ompa/config.py](https://github.com/jmiaie/ompa/blob/main/ompa/config.py)
- [ompa/async_api.py](https://github.com/jmiaie/ompa/blob/main/ompa/async_api.py)
</details>

# Python API Reference

The Python API provides programmatic access to OMPA's core functionality, enabling integration with AI agents, custom workflows, and external applications. The API is designed around the `Ompa` class as the primary entry point, offering lifecycle management, semantic search, knowledge graph operations, and dual-vault isolation.

---

## Installation and Setup

```bash
# Core package
pip install ompa

# With semantic search (sentence-transformers)
pip install ompa[all]

# Development installation
pip install ompa[dev]
```

Requires Python 3.10 or higher.

---

## Core Class: `Ompa`

The `Ompa` class is the main interface for all OMPA operations. It manages the vault, palace, knowledge graph, and lifecycle hooks.

### Constructor

```python
from ompa import Ompa

ao = Ompa(
    vault_path="./workspace",
    agent_name="agent",
    enable_semantic=True,
    embedding_backend=None,
    shared_vault_path=None,
    personal_vault_path=None,
    isolation_mode="strict",
)
```

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `vault_path` | `str` | `"."` | Absolute path to vault directory |
| `agent_name` | `str` | `"agent"` | Agent identifier for KG scoping |
| `enable_semantic` | `bool` | `True` | Enable semantic search functionality |
| `embedding_backend` | `EmbeddingBackend \| None` | `None` | Custom embedding backend |
| `shared_vault_path` | `str \| None` | `None` | Path for shared vault (dual-vault mode) |
| `personal_vault_path` | `str \| None` | `None` | Path for personal vault (dual-vault mode) |
| `isolation_mode` | `IsolationMode \| str` | `"strict"` | Vault isolation mode |

资料来源：[STABILITY.md](https://github.com/jmiaie/ompa/blob/main/STABILITY.md)()

### Alternative Constructor: Dual-Vault Configuration

```python
from ompa import Ompa, DualVaultConfig, IsolationMode

config = DualVaultConfig(
    shared_vault="./team-vault",
    personal_vault="./private-vault",
    mode=IsolationMode.AUTO,
)
ao = Ompa(config=config)
```

---

## Lifecycle Methods

The lifecycle API manages session boundaries and hook execution for AI agent memory integration.

```mermaid
graph TD
    A[session_start] --> B[handle_message / post_tool]
    B --> C[pre_compact]
    C --> D[stop / wrap_up]
    D --> E[Session Complete]
```

### `session_start()`

Injects memory context at the start of an agent session.

```python
result = ao.session_start()
```

**Returns:** `HookResult` — Contains `success`, `output`, and `tokens_hint` fields.

**Output:** Approximately 2,000 token context string with session history.

资料来源：[README.md](https://github.com/jmiaie/ompa/blob/main/README.md)()

### `handle_message(message: str)`

Process and classify an incoming message.

```python
result = ao.handle_message("We decided to go with Postgres")
```

**Parameters:**

| Parameter | Type | Description |
|-----------|------|-------------|
| `message` | `str` | The message content to classify |

**Returns:** `HookResult`

资料来源：[ompa/core.py](https://github.com/jmiaie/ompa/blob/main/ompa/core.py)()

### `post_tool(tool_name: str, tool_input: dict)`

Execute after a tool call to record the action.

```python
result = ao.post_tool("write", {"file_path": "work/active/auth.md"})
```

**Parameters:**

| Parameter | Type | Description |
|-----------|------|-------------|
| `tool_name` | `str` | Name of the executed tool |
| `tool_input` | `dict` | Tool input parameters |

**Returns:** `HookResult`

### `pre_compact(transcript: str)`

Called before context compaction (context window reduction).

```python
result = ao.pre_compact(transcript)
```

**Parameters:**

| Parameter | Type | Description |
|-----------|------|-------------|
| `transcript` | `str` | Full session transcript |

**Returns:** `HookResult`

### `stop()` / `wrap_up()`

End the session and persist state. `wrap_up()` is an alias for `stop()`.

```python
result = ao.stop()
# or
result = ao.wrap_up()
```

**Returns:** `HookResult` with session summary and persistence status.

### `standup()`

Alias for `session_start()`. Provides symmetry with `wrap_up()`.

```python
result = ao.standup()
```

---

## Search API

### `search(query, limit, hybrid, wing, room, vaults)`

Perform semantic search across vault notes.

```python
results = ao.search(
    "authentication decisions",
    limit=10,
    hybrid=True,
    wing="Orion",
    room=None,
    vaults=None
)
```

**Parameters:**

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `query` | `str` | Required | Search query string |
| `limit` | `int` | `5` | Maximum results to return |
| `hybrid` | `bool` | `False` | Enable hybrid keyword + semantic search |
| `wing` | `str \| None` | `None` | Filter by palace wing |
| `room` | `str \| None` | `None` | Filter by palace room |
| `vaults` | `list[str] \| None` | `None` | Target specific vaults |

**Returns:** `list[SearchResult]` — List of matching notes with relevance scores.

**Cost:** Zero API cost (local semantic search).

资料来源：[README.md](https://github.com/jmiaie/ompa/blob/main/README.md)()

### `rebuild_index()`

Rebuild the semantic index from vault contents.

```python
count = ao.rebuild_index()
```

**Returns:** `int` — Number of notes indexed.

---

## Classification API

### `classify(message: str)`

Classify a message into one of 15 message types.

```python
classification = ao.classify("We decided to go with Postgres")
```

**Returns:** `Classification` — Contains `message_type`, `confidence`, `suggested_folder`, and routing hints.

### `get_routing_hint(message: str)`

Get routing hints for a message.

```python
hint = ao.get_routing_hint("We won the enterprise deal!")
```

**Returns:** `str` — Routing hint for vault placement.

---

## Knowledge Graph API

The temporal knowledge graph stores entity relationships with validity windows.

```mermaid
graph LR
    A[Subject] -->|Predicate| B[Object]
    B -->|valid_from| C[Start Date]
    B -->|valid_to| D[End Date]
```

### `kg.add_triple(subject, predicate, object, valid_from, source)`

Add a triple to the knowledge graph.

```python
ao.kg.add_triple(
    "Kai",
    "works_on",
    "Orion",
    valid_from="2025-06-01",
    source="session"
)
```

**Parameters:**

| Parameter | Type | Description |
|-----------|------|-------------|
| `subject` | `str` | Source entity |
| `predicate` | `str` | Relationship type |
| `object` | `str` | Target entity |
| `valid_from` | `str \| None` | Validity start date (YYYY-MM-DD) |
| `valid_to` | `str \| None` | Validity end date (YYYY-MM-DD) |
| `source` | `str \| None` | Source of this knowledge |

### `kg.query_entity(entity, as_of)`

Query an entity's history at a point in time.

```python
triples = ao.kg.query_entity("Kai")
```

**Parameters:**

| Parameter | Type | Description |
|-----------|------|-------------|
| `entity` | `str` | Entity name to query |
| `as_of` | `str \| None` | Point-in-time filter (YYYY-MM-DD) |

**Returns:** `list[Triple]` — All triples involving the entity.

### `kg.timeline(entity)`

Get timeline of an entity's relationships.

```python
timeline = ao.kg.timeline("Orion")
```

**Returns:** `list[dict]` — Chronological relationship history.

### `kg.stats()`

Get knowledge graph statistics.

```python
stats = ao.kg.stats()
```

**Returns:** `dict` — Contains `triple_count`, `entity_count`, `predicate_types`, etc.

---

## Palace API

The palace provides spatial organization for memories using a metaphor of wings, rooms, drawers, halls, and tunnels.

### `palace.create_wing(name)`

Create a new wing.

```python
ao.palace.create_wing("Orion")
```

### `palace.list_wings()`

List all wings.

```python
wings = ao.palace.list_wings()
```

### `palace.create_tunnel(wing_a, wing_b, room)`

Create a cross-wing tunnel for navigation.

```python
ao.palace.create_tunnel("Alpha", "Beta", "Central Hub")
```

### `palace.stats()`

Get palace statistics.

```python
stats = ao.palace.stats()
```

---

## Vault API

### `get_stats()`

Get vault statistics.

```python
stats = ao.get_stats()
```

**Returns:** `dict` containing:

| Field | Type | Description |
|-------|------|-------------|
| `total_notes` | `int` | Total note count |
| `brain_notes` | `int` | Brain note count |
| `by_folder` | `dict` | Notes per folder |

### `write(content, file_path, tags, vault)`

Write a note to the vault.

```python
result = ao.write(
    content="# Decision\n\nUsing PostgreSQL",
    file_path="work/active/db-choice.md",
    tags=["decision", "database"],
    vault=None
)
```

### `export_to_shared(note_path, confirm, sanitize)`

Export a note from personal vault to shared vault.

```python
result = ao.export_to_shared(
    note_path="work/active/auth.md",
    confirm=True,
    sanitize=True
)
```

### `import_to_personal(note_path, link_back)`

Import a note from shared vault to personal vault.

```python
result = ao.import_to_personal(
    note_path="work/active/auth.md",
    link_back=True
)
```

### `find_orphans()`

Detect orphaned notes (notes not linked from anywhere).

```python
orphans = ao.find_orphans()
```

**Returns:** `list[Note]` — Orphaned note objects.

---

## Hooks System

Custom hooks can be registered for lifecycle events.

```python
from ompa.hooks import Hook, HookContext, HookResult

class MyHook(Hook):
    def __init__(self):
        super().__init__("my_hook", token_budget=50)

    def execute(self, context: HookContext, **kwargs) -> HookResult:
        return HookResult(
            hook_name=self.name,
            success=True,
            output="...",
            tokens_hint=50
        )

ao = Ompa("./workspace")
ao.hooks.register_hook("my_hook", MyHook())
```

### Available Hooks

| Hook | Token Budget | Purpose |
|------|--------------|---------|
| `session_start` | ~2000 | Context injection at session start |
| `handle_message` | ~200 | Message processing |
| `post_tool` | ~100 | Tool execution recording |
| `pre_compact` | ~500 | Pre-compaction processing |
| `stop` | ~200 | Session termination |

资料来源：[CLAUDE.md](https://github.com/jmiaie/ompa/blob/main/CLAUDE.md)()

---

## Dual-Vault Configuration

The dual-vault system separates shared and personal notes.

```python
from ompa.config import DualVaultConfig, IsolationMode

config = DualVaultConfig(
    shared_vault="./team-vault",
    personal_vault="./private-vault",
    mode=IsolationMode.AUTO,
    default_vault=VaultTarget.PERSONAL
)
```

### Isolation Modes

| Mode | Behavior |
|------|----------|
| `AUTO` | Content auto-classified to shared or personal vault based on message type |
| `MANUAL` | Explicit `VaultTarget` routing per operation |
| `STRICT` | Enforce isolation boundaries |

### VaultTarget Enum

```python
from ompa.config import VaultTarget

VaultTarget.SHARED    # Team/organizational content
VaultTarget.PERSONAL # Private/personal content
```

---

## Async API

For async applications, use `ompa/async_api.py`:

```python
from ompa.async_api import AsyncOmpa

async with AsyncOmpa(vault_path="./workspace") as ao:
    await ao.session_start()
    result = await ao.search("authentication")
    await ao.stop()
```

资料来源：[STABILITY.md](https://github.com/jmiaie/ompa/blob/main/STABILITY.md)()

---

## Configuration Options

### Environment Variables

| Variable | Default | Description |
|----------|---------|-------------|
| `OMPA_VAULT_PATH` | `.` | Absolute path to vault |
| `OMPA_ENABLE_SEMANTIC` | `false` | Enable local semantic search |
| `OMPA_AGENT_NAME` | `agent` | Agent name (scopes KG entries) |
| `OMPA_SHARED_VAULT` | — | Shared vault path (dual-vault mode) |
| `OMPA_PERSONAL_VAULT` | — | Personal vault path (dual-vault mode) |

---

## Return Types

### `HookResult`

```python
@dataclass
class HookResult:
    success: bool
    output: str
    tokens_hint: int
    hook_name: str
```

### `Classification`

```python
@dataclass
class Classification:
    message_type: MessageType
    confidence: float
    suggested_folder: str
    routing_hint: str
```

### `SearchResult`

```python
@dataclass
class SearchResult:
    path: Path
    content: str
    score: float
    frontmatter: dict
```

### `Triple`

```python
@dataclass
class Triple:
    subject: str
    predicate: str
    object: str
    valid_from: str | None
    valid_to: str | None
    source: str | None
```

---

## Usage Examples

### Basic Session Workflow

```python
from ompa import Ompa

# Initialize
ao = Ompa(vault_path="./workspace")

# Start session
context = ao.session_start()
print(context.output)

# Process messages
ao.handle_message("We decided to go with Postgres")
ao.post_tool("write", {"file_path": "work/active/db-choice.md"})

# Search
results = ao.search("authentication decisions")

# End session
ao.stop()
```

### Dual-Vault Workflow

```python
from ompa import Ompa, DualVaultConfig, IsolationMode

config = DualVaultConfig(
    shared_vault="./team-vault",
    personal_vault="./private-vault",
    mode=IsolationMode.AUTO,
)

ao = Ompa(config=config)

# Auto-routed writes
ao.write("Team decision about API design", tags=["decision"])

# Manual routing
from ompa.config import VaultTarget
ao.write("Personal note", vault=VaultTarget.PERSONAL)

# Export to shared vault
ao.export_to_shared("personal/note.md", sanitize=True)
```

### Knowledge Graph Usage

```python
ao = Ompa(vault_path="./workspace")

# Add relationships
ao.kg.add_triple("Kai", "works_on", "Orion", valid_from="2025-06-01")
ao.kg.add_triple("Orion", "uses", "PostgreSQL", valid_from="2025-06-15")

# Query history
triples = ao.kg.query_entity("Kai")
timeline = ao.kg.timeline("Orion")

# Get stats
print(ao.kg.stats())
```

---

## Stable Public API

The following API surface is stable per Semantic Versioning:

- `Ompa` class and all public methods
- `DualVaultConfig`, `IsolationMode`, `VaultTarget`
- `HookResult`, `Classification`, `SearchResult`, `Triple`
- `SemanticIndex`, `SyncBackend`, adapters
- `count_tokens()` utility

Internal implementation details may change in minor versions.

资料来源：[STABILITY.md](https://github.com/jmiaie/ompa/blob/main/STABILITY.md)()

---

---

## Doramagic Pitfall Log

Project: jmiaie/ompa

Summary: Found 11 potential pitfall items; 0 are high/blocking. Highest priority: installation - 来源证据：OMPA v0.2.0 — The Big Rename.

## 1. installation · 来源证据：OMPA v0.2.0 — The Big Rename

- Severity: medium
- Evidence strength: source_linked
- Finding: GitHub 社区证据显示该项目存在一个安装相关的待验证问题：OMPA v0.2.0 — The Big Rename
- User impact: 可能阻塞安装或首次运行。
- Suggested check: 来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。
- Guardrail action: 不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。
- Evidence: community_evidence:github | cevd_ac771ab081be444ab18c5c1963becb64 | https://github.com/jmiaie/ompa/releases/tag/v0.2.0 | 来源讨论提到 python 相关条件，需在安装/试用前复核。

## 2. configuration · 来源证据：[P0] agent_integration.py race condition — session.memory attribute not available on cold start

- Severity: medium
- Evidence strength: source_linked
- Finding: GitHub 社区证据显示该项目存在一个配置相关的待验证问题：[P0] agent_integration.py race condition — session.memory attribute not available on cold start
- User impact: 可能阻塞安装或首次运行。
- Suggested check: 来源问题仍为 open，Pack Agent 需要复核是否仍影响当前版本。
- Guardrail action: 不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。
- Evidence: community_evidence:github | cevd_db65ef8ac28c41048d74c03c80cbed28 | https://github.com/jmiaie/ompa/issues/6 | 来源讨论提到 python 相关条件，需在安装/试用前复核。

## 3. capability · 能力判断依赖假设

- Severity: medium
- Evidence strength: source_linked
- Finding: README/documentation is current enough for a first validation pass.
- User impact: 假设不成立时，用户拿不到承诺的能力。
- Suggested check: 将假设转成下游验证清单。
- Guardrail action: 假设必须转成验证项；没有验证结果前不能写成事实。
- Evidence: capability.assumptions | github_repo:1207151629 | https://github.com/jmiaie/ompa | README/documentation is current enough for a first validation pass.

## 4. runtime · 社区讨论暴露的待验证问题：I did an analysis of 44 AI agent frameworks, sharing the result

- Severity: medium
- Evidence strength: source_linked
- Finding: I did an analysis of 44 AI agent frameworks, sharing the result 18 Feb 2026 · One thing missing from most framework comparisons is how they handle failures during agent execution. Tool call retries, error recovery, and ...
- User impact: 这类外部讨论可能代表真实用户在安装、配置、升级或生产使用时遇到阻力；发布前不能只依赖官方 README。
- Suggested check: Pack Agent 需要打开来源链接，确认问题是否仍然存在，并把验证结论写入说明书和边界卡。
- Evidence: social_signal:reddit | ssig_33233a78090343098fbddbeab9bc927d | https://www.reddit.com/r/LocalLLaMA/comments/1r84o6p/i_did_an_analysis_of_44_ai_agent_frameworks/ | I did an analysis of 44 AI agent frameworks, sharing the result

## 5. runtime · 社区讨论暴露的待验证问题：Your self-hosted AI agents can match closed-source models - I ... - Reddit

- Severity: medium
- Evidence strength: source_linked
- Finding: Your self-hosted AI agents can match closed-source models - I ... - Reddit 24 Nov 2025 · Looking for open-source knowledge management tool ... Let's compare 5 Open-Source AI Agent Tools that everyone cannot stop talking about on Reddit.
- User impact: 这类外部讨论可能代表真实用户在安装、配置、升级或生产使用时遇到阻力；发布前不能只依赖官方 README。
- Suggested check: Pack Agent 需要打开来源链接，确认问题是否仍然存在，并把验证结论写入说明书和边界卡。
- Evidence: social_signal:reddit | ssig_4fefa11ceedb46d4af5e2ff44e7709e1 | https://www.reddit.com/r/selfhosted/comments/1p5q8f1/your_selfhosted_ai_agents_can_match_closedsource/ | Your self-hosted AI agents can match closed-source models - I ... - Reddit

## 6. maintenance · 维护活跃度未知

- Severity: medium
- Evidence strength: source_linked
- Finding: 未记录 last_activity_observed。
- User impact: 新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。
- Suggested check: 补 GitHub 最近 commit、release、issue/PR 响应信号。
- Guardrail action: 维护活跃度未知时，推荐强度不能标为高信任。
- Evidence: evidence.maintainer_signals | github_repo:1207151629 | https://github.com/jmiaie/ompa | last_activity_observed missing

## 7. security_permissions · 下游验证发现风险项

- Severity: medium
- Evidence strength: source_linked
- Finding: no_demo
- User impact: 下游已经要求复核，不能在页面中弱化。
- Suggested check: 进入安全/权限治理复核队列。
- Guardrail action: 下游风险存在时必须保持 review/recommendation 降级。
- Evidence: downstream_validation.risk_items | github_repo:1207151629 | https://github.com/jmiaie/ompa | no_demo; severity=medium

## 8. security_permissions · 存在评分风险

- Severity: medium
- Evidence strength: source_linked
- Finding: no_demo
- User impact: 风险会影响是否适合普通用户安装。
- Suggested check: 把风险写入边界卡，并确认是否需要人工复核。
- Guardrail action: 评分风险必须进入边界卡，不能只作为内部分数。
- Evidence: risks.scoring_risks | github_repo:1207151629 | https://github.com/jmiaie/ompa | no_demo; severity=medium

## 9. security_permissions · 来源证据：OMPA v0.2.1 — Security & Reliability Hardening

- Severity: medium
- Evidence strength: source_linked
- Finding: GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题：OMPA v0.2.1 — Security & Reliability Hardening
- User impact: 可能阻塞安装或首次运行。
- Suggested check: 来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。
- Guardrail action: 不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。
- Evidence: community_evidence:github | cevd_ab0ad6b963354f2096bef6783c95c289 | https://github.com/jmiaie/ompa/releases/tag/v0.2.1 | 来源讨论提到 python 相关条件，需在安装/试用前复核。

## 10. maintenance · issue/PR 响应质量未知

- Severity: low
- Evidence strength: source_linked
- Finding: issue_or_pr_quality=unknown。
- User impact: 用户无法判断遇到问题后是否有人维护。
- Suggested check: 抽样最近 issue/PR，判断是否长期无人处理。
- Guardrail action: issue/PR 响应未知时，必须提示维护风险。
- Evidence: evidence.maintainer_signals | github_repo:1207151629 | https://github.com/jmiaie/ompa | issue_or_pr_quality=unknown

## 11. maintenance · 发布节奏不明确

- Severity: low
- Evidence strength: source_linked
- Finding: release_recency=unknown。
- User impact: 安装命令和文档可能落后于代码，用户踩坑概率升高。
- Suggested check: 确认最近 release/tag 和 README 安装命令是否一致。
- Guardrail action: 发布节奏未知或过期时，安装说明必须标注可能漂移。
- Evidence: evidence.maintainer_signals | github_repo:1207151629 | https://github.com/jmiaie/ompa | release_recency=unknown

<!-- canonical_name: jmiaie/ompa; human_manual_source: deepwiki_human_wiki -->
