Field guide / Scheduled automation / October 30, 2026

When a monitor goes silent, the error log may stay green.

We often build an alarm for work that fails. But what warns us when the work was never started—or the monitor itself stopped observing? This is a practical guide to keeping an expected schedule separate from the evidence that a run was observed.

Evidence level: Original fictional example and directly linked official documentation. No claim of a production incident, customer outcome, or independent benchmark.

Failure messages only describe failures that got recorded

Imagine an hourly synchronization job. Its last dashboard entry is successful. Nobody sees a fresh error. Yet the intended 14:00 run left no trace. Is the integration healthy? The answer is unknown. There may be a scheduler failure, a disabled workflow, missing log export, a downstream outage, or simply delayed logging. Starting from an empty error list skips the question of whether the system produced a new observation at all.

GitHub explicitly documents that scheduled workflow events can be delayed and, at high load, occasionally dropped. It recommends avoiding the start of the hour to reduce that risk. This is a scheduler-specific warning, not a claim that every missing entry is a dropped GitHub job.

Cloudflare's Cron Triggers guide describes UTC schedules and a dashboard history of scheduled invocations; it also notes that trigger configuration changes may take time to propagate. Seeing a Cron invocation is evidence of an attempted scheduled event, not proof the final business object was written.

A worked four-slot case, with one missing observation

All timestamps and records below are invented. We declare a fixed UTC observation window from 12:00 to 16:00, hourly slots and a 10-minute grace period. Observations are 12:02, 13:25, 15:02 and 15:05.

Expected slot (UTC)Supplied observationLocal findingWhat is still unknown
12:0012:02Within graceDid the work deliver the intended result?
13:0013:25LateScheduler late, worker late, or observation late?
14:00—Missing observationWas the job absent, or merely invisible?
15:0015:02 and 15:05Within grace, extra observationDuplicate job, retry, or duplicate log entry?

The counts are: two on-time slots, one late slot, one missing slot, one extra observation. Because the example has no authenticated scheduler events or independent destination checks, these are classifications of provided timestamps. A gap is a reason to investigate, not evidence sufficient to accuse a provider of failing.

Run this fictional example locally →

Build an evidence ladder instead of one green badge

1. Expected schedule

Describe what should have happened, in an unambiguous time zone and window. Ask whether the schedule was active, whether holidays or maintenance periods apply and whether its configuration recently changed. For this free checker, only fixed-duration UTC slots are supported; real cron expressions and daylight-saving rules must be resolved elsewhere.

2. Independent observation of the scheduled event

Look at the scheduler or platform execution history from a source with permission to observe it. Record its retention limit and the time the export was captured. An empty feed can mean either no events or a broken monitoring path. Prometheus documents an absent_over_time() function for detecting the absence of expected time-series samples over an interval. It is a useful native alternative when the environment already has reliable metrics.

3. Recorded execution status

When a job does appear, investigate its execution, retries, failed steps and idempotency boundaries. A duplicated observation does not establish a duplicate side effect. Nor does a successful execution automatically tell you the relevant account, row or file was correctly changed.

4. Downstream outcome and human acceptance

Compare the intended result with a read-only observation of the destination, in the correct time window. Keep authorization and source lineage explicit. A business owner may still need to accept the result. Moruneva's separate Outcome Reconciler and Acceptance Evidence Workbench explore portions of these later steps using only supplied, pseudonymous snapshots.

Four traps that produce false reassurance

Trap A — the clock is interpreted differently. A local timestamp without a zone, a daylight-saving transition, or a changed cron schedule makes two observers disagree about the intended slot. Pin both the expected schedule and observation timestamps to UTC before comparing.

Trap B — a late event lands in the next slot. Our tool assigns an observed timestamp to the preceding fixed UTC slot. If a 13:00 run only appears after 14:00, it may be assigned to 14:00. With no trusted run identifier, a pure timestamp comparison cannot reconstruct its actual origin. That ambiguity is an explicit limitation, not an edge case we silently correct.

Trap C — the monitor and the job share the same failure domain. If both stop together, the monitor may never emit an error about its own absence. A separate expected-event generator, second observation channel, or a native absence alert can reduce that blind spot, but no single channel guarantees perfect coverage.

Trap D — the audit window is still open. If you request an interval extending into the future, the checker can label later unobserved slots “missing” while they are not yet due. Its companion interface now warns about windows that have not started or have not ended, based on the current device clock. The clock itself is unverified, and the versioned count-only export remains a classification of supplied data rather than a claim that the job was overdue. Prefer completed historical windows and note the observation export's capture time before escalating a gap.

When should you use a spreadsheet instead?

For one small, fixed schedule, generate the expected timestamps in a spreadsheet and compare them with exported event times. If you already operate Prometheus, a native time-series absence rule may be simpler than exporting CSV. If you need real-time alerts, recurrence calendars, authenticated execution IDs or a full incident response process, a static browser checker is insufficient. A responsible tool should tell you when another existing method is better.

The free Moruneva check deliberately stops early.

It cannot access GitHub, Cloudflare, n8n, Prometheus or your customers' systems. It does not subscribe to events, monitor in the background, prove a missed execution, certify business delivery or send alerts. The versioned JSON report is count-only and always requires human review.

Further reading and reproducibility

The provider-specific facts in this article are grounded in original documentation: GitHub scheduled workflow event semantics, GitHub troubleshooting of delayed or missing schedules, Cloudflare Cron Trigger scheduling and event logs, and Prometheus query functions. These references establish platform behaviors, not that any one provider failed in our fictional case.

The companion Schedule Silence Check ships with a deterministic four-slot example, a reusable in-process JavaScript module and unit tests. It intentionally reports whether provided timestamps cover expected fixed UTC slots; nothing more. Feedback about which decisions this prevents—or whether a native alternative is already sufficient—is more valuable than a page-view count.

Browse other small tools → · Suggest a real (non-sensitive) edge case → · Privacy →