You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Observation-level forget on a session-<id>-* snapshot entity is silently undone by the next Stop #346
PR #344 (#322) fixed captureEntity's replace: true path so it no longer
overwrites a whole-entityforget (an entity archiveEntity flipped to status: 'archived'). It does not, and cannot, protect an observation-level forget on an entity that stays active (e.g. the user forgets one specific
observation on session-<id>-files via removeObservation, but the entity
itself is not archived).
For the three session-<id>-* snapshot entities session-summary.js writes
with replace: true, an observation-level forget on one of them will be
silently undone on the next Stop: replace re-derives the entity's full
observation set from the transcript and overwrites whatever was there,
including the fact that one observation had been removed.
This is now explicitly documented as an unaddressed gap in the code itself
— scripts/hooks/_shared.js, the comment directly above the if (replace && !isNew && row.status === 'archived') check in captureEntityInner — but nothing currently detects or prevents it.
Why this is plausibly real, not theoretical
The three session-<id>-* entities are re-derived from the session
transcript on every Stop by design (that is the whole point of #322's replace fix — they are snapshots, not accumulating logs). Any user
correction made via forget at the observation level on one of these three
entities specifically is, structurally, guaranteed to be re-derived away on
the very next Stop, for as long as the session continues. This is different
from commit-<sha> or pre-compact-<id> entities, which append and where
an observation-level forget survives (nothing re-derives and overwrites the
full set on those paths).
Options
Accept it as documented, out of scope — an observation-level forget on
a machine-derived, transcript-re-derived snapshot entity is a narrower use
case than forgetting a whole entity, and the next Stop's re-derivation
will produce the same observation again anyway if the underlying
transcript fact is still true — so "forgetting" one observation on one of
these three entities may not be a coherent user action to support.
Track per-observation forgets and exclude them from re-derivation — a
real fix, but requires replace to diff against a forgotten-observations
list rather than doing a full delete+reinsert, adding real complexity to
a hot per-turn path.
Warn or refuseforget at the observation level specifically for session-<id>-* entities, pointing the user at the whole-entity forget
instead, since that is the only form replace actually respects.
src/knowledge-graph.ts's removeObservation (the observation-level
forget path) does not touch status.
scripts/hooks/_shared.js's archived-entity check in captureEntityInner
keys entirely on row.status === 'archived', so it cannot see or protect
an active entity with a removed observation.
Not a release blocker for #344 — the whole-entity protection that PR fixes
is real and independent of this gap.
Fixed in #357 (merged as 554e714) and published in 4.10.1 on npm next. forget stores a hash of the removed text on the three session snapshot entities and Stop's replace path filters it; an explicit remember restores it. Guard break-tested: removing the filter turns tests/hooks/session-summary.test.ts red for files, fixes and summary (3 failed). The new invariant forgotten-session-observations-stay-removed holds on a real graph. Two hardening gaps on the import path and on corrupted metadata are tracked in #359.
Activity
chore(sdlc): adopt the SDLC loop with a tree-bound verify receipt
kevintseng commentedon Sep 19, 2026
Fixed in #357 (merged as 554e714) and published in 4.10.1 on npm
next.forgetstores a hash of the removed text on the three session snapshot entities and Stop'sreplacepath filters it; an explicitrememberrestores it. Guard break-tested: removing the filter turnstests/hooks/session-summary.test.tsred for files, fixes and summary (3 failed). The new invariantforgotten-session-observations-stay-removedholds on a real graph. Two hardening gaps on the import path and on corrupted metadata are tracked in #359.intent: accept observation-forget-survives-stop
fix(release): prepare v4.10.1 candidate