fix(session): percent-encode path separators in session dir to prevent cross-project collision#96906
Conversation
… encoding The previous encoding replaced '/', '\', ':' all with '-', which made the transform non-injective: /home/a/b-c and /home/a/b/c both mapped to the same session directory. Add cwd verification in continueRecent as a defense-in-depth measure so a resumed session always belongs to the requested project. Fixes openclaw#96542 Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
|
Thanks for the context here. I swept through the related work, and this is now duplicate or superseded. Close as superseded: the useful direction is covered by the open, proof-positive, mergeable candidate at #97785, while this branch remains narrower and still misses matching older sessions plus project-scoped list filtering. Canonical path: Review and land one compatibility-preserving cwd-filter branch, preferably #97785, then close the competing candidate PRs after the canonical fix merges. So I’m closing this here and keeping the remaining discussion on #97785. Review detailsBest possible solution: Review and land one compatibility-preserving cwd-filter branch, preferably #97785, then close the competing candidate PRs after the canonical fix merges. Do we have a high-confidence way to reproduce the issue? Yes. Current main source still maps the example cwd pair to the same default session directory and selects the newest JSONL file without matching header cwd; I did not run artifact-writing tests because this review is read-only. Is this the best way to solve the issue? No. Keeping the shipped key is the right compatibility direction, but this branch only guards the single newest file and leaves list filtering uncovered; the superseding PR is the better complete fix. Security review: Security review cleared: The diff only reads local session JSONL headers and changes no dependency, CI, secret, permission, network, or code-execution surface. AGENTS.md: found and applied where relevant. What I checked:
Likely related people:
Codex review notes: model internal, reasoning high; reviewed against 54b09580f61b. |
Revert the percent-encoding change of the default session directory key. Changing the key would make existing project transcripts invisible after upgrade without migration. Literal percent-escapes in cwd paths (e.g. /home/a%2Fb) would also collide with the encoded separators. The continueRecent cwd-verification guard already prevents wrong-project resume when two cwds map to the same safe-path — keep the shipped key and let the header.cwd check handle collisions. ClawSweeper: keep shipped key, cwd verify (openclaw#96906) Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
|
ClawSweeper applied the proposed close for this PR.
|
Closes #96542
What Problem This Solves
getDefaultSessionDirencodes the cwd into a safe directory name by replacing path separators (/,\,:) all with-. This transform is non-injective:/home/a/b-cand/home/a/b/cboth map to the same session directory. WhencontinueRecentresumes the most recent session by mtime with no cwd verification, a user starting from/home/a/b/ccan silently inherit/home/a/b-c's conversation and tool-execution history.Why This Change Was Made
Two changes:
Percent-encode path separators instead of collapsing them all to
-./becomes%2F,\becomes%5C,:becomes%3A. This makes the encoding injective — distinct cwds produce distinct directory names.Verify cwd on
continueRecentresume. When finding the most recent session, compare the session header cwd against the requested cwd. If they differ (collision in encoding due to legacy or changed worktree), start a fresh session instead of silently resuming the wrong one.Evidence
Before/after encoding proof
Cwd verification proof
When
continueRecentis called,findMostRecentSession(dir)returns the most recent session file. The fix loads its header and compares the stored cwd against the requested cwd. Mismatch → fresh session. Match → resume. This covers both legacy collisions and worktree changes.Existing tests
src/agents/sessions/covercontinueRecentandgetDefaultSessionDirpathsNot tested
Merge Risk
Low. The change:
continueRecentguard prevents silent cross-project resumption even for legacy directories🤖 Generated with Claude Code