fix(hygiene): background strategy trims only under pressure without contextHygieneEnabled - #79
Merged
Merged
Conversation
…ontextHygieneEnabled Since d219600 the break-even/cold timing applied to every session the turn_end handler considered enabled, including sessions enabled only by autoTriggerStrategy "background" with contextHygieneEnabled off; those had trimmed under pressure only. Restore that gate: without contextHygieneEnabled a ready batch commits only under pressure (cause "pressure"), never at break-even, and no mark is held. Found by re-running the item-14 evaluator (task-eval --background-prep --cache-warming=idle): the no-compaction baseline arm had begun trimming (5,963,248 -> 5,507,252 synthetic input tokens) and every arm's idle warm count dropped from 2 to 0 because each committed edit rebuilds the agent's messages and Pi's warmer reports "conversation context changed".
Owner
Author
|
Receipts (local,
|
alpertarhan
marked this pull request as ready for review
September 27, 2026 23:33
alpertarhan
added a commit
that referenced
this pull request
Sep 28, 2026
…ries; review-wave-1 fixes and the findings reports (#80) * docs(findings): add the 2026-09-28 external review reports Four audits of the 9.8.0-canary.7 wave (#75-#79), one folder per model-harness pair, indexed from docs/README.md and docs/findings/README.md. Advisory only; the package excludes docs/findings (package.json files). * fix(hygiene): keep a carried trim through interrupted and busy boundaries; 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.
alpertarhan
added a commit
that referenced
this pull request
Sep 28, 2026
Integration candidate for the maintainer's daily Pi (real-session data collection on the cold-cache trim and the host cache ledger); not published. CHANGELOG dates the [Unreleased] notes since canary.7 (#79-#83) under 9.8.0-canary.8; README and guide name the checkout version. bun run release:check (env -i): typecheck clean; 1603 pass / 5 skip (Docker sandbox) / 0 fail; adversarial gate 384/0; bench within limits; build; release audit passed; compat:pi latest = 0.87.1.
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.
fix: background strategy trims only under pressure without
contextHygieneEnabledFound by re-running the item-14 evidence commands (
task-eval-reports/item14-cost-evidence-2026-09-25/COMMANDS.txt) onmain. Results stay local; nothing new is committed undertask-eval-reports/(now ignored by default, the cited 09-25 directory stays tracked).What was wrong
Since
d219600(P1-4 timing, #76) the break-even/cold rule applied to every session theturn_endhandler considered enabled — including sessions enabled only byautoTriggerStrategy: "background"withcontextHygieneEnabled: false, which had trimmed only under pressure before. Effects in the evaluator (--background-prep --cache-warming=idle, same flags as 09-25):no-compactionbaseline arm started trimming: 5,963,248 → 5,507,252 synthetic input tokens atd219600(bisected:370a832still 5,963,248 with 2 warms);conversation context changed(probed viasession.cacheWarmingStatusafter each idle wait).Fix
register-smart-context-tool.tsturn_end: withoutcontextHygieneEnabled, a ready batch commits only under pressure (causepressure), never at break-even, and no mark is held. Test: "trims only under pressure when the background strategy enables cleanup without contextHygieneEnabled" (below the gate: no entries, no mark, a cold request changes nothing; at the gate:cause: "pressure"). The timing fixture now opts intocontextHygieneEnabledexplicitly. Mutation: removing the guard fails exactly that test. Docs: configuration (background strategy row), evaluation (expected warm count for hygiene arms), CHANGELOG Fixed.Post-fix evaluator (local, offline; vs the 09-25 report)
--background-prep --cache-warming=idle):no-compaction75 requests, 2 warms, prefix 0.9909 (as 09-25);eesv87 / 2 warms / 0.8548 (as 09-25);recoverable-hygiene73 / 0 warms andhybrid85 / 0 warms — by design now: cleanup is on in those arms and a break-even trim commits at the idle boundary.--cache-warming=streaming): exactly 1 warm per arm during the long tool run (as 09-25).Verification
See the receipts comment.