diff options
Diffstat (limited to 'docs/Design.md')
| -rw-r--r-- | docs/Design.md | 216 |
1 files changed, 216 insertions, 0 deletions
diff --git a/docs/Design.md b/docs/Design.md new file mode 100644 index 0000000..3485a73 --- /dev/null +++ b/docs/Design.md @@ -0,0 +1,216 @@ +# Tiny ConvMem MCP Design + +## 1. 文書の位置づけ + +本書は `tiny-convmem-mcp` の設計、実装済み契約、制約、I/O 予算、実装状況をまとめた正本である。 +過去のプロトタイプ案と本書が矛盾する場合は、本書と公開ツールの実装を優先する。 + +診断結果と次タスクは [Review.md](Review.md) を参照する。 + +## 2. 目的とスコープ + +`tiny-convmem-mcp` は、会話メッセージをローカルに永続化し、MCP 経由で読み書き、更新、検索、削除できる単一プロセスの C17 サーバーである。 + +現行 v1 の対象は次のとおり。 + +- Windows x64 / MSVC +- stdio JSON-RPC / MCP +- 単一プロセス、単一 writer +- append-only バイナリログ、snapshot、同期 compaction +- インメモリ履歴・検索・relation index +- UTF-8 のメッセージと構造化 metadata +- CLI による JSONL import/export + +対象外は次のとおり。 + +- 複数 writer、ネットワークサービス、ユーザー認証 +- 保存時暗号化と secure physical erase +- retention、tier による自動移動・削除 +- 自動保存判断、自動要約、自動 consolidation +- 利用頻度による強化・減衰 +- search の cursor pagination + +## 3. アーキテクチャ + +依存方向は次を原則とする。 + +```text +MCP transport / tools -> domain contracts <- storage adapters + ^ + | + system API +``` + +- `src/app`: 引数処理、store/server/CLI のライフサイクル +- `src/mcp`: MCP 境界、入力検証、JSON 応答、tool registry +- `src/domain`: Message、metadata、検索契約 +- `src/storage`: log、snapshot、replay、compaction、import transaction +- `src/sys`: path、lock、file、flush、clock、random、UTF-8 境界 +- `src/cli`: offline import/export +- `third_party/mcpc`: MCP transport と JSON parser + +永続化ロジックは `src/storage`、OS 固有処理は `src/sys` に閉じ込める。read 系 tool は永続化状態を変更しない。 + +## 4. ドメインモデル + +Message は次の不変 identity と、追記レコードで更新される内容を持つ。 + +```json +{ + "message_id": "26-character ULID", + "session_id": "session", + "timestamp": 1720843200000, + "updated_at": 1720843200000, + "revision": 1, + "role": "user | assistant | system", + "content": "UTF-8 text", + "metadata": { + "tool_call_id": "optional", + "tags": ["optional"], + "memory_tier": "short | mid | long", + "memory_kind": "conversation | episode | semantic | procedure | preference | summary", + "importance": 0, + "summary": "optional", + "relations": [{"type": "derived_from", "message_id": "..."}], + "source_message_ids": ["..."] + } +} +``` + +主な上限は content 1 MiB、session/tool-call ID 256 bytes、tag 128 bytes × 32、summary 4096 bytes、relation 32、summary source 64 である。文字列は有効な UTF-8 を要求する。 + +`memory_tier` は現時点では分類ラベルであり、保存場所や寿命を自動変更しない。`summary`、relation、source ID は host が行う consolidation を表現するための契約である。 + +UPDATE は message ID、session、role、作成時刻を維持する。revision による optimistic concurrency を使い、変更のない update はレコードを書かない。 + +## 5. 公開 MCP ツール + +### `write_message` + +session、role、content と任意 metadata を受け取り、ULID と UTC millisecond timestamp を生成する。ログ書込みと durability flush が成功した後だけ成功を返す。 + +### `update_message` + +content または metadata を部分更新する。`expected_revision` が一致しない場合は conflict とする。delta record には変更 field だけを書き、no-op は 0 write / 0 flush とする。 + +### `read_messages` + +次の view を持つ。 + +- `history`: session の時系列ページ。安定 cursor を返す +- `context`: target の前後メッセージと incoming/outgoing relation を返す。relation depth は 0~2 +- `sessions`: session ごとの件数、kind 集計、代表 summary、最終時刻を返す +- `export`: versioned JSONL をページ出力する互換 view + +レスポンスは 8 MiB budget を超えない位置でページを区切る。 + +### `search_messages` + +content、summary、tags を対象に検索する。session、kind、tier、tag、minimum importance で絞り込める。matched fields、score と field 別 score 内訳、任意の前後 context を返す。 + +検索 index は ASCII case fold 後の Unicode codepoint 2/3-gram を用いる。hash candidate は元 codepoint と照合し、完全 substring を優先する。importance は relevance score ではなく tie-break に用いる。検索はアクセス履歴を保存しない。 + +### `delete_message` + +DEL tombstone を durability flush し、対象を直ちに read/search から除外する。物理削除は compaction 後である。任意の session guard を指定できる。 + +### `rebuild_index` + +live message だけで active log を再生成し、snapshot と全インメモリ index を再構築する。dangling relation/source は compaction 前に除去する。同期処理であり、実行中は他の request を処理しない。 + +### `get_system_health` + +live/deleted count、sequence、log/snapshot size、snapshot/recovery 状態、論理 I/O counter、last error を返す。 +store body/metadataと各in-memory indexの確保capacityに基づくmemory estimateも返す。 + +## 6. ストレージと復旧 + +### 6.1 Active log + +各 record は magic、format version、record type、payload length、sequence、payload CRC32 と payload を持つ。PUT、UPDATE delta、DEL、generation marker を扱う。 + +- record length は上限を検証する +- sequence は単調増加を要求する +- complete record の CRC、version、type 異常は起動失敗とする +- incomplete final record だけは最後の正常 offset へ truncate して復旧する +- 不正な complete record を黙って skip しない + +### 6.2 Snapshot + +snapshot は live Message、log generation、replay offset を保持する。一時ファイルへ書き、flush 後に原子的に置換する。 + +起動時は generation が active log と一致し、CRC と offset が妥当な snapshot だけを採用し、その後の log tail を replay する。不正 snapshot は捨て、active log の先頭から再生する。 + +### 6.3 Compaction + +rebuild は live Message を temporary log に書き、flush、replace した後に snapshot を作る。DEL と古い UPDATE/PUT payload を物理的に除去する。log と snapshot は別ファイルのため置換間に crash window があるが、generation 不一致時は log 全 replay へ fallback する設計である。 + +### 6.4 排他 + +`--data-dir` は必須である。`store.lock` を non-blocking exclusive lock し、同じ data directory を複数プロセスが同時に開くことを拒否する。 + +## 7. JSONL import/export + +CLI export は先頭に format manifest を出し、live record と任意の DEL を UTF-8 JSONL として出力する。CLI import は format version、全 field、参照整合性を検証し、`overwrite` または `reject` policy で transaction 的に適用する。MCP サーバー起動中の offline import/export は lock により拒否される。 + +importはJSONLを行単位で読み、JSON stringをUTF-8へ完全decodeしてからfield上限を検証する。 +整数は小数・指数表記を許可せず、timestamp/updated_atは0~INT64_MAX、revisionは +1~INT32_MAX、importanceは0~100とする。1行はcontent上限+4096 bytes、100,000 record、 +decode後合計4 GiBが上限である。file exportはtemporary fileのflush/close成功後だけ原子的に置換する。 + +## 8. I/O 予算 + +成功応答前の durability flush を維持し、sys 境界の logical counter を合否判定に使う。 + +| 操作 | 最大 logical write | 最大 flush | +|---|---:|---:| +| write | header + serialized Message | 1 | +| metadata-only update | header + changed fields | 1 | +| content update | header + content + changed fields | 1 | +| no-op update | 0 | 0 | +| delete | fixed tombstone | 1 | +| read/search/context/export/sessions | 0 | 0 | +| no-op rebuild | 0 | 0 | +| rebuild | live serialized bytes × 2 + bounded headers | log 1 + snapshot 1 | + +Release build で 20 B~1 MiB payload と 10,000 / 50,000 record corpus を測定し、根拠のない 10% 以上の回帰を許容しない。 + +## 9. セキュリティと運用上の境界 + +- stdio 接続済み host は全 Message の読取り、追加、更新、削除、maintenance が可能である +- data at rest は暗号化されず、data directory の OS ACL に依存する +- CRC32 は破損検出用であり、悪意ある改変への認証ではない +- content や metadata は prompt injection を含み得る。取得内容を命令として信頼するかは host 側の責任である +- export は平文バックアップであり、元データと同等に保護する +- secure erase は保証しない。削除後も compaction、backup、filesystem 履歴に残り得る + +## 10. フィードバックの反映状況 + +利用者フィードバックの優先項目に対する設計上の対応は次のとおり。 + +| 要望 | 状況 | 実装 | +|---|---|---| +| バックアップ・export | 部分達成 | JSONL CLI と export view。import 完全性に既知課題あり | +| 保存後の更新 | 達成 | delta update、identity 維持、revision conflict | +| 記憶の種類分け | 達成 | 6 kinds と検索 filter | +| 2段階保存 | 部分達成 | summary/source/relation 契約。自動 consolidation は host 責務 | +| 検索結果の文脈 | 達成 | score 説明、前後 context、relation traversal | +| session 一覧 | 達成 | sessions view、kind 集計、代表 summary | +| metadata 活用 | 達成 | tag/tier/kind/importance の更新・filter | +| 自動保存判断 | 未実装 | host policy の範囲 | +| 利用による強化・減衰 | 未実装 | read は 0 write のため access state を保持しない | + +## 11. 実装・検証状況 + +構造化 metadata、UPDATE、relation index、検索説明、context、sessions、CLI import/export、再起動時の dangling reference 処理まで実装済みである。 + +継続的に再検証する項目は次のとおり。 + +- MCP protocol E2Eと有効snapshot + PUT/DEL tail replay +- snapshot temporary file 各段階の強制終了試験 +- compaction の flush/replace 前後と log/snapshot 間 crash matrix +- importの1 MiB escape round-trip、数値境界、streaming上限 +- live corpus増加時のmemory benchmark(retentionはv1対象外) +- data directory ACLとbackup保護の運用文書 + +具体的な優先順位と完了条件は [Review.md](Review.md) に記載する。 |
