export type TimerHandle = { id: ReturnType | number; }; /** * The seam every guard time read and timer goes through. The real clock is * the default; tests swap in a FakeClock to advance time deterministically. * See docs/superpowers/specs/2026-07-19-fake-clock-time-guards-design.md. */ export type Clock = { /** Monotonic milliseconds. What a time guard meters against. */ now(): number; /** Milliseconds since the Unix epoch. What std::date reads. Unused today; * here so issue #609 can reroute std::date through this seam later. */ wallTime(): number; setTimer(fn: () => void, delayMs: number): TimerHandle; clearTimer(handle: TimerHandle): void; }; export declare const realClock: Clock; /** The wall-clock epoch a fresh FakeClock reports as "now" (before any advance). * A realistic date, not 0, so a fixture reading today()/format(now()) under a * fake clock gets 2026, not 1970. std::date reads wallTime() (#609), so this is * load-bearing — clock.test.ts references this constant, not a literal. */ export declare const FAKE_CLOCK_WALL_BASE_MS: number; export declare class FakeClock implements Clock { private monotonicMs; private wallBaseMs; private timers; private nextId; now(): number; wallTime(): number; setTimer(fn: () => void, delayMs: number): TimerHandle; clearTimer(handle: TimerHandle): void; /** * Move the clock forward `ms` and fire every timer due within that span. * * Termination: in this codebase's usage the loop always ends. A guard * timer's callback only aborts; it never re-arms (re-arming is startWindow, * which runs at a later runner step), and every guard delay is >= 0, so each * iteration removes one timer and no callback adds one that is due earlier. * The loop is NOT proof against an arbitrary caller that arms a fresh 0ms * timer from inside a fired callback — that is a hypothetical no code here * does, so there is no firing cap. The guard below rejects the one misuse * that is easy to hit by accident: a negative or NaN advance, which would * move the clock backward or corrupt it. */ advance(ms: number): void; private earliestDueBy; }