summaryrefslogtreecommitdiff
path: root/docs/architecture.md
diff options
context:
space:
mode:
Diffstat (limited to 'docs/architecture.md')
-rw-r--r--docs/architecture.md375
1 files changed, 0 insertions, 375 deletions
diff --git a/docs/architecture.md b/docs/architecture.md
deleted file mode 100644
index 04e2489..0000000
--- a/docs/architecture.md
+++ /dev/null
@@ -1,375 +0,0 @@
-# Architecture
-
-設計項目ごとの実装・テスト状況は
-[設計・実装・テスト状況一覧](implementation-status.md)を参照してください。
-
-`tiny-convmem-mcp` is a single-process C17 MCP server backed by a
-durable append-only conversation log. The executable owns the stdio dispatch
-boundary and uses mcpc's bundled mjson parser through a local compatibility
-layer.
-
-Conversation-memory work is split into these dependencies:
-
-```text
-MCP transport and tools -> domain contracts <- storage adapters
-```
-
-- `src/mcp` translates MCP requests and responses. It may depend on mcpc and
- domain contracts, but it must not contain persistence logic.
-- `src/domain` owns conversation and message concepts without depending on
- mcpc or a database.
-- `src/storage` implements the versioned binary log, recovery, snapshot, and
- compaction through the platform-neutral `src/sys` API.
-- `src/sys` owns UTF-8 path conversion, files, process locks, durable flush,
- clocks, and random bytes. Its implementation is the only platform split.
-
-## Implemented prototype contract (v1)
-
-The seven public tools are `write_message`, `update_message`, `read_messages`,
-`search_messages`, `delete_message`, `rebuild_index`, and `get_system_health`. The detailed
-"ProtoType Architecture v0.0.1" below is retained as the original proposal;
-where it conflicts with this section, the implemented contract is authoritative.
-
-- `write_message` creates the ULID and UTC millisecond timestamp. A PUT or DEL
- succeeds only after the platform durability flush succeeds.
-- Deletion is immediately invisible but remains a tombstone until synchronous
- compaction. `metadata.deleted` is not part of immutable Message data.
-- Metadata supports optional `tool_call_id`, `tags`, `memory_tier`, memory kind,
- importance, summary, typed relations, and summary source IDs.
- Tiers remain labels; no automatic lifecycle operation is performed.
-- `read_messages` defaults to the compatible chronological history view and also
- exposes sessions, context, and versioned JSONL export views.
-- UPDATE records use optimistic revisions and delta fields. A no-op update does
- not write or flush storage.
-- Search uses ASCII-case-folded Unicode codepoint 2/3-grams, verifies hash
- matches against the original codepoints, and ranks exact substrings first.
-- A log record contains magic, format version, type, payload length, sequence,
- and payload CRC32. PUT, DEL, and generation marker records are supported.
-- A valid snapshot contains immutable messages and a log generation/offset.
- Startup loads it only when the active log generation matches, then replays the
- tail. Otherwise startup performs a full log replay.
-- An incomplete final record is truncated. Unknown versions/types, invalid
- lengths, non-monotonic sequences, or CRC errors within a complete record stop
- startup without silently skipping data.
-- `--data-dir <path>` is mandatory and guarded by a process-exclusive lock.
-
-The prototype remains Windows x64/MSVC and single-process. Retention,
-encryption, search pagination, multiple writers, automated summarization, and secure
-physical erasure are outside v1.
-
-# ProtoType Architecture v0.0.1
-Tiny-ConvMem-MCP: FINAL TOOL INTERFACE SPECIFICATION (v1.0)
-
-この定義は、システムと外部(LLMプロセス)との間の「契約書」となります。これで実装に着手できますね!
-No. Tool Name カテゴリ 機能概要 入力引数 (Arguments) 出力値 (Response)
-1 write_message SET/WRITE 新しいメッセージイベントをログファイルへ追記し、インデックスを更新する。 session_id, role, content, timestamp status: Enum(OK, ERROR)
-2 read_messages GET/READ 特定セッションIDのメッセージを安定順序でページ取得する。 session_id、limit、cursor history、nextCursor
-3 search_messages GET/READ クエリに基づいてログファイルから関連するメッセージを特定し、返す。(インデックス利用が前提) query, session_id (任意), limit: 整数 results: 配列(メッセージオブジェクト)
-4 delete_message SET/MANAGE 特定のメッセージIDを指定してログから完全に削除し、インデックスをクリーンアップする。 message_id: 唯一ID, session_id (任意) status: Enum(OK, NOT_FOUND)
-5 rebuild_index SET/MANAGE インデックスファイルを再生成し、データ整合性を回復させる。(メンテナンス) なし status: Enum(OK, ERROR)
-6 get_system_health GET/READ システムの稼働状況とログファイルの健全性レポートを提供する。 なし report: JSON (ヘルスステータス)
-
-
-データ構造設計:メッセージオブジェクト (Message Object Definition)
-🎯 基本方針
-
-全てのデータは**「不変(Immutable)」**であることを原則とします。一度記録されたイベントは変更せず、削除が必要な場合は新しいエントリで処理するか、専用の delete_message コマンドで対応します。
-📝 メッセージオブジェクト (Message) の構造定義案
-
-メッセージを構成する要素を分解し、データ型を明確に定義します。(C++でのStructやJSONスキーマとして使用できます)
-
-{
- "message_id": "UUID/ULID文字列", // ★最重要。削除・参照のユニークキー
- "session_id": "ユーザー固有のセッション識別子",
- "timestamp": 1720843200000, // UTCミリ秒タイムスタンプ (UTC厳守)
- "role": "ENUM (user | assistant | system)", // メッセージの発信元
- "content": "メッセージの本文(テキストデータ)", // 記録したい主要な情報
- "metadata": { // 追加情報格納用。拡張性を持たせるための辞書型
- "tool_call_id": "もしこのメッセージがツール呼び出しの結果ならIDを保持",
- "is_system_message": true/false, // システム操作やプロンプト定義など
- "checksum": "(オプション)データの完全性を保証するためのハッシュ値"
- }
-}
-
-⚙️ 補足的なデータ構造の定義
-
-ログシステムをより堅牢にするために、メッセージとは別に必要な型も定義しておくと完璧です。
-
- LogEntry (永続化層の最小単位):
- 実際にディスクに書き込まれる最も小さいデータ単位。(上記 Message のバイナリ/JSON表現)
- SearchIndexEntry (インデックス構造体):
- 検索効率を最大化するための、非常に軽量なメタデータ。
- message_id: どのメッセージかを示すキー
- session_id: 属するセッションID
- keywords_hash: メッセージ内容から抽出されたキーワードのハッシュ値(またはリスト)
- file_offset: ログファイル内での物理的な開始位置
- data_size: そのメッセージが占めるバイトサイズ
-
-📐 Tiny-ConMem-MCP: ストレージ制御 統合設計仕様
-1. アーキテクチャ概観
-
-┌─────────────────────────────────────────────────────────────┐
-│ 外部プロセス (LLM Host) │
-└──────────────────────────┬──────────────────────────────────┘
- │ stdio (JSON-RPC)
-┌──────────────────────────▼──────────────────────────────────┐
-│ L1: Protocol Layer (mcpc) │
-│ MCPメッセージの受信・ツールディスパッチ │
-└──────────────────────────┬──────────────────────────────────┘
- │
-┌──────────────────────────▼──────────────────────────────────┐
-│ L2: Memory Core (ビジネスロジック) │
-│ │
-│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
-│ │ Write Queue │ │ In-Memory │ │ Search │ │
-│ │ (保留中キュー) │ │ Index │ │ Engine │ │
-│ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │
-│ │ │ │ │
-└─────────┼────────────────┼────────────────┼──────────────────┘
- │ │ │
-┌─────────▼────────────────▼────────────────▼──────────────────┐
-│ L3: Persistence Layer (永続化層) │
-│ │
-│ ┌──────────┐ ┌────────────┐ ┌───────────────────┐ │
-│ │ active.log│ │snapshot.bin│ │ compaction worker │ │
-│ │(append- │ │(状態保存) │ │(ログ整理・容量削減) │ │
-│ │ only) │ └────────────┘ └───────────────────┘ │
-│ └──────────┘ │
-└─────────────────────────────────────────────────────────────┘
-
-2. データ構造定義
-2.1 Message Object(永続化対象の基本単位)
-
-全ツールの入力・出力の中心となるデータです。一度書き込まれたら不変(Immutable)で、変更は新エントリの追記で表現します。
-
-// Message (ログ1レコードの論理構造)
-{
- "message_id": "ULID文字列", // 削除・参照のユニークキー
- "session_id": "セッション識別子", // セッション単位のグルーピング
- "timestamp": 1720843200000, // UTC ミリ秒
- "role": "user | assistant | system",
- "content": "メッセージ本文",
- "metadata": {
- "tool_call_id": "(任意)ツール呼び出しID",
- "tags": ["カレー", "設計"], //(任意)検索用タグ
- "memory_tier": "short | mid | long", // 後述のメモリ階層フラグ
- "deleted": false // 論理削除フラグ
- }
-}
-
-2.2 LogRecord(ディスク上の物理フォーマット)
-
-active.log に追記される物理レコードです。Message Object をシリアライズしたものに、検証用のメタ情報を付加します。
-
-┌──────────┬──────────┬─────────────────────┬──────────┐
-│ record │ payload │ payload (serialized │ checksum │
-│ length │ type │ Message Object) │ (CRC32) │
-│ (4 byte) │ (1 byte) │ (可変長) │ (4 byte) │
-└──────────┴──────────┴─────────────────────┴──────────┘
-
-payload_type:
- 0x01 = PUT (メッセージの書き込み)
- 0x02 = DEL (メッセージの論理削除)
- 0x03 = SNAPSHOT_MARKER (snapshot境界マーカー)
-
-2.3 In-Memory Index(メモリ上のインデックス)
-
-メモリ上に保持する高速検索用の目次です。これが SearchIndexEntry の実体で、search_messages / read_messages の高速化を担います。
-
-struct IndexEntry {
- uint64_t file_id; // ログファイル識別子 (1 = active.log 等)
- uint64_t offset; // レコードの開始バイト位置
- uint32_t length; // レコード長
- int64_t timestamp; // メッセージのタイムスタンプ
- uint8_t type; // PUT / DEL
- // セッションID・メッセージID は
- // ハッシュテーブルの Key として使用
-};
-
-// メモリ上のデータ構造(ハッシュテーブル + リスト)
-HashTable<message_id, IndexEntry*> // message_id → 位置情報
-HashTable<session_id, List<message_id>> // session_id → 所属メッセージ一覧
-HashTable<keyword_hash, List<message_id>> // 検索用キーワード逆引き
-
-3. 書き込みパイプライン(write_message / delete_message)
-
-┌─────────────┐
-│ MCP Tool 呼出 │ write_message / delete_message
-└──────┬──────┘
- │
- ▼
-┌─────────────────────┐
-│ Step 1: メモリ更新 │ In-Memory Index に即座に反映
-│ │ (PUT → 追加, DEL → フラグ更新)
-└──────┬──────────────┘
- │
- ▼
-┌─────────────────────┐
-│ Step 2: キュー追加 │ Write Queue に LogRecord を積む
-└──────┬──────────────┘
- │
- ▼
-┌─────────────────────┐
-│ Step 3: バッチ書き込み │ flush_interval_ms (1000ms) または
-│ │ max_pending_records (128件) に
-│ │ 達したら write() で一括追記
-└──────┬──────────────┘
- │
- ▼
-┌─────────────────────┐
-│ Step 4: 定期 fsync │ fsync_interval_ms (5000ms) ごとに
-│ │ fsync() でディスクに確実に落とす
-└─────────────────────┘
-
-設計パラメータ:
-
-#define FLUSH_INTERVAL_MS 1000 // キュー→ファイルの書き出し間隔
-#define FSYNC_INTERVAL_MS 5000 // fsync() の実行間隔
-#define MAX_PENDING_RECORDS 128 // キューの最大保留件数
-
-4. 読み込みパイプライン(read_messages / search_messages)
-
-┌─────────────┐
-│ MCP Tool 呼出 │ read_messages / search_messages
-└──────┬──────┘
- │
- ▼
-┌─────────────────────┐
-│ Step 1: インデックス │ In-Memory Index から該当レコードの
-│ 検索 │ (file_id, offset, length) を取得
-└──────┬──────────────┘
- │
- ▼
-┌─────────────────────┐
-│ Step 2: pread() │ ログファイルの該当オフセットのみ
-│ 部分読み出し │ pread(fd, buf, length, offset)
-│ │ ※ログ全体は読み込まない
-└──────┬──────────────┘
- │
- ▼
-┌─────────────────────┐
-│ Step 3: デシリアライズ│ LogRecord → Message Object に復元
-│ │ deleted フラグを確認し、
-│ │ 削除済みなら除外
-└──────┬──────────────┘
- │
- ▼
-┌─────────────────────┐
-│ Step 4: レスポンス │ JSON配列として MCP 経由で返却
-│ 返却 │
-└─────────────────────┘
-
-5. 起動時復旧シーケンス
-
-プロセス起動
- │
- ▼
-┌──────────────────┐
-│ Step 1: │
-│ snapshot.bin 読込 │ 最後のスナップショットから
-│ │ In-Memory Index を復元
-└──────┬───────────┘
- │
- ▼
-┌──────────────────┐
-│ Step 2: │ snapshot 作成時点以降の
-│ ログ再生 │ active.log を先頭から順に読み、
-│ │ PUT / DEL レコードを適用
-│ │ (index を更新していく)
-└──────┬───────────┘
- │
- ▼
-┌──────────────────┐
-│ Step 3: │ インデックスが完全に再構築された状態で
-│ サービス開始 │ stdio 受付を開始
-└──────────────────┘
-
-6. Snapshot 処理(rebuild_index の一部としても動作)
-
-現在有効なデータ (deleted=false) を列挙
- │
- ▼
-snapshot.tmp にシリアライズして書き出し
- │
- ▼
-fsync(snapshot.tmp)
- │
- ▼
-rename(snapshot.tmp → snapshot.bin)
- │ ← アトミック操作。クラッシュしても古い snapshot.bin が残る
- ▼
-完了
-
-役割: 起動時のログ再生量を減らし、起動時間を短縮する。
-7. Compaction 処理
-
-トリガー: ログファイルサイズが閾値を超えた または rebuild_index 呼出
- │
- ▼
-現在有効なデータ (deleted=false) のみを列挙
- │
- ▼
-new_active.log に有効レコードのみを書き出し
- │
- ▼
-fsync(new_active.log)
- │
- ▼
-rename(new_active.log → active.log)
- │ ← アトミック操作
- ▼
-古いログファイルを削除
- │
- ▼
-新しい snapshot.bin も生成 (compaction 後の状態を保存)
- │
- ▼
-In-Memory Index の file_id / offset を更新
-
-役割: ログ肥大化を防ぎ、ディスク使用量を削減する。
-8. メモリ階層とデータライフサイクル
-
-Message Object の metadata.memory_tier を用いて、LLM会話の寿命を管理します。
-
-┌─────────────┬──────────────────────────┬──────────────────┐
-│ 階層 │ 内容 │ 保存場所 │
-├─────────────┼──────────────────────────┼──────────────────┤
-│ short (短期) │ 直近の会話メッセージ │ メモリ + active.log│
-│ │ │ (即座に参照可能) │
-├─────────────┼──────────────────────────┼──────────────────┤
-│ mid (中期) │ セッションの要約・抽象化 │ active.log + │
-│ │ │ snapshot │
-├─────────────┼──────────────────────────┼──────────────────┤
-│ long (長期) │ 重要なユーザー設定・ │ snapshot 優先で │
-│ │ 継続的記憶 (key-value) │ 永続化 │
-├─────────────┼──────────────────────────┼──────────────────┤
-│ discard │ 一時的な雑談・重複情報・ │ compaction 時に │
-│ (破棄対象) │ 古い全文ログ │ 削除対象 │
-└─────────────┴──────────────────────────┴──────────────────┘
-
-ライフサイクル:
-
-write_message (memory_tier=short)
- │
- │ セッション終了・要約トリガー
- ▼
-要約生成 → write_message (memory_tier=mid)
- │ 元の short メッセージを delete_message で論理削除
- ▼
-compaction 時に short の deleted レコードが物理削除される
- │
- │ 長期的に重要と判断されたもの
- ▼
-write_message (memory_tier=long)
- │ snapshot 優先で永続化
- ▼
-discard レコードは compaction 時に消える
-
-9. MCP Tool とストレージ層の対応表(最終版)
-Tool L2処理 L3処理 関連コンポーネント
-write_message Index更新 + Queue追加 flush時に active.log へ追記 Write Queue, In-Memory Index
-read_messages session_id で Index 検索 pread() で該当レコード読み出し In-Memory Index, active.log
-search_messages キーワードハッシュで Index 検索 pread() で該当レコード読み出し In-Memory Index, active.log
-delete_message Index の type を DEL に更新 DEL レコードを active.log へ追記 Write Queue, In-Memory Index
-rebuild_index 全有効データを再列挙 snapshot 作成 + compaction 実行 Snapshot, Compaction Worker
-get_system_health 各種カウンタ収集 ログファイルサイズ・整合性チェック 全コンポーネント