# Changelog

## 1.2.6 — 2026-08-23

- Fixed an ambiguous WordPress option update that could stop consecutive scan batches with `LGS-LOCK-LOST` when the requested lock renewal was already stored.
- Preserved safe failure when the lock disappears, changes owner, or cannot reach the required expiry.

## 1.2.5 — 2026-08-23

- Separated active and historical findings into source-aware tabs for files, database records, and plugin advisories, with filtered counts and pagination.
- Replaced path-like database identifiers with human-readable content, option, user, table, and site locations.
- Added exact, copyable `SELECT` queries for recognized database findings without executing SQL or generating data-changing statements.
- Reorganized each finding into evidence, location, safe investigation, conditional correction, cleanup verification, and legitimate-context sections.
- Added explicit serialized-option, account-session, credential-rotation, cache, and rescan guidance where applicable.
- Added a restrained Garaje Imagina attribution strip to Overview with an accessible, tracking-free link to the official LocalGuard Scanner product page.

## 1.2.4 — 2026-08-22

- Added conservative per-file reconciliation so confirmed deleted paths move from Active findings to History even when an unrelated omission makes file coverage incomplete.
- Added stable-ID, resumable reconciliation batches with signed checkpoints and no path disclosure in progress, diagnostics, alerts, or AJAX responses.
- Preserved existing, excluded, symbolic-link, malformed, unreadable, or otherwise unverifiable paths as active.
- Added aggregate progress for previous findings checked and moved to History.
- Added regression coverage for deleted `upgrade-temp-backup` trees, path traversal, wrappers, links, exclusions, permissions, pagination, reappearance, and repository failures.

## 1.2.3 — 2026-08-22

- Separated active findings from resolved audit history, with independent counts, pagination, last-observed scan, and resolution date.
- Added per-area coverage so verified files can resolve stale file findings even when database coverage is incomplete.
- Preserved findings under exclusions or unverified areas and made resolution failures terminal and safe.
- Added schema version 5 with `resolved_at`, including idempotent migration and recurrence cleanup.
- Reconciled volatile discovery totals with confirmed processing so the displayed processed count never exceeds its total.
- Added area-specific coverage details to the scan result and overview.

## 1.2.2 — 2026-08-22

- Added a resumable discovery pass so scans can report exact processed-item progress after inventory completes.
- Persisted operational counters, stages, checkpoint activity, and safe failure codes across page reloads and WP-Cron continuations.
- Replaced the generic checkpoint message with structured administrator diagnostics that exclude paths, content, SQL, and secrets.
- Added schema-column diagnostics and an idempotent version 4 migration for progress and failure metadata.
- Added a responsive operational progress view with separate review-required and informational counts.

## 1.2.1 — 2026-08-22

Corrections to three defects that made the scanner miss code, misreport coverage, and keep a suppression model that could not work. No new detection weights and no destructive action.

- Fixed a false negative: `ObfuscationDetector`, `PhpDataFlowDetector` and `PhpDataFlowAnalyzer` required the literal string `<?php`, so a file whose only opening tag was `<?=` or a bare short tag was never analyzed. Recognition moved to a shared `PhpSource` helper that also rejects `<?xml`.
- Fixed a lifecycle defect: a single configured exclusion produced an `excluded_directory` coverage entry, which marked every scan `partial`, which meant `mark_unseen_resolved()` never ran and corrected findings stayed active forever. Coverage now separates deliberate exclusions from areas the scan failed to inspect; only the second kind makes a scan unverified.
- Findings located inside an excluded directory are never resolved automatically, because they were not re-inspected. The administration screen reports both kinds of coverage gap separately.
- Froze configured exclusions in the signed scan cursor, so settings changes during a resumable scan cannot alter the scope used for lifecycle decisions.
- Restored the missing-core-file check, which was suppressed by the same coverage condition, while filtering excluded core paths so they can never be reported as missing.
- Aligned the suppression contract end to end: the schema gained `site_id`, `locator_hash` and `object_sha256`; `SuppressionService` reads the stored `expires_at` as well as a raw timestamp and honours site scope; `SuppressionRepository` gained read and revoke operations; `FindingPersister` now applies suppressions instead of always passing `false`.
- Added object-scoped suppression pinned to a content hash, so a rule added in a later version does not reopen a false positive on an unchanged file, and the suppression lapses by itself once the file changes.
- Kept ignored findings for traceability without including them in actionable lists or counters, and resolved them when a verified scan no longer observes them.
- Made invalid suppression expiries fail towards showing findings and made suppression write failures explicit.
- Stopped discarding evaluated data: the file inventory now stores the real trust value instead of a hardcoded `untrusted`, refreshes it on every scan, and records the inode change time.
- Added regression coverage for every correction, plus two acceptance corpus samples: a `<?=` payload and an XML document that must stay clean.

## 1.2.0 — 2026-08-20

- Replaced the dense findings table with an accessible `details`/`summary` list that opens only the first critical or high-risk item.
- Added guided explanations for every detector: what LocalGuard observed, why it deserves attention, safe review steps, and false-positive context.
- Improved Overview, Scan, diagnostics, and Settings with truthful states and practical VPS and WP-Cron guidance.
- Added an accessible severity system that combines color, symbols, labels, scores, confidence, and status.
- Kept all detailed findings inside the authenticated administration panel and added no destructive action, dependency, network request, or database migration.

## 1.1.0 — 2026-08-20

- Added exact core trust so only signed hash matches can skip malware heuristics; integrity and permission checks still run.
- Replaced proximity-based PHP sequence alerts with bounded, function-scoped data-flow analysis.
- Distinguished fixed non-executable logging from request-controlled paths and writes to executable files.
- Classified token-verified inert uploads `index.php` markers as informational while keeping all other uploads PHP suspicious.
- Added a signed, offline Multisite-aware plugin advisory snapshot for User Meta through version 3.1.2.
- Added regression coverage for the legitimate Formidable, SimplePie, Jetpack, Astra/MailPoet-style upload-marker cases and nearby malicious variants.
- Preserved report-only behavior and shared-VPS resource budgets.

## 1.0.0 — 2026-08-20

- Added local, resumable file and database scanning.
- Added signed rules and exact SHA-256 WordPress core catalogs.
- Added contextual risk classification and finding lifecycle tracking.
- Added manual and daily scans with redacted high-risk email alerts.
- Added English and Spanish administration screens and local diagnostics.
- Added Multisite super-administrator controls, coverage reporting, retention, and shared-VPS resource budgets.
- Kept every response action non-destructive; version 1.0 reports only.
