Skip to content

fix(compaction): plugin engines never received the session store, making skew persistence inert - #554

Merged
Kyzcreig merged 1 commit into
mainfrom
fix/lcm-skew-persistence-binding
Aug 10, 2026
Merged

Kyzcreig merged 1 commit into
mainfrom
fix/lcm-skew-persistence-binding

Conversation

@Kyzcreig

Copy link
Copy Markdown
Collaborator

The calibration stack was correct and completely inert

Three PRs shipped it -- #529 (survive a restart), #539 (key by provider/model), #541 (per content class). All three are right. None of them did anything, because the engine this fleet runs never received the session store.

Measured on the live tree 2026-08-09:

COMPACTION_SKEW ... ratio=1.405 ... class=tool     <- loop running fine
COMPACTION_SKEW ... ratio=1.353 ... class=tool
COMPACTION_SKEW ... ratio=1.335 ... class=tool

sqlite> SELECT COUNT(*) FROM compression_skew_calibration;
0                                                  <- nothing persisted

Root cause

agent_init binds the session store through:

getattr(agent.context_compressor, "bind_session_state", None)

ContextCompressor defines that method. The ContextEngine ABC did not. So every plugin engine skipped the bind silently -- no exception, no log -- left _session_db unset, and made _persist_skew_history() return at its first guard forever.

The consequence is the exact gap #529 was built to close: the learned ratio (a measured 1.33-1.41 under-count on tool output) was discarded on every restart and relearned from raw-rough 1.0.

Fix

Define a minimal default bind_session_state on the ABC.

Deliberately not a fix to LCM alone -- any future engine now inherits a working bind instead of failing the same silent way. ContextCompressor keeps its richer override (cooldown + failure-streak rehydration), pinned by a test so the default can't shadow it.

Proof

E2E on the real engine, not a double:

load_context_engine("lcm").bind_session_state(db, "s1")
_persist_skew_history()
-> [('claude-apr', 'claude-opus-5', [1.4, 1.35, 1.33])]

9 tests, RED-proven -- removing the method fails 7. Two are class-level guards rather than instance tests:

  • test_every_concrete_engine_can_be_bound enumerates ContextEngine subclasses, so the next engine to miss this fails at test time instead of in production
  • test_agent_init_binds_through_getattr pins the call shape the fix depends on, so the ABC default can't quietly become decorative

The tests assert the wiring, not just the logic. A persist method that works in isolation while nothing hands it a DB is exactly the failure that shipped three times in this subsystem.

979 passed across the compaction / skew / context-engine surface.

…ing skew persistence inert

Three PRs shipped the skew-calibration stack -- #529 (survive a restart),
#539 (key by provider/model), #541 (calibrate per content class). All three
are correct. All three were INERT for the LCM engine, which is the engine
this fleet actually runs.

Measured on the live tree 2026-08-09:

    COMPACTION_SKEW ... ratio=1.405 ... class=tool     <- loop running fine
    COMPACTION_SKEW ... ratio=1.353 ... class=tool
    sqlite> SELECT COUNT(*) FROM compression_skew_calibration;
    0                                                  <- nothing persisted

agent_init binds the session store with:

    getattr(agent.context_compressor, "bind_session_state", None)

ContextCompressor defines that method; the ContextEngine ABC did not. So
every plugin engine skipped the bind SILENTLY -- no exception, no log --
left _session_db unset, and _persist_skew_history() returned at its first
guard forever. The learned ratio (measured 1.33-1.41 under-count on tool
output) was thrown away on every restart and relearned from raw-rough 1.0,
which is precisely the gap #529 existed to close.

Fix: define a minimal default bind_session_state on the ABC. Deliberately
not a fix to LCM alone -- any future engine now inherits a working bind
instead of failing the same silent way. ContextCompressor keeps its richer
override (cooldown + failure-streak rehydration), pinned by a test.

E2E on the real engine (not a double):

    load_context_engine("lcm").bind_session_state(db, "s1")
    _persist_skew_history()
    -> [('claude-apr', 'claude-opus-5', [1.4, 1.35, 1.33])]

9 tests, RED-proven: removing the method fails 7, including
test_every_concrete_engine_can_be_bound (enumerates ContextEngine
subclasses so the NEXT engine to miss this fails at test time, not in
production) and test_agent_init_binds_through_getattr (pins the call shape
the fix depends on, so the ABC default cannot quietly become decorative).

The tests assert the WIRING, not just the logic. A persist method that
works in isolation while nothing hands it a DB is exactly the failure that
shipped three times in this subsystem.

979 passed across the compaction/skew/context-engine surface.
@Kyzcreig
Kyzcreig added this pull request to the merge queue Aug 10, 2026
Merged via the queue into main with commit 5a4ec3b Aug 10, 2026
44 checks passed
@Kyzcreig
Kyzcreig deleted the fix/lcm-skew-persistence-binding branch August 10, 2026 07:15
@Kyzcreig
Kyzcreig restored the fix/lcm-skew-persistence-binding branch September 21, 2026 10:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant