/** * [WHO]: EvolutionAutoObserver turns explicit reusable-lesson and structured turn output into candidate records, rate limited per scope root; activation still requires the store evidence gate * [FROM]: Depends on extension turn_end context, evolution gate, and evolution store validation/persistence * [TO]: Consumed by optional evolution extension entry * [HERE]: extensions/optional/evolution/evolution-auto.ts - deterministic loop-level self-evolution observer with scope gates */ import type { ExtensionContext, TurnEndEvent } from "../../../core/extensions-host/types.js"; import { type EvolutionGateRunner } from "./evolution-gate.js"; /** * One rate limit for every branch that can create a candidate, keyed by the scope root it writes * to rather than by session. * * Keying by session was right only while session scope was the sole writer. A structured proposal * may target global or workspace, and two sessions proposing the same global artifact each got * their own budget; keying by root makes a scope's limit that scope's, and a workspace proposal can * no longer be muted by an unrelated session's memory. * * The last consumed turn is held in that scope's on-disk evidence cursor rather than in this * instance, because a cursor that forgets on restart is not a cursor. What the cursor does *not* do * is outlast its own turn window: it suppresses a fixed number of turns, new evidence is always * admitted, and a stream belonging to a different session starts from nothing. That keeps it a * bounded re-read of recent work rather than a standing judgement about an idea. */ export declare class EvolutionAutoObserver { #private; constructor(options?: { runGate?: EvolutionGateRunner; }); observeTurnEnd(event: TurnEndEvent, ctx: ExtensionContext): Promise<{ candidateId?: string; skipped?: string; }>; }