Client timeout + retry can duplicate memcells for identical session/messages payload
メンテナーはふだん 1 日以内に返信
まだ誰も着手していません。
評価
- 難易度
- 5/5
- 見積もり時間
- 1週間以上
- 初心者へのやさしさ
- 35/100
調査の方向性
Start by tracing /api/v1/memory/add and /api/v1/memory/flush, then inspect how the buffer merge path consumes messages and creates rows in the SQLite memcell table. Decide how retries should be identified and handled, including what happens when a key is reused with a different payload. Done means a retry cannot create duplicate memcells or downstream Markdown and search results, and the behavior is covered by tests.
索引モデルが issue の本文から書いたものです。
説明
Summary
When a client times out on /api/v1/memory/add or /api/v1/memory/flush, the server may continue processing in the background. If the client then retries the same session_id with the identical messages payload, EverOS can create duplicate memcell rows with the same message_ids_json but different memcell_id values.
Those duplicate memcells can later propagate into Markdown and search results.
Environment
- EverOS version: 1.0.0
- Runtime: Linux container
- Memorize mode:
chat - Memory root: isolated test memory root
- Sample data: synthetic text only
No real user memory was used.
Why this matters
Clients cannot safely treat timeout as failure. A timed-out request may still generate memcells, Markdown files, cascade updates, and searchable rows. If the client blindly retries the same payload, the memory store can be polluted with duplicate memories.
This is especially risky for agent memory integrations, where callers often retry on HTTP timeout.
Reproduction Outline
Use an isolated memory root and synthetic messages.
- Start EverOS server in
chatmode. - Send
/api/v1/memory/addwith a short client timeout. - Send
/api/v1/memory/flushwith a short client timeout. - Without auditing backend state, retry the same
/addpayload:- same
app_id - same
project_id - same
session_id - same
messages - same timestamps
- same
- Retry
/flush. - Inspect SQLite
memcell. - Wait for background extraction / cascade to finish.
- Inspect Markdown and search results.
Synthetic Payload Shape
Example payload shape:
{
"session_id": "retry_probe_001",
"app_id": "test_app",
"project_id": "retry_audit",
"messages": [
{
"sender_id": "test_user",
"sender_name": "Test User",
"role": "user",
"timestamp": 1780870000000,
"content": "Remember exactly: retry-token-mu equals audit-mu-772."
},
{
"sender_id": "test_assistant",
"sender_name": "Test Assistant",
"role": "assistant",
"timestamp": 1780870000500,
"content": "Acknowledged. I will preserve the exact retry audit token."
}
]
}
Observed Behavior
After retrying the same payload, SQLite contained two memcell rows for the same session.
Both rows had the same message_ids_json, but different memcell_id values.
Example observed shape:
memcell_id: mc_<first>
message_ids_json:
["m_retry_probe_001_1780870000000_000", "m_retry_probe_001_1780870000500_001"]
memcell_id: mc_<second>
message_ids_json:
["m_retry_probe_001_1780870000000_000", "m_retry_probe_001_1780870000500_001"]
After background processing completed:
- Markdown contained repeated references to the same synthetic marker.
- Search returned duplicate episode results for the same synthetic marker.
Expected Behavior
EverOS should provide retry-safe behavior for timed-out clients.
Possible acceptable fixes:
- Support an
idempotency_keyorclient_request_idon/add. - Expose request/session processing status so clients can audit before retrying.
- Prevent duplicate memcell creation for the same
app_id,project_id,session_id,track, andmessage_ids_json. - Document safe retry behavior for
/addand/flush.
Current Code Observation
The input message IDs appear deterministic for the same session_id, timestamp, and message index.
However, memcell_id is minted independently for each boundary result. The memcell table uses memcell_id as primary key and does not appear to enforce uniqueness on:
app_id + project_id + session_id + track + message_ids_json
The buffer merge path deduplicates by message_id, but once messages have been consumed into a memcell and the buffer is cleared, replaying the same payload can create a new memcell.
Suggested Direction
The safest contract would be API-level idempotency:
- Client supplies an
idempotency_key. - EverOS stores key + payload hash + processing status + result.
- Retrying the same key returns the original result or current processing state.
- Same key with different payload returns a conflict error.
A lower-level safety net would be to prevent duplicate memcells for the same scoped message_ids_json, but that alone may not fully solve HTTP retry semantics.
- 主要言語
- Python
- スター
- 13.3k
- フォーク
- 926
- 平均マージ
- 17時間 40分
- マージ済み PR(30日)
- 31
環境構築
このプロジェクトには開発コンテナ、Dockerfile、コントリビューションガイドがありません。まず README を読み、一般的な手順ははじめてのコントリビューションガイドを参照してください。
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
EverMind-AI/EverOS のほかの issue
-
難易度 2/5 半日 初心者へのやさしさ 62/100
EverMind-AI/EverOS#414 ·
メンテナーはふだん 1 日以内に返信
-
[Offer] Free independent recomputation of your published memory benchmarks (assayed-tier upgrade)オープン
難易度 4/5 1〜2日 初心者へのやさしさ 3/100
EverMind-AI/EverOS#504 ·
メンテナーはふだん 1 日以内に返信
-
bug
難易度 3/5 1〜2日 初心者へのやさしさ 45/100
EverMind-AI/EverOS#502 ·
メンテナーはふだん 1 日以内に返信
-
enhancement
難易度 4/5 3〜5日 初心者へのやさしさ 35/100
EverMind-AI/EverOS#501 ·
メンテナーはふだん 1 日以内に返信
-
難易度 3/5 1〜2日 初心者へのやさしさ 55/100
EverMind-AI/EverOS#498 ·
メンテナーはふだん 1 日以内に返信
EverMind-AI/EverOS の issue をすべて見る
似ている issue
-
難易度 1/5 1時間未満 初心者へのやさしさ 82/100
EchoTools/nevr-runtime#651 ·
メンテナーはふだん 1 日以内に返信
-
bug frontend rt sev-3
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
-
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
メンテナーはふだん 2 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 65/100
noontide-co/mainbranch#1211 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
[1.x Bug] run-operation --sql reports success but rolls back writes on transaction-capable adaptersオープンtriage
難易度 2/5 1〜3時間 初心者へのやさしさ 64/100
dbt-labs/dbt#16784 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信