[Bug]: scroll eviction drops a user turn that sits inside a tool-heavy span — the live window loses the request while history.db keeps it
Environment
QwenPaw 2.2.x, default strategy=scroll (context_manager_backend = "light").
Symptom
After a long tool-heavy task (repeated file reads, diffs, log dumps), the largest stretch of tool output was evicted from the live window as a whole, and the two user turns bracketing that stretch disappeared with it. Neither the user nor the model could see them — it reads as "history lost".
The data is neither missing nor corrupt:
PRAGMA integrity_check= ok;content/blocks/metadata/dedup_keyintact- logs show
scroll: compact timing outcome=at_or_below_triggerthroughout — compaction never triggered - the rows are still in
history.dband remain recallable
Root cause
scroll/manager.py::_repair_dangling_user_boundary only guarantees a turn boundary (if middle ends on a user msg and tail starts with the reply, the reply is pulled back into middle). It cannot protect a user instruction that sits in the middle of a long tool chain — that instruction is simply part of the evictable middle and gets evicted together with it.
Suggested fix
- Pin real
userrows during eviction (at minimum keep the user requests of an evicted span visible in the live window or in the index). - Add a regression test: after eviction, the user request(s) of the evicted span must still be visible in the live window or in its eviction-index entry.
Related: #7733 (long-term design), #5848 (merged — labels un-headlined spans in the eviction index; covers the index layer only, not protection of user rows).
Source: agentscope-ai/QwenPaw