Skip to content

Read-only cache inspection refreshes legacy access age through empty WAL sidecars #643

Description

@N0zoM1z0

Before submitting

  • I searched the open and closed issues for a related report.
  • I removed credentials, tokens, private paths, and sensitive repository content.

Area

Cache, receipt, or token accounting

Observed behavior

Repeated cache list changes the reported last-access time of a legacy WAL-mode cache whose metadata lacks a persisted access timestamp, despite no source indexing or database writes. The first read-only metadata inspection creates an empty WAL; the next scan treats its new mtime as recent activity.

Reproduction

  1. In a disposable cache namespace, index a one-file repository.
  2. Remove meta.last_access_unix_seconds to reduce the fixture to the existing fallback-age behavior, close all connections, and set main-database mtime to Unix second 100.
  3. Run cache list twice.
  4. Observe first last_access_unix_seconds=100, then a current timestamp, with the main file still at mtime 100 and a newly created zero-byte WAL.

This reduced metadata fixture is not an authentic full historical release schema.

Expected behavior

Read-only cache inspection must not renew fallback access age or alter age-based prune/LRU eligibility. Empty WAL sidecar initialization must not count as repository activity; nonempty WAL transaction data remains relevant.

Impact and scope

Legacy caches using filesystem timestamps can evade age-based cleanup or move later in LRU eviction order merely because they were inspected. Caches using valid persisted access timestamps do not use this fallback.

LeanToken version or revision

Reproduced with the sealed native executable from bcdc63c7619b70a487bbeb6563b2906be5a64d18 (0.1.28 development).

Environment

Linux x86_64; Rust 1.95; isolated disposable CLI cache.

Repository and request context

One source file; managed WAL-mode database; repeated cache list.

Earliest failure stage

Indexing, inventory, or cache

Relevant output or evidence

First list: access=100, main bytes=274432/mtime=100, WAL bytes=0/new mtime.
Second list: access=current WAL mtime, main bytes/mtime unchanged, WAL bytes=0.

Analysis or suspected cause

Confirmed source path: scan_artifacts includes every main/WAL mtime regardless of WAL length. inspect_database opens read-only SQLite, which can initialize WAL/SHM sidecars. The next scan then promotes that empty WAL timestamp into fallback access age.

Additional context

Discovered while adding the selective-compaction retention regression in #642. That PR also refuses compaction when access age is inferred from file timestamps, avoiding VACUUM-driven age renewal.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions