= 3.01.03 =
* Extended **Protect WPBakery animations** to keep the audited lifecycle-critical `wpb_flexslider`, `nivo-slider`, `isotope`, `jquery-ui-tabs`, and `jquery-ui-accordion` providers out of UltraCache Delay queues alongside `vc_waypoints` and `vc_carousel_js`. These scripts remain eligible for normal defer optimization.

= 3.01.02 =
* Extended **Protect WPBakery animations** to keep `vc_carousel_js` initialization out of UltraCache Delay queues as well as `vc_waypoints`, preventing WPBakery image carousels from remaining hidden when their `window.load` initialization would otherwise be delayed. Both scripts remain eligible for normal defer optimization.

= 3.01.01 =
* Added **Protect WPBakery animations** under Advanced Frontend Javascript manipulation. When enabled, WPBakery/Visual Composer `vc_waypoints` animation-reveal JavaScript is kept out of UltraCache Delay queues while remaining eligible for normal defer optimization.
* Setup Wizard now detects active WPBakery/Visual Composer installations and automatically enables **Protect WPBakery animations** without adding entries to JavaScript safeguard lists or changing other `vc_*` scripts.

= 3.00.16 =
* Cleared Browser Runtime Scan WordPress coding-standard warnings without changing scanner behavior: scanner query reads now document their short-lived token verification, and the current request URI is sanitized before scan-target normalization.

= 3.00.15 =
* Browser Runtime Scan anonymous passes now run inside a credentialless iframe authorized by a short-lived, same-site scan-only token, so WordPress resolves the request as anonymous from the beginning without `wp_set_current_user()` or authentication-cookie manipulation.
* Removed the administrator REST nonce from scanner frontend documents; the scan token grants no WordPress user, capability, settings access, or write action and only enables the collector for its bound scan id and URL.
* `Debug Browser Scanner` now exposes the same credentialless scanner iframe visibly inside the admin page instead of opening a credential-bearing popup; unsupported browsers fail explicitly instead of producing a differential from the wrong context.
* Removed the obsolete logged-in/admin Runtime Scan context because logged-in frontend optimization is intentionally bypassed.
* Runtime Scan baseline state now preserves unrelated font delivery, iframe lazy-loading, WooCommerce Blocks CSS cleanup, critical-request-chain relief, and cart-fragment suppression settings instead of changing them during a JavaScript differential scan.

= 3.00.14 =
* Moved the existing Browser Scanner visible-window debug setting into `Advanced Frontend Javascript manipulation` and renamed its UI label to `Debug Browser Scanner` without changing the stored setting key or current saved state.
* Runtime Scan Comparison diagnostics now activate and render only while `Debug Browser Scanner` is enabled; disabling the setting clears any temporary comparison state while normal hidden-iframe Runtime Scan behavior remains unchanged.

= 3.00.13 =
* Logged-in frontend requests now bypass UltraCache frontend performance transformations, including JavaScript defer/delay/reordering, CSS bundle/delay helpers, font delivery rewrites, asynchronous CSS/iframe helpers, asset-chain cleanup, full-HTML performance rewrites, and frontend media URL replacement.
* Page-cache bypass behavior for logged-in users is unchanged; upload/background media conversion, object cache, invalidation, diagnostics, and administrative/background workflows remain available.
* Runtime Scanner `Anonymous frontend` requests continue to switch to the anonymous user before frontend transformations execute, while real logged-in browsing remains unmodified.

= 3.00.12 =
* When `Open Browser scanner in new window` is enabled, Runtime Scan now pauses immediately after the unoptimized baseline capture and shows a manual `Continue` button before restoring JavaScript optimizations or starting cycle 1.
* The visible Browser Scanner window remains on the captured baseline page during the pause so its live page and DevTools console can be inspected; the existing hidden iframe path remains unchanged.

= 3.00.11 =
* Added the Advanced setting `Open Browser scanner in new window` with a canonical default of Off; existing hidden-iframe Browser Runtime Scan behavior remains unchanged while the setting is Off.
* When the visible Browser Scanner setting is enabled, Runtime Scan pre-opens a real browser window from the user click, reuses it for baseline and optimized passes, and keeps it open for live page/DevTools inspection.
* Runtime Scan collector bridge delivery now supports both the existing iframe parent and the optional visible window opener without adding a second scanner or REST polling path.

= 3.00.10 =
* Fixed Runtime Scan canonical Warm session acquisition to use the existing `warm` foreground job type instead of the unsupported `runtime_scan` job type that returned HTTP 409 before warming.

= 3.00.09 =
* Runtime Scan now warms its selected URL through the existing manual Warm page pipeline and foreground warm session instead of bypassing the canonical pipeline with a direct low-level warm_url call.
* Page warm execution budgets and loopback HTTP request timeouts now follow PHP max_execution_time instead of arbitrary 10/20/45/60/75-second page-warm caps; max_execution_time=0 is treated as unlimited for the warm request.
* CSS bundle source requests invoked by the Warm pipeline now inherit the same max_execution_time-based request timeout instead of reintroducing a 10/120-second cap.
* Safe page-warm and CSS-bundle loopback requests no longer truncate an explicitly requested timeout to 60 seconds, allowing those warm callers to honor the server execution limit.
* Warm URL locks and foreground/cron ownership leases are no longer allowed to expire before a finite PHP max_execution_time window can complete.

= 3.00.08 =
* Browser Runtime Scan no longer self-finalizes after 12 seconds or on beforeunload; a normal capture now completes only after the scanned page fires window load and the existing 4.5-second settle period, while the dashboard's 300-second hard timeout remains the only emergency cutoff.
* The unoptimized Runtime Scan pass now also disables and later restores the full WooCommerce frontend strategy state, including product/gallery asset cleanup, product-filter asset cleanup, WooCommerce Blocks CSS cleanup, and Cart fragments behavior.

= 3.00.07 =
* Browser Runtime Scan now waits up to 300 seconds for the frontend collector to complete instead of aborting after 20 seconds.
* A Runtime Scan hard-timeout is reported explicitly as a timeout failure and is never recorded or presented as a clean zero-error scan.

= 3.00.06 =
* Fixed Runtime Scan comparison so both captures open the exact same scan URL and use the same frontend rendering path.
* Removed the baseline-only runtime settings override and changing baseline/optimized URL markers.
* Runtime Scan still disables/restores the normal JavaScript optimization switches between captures while preserving safeguard lists unchanged.

= 3.00.05 =
* Keep Defer Instead of Delay and Do Not Defer or Delay completely untouched during Runtime Scan baseline capture; the baseline now snapshots and temporarily disables only JavaScript optimization engine settings before Flush/Warm/capture, then restores only those settings before the optimized pass.
* Prevent Runtime Scan baseline preparation from overwriting default, manually maintained, or previously learned JavaScript safeguards while preserving the existing differential scan and Error Fixer flow.

= 3.00.04 =
* Make Runtime Scan baseline use the real saved JavaScript configuration lifecycle: snapshot current JavaScript optimization settings and the Defer Instead / Do Not Defer or Delay lists, temporarily disable the JavaScript optimization engines and clear both safeguard lists, Flush All, warm the selected scan URL, capture the baseline, then restore the exact snapshot before the optimized Flush/Warm/browser scan.
* Guarantee restoration of the original JavaScript settings and safeguard lists through a finally path if baseline preparation, warm-up, or browser capture fails.
* Keep the temporary Runtime Scan Comparison diagnostics from 3.00.03 so baseline, raw optimized, and differential sets can be verified while this flow is tested.

= 3.00.03 =
* Added temporary Runtime Scan comparison diagnostics for baseline, raw optimized, and differential errors with normalized matching signatures; scan and repair behavior are unchanged.

= 3.00.02 =
* Make Browser Runtime Scan differential: capture a baseline request with UltraCache JavaScript manipulation disabled, flush and run the optimized scan, and send only new optimized-only runtime errors to JavaScript Error Fixer while retaining baseline evidence in the scan result.
* Keep the baseline request isolated to the diagnostic URL instead of globally changing live JavaScript settings, and treat the new Runtime Scan mode query argument as an internal non-cacheable control parameter.
* Let the Setup Wizard resolve ambiguous Defer Instead / Do Not Defer or Delay findings by trying Defer Instead first, then escalating the same persistent candidate to Do Not Defer or Delay on the following scan through the existing safeguard state.
* Complete the Setup Wizard with a browser-check notice instead of a failed setup state when optimized-only runtime errors remain after all confident automatic safeguards have been exhausted.

= 3.00.01 =
* Rename the WordPress-facing plugin title to UltraCache - Cache and Speed Optimization while preserving the ultracache slug, folder, text domain, function prefixes, and internal identifiers.
* Promote UltraCache to the 3.00.01 release series without changing runtime behavior beyond the version metadata.

= 2.59.13.84 =
* Invalidate the PHP OPcache entry for wp-config.php immediately after a verified UltraCache-managed write so newly saved Varnish/Redis secret constants are visible to the next request without waiting for OPcache timestamp revalidation.
* Surface the runtime planner reason when Varnish exact-invalidation capability detection is blocked before any transport request is sent.

= 2.59.13.83 =
* Make administrator-triggered Varnish exact-BAN capability probes retry up to three times only for transient Admin transport failures while keeping authentication, invalid-command, and explicit Varnish rejection failures immediate.
* Accept Varnish CLI 200 and 201 success responses for Admin BAN operations and surface the last concrete transport result directly in the canary failure message when capability detection still fails.

= 2.59.13.82 =
* Restore the compatibility export for the Varnish default-endpoint helper after the mode-aware endpoint synchronization change, preventing varnish.js from failing module registration and cascading into cache/dashboard bootstrap failures.

= 2.59.13.81 =
* Keep the Varnish endpoint field synchronized when Purge mode changes: replace the previous mode's populated default endpoint with the new mode's default, including the equivalent http://127.0.0.1:82 form, while preserving custom endpoints.

= 2.59.13.80 =
* Give Redetect Varnish Capabilities a dedicated 20-second Varnish admin-socket timeout for diagnostic exact-invalidation probes, while preserving the user's normal production invalidation timeout.

= 2.59.13.79 =
* Make Save Varnish Settings run the existing Varnish capability detection after a successful save and persist the Varnish settings again after successful capability detection, reusing shared save/test helpers without nested UI-queue operations.
* Rename the dashboard Test Varnish action to Redetect Varnish Capabilities and remove the standalone Measure Varnish Performance button while retaining the existing performance measurement subsystem internally.

= 2.59.13.78 =
* Extend the unified Setup Wizard configuration progress with Query-string args whitelist population before font optimization, reusing the existing Populate detector and normal settings save flow so detected taxonomy/attribute keys are appended without replacing user-maintained entries.

= 2.59.13.77 =
* Move Scan Browser Runtime Errors cycle progress from the inline JS / Defer Safeguards & Diagnostics panel into a dedicated live modal while reusing the same Runtime Scan status, repair-cycle runner, and stored results.

