/** * ScribeRunner — Third peer runner for the Internalization Engine (PRI-109). * * Migrated to extend BasePeerRunner (PRI-302). The shared lease → buildContext → * invoke → poll → fetch → validate → succeed/fail pipeline is now in the base * class. This file only contains Scribe-specific logic. * * Key constraints (ADR-0003): * - Uses PDRuntimeAdapter for all LLM execution (no direct SDK calls) * - Does NOT directly invoke Artificer (host layer enqueues next task) * - No plugin-layer imports (core is infrastructure-agnostic) * - No timer-based scheduling (sleep via setTimeout is polling-only) * - Uses RuntimeStateManager for all state operations * * Pipeline: * 1. acquireLease — isolated try/catch, lease_conflict is non-mutating * 2. resolve Philosopher dependency from dependencyTaskIds * 3. fetch Philosopher artifact via PIArtifactStore * 4. startRun with outputSchemaRef: 'scribe-output-v1' * 5. pollUntilTerminal * 6. fetchOutput → validate as unknown → cast to ScribeOutputV1 * 7. updateRunOutput → persist serialized output * 8. write PIArtifact → markTaskSucceeded with scribe:// resultRef * * @see docs/adr/0003-peer-agent-state-machine-orchestration.md * @see BasePeerRunner in runner/base-peer-runner.ts */ import type { RunHandle } from '../runtime-protocol.js'; import type { ScribeOutputV1, ScribeValidator } from './scribe-output.js'; import type { TaskRecord } from '../task-status.js'; import { type PDErrorCategory } from '../error-categories.js'; import type { FormationContext } from './formation-context.js'; import { BasePeerRunner } from '../runner/base-peer-runner.js'; import type { PeerRunnerOptions, PeerRunnerDeps, PeerRunnerResult, PeerRunnerValidationResult } from '../runner/peer-runner-types.js'; import type { OutputLanguage } from '../language-directive.js'; /** Context built by ScribeRunner.buildContext() and consumed by invokeRuntime(). */ interface ScribeContext { readonly contextHash: string; readonly philosopherArtifact: string; readonly sourcePhilosopherArtifactId: string; /** * PRI-816 (R-01): authoritative dreamer artifact id extracted from the * philosopher artifact's `sourceDreamerArtifactId`. Optional — absent on * pre-PRI-508 philosopher artifacts, where the scribe keeps emitting no * `sourceTrace.dreamerArtifactId` (backward compatible). */ readonly sourceDreamerArtifactId?: string; /** * PRI-838: bounded projection of the formation evidence this formation was * built from — the dreamer's full (bounded) proposal set, the source * diagnosis, and provenance. Optional: undefined when the dreamer artifact * could not be resolved, in which case the prompt keeps its pre-PRI-838 * shape exactly (legacy / degraded compatibility). */ readonly formationContext?: FormationContext; } export type ScribeRunnerResultStatus = 'succeeded' | 'failed' | 'retried'; export interface ScribeRunnerResult { readonly status: ScribeRunnerResultStatus; readonly taskId: string; readonly runId?: string; readonly artifactId?: string; readonly resultRef?: string; readonly contextHash?: string; readonly output?: ScribeOutputV1; readonly errorCategory?: PDErrorCategory; readonly failureReason?: string; readonly attemptCount: number; } export type ScribeRunnerOptions = PeerRunnerOptions; export interface ResolvedScribeRunnerOptions { readonly pollIntervalMs: number; readonly timeoutMs: number; readonly defaultMaxAttempts: number; readonly owner: string; readonly runtimeKind: string; readonly agentId: string; /** Owner's preferred language for principle generation (PRI-336). Undefined = no directive. */ readonly outputLanguage?: OutputLanguage; /** Whether to inject CORE_PRINCIPLES into the scribe prompt (default: true). */ readonly coreGrounding: boolean; } export declare const DEFAULT_SCRIBE_RUNNER_OPTIONS: Readonly>; export declare function resolveScribeRunnerOptions(options: ScribeRunnerOptions): ResolvedScribeRunnerOptions; export interface ScribeRunnerDeps extends PeerRunnerDeps { readonly validator: ScribeValidator; } export declare class ScribeRunner extends BasePeerRunner { private readonly validator; constructor(deps: ScribeRunnerDeps, options: PeerRunnerOptions); get permanentErrorCategories(): ReadonlySet; buildContext(taskId: string): Promise; /** * PRI-838: narrow task view for formation-context resolution. * * Phase identity exists ONLY on the task row — every PI artifact is written * with `artifact_kind = 'principle'`, so the diagnostic predecessor cannot be * identified from artifact records alone (see formation-context.ts). */ private lookupFormationTask; invokeRuntime(taskId: string, context: ScribeContext): Promise; /** 修订轮反馈 (P0-E): 读取任务元数据 revisionFeedback, 缺失返回 null */ private resolveRevisionFeedback; validateOutput(output: unknown, taskId: string, context: ScribeContext): Promise; succeedTask(taskId: string, runId: string, output: ScribeOutputV1, task: TaskRecord, contextHash: string, context: ScribeContext): Promise>; /** * Re-inject taskId if stripped by stripLineageFields (PRI-272 / ERR-008). * Only fill when absent via Object.hasOwn — present-but-falsy values * must reach validation and fail loud (Runtime Contract Rule 3). * * The generatedAt override is handled by the base class via * super.postFetchTransform(). */ protected postFetchTransform(taskId: string, untrustedOutput: unknown, _context: ScribeContext): void; protected emitSuccessTelemetry(taskId: string, output: ScribeOutputV1): void; } export {}; //# sourceMappingURL=scribe-runner.d.ts.map