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
bug(renderer): resume re-appends the entire ghost log every time #731
Problem (found during the #725 review; not introduced by it)
On resume, src/renderer/src/workspace/hook/actions/session.ts (~L379-424) reads the on-disk ghost log, reconciles it against the loaded JSONL tail, and then persists ghostsToPersist(current.ghosts, merged). current.ghosts is the fresh empty map of the new runtime, so every ghost reloaded from disk looks "new" and is appended to the log again.
Expected
Only ghosts whose state actually changed during bootstrap reconciliation (newly superseded, newly orphaned) should be appended; ghosts loaded unchanged from disk should not be re-written.
Impact
The per-session ghost log grows by its own size on every resume of a long session. With #725, hidden orphans are also reloaded, hidden and swept on each resume, which rides on the same re-append. reduceGhostLog folds duplicates at read time so behaviour is correct, but the file and the resume cost grow without bound.
Measurement (quality loop, 2026-09-25) before any fix: across the 17 ghost logs of sessions still in the workspace (28,179 lines, largest 10.5 MB), there are 0 lines duplicating the same (uuid, _atp.updatedAt). If every resume re-appended the loaded ghosts unchanged, those duplicates would be there (GhostJournal.append does not dedup against disk).
Either:
the spawnSession bootstrap at session.ts:634 is not the path current resumes take (rehydrate may go through initialHistory.ts:357, whose diff base may already hold the loaded ghosts); or
startup compactAllGhostLogs (index.ts:880) rewrites the files before duplicates are ever observed.
The code reading in this issue still looks right for that one path, so this stays open, but it isn't fixed on a guess.
Evidence that would settle it: a debug run that resumes one session twice, with ghostAppend calls counted in feed-debug and the file line count checked before compaction.
Labelled needs-evidence. (#1223 separately stops orphaned ghost logs, which are 2.1 GB of the 2.2 GB directory, from accumulating.)
Update: the #1223 review found why no duplicates show. Since 0cb71e99 (July), nothing reads a ghost log on restore; filed as #1225. The re-append path in this issue only runs on a fresh spawn, against an empty log. Revisit this once #1225 wires the reader.
Activity
Juliusolsson05 commentedon Sep 25, 2026
Measurement (quality loop, 2026-09-25) before any fix: across the 17 ghost logs of sessions still in the workspace (28,179 lines, largest 10.5 MB), there are 0 lines duplicating the same
(uuid, _atp.updatedAt). If every resume re-appended the loaded ghosts unchanged, those duplicates would be there (GhostJournal.appenddoes not dedup against disk).Either:
spawnSessionbootstrap atsession.ts:634is not the path current resumes take (rehydrate may go throughinitialHistory.ts:357, whose diff base may already hold the loaded ghosts); orcompactAllGhostLogs(index.ts:880) rewrites the files before duplicates are ever observed.The code reading in this issue still looks right for that one path, so this stays open, but it isn't fixed on a guess.
Evidence that would settle it: a debug run that resumes one session twice, with
ghostAppendcalls counted in feed-debug and the file line count checked before compaction.Labelled
needs-evidence. (#1223 separately stops orphaned ghost logs, which are 2.1 GB of the 2.2 GB directory, from accumulating.)Juliusolsson05 commentedon Sep 25, 2026
Update: the #1223 review found why no duplicates show. Since
0cb71e99(July), nothing reads a ghost log on restore; filed as #1225. The re-append path in this issue only runs on a fresh spawn, against an empty log. Revisit this once #1225 wires the reader.fix(workspace): restore holds only ghosts the committed tail has not …