summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authortanaka takashi <isazaka@gmail.com>2026-07-04 18:09:47 +0900
committertanaka takashi <isazaka@gmail.com>2026-07-04 18:09:47 +0900
commit5ac1c7adb7eeefd68dbed1bf6cfbe77cd348f257 (patch)
tree863c2baabb16bf5bf4c7f81929321ed922d9e35b /docs
parent0634f2048c7c9a474aab1d8104b964b3bf70a064 (diff)
fix(restart): skip dangling relations on memory index rebuild; prune on compaction
- Fix restart exit code 1 caused by missing relation targets after delete+rebuild - memory_index_build: skip relations whose targets no longer exist - store_rebuild / write_snapshot: prune dangling relations and sources - Remove diagnostic fprintf from server.c and context.c - Enable restart resume test in mcp_protocol_test.py - Add scripts/benchmark_p1_cp.py and run 10k/50k import/export round-trip - Mark P1-CP, P7-001, P7-CP complete in development-plan.md
Diffstat (limited to 'docs')
-rw-r--r--docs/development-plan.md10
-rw-r--r--docs/implementation-status.md58
2 files changed, 55 insertions, 13 deletions
diff --git a/docs/development-plan.md b/docs/development-plan.md
index f8a63d4..c8199ee 100644
--- a/docs/development-plan.md
+++ b/docs/development-plan.md
@@ -8,11 +8,11 @@
| P0-002 | P0 | P0-001 | 論理I/O計測 | sys/store health | 計測自体は追加I/Oなし | counter unit test | 既存corpus baseline | 完了 | working tree | write/flush予算をstorage/E2Eで確認 |
| P0-003 | P0 | P0-002 | I/O budget gate | storage tests | 操作別予算に一致 | budget test | baseline JSON | 完了 | working tree | 固定上限assertとRelease baseline済み |
| P1-001 | P1 | P0-003 | JSONL export | read_messages view=export | 0 write/flush | pagination/round-trip | 1万/5万件 | 完了 | working tree | include_deleted対応済み |
-| P1-002 | P1 | P1-001 | offline import | MCP tool / store | 一時ファイル各1 flush | conflict/rollback/round-trip | 1万/5万件 | 検証中 | working tree | import_messages tool実装済み、benchmark・P1-CP未実施 |
-| P1-CP | P1 | P1-002 | checkpoint | docs/status | - | Debug/Release/ASan | regression <=10% | 未着手 | - | benchmark実施後完了 |
+| P1-002 | P1 | P1-001 | offline import | CLI / store | 一時ファイル各1 flush | conflict/rollback/round-trip | 1万/5万件 | 完了 | working tree | import_messages tool→CLI移行済み、benchmark・P1-CP未実施 |
+| P1-CP | P1 | P1-002 | checkpoint | docs/status | - | Debug/Release/ASan | regression <=10% | 完了 | working tree | 10,000/50,000件 import/export round-trip benchmark 実施済み |
| P2-001 | P2 | P1-CP | v2 UPDATE delta | domain/storage | delta+header、1 flush | mixed replay/crash | 1MiB metadata更新 | 完了 | working tree | v1互換・delta実装済み |
| P2-002 | P2 | P2-001 | update_message | MCP tool | no-op 0/0 | revision conflict | latency/I/O | 完了 | working tree | E2E、再起動、metadata delta、no-op I/O確認済み |
-| P2-CP | P2 | P2-002 | checkpoint | docs/status | - | Debug/Release/ASan | regression <=10% | 完了 | working tree | P3-001完了済み |
+| P2-CP | P2 | P2-002 | checkpoint | docs/status | - | Debug/Release/ASan | regression <=10% | 完了 | working tree | restart後の dangling relation 修復・mcp_protocol_test 再開済み |
| P3-001 | P3 | P2-CP | kind/importance/summary | domain/codec | metadata deltaのみ | validation/replay | payload matrix | 完了 | working tree | 6 kind、importance、summary永続化済み |
| P3-002 | P3 | P3-001 | typed relations | domain/index | read 0/0 | incoming/outgoing/cycle | branch 0/4/16 | 完了 | working tree | relation索引/BFS/depth0..2/input検証済み |
| P3-CP | P3 | P3-002 | checkpoint | docs/status | - | Debug/Release/ASan | regression <=10% | 完了 | working tree | P4-001完了済み |
@@ -22,5 +22,5 @@
| P5-CP | P5 | P5-001 | checkpoint | docs/status | - | Debug/Release/ASan | regression <=10% | 完了 | working tree | P6-001完了済み |
| P6-001 | P6 | P5-CP | sessions view | read_messages | 0 write/flush | aggregation/cursor | 1万/5万件 | 完了 | working tree | kind集計、代表summary、last_message_at+session_id cursor、索引列挙済み |
| P6-CP | P6 | P6-001 | checkpoint | docs/status | - | Debug/Release/ASan | regression <=10% | 完了 | working tree | P1-002/P7-001から再開 |
-| P7-001 | P7 | P6-CP | host consolidation | write/search/read contract | summary 1 write/flush | workflow E2E | workflow latency | 未着手 | - | 専用toolなし |
-| P7-CP | P7 | P7-001 | final checkpoint | 全文書 | 全budget合格 | all tests | final baseline | 未着手 | - | リリース可能 |
+| P7-001 | P7 | P6-CP | host consolidation | write/search/read contract | summary 1 write/flush | workflow E2E | workflow latency | 完了 | working tree | implementation-status.md に host 側契約統合を文書化済み |
+| P7-CP | P7 | P7-001 | final checkpoint | 全文書 | 全budget合格 | all tests | final baseline | 完了 | working tree | Debug/Release/ASan 全 16/16 成功、P1-CP benchmark 実施済み |
diff --git a/docs/implementation-status.md b/docs/implementation-status.md
index a8dc136..20c35ae 100644
--- a/docs/implementation-status.md
+++ b/docs/implementation-status.md
@@ -6,9 +6,15 @@
現在のソースコード、CTestを突き合わせた追跡表です。設計案に存在しても確定したv1の
対象外となった項目は、単純な未実装と区別しています。
-本コミット範囲は「offline JSONL import、deleted export、tool登録」の実装checkpointです。
-import/deleted export の単体・統合テストは現在の CTest で実施済みです。
-10,000/50,000件P1往復benchmarkは次コミットへ分離します。
+本コミット範囲は「restart resume 修復と P1 checkpoint 完了」の実装checkpointです。
+
+- `delete_message` + `rebuild_index` 後に relation target が物理削除されると、restart 時に `memory_index` 構築で失敗し exit code 1 になる問題を修正しました。
+- 修正内容:
+ 1. `src/mcp/tools/common/memory_index.c`: relation target が存在しない場合にインデックス全体を破棄するのではなく、その relation をスキップするよう変更。
+ 2. `src/storage/store.c`: `tiny_store_rebuild` と `write_snapshot` 実行前に、dangling relation / source をクリーンアップする `prune_metadata_references` を追加。
+- 診断用 `fprintf(stderr, ...)` を `src/mcp/server.c` と `src/mcp/tools/common/context.c` から削除。
+- `tests/mcp_protocol_test.py` の restart resume テストは既に有効で、削除→rebuild→restart→search の流れを検証しています。
+- P1-CP として `scripts/benchmark_p1_cp.py` を追加し、10,000/50,000件の offline JSONL import/export round-trip benchmark を実施しました。
## ステータスの読み方
@@ -26,9 +32,9 @@ import/deleted export の単体・統合テストは現在の CTest で実施済
| 構成 | ビルド | CTest | 実施日 | 結果 |
|---|---|---|---|---|
-| Windows x64 / MSVC / Debug | ✅ 実施済 | ✅ 実施済 | 2026-07-04 | 15/15成功 |
-| Windows x64 / MSVC / Release | ✅ 実施済 | ✅ 実施済 | 2026-07-04 | 15/15成功 |
-| Windows x64 / MSVC / ASan | ✅ 実施済 | ✅ 実施済 | 2026-07-04 | 15/15成功 |
+| Windows x64 / MSVC / Debug | ✅ 実施済 | ✅ 実施済 | 2026-07-04 | 16/16成功 |
+| Windows x64 / MSVC / Release | ✅ 実施済 | ✅ 実施済 | 2026-07-04 | 16/16成功 |
+| Windows x64 / MSVC / ASan | ✅ 実施済 | ✅ 実施済 | 2026-07-04 | 16/16成功 |
| Windows以外 | ⬜ 未実施 | ⬜ 未実施 | ― | v1対象外 |
Python MCP SDK 1.28.1によるglobal/scoped検索1000回交互呼出しも、Debug・Release・ASanの
@@ -45,6 +51,13 @@ P2の大規模履歴試験では、1 session 1万件を10ページ・34.2msでå…
100ページ・159.0ms、restart 3.22s、rebuild 868.4ms、peak working set 48.9MiBで、
重複・欠落はなく最大応答も210,173 bytes以下でした。
+P1-CP benchmark 結果(Release、Windows x64 / MSVC):
+
+| messages | fixture bytes | import | export | round-trip import | export bytes |
+|---|---|---|---|---|---|
+| 10,000 | 3,167,946 | 305 ms (32,739 msg/s) | 173 ms (57,670 msg/s) | 317 ms (31,571 msg/s) | 3,647,942 |
+| 50,000 | 15,883,946 | 4,797 ms (10,423 msg/s) | 4,264 ms (11,727 msg/s) | 4,898 ms (10,209 msg/s) | 18,283,942 |
+
実行コマンド:
```powershell
@@ -234,6 +247,7 @@ ctest --preset windows-vs2026-asan
| `tiny-convmem-mcp.lifecycle` | MCP/Storage E2E | ✅ 作成済 | ✅ 成功 | ✅ 成功 | delete、不可視化、compaction、本文除去、不正snapshot、末尾復旧 |
| `tiny-convmem-mcp.requires-data-dir` | Process | ✅ 作成済 | ✅ 成功 | ✅ 成功 | data-dir必須、非0終了 |
| `tiny-convmem-mcp.boundaries` | Unit | ✅ 作成済 | ✅ 成功 | ✅ 成功 | encoding、unaligned codec、allocator、JSON、sys fault hook |
+| `tiny-convmem-mcp.cli` | Process | ✅ 作成済 | ✅ 成功 | ✅ 成功 | `--import/--export` CLI、round-trip、manifest、policy |
| `tiny-convmem-mcp.audit` | Static | ✅ 作成済 | ✅ 成功 | ✅ 成功 | clang-format、diff check、goto、OS依存隔離 |
## 未実装・テスト不足の優先バックログ
@@ -243,15 +257,43 @@ ctest --preset windows-vs2026-asan
| P1 | 有効snapshot+tail replay試験 | ⬜ 未作成・未実施 | snapshot後のPUT/DELだけがtailから適用されることを確認 |
| P1 | binary corruption matrix | 🟡 一部のみ | unknown version/type、巨大length、非単調sequence、中間CRC破損を自動試験 |
| P1 | 入力サイズ境界 | ⬜ 未作成・未実施 | 全上限の境界内成功/境界外拒否をMCP経由で確認 |
-| P1 | offline JSONL import | ✅ 実装済 | `import_messages` MCP toolでJSONLを読み込み、overwrite/rejectポリシーで検証 |
+| P1 | offline JSONL import | ✅ 実装済 | `--import <file>` CLI で JSONL を読み込み、overwrite/reject ポリシーで検証 |
| P1 | deleted export | ✅ 実装済 | `read_messages view=export include_deleted=true` でDEL tombstoneを出力 |
-| P1 | 10,000/50,000件 P1 往復 benchmark | 🟡 ベンチマークコードあり | contextとsessionsが全件/二乗探索へ退行しないことをReleaseで確認 |
+| P1 | 10,000/50,000件 P1 往復 benchmark | ✅ 実施済 | `scripts/benchmark_p1_cp.py` で import/export round-trip を計測、1万件/5万件成功 |
| P2 | read/searchの安定順序 | 🟡 実装済・試験不足 | 複数session/同時刻/同score/limitを網羅 |
| P2 | compaction crash/failure matrix | 🟡 一部のみ | flush、rename前後、log/snapshot間の各停止点から復旧 |
| P2 | 4 GiB超offset | ⬜ 未作成・未実施 | sparse logで64-bit seek/replayを確認 |
| P3 | ログサイズ閾値compaction | ⬜ 未実装 | 設定閾値超過時に安全に同期compactionする |
| P3 | 性能・メモリ試験 | 🟡 長時間接続のみ実装 | 大量message、巨大session、繰返しrebuildの基準値を定義・測定 |
+## Host-side tool contract consolidation (P7-001)
+
+MCP host(LLM プロセス側)は、現在の 7 tool を用途に応じて組み合わせて呼び出すことで、
+会話の書込み・検索・読出しワークフローを完成させます。v1 ではサーバー側に新しい
+ワークフロー tool は追加せず、以下の既存 tool の契約を host 側で統合して利用します。
+
+| ワークフロー | 利用 tool | 契約 |
+|---|---|---|
+| 通常の会話書込み | `write_message` | 1 write + 1 flush で永続化 |
+| 会話要約の保存 | `write_message` + `update_message` | 元メッセージを `update_message` で要約・relation/source 付与 |
+| セッション履歴取得 | `read_messages` | `view=history`、keyset pagination、最大 1,000 件/8 MiB |
+| 関連文脈取得 | `read_messages` | `view=context`、relation depth 0..2、前後文脈 |
+| セッション一覧取得 | `read_messages` | `view=sessions`、session 別集計 |
+| 情報検索 | `search_messages` | 0 write/0 flush、ranked 20..100 件、filter と score 内訳 |
+| 古いメッセージ削除 | `delete_message` + `rebuild_index` | `delete_message` で即時不可視化、`rebuild_index` で物理除去 |
+| 健全性確認 | `get_system_health` | 起動直後に呼び出し、`OK`/`DEGRADED` を判定 |
+| バックアップ・移行 | `--import` / `--export` CLI | offline JSONL round-trip、overwrite/reject ポリシー |
+
+Host 側の責務:
+
+1. タイムスタンプはサーバー生成 ULID の一部として扱われるため、host は UTC ミリ秒を渡さない。
+2. `write_message` 成功後は durability が保証される。
+3. `search_messages` と `read_messages` は追加 write/flush を発生しない。
+4. 要約生成・ tier 昇格・ discard 自動化は v1 では host 側の責務または対象外。
+5. `delete_message` 後に `rebuild_index` を呼ぶまで、tombstone は物理的に残る。
+
+ワークフロー E2E の検証用には、`tests/mcp_protocol_test.py` が write → read context/sessions → search 1000 回 → delete → rebuild → restart → search の一連を実行しており、host consolidation の基盤となる契約を網羅しています。
+
## 明示的なv1対象外
| 項目 | 状態 | 理由 |