docs(openclaw): document issue 25 duplicate porridge logging & update triage filter

This commit is contained in:
Moritz Graf
2026-10-12 12:09:57 +02:00
parent 3b190988be
commit 4831147087
3 changed files with 37 additions and 3 deletions
+34
View File
@@ -799,3 +799,37 @@ This document captures fixed issues, operational quirks, and incident root-cause
- Always register cron jobs with `--declaration-key` and check existing jobs via JSON rather than table text grep.
- Document all declarative setup scripts in `AGENTS.md` under `Register / Sync Automations`.
- Ensure all data directories (`daily`, `sleep`, `activities`) are safely created in `GarminMirrorWriter`.
### Issue 25: Self-Quoting Duplicate Meal Logging & Turn Bleed on High-Context Session (Topic 21)
- **Date**: 2026-10-12
- **Severity**: Medium (Morning porridge was logged twice on 2026-10-12, inflating daily intake to 1,906 kcal instead of 1,611 kcal; redundant pudding correction was appended to 2026-10-11)
- **Symptom**:
Moritz noticed on the personal health dashboard (`moritz.html`) that his morning porridge had been recorded twice.
- **Root Cause Isolated via Rapid Triage**:
1. **Extreme Context Bloat**: Session `aff9fd77` in Topic 21 had accumulated **58,856 tokens** across 103 events due to heavy tool results and previous turns.
2. **External Tool Attention Disorientation**:
- At 08:41 (SEQ 32–37), the morning porridge was properly logged in 4 individual items (`01M4QDGVY...` to `01M4QDH51...`, ~295 kcal total).
- At 11:35 (SEQ 39), Moritz sent an audio message reporting 1.5 Brezen mit Butter, Weißwürste, and Händlmaier sweet mustard.
- The assistant performed an external Perplexity web search for mustard calories, which returned ~16 kB of text.
- Upon receiving the search result at SEQ 49, `z-ai/glm-5.3-flash` suffered severe attention disorientation: seeing `replyToId: 21` (standard Telegram forum topic metadata) and earlier messages in context, it hallucinated that earlier completed turns were unhandled requests.
3. **Self-Quoting Duplicate Execution**:
- In SEQ 51, the model literally copied its own earlier assistant confirmation text from SEQ 37 (`✅ *Morgenporridge (60 g Mischung · 60 ml Hafermilch · 120 ml Wasser · 50 g Kiwi)* geloggt`) and executed `datastore.py add` to log a duplicate 295 kcal composite portion (`01M4QQH2KJ85TB5N2MBM230ZYN`).
- In SEQ 53, it did the same for yesterday's pudding correction (`01M4QQHMG8S30B43241B10ND3J`, +260 kcal).
- **Resolution**:
1. **Deleted Duplicate Events via Datastore CLI**:
- Deleted duplicate porridge event `01M4QQH2KJ85TB5N2MBM230ZYN` (295 kcal) and duplicate pudding event `01M4QQHMG8S30B43241B10ND3J` (260 kcal) via `datastore.py delete`.
- Re-rendered all views and published updated dashboards (`render_views.py` & `update_moritz_website.py`). Today's total restored to exact **1.611 kcal** (**75,1 g Protein**).
2. **Notified Telegram Topic 21**:
- Sent confirmation message (Message ID `2700`) to Topic 21 detailing the correction and showing the cleaned-up macros.
3. **Hardened `knowledge-wiki/agents/koch.md`**:
- Added strict rule: *„KEINE DUPLIKATE ODER SELBST-ZITATE LOGGEN“*. Explicitly forbidden from parsing previous assistant confirmation messages as intake items and forbidden from re-logging earlier completed meals.
4. **Session Reset**:
- Safely deleted and archived the bloated 58k-token session via `openclaw sessions delete`.
5. **Triage Script Optimization**:
- Updated `openclaw-triage.py` to automatically exclude background `:heartbeat` sessions when querying by topic ID.
- **How to Avoid Recurrence**:
- System prompts for transactional logging agents must explicitly forbid treating assistant confirmation messages as intake events.
- Agents must enforce strict focus on the very last user message at the tail of the transcript.
- Reset sessions periodically when context grows beyond 30k tokens for simple transactional logging tasks.
+2 -2
View File
@@ -49,12 +49,12 @@ def triage_agent_session(agent, topic_id=None, limit=10, db_root="/home/node/.op
if topic_id:
target_pattern = f"%topic:{topic_id}%"
cur.execute(
"SELECT session_key, current_session_id, status, updated_at, entry_json FROM session_nodes WHERE session_key LIKE ? ORDER BY updated_at DESC LIMIT 1",
"SELECT session_key, current_session_id, status, updated_at, entry_json FROM session_nodes WHERE session_key LIKE ? AND session_key NOT LIKE '%:heartbeat' ORDER BY updated_at DESC LIMIT 1",
(target_pattern,)
)
else:
cur.execute(
"SELECT session_key, current_session_id, status, updated_at, entry_json FROM session_nodes ORDER BY updated_at DESC LIMIT 1"
"SELECT session_key, current_session_id, status, updated_at, entry_json FROM session_nodes WHERE session_key NOT LIKE '%:heartbeat' ORDER BY updated_at DESC LIMIT 1"
)
row = cur.fetchone()