fix(hygiene): keep a carried trim through interrupted and busy boundaries; review-wave-1 fixes and the findings reports - #80
Merged
Conversation
…ries; lifetime from the last cache writer From the 2026-09-28 review reports (docs/findings), verified against the code and Pi 0.87.1 before changing anything: - turn_end dropped `applied` at its top and restored it only on a contested boundary. Pi persists an aborted/failed response with a fresh timestamp, so after such a turn the next request looked warm, went out untrimmed and rewrote the prefix the interrupted request had just cached (claude B1, deepseek P1-2, muse P0-2). `applied` now lives until a boundary commits it, unchangedSince fails, the session changes or contextHygieneEnabled is turned off. - The cold check read the cache lifetime from the last response only; a fully cached or interrupted response after a 1h write made the prefix look 5 minutes old (claude B2). cachedPrefix() dates the entry by the last response and takes the lifetime from the last response that wrote cache, the host-cache-ledger rule. - canAutoTrim requires smart_context reachable (toolExposure.reachable "history"), as artifact offload does; ARCHITECTURE said so but nothing enforced it (deepseek P1-9, muse P0-5). Readiness names the inactive state. - A queued change meeting an incomplete turn now leaves the "not applied" note (glm B2); committed rewinds reach the ledger as "rewind" (glm B1). - noteForeignCompaction takes an explicit source instead of matching the notice text (claude B4); the before_switch/before_fork ledger resets were redundant with session_start (claude B5); markedAt was write-only. - Comments: break-even N* counts the trimmed request (claude B7); the veto derivation states why the miss really costs missCost - w*X (deepseek P1-3 and muse P0-3 are wrong: the warm path still reads X at r). - Bench: price a held trim (trimTokens) beside plan trim (claude P1). - package.json files excludes docs/findings (claude C2). Tests: aborted/error turns append the interrupted response before turn_end; busy boundary keeps the carried trim; cleanup off forgets it; 1h lifetime survives a fully cached response; rewind attribution; incomplete-turn note.
Owner
Author
|
Receipts (local,
|
alpertarhan
marked this pull request as ready for review
September 28, 2026 10:42
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Review wave 1: verified findings on the #76–#79 code, plus the findings reports
Four external reviews landed under
docs/findings/(first commit). Every claim acted on here was re-verified against the code and Pi 0.87.1 first; three claims were found wrong and left alone (noted below).Fixed (second commit)
turn_endnulledappliedat its top and restored it only on a contested boundary. Pi persists an aborted/failed response with a fresh timestamp (agent-session.js:333), so after such a turn the next request looked warm, went out untrimmed and rewrote the prefix the interrupted request had just cached.appliednow lives until a boundary commits it,unchangedSincefails, the session changes, orcontextHygieneEnabledis turned off. Tests append the interrupted response beforeturn_end(aborted and error), cover a busy boundary (canAutoTrimfalse) and cleanup turned off.cacheWrite = 0) or interrupted response after a 1h write made the prefix look 5 minutes old.cachedPrefix()dates the entry by the last response and takes the lifetime from the last response that wrote cache — the host-cache-ledger rule.smart_context(deepseek P1-9, muse P0-5):canAutoTrimcheckstoolExposure.reachable("history")like artifact offload; ARCHITECTURE claimed it, nothing enforced it. Smoke throughsrc/index.tswiring with a fake host:eager/lazytrim (1 context_edit),offdoes not.Readiness & detailsnames the inactive state.trimin the ledger (glm B1):staged.kind, newContextEditKindrewind.sourcefornoteForeignCompactioninstead ofstartsWith("Another")(claude B4); redundantbefore_switch/before_forkledger resets removed (claude B5;session_startresets); write-onlymarkedAtremoved; break-even docstring counts the trimmed request (claude B7); veto derivation comment; bench caseprice a held trim(trimTokens, p95 3.3 ms) besideplan trim;package.jsonfilesexcludesdocs/findings(claude C2; packed count unchanged at 269).Claims checked and not applied
missCost = (w − r)·P; the warm path still reads X atr, the cold+trim path neither reads nor writes X, so the avoided cost ismissCost − w·X. The comment now states the derivation.stopis sticky (muse P1-1): Pi re-decides per request (cache-warmer.d.ts:47).Not in this PR
#75-area defects confirmed by re-verification (artifact-storage chunk views — reproduced with a 1.2 MB line; tombstone pruning; Hindsight fail-open ledger; native compaction budget/estimate/backup; bridge lock; Mnemopi readiness; Home settings
writeConfig; dashboard in RPC; settled watchdog; receipts; UI batch) are queued for separate PRs.