Commit 64533a2
mt:: + server — wipe tier state on whole-seq seq_rm (agent task lifecycle)
Setup for the agent army: long-running workers reuse a slot for many
unrelated tasks throughout the day. Without explicit per-task cleanup,
two failure modes accumulate:
1. Memory leak: warm slots from prior tasks stay occupied (the existing
inline comment at the seq_rm site even acknowledged this — "we only
free a warm slot when the warm copy itself becomes obsolete, e.g.
via clear()" — but clear() only fires on whole-cache wipe, never per
slot).
2. Worse: stale semantic fingerprints from prior tasks persist in the
SemanticIndex. A new task's query embedding can cosine-match against
a prior task's chunk and trigger restoration of that chunk's K/V
from warm/cold — attention then reads garbage, model confabulates.
This silent-failure mode would be hard to debug in production.
Fix in two pieces:
- mt::seq_rm: when called with the whole-seq sentinel (p0<0 or p1<0,
i.e. "task done, wipe the slot"), clear warm_pos_to_slot_,
evicted_to_warm_, warm_insertion_order_, cold_positions_,
warm_recur_buf_, semantic_, refill warm_free_slots_, reset
pressure_announced_. Logs the wipe count for visibility. n_seq_max=1
today so the wipe is global; will need per-seq scoping when mt::
grows multi-seq support.
- server-context.cpp: self-healing kv_evict_through cursor in the
proactive eviction trigger. When the cursor exceeds n_tokens, the
slot was truncated (new task with no shared prefix wipes the cache
via memory_seq_rm); reset to 0. Avoids having to instrument every
memory_seq_rm site in the server.
Smoke (Qwen3.6-35B-A3B-Q5, --kv-tier-semantic-index bge-small.gguf,
--ctx-size 8192). Two-task isolation test with distinct needles:
TASK A (drop NEEDLE_A, force eviction):
backup [0,409) -> fingerprint, backup [409,818) -> fingerprint
restore_semantic: 1 hint, 409 positions restored
IMPLICIT WIPE (task B's prompt has no shared prefix):
mt::seq_rm: whole-seq wipe for seq 0 — freed 818 warm slots,
dropped 0 cold entries, cleared 2 semantic fingerprints
TASK B (drop NEEDLE_B, ask for code):
backup [0,409) -> fingerprint (FRESH content), backup [409,818)
restore_semantic: 1 hint, 409 positions restored
Model answer: "MERIDIAN-4920-SILVERFROST-PEREGRINE" (NEEDLE_B)
NEEDLE_A nowhere in answer
Without the fix, task B either 500'd ("Context size has been exceeded"
because the stale cursor blocked eviction) or — worse — recalled
NEEDLE_A from a stale fingerprint match.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>1 parent 3a29bc6 commit 64533a2
2 files changed
Lines changed: 54 additions & 4 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
936 | 936 | | |
937 | 937 | | |
938 | 938 | | |
939 | | - | |
940 | | - | |
941 | | - | |
942 | | - | |
| 939 | + | |
943 | 940 | | |
944 | 941 | | |
945 | 942 | | |
946 | 943 | | |
947 | 944 | | |
| 945 | + | |
| 946 | + | |
| 947 | + | |
| 948 | + | |
| 949 | + | |
| 950 | + | |
| 951 | + | |
| 952 | + | |
| 953 | + | |
| 954 | + | |
| 955 | + | |
| 956 | + | |
| 957 | + | |
| 958 | + | |
| 959 | + | |
| 960 | + | |
| 961 | + | |
| 962 | + | |
| 963 | + | |
| 964 | + | |
| 965 | + | |
| 966 | + | |
| 967 | + | |
| 968 | + | |
| 969 | + | |
| 970 | + | |
| 971 | + | |
| 972 | + | |
| 973 | + | |
| 974 | + | |
| 975 | + | |
| 976 | + | |
| 977 | + | |
| 978 | + | |
| 979 | + | |
| 980 | + | |
| 981 | + | |
| 982 | + | |
| 983 | + | |
| 984 | + | |
| 985 | + | |
| 986 | + | |
948 | 987 | | |
949 | 988 | | |
950 | 989 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1490 | 1490 | | |
1491 | 1491 | | |
1492 | 1492 | | |
| 1493 | + | |
| 1494 | + | |
| 1495 | + | |
| 1496 | + | |
| 1497 | + | |
| 1498 | + | |
| 1499 | + | |
| 1500 | + | |
| 1501 | + | |
| 1502 | + | |
| 1503 | + | |
1493 | 1504 | | |
1494 | 1505 | | |
1495 | 1506 | | |
| |||
0 commit comments