Repository navigation
fix(watcher): keep the startup poll from holding back digests and security intake - #216
Merged
Merged
Conversation
…urity intake start() awaited a full poll before spawning the loops, so on 2026-11-11 the startup poll ran fix attempts inline from 06:16 past 07:30 and housekeeping never started: the 07:00 PR digest was missed and the security inbox was not polled. The loops now start straight after warm start and each runs its first cycle immediately; retries and cascades come from the housekeeping tick instead of a duplicate in the startup poll. Schedules only fired inside their exact hour and kept their last run in memory, so a long tick or a restart skipped a slot, and a restart inside the hour could repeat one. A slot now stays due for the rest of its UTC day until it runs, and the last run is stored in scheduled_runs so a restart resumes it. Digests also go out while Claude runs are paused for a rate limit, since they need no Claude run. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
🟢 Tier S · Ready to mergeThe watcher starts source polling, security intake, and housekeeping loops immediately after warm start, with each loop running independently. Scheduled reports catch up within their UTC slot day and persist the latest run time, and digest delivery continues during Claude rate-limit pauses. The pull request also adds tests for startup behavior, scheduling, persisted run state, and live poll-cycle telemetry. Latest changes: The newest commits restore poll-cycle duration telemetry in the live source-poll loop and add a test that verifies the running watcher records it.
📂 Walkthrough · 12
Reviewed the commits since |
… its start Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What broke
After the 0.57.5 restart on 2026-11-11,
start()awaited a full poll before spawning the loops. That poll ran fix attempts inline from 06:16 until after 07:30, so housekeeping never started. As a result:Changes
poll()remains only as a test driver.ReportSchedule::is_dueused to fire only within the exact slot hour. Now a slot stays due for the rest of its UTC day until it runs. A long housekeeping tick or a restart no longer skips it, and a missed slot never fires on a later day.scheduled_runstable (V19) stores each schedule's last run, so a restart neither repeats nor skips a slot. This applies to the PR digest and the repetitive-issues digest.Tests
Each new test was confirmed to fail without its fix:
a_source_blocking_its_thread_never_stalls_security_intakenow drivesstart(). With the startup poll put back, it fails.the_pr_digest_goes_out_while_runs_are_paused_for_a_rate_limitfails if the paused tickcontinues.a_slot_missed_at_its_hour_runs_later_that_day_onlya_restarted_watcher_resumes_the_pr_digest_from_its_last_recorded_runa_scheduled_run_keeps_only_its_latest_time🤖 Generated with Claude Code