Skip to content

Page-state rollback can overwrite concurrent page edits #59

Description

@jzjzzzzzzz

Summary

project_page_state.py can overwrite a concurrent in-place edit while rolling back a multi-page projection.

Reproduction

  1. Start a page-state projection that changes at least two pages.
  2. Let the first page publish successfully.
  3. Modify that published page in place from another process, preserving its inode.
  4. Make publication of a later page fail.

Actual behavior

Rollback recognizes the page only by the transaction's published inode, unlinks it, restores the original before-image, and removes the recovery lock. The concurrent writer's bytes are lost.

A regression reproducer observes:

exit_code=1
concurrent_edit_preserved=False
restored_to_old_bytes=True
lock_exists=False

Expected behavior

Rollback must behave as a compare-and-swap against the exact verified after-image. If the canonical page's bytes or stable identity have changed since publication, it must:

  • preserve the concurrent page bytes;
  • preserve the original rollback image;
  • retain the writer lock and recovery journal with rollback-required status;
  • require reconciliation instead of declaring rollback complete.

Impact

This is a data-loss issue: an unrelated editor can successfully write a page and have that edit silently replaced by a later failure elsewhere in the projection batch.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions