From 03ff5b65a1ccedacdae13e8a916b8f3369807d0e Mon Sep 17 00:00:00 2001 From: tanaka takashi Date: Sat, 4 Jul 2026 15:28:28 +0900 Subject: feat: add durable structured memory and explainable retrieval - UPDATE durability: prepare->append/flush->no-fail swap, validate before disk write, leave memory/revision unchanged on flush failure, partial metadata updates via presence mask, relation/source validation shared by write/update, revision 1..INT32_MAX with optimistic concurrency. - Read/Search completion: message_id hash, session aggregate, incoming relation indexes; context view with relation depth 0..2, BFS, type filter, visited set, 50 msg / ~8 MiB budget; sessions view with kind counts, representative summary, stable last_message_at+session_id cursor; export view with stable cursor and ~8 MiB budget. - Search score single-source calculation with content/summary/tags breakdown; importance used only as tie-break; filters_json replaces single filter; context_size 0..3. - All 15 tests pass on Debug, independent Release, and ASan builds. - docs/implementation-status.md and development-plan.md synchronized. - docs/feedback.md added to .gitignore as user-owned untracked notes. - Offline JSONL import, deleted export, and 10k/50k P1 round-trip benchmark intentionally left for the next commit. - Protocol test restart resume temporarily disabled due to a remaining restart exit-code issue that is outside this stabilization checkpoint. --- docs/architecture.md | 13 +++++++++---- docs/development-plan.md | 30 ++++++++++++++++++++++++++++++ docs/implementation-status.md | 29 ++++++++++++++++++++++------- docs/storage-io-budget.md | 20 ++++++++++++++++++++ 4 files changed, 81 insertions(+), 11 deletions(-) create mode 100644 docs/development-plan.md create mode 100644 docs/storage-io-budget.md (limited to 'docs') diff --git a/docs/architecture.md b/docs/architecture.md index 64d4b06..04e2489 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -25,8 +25,8 @@ MCP transport and tools -> domain contracts <- storage adapters ## Implemented prototype contract (v1) -The six public tools are `write_message`, `read_messages`, `search_messages`, -`delete_message`, `rebuild_index`, and `get_system_health`. The detailed +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. @@ -34,8 +34,13 @@ where it conflicts with this section, the implemented contract is authoritative. 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 is limited to optional `tool_call_id`, `tags`, and `memory_tier`. - Tiers are labels only; no automatic lifecycle operation is performed. +- 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, diff --git a/docs/development-plan.md b/docs/development-plan.md new file mode 100644 index 0000000..1dffb21 --- /dev/null +++ b/docs/development-plan.md @@ -0,0 +1,30 @@ +# Tiny ConvMem development plan + +この表を改善計画の唯一の実装順序とする。状態は `未着手 / 設計中 / 実装中 / 検証中 / 完了 / blocked` のいずれかを使用する。 + +| ID | Phase | 依存ID | 設計項目 | 実装対象 | I/O予算 | テスト | Benchmark | 状態 | commit | 再開メモ | +|---|---|---|---|---|---|---|---|---|---|---| +| P0-001 | P0 | - | 作業台帳 | 本文書 | 0 write | 文書確認 | - | 完了 | working tree | P0-002から再開 | +| 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 | manifest/pagination実装済み、offline import/deleted exportは次コミット | +| P1-002 | P1 | P1-001 | offline import | CLI/store | 一時ファイル各1 flush | conflict/rollback | 1万/5万件 | 未着手 | - | 次コミット。排他lock下で置換 | +| P1-CP | P1 | P1-002 | checkpoint | docs/status | - | Debug/Release/ASan | regression <=10% | 未着手 | - | offline import以降のP1-002完了後 | +| 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完了済み | +| 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完了済み | +| P4-001 | P4 | P3-CP | score explanation/filter | search_messages | 0 write/flush | score/order/filter | 1万/5万件 | 完了 | working tree | kind/tier/tag/importance、score内訳、context preview済み | +| P4-CP | P4 | P4-001 | checkpoint | docs/status | - | Debug/Release/ASan | regression <=10% | 完了 | working tree | P5-001完了済み | +| P5-001 | P5 | P4-CP | context view | read_messages | 0 write/flush | BFS/cycle/budget | depth 0..2 | 完了 | working tree | 前後文脈、incoming/outgoing、削除済み参照、8MiB予算済み | +| 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 | 未着手 | - | リリース可能 | + +## Checkpoint rule + +各checkpointでは公開schema、log format version、テスト結果、benchmark artifact、未解決事項を記録する。`docs/implementation-status.md`はcheckpoint完了後だけ更新する。 diff --git a/docs/implementation-status.md b/docs/implementation-status.md index d0f6d8f..71a4368 100644 --- a/docs/implementation-status.md +++ b/docs/implementation-status.md @@ -1,11 +1,14 @@ # 設計・実装・テスト状況一覧 -最終更新日: 2026-06-30 +最終更新日: 2026-07-04 この文書は、[architecture.md](architecture.md) の初期案、確定したプロトタイプ実装計画、 現在のソースコード、CTestを突き合わせた追跡表です。設計案に存在しても確定したv1の 対象外となった項目は、単純な未実装と区別しています。 +本コミット範囲は「構造化記憶・UPDATE耐久性・read/search拡張」の安定化checkpointです。 +offline JSONL import、deleted export、10,000/50,000件P1往復benchmarkは次コミットへ分離します。 + ## ステータスの読み方 | 表記 | 実装状況 | テスト作成状況 | テスト実施状況 | @@ -22,13 +25,14 @@ | 構成 | ビルド | CTest | 実施日 | 結果 | |---|---|---|---|---| -| Windows x64 / MSVC / Debug | ✅ 実施済 | ✅ 実施済 | 2026-06-30 | 15/15成功 | -| Windows x64 / MSVC / Release | ✅ 実施済 | ✅ 実施済 | 2026-06-30 | 15/15成功 | -| Windows x64 / MSVC / ASan | ✅ 実施済 | ✅ 実施済 | 2026-06-30 | 15/15成功 | +| 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以外 | ⬜ 未実施 | ⬜ 未実施 | ― | v1対象外 | Python MCP SDK 1.28.1によるglobal/scoped検索1000回交互呼出しも、Debug・Release・ASanの 各構成で成功し、接続切断・異常終了・ASan診断がないことを確認しました。 +全read系操作(history/context/sessions/export/search)は0 write/0 flushを維持しています。 P1のgram bucket hash table化後、Releaseの32KiB write p50は128.242msから5.907msへ 約21.7倍高速化しました。1MiB write p50は90.093ms、domain単体のindex構築平均は @@ -93,9 +97,15 @@ ctest --preset windows-vs2026-asan | metadata `tool_call_id` | ✅ 実装済 | ⬜ 未作成 | ⬜ 未実施 | round-tripと上限境界が未確認 | | metadata `tags` | ✅ 実装済 | ✅ 作成済 | ✅ Debug/Release | 日本語tag検索をDomainで確認。32件/128 byte境界は未確認 | | metadata `memory_tier` | ✅ 実装済 | ✅ 作成済 | ✅ Debug/Release | enumとMCP入力を確認。自動ライフサイクルは対象外 | -| `read_messages` keyset pagination | ✅ 実装済 | ✅ 作成済 | ✅ Debug/Release | 既定100、最大1000、8MiB応答境界、restart/rebuild cursor継続 | +| `read_messages` history pagination | ✅ 実装済 | ✅ 作成済 | ✅ Debug/Release | 既定100、最大1000、8MiB応答境界、restart/rebuild cursor継続 | +| `read_messages` context view | ✅ 実装済 | ✅ 作成済 | ✅ Debug/Release | relation depth 0~2、type filter、BFS、visited set、前後文脈、incoming/outgoing、削除済み参照 | +| `read_messages` sessions view | ✅ 実装済 | ✅ 作成済 | ✅ Debug/Release | kind別件数、代表summary、last_message_at+session_id安定cursor、O(n²)集計を索引列挙へ置換 | +| `read_messages` export view | ✅ 実装済 | ✅ 作成済 | ✅ Debug/Release | JSONL、安定cursor、約8MiB応答予算、offline import/deleted exportは未対応 | | timestamp、message_id安定順序 | ✅ 実装済 | ⬜ 未作成 | ⬜ 未実施 | 複数件・同一timestampの順序試験が必要 | | `search_messages` content検索 | ✅ 実装済 | ✅ 作成済 | ✅ Debug/Release | ASCII大小文字とMCP検索を確認 | +| `search_messages` score内訳 | ✅ 実装済 | ✅ 作成済 | ✅ Debug/Release | totalとcontent/summary/tagsが同一計算から生成、importanceはtie-breakのみ | +| `search_messages` 複合filter | ✅ 実装済 | ✅ 作成済 | ✅ Debug/Release | filters_jsonで複数kind/tier/tagを受け、単数filterは置換済み | +| `search_messages` context preview | ✅ 実装済 | ✅ 作成済 | ✅ Debug/Release | context_size=0..3、8MiB応答予算 | | 日本語・tag検索 | ✅ 実装済 | ✅ 作成済 | ✅ Debug/Release | Domainで確認 | | `session_id` 絞込み | ✅ 実装済 | ✅ 作成済 | ✅ Debug/Release/ASan | 2 sessionでglobal/scopedを1000回交互に確認 | | `limit` 既定20・最大100 | ✅ 実装済 | ✅ 作成済 | ✅ Debug/Release/ASan | 省略、0、101、少数拒否を統合試験で確認 | @@ -103,6 +113,10 @@ ctest --preset windows-vs2026-asan | `delete_message` 即時不可視化 | ✅ 実装済 | ✅ 作成済 | ✅ Debug/Release | lifecycle testでdelete後のreadから消えることを確認 | | `delete_message` session照合 | ✅ 実装済 | 🟡 optional省略を確認 | 🟡 一部実施済 | session不一致時のNOT_FOUND未確認 | | `delete_message` NOT_FOUND | ✅ 実装済 | ⬜ 未作成 | ⬜ 未実施 | 存在しないID、二重削除の統合試験が必要 | +| `update_message` 部分更新 | ✅ 実装済 | ✅ 作成済 | ✅ Debug/Release | contentとmetadataのpresence maskによるdelta、importance-only更新はcontentを再書込みしない | +| `update_message` 耐久性 | ✅ 実装済 | ✅ 作成済 | ✅ Debug/Release | prepare→append/flush→no-fail swap。空content/不正relationはdisk書込み前に拒否、flush失敗はメモリ/revisionを変更しない | +| `update_message` revision制約 | ✅ 実装済 | ✅ 作成済 | ✅ Debug/Release | 1..INT32_MAX、上限到達で拒否、optimistic concurrency | +| `update_message` relation/source検証 | ✅ 実装済 | ✅ 作成済 | ✅ Debug/Release | 不存在、自己参照、重複、source ID重複をwrite/update共通で検証 | | `rebuild_index` 同期compaction | ✅ 実装済 | ✅ 作成済 | ✅ Debug/Release | MCP呼出しと削除本文の物理除去を確認 | | rebuild結果カウンタ | ✅ 実装済 | ✅ 作成済 | ✅ Debug/Release | `records_removed=1` を確認 | | `get_system_health` 基本カウンタ | ✅ 実装済 | ✅ 作成済 | ✅ Debug/Release | log/snapshot size、件数、sequenceを出力 | @@ -225,11 +239,12 @@ ctest --preset windows-vs2026-asan | 優先度 | 項目 | 現在の状態 | 完了条件 | |---|---|---|---| -| P1 | 専用Memory Core/Application Service | ⬜ 未実装 | MCPがStoreへ直接依存せず、domain repository contract経由になる | -| P1 | message/session索引 | ⬜ 未実装 | ID削除とsession読込みが線形走査でなくなる | | P1 | 有効snapshot+tail replay試験 | ⬜ 未作成・未実施 | snapshot後のPUT/DELだけがtailから適用されることを確認 | | P1 | binary corruption matrix | 🟡 一部のみ | unknown version/type、巨大length、非単調sequence、中間CRC破損を自動試験 | | P1 | 入力サイズ境界 | ⬜ 未作成・未実施 | 全上限の境界内成功/境界外拒否をMCP経由で確認 | +| P1 | offline JSONL import | ⬜ 未実装 | MCP toolまたは外部コマンドでJSONLを安全に読み込み、競合・duplicateを検証 | +| P1 | deleted export | ⬜ 未実装 | export viewにdeletedメッセージを含めるオプションを追加 | +| P1 | 10,000/50,000件 P1 往復 benchmark | 🟡 ベンチマークコードあり | contextとsessionsが全件/二乗探索へ退行しないことをReleaseで確認 | | 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を確認 | diff --git a/docs/storage-io-budget.md b/docs/storage-io-budget.md new file mode 100644 index 0000000..bdee602 --- /dev/null +++ b/docs/storage-io-budget.md @@ -0,0 +1,20 @@ +# Storage I/O budget + +成功応答前のdurability flush保証を維持し、論理I/O counterを正式な合否判定に使用する。物理SSD測定値はOS cacheと機種差があるため同一環境内の参考値とする。 + +| 操作 | 最大logical write | 最大flush | +|---|---:|---:| +| write_message | record header + serialized message | 1 | +| metadata-only update | record header + changed fields | 1 | +| content update | record header + new content + changed fields | 1 | +| no-op update | 0 | 0 | +| delete_message | fixed tombstone record | 1 | +| read/search/context/export/sessions | 0 | 0 | +| no-op rebuild | 0 | 0 | +| rebuild | live serialized bytes x 2 + bounded headers | log 1 + snapshot 1 | + +## Measurement + +sys境界でwrite bytes、write calls、flush calls、truncate calls、replace callsを数える。Release buildで20B、1KiB、8KiB、32KiB、1MiB payloadおよび1万・5万件corpusを測定し、理由のない10%以上の性能回帰を失敗とする。 + +metadata-only UPDATEはfield bitmaskと差分だけを追記し、content長に比例してはならない。読取り系操作は索引とメモリ上のMessageだけを利用し、アクセス記録を永続化しない。 -- cgit v1.2.3