import type { OrgDaemon } from './daemon.js'; import type { RunningOrg } from './daemon-types.js'; import type { OrgRole } from './types.js'; /** Idle watchdog's per-tick recovery check: given the previous nudge timestamp, * the cumulative nudge count, and the timestamp of the most recent real tool * call, returns the nudge count that should carry forward now that fresh * activity means the org is no longer idle. * * `nudgedAt !== 0` means we're recovering from an outstanding nudge. Resetting * the counter here means it only ever tracks UNRESOLVED idle spells in a row, * not a lifetime total — a long-running org that goes idle and recovers any * number of times (e.g. periodic checkpoints on a slow background task) is * never punished for having had several separate, healthy idle spells over * its lifetime. Before this existed, `nudges` only ever incremented, so a run * that answered every single nudge with real work still hit the "org idle * again after 3 nudges" cap and got force-stopped on its 4th idle spell — * observed live killing an in-progress 24h soak test under 90 minutes in. * * But "recovering" must mean genuine forward progress, not just any bus * event — a bare, content-free reply to the nudge (a boss that answers with * "✓ Complete" and calls no tools at all) still updates lastActivity, so the * org isn't flagged as silent, but it accomplishes nothing: nobody outside * the boss's own turn ever sees it, since role coordination only happens via * tool calls (org_send, org_task, ...). Requiring `lastToolActivity >= * nudgedAt` — a real tool call happened AFTER this nudge was sent — closes * that gap: observed live, a boss stuck responding to four consecutive * 10-minute nudges with one-line acknowledgments and zero tool calls looped * indefinitely making no progress, because every trivial reply reset the cap * that was supposed to catch exactly this. */ export declare function resolvedIdleNudgeCount(nudgedAt: number, nudges: number, lastToolActivity: number): number; /** What the bus subscriber in startOrgInner tracks and the watchdog reads. */ export interface IdleActivity { lastActivity: () => number; lastToolActivity: () => number; roleActivity: Map; noProgressAlarmed: Set; } export declare function startIdleWatchdog(daemon: OrgDaemon, name: string, running: RunningOrg, bossRole: OrgRole, activity: IdleActivity): void; //# sourceMappingURL=idle-watchdog.d.ts.map