= 2.59.13.76 =
* Enable LCP Frontend Discovery and Lazy load third-party iframes in the existing recommended Optimal Settings recipe used by the unified Setup Wizard.

= 2.59.13.75 =
* Hide the Setup choices configuration section immediately after the Wizard Next action starts configuration, keeping the selected values in the existing shared setup flow while progress takes over the modal.

= 2.59.13.74 =
* Rework the unified Setup Wizard review layout so Setup choices appears directly below the explanatory text and spans nearly the full modal width, without changing Wizard behavior or underlying settings flows.

= 2.59.13.73 =
* Simplify the unified Setup Wizard UI by removing the visible Website analysis summary while retaining the same internal detection for recommended defaults and capability decisions.
* Make Homepage the default Wizard warm-up scope and use Homepage as the fallback when no valid Wizard warm-up selection is available.
* Reduce the Wizard setup footer to a single Next action; closing or postponing remains available through the modal close control.

= 2.59.13.72 =
* Merge the fresh-install Setup Wizard and the Overview optimal-configuration action into one shared Setup Wizard path; Overview now exposes a single Run Wizard action and removes the duplicate Flush All Cache / Warm Site buttons from the Optimal Configuration card.
* Add Wizard Object Cache and warm-up selectors without creating parallel settings or workers: Object Cache reuses the existing backend probe/save/runtime-verification path, while Homepage, Homepage + Menu, and Full Site reuse the normal Warm Cache menu/depth/source settings and existing warm runners.
* Update Optimal Configuration guidance so manually maintained credentials, schedules, exclusions, safeguards, and lists are explicitly preserved, and allow the same setup-wizard state machine to be started manually on existing installations.

= 2.59.13.71 =
* Forward the active dashboard manual-session owner token from homepage-first media processing into the shared attachment worker, preventing a false HTTP 409 exclusive-queue conflict during live homepage conversion while leaving local-asset processing and queue ownership semantics unchanged.

= 2.59.13.70 =
* Use WordPress core `wp_is_writable()` directly when setup planning probes the object-cache disk backend, removing the direct PHP `is_writable()` fallback flagged by WordPress Coding Standards without changing the backend availability decision.

= 2.59.13.69 =
* Make Start / Resume Conversion refresh homepage media discovery under the existing exclusive dashboard media session, convert homepage attachments and local theme/plugin image assets first in the foreground, then cross a semantic homepage checkpoint and continue the normal full Media Library conversion.
* Make Apply Optimal Settings reuse the same homepage foreground conversion phase but stop at the homepage checkpoint, release manual media ownership without resuming background media work, and provide a Skip image conversion action that exits after the current conversion unit without marking remaining homepage media failed.

= 2.59.13.68 =
* Make Apply Optimal Settings and the First-Run Setup Wizard reuse the standalone Runtime Scan self-healing cycle: the same target-only Purge/Warm preparation, iframe Browser Runtime Scan, Console Error Fixer request, deterministic safeguard save, zero-error stop, and six-scan limit now run from one shared implementation.
* Remove the obsolete Apply-only hidden runtime scanner/polling and JavaScript safeguard repair helpers so automatic setup cannot diverge from the proven standalone Runtime Scan flow.

= 2.59.13.67 =
* Make every standalone Runtime Scan self-healing cycle honor Page URL to scan as the single warm and scan target: after Purge All, warm only that exact URL instead of warming the homepage, configured menu, or starting the background full-site warm-up.
* Resolve the Runtime Scan target URL once at cycle start and reuse the same value for warm-up, iframe capture, and JavaScript Error Fixer analysis so the cycle cannot drift to another configured warm scope.

= 2.59.13.66 =
* Turn the standalone Scan Browser Runtime Errors action into a bounded self-healing cycle: before each scan it clears cache and warms the configured site scope, captures errors through the existing iframe runtime scanner, sends those exact errors through the existing Console Error Handler, saves only deterministic recommended Defer Instead / Do Not Defer or Delay actions, and repeats until zero runtime errors or six scans.
* Stop the Runtime Scan cycle when Error Fixer cannot prove a new deterministic action; the sixth scan is final verification and remaining errors stay visible instead of applying an unverified final change.
* Remove Apply Optimal Settings' automatic Defer JS dependency preset append so JavaScript safeguards are no longer pre-seeded outside Error Fixer evidence.

= 2.59.13.65 =
* Replace the manual Scan Browser Runtime Errors popup/REST-polling transport with an transparent fixed 1280×900 iframe that returns one completed serialized runtime payload directly to the admin through a scan-ID- and origin-validated `postMessage` bridge; the manual scan no longer depends on runtime report REST storage or polling.
* Keep Browser Runtime Scan as input to the existing Console Error Handler: captured errors continue through the same `runConsoleErrorFixer()` / `scanType: console` path used by Extract Console Error Suggestions, with no alternate suggestion engine or scan fallback.

= 2.59.13.64 =
* Make Scan Browser Runtime Errors persist one completed raw browser-error report instead of posting on every captured error, removing report-write contention from the collector path.
* Remove JavaScript Error Fixer/suggestion generation from runtime report save/read operations; runtime reporting now stores and returns raw browser evidence only.
* Feed captured Runtime Scan errors into the same Console Error Handler path used by Extract Console Error Suggestions, including the same `scanType: console` diagnostic queue engine and result rendering.

= 2.59.13.63 =
* Make Apply Optimal Settings JavaScript verification proof-required: remove the HTML dependency analyzer fallback and the hidden snapshot-report fallback from the automatic compatibility path.
* Fail Apply Optimal Settings when any tested runtime page does not return a complete persisted report, when Error Fixer cannot prove an automatic action for remaining runtime errors, or when errors remain after five verification passes; do not mark setup complete without verified JavaScript compatibility.

= 2.59.13.62 =
* Enable **Delay non-critical/local JS** in Apply Optimal Settings and move its dashboard control from Advanced Frontend Javascript manipulation into the main Javascript manipulation card immediately above Delay safe third-party JS.
* Make the existing Apply Optimal Settings / First-Run JavaScript compatibility loop consume exact recommended Error Fixer actions from its hidden runtime scans before using HTML dependency analysis as a fallback; automatically apply only resolved Defer Instead or Do Not Defer or Delay targets, purge/rewarm, and verify for up to five passes with early stop when clean or when no new deterministic fix exists.

= 2.59.13.61 =
* Expand a proven missing-global dynamic function-dispatch failure across the same literal runtime dispatch collection in one Error Fixer pass: only function names present in that exact runtime set, with exactly one loaded provider and a proven provider/dispatcher strategy conflict, become fixes; no same-owner, filename, plugin, or symbol-prefix expansion is used.

= 2.59.13.60 =
* Make jQuery-plugin Error Fixer ordering use the exact loaded provider and direct-consumer page-inventory records already proven by Runtime Scan, instead of re-resolving their filenames/handles through fuzzy inventory matching that could manufacture multi-strategy ambiguity.

= 2.59.13.59 =
* Keep explicit `jQuery(...).method is not a function` failures inside the jQuery-plugin dependency resolver: accept a direct consumer only when scanned page code actually calls the missing method, so wrapper/runtime stack frames cannot displace the real consumer.
* When the loaded jQuery plugin provider/consumer pair or its execution-order proof is incomplete, keep the finding review-only inside the jQuery-plugin resolver instead of falling through to the generic failing-consumer exclusion fallback.

= 2.59.13.58 =
* Separate wrong-type JavaScript TypeErrors from missing-global provider resolution: `X.foo is not a function` now proves that `X` exists, so Error Fixer repairs only the exact failing consumer strategy (`Delay` → `Defer Instead`, then non-delayed `defer`/`async` → `Do Not Defer or Delay`) instead of inventing a provider for `X`.
* Reject bare self-referential symbol transforms such as `x = JSON.parse(x)` or `x = normalize(x)` as provider-definition evidence during local source discovery, while retaining real declarations/definitions for genuine `ReferenceError: X is not defined` analysis.

= 2.59.13.57 =
* Make JavaScript Error Fixer action rendering total for appendable findings: a resolved `preferredTarget` still shows only its exact recommended action, while an appendable finding with no resolved target now exposes the two exact choices (`Defer Instead` and `Add to Do Not Defer or Delay`) instead of rendering with no button; dependency-chain actions remain hidden in this unresolved case.
* Treat same-owner symbol providers found only by filesystem/code discovery as review-only evidence when that provider is absent from the scanned page inventory, instead of presenting an unloaded file as an active appendable runtime provider.

= 2.59.13.56 =
* Make unresolved runtime-source fallback findings actionable in JavaScript Error Fixer: when no concrete provider can be resolved and the exact plugin/theme source is retained as the compatibility fallback, mark the finding for `Do Not Defer or Delay` so the recommended append button is shown instead of leaving a ready-to-append finding with no action.

= 2.59.13.55 =
* Make jQuery-plugin Error Fixer dependency findings strategy-aware: when one concrete provider and direct consumer have a proven runtime ordering conflict, recommend only the provider with the least-invasive `Defer Instead` or `Do Not Defer or Delay` target selected from their scanned strategies; keep the consumer as causal evidence instead of a duplicate appendable fix.
* Do not emit jQuery-plugin provider/consumer appendable findings when Runtime Scan cannot prove a single actionable execution-order conflict; continue through the existing error-scoped fallback pipeline instead.

= 2.59.13.54 =
* Restore anonymous inline third-party content-pattern delay with boundary-aware prefix matching: user-visible token-prefix fragments ending in `-` or `_` must begin at a real identifier boundary, preventing suffix collisions inside unrelated application identifiers while preserving normal URL/domain/code and established simple-token matching.
* Keep the WordPress registered dependency-closure protection for Do Not Defer or Delay unchanged.

= 2.59.13.53 =
* Restore the anonymous-inline JavaScript safeguard removed in 2.59.13.52: third-party content-pattern delay now requires a canonical WordPress-style inline companion with both a captured handle and a matching `-js` / `-js-before` / `-js-after` / `-js-extra` / `-js-translations` ID family, preventing arbitrary inline application bootstraps from being delayed by incidental pattern matches.
* Retain the 2.59.13.52 WordPress registered dependency-closure protection for Do Not Defer or Delay unchanged.

= 2.59.13.52 =
* Make the visible Do Not Defer or Delay list dependency-preserving for WordPress-registered scripts: when an explicitly excluded registered handle is kept blocking, its real registered dependency closure inherits the same runtime protection so UltraCache cannot create a deferred provider before a blocking consumer.
* Restore anonymous inline third-party content-pattern delay behavior removed in 2.59.09.08, allowing visible patterns such as gtag/dataLayer/GTM bootstrap markers to delay matching inline analytics again while retaining user exclusions and WordPress inline dependency-block protection.

= 2.59.13.51 =
* Make JavaScript Error Fixer action controls honor each finding's backend `preferredTarget`: confirmed console findings show only the exact recommended Defer Instead or Do Not Defer or Delay action, while Analyzer/general diagnostic action choices remain unchanged.
* Split Console Error Handler bulk actions by recommendation target, including correct escalation from an already-applied Defer Instead safeguard to Do Not Defer or Delay when the backend marks the finding as a fallback candidate.

= 2.59.13.50 =
* Canonicalize WordPress script families in JavaScript diagnostics using real `data-ultracache-handle` registry evidence: matching external, `-js-before`, `-js-after`, `-js-extra`, and `-js-translations` fragments inherit the same handle and declared dependency metadata, so Error Fixer can diagnose the parent dependency chain instead of falling back to the consumer.
* Do not infer new WordPress families from script IDs alone; sibling propagation occurs only when an explicit WordPress handle was captured for that family.

= 2.59.13.49 =
* Make JavaScript Error Fixer resolve WordPress inline `*-js-after` companions to their owning enqueued script before dependency diagnosis. If that parent is defer/delay/async, recommend the parent as the direct execution-order fix; if the parent is already blocking, inspect its own declared WordPress dependencies instead.
* When multiple late providers are all direct declared dependencies of the same exact failing consumer, report those broken edges instead of falling back to the consumer itself; unrelated page dependency conflicts remain excluded from Error Fixer results.

= 2.59.13.48 =
* Consolidate console errors within the same pasted batch: a later unresolved fallback is suppressed only when an earlier resolved failure is causally linked by the same script identity, the real WordPress dependency ancestry, or concrete provider code for the later missing symbol. Independent errors remain visible.
* Treat WordPress inline `*-js-before` / `*-js-after` frames as companions of their owning enqueued script, so the Error Fixer proposes one parent target instead of duplicate inline-and-parent exclusions.
* Keep error-scoped WordPress registry/provider findings in the Error Fixer Appendable Fixes bucket even when the minimal action is Do Not Defer or Delay; Analyzer-only page-wide findings remain separate.

= 2.59.13.47 =
* Restore JavaScript Error Fixer to an error-scoped pipeline: remove the page-wide declared-dependency and lifecycle Analyzer passes from console/runtime error fixing, so unrelated silent dependency findings no longer appear as fixes for a specific browser error.
* Resolve each failing script against its actual WordPress-declared dependencies first and recommend only a unique execution-order conflict; if the registry does not explain the failure, fall back to a unique loaded symbol provider and then targeted active plugin/theme discovery instead of broad suggestion fan-out.
* Remove hardcoded WordPress missing-symbol-to-provider mappings from the Error Fixer, stop treating arbitrary `object.method is not a function` errors as jQuery plugin failures, and never recommend multiple method consumers when no concrete provider was found.

= 2.59.13.46 =
* Simplify the Media queue summary to completed, pending, processing, and failed states. Completed combines successfully processed items with queue items that were already up to date, removing the misleading processed/already optimized split.

= 2.59.13.45 =
* Clarify the Media batch summary cards: show AVIF and WebP optimized-file counts on separate lines, rename the ambiguous Media status total to Media queue items, include processed queue items in the breakdown, and show Target policy, Fallback, and Queue format on separate lines.

= 2.59.13.44 =
* Make successful Varnish capability proofs persistent until their bound configuration/capability fingerprint changes or a new test supersedes them; remove the seven-day proof expiry from exact invalidation, topology/flush scope, ESI, HTML variants, batch BAN, and soft-purge-related capability state. Legacy stored expiry timestamps are ignored so previously verified capabilities remain valid after upgrade.
* Remove Varnish proof-expiry and per-endpoint tested-at timestamps from the diagnostics UI; Test Varnish still records internal probe timestamps for state/diagnostic purposes but no longer presents when a successful capability test was performed.

= 2.59.13.43 =
* Fixed the WordPress 6.7+ early translation-loading notice in the pre-init Varnish ESI capability status path by routing its four runtime messages through the existing init-aware translation helper.

= 2.59.13.42 =
* Fix Overview → Warm Site so it honors the persistent **Also warm CSS bundles** preference exactly like Cache → Warm Cache → Full Site, including the configured CSS bundle scope, CSS readiness guard, and matching resumable warm job type.

= 2.59.13.41 =
* Fix the WordPress 6.7+ early translation-loading notice for the query-combination-limit warm bypass message by routing it through the existing init-aware translation helper.

= 2.59.13.40 =
* Add **Query cache combination level** with 1 = 8, 2 = 64, 3 = 512 (default), 4 = 4,096, and ALL (NOT RECOMMENDED), plus a live bounded calculator based on the effective query-string allowlist; very large allowlists use scientific notation instead of allocating enormous integers or combination sets.
* Replace page-cache query-family rotation with hard admission control: canonical URLs do not consume query capacity, orig/WebP/AVIF representations share one query identity, existing cached variants remain usable, and new unknown variants bypass cache once the configured per-path limit is full instead of evicting older variants and creating unbounded registry churn.
* Add independent hourly and catch-up garbage collection for `wp_ultracache_cache_asset_refs`, deleting only expired inactive rows in bounded 5,000-row batches with a per-run delete/time budget; stale generated-CSS cache invalidation now uses the canonical cache deletion path so affected registry rows are marked inactive correctly.

= 2.59.13.39 =
* Fix Browser Runtime Scan report races that could leave real JavaScript errors unrecorded while repeated `/runtime-js-scan/report` requests returned HTTP 409. The frontend collector is now the normal serialized writer, admin scan loops poll persisted reports instead of POSTing competing snapshots, final collector flush is requested explicitly, and direct DOM snapshot submission is retained only as a fallback.
* Reduce runtime-scan report pressure by replacing the collector's 1-second overlapping report loop with one baseline snapshot, error-driven serialized updates, and bounded completed snapshots; add short bounded server-side merge-lock acquisition retries for residual cross-navigation contention.
* Enable **Async external CSS** in Apply Optimal Settings while preserving the administrator-maintained external CSS async exclusion list.

= 2.59.13.38 =
* Add automatic CSS Bundle Exclusion selection to First-Run Setup and Apply Optimal Settings after the initial homepage HTML + CSS warm. Use the existing compact CSS profiler source-byte inventory, consider only sources larger than 50 KB, select up to two while preferring a large theme stylesheet, append without overwriting existing exclusions, then purge and rebuild the homepage CSS bundle.
* Cap automatic setup at two total CSS Bundle Exclusion entries (including existing manual/previous entries), skip cleanly when CSS warm/profiler data is unavailable, and avoid progressively adding more exclusions on repeated Optimal Settings runs.

= 2.59.13.37 =
* Replace the always-run automatic HTML JavaScript dependency analysis in First-Run Setup and Apply Optimal Settings with hidden same-origin browser runtime checks on the homepage and up to three discovered navigation URLs.
* Preserve JavaScript safeguard lists when runtime checks capture no errors. Run Analyze HTML JS Dependencies only on pages that actually report runtime errors, apply only deterministic Strong Suggestion safeguards when available, then purge/rewarm and retest.
* Bound automatic JavaScript self-healing to three runtime verification passes, leave unresolved/non-deterministic runtime errors for manual review, and keep the normal standalone Runtime Scan and Analyze HTML JS Dependencies interfaces unchanged.

= 2.59.13.36 =
* Simplify the manual Apply Optimal Settings modal so the Overview button immediately starts website analysis and configuration in the same progress flow, with no pre-apply Detected environment or Settings applied now review boxes and no second confirmation click.
* Keep initial setup-plan failures retryable, while preserving the existing live apply/preparation progress and completion verification UI.

= 2.59.13.35 =
* Preserve already-configured Object Cache and Varnish infrastructure during First-Run Setup and Apply Optimal Settings reruns. Existing UltraCache Object Cache is runtime-verified without changing its backend, fallback, credentials, or drop-in; existing external object-cache drop-ins are preserved without UltraCache takeover.
* Add a setup-only persistence context so ordinary wizard/Optimal Settings saves skip Object Cache drop-in synchronization plus Varnish validation/rate-limit resynchronization. Fresh or unconfigured sites still use the existing Redis → APCu → SQLite → Disk Object Cache setup flow, and manual Server controls keep their existing behavior.

= 2.59.13.34 =
* Simplify Warm Cache to three scope actions (Homepage, Configured Menu, Full Site) controlled by one persistent **Also warm CSS bundles** setting, enabled by default and by Apply Optimal Settings.
* When the CSS warm option is enabled the same three actions warm HTML plus the configured CSS bundle scope; when disabled they warm HTML only. Reuse the same preference in First-Run/Optimal site preparation and JavaScript safeguard purge/rewarm, and remove the duplicate CSS-specific and restart action buttons.

= 2.59.13.33 =
* Reuse the existing Warm/Media/JavaScript ProgressPanel inside First-Run Setup and Apply Optimal Settings for live configured-menu warm and HTML JavaScript dependency-analysis progress, while suppressing only the duplicate standalone floating popup during those setup flows.
* Add phased live progress for the automatic JavaScript safeguard cache refresh (purge, homepage rewarm, configured-menu warm, and background full-site warm resume), with the menu stage automatically switching to the existing per-URL warm counters.

= 2.59.13.32 =
* Preserve server-managed HTML compression as a distinct Setup Plan result and show **Server managed** instead of **Off** in Apply Optimal Settings when the compression probe confirms that the web server or upstream layer already handles HTML compression.

= 2.59.13.31 =
* Move Activity Summary and Diagnostics from Overview to Advanced and preserve their side-by-side desktop layout.
* Open Query-string args caching by default.
* Add an Automation tab before Advanced and move Automation & Scheduling out of Cache.
* Add a Fonts & CSS tab before Media and move CSS Delivery, Fonts Optimization, and CSS Bundle Exclusions & Diagnostics there.
* Rename the Frontend tab to Javascript, keep JavaScript safeguards there, place WooCommerce beside Javascript manipulation, and simplify the WooCommerce card title.
* Restore LCP Diagnostics & Settings to Media directly above Media settings & Media Library replacement.
* Convert Advanced Frontend Javascript manipulation, Advanced CSS Delivery, and Advanced Fonts Optimisation to accordions and replace their subtitles with a red performance warning.
* Convert Quick start & examples to an Overview accordion while keeping it as the final Overview section.
* Add deliberate spacing between General Inclusions and the Advanced diagnostics area.
* Update Manual Setup/Help paths for the new Javascript, Fonts & CSS, and Automation tabs.

= 2.59.13.30 =
* Move Cache Statistics plus General Exclusions and General Inclusions to the Advanced tab.
* Move Support this plugin to Overview and keep Quick start & examples as the final Overview section.
* Place Activity Summary and Diagnostics side by side in Overview while keeping Advanced Diagnostics in Advanced.
* Move First-party parallel execution, Third-party parallel execution, LCP Boundary Delay, and Delay non-critical/local JS into a dedicated Advanced Frontend Javascript manipulation card.
* Move Inline CSS Bundling, Async Remaining CSS, and Aggressive Async CSS into a dedicated Advanced CSS Delivery card.
* Move Async Generated Font-Mix CSS Bundle and Advanced Runtime Font CSS Rewrite into a dedicated Advanced Fonts Optimisation card.
* Restyle the primary dashboard tabs to match the square card treatment, including the native white-card appearance, and add controlled spacing below the tab bar.
* Add breathing room between Server integration cards, especially Object Cache / Varnish and External Cache Flush, and normalize diagnostic-card/group spacing.
* Update Help guidance for Delay non-critical/local JS to its new Advanced tab location.

