import { type RolePolicyConfig } from "../domain/role-policy.js"; import type { Clock, KernelPaths } from "./types.js"; import { type DeliveryAuthorization } from "./result-binding.js"; import { type TerminalSecretScanReference } from "./result-terminal.js"; export interface FreshRoleCreateInput { readonly operation_id: string; readonly identity_digest: string; readonly role_id: string; readonly engine: "claude" | "codex"; readonly model: string; /** Role-bound: grader-output.v1 for grade; reflection.v1 for reflection — never mixed. */ readonly schema_version: "grader-output.v1" | "reflection.v1"; readonly evidence_digest: string; readonly evidence?: Readonly>; } /** * Fresh-role outcome. Codex structured-exec completes synchronously. * Interactive Claude structured-role may return pending (launched/waiting); * completion is recovered only via inspectExact after durable result exists. * Grade and reflection completed shapes stay schema-distinct (no coercion). */ export type FreshRoleResult = { readonly ok: true; readonly status: "completed"; readonly schema_version: "grader-output.v1"; readonly session_id: string; readonly output_digest: string; readonly passed: boolean; readonly summary: string; readonly engine: "claude" | "codex"; readonly model: string; readonly role_id: string; } | { readonly ok: true; readonly status: "completed"; readonly schema_version: "reflection.v1"; readonly session_id: string; readonly output_digest: string; readonly engine: "claude"; readonly model: string; readonly role_id: "oms.bounded-dreamer"; } | { readonly ok: true; readonly status: "pending"; readonly session_id: string; readonly engine: "claude" | "codex"; readonly model: string; readonly role_id: string; readonly schema_version: "grader-output.v1" | "reflection.v1"; }; export type FreshRoleFailure = { readonly ok: false; readonly reason: string; readonly absent?: boolean; readonly ambiguous?: boolean; }; /** Expected stage intent for inspect recovery — never self-compare receipt to itself. */ export interface FreshRoleInspectInput { readonly operation_id: string; readonly identity_digest: string; readonly role_id?: string; readonly engine?: "claude" | "codex"; readonly model?: string; readonly schema_version?: "grader-output.v1" | "reflection.v1"; readonly evidence_digest?: string; readonly evidence?: Readonly>; } export interface FreshRoleAdapter { readonly createExact: (input: FreshRoleCreateInput) => FreshRoleResult | FreshRoleFailure; readonly inspectExact: (input: FreshRoleInspectInput) => FreshRoleResult | FreshRoleFailure; } /** * Exact stop with readback. WorkerPaneAdapter.stop is void; this wrapper * performs kill then observe-only confirmation (or inspect-only on replay). */ export interface StopAdapter { readonly createExact: (input: { readonly operation_id: string; readonly identity_digest: string; readonly task_id: string; readonly attempt: number; readonly pane_id: string; readonly session_id: string; readonly launch_operation_id: string; readonly launch_identity_digest: string; readonly physical_nonce: string; }) => { readonly ok: true; } | { readonly ok: false; readonly reason: string; readonly ambiguous?: boolean; }; readonly inspectExact: (input: { readonly operation_id: string; readonly identity_digest: string; readonly task_id: string; readonly attempt: number; readonly pane_id: string; readonly session_id: string; readonly launch_operation_id: string; readonly launch_identity_digest: string; readonly physical_nonce: string; }) => { readonly ok: true; } | { readonly ok: false; readonly reason: string; readonly absent?: boolean; readonly ambiguous?: boolean; }; } export interface DeliveryAdapter { readonly inspectPushExact: (input: { readonly operation_id: string; readonly repository: string; /** Exact push remote URL (e.g. git@github.com:owner/repo.git). */ readonly remote: string; readonly branch: string; readonly commit: string; }) => { readonly ok: true; readonly remote_head: string; } | { readonly ok: false; readonly reason: string; readonly ambiguous?: boolean; readonly absent?: boolean; }; readonly pushExact: (input: { readonly operation_id: string; readonly repository: string; readonly remote: string; readonly branch: string; readonly commit: string; readonly force: false; readonly refspec: string; }) => { readonly ok: true; readonly remote_head: string; } | { readonly ok: false; readonly reason: string; readonly ambiguous?: boolean; }; readonly inspectDraftPrExact: (input: { readonly operation_id: string; readonly repository: string; readonly branch: string; /** Exact PR base branch (e.g. main). */ readonly base_branch: string; readonly head_commit: string; }) => { readonly ok: true; readonly url: string; readonly is_draft: true; readonly head_commit: string; readonly base_branch: string; } | { readonly ok: false; readonly reason: string; readonly ambiguous?: boolean; readonly absent?: boolean; }; readonly createDraftPrExact: (input: { readonly operation_id: string; readonly repository: string; readonly branch: string; readonly base_branch: string; readonly head_commit: string; readonly draft: true; }) => { readonly ok: true; readonly url: string; readonly is_draft: true; readonly head_commit: string; readonly base_branch: string; } | { readonly ok: false; readonly reason: string; readonly ambiguous?: boolean; }; } export type { DeliveryAuthorization } from "./result-binding.js"; export { deliveryAuthorizationDigest } from "./result-binding.js"; export interface ResultSecretScanInput { readonly task_id: string; readonly worktree_path: string; readonly base_commit: string; readonly result_commit: string; readonly outbound: Readonly>; } export interface ResultSecretScanOutput { readonly passed: boolean; /** Full immutable reference — required for journal + terminal evidence (7A.3C §D). */ readonly reference: TerminalSecretScanReference; } /** * Production result-service config. No injected Git probe, verification harness, * or after-bind callbacks — those exist only on the harness impl seams. */ export interface ResultServiceConfig { readonly paths: KernelPaths; readonly clock: Clock; readonly rolePolicy?: RolePolicyConfig; readonly gradeAdapter: FreshRoleAdapter; readonly reflectionAdapter: FreshRoleAdapter; readonly stopAdapter: StopAdapter; readonly deliveryAdapter?: DeliveryAdapter; readonly deliveryAuthorization?: DeliveryAuthorization | null; /** * Must call runSecretScan with exact task/base/worktree/head/outbound. * Returns full immutable SecretScanReference. Omit fails closed for repository-backed. */ readonly secretScan?: (input: ResultSecretScanInput) => ResultSecretScanOutput; } export type ProcessResultStatus = "verified_human_ready" | "delivered_human_ready" | "retryable" | "blocked" | "needs_human" | "local_verified" /** Interactive Claude grade/reflection launched; inspect-only recovery next. */ | "awaiting_role"; export interface ProcessResultOutcome { readonly ok: boolean; readonly status: ProcessResultStatus; readonly task_id: string; readonly attempt: number; readonly version: number; readonly pending_verification: boolean; readonly result_commit?: string; readonly verification_outcome?: string; readonly grade_passed?: boolean; readonly draft_pr_url?: string | null; readonly reason?: string; readonly reused?: boolean; } export type TaskTerminalInspection = { readonly status: "non_terminal" | "done" | "blocked"; readonly task_id: string; readonly version: number; }; export type ResultService = { readonly processResult: (input: { readonly expectedRunId?: string; readonly expectedRunVersion?: number; readonly taskId: string; readonly expectedVersion: number; readonly expectedSourceDigest: string; }) => ProcessResultOutcome; readonly inspectTaskTerminal: (input: { readonly expectedRunId?: string; readonly expectedRunVersion?: number; readonly taskId: string; }) => TaskTerminalInspection; }; /** * Sealed production factory. Explicitly reconstructs ResultServiceConfig only — * never inspects, casts, or allowlists hidden seam keys. Excess properties on * the caller object are not forwarded. */ export declare function createResultService(config: ResultServiceConfig): ResultService; /** * Production adapter factories live in src/v2/result-adapters.ts. * Kernel keeps contracts + processResult only; lineage resolution is in result-lineage.ts. */