/** * Repair Replay Resolver — PRI-634 PR-A (SPEC Slice B, §23–§30). * * Resolves the deterministic replay evidence a repair round needs, BY * REFERENCE, from the one durable authority: the source Evaluator artifact's * runtime-owned `adversarialResult`. The resolved RepairReplayContext exists * only in prompt context — it is never persisted, never a second fact store, * and RepairPayload stays a bounded control payload. * * Pipeline: * RepairPayload.sourceEvaluatorTaskId * → evaluator task's durable completionIntent.sourceRunId (deterministic * artifact identity: pi-art--) * → PiArtifactStore.getArtifactById (fallback: listBySourceTaskId when * the intent is absent — exactly-one rule, otherwise fail loud) * → runtime-validate contentJson.adversarialResult (rc-1/rc-4) * → normalize legacy actualDecision= representation (SPEC §21) * → partition trace failures / system failures / global violations * → bounded deterministic stratified selection (SPEC §30) * * Trust boundary: artifact contentJson is durable-but-untrusted at read time. * Every field access uses Object.hasOwn (rc-5) and typeof/Array.isArray * guards (rc-4) — no `as` casts. Missing or ambiguous evidence fails loud * with a structured reason (rc-3/rc-9) so the caller can refuse a blind * repair retry (SPEC §27). */ import type { TaskRecord } from '../task-status.js'; import type { PIArtifactStore } from './pi-artifact.js'; /** * Repair-prompt budget cap for replay evidence (SPEC §29): at most this many * failure entries enter the Artificer repair prompt. 16 entries × ~30 tokens * stays comfortably inside the existing prompt budget. */ export declare const MAX_REPLAY_FAILURES_IN_REPAIR = 16; export interface ReplayFailureEvidence { readonly caseId: string; readonly attackType?: string; readonly expectedDecision?: string; /** Real decision the rule returned; absent for timeout/throw failures. */ readonly actualDecision?: string; readonly errorType: string; readonly message?: string; } export interface RepairReplayContext { readonly sourceEvaluatorTaskId: string; readonly sourceEvaluatorArtifactId: string; /** True — the presence of a runtime-owned adversarialResult means replay ran. */ readonly ran: boolean; readonly passed: boolean; /** Total durable failures (pre-selection). */ readonly failedCaseCount: number; /** Selected trace-case failures (bounded, mismatch-first stratified). */ readonly traceFailures: readonly ReplayFailureEvidence[]; /** Selected system-sentinel failures (bounded; excludes forbidden patterns). */ readonly systemFailures: readonly ReplayFailureEvidence[]; /** Selected forbidden-pattern violations (bounded, shared budget). */ readonly globalViolations: readonly string[]; /** Total durable forbidden-pattern violations (pre-selection). */ readonly globalViolationCount: number; /** True when bounded selection omitted any durable failure or violation. */ readonly truncated: boolean; } export type RepairReplayResolutionFailureReason = 'task_missing' | 'artifact_missing' | 'artifact_ambiguous' | 'adversarial_result_missing' | 'adversarial_result_invalid'; export type RepairReplayResolution = { readonly ok: true; readonly context: RepairReplayContext; } | { readonly ok: false; readonly reason: RepairReplayResolutionFailureReason; readonly detail: string; }; export interface RepairReplayResolverDeps { readonly artifactStore: Pick; readonly getTask: (taskId: string) => Promise; } /** * Bounded deterministic stratified selection (SPEC §30 as tightened by review * 2026-09-02). Trace failures, system failures, and global violations share * ONE capacity budget — no evidence class can bypass the prompt bound: * * 1. system failure representatives (stable order); * 2. one global-violation representative for the whole violation group; * 3. true decision mismatches FIRST by expected axis — at least one * expected=allow, one expected=block, one expected=propose_correction * representative each (when present) — so low-value runtime failures can * never evict every behavioral mismatch from the prompt; * 4. remaining errorType × expectedDecision group representatives * (stable first-occurrence order, mismatch-preferring); * 5. stable-order fill over trace → system → remaining violations; * 6. truncated=true when anything was omitted. */ export declare function selectBoundedReplayFailures(params: { traceFailures: readonly ReplayFailureEvidence[]; systemFailures: readonly ReplayFailureEvidence[]; globalViolations: readonly string[]; capacity: number; }): { readonly selectedTrace: readonly ReplayFailureEvidence[]; readonly selectedSystem: readonly ReplayFailureEvidence[]; readonly selectedGlobalViolations: readonly string[]; readonly truncated: boolean; }; /** * Resolve the bounded, normalized replay-evidence context for a repair round. * Pure read + transform: no writes, no telemetry side effects — callers own * observability. */ export declare function resolveRepairReplayContext(params: { readonly sourceEvaluatorTaskId: string; readonly deps: RepairReplayResolverDeps; }): Promise; //# sourceMappingURL=repair-replay-resolver.d.ts.map