Skip to content

fix(overseer): stop replaced tick workers - #4981

Merged
rysweet merged 3 commits into
mainfrom
fix/overseer-tick-watchdog
Sep 2, 2026
Merged

fix(overseer): stop replaced tick workers#4981
rysweet merged 3 commits into
mainfrom
fix/overseer-tick-watchdog

Conversation

@rysweet

@rysweet rysweet commented Jul 29, 2026

Copy link
Copy Markdown
Owner

Summary

Prevent one stuck Overseer worker from blocking every later scheduled run, and prevent that old worker from changing shared state after it has been replaced.

  • release the running flag after a bounded wait so a replacement run can start
  • use a generation number so the old worker cannot clear the replacement worker's flag
  • stop the old worker before it starts another action
  • allow one action already running to finish because a blocked system call cannot be safely killed
  • block outdated observation writes, daemon log summaries, activity records, and counter updates
  • keep normal behavior unchanged when no replacement occurs

Limits

This is cooperative stopping. It cannot interrupt a system call or external command that is already running. Time limits for individual external calls are separate work.

Validation

  • Overseer action-stopping tests
  • observation-write tests
  • daemon worker and watchdog tests
  • report compatibility tests
  • repository pre-commit and pre-push checks
  • strict maintainer review: CLEAN

Co-authored-by: Copilot 223556219+Copilot@users.noreply.github.com

rysweet and others added 3 commits July 28, 2026 23:48
Observed Problem #3: the acting-overseer tick loop was missing scheduled
ticks. Cadence is every 15 min, but status showed the last tick at
2026-07-28T19:23:39Z marked (stale), with large gaps (17:57:55Z -> 19:23:39Z
~86 min).

Root cause: the acting-overseer tick uses a bare AtomicBool overlap guard
(overseer_tick_running) cleared by a spawned thread's ClearOnDrop. If a tick
HANGS on a long gh/network call, ClearOnDrop never runs, so the guard stays
true forever and every subsequent scheduled tick is dropped -> staleness and
multi-tick gaps. There was no watchdog to reclaim the stuck guard.

Fix (additive / non-breaking):
- Add a pure, clock-injected TickWatchdog + guard_generation_matches helper
  next to OverseerCadence in src/overseer/wiring.rs. The watchdog bounds
  max in-flight time (three cadence intervals, floored at 10 min) and is
  fully unit-tested (budget floor, reclaim on overrun, monotonic-safe
  inflight, generation-guard race, end-to-end hung-tick model).
- Wire it into the daemon: record arm time + generation when a tick arms;
  before the cadence check, if a tick has been in flight past the bound,
  reclaim the guard, bump the generation, and emit a tracing::warn! plus a
  daemon_log staleness/liveness signal so a catch-up tick can fire.
- Generation-token guard on ClearOnDrop: a late-finishing hung tick only
  clears the guard if its captured generation still matches current, avoiding
  the stale-clear race against a catch-up tick.

Structured tracing + OTel only (no print!/println!). Preserves PRD and OODA
cadence semantics. Adds 6 unit tests.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Use one generation value to stop later actions and block outdated memory, daemon-log, and activity writes after watchdog replacement.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@rysweet rysweet changed the title fix(overseer): watchdog reclaims hung tick guard to prevent missed ticks (Problem #3) fix(overseer): stop replaced tick workers Sep 2, 2026
@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown

📊 Coverage Summary

Generated by cargo llvm-cov --workspace --summary-only (nightly, excluding test files)

Module Lines Covered Coverage
Total 214962 181683 84.5%

Coverage data from CI run. Test files matching tests?/ are excluded from line counts.

@rysweet
rysweet merged commit f7a47f3 into main Sep 2, 2026
18 checks passed
@rysweet
rysweet deleted the fix/overseer-tick-watchdog branch September 2, 2026 14:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants