import { type ParsedPayload } from "../../../hooks/adapter/parse.js"; import { type RuntimeTelemetryOptions } from "../../../hooks/adapter/runtime-telemetry.js"; import { type EventAdapterIdV3 } from "../adapter-id.js"; import type { RuntimeAttestationV3Base } from "../base-contract.js"; import { type CursorExecutionModeV3 } from "../capabilities.js"; import type { EventV3 } from "../contract.js"; import { type EventV3WriteMode } from "../control.js"; import { type RuntimeTelemetryCapabilitiesV3 } from "../runtime-telemetry-capabilities.js"; import { type OpenSpanStateV3 } from "../span-state.js"; import { type WriteEventV3Options, type WriteEventV3Result } from "../writer.js"; import { type HookSignalV3 } from "./hook.js"; import type { TurnRitualEvidenceV3 } from "./hook-base.js"; declare const STATE_FORMAT: "harnery-v3-hook-producer"; declare const STATE_VERSION: 3; interface SpanStateV3 extends OpenSpanStateV3 { source_id: `hid_${string}`; semantic_key?: `hid_${string}`; recovery_reason?: string; turn_id?: `tid_${string}`; turn_stamp?: "native_payload" | "producer_state"; requested_event_id?: `evt_${string}`; tool_name?: string; } interface ClosedSpanV3 { source_id: `hid_${string}`; semantic_key?: `hid_${string}`; span_id: `span_${string}`; closed_event_id: `evt_${string}`; turn_ordinal: number; } interface OpenWaitV3 extends OpenSpanStateV3 { wait_id: `hid_${string}`; started_event_id: `evt_${string}`; turn_id: `tid_${string}`; } interface TurnHarnessTimingV3 { hook_time_ms: number; hook_count: number; slowest_hook?: string; slowest_hook_ms: number; } interface CursorResponseRitualV3 { turn_id: `tid_${string}`; native_turn_id?: string; observed_at: string; status_box_present: boolean; status_box_present_strict: boolean; } interface PendingEventV3 { source_id?: `hid_${string}`; event: EventV3; } interface TurnContextTargetV3 { terminal_event_id: `evt_${string}`; terminal_observed_at: string; turn_id: `tid_${string}`; run_id?: `run_${string}`; workflow_id?: `wf_${string}`; workflow_agent_id?: string; } interface PendingRuntimeContextV3 extends TurnContextTargetV3 { native_session_id: string; native_turn_id: string; transcript_path?: string; runtime_version?: string; attempts: number; } interface ActiveRuntimeContextProbeV3 { turn_id: `tid_${string}`; attempted_at: string; boundary?: "tool_completed"; } interface DelegationStateV3 extends OpenSpanStateV3 { source_id: `hid_${string}`; delegation_id: `del_${string}`; child_generation_id: `gen_${string}`; role: string; } export interface HookProducerStateV3 { format: typeof STATE_FORMAT; format_version: typeof STATE_VERSION; adapter: EventAdapterIdV3; instance_id: `inst_${string}`; session_id: `sid_${string}`; generation_id: `gen_${string}`; attestation_id: `att_${string}`; capability_profile: `cap_${string}`; cursor_mode?: CursorExecutionModeV3; privacy_epoch_id: `pep_${string}`; /** * Genesis id of the ledger epoch this producer's boot chain lives in. The * fingerprint key epoch survives ledger rotation, so this is the field that * keeps a state file from being adopted across an epoch boundary (its * sequences and causal links only validate inside their own epoch). A state * without it predates the field and is never adopted. */ epoch_genesis_id?: `gex_${string}`; boot_id: `boot_${string}`; clock_id: `clk_${string}`; next_sequence: number; current_turn_id?: `tid_${string}`; /** Native turn identity retained owner-only for transcript attribution. */ current_native_turn_id?: string; /** Latest completed assistant response for Cursor's open turn. The response * body is discarded by agent-hook; only these booleans survive until Stop * copies them into the authoritative turn.completed ritual observation. */ cursor_response_ritual?: CursorResponseRitualV3; tool_call_count: number; tool_call_count_turn_id?: `tid_${string}`; last_event_id?: `evt_${string}`; last_monotonic_ns?: string; last_observed_at?: string; started_event_id?: `evt_${string}`; /** A derived lifecycle reopen is allowed to exist before the adapter's next * native prompt. Retained owner-only until that prompt starts a real turn. */ session_start_derivation?: "approved_lifecycle_reopen" | "validated_current_session_heal"; session_span: OpenSpanStateV3; current_turn_span?: OpenSpanStateV3; terminal: boolean; spans: SpanStateV3[]; delegations: DelegationStateV3[]; closed_spans: ClosedSpanV3[]; closed_turn_ids: `tid_${string}`[]; waits: OpenWaitV3[]; turn_harness: TurnHarnessTimingV3; turn_ordinal: number; pending?: PendingEventV3; pending_runtime_contexts?: PendingRuntimeContextV3[]; /** Last bounded active-turn probe; owner-only and used only for cadence. */ active_runtime_context_probe?: ActiveRuntimeContextProbeV3; /** Last emitted runtime source witness; owner-only measurement deduplication. */ last_context_source_witness?: string; /** Verified adapter-native transcript path retained only in owner-only state. */ runtime_transcript_path?: string; /** Tuning carried by the current attestation; {} means attested-none. * Absent on pre-upgrade state files, which seed silently on first sight. */ last_attested_tuning?: { effort?: string; speed?: string; }; /** Model observation carried forward into a refreshed attestation when the * change-time transcript read does not pair a model with the new tuning. */ last_attested_model?: { provider: string; id: string; }; /** Telemetry evidence carried forward verbatim: a tuning change does not * alter what telemetry the runtime proved it can deliver. */ last_attested_telemetry?: RuntimeTelemetryCapabilitiesV3; /** Full observations preserve missing and unsupported states when a * different attestation channel changes. */ last_attested_model_observation?: RuntimeAttestationV3Base["model"]; last_attested_tuning_observation?: RuntimeAttestationV3Base["tuning"]; /** Turn already probed for Codex tuning while effort is unknown; bounds the * rollout forward-scan to one attempt per turn. */ tuning_probe_turn_id?: `tid_${string}`; } export interface RecordHookSignalV3Input { coordRoot: string; mode: EventV3WriteMode; signal: HookSignalV3; payload: ParsedPayload; adapter: EventAdapterIdV3; instance_id: `inst_${string}`; run_id?: `run_${string}`; workflow_id?: `wf_${string}`; workflow_agent_id?: string; producer_id: `prd_${string}`; build_id: `build_${string}`; platform: "linux" | "windows" | "macos" | "unknown"; bridge?: "codex-wsl"; adapterVersion?: string; harnessVersion?: string; monotonic_ns?: string; observed_at?: string; hook_name?: string; hook_duration_ms?: number; stop_remediation?: boolean; turn_ritual?: TurnRitualEvidenceV3; session_start_derivation?: "approved_lifecycle_reopen" | "validated_current_session_heal"; delegated_child?: { generation_id: `gen_${string}`; parent_generation_id: `gen_${string}`; delegation_id: `del_${string}`; caused_by_event_id: `evt_${string}`; }; /** Optional roots and read budgets for runtime telemetry adapters. */ runtimeTelemetryOptions?: RuntimeTelemetryOptions; writerOptions?: WriteEventV3Options; /** * Skip the crash-recovery intake file when the caller already owns a * bounded, drainable queue. This prevents raw hook payloads from touching * disk before normalization. The default remains the durable spool used by * interactive harness hooks. */ intake?: "durable" | "memory_only"; } export type RecordHookSignalV3Result = { state: "gate_closed"; reason: string; } | { state: "missing_session_start"; } | { state: "already_started"; event_id: string; } | { state: "unpairable_tool"; reason: "missing_tool_use_id" | "no_open_span"; } /** A late signal for a span already closed in memory; preserved in diagnostics, never re-opened. */ | { state: "suppressed"; reason: "closed_span"; } | { state: "ignored"; } | { state: "observed"; generation_id: `gen_${string}`; turn_id: `tid_${string}`; observed_at: string; } /** Durably queued in the intake spool; a lease holder or drain hook records it. */ | { state: "spooled"; } /** Memory-only delivery could not acquire the producer lease and was dropped. */ | { state: "busy"; } | { state: "recorded"; event: EventV3; durability: WriteEventV3Result; recovered: boolean; }; export type ApprovedSessionEndReasonV3 = "approved_explicit_end" | "approved_verified_archive" | "policy_idle_timeout" | "policy_parent_terminal" | "policy_stale_sweep" | "policy_agent_completed" | "policy_run_completed" | "policy_superseded" | "policy_host_disappeared"; export interface HookProducerStateRecordV3 { path: string; modified_at_ms: number; state: HookProducerStateV3; } export interface RecordApprovedSessionEndV3Input { coordRoot: string; mode: EventV3WriteMode; instance_id: `inst_${string}`; generation_id: `gen_${string}`; build_id: `build_${string}`; platform: "linux" | "windows" | "macos" | "unknown"; reason: ApprovedSessionEndReasonV3; outcome: "succeeded" | "failed" | "cancelled" | "timed_out" | "denied" | "interrupted" | "unknown"; observed_at?: string; caused_by_event_id?: `evt_${string}`; coordination_finalized?: boolean; confidence?: "exact" | "high" | "medium" | "low"; writerOptions?: WriteEventV3Options; } export type RecordApprovedSessionEndV3Result = { state: "gate_closed"; reason: string; } | { state: "generation_unavailable"; reason: string; } | { state: "already_ended"; event_id?: `evt_${string}`; } | { state: "recorded"; event: EventV3; durability: WriteEventV3Result; recovered: boolean; }; /** * Record one hook signal through a private, crash-recoverable producer state file. * The function is inert unless the exact requested candidate or active gate is open. * * Delivery guarantee: the parsed signal is appended to a durable intake spool * BEFORE any producer state is read or validated, so a lost lease, a crash, or * a state-format mismatch never destroys a delivered signal. Whichever process * holds the session's state lease drains the spool in append order and rescans * until an empty pass; reconcile and session-start hooks drain any group whose * final appender never got the lease. */ export declare function recordHookSignalV3(input: RecordHookSignalV3Input): RecordHookSignalV3Result; export interface DrainHookIntakeSpoolV3Result { groups_with_records: number; groups_drained: number; groups_skipped_busy: number; } /** * Drain every session's pending intake records. This is the terminal drainer: * it does not depend on a "next signal" ever arriving for a session, so it is * wired into reconcile and session-start paths to pick up a final signal whose * appender lost the lease and exited. */ export declare function drainHookIntakeSpoolV3(coordRoot: string): DrainHookIntakeSpoolV3Result; /** Privacy-safe environment and recovery provenance for Codex mid-flight * onboarding. WSLENV values are never recorded, only normalized variable * names, and the native session identifier itself remains fingerprinted. */ export declare function codexMidFlightDiagnosticContext(payload: ParsedPayload, env?: NodeJS.ProcessEnv): Record; /** * End one exact live generation under the same private-state lease used by its * native hook producer. This is the only approved-authority terminal writer: * archive reconciliation, explicit `harn-end`, and policy cascades all converge * here so they cannot race each other or append activity after termination. */ export declare function recordApprovedSessionEndV3(input: RecordApprovedSessionEndV3Input): RecordApprovedSessionEndV3Result; export interface SalvageOpenSpansV3Input { coordRoot: string; mode: EventV3WriteMode; instance_id: `inst_${string}`; generation_id: `gen_${string}`; allowed_span_ids: readonly `span_${string}`[]; requested_turn_id?: `tid_${string}`; build_id: `build_${string}`; platform: "linux" | "windows" | "macos" | "unknown"; observed_at?: string; writerOptions?: WriteEventV3Options; } export type SalvageOpenSpansV3Result = { state: "gate_closed"; reason: string; } | { state: "generation_unavailable"; reason: string; } | { state: "salvaged"; closed: number; }; /** * Explicit-end salvage (ADR 0078): terminalize exactly the approved open-span * set with derived recovery terminals so an authorized end stops wedging * behind spans nothing else can close. Runs under the same private-state * lease as the native producer; spans outside the approved set are refused by * the caller's eligibility gate and never touched here. */ export declare function salvageOpenSpansV3(input: SalvageOpenSpansV3Input): SalvageOpenSpansV3Result; export declare function listHookProducerStateRecordsV3(coordRoot: string, options?: { includeTerminal?: boolean; }): HookProducerStateRecordV3[]; export interface ReanchorArchivedHookProducersV3Input { coordRoot: string; archivedEpoch: string; mode: EventV3WriteMode; build_id: `build_${string}`; platform: "linux" | "windows" | "macos" | "unknown"; observed_at?: string; } export interface ReanchorArchivedHookProducersV3Result { sessions: number; turns: number; } /** * Re-anchor every live archived hook producer into a newly activated epoch. * * The archive rename is the rotation's atomic snapshot: it includes every * state published before the boundary without copying any old boot sequence * or causal link into the successor. Each live session gets a fresh * generation and attestation. Only a turn that was open at the boundary is * reopened, which makes command telemetry joinable before another adapter * hook fires while preserving the between-turn state for idle sessions. */ export declare function reanchorArchivedHookProducersV3(input: ReanchorArchivedHookProducersV3Input): ReanchorArchivedHookProducersV3Result; export declare function readHookProducerStateV3(coordRoot: string, adapter: EventAdapterIdV3, nativeSessionId: string): HookProducerStateV3 | undefined; export interface ReconcilePendingRuntimeContextV3Input { coordRoot: string; mode: EventV3WriteMode; nativeSessionId: string; producer_id: `prd_${string}`; build_id: `build_${string}`; platform: "linux" | "windows" | "macos" | "unknown"; finalAttempt?: boolean; runtimeTelemetryOptions?: RuntimeTelemetryOptions; writerOptions?: WriteEventV3Options; } export type ReconcilePendingRuntimeContextV3Result = { state: "gate_closed"; } | { state: "missing"; } | { state: "busy"; } | { state: "not_pending"; } | { state: "pending"; } | { state: "settled"; }; /** * Retry one Codex session's owner-only context join without replaying its Stop * signal. Codex appends `task_complete` only after the synchronous Stop hook * exits, so this is invoked by a bounded detached worker after that exit. */ export declare function reconcilePendingRuntimeContextV3(input: ReconcilePendingRuntimeContextV3Input): ReconcilePendingRuntimeContextV3Result; /** Resolve one terminal producer only when native session and instance identity agree. */ export declare function readTerminalHookProducerStateV3(coordRoot: string, nativeSessionId: string, instanceId: `inst_${string}`): HookProducerStateV3 | undefined; export declare function readHookProducerStateByInstanceV3(coordRoot: string, instanceId: `inst_${string}`): HookProducerStateV3 | undefined; /** * Join a coordination actor to its hook producer. * * Native subagent commands can retain the parent's session id even after the * child has its own canonical generation. Prefer the native session join, but * when that points at a different instance accept only one exact live * instance match for the same adapter. */ export declare function readJoinableHookProducerStateV3(coordRoot: string, adapter: EventAdapterIdV3, nativeSessionId: string, instanceId: `inst_${string}`): HookProducerStateV3 | undefined; export {}; //# sourceMappingURL=recorder.d.ts.map