Repository navigation
Conversation
…n different instances
nazbert
added a commit
to nazbert/Deckard
that referenced
this pull request
Jul 12, 2026
clear_old_cached_pages snapshotted evictable pages under _pages_lock and then ran clear_action_objects() + pop outside it (issue StreamController#4 / B-04). Three windows let it gut a LIVE page: a controller's screensaver-pending page was invisible to the guards entirely (held for the whole screensaver duration -- hide() then loaded a page whose every action was dead, and the next get_page minted a duplicate Page); a page activated between snapshot and teardown got its actions torn down while active (WindowGrabber cycling past max_pages generates exactly this pressure); and gut-then-pop could hand the gutted object to a concurrent get_page. Each candidate is now re-validated under _pages_lock immediately before teardown (skip if replaced, re-marked mid-tick, active on any controller, or screensaver-pending) and popped BEFORE clear_action_objects -- a concurrent get_page mints a fresh Page instead of receiving the corpse. The teardown itself stays outside the lock (plugin hooks, D1). Residual: a page fetched but not yet activated at re-validation time is only closed structurally by the pin-count API (#81) -- documented there. tests/scenario_eviction_revalidate.py red-checks the pending-page window and the activation TOCTOU (made deterministic by activating the second candidate from the first one's teardown hook), plus a non-vacuous check that stale pages still evict.
nazbert
added a commit
to nazbert/Deckard
that referenced
this pull request
Jul 12, 2026
Review round 1 follow-ups on the eviction re-validate fix (issue StreamController#4): - Reframe the risk model: eviction is a purely in-memory teardown (no Page.save/atomic_write_json, never touches the page JSON), so StreamController#4's harm is USE-AFTER-EVICT -- a visible page whose actions are all dead plus a duplicate Page minted on the next get_page() -- recoverable by a page reload/replug, NOT on-disk data loss. Documented at the eviction path. - Add a window-3 leg to scenario_eviction_revalidate: a get_page() during the teardown gap must receive a FRESH Page (via StreamController#28's single-flight builder), not the gutted corpse. Red-checked -- with gut-before-pop restored the leg fails ("handed the gutted corpse"). - Document that remove_page's own out-of-lock clear_action_objects needs NO _page_is_live guard: the cache is keyed per-controller (distinct Page per (controller, path)) and load_page() moves active_page onto a different path before the pop, so it can never gut a live/pending page. - Pin the #81 residual in a comment: a page fetched via get_page() but not yet load_page()'d is born ready_to_clear=True and stays evictable in the pre-activation window; harm is narrow (action_objects empty pre-init, so teardown is a near-no-op -> only the duplicate-Page mint). Deferred to #81.
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.
Changes: