Skip to content

Commit 609c7e4

Browse files
author
Hermes Agent
committed
fix(embedded-agent-runner): accept compaction rewrites in session fence check
sessionFenceRewriteIsBenign rejected all rewrites where the file inode changed, even when content validation passed. When compaction rewrites the session file (new inode, smaller size), the early sameSessionFileIdentity check caused both benign-check functions to return false, triggering a false-positive EmbeddedAttemptSessionTakeoverError. Fix: remove sameSessionFileIdentity from the early-return guard in sessionFenceRewriteIsBenign. The function already rigorously validates content via lineMatchesLinearTranscriptMigration. When content validation passes, the rewrite is safe regardless of whether the inode changed — a compaction rewrite with new inode is benign.
1 parent f44af7e commit 609c7e4

1 file changed

Lines changed: 11 additions & 2 deletions

File tree

src/agents/embedded-agent-runner/run/attempt.session-lock.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -259,11 +259,13 @@ async function sessionFenceRewriteIsBenign(params: {
259259
previous: SessionFileFenceSnapshot | undefined;
260260
current: SessionFileFingerprint;
261261
}): Promise<boolean> {
262+
// Compaction can rewrite the session file with a new inode (dev/ino).
263+
// Defer the inode identity check past content validation so that a
264+
// content-valid compaction rewrite is accepted regardless of inode.
262265
if (
263266
!params.previous?.fingerprint.exists ||
264267
!params.current.exists ||
265268
!params.previous.text ||
266-
!sameSessionFileIdentity(params.previous.fingerprint, params.current) ||
267269
params.current.size > BigInt(MAX_BENIGN_SESSION_FENCE_REWRITE_RESULT_BYTES) ||
268270
params.current.size > MAX_SAFE_FILE_OFFSET
269271
) {
@@ -296,7 +298,14 @@ async function sessionFenceRewriteIsBenign(params: {
296298
expectedParentId = lineMatch.nextPreviousId ?? expectedParentId;
297299
}
298300
const appendedLines = currentLines.slice(previousLines.length);
299-
return appendedLines.every(isTranscriptOnlyOpenClawAssistantLine);
301+
if (!appendedLines.every(isTranscriptOnlyOpenClawAssistantLine)) {
302+
return false;
303+
}
304+
// Content validation passed — benign rewrite regardless of inode.
305+
// If the inode also matches: same-file rewrite (e.g. compaction in-place).
306+
// If the inode changed: compaction created a new file (new inode),
307+
// which is still benign because content passed validation.
308+
return true;
300309
}
301310

302311
type OwnedSessionFileWrite = {

0 commit comments

Comments
 (0)