session-start-hook.sh reads HOOK_STDIN to extract session_id (per #206/#270's comments: "this hook never read its stdin, so it had neither source nor session_id... Only session_id is needed") — but the payload also carries source, and it's discarded. The recap (=== MEMORY === and friends) is printed identically regardless of whether the trigger is startup, resume, compact, clear, or fork.
That's right for startup/resume/clear when the model's context is empty or being replaced. It's not right for compact: at that moment the conversation already has a just-produced summary of everything that happened in it. Re-adding a second, differently-sourced recap of the same general period on top is pure duplication, and it happens on every single auto-compaction.
Measured, not guessed (50 sessions, ~40 days, one user):
| SessionStart source |
fired |
non-empty |
total chars |
avg/fire |
max |
compact |
82 |
41 |
37,634 |
459 |
2,193 |
startup |
180 |
84 |
71,039 |
395 |
3,368 |
resume |
48 |
22 |
45,685 |
952 |
4,934 |
compact fired essentially as often as startup, at comparable per-fire cost, injecting content the model's own compaction summary already substantially overlaps with.
Proposed fix: extract source the same narrow way session_id already is (no new dependency), and skip (or emit a drastically shorter marker — e.g. just the .remember/ path reminder, no recap body) when source = "compact". startup/resume/clear/fork unchanged.
Happy to provide the extraction snippet in the same style as the existing _stdin_session_id heuristic if useful.
session-start-hook.shreadsHOOK_STDINto extractsession_id(per #206/#270's comments: "this hook never read its stdin, so it had neithersourcenorsession_id... Onlysession_idis needed") — but the payload also carriessource, and it's discarded. The recap (=== MEMORY ===and friends) is printed identically regardless of whether the trigger isstartup,resume,compact,clear, orfork.That's right for
startup/resume/clearwhen the model's context is empty or being replaced. It's not right forcompact: at that moment the conversation already has a just-produced summary of everything that happened in it. Re-adding a second, differently-sourced recap of the same general period on top is pure duplication, and it happens on every single auto-compaction.Measured, not guessed (50 sessions, ~40 days, one user):
compactstartupresumecompactfired essentially as often asstartup, at comparable per-fire cost, injecting content the model's own compaction summary already substantially overlaps with.Proposed fix: extract
sourcethe same narrow waysession_idalready is (no new dependency), and skip (or emit a drastically shorter marker — e.g. just the.remember/path reminder, no recap body) whensource = "compact".startup/resume/clear/forkunchanged.Happy to provide the extraction snippet in the same style as the existing
_stdin_session_idheuristic if useful.