A tab unseen for a while can still hold writing or a transfer. Choosing sleep from elapsed idle time alone risks removing the very state someone expects to retain. I narrowly select safe reading tabs and keep uncertain cases live rather than treating missing evidence as permission.

Idle time is only the first gate

CanSleepTab checks the default five-minute idle period, human ownership, loading state and protection for pinned/current/reference tabs. Already dormant or releasing entries are not selected again. Passing this helper does not close the document; host and frame checks follow.

The host also excludes private sessions, audible playback, capture, developer tools, pending navigation, interaction, drafts and authentication pages. Its active-download-path condition is broader than only asking whether this candidate tab has a transfer. Describing that protection more narrowly than the code would make another tab's download appear to prevent sleep for no explained reason.

Keep editors live even before the first keystroke

PageCanSleep refuses forms, textareas, inputs, selects, editable content, canvas, object and embed elements. Editors and file inputs remain protected even before typing begins. This broad rule can include a simple search form, so the policy does not promise that every apparent reading page will sleep.

Custom elements are also excluded because a closed shadow root may hide an editor. Playing media, mediaSession state and held/pending Web Locks add checks. The fixed inspection asks whether page structure should remain live; it is not a feature for returning field values to a model. It does not claim complete preservation of every application state that structural inspection cannot identify.

Keep the tab if even one frame cannot be verified

The host walks the main frame subtree and requires each safety result to be exactly true. Every check has a bounded wait; exceptions and timeouts count as unsafe. An unreadable frame is not assumed to contain no writing. Keeping uncertain pages live is a deliberate cost of the feature.

Because the tab can change during those awaits, eligible state, contents identity and documentEpoch are checked again afterward. Earlier safety evidence must not apply to another document. That asynchronous fence is not reproduced by a boolean policy table alone and must be handled separately when eligibility is connected to an actual close.

Respect a beforeunload refusal instead of forcing closure

Sleep retains bounded URL/title history, zoom and mute before requesting renderer close with waitForBeforeUnload. If the document prevents unloading, releasing state is reset and a protection delay applies. A memory-saving objective does not create authority to override the page's refusal.

The structure also avoids blocking all other work on one slow unload handler. Actual release belongs to destruction and subsequent state, not the candidate calculation alone. I read protection, close attempt and release as separate stages so interface language and runner results can report the same meaning without prematurely declaring completion.

A synthetic allow result is not live safety verification

The new module accepts declared protection state and shows why candidacy is blocked. Even declared all-frame safety and unload permission leave renderer_released False. It inspects no DOM and authenticates no current task permission. The real host's rechecks and close lifetime have not been erased from the integration contract.

This article reviews current code and selected original tests without putting the person's tabs to sleep. Original unit cases cover idle boundaries and pin/agent/loading/transfer protection; independent synthetic tests were run separately. I publish the judgment that retaining work comes first even when conservative exclusions reduce the apparent memory saving.