/**
 * Background worker that drains the review outbox.
 *
 * Loop: every `pollIntervalMs` (default 30s)
 *   1. Recycle leases whose owners died mid-flight.
 *   2. If under concurrency cap and daily budget, lease the next pending job.
 *   3. Run the injected `executeReview` callback (SDK call lives in
 *      `reviewAgentSdk.ts`; injection keeps the worker testable without
 *      mocking Claude itself).
 *   4. Validate the agent emission and persist via skillNotesWriter, or
 *      markFailed with a reason.
 *
 * Resource limits enforced here:
 *   - concurrency cap (default 1, env override capped at 2)
 *   - daily-budget cap (default 100 jobs/day)
 *   - per-(skillId,failureModeHash) cooldown (default 5 min, in-memory)
 *
 * Feature flag: env SELF_IMPROVE_REVIEW_ENABLED defaults to false. When the
 * flag is unset, `start()` is a no-op so deploys are safe by default.
 *
 * See docs/architecture/self-improving-design.md §10 (Worker Resource Limits).
 */
import type { ReviewOutboxHandle } from './reviewOutbox';
export interface ReviewJobPayload {
    skillId: string;
    failureModeHash?: string;
    /** Free-form payload forwarded to the SDK call. */
    context: unknown;
}
/** Result of one review attempt. The worker uses this to decide done/failed. */
export type ReviewExecutionResult = {
    ok: true;
    emission: unknown;
} | {
    ok: false;
    reason: 'sdk_error' | 'sdk_timeout' | 'sdk_invalid';
    details: string;
};
export type ReviewExecutor = (payload: ReviewJobPayload) => Promise<ReviewExecutionResult>;
export interface ReviewWorkerOptions {
    outbox: ReviewOutboxHandle;
    /** Injected SDK call. Pure function so the worker can be unit-tested without Claude. */
    executeReview: ReviewExecutor;
    pollIntervalMs?: number;
    concurrency?: number;
    dailyBudget?: number;
    perSkillCooldownMs?: number;
    workerOwner?: string;
    /** Override `Date.now()` for deterministic tests. */
    clock?: () => number;
    /** Override notes directory passed to skillNotesWriter (tests). */
    notesDir?: string;
    /** Optional registry of valid tool/skill IDs for emission validation. */
    toolRegistry?: ReadonlySet<string>;
}
interface ReviewWorkerStats {
    attempted: number;
    succeeded: number;
    rejected: number;
    failedTransient: number;
    failedPermanent: number;
    cooldownSkipped: number;
    budgetExhausted: number;
}
export declare class ReviewWorker {
    private timer;
    private inflight;
    private readonly cooldownUntil;
    private readonly opts;
    readonly stats: ReviewWorkerStats;
    constructor(opts: ReviewWorkerOptions);
    /**
     * Start the poll loop. No-op if `SELF_IMPROVE_REVIEW_ENABLED` is not set
     * to a truthy value. Returns true if the worker actually started.
     */
    start(): boolean;
    stop(): void;
    /**
     * Single iteration of the loop. Exposed for tests so we don't have to
     * twiddle `setInterval` timing.
     */
    tick(): Promise<void>;
    private checkCooldown;
    private processJob;
    private recordWriteOutcome;
}
export declare const __testing: {
    DEFAULT_POLL_INTERVAL_MS: number;
    DEFAULT_CONCURRENCY: number;
    MAX_CONCURRENCY: number;
    DEFAULT_DAILY_BUDGET: number;
    DEFAULT_COOLDOWN_MS: number;
};
export {};
//# sourceMappingURL=reviewWorker.d.ts.map