# https://github.com/jshsakura/oc-piloci 项目说明书

生成时间：2026-05-18 00:58:38 UTC

## 目录

- [Introduction to piLoci](#introduction)
- [Getting Started](#getting-started)
- [System Architecture](#architecture-overview)
- [Technology Stack](#tech-stack)
- [MCP Server Implementation](#mcp-server)
- [Authentication & Security](#authentication)
- [API Routes](#api-routes)
- [Curator Pipeline](#curator-pipeline)
- [Storage Layer](#storage-layer)
- [Database Models](#database-models)
- [Web Dashboard](#web-dashboard)
- [Workspace UI & Team Features](#workspace-ui)

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

## Introduction to piLoci

### 相关页面

相关主题：[System Architecture](#architecture-overview), [Getting Started](#getting-started), [Technology Stack](#tech-stack)

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

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

- [README.md](https://github.com/jshsakura/oc-piloci/blob/main/README.md)
- [README.ko.md](https://github.com/jshsakura/oc-piloci/blob/main/README.ko.md)
- [DESIGN-HARNESS.md](https://github.com/jshsakura/oc-piloci/blob/main/web/DESIGN-HARNESS.md)
- [CLAUDE.md](https://github.com/jshsakura/oc-piloci/blob/main/CLAUDE.md)
- [MEMORY.md](https://github.com/jshsakura/oc-piloci/blob/main/MEMORY.md)
- [src/piloci/installer.py](https://github.com/jshsakura/oc-piloci/blob/main/src/piloci/installer.py)
- [src/piloci/cli.py](https://github.com/jshsakura/oc-piloci/blob/main/src/piloci/cli.py)
- [web/lib/api.ts](https://github.com/jshsakura/oc-piloci/blob/main/web/lib/api.ts)
</details>

# Introduction to piLoci

piLoci is a lightweight, self-hosted memory curation system designed for AI coding assistants. It acts as a "quiet automatic memory curator" — silently capturing, organizing, and surfacing context from coding sessions to enhance productivity across projects. The system runs on Raspberry Pi 5 or any server, providing privacy-first memory management without relying on external cloud services.

## Overview

piLoci bridges the gap between ephemeral AI coding sessions and persistent knowledge storage. When developers use AI assistants like Claude Code or OpenCode, piLoci captures session context, extracts actionable memories, and stores them in a searchable vector database. This enables developers to build a cumulative knowledge base that improves over time.

### Core Value Proposition

| Aspect | Description |
|--------|-------------|
| **Privacy** | Self-hosted on local hardware; no data leaves your network |
| **Automatic** | Silent capture of sessions without manual intervention |
| **Project-scoped** | Memories organized by project for clean isolation |
| **MCP-enabled** | Native integration with Model Context Protocol tools |

资料来源：[README.md](https://github.com/jshsakura/oc-piloci/blob/main/README.md)

### Design Philosophy

piLoci embodies the metaphor of a "behind-the-scenes assistant quietly organizing notes" (뒤에서 조용히 돕는 자동 기억 큐레이터). The design direction emphasizes:

- **Curation over collection** — Not just storing everything, but organizing meaningful insights
- **Graph/workspace representation** — Visualizing relationships between memories and sessions
- **Minimal friction** — One-line pairing, automatic capture, zero-token exposure

资料来源：[CLAUDE.md](https://github.com/jshsakura/oc-piloci/blob/main/CLAUDE.md)

## Architecture

### System Components

```mermaid
graph TD
    subgraph Client["Client Side"]
        ClaudeCode[Claude Code]
        OpenCode[OpenCode]
        Cursor[Cursor IDE]
    end

    subgraph MCP["MCP Layer"]
        Memory[MCP: memory]
        Recall[MCP: recall]
        Recommend[MCP: recommend]
    end

    subgraph Server["piLoci Server"]
        API[Python API Server]
        SQLite[(SQLite<br/>Identity Data)]
        LanceDB[(LanceDB<br/>Vector Store)]
        Redis[(Redis<br/>Sessions)]
        Embed[FastEmbed/ONNX]
    end

    subgraph WebUI["Web Frontend"]
        Dashboard[Dashboard]
        Projects[Project Workspace]
        Admin[Admin Console]
    end

    ClaudeCode <--> MCP
    OpenCode <--> MCP
    Cursor <--> MCP
    MCP <--> API
    API <--> SQLite
    API <--> LanceDB
    API <--> Redis
    API <--> Embed
    API <--> WebUI
```

### Technology Stack

| Component | Technology | Purpose |
|-----------|------------|---------|
| **Backend** | Python | MCP-enabled API server |
| **Identity DB** | SQLite | User accounts, projects, sessions |
| **Vector Store** | LanceDB | Embedded memory storage |
| **Session Cache** | Redis | Session state management |
| **Embeddings** | FastEmbed (ONNX) | Fast on-device inference |
| **Frontend** | Next.js | Web UI, dashboard, settings |

资料来源：[README.md](https://github.com/jshsakura/oc-piloci/blob/main/README.md)

### Web Frontend Structure

The web application follows a consistent page pattern defined in `web/DESIGN-HARNESS.md`:

```tsx
<AppShell>
  <div className="pi-page">
    <section className="pi-page-hero">
      <p className="pi-eyebrow">Area label</p>
      <h1 className="pi-title mt-2">Page title</h1>
      <p className="pi-subtitle">One sentence explaining the page.</p>
    </section>

    <section className="grid gap-3 sm:grid-cols-3">
      <div className="pi-metric-card">...</div>
    </section>

    <section className="pi-panel p-3">...</section>
  </div>
</AppShell>
```

#### Baseline Pages

| Page | Component | Purpose |
|------|-----------|---------|
| Dashboard | `app/dashboard/page.tsx` + `DashboardSummaryPanels.tsx` | User overview with metrics |
| Admin Console | `app/admin/users/page.tsx` | User management |
| Project Workspace | `app/projects/page.tsx` + `ProjectListView.tsx` | Project-level memory access |
| Privacy | `app/privacy/page.tsx` | Privacy policy |
| Terms | `app/terms/page.tsx` | Terms of service |

资料来源：[DESIGN-HARNESS.md](https://github.com/jshsakura/oc-piloci/blob/main/web/DESIGN-HARNESS.md)

## Client Connection Flow

### Supported Clients

piLoci integrates with multiple AI coding assistants through MCP:

| Client | Session Capture | MCP Tools |
|--------|----------------|-----------|
| **Claude Code** | SessionStart/Stop hooks | memory, recall, recommend |
| **Claude Desktop** | Static config | memory, recall, recommend |
| **OpenCode** | Static config only | memory, recall, recommend |
| **Cursor** | Static config | memory, recall, recommend |

资料来源：[web/components/TokenManager.tsx](https://github.com/jshsakura/oc-piloci/blob/main/web/components/TokenManager.tsx)

### Connection Process

```mermaid
sequenceDiagram
    participant User
    participant CLI
    participant WebUI
    participant Server

    User->>CLI: piloci login
    CLI->>Server: OAuth or install code request
    Server->>WebUI: Redirect to /device
    User->>WebUI: Login + approve
    WebUI->>CLI: Token ready
    CLI->>Server: Poll and receive token
    Server->>CLI: Token + URLs
    CLI->>User: Configuration complete

    User->>CLI: piloci install
    CLI->>Server: Download MCP server config
    Server->>CLI: .mcp.json + hooks
    CLI->>User: MCP tools available
```

### What Connection Establishes

The pairing process creates the following artifacts:

```
~/.config/piloci/
├── config.json     # Token + ingest/analyze URLs (mode 0600)
├── hook.py         # SessionStart catch-up (Claude only)
└── stop-hook.sh    # Stop live push (Claude only)

~/.claude.json              # MCP server entry (Claude only)
~/.claude/settings.json     # SessionStart + Stop hooks (Claude only)
~/.config/opencode/         # MCP server entry (OpenCode)
```

资料来源：[README.ko.md](https://github.com/jshsakura/oc-piloci/blob/main/README.ko.md)

## CLI Commands

The `piloci` CLI provides complete installation and management capabilities:

| Command | Description |
|---------|-------------|
| `piloci login` | Authenticate with the server (OAuth or install code) |
| `piloci install` | Install MCP server and hooks for AI clients |
| `piloci uninstall` | Remove all piLoci artifacts, optionally restore backups |
| `piloci restore` | Restore client configs from .piloci-bak snapshots |
| `piloci backfill-cwd` | Fix legacy slug-collision bug in session data |

### Install Command Options

| Flag | Purpose |
|------|---------|
| `--server` | Override server URL when only install code is provided |
| `--token` | Use token directly instead of resolving URL |
| `--force` | Wipe existing plugin folders and reinstall fresh |

### Uninstall Command Options

| Flag | Purpose |
|------|---------|
| `--yes` | Skip confirmation prompt |
| `--no-restore` | Remove entries surgically instead of restoring backups |

资料来源：[src/piloci/cli.py](https://github.com/jshsakura/oc-piloci/blob/main/src/piloci/cli.py)

## Plugin Installation Structure

For Claude Code, piLoci installs as a Claude plugin with hooks:

```
piloci/
├── .claude-plugin/
│   └── plugin.json          # Manifest with name, version, description
├── hooks/
│   ├── hooks.json           # SessionStart + Stop wired to scripts
│   ├── hook.py              # Downloaded from /api/hook/script
│   └── stop-hook.sh         # Downloaded from /api/hook/stop-script
└── .mcp.json                # MCP server config for memory/recall/recommend
```

资料来源：[src/piloci/installer.py](https://github.com/jshsakura/oc-piloci/blob/main/src/piloci/installer.py)

## Data Models

### API Client Functions

The frontend communicates with the backend through typed API functions:

```typescript
// Project operations
getProjects: () => request<Project[]>("api/projects")
getProjectBySlug: (slug: string) => request<Project>(`api/projects/slug/${slug}`)
createProject: (body) => request<Project>("api/projects", { method: "POST", body })
getProjectFreshness: (projectId) => request<ProjectFreshness>(`api/projects/${projectId}/freshness`)

// Session operations
getSessions: () => request<Session[]>("api/sessions")

// Memory operations
createMemory: (projectId, body) => request<Memory>(`api/memories`, { method: "POST", body })

// Distillation operations
runDistillationNow: () => request<{ woken: boolean; note: string }>("/api/distillation/run-now", { method: "POST" })
getDistillationPreferences: () => request<DistillationPreferences>("api/preferences")
updateDistillationPreferences: (body) => request<DistillationPreferences>("api/preferences", { method: "PATCH", body })

// Budget operations
budgetUsage: () => request<BudgetUsage>("api/budget/usage")
```

资料来源：[web/lib/api.ts](https://github.com/jshsakura/oc-piloci/blob/main/web/lib/api.ts)

### Project Sessions Panel

The session viewer displays captured coding sessions:

| Field | Description |
|-------|-------------|
| `ingest_id` | Unique session identifier |
| `client` | AI client used (Claude Code, OpenCode, etc.) |
| `project_slug` | Associated project |
| `project_name` | Human-readable project name |
| `created_at` | Session start timestamp |
| `processed_at` | When distillation completed |
| `memories_extracted` | Number of memories extracted |
| `error` | Any processing errors |
| `transcript` | Full session transcript (expandable) |

资料来源：[web/components/ProjectSessionsPanel.tsx](https://github.com/jshsakura/oc-piloci/blob/main/web/components/ProjectSessionsPanel.tsx)

### Instincts (Top Knacks)

Instincts are triggered memory patterns:

| Field | Description |
|-------|-------------|
| `instinct_id` | Unique instinct identifier |
| `trigger` | Condition pattern ("when...") |
| `action` | Suggested action ("→...") |
| `project_slug` | Associated project |
| `domain` | Knowledge domain |
| `instinct_count` | Number of times triggered |

资料来源：[web/components/DashboardSummaryPanels.tsx](https://github.com/jshsakura/oc-piloci/blob/main/web/components/DashboardSummaryPanels.tsx)

## Usage Scenarios

### Scenario A — Team Project Memory Hub

A small team sets up one piLoci on a shared Raspberry Pi 5. Each member creates an account, joins shared projects, and stores memories via MCP tools. Everyone benefits from the same knowledge base while project isolation keeps unrelated work separate.

### Scenario B — Multi-Project Workspace

A solo developer runs several projects (e.g., "thesis research", "side project", "client work") on one piLoci. Each project's memories stay isolated, and the workspace viewer shows notes and relationships per project.

### Scenario C — Obsidian Export

Generate workspace notes and export to an Obsidian vault:

```bash
curl -sS http://localhost:8314/api/projects/slug/my-project/workspace
```

Or download a ready-made archive:

```bash
curl -OJ http://localhost:8314/api/vault/my-project/export
```

资料来源：[README.md](https://github.com/jshsakura/oc-piloci/blob/main/README.md)

## Deployment Configuration

### Environment Variables

When running behind a reverse proxy, the `BASE_URL` environment variable is required:

```env
BASE_URL=https://piloci.example.com
```

This ensures Google OAuth redirect URIs match exactly:

```
https://piloci.example.com/auth/google/callback
```

Without `BASE_URL`, the backend may generate callbacks based on internal request hosts, causing `redirect_uri_mismatch` errors.

### Port Configuration

The default port is `8314`. When exposing via reverse proxy or tunnel (Cloudflare Tunnel, Caddy, nginx), proxy external traffic to `http://127.0.0.1:8314`.

资料来源：[README.ko.md](https://github.com/jshsakura/oc-piloci/blob/main/README.ko.md)

## Version Management

piLoci uses a single-source version system:

| Rule | Description |
|------|-------------|
| **Source** | `pyproject.toml` → `[project].version` |
| **Default bump** | `+0.0.1` patch only |
| **Major/Minor** | Requires explicit approval |
| **Release trigger** | Git tag push: `git tag v{version} && git push origin main v{version}` |
| **Tag format** | Must match: `v0.2.0` ↔ `0.2.0` |

### Pre-release Checklist

Before tagging:

1. Update version in `pyproject.toml`
2. Run tests: `pytest tests/ -v`
3. Build package: `uv build`
4. Build web (if changed): `pnpm build` in `web/`

### GitHub Actions Pipeline

The `publish.yml` workflow handles:

- Version guard (tag matches `pyproject.toml`)
- Test gate
- Web build artifact
- Multi-arch Docker image publish
- GitHub Release creation
- PyPI publish as `oc-piloci`

资料来源：[CLAUDE.md](https://github.com/jshsakura/oc-piloci/blob/main/CLAUDE.md)

## Development Workflow

### Starting an Implementation Session

1. Begin each session at `PLAN.md`
2. Check `## 현재 상태` (Current Status) for incomplete items
3. Implement the next pending item
4. Document completion in PLAN.md

### Current Development Focus

Based on recent changes documented in `MEMORY.md`:

- **Memory creation UI speed** — Narrow v0.3 slice for faster memory creation
- **Graph UI direction** — Planning for React Flow-based interactive memory visualization
- **Copy style** — Landing page emphasizes "quiet automatic memory curator" metaphor
- **Vault caching** — Tests added for `tests/test_vault_cache.py`

资料来源：[MEMORY.md](https://github.com/jshsakura/oc-piloci/blob/main/MEMORY.md)

### Design Guidelines for Frontend

Key principles from `CLAUDE.md`:

- **Avoid dash-heavy feature lists** — Use paragraph-based Korean/English copy
- **Translate optimizations to UX** — Don't just list technical features
- **Maintain metaphor** — "뒤에서 조용히 돕는 자동 기억 큐레이터" (behind-the-scenes quiet assistant)
- **Graph direction** — Visual metaphor of a curator organizing post-it notes

---

<a id='getting-started'></a>

## Getting Started

### 相关页面

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

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

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

- [.env.example](https://github.com/jshsakura/oc-piloci/blob/main/.env.example)
- [docker-compose.yml](https://github.com/jshsakura/oc-piloci/blob/main/docker-compose.yml)
- [deploy/setup.sh](https://github.com/jshsakura/oc-piloci/blob/main/deploy/setup.sh)
- [src/piloci/config.py](https://github.com/jshsakura/oc-piloci/blob/main/src/piloci/config.py)
</details>

# Getting Started

piLoci is a personal memory hub designed for AI coding assistants. It runs on a local server (typically Raspberry Pi 5) and captures, stores, and retrieves contextual memories from AI-assisted coding sessions. This guide walks you through the complete setup process from hardware prerequisites to first login.

## Prerequisites

### Hardware Requirements

| Component | Minimum | Recommended |
|-----------|---------|-------------|
| Device | Raspberry Pi 5 (4GB+) | Raspberry Pi 5 (8GB) |
| Storage | 32GB SD card | 64GB+ SSD via USB |
| Network | Ethernet or WiFi | Ethernet |
| OS | Raspberry Pi OS (64-bit) | Raspberry Pi OS (64-bit) |

资料来源：[README.md](https://github.com/jshsakura/oc-piloci/blob/main/README.md)

### Software Requirements

- **Docker** and **Docker Compose** installed on the host
- **Google OAuth credentials** (for authentication)
- A domain name (optional, for remote access via Cloudflare Tunnel)

## Installation

### Step 1: Clone the Repository

```bash
git clone https://github.com/jshsakura/oc-piloci.git
cd oc-piloci
```

### Step 2: Configure Environment Variables

Copy the example environment file and configure it:

```bash
cp .env.example .env
```

Edit `.env` with your specific settings:

```env
# Required: Set your external HTTPS domain if behind a reverse proxy
BASE_URL=https://piloci.example.com

# Google OAuth credentials (required for authentication)
GOOGLE_CLIENT_ID=your_client_id_here
GOOGLE_CLIENT_SECRET=your_client_secret_here

# Secret key for session encryption
SECRET_KEY=your_random_secret_key_here
```

> **Important:** When deploying behind a reverse proxy, you MUST set `BASE_URL` to your external HTTPS domain. Without it, Google OAuth redirect URIs will fail with `redirect_uri_mismatch`. 资料来源：[README.ko.md](https://github.com/jshsakura/oc-piloci/blob/main/README.ko.md)

#### Google OAuth Setup

1. Go to [Google Cloud Console](https://console.cloud.google.com/)
2. Create a new project or select an existing one
3. Navigate to **APIs & Services** → **Credentials**
4. Create an **OAuth 2.0 Client ID** (Web application type)
5. Add the following authorized redirect URI (replace with your domain):

```
https://piloci.example.com/auth/google/callback
```

The callback URI must match **exactly**, including trailing slashes. 资料来源：[README.ko.md](https://github.com/jshsakura/oc-piloci/blob/main/README.ko.md)

### Step 3: Deploy with Docker Compose

The project uses Docker Compose for container orchestration:

```bash
docker compose up -d
```

This starts the following services:

| Service | Port | Purpose |
|---------|------|---------|
| web | 8314 | Next.js frontend + API server |
| redis | 6379 | Session storage |
| worker | - | Background distillation worker |

资料来源：[docker-compose.yml](https://github.com/jshsakura/oc-piloci/blob/main/docker-compose.yml)

### Step 4: Verify Deployment

Check the health status:

```bash
curl http://localhost:8314/healthz
```

A successful response indicates the application is running correctly.

## Architecture Overview

```mermaid
graph TB
    subgraph "Client Side"
        CC[Claude Code / Claude Desktop]
        OC[OpenCode]
        CU[Cursor]
    end
    
    subgraph "piLoci Server"
        WEB[Web App :8314]
        REDIS[(Redis<br/>Sessions)]
        WORKER[Distillation<br/>Worker]
        DB[(LanceDB<br/>Memories)]
    end
    
    subgraph "AI Clients → piLoci"
        CC --> MCP[MCP Server]
        OC --> MCP
        CU --> MCP
    end
    
    MCP -->|Ingest| WEB
    WEB --> REDIS
    WEB --> DB
    WORKER --> DB
    WORKER -->|Distill| CC
```

资料来源：[README.md](https://github.com/jshsakura/oc-piloci/blob/main/README.md)

## Client Connection

### Claude Code Setup

1. Navigate to **Settings → Tokens** in the web UI
2. Generate an install code
3. Run the pairing command:

```bash
piloci login --pair <install_code>
piloci install
```

Or use the one-liner:

```bash
curl -sSL https://piloci.example.com/install/<install_code> | bash
```

This automatically:
- Writes token + URLs to `~/.config/piloci/config.json`
- Registers the MCP server in `~/.claude.json`
- Configures session capture hooks in `~/.claude/settings.json`

资料来源：[README.ko.md](https://github.com/jshsakura/oc-piloci/blob/main/README.ko.md)

### What Gets Installed

```
~/.config/piloci/
├── config.json     # Token + ingest/analyze URLs (mode 0600)
├── hook.py         # SessionStart catch-up hook (Claude Code only)
└── stop-hook.sh    # Stop live push (Claude Code only)

~/.claude.json              # MCP server entry (Claude Code only)
~/.claude/settings.json     # SessionStart + Stop hooks (Claude Code only)
```

资料来源：[README.ko.md](https://github.com/jshsakura/oc-piloci/blob/main/README.ko.md)

## Remote Access

### Exposing Port 8314

Configure your reverse proxy or tunnel to expose port 8314:

| Proxy/Tunnel | Configuration |
|--------------|---------------|
| Cloudflare Tunnel | Point to `http://127.0.0.1:8314` |
| Caddy | Proxy to `localhost:8314` |
| nginx | Proxy pass to `127.0.0.1:8314` |

### Cloudflare Tunnel Setup

```bash
cloudflared tunnel --url http://localhost:8314
```

资料来源：[README.ko.md](https://github.com/jshsakura/oc-piloci/blob/main/README.ko.md)

## Configuration Reference

### Environment Variables

| Variable | Required | Default | Description |
|----------|----------|---------|-------------|
| `BASE_URL` | Yes (remote) | `http://localhost:8314` | External HTTPS URL when behind proxy |
| `GOOGLE_CLIENT_ID` | Yes | - | Google OAuth Client ID |
| `GOOGLE_CLIENT_SECRET` | Yes | - | Google OAuth Client Secret |
| `SECRET_KEY` | Yes | - | Session encryption key |
| `DATA_DIR` | No | `./data` | Data persistence directory |
| `REDIS_URL` | No | `redis://redis:6379` | Redis connection URL |

资料来源：[src/piloci/config.py](https://github.com/jshsakura/oc-piloci/blob/main/src/piloci/config.py)

### Data Storage

The application stores data in:

- **SQLite**: User identity and authentication data
- **LanceDB**: Embedded vector storage for memories
- **Redis**: Session data and real-time state

资料来源：[README.md](https://github.com/jshsakura/oc-piloci/blob/main/README.md)

## Development Mode

### Local Stack Development

```bash
# Start backend with hot reload
uv run uvicorn src.piloci.main:app --reload --port 8314

# In another terminal, start worker
uv run python -m piloci.worker.distillation
```

### Web Frontend Development

```bash
cd web
pnpm install --frozen-lockfile
pnpm dev
```

资料来源：[README.md](https://github.com/jshsakura/oc-piloci/blob/main/README.md)

## Next Steps

After successful installation:

1. **Create an account** via the web UI at `http://localhost:8314/signup`
2. **Connect your AI client** using the pairing flow
3. **Create projects** to organize your memories
4. **Explore the dashboard** to view session history and extracted memories

For troubleshooting, check the logs:

```bash
docker compose logs -f web
docker compose logs -f worker

---

<a id='architecture-overview'></a>

## System Architecture

### 相关页面

相关主题：[Introduction to piLoci](#introduction), [Technology Stack](#tech-stack), [Storage Layer](#storage-layer), [MCP Server Implementation](#mcp-server)

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

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

- [README.md](https://github.com/jshsakura/oc-piloci/blob/main/README.md)
- [CLAUDE.md](https://github.com/jshsakura/oc-piloci/blob/main/CLAUDE.md)
- [web/lib/api.ts](https://github.com/jshsakura/oc-piloci/blob/main/web/lib/api.ts)
- [src/piloci/installer.py](https://github.com/jshsakura/oc-piloci/blob/main/src/piloci/installer.py)
- [web/DESIGN-HARNESS.md](https://github.com/jshsakura/oc-piloci/blob/main/web/DESIGN-HARNESS.md)
- [MEMORY.md](https://github.com/jshsakura/oc-piloci/blob/main/MEMORY.md)
- [web/app/page.tsx](https://github.com/jshsakura/oc-piloci/blob/main/web/app/page.tsx)
- [web/components/DashboardSummaryPanels.tsx](https://github.com/jshsakura/oc-piloci/blob/main/web/components/DashboardSummaryPanels.tsx)
- [web/app/admin/users/page.tsx](https://github.com/jshsakura/oc-piloci/blob/main/web/app/admin/users/page.tsx)
</details>

# System Architecture

piLoci is a self-hosted memory curation system designed for AI-assisted development workflows. It operates as a client-server architecture where a Raspberry Pi (or any server) acts as a central hub for capturing, processing, and retrieving contextual memories from AI coding sessions. The system bridges the gap between ephemeral AI conversations and persistent, searchable knowledge bases.

## High-Level Architecture Overview

piLoci follows a layered architecture pattern comprising four primary tiers: a frontend presentation layer, a backend API layer, a storage abstraction layer, and a client integration layer. Each tier is independently deployable and communicates through well-defined interfaces, enabling flexibility in deployment scenarios.

The backend is built with Python and leverages the Model Context Protocol (MCP) to expose memory management tools to AI clients such as Claude Code and OpenCode. The frontend is a Next.js application that provides both user-facing interfaces and administrative capabilities. The storage layer abstracts away the complexity of handling different database technologies, providing a unified API for memory operations.

```mermaid
graph TD
    subgraph Client["Client Layer"]
        ClaudeCode["Claude Code"]
        OpenCode["OpenCode"]
        Cursor["Cursor IDE"]
    end

    subgraph Server["piLoci Server"]
        API["FastAPI Server<br/>(Port 8314)"]
        MCP["MCP Tools<br/>memory/recall/recommend"]
    end

    subgraph Storage["Storage Layer"]
        SQLite["SQLite<br/>(Identity)"]
        LanceDB["LanceDB<br/>(Vectors)"]
        Redis["Redis<br/>(Sessions)"]
    end

    subgraph Frontend["Frontend Layer"]
        NextJS["Next.js App<br/>(Web UI)"]
        Admin["Admin Console"]
        Dashboard["User Dashboard"]
    end

    Client -->|HTTP/MCP| Server
    NextJS -->|REST API| API
    API --> Storage
    API --> MCP
```

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

## Technology Stack

piLoci's architecture leverages a carefully selected technology stack optimized for self-hosted deployment on resource-constrained hardware like the Raspberry Pi 5. Each component serves a specific purpose in the overall system.

| Component | Technology | Purpose | Location |
|-----------|------------|---------|----------|
| Backend API | FastAPI | REST API + MCP server | `src/piloci/` |
| Vector Storage | LanceDB | Embedded memory storage with vector search | `src/piloci/storage/` |
| Identity DB | SQLite | User/project identity and metadata | `src/piloci/db/` |
| Session Cache | Redis | Temporary session data caching | `docker-compose.yml` |
| Embeddings | fastembed (ONNX) | Local CPU-based embedding inference | `src/piloci/storage/` |
| Frontend | Next.js 14 | React-based web application | `web/` |
| Styling | Tailwind CSS | Utility-first design system | `web/` |
| Container | Docker | Self-contained deployment | `docker-compose.yml` |

资料来源：[README.md:85-95]()

### Embedding Infrastructure

The system uses fastembed for ONNX-based embeddings, enabling fast, on-device inference without requiring GPU resources. This design choice is critical for the target deployment environment of Raspberry Pi devices where power efficiency and thermal constraints are primary concerns.

The embedding service processes text content and generates vector representations that capture semantic meaning. These vectors are stored in LanceDB, which provides efficient similarity search capabilities essential for the recall and recommendation features.

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

## Frontend Architecture

The Next.js frontend follows a component-driven architecture with clear separation between presentation components, data fetching logic, and layout structures. The application is organized around a shell-based layout pattern that provides consistent navigation and authentication state across all pages.

### Page Structure Pattern

All application pages follow a standardized layout defined in `AppShell.tsx` with specific section patterns for different content types.

```mermaid
graph TD
    AppShell["AppShell Component<br/>(web/components/AppShell.tsx)"]
    Hero["pi-page-hero<br/>(Title + Subtitle)"]
    Metrics["pi-metric-card<br/>(Data Cards)"]
    Panel["pi-panel<br/>(Content Sections)"]

    AppShell --> Hero
    AppShell --> Metrics
    AppShell --> Panel
```

The component hierarchy follows this pattern:

```
AppShell
└── div.pi-page
    ├── section.pi-page-hero
    │   ├── p.pi-eyebrow
    │   ├── h1.pi-title
    │   └── p.pi-subtitle
    ├── section.pi-page (metrics grid)
    │   └── div.pi-metric-card
    └── section.pi-panel (content areas)
```

资料来源：[web/DESIGN-HARNESS.md:10-30]()

### Key Frontend Components

| Component | File Path | Responsibility |
|-----------|-----------|----------------|
| AppShell | `web/components/AppShell.tsx` | Authenticated shell with glass navigation |
| DashboardSummaryPanels | `web/components/DashboardSummaryPanels.tsx` | User dashboard with metrics and session lists |
| ProjectSessionsPanel | `web/components/ProjectSessionsPanel.tsx` | Project-specific session viewer with transcripts |
| TokenManager | `web/components/TokenManager.tsx` | Installation token generation and display |
| DistillationSettings | `web/components/DistillationSettingsPanel.tsx` | Memory processing configuration |

资料来源：[web/components/DashboardSummaryPanels.tsx:1-80]()

### API Client Layer

The frontend communicates with the backend through a typed API client defined in `web/lib/api.ts`. This module provides a centralized request function that handles authentication, error handling, and response typing.

```typescript
// Simplified API client structure
const api = {
  projects: {
    list: () => request<Project[]>("/api/projects"),
    create: (body) => request<Project>("/api/projects", { method: "POST", body }),
    getBySlug: (slug) => request<Project>(`/api/projects/slug/${slug}`),
  },
  memories: {
    create: (projectId, body) => request<Memory>(`/api/projects/${projectId}/memories`, { method: "POST", body }),
    list: (projectId) => request<Memory[]>(`/api/projects/${projectId}/memories`),
  },
  distillation: {
    runNow: () => request<{ woken: boolean; note: string }>("/api/distillation/run-now", { method: "POST" }),
    getPreferences: () => request<DistillationPreferences>("/api/preferences"),
    updatePreferences: (body) => request<DistillationPreferences>("/api/preferences", { method: "PATCH", body }),
  },
};
```

资料来源：[web/lib/api.ts:1-50]()

### Landing Page Architecture

The landing page (`web/app/page.tsx`) serves as the public-facing entry point for unauthenticated users and implements a conversion-focused design with feature highlights and installation guidance.

```mermaid
graph LR
    Hero["Hero Section<br/>(CTA: Signup/Dashboard)"]
    Features["Features Grid<br/>(4-column)"]
    Install["Installation Guide<br/>(CLI + bash options)"]
    Uninstall["Uninstall Note<br/>(Removal instructions)"]

    Hero --> Features
    Features --> Install
    Install --> Uninstall
```

资料来源：[web/app/page.tsx:1-60]()

## Backend Architecture

The Python backend implements a FastAPI application that serves both REST API endpoints and MCP tool interfaces. The architecture emphasizes separation of concerns through distinct modules for API routes, database operations, and storage abstraction.

### Application Entry Point

The main application module (`src/piloci/main.py`) initializes the FastAPI server with middleware configuration, CORS settings, and route registration. The application listens on port 8314 by default and supports configuration through environment variables.

Key configuration parameters:

| Parameter | Default | Purpose |
|-----------|---------|---------|
| `BASE_URL` | (auto-detected) | External HTTPS domain for OAuth callbacks |
| `DATABASE_URL` | (local path) | SQLite database location |
| `REDIS_URL` | (local) | Redis connection for session caching |
| `PORT` | 8314 | HTTP server port |

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

### Database Architecture

The system uses three distinct storage mechanisms, each optimized for specific data access patterns.

```mermaid
graph TD
    API["FastAPI Server"]
    Session["Session Management"]
    Identity["SQLite<br/>(Identity Data)"]
    Vectors["LanceDB<br/>(Memory Vectors)"]
    Cache["Redis<br/>(Session Cache)"]

    API --> Session
    Session --> Identity
    Session --> Vectors
    Session --> Cache
```

#### Identity Database (SQLite)

SQLite handles persistent identity data including user accounts, project metadata, and session records. The session module (`src/piloci/db/session.py`) provides an abstraction layer for database operations.

```python
# Session database schema concept
class Session:
    id: str
    user_id: str
    project_id: str
    client: str  # "claude-code" | "opencode" | "cursor"
    ingest_id: str
    created_at: datetime
    processed_at: Optional[datetime]
    memories_extracted: int
    error: Optional[str]
```

资料来源：[web/components/DashboardSummaryPanels.tsx:30-50]()

#### Vector Storage (LanceDB)

LanceDB stores embedded memory content with vector representations for semantic search. The storage module provides CRUD operations for memories and supports similarity-based retrieval for the recall and recommendation features.

#### Session Cache (Redis)

Redis provides low-latency caching for active sessions and real-time processing state. The distillation worker uses Redis for queue management and processing state tracking.

资料来源：[README.md:85-90]()

### API Route Organization

API routes are organized by resource type and follow RESTful conventions:

| Route Prefix | Handler | Purpose |
|--------------|---------|---------|
| `/api/auth/*` | Authentication | OAuth flows, session management |
| `/api/projects/*` | Project management | CRUD, slug lookup, freshness |
| `/api/memories/*` | Memory operations | Create, list, vector search |
| `/api/budget/*` | Budget tracking | Usage reporting |
| `/api/preferences` | User settings | Distillation configuration |
| `/api/distillation/*` | Worker control | Manual trigger, status |

资料来源：[web/lib/api.ts:1-40]()

## Installer Architecture

The installer module (`src/piloci/installer.py`) handles client-side setup by creating configuration files and registering MCP servers with supported AI clients. It follows a plugin-based architecture for each supported client type.

### Claude Code Installer Layout

```mermaid
graph TD
    Plugin["Claude Plugin<br/>~/.claude/plugins/piloci/"]
    PluginManifest[".claude-plugin/plugin.json"]
    Hooks["hooks/hooks.json"]
    Scripts["hooks/hook.py<br/>hooks/stop-hook.sh"]
    MCP[".mcp.json<br/>(MCP Server Config)"]

    Plugin --> PluginManifest
    Plugin --> Hooks
    Plugin --> Scripts
    Plugin --> MCP
```

资料来源：[src/piloci/installer.py:20-50]()

### Installation Workflow

1. **Manifest Creation**: Generates `plugin.json` with version, description, and author metadata
2. **Hook Configuration**: Creates `hooks.json` linking SessionStart and Stop events to plugin scripts
3. **Script Download**: Fetches `hook.py` and `stop-hook.sh` from the server's `/api/hook/` endpoints
4. **MCP Registration**: Creates `.mcp.json` exposing memory, recall, and recommend tools

资料来源：[src/piloci/installer.py:50-80]()

## Deployment Architecture

piLoci is designed for self-hosted deployment, typically on a Raspberry Pi 5 within the user's local network. The system supports exposure through reverse proxies or tunnels for remote access.

### Docker Deployment

The recommended deployment uses Docker Compose with the following service structure:

```yaml
services:
  piloci:
    image: ghcr.io/jshsakura/oc-piloci:latest
    ports:
      - "8314:8314"
    volumes:
      - ./data:/data
    environment:
      - BASE_URL=https://piloci.example.com
      - DATABASE_URL=sqlite:///data/piloci.db
```

资料来源：[docker-compose.yml](https://github.com/jshsakura/oc-piloci/blob/main/docker-compose.yml)

### Reverse Proxy Configuration

When deploying behind a reverse proxy (Cloudflare Tunnel, Caddy, nginx), port 8314 should be exposed externally. The `BASE_URL` environment variable must be set to the external HTTPS domain for proper OAuth callback URL generation.

Google OAuth requires exact callback URI matching:
```
https://piloci.opencourse.kr/auth/google/callback
```

资料来源：[README.ko.md:25-40]()

## Client Connection Flow

The system supports multiple AI clients through standardized MCP interfaces. Each client has specific integration requirements.

```mermaid
sequenceDiagram
    participant User
    participant CLI as piloci CLI
    participant Browser
    participant Server as piLoci Server
    participant Claude as Claude Code

    User->>CLI: piloci login
    CLI->>Browser: Opens /device page
    User->>Browser: Login + Approve
    Browser->>Server: Token exchange
    Server->>CLI: Token + URLs
    CLI->>CLI: Write ~/.config/piloci/config.json
    CLI->>Server: Register MCP server
    User->>Claude: Start session
    Claude->>CLI: MCP tool calls (memory/recall/recommend)
    CLI->>Server: API requests
    Server->>Claude: Memory results
```

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

### Supported Clients

| Client | MCP Support | Hook Support | Configuration Location |
|--------|-------------|--------------|------------------------|
| Claude Code | Full | SessionStart + Stop | `~/.claude.json`, `~/.claude/settings.json` |
| Claude Desktop | Full | N/A | `~/Library/Application Support/Claude/` |
| OpenCode | Full | N/A | `~/.config/opencode/opencode.json` |
| Cursor | Partial | N/A | Cursor MCP settings |

资料来源：[web/components/TokenManager.tsx:1-30]()

## Distillation System

The distillation system processes captured sessions to extract structured memories. It operates as a configurable background worker with temperature and load-based throttling.

### Distillation Settings

| Parameter | Purpose | Default Behavior |
|-----------|---------|------------------|
| Temperature Ceiling | SoC temperature threshold (°C) | Worker pauses when exceeded |
| Load Ceiling | 1-minute load average limit | Worker pauses when exceeded |
| Overflow Threshold | Workload threshold for aggressive processing | Ignores load when exceeded |

资料来源：[web/components/DistillationSettingsPanel.tsx:1-40]()

### Processing Pipeline

1. **Session Capture**: Hook scripts send transcripts via the ingest API
2. **Transcript Storage**: Raw content stored with session metadata
3. **Embedding Generation**: fastembed creates vector representations
4. **Memory Extraction**: LLM processes transcript to identify key learnings
5. **Vector Indexing**: Extracted memories indexed in LanceDB for retrieval

## Admin Console

The admin console (`web/app/admin/users/page.tsx`) provides administrative oversight with user management and system statistics.

### Admin Features

| Feature | Description | Endpoint |
|---------|-------------|----------|
| User Statistics | Total, pending, admin counts | Calculated from database |
| User Management | View and manage user accounts | `/api/admin/users` |
| System Health | Dashboard with key metrics | DashboardSummaryPanels |

资料来源：[web/app/admin/users/page.tsx:1-50]()

## Version Management

The system uses a single-source version policy where `pyproject.toml` is the authoritative version source. The `piloci.__version__` is derived from package metadata rather than hardcoded values.

### Release Process

1. Update version in `pyproject.toml` (patch increment by default)
2. Run validation: `pytest tests/ -v` and `uv build`
3. Tag with matching version: `git tag v{version}`
4. Push tag to trigger GitHub Actions workflow

The publish workflow (`publish.yml`) performs tag/version consistency checks, runs tests, builds the web app, publishes Docker images, creates GitHub Release, and publishes to PyPI.

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

## Development Workflow

Development follows a session-based approach where each implementation session begins by reviewing `PLAN.md` and checking the current status section for the next incomplete item.

### Development Stack Commands

```bash
# Backend development
cd src
uv run pytest tests/ -v
uv run black .
uv run ruff check .

# Frontend development
cd web
pnpm install --frozen-lockfile
pnpm build
```

资料来源：[README.md:60-75]()

## System Data Flow

```mermaid
graph LR
    subgraph Capture["Capture Phase"]
        Transcript["User/AI Transcript"]
        Hook["SessionStart Hook"]
    end

    subgraph Process["Processing Phase"]
        Ingest["Ingest API"]
        Embed["Embedding (fastembed)"]
        Extract["Memory Extraction"]
    end

    subgraph Store["Storage Phase"]
        SQLite["SQLite (Metadata)"]
        LanceDB["LanceDB (Vectors)"]
        Redis["Redis (Cache)"]
    end

    subgraph Retrieve["Retrieval Phase"]
        Recall["recall tool"]
        Recommend["recommend tool"]
        Search["Vector Search"]
    end

    Transcript --> Hook
    Hook --> Ingest
    Ingest --> Embed
    Embed --> Extract
    Extract --> SQLite
    Extract --> LanceDB
    Ingest --> Redis

    Recall --> Search
    Recommend --> Search
    Search --> LanceDB
    Search --> Retrieve
```

## Summary

piLoci's architecture reflects a pragmatic approach to self-hosted AI memory management. By combining FastAPI for the backend, Next.js for the frontend, and purpose-built storage solutions (SQLite, LanceDB, Redis), the system achieves a balance between simplicity and capability. The MCP integration layer enables seamless interaction with popular AI coding tools while maintaining client neutrality. The modular design allows each component to be upgraded or replaced independently, and the Docker-based deployment ensures consistent behavior across different host environments.

---

<a id='tech-stack'></a>

## Technology Stack

### 相关页面

相关主题：[System Architecture](#architecture-overview), [Storage Layer](#storage-layer), [Web Dashboard](#web-dashboard)

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

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

- [pyproject.toml](https://github.com/jshsakura/oc-piloci/blob/main/pyproject.toml)
- [web/package.json](https://github.com/jshsakura/oc-piloci/blob/main/web/package.json)
- [src/piloci/storage/lancedb_store.py](https://github.com/jshsakura/oc-piloci/blob/main/src/piloci/storage/lancedb_store.py)
- [docs/ADR-014-lancedb-backend.md](https://github.com/jshsakura/oc-piloci/blob/main/docs/ADR-014-lancedb-backend.md)
- [MEMORY.md](https://github.com/jshsakura/oc-piloci/blob/main/MEMORY.md)
- [web/DESIGN-HARNESS.md](https://github.com/jshsakura/oc-piloci/blob/main/web/DESIGN-HARNESS.md)
- [README.md](https://github.com/jshsakura/oc-piloci/blob/main/README.md)
- [README.ko.md](https://github.com/jshsakura/oc-piloci/blob/main/README.ko.md)
</details>

# Technology Stack

piLoci is a memory curation system built on a modern, lightweight technology stack designed for privacy-focused local deployment. The architecture combines a Python-based API backend with a Next.js frontend, leveraging specialized databases for vector storage and session management.

## Architecture Overview

```mermaid
graph TB
    subgraph "Client Layer"
        ClaudeCode["Claude Code"]
        OpenCode["OpenCode"]
        Cursor["Cursor"]
    end
    
    subgraph "Frontend Layer (Next.js)"
        WebApp["Next.js Web App<br/>:3000"]
        UI["shadcn/ui + TailwindCSS"]
    end
    
    subgraph "Backend Layer (Python)"
        API["FastAPI + Uvicorn<br/>:8314"]
        MCP["MCP Server Tools"]
        Auth["Google OAuth"]
    end
    
    subgraph "Storage Layer"
        SQLite["SQLite<br/>Identity Data"]
        LanceDB["LanceDB<br/>Vector Storage"]
        Redis["Redis<br/>Sessions"]
        FastEmbed["FastEmbed<br/>ONNX Embeddings"]
    end
    
    ClaudeCode --> MCP
    OpenCode --> MCP
    Cursor --> MCP
    WebApp --> API
    API --> SQLite
    API --> LanceDB
    API --> Redis
    LanceDB --> FastEmbed
```

## Backend Technology

### Core Framework

| Component | Technology | Purpose |
|-----------|------------|---------|
| Web Framework | FastAPI | Async API server with automatic OpenAPI docs |
| ASGI Server | Uvicorn | High-performance ASGI server |
| ORM | SQLAlchemy | Database abstraction and migrations |
| Validation | Pydantic | Data validation and serialization |

资料来源：[pyproject.toml:1-50](https://github.com/jshsakura/oc-piloci/blob/main/pyproject.toml)

### Data Storage

#### SQLite — Identity Data

SQLite serves as the primary relational database for storing user identity, project metadata, and session records. It provides ACID compliance with minimal overhead, making it ideal for single-instance deployments.

```python
# Simplified storage layer pattern
from sqlalchemy import create_engine
engine = create_engine("sqlite:///piloci.db")
```

资料来源：[pyproject.toml:20-35](https://github.com/jshsakura/oc-piloci/blob/main/pyproject.toml)

#### LanceDB — Vector Storage

LanceDB is the vector database for semantic memory storage. It offers:

- Columnar storage format optimized for ML workloads
- Native Python bindings
- Efficient similarity search on embedded vectors
- Persistent storage with automatic indexing

```python
# From the LanceDB store implementation
import lancedb
db = lancedb.connect("./data/lancedb")
table = db.open_table("memories")
```

资料来源：[src/piloci/storage/lancedb_store.py:1-30](https://github.com/jshsakura/oc-piloci/blob/main/src/piloci/storage/lancedb_store.py)

The decision to use LanceDB was documented in ADR-014, citing advantages over alternatives like ChromaDB and Qdrant for local-first deployments.

资料来源：[docs/ADR-014-lancedb-backend.md:1-25](https://github.com/jshsakura/oc-piloci/blob/main/docs/ADR-014-lancedb-backend.md)

#### Redis — Session Management

Redis handles ephemeral session data with millisecond latency. It supports:

- Session token storage and validation
- Real-time session state tracking
- Pub/sub for distributed caching

资料来源：[README.md:50-60](https://github.com/jshsakura/oc-piloci/blob/main/README.md)

### Embeddings Engine

**FastEmbed** provides ONNX-based embedding inference with these characteristics:

| Feature | Description |
|---------|-------------|
| Runtime | ONNX (Open Neural Network Exchange) |
| Deployment | On-device inference |
| Speed | Optimized for CPU execution |
| Privacy | No external API calls for embedding generation |

资料来源：[README.md:55-60](https://github.com/jshsakura/oc-piloci/blob/main/README.md)

```python
# Embedding generation (conceptual)
from fastembed import TextEmbedding
model = TextEmbedding(model_name="BAAI/bge-small-en-v1.5")
embeddings = list(model.embed(documents))
```

资料来源：[pyproject.toml:40-50](https://github.com/jshsakura/oc-piloci/blob/main/pyproject.toml)

### Authentication

| Provider | Protocol | Library |
|----------|----------|---------|
| Google OAuth 2.0 | OAuth 2.0 | Authlib |

资料来源：[pyproject.toml:25-40](https://github.com/jshsakura/oc-piloci/blob/main/pyproject.toml)

Google OAuth requires proper `BASE_URL` configuration when behind a reverse proxy:

```env
BASE_URL=https://piloci.opencourse.kr
```

资料来源：[README.ko.md:100-110](https://github.com/jshsakura/oc-piloci/blob/main/README.ko.md)

## Frontend Technology

### Framework & Runtime

| Component | Technology | Version |
|-----------|------------|---------|
| Framework | Next.js | 15.x |
| Language | TypeScript | 5.x |
| Runtime | React | 19.x |
| Package Manager | pnpm | 9.x |

资料来源：[web/package.json:1-30](https://github.com/jshsakura/oc-piloci/blob/main/web/package.json)

### UI Components

| Layer | Library | Purpose |
|-------|---------|---------|
| CSS Framework | TailwindCSS | Utility-first styling |
| Component Library | shadcn/ui | Accessible, customizable components |
| Icons | Lucide React | Consistent icon system |
| Styling Pattern | CSS Variables | Design token system via `--pi-*` variables |

资料来源：[web/DESIGN-HARNESS.md:1-20](https://github.com/jshsakura/oc-piloci/blob/main/web/DESIGN-HARNESS.md)

### Design System Pattern

The frontend follows a standardized page pattern with consistent CSS class naming:

```tsx
<AppShell>
  <div className="pi-page">
    <section className="pi-page-hero">
      <p className="pi-eyebrow">Area label</p>
      <h1 className="pi-title mt-2">Page title</h1>
      <p className="pi-subtitle">One sentence explaining the page.</p>
    </section>
    {/* Content sections */}
  </div>
</AppShell>
```

资料来源：[web/DESIGN-HARNESS.md:20-35](https://github.com/jshsakura/oc-piloci/blob/main/web/DESIGN-HARNESS.md)

## Infrastructure & Deployment

### Containerization

```yaml
# docker-compose.yml structure
services:
  api:
    build: .
    ports:
      - "8314:8314"
  redis:
    image: redis:alpine
  # SQLite and LanceDB are file-based, mounted as volumes
```

资料来源：[MEMORY.md:1-20](https://github.com/jshsakura/oc-piloci/blob/main/MEMORY.md)

### Hardware Targets

| Platform | Use Case | Notes |
|----------|----------|-------|
| Raspberry Pi 5 | Primary target | Local deployment, Cloudflare Tunnel access |
| x86_64 Server | Production | Multi-arch Docker images |
| ARM64 | Edge computing | Supported via Docker multi-arch builds |

资料来源：[README.ko.md:30-45](https://github.com/jshsakura/oc-piloci/blob/main/README.ko.md)

### Network Configuration

| Port | Service | Protocol |
|------|---------|----------|
| 3000 | Next.js Frontend | HTTP/HTTPS |
| 8314 | FastAPI Backend | HTTP (internal) |
| 6379 | Redis | TCP (internal) |

资料来源：[README.ko.md:95-105](https://github.com/jshsakura/oc-piloci/blob/main/README.ko.md)

### Reverse Proxy Support

- **Cloudflare Tunnel** — Remote access without port forwarding
- **Caddy** — Automatic HTTPS
- **nginx** — Traditional reverse proxy
- **Custom BASE_URL** — Required for OAuth callbacks behind proxies

资料来源：[README.ko.md:95-100](https://github.com/jshsakura/oc-piloci/blob/main/README.ko.md)

## MCP Integration

The Model Context Protocol (MCP) enables AI assistants to interact with piLoci's memory system:

```mermaid
graph LR
    AI["AI Assistant<br/>(Claude Code, OpenCode, Cursor)"]
    MCP["MCP Server<br/>piloci.tools"]
    API["piLoci API<br/>:8314"]
    DB["Storage Layer"]
    
    AI -->|"MCP Protocol"| MCP
    MCP -->|"REST API"| API
    API -->|"Query/Store"| DB
```

| Tool | Function |
|------|----------|
| `memory` | Store new memories from conversation context |
| `recall` | Semantic search through stored memories |
| `recommend` | Context-aware memory suggestions |

资料来源：[README.md:20-40](https://github.com/jshsakura/oc-piloci/blob/main/README.md)

## Technology Decision Records

Key architectural decisions are documented in the `/docs/ADR-*` directory:

| ADR | Topic | Status |
|-----|-------|--------|
| ADR-014 | LanceDB Backend Selection | Implemented |
| ADR-015 | FastEmbed for Embeddings | Implemented |

资料来源：[docs/ADR-014-lancedb-backend.md:1-10](https://github.com/jshsakura/oc-piloci/blob/main/docs/ADR-014-lancedb-backend.md)

## Development Workflow

### Local Development Stack

```bash
# Backend
uv run pytest tests/ -v
uv build
uv run uvicorn src.piloci.api.main:app --reload --port 8314

# Frontend
cd web && pnpm install
pnpm dev    # Development server
pnpm build  # Production build
```

资料来源：[MEMORY.md:50-70](https://github.com/jshsakura/oc-piloci/blob/main/MEMORY.md)

### Release Process

```bash
# 1. Update version in pyproject.toml (+0.0.1 patch unit)
# 2. Validate
pytest tests/ -v
uv build

# 3. Tag and push
git tag v{version}
git push origin main v{version}
```

资料来源：[CLAUDE.md:25-40](https://github.com/jshsakura/oc-piloci/blob/main/CLAUDE.md)

GitHub Actions `publish.yml` handles:
- Version guard validation
- Test execution gate
- Web app build artifact
- Multi-arch Docker image publishing
- GitHub Release creation
- PyPI package publication (`oc-piloci`)

资料来源：[CLAUDE.md:20-30](https://github.com/jshsakura/oc-piloci/blob/main/CLAUDE.md)

## Version Management

Version is managed as a single source of truth in `pyproject.toml`:

```toml
[project]
version = "0.3.0"
```

All release artifacts (Docker images, PyPI packages, GitHub releases) derive their versions from this field. No separate version files should be modified.

资料来源：[CLAUDE.md:10-25](https://github.com/jshsakura/oc-piloci/blob/main/CLAUDE.md)

## Summary

| Layer | Technology | Key Benefit |
|-------|------------|-------------|
| API | FastAPI + Uvicorn | Async performance, auto docs |
| Database | SQLite | Zero-config, portable |
| Vectors | LanceDB + FastEmbed | Local ML inference |
| Sessions | Redis | Sub-millisecond latency |
| Frontend | Next.js + shadcn/ui | Type-safe, accessible UI |
| Auth | Google OAuth (Authlib) | Secure SSO |
| Deployment | Docker + Cloudflare Tunnel | Edge-ready |

---

<a id='mcp-server'></a>

## MCP Server Implementation

### 相关页面

相关主题：[API Routes](#api-routes), [Authentication & Security](#authentication), [Curator Pipeline](#curator-pipeline)

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

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

- [src/piloci/mcp/server.py](https://github.com/jshsakura/oc-piloci/blob/main/src/piloci/mcp/server.py)
- [src/piloci/mcp/streamable_http.py](https://github.com/jshsakura/oc-piloci/blob/main/src/piloci/mcp/streamable_http.py)
- [src/piloci/mcp/sse.py](https://github.com/jshsakura/oc-piloci/blob/main/src/piloci/mcp/sse.py)
- [src/piloci/mcp/session_state.py](https://github.com/jshsakura/oc-piloci/blob/main/src/piloci/mcp/session_state.py)
- [src/piloci/tools/memory_tools.py](https://github.com/jshsakura/oc-piloci/blob/main/src/piloci/tools/memory_tools.py)
- [src/piloci/tools/instinct_tools.py](https://github.com/jshsakura/oc-piloci/blob/main/src/piloci/tools/instinct_tools.py)
</details>

# MCP Server Implementation

## Overview

The MCP (Model Context Protocol) Server in piLoci provides a standardized interface for AI clients (Claude Code, Claude Desktop, OpenCode, Cursor) to interact with piLoci's memory and cognitive services. This implementation exposes memory management tools, recall capabilities, and recommendation functions as MCP tools that can be invoked by AI assistants during conversations.

The MCP server architecture is designed for:

- **Session-aware context management** — Tracking and persisting conversation context across sessions
- **Tool-based memory operations** — Enabling LLMs to create, search, and retrieve memories
- **Multi-client support** — Serving multiple AI clients simultaneously with isolated state
- **Streaming communication** — Supporting both HTTP streaming and Server-Sent Events (SSE)

资料来源：[README.md](https://github.com/jshsakura/oc-piloci/blob/main/README.md)

---

## Architecture

### Component Overview

```mermaid
graph TD
    subgraph "AI Clients"
        CC[Claude Code]
        CD[Claude Desktop]
        OC[OpenCode]
        CU[Cursor]
    end

    subgraph "MCP Server Layer"
        SERVER[MCP Server]
        HTTP[Streamable HTTP]
        SSE[Server-Sent Events]
        SESSION[Session State Manager]
    end

    subgraph "Tools Layer"
        MEM[memory_tools.py]
        INST[instinct_tools.py]
    end

    subgraph "Backend Services"
        API[API Routes]
        DB[(SQLite)]
        LANCE[(LanceDB)]
        REDIS[(Redis)]
    end

    CC --> SERVER
    CD --> SERVER
    OC --> SERVER
    CU --> SERVER
    
    SERVER --> HTTP
    SERVER --> SSE
    SERVER --> SESSION
    
    SERVER --> MEM
    SERVER --> INST
    
    MEM --> API
    INST --> API
    
    API --> DB
    API --> LANCE
    API --> REDIS
```

### Directory Structure

```
src/piloci/mcp/
├── server.py           # Core MCP server implementation
├── streamable_http.py  # HTTP streaming transport
├── sse.py              # Server-Sent Events transport
├── session_state.py    # Session state management
└── __init__.py

src/piloci/tools/
├── memory_tools.py     # Memory-related MCP tools
├── instinct_tools.py   # Instinct/recommendation tools
└── __init__.py
```

资料来源：[README.md](https://github.com/jshsakura/oc-piloci/blob/main/README.md) and [CLAUDE.md](https://github.com/jshsakura/oc-piloci/blob/main/CLAUDE.md)

---

## MCP Server Core

### Server Initialization

The main MCP server is implemented in `src/piloci/mcp/server.py`. It follows the standard MCP protocol implementation, providing:

- Tool registration and schema management
- Request/response handling
- Protocol negotiation
- Authentication integration

### Tool Registration

MCP tools are registered through `src/piloci/mcp/tools.py` and implemented in the `src/piloci/tools/` directory.

资料来源：[CLAUDE.md](https://github.com/jshsakura/oc-piloci/blob/main/CLAUDE.md)

---

## Transport Layer

piLoci supports two transport mechanisms for MCP communication:

### Streamable HTTP

Located in `src/piloci/mcp/streamable_http.py`, this transport provides:

- Bidirectional streaming over HTTP
- Long-poll fallback for clients without streaming support
- Request/response multiplexing

### Server-Sent Events (SSE)

Located in `src/piloci/mcp/sse.py`, this transport provides:

- Server-to-client event streaming
- Lightweight alternative for simple use cases
- Automatic reconnection handling

### Transport Comparison

| Feature | Streamable HTTP | SSE |
|---------|-----------------|-----|
| Bidirectional | ✅ Full duplex | ❌ Server-to-client only |
| Latency | Low | Low |
| Browser Compatibility | Requires polling fallback | Native browser support |
| Use Case | Claude Code, Desktop | Simple integrations |

---

## Session State Management

### Session State Module

The `src/piloci/mcp/session_state.py` module manages:

- **Session lifecycle** — Creation, tracking, and cleanup of client sessions
- **Context isolation** — Ensuring each client's memory space remains isolated
- **State persistence** — Persisting session context across restarts

```mermaid
stateDiagram-v2
    [*] --> Unauthenticated: Client connects
    Unauthenticated --> Authenticated: Token validated
    Authenticated --> Active: Session started
    Active --> Active: Tools invoked
    Active --> Paused: Client idle timeout
    Paused --> Active: Client reconnects
    Active --> [*]: Session ended
```

### Session Data Flow

```mermaid
graph LR
    A[AI Client] -->|Tool Request| B[MCP Server]
    B -->|Lookup Session| C[Session State]
    C -->|Session Context| B
    B -->|Execute Tool| D[Tools Layer]
    D -->|Results + Updated State| B
    B -->|Response| A
    B -->|Persist State| C
```

---

## MCP Tools

### Memory Tools

Implemented in `src/piloci/tools/memory_tools.py`, these tools provide:

| Tool Name | Purpose | Description |
|-----------|---------|-------------|
| `memory` | Create memories | Store new information from conversations |
| `recall` | Search memories | Retrieve relevant memories based on query |
| `recommend` | Context suggestions | Suggest relevant memories for current context |

#### Tool Schema Requirements

According to project conventions in `CLAUDE.md`:

- Tool descriptions must be ≤ 120 characters
- Parameter descriptions must be ≤ 80 characters
- All schemas must pass `compact_schema()` validation

资料来源：[CLAUDE.md](https://github.com/jshsakura/oc-piloci/blob/main/CLAUDE.md)

### Instinct Tools

Implemented in `src/piloci/tools/instinct_tools.py`, these tools provide:

- Pattern recognition based on historical interactions
- Proactive memory suggestions
- Contextual recommendations

### Tool Testing

All MCP tools must have corresponding tests:

```
tests/test_tools_*.py
```

资料来源：[CLAUDE.md](https://github.com/jshsakura/oc-piloci/blob/main/CLAUDE.md)

---

## Client Integration

### Supported Clients

piLoci's MCP server integrates with the following AI clients:

| Client | Config File | MCP Tools | Hooks |
|--------|-------------|-----------|-------|
| Claude Desktop | `claude_desktop_config.json` | ✅ | N/A |
| Claude Code | `~/.claude.json`, `.mcp.json` | ✅ | SessionStart, Stop |
| OpenCode | `opencode.json` | ✅ | ❌ |
| Cursor | Cursor config | ✅ | N/A |

### Claude Code Integration

For Claude Code, the MCP server is installed via `src/piloci/installer.py`:

```python
install_codex_mcp(base_url: str, token: str, *, home: Path | None = None) -> Path
```

This function:

1. Downloads hook scripts to `~/.config/piloci/`
2. Updates Claude Code's configuration files
3. Registers the MCP server in `~/.claude.json`

资料来源：[src/piloci/installer.py](https://github.com/jshsakura/oc-piloci/blob/main/src/piloci/installer.py)

### File-Based Configuration

The installer creates the following structure:

```
~/.config/piloci/
├── config.json          # Token + ingest/analyze URLs
├── hook.py              # SessionStart catch-up script
└── stop-hook.sh        # Stop live push script

~/.claude.json           # MCP server entries (Claude Code)
.mcp.json               # Additional MCP configuration
```

资料来源：[README.ko.md](https://github.com/jshsakura/oc-piloci/blob/main/README.ko.md)

---

## Installation Flow

```mermaid
sequenceDiagram
    participant User
    participant CLI as piloci CLI
    participant Installer as installer.py
    participant Config as Config Files
    participant MCPServer as MCP Server

    User->>CLI: piloci install --client claude-code
    CLI->>Installer: install_codex_mcp()
    Installer->>Installer: Download hook scripts
    Installer->>Config: Write config.json
    Installer->>Config: Update ~/.claude.json
    Installer->>MCPServer: Register MCP tools
    Config-->>User: Installation complete
```

---

## Configuration

### Server Configuration

The MCP server is configured through environment variables:

| Variable | Description | Example |
|----------|-------------|---------|
| `BASE_URL` | External HTTPS domain | `https://piloci.example.com` |
| `PORT` | Server port (default: 8314) | `8314` |

### Client-Side Configuration

Each client requires specific configuration to connect to the MCP server:

```json
{
  "mcpServers": {
    "piloci": {
      "command": "python",
      "args": ["-m", "piloci.mcp.server"],
      "env": {
        "PILOCI_TOKEN": "<user_token>"
      }
    }
  }
}
```

---

## API Endpoints

The MCP server exposes the following API routes (defined in `src/piloci/api/routes.py`):

| Endpoint | Method | Description |
|----------|--------|-------------|
| `/api/memories` | POST | Create a new memory (project-scoped) |
| `/api/memories` | GET | List memories for context |
| `/api/projects/{id}/freshness` | GET | Check project data freshness |
| `/api/distillation/run-now` | POST | Trigger manual distillation |
| `/api/budget/usage` | GET | Get external LLM budget usage |
| `/api/preferences` | GET/PATCH | Get/update distillation preferences |

资料来源：[web/lib/api.ts](https://github.com/jshsakura/oc-piloci/blob/main/web/lib/api.ts)

---

## Security Considerations

### Token-Based Authentication

- All MCP communications require a valid token
- Tokens are stored in `~/.config/piloci/config.json` with mode `0600`
- No token characters are exposed in logs or error messages

### Data Isolation

- Each client's data is isolated by session
- Project-scoped memories prevent cross-project data leakage
- User authentication via Google OAuth

资料来源：[README.ko.md](https://github.com/jshsakura/oc-piloci/blob/main/README.ko.md)

---

## Testing

### Test Coverage

MCP functionality is tested via:

- `tests/test_tools_*.py` — Tool-specific tests
- `tests/test_vault_cache.py` — Vault and caching tests

### Test Commands

```bash
# Run all MCP-related tests
uv run pytest tests/test_tools_*.py -v

# Run with coverage
uv run pytest tests/test_vault_cache.py -v --no-cov
```

资料来源：[MEMORY.md](https://github.com/jshsakura/oc-piloci/blob/main/MEMORY.md)

---

## Development Guidelines

### Adding New MCP Tools

1. Implement in `src/piloci/tools/`
2. Register in `src/piloci/mcp/tools.py`
3. Keep descriptions within character limits
4. Validate with `compact_schema()`
5. Add tests in `tests/test_tools_*.py`

### Code Quality

| Tool | Configuration |
|------|----------------|
| Formatter | black (line-length=100) |
| Linter | ruff |
| Import sorting | isort (profile=black) |

Run pre-commit hooks before committing:

```bash
uv run black .
uv run ruff check .
uv run isort .
```

资料来源：[CLAUDE.md](https://github.com/jshsakura/oc-piloci/blob/main/CLAUDE.md)

---

## See Also

- [API Routes Implementation](./api-routes.md)
- [Memory Module](./memory.md)
- [Frontend Architecture](../web/architecture.md)
- [Installation Guide](./installation.md)

---

<a id='authentication'></a>

## Authentication & Security

### 相关页面

相关主题：[MCP Server Implementation](#mcp-server), [API Routes](#api-routes), [Database Models](#database-models)

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

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

- [src/piloci/auth/oauth.py](https://github.com/jshsakura/oc-piloci/blob/main/src/piloci/auth/oauth.py)
- [src/piloci/auth/crypto.py](https://github.com/jshsakura/oc-piloci/blob/main/src/piloci/auth/crypto.py)
- [src/piloci/auth/session.py](https://github.com/jshsakura/oc-piloci/blob/main/src/piloci/auth/session.py)
- [src/piloci/auth/middleware.py](https://github.com/jshsakura/oc-piloci/blob/main/src/piloci/auth/middleware.py)
- [src/piloci/api/routes.py](https://github.com/jshsakura/oc-piloci/blob/main/src/piloci/api/routes.py)
- [src/piloci/db/models.py](https://github.com/jshsakura/oc-piloci/blob/main/src/piloci/db/models.py)
- [src/piloci/auth/install_pairing.py](https://github.com/jshsakura/oc-piloci/blob/main/src/piloci/auth/install_pairing.py)
</details>

# Authentication & Security

piLoci implements a comprehensive authentication and security system supporting multiple OAuth providers, encrypted token storage, Redis-based session management, and JWT authentication for API access. The system is designed for self-hosted deployment on resource-constrained environments like Raspberry Pi devices while maintaining enterprise-grade security practices.

## Architecture Overview

The authentication system consists of several interconnected layers:

```mermaid
graph TD
    A[Client] --> B[Next.js Frontend]
    A --> C[Python CLI Client]
    B --> D[FastAPI Backend /api/*]
    C --> D
    D --> E[OAuth Providers<br/>Google/Kakao/Naver]
    D --> F[Redis<br/>Session Store]
    D --> G[SQLite<br/>User Database]
    D --> H[LanceDB<br/>Memory Storage]
    G --> I[Encrypted OAuth Tokens<br/>Fernet + JWT Secret]
```

资料来源：[src/piloci/auth/oauth.py:1-50]()

## OAuth Authentication

piLoci supports authentication through multiple OAuth 2.0 providers, allowing users to sign in with existing accounts rather than creating new credentials.

### Supported Providers

| Provider | Auth URL | Token URL | User Info Endpoint | Scopes |
|----------|----------|-----------|-------------------|--------|
| Google | `https://accounts.google.com/o/oauth2/v2/auth` | `https://oauth2.googleapis.com/token` | `https://www.googleapis.com/oauth2/v3/userinfo` | `openid email profile` |
| Kakao | `https://kauth.kakao.com/oauth/authorize` | `https://kauth.kakao.com/oauth/token` | `https://kapi.kakao.com/v2/user/me` | `profile_nickname account_email` |
| Naver | `https://nid.naver.com/oauth2.0/authorize` | `https://nid.naver.com/oauth2.0/token` | `https://openapi.naver.com/v1/nid/me` | (none) |

资料来源：[src/piloci/auth/oauth.py:20-45]()

### OAuth Flow

```mermaid
sequenceDiagram
    participant U as User
    participant F as Frontend
    participant B as Backend
    participant P as OAuth Provider
    participant R as Redis

    U->>F: Click "Login with Provider"
    F->>B: GET /api/auth/providers
    B->>F: Return available providers
    F->>U: Redirect to OAuth authorization URL
    U->>P: Authorize application
    P->>U: Redirect with authorization code
    U->>B: GET /auth/{provider}/callback?code=XXX
    B->>P: Exchange code for tokens
    P->>B: Access token + Refresh token
    B->>B: Encrypt tokens with Fernet
    B->>G: Upsert user in SQLite
    B->>R: Create Redis session
    B->>U: Set session cookie, redirect to dashboard
```

### Provider Configuration

Each OAuth provider is configured using a `ProviderConfig` dataclass that encapsulates all provider-specific settings:

```python
@dataclass
class ProviderConfig:
    name: str
    auth_url: str
    token_url: str
    userinfo_url: str
    scopes: str
    extract_user: Callable[[dict], OAuthUserInfo]
```

资料来源：[src/piloci/auth/oauth.py:1-20]()

### Building Authorization URLs

The `build_auth_url()` function constructs OAuth authorization URLs with provider-specific parameters:

```python
def build_auth_url(provider: str, client_id: str, redirect_uri: str, state: str) -> str:
    provider_config = _get_provider(provider)
    params: dict[str, str] = {
        "client_id": client_id,
        "redirect_uri": redirect_uri,
        "response_type": "code",
        "state": state,
    }
    if provider_config.scopes:
        params["scope"] = provider_config.scopes
    params.update(provider_config.extra_auth_params)
    return f"{provider_config.auth_url}?{urlencode(params)}"
```

资料来源：[src/piloci/auth/oauth.py:67-80]()

### User Information Extraction

Each provider returns user data in different formats. The `extract_user` callback normalizes this data into a standard `OAuthUserInfo` structure:

```python
@dataclass
class OAuthUserInfo:
    provider: str
    provider_user_id: str
    email: str | None
    name: str | None
```

Provider-specific extractors handle the normalization:
- `_extract_github_user()` for GitHub (if configured)
- `_extract_kakao_user()` for Kakao API v2 response format
- `_extract_naver_user()` for Naver's response envelope

资料来源：[src/piloci/auth/oauth.py:1-50]()

## Encrypted Token Storage

OAuth tokens are encrypted before storage to prevent exposure even if the database is compromised.

### Encryption Mechanism

piLoci uses **Fernet symmetric encryption** with a key derived from the JWT secret:

```mermaid
graph LR
    A[JWT Secret<br/>from settings] --> B[Key Derivation<br/>Function]
    B --> C[Fernet Key<br/>32-byte key]
    C --> D[Fernet.encrypt<br/>OAuth Token]
    C --> E[Fernet.decrypt<br/>Stored Token]
```

资料来源：[src/piloci/auth/crypto.py:1-20]()

### Token Storage Schema

The `User` model in SQLite stores encrypted OAuth credentials:

| Column | Type | Description |
|--------|------|-------------|
| `oauth_provider` | String (nullable) | Provider name (google/kakao/naver) |
| `oauth_provider_user_id` | String (nullable) | User ID from the provider |
| `oauth_access_token` | String (nullable, encrypted) | Encrypted OAuth access token |
| `oauth_refresh_token` | String (nullable, encrypted) | Encrypted OAuth refresh token |

资料来源：[src/piloci/db/models.py:1-100]()

### Token Encryption Flow

```python
async def upsert_oauth_user(
    provider: str,
    provider_user_id: str,
    access_token: str,
    refresh_token: str | None,
    email: str | None,
    name: str | None,
) -> User:
    # Encrypt tokens before storage
    encrypted_access = encrypt_token(access_token)
    encrypted_refresh = encrypt_token(refresh_token) if refresh_token else None
    
    # Upsert user with encrypted tokens
    ...
```

资料来源：[src/piloci/auth/oauth.py:100-150]()

## Session Management

Sessions are managed through Redis for fast, stateless authentication validation.

### Session Architecture

```mermaid
graph TD
    A[Request] --> B[Auth Middleware]
    B --> C{Check Session Cookie}
    C -->|No Cookie| D[Return 401]
    C -->|Has Cookie| E[Query Redis]
    E --> F{Valid Session?}
    F -->|No| D
    F -->|Yes| G[Attach User to Request]
    G --> H[Proceed to Route Handler]
```

资料来源：[src/piloci/auth/middleware.py:1-50]()

### Session Structure

Sessions stored in Redis contain the authenticated user's identity:

```json
{
  "user_id": "uuid-string",
  "email": "user@example.com",
  "created_at": "2024-01-01T00:00:00Z",
  "expires_at": "2024-01-01T12:00:00Z"
}
```

资料来源：[src/piloci/auth/session.py:1-50]()

### Provider Disconnect Flow

Users can disconnect OAuth providers from their account. The disconnect process:

1. Validates the logged-in Redis session
2. Verifies password presence as a safety check
3. Revokes the provider token remotely via `revoke_provider_token()`
4. Clears local OAuth fields even if remote revoke fails

资料来源：[src/piloci/api/routes.py:1-100]()

```mermaid
sequenceDiagram
    participant U as User
    participant F as Frontend
    participant B as Backend
    participant R as Redis
    participant P as OAuth Provider

    U->>F: Click "Disconnect {provider}"
    F->>B: POST /auth/{provider}/disconnect
    B->>R: Validate session
    B->>B: Check password exists
    B->>P: Revoke provider token
    P-->>B: Revocation confirmation
    B->>B: Encrypt/clear OAuth fields
    B->>R: Update session
    B-->>F: Success response
```

## API Authentication

### Provider Discovery Endpoint

The frontend dynamically discovers available OAuth providers:

```
GET /api/auth/providers
```

Returns the list of configured providers based on environment credentials:

```json
{
  "providers": ["google", "kakao", "naver"],
  "local": true
}
```

资料来源：[src/piloci/api/routes.py:100-200]()

### Authentication Callback Routes

| Route | Method | Description |
|-------|--------|-------------|
| `/auth/{provider}` | GET | Initiate OAuth flow |
| `/auth/{provider}/callback` | GET | Handle OAuth callback |
| `/auth/{provider}/disconnect` | POST | Disconnect provider |

资料来源：[src/piloci/api/routes.py:200-300]()

## Rate Limiting

Authentication endpoints are protected by rate limiting to prevent brute-force attacks:

```python
# Rate limit configuration in tests
@pytest.mark.skip(reason="regression guard — re-enabled after config freeze")
async def test_auth_rate_limits():
    ...
```

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

Rate limit tests verify:
- Provider status route shape consistency
- Proper rate limiting headers
- Appropriate 429 responses after threshold exceeded

## Security Configuration

### Environment Variables

| Variable | Required | Description |
|----------|----------|-------------|
| `JWT_SECRET` | Yes | Secret key for JWT signing and Fernet encryption |
| `SESSION_SECRET` | Yes | Redis session encryption key |
| `BASE_URL` | Yes (production) | External HTTPS domain for OAuth callbacks |
| `GOOGLE_CLIENT_ID` | For Google OAuth | Google OAuth application client ID |
| `GOOGLE_CLIENT_SECRET` | For Google OAuth | Google OAuth application secret |
| `KAKAO_CLIENT_ID` | For Kakao OAuth | Kakao OAuth application client ID |
| `KAKAO_CLIENT_SECRET` | For Kakao OAuth | Kakao OAuth application secret |
| `NAVER_CLIENT_ID` | For Naver OAuth | Naver OAuth application client ID |
| `NAVER_CLIENT_SECRET` | For Naver OAuth | Naver OAuth application secret |

### OAuth Redirect URI Configuration

When deploying behind a reverse proxy, the `BASE_URL` environment variable must be set:

```env
BASE_URL=https://piloci.opencourse.kr
```

Google OAuth redirect URIs must match exactly. Register this callback in Google Cloud Console:

```
https://piloci.opencourse.kr/auth/google/callback
```

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

Without `BASE_URL`, the backend may construct callback URLs using local/internal request hosts, causing `redirect_uri_mismatch` errors even when credentials are correct.

## Development Guidelines

### Security Non-Negotiables

Per project development rules:

- All LanceDB queries **must** filter by `(user_id, project_id)` — omission causes data leakage
- Passwords: **argon2id only** — bcrypt is prohibited
- JWT secret and session secret must come from environment variables or Docker secrets only — no hardcoding in code
- Raw SQL is prohibited — use SQLAlchemy ORM exclusively
- All user input must be validated through Pydantic schemas before processing

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

### Testing Authentication

Run auth-related tests with:

```bash
uv run pytest tests/test_auth_rate_limits.py -v --no-cov
```

资料来源：[MEMORY.md:50-100]()

## Token-Based CLI Authentication

For the Python CLI client, token-based authentication is used:

```python
from piloci_client import (
    PilociError,           # base — all SDK errors
    PilociAuthError,       # HTTP 401
    PilociPermissionError, # HTTP 403
    PilociValidationError, # HTTP 422
    PilociServerError,     # HTTP 5xx
)
```

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

### Install Pairing Flow

The system supports device code flow for CLI authentication:

1. CLI displays a device code (`ABCD-1234`)
2. User opens `/device` page in browser
3. User logs in and approves
4. CLI polls and receives token
5. CLI auto-configures detected clients

资料来源：[src/piloci/auth/install_pairing.py:1-50]()

## Password-Based Authentication

### Password Reset Flow

The frontend provides password reset functionality at `/forgot-password`:

```tsx
<Link href="/forgot-password" className="text-sm text-muted-foreground">
  {t.login.forgotPassword}
</Link>
```

资料来源：[web/app/login/login-client.tsx:1-50]()

Error messages display in styled containers:

```tsx
<div className="bg-red-50 p-3 text-sm text-red-800 dark:bg-red-950">
  {serverError}
</div>
```

资料来源：[web/app/forgot-password/page.tsx:1-50]()

## Summary

piLoci's authentication and security system provides:

1. **Multi-provider OAuth** — Google, Kakao, Naver with provider-specific user extraction
2. **Encrypted token storage** — Fernet encryption using JWT secret-derived keys
3. **Redis session management** — Fast, stateless session validation
4. **Rate limiting** — Protection against brute-force attacks
5. **Provider disconnect** — Full OAuth account unlinking support
6. **Device code flow** — Secure CLI authentication for headless environments
7. **Production-ready configuration** — BASE_URL support for reverse proxy deployments

All authentication components follow the security non-negotiables defined in project development rules, ensuring consistent protection against common vulnerabilities.

---

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

## API Routes

### 相关页面

相关主题：[MCP Server Implementation](#mcp-server), [Authentication & Security](#authentication), [Storage Layer](#storage-layer)

<details>
<summary>Related Source Files</summary>

The following source files are used to generate this documentation:

- [src/piloci/api/routes.py](https://github.com/jshsakura/oc-piloci/blob/main/src/piloci/api/routes.py)
- [src/piloci/api/v1.py](https://github.com/jshsakura/oc-piloci/blob/main/src/piloci/api/v1.py)
- [src/piloci/api/team_routes.py](https://github.com/jshsakura/oc-piloci/blob/main/src/piloci/api/team_routes.py)
- [src/piloci/api/audit.py](https://github.com/jshsakura/oc-piloci/blob/main/src/piloci/api/audit.py)
- [src/piloci/api/data_portability.py](https://github.com/jshsakura/oc-piloci/blob/main/src/piloci/api/data_portability.py)
- [src/piloci/api/distillation_routes.py](https://github.com/jshsakura/oc-piloci/blob/main/src/piloci/api/distillation_routes.py)
- [src/piloci/api/ratelimit.py](https://github.com/jshsakura/oc-piloci/blob/main/src/piloci/api/ratelimit.py)
</details>

# API Routes

## Overview

The API Routes module in oc-piloci provides a comprehensive REST API layer for the platform, enabling programmatic interaction with agent orchestration, team management, auditing, data operations, and model distillation capabilities. The API follows a modular architecture with separate route handlers for different functional domains.

The routing system is built on FastAPI principles and organizes endpoints by API version and functional area, providing a clean separation of concerns while maintaining a unified API surface.

## Architecture

```mermaid
graph TD
    A[Client Request] --> B[API Gateway]
    B --> C[v1 Routes]
    C --> D[Team Routes]
    C --> E[Audit Routes]
    C --> F[Data Portability Routes]
    C --> G[Distillation Routes]
    D --> H[Rate Limiter]
    E --> H
    F --> H
    G --> H
    H --> I[Backend Services]
```

## Route Organization

### Core Route Files

| File | Purpose | Primary Responsibility |
|------|---------|------------------------|
| `routes.py` | Main router configuration | Entry point, aggregation of sub-routers |
| `v1.py` | API v1 versioning | Version-specific route mounting |
| `team_routes.py` | Team management | Team CRUD, membership, permissions |
| `audit.py` | Audit logging | Action tracking, audit trail retrieval |
| `data_portability.py` | Data operations | Import/export, data migration |
| `distillation_routes.py` | Model distillation | Knowledge distillation workflows |
| `ratelimit.py` | Rate limiting | Request throttling, quota management |

资料来源：[src/piloci/api/routes.py]()

## Versioned API Structure

The API uses URL-based versioning with v1 as the current stable version.

```mermaid
graph LR
    A[/api/v1/*] --> B[Version Router]
    B --> C[Team Endpoints]
    B --> D[Audit Endpoints]
    B --> E[Data Endpoints]
    B --> F[Distillation Endpoints]
```

### V1 Router Configuration

The v1 router serves as the main container for all v1 API endpoints, mounting sub-routers for each functional domain.

资料来源：[src/piloci/api/v1.py]()

## Team Routes

Team routes handle all team-related operations including team creation, member management, and team-level configurations.

### Supported Operations

| Operation | HTTP Method | Endpoint Pattern |
|-----------|-------------|------------------|
| List teams | GET | `/teams` |
| Create team | POST | `/teams` |
| Get team | GET | `/teams/{team_id}` |
| Update team | PUT | `/teams/{team_id}` |
| Delete team | DELETE | `/teams/{team_id}` |
| Add member | POST | `/teams/{team_id}/members` |
| Remove member | DELETE | `/teams/{team_id}/members/{user_id}` |
| List members | GET | `/teams/{team_id}/members` |

资料来源：[src/piloci/api/team_routes.py]()

## Audit Routes

Audit routes provide access to the system's audit trail, enabling compliance and monitoring use cases.

### Audit Features

- Action logging for all significant system events
- Queryable audit history by time range
- Filtering by user, team, or action type
- Audit report generation

### Common Audit Endpoints

| Endpoint | Description |
|----------|-------------|
| `GET /audit/events` | List audit events with filtering |
| `GET /audit/events/{event_id}` | Get specific audit event details |
| `GET /audit/teams/{team_id}` | Get team-specific audit history |

资料来源：[src/piloci/api/audit.py]()

## Data Portability Routes

Data portability endpoints support import and export operations for data migration and backup purposes.

### Data Operations

| Operation | Description |
|-----------|-------------|
| Export data | Generate downloadable data archives |
| Import data | Upload and process data packages |
| Data format conversion | Transform between supported formats |
| Partial sync | Incremental data synchronization |

资料来源：[src/piloci/api/data_portability.py]()

## Distillation Routes

Distillation routes manage model knowledge distillation workflows, enabling the transfer of knowledge from larger models to smaller, more efficient ones.

### Distillation Workflow

```mermaid
graph TD
    A[Teacher Model] --> B[Distillation Request]
    C[Student Model] --> B
    B --> D[Distillation Job]
    D --> E[Knowledge Transfer]
    E --> F[Trained Student Model]
    F --> G[Validation]
    G --> H[Model Registry]
```

### Distillation Endpoints

| Endpoint | Method | Description |
|----------|--------|-------------|
| `/distillation/jobs` | POST | Create new distillation job |
| `/distillation/jobs` | GET | List distillation jobs |
| `/distillation/jobs/{job_id}` | GET | Get job status |
| `/distillation/jobs/{job_id}` | DELETE | Cancel running job |

资料来源：[src/piloci/api/distillation_routes.py]()

## Rate Limiting

The rate limiting module protects the API from abuse and ensures fair resource allocation across clients.

### Rate Limit Configuration

| Parameter | Default | Description |
|-----------|---------|-------------|
| Requests per minute | 60 | Maximum requests per client per minute |
| Burst allowance | 10 | Temporary burst capacity |
| Window type | Sliding | Rate limit window algorithm |

### Rate Limit Headers

| Header | Description |
|--------|-------------|
| `X-RateLimit-Limit` | Maximum requests allowed |
| `X-RateLimit-Remaining` | Requests remaining in window |
| `X-RateLimit-Reset` | Unix timestamp when limit resets |

资料来源：[src/piloci/api/ratelimit.py]()

## Request/Response Patterns

### Standard Response Format

```json
{
  "success": true,
  "data": { },
  "meta": {
    "request_id": "uuid",
    "timestamp": "ISO8601"
  }
}
```

### Error Response Format

```json
{
  "success": false,
  "error": {
    "code": "ERROR_CODE",
    "message": "Human readable message"
  },
  "meta": {
    "request_id": "uuid",
    "timestamp": "ISO8601"
  }
}
```

## Authentication

API routes require authentication via Bearer tokens in the Authorization header:

```
Authorization: Bearer <token>
```

## Common Parameters

| Parameter | Location | Type | Description |
|-----------|----------|------|-------------|
| `team_id` | Path/Query | string | Team identifier |
| `user_id` | Path/Query | string | User identifier |
| `page` | Query | integer | Pagination offset |
| `page_size` | Query | integer | Results per page |
| `sort_by` | Query | string | Sort field |
| `order` | Query | string | Sort direction (asc/desc) |

## Middleware Stack

```mermaid
graph TD
    A[Request] --> B[Rate Limit Middleware]
    B --> C[Auth Middleware]
    C --> D[Validation Middleware]
    D --> E[Route Handler]
    E --> F[Response]
```

## Usage Examples

### Creating a Team

```bash
curl -X POST https://api.example.com/v1/teams \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "ML Research",
    "description": "Machine learning research team"
  }'
```

### Listing Audit Events

```bash
curl -X GET "https://api.example.com/v1/audit/events?team_id=123&from=2024-01-01" \
  -H "Authorization: Bearer <token>"

---

<a id='curator-pipeline'></a>

## Curator Pipeline

### 相关页面

相关主题：[Storage Layer](#storage-layer), [MCP Server Implementation](#mcp-server)

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

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

- [src/piloci/curator/__init__.py](https://github.com/jshsakura/oc-piloci/blob/main/src/piloci/curator/__init__.py)
- [src/piloci/curator/distillation_worker.py](https://github.com/jshsakura/oc-piloci/blob/main/src/piloci/curator/distillation_worker.py)
- [src/piloci/curator/gemma.py](https://github.com/jshsakura/oc-piloci/blob/main/src/piloci/curator/gemma.py)
- [src/piloci/curator/extraction.py](https://github.com/jshsakura/oc-piloci/blob/main/src/piloci/curator/extraction.py)
- [src/piloci/curator/prefilter.py](https://github.com/jshsakura/oc-piloci/blob/main/src/piloci/curator/prefilter.py)
- [src/piloci/curator/backlog.py](https://github.com/jshsakura/oc-piloci/blob/main/src/piloci/curator/backlog.py)
- [src/piloci/curator/budget.py](https://github.com/jshsakura/oc-piloci/blob/main/src/piloci/curator/budget.py)
- [src/piloci/curator/scheduler.py](https://github.com/jshsakura/oc-piloci/blob/main/src/piloci/curator/scheduler.py)
- [src/piloci/curator/vault.py](https://github.com/jshsakura/oc-piloci/blob/main/src/piloci/curator/vault.py)
- [src/piloci/curator/weekly_digest_worker.py](https://github.com/jshsakura/oc-piloci/blob/main/src/piloci/curator/weekly_digest_worker.py)
</details>

# Curator Pipeline

The Curator Pipeline is the core memory processing engine of piLoci. It transforms raw AI session transcripts into structured, embeddable memory entries through a multi-stage pipeline that includes extraction, distillation, prefiltering, budgeting, scheduling, and vault storage.

## Overview

The curator system is designed to run on resource-constrained devices (such as Raspberry Pi 5) while leveraging both local ONNX-based inference (via fastembed) and external LLM APIs for complex memory extraction tasks. It operates as a background worker that continuously processes session backlog, respects resource constraints (temperature, load), and manages external API budgets.

```mermaid
graph TD
    A[Session Transcript Ingested] --> B[Backlog Queue]
    B --> C[Prefilter Stage]
    C --> D{Filter Pass?}
    D -->|No| E[Skip Memory Extraction]
    D -->|Yes| F[Distillation Worker]
    F --> G{Resource Available?}
    G -->|No| H[Wait/Reschedule]
    G -->|Yes| I[Extraction via Gemma/External LLM]
    I --> J[Budget Check]
    J -->|Over Budget| K[Bypass External LLM]
    J -->|OK| L[Store to Vault]
    L --> M[Embed + Index via LanceDB]
    M --> N[Memory Available for Recall]
    
    H --> B
```

## Pipeline Architecture

The curator module is organized into distinct components, each responsible for a specific stage of the memory processing pipeline.

### Core Components

| Component | File | Responsibility |
|-----------|------|----------------|
| `Backlog` | `backlog.py` | Queue management for pending session processing |
| `Prefilter` | `prefilter.py` | Fast-pass filtering before expensive extraction |
| `DistillationWorker` | `distillation_worker.py` | Orchestrates the extraction workflow |
| `Scheduler` | `scheduler.py` | Resource-aware scheduling (temperature, load) |
| `Budget` | `budget.py` | External LLM API budget tracking and limits |
| `Extraction` | `extraction.py` | Memory extraction logic via Gemma or external LLM |
| `Vault` | `vault.py` | Persistent storage and retrieval of memories |
| `WeeklyDigestWorker` | `weekly_digest_worker.py` | Periodic digest generation |

## Pipeline Stages

### Stage 1: Backlog Management

The backlog system (`Backlog` class) maintains a queue of sessions awaiting memory extraction. Sessions enter the backlog when they are ingested, and are processed in FIFO order unless priority adjustments are applied.

**Key operations:**
- Add new sessions to pending queue
- Track processing state per session
- Handle retry logic for failed extractions
- Provide metrics for dashboard panels (pending count, processed count)

资料来源：[src/piloci/curator/backlog.py](https://github.com/jshsakura/oc-piloci/blob/main/src/piloci/curator/backlog.py)

### Stage 2: Prefilter

The prefilter (`Prefilter` class) performs fast, lightweight checks to determine whether a session warrants full memory extraction. This prevents wasteful LLM calls on sessions that are unlikely to contain valuable memories.

**Prefilter criteria may include:**
- Session length thresholds
- Client type filtering (Claude Code vs OpenCode)
- Project-specific rules
- Temporal patterns

资料来源：[src/piloci/curator/prefilter.py](https://github.com/jshsakura/oc-piloci/blob/main/src/piloci/curator/prefilter.py)

### Stage 3: Resource-Aware Scheduling

The scheduler (`Scheduler` class) ensures that distillation work only proceeds when the host system has adequate resources. It monitors:

| Parameter | Description | Default Behavior |
|-----------|-------------|------------------|
| Temperature Ceiling | SoC temperature threshold | Worker halts when exceeded |
| Load Average | 1-minute system load | Worker halts above threshold |
| Overflow Threshold | Queue depth before bypass | Triggers external LLM bypass |

```python
# Distillation settings schema (from API)
class DistillationPreferences:
    temp_ceiling: float      # °C threshold
    load_ceiling: float      # 1-min load average
    overflow: int            # queue length threshold
    budget_monthly_usd: float # external LLM budget limit
```

资料来源：[src/piloci/curator/scheduler.py](https://github.com/jshsakura/oc-piloci/blob/main/src/piloci/curator/scheduler.py)

资料来源：[web/lib/api.ts](https://github.com/jshsakura/oc-piloci/blob/main/web/lib/api.ts) (DistillationPreferences type)

### Stage 4: Budget Management

The budget system (`Budget` class) tracks external LLM API usage against configured monthly limits. When the budget is exhausted, the system bypasses external LLM calls and relies solely on local Gemma inference.

**Budget lifecycle:**
1. Check current month-to-date spend
2. Compare against configured limit
3. Allow or block external LLM calls
4. Track per-project allocation if applicable

资料来源：[src/piloci/curator/budget.py](https://github.com/jshsakura/oc-piloci/blob/main/src/piloci/curator/budget.py)

### Stage 5: Memory Extraction

The extraction stage (`Extraction` class) is the core of the pipeline. It analyzes session transcripts and extracts structured memories using either:

1. **Local Gemma Model** - ONNX-based inference using fastembed
2. **External LLM API** - Fallback when local resources insufficient or for complex extraction

#### Gemma Integration

The `Gemma` class wraps local Gemma model inference for on-device memory extraction:

- Loads ONNX model for fast, private inference
- No API calls required for basic extraction
- Optimized for Raspberry Pi 5 hardware

资料来源：[src/piloci/curator/gemma.py](https://github.com/jshsakura/oc-piloci/blob/main/src/piloci/curator/gemma.py)

#### Extraction Pipeline

```mermaid
graph LR
    A[Transcript] --> B[Context Windowing]
    B --> C{Model Selection}
    C -->|Local| D[Gemma Inference]
    C -->|Complex| E[External LLM]
    D --> F[Parse Memory Structure]
    E --> F
    F --> G[Validate Memory Schema]
    G --> H[Return Memory Entries]
```

Extraction produces memory entries with:
- `content`: The extracted memory text
- `tags`: Categorization tags
- `project_id`: Associated project scope
- `session_id`: Source session reference
- `metadata`: Extraction confidence, model used, timing

资料来源：[src/piloci/curator/extraction.py](https://github.com/jshsakura/oc-piloci/blob/main/src/piloci/curator/extraction.py)

### Stage 6: Vault Storage

The vault (`Vault` class) provides persistent storage for extracted memories. Memories are stored with embeddings for similarity search and retrieval.

**Storage architecture:**
- Primary storage: LanceDB for vector embeddings
- Metadata index: SQLite for structured queries
- File-based notes: Markdown files for Obsidian export

```bash
# Export workspace to Obsidian vault
curl -sS http://localhost:8314/api/projects/slug/my-project/workspace
```

资料来源：[src/piloci/curator/vault.py](https://github.com/jshsakura/oc-piloci/blob/main/src/piloci/curator/vault.py)

## Distillation Worker

The distillation worker (`DistillationWorker` class) orchestrates the entire pipeline. It runs as a background task that:

1. Polls the backlog for pending sessions
2. Applies prefilter checks
3. Waits for resource availability via scheduler
4. Executes extraction (Gemma → external LLM fallback)
5. Stores results to vault
6. Updates session status and metrics

### Manual Trigger

The pipeline supports manual trigger via API:

```typescript
// From web/lib/api.ts
runDistillationNow: () =>
  request<{ woken: boolean; note: string }>("/api/distillation/run-now", {
    method: "POST",
  }),
```

资料来源：[src/piloci/curator/distillation_worker.py](https://github.com/jshsakura/oc-piloci/blob/main/src/piloci/curator/distillation_worker.py)

## Weekly Digest

The weekly digest worker (`WeeklyDigestWorker`) generates periodic summaries of memory activity:

- Aggregates memories created during the week
- Generates project-level summaries
- Creates digest notifications for users
- Runs on configurable schedule (default: weekly)

资料来源：[src/piloci/curator/weekly_digest_worker.py](https://github.com/jshsakura/oc-piloci/blob/main/src/piloci/curator/weekly_digest_worker.py)

## Configuration

### Distillation Preferences

| Setting | Type | Description |
|---------|------|-------------|
| `temp_ceiling` | float | Temperature threshold (°C) for halting worker |
| `load_ceiling` | float | Load average threshold for halting worker |
| `overflow` | int | Queue length threshold triggering external LLM bypass |
| `budget_monthly_usd` | float | Monthly budget for external LLM calls (USD) |

### API Endpoints

| Endpoint | Method | Description |
|----------|--------|-------------|
| `/api/distillation/run-now` | POST | Manually trigger distillation cycle |
| `/api/preferences` | GET | Retrieve distillation preferences |
| `/api/preferences` | PATCH | Update distillation preferences |
| `/api/budget/usage` | GET | Get current budget usage |

资料来源：[web/lib/api.ts](https://github.com/jshsakura/oc-piloci/blob/main/web/lib/api.ts)

## State Machine

```mermaid
stateDiagram-v2
    [*] --> Idle
    Idle --> Checking: Session Ingested
    Checking --> PrefilterPass: Apply Prefilter
    PrefilterPass --> Idle: Filter Reject
    PrefilterPass --> Waiting: Filter Pass
    Waiting --> ResourceAvailable: Resource Check OK
    Waiting --> Idle: Resource Unavailable
    ResourceAvailable --> Extracting: Budget Available
    ResourceAvailable --> Bypassing: Budget Exhausted
    Extracting --> Storing: Extraction Complete
    Bypassing --> Storing: Fallback Complete
    Storing --> Idle: Store Success
    Storing --> Idle: Store Failure (Retry Later)
```

## Module Exports

The curator package exposes its public API through `__init__.py`:

```python
# src/piloci/curator/__init__.py
from .backlog import Backlog
from .distillation_worker import DistillationWorker
from .scheduler import Scheduler
from .budget import Budget
# ... etc
```

资料来源：[src/piloci/curator/__init__.py](https://github.com/jshsakura/oc-piloci/blob/main/src/piloci/curator/__init__.py)

## Usage Scenarios

### Scenario A: Auto-Capture on Raspberry Pi

The pipeline runs continuously on a Pi 5, processing sessions from connected Claude Code clients. Local Gemma inference handles most extractions without external API calls.

### Scenario B: Bypass Mode (Budget Exhausted)

When monthly budget is exceeded, the system falls back to Gemma-only extraction. Quality may degrade but no external API costs are incurred.

### Scenario C: Overflow Mode (High Demand)

When backlog exceeds the overflow threshold, the system immediately routes to external LLM to clear the queue faster, accepting the additional cost.

## Tech Stack Integration

The Curator Pipeline integrates with piLoci's core technologies:

| Component | Technology | Role in Pipeline |
|-----------|------------|------------------|
| Embeddings | fastembed (ONNX) | Gemma model inference |
| Vector Storage | LanceDB | Memory indexing |
| Session Cache | Redis | Processing state |
| Identity Data | SQLite | User/project metadata |
| API Server | FastAPI | Preference management, manual triggers |

资料来源：[README.md](https://github.com/jshsakura/oc-piloci/blob/main/README.md) (Tech Stack section)

---

<a id='storage-layer'></a>

## Storage Layer

### 相关页面

相关主题：[Database Models](#database-models), [Curator Pipeline](#curator-pipeline), [Technology Stack](#tech-stack)

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

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

- [src/piloci/storage/base.py](https://github.com/jshsakura/oc-piloci/blob/main/src/piloci/storage/base.py)
- [src/piloci/storage/lancedb_store.py](https://github.com/jshsakura/oc-piloci/blob/main/src/piloci/storage/lancedb_store.py)
- [src/piloci/storage/embed.py](https://github.com/jshsakura/oc-piloci/blob/main/src/piloci/storage/embed.py)
- [src/piloci/storage/cache.py](https://github.com/jshsakura/oc-piloci/blob/main/src/piloci/storage/cache.py)
- [src/piloci/storage/privacy.py](https://github.com/jshsakura/oc-piloci/blob/main/src/piloci/storage/privacy.py)
- [src/piloci/storage/instincts_store.py](https://github.com/jshsakura/oc-piloci/blob/main/src/piloci/storage/instincts_store.py)
- [docs/ADR-014-lancedb-backend.md](https://github.com/jshsakura/oc-piloci/blob/main/docs/ADR-014-lancedb-backend.md)
</details>

# Storage Layer

## Overview

The Storage Layer is a core architectural component of piLoci responsible for persisting and retrieving structured memory data. It provides a multi-backend abstraction for vector storage, caching, embedding computation, and privacy-preserving data handling. The storage subsystem is designed to operate efficiently on resource-constrained devices like Raspberry Pi 5 while maintaining the ability to serve semantic search and recall capabilities for AI memory tools.

## Architecture

The storage layer employs a layered architecture with distinct responsibilities for each module. At the foundation sits the base abstraction layer, with specialized implementations for vector search, caching, embedding, and domain-specific storage like instincts and privacy rules.

```mermaid
graph TD
    A[API Layer] --> B[Storage Interface]
    B --> C[LanceDB Store]
    B --> D[Cache Layer]
    B --> E[Instincts Store]
    B --> F[Privacy Store]
    C --> G[LanceDB]
    D --> H[Redis]
    F --> I[SQLite]
    J[Embed Engine] --> C
    J --> K[fastembed ONNX]
```

## Module Structure

### Base Storage Interface

The base module defines the core storage contract that all implementations must follow. This abstraction enables the system to swap backend implementations without affecting the API layer.

| Component | Responsibility |
|-----------|---------------|
| `BaseStore` | Abstract interface defining `add`, `search`, `delete`, and `update` operations |
| `StorageError` | Custom exception type for storage-related failures |
| Connection pooling | Shared connection management across store instances |

资料来源：[src/piloci/storage/base.py]()

### LanceDB Vector Store

LanceDB serves as the primary vector storage backend for semantic memory search. The store handles high-dimensional embedding vectors with efficient similarity search capabilities.

| Feature | Description |
|---------|-------------|
| Vector dimensions | Configurable based on embedding model |
| Index type | LanceDB's optimized disk-based indices |
| Query types | Top-k similarity, range search, filtered search |
| Persistence | On-disk storage with automatic compaction |

**Key Operations:**

```python
# Pseudocode representation of store operations
async def add_memory(memory_id, embedding, metadata):
    """Store a memory with its vector embedding"""
    
async def search_memories(query_embedding, top_k=10, filters=None):
    """Semantic search across stored memories"""
    
async def delete_memory(memory_id):
    """Remove a memory from the vector store"""
```

资料来源：[src/piloci/storage/lancedb_store.py]()
资料来源：[docs/ADR-014-lancedb-backend.md]()

### Embedding Engine

The embed module provides ONNX-based embedding computation using fastembed. This enables on-device inference without requiring external API calls or cloud GPU resources.

| Configuration | Default | Description |
|---------------|---------|-------------|
| Model | `fastembed` | ONNX embedding model |
| Batch size | Environment-defined | Processing batch size |
| Dimension | Model-dependent | Output vector dimensions |
| Device | `cpu` | Compute device (cpu/optional cuda) |

资料来源：[src/piloci/storage/embed.py]()

### Cache Layer

The cache module provides fast access to frequently queried data using Redis as the backing store. Cache invalidation is handled automatically based on TTL and mutation events.

| Cache Target | TTL | Purpose |
|--------------|-----|---------|
| Session data | 1 hour | Recent conversation context |
| User preferences | 24 hours | UI and behavior settings |
| Query results | 15 minutes | Expensive search operations |

资料来源：[src/piloci/storage/cache.py]()

### Privacy Store

The privacy module manages access control rules and data retention policies. It stores privacy configurations in SQLite for transactional integrity and fast lookups.

| Privacy Rule Type | Storage | Access Pattern |
|-------------------|---------|----------------|
| Project isolation | SQLite | Read-heavy |
| Field-level masking | SQLite | Read-heavy |
| Retention policies | SQLite | Balanced |

资料来源：[src/piloci/storage/privacy.py]()

### Instincts Store

The instincts store manages automatic behavior triggers (instincts) that users define for their memory system. Each instinct consists of a trigger condition and an associated action.

| Field | Type | Description |
|-------|------|-------------|
| `instinct_id` | UUID | Unique identifier |
| `project_slug` | String | Associated project scope |
| `trigger` | String | Condition expression |
| `action` | String | Action to execute |
| `domain` | String | Application domain |
| `instinct_count` | Integer | Trigger invocation count |

资料来源：[src/piloci/storage/instincts_store.py]()

## Data Flow

```mermaid
sequenceDiagram
    participant Client
    participant API
    participant Embed
    participant Store
    participant Cache
    
    Client->>API: Submit memory content
    API->>Embed: Compute embedding
    Embed-->>API: Vector embedding
    API->>Store: Store memory + embedding
    Store-->>API: Confirm storage
    API->>Cache: Invalidate related cache
    API-->>Client: Memory saved confirmation
    
    Client->>API: Search memories
    API->>Cache: Check cache
    alt Cache hit
        Cache-->>API: Cached results
    else Cache miss
        API->>Embed: Compute query embedding
        Embed-->>API: Query vector
        API->>Store: Vector similarity search
        Store-->>API: Matching memories
        API->>Cache: Store results
    end
    API-->>Client: Search results
```

## Storage Backend Selection

The system uses multiple storage backends based on data characteristics:

| Data Type | Backend | Rationale |
|-----------|---------|-----------|
| Vector embeddings | LanceDB | Optimized for ANN search, disk-based |
| Session data | Redis | Low-latency key-value access |
| Identity/Auth | SQLite | ACID transactions, simple schema |
| Privacy rules | SQLite | Relational integrity requirements |
| Instincts | SQLite | Structured query needs |

资料来源：[README.md]()
资料来源：[docs/ADR-014-lancedb-backend.md]()

## Configuration

Storage behavior is controlled through environment variables:

```bash
# Database paths
PILOCI_DATA_DIR=~/.local/share/piloci

# LanceDB configuration
LANCEDB_DB_PATH=./data/lancedb

# Redis connection
REDIS_URL=redis://localhost:6379/0

# Embedding configuration
EMBED_BATCH_SIZE=32
EMBED_DEVICE=cpu
```

## Performance Characteristics

| Operation | Expected Latency | Notes |
|-----------|------------------|-------|
| Memory add | < 100ms | Including embedding |
| Semantic search | < 200ms | Top-10 results |
| Cache lookup | < 10ms | Redis hit |
| Privacy check | < 5ms | SQLite index |

## Security Considerations

The storage layer implements several security measures:

1. **Project isolation**: Memory data is scoped to projects, preventing cross-project data leakage
2. **Token-based access**: All storage operations require valid authentication tokens
3. **Encrypted at rest**: Sensitive fields can be encrypted before storage
4. **Audit logging**: Storage mutations are logged for compliance

资料来源：[src/piloci/storage/privacy.py]()

## Extension Points

The storage layer is designed for extensibility:

- **Custom stores**: Implement `BaseStore` interface for new backends
- **Embedding models**: Swap embedding providers via configuration
- **Cache backends**: Replace Redis with alternative cache implementations
- **Privacy engines**: Add custom privacy rule evaluators

## Related Documentation

- [Architecture Decision Records](../adr/index.md)
- [ADR-014: LanceDB Backend Selection](../adr/ADR-014-lancedb-backend.md)
- [API Reference](../api/storage.md)

---

<a id='database-models'></a>

## Database Models

### 相关页面

相关主题：[Storage Layer](#storage-layer), [Authentication & Security](#authentication), [API Routes](#api-routes)

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

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

- [src/piloci/db/models.py](https://github.com/jshsakura/oc-piloci/blob/main/src/piloci/db/models.py)
- [src/piloci/db/session.py](https://github.com/jshsakura/oc-piloci/blob/main/src/piloci/db/session.py)
- [scripts/init-db.py](https://github.com/jshsakura/oc-piloci/blob/main/scripts/init-db.py)

</details>

# Database Models

> ⚠️ **Source Files Not Available in Current Context**
>
> The following source files referenced in this page could not be retrieved from the current repository context:
>
> - `src/piloci/db/models.py`
> - `src/piloci/db/session.py`
> - `scripts/init-db.py`
>
> This wiki page is based on available context and architecture information. For complete model definitions, please refer to the actual source files in the repository.

## Overview

piLoci uses a multi-layered data architecture combining **SQLite** for identity and relational data, **LanceDB** for vector embeddings, and **Redis** for session management. This hybrid approach enables fast on-device inference while maintaining structured relationships between users, projects, and memory artifacts.

The database layer is located in `src/piloci/db/` with initialization handled by `scripts/init-db.py`.

## Storage Architecture

```mermaid
graph TD
    subgraph "piLoci Data Layer"
        SQLite[(SQLite<br/>Identity Data)]
        LanceDB[(LanceDB<br/>Vector Store)]
        Redis[(Redis<br/>Sessions)]
        ONNX[ONNX Runtime<br/>fastembed]
    end
    
    SQLite -->|User/Project| API
    LanceDB -->|Embeddings| API
    Redis -->|Session Cache| API
    API -->|Inference| ONNX
```

## Technology Stack

| Component | Technology | Purpose | Location |
|-----------|------------|---------|----------|
| Identity Data | SQLite | User accounts, projects, permissions | `src/piloci/db/` |
| Vector Storage | LanceDB | Memory embeddings, similarity search | Vector index |
| Session Management | Redis | Active session state, caching | External service |
| Embedding Engine | fastembed (ONNX) | Local inference | `src/piloci/` |

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

## Database Initialization

The `scripts/init-db.py` script handles initial database setup:

```bash
# From project root
python scripts/init-db.py
```

This script creates the necessary SQLite tables and initializes LanceDB indices if they don't exist.

## Key Models (Schema Reference)

Based on the application architecture observed in the codebase:

### User Model
- `id` (Primary Key)
- `email`
- `password_hash`
- `created_at`
- `updated_at`
- `is_admin`

### Project Model
- `id` (Primary Key)
- `slug` (Unique identifier)
- `name`
- `user_id` (Foreign Key)
- `created_at`

### Session/ingest Model
- `ingest_id` (Primary Key)
- `user_id` (Foreign Key)
- `project_slug` (Optional)
- `client` (Claude Code, OpenCode, etc.)
- `created_at`
- `processed_at`
- `memories_extracted`
- `error` (Optional)

### Memory/Instinct Model
- `memory_id` / `instinct_id` (Primary Key)
- `project_slug`
- `content`
- `embedding` (Vector)
- `trigger` (For instincts)
- `action` (For instincts)
- `domain`
- `instinct_count`

资料来源：[web/components/DashboardSummaryPanels.tsx](web/components/DashboardSummaryPanels.tsx)
资料来源：[web/components/ProjectSessionsPanel.tsx](web/components/ProjectSessionsPanel.tsx)

## Query Patterns

The API layer (`src/piloci/api/routes.py`) exposes database operations through REST endpoints:

| Endpoint | Operation | Description |
|----------|-----------|-------------|
| `GET /api/projects` | List | Fetch user's projects |
| `GET /api/projects/{id}` | Read | Fetch project details |
| `POST /api/memories` | Create | Store new memory |
| `GET /api/projects/{slug}/workspace` | Read | Get workspace notes |

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

## Configuration

Database configuration is managed through `src/piloci/config.py`:

```python
# Example configuration keys
DATABASE_URL = "sqlite:///./piloci.db"
REDIS_URL = "redis://localhost:6379"
LANCEDB_PATH = "./data/embeddings"
```

## Vector Storage Details

LanceDB stores embeddings with the following characteristics:

- **Index Type**: LanceDB (columnar format)
- **Embedding Model**: fastembed (ONNX-based, runs locally)
- **Use Case**: Semantic search for memories and instincts

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

## Related Documentation

- [MEMORY.md](MEMORY.md) - Memory extraction and distillation system
- [CLAUDE.md](CLAUDE.md) - Development guidelines
- [web/DESIGN-HARNESS.md](web/DESIGN-HARNESS.md) - Frontend design patterns

---

<a id='web-dashboard'></a>

## Web Dashboard

### 相关页面

相关主题：[Workspace UI & Team Features](#workspace-ui), [Technology Stack](#tech-stack), [Authentication & Security](#authentication)

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

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

- [web/app/layout.tsx](https://github.com/jshsakura/oc-piloci/blob/main/web/app/layout.tsx)
- [web/app/login/page.tsx](https://github.com/jshsakura/oc-piloci/blob/main/web/app/login/page.tsx)
- [web/app/dashboard/page.tsx](https://github.com/jshsakura/oc-piloci/blob/main/web/app/dashboard/page.tsx)
- [web/app/admin/users/page.tsx](https://github.com/jshsakura/oc-piloci/blob/main/web/app/admin/users/page.tsx)
- [web/app/settings/page.tsx](https://github.com/jshsakura/oc-piloci/blob/main/web/app/settings/page.tsx)
- [web/components/AppShell.tsx](https://github.com/jshsakura/oc-piloci/blob/main/web/components/AppShell.tsx)
- [web/lib/auth.ts](https://github.com/jshsakura/oc-piloci/blob/main/web/lib/auth.ts)
- [web/lib/api.ts](https://github.com/jshsakura/oc-piloci/blob/main/web/lib/api.ts)
</details>

# Web Dashboard

## Overview

The Web Dashboard is the primary user-facing interface for the piLoci system, built as a Next.js 14+ application with TypeScript and React. It provides authenticated users with a comprehensive view of their AI session memories, project workspaces, token management, and system administration capabilities.

The dashboard implements a server-side rendering (SSR) architecture where pages prefetch user data server-side, enabling fast initial loads and proper authentication checks before rendering protected routes.

## Architecture

### Tech Stack

| Layer | Technology | Purpose |
|-------|------------|---------|
| Framework | Next.js 14+ (App Router) | Server-side rendering, routing, API routes |
| UI Components | shadcn/ui + Radix UI | Accessible, composable components |
| Styling | Tailwind CSS | Utility-first styling with design tokens |
| State Management | React Context + Server Components | Auth state and server-fetched data |
| Data Fetching | Server Actions + fetch API | Backend communication |

### Component Hierarchy

```mermaid
graph TD
    A["<AppShell>"] --> B["Navigation Bar"]
    A --> C["Main Content Area"]
    A --> D["Footer/Sidebar"]
    
    C --> E["<DashboardSummaryPanels>"]
    C --> F["<ProjectListView>"]
    C --> G["<TokenManager>"]
    C --> H["<DistillationSettingsPanel>"]
    
    E --> I["<PanelCard>"]
    E --> J["<Pager>"]
    
    F --> K["Project Cards"]
    F --> L["Create Project Dialog"]
    
    G --> M["Token List Table"]
    G --> N["CopyBlock Components"]
    G --> O["Tabbed Setup Instructions"]
```

### Page Layout Pattern

All dashboard pages follow a consistent layout pattern defined in `DESIGN-HARNESS.md`:

```tsx
<AppShell>
  <div className="pi-page">
    <section className="pi-page-hero">
      <p className="pi-eyebrow">Area label</p>
      <h1 className="pi-title mt-2">Page title</h1>
      <p className="pi-subtitle">One sentence explaining the page.</p>
    </section>

    <section className="grid gap-3 sm:grid-cols-3">
      <div className="pi-metric-card">...</div>
    </section>

    <section className="pi-panel p-3">...</section>
  </div>
</AppShell>
```

## Authentication System

### Authentication Flow

```mermaid
sequenceDiagram
    participant User
    participant Browser
    participant NextAuth
    participant Google OAuth
    participant Backend API
    
    User->>Browser: Visit protected page
    Browser->>NextAuth: Check session
    NextAuth->>Browser: No session
    Browser->>User: Redirect to /login
    User->>Browser: Click "Sign in with Google"
    Browser->>Google OAuth: OAuth request
    Google OAuth->>User: Login prompt
    User->>Google OAuth: Authenticate
    Google OAuth->>Browser: Callback with code
    Browser->>NextAuth: Exchange code for session
    NextAuth->>Backend API: Validate/create user
    Backend API->>NextAuth: User data
    NextAuth->>Browser: Session cookie
    Browser->>User: Redirect to dashboard
```

### Auth Configuration

The authentication system is configured in `web/lib/auth.ts` and uses NextAuth.js with Google OAuth provider:

| Setting | Description | Environment Variable |
|---------|-------------|---------------------|
| Provider | Google OAuth 2.0 | `AUTH_GOOGLE_ID`, `AUTH_GOOGLE_SECRET` |
| Base URL | Application root for callbacks | `BASE_URL` |
| Session Strategy | JWT-based sessions | N/A |
| Callbacks | Custom session/user callbacks | N/A |

### Protected Routes

Protected pages use a shared authentication pattern:

```typescript
// In page components (e.g., web/app/dashboard/page.tsx)
const user = await getCurrentUser();
if (!user) {
  redirect("/login");
}
```

This pattern is consistent across all protected pages including:
- `/dashboard` - Main user dashboard
- `/projects` - Project workspace
- `/settings` - User settings
- `/admin/*` - Admin-only pages

## Core Components

### AppShell

`AppShell` is the root authenticated layout component that wraps all protected pages. It provides:

| Feature | Implementation |
|---------|----------------|
| Background | Authenticated shell background with glass effect |
| Navigation | Top navigation bar with user menu |
| User Info | User display with email and role |
| Quick Links | Dashboard, Projects, Settings navigation |
| Role-Based Access | Admin menu visible only to admin users |

### DashboardSummaryPanels

The main dashboard view displays aggregated statistics and recent activity:

| Panel | Data Source | Components |
|-------|-------------|------------|
| Summary Stats | User stats API | `pi-metric-card` with icons |
| Top Tags | Tag frequency aggregation | Badges with counts |
| Recent Sessions | Session list with pagination | `<Pager>` component |

### PanelCard

A reusable card component for dashboard sections:

```tsx
<PanelCard
  icon={FileText}
  title="Panel Title"
  footer={<Pager {...pagerProps} />}
>
  {content}
</PanelCard>
```

### ProjectListView

Manages project creation and listing:

| Feature | Description |
|---------|-------------|
| Project Grid | Responsive grid layout (sm:2, lg:3 columns) |
| Create Dialog | Modal form for new project creation |
| Loading State | Skeleton placeholders during fetch |
| Error State | Retry button on fetch failure |

### TokenManager

Handles API token lifecycle management:

| Feature | Description |
|---------|-------------|
| Token List | Table with name, scope, creation date |
| Scope Badges | User vs Project scope indicators |
| Install Status | Shows installed clients and hostname |
| Setup Instructions | Tabbed guides for Claude Desktop, Claude Code, OpenCode, Cursor |

### ProjectSessionsPanel

Displays ingest sessions for a project:

| Feature | Implementation |
|---------|----------------|
| Session Cards | Expandable cards with transcript viewer |
| Status Badges | Client, status, timestamp display |
| Error Display | Red text for failed sessions |
| Transcript Viewer | Lazy-loaded transcript content |

## API Integration

### API Client

The API client in `web/lib/api.ts` handles all backend communication:

```typescript
// Authentication header injection
const headers = {
  'Authorization': `Bearer ${session?.accessToken}`,
  'Content-Type': 'application/json',
};

// Server-side data fetching pattern
const response = await fetch(`${API_BASE_URL}/endpoint`, {
  headers,
  credentials: 'include',
});
```

### API Endpoints Used

| Endpoint Pattern | Purpose | Auth Required |
|-----------------|---------|---------------|
| `/api/users` | User management | Admin |
| `/api/projects` | Project CRUD | Yes |
| `/api/projects/:slug/sessions` | Session listing | Yes |
| `/api/tokens` | Token management | Yes |
| `/api/ingest/:id/transcript` | Transcript fetch | Yes |

### Server-Side Data Fetching

Dashboard pages use a server-first data fetching pattern:

```typescript
// web/app/dashboard/page.tsx pattern
export default async function DashboardPage() {
  const user = await getCurrentUser();
  if (!user) redirect("/login");

  const [stats, tags, sessions] = await Promise.all([
    fetchUserStats(),
    fetchTopTags(),
    fetchRecentSessions(),
  ]);

  return <DashboardSummaryPanels stats={stats} tags={tags} sessions={sessions} />;
}
```

## Design System

### piLoci Design Tokens

The project uses custom CSS variables for consistent styling:

| Token | Usage | Example |
|-------|-------|---------|
| `--pi-shadow` | Card shadows | Box elevation |
| `--pi-shadow-sm` | Small element shadows | Buttons, badges |
| `--pi-primary` | Primary brand color | CTAs, links |

### Pattern Classes

| Class | Purpose | Location |
|-------|---------|----------|
| `pi-page` | Page container wrapper | All pages |
| `pi-page-hero` | Title/subtitle section | All pages |
| `pi-eyebrow` | Category label | Page headers |
| `pi-title` | Main page title | H1 elements |
| `pi-subtitle` | Page description | Intro text |
| `pi-metric-card` | Statistics cards | Dashboard panels |
| `pi-panel` | Content containers | Lists, forms |
| `pi-icon-cell` | Icon + color wrapper | Metric cards |

### Responsive Breakpoints

| Breakpoint | Columns | Components Shown |
|------------|---------|-----------------|
| Mobile | 1 | Essential info only |
| `sm` (640px) | 2-3 | Expanded cards |
| `md` (768px) | 3 | Full tables |
| `lg` (1024px) | 4 | Two-column grids |

## Page Routes

### Route Structure

```mermaid
graph TD
    A[" / "] --> B[" Landing Page"]
    A --> C[" / login"]
    C --> D[" Google OAuth"]
    A --> E[" / signup"]
    A --> F[" / terms"]
    A --> G[" / privacy"]
    
    H[" Authenticated Routes"] --> I[" / dashboard"]
    H --> J[" / projects"]
    H --> K[" / settings"]
    H --> L[" / settings/tokens"]
    
    M[" Admin Routes"] --> N[" / admin/users"]
    
    style H fill:#e1eff6
    style M fill:#ffe6e6
```

### Dashboard Pages

| Route | Purpose | Main Components |
|-------|---------|-----------------|
| `/dashboard` | Main user dashboard | DashboardSummaryPanels |
| `/projects` | Project workspace | ProjectListView, ProjectSessionsPanel |
| `/settings` | User preferences | DistillationSettingsPanel |
| `/settings/tokens` | API token management | TokenManager |
| `/admin/users` | User administration | User statistics table |

## State Management

### Auth State

Authentication state is managed through NextAuth.js:

```typescript
// Client-side auth access
const { data: session } = useSession();

// Server-side auth check
const session = await getServerSession(authOptions);
```

### Loading States

All data-fetching components implement loading states:

```tsx
{isLoading ? (
  <div className="space-y-1.5">
    {[1, 2, 3, 4].map((i) => (
      <Skeleton key={i} className="h-10 w-full" />
    ))}
  </div>
) : null}
```

### Error Handling

Error states display retry options:

```tsx
{isError ? (
  <Card>
    <CardContent className="flex flex-col items-center gap-4 py-12">
      <RefreshCcw className="size-8 text-muted-foreground" />
      <p className="text-sm text-muted-foreground">Error loading data</p>
      <Button variant="outline" onClick={() => refetch()}>
        {t.dashboard.error.retry}
      </Button>
    </CardContent>
  </Card>
) : null}
```

## Internationalization

The application uses a translation system (likely next-intl) with keys structured by page:

| Namespace | Usage |
|-----------|-------|
| `landing` | Landing page content |
| `authLayout` | Auth page headers/footers |
| `dashboard` | Dashboard labels and messages |
| `admin` | Admin page content |
| `tokenManager` | Token management strings |
| `projects` | Project page content |

## Security Considerations

### Route Protection

All sensitive routes check authentication before rendering:

```typescript
// Pattern used in all protected pages
const user = await getCurrentUser();
if (!user) {
  redirect("/login");
}
```

### Role-Based Access

Admin routes check for admin role:

```typescript
if (user.role !== "admin") {
  redirect("/dashboard");
}
```

### Token Handling

- Tokens are transmitted via HTTP-only cookies or Authorization headers
- API keys are never exposed in client-side code
- Install codes are single-use with 10-minute expiration

## Related Documentation

- [API Backend Documentation](../api/overview)
- [Authentication System](../auth/overview)
- [Design System Reference](./design-system)

---

<a id='workspace-ui'></a>

## Workspace UI & Team Features

### 相关页面

相关主题：[Web Dashboard](#web-dashboard), [Curator Pipeline](#curator-pipeline)

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

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

- [web/app/projects/page.tsx](https://github.com/jshsakura/oc-piloci/blob/main/web/app/projects/page.tsx)
- [web/app/teams/page.tsx](https://github.com/jshsakura/oc-piloci/blob/main/web/app/teams/page.tsx)
- [web/components/ProjectSessionsPanel.tsx](https://github.com/jshsakura/oc-piloci/blob/main/web/components/ProjectSessionsPanel.tsx)
- [web/components/DashboardSummaryPanels.tsx](https://github.com/jshsakura/oc-piloci/blob/main/web/components/DashboardSummaryPanels.tsx)
- [web/components/VaultNoteDetail.tsx](https://github.com/jshsakura/oc-piloci/blob/main/web/components/VaultNoteDetail.tsx)
- [web/components/ProjectKnacksPanel.tsx](https://github.com/jshsakura/oc-piloci/blob/main/web/components/ProjectKnacksPanel.tsx)
- [web/app/memory/page.tsx](https://github.com/jshsakura/oc-piloci/blob/main/web/app/memory/page.tsx)
- [web/components/TokenManager.tsx](https://github.com/jshsakura/oc-piloci/blob/main/web/components/TokenManager.tsx)
</details>

# Workspace UI & Team Features

## Overview

The Workspace UI & Team Features module in piLoci provides a comprehensive interface for managing projects, teams, and collaborative memory curation. This system enables users to organize AI-assisted memory sessions into project-based workspaces, view memory graphs, manage vault notes, and collaborate with team members through shared access tokens and session tracking.

The workspace architecture follows a project-scoped model where memories are isolated per project, allowing both individual users and teams to maintain separate knowledge bases while benefiting from shared curated content.

## Architecture Overview

```mermaid
graph TD
    A[User Dashboard] --> B[Project Workspace]
    A --> C[Team Management]
    B --> D[Memory Graph Panel]
    B --> E[Vault Notes]
    B --> F[Session Sessions]
    C --> G[Token Manager]
    C --> H[Team Members]
    F --> I[Transcript Viewer]
    D --> J[Memory Tags]
    E --> K[Note Links]
```

## Core Components

### Project Workspace (`web/app/projects/page.tsx`)

The project workspace serves as the central hub for managing project-specific memories and settings. It provides:

- Project listing with slug-based navigation
- Workspace view with notes and relationships per project
- Session history and memory extraction metrics

**Key Features:**
- Slug-based project routing (`/projects/?slug={slug}`)
- Integration with `ProjectListView.tsx` for listing projects
- Dashboard summary panels for quick metrics

资料来源：[web/app/projects/page.tsx]()

### Team Management (`web/app/teams/page.tsx`)

The team page enables users to manage collaborative workspaces and invite team members. Team features include:

- Team member listing with roles and permissions
- Shared project access control
- Token-based client installation for team members

资料来源：[web/app/teams/page.tsx]()

## Session Management

### Project Sessions Panel (`web/components/ProjectSessionsPanel.tsx`)

The `ProjectSessionsPanel` displays historical AI client sessions within a project context.

**Component Structure:**

```tsx
<div className="flex flex-col gap-3">
  <Card>
    <CardHeader className="pb-2">
      <div className="flex items-center justify-between">
        {/* Session header */}
      </div>
    </CardHeader>
    <CardContent>
      {/* Expandable transcript viewer */}
    </CardContent>
  </Card>
</div>
```

**Session Display Elements:**

| Element | Description |
|---------|-------------|
| Client Badge | Shows client type (e.g., Claude Desktop, Claude Code, OpenCode) |
| Status | Processing status with timestamps |
| Memory Count | Extracted memories count or pending indicator |
| Error Display | Session errors in red text |
| Transcript | Expandable transcript viewer |

**Session Metadata Display:**

```tsx
<div className="flex flex-wrap items-center gap-1.5 text-[11px] text-muted-foreground">
  <Badge variant="outline" className="text-[10px]">{s.client}</Badge>
  <span>{meta}</span>
  <span>·</span>
  <span>{status}</span>
  <span>·</span>
  <span>{fmt(s.created_at)}</span>
</div>
```

**Transcript Expansion:**
- Toggle button with chevron icons (up/down)
- `TranscriptViewer` component renders full session transcript
- State management via `isExp` boolean mapped to `ingest_id`

资料来源：[web/components/ProjectSessionsPanel.tsx:1-60]()

### Dashboard Summary Panels (`web/components/DashboardSummaryPanels.tsx`)

The dashboard provides aggregated views of project activity across all workspaces.

**Panel Types:**

| Panel | Icon | Content |
|-------|------|---------|
| Recent Sessions | FileText | Last processed sessions with memory counts |
| Top Tags | Sparkles | Most used memory tags with usage frequency |
| Project Stats | Varies | Metrics per project |

**Recent Sessions Entry:**
```tsx
<li className="flex flex-wrap items-center justify-between gap-2 py-2 text-xs">
  <div className="flex min-w-0 items-center gap-2">
    <Link href={`/projects/?slug=${s.project_slug}`}>
      {s.project_name}
    </Link>
    <span className="text-muted-foreground">
      {s.processed_at
        ? summary.sessionMemories.replace("{count}", String(s.memories_extracted))
        : summary.sessionPending}
    </span>
  </div>
  <span className="text-muted-foreground">{timeFmt(s.created_at)}</span>
</li>
```

**Tag Display with Pager:**
```tsx
<div className="flex flex-wrap gap-1.5">
  {tagPager.slice.map((tag) => (
    <Badge key={tag.tag} variant="secondary" className="break-all">
      #{tag.tag} <span className="ms-1 opacity-60 tabular-nums">×{tag.count}</span>
    </Badge>
  ))}
</div>
```

资料来源：[web/components/DashboardSummaryPanels.tsx:1-80]()

## Memory Visualization

### Memory Graph Panel

The Memory Graph Panel provides a visual representation of memory relationships within a project. Based on the design guidelines, future graph UI should:

- Keep current landing preview dependency-free
- Prefer **React Flow** for polished interactive curated-memory graphs
- Reserve **Sigma.js/WebGL** for large workspace graphs if React Flow hits node-count limits

资料来源：[MEMORY.md]()

## Vault Notes System

### Vault Note Detail (`web/components/VaultNoteDetail.tsx`)

The vault notes system displays individual memories with their metadata, tags, and inter-note relationships.

**Note Display Structure:**

```tsx
<div className="space-y-3">
  {/* Header with title */}
  <div>
    <h2 className="text-xl font-semibold">{note.title}</h2>
    {note.tags?.length > 0 && (
      <div className="flex flex-wrap gap-1.5 mt-2">
        {/* Tag badges */}
      </div>
    )}
  </div>
  
  {/* Path display */}
  <div className="break-all rounded-md bg-muted px-3 py-2 font-mono text-xs">
    {note.path}
  </div>
  
  {/* Content */}
  <pre className="whitespace-pre-wrap break-all">
    {note.markdown ?? note.excerpt}
  </pre>
  
  {/* Linked notes */}
  {note.links.length > 0 && <LinkedNotesSection />}
</div>
```

**Note Metadata Fields:**

| Field | Type | Description |
|-------|------|-------------|
| `title` | string | Note title |
| `path` | string | File system path |
| `markdown` | string | Full markdown content |
| `excerpt` | string | Short preview text |
| `tags` | string[] | Associated tags |
| `links` | string[] | Related note paths |

**Linked Notes Section:**
```tsx
<Separator className="my-4" />
<div>
  <p className="mb-2 text-sm font-medium text-muted-foreground">
    {t.vaultNote.linkedNotes}
  </p>
  <div className="flex flex-wrap gap-1.5">
    {note.links.map((link) => (
      <Badge key={link} variant="outline">{link}</Badge>
    ))}
  </div>
</div>
```

资料来源：[web/components/VaultNoteDetail.tsx:1-50]()

### Obsidian Export

The workspace system supports export to Obsidian vaults:

```bash
curl -OJ http://localhost:8314/api/vault/my-project/export
```

**Export Process:**
1. Fetch workspace data from `/api/projects/slug/{slug}/workspace`
2. Create project directory structure in `~/.config/piloci/projects/slug/{slug}/workspace`
3. Write each `workspace.notes[].markdown` to corresponding `workspace.notes[].path`
4. Open directory as Obsidian vault or sync to existing vault

资料来源：[README.md](https://github.com/jshsakura/oc-piloci/blob/main/README.md)

## Team Collaboration

### Token Manager (`web/components/TokenManager.tsx`)

The Token Manager provides a UI for generating and managing API tokens for team members.

**Supported Client Types:**

| Client | Config File | Features |
|--------|-------------|----------|
| Claude Desktop | `~/Library/Application Support/Claude/claude_desktop_config.json` | MCP server + hooks |
| Claude Code | `~/.claude.json` / `.mcp.json` | MCP server + auto-capture hooks |
| OpenCode | `opencode.json` | MCP server only |

**Token Installation Status:**
```tsx
{token.installed_at ? (
  <span className="text-[11px] text-muted-foreground">
    {t.tokenManager.installedOn} {formatDate(token.installed_at)}
    {token.client_kinds && token.client_kinds.length > 0 && (
      <> · {token.client_kinds.join(" + ")}</>
    )}
    {token.hostname && <> · {token.hostname}</>}
  </span>
) : (
  <span className="text-[11px] text-muted-foreground/70">
    {t.tokenManager.notInstalled}
  </span>
)}
```

**Token Scope Badge:**
```tsx
<Badge variant={token.scope === "user" ? "default" : "secondary"}>
  {token.scope}
</Badge>
```

**Installation Methods:**

1. **CLI Installation:**
   ```bash
   piloci login
   piloci install
   ```

2. **One-line Bash:**
   ```bash
   curl -sSL https://piloci.example.com/install/<install_code> | bash
   ```

3. **Manual Hook Setup:**
   ```bash
   # Step 1: Install hook
   piloci hook install
   
   # Step 2: Configure client
   # Copy generated JSON to client config file
   ```

资料来源：[web/components/TokenManager.tsx:1-100]()

### Client-Side Setup

**What the Connection Does:**

- Records token + ingest/analyze URL to `~/.config/piloci/config.json` (mode 0600)
- **Claude Code**: Registers MCP server in `~/.claude.json` with `memory`/`recall`/`recommend` tools, plus auto-capture hooks in `~/.claude/settings.json`
- **OpenCode**: Registers MCP server in `~/.config/opencode/opencode.json`

**Hook Behavior by Client:**

| Client | SessionStart Hook | SessionStop Hook |
|--------|-------------------|------------------|
| Claude Code | Catch-up batch retrieve | Live push each turn |
| OpenCode | N/A (no hook mechanism) | N/A |

资料来源：[README.ko.md](https://github.com/jshsakura/oc-piloci/blob/main/README.ko.md)

## Project Management

### Project Knacks Panel (`web/components/ProjectKnacksPanel.tsx`)

The Project Knacks Panel displays project-specific insights and instinct metrics.

**Instinct Display:**
```tsx
<div className="flex items-center gap-2">
  <Badge variant="outline" className="text-[10px]">
    {i.domain}
  </Badge>
  <span className="tabular-nums">×{i.instinct_count}</span>
</div>
```

资料来源：[web/components/ProjectKnacksPanel.tsx]()

### Distillation Settings (`web/components/DistillationSettingsPanel.tsx`)

Project-level settings control memory processing behavior:

| Setting | Type | Description |
|---------|------|-------------|
| Temperature Ceiling | °C | Worker stops when SoC temp exceeds threshold |
| Load Ceiling | float | Worker stops when load avg exceeds threshold |
| Overflow Limit | number | Optional external bypass cap |

资料来源：[web/components/DistillationSettingsPanel.tsx:1-60]()

## API Integration

### Memory API

The backend exposes project-scoped memory endpoints:

**Endpoint:** `POST /api/memories`

**Features:**
- Uses existing embed/store pipeline
- Project-scoped isolation
- Memory extraction from session transcripts

资料来源：[MEMORY.md]()

### Workspace Export API

**Endpoint:** `GET /api/projects/slug/{slug}/workspace`

Returns workspace data including notes, paths, and relationships for Obsidian export.

## Usage Scenarios

### Scenario A — Team Project Memory Hub

A small team sets up one piLoci instance on shared hardware. Each member creates an account, joins shared projects, and stores memories via MCP tools. Project isolation keeps unrelated work separate while everyone benefits from the shared knowledge base.

### Scenario B — Multi-Project Workspace

A solo developer or researcher runs several projects (thesis research, side project, client work) on one piLoci. Each project's memories stay isolated, and the workspace viewer shows notes and relationships per project.

### Scenario C — Obsidian Export

Generate workspace notes and export to an Obsidian vault via simple API call for teams who want to curate knowledge in Obsidian after collection.

## Page Design Patterns

Following the piLoci design harness guidelines:

```tsx
<AppShell>
  <div className="pi-page">
    <section className="pi-page-hero">
      <p className="pi-eyebrow">Area label</p>
      <h1 className="pi-title mt-2">Page title</h1>
      <p className="pi-subtitle">One sentence explaining the page.</p>
    </section>

    <section className="grid gap-3 sm:grid-cols-3">
      <div className="pi-metric-card">...</div>
    </section>

    <section className="pi-panel p-3">...</section>
  </div>
</AppShell>
```

**Design Classes:**

| Class | Usage |
|-------|-------|
| `pi-page` | Main page container |
| `pi-page-hero` | Hero section with title and subtitle |
| `pi-eyebrow` | Small label above title |
| `pi-title` | Page title (H1) |
| `pi-subtitle` | Descriptive subtitle |
| `pi-metric-card` | Metric display cards |
| `pi-panel` | Content panels with consistent styling |

资料来源：[web/DESIGN-HARNESS.md](https://github.com/jshsakura/oc-piloci/blob/main/web/DESIGN-HARNESS.md)

---

---

## Doramagic 踩坑日志

项目：jshsakura/oc-piloci

摘要：发现 33 个潜在踩坑项，其中 0 个为 high/blocking；最高优先级：安装坑 - 失败模式：installation: Release v0.3.61。

## 1. 安装坑 · 失败模式：installation: Release v0.3.61

- 严重度：medium
- 证据强度：source_linked
- 发现：Developers should check this installation risk before relying on the project: Release v0.3.61
- 对用户的影响：Upgrade or migration may change expected behavior: Release v0.3.61
- 建议检查：Before packaging this project, run the relevant install/config/quickstart check for: Release v0.3.61. Context: Observed when using docker
- 防护动作：State this as source-backed community evidence, not as Doramagic reproduction.
- 证据：failure_mode_cluster:github_release | fmev_238385c7d11f6862a1b9d0c024a94181 | https://github.com/jshsakura/oc-piloci/releases/tag/v0.3.61 | Release v0.3.61

## 2. 安装坑 · 失败模式：installation: Release v0.3.62

- 严重度：medium
- 证据强度：source_linked
- 发现：Developers should check this installation risk before relying on the project: Release v0.3.62
- 对用户的影响：Upgrade or migration may change expected behavior: Release v0.3.62
- 建议检查：Before packaging this project, run the relevant install/config/quickstart check for: Release v0.3.62. Context: Observed when using docker
- 防护动作：State this as source-backed community evidence, not as Doramagic reproduction.
- 证据：failure_mode_cluster:github_release | fmev_115c2527b334fad79621b999d3e94857 | https://github.com/jshsakura/oc-piloci/releases/tag/v0.3.62 | Release v0.3.62

## 3. 安装坑 · 失败模式：installation: Release v0.3.63

- 严重度：medium
- 证据强度：source_linked
- 发现：Developers should check this installation risk before relying on the project: Release v0.3.63
- 对用户的影响：Upgrade or migration may change expected behavior: Release v0.3.63
- 建议检查：Before packaging this project, run the relevant install/config/quickstart check for: Release v0.3.63. Context: Observed when using docker
- 防护动作：State this as source-backed community evidence, not as Doramagic reproduction.
- 证据：failure_mode_cluster:github_release | fmev_348782b397ba2bb56859e630ea890c99 | https://github.com/jshsakura/oc-piloci/releases/tag/v0.3.63 | Release v0.3.63

## 4. 安装坑 · 失败模式：installation: Release v0.3.64

- 严重度：medium
- 证据强度：source_linked
- 发现：Developers should check this installation risk before relying on the project: Release v0.3.64
- 对用户的影响：Upgrade or migration may change expected behavior: Release v0.3.64
- 建议检查：Before packaging this project, run the relevant install/config/quickstart check for: Release v0.3.64. Context: Observed when using docker
- 防护动作：State this as source-backed community evidence, not as Doramagic reproduction.
- 证据：failure_mode_cluster:github_release | fmev_a5608f313037217768976fadbcbd00e3 | https://github.com/jshsakura/oc-piloci/releases/tag/v0.3.64 | Release v0.3.64

## 5. 安装坑 · 失败模式：installation: Release v0.3.65

- 严重度：medium
- 证据强度：source_linked
- 发现：Developers should check this installation risk before relying on the project: Release v0.3.65
- 对用户的影响：Upgrade or migration may change expected behavior: Release v0.3.65
- 建议检查：Before packaging this project, run the relevant install/config/quickstart check for: Release v0.3.65. Context: Observed when using docker
- 防护动作：State this as source-backed community evidence, not as Doramagic reproduction.
- 证据：failure_mode_cluster:github_release | fmev_593467b90b436b99ecac227152d65f93 | https://github.com/jshsakura/oc-piloci/releases/tag/v0.3.65 | Release v0.3.65

## 6. 安装坑 · 失败模式：installation: Release v0.3.66

- 严重度：medium
- 证据强度：source_linked
- 发现：Developers should check this installation risk before relying on the project: Release v0.3.66
- 对用户的影响：Upgrade or migration may change expected behavior: Release v0.3.66
- 建议检查：Before packaging this project, run the relevant install/config/quickstart check for: Release v0.3.66. Context: Observed when using docker
- 防护动作：State this as source-backed community evidence, not as Doramagic reproduction.
- 证据：failure_mode_cluster:github_release | fmev_41cea4cedb6fe85b101b1ee1e744a2a2 | https://github.com/jshsakura/oc-piloci/releases/tag/v0.3.66 | Release v0.3.66

## 7. 安装坑 · 失败模式：installation: Release v0.3.67

- 严重度：medium
- 证据强度：source_linked
- 发现：Developers should check this installation risk before relying on the project: Release v0.3.67
- 对用户的影响：Upgrade or migration may change expected behavior: Release v0.3.67
- 建议检查：Before packaging this project, run the relevant install/config/quickstart check for: Release v0.3.67. Context: Observed when using docker
- 防护动作：State this as source-backed community evidence, not as Doramagic reproduction.
- 证据：failure_mode_cluster:github_release | fmev_51ad1a6fbbb3b6c3fdc1be72bcfae7ea | https://github.com/jshsakura/oc-piloci/releases/tag/v0.3.67 | Release v0.3.67

## 8. 安装坑 · 失败模式：installation: Release v0.3.68

- 严重度：medium
- 证据强度：source_linked
- 发现：Developers should check this installation risk before relying on the project: Release v0.3.68
- 对用户的影响：Upgrade or migration may change expected behavior: Release v0.3.68
- 建议检查：Before packaging this project, run the relevant install/config/quickstart check for: Release v0.3.68. Context: Observed when using docker
- 防护动作：State this as source-backed community evidence, not as Doramagic reproduction.
- 证据：failure_mode_cluster:github_release | fmev_7bc0641dd202d881746e1010d1b03fe5 | https://github.com/jshsakura/oc-piloci/releases/tag/v0.3.68 | Release v0.3.68

## 9. 安装坑 · 失败模式：installation: Release v0.3.69

- 严重度：medium
- 证据强度：source_linked
- 发现：Developers should check this installation risk before relying on the project: Release v0.3.69
- 对用户的影响：Upgrade or migration may change expected behavior: Release v0.3.69
- 建议检查：Before packaging this project, run the relevant install/config/quickstart check for: Release v0.3.69. Context: Observed when using docker
- 防护动作：State this as source-backed community evidence, not as Doramagic reproduction.
- 证据：failure_mode_cluster:github_release | fmev_ba1666889342a143a76dda2fa013ddf2 | https://github.com/jshsakura/oc-piloci/releases/tag/v0.3.69 | Release v0.3.69

## 10. 安装坑 · 失败模式：installation: Release v0.3.70

- 严重度：medium
- 证据强度：source_linked
- 发现：Developers should check this installation risk before relying on the project: Release v0.3.70
- 对用户的影响：Upgrade or migration may change expected behavior: Release v0.3.70
- 建议检查：Before packaging this project, run the relevant install/config/quickstart check for: Release v0.3.70. Context: Observed when using docker
- 防护动作：State this as source-backed community evidence, not as Doramagic reproduction.
- 证据：failure_mode_cluster:github_release | fmev_18504a4306cc5d44261e6d0f5ec47f54 | https://github.com/jshsakura/oc-piloci/releases/tag/v0.3.70 | Release v0.3.70

## 11. 安装坑 · 失败模式：installation: Release v0.3.71

- 严重度：medium
- 证据强度：source_linked
- 发现：Developers should check this installation risk before relying on the project: Release v0.3.71
- 对用户的影响：Upgrade or migration may change expected behavior: Release v0.3.71
- 建议检查：Before packaging this project, run the relevant install/config/quickstart check for: Release v0.3.71. Context: Observed when using docker
- 防护动作：State this as source-backed community evidence, not as Doramagic reproduction.
- 证据：failure_mode_cluster:github_release | fmev_4f40f1505195306061984312ceafb8d8 | https://github.com/jshsakura/oc-piloci/releases/tag/v0.3.71 | Release v0.3.71

## 12. 安装坑 · 失败模式：installation: Release v0.3.72

- 严重度：medium
- 证据强度：source_linked
- 发现：Developers should check this installation risk before relying on the project: Release v0.3.72
- 对用户的影响：Upgrade or migration may change expected behavior: Release v0.3.72
- 建议检查：Before packaging this project, run the relevant install/config/quickstart check for: Release v0.3.72. Context: Observed when using docker
- 防护动作：State this as source-backed community evidence, not as Doramagic reproduction.
- 证据：failure_mode_cluster:github_release | fmev_a62aef6e3f8ef8401a1d0bb3ce5d66d5 | https://github.com/jshsakura/oc-piloci/releases/tag/v0.3.72 | Release v0.3.72

## 13. 安装坑 · 失败模式：installation: Release v0.3.73

- 严重度：medium
- 证据强度：source_linked
- 发现：Developers should check this installation risk before relying on the project: Release v0.3.73
- 对用户的影响：Upgrade or migration may change expected behavior: Release v0.3.73
- 建议检查：Before packaging this project, run the relevant install/config/quickstart check for: Release v0.3.73. Context: Observed when using docker
- 防护动作：State this as source-backed community evidence, not as Doramagic reproduction.
- 证据：failure_mode_cluster:github_release | fmev_402be624902b0ff4a70763241e96f92a | https://github.com/jshsakura/oc-piloci/releases/tag/v0.3.73 | Release v0.3.73

## 14. 安装坑 · 失败模式：installation: Release v0.3.74

- 严重度：medium
- 证据强度：source_linked
- 发现：Developers should check this installation risk before relying on the project: Release v0.3.74
- 对用户的影响：Upgrade or migration may change expected behavior: Release v0.3.74
- 建议检查：Before packaging this project, run the relevant install/config/quickstart check for: Release v0.3.74. Context: Observed when using docker
- 防护动作：State this as source-backed community evidence, not as Doramagic reproduction.
- 证据：failure_mode_cluster:github_release | fmev_f1c1782e6dc53172212d524d1e194b8f | https://github.com/jshsakura/oc-piloci/releases/tag/v0.3.74 | Release v0.3.74

## 15. 安装坑 · 失败模式：installation: Release v0.3.75

- 严重度：medium
- 证据强度：source_linked
- 发现：Developers should check this installation risk before relying on the project: Release v0.3.75
- 对用户的影响：Upgrade or migration may change expected behavior: Release v0.3.75
- 建议检查：Before packaging this project, run the relevant install/config/quickstart check for: Release v0.3.75. Context: Observed when using docker
- 防护动作：State this as source-backed community evidence, not as Doramagic reproduction.
- 证据：failure_mode_cluster:github_release | fmev_65320a1ebb2900791f1e9b16cbf8e8d6 | https://github.com/jshsakura/oc-piloci/releases/tag/v0.3.75 | Release v0.3.75

## 16. 安装坑 · 失败模式：installation: Release v0.3.76

- 严重度：medium
- 证据强度：source_linked
- 发现：Developers should check this installation risk before relying on the project: Release v0.3.76
- 对用户的影响：Upgrade or migration may change expected behavior: Release v0.3.76
- 建议检查：Before packaging this project, run the relevant install/config/quickstart check for: Release v0.3.76. Context: Observed when using docker
- 防护动作：State this as source-backed community evidence, not as Doramagic reproduction.
- 证据：failure_mode_cluster:github_release | fmev_78ad7e0a2110bee066ed708a51554c0d | https://github.com/jshsakura/oc-piloci/releases/tag/v0.3.76 | Release v0.3.76

## 17. 安装坑 · 来源证据：Release v0.3.15

- 严重度：medium
- 证据强度：source_linked
- 发现：GitHub 社区证据显示该项目存在一个安装相关的待验证问题：Release v0.3.15
- 对用户的影响：可能增加新用户试用和生产接入成本。
- 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。
- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。
- 证据：community_evidence:github | cevd_ab726a10491d4c14b7fa95fd35beee64 | https://github.com/jshsakura/oc-piloci/releases/tag/v0.3.15 | 来源讨论提到 docker 相关条件，需在安装/试用前复核。

## 18. 安装坑 · 来源证据：Release v0.3.16

- 严重度：medium
- 证据强度：source_linked
- 发现：GitHub 社区证据显示该项目存在一个安装相关的待验证问题：Release v0.3.16
- 对用户的影响：可能增加新用户试用和生产接入成本。
- 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。
- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。
- 证据：community_evidence:github | cevd_bc556664008b404db3fc774023736dcb | https://github.com/jshsakura/oc-piloci/releases/tag/v0.3.16 | 来源讨论提到 docker 相关条件，需在安装/试用前复核。

## 19. 安装坑 · 来源证据：Release v0.3.17

- 严重度：medium
- 证据强度：source_linked
- 发现：GitHub 社区证据显示该项目存在一个安装相关的待验证问题：Release v0.3.17
- 对用户的影响：可能增加新用户试用和生产接入成本。
- 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。
- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。
- 证据：community_evidence:github | cevd_013d47bb794f4f13b2f8e2a5859cdabf | https://github.com/jshsakura/oc-piloci/releases/tag/v0.3.17 | 来源讨论提到 docker 相关条件，需在安装/试用前复核。

## 20. 安装坑 · 来源证据：Release v0.3.22

- 严重度：medium
- 证据强度：source_linked
- 发现：GitHub 社区证据显示该项目存在一个安装相关的待验证问题：Release v0.3.22
- 对用户的影响：可能增加新用户试用和生产接入成本。
- 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。
- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。
- 证据：community_evidence:github | cevd_4bfd96a53e7e4d859637f79a8ee350d1 | https://github.com/jshsakura/oc-piloci/releases/tag/v0.3.22 | 来源讨论提到 docker 相关条件，需在安装/试用前复核。

## 21. 安装坑 · 来源证据：Release v0.3.23

- 严重度：medium
- 证据强度：source_linked
- 发现：GitHub 社区证据显示该项目存在一个安装相关的待验证问题：Release v0.3.23
- 对用户的影响：可能增加新用户试用和生产接入成本。
- 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。
- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。
- 证据：community_evidence:github | cevd_38baea4290d648a887a4c7575a3c8c55 | https://github.com/jshsakura/oc-piloci/releases/tag/v0.3.23 | 来源讨论提到 docker 相关条件，需在安装/试用前复核。

## 22. 安装坑 · 来源证据：Release v0.3.24

- 严重度：medium
- 证据强度：source_linked
- 发现：GitHub 社区证据显示该项目存在一个安装相关的待验证问题：Release v0.3.24
- 对用户的影响：可能增加新用户试用和生产接入成本。
- 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。
- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。
- 证据：community_evidence:github | cevd_654bcb552e094dd18bcc59cfdc2a83b5 | https://github.com/jshsakura/oc-piloci/releases/tag/v0.3.24 | 来源讨论提到 docker 相关条件，需在安装/试用前复核。

## 23. 安装坑 · 来源证据：Release v0.3.25

- 严重度：medium
- 证据强度：source_linked
- 发现：GitHub 社区证据显示该项目存在一个安装相关的待验证问题：Release v0.3.25
- 对用户的影响：可能增加新用户试用和生产接入成本。
- 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。
- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。
- 证据：community_evidence:github | cevd_e2f6528bce8040c0bab4d074214b33c5 | https://github.com/jshsakura/oc-piloci/releases/tag/v0.3.25 | 来源讨论提到 docker 相关条件，需在安装/试用前复核。

## 24. 安装坑 · 来源证据：Release v0.3.26

- 严重度：medium
- 证据强度：source_linked
- 发现：GitHub 社区证据显示该项目存在一个安装相关的待验证问题：Release v0.3.26
- 对用户的影响：可能增加新用户试用和生产接入成本。
- 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。
- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。
- 证据：community_evidence:github | cevd_f358a19a360f476bbd41bb4e35bca86e | https://github.com/jshsakura/oc-piloci/releases/tag/v0.3.26 | 来源讨论提到 docker 相关条件，需在安装/试用前复核。

## 25. 安装坑 · 来源证据：Release v0.3.27

- 严重度：medium
- 证据强度：source_linked
- 发现：GitHub 社区证据显示该项目存在一个安装相关的待验证问题：Release v0.3.27
- 对用户的影响：可能增加新用户试用和生产接入成本。
- 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。
- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。
- 证据：community_evidence:github | cevd_973b50ab39634ba4af49b7df022af9a1 | https://github.com/jshsakura/oc-piloci/releases/tag/v0.3.27 | 来源讨论提到 docker 相关条件，需在安装/试用前复核。

## 26. 安装坑 · 来源证据：Release v0.3.28

- 严重度：medium
- 证据强度：source_linked
- 发现：GitHub 社区证据显示该项目存在一个安装相关的待验证问题：Release v0.3.28
- 对用户的影响：可能增加新用户试用和生产接入成本。
- 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。
- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。
- 证据：community_evidence:github | cevd_ca63e0beff7c4da8844cdea3d52415b6 | https://github.com/jshsakura/oc-piloci/releases/tag/v0.3.28 | 来源讨论提到 docker 相关条件，需在安装/试用前复核。

## 27. 配置坑 · 可能修改宿主 AI 配置

- 严重度：medium
- 证据强度：source_linked
- 发现：项目面向 Claude/Cursor/Codex/Gemini/OpenCode 等宿主，或安装命令涉及用户配置目录。
- 对用户的影响：安装可能改变本机 AI 工具行为，用户需要知道写入位置和回滚方法。
- 建议检查：列出会写入的配置文件、目录和卸载/回滚步骤。
- 防护动作：涉及宿主配置目录时必须给回滚路径，不能只给安装命令。
- 证据：capability.host_targets | github_repo:1219455965 | https://github.com/jshsakura/oc-piloci | host_targets=mcp_host, claude

## 28. 能力坑 · 能力判断依赖假设

- 严重度：medium
- 证据强度：source_linked
- 发现：README/documentation is current enough for a first validation pass.
- 对用户的影响：假设不成立时，用户拿不到承诺的能力。
- 建议检查：将假设转成下游验证清单。
- 防护动作：假设必须转成验证项；没有验证结果前不能写成事实。
- 证据：capability.assumptions | github_repo:1219455965 | https://github.com/jshsakura/oc-piloci | README/documentation is current enough for a first validation pass.

## 29. 维护坑 · 维护活跃度未知

- 严重度：medium
- 证据强度：source_linked
- 发现：未记录 last_activity_observed。
- 对用户的影响：新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。
- 建议检查：补 GitHub 最近 commit、release、issue/PR 响应信号。
- 防护动作：维护活跃度未知时，推荐强度不能标为高信任。
- 证据：evidence.maintainer_signals | github_repo:1219455965 | https://github.com/jshsakura/oc-piloci | last_activity_observed missing

## 30. 安全/权限坑 · 下游验证发现风险项

- 严重度：medium
- 证据强度：source_linked
- 发现：no_demo
- 对用户的影响：下游已经要求复核，不能在页面中弱化。
- 建议检查：进入安全/权限治理复核队列。
- 防护动作：下游风险存在时必须保持 review/recommendation 降级。
- 证据：downstream_validation.risk_items | github_repo:1219455965 | https://github.com/jshsakura/oc-piloci | no_demo; severity=medium

## 31. 安全/权限坑 · 存在评分风险

- 严重度：medium
- 证据强度：source_linked
- 发现：no_demo
- 对用户的影响：风险会影响是否适合普通用户安装。
- 建议检查：把风险写入边界卡，并确认是否需要人工复核。
- 防护动作：评分风险必须进入边界卡，不能只作为内部分数。
- 证据：risks.scoring_risks | github_repo:1219455965 | https://github.com/jshsakura/oc-piloci | no_demo; severity=medium

## 32. 维护坑 · issue/PR 响应质量未知

- 严重度：low
- 证据强度：source_linked
- 发现：issue_or_pr_quality=unknown。
- 对用户的影响：用户无法判断遇到问题后是否有人维护。
- 建议检查：抽样最近 issue/PR，判断是否长期无人处理。
- 防护动作：issue/PR 响应未知时，必须提示维护风险。
- 证据：evidence.maintainer_signals | github_repo:1219455965 | https://github.com/jshsakura/oc-piloci | issue_or_pr_quality=unknown

## 33. 维护坑 · 发布节奏不明确

- 严重度：low
- 证据强度：source_linked
- 发现：release_recency=unknown。
- 对用户的影响：安装命令和文档可能落后于代码，用户踩坑概率升高。
- 建议检查：确认最近 release/tag 和 README 安装命令是否一致。
- 防护动作：发布节奏未知或过期时，安装说明必须标注可能漂移。
- 证据：evidence.maintainer_signals | github_repo:1219455965 | https://github.com/jshsakura/oc-piloci | release_recency=unknown

<!-- canonical_name: jshsakura/oc-piloci; human_manual_source: deepwiki_human_wiki -->
