From a5f3447ceab70d9b69a48318595b2fe75833ba64 Mon Sep 17 00:00:00 2001 From: Osher-Elhadad Date: Mon, 10 Aug 2026 17:09:07 +0000 Subject: [PATCH] refactor(compact): derive the cache boundary from the shared tracker /compact fell through to apply's legacy store-backed prevLen, which the chat path had already moved off. So this endpoint kept two properties the chat path had shed: concurrent turns of one session race on a read-then-deferred-write, and the boundary lives in a store key (cg:len:) competing for the pin budget rather than in memory. The motivation is measurement, not a live cache regression -- the chat path was already on the tracker. /compact is the offline replay/eval endpoint, so a boundary derived differently from production means eval measures a different component than the one that ships. Same class of divergence as the window this handler used to hard-code as unknown a few lines above, and unnoticed for the same reason: both are silent. Deliberately NOT claiming to fix the pin-budget fail-open in #47. I could not construct a churn pattern that actually evicts cg:len: -- it survived 40 frozen decisions from distinct sessions plus 40 ordinary puts at MaxEntries 20 -- and I am not going to assert a fix for a failure I cannot reproduce. #47 stays open for the eviction question; this change removes the /compact path's exposure to it by keeping the boundary out of the store entirely, which is a consequence rather than the point. No test: the two paths are behaviourally identical on the boundary they derive, so a test asserting turn-to-turn behaviour passes either way -- I wrote one, watched it pass with the tracker removed, and deleted it rather than keep a test that proves nothing. Signed-off-by: Osher-Elhadad --- proxy/proxy.go | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/proxy/proxy.go b/proxy/proxy.go index dfbe301f..1f48a722 100644 --- a/proxy/proxy.go +++ b/proxy/proxy.go @@ -277,12 +277,28 @@ func (h *Handler) compact(w http.ResponseWriter, r *http.Request) { window = w } } - out, _ := apply.BodyFull( - r.Context(), pipe, h.store, provider, body, - r.Header.Get("x-context-guru-session"), - strings.EqualFold(r.Header.Get("x-context-guru-bypass"), "true"), - models, window, cacheMode, - ) + // Use the SAME boundary tracker as the chat path. /compact used to fall through to + // apply's legacy store-backed prevLen, which the chat path had already moved off, so this + // endpoint kept two properties the chat path had shed: concurrent turns of one session + // race on a read-then-deferred-write, and the boundary lives in a store key (`cg:len:`) + // that competes for the pin budget instead of in memory. + // + // The motivation is measurement rather than a live cache regression: /compact is the + // offline replay/eval endpoint, so a boundary derived differently from production means + // eval measures a different component than the one that ships. That is the same class of + // divergence as the window this handler used to hard-code as unknown, a few lines above — + // and it went unnoticed for the same reason, because both are silent. + res := apply.BodyOpts(r.Context(), pipe, h.store, apply.Opts{ + Provider: provider, + Body: body, + Session: r.Header.Get("x-context-guru-session"), + Bypass: strings.EqualFold(r.Header.Get("x-context-guru-bypass"), "true"), + Models: models, + Window: window, + CacheMode: cacheMode, + Tracker: h.tracker, + }) + out := res.Body w.Header().Set("Content-Type", "application/json") w.Write(out) }