detail
USR369 asked me to chase down why a file got auto-archived instantly instead of after the documented 3-day wait. Root cause confirmed by direct code reading: trash_lifecycle computed age via filemtime($fp) -- but rename() (used by every trash-mover on the platform: CLEAN.php's commands_sweep, and all 3 call sites in CLEANBACKUPS.php's to_trash()) is a metadata-only operation on POSIX systems that PRESERVES the original file's content-modification time, it does not reset it. So a file that had not been edited recently before entering trash already had an old mtime the moment it arrived -- if that pre-existing age was already 3+ days, it qualified for archival on the very first sweep run after entering trash, not 3 days after entering trash as the SOP intends. This is a systemic bug, not a one-off -- affects every trash-entry path on the platform, not just the one that happened to trigger it in yesterday's test. FIX: every trash-mover on this platform already embeds the real trash-entry timestamp directly in the filename it produces (…_YYYYMMDD_HHMMSS, sometimes followed by a file extension) -- confirmed 3 distinct real naming conventions currently in trash/ (CLEAN.php's own REPLACED pattern, CLEANBACKUPS.php's reason-tagged pattern, and BACKUP.php's PREVIOUS-rotation pattern) and built a regex that correctly parses all 3, verified against real sampled filenames before deploying (an earlier draft of the regex had a real bug of its own -- matched the wrong embedded date on a filename containing two, caught by testing against actual data before trusting it, not just believing it looked right). Falls back to filemtime() only when no parseable timestamp exists in the filename, preserving prior behavior for older/manually-placed trash items. Added an age_source field to the output (filename_timestamp vs filemtime_fallback) for transparency going forward.