= 2.59.13.29 =
* Keep the detailed Help setup workflow as a Manual Setup alternative instead of removing it after the First-Run Wizard and Apply Optimal Settings automation.
* Rewrite the Manual Setup checklist around the six-tab dashboard, with explicit paths for HTML compression, warm menu/sources, media formats and conversion testing, fonts, WooCommerce, MailerLite, Object Cache, Varnish, and warm automation.
* Add a Manual preparation section with the new Overview / Cache / Media locations for Flush All, homepage/menu warm-up, existing-media conversion, and full-site Warm Site.
* Update post-install JavaScript, CSS diagnostics, and query-string caching guidance to point to their current Frontend and Cache tab locations.
* Preserve the manual JavaScript troubleshooting loop with the new Frontend → JS Safeguards, Overview → Flush All, and Cache → Warm Cache paths for users who configure or debug without the automatic assistant.

= 2.59.13.28 =
* Reorganize the UltraCache dashboard into six primary tabs: Overview, Cache, Frontend, Media, Server, and Advanced.
* Add addressable `?tab=` dashboard URLs with browser Back/Forward synchronization so administrators can link directly to a subsystem without introducing separate admin pages.
* Keep existing cards and running job engines mounted while tab content is hidden, so warm-up, media conversion, setup, and diagnostics work is not interrupted by navigation.
* Add Overview quick actions for Apply Optimal Settings, Flush All Cache, and full-site Warm Site, alongside cache statistics and recent activity.
* Group page-cache/warm/query/exclusion/automation controls under Cache; JavaScript/CSS/fonts/LCP/WooCommerce under Frontend; media conversion and Media Library Replacement under Media; Object Cache/Varnish/LiteSpeed/OPcache/APCu/Nginx under Server; and diagnostics/profiler/testing/import-export/support under Advanced.
* Add responsive horizontal tab navigation for narrow WordPress admin layouts while preserving the existing card and accordion design inside each subsystem.

= 2.59.13.27 =
* Integrate the existing resumable Analyze HTML JS Dependencies workflow into both First-Run Setup and Apply Optimal Settings after automatic website preparation.
* Automatically apply only deterministic Strong Suggestions, respecting each scanner `preferredTarget`: use Defer Instead when sufficient, escalate to Do Not Defer or Delay when exclusion is required, and remove overlapping Defer Instead entries during that escalation.
* Run a bounded correction loop of scan → deterministic safeguard apply → cache purge / homepage and menu rewarm / full-site warm resume → rescan, with at most three correction passes and a final verification scan after the third applied pass.
* Add persistent singleton `javascript` and `verify` wizard stages so refreshes resume the correct setup phase and first-run setup is not marked complete until the administrator confirms the final visible-interaction check.
* Keep browser-runtime/console diagnostics and generic heuristic dependency suggestions manual; automatic setup never applies speculative JavaScript exclusions.
* Normalize successful setup progress state from the engine-level `done` value to the modal `complete` presentation state so finished Flush/Warm/JavaScript steps render with their completed checkmark instead of appearing to remain active.

= 2.59.13.26 =
* Automatically prepare the website after Apply Optimal Settings: run the existing Flush All pipeline, warm the homepage, warm the configured deterministic menu when available, and start or resume the existing background full-site warm orchestrator.
* Prepare existing Media Library conversion without resetting prior work by continuing the existing media queue rebuild/repair state and resuming background media processing.
* Extend the fresh-install wizard state with a singleton `prepare` step so configuration and preparation progress survives refreshes without adding job IDs, generations, or a parallel setup queue.
* Keep setup orchestration on the existing cache, warm-up, and media engines; no second warm or conversion implementation is introduced.

= 2.59.13.25 =
* Add a fresh-install-only First-Run Setup Wizard that opens automatically on the first UltraCache dashboard visit and never auto-opens for upgrades or existing installations.
* Persist one small wizard state (`status`, `current_step`, `completed_steps`, `last_error`, `updated_at`) so welcome/analyze/configure progress survives dashboard refreshes without job IDs, generations, or setup history.
* Reuse the existing read-only Setup Plan and Apply Optimal Settings engine inside the wizard instead of introducing parallel detection or configuration logic; an interrupted configure step can be resumed by safely rerunning the idempotent setup engine.
* Keep Not now non-destructive: closing the wizard does not mark setup complete, while a successfully applied configuration records the singleton wizard as completed and prevents future automatic opening.

= 2.59.13.24 =
* Make Apply Optimal Settings run the existing Media Library conversion test automatically and choose image formats from real sample results: prefer AVIF with WebP fallback when both pass, use AVIF with original fallback when only AVIF passes, use WebP when AVIF fails, and enable Convert new uploads only after a successful tested format.
* Preserve the existing image-format/upload-conversion settings when the Media Library test is indeterminate, while applying the deterministic media defaults of Compact compression and a 1920-pixel maximum upload side.
* Enable Local Google Fonts Optimization, Bundle Generated Font-Mix CSS, and Delay icon fonts as part of Optimal Settings.
* Apply WooCommerce empty-cart suppression and MailerLite lazy nonce refresh conditionally from the reviewed Setup Plan only when those integrations are detected; keep them disabled when not applicable.
* Update the Apply Optimal Settings review/progress UI and installation Help so media, font, and conditional integration steps are no longer presented as manual post-install work.

= 2.59.13.23 =
* Make Apply Optimal Settings automatically configure the deterministic site warm-up scope from the reviewed Setup Plan: select a clear primary/main/header frontend menu at Depth 1 and save Homepage / blog index, Selected menu URLs, Pages, Posts, and Categories when available.
* Preserve the existing warm-up menu selection when multiple assigned menus have no deterministic primary signal or no assigned frontend menu exists, instead of guessing or overwriting a user choice; still configure the deterministic non-menu full-site sources.
* Show the recommended warm menu and full-site sources in the Apply Optimal Settings review modal and add a dedicated warm-scope progress phase during Apply.
* Keep scheduled/cron warm limits and automation switches unchanged in this release; only the site-specific menu/depth/source scope is automated.

= 2.59.13.22 =
* Make Apply Optimal Settings run the existing live HTML Compression capability probe automatically, keep UltraCache compression off when the server already handles delivery, prefer Brotli then gzip when UltraCache must compress HTML, and preserve the current compression setting when the loopback result is indeterminate instead of guessing.
* Harden the compression probe contract by recording whether both Brotli and gzip loopback challenges completed, so failed/incomplete loopbacks are no longer treated as proof that the server is uncompressed.
* Complete automatic Object Cache setup with deterministic Redis → APCu → SQLite → Disk capability checks, drop-in configuration through the existing settings transaction, and a fresh-request runtime payload verification; restore the previous Object Cache configuration when final verification fails.
* Keep persisted Redis credentials and externally managed secrets out of client-side Optimal Settings capability probes so redacted password fields cannot override the real server-side credential during detection.

= 2.59.13.21 =
* Add a review-first Apply Optimal Settings modal that loads the read-only Setup Plan before any settings are changed and clearly separates detected environment capabilities from the configuration applied by the current Optimal Settings recipe.
* Show live setup-plan status for server, Object Cache candidate, compression, media encoder candidates, integrations, and primary-menu selection, while marking capabilities that still require later live validation instead of presenting them as already configured.
* Add phase-aware Apply progress for recommended settings, Object Cache verification/configuration, append-only JavaScript dependency safeguards, and completion; keep the modal open with explicit success or failure state instead of applying directly from the dashboard card.

= 2.59.13.20 =
* Add a read-only Setup Detection / Planning Engine with a dedicated REST plan endpoint for server, object-cache, compression, media, integration, external-cache, menu, and warm-up capability mapping.
* Produce deterministic recommendations for Object Cache priority, compression verification, media format candidates, conditional WooCommerce/MailerLite setup, primary-menu selection, and default warm-up sources without applying or persisting UltraCache settings.
* Keep live compression, Object Cache, and image-conversion verification explicitly pending for the later setup stages instead of guessing from extension availability alone.

= 2.59.13.19 =
* Replaced the settings Profile presets with a single Apply Optimal Settings workflow based on the former Aggressive configuration.
* Removed All Off, Safe, Balanced, Aggressive, Custom matching/preset UI and their settings-profile selection logic.
* Apply Optimal Settings preserves infrastructure credentials, schedules, exclusions, safeguards, and user-maintained lists while keeping append-only Defer dependency defaults and deterministic Object Cache detection.

= 2.59.13.18 =
* Fix the WordPress 6.7+ early translation-loading notice by moving the public warm-runtime upgrade reset from plugins_loaded to early init, so UltraCache translations are not triggered before the supported lifecycle point.

= 2.59.13.17 =
* Fix the PHP 8.4 implicit-nullable deprecation in the Media Conversion Test REST endpoint by declaring its optional WP_REST_Request parameter explicitly nullable.

= 2.59.13.16 =
* Make Media Library Replacement tables explicitly use InnoDB instead of inheriting the server default storage engine, and keep the two widest reference indexes below the 1000-byte MyISAM key ceiling by storing table identifiers at their 64-character database limit and indexing the first 160 characters of row identity.
* Replace the schema-upgrade SQL MD5() backfill with bounded PHP md5() batches so replacement schema setup remains compatible with database servers where the legacy SQL MD5 function is unavailable.

= 2.59.13.15 =
* Make Strong lifecycle suggestions emitter-timing-aware: classify strong event emissions as immediate, DOM-ready, window-load, deferred callback, unknown, or mixed; suppress callback/unknown/mixed races, keep Delay-to-Defer recommendations for DOM-ready/window-load emitters, and escalate truly immediate blocking emissions to Do Not Defer or Delay.
* Persist emitter timing evidence in the per-file JavaScript analysis cache with a parser-version bump, and fix blank emitter labels to fall back to script id/source when the WordPress handle is empty.

= 2.59.13.14 =
* Remove the obsolete 80-file content-analysis ceiling from the resumable Analyze HTML JS Dependencies workflow so every prepared local JavaScript candidate is processed before dependency evidence is correlated.
* Keep each iteration bounded to at most 10 JavaScript files and the existing ~1.8 second runtime budget, preserving resumable execution without truncating larger page inventories.
* Keep Strong Suggestion heuristics, stable evidence identity, exact safeguard actions, persistent analysis cache, resume/integrity checks, progress popup, and Help guidance otherwise unchanged.

= 2.59.13.13 =
* Fix resumable Analyze HTML JS Dependencies evidence correlation to bind lifecycle findings to a stable per-script identity instead of persisted numeric inventory indexes, preventing stripped inline-script bodies from compacting the inventory and assigning listener/emitter evidence to the wrong script. Older in-flight evidence jobs are rejected and must be rescanned.
* Make exact Strong Suggestion actions write exactly the displayed suggested handle/path to Defer Instead or Do Not Defer or Delay; plugin/theme path expansion is now reserved for Defer Chain and Exclude Chain actions.
* Keep Strong Suggestion heuristics, batching, persistent analysis cache, progress popup, and the 2.59.13.12 Help guidance otherwise unchanged.

= 2.59.13.12 =
* Add a post-install Help subsection beneath the JavaScript console-check steps for cases where the Console is clear but page functionality still fails, directing administrators to Analyze HTML JS Dependencies and warning against blindly applying every suggested safeguard.
* Keep the JavaScript analyzer, Strong Suggestions heuristics, batching, cache, resume, progress popup, and safeguard behavior unchanged.

= 2.59.13.11 =
* Fix Analyze HTML JS Dependencies settings-integrity fingerprinting to read the canonical UltraCache runtime settings array instead of the REST settings response object, eliminating the array_key_exists() type error introduced in 2.59.13.09; also allow the saved scan URL to be restored during dashboard-refresh resume without reassigning a const.
* Surface the resumable HTML JS dependency scan through the shared Warm/Media progress popup, with phase, page-script, local-file, processed-file, persistent-cache-hit, and freshly parsed-file progress while retaining the existing inline diagnostic status.
* Keep the 2.59.13.10 Strong Suggestions heuristics, batching, persistent per-file evidence cache, resume behavior, and settings-change invalidation semantics unchanged.

= 2.59.13.10 =
* Harden Analyze HTML JS Dependencies Strong Suggestions so only deterministic execution-order contradictions are promoted: delayed listeners/providers must be provably later than blocking/deferred counterparts, while uncertain async races remain outside the focused Strong stream.
* Suppress lifecycle self-correlation for duplicate inventory representations of the same script, and merge multiple independent lifecycle/dependency signals for one target into a single ranked Strong Suggestion with an evidence count instead of duplicate findings.
* Prioritize unsafeguarded multi-signal findings, keep lifecycle evidence ahead of declared-dependency-only evidence, and cap the focused Strong result set at eight actionable scripts without changing the broader Runtime/Console diagnostic heuristics.

= 2.59.13.09 =
* Add phase-aware Analyze HTML JS Dependencies progress reporting with page-inventory, local-file, processed-file, persistent-cache-hit, and freshly parsed-file counters while preserving the bounded 2.59.13.08 evidence pipeline.
* Persist a browser-session resume hint for the active HTML dependency job and automatically continue the same server-authoritative job after an administrator dashboard refresh; the existing same-URL server deduplication remains the fallback when browser session state is unavailable.
* Bind every scan to a fingerprint of the JavaScript execution-order settings used to build its page profile and inventory, revalidate that fingerprint during batches and before publishing Strong Suggestions, and stop with an explicit fresh-scan requirement if the configuration changes mid-run.

= 2.59.13.08 =
* Consolidate the resumable Analyze HTML JS Dependencies path around one compact per-script evidence registry instead of persisting separate listener/emitter maps, so every readable local JavaScript file contributes one normalized evidence record from either the persistent cache or the bounded scanner.
* Build final lifecycle correlation and Strong Suggestions from that shared registry without reopening or reparsing JavaScript files, while retaining the existing declared WordPress dependency-edge analysis from the same page inventory.
* Keep 2.59.13.07 in-flight scan compatibility by translating the previous persisted listener/emitter maps at correlation time, and expose single-pass evidence counters in the completed diagnostic result without changing suggestion heuristics.

= 2.59.13.07 =
* Add persistent per-file lifecycle-analysis caching for Analyze HTML JS Dependencies using UltraCache revisioned state storage, keyed by normalized local file path and validated by file mtime, filesize, and parser version.
* Reuse only compact extracted listener/emitter evidence for unchanged local JavaScript files; never persist JavaScript bodies, and automatically reanalyze and replace a cache row when the source fingerprint changes.
* Track cache hits, misses, and writes in the resumable scan result, and clear the JS analysis cache at the canonical Flush All clean-slate boundary while retaining the 2.59.13.06 batching and 2.59.13.05 Strong Suggestions behavior.

= 2.59.13.06 =
* Make Analyze HTML JS Dependencies use a dedicated resumable action job so page preparation, bounded local-JavaScript analysis batches, and final evidence correlation no longer run as one monolithic Strong Suggestions request.
* Process at most 10 readable local JavaScript files per lifecycle-analysis iteration with a short runtime budget, persist the cursor plus compact listener/emitter evidence between requests, resume the same URL job after an interrupted dashboard session, and skip the legacy monolithic JS safety file pass during this dedicated scan.
* Keep the 2.59.13.05 Strong Suggestions heuristics and output contract unchanged, avoid the global heavy-action lock for the resumable analyzer, and keep inline script bodies out of persisted scan state.

= 2.59.13.05 =
* Add a focused Strong Suggestions stream to Analyze HTML JS Dependencies so high-confidence silent Delay/Defer execution-order conflicts are surfaced separately from broad compatibility heuristics.
* Extend local JavaScript lifecycle analysis to resolve generic event-dispatch wrapper methods that forward literal lifecycle names into dispatchEvent(new CustomEvent/Event(...)), allowing missed one-time initialization events to be detected without hardcoded plugin exceptions.
* Prefer the exact WordPress script handle for Strong Suggestions when available, deduplicate by script, prioritize lifecycle conflicts, and cap the focused result set so actionable findings are not buried under low-value matches.

= 2.59.13.04 =
* Update the WordPress.org Donate link to the UltraCache page at https://iniotakis.com/ultracache/.
* Update installation step 14 to enable Warm uncached URLs after first visit under Warm Cache.

= 2.59.13.03 =
* Extend Console Error Handler diagnostics with the actual WordPress script dependency graph from the selected page and compare each declared edge against the final Delay/Defer/blocking strategy applied by UltraCache.
* Inspect readable same-site JavaScript files for lifecycle listener/emitter relationships so one-time initialization order risks can be proposed even when the browser produces no console error.
* Keep an exact script visible when the same runtime error persists after it is already listed in Do Not Defer or Delay; distinguish a safeguard that is still optimized in final HTML from a fully blocking script whose dependency chain still needs investigation.
* Add dedicated dependency-risk and persistent-failure diagnostic buckets without adding hidden compatibility exceptions or changing either safeguard list automatically.

= 2.59.13.02 =
* Add per-page Elementor generated-CSS dependency reconciliation to the shared final cache-storage path. UltraCache dynamically discovers Elementor `post-{id}.css` references in each rendered page, regenerates only missing referenced files through Elementor's own `Post_CSS::create($post_id)->update()` contract, verifies the physical file, and refreshes the dependency version before page-cache storage.
* Apply the same dependency contract to normal frontend STORE requests and shared warm writes. Unresolved Elementor CSS dependencies prevent UltraCache from storing that broken HTML variant instead of publishing a cache entry that references missing generated CSS.
* Keep Elementor cache ownership with Elementor: no global Elementor CSS regeneration is introduced. Optional Elementor Flush All still uses Elementor's native clear; CSS is rebuilt per page as each URL is visited or warmed.
* Correct Elementor help/FAQ text so Element Cache expiration is described as element-output lifetime, not generated-CSS lifetime.
* Make the two atomic schema-install `add_option()` calls use the explicit prefixed `ultracache_locks_schema_install_lock` option name so WordPress.org static review can verify the namespace without changing lock semantics.

= 2.59.13.01 =
* Fix the first-visit background warm runtime setting lookup so the enabled dashboard switch is read through the canonical snake_case runtime settings contract after a successful frontend STORE.
* Preserve the existing post-response enqueue boundary, shared targeted warm pipeline, Background warm pages per minute rate, and configured Varnish/LiteSpeed warm stages; no options or queue semantics are changed.

= 2.59.12.99 =
* Detect active Elementor as a supported native cache layer and add an opt-in Also flush Elementor Cache switch under External Cache Flush.
* Clear Elementor through its native files manager before UltraCache removes page cache, suppress the resulting self-originated Elementor callback, and let existing warm-after-flush work start only after both cache layers are invalidated.
* Add FAQ guidance recommending a 1 Year Elementor Element Cache expiration for mostly static sites without changing Elementor settings automatically.

= 2.59.12.98 =
* Defer Elementor generated-file invalidation reconciliation until shutdown so multiple clears in one request coalesce after the final clear, then run one canonical UltraCache Flush All and the existing configured warm behavior.
* Add narrowly scoped PHPCS SchemaChange ignores, with explicit versioned custom-table index-repair justification, to the eight intentional legacy index migration statements.

= 2.59.12.97 =
* Flush the canonical UltraCache page-cache layers when active Elementor clears its generated public files, preventing cached HTML from retaining references to removed Elementor CSS files.
* Reuse the existing Flush All warm behavior after Elementor invalidation; no Elementor-specific warm queue or crawler is added.
* Remove the Elementor Element Cache FAQ recommendation because disabling that separate cache does not prevent Elementor generated-file invalidation.

= 2.59.12.96 =
* Replace dynamic media queue and Media Library Replacement blocker `IN (...)` SQL construction with bounded 20-row batches whose complete placeholder sets are declared directly in each prepared query.
* Pass every affected prepared statement directly to the matching `$wpdb` read/write method, eliminating ambiguous intermediate query variables and replacement-count reports without suppressing database checks.
* Preserve the existing bulk operation semantics, table-identifier validation, blocker decisions, queue resets, cleanup, and readiness diagnostics.

= 2.59.12.95 =
* Align the runtime `ULTRACACHE_VERSION` constant with the installed plugin version so administrator JavaScript and CSS assets use the current cache-busting query value.
* Ensure the corrected automatic warm-up popup guidance is loaded immediately after upgrading instead of reusing the cached 2.59.12.93 `ui.js` asset.

= 2.59.12.94 =
* Correct the setup help popup so automatic warm-up guidance points to Warm full site after Flush All Cache and/or Warm uncached URLs after first visit instead of the unrelated scheduled-cleanup option.

= 2.59.12.93 =
* Add an optional Warm uncached URLs after first visit switch that queues the first cold frontend URL into the shared background warm pipeline, coalesces with on-visit CSS bundle work, uses the configured Background warm pages per minute rate, and completes the same enabled external-cache stages as full-site warming.
* Restore a locked LCP mapping as an immutable terminal boundary: missing request-credentials metadata no longer reopens frontend observation for that viewport.
* Remove the credentials-only update path that could modify a locked LCP row and trigger a targeted purge or LCP refresh without an explicit Forget mapping or Relearn action.
* Keep runtime image request credentials observation inside the normal Learning cycle only; existing locked mappings with an unknown mode remain unchanged until the administrator explicitly starts a new learning cycle.

