/** * Durable drumbeat registry (DEC-086, slice D2). * * The ephemeral presence files (DEC-051) are swept ~15s after the last * heartbeat, so a genuinely *stopped* agent leaves no trace there — yet the * stopped agent is exactly what the drumbeat must relance. The host plugin * therefore records a **durable** stop entry here, under * `/.h2a/drumbeat/.json`, which survives the presence * sweep until the agent is cleanly resumed or finished. * * The presence `workStatus`/`inferStall` (D1) still cover the running-but-idle * case; this registry covers the stopped case. */ import type { H2ALaunchContext, H2AReflexiveAction, H2AWorkStatus } from "@sentropic/h2a"; export interface H2ADrumbeatEntry { readonly instance: string; /** Status the agent reported when it stopped. */ readonly workStatus: H2AWorkStatus; /** ISO timestamp of the stop. */ readonly stoppedAt: string; /** Launch context captured at start, for the relauncher (DEC-084). */ readonly launchContext?: H2ALaunchContext; /** How many relances have been issued for this stop. */ readonly relanceCount: number; /** ISO timestamp of the last relance, if any. */ readonly lastRelanceAt?: string; /** * D5: set when a reflexive-watchdog terminal action (escalate/reroute) resolved * this stop. `scanDrumbeat` skips terminal entries so they are not re-decided; * a genuine fresh `recordStop` overwrites the entry (a new relance budget). */ readonly terminal?: { readonly action: H2AReflexiveAction; readonly at: string; }; } export interface RecordStopInput { readonly instance: string; readonly workStatus: H2AWorkStatus; readonly launchContext?: H2ALaunchContext; } /** * Record (upsert) that an agent stopped. Resets `relanceCount` to 0 — a fresh * stop is a fresh relance budget. The host plugin calls this on exit. */ export declare function recordStop(root: string, input: RecordStopInput, now?: number): H2ADrumbeatEntry; export declare function readDrumbeatEntry(root: string, instance: string): H2ADrumbeatEntry | undefined; export declare function listDrumbeat(root: string): H2ADrumbeatEntry[]; /** Remove an entry — call when the agent is cleanly resumed or finished. */ export declare function clearDrumbeatEntry(root: string, instance: string): void; /** Increment the relance counter after a relance was issued. */ export declare function markRelanced(root: string, instance: string, now?: number): H2ADrumbeatEntry | undefined; /** * D5: mark an entry terminal (a reflexive-watchdog escalate/reroute resolved it). * `scanDrumbeat` skips terminal entries, so the watchdog does not re-decide it * each beat — without the destructive delete that a later `recordStop` (which * resets `relanceCount`) would re-arm into a slow loop. */ export declare function markDrumbeatTerminal(root: string, instance: string, action: H2AReflexiveAction, now?: number): H2ADrumbeatEntry | undefined; //# sourceMappingURL=registry.d.ts.map