Skip to content

refactor: remove the on-disk ghost log - #1235

Merged
Juliusolsson05 merged 3 commits into
mainfrom
refactor/remove-ghost-log
Sep 25, 2026
Merged

Juliusolsson05 merged 3 commits into
mainfrom
refactor/remove-ghost-log

Conversation

@Juliusolsson05

@Juliusolsson05 Juliusolsson05 commented Sep 25, 2026 •

Copy link
Copy Markdown
Owner

Fixes #731

Why (owner decision, 2026-09-25)

<userData>/ghost-logs/<sessionId>.ghost.jsonl persisted the renderer's provisional rows, so that a pane which crashed mid-turn could show them after a restart.

What goes

  • Main: GhostJournal with its startup compaction, the ghost:append / ghost:read IPC, and the shutdown flush.
  • Preload: the ghost bridge.
  • Renderer:
    • every ghostAppend;
    • the dead spawn-time bootstrap in session.ts;
    • ghostsToPersist.
  • Retention: the ghost-logs bucket, and fix(storage): prune orphaned ghost logs; protect a ghost log only while its session exists #1223's owner provider together with WorkspaceFileStore.sessionOwnershipKnown, which existed only for it. sessionIds() stays because it has another caller.

What stays

In-memory ghosts are unchanged: the live streaming preview, and the fallback for JSONL stuck mid-turn while the pane is live. docs/design/ghost-system.md now says crash-resume is deliberately not covered, and explains why.

Cleanup of existing installs

storage/legacyGhostLogs.ts removes the directory in the background on every launch. It is an idempotent rm -rf, and failure is logged and harmless. It can be deleted a few releases after this change ships.

Tests

  • New: legacyGhostLogs.test.ts checks that the directory is removed, its siblings are untouched, and a missing directory is a no-op.
  • Removed: tests of removed code (journal, owner retention, ownership flag).
  • Retargeted: the shutdown diagnostic test now uses the recordings flush. The burst-cadence test asserts the ghost map instead of IPC append counts.
  • Suite results:
    • tsc -b is clean.
    • The full suite passes 6,713 of 6,715 (1 skipped). The one failure, src/main/workflows/control.system.test.ts (a 5 s timeout), fails identically on a clean origin/main locally, and main's CI is green. It is local environment, unrelated.

🤖 Generated with Claude Code

Review disposition (A Claude, B Pi; 2 rounds)

Finding Disposition
A1: ARCHITECTURE.md still described the journal (dead link, crash-resume claims, storage row) Fixed (dfc1534e)
A2: ghost-system.md contradicted its new "in memory only" section Fixed
A3/B2: stale comments (devDebug, bundleCorpus, useIpcSubscriptions ×2, SessionFeed, extraction script) Fixed
A4: unused basename import Removed
A5/B1/B3: cleanup contracts unpinned (force:false and a removed try/catch survived) Fixed: quiet-no-op (no warn) and never-rejects tests; both mutants killed
B3b: no tripwire on the startup call site Accepted (repo norm)
Merge 736e51e9 (#1228 conflict) Verified by both in round 2: sweepGhosts intact, every persistence call site gone

Round 2: A and B MERGE-READY on dfc1534e. Steering q7 condition met: round 2 and CI both ran on the post-merge head.

Juliusolsson05 and others added 2 commits September 25, 2026 01:26
Owner decision (2026-09-25, #1227). <userData>/ghost-logs persisted the
renderer's provisional rows so a pane that crashed mid-turn could show
them after a restart. Nothing had read those files since 0cb71e9
(2026-07-16): the only reader looked them up under a freshly minted spawn
id. They had grown to 2.1 GB (1,935 of 1,955 files for sessions that no
longer existed), had OOM'd main once, and needed their own compaction and
retention. Reviving the reader (#1227) needed clock and identity
machinery to avoid repainting committed turns, for a rare case whose
restored text is not in the agent's own resumed conversation.

Removed: GhostJournal and its compaction, the ghost:append/ghost:read IPC
and preload bridge, every renderer append, the dead spawn-time bootstrap,
ghostsToPersist, the ghost-logs retention bucket and #1223's owner
provider (with the store's sessionOwnershipKnown flag it existed for).
storage/legacyGhostLogs.ts deletes the old directory in the background on
launch. In-memory ghosts (the live streaming preview and the JSONL-stuck
fallback) are unchanged. docs/design/ghost-system.md says so.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Keeps #1228's sweepGhosts and drops ghostsToPersist, which this branch
removes along with the on-disk log.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Juliusolsson05 added a commit that referenced this pull request Sep 25, 2026
#1234 opened

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- ARCHITECTURE.md: drop the dead ghost-journal link and the crash-resume
  claims; the storage table lists the legacy directory as deleted on
  launch.
- ghost-system.md: the lifecycle, TTL and eviction sections no longer
  describe a journal.
- Stale code comments (devDebug, bundleCorpus, useIpcSubscriptions,
  SessionFeed) and the extraction script note corrected; unused
  basename import removed.
- legacyGhostLogs tests now pin the quiet no-op (no warn when the
  directory is already gone) and the never-rejects contract its void
  call site depends on; both surviving mutants are killed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.

bug(renderer): resume re-appends the entire ghost log every time

1 participant