= 2.59.12.91 =
* Extend the existing frontend LCP discovery cycle, only when Fix sliders / hero sections and LCP Image Priority are active, to observe the actual runtime image request credentials mode used for the LCP image URL.
* Suppress speculative slider/hero image preloads while the credentials mode is unknown; after browser observation, persist `none`, `anonymous`, or `use-credentials` and refresh only the affected page through the existing targeted LCP refresh queue.
* Emit browser-observed image preloads with the exact persisted `crossorigin` contract, skip preloading when the runtime mode is unavailable or conflicting, and keep non-slider pages on their existing preload behavior.
* Reopen legacy locked LCP mappings only for their missing credentials field, without relearning the LCP resource or triggering a full-site flush/warm cycle.

= 2.59.12.90 =
* Add FAQ guidance to disable Elementor Element Cache when UltraCache Page Cache is active, while keeping Elementor CSS Print Method on External File and running one Clear Files & Data, Flush All, and Warm Cache cycle after the change.
* Add FAQ guidance for strict color fidelity: disable Ignore color profile preservation; images whose embedded profile cannot be verified or preserved may remain in their original JPG/PNG format instead of being converted to AVIF/WebP.
* Enable Ignore color profile preservation by default in the Aggressive performance profile to maximize AVIF/WebP conversion coverage; Safe, Balanced, and All Off retain strict profile preservation.

= 2.59.12.89 =
* Remove the canonical Media Library Replacement singleton workflow option during dashboard Delete All cleanup and normal WordPress uninstall.
* Repeat deletion of the singleton workflow option in the uninstall final cleanup pass so a loaded shutdown callback cannot leave completed replacement state behind after the custom tables are dropped.
* Prevent a clean reinstall from displaying stale Preparation Complete, Replacement Applied, Verify, or Delete state from a workflow that belonged to the removed installation.

= 2.59.12.86 =
* Record resumable Theme CSS checksum validation with the canonical `validated` status instead of the incompatible `seen` value.
* Keep post-apply Theme CSS inventory persistence on the same canonical validation status so the inventory has one status contract.
* Remove the false "Theme CSS files disappeared" failure caused by the validator writing a status that the final file-set parity query did not recognize.

= 2.59.12.85 =
* Count deferred blocker sibling rows as part of the same canonical registry inventory, keeping registry/readiness parity stable after an affected attachment moves from matched to blocked_dependency.
* Persist registry completion as a durable singleton workflow milestone with the validated registry and readiness variant counts.
* Prevent a later Prepare request from repeating the initial registry consistency phase after blocker deferral; resume directly from file-copy planning without jobs, generations, or alternate state sources.

= 2.59.12.84 =
* Preserve the completed singleton readiness inventory when Prepare initializes the replacement registry instead of replacing the canonical readiness section with an empty default array.
* Make the final Prepare consistency check compare registry variants against the same persisted readiness snapshot that authorized Prepare, fixing false registry/readiness results such as 6654/0 after a complete scan.
* Keep readiness and Prepare in one canonical workflow option without reintroducing jobs, generations, fallback state sources, or browser-side workflow selection.

= 2.59.12.83 =
* Make deletion of Prepare-created replacement destinations best-effort during Restart so an unlink failure cannot block the authoritative reset of the one Media Library Replacement workflow.
* Continue clearing all six replacement tables, blocker decisions, plans, cursors, confirmations, and canonical workflow state after best-effort destination cleanup; the next Prepare re-evaluates any remaining file through the normal filesystem plan.
* Preserve the hard Restart boundary after destructive Do work has started and keep overwrite-backup restoration fail-closed.

= 2.59.12.82 =
* Make Restart Replacement Plan an authoritative reset of the one Media Library Replacement workflow without publication-contract versions, destination-ownership proofs, job provenance, or legacy-plan compatibility gates.
* Restore overwrite backups and remove destinations recorded as created during the current Prepare directly from the singleton registry, then clear all replacement tables, blocker decisions, plans, cursors, confirmations, and persisted workflow state.
* Preserve the existing block after destructive Do work has started, where rollback evidence is still required before any reset.

= 2.59.12.81 =
* Replace the Media Library Replacement execution-instance model with one canonical persisted workflow state shared by Prepare, blocker decisions, Do, Verify, Delete Originals, recovery, and status polling.
* Remove functional job IDs and generations from replacement REST requests, responses, SQL selection, React state, pagination, previews, CLI operations, and destructive authorization; retain legacy schema columns only as blank compatibility fields until a later schema-only cleanup.
* Make Restart clear all current replacement rows, blocker decisions, database/file/metadata/Theme CSS plans, nested cursors, confirmations, and workflow state, while preserving rollback evidence by refusing an unsafe reset after destructive Do work has begun.
* Make the blocker badge and atomic modal consume the same singleton backend truth, and isolate database, cleanup, and Theme CSS previews from authoritative workflow status.
* Persist readiness, database indexing, intermediate expansion, Theme CSS scanning, streaming, validation, and resumable cursors inside the canonical state; bind just-in-time destructive confirmation to the current plan fingerprint so cross-session continuation does not depend on browser or token lifetime.
* Preserve the bounded database reference extractor and inline data-URI exclusion introduced in 2.59.12.77 without changing its implementation bytes.

= 2.59.12.80 =
* Replace the separate Decide Blockers payload and open flags with one atomic modal state so the verified blocker response and the visible modal are committed in the same React state transition.
* Let the blocker endpoint select the server-active replacement job on initial open, lock pagination to the returned job, validate the response contract, and refuse to render an open modal without a real payload.
* Stop database, Theme CSS, and cleanup preview responses from overwriting the authoritative Media Library Replacement workflow status, and make periodic status refresh resolve the active job on the server.
* Preserve loaded blocker decisions across pagination while replacing them cleanly on the first modal load, without changing blocker rows, decisions, Prepare, Do, or database contracts.

= 2.59.12.79 =
* Remove short-lived database and Theme CSS confirmation tokens from Prepare planning validation, the final pre-Do guard, and prepared-plan validity so a completed plan remains actionable hours or days later.
* Suppress destructive token issuance from internal Prepare and recovery previews while retaining fresh confirmation tokens for explicitly invoked standalone preview/apply endpoints.
* Issue and consume a fresh database or Theme CSS start token inside the first authenticated Do chunk for that phase, then persist durable job/generation authorization for every later resumable chunk.
* Allow paused Do recovery to resume after the token TTL or from a later authorized administrator session without weakening registry, destination-file, metadata, database, Theme CSS, generation, or fingerprint guards.

= 2.59.12.78 =
* Make the authoritative active workflow status job ID take precedence over stale mapping, database, blocker, or cleanup preview job IDs when dashboard actions resolve the current Media Library Replacement job.
* Clear blocker payloads, decisions, and every replacement preview/modal state after Restart Replacement Plan so a previous job cannot remain attached to a newly prepared job in React state.
* Replace blocker decisions on the initial modal load and merge them only during pagination, preventing React batching from restoring decisions retained by an earlier job.
* Reject blocker responses whose returned job ID differs from the requested active job instead of presenting an empty Decide Blockers modal against the wrong replacement plan.

= 2.59.12.77 =
* Replace whole-value global PCRE image-reference extraction with one deterministic bounded byte scan, preventing large inline data-image payloads from trapping Media Library Replacement Prepare in CPU-bound backtracking after nginx has returned 504.
* Ignore inline data URIs because they are embedded payloads rather than replaceable Media Library files, while retaining exact raw database fragments for Apply and Verify.
* Reuse the existing reference normalization, uploads-path resolution, prepared database index, matching, Apply, and verification contracts without changing SQL pagination, escaping, blocker decisions, or adding development-version migration code.
* Preserve existing reference coverage for HTML, CSS url(), absolute and protocol-relative URLs, JSON-escaped slashes, query strings, fragments, and srcset-style values without creating a second full unescaped copy of each database value.

= 2.59.12.76 =
* Replace unbounded leading-wildcard Media Library Replacement database candidate searches with adaptive, bounded primary-key windows; image predicates execute only inside the resolved row range, while unsupported table shapes retain bounded raw-row OFFSET traversal.
* Make reference-index replay idempotent with INSERT IGNORE, advance progress by physical rows scanned rather than matching references found, keep database-match work out of the denominator until indexing completes, and expose the current table, column, cursor, scanned rows, and query duration.
* Continue the complete non-destructive Prepare discovery and planning flow when blocker rows exist. Defer every sibling row of an affected attachment to prevent partial file or metadata plans, then open Decide Blockers only after database and Theme CSS planning completes.
* Finalize group and per-file blocker decisions without starting Apply: whole-attachment exclusions proceed directly to the final pre-Do guard, while verified-overwrite decisions reactivate only affected attachments and rebuild their file, database, and Theme CSS plans.

= 2.59.12.73 =
* Stop the Prepare dashboard runner immediately when the server enters decisions_required, close the active progress panel, release the Prepare lease, and expose Decide Blockers without repeatedly calling the same Prepare phase.
* Remove redundant per-chunk replacement status GET requests from Prepare and treat the final status refresh as non-fatal, preventing transient nginx/PHP-FPM 502 responses from turning persisted Prepare progress into a dashboard failure.
* Add per-file blocker decisions beneath each group policy. Group decisions provide the scalable default, while paginated individual rows can override that policy before one atomic save.
* Keep Save Decisions limited to decision persistence and Prepare completion. Apply remains disabled until Prepare finishes and always requires a separate explicit click.

= 2.59.12.72 =
* Add a Prepare → Decide Blockers → Apply Media Library Replacement workflow: Prepare freezes actionable conversion and destination blockers instead of treating them as technical Prepare failures, and Apply remains locked until every blocker group is resolved.
* Persist blocker code, detail, generation, group decision, administrator, and decision time on the prepared physical registry; support keeping affected attachments as originals and overwriting different existing destinations through the existing verified backup contract.
* Add a grouped blocker decision modal using the existing replacement-preview layout, summary cards, server-side pagination, group-level actions, and per-unit details so large libraries require one decision per blocker class instead of one decision per image.
* Remove the global Existing destination files policy from the main Media Library Replacement settings; identical verified destinations remain automatic, while actual collisions are discovered by Prepare and presented only when they exist.
* Exclude keep-original attachments from file copy, metadata planning, database and Theme CSS matching, verification, and original deletion while retaining them in the frozen decision audit trail.

= 2.59.12.71 =
* Make replacement readiness prefer an authoritative persisted semantic skip for an exact physical source/format over stale pending duplicates from compatible parent requests.
* Carry physical-unit skip reason and detail through readiness blocker signatures, responses, progress messages, and dashboard diagnostics so deterministic unsupported variants report their real conversion blocker.
* Prevent replacement readiness from requeueing an exact unit already resolved as a terminal semantic skip while continuing to block Prepare until the required target file can actually be generated.

