fix(agent-core): allow benign session rewrites with different inode#88653
fix(agent-core): allow benign session rewrites with different inode#88653raymondjxj wants to merge 1 commit into
Conversation
Compaction rewrites session files via writeFile+rename, which always creates a new inode. Previously, sessionFenceRewriteIsBenign rejected such rewrites at the identity check (sameSessionFileIdentity), so the content validation that follows never ran, causing EmbeddedAttemptSessionTakeoverError false positives. This change removes the inode identity gate from sessionFenceRewriteIsBenign while preserving all content validation: file must exist, end with a newline, append only valid transcript lines. A file with a different inode but valid compaction-style content is indistinguishable from a compaction from the agent's perspective, so the inode check was both too strict and redundant with the content checks. Fixes EmbeddedAttemptSessionTakeoverError during concurrent compaction.
|
Thanks for the context here. I swept through the related work, and this is now duplicate or superseded. Close: the compaction false-positive this PR was trying to address is now handled by the merged owned-compaction persistence path in current main and v2026.6.6, while this branch still weakens the session takeover boundary by trusting content-only replacement rewrites. Canonical path: The related merged PR So I’m closing this here and keeping the remaining discussion on #90775. Review detailsBest possible solution: Keep the shipped owned-compaction persistence hook and continue rejecting content-only replacement rewrites unless a future narrow, proof-backed owner signal is needed. Do we have a high-confidence way to reproduce the issue? No high-confidence current-main reproduction remains for the original compaction false positive: current main and v2026.6.6 contain the owned compaction persistence path and regression coverage. Source inspection does show the proposed patch would broaden replacement-file trust if merged. Is this the best way to solve the issue? No: this is not the best way to solve the issue. The merged replacement fixes owned compaction at the writer/provenance boundary while preserving rejection of raw external session edits. Security review: Security review needs attention: The patch weakens a session takeover safety check by trusting replacement-file contents without inode or owned-write provenance.
AGENTS.md: found and applied where relevant. What I checked:
Likely related people:
Codex review notes: model internal, reasoning high; reviewed against 7a7165ad22c4; fix evidence: release v2026.6.6, commit bbfe8ccaf60e. |
|
ClawSweeper applied the proposed close for this PR.
|
Summary
Compaction rewrites session files via
writeFile+rename, which always creates a new inode. Previously,sessionFenceRewriteIsBenignrejected such rewrites at the inode identity gate (sameSessionFileIdentity), so the content validation that follows never ran, causingEmbeddedAttemptSessionTakeoverErrorfalse positives.Root Cause
In
sessionFenceRewriteIsBenign(line 266), thesameSessionFileIdentitycheck comparesdev + ino. When compaction runs, it replaces the session file with a new inode, causing this check to returnfalseand the function to exit early — without ever performing content validation.The actual error path:
releaseForPrompt()records fingerprint (inode A)assertSessionFileFence()compares fingerprint: inode B ≠ inode AsessionFenceRewriteIsBenigncalled, failssameSessionFileIdentitycheckEmbeddedAttemptSessionTakeoverErrorthrown — false positiveFix
Remove the inode identity gate from
sessionFenceRewriteIsBenignwhile preserving all content validation. The content checks remain fully in place: file must exist, end with a newline, append only valid transcript lines, and stay within size limits. A file with a different inode but valid compaction-style content is indistinguishable from a compaction from the agent's perspective.Source
src/agents/embedded-agent-runner/run/attempt.session-lock.ts, functionsessionFenceRewriteIsBenign, line 266.Testing
sessionFenceRewriteIsBenignreturnstruefor same-content file with different inodeEmbeddedAttemptSessionTakeoverError