Skip to content

Bug: async session commit can re-commit old messages before live session switch completes #580

@dddgogogo

Description

@dddgogogo

Summary

POST /api/v1/sessions/{session_id}/commit?wait=false can report the commit as accepted/running, but the live session's messages.jsonl is not switched/cleared in time. As a result, a later session commit can re-commit old messages from the same session.

Expected behavior

For async commit mode:

  • the API should still return immediately with a task id;
  • but the task should only be marked completed after the live session directory has actually finished switching to the committed state;
  • after completion, the live session's messages.jsonl should already be cleared (or otherwise guaranteed not to be re-consumed by a later commit).

Actual behavior

Observed behavior on our side:

  • wait=false returns accepted with a task_id;
  • during/after async commit, the old live session messages.jsonl can remain in place for some time;
  • if another commit is triggered on the same session, old messages may be committed again.

From source reading, it appears that:

  • Session.commit_async() archives current messages into a temp session tree and writes an empty messages.jsonl into the temp session;
  • the actual switch from temp -> live session directory happens later in the semantic processing callback;
  • but the async commit task/completion semantics do not appear to guarantee that the live session switch has finished before the task is treated as done.

Reproduction idea

  1. Create a session.
  2. Add one message.
  3. Call POST /api/v1/sessions/{session_id}/commit?wait=false.
  4. Before/around the time the async commit finishes switching the live session tree, trigger another commit on the same session.
  5. Observe that the previous message can be re-committed because the live messages.jsonl was still the old one when the session was reloaded.

Why this matters

This breaks the expected idempotence boundary for async session commit and can lead to duplicate memory extraction / duplicate commit of old session messages.

Suggested direction

Keep async commit non-blocking, but make task completion semantics stricter:

  • accepted / running: background work has started;
  • completed: the live session target has already been switched to the committed state.

In other words, wait=false should still be asynchronous, but task.status=completed should imply that a subsequent commit on the same session cannot re-consume old messages.jsonl content.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Status

    In progress

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions