Add daily_post check: confirm today's post actually published #2
Loading…
Reference in a new issue
No description provided.
Delete branch "feature/daily-post-check"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Adds a
daily_postcheck that confirms a post actually published today.Why
The
wp_croncheck reports success wheneverwp-cron.phpreturns HTTP 200. That proves the endpoint responds; it does not prove anything was published.On 2026-08-21 a scheduled post on sqlserverscience.com stayed in
futurestatus past its 09:28 slot. Vigilance Sentinel was triggeringwp-cron.phpevery minute throughout, and it answered HTTP 200 every time, so roughly 200 successful triggers happened while the post never went out. The site missed a day with every check reporting green.The cause was the
publish_future_postevent being absent from WordPress's cron array. No existing check could see that, because every existing check measures a mechanism rather than an outcome.What it does
Asks the site what it last published:
Before
expectPostByLocalTimethe check passes, because the day's post is not due yet. From that time onwards it fails until something has been published on the current date intimeZone.Real output from a live run against sqlserverscience.com, passing:
And failing, produced by pointing the same check at the site's oldest post:
Design decisions
Calendar-day rather than rolling age window. A
maxAgeHourswindow drifts with the previous day's publish time. With a 09:00-09:30 posting window and a 26-hour threshold, a post at 09:30 followed by nothing would not trip until 11:30 the next day, and the margin moves daily. A cutoff answers the question directly: has today's post gone out yet.Time zone aware. Both the day boundary and the cutoff are evaluated in the configured zone, because publishing schedules are set in site-local time. A test covers a post whose UTC date and site-local date differ, which would otherwise be judged as "today" incorrectly.
No credentials. The REST API exposes published posts anonymously and refuses anonymous requests for scheduled ones, verified:
?status=futurereturns HTTP 400 unauthenticated. Detecting an overduefuturepost directly would need an application password, giving a monitoring tool write access to the site.date_gmt, notdate. WordPress emits both without a timezone designator.dateis site-local and would be parsed as the monitoring machine's local time. The check fails with a clear message ifdate_gmtis missing from the requested_fields.Alert-only. Remediation would need write credentials and turns a monitor into an actor. Out of scope for this tool.
Limitations, stated plainly
Testing
dotnet buildclean, 0 warnings.dotnet test22 passed, 0 failed.smtp.hostwas blanked for the local runs.Notes
THIRD-PARTY-NOTICES.mdis unchanged and the zero-dependency constraint holds.InternalsVisibleToadded so tests can reach the parsing helpers and aCheckAsyncoverload that takes the current time, which is what makes the day-boundary cases testable without waiting on the clock.UnitTest1.csis removed.ARCHITECTURE.md,README.md,SETUP-GUIDE.md, andsamples/example-site.jsonupdated in this commit.Assumptions
contentFreshnessblock getEnabled = truefrom the model default but an emptyUrl, and the check skips with a success result when no URL is set. Existing deployments therefore behave exactly as before until a URL is configured.TimeZoneInfo.FindSystemTimeZoneByIdaccepts IANA identifiers on Windows as well as Linux, which holds on .NET 6+ with ICU. A Windows identifier such asCentral Standard Timealso works.