Skip to content

fix(store): keep fork resets isolated from parent tape#126

Merged
frostming merged 1 commit intobubbuild:mainfrom
Andy963:fix/fork-reset-isolation
Mar 20, 2026
Merged

fix(store): keep fork resets isolated from parent tape#126
frostming merged 1 commit intobubbuild:mainfrom
Andy963:fix/fork-reset-isolation

Conversation

@Andy963
Copy link
Contributor

@Andy963 Andy963 commented Mar 19, 2026

Summary

Fix ForkTapeStore.reset() so resets performed inside a fork stay isolated from the parent tape until merge-back.

Previously, reset() always called both the in-fork store reset and parent.reset(). That meant tape.reset inside a fork could immediately wipe the parent tape even when merge_back=False, breaking fork isolation and risking data loss.

What Changed

  • Track the active fork tape and whether it was reset within the current fork context.
  • In ForkTapeStore.reset():
    • keep immediate parent reset behavior outside a fork
    • keep immediate parent reset behavior for non-fork tapes
    • defer parent reset for the active fork tape
  • In fetch_all():
    • hide parent entries once the active fork tape has been reset in the current fork
  • In fork() finalization:
    • apply parent.reset(tape) only when merge_back=True and the forked tape was reset
    • then append forked entries back to the parent

Why

This restores the expected isolation semantics:

  • merge_back=False: fork changes, including reset, must not affect the parent tape
  • merge_back=True: reset should replace parent tape contents only when the fork is committed

Tests

Added regression coverage for:

  • reset inside fork with merge_back=False preserves parent entries
  • reset inside fork with merge_back=True replaces parent entries
  • reset inside fork hides parent entries during reads
  • reset outside fork still resets the parent immediately

Verification

  • uv run ruff check .
  • uv run mypy src
  • uv run pytest -q

@frostming
Copy link
Collaborator

That meant tape.reset inside a fork could immediately wipe the parent tape even when merge_back=False, breaking fork isolation and risking data loss.

Can we fix this by not wiping the parent tape when merge_back=False?

@Andy963
Copy link
Contributor Author

Andy963 commented Mar 19, 2026

That meant tape.reset inside a fork could immediately wipe the parent tape even when merge_back=False, breaking fork isolation and risking data loss.

Can we fix this by not wiping the parent tape when merge_back=False?

Yes, and this PR implements that in a more complete way.

Instead of only skipping the parent wipe when merge_back=False, it keeps reset fork-local during execution and only applies the parent reset when the fork is merged back. That preserves isolation semantics and avoids partial behavior differences between read-time and merge-time state.

@frostming frostming merged commit 6585863 into bubbuild:main Mar 20, 2026
5 checks passed
@Andy963 Andy963 deleted the fix/fork-reset-isolation branch March 20, 2026 01:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants