Set up the file watcher
First capture: creating the baseline
On the first start there is nothing to compare against — instead the pass creates the baseline: a checksum for every file (sha256 where PHP provides it, otherwise md5), plus size, modification time and area. This runs in small portions, out of the box up to 400 files or 5 seconds per step; you can close the window and carry on later. There is no percentage during the first capture, because nobody knows the total yet — what is shown is files read and directories still open. One thing up front: the watchdog remembers what it finds and takes it to be correct. If you are not sure about the installation, run the file integrity check (core against WordPress.org) and the malware scan first. After a move or a restore, “Discard baseline” is the clean way to go: all checksums and findings are dropped, and the next pass captures everything anew. This cannot be undone.
What is checked — and what is not
The tree from the WordPress directory downwards is checked. If wp-content or the plugin directory sits outside it at your host, it is added as a root of its own and gets its own prefix in the display. A wp-config.php that sits one level above the installation is included as a named single file and checked first at the start of every pass — the parent directory itself is deliberately not searched, since at most hosts it holds other people's installations and backups. Excluded out of the box are the uploads directory and 15 built-in cache, temp and log patterns (among them wp-content/cache, wp-content/upgrade, node_modules, .git, *.log); you can turn both switches off, and then the pass takes longer and every image upload produces a finding. You add your own patterns in the exclusion list: up to 100 entries, each at most 200 characters. A pattern without a slash matches every path segment of that name, a pattern with a slash is anchored at the root, and * applies within a segment. A pattern that matches all the example paths is rejected — it would switch the monitoring off without anyone being able to tell from the list. As you enter it, the number of files in the current baseline that fall under it is counted and displayed. Not read are files above the size limit (16 MB out of the box, adjustable from 1 to 512), unreadable files and everything behind a symbolic link — these cases appear as separate figures in the result and expressly do not count as “missing”.
Reading and applying findings
There are three kinds: changed, new, missing. At most one open finding per file appears in the list, with first sighting, last sighting and a counter. The comparison is made against the last confirmed baseline, not against the last pass — which is why a finding stays put until you apply it. If the content aligns with the baseline again by itself (an update rolled back, a file restored), the finding disappears; a reported new file that is gone again is written to the activity log with its path instead of being deleted silently. “Apply baseline” shows in advance what would happen and then works in blocks of 500: changed files get their new checksum, new ones are added, missing ones drop out. Nothing changes about the files themselves — but the old checksum is gone afterwards, so look at everything you cannot explain before you press it. For your records there is a CSV export with up to 2000 open findings including the old and the new checksum. Two limits are worth knowing: above 3000 open findings counting continues but nothing more is stored (the interface says so), and of the history the 500 most recently applied findings are kept. An aborted pass does not determine missing files — that takes a complete run.
Immediate alert for sensitive files
Switched on out of the box. “Sensitive” here does not mean “important”, but rather: whoever can change this file runs their own code or gets hold of the access data. Those are wp-config.php, server configurations (.htaccess, .htpasswd, .user.ini, php.ini, web.config), drop-ins (db.php, object-cache.php, advanced-cache.php, sunrise.php and relatives), mu-plugins, and PHP files in places where none should be: in the uploads directory, in the WordPress root and in wp-content outside plugins and themes. These alerts go out at the end of every portion, not only at the end of the pass — on a large installation there are hours in between. The minimum interval is 15 minutes out of the box (adjustable from 0 to 1440); whatever comes in during that time is collected and goes out with the next alert, nothing is lost. One alert lists at most 200 entries, the rest is given as a number. At the end of the pass and when it is aborted, the remainder is flushed regardless of the interval. Test the route once with the sample alert: it tells you explicitly whether wp_mail() accepted or rejected the message — whether it is delivered is decided by the server behind it. You can also enter patterns of your own as sensitive; open findings are reclassified immediately in the process, so that the list does not show two truths.
Automation and schedule
Out of the box the pass only runs when you start it. If you switch the automation on, you choose between hourly, twice daily, daily (the default) and weekly. The first appointment is deliberately 5 minutes in the future, so that a pass does not start up in the middle of your work in the backend. It is counted from the start of the last pass, with 5 minutes of tolerance — otherwise a long pass would run less and less often each time. The cron works through the same portions and reschedules itself every 30 seconds as long as something is still open; if you are at the wheel in the browser yourself, it waits 120 seconds and does not grab the steering wheel. Two drivers on the same job are ruled out by a token that is passed along with every response; the lock expires after 60 seconds, so that a browser slammed shut does not block the job for good. If DISABLE_WP_CRON is set in your installation, the message when you switch it on tells you that the pass only starts when wp-cron.php is called from outside — that is, when a server cron job is set up.