Skip to content

fix(agent-core): allow benign session rewrites with different inode#88653

Open
raymondjxj wants to merge 1 commit into
openclaw:mainfrom
raymondjxj:fix/session-fence-inode-false-positive
Open

fix(agent-core): allow benign session rewrites with different inode#88653
raymondjxj wants to merge 1 commit into
openclaw:mainfrom
raymondjxj:fix/session-fence-inode-false-positive

Conversation

@raymondjxj

Copy link
Copy Markdown

Summary

Compaction rewrites session files via writeFile+rename, which always creates a new inode. Previously, sessionFenceRewriteIsBenign rejected such rewrites at the inode identity gate (sameSessionFileIdentity), so the content validation that follows never ran, causing EmbeddedAttemptSessionTakeoverError false positives.

Root Cause

In sessionFenceRewriteIsBenign (line 266), the sameSessionFileIdentity check compares dev + ino. When compaction runs, it replaces the session file with a new inode, causing this check to return false and the function to exit early — without ever performing content validation.

The actual error path:

  1. releaseForPrompt() records fingerprint (inode A)
  2. Compaction runs, renames new file (inode B)
  3. assertSessionFileFence() compares fingerprint: inode B ≠ inode A
  4. sessionFenceRewriteIsBenign called, fails sameSessionFileIdentity check
  5. EmbeddedAttemptSessionTakeoverError thrown — false positive

Fix

Remove the inode identity gate from sessionFenceRewriteIsBenign while 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, function sessionFenceRewriteIsBenign, line 266.

Testing

  • Unit test: verify sessionFenceRewriteIsBenign returns true for same-content file with different inode
  • Integration test: run compaction concurrently with message processing, verify no EmbeddedAttemptSessionTakeoverError

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.
@openclaw-barnacle openclaw-barnacle Bot added agents Agent runtime and tooling size: XS triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. triage: refactor-only Candidate: refactor/cleanup-only PR without maintainer context. labels May 31, 2026
@clawsweeper

clawsweeper Bot commented May 31, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs real behavior proof before merge. Reviewed May 31, 2026, 10:28 AM ET / 14:28 UTC.

Summary
The PR removes the sameSessionFileIdentity guard from sessionFenceRewriteIsBenign so different-inode session rewrites can pass content validation.

PR surface: Source -1. Total -1 across 1 file.

Reproducibility: unclear. for the reported real-world compaction failure: source inspection confirms current main rejects a different-inode rewrite before content validation, but I did not establish that the actual OpenClaw compaction path rewrites the active fenced file that way.

Review metrics: 1 noteworthy metric.

  • Session fence guard relaxed: 1 inode-identity check removed. This is the guard that currently prevents a replacement file from being trusted solely because its JSONL contents look benign.

Merge readiness
Overall: 🧂 unranked krab
Proof: 🧂 unranked krab
Patch quality: 🧂 unranked krab
Result: blocked until real behavior proof is added.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • [P1] Add redacted real behavior proof for the reported compaction/reacquire scenario, such as terminal output or logs showing the failure path and after-fix result.
  • Replace the broad content-only trust with a narrow owned/trusted compaction path and focused regression tests.

Proof guidance:

  • [P1] Needs real behavior proof before merge: The external PR includes no after-fix logs, terminal output, recording, screenshot, or linked artifact for the compaction scenario; contributors should add redacted proof and then trigger a fresh review if needed. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.

Mantis proof suggestion
The reported failure manifests as a Telegram bot stop-processing loop, so live Telegram proof would materially improve confidence after the session-fence repair is narrowed. A maintainer can ask Mantis to capture proof by posting a new PR comment that starts with the OpenClaw Mantis account mention, followed by:

telegram live: verify a Telegram agent continues replying after embedded session compaction while a prompt stream is active.

Risk before merge

  • [P1] The relaxed rewrite path could accept an unowned replacement file that preserves prior lines and appends OpenClaw-looking assistant entries, weakening takeover detection.
  • [P1] The PR does not include after-fix real behavior proof for the reported compaction scenario, and the inspected compaction paths do not clearly match the same-path writeFile+rename claim.
  • [P1] No focused regression test proves that actual compaction is benign while arbitrary replacement files are still rejected.

Maintainer options:

  1. Preserve ownership proof before merge (recommended)
    Tie any different-inode acceptance to an owned/trusted compaction write or equivalent provenance and add regression coverage for both accepted compaction and rejected unowned replacement.
  2. Accept content-only trust explicitly
    Maintainers can intentionally accept content-valid replacement files, but that should be a documented session-fence policy choice with tests covering the threat assumptions.
  3. Pause for a real reproduction
    If the actual compaction write path cannot be reproduced, pause this branch until logs or a live run show which writer needs to be trusted.

Next step before merge

  • [P1] Maintainer review is needed because the remaining blocker is a session takeover safety decision plus missing real behavior proof, not a narrow mechanical repair.

Security
Needs attention: The patch weakens a session takeover safety check by trusting replacement-file contents without ownership or inode provenance.

Review findings

  • [P1] Keep replacement writes tied to owned compaction — src/agents/embedded-agent-runner/run/attempt.session-lock.ts:263-268
Review details

Best possible solution:

Keep replacement-file acceptance tied to an owned or trusted compaction write, or another narrow provenance signal, with regression coverage and redacted real-run proof.

Do we have a high-confidence way to reproduce the issue?

Unclear for the reported real-world compaction failure: source inspection confirms current main rejects a different-inode rewrite before content validation, but I did not establish that the actual OpenClaw compaction path rewrites the active fenced file that way.

Is this the best way to solve the issue?

No: accepting every content-valid replacement file is broader than the claimed compaction false positive. The safer fix is to prove the actual writer and preserve ownership or trusted-compaction provenance.

Full review comments:

  • [P1] Keep replacement writes tied to owned compaction — src/agents/embedded-agent-runner/run/attempt.session-lock.ts:263-268
    By removing the identity guard for every rewrite, an unowned process can replace the session file with one that preserves the previous lines and appends OpenClaw-looking assistant entries, and assertSessionFileFence() will trust it as benign. The inspected compaction paths acquire the session lock and append entries or write a successor file, so this should be fixed by proving and trusting the actual compaction write path rather than accepting arbitrary replacement files by content alone.
    Confidence: 0.86

Overall correctness: patch is incorrect
Overall confidence: 0.86

AGENTS.md: found and applied where relevant.

Codex review notes: reasoning high; reviewed against 88c99ddf5f82.

Label changes

Label justifications:

  • P1: The PR targets an agent workflow that can stop processing messages and changes the active session takeover guard.
  • merge-risk: 🚨 session-state: Merging this patch could make an unowned replacement transcript become trusted session state after prompt-lock reacquisition.
  • merge-risk: 🚨 security-boundary: Removing inode provenance from the benign rewrite path weakens the boundary between owned OpenClaw writes and external file replacement.
  • rating: 🧂 unranked krab: Overall readiness is 🧂 unranked krab; proof is 🧂 unranked krab and patch quality is 🧂 unranked krab.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs real behavior proof before merge: The external PR includes no after-fix logs, terminal output, recording, screenshot, or linked artifact for the compaction scenario; contributors should add redacted proof and then trigger a fresh review if needed. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
Evidence reviewed

PR surface:

Source -1. Total -1 across 1 file.

View PR surface stats
Area Files Added Removed Net
Source 1 0 1 -1
Tests 0 0 0 0
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 1 0 1 -1

Security concerns:

  • [medium] Replacement file can bypass takeover detection — src/agents/embedded-agent-runner/run/attempt.session-lock.ts:263
    Dropping the identity guard means a different inode can be accepted if its content matches the helper's limited benign-rewrite checks, which weakens protection against unowned session transcript replacement.
    Confidence: 0.84

What I checked:

Likely related people:

  • steipete: Recent path history shows steipete carried the large agent-runtime internalization, moved session write locking into the owned session runtime, and touched adjacent compaction successor code. (role: recent area contributor; confidence: high; commits: bb46b79d3c14, 5f68291f4f54, 912f66317334; files: src/agents/embedded-agent-runner/run/attempt.session-lock.ts, src/agents/embedded-agent-runner/compaction-successor-transcript.ts)
  • openperf: Recent merged history on the same session-lock file includes the timeout-abort lock release fix, which is adjacent to prompt-lock and takeover handling. (role: recent area contributor; confidence: medium; commits: 65fb56513fb2; files: src/agents/embedded-agent-runner/run/attempt.session-lock.ts)
  • luoyanglang: Recent merged history on the session-lock tests and implementation fixed session event queue self-wait behavior in the same embedded runner lock surface. (role: recent area contributor; confidence: medium; commits: b789e71e57d9; files: src/agents/embedded-agent-runner/run/attempt.session-lock.ts, src/agents/embedded-agent-runner/run/attempt.session-lock.test.ts)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P1 High-priority user-facing bug, regression, or broken workflow. merge-risk: 🚨 session-state 🚨 May lose, corrupt, stale, or mis-associate session, agent, or context state. merge-risk: 🚨 security-boundary 🚨 May affect sandboxing, authorization, credentials, or sensitive data. labels May 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling merge-risk: 🚨 security-boundary 🚨 May affect sandboxing, authorization, credentials, or sensitive data. merge-risk: 🚨 session-state 🚨 May lose, corrupt, stale, or mis-associate session, agent, or context state. P1 High-priority user-facing bug, regression, or broken workflow. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. size: XS status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. triage: refactor-only Candidate: refactor/cleanup-only PR without maintainer context.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant