@alis-build/harness-eval 0.1.2 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +92 -8
- package/dist/adapters/claude-code/index.d.ts +2 -2
- package/dist/adapters/claude-code/index.js +2 -1
- package/dist/adapters/codex/index.d.ts +68 -0
- package/dist/adapters/codex/index.js +3 -0
- package/dist/{claude-code-DZ4Vkgp6.js → claude-code-C_7hxC8z.js} +3 -245
- package/dist/claude-code-C_7hxC8z.js.map +1 -0
- package/dist/cli/bin.js +131 -151
- package/dist/cli/bin.js.map +1 -1
- package/dist/codex-0cHO2te9.js +496 -0
- package/dist/codex-0cHO2te9.js.map +1 -0
- package/dist/config/loader.d.ts +2 -2
- package/dist/config/loader.js +2 -2
- package/dist/{index-V22PrR0p.d.ts → index-DnvP1UBl.d.ts} +2 -2
- package/dist/index.d.ts +132 -6
- package/dist/index.js +6 -5
- package/dist/index.js.map +1 -1
- package/dist/loader-B1WmGGzf.d.ts +107 -0
- package/dist/{loader-DcI0KfRX.js → loader-DnQ6Jt0i.js} +472 -209
- package/dist/loader-DnQ6Jt0i.js.map +1 -0
- package/dist/{projections-BcX7w-f6.js → reporter-Biy-5-9M.js} +1335 -758
- package/dist/reporter-Biy-5-9M.js.map +1 -0
- package/dist/runner/suite.d.ts +1 -1
- package/dist/runner/suite.js +1 -1
- package/dist/{suite-DPJMIEbu.d.ts → suite-BEShV0by.d.ts} +2 -2
- package/dist/{suite-Dlzl-HI0.js → suite-BcP64nlb.js} +16 -2
- package/dist/{suite-Dlzl-HI0.js.map → suite-BcP64nlb.js.map} +1 -1
- package/dist/{types-CD3TwOtZ.d.ts → types-0QkNVyp9.d.ts} +2 -2
- package/dist/types-Bac8_Ixb.js +246 -0
- package/dist/types-Bac8_Ixb.js.map +1 -0
- package/dist/types-Bu8uOZZN.d.ts +77 -0
- package/dist/{types-B9H4IZtA.d.ts → types-C0gBkl0-.d.ts} +3 -2
- package/package.json +6 -2
- package/dist/claude-code-DZ4Vkgp6.js.map +0 -1
- package/dist/loader-C9yQHUPC.d.ts +0 -50
- package/dist/loader-DcI0KfRX.js.map +0 -1
- package/dist/projections-BcX7w-f6.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reporter-Biy-5-9M.js","names":["DEFAULT_TIMEOUT_MS","buildJudgeArgs","parseYaml","formatJson","RESET","GREEN","RED","formatRate"],"sources":["../src/types/eval-record.ts","../src/grader/prompt.ts","../src/grader/parse.ts","../src/grader/spawn-judge.ts","../src/grader/claude-grader.ts","../src/grader/codex-grader.ts","../src/grader/expectations.ts","../src/grader/transcript.ts","../src/eval-record/judge-metadata.ts","../src/grader/grade-report.ts","../src/grader/resolve-grade-options.ts","../src/grader/format-console.ts","../src/eval-interchange/normalize.ts","../src/eval-interchange/protojson/trajectory-instances.ts","../src/eval-interchange/protojson/evaluation-instance.ts","../src/metrics/trajectory.ts","../src/eval-interchange/protojson/harness-metrics.ts","../src/eval-interchange/enrich.ts","../src/eval-record/build.ts","../src/eval-interchange/projections.ts","../src/pipeline/resolve-inputs.ts","../src/cli/args.ts","../src/cli/commands/envelope.ts","../src/pipeline/run-pipeline.ts","../src/otel/attributes.ts","../src/otel/messages.ts","../src/otel/types.ts","../src/otel/emitter.ts","../src/reporter/format-console.ts","../src/reporter/format-json.ts","../src/reporter/format-markdown.ts","../src/reporter/renderable.ts","../src/reporter/index.ts"],"sourcesContent":["/**\n * Cross-harness eval record contract for storage, CI/CD, and external judges.\n */\n\nimport type { AdapterDiagnostics } from \"../adapters/types\";\nimport type { GradedExpectation, GradingSummary } from \"../grader/types\";\nimport type {\n EvaluationInstanceJson,\n HarnessMetrics,\n ProtojsonTrajectory,\n TrajectoryInstancesJson,\n} from \"./eval-interchange\";\nimport type { AssertionResult } from \"./assertions\";\nimport type { TrajectoryView } from \"./trajectory\";\n\n/** Schema version for {@link EvalRunEnvelope} JSON documents. */\nexport const EVAL_RUN_SCHEMA_VERSION = \"1.0\";\n\n/** Schema version embedded in each {@link TrajectoryView} at export time. */\nexport const TRAJECTORY_SCHEMA_VERSION = \"1.0\";\n\n/** Link to the suite spec that produced a run. */\nexport interface SuiteReference {\n uri?: string;\n id?: string;\n contentHash?: string;\n}\n\n/** Harness that executed the run. */\nexport interface HarnessInfo {\n adapter: string;\n frameworkVersion?: string;\n harnessVersion?: string;\n}\n\n/** CI, git, or runtime provenance for correlation in the DB. */\nexport interface EvalProvenance {\n runId?: string;\n ci?: {\n provider?: string;\n jobId?: string;\n pipelineId?: string;\n url?: string;\n };\n git?: {\n commit?: string;\n branch?: string;\n repository?: string;\n };\n pluginVersion?: string;\n triggeredBy?: string;\n [key: string]: unknown;\n}\n\n/** Aggregate behavioral summary for the run. */\nexport interface EvalRunSummary {\n cellsTotal: number;\n cellsPassed: number;\n behavioralPass: boolean;\n outcomePass?: boolean;\n}\n\n/** Identity of the judge that produced outcome grades. */\nexport interface JudgeInfo {\n id: string;\n model?: string;\n version?: string;\n /** Grading adapter id when known (e.g. `codex`, `claude-code`). */\n adapter?: string;\n}\n\n/** Outcome grades for one repetition (built-in or external judge). */\nexport interface OutcomeGrades {\n judge: JudgeInfo;\n expectations: GradedExpectation[];\n summary: GradingSummary;\n evalFeedback?: {\n suggestions: Array<{ assertion?: string; reason: string }>;\n overall: string;\n };\n error?: string;\n}\n\n/** Score from an external eval framework (LangSmith, Braintrust, custom). */\nexport interface ExternalScore {\n source: string;\n metric: string;\n value: number | boolean | string;\n metadata?: Record<string, unknown>;\n}\n\n/** Optional large or vendor-specific blobs (store by reference in DB when possible). */\nexport interface EvalArtifacts {\n rawStreamEvents?: unknown[];\n otlpTraceUri?: string;\n transcript?: string;\n}\n\n/** One harness invocation — the unit external judges and trajectory queries use. */\nexport interface EvalRepetition {\n repetitionIndex: number;\n durationMs: number;\n trajectory?: TrajectoryView & { schemaVersion: string };\n diagnostics?: Partial<AdapterDiagnostics>;\n assertionResults: AssertionResult[];\n outcomeGrades?: OutcomeGrades;\n externalScores?: ExternalScore[];\n artifacts?: EvalArtifacts;\n\n /** Vertex EvaluationInstance protojson wire object. */\n evaluationInstance?: EvaluationInstanceJson;\n\n /** Vertex Trajectory*Instance protojson wire objects keyed by metric. */\n trajectoryInstances?: TrajectoryInstancesJson;\n\n /** Harness-precomputed trajectory metric scores (camelCase). */\n harnessMetrics?: HarnessMetrics;\n\n latencySeconds?: number;\n failure?: 0 | 1;\n\n error?: {\n message: string;\n diagnostics?: Partial<AdapterDiagnostics>;\n };\n}\n\n/** Behavioral stats for one assertion across repetitions in a cell. */\nexport interface EvalAssertionStat {\n description: string;\n threshold: number;\n passedCount: number;\n evaluatedCount: number;\n passRate: number;\n meetsThreshold: boolean;\n}\n\n/** One (test case × matrix cell) result. */\nexport interface EvalCellResult {\n caseId: string;\n category?: string;\n notes?: string;\n prompt?: string;\n expectations?: string[];\n cellLabel: string;\n axes?: Record<string, string>;\n /** Reference trajectory in Vertex protojson wire format. */\n referenceTrajectory?: ProtojsonTrajectory;\n humanRatings?: Record<string, number>;\n assertionStats: EvalAssertionStat[];\n adapterErrors: number;\n behavioralPass: boolean;\n outcomePass?: boolean;\n repetitions: EvalRepetition[];\n}\n\n/** Top-level document for CI/CD pipelines, APIs, and databases. */\nexport interface EvalRunEnvelope {\n schemaVersion: typeof EVAL_RUN_SCHEMA_VERSION;\n runId: string;\n startedAt: string;\n durationMs: number;\n suite?: SuiteReference;\n harness: HarnessInfo;\n provenance?: EvalProvenance;\n summary: EvalRunSummary;\n cells: EvalCellResult[];\n}\n\nexport interface BuildEvalRunEnvelopeOptions {\n /** Override envelope runId; defaults to a random UUID. */\n runId?: string;\n /** Link to the suite YAML that produced the run. */\n suite?: SuiteReference;\n /** Harness adapter metadata; adapter defaults to `\"claude-code\"`. */\n harness?: Partial<HarnessInfo>;\n /** CI, git, and runtime provenance for correlation. */\n provenance?: EvalProvenance;\n /** Outcome grades to merge from a grader run. */\n grading?: {\n gradedAt?: string;\n sourceReport?: string;\n results: Array<{\n caseId: string;\n cellLabel: string;\n repetitionIndex: number;\n expectations: GradedExpectation[];\n summary: GradingSummary;\n evalFeedback?: OutcomeGrades[\"evalFeedback\"];\n graderError?: string;\n durationMs?: number;\n }>;\n judge?: JudgeInfo;\n };\n /** Include text transcript artifact (default true). */\n includeTranscript?: boolean;\n /** Include raw stream-json events (default false; debug only). */\n includeRawStreamEvents?: boolean;\n}\n","/**\n * Build the grader prompt for Claude subprocess grading.\n */\n\nimport type { GraderInput } from \"./types\";\n\n/**\n * Build the full grader prompt including eval prompt, transcript, and schema.\n *\n * When `systemInstruction` is set it is prepended as a judge-specific prefix.\n */\nexport function buildGraderPrompt(input: GraderInput): string {\n const expectationList = input.expectations\n .map((e, i) => `${i + 1}. ${e}`)\n .join(\"\\n\");\n\n const prefix = input.systemInstruction\n ? `${input.systemInstruction.trim()}\\n\\n`\n : \"\";\n\n return `${prefix}You are an automated evaluation grader (not the agent under test). Your only job is to score expectations against the transcript below.\n\nYour job is to evaluate each expectation against the transcript and final response.\nPASS only when there is clear evidence in the transcript or final response.\nWhen uncertain, FAIL — burden of proof is on PASS.\n\nAlso critique the expectations themselves if any are trivially satisfied or miss important outcomes.\n\n## Eval prompt\n\n${input.prompt}\n\n## Execution transcript\n\n${input.transcript}\n\n## Expectations to grade\n\n${expectationList}\n\n## Output format\n\nRespond with ONLY a single JSON object (no markdown fences, no commentary) matching this schema:\n\n{\n \"expectations\": [\n { \"text\": \"<original expectation>\", \"passed\": true|false, \"evidence\": \"<quote or description>\" }\n ],\n \"summary\": { \"passed\": <int>, \"failed\": <int>, \"total\": <int>, \"pass_rate\": <0.0-1.0> },\n \"eval_feedback\": {\n \"suggestions\": [{ \"assertion\": \"<optional>\", \"reason\": \"<string>\" }],\n \"overall\": \"<brief assessment>\"\n }\n}\n\nInclude every expectation in the same order. summary must match the expectations array.`;\n}\n","/**\n * Parse grader JSON from Claude stdout / response text.\n */\n\nimport type {\n EvalFeedback,\n GradedExpectation,\n GradingSummary,\n GraderOutput,\n} from \"./types\";\n\n/**\n * Extract assistant text from Claude stdout.\n *\n * Handles plain text, single JSON result envelopes, stream-json arrays, and\n * assistant message objects — the judge subprocess may emit any of these\n * depending on Claude Code version and flags.\n */\nexport function extractClaudeResponseText(stdout: string): string {\n const trimmed = stdout.trim();\n if (!trimmed) return \"\";\n\n try {\n const data = JSON.parse(trimmed) as unknown;\n\n if (Array.isArray(data)) {\n return extractFromEventArray(data) ?? trimmed;\n }\n\n if (typeof data === \"object\" && data !== null) {\n const event = data as { type?: string; result?: string; message?: unknown };\n if (event.type === \"result\" && typeof event.result === \"string\") {\n return event.result;\n }\n if (event.type === \"assistant\" && event.message) {\n const text = textFromAssistantMessage(event.message);\n if (text) return text;\n }\n }\n } catch {\n // fall through to raw stdout\n }\n\n return trimmed;\n}\n\n/**\n * Extract assistant text from Codex judge stdout.\n *\n * Handles plain text and JSONL streams from accidental `--json` usage.\n */\nexport function extractCodexResponseText(stdout: string): string {\n const trimmed = stdout.trim();\n if (!trimmed) return \"\";\n\n const lines = trimmed.split(\"\\n\").filter((line) => line.trim().length > 0);\n if (lines.length > 1) {\n // Scan from the end — the final assistant_message in JSONL is the judge verdict.\n for (let i = lines.length - 1; i >= 0; i--) {\n try {\n const event = JSON.parse(lines[i]!) as {\n type?: string;\n item?: { type?: string; item_type?: string; text?: string };\n };\n if (\n event.type === \"item.completed\" &&\n (event.item?.type === \"assistant_message\" ||\n event.item?.item_type === \"assistant_message\") &&\n event.item.text\n ) {\n return event.item.text;\n }\n } catch {\n continue;\n }\n }\n }\n\n return trimmed;\n}\n\n/** Walk a stream-json event array and return the final assistant or result text. */\nfunction extractFromEventArray(events: unknown[]): string | null {\n const result = events.find(\n (e) =>\n typeof e === \"object\" &&\n e !== null &&\n (e as { type?: string }).type === \"result\",\n ) as { result?: string } | undefined;\n if (result?.result) return result.result;\n\n const assistantTexts: string[] = [];\n for (const event of events) {\n if (\n typeof event === \"object\" &&\n event !== null &&\n (event as { type?: string }).type === \"assistant\"\n ) {\n const text = textFromAssistantMessage(\n (event as { message?: unknown }).message,\n );\n if (text) assistantTexts.push(text);\n }\n }\n if (assistantTexts.length > 0) {\n return assistantTexts[assistantTexts.length - 1];\n }\n return null;\n}\n\n/** Concatenate text blocks from an Anthropic-style assistant message object. */\nfunction textFromAssistantMessage(message: unknown): string | null {\n if (!message || typeof message !== \"object\") return null;\n const content = (message as { content?: unknown }).content;\n if (typeof content === \"string\") return content;\n if (!Array.isArray(content)) return null;\n\n const texts: string[] = [];\n for (const block of content) {\n if (\n typeof block === \"object\" &&\n block !== null &&\n (block as { type?: string }).type === \"text\" &&\n typeof (block as { text?: string }).text === \"string\"\n ) {\n texts.push((block as { text: string }).text);\n }\n }\n return texts.length > 0 ? texts.join(\"\\n\") : null;\n}\n\n/**\n * Parse grader JSON from response text.\n *\n * Tries the raw string first, then fenced code blocks and brace-delimited\n * substrings. Returns null when no valid expectations array is found.\n */\nexport function parseGraderJson(text: string): GraderOutput | null {\n const candidates = [text.trim(), extractJsonBlock(text)];\n for (const candidate of candidates) {\n if (!candidate) continue;\n try {\n const raw = JSON.parse(candidate) as RawGraderJson;\n const normalized = normalizeGraderJson(raw);\n if (normalized.expectations.length > 0) {\n return normalized;\n }\n } catch {\n continue;\n }\n }\n return null;\n}\n\n/** Raw grader JSON shape before normalization (snake_case from prompt schema). */\ninterface RawGraderJson {\n expectations?: Array<{\n text?: string;\n passed?: boolean;\n evidence?: string;\n }>;\n summary?: {\n passed?: number;\n failed?: number;\n total?: number;\n pass_rate?: number;\n passRate?: number;\n };\n eval_feedback?: {\n suggestions?: Array<{ assertion?: string; reason?: string }>;\n overall?: string;\n };\n}\n\n/** Extract JSON from markdown fences or the outermost `{...}` substring. */\nfunction extractJsonBlock(text: string): string | null {\n const fence = text.match(/```(?:json)?\\s*([\\s\\S]*?)```/);\n if (fence?.[1]) return fence[1].trim();\n\n const start = text.indexOf(\"{\");\n const end = text.lastIndexOf(\"}\");\n if (start >= 0 && end > start) {\n return text.slice(start, end + 1);\n }\n return null;\n}\n\n/** Map raw grader JSON to runtime {@link GraderOutput} with computed summary. */\nfunction normalizeGraderJson(raw: RawGraderJson): GraderOutput {\n const expectations: GradedExpectation[] = (raw.expectations ?? []).map(\n (e) => ({\n text: e.text ?? \"\",\n passed: Boolean(e.passed),\n evidence: e.evidence ?? \"\",\n }),\n );\n\n const passed = expectations.filter((e) => e.passed).length;\n const failed = expectations.length - passed;\n const total = expectations.length;\n const passRate =\n raw.summary?.pass_rate ??\n raw.summary?.passRate ??\n (total === 0 ? 0 : passed / total);\n\n const summary: GradingSummary = {\n passed: raw.summary?.passed ?? passed,\n failed: raw.summary?.failed ?? failed,\n total: raw.summary?.total ?? total,\n passRate,\n };\n\n let evalFeedback: EvalFeedback | undefined;\n if (raw.eval_feedback) {\n evalFeedback = {\n suggestions: (raw.eval_feedback.suggestions ?? []).map((s) => ({\n assertion: s.assertion,\n reason: s.reason ?? \"\",\n })),\n overall: raw.eval_feedback.overall ?? \"\",\n };\n }\n\n return { expectations, summary, evalFeedback };\n}\n","/**\n * Shared subprocess utilities for judge graders (Claude + Codex).\n *\n * Owns detached spawn, process-group teardown, and SIGTERM → SIGKILL\n * escalation so both graders share one implementation.\n */\n\nimport { spawn, type ChildProcess } from \"node:child_process\";\n\nconst KILL_GRACE_MS = 5_000;\n\n/** Kill the detached process group (fallback to single process if group kill fails). */\nexport function killTree(child: ChildProcess, signal: NodeJS.Signals): void {\n if (child.pid === undefined) return;\n try {\n process.kill(-child.pid, signal);\n } catch {\n try {\n child.kill(signal);\n } catch {\n // process already gone\n }\n }\n}\n\nexport interface SpawnJudgeOptions {\n binary: string;\n args: string[];\n timeoutMs: number;\n env?: Record<string, string | undefined>;\n cwd?: string;\n}\n\n/**\n * Spawn a judge subprocess with process-group teardown and collect stdout.\n *\n * Non-zero exit with empty stdout is treated as failure; partial stdout on\n * non-zero exit is retained (judges sometimes exit non-zero after emitting JSON).\n */\nexport function spawnCollectStdout(options: SpawnJudgeOptions): Promise<string> {\n const { binary, args, timeoutMs, env, cwd } = options;\n\n return new Promise((resolve, reject) => {\n const child = spawn(binary, args, {\n env: env ?? process.env,\n cwd,\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n detached: true,\n });\n\n const chunks: string[] = [];\n child.stdout?.setEncoding(\"utf8\");\n child.stdout?.on(\"data\", (c: string) => chunks.push(c));\n\n const stderrChunks: string[] = [];\n child.stderr?.setEncoding(\"utf8\");\n child.stderr?.on(\"data\", (c: string) => stderrChunks.push(c));\n\n let killEscalation: NodeJS.Timeout | null = null;\n\n const timer = setTimeout(() => {\n killTree(child, \"SIGTERM\");\n killEscalation = setTimeout(() => killTree(child, \"SIGKILL\"), KILL_GRACE_MS);\n const stderrHint = stderrChunks.join(\"\").trim().slice(0, 400);\n reject(\n new Error(\n `grader timed out after ${timeoutMs}ms` +\n (stderrHint ? ` (stderr: ${stderrHint})` : \"\"),\n ),\n );\n }, timeoutMs);\n\n const finalize = (err?: Error) => {\n clearTimeout(timer);\n if (killEscalation) clearTimeout(killEscalation);\n if (err) reject(err);\n else resolve(chunks.join(\"\"));\n };\n\n child.on(\"error\", (err) => finalize(err));\n child.on(\"close\", (code) => {\n if (code !== 0 && chunks.length === 0) {\n finalize(\n new Error(\n `grader exited ${code}: ${stderrChunks.join(\"\").slice(0, 500)}`,\n ),\n );\n } else {\n finalize();\n }\n });\n });\n}\n","/**\n * Grade expectations by spawning Claude as judge (skill-creator grader pattern).\n */\n\nimport { buildJudgeArgs } from \"../adapters/claude-code/flags\";\nimport type { ClaudeCodeOptions } from \"../adapters/claude-code/types\";\nimport { buildGraderPrompt } from \"./prompt\";\nimport { extractClaudeResponseText, parseGraderJson } from \"./parse\";\nimport { spawnCollectStdout } from \"./spawn-judge\";\nimport type { GraderFn, GraderInput, GraderOutput } from \"./types\";\n\nconst DEFAULT_TIMEOUT_MS = 300_000;\n\n/**\n * Judge subprocess defaults — grading is a single-shot JSON response, not an agent session.\n * Without these, Claude Code may load plugins/MCP and loop on tools until timeout.\n */\nexport const JUDGE_CLAUDE_DEFAULTS: ClaudeCodeOptions = {\n maxTurns: 1,\n bare: true,\n disableSlashCommands: true,\n noSessionPersistence: true,\n};\n\n/** Merge user-supplied Claude Code options over judge-safe defaults. */\nexport function mergeJudgeClaudeOptions(\n claudeCode?: ClaudeCodeOptions,\n): ClaudeCodeOptions {\n return { ...JUDGE_CLAUDE_DEFAULTS, ...claudeCode };\n}\n\n/** Options for {@link createClaudeGrader} / {@link runClaudeGrader}. */\nexport interface ClaudeGraderOptions {\n binary?: string;\n model?: string;\n timeoutMs?: number;\n env?: Record<string, string>;\n cwd?: string;\n claudeCode?: ClaudeCodeOptions;\n}\n\n/** Factory returning a {@link GraderFn} bound to subprocess options. */\nexport function createClaudeGrader(\n options: ClaudeGraderOptions = {},\n): GraderFn {\n return (input) => runClaudeGrader(input, options);\n}\n\n/**\n * Spawn Claude as judge, parse JSON response, align with input expectations.\n *\n * Unparseable output fails all expectations and sets {@link GraderOutput.error}.\n */\nexport async function runClaudeGrader(\n input: GraderInput,\n options: ClaudeGraderOptions = {},\n): Promise<GraderOutput> {\n const binary = options.binary ?? options.claudeCode?.binary ?? \"claude\";\n const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n const prompt = buildGraderPrompt(input);\n const model = options.model ?? options.claudeCode?.model;\n\n const args = buildJudgeArgs(prompt, {\n ...mergeJudgeClaudeOptions(options.claudeCode),\n model,\n });\n\n const stdout = await spawnCollectStdout({\n binary,\n args,\n timeoutMs,\n env: buildChildEnv(options.env),\n cwd: options.cwd,\n });\n const responseText = extractClaudeResponseText(stdout);\n const parsed = parseGraderJson(responseText);\n\n if (!parsed) {\n return {\n expectations: input.expectations.map((text) => ({\n text,\n passed: false,\n evidence: \"Grader returned unparseable output\",\n })),\n summary: {\n passed: 0,\n failed: input.expectations.length,\n total: input.expectations.length,\n passRate: 0,\n },\n error: `failed to parse grader JSON from response: ${responseText.slice(0, 200)}`,\n };\n }\n\n // Align expectation text with input order when grader omits text field\n const expectations = input.expectations.map((text, i) => {\n const graded = parsed.expectations[i];\n return {\n text,\n passed: graded?.passed ?? false,\n evidence: graded?.evidence ?? \"No evidence returned\",\n };\n });\n\n const passed = expectations.filter((e) => e.passed).length;\n const total = expectations.length;\n\n return {\n expectations,\n summary: {\n passed,\n failed: total - passed,\n total,\n passRate: total === 0 ? 0 : passed / total,\n },\n evalFeedback: parsed.evalFeedback,\n };\n}\n\n/**\n * Build subprocess env, stripping CLAUDECODE to avoid nested-session guards.\n */\nfunction buildChildEnv(extraEnv?: Record<string, string>): Record<string, string | undefined> {\n const env = { ...process.env, ...extraEnv };\n delete env.CLAUDECODE;\n return env;\n}\n","/**\n * Grade expectations by spawning Codex as judge.\n */\n\nimport { buildJudgeArgs } from \"../adapters/codex/flags\";\nimport type { CodexOptions } from \"../adapters/codex/types\";\nimport { buildGraderPrompt } from \"./prompt\";\nimport { extractCodexResponseText, parseGraderJson } from \"./parse\";\nimport { spawnCollectStdout } from \"./spawn-judge\";\nimport type { GraderFn, GraderInput, GraderOutput } from \"./types\";\n\nconst DEFAULT_TIMEOUT_MS = 300_000;\n\n/** Judge subprocess defaults — single-shot grading without persistent sessions. */\nexport const JUDGE_CODEX_DEFAULTS: CodexOptions = {\n ephemeral: true,\n ignoreUserConfig: true,\n skipGitRepoCheck: true,\n};\n\n/** Merge user-supplied Codex options over judge-safe defaults. */\nexport function mergeJudgeCodexOptions(\n codex?: CodexOptions,\n): CodexOptions {\n return { ...JUDGE_CODEX_DEFAULTS, ...codex };\n}\n\n/** Options for {@link createCodexGrader} / {@link runCodexGrader}. */\nexport interface CodexGraderOptions {\n binary?: string;\n model?: string;\n timeoutMs?: number;\n env?: Record<string, string>;\n cwd?: string;\n codex?: CodexOptions;\n}\n\n/** Factory returning a {@link GraderFn} bound to subprocess options. */\nexport function createCodexGrader(\n options: CodexGraderOptions = {},\n): GraderFn {\n return (input) => runCodexGrader(input, options);\n}\n\n/**\n * Spawn Codex as judge, parse JSON response, align with input expectations.\n *\n * Unparseable output fails all expectations and sets {@link GraderOutput.error}.\n */\nexport async function runCodexGrader(\n input: GraderInput,\n options: CodexGraderOptions = {},\n): Promise<GraderOutput> {\n const binary = options.binary ?? options.codex?.binary ?? \"codex\";\n const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n const prompt = buildGraderPrompt(input);\n const model = options.model ?? options.codex?.model;\n\n const args = buildJudgeArgs(prompt, {\n ...mergeJudgeCodexOptions(options.codex),\n model,\n cwd: options.cwd,\n });\n\n const stdout = await spawnCollectStdout({\n binary,\n args,\n timeoutMs,\n env: { ...process.env, ...options.env },\n cwd: options.cwd,\n });\n const responseText = extractCodexResponseText(stdout);\n const parsed = parseGraderJson(responseText);\n\n if (!parsed) {\n return {\n expectations: input.expectations.map((text) => ({\n text,\n passed: false,\n evidence: \"Grader returned unparseable output\",\n })),\n summary: {\n passed: 0,\n failed: input.expectations.length,\n total: input.expectations.length,\n passRate: 0,\n },\n error: `failed to parse grader JSON from response: ${responseText.slice(0, 200)}`,\n };\n }\n\n const expectations = input.expectations.map((text, i) => {\n const graded = parsed.expectations[i];\n return {\n text,\n passed: graded?.passed ?? false,\n evidence: graded?.evidence ?? \"No evidence returned\",\n };\n });\n\n const passed = expectations.filter((e) => e.passed).length;\n const total = expectations.length;\n\n return {\n expectations,\n summary: {\n passed,\n failed: total - passed,\n total,\n passRate: total === 0 ? 0 : passed / total,\n },\n evalFeedback: parsed.evalFeedback,\n };\n}\n\n","/**\n * Load expectations sidecar (YAML or JSON).\n */\n\nimport { readFile } from \"node:fs/promises\";\n\nimport { parse as parseYaml } from \"yaml\";\n\nimport type { ExpectationsMap } from \"./types\";\n\n/**\n * Load expectations sidecar (YAML or JSON).\n *\n * File format: `{ \"<caseId>\": [\"expectation 1\", ...], ... }`.\n */\nexport async function loadExpectationsMap(path: string): Promise<ExpectationsMap> {\n const text = await readFile(path, \"utf8\");\n const trimmed = path.trim().toLowerCase();\n\n let raw: unknown;\n if (trimmed.endsWith(\".json\")) {\n raw = JSON.parse(text);\n } else {\n raw = parseYaml(text);\n }\n\n if (!raw || typeof raw !== \"object\") {\n throw new Error(`expectations file must be an object mapping case ids to lists`);\n }\n\n const map: ExpectationsMap = {};\n for (const [caseId, value] of Object.entries(raw as Record<string, unknown>)) {\n if (!Array.isArray(value)) {\n throw new Error(`expectations for case \"${caseId}\" must be an array of strings`);\n }\n map[caseId] = value.map(String);\n }\n return map;\n}\n","/**\n * TrajectoryView → markdown transcript for LLM graders.\n */\n\nimport type { TrajectoryView } from \"../types/trajectory\";\n\n/** Maximum characters per tool result embedded in grader transcripts. */\nconst MAX_RESULT_CHARS = 4000;\n\n/**\n * Render a {@link TrajectoryView} as markdown for LLM graders.\n *\n * Tool results are truncated at {@link MAX_RESULT_CHARS} to keep judge\n * prompts within reasonable token limits.\n */\nexport function trajectoryToTranscript(\n view: TrajectoryView,\n prompt?: string,\n): string {\n const lines: string[] = [];\n\n if (prompt) {\n lines.push(\"## User prompt\", \"\", prompt, \"\");\n }\n\n for (const turn of view.turns) {\n lines.push(`## Assistant turn ${turn.turnIndex + 1}`, \"\");\n if (turn.text) {\n lines.push(turn.text, \"\");\n }\n for (const call of turn.toolCalls) {\n lines.push(`[Tool call] ${call.name} (id=${call.callId})`);\n lines.push(`Arguments: ${formatJson(call.args)}`);\n if (call.result !== null) {\n lines.push(`[Tool result] ${formatResult(call.result)}`);\n if (call.isError) lines.push(\"(tool reported error)\");\n } else {\n lines.push(\"[Tool result] (none observed)\");\n }\n lines.push(\"\");\n }\n if (turn.stopReason) {\n lines.push(`Stop reason: ${turn.stopReason}`, \"\");\n }\n }\n\n const finalInTurns = view.turns.some((t) => t.text === view.finalResponse);\n if (view.finalResponse && !finalInTurns) {\n lines.push(\"## Final response\", \"\", view.finalResponse, \"\");\n }\n\n lines.push(\n \"## Session metadata\",\n `session_id: ${view.meta.sessionId}`,\n `model: ${view.meta.model}`,\n `cwd: ${view.meta.cwd}`,\n `success: ${view.success}`,\n `tool_calls: ${view.toolCalls.length}`,\n `duration_ms: ${view.usage.durationMs}`,\n `input_tokens: ${view.usage.inputTokens}`,\n `output_tokens: ${view.usage.outputTokens}`,\n );\n\n return lines.join(\"\\n\").trimEnd();\n}\n\n/** Format unknown values as JSON for transcript embedding. */\nfunction formatJson(value: unknown): string {\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n}\n\n/** Format a tool result, truncating long string or JSON payloads. */\nfunction formatResult(result: unknown): string {\n if (typeof result === \"string\") {\n return truncate(result);\n }\n return truncate(formatJson(result));\n}\n\n/** Truncate text with ellipsis when exceeding the transcript size budget. */\nfunction truncate(text: string): string {\n if (text.length <= MAX_RESULT_CHARS) return text;\n return `${text.slice(0, MAX_RESULT_CHARS)}… (truncated)`;\n}\n","/**\n * Stable judge identifiers for eval-run envelope provenance.\n */\n\nimport type { GradingConfig } from \"../config/grading-loader\";\nimport type { JudgeInfo } from \"../types/eval-record\";\n\n/** Map harness grading adapter id to a stable judge identifier. */\nexport function judgeIdForAdapter(adapter: string | undefined): string {\n switch (adapter) {\n case \"codex\":\n return \"harness-eval/codex-grader\";\n case \"claude-code\":\n return \"harness-eval/claude-grader\";\n default:\n return adapter ? `harness-eval/${adapter}-grader` : \"harness-eval/claude-grader\";\n }\n}\n\n/** Build {@link JudgeInfo} from grading adapter and optional model override. */\nexport function resolveJudgeInfo(options: {\n adapter?: string;\n model?: string;\n id?: string;\n}): JudgeInfo {\n const adapter = options.adapter ?? \"claude-code\";\n return {\n id: options.id ?? judgeIdForAdapter(adapter),\n model: options.model,\n adapter,\n };\n}\n\n/** Derive judge metadata from a parsed grading YAML config. */\nexport function judgeInfoFromGradingConfig(\n config: GradingConfig,\n): JudgeInfo {\n const adapter = config.judge.adapter ?? \"claude-code\";\n const model =\n config.judge.model ??\n (config.judge.codex as { model?: string } | undefined)?.model ??\n (config.judge.claudeCode as { model?: string } | undefined)?.model;\n\n return resolveJudgeInfo({ adapter, model });\n}\n","/**\n * Grade a harness-eval SuiteReport with outcome expectations (LLM judge).\n */\n\nimport { readFile } from \"node:fs/promises\";\n\nimport { createClaudeGrader, type ClaudeGraderOptions } from \"./claude-grader\";\nimport { createCodexGrader, type CodexGraderOptions } from \"./codex-grader\";\nimport { loadExpectationsMap } from \"./expectations\";\nimport { trajectoryToTranscript } from \"./transcript\";\nimport type {\n GradeReportOptions,\n GraderFn,\n RepGradingResult,\n SuiteGradingReport,\n} from \"./types\";\nimport { createLimit } from \"../runner/limit\";\nimport type { CellReport, SuiteReport } from \"../runner/types\";\nimport { resolveJudgeInfo } from \"../eval-record/judge-metadata\";\n\n/**\n * Grade every repetition in a {@link SuiteReport} that has expectations.\n *\n * Expectations come from inline case fields or an optional sidecar YAML/JSON\n * map. Runs are concurrent under {@link GradeReportOptions.maxConcurrent}.\n */\nexport async function gradeReport(\n report: SuiteReport,\n options: GradeReportOptions = {},\n): Promise<SuiteGradingReport> {\n const expectationsMap = options.expectationsPath\n ? await loadExpectationsMap(options.expectationsPath)\n : {};\n\n // Select grader subprocess by judge adapter id from grading YAML or CLI.\n const gradeFn: GraderFn =\n options.gradeFn ??\n (options.judgeAdapter === \"codex\"\n ? createCodexGrader({\n binary: options.binary,\n model: options.model,\n timeoutMs: options.timeoutMs,\n env: options.env,\n cwd: options.cwd,\n codex: options.codex as CodexGraderOptions[\"codex\"],\n })\n : createClaudeGrader({\n binary: options.binary,\n model: options.model,\n timeoutMs: options.timeoutMs,\n env: options.env,\n cwd: options.cwd,\n claudeCode: options.claudeCode as ClaudeGraderOptions[\"claudeCode\"],\n }));\n\n const maxConcurrent = options.maxConcurrent ?? 2;\n const limit = createLimit(maxConcurrent);\n\n const tasks: Array<{\n cell: CellReport;\n rep: CellReport[\"repetitions\"][number];\n expectations: string[];\n }> = [];\n\n for (const cell of report.cells) {\n const expectations =\n cell.expectations ??\n expectationsMap[cell.caseId] ??\n [];\n\n if (expectations.length === 0) continue;\n\n for (const rep of cell.repetitions) {\n if (!rep.adapterResult) continue;\n tasks.push({ cell, rep, expectations });\n }\n }\n\n const gradeStartTs = Date.now();\n options.onProgress?.({ kind: \"grade-start\", total: tasks.length });\n\n const results: RepGradingResult[] = await Promise.all(\n tasks.map(({ cell, rep, expectations }) =>\n limit(async () => {\n const start = Date.now();\n const view = rep.adapterResult!.view;\n const prompt = cell.prompt ?? \"\";\n const transcript = trajectoryToTranscript(view, prompt);\n\n try {\n const graded = await gradeFn({\n prompt,\n transcript,\n expectations,\n systemInstruction: options.systemInstruction,\n });\n\n const result: RepGradingResult = {\n caseId: cell.caseId,\n cellLabel: cell.cell.label,\n repetitionIndex: rep.repetitionIndex,\n prompt,\n expectations: graded.expectations,\n summary: graded.summary,\n evalFeedback: graded.evalFeedback,\n graderError: graded.error,\n durationMs: Date.now() - start,\n };\n\n options.onProgress?.({\n kind: \"grade-complete\",\n caseId: result.caseId,\n cellLabel: result.cellLabel,\n repetitionIndex: result.repetitionIndex,\n passed: result.summary.passed,\n failed: result.summary.failed,\n durationMs: result.durationMs,\n graderError: result.graderError,\n });\n\n return result;\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n const result: RepGradingResult = {\n caseId: cell.caseId,\n cellLabel: cell.cell.label,\n repetitionIndex: rep.repetitionIndex,\n prompt,\n expectations: expectations.map((text) => ({\n text,\n passed: false,\n evidence: message,\n })),\n summary: {\n passed: 0,\n failed: expectations.length,\n total: expectations.length,\n passRate: 0,\n },\n graderError: message,\n durationMs: Date.now() - start,\n };\n\n options.onProgress?.({\n kind: \"grade-complete\",\n caseId: result.caseId,\n cellLabel: result.cellLabel,\n repetitionIndex: result.repetitionIndex,\n passed: 0,\n failed: expectations.length,\n durationMs: result.durationMs,\n graderError: message,\n });\n\n return result;\n }\n }),\n ),\n );\n\n results.sort((a, b) => {\n const keyA = `${a.caseId}::${a.cellLabel}::${a.repetitionIndex}`;\n const keyB = `${b.caseId}::${b.cellLabel}::${b.repetitionIndex}`;\n return keyA.localeCompare(keyB);\n });\n\n const totalExpectations = results.reduce((n, r) => n + r.summary.total, 0);\n const passedExpectations = results.reduce((n, r) => n + r.summary.passed, 0);\n\n options.onProgress?.({\n kind: \"grade-done\",\n durationMs: Date.now() - gradeStartTs,\n totalExpectations,\n passedExpectations,\n });\n\n return {\n gradedAt: new Date().toISOString(),\n sourceReport: options.sourceReport ?? \"\",\n gradingConfigPath: options.gradingConfigPath,\n judge: resolveJudgeInfo({\n adapter: options.judgeAdapter ?? \"claude-code\",\n model: options.model,\n }),\n results,\n summary: {\n passed: passedExpectations,\n failed: totalExpectations - passedExpectations,\n total: totalExpectations,\n passRate:\n totalExpectations === 0 ? 0 : passedExpectations / totalExpectations,\n },\n };\n}\n\n/** Load a suite report JSON file produced by `harness-eval run`. */\nexport async function loadSuiteReport(path: string): Promise<SuiteReport> {\n const text = await readFile(path, \"utf8\");\n return JSON.parse(text) as SuiteReport;\n}\n","/**\n * Merge grading YAML with CLI overrides for `gradeReport`.\n */\n\nimport type { ClaudeCodeOptions } from \"../adapters/claude-code/types\";\nimport type { CodexOptions } from \"../adapters/codex/types\";\nimport type { GradingConfig } from \"../config/grading-loader\";\nimport type { GradeReportOptions } from \"./types\";\n\n/** CLI flag overrides for grading (take precedence over grading YAML). */\nexport interface GradeCliOverrides {\n model?: string;\n binary?: string;\n timeoutMs?: number;\n maxConcurrent?: number;\n expectationsPath?: string;\n sourceReport?: string;\n}\n\n/**\n * Merge standalone grading YAML with CLI flags (CLI wins).\n */\nexport function resolveGradeOptions(\n fileConfig?: GradingConfig,\n cli: GradeCliOverrides = {},\n configPath?: string,\n): GradeReportOptions {\n const judge = fileConfig?.judge;\n\n const adapter = judge?.adapter ?? \"claude-code\";\n\n const claudeCode = (judge?.claudeCode ?? {}) as ClaudeCodeOptions;\n const codex = (judge?.codex ?? {}) as CodexOptions;\n const adapterBlock = adapter === \"codex\" ? codex : claudeCode;\n const binary = cli.binary ?? adapterBlock.binary;\n const model = cli.model ?? judge?.model ?? adapterBlock.model;\n\n if (adapter === \"codex\") {\n // Strip binary/model from nested codex block — they are promoted to top-level options.\n return {\n sourceReport: cli.sourceReport,\n expectationsPath: cli.expectationsPath,\n model,\n binary,\n timeoutMs: cli.timeoutMs ?? judge?.timeoutMs,\n maxConcurrent: cli.maxConcurrent ?? judge?.maxConcurrent,\n systemInstruction: judge?.system_instruction,\n env: judge?.env,\n cwd: judge?.cwd,\n judgeAdapter: \"codex\",\n codex: {\n ...codex,\n binary: undefined,\n model: undefined,\n },\n gradingConfigPath: configPath,\n };\n }\n\n if (adapter !== \"claude-code\") {\n throw new Error(\n `unsupported grading adapter \"${adapter}\" (supported: claude-code, codex)`,\n );\n }\n\n return {\n sourceReport: cli.sourceReport,\n expectationsPath: cli.expectationsPath,\n model,\n binary,\n timeoutMs: cli.timeoutMs ?? judge?.timeoutMs,\n maxConcurrent: cli.maxConcurrent ?? judge?.maxConcurrent,\n systemInstruction: judge?.system_instruction,\n env: judge?.env,\n cwd: judge?.cwd,\n judgeAdapter: \"claude-code\" as const,\n claudeCode: {\n ...claudeCode,\n binary: undefined,\n model: undefined,\n },\n gradingConfigPath: configPath,\n };\n}\n","/**\n * Console formatter for suite grading reports.\n */\n\nimport type { RepGradingResult, SuiteGradingReport } from \"./types\";\n\nconst RESET = \"\\x1b[0m\";\nconst GREEN = \"\\x1b[32m\";\nconst RED = \"\\x1b[31m\";\nconst DIM = \"\\x1b[2m\";\n\n/**\n * Format a {@link SuiteGradingReport} for terminal output.\n *\n * @param color When true, emit ANSI status colors (default for TTY console).\n */\nexport function formatGradingConsole(\n report: SuiteGradingReport,\n color = true,\n): string {\n const lines: string[] = [];\n\n if (report.results.length === 0) {\n lines.push(\n \"No repetitions graded. Add expectations to the suite YAML or pass --expectations.\",\n );\n return lines.join(\"\\n\");\n }\n\n for (const result of report.results) {\n const allPassed = result.summary.failed === 0 && !result.graderError;\n const status = allPassed\n ? color ? `${GREEN}PASS${RESET}` : \"PASS\"\n : color ? `${RED}FAIL${RESET}` : \"FAIL\";\n\n lines.push(\n `${result.caseId} @ ${result.cellLabel} rep${result.repetitionIndex} ${status}`,\n );\n\n if (result.graderError) {\n lines.push(\n color\n ? ` ${RED}grader error: ${result.graderError}${RESET}`\n : ` grader error: ${result.graderError}`,\n );\n }\n\n for (const exp of result.expectations) {\n const marker = exp.passed\n ? color ? `${GREEN}✓${RESET}` : \"✓\"\n : color ? `${RED}✗${RESET}` : \"✗\";\n lines.push(` ├─ ${exp.text} ${marker}`);\n if (!exp.passed || exp.evidence) {\n lines.push(\n color\n ? ` │ ${DIM}${exp.evidence}${RESET}`\n : ` │ ${exp.evidence}`,\n );\n }\n }\n\n const pct = (result.summary.passRate * 100).toFixed(0);\n lines.push(\n ` └─ ${result.summary.passed}/${result.summary.total} (${pct}%) expectations`,\n );\n lines.push(\"\");\n }\n\n const overallPct = (report.summary.passRate * 100).toFixed(0);\n lines.push(\n `Overall: ${report.summary.passed}/${report.summary.total} (${overallPct}%) expectations passed`,\n );\n\n return lines.join(\"\\n\").trimEnd();\n}\n\n/** True when every graded rep passed all expectations without grader errors. */\nexport function gradingReportPassed(report: SuiteGradingReport): boolean {\n return report.results.every(\n (r) => !r.graderError && r.summary.failed === 0 && r.summary.total > 0,\n );\n}\n","/**\n * Normalize harness and suite data into Vertex protojson wire shapes.\n *\n * Accepts both {@link ToolCall} (harness runtime) and suite YAML reference\n * step shapes, producing consistent {@link ProtojsonTrajectory} objects for\n * EvaluateInstances and envelope export.\n */\n\nimport type { ToolCall } from \"../types/trajectory\";\nimport type { ProtojsonTrajectory, ReferenceToolNameMode } from \"../types/eval-interchange\";\n\n/** Input accepted by trajectory normalizers — harness or suite reference steps. */\nexport type TrajectoryInput =\n | ToolCall[]\n | Array<{ tool_name: string; tool_input: unknown | string }>;\n\n/**\n * Serialize tool arguments to the Vertex wire string format.\n *\n * Already-string inputs pass through unchanged (e.g. pre-serialized reference\n * steps). Objects and nullish values become JSON strings; empty input becomes `{}`.\n *\n * @param args - Tool arguments from harness or suite YAML.\n * @returns JSON string suitable for {@link ProtojsonToolCall.toolInput}.\n */\nexport function serializeToolInput(args: unknown): string {\n if (typeof args === \"string\") return args;\n return JSON.stringify(args ?? {});\n}\n\n/**\n * Normalize a tool name according to suite reference configuration.\n *\n * In `\"bare\"` mode, strips the MCP namespace prefix (`mcp__api__foo` → `foo`)\n * so reference trajectories authored with bare names match harness tool names.\n *\n * @param toolName - Raw tool name from harness or suite.\n * @param mode - `\"harness\"` preserves the name; `\"bare\"` strips after last `__`.\n */\nexport function normalizeReferenceToolName(\n toolName: string,\n mode: ReferenceToolNameMode,\n): string {\n if (mode !== \"bare\") return toolName;\n\n const separator = toolName.lastIndexOf(\"__\");\n if (separator === -1) return toolName;\n return toolName.slice(separator + 2);\n}\n\n/**\n * Convert a harness or suite trajectory into Vertex protojson wire format.\n *\n * `toolNameMode` controls MCP prefix stripping for every tool name in the\n * trajectory. Suite reference steps and predicted harness tool calls use the\n * same mode so comparisons stay consistent across metrics and instances.\n *\n * @param trajectory - Tool calls in harness or YAML reference shape.\n * @param options.toolNameMode - `\"harness\"` keeps full names; `\"bare\"` strips after last `__`.\n */\nexport function toProtojsonTrajectory(\n trajectory: TrajectoryInput,\n options: { toolNameMode?: ReferenceToolNameMode } = {},\n): ProtojsonTrajectory {\n const toolNameMode = options.toolNameMode ?? \"harness\";\n\n return {\n toolCalls: trajectory.map((toolCall) => {\n const name = \"name\" in toolCall ? toolCall.name : toolCall.tool_name;\n const args = \"args\" in toolCall ? toolCall.args : toolCall.tool_input;\n\n return {\n toolName: normalizeReferenceToolName(name, toolNameMode),\n toolInput: serializeToolInput(args),\n };\n }),\n };\n}\n","/**\n * Build Vertex Trajectory*Instance protojson wire objects.\n *\n * Each trajectory metric in Vertex EvaluateInstances expects a specific\n * protobuf message. This module constructs all six instance payloads from\n * one predicted/reference pair so callers can batch-upload via JSONL.\n */\n\nimport { toProtojsonTrajectory } from \"../normalize\";\nimport type {\n ProtojsonTrajectory,\n ReferenceToolNameMode,\n TrajectoryInstancesJson,\n TrajectoryPairInstanceJson,\n TrajectorySingleToolUseInstanceJson,\n} from \"../../types/eval-interchange\";\nimport type { ToolCall } from \"../../types/trajectory\";\n\ntype ReferenceStep = { tool_name: string; tool_input: unknown };\n\n/**\n * Build a pair instance with predicted and reference trajectories.\n *\n * Both sides use the same `referenceToolNameMode` so wire payloads align with\n * {@link toHarnessMetrics} and Vertex EvaluateInstances sees comparable names.\n * In `\"bare\"` mode, MCP prefixes are stripped on predicted and reference alike.\n */\nfunction pairInstance(\n predicted: ToolCall[],\n reference: ReferenceStep[],\n referenceToolNameMode: ReferenceToolNameMode,\n): TrajectoryPairInstanceJson {\n return {\n predictedTrajectory: toProtojsonTrajectory(predicted, {\n toolNameMode: referenceToolNameMode,\n }),\n referenceTrajectory: toProtojsonTrajectory(reference, {\n toolNameMode: referenceToolNameMode,\n }),\n };\n}\n\n/**\n * Build all Trajectory*Instance payloads for one predicted/reference pair.\n *\n * Pair metrics (exact, in-order, any-order, precision, recall) share the\n * same trajectory pair; single-tool-use omits the reference trajectory\n * per Vertex API shape.\n */\nexport function toTrajectoryInstances(options: {\n predicted: ToolCall[];\n reference: ReferenceStep[];\n referenceToolNameMode?: ReferenceToolNameMode;\n}): TrajectoryInstancesJson {\n const referenceToolNameMode = options.referenceToolNameMode ?? \"harness\";\n const pair = pairInstance(\n options.predicted,\n options.reference,\n referenceToolNameMode,\n );\n\n return {\n exactMatch: pair,\n inOrderMatch: pair,\n anyOrderMatch: pair,\n precision: pair,\n recall: pair,\n singleToolUse: {\n predictedTrajectory: pair.predictedTrajectory,\n },\n };\n}\n\n/**\n * Convert suite reference steps to cell-level protojson trajectory export.\n */\nexport function toReferenceTrajectory(\n reference: ReferenceStep[],\n referenceToolNameMode: ReferenceToolNameMode = \"harness\",\n): ProtojsonTrajectory {\n return toProtojsonTrajectory(reference, { toolNameMode: referenceToolNameMode });\n}\n\n/**\n * Map a trajectory instance key to the Vertex protobuf message type name.\n *\n * Used as `messageType` in {@link InstancesJsonlRow} for EvaluateInstances batching.\n */\nexport function trajectoryInstanceMessageType(\n key: keyof TrajectoryInstancesJson,\n): string {\n switch (key) {\n case \"exactMatch\":\n return \"TrajectoryExactMatchInstance\";\n case \"inOrderMatch\":\n return \"TrajectoryInOrderMatchInstance\";\n case \"anyOrderMatch\":\n return \"TrajectoryAnyOrderMatchInstance\";\n case \"precision\":\n return \"TrajectoryPrecisionInstance\";\n case \"recall\":\n return \"TrajectoryRecallInstance\";\n case \"singleToolUse\":\n return \"TrajectorySingleToolUseInstance\";\n }\n}\n\nexport type { TrajectoryPairInstanceJson, TrajectorySingleToolUseInstanceJson };\n","/**\n * Build Vertex EvaluationInstance protojson wire objects.\n *\n * Maps harness prompt/response text into the InstanceData wrapper shape\n * expected by EvaluateInstances for text-based metrics.\n */\n\nimport type { EvaluationInstanceJson } from \"../../types/eval-interchange\";\n\n/**\n * Build an EvaluationInstance protojson object from harness strings.\n *\n * Omitted fields are excluded from the output object rather than set to\n * empty wrappers — protojson omits unset optional fields.\n *\n * @param options.prompt - Case prompt sent to the agent.\n * @param options.response - Final agent response from the trajectory.\n * @param options.reference - Optional reference answer text (rare in harness eval).\n */\nexport function toEvaluationInstance(options: {\n prompt?: string;\n response?: string;\n reference?: string;\n}): EvaluationInstanceJson {\n const instance: EvaluationInstanceJson = {};\n\n if (options.prompt !== undefined) {\n instance.prompt = { text: options.prompt };\n }\n if (options.response !== undefined) {\n instance.response = { text: options.response };\n }\n if (options.reference !== undefined) {\n instance.reference = { text: options.reference };\n }\n\n return instance;\n}\n","/**\n * Trajectory-level metrics for comparing predicted and reference tool-call sequences.\n *\n * Aligns with Vertex AI EvaluationService trajectory metrics (exact match,\n * in-order, any-order, precision, recall, single tool use). Tool calls are\n * compared by `(tool_name, serialized tool_input)` identity after normalization.\n *\n * Binary metrics return 0 or 1; precision and recall return fractions in [0, 1].\n */\n\nimport { serializeToolInput } from \"../eval-interchange/normalize\";\n\n/** Canonical wire tool call used internally for comparison. */\nexport interface WireToolCall {\n tool_name: string;\n tool_input: string;\n}\n\n/** All trajectory metric scores for one predicted/reference pair. */\nexport interface TrajectoryMetrics {\n trajectory_exact_match: number;\n trajectory_in_order_match: number;\n trajectory_any_order_match: number;\n trajectory_precision: number;\n trajectory_recall: number;\n trajectory_single_tool_use: number;\n}\n\n/** Input accepted by trajectory metrics — wire or harness/YAML shapes. */\nexport type TrajectoryInput =\n | WireToolCall[]\n | Array<{ tool_name: string; tool_input: unknown | string }>;\n\nfunction normalizeToolCall(\n toolCall: TrajectoryInput[number],\n): WireToolCall {\n if (typeof toolCall.tool_input === \"string\") {\n return {\n tool_name: toolCall.tool_name,\n tool_input: toolCall.tool_input,\n };\n }\n\n return {\n tool_name: toolCall.tool_name,\n tool_input: serializeToolInput(toolCall.tool_input),\n };\n}\n\nfunction normalizeTrajectory(trajectory: TrajectoryInput): WireToolCall[] {\n return trajectory.map(normalizeToolCall);\n}\n\n/** Stable composite key for multiset and equality checks. */\nfunction toolCallKey(toolCall: WireToolCall): string {\n return `${toolCall.tool_name}\\0${toolCall.tool_input}`;\n}\n\n/**\n * Count predicted tool calls that appear in reference (multiset intersection).\n *\n * Duplicate tool calls are matched one-for-one; order does not matter.\n */\nfunction multisetIntersectionSize(\n predicted: WireToolCall[],\n reference: WireToolCall[],\n): number {\n const refCounts = new Map<string, number>();\n for (const toolCall of reference) {\n const key = toolCallKey(toolCall);\n refCounts.set(key, (refCounts.get(key) ?? 0) + 1);\n }\n\n let matched = 0;\n for (const toolCall of predicted) {\n const key = toolCallKey(toolCall);\n const count = refCounts.get(key) ?? 0;\n if (count > 0) {\n matched += 1;\n refCounts.set(key, count - 1);\n }\n }\n\n return matched;\n}\n\n/**\n * Whether reference appears as a subsequence of predicted (order preserved).\n *\n * Extra predicted calls between reference steps are allowed (in-order match\n * semantics per Vertex).\n */\nfunction isSubsequence(\n predicted: WireToolCall[],\n reference: WireToolCall[],\n): boolean {\n let refIndex = 0;\n for (const toolCall of predicted) {\n if (refIndex >= reference.length) break;\n if (toolCallKey(toolCall) === toolCallKey(reference[refIndex]!)) {\n refIndex += 1;\n }\n }\n return refIndex === reference.length;\n}\n\nfunction arraysEqual(left: WireToolCall[], right: WireToolCall[]): boolean {\n if (left.length !== right.length) return false;\n return left.every((toolCall, index) => {\n const other = right[index]!;\n return toolCallKey(toolCall) === toolCallKey(other);\n });\n}\n\n/** Exact sequence equality after normalization. */\nexport function trajectoryExactMatch(\n predicted: TrajectoryInput,\n reference: TrajectoryInput,\n): number {\n const predictedNorm = normalizeTrajectory(predicted);\n const referenceNorm = normalizeTrajectory(reference);\n return arraysEqual(predictedNorm, referenceNorm) ? 1 : 0;\n}\n\n/** Reference is a subsequence of predicted (order preserved, extras allowed). */\nexport function trajectoryInOrderMatch(\n predicted: TrajectoryInput,\n reference: TrajectoryInput,\n): number {\n const predictedNorm = normalizeTrajectory(predicted);\n const referenceNorm = normalizeTrajectory(reference);\n return isSubsequence(predictedNorm, referenceNorm) ? 1 : 0;\n}\n\n/** Same multiset of tool calls; length must match. */\nexport function trajectoryAnyOrderMatch(\n predicted: TrajectoryInput,\n reference: TrajectoryInput,\n): number {\n const predictedNorm = normalizeTrajectory(predicted);\n const referenceNorm = normalizeTrajectory(reference);\n if (predictedNorm.length !== referenceNorm.length) return 0;\n\n const predictedKeys = predictedNorm.map(toolCallKey).sort();\n const referenceKeys = referenceNorm.map(toolCallKey).sort();\n return predictedKeys.every((key, index) => key === referenceKeys[index])\n ? 1\n : 0;\n}\n\n/**\n * Fraction of predicted tool calls that appear in reference (multiset).\n *\n * Returns 1 when both trajectories are empty.\n */\nexport function trajectoryPrecision(\n predicted: TrajectoryInput,\n reference: TrajectoryInput,\n): number {\n const predictedNorm = normalizeTrajectory(predicted);\n if (predictedNorm.length === 0) return reference.length === 0 ? 1 : 0;\n\n const referenceNorm = normalizeTrajectory(reference);\n return multisetIntersectionSize(predictedNorm, referenceNorm) /\n predictedNorm.length;\n}\n\n/**\n * Fraction of reference tool calls matched in predicted (multiset recall).\n *\n * Returns 1 when reference is empty and predicted is empty.\n */\nexport function trajectoryRecall(\n predicted: TrajectoryInput,\n reference: TrajectoryInput,\n): number {\n const referenceNorm = normalizeTrajectory(reference);\n if (referenceNorm.length === 0) return predicted.length === 0 ? 1 : 0;\n\n const predictedNorm = normalizeTrajectory(predicted);\n return multisetIntersectionSize(predictedNorm, referenceNorm) /\n referenceNorm.length;\n}\n\n/** Both trajectories have exactly one call and they match. */\nexport function trajectorySingleToolUse(\n predicted: TrajectoryInput,\n reference: TrajectoryInput,\n): number {\n const predictedNorm = normalizeTrajectory(predicted);\n const referenceNorm = normalizeTrajectory(reference);\n if (predictedNorm.length !== 1 || referenceNorm.length !== 1) return 0;\n return toolCallKey(predictedNorm[0]!) === toolCallKey(referenceNorm[0]!)\n ? 1\n : 0;\n}\n\n/** Compute all trajectory metrics in one pass. */\nexport function computeTrajectoryMetrics(\n predicted: TrajectoryInput,\n reference: TrajectoryInput,\n): TrajectoryMetrics {\n return {\n trajectory_exact_match: trajectoryExactMatch(predicted, reference),\n trajectory_in_order_match: trajectoryInOrderMatch(predicted, reference),\n trajectory_any_order_match: trajectoryAnyOrderMatch(predicted, reference),\n trajectory_precision: trajectoryPrecision(predicted, reference),\n trajectory_recall: trajectoryRecall(predicted, reference),\n trajectory_single_tool_use: trajectorySingleToolUse(predicted, reference),\n };\n}\n\n/**\n * Parse a wire tool_input string to JSON, or return the raw string on failure.\n *\n * Exported for tool-call metrics that need structured arg comparison.\n */\nfunction parseToolInput(toolInput: string): unknown {\n try {\n return JSON.parse(toolInput) as unknown;\n } catch {\n return toolInput;\n }\n}\n\nexport { parseToolInput };\n","/**\n * Harness-owned trajectory metric scores in Vertex camelCase field names.\n *\n * Wraps {@link computeTrajectoryMetrics} for envelope export. External\n * systems can compare harness-precomputed scores against Vertex EvaluateInstances\n * results without reimplementing trajectory matching logic.\n */\n\nimport { computeTrajectoryMetrics } from \"../../metrics/trajectory\";\nimport { normalizeReferenceToolName } from \"../normalize\";\nimport type { HarnessMetrics, ReferenceToolNameMode } from \"../../types/eval-interchange\";\nimport type { ToolCall } from \"../../types/trajectory\";\n\n/** Suite YAML reference step shape accepted by metric computation. */\ntype ReferenceStep = { tool_name: string; tool_input: unknown };\n\n/**\n * Compute trajectory metrics and map snake_case keys to Vertex camelCase.\n *\n * When `referenceToolNameMode` is `\"bare\"`, both predicted and reference tool\n * names are stripped to the suffix after the last `__` so suite reference steps\n * authored with bare names (e.g. `ListLandingZones`) match harness MCP names\n * (e.g. `mcp__plugin__ListLandingZones`).\n *\n * @param predicted - Tool calls from the harness trajectory view.\n * @param reference - Reference steps from suite YAML.\n * @param options.referenceToolNameMode - Name normalization mode from suite YAML.\n */\nexport function toHarnessMetrics(\n predicted: ToolCall[],\n reference: ReferenceStep[],\n options: { referenceToolNameMode?: ReferenceToolNameMode } = {},\n): HarnessMetrics {\n const referenceToolNameMode = options.referenceToolNameMode ?? \"harness\";\n\n const metrics = computeTrajectoryMetrics(\n predicted.map((toolCall) => ({\n tool_name: normalizeReferenceToolName(toolCall.name, referenceToolNameMode),\n tool_input: toolCall.args,\n })),\n reference.map((step) => ({\n tool_name: normalizeReferenceToolName(step.tool_name, referenceToolNameMode),\n tool_input: step.tool_input,\n })),\n );\n\n return {\n trajectoryExactMatch: metrics.trajectory_exact_match,\n trajectoryInOrderMatch: metrics.trajectory_in_order_match,\n trajectoryAnyOrderMatch: metrics.trajectory_any_order_match,\n trajectoryPrecision: metrics.trajectory_precision,\n trajectoryRecall: metrics.trajectory_recall,\n trajectorySingleToolUse: metrics.trajectory_single_tool_use,\n };\n}\n","/**\n * Enrich eval repetitions with Vertex protojson interchange fields.\n *\n * Called during envelope build for each successful repetition. Adds\n * `evaluationInstance`, optional `trajectoryInstances` / `harnessMetrics`\n * when a suite reference exists, and Vertex-style `latencySeconds` / `failure`\n * flags derived from trajectory success.\n */\n\nimport { toEvaluationInstance } from \"./protojson/evaluation-instance\";\nimport { toHarnessMetrics } from \"./protojson/harness-metrics\";\nimport { toTrajectoryInstances } from \"./protojson/trajectory-instances\";\nimport type { EvalRepetition } from \"../types/eval-record\";\nimport type { ReferenceTrajectoryConfig } from \"../types/eval-interchange\";\nimport type { ToolCall } from \"../types/trajectory\";\n\n/** Extract reference steps from suite config when present. */\nfunction referenceSteps(\n reference?: ReferenceTrajectoryConfig,\n): Array<{ tool_name: string; tool_input: unknown }> | undefined {\n return reference?.steps;\n}\n\n/**\n * Attach Vertex protojson interchange fields to one {@link EvalRepetition}.\n *\n * When no trajectory exists (adapter error), sets `failure: 1` and skips\n * protojson payloads. Trajectory instances and harness metrics are only\n * computed when the suite defines a non-empty reference trajectory.\n *\n * @param repetition - Base repetition from the runner (trajectory, assertions, grades).\n * @param options.prompt - Case prompt for EvaluationInstance.\n * @param options.reference - Suite reference trajectory config, if any.\n */\nexport function enrichRepetitionWithProtojson(\n repetition: EvalRepetition,\n options: {\n prompt?: string;\n reference?: ReferenceTrajectoryConfig;\n } = {},\n): EvalRepetition {\n if (!repetition.trajectory) {\n return {\n ...repetition,\n failure: 1,\n };\n }\n\n const predicted = repetition.trajectory.toolCalls;\n const referenceStepsList = referenceSteps(options.reference);\n const referenceToolNameMode = options.reference?.tool_name_mode ?? \"harness\";\n\n const enriched: EvalRepetition = {\n ...repetition,\n evaluationInstance: toEvaluationInstance({\n prompt: options.prompt,\n response: repetition.trajectory.finalResponse,\n }),\n // Vertex EvaluateInstances expects seconds; harness stores milliseconds.\n latencySeconds: repetition.trajectory.usage.durationMs / 1000,\n failure: repetition.trajectory.success ? 0 : 1,\n };\n\n if (referenceStepsList?.length) {\n enriched.trajectoryInstances = toTrajectoryInstances({\n predicted,\n reference: referenceStepsList,\n referenceToolNameMode,\n });\n enriched.harnessMetrics = toHarnessMetrics(predicted, referenceStepsList, {\n referenceToolNameMode,\n });\n }\n\n return enriched;\n}\n\n/**\n * Return predicted tool calls from a repetition, or an empty array.\n *\n * Convenience for metrics and tests that need harness-shaped tool calls\n * without null-checking trajectory.\n */\nexport function predictedToolCalls(repetition: EvalRepetition): ToolCall[] {\n return repetition.trajectory?.toolCalls ?? [];\n}\n","/**\n * Build {@link EvalRunEnvelope} from harness-eval run and grading reports.\n *\n * This is the canonical export path from in-process or on-disk {@link SuiteReport}\n * JSON into the cross-harness eval record contract. It stitches together:\n *\n * - Behavioral assertion results from the runner\n * - Optional outcome grades from the LLM grader\n * - Vertex protojson interchange fields via {@link enrichRepetitionWithProtojson}\n * - Optional artifacts (transcript, raw stream-json) controlled by build options\n *\n * Downstream consumers include CI gates, databases, and the `harness-eval envelope`\n * CLI projection commands.\n */\n\nimport { randomUUID } from \"node:crypto\";\nimport { readFile } from \"node:fs/promises\";\nimport { createHash } from \"node:crypto\";\nimport { resolve, dirname, basename, join } from \"node:path\";\nimport { stat } from \"node:fs/promises\";\n\nimport { loadGradingConfig } from \"../config/grading-loader\";\nimport { loadSuite } from \"../config/loader\";\nimport { trajectoryToTranscript } from \"../grader/transcript\";\nimport { toReferenceTrajectory } from \"../eval-interchange/protojson/trajectory-instances\";\nimport { enrichRepetitionWithProtojson } from \"../eval-interchange/enrich\";\nimport type { SuiteGradingReport } from \"../grader/types\";\nimport type {\n BuildEvalRunEnvelopeOptions,\n EvalCellResult,\n EvalRepetition,\n EvalRunEnvelope,\n JudgeInfo,\n} from \"../types/eval-record\";\nimport {\n EVAL_RUN_SCHEMA_VERSION,\n TRAJECTORY_SCHEMA_VERSION,\n} from \"../types/eval-record\";\nimport type { SuiteReport } from \"../runner/types\";\nimport { judgeInfoFromGradingConfig,\n resolveJudgeInfo,\n} from \"./judge-metadata\";\n\n/**\n * Pull raw stream-json events from an adapter result when the adapter exposes them.\n *\n * Adapters may attach `rawEvents` for debug-only envelope export; this helper\n * avoids coupling the builder to a specific adapter result type.\n */\nfunction extractRawEvents(adapterResult: unknown): unknown[] | undefined {\n if (\n adapterResult !== null &&\n typeof adapterResult === \"object\" &&\n \"rawEvents\" in adapterResult &&\n Array.isArray((adapterResult as { rawEvents: unknown }).rawEvents)\n ) {\n return (adapterResult as { rawEvents: unknown[] }).rawEvents;\n }\n return undefined;\n}\n\n/**\n * Derive cell-level outcome pass from graded repetitions.\n *\n * Returns `undefined` when no repetition was graded (outcome gate not applicable).\n * When graded, every repetition must have zero failed expectations and no grader error.\n *\n * @param _caseId - Reserved for future per-case outcome rules; unused today.\n * @param _cellLabel - Reserved for future per-cell outcome rules; unused today.\n */\nfunction outcomePassForCell(\n _caseId: string,\n _cellLabel: string,\n repetitions: EvalRepetition[],\n): boolean | undefined {\n const graded = repetitions.filter((r) => r.outcomeGrades);\n if (graded.length === 0) return undefined;\n return graded.every(\n (r) =>\n r.outcomeGrades!.error === undefined &&\n r.outcomeGrades!.summary.failed === 0,\n );\n}\n\n/** Resolve judge metadata for envelope export (explicit options win). */\nasync function resolveEnvelopeJudge(options: {\n grading?: BuildEvalRunEnvelopeOptions[\"grading\"];\n gradingConfigPath?: string;\n}): Promise<JudgeInfo> {\n if (options.grading?.judge) {\n return options.grading.judge;\n }\n\n if (options.gradingConfigPath) {\n try {\n const config = await loadGradingConfig(\n resolve(options.gradingConfigPath),\n );\n return judgeInfoFromGradingConfig(config);\n } catch {\n // Fall through to default when grading YAML is missing or invalid.\n }\n }\n\n return resolveJudgeInfo({ adapter: \"claude-code\" });\n}\n\n/** Path to pass to {@link loadSuite} (directory layout uses the suite folder). */\nasync function resolveSuiteLoadPath(suitePath: string): Promise<string> {\n const abs = resolve(suitePath);\n if (basename(abs) === \"suite.yaml\") {\n return dirname(abs);\n }\n try {\n const info = await stat(abs);\n if (info.isDirectory()) {\n return abs;\n }\n } catch {\n // Fall through — loadSuite will surface read errors.\n }\n return abs;\n}\n\n/** Read suite YAML bytes for content hashing. */\nasync function readSuiteYamlContent(suitePath: string): Promise<string> {\n const loadPath = await resolveSuiteLoadPath(suitePath);\n const yamlPath =\n basename(resolve(suitePath)) === \"suite.yaml\"\n ? resolve(suitePath)\n : join(loadPath, \"suite.yaml\");\n return readFile(yamlPath, \"utf8\");\n}\nasync function resolveEnvelopeHarnessAdapter(options: {\n harnessAdapter?: string;\n suitePath?: string;\n}): Promise<string> {\n if (options.harnessAdapter) {\n return options.harnessAdapter;\n }\n\n if (options.suitePath) {\n try {\n const suite = await loadSuite(await resolveSuiteLoadPath(options.suitePath));\n if (suite.adapter) {\n return suite.adapter;\n }\n } catch {\n // Fall through to default when suite cannot be loaded.\n }\n }\n\n return \"claude-code\";\n}\n\n/**\n * Convert a {@link SuiteReport} (and optional grading) into a versioned\n * {@link EvalRunEnvelope} for storage or API handoff.\n *\n * @param report - Runner output for one suite execution.\n * @param options - Provenance, grading merge, and artifact inclusion flags.\n * @returns A fully populated envelope with protojson interchange fields on each repetition.\n */\nexport function buildEvalRunEnvelope(\n report: SuiteReport,\n options: BuildEvalRunEnvelopeOptions = {},\n): EvalRunEnvelope {\n // Transcript is on by default — judges and external tools expect it.\n const includeTranscript = options.includeTranscript !== false;\n // Raw stream-json is opt-in: large, vendor-specific, not cross-harness.\n const includeRaw = options.includeRawStreamEvents === true;\n\n const judge =\n options.grading?.judge ?? resolveJudgeInfo({ adapter: \"claude-code\" });\n\n const cells: EvalCellResult[] = report.cells.map((cell) => {\n const prompt = cell.prompt ?? \"\";\n const referenceTrajectoryConfig = cell.reference_trajectory;\n // Cell-level reference is exported in Vertex wire format for DB storage and\n // interchange even when individual repetitions also carry trajectoryInstances.\n const referenceTrajectory = referenceTrajectoryConfig\n ? toReferenceTrajectory(\n referenceTrajectoryConfig.steps,\n referenceTrajectoryConfig.tool_name_mode ?? \"harness\",\n )\n : undefined;\n const repetitions: EvalRepetition[] = cell.repetitions.map((rep) => {\n const base: EvalRepetition = {\n repetitionIndex: rep.repetitionIndex,\n durationMs: rep.durationMs,\n assertionResults: rep.assertionResults,\n };\n\n if (rep.error) {\n base.error = {\n message: rep.error.message,\n diagnostics: rep.error.diagnostics,\n };\n return base;\n }\n\n if (rep.adapterResult) {\n base.trajectory = {\n ...rep.adapterResult.view,\n schemaVersion: TRAJECTORY_SCHEMA_VERSION,\n };\n base.diagnostics = rep.adapterResult.diagnostics;\n\n const artifacts: EvalRepetition[\"artifacts\"] = {};\n if (includeTranscript) {\n artifacts.transcript = trajectoryToTranscript(\n rep.adapterResult.view,\n prompt,\n );\n }\n if (includeRaw) {\n const raw = extractRawEvents(rep.adapterResult);\n if (raw) artifacts.rawStreamEvents = raw;\n }\n if (Object.keys(artifacts).length > 0) {\n base.artifacts = artifacts;\n }\n }\n\n // Match grading rows by the same composite key the grader uses: case × cell × rep.\n const graded = options.grading?.results.find(\n (r) =>\n r.caseId === cell.caseId &&\n r.cellLabel === cell.cell.label &&\n r.repetitionIndex === rep.repetitionIndex,\n );\n\n if (graded) {\n base.outcomeGrades = {\n judge,\n expectations: graded.expectations,\n summary: graded.summary,\n evalFeedback: graded.evalFeedback,\n error: graded.graderError,\n };\n }\n\n // Protojson fields (evaluationInstance, trajectoryInstances, harnessMetrics)\n // are derived from trajectory + suite reference config, not from the runner report.\n return enrichRepetitionWithProtojson(base, {\n prompt,\n reference: referenceTrajectoryConfig,\n });\n });\n\n return {\n caseId: cell.caseId,\n category: cell.category,\n notes: cell.notes,\n prompt: cell.prompt,\n expectations: cell.expectations,\n referenceTrajectory,\n humanRatings: cell.human_ratings,\n cellLabel: cell.cell.label,\n axes: cell.cell.axes,\n assertionStats: cell.assertionStats,\n adapterErrors: cell.adapterErrors,\n behavioralPass: cell.passed,\n outcomePass: outcomePassForCell(\n cell.caseId,\n cell.cell.label,\n repetitions,\n ),\n repetitions,\n };\n });\n\n const cellsPassed = cells.filter((c) => c.behavioralPass).length;\n const gradedCells = cells.filter((c) => c.outcomePass !== undefined);\n // Run-level outcomePass is omitted when grading was not run for any cell.\n const outcomePass =\n gradedCells.length > 0\n ? gradedCells.every((c) => c.outcomePass === true)\n : undefined;\n\n return {\n schemaVersion: EVAL_RUN_SCHEMA_VERSION,\n runId: options.runId ?? randomUUID(),\n startedAt: report.startedAt,\n durationMs: report.durationMs,\n suite: options.suite,\n harness: {\n adapter: options.harness?.adapter ?? \"claude-code\",\n frameworkVersion: options.harness?.frameworkVersion,\n harnessVersion: options.harness?.harnessVersion,\n },\n provenance: options.provenance,\n summary: {\n cellsTotal: cells.length,\n cellsPassed,\n behavioralPass: cellsPassed === cells.length,\n outcomePass,\n },\n cells,\n };\n}\n\n/**\n * Build an envelope from on-disk runner and grader JSON artifacts.\n *\n * Reads `reportPath` as a {@link SuiteReport}. When `gradingPath` is set, merges\n * outcome grades from a {@link SuiteGradingReport}. When `suitePath` is set,\n * attaches suite URI and SHA-256 content hash for reproducibility.\n *\n * @param reportPath - Path to the suite run report JSON from `harness-eval run`.\n * @param options - Same build options as {@link buildEvalRunEnvelope}, plus file paths.\n */\nexport async function buildEvalRunEnvelopeFromFiles(\n reportPath: string,\n options: BuildEvalRunEnvelopeOptions & {\n gradingPath?: string;\n suitePath?: string;\n } = {},\n): Promise<EvalRunEnvelope> {\n const reportText = await readFile(reportPath, \"utf8\");\n const report = JSON.parse(reportText) as SuiteReport;\n\n const harnessAdapter = await resolveEnvelopeHarnessAdapter({\n harnessAdapter: options.harness?.adapter,\n suitePath: options.suitePath,\n });\n\n let grading: BuildEvalRunEnvelopeOptions[\"grading\"] | undefined =\n options.grading;\n\n if (options.gradingPath) {\n const gradingText = await readFile(options.gradingPath, \"utf8\");\n const parsed = JSON.parse(gradingText) as SuiteGradingReport;\n const judge =\n parsed.judge ??\n (await resolveEnvelopeJudge({\n gradingConfigPath: parsed.gradingConfigPath,\n }));\n grading = {\n gradedAt: parsed.gradedAt,\n sourceReport: parsed.sourceReport,\n results: parsed.results,\n judge,\n };\n }\n\n let suite = options.suite;\n if (options.suitePath) {\n const content = await readSuiteYamlContent(options.suitePath);\n suite = {\n ...suite,\n uri: options.suitePath,\n contentHash: createHash(\"sha256\").update(content).digest(\"hex\"),\n };\n }\n\n return buildEvalRunEnvelope(report, {\n ...options,\n suite,\n grading,\n harness: {\n ...options.harness,\n adapter: harnessAdapter,\n },\n });\n}\n","/**\n * Envelope projection methods for Vertex protojson interchange output.\n *\n * Flatten a nested {@link EvalRunEnvelope} into JSONL-friendly rows for:\n *\n * - `trajectory` projection — one {@link EvalDatasetRow} per repetition\n * - `instances` projection — one {@link InstancesJsonlRow} per trajectory metric\n *\n * Used by `harness-eval envelope --projection trajectory|instances`.\n */\n\nimport type {\n EvalDatasetRow,\n InstancesJsonlRow,\n TrajectoryInstanceMetricKey,\n TrajectoryInstancesJson,\n} from \"../types/eval-interchange\";\nimport type {\n EvalCellResult,\n EvalRepetition,\n EvalRunEnvelope,\n} from \"../types/eval-record\";\nimport { trajectoryInstanceMessageType } from \"./protojson/trajectory-instances\";\n\n/** Trajectory instance keys emitted in stable order for JSONL export. */\nconst TRAJECTORY_INSTANCE_KEYS: TrajectoryInstanceMetricKey[] = [\n \"exactMatch\",\n \"inOrderMatch\",\n \"anyOrderMatch\",\n \"precision\",\n \"recall\",\n \"singleToolUse\",\n];\n\n/**\n * Flatten one repetition into a trajectory dataset row.\n *\n * Pulls prompt from the cell, response from evaluationInstance, and falls\n * back to duration-based latency when enrich did not set latencySeconds.\n */\nexport function repetitionToDatasetRow(\n cell: EvalCellResult,\n repetition: EvalRepetition,\n): EvalDatasetRow {\n return {\n caseId: cell.caseId,\n repetitionIndex: repetition.repetitionIndex,\n prompt: cell.prompt,\n response: repetition.evaluationInstance?.response?.text,\n evaluationInstance: repetition.evaluationInstance,\n latencySeconds: repetition.latencySeconds ?? repetition.durationMs / 1000,\n failure: repetition.failure ?? (repetition.trajectory?.success ? 0 : 1),\n humanRatings: cell.humanRatings,\n };\n}\n\n/**\n * Expand one repetition into type-tagged instance rows for EvaluateInstances.\n *\n * Returns an empty array when the repetition has no reference trajectory\n * (and therefore no trajectoryInstances block).\n */\nexport function repetitionToInstanceRows(\n cell: EvalCellResult,\n repetition: EvalRepetition,\n): InstancesJsonlRow[] {\n if (!repetition.trajectoryInstances) return [];\n\n const rows: InstancesJsonlRow[] = [];\n for (const key of TRAJECTORY_INSTANCE_KEYS) {\n const instance = repetition.trajectoryInstances[key];\n if (!instance) continue;\n\n rows.push({\n messageType: trajectoryInstanceMessageType(key),\n caseId: cell.caseId,\n repetitionIndex: repetition.repetitionIndex,\n instance,\n });\n }\n\n return rows;\n}\n\n/**\n * Trajectory projection — all repetitions in the envelope as dataset rows.\n */\nexport function toTrajectory(envelope: EvalRunEnvelope): EvalDatasetRow[] {\n const rows: EvalDatasetRow[] = [];\n for (const cell of envelope.cells) {\n for (const repetition of cell.repetitions) {\n rows.push(repetitionToDatasetRow(cell, repetition));\n }\n }\n return rows;\n}\n\n/**\n * Instances projection — all trajectory metric instances as JSONL rows.\n */\nexport function toInstancesJsonl(envelope: EvalRunEnvelope): InstancesJsonlRow[] {\n const rows: InstancesJsonlRow[] = [];\n for (const cell of envelope.cells) {\n for (const repetition of cell.repetitions) {\n rows.push(...repetitionToInstanceRows(cell, repetition));\n }\n }\n return rows;\n}\n\n/** Return which trajectory metric keys are populated on an instances block. */\nexport function listTrajectoryInstanceKeys(\n instances: TrajectoryInstancesJson,\n): TrajectoryInstanceMetricKey[] {\n return TRAJECTORY_INSTANCE_KEYS.filter((key) => instances[key] !== undefined);\n}\n","/**\n * Resolve pipeline step inputs and outputs with precedence rules.\n *\n * Precedence: CLI override > explicit YAML > prior step in this run > default path on disk > error.\n */\n\nimport { stat } from \"node:fs/promises\";\nimport { dirname, resolve } from \"node:path\";\n\nimport type { EnvelopeProjection } from \"../cli/commands/envelope\";\nimport type { PipelineConfig } from \"../config/pipeline-schema\";\nimport { DEFAULT_PIPELINE_OUTPUTS } from \"../config/pipeline-schema\";\nimport { loadSuiteDocument } from \"../config/suite-document-loader\";\nimport { ConfigError } from \"../config/transform\";\n\nexport type PipelineStepName = \"run\" | \"grade\" | \"envelope\";\n\n/** CLI overrides for pipeline artifact paths (take precedence over YAML). */\nexport interface PipelineCliOverrides {\n run?: { output?: string; maxConcurrent?: number };\n grade?: { input?: string; output?: string; maxConcurrent?: number };\n envelope?: {\n report?: string;\n grading?: string;\n output?: string;\n projection?: EnvelopeProjection;\n };\n}\n\n/** Resolved paths for the harness run step. */\nexport interface ResolvedPipelineRun {\n output: string;\n maxConcurrent?: number;\n}\n\n/** Resolved input (suite report) and output (grading JSON) for the grade step. */\nexport interface ResolvedPipelineGrade {\n input: string;\n output: string;\n maxConcurrent?: number;\n}\n\n/** Resolved artifact paths for the envelope export step. */\nexport interface ResolvedPipelineEnvelope {\n report: string;\n grading?: string;\n output: string;\n projection: EnvelopeProjection;\n includeRawStreamEvents: boolean;\n noTranscript: boolean;\n}\n\n/** Fully resolved pipeline inputs for one or more enabled steps. */\nexport interface ResolvedPipeline {\n suitePath: string;\n run?: ResolvedPipelineRun;\n grade?: ResolvedPipelineGrade;\n envelope?: ResolvedPipelineEnvelope;\n}\n\n/** Inputs for {@link resolvePipelineInputs}. */\nexport interface ResolvePipelineInputsOptions {\n suitePath: string;\n suiteDir: string;\n pipeline: PipelineConfig;\n steps: PipelineStepName[];\n executed?: {\n run?: { output: string };\n grade?: { input: string; output: string };\n };\n overrides?: PipelineCliOverrides;\n}\n\n/** Resolve absolute paths for enabled pipeline steps. */\nexport async function resolvePipelineInputs(\n options: ResolvePipelineInputsOptions,\n): Promise<ResolvedPipeline> {\n const { suitePath, suiteDir, pipeline, steps, overrides } = options;\n const executed = options.executed ?? {};\n const stepSet = new Set(steps);\n\n const resolved: ResolvedPipeline = { suitePath: resolve(suitePath) };\n\n const defaultRunOutput = resolve(\n suiteDir,\n pipeline.run?.output ?? DEFAULT_PIPELINE_OUTPUTS.run,\n );\n const defaultGradeOutput = resolve(\n suiteDir,\n pipeline.grade?.output ?? DEFAULT_PIPELINE_OUTPUTS.grade,\n );\n\n if (stepSet.has(\"run\") && pipeline.run) {\n resolved.run = {\n output: resolve(\n suiteDir,\n overrides?.run?.output ?? pipeline.run.output,\n ),\n maxConcurrent: overrides?.run?.maxConcurrent ?? pipeline.run.maxConcurrent,\n };\n }\n\n if (stepSet.has(\"grade\") && pipeline.grade) {\n const input = await resolveReportPath({\n explicit: overrides?.grade?.input ?? pipeline.grade.input,\n executedOutput: executed.run?.output,\n defaultPath: defaultRunOutput,\n label: \"grade input (report)\",\n });\n\n resolved.grade = {\n input,\n output: resolve(\n suiteDir,\n overrides?.grade?.output ?? pipeline.grade.output,\n ),\n maxConcurrent:\n overrides?.grade?.maxConcurrent ?? pipeline.grade.maxConcurrent,\n };\n }\n\n if (stepSet.has(\"envelope\") && pipeline.envelope) {\n const report = await resolveReportPath({\n explicit: overrides?.envelope?.report ?? pipeline.envelope.report,\n executedOutput: executed.run?.output,\n defaultPath: defaultRunOutput,\n label: \"envelope report\",\n });\n\n const grading = await resolveOptionalGradingPath({\n explicit: overrides?.envelope?.grading ?? pipeline.envelope.grading,\n executedOutput: executed.grade?.output,\n defaultPath: defaultGradeOutput,\n });\n\n resolved.envelope = {\n report,\n grading,\n output: resolve(\n suiteDir,\n overrides?.envelope?.output ?? pipeline.envelope.output,\n ),\n projection:\n overrides?.envelope?.projection ??\n pipeline.envelope.projection ??\n \"envelope\",\n includeRawStreamEvents:\n pipeline.envelope.includeRawStreamEvents ?? false,\n noTranscript: pipeline.envelope.noTranscript ?? false,\n };\n }\n\n return resolved;\n}\n\n/**\n * Resolve a required report path: explicit override → prior step output → default on disk.\n * Throws when none of the above exist.\n */\nasync function resolveReportPath(options: {\n explicit?: string;\n executedOutput?: string;\n defaultPath: string;\n label: string;\n}): Promise<string> {\n if (options.explicit) {\n return resolve(options.explicit);\n }\n if (options.executedOutput) {\n return resolve(options.executedOutput);\n }\n if (await pathExists(options.defaultPath)) {\n return options.defaultPath;\n }\n throw new ConfigError(\n `pipeline: could not resolve ${options.label}; specify an explicit path or run the run step first`,\n options.defaultPath,\n );\n}\n\n/** Resolve optional grading path; returns undefined when grading was not run and file is absent. */\nasync function resolveOptionalGradingPath(options: {\n explicit?: string;\n executedOutput?: string;\n defaultPath: string;\n}): Promise<string | undefined> {\n if (options.explicit) {\n return resolve(options.explicit);\n }\n if (options.executedOutput) {\n return resolve(options.executedOutput);\n }\n if (await pathExists(options.defaultPath)) {\n return options.defaultPath;\n }\n return undefined;\n}\n\nasync function pathExists(filePath: string): Promise<boolean> {\n try {\n await stat(filePath);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Resolve a grading artifact path from a unified suite's `pipeline:` block.\n *\n * Used by `harness-eval envelope --suite` when `--grading` is omitted (spec C-7).\n * Checks `pipeline.envelope.grading` then default `pipeline.grade.output` on disk.\n */\nexport async function resolveGradingArtifactFromSuite(\n suitePath: string,\n): Promise<string | undefined> {\n let doc;\n try {\n doc = await loadSuiteDocument(suitePath);\n } catch {\n return undefined;\n }\n if (!doc.pipeline) return undefined;\n\n const explicit = doc.pipeline.envelope?.grading;\n if (explicit && (await pathExists(explicit))) {\n return explicit;\n }\n\n const defaultGrade = doc.pipeline.grade?.output;\n if (defaultGrade && (await pathExists(defaultGrade))) {\n return defaultGrade;\n }\n\n return undefined;\n}\n\n/** Parse `--steps run,grade,envelope` against configured pipeline keys. */\nexport function parsePipelineSteps(\n pipeline: PipelineConfig,\n stepsArg: string | undefined,\n): PipelineStepName[] {\n const configured: PipelineStepName[] = [];\n if (pipeline.run !== undefined) configured.push(\"run\");\n if (pipeline.grade !== undefined) configured.push(\"grade\");\n if (pipeline.envelope !== undefined) configured.push(\"envelope\");\n\n if (configured.length === 0) {\n throw new ConfigError(\"pipeline block has no steps configured\");\n }\n\n if (!stepsArg) {\n return configured;\n }\n\n const validStepNames: ReadonlySet<string> = new Set([\"run\", \"grade\", \"envelope\"]);\n const requested = stepsArg\n .split(\",\")\n .map((s) => s.trim())\n .filter(Boolean);\n\n for (const step of requested) {\n if (!validStepNames.has(step)) {\n throw new ConfigError(\n `unknown pipeline step \"${step}\"; valid steps are: run, grade, envelope`,\n );\n }\n if (!configured.includes(step as PipelineStepName)) {\n throw new ConfigError(\n `pipeline step \"${step}\" is not configured in suite.yaml`,\n );\n }\n }\n\n const requestedSet = new Set(requested);\n return configured.filter((step) => requestedSet.has(step));\n}\n\n/** Parent directory of suite.yaml. */\nexport function suiteDirectoryFromPath(suitePath: string): string {\n return dirname(resolve(suitePath));\n}\n","/**\n * Minimal argv parser — no external deps.\n *\n * Parses `command`, positional args, and `--long` / `-s` flags. Boolean\n * flags omit a value; the next token starting with `-` is not consumed as\n * a value. Use `--` to pass through remaining tokens as positional.\n */\n\n/** Parsed CLI argv: optional subcommand, positional args, and flag map. */\nexport interface ParsedArgs {\n command?: string;\n positional: string[];\n options: Record<string, string | boolean>;\n}\n\n/** Parse process argv into command, positional args, and options. */\nexport function parseArgs(argv: string[]): ParsedArgs {\n const positional: string[] = [];\n const options: Record<string, string | boolean> = {};\n let command: string | undefined;\n\n const args = [...argv];\n if (args.length > 0 && !args[0].startsWith(\"-\")) {\n command = args.shift();\n }\n\n for (let i = 0; i < args.length; i++) {\n const arg = args[i];\n if (arg === \"--\") {\n positional.push(...args.slice(i + 1));\n break;\n }\n if (arg.startsWith(\"--\")) {\n const key = arg.slice(2);\n const next = args[i + 1];\n if (next && !next.startsWith(\"-\")) {\n options[key] = next;\n i++;\n } else {\n options[key] = true;\n }\n } else if (arg.startsWith(\"-\") && arg.length === 2) {\n const key = arg.slice(1);\n const next = args[i + 1];\n if (next && !next.startsWith(\"-\")) {\n options[key] = next;\n i++;\n } else {\n options[key] = true;\n }\n } else {\n positional.push(arg);\n }\n }\n\n return { command, positional, options };\n}\n\n/** Return a string option value, or undefined when absent or boolean. */\nexport function getOption(\n options: Record<string, string | boolean>,\n name: string,\n): string | undefined {\n const v = options[name];\n return typeof v === \"string\" ? v : undefined;\n}\n\n/** Parse an integer option with fallback when absent or non-numeric. */\nexport function getOptionInt(\n options: Record<string, string | boolean>,\n name: string,\n defaultValue: number,\n): number {\n const v = getOption(options, name);\n if (v === undefined) return defaultValue;\n const n = Number.parseInt(v, 10);\n if (!Number.isFinite(n)) return defaultValue;\n return n;\n}\n\n/** True when a boolean flag is set or explicitly `\"true\"`. */\nexport function hasOption(\n options: Record<string, string | boolean>,\n name: string,\n): boolean {\n const v = options[name];\n return v === true || (typeof v === \"string\" && v === \"true\");\n}\n","/**\n * `harness-eval envelope` — build EvalRunEnvelope and interchange projections.\n *\n * Reads a suite run report (and optional grading JSON), builds a versioned\n * {@link EvalRunEnvelope}, and serializes one of three projections:\n *\n * - `envelope` — full nested JSON document (default)\n * - `trajectory` — JSONL of {@link EvalDatasetRow} per repetition\n * - `instances` — JSONL of {@link InstancesJsonlRow} for Vertex batch upload\n *\n * Exit code 0 when behavioral pass, 1 when any cell failed assertions.\n */\n\nimport { readFile, writeFile } from \"node:fs/promises\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nimport { buildEvalRunEnvelopeFromFiles } from \"../../eval-record/build\";\nimport {\n toInstancesJsonl,\n toTrajectory,\n} from \"../../eval-interchange/projections\";\nimport { resolveGradingArtifactFromSuite } from \"../../pipeline/resolve-inputs\";\nimport type { EvalRunEnvelope } from \"../../types/eval-record\";\nimport { getOption, hasOption, type ParsedArgs } from \"../args\";\n\n/** Supported `--projection` values for envelope output. */\nexport type EnvelopeProjection =\n | \"envelope\"\n | \"trajectory\"\n | \"instances\";\n\nconst PROJECTIONS = new Set<EnvelopeProjection>([\n \"envelope\",\n \"trajectory\",\n \"instances\",\n]);\n\n/**\n * Parse and validate `--projection` CLI flag.\n *\n * @returns `\"envelope\"` when omitted; `undefined` when value is invalid.\n */\nexport function parseEnvelopeProjection(\n value: string | undefined,\n): EnvelopeProjection | undefined {\n if (value === undefined) return \"envelope\";\n if (PROJECTIONS.has(value as EnvelopeProjection)) {\n return value as EnvelopeProjection;\n }\n return undefined;\n}\n\n/**\n * Serialize an envelope to stdout/file string for the chosen projection.\n *\n * Trajectory and instances projections emit NDJSON (one JSON object per line).\n */\nexport function serializeEnvelopeProjection(\n envelope: EvalRunEnvelope,\n projection: EnvelopeProjection,\n): string {\n switch (projection) {\n case \"trajectory\":\n return `${toTrajectory(envelope).map((row) => JSON.stringify(row)).join(\"\\n\")}\\n`;\n case \"instances\":\n return `${toInstancesJsonl(envelope).map((row) => JSON.stringify(row)).join(\"\\n\")}\\n`;\n case \"envelope\":\n default:\n return `${JSON.stringify(envelope, null, 2)}\\n`;\n }\n}\n\n/** Read harness-eval package version for envelope harness.frameworkVersion. */\nasync function readFrameworkVersion(): Promise<string | undefined> {\n try {\n const packagePath = join(\n dirname(fileURLToPath(import.meta.url)),\n \"../../../package.json\",\n );\n const text = await readFile(packagePath, \"utf8\");\n const pkg = JSON.parse(text) as { version?: string };\n return pkg.version;\n } catch {\n return undefined;\n }\n}\n\n/**\n * CLI entry point for the `envelope` subcommand.\n *\n * @returns Process exit code: 0 on behavioral pass, 1 on failure, 2 on usage/error.\n */\nexport async function envelopeCommand(args: ParsedArgs): Promise<number> {\n const reportPath = args.positional[0];\n if (!reportPath) {\n console.error(\n \"usage: harness-eval envelope <report.json> [--output path] [--grading path] [--suite path] [--projection envelope|trajectory|instances] [--include-raw-stream-events] [--no-transcript]\",\n );\n return 2;\n }\n\n const outputPath = getOption(args.options, \"output\");\n const suitePath = getOption(args.options, \"suite\");\n let gradingPath = getOption(args.options, \"grading\");\n if (!gradingPath && suitePath) {\n gradingPath = await resolveGradingArtifactFromSuite(suitePath);\n }\n const projection = parseEnvelopeProjection(\n getOption(args.options, \"projection\"),\n );\n\n if (!projection) {\n console.error(\n \"invalid --projection; expected envelope, trajectory, or instances\",\n );\n return 2;\n }\n\n let envelope: EvalRunEnvelope;\n try {\n const frameworkVersion = await readFrameworkVersion();\n envelope = await buildEvalRunEnvelopeFromFiles(reportPath, {\n gradingPath,\n suitePath,\n includeTranscript: !hasOption(args.options, \"no-transcript\"),\n includeRawStreamEvents: hasOption(args.options, \"include-raw-stream-events\"),\n harness: { frameworkVersion },\n });\n } catch (err) {\n console.error(err instanceof Error ? err.message : String(err));\n return 2;\n }\n\n const serialized = serializeEnvelopeProjection(envelope, projection);\n\n if (outputPath) {\n await writeFile(outputPath, serialized, \"utf8\");\n } else {\n process.stdout.write(serialized);\n }\n\n return envelope.summary.behavioralPass ? 0 : 1;\n}\n","/**\n * Orchestrate run → grade → envelope pipeline steps.\n */\n\nimport { writeFile } from \"node:fs/promises\";\n\nimport { getAdapter } from \"../adapters/registry\";\nimport type { GradingConfig } from \"../config/grading-loader\";\nimport type { SuiteDocument } from \"../config/suite-document\";\nimport { ConfigError } from \"../config/transform\";\nimport { gradeReport, gradingReportPassed, loadSuiteReport, resolveGradeOptions } from \"../grader/index\";\nimport { buildEvalRunEnvelopeFromFiles } from \"../eval-record/build\";\nimport { serializeEnvelopeProjection } from \"../cli/commands/envelope\";\nimport { runSuite } from \"../runner/suite\";\nimport type { ProgressCallback, SuiteReport } from \"../runner/types\";\nimport type { GradeReportOptions } from \"../grader/types\";\nimport {\n parsePipelineSteps,\n resolvePipelineInputs,\n suiteDirectoryFromPath,\n type PipelineCliOverrides,\n type PipelineStepName,\n} from \"./resolve-inputs\";\n\n/** Options for {@link runPipeline} (CLI flags and progress callbacks). */\nexport interface RunPipelineOptions {\n /** Comma-separated subset of configured steps (e.g. `run,grade`). */\n steps?: string;\n maxConcurrent?: number;\n overrides?: PipelineCliOverrides;\n onRunProgress?: ProgressCallback;\n onGradeProgress?: GradeReportOptions[\"onProgress\"];\n /** Framework version stamped on envelope export. */\n frameworkVersion?: string;\n}\n\n/** Outcome of a pipeline run including per-step exit semantics. */\nexport interface RunPipelineResult {\n /** 0 pass, 1 eval/grade/envelope failure, 2 load error (thrown before return). */\n exitCode: number;\n stepsRun: PipelineStepName[];\n runReport?: SuiteReport;\n}\n\n/** Execute configured pipeline steps in order; stop on first failure. */\nexport async function runPipeline(\n doc: SuiteDocument,\n options: RunPipelineOptions = {},\n): Promise<RunPipelineResult> {\n if (!doc.pipeline) {\n throw new ConfigError(\"suite document has no pipeline block\", doc.suitePath);\n }\n\n const steps = parsePipelineSteps(doc.pipeline, options.steps);\n const suiteDir = suiteDirectoryFromPath(doc.suitePath);\n const executed: {\n run?: { output: string };\n grade?: { input: string; output: string };\n } = {};\n\n let runReport: SuiteReport | undefined;\n let exitCode = 0;\n\n for (const step of steps) {\n const resolved = await resolvePipelineInputs({\n suitePath: doc.suitePath,\n suiteDir,\n pipeline: doc.pipeline,\n steps: [step],\n executed,\n overrides: options.overrides,\n });\n\n if (step === \"run\" && resolved.run) {\n const adapter = getAdapter(doc.suite.adapter ?? \"claude-code\");\n runReport = await runSuite(doc.suite, {\n adapter,\n maxConcurrent:\n resolved.run.maxConcurrent ?? options.maxConcurrent ?? 4,\n onProgress: options.onRunProgress,\n });\n await writeFile(\n resolved.run.output,\n JSON.stringify(runReport, null, 2),\n \"utf8\",\n );\n executed.run = { output: resolved.run.output };\n // Fail fast: behavioral assertion failures skip later pipeline steps.\n if (!runReport.cells.every((cell) => cell.passed)) {\n return { exitCode: 1, stepsRun: steps.slice(0, steps.indexOf(step) + 1), runReport };\n }\n continue;\n }\n\n if (step === \"grade\" && resolved.grade) {\n if (!doc.judge) {\n throw new ConfigError(\"grade step requires inline judge: block in suite.yaml\", doc.suitePath);\n }\n const gradingConfig: GradingConfig = { judge: doc.judge };\n const gradeOptions = resolveGradeOptions(\n gradingConfig,\n {\n sourceReport: resolved.grade.input,\n maxConcurrent: resolved.grade.maxConcurrent,\n },\n doc.suitePath,\n );\n const report = await loadSuiteReport(resolved.grade.input);\n const grading = await gradeReport(report, {\n ...gradeOptions,\n onProgress: options.onGradeProgress,\n });\n await writeFile(\n resolved.grade.output,\n JSON.stringify(grading, null, 2),\n \"utf8\",\n );\n executed.grade = {\n input: resolved.grade.input,\n output: resolved.grade.output,\n };\n if (!gradingReportPassed(grading)) {\n // Outcome grading failure stops the pipeline before envelope export.\n return {\n exitCode: 1,\n stepsRun: steps.slice(0, steps.indexOf(step) + 1),\n runReport,\n };\n }\n continue;\n }\n\n if (step === \"envelope\" && resolved.envelope) {\n const envelope = await buildEvalRunEnvelopeFromFiles(\n resolved.envelope.report,\n {\n gradingPath: resolved.envelope.grading,\n suitePath: doc.suitePath,\n includeTranscript: !resolved.envelope.noTranscript,\n includeRawStreamEvents: resolved.envelope.includeRawStreamEvents,\n harness: { frameworkVersion: options.frameworkVersion },\n },\n );\n const serialized = serializeEnvelopeProjection(\n envelope,\n resolved.envelope.projection,\n );\n await writeFile(resolved.envelope.output, serialized, \"utf8\");\n const behavioralFail = !envelope.summary.behavioralPass;\n const outcomeFail =\n envelope.summary.outcomePass !== undefined &&\n !envelope.summary.outcomePass;\n if (behavioralFail || outcomeFail) {\n return {\n exitCode: 1,\n stepsRun: steps.slice(0, steps.indexOf(step) + 1),\n runReport,\n };\n }\n continue;\n }\n }\n\n return { exitCode, stepsRun: steps, runReport };\n}\n","/**\n * Helpers for OTLP attribute values.\n *\n * OTLP JSON uses typed value objects (`stringValue`, `intValue`, etc.) rather\n * than plain JSON scalars on attributes.\n */\n\nimport type { AnyValue, KeyValue } from \"./types\";\n\n/** Build a string-typed OTLP attribute. */\nexport function strAttr(key: string, value: string): KeyValue {\n return { key, value: { stringValue: value } };\n}\n\n/** Build an integer-typed OTLP attribute (stored as decimal string). */\nexport function intAttr(key: string, value: number): KeyValue {\n return { key, value: { intValue: String(value) } };\n}\n\n/** Build a boolean-typed OTLP attribute. */\nexport function boolAttr(key: string, value: boolean): KeyValue {\n return { key, value: { boolValue: value } };\n}\n\n/** Build a JSON-serialized string attribute (common for message arrays). */\nexport function jsonAttr(key: string, value: unknown): KeyValue {\n return { key, value: { stringValue: JSON.stringify(value) } };\n}\n\n/** Coerce an arbitrary JS value into an OTLP {@link AnyValue}. */\nexport function anyValue(value: unknown): AnyValue {\n if (value === null || value === undefined) {\n return { stringValue: \"\" };\n }\n if (typeof value === \"string\") {\n return { stringValue: value };\n }\n if (typeof value === \"boolean\") {\n return { boolValue: value };\n }\n if (typeof value === \"number\") {\n if (Number.isInteger(value)) {\n return { intValue: String(value) };\n }\n return { doubleValue: value };\n }\n return { stringValue: JSON.stringify(value) };\n}\n","/**\n * Build GenAI semconv message arrays from a {@link TrajectoryView}.\n *\n * Message shapes follow OpenTelemetry GenAI semantic conventions for\n * `gen_ai.input.messages` and `gen_ai.output.messages` span attributes.\n */\n\nimport type { AssistantTurn, ToolCall, TrajectoryView } from \"../types/trajectory\";\n\n/** One message in GenAI semconv format (role + typed parts). */\nexport interface GenAiMessage {\n role: string;\n parts: GenAiPart[];\n finish_reason?: string;\n}\n\n/** Discriminated content part within a {@link GenAiMessage}. */\nexport type GenAiPart =\n | { type: \"text\"; content: string }\n | {\n type: \"tool_call\";\n id: string;\n name: string;\n arguments: unknown;\n }\n | {\n type: \"tool_call_response\";\n id: string;\n result: unknown;\n };\n\n/**\n * Map harness stop reasons to GenAI semconv finish_reason values.\n *\n * Unknown reasons pass through unchanged for forward compatibility.\n */\nexport function mapStopReason(reason: string | null): string | undefined {\n if (!reason) return undefined;\n switch (reason) {\n case \"end_turn\":\n return \"stop\";\n case \"tool_use\":\n return \"tool_calls\";\n case \"max_tokens\":\n return \"length\";\n case \"stop_sequence\":\n return \"stop\";\n default:\n return reason;\n }\n}\n\n/** Build a tool_call part from a {@link ToolCall}. */\nexport function toolCallPart(call: ToolCall): GenAiPart {\n return {\n type: \"tool_call\",\n id: call.callId,\n name: call.name,\n arguments: call.args ?? {},\n };\n}\n\n/** Build a tool_call_response part from a {@link ToolCall} result. */\nexport function toolResponsePart(call: ToolCall): GenAiPart {\n return {\n type: \"tool_call_response\",\n id: call.callId,\n result: call.result,\n };\n}\n\n/** Convert one assistant turn to a GenAI semconv assistant message. */\nexport function assistantMessageFromTurn(turn: AssistantTurn): GenAiMessage {\n const parts: GenAiPart[] = [];\n if (turn.text) {\n parts.push({ type: \"text\", content: turn.text });\n }\n for (const call of turn.toolCalls) {\n parts.push(toolCallPart(call));\n }\n const finish = mapStopReason(turn.stopReason);\n return {\n role: \"assistant\",\n parts,\n ...(finish ? { finish_reason: finish } : {}),\n };\n}\n\n/** Aggregate tool results from a turn into a single tool-role message, if any. */\nexport function toolResultsMessage(calls: ToolCall[]): GenAiMessage | null {\n const parts = calls\n .filter((c) => c.result !== null)\n .map((c) => toolResponsePart(c));\n if (parts.length === 0) return null;\n return { role: \"tool\", parts };\n}\n\n/**\n * Input history before the assistant turn at `turnIndex`.\n */\nexport function inputMessagesBeforeTurn(\n view: TrajectoryView,\n turnIndex: number,\n prompt?: string,\n): GenAiMessage[] {\n const messages: GenAiMessage[] = [];\n\n if (prompt) {\n messages.push({\n role: \"user\",\n parts: [{ type: \"text\", content: prompt }],\n });\n }\n\n for (let i = 0; i < turnIndex; i++) {\n const turn = view.turns[i];\n if (!turn) continue;\n messages.push(assistantMessageFromTurn(turn));\n const toolMsg = toolResultsMessage(turn.toolCalls);\n if (toolMsg) messages.push(toolMsg);\n }\n\n return messages;\n}\n\n/** Messages representing model output for the final turn (or synthetic final response). */\nexport function finalOutputMessages(view: TrajectoryView): GenAiMessage[] {\n if (view.turns.length === 0) {\n if (!view.finalResponse) return [];\n return [\n {\n role: \"assistant\",\n parts: [{ type: \"text\", content: view.finalResponse }],\n finish_reason: mapStopReason(view.finalStopReason),\n },\n ];\n }\n\n const last = view.turns[view.turns.length - 1];\n return [assistantMessageFromTurn(last)];\n}\n","/**\n * Minimal OTLP JSON types for trace export.\n *\n * Shapes follow OTLP/HTTP JSON Protobuf encoding (lowerCamelCase field names).\n * @see https://opentelemetry.io/docs/specs/otlp/\n */\n\n/** OTLP ExportTraceServiceRequest root — batch of resource spans. */\nexport interface ExportTraceServiceRequest {\n resourceSpans: ResourceSpans[];\n}\n\n/** Resource-attributed span group in an export batch. */\nexport interface ResourceSpans {\n resource: Resource;\n scopeSpans: ScopeSpans[];\n}\n\n/** OTLP resource descriptor (service.name, agent metadata). */\nexport interface Resource {\n attributes: KeyValue[];\n}\n\n/** Spans emitted by one instrumentation scope within a resource. */\nexport interface ScopeSpans {\n scope: InstrumentationScope;\n spans: Span[];\n}\n\n/** Instrumentation library identity (name + optional version). */\nexport interface InstrumentationScope {\n name: string;\n version?: string;\n}\n\n/** One span in OTLP JSON encoding (nanosecond timestamps as strings). */\nexport interface Span {\n traceId: string;\n spanId: string;\n parentSpanId?: string;\n name: string;\n kind: number;\n startTimeUnixNano: string;\n endTimeUnixNano: string;\n attributes: KeyValue[];\n status?: SpanStatus;\n}\n\n/** OTLP span status (OK, ERROR, or UNSET). */\nexport interface SpanStatus {\n code: number;\n message?: string;\n}\n\n/** Key-value attribute pair on a span or resource. */\nexport interface KeyValue {\n key: string;\n value: AnyValue;\n}\n\n/** Discriminated OTLP attribute value (one of the typed fields set). */\nexport interface AnyValue {\n stringValue?: string;\n boolValue?: boolean;\n intValue?: string;\n doubleValue?: number;\n bytesValue?: string;\n arrayValue?: ArrayValue;\n kvlistValue?: KeyValueList;\n}\n\nexport interface ArrayValue {\n values: AnyValue[];\n}\n\nexport interface KeyValueList {\n values: KeyValue[];\n}\n\n/** OTLP span kinds (enum integers). */\nexport const SpanKind = {\n INTERNAL: 1,\n CLIENT: 2,\n} as const;\n\n/** OTLP status codes. */\nexport const StatusCode = {\n UNSET: 0,\n OK: 1,\n ERROR: 2,\n} as const;\n\n/** Options passed to {@link trajectoryToOtlp} / {@link emitOtel}. */\nexport interface EmitOtelOptions {\n /** User prompt for the first `gen_ai.input.messages` entry. */\n prompt?: string;\n /** `gen_ai.agent.name` on the root span. Default: `claude-code`. */\n agentName?: string;\n /** `gen_ai.provider.name`. Default: `anthropic`. */\n providerName?: string;\n /** Resource `service.name`. Default: `harness-eval`. */\n serviceName?: string;\n /** Instrumentation scope name. Default: `@alis-build/harness-eval`. */\n instrumentationScope?: string;\n /**\n * Wall-clock end time for the trace (ms). Defaults to `Date.now()`.\n * Start is derived from `view.usage.durationMs`.\n */\n endTimeMs?: number;\n}\n","/**\n * TrajectoryView → OTLP JSON export using OpenTelemetry GenAI semantic conventions.\n *\n * Produces an `ExportTraceServiceRequest` suitable for OTLP/HTTP JSON ingestion.\n * Assertions continue to use {@link TrajectoryView} directly; this is export-only.\n */\n\nimport { createHash } from \"node:crypto\";\n\nimport type { TrajectoryView } from \"../types/trajectory\";\nimport { boolAttr, intAttr, jsonAttr, strAttr } from \"./attributes\";\nimport {\n assistantMessageFromTurn,\n inputMessagesBeforeTurn,\n mapStopReason,\n} from \"./messages\";\nimport type {\n EmitOtelOptions,\n ExportTraceServiceRequest,\n Span,\n SpanStatus,\n} from \"./types\";\nimport { SpanKind, StatusCode } from \"./types\";\n\nconst INSTRUMENTATION_VERSION = \"0.1.0\";\n\ninterface SpanTiming {\n startNs: string;\n endNs: string;\n}\n\n/**\n * Map a {@link TrajectoryView} to OTLP trace JSON.\n *\n * Span tree (siblings under `invoke_agent`, not nested):\n * ```\n * invoke_agent\n * ├── chat {model}\n * ├── execute_tool {name}\n * ├── chat {model}\n * └── ...\n * ```\n */\nexport function trajectoryToOtlp(\n view: TrajectoryView,\n options: EmitOtelOptions = {},\n): ExportTraceServiceRequest {\n const agentName = options.agentName ?? \"claude-code\";\n const providerName = options.providerName ?? \"anthropic\";\n const serviceName = options.serviceName ?? \"harness-eval\";\n const scopeName =\n options.instrumentationScope ?? \"@alis-build/harness-eval\";\n\n const traceId = traceIdFromSession(view.meta.sessionId);\n const rootSpanId = spanIdFromKey(traceId, \"invoke_agent\");\n\n const durationMs = Math.max(view.usage.durationMs, 1);\n const endMs = options.endTimeMs ?? Date.now();\n const startMs = endMs - durationMs;\n const rootStartNs = msToNs(startMs);\n const rootEndNs = msToNs(endMs);\n\n const spans: Span[] = [];\n const timings = buildSpanTimings(view, startMs, endMs);\n\n spans.push({\n traceId,\n spanId: rootSpanId,\n name: \"invoke_agent\",\n kind: SpanKind.INTERNAL,\n startTimeUnixNano: rootStartNs,\n endTimeUnixNano: rootEndNs,\n attributes: [\n strAttr(\"gen_ai.operation.name\", \"invoke_agent\"),\n strAttr(\"gen_ai.agent.name\", agentName),\n strAttr(\"gen_ai.provider.name\", providerName),\n strAttr(\"gen_ai.conversation.id\", view.meta.sessionId),\n strAttr(\"gen_ai.request.model\", view.meta.model),\n strAttr(\"gen_ai.response.model\", view.meta.model),\n intAttr(\"gen_ai.usage.input_tokens\", view.usage.inputTokens),\n intAttr(\"gen_ai.usage.output_tokens\", view.usage.outputTokens),\n boolAttr(\"harness_eval.success\", view.success),\n ],\n status: viewStatus(view),\n });\n\n let opIndex = 0;\n for (const turn of view.turns) {\n const chatTiming = timings[opIndex++];\n const chatSpanId = spanIdFromKey(traceId, `chat:${turn.turnIndex}`);\n const inputMessages = inputMessagesBeforeTurn(\n view,\n turn.turnIndex,\n options.prompt,\n );\n const outputMessages = [assistantMessageFromTurn(turn)];\n\n spans.push({\n traceId,\n spanId: chatSpanId,\n parentSpanId: rootSpanId,\n name: `chat ${view.meta.model}`,\n kind: SpanKind.CLIENT,\n startTimeUnixNano: chatTiming.startNs,\n endTimeUnixNano: chatTiming.endNs,\n attributes: [\n strAttr(\"gen_ai.operation.name\", \"chat\"),\n strAttr(\"gen_ai.provider.name\", providerName),\n strAttr(\"gen_ai.request.model\", view.meta.model),\n strAttr(\"gen_ai.response.model\", view.meta.model),\n ...(inputMessages.length > 0\n ? [jsonAttr(\"gen_ai.input.messages\", inputMessages)]\n : []),\n jsonAttr(\"gen_ai.output.messages\", outputMessages),\n ...(turn.stopReason\n ? [\n jsonAttr(\"gen_ai.response.finish_reasons\", [\n mapStopReason(turn.stopReason) ?? turn.stopReason,\n ]),\n ]\n : []),\n ],\n status: { code: StatusCode.OK },\n });\n\n if (turn.toolCalls.length === 0) continue;\n\n const toolTiming = timings[opIndex++];\n for (const call of turn.toolCalls) {\n const toolSpanId = spanIdFromKey(\n traceId,\n `tool:${call.callId}`,\n );\n\n spans.push({\n traceId,\n spanId: toolSpanId,\n parentSpanId: rootSpanId,\n name: `execute_tool ${call.name}`,\n kind: SpanKind.INTERNAL,\n startTimeUnixNano: toolTiming.startNs,\n endTimeUnixNano: toolTiming.endNs,\n attributes: [\n strAttr(\"gen_ai.operation.name\", \"execute_tool\"),\n strAttr(\"gen_ai.provider.name\", providerName),\n strAttr(\"gen_ai.tool.name\", call.name),\n strAttr(\"gen_ai.tool.call.id\", call.callId),\n jsonAttr(\"gen_ai.tool.call.arguments\", call.args ?? {}),\n ...(call.result !== null\n ? [jsonAttr(\"gen_ai.tool.call.result\", call.result)]\n : []),\n ...(call.namespace\n ? [strAttr(\"harness_eval.tool.namespace\", call.namespace)]\n : []),\n boolAttr(\"harness_eval.tool.is_error\", call.isError),\n ],\n status: call.isError\n ? { code: StatusCode.ERROR, message: \"tool reported error\" }\n : { code: StatusCode.OK },\n });\n }\n }\n\n return {\n resourceSpans: [\n {\n resource: {\n attributes: [\n strAttr(\"service.name\", serviceName),\n strAttr(\"gen_ai.agent.name\", agentName),\n ],\n },\n scopeSpans: [\n {\n scope: {\n name: scopeName,\n version: INSTRUMENTATION_VERSION,\n },\n spans,\n },\n ],\n },\n ],\n };\n}\n\n/** Alias for {@link trajectoryToOtlp} — matches implementation plan naming. */\nexport const emitOtel = trajectoryToOtlp;\n\n/** Map view success flag to OTLP span status on the root invoke_agent span. */\nfunction viewStatus(view: TrajectoryView): SpanStatus {\n if (view.success) {\n return { code: StatusCode.OK };\n }\n return {\n code: StatusCode.ERROR,\n message: \"harness run did not complete successfully\",\n };\n}\n\n/**\n * Assign synthetic timestamps to chat and tool spans.\n *\n * Stream-json does not carry per-turn wall times, so we divide the session\n * duration evenly across chat/tool slots for OTLP consumers that require\n * start/end times on every span.\n */\nfunction buildSpanTimings(\n view: TrajectoryView,\n startMs: number,\n endMs: number,\n): SpanTiming[] {\n const slots: Array<\"chat\" | \"tools\"> = [];\n for (const turn of view.turns) {\n slots.push(\"chat\");\n if (turn.toolCalls.length > 0) slots.push(\"tools\");\n }\n\n if (slots.length === 0) {\n return [];\n }\n\n const totalMs = Math.max(endMs - startMs, 1);\n const slotMs = totalMs / slots.length;\n const timings: SpanTiming[] = [];\n let offset = startMs;\n\n for (const slot of slots) {\n const slotStart = offset;\n const slotEnd = offset + slotMs;\n timings.push({\n startNs: msToNs(slotStart),\n endNs: msToNs(slotEnd),\n });\n offset = slotEnd;\n }\n\n return timings;\n}\n\n/**\n * Derive a deterministic 128-bit trace id from the harness session id.\n *\n * Uses SHA-256 truncation so the same session always maps to the same trace.\n */\nexport function traceIdFromSession(sessionId: string): string {\n return createHash(\"sha256\")\n .update(`harness-eval:trace:${sessionId}`)\n .digest(\"hex\")\n .slice(0, 32)\n .toUpperCase();\n}\n\n/**\n * Derive a deterministic 64-bit span id from trace id and a logical span key.\n */\nexport function spanIdFromKey(traceId: string, key: string): string {\n return createHash(\"sha256\")\n .update(`${traceId}:span:${key}`)\n .digest(\"hex\")\n .slice(0, 16)\n .toUpperCase();\n}\n\n/** Convert milliseconds since epoch to OTLP nanosecond timestamp string. */\nfunction msToNs(ms: number): string {\n return String(Math.round(ms * 1_000_000));\n}\n","/**\n * Console (ANSI) report formatter.\n */\n\nimport type { RenderableRow } from \"./types\";\n\nconst RESET = \"\\x1b[0m\";\nconst GREEN = \"\\x1b[32m\";\nconst RED = \"\\x1b[31m\";\nconst YELLOW = \"\\x1b[33m\";\nconst DIM = \"\\x1b[2m\";\n\n/**\n * Render renderable rows as ANSI-colored console output.\n *\n * @param color When false, emit plain text without escape codes.\n */\nexport function formatConsole(rows: RenderableRow[], color = true): string {\n const lines: string[] = [];\n\n for (const row of rows) {\n const status = row.passed\n ? color ? `${GREEN}PASS${RESET}` : \"PASS\"\n : color ? `${RED}FAIL${RESET}` : \"FAIL\";\n\n const crashNote =\n row.adapterErrors > 0\n ? ` ${color ? YELLOW : \"\"}[${row.adapterErrors} adapter errors]${color ? RESET : \"\"}`\n : \"\";\n\n lines.push(`${row.caseId} @ ${row.cellLabel} ${status}${crashNote}`);\n if (row.category) lines.push(` category: ${row.category}`);\n\n for (const stat of row.stats) {\n const marker = stat.meetsThreshold\n ? color ? `${GREEN}✓${RESET}` : \"✓\"\n : color ? `${RED}✗${RESET}` : \"✗\";\n\n const rateStr = formatRate(stat);\n const thresholdPct = (stat.threshold * 100).toFixed(0);\n let line = ` ├─ ${stat.description}: ${rateStr} [threshold ${thresholdPct}%] ${marker}`;\n\n if (stat.delta !== undefined && stat.baselinePassRate !== undefined) {\n const arrow = stat.delta >= 0 ? \"↑\" : \"↓\";\n const basePct = (stat.baselinePassRate * 100).toFixed(0);\n const curPct = (stat.passRate * 100).toFixed(0);\n const deltaPct = (stat.delta * 100).toFixed(0);\n line += ` (${basePct}% → ${curPct}% (${arrow}${deltaPct}%))`;\n }\n\n lines.push(line);\n }\n lines.push(\"\");\n }\n\n return lines.join(\"\\n\").trimEnd();\n}\n\n/** Format pass rate for display, noting when all reps crashed. */\nfunction formatRate(stat: RenderableRow[\"stats\"][number]): string {\n if (stat.evaluatedCount === 0) {\n return `0/${stat.totalReps} (all reps crashed)`;\n }\n const pct = (stat.passRate * 100).toFixed(0);\n return `${stat.passedCount}/${stat.evaluatedCount} (${pct}%)`;\n}\n","/**\n * JSON report formatter (passthrough).\n */\n\nimport type { SuiteReport } from \"../runner/types\";\n\n/**\n * Serialize a suite report as indented JSON (no transformation).\n *\n * Used by `--format json` and `--output` persistence.\n */\nexport function formatJson(report: SuiteReport): string {\n return JSON.stringify(report, null, 2);\n}\n","/**\n * Markdown (GFM) report formatter.\n */\n\nimport type { RenderableRow } from \"./types\";\n\n/** Render renderable rows as a GitHub-flavored markdown report. */\nexport function formatMarkdown(rows: RenderableRow[]): string {\n const lines: string[] = [\"# Harness Eval Report\", \"\"];\n\n for (const row of rows) {\n const status = row.passed ? \"PASS\" : \"FAIL\";\n const crashNote =\n row.adapterErrors > 0 ? ` (${row.adapterErrors} adapter errors)` : \"\";\n\n lines.push(`## ${row.caseId} @ ${row.cellLabel} — ${status}${crashNote}`);\n if (row.category) lines.push(`**Category:** ${row.category}`);\n if (row.notes) {\n lines.push(\"<details><summary>Notes</summary>\", row.notes, \"</details>\");\n }\n lines.push(\"\");\n lines.push(\"| Assertion | Result | Threshold | Status |\");\n lines.push(\"| --- | --- | --- | --- |\");\n\n for (const stat of row.stats) {\n const rateStr = formatRate(stat);\n const threshold = `${(stat.threshold * 100).toFixed(0)}%`;\n const statusCell = stat.meetsThreshold ? \"✓\" : \"✗\";\n let result = rateStr;\n if (stat.delta !== undefined && stat.baselinePassRate !== undefined) {\n const base = (stat.baselinePassRate * 100).toFixed(0);\n const cur = (stat.passRate * 100).toFixed(0);\n const d = (stat.delta * 100).toFixed(0);\n const sign = stat.delta >= 0 ? \"+\" : \"\";\n result += ` (${base}% → ${cur}%, ${sign}${d}%)`;\n }\n lines.push(`| ${stat.description} | ${result} | ${threshold} | ${statusCell} |`);\n }\n lines.push(\"\");\n }\n\n return lines.join(\"\\n\").trimEnd();\n}\n\n/** Format pass rate for markdown tables, noting when all reps crashed. */\nfunction formatRate(stat: RenderableRow[\"stats\"][number]): string {\n if (stat.evaluatedCount === 0) {\n return `0/${stat.totalReps} (all reps crashed)`;\n }\n const pct = (stat.passRate * 100).toFixed(0);\n return `${stat.passedCount}/${stat.evaluatedCount} (${pct}%)`;\n}\n","/**\n * SuiteReport → RenderableRow[] intermediate model.\n */\n\nimport type { CellReport, SuiteReport } from \"../runner/types\";\nimport type { RenderableRow, RenderableStat } from \"./types\";\n\n/** Map a suite report to formatter-ready rows (one per cell). */\nexport function toRenderableRows(report: SuiteReport): RenderableRow[] {\n return report.cells.map((cell) => cellToRow(cell));\n}\n\n/**\n * Attach baseline pass-rate deltas to matching rows.\n *\n * Rows without a matching baseline cell are returned unchanged.\n */\nexport function applyBaseline(\n rows: RenderableRow[],\n baseline: SuiteReport,\n): RenderableRow[] {\n const baselineMap = new Map(\n baseline.cells.map((c) => [`${c.caseId}::${c.cell.label}`, c]),\n );\n\n return rows.map((row) => {\n const baseCell = baselineMap.get(`${row.caseId}::${row.cellLabel}`);\n if (!baseCell) return row;\n\n const stats = row.stats.map((stat, i) => {\n const baseStat = baseCell.assertionStats[i];\n if (!baseStat) return stat;\n const delta = stat.passRate - baseStat.passRate;\n return {\n ...stat,\n baselinePassRate: baseStat.passRate,\n delta,\n };\n });\n\n return { ...row, stats };\n });\n}\n\n/** Convert one {@link CellReport} to a {@link RenderableRow}. */\nfunction cellToRow(cell: CellReport): RenderableRow {\n const totalReps = cell.repetitions.length;\n\n const stats: RenderableStat[] = cell.assertionStats.map((s) => ({\n description: s.description,\n threshold: s.threshold,\n passedCount: s.passedCount,\n evaluatedCount: s.evaluatedCount,\n totalReps,\n adapterErrors: cell.adapterErrors,\n passRate: s.passRate,\n meetsThreshold: s.meetsThreshold,\n }));\n\n return {\n caseId: cell.caseId,\n category: cell.category,\n notes: cell.notes,\n cellLabel: cell.cell.label,\n passed: cell.passed,\n adapterErrors: cell.adapterErrors,\n totalReps,\n stats,\n };\n}\n","/**\n * Reporter public API.\n */\n\nimport type { SuiteReport } from \"../runner/types\";\nimport { formatConsole } from \"./format-console\";\nimport { formatJson } from \"./format-json\";\nimport { formatMarkdown } from \"./format-markdown\";\nimport { applyBaseline, toRenderableRows } from \"./renderable\";\nimport type { ReporterOptions } from \"./types\";\n\nexport type { ReporterOptions, ReportFormat, RenderableRow } from \"./types\";\n\n/**\n * Format a {@link SuiteReport} for console, markdown, or JSON output.\n *\n * JSON format bypasses the renderable intermediate model and serializes the\n * report directly. Console and markdown apply optional baseline deltas.\n */\nexport function formatReport(\n report: SuiteReport,\n options: ReporterOptions,\n): string {\n if (options.format === \"json\") {\n return formatJson(report);\n }\n\n let rows = toRenderableRows(report);\n if (options.baseline) {\n rows = applyBaseline(rows, options.baseline);\n }\n\n const useColor =\n options.color ?? (options.format === \"console\");\n\n if (options.format === \"markdown\") {\n return formatMarkdown(rows);\n }\n\n return formatConsole(rows, useColor);\n}\n"],"mappings":"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"}
|
package/dist/runner/suite.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as runSuite } from "../suite-
|
|
1
|
+
import { t as runSuite } from "../suite-BEShV0by.js";
|
|
2
2
|
export { runSuite };
|
package/dist/runner/suite.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as runSuite } from "../suite-
|
|
1
|
+
import { t as runSuite } from "../suite-BcP64nlb.js";
|
|
2
2
|
export { runSuite };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { c as RunSuiteOptions, d as TestSuite, l as SuiteReport } from "./types-
|
|
1
|
+
import { c as RunSuiteOptions, d as TestSuite, l as SuiteReport } from "./types-0QkNVyp9.js";
|
|
2
2
|
|
|
3
3
|
//#region src/runner/suite.d.ts
|
|
4
4
|
/**
|
|
@@ -9,4 +9,4 @@ import { c as RunSuiteOptions, d as TestSuite, l as SuiteReport } from "./types-
|
|
|
9
9
|
declare function runSuite(suite: TestSuite, options?: RunSuiteOptions): Promise<SuiteReport>;
|
|
10
10
|
//#endregion
|
|
11
11
|
export { runSuite as t };
|
|
12
|
-
//# sourceMappingURL=suite-
|
|
12
|
+
//# sourceMappingURL=suite-BEShV0by.d.ts.map
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { t as claudeCodeAdapter } from "./claude-code-
|
|
1
|
+
import { t as claudeCodeAdapter } from "./claude-code-C_7hxC8z.js";
|
|
2
2
|
import { n as parseCardinality, t as describeCardinality } from "./cardinality-DlE44e-4.js";
|
|
3
|
+
import { t as codexAdapter } from "./codex-0cHO2te9.js";
|
|
3
4
|
//#region src/assertions/patterns.ts
|
|
4
5
|
/**
|
|
5
6
|
* Test whether a fully-qualified tool name matches a pattern.
|
|
@@ -460,6 +461,7 @@ function registerBuiltIn(id, adapter) {
|
|
|
460
461
|
ADAPTERS[id] = adapter;
|
|
461
462
|
}
|
|
462
463
|
registerBuiltIn("claude-code", claudeCodeAdapter);
|
|
464
|
+
registerBuiltIn("codex", codexAdapter);
|
|
463
465
|
/**
|
|
464
466
|
* Register a harness adapter by id.
|
|
465
467
|
*
|
|
@@ -505,12 +507,24 @@ function toClaudeCodeConfig(layers, prompt) {
|
|
|
505
507
|
merged.prompt = prompt;
|
|
506
508
|
return merged;
|
|
507
509
|
}
|
|
510
|
+
/** Merge generic suite config layers into a flat {@link CodexAdapterConfig}. */
|
|
511
|
+
function toCodexConfig(layers, prompt) {
|
|
512
|
+
const merged = {};
|
|
513
|
+
for (const layer of layers) {
|
|
514
|
+
const { codex, ...generic } = layer;
|
|
515
|
+
Object.assign(merged, generic);
|
|
516
|
+
if (codex && typeof codex === "object") Object.assign(merged, codex);
|
|
517
|
+
}
|
|
518
|
+
merged.prompt = prompt;
|
|
519
|
+
return merged;
|
|
520
|
+
}
|
|
508
521
|
/**
|
|
509
522
|
* Resolve merged suite layers into the flat config shape expected by the
|
|
510
523
|
* selected harness adapter.
|
|
511
524
|
*/
|
|
512
525
|
function resolveRunConfig(adapterId, layers, prompt) {
|
|
513
526
|
if (adapterId === "claude-code" || adapterId === "claude-code") return toClaudeCodeConfig(layers, prompt);
|
|
527
|
+
if (adapterId === "codex") return toCodexConfig(layers, prompt);
|
|
514
528
|
const merged = {};
|
|
515
529
|
for (const layer of layers) Object.assign(merged, layer);
|
|
516
530
|
merged.prompt = prompt;
|
|
@@ -735,4 +749,4 @@ async function runSuite(suite, options = {}) {
|
|
|
735
749
|
//#endregion
|
|
736
750
|
export { aggregateCell as a, runRepetition as c, getDefaultAdapter as d, listAdapters as f, evaluateAll as h, DEFAULT_THRESHOLD as i, DEFAULT_ADAPTER_ID as l, evaluate as m, createLimit as n, getRepetitions as o, registerAdapter as p, DEFAULT_REPETITIONS as r, mergeConfig as s, runSuite as t, getAdapter as u };
|
|
737
751
|
|
|
738
|
-
//# sourceMappingURL=suite-
|
|
752
|
+
//# sourceMappingURL=suite-BcP64nlb.js.map
|