= 2.59.12.70 =
* Persist deterministic physical-unit semantic skips with their exact reason, detail, source fingerprint, and conversion-context signature so missing targets do not reopen unchanged skipped work.
* Reattempt a persisted semantic skip only after the source descriptor/fingerprint changes, the conversion context changes, or an explicit regeneration resets the unit.
* Reconcile terminal attachment parents that still contain nonterminal child units and derive completion from the authoritative child aggregate instead of leaving skipped/done parents with pending units.
* Stop WP-CLI media processing after repeated identical persisted queue signatures, preventing parent/unit attempt counters from masking a no-progress state-machine loop.

= 2.59.12.69 =
* Restored the intermediate attachment metadata verification helper used by replacement Verify and cleanup inspection after the attachment-level metadata apply refactor.

= 2.59.12.68 =
* Apply Media Library Replacement attachment metadata through one authoritative old-to-final plan per attachment instead of separate main-image and intermediate-size writes to the same serialized metadata value.
* Add an additive per-attachment metadata-plan registry that preserves active version 13 jobs, materializes plans during Prepare, and lazily materializes plans when resuming jobs created by earlier builds.
* Fix false Do consistency failures where UltraCache interpreted its own already-applied thumbnail metadata changes as external attachment changes.
* Support deterministic recovery from persisted partial states created by older runs while continuing to reject unknown filename, MIME, metadata, or custom-field changes made after Prepare.
* Count metadata Do progress by attachments with a stable total while retaining per-file registry rows for file verification, reference replacement, diagnostics, and rollback evidence.

= 2.59.12.67 =
* Keep the failed Prepare Replacement button disabled while replacing its technical-only tooltip with the actionable recovery path: open Advanced / Manual Recovery, run “Restart Replacement Plan”, and then run “Prepare Replacement” again.
* Display the same Prepare failure recovery guidance persistently below the disabled button so the next action remains visible without mouse hover or on touch devices, while leaving all Manual Recovery logic and enablement unchanged.

= 2.59.12.66 =
* Make Media Library Replacement Prepare consistency authoritative to persisted registry rows and readiness unique variants instead of transient scan-level skipped counters, preventing attachments without intermediate metadata or ignored non-physical metadata slots from falsely failing Prepare.
* Treat absent intermediate sizes and invalid non-physical metadata slots as no-work inventory entries rather than replacement blockers; continue to persist and block on real missing/unreadable source files, invalid generated outputs, registry skipped rows, insertion failures, and registry/readiness mismatches.
* Report registry skipped/failed rows and scan insertion failures explicitly in Prepare consistency errors so a server-backed failure identifies the authoritative blocker class.
* Keep the readiness progress popup open after terminal conversion blockers and append the requested recovery action: run “Scan Media Library & Repair Status” and rerun “Start / Resume Conversion”.

= 2.59.12.65 =
* Reconcile attachment parent state immediately after cooperative interruption, administrator pause, Retry Failed, fatal-shutdown recovery, and stale-worker recovery so dashboard, WP-CLI, readiness, and background workers resume from the same persisted physical-unit aggregate.
* Make exact child-unit shutdown recovery authoritative for the parent recovery status and stale-recovery generation, preventing parent and main/thumbnail retry budgets from diverging after a terminated worker.
* Clear obsolete encoder-attempt evidence whenever a unit is returned by a worker-level pause, interruption, or stale recovery, preserving the exact worker failure reason instead of displaying encoder diagnostics from an earlier conversion attempt.
* Resume background dispatch after a dashboard manual session ends when attachment work, local assets, physical units, queue build, or lazy unit inventory still require progress; do not depend only on attachment-level pending rows.
* Harden cross-surface recovery contracts for UI-to-WP-CLI and WP-CLI-to-UI handoff, output-written-before-claim-loss reconciliation, terminal retry limits, legacy false-done repair, metadata superseding, and independent AVIF/WebP unit state without changing the parent or child schemas.

= 2.59.12.64 =
* Stop Prepare Replacement readiness deterministically when a complete pass still has queueable variants but produces no enqueue, physical-unit attempt, generated output, unit-state transition, or blocker-set change; complete with blockers instead of starting an unbounded verification pass.
* Persist a deterministic blocker signature across readiness chunks and passes, including attachment, physical file, status, attempts, failure code/stage/detail, so repeated unresolved state is observable and resumable without arbitrary pass limits.
* Read readiness state from exact physical AVIF/WebP child units across compatible exact, best, and both parent policies, preserving per-file failure details and preventing attachment-level success from hiding a failed main image or thumbnail.
* Report the first exact blocked attachment, main/intermediate source path, persisted failure code, and failure detail in the readiness response and dashboard while keeping Media Library replacement locked until every required output is valid and current.

= 2.59.12.63 =
* Add authoritative physical-unit status counters joined to attachment parent policies, including materialized-parent coverage, pending/processing/done/failed/skipped units, retry-pending units, required totals, outstanding work, and completion that remains false while lazy inventory coverage is incomplete.
* Separate legacy parent-row touches from completed attachments and physical-unit attempts in batch results; report attachment/local-asset terminal outcomes, resolved/generated units, retryable unit failures, and terminal unit failures without changing attachment-level queue semantics.
* Make WP-CLI process, rebuild, process-batch, and scoped-ID output use the exact aggregate counters, remove ambiguous attachment wording, and refuse completion while either parent rows or physical units remain failed.
* Count readiness generated units only from successfully generated AVIF/WebP outputs rather than attempted units, while retaining legacy response aliases for compatibility with existing REST/background consumers.
* Keep dashboard batches, maintenance dispatch, cron fallback, and WP-CLI active while lazy physical-unit inventory is incomplete even when no attachment parent is currently pending; expose exact coverage and wait-state diagnostics instead of reporting premature completion.
* Avoid duplicate reconciliation inside one process batch, exclude terminal skipped parents that require no physical inventory from coverage debt, and report migration failures as explicit incomplete work rather than silently advancing counters.

= 2.59.12.62 =
* Route dashboard, REST, WP-CLI, Media Library Replacement readiness, and background attachment processing through one authoritative physical-unit worker; remove the CLI whole-attachment shortcut and process one persisted main/thumbnail output unit per claim.
* Persist exact per-file success, semantic skip, retryable failure, terminal failure, encoder-attempt evidence, source fingerprint, attempt count, and stale-worker recovery state before any later unit can run.
* Derive each attachment parent status only from active child-unit rows, forbid done when any required main image or thumbnail remains pending/failed, and trigger affected-page processing only after the complete parent reaches a successful terminal state.
* Extend pause, retry, explicit regeneration, cooperative interruption, fatal-shutdown recovery, and stale-claim recovery to child units while retaining the attachment-level parent queue, local-asset execution, UI attachment counters, and existing schema versions.

= 2.59.12.61 =
* Lazily materialize physical conversion units for existing attachment queue rows during rebuild, execution, Media Library Replacement readiness, and bounded administrator/CLI maintenance while leaving local-asset rows atomic and unchanged.
* Reconcile every active unit against its exact source and target files: validate format headers and freshness, mark current outputs done, keep missing/stale/invalid outputs pending, classify unsupported mappings as skipped, and supersede obsolete metadata units.
* Recompute attachment parent state from reconciled child units so a legacy done/skipped row cannot remain complete while a required main image or thumbnail is missing; preserve terminal failed parents until explicit retry unless all required outputs are already valid.
* Keep child rows synchronized after the legacy attachment worker persists a result, remove child rows with parent rebuild/clear operations, and clean bounded orphan units plus persistent migration state without changing UI attachment counters or activating child-unit claims yet.

= 2.59.12.60 =
* Add a dedicated persistent physical media conversion unit table keyed to the existing attachment-level parent queue without changing current UI, REST, WP-CLI, background-worker, retry, local-asset, or replacement execution semantics.
* Build deterministic main and intermediate source inventories that expand best/both policies into concrete AVIF/WebP units, persist exact source and target paths plus fingerprints, and remain idempotent across repeated synchronization.
* Supersede obsolete physical units when attachment metadata changes, reactivate changed source fingerprints as pending work, and retain the parent queue as the stable aggregate/request contract for the later per-unit worker migration.
* Register the new operational table with UltraCache table validation, activation schema checks, plugin-data cleanup, uninstall cleanup, and Media Library Replacement operational-state exclusion.

= 2.59.12.59 =
* Release cooperative local-asset early-return claims immediately back to pending without consuming failure budgets, and recover fatal/terminated PHP shutdown claims automatically; quarantine only repeated real worker terminations after the persistent recovery budget is exhausted.
* Make Retry Failed recover abandoned processing rows as well as terminal failed rows under the exclusive media-process lease, expose recoverable interrupted work to the dashboard, and dispatch the queue immediately after administrator recovery.
* Order pending media work by the lowest attempt count before row identity so a retried AVIF or WebP unit cannot starve another pending format for the same source.
* Add the Images & Media Library FAQ guidance for theme/plugin images that remain JPEG or PNG, while preserving original local files and the existing rewrite, encoder, replacement, and schema contracts.

= 2.59.12.58 =
* Fix local theme, plugin, mu-plugin, and WordPress-includes media jobs remaining in processing before encoder execution when the guarded source-fingerprint UPDATE matched the active claim but changed no stored values.
* Treat MySQL/MariaDB zero changed rows as a valid no-op only after an exact id, status, attempts, and started-at claim verification; retain stale-claim rejection when that authoritative claim no longer exists.
* Preserve the existing local-source resolver, generated identity, shared media queue, AVIF/WebP encoders, affected-page fence, Media Library Replacement, and schema versions without adding a migration.

= 2.59.12.57 =
* Repair the media queue schema 4-to-5 upgrade by adding source-request uniqueness only after legacy attachment rows receive their canonical source identity and requested-format values.
* Replace MariaDB-incompatible SHOW INDEX WHERE ... LIMIT probes with full index metadata inspection, and rebuild the legacy unique attachment indexes as the required non-unique lookup indexes without duplicate-key attempts.
* Make media queue and affected-page reference upgrades idempotent across fresh, legacy, and partially applied schemas, deduplicating only identical canonical work identities before creating the final unique indexes.
* Advance the media queue schema to 6 and affected-page reference schema to 3 while preserving queued attachment/local-asset work, statuses, retries, source fingerprints, and page-purge requirements.

= 2.59.12.56 =
* Complete the integrated local-image rewrite and WordPress-aware wp_options replacement regression candidate across canonical WordPress-derived source resolution, collision-free local-asset variants, the shared media queue, HTML/CSS/LCP surfaces, option identity, cache synchronization, concurrency, recovery, and rollback.
* Match native WordPress option action sequencing around the byte-exact writer: publish the generic update_option action immediately before the atomic SQL mutation, then publish the option-specific update action and updated_option only after the database and runtime cache state are verified.
* Preserve the established Media Library uploads generated identity byte-for-byte, keep Media Library Replacement scoped away from theme/plugin originals, retain schema 13 without migration, and keep local-asset work isolated from attachment rebuild and repair operations.
* Add one integrated release gate covering executable identity/freshness/option-writer behavior, source-contract parity, complete PHP syntax, release metadata, package root, archive integrity, and exclusion of development tests from the installable ZIP.

= 2.59.12.55 =
* Keep every persisted WordPress option reference on the dedicated option-aware writer even when the active multisite blog context changes after Prepare Replacement; never fall through to the generic database-row writer.
* Bind Apply, verification repair, recovery, and rollback to the exact current $wpdb->options table and fail closed with a specific context-change result before any database mutation.
* Expand executable regression coverage for autoloaded and non-autoloaded raw, serialized, and JSON-like options, alloptions/notoptions synchronization, persistent cache invalidation, filter mutation, reused IDs, multisite context drift, concurrent compare-and-swap conflicts, and rollback parity.
* Preserve Media Library Replacement schema 13 and the 2.59.12.54 option-name identity contract without adding a migration or changing non-option database replacement behavior.

= 2.59.12.54 =
* Route Media Library Replacement writes to the current WordPress options table through a dedicated option-aware compare-and-swap adapter instead of the generic database-row writer.
* Persist the exact option name with each indexed and planned option reference, block legacy or reused option IDs without matching identity, and preserve byte-exact concurrent-writer protection.
* Synchronize per-option, alloptions, notoptions, and persistent object-cache state after apply, verification repair, recovery, and rollback; verify the exact cached value before completion.
* Run WordPress option sanitization and pre-update filters before the atomic write, reject transformed plans, and publish the standard option update actions only after the database and runtime cache state are verified.
* Upgrade Media Library Replacement schema 12 to 13 additively without discarding existing registry rows; option plans created before the identity contract require a fresh Prepare step.

= 2.59.12.53 =
* Route full-document and filtered-fragment image admission through the canonical WordPress-derived local-source roots, restoring theme, plugin, mu-plugin, and WordPress-includes rewrite parity without changing Media Library Replacement scope.
* Share one side-effect-free exact-source AVIF/WebP lookup across HTML attributes, srcset, inline and external CSS, Slider Revolution image attributes, LCP candidate preference, and LCP preload equivalence while preserving existing uploads and local-asset identities.
* Extend supported semantic image surfaces with lazy srcsets, Slider image data attributes, and video posters, keep foreign/non-image/metadata/download contexts unchanged, and retain lookup-only frontend behavior with the existing local-asset queue.

= 2.59.12.52 =
* Extend the existing persistent media queue with canonical local-asset work rows for theme, plugin, mu-plugin, and WordPress-includes image sources without creating a second queue or attachment record.
* Re-resolve each local public source through the existing WordPress-derived path contract before encoding, bind work to canonical source identity plus exact requested format and source fingerprint, and keep frontend requests lookup-only.
* Reuse the established AVIF/WebP encoder, admission, color-profile, orientation, animation, atomic output, retry, stale-worker, affected-page purge, and background dispatch contracts while preserving Media Library attachment queue behavior.

= 2.59.12.51 =
* Add a separate WordPress-derived local-asset AVIF/WebP storage namespace and collision-resistant source identity for theme, plugin, mu-plugin, and WordPress-includes images.
* Preserve the established uploads-relative generated paths byte-for-byte while deriving non-upload identity from canonical source scope, owner, relative path, and full source filename.
* Let runtime public-URL lookup serve fresh existing local-asset derivatives with the same exact-source mtime/size freshness contract, while leaving non-attachment queue generation for the next roadmap version.

= 2.59.12.50 =
* Add one canonical local public image source descriptor using the existing WordPress-derived uploads, plugin, mu-plugin, theme, and WordPress-includes path resolvers.
* Route frontend AVIF/WebP public-URL admission through the shared descriptor while preserving the established uploads-relative generated identity, freshness lookup, and attachment-backed on-demand queue behavior.
* Memoize exact local source descriptors, preserve query-insensitive source identity, support custom registered theme directories, and reject foreign URLs, unsupported extensions, traversal, and UltraCache-generated cache/image outputs.

= 2.59.12.49 =
* Exclude every UltraCache-owned table and UltraCache-owned option row from Media Library replacement database discovery, planning, preview, apply, verification, and rollback.
* Add an apply-time internal-state guard so a plan created by an earlier version cannot write UltraCache operational records; existing internal plan rows are classified as excluded instead of failed.
* Add Continue Replacement recovery for failed metadata, database, Theme CSS, and post-replacement Flush All phases while preserving every completed change.
* Add Restart Database Replacement for database-phase failures, rebuilding only unresolved database references from the current database while preserving switched attachment metadata and successful content replacements.
* Run Flush All after Media Library replacement completes and report the attachment, site-content, internal-exclusion, and clean-slate cache-reset result in the completion message.

= 2.59.12.48 =
* Show homepage HTML warm completion with the canonical warmed URL and the actual HTML, Varnish-variant, and LiteSpeed pipeline stages instead of a static success sentence.
* Show homepage HTML + CSS bundle warm completion through the same stage formatter used by menu and full-site warm-up, including CSS and the verified Varnish variant count.
* Reuse the same result-driven homepage summary when a shared/homepage CSS bundle is prepared before a broader manual warm job; no warm runtime behavior is changed.

= 2.59.12.47 =
* Make Flush All a clean warm/Varnish queue generation boundary by deleting every prior pending, retrying, processing, completed, skipped, and terminal row instead of preserving invalidation and refill work.
* Clear foreground and cron ownership, bump the warm generation, unschedule old ticks, and wait for the authoritative cron worker lease to finish before deleting the old queue.
* Hold a purge mutation barrier that blocks new page-cache and generated-CSS write locks and drains existing write/build locks before the cache directory is removed.
* Start external cache clearing and the optional warm-after-flush plan only after the purge mutation barrier is released, so any resulting queue rows belong exclusively to the new generation.
* Fail Flush All when the clean-slate queue reset cannot be committed instead of reporting success with stale queue work still present.

= 2.59.12.46 =
* Allow the authenticated HTML-variant diagnostic warm pipeline to ignore only the `DONOTCACHEPAGE` flag inherited from the current UltraCache admin/REST request while preserving all public URL eligibility, exclusion, WooCommerce, and cacheability checks.
* Revise the HTML-variant capability contract so the self-blocked 2.59.12.45 observation is invalidated and cannot remain authoritative before a fresh Test Varnish run.
* Present an incomplete upstream warm/refill observation as `Observation incomplete` with its concrete stored reason instead of collapsing it into `Not supported · 0 of N`.

= 2.59.12.45 =
* Retry only transient DNS, transport, timeout, throttling, and server failures during public Varnish HTML-variant refill while stopping immediately on successful or terminal HTTP responses.
* Remove the stale `cache-write-failed` classification from successful HTML warm results and propagate the actual failed Varnish bucket, HTTP/error code, retryability, and bounded attempt history through the warm pipeline and queue result.
* Keep HTML-variant capability observation inconclusive when the canonical warm/refill path cannot reach the per-bucket proof stage instead of converting an upstream refill failure into a false variant-unsupported result.
* Pass the explicit warmed page URL, source, and Accept bucket into the final media rewrite so cron, CLI, stale, and warm workers can queue missing AVIF/WebP files and associate them with the correct page.
* Scope missing-media discovery limits per warmed page and continue affected-page registration when a missing optimized lookup is memoized or already queued elsewhere in the same worker.
* Rewrite local upload background images emitted by page builders inside inline CSS `<style>` blocks through the same validated AVIF/WebP lookup and on-demand generation path used by image markup and style attributes.

= 2.59.12.44 =
* Separate Varnish capability observation from control transport: create and verify canaries through the canonical public WordPress route while sending PURGE or BAN only to the configured control endpoint.
* Restore HTTP exact-invalidation discovery for control-only listeners such as the Hetzner endpoint without requiring those listeners to serve ordinary frontend GET requests.
* Preserve independent Exact PURGE and Exact BAN behavior probes and derive broader capability tests from the method verified during the current run.
* Preserve terminal topology outcomes such as entire-host `not-applicable` instead of reclassifying them through generic supported/unsupported aggregation.
* Persist endpoint, basic-test, HTML-variant, ESI, and aggregate capability diagnostics in existing revisioned UltraCache state records, with one-time migration from superseded diagnostic options.
* Invalidate the incorrect 2.59.12.43 capability proofs through revised capability fingerprints so they cannot authorize runtime behavior before a fresh Test Varnish run.
* Keep capability-probe operations isolated from production recent-operation reporting and require a specific reason for every non-executed or inconclusive capability result.

= 2.59.12.43 =
* Independently behavior-test HTTP Exact PURGE and Exact BAN on every configured endpoint instead of limiting probes from the configured method or adapter classification.
* Derive the common production hard-invalidation method from current endpoint proofs and use the same verified method for targeted, HTML-only, and entire-host runtime operations.
* Probe Batch BAN, HTML-only flush, entire-host flush, soft purge, stale refresh, and origin revalidation independently without executing known-URL or TTL production fallbacks.
* Persist explicit per-endpoint capability states, reason codes, messages, applicability, conclusiveness, timestamps, and proof expiry in the existing UltraCache state table.
* Distinguish supported, not supported, not applicable, observation incomplete, configuration changed, proof expired, and not tested outcomes; every untested UI result includes its specific persisted reason.
* Migrate the legacy endpoint capability option into the existing UltraCache state record and remove the legacy option after successful persistence; no transient state is added.

= 2.59.12.42 =
* Make Automatic Varnish site flushing choose from the observed static-object route and verified production capabilities instead of preferring HTML-only flush unconditionally.
* Select verified entire-host flush when public static objects pass through Varnish, and select verified HTML-only flush when public static objects bypass Varnish.
* Report a verified HTML-only operation as degraded when static ownership is inconclusive or static objects pass through Varnish without verified entire-host invalidation.
* Display the actual site runtime strategy in the Varnish summary: HTML-only flush, entire-host flush, known site pages, or automatic expiry.
* Preserve the existing capability persistence, production transports, VCL contracts, and explicit manual scope behavior.

= 2.59.12.41 =
* Use one bounded post-invalidation observation contract for exact invalidation, batch BAN, HTML-only flush, entire-host flush, and static preservation proofs.
* Retry transient public DNS/HTTP observation failures while still requiring two successful responses that match the expected canary generation or exact written artifact.
* Fail immediately on any successful stale or mismatched observation so retries cannot manufacture a capability the production runtime does not support.
* Report exhausted transport-only observations as `observation-incomplete` instead of incorrectly classifying the server capability as unsupported.
* Preserve the existing production planner, control operations, capability tables, and persistent diagnostic contracts without adding transient state.

= 2.59.12.40 =
* Preserve the complete Varnish basic-test contract instead of truncating associative payloads by key count, recursion budget, insertion order, or string length.
* Persist the full ESI capability proof and endpoint/test evidence through the existing sanitization contract.
* Add an independent contract-bound HTML variant capability record and use it as the authoritative public-path registry source.
* Restore the HTML variant capability into the basic diagnostic response from its dedicated record and remove the redundant capability-list slice.
