/** * DiagRouterRunner — Stage C runner for the split diagnostician pipeline. * * Receives both Stage A (Root Cause) and Stage B (Distiller) artifacts and * produces the final DiagnosticianOutputV1 — the unchanged downstream contract * consumed by the rest of the system. * * Unlike Stages A and B which only write PIArtifacts, Stage C commits via * DiagnosticianCommitter (same as the monolithic DiagnosticianRunner) and * calls the onDiagnosisComplete bridge callback (INF-9). * * Extends BasePeerRunner following the DreamerRunner pattern (PRI-302). * The shared lease → buildContext → invoke → poll → fetch → validate → * succeed/fail pipeline is in the base class. This file only contains * Stage C–specific logic. * * Key constraints: * - Uses PDRuntimeAdapter for all LLM execution (no direct SDK calls) * - No plugin-layer imports (core is infrastructure-agnostic) * - Uses RuntimeStateManager for all state operations * - Commits via DiagnosticianCommitter (reuses existing committer) * Does NOT call onDiagnosisComplete — that is the bridge's responsibility * (PainSignalBridge.onPainDetected) to avoid double invocation (P0-1 fix). * - Router MUST NOT re-derive root causes or invent new principles * * @see PRI-372 * @see BasePeerRunner in runner/base-peer-runner.ts */ import type { RunHandle } from '../runtime-protocol.js'; import type { DiagnosticianOutputV1 } from '../diagnostician-output.js'; import type { DiagRootCauseOutputV1 } from '../diagnostician/diag-rootcause-output.js'; import type { DiagDistillerOutputV1 } from '../diagnostician/diag-distiller-output.js'; import type { DiagnosticianCommitter } from '../store/commit/diagnostician-committer.js'; import type { TaskRecord } from '../task-status.js'; import { type PDErrorCategory } from '../error-categories.js'; import type { EffectivePdConfig } from '../config/pd-config-types.js'; import { BasePeerRunner } from '../runner/base-peer-runner.js'; import type { PeerRunnerOptions, PeerRunnerDeps, PeerRunnerResult, PeerRunnerValidationResult } from '../runner/peer-runner-types.js'; /** Context built by DiagRouterRunner.buildContext() and consumed by invokeRuntime(). */ interface DiagRouterContext { readonly contextHash: string; readonly contextRefs: string[]; readonly rootCauseArtifactId: string; readonly rootCauseOutput: DiagRootCauseOutputV1; readonly distillerArtifactId: string; readonly distillerOutput: DiagDistillerOutputV1; } export interface DiagRouterRunnerDeps extends PeerRunnerDeps { readonly committer: DiagnosticianCommitter; } export interface DiagRouterRunnerOptions extends PeerRunnerOptions { /** Effective PD config for feature flag resolution (ADR-0019). */ readonly effectiveConfig?: EffectivePdConfig; } /** * Stage C runner for the split diagnostician pipeline. * * Produces the final DiagnosticianOutputV1 by routing the distilled principle * from Stage B into the appropriate recommendation taxonomy kind(s). Commits * via DiagnosticianCommitter (same as the monolithic DiagnosticianRunner) and * calls onDiagnosisComplete after commit. * * @see PRI-372 */ export declare class DiagRouterRunner extends BasePeerRunner { private readonly committer; private readonly defaultValidator; constructor(deps: DiagRouterRunnerDeps, options: DiagRouterRunnerOptions); get permanentErrorCategories(): ReadonlySet; buildContext(taskId: string): Promise; invokeRuntime(taskId: string, context: DiagRouterContext): Promise; validateOutput(output: unknown, taskId: string, _context: DiagRouterContext): Promise; succeedTask(taskId: string, runId: string, output: DiagnosticianOutputV1, task: TaskRecord, contextHash: string, _context: DiagRouterContext): Promise>; /** * P0: Inject invariant fields from upstream artifacts into LLM output. * P2: Override rootCause/evidence/confidence if LLM generated inconsistent values. * * These fields are deterministic copies from Stage A and Stage B — the LLM * MUST NOT control them. By injecting here (before validation), we: * 1. Eliminate the risk of LLM rephrasing rootCause or inventing evidence * 2. Reduce LLM output complexity (fewer fields = fewer errors on weak models) * 3. Ensure EP-07 compliance (rootCause from Stage A, confidence from Stage B) * * Also re-injects taskId if stripped by stripLineageFields (PRI-272 / ERR-008). */ protected postFetchTransform(taskId: string, untrustedOutput: unknown, context: DiagRouterContext): void; protected emitSuccessTelemetry(taskId: string, output: DiagnosticianOutputV1, _context: DiagRouterContext): void; } export {}; //# sourceMappingURL=diag-router-runner.d.ts.map