fix(sessions): make hard deletes complete and retryable - #1174
Open
GautamSharma99 wants to merge 1 commit into
Open
fix(sessions): make hard deletes complete and retryable#1174GautamSharma99 wants to merge 1 commit into
GautamSharma99 wants to merge 1 commit into
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
delete_session()documented a permanent hard delete of both the primary JSONL transcript and its sibling subagent directory, but it removed the primary file first and then called:Any permission, read-only filesystem, traversal, or transient I/O failure was silently discarded. The call returned success with sensitive subagent transcripts still present, and the deleted primary file made the same public operation impossible to retry.
This PR makes hard-delete success truthful and failures recoverable.
Fixes #1164.
New deletion order
Subagent cleanup now happens first because it contains the data whose silent retention created the bug. If that cleanup fails, the primary transcript remains discoverable and the caller can retry
delete_session()after resolving the filesystem problem.If the final primary unlink fails, the subagent tree is already gone and the retained primary transcript still permits another retry.
Error semantics
Removed broad suppression
ignore_errors=Trueis gone. Permission errors, read-only filesystem errors, busy files, and otherOSErrorfailures now propagate to the caller.The public docstring now documents
OSError.Ignore only an actually absent sibling tree
A missing subagent directory is normal and remains a no-op.
However,
shutil.rmtree()can also surfaceFileNotFoundErrorfor a nested entry that disappears during traversal on supported Python versions/filesystems. Treating every ENOENT as "the tree is absent" would recreate partial-delete behavior.After
rmtree()raisesFileNotFoundError, the implementation useslstat()on the top-level sibling path:This also handles a concurrent process removing the entire tree between lookup and deletion without turning an already-satisfied cleanup into an error.
Resulting guarantees
On normal return:
{session_id}.jsonlis absent;{session_id}/subagent tree is absent.On subagent cleanup failure:
delete_session()call is retryable.On primary unlink failure:
As with any unlocked filesystem API, another process can recreate a path after deletion; this PR guarantees the state established by this operation rather than attempting cross-process locking.
Regression tests
Added tests that verify:
PermissionErrorfrom subagent cleanup propagates;FileNotFoundErrorpropagates while the top-level tree still exists;unlink()failure occurs only after the subagent tree is removed;Validation
Scope
This changes only the filesystem-backed
delete_session()operation and its tests/documentation. SessionStore-backed deletion, other mutation APIs, and public signatures are unchanged.