← Back to PRs

#17812: fix: prune HEARTBEAT_OK turns from session transcript

by MisterGuy420 open 2026-02-16 06:18 View on GitHub →
size: S trusted-contributor
## Summary Prune HEARTBEAT_OK user and assistant messages from the session transcript when heartbeat results in shouldSkip: true. This prevents context pollution from accumulating zero-information heartbeat exchanges over time. ## Changes - Added transcript cleanup for heartbeat-only responses - Follows existing pattern of delivery suppression and updatedAt restoration ## Testing - Tested that heartbeat still runs and detects alerts - Verified silent acks are cleaned up from transcript - No behavioral change for meaningful heartbeat content Fixes openclaw/openclaw#17804 <!-- greptile_comment --> <h3>Greptile Summary</h3> This PR adds transcript pruning for HEARTBEAT_OK responses to prevent context pollution from zero-information heartbeat exchanges. The approach captures the session entry count before the heartbeat runs, then truncates entries back to that count if the heartbeat result is skippable. - **Critical data loss bug**: The pre-counting guard requires `entry?.sessionFile` to be truthy (line 598), but the pruning function only checks `entry?.sessionId` (line 362). When `sessionFile` is undefined — a valid state per the `SessionEntry` type — `originalEntryCount` stays at `0` while pruning still proceeds, resulting in the entire session transcript being rewritten with only the header. - **Race condition concern**: The raw `fs.promises.writeFile` in `pruneHeartbeatTranscript` can clobber concurrent writes from other processes (e.g., the Pi agent) that append to the session file between the read and write operations. <h3>Confidence Score: 1/5</h3> - This PR has a data loss bug that can destroy session transcripts when entry.sessionFile is undefined. - The asymmetric guard between the pre-counting block (requires entry.sessionFile) and pruneHeartbeatTranscript (only requires entry.sessionId) creates a path where originalEntryCount is 0 but pruning proceeds, truncating the entire transcript to just the header. This is a silent data loss bug with no test coverage. - src/infra/heartbeat-runner.ts — the pruneHeartbeatTranscript function and the pre-counting block both need the guard conditions aligned to prevent transcript data loss. <sub>Last reviewed commit: c007e7e</sub> <!-- greptile_other_comments_section --> <!-- /greptile_comment -->

Most Similar PRs