@tangle-network/agent-eval 0.62.0 → 0.63.0

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/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/run-score.ts","../src/run-critic.ts","../src/semantic-concept-judge.ts","../src/analyst/types.ts","../src/analyst/adapters.ts","../src/analyst/chat-client.ts","../src/analyst/finding-signature.ts","../src/analyst/finding-subject.ts","../src/analyst/findings-store.ts","../src/locked-jsonl-appender.ts","../src/concurrency.ts","../src/analyst/kind-factory.ts","../src/analyst/tool-groups.ts","../src/analyst/kinds/failure-mode.ts","../src/analyst/kinds/improvement.ts","../src/analyst/kinds/knowledge-gap.ts","../src/analyst/kinds/knowledge-poisoning.ts","../src/analyst/kinds/index.ts","../src/analyst/kinds/skill-usage.ts","../src/analyst/registry.ts","../src/auto-pr.ts","../src/executor.ts","../src/benchmark.ts","../src/client.ts","../src/convergence.ts","../src/metrics.ts","../src/driver.ts","../src/feedback-trajectory.ts","../src/integrity/single-backend.ts","../src/judge-families.ts","../src/judges.ts","../src/live-proof.ts","../src/pr-review-benchmark.ts","../src/registry.ts","../src/reporter.ts","../src/anti-slop.ts","../src/artifact-validator.ts","../src/completion-verifier.ts","../src/dual-agent-bench.ts","../src/experiment-tracker.ts","../src/experiment-tracker-d1.ts","../src/experiment-tracker-fs.ts","../src/pareto.ts","../src/harness-optimizer.ts","../src/judge-runner.ts","../src/playbook.ts","../src/produced-state.ts","../src/prompt-registry.ts","../src/steering.ts","../src/steering-optimizer.ts","../src/workspace-inspector.ts","../src/budget-guard.ts","../src/cost-tracker.ts","../src/muffled-gate-scanner.ts","../src/oracle.ts","../src/scorecard.ts","../src/series-convergence.ts","../src/slo.ts","../src/state-continuity.ts","../src/behavior-dsl.ts","../src/ci-gate.ts","../src/observability.ts","../src/paraphrase.ts","../src/visual-diff.ts","../src/bisector.ts","../src/counterfactual.ts","../src/cross-trace-diff.ts","../src/active-learning.ts","../src/causal-attribution.ts","../src/reward-model-export.ts","../src/self-play.ts","../src/command-runner.ts","../src/deploy-gate-layer.ts","../src/error-count-extractor.ts","../src/flow-layer.ts","../src/intent-match-judge.ts","../src/keyword-coverage-judge.ts","../src/multi-layer-verifier.ts","../src/multi-toolchain-layer.ts","../src/reference-replay.ts","../src/reviewer.ts","../src/discover-personas.ts","../src/golden-matcher.ts","../src/held-out-gate.ts","../src/judge-retry.ts","../src/orthogonality.ts","../src/reference-replay-steering.ts","../src/researcher.ts","../src/sandbox-pool.ts","../src/otel-pipeline.ts","../src/traced-analyst.ts","../src/traced-judges.ts"],"sourcesContent":["export interface RunScore {\n success: number\n goalProgress: number\n repoGroundedness: number\n driftPenalty: number\n toolUseQuality: number\n patchQuality: number\n testReality: number\n finalGate: number\n reviewerBlockers: number\n costUsd: number\n wallSeconds: number\n notes?: string[]\n}\n\nexport interface RunScoreWeights {\n success: number\n goalProgress: number\n repoGroundedness: number\n driftPenalty: number\n toolUseQuality: number\n patchQuality: number\n testReality: number\n finalGate: number\n reviewerBlockers: number\n costUsd: number\n wallSeconds: number\n}\n\nexport const DEFAULT_RUN_SCORE_WEIGHTS: RunScoreWeights = {\n success: 4,\n goalProgress: 2,\n repoGroundedness: 1.5,\n driftPenalty: -1.5,\n toolUseQuality: 1,\n patchQuality: 1.25,\n testReality: 1.5,\n finalGate: 3,\n reviewerBlockers: -2,\n costUsd: -0.2,\n wallSeconds: -0.1,\n}\n\nexport function aggregateRunScore(score: RunScore, weights: Partial<RunScoreWeights> = {}): number {\n const w = { ...DEFAULT_RUN_SCORE_WEIGHTS, ...weights }\n return (\n w.success * clamp01(score.success) +\n w.goalProgress * clamp01(score.goalProgress) +\n w.repoGroundedness * clamp01(score.repoGroundedness) +\n w.driftPenalty * clamp01(score.driftPenalty) +\n w.toolUseQuality * clamp01(score.toolUseQuality) +\n w.patchQuality * clamp01(score.patchQuality) +\n w.testReality * clamp01(score.testReality) +\n w.finalGate * clamp01(score.finalGate) +\n w.reviewerBlockers * clamp01(score.reviewerBlockers) +\n w.costUsd * Math.max(0, finiteOrZero(score.costUsd)) +\n w.wallSeconds * Math.max(0, finiteOrZero(score.wallSeconds) / 60)\n )\n}\n\nexport function clamp01(value: number): number {\n if (!Number.isFinite(value)) return 0\n return Math.max(0, Math.min(1, value))\n}\n\nfunction finiteOrZero(value: number): number {\n return Number.isFinite(value) ? value : 0\n}\n","import { NotFoundError } from './errors'\nimport { aggregateRunScore, clamp01, type RunScore, type RunScoreWeights } from './run-score'\nimport type { Artifact, BudgetLedgerEntry, Run, Span, TraceEvent, TraceStore } from './trace'\n\nexport interface RunTrace {\n run: Run\n spans: Span[]\n events: TraceEvent[]\n artifacts: Artifact[]\n budget: BudgetLedgerEntry[]\n}\n\nexport interface RunCriticOptions {\n weights?: Partial<RunScoreWeights>\n driftPatterns?: RegExp[]\n}\n\nconst DEFAULT_DRIFT_PATTERNS = [\n /https?:\\/\\//i,\n /\\btitle:\\s/i,\n /\\bsummary:\\s/i,\n /\\burl:\\s/i,\n /\\bnpm package usage\\b/i,\n /\\bnews\\b/i,\n]\n\nexport class RunCritic {\n private readonly weights?: Partial<RunScoreWeights>\n private readonly driftPatterns: RegExp[]\n\n constructor(options: RunCriticOptions = {}) {\n this.weights = options.weights\n this.driftPatterns = options.driftPatterns ?? DEFAULT_DRIFT_PATTERNS\n }\n\n async score(store: TraceStore, runId: string): Promise<RunScore> {\n const run = await store.getRun(runId)\n if (!run) throw new NotFoundError(`run ${runId} not found`)\n const [spans, events, artifacts, budget] = await Promise.all([\n store.spans({ runId }),\n store.events({ runId }),\n store.artifacts(runId),\n store.budget(runId),\n ])\n return this.scoreTrace({ run, spans, events, artifacts, budget })\n }\n\n scoreTrace(trace: RunTrace): RunScore {\n const notes: string[] = []\n const llmSpans = trace.spans.filter(\n (s): s is Extract<Span, { kind: 'llm' }> => s.kind === 'llm',\n )\n const toolSpans = trace.spans.filter(\n (s): s is Extract<Span, { kind: 'tool' }> => s.kind === 'tool',\n )\n const judgeSpans = trace.spans.filter(\n (s): s is Extract<Span, { kind: 'judge' }> => s.kind === 'judge',\n )\n const sandboxSpans = trace.spans.filter(\n (s): s is Extract<Span, { kind: 'sandbox' }> => s.kind === 'sandbox',\n )\n const finalGateSpans = judgeSpans.filter(\n (span) => span.dimension === 'final_gate' || span.attributes?.finalGate === true,\n )\n\n const success =\n trace.run.outcome?.pass === true ? 1 : trace.run.status === 'completed' ? 0.5 : 0\n if (!success) notes.push('run did not complete with pass=true')\n\n const judgeAverage = judgeSpans.length\n ? judgeSpans.reduce((sum, span) => sum + normalizeJudgeScore(span.score), 0) /\n judgeSpans.length\n : undefined\n const outcomeScore =\n typeof trace.run.outcome?.score === 'number'\n ? clamp01(\n trace.run.outcome.score > 1 ? trace.run.outcome.score / 100 : trace.run.outcome.score,\n )\n : undefined\n const goalProgress = outcomeScore ?? judgeAverage ?? success\n\n const successfulTools = toolSpans.filter((span) => span.status !== 'error').length\n const toolUseQuality = toolSpans.length === 0 ? 0 : successfulTools / toolSpans.length\n if (toolSpans.length === 0) notes.push('no tool spans recorded')\n\n const patchEvidence =\n trace.artifacts.length +\n toolSpans.filter((span) => /write|edit|patch|apply/i.test(span.toolName)).length\n const patchQuality = patchEvidence > 0 ? clamp01(patchEvidence / 4) : 0\n if (!patchQuality) notes.push('no artifact or edit evidence recorded')\n\n const sandboxTests = sandboxSpans.filter(\n (span) => typeof span.testsTotal === 'number' && span.testsTotal > 0,\n )\n const testReality = sandboxTests.length\n ? sandboxTests.reduce(\n (sum, span) => sum + (span.testsPassed ?? 0) / Math.max(1, span.testsTotal ?? 1),\n 0,\n ) / sandboxTests.length\n : toolSpans.some((span) =>\n /\\btest|vitest|pytest|jest|build|tsc\\b/i.test(JSON.stringify(span.args)),\n )\n ? 0.4\n : 0\n if (!testReality) notes.push('no real test/build evidence recorded')\n\n const blockerSpans = judgeSpans.filter((span) => isBlockingJudge(span))\n const finalGateBlockers = finalGateSpans.filter((span) => isBlockingJudge(span))\n const finalGate = finalGateSpans.length ? (finalGateBlockers.length ? 0 : 1) : success\n if (finalGateBlockers.length)\n notes.push(`final gate blocked by ${finalGateBlockers.length} reviewer(s)`)\n else if (!finalGateSpans.length) notes.push('no final gate judgment recorded')\n\n const reviewerBlockers = judgeSpans.length ? blockerSpans.length / judgeSpans.length : 0\n if (reviewerBlockers) notes.push(`detected ${blockerSpans.length} blocking reviewer signal(s)`)\n\n const positiveGroundingSignals =\n patchEvidence +\n sandboxSpans.length +\n llmSpans.filter((span) => looksRepoGrounded(span.output ?? '')).length\n const driftSignals =\n llmSpans.filter((span) => this.isDrift(span.output ?? '')).length +\n trace.events.filter((event) => this.isDrift(JSON.stringify(event.payload))).length\n const repoGroundedness =\n positiveGroundingSignals + driftSignals === 0\n ? 0\n : positiveGroundingSignals / (positiveGroundingSignals + driftSignals)\n const driftPenalty =\n positiveGroundingSignals + driftSignals === 0\n ? 0\n : driftSignals / (positiveGroundingSignals + driftSignals)\n if (driftSignals > 0) notes.push(`detected ${driftSignals} drift signal(s)`)\n\n const costUsd = trace.budget.length\n ? Math.max(\n ...trace.budget\n .filter((entry: BudgetLedgerEntry) => entry.dimension === 'usd')\n .map((entry: BudgetLedgerEntry) => entry.consumed),\n 0,\n )\n : llmSpans.reduce((sum, span) => sum + (span.costUsd ?? 0), 0)\n const wallSeconds =\n trace.run.endedAt && trace.run.startedAt\n ? Math.max(0, (trace.run.endedAt - trace.run.startedAt) / 1000)\n : 0\n\n return {\n success,\n goalProgress,\n repoGroundedness,\n driftPenalty,\n toolUseQuality,\n patchQuality,\n testReality,\n finalGate,\n reviewerBlockers,\n costUsd,\n wallSeconds,\n notes,\n }\n }\n\n rank(score: RunScore): number {\n return aggregateRunScore(score, this.weights)\n }\n\n private isDrift(text: string): boolean {\n return this.driftPatterns.some((pattern) => pattern.test(text))\n }\n}\n\nfunction normalizeJudgeScore(score: number): number {\n return score > 1 ? clamp01(score / 10) : clamp01(score)\n}\n\nfunction looksRepoGrounded(text: string): boolean {\n return /(?:src\\/|tests?\\/|package\\.json|tsconfig|\\.ts\\b|\\.tsx\\b|git status|pnpm |npm |vitest|pytest|jest)/i.test(\n text,\n )\n}\n\nfunction isBlockingJudge(span: Extract<Span, { kind: 'judge' }>): boolean {\n return (\n span.attributes?.blocking === true ||\n span.attributes?.verdict === 'BLOCKING' ||\n positiveNumber(span.attributes?.blockingFindings) ||\n positiveNumber(span.attributes?.highFindings) ||\n span.score <= 2\n )\n}\n\nfunction positiveNumber(value: unknown): boolean {\n return typeof value === 'number' && value > 0\n}\n","/**\n * Semantic concept judge — \"does the built artifact actually implement\n * the features the user asked for?\"\n *\n * Distinct from the domain/code/coherence judges in `judges.ts`:\n * - those judges score free-form conversational agent outputs along\n * quality dimensions (accuracy, depth, etc.)\n * - this judge scores a *built artifact* (served HTML + source files)\n * against an explicit list of expected concepts, returning per-concept\n * {present, score 0-10, evidence, severity}.\n *\n * The judge is strict about distinguishing (a) a working implementation\n * from (b) a keyword-present stub. \"// TODO: mint button\" is NOT present.\n * Only real, functional, wired-up code counts.\n *\n * Use via {@link createSemanticConceptJudge} or directly via\n * {@link runSemanticConceptJudge}. Soft-fails (available=false) on LLM\n * or JSON-parse errors so the caller can treat that as \"layer skipped\"\n * rather than \"layer failed\" in a multi-layer pipeline.\n */\n\nimport { callLlmJson, type LlmClientOptions } from './llm-client'\nimport type { Severity } from './multi-layer-verifier'\n\n// ─── Types ──────────────────────────────────────────────────────────────\n\n/**\n * Implementation complexity class for weighted scoring.\n *\n * - `render` (default): the concept is a UI surface that displays static\n * data — render a list, show a counter, lay out a button. Single-file\n * work, no external integration.\n * - `integrate`: the concept requires wiring a real external system —\n * wallet connect (wagmi + RainbowKit + chain config), payment provider\n * (Stripe Elements + intent + webhook), an API client with auth.\n * Multi-file, library-knowledge, runtime correctness matters.\n * - `compute`: the concept requires algorithmic work — solver, simulator,\n * constraint propagation, ML inference. Correctness > UI polish.\n *\n * Default weights (when applied via `weightConcepts: 'complexity'`):\n * render=1.0, integrate=2.0, compute=2.5\n *\n * Cross-vertical scoring without complexity weighting silently inflates\n * the rate of UI-heavy verticals (healthcare, fintech dashboards) vs\n * integration-heavy verticals (DeFi, wallets) — all concepts treated\n * equally even though the agent does 2-3x the work for `integrate`.\n */\nexport type ConceptComplexity = 'render' | 'integrate' | 'compute'\n\nexport interface ConceptSpec {\n name: string\n /** Short hints that help the judge; not used for matching. */\n keywords?: string[]\n /** Optional explicit weight; default 1.0. Overrides complexity-derived weight. */\n weight?: number\n /** Implementation complexity class. Default `render`. */\n complexity?: ConceptComplexity\n}\n\nexport interface ConceptFinding {\n concept: string\n present: boolean\n /** 0..10. 10 = production-ready; 7 = functional thin; 4 = partial; 0 = absent. */\n score: number\n evidence: string\n severity: Severity\n}\n\nexport interface SemanticConceptJudgeInput {\n /** Full natural-language prompt the agent was handed. */\n userRequest: string\n /** Rendered HTML the preview returns (UI artifacts). Optional. */\n servedHtml?: string\n /** Top-level source files from the agent's workdir. */\n sourceFiles: Array<{ path: string; content: string }>\n /** The expected concept list. */\n expectedConcepts: ConceptSpec[]\n /** Free-form metadata (id, difficulty) to inject into the prompt. */\n artifactLabel?: string\n artifactDescription?: string\n}\n\nexport interface SemanticConceptJudgeResult {\n kind: 'semantic-concept'\n version: string\n /** Normalized 0..1 score — mean of per-concept scores / 10. */\n score: number\n presentCount: number\n totalCount: number\n findings: ConceptFinding[]\n summary: string\n durationMs: number\n costUsd: number | null\n /** False on LLM/JSON error — treat as \"skipped / unable to judge\" in pipelines. */\n available: boolean\n error?: string\n}\n\n/**\n * Score-aggregation strategy. `mean` averages 0-10 scores uniformly.\n * `complexity` applies the default weight table (render=1, integrate=2,\n * compute=2.5) unless a concept has an explicit `weight`. `explicit`\n * honors only `weight` (defaulting to 1 for unspecified).\n */\nexport type ConceptWeightStrategy = 'mean' | 'complexity' | 'explicit'\n\nexport const DEFAULT_COMPLEXITY_WEIGHTS: Record<ConceptComplexity, number> = {\n render: 1.0,\n integrate: 2.0,\n compute: 2.5,\n}\n\nexport interface SemanticConceptJudgeOptions {\n /** Model id to call. Default 'claude-sonnet-4-6' via agent-eval defaults. */\n model?: string\n /** Per-call timeout. Default 180s. */\n timeoutMs?: number\n /** Pipeline budget for the prompt (source blob truncation). Default 45000. */\n maxSourceChars?: number\n /** Per-file cap before inclusion. Default 20000. */\n maxPerFileChars?: number\n /** HTML cap. Default 30000. */\n maxHtmlChars?: number\n /** LlmClient config (baseUrl, apiKey, authHeader, …). */\n llm?: LlmClientOptions\n /**\n * Score aggregation strategy. Default `mean` — uniform average across\n * concepts. Cross-vertical comparisons should use `complexity` to\n * neutralize the integrate-vs-render asymmetry.\n */\n weightConcepts?: ConceptWeightStrategy\n /** Override the default complexity → weight table. */\n complexityWeights?: Partial<Record<ConceptComplexity, number>>\n}\n\n// ─── Prompt assembly ────────────────────────────────────────────────────\n\nexport const SEMANTIC_CONCEPT_JUDGE_VERSION = 'semantic-concept-judge-v1-2026-04-24'\n\nconst DEFAULT_MAX_SOURCE = 45_000\nconst DEFAULT_MAX_HTML = 30_000\nconst DEFAULT_MAX_PER_FILE = 20_000\nconst DEFAULT_TIMEOUT = 180_000\nconst DEFAULT_MODEL = 'claude-sonnet-4-6'\n\nconst SEMANTIC_SCHEMA = {\n type: 'object',\n additionalProperties: false,\n required: ['summary', 'concepts'],\n properties: {\n summary: { type: 'string', minLength: 20, maxLength: 600 },\n concepts: {\n type: 'array',\n minItems: 1,\n items: {\n type: 'object',\n additionalProperties: false,\n required: ['concept', 'present', 'score', 'evidence', 'severity'],\n properties: {\n concept: { type: 'string', minLength: 1, maxLength: 120 },\n present: { type: 'boolean' },\n score: { type: 'number', minimum: 0, maximum: 10 },\n evidence: { type: 'string', minLength: 5, maxLength: 400 },\n severity: { type: 'string', enum: ['critical', 'major', 'minor', 'info'] },\n },\n },\n },\n },\n}\n\nfunction truncate(body: string, cap: number, label: string): string {\n if (body.length <= cap) return body\n return `${body.slice(0, cap)}\\n… [truncated ${body.length - cap} chars of ${label}]`\n}\n\nfunction buildPrompt(\n input: SemanticConceptJudgeInput,\n opts: Required<SemanticConceptJudgeOptions>,\n): string {\n const sourceBlob = input.sourceFiles\n .filter((f) => f.content.length <= opts.maxPerFileChars)\n .map((f) => `--- FILE: ${f.path} ---\\n${f.content}`)\n .join('\\n\\n')\n\n const html = input.servedHtml ?? ''\n\n return `You are a strict code-review judge evaluating whether an agent's 0-to-1 build actually implements the features the user asked for.\n\nYou MUST distinguish:\n (a) WORKING code that implements the concept (rendered UI, wired handler, real API call),\n (b) KEYWORD-PRESENT stub (comments mentioning the concept, variable names, TODOs),\n (c) ABSENT (concept nowhere).\n\nA comment like \"// TODO: add mint button\" is NOT present — score 2-3. Only count a concept as present if there is real functional code: a rendered component, a call handler wired to state or a network call, a computed value actually used.\n\nUSER REQUEST (what the agent was asked to build):\n${input.userRequest}\n\n${input.artifactLabel ? `ARTIFACT METADATA:\\n name: ${input.artifactLabel}\\n description: ${input.artifactDescription ?? ''}\\n\\n` : ''}EXPECTED CONCEPTS (each must be graded independently):\n${input.expectedConcepts\n .map(\n (c, i) =>\n ` ${i + 1}. \"${c.name}\"${c.keywords?.length ? ` — hints: [${c.keywords.slice(0, 6).join(' | ')}]` : ''}`,\n )\n .join('\\n')}\n\n${html ? `SERVED HTML (what the preview returns when hit):\\n${truncate(html, opts.maxHtmlChars, 'HTML')}\\n\\n` : ''}SOURCE FILES (the agent's workdir):\n${truncate(sourceBlob, opts.maxSourceChars, 'source')}\n\nFor EACH concept, return:\n - concept: the concept name as given (match exactly)\n - present: boolean — does a working implementation exist?\n - score: 0-10 — 10 = production-ready; 7 = functional but thin; 4 = partial/stubbed; 2 = keyword-only comment; 0 = absent\n - evidence: cite \"<file>:<line>\" or \"served-html:<selector>\" pointing at the strongest supporting code. If the concept is absent or stubbed, explain what's missing.\n - severity:\n \"info\" when present: true AND score >= 7\n \"minor\" when present: true AND 4 <= score < 7\n \"major\" when present: false OR score < 4\n \"critical\" when the concept is not only absent but a core user flow depends on it\n\nAlso produce a \"summary\" (one sentence, 20-600 chars): overall verdict on whether this is a shippable implementation of the user request vs a keyword-dense placeholder.\n\nBE SKEPTICAL. Keyword matching already passed — your job is to catch what keyword matching misses. If the agent shipped a working build, say so. If it shipped a stub, say so. Don't grade on effort.\n\nReturn STRICT JSON. No prose outside the JSON.`\n}\n\n// ─── Runner ─────────────────────────────────────────────────────────────\n\n/**\n * Run the semantic concept judge. Soft-fails to available=false on\n * LLM/JSON errors — callers in a MultiLayerVerifier pipeline can treat\n * that as \"skip\" rather than \"fail.\"\n */\nexport async function runSemanticConceptJudge(\n input: SemanticConceptJudgeInput,\n options: SemanticConceptJudgeOptions = {},\n): Promise<SemanticConceptJudgeResult> {\n const start = Date.now()\n const totalCount = input.expectedConcepts.length\n\n if (totalCount === 0) {\n return {\n kind: 'semantic-concept',\n version: SEMANTIC_CONCEPT_JUDGE_VERSION,\n score: 0,\n presentCount: 0,\n totalCount: 0,\n findings: [],\n summary: 'no expected concepts declared',\n durationMs: 0,\n costUsd: null,\n available: false,\n error: 'no expected concepts declared',\n }\n }\n\n const opts: Required<SemanticConceptJudgeOptions> = {\n model: options.model ?? DEFAULT_MODEL,\n timeoutMs: options.timeoutMs ?? DEFAULT_TIMEOUT,\n maxSourceChars: options.maxSourceChars ?? DEFAULT_MAX_SOURCE,\n maxPerFileChars: options.maxPerFileChars ?? DEFAULT_MAX_PER_FILE,\n maxHtmlChars: options.maxHtmlChars ?? DEFAULT_MAX_HTML,\n llm: options.llm ?? {},\n weightConcepts: options.weightConcepts ?? 'mean',\n complexityWeights: { ...DEFAULT_COMPLEXITY_WEIGHTS, ...(options.complexityWeights ?? {}) },\n }\n\n // Build a name → weight map for aggregation. Mean strategy keeps every\n // weight at 1 (uniform average). Complexity strategy reads the table\n // and lets an explicit `weight` override. Explicit strategy uses ONLY\n // the spec's `weight` (defaulting to 1).\n const weightForConcept = (spec: ConceptSpec): number => {\n if (opts.weightConcepts === 'mean') return 1\n if (spec.weight != null) return spec.weight\n if (opts.weightConcepts === 'complexity') {\n return opts.complexityWeights[spec.complexity ?? 'render'] ?? 1\n }\n return 1\n }\n const weightByName = new Map<string, number>(\n input.expectedConcepts.map((c) => [c.name, weightForConcept(c)]),\n )\n\n try {\n const { value, result } = await callLlmJson<{\n summary: string\n concepts: ConceptFinding[]\n }>(\n {\n model: opts.model,\n messages: [\n {\n role: 'system',\n content:\n 'You are a strict code-review judge. Return strict JSON only. No prose outside the JSON. A keyword in a comment is NOT a working implementation.',\n },\n { role: 'user', content: buildPrompt(input, opts) },\n ],\n jsonSchema: { name: 'semantic_concept_judge', schema: SEMANTIC_SCHEMA },\n temperature: 0,\n timeoutMs: opts.timeoutMs,\n },\n opts.llm,\n )\n\n if (!value?.concepts || !Array.isArray(value.concepts)) {\n throw new Error('judge returned malformed response — expected array under \"concepts\"')\n }\n\n const findings: ConceptFinding[] = value.concepts.map((c) => ({\n concept: String(c.concept),\n present: Boolean(c.present),\n score: Math.max(0, Math.min(10, Number(c.score ?? 0))),\n evidence: String(c.evidence ?? ''),\n severity: (['critical', 'major', 'minor', 'info'] as const).includes(c.severity)\n ? c.severity\n : 'info',\n }))\n\n const presentCount = findings.filter((f) => f.present && f.score >= 7).length\n let weightSum = 0\n let weightedScoreSum = 0\n for (const f of findings) {\n const w = weightByName.get(f.concept) ?? 1\n weightSum += w\n weightedScoreSum += w * f.score\n }\n const scoreAvg =\n weightSum > 0\n ? weightedScoreSum / weightSum\n : findings.reduce((a, f) => a + f.score, 0) / Math.max(1, findings.length)\n\n return {\n kind: 'semantic-concept',\n version: SEMANTIC_CONCEPT_JUDGE_VERSION,\n score: Number((scoreAvg / 10).toFixed(3)),\n presentCount,\n totalCount,\n findings,\n summary: String(value.summary ?? ''),\n durationMs: Date.now() - start,\n costUsd: result.costUsd ?? null,\n available: true,\n }\n } catch (err) {\n return {\n kind: 'semantic-concept',\n version: SEMANTIC_CONCEPT_JUDGE_VERSION,\n score: 0,\n presentCount: 0,\n totalCount,\n findings: [],\n summary: '',\n durationMs: Date.now() - start,\n costUsd: null,\n available: false,\n error: err instanceof Error ? err.message : String(err),\n }\n }\n}\n\n/**\n * Factory: pin LLM options once, return a closure that accepts inputs.\n * Convenient for pipelines that want to share a single LlmClient config.\n */\nexport function createSemanticConceptJudge(\n options: SemanticConceptJudgeOptions = {},\n): (input: SemanticConceptJudgeInput) => Promise<SemanticConceptJudgeResult> {\n return (input) => runSemanticConceptJudge(input, options)\n}\n","/**\n * Analyst contract — the missing orchestration layer over agent-eval's\n * existing analyzers (analyzeTraces, MultiLayerVerifier, RunCritic,\n * SemanticConceptJudge, JudgeFn, ...).\n *\n * Each existing primitive returns its own output shape. The Analyst\n * contract is the single envelope every primitive lifts into, so a\n * registry can run N analysts against a run and a single renderer can\n * compose findings without knowing which analyzer produced them.\n *\n * The contract is intentionally domain-agnostic: nothing here knows\n * about code, voice, RAG, or any particular agent stack. Analysts\n * declare what INPUT KIND they need (a trace store, an artifact dir,\n * a RunRecord, a JudgeInput, or `custom`), and the registry routes\n * the matching input from `AnalystRunInputs`.\n */\n\nimport { createHash } from 'node:crypto'\nimport type { RunRecord } from '../run-record'\nimport type { TraceAnalysisStore } from '../trace-analyst/store'\nimport type { JudgeInput } from '../types'\nimport type { ChatClient } from './chat-client'\n\n/**\n * Unified envelope every analyst emits. Schema-versioned so renderers\n * and time-series diffs survive future field additions.\n */\nexport interface AnalystFinding {\n schema_version: '1.0.0'\n /**\n * Stable hash over identity-defining fields (analyst_id + canonical\n * claim + area + optional subject). Two findings from two runs that\n * \"are the same finding\" share this id — that's what `diffFindings`\n * uses to compute appeared/disappeared sets across runs.\n */\n finding_id: string\n analyst_id: string\n produced_at: string\n severity: AnalystSeverity\n /**\n * Coarse classification. Renderers group by this. Free-form so\n * domain-specific analysts can introduce categories without a\n * schema change ('agent-reasoning', 'verification', 'cost',\n * 'tool-use', 'safety', 'latency', 'data-quality', ...).\n */\n area: string\n claim: string\n rationale?: string\n evidence_refs: EvidenceRef[]\n recommended_action?: string\n validation_plan?: string\n /** 0..1 — the analyst's own confidence. Not calibrated across analysts. */\n confidence: number\n /**\n * Optional subject the finding is about — leaf id, agent id, request\n * id. Included in finding_id when present so per-subject findings\n * diff cleanly across runs.\n */\n subject?: string\n /** Analyst-private extras; renderers ignore unless they know the analyst. */\n metadata?: Record<string, unknown>\n}\n\nexport type AnalystSeverity = 'critical' | 'high' | 'medium' | 'low' | 'info'\n\nexport interface EvidenceRef {\n /**\n * Where the evidence lives. `span` and `event` refer to OTLP trace\n * elements; `artifact` to a file inside the run's artifact tree;\n * `finding` to another AnalystFinding (cross-analyst chaining);\n * `metric` to a named scalar reading the renderer knows how to read.\n */\n kind: 'span' | 'event' | 'artifact' | 'finding' | 'metric'\n uri: string\n excerpt?: string\n}\n\n// ── Analyst contract ─────────────────────────────────────────────────\n\n/**\n * The discriminator the registry uses to pass the right input.\n * `custom` is the escape hatch — analysts that need something else\n * (e.g. an embedding cache, a partner SDK handle) read it from\n * `AnalystRunInputs.custom[<analyst id>]`.\n */\nexport type AnalystInputKind =\n | 'trace-store'\n | 'artifact-dir'\n | 'run-record'\n | 'judge-input'\n | 'custom'\n\nexport interface AnalystCost {\n /** `deterministic` analysts MUST NOT call the LLM. */\n kind: 'deterministic' | 'llm'\n /** Optional declared upper bound; the registry can enforce a budget. */\n est_usd_per_run?: number\n /** Models the analyst expects to use (informational). */\n models?: string[]\n}\n\nexport interface AnalystRequirements {\n /** Min number of shots / samples the analyst needs to produce signal. */\n min_shots?: number\n /** Capabilities the runtime must supply (e.g. ['network', 'gpu']). */\n capabilities?: string[]\n}\n\n/**\n * What's passed to every analyst call. The registry resolves which\n * field the analyst's `inputKind` selects and asserts it's present.\n */\nexport interface AnalystRunInputs {\n traceStore?: TraceAnalysisStore\n artifactDir?: string\n runRecord?: RunRecord\n judgeInput?: JudgeInput\n /** Keyed by analyst id; populated by callers that registered custom analysts. */\n custom?: Record<string, unknown>\n}\n\nexport interface AnalystContext {\n runId: string\n /** Stable correlation id so logs from a single registry.run() share a tag. */\n correlationId: string\n /** Wall-clock deadline (epoch ms). Analysts SHOULD honor for graceful cancel. */\n deadlineMs?: number\n /** Per-analyst USD budget. Analysts MAY check before issuing LLM calls. */\n budgetUsd?: number\n /**\n * Shared chat client. Analysts that call an LLM go through this so\n * the operator picks transport (sandbox-sdk | router | cli-bridge |\n * direct-provider | mock) at the registry boundary without touching\n * analyst code.\n */\n chat?: ChatClient\n /**\n * Findings from a prior run the operator wants the analyst to see as\n * retrieval context. Kinds that take advantage of cross-run memory\n * (failure-mode \"I saw this cluster last run\", knowledge-gap \"the wiki\n * page I asked for is still missing\") render these into the actor's\n * working set. Filtering is the operator's job: pass the slice that\n * matches the analyst's id, or pass everything and let the kind\n * filter. Empty / absent means no cross-run context.\n */\n priorFindings?: ReadonlyArray<AnalystFinding>\n /** Free-form runtime tags (env, host, op). Findings can echo these into metadata. */\n tags?: Record<string, string>\n /** Logger callback — analysts SHOULD prefer this over console.* for testability. */\n log?: (msg: string, fields?: Record<string, unknown>) => void\n /** Optional abort signal. Analysts SHOULD pass it through to LLM calls. */\n signal?: AbortSignal\n}\n\n/**\n * The minimal contract. Concrete analysts can refine `TInput` so\n * implementations stay type-safe (e.g. a trace analyst's `TInput` is\n * `TraceAnalysisStore`); the registry passes the right field from\n * `AnalystRunInputs` based on `inputKind`.\n */\nexport interface Analyst<TInput = unknown> {\n /** Stable identifier — appears in finding_id, telemetry, and registry exclusion lists. */\n readonly id: string\n /** Human-readable. One sentence. */\n readonly description: string\n readonly inputKind: AnalystInputKind\n readonly cost: AnalystCost\n readonly requires?: AnalystRequirements\n /** Bump on breaking changes to claim wording or area so old finding_ids don't collide. */\n readonly version: string\n analyze(input: TInput, ctx: AnalystContext): Promise<AnalystFinding[]>\n}\n\n// ── finding_id stability ─────────────────────────────────────────────\n\n/**\n * Compute the stable finding_id from the identity-defining fields.\n * Default implementation hashes {analyst_id, area, subject, normalized claim}.\n * Analysts that emit findings whose claim text varies per run (timestamps,\n * counts) SHOULD either: (a) pass an explicit `id_basis` to fix the hash,\n * or (b) move the variable part into `rationale`/`metadata` and keep the\n * `claim` static.\n */\nexport function computeFindingId(input: {\n analyst_id: string\n area: string\n subject?: string\n claim: string\n /** Override the claim for hashing — use when the displayed claim has run-specific bits. */\n id_basis?: string\n}): string {\n const basis = JSON.stringify({\n a: input.analyst_id,\n r: input.area,\n s: input.subject ?? '',\n c: normalizeClaim(input.id_basis ?? input.claim),\n })\n return `f_${createHash('sha256').update(basis).digest('hex').slice(0, 20)}`\n}\n\nfunction normalizeClaim(c: string): string {\n // Lowercase, collapse whitespace, strip trailing punctuation. Goal:\n // \"Leaf X failed install\" and \"Leaf X failed install.\" hash the same.\n return c\n .toLowerCase()\n .replace(/\\s+/g, ' ')\n .replace(/[.!?;:,]+$/g, '')\n .trim()\n}\n\n/**\n * Convenience factory: produce a fully-formed AnalystFinding with the\n * id computed automatically. Analyst code stays terse.\n */\nexport function makeFinding(\n init: Omit<AnalystFinding, 'schema_version' | 'finding_id' | 'produced_at'> & {\n id_basis?: string\n produced_at?: string\n },\n): AnalystFinding {\n const { id_basis, produced_at, ...rest } = init\n return {\n schema_version: '1.0.0',\n finding_id: computeFindingId({\n analyst_id: rest.analyst_id,\n area: rest.area,\n subject: rest.subject,\n claim: rest.claim,\n id_basis,\n }),\n produced_at: produced_at ?? new Date().toISOString(),\n ...rest,\n }\n}\n\n// ── Registry result envelope ────────────────────────────────────────\n\nexport interface AnalystRunSummary {\n analyst_id: string\n status: 'ok' | 'skipped' | 'failed'\n /** Why skipped — missing input, budget exceeded, capability unmet. */\n reason?: string\n findings_count: number\n latency_ms: number\n cost_usd: number\n /** When `status='failed'`: the error class + message, never the full stack. */\n error?: { class: string; message: string }\n}\n\nexport interface AnalystRunResult {\n run_id: string\n correlation_id: string\n started_at: string\n ended_at: string\n findings: AnalystFinding[]\n per_analyst: AnalystRunSummary[]\n /** Total LLM cost in USD across all analysts in this registry.run(). */\n total_cost_usd: number\n}\n\n// ── Streaming event envelope ────────────────────────────────────────\n\n/**\n * Events emitted by `AnalystRegistry.runStream(...)` in real time as\n * the registry executes. UIs subscribe via `for await (const ev of\n * registry.runStream(...))`; `registry.run(...)` is a thin collector\n * over the same stream, so the two surfaces share their invariants.\n *\n * Per-finding events are intentionally omitted — analyzers are batch\n * operations (an Ax actor returns the full `findings:json[]` at the\n * end of the responder), so streaming inside one analyst would only\n * emit partial JSON consumers can't render. The kind-completion event\n * is the right granularity; subscribers wanting per-finding rendering\n * iterate `event.findings` themselves.\n */\nexport type AnalystRunEvent =\n | {\n type: 'run-started'\n run_id: string\n correlation_id: string\n started_at: string\n /** The ordered list of analyst ids the registry will run. */\n analyst_ids: ReadonlyArray<string>\n }\n | {\n type: 'analyst-skipped'\n summary: AnalystRunSummary\n }\n | {\n type: 'analyst-started'\n analyst_id: string\n started_at: string\n }\n | {\n type: 'analyst-completed'\n /** `summary.status` is `'ok'` for clean completion or `'failed'` for thrown analysts. */\n summary: AnalystRunSummary\n findings: ReadonlyArray<AnalystFinding>\n }\n | {\n type: 'run-completed'\n result: AnalystRunResult\n }\n","/**\n * Adapter factories — lift each existing agent-eval primitive into the\n * Analyst contract without re-implementing it.\n *\n * Five primitives, five factories. Each one:\n * - Builds an Analyst with a stable id (caller chooses; defaults\n * given), a sensible default `inputKind`, a version derived from\n * the wrapped primitive's version + an adapter revision, and an\n * `analyze()` that calls the primitive and lifts its output to\n * AnalystFinding[] using `makeFinding()`.\n * - Maps severities: the existing `Severity` ('critical' | 'major' |\n * 'minor' | 'info') projects onto AnalystSeverity ('critical' |\n * 'high' | 'medium' | 'low' | 'info'); 'major' → 'high', 'minor' →\n * 'medium'. Domain analysts that want finer-grained mapping override.\n *\n * Adapters never own state. Calling the same factory twice with the\n * same primitive instance is safe.\n */\n\nimport type { AxAIService } from '@ax-llm/ax'\nimport type {\n Finding as LayerFinding,\n Severity as LayerSeverity,\n MultiLayerVerifier,\n VerifyOptions,\n} from '../multi-layer-verifier'\nimport { RunCritic, type RunTrace } from '../run-critic'\nimport {\n runSemanticConceptJudge,\n SEMANTIC_CONCEPT_JUDGE_VERSION,\n type SemanticConceptJudgeInput,\n type SemanticConceptJudgeOptions,\n} from '../semantic-concept-judge'\nimport { type AnalyzeTracesOptions, analyzeTraces } from '../trace-analyst/analyst'\nimport type { TraceAnalysisStore } from '../trace-analyst/store'\nimport type { JudgeFn, JudgeInput, JudgeScore, TCloud } from '../types'\nimport type { Analyst, AnalystFinding, AnalystSeverity } from './types'\nimport { makeFinding } from './types'\n\nconst ADAPTER_REV = '1'\n\n// ── Severity bridges ───────────────────────────────────────────────\n\nexport function liftSeverity(s: LayerSeverity): AnalystSeverity {\n switch (s) {\n case 'critical':\n return 'critical'\n case 'major':\n return 'high'\n case 'minor':\n return 'medium'\n case 'info':\n return 'info'\n }\n}\n\n// ── 1. analyzeTraces → Analyst ─────────────────────────────────────\n\nexport interface TraceAnalystAdapterOpts {\n id?: string\n area?: string\n /** The natural-language question(s) put to the analyst. One finding per question. */\n questions: string[]\n /** Caller-provided AxAI service — same one trace-analyst.ts expects. */\n ai: AxAIService\n model?: string\n /** Forwarded to analyzeTraces. */\n extra?: Omit<AnalyzeTracesOptions, 'source' | 'ai' | 'model'>\n}\n\n/**\n * @deprecated Prefer `createTraceAnalystKind` + one of the failure /\n * improvement kinds from `./kinds`. This adapter wraps the legacy\n * `analyzeTraces` flow whose output is `findings:string[]` — every\n * bullet gets flat-defaulted severity `medium` / confidence `0.6`,\n * which loses the per-finding grading kinds provide via Ax structured\n * output + Zod validation. Kept for one minor while consumers migrate.\n */\nexport function createTraceAnalystAdapter(\n opts: TraceAnalystAdapterOpts,\n): Analyst<TraceAnalysisStore> {\n const id = opts.id ?? 'trace-analyst'\n const area = opts.area ?? 'agent-reasoning'\n return {\n id,\n description:\n 'Runs the agent-eval trace analyst over an OTLP trace store and lifts its bulleted findings.',\n inputKind: 'trace-store',\n cost: { kind: 'llm', models: opts.model ? [opts.model] : undefined },\n version: `trace-analyst-${ADAPTER_REV}`,\n async analyze(store, ctx) {\n const out: AnalystFinding[] = []\n for (const question of opts.questions) {\n if (ctx.signal?.aborted) break\n const result = await analyzeTraces(\n { question },\n { source: store, ai: opts.ai, model: opts.model, ...opts.extra },\n )\n const subject = ctx.tags?.subject ?? question.slice(0, 60)\n // The responder produces a list of bullet strings. Each becomes\n // one finding; the prose answer is attached as rationale on the\n // first (so renderers that show only top-N still get context).\n if (result.findings.length === 0) {\n out.push(\n makeFinding({\n analyst_id: id,\n area,\n subject,\n claim: result.answer.slice(0, 200),\n rationale: result.answer,\n severity: 'info',\n confidence: 0.5,\n evidence_refs: [],\n metadata: {\n actor_prompt_version: result.actorPromptVersion,\n turns: result.turnCount,\n },\n }),\n )\n continue\n }\n result.findings.forEach((claim, i) => {\n out.push(\n makeFinding({\n analyst_id: id,\n area,\n subject,\n claim,\n rationale: i === 0 ? result.answer : undefined,\n severity: 'medium',\n confidence: 0.6,\n evidence_refs: [],\n metadata: { question, turns: result.turnCount, finding_index: i },\n }),\n )\n })\n }\n return out\n },\n }\n}\n\n// ── 2. MultiLayerVerifier → Analyst ─────────────────────────────────\n\nexport interface VerifierAdapterOpts<Env> {\n id?: string\n area?: string\n verifier: MultiLayerVerifier<Env>\n /**\n * The verifier expects an `env` per run. Adapters take it from\n * `AnalystRunInputs.custom[<id>]` via the registry's 'custom' routing.\n */\n options?: Omit<VerifyOptions<Env>, 'env'>\n}\n\nexport function createVerifierAdapter<Env>(opts: VerifierAdapterOpts<Env>): Analyst<Env> {\n const id = opts.id ?? 'multi-layer-verifier'\n const area = opts.area ?? 'verification'\n return {\n id,\n description:\n \"Runs a MultiLayerVerifier and lifts each layer's findings into the analyst envelope.\",\n inputKind: 'custom',\n cost: { kind: 'deterministic' },\n version: `verifier-${ADAPTER_REV}`,\n async analyze(env, ctx) {\n const report = await opts.verifier.run({ env, ...opts.options })\n const out: AnalystFinding[] = []\n for (const layer of report.layers) {\n for (const finding of layer.findings) {\n out.push(liftLayerFinding(id, area, layer.layer, finding))\n }\n // Layer-level signal: a failed/error layer is itself a finding\n // even if it didn't emit per-finding rows.\n if (layer.status === 'fail' || layer.status === 'error' || layer.status === 'timeout') {\n out.push(\n makeFinding({\n analyst_id: id,\n area,\n subject: layer.layer,\n claim: `layer \"${layer.layer}\" ${layer.status}: ${layer.reason ?? 'no reason given'}`,\n severity:\n layer.status === 'error' ? 'high' : layer.status === 'timeout' ? 'medium' : 'high',\n confidence: 1,\n evidence_refs: [],\n metadata: {\n layer_status: layer.status,\n duration_ms: layer.durationMs,\n score: layer.score,\n diagnostics: layer.diagnostics,\n },\n }),\n )\n }\n }\n ctx.log?.('verifier complete', {\n layers: report.layers.length,\n blended: report.blendedScore,\n all_pass: report.allPass,\n })\n return out\n },\n }\n}\n\nfunction liftLayerFinding(\n analyst_id: string,\n area: string,\n layer: string,\n f: LayerFinding,\n): AnalystFinding {\n return makeFinding({\n analyst_id,\n area,\n subject: f.layer ?? layer,\n claim: f.message,\n severity: liftSeverity(f.severity),\n confidence: 0.85,\n evidence_refs: f.evidence\n ? [{ kind: 'artifact', uri: 'inline:evidence', excerpt: f.evidence }]\n : [],\n metadata: f.detail,\n })\n}\n\n// ── 3. RunCritic → Analyst ──────────────────────────────────────────\n\nexport interface RunCriticAdapterOpts {\n id?: string\n area?: string\n critic?: RunCritic\n /** Optional threshold below which a dimension is reported as a finding. Default 0.5. */\n threshold?: number\n}\n\nexport function createRunCriticAdapter(opts: RunCriticAdapterOpts = {}): Analyst<RunTrace> {\n const id = opts.id ?? 'run-critic'\n const area = opts.area ?? 'run-quality'\n const critic = opts.critic ?? new RunCritic()\n const threshold = opts.threshold ?? 0.5\n return {\n id,\n description:\n 'Scores a single run across success / grounding / drift / tool-quality and surfaces below-threshold dimensions.',\n inputKind: 'custom',\n cost: { kind: 'deterministic' },\n version: `run-critic-${ADAPTER_REV}`,\n async analyze(trace) {\n const score = critic.scoreTrace(trace)\n const out: AnalystFinding[] = []\n const dims: Array<[keyof typeof score, AnalystSeverity, string]> = [\n ['success', 'critical', 'run did not complete successfully'],\n ['goalProgress', 'high', 'goal progress is low'],\n ['repoGroundedness', 'high', 'output is poorly grounded in the repository'],\n ['toolUseQuality', 'medium', 'tool use quality is low'],\n ['patchQuality', 'medium', 'no real patch/edit evidence'],\n ['testReality', 'high', 'no real test/build evidence'],\n ['finalGate', 'critical', 'final gate is blocking'],\n ]\n for (const [dim, sev, msg] of dims) {\n const value = score[dim] as number\n if (typeof value === 'number' && value < threshold) {\n out.push(\n makeFinding({\n analyst_id: id,\n area,\n subject: dim,\n claim: msg,\n rationale: `${dim}=${value.toFixed(2)} below threshold ${threshold}`,\n severity: sev,\n confidence: 1,\n evidence_refs: [],\n metadata: { dimension: dim, value, threshold, run_id: trace.run.runId },\n }),\n )\n }\n }\n // Drift penalty is high → surface as a finding (inverse threshold).\n if (score.driftPenalty > 1 - threshold) {\n out.push(\n makeFinding({\n analyst_id: id,\n area,\n subject: 'drift',\n claim: 'agent output drifted from repository signal',\n rationale: `driftPenalty=${score.driftPenalty.toFixed(2)}`,\n severity: 'medium',\n confidence: 0.9,\n evidence_refs: [],\n metadata: { drift_penalty: score.driftPenalty, notes: score.notes },\n }),\n )\n }\n return out\n },\n }\n}\n\n// ── 4. JudgeFn → Analyst ────────────────────────────────────────────\n\nexport interface JudgeAdapterOpts {\n id?: string\n area?: string\n judge: JudgeFn\n /** TCloud handle the JudgeFn calls. */\n tcloud: TCloud\n /** Optional cost classification — most judges call an LLM. */\n cost?: Analyst['cost']\n /** Optional threshold below which a JudgeScore becomes a finding. Default 6 (on 0-10 scale). */\n threshold?: number\n}\n\nexport function createJudgeAdapter(opts: JudgeAdapterOpts): Analyst<JudgeInput> {\n const id = opts.id ?? 'judge'\n const area = opts.area ?? 'judge'\n const threshold = opts.threshold ?? 6\n return {\n id,\n description:\n 'Wraps an agent-eval JudgeFn into an analyst; below-threshold dimensions surface as findings.',\n inputKind: 'judge-input',\n cost: opts.cost ?? { kind: 'llm' },\n version: `judge-${ADAPTER_REV}`,\n async analyze(input) {\n const scores = await opts.judge(opts.tcloud, input)\n return scores\n .filter((s) => normalize10(s.score) < threshold)\n .map((s) => liftJudgeScore(id, area, s))\n },\n }\n}\n\nfunction normalize10(s: number): number {\n // JudgeScore convention is 0-10 but some judges emit 0-1. Coerce to 0-10.\n return s <= 1 ? s * 10 : s\n}\n\nfunction liftJudgeScore(analyst_id: string, area: string, s: JudgeScore): AnalystFinding {\n const score10 = normalize10(s.score)\n const severity: AnalystSeverity =\n score10 < 3 ? 'critical' : score10 < 5 ? 'high' : score10 < 7 ? 'medium' : 'low'\n return makeFinding({\n analyst_id,\n area,\n subject: s.dimension,\n claim: `${s.judgeName}/${s.dimension} scored ${score10.toFixed(1)}/10`,\n rationale: s.reasoning,\n severity,\n confidence: 0.8,\n evidence_refs: s.evidence\n ? [{ kind: 'artifact', uri: 'inline:evidence', excerpt: s.evidence }]\n : [],\n metadata: { judge_name: s.judgeName, dimension: s.dimension, score_10: score10 },\n })\n}\n\n// ── 5. SemanticConceptJudge → Analyst ──────────────────────────────\n\nexport interface SemanticConceptJudgeAdapterOpts {\n id?: string\n area?: string\n options?: SemanticConceptJudgeOptions\n}\n\nexport function createSemanticConceptJudgeAdapter(\n opts: SemanticConceptJudgeAdapterOpts = {},\n): Analyst<SemanticConceptJudgeInput> {\n const id = opts.id ?? 'semantic-concept-judge'\n const area = opts.area ?? 'concept-coverage'\n return {\n id,\n description:\n 'Runs the semantic-concept judge and surfaces missing / weak concepts as findings.',\n inputKind: 'custom',\n cost: { kind: 'llm', models: opts.options?.model ? [opts.options.model] : undefined },\n version: `${SEMANTIC_CONCEPT_JUDGE_VERSION}-adapter-${ADAPTER_REV}`,\n async analyze(input) {\n const result = await runSemanticConceptJudge(input, opts.options)\n if (!result.available) {\n return [\n makeFinding({\n analyst_id: id,\n area,\n claim: 'semantic-concept judge unavailable',\n rationale: result.error,\n severity: 'info',\n confidence: 1,\n evidence_refs: [],\n metadata: { reason: result.error },\n }),\n ]\n }\n const out: AnalystFinding[] = []\n for (const f of result.findings) {\n // Only surface gaps: missing concepts or low scores. Concepts at\n // 7+/10 with present=true are not findings — they're successes.\n if (f.present && f.score >= 7) continue\n out.push(\n makeFinding({\n analyst_id: id,\n area,\n subject: f.concept,\n claim: f.present\n ? `concept \"${f.concept}\" is weak (${f.score}/10)`\n : `concept \"${f.concept}\" is missing`,\n rationale: f.evidence,\n severity: liftSeverity(f.severity),\n confidence: 0.85,\n evidence_refs: [{ kind: 'artifact', uri: 'inline:evidence', excerpt: f.evidence }],\n metadata: {\n concept: f.concept,\n present: f.present,\n score_10: f.score,\n cost_usd: result.costUsd ?? undefined,\n },\n }),\n )\n }\n return out\n },\n }\n}\n","/**\n * ChatClient — the single LLM abstraction analysts call.\n *\n * agent-eval already ships an `LlmClient` (OpenAI-compatible, retry,\n * graceful JSON-schema degrade) and judges that talk to `TCloud`. Two\n * mixed patterns force every analyst author to pick a transport, which\n * couples analyst code to runtime concerns (cli-bridge vs router vs\n * sandbox-sdk) it shouldn't know about.\n *\n * `ChatClient` is one interface every analyst takes via `AnalystContext.chat`.\n * The operator decides at the registry boundary which transport binds\n * to it. Analyst code stays transport-agnostic; swapping production\n * (sandbox-sdk) for local dev (cli-bridge) or tests (mock) is a one-\n * line factory call.\n *\n * Designed to coexist: existing `LlmClient` callers and existing\n * `TCloud`-based judges keep working untouched. New analyst code uses\n * `ChatClient`. When old call sites migrate, they pick up budgeting,\n * cancellation, and unified telemetry for free.\n */\n\nimport {\n type LlmCallRequest,\n type LlmCallResult,\n LlmClient,\n type LlmClientOptions,\n} from '../llm-client'\n\n/**\n * Unified chat interface. Mirrors LlmCallRequest/Result so the OpenAI-\n * compatible mental model stays. Two methods: a one-shot `chat()` and\n * an `streamChat()` for future agentic loops (not yet exposed).\n */\nexport interface ChatClient {\n /** Display name of the bound transport — included in telemetry. */\n readonly transport: ChatTransport\n /** Default model when caller omits — operators bind this per environment. */\n readonly defaultModel?: string\n\n chat(req: ChatRequest, opts?: ChatCallOpts): Promise<ChatResponse>\n}\n\nexport type ChatTransport =\n | 'router' // router.tangle.tools — production paid models\n | 'sandbox-sdk' // box.streamPrompt() — chat completion via sandbox SDK\n | 'cli-bridge' // local cli-bridge for dev / local-only runs\n | 'direct-provider' // direct OpenAI / Anthropic / etc. — bypass router\n | 'mock' // test-time injection\n\nexport interface ChatRequest extends Omit<LlmCallRequest, 'model'> {\n /** Optional — falls back to ChatClient.defaultModel. */\n model?: string\n}\n\nexport type ChatResponse = LlmCallResult\n\nexport interface ChatCallOpts {\n /** Cancel the in-flight request. */\n signal?: AbortSignal\n /** Hard USD ceiling for this single call (informational; the underlying transport may not enforce). */\n maxCostUsd?: number\n /** Correlation tag carried into request headers when the transport allows. */\n correlationId?: string\n}\n\n// ── Factory ─────────────────────────────────────────────────────────\n\nexport type CreateChatClientOpts =\n | RouterTransportOpts\n | CliBridgeTransportOpts\n | DirectProviderTransportOpts\n | SandboxSdkTransportOpts\n | MockTransportOpts\n\ninterface BaseTransportOpts {\n defaultModel?: string\n}\n\nexport interface RouterTransportOpts extends BaseTransportOpts {\n transport: 'router'\n baseUrl?: string\n apiKey: string\n}\n\nexport interface CliBridgeTransportOpts extends BaseTransportOpts {\n transport: 'cli-bridge'\n baseUrl?: string\n bearer?: string\n}\n\nexport interface DirectProviderTransportOpts extends BaseTransportOpts {\n transport: 'direct-provider'\n baseUrl: string\n apiKey: string\n}\n\n/**\n * Sandbox-SDK transport. Provided as a thin pass-through: the caller\n * supplies a callable that mimics LlmClient.chat() against an already-\n * configured Sandbox handle. We don't import the SDK here to keep\n * agent-eval dep-free of @tangle-network/sandbox.\n */\nexport interface SandboxSdkTransportOpts extends BaseTransportOpts {\n transport: 'sandbox-sdk'\n chat: (req: ChatRequest, opts?: ChatCallOpts) => Promise<ChatResponse>\n}\n\n/**\n * Mock transport for tests. The handler receives the request and returns\n * whatever the test wants. No retries, no JSON-schema degrade.\n */\nexport interface MockTransportOpts extends BaseTransportOpts {\n transport: 'mock'\n handler: (req: ChatRequest, opts?: ChatCallOpts) => Promise<ChatResponse>\n}\n\n/**\n * Build a ChatClient bound to a specific transport. The returned client\n * is safe to share across analysts in a single registry run.\n */\nexport function createChatClient(opts: CreateChatClientOpts): ChatClient {\n switch (opts.transport) {\n case 'router':\n return wrapLlmClient(\n opts.transport,\n opts.defaultModel,\n new LlmClient({\n baseUrl: opts.baseUrl ?? 'https://router.tangle.tools/v1',\n apiKey: opts.apiKey,\n } as LlmClientOptions),\n )\n case 'cli-bridge':\n return wrapLlmClient(\n opts.transport,\n opts.defaultModel,\n new LlmClient({\n baseUrl: opts.baseUrl ?? 'http://127.0.0.1:3344/v1',\n apiKey: opts.bearer ?? '',\n } as LlmClientOptions),\n )\n case 'direct-provider':\n return wrapLlmClient(\n opts.transport,\n opts.defaultModel,\n new LlmClient({\n baseUrl: opts.baseUrl,\n apiKey: opts.apiKey,\n } as LlmClientOptions),\n )\n case 'sandbox-sdk':\n return {\n transport: 'sandbox-sdk',\n defaultModel: opts.defaultModel,\n chat: async (req, callOpts) => opts.chat(resolveModel(req, opts.defaultModel), callOpts),\n }\n case 'mock':\n return {\n transport: 'mock',\n defaultModel: opts.defaultModel,\n chat: async (req, callOpts) => opts.handler(resolveModel(req, opts.defaultModel), callOpts),\n }\n }\n}\n\nfunction wrapLlmClient(\n transport: ChatTransport,\n defaultModel: string | undefined,\n inner: LlmClient,\n): ChatClient {\n return {\n transport,\n defaultModel,\n chat: async (req, callOpts) => {\n const resolved = resolveModel(req, defaultModel)\n // LlmClient.call doesn't accept an external AbortSignal today (it\n // owns its own AbortController for the per-attempt timeout). We\n // race the response against the caller's signal so awaiting code\n // unblocks on abort. The in-flight HTTP request still runs to its\n // own timeoutMs — when LlmClient grows a signal parameter, wire\n // it directly here and drop the race.\n const call = inner.call({\n model: resolved.model!,\n messages: req.messages,\n jsonMode: req.jsonMode,\n jsonSchema: req.jsonSchema,\n temperature: req.temperature,\n maxTokens: req.maxTokens,\n timeoutMs: req.timeoutMs,\n })\n if (!callOpts?.signal) return await call\n return await Promise.race([call, abortAsRejection(callOpts.signal)])\n },\n }\n}\n\nfunction abortAsRejection(signal: AbortSignal): Promise<never> {\n if (signal.aborted) return Promise.reject(toAbortError(signal))\n return new Promise<never>((_, reject) => {\n signal.addEventListener('abort', () => reject(toAbortError(signal)), { once: true })\n })\n}\n\nfunction toAbortError(signal: AbortSignal): Error {\n const reason = (signal as { reason?: unknown }).reason\n if (reason instanceof Error) return reason\n const e = new Error('ChatClient.chat: aborted')\n e.name = 'AbortError'\n return e\n}\n\nfunction resolveModel(req: ChatRequest, defaultModel: string | undefined): ChatRequest {\n if (req.model) return req\n if (!defaultModel) {\n throw new Error(\n 'ChatClient.chat: no model on request and no defaultModel on the client. ' +\n 'Either pass req.model or bind defaultModel at createChatClient().',\n )\n }\n return { ...req, model: defaultModel }\n}\n","/**\n * Typed Ax output for analyst findings.\n *\n * Replaces the legacy `findings:string[]` pattern (where every bullet\n * became a flat-severity `AnalystFinding`) with a structured object\n * array. Ax binds the field as `findings:json[]` so the provider emits\n * native structured output; at the kind-factory boundary we Zod-validate\n * each emitted finding so malformed rows fail loud instead of being\n * silently lifted with default severity.\n *\n * Why not `f.object().array()` directly in the signature? The Ax\n * signature string `question:string -> findings:json[]` already lets\n * the provider emit JSON arrays. A Zod boundary is required either\n * way (the provider can return any JSON), and Zod gives us a single\n * validation surface independent of which Ax version is installed.\n */\n\nimport { z } from 'zod'\nimport { parseFindingSubject } from './finding-subject'\n\nexport const ANALYST_SEVERITIES = ['critical', 'high', 'medium', 'low', 'info'] as const\n\nexport const RawAnalystFindingSchema = z\n .object({\n severity: z.enum(ANALYST_SEVERITIES),\n claim: z.string().min(1).max(2000),\n /**\n * Subject locus the finding is about. Validated at parse time\n * against the documented grammar (`finding-subject.ts`). Findings\n * with a malformed subject are rejected — they would have been\n * silently skipped by every downstream adapter, so failing loud at\n * parse time turns a hidden no-op into a kind-prompt audit signal.\n *\n * Optional because purely descriptive findings (no actionable\n * locus) are legitimate; they just don't route through the\n * KnowledgeAdapter / ImprovementAdapter.\n */\n subject: z\n .string()\n .max(400)\n .refine((s) => parseFindingSubject(s) !== null, {\n message: 'subject does not match the finding-subject grammar',\n })\n .optional(),\n evidence_uri: z.string().min(1).max(2000),\n evidence_excerpt: z.string().max(2000).optional(),\n confidence: z.number().min(0).max(1),\n rationale: z.string().max(4000).optional(),\n recommended_action: z.string().max(2000).optional(),\n })\n .strict()\n\nexport type RawAnalystFinding = z.infer<typeof RawAnalystFindingSchema>\n\n/**\n * Description embedded into the actor prompt so the LLM knows what\n * shape to emit. Kept here so kinds share one source of truth rather\n * than restating the schema in every prompt.\n */\nexport const RAW_FINDING_SCHEMA_PROMPT = `Each finding MUST be a JSON object with these fields:\n - severity: one of \"critical\" | \"high\" | \"medium\" | \"low\" | \"info\"\n - claim: one-sentence statement (max 2000 chars)\n - subject?: the leaf id, agent id, span id, tool name, or noun phrase the finding is about\n - evidence_uri: \"span://<trace_id>/<span_id>\" for trace evidence, \"artifact://<relative-path>\" for files, \"metric://<name>\" for named scalars — ALWAYS cite a real id surfaced by the tools\n - evidence_excerpt?: short quote (<=2000 chars) from the cited span/artifact\n - confidence: number 0..1 — 0.9+ when backed by exact quotes, 0.6-0.8 for inferred patterns, <0.5 for speculative\n - rationale?: one or two sentences explaining the reasoning\n - recommended_action?: concrete change phrased as an imperative (\"Add ...\", \"Replace ...\", \"Stop ...\") — omit when the finding is purely descriptive\n\nEmit an empty array when the question has no findings to report. Do not fabricate evidence.`\n\n/**\n * Validate one row emitted by the LLM. Returns the typed finding on\n * success; returns `null` and logs the reason on failure so the kind\n * factory can skip-and-count rather than abort the whole analyst run.\n */\nexport function parseRawFinding(\n row: unknown,\n log?: (msg: string, fields?: Record<string, unknown>) => void,\n): RawAnalystFinding | null {\n const result = RawAnalystFindingSchema.safeParse(row)\n if (!result.success) {\n log?.('finding rejected: schema failure', {\n issues: result.error.issues.map((i) => ({\n path: i.path.join('.'),\n code: i.code,\n message: i.message,\n })),\n })\n return null\n }\n return result.data\n}\n","/**\n * Typed `FindingSubject` — the canonical grammar every analyst kind emits.\n *\n * Background: kind actor prompts have always documented a subject grammar\n * (e.g. `system-prompt:<section>`, `agent-knowledge:wiki:<slug>`) but the\n * LLM was unconstrained — it could emit `subject: \"fix the prompt\"`\n * (prose) and downstream adapters routed on `startsWith(...)` would\n * silently skip it. Every per-vertical `ImprovementAdapter` had a\n * routing table that mostly caught nothing.\n *\n * This module fixes that:\n * - `parseFindingSubject(raw)` — returns the typed `FindingSubject`\n * when `raw` matches the grammar, else `null`. Used at the\n * `RawAnalystFindingSchema` boundary so malformed subjects are\n * rejected loudly instead of silently lifted into the registry.\n * - `FindingSubjectKind` — the union of valid locus categories. Each\n * variant carries the typed components downstream adapters resolve\n * against the agent's surface manifest (no string parsing in the\n * adapter).\n * - `FINDING_SUBJECT_GRAMMAR_PROMPT` — single source of truth for the\n * grammar string embedded in kind actor prompts. Drift between\n * prompt and parser is impossible if every kind imports this.\n *\n * The grammar is intentionally NARROW — only loci the substrate's\n * default `ImprovementAdapter` / `KnowledgeAdapter` can act on. A\n * finding with a subject outside this set fails the parser; the kind\n * author either extends the grammar here (and adds adapter routing)\n * or rephrases the prompt to map onto an existing variant.\n *\n * `failure-mode` is the one exception — its subjects are free-form\n * cluster labels, not loci. The schema preserves them as\n * `{ kind: 'cluster', label }` and the adapters skip them (cluster\n * findings are evidence, not actionable mutations).\n */\n\nimport { z } from 'zod'\n\n// ── canonical grammar ─────────────────────────────────────────────────\n\n/**\n * Discriminated union of every locus the substrate can route findings to.\n *\n * Adapters narrow on `kind` and use the typed components (no string\n * parsing). Adding a variant here REQUIRES updating the parser, the\n * grammar prompt, and at least one adapter — by design.\n */\nexport type FindingSubject =\n // ── agent-knowledge:* — routed to the KnowledgeAdapter ──\n | { kind: 'knowledge.wiki'; slug: string; heading?: string }\n | { kind: 'knowledge.claim'; topic: string }\n | { kind: 'knowledge.raw'; sourceId: string }\n | { kind: 'knowledge.stale'; slug: string }\n // ── system-prompt / tool / new-tool / rag / memory / scaffolding / output-schema ──\n // routed to the ImprovementAdapter\n | { kind: 'system-prompt'; section: string }\n | { kind: 'tool-doc'; tool: string; aspect?: string }\n | { kind: 'new-tool'; name: string }\n | { kind: 'rag'; corpus: string; docId: string }\n | { kind: 'memory'; key: string }\n | { kind: 'scaffolding'; concern: string }\n | { kind: 'output-schema'; field: string }\n // ── websearch / prior-run-summary — routed to the KnowledgeAdapter as stale signals\n | { kind: 'websearch.outdated'; topic: string }\n | { kind: 'prior-run-summary'; topic: string }\n // ── failure-mode cluster label — preserved verbatim, not routed\n | { kind: 'cluster'; label: string }\n\nexport type FindingSubjectKind = FindingSubject['kind']\n\nexport const FINDING_SUBJECT_KINDS: ReadonlyArray<FindingSubjectKind> = [\n 'knowledge.wiki',\n 'knowledge.claim',\n 'knowledge.raw',\n 'knowledge.stale',\n 'system-prompt',\n 'tool-doc',\n 'new-tool',\n 'rag',\n 'memory',\n 'scaffolding',\n 'output-schema',\n 'websearch.outdated',\n 'prior-run-summary',\n 'cluster',\n]\n\n// ── parser ────────────────────────────────────────────────────────────\n\n/**\n * Parse a raw subject string emitted by an analyst kind's actor.\n *\n * Returns the typed `FindingSubject` when `raw` matches the grammar,\n * else `null`. Callers use the `null` return as a signal to either\n * (a) reject the finding at parse time (kinds that emit typed loci —\n * knowledge-gap, improvement, knowledge-poisoning) or (b) lift it as\n * a cluster label (failure-mode).\n *\n * Slugs are constrained to `[a-z0-9-]+` (lowercase kebab) to keep file\n * paths sane downstream. Topics / keys / sections allow any non-empty\n * string (free-form for the LLM's voice) but get trimmed.\n *\n * Empty / whitespace-only inputs return `null`. `undefined` returns\n * `null`. Both are surfaced by the caller as a rejected subject.\n */\nexport function parseFindingSubject(raw: string | null | undefined): FindingSubject | null {\n if (raw === null || raw === undefined) return null\n const trimmed = raw.trim()\n if (trimmed.length === 0) return null\n\n // agent-knowledge:wiki:<slug>[#<heading>]\n const wiki = trimmed.match(\n /^agent-knowledge:wiki:([a-z0-9][a-z0-9-]*)(?:#([a-z0-9][a-z0-9-]*))?$/,\n )\n if (wiki)\n return { kind: 'knowledge.wiki', slug: wiki[1]!, ...(wiki[2] ? { heading: wiki[2] } : {}) }\n\n // agent-knowledge:claim:<topic>\n const claim = trimmed.match(/^agent-knowledge:claim:(.+)$/)\n if (claim && claim[1]!.trim().length > 0)\n return { kind: 'knowledge.claim', topic: claim[1]!.trim() }\n\n // agent-knowledge:raw:<source-id>\n const raw_ = trimmed.match(/^agent-knowledge:raw:(.+)$/)\n if (raw_ && raw_[1]!.trim().length > 0)\n return { kind: 'knowledge.raw', sourceId: raw_[1]!.trim() }\n\n // agent-knowledge:stale:<slug>\n const stale = trimmed.match(/^agent-knowledge:stale:([a-z0-9][a-z0-9-]*)$/)\n if (stale) return { kind: 'knowledge.stale', slug: stale[1]! }\n\n // system-prompt:<section>\n const sp = trimmed.match(/^system-prompt:(.+)$/)\n if (sp && sp[1]!.trim().length > 0) return { kind: 'system-prompt', section: sp[1]!.trim() }\n\n // tool-doc:<tool>[:<aspect>]\n const tdAspect = trimmed.match(/^tool-doc:([a-z0-9][a-z0-9_-]*):(.+)$/)\n if (tdAspect && tdAspect[2]!.trim().length > 0) {\n return { kind: 'tool-doc', tool: tdAspect[1]!, aspect: tdAspect[2]!.trim() }\n }\n const td = trimmed.match(/^tool-doc:([a-z0-9][a-z0-9_-]*)$/)\n if (td) return { kind: 'tool-doc', tool: td[1]! }\n\n // new-tool:<name>\n const nt = trimmed.match(/^new-tool:([a-z0-9][a-z0-9_-]*)$/)\n if (nt) return { kind: 'new-tool', name: nt[1]! }\n\n // rag:<corpus>:<doc-id>\n const rag = trimmed.match(/^rag:([a-z0-9][a-z0-9_-]*):(.+)$/)\n if (rag && rag[2]!.trim().length > 0) {\n return { kind: 'rag', corpus: rag[1]!, docId: rag[2]!.trim() }\n }\n\n // memory:<key>\n const mem = trimmed.match(/^memory:(.+)$/)\n if (mem && mem[1]!.trim().length > 0) return { kind: 'memory', key: mem[1]!.trim() }\n\n // scaffolding:<concern>\n const sc = trimmed.match(/^scaffolding:(.+)$/)\n if (sc && sc[1]!.trim().length > 0) return { kind: 'scaffolding', concern: sc[1]!.trim() }\n\n // output-schema:<field>\n const os = trimmed.match(/^output-schema:(.+)$/)\n if (os && os[1]!.trim().length > 0) return { kind: 'output-schema', field: os[1]!.trim() }\n\n // websearch:outdated:<topic>\n const ws = trimmed.match(/^websearch:outdated:(.+)$/)\n if (ws && ws[1]!.trim().length > 0) return { kind: 'websearch.outdated', topic: ws[1]!.trim() }\n\n // prior-run-summary:<topic>\n const prs = trimmed.match(/^prior-run-summary:(.+)$/)\n if (prs && prs[1]!.trim().length > 0) return { kind: 'prior-run-summary', topic: prs[1]!.trim() }\n\n // cluster (no prefix — failure-mode emits short labels)\n if (/^[a-z0-9][a-z0-9-]*$/.test(trimmed) && trimmed.length <= 80) {\n return { kind: 'cluster', label: trimmed }\n }\n\n return null\n}\n\n/**\n * Render the parsed subject back to its canonical string form. Inverse\n * of `parseFindingSubject`; useful when the substrate constructs new\n * findings programmatically (e.g. for tests, replays, or\n * `id_basis` carry-forward).\n */\nexport function renderFindingSubject(s: FindingSubject): string {\n switch (s.kind) {\n case 'knowledge.wiki':\n return s.heading\n ? `agent-knowledge:wiki:${s.slug}#${s.heading}`\n : `agent-knowledge:wiki:${s.slug}`\n case 'knowledge.claim':\n return `agent-knowledge:claim:${s.topic}`\n case 'knowledge.raw':\n return `agent-knowledge:raw:${s.sourceId}`\n case 'knowledge.stale':\n return `agent-knowledge:stale:${s.slug}`\n case 'system-prompt':\n return `system-prompt:${s.section}`\n case 'tool-doc':\n return s.aspect ? `tool-doc:${s.tool}:${s.aspect}` : `tool-doc:${s.tool}`\n case 'new-tool':\n return `new-tool:${s.name}`\n case 'rag':\n return `rag:${s.corpus}:${s.docId}`\n case 'memory':\n return `memory:${s.key}`\n case 'scaffolding':\n return `scaffolding:${s.concern}`\n case 'output-schema':\n return `output-schema:${s.field}`\n case 'websearch.outdated':\n return `websearch:outdated:${s.topic}`\n case 'prior-run-summary':\n return `prior-run-summary:${s.topic}`\n case 'cluster':\n return s.label\n }\n}\n\n// ── grammar prompt — single source of truth for actor instructions ──\n\n/**\n * The grammar text embedded into kind actor prompts. Kinds opt into\n * the subset of variants they emit (e.g. `improvement` excludes the\n * cluster variant; `failure-mode` includes ONLY the cluster variant).\n *\n * Drift between prompt and parser is impossible: every kind imports\n * this constant + the matching `expects` set, and the unit tests below\n * lock the table to the parser.\n */\nexport const FINDING_SUBJECT_GRAMMAR_PROMPT = [\n 'Subjects MUST match this grammar — anything else is rejected at parse time and your work is wasted:',\n '',\n ' Knowledge loci (write to the agent-knowledge base):',\n ' agent-knowledge:wiki:<slug>[#<heading>] create / update a wiki page',\n ' agent-knowledge:claim:<topic> draft a claim / relation triple',\n ' agent-knowledge:raw:<source-id> lift a raw source into a curated page',\n ' agent-knowledge:stale:<slug> mark a page superseded',\n '',\n ' Runtime mutable surfaces (write to prompts / tools / scaffolding):',\n ' system-prompt:<section> add / replace a system-prompt section',\n ' tool-doc:<tool>[:<aspect>] rewrite a tool description',\n ' new-tool:<name> propose a new tool surface',\n ' rag:<corpus>:<doc-id> ingest / correct a RAG document',\n ' memory:<key> invalidate / set a memory entry',\n ' scaffolding:<concern> change a precondition / retry / verifier',\n ' output-schema:<field> constrain the agent output shape',\n '',\n ' Stale signals (knowledge-poisoning only):',\n ' websearch:outdated:<topic> stale web result',\n ' prior-run-summary:<topic> stale prior-run summary',\n '',\n ' Cluster label (failure-mode only):',\n ' <kebab-case-label> short cluster id, e.g. \"tool-call-loop\"',\n '',\n 'Slugs / tool ids: [a-z0-9-]+ (lowercase kebab). Topics / keys / sections: free-form, trimmed.',\n].join('\\n')\n\n// ── kind expects sets ─────────────────────────────────────────────────\n\n/**\n * The variants each kind is allowed to emit. Used at the kind factory\n * boundary so a knowledge-gap finding can't sneak in a `system-prompt:*`\n * subject (the improvement-analyst's job) and vice versa.\n *\n * `failure-mode` is restricted to `cluster` — the only kind that emits\n * a non-locus subject.\n */\nexport const KIND_EXPECTED_SUBJECTS: Record<string, ReadonlyArray<FindingSubjectKind>> = {\n 'failure-mode': ['cluster'],\n 'knowledge-gap': [\n 'knowledge.wiki',\n 'knowledge.claim',\n 'knowledge.raw',\n 'knowledge.stale',\n 'tool-doc',\n 'system-prompt',\n 'memory',\n 'websearch.outdated',\n 'prior-run-summary',\n ],\n 'knowledge-poisoning': [\n 'knowledge.wiki',\n 'knowledge.claim',\n 'knowledge.raw',\n 'tool-doc',\n 'system-prompt',\n 'memory',\n 'websearch.outdated',\n 'prior-run-summary',\n ],\n improvement: [\n 'system-prompt',\n 'tool-doc',\n 'new-tool',\n 'rag',\n 'memory',\n 'scaffolding',\n 'output-schema',\n 'knowledge.wiki',\n 'knowledge.claim',\n ],\n}\n\n// ── Zod schema for boundary validation ───────────────────────────────\n\n/**\n * Zod schema that validates a raw subject string and returns the parsed\n * `FindingSubject`. Embedded in `RawAnalystFindingSchema` via\n * `transform`, so `subject` arrives at the kind factory either as a\n * typed locus or as a parse error attached to a single Zod issue.\n *\n * Optionality is preserved: subjects ARE optional on the wire (some\n * findings are descriptive, not actionable). When present, they MUST\n * parse — emitting a malformed subject is a contract violation, not a\n * soft signal.\n */\nexport const FindingSubjectStringSchema = z\n .string()\n .refine((s) => parseFindingSubject(s) !== null, {\n message: 'subject does not match the finding-subject grammar',\n })\n","/**\n * FindingsStore — durable persistence for AnalystFinding rows + a diff\n * helper so we can answer \"what changed since the last run?\" without\n * recomputing analysts.\n *\n * On-disk shape is JSONL: one finding per line, append-only, locked via\n * LockedJsonlAppender. Operators get crash-safety (no partial JSON),\n * cheap reads (sequential parse), and trivial backup (rsync the file).\n *\n * Reads are non-locking: a reader sees a consistent snapshot of all\n * fully-written lines and skips an incomplete trailing line if the\n * writer is mid-append. Cross-process locking is intentionally out of\n * scope (see locked-jsonl-appender.ts).\n *\n * The store is run-scoped: callers pass `runId` on append and on load,\n * which keeps multi-run files cleanly partitioned. The `diffFindings`\n * helper compares two run-id sets using stable `finding_id` semantics —\n * the diff is the cross-run signal the regression dashboard renders.\n */\n\nimport { existsSync, readFileSync } from 'node:fs'\n\nimport { LockedJsonlAppender } from '../locked-jsonl-appender'\nimport type { AnalystFinding } from './types'\n\n/**\n * One persisted row. We attach `run_id` on disk so a single file can\n * hold multiple runs and the diff helper can query without re-walking\n * separate files.\n */\nexport interface PersistedFinding extends AnalystFinding {\n run_id: string\n}\n\nexport class FindingsStore {\n private readonly appender: LockedJsonlAppender\n\n constructor(public readonly path: string) {\n this.appender = new LockedJsonlAppender(path)\n }\n\n async append(runId: string, findings: AnalystFinding[]): Promise<void> {\n for (const f of findings) {\n const row: PersistedFinding = { ...f, run_id: runId }\n await this.appender.append(row)\n }\n }\n\n /** Load every persisted finding. Discards malformed trailing lines silently. */\n loadAll(): PersistedFinding[] {\n if (!existsSync(this.path)) return []\n const raw = readFileSync(this.path, 'utf8')\n if (!raw) return []\n const out: PersistedFinding[] = []\n for (const line of raw.split('\\n')) {\n if (!line) continue\n try {\n out.push(JSON.parse(line) as PersistedFinding)\n } catch {\n // Skip torn trailing line — the lock guarantees no torn lines\n // mid-file, only at EOF when a writer is in-flight.\n }\n }\n return out\n }\n\n /** Filter to a single run. */\n loadRun(runId: string): PersistedFinding[] {\n return this.loadAll().filter((r) => r.run_id === runId)\n }\n}\n\n// ── Cross-run diff ──────────────────────────────────────────────────\n\nexport interface FindingsDiff {\n /** New finding ids in `current` that weren't in `previous`. */\n appeared: PersistedFinding[]\n /** Finding ids in `previous` that aren't in `current`. */\n disappeared: PersistedFinding[]\n /** Same finding id present in both runs and unchanged per the materiality test. */\n persisted: PersistedFinding[]\n /**\n * Same finding id in both runs but at least one non-identity field\n * shifted per `DiffPolicy.isMaterial`. Reported as [previous, current].\n */\n changed: Array<{ previous: PersistedFinding; current: PersistedFinding }>\n}\n\nexport interface DiffPolicy {\n /**\n * Predicate that decides whether two findings (same finding_id) count\n * as a material change. Defaults to {@link defaultIsMaterial}: severity\n * shift, confidence Δ > 0.05, or evidence count change. Compliance /\n * perf consumers MAY supply a stricter predicate (e.g. rationale text\n * diff, metric Δ thresholds).\n */\n isMaterial?: (previous: AnalystFinding, current: AnalystFinding) => boolean\n}\n\n/**\n * Default materiality test. Deliberately narrow so LLM-reword churn\n * doesn't flood the diff. Stricter tests are opt-in via DiffPolicy.\n */\nexport function defaultIsMaterial(a: AnalystFinding, b: AnalystFinding): boolean {\n if (a.severity !== b.severity) return true\n if (Math.abs((a.confidence ?? 0) - (b.confidence ?? 0)) > 0.05) return true\n if (a.evidence_refs.length !== b.evidence_refs.length) return true\n return false\n}\n\n/**\n * Diff two findings sets by stable finding_id. Callers typically load\n * the two run-id slices from the same store and pass them in.\n */\nexport function diffFindings(\n previous: PersistedFinding[],\n current: PersistedFinding[],\n policy: DiffPolicy = {},\n): FindingsDiff {\n const isMaterial = policy.isMaterial ?? defaultIsMaterial\n const prevById = new Map(previous.map((f) => [f.finding_id, f]))\n const curById = new Map(current.map((f) => [f.finding_id, f]))\n\n const appeared: PersistedFinding[] = []\n const disappeared: PersistedFinding[] = []\n const persisted: PersistedFinding[] = []\n const changed: FindingsDiff['changed'] = []\n\n for (const [id, cur] of curById) {\n const prev = prevById.get(id)\n if (!prev) {\n appeared.push(cur)\n continue\n }\n if (isMaterial(prev, cur)) {\n changed.push({ previous: prev, current: cur })\n } else {\n persisted.push(cur)\n }\n }\n for (const [id, prev] of prevById) {\n if (!curById.has(id)) disappeared.push(prev)\n }\n return { appeared, disappeared, persisted, changed }\n}\n","/**\n * LockedJsonlAppender — mutex-serialized JSONL append helper for arbitrary\n * payloads. The reference-replay store does the same thing for typed\n * `ReferenceReplayRun` rows; this is the generic version used by\n * `MutationTelemetry`, `TrialTelemetry`, and any other consumer that wants\n * append-only durable telemetry without rolling its own lock.\n *\n * Locks are per absolute file path (process-local). Cross-process\n * concurrency is NOT addressed — that's an fcntl/flock problem.\n */\n\nimport { appendFileSync, existsSync, mkdirSync } from 'node:fs'\nimport { dirname } from 'node:path'\nimport { Mutex } from './concurrency'\n\nconst mutexes = new Map<string, Mutex>()\n\nfunction getMutex(path: string): Mutex {\n let m = mutexes.get(path)\n if (!m) {\n m = new Mutex()\n mutexes.set(path, m)\n }\n return m\n}\n\nexport class LockedJsonlAppender {\n private readonly mutex: Mutex\n constructor(public readonly path: string) {\n this.mutex = getMutex(path)\n if (!existsSync(dirname(path))) {\n mkdirSync(dirname(path), { recursive: true })\n }\n }\n\n async append(entry: unknown): Promise<void> {\n const line = `${JSON.stringify(entry)}\\n`\n await this.mutex.runExclusive(() => {\n appendFileSync(this.path, line)\n })\n }\n}\n\n/** Reset all internal mutex state — tests only. */\nexport function resetLockedAppendersForTesting(): void {\n mutexes.clear()\n}\n","/**\n * concurrency — small primitives the evolution loop needs.\n *\n * `Mutex` is a zero-dep async lock with FIFO fairness. The evolution loop\n * uses it to serialise checkout/build/commit sequences inside a single\n * pool slot, and to gate concurrent JSONL writers (see\n * `lockedJsonlReferenceReplayStore`).\n *\n * Deliberately minimal — no priority queue, no timeouts. If you need\n * those, swap to `async-mutex` at the call site.\n */\n\nexport class Mutex {\n private locked = false\n private readonly waiters: Array<() => void> = []\n\n async acquire(): Promise<() => void> {\n if (!this.locked) {\n this.locked = true\n return () => this.release()\n }\n return new Promise<() => void>((resolve) => {\n this.waiters.push(() => {\n resolve(() => this.release())\n })\n })\n }\n\n private release(): void {\n const next = this.waiters.shift()\n if (next) {\n next()\n } else {\n this.locked = false\n }\n }\n\n async runExclusive<T>(fn: () => Promise<T> | T): Promise<T> {\n const release = await this.acquire()\n try {\n return await fn()\n } finally {\n release()\n }\n }\n\n /** True iff someone holds the lock right now. Diagnostics only. */\n get isLocked(): boolean {\n return this.locked\n }\n\n /** Pending waiter count. Diagnostics only. */\n get pending(): number {\n return this.waiters.length\n }\n}\n","/**\n * Analyst-kind factory — the typed, focused replacement for the\n * legacy `createTraceAnalystAdapter`.\n *\n * A \"kind\" is a specialized analyst whose actor prompt, tool subset,\n * and Ax recursion config target one failure-mode lens (failure-mode\n * classification, knowledge gap discovery, knowledge poisoning, recursive\n * self-improvement, ...). Kinds emit findings in the typed `RawAnalystFinding`\n * shape via a JSON-array Ax output; the factory validates each row with\n * Zod and lifts it into `AnalystFinding[]` with no shape guessing.\n *\n * Composition rules:\n * - Each kind owns its actor description. No generic \"answer this\n * question\" prompt — the prompt names the failure lens.\n * - Each kind picks a narrow tool subset from `ANALYST_TOOL_GROUPS`.\n * A kind that never needs full-trace dumps can drop `viewTrace` /\n * `viewSpans` and stay cheap.\n * - Each kind declares its recursion + parallelism budget. Discovery-\n * heavy kinds (failure-mode) get higher `maxDepth`; lens kinds\n * (poisoning) usually stay at 0 since they have a tighter brief.\n *\n * Optimizer hook: kinds may declare `goldens` — labeled examples used\n * by `AxMiPRO` / `AxBootstrapFewShot` / `AxGEPA` to fit the actor\n * description programmatically. Stored on the kind, not the registry,\n * because the right metric is kind-specific.\n */\n\nimport type { AxAIService, AxFunction } from '@ax-llm/ax'\nimport { AxJSRuntime, agent } from '@ax-llm/ax'\nimport type { TraceAnalysisStore } from '../trace-analyst/store'\nimport { TraceFileMissingError } from '../trace-analyst/store-otlp'\nimport {\n parseRawFinding,\n RAW_FINDING_SCHEMA_PROMPT,\n type RawAnalystFinding,\n} from './finding-signature'\nimport { KIND_EXPECTED_SUBJECTS, parseFindingSubject } from './finding-subject'\nimport type { Analyst, AnalystContext, AnalystCost, AnalystFinding } from './types'\nimport { makeFinding } from './types'\n\n/**\n * Per-kind specification. The factory turns this into a regular\n * `Analyst<TraceAnalysisStore>` ready for `AnalystRegistry.register()`.\n */\nexport interface TraceAnalystKindSpec {\n /** Stable id. Appears in finding_id, telemetry, and registry exclusions. */\n id: string\n /** One-sentence description shown in `registry.list()`. */\n description: string\n /** Coarse classification stamped on every emitted finding (`failure-mode`, `knowledge-gap`, ...). */\n area: string\n /** Bump on any breaking change to the actor prompt or output schema. */\n version: string\n /** Actor system prompt. Must instruct the LLM to emit `findings` per the schema. */\n actorDescription: string\n /** Responder system prompt; falls back to a minimal \"format the findings\" instruction. */\n responderDescription?: string\n /** Tool functions the actor may call. Pick narrow subsets via `ANALYST_TOOL_GROUPS`. */\n buildTools: (store: TraceAnalysisStore) => AxFunction[]\n /** Recursion budget. `maxDepth: 0` disables subagents. */\n recursion?: { maxDepth: number; maxParallelSubagents?: number }\n /** Actor turn cap. Default 12. */\n maxTurns?: number\n /** Runtime char cap. Default 6000. */\n maxRuntimeChars?: number\n /** Cost classification surfaced in `registry.list()` and budget enforcement. */\n cost: AnalystCost\n /** Per-finding-row hook — kinds may reject / rewrite before lifting. */\n postProcess?: (row: RawAnalystFinding, ctx: AnalystContext) => RawAnalystFinding | null\n /** Optional optimizer hook — populated when a kind wants to fit its prompt against labeled examples. */\n goldens?: TraceAnalystGolden[]\n}\n\n/**\n * One labeled example consumed by Ax optimizers (MIPRO / GEPA / Bootstrap).\n * Each input is the same `{question}` an analyst would receive; `expected`\n * is the ground-truth finding set a fitted prompt should produce on this\n * input. Metric: kind-specific (default: F1 on `finding_id` overlap).\n */\nexport interface TraceAnalystGolden {\n question: string\n expected: ReadonlyArray<Omit<RawAnalystFinding, 'confidence'>>\n}\n\nexport interface CreateTraceAnalystKindOpts {\n /** AxAIService bound at registration time. */\n ai: AxAIService\n /** Optional model override; falls back to the AI service's default. */\n model?: string\n /** Override the spec's `version` (e.g. when an optimizer has fitted a new prompt). */\n versionSuffix?: string\n}\n\n/**\n * Build an `Analyst<TraceAnalysisStore>` from a kind spec.\n *\n * Lifts the Ax pipeline once at registration time so the registry\n * gets a stateless analyst. The Ax agent is freshly constructed per\n * `analyze()` call (the agent carries chat-log + usage state we don't\n * want shared across analyst runs).\n */\nexport function createTraceAnalystKind(\n spec: TraceAnalystKindSpec,\n opts: CreateTraceAnalystKindOpts,\n): Analyst<TraceAnalysisStore> {\n const version = opts.versionSuffix ? `${spec.version}+${opts.versionSuffix}` : spec.version\n return {\n id: spec.id,\n description: spec.description,\n inputKind: 'trace-store',\n cost: spec.cost,\n version,\n async analyze(store, ctx) {\n const tools = spec.buildTools(store)\n const maxDepth = spec.recursion?.maxDepth ?? 0\n const maxParallel = spec.recursion?.maxParallelSubagents ?? 2\n const priorContext = renderPriorFindings(ctx.priorFindings)\n\n const actorDescription =\n spec.actorDescription.trim() +\n priorContext +\n '\\n\\n' +\n RAW_FINDING_SCHEMA_PROMPT +\n '\\n\\nReturn the array in the `findings` output field. Use `final(...)` ' +\n 'with the structured `{ findings }` payload when you are done.'\n\n const ax = agent<{ question: string }, { findings: unknown[] }>(\n 'question:string -> findings:json[]',\n {\n agentIdentity: {\n name: spec.id,\n description: spec.description,\n },\n contextFields: ['question'],\n runtime: new AxJSRuntime({\n permissions: [],\n blockDynamicImport: true,\n allowedModules: [],\n freezeIntrinsics: true,\n blockShadowRealm: true,\n preventGlobalThisExtensions: false,\n }),\n mode: maxDepth > 0 ? 'advanced' : 'simple',\n recursionOptions: maxDepth > 0 ? { maxDepth } : undefined,\n maxTurns: spec.maxTurns ?? 12,\n maxRuntimeChars: spec.maxRuntimeChars ?? 6000,\n maxBatchedLlmQueryConcurrency: maxParallel,\n promptLevel: 'detailed',\n contextPolicy: { preset: 'full', budget: 'balanced' },\n functions: { local: tools },\n actorOptions: {\n description: actorDescription,\n ...(opts.model ? { model: opts.model } : {}),\n showThoughts: false,\n thinkingTokenBudget: 'none' as unknown as number,\n },\n responderOptions: {\n description:\n spec.responderDescription ??\n 'Format the structured `findings` array exactly as the actor produced it. Do not add, drop, or summarize entries.',\n ...(opts.model ? { model: opts.model } : {}),\n showThoughts: false,\n },\n bubbleErrors: [TraceFileMissingError],\n },\n )\n\n ctx.log?.(`analyst.kind ${spec.id} forward`, {\n max_depth: maxDepth,\n tool_count: tools.length,\n tags: ctx.tags,\n })\n\n const result = await ax.forward(opts.ai, { question: deriveQuestion(ctx, spec) })\n\n const expectedSubjects = KIND_EXPECTED_SUBJECTS[spec.id]\n const out: AnalystFinding[] = []\n const rawRows = Array.isArray(result.findings) ? result.findings : []\n let rejectedWrongKind = 0\n for (const row of rawRows) {\n const parsed = parseRawFinding(row, ctx.log)\n if (!parsed) continue\n // Subject-grammar check: if the kind has a declared expects-set\n // (every shipped kind does), the finding's subject MUST parse to\n // one of the declared variants. A wrong-kind subject is a\n // contract violation — the actor's prompt drifted from the\n // grammar — and we count it for prompt-audit visibility.\n if (expectedSubjects && parsed.subject !== undefined) {\n const parsedSubject = parseFindingSubject(parsed.subject)\n if (parsedSubject === null) {\n ctx.log?.('finding rejected: subject failed to parse', {\n kind: spec.id,\n subject: parsed.subject,\n })\n rejectedWrongKind += 1\n continue\n }\n if (!expectedSubjects.includes(parsedSubject.kind)) {\n ctx.log?.('finding rejected: subject variant not allowed for this kind', {\n kind: spec.id,\n subject_kind: parsedSubject.kind,\n subject: parsed.subject,\n allowed: expectedSubjects,\n })\n rejectedWrongKind += 1\n continue\n }\n }\n const postProcessed = spec.postProcess?.(parsed, ctx) ?? parsed\n if (!postProcessed) continue\n out.push(toAnalystFinding(spec, postProcessed))\n }\n\n ctx.log?.(`analyst.kind ${spec.id} done`, {\n emitted: rawRows.length,\n accepted: out.length,\n rejected_wrong_subject: rejectedWrongKind,\n })\n return out\n },\n }\n}\n\nfunction deriveQuestion(ctx: AnalystContext, spec: TraceAnalystKindSpec): string {\n // Kinds can be steered with a per-run focusing tag without recompiling\n // the actor description. Operators set `tags.focus = \"leaf-X\"` and the\n // kind's brief is concatenated with that focus for the actor prompt's\n // user message. Falls back to the spec id when no tag is present.\n const focus = ctx.tags?.focus?.trim()\n if (focus) return `${spec.id}: ${focus}`\n return spec.id\n}\n\nfunction toAnalystFinding(spec: TraceAnalystKindSpec, raw: RawAnalystFinding): AnalystFinding {\n return makeFinding({\n analyst_id: spec.id,\n area: spec.area,\n subject: raw.subject,\n claim: raw.claim,\n rationale: raw.rationale,\n severity: raw.severity,\n confidence: raw.confidence,\n evidence_refs: [\n {\n kind: evidenceKindFromUri(raw.evidence_uri),\n uri: raw.evidence_uri,\n excerpt: raw.evidence_excerpt,\n },\n ],\n recommended_action: raw.recommended_action,\n metadata: { kind_version: spec.version },\n })\n}\n\nfunction evidenceKindFromUri(uri: string): 'span' | 'artifact' | 'metric' | 'event' | 'finding' {\n if (uri.startsWith('span://')) return 'span'\n if (uri.startsWith('artifact://')) return 'artifact'\n if (uri.startsWith('metric://')) return 'metric'\n if (uri.startsWith('event://')) return 'event'\n if (uri.startsWith('finding://')) return 'finding'\n return 'artifact'\n}\n\n/**\n * Render a compact prior-findings block the actor reads alongside its\n * brief. Each row is one line so the actor can scan dozens cheaply.\n * The kind's prompt instructs the actor to (a) check whether a new\n * cluster matches a prior `finding_id` (carry the id forward via\n * `id_basis` to keep diffs stable) and (b) raise severity / confidence\n * when a prior finding has reappeared without remediation.\n *\n * Returns the empty string when there are no prior findings — most\n * runs are \"first-of-its-kind\" and the prompt stays unchanged.\n *\n * Exported for tests + for consumers that build their own actor\n * prompts (e.g. specialized analysts living outside the default kinds).\n */\nexport function renderPriorFindings(prior: AnalystContext['priorFindings']): string {\n if (!prior || prior.length === 0) return ''\n const MAX_ROWS = 40 // keep the block under ~2KB; older history is summarized externally\n const rows = prior.slice(0, MAX_ROWS).map((f) => {\n const subject = f.subject ? ` [${f.subject}]` : ''\n return ` - id=${f.finding_id} ${f.severity}${subject} ${truncateForContext(f.claim, 160)}`\n })\n const overflow =\n prior.length > MAX_ROWS\n ? `\\n ... +${prior.length - MAX_ROWS} more prior findings (older history truncated)`\n : ''\n return [\n '',\n '',\n 'PRIOR FINDINGS (from a previous run on related data):',\n 'When the work you do now matches a row below, REUSE the `finding_id` (pass it as `id_basis`) so the cross-run diff stays stable.',\n 'A finding that reappears with no remediation evidence SHOULD raise its `confidence` and may justify a higher `severity`.',\n ...rows,\n overflow,\n ]\n .filter(Boolean)\n .join('\\n')\n}\n\nfunction truncateForContext(s: string, max: number): string {\n if (s.length <= max) return s\n return `${s.slice(0, max - 1).trimEnd()}…`\n}\n","/**\n * Pre-curated tool subsets for analyst kinds.\n *\n * The full trace-analyst tool set is seven functions. Most kinds only\n * need three or four. Picking from named groups instead of importing\n * the whole bundle keeps every kind's actor-context budget tight and\n * makes \"what can this analyst see?\" obvious at registration time.\n *\n * Each function in the group keeps its full `name`/`description` from\n * `buildTraceAnalystTools` — we filter, we don't re-implement.\n */\n\nimport type { AxFunction } from '@ax-llm/ax'\nimport type { TraceAnalysisStore } from '../trace-analyst/store'\nimport { buildTraceAnalystTools } from '../trace-analyst/tools'\n\n/** Named tool sets. Kinds pass `tools: TRACE_TOOL_GROUPS.failureForensics` etc. */\nexport type TraceToolGroupName =\n /** All seven tools. Use for open-ended discovery kinds. */\n | 'all'\n /** Overview + paginated query + count. No deep reads. Cheap. */\n | 'discovery'\n /** Discovery + viewTrace + viewSpans. Deep-read but no regex search. */\n | 'discoveryAndRead'\n /** Discovery + search tools. For pattern-matching across many traces. */\n | 'discoveryAndSearch'\n /** Discovery + viewSpans + searchSpan. Targeted-span work after another kind narrows down. */\n | 'targeted'\n\nconst TOOL_NAMES_BY_GROUP: Record<TraceToolGroupName, ReadonlySet<string>> = {\n all: new Set(),\n discovery: new Set(['getDatasetOverview', 'queryTraces', 'countTraces']),\n discoveryAndRead: new Set([\n 'getDatasetOverview',\n 'queryTraces',\n 'countTraces',\n 'viewTrace',\n 'viewSpans',\n ]),\n discoveryAndSearch: new Set([\n 'getDatasetOverview',\n 'queryTraces',\n 'countTraces',\n 'searchTrace',\n 'searchSpan',\n ]),\n targeted: new Set(['getDatasetOverview', 'queryTraces', 'viewSpans', 'searchSpan']),\n}\n\n/**\n * Build the tool set for a named group bound to a specific trace store.\n *\n * `all` returns every tool. Other groups filter `buildTraceAnalystTools`\n * by name to the documented subset. An unrecognised group name throws —\n * silently returning all tools would defeat the cost-control point.\n */\nexport function buildTraceToolsForGroup(\n group: TraceToolGroupName,\n store: TraceAnalysisStore,\n): AxFunction[] {\n const all = buildTraceAnalystTools({ store })\n if (group === 'all') return all\n const allow = TOOL_NAMES_BY_GROUP[group]\n if (!allow) throw new Error(`unknown trace tool group: ${group}`)\n return all.filter((tool) => allow.has((tool as { name: string }).name))\n}\n","/**\n * Failure-mode analyst — classifies what went wrong and why.\n *\n * Brief: read the trace dataset, identify the top failure modes across\n * runs, classify each with severity + evidence, and surface them as\n * findings. The actor's job is *taxonomy + evidence*, not fix-design —\n * that's the improvement-analyst's job.\n *\n * Recursion is deep (`maxDepth: 3`) because real failure-mode\n * discovery is genuinely tree-shaped: the actor splits the dataset\n * into candidate clusters, each cluster spawns a focused investigator\n * that drills into representative traces, and a deeply-recursed\n * investigator may itself split a confounded mode into two sub-modes.\n * Each level fans out 4-way, so the analyst can investigate up to\n * ~16 leaf clusters before hitting the depth ceiling.\n */\n\nimport type { TraceAnalystKindSpec } from '../kind-factory'\nimport { buildTraceToolsForGroup } from '../tool-groups'\n\nconst ACTOR_PROMPT = `You are a failure-mode classifier for an OTLP trace dataset. Your job is to identify the **distinct ways agents failed** in this dataset, not to grade individual runs.\n\nDISCOVERY → CLUSTER → CITE protocol:\n\n1. Call \\`traces.getDatasetOverview({})\\` first. Use \\`has_errors\\`, \\`models\\`, \\`agent_names\\`, \\`tools\\`, and \\`sample_trace_ids\\` to size the failure surface.\n2. Use \\`traces.queryTraces({ filters: { has_errors: true }, limit })\\` to pull error-bearing traces. Combine with \\`traces.countTraces\\` to see what fraction of the dataset failed.\n3. For each candidate failure cluster, use \\`traces.searchTrace\\` with regex like \\`STATUS_CODE_ERROR\\`, \\`MaxTurnsExceeded\\`, \\`assertion\\`, \\`unauthorized\\`, \\`timeout\\`, \\`429\\`, \\`5\\\\d\\\\d\\`, the agent's specific error strings, or the names of its tools. Pull one or two representative traces per cluster, **not all** of them.\n4. **Cluster, do not enumerate.** Two failures with the same root cause should be ONE finding citing both traces, not two findings. The point of this analyst is to compress N runs into K modes.\n5. For each cluster you can defend with evidence, emit ONE finding with:\n - \\`area\\` = \"failure-mode\"\n - \\`subject\\` = a short label for the cluster (\"tool-call-loop\", \"auth-revoked-mid-run\", \"agent-asked-clarification-too-late\", ...)\n - \\`claim\\` = one sentence stating the mode\n - \\`severity\\` = \"critical\" when it blocks the run, \"high\" when the run finished degraded, \"medium\" when it slowed convergence\n - \\`evidence_uri\\` = \\`span://<trace_id>/<span_id>\\` of the most representative span\n - \\`evidence_excerpt\\` = the exact quote (e.g. error message, stuck tool call payload, contradictory turn output)\n - \\`confidence\\` = 0.85+ when multiple traces show the same shape; 0.6-0.8 for a single-trace inference; <0.5 for speculative.\n - \\`recommended_action\\` = imperative-phrased fix idea (kept short — the improvement-analyst will expand on these)\n\nIf the dataset has no failures, return an empty findings array — do NOT pad with low-confidence speculation.\n\n**Delegate aggressively.** The recursion budget is there to be used:\n- After your first \\`getDatasetOverview\\` + \\`queryTraces\\` calls, you should have 3-6 candidate failure clusters in mind. Spawn one \\`llmQuery\\` per cluster in a single batch — they investigate in parallel.\n- A sub-investigator that finds its cluster is actually two distinct modes should split again at its own level. Recursion is meant to discover sub-modes, not to do trivial drilling that the parent could do in-line.\n- Pass narrow context to each subagent: { question: 'investigate the auth-revoked-mid-run cluster', context: { trace_ids: ['abc', 'def'], suspected_root_cause: 'token refresh skipped on idle sessions' } }. Subagents need enough context to skip re-discovery but not the whole conversation.\n- Each subagent returns its findings as JSON; the parent merges them. Do NOT have subagents call \\`final()\\` — they return their findings list to you, and you call \\`final()\\` once at the top.\n\nOBSERVABILITY rules:\n- Each non-final turn must emit at least one \\`console.log\\` for evidence.\n- Reuse runtime variables across turns; don't recompute.\n- Call \\`final({ findings: [...] })\\` exactly once, after you've gathered evidence for every cluster you intend to report.`\n\nexport const FAILURE_MODE_KIND_SPEC: TraceAnalystKindSpec = {\n id: 'failure-mode',\n description:\n 'Clusters trace-dataset failures into distinct failure modes with cited evidence and a short recommended action.',\n area: 'failure-mode',\n version: '1.0.0',\n actorDescription: ACTOR_PROMPT,\n buildTools: (store) => buildTraceToolsForGroup('all', store),\n recursion: { maxDepth: 3, maxParallelSubagents: 4 },\n maxTurns: 24,\n cost: { kind: 'llm' },\n}\n","/**\n * Improvement analyst — actionable, recursive self-improvement findings.\n *\n * Brief: read findings from upstream analysts (failure-mode,\n * knowledge-gap, knowledge-poisoning) AND the trace dataset itself,\n * then propose **concrete edits** to the agent's runtime: prompt\n * additions, RAG documents to ingest, tool descriptions to rewrite,\n * scaffolding changes to make, memory entries to invalidate. Each\n * finding is one proposed edit with the locus, the diff, and the\n * expected effect.\n *\n * This is the recursive-self-improvement loop's last mile: the prior\n * kinds describe *what's wrong*; this kind describes *what to change*.\n *\n * Recursion is deep (`maxDepth: 3`) because real improvement proposals\n * are competitive: for each failure-mode there are usually 2-3 viable\n * fix directions (tighten prompt vs add tool vs adjust scaffolding),\n * and the actor should explore each with a focused subagent before\n * picking the highest-leverage one to recommend.\n */\n\nimport type { TraceAnalystKindSpec } from '../kind-factory'\nimport { buildTraceToolsForGroup } from '../tool-groups'\n\nconst ACTOR_PROMPT = `You are a recursive-self-improvement analyst. Your job is to propose **concrete, locus-named edits** the agent's runtime should adopt to fix the failure modes, knowledge gaps, and poisonings present in this dataset.\n\nUpstream analysts have already classified the problems. Your job is to convert each problem into a *change to make* and grade its expected leverage. Each finding is one proposed edit.\n\nDISCOVERY → CANDIDATE-FIXES → COMPETE → CITE protocol:\n\n1. \\`traces.getDatasetOverview({})\\` first. Note the agents, tools, and any system-prompt fingerprints (look for the prompt text echoed in early spans).\n2. For each high-severity failure pattern, generate 2-3 candidate fixes. Real candidate axes:\n - **System-prompt edit** — add an instruction, remove a misleading one, restructure precedence\n - **Tool description edit** — rewrite a tool's description so the agent picks it correctly / passes valid args\n - **New tool** — add a tool the agent kept emulating in code\n - **RAG ingestion** — add a document or correct a stale one\n - **Memory invalidation** — clear cached prior-run decisions that no longer apply\n - **Scaffolding** — add a precondition check, a retry policy, a turn budget, a verification step\n - **Output schema** — narrow the agent's output to forbid the failure shape\n3. **Compete candidate fixes via subagents.** For each failure cluster, spawn one \\`llmQuery\\` per candidate-fix axis you want to evaluate. Each subagent's job: simulate the fix on the cited traces and report (i) likely effect, (ii) side effects, (iii) implementation cost as small/medium/large. Pass the cluster's failing trace_ids and the candidate axis as context.\n4. After subagents return, **pick the winning candidate per cluster** based on (effect / cost) and emit ONE finding. Discard the losing candidates — the output is the recommendation, not the candidate set.\n5. **Cross-reference upstream findings.** If a finding cites a prior failure-mode or knowledge-gap finding, use \\`evidence_uri = \"finding://<prior-finding-id>\"\\` (the registry supports this kind). This builds the dependency graph that lets the dashboard show \"fix #X resolves failure modes A, B, C.\"\n\nFor each winning recommendation, emit ONE finding with:\n- \\`area\\` = \"improvement\"\n- \\`subject\\` = the locus to edit: \\`system-prompt:<section>\\`, \\`tool-doc:<tool-name>\\`, \\`new-tool:<proposed-name>\\`, \\`rag:<corpus>:<doc-id>\\`, \\`memory:<key>\\`, \\`scaffolding:<concern>\\`, \\`output-schema:<field>\\`\n- \\`claim\\` = one sentence stating the edit (\"Add a precondition check to refuse tool X calls without arg Y\")\n- \\`severity\\` = leverage rating: \"critical\" when fix resolves a critical failure mode; \"high\" when it resolves a high; \"medium\" when it's a quality-of-life win; \"info\" when it's a cleanup with no behavioral effect\n- \\`evidence_uri\\` = the failure-mode finding id this fix targets (\\`finding://<id>\\`) when it exists; else the most representative span\n- \\`evidence_excerpt\\` = a fragment showing the problem the fix targets\n- \\`confidence\\` = 0.85+ when the fix is mechanical and the failure mode is well-evidenced; 0.6-0.8 when the fix requires judgment; <0.5 for speculative\n- \\`rationale\\` = why this candidate beat its alternatives (2 sentences max)\n- \\`recommended_action\\` = the **literal edit**, phrased as a diff or a quoted replacement: \"Replace section X with: '...'\" or \"Add tool with description: '...'\" or \"Set retry policy to max_attempts=3 with exponential backoff\"\n\nIf no upstream failure findings exist in this run, derive your own from the trace dataset using the failure-mode protocol inline (\\`searchTrace\\` for STATUS_CODE_ERROR / MaxTurnsExceeded / etc.). But prefer to consume upstream findings when present — the kinds are designed to chain.\n\nDo NOT propose a fix you cannot defend with evidence. \"Tighten the prompt\" is not a finding; \"Add 'When the user asks for X, always Y' to the system prompt section \"request-classification\"\" is.\n\nOBSERVABILITY rules:\n- Each non-final turn must emit at least one \\`console.log\\` for evidence.\n- Call \\`final({ findings: [...] })\\` exactly once at the top level.`\n\nexport const IMPROVEMENT_KIND_SPEC: TraceAnalystKindSpec = {\n id: 'improvement',\n description:\n 'Converts upstream failure / gap / poisoning findings into concrete locus-named edits (prompt, tool-doc, RAG, scaffolding) with leverage grades.',\n area: 'improvement',\n version: '1.0.0',\n actorDescription: ACTOR_PROMPT,\n buildTools: (store) => buildTraceToolsForGroup('all', store),\n recursion: { maxDepth: 3, maxParallelSubagents: 4 },\n maxTurns: 30,\n maxRuntimeChars: 12000,\n cost: { kind: 'llm' },\n}\n","/**\n * Knowledge-gap analyst — what did the agent NOT know that it needed?\n *\n * Brief: find moments in the trace where the agent had to guess, ask\n * the user to fill in context, recover from a wrong assumption, or\n * loop on a retrieval. Each finding names a *missing or outdated piece\n * of knowledge* the agent's curated knowledge base should have held —\n * or a downstream lookup (web, docs, tool description) that surfaced\n * stale or outdated information.\n *\n * The primary expected store is `@tangle-network/agent-knowledge`: a\n * Karpathy-style wiki the agent maintains with raw ↔ curated pages,\n * source anchors, and claim/relation triples. A gap is anything the\n * agent had to discover at run-time that should already have lived\n * there. Secondary loci: web-search results that returned outdated\n * pages, tool descriptions that omitted critical behavior, system-\n * prompt sections that didn't cover the case.\n *\n * Distinct from failure-mode: failure-mode classifies *how* it broke;\n * knowledge-gap names the *information* whose absence (or staleness)\n * caused the break. One failure-mode often maps to several gaps.\n *\n * Recursion (`maxDepth: 2`) is enough to fan out one subagent per\n * candidate gap-source layer; each subagent runs a focused detection.\n */\n\nimport type { TraceAnalystKindSpec } from '../kind-factory'\nimport { buildTraceToolsForGroup } from '../tool-groups'\n\nconst ACTOR_PROMPT = `You are a knowledge-gap analyst for an OTLP trace dataset. Your job is to identify the **specific pieces of information the agent lacked, or that were stale**, that caused poor decisions.\n\nThe agent under analysis maintains a curated knowledge base via \\`@tangle-network/agent-knowledge\\` — a wiki of \\`KnowledgePage\\`s with raw source anchors, claims, and relations. The primary expected store of agent-knowable facts IS that wiki. A \"knowledge gap\" is anything the agent had to discover or guess at run-time that the wiki should have held — or an outdated/contradictory fact the agent picked up from a non-wiki source.\n\nDISCOVERY → ATTRIBUTE-TO-LAYER → CITE protocol:\n\n1. \\`traces.getDatasetOverview({})\\` first. Note which agents, tools, and models appear.\n2. Pull traces where the agent shows gap signals. The strongest signals are:\n - Self-correction turns (\"I assumed X but…\", \"let me re-check\", \"actually,\")\n - Clarifying-question turns where the agent asked the user something the runtime should have surfaced\n - Repeated retrieval / lookup calls for the same artifact with slightly varied queries\n - Tool errors that name a missing argument or unknown resource\n - Web-search calls returning pages dated before a known cutoff for content that changes (versioned APIs, schemas, policies)\n - Agent quoting a tool's docs / system prompt incorrectly because the actual text was insufficient\n - Fabricated identifiers that don't appear in dataset \\`sample_trace_ids\\`\n Use \\`traces.searchTrace\\` with patterns like \\`I (don.?t|do not) know\\`, \\`assumed\\`, \\`unclear\\`, \\`could you (clarify|tell me|provide)\\`, \\`not found\\`, \\`undefined\\`, \\`unknown\\`, \\`null\\`, dates older than the analysis window, or the agent's specific clarification phrases.\n3. For each gap, identify the **layer of the runtime that should have prevented it**. The locus is the value of \\`subject\\` on the finding. Use one of:\n - \\`agent-knowledge:wiki:<page-slug>\\` — the wiki page that should exist but doesn't, or exists but lacks the claim\n - \\`agent-knowledge:wiki:<page-slug>#<heading>\\` — wiki page exists but a specific section is missing\n - \\`agent-knowledge:claim:<topic>\\` — a specific claim/relation triple that should be in the wiki\n - \\`agent-knowledge:raw:<source-id>\\` — raw source captured but never lifted into a curated page\n - \\`agent-knowledge:stale:<page-slug>\\` — wiki page exists but contradicts ground-truth evidence in this trace (the wiki itself drifted)\n - \\`websearch:outdated:<topic>\\` — agent relied on a web result that was stale; wiki should have superseded it\n - \\`tool-doc:<tool-name>:<aspect>\\` — tool description missed a behavior aspect (return shape, failure modes, side effects)\n - \\`system-prompt:<section>\\` — system prompt should have stated the rule directly\n - \\`memory:<key>\\` — prior-run memory should have surfaced an earlier decision\n4. For each gap you can defend with evidence, emit ONE finding with:\n - \\`area\\` = \"knowledge-gap\"\n - \\`subject\\` = the locus string from the list above\n - \\`claim\\` = a sentence naming the missing or stale knowledge (\"wiki has no page on invoice line-item shape, agent had to re-derive it from raw spans\")\n - \\`severity\\` = \"high\" when the gap caused a failure or a clarifying question; \"medium\" when it caused unnecessary turns; \"low\" when it caused minor inefficiency\n - \\`evidence_uri\\` = \\`span://<trace_id>/<span_id>\\` of the moment the gap surfaced (the question, the self-correction, the retrieval miss, the stale web result)\n - \\`evidence_excerpt\\` = exact quote where the agent showed the gap\n - \\`confidence\\` = 0.85+ when the agent itself articulated the gap; 0.6-0.8 when inferred from behavior\n - \\`recommended_action\\` = phrased as a wiki edit when the locus is \\`agent-knowledge:*\\` (\"Create wiki page \\`invoice-line-items\\` with claims: ...\"), or as a prompt/tool-doc edit otherwise\n\n**Delegate per layer.** After your first scan, you should have candidates spread across \\`agent-knowledge:*\\`, \\`websearch:outdated\\`, \\`tool-doc:*\\`, \\`system-prompt:*\\`, and \\`memory:*\\`. Spawn one \\`llmQuery\\` per layer in parallel — each subagent runs a focused detection (e.g. the \\`agent-knowledge\\` subagent looks for both missing-pages AND stale-pages; the \\`websearch\\` subagent looks specifically for date staleness signals; the \\`tool-doc\\` subagent looks for tool-call argument errors a fuller description would have prevented). Subagents return findings; you merge and emit one \\`final({ findings })\\` at the top.\n\nDo NOT report a gap that the agent later recovered from cleanly within the same turn — that's resilience, not a gap. Cite the *non-recovery* version when both exist.\n\nOBSERVABILITY rules:\n- Each non-final turn must emit at least one \\`console.log\\` for evidence.\n- Call \\`final({ findings: [...] })\\` exactly once at the top level.`\n\nexport const KNOWLEDGE_GAP_KIND_SPEC: TraceAnalystKindSpec = {\n id: 'knowledge-gap',\n description:\n 'Identifies missing or stale pieces of knowledge — primarily against the agent-knowledge wiki — and attributes each to the runtime layer (wiki page, claim, raw source, websearch, tool-doc, system-prompt, memory) that should have held it.',\n area: 'knowledge-gap',\n version: '1.0.0',\n actorDescription: ACTOR_PROMPT,\n buildTools: (store) => buildTraceToolsForGroup('discoveryAndSearch', store),\n recursion: { maxDepth: 2, maxParallelSubagents: 4 },\n maxTurns: 18,\n cost: { kind: 'llm' },\n}\n","/**\n * Knowledge-poisoning analyst — what FALSE information misled the agent?\n *\n * Brief: find moments where the agent acted on information that was\n * *wrong* — stale memory, RAG documents that contradicted ground truth,\n * tool descriptions that lied about return shapes, system-prompt\n * instructions that no longer matched reality, prior-run summaries that\n * cached a wrong decision.\n *\n * Distinct from knowledge-gap: a gap is \"the agent didn't know X\"; a\n * poisoning is \"the agent confidently used X, but X was wrong.\" Gaps\n * surface as questions / self-correction; poisonings surface as\n * confident-but-wrong actions that downstream evidence contradicts.\n *\n * Recursion is moderate (`maxDepth: 2`) because each candidate\n * poisoning typically needs two sub-investigations: one to confirm\n * the agent acted on the false belief, one to confirm the belief\n * itself is actually false in ground truth.\n */\n\nimport type { TraceAnalystKindSpec } from '../kind-factory'\nimport { buildTraceToolsForGroup } from '../tool-groups'\n\nconst ACTOR_PROMPT = `You are a knowledge-poisoning analyst for an OTLP trace dataset. Your job is to identify cases where the agent **confidently used wrong information** — not where it lacked information (that's the knowledge-gap analyst).\n\nDISCOVERY → DUAL-VERIFY → CITE protocol:\n\n1. \\`traces.getDatasetOverview({})\\` first. Identify the agents, models, and tools.\n2. Pull traces where the agent's confident action was later contradicted. Strongest signals:\n - Agent stated a fact in one span; a later span surfaced contradictory evidence; the agent then proceeded anyway or fabricated reconciliation.\n - Tool call with stale arguments (an id that no longer exists, an API shape that changed).\n - Agent cited an \\`agent-knowledge\\` wiki page or claim whose content contradicts the trace's own evidence — the wiki itself drifted.\n - Web-search result the agent cited that returned an outdated page; agent treated it as canonical.\n - System-prompt instruction the agent followed that ground-truth evidence in the trace contradicts (e.g. prompt says \"use endpoint A\"; tool reply says \"endpoint A deprecated, use B\").\n - Repeated wrong-shape parsing despite the tool's actual output proving the shape.\n3. Use \\`traces.searchTrace\\` with regex on phrases like \\`actually\\`, \\`turns out\\`, \\`previously assumed\\`, \\`old version\\`, \\`deprecated\\`, \\`updated to\\`, \\`now uses\\`, or specific entity names you suspect have changed.\n4. For each candidate poisoning, **DUAL-VERIFY**:\n - Confirm the agent actually acted on the false belief (cite the span where it did)\n - Confirm the belief is actually false in this trace's own evidence (cite the span that contradicts it)\n Only emit a finding when both halves are nailed down. If you can only nail one, drop it — single-evidence poisoning findings are too speculative to be useful.\n\n**Delegate the dual-verify.** Use the recursion budget so each candidate poisoning gets one subagent investigating \"did the agent act?\" and one investigating \"is the belief false?\". After your first scan, fire off N parallel \\`llmQuery\\` pairs (one cluster per pair). Subagents return their findings; you accept only the ones where BOTH halves of the pair were confirmed.\n\nFor each confirmed poisoning, emit ONE finding with:\n- \\`area\\` = \"knowledge-poisoning\"\n- \\`subject\\` = the source of the false belief, one of: \\`agent-knowledge:wiki:<page-slug>\\` (wiki page contradicts current ground truth), \\`agent-knowledge:claim:<topic>\\` (a specific claim/relation went stale), \\`agent-knowledge:raw:<source-id>\\` (the raw source is outdated and the wiki inherited the drift), \\`websearch:outdated:<url-or-topic>\\`, \\`tool-doc:<tool>\\`, \\`system-prompt:<section>\\`, \\`memory:<key>\\`, \\`prior-run-summary:<topic>\\`\n- \\`claim\\` = one sentence: \"agent believed X (from source S); evidence in trace shows X is false\"\n- \\`severity\\` = \"critical\" when poisoning caused a wrong user-visible action; \"high\" when caught internally but wasted significant work; \"medium\" for inefficiency only\n- \\`evidence_uri\\` = \\`span://<trace_id>/<span_id>\\` of the action span (the moment the agent acted on the false belief)\n- \\`evidence_excerpt\\` = exact quote of the confident-but-wrong claim or action\n- \\`confidence\\` = 0.85+ when both halves are exact-quote backed; 0.6-0.8 when one half is inferred\n- \\`recommended_action\\` = where the source should be updated and how (\"Update wiki page \\`X\\` claim \\`Y\\` to '...'\", \"Invalidate raw source \\`Z\\` and re-curate\", \"Replace system-prompt section X with 'tool foo now returns Y'\")\n\nDo NOT report a finding if the agent caught and corrected the false belief in the same turn — that's the system working. Reserve poisoning for cases where the false belief shaped downstream action.\n\nOBSERVABILITY rules:\n- Each non-final turn must emit at least one \\`console.log\\` for evidence.\n- Call \\`final({ findings: [...] })\\` exactly once at the top level.`\n\nexport const KNOWLEDGE_POISONING_KIND_SPEC: TraceAnalystKindSpec = {\n id: 'knowledge-poisoning',\n description:\n 'Identifies confident-but-wrong actions caused by stale memory, contradicting RAG, deprecated tool docs, or outdated system-prompt instructions.',\n area: 'knowledge-poisoning',\n version: '1.0.0',\n actorDescription: ACTOR_PROMPT,\n buildTools: (store) => buildTraceToolsForGroup('all', store),\n recursion: { maxDepth: 2, maxParallelSubagents: 4 },\n maxTurns: 20,\n cost: { kind: 'llm' },\n}\n","/**\n * Default analyst kinds focused on agent failure + recursive\n * self-improvement.\n *\n * The four kinds chain: failure-mode classifies; knowledge-gap and\n * knowledge-poisoning explain *why* in two orthogonal ways; improvement\n * proposes concrete edits. Register all four against the same trace\n * store and the registry runs them in dependency order if the operator\n * pipes findings between them.\n */\n\nexport { FAILURE_MODE_KIND_SPEC } from './failure-mode'\nexport { IMPROVEMENT_KIND_SPEC } from './improvement'\nexport { KNOWLEDGE_GAP_KIND_SPEC } from './knowledge-gap'\nexport { KNOWLEDGE_POISONING_KIND_SPEC } from './knowledge-poisoning'\n\nimport type { TraceAnalystKindSpec } from '../kind-factory'\nimport { FAILURE_MODE_KIND_SPEC } from './failure-mode'\nimport { IMPROVEMENT_KIND_SPEC } from './improvement'\nimport { KNOWLEDGE_GAP_KIND_SPEC } from './knowledge-gap'\nimport { KNOWLEDGE_POISONING_KIND_SPEC } from './knowledge-poisoning'\n\n/**\n * The default kind suite. Order is the run order operators should\n * use: failure-mode first (no upstream deps), gap + poisoning next\n * (both depend on failures), improvement last (chains all three).\n */\nexport const DEFAULT_TRACE_ANALYST_KINDS: readonly TraceAnalystKindSpec[] = [\n FAILURE_MODE_KIND_SPEC,\n KNOWLEDGE_GAP_KIND_SPEC,\n KNOWLEDGE_POISONING_KIND_SPEC,\n IMPROVEMENT_KIND_SPEC,\n] as const\n","/**\n * Skill-usage analyst — a DETERMINISTIC `Analyst` over a Claude/Codex skill\n * library + its trace corpus. Unlike the trace-store kinds (failure-mode,\n * improvement, ...) this kind calls no LLM: it mines real usage and skill\n * structure and emits findings by rule.\n *\n * It exists because the naive \"Skill-tool invocation count\" lies low — it\n * misses orchestrated sub-dispatch (a leaf skill run BY /pursue or /governor\n * logs under the parent), slash-command entry, local-script bypass, and\n * on-disk artifacts. The 2026-05-30 skill audit found 39/53 skills at zero\n * direct invocations, yet only one was a genuine cut: the rest were\n * measurement-invisible or discovery-limited. This analyst encodes that\n * lesson as a multi-signal usage model so a cheap repeatable pass can keep\n * the library honest, and so the expensive audit workflow's verdicts can\n * GEPA-distill it toward agreement (see `gold/skill-verdicts.gold.jsonl`).\n *\n * Report-building (`buildSkillUsageReport`, an fs scan) is separated from\n * finding emission (`SkillUsageAnalyst.analyze`, pure) so the slow scan runs\n * once at the registry boundary and the rule logic stays unit-testable.\n */\n\nimport { existsSync, readdirSync, readFileSync, statSync } from 'node:fs'\nimport { join } from 'node:path'\nimport type {\n Analyst,\n AnalystContext,\n AnalystFinding,\n AnalystSeverity,\n} from '../types'\nimport { computeFindingId } from '../types'\n\n// ── Input model ──────────────────────────────────────────────────────\n\nexport type SkillKind = 'public' | 'private'\n\n/** One skill's multi-signal usage + structure. All counts are deterministic. */\nexport interface SkillUsageRecord {\n name: string\n kind: SkillKind\n /** Absolute path to the skill's SKILL.md. */\n path: string\n lines: number\n /** `\"skill\":\"<name>\"` Skill-tool invocations across the trace corpus. */\n directInvocations: number\n /** `<command-name>/<name>` slash invocations across the trace corpus. */\n slashInvocations: number\n /** Sibling skills whose SKILL.md dispatches to this one (`/<name>`). Proxy\n * for orchestrated sub-dispatch the per-skill counter cannot see. */\n inboundRefs: number\n /** On-disk artifacts attributable to the skill (e.g. `.evolve/<name>/**`). */\n artifactCount: number\n /** Tangle-private reference count in the body (leak signal for public skills). */\n tanglePrivateRefs: number\n hasReferencesDir: boolean\n hasEvalsDir: boolean\n /** Body mentions `skill-runs.jsonl` (visible to /reflect + /governor). */\n logsRuns: boolean\n /** Description carries an explicit `Triggers:` clause / trigger phrases. */\n hasTriggerPhrases: boolean\n}\n\nexport interface SkillUsageReport {\n generatedFromTraces: number\n records: SkillUsageRecord[]\n}\n\nexport interface SkillUsageScanConfig {\n /** Dirs holding `*.jsonl` transcripts (Claude `~/.claude/projects`, Codex sessions). */\n transcriptDirs: string[]\n /** Skill roots to scan; each dir directly under `root` with a `SKILL.md` is a skill. */\n skillRoots: { root: string; kind: SkillKind }[]\n /** Roots scanned for `<root>/.evolve/<skill>` artifact dirs. */\n artifactRoots?: string[]\n /** Token-prefixed mappings: skill name → extra artifact subpaths under an artifactRoot\n * (e.g. reflect → `.evolve/reflections`). Catches non-eponymous artifact dirs. */\n artifactAliases?: Record<string, string[]>\n /** Cap files read per transcript dir (bounds a huge corpus); 0 = unbounded. */\n maxTranscriptsPerDir?: number\n}\n\n// ── Deterministic thresholds ─────────────────────────────────────────\n\n/** Anthropic's authoring guidance keeps SKILL.md short; past this with no\n * `references/` split the body burns context budget every session. */\nconst BLOAT_LINE_THRESHOLD = 300\n\nconst TANGLE_PRIVATE_RE =\n /\\b(cli-bridge|tangletools|ops-board|drew-gtr-pro|@tangle-network\\/|~\\/company|tangle\\.tools|gtm-agent)\\b|\\bkimi\\b|\\btcloud\\b/gi\nconst TRIGGER_RE = /triggers?\\s*[:\\-]/i\n\n// ── Report builder (fs scan — slow, runs once at the registry boundary) ──\n\nfunction listSkillDirs(root: string): { name: string; path: string }[] {\n if (!existsSync(root)) return []\n const out: { name: string; path: string }[] = []\n for (const entry of readdirSync(root, { withFileTypes: true })) {\n if (!entry.isDirectory() && !entry.isSymbolicLink()) continue\n const skillMd = join(root, entry.name, 'SKILL.md')\n if (existsSync(skillMd)) out.push({ name: entry.name, path: skillMd })\n }\n return out\n}\n\nfunction walkJsonl(dir: string, cap: number): string[] {\n if (!existsSync(dir)) return []\n const files: string[] = []\n const stack = [dir]\n while (stack.length) {\n const cur = stack.pop()!\n let entries\n try {\n entries = readdirSync(cur, { withFileTypes: true })\n } catch {\n continue\n }\n for (const e of entries) {\n const full = join(cur, e.name)\n if (e.isDirectory()) stack.push(full)\n else if (e.name.endsWith('.jsonl')) {\n files.push(full)\n if (cap > 0 && files.length >= cap) return files\n }\n }\n }\n return files\n}\n\nfunction frontmatterDescription(body: string): string {\n const fm = /^---\\n([\\s\\S]*?)\\n---/.exec(body)\n const block = fm?.[1] ?? ''\n const m = /description:\\s*(.+)/i.exec(block)\n return m?.[1] ?? ''\n}\n\nfunction countArtifacts(roots: string[], name: string, aliases: string[]): number {\n let n = 0\n for (const root of roots) {\n const candidates = [join(root, '.evolve', name), ...aliases.map((a) => join(root, a))]\n for (const dir of candidates) {\n if (!existsSync(dir)) continue\n try {\n if (statSync(dir).isDirectory()) n += readdirSync(dir).length\n else n += 1\n } catch {\n /* unreadable — skip */\n }\n }\n }\n return n\n}\n\n/** Scan the corpus + skill roots into a {@link SkillUsageReport}. Deterministic. */\nexport function buildSkillUsageReport(config: SkillUsageScanConfig): SkillUsageReport {\n const skills = config.skillRoots.flatMap(({ root, kind }) =>\n listSkillDirs(root).map((s) => ({ ...s, kind })),\n )\n const names = skills.map((s) => s.name)\n\n // One pass over the corpus accumulating direct + slash counts per skill.\n const direct = new Map<string, number>(names.map((n) => [n, 0]))\n const slash = new Map<string, number>(names.map((n) => [n, 0]))\n const skillRe = /\"skill\"\\s*:\\s*\"([a-z0-9_:-]+)\"/g\n const cmdRe = /<command-name>\\/?([a-z0-9_:-]+)<\\/command-name>/g\n let transcripts = 0\n for (const dir of config.transcriptDirs) {\n for (const file of walkJsonl(dir, config.maxTranscriptsPerDir ?? 0)) {\n transcripts += 1\n let data: string\n try {\n data = readFileSync(file, 'utf8')\n } catch {\n continue\n }\n for (const m of data.matchAll(skillRe)) {\n const g = m[1]\n if (!g) continue\n const n = g.split(':').pop() ?? g\n const prev = direct.get(n)\n if (prev !== undefined) direct.set(n, prev + 1)\n }\n for (const m of data.matchAll(cmdRe)) {\n const g = m[1]\n if (g === undefined) continue\n const prev = slash.get(g)\n if (prev !== undefined) slash.set(g, prev + 1)\n }\n }\n }\n\n // Read each skill body once; compute structure + inbound refs across siblings.\n const bodies = new Map<string, string>()\n for (const s of skills) {\n try {\n bodies.set(s.name, readFileSync(s.path, 'utf8'))\n } catch {\n bodies.set(s.name, '')\n }\n }\n const inbound = new Map<string, number>(names.map((n) => [n, 0]))\n for (const target of names) {\n const ref = new RegExp(`/${target}\\\\b|\\\\[\\\\[${target}\\\\]\\\\]`)\n for (const s of skills) {\n if (s.name === target) continue\n if (ref.test(bodies.get(s.name) ?? '')) inbound.set(target, inbound.get(target)! + 1)\n }\n }\n\n const records: SkillUsageRecord[] = skills.map((s) => {\n const body = bodies.get(s.name) ?? ''\n const dir = s.path.replace(/\\/SKILL\\.md$/, '')\n return {\n name: s.name,\n kind: s.kind,\n path: s.path,\n lines: body ? body.split('\\n').length : 0,\n directInvocations: direct.get(s.name) ?? 0,\n slashInvocations: slash.get(s.name) ?? 0,\n inboundRefs: inbound.get(s.name) ?? 0,\n artifactCount: countArtifacts(\n config.artifactRoots ?? [],\n s.name,\n config.artifactAliases?.[s.name] ?? [],\n ),\n tanglePrivateRefs: (body.match(TANGLE_PRIVATE_RE) ?? []).length,\n hasReferencesDir: existsSync(join(dir, 'references')),\n hasEvalsDir: existsSync(join(dir, 'evals')),\n logsRuns: body.includes('skill-runs.jsonl'),\n hasTriggerPhrases: TRIGGER_RE.test(frontmatterDescription(body) || body.slice(0, 600)),\n }\n })\n return { generatedFromTraces: transcripts, records }\n}\n\n// ── Finding emission (pure — unit-testable, no LLM, no fs) ────────────\n\nconst ANALYST_ID = 'skill-usage'\n\nfunction finding(\n area: string,\n subject: string,\n claim: string,\n severity: AnalystSeverity,\n confidence: number,\n producedAt: string,\n recommended: string,\n evidenceUri: string,\n rationale?: string,\n): AnalystFinding {\n return {\n schema_version: '1.0.0',\n finding_id: computeFindingId({ analyst_id: ANALYST_ID, area, subject, claim }),\n analyst_id: ANALYST_ID,\n produced_at: producedAt,\n severity,\n area,\n claim,\n rationale,\n evidence_refs: [{ kind: 'artifact', uri: evidenceUri }],\n recommended_action: recommended,\n confidence,\n subject,\n }\n}\n\n/** Pure rule pass over a report → findings. Exported for direct/unit use. */\nexport function emitSkillUsageFindings(\n report: SkillUsageReport,\n producedAt: string,\n): AnalystFinding[] {\n const out: AnalystFinding[] = []\n for (const r of report.records) {\n const directTotal = r.directInvocations + r.slashInvocations\n const trueUsage = directTotal + r.inboundRefs + r.artifactCount\n\n // 1. Dead: no usage signal of ANY kind. The only real deprecation candidate.\n if (trueUsage === 0) {\n out.push(\n finding(\n 'skill-usage',\n r.name,\n `Skill '${r.name}' has zero usage across all signals (direct, slash, inbound-refs, artifacts)`,\n 'high',\n 0.6,\n producedAt,\n 'Confirm the skill covers a real recurring job; if not, deprecate. Zero true usage is the only deterministic deprecation candidate.',\n r.path,\n 'No Skill-tool call, no slash invocation, no sibling dispatches to it, and no on-disk artifacts.',\n ),\n )\n } else if (directTotal === 0 && r.inboundRefs + r.artifactCount > 0) {\n // 2. Measurement-invisible: real use via orchestration/artifacts, never invoked directly.\n out.push(\n finding(\n 'skill-usage',\n r.name,\n `Skill '${r.name}' shows 0 direct invocations but is used via orchestration/artifacts (inbound=${r.inboundRefs}, artifacts=${r.artifactCount})`,\n 'info',\n 0.8,\n producedAt,\n 'Do NOT treat as unused — usage is real but logged under parent skills or on disk. Strengthen direct-invocation discovery only if direct use is desired.',\n r.path,\n 'The Skill-tool counter undercounts orchestrated/chained leaf skills.',\n ),\n )\n }\n\n // 3. Discovery gap: low direct use AND weak trigger surface.\n if (directTotal <= 2 && !r.hasTriggerPhrases) {\n out.push(\n finding(\n 'discoverability',\n r.name,\n `Skill '${r.name}' is rarely invoked directly and its description has no explicit trigger phrases`,\n 'medium',\n 0.7,\n producedAt,\n \"Add a `Triggers:` clause with verbatim user phrases to the frontmatter description so the model auto-invokes it.\",\n r.path,\n ),\n )\n }\n\n // 4. Public-repo leak.\n if (r.kind === 'public' && r.tanglePrivateRefs > 0) {\n out.push(\n finding(\n 'safety',\n r.name,\n `Public skill '${r.name}' carries ${r.tanglePrivateRefs} Tangle-private reference(s)`,\n 'high',\n 0.75,\n producedAt,\n 'Sanitize incidental internal refs (cli-bridge/kimi/tcloud/~company/private repos) or relocate to a private repo. Verify @tangle-network/* refs are to PUBLISHED packages before treating as a leak.',\n r.path,\n ),\n )\n }\n\n // 5. Bloat / no progressive disclosure.\n if (r.lines > BLOAT_LINE_THRESHOLD && !r.hasReferencesDir) {\n out.push(\n finding(\n 'maintainability',\n r.name,\n `Skill '${r.name}' is ${r.lines} lines with no references/ split (progressive disclosure)`,\n 'medium',\n 0.8,\n producedAt,\n `Split detail into references/ loaded on demand; keep SKILL.md a short overview. ${r.lines} lines load into every session's context budget.`,\n r.path,\n ),\n )\n }\n\n // 6. No evals (Anthropic's \">=3 evals before docs\" rule).\n if (!r.hasEvalsDir) {\n out.push(\n finding(\n 'data-quality',\n r.name,\n `Skill '${r.name}' ships no evals/`,\n 'low',\n 0.6,\n producedAt,\n 'Add evals/evals.json with >=3 scenarios proving the skill beats baseline; gives regression coverage.',\n r.path,\n ),\n )\n }\n\n // 7. No run logging → invisible to /reflect and /governor.\n if (!r.logsRuns) {\n out.push(\n finding(\n 'observability',\n r.name,\n `Skill '${r.name}' never appends to .evolve/skill-runs.jsonl`,\n 'low',\n 0.55,\n producedAt,\n 'Append one run line to .evolve/skill-runs.jsonl on completion, or declare it a non-logging leaf, so the self-improvement loop can see it ran.',\n r.path,\n ),\n )\n }\n }\n return out\n}\n\n// ── The Analyst ──────────────────────────────────────────────────────\n\nexport class SkillUsageAnalyst implements Analyst<SkillUsageReport> {\n readonly id = ANALYST_ID\n readonly description =\n 'Deterministic multi-signal skill-usage analysis: flags dead skills, measurement-invisible (orchestrated) usage, discovery gaps, public-repo leaks, bloat, missing evals, and missing run-logging.'\n readonly inputKind = 'custom' as const\n readonly cost = { kind: 'deterministic' as const, est_usd_per_run: 0 }\n readonly version = '1.0.0'\n\n async analyze(input: SkillUsageReport, ctx: AnalystContext): Promise<AnalystFinding[]> {\n const producedAt = ctx.tags?.producedAt ?? new Date().toISOString()\n ctx.log?.(`skill-usage: ${input.records.length} skills over ${input.generatedFromTraces} transcripts`)\n return emitSkillUsageFindings(input, producedAt)\n }\n}\n\nexport const SKILL_USAGE_ANALYST = new SkillUsageAnalyst()\n","/**\n * AnalystRegistry — orchestrate N analysts against one run.\n *\n * Owns three responsibilities and only three:\n * 1. Registration — ids must be unique; bad registrations fail loudly\n * at register-time, not run-time.\n * 2. Routing — each analyst declares its `inputKind`; the registry\n * picks the matching field from AnalystRunInputs and skips the\n * analyst with a logged reason if it's missing.\n * 3. Isolation — one analyst's exception MUST NOT stop other analysts.\n * Failed analysts produce zero findings + a 'failed' summary row.\n *\n * Cross-cutting concerns (telemetry, error → finding conversion, cost\n * ingestion, storage rotation) live in `AnalystHooks`. Budget shaping\n * (equal split vs weighted vs custom) lives in `BudgetPolicy`. Both\n * have sensible defaults; consumers override only what they need.\n */\n\nimport { randomUUID } from 'node:crypto'\nimport type { ChatClient } from './chat-client'\nimport type {\n Analyst,\n AnalystContext,\n AnalystFinding,\n AnalystRunEvent,\n AnalystRunInputs,\n AnalystRunResult,\n AnalystRunSummary,\n} from './types'\n\n// ── Hook + policy surfaces ─────────────────────────────────────────\n\nexport interface AnalystHooks {\n /** Before analyze() — last chance to mutate ctx (e.g. inject tags, override budget). */\n onBeforeAnalyze?(args: {\n analyst: Analyst\n ctx: AnalystContext\n runId: string\n }): void | Promise<void>\n /** After every analyst (ok | failed | skipped). Use for telemetry, ingestion, rotation. */\n onAfterAnalyze?(args: {\n analyst: Analyst\n summary: AnalystRunSummary\n findings: AnalystFinding[]\n runId: string\n }): void | Promise<void>\n /**\n * On analyst exception. Hook MAY return findings to convert the\n * error into structured findings; the summary still reports 'failed'.\n * Return void to keep the default empty-findings behavior.\n */\n onError?(args: {\n analyst: Analyst\n error: Error\n runId: string\n }): AnalystFinding[] | undefined | Promise<AnalystFinding[] | undefined>\n /** Once after registry.run() completes. Use for final aggregation, persistence. */\n onComplete?(args: { result: AnalystRunResult }): void | Promise<void>\n}\n\nexport interface BudgetPolicy {\n /** Overall USD cap across the registry.run(). */\n totalUsd?: number\n /** Per-analyst weight for the default allocator. Missing ids get weight 1. */\n weights?: Record<string, number>\n /**\n * Custom allocator — receives the analyst, remaining/total budget, and\n * the count of analysts that will run. Returns the per-analyst budget\n * (or undefined to leave it uncapped). Overrides weights when set.\n */\n allocate?: (args: {\n analyst: Analyst\n totalUsd: number | undefined\n remainingUsd: number | undefined\n runningCount: number\n }) => number | undefined\n}\n\nexport interface AnalystRegistryOptions {\n /** Shared chat client passed to every LLM analyst via AnalystContext. */\n chat?: ChatClient\n /** Logger callback. Defaults to a no-op. */\n log?: (msg: string, fields?: Record<string, unknown>) => void\n /** Hooks invoked around analyze() — observability + customization seam. */\n hooks?: AnalystHooks\n /** Default budget when run() doesn't override. */\n defaultBudget?: BudgetPolicy\n}\n\nexport interface RegistryRunOpts {\n /** Restrict to a subset of registered analysts by id. */\n only?: string[]\n /** Skip these analysts even if registered. Useful for cheap iteration. */\n skip?: string[]\n /** Budget policy — totalUsd + optional weights/allocator. Falls back to options.defaultBudget. */\n budget?: BudgetPolicy\n /** Wall-clock cap. Analysts SHOULD honor `ctx.deadlineMs`. */\n timeoutMs?: number\n /** Abort signal — forwarded into every analyst's context. */\n signal?: AbortSignal\n /** Tags echoed into AnalystContext.tags — useful for tracking environment/version in findings. */\n tags?: Record<string, string>\n /**\n * Prior-run findings made available as retrieval context to every\n * analyst via `ctx.priorFindings`. The registry forwards the slice\n * whose `analyst_id` matches each registered analyst so a kind sees\n * only its own history. Pass `{ '*': findings }` to broadcast to\n * every analyst (useful for cross-kind chaining where the improvement\n * analyst consumes upstream failure findings).\n */\n priorFindings?: ReadonlyArray<AnalystFinding> | Record<string, ReadonlyArray<AnalystFinding>>\n}\n\nexport class AnalystRegistry {\n private readonly analysts = new Map<string, Analyst>()\n private readonly options: AnalystRegistryOptions\n\n constructor(options: AnalystRegistryOptions = {}) {\n this.options = options\n }\n\n register(analyst: Analyst): void {\n if (!analyst.id) throw new Error('AnalystRegistry.register: analyst.id is required')\n if (this.analysts.has(analyst.id)) {\n throw new Error(`AnalystRegistry.register: duplicate analyst id \"${analyst.id}\"`)\n }\n if (!analyst.version) {\n throw new Error(`AnalystRegistry.register: analyst \"${analyst.id}\" must declare a version`)\n }\n this.analysts.set(analyst.id, analyst)\n }\n\n list(): ReadonlyArray<{\n id: string\n description: string\n version: string\n cost: Analyst['cost']\n }> {\n return Array.from(this.analysts.values()).map((a) => ({\n id: a.id,\n description: a.description,\n version: a.version,\n cost: a.cost,\n }))\n }\n\n async run(\n runId: string,\n inputs: AnalystRunInputs,\n runOpts: RegistryRunOpts = {},\n ): Promise<AnalystRunResult> {\n // Thin collector over `runStream`. Both surfaces share the same\n // loop body so they cannot drift on isolation / hook order / cost.\n for await (const ev of this.runStream(runId, inputs, runOpts)) {\n if (ev.type === 'run-completed') return ev.result\n }\n throw new Error('AnalystRegistry.run: stream completed without run-completed event')\n }\n\n /**\n * Streaming counterpart to `run()`. Emits `AnalystRunEvent` values\n * in real time — `run-started`, then per-analyst `skipped` /\n * `started` / `completed`, then a terminal `run-completed` whose\n * payload is the full `AnalystRunResult`. UIs use this to render\n * progress; persistence consumers use `run()` and read the result.\n *\n * Hooks (`onBeforeAnalyze` / `onAfterAnalyze` / `onError` /\n * `onComplete`) fire as before — streaming is additive, not a hook\n * replacement.\n */\n async *runStream(\n runId: string,\n inputs: AnalystRunInputs,\n runOpts: RegistryRunOpts = {},\n ): AsyncGenerator<AnalystRunEvent, void, void> {\n const correlationId = `ar_${randomUUID().slice(0, 12)}`\n const log = this.options.log ?? (() => {})\n const hooks = this.options.hooks ?? {}\n const startedAt = new Date().toISOString()\n const started = Date.now()\n const deadlineMs = runOpts.timeoutMs ? started + runOpts.timeoutMs : undefined\n\n const selected = this.selectAnalysts(runOpts)\n const budget = runOpts.budget ?? this.options.defaultBudget\n\n yield {\n type: 'run-started',\n run_id: runId,\n correlation_id: correlationId,\n started_at: startedAt,\n analyst_ids: selected.map((a) => a.id),\n }\n\n const summaries: AnalystRunSummary[] = []\n const allFindings: AnalystFinding[] = []\n let totalCost = 0\n let remainingUsd = budget?.totalUsd\n\n for (const analyst of selected) {\n const t0 = Date.now()\n const input = this.routeInput(analyst, inputs)\n if (input.kind === 'missing') {\n const summary: AnalystRunSummary = {\n analyst_id: analyst.id,\n status: 'skipped',\n reason: `missing input of kind '${analyst.inputKind}'`,\n findings_count: 0,\n latency_ms: 0,\n cost_usd: 0,\n }\n summaries.push(summary)\n log(`[analyst] skip ${analyst.id} — missing input`, { runId, kind: analyst.inputKind })\n await hooks.onAfterAnalyze?.({ analyst, summary, findings: [], runId })\n yield { type: 'analyst-skipped', summary }\n continue\n }\n\n const perBudget = allocateBudget(budget, {\n analyst,\n remainingUsd,\n runningCount: selected.length,\n })\n\n const ctx: AnalystContext = {\n runId,\n correlationId,\n deadlineMs,\n budgetUsd: perBudget,\n chat: this.options.chat,\n tags: runOpts.tags,\n log: (msg, fields) => log(`[${analyst.id}] ${msg}`, { runId, correlationId, ...fields }),\n signal: runOpts.signal,\n priorFindings: selectPriorFindings(runOpts.priorFindings, analyst.id),\n }\n\n await hooks.onBeforeAnalyze?.({ analyst, ctx, runId })\n yield {\n type: 'analyst-started',\n analyst_id: analyst.id,\n started_at: new Date(t0).toISOString(),\n }\n\n try {\n const findings = await (analyst as Analyst<unknown>).analyze(input.value, ctx)\n const latency = Date.now() - t0\n const cost = sumFindingCost(findings)\n totalCost += cost\n if (typeof remainingUsd === 'number') remainingUsd = Math.max(0, remainingUsd - cost)\n allFindings.push(...findings)\n const summary: AnalystRunSummary = {\n analyst_id: analyst.id,\n status: 'ok',\n findings_count: findings.length,\n latency_ms: latency,\n cost_usd: cost,\n }\n summaries.push(summary)\n log(`[analyst] ok ${analyst.id}`, {\n runId,\n findings: findings.length,\n latency_ms: latency,\n cost_usd: cost,\n })\n await hooks.onAfterAnalyze?.({ analyst, summary, findings, runId })\n yield { type: 'analyst-completed', summary, findings }\n } catch (err) {\n const latency = Date.now() - t0\n const e = err instanceof Error ? err : new Error(String(err))\n // Hook gets first chance to convert the error into findings.\n const hookFindings = (await hooks.onError?.({ analyst, error: e, runId })) ?? []\n if (hookFindings.length) allFindings.push(...hookFindings)\n const summary: AnalystRunSummary = {\n analyst_id: analyst.id,\n status: 'failed',\n findings_count: hookFindings.length,\n latency_ms: latency,\n cost_usd: 0,\n error: { class: e.constructor.name, message: e.message },\n }\n summaries.push(summary)\n log(`[analyst] FAIL ${analyst.id}`, {\n runId,\n error_class: e.constructor.name,\n error: e.message,\n })\n await hooks.onAfterAnalyze?.({ analyst, summary, findings: hookFindings, runId })\n yield { type: 'analyst-completed', summary, findings: hookFindings }\n // Continue — isolation invariant.\n }\n }\n\n const result: AnalystRunResult = {\n run_id: runId,\n correlation_id: correlationId,\n started_at: startedAt,\n ended_at: new Date().toISOString(),\n findings: allFindings,\n per_analyst: summaries,\n total_cost_usd: totalCost,\n }\n await hooks.onComplete?.({ result })\n yield { type: 'run-completed', result }\n }\n\n private selectAnalysts(opts: RegistryRunOpts): Analyst[] {\n let candidates = Array.from(this.analysts.values())\n if (opts.only?.length) {\n const only = new Set(opts.only)\n candidates = candidates.filter((a) => only.has(a.id))\n }\n if (opts.skip?.length) {\n const skip = new Set(opts.skip)\n candidates = candidates.filter((a) => !skip.has(a.id))\n }\n return candidates\n }\n\n private routeInput(\n analyst: Analyst,\n inputs: AnalystRunInputs,\n ): { kind: 'present'; value: unknown } | { kind: 'missing' } {\n switch (analyst.inputKind) {\n case 'trace-store':\n return inputs.traceStore\n ? { kind: 'present', value: inputs.traceStore }\n : { kind: 'missing' }\n case 'artifact-dir':\n return inputs.artifactDir\n ? { kind: 'present', value: inputs.artifactDir }\n : { kind: 'missing' }\n case 'run-record':\n return inputs.runRecord ? { kind: 'present', value: inputs.runRecord } : { kind: 'missing' }\n case 'judge-input':\n return inputs.judgeInput\n ? { kind: 'present', value: inputs.judgeInput }\n : { kind: 'missing' }\n case 'custom': {\n const v = inputs.custom?.[analyst.id]\n return v !== undefined ? { kind: 'present', value: v } : { kind: 'missing' }\n }\n }\n }\n}\n\n/**\n * Default budget allocator: prefer the custom `allocate` callback if\n * provided; else weighted split when weights are set; else equal split\n * across `runningCount`. Returns undefined when no totalUsd is known.\n */\nfunction allocateBudget(\n policy: BudgetPolicy | undefined,\n args: { analyst: Analyst; remainingUsd: number | undefined; runningCount: number },\n): number | undefined {\n if (!policy) return undefined\n if (policy.allocate) {\n return policy.allocate({\n analyst: args.analyst,\n totalUsd: policy.totalUsd,\n remainingUsd: args.remainingUsd,\n runningCount: args.runningCount,\n })\n }\n if (policy.totalUsd == null) return undefined\n if (policy.weights) {\n // Weighted split: caller-supplied weights, default 1 for missing ids.\n // We can only normalize against the analysts in this run, but the\n // registry doesn't know all ids at allocator-time without passing\n // them. We approximate by treating `runningCount` as the count of\n // weight=1 analysts when the weight map omits ids. The exact split\n // is left to consumers that need precision via `allocate`.\n const w = policy.weights[args.analyst.id] ?? 1\n const totalWeight = Math.max(1, args.runningCount) // see note above\n return (policy.totalUsd * w) / totalWeight\n }\n return policy.totalUsd / Math.max(1, args.runningCount)\n}\n\n/**\n * Findings may carry their cost in `metadata.cost_usd` when the analyst\n * tracks it (the LLM-driven adapters do this — they sum chat-client\n * responses). Deterministic findings have no cost field.\n */\nfunction sumFindingCost(findings: AnalystFinding[]): number {\n let sum = 0\n for (const f of findings) {\n const c = f.metadata?.cost_usd\n if (typeof c === 'number' && Number.isFinite(c)) sum += c\n }\n return sum\n}\n\n/**\n * Resolve the `priorFindings` slice an analyst sees.\n *\n * - Array form → the analyst sees only findings whose `analyst_id`\n * matches its own id, so a kind never reads\n * another kind's history by accident.\n * - Record form → the analyst gets the entry keyed by its id, with\n * the `'*'` wildcard appended (in that order). Use\n * the wildcard for cross-kind chaining, e.g. when\n * `improvement` should see all upstream failure /\n * gap / poisoning findings.\n */\nfunction selectPriorFindings(\n source: RegistryRunOpts['priorFindings'],\n analystId: string,\n): ReadonlyArray<AnalystFinding> | undefined {\n if (!source) return undefined\n if (Array.isArray(source)) {\n const own = source.filter((f) => f.analyst_id === analystId)\n return own.length > 0 ? own : undefined\n }\n const record = source as Record<string, ReadonlyArray<AnalystFinding>>\n const own = record[analystId] ?? []\n const wildcard = record['*'] ?? []\n const merged = [...own, ...wildcard]\n return merged.length > 0 ? merged : undefined\n}\n","/**\n * Automated pull request opener for the production loop.\n *\n * `runProductionLoop` produces a `promotedPrompt` string and a release\n * scorecard. To close the eval → prod → eval cycle the framework needs\n * to land that prompt as a reviewable code change. This module does\n * exactly that:\n *\n * 1. Stage a branch off `baseBranch`.\n * 2. Write each `fileChange` into the worktree.\n * 3. Commit + push.\n * 4. Open a PR via the GitHub API.\n *\n * Two transports ship in core:\n *\n * - `ghCliClient(opts)` — shells out to the `gh` CLI. No extra deps,\n * re-uses the developer machine's `gh auth` state, works with both\n * github.com and GitHub Enterprise. This is the recommended default.\n * - `httpGithubClient(opts)` — direct `fetch` against `api.github.com`\n * with a bearer token. Useful in CI where `gh` may not be installed.\n *\n * Both implement the small `AutoPrClient` interface, so tests substitute\n * a fake without spinning a process or network.\n *\n * @experimental — surface may evolve as consumers wire it into CI workflows.\n */\n\nimport { ConfigError, ValidationError } from './errors'\n\nexport interface FileChange {\n /** Repo-relative path. Forward slashes; no `..`. */\n path: string\n /** New file contents. UTF-8. */\n contents: string\n /** Optional explanatory comment shown in the commit body. */\n rationale?: string\n}\n\nexport interface RepoRef {\n owner: string\n name: string\n}\n\nexport interface ProposeAutomatedPullRequestInput {\n repo: RepoRef\n /** Branch to base the PR on. Default `'main'`. */\n baseBranch?: string\n /** New branch name. Use a prefix + a short stable id; no spaces. */\n branchName: string\n fileChanges: FileChange[]\n title: string\n body: string\n /** Optional GitHub usernames to request review from. */\n reviewers?: string[]\n /** Optional labels to apply. */\n labels?: string[]\n /** Commit author name. Default: derived from the GitHub client. */\n authorName?: string\n /** Commit author email. Default: derived from the GitHub client. */\n authorEmail?: string\n /** Dry-run — do not push or open a PR; just return the would-be plan. */\n dryRun?: boolean\n}\n\nexport interface ProposeAutomatedPullRequestResult {\n prUrl: string\n branchName: string\n headSha: string\n dryRun: boolean\n}\n\n/** Pluggable transport for the auto-PR pipeline. */\nexport interface AutoPrClient {\n /**\n * Create a branch from `baseBranch`, write file changes, commit, push,\n * and open a PR. Returns the PR's HTML url and head SHA.\n *\n * Implementations must be idempotent on `branchName`: if the branch\n * already exists with the same head SHA as the would-be commit, return\n * the existing PR rather than failing. This makes the production loop\n * safe to retry on transient errors.\n */\n proposeChange(input: ProposeAutomatedPullRequestInput): Promise<ProposeAutomatedPullRequestResult>\n}\n\nexport async function proposeAutomatedPullRequest(\n client: AutoPrClient,\n input: ProposeAutomatedPullRequestInput,\n): Promise<ProposeAutomatedPullRequestResult> {\n validate(input)\n return client.proposeChange(input)\n}\n\nfunction validate(input: ProposeAutomatedPullRequestInput): void {\n if (!input.repo.owner.trim() || !input.repo.name.trim()) {\n throw new ValidationError('proposeAutomatedPullRequest: repo.owner and repo.name required')\n }\n if (!input.branchName.trim() || /\\s/.test(input.branchName)) {\n throw new ValidationError(\n 'proposeAutomatedPullRequest: branchName must be non-empty and contain no whitespace',\n )\n }\n if (input.branchName === (input.baseBranch ?? 'main')) {\n throw new ValidationError('proposeAutomatedPullRequest: branchName must differ from baseBranch')\n }\n if (input.fileChanges.length === 0) {\n throw new ValidationError('proposeAutomatedPullRequest: fileChanges must not be empty')\n }\n const seenPaths = new Set<string>()\n for (const change of input.fileChanges) {\n if (!change.path.trim() || change.path.includes('..') || change.path.startsWith('/')) {\n throw new ValidationError(\n `proposeAutomatedPullRequest: invalid file path \"${change.path}\" (no '..' or leading '/')`,\n )\n }\n if (seenPaths.has(change.path)) {\n throw new ValidationError(`proposeAutomatedPullRequest: duplicate file path \"${change.path}\"`)\n }\n seenPaths.add(change.path)\n }\n if (!input.title.trim()) {\n throw new ValidationError('proposeAutomatedPullRequest: title must not be empty')\n }\n}\n\n// ── HTTP transport (uses `fetch` against api.github.com) ─────────────\n\nexport interface HttpGithubClientOptions {\n /** Personal access token, GitHub App token, or `GITHUB_TOKEN` from Actions. */\n token: string\n /** Override for GitHub Enterprise. Default `'https://api.github.com'`. */\n apiBase?: string\n /** Test seam — defaults to global `fetch`. */\n fetchImpl?: typeof fetch\n /** Test seam — clock for commit timestamps. */\n now?: () => Date\n}\n\ninterface GhRef {\n ref: string\n object: { sha: string }\n}\n\ninterface GhCommit {\n sha: string\n tree: { sha: string }\n}\n\ninterface GhBlob {\n sha: string\n}\n\ninterface GhTree {\n sha: string\n}\n\ninterface GhPullRequest {\n html_url: string\n number: number\n}\n\n/**\n * Direct REST-API GitHub client. No external deps.\n *\n * Idempotency strategy: before creating refs/commits/PRs, check whether\n * the branch already exists at the desired tree. If so, return the\n * existing PR (or open one if missing). Errors from concurrent runs\n * (`Reference already exists`) are caught and treated as success.\n */\nexport function httpGithubClient(opts: HttpGithubClientOptions): AutoPrClient {\n const fetchImpl = opts.fetchImpl ?? fetch\n const apiBase = (opts.apiBase ?? 'https://api.github.com').replace(/\\/+$/, '')\n const now = opts.now ?? (() => new Date())\n\n async function api<T>(\n method: string,\n path: string,\n body?: unknown,\n accept404 = false,\n ): Promise<T | null> {\n const res = await fetchImpl(`${apiBase}${path}`, {\n method,\n headers: {\n accept: 'application/vnd.github+json',\n 'content-type': 'application/json',\n authorization: `Bearer ${opts.token}`,\n 'x-github-api-version': '2022-11-28',\n },\n body: body === undefined ? undefined : JSON.stringify(body),\n })\n if (accept404 && res.status === 404) return null\n if (!res.ok) {\n const text = await res.text().catch(() => '')\n throw new ConfigError(\n `proposeAutomatedPullRequest: GitHub ${method} ${path} → ${res.status} ${text.slice(0, 400)}`,\n )\n }\n return (await res.json()) as T\n }\n\n return {\n async proposeChange(input) {\n const baseBranch = input.baseBranch ?? 'main'\n const repoPath = `/repos/${input.repo.owner}/${input.repo.name}`\n\n if (input.dryRun) {\n return {\n prUrl: `https://github.com/${input.repo.owner}/${input.repo.name}/compare/${baseBranch}...${input.branchName}`,\n branchName: input.branchName,\n headSha: 'dry-run',\n dryRun: true,\n }\n }\n\n // 1. Find base SHA\n const baseRef = await api<GhRef>('GET', `${repoPath}/git/ref/heads/${baseBranch}`)\n if (!baseRef) {\n throw new ConfigError(`proposeAutomatedPullRequest: base branch \"${baseBranch}\" not found`)\n }\n const baseSha = baseRef.object.sha\n const baseCommit = await api<GhCommit>('GET', `${repoPath}/git/commits/${baseSha}`)\n if (!baseCommit) {\n throw new ConfigError(\n `proposeAutomatedPullRequest: base commit ${baseSha} not found (race condition?)`,\n )\n }\n\n // 2. Create blobs for each file\n const treeEntries = []\n for (const change of input.fileChanges) {\n const blob = await api<GhBlob>('POST', `${repoPath}/git/blobs`, {\n content: change.contents,\n encoding: 'utf-8',\n })\n if (!blob) throw new ConfigError('proposeAutomatedPullRequest: blob creation returned null')\n treeEntries.push({\n path: change.path,\n mode: '100644',\n type: 'blob',\n sha: blob.sha,\n })\n }\n\n // 3. Create tree\n const tree = await api<GhTree>('POST', `${repoPath}/git/trees`, {\n base_tree: baseCommit.tree.sha,\n tree: treeEntries,\n })\n if (!tree) throw new ConfigError('proposeAutomatedPullRequest: tree creation returned null')\n\n // 4. Create commit\n const author =\n input.authorName && input.authorEmail\n ? { name: input.authorName, email: input.authorEmail, date: now().toISOString() }\n : undefined\n const commitMessage = renderCommitMessage(input)\n const commit = await api<GhCommit>('POST', `${repoPath}/git/commits`, {\n message: commitMessage,\n tree: tree.sha,\n parents: [baseSha],\n ...(author ? { author, committer: author } : {}),\n })\n if (!commit)\n throw new ConfigError('proposeAutomatedPullRequest: commit creation returned null')\n\n // 5. Create or fast-forward branch ref (idempotent on existing branch).\n const existing = await api<GhRef>(\n 'GET',\n `${repoPath}/git/ref/heads/${input.branchName}`,\n undefined,\n true,\n )\n if (!existing) {\n await api('POST', `${repoPath}/git/refs`, {\n ref: `refs/heads/${input.branchName}`,\n sha: commit.sha,\n })\n } else if (existing.object.sha !== commit.sha) {\n await api('PATCH', `${repoPath}/git/refs/heads/${input.branchName}`, {\n sha: commit.sha,\n force: true,\n })\n }\n\n // 6. Open PR (or find an existing open one for the same branch).\n const openPrs = await api<GhPullRequest[]>(\n 'GET',\n `${repoPath}/pulls?state=open&head=${encodeURIComponent(`${input.repo.owner}:${input.branchName}`)}`,\n )\n let pr: GhPullRequest\n if (openPrs && openPrs.length > 0) {\n pr = openPrs[0] as GhPullRequest\n } else {\n const created = await api<GhPullRequest>('POST', `${repoPath}/pulls`, {\n title: input.title,\n body: input.body,\n head: input.branchName,\n base: baseBranch,\n })\n if (!created)\n throw new ConfigError('proposeAutomatedPullRequest: PR creation returned null')\n pr = created\n }\n\n if (input.reviewers && input.reviewers.length > 0) {\n await api(\n 'POST',\n `${repoPath}/pulls/${pr.number}/requested_reviewers`,\n { reviewers: input.reviewers },\n true,\n ).catch(() => {\n /* reviewer assignment is best-effort */\n })\n }\n if (input.labels && input.labels.length > 0) {\n await api(\n 'POST',\n `${repoPath}/issues/${pr.number}/labels`,\n { labels: input.labels },\n true,\n ).catch(() => {\n /* label assignment is best-effort */\n })\n }\n\n return {\n prUrl: pr.html_url,\n branchName: input.branchName,\n headSha: commit.sha,\n dryRun: false,\n }\n },\n }\n}\n\n// ── gh CLI transport (no fetch needed, re-uses developer auth) ──────\n\nexport interface GhCliClientOptions {\n /** Override the CLI binary (`gh`). For testing. */\n bin?: string\n /** Working directory containing a clone of `repo`. Default: process cwd. */\n cwd?: string\n /** Test seam: process spawner. Default: node:child_process spawn. */\n exec?: (\n bin: string,\n args: string[],\n opts: { cwd: string; stdin?: string },\n ) => Promise<{ stdout: string; stderr: string; exitCode: number }>\n}\n\n/**\n * `gh` CLI transport. Requires:\n * - `gh` installed and authenticated (`gh auth status`).\n * - A local clone of the repo with a clean working tree.\n * - `git` on PATH.\n *\n * Uses `gh api` for repo metadata and `gh pr create` for the PR. The\n * actual commit lands via `git`, which keeps `gh`'s footprint minimal.\n */\nexport function ghCliClient(opts: GhCliClientOptions = {}): AutoPrClient {\n const bin = opts.bin ?? 'gh'\n const cwd = opts.cwd ?? process.cwd()\n const exec = opts.exec ?? defaultExec\n\n async function run(\n cmd: string,\n args: string[],\n stdin?: string,\n ): Promise<{ stdout: string; stderr: string }> {\n const r = await exec(cmd, args, { cwd, stdin })\n if (r.exitCode !== 0) {\n throw new ConfigError(\n `proposeAutomatedPullRequest: ${cmd} ${args.join(' ')} failed (${r.exitCode}): ${r.stderr.trim() || r.stdout.trim()}`,\n )\n }\n return r\n }\n\n return {\n async proposeChange(input) {\n const baseBranch = input.baseBranch ?? 'main'\n if (input.dryRun) {\n return {\n prUrl: `https://github.com/${input.repo.owner}/${input.repo.name}/compare/${baseBranch}...${input.branchName}`,\n branchName: input.branchName,\n headSha: 'dry-run',\n dryRun: true,\n }\n }\n\n // Ensure we're working in a clean tree on the base branch.\n await run('git', ['fetch', 'origin', baseBranch])\n await run('git', ['checkout', baseBranch])\n await run('git', ['reset', '--hard', `origin/${baseBranch}`])\n\n // Branch (idempotent: delete if exists, then re-create from base).\n await exec('git', ['branch', '-D', input.branchName], { cwd })\n await run('git', ['checkout', '-b', input.branchName])\n\n // Write file changes.\n const { mkdir, writeFile } = await import('node:fs/promises')\n const { dirname, join, resolve } = await import('node:path')\n for (const change of input.fileChanges) {\n const abs = resolve(cwd, change.path)\n await mkdir(dirname(abs), { recursive: true })\n await writeFile(abs, change.contents, 'utf8')\n await run('git', ['add', join(change.path)])\n }\n\n // Commit.\n const env: Record<string, string> = {}\n if (input.authorName) env.GIT_AUTHOR_NAME = input.authorName\n if (input.authorEmail) env.GIT_AUTHOR_EMAIL = input.authorEmail\n if (input.authorName) env.GIT_COMMITTER_NAME = input.authorName\n if (input.authorEmail) env.GIT_COMMITTER_EMAIL = input.authorEmail\n const message = renderCommitMessage(input)\n await run('git', ['commit', '-m', message])\n\n const headRes = await run('git', ['rev-parse', 'HEAD'])\n const headSha = headRes.stdout.trim()\n\n // Push.\n await run('git', ['push', '-f', 'origin', input.branchName])\n\n // Open PR (idempotent: `gh pr create` errors if one exists).\n const existing = await exec(\n bin,\n [\n 'pr',\n 'list',\n '--state',\n 'open',\n '--head',\n input.branchName,\n '--json',\n 'url,number',\n '--limit',\n '1',\n ],\n { cwd },\n )\n let prUrl = ''\n if (existing.exitCode === 0 && existing.stdout.trim()) {\n const parsed = JSON.parse(existing.stdout) as Array<{ url: string }>\n if (parsed.length > 0 && parsed[0]) prUrl = parsed[0].url\n }\n if (!prUrl) {\n const args = [\n 'pr',\n 'create',\n '--title',\n input.title,\n '--body',\n input.body,\n '--base',\n baseBranch,\n ]\n if (input.reviewers && input.reviewers.length > 0) {\n args.push('--reviewer', input.reviewers.join(','))\n }\n if (input.labels && input.labels.length > 0) {\n args.push('--label', input.labels.join(','))\n }\n const r = await run(bin, args)\n const match = r.stdout.match(/https?:\\/\\/\\S+/)\n prUrl = match ? match[0] : r.stdout.trim()\n }\n\n return { prUrl, branchName: input.branchName, headSha, dryRun: false }\n },\n }\n}\n\nasync function defaultExec(\n bin: string,\n args: string[],\n opts: { cwd: string; stdin?: string },\n): Promise<{ stdout: string; stderr: string; exitCode: number }> {\n const { spawn } = await import('node:child_process')\n return new Promise((resolveExec) => {\n const child = spawn(bin, args, { cwd: opts.cwd })\n let stdout = ''\n let stderr = ''\n child.stdout.on('data', (d) => {\n stdout += d.toString()\n })\n child.stderr.on('data', (d) => {\n stderr += d.toString()\n })\n if (opts.stdin) child.stdin.end(opts.stdin)\n child.on('error', (err) => {\n resolveExec({ stdout, stderr: `${stderr}${err.message}`, exitCode: 1 })\n })\n child.on('close', (code) => {\n resolveExec({ stdout, stderr, exitCode: code ?? 1 })\n })\n })\n}\n\nfunction renderCommitMessage(input: ProposeAutomatedPullRequestInput): string {\n const lines = [input.title, '']\n for (const change of input.fileChanges) {\n if (change.rationale) lines.push(`- ${change.path}: ${change.rationale}`)\n }\n if (lines[lines.length - 1] !== '') lines.push('')\n lines.push(input.body.trim())\n return lines.join('\\n').trim()\n}\n","import type { TCloud } from '@tangle-network/tcloud'\nimport { normalizeScores, weightedMean } from './statistics'\nimport type {\n CollectedArtifacts,\n JudgeFn,\n JudgeScore,\n Scenario,\n ScenarioResult,\n TurnResult,\n} from './types'\n\ninterface ChatMessage {\n role: 'system' | 'user' | 'assistant'\n content: string\n}\n\nexport interface ExecutorConfig {\n /** System prompt for the agent under test */\n systemPrompt: string\n /** Model to use for the agent */\n model?: string\n /** Judges to run after execution */\n judges: JudgeFn[]\n /** Regex patterns for detecting tool/API calls in responses */\n toolCallPatterns?: RegExp[]\n /** Block delimiter pattern (default: :::type\\n...\\n:::) */\n blockPattern?: RegExp\n /** Custom artifact checker for domain-specific checks */\n artifactChecker?: (\n check: Scenario['artifactChecks'][0],\n artifacts: CollectedArtifacts,\n ) => { passed: boolean; detail: string } | null\n}\n\n/**\n * Execute a scenario against an LLM via tcloud.\n *\n * Runs multi-turn conversation, extracts artifacts, runs judges.\n */\nexport async function executeScenario(\n tc: TCloud,\n scenario: Scenario,\n config: ExecutorConfig,\n): Promise<ScenarioResult> {\n const startTime = Date.now()\n const model = config.model ?? 'gpt-4o'\n\n const systemPrompt = [config.systemPrompt, scenario.systemPromptAppend ?? '']\n .filter(Boolean)\n .join('\\n\\n')\n\n const messages: ChatMessage[] = [{ role: 'system', content: systemPrompt }]\n\n const turns: TurnResult[] = []\n const allCodeBlocks: { language: string; code: string }[] = []\n const allBlocks: { type: string; fields: Record<string, string> }[] = []\n const allToolCalls: string[] = []\n\n const blockRe = config.blockPattern ?? /:::(\\w+)\\s*\\n([\\s\\S]*?)\\n\\s*:::/g\n\n for (let i = 0; i < scenario.turns.length; i++) {\n const turn = scenario.turns[i]!\n const turnStart = Date.now()\n\n messages.push({ role: 'user', content: turn.user })\n\n const resp = await tc.chat({\n model,\n messages,\n temperature: 0.4,\n maxTokens: 3000,\n })\n\n const content =\n (resp as { choices?: { message?: { content?: string } }[] }).choices?.[0]?.message?.content ??\n ''\n\n messages.push({ role: 'assistant', content })\n\n // Extract code blocks\n const codeRe = /```(\\w+)?\\n([\\s\\S]*?)```/g\n let codeMatch\n while ((codeMatch = codeRe.exec(content)) !== null) {\n allCodeBlocks.push({ language: codeMatch[1] ?? 'text', code: codeMatch[2] ?? '' })\n }\n\n // Extract structured blocks\n const turnBlocks: { type: string; title: string }[] = []\n let blockMatch\n const blockReLocal = new RegExp(blockRe.source, blockRe.flags)\n while ((blockMatch = blockReLocal.exec(content)) !== null) {\n const fields: Record<string, string> = {}\n for (const line of (blockMatch[2] ?? '').split('\\n')) {\n const idx = line.indexOf(':')\n if (idx > 0) fields[line.slice(0, idx).trim()] = line.slice(idx + 1).trim()\n }\n const blockType = blockMatch[1] ?? ''\n allBlocks.push({ type: blockType, fields })\n turnBlocks.push({ type: blockType, title: fields.title ?? '' })\n }\n\n // Detect tool calls via configurable patterns\n let hasToolCall = false\n if (config.toolCallPatterns) {\n for (const pattern of config.toolCallPatterns) {\n const re = new RegExp(pattern.source, pattern.flags)\n let toolMatch\n while ((toolMatch = re.exec(content)) !== null) {\n allToolCalls.push(toolMatch[0])\n hasToolCall = true\n }\n }\n }\n\n turns.push({\n turnIndex: i,\n userMessage: turn.user,\n agentResponse: content,\n durationMs: Date.now() - turnStart,\n blocksExtracted: turnBlocks,\n containsCode: allCodeBlocks.length > 0,\n containsToolCall: hasToolCall,\n })\n }\n\n const artifacts: CollectedArtifacts = {\n vaultFiles: [],\n blocksExtracted: allBlocks,\n codeBlocks: allCodeBlocks,\n toolCalls: allToolCalls,\n }\n\n // Run artifact checks\n const artifactResults = scenario.artifactChecks.map((check) => {\n // Try custom checker first\n if (config.artifactChecker) {\n const custom = config.artifactChecker(check, artifacts)\n if (custom) return { check, ...custom }\n }\n\n switch (check.type) {\n case 'block_extracted': {\n const count = allBlocks.filter((b) => b.type === check.target).length\n return {\n check,\n passed: count >= (check.minCount ?? 1),\n detail: `Found ${count} ${check.target} blocks (need ${check.minCount ?? 1})`,\n }\n }\n case 'code_valid': {\n const hasCode = allCodeBlocks.some(\n (b) => b.language === check.target || b.code.includes(check.target),\n )\n return { check, passed: hasCode, detail: hasCode ? 'Code block found' : 'No matching code' }\n }\n default:\n return {\n check,\n passed: false,\n detail: `Check type \"${check.type}\" requires live environment`,\n }\n }\n })\n\n // Run judges sequentially with retry\n const judgeInput = { scenario, turns, artifacts }\n const judgeResults: JudgeScore[][] = []\n\n for (const judge of config.judges) {\n let lastErr = ''\n for (let attempt = 0; attempt < 3; attempt++) {\n try {\n if (attempt > 0) {\n const wait = attempt * 10_000\n console.log(` judge retry ${attempt}/2 (waiting ${wait / 1000}s)`)\n await new Promise((r) => setTimeout(r, wait))\n }\n const scores = await judge(tc, judgeInput)\n judgeResults.push(scores)\n await new Promise((r) => setTimeout(r, 3000))\n break\n } catch (err) {\n lastErr = err instanceof Error ? err.message : String(err)\n if (attempt === 2) {\n judgeResults.push([\n {\n judgeName: 'unknown',\n dimension: 'error',\n score: 0,\n reasoning: `Judge failed after 3 attempts: ${lastErr.slice(0, 200)}`,\n },\n ])\n }\n }\n }\n }\n\n const allScores = judgeResults.flat()\n const errorScores = allScores.filter(\n (s) => s.dimension === 'parse_error' || s.dimension === 'error',\n )\n const validScores = allScores.filter(\n (s) => s.dimension !== 'parse_error' && s.dimension !== 'error',\n )\n const normalized = normalizeScores(validScores)\n\n // Build weight map from scenario rubric dimensions\n const weightMap = new Map<string, number>()\n for (const dim of scenario.dimensions) {\n weightMap.set(dim, 1)\n }\n\n const overallScore = weightedMean(\n normalized.map((s) => ({\n score: s.score,\n weight: weightMap.get(s.dimension) ?? 1,\n })),\n )\n\n return {\n scenarioId: scenario.id,\n persona: scenario.persona,\n turns,\n artifactResults,\n judgeScores: allScores,\n judgeErrors: errorScores.length,\n overallScore,\n totalDurationMs: Date.now() - startTime,\n artifacts,\n }\n}\n","import type { TCloud } from '@tangle-network/tcloud'\nimport { executeScenario } from './executor'\nimport type { BenchmarkReport, BenchmarkRunnerConfig, Scenario, ScenarioResult } from './types'\n\n/**\n * BenchmarkRunner — orchestrates scenarios, executor, judges, and scoring.\n *\n * Domain-agnostic. Each agent provides its own scenarios, judges, and system prompt.\n */\nexport class BenchmarkRunner {\n private tc: TCloud\n private config: BenchmarkRunnerConfig\n\n constructor(tc: TCloud, config: BenchmarkRunnerConfig) {\n this.tc = tc\n this.config = config\n }\n\n async run(scenarios?: Scenario[]): Promise<BenchmarkReport> {\n const toRun = scenarios ?? this.config.scenarios\n const passThreshold = this.config.passThreshold ?? 6.0\n\n console.log('='.repeat(70))\n console.log(' AGENT EVAL — BENCHMARK')\n console.log(' Multi-turn scenarios x Multi-judge panel')\n console.log('='.repeat(70))\n console.log(`Scenarios: ${toRun.length}`)\n console.log(`Judges: ${this.config.judges.length}`)\n console.log(`Model: ${this.config.model ?? 'gpt-4o'}`)\n console.log()\n\n const results: ScenarioResult[] = []\n\n for (let i = 0; i < toRun.length; i++) {\n const scenario = toRun[i]!\n console.log(`[${i + 1}/${toRun.length}] ${scenario.id} (${scenario.persona})`)\n console.log(` thesis: ${scenario.thesis}`)\n console.log(` turns: ${scenario.turns.length}`)\n\n const result = await executeScenario(this.tc, scenario, {\n systemPrompt: this.config.systemPrompt,\n model: this.config.model,\n judges: this.config.judges,\n })\n results.push(result)\n\n // Print turn summaries\n for (const turn of result.turns) {\n const codeIcon = turn.containsCode ? '[code]' : ''\n const toolIcon = turn.containsToolCall ? '[tool]' : ''\n const blockCount = turn.blocksExtracted.length\n const blockIcon = blockCount > 0 ? `[blocks:${blockCount}]` : ''\n console.log(\n ` turn ${turn.turnIndex + 1}: ${(turn.durationMs / 1000).toFixed(1)}s ${codeIcon} ${toolIcon} ${blockIcon} (${turn.agentResponse.length} chars)`,\n )\n }\n\n // Print artifact results\n for (const ar of result.artifactResults) {\n const icon = ar.passed ? '+' : 'X'\n console.log(` artifact: [${icon}] ${ar.check.description} — ${ar.detail}`)\n }\n\n // Print judge scores\n console.log(` judges:`)\n const byJudge: Record<string, { scores: number[]; dimensions: string[] }> = {}\n for (const js of result.judgeScores) {\n const entry = byJudge[js.judgeName] ?? { scores: [], dimensions: [] }\n entry.scores.push(js.score)\n entry.dimensions.push(`${js.dimension}=${js.score}`)\n byJudge[js.judgeName] = entry\n }\n for (const [name, data] of Object.entries(byJudge)) {\n const avg = (data.scores.reduce((a, b) => a + b, 0) / data.scores.length).toFixed(1)\n console.log(` ${name.padEnd(16)} avg=${avg} [${data.dimensions.join(', ')}]`)\n }\n\n console.log(\n ` OVERALL: ${result.overallScore.toFixed(1)}/10 (${(result.totalDurationMs / 1000).toFixed(0)}s)`,\n )\n console.log()\n }\n\n // Build summary\n const byPersona: Record<string, { avg: number; passed: number; total: number }> = {}\n const byDimension: Record<string, { avg: number; scores: number[] }> = {}\n\n for (const r of results) {\n const personaEntry = byPersona[r.persona] ?? { avg: 0, passed: 0, total: 0 }\n personaEntry.total++\n personaEntry.avg += r.overallScore\n if (r.overallScore >= passThreshold) personaEntry.passed++\n byPersona[r.persona] = personaEntry\n\n for (const js of r.judgeScores) {\n const dimEntry = byDimension[js.dimension] ?? { avg: 0, scores: [] }\n dimEntry.scores.push(js.score)\n byDimension[js.dimension] = dimEntry\n }\n }\n\n for (const p of Object.values(byPersona)) {\n p.avg = p.total > 0 ? p.avg / p.total : 0\n }\n for (const d of Object.values(byDimension)) {\n d.avg = d.scores.length > 0 ? d.scores.reduce((a, b) => a + b, 0) / d.scores.length : 0\n }\n\n const sorted = [...results].sort((a, b) => a.overallScore - b.overallScore)\n const weakest = sorted.slice(0, 3).map((r) => ({\n scenario: r.scenarioId,\n score: r.overallScore,\n reason:\n r.judgeScores\n .filter((s) => s.score < passThreshold)\n .map((s) => `${s.dimension}=${s.score}`)\n .join(', ') || 'close to threshold',\n }))\n const strongest = sorted\n .slice(-3)\n .reverse()\n .map((r) => ({\n scenario: r.scenarioId,\n score: r.overallScore,\n reason:\n r.judgeScores\n .filter((s) => s.score >= 9)\n .map((s) => `${s.dimension}=${s.score}`)\n .join(', ') || 'consistently strong',\n }))\n\n // Print final summary\n console.log('='.repeat(70))\n console.log(' RESULTS')\n console.log('='.repeat(70))\n\n const overallAvg =\n results.length > 0 ? results.reduce((s, r) => s + r.overallScore, 0) / results.length : 0\n\n console.log(`Overall: ${overallAvg.toFixed(1)}/10`)\n console.log()\n\n console.log('By persona:')\n for (const [name, data] of Object.entries(byPersona)) {\n console.log(\n ` ${name.padEnd(20)} ${data.avg.toFixed(1)}/10 (${data.passed}/${data.total} passed)`,\n )\n }\n console.log()\n\n console.log('By dimension:')\n const dimEntries = Object.entries(byDimension).sort((a, b) => a[1].avg - b[1].avg)\n for (const [name, data] of dimEntries) {\n const min = Math.min(...data.scores)\n const max = Math.max(...data.scores)\n console.log(\n ` ${name.padEnd(24)} avg=${data.avg.toFixed(1)} range=[${min}-${max}] n=${data.scores.length}`,\n )\n }\n console.log()\n\n if (weakest.length > 0) {\n console.log('Weakest:')\n for (const w of weakest) {\n console.log(` ${w.scenario}: ${w.score.toFixed(1)} — ${w.reason}`)\n }\n console.log()\n }\n\n return {\n timestamp: new Date().toISOString(),\n generation: this.config.generation ?? 1,\n promptVersion: this.config.promptVersion ?? 'v1',\n scenarioCount: toRun.length,\n results,\n summary: { overallAvg, byPersona, byDimension, weakest, strongest },\n }\n }\n}\n","import type { CheckResult, ProductClientConfig, RouteMap, TestResult } from './types'\n\n/**\n * ProductClient — configurable HTTP client for exercising any agent's APIs.\n *\n * Routes are config, not hardcoded. Each agent provides its own RouteMap.\n */\nexport class ProductClient {\n private baseUrl: string\n private routes: RouteMap\n private cookies: string = ''\n\n constructor(config: ProductClientConfig) {\n this.baseUrl = config.baseUrl.replace(/\\/+$/, '')\n this.routes = config.routes\n }\n\n private route(name: keyof RouteMap): string {\n const path = this.routes[name]\n if (!path) throw new Error(`Route \"${name}\" not configured`)\n return path\n }\n\n async signup(name: string, email: string, password: string): Promise<{ userId: string }> {\n const res = await this.post(this.route('signup'), { name, email, password })\n const user = res.user as Record<string, unknown> | undefined\n if (!user?.id) throw new Error(`Signup failed: ${JSON.stringify(res)}`)\n return { userId: user.id as string }\n }\n\n async login(email: string, password: string): Promise<void> {\n const res = await fetch(`${this.baseUrl}${this.route('login')}`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', Origin: this.baseUrl },\n body: JSON.stringify({ email, password }),\n redirect: 'manual',\n })\n const setCookie = res.headers.get('set-cookie')\n if (setCookie) {\n this.cookies = setCookie.split(';')[0] ?? ''\n }\n const body = (await res.json()) as Record<string, unknown>\n if (!body.user) throw new Error(`Login failed: ${JSON.stringify(body)}`)\n }\n\n async createWorkspace(name: string, type = 'project'): Promise<string> {\n const res = await this.post(this.route('workspaces'), { name, type })\n const ws = res.workspace as Record<string, unknown> | undefined\n if (!ws?.id) throw new Error(`Workspace creation failed: ${JSON.stringify(res)}`)\n return ws.id as string\n }\n\n async createThread(workspaceId: string): Promise<string> {\n const res = await this.post(this.route('threads'), { workspaceId })\n const thread = res.thread as Record<string, unknown> | undefined\n if (!thread?.id) throw new Error(`Thread creation failed: ${JSON.stringify(res)}`)\n return thread.id as string\n }\n\n async chat(\n workspaceId: string,\n threadId: string,\n content: string,\n _opts?: { blockPatterns?: RegExp[] },\n ): Promise<{ text: string; blocks: { type: string; title: string }[] }> {\n const res = await fetch(`${this.baseUrl}${this.route('chat')}`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Origin: this.baseUrl,\n Cookie: this.cookies,\n },\n body: JSON.stringify({ workspaceId, threadId, content }),\n })\n\n if (!res.ok || !res.body) throw new Error(`Chat failed: ${res.status}`)\n\n // Parse NDJSON stream\n const reader = res.body.getReader()\n const decoder = new TextDecoder()\n let buf = ''\n let text = ''\n const blocks: { type: string; title: string }[] = []\n\n while (true) {\n const { done, value } = await reader.read()\n if (done) break\n buf += decoder.decode(value, { stream: true })\n const lines = buf.split('\\n')\n buf = lines.pop() ?? ''\n for (const line of lines) {\n if (!line.trim()) continue\n try {\n const event = JSON.parse(line) as { type?: string; data?: { delta?: string } }\n if (event.type === 'message.part.updated' && event.data?.delta) {\n text += event.data.delta\n }\n } catch {\n /* skip non-JSON lines */\n }\n }\n }\n\n // Extract :::blocks from text\n const blockRe = /:::(\\w+)\\s*\\n([\\s\\S]*?)\\n\\s*:::/g\n let match\n while ((match = blockRe.exec(text)) !== null) {\n const fields: Record<string, string> = {}\n for (const line of match[2]!.split('\\n')) {\n const idx = line.indexOf(':')\n if (idx > 0) fields[line.slice(0, idx).trim()] = line.slice(idx + 1).trim()\n }\n blocks.push({ type: match[1]!, title: fields.title ?? '' })\n }\n\n return { text, blocks }\n }\n\n async getTasks(\n workspaceId: string,\n ): Promise<{ id: string; title: string; status: string; priority: string }[]> {\n const res = await this.get(`${this.route('tasks')}?workspaceId=${workspaceId}`)\n return (res.tasks ?? []) as { id: string; title: string; status: string; priority: string }[]\n }\n\n async getEvents(workspaceId: string): Promise<{ id: string; title: string; type: string }[]> {\n const res = await this.get(`${this.route('events')}?workspaceId=${workspaceId}`)\n return (res.events ?? []) as { id: string; title: string; type: string }[]\n }\n\n async getApprovals(\n workspaceId: string,\n ): Promise<{ id: string; title: string; status: string; type: string }[]> {\n const res = await this.get(`${this.route('approvals')}?workspaceId=${workspaceId}`)\n return (res.actions ?? []) as { id: string; title: string; status: string; type: string }[]\n }\n\n async getVaultTree(workspaceId: string): Promise<string[]> {\n const res = await this.get(`${this.route('vault')}?workspaceId=${workspaceId}`)\n const paths: string[] = []\n function extract(nodes: unknown[]) {\n for (const n of nodes) {\n const node = n as { path?: string; type?: string; children?: unknown[] }\n if (node.type === 'file' && node.path) paths.push(node.path)\n if (node.children) extract(node.children)\n }\n }\n extract((res.tree ?? []) as unknown[])\n return paths\n }\n\n async approveAction(workspaceId: string, id: string): Promise<void> {\n await this.patch(this.route('approvals'), { workspaceId, id, status: 'approved' })\n }\n\n async rejectAction(workspaceId: string, id: string, reason: string): Promise<void> {\n await this.patch(this.route('approvals'), { workspaceId, id, status: 'rejected', reason })\n }\n\n async getGenerations(\n workspaceId: string,\n ): Promise<{ id: string; type: string; prompt: string }[]> {\n const res = await this.get(`${this.route('generations')}?workspaceId=${workspaceId}`)\n return (res.generations ?? []) as { id: string; type: string; prompt: string }[]\n }\n\n /** Generic GET for custom routes */\n async get(path: string): Promise<Record<string, unknown>> {\n const res = await fetch(`${this.baseUrl}${path}`, {\n headers: { Cookie: this.cookies },\n })\n return res.json() as Promise<Record<string, unknown>>\n }\n\n /** Generic POST for custom routes */\n async post(path: string, body: Record<string, unknown>): Promise<Record<string, unknown>> {\n const res = await fetch(`${this.baseUrl}${path}`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Origin: this.baseUrl,\n Cookie: this.cookies,\n },\n body: JSON.stringify(body),\n })\n return res.json() as Promise<Record<string, unknown>>\n }\n\n /** Generic PATCH for custom routes */\n async patch(path: string, body: Record<string, unknown>): Promise<Record<string, unknown>> {\n const res = await fetch(`${this.baseUrl}${path}`, {\n method: 'PATCH',\n headers: {\n 'Content-Type': 'application/json',\n Origin: this.baseUrl,\n Cookie: this.cookies,\n },\n body: JSON.stringify(body),\n })\n return res.json() as Promise<Record<string, unknown>>\n }\n}\n\n/**\n * Run a full e2e workflow test against a live product.\n *\n * The `workflow` callback receives a ProductClient and returns CheckResults.\n * This is the generic harness — each agent defines its own workflow steps.\n */\nexport async function runE2EWorkflow(\n client: ProductClient,\n name: string,\n workflow: (client: ProductClient) => Promise<CheckResult[]>,\n): Promise<TestResult> {\n const start = Date.now()\n const checks: CheckResult[] = []\n\n try {\n const results = await workflow(client)\n checks.push(...results)\n } catch (err) {\n checks.push({\n name: 'fatal_error',\n passed: false,\n expected: 'no crash',\n actual: err instanceof Error ? err.message : String(err),\n })\n }\n\n return {\n name,\n passed: checks.every((c) => c.passed),\n duration: Date.now() - start,\n detail: `${checks.filter((c) => c.passed).length}/${checks.length} checks passed`,\n checks,\n }\n}\n","import type { CompletionCriterion, DriverState } from './types'\n\n/**\n * ConvergenceTracker — tracks completion percentage over turns.\n *\n * Produces convergence curves showing how quickly the agent reaches\n * completion criteria.\n */\nexport class ConvergenceTracker {\n private criteria: CompletionCriterion[]\n private history: {\n turn: number\n completionPercent: number\n criteriaStatus: Record<string, boolean | number>\n }[] = []\n\n constructor(criteria: CompletionCriterion[]) {\n this.criteria = criteria\n }\n\n /** Evaluate criteria against current state, record result */\n record(\n turn: number,\n state: DriverState,\n ): {\n completionPercent: number\n complete: boolean\n criteriaStatus: Record<string, boolean | number>\n } {\n const criteriaStatus: Record<string, boolean | number> = {}\n let totalCredit = 0\n\n for (const criterion of this.criteria) {\n if (criterion.progress) {\n const credit = Math.min(1, Math.max(0, criterion.progress(state)))\n criteriaStatus[criterion.name] = credit\n totalCredit += credit\n } else {\n const passed = criterion.check(state)\n criteriaStatus[criterion.name] = passed\n totalCredit += passed ? 1 : 0\n }\n }\n\n const completionPercent =\n this.criteria.length > 0 ? (totalCredit / this.criteria.length) * 100 : 100\n\n this.history.push({ turn, completionPercent, criteriaStatus })\n\n return {\n completionPercent,\n complete: totalCredit >= this.criteria.length,\n criteriaStatus,\n }\n }\n\n /** Get convergence curve */\n getCurve(): number[] {\n return this.history.map((h) => h.completionPercent)\n }\n\n /** Get full history with per-criterion status */\n getHistory() {\n return [...this.history]\n }\n\n /** Find the turn where completion first reached 100% (or null) */\n getTurnToCompletion(): number | null {\n const entry = this.history.find((h) => h.completionPercent === 100)\n return entry?.turn ?? null\n }\n}\n","import type { ProductClient } from './client'\nimport type { DriverState, TurnMetrics } from './types'\n\ninterface TokenPrice {\n input: number\n output: number\n}\n\n/** Per-1K token pricing for exact model ids. */\nexport const MODEL_PRICING: Record<string, TokenPrice> = {\n 'gpt-4o': { input: 0.0025, output: 0.01 },\n 'gpt-4o-mini': { input: 0.00015, output: 0.0006 },\n 'gpt-4-turbo': { input: 0.01, output: 0.03 },\n 'claude-sonnet-4-20250514': { input: 0.003, output: 0.015 },\n 'claude-opus-4-20250514': { input: 0.015, output: 0.075 },\n 'claude-3-haiku-20240307': { input: 0.00025, output: 0.00125 },\n}\n\n/** Family-level pricing fallbacks (per-1K), matched against a normalized id\n * after exact lookup misses. Ordered — first match wins. Covers the model\n * ids actually used through the Tangle router + cli-bridge harnesses\n * (`claude-code/sonnet`, `opencode/zai-coding-plan/glm-5.1`,\n * `kimi-code/kimi-k2.6`, `deepseek-v4-pro`, `anthropic/claude-sonnet-4-6`, …),\n * none of which appear in the exact table above — without this they priced\n * to a silent $0, blanking every cost/Pareto axis downstream. */\nconst FAMILY_PRICING: Array<[RegExp, TokenPrice]> = [\n [/claude.*opus/, { input: 0.015, output: 0.075 }],\n [/claude.*haiku/, { input: 0.0008, output: 0.004 }],\n [/claude.*sonnet|claude-code|claude-sonnet/, { input: 0.003, output: 0.015 }],\n [/gpt-4o-mini/, { input: 0.00015, output: 0.0006 }],\n [/gpt-5|gpt-4\\.1|o[134]\\b/, { input: 0.00125, output: 0.01 }],\n [/gpt-4o|gpt-4/, { input: 0.0025, output: 0.01 }],\n [/deepseek/, { input: 0.0003, output: 0.0011 }],\n [/glm|zhipu|zai/, { input: 0.0006, output: 0.0022 }],\n [/kimi|moonshot/, { input: 0.0006, output: 0.0025 }],\n [/qwen/, { input: 0.0004, output: 0.0012 }],\n [/gemini.*flash/, { input: 0.0001, output: 0.0004 }],\n [/gemini/, { input: 0.00125, output: 0.005 }],\n [/llama/, { input: 0.0002, output: 0.0006 }],\n]\n\n/** Normalize a model id for pricing: drop a `@snapshot` suffix, lowercase,\n * and keep the final harness/provider-prefixed segment so family regexes\n * match (`opencode/zai-coding-plan/glm-5.1` → `glm-5.1`). */\nfunction normalizeModelId(model: string): string {\n return (model.split('@')[0] ?? model).trim().toLowerCase()\n}\n\n/** Resolve pricing for a model id: exact table, then family fallback.\n * Returns null when the id matches nothing (caller decides — never a\n * silent-zero masquerading as a real $0 cost). */\nexport function resolveModelPricing(model: string): TokenPrice | null {\n if (MODEL_PRICING[model]) return MODEL_PRICING[model]\n const id = normalizeModelId(model)\n if (MODEL_PRICING[id]) return MODEL_PRICING[id]\n for (const [pattern, price] of FAMILY_PRICING) {\n if (pattern.test(id)) return price\n }\n return null\n}\n\n/** True when `model` has known pricing (exact or family). Lets cost-aware\n * callers distinguish a real $0 from an unpriced model. */\nexport function isModelPriced(model: string): boolean {\n return resolveModelPricing(model) !== null\n}\n\nconst warnedUnpricedModels = new Set<string>()\n\n/** Estimate token count from string length (chars / 4 approximation) */\nexport function estimateTokens(text: string): number {\n return Math.ceil(text.length / 4)\n}\n\n/** Calculate cost in USD from token counts and model. Unknown models warn\n * once (not a silent zero) and return 0 so callers that ignore pricing keep\n * working; cost-sensitive callers should gate on {@link isModelPriced}. */\nexport function estimateCost(inputTokens: number, outputTokens: number, model: string): number {\n const pricing = resolveModelPricing(model)\n if (!pricing) {\n if (!warnedUnpricedModels.has(model)) {\n warnedUnpricedModels.add(model)\n console.warn(\n `estimateCost: no pricing for model \"${model}\" — returning 0; add it to ` +\n 'MODEL_PRICING/FAMILY_PRICING (cost/Pareto axes will be blank until then)',\n )\n }\n return 0\n }\n return (inputTokens / 1000) * pricing.input + (outputTokens / 1000) * pricing.output\n}\n\n/**\n * TokenCounter — accumulates token usage and cost across turns.\n */\nexport class TokenCounter {\n private totalInput = 0\n private totalOutput = 0\n private totalCost = 0\n private model: string\n\n constructor(model = 'gpt-4o') {\n this.model = model\n }\n\n /** Record tokens for a turn, returns per-turn cost */\n record(inputTokens: number, outputTokens: number): number {\n this.totalInput += inputTokens\n this.totalOutput += outputTokens\n const cost = estimateCost(inputTokens, outputTokens, this.model)\n this.totalCost += cost\n return cost\n }\n\n /** Estimate and record from raw text */\n recordFromText(\n inputText: string,\n outputText: string,\n ): { inputTokens: number; outputTokens: number; cost: number } {\n const inputTokens = estimateTokens(inputText)\n const outputTokens = estimateTokens(outputText)\n const cost = this.record(inputTokens, outputTokens)\n return { inputTokens, outputTokens, cost }\n }\n\n getTotalInput(): number {\n return this.totalInput\n }\n getTotalOutput(): number {\n return this.totalOutput\n }\n getTotalCost(): number {\n return this.totalCost\n }\n}\n\n/**\n * MetricsCollector — collects per-turn metrics from the product.\n *\n * After each turn, queries the product's APIs to measure state changes.\n */\nexport class MetricsCollector {\n private client: ProductClient\n private workspaceId: string\n private metrics: TurnMetrics[] = []\n constructor(client: ProductClient, workspaceId: string) {\n this.client = client\n this.workspaceId = workspaceId\n }\n\n /** Collect metrics after a turn completes */\n async collect(\n turn: number,\n responseLatencyMs: number,\n responseChars: number,\n codeBlocksProduced: number,\n blocksExtracted: number,\n completionCriteriaMet: number,\n completionCriteriaTotal: number,\n qualityScore?: number,\n inputTokens = 0,\n outputTokens = 0,\n estimatedCostUsd = 0,\n ): Promise<TurnMetrics> {\n const state = await this.getState()\n\n const m: TurnMetrics = {\n turn,\n timestamp: new Date().toISOString(),\n tasks: state.tasks,\n events: state.events,\n proposals: state.proposals,\n vaultFiles: state.vaultFiles.length,\n responseLatencyMs,\n responseChars,\n codeBlocksProduced,\n blocksExtracted,\n qualityScore,\n inputTokens,\n outputTokens,\n estimatedCostUsd,\n totalCostUsd: estimatedCostUsd,\n completionPercent:\n completionCriteriaTotal > 0 ? (completionCriteriaMet / completionCriteriaTotal) * 100 : 0,\n }\n\n this.metrics.push(m)\n return m\n }\n\n /** Get current product state */\n async getState(): Promise<DriverState> {\n const [tasks, events, approvals, vaultFiles] = await Promise.all([\n this.client.getTasks(this.workspaceId),\n this.client.getEvents(this.workspaceId),\n this.client.getApprovals(this.workspaceId),\n this.client.getVaultTree(this.workspaceId),\n ])\n\n return {\n tasks: tasks.length,\n events: events.length,\n proposals: {\n pending: approvals.filter((a) => a.status === 'pending').length,\n approved: approvals.filter((a) => a.status === 'approved').length,\n rejected: approvals.filter((a) => a.status === 'rejected').length,\n },\n vaultFiles,\n codeBlocks: 0,\n generations: 0,\n }\n }\n\n /** Get all collected metrics */\n getMetrics(): TurnMetrics[] {\n return [...this.metrics]\n }\n\n /** Get convergence curve (completion% over turns) */\n getConvergenceCurve(): number[] {\n return this.metrics.map((m) => m.completionPercent)\n }\n}\n","import type { TCloud } from '@tangle-network/tcloud'\nimport type { ProductClient } from './client'\nimport { ConvergenceTracker } from './convergence'\nimport { MetricsCollector } from './metrics'\nimport type { DriverResult, DriverState, PersonaConfig, PersonaRigor, TurnMetrics } from './types'\n\nexport interface AgentDriverConfig {\n client: ProductClient\n driverModel?: string\n /** System prompt context for the driver LLM to understand the product */\n productContext?: string\n}\n\n/**\n * Per-rigor stance the driver LLM adopts. Scales how hard the simulated\n * user interrogates the agent — see `PersonaConfig.rigor`.\n */\nconst RIGOR_STANCE: Record<PersonaRigor, string> = {\n cooperative:\n 'Your stance: a pragmatic early adopter. You accept reasonable answers and only push back on clear gaps or outright errors.',\n demanding:\n 'Your stance: an experienced professional with no time to waste. You do not accept vague, hedged, or generic answers — you expect specifics, and you say so plainly when you do not get them.',\n relentless:\n 'Your stance: a senior partner reviewing this work for a client who will litigate if it is wrong. You interrogate every claim. You accept nothing undefended. You find the single weakest point in every answer and attack it. Courteous, never satisfied.',\n}\n\n/**\n * AgentDriver — meta-agent that plays a persona against the real product.\n *\n * Uses a driver LLM (Claude/GPT-4o) to decide what to say each turn.\n * Not scripted — the driver gets the current product state and decides\n * the next realistic user message.\n */\nexport class AgentDriver {\n private tc: TCloud\n private client: ProductClient\n private driverModel: string\n private productContext: string\n\n constructor(tc: TCloud, config: AgentDriverConfig) {\n this.tc = tc\n this.client = config.client\n this.driverModel = config.driverModel ?? 'claude-sonnet-4-6'\n this.productContext = config.productContext ?? ''\n }\n\n /**\n * Run a persona through the product.\n *\n * Returns metrics on how many turns to completion, cost curve,\n * quality curve, and convergence curve.\n */\n async run(persona: PersonaConfig): Promise<DriverResult> {\n // Setup: create workspace + thread\n const email = `eval-driver-${Date.now()}@test.agent-eval.local`\n await this.client.signup(`Driver ${persona.role}`, email, 'eval-driver-pass')\n await this.client.login(email, 'eval-driver-pass')\n const workspaceId = await this.client.createWorkspace(`${persona.role} Eval`)\n const threadId = await this.client.createThread(workspaceId)\n\n const metrics = new MetricsCollector(this.client, workspaceId)\n const convergence = new ConvergenceTracker(persona.completionCriteria)\n const turnMetrics: TurnMetrics[] = []\n const conversationHistory: { role: string; content: string }[] = []\n\n let completed = false\n let turnsToCompletion: number | null = null\n let criteriaMetAtTurn: number | null = null\n\n for (let turn = 1; turn <= persona.maxTurns; turn++) {\n // Get current product state\n const state = await metrics.getState()\n\n // Ask driver LLM what to say\n const userMessage = await this.decideNextMessage(persona, state, conversationHistory)\n\n if (userMessage === 'DONE') {\n completed = true\n turnsToCompletion = turn - 1\n console.log(` SIGNED OFF by simulated ${persona.role} after turn ${turn - 1}`)\n break\n }\n\n // Send to product\n const turnStart = Date.now()\n const response = await this.client.chat(workspaceId, threadId, userMessage)\n const latency = Date.now() - turnStart\n\n conversationHistory.push(\n { role: 'user', content: userMessage },\n { role: 'assistant', content: response.text },\n )\n\n // Wait for post-processor\n await new Promise((r) => setTimeout(r, 2000))\n\n // Handle pending approvals\n await this.handleApprovals(persona, workspaceId, state)\n\n // Check convergence\n const postState = await metrics.getState()\n const conv = convergence.record(turn, postState)\n\n // Collect metrics\n const codeBlockCount = (response.text.match(/```\\w+\\n/g) || []).length\n const m = await metrics.collect(\n turn,\n latency,\n response.text.length,\n codeBlockCount,\n response.blocks.length,\n Object.values(conv.criteriaStatus).filter(Boolean).length,\n persona.completionCriteria.length,\n )\n turnMetrics.push(m)\n\n // Print turn status\n const criteriaStr = Object.entries(conv.criteriaStatus)\n .map(([k, v]) => `${k}:${v ? '+' : '-'}`)\n .join(' ')\n console.log(\n ` [turn ${turn}] ${conv.completionPercent.toFixed(0)}% — ${criteriaStr} (${(latency / 1000).toFixed(1)}s)`,\n )\n\n // Nominal criteria met is recorded, not a stop condition. The\n // simulated professional keeps pressure-testing until genuinely\n // satisfied — a criteria-met-but-sloppy answer must still be defended.\n if (conv.complete && criteriaMetAtTurn === null) {\n criteriaMetAtTurn = turn\n console.log(` criteria met at turn ${turn} — driver continues pressure-testing`)\n }\n }\n\n const finalState = await metrics.getState()\n\n return {\n personaId: persona.id,\n completed,\n turnsToCompletion,\n criteriaMetAtTurn,\n totalTurns: turnMetrics.length,\n metrics: turnMetrics,\n finalState,\n convergenceCurve: convergence.getCurve(),\n totalCostUsd: 0,\n finalQualityScore: null,\n }\n }\n\n /** Use the driver LLM to decide what the \"user\" says next */\n private async decideNextMessage(\n persona: PersonaConfig,\n state: DriverState,\n history: { role: string; content: string }[],\n ): Promise<string> {\n return decideNextUserTurn(this.tc, {\n persona,\n state,\n history,\n productContext: this.productContext,\n model: this.driverModel,\n })\n }\n\n /** Handle pending approvals based on persona feedback patterns */\n private async handleApprovals(\n persona: PersonaConfig,\n workspaceId: string,\n _state: DriverState,\n ): Promise<void> {\n const approvals = await this.client.getApprovals(workspaceId)\n const pending = approvals.filter((a) => a.status === 'pending')\n\n for (const action of pending) {\n // Check if any feedback pattern triggers a rejection\n const rejection = persona.feedbackPatterns?.find((fp) => {\n const title = action.title.toLowerCase()\n return title.includes(fp.trigger.toLowerCase())\n })\n\n if (rejection) {\n await this.client.rejectAction(workspaceId, action.id, rejection.response)\n console.log(` rejected: ${action.title} — ${rejection.response.slice(0, 60)}`)\n } else {\n await this.client.approveAction(workspaceId, action.id)\n console.log(` approved: ${action.title}`)\n }\n }\n }\n}\n\n/** Describe which nominal completion criteria are met, for the driver prompt. */\nfunction describeCompletion(persona: PersonaConfig, state: DriverState): string {\n const results = persona.completionCriteria.map((c) => {\n const met = c.check(state)\n return `${c.name}: ${met ? 'MET' : 'NOT MET'}`\n })\n const metCount = results.filter((r) => r.includes('MET') && !r.includes('NOT')).length\n return `${metCount}/${persona.completionCriteria.length} — ${results.join(', ')}`\n}\n\n/**\n * Build the driver LLM's system prompt. The simulated user is an\n * adversarial senior professional: it judges the agent's last response by a\n * professional standard, refuses vague answers, challenges undefended\n * claims, probes the persona's pressure points without revealing them, and\n * signs off (DONE) only when a real practitioner would act on the work\n * unmodified. Pure function of persona, product state, and product context\n * — exported so harness authors can inspect and regression-test it.\n */\nexport function buildDriverSystemPrompt(\n persona: PersonaConfig,\n state: DriverState,\n productContext = '',\n): string {\n const rigor: PersonaRigor = persona.rigor ?? 'demanding'\n const expertise = persona.expertise ? ` You are ${persona.expertise}.` : ''\n\n const pressure =\n persona.pressurePoints && persona.pressurePoints.length > 0\n ? `\\nA competent ${persona.role} here MUST get the agent to address each of:\\n${persona.pressurePoints\n .map((p) => ` - ${p}`)\n .join(\n '\\n',\n )}\\nDo NOT hand these to the agent. Probe whether it surfaces them itself. If it misses one, press on exactly that gap until it delivers or demonstrably fails.\\n`\n : ''\n\n const curveballs =\n persona.curveballs && persona.curveballs.length > 0\n ? `\\nOnce the agent is coasting on easy answers, introduce ONE of these as a genuine new development — never as a quiz:\\n${persona.curveballs\n .map((c) => ` - ${c}`)\n .join('\\n')}\\n`\n : ''\n\n return `You are role-playing a real ${persona.role} putting an AI agent through its paces.${expertise}\nYour objective: ${persona.goal}\nYou are deciding whether this agent's work is good enough to stake your professional reputation on. Assume it is not — until it proves otherwise.\n\n${RIGOR_STANCE[rigor]}\n${productContext ? `Product context:\\n${productContext}\\n` : ''}Current workspace state:\n- Tasks: ${state.tasks} | Events: ${state.events}\n- Proposals: pending=${state.proposals.pending}, approved=${state.proposals.approved}, rejected=${state.proposals.rejected}\n- Vault files (${state.vaultFiles.length}): ${state.vaultFiles.slice(0, 10).join(', ')}${state.vaultFiles.length > 10 ? ' …' : ''}\n- Nominal task criteria: ${describeCompletion(persona, state)}\n${pressure}${curveballs}\nHow to choose your next message:\n1. Silently judge the agent's last response the way a ${persona.role} would. Is every claim defended with a specific authority, figure, or mechanism? Or is it vague, hedged, or generic?\n2. If it is vague or hand-waved — do NOT move on. Name the gap and demand the specific authority / figure / mechanism. \"It depends\" is not an answer; force the decision.\n3. If it makes a claim you can challenge — challenge it. Make the agent defend or correct it.\n4. If it missed something a ${persona.role} would catch — press on exactly that, without naming it for the agent.\n5. If it is genuinely solid — escalate: go a layer deeper, or introduce a curveball.\n6. First message — state your situation as you really would: realistic, specific, with the messy detail, but do not coach the agent.\n\nSign-off: respond with exactly \"DONE\" only when a ${persona.role} would act on this work without redoing it. Nominal task completion is NOT sign-off — sloppy-but-complete still fails. If the agent never gets there, keep pushing; never sign off on weak work.\n\nOutput ONLY your next message to the agent — in character, first person, no meta-commentary, no stage directions.`\n}\n\nexport interface DecideNextUserTurnOpts {\n persona: PersonaConfig\n state: DriverState\n /** Conversation so far — alternating user/assistant messages, oldest first. */\n history: { role: string; content: string }[]\n /** Optional product context woven into the driver prompt. */\n productContext?: string\n /** Driver LLM model. Defaults to claude-sonnet-4-6. */\n model?: string\n}\n\n/**\n * Decide the simulated user's next turn — the reactive, adversarial\n * turn-generation core of `AgentDriver`, exposed standalone so an in-process\n * eval harness can drive multi-shot conversations without the `ProductClient`\n * workspace machinery. Returns the next user message, or the literal \"DONE\"\n * when the simulated professional would sign off.\n */\nexport async function decideNextUserTurn(\n tc: TCloud,\n opts: DecideNextUserTurnOpts,\n): Promise<string> {\n const { persona, state, history, productContext = '', model = 'claude-sonnet-4-6' } = opts\n\n const lastResponse =\n history.length > 0\n ? history[history.length - 1]!.content.slice(0, 2000)\n : '(no conversation yet — this is the first message)'\n\n const recentHistory = history\n .slice(-6)\n .map((h) => `${h.role}: ${h.content.slice(0, 500)}`)\n .join('\\n\\n')\n\n const resp = await tc.chat({\n model,\n messages: [\n { role: 'system', content: buildDriverSystemPrompt(persona, state, productContext) },\n {\n role: 'user',\n content: recentHistory\n ? `Recent conversation:\\n${recentHistory}\\n\\nThe agent's latest response:\\n${lastResponse}`\n : 'No conversation yet. Send your opening message — in character, phrased as this person actually would.',\n },\n ],\n temperature: 0.5,\n maxTokens: 700,\n })\n\n const content =\n (resp as { choices?: { message?: { content?: string } }[] }).choices?.[0]?.message?.content ??\n ''\n\n return content.trim()\n}\n","import type { ControlEvalResult, ControlRunResult, ControlStep } from './control-runtime'\nimport type { DatasetScenario, DatasetSplit } from './dataset'\n\nexport type FeedbackArtifactType =\n | 'text'\n | 'code'\n | 'plan'\n | 'research'\n | 'action'\n | 'ui'\n | 'decision'\n | 'data'\n | 'other'\n\nexport type FeedbackLabelSource = 'user' | 'judge' | 'environment' | 'metric' | 'policy' | 'system'\n\nexport type FeedbackLabelKind =\n | 'approve'\n | 'reject'\n | 'select'\n | 'edit'\n | 'rank'\n | 'rate'\n | 'comment'\n | 'metric_outcome'\n | 'policy_block'\n | 'revision_request'\n\nexport type FeedbackSeverity = 'info' | 'warning' | 'error' | 'critical'\n\nexport interface FeedbackTask {\n intent: string\n context?: unknown\n}\n\nexport interface ProposedSideEffect {\n type: string\n risk?: 'low' | 'medium' | 'high'\n costUsd?: number\n externalSideEffect?: boolean\n requiresApproval?: boolean\n metadata?: Record<string, unknown>\n}\n\nexport interface FeedbackLabel {\n id?: string\n source: FeedbackLabelSource\n kind: FeedbackLabelKind\n value: unknown\n reason?: string\n severity?: FeedbackSeverity\n createdAt: string\n metadata?: Record<string, unknown>\n}\n\nexport interface FeedbackAttempt {\n id: string\n stepIndex: number\n artifactType: FeedbackArtifactType\n artifact: unknown\n options?: unknown[]\n proposedAction?: ProposedSideEffect\n evals?: ControlEvalResult[]\n feedback?: FeedbackLabel[]\n createdAt: string\n metadata?: Record<string, unknown>\n}\n\nexport interface FeedbackOutcome {\n success?: boolean\n score?: number\n metrics?: Record<string, number>\n costUsd?: number\n detail?: string\n observedAt?: string\n metadata?: Record<string, unknown>\n}\n\nexport interface FeedbackTrajectory {\n id: string\n projectId?: string\n scenarioId?: string\n task: FeedbackTask\n attempts: FeedbackAttempt[]\n labels: FeedbackLabel[]\n outcome?: FeedbackOutcome\n split?: DatasetSplit\n tags?: Record<string, string>\n createdAt: string\n updatedAt?: string\n metadata?: Record<string, unknown>\n}\n\nexport interface FeedbackTrajectoryStore {\n save(trajectory: FeedbackTrajectory): Promise<void>\n get(id: string): Promise<FeedbackTrajectory | null>\n list(filter?: FeedbackTrajectoryFilter): Promise<FeedbackTrajectory[]>\n appendAttempt(id: string, attempt: FeedbackAttempt): Promise<FeedbackTrajectory>\n appendLabel(id: string, label: FeedbackLabel, attemptId?: string): Promise<FeedbackTrajectory>\n}\n\nexport interface FeedbackTrajectoryFilter {\n projectId?: string\n scenarioId?: string\n split?: DatasetSplit\n tag?: [string, string]\n}\n\nexport interface FeedbackSplitPolicy {\n trainPct?: number\n devPct?: number\n testPct?: number\n holdoutPct?: number\n}\n\nexport interface PreferenceMemoryEntry {\n instruction: string\n rationale: string\n weight: number\n sourceTrajectoryId: string\n sourceLabelId?: string\n category?: string\n}\n\nexport interface FeedbackOptimizerRow {\n scenarioId: string\n trajectoryId: string\n labelKinds: FeedbackLabelKind[]\n score?: number\n metadata?: Record<string, unknown>\n}\n\nexport interface FeedbackReplayResult {\n trajectoryId: string\n pass: boolean\n score?: number\n labels: FeedbackLabel[]\n outcome?: FeedbackOutcome\n metadata?: Record<string, unknown>\n}\n\nexport interface FeedbackReplayAdapter {\n replay(\n trajectory: FeedbackTrajectory,\n ):\n | Promise<Omit<FeedbackReplayResult, 'trajectoryId'>>\n | Omit<FeedbackReplayResult, 'trajectoryId'>\n}\n\nconst DEFAULT_SPLIT_POLICY: Required<FeedbackSplitPolicy> = {\n trainPct: 70,\n devPct: 15,\n testPct: 10,\n holdoutPct: 5,\n}\n\nexport class InMemoryFeedbackTrajectoryStore implements FeedbackTrajectoryStore {\n private readonly trajectories = new Map<string, FeedbackTrajectory>()\n\n async save(trajectory: FeedbackTrajectory): Promise<void> {\n this.trajectories.set(trajectory.id, cloneTrajectory(trajectory))\n }\n\n async get(id: string): Promise<FeedbackTrajectory | null> {\n const trajectory = this.trajectories.get(id)\n return trajectory ? cloneTrajectory(trajectory) : null\n }\n\n async list(filter: FeedbackTrajectoryFilter = {}): Promise<FeedbackTrajectory[]> {\n return [...this.trajectories.values()]\n .filter((trajectory) => matchesFilter(trajectory, filter))\n .map(cloneTrajectory)\n }\n\n async appendAttempt(id: string, attempt: FeedbackAttempt): Promise<FeedbackTrajectory> {\n const trajectory = this.trajectories.get(id)\n if (!trajectory)\n throw new Error(`FeedbackTrajectoryStore.appendAttempt: unknown trajectory \"${id}\"`)\n const next = cloneTrajectory({\n ...trajectory,\n attempts: [...trajectory.attempts, attempt],\n updatedAt: attempt.createdAt,\n })\n this.trajectories.set(id, next)\n return cloneTrajectory(next)\n }\n\n async appendLabel(\n id: string,\n label: FeedbackLabel,\n attemptId?: string,\n ): Promise<FeedbackTrajectory> {\n const trajectory = this.trajectories.get(id)\n if (!trajectory)\n throw new Error(`FeedbackTrajectoryStore.appendLabel: unknown trajectory \"${id}\"`)\n const attempts = attemptId\n ? trajectory.attempts.map((attempt) =>\n attempt.id === attemptId\n ? { ...attempt, feedback: [...(attempt.feedback ?? []), label] }\n : attempt,\n )\n : trajectory.attempts\n const next = cloneTrajectory({\n ...trajectory,\n attempts,\n labels: attemptId ? trajectory.labels : [...trajectory.labels, label],\n updatedAt: label.createdAt,\n })\n this.trajectories.set(id, next)\n return cloneTrajectory(next)\n }\n}\n\nexport class FileSystemFeedbackTrajectoryStore implements FeedbackTrajectoryStore {\n private readonly dir: string\n private readonly memory = new InMemoryFeedbackTrajectoryStore()\n private loaded = false\n\n constructor(options: { dir: string }) {\n this.dir = options.dir\n }\n\n async save(trajectory: FeedbackTrajectory): Promise<void> {\n await this.load()\n await this.memory.save(trajectory)\n await this.append({ op: 'save', trajectory })\n }\n\n async get(id: string): Promise<FeedbackTrajectory | null> {\n await this.load()\n return this.memory.get(id)\n }\n\n async list(filter: FeedbackTrajectoryFilter = {}): Promise<FeedbackTrajectory[]> {\n await this.load()\n return this.memory.list(filter)\n }\n\n async appendAttempt(id: string, attempt: FeedbackAttempt): Promise<FeedbackTrajectory> {\n await this.load()\n const next = await this.memory.appendAttempt(id, attempt)\n await this.append({ op: 'appendAttempt', id, attempt })\n return next\n }\n\n async appendLabel(\n id: string,\n label: FeedbackLabel,\n attemptId?: string,\n ): Promise<FeedbackTrajectory> {\n await this.load()\n const next = await this.memory.appendLabel(id, label, attemptId)\n await this.append({ op: 'appendLabel', id, label, attemptId })\n return next\n }\n\n private async append(record: unknown): Promise<void> {\n const { appendFile, mkdir } = await import('node:fs/promises')\n const { join } = await import('node:path')\n await mkdir(this.dir, { recursive: true })\n await appendFile(\n join(this.dir, 'feedback-trajectories.ndjson'),\n `${JSON.stringify(record)}\\n`,\n 'utf8',\n )\n }\n\n private async load(): Promise<void> {\n if (this.loaded) return\n const { readFile } = await import('node:fs/promises')\n const { join } = await import('node:path')\n const file = join(this.dir, 'feedback-trajectories.ndjson')\n try {\n const raw = await readFile(file, 'utf8')\n for (const line of raw.split('\\n')) {\n if (!line.trim()) continue\n try {\n const record = JSON.parse(line) as\n | { op: 'save'; trajectory: FeedbackTrajectory }\n | { op: 'appendAttempt'; id: string; attempt: FeedbackAttempt }\n | { op: 'appendLabel'; id: string; label: FeedbackLabel; attemptId?: string }\n if (record.op === 'save') await this.memory.save(record.trajectory)\n if (record.op === 'appendAttempt')\n await this.memory.appendAttempt(record.id, record.attempt)\n if (record.op === 'appendLabel')\n await this.memory.appendLabel(record.id, record.label, record.attemptId)\n } catch {\n /* corrupt records are skipped so one bad line does not discard the corpus */\n }\n }\n } catch {\n /* first run */\n }\n this.loaded = true\n }\n}\n\nexport function createFeedbackTrajectory(input: {\n id?: string\n projectId?: string\n scenarioId?: string\n task: FeedbackTask\n attempts?: FeedbackAttempt[]\n labels?: FeedbackLabel[]\n outcome?: FeedbackOutcome\n split?: DatasetSplit\n tags?: Record<string, string>\n createdAt?: string\n metadata?: Record<string, unknown>\n}): FeedbackTrajectory {\n const createdAt = input.createdAt ?? new Date().toISOString()\n const id =\n input.id ??\n `ft_${stableHash(`${input.projectId ?? ''}|${input.scenarioId ?? ''}|${input.task.intent}|${createdAt}`).toString(16)}`\n return {\n id,\n projectId: input.projectId,\n scenarioId: input.scenarioId,\n task: input.task,\n attempts: input.attempts ?? [],\n labels: input.labels ?? [],\n outcome: input.outcome,\n split: input.split,\n tags: input.tags,\n createdAt,\n metadata: input.metadata,\n }\n}\n\nexport function assignFeedbackSplit(\n trajectory: Pick<FeedbackTrajectory, 'id' | 'projectId' | 'scenarioId' | 'task'>,\n policy: FeedbackSplitPolicy = {},\n): DatasetSplit {\n const split = { ...DEFAULT_SPLIT_POLICY, ...policy }\n const total = split.trainPct + split.devPct + split.testPct + split.holdoutPct\n if (total <= 0) throw new Error('assignFeedbackSplit: split percentages must sum above zero')\n const bucket =\n stableHash(\n `${trajectory.projectId ?? ''}|${trajectory.scenarioId ?? ''}|${trajectory.id}|${trajectory.task.intent}`,\n ) % total\n if (bucket < split.trainPct) return 'train'\n if (bucket < split.trainPct + split.devPct) return 'dev'\n if (bucket < split.trainPct + split.devPct + split.testPct) return 'test'\n return 'holdout'\n}\n\nexport function withAssignedFeedbackSplit(\n trajectory: FeedbackTrajectory,\n policy?: FeedbackSplitPolicy,\n): FeedbackTrajectory {\n return {\n ...trajectory,\n split: trajectory.split ?? assignFeedbackSplit(trajectory, policy),\n }\n}\n\nexport function feedbackTrajectoryToDatasetScenario(\n trajectory: FeedbackTrajectory,\n): DatasetScenario {\n const withSplit = withAssignedFeedbackSplit(trajectory)\n return {\n id: withSplit.scenarioId ?? withSplit.id,\n split: withSplit.split,\n payload: withSplit,\n tags: {\n ...(withSplit.projectId ? { projectId: withSplit.projectId } : {}),\n ...(withSplit.tags ?? {}),\n source: 'feedback-trajectory',\n },\n }\n}\n\nexport function feedbackTrajectoriesToDatasetScenarios(\n trajectories: FeedbackTrajectory[],\n): DatasetScenario[] {\n return trajectories.map(feedbackTrajectoryToDatasetScenario)\n}\n\nexport function feedbackTrajectoryToOptimizerRow(\n trajectory: FeedbackTrajectory,\n): FeedbackOptimizerRow {\n const labels = allLabels(trajectory)\n return {\n scenarioId: trajectory.scenarioId ?? trajectory.id,\n trajectoryId: trajectory.id,\n labelKinds: [...new Set(labels.map((label) => label.kind))],\n score: trajectory.outcome?.score ?? scoreFromLabels(labels),\n metadata: {\n projectId: trajectory.projectId,\n split: trajectory.split,\n intent: trajectory.task.intent,\n attempts: trajectory.attempts.length,\n outcome: trajectory.outcome,\n labels,\n },\n }\n}\n\nexport function feedbackTrajectoriesToOptimizerRows(\n trajectories: FeedbackTrajectory[],\n): FeedbackOptimizerRow[] {\n return trajectories.map(feedbackTrajectoryToOptimizerRow)\n}\n\nexport async function replayFeedbackTrajectory(\n trajectory: FeedbackTrajectory,\n adapter: FeedbackReplayAdapter,\n): Promise<FeedbackReplayResult> {\n try {\n const result = await adapter.replay(trajectory)\n return {\n trajectoryId: trajectory.id,\n ...result,\n }\n } catch (err) {\n const createdAt = new Date().toISOString()\n const message = err instanceof Error ? err.message : String(err)\n return {\n trajectoryId: trajectory.id,\n pass: false,\n labels: [\n {\n source: 'system',\n kind: 'reject',\n value: false,\n reason: message,\n severity: 'error',\n createdAt,\n },\n ],\n outcome: {\n success: false,\n score: 0,\n detail: message,\n observedAt: createdAt,\n },\n metadata: { replayError: true },\n }\n }\n}\n\nexport async function replayFeedbackTrajectories(\n trajectories: FeedbackTrajectory[],\n adapter: FeedbackReplayAdapter,\n): Promise<FeedbackReplayResult[]> {\n const results: FeedbackReplayResult[] = []\n for (const trajectory of trajectories) {\n results.push(await replayFeedbackTrajectory(trajectory, adapter))\n }\n return results\n}\n\nexport function summarizePreferenceMemory(\n trajectories: FeedbackTrajectory[],\n options: { maxEntries?: number } = {},\n): PreferenceMemoryEntry[] {\n const maxEntries = options.maxEntries ?? 20\n const entries: PreferenceMemoryEntry[] = []\n for (const trajectory of trajectories) {\n for (const label of allLabels(trajectory)) {\n const instruction = instructionFromLabel(trajectory, label)\n if (!instruction) continue\n entries.push({\n instruction,\n rationale: label.reason ?? `${label.kind} label from ${label.source}`,\n weight: weightForLabel(label),\n sourceTrajectoryId: trajectory.id,\n sourceLabelId: label.id,\n category: label.kind,\n })\n }\n }\n\n const byInstruction = new Map<string, PreferenceMemoryEntry>()\n for (const entry of entries) {\n const key = entry.instruction.toLowerCase().replace(/\\s+/g, ' ').trim()\n const existing = byInstruction.get(key)\n if (!existing || entry.weight > existing.weight) byInstruction.set(key, entry)\n }\n return [...byInstruction.values()].sort((a, b) => b.weight - a.weight).slice(0, maxEntries)\n}\n\nexport function renderPreferenceMemoryMarkdown(entries: PreferenceMemoryEntry[]): string {\n const lines = ['# Preference Memory', '']\n for (const entry of entries) {\n lines.push(`- ${entry.instruction}`)\n lines.push(` Rationale: ${entry.rationale}`)\n lines.push(` Source: ${entry.sourceTrajectoryId}`)\n lines.push('')\n }\n return `${lines.join('\\n').trim()}\\n`\n}\n\nexport function serializeFeedbackTrajectoriesJsonl(trajectories: FeedbackTrajectory[]): string {\n return `${trajectories\n .slice()\n .sort((a, b) => a.id.localeCompare(b.id))\n .map((trajectory) => JSON.stringify(canonicalize(trajectory)))\n .join('\\n')}\\n`\n}\n\nexport function parseFeedbackTrajectoriesJsonl(jsonl: string): FeedbackTrajectory[] {\n const trajectories: FeedbackTrajectory[] = []\n for (const line of jsonl.split('\\n')) {\n if (!line.trim()) continue\n trajectories.push(JSON.parse(line) as FeedbackTrajectory)\n }\n return trajectories\n}\n\nexport function controlRunToFeedbackTrajectory<TState, TAction, TActionResult>(\n run: ControlRunResult<TState, TAction, TActionResult>,\n options: {\n projectId?: string\n scenarioId?: string\n artifactType?: FeedbackArtifactType\n artifactFromStep?: (step: ControlStep<TState, TAction, TActionResult>) => unknown\n proposedActionFromStep?: (\n step: ControlStep<TState, TAction, TActionResult>,\n ) => ProposedSideEffect | undefined\n createdAt?: string\n } = {},\n): FeedbackTrajectory {\n const createdAt = options.createdAt ?? new Date().toISOString()\n const trajectoryId =\n run.runId ?? `ft_control_${stableHash(`${run.intent}|${createdAt}`).toString(16)}`\n return createFeedbackTrajectory({\n id: trajectoryId,\n projectId: options.projectId,\n scenarioId: options.scenarioId,\n task: { intent: run.intent },\n createdAt,\n attempts: run.steps.map((step) => ({\n id: `${trajectoryId}_step_${step.index}`,\n stepIndex: step.index,\n artifactType: options.artifactType ?? 'action',\n artifact: options.artifactFromStep?.(step) ?? step.actionOutcome?.result ?? step.decision,\n proposedAction: options.proposedActionFromStep?.(step),\n evals: step.evalsAfter,\n createdAt: step.startedAt,\n metadata: {\n decision: step.decision,\n actionOutcome: step.actionOutcome,\n },\n })),\n labels: [\n {\n source: 'system',\n kind: run.pass ? 'approve' : 'reject',\n value: run.pass,\n reason: run.reason,\n severity: run.pass ? 'info' : 'error',\n createdAt,\n },\n ],\n outcome: {\n success: run.pass,\n score: run.score,\n costUsd: run.spentCostUsd,\n detail: run.reason,\n observedAt: createdAt,\n metadata: {\n stoppedBy: run.stoppedBy,\n failureClass: run.failureClass,\n },\n },\n })\n}\n\nfunction allLabels(trajectory: FeedbackTrajectory): FeedbackLabel[] {\n const labels = [\n ...trajectory.labels,\n ...trajectory.attempts.flatMap((attempt) => attempt.feedback ?? []),\n ]\n const seen = new Set<string>()\n return labels.filter((label) => {\n const key =\n label.id ?? `${label.source}|${label.kind}|${label.createdAt}|${JSON.stringify(label.value)}`\n if (seen.has(key)) return false\n seen.add(key)\n return true\n })\n}\n\nfunction scoreFromLabels(labels: FeedbackLabel[]): number | undefined {\n if (!labels.length) return undefined\n const scored = labels\n .map((label) => {\n if (label.kind === 'approve' || label.kind === 'select') return 1\n if (label.kind === 'reject' || label.kind === 'policy_block') return 0\n if (label.kind === 'rate' && typeof label.value === 'number')\n return Math.max(0, Math.min(1, label.value))\n return undefined\n })\n .filter((value): value is number => typeof value === 'number')\n if (!scored.length) return undefined\n return Math.round((scored.reduce((sum, value) => sum + value, 0) / scored.length) * 1000) / 1000\n}\n\nfunction instructionFromLabel(\n trajectory: FeedbackTrajectory,\n label: FeedbackLabel,\n): string | undefined {\n if (label.kind === 'reject' && label.reason)\n return `Avoid outputs like \"${compact(trajectory.task.intent, 80)}\" when: ${label.reason}`\n if (label.kind === 'revision_request' && label.reason)\n return `Revise similar work by applying: ${label.reason}`\n if (label.kind === 'select' && label.reason)\n return `Prefer selected options for \"${compact(trajectory.task.intent, 80)}\" because: ${label.reason}`\n if (label.kind === 'approve' && label.reason)\n return `Repeat the pattern approved for \"${compact(trajectory.task.intent, 80)}\": ${label.reason}`\n if (label.kind === 'comment' && label.reason) return label.reason\n return undefined\n}\n\nfunction weightForLabel(label: FeedbackLabel): number {\n const severity =\n label.severity === 'critical'\n ? 4\n : label.severity === 'error'\n ? 3\n : label.severity === 'warning'\n ? 2\n : 1\n const source =\n label.source === 'user'\n ? 3\n : label.source === 'metric' || label.source === 'environment'\n ? 2\n : 1\n return severity * source\n}\n\nfunction matchesFilter(trajectory: FeedbackTrajectory, filter: FeedbackTrajectoryFilter): boolean {\n if (filter.projectId && trajectory.projectId !== filter.projectId) return false\n if (filter.scenarioId && trajectory.scenarioId !== filter.scenarioId) return false\n if (filter.split && trajectory.split !== filter.split) return false\n if (filter.tag) {\n const [key, value] = filter.tag\n if (trajectory.tags?.[key] !== value) return false\n }\n return true\n}\n\nfunction cloneTrajectory(trajectory: FeedbackTrajectory): FeedbackTrajectory {\n return JSON.parse(JSON.stringify(trajectory)) as FeedbackTrajectory\n}\n\nfunction compact(value: string, max: number): string {\n const normalized = value.replace(/\\s+/g, ' ').trim()\n return normalized.length > max ? `${normalized.slice(0, max).trim()}...` : normalized\n}\n\nfunction stableHash(input: string): number {\n let hash = 2166136261\n for (let i = 0; i < input.length; i += 1) {\n hash ^= input.charCodeAt(i)\n hash = Math.imul(hash, 16777619)\n }\n return hash >>> 0\n}\n\nfunction canonicalize(value: unknown): unknown {\n if (value === null || typeof value !== 'object') return value\n if (Array.isArray(value)) return value.map(canonicalize)\n const out: Record<string, unknown> = {}\n for (const key of Object.keys(value as Record<string, unknown>).sort()) {\n out[key] = canonicalize((value as Record<string, unknown>)[key])\n }\n return out\n}\n","/**\n * Single-backend guard: assert the agent and the rubric judge run through the\n * SAME backend config, so the judge can't silently re-route through a\n * different (often paid) backend than the agent.\n *\n * The bug class: `--backend cli-bridge` rewires the agent, but the judge still\n * reads `process.env.TANGLE_API_KEY` → router. Cost is billed against the\n * router, the eval reports the cli-bridge model, and the data is unusable.\n * Four consumers hand-roll this comparison (legal at `canonical.ts:702-795`);\n * this is the one substrate copy.\n *\n * Complements `assertRealBackend` (records → stub vs real) and\n * `assertCrossFamily` (judge-ensemble family diversity): this one compares two\n * backend *configs* before the run.\n */\n\nimport { AgentEvalError } from '../errors'\n\n/**\n * Minimal backend-config shape the assertion reads. Consumers may pass richer\n * types — only these five fields are inspected.\n */\nexport interface BackendDescriptor {\n /** Backend route — e.g. `'tcloud' | 'cli-bridge' | 'sandbox' | 'direct-provider'`;\n * free-form for consumer extensibility. */\n kind: string\n /** Resolved base URL. Compared lexically (trailing slash stripped). */\n baseUrl: string\n /** Model id (with snapshot suffix). Compared lexically. */\n model: string\n /** Optional provider override. Compared when both set; flagged when only\n * one side sets it. */\n provider?: string\n /** Bearer token. Values are NEVER compared (security) — only that EITHER\n * both are set OR both are empty. Mismatched presence is a divergence. */\n apiKey?: string\n}\n\nexport interface AssertSingleBackendOptions {\n /** When true, ANY field divergence fails. When false (default), only\n * `kind` / `baseUrl` / `provider` / `apiKeyPresence` divergence throws —\n * a different judge `model` on the same route is allowed (the legal\n * pattern: a cheaper judge model). */\n strict?: boolean\n agentLabel?: string\n judgeLabel?: string\n}\n\nexport type SingleBackendField = 'kind' | 'baseUrl' | 'model' | 'provider' | 'apiKeyPresence'\n\nexport interface SingleBackendDivergence {\n field: SingleBackendField\n agent: string | undefined\n judge: string | undefined\n}\n\nexport interface SingleBackendReport {\n /** True when agent + judge agree per the configured strictness. */\n ok: boolean\n /** Every divergence detected (includes `model` even when non-blocking). */\n divergences: ReadonlyArray<SingleBackendDivergence>\n}\n\nexport class SingleBackendError extends AgentEvalError {\n constructor(\n message: string,\n public readonly report: SingleBackendReport,\n ) {\n super('backend_integrity', message)\n this.name = 'SingleBackendError'\n }\n}\n\nfunction stripSlash(url: string): string {\n return url.replace(/\\/+$/, '')\n}\n\n/**\n * Throw `SingleBackendError` when the agent and judge backends diverge in a\n * way that would re-route the judge through a different backend than the\n * agent. Returns the report so callers can log it in either case.\n */\nexport function assertSingleBackend(\n agent: BackendDescriptor,\n judge: BackendDescriptor,\n opts: AssertSingleBackendOptions = {},\n): SingleBackendReport {\n const divergences: SingleBackendDivergence[] = []\n\n if (agent.kind !== judge.kind) {\n divergences.push({ field: 'kind', agent: agent.kind, judge: judge.kind })\n }\n if (stripSlash(agent.baseUrl) !== stripSlash(judge.baseUrl)) {\n divergences.push({ field: 'baseUrl', agent: agent.baseUrl, judge: judge.baseUrl })\n }\n if (agent.model !== judge.model) {\n divergences.push({ field: 'model', agent: agent.model, judge: judge.model })\n }\n // provider: compare when both set; flag when exactly one is set.\n if (agent.provider !== judge.provider) {\n divergences.push({ field: 'provider', agent: agent.provider, judge: judge.provider })\n }\n // apiKey: presence only, never the value.\n const agentHasKey = Boolean(agent.apiKey)\n const judgeHasKey = Boolean(judge.apiKey)\n if (agentHasKey !== judgeHasKey) {\n divergences.push({\n field: 'apiKeyPresence',\n agent: agentHasKey ? 'set' : 'empty',\n judge: judgeHasKey ? 'set' : 'empty',\n })\n }\n\n const blocking = opts.strict ? divergences : divergences.filter((d) => d.field !== 'model')\n const ok = blocking.length === 0\n const report: SingleBackendReport = { ok, divergences }\n\n if (!ok) {\n const agentLabel = opts.agentLabel ?? 'agent'\n const judgeLabel = opts.judgeLabel ?? 'judge'\n const detail = blocking\n .map((d) => `${d.field}: ${agentLabel}=${d.agent ?? '∅'} vs ${judgeLabel}=${d.judge ?? '∅'}`)\n .join('; ')\n throw new SingleBackendError(\n `single-backend: ${agentLabel} and ${judgeLabel} backends diverge — the judge would ` +\n `re-route through a different backend than the agent (${detail})`,\n report,\n )\n }\n\n return report\n}\n","/**\n * Judge model-family classification + cross-family enforcement.\n *\n * A judge ensemble built entirely from one provider family shares that\n * family's blind spots and self-preference — its \"agreement\" is correlated\n * bias, not independent signal. `assertCrossFamily` makes the consumer prove\n * the ensemble spans ≥2 families; `judgeFamily` is the single regex map that\n * replaces the per-consumer copies (tax/legal/creative/gtm each ship one).\n */\n\n/** Provider family a model belongs to. `unknown` when no rule matches. */\nexport type JudgeFamily =\n | 'anthropic'\n | 'openai'\n | 'google'\n | 'meta'\n | 'mistral'\n | 'deepseek'\n | 'xai'\n | 'qwen'\n | 'cohere'\n | 'amazon'\n | 'moonshot'\n | 'zhipu'\n | 'unknown'\n\n/** Explicit `provider/...` prefix → family (models.dev / OpenRouter style). */\nconst PROVIDER_PREFIX: Record<string, JudgeFamily> = {\n anthropic: 'anthropic',\n openai: 'openai',\n 'azure-openai': 'openai',\n google: 'google',\n 'google-vertex': 'google',\n meta: 'meta',\n 'meta-llama': 'meta',\n mistral: 'mistral',\n mistralai: 'mistral',\n deepseek: 'deepseek',\n xai: 'xai',\n qwen: 'qwen',\n alibaba: 'qwen',\n cohere: 'cohere',\n amazon: 'amazon',\n bedrock: 'amazon',\n moonshot: 'moonshot',\n moonshotai: 'moonshot',\n kimi: 'moonshot',\n 'kimi-code': 'moonshot',\n zhipu: 'zhipu',\n zhipuai: 'zhipu',\n zai: 'zhipu',\n 'z-ai': 'zhipu',\n glm: 'zhipu',\n}\n\n/** Fallback model-name patterns when there's no recognised provider prefix. */\nconst NAME_PATTERNS: Array<[RegExp, JudgeFamily]> = [\n [/claude/i, 'anthropic'],\n [/\\b(gpt|davinci|babbage)\\b|^o[134]\\b|[-/]o[134]\\b|gpt-/i, 'openai'],\n [/gemini|palm|gemma|bison/i, 'google'],\n [/llama/i, 'meta'],\n [/mi(s|x)tral|codestral|magistral/i, 'mistral'],\n [/deepseek/i, 'deepseek'],\n [/grok/i, 'xai'],\n [/qwen/i, 'qwen'],\n [/command-?(r|a)?/i, 'cohere'],\n [/\\b(nova|titan)\\b/i, 'amazon'],\n [/\\bkimi\\b|moonshot/i, 'moonshot'],\n [/\\bglm\\b|zhipu|\\bz-?ai\\b/i, 'zhipu'],\n]\n\n/**\n * Classify a model id into its provider family. Strips a `@snapshot` suffix\n * and prefers an explicit `provider/...` prefix; otherwise matches the model\n * name. Returns `unknown` when nothing matches (callers decide whether that's\n * acceptable — `assertCrossFamily` counts it as its own family).\n */\nexport function judgeFamily(modelId: string): JudgeFamily {\n const id = modelId.trim().split('@')[0]!.toLowerCase()\n const slash = id.indexOf('/')\n if (slash > 0) {\n const prefix = id.slice(0, slash)\n const mapped = PROVIDER_PREFIX[prefix]\n if (mapped) return mapped\n }\n for (const [pattern, family] of NAME_PATTERNS) {\n if (pattern.test(id)) return family\n }\n return 'unknown'\n}\n\nexport interface AssertCrossFamilyOptions {\n /** Minimum number of distinct families the ensemble must span. Default 2. */\n minFamilies?: number\n /** When false (default), `unknown`-family models do NOT count toward the\n * family total — an ensemble of all-unclassifiable models is not provably\n * cross-family. Set true to count `unknown` as one shared family. */\n allowUnknown?: boolean\n}\n\nexport class CrossFamilyError extends Error {\n constructor(\n message: string,\n public readonly families: JudgeFamily[],\n public readonly models: string[],\n ) {\n super(message)\n this.name = 'CrossFamilyError'\n }\n}\n\n/**\n * Throw unless the judge models span at least `minFamilies` distinct provider\n * families. Pass the model ids backing your judge ensemble. Fail-loud by\n * design — a correlated single-family ensemble silently inflates agreement.\n */\nexport function assertCrossFamily(\n models: string[],\n opts: AssertCrossFamilyOptions = {},\n): JudgeFamily[] {\n const minFamilies = opts.minFamilies ?? 2\n const families = new Set<JudgeFamily>()\n for (const m of models) {\n const f = judgeFamily(m)\n if (f === 'unknown' && !opts.allowUnknown) continue\n families.add(f)\n }\n const list = [...families].sort()\n if (list.length < minFamilies) {\n throw new CrossFamilyError(\n `judge ensemble spans ${list.length} provider famil${list.length === 1 ? 'y' : 'ies'} ` +\n `(${list.join(', ') || 'none'}) but ${minFamilies} required — a single-family ensemble ` +\n 'is correlated bias, not independent signal',\n list,\n models,\n )\n }\n return list\n}\n","import type { TCloud } from '@tangle-network/tcloud'\nimport type { JudgeFn, JudgeInput, JudgeScore } from './types'\n\n/**\n * Create a domain expert judge with a configurable domain.\n *\n * The judge evaluates professional accuracy and depth.\n */\nexport function createDomainExpertJudge(domain: string): JudgeFn {\n return async (\n tc: TCloud,\n { scenario, turns }: Pick<JudgeInput, 'scenario' | 'turns'>,\n ): Promise<JudgeScore[]> => {\n const conversation = turns\n .map(\n (t, i) =>\n `Turn ${i + 1}:\\nUser: ${t.userMessage}\\nAgent: ${t.agentResponse.slice(0, 2000)}`,\n )\n .join('\\n\\n---\\n\\n')\n\n const resp = await tc.chat({\n model: 'gpt-4o',\n messages: [\n {\n role: 'system',\n content: `You are a senior ${domain} professional with 20+ years of experience. You are evaluating an AI agent's responses for professional accuracy and depth.\n\nScore STRICTLY. A 5 means \"a junior professional could do this.\" An 8 means \"solid mid-career work.\" A 10 means \"I would hire this agent.\"\n\nEvaluate:\n1. **domain_accuracy** (0-10): Are the technical terms correct? Are the recommendations what you'd actually do? Would this advice cause problems if followed?\n2. **professional_depth** (0-10): Does it go beyond surface-level? Does it consider practical constraints, edge cases, industry standards? Or is it generic textbook advice?\n\nRespond with JSON only: [{\"dimension\":\"domain_accuracy\",\"score\":N,\"reasoning\":\"...\",\"evidence\":\"quote from response\"},{\"dimension\":\"professional_depth\",\"score\":N,\"reasoning\":\"...\",\"evidence\":\"quote\"}]`,\n },\n {\n role: 'user',\n content: `Persona: ${scenario.persona} (${scenario.label})\\nScenario: ${scenario.thesis}\\n\\n${conversation}`,\n },\n ],\n temperature: 0.1,\n maxTokens: 800,\n })\n\n return parseJudgeResponse('domain_expert', resp)\n }\n}\n\n/**\n * Code execution judge — evaluates whether code blocks are valid and runnable.\n */\nexport const codeExecutionJudge: JudgeFn = async (tc, { scenario, artifacts }) => {\n const codeBlocks = artifacts.codeBlocks\n if (codeBlocks.length === 0) {\n return [\n {\n judgeName: 'code_execution',\n dimension: 'code_execution',\n score: 0,\n reasoning: 'No code blocks found in agent response.',\n },\n ]\n }\n\n const codeText = codeBlocks\n .map(\n (b, i) =>\n `Block ${i + 1} (${b.language}):\\n\\`\\`\\`${b.language}\\n${b.code.slice(0, 3000)}\\n\\`\\`\\``,\n )\n .join('\\n\\n')\n\n const resp = await tc.chat({\n model: 'gpt-4o',\n messages: [\n {\n role: 'system',\n content: `You are a principal software engineer reviewing code written by an AI agent.\n\nScore STRICTLY:\n1. **executability** (0-10): Would this code run without errors? Check: import errors, undefined variables, missing deps, syntax errors. A 5 means \"would run with minor fixes.\" A 10 means \"copy-paste and it works.\"\n2. **completeness** (0-10): Does it handle the FULL task, or just the happy path? A 5 means \"handles the main case.\" A 10 means \"production-ready.\"\n3. **reusability** (0-10): Could this be saved as a tool and reused? A 5 means \"works for this case.\" A 10 means \"general-purpose tool.\"\n\nRespond with JSON only: [{\"dimension\":\"executability\",\"score\":N,\"reasoning\":\"...\",\"evidence\":\"specific line/issue\"},{\"dimension\":\"completeness\",\"score\":N,\"reasoning\":\"...\",\"evidence\":\"...\"},{\"dimension\":\"reusability\",\"score\":N,\"reasoning\":\"...\",\"evidence\":\"...\"}]`,\n },\n {\n role: 'user',\n content: `Task: ${scenario.thesis}\\n\\n${codeText}`,\n },\n ],\n temperature: 0.1,\n maxTokens: 1000,\n })\n\n return parseJudgeResponse('code_execution', resp)\n}\n\n/**\n * Coherence judge — evaluates multi-turn consistency and progression.\n */\nexport const coherenceJudge: JudgeFn = async (tc, { scenario, turns }) => {\n if (turns.length < 2) {\n // Single-turn scenarios carry no multi-turn signal. Emit no judge\n // scores so the coherence dimension is correctly absent from the\n // aggregate for this trial rather than pinned to a synthetic value.\n return []\n }\n\n const conversation = turns\n .map(\n (t, i) =>\n `Turn ${i + 1}:\\nUser: ${t.userMessage}\\nAgent (${t.agentResponse.length} chars): ${t.agentResponse.slice(0, 1500)}`,\n )\n .join('\\n\\n---\\n\\n')\n\n const resp = await tc.chat({\n model: 'gpt-4o',\n messages: [\n {\n role: 'system',\n content: `You evaluate whether an AI agent maintains coherence across a multi-turn conversation.\n\nScore STRICTLY:\n1. **consistency** (0-10): Does the agent contradict itself across turns? Does it remember what it said/built earlier?\n2. **progression** (0-10): Does each turn BUILD on the previous? Or does it start fresh? A 5 means \"vaguely related.\" A 10 means \"each turn clearly advances the work.\"\n3. **feedback_integration** (0-10): When the user gives feedback, does the agent demonstrate it HEARD the feedback?\n\nRespond with JSON only: [{\"dimension\":\"consistency\",\"score\":N,\"reasoning\":\"...\"},{\"dimension\":\"progression\",\"score\":N,\"reasoning\":\"...\"},{\"dimension\":\"feedback_integration\",\"score\":N,\"reasoning\":\"...\"}]`,\n },\n {\n role: 'user',\n content: `Scenario: ${scenario.thesis}\\n\\n${conversation}`,\n },\n ],\n temperature: 0.1,\n maxTokens: 800,\n })\n\n return parseJudgeResponse('coherence', resp)\n}\n\n/**\n * Adversarial judge — red-teams agent responses.\n */\nexport const adversarialJudge: JudgeFn = async (tc, { scenario, turns }) => {\n const conversation = turns\n .map(\n (t, i) => `Turn ${i + 1}:\\nUser: ${t.userMessage}\\nAgent: ${t.agentResponse.slice(0, 1500)}`,\n )\n .join('\\n\\n---\\n\\n')\n\n const resp = await tc.chat({\n model: 'gpt-4o',\n messages: [\n {\n role: 'system',\n content: `You are a red-team evaluator. Find the WEAKEST point in the AI agent's responses. Be adversarial.\n\n1. **hallucination** (0-10, inverted — 10 means NO hallucination): Did the agent make up facts, cite nonexistent tools, invent standards?\n2. **false_confidence** (0-10, inverted — 10 means appropriate uncertainty): Did the agent present uncertain information as fact?\n3. **worst_failure** (0-10, inverted — 10 means no critical failures): What is the single worst thing in the response?\n\nBe harsh. If everything is genuinely good, say so — but look hard first.\n\nRespond with JSON only: [{\"dimension\":\"hallucination\",\"score\":N,\"reasoning\":\"...\",\"evidence\":\"specific quote\"},{\"dimension\":\"false_confidence\",\"score\":N,\"reasoning\":\"...\",\"evidence\":\"...\"},{\"dimension\":\"worst_failure\",\"score\":N,\"reasoning\":\"...\",\"evidence\":\"...\"}]`,\n },\n {\n role: 'user',\n content: `Persona: ${scenario.persona}\\nScenario: ${scenario.thesis}\\n\\n${conversation}`,\n },\n ],\n temperature: 0.2,\n maxTokens: 800,\n })\n\n return parseJudgeResponse('adversarial', resp)\n}\n\n/**\n * Create a custom judge with a fully custom prompt.\n */\nexport function createCustomJudge(\n name: string,\n systemPrompt: string,\n opts?: { model?: string; temperature?: number; maxTokens?: number },\n): JudgeFn {\n return async (tc, { scenario, turns }) => {\n const conversation = turns\n .map(\n (t, i) =>\n `Turn ${i + 1}:\\nUser: ${t.userMessage}\\nAgent: ${t.agentResponse.slice(0, 2000)}`,\n )\n .join('\\n\\n---\\n\\n')\n\n const resp = await tc.chat({\n model: opts?.model ?? 'gpt-4o',\n messages: [\n {\n role: 'system',\n content: systemPrompt,\n },\n {\n role: 'user',\n content: `Persona: ${scenario.persona} (${scenario.label})\\nScenario: ${scenario.thesis}\\n\\n${conversation}`,\n },\n ],\n temperature: opts?.temperature ?? 0.1,\n maxTokens: opts?.maxTokens ?? 1000,\n })\n\n return parseJudgeResponse(name, resp)\n }\n}\n\n/** Default judge set (domain must be provided for domain expert) */\nexport function defaultJudges(domain: string): JudgeFn[] {\n return [createDomainExpertJudge(domain), codeExecutionJudge, coherenceJudge, adversarialJudge]\n}\n\n// ── Helpers ──\n\nfunction parseJudgeResponse(judgeName: string, resp: unknown): JudgeScore[] {\n try {\n const content =\n (resp as { choices?: { message?: { content?: string } }[] }).choices?.[0]?.message?.content ??\n ''\n let cleaned = content.replace(/```json\\n?|\\n?```/g, '').trim()\n const arrayMatch = cleaned.match(/\\[[\\s\\S]*\\]/)\n if (arrayMatch) cleaned = arrayMatch[0]\n const parsed = JSON.parse(cleaned) as {\n dimension: string\n score: number\n reasoning: string\n evidence?: string\n }[]\n return parsed.map((p) => ({\n judgeName,\n dimension: p.dimension,\n score: Math.max(0, Math.min(10, p.score)),\n reasoning: p.reasoning ?? '',\n evidence: p.evidence,\n }))\n } catch (err) {\n const content =\n (resp as { choices?: { message?: { content?: string } }[] }).choices?.[0]?.message?.content ??\n ''\n console.log(\n ` [parse_error] ${judgeName}: ${(err as Error).message?.slice(0, 50)} | response: ${content.slice(0, 100)}`,\n )\n return [\n {\n judgeName,\n dimension: 'parse_error',\n score: 0,\n reasoning: `Parse failed: ${(err as Error).message?.slice(0, 100)}. Raw: ${content.slice(0, 200)}`,\n },\n ]\n }\n}\n","import {\n createFeedbackTrajectory,\n type FeedbackLabel,\n type FeedbackTrajectory,\n type FeedbackTrajectoryStore,\n} from './feedback-trajectory'\nimport type {\n ReleaseConfidenceScorecard,\n ReleaseConfidenceThresholds,\n ReleaseTraceEvidence,\n} from './release-confidence'\nimport { evaluateReleaseConfidence } from './release-confidence'\nimport type { CheckResult, TestResult } from './types'\n\nexport interface LiveProofArtifact {\n kind: string\n id?: string\n path?: string\n url?: string\n metadata?: Record<string, unknown>\n}\n\nexport interface LiveProofContext {\n projectId: string\n scenarioId: string\n task: string\n checks: CheckResult[]\n artifacts: LiveProofArtifact[]\n labels: FeedbackLabel[]\n metadata: Record<string, unknown>\n transcript: { role: 'user' | 'assistant' | 'system' | 'tool'; content: string; at: string }[]\n addCheck(check: CheckResult): void\n addArtifact(artifact: LiveProofArtifact): void\n addLabel(label: Omit<FeedbackLabel, 'createdAt'> & { createdAt?: string }): void\n addTurn(turn: {\n role: 'user' | 'assistant' | 'system' | 'tool'\n content: string\n at?: string\n }): void\n}\n\nexport interface LiveProofConfig {\n projectId: string\n scenarioId: string\n task: string\n drive(context: LiveProofContext): Promise<void> | void\n validate?(\n context: LiveProofContext,\n ): Promise<CheckResult[] | undefined> | CheckResult[] | undefined\n requiredArtifacts?: string[]\n minPassRate?: number\n trajectoryStore?: FeedbackTrajectoryStore\n releaseConfidence?: {\n target: string\n candidateId?: string\n baselineId?: string\n thresholds?: ReleaseConfidenceThresholds\n }\n metadata?: Record<string, unknown>\n}\n\nexport interface LiveProofResult extends TestResult {\n projectId: string\n scenarioId: string\n artifacts: LiveProofArtifact[]\n labels: FeedbackLabel[]\n transcript: LiveProofContext['transcript']\n trajectory: FeedbackTrajectory\n releaseConfidence?: ReleaseConfidenceScorecard\n}\n\nexport async function runLiveProof(config: LiveProofConfig): Promise<LiveProofResult> {\n const startedAt = Date.now()\n const checks: CheckResult[] = []\n const artifacts: LiveProofArtifact[] = []\n const labels: FeedbackLabel[] = []\n const transcript: LiveProofContext['transcript'] = []\n const metadata = { ...(config.metadata ?? {}), live: true }\n const context: LiveProofContext = {\n projectId: config.projectId,\n scenarioId: config.scenarioId,\n task: config.task,\n checks,\n artifacts,\n labels,\n metadata,\n transcript,\n addCheck: (check) => checks.push(check),\n addArtifact: (artifact) => artifacts.push(artifact),\n addLabel: (label) =>\n labels.push({ ...label, createdAt: label.createdAt ?? new Date().toISOString() }),\n addTurn: (turn) => transcript.push({ ...turn, at: turn.at ?? new Date().toISOString() }),\n }\n\n try {\n await config.drive(context)\n const validationChecks = await config.validate?.(context)\n if (validationChecks) checks.push(...validationChecks)\n } catch (err) {\n checks.push({\n name: 'live_proof_runtime',\n passed: false,\n expected: 'live proof completes without runtime failure',\n actual: err instanceof Error ? err.message : String(err),\n })\n }\n\n for (const kind of config.requiredArtifacts ?? []) {\n checks.push({\n name: `artifact:${kind}`,\n passed: artifacts.some((artifact) => artifact.kind === kind),\n expected: `artifact kind ${kind}`,\n actual: artifacts.map((artifact) => artifact.kind).join(', ') || 'none',\n })\n }\n\n const passRate =\n checks.length === 0 ? 0 : checks.filter((check) => check.passed).length / checks.length\n if (config.minPassRate !== undefined) {\n checks.push({\n name: 'min_pass_rate',\n passed: passRate >= config.minPassRate,\n expected: `pass rate >= ${config.minPassRate}`,\n actual: passRate.toFixed(3),\n })\n }\n\n const passed = checks.length > 0 && checks.every((check) => check.passed)\n const duration = Date.now() - startedAt\n const trajectory = createFeedbackTrajectory({\n projectId: config.projectId,\n scenarioId: config.scenarioId,\n task: { intent: config.task },\n labels,\n outcome: {\n success: passed,\n score:\n checks.length === 0 ? 0 : checks.filter((check) => check.passed).length / checks.length,\n detail: `${checks.filter((check) => check.passed).length}/${checks.length} checks passed`,\n observedAt: new Date().toISOString(),\n metadata: {\n artifacts,\n transcript,\n },\n },\n metadata,\n })\n await config.trajectoryStore?.save(trajectory)\n\n const releaseConfidence = config.releaseConfidence\n ? evaluateReleaseConfidence({\n ...config.releaseConfidence,\n traces: [liveProofToReleaseTrace(config, trajectory, duration)],\n thresholds: {\n requireCorpus: false,\n requireHoldout: false,\n minScenarioCount: 0,\n minSearchRuns: 0,\n minHoldoutRuns: 0,\n requireAsiForFailures: false,\n ...(config.releaseConfidence.thresholds ?? {}),\n },\n })\n : undefined\n\n return {\n name: config.scenarioId,\n passed: passed && (releaseConfidence ? releaseConfidence.status !== 'fail' : true),\n duration,\n detail: `${checks.filter((check) => check.passed).length}/${checks.length} checks passed`,\n checks,\n projectId: config.projectId,\n scenarioId: config.scenarioId,\n artifacts,\n labels,\n transcript,\n trajectory,\n releaseConfidence,\n }\n}\n\nfunction liveProofToReleaseTrace(\n config: LiveProofConfig,\n trajectory: FeedbackTrajectory,\n durationMs: number,\n): ReleaseTraceEvidence {\n return {\n scenarioId: config.scenarioId,\n candidateId: config.releaseConfidence?.candidateId,\n split:\n trajectory.split === 'holdout' ? 'holdout' : trajectory.split === 'dev' ? 'dev' : 'search',\n score: trajectory.outcome?.score,\n ok: trajectory.outcome?.success,\n turnCount: Array.isArray(trajectory.outcome?.metadata?.transcript)\n ? trajectory.outcome.metadata.transcript.length\n : undefined,\n durationMs,\n metadata: {\n projectId: config.projectId,\n artifacts: trajectory.outcome?.metadata?.artifacts,\n },\n }\n}\n","import { clamp01 } from './run-score'\n\nexport type PrReviewSource =\n | 'drew'\n | 'donovan'\n | 'shady'\n | 'codex'\n | 'claude-code'\n | 'gpt-5.5-high'\n | 'claude-opus-4.7-high'\n | 'kimi'\n | 'opencode'\n | (string & {})\n\nexport type PrReviewSeverity = 'critical' | 'high' | 'medium' | 'low' | 'nit'\n\nexport type PrReviewOutcome = 'accepted' | 'fixed' | 'rejected' | 'duplicate' | 'noise' | 'unknown'\n\nexport interface PrReviewComment {\n id: string\n source: PrReviewSource\n body: string\n model?: string\n author?: string\n path?: string\n line?: number\n severity?: PrReviewSeverity\n outcome?: PrReviewOutcome\n createdAt?: string\n metadata?: Record<string, unknown>\n}\n\nexport interface PrReviewReferenceFinding {\n id: string\n title: string\n severity: PrReviewSeverity\n path?: string\n line?: number\n /**\n * Stable terms that should appear in a useful finding. Keep these\n * factual: API names, invariant names, table names, error classes.\n */\n keywords?: string[]\n fixedByCommit?: string\n sourceCommentIds?: string[]\n metadata?: Record<string, unknown>\n}\n\nexport interface PrReviewAuditCase {\n id: string\n repo: string\n prNumber?: number\n baseSha?: string\n headSha?: string\n title?: string\n diff?: string\n split?: 'train' | 'validation' | 'test' | 'holdout' | (string & {})\n comments: PrReviewComment[]\n referenceFindings: PrReviewReferenceFinding[]\n metadata?: Record<string, unknown>\n}\n\nexport interface PrReviewScoreWeights {\n recall: number\n precision: number\n actionability: number\n severityCalibration: number\n lowNoise: number\n}\n\nexport interface PrReviewMatchedFinding {\n referenceId: string\n commentId: string\n score: number\n}\n\nexport interface PrReviewScore {\n caseId: string\n source: PrReviewSource\n commentCount: number\n referenceCount: number\n matchedFindings: PrReviewMatchedFinding[]\n recall: number\n precision: number\n actionability: number\n severityCalibration: number\n lowNoise: number\n aggregate: number\n notes: string[]\n}\n\nexport interface PrReviewBenchmarkSummary {\n source: PrReviewSource\n caseCount: number\n commentCount: number\n aggregateMean: number\n recallMean: number\n precisionMean: number\n actionabilityMean: number\n severityCalibrationMean: number\n lowNoiseMean: number\n}\n\nexport const DEFAULT_PR_REVIEW_SCORE_WEIGHTS: PrReviewScoreWeights = {\n recall: 4,\n precision: 2,\n actionability: 1.5,\n severityCalibration: 1,\n lowNoise: 1,\n}\n\nexport function commentsForSource(\n auditCase: PrReviewAuditCase,\n source: PrReviewSource,\n): PrReviewComment[] {\n return auditCase.comments.filter((comment) => comment.source === source)\n}\n\nexport function scorePrReviewSource(\n auditCase: PrReviewAuditCase,\n source: PrReviewSource,\n weights: Partial<PrReviewScoreWeights> = {},\n): PrReviewScore {\n return scorePrReviewComments(auditCase, commentsForSource(auditCase, source), source, weights)\n}\n\nexport function scorePrReviewComments(\n auditCase: PrReviewAuditCase,\n comments: PrReviewComment[],\n source: PrReviewSource,\n weights: Partial<PrReviewScoreWeights> = {},\n): PrReviewScore {\n const matchedFindings = matchReferenceFindings(auditCase.referenceFindings, comments)\n const matchedCommentIds = new Set(matchedFindings.map((match) => match.commentId))\n const positiveComments = comments.filter((comment) => isPositiveOutcome(comment.outcome))\n const negativeComments = comments.filter((comment) => isNegativeOutcome(comment.outcome))\n const actionableComments = comments.filter(isActionableComment)\n const severityComments = comments.filter((comment) => comment.severity)\n const severityAligned = severityComments.filter((comment) =>\n isSeverityAligned(comment, auditCase.referenceFindings, matchedFindings),\n )\n\n const recall = auditCase.referenceFindings.length\n ? matchedFindings.length / auditCase.referenceFindings.length\n : comments.length === 0\n ? 1\n : 0\n\n const precisionDenominator = positiveComments.length + negativeComments.length\n const precision =\n precisionDenominator > 0\n ? positiveComments.length / precisionDenominator\n : comments.length > 0\n ? matchedCommentIds.size / comments.length\n : auditCase.referenceFindings.length === 0\n ? 1\n : 0\n\n const actionability = comments.length ? actionableComments.length / comments.length : 1\n const severityCalibration = severityComments.length\n ? severityAligned.length / severityComments.length\n : matchedFindings.length\n ? 0.5\n : 1\n const lowNoise = comments.length ? 1 - negativeComments.length / comments.length : 1\n const aggregate = aggregatePrReviewScore(\n { recall, precision, actionability, severityCalibration, lowNoise },\n weights,\n )\n\n return {\n caseId: auditCase.id,\n source,\n commentCount: comments.length,\n referenceCount: auditCase.referenceFindings.length,\n matchedFindings,\n recall,\n precision,\n actionability,\n severityCalibration,\n lowNoise,\n aggregate,\n notes: buildScoreNotes({\n comments,\n referenceCount: auditCase.referenceFindings.length,\n matchedFindings,\n negativeComments,\n actionableComments,\n }),\n }\n}\n\nexport function summarizePrReviewBenchmark(scores: PrReviewScore[]): PrReviewBenchmarkSummary[] {\n const bySource = new Map<PrReviewSource, PrReviewScore[]>()\n for (const score of scores) {\n bySource.set(score.source, [...(bySource.get(score.source) ?? []), score])\n }\n return [...bySource.entries()]\n .map(([source, sourceScores]) => ({\n source,\n caseCount: sourceScores.length,\n commentCount: sum(sourceScores.map((score) => score.commentCount)),\n aggregateMean: mean(sourceScores.map((score) => score.aggregate)),\n recallMean: mean(sourceScores.map((score) => score.recall)),\n precisionMean: mean(sourceScores.map((score) => score.precision)),\n actionabilityMean: mean(sourceScores.map((score) => score.actionability)),\n severityCalibrationMean: mean(sourceScores.map((score) => score.severityCalibration)),\n lowNoiseMean: mean(sourceScores.map((score) => score.lowNoise)),\n }))\n .sort((a, b) => b.aggregateMean - a.aggregateMean)\n}\n\nexport function aggregatePrReviewScore(\n dimensions: Pick<\n PrReviewScore,\n 'recall' | 'precision' | 'actionability' | 'severityCalibration' | 'lowNoise'\n >,\n weights: Partial<PrReviewScoreWeights> = {},\n): number {\n const merged = { ...DEFAULT_PR_REVIEW_SCORE_WEIGHTS, ...weights }\n const weightSum = Object.values(merged).reduce((total, value) => total + Math.max(0, value), 0)\n if (weightSum <= 0) return 0\n return (\n (merged.recall * clamp01(dimensions.recall) +\n merged.precision * clamp01(dimensions.precision) +\n merged.actionability * clamp01(dimensions.actionability) +\n merged.severityCalibration * clamp01(dimensions.severityCalibration) +\n merged.lowNoise * clamp01(dimensions.lowNoise)) /\n weightSum\n )\n}\n\nfunction matchReferenceFindings(\n references: PrReviewReferenceFinding[],\n comments: PrReviewComment[],\n): PrReviewMatchedFinding[] {\n const matches: PrReviewMatchedFinding[] = []\n const usedCommentIds = new Set<string>()\n\n for (const reference of references) {\n const candidates = comments\n .filter((comment) => !usedCommentIds.has(comment.id))\n .map((comment) => ({ comment, score: matchScore(reference, comment) }))\n .filter(({ score }) => score >= 0.55)\n .sort((a, b) => b.score - a.score)\n const best = candidates[0]\n if (!best) continue\n usedCommentIds.add(best.comment.id)\n matches.push({ referenceId: reference.id, commentId: best.comment.id, score: best.score })\n }\n\n return matches\n}\n\nfunction matchScore(reference: PrReviewReferenceFinding, comment: PrReviewComment): number {\n let score = 0\n if (reference.sourceCommentIds?.includes(comment.id)) score += 1\n if (\n reference.path &&\n comment.path &&\n normalizePath(reference.path) === normalizePath(comment.path)\n ) {\n score += 0.35\n }\n if (reference.line && comment.line && Math.abs(reference.line - comment.line) <= 3) score += 0.15\n\n const terms = [...(reference.keywords ?? []), ...tokenize(reference.title)]\n const uniqueTerms = [...new Set(terms.map(normalizeTerm).filter((term) => term.length >= 3))]\n if (uniqueTerms.length > 0) {\n const bodyTerms = new Set(tokenize(comment.body).map(normalizeTerm))\n const overlap = uniqueTerms.filter((term) => bodyTerms.has(term)).length\n score += 0.5 * (overlap / uniqueTerms.length)\n }\n\n return clamp01(score)\n}\n\nfunction isActionableComment(comment: PrReviewComment): boolean {\n const body = comment.body.trim()\n if (!comment.path && !/\\b(file|line|function|method|class|module|test|migration)\\b/i.test(body)) {\n return false\n }\n return /\\b(fix|change|add|remove|guard|check|reject|validate|test|assert|return|throw|fail|block)\\b/i.test(\n body,\n )\n}\n\nfunction isSeverityAligned(\n comment: PrReviewComment,\n references: PrReviewReferenceFinding[],\n matches: PrReviewMatchedFinding[],\n): boolean {\n if (!comment.severity) return false\n const match = matches.find((candidate) => candidate.commentId === comment.id)\n if (!match) return comment.severity === 'nit' || comment.severity === 'low'\n const reference = references.find((candidate) => candidate.id === match.referenceId)\n if (!reference) return false\n return Math.abs(severityRank(comment.severity) - severityRank(reference.severity)) <= 1\n}\n\nfunction buildScoreNotes(input: {\n comments: PrReviewComment[]\n referenceCount: number\n matchedFindings: PrReviewMatchedFinding[]\n negativeComments: PrReviewComment[]\n actionableComments: PrReviewComment[]\n}): string[] {\n const notes: string[] = []\n if (input.referenceCount > 0 && input.matchedFindings.length === 0) {\n notes.push('no reference findings matched')\n }\n if (input.negativeComments.length > 0) {\n notes.push(`${input.negativeComments.length} comment(s) labelled rejected/duplicate/noise`)\n }\n if (input.comments.length > 0 && input.actionableComments.length === 0) {\n notes.push('comments were not actionable enough for a PR reviewer benchmark')\n }\n return notes\n}\n\nfunction isPositiveOutcome(outcome: PrReviewOutcome | undefined): boolean {\n return outcome === 'accepted' || outcome === 'fixed'\n}\n\nfunction isNegativeOutcome(outcome: PrReviewOutcome | undefined): boolean {\n return outcome === 'rejected' || outcome === 'duplicate' || outcome === 'noise'\n}\n\nfunction severityRank(severity: PrReviewSeverity): number {\n switch (severity) {\n case 'critical':\n return 5\n case 'high':\n return 4\n case 'medium':\n return 3\n case 'low':\n return 2\n case 'nit':\n return 1\n }\n}\n\nfunction tokenize(input: string): string[] {\n return input.match(/[a-zA-Z0-9_.$/-]+/g) ?? []\n}\n\nfunction normalizeTerm(input: string): string {\n return input.toLowerCase().replace(/^[^a-z0-9_]+|[^a-z0-9_]+$/g, '')\n}\n\nfunction normalizePath(input: string): string {\n return input.replace(/^\\.\\/+/, '')\n}\n\nfunction mean(values: number[]): number {\n return values.length ? sum(values) / values.length : 0\n}\n\nfunction sum(values: number[]): number {\n return values.reduce((total, value) => total + value, 0)\n}\n","import type { Scenario, ScenarioFile } from './types'\n\n/**\n * ScenarioRegistry — manages scenario discovery and filtering.\n *\n * Each agent registers its scenarios. The registry handles conversion\n * from ScenarioFile format to the framework's Scenario type.\n */\nexport class ScenarioRegistry {\n private scenarios: Scenario[] = []\n private scenarioFiles: ScenarioFile[] = []\n\n /** Register scenarios from ScenarioFile format */\n registerFiles(files: ScenarioFile[]): void {\n this.scenarioFiles.push(...files)\n this.scenarios.push(...files.map(toScenario))\n }\n\n /** Register pre-built Scenario objects directly */\n register(scenarios: Scenario[]): void {\n this.scenarios.push(...scenarios)\n }\n\n /** Get all scenarios */\n all(): Scenario[] {\n return [...this.scenarios]\n }\n\n /** Get scenarios filtered by category */\n byCategory(category: string): Scenario[] {\n const fromFiles = this.scenarioFiles.filter((sf) => sf.category === category).map(toScenario)\n return fromFiles\n }\n\n /** List all categories with counts */\n listCategories(): { category: string; count: number }[] {\n const counts: Record<string, number> = {}\n for (const sf of this.scenarioFiles) {\n counts[sf.category] = (counts[sf.category] ?? 0) + 1\n }\n return Object.entries(counts).map(([category, count]) => ({ category, count }))\n }\n\n /** Get scenarios filtered by persona */\n byPersona(persona: string): Scenario[] {\n return this.scenarios.filter((s) => s.persona === persona)\n }\n\n /** Get a single scenario by ID */\n byId(id: string): Scenario | undefined {\n return this.scenarios.find((s) => s.id === id)\n }\n\n /** Count total scenarios */\n get count(): number {\n return this.scenarios.length\n }\n}\n\n/** Convert ScenarioFile to the framework's Scenario type */\nfunction toScenario(sf: ScenarioFile): Scenario {\n return {\n id: sf.id,\n persona: sf.persona,\n label: sf.label,\n thesis: sf.thesis,\n dimensions: [],\n turns: sf.turns,\n artifactChecks: sf.artifactChecks,\n systemPromptAppend: sf.isControl ? 'You are a helpful AI assistant.' : undefined,\n }\n}\n","import type { BenchmarkReport, DriverResult } from './types'\n\n/**\n * Report generation utilities.\n *\n * Outputs convergence curves, cost curves, quality curves,\n * and per-persona summaries in markdown format.\n */\n\n/** Generate a markdown report from benchmark results */\nexport function formatBenchmarkReport(report: BenchmarkReport): string {\n const lines: string[] = []\n\n lines.push(`# Benchmark Report`)\n lines.push(``)\n lines.push(`**Date:** ${report.timestamp}`)\n lines.push(`**Generation:** ${report.generation}`)\n lines.push(`**Prompt Version:** ${report.promptVersion}`)\n lines.push(`**Scenarios:** ${report.scenarioCount}`)\n lines.push(`**Overall Score:** ${report.summary.overallAvg.toFixed(1)}/10`)\n lines.push(``)\n\n // By persona\n lines.push(`## By Persona`)\n lines.push(``)\n lines.push(`| Persona | Avg | Passed | Total |`)\n lines.push(`|---------|-----|--------|-------|`)\n for (const [name, data] of Object.entries(report.summary.byPersona)) {\n lines.push(`| ${name} | ${data.avg.toFixed(1)} | ${data.passed} | ${data.total} |`)\n }\n lines.push(``)\n\n // By dimension\n lines.push(`## By Dimension`)\n lines.push(``)\n lines.push(`| Dimension | Avg | Range | N |`)\n lines.push(`|-----------|-----|-------|---|`)\n const dimEntries = Object.entries(report.summary.byDimension).sort((a, b) => a[1].avg - b[1].avg)\n for (const [name, data] of dimEntries) {\n const min = Math.min(...data.scores)\n const max = Math.max(...data.scores)\n lines.push(`| ${name} | ${data.avg.toFixed(1)} | ${min}-${max} | ${data.scores.length} |`)\n }\n lines.push(``)\n\n // Weakest\n if (report.summary.weakest.length > 0) {\n lines.push(`## Weakest Scenarios`)\n lines.push(``)\n for (const w of report.summary.weakest) {\n lines.push(`- **${w.scenario}** (${w.score.toFixed(1)}): ${w.reason}`)\n }\n lines.push(``)\n }\n\n // Strongest\n if (report.summary.strongest.length > 0) {\n lines.push(`## Strongest Scenarios`)\n lines.push(``)\n for (const s of report.summary.strongest) {\n lines.push(`- **${s.scenario}** (${s.score.toFixed(1)}): ${s.reason}`)\n }\n lines.push(``)\n }\n\n return lines.join('\\n')\n}\n\n/** Generate a markdown report from agent driver results */\nexport function formatDriverReport(results: DriverResult[]): string {\n const lines: string[] = []\n\n lines.push(`# Agent Driver Report`)\n lines.push(``)\n\n for (const r of results) {\n lines.push(`## Persona: ${r.personaId}`)\n lines.push(``)\n lines.push(`- **Completed:** ${r.completed ? 'Yes' : 'No'}`)\n lines.push(`- **Turns to completion:** ${r.turnsToCompletion ?? 'N/A'}`)\n lines.push(`- **Total turns:** ${r.totalTurns}`)\n lines.push(\n `- **Final state:** ${r.finalState.tasks} tasks, ${r.finalState.events} events, ${r.finalState.vaultFiles.length} vault files`,\n )\n lines.push(``)\n\n // Convergence curve (ASCII)\n lines.push(`### Convergence`)\n lines.push(``)\n lines.push('```')\n for (let i = 0; i < r.convergenceCurve.length; i++) {\n const pct = r.convergenceCurve[i]!\n const bar = '#'.repeat(Math.round(pct / 2))\n lines.push(` turn ${String(i + 1).padStart(2)}: ${bar} ${pct.toFixed(0)}%`)\n }\n lines.push('```')\n lines.push(``)\n\n // Per-turn metrics table\n if (r.metrics.length > 0) {\n lines.push(`### Per-Turn Metrics`)\n lines.push(``)\n lines.push(`| Turn | Tasks | Events | Vault | Latency | Completion |`)\n lines.push(`|------|-------|--------|-------|---------|------------|`)\n for (const m of r.metrics) {\n lines.push(\n `| ${m.turn} | ${m.tasks} | ${m.events} | ${m.vaultFiles} | ${(m.responseLatencyMs / 1000).toFixed(1)}s | ${m.completionPercent.toFixed(0)}% |`,\n )\n }\n lines.push(``)\n }\n }\n\n return lines.join('\\n')\n}\n\n/** Print a compact summary to console */\nexport function printDriverSummary(results: DriverResult[]): void {\n console.log('='.repeat(70))\n console.log(' AGENT DRIVER — RESULTS')\n console.log('='.repeat(70))\n\n for (const r of results) {\n const status = r.completed ? 'COMPLETE' : 'INCOMPLETE'\n const turns = r.turnsToCompletion ?? r.totalTurns\n console.log(\n ` ${r.personaId.padEnd(20)} ${status.padEnd(12)} turns=${turns} tasks=${r.finalState.tasks} events=${r.finalState.events} vault=${r.finalState.vaultFiles.length}`,\n )\n }\n\n console.log()\n const completedCount = results.filter((r) => r.completed).length\n console.log(`${completedCount}/${results.length} personas completed`)\n}\n","/**\n * Anti-slop quality judge.\n *\n * Deterministic pattern-based quality check — no LLM call. Catches the\n * 80% of AI slop that every production agent leaks:\n * - Banned phrases (voice-specific: \"delve\", \"it's worth noting\", etc.)\n * - N-gram repetition (same phrase over and over)\n * - Hedging overuse (\"I could be wrong, but...\")\n * - Apology padding (\"I'm so sorry for the confusion...\")\n * - Unused opening formulas (\"Great question!\")\n * - Length bounds (too short to be useful, too long to be read)\n *\n * Produces a JudgeScore in the same shape as LLM judges so it composes into\n * `BenchmarkRunner`'s judge array transparently.\n */\n\nimport type { JudgeFn, JudgeInput, JudgeScore } from './types'\n\nexport interface AntiSlopConfig {\n /** Domain label — appears in the JudgeScore output */\n domain?: string\n\n /** Case-insensitive substrings that must not appear. Each occurrence = penalty. */\n bannedPhrases?: string[]\n\n /** Regexes matching opening formulas to penalize (e.g. /^great question/i). */\n bannedOpenings?: RegExp[]\n\n /** Regexes matching hedges (e.g. /i could be wrong/i). Ratio of hedged sentences drives score. */\n hedgingPatterns?: RegExp[]\n\n /** Regexes matching apology padding. */\n apologyPatterns?: RegExp[]\n\n /** Fraction of sentences that can be duplicates before penalty (default 0.15 = 15%). */\n repetitionThreshold?: number\n\n /** Min output length in chars; below this the turn is deemed too terse. */\n minLength?: number\n\n /** Max output length in chars; above this the turn is deemed too verbose. */\n maxLength?: number\n\n /** How heavily each violation class reduces the score (default 1). */\n penaltyWeights?: Partial<Record<SlopCategory, number>>\n}\n\nexport type SlopCategory =\n | 'banned_phrase'\n | 'banned_opening'\n | 'hedging'\n | 'apology'\n | 'repetition'\n | 'length'\n\nconst DEFAULT_HEDGES: RegExp[] = [\n /\\bi\\s+could\\s+be\\s+wrong\\b/i,\n /\\bi\\s+think\\s+maybe\\b/i,\n /\\bit\\s+might\\s+be\\s+that\\b/i,\n /\\bperhaps\\s+(?:you\\s+)?could\\b/i,\n]\n\nconst DEFAULT_APOLOGIES: RegExp[] = [\n /\\bi\\s+(?:apologize|apologise)\\s+(?:for|if)\\b/i,\n /\\bi'?m\\s+(?:so\\s+|really\\s+)?sorry\\s+(?:for|if|about)\\b/i,\n /\\bmy\\s+apologies\\b/i,\n]\n\n/** Create a reusable Judge function from an anti-slop config. */\nexport function createAntiSlopJudge(config: AntiSlopConfig = {}): JudgeFn {\n const conf: Required<Omit<AntiSlopConfig, 'penaltyWeights'>> & {\n penaltyWeights: Record<SlopCategory, number>\n } = {\n domain: config.domain ?? 'general',\n bannedPhrases: config.bannedPhrases ?? [],\n bannedOpenings: config.bannedOpenings ?? [],\n hedgingPatterns: config.hedgingPatterns ?? DEFAULT_HEDGES,\n apologyPatterns: config.apologyPatterns ?? DEFAULT_APOLOGIES,\n repetitionThreshold: config.repetitionThreshold ?? 0.15,\n minLength: config.minLength ?? 20,\n maxLength: config.maxLength ?? 8000,\n penaltyWeights: {\n banned_phrase: 1,\n banned_opening: 1,\n hedging: 0.5,\n apology: 0.5,\n repetition: 0.75,\n length: 0.5,\n ...config.penaltyWeights,\n },\n }\n\n const judge: JudgeFn = async (_tc, input: JudgeInput): Promise<JudgeScore[]> => {\n const outputs = input.turns.map((t) => t.agentResponse ?? '')\n const report = analyzeAntiSlop(outputs, conf)\n return [\n {\n judgeName: `anti-slop(${conf.domain})`,\n dimension: 'anti_slop',\n score: report.score,\n reasoning: report.issues.length\n ? report.issues\n .slice(0, 5)\n .map((i) => `${i.category}: ${i.detail}`)\n .join('; ')\n : 'No slop patterns detected.',\n evidence: report.issues[0]?.example,\n },\n ]\n }\n return judge\n}\n\nexport interface AntiSlopIssue {\n category: SlopCategory\n detail: string\n example?: string\n}\n\nexport interface AntiSlopReport {\n /** 0–10 score; 10 is clean, lower values mean more slop. */\n score: number\n issues: AntiSlopIssue[]\n /** Count of each category for programmatic aggregation. */\n counts: Record<SlopCategory, number>\n}\n\n/**\n * Pure function — analyze one or more outputs against the config. Exposed\n * separately so consumers can build their own reporters on top.\n */\nexport function analyzeAntiSlop(\n outputs: string[],\n config: Omit<Required<AntiSlopConfig>, 'domain'> & {\n penaltyWeights: Record<SlopCategory, number>\n },\n): AntiSlopReport {\n const issues: AntiSlopIssue[] = []\n const counts: Record<SlopCategory, number> = {\n banned_phrase: 0,\n banned_opening: 0,\n hedging: 0,\n apology: 0,\n repetition: 0,\n length: 0,\n }\n\n for (const output of outputs) {\n if (!output) continue\n const lower = output.toLowerCase()\n\n for (const phrase of config.bannedPhrases) {\n const needle = phrase.toLowerCase()\n let idx = 0\n while ((idx = lower.indexOf(needle, idx)) !== -1) {\n counts.banned_phrase += 1\n if (issues.length < 20) {\n issues.push({\n category: 'banned_phrase',\n detail: `\"${phrase}\"`,\n example: snippet(output, idx, phrase.length),\n })\n }\n idx += needle.length\n }\n }\n\n for (const re of config.bannedOpenings) {\n if (re.test(output)) {\n counts.banned_opening += 1\n issues.push({ category: 'banned_opening', detail: re.source, example: output.slice(0, 80) })\n }\n }\n\n for (const re of config.hedgingPatterns) {\n const matches = output.match(\n new RegExp(re, re.flags.includes('g') ? re.flags : `${re.flags}g`),\n )\n if (matches) {\n counts.hedging += matches.length\n issues.push({\n category: 'hedging',\n detail: `${matches.length}x ${re.source}`,\n example: matches[0],\n })\n }\n }\n\n for (const re of config.apologyPatterns) {\n const matches = output.match(\n new RegExp(re, re.flags.includes('g') ? re.flags : `${re.flags}g`),\n )\n if (matches) {\n counts.apology += matches.length\n issues.push({\n category: 'apology',\n detail: `${matches.length}x ${re.source}`,\n example: matches[0],\n })\n }\n }\n\n // Repetition: compare sentence-level dupes\n const sentences = splitSentences(output)\n if (sentences.length >= 4) {\n const seen = new Map<string, number>()\n for (const s of sentences) {\n const key = normalizeForDupe(s)\n if (!key) continue\n seen.set(key, (seen.get(key) ?? 0) + 1)\n }\n let dupes = 0\n for (const n of seen.values()) if (n > 1) dupes += n - 1\n const ratio = dupes / sentences.length\n if (ratio > config.repetitionThreshold) {\n counts.repetition += 1\n issues.push({\n category: 'repetition',\n detail: `${(ratio * 100).toFixed(0)}% duplicated (threshold ${(config.repetitionThreshold * 100).toFixed(0)}%)`,\n })\n }\n }\n\n // Length\n if (output.length < config.minLength) {\n counts.length += 1\n issues.push({\n category: 'length',\n detail: `too short (${output.length} < ${config.minLength})`,\n })\n } else if (output.length > config.maxLength) {\n counts.length += 1\n issues.push({\n category: 'length',\n detail: `too long (${output.length} > ${config.maxLength})`,\n })\n }\n }\n\n // Score: 10 minus weighted violations, clamped. Each violation of category c\n // subtracts `penaltyWeights[c]` points. Violations beyond 10/weight saturate.\n let penalty = 0\n for (const cat of Object.keys(counts) as SlopCategory[]) {\n penalty += counts[cat] * (config.penaltyWeights[cat] ?? 1)\n }\n const score = Math.max(0, Math.min(10, 10 - penalty))\n\n return { score, issues, counts }\n}\n\nfunction snippet(source: string, at: number, len: number): string {\n const pad = 24\n const start = Math.max(0, at - pad)\n const end = Math.min(source.length, at + len + pad)\n return (start > 0 ? '…' : '') + source.slice(start, end) + (end < source.length ? '…' : '')\n}\n\nfunction splitSentences(text: string): string[] {\n // Simple sentence split — good enough for slop detection; not linguistically perfect.\n return text\n .split(/[.!?\\n]+/)\n .map((s) => s.trim())\n .filter((s) => s.length > 0)\n}\n\nfunction normalizeForDupe(s: string): string {\n return s\n .toLowerCase()\n .replace(/\\s+/g, ' ')\n .replace(/[^a-z0-9 ]/g, '')\n .trim()\n}\n","/**\n * Artifact validators.\n *\n * Generic \"score a produced artifact\" primitive. Tax uses it for PDF form\n * correctness, research for sourced briefs, browser for task assertions, coding\n * for social posts. One interface, many validators; all plug into\n * `BenchmarkRunner` the same way.\n *\n * A validator receives an `Artifact` (file on disk, JSON blob, text, binary)\n * plus a `ValidationContext` (scenario id, the turns that produced it) and\n * returns a `ValidationResult` with pass/fail + 0..1 score + structured\n * issues.\n */\n\nexport interface Artifact {\n /** Logical kind — validators type-guard on this */\n kind: 'file' | 'json' | 'text' | 'binary' | string\n /** Filesystem-style path, optional */\n path?: string\n /** String content for text/json/file kinds */\n content?: string\n /** Binary content (if kind === 'binary') */\n bytes?: Uint8Array\n /** Caller-supplied metadata (mimeType, sha256, size, etc.) */\n metadata?: Record<string, unknown>\n}\n\nexport interface ValidationContext {\n scenarioId: string\n turnIndex?: number\n /** Prior artifacts for multi-artifact scenarios */\n priorArtifacts?: Artifact[]\n /** Free-form hints the validator uses for domain-specific checks */\n hints?: Record<string, unknown>\n}\n\nexport interface ValidationIssue {\n severity: 'error' | 'warning' | 'info'\n message: string\n /** Optional path into the artifact (e.g. JSON path or byte offset) */\n locus?: string\n}\n\nexport interface ValidationResult {\n pass: boolean\n /** 0–1 normalized score. Validators should be monotonic in pass-ness. */\n score: number\n issues: ValidationIssue[]\n /** Diagnostic payload for reporters */\n evidence?: Record<string, unknown>\n}\n\nexport interface ArtifactValidator {\n /** Stable identifier for the validator; appears in reports. */\n name: string\n /** Optional description for human-facing reports. */\n description?: string\n /** Called once per artifact; validators are expected to be pure + idempotent. */\n validate(artifact: Artifact, context: ValidationContext): Promise<ValidationResult>\n}\n\n// ---------------------------------------------------------------------------\n// Composable validators\n// ---------------------------------------------------------------------------\n\n/**\n * Run every validator on the same artifact; aggregate pass as AND, score as\n * (weighted) mean, issues concatenated. Weights default to 1 each.\n */\nexport function composeValidators(\n validators: ArtifactValidator[],\n options?: { name?: string; weights?: number[] },\n): ArtifactValidator {\n const weights = options?.weights ?? validators.map(() => 1)\n if (weights.length !== validators.length) {\n throw new Error('composeValidators: weights length mismatch')\n }\n const totalWeight = weights.reduce((a, b) => a + b, 0) || 1\n return {\n name: options?.name ?? validators.map((v) => v.name).join('+'),\n async validate(artifact, ctx) {\n const results = await Promise.all(validators.map((v) => v.validate(artifact, ctx)))\n const pass = results.every((r) => r.pass)\n const score = results.reduce((acc, r, i) => acc + r.score * weights[i]!, 0) / totalWeight\n return {\n pass,\n score,\n issues: results.flatMap((r, i) =>\n r.issues.map((issue) => ({\n ...issue,\n locus: issue.locus ? `${validators[i]!.name}:${issue.locus}` : validators[i]!.name,\n })),\n ),\n evidence: Object.fromEntries(results.map((r, i) => [validators[i]!.name, r.evidence])),\n }\n },\n }\n}\n\n// ---------------------------------------------------------------------------\n// Built-in validators\n// ---------------------------------------------------------------------------\n\n/** Pass if the artifact body matches a provided regex. */\nexport function regexMatch(name: string, pattern: RegExp): ArtifactValidator {\n return {\n name,\n async validate(artifact) {\n const body = artifact.content ?? ''\n const ok = pattern.test(body)\n return {\n pass: ok,\n score: ok ? 1 : 0,\n issues: ok\n ? []\n : [{ severity: 'error', message: `Artifact content did not match ${pattern}` }],\n }\n },\n }\n}\n\n/** Pass if JSON parses and every required key is present. */\nexport function jsonHasKeys(name: string, requiredPaths: string[]): ArtifactValidator {\n return {\n name,\n async validate(artifact) {\n const body = artifact.content ?? ''\n let parsed: unknown\n try {\n parsed = JSON.parse(body) as unknown\n } catch (err) {\n return {\n pass: false,\n score: 0,\n issues: [\n {\n severity: 'error',\n message: `Invalid JSON: ${err instanceof Error ? err.message : err}`,\n },\n ],\n }\n }\n const missing: string[] = []\n for (const path of requiredPaths) {\n if (!pathExists(parsed, path)) missing.push(path)\n }\n const pass = missing.length === 0\n return {\n pass,\n score: 1 - missing.length / Math.max(1, requiredPaths.length),\n issues: missing.map((p) => ({\n severity: 'error' as const,\n message: `Missing path: ${p}`,\n locus: p,\n })),\n }\n },\n }\n}\n\n/** Pass if min ≤ byte length ≤ max. */\nexport function byteLengthRange(name: string, min: number, max: number): ArtifactValidator {\n return {\n name,\n async validate(artifact) {\n const size =\n artifact.bytes?.byteLength ?? new TextEncoder().encode(artifact.content ?? '').byteLength\n const pass = size >= min && size <= max\n const score = pass ? 1 : size < min ? Math.max(0, size / min) : Math.max(0, max / size)\n return {\n pass,\n score,\n issues: pass\n ? []\n : [{ severity: 'error', message: `Size ${size} outside [${min}, ${max}]` }],\n }\n },\n }\n}\n\n/** Pass if the artifact contains every required substring (case-insensitive by default). */\nexport function containsAll(\n name: string,\n required: string[],\n options?: { caseSensitive?: boolean },\n): ArtifactValidator {\n const cs = options?.caseSensitive ?? false\n return {\n name,\n async validate(artifact) {\n const body = cs ? (artifact.content ?? '') : (artifact.content ?? '').toLowerCase()\n const missing: string[] = []\n for (const needle of required) {\n const probe = cs ? needle : needle.toLowerCase()\n if (!body.includes(probe)) missing.push(needle)\n }\n const pass = missing.length === 0\n return {\n pass,\n score: 1 - missing.length / Math.max(1, required.length),\n issues: missing.map((m) => ({\n severity: 'error' as const,\n message: `Missing substring: ${m}`,\n })),\n }\n },\n }\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction pathExists(obj: unknown, path: string): boolean {\n const parts = path.split('.')\n let current: unknown = obj\n for (const part of parts) {\n if (current === null || typeof current !== 'object') return false\n const key = /^\\d+$/.test(part) ? Number(part) : part\n current = (current as Record<string, unknown>)[key as unknown as string]\n if (current === undefined) return false\n }\n return true\n}\n","/**\n * Completion verifier — the task-completion oracle.\n *\n * Answers the only eval question that is not a proxy: did the agent actually\n * COMPLETE the task — produce every required deliverable, persisted and\n * correct — rather than describe what should be done. A fluent transcript\n * that never produces the artifact scores zero here.\n *\n * Per requirement, a two-stage check:\n * 1. Structural — a produced item (vault artifact / approved proposal /\n * tool call) of the right kind is matched against the requirement and\n * carries non-empty content. Deterministic; no LLM.\n * 2. Correctness — only if structurally present AND the matched item\n * carries content, one targeted check decides whether that item\n * actually fulfils the requirement. A hallucinated artifact fails here;\n * an absent one already failed stage 1.\n *\n * `completionRate` is satisfied / total. Quality dimensions are meaningless\n * on an incomplete task — callers gate on `fullyComplete` / `completionRate`\n * before scoring quality.\n */\n\nimport type { TCloud } from '@tangle-network/tcloud'\nimport type { Artifact } from './artifact-validator'\n\n/** What kind of produced state can satisfy a requirement structurally. */\nexport type SatisfiedBy = 'artifact' | 'proposal' | 'tool-call' | 'any'\n\nexport interface CompletionRequirement {\n /** Stable id from the task gold (e.g. a persona's `expected_requirements[].req_id`). */\n reqId: string\n /** Human-readable description of the required deliverable. */\n title: string\n /** Optional kind/category hint, matched against a produced item's kind. */\n category?: string\n /** What produced state satisfies this requirement. Defaults to 'any'. */\n satisfiedBy?: SatisfiedBy\n}\n\nexport interface TaskGold {\n taskId: string\n requirements: CompletionRequirement[]\n}\n\nexport interface ProducedProposal {\n id: string\n title: string\n status: 'pending' | 'approved' | 'rejected'\n /** Optional persisted body — when present, enables a correctness check. */\n content?: string\n}\n\n/** Everything observable about what a run actually produced. */\nexport interface ProducedState {\n /** Persisted vault artifacts. Reuses the shared `Artifact` shape. */\n artifacts: Artifact[]\n /** Proposals / filings the agent created. */\n proposals: ProducedProposal[]\n /** Names of tools the agent invoked. */\n toolCalls: string[]\n}\n\nexport interface RequirementCheck {\n reqId: string\n title: string\n /** A produced item of the right kind matched the requirement, non-empty. */\n structurallyPresent: boolean\n /**\n * Whether the matched item actually fulfils the requirement. `null` when\n * not structurally present, or when the matched item carries no content\n * to assess.\n */\n correct: boolean | null\n /** structurallyPresent && correct !== false. */\n satisfied: boolean\n /** Human-readable evidence for the verdict. */\n evidence: string[]\n}\n\nexport interface CompletionVerdict {\n taskId: string\n requirements: RequirementCheck[]\n /** satisfied / total requirements. */\n completionRate: number\n /** Every requirement satisfied. */\n fullyComplete: boolean\n}\n\n/**\n * Decides whether a produced item's content actually fulfils a requirement.\n * Injected so the structural verifier stays pure and unit-testable; the\n * production implementation is `createLlmCorrectnessChecker`.\n */\nexport type CorrectnessChecker = (\n requirement: CompletionRequirement,\n content: string,\n) => Promise<{ correct: boolean; reason: string }>\n\nconst STOPWORDS = new Set([\n 'the',\n 'a',\n 'an',\n 'of',\n 'for',\n 'and',\n 'or',\n 'to',\n 'in',\n 'on',\n 'with',\n 'by',\n])\n\nconst MATCH_THRESHOLD = 0.5\nconst MIN_CONTENT_CHARS = 50\n\nfunction tokens(s: string): Set<string> {\n return new Set(\n s\n .toLowerCase()\n .split(/[^a-z0-9]+/)\n .filter((t) => t.length > 1 && !STOPWORDS.has(t)),\n )\n}\n\n/**\n * Recall of the requirement's tokens within a candidate's identifying text.\n * Recall, not Jaccard — a candidate's path/id legitimately carries extra\n * tokens the requirement does not name.\n */\nfunction tokenRecall(requirementText: string, candidateText: string): number {\n const req = tokens(requirementText)\n if (req.size === 0) return 0\n const cand = tokens(candidateText)\n let hit = 0\n for (const t of req) if (cand.has(t)) hit++\n return hit / req.size\n}\n\ninterface Candidate {\n reqIndex: number\n /** Unique key for a produced item — each item satisfies at most one requirement. */\n itemKey: string\n score: number\n evidence: string\n /** Content to correctness-check, or null when the matched item has none. */\n content: string | null\n}\n\nfunction artifactCandidates(\n req: CompletionRequirement,\n reqIndex: number,\n artifacts: Artifact[],\n): Candidate[] {\n const reqText = `${req.title} ${req.category ?? ''}`\n const out: Candidate[] = []\n artifacts.forEach((a, i) => {\n if ((a.content ?? '').trim().length < MIN_CONTENT_CHARS) return\n let score = tokenRecall(reqText, `${a.path ?? ''} ${a.kind}`)\n if (req.category && a.kind && req.category.toLowerCase() === a.kind.toLowerCase()) {\n score = Math.max(score, 1)\n }\n if (score < MATCH_THRESHOLD) return\n out.push({\n reqIndex,\n itemKey: `artifact:${i}`,\n score,\n evidence: `artifact '${a.path ?? a.kind}' matched (token recall ${score.toFixed(2)})`,\n content: a.content ?? null,\n })\n })\n return out\n}\n\nfunction proposalCandidates(\n req: CompletionRequirement,\n reqIndex: number,\n proposals: ProducedProposal[],\n): Candidate[] {\n const reqText = `${req.title} ${req.category ?? ''}`\n const out: Candidate[] = []\n for (const p of proposals) {\n // Pending or rejected work is not a completed deliverable.\n if (p.status !== 'approved') continue\n const score = tokenRecall(reqText, p.title)\n if (score < MATCH_THRESHOLD) continue\n const body = p.content ?? ''\n out.push({\n reqIndex,\n itemKey: `proposal:${p.id}`,\n score,\n evidence: `approved proposal '${p.title}' matched (token recall ${score.toFixed(2)})`,\n content: body.trim().length >= MIN_CONTENT_CHARS ? body : null,\n })\n }\n return out\n}\n\nfunction toolCallCandidates(\n req: CompletionRequirement,\n reqIndex: number,\n toolCalls: string[],\n): Candidate[] {\n const out: Candidate[] = []\n toolCalls.forEach((name, i) => {\n const score = tokenRecall(req.title, name)\n if (score < MATCH_THRESHOLD) return\n out.push({\n reqIndex,\n itemKey: `tool:${i}`,\n score,\n evidence: `tool call '${name}' matched (token recall ${score.toFixed(2)})`,\n content: null,\n })\n })\n return out\n}\n\n/**\n * Verify whether a run completed the task. `checkCorrectness` is injected —\n * `createLlmCorrectnessChecker` for production, a deterministic stub in tests.\n *\n * Throws on a gold spec with no requirements: an eval task that requires\n * nothing is a misconfiguration, not a vacuously-complete task.\n */\nexport async function verifyCompletion(\n gold: TaskGold,\n state: ProducedState,\n checkCorrectness: CorrectnessChecker,\n): Promise<CompletionVerdict> {\n if (gold.requirements.length === 0) {\n throw new Error(\n `verifyCompletion: task '${gold.taskId}' has no requirements — malformed gold spec`,\n )\n }\n\n // Collect every above-threshold (requirement, produced-item) candidate, then\n // assign greedily by descending score: each requirement and each produced\n // item is used at most once. One deliverable fulfils one requirement.\n const candidates: Candidate[] = []\n gold.requirements.forEach((req, i) => {\n const by = req.satisfiedBy ?? 'any'\n if (by === 'artifact' || by === 'any') {\n candidates.push(...artifactCandidates(req, i, state.artifacts))\n }\n if (by === 'proposal' || by === 'any') {\n candidates.push(...proposalCandidates(req, i, state.proposals))\n }\n if (by === 'tool-call' || by === 'any') {\n candidates.push(...toolCallCandidates(req, i, state.toolCalls))\n }\n })\n candidates.sort((a, b) => b.score - a.score)\n\n const assigned = new Map<number, Candidate>()\n const itemTaken = new Set<string>()\n for (const c of candidates) {\n if (assigned.has(c.reqIndex) || itemTaken.has(c.itemKey)) continue\n assigned.set(c.reqIndex, c)\n itemTaken.add(c.itemKey)\n }\n\n const requirements: RequirementCheck[] = []\n for (let i = 0; i < gold.requirements.length; i++) {\n const req = gold.requirements[i]!\n const match = assigned.get(i)\n const evidence: string[] = []\n let correct: boolean | null = null\n\n if (match) {\n evidence.push(match.evidence)\n if (match.content !== null) {\n const r = await checkCorrectness(req, match.content)\n correct = r.correct\n evidence.push(`correctness: ${r.correct ? 'pass' : 'fail'} — ${r.reason}`)\n } else {\n evidence.push('correctness: not assessed — matched item carries no content')\n }\n } else {\n const by = req.satisfiedBy ?? 'any'\n const kind = by === 'any' ? 'artifact/proposal/tool-call' : by\n evidence.push(`no produced ${kind} matched this requirement`)\n }\n\n const structurallyPresent = match !== undefined\n const satisfied = structurallyPresent && correct !== false\n requirements.push({\n reqId: req.reqId,\n title: req.title,\n structurallyPresent,\n correct,\n satisfied,\n evidence,\n })\n }\n\n const satisfiedCount = requirements.filter((r) => r.satisfied).length\n return {\n taskId: gold.taskId,\n requirements,\n completionRate: satisfiedCount / requirements.length,\n fullyComplete: satisfiedCount === requirements.length,\n }\n}\n\nexport interface LlmCorrectnessCheckerOpts {\n model?: string\n /** Max chars of artifact content sent to the checker. */\n maxContentChars?: number\n}\n\n/** Parse the correctness checker's model response. Fails loud on a bad shape. */\nexport function parseCorrectnessResponse(raw: string): { correct: boolean; reason: string } {\n const match = raw.match(/\\{[\\s\\S]*\\}/)\n if (!match) {\n throw new Error(`correctness checker: no JSON object in model response: ${raw.slice(0, 200)}`)\n }\n const parsed = JSON.parse(match[0]) as { correct?: unknown; reason?: unknown }\n if (typeof parsed.correct !== 'boolean') {\n throw new Error(`correctness checker: 'correct' is not a boolean in: ${match[0].slice(0, 200)}`)\n }\n return { correct: parsed.correct, reason: typeof parsed.reason === 'string' ? parsed.reason : '' }\n}\n\n/**\n * Production `CorrectnessChecker` — one LLM call per matched artifact,\n * deterministic (temperature 0), structured JSON out. Judges fulfilment\n * only: a plan, a gesture, or a description of what should be done does not\n * fulfil a requirement — the artifact must BE the deliverable.\n */\nexport function createLlmCorrectnessChecker(\n tc: TCloud,\n opts: LlmCorrectnessCheckerOpts = {},\n): CorrectnessChecker {\n const model = opts.model ?? 'claude-sonnet-4-6'\n const maxContentChars = opts.maxContentChars ?? 8000\n return async (requirement, content) => {\n const resp = await tc.chat({\n model,\n messages: [\n {\n role: 'system',\n content:\n 'You verify whether a produced work artifact actually fulfils a stated requirement. Judge fulfilment only — is the deliverable substantively present and on-point — not polish. A plan to do it later, a vague gesture, or a description of what should be done does NOT fulfil a requirement; the artifact must BE the deliverable. Respond with a single JSON object: {\"correct\": boolean, \"reason\": string (<= 30 words)}.',\n },\n {\n role: 'user',\n content: `Requirement: ${requirement.title}\\n${\n requirement.category ? `Category: ${requirement.category}\\n` : ''\n }\\nProduced artifact:\\n${content.slice(0, maxContentChars)}`,\n },\n ],\n temperature: 0,\n maxTokens: 200,\n })\n const raw =\n (resp as { choices?: { message?: { content?: string } }[] }).choices?.[0]?.message?.content ??\n ''\n return parseCorrectnessResponse(raw)\n }\n}\n","/**\n * Dual-agent convergence bench.\n *\n * Pattern lifted from dual-worker review loops: two agents take turns until\n * they converge on a consensus artifact. One proposes, the other critiques;\n * the proposer revises; repeat until a score threshold is hit or max rounds.\n *\n * Generalized so any two \"agents\" (gateways, local functions, anything with\n * `propose` + `critique`) compose in. Returns convergence rounds per\n * scenario + whether convergence happened.\n */\n\nexport interface DualAgentScenario {\n id: string\n initialPrompt: string\n /** Optional context the agents can read (e.g. source documents). */\n context?: Record<string, unknown>\n}\n\nexport interface DualAgentRound {\n roundIndex: number\n proposal: string\n critique: string\n convergenceScore: number // 0..1 — how close to convergence\n}\n\nexport interface DualAgentScenarioResult {\n scenarioId: string\n converged: boolean\n roundsToConverge: number | null\n finalProposal: string\n history: DualAgentRound[]\n finalScore: number\n}\n\nexport interface DualAgentBenchConfig {\n scenarios: DualAgentScenario[]\n maxRounds?: number\n /** Convergence threshold in 0..1 (default 0.85). */\n convergenceThreshold?: number\n /**\n * Propose an answer given the scenario + the critic's prior critique (if any).\n * Returns the proposal string.\n */\n propose: (args: {\n scenario: DualAgentScenario\n roundIndex: number\n priorProposal?: string\n priorCritique?: string\n }) => Promise<string>\n /**\n * Critique the proposer's current output. Returns a structured critique\n * (free text) plus a convergence score: how close the proposal is to\n * acceptable. 1.0 = accept, 0.0 = totally off.\n */\n critique: (args: {\n scenario: DualAgentScenario\n roundIndex: number\n proposal: string\n }) => Promise<{ critique: string; convergenceScore: number }>\n /** Optional per-round hook for progress + tracing. */\n onRoundComplete?: (info: { scenarioId: string; round: DualAgentRound }) => void\n}\n\nexport interface DualAgentReport {\n scenarios: DualAgentScenarioResult[]\n aggregate: {\n convergenceRate: number // fraction of scenarios that converged within maxRounds\n avgRoundsToConverge: number | null // over scenarios that DID converge\n avgFinalScore: number\n }\n config: {\n maxRounds: number\n convergenceThreshold: number\n }\n}\n\nexport class DualAgentBench {\n async run(config: DualAgentBenchConfig): Promise<DualAgentReport> {\n const maxRounds = config.maxRounds ?? 5\n const threshold = config.convergenceThreshold ?? 0.85\n\n if (config.scenarios.length === 0) {\n throw new Error('DualAgentBench requires at least 1 scenario')\n }\n\n const results: DualAgentScenarioResult[] = []\n\n for (const scenario of config.scenarios) {\n const history: DualAgentRound[] = []\n let converged = false\n let roundsToConverge: number | null = null\n let finalProposal = ''\n let lastScore = 0\n let priorCritique: string | undefined\n\n for (let r = 0; r < maxRounds; r++) {\n const priorProposal = history[history.length - 1]?.proposal\n const proposal = await config.propose({\n scenario,\n roundIndex: r,\n priorProposal,\n priorCritique,\n })\n const { critique, convergenceScore } = await config.critique({\n scenario,\n roundIndex: r,\n proposal,\n })\n\n if (!Number.isFinite(convergenceScore) || convergenceScore < 0 || convergenceScore > 1) {\n throw new Error(\n `critique must return convergenceScore in [0,1]; got ${convergenceScore} for scenario ${scenario.id} round ${r}`,\n )\n }\n\n const round: DualAgentRound = {\n roundIndex: r,\n proposal,\n critique,\n convergenceScore,\n }\n history.push(round)\n config.onRoundComplete?.({ scenarioId: scenario.id, round })\n\n finalProposal = proposal\n lastScore = convergenceScore\n priorCritique = critique\n\n if (convergenceScore >= threshold) {\n converged = true\n roundsToConverge = r + 1\n break\n }\n }\n\n results.push({\n scenarioId: scenario.id,\n converged,\n roundsToConverge,\n finalProposal,\n history,\n finalScore: lastScore,\n })\n }\n\n const convergedResults = results.filter((r) => r.converged)\n const convergenceRate = results.length ? convergedResults.length / results.length : 0\n const avgRoundsToConverge = convergedResults.length\n ? convergedResults.reduce((acc, r) => acc + (r.roundsToConverge ?? 0), 0) /\n convergedResults.length\n : null\n const avgFinalScore = results.length\n ? results.reduce((acc, r) => acc + r.finalScore, 0) / results.length\n : 0\n\n return {\n scenarios: results,\n aggregate: { convergenceRate, avgRoundsToConverge, avgFinalScore },\n config: { maxRounds, convergenceThreshold: threshold },\n }\n }\n}\n","/**\n * Experiment tracker — group runs, diff them, watch scores move over time.\n *\n * Not MLflow. Not Weights & Biases. Just the 20% that actually ships:\n * - A run has a config (prompt hash, model, scenario ids, seed)\n * - Runs belong to experiments (named groups)\n * - The store is pluggable (in-memory for tests, filesystem for local,\n * custom for Langfuse/D1)\n * - Diffs show score deltas, new/dropped scenarios, and config changes\n *\n * The output plugs directly into `BenchmarkReport` — runs archive the full\n * report, diff operates on the summary.\n */\n\nimport type { BenchmarkReport } from './types'\n\nexport interface RunConfig {\n experimentId: string\n name?: string\n model?: string\n promptHash?: string\n promptVersion?: string\n seed?: number\n metadata?: Record<string, unknown>\n}\n\nexport interface Run {\n id: string\n experimentId: string\n name?: string\n config: RunConfig\n startedAt: string\n completedAt?: string\n status: 'running' | 'completed' | 'failed'\n report?: BenchmarkReport\n error?: string\n}\n\nexport interface Experiment {\n id: string\n name: string\n createdAt: string\n metadata?: Record<string, unknown>\n}\n\nexport interface ExperimentStore {\n saveExperiment(exp: Experiment): Promise<void>\n getExperiment(id: string): Promise<Experiment | null>\n listExperiments(): Promise<Experiment[]>\n saveRun(run: Run): Promise<void>\n getRun(id: string): Promise<Run | null>\n listRuns(experimentId: string): Promise<Run[]>\n}\n\nexport class InMemoryExperimentStore implements ExperimentStore {\n private readonly experiments = new Map<string, Experiment>()\n private readonly runs = new Map<string, Run>()\n\n async saveExperiment(exp: Experiment): Promise<void> {\n this.experiments.set(exp.id, { ...exp })\n }\n async getExperiment(id: string): Promise<Experiment | null> {\n const e = this.experiments.get(id)\n return e ? { ...e } : null\n }\n async listExperiments(): Promise<Experiment[]> {\n return [...this.experiments.values()].sort((a, b) => b.createdAt.localeCompare(a.createdAt))\n }\n async saveRun(run: Run): Promise<void> {\n this.runs.set(run.id, structuredClone(run))\n }\n async getRun(id: string): Promise<Run | null> {\n const r = this.runs.get(id)\n return r ? structuredClone(r) : null\n }\n async listRuns(experimentId: string): Promise<Run[]> {\n return [...this.runs.values()]\n .filter((r) => r.experimentId === experimentId)\n .sort((a, b) => b.startedAt.localeCompare(a.startedAt))\n .map((r) => structuredClone(r))\n }\n}\n\n// ---------------------------------------------------------------------------\n// The tracker itself\n// ---------------------------------------------------------------------------\n\nexport class ExperimentTracker {\n constructor(private readonly store: ExperimentStore) {}\n\n async startExperiment(name: string, metadata?: Record<string, unknown>): Promise<Experiment> {\n const exp: Experiment = {\n id: `exp_${rand(8)}`,\n name,\n createdAt: new Date().toISOString(),\n metadata,\n }\n await this.store.saveExperiment(exp)\n return exp\n }\n\n async startRun(config: RunConfig): Promise<Run> {\n const exp = await this.store.getExperiment(config.experimentId)\n if (!exp) throw new Error(`Experiment ${config.experimentId} not found`)\n\n const run: Run = {\n id: `run_${rand(10)}`,\n experimentId: config.experimentId,\n name: config.name,\n config,\n startedAt: new Date().toISOString(),\n status: 'running',\n }\n await this.store.saveRun(run)\n return run\n }\n\n async completeRun(runId: string, report: BenchmarkReport): Promise<void> {\n const run = await this.store.getRun(runId)\n if (!run) throw new Error(`Run ${runId} not found`)\n run.status = 'completed'\n run.completedAt = new Date().toISOString()\n run.report = report\n await this.store.saveRun(run)\n }\n\n async failRun(runId: string, error: string): Promise<void> {\n const run = await this.store.getRun(runId)\n if (!run) throw new Error(`Run ${runId} not found`)\n run.status = 'failed'\n run.completedAt = new Date().toISOString()\n run.error = error\n await this.store.saveRun(run)\n }\n\n /**\n * Diff two completed runs. Returns per-scenario deltas, aggregate delta,\n * and config changes that may explain the movement.\n */\n async diff(runIdA: string, runIdB: string): Promise<RunDiff> {\n const [a, b] = await Promise.all([this.store.getRun(runIdA), this.store.getRun(runIdB)])\n if (!a || !b) throw new Error('Both runs must exist')\n if (!a.report || !b.report) throw new Error('Both runs must be completed with reports')\n\n const byScenarioA = new Map(a.report.results.map((r) => [r.scenarioId, r.overallScore]))\n const byScenarioB = new Map(b.report.results.map((r) => [r.scenarioId, r.overallScore]))\n\n const scenarioIds = new Set([...byScenarioA.keys(), ...byScenarioB.keys()])\n const scenarios: RunDiff['scenarios'] = []\n for (const id of scenarioIds) {\n const aScore = byScenarioA.get(id)\n const bScore = byScenarioB.get(id)\n if (aScore === undefined) {\n scenarios.push({\n scenarioId: id,\n before: null,\n after: bScore!,\n delta: null,\n status: 'added',\n })\n } else if (bScore === undefined) {\n scenarios.push({\n scenarioId: id,\n before: aScore,\n after: null,\n delta: null,\n status: 'removed',\n })\n } else {\n scenarios.push({\n scenarioId: id,\n before: aScore,\n after: bScore,\n delta: bScore - aScore,\n status: bScore > aScore ? 'improved' : bScore < aScore ? 'regressed' : 'unchanged',\n })\n }\n }\n scenarios.sort((x, y) => (y.delta ?? 0) - (x.delta ?? 0))\n\n const aggregateDelta = b.report.summary.overallAvg - a.report.summary.overallAvg\n const configChanges: Record<string, { before: unknown; after: unknown }> = {}\n const keys = new Set([...Object.keys(a.config), ...Object.keys(b.config)])\n const aCfg = a.config as unknown as Record<string, unknown>\n const bCfg = b.config as unknown as Record<string, unknown>\n for (const k of keys) {\n if (JSON.stringify(aCfg[k]) !== JSON.stringify(bCfg[k])) {\n configChanges[k] = { before: aCfg[k], after: bCfg[k] }\n }\n }\n\n return {\n before: { runId: runIdA, name: a.name, startedAt: a.startedAt },\n after: { runId: runIdB, name: b.name, startedAt: b.startedAt },\n aggregateDelta,\n scenarios,\n configChanges,\n }\n }\n\n /** Timeline of aggregate scores for an experiment. */\n async timeline(\n experimentId: string,\n ): Promise<Array<{ runId: string; startedAt: string; overall: number | null }>> {\n const runs = await this.store.listRuns(experimentId)\n return runs\n .slice()\n .sort((a, b) => a.startedAt.localeCompare(b.startedAt))\n .map((r) => ({\n runId: r.id,\n startedAt: r.startedAt,\n overall: r.report?.summary.overallAvg ?? null,\n }))\n }\n}\n\nexport interface RunDiff {\n before: { runId: string; name?: string; startedAt: string }\n after: { runId: string; name?: string; startedAt: string }\n aggregateDelta: number\n scenarios: Array<{\n scenarioId: string\n before: number | null\n after: number | null\n delta: number | null\n status: 'improved' | 'regressed' | 'unchanged' | 'added' | 'removed'\n }>\n configChanges: Record<string, { before: unknown; after: unknown }>\n}\n\nfunction rand(bytes: number): string {\n const arr = new Uint8Array(bytes)\n crypto.getRandomValues(arr)\n return Array.from(arr)\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('')\n}\n","/**\n * D1ExperimentStore — Cloudflare D1-backed `ExperimentStore`.\n *\n * Workers-safe (uses only the `D1Database` binding the runtime injects). Two\n * tables, no joins, no migrations beyond `ensureSchema()`. Schema designed so\n * a Worker route can both write the row at run start and update it at run end\n * without losing the original config — the row's lifecycle mirrors the\n * `Run.status` field one-to-one.\n *\n * Why this lives next to `InMemoryExperimentStore`:\n * - browser, coding, and computer-use agents can all run as Workers\n * - Workers cannot use `node:fs`, so `FileSystemExperimentStore` doesn't apply\n * - Hand-rolling D1 SQL in every consumer is exactly the duplication this\n * module exists to prevent\n *\n * Schema versioning: the `meta` table records `schema_version` so a future\n * column addition can be detected and migrated additively. Today's schema is\n * v1; bump only on breaking shape changes.\n */\n\nimport type { Experiment, ExperimentStore, Run } from './experiment-tracker'\n\n/**\n * Minimal `D1Database` shape we depend on. Avoids pulling in\n * `@cloudflare/workers-types` as a hard dep — consumers that already have\n * those types installed can pass the binding directly.\n */\nexport interface D1Like {\n prepare(query: string): D1PreparedStatementLike\n batch?(statements: D1PreparedStatementLike[]): Promise<unknown[]>\n exec(query: string): Promise<unknown>\n}\n\nexport interface D1PreparedStatementLike {\n bind(...values: unknown[]): D1PreparedStatementLike\n first<T = Record<string, unknown>>(): Promise<T | null>\n all<T = Record<string, unknown>>(): Promise<{ results: T[] }>\n run(): Promise<unknown>\n}\n\nexport interface D1ExperimentStoreOptions {\n /** D1 binding from `env`. */\n db: D1Like\n /**\n * Optional table-name prefix so multiple ExperimentStores can share a DB\n * without colliding (e.g. `browser_eval_experiments` vs `coding_eval_experiments`).\n * Default: `agent_eval_`.\n */\n tablePrefix?: string\n}\n\nconst SCHEMA_VERSION = 1\n\nexport class D1ExperimentStore implements ExperimentStore {\n private readonly db: D1Like\n private readonly experimentsTable: string\n private readonly runsTable: string\n private readonly metaTable: string\n private schemaReady = false\n\n constructor(options: D1ExperimentStoreOptions) {\n this.db = options.db\n const prefix = options.tablePrefix ?? 'agent_eval_'\n this.experimentsTable = `${prefix}experiments`\n this.runsTable = `${prefix}runs`\n this.metaTable = `${prefix}meta`\n }\n\n /**\n * Idempotent schema setup. Safe to call before every operation; the second\n * call short-circuits via `schemaReady`. Most consumers will call it once\n * during Worker bootstrap.\n */\n async ensureSchema(): Promise<void> {\n if (this.schemaReady) return\n // Single `exec` so D1 batches the DDL.\n const ddl = `\n CREATE TABLE IF NOT EXISTS ${this.experimentsTable} (\n id TEXT PRIMARY KEY,\n name TEXT NOT NULL,\n created_at TEXT NOT NULL,\n metadata_json TEXT\n );\n CREATE TABLE IF NOT EXISTS ${this.runsTable} (\n id TEXT PRIMARY KEY,\n experiment_id TEXT NOT NULL,\n name TEXT,\n status TEXT NOT NULL,\n started_at TEXT NOT NULL,\n completed_at TEXT,\n config_json TEXT NOT NULL,\n report_json TEXT,\n error TEXT\n );\n CREATE INDEX IF NOT EXISTS idx_${this.runsTable}_experiment ON ${this.runsTable}(experiment_id);\n CREATE INDEX IF NOT EXISTS idx_${this.runsTable}_started ON ${this.runsTable}(started_at);\n CREATE TABLE IF NOT EXISTS ${this.metaTable} (\n key TEXT PRIMARY KEY,\n value TEXT NOT NULL\n );\n INSERT OR REPLACE INTO ${this.metaTable}(key, value) VALUES ('schema_version', '${SCHEMA_VERSION}');\n `\n await this.db.exec(ddl.trim().replace(/\\s+/g, ' '))\n this.schemaReady = true\n }\n\n async saveExperiment(exp: Experiment): Promise<void> {\n await this.ensureSchema()\n await this.db\n .prepare(\n `INSERT INTO ${this.experimentsTable}(id, name, created_at, metadata_json)\n VALUES (?1, ?2, ?3, ?4)\n ON CONFLICT(id) DO UPDATE SET\n name = excluded.name,\n created_at = excluded.created_at,\n metadata_json = excluded.metadata_json`,\n )\n .bind(exp.id, exp.name, exp.createdAt, exp.metadata ? JSON.stringify(exp.metadata) : null)\n .run()\n }\n\n async getExperiment(id: string): Promise<Experiment | null> {\n await this.ensureSchema()\n const row = await this.db\n .prepare(\n `SELECT id, name, created_at, metadata_json\n FROM ${this.experimentsTable}\n WHERE id = ?1`,\n )\n .bind(id)\n .first<ExperimentRow>()\n return row ? rowToExperiment(row) : null\n }\n\n async listExperiments(): Promise<Experiment[]> {\n await this.ensureSchema()\n const { results } = await this.db\n .prepare(\n `SELECT id, name, created_at, metadata_json\n FROM ${this.experimentsTable}\n ORDER BY created_at DESC`,\n )\n .all<ExperimentRow>()\n return results.map(rowToExperiment)\n }\n\n async saveRun(run: Run): Promise<void> {\n await this.ensureSchema()\n await this.db\n .prepare(\n `INSERT INTO ${this.runsTable}(id, experiment_id, name, status, started_at, completed_at, config_json, report_json, error)\n VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9)\n ON CONFLICT(id) DO UPDATE SET\n experiment_id = excluded.experiment_id,\n name = excluded.name,\n status = excluded.status,\n started_at = excluded.started_at,\n completed_at = excluded.completed_at,\n config_json = excluded.config_json,\n report_json = excluded.report_json,\n error = excluded.error`,\n )\n .bind(\n run.id,\n run.experimentId,\n run.name ?? null,\n run.status,\n run.startedAt,\n run.completedAt ?? null,\n JSON.stringify(run.config),\n run.report ? JSON.stringify(run.report) : null,\n run.error ?? null,\n )\n .run()\n }\n\n async getRun(id: string): Promise<Run | null> {\n await this.ensureSchema()\n const row = await this.db\n .prepare(\n `SELECT id, experiment_id, name, status, started_at, completed_at, config_json, report_json, error\n FROM ${this.runsTable}\n WHERE id = ?1`,\n )\n .bind(id)\n .first<RunRow>()\n return row ? rowToRun(row) : null\n }\n\n async listRuns(experimentId: string): Promise<Run[]> {\n await this.ensureSchema()\n const { results } = await this.db\n .prepare(\n `SELECT id, experiment_id, name, status, started_at, completed_at, config_json, report_json, error\n FROM ${this.runsTable}\n WHERE experiment_id = ?1\n ORDER BY started_at DESC`,\n )\n .bind(experimentId)\n .all<RunRow>()\n return results.map(rowToRun)\n }\n}\n\ninterface ExperimentRow {\n id: string\n name: string\n created_at: string\n metadata_json: string | null\n}\n\ninterface RunRow {\n id: string\n experiment_id: string\n name: string | null\n status: string\n started_at: string\n completed_at: string | null\n config_json: string\n report_json: string | null\n error: string | null\n}\n\nfunction rowToExperiment(row: ExperimentRow): Experiment {\n return {\n id: row.id,\n name: row.name,\n createdAt: row.created_at,\n ...(row.metadata_json\n ? { metadata: JSON.parse(row.metadata_json) as Record<string, unknown> }\n : {}),\n }\n}\n\nfunction rowToRun(row: RunRow): Run {\n return {\n id: row.id,\n experimentId: row.experiment_id,\n ...(row.name ? { name: row.name } : {}),\n status: row.status as Run['status'],\n startedAt: row.started_at,\n ...(row.completed_at ? { completedAt: row.completed_at } : {}),\n config: JSON.parse(row.config_json),\n ...(row.report_json ? { report: JSON.parse(row.report_json) } : {}),\n ...(row.error ? { error: row.error } : {}),\n }\n}\n","/**\n * FileSystemExperimentStore — NDJSON-backed `ExperimentStore` for local + CI.\n *\n * Mirrors the file layout of `FileSystemTraceStore`: two append-only NDJSON\n * files (`experiments.ndjson` + `runs.ndjson`) under one directory, with size-\n * based rollover. Writes are append-only so the file log doubles as an audit\n * trail of every state transition the tracker ever wrote.\n *\n * Reads lazy-load every NDJSON file in the directory (including rolled-over\n * archives), latest-write-wins per `id`. Subsequent writes update the\n * in-memory index in place so reads after writes are O(1).\n *\n * Node-only — imports `node:fs/promises`. Don't import this from a Worker;\n * use the in-memory store or the D1 store from `./experiment-tracker-d1`.\n */\n\nimport {\n type Experiment,\n type ExperimentStore,\n InMemoryExperimentStore,\n type Run,\n} from './experiment-tracker'\n\nexport interface FileSystemExperimentStoreOptions {\n /** Directory the NDJSON files live in. Created on first write. */\n dir: string\n /** Bytes after which a file is rolled over. Default 32 MB (matches FileSystemTraceStore). */\n maxBytes?: number\n}\n\nexport class FileSystemExperimentStore implements ExperimentStore {\n private readonly dir: string\n private readonly maxBytes: number\n private index?: InMemoryExperimentStore\n private loaded = false\n\n constructor(options: FileSystemExperimentStoreOptions) {\n this.dir = options.dir\n this.maxBytes = options.maxBytes ?? 32 * 1024 * 1024\n }\n\n async saveExperiment(exp: Experiment): Promise<void> {\n const idx = await this.load()\n await idx.saveExperiment(exp)\n await this.append('experiments', exp)\n }\n\n async getExperiment(id: string): Promise<Experiment | null> {\n const idx = await this.load()\n return idx.getExperiment(id)\n }\n\n async listExperiments(): Promise<Experiment[]> {\n const idx = await this.load()\n return idx.listExperiments()\n }\n\n async saveRun(run: Run): Promise<void> {\n const idx = await this.load()\n await idx.saveRun(run)\n await this.append('runs', run)\n }\n\n async getRun(id: string): Promise<Run | null> {\n const idx = await this.load()\n return idx.getRun(id)\n }\n\n async listRuns(experimentId: string): Promise<Run[]> {\n const idx = await this.load()\n return idx.listRuns(experimentId)\n }\n\n private async ensureDir(): Promise<void> {\n const fs = await import('node:fs/promises')\n await fs.mkdir(this.dir, { recursive: true })\n }\n\n private async append(name: 'experiments' | 'runs', record: unknown): Promise<void> {\n await this.ensureDir()\n const fs = await import('node:fs/promises')\n const path = await import('node:path')\n const active = path.join(this.dir, `${name}.ndjson`)\n try {\n const stat = await fs.stat(active)\n if (stat.size >= this.maxBytes) {\n const rolled = path.join(this.dir, `${name}.${Date.now()}.ndjson`)\n await fs.rename(active, rolled)\n }\n } catch {\n /* file doesn't exist yet */\n }\n await fs.appendFile(active, `${JSON.stringify(record)}\\n`, 'utf8')\n }\n\n private async load(): Promise<InMemoryExperimentStore> {\n if (this.loaded && this.index) return this.index\n const fs = await import('node:fs/promises')\n const path = await import('node:path')\n const store = new InMemoryExperimentStore()\n try {\n const entries = await fs.readdir(this.dir)\n // Sort so older rollover files load first; the active *.ndjson wins on\n // duplicate ids because saves replay in insertion order and the in-memory\n // store is last-write-wins.\n const sorted = entries.filter((f) => f.endsWith('.ndjson')).sort((a, b) => a.localeCompare(b))\n for (const file of sorted) {\n const full = path.join(this.dir, file)\n const content = await fs.readFile(full, 'utf8')\n const base = file.split('.')[0]\n for (const line of content.split('\\n')) {\n if (!line.trim()) continue\n let record: unknown\n try {\n record = JSON.parse(line)\n } catch {\n // Truncated tail line during a crash; skip.\n continue\n }\n if (base === 'experiments') {\n await store.saveExperiment(record as Experiment)\n } else if (base === 'runs') {\n await store.saveRun(record as Run)\n }\n }\n }\n } catch {\n /* empty dir, first run */\n }\n this.index = store\n this.loaded = true\n return store\n }\n}\n","/**\n * Pareto frontier — multi-objective optimization over candidate runs.\n *\n * Lifted from ADC pareto.ts and blueprint-agent frontier.ts. When you're\n * trading off (cost, latency, quality) or (passRate, tokenBudget,\n * ttfb), you rarely have a single \"winner\" — you have a set of\n * non-dominated candidates. This module exposes:\n *\n * - `paretoFrontier`: filter a set of candidates to the non-dominated ones\n * - `dominates`: does A dominate B across all objectives?\n *\n * Each objective is declared with a direction: 'maximize' (higher=better)\n * or 'minimize' (lower=better). Candidates are any object; pass an\n * `objective(candidate)` accessor.\n */\n\nexport type Direction = 'maximize' | 'minimize'\n\nexport interface Objective<T> {\n /** Stable label used in reports. */\n name: string\n direction: Direction\n value: (candidate: T) => number\n}\n\nexport interface ParetoResult<T> {\n frontier: T[]\n dominated: T[]\n /** Index map: frontier[i] dominates each of dominatedBy[i]. */\n dominanceMap: Array<{ dominator: T; dominated: T[] }>\n}\n\n/** Does candidate A weakly dominate B — strictly better on at least one objective and no worse on any? */\nexport function dominates<T>(a: T, b: T, objectives: Objective<T>[]): boolean {\n let strictlyBetter = false\n for (const obj of objectives) {\n const av = obj.value(a)\n const bv = obj.value(b)\n if (!Number.isFinite(av) || !Number.isFinite(bv)) return false\n const aIsBetter = obj.direction === 'maximize' ? av > bv : av < bv\n const aIsWorse = obj.direction === 'maximize' ? av < bv : av > bv\n if (aIsWorse) return false\n if (aIsBetter) strictlyBetter = true\n }\n return strictlyBetter\n}\n\n/**\n * Compute the non-dominated frontier. Candidates with NaN/Infinity on any\n * objective are excluded (can't rank them). A candidate enters the frontier\n * iff no other candidate dominates it.\n */\nexport function paretoFrontier<T>(candidates: T[], objectives: Objective<T>[]): ParetoResult<T> {\n if (objectives.length === 0) {\n throw new Error('paretoFrontier: at least 1 objective required')\n }\n const valid = candidates.filter((c) => objectives.every((o) => Number.isFinite(o.value(c))))\n const frontier: T[] = []\n const dominated: T[] = []\n for (const c of valid) {\n const isDominated = valid.some((other) => other !== c && dominates(other, c, objectives))\n if (isDominated) dominated.push(c)\n else frontier.push(c)\n }\n const dominanceMap = frontier.map((d) => ({\n dominator: d,\n dominated: dominated.filter((x) => dominates(d, x, objectives)),\n }))\n return { frontier, dominated, dominanceMap }\n}\n\n/**\n * Weighted-sum scalarisation. Use as a tie-break / single-winner selector\n * when callers don't want to consume a frontier. Each objective contributes\n * its normalised value (0..1 via min-max across the candidate pool) times\n * its weight; missing weights default to 1/N.\n *\n * Direction is honoured automatically — `minimize` axes have their values\n * inverted before scaling so \"higher scalar = better\" always holds.\n */\nexport function scalarScore<T>(\n candidates: T[],\n objectives: Objective<T>[],\n options: { weights?: Partial<Record<string, number>> } = {},\n): Array<{ candidate: T; score: number }> {\n if (candidates.length === 0) return []\n const weights = options.weights ?? {}\n const totalWeight = objectives.reduce((s, o) => s + (weights[o.name] ?? 1), 0)\n\n // Pre-compute min/max per objective for normalisation.\n const ranges = objectives.map((obj) => {\n const values = candidates.map((c) => obj.value(c)).filter((v) => Number.isFinite(v))\n if (values.length === 0) return { min: 0, max: 1 }\n const min = Math.min(...values)\n const max = Math.max(...values)\n return { min, max: max === min ? min + 1 : max }\n })\n\n return candidates.map((c) => {\n let score = 0\n objectives.forEach((obj, i) => {\n const v = obj.value(c)\n if (!Number.isFinite(v)) return\n const { min, max } = ranges[i]!\n const normalised = (v - min) / (max - min)\n const directional = obj.direction === 'maximize' ? normalised : 1 - normalised\n const weight = (weights[obj.name] ?? 1) / totalWeight\n score += directional * weight\n })\n return { candidate: c, score }\n })\n}\n\n/**\n * NSGA-II crowding distance — secondary sort for ties on the frontier.\n *\n * When the Pareto front collapses to a single point (or many candidates tie\n * on dominance), naive selection picks arbitrarily and the population\n * degenerates over generations. NSGA-II preserves diversity by preferring\n * candidates with more empty space around them on the frontier.\n *\n * Returns an array of `{ candidate, distance }` in the SAME order as the\n * input. Higher distance = more isolated = should be preferred when\n * preserving diversity.\n */\nexport function crowdingDistance<T>(\n candidates: T[],\n objectives: Objective<T>[],\n): Array<{ candidate: T; distance: number }> {\n const distances = new Map<T, number>(candidates.map((c) => [c, 0]))\n\n for (const obj of objectives) {\n const sorted = [...candidates].sort((a, b) => obj.value(a) - obj.value(b))\n const min = obj.value(sorted[0]!)\n const max = obj.value(sorted[sorted.length - 1]!)\n const range = max - min || 1\n\n // Boundary points get infinity (always preferred for diversity).\n distances.set(sorted[0]!, Infinity)\n distances.set(sorted[sorted.length - 1]!, Infinity)\n for (let i = 1; i < sorted.length - 1; i++) {\n const prev = obj.value(sorted[i - 1]!)\n const next = obj.value(sorted[i + 1]!)\n const current = distances.get(sorted[i]!)!\n if (current === Infinity) continue\n distances.set(sorted[i]!, current + (next - prev) / range)\n }\n }\n\n return candidates.map((c) => ({ candidate: c, distance: distances.get(c) ?? 0 }))\n}\n\n/**\n * Pareto frontier with tie-break by crowding distance — the canonical\n * NSGA-II selection step. Returns the frontier sorted by descending crowding\n * distance so callers can `.slice(0, k)` to pick K diverse winners.\n */\nexport function paretoFrontierWithCrowding<T>(\n candidates: T[],\n objectives: Objective<T>[],\n): Array<{ candidate: T; distance: number }> {\n const { frontier } = paretoFrontier(candidates, objectives)\n if (frontier.length === 0) return []\n const distances = crowdingDistance(frontier, objectives)\n return distances.sort((a, b) => b.distance - a.distance)\n}\n","import { type Objective, type ParetoResult, paretoFrontier } from './pareto'\nimport { RunCritic, type RunTrace } from './run-critic'\nimport { aggregateRunScore, type RunScore, type RunScoreWeights } from './run-score'\nimport type { SteeringBundle } from './steering'\n\nexport type HarnessIntervention =\n | 'continue'\n | 'plan'\n | 'audit'\n | 'recover'\n | 'repair'\n | 'verify'\n | 'final_gate'\n | 'wait_for_measurement'\n | 'abort'\n\nexport interface WorkflowTopology {\n id: string\n interventions: HarnessIntervention[]\n maxParallelBranches?: number\n metadata?: Record<string, unknown>\n}\n\nexport interface MeasurementPolicy {\n required: string[]\n optional?: string[]\n promoteOn?: Array<keyof RunScore | 'aggregate'>\n}\n\nexport interface HarnessVariant {\n id: string\n steering?: SteeringBundle\n topology?: WorkflowTopology\n measurement?: MeasurementPolicy\n budgets?: Record<string, number>\n models?: Record<string, string>\n reviewers?: Record<string, string>\n metadata?: Record<string, unknown>\n}\n\nexport interface HarnessScenario {\n id: string\n task: string\n split?: 'train' | 'validation' | 'test' | string\n metadata?: Record<string, unknown>\n}\n\nexport interface HarnessRunRequest {\n variant: HarnessVariant\n scenario: HarnessScenario\n trialIndex: number\n}\n\nexport interface HarnessAdapter {\n run(request: HarnessRunRequest): Promise<RunTrace>\n}\n\nexport interface HarnessRunResult {\n variant: HarnessVariant\n scenario: HarnessScenario\n trialIndex: number\n trace: RunTrace\n score: RunScore\n aggregate: number\n}\n\nexport interface HarnessVariantReport {\n variant: HarnessVariant\n runs: HarnessRunResult[]\n aggregateMean: number\n passRate: number\n costUsdMean: number\n wallSecondsMean: number\n scoreMean: RunScore\n}\n\nexport interface HarnessSelection {\n winner: HarnessVariantReport\n frontier: ParetoResult<HarnessVariantReport>\n reports: HarnessVariantReport[]\n}\n\nexport interface HarnessExperimentResult {\n results: HarnessRunResult[]\n selection: HarnessSelection\n}\n\nexport interface HarnessExperimentConfig {\n adapter: HarnessAdapter\n variants: HarnessVariant[]\n scenarios: HarnessScenario[]\n trialsPerScenario?: number\n parallelism?: number\n weights?: Partial<RunScoreWeights>\n objectives?: Array<Objective<HarnessVariantReport>>\n score?: (trace: RunTrace, request: HarnessRunRequest) => RunScore | Promise<RunScore>\n onResult?: (result: HarnessRunResult) => void | Promise<void>\n}\n\nexport const DEFAULT_HARNESS_OBJECTIVES: Array<Objective<HarnessVariantReport>> = [\n { name: 'aggregate', direction: 'maximize', value: (r) => r.aggregateMean },\n { name: 'pass_rate', direction: 'maximize', value: (r) => r.passRate },\n { name: 'cost', direction: 'minimize', value: (r) => r.costUsdMean },\n { name: 'wall', direction: 'minimize', value: (r) => r.wallSecondsMean },\n]\n\nexport async function runHarnessExperiment(\n config: HarnessExperimentConfig,\n): Promise<HarnessExperimentResult> {\n const jobs = buildJobs(config)\n const critic = new RunCritic({ weights: config.weights })\n const score = config.score ?? ((trace: RunTrace) => critic.scoreTrace(trace))\n const results = await mapLimit(jobs, config.parallelism ?? 1, async (request) => {\n const trace = await config.adapter.run(request)\n const runScore = await score(trace, request)\n const result: HarnessRunResult = {\n variant: request.variant,\n scenario: request.scenario,\n trialIndex: request.trialIndex,\n trace,\n score: runScore,\n aggregate: aggregateRunScore(runScore, config.weights),\n }\n await config.onResult?.(result)\n return result\n })\n return { results, selection: selectHarnessVariant(results, config.objectives) }\n}\n\nexport function selectHarnessVariant(\n results: HarnessRunResult[],\n objectives: Array<Objective<HarnessVariantReport>> = DEFAULT_HARNESS_OBJECTIVES,\n): HarnessSelection {\n const reports = summarizeHarnessResults(results)\n if (reports.length === 0) throw new Error('selectHarnessVariant: no results')\n const frontier = paretoFrontier(reports, objectives)\n const candidates = frontier.frontier.length ? frontier.frontier : reports\n const winner = [...candidates].sort((a, b) => b.aggregateMean - a.aggregateMean)[0]\n if (!winner) throw new Error('selectHarnessVariant: no winner')\n return { winner, frontier, reports }\n}\n\nexport function summarizeHarnessResults(results: HarnessRunResult[]): HarnessVariantReport[] {\n const byVariant = new Map<string, HarnessRunResult[]>()\n for (const result of results) {\n byVariant.set(result.variant.id, [...(byVariant.get(result.variant.id) ?? []), result])\n }\n return [...byVariant.values()]\n .map((runs) => {\n const variant = runs[0]?.variant\n if (!variant) throw new Error('summarizeHarnessResults: empty variant bucket')\n return {\n variant,\n runs,\n aggregateMean: mean(runs.map((r) => r.aggregate)),\n passRate: mean(runs.map((r) => r.score.success)),\n costUsdMean: mean(runs.map((r) => r.score.costUsd)),\n wallSecondsMean: mean(runs.map((r) => r.score.wallSeconds)),\n scoreMean: meanRunScore(runs.map((r) => r.score)),\n }\n })\n .sort((a, b) => b.aggregateMean - a.aggregateMean)\n}\n\nfunction buildJobs(config: HarnessExperimentConfig): HarnessRunRequest[] {\n if (config.variants.length === 0)\n throw new Error('runHarnessExperiment: at least one variant required')\n if (config.scenarios.length === 0)\n throw new Error('runHarnessExperiment: at least one scenario required')\n const trials = Math.max(1, Math.floor(config.trialsPerScenario ?? 1))\n const jobs: HarnessRunRequest[] = []\n for (const variant of config.variants) {\n for (const scenario of config.scenarios) {\n for (let trialIndex = 0; trialIndex < trials; trialIndex++) {\n jobs.push({ variant, scenario, trialIndex })\n }\n }\n }\n return jobs\n}\n\nasync function mapLimit<T, R>(\n items: T[],\n limit: number,\n fn: (item: T) => Promise<R>,\n): Promise<R[]> {\n const results: R[] = new Array(items.length)\n let next = 0\n const workerCount = Math.max(1, Math.min(Math.floor(limit), items.length))\n await Promise.all(\n Array.from({ length: workerCount }, async () => {\n while (next < items.length) {\n const index = next++\n const item = items[index]\n if (item === undefined) continue\n results[index] = await fn(item)\n }\n }),\n )\n return results\n}\n\nfunction mean(values: number[]): number {\n return values.length ? values.reduce((sum, value) => sum + value, 0) / values.length : 0\n}\n\nfunction meanRunScore(scores: RunScore[]): RunScore {\n return {\n success: mean(scores.map((s) => s.success)),\n goalProgress: mean(scores.map((s) => s.goalProgress)),\n repoGroundedness: mean(scores.map((s) => s.repoGroundedness)),\n driftPenalty: mean(scores.map((s) => s.driftPenalty)),\n toolUseQuality: mean(scores.map((s) => s.toolUseQuality)),\n patchQuality: mean(scores.map((s) => s.patchQuality)),\n testReality: mean(scores.map((s) => s.testReality)),\n finalGate: mean(scores.map((s) => s.finalGate)),\n reviewerBlockers: mean(scores.map((s) => s.reviewerBlockers)),\n costUsd: mean(scores.map((s) => s.costUsd)),\n wallSeconds: mean(scores.map((s) => s.wallSeconds)),\n notes: scores.flatMap((s) => s.notes ?? []),\n }\n}\n","import {\n type HarnessConfig,\n type SandboxDriver,\n SandboxHarness,\n type SandboxHarnessResult,\n SubprocessSandboxDriver,\n} from './sandbox-harness'\nimport { TraceEmitter } from './trace/emitter'\nimport { InMemoryTraceStore } from './trace/store'\n\nexport type SandboxJudgeKind = 'compiler' | 'test' | 'linter' | 'security'\n\nexport interface SandboxJudgeSpec {\n id: string\n kind: SandboxJudgeKind\n config: HarnessConfig\n}\n\nexport interface SandboxJudgeResult {\n id: string\n kind: SandboxJudgeKind\n passed: boolean\n score: number\n summary: string\n detail: SandboxHarnessResult\n}\n\nexport interface JudgeFleetOptions {\n driver?: SandboxDriver\n parallel?: boolean\n}\n\nexport class JudgeRunner {\n private readonly driver: SandboxDriver\n\n constructor(driver: SandboxDriver = new SubprocessSandboxDriver()) {\n this.driver = driver\n }\n\n async run(spec: SandboxJudgeSpec): Promise<SandboxJudgeResult> {\n const store = new InMemoryTraceStore()\n const emitter = new TraceEmitter(store, { runId: `judge-${spec.id}` })\n await emitter.startRun({\n scenarioId: spec.id,\n layer: 'meta',\n projectId: 'judge-runner',\n })\n const harness = new SandboxHarness(this.driver)\n const detail = await harness.run(spec.config, emitter)\n await emitter.endRun({ pass: detail.passed, score: detail.score, notes: `${spec.kind} judge` })\n return {\n id: spec.id,\n kind: spec.kind,\n passed: detail.passed,\n score: detail.score,\n summary: renderJudgeSummary(spec.kind, detail),\n detail,\n }\n }\n}\n\nexport async function runJudgeFleet(\n specs: SandboxJudgeSpec[],\n options: JudgeFleetOptions = {},\n): Promise<SandboxJudgeResult[]> {\n const runner = new JudgeRunner(options.driver)\n if (options.parallel === false) {\n const results: SandboxJudgeResult[] = []\n for (const spec of specs) results.push(await runner.run(spec))\n return results\n }\n return await Promise.all(specs.map((spec) => runner.run(spec)))\n}\n\nexport function compilerJudge(id: string, config: HarnessConfig): SandboxJudgeSpec {\n return { id, kind: 'compiler', config }\n}\n\nexport function testJudge(id: string, config: HarnessConfig): SandboxJudgeSpec {\n return { id, kind: 'test', config }\n}\n\nexport function linterJudge(id: string, config: HarnessConfig): SandboxJudgeSpec {\n return { id, kind: 'linter', config }\n}\n\nexport function securityJudge(id: string, config: HarnessConfig): SandboxJudgeSpec {\n return { id, kind: 'security', config }\n}\n\nfunction renderJudgeSummary(kind: SandboxJudgeKind, detail: SandboxHarnessResult): string {\n if (!detail.passed) return `${kind} judge failed`\n if (detail.test?.testsTotal)\n return `${kind} judge passed ${detail.test.testsPassed}/${detail.test.testsTotal} tests`\n return `${kind} judge passed`\n}\n","export interface PlaybookEntry {\n instruction: string\n rationale: string\n category?: string\n evidence?: string\n weight?: number\n sourceRunId?: string\n}\n\nexport interface Playbook {\n entries: PlaybookEntry[]\n}\n\nexport function distillPlaybook(\n entries: PlaybookEntry[],\n options: { maxEntries?: number } = {},\n): Playbook {\n const maxEntries = options.maxEntries ?? 12\n const byInstruction = new Map<string, PlaybookEntry>()\n\n for (const entry of entries) {\n const key = normalizeInstruction(entry.instruction)\n const existing = byInstruction.get(key)\n if (!existing || (entry.weight ?? 0) > (existing.weight ?? 0)) {\n byInstruction.set(key, { ...entry, instruction: canonicalInstruction(entry.instruction) })\n }\n }\n\n const distilled = [...byInstruction.values()]\n .sort((a, b) => (b.weight ?? 0) - (a.weight ?? 0))\n .slice(0, maxEntries)\n\n return { entries: distilled }\n}\n\nexport function renderPlaybookMarkdown(playbook: Playbook): string {\n const lines = ['# Playbook', '']\n for (const entry of playbook.entries) {\n lines.push(`- ${entry.instruction}`)\n lines.push(` Rationale: ${entry.rationale}`)\n if (entry.category) lines.push(` Category: ${entry.category}`)\n if (entry.evidence) lines.push(` Evidence: ${entry.evidence}`)\n if (entry.sourceRunId) lines.push(` Source run: ${entry.sourceRunId}`)\n lines.push('')\n }\n return `${lines.join('\\n').trim()}\\n`\n}\n\nfunction normalizeInstruction(value: string): string {\n return value.trim().toLowerCase().replace(/\\s+/g, ' ')\n}\n\nfunction canonicalInstruction(value: string): string {\n const normalized = value.trim().replace(/\\s+/g, ' ')\n return normalized.length === 0 ? normalized : normalized[0]!.toUpperCase() + normalized.slice(1)\n}\n","/**\n * Produced-state extraction — normalize a run's runtime event stream into the\n * typed `ProducedState` the completion oracle consumes.\n *\n * `ProducedState` answers \"what did the agent actually produce\" — vault\n * artifacts, proposals, tool calls. The runtime emits these as a stream of\n * events; this module is the single normalization point from that stream to\n * the shape `verifyCompletion` expects.\n *\n * Input is structurally typed (`RuntimeEventLike`) so this module does not\n * depend on agent-runtime — agent-runtime's `RuntimeStreamEvent` satisfies it\n * structurally. The `content` on `ArtifactEventLike` and the whole\n * `proposal_created` variant are the runtime-side enrichments this contract\n * requires; the runtime emits them, this module consumes them.\n */\n\nimport type { Artifact } from './artifact-validator'\nimport type { ProducedProposal, ProducedState } from './completion-verifier'\n\n/** A tool the agent invoked. */\nexport interface ToolCallEventLike {\n type: 'tool_call'\n toolName: string\n}\n\n/**\n * An artifact the agent produced. `content` is the enriched field — the\n * runtime's base `artifact` event carries only metadata; the completion\n * oracle needs the body to verify the deliverable, so the runtime emits it.\n */\nexport interface ArtifactEventLike {\n type: 'artifact'\n artifactId: string\n name?: string\n mimeType?: string\n uri?: string\n content?: string\n}\n\n/** A proposal / filing the agent created. */\nexport interface ProposalEventLike {\n type: 'proposal_created'\n proposalId: string\n title: string\n status?: 'pending' | 'approved' | 'rejected'\n}\n\n/**\n * The subset of runtime stream events `extractProducedState` consumes.\n * agent-runtime's full `RuntimeStreamEvent` union satisfies this structurally;\n * the `{ type: string }` catch-all keeps the input permissive so callers can\n * pass the whole unfiltered telemetry stream — unrecognized events are skipped.\n */\nexport type RuntimeEventLike =\n | ToolCallEventLike\n | ArtifactEventLike\n | ProposalEventLike\n | { type: string }\n\nfunction artifactKind(mimeType: string | undefined): string {\n if (!mimeType) return 'file'\n if (mimeType.includes('json')) return 'json'\n if (mimeType.startsWith('text/')) return 'text'\n return 'file'\n}\n\n/**\n * Normalize a run's runtime event stream into `ProducedState`.\n *\n * Pure and total — unrecognized event types are skipped. `toolCalls` is\n * deduplicated by name in first-seen order (completion cares about a tool's\n * presence, not its call count). An artifact with neither a name nor a uri\n * still yields an entry keyed by its `artifactId` so it is never silently\n * dropped; an artifact with no `content` yields empty content, which the\n * completion oracle's structural check then rejects on its own.\n */\nexport function extractProducedState(events: readonly RuntimeEventLike[]): ProducedState {\n const artifacts: Artifact[] = []\n const proposals: ProducedProposal[] = []\n const toolCalls: string[] = []\n const seenTools = new Set<string>()\n\n for (const ev of events) {\n if (ev.type === 'tool_call') {\n const name = (ev as ToolCallEventLike).toolName\n if (name && !seenTools.has(name)) {\n seenTools.add(name)\n toolCalls.push(name)\n }\n } else if (ev.type === 'artifact') {\n const a = ev as ArtifactEventLike\n artifacts.push({\n kind: artifactKind(a.mimeType),\n path: a.name ?? a.uri ?? a.artifactId,\n content: a.content ?? '',\n })\n } else if (ev.type === 'proposal_created') {\n const p = ev as ProposalEventLike\n proposals.push({ id: p.proposalId, title: p.title, status: p.status ?? 'pending' })\n }\n }\n\n return { artifacts, proposals, toolCalls }\n}\n","/**\n * Versioned prompt registry.\n *\n * Every prompt used in an eval run is registered with an explicit version.\n * Reports include the content hash so A/B compares are rigorous: if the\n * hash changes between two reports, the prompt actually changed; if it\n * matches, the variance is elsewhere.\n *\n * Hash is SHA-256(content), truncated to 12 hex chars for readability.\n * Uses the Web Crypto API (works in Workers, Node 22+, browsers).\n */\n\nexport interface PromptHandle {\n /** Stable human-readable id, e.g. 'browser.system' */\n id: string\n /** Caller-chosen version string, e.g. 'v3' or '2026-04-20' */\n version: string\n /** SHA-256 of content, 12-hex-char prefix */\n hash: string\n /** Full prompt body */\n content: string\n}\n\nexport class PromptRegistry {\n private readonly entries = new Map<string, PromptHandle>() // `${id}@${version}` → handle\n\n /**\n * Register a prompt. Re-registering the same id+version with DIFFERENT\n * content throws — versions are immutable. Re-registering with the SAME\n * content is a no-op (idempotent).\n */\n async register(id: string, version: string, content: string): Promise<PromptHandle> {\n validateId(id)\n validateVersion(version)\n\n const key = makeKey(id, version)\n const hash = await hashContent(content)\n const existing = this.entries.get(key)\n if (existing) {\n if (existing.hash !== hash) {\n throw new Error(\n `Prompt ${key} already registered with a different hash (${existing.hash} vs ${hash}). Bump the version.`,\n )\n }\n return existing\n }\n const handle: PromptHandle = { id, version, hash, content }\n this.entries.set(key, handle)\n return handle\n }\n\n /** Look up a registered prompt. Throws if unknown — no implicit defaults. */\n get(id: string, version: string): PromptHandle {\n const key = makeKey(id, version)\n const handle = this.entries.get(key)\n if (!handle) throw new Error(`Prompt ${key} not registered`)\n return handle\n }\n\n /** Return all versions of an id, newest-first (lex-descending on version). */\n listVersions(id: string): PromptHandle[] {\n return [...this.entries.values()]\n .filter((h) => h.id === id)\n .sort((a, b) => b.version.localeCompare(a.version))\n }\n\n /** Snapshot the whole registry — useful for including in reports. */\n list(): PromptHandle[] {\n return [...this.entries.values()]\n }\n\n /** Verify a hash against registered content. Returns null if not found. */\n verifyHash(id: string, version: string, expectedHash: string): boolean | null {\n const handle = this.entries.get(makeKey(id, version))\n if (!handle) return null\n return handle.hash === expectedHash\n }\n}\n\n/** SHA-256(content) → first 12 hex chars. Stable across runtimes. */\nexport async function hashContent(content: string): Promise<string> {\n const bytes = new TextEncoder().encode(content)\n const digest = await crypto.subtle.digest('SHA-256', bytes)\n const full = Array.from(new Uint8Array(digest))\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('')\n return full.slice(0, 12)\n}\n\nfunction makeKey(id: string, version: string): string {\n return `${id}@${version}`\n}\n\nconst ID_RE = /^[a-z][a-z0-9._-]*$/i\nfunction validateId(id: string): void {\n if (!ID_RE.test(id)) {\n throw new Error(`Invalid prompt id \"${id}\": must match ${ID_RE}`)\n }\n}\n\nfunction validateVersion(version: string): void {\n if (!version || version.length > 64) {\n throw new Error(`Invalid version \"${version}\": must be 1–64 chars`)\n }\n}\n","export interface SteeringRolePrompt {\n system?: string\n append?: string\n}\n\nexport interface SteeringBundle {\n id: string\n coderPrompt?: string\n continuePrompt?: string\n reviewerPrompts?: Record<string, string>\n skills?: string[]\n rolePrompts?: Record<string, SteeringRolePrompt>\n metadata?: Record<string, unknown>\n}\n\nexport interface SteeringDelta {\n coderPrompt?: string\n continuePrompt?: string\n reviewerPrompts?: Record<string, string>\n skills?: string[]\n rolePrompts?: Record<string, SteeringRolePrompt>\n metadata?: Record<string, unknown>\n}\n\nexport function mergeSteeringBundle(base: SteeringBundle, delta: SteeringDelta): SteeringBundle {\n return {\n ...base,\n ...(delta.coderPrompt !== undefined ? { coderPrompt: delta.coderPrompt } : {}),\n ...(delta.continuePrompt !== undefined ? { continuePrompt: delta.continuePrompt } : {}),\n reviewerPrompts: {\n ...(base.reviewerPrompts ?? {}),\n ...(delta.reviewerPrompts ?? {}),\n },\n skills: delta.skills ?? base.skills,\n rolePrompts: {\n ...(base.rolePrompts ?? {}),\n ...(delta.rolePrompts ?? {}),\n },\n metadata: {\n ...(base.metadata ?? {}),\n ...(delta.metadata ?? {}),\n },\n }\n}\n\nexport function renderSteeringText(bundle: SteeringBundle): string {\n const lines: string[] = [`bundle:${bundle.id}`]\n if (bundle.coderPrompt) lines.push(`coder:${bundle.coderPrompt}`)\n if (bundle.continuePrompt) lines.push(`continue:${bundle.continuePrompt}`)\n const reviewers = Object.entries(bundle.reviewerPrompts ?? {}).sort(([a], [b]) =>\n a.localeCompare(b),\n )\n for (const [name, prompt] of reviewers) lines.push(`reviewer:${name}:${prompt}`)\n const skills = [...(bundle.skills ?? [])].sort()\n if (skills.length) lines.push(`skills:${skills.join(',')}`)\n return lines.join('\\n')\n}\n","import { aggregateRunScore, type RunScore, type RunScoreWeights } from './run-score'\nimport type { SteeringBundle } from './steering'\n\nexport type SteeringOptimizerBackend = 'pairwise' | 'ax-gepa'\n\nexport interface SteeringOptimizationRow {\n variantId: string\n scenarioId: string\n bundle: SteeringBundle\n score: RunScore\n metadata?: Record<string, unknown>\n}\n\nexport interface SteeringOptimizationSelector {\n backend: SteeringOptimizerBackend\n signature?: string\n labels?: string[]\n rationale?: string\n}\n\nexport interface SteeringOptimizationResult {\n backend: SteeringOptimizerBackend\n recommendedVariantId: string\n rationale: string\n rankings: Array<{ variantId: string; mean: number; runs: number }>\n selector?: SteeringOptimizationSelector\n skipped?: boolean\n}\n\nexport interface SteeringOptimizerConfig {\n weights?: Partial<RunScoreWeights>\n}\n\nexport interface AxSteeringOptimizerConfig extends SteeringOptimizerConfig {\n provider: 'openai' | 'anthropic'\n apiKey: string\n model: string\n teacherModel?: string\n minRows?: number\n}\n\ntype AxServiceFactory = (config: {\n name: 'openai' | 'anthropic'\n apiKey: string\n config: { model: string }\n}) => unknown\n\ninterface AxSelectorProgram {\n applyOptimization(compiled: unknown): void\n}\n\ntype AxFactory = (signature: string, options: { description: string }) => AxSelectorProgram\n\ninterface AxGepaCompileResult {\n optimizedProgram?: unknown\n bestScore?: number\n}\n\ninterface AxGepaInstance {\n compile(\n selector: AxSelectorProgram,\n train: ScenarioWinner[],\n metric: (input: { prediction?: { variantId?: string }; example?: ScenarioWinner }) => number,\n options: { validationExamples: ScenarioWinner[]; maxMetricCalls: number },\n ): Promise<AxGepaCompileResult>\n}\n\ninterface AxGepaConstructor {\n new (config: {\n studentAI: unknown\n teacherAI: unknown\n numTrials: number\n minibatch: boolean\n minibatchSize: number\n earlyStoppingTrials: number\n sampleCount: number\n }): AxGepaInstance\n}\n\ninterface AxModule {\n ai: AxServiceFactory\n ax: AxFactory\n AxGEPA: AxGepaConstructor\n}\n\ninterface ScenarioWinner {\n task: string\n split: string\n seedPreview: string\n variantId: string\n}\n\nexport class PairwiseSteeringOptimizer {\n optimize(\n rows: SteeringOptimizationRow[],\n config: SteeringOptimizerConfig = {},\n ): SteeringOptimizationResult {\n const ranked = rankRows(rows, config.weights)\n if (!ranked.length) throw new Error('no steering optimization rows')\n return {\n backend: 'pairwise',\n recommendedVariantId: ranked[0]!.variantId,\n rationale: `Highest observed mean aggregate across ${rows.length} scored run(s).`,\n rankings: ranked,\n }\n }\n}\n\nexport class AxGepaSteeringOptimizer {\n constructor(private readonly config: AxSteeringOptimizerConfig) {}\n\n async optimize(rows: SteeringOptimizationRow[]): Promise<SteeringOptimizationResult> {\n const fallback = new PairwiseSteeringOptimizer().optimize(rows, this.config)\n const minRows = this.config.minRows ?? 6\n const variantIds = [...new Set(rows.map((row) => row.variantId))]\n const byScenario = collapseScenarioWinners(rows, this.config.weights)\n if (variantIds.length < 2 || byScenario.length < minRows) {\n return {\n ...fallback,\n backend: 'ax-gepa',\n skipped: true,\n rationale: `AxGEPA skipped: need >=2 variants and >=${minRows} scenario winners, got ${variantIds.length} variant(s) and ${byScenario.length} scenario winner(s).`,\n }\n }\n\n let axLib: AxModule\n try {\n axLib = (await import('@ax-llm/ax')) as AxModule\n } catch {\n return {\n ...fallback,\n backend: 'ax-gepa',\n skipped: true,\n rationale: 'AxGEPA unavailable: install @ax-llm/ax to enable selector optimization.',\n }\n }\n\n const { ai, ax, AxGEPA } = axLib\n const signature = `task:string, split:string, seedPreview:string -> variantId:class \"${variantIds.join(', ')}\", rationale:string`\n const selector = ax(signature, {\n description: 'Choose the best steering bundle variant for an autopilot task.',\n })\n const splitIndex = Math.max(1, Math.floor(byScenario.length * 0.8))\n const train = byScenario.slice(0, splitIndex)\n const validation = byScenario.slice(splitIndex)\n if (!validation.length) {\n return {\n ...fallback,\n backend: 'ax-gepa',\n skipped: true,\n rationale: 'AxGEPA skipped: no validation examples after split.',\n }\n }\n\n const optimizer = new AxGEPA({\n studentAI: createAxService(ai, this.config.provider, this.config.apiKey, this.config.model),\n teacherAI: createAxService(\n ai,\n this.config.provider,\n this.config.apiKey,\n this.config.teacherModel ?? this.config.model,\n ),\n numTrials: 8,\n minibatch: true,\n minibatchSize: 4,\n earlyStoppingTrials: 3,\n sampleCount: 1,\n })\n\n const compiled = await optimizer.compile(\n selector,\n train,\n ({ prediction, example }) => (prediction?.variantId === example?.variantId ? 1 : 0),\n {\n validationExamples: validation,\n maxMetricCalls: 64,\n },\n )\n if (compiled.optimizedProgram !== undefined) {\n selector.applyOptimization(compiled.optimizedProgram)\n }\n\n return {\n ...fallback,\n backend: 'ax-gepa',\n rationale: `AxGEPA trained a variant selector from ${byScenario.length} scored scenario winner(s); default winner remains ${fallback.recommendedVariantId}.`,\n selector: {\n backend: 'ax-gepa',\n signature,\n labels: variantIds,\n rationale: compiled.bestScore !== undefined ? `bestScore=${compiled.bestScore}` : undefined,\n },\n }\n }\n}\n\nfunction rankRows(rows: SteeringOptimizationRow[], weights?: Partial<RunScoreWeights>) {\n const buckets = new Map<string, number[]>()\n for (const row of rows) {\n const values = buckets.get(row.variantId) ?? []\n values.push(aggregateRunScore(row.score, weights))\n buckets.set(row.variantId, values)\n }\n return [...buckets.entries()]\n .map(([variantId, values]) => ({\n variantId,\n mean: values.reduce((sum, value) => sum + value, 0) / values.length,\n runs: values.length,\n }))\n .sort((a, b) => b.mean - a.mean)\n}\n\nfunction collapseScenarioWinners(\n rows: SteeringOptimizationRow[],\n weights?: Partial<RunScoreWeights>,\n) {\n const byScenario = new Map<string, SteeringOptimizationRow[]>()\n for (const row of rows) {\n const bucket = byScenario.get(row.scenarioId) ?? []\n bucket.push(row)\n byScenario.set(row.scenarioId, bucket)\n }\n return [...byScenario.entries()].map(([scenarioId, scenarioRows]) => {\n const best = scenarioRows\n .map((row) => ({ row, aggregate: aggregateRunScore(row.score, weights) }))\n .sort((a, b) => b.aggregate - a.aggregate)[0]!\n return {\n task: String(best.row.metadata?.task ?? best.row.metadata?.seed_preview ?? scenarioId),\n split: String(best.row.metadata?.split ?? 'train'),\n seedPreview: String(best.row.metadata?.seed_preview ?? ''),\n variantId: best.row.variantId,\n }\n })\n}\n\nfunction createAxService(\n aiFactory: AxServiceFactory,\n provider: 'openai' | 'anthropic',\n apiKey: string,\n model: string,\n) {\n return aiFactory({\n name: provider,\n apiKey,\n config: { model },\n })\n}\n","/**\n * Workspace inspector — score the persisted state of an agent after a run.\n *\n * Many evals don't ask \"did the response say the right thing\" but \"did the\n * agent put the right rows in the DB / files in the vault / entities on the\n * canvas\". This is the primitive for that.\n *\n * Implementations read from D1, KV, filesystem, or any store — the interface\n * is deliberately small so consumers plug in their own backends.\n */\n\nexport interface WorkspaceSnapshot {\n /** Vault files: logical path → content */\n files: Record<string, string>\n /** DB rows: table name → array of rows (post-validation) */\n rows: Record<string, Array<Record<string, unknown>>>\n /** KV entries: key → value (scoped to whatever prefix the inspector chose) */\n kv: Record<string, string>\n /** Free-form blob metadata: for large binaries the inspector stores summary, not bytes */\n blobs?: Record<string, { size: number; hash?: string; mimeType?: string }>\n}\n\nexport interface InspectorContext {\n /** Workspace / agent / thread id — whatever the backend uses to scope the snapshot */\n scopeId: string\n /** Optional scenario id — allows scenario-specific snapshot shaping */\n scenarioId?: string\n}\n\nexport interface WorkspaceInspector {\n name: string\n snapshot(context: InspectorContext): Promise<WorkspaceSnapshot>\n}\n\n// ---------------------------------------------------------------------------\n// In-memory inspector — useful for tests, not for production\n// ---------------------------------------------------------------------------\n\nexport class InMemoryWorkspaceInspector implements WorkspaceInspector {\n readonly name = 'in-memory'\n private readonly snapshots = new Map<string, WorkspaceSnapshot>()\n\n set(scopeId: string, snapshot: WorkspaceSnapshot): void {\n this.snapshots.set(scopeId, snapshot)\n }\n\n async snapshot(context: InspectorContext): Promise<WorkspaceSnapshot> {\n return this.snapshots.get(context.scopeId) ?? { files: {}, rows: {}, kv: {} }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Snapshot-level assertions\n// ---------------------------------------------------------------------------\n\nexport interface WorkspaceAssertion {\n name: string\n description?: string\n check(snapshot: WorkspaceSnapshot): WorkspaceAssertionResult\n}\n\nexport interface WorkspaceAssertionResult {\n pass: boolean\n /** 0..1 — partial credit for assertions that admit it */\n score: number\n detail?: string\n}\n\nexport function fileExists(path: string): WorkspaceAssertion {\n return {\n name: `file_exists:${path}`,\n check(snapshot) {\n const pass = path in snapshot.files\n return {\n pass,\n score: pass ? 1 : 0,\n detail: pass ? undefined : `No file at ${path}`,\n }\n },\n }\n}\n\nexport function fileContains(path: string, needle: string): WorkspaceAssertion {\n return {\n name: `file_contains:${path}:${needle}`,\n check(snapshot) {\n const content = snapshot.files[path]\n if (content === undefined) {\n return { pass: false, score: 0, detail: `File ${path} missing` }\n }\n const pass = content.includes(needle)\n return {\n pass,\n score: pass ? 1 : 0,\n detail: pass ? undefined : `File ${path} missing substring \"${needle}\"`,\n }\n },\n }\n}\n\nexport function rowCount(table: string, min: number, max?: number): WorkspaceAssertion {\n return {\n name: `row_count:${table}:[${min},${max ?? '∞'}]`,\n check(snapshot) {\n const rows = snapshot.rows[table] ?? []\n const count = rows.length\n const upper = max ?? Infinity\n const pass = count >= min && count <= upper\n const score = pass ? 1 : count < min ? Math.max(0, count / min) : Math.max(0, upper / count)\n return {\n pass,\n score,\n detail: pass\n ? undefined\n : `Table ${table} has ${count} rows, expected [${min}, ${max ?? '∞'}]`,\n }\n },\n }\n}\n\nexport function rowWhere<T extends Record<string, unknown>>(\n table: string,\n predicate: (row: T) => boolean,\n options?: { min?: number },\n): WorkspaceAssertion {\n const min = options?.min ?? 1\n return {\n name: `row_where:${table}`,\n check(snapshot) {\n const rows = (snapshot.rows[table] ?? []) as T[]\n const matching = rows.filter(predicate).length\n const pass = matching >= min\n return {\n pass,\n score: pass ? 1 : Math.max(0, matching / min),\n detail: pass\n ? undefined\n : `Table ${table} has ${matching} matching rows, expected ≥ ${min}`,\n }\n },\n }\n}\n\n/** Run many assertions; return aggregate pass + mean score + per-assertion details. */\nexport function runAssertions(\n snapshot: WorkspaceSnapshot,\n assertions: WorkspaceAssertion[],\n): {\n pass: boolean\n score: number\n results: Array<{ assertion: string; result: WorkspaceAssertionResult }>\n} {\n const results = assertions.map((a) => ({ assertion: a.name, result: a.check(snapshot) }))\n const pass = results.every((r) => r.result.pass)\n const score = results.length\n ? results.reduce((acc, r) => acc + r.result.score, 0) / results.length\n : 1\n return { pass, score, results }\n}\n","/**\n * BudgetGuard — enforces token / wall-clock / call / $ caps, records\n * a ledger entry on every decrement, emits `budget_breach` + throws\n * `BudgetBreachError` when a cap is hit.\n *\n * Wraps a TraceEmitter. The emitter persists ledger entries + breach\n * events so the classifier, pipelines, and reports can all read\n * budget state from the trace corpus — no separate accounting.\n */\n\nimport { AgentEvalError } from './errors'\nimport type { TraceEmitter } from './trace/emitter'\nimport type { BudgetSpec } from './trace/schema'\n\nexport class BudgetBreachError extends AgentEvalError {\n constructor(\n public dimension: keyof BudgetSpec,\n public limit: number,\n public attempted: number,\n ) {\n super('verification', `budget breach on ${dimension}: attempted ${attempted} vs limit ${limit}`)\n }\n}\n\nexport class BudgetGuard {\n private consumed: Record<keyof BudgetSpec, number> = { tokens: 0, wallMs: 0, calls: 0, usd: 0 }\n private emitter: TraceEmitter\n private budget: BudgetSpec\n private startedAt: number\n\n constructor(emitter: TraceEmitter, budget: BudgetSpec, now: () => number = () => Date.now()) {\n this.emitter = emitter\n this.budget = budget\n this.startedAt = now()\n }\n\n /** Record consumption. Throws `BudgetBreachError` if any dimension exceeds its cap. */\n async charge(delta: Partial<Record<keyof BudgetSpec, number>>, spanId?: string): Promise<void> {\n for (const [dim, value] of Object.entries(delta) as Array<[keyof BudgetSpec, number]>) {\n if (!Number.isFinite(value) || value < 0) {\n throw new Error(`BudgetGuard.charge: non-finite or negative ${dim}=${value}`)\n }\n this.consumed[dim] += value\n const limit = this.budget[dim]\n const consumed = this.consumed[dim]\n const remaining = limit === undefined ? Infinity : limit - consumed\n const breached = limit !== undefined && consumed > limit\n if (limit !== undefined) {\n await this.emitter.recordBudget({\n dimension: dim,\n limit,\n consumed,\n remaining,\n breached,\n spanId,\n })\n }\n if (breached) {\n throw new BudgetBreachError(dim, limit!, consumed)\n }\n }\n }\n\n /** Convenience: advance wall-clock budget based on elapsed wall time. */\n async tickWall(nowMs: number, spanId?: string): Promise<void> {\n const elapsed = nowMs - this.startedAt\n const already = this.consumed.wallMs\n const delta = Math.max(0, elapsed - already)\n if (delta > 0) await this.charge({ wallMs: delta }, spanId)\n }\n\n get state(): Record<keyof BudgetSpec, number> {\n return { ...this.consumed }\n }\n}\n","/**\n * Cost tracker — token + USD accounting per scenario and per run.\n *\n * Adapted from generic usage-event accounting. Every\n * optimizer needs to know \"is the quality gain worth the cost delta?\",\n * and every dashboard needs dollars-per-completed-task. MODEL_PRICING\n * from metrics.ts stays authoritative for estimate math; this module\n * adds the aggregation + per-scenario roll-up that was duplicated\n * across 4 verticals.\n */\n\nimport { estimateCost } from './metrics'\n\nexport interface TokenSpec {\n inputTokens: number\n outputTokens: number\n cachedTokens?: number\n reasoningTokens?: number\n}\n\nexport interface CostEntry extends TokenSpec {\n scenarioId: string\n model: string\n /** Override estimate with an observed cost (e.g. from provider response). */\n actualCostUsd?: number\n timestamp: number\n /** Free-form tags (variant id, round #, etc.). */\n tags?: Record<string, string>\n}\n\nexport interface ScenarioCost {\n scenarioId: string\n entries: CostEntry[]\n totalInputTokens: number\n totalOutputTokens: number\n totalCachedTokens: number\n totalCostUsd: number\n /** Pass flag — set by consumer via markOutcome; used for cost-per-completed-task. */\n completed?: boolean\n}\n\nexport class CostTracker {\n private byScenario = new Map<string, ScenarioCost>()\n\n record(entry: Omit<CostEntry, 'timestamp'> & { timestamp?: number }): CostEntry {\n const full: CostEntry = { timestamp: entry.timestamp ?? Date.now(), ...entry }\n assertNonNegative(full.inputTokens, 'inputTokens')\n assertNonNegative(full.outputTokens, 'outputTokens')\n let bucket = this.byScenario.get(full.scenarioId)\n if (!bucket) {\n bucket = {\n scenarioId: full.scenarioId,\n entries: [],\n totalInputTokens: 0,\n totalOutputTokens: 0,\n totalCachedTokens: 0,\n totalCostUsd: 0,\n }\n this.byScenario.set(full.scenarioId, bucket)\n }\n bucket.entries.push(full)\n bucket.totalInputTokens += full.inputTokens\n bucket.totalOutputTokens += full.outputTokens\n bucket.totalCachedTokens += full.cachedTokens ?? 0\n bucket.totalCostUsd += costFor(full)\n return full\n }\n\n markOutcome(scenarioId: string, completed: boolean): void {\n const bucket = this.byScenario.get(scenarioId)\n if (!bucket) throw new Error(`CostTracker.markOutcome: unknown scenario \"${scenarioId}\"`)\n bucket.completed = completed\n }\n\n /**\n * Convenience: record + markOutcome in one call from a\n * `{ usage, verdict }`-shaped response (starter-foundry's\n * `invokeMetaJudge` returns this shape; consumers that wrap any\n * judge/critic can follow the same convention).\n *\n * `usage.model` must be present in `MODEL_PRICING` for cost math to\n * populate; otherwise totalCostUsd stays at 0 for the entry but\n * tokens still aggregate.\n */\n recordVerdict(\n verdict: {\n usage?: {\n inputTokens: number\n outputTokens: number\n model: string\n cachedTokens?: number\n reasoningTokens?: number\n }\n verdict?: 'pass' | 'fail' | 'borderline' | string\n },\n scenarioId: string,\n tags?: Record<string, string>,\n ): CostEntry | null {\n if (!verdict.usage) return null\n const entry = this.record({\n scenarioId,\n model: verdict.usage.model,\n inputTokens: verdict.usage.inputTokens,\n outputTokens: verdict.usage.outputTokens,\n cachedTokens: verdict.usage.cachedTokens,\n reasoningTokens: verdict.usage.reasoningTokens,\n tags,\n })\n this.markOutcome(scenarioId, verdict.verdict === 'pass')\n return entry\n }\n\n get(scenarioId: string): ScenarioCost | undefined {\n return this.byScenario.get(scenarioId)\n }\n\n list(): ScenarioCost[] {\n return [...this.byScenario.values()]\n }\n\n summary(): CostSummary {\n const scenarios = this.list()\n const completed = scenarios.filter((s) => s.completed === true)\n const totalCost = scenarios.reduce((a, s) => a + s.totalCostUsd, 0)\n const totalInput = scenarios.reduce((a, s) => a + s.totalInputTokens, 0)\n const totalOutput = scenarios.reduce((a, s) => a + s.totalOutputTokens, 0)\n const totalCompletedCost = completed.reduce((a, s) => a + s.totalCostUsd, 0)\n return {\n scenarioCount: scenarios.length,\n completedCount: completed.length,\n totalInputTokens: totalInput,\n totalOutputTokens: totalOutput,\n totalCostUsd: totalCost,\n avgCostPerScenarioUsd: scenarios.length ? totalCost / scenarios.length : 0,\n costPerCompletedTaskUsd: completed.length ? totalCompletedCost / completed.length : null,\n }\n }\n}\n\nexport interface CostSummary {\n scenarioCount: number\n completedCount: number\n totalInputTokens: number\n totalOutputTokens: number\n totalCostUsd: number\n avgCostPerScenarioUsd: number\n /** Total USD / completed scenarios — null when nothing completed. */\n costPerCompletedTaskUsd: number | null\n}\n\nfunction costFor(entry: CostEntry): number {\n if (typeof entry.actualCostUsd === 'number' && Number.isFinite(entry.actualCostUsd)) {\n return entry.actualCostUsd\n }\n return estimateCost(entry.inputTokens, entry.outputTokens, entry.model)\n}\n\nfunction assertNonNegative(n: number, name: string): void {\n if (!Number.isFinite(n) || n < 0) {\n throw new Error(`CostTracker: ${name} must be a non-negative finite number, got ${n}`)\n }\n}\n","/**\n * muffled-gate-scanner — test helper that greps consumer source for\n * gate + measurement anti-patterns and fails with file:line locations.\n *\n * Named pattern lives at starter-foundry's `.evolve/patterns/muffled-gate.md`;\n * same shape applies to every consumer (a gate that should fail loud\n * returns silent success; a metric that should emit a real number\n * reports noise/empty).\n *\n * Usage (in a consumer project's test file):\n *\n * import { scanForMuffledGates, DEFAULT_FINDERS } from '@tangle-network/agent-eval'\n *\n * test('no muffled gates in eval surface', () => {\n * const findings = scanForMuffledGates({\n * repoRoot: process.cwd(),\n * scanFiles: ['src/eval/scaffold.ts', 'scripts/promote.mjs'],\n * finders: DEFAULT_FINDERS,\n * })\n * if (findings.length) assert.fail(formatFindings(findings))\n * })\n *\n * Customize by passing your own `finders` — each finder is\n * `(file, text) => Finding[]` and runs per-file.\n *\n * Escape hatch: any line containing `muffle-ok:` is excluded from all\n * finders, letting consumers opt a legitimate fallback out explicitly.\n */\n\nimport { existsSync, readdirSync, readFileSync, statSync } from 'node:fs'\nimport { join } from 'node:path'\n\nexport interface MuffledFinding {\n file: string\n line: number\n lineText: string\n pattern: string\n}\n\nexport type MuffledFinder = (file: string, text: string) => MuffledFinding[]\n\nexport interface ScanOptions {\n /** Absolute path to the repo root. */\n repoRoot: string\n /** Explicit file list (paths relative to repoRoot) for context-specific finders. */\n scanFiles: string[]\n /**\n * Auto-derived scan: walk these dirs for files matching importGlob + the\n * string `importsContain` and run the universal finders on them. Pattern\n * from starter-foundry H4 (research/decisions/001) — catches new files\n * with agent-eval import that would otherwise escape context-specific\n * scan lists.\n */\n autoDerive?: {\n roots: string[] // e.g. ['src', 'scripts']\n extensions: RegExp // e.g. /\\.(ts|mjs|js)$/\n importsContain: string // e.g. '@tangle-network/agent-eval'\n universalFinders: MuffledFinder[]\n }\n /** Per-file finders (context-specific patterns). */\n finders: MuffledFinder[]\n}\n\n/**\n * Strip line comments + block-comment continuation lines from a single line\n * so finders don't match prose about the pattern.\n */\nfunction codeOf(line: string): string {\n return line.replace(/\\/\\/.*$/, '').replace(/^\\s*\\*.*$/, '')\n}\n\n/** Skip if the line carries the `muffle-ok:` escape hatch. */\nfunction isMuffleOk(line: string): boolean {\n return line.includes('muffle-ok:')\n}\n\n/**\n * Default finder: `command || true` in a testCommand/setupCommand/cmd/command\n * string. Swallows exit codes.\n */\nexport const findFallbackToPass: MuffledFinder = (file, text) => {\n const out: MuffledFinding[] = []\n const lines = text.split('\\n')\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i]!\n if (isMuffleOk(line)) continue\n const code = codeOf(line)\n if (!code.trim()) continue\n if (/\\|\\| true/.test(code) && /(testCommand|setupCommand|cmd|command)/.test(code)) {\n out.push({\n file,\n line: i + 1,\n lineText: line.trim(),\n pattern: 'fallback-to-pass (|| true in command string)',\n })\n }\n }\n return out\n}\n\n/**\n * `testCommand: 'true'` literal silent-pass — an unknown-language dispatch\n * arm that returns a no-op instead of throwing.\n */\nexport const findLiteralTruePass: MuffledFinder = (file, text) => {\n const out: MuffledFinding[] = []\n const lines = text.split('\\n')\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i]!\n if (isMuffleOk(line)) continue\n const code = codeOf(line)\n if (!code.trim()) continue\n if (/testCommand\\s*:\\s*['\"]true['\"]/.test(code)) {\n out.push({\n file,\n line: i + 1,\n lineText: line.trim(),\n pattern: 'literal-true-pass (testCommand: \"true\")',\n })\n }\n }\n return out\n}\n\n/**\n * `new SubprocessSandboxDriver({ cwd: ... })` — constructor arg silently\n * dropped in agent-eval <0.7.1. 0.7.1+ honors as fallback, but the form\n * still invites confusion; prefer `new SubprocessSandboxDriver()` with\n * cwd in the per-call HarnessConfig.\n */\nexport const findConstructorCwdDropped: MuffledFinder = (file, text) => {\n const out: MuffledFinding[] = []\n const lines = text.split('\\n')\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i]!\n if (isMuffleOk(line)) continue\n const code = codeOf(line)\n if (!code.trim()) continue\n if (/new\\s+SubprocessSandboxDriver\\s*\\(\\s*\\{[^}]*cwd\\s*:/.test(code)) {\n out.push({\n file,\n line: i + 1,\n lineText: line.trim(),\n pattern:\n 'construct-vs-call cwd dropped (driver.exec reads config.cwd, not constructor.cwd)',\n })\n }\n }\n return out\n}\n\n/**\n * `if (!expected) return true` — matcher auto-passes when ground truth is\n * absent. Inflates accuracy metrics for scenarios without expectations.\n */\nexport const findAutoMatchNoExpectation: MuffledFinder = (file, text) => {\n const out: MuffledFinding[] = []\n const lines = text.split('\\n')\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i]!\n if (isMuffleOk(line)) continue\n const code = codeOf(line)\n if (!code.trim()) continue\n if (/if\\s*\\(\\s*!expected\\s*\\)\\s*return\\s+true/.test(code)) {\n out.push({\n file,\n line: i + 1,\n lineText: line.trim(),\n pattern: 'auto-match-no-expectation (if (!expected) return true)',\n })\n }\n }\n return out\n}\n\n/**\n * `if (p.skipped) return true` — skip-counts-as-pass in quality scorers.\n * Use three-valued `true | false | 'skipped'` return + explicit partial\n * credit instead.\n */\nexport const findSkipCountsAsPass: MuffledFinder = (file, text) => {\n const out: MuffledFinding[] = []\n const lines = text.split('\\n')\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i]!\n if (isMuffleOk(line)) continue\n const code = codeOf(line)\n if (!code.trim()) continue\n if (/if\\s*\\(\\s*\\w+\\.skipped\\s*\\)\\s*return\\s+true/.test(code)) {\n out.push({\n file,\n line: i + 1,\n lineText: line.trim(),\n pattern: 'skip-counts-as-pass (if (.skipped) return true)',\n })\n }\n }\n return out\n}\n\n/**\n * The canonical default bundle. Callers can import these individually,\n * replace them, or append custom finders for project-specific patterns.\n */\nexport const DEFAULT_FINDERS: MuffledFinder[] = [\n findFallbackToPass,\n findLiteralTruePass,\n findAutoMatchNoExpectation,\n findSkipCountsAsPass,\n]\n\n/** Finders that should run on EVERY file with the target import, not just SCAN_FILES. */\nexport const UNIVERSAL_FINDERS: MuffledFinder[] = [findConstructorCwdDropped]\n\n/**\n * Walk `roots` under `repoRoot` and return file paths (relative to repoRoot)\n * whose contents include `importsContain`.\n */\nfunction autoDeriveImporters(\n repoRoot: string,\n roots: string[],\n extensions: RegExp,\n importsContain: string,\n): string[] {\n const matches: string[] = []\n const walk = (rel: string) => {\n const abs = join(repoRoot, rel)\n if (!existsSync(abs)) return\n for (const entry of readdirSync(abs)) {\n const sub = join(rel, entry)\n const subAbs = join(repoRoot, sub)\n let st\n try {\n st = statSync(subAbs)\n } catch {\n continue\n }\n if (st.isDirectory()) {\n if (\n entry === 'node_modules' ||\n entry === 'dist' ||\n entry === 'dist-tests' ||\n entry.startsWith('.')\n )\n continue\n walk(sub)\n } else if (st.isFile() && extensions.test(entry)) {\n if (entry.endsWith('.test.ts') || entry.endsWith('.test.mjs') || entry.endsWith('.test.js'))\n continue\n let text: string\n try {\n text = readFileSync(subAbs, 'utf8')\n } catch {\n continue\n }\n if (text.includes(importsContain)) matches.push(sub)\n }\n }\n }\n for (const r of roots) walk(r)\n return matches\n}\n\n/**\n * Run all finders against the configured files. Returns a flat list of\n * findings. Callers format + assert as they prefer.\n */\nexport function scanForMuffledGates(opts: ScanOptions): MuffledFinding[] {\n const findings: MuffledFinding[] = []\n const scanned = new Set<string>()\n\n // Context-specific: run all finders on explicit SCAN_FILES.\n for (const file of opts.scanFiles) {\n const abs = join(opts.repoRoot, file)\n if (!existsSync(abs)) continue\n const text = readFileSync(abs, 'utf8')\n for (const find of opts.finders) findings.push(...find(file, text))\n scanned.add(file)\n }\n\n // Auto-derived: run universal finders on every importer not already scanned.\n if (opts.autoDerive) {\n const importers = autoDeriveImporters(\n opts.repoRoot,\n opts.autoDerive.roots,\n opts.autoDerive.extensions,\n opts.autoDerive.importsContain,\n )\n for (const file of importers) {\n if (scanned.has(file)) continue\n const abs = join(opts.repoRoot, file)\n if (!existsSync(abs)) continue\n const text = readFileSync(abs, 'utf8')\n for (const find of opts.autoDerive.universalFinders) findings.push(...find(file, text))\n }\n }\n\n return findings\n}\n\n/**\n * Format findings into a single assert.fail-ready message. Each finding\n * carries file:line + pattern name + the offending line.\n */\nexport function formatFindings(findings: MuffledFinding[]): string {\n if (findings.length === 0) return ''\n return [\n `Found ${findings.length} muffled-gate pattern(s).`,\n `Fix each or annotate the line with \"// muffle-ok: <reason>\".`,\n '',\n ...findings.map((f) => ` ${f.file}:${f.line} — ${f.pattern}\\n ${f.lineText}`),\n ].join('\\n')\n}\n","/**\n * Declarative oracles — ground-truth assertions without an LLM.\n *\n * Lifted from browser-agent-driver's _oracle.mjs. When you know the\n * expected outcome exactly (a URL, a text fragment, a JSON shape), you\n * don't need an LLM judge — you need a regex. These oracles are\n * composable pass/fail checks over an observation bundle.\n *\n * Each oracle returns { pass, detail, evidence? } and has a short\n * `id` for reporting. `evaluateOracles` runs a batch and aggregates.\n */\n\nexport interface OracleObservation {\n /** Final observable text output from the agent (response, page snapshot, stdout). */\n text?: string\n /** Final URL — for browser-style scenarios. */\n url?: string\n /** Any structured JSON the agent produced. */\n json?: unknown\n /** Free-form context used by custom oracles. */\n context?: Record<string, unknown>\n}\n\nexport interface OracleResult {\n id: string\n pass: boolean\n detail: string\n evidence?: string\n}\n\nexport interface Oracle {\n id: string\n check(obs: OracleObservation): OracleResult\n}\n\nexport function textInSnapshot(needle: string, opts: { caseSensitive?: boolean } = {}): Oracle {\n const id = `text-in-snapshot(${needle})`\n return {\n id,\n check(obs) {\n const hay = obs.text ?? ''\n const found = opts.caseSensitive\n ? hay.includes(needle)\n : hay.toLowerCase().includes(needle.toLowerCase())\n return {\n id,\n pass: found,\n detail: found ? `\"${needle}\" found` : `\"${needle}\" not present in observation`,\n evidence: found ? excerpt(hay, needle, opts.caseSensitive) : undefined,\n }\n },\n }\n}\n\nexport function urlContains(fragment: string): Oracle {\n const id = `url-contains(${fragment})`\n return {\n id,\n check(obs) {\n const url = obs.url ?? ''\n const pass = url.toLowerCase().includes(fragment.toLowerCase())\n return {\n id,\n pass,\n detail: pass ? `url ok (${url})` : `url \"${url}\" missing \"${fragment}\"`,\n evidence: url,\n }\n },\n }\n}\n\nexport function jsonShape(expected: Record<string, unknown>): Oracle {\n const id = `json-shape(${Object.keys(expected).join(',')})`\n return {\n id,\n check(obs) {\n const json = obs.json\n if (!isObject(json)) {\n return { id, pass: false, detail: 'observation.json missing or not an object' }\n }\n for (const [k, v] of Object.entries(expected)) {\n if (!(k in json)) return { id, pass: false, detail: `key \"${k}\" missing` }\n const actual = (json as Record<string, unknown>)[k]\n if (typeof v === 'string' && v.startsWith('re:')) {\n const re = new RegExp(v.slice(3))\n if (typeof actual !== 'string' || !re.test(actual)) {\n return { id, pass: false, detail: `key \"${k}\" failed regex ${v}` }\n }\n } else if (actual !== v) {\n return {\n id,\n pass: false,\n detail: `key \"${k}\" = ${JSON.stringify(actual)}, expected ${JSON.stringify(v)}`,\n }\n }\n }\n return { id, pass: true, detail: 'all keys match' }\n },\n }\n}\n\nexport function regexMatches(pattern: RegExp): Oracle {\n const id = `regex(${pattern.source})`\n return {\n id,\n check(obs) {\n const hay = obs.text ?? ''\n const m = hay.match(pattern)\n return {\n id,\n pass: m !== null,\n detail: m ? `matched \"${m[0]}\"` : `pattern ${pattern.source} not matched`,\n evidence: m?.[0],\n }\n },\n }\n}\n\n/**\n * Anti-bot detector — distinguishes genuine failures from blocked navigation\n * (cloudflare, recaptcha, etc). Returns an Oracle that PASSES when no block\n * marker is present; on block, detail names the blocker so runners can tag\n * results as \"blocked\" rather than \"failed\". Lifted from browser-agent-driver.\n */\nexport function notBlocked(): Oracle {\n const id = 'not-blocked'\n const markers: Array<{ name: string; re: RegExp }> = [\n { name: 'cloudflare', re: /just a moment|verifying you are human|cf-chl-|cloudflare/i },\n { name: 'recaptcha', re: /recaptcha|i'?m not a robot|challenge.?form/i },\n { name: 'hcaptcha', re: /hcaptcha/i },\n { name: 'akamai', re: /akamai|pragma: no-cache/i },\n { name: 'perimeterx', re: /perimeterx|px-captcha/i },\n { name: 'rate-limit', re: /rate.?limit|429 too many requests/i },\n { name: 'access-denied', re: /access denied|403 forbidden/i },\n ]\n return {\n id,\n check(obs) {\n const hay = obs.text ?? ''\n for (const { name, re } of markers) {\n if (re.test(hay)) {\n return {\n id,\n pass: false,\n detail: `blocked by ${name}`,\n evidence: (hay.match(re) ?? [])[0],\n }\n }\n }\n return { id, pass: true, detail: 'no anti-bot block detected' }\n },\n }\n}\n\nexport interface OracleReport {\n results: OracleResult[]\n pass: boolean\n passCount: number\n failCount: number\n /** 0-1 ratio of oracles passed. */\n score: number\n}\n\n/** Run all oracles against one observation and aggregate. */\nexport function evaluateOracles(obs: OracleObservation, oracles: Oracle[]): OracleReport {\n const results = oracles.map((o) => o.check(obs))\n const passCount = results.filter((r) => r.pass).length\n const failCount = results.length - passCount\n return {\n results,\n pass: failCount === 0 && results.length > 0,\n passCount,\n failCount,\n score: results.length ? passCount / results.length : 0,\n }\n}\n\nfunction excerpt(hay: string, needle: string, caseSensitive = false): string {\n const haySearch = caseSensitive ? hay : hay.toLowerCase()\n const needleSearch = caseSensitive ? needle : needle.toLowerCase()\n const idx = haySearch.indexOf(needleSearch)\n if (idx === -1) return ''\n const start = Math.max(0, idx - 20)\n const end = Math.min(hay.length, idx + needle.length + 20)\n return (start > 0 ? '…' : '') + hay.slice(start, end) + (end < hay.length ? '…' : '')\n}\n\nfunction isObject(v: unknown): v is Record<string, unknown> {\n return typeof v === 'object' && v !== null && !Array.isArray(v)\n}\n","/**\n * @stable\n *\n * Eval scorecard — the persistent (persona × profile) score timeline.\n *\n * Every benchmark run folds into per-cell entries; a cell is\n * `(scenarioId, profileHash)` and its timeline carries one entry per commit.\n * The scorecard answers the question a single run cannot: did THIS change\n * regress persona P on profile F, even while the aggregate improved?\n *\n * Storage is an append-only JSONL log — one line per (cell, commit). Appends\n * never read-modify-write, so concurrent campaign runs cannot clobber each\n * other; `loadScorecard` folds the log into the queryable `Scorecard`, and a\n * malformed line never breaks the read. `diffScorecard` compares the latest\n * entry of each cell against its predecessor with Cohen's d + Welch's t-test.\n */\n\nimport { appendFileSync, existsSync, mkdirSync, readFileSync } from 'node:fs'\nimport { dirname } from 'node:path'\nimport type { AgentProfile } from './agent-profile'\nimport { agentProfileHash } from './agent-profile'\nimport { welchsTTest } from './baseline'\nimport type { RunRecord } from './run-record'\nimport { cohensD } from './statistics'\n\n// ── Types ────────────────────────────────────────────────────────────\n\n/** One commit's measurement of one (scenario, profile) cell. */\nexport interface ScorecardEntry {\n commitSha: string\n /** ISO timestamp the entry was recorded. */\n timestamp: string\n /** Per-seed (or per-rep) scores for this cell at this commit. */\n scores: number[]\n /** Median of `scores` — the cell's headline score for the commit. */\n composite: number\n /** Per-dimension means, when the runs carried a judge breakdown. */\n perDimension?: Record<string, number>\n /** RunRecord ids folded into this entry — provenance. */\n runIds: string[]\n}\n\n/** A (scenario, profile) cell and its commit-ordered score timeline. */\nexport interface ScorecardCell {\n scenarioId: string\n profileHash: string\n /** Model id — denormalised from the profile for readable filtering. */\n model: string\n timeline: ScorecardEntry[]\n}\n\n/** The folded scorecard: every cell, plus the profile definitions by hash. */\nexport interface Scorecard {\n cells: ScorecardCell[]\n /** Profile definitions seen — keeps the scorecard self-describing. */\n profiles: Record<string, AgentProfile>\n}\n\n/** One append-only log line — a single cell's entry for a single commit. */\nexport interface ScorecardLogLine {\n scenarioId: string\n profileHash: string\n model: string\n profile: AgentProfile\n entry: ScorecardEntry\n}\n\n// ── Recording ────────────────────────────────────────────────────────\n\nexport interface RecordRunsOptions {\n /** The profile that produced these runs — keys the cell. */\n profile: AgentProfile\n commitSha: string\n /** Defaults to `new Date().toISOString()`. */\n timestamp?: string\n}\n\nfunction median(xs: number[]): number {\n if (xs.length === 0) return 0\n const sorted = [...xs].sort((a, b) => a - b)\n const mid = Math.floor(sorted.length / 2)\n return sorted.length % 2 === 0 ? (sorted[mid - 1]! + sorted[mid]!) / 2 : sorted[mid]!\n}\n\n/** The split score the run actually carries (`holdout` runs fill holdoutScore). */\nfunction runScore(run: RunRecord): number | undefined {\n return run.outcome.holdoutScore ?? run.outcome.searchScore\n}\n\n/** Mean of each judge dimension across the runs that reported one. */\nfunction aggregatePerDimension(runs: RunRecord[]): Record<string, number> | undefined {\n const sums = new Map<string, { total: number; count: number }>()\n for (const run of runs) {\n const dims = run.outcome.judgeScores?.perDimMean\n if (!dims) continue\n for (const [dim, value] of Object.entries(dims)) {\n if (!Number.isFinite(value)) continue\n const acc = sums.get(dim) ?? { total: 0, count: 0 }\n acc.total += value\n acc.count += 1\n sums.set(dim, acc)\n }\n }\n if (sums.size === 0) return undefined\n const out: Record<string, number> = {}\n for (const [dim, acc] of sums) out[dim] = acc.total / acc.count\n return out\n}\n\n/**\n * Fold a benchmark's `RunRecord[]` into per-cell scorecard log lines — one\n * line per scenario the runs cover. All runs are attributed to the single\n * `profile` in `opts` (the harness ran them under it); the cell key is\n * `(scenarioId, agentProfileHash(profile))`.\n */\nexport function recordRuns(runs: RunRecord[], opts: RecordRunsOptions): ScorecardLogLine[] {\n const profileHash = agentProfileHash(opts.profile)\n const timestamp = opts.timestamp ?? new Date().toISOString()\n\n const byScenario = new Map<string, RunRecord[]>()\n for (const run of runs) {\n const scenarioId = run.scenarioId\n if (!scenarioId) continue // un-keyed run — cannot place it in a cell\n const bucket = byScenario.get(scenarioId)\n if (bucket) bucket.push(run)\n else byScenario.set(scenarioId, [run])\n }\n\n const lines: ScorecardLogLine[] = []\n for (const [scenarioId, scenarioRuns] of byScenario) {\n const scored = scenarioRuns\n .map((run) => ({ run, score: runScore(run) }))\n .filter((s): s is { run: RunRecord; score: number } => s.score !== undefined)\n if (scored.length === 0) continue\n const scores = scored.map((s) => s.score)\n const entry: ScorecardEntry = {\n commitSha: opts.commitSha,\n timestamp,\n scores,\n composite: median(scores),\n runIds: scored.map((s) => s.run.runId),\n }\n const perDimension = aggregatePerDimension(scenarioRuns)\n if (perDimension) entry.perDimension = perDimension\n lines.push({\n scenarioId,\n profileHash,\n model: opts.profile.model,\n profile: opts.profile,\n entry,\n })\n }\n return lines\n}\n\n// ── Storage ──────────────────────────────────────────────────────────\n\n/** Append cell entries to the JSONL scorecard log. Creates the file/dir. */\nexport function appendScorecard(logPath: string, lines: ScorecardLogLine[]): void {\n if (lines.length === 0) return\n mkdirSync(dirname(logPath), { recursive: true })\n appendFileSync(logPath, `${lines.map((line) => JSON.stringify(line)).join('\\n')}\\n`)\n}\n\n/** Record runs and append them to the log in one call. Returns the lines. */\nexport function recordRunsToScorecard(\n logPath: string,\n runs: RunRecord[],\n opts: RecordRunsOptions,\n): ScorecardLogLine[] {\n const lines = recordRuns(runs, opts)\n appendScorecard(logPath, lines)\n return lines\n}\n\n/**\n * Fold the JSONL log into a queryable `Scorecard`. A missing file yields an\n * empty scorecard; a malformed line is skipped — a corrupt append never\n * breaks the read. Each cell's timeline is sorted chronologically.\n */\nexport function loadScorecard(logPath: string): Scorecard {\n if (!existsSync(logPath)) return { cells: [], profiles: {} }\n const cells = new Map<string, ScorecardCell>()\n const profiles: Record<string, AgentProfile> = {}\n\n for (const raw of readFileSync(logPath, 'utf8').split('\\n')) {\n const line = raw.trim()\n if (!line) continue\n let parsed: ScorecardLogLine\n try {\n parsed = JSON.parse(line) as ScorecardLogLine\n } catch {\n continue // skip a malformed line rather than failing the whole read\n }\n if (!parsed?.scenarioId || !parsed.profileHash || !parsed.entry) continue\n const key = `${parsed.scenarioId}::${parsed.profileHash}`\n let cell = cells.get(key)\n if (!cell) {\n cell = {\n scenarioId: parsed.scenarioId,\n profileHash: parsed.profileHash,\n model: parsed.model,\n timeline: [],\n }\n cells.set(key, cell)\n }\n cell.timeline.push(parsed.entry)\n if (parsed.profile) profiles[parsed.profileHash] = parsed.profile\n }\n\n for (const cell of cells.values()) {\n cell.timeline.sort((a, b) => a.timestamp.localeCompare(b.timestamp))\n }\n return { cells: [...cells.values()], profiles }\n}\n\n// ── Diff ─────────────────────────────────────────────────────────────\n\nexport type CellVerdict = 'improved' | 'regressed' | 'flat' | 'new'\n\nexport interface ScorecardCellDiff {\n scenarioId: string\n profileHash: string\n model: string\n verdict: CellVerdict\n /** Composite of the latest entry. */\n current: number\n /** Composite of the comparison entry — `null` when `verdict === 'new'`. */\n baseline: number | null\n /** `current − baseline` — `null` when new. */\n delta: number | null\n /** Cohen's d of current vs baseline samples — `null` when new or n < 2. */\n cohensD: number | null\n /** Welch's t-test p-value — `null` when new or n < 2. */\n pValue: number | null\n currentCommit: string\n baselineCommit: string | null\n}\n\nexport interface ScorecardDiff {\n cells: ScorecardCellDiff[]\n summary: { improved: number; regressed: number; flat: number; new: number }\n}\n\nexport interface DiffScorecardOptions {\n /** Compare each cell against this commit instead of its immediate predecessor. */\n baselineCommit?: string\n /** |Cohen's d| at/above which a move counts as real. Default 0.5. */\n minEffect?: number\n /** p-value at/below which a move is significant. Default 0.05. */\n maxP?: number\n /**\n * |delta| at/above which a move counts when statistics are unavailable\n * (a cell with fewer than 2 samples on either side). Default 0.05.\n */\n minDelta?: number\n}\n\n/**\n * Compare the latest entry of every cell against its predecessor (or against\n * `baselineCommit`) and classify the move. A move is `improved`/`regressed`\n * only when it clears both the effect-size and significance gates; otherwise\n * `flat`. Cells with no prior entry are `new`.\n */\nexport function diffScorecard(\n scorecard: Scorecard,\n opts: DiffScorecardOptions = {},\n): ScorecardDiff {\n const minEffect = opts.minEffect ?? 0.5\n const maxP = opts.maxP ?? 0.05\n const minDelta = opts.minDelta ?? 0.05\n\n const cells: ScorecardCellDiff[] = []\n for (const cell of scorecard.cells) {\n const timeline = cell.timeline\n if (timeline.length === 0) continue\n const current = timeline[timeline.length - 1]!\n\n const baseline = opts.baselineCommit\n ? [...timeline].reverse().find((e) => e.commitSha === opts.baselineCommit && e !== current)\n : timeline[timeline.length - 2]\n\n const base: Omit<\n ScorecardCellDiff,\n 'verdict' | 'baseline' | 'delta' | 'cohensD' | 'pValue' | 'baselineCommit'\n > = {\n scenarioId: cell.scenarioId,\n profileHash: cell.profileHash,\n model: cell.model,\n current: current.composite,\n currentCommit: current.commitSha,\n }\n\n if (!baseline) {\n cells.push({\n ...base,\n verdict: 'new',\n baseline: null,\n delta: null,\n cohensD: null,\n pValue: null,\n baselineCommit: null,\n })\n continue\n }\n\n const delta = current.composite - baseline.composite\n const canStat = baseline.scores.length >= 2 && current.scores.length >= 2\n let d: number | null = null\n let p: number | null = null\n let verdict: CellVerdict\n\n if (canStat) {\n d = cohensD(baseline.scores, current.scores)\n const t = welchsTTest(baseline.scores, current.scores)\n p = Number.isFinite(t.p) ? t.p : null\n const significant = Math.abs(d) >= minEffect && p !== null && p <= maxP\n verdict = significant ? (delta > 0 ? 'improved' : 'regressed') : 'flat'\n } else {\n // Too few samples for a real test — fall back to a raw-delta threshold.\n verdict = Math.abs(delta) >= minDelta ? (delta > 0 ? 'improved' : 'regressed') : 'flat'\n }\n\n cells.push({\n ...base,\n verdict,\n baseline: baseline.composite,\n delta,\n cohensD: d,\n pValue: p,\n baselineCommit: baseline.commitSha,\n })\n }\n\n const summary = { improved: 0, regressed: 0, flat: 0, new: 0 }\n for (const cell of cells) summary[cell.verdict] += 1\n return { cells, summary }\n}\n\n/**\n * Render a scorecard diff as a human-readable report — the block a feature\n * PR prints. Regressions are listed first; flat cells are summarised, not\n * enumerated.\n */\nexport function formatScorecardDiff(diff: ScorecardDiff): string {\n const lines: string[] = []\n const { summary } = diff\n lines.push(\n `Scorecard: ${summary.regressed} regressed · ${summary.improved} improved · ` +\n `${summary.flat} flat · ${summary.new} new`,\n )\n\n const fmt = (n: number) => n.toFixed(3)\n const noteworthy = diff.cells\n .filter((c) => c.verdict === 'regressed' || c.verdict === 'improved')\n .sort((a, b) => {\n // Regressions first, then by magnitude of delta.\n if (a.verdict !== b.verdict) return a.verdict === 'regressed' ? -1 : 1\n return Math.abs(b.delta ?? 0) - Math.abs(a.delta ?? 0)\n })\n\n for (const cell of noteworthy) {\n const mark = cell.verdict === 'regressed' ? 'REGRESSED' : 'improved'\n const deltaStr =\n cell.delta !== null ? (cell.delta >= 0 ? `+${fmt(cell.delta)}` : fmt(cell.delta)) : '—'\n const stat =\n cell.cohensD !== null\n ? ` (d=${cell.cohensD.toFixed(2)}${cell.pValue !== null ? `, p=${cell.pValue.toFixed(3)}` : ''})`\n : ''\n lines.push(\n ` ${mark} ${cell.scenarioId} · ${cell.model} · ${cell.profileHash.slice(0, 8)} ` +\n `${fmt(cell.baseline ?? 0)} → ${fmt(cell.current)} ${deltaStr}${stat}`,\n )\n }\n\n return lines.join('\\n')\n}\n","/**\n * Series convergence — detects whether a sequence of scalar measurements\n * is stabilizing, drifting, or noisy.\n *\n * Lifted from ADC convergence.ts. The per-turn `ConvergenceTracker` is\n * about progress *within* a single run; this module is about drift\n * *across* runs (e.g. \"are my nightly eval scores stabilizing?\").\n *\n * Three signals:\n * - stabilized: last K values have low variance (< epsilon) — done\n * - drifting: recent trend is monotonic and beyond noise — regressing or improving\n * - noisy: neither — keep iterating, but flag as untrustworthy for gating\n */\n\nexport interface SeriesConvergenceOptions {\n /** Window size for \"recent\" analysis (default 5). */\n window?: number\n /** Coefficient-of-variation threshold below which the window is stabilized (default 0.05 = 5%). */\n stableCv?: number\n /** Minimum monotone run length to call drift (default 3). */\n driftRun?: number\n}\n\nexport interface SeriesConvergenceResult {\n state: 'stabilized' | 'drifting-up' | 'drifting-down' | 'noisy' | 'insufficient-data'\n windowMean: number\n windowCv: number\n /** Longest monotonic run at the tail of the series (positive for up, negative for down). */\n tailRun: number\n /** True when n ≥ window AND windowCv ≤ stableCv. */\n stable: boolean\n}\n\nexport function analyzeSeries(\n values: number[],\n options: SeriesConvergenceOptions = {},\n): SeriesConvergenceResult {\n const window = options.window ?? 5\n const stableCv = options.stableCv ?? 0.05\n const driftRun = options.driftRun ?? 3\n\n if (values.length < Math.max(2, Math.min(window, 3))) {\n return { state: 'insufficient-data', windowMean: 0, windowCv: 0, tailRun: 0, stable: false }\n }\n\n const tail = values.slice(-window)\n const mean = tail.reduce((a, b) => a + b, 0) / tail.length\n const variance = tail.reduce((acc, v) => acc + (v - mean) ** 2, 0) / tail.length\n const stdDev = Math.sqrt(variance)\n const refMean = Math.abs(mean) > 1e-9 ? Math.abs(mean) : 1\n const cv = stdDev / refMean\n const stable = tail.length >= window && cv <= stableCv\n\n // Tail monotonic run: count how many consecutive strictly-increasing (or decreasing)\n // steps end at the final value.\n let tailRun = 0\n let direction: 1 | -1 | 0 = 0\n for (let i = values.length - 1; i > 0; i--) {\n const delta = values[i]! - values[i - 1]!\n if (delta === 0) break\n const dir = delta > 0 ? 1 : -1\n if (direction === 0) direction = dir\n if (dir !== direction) break\n tailRun += dir\n }\n\n let state: SeriesConvergenceResult['state']\n if (stable) {\n state = 'stabilized'\n } else if (Math.abs(tailRun) >= driftRun) {\n state = tailRun > 0 ? 'drifting-up' : 'drifting-down'\n } else {\n state = 'noisy'\n }\n\n return { state, windowMean: mean, windowCv: cv, tailRun, stable }\n}\n","/**\n * SLO gates — quantified pass/fail primitives beyond score thresholds.\n *\n * Lifted from ADC's sandbox eval suite. Each SLO defines a metric, a\n * threshold, and a severity (critical | warning). Critical breaches fail\n * the eval; warnings are reported but don't gate CI. Margin is the\n * ratio of actual to threshold for histogramming \"how close are we?\"\n *\n * Consumers assemble their own SLO arrays; DEFAULT_AGENT_SLOS covers\n * the generic agent flow (provision, first token, pass rate, cost).\n */\n\nexport type SloSeverity = 'critical' | 'warning'\nexport type SloComparator = 'lte' | 'gte'\n\nexport interface Slo {\n /** Stable identifier — must be unique within an SLO set. */\n id: string\n /** Human description, shown in reports. */\n description: string\n /** Metric key looked up in the candidate record. */\n metric: string\n /** Whether the metric should stay below (lte) or above (gte) threshold. */\n comparator: SloComparator\n /** Threshold value. */\n threshold: number\n severity: SloSeverity\n}\n\nexport interface SloCheckResult {\n slo: Slo\n actual: number | undefined\n passed: boolean\n /** actual/threshold for lte, threshold/actual for gte. >1 means safe margin; <1 means breach. 0 when actual is missing. */\n margin: number\n detail: string\n}\n\nexport interface SloReport {\n results: SloCheckResult[]\n passedCritical: boolean\n criticalBreaches: SloCheckResult[]\n warnings: SloCheckResult[]\n}\n\n/**\n * Evaluate an SLO set against a candidate metrics object. Missing metrics\n * count as breaches — if you declared it, you must measure it.\n */\nexport function checkSlos(metrics: Record<string, number>, slos: Slo[]): SloReport {\n const results: SloCheckResult[] = slos.map((slo) => check(slo, metrics[slo.metric]))\n const criticalBreaches = results.filter((r) => !r.passed && r.slo.severity === 'critical')\n const warnings = results.filter((r) => !r.passed && r.slo.severity === 'warning')\n return { results, passedCritical: criticalBreaches.length === 0, criticalBreaches, warnings }\n}\n\nfunction check(slo: Slo, actual: number | undefined): SloCheckResult {\n if (actual === undefined || !Number.isFinite(actual)) {\n return {\n slo,\n actual,\n passed: false,\n margin: 0,\n detail: `metric \"${slo.metric}\" missing — declared SLOs must be measured`,\n }\n }\n if (slo.comparator === 'lte') {\n const passed = actual <= slo.threshold\n const margin = slo.threshold === 0 ? (actual === 0 ? Infinity : 0) : slo.threshold / actual\n return {\n slo,\n actual,\n passed,\n margin,\n detail: `${actual} ≤ ${slo.threshold}: ${passed ? 'ok' : 'breach'}`,\n }\n }\n const passed = actual >= slo.threshold\n const margin = actual === 0 ? 0 : actual / slo.threshold\n return {\n slo,\n actual,\n passed,\n margin,\n detail: `${actual} ≥ ${slo.threshold}: ${passed ? 'ok' : 'breach'}`,\n }\n}\n\n/** Reference SLO set for agent-style evals. Tune per-product by cloning + overriding. */\nexport const DEFAULT_AGENT_SLOS: Slo[] = [\n {\n id: 'provision_ms',\n description: 'Sandbox/session provision under 60s',\n metric: 'provisionMs',\n comparator: 'lte',\n threshold: 60_000,\n severity: 'critical',\n },\n {\n id: 'first_token_ms',\n description: 'First token under 15s',\n metric: 'firstTokenMs',\n comparator: 'lte',\n threshold: 15_000,\n severity: 'critical',\n },\n {\n id: 'pass_rate',\n description: 'Scenario pass rate ≥ 90%',\n metric: 'passRate',\n comparator: 'gte',\n threshold: 0.9,\n severity: 'critical',\n },\n {\n id: 'cost_usd',\n description: 'Per-scenario cost under $0.05',\n metric: 'costUsd',\n comparator: 'lte',\n threshold: 0.05,\n severity: 'warning',\n },\n {\n id: 'overall_score',\n description: 'Overall score ≥ 0.7',\n metric: 'overallScore',\n comparator: 'gte',\n threshold: 0.7,\n severity: 'critical',\n },\n]\n","/**\n * State continuity scoring — measures how well a resumed/handed-off agent\n * preserves prior work.\n *\n * When session 2 continues\n * session 1's work, the key question is: did it preserve key artifacts,\n * or start over and lose context? Each `ContinuityCheck` inspects one\n * aspect (file preserved, key count grew, status advanced) and yields\n * 0-1 credit; the aggregate is the simple mean.\n *\n * Generic over any \"snapshot\" shape — pass your own checks.\n */\n\nexport interface ContinuitySnapshotPair<T> {\n before: T\n after: T\n}\n\nexport interface ContinuityCheck<T> {\n /** Stable identifier; shown in the report. */\n id: string\n /** Description of what this check measures. */\n description: string\n /** Returns 0..1 credit for this dimension (1 = fully preserved/improved). */\n score: (pair: ContinuitySnapshotPair<T>) => number\n}\n\nexport interface ContinuityCheckResult {\n id: string\n description: string\n score: number\n pass: boolean\n}\n\nexport interface ContinuityReport {\n results: ContinuityCheckResult[]\n /** Mean of per-check scores, in 0..1. */\n overallScore: number\n /** True iff ALL checks scored ≥ passThreshold. */\n pass: boolean\n}\n\nexport function scoreContinuity<T>(\n pair: ContinuitySnapshotPair<T>,\n checks: ContinuityCheck<T>[],\n options: { passThreshold?: number } = {},\n): ContinuityReport {\n if (checks.length === 0) {\n throw new Error('scoreContinuity: at least 1 check required')\n }\n const passThreshold = options.passThreshold ?? 0.8\n const results: ContinuityCheckResult[] = checks.map((c) => {\n const raw = c.score(pair)\n const clamped = Number.isFinite(raw) ? Math.max(0, Math.min(1, raw)) : 0\n return { id: c.id, description: c.description, score: clamped, pass: clamped >= passThreshold }\n })\n const overallScore = results.reduce((a, r) => a + r.score, 0) / results.length\n return { results, overallScore, pass: results.every((r) => r.pass) }\n}\n\n/** Common check: a required key in a record exists and equals the prior value. */\nexport function keyPreserved<T extends Record<string, unknown>>(\n key: keyof T & string,\n): ContinuityCheck<T> {\n return {\n id: `preserved(${key})`,\n description: `\"${key}\" unchanged from before to after`,\n score: ({ before, after }) => (before[key] !== undefined && before[key] === after[key] ? 1 : 0),\n }\n}\n\n/** Common check: a collection (array) grew or stayed the same size. */\nexport function collectionPreserved<T, K extends keyof T & string>(\n key: K,\n minRatio = 1,\n): ContinuityCheck<T> {\n return {\n id: `collection-preserved(${key})`,\n description: `\"${key}\" length ≥ ${minRatio} × prior length`,\n score: ({ before, after }) => {\n const b = before[key]\n const a = after[key]\n if (!Array.isArray(b) || !Array.isArray(a)) return 0\n if (b.length === 0) return a.length === 0 ? 1 : 1\n return Math.min(1, a.length / (b.length * minRatio))\n },\n }\n}\n\n/** Common check: a status field advanced in an expected order. */\nexport function statusAdvanced<T extends Record<string, unknown>>(\n key: keyof T & string,\n progression: readonly string[],\n): ContinuityCheck<T> {\n return {\n id: `status-advanced(${key})`,\n description: `\"${key}\" progressed along ${progression.join('→')}`,\n score: ({ before, after }) => {\n const bi = progression.indexOf(String(before[key]))\n const ai = progression.indexOf(String(after[key]))\n if (bi === -1 || ai === -1) return 0\n return ai >= bi ? 1 : 0\n },\n }\n}\n","/**\n * Behavior DSL — pytest-style assertions over a run's trajectory.\n *\n * Shape:\n * expect(store, runId).toCall('search').withArgs({ q: /.+/ })\n * expect(store, runId).toRefuse()\n * expect(store, runId).toOutputMatch(/confirmed/i)\n * expect(store, runId).toRespectBudget('tokens')\n * expect(store, runId).toCompleteWithin({ wallMs: 30_000 })\n *\n * Each matcher returns an `Expectation` with `.check() → MatcherResult`\n * so the DSL is composable with suite runners — you can collect all\n * expectations into a report instead of throwing on first failure.\n */\n\nimport { llmSpans, toolSpans } from './trace/query'\nimport type { BudgetLedgerEntry, Span, ToolSpan } from './trace/schema'\nimport type { TraceStore } from './trace/store'\n\nexport interface MatcherResult {\n ok: boolean\n detail: string\n evidence?: string\n}\n\nexport interface Expectation {\n /** Human-facing label; used in reports. */\n label: string\n check(): Promise<MatcherResult>\n}\n\nexport class BehaviorAssertion {\n constructor(\n private store: TraceStore,\n private runId: string,\n ) {}\n\n toCall(toolName: string): CallExpectation {\n return new CallExpectation(this.store, this.runId, toolName)\n }\n\n toRefuse(markers: RegExp[] = DEFAULT_REFUSAL_MARKERS): Expectation {\n return {\n label: `agent(${this.runId}).toRefuse()`,\n check: async () => {\n const spans = await llmSpans(this.store, this.runId)\n const output = spans.map((s) => s.output ?? '').join('\\n')\n const hit = markers.some((re) => re.test(output))\n return hit\n ? { ok: true, detail: 'refusal marker detected' }\n : {\n ok: false,\n detail: 'no refusal marker in agent output',\n evidence: output.slice(0, 200),\n }\n },\n }\n }\n\n toOutputMatch(pattern: RegExp): Expectation {\n return {\n label: `agent(${this.runId}).toOutputMatch(${pattern.source})`,\n check: async () => {\n const spans = await llmSpans(this.store, this.runId)\n const output = spans.map((s) => s.output ?? '').join('\\n')\n const m = output.match(pattern)\n return m\n ? { ok: true, detail: `matched \"${m[0]}\"`, evidence: m[0] }\n : { ok: false, detail: 'pattern not matched', evidence: output.slice(0, 200) }\n },\n }\n }\n\n toRespectBudget(\n dimension: keyof BudgetLedgerEntry['dimension'] | 'tokens' | 'wallMs' | 'calls' | 'usd',\n ): Expectation {\n return {\n label: `agent(${this.runId}).toRespectBudget(${String(dimension)})`,\n check: async () => {\n const entries = await this.store.budget(this.runId)\n const breached = entries.some((e) => e.dimension === dimension && e.breached)\n return breached\n ? { ok: false, detail: `budget \"${String(dimension)}\" breached` }\n : { ok: true, detail: `no breach on \"${String(dimension)}\"` }\n },\n }\n }\n\n toCompleteWithin(limits: {\n wallMs?: number\n toolCalls?: number\n llmTurns?: number\n }): Expectation {\n return {\n label: `agent(${this.runId}).toCompleteWithin(${JSON.stringify(limits)})`,\n check: async () => {\n const run = await this.store.getRun(this.runId)\n if (!run?.endedAt) return { ok: false, detail: 'run has not completed' }\n const wallMs = run.endedAt - run.startedAt\n const tool = (await toolSpans(this.store, this.runId)).length\n const llm = (await llmSpans(this.store, this.runId)).length\n const violations: string[] = []\n if (limits.wallMs !== undefined && wallMs > limits.wallMs)\n violations.push(`wallMs ${wallMs} > ${limits.wallMs}`)\n if (limits.toolCalls !== undefined && tool > limits.toolCalls)\n violations.push(`toolCalls ${tool} > ${limits.toolCalls}`)\n if (limits.llmTurns !== undefined && llm > limits.llmTurns)\n violations.push(`llmTurns ${llm} > ${limits.llmTurns}`)\n return violations.length === 0\n ? { ok: true, detail: `within limits (${wallMs}ms, ${tool} tools, ${llm} turns)` }\n : { ok: false, detail: violations.join('; ') }\n },\n }\n }\n\n toNeverCall(toolName: string): Expectation {\n return {\n label: `agent(${this.runId}).toNeverCall(${toolName})`,\n check: async () => {\n const calls = await toolSpans(this.store, this.runId, toolName)\n return calls.length === 0\n ? { ok: true, detail: `tool \"${toolName}\" not invoked` }\n : {\n ok: false,\n detail: `tool \"${toolName}\" called ${calls.length}x`,\n evidence: calls[0]!.spanId,\n }\n },\n }\n }\n}\n\nexport class CallExpectation implements Expectation {\n private argMatchers: Array<(args: unknown) => boolean> = []\n private minCount = 1\n private maxCount = Infinity\n\n constructor(\n private store: TraceStore,\n private runId: string,\n private toolName: string,\n ) {}\n\n get label(): string {\n return `agent(${this.runId}).toCall(${this.toolName})`\n }\n\n withArgs(shape: Record<string, unknown | RegExp>): this {\n this.argMatchers.push((args) => matchArgs(args, shape))\n return this\n }\n\n times(n: number): this {\n this.minCount = n\n this.maxCount = n\n return this\n }\n\n atLeast(n: number): this {\n this.minCount = n\n return this\n }\n\n atMost(n: number): this {\n this.maxCount = n\n return this\n }\n\n async check(): Promise<MatcherResult> {\n const calls = await toolSpans(this.store, this.runId, this.toolName)\n const matching = calls.filter((c) => this.argMatchers.every((fn) => fn(c.args)))\n const count = matching.length\n if (count < this.minCount)\n return {\n ok: false,\n detail: `expected ≥ ${this.minCount} matching \"${this.toolName}\" calls, got ${count}`,\n }\n if (count > this.maxCount)\n return {\n ok: false,\n detail: `expected ≤ ${this.maxCount} matching \"${this.toolName}\" calls, got ${count}`,\n }\n return { ok: true, detail: `${count} matching \"${this.toolName}\" call(s)` }\n }\n}\n\nexport function expectAgent(store: TraceStore, runId: string): BehaviorAssertion {\n return new BehaviorAssertion(store, runId)\n}\n\n/** Runs every expectation, collects results. Never throws. */\nexport async function runExpectations(expectations: Expectation[]): Promise<{\n results: Array<{ label: string; result: MatcherResult }>\n pass: boolean\n passCount: number\n failCount: number\n}> {\n const results = await Promise.all(\n expectations.map(async (e) => ({ label: e.label, result: await e.check() })),\n )\n const passCount = results.filter((r) => r.result.ok).length\n return {\n results,\n pass: passCount === results.length,\n passCount,\n failCount: results.length - passCount,\n }\n}\n\nconst DEFAULT_REFUSAL_MARKERS = [\n /\\b(?:i\\s+(?:can(?:not|'t)|won't|will\\s+not|am\\s+unable|refuse))\\b/i,\n /\\b(?:sorry,?\\s+(?:but\\s+)?i\\s+(?:can't|cannot))/i,\n /\\bthat\\s+(?:would\\s+)?(?:violate|be\\s+against)\\b/i,\n /\\bunable\\s+to\\s+(?:help|assist|comply)\\b/i,\n]\n\nfunction matchArgs(args: unknown, shape: Record<string, unknown | RegExp>): boolean {\n if (args === null || typeof args !== 'object') return false\n const record = args as Record<string, unknown>\n for (const [k, expected] of Object.entries(shape)) {\n const actual = record[k]\n if (expected instanceof RegExp) {\n if (typeof actual !== 'string' || !expected.test(actual)) return false\n } else if (actual !== expected) {\n return false\n }\n }\n return true\n}\n\n// Guard against accidental Span import elision during build-time DTS generation.\nexport type { Span, ToolSpan }\n","/**\n * CI gate — evaluate a corpus against threshold contracts and generate\n * a human-readable PR/build comment.\n *\n * Three layers:\n * 1. `ThresholdContract` declarations (YAML-equivalent TS objects)\n * 2. `evaluateContract` runs the contracts against a TraceStore and\n * returns a structured report + overall pass/fail.\n * 3. `renderMarkdownReport` formats the report for GitHub PR comments.\n *\n * Consumers wrap this in their own `gh pr comment` / CI integration —\n * we don't ship the GitHub Action binary, just the library call that\n * the action invokes.\n */\n\nimport type { BaselineReport } from './baseline'\nimport { compareToBaseline, type MetricSamples } from './baseline'\nimport { checkSlos, type Slo, type SloReport } from './slo'\nimport { aggregateLlm, llmSpans, runFailureClass } from './trace/query'\nimport type { Run } from './trace/schema'\nimport type { RunFilter, TraceStore } from './trace/store'\n\nexport interface ContractMetric {\n /** Metric id matching either a predefined key or a custom extractor. */\n metric: string\n higherIsBetter: boolean\n /** Max tolerated regression (e.g. 0.02 = 2pp worse than baseline). */\n maxRegression?: number\n /** Optional extractor if the metric isn't in the default set. */\n extract?: (run: Run, store: TraceStore) => Promise<number | null>\n}\n\nexport interface ThresholdContract {\n name: string\n baseline: RunFilter\n candidate: RunFilter\n metrics: ContractMetric[]\n slos?: Slo[]\n}\n\nexport interface ContractReport {\n name: string\n baselineReport: BaselineReport\n sloReport?: SloReport\n breaches: string[]\n pass: boolean\n}\n\nexport async function evaluateContract(\n store: TraceStore,\n contract: ThresholdContract,\n): Promise<ContractReport> {\n const baselineRuns = await store.listRuns(contract.baseline)\n const candidateRuns = await store.listRuns(contract.candidate)\n if (candidateRuns.length === 0) {\n return {\n name: contract.name,\n baselineReport: { metrics: [], hasRegression: false, hasUnstable: true },\n breaches: ['no candidate runs matched'],\n pass: false,\n }\n }\n\n const samples: MetricSamples[] = []\n for (const m of contract.metrics) {\n const extract = m.extract ?? defaultExtract(m.metric)\n const baseline = await extractAll(baselineRuns, extract, store)\n const candidate = await extractAll(candidateRuns, extract, store)\n if (baseline.length < 2 || candidate.length < 2) continue\n samples.push({ metric: m.metric, higherIsBetter: m.higherIsBetter, baseline, candidate })\n }\n\n const baselineReport =\n samples.length >= 1\n ? compareToBaseline(samples)\n : { metrics: [], hasRegression: false, hasUnstable: samples.length === 0 }\n\n // SLO evaluation against candidate-side aggregate metrics\n let sloReport: SloReport | undefined\n if (contract.slos && contract.slos.length > 0) {\n const agg = await aggregateRunMetrics(candidateRuns, store)\n sloReport = checkSlos(agg, contract.slos)\n }\n\n const breaches: string[] = []\n for (const metric of baselineReport.metrics) {\n const decl = contract.metrics.find((m) => m.metric === metric.metric)\n if (!decl) continue\n if (metric.verdict === 'regressed') {\n const magnitude = Math.abs(metric.delta)\n if (decl.maxRegression === undefined || magnitude > decl.maxRegression) {\n breaches.push(\n `metric \"${metric.metric}\" regressed by ${metric.delta.toFixed(4)} (d=${metric.cohensD.toFixed(2)}, p=${metric.welchP.toExponential(2)})`,\n )\n }\n }\n }\n if (sloReport) {\n for (const r of sloReport.criticalBreaches) {\n breaches.push(`SLO \"${r.slo.id}\" breached: ${r.detail}`)\n }\n }\n\n return { name: contract.name, baselineReport, sloReport, breaches, pass: breaches.length === 0 }\n}\n\nexport function renderMarkdownReport(reports: ContractReport[]): string {\n const lines: string[] = []\n const overall = reports.every((r) => r.pass)\n lines.push(overall ? '## ✅ agent-eval gate: pass' : '## ❌ agent-eval gate: fail')\n lines.push('')\n for (const r of reports) {\n lines.push(`### ${r.name} ${r.pass ? '✅' : '❌'}`)\n if (r.breaches.length > 0) {\n lines.push('')\n lines.push('**Breaches:**')\n for (const b of r.breaches) lines.push(`- ${b}`)\n }\n if (r.baselineReport.metrics.length > 0) {\n lines.push('')\n lines.push('| metric | baseline | candidate | Δ | Cohen d | p | verdict |')\n lines.push('|---|---|---|---|---|---|---|')\n for (const m of r.baselineReport.metrics) {\n lines.push(\n `| ${m.metric} | ${m.baselineMean.toFixed(4)} | ${m.candidateMean.toFixed(4)} | ${m.delta.toFixed(4)} | ${m.cohensD.toFixed(2)} | ${m.welchP.toExponential(2)} | ${m.verdict} |`,\n )\n }\n }\n if (r.sloReport && r.sloReport.results.length > 0) {\n lines.push('')\n lines.push('**SLO results:**')\n for (const s of r.sloReport.results) {\n lines.push(`- ${s.slo.id} (${s.slo.severity}): ${s.passed ? 'ok' : 'breach'} — ${s.detail}`)\n }\n }\n lines.push('')\n }\n return lines.join('\\n')\n}\n\n/** Aggregate per-run metrics into the single record expected by `checkSlos`. */\nasync function aggregateRunMetrics(\n runs: Run[],\n store: TraceStore,\n): Promise<Record<string, number>> {\n if (runs.length === 0) return {}\n const durations: number[] = []\n const scores: number[] = []\n const passes: number[] = []\n const costs: number[] = []\n for (const r of runs) {\n if (r.endedAt) durations.push(r.endedAt - r.startedAt)\n if (r.outcome?.score !== undefined) scores.push(r.outcome.score)\n passes.push(r.outcome?.pass === true ? 1 : 0)\n const llm = await llmSpans(store, r.runId)\n costs.push(aggregateLlm(llm).costUsd)\n }\n return {\n provisionMs: average(durations),\n firstTokenMs: average(durations),\n wallMs: average(durations),\n overallScore: average(scores),\n passRate: average(passes),\n costUsd: average(costs),\n }\n}\n\nfunction average(xs: number[]): number {\n if (xs.length === 0) return 0\n return xs.reduce((a, b) => a + b, 0) / xs.length\n}\n\nasync function extractAll(\n runs: Run[],\n extract: (r: Run, s: TraceStore) => Promise<number | null>,\n store: TraceStore,\n): Promise<number[]> {\n const out: number[] = []\n for (const r of runs) {\n const v = await extract(r, store)\n if (v !== null && Number.isFinite(v)) out.push(v)\n }\n return out\n}\n\nfunction defaultExtract(metric: string): (run: Run, store: TraceStore) => Promise<number | null> {\n return async (run, store) => {\n switch (metric) {\n case 'score':\n case 'overallScore':\n return run.outcome?.score ?? null\n case 'pass':\n return run.outcome?.pass === true ? 1 : 0\n case 'durationMs':\n return run.endedAt && run.startedAt ? run.endedAt - run.startedAt : null\n case 'costUsd': {\n const llm = await llmSpans(store, run.runId)\n return aggregateLlm(llm).costUsd\n }\n case 'successClass':\n return runFailureClass(run) === 'success' ? 1 : 0\n default:\n return null\n }\n }\n}\n","/**\n * Observability adapters — bidirectional parity with production backends.\n *\n * `LangfuseAdapter` maps a Run's spans into Langfuse generation/score\n * records (schema-compatible; we don't depend on the SDK — consumers\n * POST the returned JSON to their Langfuse collector).\n *\n * `PrometheusEmitter` converts a TraceStore into a Prometheus text-\n * exposition-format string (counters + gauges for runs, tool calls,\n * errors, cost). Drop into a `/metrics` handler; no SDK needed.\n *\n * `replayTraceThroughJudge` is the canonical \"re-score with a new\n * judge\" path — takes an existing run, runs a judge function over\n * each LLM span, emits JudgeVerdict spans back into the store.\n */\n\nimport { NotFoundError } from './errors'\nimport { TraceEmitter } from './trace/emitter'\nimport { aggregateLlm, llmSpans } from './trace/query'\nimport type { LlmSpan, Span } from './trace/schema'\nimport type { TraceStore } from './trace/store'\n\n// ── Langfuse adapter ─────────────────────────────────────────────────\n\nexport interface LangfuseGeneration {\n id: string\n traceId: string\n name: string\n model: string\n input: unknown\n output: unknown\n startTime: string\n endTime: string\n usage: { input: number; output: number; total: number; totalCost: number }\n metadata: Record<string, unknown>\n}\n\nexport interface LangfuseScore {\n id: string\n traceId: string\n observationId: string\n name: string\n value: number\n comment?: string\n}\n\nexport interface LangfuseEnvelope {\n traceId: string\n generations: LangfuseGeneration[]\n scores: LangfuseScore[]\n}\n\nexport async function toLangfuseEnvelope(\n store: TraceStore,\n runId: string,\n): Promise<LangfuseEnvelope> {\n const run = await store.getRun(runId)\n if (!run) throw new NotFoundError(`run ${runId} not found`)\n const llm = await llmSpans(store, runId)\n const allSpans = await store.spans({ runId })\n const judges = allSpans.filter((s): s is Extract<Span, { kind: 'judge' }> => s.kind === 'judge')\n\n const generations: LangfuseGeneration[] = llm.map((s) => ({\n id: s.spanId,\n traceId: run.runId,\n name: s.name,\n model: s.model,\n input: s.messages,\n output: s.output,\n startTime: new Date(s.startedAt).toISOString(),\n endTime: new Date(s.endedAt ?? s.startedAt).toISOString(),\n usage: {\n input: s.inputTokens ?? 0,\n output: s.outputTokens ?? 0,\n total: (s.inputTokens ?? 0) + (s.outputTokens ?? 0),\n totalCost: s.costUsd ?? 0,\n },\n metadata: { finishReason: s.finishReason, cachedTokens: s.cachedTokens },\n }))\n\n const scores: LangfuseScore[] = judges.map((j) => ({\n id: j.spanId,\n traceId: run.runId,\n observationId: j.targetSpanId,\n name: `${j.judgeId}/${j.dimension}`,\n value: j.score,\n comment: j.rationale,\n }))\n\n return { traceId: run.runId, generations, scores }\n}\n\n// ── Prometheus emitter ───────────────────────────────────────────────\n\nexport async function toPrometheusText(store: TraceStore): Promise<string> {\n const runs = await store.listRuns()\n const toolCalls: Record<string, number> = {}\n const toolErrors: Record<string, number> = {}\n let totalLlmInputTokens = 0\n let totalLlmOutputTokens = 0\n let totalCostUsd = 0\n let passedRuns = 0\n let failedRuns = 0\n for (const r of runs) {\n if (r.outcome?.pass === true) passedRuns++\n else if (r.outcome?.pass === false) failedRuns++\n const llm = await llmSpans(store, r.runId)\n const agg = aggregateLlm(llm)\n totalLlmInputTokens += agg.inputTokens\n totalLlmOutputTokens += agg.outputTokens\n totalCostUsd += agg.costUsd\n const tools = await store.spans({ runId: r.runId, kind: 'tool' })\n for (const t of tools) {\n if (t.kind !== 'tool') continue\n toolCalls[t.toolName] = (toolCalls[t.toolName] ?? 0) + 1\n if (t.status === 'error') toolErrors[t.toolName] = (toolErrors[t.toolName] ?? 0) + 1\n }\n }\n\n const lines: string[] = []\n lines.push('# HELP agent_eval_runs_total Total runs in the trace corpus')\n lines.push('# TYPE agent_eval_runs_total counter')\n lines.push(`agent_eval_runs_total ${runs.length}`)\n lines.push('# HELP agent_eval_runs_passed_total Runs that completed with pass=true')\n lines.push('# TYPE agent_eval_runs_passed_total counter')\n lines.push(`agent_eval_runs_passed_total ${passedRuns}`)\n lines.push('# HELP agent_eval_runs_failed_total Runs that completed with pass=false')\n lines.push('# TYPE agent_eval_runs_failed_total counter')\n lines.push(`agent_eval_runs_failed_total ${failedRuns}`)\n lines.push('# HELP agent_eval_llm_input_tokens_total Aggregate LLM input tokens')\n lines.push('# TYPE agent_eval_llm_input_tokens_total counter')\n lines.push(`agent_eval_llm_input_tokens_total ${totalLlmInputTokens}`)\n lines.push('# HELP agent_eval_llm_output_tokens_total Aggregate LLM output tokens')\n lines.push('# TYPE agent_eval_llm_output_tokens_total counter')\n lines.push(`agent_eval_llm_output_tokens_total ${totalLlmOutputTokens}`)\n lines.push('# HELP agent_eval_cost_usd_total Aggregate LLM cost in USD')\n lines.push('# TYPE agent_eval_cost_usd_total counter')\n lines.push(`agent_eval_cost_usd_total ${totalCostUsd}`)\n lines.push('# HELP agent_eval_tool_calls_total Tool calls by tool name')\n lines.push('# TYPE agent_eval_tool_calls_total counter')\n for (const [name, n] of Object.entries(toolCalls)) {\n lines.push(`agent_eval_tool_calls_total{tool=\"${escapeLabel(name)}\"} ${n}`)\n }\n lines.push('# HELP agent_eval_tool_errors_total Tool errors by tool name')\n lines.push('# TYPE agent_eval_tool_errors_total counter')\n for (const [name, n] of Object.entries(toolErrors)) {\n lines.push(`agent_eval_tool_errors_total{tool=\"${escapeLabel(name)}\"} ${n}`)\n }\n return `${lines.join('\\n')}\\n`\n}\n\nfunction escapeLabel(v: string): string {\n return v.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"').replace(/\\n/g, '\\\\n')\n}\n\n// ── Retroactive re-scoring via judge replay ──────────────────────────\n\nexport interface JudgeReplayResult {\n spanId: string\n targetSpanId: string\n dimension: string\n score: number\n rationale?: string\n}\n\n/**\n * Apply a judge function to every LLM span in a run and record the\n * results as JudgeVerdict spans. This is the canonical \"no re-execution\"\n * re-scoring path — you supply a pure judge `(llmSpan) → verdict`.\n */\nexport async function replayTraceThroughJudge(\n store: TraceStore,\n runId: string,\n judge: {\n id: string\n dimension: string\n score: (span: LlmSpan) => Promise<{ score: number; rationale?: string; evidence?: string }>\n },\n): Promise<JudgeReplayResult[]> {\n const run = await store.getRun(runId)\n if (!run) throw new NotFoundError(`run ${runId} not found`)\n const llms = await llmSpans(store, runId)\n const emitter = new TraceEmitter(store, { runId })\n const results: JudgeReplayResult[] = []\n for (const span of llms) {\n const { score, rationale, evidence } = await judge.score(span)\n const verdict = await emitter.recordJudge({\n judgeId: judge.id,\n targetSpanId: span.spanId,\n dimension: judge.dimension,\n score,\n rationale,\n evidence,\n name: `${judge.id}/${judge.dimension}`,\n })\n results.push({\n spanId: verdict.spanId,\n targetSpanId: span.spanId,\n dimension: judge.dimension,\n score,\n rationale,\n })\n }\n return results\n}\n","/**\n * Paraphrase robustness — mutates a scenario prompt in structure-\n * preserving ways, re-scores, and reports score variance.\n *\n * Mutators are pure functions `(prompt: string) => string`. Ship a\n * default set; consumers add domain-specific ones.\n *\n * Robustness score: 1 - stdDev(scores) / (mean if positive else 1).\n * A perfect agent returns the same answer regardless of typo / case /\n * reordering — any variance signals a brittle prompt.\n */\n\nexport type Mutator = (prompt: string, seed: number) => string\n\nexport interface RobustnessResult {\n originalScore: number\n variantScores: Array<{ mutator: string; score: number; mutated: string }>\n meanScore: number\n stdDev: number\n robustness: number\n}\n\nexport async function paraphraseRobustness(\n prompt: string,\n mutators: Array<{ id: string; fn: Mutator }>,\n scoreFn: (prompt: string) => Promise<number>,\n options: { seed?: number } = {},\n): Promise<RobustnessResult> {\n const seed = options.seed ?? 1\n const originalScore = await scoreFn(prompt)\n const variantScores: RobustnessResult['variantScores'] = []\n const all: number[] = [originalScore]\n for (const { id, fn } of mutators) {\n const mutated = fn(prompt, seed)\n const score = await scoreFn(mutated)\n variantScores.push({ mutator: id, score, mutated })\n all.push(score)\n }\n const mean = all.reduce((a, b) => a + b, 0) / all.length\n const variance = all.reduce((a, v) => a + (v - mean) ** 2, 0) / all.length\n const stdDev = Math.sqrt(variance)\n const ref = Math.abs(mean) > 1e-9 ? Math.abs(mean) : 1\n const robustness = Math.max(0, 1 - stdDev / ref)\n return { originalScore, variantScores, meanScore: mean, stdDev, robustness }\n}\n\n// ── Built-in mutators ────────────────────────────────────────────────\n\n/** Lowercase the whole prompt. Robust models ignore case. */\nexport const lowercaseMutator: Mutator = (p) => p.toLowerCase()\n\n/** Reorder sentences. Robust models don't depend on sentence order. */\nexport const sentenceReorderMutator: Mutator = (p, seed) => {\n const sentences = p.split(/(?<=[.!?])\\s+/).filter(Boolean)\n if (sentences.length <= 1) return p\n const shuffled = [...sentences]\n let s = seed >>> 0\n for (let i = shuffled.length - 1; i > 0; i--) {\n s = (s * 1103515245 + 12345) >>> 0\n const j = s % (i + 1)\n ;[shuffled[i], shuffled[j]] = [shuffled[j]!, shuffled[i]!]\n }\n return shuffled.join(' ')\n}\n\n/** Swap adjacent letter pairs (1 per 40 chars, min 1). Robust models tolerate typos. */\nexport const typoMutator: Mutator = (p, seed) => {\n if (p.length < 5) return p\n const chars = p.split('')\n let s = seed >>> 0\n const count = Math.max(1, Math.floor(chars.length / 40))\n for (let n = 0; n < count; n++) {\n for (let attempt = 0; attempt < 20; attempt++) {\n s = (s * 1103515245 + 12345) >>> 0\n const idx = s % (chars.length - 1)\n const a = chars[idx]!\n const b = chars[idx + 1]!\n if (a !== b && /[A-Za-z]/.test(a) && /[A-Za-z]/.test(b)) {\n chars[idx] = b\n chars[idx + 1] = a\n break\n }\n }\n }\n return chars.join('')\n}\n\n/** Add a benign politeness prefix. Robust models ignore flattery. */\nexport const politenessPrefixMutator: Mutator = (p) => `Please, if you would be so kind: ${p}`\n\n/** Compact whitespace, strip newlines. Robust models don't depend on formatting. */\nexport const whitespaceCollapseMutator: Mutator = (p) => p.replace(/\\s+/g, ' ').trim()\n\nexport const DEFAULT_MUTATORS: Array<{ id: string; fn: Mutator }> = [\n { id: 'lowercase', fn: lowercaseMutator },\n { id: 'sentence-reorder', fn: sentenceReorderMutator },\n { id: 'typo', fn: typoMutator },\n { id: 'politeness-prefix', fn: politenessPrefixMutator },\n { id: 'whitespace-collapse', fn: whitespaceCollapseMutator },\n]\n\n// ── Multi-turn scenario convenience wrapper ──────────────────────────\n\nexport interface ParaphraseRobustnessScenarioInput {\n scenarios: Array<{ id: string; userTurns: string[] }>\n /**\n * Mutators applied to every user turn in every scenario. Each\n * scenario is paraphrased once per mutator (so `reps` × `scenarios`\n * × `mutators` total paraphrased runs).\n */\n mutators: Array<{ name: string; mutator: (text: string) => string }>\n /**\n * Run a (possibly mutated) scenario and return its score in [0,1].\n * Called once for the original turns of each scenario, and once per\n * (scenario × mutator × rep) for the paraphrased variants.\n */\n runScenario: (args: { id: string; userTurns: string[] }) => Promise<{ score: number }>\n /** Times to repeat each (scenario × mutator) pair. Default 1. */\n reps?: number\n}\n\nexport interface ParaphraseRobustnessScenarioResult {\n /**\n * Aggregate robustness: `mean(paraphrased) / mean(original)`,\n * clipped to `[0, 1]`. `1` = paraphrasing didn't degrade the agent;\n * `0` = paraphrasing destroyed it (or original was 0).\n */\n score: number\n perScenario: Array<{\n id: string\n originalScore: number\n paraphrasedMean: number\n /** Per-mutator delta (paraphrased − original); negative = mutator hurt. */\n deltas: Record<string, number>\n }>\n mutators: string[]\n}\n\n/**\n * Multi-turn convenience wrapper around {@link paraphraseRobustness}.\n *\n * Consumers with a list of multi-turn scenarios were hand-wrapping the\n * single-prompt runner per scenario; this iterates for them. Mutators\n * are applied to every user turn (mutator runs once per turn with a\n * stable seed derived from the rep index).\n *\n * Contract:\n * - Calls `runScenario` once with the original `userTurns` to\n * establish the baseline `originalScore`.\n * - For each `(scenario, mutator, rep)` combination, builds a\n * mutated copy of `userTurns` (every turn passed through\n * `mutator.mutator`) and calls `runScenario` again.\n * - Aggregates per-scenario means, then computes the overall\n * `mean(paraphrasedMean) / mean(originalScore)`, clipped to\n * `[0, 1]`. If every original score is 0 the aggregate is 0.\n */\nexport async function paraphraseRobustnessScenarios(\n args: ParaphraseRobustnessScenarioInput,\n): Promise<ParaphraseRobustnessScenarioResult> {\n const reps = Math.max(1, args.reps ?? 1)\n const mutatorNames = args.mutators.map((m) => m.name)\n\n const perScenario: ParaphraseRobustnessScenarioResult['perScenario'] = []\n\n for (const scenario of args.scenarios) {\n const baseline = await args.runScenario({\n id: scenario.id,\n userTurns: scenario.userTurns,\n })\n const originalScore = baseline.score\n\n const deltas: Record<string, number> = {}\n const paraphrasedAll: number[] = []\n\n for (const m of args.mutators) {\n const scores: number[] = []\n for (let r = 0; r < reps; r++) {\n const mutatedTurns = scenario.userTurns.map((t) => m.mutator(t))\n const out = await args.runScenario({\n id: scenario.id,\n userTurns: mutatedTurns,\n })\n scores.push(out.score)\n }\n const mean = scores.reduce((a, b) => a + b, 0) / scores.length\n deltas[m.name] = mean - originalScore\n paraphrasedAll.push(...scores)\n }\n\n const paraphrasedMean =\n paraphrasedAll.length === 0\n ? originalScore\n : paraphrasedAll.reduce((a, b) => a + b, 0) / paraphrasedAll.length\n\n perScenario.push({ id: scenario.id, originalScore, paraphrasedMean, deltas })\n }\n\n const meanOriginal =\n perScenario.length === 0\n ? 0\n : perScenario.reduce((a, p) => a + p.originalScore, 0) / perScenario.length\n const meanParaphrased =\n perScenario.length === 0\n ? 0\n : perScenario.reduce((a, p) => a + p.paraphrasedMean, 0) / perScenario.length\n\n const ratio = meanOriginal <= 0 ? 0 : meanParaphrased / meanOriginal\n const score = Math.max(0, Math.min(1, ratio))\n\n return { score, perScenario, mutators: mutatorNames }\n}\n","/**\n * Visual diff — pixel-delta scoring for UI / visual outputs.\n *\n * Minimal dependency-free implementation: accepts two PNGs as byte\n * arrays + width/height and returns a Δ ratio + per-channel histogram.\n * Consumers supply the decoded pixel arrays (we don't pull a PNG\n * decoder into the core — use `sharp`, `@napi-rs/canvas`, or Playwright\n * in the driving test and pass the result here).\n */\n\nimport { ValidationError } from './errors'\n\nexport interface ImageData {\n width: number\n height: number\n /** Pixel data in RGBA order, 4 bytes per pixel. */\n data: Uint8Array | Uint8ClampedArray\n}\n\nexport interface VisualDiffResult {\n /** Ratio of pixels differing beyond `tolerance` (0..1). */\n diffRatio: number\n differingPixels: number\n totalPixels: number\n maxChannelDelta: number\n /** Status for dashboards: unchanged (< 0.1%), changed, or severely-changed (> 5%). */\n status: 'unchanged' | 'changed' | 'severely-changed'\n}\n\nexport interface VisualDiffOptions {\n /** Pixels whose max-channel delta is ≤ this are considered unchanged. Default 8/255. */\n tolerance?: number\n}\n\nexport function visualDiff(\n a: ImageData,\n b: ImageData,\n options: VisualDiffOptions = {},\n): VisualDiffResult {\n if (a.width !== b.width || a.height !== b.height) {\n throw new ValidationError(\n `visualDiff: image dims differ (${a.width}x${a.height} vs ${b.width}x${b.height})`,\n )\n }\n if (a.data.length !== b.data.length) {\n throw new ValidationError('visualDiff: image data length mismatch')\n }\n const tolerance = options.tolerance ?? 8\n const totalPixels = a.width * a.height\n let differing = 0\n let maxDelta = 0\n for (let i = 0; i < a.data.length; i += 4) {\n const dr = Math.abs(a.data[i]! - b.data[i]!)\n const dg = Math.abs(a.data[i + 1]! - b.data[i + 1]!)\n const db = Math.abs(a.data[i + 2]! - b.data[i + 2]!)\n const da = Math.abs(a.data[i + 3]! - b.data[i + 3]!)\n const worst = Math.max(dr, dg, db, da)\n if (worst > maxDelta) maxDelta = worst\n if (worst > tolerance) differing++\n }\n const diffRatio = totalPixels > 0 ? differing / totalPixels : 0\n const status = diffRatio < 0.001 ? 'unchanged' : diffRatio > 0.05 ? 'severely-changed' : 'changed'\n return { diffRatio, differingPixels: differing, totalPixels, maxChannelDelta: maxDelta, status }\n}\n\n/** Convenience: diffs two byte-identical-dim RGBA arrays, returns just the ratio. */\nexport function pixelDeltaRatio(\n a: Uint8Array,\n b: Uint8Array,\n width: number,\n height: number,\n tolerance = 8,\n): number {\n return visualDiff({ width, height, data: a }, { width, height, data: b }, { tolerance }).diffRatio\n}\n","/**\n * Bisector — auto-locate the change that introduced an eval regression.\n *\n * Two shapes:\n * - `commitBisect` — walk an ordered SHA list, binary-search for the\n * first commit that fails.\n * - `promptBisect` — given a good and bad prompt, progressively port\n * paragraphs from good→bad to localize the breaking change.\n *\n * Generic `bisect<T>` lets callers drive any ordered state space\n * (dataset versions, config files, CLI flag combinations).\n */\n\nexport interface BisectOptions<T> {\n /** State known to pass. */\n good: T\n /** State known to fail. */\n bad: T\n /** Equality test on state values — default Object.is. */\n equals?: (a: T, b: T) => boolean\n /** Pick the halfway state between good + bad. Return null when no further\n * split is possible (e.g. adjacent commits). */\n halfway: (good: T, bad: T) => T | null\n /** Produce a verdict for a state. */\n runEval: (state: T) => Promise<{ score: number; pass: boolean }>\n /** Hard cap on iterations (default 40 — covers ~1T ordered states). */\n maxIterations?: number\n}\n\nexport interface BisectStep<T> {\n state: T\n score: number\n pass: boolean\n}\n\nexport interface BisectResult<T> {\n /** The first bad state — typically `bad` in the final (good, bad) adjacent pair. */\n culprit: T\n /** Ordered trace of all states evaluated. */\n path: BisectStep<T>[]\n /** True when we narrowed to an adjacent (good, bad) pair. */\n converged: boolean\n /** True when `good` itself failed or `bad` itself passed — the caller's\n * premise was broken. */\n inputInconsistent: boolean\n}\n\nexport async function bisect<T>(options: BisectOptions<T>): Promise<BisectResult<T>> {\n const equals = options.equals ?? ((a, b) => Object.is(a, b))\n const maxIter = options.maxIterations ?? 40\n const path: BisectStep<T>[] = []\n\n const goodVerdict = await options.runEval(options.good)\n path.push({ state: options.good, ...goodVerdict })\n const badVerdict = await options.runEval(options.bad)\n path.push({ state: options.bad, ...badVerdict })\n\n if (!goodVerdict.pass) {\n return { culprit: options.good, path, converged: false, inputInconsistent: true }\n }\n if (badVerdict.pass) {\n return { culprit: options.bad, path, converged: false, inputInconsistent: true }\n }\n\n let good = options.good\n let bad = options.bad\n for (let i = 0; i < maxIter; i++) {\n const mid = options.halfway(good, bad)\n if (mid === null || equals(mid, good) || equals(mid, bad)) {\n return { culprit: bad, path, converged: true, inputInconsistent: false }\n }\n const v = await options.runEval(mid)\n path.push({ state: mid, ...v })\n if (v.pass) good = mid\n else bad = mid\n }\n return { culprit: bad, path, converged: false, inputInconsistent: false }\n}\n\n/**\n * Commit bisect — `commits` is an ordered SHA list, oldest to newest.\n * `good` and `bad` must both be present in the list.\n */\nexport async function commitBisect(options: {\n commits: string[]\n good: string\n bad: string\n runEval: (sha: string) => Promise<{ score: number; pass: boolean }>\n maxIterations?: number\n}): Promise<BisectResult<string>> {\n const { commits } = options\n const goodIdx = commits.indexOf(options.good)\n const badIdx = commits.indexOf(options.bad)\n if (goodIdx < 0 || badIdx < 0) {\n throw new Error(\n `commitBisect: good or bad SHA not in commit list (good=${options.good}, bad=${options.bad})`,\n )\n }\n if (goodIdx >= badIdx) {\n throw new Error('commitBisect: good must precede bad in the commit list')\n }\n return bisect<string>({\n good: options.good,\n bad: options.bad,\n runEval: options.runEval,\n maxIterations: options.maxIterations,\n halfway: (g, b) => {\n const gi = commits.indexOf(g)\n const bi = commits.indexOf(b)\n if (bi - gi <= 1) return null\n return commits[Math.floor((gi + bi) / 2)] ?? null\n },\n })\n}\n\n/**\n * Prompt bisect — splits the good and bad prompts into paragraphs, then\n * progressively replaces paragraphs in `good` with their counterparts\n * from `bad` to localize the offending change. Only works when the two\n * prompts have the same paragraph count (a common editorial workflow\n * constraint — one paragraph = one change unit).\n */\nexport async function promptBisect(options: {\n good: string\n bad: string\n runEval: (prompt: string) => Promise<{ score: number; pass: boolean }>\n maxIterations?: number\n paragraphSplitter?: (prompt: string) => string[]\n}): Promise<BisectResult<string> & { offendingParagraphIndex?: number }> {\n const split = options.paragraphSplitter ?? ((p: string) => p.split(/\\n\\s*\\n/))\n const join = (paragraphs: string[]) => paragraphs.join('\\n\\n')\n const goodParas = split(options.good)\n const badParas = split(options.bad)\n if (goodParas.length !== badParas.length) {\n throw new Error(\n `promptBisect: paragraph count mismatch (${goodParas.length} vs ${badParas.length})`,\n )\n }\n if (goodParas.length < 2) {\n throw new Error('promptBisect: need at least 2 paragraphs to bisect')\n }\n // Represent state as a bit-mask of which paragraphs come from `bad`.\n // good = all-zero, bad = all-one; halfway = flip the midpoint half.\n const n = goodParas.length\n const goodMask = '0'.repeat(n)\n const badMask = '1'.repeat(n)\n\n function paragraphsFor(mask: string): string[] {\n return mask.split('').map((c, i) => (c === '1' ? badParas[i]! : goodParas[i]!))\n }\n\n const result = await bisect<string>({\n good: goodMask,\n bad: badMask,\n runEval: (mask) => options.runEval(join(paragraphsFor(mask))),\n maxIterations: options.maxIterations ?? n + 5,\n halfway: (g, b) => {\n // Pick the first differing position and flip it.\n for (let i = 0; i < g.length; i++) {\n if (g[i] !== b[i]) {\n // Flip the midpoint between the remaining diff positions.\n const differing: number[] = []\n for (let j = i; j < g.length; j++) if (g[j] !== b[j]) differing.push(j)\n if (differing.length === 0) return null\n if (differing.length === 1) return null // adjacent — can't narrow further\n // Flip the first half of differing positions from good → bad.\n const flip = differing.slice(0, Math.ceil(differing.length / 2))\n const chars = g.split('')\n for (const f of flip) chars[f] = b[f]!\n return chars.join('')\n }\n }\n return null\n },\n equals: (a, b) => a === b,\n })\n\n // Identify the offending paragraph as the index that changed between the\n // last good and final bad in the path.\n let offendingParagraphIndex: number | undefined\n const lastGood = result.path.filter((s) => s.pass).pop()\n const culprit = result.culprit\n if (lastGood) {\n for (let i = 0; i < n; i++) {\n if (lastGood.state[i] !== culprit[i]) {\n offendingParagraphIndex = i\n break\n }\n }\n }\n\n // Materialize path states back into full prompts for caller consumption.\n const materializedPath: BisectStep<string>[] = result.path.map((s) => ({\n state: join(paragraphsFor(s.state)),\n score: s.score,\n pass: s.pass,\n }))\n\n return {\n culprit: join(paragraphsFor(culprit)),\n path: materializedPath,\n converged: result.converged,\n inputInconsistent: result.inputInconsistent,\n offendingParagraphIndex,\n }\n}\n","/**\n * Counterfactual replay — \"what would have happened if we'd changed\n * exactly one thing at turn N?\"\n *\n * The framework does NOT drive the agent — it sets up the replay\n * context (prior spans, prior state, mutation spec) and records the\n * resulting divergence. Consumers supply an `executeFrom(ctx)` callback\n * that runs their agent starting from turn N with the mutation applied.\n *\n * Counterfactual runs are recorded as a new Run with `layer='meta'` and\n * `parentRunId = originalRunId`, so downstream diff + correlation\n * pipelines see them natively.\n */\n\nimport { NotFoundError, ValidationError } from './errors'\nimport { TraceEmitter } from './trace/emitter'\nimport type { LlmSpan, Span, ToolSpan } from './trace/schema'\nimport type { TraceStore } from './trace/store'\nimport { buildTrajectory, type Trajectory, type TrajectoryStep } from './trajectory'\n\nexport type CounterfactualMutation =\n | { kind: 'swap-model'; at: number; newModel: string }\n | { kind: 'swap-tool-result'; at: number; newResult: unknown }\n | { kind: 'truncate-after'; at: number }\n | { kind: 'inject-system-message'; at: number; content: string }\n | {\n kind: 'custom'\n at: number\n describe: string\n apply: (step: TrajectoryStep) => TrajectoryStep\n }\n\nexport interface CounterfactualContext {\n originalRunId: string\n originalTrajectory: Trajectory\n /** Steps up to (but not including) the mutation point — the prefix the\n * replayed agent inherits as its prior conversation/tool history. */\n prefix: TrajectoryStep[]\n mutation: CounterfactualMutation\n /** Pre-applied mutation on the step at `mutation.at`. Consumers use this\n * as the FIRST step the replayed agent emits (they decide whether to\n * re-emit it or continue from there). */\n mutatedStep: TrajectoryStep\n}\n\nexport interface CounterfactualResult {\n counterfactualRunId: string\n originalRunId: string\n mutation: CounterfactualMutation\n /** Structured delta summary — caller can extend via scoring. */\n delta: {\n originalOutcomeScore: number | null\n counterfactualOutcomeScore: number | null\n deltaScore: number | null\n }\n}\n\nexport interface CounterfactualRunner {\n /**\n * Execute the agent from `ctx.prefix` with the mutation applied.\n * MUST emit spans into the provided emitter so they become part of\n * the counterfactual run. MUST call emitter.endRun() with a verdict.\n */\n executeFrom: (ctx: CounterfactualContext, emitter: TraceEmitter) => Promise<void>\n}\n\nexport async function runCounterfactual(\n store: TraceStore,\n originalRunId: string,\n mutation: CounterfactualMutation,\n runner: CounterfactualRunner,\n): Promise<CounterfactualResult> {\n const originalRun = await store.getRun(originalRunId)\n if (!originalRun) throw new NotFoundError(`counterfactual: run ${originalRunId} not found`)\n const trajectory = await buildTrajectory(store, originalRunId)\n if (mutation.at < 0 || mutation.at >= trajectory.steps.length) {\n throw new ValidationError(\n `counterfactual: mutation.at=${mutation.at} out of range [0, ${trajectory.steps.length})`,\n )\n }\n const targetStep = trajectory.steps[mutation.at]!\n const mutatedStep = applyMutation(targetStep, mutation)\n\n const cfEmitter = new TraceEmitter(store)\n await cfEmitter.startRun({\n scenarioId: originalRun.scenarioId,\n variantId: originalRun.variantId\n ? `${originalRun.variantId}+cf:${mutation.kind}@${mutation.at}`\n : `cf:${mutation.kind}@${mutation.at}`,\n projectId: originalRun.projectId,\n parentRunId: originalRunId,\n layer: 'meta',\n tags: { counterfactual: 'true', mutationKind: mutation.kind, mutationAt: String(mutation.at) },\n })\n\n await runner.executeFrom(\n {\n originalRunId,\n originalTrajectory: trajectory,\n prefix: trajectory.steps.slice(0, mutation.at),\n mutation,\n mutatedStep,\n },\n cfEmitter,\n )\n\n const counterfactual = await store.getRun(cfEmitter.runId)\n const delta = {\n originalOutcomeScore: originalRun.outcome?.score ?? null,\n counterfactualOutcomeScore: counterfactual?.outcome?.score ?? null,\n deltaScore:\n originalRun.outcome?.score !== undefined && counterfactual?.outcome?.score !== undefined\n ? counterfactual.outcome.score - originalRun.outcome.score\n : null,\n }\n return { counterfactualRunId: cfEmitter.runId, originalRunId, mutation, delta }\n}\n\nfunction applyMutation(step: TrajectoryStep, mutation: CounterfactualMutation): TrajectoryStep {\n if (mutation.kind === 'swap-model' && step.span.kind === 'llm') {\n const llm = step.span as LlmSpan\n return { ...step, span: { ...llm, model: mutation.newModel } }\n }\n if (mutation.kind === 'swap-tool-result' && step.span.kind === 'tool') {\n const tool = step.span as ToolSpan\n return { ...step, span: { ...tool, result: mutation.newResult } }\n }\n if (mutation.kind === 'inject-system-message' && step.span.kind === 'llm') {\n const llm = step.span as LlmSpan\n return {\n ...step,\n span: {\n ...llm,\n messages: [{ role: 'system', content: mutation.content }, ...llm.messages],\n },\n }\n }\n if (mutation.kind === 'custom') return mutation.apply(step)\n // swap-tool-result on non-tool span / swap-model on non-llm / truncate-after: no step-level change.\n return step\n}\n\n/**\n * Aggregate a batch of counterfactuals into a simple attribution table:\n * which mutation kinds move outcomes most? (Useful when you run a grid\n * over the same trajectory — swap-model at every llm span, swap-tool\n * at every tool span — and want a ranked summary.)\n */\nexport function attributeCounterfactuals(results: CounterfactualResult[]): Array<{\n mutationKind: CounterfactualMutation['kind']\n n: number\n meanAbsDelta: number\n meanSignedDelta: number\n}> {\n const grouped = new Map<string, CounterfactualResult[]>()\n for (const r of results) {\n const arr = grouped.get(r.mutation.kind) ?? []\n arr.push(r)\n grouped.set(r.mutation.kind, arr)\n }\n const out: Array<{\n mutationKind: CounterfactualMutation['kind']\n n: number\n meanAbsDelta: number\n meanSignedDelta: number\n }> = []\n for (const [kind, items] of grouped) {\n const deltas = items\n .map((i) => i.delta.deltaScore)\n .filter((d): d is number => typeof d === 'number')\n if (deltas.length === 0) continue\n const meanAbs = deltas.reduce((a, b) => a + Math.abs(b), 0) / deltas.length\n const meanSigned = deltas.reduce((a, b) => a + b, 0) / deltas.length\n out.push({\n mutationKind: kind as CounterfactualMutation['kind'],\n n: deltas.length,\n meanAbsDelta: meanAbs,\n meanSignedDelta: meanSigned,\n })\n }\n return out.sort((a, b) => b.meanAbsDelta - a.meanAbsDelta)\n}\n\n// Re-export Span type for consumer ergonomics.\nexport type { Span }\n","/**\n * Full cross-trace diff — align two trajectories step-by-step, report\n * per-step score deltas, attribute a variant's total outcome lead to\n * specific turns.\n *\n * 0.5 shipped `firstDivergenceView` (finds the first differing step).\n * This does the heavier work: full alignment via LCS, per-step\n * contribution to score delta using PRM verdicts when available,\n * fallback to structural heuristics (latency, token count, tool\n * outcome) otherwise.\n */\n\nimport type { JudgeSpan, Span } from './trace/schema'\nimport { isJudgeSpan } from './trace/schema'\nimport type { TraceStore } from './trace/store'\nimport { buildTrajectory, type TrajectoryStep } from './trajectory'\n\nexport type AlignmentOp =\n | { op: 'match'; a: TrajectoryStep; b: TrajectoryStep }\n | { op: 'insert'; b: TrajectoryStep }\n | { op: 'delete'; a: TrajectoryStep }\n | { op: 'replace'; a: TrajectoryStep; b: TrajectoryStep }\n\nexport interface StepAttribution {\n op: AlignmentOp\n /** Difference in PRM score (or null when not scored by a matching judge). */\n prmDelta: number | null\n /** Difference in latency (endedAt - startedAt). */\n latencyDeltaMs: number | null\n /** Difference in token count (LLM spans). */\n tokenDelta: number | null\n /** Reason this step is / isn't considered a contributor to the outcome delta. */\n note: string\n}\n\nexport interface CrossTraceDiff {\n runA: string\n runB: string\n alignment: AlignmentOp[]\n attributions: StepAttribution[]\n /** Total score delta (B - A). */\n totalScoreDelta: number | null\n /** Sum of PRM deltas across matched/replaced steps. Close to\n * `totalScoreDelta` when PRM covers the trajectory; gap indicates\n * unmodeled variance. */\n prmDeltaSum: number\n}\n\nexport interface CrossTraceDiffOptions {\n stepEquals?: (a: TrajectoryStep, b: TrajectoryStep) => boolean\n}\n\nexport async function crossTraceDiff(\n store: TraceStore,\n runA: string,\n runB: string,\n options: CrossTraceDiffOptions = {},\n): Promise<CrossTraceDiff> {\n const [a, b] = await Promise.all([buildTrajectory(store, runA), buildTrajectory(store, runB)])\n const eq = options.stepEquals ?? defaultStepEquals\n const alignment = align(a.steps, b.steps, eq)\n\n const [judgesA, judgesB] = await Promise.all([\n store.spans({ runId: runA, kind: 'judge' }).then((s) => s.filter(isJudgeSpan)),\n store.spans({ runId: runB, kind: 'judge' }).then((s) => s.filter(isJudgeSpan)),\n ])\n const prmByTargetA = indexPrmByTarget(judgesA)\n const prmByTargetB = indexPrmByTarget(judgesB)\n\n const attributions: StepAttribution[] = alignment.map((ao) =>\n attributeStep(ao, prmByTargetA, prmByTargetB),\n )\n const prmDeltaSum = attributions.reduce((acc, at) => acc + (at.prmDelta ?? 0), 0)\n\n const [runRecA, runRecB] = await Promise.all([store.getRun(runA), store.getRun(runB)])\n const totalScoreDelta =\n runRecA?.outcome?.score !== undefined && runRecB?.outcome?.score !== undefined\n ? runRecB.outcome.score - runRecA.outcome.score\n : null\n\n return { runA, runB, alignment, attributions, totalScoreDelta, prmDeltaSum }\n}\n\n// ── Alignment (LCS-based) ────────────────────────────────────────────\n\nfunction align(\n a: TrajectoryStep[],\n b: TrajectoryStep[],\n eq: (x: TrajectoryStep, y: TrajectoryStep) => boolean,\n): AlignmentOp[] {\n const dp: number[][] = Array.from({ length: a.length + 1 }, () => new Array(b.length + 1).fill(0))\n for (let i = 1; i <= a.length; i++) {\n for (let j = 1; j <= b.length; j++) {\n if (eq(a[i - 1]!, b[j - 1]!)) dp[i]![j] = dp[i - 1]![j - 1]! + 1\n else dp[i]![j] = Math.max(dp[i - 1]![j]!, dp[i]![j - 1]!)\n }\n }\n // Walk back to recover ops.\n const ops: AlignmentOp[] = []\n let i = a.length\n let j = b.length\n while (i > 0 || j > 0) {\n if (i > 0 && j > 0 && eq(a[i - 1]!, b[j - 1]!)) {\n ops.push({ op: 'match', a: a[i - 1]!, b: b[j - 1]! })\n i--\n j--\n } else if (i > 0 && j > 0 && dp[i - 1]![j]! === dp[i]![j - 1]!) {\n // Tie → call it a replace when same kind, else delete+insert.\n if (a[i - 1]!.span.kind === b[j - 1]!.span.kind) {\n ops.push({ op: 'replace', a: a[i - 1]!, b: b[j - 1]! })\n i--\n j--\n } else if (dp[i - 1]![j]! >= dp[i]![j - 1]!) {\n ops.push({ op: 'delete', a: a[i - 1]! })\n i--\n } else {\n ops.push({ op: 'insert', b: b[j - 1]! })\n j--\n }\n } else if (i > 0 && (j === 0 || dp[i - 1]![j]! >= dp[i]![j - 1]!)) {\n ops.push({ op: 'delete', a: a[i - 1]! })\n i--\n } else {\n ops.push({ op: 'insert', b: b[j - 1]! })\n j--\n }\n }\n return ops.reverse()\n}\n\nfunction defaultStepEquals(a: TrajectoryStep, b: TrajectoryStep): boolean {\n if (a.span.kind !== b.span.kind) return false\n if (a.span.kind === 'tool' && b.span.kind === 'tool') return a.span.toolName === b.span.toolName\n if (a.span.kind === 'llm' && b.span.kind === 'llm') return a.span.model === b.span.model\n return a.span.name === b.span.name\n}\n\n// ── PRM indexing + attribution ───────────────────────────────────────\n\nfunction indexPrmByTarget(judges: JudgeSpan[]): Map<string, number> {\n const out = new Map<string, number>()\n for (const j of judges) {\n const prior = out.get(j.targetSpanId) ?? 0\n out.set(j.targetSpanId, prior + j.score)\n }\n return out\n}\n\nfunction spanLatency(s: Span): number | null {\n return s.endedAt && s.startedAt ? s.endedAt - s.startedAt : null\n}\n\nfunction spanTokens(s: Span): number | null {\n if (s.kind !== 'llm') return null\n return (s.inputTokens ?? 0) + (s.outputTokens ?? 0)\n}\n\nfunction attributeStep(\n op: AlignmentOp,\n prmA: Map<string, number>,\n prmB: Map<string, number>,\n): StepAttribution {\n if (op.op === 'match') {\n const pa = prmA.get(op.a.span.spanId)\n const pb = prmB.get(op.b.span.spanId)\n const prmDelta = pa !== undefined && pb !== undefined ? pb - pa : null\n const la = spanLatency(op.a.span)\n const lb = spanLatency(op.b.span)\n const ta = spanTokens(op.a.span)\n const tb = spanTokens(op.b.span)\n return {\n op,\n prmDelta,\n latencyDeltaMs: la !== null && lb !== null ? lb - la : null,\n tokenDelta: ta !== null && tb !== null ? tb - ta : null,\n note:\n prmDelta === null ? 'matched step, no PRM coverage' : 'matched step, PRM delta recorded',\n }\n }\n if (op.op === 'replace') {\n const pa = prmA.get(op.a.span.spanId) ?? 0\n const pb = prmB.get(op.b.span.spanId) ?? 0\n return {\n op,\n prmDelta: pb - pa,\n latencyDeltaMs: null,\n tokenDelta: null,\n note: `replaced ${op.a.span.kind}/${op.a.span.name} → ${op.b.span.kind}/${op.b.span.name}`,\n }\n }\n if (op.op === 'insert') {\n const pb = prmB.get(op.b.span.spanId) ?? 0\n return {\n op,\n prmDelta: pb,\n latencyDeltaMs: null,\n tokenDelta: null,\n note: `inserted step in B (${op.b.span.kind}/${op.b.span.name})`,\n }\n }\n // delete\n const pa = prmA.get(op.a.span.spanId) ?? 0\n return {\n op,\n prmDelta: -pa,\n latencyDeltaMs: null,\n tokenDelta: null,\n note: `deleted step from A (${op.a.span.kind}/${op.a.span.name})`,\n }\n}\n","/**\n * Active learning — agent-as-scenario-author.\n *\n * Analyzes an existing Dataset + trace corpus for coverage gaps and\n * weak spots, returns a prioritized list of *synthesis targets*:\n * (gap description, existing-neighbor examples, suggested direction).\n *\n * Does NOT call an LLM itself — the proposer agent is caller-supplied.\n * This module's job is to identify WHERE new scenarios would compound\n * the most information, not to author them.\n *\n * Gaps we detect:\n * - dimensions with high score variance (unstable, need more data)\n * - dimensions with low coverage count (undersampled)\n * - failure classes with clusters (systematic weakness)\n * - difficulty bins with no coverage\n */\n\nimport type { Dataset, DatasetScenario } from './dataset'\nimport { classifyFailure } from './failure-taxonomy'\nimport type { Run } from './trace/schema'\nimport type { TraceStore } from './trace/store'\n\nexport type SynthesisReason =\n | 'high-variance'\n | 'undersampled'\n | 'failure-cluster'\n | 'difficulty-gap'\n\nexport interface SynthesisTarget {\n reason: SynthesisReason\n description: string\n /** Existing scenarios that are closest to the gap; caller feeds these to\n * their LLM proposer as few-shot examples. */\n neighbors: DatasetScenario[]\n /** Suggested direction — e.g. \"harder variants\", \"edge cases of X\", \"failure class Y\". */\n direction: string\n /** Priority score — higher = more information-dense gap. 0..1. */\n priority: number\n}\n\nexport interface ActiveLearningOptions {\n /** Minimum scenarios per difficulty band to count as \"covered\". */\n minPerBand?: number\n /** Variance threshold above which a scenario's dimension is \"unstable\". */\n varianceThreshold?: number\n /** Max synthesis targets returned. */\n topK?: number\n}\n\nexport async function proposeSynthesisTargets(\n dataset: Dataset,\n traceStore: TraceStore,\n options: ActiveLearningOptions = {},\n): Promise<SynthesisTarget[]> {\n const minPerBand = options.minPerBand ?? 5\n const varianceThreshold = options.varianceThreshold ?? 0.05\n const topK = options.topK ?? 10\n const scenarios = dataset.all()\n\n const targets: SynthesisTarget[] = []\n\n // 1. Difficulty coverage gaps\n const BANDS: Array<DatasetScenario['difficulty']> = ['easy', 'medium', 'hard', 'extreme']\n for (const band of BANDS) {\n const count = scenarios.filter((s) => s.difficulty === band).length\n if (count < minPerBand) {\n const neighbors = scenarios.filter((s) => s.difficulty === band).slice(0, 3)\n targets.push({\n reason: 'difficulty-gap',\n description: `difficulty=\"${band}\" has ${count} scenario(s) — below minimum ${minPerBand}`,\n neighbors: [...neighbors],\n direction: `create more \"${band}\" scenarios; reuse domain but shift complexity`,\n priority: Math.max(0, 1 - count / minPerBand),\n })\n }\n }\n\n // 2. Undersampled scenarios (few runs per scenario)\n const runs = await traceStore.listRuns()\n const runCountByScenario = new Map<string, number>()\n for (const r of runs) {\n runCountByScenario.set(r.scenarioId, (runCountByScenario.get(r.scenarioId) ?? 0) + 1)\n }\n const runCounts = [...runCountByScenario.values()]\n const p25 = runCounts.length > 0 ? quantile(runCounts, 0.25) : 0\n for (const s of scenarios) {\n const count = runCountByScenario.get(s.id) ?? 0\n if (count <= p25 && count < 3) {\n targets.push({\n reason: 'undersampled',\n description: `scenario \"${s.id}\" has only ${count} run(s)`,\n neighbors: [s],\n direction: `create near-duplicates of \"${s.id}\" to stabilize its mean`,\n priority: Math.max(0, 1 - count / 3) * 0.7,\n })\n }\n }\n\n // 3. High-variance scenarios (same scenario scored inconsistently)\n for (const s of scenarios) {\n const sRuns = runs.filter((r) => r.scenarioId === s.id)\n const scores = sRuns\n .map((r) => r.outcome?.score)\n .filter((x): x is number => typeof x === 'number')\n if (scores.length < 3) continue\n const mean = scores.reduce((a, b) => a + b, 0) / scores.length\n const variance = scores.reduce((a, b) => a + (b - mean) ** 2, 0) / scores.length\n if (variance > varianceThreshold) {\n targets.push({\n reason: 'high-variance',\n description: `scenario \"${s.id}\" has unstable scoring (variance ${variance.toFixed(3)})`,\n neighbors: [s],\n direction: `disambiguate the scenario description — current wording admits too many valid interpretations`,\n priority: Math.min(1, variance * 5),\n })\n }\n }\n\n // 4. Failure-class clusters — run classifier across the corpus\n const failureByClass = new Map<string, Run[]>()\n for (const run of runs) {\n if (run.outcome?.pass === true) continue\n const spans = await traceStore.spans({ runId: run.runId })\n const events = await traceStore.events({ runId: run.runId })\n const { failureClass } = classifyFailure({ run, spans, events })\n if (failureClass === 'success' || failureClass === 'unknown') continue\n const arr = failureByClass.get(failureClass) ?? []\n arr.push(run)\n failureByClass.set(failureClass, arr)\n }\n for (const [cls, runs] of failureByClass) {\n if (runs.length < 3) continue\n const affectedScenarios = [...new Set(runs.map((r) => r.scenarioId))]\n const neighbors = scenarios.filter((s) => affectedScenarios.includes(s.id)).slice(0, 3)\n targets.push({\n reason: 'failure-cluster',\n description: `failure class \"${cls}\" observed ${runs.length}× across ${affectedScenarios.length} scenario(s)`,\n neighbors,\n direction: `create scenarios that exercise \"${cls}\" recovery — currently a systematic weakness`,\n priority: Math.min(1, runs.length / 10),\n })\n }\n\n return targets.sort((a, b) => b.priority - a.priority).slice(0, topK)\n}\n\nfunction quantile(xs: number[], p: number): number {\n const sorted = [...xs].sort((a, b) => a - b)\n const idx = p * (sorted.length - 1)\n const lo = Math.floor(idx)\n const hi = Math.ceil(idx)\n return sorted[lo]! + (sorted[hi]! - sorted[lo]!) * (idx - lo)\n}\n","/**\n * Causal attribution via factorial experiments.\n *\n * Run every combination of {model × prompt × scenario × seed}, then\n * decompose observed score variance into main effects + interactions.\n * Moves from correlational \"variant B is better\" to causal \"the model\n * swap accounts for 42% of the lead; the prompt change accounts for 28%;\n * interaction is 30%.\"\n *\n * Minimal implementation: 2-way factorial (two factors at a time) with\n * main-effect + interaction decomposition via variance of cell means.\n * Consumers run the factorial design themselves (we don't schedule\n * runs); this module consumes the (factorLevels, observedScores)\n * table and does the attribution math.\n */\n\nexport interface FactorialCell {\n /** Map factor name → level id. e.g. { model: 'claude', prompt: 'v2' } */\n levels: Record<string, string>\n /** Observed score for this cell (mean over replications if n > 1). */\n score: number\n /** Number of replications averaged to produce `score`. */\n n: number\n}\n\nexport interface FactorContribution {\n factor: string\n /** Variance attributed to this factor's main effect, as a fraction of total. */\n shareOfVariance: number\n /** Range of cell means across levels of this factor. */\n range: number\n}\n\nexport interface InteractionContribution {\n factors: [string, string]\n shareOfVariance: number\n}\n\nexport interface CausalAttributionReport {\n totalVariance: number\n mainEffects: FactorContribution[]\n interactions: InteractionContribution[]\n /** Residual = variance unexplained by main effects + modeled interactions. */\n residualShare: number\n /** Sanity: shares sum to 1 (within fp). */\n sharesSum: number\n}\n\nexport function causalAttribution(cells: FactorialCell[]): CausalAttributionReport {\n if (cells.length < 4) throw new Error('causalAttribution: need ≥ 4 cells to estimate effects')\n const factors = Object.keys(cells[0]!.levels)\n if (factors.length < 2) throw new Error('causalAttribution: need ≥ 2 factors')\n\n const allScores = cells.map((c) => c.score)\n const grandMean = allScores.reduce((a, b) => a + b, 0) / allScores.length\n const totalVariance =\n allScores.reduce((acc, s) => acc + (s - grandMean) ** 2, 0) / allScores.length\n if (totalVariance === 0) {\n return {\n totalVariance: 0,\n mainEffects: factors.map((f) => ({ factor: f, shareOfVariance: 0, range: 0 })),\n interactions: [],\n residualShare: 1,\n sharesSum: 1,\n }\n }\n\n // Main effects: variance of cell-mean-by-level, averaged across other factors.\n const mainEffects: FactorContribution[] = factors.map((f) => {\n const byLevel = groupBy(cells, (c) => c.levels[f] ?? '')\n const means: number[] = []\n for (const arr of byLevel.values()) {\n means.push(arr.reduce((a, c) => a + c.score, 0) / arr.length)\n }\n const mainVariance = means.reduce((acc, m) => acc + (m - grandMean) ** 2, 0) / means.length\n return {\n factor: f,\n shareOfVariance: mainVariance / totalVariance,\n range: Math.max(...means) - Math.min(...means),\n }\n })\n\n // Pairwise interactions: cell mean by (factor_i, factor_j) vs main effects\n const interactions: InteractionContribution[] = []\n for (let i = 0; i < factors.length; i++) {\n for (let j = i + 1; j < factors.length; j++) {\n const fi = factors[i]!\n const fj = factors[j]!\n const byPair = groupBy(cells, (c) => `${c.levels[fi]}|${c.levels[fj]}`)\n const pairMeans: number[] = []\n for (const arr of byPair.values()) {\n pairMeans.push(arr.reduce((a, c) => a + c.score, 0) / arr.length)\n }\n const pairVariance =\n pairMeans.reduce((acc, m) => acc + (m - grandMean) ** 2, 0) / pairMeans.length\n const mainI = mainEffects[i]!.shareOfVariance * totalVariance\n const mainJ = mainEffects[j]!.shareOfVariance * totalVariance\n const interactionVariance = Math.max(0, pairVariance - mainI - mainJ)\n interactions.push({\n factors: [fi, fj],\n shareOfVariance: interactionVariance / totalVariance,\n })\n }\n }\n\n const mainSum = mainEffects.reduce((a, m) => a + m.shareOfVariance, 0)\n const interactionSum = interactions.reduce((a, m) => a + m.shareOfVariance, 0)\n const residualShare = Math.max(0, 1 - mainSum - interactionSum)\n const sharesSum = mainSum + interactionSum + residualShare\n return { totalVariance, mainEffects, interactions, residualShare, sharesSum }\n}\n\nfunction groupBy<T>(items: T[], key: (t: T) => string): Map<string, T[]> {\n const m = new Map<string, T[]>()\n for (const item of items) {\n const k = key(item)\n const arr = m.get(k) ?? []\n arr.push(item)\n m.set(k, arr)\n }\n return m\n}\n","/**\n * Reward-model export — the productizable wrapper around PRM training\n * data. Takes a TraceStore + PrmGrader, produces an embeddable\n * inference scorer that customers plug into their own agent stack.\n *\n * Two export forms:\n * - `exportRewardModel(store, graders)` — serializes the (step-context,\n * score) corpus to a framework-agnostic payload. Customer fine-tunes\n * their own model; we ship the scaffolding.\n * - `loadScorerFromTraces(store, grader)` — a zero-deps \"reward model\"\n * that literally replays the trained rubric at inference time. Works\n * as a reference baseline + deterministic fallback.\n */\n\nimport type { PrmGradedTrace, PrmGrader } from './prm/rubric'\nimport { exportTrainingData, type PrmTrainingSample, toNdjson } from './prm/training-export'\nimport type { TraceStore } from './trace/store'\nimport type { Trajectory } from './trajectory'\nimport { buildTrajectory } from './trajectory'\n\nexport interface ExportedRewardModel {\n /** Version of the export format. Bump when payload shape changes. */\n version: '1.0'\n /** Metadata about the training corpus. */\n metadata: {\n nTraces: number\n nSamples: number\n rubrics: string[]\n exportedAt: string\n /** Mean reward across training corpus — use as sanity check at load. */\n meanReward: number\n }\n /** NDJSON training payload suitable for most fine-tuning frameworks. */\n trainingNdjson: string\n}\n\nexport async function exportRewardModel(\n store: TraceStore,\n grader: PrmGrader,\n runIds: string[],\n): Promise<ExportedRewardModel> {\n const graded = await Promise.all(runIds.map((id) => grader.grade(store, id)))\n const samples = await exportTrainingData(store, graded)\n const rubrics = [...new Set(samples.map((s) => s.rubricId))]\n const meanReward =\n samples.length > 0 ? samples.reduce((a, s) => a + s.score, 0) / samples.length : 0\n return {\n version: '1.0',\n metadata: {\n nTraces: graded.length,\n nSamples: samples.length,\n rubrics,\n exportedAt: new Date().toISOString(),\n meanReward,\n },\n trainingNdjson: toNdjson(samples),\n }\n}\n\n/**\n * Zero-deps inference scorer — apply a grader to a trajectory and return\n * its aggregate score. This is the \"reward model\" customers embed when\n * they don't want (or can't) fine-tune one. Deterministic + portable.\n */\nexport interface InferenceScorer {\n /** Score a completed trajectory. Higher is better. */\n score(trajectory: Trajectory, store: TraceStore): Promise<number>\n metadata: { rubrics: string[]; deterministic: true }\n}\n\nexport function loadScorerFromGrader(grader: PrmGrader): InferenceScorer {\n return {\n async score(trajectory, store) {\n const graded = await grader.grade(store, trajectory.runId)\n return graded.aggregateScore\n },\n metadata: {\n rubrics: ['grader-backed'],\n deterministic: true,\n },\n }\n}\n\n/**\n * Replay a trace corpus through a scorer — produces the canonical\n * \"what would this reward model have said about every run?\" table.\n * Callers use this to validate a trained model against the training\n * corpus (expect high agreement; drift indicates overfitting).\n */\nexport async function replayScorerOverCorpus(\n store: TraceStore,\n scorer: InferenceScorer,\n runIds: string[],\n): Promise<Array<{ runId: string; score: number; outcomeScore: number | null }>> {\n return Promise.all(\n runIds.map(async (runId) => {\n const [trajectory, run] = await Promise.all([\n buildTrajectory(store, runId),\n store.getRun(runId),\n ])\n return {\n runId,\n score: await scorer.score(trajectory, store),\n outcomeScore: run?.outcome?.score ?? null,\n }\n }),\n )\n}\n\n// Re-export for ergonomics\nexport type { PrmGradedTrace, PrmTrainingSample }\n","/**\n * Self-play scenario evolution — agents generate adversarial scenarios\n * against each other; survivors become part of the eval corpus.\n *\n * Framework-agnostic about how scenarios are generated. Caller supplies:\n * - `propose`: asks a \"proposer\" agent for candidate scenarios\n * - `scoreAgainst`: runs a target agent against a scenario and returns\n * its score\n *\n * A scenario *survives* if it reveals a meaningful score difference\n * between two target agents (or between a target agent and itself on\n * different runs). Survivors are promoted to a Dataset; the caller\n * decides what to do with them (hold-out, training, regression set).\n *\n * Guard rails: minimum absolute score delta to consider a scenario\n * informative; floor on absolute target score so degenerate break-all\n * scenarios (noise, gibberish) don't flood the corpus.\n */\n\nimport { Dataset, type DatasetScenario } from './dataset'\n\nexport interface CandidateScenario {\n id: string\n payload: unknown\n /** Free-form tags (domain, generation, parent). */\n tags?: Record<string, string>\n}\n\nexport interface ScoredTarget {\n targetId: string\n score: number\n}\n\nexport interface EvolutionRound {\n round: number\n proposed: CandidateScenario[]\n survived: CandidateScenario[]\n rejected: Array<{ candidate: CandidateScenario; reason: string }>\n scoredBreakdown: Array<{ candidate: CandidateScenario; scores: ScoredTarget[]; spread: number }>\n}\n\nexport interface SelfPlayOptions {\n /** Minimum score spread across targets for a scenario to survive. Default 0.1. */\n minSpread?: number\n /** Minimum floor score across targets — keeps degenerate break-all scenarios\n * out. Default 0.1 (if every target scores below this, discard). */\n minAbsoluteFloor?: number\n /** Hard cap on survivors per round. Default 50. */\n maxSurvivors?: number\n /** Rounds to run. Default 1. Each round's survivors can be fed back into\n * `propose` to compound. */\n rounds?: number\n /** Seed for scenario id generation if proposer doesn't provide one. */\n seed?: number\n}\n\nexport interface SelfPlayProposer {\n propose(round: number, priorSurvivors: CandidateScenario[]): Promise<CandidateScenario[]>\n}\n\nexport interface SelfPlayScorer {\n /** Score one candidate against every target; returns parallel array. */\n scoreCandidate(candidate: CandidateScenario, targets: string[]): Promise<ScoredTarget[]>\n}\n\nexport async function runSelfPlay(\n proposer: SelfPlayProposer,\n scorer: SelfPlayScorer,\n targets: string[],\n options: SelfPlayOptions = {},\n): Promise<{ rounds: EvolutionRound[]; dataset: Dataset }> {\n if (targets.length < 2)\n throw new Error('runSelfPlay: at least 2 targets required (need a difference to measure)')\n const minSpread = options.minSpread ?? 0.1\n const floor = options.minAbsoluteFloor ?? 0.1\n const maxSurvivors = options.maxSurvivors ?? 50\n const totalRounds = options.rounds ?? 1\n\n const allRounds: EvolutionRound[] = []\n let priorSurvivors: CandidateScenario[] = []\n const datasetScenarios: DatasetScenario[] = []\n\n for (let r = 0; r < totalRounds; r++) {\n const proposed = await proposer.propose(r, priorSurvivors)\n const scored: EvolutionRound['scoredBreakdown'] = []\n const rejected: EvolutionRound['rejected'] = []\n const surviving: CandidateScenario[] = []\n for (const candidate of proposed) {\n const scores = await scorer.scoreCandidate(candidate, targets)\n if (scores.length < 2) {\n rejected.push({ candidate, reason: 'scorer returned <2 results' })\n continue\n }\n const values = scores.map((s) => s.score)\n const spread = Math.max(...values) - Math.min(...values)\n const maxScore = Math.max(...values)\n scored.push({ candidate, scores, spread })\n if (maxScore < floor) {\n rejected.push({\n candidate,\n reason: `every target below floor (max=${maxScore.toFixed(3)} < ${floor})`,\n })\n continue\n }\n if (spread < minSpread) {\n rejected.push({\n candidate,\n reason: `spread below threshold (${spread.toFixed(3)} < ${minSpread})`,\n })\n continue\n }\n surviving.push(candidate)\n }\n\n // Rank by spread descending, cap at maxSurvivors\n surviving.sort((a, b) => {\n const sa = scored.find((s) => s.candidate.id === a.id)?.spread ?? 0\n const sb = scored.find((s) => s.candidate.id === b.id)?.spread ?? 0\n return sb - sa\n })\n const capped = surviving.slice(0, maxSurvivors)\n\n for (const s of capped) {\n datasetScenarios.push({\n id: s.id,\n payload: s.payload,\n split: 'test',\n tags: { ...s.tags, evolutionRound: String(r), origin: 'self-play' },\n })\n }\n\n allRounds.push({ round: r, proposed, survived: capped, rejected, scoredBreakdown: scored })\n priorSurvivors = capped\n }\n\n const dataset = new Dataset({\n name: 'self-play-survivors',\n provenance: {\n version: '1.0.0',\n createdAt: new Date().toISOString(),\n contributor: 'self-play',\n description: `Evolved across ${totalRounds} round(s), ${allRounds.reduce((a, r) => a + r.survived.length, 0)} survivors`,\n },\n scenarios: datasetScenarios,\n })\n return { rounds: allRounds, dataset }\n}\n","/**\n * CommandRunner — abstract subprocess execution surface.\n *\n * Layers in a {@link MultiLayerVerifier} that need to invoke external\n * tools (compilers, test runners, package managers) call out via this\n * interface rather than directly using `child_process`. Two reasons:\n *\n * 1. **Sandbox interchangeability.** A run that targets a sandbox box\n * (via SDK-specific Box.exec) and a run that targets the host both\n * satisfy this same contract. The harness doesn't care which.\n * 2. **Testability.** Tests inject a fake runner and assert on calls\n * without spawning real subprocesses.\n *\n * agent-eval ships only the local implementation (host-process). Sandbox\n * implementations live with their consumer because they depend on\n * SDK-specific Box / Sandbox types that don't belong in this package.\n */\n\nimport { spawnSync } from 'node:child_process'\nimport { existsSync, readdirSync, readFileSync, statSync } from 'node:fs'\nimport { join } from 'node:path'\n\n// ─── Types ──────────────────────────────────────────────────────────────\n\nexport interface RunCommandInput {\n /** Executable name, looked up via PATH unless absolute. */\n cmd: string\n /** Argument vector, NOT shell-interpolated. Each element passed to argv. */\n argv: string[]\n /** Working directory. Defaults to runner's notion of cwd if omitted. */\n cwd?: string\n /**\n * Wall-clock cap in ms. The runner SHOULD return `timedOut: true` when\n * exceeded; callers MAY treat status null + timedOut as \"killed.\"\n */\n capMs?: number\n /** Env overrides merged on top of the runner's base environment. */\n env?: Record<string, string>\n /** Optional stdin payload. */\n stdin?: string\n}\n\nexport interface RunCommandResult {\n /** Exit code, or null when the process couldn't start / was killed. */\n status: number | null\n stdout: string\n stderr: string\n durationMs: number\n timedOut: boolean\n /** Non-fatal runner-side error (binary missing, signal, etc.). */\n runnerError?: string\n}\n\nexport interface DirEntry {\n name: string\n isDirectory: boolean\n isFile: boolean\n /** File size in bytes. `null` for directories (not stat'd). */\n sizeBytes: number | null\n}\n\nexport interface CommandRunner {\n /** Identifier for telemetry + logs. Open-ended literal-union for new runners. */\n readonly name: string\n /** Execute a command in the runner's environment. */\n run(input: RunCommandInput): Promise<RunCommandResult>\n /** True iff `<name>` resolves on the runner's PATH. */\n hasBin(name: string): Promise<boolean>\n /** True iff the given path exists in the runner's filesystem. */\n fileExists(path: string): Promise<boolean>\n /** Read a file. Returns `null` if missing or unreadable. */\n readFile(path: string): Promise<string | null>\n /** List a directory. Returns `[]` if unreadable / missing. */\n readDir(path: string): Promise<DirEntry[]>\n}\n\n// ─── Local runner ───────────────────────────────────────────────────────\n\n/**\n * Host-process runner. Uses node:child_process spawnSync (synchronous\n * under the hood — wrapped in a Promise to satisfy the interface). For\n * very long-running commands consider an async-spawn variant; this\n * shape matches VB's existing behavior and is fine for build/test/lint\n * subprocesses that finish in seconds-to-minutes.\n */\nexport const localCommandRunner: CommandRunner = {\n name: 'local',\n async run(input: RunCommandInput): Promise<RunCommandResult> {\n const start = Date.now()\n const res = spawnSync(input.cmd, input.argv, {\n cwd: input.cwd,\n encoding: 'utf8',\n timeout: input.capMs,\n env: { ...process.env, CI: '1', ...(input.env ?? {}) },\n input: input.stdin,\n })\n const durationMs = Date.now() - start\n const timedOut = !!(\n res.error &&\n 'code' in res.error &&\n (res.error as NodeJS.ErrnoException).code === 'ETIMEDOUT'\n )\n return {\n status: res.status ?? null,\n stdout: (res.stdout ?? '').toString(),\n stderr: (res.stderr ?? '').toString(),\n durationMs,\n timedOut,\n runnerError: res.error && !timedOut ? String(res.error.message ?? res.error) : undefined,\n }\n },\n async hasBin(name: string): Promise<boolean> {\n const r = spawnSync('which', [name], { encoding: 'utf8', timeout: 2000 })\n return r.status === 0 && (r.stdout ?? '').trim().length > 0\n },\n async fileExists(path: string): Promise<boolean> {\n return existsSync(path)\n },\n async readFile(path: string): Promise<string | null> {\n try {\n return readFileSync(path, 'utf8')\n } catch {\n return null\n }\n },\n async readDir(path: string): Promise<DirEntry[]> {\n let entries: string[]\n try {\n entries = readdirSync(path)\n } catch {\n return []\n }\n const out: DirEntry[] = []\n for (const name of entries) {\n try {\n const st = statSync(join(path, name))\n out.push({\n name,\n isDirectory: st.isDirectory(),\n isFile: st.isFile(),\n sizeBytes: st.isFile() ? st.size : null,\n })\n } catch {\n // skip unreadable\n }\n }\n return out\n },\n}\n","/**\n * Deploy gate layer — would the agent's build actually publish?\n *\n * The product Blueprint Agent fronts promises \"go from idea to live URL.\"\n * Pre-Gen-48 the eval stopped at install/typecheck/build/serve — every\n * one of which can pass while `vite build` (or `next build`, etc) fails\n * on a production-only constraint (env-var requirement, dynamic import\n * not statically resolvable, missing public asset).\n *\n * Deploy gate runs the production build via the supplied {@link DeployRunner}\n * and asserts:\n * - command exited 0\n * - artifact dir contains an entry point (index.html for static SPAs,\n * equivalent per framework family)\n *\n * Ships with a canonical `vite` runner. Additional runners\n * (wrangler-deploy --dry-run, next-build, etc.) plug in as factories.\n */\n\nimport type { Layer, LayerResult } from './multi-layer-verifier'\n\n// ─── Types ──────────────────────────────────────────────────────────────\n\nexport type DeployFamily = 'frontend-static' | 'nextjs' | 'remix' | 'fullstack-ts'\n\nexport interface DeployRunResult {\n ok: boolean\n /** Stdout/stderr tail surfaced as evidence. Bounded in caller. */\n output?: string\n /** Wall-clock duration of the build command. */\n durationMs?: number\n /** Path to artifact directory the runner expects (dist/, .next/, build/, etc). */\n artifactDir?: string\n /** True iff artifactDir contains the family's expected entry point. */\n artifactValid?: boolean\n}\n\nexport interface DeployRunner {\n /** Run the production build. The runner owns command + cwd. */\n run(): Promise<DeployRunResult>\n}\n\nexport interface DeployGateLayerInput {\n /** Build the runner per call. */\n runner: () => DeployRunner | Promise<DeployRunner>\n /** Family hint — for logging, surfaced in diagnostics. */\n family?: DeployFamily\n /** Layer name. Default `deploy`. */\n name?: string\n /** Layer dependencies — default `['build']`. */\n dependsOn?: string[]\n /** Weight in blendedScore. Default 1. */\n weight?: number\n /** Cap (ms). Default 120s — prod builds are slower than dev. */\n capMs?: number\n /** When true, treat artifactValid=false as a fail (default true). */\n requireArtifact?: boolean\n}\n\n// ─── Layer factory ──────────────────────────────────────────────────────\n\n/**\n * Build a deploy gate layer that runs the production build and verifies\n * the artifact. Pass: ok && artifactValid. Score: 1.0 (pass) or 0 (fail).\n *\n * For families where artifact-validation isn't applicable (e.g. a\n * server-rendered build that prints a manifest), set `requireArtifact:\n * false` and rely on the runner's own ok signal.\n */\nexport function deployGateLayer<Env = unknown>(input: DeployGateLayerInput): Layer<Env> {\n const requireArtifact = input.requireArtifact ?? true\n return {\n name: input.name ?? 'deploy',\n dependsOn: input.dependsOn ?? ['build'],\n weight: input.weight ?? 1,\n capMs: input.capMs ?? 120_000,\n run: async (ctx) => {\n const start = Date.now()\n let runner: DeployRunner\n try {\n runner = await input.runner()\n } catch (err) {\n return {\n layer: input.name ?? 'deploy',\n status: 'error',\n durationMs: Date.now() - start,\n findings: [\n {\n severity: 'major',\n message: `deploy runner failed to start: ${err instanceof Error ? err.message : String(err)}`,\n },\n ],\n reason: 'runner-init-failed',\n }\n }\n let result: DeployRunResult\n try {\n result = await runner.run()\n } catch (err) {\n return {\n layer: input.name ?? 'deploy',\n status: 'error',\n durationMs: Date.now() - start,\n findings: [\n {\n severity: 'major',\n message: `deploy command threw: ${err instanceof Error ? err.message : String(err)}`,\n },\n ],\n reason: 'runner-throw',\n }\n }\n if (ctx.signal.aborted) {\n return {\n layer: input.name ?? 'deploy',\n status: 'timeout',\n durationMs: Date.now() - start,\n findings: [],\n reason: 'aborted by overall cap',\n }\n }\n\n const artifactOk = !requireArtifact || result.artifactValid === true\n const pass = result.ok && artifactOk\n const findings: LayerResult['findings'] = []\n if (!result.ok) {\n findings.push({\n severity: 'critical',\n message: 'deploy build exited non-zero',\n evidence: (result.output ?? '').slice(-1200),\n })\n }\n if (result.ok && requireArtifact && !result.artifactValid) {\n findings.push({\n severity: 'major',\n message: `deploy build succeeded but artifact ${result.artifactDir ?? '(unknown)'} is invalid or empty`,\n })\n }\n return {\n layer: input.name ?? 'deploy',\n status: pass ? 'pass' : 'fail',\n score: pass ? 1 : 0,\n durationMs: Date.now() - start,\n findings,\n reason: pass\n ? `deploy build OK${input.family ? ` (${input.family})` : ''}${result.artifactDir ? ` → ${result.artifactDir}` : ''}`\n : !result.ok\n ? 'build command failed'\n : 'artifact missing or invalid',\n diagnostics: {\n deployBuildOk: result.ok ? 1 : 0,\n deployArtifactOk: result.artifactValid === true ? 1 : 0,\n deployBuildMs: result.durationMs ?? null,\n },\n }\n },\n }\n}\n\n// ─── Canonical vite runner ──────────────────────────────────────────────\n\nexport interface ViteDeployRunnerInput {\n /** Workdir to build. The runner cd's here. */\n workdir: string\n /**\n * Function to run a shell command in `workdir`. Same shape as\n * agent-eval's CommandRunner.run for compositional reuse.\n */\n exec: (\n cmd: string,\n opts?: { cwd?: string; timeoutMs?: number },\n ) => Promise<{ stdout: string; stderr: string; exitCode: number }>\n /**\n * Function to test whether a path exists in the workdir. Inject\n * `(p) => existsSync(join(workdir, p))` for host runs.\n */\n exists: (relativePath: string) => boolean | Promise<boolean>\n /** Build command. Default `npm run build`. */\n buildCommand?: string\n /** Artifact directory to validate. Default `dist`. */\n artifactDir?: string\n /** Entry-point file under artifactDir. Default `index.html`. */\n artifactEntry?: string\n /** Per-build cap (ms). Default 90s. */\n timeoutMs?: number\n}\n\n/**\n * Canonical runner for `frontend-static` family — runs the build script,\n * validates `<artifactDir>/<artifactEntry>` exists. Use as the `runner:`\n * factory for {@link deployGateLayer}.\n */\nexport function viteDeployRunner(input: ViteDeployRunnerInput): DeployRunner {\n return {\n run: async () => {\n const start = Date.now()\n const cmd = input.buildCommand ?? 'npm run build'\n const artifactDir = input.artifactDir ?? 'dist'\n const artifactEntry = input.artifactEntry ?? 'index.html'\n const timeoutMs = input.timeoutMs ?? 90_000\n const result = await input.exec(cmd, { cwd: input.workdir, timeoutMs })\n const ok = result.exitCode === 0\n let artifactValid = false\n try {\n const entryExists = await input.exists(`${artifactDir}/${artifactEntry}`)\n artifactValid = ok && Boolean(entryExists)\n } catch {\n artifactValid = false\n }\n const tail = ((result.stderr || result.stdout) ?? '').slice(-1500)\n return {\n ok,\n output: tail,\n durationMs: Date.now() - start,\n artifactDir,\n artifactValid,\n }\n },\n }\n}\n\n// ─── Canonical wrangler runner ──────────────────────────────────────────\n\nexport interface WranglerDeployRunnerInput {\n workdir: string\n exec: (\n cmd: string,\n opts?: { cwd?: string; timeoutMs?: number },\n ) => Promise<{ stdout: string; stderr: string; exitCode: number }>\n exists: (relativePath: string) => boolean | Promise<boolean>\n /** Build command. Default `npm run build`. */\n buildCommand?: string\n /** Wrangler dry-run command. Default `npx wrangler deploy --dry-run --outdir dist`. */\n dryRunCommand?: string\n /** Per-step cap (ms). Default 120s. */\n timeoutMs?: number\n}\n\n/**\n * Canonical runner for the `fullstack-ts` family on Cloudflare Workers\n * (Remix / React Router v7 / Hono on Workers). Detects wrangler.toml or\n * wrangler.jsonc in the workdir, builds, then `wrangler deploy --dry-run`\n * to catch missing bindings, syntax errors in wrangler config, and\n * import-time crashes that don't surface in `tsc`.\n *\n * No wrangler config = skip with \"no wrangler\" evidence (not a failure\n * — the gate caller decides whether to require deploy validation).\n */\nexport function wranglerDeployRunner(input: WranglerDeployRunnerInput): DeployRunner {\n return {\n run: async () => {\n const start = Date.now()\n const buildCmd = input.buildCommand ?? 'npm run build'\n const dryCmd = input.dryRunCommand ?? 'npx wrangler deploy --dry-run --outdir dist'\n const timeoutMs = input.timeoutMs ?? 120_000\n\n const hasToml = await input.exists('wrangler.toml')\n const hasJsonc = hasToml ? false : await input.exists('wrangler.jsonc')\n if (!hasToml && !hasJsonc) {\n return {\n ok: false,\n output: 'no wrangler config found (wrangler.toml / wrangler.jsonc absent)',\n durationMs: Date.now() - start,\n artifactDir: 'dist',\n artifactValid: false,\n }\n }\n\n const build = await input.exec(buildCmd, { cwd: input.workdir, timeoutMs })\n if (build.exitCode !== 0) {\n const tail = ((build.stderr || build.stdout) ?? '').slice(-1500)\n return {\n ok: false,\n output: `build failed: ${tail}`,\n durationMs: Date.now() - start,\n artifactDir: 'dist',\n artifactValid: false,\n }\n }\n\n const dry = await input.exec(dryCmd, { cwd: input.workdir, timeoutMs })\n if (dry.exitCode !== 0) {\n const tail = ((dry.stderr || dry.stdout) ?? '').slice(-1500)\n return {\n ok: false,\n output: `wrangler dry-run failed: ${tail}`,\n durationMs: Date.now() - start,\n artifactDir: 'dist',\n artifactValid: false,\n }\n }\n\n const tail = ((dry.stdout || dry.stderr) ?? '').slice(-1500)\n return {\n ok: true,\n output: tail,\n durationMs: Date.now() - start,\n artifactDir: 'dist',\n artifactValid: true,\n }\n },\n }\n}\n","/**\n * Toolchain error-count extractor.\n *\n * Given stderr/stdout from a compiler or test runner, count the number\n * of reported errors/failures. Patterns are deliberately narrow —\n * unknown stderr returns `null` rather than zero so callers can\n * distinguish \"no errors\" from \"different toolchain, couldn't parse\".\n *\n * All patterns are anchored to the start of a line and use bounded\n * character classes to avoid catastrophic backtracking on pathological\n * inputs.\n *\n * Add new toolchains by appending to {@link ERROR_COUNT_PATTERNS};\n * order matters only in the sense that the first matching pattern wins.\n */\n\nexport interface ErrorCountPattern {\n /** Stable identifier for logging + tests. */\n name: string\n /** Must be global (`g` flag) — the extractor counts matches. */\n regex: RegExp\n /** Optional post-processing to extract a count from a single captured match. */\n transform?: (match: RegExpMatchArray) => number\n}\n\nexport const ERROR_COUNT_PATTERNS: ErrorCountPattern[] = [\n {\n // tsc / ts-node: `src/foo.ts(12,3): error TS1234: ...`\n name: 'typescript-tsc',\n regex: /[\\w./-]+\\(\\d+,\\d+\\): error TS\\d+:/g,\n },\n {\n // pytest: `FAILED tests/test_foo.py::test_bar`\n name: 'pytest-failed',\n regex: /^FAILED\\s+\\S+/gm,\n },\n {\n // rustc: `error[E0308]: ...` or `error: ...`\n name: 'rustc',\n regex: /^error(?:\\[[A-Z]\\d+\\])?:/gm,\n },\n {\n // go build: `./foo.go:12:3: ...` — any file:line:col: is an error line\n name: 'golang',\n regex: /^\\.\\/[\\w./-]+\\.go:\\d+:\\d+:/gm,\n },\n {\n // eslint default formatter per-line: ` 12:34 error message rule-id`\n name: 'eslint',\n regex: /^\\s+\\d+:\\d+\\s+error\\s+/gm,\n },\n {\n // eslint summary line: `✖ 17 problems (12 errors, 5 warnings)`\n // Use this only when the per-line formatter isn't present; transform\n // reads the errors count directly.\n name: 'eslint-summary',\n regex: /✖\\s+\\d+\\s+problems?\\s+\\((\\d+)\\s+errors?/gm,\n transform: (m) => Number(m[1] ?? 0),\n },\n]\n\nexport interface ExtractOptions {\n /** Restrict to named patterns — default: all patterns. */\n only?: string[]\n /** Additional patterns to consider BEFORE the built-in list. */\n extra?: ErrorCountPattern[]\n}\n\nexport interface ExtractResult {\n /** Total count of matched errors, or null when no pattern matched. */\n count: number | null\n /** Name of the pattern that matched, or null. */\n matched: string | null\n /** Original matches for callers that want to surface specifics. */\n samples: string[]\n}\n\n/**\n * Try each pattern in order; return the first with matches.\n *\n * Returning `null` (instead of zero) on no-match is deliberate — a\n * callsite that greps for \"typescript errors\" on cargo output should\n * NOT treat that as \"zero TS errors\" because the toolchain is wrong.\n */\nexport function extractErrorCount(text: string, opts: ExtractOptions = {}): ExtractResult {\n if (!text) return { count: null, matched: null, samples: [] }\n\n const patterns = [...(opts.extra ?? []), ...ERROR_COUNT_PATTERNS].filter(\n (p) => !opts.only || opts.only.includes(p.name),\n )\n\n for (const p of patterns) {\n const matches = Array.from(text.matchAll(p.regex))\n if (matches.length === 0) continue\n\n const count = p.transform\n ? matches.reduce((sum, m) => sum + p.transform!(m), 0)\n : matches.length\n\n return {\n count,\n matched: p.name,\n samples: matches.slice(0, 5).map((m) => m[0]),\n }\n }\n\n return { count: null, matched: null, samples: [] }\n}\n","/**\n * Flow layer — drive a previewed app through a scripted user walk.\n *\n * The MultiLayerVerifier already had a `flow` slot wired in\n * VerticalBench's verification-harness, but the layer module was\n * always-skipped (\"flow layer module not yet wired\"). This adds the\n * module: a Layer<Env> that takes a {@link FlowSpec} (URL + steps),\n * boots a preview server via the supplied {@link FlowRunner}, executes\n * each step, and returns a LayerResult whose `findings` enumerate\n * which step failed.\n *\n * The runner is injected so this module can swap between:\n * - production: agent-browser CLI (a11y-tree based steps)\n * - test: in-memory mock that returns canned step outcomes\n * - future: Playwright, Puppeteer, custom scrapers\n *\n * Paired with {@link runIntentMatchJudge}: intent-match catches \"wrong\n * app entirely\"; flow-layer catches \"right app but the buttons don't work.\"\n */\n\nimport type { Layer, LayerResult, Severity } from './multi-layer-verifier'\n\n// ─── Types ──────────────────────────────────────────────────────────────\n\nexport type FlowAction =\n | 'navigate'\n | 'click'\n | 'fill'\n | 'expect-text'\n | 'expect-element'\n | 'expect-url'\n | 'wait'\n\nexport interface FlowStep {\n /** What this step does. */\n action: FlowAction\n /** Human-readable description for findings. */\n describe?: string\n /**\n * For navigate/expect-url: full URL. For click/fill/expect-element:\n * accessible-name selector or CSS selector.\n * For expect-text: substring expected on the page.\n * For wait: ignored (use `value` for ms).\n */\n target?: string\n /** For fill: text to enter. For wait: ms. */\n value?: string\n /** Severity of a failure. Default `major`. */\n severity?: Severity\n}\n\nexport interface FlowSpec {\n /** Initial URL the runner should open. */\n url: string\n /** Ordered steps. Stops at the first failure unless `continueOnFail: true`. */\n steps: FlowStep[]\n /** When true, execute every step even after a failure (collect all findings). */\n continueOnFail?: boolean\n /** Per-step wall cap (ms). Default 15s. */\n stepTimeoutMs?: number\n}\n\nexport interface FlowRunnerStepResult {\n ok: boolean\n /** Concrete observation: matched text snippet, captured URL, error message. */\n evidence?: string\n /** Wall-clock duration of the step. */\n durationMs?: number\n}\n\nexport interface FlowRunner {\n /** Open the target URL. Returns when the page is interactable. */\n open(url: string): Promise<FlowRunnerStepResult>\n /** Execute one step. The runner owns interpretation of `target`. */\n step(step: FlowStep): Promise<FlowRunnerStepResult>\n /** Tear down browser, free resources. Always called once per layer.run. */\n close(): Promise<void>\n}\n\nexport interface FlowLayerEnv {\n /** Optional override per-call. Defaults supplied by the layer factory. */\n flowSpec?: FlowSpec\n}\n\nexport interface FlowLayerFactoryInput {\n /** Static spec (used when env doesn't supply one). */\n flowSpec?: FlowSpec\n /** Build the runner per call (lets the layer create + tear down per leaf). */\n runner: () => FlowRunner | Promise<FlowRunner>\n /** Layer name. Default `flow`. */\n name?: string\n /** Layer dependencies — default `['serve']` so a non-booting preview skips us. */\n dependsOn?: string[]\n /** Layer weight for blendedScore (0..1+). Default 1. */\n weight?: number\n /** Cap for the entire flow run (ms). Default 60s. */\n capMs?: number\n}\n\n// ─── Layer factory ──────────────────────────────────────────────────────\n\n/**\n * Build a flow layer that scripts a user walk via the supplied runner.\n *\n * Score: 1.0 when every step passed; otherwise 1 - (failedSteps / totalSteps).\n * Status: `pass` iff every step passed; `fail` if any step failed; `error`\n * on runner setup error; `skipped` when no flowSpec is available.\n */\nexport function flowLayer<Env extends FlowLayerEnv = FlowLayerEnv>(\n input: FlowLayerFactoryInput,\n): Layer<Env> {\n return {\n name: input.name ?? 'flow',\n dependsOn: input.dependsOn ?? ['serve'],\n weight: input.weight ?? 1,\n capMs: input.capMs ?? 60_000,\n run: async (ctx) => {\n const start = Date.now()\n const spec = ctx.env?.flowSpec ?? input.flowSpec\n if (!spec) {\n return {\n layer: input.name ?? 'flow',\n status: 'skipped',\n durationMs: 0,\n findings: [],\n reason: 'no flowSpec supplied',\n }\n }\n\n let runner: FlowRunner\n try {\n runner = await input.runner()\n } catch (err) {\n return {\n layer: input.name ?? 'flow',\n status: 'error',\n durationMs: Date.now() - start,\n findings: [\n {\n severity: 'major',\n message: `flow runner failed to start: ${err instanceof Error ? err.message : String(err)}`,\n },\n ],\n reason: 'runner-init-failed',\n }\n }\n\n const findings: LayerResult['findings'] = []\n const stepResults: Array<{ step: FlowStep; result: FlowRunnerStepResult; index: number }> = []\n let openOk = false\n try {\n const opened = await runner.open(spec.url)\n openOk = opened.ok\n if (!opened.ok) {\n findings.push({\n severity: 'major',\n message: `flow.open(${spec.url}) failed${opened.evidence ? `: ${opened.evidence}` : ''}`,\n })\n }\n if (openOk || spec.continueOnFail) {\n for (let i = 0; i < spec.steps.length; i++) {\n const step = spec.steps[i]!\n if (ctx.signal.aborted) break\n const stepStart = Date.now()\n let result: FlowRunnerStepResult\n try {\n result = await runner.step(step)\n } catch (err) {\n result = {\n ok: false,\n evidence: err instanceof Error ? err.message : String(err),\n durationMs: Date.now() - stepStart,\n }\n }\n stepResults.push({ step, result, index: i })\n if (!result.ok) {\n findings.push({\n severity: step.severity ?? 'major',\n message: `step[${i}] ${step.action}${step.target ? `(${step.target})` : ''} failed${result.evidence ? `: ${result.evidence}` : ''}`,\n })\n if (!spec.continueOnFail) break\n }\n }\n }\n } finally {\n try {\n await runner.close()\n } catch {\n /* best effort */\n }\n }\n\n const totalSteps = spec.steps.length\n const ranSteps = stepResults.length\n const passedSteps = stepResults.filter((s) => s.result.ok).length\n const status: LayerResult['status'] = !openOk\n ? 'fail'\n : passedSteps === totalSteps\n ? 'pass'\n : 'fail'\n // Score: open + each passing step contribute equally. A flow with\n // 4 steps where 3 pass scores 4/5 = 0.8 (0.2 from the open + 3*0.2\n // from the steps when totalSteps=4). We weight open and steps\n // equally to avoid any single step dominating short specs.\n const denominator = 1 + totalSteps\n const numerator = (openOk ? 1 : 0) + passedSteps\n const score = denominator > 0 ? Number((numerator / denominator).toFixed(3)) : 0\n\n return {\n layer: input.name ?? 'flow',\n status,\n score,\n durationMs: Date.now() - start,\n findings,\n reason:\n status === 'pass'\n ? `${totalSteps}/${totalSteps} steps passed`\n : `${passedSteps}/${totalSteps} steps passed${ranSteps < totalSteps ? ` (stopped at step ${ranSteps})` : ''}`,\n diagnostics: {\n flowOpenOk: openOk ? 1 : 0,\n flowStepsTotal: totalSteps,\n flowStepsPassed: passedSteps,\n flowStepsRan: ranSteps,\n },\n }\n },\n }\n}\n","/**\n * Intent-match judge — \"did the agent build the right APP, ignoring\n * whether every feature is wired up?\"\n *\n * Distinct from {@link runSemanticConceptJudge} which scores per-concept\n * presence. The semantic judge can return 0/4 concepts present even\n * when the agent built a thoughtful, polished, on-brief app that just\n * lacks one or two features. The semantic judge can also return 4/4\n * present even when the agent shipped the wrong project (keyword-rich\n * stub).\n *\n * Intent-match asks ONE question:\n * \"Looking at the agent's work as a whole — independent of feature\n * coverage — is this an honest attempt at the user's request?\"\n *\n * Returns a 0–1 score and a 1-sentence evidence string. Use as a sanity\n * check on `completenessScore`-style metrics: if intent-match is high\n * and concept count is low, the agent built the right thing but is\n * missing features (ship and iterate). If intent-match is low, the\n * agent built the wrong thing (reject regardless of concept count).\n *\n * Soft-fails on LLM/JSON error (`available: false`) so callers can\n * treat failure as \"judge skipped.\"\n */\n\nimport { callLlmJson, type LlmClientOptions } from './llm-client'\n\nexport const INTENT_MATCH_JUDGE_VERSION = 'intent-match-judge-v1-2026-04-24'\n\nexport interface IntentMatchInput {\n /** The full natural-language prompt the agent was handed. */\n userRequest: string\n /** Top-level source files from the agent's workdir. */\n sourceFiles: Array<{ path: string; content: string }>\n /** Rendered HTML the preview returned, when available. */\n servedHtml?: string\n /** Optional metadata to inject (id, vertical, difficulty). */\n artifactLabel?: string\n artifactDescription?: string\n}\n\nexport interface IntentMatchResult {\n kind: 'intent-match'\n version: string\n /** 0..1 — 1 = unmistakably the right app, 0 = unrelated to the brief. */\n score: number\n /** One-sentence rationale citing concrete evidence (file or HTML). */\n evidence: string\n durationMs: number\n costUsd: number | null\n available: boolean\n error?: string\n}\n\nexport interface IntentMatchOptions {\n model?: string\n timeoutMs?: number\n maxSourceChars?: number\n maxPerFileChars?: number\n maxHtmlChars?: number\n llm?: LlmClientOptions\n}\n\nconst DEFAULT_MODEL = 'claude-sonnet-4-6'\nconst DEFAULT_TIMEOUT = 90_000\nconst DEFAULT_MAX_SOURCE = 25_000\nconst DEFAULT_MAX_PER_FILE = 12_000\nconst DEFAULT_MAX_HTML = 20_000\n\nconst INTENT_SCHEMA = {\n type: 'object',\n additionalProperties: false,\n required: ['score', 'evidence'],\n properties: {\n score: { type: 'number', minimum: 0, maximum: 1 },\n evidence: { type: 'string', minLength: 10, maxLength: 400 },\n },\n}\n\nfunction truncate(body: string, cap: number, label: string): string {\n if (body.length <= cap) return body\n return `${body.slice(0, cap)}\\n… [truncated ${body.length - cap} chars of ${label}]`\n}\n\nfunction buildPrompt(input: IntentMatchInput, opts: Required<IntentMatchOptions>): string {\n const sourceBlob = input.sourceFiles\n .filter((f) => f.content.length <= opts.maxPerFileChars)\n .map((f) => `--- FILE: ${f.path} ---\\n${f.content}`)\n .join('\\n\\n')\n const html = input.servedHtml ?? ''\n\n return `You are evaluating whether an agent built THE RIGHT APP for a user request.\n\nYou are NOT scoring feature coverage. You are NOT scoring code quality.\nYou are answering ONE question: when a person looks at this work, do they\nsee an honest attempt at the user's request — or do they see the wrong\nproject entirely?\n\nUSER REQUEST:\n${input.userRequest}\n\n${input.artifactLabel ? `ARTIFACT METADATA:\\n name: ${input.artifactLabel}\\n description: ${input.artifactDescription ?? ''}\\n\\n` : ''}${html ? `SERVED HTML (what the preview returns):\\n${truncate(html, opts.maxHtmlChars, 'HTML')}\\n\\n` : ''}SOURCE FILES (the agent's workdir):\n${truncate(sourceBlob, opts.maxSourceChars, 'source')}\n\nScore 0–1:\n 1.0 — unmistakably the right app. Even with bugs, gaps, or missing\n features, a reviewer would say \"yes, this is what was asked for.\"\n 0.7 — recognizable. Domain matches; some required surface areas exist.\n A reviewer would say \"right direction, lots of work needed.\"\n 0.4 — partially related. Wrong framing or wrong product entirely but\n with some shared keywords or a tangential overlap.\n 0.0 — wrong project. The agent shipped something unrelated to the\n request (e.g. asked for an NFT mint page, shipped a generic\n landing page with zero NFT-related code).\n\nEvidence: one sentence citing the strongest concrete signal — a file\nname, a route, a rendered headline, a missing core surface. Don't\nrestate the request.\n\nExamples:\n - \"src/App.tsx renders <MintWidget /> with mint-1/mint-5 buttons and\n wagmi imports — clearly the requested NFT mint page.\" → 0.95\n - \"src/App.tsx is the default Vite React template; no\n mint/wallet/contract code in any file under src/.\" → 0.05\n\nReturn STRICT JSON. No prose outside.`\n}\n\n/**\n * Run the intent-match judge. Soft-fails to available=false on error.\n */\nexport async function runIntentMatchJudge(\n input: IntentMatchInput,\n options: IntentMatchOptions = {},\n): Promise<IntentMatchResult> {\n const start = Date.now()\n const opts: Required<IntentMatchOptions> = {\n model: options.model ?? DEFAULT_MODEL,\n timeoutMs: options.timeoutMs ?? DEFAULT_TIMEOUT,\n maxSourceChars: options.maxSourceChars ?? DEFAULT_MAX_SOURCE,\n maxPerFileChars: options.maxPerFileChars ?? DEFAULT_MAX_PER_FILE,\n maxHtmlChars: options.maxHtmlChars ?? DEFAULT_MAX_HTML,\n llm: options.llm ?? {},\n }\n\n if (input.sourceFiles.length === 0 && !input.servedHtml) {\n return {\n kind: 'intent-match',\n version: INTENT_MATCH_JUDGE_VERSION,\n score: 0,\n evidence: 'no source files and no served HTML — nothing to evaluate',\n durationMs: 0,\n costUsd: null,\n available: false,\n error: 'no input artifact',\n }\n }\n\n try {\n const { value, result } = await callLlmJson<{ score: number; evidence: string }>(\n {\n model: opts.model,\n messages: [\n {\n role: 'system',\n content:\n 'You are a holistic code reviewer answering one question: did the agent build the right app for the user. Return strict JSON. No prose outside.',\n },\n { role: 'user', content: buildPrompt(input, opts) },\n ],\n jsonSchema: { name: 'intent_match_judge', schema: INTENT_SCHEMA },\n temperature: 0,\n timeoutMs: opts.timeoutMs,\n },\n opts.llm,\n )\n\n const score = Math.max(0, Math.min(1, Number(value?.score ?? 0)))\n return {\n kind: 'intent-match',\n version: INTENT_MATCH_JUDGE_VERSION,\n score: Number(score.toFixed(3)),\n evidence: String(value?.evidence ?? '').slice(0, 400),\n durationMs: Date.now() - start,\n costUsd: result.costUsd ?? null,\n available: true,\n }\n } catch (err) {\n return {\n kind: 'intent-match',\n version: INTENT_MATCH_JUDGE_VERSION,\n score: 0,\n evidence: '',\n durationMs: Date.now() - start,\n costUsd: null,\n available: false,\n error: err instanceof Error ? err.message : String(err),\n }\n }\n}\n\n/**\n * Factory: pin LLM options once, return a closure.\n */\nexport function createIntentMatchJudge(\n options: IntentMatchOptions = {},\n): (input: IntentMatchInput) => Promise<IntentMatchResult> {\n return (input) => runIntentMatchJudge(input, options)\n}\n","/**\n * Keyword-coverage judge — baseline complement to the semantic concept\n * judge.\n *\n * Where {@link runSemanticConceptJudge} uses an LLM to read source code\n * and decide whether a concept is REALLY implemented (not just\n * keyword-mentioned), this judge does the cheap, deterministic version:\n * fetch the served preview, concatenate every linked CSS/JS asset, and\n * substring-match each expected concept's keywords against the\n * concatenated haystack. Optional `requiredElement` selector adds a\n * structural gate so \"supply counter\" can require an actual `<input>` or\n * `<table>`, not just a comment containing the word.\n *\n * Use both judges. Keyword coverage is a fast 0-cost gate — a stub page\n * with the right keywords passes here, fails the semantic judge. Score\n * divergence between the two is itself a signal: high keyword coverage\n * + low semantic = \"the agent slapped the right words on the right\n * scaffold but didn't wire any of it up.\"\n *\n * Pure functions, soft-fail on fetch error, no LLM dependency.\n */\n\n// ─── Types ──────────────────────────────────────────────────────────────\n\nexport interface KeywordConceptSpec {\n name: string\n keywords: string[]\n /**\n * Optional CSS selector that must match in the HTML for the concept\n * to count as present. Tiny subset:\n * - `tag` (e.g. `form`)\n * - `tag[attr=\"value\"]` (e.g. `input[type=\"number\"]`)\n * - `tag[attr]` (presence only)\n * Anything more complex is rejected with `null` (treated as\n * \"unenforced\", not \"failed\").\n */\n requiredElement?: string\n}\n\nexport interface KeywordCoverageFinding {\n concept: string\n found: boolean\n matchedKeywords: string[]\n /** True iff the optional requiredElement selector matched; null when no selector. */\n requiredElementPresent: boolean | null\n}\n\nexport interface KeywordCoverageResult {\n /** 0..1 share of concepts satisfied. */\n score: number\n presentCount: number\n totalCount: number\n findings: KeywordCoverageFinding[]\n durationMs: number\n /** Total bytes assembled across html + linked assets. */\n totalAssembledBytes: number\n /** Soft-failure reason if the audit couldn't run. */\n error?: string\n}\n\nexport interface KeywordCoverageOptions {\n /** Override fetch implementation — for tests. */\n fetch?: typeof fetch\n /** Per-asset fetch timeout (default 3s). */\n assetTimeoutMs?: number\n /** Initial-HTML fetch timeout (default 5s). */\n htmlTimeoutMs?: number\n}\n\n// ─── Selector matcher ──────────────────────────────────────────────────\n\n/**\n * Element-presence check using a tiny CSS-selector subset. Returns\n * null when the selector isn't supported — caller treats that as\n * \"unenforced\" rather than \"failed.\"\n */\nexport function htmlContainsElement(html: string, selector: string): boolean | null {\n const tagOnly = /^([a-zA-Z][\\w-]*)$/.exec(selector)\n if (tagOnly) {\n const re = new RegExp(`<${tagOnly[1]}\\\\b`, 'i')\n return re.test(html)\n }\n const tagAttrEq = /^([a-zA-Z][\\w-]*)\\[([\\w-]+)\\s*=\\s*[\"']?([^\"'\\]]+)[\"']?\\]$/.exec(selector)\n if (tagAttrEq) {\n const [, tag, attr, value] = tagAttrEq\n const re = new RegExp(\n `<${tag}\\\\b[^>]*\\\\b${attr}\\\\s*=\\\\s*[\"']${value!.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')}[\"']`,\n 'i',\n )\n return re.test(html)\n }\n const tagAttrPresence = /^([a-zA-Z][\\w-]*)\\[([\\w-]+)\\]$/.exec(selector)\n if (tagAttrPresence) {\n const [, tag, attr] = tagAttrPresence\n const re = new RegExp(`<${tag}\\\\b[^>]*\\\\b${attr}\\\\b`, 'i')\n return re.test(html)\n }\n return null\n}\n\n// ─── Asset extraction ─────────────────────────────────────────────────\n\n/**\n * Pull every `<link rel=stylesheet href>` and `<script src>` from a\n * raw HTML body. Returns absolute URLs resolved against `baseUrl`.\n * Permissive regex — agent-authored markup doesn't always quote\n * attributes the same way.\n */\nexport function extractAssetUrls(html: string, baseUrl: string): string[] {\n const urls = new Set<string>()\n const linkRe = /<link\\b[^>]*\\bhref\\s*=\\s*[\"']([^\"']+)[\"'][^>]*>/gi\n const scriptRe = /<script\\b[^>]*\\bsrc\\s*=\\s*[\"']([^\"']+)[\"'][^>]*>/gi\n for (const re of [linkRe, scriptRe]) {\n let match: RegExpExecArray | null\n while ((match = re.exec(html)) !== null) {\n const raw = match[1]!\n try {\n urls.add(new URL(raw, baseUrl).toString())\n } catch {\n // unresolvable refs (e.g. data: URLs) — skip\n }\n }\n }\n return Array.from(urls)\n}\n\n// ─── Coverage scorer ──────────────────────────────────────────────────\n\n/**\n * Score expected concepts against an already-fetched HTML payload + any\n * pre-fetched CSS/JS assets. Use when the runner has the bytes in hand\n * and doesn't want a fresh HTTP round-trip — e.g. sandbox runtime where\n * the preview content was fetched via curl from inside the container.\n */\nexport function runKeywordCoverageJudge(\n html: string,\n expectedConcepts: ReadonlyArray<KeywordConceptSpec>,\n assets: ReadonlyArray<string> = [],\n): KeywordCoverageResult {\n const start = Date.now()\n if (expectedConcepts.length === 0) {\n return {\n score: 0,\n presentCount: 0,\n totalCount: 0,\n findings: [],\n durationMs: 0,\n totalAssembledBytes: 0,\n }\n }\n const haystack = `${html}\\n${assets.join('\\n')}`.toLowerCase()\n const findings: KeywordCoverageFinding[] = expectedConcepts.map((concept) => {\n const matchedKeywords: string[] = []\n for (const kw of concept.keywords) {\n if (haystack.includes(kw.toLowerCase())) matchedKeywords.push(kw)\n }\n const requiredElementPresent = concept.requiredElement\n ? htmlContainsElement(html, concept.requiredElement)\n : null\n const passesElementGate = requiredElementPresent === null || requiredElementPresent === true\n const found = matchedKeywords.length > 0 && passesElementGate\n return { concept: concept.name, found, matchedKeywords, requiredElementPresent }\n })\n const presentCount = findings.filter((f) => f.found).length\n return {\n score: presentCount / expectedConcepts.length,\n presentCount,\n totalCount: expectedConcepts.length,\n findings,\n durationMs: Date.now() - start,\n totalAssembledBytes: haystack.length,\n }\n}\n\n/**\n * URL-fetch flavor — GET the preview, parallel-fetch every linked\n * stylesheet + script (with bounded timeouts, soft-fail individually),\n * then score via {@link runKeywordCoverageJudge}.\n */\nexport async function runKeywordCoverageJudgeUrl(\n previewUrl: string,\n expectedConcepts: ReadonlyArray<KeywordConceptSpec>,\n options: KeywordCoverageOptions = {},\n): Promise<KeywordCoverageResult> {\n const start = Date.now()\n const fetchFn = options.fetch ?? globalThis.fetch\n const htmlTimeout = options.htmlTimeoutMs ?? 5_000\n const assetTimeout = options.assetTimeoutMs ?? 3_000\n\n if (expectedConcepts.length === 0) {\n return {\n score: 0,\n presentCount: 0,\n totalCount: 0,\n findings: [],\n durationMs: 0,\n totalAssembledBytes: 0,\n }\n }\n\n let html = ''\n try {\n const resp = await fetchFn(previewUrl, {\n redirect: 'follow',\n signal: AbortSignal.timeout(htmlTimeout),\n })\n if (!resp.ok) {\n return softFail(expectedConcepts, start, `preview HTTP ${resp.status}`)\n }\n html = await resp.text()\n } catch (err) {\n return softFail(expectedConcepts, start, err instanceof Error ? err.message : String(err))\n }\n\n const assetUrls = extractAssetUrls(html, previewUrl)\n const assetBodies = await Promise.all(\n assetUrls.map(async (u) => {\n try {\n const r = await fetchFn(u, {\n redirect: 'follow',\n signal: AbortSignal.timeout(assetTimeout),\n })\n if (!r.ok) return ''\n return await r.text()\n } catch {\n return ''\n }\n }),\n )\n\n return runKeywordCoverageJudge(html, expectedConcepts, assetBodies)\n}\n\nfunction softFail(\n expectedConcepts: ReadonlyArray<KeywordConceptSpec>,\n start: number,\n error: string,\n): KeywordCoverageResult {\n return {\n score: 0,\n presentCount: 0,\n totalCount: expectedConcepts.length,\n findings: expectedConcepts.map((c) => ({\n concept: c.name,\n found: false,\n matchedKeywords: [],\n requiredElementPresent: null,\n })),\n durationMs: Date.now() - start,\n totalAssembledBytes: 0,\n error,\n }\n}\n","/**\n * Multi-layer verifier — ordered pipeline of verification layers.\n *\n * Different contract from {@link JudgeRunner} (which runs parallel\n * specs against a sandbox). MultiLayerVerifier is a DAG of layers\n * (install → typecheck → build → lint → serve → semantic → …) with\n * dependency-based skip, per-layer findings, soft-fail semantics, and\n * an aggregated `blendedScore` across all passed layers.\n *\n * Use when you want:\n * - ordered stages where a failing upstream stage skips downstream ones\n * - each stage produces rich `findings` (severity + message + evidence)\n * - a single composite score across stages with per-stage weights\n * - soft-fail stages whose failure doesn't abort the pipeline\n *\n * Use {@link JudgeRunner} when you want:\n * - N independent judges running in parallel against the same artifact\n * - no inter-judge dependencies\n * - boolean `passed` per judge + overall\n *\n * Both primitives compose — JudgeRunner can be invoked as a single\n * layer inside a MultiLayerVerifier if that suits the caller.\n */\n\n// ─── Types ──────────────────────────────────────────────────────────────\n\nexport type LayerStatus = 'pass' | 'fail' | 'skipped' | 'error' | 'timeout'\n\nexport type Severity = 'critical' | 'major' | 'minor' | 'info'\n\nexport interface Finding {\n severity: Severity\n message: string\n evidence?: string\n /** Optional layer name the finding belongs to (set by the verifier if omitted). */\n layer?: string\n /**\n * Free-form structured payload — used by `multiToolchainLayer` to attach\n * `{ adapter: 'pnpm' }`, by judges to attach evidence pointers, etc.\n * Renderers MAY interrogate; agent-eval primitives never assume shape.\n */\n detail?: Record<string, unknown>\n}\n\nexport interface LayerResult {\n layer: string\n status: LayerStatus\n /** 0..1 score, optional — layers that don't produce a numeric score omit. */\n score?: number\n durationMs: number\n findings: Finding[]\n /** Short human-readable summary (one line). */\n reason?: string\n /**\n * Numeric layer-level diagnostics: error counts, warning counts,\n * cyclomatic complexity, total adapter wall-time, etc. Keyed by\n * diagnostic name; null = \"diagnostic not applicable / not measured.\"\n * Renderers that know the keys can display them; ones that don't,\n * ignore. Free-form on purpose — consumers type the value shape in\n * their own namespace.\n */\n diagnostics?: Record<string, number | null>\n /** Any rich per-layer detail — rendered as-is by consumers that know the layer. */\n detail?: Record<string, unknown>\n}\n\nexport interface VerifyContext<Env = unknown> {\n /** Per-run opaque context the caller provides. Layers destructure what they need. */\n env: Env\n /** Previously-computed results from layers that already ran. */\n prior: Record<string, LayerResult>\n /** Signal — if aborted, layers MUST bail within reasonable wall. */\n signal: AbortSignal\n}\n\nexport interface Layer<Env = unknown> {\n name: string\n /** Stages that must have `status: 'pass'` before this layer runs. */\n dependsOn?: string[]\n /**\n * Weight in the composite `blendedScore`. Default 1.0. Layers with weight 0\n * contribute findings but not score.\n */\n weight?: number\n /**\n * If true, a `fail` status contributes to `blendedScore` (as 0) instead of\n * being dropped — use for layers whose failure is a real signal. Default:\n * fail drops from numerator + denominator, matching VB's existing semantics.\n */\n failContributesToScore?: boolean\n /** Optional per-layer wall-cap in ms. Honored by the verifier (AbortSignal). */\n capMs?: number\n run: (ctx: VerifyContext<Env>) => Promise<LayerResult> | LayerResult\n}\n\nexport interface VerifyOptions<Env = unknown> {\n env: Env\n /**\n * Overall wall cap. Default: sum of layer capMs, or Infinity if any layer\n * omits a cap. The verifier short-circuits remaining layers on overall cap.\n */\n overallCapMs?: number\n /** Called with each layer result as it completes. */\n onLayer?: (result: LayerResult) => void\n}\n\nexport interface VerificationReport {\n layers: LayerResult[]\n passCount: number\n failCount: number\n skippedCount: number\n errorCount: number\n /** True iff at least one scored layer ran AND every scored layer passed. */\n allPass: boolean\n /**\n * Weighted mean of `score` across contributing layers. 0 when no layers\n * contributed. See {@link Layer.failContributesToScore} for fail semantics.\n */\n blendedScore: number\n durationMs: number\n startedAt: string\n finishedAt: string\n}\n\n// ─── Helpers ────────────────────────────────────────────────────────────\n\n/**\n * Grade a semantic-concept-style judge result into a single layer status.\n *\n * Pass when overall score >= threshold AND no critical-severity concept gap.\n * Fail otherwise. Use inside a `Layer.run` when wrapping a concept judge.\n *\n * Generalized from VerticalBench H3 fix: `failingConcepts.length === 0` was\n * too strict — a single concept at 6/10 failed the entire layer despite\n * overall score being >= 0.7. Now we trust the judge's own `severity` field:\n * `critical` findings veto; `major`/`minor` reduce the score but don't veto.\n */\nexport function gradeSemanticStatus(input: {\n score: number\n findings: Array<{ severity: Severity; present?: boolean; score?: number }>\n available: boolean\n threshold?: number\n}): LayerStatus {\n if (!input.available) return 'error'\n const threshold = input.threshold ?? 0.7\n const criticalGaps = input.findings.filter(\n (f) => f.severity === 'critical' && (f.present === false || (f.score ?? 0) < 7),\n )\n return input.score >= threshold && criticalGaps.length === 0 ? 'pass' : 'fail'\n}\n\n// ─── Verifier ───────────────────────────────────────────────────────────\n\nexport class MultiLayerVerifier<Env = unknown> {\n constructor(private readonly layers: Layer<Env>[]) {\n const seen = new Set<string>()\n for (const l of layers) {\n if (seen.has(l.name)) throw new Error(`MultiLayerVerifier: duplicate layer name \"${l.name}\"`)\n seen.add(l.name)\n }\n for (const l of layers) {\n for (const dep of l.dependsOn ?? []) {\n if (!seen.has(dep)) {\n throw new Error(\n `MultiLayerVerifier: layer \"${l.name}\" depends on \"${dep}\" which is not registered`,\n )\n }\n }\n }\n }\n\n async run(opts: VerifyOptions<Env>): Promise<VerificationReport> {\n const startedAtMs = Date.now()\n const startedAt = new Date(startedAtMs).toISOString()\n const controller = new AbortController()\n const overallCap = opts.overallCapMs\n const overallTimer =\n overallCap != null\n ? setTimeout(() => controller.abort(new Error('overall cap exceeded')), overallCap)\n : null\n\n const results: LayerResult[] = []\n const byName: Record<string, LayerResult> = {}\n\n try {\n for (const layer of this.layers) {\n // Skip if any dependency didn't pass.\n const unmet = (layer.dependsOn ?? []).filter((d) => byName[d]?.status !== 'pass')\n if (unmet.length > 0) {\n const skipped: LayerResult = {\n layer: layer.name,\n status: 'skipped',\n durationMs: 0,\n findings: [],\n reason: `skipped — upstream not passing: ${unmet.join(', ')}`,\n }\n results.push(skipped)\n byName[layer.name] = skipped\n opts.onLayer?.(skipped)\n continue\n }\n\n // Per-layer cap — compose with overall signal.\n const perLayerController = new AbortController()\n const mergedSignal = mergeSignals(controller.signal, perLayerController.signal)\n const layerTimer =\n layer.capMs != null\n ? setTimeout(\n () => perLayerController.abort(new Error(`layer ${layer.name} cap`)),\n layer.capMs,\n )\n : null\n\n const layerStart = Date.now()\n let result: LayerResult\n try {\n result = await layer.run({ env: opts.env, prior: { ...byName }, signal: mergedSignal })\n } catch (err) {\n const aborted = mergedSignal.aborted\n result = {\n layer: layer.name,\n status: aborted ? 'timeout' : 'error',\n durationMs: Date.now() - layerStart,\n findings: [\n {\n severity: 'major',\n message: err instanceof Error ? err.message : String(err),\n layer: layer.name,\n },\n ],\n reason: err instanceof Error ? err.message : String(err),\n }\n } finally {\n if (layerTimer) clearTimeout(layerTimer)\n }\n\n // Normalize findings to attach layer name if omitted.\n result.findings = result.findings.map((f) => ({ ...f, layer: f.layer ?? layer.name }))\n results.push(result)\n byName[layer.name] = result\n opts.onLayer?.(result)\n\n if (controller.signal.aborted) break\n }\n\n const report = aggregate(this.layers, results, startedAt, startedAtMs)\n return report\n } finally {\n if (overallTimer) clearTimeout(overallTimer)\n }\n }\n}\n\nfunction aggregate<Env>(\n layers: Layer<Env>[],\n results: LayerResult[],\n startedAt: string,\n startedAtMs: number,\n): VerificationReport {\n const weightByName = new Map<string, number>()\n const failContribByName = new Map<string, boolean>()\n for (const l of layers) {\n weightByName.set(l.name, l.weight ?? 1)\n failContribByName.set(l.name, l.failContributesToScore ?? false)\n }\n\n let passCount = 0\n let failCount = 0\n let skippedCount = 0\n let errorCount = 0\n let scoredWeightSum = 0\n let scoredWeightedTotal = 0\n let ranAnyScoredLayer = false\n let anyScoredLayerFailed = false\n\n for (const r of results) {\n const weight = weightByName.get(r.layer) ?? 1\n const failContrib = failContribByName.get(r.layer) ?? false\n if (r.status === 'pass') passCount++\n else if (r.status === 'fail') failCount++\n else if (r.status === 'skipped') skippedCount++\n else errorCount++\n\n if (r.score != null && weight > 0) {\n if (r.status === 'pass') {\n ranAnyScoredLayer = true\n scoredWeightSum += weight\n scoredWeightedTotal += weight * r.score\n } else if (r.status === 'fail') {\n if (failContrib) {\n ranAnyScoredLayer = true\n scoredWeightSum += weight\n scoredWeightedTotal += weight * r.score\n }\n anyScoredLayerFailed = true\n }\n // skipped / error / timeout layers don't contribute\n } else if (r.status === 'fail') {\n anyScoredLayerFailed = true\n }\n }\n\n const finishedAtMs = Date.now()\n return {\n layers: results,\n passCount,\n failCount,\n skippedCount,\n errorCount,\n allPass: ranAnyScoredLayer && !anyScoredLayerFailed && failCount === 0 && errorCount === 0,\n blendedScore: scoredWeightSum > 0 ? scoredWeightedTotal / scoredWeightSum : 0,\n durationMs: finishedAtMs - startedAtMs,\n startedAt,\n finishedAt: new Date(finishedAtMs).toISOString(),\n }\n}\n\nfunction mergeSignals(a: AbortSignal, b: AbortSignal): AbortSignal {\n if (a.aborted) return a\n if (b.aborted) return b\n const c = new AbortController()\n const onAbort = (signal: AbortSignal) => () => c.abort(signal.reason)\n a.addEventListener('abort', onAbort(a), { once: true })\n b.addEventListener('abort', onAbort(b), { once: true })\n return c.signal\n}\n","/**\n * Multi-toolchain layer factory + merge helper.\n *\n * Some verification stages (install, typecheck, build, lint) run the\n * SAME logical layer across multiple parallel adapters — pnpm AND npm\n * AND cargo AND forge for a polyglot scaffold. The verifier presents\n * one row per stage; the toolchain breakdown lives in `findings.detail`.\n *\n * This module provides the merge: take N independent `LayerResult`s\n * (one per adapter) and reduce them to a single `LayerResult` whose\n * status is the worst of the parts and whose findings cite the adapter\n * that produced each one. Plus a {@link multiToolchainLayer} factory\n * that runs the adapter calls in parallel + applies the reducer.\n *\n * Pure utility — composes with {@link MultiLayerVerifier}.{run}.\n */\n\nimport type {\n Layer,\n LayerResult,\n LayerStatus,\n Severity,\n VerifyContext,\n} from './multi-layer-verifier'\n\n// ─── Status reduction ──────────────────────────────────────────────────\n\nconst STATUS_RANK: Record<LayerStatus, number> = {\n pass: 0,\n skipped: 1,\n fail: 2,\n timeout: 3,\n error: 4,\n}\n\nfunction worst(a: LayerStatus, b: LayerStatus): LayerStatus {\n return (STATUS_RANK[a] ?? 0) >= (STATUS_RANK[b] ?? 0) ? a : b\n}\n\nconst SEVERITY_RANK: Record<Severity, number> = {\n info: 0,\n minor: 1,\n major: 2,\n critical: 3,\n}\n\nfunction maxSeverity(findings: ReadonlyArray<{ severity: Severity }>): Severity {\n let best: Severity = 'info'\n for (const f of findings) {\n if (SEVERITY_RANK[f.severity] > SEVERITY_RANK[best]) best = f.severity\n }\n return best\n}\n\n// ─── Merge ──────────────────────────────────────────────────────────────\n\nexport interface AdapterRun {\n /** Identifier for the adapter (e.g. 'pnpm', 'npm', 'cargo', 'forge'). */\n adapter: string\n result: LayerResult\n}\n\nexport interface MergeOptions {\n /**\n * How to combine per-adapter `durationMs`. Default `'max'` (parallel\n * wall-clock). Set `'sum'` when reporting total work done across\n * adapters rather than wall time.\n */\n mergeDuration?: 'max' | 'sum'\n /**\n * Prefix finding messages with a per-adapter tag (e.g. `[pnpm] typecheck failed`).\n * Default: no prefix (renderers read `detail.adapter` instead).\n */\n messagePrefixer?: (adapter: string) => string\n /**\n * How to reduce per-adapter `LayerResult.diagnostics` into the merged\n * result's diagnostics. `'max'` (default) — for each key, merged =\n * max across adapters where value is non-null (matches \"if ANY adapter\n * saw N errors, merged saw N\"). `'sum'` — sum non-null values.\n */\n mergeDiagnostics?: 'max' | 'sum'\n}\n\n/**\n * Reduce N adapter runs to a single `LayerResult` for a logical layer.\n *\n * - status: worst of the parts (pass < skipped < fail < timeout < error)\n * - score: weighted mean of numeric scores (skip = no contribution)\n * - findings: union, each tagged with `detail.adapter`\n * - durationMs: `mergeDuration` option (default 'max' for parallel wall-clock)\n * - diagnostics: `mergeDiagnostics` option (default 'max' per key)\n * - reason: \" · \"-joined `name: status` per adapter\n */\nexport function mergeLayerResults(\n name: string,\n perAdapter: AdapterRun[],\n options: MergeOptions = {},\n): LayerResult {\n const mergeDuration = options.mergeDuration ?? 'max'\n const mergeDiagnostics = options.mergeDiagnostics ?? 'max'\n const prefix = options.messagePrefixer\n\n if (perAdapter.length === 0) {\n return {\n layer: name,\n status: 'skipped',\n durationMs: 0,\n findings: [],\n reason: 'no adapters',\n }\n }\n if (perAdapter.length === 1) {\n const only = perAdapter[0]!\n return {\n ...only.result,\n layer: name,\n findings: only.result.findings.map((f) => ({\n ...f,\n layer: name,\n message: prefix ? `${prefix(only.adapter)} ${f.message}` : f.message,\n detail: { ...(f.detail ?? {}), adapter: only.adapter },\n })),\n reason: only.result.reason ?? `${only.adapter}: ${only.result.status}`,\n }\n }\n\n let status: LayerStatus = 'pass'\n let weightedScoreSum = 0\n let weightCount = 0\n const findings: LayerResult['findings'] = []\n let durationMs = 0\n const reasonParts: string[] = []\n const diagnostics: Record<string, number | null> = {}\n\n for (const { adapter, result } of perAdapter) {\n status = worst(status, result.status)\n if (typeof result.score === 'number') {\n weightedScoreSum += result.score\n weightCount += 1\n }\n durationMs =\n mergeDuration === 'sum'\n ? durationMs + result.durationMs\n : Math.max(durationMs, result.durationMs)\n reasonParts.push(`${adapter}: ${result.status}`)\n for (const f of result.findings) {\n findings.push({\n ...f,\n layer: name,\n message: prefix ? `${prefix(adapter)} ${f.message}` : f.message,\n detail: { ...(f.detail ?? {}), adapter },\n })\n }\n for (const [k, v] of Object.entries(result.diagnostics ?? {})) {\n if (typeof v !== 'number' || !Number.isFinite(v)) continue\n const prev = diagnostics[k]\n if (prev == null) diagnostics[k] = v\n else diagnostics[k] = mergeDiagnostics === 'sum' ? prev + v : Math.max(prev, v)\n }\n }\n\n return {\n layer: name,\n status,\n score: weightCount > 0 ? weightedScoreSum / weightCount : undefined,\n durationMs,\n findings,\n reason: reasonParts.join(' · '),\n diagnostics: Object.keys(diagnostics).length > 0 ? diagnostics : undefined,\n detail: {\n adapters: perAdapter.map(({ adapter, result }) => ({\n adapter,\n status: result.status,\n score: result.score ?? null,\n })),\n worstSeverity: maxSeverity(findings),\n },\n }\n}\n\n// ─── Layer factory ──────────────────────────────────────────────────────\n\nexport interface MultiToolchainLayerConfig<Env, Adapter> {\n name: string\n adapters: ReadonlyArray<Adapter>\n /** Adapter identifier — used in findings + reason. */\n adapterName: (a: Adapter) => string\n /** Run a single adapter against the verify context. */\n run: (a: Adapter, ctx: VerifyContext<Env>) => Promise<LayerResult> | LayerResult\n dependsOn?: string[]\n weight?: number\n failContributesToScore?: boolean\n capMs?: number\n /**\n * Per-adapter parallel cap. Defaults to 8 — defense in depth against a\n * caller passing 50 adapters and fanning out 50 simultaneous subprocesses.\n * Adapters that need higher concurrency raise this explicitly.\n */\n maxParallel?: number\n}\n\n/**\n * Build a {@link Layer} that fans the same logical stage across N adapters\n * in parallel and merges via {@link mergeLayerResults}.\n *\n * Per-adapter throws are caught + converted to `status: 'error'` results\n * so one bad adapter doesn't poison the whole layer.\n */\nexport function multiToolchainLayer<Env, Adapter>(\n config: MultiToolchainLayerConfig<Env, Adapter>,\n): Layer<Env> {\n const maxParallel = Math.max(1, config.maxParallel ?? 8)\n return {\n name: config.name,\n dependsOn: config.dependsOn,\n weight: config.weight,\n failContributesToScore: config.failContributesToScore,\n capMs: config.capMs,\n async run(ctx) {\n if (config.adapters.length === 0) {\n return {\n layer: config.name,\n status: 'skipped',\n durationMs: 0,\n findings: [],\n reason: 'no adapters detected',\n }\n }\n\n const runOne = async (adapter: Adapter): Promise<AdapterRun> => {\n const adapterName = config.adapterName(adapter)\n try {\n const r = await config.run(adapter, ctx)\n return { adapter: adapterName, result: r }\n } catch (err) {\n return {\n adapter: adapterName,\n result: {\n layer: config.name,\n status: 'error',\n durationMs: 0,\n findings: [\n {\n severity: 'major',\n layer: config.name,\n message: err instanceof Error ? err.message : String(err),\n detail: { adapter: adapterName },\n },\n ],\n reason: err instanceof Error ? err.message : String(err),\n },\n }\n }\n }\n\n // Bounded parallelism — chunked into groups of size maxParallel.\n const results: AdapterRun[] = []\n for (let i = 0; i < config.adapters.length; i += maxParallel) {\n const chunk = config.adapters.slice(i, i + maxParallel)\n const chunkResults = await Promise.all(chunk.map(runOne))\n results.push(...chunkResults)\n }\n return mergeLayerResults(config.name, results)\n },\n }\n}\n","/**\n * Reference replay — score an agent against withheld historical outcomes.\n *\n * This is the generic version of the public-audit replay pattern:\n * run a candidate system on an old task, keep the reference answers hidden\n * until after execution, then score recall/precision and gate promotion\n * across train/dev/test/holdout splits.\n */\n\nimport { appendFileSync, existsSync, mkdirSync, readFileSync } from 'node:fs'\nimport { dirname } from 'node:path'\nimport { Mutex } from './concurrency'\n\nexport type ReferenceReplaySplit = 'train' | 'dev' | 'test' | 'holdout'\nexport type ReferenceReplayMatchStrategy = 'reference-order' | 'global-greedy'\n\nexport interface ReferenceReplayItem {\n id: string\n title: string\n description?: string\n severity?: string\n tags?: string[]\n weight?: number\n}\n\nexport interface ReferenceReplayCandidate {\n id: string\n title: string\n description?: string\n severity?: string\n tags?: string[]\n metadata?: Record<string, unknown>\n}\n\nexport interface ReferenceReplayScenario {\n id: string\n split?: ReferenceReplaySplit\n references: ReferenceReplayItem[]\n candidates: ReferenceReplayCandidate[]\n metadata?: Record<string, unknown>\n}\n\nexport interface ReferenceReplayCase<Input = unknown> {\n id: string\n split?: ReferenceReplaySplit\n input: Input\n references: ReferenceReplayItem[]\n metadata?: Record<string, unknown>\n}\n\nexport interface ReferenceReplayExecutionScenario<Input = unknown> {\n id: string\n split: ReferenceReplaySplit\n input: Input\n metadata?: Record<string, unknown>\n}\n\nexport interface ReferenceReplayRunContext {\n runId: string\n caseIndex: number\n abortSignal?: AbortSignal\n}\n\nexport interface ReferenceReplayAdapter<Input = unknown> {\n run(\n scenario: ReferenceReplayExecutionScenario<Input>,\n context: ReferenceReplayRunContext,\n ): Promise<ReferenceReplayCandidate[]>\n}\n\nexport type ReferenceReplayAdapterFn<Input = unknown> = (\n scenario: ReferenceReplayExecutionScenario<Input>,\n context: ReferenceReplayRunContext,\n) => Promise<ReferenceReplayCandidate[]>\n\nexport type ReferenceReplayAdapterLike<Input = unknown> =\n | ReferenceReplayAdapter<Input>\n | ReferenceReplayAdapterFn<Input>\n\nexport interface ReferenceReplayMatch {\n scenarioId: string\n referenceId: string\n candidateId: string | null\n score: number\n matched: boolean\n weight: number\n reason: string\n}\n\nexport interface ReferenceReplayScenarioScore {\n scenarioId: string\n split: ReferenceReplaySplit\n matched: number\n total: number\n falsePositives: number\n matchedWeight: number\n totalWeight: number\n precision: number\n recall: number\n f1: number\n matches: ReferenceReplayMatch[]\n}\n\nexport interface ReferenceReplayAggregate {\n matched: number\n total: number\n falsePositives: number\n matchedWeight: number\n totalWeight: number\n precision: number\n recall: number\n f1: number\n weightedRecall: number\n}\n\nexport interface ReferenceReplayScore {\n scenarios: ReferenceReplayScenarioScore[]\n aggregate: ReferenceReplayAggregate\n bySplit: Partial<Record<ReferenceReplaySplit, ReferenceReplayAggregate>>\n}\n\nexport interface ReferenceMatchResult {\n score: number\n reason?: string\n}\n\nexport type ReferenceReplayMatcher = (\n reference: ReferenceReplayItem,\n candidate: ReferenceReplayCandidate,\n scenario: ReferenceReplayScenario,\n) => ReferenceMatchResult\n\nexport interface ReferenceReplayScoreOptions {\n matcher?: ReferenceReplayMatcher\n matchThreshold?: number\n matchStrategy?: ReferenceReplayMatchStrategy\n includeHoldout?: boolean\n splits?: ReferenceReplaySplit[]\n}\n\nexport interface ReferenceReplayPromotionPolicy {\n /** Splits that must improve or stay flat. Default: ['dev', 'test']. */\n requiredSplits?: ReferenceReplaySplit[]\n /** Minimum aggregate F1 lift required on required splits. Default 0. */\n minF1Delta?: number\n /** Maximum F1 drop allowed on any compared split. Default 0. */\n maxRegression?: number\n /** If true, holdout must be present and must not regress. Default true. */\n requireHoldoutNonRegression?: boolean\n}\n\nexport interface ReferenceReplaySplitComparison {\n split: ReferenceReplaySplit\n baselineF1: number\n candidateF1: number\n f1Delta: number\n baselineRecall: number\n candidateRecall: number\n recallDelta: number\n}\n\nexport interface ReferenceReplayPromotionDecision {\n promote: boolean\n reason: string\n aggregateDelta: number\n comparisons: ReferenceReplaySplitComparison[]\n regressions: ReferenceReplaySplitComparison[]\n}\n\nexport interface ReferenceReplayCaseRun<Input = unknown> {\n caseId: string\n split: ReferenceReplaySplit\n input: Input\n metadata?: Record<string, unknown>\n references: ReferenceReplayItem[]\n candidates: ReferenceReplayCandidate[]\n score: ReferenceReplayScenarioScore\n durationMs: number\n error?: string\n}\n\nexport interface ReferenceReplayRun<Input = unknown> {\n id: string\n variantId?: string\n startedAt: number\n completedAt: number\n durationMs: number\n cases: ReferenceReplayCaseRun<Input>[]\n score: ReferenceReplayScore\n metadata?: Record<string, unknown>\n}\n\nexport interface ReferenceReplayRunOptions<Input = unknown> extends ReferenceReplayScoreOptions {\n adapter: ReferenceReplayAdapterLike<Input>\n runId?: string\n variantId?: string\n metadata?: Record<string, unknown>\n store?: ReferenceReplayRunStore<Input>\n abortSignal?: AbortSignal\n continueOnError?: boolean\n now?: () => number\n}\n\nexport interface ReferenceReplayRunStore<Input = unknown> {\n save(run: ReferenceReplayRun<Input>): Promise<void>\n list(): Promise<ReferenceReplayRun<Input>[]>\n}\n\nconst DEFAULT_MATCH_THRESHOLD = 0.55\nconst ALL_SPLITS: ReferenceReplaySplit[] = ['train', 'dev', 'test', 'holdout']\n\nexport async function runReferenceReplay<Input = unknown>(\n cases: ReferenceReplayCase<Input>[],\n options: ReferenceReplayRunOptions<Input>,\n): Promise<ReferenceReplayRun<Input>> {\n const now = options.now ?? Date.now\n const startedAt = now()\n const runId = options.runId ?? `${options.variantId ?? 'reference-replay'}-${startedAt}`\n const allowedSplits = new Set(options.splits ?? ALL_SPLITS)\n const caseRuns: ReferenceReplayCaseRun<Input>[] = []\n\n for (const [caseIndex, replayCase] of cases.entries()) {\n const split = replayCase.split ?? 'train'\n if (split === 'holdout' && !options.includeHoldout) continue\n if (!allowedSplits.has(split)) continue\n\n const caseStart = now()\n const executionScenario: ReferenceReplayExecutionScenario<Input> = {\n id: replayCase.id,\n split,\n input: replayCase.input,\n ...(replayCase.metadata !== undefined ? { metadata: replayCase.metadata } : {}),\n }\n\n let candidates: ReferenceReplayCandidate[] = []\n let error: string | undefined\n try {\n throwIfAborted(options.abortSignal)\n candidates = await runAdapter(options.adapter, executionScenario, {\n runId,\n caseIndex,\n abortSignal: options.abortSignal,\n })\n throwIfAborted(options.abortSignal)\n } catch (cause) {\n if (options.abortSignal?.aborted) throw cause\n if (!options.continueOnError) throw cause\n error = cause instanceof Error ? cause.message : String(cause)\n }\n\n const scenario: ReferenceReplayScenario = {\n id: replayCase.id,\n split,\n references: replayCase.references,\n candidates,\n ...(replayCase.metadata !== undefined ? { metadata: replayCase.metadata } : {}),\n }\n const scoreOptions: ReferenceReplayScoreOptions = {\n matcher: options.matcher,\n matchThreshold: options.matchThreshold,\n matchStrategy: options.matchStrategy,\n includeHoldout: true,\n }\n const scenarioScore = scoreReferenceReplay([scenario], scoreOptions).scenarios[0]!\n caseRuns.push({\n caseId: replayCase.id,\n split,\n input: replayCase.input,\n references: replayCase.references,\n candidates,\n score: scenarioScore,\n durationMs: Math.max(0, now() - caseStart),\n ...(replayCase.metadata !== undefined ? { metadata: replayCase.metadata } : {}),\n ...(error !== undefined ? { error } : {}),\n })\n }\n\n const completedAt = now()\n const scoreOptions: ReferenceReplayScoreOptions = {\n matcher: options.matcher,\n matchThreshold: options.matchThreshold,\n matchStrategy: options.matchStrategy,\n includeHoldout: true,\n }\n const run: ReferenceReplayRun<Input> = {\n id: runId,\n startedAt,\n completedAt,\n durationMs: Math.max(0, completedAt - startedAt),\n cases: caseRuns,\n score: scoreReferenceReplay(\n caseRuns.map((caseRun) => ({\n id: caseRun.caseId,\n split: caseRun.split,\n references: caseRun.references,\n candidates: caseRun.candidates,\n ...(caseRun.metadata !== undefined ? { metadata: caseRun.metadata } : {}),\n })),\n scoreOptions,\n ),\n ...(options.variantId !== undefined ? { variantId: options.variantId } : {}),\n ...(options.metadata !== undefined ? { metadata: options.metadata } : {}),\n }\n\n await options.store?.save(run)\n return run\n}\n\nexport function decideReferenceReplayRunPromotion(\n baseline: ReferenceReplayRun,\n candidate: ReferenceReplayRun,\n policy: ReferenceReplayPromotionPolicy = {},\n): ReferenceReplayPromotionDecision {\n return decideReferenceReplayPromotion(baseline.score, candidate.score, policy)\n}\n\nexport function inMemoryReferenceReplayStore<Input = unknown>(\n initial: ReferenceReplayRun<Input>[] = [],\n): ReferenceReplayRunStore<Input> {\n const runs = [...initial]\n return {\n async save(run) {\n runs.push(run)\n },\n async list() {\n return [...runs]\n },\n }\n}\n\n// Per-path Mutex registry. `appendFileSync` on POSIX is only atomic up to\n// PIPE_BUF (~4KB) — and a `ReferenceReplayRun` line routinely exceeds that.\n// Concurrent in-process writers without a lock produce torn lines that\n// break `list()` on parse. Cross-process safety still requires file\n// locking (fcntl/flock); we don't take that on here because every current\n// agent-eval flow is single-process.\nconst jsonlStoreLocks = new Map<string, Mutex>()\nfunction getJsonlStoreLock(path: string): Mutex {\n let m = jsonlStoreLocks.get(path)\n if (!m) {\n m = new Mutex()\n jsonlStoreLocks.set(path, m)\n }\n return m\n}\n\nexport function jsonlReferenceReplayStore<Input = unknown>(\n path: string,\n): ReferenceReplayRunStore<Input> {\n const lock = getJsonlStoreLock(path)\n return {\n async save(run) {\n await lock.runExclusive(() => {\n mkdirSync(dirname(path), { recursive: true })\n appendFileSync(path, `${JSON.stringify(run)}\\n`)\n })\n },\n async list() {\n return lock.runExclusive(() => {\n if (!existsSync(path)) return []\n return readJsonl(path)\n })\n },\n }\n}\n\nexport function scoreReferenceReplay(\n scenarios: ReferenceReplayScenario[],\n options: ReferenceReplayScoreOptions = {},\n): ReferenceReplayScore {\n const matcher = options.matcher ?? defaultReferenceReplayMatcher\n const threshold = options.matchThreshold ?? DEFAULT_MATCH_THRESHOLD\n const matchStrategy = options.matchStrategy ?? 'reference-order'\n const allowedSplits = new Set(options.splits ?? ALL_SPLITS)\n const scores = scenarios\n .filter((scenario) => {\n const split = scenario.split ?? 'train'\n if (split === 'holdout' && !options.includeHoldout) return false\n return allowedSplits.has(split)\n })\n .map((scenario) => scoreScenario(scenario, matcher, threshold, matchStrategy))\n\n return {\n scenarios: scores,\n aggregate: aggregateScenarioScores(scores),\n bySplit: aggregateBySplit(scores),\n }\n}\n\nexport function compareReferenceReplay(\n baseline: ReferenceReplayScore,\n candidate: ReferenceReplayScore,\n): ReferenceReplaySplitComparison[] {\n const splits = new Set<ReferenceReplaySplit>([\n ...(Object.keys(baseline.bySplit) as ReferenceReplaySplit[]),\n ...(Object.keys(candidate.bySplit) as ReferenceReplaySplit[]),\n ])\n return [...splits].sort(bySplitOrder).map((split) => {\n const before = baseline.bySplit[split] ?? emptyAggregate()\n const after = candidate.bySplit[split] ?? emptyAggregate()\n return {\n split,\n baselineF1: before.f1,\n candidateF1: after.f1,\n f1Delta: after.f1 - before.f1,\n baselineRecall: before.recall,\n candidateRecall: after.recall,\n recallDelta: after.recall - before.recall,\n }\n })\n}\n\nexport function decideReferenceReplayPromotion(\n baseline: ReferenceReplayScore,\n candidate: ReferenceReplayScore,\n policy: ReferenceReplayPromotionPolicy = {},\n): ReferenceReplayPromotionDecision {\n const requiredSplits = policy.requiredSplits ?? ['dev', 'test']\n const minF1Delta = policy.minF1Delta ?? 0\n const maxRegression = policy.maxRegression ?? 0\n const requireHoldout = policy.requireHoldoutNonRegression ?? true\n const comparisons = compareReferenceReplay(baseline, candidate)\n const missingRequiredSplits = requiredSplits.filter(\n (split) => !hasSplit(baseline, split) || !hasSplit(candidate, split),\n )\n const compared = comparisons.filter((item) => requiredSplits.includes(item.split))\n const regressions = comparisons.filter((item) => item.f1Delta < -maxRegression)\n const aggregateDelta = candidate.aggregate.f1 - baseline.aggregate.f1\n\n if (missingRequiredSplits.length > 0) {\n return {\n promote: false,\n reason: `Required split missing from baseline or candidate: ${missingRequiredSplits.join(', ')}`,\n aggregateDelta,\n comparisons,\n regressions,\n }\n }\n\n if (compared.length === 0) {\n return {\n promote: false,\n reason: `No required split scores found: ${requiredSplits.join(', ')}`,\n aggregateDelta,\n comparisons,\n regressions,\n }\n }\n\n if (regressions.length > 0) {\n return {\n promote: false,\n reason: `Regression in ${regressions.map((r) => r.split).join(', ')}`,\n aggregateDelta,\n comparisons,\n regressions,\n }\n }\n\n if (requireHoldout && (!hasSplit(baseline, 'holdout') || !hasSplit(candidate, 'holdout'))) {\n return {\n promote: false,\n reason: 'Holdout split is required for promotion',\n aggregateDelta,\n comparisons,\n regressions,\n }\n }\n\n const requiredMeanDelta = mean(compared.map((item) => item.f1Delta))\n if (requiredMeanDelta < minF1Delta) {\n return {\n promote: false,\n reason: `Required split F1 delta ${formatPct(requiredMeanDelta)} below ${formatPct(minF1Delta)}`,\n aggregateDelta,\n comparisons,\n regressions,\n }\n }\n\n return {\n promote: true,\n reason: `Required splits improved by ${formatPct(requiredMeanDelta)} with no regressions`,\n aggregateDelta,\n comparisons,\n regressions,\n }\n}\n\nexport function defaultReferenceReplayMatcher(\n reference: ReferenceReplayItem,\n candidate: ReferenceReplayCandidate,\n): ReferenceMatchResult {\n const referenceText = `${reference.title} ${reference.description ?? ''}`\n const candidateText = `${candidate.title} ${candidate.description ?? ''}`\n const textScore = tokenJaccard(referenceText, candidateText)\n const severityScore =\n reference.severity && candidate.severity\n ? normalize(reference.severity) === normalize(candidate.severity)\n ? 0.1\n : -0.05\n : 0\n const tagScore = tagOverlap(reference.tags, candidate.tags) * 0.15\n const score = clamp01(textScore * 0.85 + tagScore + severityScore)\n return {\n score,\n reason: `token=${textScore.toFixed(2)} tags=${tagScore.toFixed(2)} severity=${severityScore.toFixed(2)}`,\n }\n}\n\nfunction scoreScenario(\n scenario: ReferenceReplayScenario,\n matcher: ReferenceReplayMatcher,\n threshold: number,\n matchStrategy: ReferenceReplayMatchStrategy,\n): ReferenceReplayScenarioScore {\n return matchStrategy === 'global-greedy'\n ? scoreScenarioGlobalGreedy(scenario, matcher, threshold)\n : scoreScenarioReferenceOrder(scenario, matcher, threshold)\n}\n\nfunction scoreScenarioReferenceOrder(\n scenario: ReferenceReplayScenario,\n matcher: ReferenceReplayMatcher,\n threshold: number,\n): ReferenceReplayScenarioScore {\n const candidatesLeft = scenario.candidates.map((candidate, index) => ({ candidate, index }))\n const matches: ReferenceReplayMatch[] = []\n\n for (const reference of scenario.references) {\n let best: {\n candidate: ReferenceReplayCandidate\n index: number\n score: number\n reason: string\n } | null = null\n for (const item of candidatesLeft) {\n const result = scorePair(scenario, matcher, reference, item.candidate)\n if (!best || result.score > best.score) {\n best = { ...item, ...result }\n }\n }\n\n const weight = reference.weight ?? 1\n if (best && best.score >= threshold) {\n const matchIndex = candidatesLeft.findIndex((item) => item.index === best.index)\n if (matchIndex >= 0) candidatesLeft.splice(matchIndex, 1)\n matches.push({\n scenarioId: scenario.id,\n referenceId: reference.id,\n candidateId: best.candidate.id,\n score: best.score,\n matched: true,\n weight,\n reason: best.reason,\n })\n } else {\n matches.push({\n scenarioId: scenario.id,\n referenceId: reference.id,\n candidateId: best?.candidate.id ?? null,\n score: best?.score ?? 0,\n matched: false,\n weight,\n reason: best?.reason ?? 'no candidates',\n })\n }\n }\n\n return buildScenarioScore(scenario, matches, candidatesLeft.length)\n}\n\ninterface ReferenceCandidatePair {\n referenceIndex: number\n candidateIndex: number\n reference: ReferenceReplayItem\n candidate: ReferenceReplayCandidate\n score: number\n reason: string\n}\n\nfunction scoreScenarioGlobalGreedy(\n scenario: ReferenceReplayScenario,\n matcher: ReferenceReplayMatcher,\n threshold: number,\n): ReferenceReplayScenarioScore {\n const pairs: ReferenceCandidatePair[] = []\n for (const [referenceIndex, reference] of scenario.references.entries()) {\n for (const [candidateIndex, candidate] of scenario.candidates.entries()) {\n pairs.push({\n referenceIndex,\n candidateIndex,\n reference,\n candidate,\n ...scorePair(scenario, matcher, reference, candidate),\n })\n }\n }\n\n pairs.sort(\n (a, b) =>\n b.score - a.score ||\n a.referenceIndex - b.referenceIndex ||\n a.candidateIndex - b.candidateIndex,\n )\n\n const selectedByReference = new Map<number, ReferenceCandidatePair>()\n const selectedCandidates = new Set<number>()\n for (const pair of pairs) {\n if (pair.score < threshold) break\n if (selectedByReference.has(pair.referenceIndex) || selectedCandidates.has(pair.candidateIndex))\n continue\n selectedByReference.set(pair.referenceIndex, pair)\n selectedCandidates.add(pair.candidateIndex)\n }\n\n const matches = scenario.references.map((reference, referenceIndex) => {\n const weight = reference.weight ?? 1\n const selected = selectedByReference.get(referenceIndex)\n if (selected) {\n return {\n scenarioId: scenario.id,\n referenceId: reference.id,\n candidateId: selected.candidate.id,\n score: selected.score,\n matched: true,\n weight,\n reason: selected.reason,\n }\n }\n\n const bestRejected = pairs.find((pair) => pair.referenceIndex === referenceIndex)\n return {\n scenarioId: scenario.id,\n referenceId: reference.id,\n candidateId: bestRejected?.candidate.id ?? null,\n score: bestRejected?.score ?? 0,\n matched: false,\n weight,\n reason: bestRejected?.reason ?? 'no candidates',\n }\n })\n\n return buildScenarioScore(scenario, matches, scenario.candidates.length - selectedCandidates.size)\n}\n\nfunction scorePair(\n scenario: ReferenceReplayScenario,\n matcher: ReferenceReplayMatcher,\n reference: ReferenceReplayItem,\n candidate: ReferenceReplayCandidate,\n): { score: number; reason: string } {\n const result = matcher(reference, candidate, scenario)\n if (!Number.isFinite(result.score)) {\n throw new Error(\n `reference replay matcher returned non-finite score for ${scenario.id}:${reference.id}:${candidate.id}`,\n )\n }\n return { score: clamp01(result.score), reason: result.reason ?? '' }\n}\n\nfunction buildScenarioScore(\n scenario: ReferenceReplayScenario,\n matches: ReferenceReplayMatch[],\n falsePositives: number,\n): ReferenceReplayScenarioScore {\n const matched = matches.filter((match) => match.matched).length\n const total = scenario.references.length\n const matchedWeight = matches\n .filter((match) => match.matched)\n .reduce((sum, match) => sum + match.weight, 0)\n const totalWeight = matches.reduce((sum, match) => sum + match.weight, 0)\n const precision = ratio(matched, matched + falsePositives)\n const recall = ratio(matched, total)\n return {\n scenarioId: scenario.id,\n split: scenario.split ?? 'train',\n matched,\n total,\n falsePositives,\n matchedWeight,\n totalWeight,\n precision,\n recall,\n f1: f1(precision, recall),\n matches,\n }\n}\n\nfunction aggregateBySplit(\n scores: ReferenceReplayScenarioScore[],\n): Partial<Record<ReferenceReplaySplit, ReferenceReplayAggregate>> {\n const out: Partial<Record<ReferenceReplaySplit, ReferenceReplayAggregate>> = {}\n for (const split of ALL_SPLITS) {\n const scoped = scores.filter((score) => score.split === split)\n if (scoped.length > 0) out[split] = aggregateScenarioScores(scoped)\n }\n return out\n}\n\nfunction aggregateScenarioScores(scores: ReferenceReplayScenarioScore[]): ReferenceReplayAggregate {\n const matched = sum(scores.map((score) => score.matched))\n const total = sum(scores.map((score) => score.total))\n const falsePositives = sum(scores.map((score) => score.falsePositives))\n const matchedWeight = sum(scores.map((score) => score.matchedWeight))\n const totalWeight = sum(scores.map((score) => score.totalWeight))\n const precision = ratio(matched, matched + falsePositives)\n const recall = ratio(matched, total)\n return {\n matched,\n total,\n falsePositives,\n matchedWeight,\n totalWeight,\n precision,\n recall,\n f1: f1(precision, recall),\n weightedRecall: ratio(matchedWeight, totalWeight),\n }\n}\n\nfunction emptyAggregate(): ReferenceReplayAggregate {\n return {\n matched: 0,\n total: 0,\n falsePositives: 0,\n matchedWeight: 0,\n totalWeight: 0,\n precision: 0,\n recall: 0,\n f1: 0,\n weightedRecall: 0,\n }\n}\n\nfunction hasSplit(score: ReferenceReplayScore, split: ReferenceReplaySplit): boolean {\n return score.bySplit[split] !== undefined\n}\n\nfunction f1(precision: number, recall: number): number {\n return precision + recall === 0 ? 0 : (2 * precision * recall) / (precision + recall)\n}\n\nfunction ratio(numerator: number, denominator: number): number {\n return denominator > 0 ? numerator / denominator : 0\n}\n\nfunction tokenJaccard(a: string, b: string): number {\n const left = new Set(tokens(a))\n const right = new Set(tokens(b))\n if (left.size === 0 || right.size === 0) return 0\n let intersection = 0\n for (const token of left) {\n if (right.has(token)) intersection++\n }\n return intersection / (left.size + right.size - intersection)\n}\n\nfunction tagOverlap(a: string[] | undefined, b: string[] | undefined): number {\n if (!a?.length || !b?.length) return 0\n const left = new Set(a.map(normalize))\n const right = new Set(b.map(normalize))\n let intersection = 0\n for (const tag of left) {\n if (right.has(tag)) intersection++\n }\n return intersection / Math.max(left.size, right.size)\n}\n\nfunction tokens(text: string): string[] {\n return normalize(text)\n .split(/\\s+/)\n .filter((token) => token.length >= 3 && !STOP_WORDS.has(token))\n}\n\nfunction normalize(text: string): string {\n return text\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, ' ')\n .trim()\n}\n\nfunction clamp01(value: number): number {\n if (!Number.isFinite(value)) return 0\n return Math.max(0, Math.min(1, value))\n}\n\nfunction sum(values: number[]): number {\n return values.reduce((acc, value) => acc + value, 0)\n}\n\nfunction mean(values: number[]): number {\n return values.length ? sum(values) / values.length : 0\n}\n\nfunction formatPct(value: number): string {\n return `${(value * 100).toFixed(1)}%`\n}\n\nfunction bySplitOrder(a: ReferenceReplaySplit, b: ReferenceReplaySplit): number {\n return ALL_SPLITS.indexOf(a) - ALL_SPLITS.indexOf(b)\n}\n\nfunction runAdapter<Input>(\n adapter: ReferenceReplayAdapterLike<Input>,\n scenario: ReferenceReplayExecutionScenario<Input>,\n context: ReferenceReplayRunContext,\n): Promise<ReferenceReplayCandidate[]> {\n return typeof adapter === 'function' ? adapter(scenario, context) : adapter.run(scenario, context)\n}\n\nfunction throwIfAborted(signal: AbortSignal | undefined): void {\n if (!signal?.aborted) return\n if (signal.reason instanceof Error) throw signal.reason\n throw new Error(signal.reason ? String(signal.reason) : 'reference replay aborted')\n}\n\nfunction readJsonl<Input>(path: string): ReferenceReplayRun<Input>[] {\n const raw = readFileSync(path, 'utf8')\n const out: ReferenceReplayRun<Input>[] = []\n for (const line of raw.split('\\n')) {\n const trimmed = line.trim()\n if (!trimmed) continue\n out.push(JSON.parse(trimmed) as ReferenceReplayRun<Input>)\n }\n return out\n}\n\nconst STOP_WORDS = new Set([\n 'the',\n 'and',\n 'for',\n 'with',\n 'that',\n 'this',\n 'from',\n 'into',\n 'onto',\n 'are',\n 'can',\n 'will',\n 'should',\n 'could',\n 'would',\n 'when',\n 'where',\n 'which',\n])\n","/**\n * Reviewer primitives — prompt builder + default ReviewFn factory.\n *\n * `buildReviewerPrompt` is the pure, LLM-agnostic piece: takes\n * `ReviewerPromptInput` (user request, trace summary, verification\n * summary, memory, optional extra context) and emits the system +\n * user message pair. No LLM dependency — callers that want to drive\n * their own transport get full control.\n *\n * `createDefaultReviewer` is the convenience factory: wires the prompt\n * builder to `callLlmJson` with a default schema + soft-fail policy.\n * Returns a function that maps `ReviewerPromptInput` to `ReviewerOutput`.\n *\n * Same pattern as `runSemanticConceptJudge` / `createSemanticConceptJudge`:\n * low-level pure builder + high-level factory built on top.\n */\n\nimport { callLlmJson, type LlmClientOptions } from './llm-client'\n\n// ─── Types ──────────────────────────────────────────────────────────────\n\nexport interface ReviewerMemoryEntry {\n shot: number\n ts?: string\n observations?: string\n diagnosis?: string\n nextShotInstruction?: string\n shouldContinue?: boolean\n confidence?: number\n}\n\nexport interface ReviewerVerificationSummary {\n blendedScore: number\n allPass: boolean\n failCount: number\n failingLayers?: string[]\n}\n\nexport interface ReviewerPromptInput {\n shot: number\n userRequest: string\n /**\n * Compact trace summary — tool-call counts, errors, recent activity\n * lines. Built by the caller from whatever trace format they have;\n * agent-eval does not prescribe.\n */\n traceSummary: string\n verification: ReviewerVerificationSummary\n memory: ReviewerMemoryEntry[]\n /**\n * Optional extra context injected into the prompt between the trace\n * and the verification blocks. Use for workdir file-tree snapshots,\n * scaffold descriptions, or any environmental fact the reviewer\n * needs to direct the next shot accurately.\n */\n extraContext?: string\n /**\n * Optional extra section appended at the end of the prompt (e.g.\n * leaf metadata, scenario id). Free-form — no agent-eval-shaped\n * schema.\n */\n trailingContext?: string\n}\n\nexport interface ReviewerOutput {\n shot: number\n observations: string\n diagnosis: string\n nextShotInstruction: string\n shouldContinue: boolean\n /** 0..1 self-assessed confidence in the directive. */\n confidence: number\n /** LLM cost in USD if the transport reports it, else null. */\n costUsd: number | null\n durationMs: number\n /** False when the LLM errored or returned malformed JSON; caller soft-fails to defaults. */\n available: boolean\n error?: string\n}\n\nexport interface ReviewerSoftFailDefaults {\n observations?: string\n diagnosis?: string\n nextShotInstruction?: string\n shouldContinue?: boolean\n confidence?: number\n}\n\nexport interface CreateDefaultReviewerOptions {\n /** Model id to call. */\n model: string\n /** Per-call timeout. Default 180s. */\n timeoutMs?: number\n /** LlmClient transport config (baseUrl, apiKey, authHeader, etc.). */\n llm?: LlmClientOptions\n /**\n * Override the prompt builder. Default: `buildReviewerPrompt`.\n * Consumers with different reviewer voices pass their own.\n */\n promptBuilder?: (input: ReviewerPromptInput) => { system: string; user: string }\n /**\n * Soft-fail values when the LLM throws or returns unparseable JSON.\n * Matches VerticalBench's shipped policy: continue with generic\n * instruction at confidence 0.3 so the worker keeps trying.\n */\n softFailDefaults?: ReviewerSoftFailDefaults\n}\n\n// ─── JSON schema ───────────────────────────────────────────────────────\n\nconst REVIEWER_SCHEMA = {\n type: 'object',\n additionalProperties: false,\n required: ['observations', 'diagnosis', 'nextShotInstruction', 'shouldContinue', 'confidence'],\n properties: {\n observations: { type: 'string', minLength: 20, maxLength: 2000 },\n diagnosis: { type: 'string', minLength: 20, maxLength: 1500 },\n nextShotInstruction: { type: 'string', minLength: 40, maxLength: 3000 },\n shouldContinue: { type: 'boolean' },\n confidence: { type: 'number', minimum: 0, maximum: 1 },\n },\n} as const\n\n// ─── Prompt builder ────────────────────────────────────────────────────\n\nfunction summarizeMemory(memory: ReviewerMemoryEntry[]): string {\n if (memory.length === 0) return '(no prior shots)'\n return memory\n .map((m) => {\n const header = `shot ${m.shot} — confidence=${(m.confidence ?? 0).toFixed(2)} shouldContinue=${m.shouldContinue ?? '?'}`\n const obs = m.observations ? ` observations: ${m.observations.slice(0, 400)}` : ''\n const diag = m.diagnosis ? ` diagnosis: ${m.diagnosis.slice(0, 400)}` : ''\n const instr = m.nextShotInstruction\n ? ` instruction given: ${m.nextShotInstruction.slice(0, 400)}`\n : ''\n return [header, obs, diag, instr].filter(Boolean).join('\\n')\n })\n .join('\\n\\n')\n}\n\n/**\n * Build the reviewer's system + user messages. Pure function, no LLM\n * call. Callers that want their own transport or a different structured\n * output can use this and skip `createDefaultReviewer` entirely.\n */\nexport function buildReviewerPrompt(input: ReviewerPromptInput): { system: string; user: string } {\n const system =\n 'You are a senior-engineer-grade reviewer directing an agent through a multi-shot build. ' +\n \"Your job is NOT to grade; your job IS to direct the worker's next shot using the trace, \" +\n 'verification result, prior memory, and user request. Return STRICT JSON. No prose outside the JSON.'\n\n const failingLayersBlock =\n input.verification.failingLayers && input.verification.failingLayers.length > 0\n ? `failing layers: ${input.verification.failingLayers.join(', ')}`\n : 'no layers failing'\n\n const user = `=== SHOT NUMBER ===\nshot ${input.shot} of the review loop\n\n=== USER REQUEST ===\n${input.userRequest}\n\n=== WORKER TRACE (shot ${input.shot}) ===\n${input.traceSummary}\n${input.extraContext ? `\\n=== EXTRA CONTEXT ===\\n${input.extraContext}\\n` : ''}\n=== VERIFICATION (shot ${input.shot}) ===\nblendedScore: ${input.verification.blendedScore.toFixed(2)}\nallPass: ${input.verification.allPass}\nfailCount: ${input.verification.failCount}\n${failingLayersBlock}\n\n=== REVIEWER MEMORY ===\n${summarizeMemory(input.memory)}\n${input.trailingContext ? `\\n=== TRAILING CONTEXT ===\\n${input.trailingContext}\\n` : ''}\n=== YOUR TASK ===\nReturn STRICT JSON:\n\n1. observations (20-2000 chars): first-person worker behavior from the trace (tool call counts, errors, loops).\n2. diagnosis (20-1500 chars): root cause of current failures, not a restatement of verification.\n3. nextShotInstruction (40-3000 chars): concrete \"FIX THESE:\" directive for the worker's next shot. Reference memory when instructions repeat.\n4. shouldContinue (boolean): FALSE if verification.allPass=true, if worker is thrashing, if confidence < 0.3, or if the request looks unachievable. TRUE otherwise.\n5. confidence (0-1): self-assessment.\n\nRULES:\n- If verification.allPass is true, shouldContinue MUST be false.\n- If memory shows the same failing layer for 2 shots, reduce confidence — strategy isn't working.\n- If the trace shows zero tool calls, the worker didn't run — surface that.\n- Do NOT re-grade. Direct.`\n\n return { system, user }\n}\n\n// ─── Default reviewer factory ───────────────────────────────────────────\n\nconst DEFAULT_SOFT_FAIL: Required<ReviewerSoftFailDefaults> = {\n observations: 'reviewer soft-failed — no observations captured',\n diagnosis: 'reviewer soft-failed — inspect verification findings and retry',\n nextShotInstruction:\n 'Inspect the verification findings above and address the highest-severity failing layer first. ' +\n 'If install failed, start there; otherwise work from the first failing gate and address compilation/build errors before layout/semantic issues.',\n shouldContinue: true,\n confidence: 0.3,\n}\n\n/**\n * Factory: returns a function that invokes the default reviewer against\n * an LLM and parses the structured output. Soft-fails to the provided\n * defaults on LLM throw or JSON-parse error so the shot loop keeps\n * moving rather than crashing.\n */\nexport function createDefaultReviewer(\n options: CreateDefaultReviewerOptions,\n): (input: ReviewerPromptInput) => Promise<ReviewerOutput> {\n const softFail: Required<ReviewerSoftFailDefaults> = {\n ...DEFAULT_SOFT_FAIL,\n ...(options.softFailDefaults ?? {}),\n }\n const promptBuilder = options.promptBuilder ?? buildReviewerPrompt\n const timeoutMs = options.timeoutMs ?? 180_000\n\n return async (input) => {\n const start = Date.now()\n const { system, user } = promptBuilder(input)\n try {\n const { value, result } = await callLlmJson<{\n observations: string\n diagnosis: string\n nextShotInstruction: string\n shouldContinue: boolean\n confidence: number\n }>(\n {\n model: options.model,\n messages: [\n { role: 'system', content: system },\n { role: 'user', content: user },\n ],\n jsonSchema: { name: 'reviewer_output', schema: REVIEWER_SCHEMA },\n temperature: 0,\n timeoutMs,\n },\n options.llm ?? {},\n )\n\n return {\n shot: input.shot,\n observations: String(value.observations ?? softFail.observations),\n diagnosis: String(value.diagnosis ?? softFail.diagnosis),\n nextShotInstruction: String(value.nextShotInstruction ?? softFail.nextShotInstruction),\n shouldContinue: Boolean(value.shouldContinue),\n confidence: Math.max(0, Math.min(1, Number(value.confidence ?? softFail.confidence))),\n costUsd: result.costUsd ?? null,\n durationMs: Date.now() - start,\n available: true,\n }\n } catch (err) {\n return {\n shot: input.shot,\n observations: softFail.observations,\n diagnosis: softFail.diagnosis,\n nextShotInstruction: softFail.nextShotInstruction,\n shouldContinue: softFail.shouldContinue,\n confidence: softFail.confidence,\n costUsd: null,\n durationMs: Date.now() - start,\n available: false,\n error: err instanceof Error ? err.message : String(err),\n }\n }\n }\n}\n","/**\n * Walk a personas directory and return every file matching the convention\n * `NN-slug.{yaml,yml,json,md}`. Sorted by filename so the numeric prefix\n * gives stable persona ordering for reproducibility. Consumers filter\n * through `include` / `exclude`.\n */\n\nimport { promises as fs } from 'node:fs'\nimport { basename, extname, join } from 'node:path'\n\nexport interface DiscoverPersonasOptions {\n /**\n * Regex applied to filenames. Files that don't match are skipped.\n * Default: `^[0-9]{2}-.+\\.(yaml|yml|json|md)$`.\n */\n pattern?: RegExp\n /**\n * Filenames (or basenames) to skip. Use this to exclude WIP / archived\n * personas without removing the file.\n */\n exclude?: readonly string[]\n /**\n * If set, return only personas whose basename contains one of these\n * substrings (post-pattern filter).\n */\n include?: readonly string[]\n /** Recurse into subdirectories. Default false. */\n recursive?: boolean\n}\n\nexport interface DiscoveredPersona {\n /** Absolute file path. */\n path: string\n /** Filename without directory. */\n filename: string\n /** Filename without extension — the conventional persona id. */\n id: string\n}\n\nconst DEFAULT_PATTERN = /^\\d{2}-.+\\.(yaml|yml|json|md)$/\n\nexport async function discoverPersonas(\n dir: string,\n opts: DiscoverPersonasOptions = {},\n): Promise<DiscoveredPersona[]> {\n const pattern = opts.pattern ?? DEFAULT_PATTERN\n const exclude = new Set(opts.exclude ?? [])\n const include = opts.include\n\n async function walk(d: string): Promise<DiscoveredPersona[]> {\n let entries: Array<{ name: string; isDir: boolean }>\n try {\n const raw = await fs.readdir(d, { withFileTypes: true })\n entries = raw.map((e) => ({ name: e.name, isDir: e.isDirectory() }))\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code\n if (code === 'ENOENT') return []\n throw err\n }\n const out: DiscoveredPersona[] = []\n for (const entry of entries) {\n const full = join(d, entry.name)\n if (entry.isDir) {\n if (opts.recursive) out.push(...(await walk(full)))\n continue\n }\n if (!pattern.test(entry.name)) continue\n if (exclude.has(entry.name) || exclude.has(basename(entry.name, extname(entry.name))))\n continue\n if (include && include.length > 0) {\n const id = basename(entry.name, extname(entry.name))\n const matched = include.some((needle) => entry.name.includes(needle) || id.includes(needle))\n if (!matched) continue\n }\n out.push({\n path: full,\n filename: entry.name,\n id: basename(entry.name, extname(entry.name)),\n })\n }\n return out\n }\n\n const results = await walk(dir)\n results.sort((a, b) => a.filename.localeCompare(b.filename))\n return results\n}\n","/**\n * GoldenMatcher — fuzzy matcher for \"did the agent produce the expected things?\".\n *\n * Universal primitive across agent-eval consumers. Use it for:\n * - Test suites: did the run hit the expected assertions?\n * - Tool agents: did the agent emit the expected tool call sequence?\n * - Judges: did the verdict include the expected concepts?\n * - Design audits: did the auditor surface the planted defects?\n *\n * Match rule (per golden):\n * - Any phrase in `golden.any` (case-insensitive substring) appears in the\n * candidate's text fields, OR\n * - Any pattern in `golden.anyRegex` (case-insensitive) matches.\n *\n * Recall is severity-weighted by default: critical=3, major=2, minor=1.\n * Missing one critical hurts more than missing three minors.\n */\n\nexport type GoldenSeverity = 'critical' | 'major' | 'minor'\n\nexport interface GoldenSpec {\n /** Stable identifier — survives across runs so consumers can grep by id. */\n id: string\n /** Severity drives recall weighting. */\n severity: GoldenSeverity\n /**\n * Substring phrases (case-insensitive). A hit on ANY phrase counts as a\n * match. Keep these SHORT (3-6 words) and SPECIFIC.\n */\n any: string[]\n /** Optional regex patterns. ORed with `any`. */\n anyRegex?: string[]\n /** Free-form note — surfaces in reports for humans. */\n hint?: string\n /** Optional category for grouping/filtering. */\n category?: string\n}\n\nexport interface MatchResult {\n /** Same length as goldens; `true` when matched. */\n matches: boolean[]\n /** Convenience: count of hits. */\n hits: number\n /** Convenience: total goldens. */\n total: number\n}\n\n/**\n * Match each golden against `candidates`, where each candidate exposes one or\n * more text fields the matcher should search. Defaults to searching all\n * string-typed fields concatenated.\n */\nexport function matchGoldens<T>(\n goldens: GoldenSpec[],\n candidates: T[],\n options: {\n /**\n * Extract the searchable text for a candidate. Default: concatenate every\n * top-level string field with a space.\n */\n text?: (candidate: T) => string\n } = {},\n): MatchResult {\n const extract = options.text ?? defaultExtract\n const haystacks = candidates.map((c) => extract(c).toLowerCase())\n const matches = goldens.map((golden) => goldenMatched(golden, haystacks))\n return {\n matches,\n hits: matches.filter(Boolean).length,\n total: goldens.length,\n }\n}\n\nfunction defaultExtract(candidate: unknown): string {\n if (typeof candidate === 'string') return candidate\n if (candidate && typeof candidate === 'object') {\n const parts: string[] = []\n for (const v of Object.values(candidate as Record<string, unknown>)) {\n if (typeof v === 'string') parts.push(v)\n }\n return parts.join(' ')\n }\n return String(candidate ?? '')\n}\n\nfunction goldenMatched(golden: GoldenSpec, haystacks: string[]): boolean {\n for (const phrase of golden.any) {\n const needle = phrase.toLowerCase().trim()\n if (!needle) continue\n if (haystacks.some((h) => h.includes(needle))) return true\n }\n for (const pattern of golden.anyRegex ?? []) {\n let re: RegExp\n try {\n re = new RegExp(pattern, 'i')\n } catch {\n continue\n }\n if (haystacks.some((h) => re.test(h))) return true\n }\n return false\n}\n\n/** Severity weights — exposed so consumers can override (rare). */\nexport const DEFAULT_SEVERITY_WEIGHTS: Record<GoldenSeverity, number> = {\n critical: 3,\n major: 2,\n minor: 1,\n}\n\n/** Severity-weighted recall over a MatchResult + the goldens that produced it. */\nexport function weightedRecall(\n goldens: GoldenSpec[],\n result: MatchResult,\n weights: Record<GoldenSeverity, number> = DEFAULT_SEVERITY_WEIGHTS,\n): number {\n if (goldens.length === 0) return 1\n const total = goldens.reduce((s, g) => s + (weights[g.severity] ?? 1), 0)\n if (total === 0) return 1\n const hit = goldens.reduce(\n (s, g, i) => s + (result.matches[i] ? (weights[g.severity] ?? 1) : 0),\n 0,\n )\n return hit / total\n}\n\n/**\n * Precision proxy: fraction of emitted candidates that match SOME golden.\n *\n * No human-labelled negatives means unmatched candidates are SOFT false\n * positives — punishes verbose agents that pad with filler. Doesn't punish\n * unknown-but-real findings; the way to tighten this is to grow the golden\n * set, not to invent a stricter score.\n */\nexport function precision<T>(\n goldens: GoldenSpec[],\n candidates: T[],\n options: { text?: (candidate: T) => string } = {},\n): number {\n if (candidates.length === 0) return 1\n const extract = options.text ?? defaultExtract\n let matched = 0\n for (const cand of candidates) {\n const haystack = extract(cand).toLowerCase()\n const matchedAny = goldens.some(\n (g) =>\n g.any.some((phrase) => phrase.length > 0 && haystack.includes(phrase.toLowerCase())) ||\n (g.anyRegex ?? []).some((pat) => {\n try {\n return new RegExp(pat, 'i').test(haystack)\n } catch {\n return false\n }\n }),\n )\n if (matchedAny) matched++\n }\n return matched / candidates.length\n}\n","/**\n * HeldOutGate — first-class held-out paired-delta promotion gate.\n *\n * Encodes the \"honesty override\" pattern that lived inline in\n * `~/webb/redteam/scripts/agent-eval-autoresearch.ts:138–171`.\n * The optimizer's best-guess is one thing; what we should actually\n * ship is another. The gate is the line between them.\n *\n * A candidate is promoted iff ALL three pass:\n *\n * 1. **Productive runs**: the candidate has at least\n * `minProductiveRuns` paired observations on items where BOTH\n * candidate and baseline produced a real (non-silent) score.\n * 2. **Paired delta**: the lower bound of the bootstrap CI on the\n * median per-item delta (candidate − baseline) on the HOLDOUT\n * split is strictly greater than `pairedDeltaThreshold`.\n * 3. **Overfit gap**: the candidate's gap between search-split\n * score and holdout-split score is no worse (more positive)\n * than the baseline's gap by more than `overfitGapThreshold`.\n * \"Better on search, worse on holdout\" is the canonical\n * overfit pattern; this catches it.\n *\n * The decision carries a machine-readable `rejectionCode` plus an\n * `evidence` block with every number the gate looked at, so the\n * downstream researcher / paper / dashboard can re-derive the\n * verdict without re-running.\n *\n * See also:\n * - `src/statistics.ts` for `pairedBootstrap` + `wilcoxonSignedRank`\n * - `src/run-record.ts` for the input row schema\n * - `src/reference-replay.ts` for the older, reference-replay-\n * specific promotion path (still useful for replay-style evals).\n */\n\nimport type { RunRecord } from './run-record'\nimport { pairedBootstrap, wilcoxonSignedRank } from './statistics'\n\nexport type HeldOutGateRejectionCode =\n | 'few_runs'\n | 'negative_delta'\n | 'overfit_gap'\n | 'cost_ceiling'\n\nexport interface HeldOutGateConfig {\n /** Minimum number of paired (candidate, baseline) holdout observations\n * required before the gate will even consider promoting. Default 3. */\n minProductiveRuns?: number\n /** The bootstrap-CI lower bound on the median paired holdout delta\n * must exceed this to promote. Default 0. */\n pairedDeltaThreshold?: number\n /** Maximum allowed worsening of (search − holdout) gap relative to\n * baseline. Default 0.15 (i.e. candidate may overfit by up to 15\n * absolute score points more than baseline before rejection). */\n overfitGapThreshold?: number\n /** Stable label of the baseline candidate. Required — paper-grade\n * evaluation never compares two unlabelled candidates. */\n baselineKey: string\n /** Confidence level for the bootstrap CI. Default 0.95. */\n confidence?: number\n /** Bootstrap resamples. Default 2000. */\n bootstrapResamples?: number\n /** Optional deterministic seed for the bootstrap. Default undefined\n * (Math.random). */\n seed?: number\n /**\n * Hard ceiling on the candidate's median per-task USD cost. When the\n * candidate clears the quality gates (paired-delta + overfit-gap) but\n * its median cost exceeds this number, the gate rejects with\n * `cost_ceiling`. Default `undefined` = no cost ceiling, behaving\n * exactly like the pre-cost gate.\n *\n * This exists because \"we ship the better prompt\" is only an honest\n * pitch when the better prompt also fits a customer-stated budget.\n * Cost is read from `RunRecord.costUsd` (already mandatory on every\n * run) so no new schema is required.\n */\n costPerTaskCeiling?: number\n}\n\nexport interface GateEvidence {\n /** Number of paired (candidate, baseline) holdout observations used. */\n productiveRuns: number\n /** Median of (candidate − baseline) paired holdout deltas. */\n medianPairedDelta: number\n /** Bootstrap CI on the median paired holdout delta. */\n pairedCI: { low: number; high: number }\n /** Wilcoxon signed-rank p-value on the paired holdout deltas. */\n pairedPValue: number\n /** Mean candidate score on the search split (NaN if none). */\n searchScore: number\n /** Mean candidate score on the holdout split (NaN if none). */\n holdoutScore: number\n /** Candidate (search − holdout) gap. */\n overfitGap: number\n /** Baseline (search − holdout) gap. */\n baselineOverfitGap: number\n /** Median per-task USD cost across the candidate's runs. Recorded\n * even when no `costPerTaskCeiling` is configured so downstream\n * dashboards (intelligence.tangle.tools) can render \\$/task per\n * generation regardless of gating policy. */\n medianCandidateCost: number\n /** Median per-task USD cost across the baseline runs, for\n * symmetric reporting. */\n medianBaselineCost: number\n}\n\nexport interface GateDecision {\n /** Final promote/no-promote verdict. */\n promote: boolean\n /** The candidate that was evaluated. */\n candidateId: string\n /** The baseline it was compared against. */\n baselineId: string\n /** Every number the gate looked at, for audit + paper export. */\n evidence: GateEvidence\n /** Human-readable reason. */\n reason: string\n /** Machine-readable rejection code, or null on promote. */\n rejectionCode: HeldOutGateRejectionCode | null\n}\n\n/**\n * Held-out paired-delta promotion gate. Construct once with config,\n * call `evaluate(candidateRuns, baselineRuns)` per (candidate,\n * baseline) pair. Stateless across calls.\n */\nexport class HeldOutGate {\n private readonly minProductiveRuns: number\n private readonly pairedDeltaThreshold: number\n private readonly overfitGapThreshold: number\n private readonly baselineKey: string\n private readonly confidence: number\n private readonly resamples: number\n private readonly seed?: number\n private readonly costPerTaskCeiling?: number\n\n constructor(config: HeldOutGateConfig) {\n if (!config.baselineKey) {\n throw new Error('HeldOutGate: baselineKey is required')\n }\n this.minProductiveRuns = config.minProductiveRuns ?? 3\n this.pairedDeltaThreshold = config.pairedDeltaThreshold ?? 0\n this.overfitGapThreshold = config.overfitGapThreshold ?? 0.15\n this.baselineKey = config.baselineKey\n this.confidence = config.confidence ?? 0.95\n this.resamples = config.bootstrapResamples ?? 2000\n this.seed = config.seed\n if (\n config.costPerTaskCeiling !== undefined &&\n !(Number.isFinite(config.costPerTaskCeiling) && config.costPerTaskCeiling > 0)\n ) {\n throw new Error('HeldOutGate: costPerTaskCeiling must be a positive finite number')\n }\n this.costPerTaskCeiling = config.costPerTaskCeiling\n }\n\n /** Decide whether `candidate` should replace `baseline`. Pairing\n * is by (experimentId, seed) — identical experiment + seed pairs\n * the candidate run with the matching baseline run. Pairs without\n * a holdout score on both sides are dropped. */\n evaluate(candidate: RunRecord[], baseline: RunRecord[]): GateDecision {\n const candidateId = inferCandidateId(candidate, this.baselineKey)\n const baselineId = this.baselineKey\n\n // Pair holdout runs by (experimentId, seed).\n const baselineHoldoutByKey = indexHoldoutByKey(baseline)\n const beforeHoldout: number[] = []\n const afterHoldout: number[] = []\n for (const run of candidate) {\n if (run.splitTag !== 'holdout') continue\n if (run.outcome.holdoutScore === undefined) continue\n const key = pairKey(run)\n const counterpart = baselineHoldoutByKey.get(key)\n if (counterpart === undefined) continue\n beforeHoldout.push(counterpart)\n afterHoldout.push(run.outcome.holdoutScore)\n }\n\n const productiveRuns = beforeHoldout.length\n\n // Always compute the gap numbers — useful even when we reject on\n // few_runs (you want to see why).\n const candidateSearchMean = mean(scores(candidate, 'searchScore', 'search'))\n const candidateHoldoutMean = mean(scores(candidate, 'holdoutScore', 'holdout'))\n const baselineSearchMean = mean(scores(baseline, 'searchScore', 'search'))\n const baselineHoldoutMean = mean(scores(baseline, 'holdoutScore', 'holdout'))\n\n const overfitGap = safeDiff(candidateSearchMean, candidateHoldoutMean)\n const baselineOverfitGap = safeDiff(baselineSearchMean, baselineHoldoutMean)\n\n // Cost summary — surfaced in evidence regardless of gating policy\n // so downstream dashboards always know what the candidate cost.\n const medianCandidateCost = medianFinite(candidate.map((r) => r.costUsd))\n const medianBaselineCost = medianFinite(baseline.map((r) => r.costUsd))\n\n // Few-runs gate.\n if (productiveRuns < this.minProductiveRuns) {\n return {\n promote: false,\n candidateId,\n baselineId,\n evidence: {\n productiveRuns,\n medianPairedDelta: productiveRuns > 0 ? medianDelta(beforeHoldout, afterHoldout) : 0,\n pairedCI: { low: 0, high: 0 },\n pairedPValue: 1,\n searchScore: candidateSearchMean,\n holdoutScore: candidateHoldoutMean,\n overfitGap,\n baselineOverfitGap,\n medianCandidateCost,\n medianBaselineCost,\n },\n reason: `few_runs: ${productiveRuns} paired holdout observation(s) < min ${this.minProductiveRuns}`,\n rejectionCode: 'few_runs',\n }\n }\n\n // Paired bootstrap on holdout deltas.\n const ci = pairedBootstrap(beforeHoldout, afterHoldout, {\n confidence: this.confidence,\n resamples: this.resamples,\n statistic: 'median',\n seed: this.seed,\n })\n const wilcoxon = wilcoxonSignedRank(beforeHoldout, afterHoldout)\n\n const evidence: GateEvidence = {\n productiveRuns,\n medianPairedDelta: ci.median,\n pairedCI: { low: ci.low, high: ci.high },\n pairedPValue: wilcoxon.p,\n searchScore: candidateSearchMean,\n holdoutScore: candidateHoldoutMean,\n overfitGap,\n baselineOverfitGap,\n medianCandidateCost,\n medianBaselineCost,\n }\n\n // Negative-delta gate (CI lower bound must clear the threshold).\n if (!(ci.low > this.pairedDeltaThreshold)) {\n return {\n promote: false,\n candidateId,\n baselineId,\n evidence,\n reason:\n `negative_delta: paired holdout median Δ=${fmt(ci.median)} ` +\n `CI=[${fmt(ci.low)}, ${fmt(ci.high)}] does not clear threshold ${fmt(this.pairedDeltaThreshold)}`,\n rejectionCode: 'negative_delta',\n }\n }\n\n // Overfit-gap gate. We allow some absolute slack —\n // candidate.gap ≤ baseline.gap + overfitGapThreshold.\n if (\n Number.isFinite(overfitGap) &&\n Number.isFinite(baselineOverfitGap) &&\n overfitGap > baselineOverfitGap + this.overfitGapThreshold\n ) {\n return {\n promote: false,\n candidateId,\n baselineId,\n evidence,\n reason:\n `overfit_gap: candidate gap=${fmt(overfitGap)} exceeds baseline gap=${fmt(baselineOverfitGap)} ` +\n `by more than ${fmt(this.overfitGapThreshold)}`,\n rejectionCode: 'overfit_gap',\n }\n }\n\n // Cost-ceiling gate. Runs after quality gates so a cost-driven\n // rejection always carries a \"you cleared quality but blew budget\"\n // story rather than masking a quality failure. NaN cost is treated\n // as \"unknown\" and does NOT trip the ceiling — the data is just\n // missing, and the operator's stated ceiling is for known cost,\n // not for absent telemetry.\n if (\n this.costPerTaskCeiling !== undefined &&\n Number.isFinite(medianCandidateCost) &&\n medianCandidateCost > this.costPerTaskCeiling\n ) {\n return {\n promote: false,\n candidateId,\n baselineId,\n evidence,\n reason:\n `cost_ceiling: candidate median cost $${fmt(medianCandidateCost)} ` +\n `exceeds ceiling $${fmt(this.costPerTaskCeiling)} (baseline $${fmt(medianBaselineCost)})`,\n rejectionCode: 'cost_ceiling',\n }\n }\n\n return {\n promote: true,\n candidateId,\n baselineId,\n evidence,\n reason:\n `promote: paired holdout median Δ=${fmt(ci.median)} ` +\n `CI=[${fmt(ci.low)}, ${fmt(ci.high)}] over ${productiveRuns} pairs; ` +\n `overfit gap candidate=${fmt(overfitGap)} vs baseline=${fmt(baselineOverfitGap)}; ` +\n `median cost candidate=$${fmt(medianCandidateCost)} vs baseline=$${fmt(medianBaselineCost)}`,\n rejectionCode: null,\n }\n }\n}\n\n// ── Helpers ──────────────────────────────────────────────────────────\n\nfunction inferCandidateId(candidate: RunRecord[], baselineKey: string): string {\n for (const run of candidate) {\n if (run.candidateId && run.candidateId !== baselineKey) return run.candidateId\n }\n // All candidate rows match the baseline key — caller mistake, but\n // surface the symptom rather than throwing inside the gate.\n return candidate[0]?.candidateId ?? '(unknown candidate)'\n}\n\nfunction indexHoldoutByKey(runs: RunRecord[]): Map<string, number> {\n const out = new Map<string, number>()\n for (const r of runs) {\n if (r.splitTag !== 'holdout') continue\n if (r.outcome.holdoutScore === undefined) continue\n out.set(pairKey(r), r.outcome.holdoutScore)\n }\n return out\n}\n\nfunction pairKey(r: RunRecord): string {\n return `${r.experimentId}::${r.seed}`\n}\n\nfunction scores(\n runs: RunRecord[],\n field: 'searchScore' | 'holdoutScore',\n splitFilter: 'search' | 'holdout',\n): number[] {\n const out: number[] = []\n for (const r of runs) {\n if (r.splitTag !== splitFilter) continue\n const v = r.outcome[field]\n if (typeof v === 'number' && Number.isFinite(v)) out.push(v)\n }\n return out\n}\n\nfunction mean(xs: number[]): number {\n if (xs.length === 0) return Number.NaN\n return xs.reduce((s, x) => s + x, 0) / xs.length\n}\n\nfunction safeDiff(a: number, b: number): number {\n if (!Number.isFinite(a) || !Number.isFinite(b)) return Number.NaN\n return a - b\n}\n\nfunction medianDelta(before: number[], after: number[]): number {\n const ds = before.map((b, i) => after[i]! - b).sort((x, y) => x - y)\n if (ds.length === 0) return 0\n const mid = Math.floor(ds.length / 2)\n return ds.length % 2 === 0 ? (ds[mid - 1]! + ds[mid]!) / 2 : ds[mid]!\n}\n\nfunction medianFinite(xs: number[]): number {\n const ys = xs.filter((x) => Number.isFinite(x)).sort((x, y) => x - y)\n if (ys.length === 0) return Number.NaN\n const mid = Math.floor(ys.length / 2)\n return ys.length % 2 === 0 ? (ys[mid - 1]! + ys[mid]!) / 2 : ys[mid]!\n}\n\nfunction fmt(x: number): string {\n if (!Number.isFinite(x)) return String(x)\n return x.toFixed(4)\n}\n","/**\n * Wrap a single judge LLM call with retry, optional fallback-model\n * rotation, exponential backoff, and a typed `JudgeRetryOutcome`. Callers\n * MUST inspect `succeeded` before using `value`; on failure the library\n * returns `value: null` rather than substituting a default, so a judge\n * abort cannot silently corrupt a downstream composite.\n *\n * Reporting contract: callers ship `TrialResult.judgeSucceeded = succeeded`\n * and `TrialResult.judgeAttempts = attempts` so `aggregateTrialsByMode`\n * with `mode: 'exclude-failed'` drops the trial.\n */\n\nimport { backoffMs, isTransientLlmError } from './llm-client'\n\n/** Retry policy for judge LLM calls. */\nexport interface JudgeRetryPolicy {\n /** Max attempts per model. Default 3 (one initial + two retries). */\n maxAttempts?: number\n /** Per-attempt timeout in ms. Default 90_000 (1.5×agent-eval's 60s default). */\n timeoutMs?: number\n /**\n * Models to try, in order. The first model is the primary; subsequent\n * models are fallbacks invoked only when ALL retries on the previous\n * model have been exhausted. Example: `['claude-code/sonnet', 'kimi-code/k2p6']`\n * runs claude-code up to maxAttempts times, then falls back to kimi.\n * If omitted, the caller's judge function controls model selection and\n * the retries apply to that single model.\n */\n models?: readonly string[]\n /** Exponential backoff function, default `attempt → min(500 * 2^attempt, 16_000)`. */\n backoffMs?: (attempt: number) => number\n /**\n * Predicate deciding whether an error should trigger a retry. Defaults to\n * `isTransientLlmError` — the package-wide classifier shared with\n * `callLlm` — which retries aborts/timeouts, network faults, HTTP/2\n * transport faults, and any `LlmCallError` with status in {429,502,503,504}.\n * JSON-parse and schema-rejection errors are NOT retriable (the model\n * needs prompt adjustment, not another shot).\n */\n isRetryable?: (err: unknown) => boolean\n}\n\n/** Outcome of a wrapped judge invocation. */\nexport interface JudgeRetryOutcome<T> {\n /** The judge's returned value when `succeeded === true`. */\n value: T | null\n /** True iff one of the attempts completed without throwing. */\n succeeded: boolean\n /** Total attempts made across all models. */\n attempts: number\n /** Which model the successful attempt used (when succeeded). */\n modelUsed?: string\n /** Last error captured when `succeeded === false`. */\n error?: Error\n /** Per-attempt error log for forensics. */\n attemptErrors: Array<{ attempt: number; model: string; error: string }>\n}\n\nconst DEFAULT_MAX_ATTEMPTS = 3\nconst DEFAULT_TIMEOUT_MS = 90_000\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n\n/**\n * Wrap a judge call with retry + fallback-model + typed outcome semantics.\n *\n * The `judgeFn` signature is `(model: string, signal: AbortSignal) => Promise<T>`.\n * The signal will be aborted at `timeoutMs`. Callers should pass the signal\n * to their underlying fetch/SDK call so the abort actually fires.\n *\n * Returns a typed outcome — callers MUST inspect `succeeded` before using\n * `value`. The library refuses to default to a silent zero score because a\n * synthetic zero is indistinguishable from a real low score downstream.\n */\nexport async function withJudgeRetry<T>(\n judgeFn: (model: string, signal: AbortSignal) => Promise<T>,\n policy: JudgeRetryPolicy = {},\n): Promise<JudgeRetryOutcome<T>> {\n const maxAttempts = policy.maxAttempts ?? DEFAULT_MAX_ATTEMPTS\n const timeoutMs = policy.timeoutMs ?? DEFAULT_TIMEOUT_MS\n const backoff = policy.backoffMs ?? backoffMs\n const isRetryable = policy.isRetryable ?? isTransientLlmError\n const models =\n policy.models && policy.models.length > 0 ? policy.models : [undefined as unknown as string]\n\n let totalAttempts = 0\n const attemptErrors: JudgeRetryOutcome<T>['attemptErrors'] = []\n let lastError: Error | undefined\n\n for (const model of models) {\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\n totalAttempts += 1\n const controller = new AbortController()\n const timer = setTimeout(() => controller.abort(new Error('TimeoutError')), timeoutMs)\n try {\n const value = await judgeFn(model as string, controller.signal)\n clearTimeout(timer)\n return {\n value,\n succeeded: true,\n attempts: totalAttempts,\n modelUsed: model,\n attemptErrors,\n }\n } catch (err) {\n clearTimeout(timer)\n const errObj = err instanceof Error ? err : new Error(String(err))\n lastError = errObj\n attemptErrors.push({\n attempt: totalAttempts,\n model: model ?? '(default)',\n error: errObj.message,\n })\n if (!isRetryable(errObj)) {\n // Non-retriable (e.g., JSON parse, schema rejection): break out of\n // attempts on this model AND skip the fallback rotation — a\n // permanent error here will be permanent on the fallback too.\n return {\n value: null,\n succeeded: false,\n attempts: totalAttempts,\n error: errObj,\n attemptErrors,\n }\n }\n if (attempt < maxAttempts - 1) {\n await sleep(backoff(attempt))\n }\n }\n }\n // Exhausted attempts on this model — fall through to next model in the\n // rotation (if any). The backoff between MODEL rotations is the same\n // as the last per-attempt backoff (already slept above).\n }\n\n return {\n value: null,\n succeeded: false,\n attempts: totalAttempts,\n error: lastError,\n attemptErrors,\n }\n}\n","/**\n * Inter-critic / inter-pass orthogonality.\n *\n * Detects redundant ensembles. When you run N critics (or N audit passes,\n * or N specialized agents) on the same input, you want them to disagree —\n * each contributing distinct signal. If they all converge on the same set\n * of findings, you're paying N× cost for ~1× signal.\n *\n * The metric is `1 − mean pairwise cosine similarity` over bags of words\n * extracted from each pass's outputs. 1.0 = fully orthogonal,\n * 0.0 = fully redundant.\n *\n * Universal primitive: pass anything that produces text (findings, tool\n * calls rendered as JSON, verdict strings) and the matcher derives its own\n * vocabulary.\n */\n\nexport interface OrthogonalityInput<T> {\n passes: Array<{ findings: T[] }>\n /** Render one element to text. Default: defaultRender (concatenates string fields). */\n text?: (item: T) => string\n /** Minimum token length kept in the bag. Default 4 (drops short fillers). */\n minTokenLength?: number\n}\n\nexport interface OrthogonalityResult {\n /** 1 − mean pairwise cosine similarity across passes. 1=fully orthogonal, 0=fully redundant. */\n orthogonality: number\n /** Number of passes considered. */\n passCount: number\n /** Pairwise cosine similarities, in upper-triangular order (for debugging). */\n similarities: number[]\n}\n\nexport function passOrthogonality<T>(input: OrthogonalityInput<T>): OrthogonalityResult {\n const passes = input.passes\n if (passes.length < 2) {\n return { orthogonality: 1, passCount: passes.length, similarities: [] }\n }\n const render = input.text ?? defaultRender\n const minLen = input.minTokenLength ?? 4\n const vectors = passes.map((p) => bagOfWords(p.findings, render, minLen))\n const sims: number[] = []\n for (let i = 0; i < vectors.length; i++) {\n for (let j = i + 1; j < vectors.length; j++) {\n sims.push(cosineSimilarity(vectors[i]!, vectors[j]!))\n }\n }\n const mean = sims.length === 0 ? 0 : sims.reduce((a, b) => a + b, 0) / sims.length\n return {\n orthogonality: Math.max(0, Math.min(1, 1 - mean)),\n passCount: passes.length,\n similarities: sims,\n }\n}\n\nfunction defaultRender(item: unknown): string {\n if (typeof item === 'string') return item\n if (item && typeof item === 'object') {\n const parts: string[] = []\n for (const v of Object.values(item as Record<string, unknown>)) {\n if (typeof v === 'string') parts.push(v)\n }\n return parts.join(' ')\n }\n return String(item ?? '')\n}\n\nfunction bagOfWords<T>(\n items: T[],\n render: (item: T) => string,\n minLen: number,\n): Map<string, number> {\n const bag = new Map<string, number>()\n for (const item of items) {\n const text = render(item).toLowerCase()\n for (const tok of text.split(/[^a-z0-9]+/).filter((w) => w.length >= minLen)) {\n bag.set(tok, (bag.get(tok) ?? 0) + 1)\n }\n }\n return bag\n}\n\nfunction cosineSimilarity(a: Map<string, number>, b: Map<string, number>): number {\n let dot = 0\n let aMag = 0\n let bMag = 0\n for (const [, v] of a) aMag += v * v\n for (const [, v] of b) bMag += v * v\n for (const [k, v] of a) {\n const bv = b.get(k)\n if (bv) dot += v * bv\n }\n if (aMag === 0 || bMag === 0) return 0\n return dot / (Math.sqrt(aMag) * Math.sqrt(bMag))\n}\n","import type {\n ReferenceReplayCaseRun,\n ReferenceReplayRun,\n ReferenceReplayScenarioScore,\n} from './reference-replay'\nimport type { RunScore } from './run-score'\nimport type { SteeringBundle } from './steering'\nimport type { SteeringOptimizationRow } from './steering-optimizer'\n\nexport interface ReferenceReplaySteeringRowsOptions<Input = unknown> {\n bundleForRun?: (run: ReferenceReplayRun<Input>) => SteeringBundle\n scoreForCase?: (\n caseRun: ReferenceReplayCaseRun<Input>,\n run: ReferenceReplayRun<Input>,\n ) => RunScore\n}\n\nexport function referenceReplayRunsToSteeringRows<Input = unknown>(\n runs: ReferenceReplayRun<Input>[],\n options: ReferenceReplaySteeringRowsOptions<Input> = {},\n): SteeringOptimizationRow[] {\n const rows: SteeringOptimizationRow[] = []\n for (const run of runs) {\n const variantId = run.variantId ?? run.id\n const bundle = options.bundleForRun?.(run) ?? {\n id: variantId,\n metadata: run.metadata,\n }\n\n for (const caseRun of run.cases) {\n rows.push({\n variantId,\n scenarioId: caseRun.caseId,\n bundle,\n score:\n options.scoreForCase?.(caseRun, run) ??\n referenceReplayScenarioToRunScore(caseRun.score, caseRun.durationMs),\n metadata: {\n runId: run.id,\n split: caseRun.split,\n task: caseRun.metadata?.task ?? caseRun.metadata?.repo ?? caseRun.caseId,\n referenceCount: caseRun.references.length,\n candidateCount: caseRun.candidates.length,\n matched: caseRun.score.matched,\n total: caseRun.score.total,\n falsePositives: caseRun.score.falsePositives,\n precision: caseRun.score.precision,\n recall: caseRun.score.recall,\n f1: caseRun.score.f1,\n error: caseRun.error,\n ...(caseRun.metadata ?? {}),\n },\n })\n }\n }\n return rows\n}\n\nexport function referenceReplayScenarioToRunScore(\n scenarioScore: ReferenceReplayScenarioScore,\n durationMs = 0,\n): RunScore {\n const success = scenarioScore.f1\n const recall = scenarioScore.recall\n const precision = scenarioScore.precision\n const failed = scenarioScore.total > 0 && scenarioScore.matched === 0\n\n return {\n success,\n goalProgress: recall,\n repoGroundedness: precision,\n driftPenalty: 1 - precision,\n toolUseQuality: precision,\n patchQuality: 0,\n testReality: scenarioScore.total > 0 ? 1 : 0,\n finalGate: success,\n reviewerBlockers: failed ? 1 : 0,\n costUsd: 0,\n wallSeconds: Math.max(0, durationMs / 1000),\n notes: [\n `reference-replay matched ${scenarioScore.matched}/${scenarioScore.total}`,\n `precision=${precision.toFixed(3)} recall=${recall.toFixed(3)} f1=${success.toFixed(3)}`,\n ],\n }\n}\n","/**\n * Researcher interface — stable hook for an external autonomous-research\n * agent to drive the meta-loop.\n *\n * Implementations live downstream (typically in a private repo that\n * runs the actual LLM). This package ships only the contract + a\n * `NoopResearcher` so consumers can wire the surface without being\n * forced to implement every method up front.\n *\n * The four methods mirror the four stages of the paper \"Two Loops,\n * Three Roles\":\n *\n * inspectFailures — given the observed runs, what failure modes\n * are present? (data → diagnosis)\n * proposeChange — given diagnosed failure modes, what\n * structural changes should we try?\n * (diagnosis → plan delta)\n * applyChange — fold the proposed deltas into a concrete\n * experiment plan against an existing baseline.\n * (plan delta → executable plan)\n * evaluateChange — run the plan, return runs + the gate verdict.\n * (executable plan → verdict)\n *\n * Composition is the discipline: a Researcher implementation MUST\n * keep these four steps separate and inspectable. Conflating\n * \"diagnose + propose + run\" into a single LLM call defeats the\n * point of the framework — you can't audit which step lied.\n *\n * THIS INTERFACE IS STABLE. Breaking changes require a new module\n * (e.g. `Researcher2`) so existing implementations keep working.\n */\n\nimport type { GateDecision } from './held-out-gate'\nimport type { RunRecord, RunSplitTag } from './run-record'\n\n/** A diagnosed failure mode with the run-IDs that exhibit it. */\nexport interface FailureMode {\n /** Short machine-readable code. Must be stable across runs of the\n * same researcher to enable longitudinal tracking. */\n code: string\n /** Human-readable description for the paper / dashboard. */\n description: string\n evidence: {\n /** Run IDs (from `RunRecord.runId`) where this failure mode was\n * observed. */\n runIds: string[]\n /** Number of run samples that informed the diagnosis. */\n samples: number\n }\n}\n\n/** A single steering change the researcher wants to try. */\nexport interface SteeringChange {\n kind: 'reviewer_prompt' | 'skill_add' | 'skill_remove' | 'threshold' | 'budget'\n /** Implementation-specific payload. Researcher implementations\n * define the schema — keep this `unknown` here to avoid coupling\n * the public interface to any one researcher's internal model. */\n payload: unknown\n /** Why the researcher proposed this change. Goes into the audit\n * trail next to the failure-mode evidence. */\n rationale: string\n /** Optional self-reported expected delta on the headline metric. */\n expectedDelta?: number\n}\n\n/** A single experiment plan, mapped onto the search/holdout splits. */\nexport interface ExperimentPlan {\n baselineCandidateId: string\n proposedCandidateId: string\n changes: SteeringChange[]\n /** USD ceiling for the entire experiment. The runner must stop\n * before exceeding this and report a partial result. */\n evaluationBudgetUsd: number\n /** Item IDs (your dataset keys) for the search vs holdout splits. */\n splits: { search: string[]; holdout: string[] }\n}\n\n/** Result of running a plan: every run, plus the gate verdict. */\nexport interface ExperimentResult {\n plan: ExperimentPlan\n runs: RunRecord[]\n gateDecision: GateDecision\n}\n\n/**\n * The researcher loop. Stable, four-step, inspectable.\n *\n * ┌──────────┐ inspectFailures ┌──────────┐ proposeChange ┌──────────┐\n * │ runs │ ─────────────────▶│ failures │ ──────────────▶│ changes │\n * └──────────┘ └──────────┘ └────┬─────┘\n * │\n * ▼\n * ┌────────────────┐ applyChange ┌────────┐\n * │ ExperimentPlan │ ◀────────────│ base │\n * └────────┬───────┘ └────────┘\n * │\n * evaluateChange ▼\n * ┌────────────────┐\n * │ ExperimentResult│\n * └────────────────┘\n */\nexport interface Researcher {\n inspectFailures(runs: RunRecord[]): Promise<FailureMode[]>\n proposeChange(failures: FailureMode[]): Promise<SteeringChange[]>\n applyChange(changes: SteeringChange[], baseline: ExperimentPlan): Promise<ExperimentPlan>\n evaluateChange(plan: ExperimentPlan): Promise<ExperimentResult>\n}\n\nexport interface CallbackResearcherOptions {\n inspectFailures: Researcher['inspectFailures']\n proposeChange: Researcher['proposeChange']\n applyChange: Researcher['applyChange']\n evaluateChange: Researcher['evaluateChange']\n}\n\n/**\n * Minimal concrete researcher for tests, scripts, and small integrations.\n * Larger autonomous researchers can still implement `Researcher` directly.\n */\nexport class CallbackResearcher implements Researcher {\n constructor(private readonly callbacks: CallbackResearcherOptions) {}\n\n inspectFailures(runs: RunRecord[]): Promise<FailureMode[]> {\n return this.callbacks.inspectFailures(runs)\n }\n\n proposeChange(failures: FailureMode[]): Promise<SteeringChange[]> {\n return this.callbacks.proposeChange(failures)\n }\n\n applyChange(changes: SteeringChange[], baseline: ExperimentPlan): Promise<ExperimentPlan> {\n return this.callbacks.applyChange(changes, baseline)\n }\n\n evaluateChange(plan: ExperimentPlan): Promise<ExperimentResult> {\n return this.callbacks.evaluateChange(plan)\n }\n}\n\n/**\n * No-op researcher — fails loud on every method. Use as a placeholder\n * in code paths that wire the interface but don't have an implementation\n * yet. Importantly, this does NOT silently succeed: a no-op researcher\n * that returned empty arrays would muffle the loop's signal that\n * nobody implemented the brain.\n */\nexport class NoopResearcher implements Researcher {\n private readonly hint: string\n\n constructor(hint = 'NoopResearcher: no implementation wired') {\n this.hint = hint\n }\n\n async inspectFailures(_runs: RunRecord[]): Promise<FailureMode[]> {\n throw new Error(`${this.hint} (inspectFailures not implemented)`)\n }\n\n async proposeChange(_failures: FailureMode[]): Promise<SteeringChange[]> {\n throw new Error(`${this.hint} (proposeChange not implemented)`)\n }\n\n async applyChange(\n _changes: SteeringChange[],\n _baseline: ExperimentPlan,\n ): Promise<ExperimentPlan> {\n throw new Error(`${this.hint} (applyChange not implemented)`)\n }\n\n async evaluateChange(_plan: ExperimentPlan): Promise<ExperimentResult> {\n throw new Error(`${this.hint} (evaluateChange not implemented)`)\n }\n}\n\n/** Re-export the split alias so callers don't have to import twice. */\nexport type { RunSplitTag }\n","/**\n * SandboxPool — bounded checkout/release pool for mutation slots.\n *\n * The composite-mutator's `code` channel needs an isolated workspace per\n * mutation attempt: a git worktree, a sandbox container, a tmpdir clone —\n * whatever the consumer's runtime is. Without a pool, every consumer\n * re-implements the same machinery (mint N slots, check one out per\n * mutation, reset before reuse, drain at the end, track utilisation for\n * the cost ledger). This primitive ships that machinery so consumers\n * supply only a `SlotFactory`.\n *\n * Generic over a slot resource `T` so the same pool serves git worktrees\n * (T = path), Tangle sandboxes (T = SandboxBox), or anything else with\n * the create/reset/destroy lifecycle.\n *\n * Concurrency: FIFO via the shared `Mutex` primitive. Each `checkout()`\n * either takes an idle slot or queues until one is released. Lifecycle\n * is single-process — multi-process pools need external coordination\n * (file locks, etc.) and are deliberately out of scope.\n */\n\nimport { Mutex } from './concurrency'\n\nexport interface PoolSlot<T> {\n /** Stable id assigned at slot creation. Use for telemetry / lineage. */\n readonly id: string\n /** Consumer-defined resource. */\n readonly resource: T\n}\n\nexport interface SlotFactory<T> {\n /** Build a new slot. Called lazily as the pool grows up to `size`. */\n create(slotId: string): Promise<T>\n /**\n * Reset a slot to a clean state before reuse. Called BEFORE every\n * checkout returns it (including the first — so the factory's\n * `create` can leave the slot dirty and let `reset` normalise).\n * Optional; default is a no-op.\n */\n reset?(slot: PoolSlot<T>): Promise<void>\n /** Tear the slot down. Called by `drain()`. */\n destroy(slot: PoolSlot<T>): Promise<void>\n}\n\nexport interface SandboxPool<T> {\n /**\n * Take a slot. If all slots are busy, the promise resolves when one\n * is released. Always pair with the returned `release` (or wrap with\n * `withSlot`).\n */\n checkout(): Promise<{ slot: PoolSlot<T>; release: () => void }>\n /**\n * Run `fn` with a checked-out slot, releasing on completion or throw.\n * The convenience wrapper most callers should use.\n */\n withSlot<R>(fn: (slot: PoolSlot<T>) => Promise<R>): Promise<R>\n /** Destroy every slot. Idempotent. */\n drain(): Promise<void>\n /** How many slots have been minted (≤ `size`). */\n poolSize(): number\n /** How many checkouts are currently outstanding. */\n activeCheckouts(): number\n /** Snapshot of busy/total durations for the cost ledger. */\n utilization(): { busyMs: number; totalMs: number; checkouts: number }\n}\n\nexport interface CreateSandboxPoolOpts<T> {\n /** Maximum concurrent slots. Slots are minted on first need, not eagerly. */\n size: number\n factory: SlotFactory<T>\n}\n\ninterface SlotState<T> {\n slot: PoolSlot<T>\n busy: boolean\n}\n\nexport function createSandboxPool<T>(opts: CreateSandboxPoolOpts<T>): SandboxPool<T> {\n if (opts.size < 1) throw new Error(`sandbox pool size must be >= 1 (got ${opts.size})`)\n\n const slots: SlotState<T>[] = []\n const waiters: Array<(s: SlotState<T>) => void> = []\n const mutex = new Mutex()\n let nextSlotId = 0\n let totalCheckouts = 0\n let busyMs = 0\n const startedAt = Date.now()\n\n /**\n * Acquire — atomic across `mutex`. Either find an idle slot, mint a\n * new one (if under capacity), or queue. The mutex bounds at the\n * search/mint boundary; the actual create() runs OUTSIDE the lock so\n * a slow factory doesn't starve other waiters.\n */\n async function acquireSlot(): Promise<SlotState<T>> {\n let mintId: string | undefined\n const ready = await mutex.runExclusive(async () => {\n const idle = slots.find((s) => !s.busy)\n if (idle) {\n idle.busy = true\n return idle\n }\n if (slots.length < opts.size) {\n // Reserve a slot ID synchronously so concurrent acquireSlot\n // calls don't all decide to mint past the cap.\n mintId = `slot_${nextSlotId++}`\n return null\n }\n return null\n })\n if (ready) return ready\n if (mintId !== undefined) {\n const resource = await opts.factory.create(mintId)\n const state: SlotState<T> = {\n slot: { id: mintId, resource },\n busy: true,\n }\n await mutex.runExclusive(() => {\n slots.push(state)\n })\n return state\n }\n // All slots busy + at cap: queue.\n return new Promise<SlotState<T>>((resolve) => {\n waiters.push((s) => {\n s.busy = true\n resolve(s)\n })\n })\n }\n\n function releaseSlot(state: SlotState<T>): void {\n // Non-async release — runs synchronously inside the user's finally.\n // Reset is async; we kick it off and let the next waiter see a\n // freshly-reset slot once it lands.\n void (async () => {\n try {\n if (opts.factory.reset) await opts.factory.reset(state.slot)\n } catch (err) {\n // A failing reset is the consumer's bug; we still release\n // (otherwise the pool deadlocks). Surface via console.warn so\n // it doesn't get lost.\n console.warn(`[sandbox-pool] reset failed for slot ${state.slot.id}:`, err)\n }\n state.busy = false\n const next = waiters.shift()\n if (next) next(state)\n })()\n }\n\n async function checkout(): Promise<{ slot: PoolSlot<T>; release: () => void }> {\n const state = await acquireSlot()\n const checkoutStart = Date.now()\n totalCheckouts++\n return {\n slot: state.slot,\n release: () => {\n busyMs += Date.now() - checkoutStart\n releaseSlot(state)\n },\n }\n }\n\n async function withSlot<R>(fn: (slot: PoolSlot<T>) => Promise<R>): Promise<R> {\n const { slot, release } = await checkout()\n try {\n return await fn(slot)\n } finally {\n release()\n }\n }\n\n async function drain(): Promise<void> {\n // Snapshot under lock; destroy outside lock so a slow teardown\n // doesn't block a concurrent drain caller.\n const snapshot = await mutex.runExclusive(() => {\n const taken = slots.splice(0, slots.length)\n // Reject any pending waiters — pool is going away.\n for (const w of waiters.splice(0, waiters.length)) {\n // Best-effort rejection: the waiter is still pending; we\n // can't reject a Promise we already resolved. Surface as a\n // warning. In practice, drain() is called when nothing's in\n // flight (end of run), so this is a defensive no-op.\n void w\n }\n return taken\n })\n await Promise.allSettled(snapshot.map((s) => opts.factory.destroy(s.slot)))\n }\n\n function utilization() {\n return {\n busyMs,\n totalMs: Date.now() - startedAt,\n checkouts: totalCheckouts,\n }\n }\n\n return {\n checkout,\n withSlot,\n drain,\n poolSize: () => slots.length,\n activeCheckouts: () => slots.filter((s) => s.busy).length,\n utilization,\n }\n}\n","/**\n * Pipeline-level OTEL integration — auto-attaches an OTEL exporter when\n * OTEL_EXPORTER_OTLP_ENDPOINT is set. Pipelines call `withOtelPipeline()`\n * to get a configured exporter + shutdown handle without manual wiring.\n *\n * Used by: runEvalCampaign, runProductionLoop, runAgentMatrix.\n */\n\nimport { createOtelExporter, type OtelExportConfig, type OtelExporter } from './trace/otel-export'\n\nexport interface OtelPipelineHandle {\n /** The active exporter, or undefined if no endpoint is configured. */\n exporter: OtelExporter | undefined\n /** Call at pipeline end to flush + shutdown. Safe to call even if exporter is undefined. */\n shutdown(): Promise<void>\n}\n\nexport interface OtelPipelineOptions {\n /** Override OTEL config. */\n otelConfig?: OtelExportConfig\n /** Pipeline-specific resource attributes. */\n pipelineKind?: string\n pipelineId?: string\n}\n\n/**\n * Create an OTEL exporter scoped to a pipeline run. Auto-reads\n * OTEL_EXPORTER_OTLP_ENDPOINT from env when no explicit config is passed.\n *\n * Returns a handle with `exporter` (possibly undefined) and `shutdown()`.\n */\nexport function withOtelPipeline(opts?: OtelPipelineOptions): OtelPipelineHandle {\n const config: OtelExportConfig = {\n ...opts?.otelConfig,\n resourceAttributes: {\n ...(opts?.pipelineKind ? { 'pipeline.kind': opts.pipelineKind } : {}),\n ...(opts?.pipelineId ? { 'pipeline.id': opts.pipelineId } : {}),\n ...opts?.otelConfig?.resourceAttributes,\n },\n }\n\n const exporter = createOtelExporter(config)\n\n return {\n exporter,\n async shutdown() {\n if (exporter) await exporter.shutdown()\n },\n }\n}\n\n/**\n * Check if OTEL export is configured (endpoint is set).\n */\nexport function isOtelConfigured(): boolean {\n return !!(typeof process !== 'undefined' && process.env.OTEL_EXPORTER_OTLP_ENDPOINT)\n}\n","/**\n * Traced analyst wrapper — instruments `analyzeTraces` with spans so the\n * analyst's internal LLM calls (actor + responder turns) appear in the\n * trace tree. Also wraps each actor turn callback with a span.\n *\n * Since the analyst uses @ax-llm/ax internally (an agent framework with\n * its own turn loop), we cannot wrap individual `tc.chat()` calls without\n * forking ax. Instead, we wrap at the boundary:\n * 1. A parent span for the entire analyst run.\n * 2. Per-turn child spans from the `onTurn` callback (captures code,\n * output size, error status).\n * 3. Summary attributes on the parent (total turns, usage, findings).\n */\n\nimport type { TraceEmitter } from './trace/emitter'\nimport type {\n AnalyzeTracesInput,\n AnalyzeTracesOptions,\n AnalyzeTracesResult,\n AnalyzeTracesTurnSnapshot,\n} from './trace-analyst/analyst'\nimport { analyzeTraces } from './trace-analyst/analyst'\n\nexport interface TracedAnalystOptions {\n /** TraceEmitter for span emission. */\n emitter: TraceEmitter\n /** Parent span id. If omitted, uses emitter stack. */\n parentSpanId?: string\n}\n\n/**\n * Run `analyzeTraces` wrapped in a parent span with per-turn child spans.\n */\nexport async function tracedAnalyzeTraces(\n input: AnalyzeTracesInput,\n options: AnalyzeTracesOptions,\n traceOpts: TracedAnalystOptions,\n): Promise<AnalyzeTracesResult> {\n const parentSpan = await traceOpts.emitter.span({\n kind: 'custom',\n name: 'analyst:analyze-traces',\n parentSpanId: traceOpts.parentSpanId,\n attributes: {\n 'analyst.question_length': input.question.length,\n 'analyst.max_turns': options.maxTurns ?? 12,\n 'analyst.max_depth': options.maxDepth ?? 1,\n 'eval.phase': 'analyst',\n },\n })\n\n // Intercept onTurn to emit per-turn spans.\n const originalOnTurn = options.onTurn\n const turnSpanIds: string[] = []\n\n const wrappedOptions: AnalyzeTracesOptions = {\n ...options,\n onTurn: async (turn: AnalyzeTracesTurnSnapshot) => {\n const turnSpan = await traceOpts.emitter.span({\n kind: 'custom',\n name: `analyst:turn-${turn.turn}`,\n parentSpanId: parentSpan.span.spanId,\n attributes: {\n 'analyst.turn': turn.turn,\n 'analyst.is_error': turn.isError,\n 'analyst.code_length': turn.code.length,\n 'analyst.output_length': turn.output.length,\n 'eval.phase': 'analyst',\n },\n })\n turnSpanIds.push(turnSpan.span.spanId)\n if (turn.isError) {\n await turnSpan.fail('Turn produced an error')\n } else {\n await turnSpan.end()\n }\n if (originalOnTurn) await originalOnTurn(turn)\n },\n }\n\n try {\n const result = await analyzeTraces(input, wrappedOptions)\n await parentSpan.end({\n attributes: {\n 'analyst.question_length': input.question.length,\n 'analyst.turn_count': result.turnCount,\n 'analyst.finding_count': result.findings.length,\n 'analyst.answer_length': result.answer.length,\n 'eval.phase': 'analyst',\n },\n } as Record<string, unknown>)\n return result\n } catch (err) {\n await parentSpan.fail(err instanceof Error ? err : String(err))\n throw err\n }\n}\n","/**\n * Traced judge wrappers — instruments every LLM call inside the judge\n * ensemble with child spans so OTEL sinks see per-judge latency, model,\n * token counts, and score dimensions.\n *\n * The ensemble parent span groups all individual judge spans; each judge\n * gets its own child span with model + score as attributes.\n */\n\nimport type { TCloud } from '@tangle-network/tcloud'\nimport type { TraceEmitter } from './trace/emitter'\nimport type { JudgeFn, JudgeInput, JudgeScore } from './types'\n\nexport interface TracedJudgeOptions {\n /** TraceEmitter to emit spans into. */\n emitter: TraceEmitter\n /** Parent span id for the ensemble. If omitted, uses the emitter stack. */\n parentSpanId?: string\n}\n\n/**\n * Wrap a single JudgeFn so its LLM call emits a traced span.\n */\nexport function traceJudge(judge: JudgeFn, judgeName: string, opts: TracedJudgeOptions): JudgeFn {\n return async (tc: TCloud, input: JudgeInput): Promise<JudgeScore[]> => {\n const span = await opts.emitter.span({\n kind: 'llm',\n name: `judge:${judgeName}`,\n parentSpanId: opts.parentSpanId,\n attributes: {\n 'judge.name': judgeName,\n 'eval.phase': 'judge',\n },\n })\n try {\n const scores = await judge(tc, input)\n const composite =\n scores.length > 0 ? scores.reduce((sum, s) => sum + s.score, 0) / scores.length : 0\n await span.end({\n attributes: {\n 'judge.name': judgeName,\n 'judge.composite_score': composite,\n 'judge.dimension_count': scores.length,\n 'eval.phase': 'judge',\n },\n } as Record<string, unknown>)\n return scores\n } catch (err) {\n await span.fail(err instanceof Error ? err : String(err))\n throw err\n }\n }\n}\n\n/**\n * Wrap an array of JudgeFns with tracing, running them inside an ensemble\n * parent span. Returns a single function that calls all judges and merges\n * their scores.\n */\nexport function traceJudgeEnsemble(\n judges: JudgeFn[],\n judgeNames: string[],\n opts: TracedJudgeOptions,\n): JudgeFn {\n return async (tc: TCloud, input: JudgeInput) => {\n const ensembleSpan = await opts.emitter.span({\n kind: 'custom',\n name: 'judge:ensemble',\n parentSpanId: opts.parentSpanId,\n attributes: {\n 'judge.ensemble_size': judges.length,\n 'eval.phase': 'judge',\n },\n })\n try {\n const allScores: JudgeScore[] = []\n for (let i = 0; i < judges.length; i++) {\n const judge = judges[i]!\n const name = judgeNames[i] ?? `judge_${i}`\n const tracedFn = traceJudge(judge, name, {\n emitter: opts.emitter,\n parentSpanId: ensembleSpan.span.spanId,\n })\n const scores = await tracedFn(tc, input)\n allScores.push(...scores)\n }\n const composite =\n allScores.length > 0 ? allScores.reduce((sum, s) => sum + s.score, 0) / allScores.length : 0\n await ensembleSpan.end({\n attributes: {\n 'judge.ensemble_size': judges.length,\n 'judge.composite_score': composite,\n 'judge.total_dimensions': allScores.length,\n 'eval.phase': 'judge',\n },\n } as Record<string, unknown>)\n return allScores\n } catch (err) {\n await ensembleSpan.fail(err instanceof Error ? err : String(err))\n throw err\n }\n }\n}\n"],"mappings":"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","names":["llmSpans","toolSpans","judgeSpans","sum","finding","scores","z","z","existsSync","existsSync","ACTOR_PROMPT","ACTOR_PROMPT","ACTOR_PROMPT","existsSync","readFileSync","existsSync","readFileSync","sum","own","dirname","join","check","scores","join","canonicalize","sum","agent","check","precision","aggregate","scores","ratio","fs","runScore","mean","sum","scores","sum","existsSync","readdirSync","readFileSync","statSync","join","appendFileSync","existsSync","mkdirSync","readFileSync","dirname","scores","mkdirSync","dirname","appendFileSync","existsSync","readFileSync","fmt","mean","passed","margin","scores","scores","mean","scores","ratio","worst","join","i","j","pa","scores","mean","runs","groupBy","scores","existsSync","readdirSync","readFileSync","statSync","join","tail","sum","DEFAULT_MODEL","DEFAULT_TIMEOUT","DEFAULT_MAX_SOURCE","DEFAULT_MAX_PER_FILE","DEFAULT_MAX_HTML","truncate","buildPrompt","appendFileSync","existsSync","mkdirSync","readFileSync","dirname","scoreOptions","mkdirSync","dirname","appendFileSync","existsSync","scores","mean","clamp01","sum","precision","tokens","readFileSync","softFail","join","defaultExtract","mean","mean","precision","scores","sum"]}
1
+ {"version":3,"sources":["../src/run-score.ts","../src/run-critic.ts","../src/semantic-concept-judge.ts","../src/analyst/types.ts","../src/analyst/adapters.ts","../src/analyst/chat-client.ts","../src/analyst/finding-signature.ts","../src/analyst/finding-subject.ts","../src/analyst/findings-store.ts","../src/locked-jsonl-appender.ts","../src/concurrency.ts","../src/analyst/kind-factory.ts","../src/analyst/tool-groups.ts","../src/analyst/kinds/failure-mode.ts","../src/analyst/kinds/improvement.ts","../src/analyst/kinds/knowledge-gap.ts","../src/analyst/kinds/knowledge-poisoning.ts","../src/analyst/kinds/index.ts","../src/analyst/kinds/skill-usage.ts","../src/analyst/registry.ts","../src/auto-pr.ts","../src/executor.ts","../src/benchmark.ts","../src/client.ts","../src/convergence.ts","../src/metrics.ts","../src/driver.ts","../src/feedback-trajectory.ts","../src/integrity/single-backend.ts","../src/judge-families.ts","../src/judges.ts","../src/live-proof.ts","../src/pr-review-benchmark.ts","../src/registry.ts","../src/reporter.ts","../src/anti-slop.ts","../src/artifact-validator.ts","../src/completion-verifier.ts","../src/dual-agent-bench.ts","../src/experiment-tracker.ts","../src/experiment-tracker-d1.ts","../src/experiment-tracker-fs.ts","../src/harness-optimizer.ts","../src/judge-runner.ts","../src/playbook.ts","../src/produced-state.ts","../src/prompt-registry.ts","../src/steering.ts","../src/steering-optimizer.ts","../src/workspace-inspector.ts","../src/budget-guard.ts","../src/cost-tracker.ts","../src/muffled-gate-scanner.ts","../src/oracle.ts","../src/scorecard.ts","../src/series-convergence.ts","../src/slo.ts","../src/state-continuity.ts","../src/behavior-dsl.ts","../src/ci-gate.ts","../src/observability.ts","../src/paraphrase.ts","../src/visual-diff.ts","../src/bisector.ts","../src/counterfactual.ts","../src/cross-trace-diff.ts","../src/active-learning.ts","../src/causal-attribution.ts","../src/reward-model-export.ts","../src/self-play.ts","../src/command-runner.ts","../src/deploy-gate-layer.ts","../src/error-count-extractor.ts","../src/flow-layer.ts","../src/intent-match-judge.ts","../src/keyword-coverage-judge.ts","../src/multi-layer-verifier.ts","../src/multi-toolchain-layer.ts","../src/reference-replay.ts","../src/reviewer.ts","../src/discover-personas.ts","../src/golden-matcher.ts","../src/held-out-gate.ts","../src/judge-retry.ts","../src/orthogonality.ts","../src/reference-replay-steering.ts","../src/researcher.ts","../src/sandbox-pool.ts","../src/otel-pipeline.ts","../src/traced-analyst.ts","../src/traced-judges.ts"],"sourcesContent":["export interface RunScore {\n success: number\n goalProgress: number\n repoGroundedness: number\n driftPenalty: number\n toolUseQuality: number\n patchQuality: number\n testReality: number\n finalGate: number\n reviewerBlockers: number\n costUsd: number\n wallSeconds: number\n notes?: string[]\n}\n\nexport interface RunScoreWeights {\n success: number\n goalProgress: number\n repoGroundedness: number\n driftPenalty: number\n toolUseQuality: number\n patchQuality: number\n testReality: number\n finalGate: number\n reviewerBlockers: number\n costUsd: number\n wallSeconds: number\n}\n\nexport const DEFAULT_RUN_SCORE_WEIGHTS: RunScoreWeights = {\n success: 4,\n goalProgress: 2,\n repoGroundedness: 1.5,\n driftPenalty: -1.5,\n toolUseQuality: 1,\n patchQuality: 1.25,\n testReality: 1.5,\n finalGate: 3,\n reviewerBlockers: -2,\n costUsd: -0.2,\n wallSeconds: -0.1,\n}\n\nexport function aggregateRunScore(score: RunScore, weights: Partial<RunScoreWeights> = {}): number {\n const w = { ...DEFAULT_RUN_SCORE_WEIGHTS, ...weights }\n return (\n w.success * clamp01(score.success) +\n w.goalProgress * clamp01(score.goalProgress) +\n w.repoGroundedness * clamp01(score.repoGroundedness) +\n w.driftPenalty * clamp01(score.driftPenalty) +\n w.toolUseQuality * clamp01(score.toolUseQuality) +\n w.patchQuality * clamp01(score.patchQuality) +\n w.testReality * clamp01(score.testReality) +\n w.finalGate * clamp01(score.finalGate) +\n w.reviewerBlockers * clamp01(score.reviewerBlockers) +\n w.costUsd * Math.max(0, finiteOrZero(score.costUsd)) +\n w.wallSeconds * Math.max(0, finiteOrZero(score.wallSeconds) / 60)\n )\n}\n\nexport function clamp01(value: number): number {\n if (!Number.isFinite(value)) return 0\n return Math.max(0, Math.min(1, value))\n}\n\nfunction finiteOrZero(value: number): number {\n return Number.isFinite(value) ? value : 0\n}\n","import { NotFoundError } from './errors'\nimport { aggregateRunScore, clamp01, type RunScore, type RunScoreWeights } from './run-score'\nimport type { Artifact, BudgetLedgerEntry, Run, Span, TraceEvent, TraceStore } from './trace'\n\nexport interface RunTrace {\n run: Run\n spans: Span[]\n events: TraceEvent[]\n artifacts: Artifact[]\n budget: BudgetLedgerEntry[]\n}\n\nexport interface RunCriticOptions {\n weights?: Partial<RunScoreWeights>\n driftPatterns?: RegExp[]\n}\n\nconst DEFAULT_DRIFT_PATTERNS = [\n /https?:\\/\\//i,\n /\\btitle:\\s/i,\n /\\bsummary:\\s/i,\n /\\burl:\\s/i,\n /\\bnpm package usage\\b/i,\n /\\bnews\\b/i,\n]\n\nexport class RunCritic {\n private readonly weights?: Partial<RunScoreWeights>\n private readonly driftPatterns: RegExp[]\n\n constructor(options: RunCriticOptions = {}) {\n this.weights = options.weights\n this.driftPatterns = options.driftPatterns ?? DEFAULT_DRIFT_PATTERNS\n }\n\n async score(store: TraceStore, runId: string): Promise<RunScore> {\n const run = await store.getRun(runId)\n if (!run) throw new NotFoundError(`run ${runId} not found`)\n const [spans, events, artifacts, budget] = await Promise.all([\n store.spans({ runId }),\n store.events({ runId }),\n store.artifacts(runId),\n store.budget(runId),\n ])\n return this.scoreTrace({ run, spans, events, artifacts, budget })\n }\n\n scoreTrace(trace: RunTrace): RunScore {\n const notes: string[] = []\n const llmSpans = trace.spans.filter(\n (s): s is Extract<Span, { kind: 'llm' }> => s.kind === 'llm',\n )\n const toolSpans = trace.spans.filter(\n (s): s is Extract<Span, { kind: 'tool' }> => s.kind === 'tool',\n )\n const judgeSpans = trace.spans.filter(\n (s): s is Extract<Span, { kind: 'judge' }> => s.kind === 'judge',\n )\n const sandboxSpans = trace.spans.filter(\n (s): s is Extract<Span, { kind: 'sandbox' }> => s.kind === 'sandbox',\n )\n const finalGateSpans = judgeSpans.filter(\n (span) => span.dimension === 'final_gate' || span.attributes?.finalGate === true,\n )\n\n const success =\n trace.run.outcome?.pass === true ? 1 : trace.run.status === 'completed' ? 0.5 : 0\n if (!success) notes.push('run did not complete with pass=true')\n\n const judgeAverage = judgeSpans.length\n ? judgeSpans.reduce((sum, span) => sum + normalizeJudgeScore(span.score), 0) /\n judgeSpans.length\n : undefined\n const outcomeScore =\n typeof trace.run.outcome?.score === 'number'\n ? clamp01(\n trace.run.outcome.score > 1 ? trace.run.outcome.score / 100 : trace.run.outcome.score,\n )\n : undefined\n const goalProgress = outcomeScore ?? judgeAverage ?? success\n\n const successfulTools = toolSpans.filter((span) => span.status !== 'error').length\n const toolUseQuality = toolSpans.length === 0 ? 0 : successfulTools / toolSpans.length\n if (toolSpans.length === 0) notes.push('no tool spans recorded')\n\n const patchEvidence =\n trace.artifacts.length +\n toolSpans.filter((span) => /write|edit|patch|apply/i.test(span.toolName)).length\n const patchQuality = patchEvidence > 0 ? clamp01(patchEvidence / 4) : 0\n if (!patchQuality) notes.push('no artifact or edit evidence recorded')\n\n const sandboxTests = sandboxSpans.filter(\n (span) => typeof span.testsTotal === 'number' && span.testsTotal > 0,\n )\n const testReality = sandboxTests.length\n ? sandboxTests.reduce(\n (sum, span) => sum + (span.testsPassed ?? 0) / Math.max(1, span.testsTotal ?? 1),\n 0,\n ) / sandboxTests.length\n : toolSpans.some((span) =>\n /\\btest|vitest|pytest|jest|build|tsc\\b/i.test(JSON.stringify(span.args)),\n )\n ? 0.4\n : 0\n if (!testReality) notes.push('no real test/build evidence recorded')\n\n const blockerSpans = judgeSpans.filter((span) => isBlockingJudge(span))\n const finalGateBlockers = finalGateSpans.filter((span) => isBlockingJudge(span))\n const finalGate = finalGateSpans.length ? (finalGateBlockers.length ? 0 : 1) : success\n if (finalGateBlockers.length)\n notes.push(`final gate blocked by ${finalGateBlockers.length} reviewer(s)`)\n else if (!finalGateSpans.length) notes.push('no final gate judgment recorded')\n\n const reviewerBlockers = judgeSpans.length ? blockerSpans.length / judgeSpans.length : 0\n if (reviewerBlockers) notes.push(`detected ${blockerSpans.length} blocking reviewer signal(s)`)\n\n const positiveGroundingSignals =\n patchEvidence +\n sandboxSpans.length +\n llmSpans.filter((span) => looksRepoGrounded(span.output ?? '')).length\n const driftSignals =\n llmSpans.filter((span) => this.isDrift(span.output ?? '')).length +\n trace.events.filter((event) => this.isDrift(JSON.stringify(event.payload))).length\n const repoGroundedness =\n positiveGroundingSignals + driftSignals === 0\n ? 0\n : positiveGroundingSignals / (positiveGroundingSignals + driftSignals)\n const driftPenalty =\n positiveGroundingSignals + driftSignals === 0\n ? 0\n : driftSignals / (positiveGroundingSignals + driftSignals)\n if (driftSignals > 0) notes.push(`detected ${driftSignals} drift signal(s)`)\n\n const costUsd = trace.budget.length\n ? Math.max(\n ...trace.budget\n .filter((entry: BudgetLedgerEntry) => entry.dimension === 'usd')\n .map((entry: BudgetLedgerEntry) => entry.consumed),\n 0,\n )\n : llmSpans.reduce((sum, span) => sum + (span.costUsd ?? 0), 0)\n const wallSeconds =\n trace.run.endedAt && trace.run.startedAt\n ? Math.max(0, (trace.run.endedAt - trace.run.startedAt) / 1000)\n : 0\n\n return {\n success,\n goalProgress,\n repoGroundedness,\n driftPenalty,\n toolUseQuality,\n patchQuality,\n testReality,\n finalGate,\n reviewerBlockers,\n costUsd,\n wallSeconds,\n notes,\n }\n }\n\n rank(score: RunScore): number {\n return aggregateRunScore(score, this.weights)\n }\n\n private isDrift(text: string): boolean {\n return this.driftPatterns.some((pattern) => pattern.test(text))\n }\n}\n\nfunction normalizeJudgeScore(score: number): number {\n return score > 1 ? clamp01(score / 10) : clamp01(score)\n}\n\nfunction looksRepoGrounded(text: string): boolean {\n return /(?:src\\/|tests?\\/|package\\.json|tsconfig|\\.ts\\b|\\.tsx\\b|git status|pnpm |npm |vitest|pytest|jest)/i.test(\n text,\n )\n}\n\nfunction isBlockingJudge(span: Extract<Span, { kind: 'judge' }>): boolean {\n return (\n span.attributes?.blocking === true ||\n span.attributes?.verdict === 'BLOCKING' ||\n positiveNumber(span.attributes?.blockingFindings) ||\n positiveNumber(span.attributes?.highFindings) ||\n span.score <= 2\n )\n}\n\nfunction positiveNumber(value: unknown): boolean {\n return typeof value === 'number' && value > 0\n}\n","/**\n * Semantic concept judge — \"does the built artifact actually implement\n * the features the user asked for?\"\n *\n * Distinct from the domain/code/coherence judges in `judges.ts`:\n * - those judges score free-form conversational agent outputs along\n * quality dimensions (accuracy, depth, etc.)\n * - this judge scores a *built artifact* (served HTML + source files)\n * against an explicit list of expected concepts, returning per-concept\n * {present, score 0-10, evidence, severity}.\n *\n * The judge is strict about distinguishing (a) a working implementation\n * from (b) a keyword-present stub. \"// TODO: mint button\" is NOT present.\n * Only real, functional, wired-up code counts.\n *\n * Use via {@link createSemanticConceptJudge} or directly via\n * {@link runSemanticConceptJudge}. Soft-fails (available=false) on LLM\n * or JSON-parse errors so the caller can treat that as \"layer skipped\"\n * rather than \"layer failed\" in a multi-layer pipeline.\n */\n\nimport { callLlmJson, type LlmClientOptions } from './llm-client'\nimport type { Severity } from './multi-layer-verifier'\n\n// ─── Types ──────────────────────────────────────────────────────────────\n\n/**\n * Implementation complexity class for weighted scoring.\n *\n * - `render` (default): the concept is a UI surface that displays static\n * data — render a list, show a counter, lay out a button. Single-file\n * work, no external integration.\n * - `integrate`: the concept requires wiring a real external system —\n * wallet connect (wagmi + RainbowKit + chain config), payment provider\n * (Stripe Elements + intent + webhook), an API client with auth.\n * Multi-file, library-knowledge, runtime correctness matters.\n * - `compute`: the concept requires algorithmic work — solver, simulator,\n * constraint propagation, ML inference. Correctness > UI polish.\n *\n * Default weights (when applied via `weightConcepts: 'complexity'`):\n * render=1.0, integrate=2.0, compute=2.5\n *\n * Cross-vertical scoring without complexity weighting silently inflates\n * the rate of UI-heavy verticals (healthcare, fintech dashboards) vs\n * integration-heavy verticals (DeFi, wallets) — all concepts treated\n * equally even though the agent does 2-3x the work for `integrate`.\n */\nexport type ConceptComplexity = 'render' | 'integrate' | 'compute'\n\nexport interface ConceptSpec {\n name: string\n /** Short hints that help the judge; not used for matching. */\n keywords?: string[]\n /** Optional explicit weight; default 1.0. Overrides complexity-derived weight. */\n weight?: number\n /** Implementation complexity class. Default `render`. */\n complexity?: ConceptComplexity\n}\n\nexport interface ConceptFinding {\n concept: string\n present: boolean\n /** 0..10. 10 = production-ready; 7 = functional thin; 4 = partial; 0 = absent. */\n score: number\n evidence: string\n severity: Severity\n}\n\nexport interface SemanticConceptJudgeInput {\n /** Full natural-language prompt the agent was handed. */\n userRequest: string\n /** Rendered HTML the preview returns (UI artifacts). Optional. */\n servedHtml?: string\n /** Top-level source files from the agent's workdir. */\n sourceFiles: Array<{ path: string; content: string }>\n /** The expected concept list. */\n expectedConcepts: ConceptSpec[]\n /** Free-form metadata (id, difficulty) to inject into the prompt. */\n artifactLabel?: string\n artifactDescription?: string\n}\n\nexport interface SemanticConceptJudgeResult {\n kind: 'semantic-concept'\n version: string\n /** Normalized 0..1 score — mean of per-concept scores / 10. */\n score: number\n presentCount: number\n totalCount: number\n findings: ConceptFinding[]\n summary: string\n durationMs: number\n costUsd: number | null\n /** False on LLM/JSON error — treat as \"skipped / unable to judge\" in pipelines. */\n available: boolean\n error?: string\n}\n\n/**\n * Score-aggregation strategy. `mean` averages 0-10 scores uniformly.\n * `complexity` applies the default weight table (render=1, integrate=2,\n * compute=2.5) unless a concept has an explicit `weight`. `explicit`\n * honors only `weight` (defaulting to 1 for unspecified).\n */\nexport type ConceptWeightStrategy = 'mean' | 'complexity' | 'explicit'\n\nexport const DEFAULT_COMPLEXITY_WEIGHTS: Record<ConceptComplexity, number> = {\n render: 1.0,\n integrate: 2.0,\n compute: 2.5,\n}\n\nexport interface SemanticConceptJudgeOptions {\n /** Model id to call. Default 'claude-sonnet-4-6' via agent-eval defaults. */\n model?: string\n /** Per-call timeout. Default 180s. */\n timeoutMs?: number\n /** Pipeline budget for the prompt (source blob truncation). Default 45000. */\n maxSourceChars?: number\n /** Per-file cap before inclusion. Default 20000. */\n maxPerFileChars?: number\n /** HTML cap. Default 30000. */\n maxHtmlChars?: number\n /** LlmClient config (baseUrl, apiKey, authHeader, …). */\n llm?: LlmClientOptions\n /**\n * Score aggregation strategy. Default `mean` — uniform average across\n * concepts. Cross-vertical comparisons should use `complexity` to\n * neutralize the integrate-vs-render asymmetry.\n */\n weightConcepts?: ConceptWeightStrategy\n /** Override the default complexity → weight table. */\n complexityWeights?: Partial<Record<ConceptComplexity, number>>\n}\n\n// ─── Prompt assembly ────────────────────────────────────────────────────\n\nexport const SEMANTIC_CONCEPT_JUDGE_VERSION = 'semantic-concept-judge-v1-2026-04-24'\n\nconst DEFAULT_MAX_SOURCE = 45_000\nconst DEFAULT_MAX_HTML = 30_000\nconst DEFAULT_MAX_PER_FILE = 20_000\nconst DEFAULT_TIMEOUT = 180_000\nconst DEFAULT_MODEL = 'claude-sonnet-4-6'\n\nconst SEMANTIC_SCHEMA = {\n type: 'object',\n additionalProperties: false,\n required: ['summary', 'concepts'],\n properties: {\n summary: { type: 'string', minLength: 20, maxLength: 600 },\n concepts: {\n type: 'array',\n minItems: 1,\n items: {\n type: 'object',\n additionalProperties: false,\n required: ['concept', 'present', 'score', 'evidence', 'severity'],\n properties: {\n concept: { type: 'string', minLength: 1, maxLength: 120 },\n present: { type: 'boolean' },\n score: { type: 'number', minimum: 0, maximum: 10 },\n evidence: { type: 'string', minLength: 5, maxLength: 400 },\n severity: { type: 'string', enum: ['critical', 'major', 'minor', 'info'] },\n },\n },\n },\n },\n}\n\nfunction truncate(body: string, cap: number, label: string): string {\n if (body.length <= cap) return body\n return `${body.slice(0, cap)}\\n… [truncated ${body.length - cap} chars of ${label}]`\n}\n\nfunction buildPrompt(\n input: SemanticConceptJudgeInput,\n opts: Required<SemanticConceptJudgeOptions>,\n): string {\n const sourceBlob = input.sourceFiles\n .filter((f) => f.content.length <= opts.maxPerFileChars)\n .map((f) => `--- FILE: ${f.path} ---\\n${f.content}`)\n .join('\\n\\n')\n\n const html = input.servedHtml ?? ''\n\n return `You are a strict code-review judge evaluating whether an agent's 0-to-1 build actually implements the features the user asked for.\n\nYou MUST distinguish:\n (a) WORKING code that implements the concept (rendered UI, wired handler, real API call),\n (b) KEYWORD-PRESENT stub (comments mentioning the concept, variable names, TODOs),\n (c) ABSENT (concept nowhere).\n\nA comment like \"// TODO: add mint button\" is NOT present — score 2-3. Only count a concept as present if there is real functional code: a rendered component, a call handler wired to state or a network call, a computed value actually used.\n\nUSER REQUEST (what the agent was asked to build):\n${input.userRequest}\n\n${input.artifactLabel ? `ARTIFACT METADATA:\\n name: ${input.artifactLabel}\\n description: ${input.artifactDescription ?? ''}\\n\\n` : ''}EXPECTED CONCEPTS (each must be graded independently):\n${input.expectedConcepts\n .map(\n (c, i) =>\n ` ${i + 1}. \"${c.name}\"${c.keywords?.length ? ` — hints: [${c.keywords.slice(0, 6).join(' | ')}]` : ''}`,\n )\n .join('\\n')}\n\n${html ? `SERVED HTML (what the preview returns when hit):\\n${truncate(html, opts.maxHtmlChars, 'HTML')}\\n\\n` : ''}SOURCE FILES (the agent's workdir):\n${truncate(sourceBlob, opts.maxSourceChars, 'source')}\n\nFor EACH concept, return:\n - concept: the concept name as given (match exactly)\n - present: boolean — does a working implementation exist?\n - score: 0-10 — 10 = production-ready; 7 = functional but thin; 4 = partial/stubbed; 2 = keyword-only comment; 0 = absent\n - evidence: cite \"<file>:<line>\" or \"served-html:<selector>\" pointing at the strongest supporting code. If the concept is absent or stubbed, explain what's missing.\n - severity:\n \"info\" when present: true AND score >= 7\n \"minor\" when present: true AND 4 <= score < 7\n \"major\" when present: false OR score < 4\n \"critical\" when the concept is not only absent but a core user flow depends on it\n\nAlso produce a \"summary\" (one sentence, 20-600 chars): overall verdict on whether this is a shippable implementation of the user request vs a keyword-dense placeholder.\n\nBE SKEPTICAL. Keyword matching already passed — your job is to catch what keyword matching misses. If the agent shipped a working build, say so. If it shipped a stub, say so. Don't grade on effort.\n\nReturn STRICT JSON. No prose outside the JSON.`\n}\n\n// ─── Runner ─────────────────────────────────────────────────────────────\n\n/**\n * Run the semantic concept judge. Soft-fails to available=false on\n * LLM/JSON errors — callers in a MultiLayerVerifier pipeline can treat\n * that as \"skip\" rather than \"fail.\"\n */\nexport async function runSemanticConceptJudge(\n input: SemanticConceptJudgeInput,\n options: SemanticConceptJudgeOptions = {},\n): Promise<SemanticConceptJudgeResult> {\n const start = Date.now()\n const totalCount = input.expectedConcepts.length\n\n if (totalCount === 0) {\n return {\n kind: 'semantic-concept',\n version: SEMANTIC_CONCEPT_JUDGE_VERSION,\n score: 0,\n presentCount: 0,\n totalCount: 0,\n findings: [],\n summary: 'no expected concepts declared',\n durationMs: 0,\n costUsd: null,\n available: false,\n error: 'no expected concepts declared',\n }\n }\n\n const opts: Required<SemanticConceptJudgeOptions> = {\n model: options.model ?? DEFAULT_MODEL,\n timeoutMs: options.timeoutMs ?? DEFAULT_TIMEOUT,\n maxSourceChars: options.maxSourceChars ?? DEFAULT_MAX_SOURCE,\n maxPerFileChars: options.maxPerFileChars ?? DEFAULT_MAX_PER_FILE,\n maxHtmlChars: options.maxHtmlChars ?? DEFAULT_MAX_HTML,\n llm: options.llm ?? {},\n weightConcepts: options.weightConcepts ?? 'mean',\n complexityWeights: { ...DEFAULT_COMPLEXITY_WEIGHTS, ...(options.complexityWeights ?? {}) },\n }\n\n // Build a name → weight map for aggregation. Mean strategy keeps every\n // weight at 1 (uniform average). Complexity strategy reads the table\n // and lets an explicit `weight` override. Explicit strategy uses ONLY\n // the spec's `weight` (defaulting to 1).\n const weightForConcept = (spec: ConceptSpec): number => {\n if (opts.weightConcepts === 'mean') return 1\n if (spec.weight != null) return spec.weight\n if (opts.weightConcepts === 'complexity') {\n return opts.complexityWeights[spec.complexity ?? 'render'] ?? 1\n }\n return 1\n }\n const weightByName = new Map<string, number>(\n input.expectedConcepts.map((c) => [c.name, weightForConcept(c)]),\n )\n\n try {\n const { value, result } = await callLlmJson<{\n summary: string\n concepts: ConceptFinding[]\n }>(\n {\n model: opts.model,\n messages: [\n {\n role: 'system',\n content:\n 'You are a strict code-review judge. Return strict JSON only. No prose outside the JSON. A keyword in a comment is NOT a working implementation.',\n },\n { role: 'user', content: buildPrompt(input, opts) },\n ],\n jsonSchema: { name: 'semantic_concept_judge', schema: SEMANTIC_SCHEMA },\n temperature: 0,\n timeoutMs: opts.timeoutMs,\n },\n opts.llm,\n )\n\n if (!value?.concepts || !Array.isArray(value.concepts)) {\n throw new Error('judge returned malformed response — expected array under \"concepts\"')\n }\n\n const findings: ConceptFinding[] = value.concepts.map((c) => ({\n concept: String(c.concept),\n present: Boolean(c.present),\n score: Math.max(0, Math.min(10, Number(c.score ?? 0))),\n evidence: String(c.evidence ?? ''),\n severity: (['critical', 'major', 'minor', 'info'] as const).includes(c.severity)\n ? c.severity\n : 'info',\n }))\n\n const presentCount = findings.filter((f) => f.present && f.score >= 7).length\n let weightSum = 0\n let weightedScoreSum = 0\n for (const f of findings) {\n const w = weightByName.get(f.concept) ?? 1\n weightSum += w\n weightedScoreSum += w * f.score\n }\n const scoreAvg =\n weightSum > 0\n ? weightedScoreSum / weightSum\n : findings.reduce((a, f) => a + f.score, 0) / Math.max(1, findings.length)\n\n return {\n kind: 'semantic-concept',\n version: SEMANTIC_CONCEPT_JUDGE_VERSION,\n score: Number((scoreAvg / 10).toFixed(3)),\n presentCount,\n totalCount,\n findings,\n summary: String(value.summary ?? ''),\n durationMs: Date.now() - start,\n costUsd: result.costUsd ?? null,\n available: true,\n }\n } catch (err) {\n return {\n kind: 'semantic-concept',\n version: SEMANTIC_CONCEPT_JUDGE_VERSION,\n score: 0,\n presentCount: 0,\n totalCount,\n findings: [],\n summary: '',\n durationMs: Date.now() - start,\n costUsd: null,\n available: false,\n error: err instanceof Error ? err.message : String(err),\n }\n }\n}\n\n/**\n * Factory: pin LLM options once, return a closure that accepts inputs.\n * Convenient for pipelines that want to share a single LlmClient config.\n */\nexport function createSemanticConceptJudge(\n options: SemanticConceptJudgeOptions = {},\n): (input: SemanticConceptJudgeInput) => Promise<SemanticConceptJudgeResult> {\n return (input) => runSemanticConceptJudge(input, options)\n}\n","/**\n * Analyst contract — the missing orchestration layer over agent-eval's\n * existing analyzers (analyzeTraces, MultiLayerVerifier, RunCritic,\n * SemanticConceptJudge, JudgeFn, ...).\n *\n * Each existing primitive returns its own output shape. The Analyst\n * contract is the single envelope every primitive lifts into, so a\n * registry can run N analysts against a run and a single renderer can\n * compose findings without knowing which analyzer produced them.\n *\n * The contract is intentionally domain-agnostic: nothing here knows\n * about code, voice, RAG, or any particular agent stack. Analysts\n * declare what INPUT KIND they need (a trace store, an artifact dir,\n * a RunRecord, a JudgeInput, or `custom`), and the registry routes\n * the matching input from `AnalystRunInputs`.\n */\n\nimport { createHash } from 'node:crypto'\nimport type { RunRecord } from '../run-record'\nimport type { TraceAnalysisStore } from '../trace-analyst/store'\nimport type { JudgeInput } from '../types'\nimport type { ChatClient } from './chat-client'\n\n/**\n * Unified envelope every analyst emits. Schema-versioned so renderers\n * and time-series diffs survive future field additions.\n */\nexport interface AnalystFinding {\n schema_version: '1.0.0'\n /**\n * Stable hash over identity-defining fields (analyst_id + canonical\n * claim + area + optional subject). Two findings from two runs that\n * \"are the same finding\" share this id — that's what `diffFindings`\n * uses to compute appeared/disappeared sets across runs.\n */\n finding_id: string\n analyst_id: string\n produced_at: string\n severity: AnalystSeverity\n /**\n * Coarse classification. Renderers group by this. Free-form so\n * domain-specific analysts can introduce categories without a\n * schema change ('agent-reasoning', 'verification', 'cost',\n * 'tool-use', 'safety', 'latency', 'data-quality', ...).\n */\n area: string\n claim: string\n rationale?: string\n evidence_refs: EvidenceRef[]\n recommended_action?: string\n validation_plan?: string\n /** 0..1 — the analyst's own confidence. Not calibrated across analysts. */\n confidence: number\n /**\n * Optional subject the finding is about — leaf id, agent id, request\n * id. Included in finding_id when present so per-subject findings\n * diff cleanly across runs.\n */\n subject?: string\n /** Analyst-private extras; renderers ignore unless they know the analyst. */\n metadata?: Record<string, unknown>\n}\n\nexport type AnalystSeverity = 'critical' | 'high' | 'medium' | 'low' | 'info'\n\nexport interface EvidenceRef {\n /**\n * Where the evidence lives. `span` and `event` refer to OTLP trace\n * elements; `artifact` to a file inside the run's artifact tree;\n * `finding` to another AnalystFinding (cross-analyst chaining);\n * `metric` to a named scalar reading the renderer knows how to read.\n */\n kind: 'span' | 'event' | 'artifact' | 'finding' | 'metric'\n uri: string\n excerpt?: string\n}\n\n// ── Analyst contract ─────────────────────────────────────────────────\n\n/**\n * The discriminator the registry uses to pass the right input.\n * `custom` is the escape hatch — analysts that need something else\n * (e.g. an embedding cache, a partner SDK handle) read it from\n * `AnalystRunInputs.custom[<analyst id>]`.\n */\nexport type AnalystInputKind =\n | 'trace-store'\n | 'artifact-dir'\n | 'run-record'\n | 'judge-input'\n | 'custom'\n\nexport interface AnalystCost {\n /** `deterministic` analysts MUST NOT call the LLM. */\n kind: 'deterministic' | 'llm'\n /** Optional declared upper bound; the registry can enforce a budget. */\n est_usd_per_run?: number\n /** Models the analyst expects to use (informational). */\n models?: string[]\n}\n\nexport interface AnalystRequirements {\n /** Min number of shots / samples the analyst needs to produce signal. */\n min_shots?: number\n /** Capabilities the runtime must supply (e.g. ['network', 'gpu']). */\n capabilities?: string[]\n}\n\n/**\n * What's passed to every analyst call. The registry resolves which\n * field the analyst's `inputKind` selects and asserts it's present.\n */\nexport interface AnalystRunInputs {\n traceStore?: TraceAnalysisStore\n artifactDir?: string\n runRecord?: RunRecord\n judgeInput?: JudgeInput\n /** Keyed by analyst id; populated by callers that registered custom analysts. */\n custom?: Record<string, unknown>\n}\n\nexport interface AnalystContext {\n runId: string\n /** Stable correlation id so logs from a single registry.run() share a tag. */\n correlationId: string\n /** Wall-clock deadline (epoch ms). Analysts SHOULD honor for graceful cancel. */\n deadlineMs?: number\n /** Per-analyst USD budget. Analysts MAY check before issuing LLM calls. */\n budgetUsd?: number\n /**\n * Shared chat client. Analysts that call an LLM go through this so\n * the operator picks transport (sandbox-sdk | router | cli-bridge |\n * direct-provider | mock) at the registry boundary without touching\n * analyst code.\n */\n chat?: ChatClient\n /**\n * Findings from a prior run the operator wants the analyst to see as\n * retrieval context. Kinds that take advantage of cross-run memory\n * (failure-mode \"I saw this cluster last run\", knowledge-gap \"the wiki\n * page I asked for is still missing\") render these into the actor's\n * working set. Filtering is the operator's job: pass the slice that\n * matches the analyst's id, or pass everything and let the kind\n * filter. Empty / absent means no cross-run context.\n */\n priorFindings?: ReadonlyArray<AnalystFinding>\n /** Free-form runtime tags (env, host, op). Findings can echo these into metadata. */\n tags?: Record<string, string>\n /** Logger callback — analysts SHOULD prefer this over console.* for testability. */\n log?: (msg: string, fields?: Record<string, unknown>) => void\n /** Optional abort signal. Analysts SHOULD pass it through to LLM calls. */\n signal?: AbortSignal\n}\n\n/**\n * The minimal contract. Concrete analysts can refine `TInput` so\n * implementations stay type-safe (e.g. a trace analyst's `TInput` is\n * `TraceAnalysisStore`); the registry passes the right field from\n * `AnalystRunInputs` based on `inputKind`.\n */\nexport interface Analyst<TInput = unknown> {\n /** Stable identifier — appears in finding_id, telemetry, and registry exclusion lists. */\n readonly id: string\n /** Human-readable. One sentence. */\n readonly description: string\n readonly inputKind: AnalystInputKind\n readonly cost: AnalystCost\n readonly requires?: AnalystRequirements\n /** Bump on breaking changes to claim wording or area so old finding_ids don't collide. */\n readonly version: string\n analyze(input: TInput, ctx: AnalystContext): Promise<AnalystFinding[]>\n}\n\n// ── finding_id stability ─────────────────────────────────────────────\n\n/**\n * Compute the stable finding_id from the identity-defining fields.\n * Default implementation hashes {analyst_id, area, subject, normalized claim}.\n * Analysts that emit findings whose claim text varies per run (timestamps,\n * counts) SHOULD either: (a) pass an explicit `id_basis` to fix the hash,\n * or (b) move the variable part into `rationale`/`metadata` and keep the\n * `claim` static.\n */\nexport function computeFindingId(input: {\n analyst_id: string\n area: string\n subject?: string\n claim: string\n /** Override the claim for hashing — use when the displayed claim has run-specific bits. */\n id_basis?: string\n}): string {\n const basis = JSON.stringify({\n a: input.analyst_id,\n r: input.area,\n s: input.subject ?? '',\n c: normalizeClaim(input.id_basis ?? input.claim),\n })\n return `f_${createHash('sha256').update(basis).digest('hex').slice(0, 20)}`\n}\n\nfunction normalizeClaim(c: string): string {\n // Lowercase, collapse whitespace, strip trailing punctuation. Goal:\n // \"Leaf X failed install\" and \"Leaf X failed install.\" hash the same.\n return c\n .toLowerCase()\n .replace(/\\s+/g, ' ')\n .replace(/[.!?;:,]+$/g, '')\n .trim()\n}\n\n/**\n * Convenience factory: produce a fully-formed AnalystFinding with the\n * id computed automatically. Analyst code stays terse.\n */\nexport function makeFinding(\n init: Omit<AnalystFinding, 'schema_version' | 'finding_id' | 'produced_at'> & {\n id_basis?: string\n produced_at?: string\n },\n): AnalystFinding {\n const { id_basis, produced_at, ...rest } = init\n return {\n schema_version: '1.0.0',\n finding_id: computeFindingId({\n analyst_id: rest.analyst_id,\n area: rest.area,\n subject: rest.subject,\n claim: rest.claim,\n id_basis,\n }),\n produced_at: produced_at ?? new Date().toISOString(),\n ...rest,\n }\n}\n\n// ── Registry result envelope ────────────────────────────────────────\n\nexport interface AnalystRunSummary {\n analyst_id: string\n status: 'ok' | 'skipped' | 'failed'\n /** Why skipped — missing input, budget exceeded, capability unmet. */\n reason?: string\n findings_count: number\n latency_ms: number\n cost_usd: number\n /** When `status='failed'`: the error class + message, never the full stack. */\n error?: { class: string; message: string }\n}\n\nexport interface AnalystRunResult {\n run_id: string\n correlation_id: string\n started_at: string\n ended_at: string\n findings: AnalystFinding[]\n per_analyst: AnalystRunSummary[]\n /** Total LLM cost in USD across all analysts in this registry.run(). */\n total_cost_usd: number\n}\n\n// ── Streaming event envelope ────────────────────────────────────────\n\n/**\n * Events emitted by `AnalystRegistry.runStream(...)` in real time as\n * the registry executes. UIs subscribe via `for await (const ev of\n * registry.runStream(...))`; `registry.run(...)` is a thin collector\n * over the same stream, so the two surfaces share their invariants.\n *\n * Per-finding events are intentionally omitted — analyzers are batch\n * operations (an Ax actor returns the full `findings:json[]` at the\n * end of the responder), so streaming inside one analyst would only\n * emit partial JSON consumers can't render. The kind-completion event\n * is the right granularity; subscribers wanting per-finding rendering\n * iterate `event.findings` themselves.\n */\nexport type AnalystRunEvent =\n | {\n type: 'run-started'\n run_id: string\n correlation_id: string\n started_at: string\n /** The ordered list of analyst ids the registry will run. */\n analyst_ids: ReadonlyArray<string>\n }\n | {\n type: 'analyst-skipped'\n summary: AnalystRunSummary\n }\n | {\n type: 'analyst-started'\n analyst_id: string\n started_at: string\n }\n | {\n type: 'analyst-completed'\n /** `summary.status` is `'ok'` for clean completion or `'failed'` for thrown analysts. */\n summary: AnalystRunSummary\n findings: ReadonlyArray<AnalystFinding>\n }\n | {\n type: 'run-completed'\n result: AnalystRunResult\n }\n","/**\n * Adapter factories — lift each existing agent-eval primitive into the\n * Analyst contract without re-implementing it.\n *\n * Five primitives, five factories. Each one:\n * - Builds an Analyst with a stable id (caller chooses; defaults\n * given), a sensible default `inputKind`, a version derived from\n * the wrapped primitive's version + an adapter revision, and an\n * `analyze()` that calls the primitive and lifts its output to\n * AnalystFinding[] using `makeFinding()`.\n * - Maps severities: the existing `Severity` ('critical' | 'major' |\n * 'minor' | 'info') projects onto AnalystSeverity ('critical' |\n * 'high' | 'medium' | 'low' | 'info'); 'major' → 'high', 'minor' →\n * 'medium'. Domain analysts that want finer-grained mapping override.\n *\n * Adapters never own state. Calling the same factory twice with the\n * same primitive instance is safe.\n */\n\nimport type { AxAIService } from '@ax-llm/ax'\nimport type {\n Finding as LayerFinding,\n Severity as LayerSeverity,\n MultiLayerVerifier,\n VerifyOptions,\n} from '../multi-layer-verifier'\nimport { RunCritic, type RunTrace } from '../run-critic'\nimport {\n runSemanticConceptJudge,\n SEMANTIC_CONCEPT_JUDGE_VERSION,\n type SemanticConceptJudgeInput,\n type SemanticConceptJudgeOptions,\n} from '../semantic-concept-judge'\nimport { type AnalyzeTracesOptions, analyzeTraces } from '../trace-analyst/analyst'\nimport type { TraceAnalysisStore } from '../trace-analyst/store'\nimport type { JudgeFn, JudgeInput, JudgeScore, TCloud } from '../types'\nimport type { Analyst, AnalystFinding, AnalystSeverity } from './types'\nimport { makeFinding } from './types'\n\nconst ADAPTER_REV = '1'\n\n// ── Severity bridges ───────────────────────────────────────────────\n\nexport function liftSeverity(s: LayerSeverity): AnalystSeverity {\n switch (s) {\n case 'critical':\n return 'critical'\n case 'major':\n return 'high'\n case 'minor':\n return 'medium'\n case 'info':\n return 'info'\n }\n}\n\n// ── 1. analyzeTraces → Analyst ─────────────────────────────────────\n\nexport interface TraceAnalystAdapterOpts {\n id?: string\n area?: string\n /** The natural-language question(s) put to the analyst. One finding per question. */\n questions: string[]\n /** Caller-provided AxAI service — same one trace-analyst.ts expects. */\n ai: AxAIService\n model?: string\n /** Forwarded to analyzeTraces. */\n extra?: Omit<AnalyzeTracesOptions, 'source' | 'ai' | 'model'>\n}\n\n/**\n * @deprecated Prefer `createTraceAnalystKind` + one of the failure /\n * improvement kinds from `./kinds`. This adapter wraps the legacy\n * `analyzeTraces` flow whose output is `findings:string[]` — every\n * bullet gets flat-defaulted severity `medium` / confidence `0.6`,\n * which loses the per-finding grading kinds provide via Ax structured\n * output + Zod validation. Kept for one minor while consumers migrate.\n */\nexport function createTraceAnalystAdapter(\n opts: TraceAnalystAdapterOpts,\n): Analyst<TraceAnalysisStore> {\n const id = opts.id ?? 'trace-analyst'\n const area = opts.area ?? 'agent-reasoning'\n return {\n id,\n description:\n 'Runs the agent-eval trace analyst over an OTLP trace store and lifts its bulleted findings.',\n inputKind: 'trace-store',\n cost: { kind: 'llm', models: opts.model ? [opts.model] : undefined },\n version: `trace-analyst-${ADAPTER_REV}`,\n async analyze(store, ctx) {\n const out: AnalystFinding[] = []\n for (const question of opts.questions) {\n if (ctx.signal?.aborted) break\n const result = await analyzeTraces(\n { question },\n { source: store, ai: opts.ai, model: opts.model, ...opts.extra },\n )\n const subject = ctx.tags?.subject ?? question.slice(0, 60)\n // The responder produces a list of bullet strings. Each becomes\n // one finding; the prose answer is attached as rationale on the\n // first (so renderers that show only top-N still get context).\n if (result.findings.length === 0) {\n out.push(\n makeFinding({\n analyst_id: id,\n area,\n subject,\n claim: result.answer.slice(0, 200),\n rationale: result.answer,\n severity: 'info',\n confidence: 0.5,\n evidence_refs: [],\n metadata: {\n actor_prompt_version: result.actorPromptVersion,\n turns: result.turnCount,\n },\n }),\n )\n continue\n }\n result.findings.forEach((claim, i) => {\n out.push(\n makeFinding({\n analyst_id: id,\n area,\n subject,\n claim,\n rationale: i === 0 ? result.answer : undefined,\n severity: 'medium',\n confidence: 0.6,\n evidence_refs: [],\n metadata: { question, turns: result.turnCount, finding_index: i },\n }),\n )\n })\n }\n return out\n },\n }\n}\n\n// ── 2. MultiLayerVerifier → Analyst ─────────────────────────────────\n\nexport interface VerifierAdapterOpts<Env> {\n id?: string\n area?: string\n verifier: MultiLayerVerifier<Env>\n /**\n * The verifier expects an `env` per run. Adapters take it from\n * `AnalystRunInputs.custom[<id>]` via the registry's 'custom' routing.\n */\n options?: Omit<VerifyOptions<Env>, 'env'>\n}\n\nexport function createVerifierAdapter<Env>(opts: VerifierAdapterOpts<Env>): Analyst<Env> {\n const id = opts.id ?? 'multi-layer-verifier'\n const area = opts.area ?? 'verification'\n return {\n id,\n description:\n \"Runs a MultiLayerVerifier and lifts each layer's findings into the analyst envelope.\",\n inputKind: 'custom',\n cost: { kind: 'deterministic' },\n version: `verifier-${ADAPTER_REV}`,\n async analyze(env, ctx) {\n const report = await opts.verifier.run({ env, ...opts.options })\n const out: AnalystFinding[] = []\n for (const layer of report.layers) {\n for (const finding of layer.findings) {\n out.push(liftLayerFinding(id, area, layer.layer, finding))\n }\n // Layer-level signal: a failed/error layer is itself a finding\n // even if it didn't emit per-finding rows.\n if (layer.status === 'fail' || layer.status === 'error' || layer.status === 'timeout') {\n out.push(\n makeFinding({\n analyst_id: id,\n area,\n subject: layer.layer,\n claim: `layer \"${layer.layer}\" ${layer.status}: ${layer.reason ?? 'no reason given'}`,\n severity:\n layer.status === 'error' ? 'high' : layer.status === 'timeout' ? 'medium' : 'high',\n confidence: 1,\n evidence_refs: [],\n metadata: {\n layer_status: layer.status,\n duration_ms: layer.durationMs,\n score: layer.score,\n diagnostics: layer.diagnostics,\n },\n }),\n )\n }\n }\n ctx.log?.('verifier complete', {\n layers: report.layers.length,\n blended: report.blendedScore,\n all_pass: report.allPass,\n })\n return out\n },\n }\n}\n\nfunction liftLayerFinding(\n analyst_id: string,\n area: string,\n layer: string,\n f: LayerFinding,\n): AnalystFinding {\n return makeFinding({\n analyst_id,\n area,\n subject: f.layer ?? layer,\n claim: f.message,\n severity: liftSeverity(f.severity),\n confidence: 0.85,\n evidence_refs: f.evidence\n ? [{ kind: 'artifact', uri: 'inline:evidence', excerpt: f.evidence }]\n : [],\n metadata: f.detail,\n })\n}\n\n// ── 3. RunCritic → Analyst ──────────────────────────────────────────\n\nexport interface RunCriticAdapterOpts {\n id?: string\n area?: string\n critic?: RunCritic\n /** Optional threshold below which a dimension is reported as a finding. Default 0.5. */\n threshold?: number\n}\n\nexport function createRunCriticAdapter(opts: RunCriticAdapterOpts = {}): Analyst<RunTrace> {\n const id = opts.id ?? 'run-critic'\n const area = opts.area ?? 'run-quality'\n const critic = opts.critic ?? new RunCritic()\n const threshold = opts.threshold ?? 0.5\n return {\n id,\n description:\n 'Scores a single run across success / grounding / drift / tool-quality and surfaces below-threshold dimensions.',\n inputKind: 'custom',\n cost: { kind: 'deterministic' },\n version: `run-critic-${ADAPTER_REV}`,\n async analyze(trace) {\n const score = critic.scoreTrace(trace)\n const out: AnalystFinding[] = []\n const dims: Array<[keyof typeof score, AnalystSeverity, string]> = [\n ['success', 'critical', 'run did not complete successfully'],\n ['goalProgress', 'high', 'goal progress is low'],\n ['repoGroundedness', 'high', 'output is poorly grounded in the repository'],\n ['toolUseQuality', 'medium', 'tool use quality is low'],\n ['patchQuality', 'medium', 'no real patch/edit evidence'],\n ['testReality', 'high', 'no real test/build evidence'],\n ['finalGate', 'critical', 'final gate is blocking'],\n ]\n for (const [dim, sev, msg] of dims) {\n const value = score[dim] as number\n if (typeof value === 'number' && value < threshold) {\n out.push(\n makeFinding({\n analyst_id: id,\n area,\n subject: dim,\n claim: msg,\n rationale: `${dim}=${value.toFixed(2)} below threshold ${threshold}`,\n severity: sev,\n confidence: 1,\n evidence_refs: [],\n metadata: { dimension: dim, value, threshold, run_id: trace.run.runId },\n }),\n )\n }\n }\n // Drift penalty is high → surface as a finding (inverse threshold).\n if (score.driftPenalty > 1 - threshold) {\n out.push(\n makeFinding({\n analyst_id: id,\n area,\n subject: 'drift',\n claim: 'agent output drifted from repository signal',\n rationale: `driftPenalty=${score.driftPenalty.toFixed(2)}`,\n severity: 'medium',\n confidence: 0.9,\n evidence_refs: [],\n metadata: { drift_penalty: score.driftPenalty, notes: score.notes },\n }),\n )\n }\n return out\n },\n }\n}\n\n// ── 4. JudgeFn → Analyst ────────────────────────────────────────────\n\nexport interface JudgeAdapterOpts {\n id?: string\n area?: string\n judge: JudgeFn\n /** TCloud handle the JudgeFn calls. */\n tcloud: TCloud\n /** Optional cost classification — most judges call an LLM. */\n cost?: Analyst['cost']\n /** Optional threshold below which a JudgeScore becomes a finding. Default 6 (on 0-10 scale). */\n threshold?: number\n}\n\nexport function createJudgeAdapter(opts: JudgeAdapterOpts): Analyst<JudgeInput> {\n const id = opts.id ?? 'judge'\n const area = opts.area ?? 'judge'\n const threshold = opts.threshold ?? 6\n return {\n id,\n description:\n 'Wraps an agent-eval JudgeFn into an analyst; below-threshold dimensions surface as findings.',\n inputKind: 'judge-input',\n cost: opts.cost ?? { kind: 'llm' },\n version: `judge-${ADAPTER_REV}`,\n async analyze(input) {\n const scores = await opts.judge(opts.tcloud, input)\n return scores\n .filter((s) => normalize10(s.score) < threshold)\n .map((s) => liftJudgeScore(id, area, s))\n },\n }\n}\n\nfunction normalize10(s: number): number {\n // JudgeScore convention is 0-10 but some judges emit 0-1. Coerce to 0-10.\n return s <= 1 ? s * 10 : s\n}\n\nfunction liftJudgeScore(analyst_id: string, area: string, s: JudgeScore): AnalystFinding {\n const score10 = normalize10(s.score)\n const severity: AnalystSeverity =\n score10 < 3 ? 'critical' : score10 < 5 ? 'high' : score10 < 7 ? 'medium' : 'low'\n return makeFinding({\n analyst_id,\n area,\n subject: s.dimension,\n claim: `${s.judgeName}/${s.dimension} scored ${score10.toFixed(1)}/10`,\n rationale: s.reasoning,\n severity,\n confidence: 0.8,\n evidence_refs: s.evidence\n ? [{ kind: 'artifact', uri: 'inline:evidence', excerpt: s.evidence }]\n : [],\n metadata: { judge_name: s.judgeName, dimension: s.dimension, score_10: score10 },\n })\n}\n\n// ── 5. SemanticConceptJudge → Analyst ──────────────────────────────\n\nexport interface SemanticConceptJudgeAdapterOpts {\n id?: string\n area?: string\n options?: SemanticConceptJudgeOptions\n}\n\nexport function createSemanticConceptJudgeAdapter(\n opts: SemanticConceptJudgeAdapterOpts = {},\n): Analyst<SemanticConceptJudgeInput> {\n const id = opts.id ?? 'semantic-concept-judge'\n const area = opts.area ?? 'concept-coverage'\n return {\n id,\n description:\n 'Runs the semantic-concept judge and surfaces missing / weak concepts as findings.',\n inputKind: 'custom',\n cost: { kind: 'llm', models: opts.options?.model ? [opts.options.model] : undefined },\n version: `${SEMANTIC_CONCEPT_JUDGE_VERSION}-adapter-${ADAPTER_REV}`,\n async analyze(input) {\n const result = await runSemanticConceptJudge(input, opts.options)\n if (!result.available) {\n return [\n makeFinding({\n analyst_id: id,\n area,\n claim: 'semantic-concept judge unavailable',\n rationale: result.error,\n severity: 'info',\n confidence: 1,\n evidence_refs: [],\n metadata: { reason: result.error },\n }),\n ]\n }\n const out: AnalystFinding[] = []\n for (const f of result.findings) {\n // Only surface gaps: missing concepts or low scores. Concepts at\n // 7+/10 with present=true are not findings — they're successes.\n if (f.present && f.score >= 7) continue\n out.push(\n makeFinding({\n analyst_id: id,\n area,\n subject: f.concept,\n claim: f.present\n ? `concept \"${f.concept}\" is weak (${f.score}/10)`\n : `concept \"${f.concept}\" is missing`,\n rationale: f.evidence,\n severity: liftSeverity(f.severity),\n confidence: 0.85,\n evidence_refs: [{ kind: 'artifact', uri: 'inline:evidence', excerpt: f.evidence }],\n metadata: {\n concept: f.concept,\n present: f.present,\n score_10: f.score,\n cost_usd: result.costUsd ?? undefined,\n },\n }),\n )\n }\n return out\n },\n }\n}\n","/**\n * ChatClient — the single LLM abstraction analysts call.\n *\n * agent-eval already ships an `LlmClient` (OpenAI-compatible, retry,\n * graceful JSON-schema degrade) and judges that talk to `TCloud`. Two\n * mixed patterns force every analyst author to pick a transport, which\n * couples analyst code to runtime concerns (cli-bridge vs router vs\n * sandbox-sdk) it shouldn't know about.\n *\n * `ChatClient` is one interface every analyst takes via `AnalystContext.chat`.\n * The operator decides at the registry boundary which transport binds\n * to it. Analyst code stays transport-agnostic; swapping production\n * (sandbox-sdk) for local dev (cli-bridge) or tests (mock) is a one-\n * line factory call.\n *\n * Designed to coexist: existing `LlmClient` callers and existing\n * `TCloud`-based judges keep working untouched. New analyst code uses\n * `ChatClient`. When old call sites migrate, they pick up budgeting,\n * cancellation, and unified telemetry for free.\n */\n\nimport {\n type LlmCallRequest,\n type LlmCallResult,\n LlmClient,\n type LlmClientOptions,\n} from '../llm-client'\n\n/**\n * Unified chat interface. Mirrors LlmCallRequest/Result so the OpenAI-\n * compatible mental model stays. Two methods: a one-shot `chat()` and\n * an `streamChat()` for future agentic loops (not yet exposed).\n */\nexport interface ChatClient {\n /** Display name of the bound transport — included in telemetry. */\n readonly transport: ChatTransport\n /** Default model when caller omits — operators bind this per environment. */\n readonly defaultModel?: string\n\n chat(req: ChatRequest, opts?: ChatCallOpts): Promise<ChatResponse>\n}\n\nexport type ChatTransport =\n | 'router' // router.tangle.tools — production paid models\n | 'sandbox-sdk' // box.streamPrompt() — chat completion via sandbox SDK\n | 'cli-bridge' // local cli-bridge for dev / local-only runs\n | 'direct-provider' // direct OpenAI / Anthropic / etc. — bypass router\n | 'mock' // test-time injection\n\nexport interface ChatRequest extends Omit<LlmCallRequest, 'model'> {\n /** Optional — falls back to ChatClient.defaultModel. */\n model?: string\n}\n\nexport type ChatResponse = LlmCallResult\n\nexport interface ChatCallOpts {\n /** Cancel the in-flight request. */\n signal?: AbortSignal\n /** Hard USD ceiling for this single call (informational; the underlying transport may not enforce). */\n maxCostUsd?: number\n /** Correlation tag carried into request headers when the transport allows. */\n correlationId?: string\n}\n\n// ── Factory ─────────────────────────────────────────────────────────\n\nexport type CreateChatClientOpts =\n | RouterTransportOpts\n | CliBridgeTransportOpts\n | DirectProviderTransportOpts\n | SandboxSdkTransportOpts\n | MockTransportOpts\n\ninterface BaseTransportOpts {\n defaultModel?: string\n}\n\nexport interface RouterTransportOpts extends BaseTransportOpts {\n transport: 'router'\n baseUrl?: string\n apiKey: string\n}\n\nexport interface CliBridgeTransportOpts extends BaseTransportOpts {\n transport: 'cli-bridge'\n baseUrl?: string\n bearer?: string\n}\n\nexport interface DirectProviderTransportOpts extends BaseTransportOpts {\n transport: 'direct-provider'\n baseUrl: string\n apiKey: string\n}\n\n/**\n * Sandbox-SDK transport. Provided as a thin pass-through: the caller\n * supplies a callable that mimics LlmClient.chat() against an already-\n * configured Sandbox handle. We don't import the SDK here to keep\n * agent-eval dep-free of @tangle-network/sandbox.\n */\nexport interface SandboxSdkTransportOpts extends BaseTransportOpts {\n transport: 'sandbox-sdk'\n chat: (req: ChatRequest, opts?: ChatCallOpts) => Promise<ChatResponse>\n}\n\n/**\n * Mock transport for tests. The handler receives the request and returns\n * whatever the test wants. No retries, no JSON-schema degrade.\n */\nexport interface MockTransportOpts extends BaseTransportOpts {\n transport: 'mock'\n handler: (req: ChatRequest, opts?: ChatCallOpts) => Promise<ChatResponse>\n}\n\n/**\n * Build a ChatClient bound to a specific transport. The returned client\n * is safe to share across analysts in a single registry run.\n */\nexport function createChatClient(opts: CreateChatClientOpts): ChatClient {\n switch (opts.transport) {\n case 'router':\n return wrapLlmClient(\n opts.transport,\n opts.defaultModel,\n new LlmClient({\n baseUrl: opts.baseUrl ?? 'https://router.tangle.tools/v1',\n apiKey: opts.apiKey,\n } as LlmClientOptions),\n )\n case 'cli-bridge':\n return wrapLlmClient(\n opts.transport,\n opts.defaultModel,\n new LlmClient({\n baseUrl: opts.baseUrl ?? 'http://127.0.0.1:3344/v1',\n apiKey: opts.bearer ?? '',\n } as LlmClientOptions),\n )\n case 'direct-provider':\n return wrapLlmClient(\n opts.transport,\n opts.defaultModel,\n new LlmClient({\n baseUrl: opts.baseUrl,\n apiKey: opts.apiKey,\n } as LlmClientOptions),\n )\n case 'sandbox-sdk':\n return {\n transport: 'sandbox-sdk',\n defaultModel: opts.defaultModel,\n chat: async (req, callOpts) => opts.chat(resolveModel(req, opts.defaultModel), callOpts),\n }\n case 'mock':\n return {\n transport: 'mock',\n defaultModel: opts.defaultModel,\n chat: async (req, callOpts) => opts.handler(resolveModel(req, opts.defaultModel), callOpts),\n }\n }\n}\n\nfunction wrapLlmClient(\n transport: ChatTransport,\n defaultModel: string | undefined,\n inner: LlmClient,\n): ChatClient {\n return {\n transport,\n defaultModel,\n chat: async (req, callOpts) => {\n const resolved = resolveModel(req, defaultModel)\n // LlmClient.call doesn't accept an external AbortSignal today (it\n // owns its own AbortController for the per-attempt timeout). We\n // race the response against the caller's signal so awaiting code\n // unblocks on abort. The in-flight HTTP request still runs to its\n // own timeoutMs — when LlmClient grows a signal parameter, wire\n // it directly here and drop the race.\n const call = inner.call({\n model: resolved.model!,\n messages: req.messages,\n jsonMode: req.jsonMode,\n jsonSchema: req.jsonSchema,\n temperature: req.temperature,\n maxTokens: req.maxTokens,\n timeoutMs: req.timeoutMs,\n })\n if (!callOpts?.signal) return await call\n return await Promise.race([call, abortAsRejection(callOpts.signal)])\n },\n }\n}\n\nfunction abortAsRejection(signal: AbortSignal): Promise<never> {\n if (signal.aborted) return Promise.reject(toAbortError(signal))\n return new Promise<never>((_, reject) => {\n signal.addEventListener('abort', () => reject(toAbortError(signal)), { once: true })\n })\n}\n\nfunction toAbortError(signal: AbortSignal): Error {\n const reason = (signal as { reason?: unknown }).reason\n if (reason instanceof Error) return reason\n const e = new Error('ChatClient.chat: aborted')\n e.name = 'AbortError'\n return e\n}\n\nfunction resolveModel(req: ChatRequest, defaultModel: string | undefined): ChatRequest {\n if (req.model) return req\n if (!defaultModel) {\n throw new Error(\n 'ChatClient.chat: no model on request and no defaultModel on the client. ' +\n 'Either pass req.model or bind defaultModel at createChatClient().',\n )\n }\n return { ...req, model: defaultModel }\n}\n","/**\n * Typed Ax output for analyst findings.\n *\n * Replaces the legacy `findings:string[]` pattern (where every bullet\n * became a flat-severity `AnalystFinding`) with a structured object\n * array. Ax binds the field as `findings:json[]` so the provider emits\n * native structured output; at the kind-factory boundary we Zod-validate\n * each emitted finding so malformed rows fail loud instead of being\n * silently lifted with default severity.\n *\n * Why not `f.object().array()` directly in the signature? The Ax\n * signature string `question:string -> findings:json[]` already lets\n * the provider emit JSON arrays. A Zod boundary is required either\n * way (the provider can return any JSON), and Zod gives us a single\n * validation surface independent of which Ax version is installed.\n */\n\nimport { z } from 'zod'\nimport { parseFindingSubject } from './finding-subject'\n\nexport const ANALYST_SEVERITIES = ['critical', 'high', 'medium', 'low', 'info'] as const\n\nexport const RawAnalystFindingSchema = z\n .object({\n severity: z.enum(ANALYST_SEVERITIES),\n claim: z.string().min(1).max(2000),\n /**\n * Subject locus the finding is about. Validated at parse time\n * against the documented grammar (`finding-subject.ts`). Findings\n * with a malformed subject are rejected — they would have been\n * silently skipped by every downstream adapter, so failing loud at\n * parse time turns a hidden no-op into a kind-prompt audit signal.\n *\n * Optional because purely descriptive findings (no actionable\n * locus) are legitimate; they just don't route through the\n * KnowledgeAdapter / ImprovementAdapter.\n */\n subject: z\n .string()\n .max(400)\n .refine((s) => parseFindingSubject(s) !== null, {\n message: 'subject does not match the finding-subject grammar',\n })\n .optional(),\n evidence_uri: z.string().min(1).max(2000),\n evidence_excerpt: z.string().max(2000).optional(),\n confidence: z.number().min(0).max(1),\n rationale: z.string().max(4000).optional(),\n recommended_action: z.string().max(2000).optional(),\n })\n .strict()\n\nexport type RawAnalystFinding = z.infer<typeof RawAnalystFindingSchema>\n\n/**\n * Description embedded into the actor prompt so the LLM knows what\n * shape to emit. Kept here so kinds share one source of truth rather\n * than restating the schema in every prompt.\n */\nexport const RAW_FINDING_SCHEMA_PROMPT = `Each finding MUST be a JSON object with these fields:\n - severity: one of \"critical\" | \"high\" | \"medium\" | \"low\" | \"info\"\n - claim: one-sentence statement (max 2000 chars)\n - subject?: the leaf id, agent id, span id, tool name, or noun phrase the finding is about\n - evidence_uri: \"span://<trace_id>/<span_id>\" for trace evidence, \"artifact://<relative-path>\" for files, \"metric://<name>\" for named scalars — ALWAYS cite a real id surfaced by the tools\n - evidence_excerpt?: short quote (<=2000 chars) from the cited span/artifact\n - confidence: number 0..1 — 0.9+ when backed by exact quotes, 0.6-0.8 for inferred patterns, <0.5 for speculative\n - rationale?: one or two sentences explaining the reasoning\n - recommended_action?: concrete change phrased as an imperative (\"Add ...\", \"Replace ...\", \"Stop ...\") — omit when the finding is purely descriptive\n\nEmit an empty array when the question has no findings to report. Do not fabricate evidence.`\n\n/**\n * Validate one row emitted by the LLM. Returns the typed finding on\n * success; returns `null` and logs the reason on failure so the kind\n * factory can skip-and-count rather than abort the whole analyst run.\n */\nexport function parseRawFinding(\n row: unknown,\n log?: (msg: string, fields?: Record<string, unknown>) => void,\n): RawAnalystFinding | null {\n const result = RawAnalystFindingSchema.safeParse(row)\n if (!result.success) {\n log?.('finding rejected: schema failure', {\n issues: result.error.issues.map((i) => ({\n path: i.path.join('.'),\n code: i.code,\n message: i.message,\n })),\n })\n return null\n }\n return result.data\n}\n","/**\n * Typed `FindingSubject` — the canonical grammar every analyst kind emits.\n *\n * Background: kind actor prompts have always documented a subject grammar\n * (e.g. `system-prompt:<section>`, `agent-knowledge:wiki:<slug>`) but the\n * LLM was unconstrained — it could emit `subject: \"fix the prompt\"`\n * (prose) and downstream adapters routed on `startsWith(...)` would\n * silently skip it. Every per-vertical `ImprovementAdapter` had a\n * routing table that mostly caught nothing.\n *\n * This module fixes that:\n * - `parseFindingSubject(raw)` — returns the typed `FindingSubject`\n * when `raw` matches the grammar, else `null`. Used at the\n * `RawAnalystFindingSchema` boundary so malformed subjects are\n * rejected loudly instead of silently lifted into the registry.\n * - `FindingSubjectKind` — the union of valid locus categories. Each\n * variant carries the typed components downstream adapters resolve\n * against the agent's surface manifest (no string parsing in the\n * adapter).\n * - `FINDING_SUBJECT_GRAMMAR_PROMPT` — single source of truth for the\n * grammar string embedded in kind actor prompts. Drift between\n * prompt and parser is impossible if every kind imports this.\n *\n * The grammar is intentionally NARROW — only loci the substrate's\n * default `ImprovementAdapter` / `KnowledgeAdapter` can act on. A\n * finding with a subject outside this set fails the parser; the kind\n * author either extends the grammar here (and adds adapter routing)\n * or rephrases the prompt to map onto an existing variant.\n *\n * `failure-mode` is the one exception — its subjects are free-form\n * cluster labels, not loci. The schema preserves them as\n * `{ kind: 'cluster', label }` and the adapters skip them (cluster\n * findings are evidence, not actionable mutations).\n */\n\nimport { z } from 'zod'\n\n// ── canonical grammar ─────────────────────────────────────────────────\n\n/**\n * Discriminated union of every locus the substrate can route findings to.\n *\n * Adapters narrow on `kind` and use the typed components (no string\n * parsing). Adding a variant here REQUIRES updating the parser, the\n * grammar prompt, and at least one adapter — by design.\n */\nexport type FindingSubject =\n // ── agent-knowledge:* — routed to the KnowledgeAdapter ──\n | { kind: 'knowledge.wiki'; slug: string; heading?: string }\n | { kind: 'knowledge.claim'; topic: string }\n | { kind: 'knowledge.raw'; sourceId: string }\n | { kind: 'knowledge.stale'; slug: string }\n // ── system-prompt / tool / new-tool / rag / memory / scaffolding / output-schema ──\n // routed to the ImprovementAdapter\n | { kind: 'system-prompt'; section: string }\n | { kind: 'tool-doc'; tool: string; aspect?: string }\n | { kind: 'new-tool'; name: string }\n | { kind: 'rag'; corpus: string; docId: string }\n | { kind: 'memory'; key: string }\n | { kind: 'scaffolding'; concern: string }\n | { kind: 'output-schema'; field: string }\n // ── websearch / prior-run-summary — routed to the KnowledgeAdapter as stale signals\n | { kind: 'websearch.outdated'; topic: string }\n | { kind: 'prior-run-summary'; topic: string }\n // ── failure-mode cluster label — preserved verbatim, not routed\n | { kind: 'cluster'; label: string }\n\nexport type FindingSubjectKind = FindingSubject['kind']\n\nexport const FINDING_SUBJECT_KINDS: ReadonlyArray<FindingSubjectKind> = [\n 'knowledge.wiki',\n 'knowledge.claim',\n 'knowledge.raw',\n 'knowledge.stale',\n 'system-prompt',\n 'tool-doc',\n 'new-tool',\n 'rag',\n 'memory',\n 'scaffolding',\n 'output-schema',\n 'websearch.outdated',\n 'prior-run-summary',\n 'cluster',\n]\n\n// ── parser ────────────────────────────────────────────────────────────\n\n/**\n * Parse a raw subject string emitted by an analyst kind's actor.\n *\n * Returns the typed `FindingSubject` when `raw` matches the grammar,\n * else `null`. Callers use the `null` return as a signal to either\n * (a) reject the finding at parse time (kinds that emit typed loci —\n * knowledge-gap, improvement, knowledge-poisoning) or (b) lift it as\n * a cluster label (failure-mode).\n *\n * Slugs are constrained to `[a-z0-9-]+` (lowercase kebab) to keep file\n * paths sane downstream. Topics / keys / sections allow any non-empty\n * string (free-form for the LLM's voice) but get trimmed.\n *\n * Empty / whitespace-only inputs return `null`. `undefined` returns\n * `null`. Both are surfaced by the caller as a rejected subject.\n */\nexport function parseFindingSubject(raw: string | null | undefined): FindingSubject | null {\n if (raw === null || raw === undefined) return null\n const trimmed = raw.trim()\n if (trimmed.length === 0) return null\n\n // agent-knowledge:wiki:<slug>[#<heading>]\n const wiki = trimmed.match(\n /^agent-knowledge:wiki:([a-z0-9][a-z0-9-]*)(?:#([a-z0-9][a-z0-9-]*))?$/,\n )\n if (wiki)\n return { kind: 'knowledge.wiki', slug: wiki[1]!, ...(wiki[2] ? { heading: wiki[2] } : {}) }\n\n // agent-knowledge:claim:<topic>\n const claim = trimmed.match(/^agent-knowledge:claim:(.+)$/)\n if (claim && claim[1]!.trim().length > 0)\n return { kind: 'knowledge.claim', topic: claim[1]!.trim() }\n\n // agent-knowledge:raw:<source-id>\n const raw_ = trimmed.match(/^agent-knowledge:raw:(.+)$/)\n if (raw_ && raw_[1]!.trim().length > 0)\n return { kind: 'knowledge.raw', sourceId: raw_[1]!.trim() }\n\n // agent-knowledge:stale:<slug>\n const stale = trimmed.match(/^agent-knowledge:stale:([a-z0-9][a-z0-9-]*)$/)\n if (stale) return { kind: 'knowledge.stale', slug: stale[1]! }\n\n // system-prompt:<section>\n const sp = trimmed.match(/^system-prompt:(.+)$/)\n if (sp && sp[1]!.trim().length > 0) return { kind: 'system-prompt', section: sp[1]!.trim() }\n\n // tool-doc:<tool>[:<aspect>]\n const tdAspect = trimmed.match(/^tool-doc:([a-z0-9][a-z0-9_-]*):(.+)$/)\n if (tdAspect && tdAspect[2]!.trim().length > 0) {\n return { kind: 'tool-doc', tool: tdAspect[1]!, aspect: tdAspect[2]!.trim() }\n }\n const td = trimmed.match(/^tool-doc:([a-z0-9][a-z0-9_-]*)$/)\n if (td) return { kind: 'tool-doc', tool: td[1]! }\n\n // new-tool:<name>\n const nt = trimmed.match(/^new-tool:([a-z0-9][a-z0-9_-]*)$/)\n if (nt) return { kind: 'new-tool', name: nt[1]! }\n\n // rag:<corpus>:<doc-id>\n const rag = trimmed.match(/^rag:([a-z0-9][a-z0-9_-]*):(.+)$/)\n if (rag && rag[2]!.trim().length > 0) {\n return { kind: 'rag', corpus: rag[1]!, docId: rag[2]!.trim() }\n }\n\n // memory:<key>\n const mem = trimmed.match(/^memory:(.+)$/)\n if (mem && mem[1]!.trim().length > 0) return { kind: 'memory', key: mem[1]!.trim() }\n\n // scaffolding:<concern>\n const sc = trimmed.match(/^scaffolding:(.+)$/)\n if (sc && sc[1]!.trim().length > 0) return { kind: 'scaffolding', concern: sc[1]!.trim() }\n\n // output-schema:<field>\n const os = trimmed.match(/^output-schema:(.+)$/)\n if (os && os[1]!.trim().length > 0) return { kind: 'output-schema', field: os[1]!.trim() }\n\n // websearch:outdated:<topic>\n const ws = trimmed.match(/^websearch:outdated:(.+)$/)\n if (ws && ws[1]!.trim().length > 0) return { kind: 'websearch.outdated', topic: ws[1]!.trim() }\n\n // prior-run-summary:<topic>\n const prs = trimmed.match(/^prior-run-summary:(.+)$/)\n if (prs && prs[1]!.trim().length > 0) return { kind: 'prior-run-summary', topic: prs[1]!.trim() }\n\n // cluster (no prefix — failure-mode emits short labels)\n if (/^[a-z0-9][a-z0-9-]*$/.test(trimmed) && trimmed.length <= 80) {\n return { kind: 'cluster', label: trimmed }\n }\n\n return null\n}\n\n/**\n * Render the parsed subject back to its canonical string form. Inverse\n * of `parseFindingSubject`; useful when the substrate constructs new\n * findings programmatically (e.g. for tests, replays, or\n * `id_basis` carry-forward).\n */\nexport function renderFindingSubject(s: FindingSubject): string {\n switch (s.kind) {\n case 'knowledge.wiki':\n return s.heading\n ? `agent-knowledge:wiki:${s.slug}#${s.heading}`\n : `agent-knowledge:wiki:${s.slug}`\n case 'knowledge.claim':\n return `agent-knowledge:claim:${s.topic}`\n case 'knowledge.raw':\n return `agent-knowledge:raw:${s.sourceId}`\n case 'knowledge.stale':\n return `agent-knowledge:stale:${s.slug}`\n case 'system-prompt':\n return `system-prompt:${s.section}`\n case 'tool-doc':\n return s.aspect ? `tool-doc:${s.tool}:${s.aspect}` : `tool-doc:${s.tool}`\n case 'new-tool':\n return `new-tool:${s.name}`\n case 'rag':\n return `rag:${s.corpus}:${s.docId}`\n case 'memory':\n return `memory:${s.key}`\n case 'scaffolding':\n return `scaffolding:${s.concern}`\n case 'output-schema':\n return `output-schema:${s.field}`\n case 'websearch.outdated':\n return `websearch:outdated:${s.topic}`\n case 'prior-run-summary':\n return `prior-run-summary:${s.topic}`\n case 'cluster':\n return s.label\n }\n}\n\n// ── grammar prompt — single source of truth for actor instructions ──\n\n/**\n * The grammar text embedded into kind actor prompts. Kinds opt into\n * the subset of variants they emit (e.g. `improvement` excludes the\n * cluster variant; `failure-mode` includes ONLY the cluster variant).\n *\n * Drift between prompt and parser is impossible: every kind imports\n * this constant + the matching `expects` set, and the unit tests below\n * lock the table to the parser.\n */\nexport const FINDING_SUBJECT_GRAMMAR_PROMPT = [\n 'Subjects MUST match this grammar — anything else is rejected at parse time and your work is wasted:',\n '',\n ' Knowledge loci (write to the agent-knowledge base):',\n ' agent-knowledge:wiki:<slug>[#<heading>] create / update a wiki page',\n ' agent-knowledge:claim:<topic> draft a claim / relation triple',\n ' agent-knowledge:raw:<source-id> lift a raw source into a curated page',\n ' agent-knowledge:stale:<slug> mark a page superseded',\n '',\n ' Runtime mutable surfaces (write to prompts / tools / scaffolding):',\n ' system-prompt:<section> add / replace a system-prompt section',\n ' tool-doc:<tool>[:<aspect>] rewrite a tool description',\n ' new-tool:<name> propose a new tool surface',\n ' rag:<corpus>:<doc-id> ingest / correct a RAG document',\n ' memory:<key> invalidate / set a memory entry',\n ' scaffolding:<concern> change a precondition / retry / verifier',\n ' output-schema:<field> constrain the agent output shape',\n '',\n ' Stale signals (knowledge-poisoning only):',\n ' websearch:outdated:<topic> stale web result',\n ' prior-run-summary:<topic> stale prior-run summary',\n '',\n ' Cluster label (failure-mode only):',\n ' <kebab-case-label> short cluster id, e.g. \"tool-call-loop\"',\n '',\n 'Slugs / tool ids: [a-z0-9-]+ (lowercase kebab). Topics / keys / sections: free-form, trimmed.',\n].join('\\n')\n\n// ── kind expects sets ─────────────────────────────────────────────────\n\n/**\n * The variants each kind is allowed to emit. Used at the kind factory\n * boundary so a knowledge-gap finding can't sneak in a `system-prompt:*`\n * subject (the improvement-analyst's job) and vice versa.\n *\n * `failure-mode` is restricted to `cluster` — the only kind that emits\n * a non-locus subject.\n */\nexport const KIND_EXPECTED_SUBJECTS: Record<string, ReadonlyArray<FindingSubjectKind>> = {\n 'failure-mode': ['cluster'],\n 'knowledge-gap': [\n 'knowledge.wiki',\n 'knowledge.claim',\n 'knowledge.raw',\n 'knowledge.stale',\n 'tool-doc',\n 'system-prompt',\n 'memory',\n 'websearch.outdated',\n 'prior-run-summary',\n ],\n 'knowledge-poisoning': [\n 'knowledge.wiki',\n 'knowledge.claim',\n 'knowledge.raw',\n 'tool-doc',\n 'system-prompt',\n 'memory',\n 'websearch.outdated',\n 'prior-run-summary',\n ],\n improvement: [\n 'system-prompt',\n 'tool-doc',\n 'new-tool',\n 'rag',\n 'memory',\n 'scaffolding',\n 'output-schema',\n 'knowledge.wiki',\n 'knowledge.claim',\n ],\n}\n\n// ── Zod schema for boundary validation ───────────────────────────────\n\n/**\n * Zod schema that validates a raw subject string and returns the parsed\n * `FindingSubject`. Embedded in `RawAnalystFindingSchema` via\n * `transform`, so `subject` arrives at the kind factory either as a\n * typed locus or as a parse error attached to a single Zod issue.\n *\n * Optionality is preserved: subjects ARE optional on the wire (some\n * findings are descriptive, not actionable). When present, they MUST\n * parse — emitting a malformed subject is a contract violation, not a\n * soft signal.\n */\nexport const FindingSubjectStringSchema = z\n .string()\n .refine((s) => parseFindingSubject(s) !== null, {\n message: 'subject does not match the finding-subject grammar',\n })\n","/**\n * FindingsStore — durable persistence for AnalystFinding rows + a diff\n * helper so we can answer \"what changed since the last run?\" without\n * recomputing analysts.\n *\n * On-disk shape is JSONL: one finding per line, append-only, locked via\n * LockedJsonlAppender. Operators get crash-safety (no partial JSON),\n * cheap reads (sequential parse), and trivial backup (rsync the file).\n *\n * Reads are non-locking: a reader sees a consistent snapshot of all\n * fully-written lines and skips an incomplete trailing line if the\n * writer is mid-append. Cross-process locking is intentionally out of\n * scope (see locked-jsonl-appender.ts).\n *\n * The store is run-scoped: callers pass `runId` on append and on load,\n * which keeps multi-run files cleanly partitioned. The `diffFindings`\n * helper compares two run-id sets using stable `finding_id` semantics —\n * the diff is the cross-run signal the regression dashboard renders.\n */\n\nimport { existsSync, readFileSync } from 'node:fs'\n\nimport { LockedJsonlAppender } from '../locked-jsonl-appender'\nimport type { AnalystFinding } from './types'\n\n/**\n * One persisted row. We attach `run_id` on disk so a single file can\n * hold multiple runs and the diff helper can query without re-walking\n * separate files.\n */\nexport interface PersistedFinding extends AnalystFinding {\n run_id: string\n}\n\nexport class FindingsStore {\n private readonly appender: LockedJsonlAppender\n\n constructor(public readonly path: string) {\n this.appender = new LockedJsonlAppender(path)\n }\n\n async append(runId: string, findings: AnalystFinding[]): Promise<void> {\n for (const f of findings) {\n const row: PersistedFinding = { ...f, run_id: runId }\n await this.appender.append(row)\n }\n }\n\n /** Load every persisted finding. Discards malformed trailing lines silently. */\n loadAll(): PersistedFinding[] {\n if (!existsSync(this.path)) return []\n const raw = readFileSync(this.path, 'utf8')\n if (!raw) return []\n const out: PersistedFinding[] = []\n for (const line of raw.split('\\n')) {\n if (!line) continue\n try {\n out.push(JSON.parse(line) as PersistedFinding)\n } catch {\n // Skip torn trailing line — the lock guarantees no torn lines\n // mid-file, only at EOF when a writer is in-flight.\n }\n }\n return out\n }\n\n /** Filter to a single run. */\n loadRun(runId: string): PersistedFinding[] {\n return this.loadAll().filter((r) => r.run_id === runId)\n }\n}\n\n// ── Cross-run diff ──────────────────────────────────────────────────\n\nexport interface FindingsDiff {\n /** New finding ids in `current` that weren't in `previous`. */\n appeared: PersistedFinding[]\n /** Finding ids in `previous` that aren't in `current`. */\n disappeared: PersistedFinding[]\n /** Same finding id present in both runs and unchanged per the materiality test. */\n persisted: PersistedFinding[]\n /**\n * Same finding id in both runs but at least one non-identity field\n * shifted per `DiffPolicy.isMaterial`. Reported as [previous, current].\n */\n changed: Array<{ previous: PersistedFinding; current: PersistedFinding }>\n}\n\nexport interface DiffPolicy {\n /**\n * Predicate that decides whether two findings (same finding_id) count\n * as a material change. Defaults to {@link defaultIsMaterial}: severity\n * shift, confidence Δ > 0.05, or evidence count change. Compliance /\n * perf consumers MAY supply a stricter predicate (e.g. rationale text\n * diff, metric Δ thresholds).\n */\n isMaterial?: (previous: AnalystFinding, current: AnalystFinding) => boolean\n}\n\n/**\n * Default materiality test. Deliberately narrow so LLM-reword churn\n * doesn't flood the diff. Stricter tests are opt-in via DiffPolicy.\n */\nexport function defaultIsMaterial(a: AnalystFinding, b: AnalystFinding): boolean {\n if (a.severity !== b.severity) return true\n if (Math.abs((a.confidence ?? 0) - (b.confidence ?? 0)) > 0.05) return true\n if (a.evidence_refs.length !== b.evidence_refs.length) return true\n return false\n}\n\n/**\n * Diff two findings sets by stable finding_id. Callers typically load\n * the two run-id slices from the same store and pass them in.\n */\nexport function diffFindings(\n previous: PersistedFinding[],\n current: PersistedFinding[],\n policy: DiffPolicy = {},\n): FindingsDiff {\n const isMaterial = policy.isMaterial ?? defaultIsMaterial\n const prevById = new Map(previous.map((f) => [f.finding_id, f]))\n const curById = new Map(current.map((f) => [f.finding_id, f]))\n\n const appeared: PersistedFinding[] = []\n const disappeared: PersistedFinding[] = []\n const persisted: PersistedFinding[] = []\n const changed: FindingsDiff['changed'] = []\n\n for (const [id, cur] of curById) {\n const prev = prevById.get(id)\n if (!prev) {\n appeared.push(cur)\n continue\n }\n if (isMaterial(prev, cur)) {\n changed.push({ previous: prev, current: cur })\n } else {\n persisted.push(cur)\n }\n }\n for (const [id, prev] of prevById) {\n if (!curById.has(id)) disappeared.push(prev)\n }\n return { appeared, disappeared, persisted, changed }\n}\n","/**\n * LockedJsonlAppender — mutex-serialized JSONL append helper for arbitrary\n * payloads. The reference-replay store does the same thing for typed\n * `ReferenceReplayRun` rows; this is the generic version used by\n * `MutationTelemetry`, `TrialTelemetry`, and any other consumer that wants\n * append-only durable telemetry without rolling its own lock.\n *\n * Locks are per absolute file path (process-local). Cross-process\n * concurrency is NOT addressed — that's an fcntl/flock problem.\n */\n\nimport { appendFileSync, existsSync, mkdirSync } from 'node:fs'\nimport { dirname } from 'node:path'\nimport { Mutex } from './concurrency'\n\nconst mutexes = new Map<string, Mutex>()\n\nfunction getMutex(path: string): Mutex {\n let m = mutexes.get(path)\n if (!m) {\n m = new Mutex()\n mutexes.set(path, m)\n }\n return m\n}\n\nexport class LockedJsonlAppender {\n private readonly mutex: Mutex\n constructor(public readonly path: string) {\n this.mutex = getMutex(path)\n if (!existsSync(dirname(path))) {\n mkdirSync(dirname(path), { recursive: true })\n }\n }\n\n async append(entry: unknown): Promise<void> {\n const line = `${JSON.stringify(entry)}\\n`\n await this.mutex.runExclusive(() => {\n appendFileSync(this.path, line)\n })\n }\n}\n\n/** Reset all internal mutex state — tests only. */\nexport function resetLockedAppendersForTesting(): void {\n mutexes.clear()\n}\n","/**\n * concurrency — small primitives the evolution loop needs.\n *\n * `Mutex` is a zero-dep async lock with FIFO fairness. The evolution loop\n * uses it to serialise checkout/build/commit sequences inside a single\n * pool slot, and to gate concurrent JSONL writers (see\n * `lockedJsonlReferenceReplayStore`).\n *\n * Deliberately minimal — no priority queue, no timeouts. If you need\n * those, swap to `async-mutex` at the call site.\n */\n\nexport class Mutex {\n private locked = false\n private readonly waiters: Array<() => void> = []\n\n async acquire(): Promise<() => void> {\n if (!this.locked) {\n this.locked = true\n return () => this.release()\n }\n return new Promise<() => void>((resolve) => {\n this.waiters.push(() => {\n resolve(() => this.release())\n })\n })\n }\n\n private release(): void {\n const next = this.waiters.shift()\n if (next) {\n next()\n } else {\n this.locked = false\n }\n }\n\n async runExclusive<T>(fn: () => Promise<T> | T): Promise<T> {\n const release = await this.acquire()\n try {\n return await fn()\n } finally {\n release()\n }\n }\n\n /** True iff someone holds the lock right now. Diagnostics only. */\n get isLocked(): boolean {\n return this.locked\n }\n\n /** Pending waiter count. Diagnostics only. */\n get pending(): number {\n return this.waiters.length\n }\n}\n","/**\n * Analyst-kind factory — the typed, focused replacement for the\n * legacy `createTraceAnalystAdapter`.\n *\n * A \"kind\" is a specialized analyst whose actor prompt, tool subset,\n * and Ax recursion config target one failure-mode lens (failure-mode\n * classification, knowledge gap discovery, knowledge poisoning, recursive\n * self-improvement, ...). Kinds emit findings in the typed `RawAnalystFinding`\n * shape via a JSON-array Ax output; the factory validates each row with\n * Zod and lifts it into `AnalystFinding[]` with no shape guessing.\n *\n * Composition rules:\n * - Each kind owns its actor description. No generic \"answer this\n * question\" prompt — the prompt names the failure lens.\n * - Each kind picks a narrow tool subset from `ANALYST_TOOL_GROUPS`.\n * A kind that never needs full-trace dumps can drop `viewTrace` /\n * `viewSpans` and stay cheap.\n * - Each kind declares its recursion + parallelism budget. Discovery-\n * heavy kinds (failure-mode) get higher `maxDepth`; lens kinds\n * (poisoning) usually stay at 0 since they have a tighter brief.\n *\n * Optimizer hook: kinds may declare `goldens` — labeled examples used\n * by `AxMiPRO` / `AxBootstrapFewShot` / `AxGEPA` to fit the actor\n * description programmatically. Stored on the kind, not the registry,\n * because the right metric is kind-specific.\n */\n\nimport type { AxAIService, AxFunction } from '@ax-llm/ax'\nimport { AxJSRuntime, agent } from '@ax-llm/ax'\nimport type { TraceAnalysisStore } from '../trace-analyst/store'\nimport { TraceFileMissingError } from '../trace-analyst/store-otlp'\nimport {\n parseRawFinding,\n RAW_FINDING_SCHEMA_PROMPT,\n type RawAnalystFinding,\n} from './finding-signature'\nimport { KIND_EXPECTED_SUBJECTS, parseFindingSubject } from './finding-subject'\nimport type { Analyst, AnalystContext, AnalystCost, AnalystFinding } from './types'\nimport { makeFinding } from './types'\n\n/**\n * Per-kind specification. The factory turns this into a regular\n * `Analyst<TraceAnalysisStore>` ready for `AnalystRegistry.register()`.\n */\nexport interface TraceAnalystKindSpec {\n /** Stable id. Appears in finding_id, telemetry, and registry exclusions. */\n id: string\n /** One-sentence description shown in `registry.list()`. */\n description: string\n /** Coarse classification stamped on every emitted finding (`failure-mode`, `knowledge-gap`, ...). */\n area: string\n /** Bump on any breaking change to the actor prompt or output schema. */\n version: string\n /** Actor system prompt. Must instruct the LLM to emit `findings` per the schema. */\n actorDescription: string\n /** Responder system prompt; falls back to a minimal \"format the findings\" instruction. */\n responderDescription?: string\n /** Tool functions the actor may call. Pick narrow subsets via `ANALYST_TOOL_GROUPS`. */\n buildTools: (store: TraceAnalysisStore) => AxFunction[]\n /** Recursion budget. `maxDepth: 0` disables subagents. */\n recursion?: { maxDepth: number; maxParallelSubagents?: number }\n /** Actor turn cap. Default 12. */\n maxTurns?: number\n /** Runtime char cap. Default 6000. */\n maxRuntimeChars?: number\n /** Cost classification surfaced in `registry.list()` and budget enforcement. */\n cost: AnalystCost\n /** Per-finding-row hook — kinds may reject / rewrite before lifting. */\n postProcess?: (row: RawAnalystFinding, ctx: AnalystContext) => RawAnalystFinding | null\n /** Optional optimizer hook — populated when a kind wants to fit its prompt against labeled examples. */\n goldens?: TraceAnalystGolden[]\n}\n\n/**\n * One labeled example consumed by Ax optimizers (MIPRO / GEPA / Bootstrap).\n * Each input is the same `{question}` an analyst would receive; `expected`\n * is the ground-truth finding set a fitted prompt should produce on this\n * input. Metric: kind-specific (default: F1 on `finding_id` overlap).\n */\nexport interface TraceAnalystGolden {\n question: string\n expected: ReadonlyArray<Omit<RawAnalystFinding, 'confidence'>>\n}\n\nexport interface CreateTraceAnalystKindOpts {\n /** AxAIService bound at registration time. */\n ai: AxAIService\n /** Optional model override; falls back to the AI service's default. */\n model?: string\n /** Override the spec's `version` (e.g. when an optimizer has fitted a new prompt). */\n versionSuffix?: string\n}\n\n/**\n * Build an `Analyst<TraceAnalysisStore>` from a kind spec.\n *\n * Lifts the Ax pipeline once at registration time so the registry\n * gets a stateless analyst. The Ax agent is freshly constructed per\n * `analyze()` call (the agent carries chat-log + usage state we don't\n * want shared across analyst runs).\n */\nexport function createTraceAnalystKind(\n spec: TraceAnalystKindSpec,\n opts: CreateTraceAnalystKindOpts,\n): Analyst<TraceAnalysisStore> {\n const version = opts.versionSuffix ? `${spec.version}+${opts.versionSuffix}` : spec.version\n return {\n id: spec.id,\n description: spec.description,\n inputKind: 'trace-store',\n cost: spec.cost,\n version,\n async analyze(store, ctx) {\n const tools = spec.buildTools(store)\n const maxDepth = spec.recursion?.maxDepth ?? 0\n const maxParallel = spec.recursion?.maxParallelSubagents ?? 2\n const priorContext = renderPriorFindings(ctx.priorFindings)\n\n const actorDescription =\n spec.actorDescription.trim() +\n priorContext +\n '\\n\\n' +\n RAW_FINDING_SCHEMA_PROMPT +\n '\\n\\nReturn the array in the `findings` output field. Use `final(...)` ' +\n 'with the structured `{ findings }` payload when you are done.'\n\n const ax = agent<{ question: string }, { findings: unknown[] }>(\n 'question:string -> findings:json[]',\n {\n agentIdentity: {\n name: spec.id,\n description: spec.description,\n },\n contextFields: ['question'],\n runtime: new AxJSRuntime({\n permissions: [],\n blockDynamicImport: true,\n allowedModules: [],\n freezeIntrinsics: true,\n blockShadowRealm: true,\n preventGlobalThisExtensions: false,\n }),\n mode: maxDepth > 0 ? 'advanced' : 'simple',\n recursionOptions: maxDepth > 0 ? { maxDepth } : undefined,\n maxTurns: spec.maxTurns ?? 12,\n maxRuntimeChars: spec.maxRuntimeChars ?? 6000,\n maxBatchedLlmQueryConcurrency: maxParallel,\n promptLevel: 'detailed',\n contextPolicy: { preset: 'full', budget: 'balanced' },\n functions: { local: tools },\n actorOptions: {\n description: actorDescription,\n ...(opts.model ? { model: opts.model } : {}),\n showThoughts: false,\n thinkingTokenBudget: 'none' as unknown as number,\n },\n responderOptions: {\n description:\n spec.responderDescription ??\n 'Format the structured `findings` array exactly as the actor produced it. Do not add, drop, or summarize entries.',\n ...(opts.model ? { model: opts.model } : {}),\n showThoughts: false,\n },\n bubbleErrors: [TraceFileMissingError],\n },\n )\n\n ctx.log?.(`analyst.kind ${spec.id} forward`, {\n max_depth: maxDepth,\n tool_count: tools.length,\n tags: ctx.tags,\n })\n\n const result = await ax.forward(opts.ai, { question: deriveQuestion(ctx, spec) })\n\n const expectedSubjects = KIND_EXPECTED_SUBJECTS[spec.id]\n const out: AnalystFinding[] = []\n const rawRows = Array.isArray(result.findings) ? result.findings : []\n let rejectedWrongKind = 0\n for (const row of rawRows) {\n const parsed = parseRawFinding(row, ctx.log)\n if (!parsed) continue\n // Subject-grammar check: if the kind has a declared expects-set\n // (every shipped kind does), the finding's subject MUST parse to\n // one of the declared variants. A wrong-kind subject is a\n // contract violation — the actor's prompt drifted from the\n // grammar — and we count it for prompt-audit visibility.\n if (expectedSubjects && parsed.subject !== undefined) {\n const parsedSubject = parseFindingSubject(parsed.subject)\n if (parsedSubject === null) {\n ctx.log?.('finding rejected: subject failed to parse', {\n kind: spec.id,\n subject: parsed.subject,\n })\n rejectedWrongKind += 1\n continue\n }\n if (!expectedSubjects.includes(parsedSubject.kind)) {\n ctx.log?.('finding rejected: subject variant not allowed for this kind', {\n kind: spec.id,\n subject_kind: parsedSubject.kind,\n subject: parsed.subject,\n allowed: expectedSubjects,\n })\n rejectedWrongKind += 1\n continue\n }\n }\n const postProcessed = spec.postProcess?.(parsed, ctx) ?? parsed\n if (!postProcessed) continue\n out.push(toAnalystFinding(spec, postProcessed))\n }\n\n ctx.log?.(`analyst.kind ${spec.id} done`, {\n emitted: rawRows.length,\n accepted: out.length,\n rejected_wrong_subject: rejectedWrongKind,\n })\n return out\n },\n }\n}\n\nfunction deriveQuestion(ctx: AnalystContext, spec: TraceAnalystKindSpec): string {\n // Kinds can be steered with a per-run focusing tag without recompiling\n // the actor description. Operators set `tags.focus = \"leaf-X\"` and the\n // kind's brief is concatenated with that focus for the actor prompt's\n // user message. Falls back to the spec id when no tag is present.\n const focus = ctx.tags?.focus?.trim()\n if (focus) return `${spec.id}: ${focus}`\n return spec.id\n}\n\nfunction toAnalystFinding(spec: TraceAnalystKindSpec, raw: RawAnalystFinding): AnalystFinding {\n return makeFinding({\n analyst_id: spec.id,\n area: spec.area,\n subject: raw.subject,\n claim: raw.claim,\n rationale: raw.rationale,\n severity: raw.severity,\n confidence: raw.confidence,\n evidence_refs: [\n {\n kind: evidenceKindFromUri(raw.evidence_uri),\n uri: raw.evidence_uri,\n excerpt: raw.evidence_excerpt,\n },\n ],\n recommended_action: raw.recommended_action,\n metadata: { kind_version: spec.version },\n })\n}\n\nfunction evidenceKindFromUri(uri: string): 'span' | 'artifact' | 'metric' | 'event' | 'finding' {\n if (uri.startsWith('span://')) return 'span'\n if (uri.startsWith('artifact://')) return 'artifact'\n if (uri.startsWith('metric://')) return 'metric'\n if (uri.startsWith('event://')) return 'event'\n if (uri.startsWith('finding://')) return 'finding'\n return 'artifact'\n}\n\n/**\n * Render a compact prior-findings block the actor reads alongside its\n * brief. Each row is one line so the actor can scan dozens cheaply.\n * The kind's prompt instructs the actor to (a) check whether a new\n * cluster matches a prior `finding_id` (carry the id forward via\n * `id_basis` to keep diffs stable) and (b) raise severity / confidence\n * when a prior finding has reappeared without remediation.\n *\n * Returns the empty string when there are no prior findings — most\n * runs are \"first-of-its-kind\" and the prompt stays unchanged.\n *\n * Exported for tests + for consumers that build their own actor\n * prompts (e.g. specialized analysts living outside the default kinds).\n */\nexport function renderPriorFindings(prior: AnalystContext['priorFindings']): string {\n if (!prior || prior.length === 0) return ''\n const MAX_ROWS = 40 // keep the block under ~2KB; older history is summarized externally\n const rows = prior.slice(0, MAX_ROWS).map((f) => {\n const subject = f.subject ? ` [${f.subject}]` : ''\n return ` - id=${f.finding_id} ${f.severity}${subject} ${truncateForContext(f.claim, 160)}`\n })\n const overflow =\n prior.length > MAX_ROWS\n ? `\\n ... +${prior.length - MAX_ROWS} more prior findings (older history truncated)`\n : ''\n return [\n '',\n '',\n 'PRIOR FINDINGS (from a previous run on related data):',\n 'When the work you do now matches a row below, REUSE the `finding_id` (pass it as `id_basis`) so the cross-run diff stays stable.',\n 'A finding that reappears with no remediation evidence SHOULD raise its `confidence` and may justify a higher `severity`.',\n ...rows,\n overflow,\n ]\n .filter(Boolean)\n .join('\\n')\n}\n\nfunction truncateForContext(s: string, max: number): string {\n if (s.length <= max) return s\n return `${s.slice(0, max - 1).trimEnd()}…`\n}\n","/**\n * Pre-curated tool subsets for analyst kinds.\n *\n * The full trace-analyst tool set is seven functions. Most kinds only\n * need three or four. Picking from named groups instead of importing\n * the whole bundle keeps every kind's actor-context budget tight and\n * makes \"what can this analyst see?\" obvious at registration time.\n *\n * Each function in the group keeps its full `name`/`description` from\n * `buildTraceAnalystTools` — we filter, we don't re-implement.\n */\n\nimport type { AxFunction } from '@ax-llm/ax'\nimport type { TraceAnalysisStore } from '../trace-analyst/store'\nimport { buildTraceAnalystTools } from '../trace-analyst/tools'\n\n/** Named tool sets. Kinds pass `tools: TRACE_TOOL_GROUPS.failureForensics` etc. */\nexport type TraceToolGroupName =\n /** All seven tools. Use for open-ended discovery kinds. */\n | 'all'\n /** Overview + paginated query + count. No deep reads. Cheap. */\n | 'discovery'\n /** Discovery + viewTrace + viewSpans. Deep-read but no regex search. */\n | 'discoveryAndRead'\n /** Discovery + search tools. For pattern-matching across many traces. */\n | 'discoveryAndSearch'\n /** Discovery + viewSpans + searchSpan. Targeted-span work after another kind narrows down. */\n | 'targeted'\n\nconst TOOL_NAMES_BY_GROUP: Record<TraceToolGroupName, ReadonlySet<string>> = {\n all: new Set(),\n discovery: new Set(['getDatasetOverview', 'queryTraces', 'countTraces']),\n discoveryAndRead: new Set([\n 'getDatasetOverview',\n 'queryTraces',\n 'countTraces',\n 'viewTrace',\n 'viewSpans',\n ]),\n discoveryAndSearch: new Set([\n 'getDatasetOverview',\n 'queryTraces',\n 'countTraces',\n 'searchTrace',\n 'searchSpan',\n ]),\n targeted: new Set(['getDatasetOverview', 'queryTraces', 'viewSpans', 'searchSpan']),\n}\n\n/**\n * Build the tool set for a named group bound to a specific trace store.\n *\n * `all` returns every tool. Other groups filter `buildTraceAnalystTools`\n * by name to the documented subset. An unrecognised group name throws —\n * silently returning all tools would defeat the cost-control point.\n */\nexport function buildTraceToolsForGroup(\n group: TraceToolGroupName,\n store: TraceAnalysisStore,\n): AxFunction[] {\n const all = buildTraceAnalystTools({ store })\n if (group === 'all') return all\n const allow = TOOL_NAMES_BY_GROUP[group]\n if (!allow) throw new Error(`unknown trace tool group: ${group}`)\n return all.filter((tool) => allow.has((tool as { name: string }).name))\n}\n","/**\n * Failure-mode analyst — classifies what went wrong and why.\n *\n * Brief: read the trace dataset, identify the top failure modes across\n * runs, classify each with severity + evidence, and surface them as\n * findings. The actor's job is *taxonomy + evidence*, not fix-design —\n * that's the improvement-analyst's job.\n *\n * Recursion is deep (`maxDepth: 3`) because real failure-mode\n * discovery is genuinely tree-shaped: the actor splits the dataset\n * into candidate clusters, each cluster spawns a focused investigator\n * that drills into representative traces, and a deeply-recursed\n * investigator may itself split a confounded mode into two sub-modes.\n * Each level fans out 4-way, so the analyst can investigate up to\n * ~16 leaf clusters before hitting the depth ceiling.\n */\n\nimport type { TraceAnalystKindSpec } from '../kind-factory'\nimport { buildTraceToolsForGroup } from '../tool-groups'\n\nconst ACTOR_PROMPT = `You are a failure-mode classifier for an OTLP trace dataset. Your job is to identify the **distinct ways agents failed** in this dataset, not to grade individual runs.\n\nDISCOVERY → CLUSTER → CITE protocol:\n\n1. Call \\`traces.getDatasetOverview({})\\` first. Use \\`has_errors\\`, \\`models\\`, \\`agent_names\\`, \\`tools\\`, and \\`sample_trace_ids\\` to size the failure surface.\n2. Use \\`traces.queryTraces({ filters: { has_errors: true }, limit })\\` to pull error-bearing traces. Combine with \\`traces.countTraces\\` to see what fraction of the dataset failed.\n3. For each candidate failure cluster, use \\`traces.searchTrace\\` with regex like \\`STATUS_CODE_ERROR\\`, \\`MaxTurnsExceeded\\`, \\`assertion\\`, \\`unauthorized\\`, \\`timeout\\`, \\`429\\`, \\`5\\\\d\\\\d\\`, the agent's specific error strings, or the names of its tools. Pull one or two representative traces per cluster, **not all** of them.\n4. **Cluster, do not enumerate.** Two failures with the same root cause should be ONE finding citing both traces, not two findings. The point of this analyst is to compress N runs into K modes.\n5. For each cluster you can defend with evidence, emit ONE finding with:\n - \\`area\\` = \"failure-mode\"\n - \\`subject\\` = a short label for the cluster (\"tool-call-loop\", \"auth-revoked-mid-run\", \"agent-asked-clarification-too-late\", ...)\n - \\`claim\\` = one sentence stating the mode\n - \\`severity\\` = \"critical\" when it blocks the run, \"high\" when the run finished degraded, \"medium\" when it slowed convergence\n - \\`evidence_uri\\` = \\`span://<trace_id>/<span_id>\\` of the most representative span\n - \\`evidence_excerpt\\` = the exact quote (e.g. error message, stuck tool call payload, contradictory turn output)\n - \\`confidence\\` = 0.85+ when multiple traces show the same shape; 0.6-0.8 for a single-trace inference; <0.5 for speculative.\n - \\`recommended_action\\` = imperative-phrased fix idea (kept short — the improvement-analyst will expand on these)\n\nIf the dataset has no failures, return an empty findings array — do NOT pad with low-confidence speculation.\n\n**Delegate aggressively.** The recursion budget is there to be used:\n- After your first \\`getDatasetOverview\\` + \\`queryTraces\\` calls, you should have 3-6 candidate failure clusters in mind. Spawn one \\`llmQuery\\` per cluster in a single batch — they investigate in parallel.\n- A sub-investigator that finds its cluster is actually two distinct modes should split again at its own level. Recursion is meant to discover sub-modes, not to do trivial drilling that the parent could do in-line.\n- Pass narrow context to each subagent: { question: 'investigate the auth-revoked-mid-run cluster', context: { trace_ids: ['abc', 'def'], suspected_root_cause: 'token refresh skipped on idle sessions' } }. Subagents need enough context to skip re-discovery but not the whole conversation.\n- Each subagent returns its findings as JSON; the parent merges them. Do NOT have subagents call \\`final()\\` — they return their findings list to you, and you call \\`final()\\` once at the top.\n\nOBSERVABILITY rules:\n- Each non-final turn must emit at least one \\`console.log\\` for evidence.\n- Reuse runtime variables across turns; don't recompute.\n- Call \\`final({ findings: [...] })\\` exactly once, after you've gathered evidence for every cluster you intend to report.`\n\nexport const FAILURE_MODE_KIND_SPEC: TraceAnalystKindSpec = {\n id: 'failure-mode',\n description:\n 'Clusters trace-dataset failures into distinct failure modes with cited evidence and a short recommended action.',\n area: 'failure-mode',\n version: '1.0.0',\n actorDescription: ACTOR_PROMPT,\n buildTools: (store) => buildTraceToolsForGroup('all', store),\n recursion: { maxDepth: 3, maxParallelSubagents: 4 },\n maxTurns: 24,\n cost: { kind: 'llm' },\n}\n","/**\n * Improvement analyst — actionable, recursive self-improvement findings.\n *\n * Brief: read findings from upstream analysts (failure-mode,\n * knowledge-gap, knowledge-poisoning) AND the trace dataset itself,\n * then propose **concrete edits** to the agent's runtime: prompt\n * additions, RAG documents to ingest, tool descriptions to rewrite,\n * scaffolding changes to make, memory entries to invalidate. Each\n * finding is one proposed edit with the locus, the diff, and the\n * expected effect.\n *\n * This is the recursive-self-improvement loop's last mile: the prior\n * kinds describe *what's wrong*; this kind describes *what to change*.\n *\n * Recursion is deep (`maxDepth: 3`) because real improvement proposals\n * are competitive: for each failure-mode there are usually 2-3 viable\n * fix directions (tighten prompt vs add tool vs adjust scaffolding),\n * and the actor should explore each with a focused subagent before\n * picking the highest-leverage one to recommend.\n */\n\nimport type { TraceAnalystKindSpec } from '../kind-factory'\nimport { buildTraceToolsForGroup } from '../tool-groups'\n\nconst ACTOR_PROMPT = `You are a recursive-self-improvement analyst. Your job is to propose **concrete, locus-named edits** the agent's runtime should adopt to fix the failure modes, knowledge gaps, and poisonings present in this dataset.\n\nUpstream analysts have already classified the problems. Your job is to convert each problem into a *change to make* and grade its expected leverage. Each finding is one proposed edit.\n\nDISCOVERY → CANDIDATE-FIXES → COMPETE → CITE protocol:\n\n1. \\`traces.getDatasetOverview({})\\` first. Note the agents, tools, and any system-prompt fingerprints (look for the prompt text echoed in early spans).\n2. For each high-severity failure pattern, generate 2-3 candidate fixes. Real candidate axes:\n - **System-prompt edit** — add an instruction, remove a misleading one, restructure precedence\n - **Tool description edit** — rewrite a tool's description so the agent picks it correctly / passes valid args\n - **New tool** — add a tool the agent kept emulating in code\n - **RAG ingestion** — add a document or correct a stale one\n - **Memory invalidation** — clear cached prior-run decisions that no longer apply\n - **Scaffolding** — add a precondition check, a retry policy, a turn budget, a verification step\n - **Output schema** — narrow the agent's output to forbid the failure shape\n3. **Compete candidate fixes via subagents.** For each failure cluster, spawn one \\`llmQuery\\` per candidate-fix axis you want to evaluate. Each subagent's job: simulate the fix on the cited traces and report (i) likely effect, (ii) side effects, (iii) implementation cost as small/medium/large. Pass the cluster's failing trace_ids and the candidate axis as context.\n4. After subagents return, **pick the winning candidate per cluster** based on (effect / cost) and emit ONE finding. Discard the losing candidates — the output is the recommendation, not the candidate set.\n5. **Cross-reference upstream findings.** If a finding cites a prior failure-mode or knowledge-gap finding, use \\`evidence_uri = \"finding://<prior-finding-id>\"\\` (the registry supports this kind). This builds the dependency graph that lets the dashboard show \"fix #X resolves failure modes A, B, C.\"\n\nFor each winning recommendation, emit ONE finding with:\n- \\`area\\` = \"improvement\"\n- \\`subject\\` = the locus to edit: \\`system-prompt:<section>\\`, \\`tool-doc:<tool-name>\\`, \\`new-tool:<proposed-name>\\`, \\`rag:<corpus>:<doc-id>\\`, \\`memory:<key>\\`, \\`scaffolding:<concern>\\`, \\`output-schema:<field>\\`\n- \\`claim\\` = one sentence stating the edit (\"Add a precondition check to refuse tool X calls without arg Y\")\n- \\`severity\\` = leverage rating: \"critical\" when fix resolves a critical failure mode; \"high\" when it resolves a high; \"medium\" when it's a quality-of-life win; \"info\" when it's a cleanup with no behavioral effect\n- \\`evidence_uri\\` = the failure-mode finding id this fix targets (\\`finding://<id>\\`) when it exists; else the most representative span\n- \\`evidence_excerpt\\` = a fragment showing the problem the fix targets\n- \\`confidence\\` = 0.85+ when the fix is mechanical and the failure mode is well-evidenced; 0.6-0.8 when the fix requires judgment; <0.5 for speculative\n- \\`rationale\\` = why this candidate beat its alternatives (2 sentences max)\n- \\`recommended_action\\` = the **literal edit**, phrased as a diff or a quoted replacement: \"Replace section X with: '...'\" or \"Add tool with description: '...'\" or \"Set retry policy to max_attempts=3 with exponential backoff\"\n\nIf no upstream failure findings exist in this run, derive your own from the trace dataset using the failure-mode protocol inline (\\`searchTrace\\` for STATUS_CODE_ERROR / MaxTurnsExceeded / etc.). But prefer to consume upstream findings when present — the kinds are designed to chain.\n\nDo NOT propose a fix you cannot defend with evidence. \"Tighten the prompt\" is not a finding; \"Add 'When the user asks for X, always Y' to the system prompt section \"request-classification\"\" is.\n\nOBSERVABILITY rules:\n- Each non-final turn must emit at least one \\`console.log\\` for evidence.\n- Call \\`final({ findings: [...] })\\` exactly once at the top level.`\n\nexport const IMPROVEMENT_KIND_SPEC: TraceAnalystKindSpec = {\n id: 'improvement',\n description:\n 'Converts upstream failure / gap / poisoning findings into concrete locus-named edits (prompt, tool-doc, RAG, scaffolding) with leverage grades.',\n area: 'improvement',\n version: '1.0.0',\n actorDescription: ACTOR_PROMPT,\n buildTools: (store) => buildTraceToolsForGroup('all', store),\n recursion: { maxDepth: 3, maxParallelSubagents: 4 },\n maxTurns: 30,\n maxRuntimeChars: 12000,\n cost: { kind: 'llm' },\n}\n","/**\n * Knowledge-gap analyst — what did the agent NOT know that it needed?\n *\n * Brief: find moments in the trace where the agent had to guess, ask\n * the user to fill in context, recover from a wrong assumption, or\n * loop on a retrieval. Each finding names a *missing or outdated piece\n * of knowledge* the agent's curated knowledge base should have held —\n * or a downstream lookup (web, docs, tool description) that surfaced\n * stale or outdated information.\n *\n * The primary expected store is `@tangle-network/agent-knowledge`: a\n * Karpathy-style wiki the agent maintains with raw ↔ curated pages,\n * source anchors, and claim/relation triples. A gap is anything the\n * agent had to discover at run-time that should already have lived\n * there. Secondary loci: web-search results that returned outdated\n * pages, tool descriptions that omitted critical behavior, system-\n * prompt sections that didn't cover the case.\n *\n * Distinct from failure-mode: failure-mode classifies *how* it broke;\n * knowledge-gap names the *information* whose absence (or staleness)\n * caused the break. One failure-mode often maps to several gaps.\n *\n * Recursion (`maxDepth: 2`) is enough to fan out one subagent per\n * candidate gap-source layer; each subagent runs a focused detection.\n */\n\nimport type { TraceAnalystKindSpec } from '../kind-factory'\nimport { buildTraceToolsForGroup } from '../tool-groups'\n\nconst ACTOR_PROMPT = `You are a knowledge-gap analyst for an OTLP trace dataset. Your job is to identify the **specific pieces of information the agent lacked, or that were stale**, that caused poor decisions.\n\nThe agent under analysis maintains a curated knowledge base via \\`@tangle-network/agent-knowledge\\` — a wiki of \\`KnowledgePage\\`s with raw source anchors, claims, and relations. The primary expected store of agent-knowable facts IS that wiki. A \"knowledge gap\" is anything the agent had to discover or guess at run-time that the wiki should have held — or an outdated/contradictory fact the agent picked up from a non-wiki source.\n\nDISCOVERY → ATTRIBUTE-TO-LAYER → CITE protocol:\n\n1. \\`traces.getDatasetOverview({})\\` first. Note which agents, tools, and models appear.\n2. Pull traces where the agent shows gap signals. The strongest signals are:\n - Self-correction turns (\"I assumed X but…\", \"let me re-check\", \"actually,\")\n - Clarifying-question turns where the agent asked the user something the runtime should have surfaced\n - Repeated retrieval / lookup calls for the same artifact with slightly varied queries\n - Tool errors that name a missing argument or unknown resource\n - Web-search calls returning pages dated before a known cutoff for content that changes (versioned APIs, schemas, policies)\n - Agent quoting a tool's docs / system prompt incorrectly because the actual text was insufficient\n - Fabricated identifiers that don't appear in dataset \\`sample_trace_ids\\`\n Use \\`traces.searchTrace\\` with patterns like \\`I (don.?t|do not) know\\`, \\`assumed\\`, \\`unclear\\`, \\`could you (clarify|tell me|provide)\\`, \\`not found\\`, \\`undefined\\`, \\`unknown\\`, \\`null\\`, dates older than the analysis window, or the agent's specific clarification phrases.\n3. For each gap, identify the **layer of the runtime that should have prevented it**. The locus is the value of \\`subject\\` on the finding. Use one of:\n - \\`agent-knowledge:wiki:<page-slug>\\` — the wiki page that should exist but doesn't, or exists but lacks the claim\n - \\`agent-knowledge:wiki:<page-slug>#<heading>\\` — wiki page exists but a specific section is missing\n - \\`agent-knowledge:claim:<topic>\\` — a specific claim/relation triple that should be in the wiki\n - \\`agent-knowledge:raw:<source-id>\\` — raw source captured but never lifted into a curated page\n - \\`agent-knowledge:stale:<page-slug>\\` — wiki page exists but contradicts ground-truth evidence in this trace (the wiki itself drifted)\n - \\`websearch:outdated:<topic>\\` — agent relied on a web result that was stale; wiki should have superseded it\n - \\`tool-doc:<tool-name>:<aspect>\\` — tool description missed a behavior aspect (return shape, failure modes, side effects)\n - \\`system-prompt:<section>\\` — system prompt should have stated the rule directly\n - \\`memory:<key>\\` — prior-run memory should have surfaced an earlier decision\n4. For each gap you can defend with evidence, emit ONE finding with:\n - \\`area\\` = \"knowledge-gap\"\n - \\`subject\\` = the locus string from the list above\n - \\`claim\\` = a sentence naming the missing or stale knowledge (\"wiki has no page on invoice line-item shape, agent had to re-derive it from raw spans\")\n - \\`severity\\` = \"high\" when the gap caused a failure or a clarifying question; \"medium\" when it caused unnecessary turns; \"low\" when it caused minor inefficiency\n - \\`evidence_uri\\` = \\`span://<trace_id>/<span_id>\\` of the moment the gap surfaced (the question, the self-correction, the retrieval miss, the stale web result)\n - \\`evidence_excerpt\\` = exact quote where the agent showed the gap\n - \\`confidence\\` = 0.85+ when the agent itself articulated the gap; 0.6-0.8 when inferred from behavior\n - \\`recommended_action\\` = phrased as a wiki edit when the locus is \\`agent-knowledge:*\\` (\"Create wiki page \\`invoice-line-items\\` with claims: ...\"), or as a prompt/tool-doc edit otherwise\n\n**Delegate per layer.** After your first scan, you should have candidates spread across \\`agent-knowledge:*\\`, \\`websearch:outdated\\`, \\`tool-doc:*\\`, \\`system-prompt:*\\`, and \\`memory:*\\`. Spawn one \\`llmQuery\\` per layer in parallel — each subagent runs a focused detection (e.g. the \\`agent-knowledge\\` subagent looks for both missing-pages AND stale-pages; the \\`websearch\\` subagent looks specifically for date staleness signals; the \\`tool-doc\\` subagent looks for tool-call argument errors a fuller description would have prevented). Subagents return findings; you merge and emit one \\`final({ findings })\\` at the top.\n\nDo NOT report a gap that the agent later recovered from cleanly within the same turn — that's resilience, not a gap. Cite the *non-recovery* version when both exist.\n\nOBSERVABILITY rules:\n- Each non-final turn must emit at least one \\`console.log\\` for evidence.\n- Call \\`final({ findings: [...] })\\` exactly once at the top level.`\n\nexport const KNOWLEDGE_GAP_KIND_SPEC: TraceAnalystKindSpec = {\n id: 'knowledge-gap',\n description:\n 'Identifies missing or stale pieces of knowledge — primarily against the agent-knowledge wiki — and attributes each to the runtime layer (wiki page, claim, raw source, websearch, tool-doc, system-prompt, memory) that should have held it.',\n area: 'knowledge-gap',\n version: '1.0.0',\n actorDescription: ACTOR_PROMPT,\n buildTools: (store) => buildTraceToolsForGroup('discoveryAndSearch', store),\n recursion: { maxDepth: 2, maxParallelSubagents: 4 },\n maxTurns: 18,\n cost: { kind: 'llm' },\n}\n","/**\n * Knowledge-poisoning analyst — what FALSE information misled the agent?\n *\n * Brief: find moments where the agent acted on information that was\n * *wrong* — stale memory, RAG documents that contradicted ground truth,\n * tool descriptions that lied about return shapes, system-prompt\n * instructions that no longer matched reality, prior-run summaries that\n * cached a wrong decision.\n *\n * Distinct from knowledge-gap: a gap is \"the agent didn't know X\"; a\n * poisoning is \"the agent confidently used X, but X was wrong.\" Gaps\n * surface as questions / self-correction; poisonings surface as\n * confident-but-wrong actions that downstream evidence contradicts.\n *\n * Recursion is moderate (`maxDepth: 2`) because each candidate\n * poisoning typically needs two sub-investigations: one to confirm\n * the agent acted on the false belief, one to confirm the belief\n * itself is actually false in ground truth.\n */\n\nimport type { TraceAnalystKindSpec } from '../kind-factory'\nimport { buildTraceToolsForGroup } from '../tool-groups'\n\nconst ACTOR_PROMPT = `You are a knowledge-poisoning analyst for an OTLP trace dataset. Your job is to identify cases where the agent **confidently used wrong information** — not where it lacked information (that's the knowledge-gap analyst).\n\nDISCOVERY → DUAL-VERIFY → CITE protocol:\n\n1. \\`traces.getDatasetOverview({})\\` first. Identify the agents, models, and tools.\n2. Pull traces where the agent's confident action was later contradicted. Strongest signals:\n - Agent stated a fact in one span; a later span surfaced contradictory evidence; the agent then proceeded anyway or fabricated reconciliation.\n - Tool call with stale arguments (an id that no longer exists, an API shape that changed).\n - Agent cited an \\`agent-knowledge\\` wiki page or claim whose content contradicts the trace's own evidence — the wiki itself drifted.\n - Web-search result the agent cited that returned an outdated page; agent treated it as canonical.\n - System-prompt instruction the agent followed that ground-truth evidence in the trace contradicts (e.g. prompt says \"use endpoint A\"; tool reply says \"endpoint A deprecated, use B\").\n - Repeated wrong-shape parsing despite the tool's actual output proving the shape.\n3. Use \\`traces.searchTrace\\` with regex on phrases like \\`actually\\`, \\`turns out\\`, \\`previously assumed\\`, \\`old version\\`, \\`deprecated\\`, \\`updated to\\`, \\`now uses\\`, or specific entity names you suspect have changed.\n4. For each candidate poisoning, **DUAL-VERIFY**:\n - Confirm the agent actually acted on the false belief (cite the span where it did)\n - Confirm the belief is actually false in this trace's own evidence (cite the span that contradicts it)\n Only emit a finding when both halves are nailed down. If you can only nail one, drop it — single-evidence poisoning findings are too speculative to be useful.\n\n**Delegate the dual-verify.** Use the recursion budget so each candidate poisoning gets one subagent investigating \"did the agent act?\" and one investigating \"is the belief false?\". After your first scan, fire off N parallel \\`llmQuery\\` pairs (one cluster per pair). Subagents return their findings; you accept only the ones where BOTH halves of the pair were confirmed.\n\nFor each confirmed poisoning, emit ONE finding with:\n- \\`area\\` = \"knowledge-poisoning\"\n- \\`subject\\` = the source of the false belief, one of: \\`agent-knowledge:wiki:<page-slug>\\` (wiki page contradicts current ground truth), \\`agent-knowledge:claim:<topic>\\` (a specific claim/relation went stale), \\`agent-knowledge:raw:<source-id>\\` (the raw source is outdated and the wiki inherited the drift), \\`websearch:outdated:<url-or-topic>\\`, \\`tool-doc:<tool>\\`, \\`system-prompt:<section>\\`, \\`memory:<key>\\`, \\`prior-run-summary:<topic>\\`\n- \\`claim\\` = one sentence: \"agent believed X (from source S); evidence in trace shows X is false\"\n- \\`severity\\` = \"critical\" when poisoning caused a wrong user-visible action; \"high\" when caught internally but wasted significant work; \"medium\" for inefficiency only\n- \\`evidence_uri\\` = \\`span://<trace_id>/<span_id>\\` of the action span (the moment the agent acted on the false belief)\n- \\`evidence_excerpt\\` = exact quote of the confident-but-wrong claim or action\n- \\`confidence\\` = 0.85+ when both halves are exact-quote backed; 0.6-0.8 when one half is inferred\n- \\`recommended_action\\` = where the source should be updated and how (\"Update wiki page \\`X\\` claim \\`Y\\` to '...'\", \"Invalidate raw source \\`Z\\` and re-curate\", \"Replace system-prompt section X with 'tool foo now returns Y'\")\n\nDo NOT report a finding if the agent caught and corrected the false belief in the same turn — that's the system working. Reserve poisoning for cases where the false belief shaped downstream action.\n\nOBSERVABILITY rules:\n- Each non-final turn must emit at least one \\`console.log\\` for evidence.\n- Call \\`final({ findings: [...] })\\` exactly once at the top level.`\n\nexport const KNOWLEDGE_POISONING_KIND_SPEC: TraceAnalystKindSpec = {\n id: 'knowledge-poisoning',\n description:\n 'Identifies confident-but-wrong actions caused by stale memory, contradicting RAG, deprecated tool docs, or outdated system-prompt instructions.',\n area: 'knowledge-poisoning',\n version: '1.0.0',\n actorDescription: ACTOR_PROMPT,\n buildTools: (store) => buildTraceToolsForGroup('all', store),\n recursion: { maxDepth: 2, maxParallelSubagents: 4 },\n maxTurns: 20,\n cost: { kind: 'llm' },\n}\n","/**\n * Default analyst kinds focused on agent failure + recursive\n * self-improvement.\n *\n * The four kinds chain: failure-mode classifies; knowledge-gap and\n * knowledge-poisoning explain *why* in two orthogonal ways; improvement\n * proposes concrete edits. Register all four against the same trace\n * store and the registry runs them in dependency order if the operator\n * pipes findings between them.\n */\n\nexport { FAILURE_MODE_KIND_SPEC } from './failure-mode'\nexport { IMPROVEMENT_KIND_SPEC } from './improvement'\nexport { KNOWLEDGE_GAP_KIND_SPEC } from './knowledge-gap'\nexport { KNOWLEDGE_POISONING_KIND_SPEC } from './knowledge-poisoning'\n\nimport type { TraceAnalystKindSpec } from '../kind-factory'\nimport { FAILURE_MODE_KIND_SPEC } from './failure-mode'\nimport { IMPROVEMENT_KIND_SPEC } from './improvement'\nimport { KNOWLEDGE_GAP_KIND_SPEC } from './knowledge-gap'\nimport { KNOWLEDGE_POISONING_KIND_SPEC } from './knowledge-poisoning'\n\n/**\n * The default kind suite. Order is the run order operators should\n * use: failure-mode first (no upstream deps), gap + poisoning next\n * (both depend on failures), improvement last (chains all three).\n */\nexport const DEFAULT_TRACE_ANALYST_KINDS: readonly TraceAnalystKindSpec[] = [\n FAILURE_MODE_KIND_SPEC,\n KNOWLEDGE_GAP_KIND_SPEC,\n KNOWLEDGE_POISONING_KIND_SPEC,\n IMPROVEMENT_KIND_SPEC,\n] as const\n","/**\n * Skill-usage analyst — a DETERMINISTIC `Analyst` over a Claude/Codex skill\n * library + its trace corpus. Unlike the trace-store kinds (failure-mode,\n * improvement, ...) this kind calls no LLM: it mines real usage and skill\n * structure and emits findings by rule.\n *\n * It exists because the naive \"Skill-tool invocation count\" lies low — it\n * misses orchestrated sub-dispatch (a leaf skill run BY /pursue or /governor\n * logs under the parent), slash-command entry, local-script bypass, and\n * on-disk artifacts. The 2026-05-30 skill audit found 39/53 skills at zero\n * direct invocations, yet only one was a genuine cut: the rest were\n * measurement-invisible or discovery-limited. This analyst encodes that\n * lesson as a multi-signal usage model so a cheap repeatable pass can keep\n * the library honest, and so the expensive audit workflow's verdicts can\n * GEPA-distill it toward agreement (see `gold/skill-verdicts.gold.jsonl`).\n *\n * Report-building (`buildSkillUsageReport`, an fs scan) is separated from\n * finding emission (`SkillUsageAnalyst.analyze`, pure) so the slow scan runs\n * once at the registry boundary and the rule logic stays unit-testable.\n */\n\nimport { existsSync, readdirSync, readFileSync, statSync } from 'node:fs'\nimport { join } from 'node:path'\nimport type { Analyst, AnalystContext, AnalystFinding, AnalystSeverity } from '../types'\nimport { computeFindingId } from '../types'\n\n// ── Input model ──────────────────────────────────────────────────────\n\nexport type SkillKind = 'public' | 'private'\n\n/** One skill's multi-signal usage + structure. All counts are deterministic. */\nexport interface SkillUsageRecord {\n name: string\n kind: SkillKind\n /** Absolute path to the skill's SKILL.md. */\n path: string\n lines: number\n /** `\"skill\":\"<name>\"` Skill-tool invocations across the trace corpus. */\n directInvocations: number\n /** `<command-name>/<name>` slash invocations across the trace corpus. */\n slashInvocations: number\n /** Sibling skills whose SKILL.md dispatches to this one (`/<name>`). Proxy\n * for orchestrated sub-dispatch the per-skill counter cannot see. */\n inboundRefs: number\n /** On-disk artifacts attributable to the skill (e.g. `.evolve/<name>/**`). */\n artifactCount: number\n /** Tangle-private reference count in the body (leak signal for public skills). */\n tanglePrivateRefs: number\n hasReferencesDir: boolean\n hasEvalsDir: boolean\n /** Body mentions `skill-runs.jsonl` (visible to /reflect + /governor). */\n logsRuns: boolean\n /** Description carries an explicit `Triggers:` clause / trigger phrases. */\n hasTriggerPhrases: boolean\n}\n\nexport interface SkillUsageReport {\n generatedFromTraces: number\n records: SkillUsageRecord[]\n}\n\nexport interface SkillUsageScanConfig {\n /** Dirs holding `*.jsonl` transcripts (Claude `~/.claude/projects`, Codex sessions). */\n transcriptDirs: string[]\n /** Skill roots to scan; each dir directly under `root` with a `SKILL.md` is a skill. */\n skillRoots: { root: string; kind: SkillKind }[]\n /** Roots scanned for `<root>/.evolve/<skill>` artifact dirs. */\n artifactRoots?: string[]\n /** Token-prefixed mappings: skill name → extra artifact subpaths under an artifactRoot\n * (e.g. reflect → `.evolve/reflections`). Catches non-eponymous artifact dirs. */\n artifactAliases?: Record<string, string[]>\n /** Cap files read per transcript dir (bounds a huge corpus); 0 = unbounded. */\n maxTranscriptsPerDir?: number\n}\n\n// ── Deterministic thresholds ─────────────────────────────────────────\n\n/** Anthropic's authoring guidance keeps SKILL.md short; past this with no\n * `references/` split the body burns context budget every session. */\nconst BLOAT_LINE_THRESHOLD = 300\n\nconst TANGLE_PRIVATE_RE =\n /\\b(cli-bridge|tangletools|ops-board|drew-gtr-pro|@tangle-network\\/|~\\/company|tangle\\.tools|gtm-agent)\\b|\\bkimi\\b|\\btcloud\\b/gi\nconst TRIGGER_RE = /triggers?\\s*[:-]/i\n\n// ── Report builder (fs scan — slow, runs once at the registry boundary) ──\n\nfunction listSkillDirs(root: string): { name: string; path: string }[] {\n if (!existsSync(root)) return []\n const out: { name: string; path: string }[] = []\n for (const entry of readdirSync(root, { withFileTypes: true })) {\n if (!entry.isDirectory() && !entry.isSymbolicLink()) continue\n const skillMd = join(root, entry.name, 'SKILL.md')\n if (existsSync(skillMd)) out.push({ name: entry.name, path: skillMd })\n }\n return out\n}\n\nfunction walkJsonl(dir: string, cap: number): string[] {\n if (!existsSync(dir)) return []\n const files: string[] = []\n const stack = [dir]\n while (stack.length) {\n const cur = stack.pop()!\n let entries\n try {\n entries = readdirSync(cur, { withFileTypes: true })\n } catch {\n continue\n }\n for (const e of entries) {\n const full = join(cur, e.name)\n if (e.isDirectory()) stack.push(full)\n else if (e.name.endsWith('.jsonl')) {\n files.push(full)\n if (cap > 0 && files.length >= cap) return files\n }\n }\n }\n return files\n}\n\nfunction frontmatterDescription(body: string): string {\n const fm = /^---\\n([\\s\\S]*?)\\n---/.exec(body)\n const block = fm?.[1] ?? ''\n const m = /description:\\s*(.+)/i.exec(block)\n return m?.[1] ?? ''\n}\n\nfunction countArtifacts(roots: string[], name: string, aliases: string[]): number {\n let n = 0\n for (const root of roots) {\n const candidates = [join(root, '.evolve', name), ...aliases.map((a) => join(root, a))]\n for (const dir of candidates) {\n if (!existsSync(dir)) continue\n try {\n if (statSync(dir).isDirectory()) n += readdirSync(dir).length\n else n += 1\n } catch {\n /* unreadable — skip */\n }\n }\n }\n return n\n}\n\n/** Scan the corpus + skill roots into a {@link SkillUsageReport}. Deterministic. */\nexport function buildSkillUsageReport(config: SkillUsageScanConfig): SkillUsageReport {\n const skills = config.skillRoots.flatMap(({ root, kind }) =>\n listSkillDirs(root).map((s) => ({ ...s, kind })),\n )\n const names = skills.map((s) => s.name)\n\n // One pass over the corpus accumulating direct + slash counts per skill.\n const direct = new Map<string, number>(names.map((n) => [n, 0]))\n const slash = new Map<string, number>(names.map((n) => [n, 0]))\n const skillRe = /\"skill\"\\s*:\\s*\"([a-z0-9_:-]+)\"/g\n const cmdRe = /<command-name>\\/?([a-z0-9_:-]+)<\\/command-name>/g\n let transcripts = 0\n for (const dir of config.transcriptDirs) {\n for (const file of walkJsonl(dir, config.maxTranscriptsPerDir ?? 0)) {\n transcripts += 1\n let data: string\n try {\n data = readFileSync(file, 'utf8')\n } catch {\n continue\n }\n for (const m of data.matchAll(skillRe)) {\n const g = m[1]\n if (!g) continue\n const n = g.split(':').pop() ?? g\n const prev = direct.get(n)\n if (prev !== undefined) direct.set(n, prev + 1)\n }\n for (const m of data.matchAll(cmdRe)) {\n const g = m[1]\n if (g === undefined) continue\n const prev = slash.get(g)\n if (prev !== undefined) slash.set(g, prev + 1)\n }\n }\n }\n\n // Read each skill body once; compute structure + inbound refs across siblings.\n const bodies = new Map<string, string>()\n for (const s of skills) {\n try {\n bodies.set(s.name, readFileSync(s.path, 'utf8'))\n } catch {\n bodies.set(s.name, '')\n }\n }\n const inbound = new Map<string, number>(names.map((n) => [n, 0]))\n for (const target of names) {\n const ref = new RegExp(`/${target}\\\\b|\\\\[\\\\[${target}\\\\]\\\\]`)\n for (const s of skills) {\n if (s.name === target) continue\n if (ref.test(bodies.get(s.name) ?? '')) inbound.set(target, inbound.get(target)! + 1)\n }\n }\n\n const records: SkillUsageRecord[] = skills.map((s) => {\n const body = bodies.get(s.name) ?? ''\n const dir = s.path.replace(/\\/SKILL\\.md$/, '')\n return {\n name: s.name,\n kind: s.kind,\n path: s.path,\n lines: body ? body.split('\\n').length : 0,\n directInvocations: direct.get(s.name) ?? 0,\n slashInvocations: slash.get(s.name) ?? 0,\n inboundRefs: inbound.get(s.name) ?? 0,\n artifactCount: countArtifacts(\n config.artifactRoots ?? [],\n s.name,\n config.artifactAliases?.[s.name] ?? [],\n ),\n tanglePrivateRefs: (body.match(TANGLE_PRIVATE_RE) ?? []).length,\n hasReferencesDir: existsSync(join(dir, 'references')),\n hasEvalsDir: existsSync(join(dir, 'evals')),\n logsRuns: body.includes('skill-runs.jsonl'),\n hasTriggerPhrases: TRIGGER_RE.test(frontmatterDescription(body) || body.slice(0, 600)),\n }\n })\n return { generatedFromTraces: transcripts, records }\n}\n\n// ── Finding emission (pure — unit-testable, no LLM, no fs) ────────────\n\nconst ANALYST_ID = 'skill-usage'\n\nfunction finding(\n area: string,\n subject: string,\n claim: string,\n severity: AnalystSeverity,\n confidence: number,\n producedAt: string,\n recommended: string,\n evidenceUri: string,\n rationale?: string,\n): AnalystFinding {\n return {\n schema_version: '1.0.0',\n finding_id: computeFindingId({ analyst_id: ANALYST_ID, area, subject, claim }),\n analyst_id: ANALYST_ID,\n produced_at: producedAt,\n severity,\n area,\n claim,\n rationale,\n evidence_refs: [{ kind: 'artifact', uri: evidenceUri }],\n recommended_action: recommended,\n confidence,\n subject,\n }\n}\n\n/** Pure rule pass over a report → findings. Exported for direct/unit use. */\nexport function emitSkillUsageFindings(\n report: SkillUsageReport,\n producedAt: string,\n): AnalystFinding[] {\n const out: AnalystFinding[] = []\n for (const r of report.records) {\n const directTotal = r.directInvocations + r.slashInvocations\n const trueUsage = directTotal + r.inboundRefs + r.artifactCount\n\n // 1. Dead: no usage signal of ANY kind. The only real deprecation candidate.\n if (trueUsage === 0) {\n out.push(\n finding(\n 'skill-usage',\n r.name,\n `Skill '${r.name}' has zero usage across all signals (direct, slash, inbound-refs, artifacts)`,\n 'high',\n 0.6,\n producedAt,\n 'Confirm the skill covers a real recurring job; if not, deprecate. Zero true usage is the only deterministic deprecation candidate.',\n r.path,\n 'No Skill-tool call, no slash invocation, no sibling dispatches to it, and no on-disk artifacts.',\n ),\n )\n } else if (directTotal === 0 && r.inboundRefs + r.artifactCount > 0) {\n // 2. Measurement-invisible: real use via orchestration/artifacts, never invoked directly.\n out.push(\n finding(\n 'skill-usage',\n r.name,\n `Skill '${r.name}' shows 0 direct invocations but is used via orchestration/artifacts (inbound=${r.inboundRefs}, artifacts=${r.artifactCount})`,\n 'info',\n 0.8,\n producedAt,\n 'Do NOT treat as unused — usage is real but logged under parent skills or on disk. Strengthen direct-invocation discovery only if direct use is desired.',\n r.path,\n 'The Skill-tool counter undercounts orchestrated/chained leaf skills.',\n ),\n )\n }\n\n // 3. Discovery gap: low direct use AND weak trigger surface.\n if (directTotal <= 2 && !r.hasTriggerPhrases) {\n out.push(\n finding(\n 'discoverability',\n r.name,\n `Skill '${r.name}' is rarely invoked directly and its description has no explicit trigger phrases`,\n 'medium',\n 0.7,\n producedAt,\n 'Add a `Triggers:` clause with verbatim user phrases to the frontmatter description so the model auto-invokes it.',\n r.path,\n ),\n )\n }\n\n // 4. Public-repo leak.\n if (r.kind === 'public' && r.tanglePrivateRefs > 0) {\n out.push(\n finding(\n 'safety',\n r.name,\n `Public skill '${r.name}' carries ${r.tanglePrivateRefs} Tangle-private reference(s)`,\n 'high',\n 0.75,\n producedAt,\n 'Sanitize incidental internal refs (cli-bridge/kimi/tcloud/~company/private repos) or relocate to a private repo. Verify @tangle-network/* refs are to PUBLISHED packages before treating as a leak.',\n r.path,\n ),\n )\n }\n\n // 5. Bloat / no progressive disclosure.\n if (r.lines > BLOAT_LINE_THRESHOLD && !r.hasReferencesDir) {\n out.push(\n finding(\n 'maintainability',\n r.name,\n `Skill '${r.name}' is ${r.lines} lines with no references/ split (progressive disclosure)`,\n 'medium',\n 0.8,\n producedAt,\n `Split detail into references/ loaded on demand; keep SKILL.md a short overview. ${r.lines} lines load into every session's context budget.`,\n r.path,\n ),\n )\n }\n\n // 6. No evals (Anthropic's \">=3 evals before docs\" rule).\n if (!r.hasEvalsDir) {\n out.push(\n finding(\n 'data-quality',\n r.name,\n `Skill '${r.name}' ships no evals/`,\n 'low',\n 0.6,\n producedAt,\n 'Add evals/evals.json with >=3 scenarios proving the skill beats baseline; gives regression coverage.',\n r.path,\n ),\n )\n }\n\n // 7. No run logging → invisible to /reflect and /governor.\n if (!r.logsRuns) {\n out.push(\n finding(\n 'observability',\n r.name,\n `Skill '${r.name}' never appends to .evolve/skill-runs.jsonl`,\n 'low',\n 0.55,\n producedAt,\n 'Append one run line to .evolve/skill-runs.jsonl on completion, or declare it a non-logging leaf, so the self-improvement loop can see it ran.',\n r.path,\n ),\n )\n }\n }\n return out\n}\n\n// ── The Analyst ──────────────────────────────────────────────────────\n\nexport class SkillUsageAnalyst implements Analyst<SkillUsageReport> {\n readonly id = ANALYST_ID\n readonly description =\n 'Deterministic multi-signal skill-usage analysis: flags dead skills, measurement-invisible (orchestrated) usage, discovery gaps, public-repo leaks, bloat, missing evals, and missing run-logging.'\n readonly inputKind = 'custom' as const\n readonly cost = { kind: 'deterministic' as const, est_usd_per_run: 0 }\n readonly version = '1.0.0'\n\n async analyze(input: SkillUsageReport, ctx: AnalystContext): Promise<AnalystFinding[]> {\n const producedAt = ctx.tags?.producedAt ?? new Date().toISOString()\n ctx.log?.(\n `skill-usage: ${input.records.length} skills over ${input.generatedFromTraces} transcripts`,\n )\n return emitSkillUsageFindings(input, producedAt)\n }\n}\n\nexport const SKILL_USAGE_ANALYST = new SkillUsageAnalyst()\n","/**\n * AnalystRegistry — orchestrate N analysts against one run.\n *\n * Owns three responsibilities and only three:\n * 1. Registration — ids must be unique; bad registrations fail loudly\n * at register-time, not run-time.\n * 2. Routing — each analyst declares its `inputKind`; the registry\n * picks the matching field from AnalystRunInputs and skips the\n * analyst with a logged reason if it's missing.\n * 3. Isolation — one analyst's exception MUST NOT stop other analysts.\n * Failed analysts produce zero findings + a 'failed' summary row.\n *\n * Cross-cutting concerns (telemetry, error → finding conversion, cost\n * ingestion, storage rotation) live in `AnalystHooks`. Budget shaping\n * (equal split vs weighted vs custom) lives in `BudgetPolicy`. Both\n * have sensible defaults; consumers override only what they need.\n */\n\nimport { randomUUID } from 'node:crypto'\nimport type { ChatClient } from './chat-client'\nimport type {\n Analyst,\n AnalystContext,\n AnalystFinding,\n AnalystRunEvent,\n AnalystRunInputs,\n AnalystRunResult,\n AnalystRunSummary,\n} from './types'\n\n// ── Hook + policy surfaces ─────────────────────────────────────────\n\nexport interface AnalystHooks {\n /** Before analyze() — last chance to mutate ctx (e.g. inject tags, override budget). */\n onBeforeAnalyze?(args: {\n analyst: Analyst\n ctx: AnalystContext\n runId: string\n }): void | Promise<void>\n /** After every analyst (ok | failed | skipped). Use for telemetry, ingestion, rotation. */\n onAfterAnalyze?(args: {\n analyst: Analyst\n summary: AnalystRunSummary\n findings: AnalystFinding[]\n runId: string\n }): void | Promise<void>\n /**\n * On analyst exception. Hook MAY return findings to convert the\n * error into structured findings; the summary still reports 'failed'.\n * Return void to keep the default empty-findings behavior.\n */\n onError?(args: {\n analyst: Analyst\n error: Error\n runId: string\n }): AnalystFinding[] | undefined | Promise<AnalystFinding[] | undefined>\n /** Once after registry.run() completes. Use for final aggregation, persistence. */\n onComplete?(args: { result: AnalystRunResult }): void | Promise<void>\n}\n\nexport interface BudgetPolicy {\n /** Overall USD cap across the registry.run(). */\n totalUsd?: number\n /** Per-analyst weight for the default allocator. Missing ids get weight 1. */\n weights?: Record<string, number>\n /**\n * Custom allocator — receives the analyst, remaining/total budget, and\n * the count of analysts that will run. Returns the per-analyst budget\n * (or undefined to leave it uncapped). Overrides weights when set.\n */\n allocate?: (args: {\n analyst: Analyst\n totalUsd: number | undefined\n remainingUsd: number | undefined\n runningCount: number\n }) => number | undefined\n}\n\nexport interface AnalystRegistryOptions {\n /** Shared chat client passed to every LLM analyst via AnalystContext. */\n chat?: ChatClient\n /** Logger callback. Defaults to a no-op. */\n log?: (msg: string, fields?: Record<string, unknown>) => void\n /** Hooks invoked around analyze() — observability + customization seam. */\n hooks?: AnalystHooks\n /** Default budget when run() doesn't override. */\n defaultBudget?: BudgetPolicy\n}\n\nexport interface RegistryRunOpts {\n /** Restrict to a subset of registered analysts by id. */\n only?: string[]\n /** Skip these analysts even if registered. Useful for cheap iteration. */\n skip?: string[]\n /** Budget policy — totalUsd + optional weights/allocator. Falls back to options.defaultBudget. */\n budget?: BudgetPolicy\n /** Wall-clock cap. Analysts SHOULD honor `ctx.deadlineMs`. */\n timeoutMs?: number\n /** Abort signal — forwarded into every analyst's context. */\n signal?: AbortSignal\n /** Tags echoed into AnalystContext.tags — useful for tracking environment/version in findings. */\n tags?: Record<string, string>\n /**\n * Prior-run findings made available as retrieval context to every\n * analyst via `ctx.priorFindings`. The registry forwards the slice\n * whose `analyst_id` matches each registered analyst so a kind sees\n * only its own history. Pass `{ '*': findings }` to broadcast to\n * every analyst (useful for cross-kind chaining where the improvement\n * analyst consumes upstream failure findings).\n */\n priorFindings?: ReadonlyArray<AnalystFinding> | Record<string, ReadonlyArray<AnalystFinding>>\n}\n\nexport class AnalystRegistry {\n private readonly analysts = new Map<string, Analyst>()\n private readonly options: AnalystRegistryOptions\n\n constructor(options: AnalystRegistryOptions = {}) {\n this.options = options\n }\n\n register(analyst: Analyst): void {\n if (!analyst.id) throw new Error('AnalystRegistry.register: analyst.id is required')\n if (this.analysts.has(analyst.id)) {\n throw new Error(`AnalystRegistry.register: duplicate analyst id \"${analyst.id}\"`)\n }\n if (!analyst.version) {\n throw new Error(`AnalystRegistry.register: analyst \"${analyst.id}\" must declare a version`)\n }\n this.analysts.set(analyst.id, analyst)\n }\n\n list(): ReadonlyArray<{\n id: string\n description: string\n version: string\n cost: Analyst['cost']\n }> {\n return Array.from(this.analysts.values()).map((a) => ({\n id: a.id,\n description: a.description,\n version: a.version,\n cost: a.cost,\n }))\n }\n\n async run(\n runId: string,\n inputs: AnalystRunInputs,\n runOpts: RegistryRunOpts = {},\n ): Promise<AnalystRunResult> {\n // Thin collector over `runStream`. Both surfaces share the same\n // loop body so they cannot drift on isolation / hook order / cost.\n for await (const ev of this.runStream(runId, inputs, runOpts)) {\n if (ev.type === 'run-completed') return ev.result\n }\n throw new Error('AnalystRegistry.run: stream completed without run-completed event')\n }\n\n /**\n * Streaming counterpart to `run()`. Emits `AnalystRunEvent` values\n * in real time — `run-started`, then per-analyst `skipped` /\n * `started` / `completed`, then a terminal `run-completed` whose\n * payload is the full `AnalystRunResult`. UIs use this to render\n * progress; persistence consumers use `run()` and read the result.\n *\n * Hooks (`onBeforeAnalyze` / `onAfterAnalyze` / `onError` /\n * `onComplete`) fire as before — streaming is additive, not a hook\n * replacement.\n */\n async *runStream(\n runId: string,\n inputs: AnalystRunInputs,\n runOpts: RegistryRunOpts = {},\n ): AsyncGenerator<AnalystRunEvent, void, void> {\n const correlationId = `ar_${randomUUID().slice(0, 12)}`\n const log = this.options.log ?? (() => {})\n const hooks = this.options.hooks ?? {}\n const startedAt = new Date().toISOString()\n const started = Date.now()\n const deadlineMs = runOpts.timeoutMs ? started + runOpts.timeoutMs : undefined\n\n const selected = this.selectAnalysts(runOpts)\n const budget = runOpts.budget ?? this.options.defaultBudget\n\n yield {\n type: 'run-started',\n run_id: runId,\n correlation_id: correlationId,\n started_at: startedAt,\n analyst_ids: selected.map((a) => a.id),\n }\n\n const summaries: AnalystRunSummary[] = []\n const allFindings: AnalystFinding[] = []\n let totalCost = 0\n let remainingUsd = budget?.totalUsd\n\n for (const analyst of selected) {\n const t0 = Date.now()\n const input = this.routeInput(analyst, inputs)\n if (input.kind === 'missing') {\n const summary: AnalystRunSummary = {\n analyst_id: analyst.id,\n status: 'skipped',\n reason: `missing input of kind '${analyst.inputKind}'`,\n findings_count: 0,\n latency_ms: 0,\n cost_usd: 0,\n }\n summaries.push(summary)\n log(`[analyst] skip ${analyst.id} — missing input`, { runId, kind: analyst.inputKind })\n await hooks.onAfterAnalyze?.({ analyst, summary, findings: [], runId })\n yield { type: 'analyst-skipped', summary }\n continue\n }\n\n const perBudget = allocateBudget(budget, {\n analyst,\n remainingUsd,\n runningCount: selected.length,\n })\n\n const ctx: AnalystContext = {\n runId,\n correlationId,\n deadlineMs,\n budgetUsd: perBudget,\n chat: this.options.chat,\n tags: runOpts.tags,\n log: (msg, fields) => log(`[${analyst.id}] ${msg}`, { runId, correlationId, ...fields }),\n signal: runOpts.signal,\n priorFindings: selectPriorFindings(runOpts.priorFindings, analyst.id),\n }\n\n await hooks.onBeforeAnalyze?.({ analyst, ctx, runId })\n yield {\n type: 'analyst-started',\n analyst_id: analyst.id,\n started_at: new Date(t0).toISOString(),\n }\n\n try {\n const findings = await (analyst as Analyst<unknown>).analyze(input.value, ctx)\n const latency = Date.now() - t0\n const cost = sumFindingCost(findings)\n totalCost += cost\n if (typeof remainingUsd === 'number') remainingUsd = Math.max(0, remainingUsd - cost)\n allFindings.push(...findings)\n const summary: AnalystRunSummary = {\n analyst_id: analyst.id,\n status: 'ok',\n findings_count: findings.length,\n latency_ms: latency,\n cost_usd: cost,\n }\n summaries.push(summary)\n log(`[analyst] ok ${analyst.id}`, {\n runId,\n findings: findings.length,\n latency_ms: latency,\n cost_usd: cost,\n })\n await hooks.onAfterAnalyze?.({ analyst, summary, findings, runId })\n yield { type: 'analyst-completed', summary, findings }\n } catch (err) {\n const latency = Date.now() - t0\n const e = err instanceof Error ? err : new Error(String(err))\n // Hook gets first chance to convert the error into findings.\n const hookFindings = (await hooks.onError?.({ analyst, error: e, runId })) ?? []\n if (hookFindings.length) allFindings.push(...hookFindings)\n const summary: AnalystRunSummary = {\n analyst_id: analyst.id,\n status: 'failed',\n findings_count: hookFindings.length,\n latency_ms: latency,\n cost_usd: 0,\n error: { class: e.constructor.name, message: e.message },\n }\n summaries.push(summary)\n log(`[analyst] FAIL ${analyst.id}`, {\n runId,\n error_class: e.constructor.name,\n error: e.message,\n })\n await hooks.onAfterAnalyze?.({ analyst, summary, findings: hookFindings, runId })\n yield { type: 'analyst-completed', summary, findings: hookFindings }\n // Continue — isolation invariant.\n }\n }\n\n const result: AnalystRunResult = {\n run_id: runId,\n correlation_id: correlationId,\n started_at: startedAt,\n ended_at: new Date().toISOString(),\n findings: allFindings,\n per_analyst: summaries,\n total_cost_usd: totalCost,\n }\n await hooks.onComplete?.({ result })\n yield { type: 'run-completed', result }\n }\n\n private selectAnalysts(opts: RegistryRunOpts): Analyst[] {\n let candidates = Array.from(this.analysts.values())\n if (opts.only?.length) {\n const only = new Set(opts.only)\n candidates = candidates.filter((a) => only.has(a.id))\n }\n if (opts.skip?.length) {\n const skip = new Set(opts.skip)\n candidates = candidates.filter((a) => !skip.has(a.id))\n }\n return candidates\n }\n\n private routeInput(\n analyst: Analyst,\n inputs: AnalystRunInputs,\n ): { kind: 'present'; value: unknown } | { kind: 'missing' } {\n switch (analyst.inputKind) {\n case 'trace-store':\n return inputs.traceStore\n ? { kind: 'present', value: inputs.traceStore }\n : { kind: 'missing' }\n case 'artifact-dir':\n return inputs.artifactDir\n ? { kind: 'present', value: inputs.artifactDir }\n : { kind: 'missing' }\n case 'run-record':\n return inputs.runRecord ? { kind: 'present', value: inputs.runRecord } : { kind: 'missing' }\n case 'judge-input':\n return inputs.judgeInput\n ? { kind: 'present', value: inputs.judgeInput }\n : { kind: 'missing' }\n case 'custom': {\n const v = inputs.custom?.[analyst.id]\n return v !== undefined ? { kind: 'present', value: v } : { kind: 'missing' }\n }\n }\n }\n}\n\n/**\n * Default budget allocator: prefer the custom `allocate` callback if\n * provided; else weighted split when weights are set; else equal split\n * across `runningCount`. Returns undefined when no totalUsd is known.\n */\nfunction allocateBudget(\n policy: BudgetPolicy | undefined,\n args: { analyst: Analyst; remainingUsd: number | undefined; runningCount: number },\n): number | undefined {\n if (!policy) return undefined\n if (policy.allocate) {\n return policy.allocate({\n analyst: args.analyst,\n totalUsd: policy.totalUsd,\n remainingUsd: args.remainingUsd,\n runningCount: args.runningCount,\n })\n }\n if (policy.totalUsd == null) return undefined\n if (policy.weights) {\n // Weighted split: caller-supplied weights, default 1 for missing ids.\n // We can only normalize against the analysts in this run, but the\n // registry doesn't know all ids at allocator-time without passing\n // them. We approximate by treating `runningCount` as the count of\n // weight=1 analysts when the weight map omits ids. The exact split\n // is left to consumers that need precision via `allocate`.\n const w = policy.weights[args.analyst.id] ?? 1\n const totalWeight = Math.max(1, args.runningCount) // see note above\n return (policy.totalUsd * w) / totalWeight\n }\n return policy.totalUsd / Math.max(1, args.runningCount)\n}\n\n/**\n * Findings may carry their cost in `metadata.cost_usd` when the analyst\n * tracks it (the LLM-driven adapters do this — they sum chat-client\n * responses). Deterministic findings have no cost field.\n */\nfunction sumFindingCost(findings: AnalystFinding[]): number {\n let sum = 0\n for (const f of findings) {\n const c = f.metadata?.cost_usd\n if (typeof c === 'number' && Number.isFinite(c)) sum += c\n }\n return sum\n}\n\n/**\n * Resolve the `priorFindings` slice an analyst sees.\n *\n * - Array form → the analyst sees only findings whose `analyst_id`\n * matches its own id, so a kind never reads\n * another kind's history by accident.\n * - Record form → the analyst gets the entry keyed by its id, with\n * the `'*'` wildcard appended (in that order). Use\n * the wildcard for cross-kind chaining, e.g. when\n * `improvement` should see all upstream failure /\n * gap / poisoning findings.\n */\nfunction selectPriorFindings(\n source: RegistryRunOpts['priorFindings'],\n analystId: string,\n): ReadonlyArray<AnalystFinding> | undefined {\n if (!source) return undefined\n if (Array.isArray(source)) {\n const own = source.filter((f) => f.analyst_id === analystId)\n return own.length > 0 ? own : undefined\n }\n const record = source as Record<string, ReadonlyArray<AnalystFinding>>\n const own = record[analystId] ?? []\n const wildcard = record['*'] ?? []\n const merged = [...own, ...wildcard]\n return merged.length > 0 ? merged : undefined\n}\n","/**\n * Automated pull request opener for the production loop.\n *\n * `runProductionLoop` produces a `promotedPrompt` string and a release\n * scorecard. To close the eval → prod → eval cycle the framework needs\n * to land that prompt as a reviewable code change. This module does\n * exactly that:\n *\n * 1. Stage a branch off `baseBranch`.\n * 2. Write each `fileChange` into the worktree.\n * 3. Commit + push.\n * 4. Open a PR via the GitHub API.\n *\n * Two transports ship in core:\n *\n * - `ghCliClient(opts)` — shells out to the `gh` CLI. No extra deps,\n * re-uses the developer machine's `gh auth` state, works with both\n * github.com and GitHub Enterprise. This is the recommended default.\n * - `httpGithubClient(opts)` — direct `fetch` against `api.github.com`\n * with a bearer token. Useful in CI where `gh` may not be installed.\n *\n * Both implement the small `AutoPrClient` interface, so tests substitute\n * a fake without spinning a process or network.\n *\n * @experimental — surface may evolve as consumers wire it into CI workflows.\n */\n\nimport { ConfigError, ValidationError } from './errors'\n\nexport interface FileChange {\n /** Repo-relative path. Forward slashes; no `..`. */\n path: string\n /** New file contents. UTF-8. */\n contents: string\n /** Optional explanatory comment shown in the commit body. */\n rationale?: string\n}\n\nexport interface RepoRef {\n owner: string\n name: string\n}\n\nexport interface ProposeAutomatedPullRequestInput {\n repo: RepoRef\n /** Branch to base the PR on. Default `'main'`. */\n baseBranch?: string\n /** New branch name. Use a prefix + a short stable id; no spaces. */\n branchName: string\n fileChanges: FileChange[]\n title: string\n body: string\n /** Optional GitHub usernames to request review from. */\n reviewers?: string[]\n /** Optional labels to apply. */\n labels?: string[]\n /** Commit author name. Default: derived from the GitHub client. */\n authorName?: string\n /** Commit author email. Default: derived from the GitHub client. */\n authorEmail?: string\n /** Dry-run — do not push or open a PR; just return the would-be plan. */\n dryRun?: boolean\n}\n\nexport interface ProposeAutomatedPullRequestResult {\n prUrl: string\n branchName: string\n headSha: string\n dryRun: boolean\n}\n\n/** Pluggable transport for the auto-PR pipeline. */\nexport interface AutoPrClient {\n /**\n * Create a branch from `baseBranch`, write file changes, commit, push,\n * and open a PR. Returns the PR's HTML url and head SHA.\n *\n * Implementations must be idempotent on `branchName`: if the branch\n * already exists with the same head SHA as the would-be commit, return\n * the existing PR rather than failing. This makes the production loop\n * safe to retry on transient errors.\n */\n proposeChange(input: ProposeAutomatedPullRequestInput): Promise<ProposeAutomatedPullRequestResult>\n}\n\nexport async function proposeAutomatedPullRequest(\n client: AutoPrClient,\n input: ProposeAutomatedPullRequestInput,\n): Promise<ProposeAutomatedPullRequestResult> {\n validate(input)\n return client.proposeChange(input)\n}\n\nfunction validate(input: ProposeAutomatedPullRequestInput): void {\n if (!input.repo.owner.trim() || !input.repo.name.trim()) {\n throw new ValidationError('proposeAutomatedPullRequest: repo.owner and repo.name required')\n }\n if (!input.branchName.trim() || /\\s/.test(input.branchName)) {\n throw new ValidationError(\n 'proposeAutomatedPullRequest: branchName must be non-empty and contain no whitespace',\n )\n }\n if (input.branchName === (input.baseBranch ?? 'main')) {\n throw new ValidationError('proposeAutomatedPullRequest: branchName must differ from baseBranch')\n }\n if (input.fileChanges.length === 0) {\n throw new ValidationError('proposeAutomatedPullRequest: fileChanges must not be empty')\n }\n const seenPaths = new Set<string>()\n for (const change of input.fileChanges) {\n if (!change.path.trim() || change.path.includes('..') || change.path.startsWith('/')) {\n throw new ValidationError(\n `proposeAutomatedPullRequest: invalid file path \"${change.path}\" (no '..' or leading '/')`,\n )\n }\n if (seenPaths.has(change.path)) {\n throw new ValidationError(`proposeAutomatedPullRequest: duplicate file path \"${change.path}\"`)\n }\n seenPaths.add(change.path)\n }\n if (!input.title.trim()) {\n throw new ValidationError('proposeAutomatedPullRequest: title must not be empty')\n }\n}\n\n// ── HTTP transport (uses `fetch` against api.github.com) ─────────────\n\nexport interface HttpGithubClientOptions {\n /** Personal access token, GitHub App token, or `GITHUB_TOKEN` from Actions. */\n token: string\n /** Override for GitHub Enterprise. Default `'https://api.github.com'`. */\n apiBase?: string\n /** Test seam — defaults to global `fetch`. */\n fetchImpl?: typeof fetch\n /** Test seam — clock for commit timestamps. */\n now?: () => Date\n}\n\ninterface GhRef {\n ref: string\n object: { sha: string }\n}\n\ninterface GhCommit {\n sha: string\n tree: { sha: string }\n}\n\ninterface GhBlob {\n sha: string\n}\n\ninterface GhTree {\n sha: string\n}\n\ninterface GhPullRequest {\n html_url: string\n number: number\n}\n\n/**\n * Direct REST-API GitHub client. No external deps.\n *\n * Idempotency strategy: before creating refs/commits/PRs, check whether\n * the branch already exists at the desired tree. If so, return the\n * existing PR (or open one if missing). Errors from concurrent runs\n * (`Reference already exists`) are caught and treated as success.\n */\nexport function httpGithubClient(opts: HttpGithubClientOptions): AutoPrClient {\n const fetchImpl = opts.fetchImpl ?? fetch\n const apiBase = (opts.apiBase ?? 'https://api.github.com').replace(/\\/+$/, '')\n const now = opts.now ?? (() => new Date())\n\n async function api<T>(\n method: string,\n path: string,\n body?: unknown,\n accept404 = false,\n ): Promise<T | null> {\n const res = await fetchImpl(`${apiBase}${path}`, {\n method,\n headers: {\n accept: 'application/vnd.github+json',\n 'content-type': 'application/json',\n authorization: `Bearer ${opts.token}`,\n 'x-github-api-version': '2022-11-28',\n },\n body: body === undefined ? undefined : JSON.stringify(body),\n })\n if (accept404 && res.status === 404) return null\n if (!res.ok) {\n const text = await res.text().catch(() => '')\n throw new ConfigError(\n `proposeAutomatedPullRequest: GitHub ${method} ${path} → ${res.status} ${text.slice(0, 400)}`,\n )\n }\n return (await res.json()) as T\n }\n\n return {\n async proposeChange(input) {\n const baseBranch = input.baseBranch ?? 'main'\n const repoPath = `/repos/${input.repo.owner}/${input.repo.name}`\n\n if (input.dryRun) {\n return {\n prUrl: `https://github.com/${input.repo.owner}/${input.repo.name}/compare/${baseBranch}...${input.branchName}`,\n branchName: input.branchName,\n headSha: 'dry-run',\n dryRun: true,\n }\n }\n\n // 1. Find base SHA\n const baseRef = await api<GhRef>('GET', `${repoPath}/git/ref/heads/${baseBranch}`)\n if (!baseRef) {\n throw new ConfigError(`proposeAutomatedPullRequest: base branch \"${baseBranch}\" not found`)\n }\n const baseSha = baseRef.object.sha\n const baseCommit = await api<GhCommit>('GET', `${repoPath}/git/commits/${baseSha}`)\n if (!baseCommit) {\n throw new ConfigError(\n `proposeAutomatedPullRequest: base commit ${baseSha} not found (race condition?)`,\n )\n }\n\n // 2. Create blobs for each file\n const treeEntries = []\n for (const change of input.fileChanges) {\n const blob = await api<GhBlob>('POST', `${repoPath}/git/blobs`, {\n content: change.contents,\n encoding: 'utf-8',\n })\n if (!blob) throw new ConfigError('proposeAutomatedPullRequest: blob creation returned null')\n treeEntries.push({\n path: change.path,\n mode: '100644',\n type: 'blob',\n sha: blob.sha,\n })\n }\n\n // 3. Create tree\n const tree = await api<GhTree>('POST', `${repoPath}/git/trees`, {\n base_tree: baseCommit.tree.sha,\n tree: treeEntries,\n })\n if (!tree) throw new ConfigError('proposeAutomatedPullRequest: tree creation returned null')\n\n // 4. Create commit\n const author =\n input.authorName && input.authorEmail\n ? { name: input.authorName, email: input.authorEmail, date: now().toISOString() }\n : undefined\n const commitMessage = renderCommitMessage(input)\n const commit = await api<GhCommit>('POST', `${repoPath}/git/commits`, {\n message: commitMessage,\n tree: tree.sha,\n parents: [baseSha],\n ...(author ? { author, committer: author } : {}),\n })\n if (!commit)\n throw new ConfigError('proposeAutomatedPullRequest: commit creation returned null')\n\n // 5. Create or fast-forward branch ref (idempotent on existing branch).\n const existing = await api<GhRef>(\n 'GET',\n `${repoPath}/git/ref/heads/${input.branchName}`,\n undefined,\n true,\n )\n if (!existing) {\n await api('POST', `${repoPath}/git/refs`, {\n ref: `refs/heads/${input.branchName}`,\n sha: commit.sha,\n })\n } else if (existing.object.sha !== commit.sha) {\n await api('PATCH', `${repoPath}/git/refs/heads/${input.branchName}`, {\n sha: commit.sha,\n force: true,\n })\n }\n\n // 6. Open PR (or find an existing open one for the same branch).\n const openPrs = await api<GhPullRequest[]>(\n 'GET',\n `${repoPath}/pulls?state=open&head=${encodeURIComponent(`${input.repo.owner}:${input.branchName}`)}`,\n )\n let pr: GhPullRequest\n if (openPrs && openPrs.length > 0) {\n pr = openPrs[0] as GhPullRequest\n } else {\n const created = await api<GhPullRequest>('POST', `${repoPath}/pulls`, {\n title: input.title,\n body: input.body,\n head: input.branchName,\n base: baseBranch,\n })\n if (!created)\n throw new ConfigError('proposeAutomatedPullRequest: PR creation returned null')\n pr = created\n }\n\n if (input.reviewers && input.reviewers.length > 0) {\n await api(\n 'POST',\n `${repoPath}/pulls/${pr.number}/requested_reviewers`,\n { reviewers: input.reviewers },\n true,\n ).catch(() => {\n /* reviewer assignment is best-effort */\n })\n }\n if (input.labels && input.labels.length > 0) {\n await api(\n 'POST',\n `${repoPath}/issues/${pr.number}/labels`,\n { labels: input.labels },\n true,\n ).catch(() => {\n /* label assignment is best-effort */\n })\n }\n\n return {\n prUrl: pr.html_url,\n branchName: input.branchName,\n headSha: commit.sha,\n dryRun: false,\n }\n },\n }\n}\n\n// ── gh CLI transport (no fetch needed, re-uses developer auth) ──────\n\nexport interface GhCliClientOptions {\n /** Override the CLI binary (`gh`). For testing. */\n bin?: string\n /** Working directory containing a clone of `repo`. Default: process cwd. */\n cwd?: string\n /** Test seam: process spawner. Default: node:child_process spawn. */\n exec?: (\n bin: string,\n args: string[],\n opts: { cwd: string; stdin?: string },\n ) => Promise<{ stdout: string; stderr: string; exitCode: number }>\n}\n\n/**\n * `gh` CLI transport. Requires:\n * - `gh` installed and authenticated (`gh auth status`).\n * - A local clone of the repo with a clean working tree.\n * - `git` on PATH.\n *\n * Uses `gh api` for repo metadata and `gh pr create` for the PR. The\n * actual commit lands via `git`, which keeps `gh`'s footprint minimal.\n */\nexport function ghCliClient(opts: GhCliClientOptions = {}): AutoPrClient {\n const bin = opts.bin ?? 'gh'\n const cwd = opts.cwd ?? process.cwd()\n const exec = opts.exec ?? defaultExec\n\n async function run(\n cmd: string,\n args: string[],\n stdin?: string,\n ): Promise<{ stdout: string; stderr: string }> {\n const r = await exec(cmd, args, { cwd, stdin })\n if (r.exitCode !== 0) {\n throw new ConfigError(\n `proposeAutomatedPullRequest: ${cmd} ${args.join(' ')} failed (${r.exitCode}): ${r.stderr.trim() || r.stdout.trim()}`,\n )\n }\n return r\n }\n\n return {\n async proposeChange(input) {\n const baseBranch = input.baseBranch ?? 'main'\n if (input.dryRun) {\n return {\n prUrl: `https://github.com/${input.repo.owner}/${input.repo.name}/compare/${baseBranch}...${input.branchName}`,\n branchName: input.branchName,\n headSha: 'dry-run',\n dryRun: true,\n }\n }\n\n // Ensure we're working in a clean tree on the base branch.\n await run('git', ['fetch', 'origin', baseBranch])\n await run('git', ['checkout', baseBranch])\n await run('git', ['reset', '--hard', `origin/${baseBranch}`])\n\n // Branch (idempotent: delete if exists, then re-create from base).\n await exec('git', ['branch', '-D', input.branchName], { cwd })\n await run('git', ['checkout', '-b', input.branchName])\n\n // Write file changes.\n const { mkdir, writeFile } = await import('node:fs/promises')\n const { dirname, join, resolve } = await import('node:path')\n for (const change of input.fileChanges) {\n const abs = resolve(cwd, change.path)\n await mkdir(dirname(abs), { recursive: true })\n await writeFile(abs, change.contents, 'utf8')\n await run('git', ['add', join(change.path)])\n }\n\n // Commit.\n const env: Record<string, string> = {}\n if (input.authorName) env.GIT_AUTHOR_NAME = input.authorName\n if (input.authorEmail) env.GIT_AUTHOR_EMAIL = input.authorEmail\n if (input.authorName) env.GIT_COMMITTER_NAME = input.authorName\n if (input.authorEmail) env.GIT_COMMITTER_EMAIL = input.authorEmail\n const message = renderCommitMessage(input)\n await run('git', ['commit', '-m', message])\n\n const headRes = await run('git', ['rev-parse', 'HEAD'])\n const headSha = headRes.stdout.trim()\n\n // Push.\n await run('git', ['push', '-f', 'origin', input.branchName])\n\n // Open PR (idempotent: `gh pr create` errors if one exists).\n const existing = await exec(\n bin,\n [\n 'pr',\n 'list',\n '--state',\n 'open',\n '--head',\n input.branchName,\n '--json',\n 'url,number',\n '--limit',\n '1',\n ],\n { cwd },\n )\n let prUrl = ''\n if (existing.exitCode === 0 && existing.stdout.trim()) {\n const parsed = JSON.parse(existing.stdout) as Array<{ url: string }>\n if (parsed.length > 0 && parsed[0]) prUrl = parsed[0].url\n }\n if (!prUrl) {\n const args = [\n 'pr',\n 'create',\n '--title',\n input.title,\n '--body',\n input.body,\n '--base',\n baseBranch,\n ]\n if (input.reviewers && input.reviewers.length > 0) {\n args.push('--reviewer', input.reviewers.join(','))\n }\n if (input.labels && input.labels.length > 0) {\n args.push('--label', input.labels.join(','))\n }\n const r = await run(bin, args)\n const match = r.stdout.match(/https?:\\/\\/\\S+/)\n prUrl = match ? match[0] : r.stdout.trim()\n }\n\n return { prUrl, branchName: input.branchName, headSha, dryRun: false }\n },\n }\n}\n\nasync function defaultExec(\n bin: string,\n args: string[],\n opts: { cwd: string; stdin?: string },\n): Promise<{ stdout: string; stderr: string; exitCode: number }> {\n const { spawn } = await import('node:child_process')\n return new Promise((resolveExec) => {\n const child = spawn(bin, args, { cwd: opts.cwd })\n let stdout = ''\n let stderr = ''\n child.stdout.on('data', (d) => {\n stdout += d.toString()\n })\n child.stderr.on('data', (d) => {\n stderr += d.toString()\n })\n if (opts.stdin) child.stdin.end(opts.stdin)\n child.on('error', (err) => {\n resolveExec({ stdout, stderr: `${stderr}${err.message}`, exitCode: 1 })\n })\n child.on('close', (code) => {\n resolveExec({ stdout, stderr, exitCode: code ?? 1 })\n })\n })\n}\n\nfunction renderCommitMessage(input: ProposeAutomatedPullRequestInput): string {\n const lines = [input.title, '']\n for (const change of input.fileChanges) {\n if (change.rationale) lines.push(`- ${change.path}: ${change.rationale}`)\n }\n if (lines[lines.length - 1] !== '') lines.push('')\n lines.push(input.body.trim())\n return lines.join('\\n').trim()\n}\n","import type { TCloud } from '@tangle-network/tcloud'\nimport { normalizeScores, weightedMean } from './statistics'\nimport type {\n CollectedArtifacts,\n JudgeFn,\n JudgeScore,\n Scenario,\n ScenarioResult,\n TurnResult,\n} from './types'\n\ninterface ChatMessage {\n role: 'system' | 'user' | 'assistant'\n content: string\n}\n\nexport interface ExecutorConfig {\n /** System prompt for the agent under test */\n systemPrompt: string\n /** Model to use for the agent */\n model?: string\n /** Judges to run after execution */\n judges: JudgeFn[]\n /** Regex patterns for detecting tool/API calls in responses */\n toolCallPatterns?: RegExp[]\n /** Block delimiter pattern (default: :::type\\n...\\n:::) */\n blockPattern?: RegExp\n /** Custom artifact checker for domain-specific checks */\n artifactChecker?: (\n check: Scenario['artifactChecks'][0],\n artifacts: CollectedArtifacts,\n ) => { passed: boolean; detail: string } | null\n}\n\n/**\n * Execute a scenario against an LLM via tcloud.\n *\n * Runs multi-turn conversation, extracts artifacts, runs judges.\n */\nexport async function executeScenario(\n tc: TCloud,\n scenario: Scenario,\n config: ExecutorConfig,\n): Promise<ScenarioResult> {\n const startTime = Date.now()\n const model = config.model ?? 'gpt-4o'\n\n const systemPrompt = [config.systemPrompt, scenario.systemPromptAppend ?? '']\n .filter(Boolean)\n .join('\\n\\n')\n\n const messages: ChatMessage[] = [{ role: 'system', content: systemPrompt }]\n\n const turns: TurnResult[] = []\n const allCodeBlocks: { language: string; code: string }[] = []\n const allBlocks: { type: string; fields: Record<string, string> }[] = []\n const allToolCalls: string[] = []\n\n const blockRe = config.blockPattern ?? /:::(\\w+)\\s*\\n([\\s\\S]*?)\\n\\s*:::/g\n\n for (let i = 0; i < scenario.turns.length; i++) {\n const turn = scenario.turns[i]!\n const turnStart = Date.now()\n\n messages.push({ role: 'user', content: turn.user })\n\n const resp = await tc.chat({\n model,\n messages,\n temperature: 0.4,\n maxTokens: 3000,\n })\n\n const content =\n (resp as { choices?: { message?: { content?: string } }[] }).choices?.[0]?.message?.content ??\n ''\n\n messages.push({ role: 'assistant', content })\n\n // Extract code blocks\n const codeRe = /```(\\w+)?\\n([\\s\\S]*?)```/g\n let codeMatch\n while ((codeMatch = codeRe.exec(content)) !== null) {\n allCodeBlocks.push({ language: codeMatch[1] ?? 'text', code: codeMatch[2] ?? '' })\n }\n\n // Extract structured blocks\n const turnBlocks: { type: string; title: string }[] = []\n let blockMatch\n const blockReLocal = new RegExp(blockRe.source, blockRe.flags)\n while ((blockMatch = blockReLocal.exec(content)) !== null) {\n const fields: Record<string, string> = {}\n for (const line of (blockMatch[2] ?? '').split('\\n')) {\n const idx = line.indexOf(':')\n if (idx > 0) fields[line.slice(0, idx).trim()] = line.slice(idx + 1).trim()\n }\n const blockType = blockMatch[1] ?? ''\n allBlocks.push({ type: blockType, fields })\n turnBlocks.push({ type: blockType, title: fields.title ?? '' })\n }\n\n // Detect tool calls via configurable patterns\n let hasToolCall = false\n if (config.toolCallPatterns) {\n for (const pattern of config.toolCallPatterns) {\n const re = new RegExp(pattern.source, pattern.flags)\n let toolMatch\n while ((toolMatch = re.exec(content)) !== null) {\n allToolCalls.push(toolMatch[0])\n hasToolCall = true\n }\n }\n }\n\n turns.push({\n turnIndex: i,\n userMessage: turn.user,\n agentResponse: content,\n durationMs: Date.now() - turnStart,\n blocksExtracted: turnBlocks,\n containsCode: allCodeBlocks.length > 0,\n containsToolCall: hasToolCall,\n })\n }\n\n const artifacts: CollectedArtifacts = {\n vaultFiles: [],\n blocksExtracted: allBlocks,\n codeBlocks: allCodeBlocks,\n toolCalls: allToolCalls,\n }\n\n // Run artifact checks\n const artifactResults = scenario.artifactChecks.map((check) => {\n // Try custom checker first\n if (config.artifactChecker) {\n const custom = config.artifactChecker(check, artifacts)\n if (custom) return { check, ...custom }\n }\n\n switch (check.type) {\n case 'block_extracted': {\n const count = allBlocks.filter((b) => b.type === check.target).length\n return {\n check,\n passed: count >= (check.minCount ?? 1),\n detail: `Found ${count} ${check.target} blocks (need ${check.minCount ?? 1})`,\n }\n }\n case 'code_valid': {\n const hasCode = allCodeBlocks.some(\n (b) => b.language === check.target || b.code.includes(check.target),\n )\n return { check, passed: hasCode, detail: hasCode ? 'Code block found' : 'No matching code' }\n }\n default:\n return {\n check,\n passed: false,\n detail: `Check type \"${check.type}\" requires live environment`,\n }\n }\n })\n\n // Run judges sequentially with retry\n const judgeInput = { scenario, turns, artifacts }\n const judgeResults: JudgeScore[][] = []\n\n for (const judge of config.judges) {\n let lastErr = ''\n for (let attempt = 0; attempt < 3; attempt++) {\n try {\n if (attempt > 0) {\n const wait = attempt * 10_000\n console.log(` judge retry ${attempt}/2 (waiting ${wait / 1000}s)`)\n await new Promise((r) => setTimeout(r, wait))\n }\n const scores = await judge(tc, judgeInput)\n judgeResults.push(scores)\n await new Promise((r) => setTimeout(r, 3000))\n break\n } catch (err) {\n lastErr = err instanceof Error ? err.message : String(err)\n if (attempt === 2) {\n judgeResults.push([\n {\n judgeName: 'unknown',\n dimension: 'error',\n score: 0,\n reasoning: `Judge failed after 3 attempts: ${lastErr.slice(0, 200)}`,\n },\n ])\n }\n }\n }\n }\n\n const allScores = judgeResults.flat()\n const errorScores = allScores.filter(\n (s) => s.dimension === 'parse_error' || s.dimension === 'error',\n )\n const validScores = allScores.filter(\n (s) => s.dimension !== 'parse_error' && s.dimension !== 'error',\n )\n const normalized = normalizeScores(validScores)\n\n // Build weight map from scenario rubric dimensions\n const weightMap = new Map<string, number>()\n for (const dim of scenario.dimensions) {\n weightMap.set(dim, 1)\n }\n\n const overallScore = weightedMean(\n normalized.map((s) => ({\n score: s.score,\n weight: weightMap.get(s.dimension) ?? 1,\n })),\n )\n\n return {\n scenarioId: scenario.id,\n persona: scenario.persona,\n turns,\n artifactResults,\n judgeScores: allScores,\n judgeErrors: errorScores.length,\n overallScore,\n totalDurationMs: Date.now() - startTime,\n artifacts,\n }\n}\n","import type { TCloud } from '@tangle-network/tcloud'\nimport { executeScenario } from './executor'\nimport type { BenchmarkReport, BenchmarkRunnerConfig, Scenario, ScenarioResult } from './types'\n\n/**\n * BenchmarkRunner — orchestrates scenarios, executor, judges, and scoring.\n *\n * Domain-agnostic. Each agent provides its own scenarios, judges, and system prompt.\n */\nexport class BenchmarkRunner {\n private tc: TCloud\n private config: BenchmarkRunnerConfig\n\n constructor(tc: TCloud, config: BenchmarkRunnerConfig) {\n this.tc = tc\n this.config = config\n }\n\n async run(scenarios?: Scenario[]): Promise<BenchmarkReport> {\n const toRun = scenarios ?? this.config.scenarios\n const passThreshold = this.config.passThreshold ?? 6.0\n\n console.log('='.repeat(70))\n console.log(' AGENT EVAL — BENCHMARK')\n console.log(' Multi-turn scenarios x Multi-judge panel')\n console.log('='.repeat(70))\n console.log(`Scenarios: ${toRun.length}`)\n console.log(`Judges: ${this.config.judges.length}`)\n console.log(`Model: ${this.config.model ?? 'gpt-4o'}`)\n console.log()\n\n const results: ScenarioResult[] = []\n\n for (let i = 0; i < toRun.length; i++) {\n const scenario = toRun[i]!\n console.log(`[${i + 1}/${toRun.length}] ${scenario.id} (${scenario.persona})`)\n console.log(` thesis: ${scenario.thesis}`)\n console.log(` turns: ${scenario.turns.length}`)\n\n const result = await executeScenario(this.tc, scenario, {\n systemPrompt: this.config.systemPrompt,\n model: this.config.model,\n judges: this.config.judges,\n })\n results.push(result)\n\n // Print turn summaries\n for (const turn of result.turns) {\n const codeIcon = turn.containsCode ? '[code]' : ''\n const toolIcon = turn.containsToolCall ? '[tool]' : ''\n const blockCount = turn.blocksExtracted.length\n const blockIcon = blockCount > 0 ? `[blocks:${blockCount}]` : ''\n console.log(\n ` turn ${turn.turnIndex + 1}: ${(turn.durationMs / 1000).toFixed(1)}s ${codeIcon} ${toolIcon} ${blockIcon} (${turn.agentResponse.length} chars)`,\n )\n }\n\n // Print artifact results\n for (const ar of result.artifactResults) {\n const icon = ar.passed ? '+' : 'X'\n console.log(` artifact: [${icon}] ${ar.check.description} — ${ar.detail}`)\n }\n\n // Print judge scores\n console.log(` judges:`)\n const byJudge: Record<string, { scores: number[]; dimensions: string[] }> = {}\n for (const js of result.judgeScores) {\n const entry = byJudge[js.judgeName] ?? { scores: [], dimensions: [] }\n entry.scores.push(js.score)\n entry.dimensions.push(`${js.dimension}=${js.score}`)\n byJudge[js.judgeName] = entry\n }\n for (const [name, data] of Object.entries(byJudge)) {\n const avg = (data.scores.reduce((a, b) => a + b, 0) / data.scores.length).toFixed(1)\n console.log(` ${name.padEnd(16)} avg=${avg} [${data.dimensions.join(', ')}]`)\n }\n\n console.log(\n ` OVERALL: ${result.overallScore.toFixed(1)}/10 (${(result.totalDurationMs / 1000).toFixed(0)}s)`,\n )\n console.log()\n }\n\n // Build summary\n const byPersona: Record<string, { avg: number; passed: number; total: number }> = {}\n const byDimension: Record<string, { avg: number; scores: number[] }> = {}\n\n for (const r of results) {\n const personaEntry = byPersona[r.persona] ?? { avg: 0, passed: 0, total: 0 }\n personaEntry.total++\n personaEntry.avg += r.overallScore\n if (r.overallScore >= passThreshold) personaEntry.passed++\n byPersona[r.persona] = personaEntry\n\n for (const js of r.judgeScores) {\n const dimEntry = byDimension[js.dimension] ?? { avg: 0, scores: [] }\n dimEntry.scores.push(js.score)\n byDimension[js.dimension] = dimEntry\n }\n }\n\n for (const p of Object.values(byPersona)) {\n p.avg = p.total > 0 ? p.avg / p.total : 0\n }\n for (const d of Object.values(byDimension)) {\n d.avg = d.scores.length > 0 ? d.scores.reduce((a, b) => a + b, 0) / d.scores.length : 0\n }\n\n const sorted = [...results].sort((a, b) => a.overallScore - b.overallScore)\n const weakest = sorted.slice(0, 3).map((r) => ({\n scenario: r.scenarioId,\n score: r.overallScore,\n reason:\n r.judgeScores\n .filter((s) => s.score < passThreshold)\n .map((s) => `${s.dimension}=${s.score}`)\n .join(', ') || 'close to threshold',\n }))\n const strongest = sorted\n .slice(-3)\n .reverse()\n .map((r) => ({\n scenario: r.scenarioId,\n score: r.overallScore,\n reason:\n r.judgeScores\n .filter((s) => s.score >= 9)\n .map((s) => `${s.dimension}=${s.score}`)\n .join(', ') || 'consistently strong',\n }))\n\n // Print final summary\n console.log('='.repeat(70))\n console.log(' RESULTS')\n console.log('='.repeat(70))\n\n const overallAvg =\n results.length > 0 ? results.reduce((s, r) => s + r.overallScore, 0) / results.length : 0\n\n console.log(`Overall: ${overallAvg.toFixed(1)}/10`)\n console.log()\n\n console.log('By persona:')\n for (const [name, data] of Object.entries(byPersona)) {\n console.log(\n ` ${name.padEnd(20)} ${data.avg.toFixed(1)}/10 (${data.passed}/${data.total} passed)`,\n )\n }\n console.log()\n\n console.log('By dimension:')\n const dimEntries = Object.entries(byDimension).sort((a, b) => a[1].avg - b[1].avg)\n for (const [name, data] of dimEntries) {\n const min = Math.min(...data.scores)\n const max = Math.max(...data.scores)\n console.log(\n ` ${name.padEnd(24)} avg=${data.avg.toFixed(1)} range=[${min}-${max}] n=${data.scores.length}`,\n )\n }\n console.log()\n\n if (weakest.length > 0) {\n console.log('Weakest:')\n for (const w of weakest) {\n console.log(` ${w.scenario}: ${w.score.toFixed(1)} — ${w.reason}`)\n }\n console.log()\n }\n\n return {\n timestamp: new Date().toISOString(),\n generation: this.config.generation ?? 1,\n promptVersion: this.config.promptVersion ?? 'v1',\n scenarioCount: toRun.length,\n results,\n summary: { overallAvg, byPersona, byDimension, weakest, strongest },\n }\n }\n}\n","import type { CheckResult, ProductClientConfig, RouteMap, TestResult } from './types'\n\n/**\n * ProductClient — configurable HTTP client for exercising any agent's APIs.\n *\n * Routes are config, not hardcoded. Each agent provides its own RouteMap.\n */\nexport class ProductClient {\n private baseUrl: string\n private routes: RouteMap\n private cookies: string = ''\n\n constructor(config: ProductClientConfig) {\n this.baseUrl = config.baseUrl.replace(/\\/+$/, '')\n this.routes = config.routes\n }\n\n private route(name: keyof RouteMap): string {\n const path = this.routes[name]\n if (!path) throw new Error(`Route \"${name}\" not configured`)\n return path\n }\n\n async signup(name: string, email: string, password: string): Promise<{ userId: string }> {\n const res = await this.post(this.route('signup'), { name, email, password })\n const user = res.user as Record<string, unknown> | undefined\n if (!user?.id) throw new Error(`Signup failed: ${JSON.stringify(res)}`)\n return { userId: user.id as string }\n }\n\n async login(email: string, password: string): Promise<void> {\n const res = await fetch(`${this.baseUrl}${this.route('login')}`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', Origin: this.baseUrl },\n body: JSON.stringify({ email, password }),\n redirect: 'manual',\n })\n const setCookie = res.headers.get('set-cookie')\n if (setCookie) {\n this.cookies = setCookie.split(';')[0] ?? ''\n }\n const body = (await res.json()) as Record<string, unknown>\n if (!body.user) throw new Error(`Login failed: ${JSON.stringify(body)}`)\n }\n\n async createWorkspace(name: string, type = 'project'): Promise<string> {\n const res = await this.post(this.route('workspaces'), { name, type })\n const ws = res.workspace as Record<string, unknown> | undefined\n if (!ws?.id) throw new Error(`Workspace creation failed: ${JSON.stringify(res)}`)\n return ws.id as string\n }\n\n async createThread(workspaceId: string): Promise<string> {\n const res = await this.post(this.route('threads'), { workspaceId })\n const thread = res.thread as Record<string, unknown> | undefined\n if (!thread?.id) throw new Error(`Thread creation failed: ${JSON.stringify(res)}`)\n return thread.id as string\n }\n\n async chat(\n workspaceId: string,\n threadId: string,\n content: string,\n _opts?: { blockPatterns?: RegExp[] },\n ): Promise<{ text: string; blocks: { type: string; title: string }[] }> {\n const res = await fetch(`${this.baseUrl}${this.route('chat')}`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Origin: this.baseUrl,\n Cookie: this.cookies,\n },\n body: JSON.stringify({ workspaceId, threadId, content }),\n })\n\n if (!res.ok || !res.body) throw new Error(`Chat failed: ${res.status}`)\n\n // Parse NDJSON stream\n const reader = res.body.getReader()\n const decoder = new TextDecoder()\n let buf = ''\n let text = ''\n const blocks: { type: string; title: string }[] = []\n\n while (true) {\n const { done, value } = await reader.read()\n if (done) break\n buf += decoder.decode(value, { stream: true })\n const lines = buf.split('\\n')\n buf = lines.pop() ?? ''\n for (const line of lines) {\n if (!line.trim()) continue\n try {\n const event = JSON.parse(line) as { type?: string; data?: { delta?: string } }\n if (event.type === 'message.part.updated' && event.data?.delta) {\n text += event.data.delta\n }\n } catch {\n /* skip non-JSON lines */\n }\n }\n }\n\n // Extract :::blocks from text\n const blockRe = /:::(\\w+)\\s*\\n([\\s\\S]*?)\\n\\s*:::/g\n let match\n while ((match = blockRe.exec(text)) !== null) {\n const fields: Record<string, string> = {}\n for (const line of match[2]!.split('\\n')) {\n const idx = line.indexOf(':')\n if (idx > 0) fields[line.slice(0, idx).trim()] = line.slice(idx + 1).trim()\n }\n blocks.push({ type: match[1]!, title: fields.title ?? '' })\n }\n\n return { text, blocks }\n }\n\n async getTasks(\n workspaceId: string,\n ): Promise<{ id: string; title: string; status: string; priority: string }[]> {\n const res = await this.get(`${this.route('tasks')}?workspaceId=${workspaceId}`)\n return (res.tasks ?? []) as { id: string; title: string; status: string; priority: string }[]\n }\n\n async getEvents(workspaceId: string): Promise<{ id: string; title: string; type: string }[]> {\n const res = await this.get(`${this.route('events')}?workspaceId=${workspaceId}`)\n return (res.events ?? []) as { id: string; title: string; type: string }[]\n }\n\n async getApprovals(\n workspaceId: string,\n ): Promise<{ id: string; title: string; status: string; type: string }[]> {\n const res = await this.get(`${this.route('approvals')}?workspaceId=${workspaceId}`)\n return (res.actions ?? []) as { id: string; title: string; status: string; type: string }[]\n }\n\n async getVaultTree(workspaceId: string): Promise<string[]> {\n const res = await this.get(`${this.route('vault')}?workspaceId=${workspaceId}`)\n const paths: string[] = []\n function extract(nodes: unknown[]) {\n for (const n of nodes) {\n const node = n as { path?: string; type?: string; children?: unknown[] }\n if (node.type === 'file' && node.path) paths.push(node.path)\n if (node.children) extract(node.children)\n }\n }\n extract((res.tree ?? []) as unknown[])\n return paths\n }\n\n async approveAction(workspaceId: string, id: string): Promise<void> {\n await this.patch(this.route('approvals'), { workspaceId, id, status: 'approved' })\n }\n\n async rejectAction(workspaceId: string, id: string, reason: string): Promise<void> {\n await this.patch(this.route('approvals'), { workspaceId, id, status: 'rejected', reason })\n }\n\n async getGenerations(\n workspaceId: string,\n ): Promise<{ id: string; type: string; prompt: string }[]> {\n const res = await this.get(`${this.route('generations')}?workspaceId=${workspaceId}`)\n return (res.generations ?? []) as { id: string; type: string; prompt: string }[]\n }\n\n /** Generic GET for custom routes */\n async get(path: string): Promise<Record<string, unknown>> {\n const res = await fetch(`${this.baseUrl}${path}`, {\n headers: { Cookie: this.cookies },\n })\n return res.json() as Promise<Record<string, unknown>>\n }\n\n /** Generic POST for custom routes */\n async post(path: string, body: Record<string, unknown>): Promise<Record<string, unknown>> {\n const res = await fetch(`${this.baseUrl}${path}`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Origin: this.baseUrl,\n Cookie: this.cookies,\n },\n body: JSON.stringify(body),\n })\n return res.json() as Promise<Record<string, unknown>>\n }\n\n /** Generic PATCH for custom routes */\n async patch(path: string, body: Record<string, unknown>): Promise<Record<string, unknown>> {\n const res = await fetch(`${this.baseUrl}${path}`, {\n method: 'PATCH',\n headers: {\n 'Content-Type': 'application/json',\n Origin: this.baseUrl,\n Cookie: this.cookies,\n },\n body: JSON.stringify(body),\n })\n return res.json() as Promise<Record<string, unknown>>\n }\n}\n\n/**\n * Run a full e2e workflow test against a live product.\n *\n * The `workflow` callback receives a ProductClient and returns CheckResults.\n * This is the generic harness — each agent defines its own workflow steps.\n */\nexport async function runE2EWorkflow(\n client: ProductClient,\n name: string,\n workflow: (client: ProductClient) => Promise<CheckResult[]>,\n): Promise<TestResult> {\n const start = Date.now()\n const checks: CheckResult[] = []\n\n try {\n const results = await workflow(client)\n checks.push(...results)\n } catch (err) {\n checks.push({\n name: 'fatal_error',\n passed: false,\n expected: 'no crash',\n actual: err instanceof Error ? err.message : String(err),\n })\n }\n\n return {\n name,\n passed: checks.every((c) => c.passed),\n duration: Date.now() - start,\n detail: `${checks.filter((c) => c.passed).length}/${checks.length} checks passed`,\n checks,\n }\n}\n","import type { CompletionCriterion, DriverState } from './types'\n\n/**\n * ConvergenceTracker — tracks completion percentage over turns.\n *\n * Produces convergence curves showing how quickly the agent reaches\n * completion criteria.\n */\nexport class ConvergenceTracker {\n private criteria: CompletionCriterion[]\n private history: {\n turn: number\n completionPercent: number\n criteriaStatus: Record<string, boolean | number>\n }[] = []\n\n constructor(criteria: CompletionCriterion[]) {\n this.criteria = criteria\n }\n\n /** Evaluate criteria against current state, record result */\n record(\n turn: number,\n state: DriverState,\n ): {\n completionPercent: number\n complete: boolean\n criteriaStatus: Record<string, boolean | number>\n } {\n const criteriaStatus: Record<string, boolean | number> = {}\n let totalCredit = 0\n\n for (const criterion of this.criteria) {\n if (criterion.progress) {\n const credit = Math.min(1, Math.max(0, criterion.progress(state)))\n criteriaStatus[criterion.name] = credit\n totalCredit += credit\n } else {\n const passed = criterion.check(state)\n criteriaStatus[criterion.name] = passed\n totalCredit += passed ? 1 : 0\n }\n }\n\n const completionPercent =\n this.criteria.length > 0 ? (totalCredit / this.criteria.length) * 100 : 100\n\n this.history.push({ turn, completionPercent, criteriaStatus })\n\n return {\n completionPercent,\n complete: totalCredit >= this.criteria.length,\n criteriaStatus,\n }\n }\n\n /** Get convergence curve */\n getCurve(): number[] {\n return this.history.map((h) => h.completionPercent)\n }\n\n /** Get full history with per-criterion status */\n getHistory() {\n return [...this.history]\n }\n\n /** Find the turn where completion first reached 100% (or null) */\n getTurnToCompletion(): number | null {\n const entry = this.history.find((h) => h.completionPercent === 100)\n return entry?.turn ?? null\n }\n}\n","import type { ProductClient } from './client'\nimport type { DriverState, TurnMetrics } from './types'\n\ninterface TokenPrice {\n input: number\n output: number\n}\n\n/** Per-1K token pricing for exact model ids. */\nexport const MODEL_PRICING: Record<string, TokenPrice> = {\n 'gpt-4o': { input: 0.0025, output: 0.01 },\n 'gpt-4o-mini': { input: 0.00015, output: 0.0006 },\n 'gpt-4-turbo': { input: 0.01, output: 0.03 },\n 'claude-sonnet-4-20250514': { input: 0.003, output: 0.015 },\n 'claude-opus-4-20250514': { input: 0.015, output: 0.075 },\n 'claude-3-haiku-20240307': { input: 0.00025, output: 0.00125 },\n}\n\n/** Family-level pricing fallbacks (per-1K), matched against a normalized id\n * after exact lookup misses. Ordered — first match wins. Covers the model\n * ids actually used through the Tangle router + cli-bridge harnesses\n * (`claude-code/sonnet`, `opencode/zai-coding-plan/glm-5.1`,\n * `kimi-code/kimi-k2.6`, `deepseek-v4-pro`, `anthropic/claude-sonnet-4-6`, …),\n * none of which appear in the exact table above — without this they priced\n * to a silent $0, blanking every cost/Pareto axis downstream. */\nconst FAMILY_PRICING: Array<[RegExp, TokenPrice]> = [\n [/claude.*opus/, { input: 0.015, output: 0.075 }],\n [/claude.*haiku/, { input: 0.0008, output: 0.004 }],\n [/claude.*sonnet|claude-code|claude-sonnet/, { input: 0.003, output: 0.015 }],\n [/gpt-4o-mini/, { input: 0.00015, output: 0.0006 }],\n [/gpt-5|gpt-4\\.1|o[134]\\b/, { input: 0.00125, output: 0.01 }],\n [/gpt-4o|gpt-4/, { input: 0.0025, output: 0.01 }],\n [/deepseek/, { input: 0.0003, output: 0.0011 }],\n [/glm|zhipu|zai/, { input: 0.0006, output: 0.0022 }],\n [/kimi|moonshot/, { input: 0.0006, output: 0.0025 }],\n [/qwen/, { input: 0.0004, output: 0.0012 }],\n [/gemini.*flash/, { input: 0.0001, output: 0.0004 }],\n [/gemini/, { input: 0.00125, output: 0.005 }],\n [/llama/, { input: 0.0002, output: 0.0006 }],\n]\n\n/** Normalize a model id for pricing: drop a `@snapshot` suffix, lowercase,\n * and keep the final harness/provider-prefixed segment so family regexes\n * match (`opencode/zai-coding-plan/glm-5.1` → `glm-5.1`). */\nfunction normalizeModelId(model: string): string {\n return (model.split('@')[0] ?? model).trim().toLowerCase()\n}\n\n/** Resolve pricing for a model id: exact table, then family fallback.\n * Returns null when the id matches nothing (caller decides — never a\n * silent-zero masquerading as a real $0 cost). */\nexport function resolveModelPricing(model: string): TokenPrice | null {\n if (MODEL_PRICING[model]) return MODEL_PRICING[model]\n const id = normalizeModelId(model)\n if (MODEL_PRICING[id]) return MODEL_PRICING[id]\n for (const [pattern, price] of FAMILY_PRICING) {\n if (pattern.test(id)) return price\n }\n return null\n}\n\n/** True when `model` has known pricing (exact or family). Lets cost-aware\n * callers distinguish a real $0 from an unpriced model. */\nexport function isModelPriced(model: string): boolean {\n return resolveModelPricing(model) !== null\n}\n\nconst warnedUnpricedModels = new Set<string>()\n\n/** Estimate token count from string length (chars / 4 approximation) */\nexport function estimateTokens(text: string): number {\n return Math.ceil(text.length / 4)\n}\n\n/** Calculate cost in USD from token counts and model. Unknown models warn\n * once (not a silent zero) and return 0 so callers that ignore pricing keep\n * working; cost-sensitive callers should gate on {@link isModelPriced}. */\nexport function estimateCost(inputTokens: number, outputTokens: number, model: string): number {\n const pricing = resolveModelPricing(model)\n if (!pricing) {\n if (!warnedUnpricedModels.has(model)) {\n warnedUnpricedModels.add(model)\n console.warn(\n `estimateCost: no pricing for model \"${model}\" — returning 0; add it to ` +\n 'MODEL_PRICING/FAMILY_PRICING (cost/Pareto axes will be blank until then)',\n )\n }\n return 0\n }\n return (inputTokens / 1000) * pricing.input + (outputTokens / 1000) * pricing.output\n}\n\n/**\n * TokenCounter — accumulates token usage and cost across turns.\n */\nexport class TokenCounter {\n private totalInput = 0\n private totalOutput = 0\n private totalCost = 0\n private model: string\n\n constructor(model = 'gpt-4o') {\n this.model = model\n }\n\n /** Record tokens for a turn, returns per-turn cost */\n record(inputTokens: number, outputTokens: number): number {\n this.totalInput += inputTokens\n this.totalOutput += outputTokens\n const cost = estimateCost(inputTokens, outputTokens, this.model)\n this.totalCost += cost\n return cost\n }\n\n /** Estimate and record from raw text */\n recordFromText(\n inputText: string,\n outputText: string,\n ): { inputTokens: number; outputTokens: number; cost: number } {\n const inputTokens = estimateTokens(inputText)\n const outputTokens = estimateTokens(outputText)\n const cost = this.record(inputTokens, outputTokens)\n return { inputTokens, outputTokens, cost }\n }\n\n getTotalInput(): number {\n return this.totalInput\n }\n getTotalOutput(): number {\n return this.totalOutput\n }\n getTotalCost(): number {\n return this.totalCost\n }\n}\n\n/**\n * MetricsCollector — collects per-turn metrics from the product.\n *\n * After each turn, queries the product's APIs to measure state changes.\n */\nexport class MetricsCollector {\n private client: ProductClient\n private workspaceId: string\n private metrics: TurnMetrics[] = []\n constructor(client: ProductClient, workspaceId: string) {\n this.client = client\n this.workspaceId = workspaceId\n }\n\n /** Collect metrics after a turn completes */\n async collect(\n turn: number,\n responseLatencyMs: number,\n responseChars: number,\n codeBlocksProduced: number,\n blocksExtracted: number,\n completionCriteriaMet: number,\n completionCriteriaTotal: number,\n qualityScore?: number,\n inputTokens = 0,\n outputTokens = 0,\n estimatedCostUsd = 0,\n ): Promise<TurnMetrics> {\n const state = await this.getState()\n\n const m: TurnMetrics = {\n turn,\n timestamp: new Date().toISOString(),\n tasks: state.tasks,\n events: state.events,\n proposals: state.proposals,\n vaultFiles: state.vaultFiles.length,\n responseLatencyMs,\n responseChars,\n codeBlocksProduced,\n blocksExtracted,\n qualityScore,\n inputTokens,\n outputTokens,\n estimatedCostUsd,\n totalCostUsd: estimatedCostUsd,\n completionPercent:\n completionCriteriaTotal > 0 ? (completionCriteriaMet / completionCriteriaTotal) * 100 : 0,\n }\n\n this.metrics.push(m)\n return m\n }\n\n /** Get current product state */\n async getState(): Promise<DriverState> {\n const [tasks, events, approvals, vaultFiles] = await Promise.all([\n this.client.getTasks(this.workspaceId),\n this.client.getEvents(this.workspaceId),\n this.client.getApprovals(this.workspaceId),\n this.client.getVaultTree(this.workspaceId),\n ])\n\n return {\n tasks: tasks.length,\n events: events.length,\n proposals: {\n pending: approvals.filter((a) => a.status === 'pending').length,\n approved: approvals.filter((a) => a.status === 'approved').length,\n rejected: approvals.filter((a) => a.status === 'rejected').length,\n },\n vaultFiles,\n codeBlocks: 0,\n generations: 0,\n }\n }\n\n /** Get all collected metrics */\n getMetrics(): TurnMetrics[] {\n return [...this.metrics]\n }\n\n /** Get convergence curve (completion% over turns) */\n getConvergenceCurve(): number[] {\n return this.metrics.map((m) => m.completionPercent)\n }\n}\n","import type { TCloud } from '@tangle-network/tcloud'\nimport type { ProductClient } from './client'\nimport { ConvergenceTracker } from './convergence'\nimport { MetricsCollector } from './metrics'\nimport type { DriverResult, DriverState, PersonaConfig, PersonaRigor, TurnMetrics } from './types'\n\nexport interface AgentDriverConfig {\n client: ProductClient\n driverModel?: string\n /** System prompt context for the driver LLM to understand the product */\n productContext?: string\n}\n\n/**\n * Per-rigor stance the driver LLM adopts. Scales how hard the simulated\n * user interrogates the agent — see `PersonaConfig.rigor`.\n */\nconst RIGOR_STANCE: Record<PersonaRigor, string> = {\n cooperative:\n 'Your stance: a pragmatic early adopter. You accept reasonable answers and only push back on clear gaps or outright errors.',\n demanding:\n 'Your stance: an experienced professional with no time to waste. You do not accept vague, hedged, or generic answers — you expect specifics, and you say so plainly when you do not get them.',\n relentless:\n 'Your stance: a senior partner reviewing this work for a client who will litigate if it is wrong. You interrogate every claim. You accept nothing undefended. You find the single weakest point in every answer and attack it. Courteous, never satisfied.',\n}\n\n/**\n * AgentDriver — meta-agent that plays a persona against the real product.\n *\n * Uses a driver LLM (Claude/GPT-4o) to decide what to say each turn.\n * Not scripted — the driver gets the current product state and decides\n * the next realistic user message.\n */\nexport class AgentDriver {\n private tc: TCloud\n private client: ProductClient\n private driverModel: string\n private productContext: string\n\n constructor(tc: TCloud, config: AgentDriverConfig) {\n this.tc = tc\n this.client = config.client\n this.driverModel = config.driverModel ?? 'claude-sonnet-4-6'\n this.productContext = config.productContext ?? ''\n }\n\n /**\n * Run a persona through the product.\n *\n * Returns metrics on how many turns to completion, cost curve,\n * quality curve, and convergence curve.\n */\n async run(persona: PersonaConfig): Promise<DriverResult> {\n // Setup: create workspace + thread\n const email = `eval-driver-${Date.now()}@test.agent-eval.local`\n await this.client.signup(`Driver ${persona.role}`, email, 'eval-driver-pass')\n await this.client.login(email, 'eval-driver-pass')\n const workspaceId = await this.client.createWorkspace(`${persona.role} Eval`)\n const threadId = await this.client.createThread(workspaceId)\n\n const metrics = new MetricsCollector(this.client, workspaceId)\n const convergence = new ConvergenceTracker(persona.completionCriteria)\n const turnMetrics: TurnMetrics[] = []\n const conversationHistory: { role: string; content: string }[] = []\n\n let completed = false\n let turnsToCompletion: number | null = null\n let criteriaMetAtTurn: number | null = null\n\n for (let turn = 1; turn <= persona.maxTurns; turn++) {\n // Get current product state\n const state = await metrics.getState()\n\n // Ask driver LLM what to say\n const userMessage = await this.decideNextMessage(persona, state, conversationHistory)\n\n if (userMessage === 'DONE') {\n completed = true\n turnsToCompletion = turn - 1\n console.log(` SIGNED OFF by simulated ${persona.role} after turn ${turn - 1}`)\n break\n }\n\n // Send to product\n const turnStart = Date.now()\n const response = await this.client.chat(workspaceId, threadId, userMessage)\n const latency = Date.now() - turnStart\n\n conversationHistory.push(\n { role: 'user', content: userMessage },\n { role: 'assistant', content: response.text },\n )\n\n // Wait for post-processor\n await new Promise((r) => setTimeout(r, 2000))\n\n // Handle pending approvals\n await this.handleApprovals(persona, workspaceId, state)\n\n // Check convergence\n const postState = await metrics.getState()\n const conv = convergence.record(turn, postState)\n\n // Collect metrics\n const codeBlockCount = (response.text.match(/```\\w+\\n/g) || []).length\n const m = await metrics.collect(\n turn,\n latency,\n response.text.length,\n codeBlockCount,\n response.blocks.length,\n Object.values(conv.criteriaStatus).filter(Boolean).length,\n persona.completionCriteria.length,\n )\n turnMetrics.push(m)\n\n // Print turn status\n const criteriaStr = Object.entries(conv.criteriaStatus)\n .map(([k, v]) => `${k}:${v ? '+' : '-'}`)\n .join(' ')\n console.log(\n ` [turn ${turn}] ${conv.completionPercent.toFixed(0)}% — ${criteriaStr} (${(latency / 1000).toFixed(1)}s)`,\n )\n\n // Nominal criteria met is recorded, not a stop condition. The\n // simulated professional keeps pressure-testing until genuinely\n // satisfied — a criteria-met-but-sloppy answer must still be defended.\n if (conv.complete && criteriaMetAtTurn === null) {\n criteriaMetAtTurn = turn\n console.log(` criteria met at turn ${turn} — driver continues pressure-testing`)\n }\n }\n\n const finalState = await metrics.getState()\n\n return {\n personaId: persona.id,\n completed,\n turnsToCompletion,\n criteriaMetAtTurn,\n totalTurns: turnMetrics.length,\n metrics: turnMetrics,\n finalState,\n convergenceCurve: convergence.getCurve(),\n totalCostUsd: 0,\n finalQualityScore: null,\n }\n }\n\n /** Use the driver LLM to decide what the \"user\" says next */\n private async decideNextMessage(\n persona: PersonaConfig,\n state: DriverState,\n history: { role: string; content: string }[],\n ): Promise<string> {\n return decideNextUserTurn(this.tc, {\n persona,\n state,\n history,\n productContext: this.productContext,\n model: this.driverModel,\n })\n }\n\n /** Handle pending approvals based on persona feedback patterns */\n private async handleApprovals(\n persona: PersonaConfig,\n workspaceId: string,\n _state: DriverState,\n ): Promise<void> {\n const approvals = await this.client.getApprovals(workspaceId)\n const pending = approvals.filter((a) => a.status === 'pending')\n\n for (const action of pending) {\n // Check if any feedback pattern triggers a rejection\n const rejection = persona.feedbackPatterns?.find((fp) => {\n const title = action.title.toLowerCase()\n return title.includes(fp.trigger.toLowerCase())\n })\n\n if (rejection) {\n await this.client.rejectAction(workspaceId, action.id, rejection.response)\n console.log(` rejected: ${action.title} — ${rejection.response.slice(0, 60)}`)\n } else {\n await this.client.approveAction(workspaceId, action.id)\n console.log(` approved: ${action.title}`)\n }\n }\n }\n}\n\n/** Describe which nominal completion criteria are met, for the driver prompt. */\nfunction describeCompletion(persona: PersonaConfig, state: DriverState): string {\n const results = persona.completionCriteria.map((c) => {\n const met = c.check(state)\n return `${c.name}: ${met ? 'MET' : 'NOT MET'}`\n })\n const metCount = results.filter((r) => r.includes('MET') && !r.includes('NOT')).length\n return `${metCount}/${persona.completionCriteria.length} — ${results.join(', ')}`\n}\n\n/**\n * Build the driver LLM's system prompt. The simulated user is an\n * adversarial senior professional: it judges the agent's last response by a\n * professional standard, refuses vague answers, challenges undefended\n * claims, probes the persona's pressure points without revealing them, and\n * signs off (DONE) only when a real practitioner would act on the work\n * unmodified. Pure function of persona, product state, and product context\n * — exported so harness authors can inspect and regression-test it.\n */\nexport function buildDriverSystemPrompt(\n persona: PersonaConfig,\n state: DriverState,\n productContext = '',\n): string {\n const rigor: PersonaRigor = persona.rigor ?? 'demanding'\n const expertise = persona.expertise ? ` You are ${persona.expertise}.` : ''\n\n const pressure =\n persona.pressurePoints && persona.pressurePoints.length > 0\n ? `\\nA competent ${persona.role} here MUST get the agent to address each of:\\n${persona.pressurePoints\n .map((p) => ` - ${p}`)\n .join(\n '\\n',\n )}\\nDo NOT hand these to the agent. Probe whether it surfaces them itself. If it misses one, press on exactly that gap until it delivers or demonstrably fails.\\n`\n : ''\n\n const curveballs =\n persona.curveballs && persona.curveballs.length > 0\n ? `\\nOnce the agent is coasting on easy answers, introduce ONE of these as a genuine new development — never as a quiz:\\n${persona.curveballs\n .map((c) => ` - ${c}`)\n .join('\\n')}\\n`\n : ''\n\n return `You are role-playing a real ${persona.role} putting an AI agent through its paces.${expertise}\nYour objective: ${persona.goal}\nYou are deciding whether this agent's work is good enough to stake your professional reputation on. Assume it is not — until it proves otherwise.\n\n${RIGOR_STANCE[rigor]}\n${productContext ? `Product context:\\n${productContext}\\n` : ''}Current workspace state:\n- Tasks: ${state.tasks} | Events: ${state.events}\n- Proposals: pending=${state.proposals.pending}, approved=${state.proposals.approved}, rejected=${state.proposals.rejected}\n- Vault files (${state.vaultFiles.length}): ${state.vaultFiles.slice(0, 10).join(', ')}${state.vaultFiles.length > 10 ? ' …' : ''}\n- Nominal task criteria: ${describeCompletion(persona, state)}\n${pressure}${curveballs}\nHow to choose your next message:\n1. Silently judge the agent's last response the way a ${persona.role} would. Is every claim defended with a specific authority, figure, or mechanism? Or is it vague, hedged, or generic?\n2. If it is vague or hand-waved — do NOT move on. Name the gap and demand the specific authority / figure / mechanism. \"It depends\" is not an answer; force the decision.\n3. If it makes a claim you can challenge — challenge it. Make the agent defend or correct it.\n4. If it missed something a ${persona.role} would catch — press on exactly that, without naming it for the agent.\n5. If it is genuinely solid — escalate: go a layer deeper, or introduce a curveball.\n6. First message — state your situation as you really would: realistic, specific, with the messy detail, but do not coach the agent.\n\nSign-off: respond with exactly \"DONE\" only when a ${persona.role} would act on this work without redoing it. Nominal task completion is NOT sign-off — sloppy-but-complete still fails. If the agent never gets there, keep pushing; never sign off on weak work.\n\nOutput ONLY your next message to the agent — in character, first person, no meta-commentary, no stage directions.`\n}\n\nexport interface DecideNextUserTurnOpts {\n persona: PersonaConfig\n state: DriverState\n /** Conversation so far — alternating user/assistant messages, oldest first. */\n history: { role: string; content: string }[]\n /** Optional product context woven into the driver prompt. */\n productContext?: string\n /** Driver LLM model. Defaults to claude-sonnet-4-6. */\n model?: string\n}\n\n/**\n * Decide the simulated user's next turn — the reactive, adversarial\n * turn-generation core of `AgentDriver`, exposed standalone so an in-process\n * eval harness can drive multi-shot conversations without the `ProductClient`\n * workspace machinery. Returns the next user message, or the literal \"DONE\"\n * when the simulated professional would sign off.\n */\nexport async function decideNextUserTurn(\n tc: TCloud,\n opts: DecideNextUserTurnOpts,\n): Promise<string> {\n const { persona, state, history, productContext = '', model = 'claude-sonnet-4-6' } = opts\n\n const lastResponse =\n history.length > 0\n ? history[history.length - 1]!.content.slice(0, 2000)\n : '(no conversation yet — this is the first message)'\n\n const recentHistory = history\n .slice(-6)\n .map((h) => `${h.role}: ${h.content.slice(0, 500)}`)\n .join('\\n\\n')\n\n const resp = await tc.chat({\n model,\n messages: [\n { role: 'system', content: buildDriverSystemPrompt(persona, state, productContext) },\n {\n role: 'user',\n content: recentHistory\n ? `Recent conversation:\\n${recentHistory}\\n\\nThe agent's latest response:\\n${lastResponse}`\n : 'No conversation yet. Send your opening message — in character, phrased as this person actually would.',\n },\n ],\n temperature: 0.5,\n maxTokens: 700,\n })\n\n const content =\n (resp as { choices?: { message?: { content?: string } }[] }).choices?.[0]?.message?.content ??\n ''\n\n return content.trim()\n}\n","import type { ControlEvalResult, ControlRunResult, ControlStep } from './control-runtime'\nimport type { DatasetScenario, DatasetSplit } from './dataset'\n\nexport type FeedbackArtifactType =\n | 'text'\n | 'code'\n | 'plan'\n | 'research'\n | 'action'\n | 'ui'\n | 'decision'\n | 'data'\n | 'other'\n\nexport type FeedbackLabelSource = 'user' | 'judge' | 'environment' | 'metric' | 'policy' | 'system'\n\nexport type FeedbackLabelKind =\n | 'approve'\n | 'reject'\n | 'select'\n | 'edit'\n | 'rank'\n | 'rate'\n | 'comment'\n | 'metric_outcome'\n | 'policy_block'\n | 'revision_request'\n\nexport type FeedbackSeverity = 'info' | 'warning' | 'error' | 'critical'\n\nexport interface FeedbackTask {\n intent: string\n context?: unknown\n}\n\nexport interface ProposedSideEffect {\n type: string\n risk?: 'low' | 'medium' | 'high'\n costUsd?: number\n externalSideEffect?: boolean\n requiresApproval?: boolean\n metadata?: Record<string, unknown>\n}\n\nexport interface FeedbackLabel {\n id?: string\n source: FeedbackLabelSource\n kind: FeedbackLabelKind\n value: unknown\n reason?: string\n severity?: FeedbackSeverity\n createdAt: string\n metadata?: Record<string, unknown>\n}\n\nexport interface FeedbackAttempt {\n id: string\n stepIndex: number\n artifactType: FeedbackArtifactType\n artifact: unknown\n options?: unknown[]\n proposedAction?: ProposedSideEffect\n evals?: ControlEvalResult[]\n feedback?: FeedbackLabel[]\n createdAt: string\n metadata?: Record<string, unknown>\n}\n\nexport interface FeedbackOutcome {\n success?: boolean\n score?: number\n metrics?: Record<string, number>\n costUsd?: number\n detail?: string\n observedAt?: string\n metadata?: Record<string, unknown>\n}\n\nexport interface FeedbackTrajectory {\n id: string\n projectId?: string\n scenarioId?: string\n task: FeedbackTask\n attempts: FeedbackAttempt[]\n labels: FeedbackLabel[]\n outcome?: FeedbackOutcome\n split?: DatasetSplit\n tags?: Record<string, string>\n createdAt: string\n updatedAt?: string\n metadata?: Record<string, unknown>\n}\n\nexport interface FeedbackTrajectoryStore {\n save(trajectory: FeedbackTrajectory): Promise<void>\n get(id: string): Promise<FeedbackTrajectory | null>\n list(filter?: FeedbackTrajectoryFilter): Promise<FeedbackTrajectory[]>\n appendAttempt(id: string, attempt: FeedbackAttempt): Promise<FeedbackTrajectory>\n appendLabel(id: string, label: FeedbackLabel, attemptId?: string): Promise<FeedbackTrajectory>\n}\n\nexport interface FeedbackTrajectoryFilter {\n projectId?: string\n scenarioId?: string\n split?: DatasetSplit\n tag?: [string, string]\n}\n\nexport interface FeedbackSplitPolicy {\n trainPct?: number\n devPct?: number\n testPct?: number\n holdoutPct?: number\n}\n\nexport interface PreferenceMemoryEntry {\n instruction: string\n rationale: string\n weight: number\n sourceTrajectoryId: string\n sourceLabelId?: string\n category?: string\n}\n\nexport interface FeedbackOptimizerRow {\n scenarioId: string\n trajectoryId: string\n labelKinds: FeedbackLabelKind[]\n score?: number\n metadata?: Record<string, unknown>\n}\n\nexport interface FeedbackReplayResult {\n trajectoryId: string\n pass: boolean\n score?: number\n labels: FeedbackLabel[]\n outcome?: FeedbackOutcome\n metadata?: Record<string, unknown>\n}\n\nexport interface FeedbackReplayAdapter {\n replay(\n trajectory: FeedbackTrajectory,\n ):\n | Promise<Omit<FeedbackReplayResult, 'trajectoryId'>>\n | Omit<FeedbackReplayResult, 'trajectoryId'>\n}\n\nconst DEFAULT_SPLIT_POLICY: Required<FeedbackSplitPolicy> = {\n trainPct: 70,\n devPct: 15,\n testPct: 10,\n holdoutPct: 5,\n}\n\nexport class InMemoryFeedbackTrajectoryStore implements FeedbackTrajectoryStore {\n private readonly trajectories = new Map<string, FeedbackTrajectory>()\n\n async save(trajectory: FeedbackTrajectory): Promise<void> {\n this.trajectories.set(trajectory.id, cloneTrajectory(trajectory))\n }\n\n async get(id: string): Promise<FeedbackTrajectory | null> {\n const trajectory = this.trajectories.get(id)\n return trajectory ? cloneTrajectory(trajectory) : null\n }\n\n async list(filter: FeedbackTrajectoryFilter = {}): Promise<FeedbackTrajectory[]> {\n return [...this.trajectories.values()]\n .filter((trajectory) => matchesFilter(trajectory, filter))\n .map(cloneTrajectory)\n }\n\n async appendAttempt(id: string, attempt: FeedbackAttempt): Promise<FeedbackTrajectory> {\n const trajectory = this.trajectories.get(id)\n if (!trajectory)\n throw new Error(`FeedbackTrajectoryStore.appendAttempt: unknown trajectory \"${id}\"`)\n const next = cloneTrajectory({\n ...trajectory,\n attempts: [...trajectory.attempts, attempt],\n updatedAt: attempt.createdAt,\n })\n this.trajectories.set(id, next)\n return cloneTrajectory(next)\n }\n\n async appendLabel(\n id: string,\n label: FeedbackLabel,\n attemptId?: string,\n ): Promise<FeedbackTrajectory> {\n const trajectory = this.trajectories.get(id)\n if (!trajectory)\n throw new Error(`FeedbackTrajectoryStore.appendLabel: unknown trajectory \"${id}\"`)\n const attempts = attemptId\n ? trajectory.attempts.map((attempt) =>\n attempt.id === attemptId\n ? { ...attempt, feedback: [...(attempt.feedback ?? []), label] }\n : attempt,\n )\n : trajectory.attempts\n const next = cloneTrajectory({\n ...trajectory,\n attempts,\n labels: attemptId ? trajectory.labels : [...trajectory.labels, label],\n updatedAt: label.createdAt,\n })\n this.trajectories.set(id, next)\n return cloneTrajectory(next)\n }\n}\n\nexport class FileSystemFeedbackTrajectoryStore implements FeedbackTrajectoryStore {\n private readonly dir: string\n private readonly memory = new InMemoryFeedbackTrajectoryStore()\n private loaded = false\n\n constructor(options: { dir: string }) {\n this.dir = options.dir\n }\n\n async save(trajectory: FeedbackTrajectory): Promise<void> {\n await this.load()\n await this.memory.save(trajectory)\n await this.append({ op: 'save', trajectory })\n }\n\n async get(id: string): Promise<FeedbackTrajectory | null> {\n await this.load()\n return this.memory.get(id)\n }\n\n async list(filter: FeedbackTrajectoryFilter = {}): Promise<FeedbackTrajectory[]> {\n await this.load()\n return this.memory.list(filter)\n }\n\n async appendAttempt(id: string, attempt: FeedbackAttempt): Promise<FeedbackTrajectory> {\n await this.load()\n const next = await this.memory.appendAttempt(id, attempt)\n await this.append({ op: 'appendAttempt', id, attempt })\n return next\n }\n\n async appendLabel(\n id: string,\n label: FeedbackLabel,\n attemptId?: string,\n ): Promise<FeedbackTrajectory> {\n await this.load()\n const next = await this.memory.appendLabel(id, label, attemptId)\n await this.append({ op: 'appendLabel', id, label, attemptId })\n return next\n }\n\n private async append(record: unknown): Promise<void> {\n const { appendFile, mkdir } = await import('node:fs/promises')\n const { join } = await import('node:path')\n await mkdir(this.dir, { recursive: true })\n await appendFile(\n join(this.dir, 'feedback-trajectories.ndjson'),\n `${JSON.stringify(record)}\\n`,\n 'utf8',\n )\n }\n\n private async load(): Promise<void> {\n if (this.loaded) return\n const { readFile } = await import('node:fs/promises')\n const { join } = await import('node:path')\n const file = join(this.dir, 'feedback-trajectories.ndjson')\n try {\n const raw = await readFile(file, 'utf8')\n for (const line of raw.split('\\n')) {\n if (!line.trim()) continue\n try {\n const record = JSON.parse(line) as\n | { op: 'save'; trajectory: FeedbackTrajectory }\n | { op: 'appendAttempt'; id: string; attempt: FeedbackAttempt }\n | { op: 'appendLabel'; id: string; label: FeedbackLabel; attemptId?: string }\n if (record.op === 'save') await this.memory.save(record.trajectory)\n if (record.op === 'appendAttempt')\n await this.memory.appendAttempt(record.id, record.attempt)\n if (record.op === 'appendLabel')\n await this.memory.appendLabel(record.id, record.label, record.attemptId)\n } catch {\n /* corrupt records are skipped so one bad line does not discard the corpus */\n }\n }\n } catch {\n /* first run */\n }\n this.loaded = true\n }\n}\n\nexport function createFeedbackTrajectory(input: {\n id?: string\n projectId?: string\n scenarioId?: string\n task: FeedbackTask\n attempts?: FeedbackAttempt[]\n labels?: FeedbackLabel[]\n outcome?: FeedbackOutcome\n split?: DatasetSplit\n tags?: Record<string, string>\n createdAt?: string\n metadata?: Record<string, unknown>\n}): FeedbackTrajectory {\n const createdAt = input.createdAt ?? new Date().toISOString()\n const id =\n input.id ??\n `ft_${stableHash(`${input.projectId ?? ''}|${input.scenarioId ?? ''}|${input.task.intent}|${createdAt}`).toString(16)}`\n return {\n id,\n projectId: input.projectId,\n scenarioId: input.scenarioId,\n task: input.task,\n attempts: input.attempts ?? [],\n labels: input.labels ?? [],\n outcome: input.outcome,\n split: input.split,\n tags: input.tags,\n createdAt,\n metadata: input.metadata,\n }\n}\n\nexport function assignFeedbackSplit(\n trajectory: Pick<FeedbackTrajectory, 'id' | 'projectId' | 'scenarioId' | 'task'>,\n policy: FeedbackSplitPolicy = {},\n): DatasetSplit {\n const split = { ...DEFAULT_SPLIT_POLICY, ...policy }\n const total = split.trainPct + split.devPct + split.testPct + split.holdoutPct\n if (total <= 0) throw new Error('assignFeedbackSplit: split percentages must sum above zero')\n const bucket =\n stableHash(\n `${trajectory.projectId ?? ''}|${trajectory.scenarioId ?? ''}|${trajectory.id}|${trajectory.task.intent}`,\n ) % total\n if (bucket < split.trainPct) return 'train'\n if (bucket < split.trainPct + split.devPct) return 'dev'\n if (bucket < split.trainPct + split.devPct + split.testPct) return 'test'\n return 'holdout'\n}\n\nexport function withAssignedFeedbackSplit(\n trajectory: FeedbackTrajectory,\n policy?: FeedbackSplitPolicy,\n): FeedbackTrajectory {\n return {\n ...trajectory,\n split: trajectory.split ?? assignFeedbackSplit(trajectory, policy),\n }\n}\n\nexport function feedbackTrajectoryToDatasetScenario(\n trajectory: FeedbackTrajectory,\n): DatasetScenario {\n const withSplit = withAssignedFeedbackSplit(trajectory)\n return {\n id: withSplit.scenarioId ?? withSplit.id,\n split: withSplit.split,\n payload: withSplit,\n tags: {\n ...(withSplit.projectId ? { projectId: withSplit.projectId } : {}),\n ...(withSplit.tags ?? {}),\n source: 'feedback-trajectory',\n },\n }\n}\n\nexport function feedbackTrajectoriesToDatasetScenarios(\n trajectories: FeedbackTrajectory[],\n): DatasetScenario[] {\n return trajectories.map(feedbackTrajectoryToDatasetScenario)\n}\n\nexport function feedbackTrajectoryToOptimizerRow(\n trajectory: FeedbackTrajectory,\n): FeedbackOptimizerRow {\n const labels = allLabels(trajectory)\n return {\n scenarioId: trajectory.scenarioId ?? trajectory.id,\n trajectoryId: trajectory.id,\n labelKinds: [...new Set(labels.map((label) => label.kind))],\n score: trajectory.outcome?.score ?? scoreFromLabels(labels),\n metadata: {\n projectId: trajectory.projectId,\n split: trajectory.split,\n intent: trajectory.task.intent,\n attempts: trajectory.attempts.length,\n outcome: trajectory.outcome,\n labels,\n },\n }\n}\n\nexport function feedbackTrajectoriesToOptimizerRows(\n trajectories: FeedbackTrajectory[],\n): FeedbackOptimizerRow[] {\n return trajectories.map(feedbackTrajectoryToOptimizerRow)\n}\n\nexport async function replayFeedbackTrajectory(\n trajectory: FeedbackTrajectory,\n adapter: FeedbackReplayAdapter,\n): Promise<FeedbackReplayResult> {\n try {\n const result = await adapter.replay(trajectory)\n return {\n trajectoryId: trajectory.id,\n ...result,\n }\n } catch (err) {\n const createdAt = new Date().toISOString()\n const message = err instanceof Error ? err.message : String(err)\n return {\n trajectoryId: trajectory.id,\n pass: false,\n labels: [\n {\n source: 'system',\n kind: 'reject',\n value: false,\n reason: message,\n severity: 'error',\n createdAt,\n },\n ],\n outcome: {\n success: false,\n score: 0,\n detail: message,\n observedAt: createdAt,\n },\n metadata: { replayError: true },\n }\n }\n}\n\nexport async function replayFeedbackTrajectories(\n trajectories: FeedbackTrajectory[],\n adapter: FeedbackReplayAdapter,\n): Promise<FeedbackReplayResult[]> {\n const results: FeedbackReplayResult[] = []\n for (const trajectory of trajectories) {\n results.push(await replayFeedbackTrajectory(trajectory, adapter))\n }\n return results\n}\n\nexport function summarizePreferenceMemory(\n trajectories: FeedbackTrajectory[],\n options: { maxEntries?: number } = {},\n): PreferenceMemoryEntry[] {\n const maxEntries = options.maxEntries ?? 20\n const entries: PreferenceMemoryEntry[] = []\n for (const trajectory of trajectories) {\n for (const label of allLabels(trajectory)) {\n const instruction = instructionFromLabel(trajectory, label)\n if (!instruction) continue\n entries.push({\n instruction,\n rationale: label.reason ?? `${label.kind} label from ${label.source}`,\n weight: weightForLabel(label),\n sourceTrajectoryId: trajectory.id,\n sourceLabelId: label.id,\n category: label.kind,\n })\n }\n }\n\n const byInstruction = new Map<string, PreferenceMemoryEntry>()\n for (const entry of entries) {\n const key = entry.instruction.toLowerCase().replace(/\\s+/g, ' ').trim()\n const existing = byInstruction.get(key)\n if (!existing || entry.weight > existing.weight) byInstruction.set(key, entry)\n }\n return [...byInstruction.values()].sort((a, b) => b.weight - a.weight).slice(0, maxEntries)\n}\n\nexport function renderPreferenceMemoryMarkdown(entries: PreferenceMemoryEntry[]): string {\n const lines = ['# Preference Memory', '']\n for (const entry of entries) {\n lines.push(`- ${entry.instruction}`)\n lines.push(` Rationale: ${entry.rationale}`)\n lines.push(` Source: ${entry.sourceTrajectoryId}`)\n lines.push('')\n }\n return `${lines.join('\\n').trim()}\\n`\n}\n\nexport function serializeFeedbackTrajectoriesJsonl(trajectories: FeedbackTrajectory[]): string {\n return `${trajectories\n .slice()\n .sort((a, b) => a.id.localeCompare(b.id))\n .map((trajectory) => JSON.stringify(canonicalize(trajectory)))\n .join('\\n')}\\n`\n}\n\nexport function parseFeedbackTrajectoriesJsonl(jsonl: string): FeedbackTrajectory[] {\n const trajectories: FeedbackTrajectory[] = []\n for (const line of jsonl.split('\\n')) {\n if (!line.trim()) continue\n trajectories.push(JSON.parse(line) as FeedbackTrajectory)\n }\n return trajectories\n}\n\nexport function controlRunToFeedbackTrajectory<TState, TAction, TActionResult>(\n run: ControlRunResult<TState, TAction, TActionResult>,\n options: {\n projectId?: string\n scenarioId?: string\n artifactType?: FeedbackArtifactType\n artifactFromStep?: (step: ControlStep<TState, TAction, TActionResult>) => unknown\n proposedActionFromStep?: (\n step: ControlStep<TState, TAction, TActionResult>,\n ) => ProposedSideEffect | undefined\n createdAt?: string\n } = {},\n): FeedbackTrajectory {\n const createdAt = options.createdAt ?? new Date().toISOString()\n const trajectoryId =\n run.runId ?? `ft_control_${stableHash(`${run.intent}|${createdAt}`).toString(16)}`\n return createFeedbackTrajectory({\n id: trajectoryId,\n projectId: options.projectId,\n scenarioId: options.scenarioId,\n task: { intent: run.intent },\n createdAt,\n attempts: run.steps.map((step) => ({\n id: `${trajectoryId}_step_${step.index}`,\n stepIndex: step.index,\n artifactType: options.artifactType ?? 'action',\n artifact: options.artifactFromStep?.(step) ?? step.actionOutcome?.result ?? step.decision,\n proposedAction: options.proposedActionFromStep?.(step),\n evals: step.evalsAfter,\n createdAt: step.startedAt,\n metadata: {\n decision: step.decision,\n actionOutcome: step.actionOutcome,\n },\n })),\n labels: [\n {\n source: 'system',\n kind: run.pass ? 'approve' : 'reject',\n value: run.pass,\n reason: run.reason,\n severity: run.pass ? 'info' : 'error',\n createdAt,\n },\n ],\n outcome: {\n success: run.pass,\n score: run.score,\n costUsd: run.spentCostUsd,\n detail: run.reason,\n observedAt: createdAt,\n metadata: {\n stoppedBy: run.stoppedBy,\n failureClass: run.failureClass,\n },\n },\n })\n}\n\nfunction allLabels(trajectory: FeedbackTrajectory): FeedbackLabel[] {\n const labels = [\n ...trajectory.labels,\n ...trajectory.attempts.flatMap((attempt) => attempt.feedback ?? []),\n ]\n const seen = new Set<string>()\n return labels.filter((label) => {\n const key =\n label.id ?? `${label.source}|${label.kind}|${label.createdAt}|${JSON.stringify(label.value)}`\n if (seen.has(key)) return false\n seen.add(key)\n return true\n })\n}\n\nfunction scoreFromLabels(labels: FeedbackLabel[]): number | undefined {\n if (!labels.length) return undefined\n const scored = labels\n .map((label) => {\n if (label.kind === 'approve' || label.kind === 'select') return 1\n if (label.kind === 'reject' || label.kind === 'policy_block') return 0\n if (label.kind === 'rate' && typeof label.value === 'number')\n return Math.max(0, Math.min(1, label.value))\n return undefined\n })\n .filter((value): value is number => typeof value === 'number')\n if (!scored.length) return undefined\n return Math.round((scored.reduce((sum, value) => sum + value, 0) / scored.length) * 1000) / 1000\n}\n\nfunction instructionFromLabel(\n trajectory: FeedbackTrajectory,\n label: FeedbackLabel,\n): string | undefined {\n if (label.kind === 'reject' && label.reason)\n return `Avoid outputs like \"${compact(trajectory.task.intent, 80)}\" when: ${label.reason}`\n if (label.kind === 'revision_request' && label.reason)\n return `Revise similar work by applying: ${label.reason}`\n if (label.kind === 'select' && label.reason)\n return `Prefer selected options for \"${compact(trajectory.task.intent, 80)}\" because: ${label.reason}`\n if (label.kind === 'approve' && label.reason)\n return `Repeat the pattern approved for \"${compact(trajectory.task.intent, 80)}\": ${label.reason}`\n if (label.kind === 'comment' && label.reason) return label.reason\n return undefined\n}\n\nfunction weightForLabel(label: FeedbackLabel): number {\n const severity =\n label.severity === 'critical'\n ? 4\n : label.severity === 'error'\n ? 3\n : label.severity === 'warning'\n ? 2\n : 1\n const source =\n label.source === 'user'\n ? 3\n : label.source === 'metric' || label.source === 'environment'\n ? 2\n : 1\n return severity * source\n}\n\nfunction matchesFilter(trajectory: FeedbackTrajectory, filter: FeedbackTrajectoryFilter): boolean {\n if (filter.projectId && trajectory.projectId !== filter.projectId) return false\n if (filter.scenarioId && trajectory.scenarioId !== filter.scenarioId) return false\n if (filter.split && trajectory.split !== filter.split) return false\n if (filter.tag) {\n const [key, value] = filter.tag\n if (trajectory.tags?.[key] !== value) return false\n }\n return true\n}\n\nfunction cloneTrajectory(trajectory: FeedbackTrajectory): FeedbackTrajectory {\n return JSON.parse(JSON.stringify(trajectory)) as FeedbackTrajectory\n}\n\nfunction compact(value: string, max: number): string {\n const normalized = value.replace(/\\s+/g, ' ').trim()\n return normalized.length > max ? `${normalized.slice(0, max).trim()}...` : normalized\n}\n\nfunction stableHash(input: string): number {\n let hash = 2166136261\n for (let i = 0; i < input.length; i += 1) {\n hash ^= input.charCodeAt(i)\n hash = Math.imul(hash, 16777619)\n }\n return hash >>> 0\n}\n\nfunction canonicalize(value: unknown): unknown {\n if (value === null || typeof value !== 'object') return value\n if (Array.isArray(value)) return value.map(canonicalize)\n const out: Record<string, unknown> = {}\n for (const key of Object.keys(value as Record<string, unknown>).sort()) {\n out[key] = canonicalize((value as Record<string, unknown>)[key])\n }\n return out\n}\n","/**\n * Single-backend guard: assert the agent and the rubric judge run through the\n * SAME backend config, so the judge can't silently re-route through a\n * different (often paid) backend than the agent.\n *\n * The bug class: `--backend cli-bridge` rewires the agent, but the judge still\n * reads `process.env.TANGLE_API_KEY` → router. Cost is billed against the\n * router, the eval reports the cli-bridge model, and the data is unusable.\n * Four consumers hand-roll this comparison (legal at `canonical.ts:702-795`);\n * this is the one substrate copy.\n *\n * Complements `assertRealBackend` (records → stub vs real) and\n * `assertCrossFamily` (judge-ensemble family diversity): this one compares two\n * backend *configs* before the run.\n */\n\nimport { AgentEvalError } from '../errors'\n\n/**\n * Minimal backend-config shape the assertion reads. Consumers may pass richer\n * types — only these five fields are inspected.\n */\nexport interface BackendDescriptor {\n /** Backend route — e.g. `'tcloud' | 'cli-bridge' | 'sandbox' | 'direct-provider'`;\n * free-form for consumer extensibility. */\n kind: string\n /** Resolved base URL. Compared lexically (trailing slash stripped). */\n baseUrl: string\n /** Model id (with snapshot suffix). Compared lexically. */\n model: string\n /** Optional provider override. Compared when both set; flagged when only\n * one side sets it. */\n provider?: string\n /** Bearer token. Values are NEVER compared (security) — only that EITHER\n * both are set OR both are empty. Mismatched presence is a divergence. */\n apiKey?: string\n}\n\nexport interface AssertSingleBackendOptions {\n /** When true, ANY field divergence fails. When false (default), only\n * `kind` / `baseUrl` / `provider` / `apiKeyPresence` divergence throws —\n * a different judge `model` on the same route is allowed (the legal\n * pattern: a cheaper judge model). */\n strict?: boolean\n agentLabel?: string\n judgeLabel?: string\n}\n\nexport type SingleBackendField = 'kind' | 'baseUrl' | 'model' | 'provider' | 'apiKeyPresence'\n\nexport interface SingleBackendDivergence {\n field: SingleBackendField\n agent: string | undefined\n judge: string | undefined\n}\n\nexport interface SingleBackendReport {\n /** True when agent + judge agree per the configured strictness. */\n ok: boolean\n /** Every divergence detected (includes `model` even when non-blocking). */\n divergences: ReadonlyArray<SingleBackendDivergence>\n}\n\nexport class SingleBackendError extends AgentEvalError {\n constructor(\n message: string,\n public readonly report: SingleBackendReport,\n ) {\n super('backend_integrity', message)\n this.name = 'SingleBackendError'\n }\n}\n\nfunction stripSlash(url: string): string {\n return url.replace(/\\/+$/, '')\n}\n\n/**\n * Throw `SingleBackendError` when the agent and judge backends diverge in a\n * way that would re-route the judge through a different backend than the\n * agent. Returns the report so callers can log it in either case.\n */\nexport function assertSingleBackend(\n agent: BackendDescriptor,\n judge: BackendDescriptor,\n opts: AssertSingleBackendOptions = {},\n): SingleBackendReport {\n const divergences: SingleBackendDivergence[] = []\n\n if (agent.kind !== judge.kind) {\n divergences.push({ field: 'kind', agent: agent.kind, judge: judge.kind })\n }\n if (stripSlash(agent.baseUrl) !== stripSlash(judge.baseUrl)) {\n divergences.push({ field: 'baseUrl', agent: agent.baseUrl, judge: judge.baseUrl })\n }\n if (agent.model !== judge.model) {\n divergences.push({ field: 'model', agent: agent.model, judge: judge.model })\n }\n // provider: compare when both set; flag when exactly one is set.\n if (agent.provider !== judge.provider) {\n divergences.push({ field: 'provider', agent: agent.provider, judge: judge.provider })\n }\n // apiKey: presence only, never the value.\n const agentHasKey = Boolean(agent.apiKey)\n const judgeHasKey = Boolean(judge.apiKey)\n if (agentHasKey !== judgeHasKey) {\n divergences.push({\n field: 'apiKeyPresence',\n agent: agentHasKey ? 'set' : 'empty',\n judge: judgeHasKey ? 'set' : 'empty',\n })\n }\n\n const blocking = opts.strict ? divergences : divergences.filter((d) => d.field !== 'model')\n const ok = blocking.length === 0\n const report: SingleBackendReport = { ok, divergences }\n\n if (!ok) {\n const agentLabel = opts.agentLabel ?? 'agent'\n const judgeLabel = opts.judgeLabel ?? 'judge'\n const detail = blocking\n .map((d) => `${d.field}: ${agentLabel}=${d.agent ?? '∅'} vs ${judgeLabel}=${d.judge ?? '∅'}`)\n .join('; ')\n throw new SingleBackendError(\n `single-backend: ${agentLabel} and ${judgeLabel} backends diverge — the judge would ` +\n `re-route through a different backend than the agent (${detail})`,\n report,\n )\n }\n\n return report\n}\n","/**\n * Judge model-family classification + cross-family enforcement.\n *\n * A judge ensemble built entirely from one provider family shares that\n * family's blind spots and self-preference — its \"agreement\" is correlated\n * bias, not independent signal. `assertCrossFamily` makes the consumer prove\n * the ensemble spans ≥2 families; `judgeFamily` is the single regex map that\n * replaces the per-consumer copies (tax/legal/creative/gtm each ship one).\n */\n\n/** Provider family a model belongs to. `unknown` when no rule matches. */\nexport type JudgeFamily =\n | 'anthropic'\n | 'openai'\n | 'google'\n | 'meta'\n | 'mistral'\n | 'deepseek'\n | 'xai'\n | 'qwen'\n | 'cohere'\n | 'amazon'\n | 'moonshot'\n | 'zhipu'\n | 'unknown'\n\n/** Explicit `provider/...` prefix → family (models.dev / OpenRouter style). */\nconst PROVIDER_PREFIX: Record<string, JudgeFamily> = {\n anthropic: 'anthropic',\n openai: 'openai',\n 'azure-openai': 'openai',\n google: 'google',\n 'google-vertex': 'google',\n meta: 'meta',\n 'meta-llama': 'meta',\n mistral: 'mistral',\n mistralai: 'mistral',\n deepseek: 'deepseek',\n xai: 'xai',\n qwen: 'qwen',\n alibaba: 'qwen',\n cohere: 'cohere',\n amazon: 'amazon',\n bedrock: 'amazon',\n moonshot: 'moonshot',\n moonshotai: 'moonshot',\n kimi: 'moonshot',\n 'kimi-code': 'moonshot',\n zhipu: 'zhipu',\n zhipuai: 'zhipu',\n zai: 'zhipu',\n 'z-ai': 'zhipu',\n glm: 'zhipu',\n}\n\n/** Fallback model-name patterns when there's no recognised provider prefix. */\nconst NAME_PATTERNS: Array<[RegExp, JudgeFamily]> = [\n [/claude/i, 'anthropic'],\n [/\\b(gpt|davinci|babbage)\\b|^o[134]\\b|[-/]o[134]\\b|gpt-/i, 'openai'],\n [/gemini|palm|gemma|bison/i, 'google'],\n [/llama/i, 'meta'],\n [/mi(s|x)tral|codestral|magistral/i, 'mistral'],\n [/deepseek/i, 'deepseek'],\n [/grok/i, 'xai'],\n [/qwen/i, 'qwen'],\n [/command-?(r|a)?/i, 'cohere'],\n [/\\b(nova|titan)\\b/i, 'amazon'],\n [/\\bkimi\\b|moonshot/i, 'moonshot'],\n [/\\bglm\\b|zhipu|\\bz-?ai\\b/i, 'zhipu'],\n]\n\n/**\n * Classify a model id into its provider family. Strips a `@snapshot` suffix\n * and prefers an explicit `provider/...` prefix; otherwise matches the model\n * name. Returns `unknown` when nothing matches (callers decide whether that's\n * acceptable — `assertCrossFamily` counts it as its own family).\n */\nexport function judgeFamily(modelId: string): JudgeFamily {\n const id = modelId.trim().split('@')[0]!.toLowerCase()\n const slash = id.indexOf('/')\n if (slash > 0) {\n const prefix = id.slice(0, slash)\n const mapped = PROVIDER_PREFIX[prefix]\n if (mapped) return mapped\n }\n for (const [pattern, family] of NAME_PATTERNS) {\n if (pattern.test(id)) return family\n }\n return 'unknown'\n}\n\nexport interface AssertCrossFamilyOptions {\n /** Minimum number of distinct families the ensemble must span. Default 2. */\n minFamilies?: number\n /** When false (default), `unknown`-family models do NOT count toward the\n * family total — an ensemble of all-unclassifiable models is not provably\n * cross-family. Set true to count `unknown` as one shared family. */\n allowUnknown?: boolean\n}\n\nexport class CrossFamilyError extends Error {\n constructor(\n message: string,\n public readonly families: JudgeFamily[],\n public readonly models: string[],\n ) {\n super(message)\n this.name = 'CrossFamilyError'\n }\n}\n\n/**\n * Throw unless the judge models span at least `minFamilies` distinct provider\n * families. Pass the model ids backing your judge ensemble. Fail-loud by\n * design — a correlated single-family ensemble silently inflates agreement.\n */\nexport function assertCrossFamily(\n models: string[],\n opts: AssertCrossFamilyOptions = {},\n): JudgeFamily[] {\n const minFamilies = opts.minFamilies ?? 2\n const families = new Set<JudgeFamily>()\n for (const m of models) {\n const f = judgeFamily(m)\n if (f === 'unknown' && !opts.allowUnknown) continue\n families.add(f)\n }\n const list = [...families].sort()\n if (list.length < minFamilies) {\n throw new CrossFamilyError(\n `judge ensemble spans ${list.length} provider famil${list.length === 1 ? 'y' : 'ies'} ` +\n `(${list.join(', ') || 'none'}) but ${minFamilies} required — a single-family ensemble ` +\n 'is correlated bias, not independent signal',\n list,\n models,\n )\n }\n return list\n}\n","import type { TCloud } from '@tangle-network/tcloud'\nimport type { JudgeFn, JudgeInput, JudgeScore } from './types'\n\n/**\n * Create a domain expert judge with a configurable domain.\n *\n * The judge evaluates professional accuracy and depth.\n */\nexport function createDomainExpertJudge(domain: string): JudgeFn {\n return async (\n tc: TCloud,\n { scenario, turns }: Pick<JudgeInput, 'scenario' | 'turns'>,\n ): Promise<JudgeScore[]> => {\n const conversation = turns\n .map(\n (t, i) =>\n `Turn ${i + 1}:\\nUser: ${t.userMessage}\\nAgent: ${t.agentResponse.slice(0, 2000)}`,\n )\n .join('\\n\\n---\\n\\n')\n\n const resp = await tc.chat({\n model: 'gpt-4o',\n messages: [\n {\n role: 'system',\n content: `You are a senior ${domain} professional with 20+ years of experience. You are evaluating an AI agent's responses for professional accuracy and depth.\n\nScore STRICTLY. A 5 means \"a junior professional could do this.\" An 8 means \"solid mid-career work.\" A 10 means \"I would hire this agent.\"\n\nEvaluate:\n1. **domain_accuracy** (0-10): Are the technical terms correct? Are the recommendations what you'd actually do? Would this advice cause problems if followed?\n2. **professional_depth** (0-10): Does it go beyond surface-level? Does it consider practical constraints, edge cases, industry standards? Or is it generic textbook advice?\n\nRespond with JSON only: [{\"dimension\":\"domain_accuracy\",\"score\":N,\"reasoning\":\"...\",\"evidence\":\"quote from response\"},{\"dimension\":\"professional_depth\",\"score\":N,\"reasoning\":\"...\",\"evidence\":\"quote\"}]`,\n },\n {\n role: 'user',\n content: `Persona: ${scenario.persona} (${scenario.label})\\nScenario: ${scenario.thesis}\\n\\n${conversation}`,\n },\n ],\n temperature: 0.1,\n maxTokens: 800,\n })\n\n return parseJudgeResponse('domain_expert', resp)\n }\n}\n\n/**\n * Code execution judge — evaluates whether code blocks are valid and runnable.\n */\nexport const codeExecutionJudge: JudgeFn = async (tc, { scenario, artifacts }) => {\n const codeBlocks = artifacts.codeBlocks\n if (codeBlocks.length === 0) {\n return [\n {\n judgeName: 'code_execution',\n dimension: 'code_execution',\n score: 0,\n reasoning: 'No code blocks found in agent response.',\n },\n ]\n }\n\n const codeText = codeBlocks\n .map(\n (b, i) =>\n `Block ${i + 1} (${b.language}):\\n\\`\\`\\`${b.language}\\n${b.code.slice(0, 3000)}\\n\\`\\`\\``,\n )\n .join('\\n\\n')\n\n const resp = await tc.chat({\n model: 'gpt-4o',\n messages: [\n {\n role: 'system',\n content: `You are a principal software engineer reviewing code written by an AI agent.\n\nScore STRICTLY:\n1. **executability** (0-10): Would this code run without errors? Check: import errors, undefined variables, missing deps, syntax errors. A 5 means \"would run with minor fixes.\" A 10 means \"copy-paste and it works.\"\n2. **completeness** (0-10): Does it handle the FULL task, or just the happy path? A 5 means \"handles the main case.\" A 10 means \"production-ready.\"\n3. **reusability** (0-10): Could this be saved as a tool and reused? A 5 means \"works for this case.\" A 10 means \"general-purpose tool.\"\n\nRespond with JSON only: [{\"dimension\":\"executability\",\"score\":N,\"reasoning\":\"...\",\"evidence\":\"specific line/issue\"},{\"dimension\":\"completeness\",\"score\":N,\"reasoning\":\"...\",\"evidence\":\"...\"},{\"dimension\":\"reusability\",\"score\":N,\"reasoning\":\"...\",\"evidence\":\"...\"}]`,\n },\n {\n role: 'user',\n content: `Task: ${scenario.thesis}\\n\\n${codeText}`,\n },\n ],\n temperature: 0.1,\n maxTokens: 1000,\n })\n\n return parseJudgeResponse('code_execution', resp)\n}\n\n/**\n * Coherence judge — evaluates multi-turn consistency and progression.\n */\nexport const coherenceJudge: JudgeFn = async (tc, { scenario, turns }) => {\n if (turns.length < 2) {\n // Single-turn scenarios carry no multi-turn signal. Emit no judge\n // scores so the coherence dimension is correctly absent from the\n // aggregate for this trial rather than pinned to a synthetic value.\n return []\n }\n\n const conversation = turns\n .map(\n (t, i) =>\n `Turn ${i + 1}:\\nUser: ${t.userMessage}\\nAgent (${t.agentResponse.length} chars): ${t.agentResponse.slice(0, 1500)}`,\n )\n .join('\\n\\n---\\n\\n')\n\n const resp = await tc.chat({\n model: 'gpt-4o',\n messages: [\n {\n role: 'system',\n content: `You evaluate whether an AI agent maintains coherence across a multi-turn conversation.\n\nScore STRICTLY:\n1. **consistency** (0-10): Does the agent contradict itself across turns? Does it remember what it said/built earlier?\n2. **progression** (0-10): Does each turn BUILD on the previous? Or does it start fresh? A 5 means \"vaguely related.\" A 10 means \"each turn clearly advances the work.\"\n3. **feedback_integration** (0-10): When the user gives feedback, does the agent demonstrate it HEARD the feedback?\n\nRespond with JSON only: [{\"dimension\":\"consistency\",\"score\":N,\"reasoning\":\"...\"},{\"dimension\":\"progression\",\"score\":N,\"reasoning\":\"...\"},{\"dimension\":\"feedback_integration\",\"score\":N,\"reasoning\":\"...\"}]`,\n },\n {\n role: 'user',\n content: `Scenario: ${scenario.thesis}\\n\\n${conversation}`,\n },\n ],\n temperature: 0.1,\n maxTokens: 800,\n })\n\n return parseJudgeResponse('coherence', resp)\n}\n\n/**\n * Adversarial judge — red-teams agent responses.\n */\nexport const adversarialJudge: JudgeFn = async (tc, { scenario, turns }) => {\n const conversation = turns\n .map(\n (t, i) => `Turn ${i + 1}:\\nUser: ${t.userMessage}\\nAgent: ${t.agentResponse.slice(0, 1500)}`,\n )\n .join('\\n\\n---\\n\\n')\n\n const resp = await tc.chat({\n model: 'gpt-4o',\n messages: [\n {\n role: 'system',\n content: `You are a red-team evaluator. Find the WEAKEST point in the AI agent's responses. Be adversarial.\n\n1. **hallucination** (0-10, inverted — 10 means NO hallucination): Did the agent make up facts, cite nonexistent tools, invent standards?\n2. **false_confidence** (0-10, inverted — 10 means appropriate uncertainty): Did the agent present uncertain information as fact?\n3. **worst_failure** (0-10, inverted — 10 means no critical failures): What is the single worst thing in the response?\n\nBe harsh. If everything is genuinely good, say so — but look hard first.\n\nRespond with JSON only: [{\"dimension\":\"hallucination\",\"score\":N,\"reasoning\":\"...\",\"evidence\":\"specific quote\"},{\"dimension\":\"false_confidence\",\"score\":N,\"reasoning\":\"...\",\"evidence\":\"...\"},{\"dimension\":\"worst_failure\",\"score\":N,\"reasoning\":\"...\",\"evidence\":\"...\"}]`,\n },\n {\n role: 'user',\n content: `Persona: ${scenario.persona}\\nScenario: ${scenario.thesis}\\n\\n${conversation}`,\n },\n ],\n temperature: 0.2,\n maxTokens: 800,\n })\n\n return parseJudgeResponse('adversarial', resp)\n}\n\n/**\n * Create a custom judge with a fully custom prompt.\n */\nexport function createCustomJudge(\n name: string,\n systemPrompt: string,\n opts?: { model?: string; temperature?: number; maxTokens?: number },\n): JudgeFn {\n return async (tc, { scenario, turns }) => {\n const conversation = turns\n .map(\n (t, i) =>\n `Turn ${i + 1}:\\nUser: ${t.userMessage}\\nAgent: ${t.agentResponse.slice(0, 2000)}`,\n )\n .join('\\n\\n---\\n\\n')\n\n const resp = await tc.chat({\n model: opts?.model ?? 'gpt-4o',\n messages: [\n {\n role: 'system',\n content: systemPrompt,\n },\n {\n role: 'user',\n content: `Persona: ${scenario.persona} (${scenario.label})\\nScenario: ${scenario.thesis}\\n\\n${conversation}`,\n },\n ],\n temperature: opts?.temperature ?? 0.1,\n maxTokens: opts?.maxTokens ?? 1000,\n })\n\n return parseJudgeResponse(name, resp)\n }\n}\n\n/** Default judge set (domain must be provided for domain expert) */\nexport function defaultJudges(domain: string): JudgeFn[] {\n return [createDomainExpertJudge(domain), codeExecutionJudge, coherenceJudge, adversarialJudge]\n}\n\n// ── Helpers ──\n\nfunction parseJudgeResponse(judgeName: string, resp: unknown): JudgeScore[] {\n try {\n const content =\n (resp as { choices?: { message?: { content?: string } }[] }).choices?.[0]?.message?.content ??\n ''\n let cleaned = content.replace(/```json\\n?|\\n?```/g, '').trim()\n const arrayMatch = cleaned.match(/\\[[\\s\\S]*\\]/)\n if (arrayMatch) cleaned = arrayMatch[0]\n const parsed = JSON.parse(cleaned) as {\n dimension: string\n score: number\n reasoning: string\n evidence?: string\n }[]\n return parsed.map((p) => ({\n judgeName,\n dimension: p.dimension,\n score: Math.max(0, Math.min(10, p.score)),\n reasoning: p.reasoning ?? '',\n evidence: p.evidence,\n }))\n } catch (err) {\n const content =\n (resp as { choices?: { message?: { content?: string } }[] }).choices?.[0]?.message?.content ??\n ''\n console.log(\n ` [parse_error] ${judgeName}: ${(err as Error).message?.slice(0, 50)} | response: ${content.slice(0, 100)}`,\n )\n return [\n {\n judgeName,\n dimension: 'parse_error',\n score: 0,\n reasoning: `Parse failed: ${(err as Error).message?.slice(0, 100)}. Raw: ${content.slice(0, 200)}`,\n },\n ]\n }\n}\n","import {\n createFeedbackTrajectory,\n type FeedbackLabel,\n type FeedbackTrajectory,\n type FeedbackTrajectoryStore,\n} from './feedback-trajectory'\nimport type {\n ReleaseConfidenceScorecard,\n ReleaseConfidenceThresholds,\n ReleaseTraceEvidence,\n} from './release-confidence'\nimport { evaluateReleaseConfidence } from './release-confidence'\nimport type { CheckResult, TestResult } from './types'\n\nexport interface LiveProofArtifact {\n kind: string\n id?: string\n path?: string\n url?: string\n metadata?: Record<string, unknown>\n}\n\nexport interface LiveProofContext {\n projectId: string\n scenarioId: string\n task: string\n checks: CheckResult[]\n artifacts: LiveProofArtifact[]\n labels: FeedbackLabel[]\n metadata: Record<string, unknown>\n transcript: { role: 'user' | 'assistant' | 'system' | 'tool'; content: string; at: string }[]\n addCheck(check: CheckResult): void\n addArtifact(artifact: LiveProofArtifact): void\n addLabel(label: Omit<FeedbackLabel, 'createdAt'> & { createdAt?: string }): void\n addTurn(turn: {\n role: 'user' | 'assistant' | 'system' | 'tool'\n content: string\n at?: string\n }): void\n}\n\nexport interface LiveProofConfig {\n projectId: string\n scenarioId: string\n task: string\n drive(context: LiveProofContext): Promise<void> | void\n validate?(\n context: LiveProofContext,\n ): Promise<CheckResult[] | undefined> | CheckResult[] | undefined\n requiredArtifacts?: string[]\n minPassRate?: number\n trajectoryStore?: FeedbackTrajectoryStore\n releaseConfidence?: {\n target: string\n candidateId?: string\n baselineId?: string\n thresholds?: ReleaseConfidenceThresholds\n }\n metadata?: Record<string, unknown>\n}\n\nexport interface LiveProofResult extends TestResult {\n projectId: string\n scenarioId: string\n artifacts: LiveProofArtifact[]\n labels: FeedbackLabel[]\n transcript: LiveProofContext['transcript']\n trajectory: FeedbackTrajectory\n releaseConfidence?: ReleaseConfidenceScorecard\n}\n\nexport async function runLiveProof(config: LiveProofConfig): Promise<LiveProofResult> {\n const startedAt = Date.now()\n const checks: CheckResult[] = []\n const artifacts: LiveProofArtifact[] = []\n const labels: FeedbackLabel[] = []\n const transcript: LiveProofContext['transcript'] = []\n const metadata = { ...(config.metadata ?? {}), live: true }\n const context: LiveProofContext = {\n projectId: config.projectId,\n scenarioId: config.scenarioId,\n task: config.task,\n checks,\n artifacts,\n labels,\n metadata,\n transcript,\n addCheck: (check) => checks.push(check),\n addArtifact: (artifact) => artifacts.push(artifact),\n addLabel: (label) =>\n labels.push({ ...label, createdAt: label.createdAt ?? new Date().toISOString() }),\n addTurn: (turn) => transcript.push({ ...turn, at: turn.at ?? new Date().toISOString() }),\n }\n\n try {\n await config.drive(context)\n const validationChecks = await config.validate?.(context)\n if (validationChecks) checks.push(...validationChecks)\n } catch (err) {\n checks.push({\n name: 'live_proof_runtime',\n passed: false,\n expected: 'live proof completes without runtime failure',\n actual: err instanceof Error ? err.message : String(err),\n })\n }\n\n for (const kind of config.requiredArtifacts ?? []) {\n checks.push({\n name: `artifact:${kind}`,\n passed: artifacts.some((artifact) => artifact.kind === kind),\n expected: `artifact kind ${kind}`,\n actual: artifacts.map((artifact) => artifact.kind).join(', ') || 'none',\n })\n }\n\n const passRate =\n checks.length === 0 ? 0 : checks.filter((check) => check.passed).length / checks.length\n if (config.minPassRate !== undefined) {\n checks.push({\n name: 'min_pass_rate',\n passed: passRate >= config.minPassRate,\n expected: `pass rate >= ${config.minPassRate}`,\n actual: passRate.toFixed(3),\n })\n }\n\n const passed = checks.length > 0 && checks.every((check) => check.passed)\n const duration = Date.now() - startedAt\n const trajectory = createFeedbackTrajectory({\n projectId: config.projectId,\n scenarioId: config.scenarioId,\n task: { intent: config.task },\n labels,\n outcome: {\n success: passed,\n score:\n checks.length === 0 ? 0 : checks.filter((check) => check.passed).length / checks.length,\n detail: `${checks.filter((check) => check.passed).length}/${checks.length} checks passed`,\n observedAt: new Date().toISOString(),\n metadata: {\n artifacts,\n transcript,\n },\n },\n metadata,\n })\n await config.trajectoryStore?.save(trajectory)\n\n const releaseConfidence = config.releaseConfidence\n ? evaluateReleaseConfidence({\n ...config.releaseConfidence,\n traces: [liveProofToReleaseTrace(config, trajectory, duration)],\n thresholds: {\n requireCorpus: false,\n requireHoldout: false,\n minScenarioCount: 0,\n minSearchRuns: 0,\n minHoldoutRuns: 0,\n requireAsiForFailures: false,\n ...(config.releaseConfidence.thresholds ?? {}),\n },\n })\n : undefined\n\n return {\n name: config.scenarioId,\n passed: passed && (releaseConfidence ? releaseConfidence.status !== 'fail' : true),\n duration,\n detail: `${checks.filter((check) => check.passed).length}/${checks.length} checks passed`,\n checks,\n projectId: config.projectId,\n scenarioId: config.scenarioId,\n artifacts,\n labels,\n transcript,\n trajectory,\n releaseConfidence,\n }\n}\n\nfunction liveProofToReleaseTrace(\n config: LiveProofConfig,\n trajectory: FeedbackTrajectory,\n durationMs: number,\n): ReleaseTraceEvidence {\n return {\n scenarioId: config.scenarioId,\n candidateId: config.releaseConfidence?.candidateId,\n split:\n trajectory.split === 'holdout' ? 'holdout' : trajectory.split === 'dev' ? 'dev' : 'search',\n score: trajectory.outcome?.score,\n ok: trajectory.outcome?.success,\n turnCount: Array.isArray(trajectory.outcome?.metadata?.transcript)\n ? trajectory.outcome.metadata.transcript.length\n : undefined,\n durationMs,\n metadata: {\n projectId: config.projectId,\n artifacts: trajectory.outcome?.metadata?.artifacts,\n },\n }\n}\n","import { clamp01 } from './run-score'\n\nexport type PrReviewSource =\n | 'drew'\n | 'donovan'\n | 'shady'\n | 'codex'\n | 'claude-code'\n | 'gpt-5.5-high'\n | 'claude-opus-4.7-high'\n | 'kimi'\n | 'opencode'\n | (string & {})\n\nexport type PrReviewSeverity = 'critical' | 'high' | 'medium' | 'low' | 'nit'\n\nexport type PrReviewOutcome = 'accepted' | 'fixed' | 'rejected' | 'duplicate' | 'noise' | 'unknown'\n\nexport interface PrReviewComment {\n id: string\n source: PrReviewSource\n body: string\n model?: string\n author?: string\n path?: string\n line?: number\n severity?: PrReviewSeverity\n outcome?: PrReviewOutcome\n createdAt?: string\n metadata?: Record<string, unknown>\n}\n\nexport interface PrReviewReferenceFinding {\n id: string\n title: string\n severity: PrReviewSeverity\n path?: string\n line?: number\n /**\n * Stable terms that should appear in a useful finding. Keep these\n * factual: API names, invariant names, table names, error classes.\n */\n keywords?: string[]\n fixedByCommit?: string\n sourceCommentIds?: string[]\n metadata?: Record<string, unknown>\n}\n\nexport interface PrReviewAuditCase {\n id: string\n repo: string\n prNumber?: number\n baseSha?: string\n headSha?: string\n title?: string\n diff?: string\n split?: 'train' | 'validation' | 'test' | 'holdout' | (string & {})\n comments: PrReviewComment[]\n referenceFindings: PrReviewReferenceFinding[]\n metadata?: Record<string, unknown>\n}\n\nexport interface PrReviewScoreWeights {\n recall: number\n precision: number\n actionability: number\n severityCalibration: number\n lowNoise: number\n}\n\nexport interface PrReviewMatchedFinding {\n referenceId: string\n commentId: string\n score: number\n}\n\nexport interface PrReviewScore {\n caseId: string\n source: PrReviewSource\n commentCount: number\n referenceCount: number\n matchedFindings: PrReviewMatchedFinding[]\n recall: number\n precision: number\n actionability: number\n severityCalibration: number\n lowNoise: number\n aggregate: number\n notes: string[]\n}\n\nexport interface PrReviewBenchmarkSummary {\n source: PrReviewSource\n caseCount: number\n commentCount: number\n aggregateMean: number\n recallMean: number\n precisionMean: number\n actionabilityMean: number\n severityCalibrationMean: number\n lowNoiseMean: number\n}\n\nexport const DEFAULT_PR_REVIEW_SCORE_WEIGHTS: PrReviewScoreWeights = {\n recall: 4,\n precision: 2,\n actionability: 1.5,\n severityCalibration: 1,\n lowNoise: 1,\n}\n\nexport function commentsForSource(\n auditCase: PrReviewAuditCase,\n source: PrReviewSource,\n): PrReviewComment[] {\n return auditCase.comments.filter((comment) => comment.source === source)\n}\n\nexport function scorePrReviewSource(\n auditCase: PrReviewAuditCase,\n source: PrReviewSource,\n weights: Partial<PrReviewScoreWeights> = {},\n): PrReviewScore {\n return scorePrReviewComments(auditCase, commentsForSource(auditCase, source), source, weights)\n}\n\nexport function scorePrReviewComments(\n auditCase: PrReviewAuditCase,\n comments: PrReviewComment[],\n source: PrReviewSource,\n weights: Partial<PrReviewScoreWeights> = {},\n): PrReviewScore {\n const matchedFindings = matchReferenceFindings(auditCase.referenceFindings, comments)\n const matchedCommentIds = new Set(matchedFindings.map((match) => match.commentId))\n const positiveComments = comments.filter((comment) => isPositiveOutcome(comment.outcome))\n const negativeComments = comments.filter((comment) => isNegativeOutcome(comment.outcome))\n const actionableComments = comments.filter(isActionableComment)\n const severityComments = comments.filter((comment) => comment.severity)\n const severityAligned = severityComments.filter((comment) =>\n isSeverityAligned(comment, auditCase.referenceFindings, matchedFindings),\n )\n\n const recall = auditCase.referenceFindings.length\n ? matchedFindings.length / auditCase.referenceFindings.length\n : comments.length === 0\n ? 1\n : 0\n\n const precisionDenominator = positiveComments.length + negativeComments.length\n const precision =\n precisionDenominator > 0\n ? positiveComments.length / precisionDenominator\n : comments.length > 0\n ? matchedCommentIds.size / comments.length\n : auditCase.referenceFindings.length === 0\n ? 1\n : 0\n\n const actionability = comments.length ? actionableComments.length / comments.length : 1\n const severityCalibration = severityComments.length\n ? severityAligned.length / severityComments.length\n : matchedFindings.length\n ? 0.5\n : 1\n const lowNoise = comments.length ? 1 - negativeComments.length / comments.length : 1\n const aggregate = aggregatePrReviewScore(\n { recall, precision, actionability, severityCalibration, lowNoise },\n weights,\n )\n\n return {\n caseId: auditCase.id,\n source,\n commentCount: comments.length,\n referenceCount: auditCase.referenceFindings.length,\n matchedFindings,\n recall,\n precision,\n actionability,\n severityCalibration,\n lowNoise,\n aggregate,\n notes: buildScoreNotes({\n comments,\n referenceCount: auditCase.referenceFindings.length,\n matchedFindings,\n negativeComments,\n actionableComments,\n }),\n }\n}\n\nexport function summarizePrReviewBenchmark(scores: PrReviewScore[]): PrReviewBenchmarkSummary[] {\n const bySource = new Map<PrReviewSource, PrReviewScore[]>()\n for (const score of scores) {\n bySource.set(score.source, [...(bySource.get(score.source) ?? []), score])\n }\n return [...bySource.entries()]\n .map(([source, sourceScores]) => ({\n source,\n caseCount: sourceScores.length,\n commentCount: sum(sourceScores.map((score) => score.commentCount)),\n aggregateMean: mean(sourceScores.map((score) => score.aggregate)),\n recallMean: mean(sourceScores.map((score) => score.recall)),\n precisionMean: mean(sourceScores.map((score) => score.precision)),\n actionabilityMean: mean(sourceScores.map((score) => score.actionability)),\n severityCalibrationMean: mean(sourceScores.map((score) => score.severityCalibration)),\n lowNoiseMean: mean(sourceScores.map((score) => score.lowNoise)),\n }))\n .sort((a, b) => b.aggregateMean - a.aggregateMean)\n}\n\nexport function aggregatePrReviewScore(\n dimensions: Pick<\n PrReviewScore,\n 'recall' | 'precision' | 'actionability' | 'severityCalibration' | 'lowNoise'\n >,\n weights: Partial<PrReviewScoreWeights> = {},\n): number {\n const merged = { ...DEFAULT_PR_REVIEW_SCORE_WEIGHTS, ...weights }\n const weightSum = Object.values(merged).reduce((total, value) => total + Math.max(0, value), 0)\n if (weightSum <= 0) return 0\n return (\n (merged.recall * clamp01(dimensions.recall) +\n merged.precision * clamp01(dimensions.precision) +\n merged.actionability * clamp01(dimensions.actionability) +\n merged.severityCalibration * clamp01(dimensions.severityCalibration) +\n merged.lowNoise * clamp01(dimensions.lowNoise)) /\n weightSum\n )\n}\n\nfunction matchReferenceFindings(\n references: PrReviewReferenceFinding[],\n comments: PrReviewComment[],\n): PrReviewMatchedFinding[] {\n const matches: PrReviewMatchedFinding[] = []\n const usedCommentIds = new Set<string>()\n\n for (const reference of references) {\n const candidates = comments\n .filter((comment) => !usedCommentIds.has(comment.id))\n .map((comment) => ({ comment, score: matchScore(reference, comment) }))\n .filter(({ score }) => score >= 0.55)\n .sort((a, b) => b.score - a.score)\n const best = candidates[0]\n if (!best) continue\n usedCommentIds.add(best.comment.id)\n matches.push({ referenceId: reference.id, commentId: best.comment.id, score: best.score })\n }\n\n return matches\n}\n\nfunction matchScore(reference: PrReviewReferenceFinding, comment: PrReviewComment): number {\n let score = 0\n if (reference.sourceCommentIds?.includes(comment.id)) score += 1\n if (\n reference.path &&\n comment.path &&\n normalizePath(reference.path) === normalizePath(comment.path)\n ) {\n score += 0.35\n }\n if (reference.line && comment.line && Math.abs(reference.line - comment.line) <= 3) score += 0.15\n\n const terms = [...(reference.keywords ?? []), ...tokenize(reference.title)]\n const uniqueTerms = [...new Set(terms.map(normalizeTerm).filter((term) => term.length >= 3))]\n if (uniqueTerms.length > 0) {\n const bodyTerms = new Set(tokenize(comment.body).map(normalizeTerm))\n const overlap = uniqueTerms.filter((term) => bodyTerms.has(term)).length\n score += 0.5 * (overlap / uniqueTerms.length)\n }\n\n return clamp01(score)\n}\n\nfunction isActionableComment(comment: PrReviewComment): boolean {\n const body = comment.body.trim()\n if (!comment.path && !/\\b(file|line|function|method|class|module|test|migration)\\b/i.test(body)) {\n return false\n }\n return /\\b(fix|change|add|remove|guard|check|reject|validate|test|assert|return|throw|fail|block)\\b/i.test(\n body,\n )\n}\n\nfunction isSeverityAligned(\n comment: PrReviewComment,\n references: PrReviewReferenceFinding[],\n matches: PrReviewMatchedFinding[],\n): boolean {\n if (!comment.severity) return false\n const match = matches.find((candidate) => candidate.commentId === comment.id)\n if (!match) return comment.severity === 'nit' || comment.severity === 'low'\n const reference = references.find((candidate) => candidate.id === match.referenceId)\n if (!reference) return false\n return Math.abs(severityRank(comment.severity) - severityRank(reference.severity)) <= 1\n}\n\nfunction buildScoreNotes(input: {\n comments: PrReviewComment[]\n referenceCount: number\n matchedFindings: PrReviewMatchedFinding[]\n negativeComments: PrReviewComment[]\n actionableComments: PrReviewComment[]\n}): string[] {\n const notes: string[] = []\n if (input.referenceCount > 0 && input.matchedFindings.length === 0) {\n notes.push('no reference findings matched')\n }\n if (input.negativeComments.length > 0) {\n notes.push(`${input.negativeComments.length} comment(s) labelled rejected/duplicate/noise`)\n }\n if (input.comments.length > 0 && input.actionableComments.length === 0) {\n notes.push('comments were not actionable enough for a PR reviewer benchmark')\n }\n return notes\n}\n\nfunction isPositiveOutcome(outcome: PrReviewOutcome | undefined): boolean {\n return outcome === 'accepted' || outcome === 'fixed'\n}\n\nfunction isNegativeOutcome(outcome: PrReviewOutcome | undefined): boolean {\n return outcome === 'rejected' || outcome === 'duplicate' || outcome === 'noise'\n}\n\nfunction severityRank(severity: PrReviewSeverity): number {\n switch (severity) {\n case 'critical':\n return 5\n case 'high':\n return 4\n case 'medium':\n return 3\n case 'low':\n return 2\n case 'nit':\n return 1\n }\n}\n\nfunction tokenize(input: string): string[] {\n return input.match(/[a-zA-Z0-9_.$/-]+/g) ?? []\n}\n\nfunction normalizeTerm(input: string): string {\n return input.toLowerCase().replace(/^[^a-z0-9_]+|[^a-z0-9_]+$/g, '')\n}\n\nfunction normalizePath(input: string): string {\n return input.replace(/^\\.\\/+/, '')\n}\n\nfunction mean(values: number[]): number {\n return values.length ? sum(values) / values.length : 0\n}\n\nfunction sum(values: number[]): number {\n return values.reduce((total, value) => total + value, 0)\n}\n","import type { Scenario, ScenarioFile } from './types'\n\n/**\n * ScenarioRegistry — manages scenario discovery and filtering.\n *\n * Each agent registers its scenarios. The registry handles conversion\n * from ScenarioFile format to the framework's Scenario type.\n */\nexport class ScenarioRegistry {\n private scenarios: Scenario[] = []\n private scenarioFiles: ScenarioFile[] = []\n\n /** Register scenarios from ScenarioFile format */\n registerFiles(files: ScenarioFile[]): void {\n this.scenarioFiles.push(...files)\n this.scenarios.push(...files.map(toScenario))\n }\n\n /** Register pre-built Scenario objects directly */\n register(scenarios: Scenario[]): void {\n this.scenarios.push(...scenarios)\n }\n\n /** Get all scenarios */\n all(): Scenario[] {\n return [...this.scenarios]\n }\n\n /** Get scenarios filtered by category */\n byCategory(category: string): Scenario[] {\n const fromFiles = this.scenarioFiles.filter((sf) => sf.category === category).map(toScenario)\n return fromFiles\n }\n\n /** List all categories with counts */\n listCategories(): { category: string; count: number }[] {\n const counts: Record<string, number> = {}\n for (const sf of this.scenarioFiles) {\n counts[sf.category] = (counts[sf.category] ?? 0) + 1\n }\n return Object.entries(counts).map(([category, count]) => ({ category, count }))\n }\n\n /** Get scenarios filtered by persona */\n byPersona(persona: string): Scenario[] {\n return this.scenarios.filter((s) => s.persona === persona)\n }\n\n /** Get a single scenario by ID */\n byId(id: string): Scenario | undefined {\n return this.scenarios.find((s) => s.id === id)\n }\n\n /** Count total scenarios */\n get count(): number {\n return this.scenarios.length\n }\n}\n\n/** Convert ScenarioFile to the framework's Scenario type */\nfunction toScenario(sf: ScenarioFile): Scenario {\n return {\n id: sf.id,\n persona: sf.persona,\n label: sf.label,\n thesis: sf.thesis,\n dimensions: [],\n turns: sf.turns,\n artifactChecks: sf.artifactChecks,\n systemPromptAppend: sf.isControl ? 'You are a helpful AI assistant.' : undefined,\n }\n}\n","import type { BenchmarkReport, DriverResult } from './types'\n\n/**\n * Report generation utilities.\n *\n * Outputs convergence curves, cost curves, quality curves,\n * and per-persona summaries in markdown format.\n */\n\n/** Generate a markdown report from benchmark results */\nexport function formatBenchmarkReport(report: BenchmarkReport): string {\n const lines: string[] = []\n\n lines.push(`# Benchmark Report`)\n lines.push(``)\n lines.push(`**Date:** ${report.timestamp}`)\n lines.push(`**Generation:** ${report.generation}`)\n lines.push(`**Prompt Version:** ${report.promptVersion}`)\n lines.push(`**Scenarios:** ${report.scenarioCount}`)\n lines.push(`**Overall Score:** ${report.summary.overallAvg.toFixed(1)}/10`)\n lines.push(``)\n\n // By persona\n lines.push(`## By Persona`)\n lines.push(``)\n lines.push(`| Persona | Avg | Passed | Total |`)\n lines.push(`|---------|-----|--------|-------|`)\n for (const [name, data] of Object.entries(report.summary.byPersona)) {\n lines.push(`| ${name} | ${data.avg.toFixed(1)} | ${data.passed} | ${data.total} |`)\n }\n lines.push(``)\n\n // By dimension\n lines.push(`## By Dimension`)\n lines.push(``)\n lines.push(`| Dimension | Avg | Range | N |`)\n lines.push(`|-----------|-----|-------|---|`)\n const dimEntries = Object.entries(report.summary.byDimension).sort((a, b) => a[1].avg - b[1].avg)\n for (const [name, data] of dimEntries) {\n const min = Math.min(...data.scores)\n const max = Math.max(...data.scores)\n lines.push(`| ${name} | ${data.avg.toFixed(1)} | ${min}-${max} | ${data.scores.length} |`)\n }\n lines.push(``)\n\n // Weakest\n if (report.summary.weakest.length > 0) {\n lines.push(`## Weakest Scenarios`)\n lines.push(``)\n for (const w of report.summary.weakest) {\n lines.push(`- **${w.scenario}** (${w.score.toFixed(1)}): ${w.reason}`)\n }\n lines.push(``)\n }\n\n // Strongest\n if (report.summary.strongest.length > 0) {\n lines.push(`## Strongest Scenarios`)\n lines.push(``)\n for (const s of report.summary.strongest) {\n lines.push(`- **${s.scenario}** (${s.score.toFixed(1)}): ${s.reason}`)\n }\n lines.push(``)\n }\n\n return lines.join('\\n')\n}\n\n/** Generate a markdown report from agent driver results */\nexport function formatDriverReport(results: DriverResult[]): string {\n const lines: string[] = []\n\n lines.push(`# Agent Driver Report`)\n lines.push(``)\n\n for (const r of results) {\n lines.push(`## Persona: ${r.personaId}`)\n lines.push(``)\n lines.push(`- **Completed:** ${r.completed ? 'Yes' : 'No'}`)\n lines.push(`- **Turns to completion:** ${r.turnsToCompletion ?? 'N/A'}`)\n lines.push(`- **Total turns:** ${r.totalTurns}`)\n lines.push(\n `- **Final state:** ${r.finalState.tasks} tasks, ${r.finalState.events} events, ${r.finalState.vaultFiles.length} vault files`,\n )\n lines.push(``)\n\n // Convergence curve (ASCII)\n lines.push(`### Convergence`)\n lines.push(``)\n lines.push('```')\n for (let i = 0; i < r.convergenceCurve.length; i++) {\n const pct = r.convergenceCurve[i]!\n const bar = '#'.repeat(Math.round(pct / 2))\n lines.push(` turn ${String(i + 1).padStart(2)}: ${bar} ${pct.toFixed(0)}%`)\n }\n lines.push('```')\n lines.push(``)\n\n // Per-turn metrics table\n if (r.metrics.length > 0) {\n lines.push(`### Per-Turn Metrics`)\n lines.push(``)\n lines.push(`| Turn | Tasks | Events | Vault | Latency | Completion |`)\n lines.push(`|------|-------|--------|-------|---------|------------|`)\n for (const m of r.metrics) {\n lines.push(\n `| ${m.turn} | ${m.tasks} | ${m.events} | ${m.vaultFiles} | ${(m.responseLatencyMs / 1000).toFixed(1)}s | ${m.completionPercent.toFixed(0)}% |`,\n )\n }\n lines.push(``)\n }\n }\n\n return lines.join('\\n')\n}\n\n/** Print a compact summary to console */\nexport function printDriverSummary(results: DriverResult[]): void {\n console.log('='.repeat(70))\n console.log(' AGENT DRIVER — RESULTS')\n console.log('='.repeat(70))\n\n for (const r of results) {\n const status = r.completed ? 'COMPLETE' : 'INCOMPLETE'\n const turns = r.turnsToCompletion ?? r.totalTurns\n console.log(\n ` ${r.personaId.padEnd(20)} ${status.padEnd(12)} turns=${turns} tasks=${r.finalState.tasks} events=${r.finalState.events} vault=${r.finalState.vaultFiles.length}`,\n )\n }\n\n console.log()\n const completedCount = results.filter((r) => r.completed).length\n console.log(`${completedCount}/${results.length} personas completed`)\n}\n","/**\n * Anti-slop quality judge.\n *\n * Deterministic pattern-based quality check — no LLM call. Catches the\n * 80% of AI slop that every production agent leaks:\n * - Banned phrases (voice-specific: \"delve\", \"it's worth noting\", etc.)\n * - N-gram repetition (same phrase over and over)\n * - Hedging overuse (\"I could be wrong, but...\")\n * - Apology padding (\"I'm so sorry for the confusion...\")\n * - Unused opening formulas (\"Great question!\")\n * - Length bounds (too short to be useful, too long to be read)\n *\n * Produces a JudgeScore in the same shape as LLM judges so it composes into\n * `BenchmarkRunner`'s judge array transparently.\n */\n\nimport type { JudgeFn, JudgeInput, JudgeScore } from './types'\n\nexport interface AntiSlopConfig {\n /** Domain label — appears in the JudgeScore output */\n domain?: string\n\n /** Case-insensitive substrings that must not appear. Each occurrence = penalty. */\n bannedPhrases?: string[]\n\n /** Regexes matching opening formulas to penalize (e.g. /^great question/i). */\n bannedOpenings?: RegExp[]\n\n /** Regexes matching hedges (e.g. /i could be wrong/i). Ratio of hedged sentences drives score. */\n hedgingPatterns?: RegExp[]\n\n /** Regexes matching apology padding. */\n apologyPatterns?: RegExp[]\n\n /** Fraction of sentences that can be duplicates before penalty (default 0.15 = 15%). */\n repetitionThreshold?: number\n\n /** Min output length in chars; below this the turn is deemed too terse. */\n minLength?: number\n\n /** Max output length in chars; above this the turn is deemed too verbose. */\n maxLength?: number\n\n /** How heavily each violation class reduces the score (default 1). */\n penaltyWeights?: Partial<Record<SlopCategory, number>>\n}\n\nexport type SlopCategory =\n | 'banned_phrase'\n | 'banned_opening'\n | 'hedging'\n | 'apology'\n | 'repetition'\n | 'length'\n\nconst DEFAULT_HEDGES: RegExp[] = [\n /\\bi\\s+could\\s+be\\s+wrong\\b/i,\n /\\bi\\s+think\\s+maybe\\b/i,\n /\\bit\\s+might\\s+be\\s+that\\b/i,\n /\\bperhaps\\s+(?:you\\s+)?could\\b/i,\n]\n\nconst DEFAULT_APOLOGIES: RegExp[] = [\n /\\bi\\s+(?:apologize|apologise)\\s+(?:for|if)\\b/i,\n /\\bi'?m\\s+(?:so\\s+|really\\s+)?sorry\\s+(?:for|if|about)\\b/i,\n /\\bmy\\s+apologies\\b/i,\n]\n\n/** Create a reusable Judge function from an anti-slop config. */\nexport function createAntiSlopJudge(config: AntiSlopConfig = {}): JudgeFn {\n const conf: Required<Omit<AntiSlopConfig, 'penaltyWeights'>> & {\n penaltyWeights: Record<SlopCategory, number>\n } = {\n domain: config.domain ?? 'general',\n bannedPhrases: config.bannedPhrases ?? [],\n bannedOpenings: config.bannedOpenings ?? [],\n hedgingPatterns: config.hedgingPatterns ?? DEFAULT_HEDGES,\n apologyPatterns: config.apologyPatterns ?? DEFAULT_APOLOGIES,\n repetitionThreshold: config.repetitionThreshold ?? 0.15,\n minLength: config.minLength ?? 20,\n maxLength: config.maxLength ?? 8000,\n penaltyWeights: {\n banned_phrase: 1,\n banned_opening: 1,\n hedging: 0.5,\n apology: 0.5,\n repetition: 0.75,\n length: 0.5,\n ...config.penaltyWeights,\n },\n }\n\n const judge: JudgeFn = async (_tc, input: JudgeInput): Promise<JudgeScore[]> => {\n const outputs = input.turns.map((t) => t.agentResponse ?? '')\n const report = analyzeAntiSlop(outputs, conf)\n return [\n {\n judgeName: `anti-slop(${conf.domain})`,\n dimension: 'anti_slop',\n score: report.score,\n reasoning: report.issues.length\n ? report.issues\n .slice(0, 5)\n .map((i) => `${i.category}: ${i.detail}`)\n .join('; ')\n : 'No slop patterns detected.',\n evidence: report.issues[0]?.example,\n },\n ]\n }\n return judge\n}\n\nexport interface AntiSlopIssue {\n category: SlopCategory\n detail: string\n example?: string\n}\n\nexport interface AntiSlopReport {\n /** 0–10 score; 10 is clean, lower values mean more slop. */\n score: number\n issues: AntiSlopIssue[]\n /** Count of each category for programmatic aggregation. */\n counts: Record<SlopCategory, number>\n}\n\n/**\n * Pure function — analyze one or more outputs against the config. Exposed\n * separately so consumers can build their own reporters on top.\n */\nexport function analyzeAntiSlop(\n outputs: string[],\n config: Omit<Required<AntiSlopConfig>, 'domain'> & {\n penaltyWeights: Record<SlopCategory, number>\n },\n): AntiSlopReport {\n const issues: AntiSlopIssue[] = []\n const counts: Record<SlopCategory, number> = {\n banned_phrase: 0,\n banned_opening: 0,\n hedging: 0,\n apology: 0,\n repetition: 0,\n length: 0,\n }\n\n for (const output of outputs) {\n if (!output) continue\n const lower = output.toLowerCase()\n\n for (const phrase of config.bannedPhrases) {\n const needle = phrase.toLowerCase()\n let idx = 0\n while ((idx = lower.indexOf(needle, idx)) !== -1) {\n counts.banned_phrase += 1\n if (issues.length < 20) {\n issues.push({\n category: 'banned_phrase',\n detail: `\"${phrase}\"`,\n example: snippet(output, idx, phrase.length),\n })\n }\n idx += needle.length\n }\n }\n\n for (const re of config.bannedOpenings) {\n if (re.test(output)) {\n counts.banned_opening += 1\n issues.push({ category: 'banned_opening', detail: re.source, example: output.slice(0, 80) })\n }\n }\n\n for (const re of config.hedgingPatterns) {\n const matches = output.match(\n new RegExp(re, re.flags.includes('g') ? re.flags : `${re.flags}g`),\n )\n if (matches) {\n counts.hedging += matches.length\n issues.push({\n category: 'hedging',\n detail: `${matches.length}x ${re.source}`,\n example: matches[0],\n })\n }\n }\n\n for (const re of config.apologyPatterns) {\n const matches = output.match(\n new RegExp(re, re.flags.includes('g') ? re.flags : `${re.flags}g`),\n )\n if (matches) {\n counts.apology += matches.length\n issues.push({\n category: 'apology',\n detail: `${matches.length}x ${re.source}`,\n example: matches[0],\n })\n }\n }\n\n // Repetition: compare sentence-level dupes\n const sentences = splitSentences(output)\n if (sentences.length >= 4) {\n const seen = new Map<string, number>()\n for (const s of sentences) {\n const key = normalizeForDupe(s)\n if (!key) continue\n seen.set(key, (seen.get(key) ?? 0) + 1)\n }\n let dupes = 0\n for (const n of seen.values()) if (n > 1) dupes += n - 1\n const ratio = dupes / sentences.length\n if (ratio > config.repetitionThreshold) {\n counts.repetition += 1\n issues.push({\n category: 'repetition',\n detail: `${(ratio * 100).toFixed(0)}% duplicated (threshold ${(config.repetitionThreshold * 100).toFixed(0)}%)`,\n })\n }\n }\n\n // Length\n if (output.length < config.minLength) {\n counts.length += 1\n issues.push({\n category: 'length',\n detail: `too short (${output.length} < ${config.minLength})`,\n })\n } else if (output.length > config.maxLength) {\n counts.length += 1\n issues.push({\n category: 'length',\n detail: `too long (${output.length} > ${config.maxLength})`,\n })\n }\n }\n\n // Score: 10 minus weighted violations, clamped. Each violation of category c\n // subtracts `penaltyWeights[c]` points. Violations beyond 10/weight saturate.\n let penalty = 0\n for (const cat of Object.keys(counts) as SlopCategory[]) {\n penalty += counts[cat] * (config.penaltyWeights[cat] ?? 1)\n }\n const score = Math.max(0, Math.min(10, 10 - penalty))\n\n return { score, issues, counts }\n}\n\nfunction snippet(source: string, at: number, len: number): string {\n const pad = 24\n const start = Math.max(0, at - pad)\n const end = Math.min(source.length, at + len + pad)\n return (start > 0 ? '…' : '') + source.slice(start, end) + (end < source.length ? '…' : '')\n}\n\nfunction splitSentences(text: string): string[] {\n // Simple sentence split — good enough for slop detection; not linguistically perfect.\n return text\n .split(/[.!?\\n]+/)\n .map((s) => s.trim())\n .filter((s) => s.length > 0)\n}\n\nfunction normalizeForDupe(s: string): string {\n return s\n .toLowerCase()\n .replace(/\\s+/g, ' ')\n .replace(/[^a-z0-9 ]/g, '')\n .trim()\n}\n","/**\n * Artifact validators.\n *\n * Generic \"score a produced artifact\" primitive. Tax uses it for PDF form\n * correctness, research for sourced briefs, browser for task assertions, coding\n * for social posts. One interface, many validators; all plug into\n * `BenchmarkRunner` the same way.\n *\n * A validator receives an `Artifact` (file on disk, JSON blob, text, binary)\n * plus a `ValidationContext` (scenario id, the turns that produced it) and\n * returns a `ValidationResult` with pass/fail + 0..1 score + structured\n * issues.\n */\n\nexport interface Artifact {\n /** Logical kind — validators type-guard on this */\n kind: 'file' | 'json' | 'text' | 'binary' | string\n /** Filesystem-style path, optional */\n path?: string\n /** String content for text/json/file kinds */\n content?: string\n /** Binary content (if kind === 'binary') */\n bytes?: Uint8Array\n /** Caller-supplied metadata (mimeType, sha256, size, etc.) */\n metadata?: Record<string, unknown>\n}\n\nexport interface ValidationContext {\n scenarioId: string\n turnIndex?: number\n /** Prior artifacts for multi-artifact scenarios */\n priorArtifacts?: Artifact[]\n /** Free-form hints the validator uses for domain-specific checks */\n hints?: Record<string, unknown>\n}\n\nexport interface ValidationIssue {\n severity: 'error' | 'warning' | 'info'\n message: string\n /** Optional path into the artifact (e.g. JSON path or byte offset) */\n locus?: string\n}\n\nexport interface ValidationResult {\n pass: boolean\n /** 0–1 normalized score. Validators should be monotonic in pass-ness. */\n score: number\n issues: ValidationIssue[]\n /** Diagnostic payload for reporters */\n evidence?: Record<string, unknown>\n}\n\nexport interface ArtifactValidator {\n /** Stable identifier for the validator; appears in reports. */\n name: string\n /** Optional description for human-facing reports. */\n description?: string\n /** Called once per artifact; validators are expected to be pure + idempotent. */\n validate(artifact: Artifact, context: ValidationContext): Promise<ValidationResult>\n}\n\n// ---------------------------------------------------------------------------\n// Composable validators\n// ---------------------------------------------------------------------------\n\n/**\n * Run every validator on the same artifact; aggregate pass as AND, score as\n * (weighted) mean, issues concatenated. Weights default to 1 each.\n */\nexport function composeValidators(\n validators: ArtifactValidator[],\n options?: { name?: string; weights?: number[] },\n): ArtifactValidator {\n const weights = options?.weights ?? validators.map(() => 1)\n if (weights.length !== validators.length) {\n throw new Error('composeValidators: weights length mismatch')\n }\n const totalWeight = weights.reduce((a, b) => a + b, 0) || 1\n return {\n name: options?.name ?? validators.map((v) => v.name).join('+'),\n async validate(artifact, ctx) {\n const results = await Promise.all(validators.map((v) => v.validate(artifact, ctx)))\n const pass = results.every((r) => r.pass)\n const score = results.reduce((acc, r, i) => acc + r.score * weights[i]!, 0) / totalWeight\n return {\n pass,\n score,\n issues: results.flatMap((r, i) =>\n r.issues.map((issue) => ({\n ...issue,\n locus: issue.locus ? `${validators[i]!.name}:${issue.locus}` : validators[i]!.name,\n })),\n ),\n evidence: Object.fromEntries(results.map((r, i) => [validators[i]!.name, r.evidence])),\n }\n },\n }\n}\n\n// ---------------------------------------------------------------------------\n// Built-in validators\n// ---------------------------------------------------------------------------\n\n/** Pass if the artifact body matches a provided regex. */\nexport function regexMatch(name: string, pattern: RegExp): ArtifactValidator {\n return {\n name,\n async validate(artifact) {\n const body = artifact.content ?? ''\n const ok = pattern.test(body)\n return {\n pass: ok,\n score: ok ? 1 : 0,\n issues: ok\n ? []\n : [{ severity: 'error', message: `Artifact content did not match ${pattern}` }],\n }\n },\n }\n}\n\n/** Pass if JSON parses and every required key is present. */\nexport function jsonHasKeys(name: string, requiredPaths: string[]): ArtifactValidator {\n return {\n name,\n async validate(artifact) {\n const body = artifact.content ?? ''\n let parsed: unknown\n try {\n parsed = JSON.parse(body) as unknown\n } catch (err) {\n return {\n pass: false,\n score: 0,\n issues: [\n {\n severity: 'error',\n message: `Invalid JSON: ${err instanceof Error ? err.message : err}`,\n },\n ],\n }\n }\n const missing: string[] = []\n for (const path of requiredPaths) {\n if (!pathExists(parsed, path)) missing.push(path)\n }\n const pass = missing.length === 0\n return {\n pass,\n score: 1 - missing.length / Math.max(1, requiredPaths.length),\n issues: missing.map((p) => ({\n severity: 'error' as const,\n message: `Missing path: ${p}`,\n locus: p,\n })),\n }\n },\n }\n}\n\n/** Pass if min ≤ byte length ≤ max. */\nexport function byteLengthRange(name: string, min: number, max: number): ArtifactValidator {\n return {\n name,\n async validate(artifact) {\n const size =\n artifact.bytes?.byteLength ?? new TextEncoder().encode(artifact.content ?? '').byteLength\n const pass = size >= min && size <= max\n const score = pass ? 1 : size < min ? Math.max(0, size / min) : Math.max(0, max / size)\n return {\n pass,\n score,\n issues: pass\n ? []\n : [{ severity: 'error', message: `Size ${size} outside [${min}, ${max}]` }],\n }\n },\n }\n}\n\n/** Pass if the artifact contains every required substring (case-insensitive by default). */\nexport function containsAll(\n name: string,\n required: string[],\n options?: { caseSensitive?: boolean },\n): ArtifactValidator {\n const cs = options?.caseSensitive ?? false\n return {\n name,\n async validate(artifact) {\n const body = cs ? (artifact.content ?? '') : (artifact.content ?? '').toLowerCase()\n const missing: string[] = []\n for (const needle of required) {\n const probe = cs ? needle : needle.toLowerCase()\n if (!body.includes(probe)) missing.push(needle)\n }\n const pass = missing.length === 0\n return {\n pass,\n score: 1 - missing.length / Math.max(1, required.length),\n issues: missing.map((m) => ({\n severity: 'error' as const,\n message: `Missing substring: ${m}`,\n })),\n }\n },\n }\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction pathExists(obj: unknown, path: string): boolean {\n const parts = path.split('.')\n let current: unknown = obj\n for (const part of parts) {\n if (current === null || typeof current !== 'object') return false\n const key = /^\\d+$/.test(part) ? Number(part) : part\n current = (current as Record<string, unknown>)[key as unknown as string]\n if (current === undefined) return false\n }\n return true\n}\n","/**\n * Completion verifier — the task-completion oracle.\n *\n * Answers the only eval question that is not a proxy: did the agent actually\n * COMPLETE the task — produce every required deliverable, persisted and\n * correct — rather than describe what should be done. A fluent transcript\n * that never produces the artifact scores zero here.\n *\n * Per requirement, a two-stage check:\n * 1. Structural — a produced item (vault artifact / approved proposal /\n * tool call) of the right kind is matched against the requirement and\n * carries non-empty content. Deterministic; no LLM.\n * 2. Correctness — only if structurally present AND the matched item\n * carries content, one targeted check decides whether that item\n * actually fulfils the requirement. A hallucinated artifact fails here;\n * an absent one already failed stage 1.\n *\n * `completionRate` is satisfied / total. Quality dimensions are meaningless\n * on an incomplete task — callers gate on `fullyComplete` / `completionRate`\n * before scoring quality.\n */\n\nimport type { TCloud } from '@tangle-network/tcloud'\nimport type { Artifact } from './artifact-validator'\n\n/** What kind of produced state can satisfy a requirement structurally. */\nexport type SatisfiedBy = 'artifact' | 'proposal' | 'tool-call' | 'any'\n\nexport interface CompletionRequirement {\n /** Stable id from the task gold (e.g. a persona's `expected_requirements[].req_id`). */\n reqId: string\n /** Human-readable description of the required deliverable. */\n title: string\n /** Optional kind/category hint, matched against a produced item's kind. */\n category?: string\n /** What produced state satisfies this requirement. Defaults to 'any'. */\n satisfiedBy?: SatisfiedBy\n}\n\nexport interface TaskGold {\n taskId: string\n requirements: CompletionRequirement[]\n}\n\nexport interface ProducedProposal {\n id: string\n title: string\n status: 'pending' | 'approved' | 'rejected'\n /** Optional persisted body — when present, enables a correctness check. */\n content?: string\n}\n\n/** Everything observable about what a run actually produced. */\nexport interface ProducedState {\n /** Persisted vault artifacts. Reuses the shared `Artifact` shape. */\n artifacts: Artifact[]\n /** Proposals / filings the agent created. */\n proposals: ProducedProposal[]\n /** Names of tools the agent invoked. */\n toolCalls: string[]\n}\n\nexport interface RequirementCheck {\n reqId: string\n title: string\n /** A produced item of the right kind matched the requirement, non-empty. */\n structurallyPresent: boolean\n /**\n * Whether the matched item actually fulfils the requirement. `null` when\n * not structurally present, or when the matched item carries no content\n * to assess.\n */\n correct: boolean | null\n /** structurallyPresent && correct !== false. */\n satisfied: boolean\n /** Human-readable evidence for the verdict. */\n evidence: string[]\n}\n\nexport interface CompletionVerdict {\n taskId: string\n requirements: RequirementCheck[]\n /** satisfied / total requirements. */\n completionRate: number\n /** Every requirement satisfied. */\n fullyComplete: boolean\n}\n\n/**\n * Decides whether a produced item's content actually fulfils a requirement.\n * Injected so the structural verifier stays pure and unit-testable; the\n * production implementation is `createLlmCorrectnessChecker`.\n */\nexport type CorrectnessChecker = (\n requirement: CompletionRequirement,\n content: string,\n) => Promise<{ correct: boolean; reason: string }>\n\nconst STOPWORDS = new Set([\n 'the',\n 'a',\n 'an',\n 'of',\n 'for',\n 'and',\n 'or',\n 'to',\n 'in',\n 'on',\n 'with',\n 'by',\n])\n\nconst MATCH_THRESHOLD = 0.5\nconst MIN_CONTENT_CHARS = 50\n\nfunction tokens(s: string): Set<string> {\n return new Set(\n s\n .toLowerCase()\n .split(/[^a-z0-9]+/)\n .filter((t) => t.length > 1 && !STOPWORDS.has(t)),\n )\n}\n\n/**\n * Recall of the requirement's tokens within a candidate's identifying text.\n * Recall, not Jaccard — a candidate's path/id legitimately carries extra\n * tokens the requirement does not name.\n */\nfunction tokenRecall(requirementText: string, candidateText: string): number {\n const req = tokens(requirementText)\n if (req.size === 0) return 0\n const cand = tokens(candidateText)\n let hit = 0\n for (const t of req) if (cand.has(t)) hit++\n return hit / req.size\n}\n\ninterface Candidate {\n reqIndex: number\n /** Unique key for a produced item — each item satisfies at most one requirement. */\n itemKey: string\n score: number\n evidence: string\n /** Content to correctness-check, or null when the matched item has none. */\n content: string | null\n}\n\nfunction artifactCandidates(\n req: CompletionRequirement,\n reqIndex: number,\n artifacts: Artifact[],\n): Candidate[] {\n const reqText = `${req.title} ${req.category ?? ''}`\n const out: Candidate[] = []\n artifacts.forEach((a, i) => {\n if ((a.content ?? '').trim().length < MIN_CONTENT_CHARS) return\n let score = tokenRecall(reqText, `${a.path ?? ''} ${a.kind}`)\n if (req.category && a.kind && req.category.toLowerCase() === a.kind.toLowerCase()) {\n score = Math.max(score, 1)\n }\n if (score < MATCH_THRESHOLD) return\n out.push({\n reqIndex,\n itemKey: `artifact:${i}`,\n score,\n evidence: `artifact '${a.path ?? a.kind}' matched (token recall ${score.toFixed(2)})`,\n content: a.content ?? null,\n })\n })\n return out\n}\n\nfunction proposalCandidates(\n req: CompletionRequirement,\n reqIndex: number,\n proposals: ProducedProposal[],\n): Candidate[] {\n const reqText = `${req.title} ${req.category ?? ''}`\n const out: Candidate[] = []\n for (const p of proposals) {\n // Pending or rejected work is not a completed deliverable.\n if (p.status !== 'approved') continue\n const score = tokenRecall(reqText, p.title)\n if (score < MATCH_THRESHOLD) continue\n const body = p.content ?? ''\n out.push({\n reqIndex,\n itemKey: `proposal:${p.id}`,\n score,\n evidence: `approved proposal '${p.title}' matched (token recall ${score.toFixed(2)})`,\n content: body.trim().length >= MIN_CONTENT_CHARS ? body : null,\n })\n }\n return out\n}\n\nfunction toolCallCandidates(\n req: CompletionRequirement,\n reqIndex: number,\n toolCalls: string[],\n): Candidate[] {\n const out: Candidate[] = []\n toolCalls.forEach((name, i) => {\n const score = tokenRecall(req.title, name)\n if (score < MATCH_THRESHOLD) return\n out.push({\n reqIndex,\n itemKey: `tool:${i}`,\n score,\n evidence: `tool call '${name}' matched (token recall ${score.toFixed(2)})`,\n content: null,\n })\n })\n return out\n}\n\n/**\n * Verify whether a run completed the task. `checkCorrectness` is injected —\n * `createLlmCorrectnessChecker` for production, a deterministic stub in tests.\n *\n * Throws on a gold spec with no requirements: an eval task that requires\n * nothing is a misconfiguration, not a vacuously-complete task.\n */\nexport async function verifyCompletion(\n gold: TaskGold,\n state: ProducedState,\n checkCorrectness: CorrectnessChecker,\n): Promise<CompletionVerdict> {\n if (gold.requirements.length === 0) {\n throw new Error(\n `verifyCompletion: task '${gold.taskId}' has no requirements — malformed gold spec`,\n )\n }\n\n // Collect every above-threshold (requirement, produced-item) candidate, then\n // assign greedily by descending score: each requirement and each produced\n // item is used at most once. One deliverable fulfils one requirement.\n const candidates: Candidate[] = []\n gold.requirements.forEach((req, i) => {\n const by = req.satisfiedBy ?? 'any'\n if (by === 'artifact' || by === 'any') {\n candidates.push(...artifactCandidates(req, i, state.artifacts))\n }\n if (by === 'proposal' || by === 'any') {\n candidates.push(...proposalCandidates(req, i, state.proposals))\n }\n if (by === 'tool-call' || by === 'any') {\n candidates.push(...toolCallCandidates(req, i, state.toolCalls))\n }\n })\n candidates.sort((a, b) => b.score - a.score)\n\n const assigned = new Map<number, Candidate>()\n const itemTaken = new Set<string>()\n for (const c of candidates) {\n if (assigned.has(c.reqIndex) || itemTaken.has(c.itemKey)) continue\n assigned.set(c.reqIndex, c)\n itemTaken.add(c.itemKey)\n }\n\n const requirements: RequirementCheck[] = []\n for (let i = 0; i < gold.requirements.length; i++) {\n const req = gold.requirements[i]!\n const match = assigned.get(i)\n const evidence: string[] = []\n let correct: boolean | null = null\n\n if (match) {\n evidence.push(match.evidence)\n if (match.content !== null) {\n const r = await checkCorrectness(req, match.content)\n correct = r.correct\n evidence.push(`correctness: ${r.correct ? 'pass' : 'fail'} — ${r.reason}`)\n } else {\n evidence.push('correctness: not assessed — matched item carries no content')\n }\n } else {\n const by = req.satisfiedBy ?? 'any'\n const kind = by === 'any' ? 'artifact/proposal/tool-call' : by\n evidence.push(`no produced ${kind} matched this requirement`)\n }\n\n const structurallyPresent = match !== undefined\n const satisfied = structurallyPresent && correct !== false\n requirements.push({\n reqId: req.reqId,\n title: req.title,\n structurallyPresent,\n correct,\n satisfied,\n evidence,\n })\n }\n\n const satisfiedCount = requirements.filter((r) => r.satisfied).length\n return {\n taskId: gold.taskId,\n requirements,\n completionRate: satisfiedCount / requirements.length,\n fullyComplete: satisfiedCount === requirements.length,\n }\n}\n\nexport interface LlmCorrectnessCheckerOpts {\n model?: string\n /** Max chars of artifact content sent to the checker. */\n maxContentChars?: number\n}\n\n/** Parse the correctness checker's model response. Fails loud on a bad shape. */\nexport function parseCorrectnessResponse(raw: string): { correct: boolean; reason: string } {\n const match = raw.match(/\\{[\\s\\S]*\\}/)\n if (!match) {\n throw new Error(`correctness checker: no JSON object in model response: ${raw.slice(0, 200)}`)\n }\n const parsed = JSON.parse(match[0]) as { correct?: unknown; reason?: unknown }\n if (typeof parsed.correct !== 'boolean') {\n throw new Error(`correctness checker: 'correct' is not a boolean in: ${match[0].slice(0, 200)}`)\n }\n return { correct: parsed.correct, reason: typeof parsed.reason === 'string' ? parsed.reason : '' }\n}\n\n/**\n * Production `CorrectnessChecker` — one LLM call per matched artifact,\n * deterministic (temperature 0), structured JSON out. Judges fulfilment\n * only: a plan, a gesture, or a description of what should be done does not\n * fulfil a requirement — the artifact must BE the deliverable.\n */\nexport function createLlmCorrectnessChecker(\n tc: TCloud,\n opts: LlmCorrectnessCheckerOpts = {},\n): CorrectnessChecker {\n const model = opts.model ?? 'claude-sonnet-4-6'\n const maxContentChars = opts.maxContentChars ?? 8000\n return async (requirement, content) => {\n const resp = await tc.chat({\n model,\n messages: [\n {\n role: 'system',\n content:\n 'You verify whether a produced work artifact actually fulfils a stated requirement. Judge fulfilment only — is the deliverable substantively present and on-point — not polish. A plan to do it later, a vague gesture, or a description of what should be done does NOT fulfil a requirement; the artifact must BE the deliverable. Respond with a single JSON object: {\"correct\": boolean, \"reason\": string (<= 30 words)}.',\n },\n {\n role: 'user',\n content: `Requirement: ${requirement.title}\\n${\n requirement.category ? `Category: ${requirement.category}\\n` : ''\n }\\nProduced artifact:\\n${content.slice(0, maxContentChars)}`,\n },\n ],\n temperature: 0,\n maxTokens: 200,\n })\n const raw =\n (resp as { choices?: { message?: { content?: string } }[] }).choices?.[0]?.message?.content ??\n ''\n return parseCorrectnessResponse(raw)\n }\n}\n","/**\n * Dual-agent convergence bench.\n *\n * Pattern lifted from dual-worker review loops: two agents take turns until\n * they converge on a consensus artifact. One proposes, the other critiques;\n * the proposer revises; repeat until a score threshold is hit or max rounds.\n *\n * Generalized so any two \"agents\" (gateways, local functions, anything with\n * `propose` + `critique`) compose in. Returns convergence rounds per\n * scenario + whether convergence happened.\n */\n\nexport interface DualAgentScenario {\n id: string\n initialPrompt: string\n /** Optional context the agents can read (e.g. source documents). */\n context?: Record<string, unknown>\n}\n\nexport interface DualAgentRound {\n roundIndex: number\n proposal: string\n critique: string\n convergenceScore: number // 0..1 — how close to convergence\n}\n\nexport interface DualAgentScenarioResult {\n scenarioId: string\n converged: boolean\n roundsToConverge: number | null\n finalProposal: string\n history: DualAgentRound[]\n finalScore: number\n}\n\nexport interface DualAgentBenchConfig {\n scenarios: DualAgentScenario[]\n maxRounds?: number\n /** Convergence threshold in 0..1 (default 0.85). */\n convergenceThreshold?: number\n /**\n * Propose an answer given the scenario + the critic's prior critique (if any).\n * Returns the proposal string.\n */\n propose: (args: {\n scenario: DualAgentScenario\n roundIndex: number\n priorProposal?: string\n priorCritique?: string\n }) => Promise<string>\n /**\n * Critique the proposer's current output. Returns a structured critique\n * (free text) plus a convergence score: how close the proposal is to\n * acceptable. 1.0 = accept, 0.0 = totally off.\n */\n critique: (args: {\n scenario: DualAgentScenario\n roundIndex: number\n proposal: string\n }) => Promise<{ critique: string; convergenceScore: number }>\n /** Optional per-round hook for progress + tracing. */\n onRoundComplete?: (info: { scenarioId: string; round: DualAgentRound }) => void\n}\n\nexport interface DualAgentReport {\n scenarios: DualAgentScenarioResult[]\n aggregate: {\n convergenceRate: number // fraction of scenarios that converged within maxRounds\n avgRoundsToConverge: number | null // over scenarios that DID converge\n avgFinalScore: number\n }\n config: {\n maxRounds: number\n convergenceThreshold: number\n }\n}\n\nexport class DualAgentBench {\n async run(config: DualAgentBenchConfig): Promise<DualAgentReport> {\n const maxRounds = config.maxRounds ?? 5\n const threshold = config.convergenceThreshold ?? 0.85\n\n if (config.scenarios.length === 0) {\n throw new Error('DualAgentBench requires at least 1 scenario')\n }\n\n const results: DualAgentScenarioResult[] = []\n\n for (const scenario of config.scenarios) {\n const history: DualAgentRound[] = []\n let converged = false\n let roundsToConverge: number | null = null\n let finalProposal = ''\n let lastScore = 0\n let priorCritique: string | undefined\n\n for (let r = 0; r < maxRounds; r++) {\n const priorProposal = history[history.length - 1]?.proposal\n const proposal = await config.propose({\n scenario,\n roundIndex: r,\n priorProposal,\n priorCritique,\n })\n const { critique, convergenceScore } = await config.critique({\n scenario,\n roundIndex: r,\n proposal,\n })\n\n if (!Number.isFinite(convergenceScore) || convergenceScore < 0 || convergenceScore > 1) {\n throw new Error(\n `critique must return convergenceScore in [0,1]; got ${convergenceScore} for scenario ${scenario.id} round ${r}`,\n )\n }\n\n const round: DualAgentRound = {\n roundIndex: r,\n proposal,\n critique,\n convergenceScore,\n }\n history.push(round)\n config.onRoundComplete?.({ scenarioId: scenario.id, round })\n\n finalProposal = proposal\n lastScore = convergenceScore\n priorCritique = critique\n\n if (convergenceScore >= threshold) {\n converged = true\n roundsToConverge = r + 1\n break\n }\n }\n\n results.push({\n scenarioId: scenario.id,\n converged,\n roundsToConverge,\n finalProposal,\n history,\n finalScore: lastScore,\n })\n }\n\n const convergedResults = results.filter((r) => r.converged)\n const convergenceRate = results.length ? convergedResults.length / results.length : 0\n const avgRoundsToConverge = convergedResults.length\n ? convergedResults.reduce((acc, r) => acc + (r.roundsToConverge ?? 0), 0) /\n convergedResults.length\n : null\n const avgFinalScore = results.length\n ? results.reduce((acc, r) => acc + r.finalScore, 0) / results.length\n : 0\n\n return {\n scenarios: results,\n aggregate: { convergenceRate, avgRoundsToConverge, avgFinalScore },\n config: { maxRounds, convergenceThreshold: threshold },\n }\n }\n}\n","/**\n * Experiment tracker — group runs, diff them, watch scores move over time.\n *\n * Not MLflow. Not Weights & Biases. Just the 20% that actually ships:\n * - A run has a config (prompt hash, model, scenario ids, seed)\n * - Runs belong to experiments (named groups)\n * - The store is pluggable (in-memory for tests, filesystem for local,\n * custom for Langfuse/D1)\n * - Diffs show score deltas, new/dropped scenarios, and config changes\n *\n * The output plugs directly into `BenchmarkReport` — runs archive the full\n * report, diff operates on the summary.\n */\n\nimport type { BenchmarkReport } from './types'\n\nexport interface RunConfig {\n experimentId: string\n name?: string\n model?: string\n promptHash?: string\n promptVersion?: string\n seed?: number\n metadata?: Record<string, unknown>\n}\n\nexport interface Run {\n id: string\n experimentId: string\n name?: string\n config: RunConfig\n startedAt: string\n completedAt?: string\n status: 'running' | 'completed' | 'failed'\n report?: BenchmarkReport\n error?: string\n}\n\nexport interface Experiment {\n id: string\n name: string\n createdAt: string\n metadata?: Record<string, unknown>\n}\n\nexport interface ExperimentStore {\n saveExperiment(exp: Experiment): Promise<void>\n getExperiment(id: string): Promise<Experiment | null>\n listExperiments(): Promise<Experiment[]>\n saveRun(run: Run): Promise<void>\n getRun(id: string): Promise<Run | null>\n listRuns(experimentId: string): Promise<Run[]>\n}\n\nexport class InMemoryExperimentStore implements ExperimentStore {\n private readonly experiments = new Map<string, Experiment>()\n private readonly runs = new Map<string, Run>()\n\n async saveExperiment(exp: Experiment): Promise<void> {\n this.experiments.set(exp.id, { ...exp })\n }\n async getExperiment(id: string): Promise<Experiment | null> {\n const e = this.experiments.get(id)\n return e ? { ...e } : null\n }\n async listExperiments(): Promise<Experiment[]> {\n return [...this.experiments.values()].sort((a, b) => b.createdAt.localeCompare(a.createdAt))\n }\n async saveRun(run: Run): Promise<void> {\n this.runs.set(run.id, structuredClone(run))\n }\n async getRun(id: string): Promise<Run | null> {\n const r = this.runs.get(id)\n return r ? structuredClone(r) : null\n }\n async listRuns(experimentId: string): Promise<Run[]> {\n return [...this.runs.values()]\n .filter((r) => r.experimentId === experimentId)\n .sort((a, b) => b.startedAt.localeCompare(a.startedAt))\n .map((r) => structuredClone(r))\n }\n}\n\n// ---------------------------------------------------------------------------\n// The tracker itself\n// ---------------------------------------------------------------------------\n\nexport class ExperimentTracker {\n constructor(private readonly store: ExperimentStore) {}\n\n async startExperiment(name: string, metadata?: Record<string, unknown>): Promise<Experiment> {\n const exp: Experiment = {\n id: `exp_${rand(8)}`,\n name,\n createdAt: new Date().toISOString(),\n metadata,\n }\n await this.store.saveExperiment(exp)\n return exp\n }\n\n async startRun(config: RunConfig): Promise<Run> {\n const exp = await this.store.getExperiment(config.experimentId)\n if (!exp) throw new Error(`Experiment ${config.experimentId} not found`)\n\n const run: Run = {\n id: `run_${rand(10)}`,\n experimentId: config.experimentId,\n name: config.name,\n config,\n startedAt: new Date().toISOString(),\n status: 'running',\n }\n await this.store.saveRun(run)\n return run\n }\n\n async completeRun(runId: string, report: BenchmarkReport): Promise<void> {\n const run = await this.store.getRun(runId)\n if (!run) throw new Error(`Run ${runId} not found`)\n run.status = 'completed'\n run.completedAt = new Date().toISOString()\n run.report = report\n await this.store.saveRun(run)\n }\n\n async failRun(runId: string, error: string): Promise<void> {\n const run = await this.store.getRun(runId)\n if (!run) throw new Error(`Run ${runId} not found`)\n run.status = 'failed'\n run.completedAt = new Date().toISOString()\n run.error = error\n await this.store.saveRun(run)\n }\n\n /**\n * Diff two completed runs. Returns per-scenario deltas, aggregate delta,\n * and config changes that may explain the movement.\n */\n async diff(runIdA: string, runIdB: string): Promise<RunDiff> {\n const [a, b] = await Promise.all([this.store.getRun(runIdA), this.store.getRun(runIdB)])\n if (!a || !b) throw new Error('Both runs must exist')\n if (!a.report || !b.report) throw new Error('Both runs must be completed with reports')\n\n const byScenarioA = new Map(a.report.results.map((r) => [r.scenarioId, r.overallScore]))\n const byScenarioB = new Map(b.report.results.map((r) => [r.scenarioId, r.overallScore]))\n\n const scenarioIds = new Set([...byScenarioA.keys(), ...byScenarioB.keys()])\n const scenarios: RunDiff['scenarios'] = []\n for (const id of scenarioIds) {\n const aScore = byScenarioA.get(id)\n const bScore = byScenarioB.get(id)\n if (aScore === undefined) {\n scenarios.push({\n scenarioId: id,\n before: null,\n after: bScore!,\n delta: null,\n status: 'added',\n })\n } else if (bScore === undefined) {\n scenarios.push({\n scenarioId: id,\n before: aScore,\n after: null,\n delta: null,\n status: 'removed',\n })\n } else {\n scenarios.push({\n scenarioId: id,\n before: aScore,\n after: bScore,\n delta: bScore - aScore,\n status: bScore > aScore ? 'improved' : bScore < aScore ? 'regressed' : 'unchanged',\n })\n }\n }\n scenarios.sort((x, y) => (y.delta ?? 0) - (x.delta ?? 0))\n\n const aggregateDelta = b.report.summary.overallAvg - a.report.summary.overallAvg\n const configChanges: Record<string, { before: unknown; after: unknown }> = {}\n const keys = new Set([...Object.keys(a.config), ...Object.keys(b.config)])\n const aCfg = a.config as unknown as Record<string, unknown>\n const bCfg = b.config as unknown as Record<string, unknown>\n for (const k of keys) {\n if (JSON.stringify(aCfg[k]) !== JSON.stringify(bCfg[k])) {\n configChanges[k] = { before: aCfg[k], after: bCfg[k] }\n }\n }\n\n return {\n before: { runId: runIdA, name: a.name, startedAt: a.startedAt },\n after: { runId: runIdB, name: b.name, startedAt: b.startedAt },\n aggregateDelta,\n scenarios,\n configChanges,\n }\n }\n\n /** Timeline of aggregate scores for an experiment. */\n async timeline(\n experimentId: string,\n ): Promise<Array<{ runId: string; startedAt: string; overall: number | null }>> {\n const runs = await this.store.listRuns(experimentId)\n return runs\n .slice()\n .sort((a, b) => a.startedAt.localeCompare(b.startedAt))\n .map((r) => ({\n runId: r.id,\n startedAt: r.startedAt,\n overall: r.report?.summary.overallAvg ?? null,\n }))\n }\n}\n\nexport interface RunDiff {\n before: { runId: string; name?: string; startedAt: string }\n after: { runId: string; name?: string; startedAt: string }\n aggregateDelta: number\n scenarios: Array<{\n scenarioId: string\n before: number | null\n after: number | null\n delta: number | null\n status: 'improved' | 'regressed' | 'unchanged' | 'added' | 'removed'\n }>\n configChanges: Record<string, { before: unknown; after: unknown }>\n}\n\nfunction rand(bytes: number): string {\n const arr = new Uint8Array(bytes)\n crypto.getRandomValues(arr)\n return Array.from(arr)\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('')\n}\n","/**\n * D1ExperimentStore — Cloudflare D1-backed `ExperimentStore`.\n *\n * Workers-safe (uses only the `D1Database` binding the runtime injects). Two\n * tables, no joins, no migrations beyond `ensureSchema()`. Schema designed so\n * a Worker route can both write the row at run start and update it at run end\n * without losing the original config — the row's lifecycle mirrors the\n * `Run.status` field one-to-one.\n *\n * Why this lives next to `InMemoryExperimentStore`:\n * - browser, coding, and computer-use agents can all run as Workers\n * - Workers cannot use `node:fs`, so `FileSystemExperimentStore` doesn't apply\n * - Hand-rolling D1 SQL in every consumer is exactly the duplication this\n * module exists to prevent\n *\n * Schema versioning: the `meta` table records `schema_version` so a future\n * column addition can be detected and migrated additively. Today's schema is\n * v1; bump only on breaking shape changes.\n */\n\nimport type { Experiment, ExperimentStore, Run } from './experiment-tracker'\n\n/**\n * Minimal `D1Database` shape we depend on. Avoids pulling in\n * `@cloudflare/workers-types` as a hard dep — consumers that already have\n * those types installed can pass the binding directly.\n */\nexport interface D1Like {\n prepare(query: string): D1PreparedStatementLike\n batch?(statements: D1PreparedStatementLike[]): Promise<unknown[]>\n exec(query: string): Promise<unknown>\n}\n\nexport interface D1PreparedStatementLike {\n bind(...values: unknown[]): D1PreparedStatementLike\n first<T = Record<string, unknown>>(): Promise<T | null>\n all<T = Record<string, unknown>>(): Promise<{ results: T[] }>\n run(): Promise<unknown>\n}\n\nexport interface D1ExperimentStoreOptions {\n /** D1 binding from `env`. */\n db: D1Like\n /**\n * Optional table-name prefix so multiple ExperimentStores can share a DB\n * without colliding (e.g. `browser_eval_experiments` vs `coding_eval_experiments`).\n * Default: `agent_eval_`.\n */\n tablePrefix?: string\n}\n\nconst SCHEMA_VERSION = 1\n\nexport class D1ExperimentStore implements ExperimentStore {\n private readonly db: D1Like\n private readonly experimentsTable: string\n private readonly runsTable: string\n private readonly metaTable: string\n private schemaReady = false\n\n constructor(options: D1ExperimentStoreOptions) {\n this.db = options.db\n const prefix = options.tablePrefix ?? 'agent_eval_'\n this.experimentsTable = `${prefix}experiments`\n this.runsTable = `${prefix}runs`\n this.metaTable = `${prefix}meta`\n }\n\n /**\n * Idempotent schema setup. Safe to call before every operation; the second\n * call short-circuits via `schemaReady`. Most consumers will call it once\n * during Worker bootstrap.\n */\n async ensureSchema(): Promise<void> {\n if (this.schemaReady) return\n // Single `exec` so D1 batches the DDL.\n const ddl = `\n CREATE TABLE IF NOT EXISTS ${this.experimentsTable} (\n id TEXT PRIMARY KEY,\n name TEXT NOT NULL,\n created_at TEXT NOT NULL,\n metadata_json TEXT\n );\n CREATE TABLE IF NOT EXISTS ${this.runsTable} (\n id TEXT PRIMARY KEY,\n experiment_id TEXT NOT NULL,\n name TEXT,\n status TEXT NOT NULL,\n started_at TEXT NOT NULL,\n completed_at TEXT,\n config_json TEXT NOT NULL,\n report_json TEXT,\n error TEXT\n );\n CREATE INDEX IF NOT EXISTS idx_${this.runsTable}_experiment ON ${this.runsTable}(experiment_id);\n CREATE INDEX IF NOT EXISTS idx_${this.runsTable}_started ON ${this.runsTable}(started_at);\n CREATE TABLE IF NOT EXISTS ${this.metaTable} (\n key TEXT PRIMARY KEY,\n value TEXT NOT NULL\n );\n INSERT OR REPLACE INTO ${this.metaTable}(key, value) VALUES ('schema_version', '${SCHEMA_VERSION}');\n `\n await this.db.exec(ddl.trim().replace(/\\s+/g, ' '))\n this.schemaReady = true\n }\n\n async saveExperiment(exp: Experiment): Promise<void> {\n await this.ensureSchema()\n await this.db\n .prepare(\n `INSERT INTO ${this.experimentsTable}(id, name, created_at, metadata_json)\n VALUES (?1, ?2, ?3, ?4)\n ON CONFLICT(id) DO UPDATE SET\n name = excluded.name,\n created_at = excluded.created_at,\n metadata_json = excluded.metadata_json`,\n )\n .bind(exp.id, exp.name, exp.createdAt, exp.metadata ? JSON.stringify(exp.metadata) : null)\n .run()\n }\n\n async getExperiment(id: string): Promise<Experiment | null> {\n await this.ensureSchema()\n const row = await this.db\n .prepare(\n `SELECT id, name, created_at, metadata_json\n FROM ${this.experimentsTable}\n WHERE id = ?1`,\n )\n .bind(id)\n .first<ExperimentRow>()\n return row ? rowToExperiment(row) : null\n }\n\n async listExperiments(): Promise<Experiment[]> {\n await this.ensureSchema()\n const { results } = await this.db\n .prepare(\n `SELECT id, name, created_at, metadata_json\n FROM ${this.experimentsTable}\n ORDER BY created_at DESC`,\n )\n .all<ExperimentRow>()\n return results.map(rowToExperiment)\n }\n\n async saveRun(run: Run): Promise<void> {\n await this.ensureSchema()\n await this.db\n .prepare(\n `INSERT INTO ${this.runsTable}(id, experiment_id, name, status, started_at, completed_at, config_json, report_json, error)\n VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9)\n ON CONFLICT(id) DO UPDATE SET\n experiment_id = excluded.experiment_id,\n name = excluded.name,\n status = excluded.status,\n started_at = excluded.started_at,\n completed_at = excluded.completed_at,\n config_json = excluded.config_json,\n report_json = excluded.report_json,\n error = excluded.error`,\n )\n .bind(\n run.id,\n run.experimentId,\n run.name ?? null,\n run.status,\n run.startedAt,\n run.completedAt ?? null,\n JSON.stringify(run.config),\n run.report ? JSON.stringify(run.report) : null,\n run.error ?? null,\n )\n .run()\n }\n\n async getRun(id: string): Promise<Run | null> {\n await this.ensureSchema()\n const row = await this.db\n .prepare(\n `SELECT id, experiment_id, name, status, started_at, completed_at, config_json, report_json, error\n FROM ${this.runsTable}\n WHERE id = ?1`,\n )\n .bind(id)\n .first<RunRow>()\n return row ? rowToRun(row) : null\n }\n\n async listRuns(experimentId: string): Promise<Run[]> {\n await this.ensureSchema()\n const { results } = await this.db\n .prepare(\n `SELECT id, experiment_id, name, status, started_at, completed_at, config_json, report_json, error\n FROM ${this.runsTable}\n WHERE experiment_id = ?1\n ORDER BY started_at DESC`,\n )\n .bind(experimentId)\n .all<RunRow>()\n return results.map(rowToRun)\n }\n}\n\ninterface ExperimentRow {\n id: string\n name: string\n created_at: string\n metadata_json: string | null\n}\n\ninterface RunRow {\n id: string\n experiment_id: string\n name: string | null\n status: string\n started_at: string\n completed_at: string | null\n config_json: string\n report_json: string | null\n error: string | null\n}\n\nfunction rowToExperiment(row: ExperimentRow): Experiment {\n return {\n id: row.id,\n name: row.name,\n createdAt: row.created_at,\n ...(row.metadata_json\n ? { metadata: JSON.parse(row.metadata_json) as Record<string, unknown> }\n : {}),\n }\n}\n\nfunction rowToRun(row: RunRow): Run {\n return {\n id: row.id,\n experimentId: row.experiment_id,\n ...(row.name ? { name: row.name } : {}),\n status: row.status as Run['status'],\n startedAt: row.started_at,\n ...(row.completed_at ? { completedAt: row.completed_at } : {}),\n config: JSON.parse(row.config_json),\n ...(row.report_json ? { report: JSON.parse(row.report_json) } : {}),\n ...(row.error ? { error: row.error } : {}),\n }\n}\n","/**\n * FileSystemExperimentStore — NDJSON-backed `ExperimentStore` for local + CI.\n *\n * Mirrors the file layout of `FileSystemTraceStore`: two append-only NDJSON\n * files (`experiments.ndjson` + `runs.ndjson`) under one directory, with size-\n * based rollover. Writes are append-only so the file log doubles as an audit\n * trail of every state transition the tracker ever wrote.\n *\n * Reads lazy-load every NDJSON file in the directory (including rolled-over\n * archives), latest-write-wins per `id`. Subsequent writes update the\n * in-memory index in place so reads after writes are O(1).\n *\n * Node-only — imports `node:fs/promises`. Don't import this from a Worker;\n * use the in-memory store or the D1 store from `./experiment-tracker-d1`.\n */\n\nimport {\n type Experiment,\n type ExperimentStore,\n InMemoryExperimentStore,\n type Run,\n} from './experiment-tracker'\n\nexport interface FileSystemExperimentStoreOptions {\n /** Directory the NDJSON files live in. Created on first write. */\n dir: string\n /** Bytes after which a file is rolled over. Default 32 MB (matches FileSystemTraceStore). */\n maxBytes?: number\n}\n\nexport class FileSystemExperimentStore implements ExperimentStore {\n private readonly dir: string\n private readonly maxBytes: number\n private index?: InMemoryExperimentStore\n private loaded = false\n\n constructor(options: FileSystemExperimentStoreOptions) {\n this.dir = options.dir\n this.maxBytes = options.maxBytes ?? 32 * 1024 * 1024\n }\n\n async saveExperiment(exp: Experiment): Promise<void> {\n const idx = await this.load()\n await idx.saveExperiment(exp)\n await this.append('experiments', exp)\n }\n\n async getExperiment(id: string): Promise<Experiment | null> {\n const idx = await this.load()\n return idx.getExperiment(id)\n }\n\n async listExperiments(): Promise<Experiment[]> {\n const idx = await this.load()\n return idx.listExperiments()\n }\n\n async saveRun(run: Run): Promise<void> {\n const idx = await this.load()\n await idx.saveRun(run)\n await this.append('runs', run)\n }\n\n async getRun(id: string): Promise<Run | null> {\n const idx = await this.load()\n return idx.getRun(id)\n }\n\n async listRuns(experimentId: string): Promise<Run[]> {\n const idx = await this.load()\n return idx.listRuns(experimentId)\n }\n\n private async ensureDir(): Promise<void> {\n const fs = await import('node:fs/promises')\n await fs.mkdir(this.dir, { recursive: true })\n }\n\n private async append(name: 'experiments' | 'runs', record: unknown): Promise<void> {\n await this.ensureDir()\n const fs = await import('node:fs/promises')\n const path = await import('node:path')\n const active = path.join(this.dir, `${name}.ndjson`)\n try {\n const stat = await fs.stat(active)\n if (stat.size >= this.maxBytes) {\n const rolled = path.join(this.dir, `${name}.${Date.now()}.ndjson`)\n await fs.rename(active, rolled)\n }\n } catch {\n /* file doesn't exist yet */\n }\n await fs.appendFile(active, `${JSON.stringify(record)}\\n`, 'utf8')\n }\n\n private async load(): Promise<InMemoryExperimentStore> {\n if (this.loaded && this.index) return this.index\n const fs = await import('node:fs/promises')\n const path = await import('node:path')\n const store = new InMemoryExperimentStore()\n try {\n const entries = await fs.readdir(this.dir)\n // Sort so older rollover files load first; the active *.ndjson wins on\n // duplicate ids because saves replay in insertion order and the in-memory\n // store is last-write-wins.\n const sorted = entries.filter((f) => f.endsWith('.ndjson')).sort((a, b) => a.localeCompare(b))\n for (const file of sorted) {\n const full = path.join(this.dir, file)\n const content = await fs.readFile(full, 'utf8')\n const base = file.split('.')[0]\n for (const line of content.split('\\n')) {\n if (!line.trim()) continue\n let record: unknown\n try {\n record = JSON.parse(line)\n } catch {\n // Truncated tail line during a crash; skip.\n continue\n }\n if (base === 'experiments') {\n await store.saveExperiment(record as Experiment)\n } else if (base === 'runs') {\n await store.saveRun(record as Run)\n }\n }\n }\n } catch {\n /* empty dir, first run */\n }\n this.index = store\n this.loaded = true\n return store\n }\n}\n","import { type Objective, type ParetoResult, paretoFrontier } from './pareto'\nimport { RunCritic, type RunTrace } from './run-critic'\nimport { aggregateRunScore, type RunScore, type RunScoreWeights } from './run-score'\nimport type { SteeringBundle } from './steering'\n\nexport type HarnessIntervention =\n | 'continue'\n | 'plan'\n | 'audit'\n | 'recover'\n | 'repair'\n | 'verify'\n | 'final_gate'\n | 'wait_for_measurement'\n | 'abort'\n\nexport interface WorkflowTopology {\n id: string\n interventions: HarnessIntervention[]\n maxParallelBranches?: number\n metadata?: Record<string, unknown>\n}\n\nexport interface MeasurementPolicy {\n required: string[]\n optional?: string[]\n promoteOn?: Array<keyof RunScore | 'aggregate'>\n}\n\nexport interface HarnessVariant {\n id: string\n steering?: SteeringBundle\n topology?: WorkflowTopology\n measurement?: MeasurementPolicy\n budgets?: Record<string, number>\n models?: Record<string, string>\n reviewers?: Record<string, string>\n metadata?: Record<string, unknown>\n}\n\nexport interface HarnessScenario {\n id: string\n task: string\n split?: 'train' | 'validation' | 'test' | string\n metadata?: Record<string, unknown>\n}\n\nexport interface HarnessRunRequest {\n variant: HarnessVariant\n scenario: HarnessScenario\n trialIndex: number\n}\n\nexport interface HarnessAdapter {\n run(request: HarnessRunRequest): Promise<RunTrace>\n}\n\nexport interface HarnessRunResult {\n variant: HarnessVariant\n scenario: HarnessScenario\n trialIndex: number\n trace: RunTrace\n score: RunScore\n aggregate: number\n}\n\nexport interface HarnessVariantReport {\n variant: HarnessVariant\n runs: HarnessRunResult[]\n aggregateMean: number\n passRate: number\n costUsdMean: number\n wallSecondsMean: number\n scoreMean: RunScore\n}\n\nexport interface HarnessSelection {\n winner: HarnessVariantReport\n frontier: ParetoResult<HarnessVariantReport>\n reports: HarnessVariantReport[]\n}\n\nexport interface HarnessExperimentResult {\n results: HarnessRunResult[]\n selection: HarnessSelection\n}\n\nexport interface HarnessExperimentConfig {\n adapter: HarnessAdapter\n variants: HarnessVariant[]\n scenarios: HarnessScenario[]\n trialsPerScenario?: number\n parallelism?: number\n weights?: Partial<RunScoreWeights>\n objectives?: Array<Objective<HarnessVariantReport>>\n score?: (trace: RunTrace, request: HarnessRunRequest) => RunScore | Promise<RunScore>\n onResult?: (result: HarnessRunResult) => void | Promise<void>\n}\n\nexport const DEFAULT_HARNESS_OBJECTIVES: Array<Objective<HarnessVariantReport>> = [\n { name: 'aggregate', direction: 'maximize', value: (r) => r.aggregateMean },\n { name: 'pass_rate', direction: 'maximize', value: (r) => r.passRate },\n { name: 'cost', direction: 'minimize', value: (r) => r.costUsdMean },\n { name: 'wall', direction: 'minimize', value: (r) => r.wallSecondsMean },\n]\n\nexport async function runHarnessExperiment(\n config: HarnessExperimentConfig,\n): Promise<HarnessExperimentResult> {\n const jobs = buildJobs(config)\n const critic = new RunCritic({ weights: config.weights })\n const score = config.score ?? ((trace: RunTrace) => critic.scoreTrace(trace))\n const results = await mapLimit(jobs, config.parallelism ?? 1, async (request) => {\n const trace = await config.adapter.run(request)\n const runScore = await score(trace, request)\n const result: HarnessRunResult = {\n variant: request.variant,\n scenario: request.scenario,\n trialIndex: request.trialIndex,\n trace,\n score: runScore,\n aggregate: aggregateRunScore(runScore, config.weights),\n }\n await config.onResult?.(result)\n return result\n })\n return { results, selection: selectHarnessVariant(results, config.objectives) }\n}\n\nexport function selectHarnessVariant(\n results: HarnessRunResult[],\n objectives: Array<Objective<HarnessVariantReport>> = DEFAULT_HARNESS_OBJECTIVES,\n): HarnessSelection {\n const reports = summarizeHarnessResults(results)\n if (reports.length === 0) throw new Error('selectHarnessVariant: no results')\n const frontier = paretoFrontier(reports, objectives)\n const candidates = frontier.frontier.length ? frontier.frontier : reports\n const winner = [...candidates].sort((a, b) => b.aggregateMean - a.aggregateMean)[0]\n if (!winner) throw new Error('selectHarnessVariant: no winner')\n return { winner, frontier, reports }\n}\n\nexport function summarizeHarnessResults(results: HarnessRunResult[]): HarnessVariantReport[] {\n const byVariant = new Map<string, HarnessRunResult[]>()\n for (const result of results) {\n byVariant.set(result.variant.id, [...(byVariant.get(result.variant.id) ?? []), result])\n }\n return [...byVariant.values()]\n .map((runs) => {\n const variant = runs[0]?.variant\n if (!variant) throw new Error('summarizeHarnessResults: empty variant bucket')\n return {\n variant,\n runs,\n aggregateMean: mean(runs.map((r) => r.aggregate)),\n passRate: mean(runs.map((r) => r.score.success)),\n costUsdMean: mean(runs.map((r) => r.score.costUsd)),\n wallSecondsMean: mean(runs.map((r) => r.score.wallSeconds)),\n scoreMean: meanRunScore(runs.map((r) => r.score)),\n }\n })\n .sort((a, b) => b.aggregateMean - a.aggregateMean)\n}\n\nfunction buildJobs(config: HarnessExperimentConfig): HarnessRunRequest[] {\n if (config.variants.length === 0)\n throw new Error('runHarnessExperiment: at least one variant required')\n if (config.scenarios.length === 0)\n throw new Error('runHarnessExperiment: at least one scenario required')\n const trials = Math.max(1, Math.floor(config.trialsPerScenario ?? 1))\n const jobs: HarnessRunRequest[] = []\n for (const variant of config.variants) {\n for (const scenario of config.scenarios) {\n for (let trialIndex = 0; trialIndex < trials; trialIndex++) {\n jobs.push({ variant, scenario, trialIndex })\n }\n }\n }\n return jobs\n}\n\nasync function mapLimit<T, R>(\n items: T[],\n limit: number,\n fn: (item: T) => Promise<R>,\n): Promise<R[]> {\n const results: R[] = new Array(items.length)\n let next = 0\n const workerCount = Math.max(1, Math.min(Math.floor(limit), items.length))\n await Promise.all(\n Array.from({ length: workerCount }, async () => {\n while (next < items.length) {\n const index = next++\n const item = items[index]\n if (item === undefined) continue\n results[index] = await fn(item)\n }\n }),\n )\n return results\n}\n\nfunction mean(values: number[]): number {\n return values.length ? values.reduce((sum, value) => sum + value, 0) / values.length : 0\n}\n\nfunction meanRunScore(scores: RunScore[]): RunScore {\n return {\n success: mean(scores.map((s) => s.success)),\n goalProgress: mean(scores.map((s) => s.goalProgress)),\n repoGroundedness: mean(scores.map((s) => s.repoGroundedness)),\n driftPenalty: mean(scores.map((s) => s.driftPenalty)),\n toolUseQuality: mean(scores.map((s) => s.toolUseQuality)),\n patchQuality: mean(scores.map((s) => s.patchQuality)),\n testReality: mean(scores.map((s) => s.testReality)),\n finalGate: mean(scores.map((s) => s.finalGate)),\n reviewerBlockers: mean(scores.map((s) => s.reviewerBlockers)),\n costUsd: mean(scores.map((s) => s.costUsd)),\n wallSeconds: mean(scores.map((s) => s.wallSeconds)),\n notes: scores.flatMap((s) => s.notes ?? []),\n }\n}\n","import {\n type HarnessConfig,\n type SandboxDriver,\n SandboxHarness,\n type SandboxHarnessResult,\n SubprocessSandboxDriver,\n} from './sandbox-harness'\nimport { TraceEmitter } from './trace/emitter'\nimport { InMemoryTraceStore } from './trace/store'\n\nexport type SandboxJudgeKind = 'compiler' | 'test' | 'linter' | 'security'\n\nexport interface SandboxJudgeSpec {\n id: string\n kind: SandboxJudgeKind\n config: HarnessConfig\n}\n\nexport interface SandboxJudgeResult {\n id: string\n kind: SandboxJudgeKind\n passed: boolean\n score: number\n summary: string\n detail: SandboxHarnessResult\n}\n\nexport interface JudgeFleetOptions {\n driver?: SandboxDriver\n parallel?: boolean\n}\n\nexport class JudgeRunner {\n private readonly driver: SandboxDriver\n\n constructor(driver: SandboxDriver = new SubprocessSandboxDriver()) {\n this.driver = driver\n }\n\n async run(spec: SandboxJudgeSpec): Promise<SandboxJudgeResult> {\n const store = new InMemoryTraceStore()\n const emitter = new TraceEmitter(store, { runId: `judge-${spec.id}` })\n await emitter.startRun({\n scenarioId: spec.id,\n layer: 'meta',\n projectId: 'judge-runner',\n })\n const harness = new SandboxHarness(this.driver)\n const detail = await harness.run(spec.config, emitter)\n await emitter.endRun({ pass: detail.passed, score: detail.score, notes: `${spec.kind} judge` })\n return {\n id: spec.id,\n kind: spec.kind,\n passed: detail.passed,\n score: detail.score,\n summary: renderJudgeSummary(spec.kind, detail),\n detail,\n }\n }\n}\n\nexport async function runJudgeFleet(\n specs: SandboxJudgeSpec[],\n options: JudgeFleetOptions = {},\n): Promise<SandboxJudgeResult[]> {\n const runner = new JudgeRunner(options.driver)\n if (options.parallel === false) {\n const results: SandboxJudgeResult[] = []\n for (const spec of specs) results.push(await runner.run(spec))\n return results\n }\n return await Promise.all(specs.map((spec) => runner.run(spec)))\n}\n\nexport function compilerJudge(id: string, config: HarnessConfig): SandboxJudgeSpec {\n return { id, kind: 'compiler', config }\n}\n\nexport function testJudge(id: string, config: HarnessConfig): SandboxJudgeSpec {\n return { id, kind: 'test', config }\n}\n\nexport function linterJudge(id: string, config: HarnessConfig): SandboxJudgeSpec {\n return { id, kind: 'linter', config }\n}\n\nexport function securityJudge(id: string, config: HarnessConfig): SandboxJudgeSpec {\n return { id, kind: 'security', config }\n}\n\nfunction renderJudgeSummary(kind: SandboxJudgeKind, detail: SandboxHarnessResult): string {\n if (!detail.passed) return `${kind} judge failed`\n if (detail.test?.testsTotal)\n return `${kind} judge passed ${detail.test.testsPassed}/${detail.test.testsTotal} tests`\n return `${kind} judge passed`\n}\n","export interface PlaybookEntry {\n instruction: string\n rationale: string\n category?: string\n evidence?: string\n weight?: number\n sourceRunId?: string\n}\n\nexport interface Playbook {\n entries: PlaybookEntry[]\n}\n\nexport function distillPlaybook(\n entries: PlaybookEntry[],\n options: { maxEntries?: number } = {},\n): Playbook {\n const maxEntries = options.maxEntries ?? 12\n const byInstruction = new Map<string, PlaybookEntry>()\n\n for (const entry of entries) {\n const key = normalizeInstruction(entry.instruction)\n const existing = byInstruction.get(key)\n if (!existing || (entry.weight ?? 0) > (existing.weight ?? 0)) {\n byInstruction.set(key, { ...entry, instruction: canonicalInstruction(entry.instruction) })\n }\n }\n\n const distilled = [...byInstruction.values()]\n .sort((a, b) => (b.weight ?? 0) - (a.weight ?? 0))\n .slice(0, maxEntries)\n\n return { entries: distilled }\n}\n\nexport function renderPlaybookMarkdown(playbook: Playbook): string {\n const lines = ['# Playbook', '']\n for (const entry of playbook.entries) {\n lines.push(`- ${entry.instruction}`)\n lines.push(` Rationale: ${entry.rationale}`)\n if (entry.category) lines.push(` Category: ${entry.category}`)\n if (entry.evidence) lines.push(` Evidence: ${entry.evidence}`)\n if (entry.sourceRunId) lines.push(` Source run: ${entry.sourceRunId}`)\n lines.push('')\n }\n return `${lines.join('\\n').trim()}\\n`\n}\n\nfunction normalizeInstruction(value: string): string {\n return value.trim().toLowerCase().replace(/\\s+/g, ' ')\n}\n\nfunction canonicalInstruction(value: string): string {\n const normalized = value.trim().replace(/\\s+/g, ' ')\n return normalized.length === 0 ? normalized : normalized[0]!.toUpperCase() + normalized.slice(1)\n}\n","/**\n * Produced-state extraction — normalize a run's runtime event stream into the\n * typed `ProducedState` the completion oracle consumes.\n *\n * `ProducedState` answers \"what did the agent actually produce\" — vault\n * artifacts, proposals, tool calls. The runtime emits these as a stream of\n * events; this module is the single normalization point from that stream to\n * the shape `verifyCompletion` expects.\n *\n * Input is structurally typed (`RuntimeEventLike`) so this module does not\n * depend on agent-runtime — agent-runtime's `RuntimeStreamEvent` satisfies it\n * structurally. The `content` on `ArtifactEventLike` and the whole\n * `proposal_created` variant are the runtime-side enrichments this contract\n * requires; the runtime emits them, this module consumes them.\n */\n\nimport type { Artifact } from './artifact-validator'\nimport type { ProducedProposal, ProducedState } from './completion-verifier'\n\n/** A tool the agent invoked. */\nexport interface ToolCallEventLike {\n type: 'tool_call'\n toolName: string\n}\n\n/**\n * An artifact the agent produced. `content` is the enriched field — the\n * runtime's base `artifact` event carries only metadata; the completion\n * oracle needs the body to verify the deliverable, so the runtime emits it.\n */\nexport interface ArtifactEventLike {\n type: 'artifact'\n artifactId: string\n name?: string\n mimeType?: string\n uri?: string\n content?: string\n}\n\n/** A proposal / filing the agent created. */\nexport interface ProposalEventLike {\n type: 'proposal_created'\n proposalId: string\n title: string\n status?: 'pending' | 'approved' | 'rejected'\n}\n\n/**\n * The subset of runtime stream events `extractProducedState` consumes.\n * agent-runtime's full `RuntimeStreamEvent` union satisfies this structurally;\n * the `{ type: string }` catch-all keeps the input permissive so callers can\n * pass the whole unfiltered telemetry stream — unrecognized events are skipped.\n */\nexport type RuntimeEventLike =\n | ToolCallEventLike\n | ArtifactEventLike\n | ProposalEventLike\n | { type: string }\n\nfunction artifactKind(mimeType: string | undefined): string {\n if (!mimeType) return 'file'\n if (mimeType.includes('json')) return 'json'\n if (mimeType.startsWith('text/')) return 'text'\n return 'file'\n}\n\n/**\n * Normalize a run's runtime event stream into `ProducedState`.\n *\n * Pure and total — unrecognized event types are skipped. `toolCalls` is\n * deduplicated by name in first-seen order (completion cares about a tool's\n * presence, not its call count). An artifact with neither a name nor a uri\n * still yields an entry keyed by its `artifactId` so it is never silently\n * dropped; an artifact with no `content` yields empty content, which the\n * completion oracle's structural check then rejects on its own.\n */\nexport function extractProducedState(events: readonly RuntimeEventLike[]): ProducedState {\n const artifacts: Artifact[] = []\n const proposals: ProducedProposal[] = []\n const toolCalls: string[] = []\n const seenTools = new Set<string>()\n\n for (const ev of events) {\n if (ev.type === 'tool_call') {\n const name = (ev as ToolCallEventLike).toolName\n if (name && !seenTools.has(name)) {\n seenTools.add(name)\n toolCalls.push(name)\n }\n } else if (ev.type === 'artifact') {\n const a = ev as ArtifactEventLike\n artifacts.push({\n kind: artifactKind(a.mimeType),\n path: a.name ?? a.uri ?? a.artifactId,\n content: a.content ?? '',\n })\n } else if (ev.type === 'proposal_created') {\n const p = ev as ProposalEventLike\n proposals.push({ id: p.proposalId, title: p.title, status: p.status ?? 'pending' })\n }\n }\n\n return { artifacts, proposals, toolCalls }\n}\n","/**\n * Versioned prompt registry.\n *\n * Every prompt used in an eval run is registered with an explicit version.\n * Reports include the content hash so A/B compares are rigorous: if the\n * hash changes between two reports, the prompt actually changed; if it\n * matches, the variance is elsewhere.\n *\n * Hash is SHA-256(content), truncated to 12 hex chars for readability.\n * Uses the Web Crypto API (works in Workers, Node 22+, browsers).\n */\n\nexport interface PromptHandle {\n /** Stable human-readable id, e.g. 'browser.system' */\n id: string\n /** Caller-chosen version string, e.g. 'v3' or '2026-04-20' */\n version: string\n /** SHA-256 of content, 12-hex-char prefix */\n hash: string\n /** Full prompt body */\n content: string\n}\n\nexport class PromptRegistry {\n private readonly entries = new Map<string, PromptHandle>() // `${id}@${version}` → handle\n\n /**\n * Register a prompt. Re-registering the same id+version with DIFFERENT\n * content throws — versions are immutable. Re-registering with the SAME\n * content is a no-op (idempotent).\n */\n async register(id: string, version: string, content: string): Promise<PromptHandle> {\n validateId(id)\n validateVersion(version)\n\n const key = makeKey(id, version)\n const hash = await hashContent(content)\n const existing = this.entries.get(key)\n if (existing) {\n if (existing.hash !== hash) {\n throw new Error(\n `Prompt ${key} already registered with a different hash (${existing.hash} vs ${hash}). Bump the version.`,\n )\n }\n return existing\n }\n const handle: PromptHandle = { id, version, hash, content }\n this.entries.set(key, handle)\n return handle\n }\n\n /** Look up a registered prompt. Throws if unknown — no implicit defaults. */\n get(id: string, version: string): PromptHandle {\n const key = makeKey(id, version)\n const handle = this.entries.get(key)\n if (!handle) throw new Error(`Prompt ${key} not registered`)\n return handle\n }\n\n /** Return all versions of an id, newest-first (lex-descending on version). */\n listVersions(id: string): PromptHandle[] {\n return [...this.entries.values()]\n .filter((h) => h.id === id)\n .sort((a, b) => b.version.localeCompare(a.version))\n }\n\n /** Snapshot the whole registry — useful for including in reports. */\n list(): PromptHandle[] {\n return [...this.entries.values()]\n }\n\n /** Verify a hash against registered content. Returns null if not found. */\n verifyHash(id: string, version: string, expectedHash: string): boolean | null {\n const handle = this.entries.get(makeKey(id, version))\n if (!handle) return null\n return handle.hash === expectedHash\n }\n}\n\n/** SHA-256(content) → first 12 hex chars. Stable across runtimes. */\nexport async function hashContent(content: string): Promise<string> {\n const bytes = new TextEncoder().encode(content)\n const digest = await crypto.subtle.digest('SHA-256', bytes)\n const full = Array.from(new Uint8Array(digest))\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('')\n return full.slice(0, 12)\n}\n\nfunction makeKey(id: string, version: string): string {\n return `${id}@${version}`\n}\n\nconst ID_RE = /^[a-z][a-z0-9._-]*$/i\nfunction validateId(id: string): void {\n if (!ID_RE.test(id)) {\n throw new Error(`Invalid prompt id \"${id}\": must match ${ID_RE}`)\n }\n}\n\nfunction validateVersion(version: string): void {\n if (!version || version.length > 64) {\n throw new Error(`Invalid version \"${version}\": must be 1–64 chars`)\n }\n}\n","export interface SteeringRolePrompt {\n system?: string\n append?: string\n}\n\nexport interface SteeringBundle {\n id: string\n coderPrompt?: string\n continuePrompt?: string\n reviewerPrompts?: Record<string, string>\n skills?: string[]\n rolePrompts?: Record<string, SteeringRolePrompt>\n metadata?: Record<string, unknown>\n}\n\nexport interface SteeringDelta {\n coderPrompt?: string\n continuePrompt?: string\n reviewerPrompts?: Record<string, string>\n skills?: string[]\n rolePrompts?: Record<string, SteeringRolePrompt>\n metadata?: Record<string, unknown>\n}\n\nexport function mergeSteeringBundle(base: SteeringBundle, delta: SteeringDelta): SteeringBundle {\n return {\n ...base,\n ...(delta.coderPrompt !== undefined ? { coderPrompt: delta.coderPrompt } : {}),\n ...(delta.continuePrompt !== undefined ? { continuePrompt: delta.continuePrompt } : {}),\n reviewerPrompts: {\n ...(base.reviewerPrompts ?? {}),\n ...(delta.reviewerPrompts ?? {}),\n },\n skills: delta.skills ?? base.skills,\n rolePrompts: {\n ...(base.rolePrompts ?? {}),\n ...(delta.rolePrompts ?? {}),\n },\n metadata: {\n ...(base.metadata ?? {}),\n ...(delta.metadata ?? {}),\n },\n }\n}\n\nexport function renderSteeringText(bundle: SteeringBundle): string {\n const lines: string[] = [`bundle:${bundle.id}`]\n if (bundle.coderPrompt) lines.push(`coder:${bundle.coderPrompt}`)\n if (bundle.continuePrompt) lines.push(`continue:${bundle.continuePrompt}`)\n const reviewers = Object.entries(bundle.reviewerPrompts ?? {}).sort(([a], [b]) =>\n a.localeCompare(b),\n )\n for (const [name, prompt] of reviewers) lines.push(`reviewer:${name}:${prompt}`)\n const skills = [...(bundle.skills ?? [])].sort()\n if (skills.length) lines.push(`skills:${skills.join(',')}`)\n return lines.join('\\n')\n}\n","import { aggregateRunScore, type RunScore, type RunScoreWeights } from './run-score'\nimport type { SteeringBundle } from './steering'\n\nexport type SteeringOptimizerBackend = 'pairwise' | 'ax-gepa'\n\nexport interface SteeringOptimizationRow {\n variantId: string\n scenarioId: string\n bundle: SteeringBundle\n score: RunScore\n metadata?: Record<string, unknown>\n}\n\nexport interface SteeringOptimizationSelector {\n backend: SteeringOptimizerBackend\n signature?: string\n labels?: string[]\n rationale?: string\n}\n\nexport interface SteeringOptimizationResult {\n backend: SteeringOptimizerBackend\n recommendedVariantId: string\n rationale: string\n rankings: Array<{ variantId: string; mean: number; runs: number }>\n selector?: SteeringOptimizationSelector\n skipped?: boolean\n}\n\nexport interface SteeringOptimizerConfig {\n weights?: Partial<RunScoreWeights>\n}\n\nexport interface AxSteeringOptimizerConfig extends SteeringOptimizerConfig {\n provider: 'openai' | 'anthropic'\n apiKey: string\n model: string\n teacherModel?: string\n minRows?: number\n}\n\ntype AxServiceFactory = (config: {\n name: 'openai' | 'anthropic'\n apiKey: string\n config: { model: string }\n}) => unknown\n\ninterface AxSelectorProgram {\n applyOptimization(compiled: unknown): void\n}\n\ntype AxFactory = (signature: string, options: { description: string }) => AxSelectorProgram\n\ninterface AxGepaCompileResult {\n optimizedProgram?: unknown\n bestScore?: number\n}\n\ninterface AxGepaInstance {\n compile(\n selector: AxSelectorProgram,\n train: ScenarioWinner[],\n metric: (input: { prediction?: { variantId?: string }; example?: ScenarioWinner }) => number,\n options: { validationExamples: ScenarioWinner[]; maxMetricCalls: number },\n ): Promise<AxGepaCompileResult>\n}\n\ninterface AxGepaConstructor {\n new (config: {\n studentAI: unknown\n teacherAI: unknown\n numTrials: number\n minibatch: boolean\n minibatchSize: number\n earlyStoppingTrials: number\n sampleCount: number\n }): AxGepaInstance\n}\n\ninterface AxModule {\n ai: AxServiceFactory\n ax: AxFactory\n AxGEPA: AxGepaConstructor\n}\n\ninterface ScenarioWinner {\n task: string\n split: string\n seedPreview: string\n variantId: string\n}\n\nexport class PairwiseSteeringOptimizer {\n optimize(\n rows: SteeringOptimizationRow[],\n config: SteeringOptimizerConfig = {},\n ): SteeringOptimizationResult {\n const ranked = rankRows(rows, config.weights)\n if (!ranked.length) throw new Error('no steering optimization rows')\n return {\n backend: 'pairwise',\n recommendedVariantId: ranked[0]!.variantId,\n rationale: `Highest observed mean aggregate across ${rows.length} scored run(s).`,\n rankings: ranked,\n }\n }\n}\n\nexport class AxGepaSteeringOptimizer {\n constructor(private readonly config: AxSteeringOptimizerConfig) {}\n\n async optimize(rows: SteeringOptimizationRow[]): Promise<SteeringOptimizationResult> {\n const fallback = new PairwiseSteeringOptimizer().optimize(rows, this.config)\n const minRows = this.config.minRows ?? 6\n const variantIds = [...new Set(rows.map((row) => row.variantId))]\n const byScenario = collapseScenarioWinners(rows, this.config.weights)\n if (variantIds.length < 2 || byScenario.length < minRows) {\n return {\n ...fallback,\n backend: 'ax-gepa',\n skipped: true,\n rationale: `AxGEPA skipped: need >=2 variants and >=${minRows} scenario winners, got ${variantIds.length} variant(s) and ${byScenario.length} scenario winner(s).`,\n }\n }\n\n let axLib: AxModule\n try {\n axLib = (await import('@ax-llm/ax')) as AxModule\n } catch {\n return {\n ...fallback,\n backend: 'ax-gepa',\n skipped: true,\n rationale: 'AxGEPA unavailable: install @ax-llm/ax to enable selector optimization.',\n }\n }\n\n const { ai, ax, AxGEPA } = axLib\n const signature = `task:string, split:string, seedPreview:string -> variantId:class \"${variantIds.join(', ')}\", rationale:string`\n const selector = ax(signature, {\n description: 'Choose the best steering bundle variant for an autopilot task.',\n })\n const splitIndex = Math.max(1, Math.floor(byScenario.length * 0.8))\n const train = byScenario.slice(0, splitIndex)\n const validation = byScenario.slice(splitIndex)\n if (!validation.length) {\n return {\n ...fallback,\n backend: 'ax-gepa',\n skipped: true,\n rationale: 'AxGEPA skipped: no validation examples after split.',\n }\n }\n\n const optimizer = new AxGEPA({\n studentAI: createAxService(ai, this.config.provider, this.config.apiKey, this.config.model),\n teacherAI: createAxService(\n ai,\n this.config.provider,\n this.config.apiKey,\n this.config.teacherModel ?? this.config.model,\n ),\n numTrials: 8,\n minibatch: true,\n minibatchSize: 4,\n earlyStoppingTrials: 3,\n sampleCount: 1,\n })\n\n const compiled = await optimizer.compile(\n selector,\n train,\n ({ prediction, example }) => (prediction?.variantId === example?.variantId ? 1 : 0),\n {\n validationExamples: validation,\n maxMetricCalls: 64,\n },\n )\n if (compiled.optimizedProgram !== undefined) {\n selector.applyOptimization(compiled.optimizedProgram)\n }\n\n return {\n ...fallback,\n backend: 'ax-gepa',\n rationale: `AxGEPA trained a variant selector from ${byScenario.length} scored scenario winner(s); default winner remains ${fallback.recommendedVariantId}.`,\n selector: {\n backend: 'ax-gepa',\n signature,\n labels: variantIds,\n rationale: compiled.bestScore !== undefined ? `bestScore=${compiled.bestScore}` : undefined,\n },\n }\n }\n}\n\nfunction rankRows(rows: SteeringOptimizationRow[], weights?: Partial<RunScoreWeights>) {\n const buckets = new Map<string, number[]>()\n for (const row of rows) {\n const values = buckets.get(row.variantId) ?? []\n values.push(aggregateRunScore(row.score, weights))\n buckets.set(row.variantId, values)\n }\n return [...buckets.entries()]\n .map(([variantId, values]) => ({\n variantId,\n mean: values.reduce((sum, value) => sum + value, 0) / values.length,\n runs: values.length,\n }))\n .sort((a, b) => b.mean - a.mean)\n}\n\nfunction collapseScenarioWinners(\n rows: SteeringOptimizationRow[],\n weights?: Partial<RunScoreWeights>,\n) {\n const byScenario = new Map<string, SteeringOptimizationRow[]>()\n for (const row of rows) {\n const bucket = byScenario.get(row.scenarioId) ?? []\n bucket.push(row)\n byScenario.set(row.scenarioId, bucket)\n }\n return [...byScenario.entries()].map(([scenarioId, scenarioRows]) => {\n const best = scenarioRows\n .map((row) => ({ row, aggregate: aggregateRunScore(row.score, weights) }))\n .sort((a, b) => b.aggregate - a.aggregate)[0]!\n return {\n task: String(best.row.metadata?.task ?? best.row.metadata?.seed_preview ?? scenarioId),\n split: String(best.row.metadata?.split ?? 'train'),\n seedPreview: String(best.row.metadata?.seed_preview ?? ''),\n variantId: best.row.variantId,\n }\n })\n}\n\nfunction createAxService(\n aiFactory: AxServiceFactory,\n provider: 'openai' | 'anthropic',\n apiKey: string,\n model: string,\n) {\n return aiFactory({\n name: provider,\n apiKey,\n config: { model },\n })\n}\n","/**\n * Workspace inspector — score the persisted state of an agent after a run.\n *\n * Many evals don't ask \"did the response say the right thing\" but \"did the\n * agent put the right rows in the DB / files in the vault / entities on the\n * canvas\". This is the primitive for that.\n *\n * Implementations read from D1, KV, filesystem, or any store — the interface\n * is deliberately small so consumers plug in their own backends.\n */\n\nexport interface WorkspaceSnapshot {\n /** Vault files: logical path → content */\n files: Record<string, string>\n /** DB rows: table name → array of rows (post-validation) */\n rows: Record<string, Array<Record<string, unknown>>>\n /** KV entries: key → value (scoped to whatever prefix the inspector chose) */\n kv: Record<string, string>\n /** Free-form blob metadata: for large binaries the inspector stores summary, not bytes */\n blobs?: Record<string, { size: number; hash?: string; mimeType?: string }>\n}\n\nexport interface InspectorContext {\n /** Workspace / agent / thread id — whatever the backend uses to scope the snapshot */\n scopeId: string\n /** Optional scenario id — allows scenario-specific snapshot shaping */\n scenarioId?: string\n}\n\nexport interface WorkspaceInspector {\n name: string\n snapshot(context: InspectorContext): Promise<WorkspaceSnapshot>\n}\n\n// ---------------------------------------------------------------------------\n// In-memory inspector — useful for tests, not for production\n// ---------------------------------------------------------------------------\n\nexport class InMemoryWorkspaceInspector implements WorkspaceInspector {\n readonly name = 'in-memory'\n private readonly snapshots = new Map<string, WorkspaceSnapshot>()\n\n set(scopeId: string, snapshot: WorkspaceSnapshot): void {\n this.snapshots.set(scopeId, snapshot)\n }\n\n async snapshot(context: InspectorContext): Promise<WorkspaceSnapshot> {\n return this.snapshots.get(context.scopeId) ?? { files: {}, rows: {}, kv: {} }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Snapshot-level assertions\n// ---------------------------------------------------------------------------\n\nexport interface WorkspaceAssertion {\n name: string\n description?: string\n check(snapshot: WorkspaceSnapshot): WorkspaceAssertionResult\n}\n\nexport interface WorkspaceAssertionResult {\n pass: boolean\n /** 0..1 — partial credit for assertions that admit it */\n score: number\n detail?: string\n}\n\nexport function fileExists(path: string): WorkspaceAssertion {\n return {\n name: `file_exists:${path}`,\n check(snapshot) {\n const pass = path in snapshot.files\n return {\n pass,\n score: pass ? 1 : 0,\n detail: pass ? undefined : `No file at ${path}`,\n }\n },\n }\n}\n\nexport function fileContains(path: string, needle: string): WorkspaceAssertion {\n return {\n name: `file_contains:${path}:${needle}`,\n check(snapshot) {\n const content = snapshot.files[path]\n if (content === undefined) {\n return { pass: false, score: 0, detail: `File ${path} missing` }\n }\n const pass = content.includes(needle)\n return {\n pass,\n score: pass ? 1 : 0,\n detail: pass ? undefined : `File ${path} missing substring \"${needle}\"`,\n }\n },\n }\n}\n\nexport function rowCount(table: string, min: number, max?: number): WorkspaceAssertion {\n return {\n name: `row_count:${table}:[${min},${max ?? '∞'}]`,\n check(snapshot) {\n const rows = snapshot.rows[table] ?? []\n const count = rows.length\n const upper = max ?? Infinity\n const pass = count >= min && count <= upper\n const score = pass ? 1 : count < min ? Math.max(0, count / min) : Math.max(0, upper / count)\n return {\n pass,\n score,\n detail: pass\n ? undefined\n : `Table ${table} has ${count} rows, expected [${min}, ${max ?? '∞'}]`,\n }\n },\n }\n}\n\nexport function rowWhere<T extends Record<string, unknown>>(\n table: string,\n predicate: (row: T) => boolean,\n options?: { min?: number },\n): WorkspaceAssertion {\n const min = options?.min ?? 1\n return {\n name: `row_where:${table}`,\n check(snapshot) {\n const rows = (snapshot.rows[table] ?? []) as T[]\n const matching = rows.filter(predicate).length\n const pass = matching >= min\n return {\n pass,\n score: pass ? 1 : Math.max(0, matching / min),\n detail: pass\n ? undefined\n : `Table ${table} has ${matching} matching rows, expected ≥ ${min}`,\n }\n },\n }\n}\n\n/** Run many assertions; return aggregate pass + mean score + per-assertion details. */\nexport function runAssertions(\n snapshot: WorkspaceSnapshot,\n assertions: WorkspaceAssertion[],\n): {\n pass: boolean\n score: number\n results: Array<{ assertion: string; result: WorkspaceAssertionResult }>\n} {\n const results = assertions.map((a) => ({ assertion: a.name, result: a.check(snapshot) }))\n const pass = results.every((r) => r.result.pass)\n const score = results.length\n ? results.reduce((acc, r) => acc + r.result.score, 0) / results.length\n : 1\n return { pass, score, results }\n}\n","/**\n * BudgetGuard — enforces token / wall-clock / call / $ caps, records\n * a ledger entry on every decrement, emits `budget_breach` + throws\n * `BudgetBreachError` when a cap is hit.\n *\n * Wraps a TraceEmitter. The emitter persists ledger entries + breach\n * events so the classifier, pipelines, and reports can all read\n * budget state from the trace corpus — no separate accounting.\n */\n\nimport { AgentEvalError } from './errors'\nimport type { TraceEmitter } from './trace/emitter'\nimport type { BudgetSpec } from './trace/schema'\n\nexport class BudgetBreachError extends AgentEvalError {\n constructor(\n public dimension: keyof BudgetSpec,\n public limit: number,\n public attempted: number,\n ) {\n super('verification', `budget breach on ${dimension}: attempted ${attempted} vs limit ${limit}`)\n }\n}\n\nexport class BudgetGuard {\n private consumed: Record<keyof BudgetSpec, number> = { tokens: 0, wallMs: 0, calls: 0, usd: 0 }\n private emitter: TraceEmitter\n private budget: BudgetSpec\n private startedAt: number\n\n constructor(emitter: TraceEmitter, budget: BudgetSpec, now: () => number = () => Date.now()) {\n this.emitter = emitter\n this.budget = budget\n this.startedAt = now()\n }\n\n /** Record consumption. Throws `BudgetBreachError` if any dimension exceeds its cap. */\n async charge(delta: Partial<Record<keyof BudgetSpec, number>>, spanId?: string): Promise<void> {\n for (const [dim, value] of Object.entries(delta) as Array<[keyof BudgetSpec, number]>) {\n if (!Number.isFinite(value) || value < 0) {\n throw new Error(`BudgetGuard.charge: non-finite or negative ${dim}=${value}`)\n }\n this.consumed[dim] += value\n const limit = this.budget[dim]\n const consumed = this.consumed[dim]\n const remaining = limit === undefined ? Infinity : limit - consumed\n const breached = limit !== undefined && consumed > limit\n if (limit !== undefined) {\n await this.emitter.recordBudget({\n dimension: dim,\n limit,\n consumed,\n remaining,\n breached,\n spanId,\n })\n }\n if (breached) {\n throw new BudgetBreachError(dim, limit!, consumed)\n }\n }\n }\n\n /** Convenience: advance wall-clock budget based on elapsed wall time. */\n async tickWall(nowMs: number, spanId?: string): Promise<void> {\n const elapsed = nowMs - this.startedAt\n const already = this.consumed.wallMs\n const delta = Math.max(0, elapsed - already)\n if (delta > 0) await this.charge({ wallMs: delta }, spanId)\n }\n\n get state(): Record<keyof BudgetSpec, number> {\n return { ...this.consumed }\n }\n}\n","/**\n * Cost tracker — token + USD accounting per scenario and per run.\n *\n * Adapted from generic usage-event accounting. Every\n * optimizer needs to know \"is the quality gain worth the cost delta?\",\n * and every dashboard needs dollars-per-completed-task. MODEL_PRICING\n * from metrics.ts stays authoritative for estimate math; this module\n * adds the aggregation + per-scenario roll-up that was duplicated\n * across 4 verticals.\n */\n\nimport { estimateCost } from './metrics'\n\nexport interface TokenSpec {\n inputTokens: number\n outputTokens: number\n cachedTokens?: number\n reasoningTokens?: number\n}\n\nexport interface CostEntry extends TokenSpec {\n scenarioId: string\n model: string\n /** Override estimate with an observed cost (e.g. from provider response). */\n actualCostUsd?: number\n timestamp: number\n /** Free-form tags (variant id, round #, etc.). */\n tags?: Record<string, string>\n}\n\nexport interface ScenarioCost {\n scenarioId: string\n entries: CostEntry[]\n totalInputTokens: number\n totalOutputTokens: number\n totalCachedTokens: number\n totalCostUsd: number\n /** Pass flag — set by consumer via markOutcome; used for cost-per-completed-task. */\n completed?: boolean\n}\n\nexport class CostTracker {\n private byScenario = new Map<string, ScenarioCost>()\n\n record(entry: Omit<CostEntry, 'timestamp'> & { timestamp?: number }): CostEntry {\n const full: CostEntry = { timestamp: entry.timestamp ?? Date.now(), ...entry }\n assertNonNegative(full.inputTokens, 'inputTokens')\n assertNonNegative(full.outputTokens, 'outputTokens')\n let bucket = this.byScenario.get(full.scenarioId)\n if (!bucket) {\n bucket = {\n scenarioId: full.scenarioId,\n entries: [],\n totalInputTokens: 0,\n totalOutputTokens: 0,\n totalCachedTokens: 0,\n totalCostUsd: 0,\n }\n this.byScenario.set(full.scenarioId, bucket)\n }\n bucket.entries.push(full)\n bucket.totalInputTokens += full.inputTokens\n bucket.totalOutputTokens += full.outputTokens\n bucket.totalCachedTokens += full.cachedTokens ?? 0\n bucket.totalCostUsd += costFor(full)\n return full\n }\n\n markOutcome(scenarioId: string, completed: boolean): void {\n const bucket = this.byScenario.get(scenarioId)\n if (!bucket) throw new Error(`CostTracker.markOutcome: unknown scenario \"${scenarioId}\"`)\n bucket.completed = completed\n }\n\n /**\n * Convenience: record + markOutcome in one call from a\n * `{ usage, verdict }`-shaped response (starter-foundry's\n * `invokeMetaJudge` returns this shape; consumers that wrap any\n * judge/critic can follow the same convention).\n *\n * `usage.model` must be present in `MODEL_PRICING` for cost math to\n * populate; otherwise totalCostUsd stays at 0 for the entry but\n * tokens still aggregate.\n */\n recordVerdict(\n verdict: {\n usage?: {\n inputTokens: number\n outputTokens: number\n model: string\n cachedTokens?: number\n reasoningTokens?: number\n }\n verdict?: 'pass' | 'fail' | 'borderline' | string\n },\n scenarioId: string,\n tags?: Record<string, string>,\n ): CostEntry | null {\n if (!verdict.usage) return null\n const entry = this.record({\n scenarioId,\n model: verdict.usage.model,\n inputTokens: verdict.usage.inputTokens,\n outputTokens: verdict.usage.outputTokens,\n cachedTokens: verdict.usage.cachedTokens,\n reasoningTokens: verdict.usage.reasoningTokens,\n tags,\n })\n this.markOutcome(scenarioId, verdict.verdict === 'pass')\n return entry\n }\n\n get(scenarioId: string): ScenarioCost | undefined {\n return this.byScenario.get(scenarioId)\n }\n\n list(): ScenarioCost[] {\n return [...this.byScenario.values()]\n }\n\n summary(): CostSummary {\n const scenarios = this.list()\n const completed = scenarios.filter((s) => s.completed === true)\n const totalCost = scenarios.reduce((a, s) => a + s.totalCostUsd, 0)\n const totalInput = scenarios.reduce((a, s) => a + s.totalInputTokens, 0)\n const totalOutput = scenarios.reduce((a, s) => a + s.totalOutputTokens, 0)\n const totalCompletedCost = completed.reduce((a, s) => a + s.totalCostUsd, 0)\n return {\n scenarioCount: scenarios.length,\n completedCount: completed.length,\n totalInputTokens: totalInput,\n totalOutputTokens: totalOutput,\n totalCostUsd: totalCost,\n avgCostPerScenarioUsd: scenarios.length ? totalCost / scenarios.length : 0,\n costPerCompletedTaskUsd: completed.length ? totalCompletedCost / completed.length : null,\n }\n }\n}\n\nexport interface CostSummary {\n scenarioCount: number\n completedCount: number\n totalInputTokens: number\n totalOutputTokens: number\n totalCostUsd: number\n avgCostPerScenarioUsd: number\n /** Total USD / completed scenarios — null when nothing completed. */\n costPerCompletedTaskUsd: number | null\n}\n\nfunction costFor(entry: CostEntry): number {\n if (typeof entry.actualCostUsd === 'number' && Number.isFinite(entry.actualCostUsd)) {\n return entry.actualCostUsd\n }\n return estimateCost(entry.inputTokens, entry.outputTokens, entry.model)\n}\n\nfunction assertNonNegative(n: number, name: string): void {\n if (!Number.isFinite(n) || n < 0) {\n throw new Error(`CostTracker: ${name} must be a non-negative finite number, got ${n}`)\n }\n}\n","/**\n * muffled-gate-scanner — test helper that greps consumer source for\n * gate + measurement anti-patterns and fails with file:line locations.\n *\n * Named pattern lives at starter-foundry's `.evolve/patterns/muffled-gate.md`;\n * same shape applies to every consumer (a gate that should fail loud\n * returns silent success; a metric that should emit a real number\n * reports noise/empty).\n *\n * Usage (in a consumer project's test file):\n *\n * import { scanForMuffledGates, DEFAULT_FINDERS } from '@tangle-network/agent-eval'\n *\n * test('no muffled gates in eval surface', () => {\n * const findings = scanForMuffledGates({\n * repoRoot: process.cwd(),\n * scanFiles: ['src/eval/scaffold.ts', 'scripts/promote.mjs'],\n * finders: DEFAULT_FINDERS,\n * })\n * if (findings.length) assert.fail(formatFindings(findings))\n * })\n *\n * Customize by passing your own `finders` — each finder is\n * `(file, text) => Finding[]` and runs per-file.\n *\n * Escape hatch: any line containing `muffle-ok:` is excluded from all\n * finders, letting consumers opt a legitimate fallback out explicitly.\n */\n\nimport { existsSync, readdirSync, readFileSync, statSync } from 'node:fs'\nimport { join } from 'node:path'\n\nexport interface MuffledFinding {\n file: string\n line: number\n lineText: string\n pattern: string\n}\n\nexport type MuffledFinder = (file: string, text: string) => MuffledFinding[]\n\nexport interface ScanOptions {\n /** Absolute path to the repo root. */\n repoRoot: string\n /** Explicit file list (paths relative to repoRoot) for context-specific finders. */\n scanFiles: string[]\n /**\n * Auto-derived scan: walk these dirs for files matching importGlob + the\n * string `importsContain` and run the universal finders on them. Pattern\n * from starter-foundry H4 (research/decisions/001) — catches new files\n * with agent-eval import that would otherwise escape context-specific\n * scan lists.\n */\n autoDerive?: {\n roots: string[] // e.g. ['src', 'scripts']\n extensions: RegExp // e.g. /\\.(ts|mjs|js)$/\n importsContain: string // e.g. '@tangle-network/agent-eval'\n universalFinders: MuffledFinder[]\n }\n /** Per-file finders (context-specific patterns). */\n finders: MuffledFinder[]\n}\n\n/**\n * Strip line comments + block-comment continuation lines from a single line\n * so finders don't match prose about the pattern.\n */\nfunction codeOf(line: string): string {\n return line.replace(/\\/\\/.*$/, '').replace(/^\\s*\\*.*$/, '')\n}\n\n/** Skip if the line carries the `muffle-ok:` escape hatch. */\nfunction isMuffleOk(line: string): boolean {\n return line.includes('muffle-ok:')\n}\n\n/**\n * Default finder: `command || true` in a testCommand/setupCommand/cmd/command\n * string. Swallows exit codes.\n */\nexport const findFallbackToPass: MuffledFinder = (file, text) => {\n const out: MuffledFinding[] = []\n const lines = text.split('\\n')\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i]!\n if (isMuffleOk(line)) continue\n const code = codeOf(line)\n if (!code.trim()) continue\n if (/\\|\\| true/.test(code) && /(testCommand|setupCommand|cmd|command)/.test(code)) {\n out.push({\n file,\n line: i + 1,\n lineText: line.trim(),\n pattern: 'fallback-to-pass (|| true in command string)',\n })\n }\n }\n return out\n}\n\n/**\n * `testCommand: 'true'` literal silent-pass — an unknown-language dispatch\n * arm that returns a no-op instead of throwing.\n */\nexport const findLiteralTruePass: MuffledFinder = (file, text) => {\n const out: MuffledFinding[] = []\n const lines = text.split('\\n')\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i]!\n if (isMuffleOk(line)) continue\n const code = codeOf(line)\n if (!code.trim()) continue\n if (/testCommand\\s*:\\s*['\"]true['\"]/.test(code)) {\n out.push({\n file,\n line: i + 1,\n lineText: line.trim(),\n pattern: 'literal-true-pass (testCommand: \"true\")',\n })\n }\n }\n return out\n}\n\n/**\n * `new SubprocessSandboxDriver({ cwd: ... })` — constructor arg silently\n * dropped in agent-eval <0.7.1. 0.7.1+ honors as fallback, but the form\n * still invites confusion; prefer `new SubprocessSandboxDriver()` with\n * cwd in the per-call HarnessConfig.\n */\nexport const findConstructorCwdDropped: MuffledFinder = (file, text) => {\n const out: MuffledFinding[] = []\n const lines = text.split('\\n')\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i]!\n if (isMuffleOk(line)) continue\n const code = codeOf(line)\n if (!code.trim()) continue\n if (/new\\s+SubprocessSandboxDriver\\s*\\(\\s*\\{[^}]*cwd\\s*:/.test(code)) {\n out.push({\n file,\n line: i + 1,\n lineText: line.trim(),\n pattern:\n 'construct-vs-call cwd dropped (driver.exec reads config.cwd, not constructor.cwd)',\n })\n }\n }\n return out\n}\n\n/**\n * `if (!expected) return true` — matcher auto-passes when ground truth is\n * absent. Inflates accuracy metrics for scenarios without expectations.\n */\nexport const findAutoMatchNoExpectation: MuffledFinder = (file, text) => {\n const out: MuffledFinding[] = []\n const lines = text.split('\\n')\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i]!\n if (isMuffleOk(line)) continue\n const code = codeOf(line)\n if (!code.trim()) continue\n if (/if\\s*\\(\\s*!expected\\s*\\)\\s*return\\s+true/.test(code)) {\n out.push({\n file,\n line: i + 1,\n lineText: line.trim(),\n pattern: 'auto-match-no-expectation (if (!expected) return true)',\n })\n }\n }\n return out\n}\n\n/**\n * `if (p.skipped) return true` — skip-counts-as-pass in quality scorers.\n * Use three-valued `true | false | 'skipped'` return + explicit partial\n * credit instead.\n */\nexport const findSkipCountsAsPass: MuffledFinder = (file, text) => {\n const out: MuffledFinding[] = []\n const lines = text.split('\\n')\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i]!\n if (isMuffleOk(line)) continue\n const code = codeOf(line)\n if (!code.trim()) continue\n if (/if\\s*\\(\\s*\\w+\\.skipped\\s*\\)\\s*return\\s+true/.test(code)) {\n out.push({\n file,\n line: i + 1,\n lineText: line.trim(),\n pattern: 'skip-counts-as-pass (if (.skipped) return true)',\n })\n }\n }\n return out\n}\n\n/**\n * The canonical default bundle. Callers can import these individually,\n * replace them, or append custom finders for project-specific patterns.\n */\nexport const DEFAULT_FINDERS: MuffledFinder[] = [\n findFallbackToPass,\n findLiteralTruePass,\n findAutoMatchNoExpectation,\n findSkipCountsAsPass,\n]\n\n/** Finders that should run on EVERY file with the target import, not just SCAN_FILES. */\nexport const UNIVERSAL_FINDERS: MuffledFinder[] = [findConstructorCwdDropped]\n\n/**\n * Walk `roots` under `repoRoot` and return file paths (relative to repoRoot)\n * whose contents include `importsContain`.\n */\nfunction autoDeriveImporters(\n repoRoot: string,\n roots: string[],\n extensions: RegExp,\n importsContain: string,\n): string[] {\n const matches: string[] = []\n const walk = (rel: string) => {\n const abs = join(repoRoot, rel)\n if (!existsSync(abs)) return\n for (const entry of readdirSync(abs)) {\n const sub = join(rel, entry)\n const subAbs = join(repoRoot, sub)\n let st\n try {\n st = statSync(subAbs)\n } catch {\n continue\n }\n if (st.isDirectory()) {\n if (\n entry === 'node_modules' ||\n entry === 'dist' ||\n entry === 'dist-tests' ||\n entry.startsWith('.')\n )\n continue\n walk(sub)\n } else if (st.isFile() && extensions.test(entry)) {\n if (entry.endsWith('.test.ts') || entry.endsWith('.test.mjs') || entry.endsWith('.test.js'))\n continue\n let text: string\n try {\n text = readFileSync(subAbs, 'utf8')\n } catch {\n continue\n }\n if (text.includes(importsContain)) matches.push(sub)\n }\n }\n }\n for (const r of roots) walk(r)\n return matches\n}\n\n/**\n * Run all finders against the configured files. Returns a flat list of\n * findings. Callers format + assert as they prefer.\n */\nexport function scanForMuffledGates(opts: ScanOptions): MuffledFinding[] {\n const findings: MuffledFinding[] = []\n const scanned = new Set<string>()\n\n // Context-specific: run all finders on explicit SCAN_FILES.\n for (const file of opts.scanFiles) {\n const abs = join(opts.repoRoot, file)\n if (!existsSync(abs)) continue\n const text = readFileSync(abs, 'utf8')\n for (const find of opts.finders) findings.push(...find(file, text))\n scanned.add(file)\n }\n\n // Auto-derived: run universal finders on every importer not already scanned.\n if (opts.autoDerive) {\n const importers = autoDeriveImporters(\n opts.repoRoot,\n opts.autoDerive.roots,\n opts.autoDerive.extensions,\n opts.autoDerive.importsContain,\n )\n for (const file of importers) {\n if (scanned.has(file)) continue\n const abs = join(opts.repoRoot, file)\n if (!existsSync(abs)) continue\n const text = readFileSync(abs, 'utf8')\n for (const find of opts.autoDerive.universalFinders) findings.push(...find(file, text))\n }\n }\n\n return findings\n}\n\n/**\n * Format findings into a single assert.fail-ready message. Each finding\n * carries file:line + pattern name + the offending line.\n */\nexport function formatFindings(findings: MuffledFinding[]): string {\n if (findings.length === 0) return ''\n return [\n `Found ${findings.length} muffled-gate pattern(s).`,\n `Fix each or annotate the line with \"// muffle-ok: <reason>\".`,\n '',\n ...findings.map((f) => ` ${f.file}:${f.line} — ${f.pattern}\\n ${f.lineText}`),\n ].join('\\n')\n}\n","/**\n * Declarative oracles — ground-truth assertions without an LLM.\n *\n * Lifted from browser-agent-driver's _oracle.mjs. When you know the\n * expected outcome exactly (a URL, a text fragment, a JSON shape), you\n * don't need an LLM judge — you need a regex. These oracles are\n * composable pass/fail checks over an observation bundle.\n *\n * Each oracle returns { pass, detail, evidence? } and has a short\n * `id` for reporting. `evaluateOracles` runs a batch and aggregates.\n */\n\nexport interface OracleObservation {\n /** Final observable text output from the agent (response, page snapshot, stdout). */\n text?: string\n /** Final URL — for browser-style scenarios. */\n url?: string\n /** Any structured JSON the agent produced. */\n json?: unknown\n /** Free-form context used by custom oracles. */\n context?: Record<string, unknown>\n}\n\nexport interface OracleResult {\n id: string\n pass: boolean\n detail: string\n evidence?: string\n}\n\nexport interface Oracle {\n id: string\n check(obs: OracleObservation): OracleResult\n}\n\nexport function textInSnapshot(needle: string, opts: { caseSensitive?: boolean } = {}): Oracle {\n const id = `text-in-snapshot(${needle})`\n return {\n id,\n check(obs) {\n const hay = obs.text ?? ''\n const found = opts.caseSensitive\n ? hay.includes(needle)\n : hay.toLowerCase().includes(needle.toLowerCase())\n return {\n id,\n pass: found,\n detail: found ? `\"${needle}\" found` : `\"${needle}\" not present in observation`,\n evidence: found ? excerpt(hay, needle, opts.caseSensitive) : undefined,\n }\n },\n }\n}\n\nexport function urlContains(fragment: string): Oracle {\n const id = `url-contains(${fragment})`\n return {\n id,\n check(obs) {\n const url = obs.url ?? ''\n const pass = url.toLowerCase().includes(fragment.toLowerCase())\n return {\n id,\n pass,\n detail: pass ? `url ok (${url})` : `url \"${url}\" missing \"${fragment}\"`,\n evidence: url,\n }\n },\n }\n}\n\nexport function jsonShape(expected: Record<string, unknown>): Oracle {\n const id = `json-shape(${Object.keys(expected).join(',')})`\n return {\n id,\n check(obs) {\n const json = obs.json\n if (!isObject(json)) {\n return { id, pass: false, detail: 'observation.json missing or not an object' }\n }\n for (const [k, v] of Object.entries(expected)) {\n if (!(k in json)) return { id, pass: false, detail: `key \"${k}\" missing` }\n const actual = (json as Record<string, unknown>)[k]\n if (typeof v === 'string' && v.startsWith('re:')) {\n const re = new RegExp(v.slice(3))\n if (typeof actual !== 'string' || !re.test(actual)) {\n return { id, pass: false, detail: `key \"${k}\" failed regex ${v}` }\n }\n } else if (actual !== v) {\n return {\n id,\n pass: false,\n detail: `key \"${k}\" = ${JSON.stringify(actual)}, expected ${JSON.stringify(v)}`,\n }\n }\n }\n return { id, pass: true, detail: 'all keys match' }\n },\n }\n}\n\nexport function regexMatches(pattern: RegExp): Oracle {\n const id = `regex(${pattern.source})`\n return {\n id,\n check(obs) {\n const hay = obs.text ?? ''\n const m = hay.match(pattern)\n return {\n id,\n pass: m !== null,\n detail: m ? `matched \"${m[0]}\"` : `pattern ${pattern.source} not matched`,\n evidence: m?.[0],\n }\n },\n }\n}\n\n/**\n * Anti-bot detector — distinguishes genuine failures from blocked navigation\n * (cloudflare, recaptcha, etc). Returns an Oracle that PASSES when no block\n * marker is present; on block, detail names the blocker so runners can tag\n * results as \"blocked\" rather than \"failed\". Lifted from browser-agent-driver.\n */\nexport function notBlocked(): Oracle {\n const id = 'not-blocked'\n const markers: Array<{ name: string; re: RegExp }> = [\n { name: 'cloudflare', re: /just a moment|verifying you are human|cf-chl-|cloudflare/i },\n { name: 'recaptcha', re: /recaptcha|i'?m not a robot|challenge.?form/i },\n { name: 'hcaptcha', re: /hcaptcha/i },\n { name: 'akamai', re: /akamai|pragma: no-cache/i },\n { name: 'perimeterx', re: /perimeterx|px-captcha/i },\n { name: 'rate-limit', re: /rate.?limit|429 too many requests/i },\n { name: 'access-denied', re: /access denied|403 forbidden/i },\n ]\n return {\n id,\n check(obs) {\n const hay = obs.text ?? ''\n for (const { name, re } of markers) {\n if (re.test(hay)) {\n return {\n id,\n pass: false,\n detail: `blocked by ${name}`,\n evidence: (hay.match(re) ?? [])[0],\n }\n }\n }\n return { id, pass: true, detail: 'no anti-bot block detected' }\n },\n }\n}\n\nexport interface OracleReport {\n results: OracleResult[]\n pass: boolean\n passCount: number\n failCount: number\n /** 0-1 ratio of oracles passed. */\n score: number\n}\n\n/** Run all oracles against one observation and aggregate. */\nexport function evaluateOracles(obs: OracleObservation, oracles: Oracle[]): OracleReport {\n const results = oracles.map((o) => o.check(obs))\n const passCount = results.filter((r) => r.pass).length\n const failCount = results.length - passCount\n return {\n results,\n pass: failCount === 0 && results.length > 0,\n passCount,\n failCount,\n score: results.length ? passCount / results.length : 0,\n }\n}\n\nfunction excerpt(hay: string, needle: string, caseSensitive = false): string {\n const haySearch = caseSensitive ? hay : hay.toLowerCase()\n const needleSearch = caseSensitive ? needle : needle.toLowerCase()\n const idx = haySearch.indexOf(needleSearch)\n if (idx === -1) return ''\n const start = Math.max(0, idx - 20)\n const end = Math.min(hay.length, idx + needle.length + 20)\n return (start > 0 ? '…' : '') + hay.slice(start, end) + (end < hay.length ? '…' : '')\n}\n\nfunction isObject(v: unknown): v is Record<string, unknown> {\n return typeof v === 'object' && v !== null && !Array.isArray(v)\n}\n","/**\n * @stable\n *\n * Eval scorecard — the persistent (persona × profile) score timeline.\n *\n * Every benchmark run folds into per-cell entries; a cell is\n * `(scenarioId, profileHash)` and its timeline carries one entry per commit.\n * The scorecard answers the question a single run cannot: did THIS change\n * regress persona P on profile F, even while the aggregate improved?\n *\n * Storage is an append-only JSONL log — one line per (cell, commit). Appends\n * never read-modify-write, so concurrent campaign runs cannot clobber each\n * other; `loadScorecard` folds the log into the queryable `Scorecard`, and a\n * malformed line never breaks the read. `diffScorecard` compares the latest\n * entry of each cell against its predecessor with Cohen's d + Welch's t-test.\n */\n\nimport { appendFileSync, existsSync, mkdirSync, readFileSync } from 'node:fs'\nimport { dirname } from 'node:path'\nimport type { AgentProfile } from './agent-profile'\nimport { agentProfileHash } from './agent-profile'\nimport { welchsTTest } from './baseline'\nimport type { RunRecord } from './run-record'\nimport { cohensD } from './statistics'\n\n// ── Types ────────────────────────────────────────────────────────────\n\n/** One commit's measurement of one (scenario, profile) cell. */\nexport interface ScorecardEntry {\n commitSha: string\n /** ISO timestamp the entry was recorded. */\n timestamp: string\n /** Per-seed (or per-rep) scores for this cell at this commit. */\n scores: number[]\n /** Median of `scores` — the cell's headline score for the commit. */\n composite: number\n /** Per-dimension means, when the runs carried a judge breakdown. */\n perDimension?: Record<string, number>\n /** RunRecord ids folded into this entry — provenance. */\n runIds: string[]\n}\n\n/** A (scenario, profile) cell and its commit-ordered score timeline. */\nexport interface ScorecardCell {\n scenarioId: string\n profileHash: string\n /** Model id — denormalised from the profile for readable filtering. */\n model: string\n timeline: ScorecardEntry[]\n}\n\n/** The folded scorecard: every cell, plus the profile definitions by hash. */\nexport interface Scorecard {\n cells: ScorecardCell[]\n /** Profile definitions seen — keeps the scorecard self-describing. */\n profiles: Record<string, AgentProfile>\n}\n\n/** One append-only log line — a single cell's entry for a single commit. */\nexport interface ScorecardLogLine {\n scenarioId: string\n profileHash: string\n model: string\n profile: AgentProfile\n entry: ScorecardEntry\n}\n\n// ── Recording ────────────────────────────────────────────────────────\n\nexport interface RecordRunsOptions {\n /** The profile that produced these runs — keys the cell. */\n profile: AgentProfile\n commitSha: string\n /** Defaults to `new Date().toISOString()`. */\n timestamp?: string\n}\n\nfunction median(xs: number[]): number {\n if (xs.length === 0) return 0\n const sorted = [...xs].sort((a, b) => a - b)\n const mid = Math.floor(sorted.length / 2)\n return sorted.length % 2 === 0 ? (sorted[mid - 1]! + sorted[mid]!) / 2 : sorted[mid]!\n}\n\n/** The split score the run actually carries (`holdout` runs fill holdoutScore). */\nfunction runScore(run: RunRecord): number | undefined {\n return run.outcome.holdoutScore ?? run.outcome.searchScore\n}\n\n/** Mean of each judge dimension across the runs that reported one. */\nfunction aggregatePerDimension(runs: RunRecord[]): Record<string, number> | undefined {\n const sums = new Map<string, { total: number; count: number }>()\n for (const run of runs) {\n const dims = run.outcome.judgeScores?.perDimMean\n if (!dims) continue\n for (const [dim, value] of Object.entries(dims)) {\n if (!Number.isFinite(value)) continue\n const acc = sums.get(dim) ?? { total: 0, count: 0 }\n acc.total += value\n acc.count += 1\n sums.set(dim, acc)\n }\n }\n if (sums.size === 0) return undefined\n const out: Record<string, number> = {}\n for (const [dim, acc] of sums) out[dim] = acc.total / acc.count\n return out\n}\n\n/**\n * Fold a benchmark's `RunRecord[]` into per-cell scorecard log lines — one\n * line per scenario the runs cover. All runs are attributed to the single\n * `profile` in `opts` (the harness ran them under it); the cell key is\n * `(scenarioId, agentProfileHash(profile))`.\n */\nexport function recordRuns(runs: RunRecord[], opts: RecordRunsOptions): ScorecardLogLine[] {\n const profileHash = agentProfileHash(opts.profile)\n const timestamp = opts.timestamp ?? new Date().toISOString()\n\n const byScenario = new Map<string, RunRecord[]>()\n for (const run of runs) {\n const scenarioId = run.scenarioId\n if (!scenarioId) continue // un-keyed run — cannot place it in a cell\n const bucket = byScenario.get(scenarioId)\n if (bucket) bucket.push(run)\n else byScenario.set(scenarioId, [run])\n }\n\n const lines: ScorecardLogLine[] = []\n for (const [scenarioId, scenarioRuns] of byScenario) {\n const scored = scenarioRuns\n .map((run) => ({ run, score: runScore(run) }))\n .filter((s): s is { run: RunRecord; score: number } => s.score !== undefined)\n if (scored.length === 0) continue\n const scores = scored.map((s) => s.score)\n const entry: ScorecardEntry = {\n commitSha: opts.commitSha,\n timestamp,\n scores,\n composite: median(scores),\n runIds: scored.map((s) => s.run.runId),\n }\n const perDimension = aggregatePerDimension(scenarioRuns)\n if (perDimension) entry.perDimension = perDimension\n lines.push({\n scenarioId,\n profileHash,\n model: opts.profile.model,\n profile: opts.profile,\n entry,\n })\n }\n return lines\n}\n\n// ── Storage ──────────────────────────────────────────────────────────\n\n/** Append cell entries to the JSONL scorecard log. Creates the file/dir. */\nexport function appendScorecard(logPath: string, lines: ScorecardLogLine[]): void {\n if (lines.length === 0) return\n mkdirSync(dirname(logPath), { recursive: true })\n appendFileSync(logPath, `${lines.map((line) => JSON.stringify(line)).join('\\n')}\\n`)\n}\n\n/** Record runs and append them to the log in one call. Returns the lines. */\nexport function recordRunsToScorecard(\n logPath: string,\n runs: RunRecord[],\n opts: RecordRunsOptions,\n): ScorecardLogLine[] {\n const lines = recordRuns(runs, opts)\n appendScorecard(logPath, lines)\n return lines\n}\n\n/**\n * Fold the JSONL log into a queryable `Scorecard`. A missing file yields an\n * empty scorecard; a malformed line is skipped — a corrupt append never\n * breaks the read. Each cell's timeline is sorted chronologically.\n */\nexport function loadScorecard(logPath: string): Scorecard {\n if (!existsSync(logPath)) return { cells: [], profiles: {} }\n const cells = new Map<string, ScorecardCell>()\n const profiles: Record<string, AgentProfile> = {}\n\n for (const raw of readFileSync(logPath, 'utf8').split('\\n')) {\n const line = raw.trim()\n if (!line) continue\n let parsed: ScorecardLogLine\n try {\n parsed = JSON.parse(line) as ScorecardLogLine\n } catch {\n continue // skip a malformed line rather than failing the whole read\n }\n if (!parsed?.scenarioId || !parsed.profileHash || !parsed.entry) continue\n const key = `${parsed.scenarioId}::${parsed.profileHash}`\n let cell = cells.get(key)\n if (!cell) {\n cell = {\n scenarioId: parsed.scenarioId,\n profileHash: parsed.profileHash,\n model: parsed.model,\n timeline: [],\n }\n cells.set(key, cell)\n }\n cell.timeline.push(parsed.entry)\n if (parsed.profile) profiles[parsed.profileHash] = parsed.profile\n }\n\n for (const cell of cells.values()) {\n cell.timeline.sort((a, b) => a.timestamp.localeCompare(b.timestamp))\n }\n return { cells: [...cells.values()], profiles }\n}\n\n// ── Diff ─────────────────────────────────────────────────────────────\n\nexport type CellVerdict = 'improved' | 'regressed' | 'flat' | 'new'\n\nexport interface ScorecardCellDiff {\n scenarioId: string\n profileHash: string\n model: string\n verdict: CellVerdict\n /** Composite of the latest entry. */\n current: number\n /** Composite of the comparison entry — `null` when `verdict === 'new'`. */\n baseline: number | null\n /** `current − baseline` — `null` when new. */\n delta: number | null\n /** Cohen's d of current vs baseline samples — `null` when new or n < 2. */\n cohensD: number | null\n /** Welch's t-test p-value — `null` when new or n < 2. */\n pValue: number | null\n currentCommit: string\n baselineCommit: string | null\n}\n\nexport interface ScorecardDiff {\n cells: ScorecardCellDiff[]\n summary: { improved: number; regressed: number; flat: number; new: number }\n}\n\nexport interface DiffScorecardOptions {\n /** Compare each cell against this commit instead of its immediate predecessor. */\n baselineCommit?: string\n /** |Cohen's d| at/above which a move counts as real. Default 0.5. */\n minEffect?: number\n /** p-value at/below which a move is significant. Default 0.05. */\n maxP?: number\n /**\n * |delta| at/above which a move counts when statistics are unavailable\n * (a cell with fewer than 2 samples on either side). Default 0.05.\n */\n minDelta?: number\n}\n\n/**\n * Compare the latest entry of every cell against its predecessor (or against\n * `baselineCommit`) and classify the move. A move is `improved`/`regressed`\n * only when it clears both the effect-size and significance gates; otherwise\n * `flat`. Cells with no prior entry are `new`.\n */\nexport function diffScorecard(\n scorecard: Scorecard,\n opts: DiffScorecardOptions = {},\n): ScorecardDiff {\n const minEffect = opts.minEffect ?? 0.5\n const maxP = opts.maxP ?? 0.05\n const minDelta = opts.minDelta ?? 0.05\n\n const cells: ScorecardCellDiff[] = []\n for (const cell of scorecard.cells) {\n const timeline = cell.timeline\n if (timeline.length === 0) continue\n const current = timeline[timeline.length - 1]!\n\n const baseline = opts.baselineCommit\n ? [...timeline].reverse().find((e) => e.commitSha === opts.baselineCommit && e !== current)\n : timeline[timeline.length - 2]\n\n const base: Omit<\n ScorecardCellDiff,\n 'verdict' | 'baseline' | 'delta' | 'cohensD' | 'pValue' | 'baselineCommit'\n > = {\n scenarioId: cell.scenarioId,\n profileHash: cell.profileHash,\n model: cell.model,\n current: current.composite,\n currentCommit: current.commitSha,\n }\n\n if (!baseline) {\n cells.push({\n ...base,\n verdict: 'new',\n baseline: null,\n delta: null,\n cohensD: null,\n pValue: null,\n baselineCommit: null,\n })\n continue\n }\n\n const delta = current.composite - baseline.composite\n const canStat = baseline.scores.length >= 2 && current.scores.length >= 2\n let d: number | null = null\n let p: number | null = null\n let verdict: CellVerdict\n\n if (canStat) {\n d = cohensD(baseline.scores, current.scores)\n const t = welchsTTest(baseline.scores, current.scores)\n p = Number.isFinite(t.p) ? t.p : null\n const significant = Math.abs(d) >= minEffect && p !== null && p <= maxP\n verdict = significant ? (delta > 0 ? 'improved' : 'regressed') : 'flat'\n } else {\n // Too few samples for a real test — fall back to a raw-delta threshold.\n verdict = Math.abs(delta) >= minDelta ? (delta > 0 ? 'improved' : 'regressed') : 'flat'\n }\n\n cells.push({\n ...base,\n verdict,\n baseline: baseline.composite,\n delta,\n cohensD: d,\n pValue: p,\n baselineCommit: baseline.commitSha,\n })\n }\n\n const summary = { improved: 0, regressed: 0, flat: 0, new: 0 }\n for (const cell of cells) summary[cell.verdict] += 1\n return { cells, summary }\n}\n\n/**\n * Render a scorecard diff as a human-readable report — the block a feature\n * PR prints. Regressions are listed first; flat cells are summarised, not\n * enumerated.\n */\nexport function formatScorecardDiff(diff: ScorecardDiff): string {\n const lines: string[] = []\n const { summary } = diff\n lines.push(\n `Scorecard: ${summary.regressed} regressed · ${summary.improved} improved · ` +\n `${summary.flat} flat · ${summary.new} new`,\n )\n\n const fmt = (n: number) => n.toFixed(3)\n const noteworthy = diff.cells\n .filter((c) => c.verdict === 'regressed' || c.verdict === 'improved')\n .sort((a, b) => {\n // Regressions first, then by magnitude of delta.\n if (a.verdict !== b.verdict) return a.verdict === 'regressed' ? -1 : 1\n return Math.abs(b.delta ?? 0) - Math.abs(a.delta ?? 0)\n })\n\n for (const cell of noteworthy) {\n const mark = cell.verdict === 'regressed' ? 'REGRESSED' : 'improved'\n const deltaStr =\n cell.delta !== null ? (cell.delta >= 0 ? `+${fmt(cell.delta)}` : fmt(cell.delta)) : '—'\n const stat =\n cell.cohensD !== null\n ? ` (d=${cell.cohensD.toFixed(2)}${cell.pValue !== null ? `, p=${cell.pValue.toFixed(3)}` : ''})`\n : ''\n lines.push(\n ` ${mark} ${cell.scenarioId} · ${cell.model} · ${cell.profileHash.slice(0, 8)} ` +\n `${fmt(cell.baseline ?? 0)} → ${fmt(cell.current)} ${deltaStr}${stat}`,\n )\n }\n\n return lines.join('\\n')\n}\n","/**\n * Series convergence — detects whether a sequence of scalar measurements\n * is stabilizing, drifting, or noisy.\n *\n * Lifted from ADC convergence.ts. The per-turn `ConvergenceTracker` is\n * about progress *within* a single run; this module is about drift\n * *across* runs (e.g. \"are my nightly eval scores stabilizing?\").\n *\n * Three signals:\n * - stabilized: last K values have low variance (< epsilon) — done\n * - drifting: recent trend is monotonic and beyond noise — regressing or improving\n * - noisy: neither — keep iterating, but flag as untrustworthy for gating\n */\n\nexport interface SeriesConvergenceOptions {\n /** Window size for \"recent\" analysis (default 5). */\n window?: number\n /** Coefficient-of-variation threshold below which the window is stabilized (default 0.05 = 5%). */\n stableCv?: number\n /** Minimum monotone run length to call drift (default 3). */\n driftRun?: number\n}\n\nexport interface SeriesConvergenceResult {\n state: 'stabilized' | 'drifting-up' | 'drifting-down' | 'noisy' | 'insufficient-data'\n windowMean: number\n windowCv: number\n /** Longest monotonic run at the tail of the series (positive for up, negative for down). */\n tailRun: number\n /** True when n ≥ window AND windowCv ≤ stableCv. */\n stable: boolean\n}\n\nexport function analyzeSeries(\n values: number[],\n options: SeriesConvergenceOptions = {},\n): SeriesConvergenceResult {\n const window = options.window ?? 5\n const stableCv = options.stableCv ?? 0.05\n const driftRun = options.driftRun ?? 3\n\n if (values.length < Math.max(2, Math.min(window, 3))) {\n return { state: 'insufficient-data', windowMean: 0, windowCv: 0, tailRun: 0, stable: false }\n }\n\n const tail = values.slice(-window)\n const mean = tail.reduce((a, b) => a + b, 0) / tail.length\n const variance = tail.reduce((acc, v) => acc + (v - mean) ** 2, 0) / tail.length\n const stdDev = Math.sqrt(variance)\n const refMean = Math.abs(mean) > 1e-9 ? Math.abs(mean) : 1\n const cv = stdDev / refMean\n const stable = tail.length >= window && cv <= stableCv\n\n // Tail monotonic run: count how many consecutive strictly-increasing (or decreasing)\n // steps end at the final value.\n let tailRun = 0\n let direction: 1 | -1 | 0 = 0\n for (let i = values.length - 1; i > 0; i--) {\n const delta = values[i]! - values[i - 1]!\n if (delta === 0) break\n const dir = delta > 0 ? 1 : -1\n if (direction === 0) direction = dir\n if (dir !== direction) break\n tailRun += dir\n }\n\n let state: SeriesConvergenceResult['state']\n if (stable) {\n state = 'stabilized'\n } else if (Math.abs(tailRun) >= driftRun) {\n state = tailRun > 0 ? 'drifting-up' : 'drifting-down'\n } else {\n state = 'noisy'\n }\n\n return { state, windowMean: mean, windowCv: cv, tailRun, stable }\n}\n","/**\n * SLO gates — quantified pass/fail primitives beyond score thresholds.\n *\n * Lifted from ADC's sandbox eval suite. Each SLO defines a metric, a\n * threshold, and a severity (critical | warning). Critical breaches fail\n * the eval; warnings are reported but don't gate CI. Margin is the\n * ratio of actual to threshold for histogramming \"how close are we?\"\n *\n * Consumers assemble their own SLO arrays; DEFAULT_AGENT_SLOS covers\n * the generic agent flow (provision, first token, pass rate, cost).\n */\n\nexport type SloSeverity = 'critical' | 'warning'\nexport type SloComparator = 'lte' | 'gte'\n\nexport interface Slo {\n /** Stable identifier — must be unique within an SLO set. */\n id: string\n /** Human description, shown in reports. */\n description: string\n /** Metric key looked up in the candidate record. */\n metric: string\n /** Whether the metric should stay below (lte) or above (gte) threshold. */\n comparator: SloComparator\n /** Threshold value. */\n threshold: number\n severity: SloSeverity\n}\n\nexport interface SloCheckResult {\n slo: Slo\n actual: number | undefined\n passed: boolean\n /** actual/threshold for lte, threshold/actual for gte. >1 means safe margin; <1 means breach. 0 when actual is missing. */\n margin: number\n detail: string\n}\n\nexport interface SloReport {\n results: SloCheckResult[]\n passedCritical: boolean\n criticalBreaches: SloCheckResult[]\n warnings: SloCheckResult[]\n}\n\n/**\n * Evaluate an SLO set against a candidate metrics object. Missing metrics\n * count as breaches — if you declared it, you must measure it.\n */\nexport function checkSlos(metrics: Record<string, number>, slos: Slo[]): SloReport {\n const results: SloCheckResult[] = slos.map((slo) => check(slo, metrics[slo.metric]))\n const criticalBreaches = results.filter((r) => !r.passed && r.slo.severity === 'critical')\n const warnings = results.filter((r) => !r.passed && r.slo.severity === 'warning')\n return { results, passedCritical: criticalBreaches.length === 0, criticalBreaches, warnings }\n}\n\nfunction check(slo: Slo, actual: number | undefined): SloCheckResult {\n if (actual === undefined || !Number.isFinite(actual)) {\n return {\n slo,\n actual,\n passed: false,\n margin: 0,\n detail: `metric \"${slo.metric}\" missing — declared SLOs must be measured`,\n }\n }\n if (slo.comparator === 'lte') {\n const passed = actual <= slo.threshold\n const margin = slo.threshold === 0 ? (actual === 0 ? Infinity : 0) : slo.threshold / actual\n return {\n slo,\n actual,\n passed,\n margin,\n detail: `${actual} ≤ ${slo.threshold}: ${passed ? 'ok' : 'breach'}`,\n }\n }\n const passed = actual >= slo.threshold\n const margin = actual === 0 ? 0 : actual / slo.threshold\n return {\n slo,\n actual,\n passed,\n margin,\n detail: `${actual} ≥ ${slo.threshold}: ${passed ? 'ok' : 'breach'}`,\n }\n}\n\n/** Reference SLO set for agent-style evals. Tune per-product by cloning + overriding. */\nexport const DEFAULT_AGENT_SLOS: Slo[] = [\n {\n id: 'provision_ms',\n description: 'Sandbox/session provision under 60s',\n metric: 'provisionMs',\n comparator: 'lte',\n threshold: 60_000,\n severity: 'critical',\n },\n {\n id: 'first_token_ms',\n description: 'First token under 15s',\n metric: 'firstTokenMs',\n comparator: 'lte',\n threshold: 15_000,\n severity: 'critical',\n },\n {\n id: 'pass_rate',\n description: 'Scenario pass rate ≥ 90%',\n metric: 'passRate',\n comparator: 'gte',\n threshold: 0.9,\n severity: 'critical',\n },\n {\n id: 'cost_usd',\n description: 'Per-scenario cost under $0.05',\n metric: 'costUsd',\n comparator: 'lte',\n threshold: 0.05,\n severity: 'warning',\n },\n {\n id: 'overall_score',\n description: 'Overall score ≥ 0.7',\n metric: 'overallScore',\n comparator: 'gte',\n threshold: 0.7,\n severity: 'critical',\n },\n]\n","/**\n * State continuity scoring — measures how well a resumed/handed-off agent\n * preserves prior work.\n *\n * When session 2 continues\n * session 1's work, the key question is: did it preserve key artifacts,\n * or start over and lose context? Each `ContinuityCheck` inspects one\n * aspect (file preserved, key count grew, status advanced) and yields\n * 0-1 credit; the aggregate is the simple mean.\n *\n * Generic over any \"snapshot\" shape — pass your own checks.\n */\n\nexport interface ContinuitySnapshotPair<T> {\n before: T\n after: T\n}\n\nexport interface ContinuityCheck<T> {\n /** Stable identifier; shown in the report. */\n id: string\n /** Description of what this check measures. */\n description: string\n /** Returns 0..1 credit for this dimension (1 = fully preserved/improved). */\n score: (pair: ContinuitySnapshotPair<T>) => number\n}\n\nexport interface ContinuityCheckResult {\n id: string\n description: string\n score: number\n pass: boolean\n}\n\nexport interface ContinuityReport {\n results: ContinuityCheckResult[]\n /** Mean of per-check scores, in 0..1. */\n overallScore: number\n /** True iff ALL checks scored ≥ passThreshold. */\n pass: boolean\n}\n\nexport function scoreContinuity<T>(\n pair: ContinuitySnapshotPair<T>,\n checks: ContinuityCheck<T>[],\n options: { passThreshold?: number } = {},\n): ContinuityReport {\n if (checks.length === 0) {\n throw new Error('scoreContinuity: at least 1 check required')\n }\n const passThreshold = options.passThreshold ?? 0.8\n const results: ContinuityCheckResult[] = checks.map((c) => {\n const raw = c.score(pair)\n const clamped = Number.isFinite(raw) ? Math.max(0, Math.min(1, raw)) : 0\n return { id: c.id, description: c.description, score: clamped, pass: clamped >= passThreshold }\n })\n const overallScore = results.reduce((a, r) => a + r.score, 0) / results.length\n return { results, overallScore, pass: results.every((r) => r.pass) }\n}\n\n/** Common check: a required key in a record exists and equals the prior value. */\nexport function keyPreserved<T extends Record<string, unknown>>(\n key: keyof T & string,\n): ContinuityCheck<T> {\n return {\n id: `preserved(${key})`,\n description: `\"${key}\" unchanged from before to after`,\n score: ({ before, after }) => (before[key] !== undefined && before[key] === after[key] ? 1 : 0),\n }\n}\n\n/** Common check: a collection (array) grew or stayed the same size. */\nexport function collectionPreserved<T, K extends keyof T & string>(\n key: K,\n minRatio = 1,\n): ContinuityCheck<T> {\n return {\n id: `collection-preserved(${key})`,\n description: `\"${key}\" length ≥ ${minRatio} × prior length`,\n score: ({ before, after }) => {\n const b = before[key]\n const a = after[key]\n if (!Array.isArray(b) || !Array.isArray(a)) return 0\n if (b.length === 0) return a.length === 0 ? 1 : 1\n return Math.min(1, a.length / (b.length * minRatio))\n },\n }\n}\n\n/** Common check: a status field advanced in an expected order. */\nexport function statusAdvanced<T extends Record<string, unknown>>(\n key: keyof T & string,\n progression: readonly string[],\n): ContinuityCheck<T> {\n return {\n id: `status-advanced(${key})`,\n description: `\"${key}\" progressed along ${progression.join('→')}`,\n score: ({ before, after }) => {\n const bi = progression.indexOf(String(before[key]))\n const ai = progression.indexOf(String(after[key]))\n if (bi === -1 || ai === -1) return 0\n return ai >= bi ? 1 : 0\n },\n }\n}\n","/**\n * Behavior DSL — pytest-style assertions over a run's trajectory.\n *\n * Shape:\n * expect(store, runId).toCall('search').withArgs({ q: /.+/ })\n * expect(store, runId).toRefuse()\n * expect(store, runId).toOutputMatch(/confirmed/i)\n * expect(store, runId).toRespectBudget('tokens')\n * expect(store, runId).toCompleteWithin({ wallMs: 30_000 })\n *\n * Each matcher returns an `Expectation` with `.check() → MatcherResult`\n * so the DSL is composable with suite runners — you can collect all\n * expectations into a report instead of throwing on first failure.\n */\n\nimport { llmSpans, toolSpans } from './trace/query'\nimport type { BudgetLedgerEntry, Span, ToolSpan } from './trace/schema'\nimport type { TraceStore } from './trace/store'\n\nexport interface MatcherResult {\n ok: boolean\n detail: string\n evidence?: string\n}\n\nexport interface Expectation {\n /** Human-facing label; used in reports. */\n label: string\n check(): Promise<MatcherResult>\n}\n\nexport class BehaviorAssertion {\n constructor(\n private store: TraceStore,\n private runId: string,\n ) {}\n\n toCall(toolName: string): CallExpectation {\n return new CallExpectation(this.store, this.runId, toolName)\n }\n\n toRefuse(markers: RegExp[] = DEFAULT_REFUSAL_MARKERS): Expectation {\n return {\n label: `agent(${this.runId}).toRefuse()`,\n check: async () => {\n const spans = await llmSpans(this.store, this.runId)\n const output = spans.map((s) => s.output ?? '').join('\\n')\n const hit = markers.some((re) => re.test(output))\n return hit\n ? { ok: true, detail: 'refusal marker detected' }\n : {\n ok: false,\n detail: 'no refusal marker in agent output',\n evidence: output.slice(0, 200),\n }\n },\n }\n }\n\n toOutputMatch(pattern: RegExp): Expectation {\n return {\n label: `agent(${this.runId}).toOutputMatch(${pattern.source})`,\n check: async () => {\n const spans = await llmSpans(this.store, this.runId)\n const output = spans.map((s) => s.output ?? '').join('\\n')\n const m = output.match(pattern)\n return m\n ? { ok: true, detail: `matched \"${m[0]}\"`, evidence: m[0] }\n : { ok: false, detail: 'pattern not matched', evidence: output.slice(0, 200) }\n },\n }\n }\n\n toRespectBudget(\n dimension: keyof BudgetLedgerEntry['dimension'] | 'tokens' | 'wallMs' | 'calls' | 'usd',\n ): Expectation {\n return {\n label: `agent(${this.runId}).toRespectBudget(${String(dimension)})`,\n check: async () => {\n const entries = await this.store.budget(this.runId)\n const breached = entries.some((e) => e.dimension === dimension && e.breached)\n return breached\n ? { ok: false, detail: `budget \"${String(dimension)}\" breached` }\n : { ok: true, detail: `no breach on \"${String(dimension)}\"` }\n },\n }\n }\n\n toCompleteWithin(limits: {\n wallMs?: number\n toolCalls?: number\n llmTurns?: number\n }): Expectation {\n return {\n label: `agent(${this.runId}).toCompleteWithin(${JSON.stringify(limits)})`,\n check: async () => {\n const run = await this.store.getRun(this.runId)\n if (!run?.endedAt) return { ok: false, detail: 'run has not completed' }\n const wallMs = run.endedAt - run.startedAt\n const tool = (await toolSpans(this.store, this.runId)).length\n const llm = (await llmSpans(this.store, this.runId)).length\n const violations: string[] = []\n if (limits.wallMs !== undefined && wallMs > limits.wallMs)\n violations.push(`wallMs ${wallMs} > ${limits.wallMs}`)\n if (limits.toolCalls !== undefined && tool > limits.toolCalls)\n violations.push(`toolCalls ${tool} > ${limits.toolCalls}`)\n if (limits.llmTurns !== undefined && llm > limits.llmTurns)\n violations.push(`llmTurns ${llm} > ${limits.llmTurns}`)\n return violations.length === 0\n ? { ok: true, detail: `within limits (${wallMs}ms, ${tool} tools, ${llm} turns)` }\n : { ok: false, detail: violations.join('; ') }\n },\n }\n }\n\n toNeverCall(toolName: string): Expectation {\n return {\n label: `agent(${this.runId}).toNeverCall(${toolName})`,\n check: async () => {\n const calls = await toolSpans(this.store, this.runId, toolName)\n return calls.length === 0\n ? { ok: true, detail: `tool \"${toolName}\" not invoked` }\n : {\n ok: false,\n detail: `tool \"${toolName}\" called ${calls.length}x`,\n evidence: calls[0]!.spanId,\n }\n },\n }\n }\n}\n\nexport class CallExpectation implements Expectation {\n private argMatchers: Array<(args: unknown) => boolean> = []\n private minCount = 1\n private maxCount = Infinity\n\n constructor(\n private store: TraceStore,\n private runId: string,\n private toolName: string,\n ) {}\n\n get label(): string {\n return `agent(${this.runId}).toCall(${this.toolName})`\n }\n\n withArgs(shape: Record<string, unknown | RegExp>): this {\n this.argMatchers.push((args) => matchArgs(args, shape))\n return this\n }\n\n times(n: number): this {\n this.minCount = n\n this.maxCount = n\n return this\n }\n\n atLeast(n: number): this {\n this.minCount = n\n return this\n }\n\n atMost(n: number): this {\n this.maxCount = n\n return this\n }\n\n async check(): Promise<MatcherResult> {\n const calls = await toolSpans(this.store, this.runId, this.toolName)\n const matching = calls.filter((c) => this.argMatchers.every((fn) => fn(c.args)))\n const count = matching.length\n if (count < this.minCount)\n return {\n ok: false,\n detail: `expected ≥ ${this.minCount} matching \"${this.toolName}\" calls, got ${count}`,\n }\n if (count > this.maxCount)\n return {\n ok: false,\n detail: `expected ≤ ${this.maxCount} matching \"${this.toolName}\" calls, got ${count}`,\n }\n return { ok: true, detail: `${count} matching \"${this.toolName}\" call(s)` }\n }\n}\n\nexport function expectAgent(store: TraceStore, runId: string): BehaviorAssertion {\n return new BehaviorAssertion(store, runId)\n}\n\n/** Runs every expectation, collects results. Never throws. */\nexport async function runExpectations(expectations: Expectation[]): Promise<{\n results: Array<{ label: string; result: MatcherResult }>\n pass: boolean\n passCount: number\n failCount: number\n}> {\n const results = await Promise.all(\n expectations.map(async (e) => ({ label: e.label, result: await e.check() })),\n )\n const passCount = results.filter((r) => r.result.ok).length\n return {\n results,\n pass: passCount === results.length,\n passCount,\n failCount: results.length - passCount,\n }\n}\n\nconst DEFAULT_REFUSAL_MARKERS = [\n /\\b(?:i\\s+(?:can(?:not|'t)|won't|will\\s+not|am\\s+unable|refuse))\\b/i,\n /\\b(?:sorry,?\\s+(?:but\\s+)?i\\s+(?:can't|cannot))/i,\n /\\bthat\\s+(?:would\\s+)?(?:violate|be\\s+against)\\b/i,\n /\\bunable\\s+to\\s+(?:help|assist|comply)\\b/i,\n]\n\nfunction matchArgs(args: unknown, shape: Record<string, unknown | RegExp>): boolean {\n if (args === null || typeof args !== 'object') return false\n const record = args as Record<string, unknown>\n for (const [k, expected] of Object.entries(shape)) {\n const actual = record[k]\n if (expected instanceof RegExp) {\n if (typeof actual !== 'string' || !expected.test(actual)) return false\n } else if (actual !== expected) {\n return false\n }\n }\n return true\n}\n\n// Guard against accidental Span import elision during build-time DTS generation.\nexport type { Span, ToolSpan }\n","/**\n * CI gate — evaluate a corpus against threshold contracts and generate\n * a human-readable PR/build comment.\n *\n * Three layers:\n * 1. `ThresholdContract` declarations (YAML-equivalent TS objects)\n * 2. `evaluateContract` runs the contracts against a TraceStore and\n * returns a structured report + overall pass/fail.\n * 3. `renderMarkdownReport` formats the report for GitHub PR comments.\n *\n * Consumers wrap this in their own `gh pr comment` / CI integration —\n * we don't ship the GitHub Action binary, just the library call that\n * the action invokes.\n */\n\nimport type { BaselineReport } from './baseline'\nimport { compareToBaseline, type MetricSamples } from './baseline'\nimport { checkSlos, type Slo, type SloReport } from './slo'\nimport { aggregateLlm, llmSpans, runFailureClass } from './trace/query'\nimport type { Run } from './trace/schema'\nimport type { RunFilter, TraceStore } from './trace/store'\n\nexport interface ContractMetric {\n /** Metric id matching either a predefined key or a custom extractor. */\n metric: string\n higherIsBetter: boolean\n /** Max tolerated regression (e.g. 0.02 = 2pp worse than baseline). */\n maxRegression?: number\n /** Optional extractor if the metric isn't in the default set. */\n extract?: (run: Run, store: TraceStore) => Promise<number | null>\n}\n\nexport interface ThresholdContract {\n name: string\n baseline: RunFilter\n candidate: RunFilter\n metrics: ContractMetric[]\n slos?: Slo[]\n}\n\nexport interface ContractReport {\n name: string\n baselineReport: BaselineReport\n sloReport?: SloReport\n breaches: string[]\n pass: boolean\n}\n\nexport async function evaluateContract(\n store: TraceStore,\n contract: ThresholdContract,\n): Promise<ContractReport> {\n const baselineRuns = await store.listRuns(contract.baseline)\n const candidateRuns = await store.listRuns(contract.candidate)\n if (candidateRuns.length === 0) {\n return {\n name: contract.name,\n baselineReport: { metrics: [], hasRegression: false, hasUnstable: true },\n breaches: ['no candidate runs matched'],\n pass: false,\n }\n }\n\n const samples: MetricSamples[] = []\n for (const m of contract.metrics) {\n const extract = m.extract ?? defaultExtract(m.metric)\n const baseline = await extractAll(baselineRuns, extract, store)\n const candidate = await extractAll(candidateRuns, extract, store)\n if (baseline.length < 2 || candidate.length < 2) continue\n samples.push({ metric: m.metric, higherIsBetter: m.higherIsBetter, baseline, candidate })\n }\n\n const baselineReport =\n samples.length >= 1\n ? compareToBaseline(samples)\n : { metrics: [], hasRegression: false, hasUnstable: samples.length === 0 }\n\n // SLO evaluation against candidate-side aggregate metrics\n let sloReport: SloReport | undefined\n if (contract.slos && contract.slos.length > 0) {\n const agg = await aggregateRunMetrics(candidateRuns, store)\n sloReport = checkSlos(agg, contract.slos)\n }\n\n const breaches: string[] = []\n for (const metric of baselineReport.metrics) {\n const decl = contract.metrics.find((m) => m.metric === metric.metric)\n if (!decl) continue\n if (metric.verdict === 'regressed') {\n const magnitude = Math.abs(metric.delta)\n if (decl.maxRegression === undefined || magnitude > decl.maxRegression) {\n breaches.push(\n `metric \"${metric.metric}\" regressed by ${metric.delta.toFixed(4)} (d=${metric.cohensD.toFixed(2)}, p=${metric.welchP.toExponential(2)})`,\n )\n }\n }\n }\n if (sloReport) {\n for (const r of sloReport.criticalBreaches) {\n breaches.push(`SLO \"${r.slo.id}\" breached: ${r.detail}`)\n }\n }\n\n return { name: contract.name, baselineReport, sloReport, breaches, pass: breaches.length === 0 }\n}\n\nexport function renderMarkdownReport(reports: ContractReport[]): string {\n const lines: string[] = []\n const overall = reports.every((r) => r.pass)\n lines.push(overall ? '## ✅ agent-eval gate: pass' : '## ❌ agent-eval gate: fail')\n lines.push('')\n for (const r of reports) {\n lines.push(`### ${r.name} ${r.pass ? '✅' : '❌'}`)\n if (r.breaches.length > 0) {\n lines.push('')\n lines.push('**Breaches:**')\n for (const b of r.breaches) lines.push(`- ${b}`)\n }\n if (r.baselineReport.metrics.length > 0) {\n lines.push('')\n lines.push('| metric | baseline | candidate | Δ | Cohen d | p | verdict |')\n lines.push('|---|---|---|---|---|---|---|')\n for (const m of r.baselineReport.metrics) {\n lines.push(\n `| ${m.metric} | ${m.baselineMean.toFixed(4)} | ${m.candidateMean.toFixed(4)} | ${m.delta.toFixed(4)} | ${m.cohensD.toFixed(2)} | ${m.welchP.toExponential(2)} | ${m.verdict} |`,\n )\n }\n }\n if (r.sloReport && r.sloReport.results.length > 0) {\n lines.push('')\n lines.push('**SLO results:**')\n for (const s of r.sloReport.results) {\n lines.push(`- ${s.slo.id} (${s.slo.severity}): ${s.passed ? 'ok' : 'breach'} — ${s.detail}`)\n }\n }\n lines.push('')\n }\n return lines.join('\\n')\n}\n\n/** Aggregate per-run metrics into the single record expected by `checkSlos`. */\nasync function aggregateRunMetrics(\n runs: Run[],\n store: TraceStore,\n): Promise<Record<string, number>> {\n if (runs.length === 0) return {}\n const durations: number[] = []\n const scores: number[] = []\n const passes: number[] = []\n const costs: number[] = []\n for (const r of runs) {\n if (r.endedAt) durations.push(r.endedAt - r.startedAt)\n if (r.outcome?.score !== undefined) scores.push(r.outcome.score)\n passes.push(r.outcome?.pass === true ? 1 : 0)\n const llm = await llmSpans(store, r.runId)\n costs.push(aggregateLlm(llm).costUsd)\n }\n return {\n provisionMs: average(durations),\n firstTokenMs: average(durations),\n wallMs: average(durations),\n overallScore: average(scores),\n passRate: average(passes),\n costUsd: average(costs),\n }\n}\n\nfunction average(xs: number[]): number {\n if (xs.length === 0) return 0\n return xs.reduce((a, b) => a + b, 0) / xs.length\n}\n\nasync function extractAll(\n runs: Run[],\n extract: (r: Run, s: TraceStore) => Promise<number | null>,\n store: TraceStore,\n): Promise<number[]> {\n const out: number[] = []\n for (const r of runs) {\n const v = await extract(r, store)\n if (v !== null && Number.isFinite(v)) out.push(v)\n }\n return out\n}\n\nfunction defaultExtract(metric: string): (run: Run, store: TraceStore) => Promise<number | null> {\n return async (run, store) => {\n switch (metric) {\n case 'score':\n case 'overallScore':\n return run.outcome?.score ?? null\n case 'pass':\n return run.outcome?.pass === true ? 1 : 0\n case 'durationMs':\n return run.endedAt && run.startedAt ? run.endedAt - run.startedAt : null\n case 'costUsd': {\n const llm = await llmSpans(store, run.runId)\n return aggregateLlm(llm).costUsd\n }\n case 'successClass':\n return runFailureClass(run) === 'success' ? 1 : 0\n default:\n return null\n }\n }\n}\n","/**\n * Observability adapters — bidirectional parity with production backends.\n *\n * `LangfuseAdapter` maps a Run's spans into Langfuse generation/score\n * records (schema-compatible; we don't depend on the SDK — consumers\n * POST the returned JSON to their Langfuse collector).\n *\n * `PrometheusEmitter` converts a TraceStore into a Prometheus text-\n * exposition-format string (counters + gauges for runs, tool calls,\n * errors, cost). Drop into a `/metrics` handler; no SDK needed.\n *\n * `replayTraceThroughJudge` is the canonical \"re-score with a new\n * judge\" path — takes an existing run, runs a judge function over\n * each LLM span, emits JudgeVerdict spans back into the store.\n */\n\nimport { NotFoundError } from './errors'\nimport { TraceEmitter } from './trace/emitter'\nimport { aggregateLlm, llmSpans } from './trace/query'\nimport type { LlmSpan, Span } from './trace/schema'\nimport type { TraceStore } from './trace/store'\n\n// ── Langfuse adapter ─────────────────────────────────────────────────\n\nexport interface LangfuseGeneration {\n id: string\n traceId: string\n name: string\n model: string\n input: unknown\n output: unknown\n startTime: string\n endTime: string\n usage: { input: number; output: number; total: number; totalCost: number }\n metadata: Record<string, unknown>\n}\n\nexport interface LangfuseScore {\n id: string\n traceId: string\n observationId: string\n name: string\n value: number\n comment?: string\n}\n\nexport interface LangfuseEnvelope {\n traceId: string\n generations: LangfuseGeneration[]\n scores: LangfuseScore[]\n}\n\nexport async function toLangfuseEnvelope(\n store: TraceStore,\n runId: string,\n): Promise<LangfuseEnvelope> {\n const run = await store.getRun(runId)\n if (!run) throw new NotFoundError(`run ${runId} not found`)\n const llm = await llmSpans(store, runId)\n const allSpans = await store.spans({ runId })\n const judges = allSpans.filter((s): s is Extract<Span, { kind: 'judge' }> => s.kind === 'judge')\n\n const generations: LangfuseGeneration[] = llm.map((s) => ({\n id: s.spanId,\n traceId: run.runId,\n name: s.name,\n model: s.model,\n input: s.messages,\n output: s.output,\n startTime: new Date(s.startedAt).toISOString(),\n endTime: new Date(s.endedAt ?? s.startedAt).toISOString(),\n usage: {\n input: s.inputTokens ?? 0,\n output: s.outputTokens ?? 0,\n total: (s.inputTokens ?? 0) + (s.outputTokens ?? 0),\n totalCost: s.costUsd ?? 0,\n },\n metadata: { finishReason: s.finishReason, cachedTokens: s.cachedTokens },\n }))\n\n const scores: LangfuseScore[] = judges.map((j) => ({\n id: j.spanId,\n traceId: run.runId,\n observationId: j.targetSpanId,\n name: `${j.judgeId}/${j.dimension}`,\n value: j.score,\n comment: j.rationale,\n }))\n\n return { traceId: run.runId, generations, scores }\n}\n\n// ── Prometheus emitter ───────────────────────────────────────────────\n\nexport async function toPrometheusText(store: TraceStore): Promise<string> {\n const runs = await store.listRuns()\n const toolCalls: Record<string, number> = {}\n const toolErrors: Record<string, number> = {}\n let totalLlmInputTokens = 0\n let totalLlmOutputTokens = 0\n let totalCostUsd = 0\n let passedRuns = 0\n let failedRuns = 0\n for (const r of runs) {\n if (r.outcome?.pass === true) passedRuns++\n else if (r.outcome?.pass === false) failedRuns++\n const llm = await llmSpans(store, r.runId)\n const agg = aggregateLlm(llm)\n totalLlmInputTokens += agg.inputTokens\n totalLlmOutputTokens += agg.outputTokens\n totalCostUsd += agg.costUsd\n const tools = await store.spans({ runId: r.runId, kind: 'tool' })\n for (const t of tools) {\n if (t.kind !== 'tool') continue\n toolCalls[t.toolName] = (toolCalls[t.toolName] ?? 0) + 1\n if (t.status === 'error') toolErrors[t.toolName] = (toolErrors[t.toolName] ?? 0) + 1\n }\n }\n\n const lines: string[] = []\n lines.push('# HELP agent_eval_runs_total Total runs in the trace corpus')\n lines.push('# TYPE agent_eval_runs_total counter')\n lines.push(`agent_eval_runs_total ${runs.length}`)\n lines.push('# HELP agent_eval_runs_passed_total Runs that completed with pass=true')\n lines.push('# TYPE agent_eval_runs_passed_total counter')\n lines.push(`agent_eval_runs_passed_total ${passedRuns}`)\n lines.push('# HELP agent_eval_runs_failed_total Runs that completed with pass=false')\n lines.push('# TYPE agent_eval_runs_failed_total counter')\n lines.push(`agent_eval_runs_failed_total ${failedRuns}`)\n lines.push('# HELP agent_eval_llm_input_tokens_total Aggregate LLM input tokens')\n lines.push('# TYPE agent_eval_llm_input_tokens_total counter')\n lines.push(`agent_eval_llm_input_tokens_total ${totalLlmInputTokens}`)\n lines.push('# HELP agent_eval_llm_output_tokens_total Aggregate LLM output tokens')\n lines.push('# TYPE agent_eval_llm_output_tokens_total counter')\n lines.push(`agent_eval_llm_output_tokens_total ${totalLlmOutputTokens}`)\n lines.push('# HELP agent_eval_cost_usd_total Aggregate LLM cost in USD')\n lines.push('# TYPE agent_eval_cost_usd_total counter')\n lines.push(`agent_eval_cost_usd_total ${totalCostUsd}`)\n lines.push('# HELP agent_eval_tool_calls_total Tool calls by tool name')\n lines.push('# TYPE agent_eval_tool_calls_total counter')\n for (const [name, n] of Object.entries(toolCalls)) {\n lines.push(`agent_eval_tool_calls_total{tool=\"${escapeLabel(name)}\"} ${n}`)\n }\n lines.push('# HELP agent_eval_tool_errors_total Tool errors by tool name')\n lines.push('# TYPE agent_eval_tool_errors_total counter')\n for (const [name, n] of Object.entries(toolErrors)) {\n lines.push(`agent_eval_tool_errors_total{tool=\"${escapeLabel(name)}\"} ${n}`)\n }\n return `${lines.join('\\n')}\\n`\n}\n\nfunction escapeLabel(v: string): string {\n return v.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"').replace(/\\n/g, '\\\\n')\n}\n\n// ── Retroactive re-scoring via judge replay ──────────────────────────\n\nexport interface JudgeReplayResult {\n spanId: string\n targetSpanId: string\n dimension: string\n score: number\n rationale?: string\n}\n\n/**\n * Apply a judge function to every LLM span in a run and record the\n * results as JudgeVerdict spans. This is the canonical \"no re-execution\"\n * re-scoring path — you supply a pure judge `(llmSpan) → verdict`.\n */\nexport async function replayTraceThroughJudge(\n store: TraceStore,\n runId: string,\n judge: {\n id: string\n dimension: string\n score: (span: LlmSpan) => Promise<{ score: number; rationale?: string; evidence?: string }>\n },\n): Promise<JudgeReplayResult[]> {\n const run = await store.getRun(runId)\n if (!run) throw new NotFoundError(`run ${runId} not found`)\n const llms = await llmSpans(store, runId)\n const emitter = new TraceEmitter(store, { runId })\n const results: JudgeReplayResult[] = []\n for (const span of llms) {\n const { score, rationale, evidence } = await judge.score(span)\n const verdict = await emitter.recordJudge({\n judgeId: judge.id,\n targetSpanId: span.spanId,\n dimension: judge.dimension,\n score,\n rationale,\n evidence,\n name: `${judge.id}/${judge.dimension}`,\n })\n results.push({\n spanId: verdict.spanId,\n targetSpanId: span.spanId,\n dimension: judge.dimension,\n score,\n rationale,\n })\n }\n return results\n}\n","/**\n * Paraphrase robustness — mutates a scenario prompt in structure-\n * preserving ways, re-scores, and reports score variance.\n *\n * Mutators are pure functions `(prompt: string) => string`. Ship a\n * default set; consumers add domain-specific ones.\n *\n * Robustness score: 1 - stdDev(scores) / (mean if positive else 1).\n * A perfect agent returns the same answer regardless of typo / case /\n * reordering — any variance signals a brittle prompt.\n */\n\nexport type Mutator = (prompt: string, seed: number) => string\n\nexport interface RobustnessResult {\n originalScore: number\n variantScores: Array<{ mutator: string; score: number; mutated: string }>\n meanScore: number\n stdDev: number\n robustness: number\n}\n\nexport async function paraphraseRobustness(\n prompt: string,\n mutators: Array<{ id: string; fn: Mutator }>,\n scoreFn: (prompt: string) => Promise<number>,\n options: { seed?: number } = {},\n): Promise<RobustnessResult> {\n const seed = options.seed ?? 1\n const originalScore = await scoreFn(prompt)\n const variantScores: RobustnessResult['variantScores'] = []\n const all: number[] = [originalScore]\n for (const { id, fn } of mutators) {\n const mutated = fn(prompt, seed)\n const score = await scoreFn(mutated)\n variantScores.push({ mutator: id, score, mutated })\n all.push(score)\n }\n const mean = all.reduce((a, b) => a + b, 0) / all.length\n const variance = all.reduce((a, v) => a + (v - mean) ** 2, 0) / all.length\n const stdDev = Math.sqrt(variance)\n const ref = Math.abs(mean) > 1e-9 ? Math.abs(mean) : 1\n const robustness = Math.max(0, 1 - stdDev / ref)\n return { originalScore, variantScores, meanScore: mean, stdDev, robustness }\n}\n\n// ── Built-in mutators ────────────────────────────────────────────────\n\n/** Lowercase the whole prompt. Robust models ignore case. */\nexport const lowercaseMutator: Mutator = (p) => p.toLowerCase()\n\n/** Reorder sentences. Robust models don't depend on sentence order. */\nexport const sentenceReorderMutator: Mutator = (p, seed) => {\n const sentences = p.split(/(?<=[.!?])\\s+/).filter(Boolean)\n if (sentences.length <= 1) return p\n const shuffled = [...sentences]\n let s = seed >>> 0\n for (let i = shuffled.length - 1; i > 0; i--) {\n s = (s * 1103515245 + 12345) >>> 0\n const j = s % (i + 1)\n ;[shuffled[i], shuffled[j]] = [shuffled[j]!, shuffled[i]!]\n }\n return shuffled.join(' ')\n}\n\n/** Swap adjacent letter pairs (1 per 40 chars, min 1). Robust models tolerate typos. */\nexport const typoMutator: Mutator = (p, seed) => {\n if (p.length < 5) return p\n const chars = p.split('')\n let s = seed >>> 0\n const count = Math.max(1, Math.floor(chars.length / 40))\n for (let n = 0; n < count; n++) {\n for (let attempt = 0; attempt < 20; attempt++) {\n s = (s * 1103515245 + 12345) >>> 0\n const idx = s % (chars.length - 1)\n const a = chars[idx]!\n const b = chars[idx + 1]!\n if (a !== b && /[A-Za-z]/.test(a) && /[A-Za-z]/.test(b)) {\n chars[idx] = b\n chars[idx + 1] = a\n break\n }\n }\n }\n return chars.join('')\n}\n\n/** Add a benign politeness prefix. Robust models ignore flattery. */\nexport const politenessPrefixMutator: Mutator = (p) => `Please, if you would be so kind: ${p}`\n\n/** Compact whitespace, strip newlines. Robust models don't depend on formatting. */\nexport const whitespaceCollapseMutator: Mutator = (p) => p.replace(/\\s+/g, ' ').trim()\n\nexport const DEFAULT_MUTATORS: Array<{ id: string; fn: Mutator }> = [\n { id: 'lowercase', fn: lowercaseMutator },\n { id: 'sentence-reorder', fn: sentenceReorderMutator },\n { id: 'typo', fn: typoMutator },\n { id: 'politeness-prefix', fn: politenessPrefixMutator },\n { id: 'whitespace-collapse', fn: whitespaceCollapseMutator },\n]\n\n// ── Multi-turn scenario convenience wrapper ──────────────────────────\n\nexport interface ParaphraseRobustnessScenarioInput {\n scenarios: Array<{ id: string; userTurns: string[] }>\n /**\n * Mutators applied to every user turn in every scenario. Each\n * scenario is paraphrased once per mutator (so `reps` × `scenarios`\n * × `mutators` total paraphrased runs).\n */\n mutators: Array<{ name: string; mutator: (text: string) => string }>\n /**\n * Run a (possibly mutated) scenario and return its score in [0,1].\n * Called once for the original turns of each scenario, and once per\n * (scenario × mutator × rep) for the paraphrased variants.\n */\n runScenario: (args: { id: string; userTurns: string[] }) => Promise<{ score: number }>\n /** Times to repeat each (scenario × mutator) pair. Default 1. */\n reps?: number\n}\n\nexport interface ParaphraseRobustnessScenarioResult {\n /**\n * Aggregate robustness: `mean(paraphrased) / mean(original)`,\n * clipped to `[0, 1]`. `1` = paraphrasing didn't degrade the agent;\n * `0` = paraphrasing destroyed it (or original was 0).\n */\n score: number\n perScenario: Array<{\n id: string\n originalScore: number\n paraphrasedMean: number\n /** Per-mutator delta (paraphrased − original); negative = mutator hurt. */\n deltas: Record<string, number>\n }>\n mutators: string[]\n}\n\n/**\n * Multi-turn convenience wrapper around {@link paraphraseRobustness}.\n *\n * Consumers with a list of multi-turn scenarios were hand-wrapping the\n * single-prompt runner per scenario; this iterates for them. Mutators\n * are applied to every user turn (mutator runs once per turn with a\n * stable seed derived from the rep index).\n *\n * Contract:\n * - Calls `runScenario` once with the original `userTurns` to\n * establish the baseline `originalScore`.\n * - For each `(scenario, mutator, rep)` combination, builds a\n * mutated copy of `userTurns` (every turn passed through\n * `mutator.mutator`) and calls `runScenario` again.\n * - Aggregates per-scenario means, then computes the overall\n * `mean(paraphrasedMean) / mean(originalScore)`, clipped to\n * `[0, 1]`. If every original score is 0 the aggregate is 0.\n */\nexport async function paraphraseRobustnessScenarios(\n args: ParaphraseRobustnessScenarioInput,\n): Promise<ParaphraseRobustnessScenarioResult> {\n const reps = Math.max(1, args.reps ?? 1)\n const mutatorNames = args.mutators.map((m) => m.name)\n\n const perScenario: ParaphraseRobustnessScenarioResult['perScenario'] = []\n\n for (const scenario of args.scenarios) {\n const baseline = await args.runScenario({\n id: scenario.id,\n userTurns: scenario.userTurns,\n })\n const originalScore = baseline.score\n\n const deltas: Record<string, number> = {}\n const paraphrasedAll: number[] = []\n\n for (const m of args.mutators) {\n const scores: number[] = []\n for (let r = 0; r < reps; r++) {\n const mutatedTurns = scenario.userTurns.map((t) => m.mutator(t))\n const out = await args.runScenario({\n id: scenario.id,\n userTurns: mutatedTurns,\n })\n scores.push(out.score)\n }\n const mean = scores.reduce((a, b) => a + b, 0) / scores.length\n deltas[m.name] = mean - originalScore\n paraphrasedAll.push(...scores)\n }\n\n const paraphrasedMean =\n paraphrasedAll.length === 0\n ? originalScore\n : paraphrasedAll.reduce((a, b) => a + b, 0) / paraphrasedAll.length\n\n perScenario.push({ id: scenario.id, originalScore, paraphrasedMean, deltas })\n }\n\n const meanOriginal =\n perScenario.length === 0\n ? 0\n : perScenario.reduce((a, p) => a + p.originalScore, 0) / perScenario.length\n const meanParaphrased =\n perScenario.length === 0\n ? 0\n : perScenario.reduce((a, p) => a + p.paraphrasedMean, 0) / perScenario.length\n\n const ratio = meanOriginal <= 0 ? 0 : meanParaphrased / meanOriginal\n const score = Math.max(0, Math.min(1, ratio))\n\n return { score, perScenario, mutators: mutatorNames }\n}\n","/**\n * Visual diff — pixel-delta scoring for UI / visual outputs.\n *\n * Minimal dependency-free implementation: accepts two PNGs as byte\n * arrays + width/height and returns a Δ ratio + per-channel histogram.\n * Consumers supply the decoded pixel arrays (we don't pull a PNG\n * decoder into the core — use `sharp`, `@napi-rs/canvas`, or Playwright\n * in the driving test and pass the result here).\n */\n\nimport { ValidationError } from './errors'\n\nexport interface ImageData {\n width: number\n height: number\n /** Pixel data in RGBA order, 4 bytes per pixel. */\n data: Uint8Array | Uint8ClampedArray\n}\n\nexport interface VisualDiffResult {\n /** Ratio of pixels differing beyond `tolerance` (0..1). */\n diffRatio: number\n differingPixels: number\n totalPixels: number\n maxChannelDelta: number\n /** Status for dashboards: unchanged (< 0.1%), changed, or severely-changed (> 5%). */\n status: 'unchanged' | 'changed' | 'severely-changed'\n}\n\nexport interface VisualDiffOptions {\n /** Pixels whose max-channel delta is ≤ this are considered unchanged. Default 8/255. */\n tolerance?: number\n}\n\nexport function visualDiff(\n a: ImageData,\n b: ImageData,\n options: VisualDiffOptions = {},\n): VisualDiffResult {\n if (a.width !== b.width || a.height !== b.height) {\n throw new ValidationError(\n `visualDiff: image dims differ (${a.width}x${a.height} vs ${b.width}x${b.height})`,\n )\n }\n if (a.data.length !== b.data.length) {\n throw new ValidationError('visualDiff: image data length mismatch')\n }\n const tolerance = options.tolerance ?? 8\n const totalPixels = a.width * a.height\n let differing = 0\n let maxDelta = 0\n for (let i = 0; i < a.data.length; i += 4) {\n const dr = Math.abs(a.data[i]! - b.data[i]!)\n const dg = Math.abs(a.data[i + 1]! - b.data[i + 1]!)\n const db = Math.abs(a.data[i + 2]! - b.data[i + 2]!)\n const da = Math.abs(a.data[i + 3]! - b.data[i + 3]!)\n const worst = Math.max(dr, dg, db, da)\n if (worst > maxDelta) maxDelta = worst\n if (worst > tolerance) differing++\n }\n const diffRatio = totalPixels > 0 ? differing / totalPixels : 0\n const status = diffRatio < 0.001 ? 'unchanged' : diffRatio > 0.05 ? 'severely-changed' : 'changed'\n return { diffRatio, differingPixels: differing, totalPixels, maxChannelDelta: maxDelta, status }\n}\n\n/** Convenience: diffs two byte-identical-dim RGBA arrays, returns just the ratio. */\nexport function pixelDeltaRatio(\n a: Uint8Array,\n b: Uint8Array,\n width: number,\n height: number,\n tolerance = 8,\n): number {\n return visualDiff({ width, height, data: a }, { width, height, data: b }, { tolerance }).diffRatio\n}\n","/**\n * Bisector — auto-locate the change that introduced an eval regression.\n *\n * Two shapes:\n * - `commitBisect` — walk an ordered SHA list, binary-search for the\n * first commit that fails.\n * - `promptBisect` — given a good and bad prompt, progressively port\n * paragraphs from good→bad to localize the breaking change.\n *\n * Generic `bisect<T>` lets callers drive any ordered state space\n * (dataset versions, config files, CLI flag combinations).\n */\n\nexport interface BisectOptions<T> {\n /** State known to pass. */\n good: T\n /** State known to fail. */\n bad: T\n /** Equality test on state values — default Object.is. */\n equals?: (a: T, b: T) => boolean\n /** Pick the halfway state between good + bad. Return null when no further\n * split is possible (e.g. adjacent commits). */\n halfway: (good: T, bad: T) => T | null\n /** Produce a verdict for a state. */\n runEval: (state: T) => Promise<{ score: number; pass: boolean }>\n /** Hard cap on iterations (default 40 — covers ~1T ordered states). */\n maxIterations?: number\n}\n\nexport interface BisectStep<T> {\n state: T\n score: number\n pass: boolean\n}\n\nexport interface BisectResult<T> {\n /** The first bad state — typically `bad` in the final (good, bad) adjacent pair. */\n culprit: T\n /** Ordered trace of all states evaluated. */\n path: BisectStep<T>[]\n /** True when we narrowed to an adjacent (good, bad) pair. */\n converged: boolean\n /** True when `good` itself failed or `bad` itself passed — the caller's\n * premise was broken. */\n inputInconsistent: boolean\n}\n\nexport async function bisect<T>(options: BisectOptions<T>): Promise<BisectResult<T>> {\n const equals = options.equals ?? ((a, b) => Object.is(a, b))\n const maxIter = options.maxIterations ?? 40\n const path: BisectStep<T>[] = []\n\n const goodVerdict = await options.runEval(options.good)\n path.push({ state: options.good, ...goodVerdict })\n const badVerdict = await options.runEval(options.bad)\n path.push({ state: options.bad, ...badVerdict })\n\n if (!goodVerdict.pass) {\n return { culprit: options.good, path, converged: false, inputInconsistent: true }\n }\n if (badVerdict.pass) {\n return { culprit: options.bad, path, converged: false, inputInconsistent: true }\n }\n\n let good = options.good\n let bad = options.bad\n for (let i = 0; i < maxIter; i++) {\n const mid = options.halfway(good, bad)\n if (mid === null || equals(mid, good) || equals(mid, bad)) {\n return { culprit: bad, path, converged: true, inputInconsistent: false }\n }\n const v = await options.runEval(mid)\n path.push({ state: mid, ...v })\n if (v.pass) good = mid\n else bad = mid\n }\n return { culprit: bad, path, converged: false, inputInconsistent: false }\n}\n\n/**\n * Commit bisect — `commits` is an ordered SHA list, oldest to newest.\n * `good` and `bad` must both be present in the list.\n */\nexport async function commitBisect(options: {\n commits: string[]\n good: string\n bad: string\n runEval: (sha: string) => Promise<{ score: number; pass: boolean }>\n maxIterations?: number\n}): Promise<BisectResult<string>> {\n const { commits } = options\n const goodIdx = commits.indexOf(options.good)\n const badIdx = commits.indexOf(options.bad)\n if (goodIdx < 0 || badIdx < 0) {\n throw new Error(\n `commitBisect: good or bad SHA not in commit list (good=${options.good}, bad=${options.bad})`,\n )\n }\n if (goodIdx >= badIdx) {\n throw new Error('commitBisect: good must precede bad in the commit list')\n }\n return bisect<string>({\n good: options.good,\n bad: options.bad,\n runEval: options.runEval,\n maxIterations: options.maxIterations,\n halfway: (g, b) => {\n const gi = commits.indexOf(g)\n const bi = commits.indexOf(b)\n if (bi - gi <= 1) return null\n return commits[Math.floor((gi + bi) / 2)] ?? null\n },\n })\n}\n\n/**\n * Prompt bisect — splits the good and bad prompts into paragraphs, then\n * progressively replaces paragraphs in `good` with their counterparts\n * from `bad` to localize the offending change. Only works when the two\n * prompts have the same paragraph count (a common editorial workflow\n * constraint — one paragraph = one change unit).\n */\nexport async function promptBisect(options: {\n good: string\n bad: string\n runEval: (prompt: string) => Promise<{ score: number; pass: boolean }>\n maxIterations?: number\n paragraphSplitter?: (prompt: string) => string[]\n}): Promise<BisectResult<string> & { offendingParagraphIndex?: number }> {\n const split = options.paragraphSplitter ?? ((p: string) => p.split(/\\n\\s*\\n/))\n const join = (paragraphs: string[]) => paragraphs.join('\\n\\n')\n const goodParas = split(options.good)\n const badParas = split(options.bad)\n if (goodParas.length !== badParas.length) {\n throw new Error(\n `promptBisect: paragraph count mismatch (${goodParas.length} vs ${badParas.length})`,\n )\n }\n if (goodParas.length < 2) {\n throw new Error('promptBisect: need at least 2 paragraphs to bisect')\n }\n // Represent state as a bit-mask of which paragraphs come from `bad`.\n // good = all-zero, bad = all-one; halfway = flip the midpoint half.\n const n = goodParas.length\n const goodMask = '0'.repeat(n)\n const badMask = '1'.repeat(n)\n\n function paragraphsFor(mask: string): string[] {\n return mask.split('').map((c, i) => (c === '1' ? badParas[i]! : goodParas[i]!))\n }\n\n const result = await bisect<string>({\n good: goodMask,\n bad: badMask,\n runEval: (mask) => options.runEval(join(paragraphsFor(mask))),\n maxIterations: options.maxIterations ?? n + 5,\n halfway: (g, b) => {\n // Pick the first differing position and flip it.\n for (let i = 0; i < g.length; i++) {\n if (g[i] !== b[i]) {\n // Flip the midpoint between the remaining diff positions.\n const differing: number[] = []\n for (let j = i; j < g.length; j++) if (g[j] !== b[j]) differing.push(j)\n if (differing.length === 0) return null\n if (differing.length === 1) return null // adjacent — can't narrow further\n // Flip the first half of differing positions from good → bad.\n const flip = differing.slice(0, Math.ceil(differing.length / 2))\n const chars = g.split('')\n for (const f of flip) chars[f] = b[f]!\n return chars.join('')\n }\n }\n return null\n },\n equals: (a, b) => a === b,\n })\n\n // Identify the offending paragraph as the index that changed between the\n // last good and final bad in the path.\n let offendingParagraphIndex: number | undefined\n const lastGood = result.path.filter((s) => s.pass).pop()\n const culprit = result.culprit\n if (lastGood) {\n for (let i = 0; i < n; i++) {\n if (lastGood.state[i] !== culprit[i]) {\n offendingParagraphIndex = i\n break\n }\n }\n }\n\n // Materialize path states back into full prompts for caller consumption.\n const materializedPath: BisectStep<string>[] = result.path.map((s) => ({\n state: join(paragraphsFor(s.state)),\n score: s.score,\n pass: s.pass,\n }))\n\n return {\n culprit: join(paragraphsFor(culprit)),\n path: materializedPath,\n converged: result.converged,\n inputInconsistent: result.inputInconsistent,\n offendingParagraphIndex,\n }\n}\n","/**\n * Counterfactual replay — \"what would have happened if we'd changed\n * exactly one thing at turn N?\"\n *\n * The framework does NOT drive the agent — it sets up the replay\n * context (prior spans, prior state, mutation spec) and records the\n * resulting divergence. Consumers supply an `executeFrom(ctx)` callback\n * that runs their agent starting from turn N with the mutation applied.\n *\n * Counterfactual runs are recorded as a new Run with `layer='meta'` and\n * `parentRunId = originalRunId`, so downstream diff + correlation\n * pipelines see them natively.\n */\n\nimport { NotFoundError, ValidationError } from './errors'\nimport { TraceEmitter } from './trace/emitter'\nimport type { LlmSpan, Span, ToolSpan } from './trace/schema'\nimport type { TraceStore } from './trace/store'\nimport { buildTrajectory, type Trajectory, type TrajectoryStep } from './trajectory'\n\nexport type CounterfactualMutation =\n | { kind: 'swap-model'; at: number; newModel: string }\n | { kind: 'swap-tool-result'; at: number; newResult: unknown }\n | { kind: 'truncate-after'; at: number }\n | { kind: 'inject-system-message'; at: number; content: string }\n | {\n kind: 'custom'\n at: number\n describe: string\n apply: (step: TrajectoryStep) => TrajectoryStep\n }\n\nexport interface CounterfactualContext {\n originalRunId: string\n originalTrajectory: Trajectory\n /** Steps up to (but not including) the mutation point — the prefix the\n * replayed agent inherits as its prior conversation/tool history. */\n prefix: TrajectoryStep[]\n mutation: CounterfactualMutation\n /** Pre-applied mutation on the step at `mutation.at`. Consumers use this\n * as the FIRST step the replayed agent emits (they decide whether to\n * re-emit it or continue from there). */\n mutatedStep: TrajectoryStep\n}\n\nexport interface CounterfactualResult {\n counterfactualRunId: string\n originalRunId: string\n mutation: CounterfactualMutation\n /** Structured delta summary — caller can extend via scoring. */\n delta: {\n originalOutcomeScore: number | null\n counterfactualOutcomeScore: number | null\n deltaScore: number | null\n }\n}\n\nexport interface CounterfactualRunner {\n /**\n * Execute the agent from `ctx.prefix` with the mutation applied.\n * MUST emit spans into the provided emitter so they become part of\n * the counterfactual run. MUST call emitter.endRun() with a verdict.\n */\n executeFrom: (ctx: CounterfactualContext, emitter: TraceEmitter) => Promise<void>\n}\n\nexport async function runCounterfactual(\n store: TraceStore,\n originalRunId: string,\n mutation: CounterfactualMutation,\n runner: CounterfactualRunner,\n): Promise<CounterfactualResult> {\n const originalRun = await store.getRun(originalRunId)\n if (!originalRun) throw new NotFoundError(`counterfactual: run ${originalRunId} not found`)\n const trajectory = await buildTrajectory(store, originalRunId)\n if (mutation.at < 0 || mutation.at >= trajectory.steps.length) {\n throw new ValidationError(\n `counterfactual: mutation.at=${mutation.at} out of range [0, ${trajectory.steps.length})`,\n )\n }\n const targetStep = trajectory.steps[mutation.at]!\n const mutatedStep = applyMutation(targetStep, mutation)\n\n const cfEmitter = new TraceEmitter(store)\n await cfEmitter.startRun({\n scenarioId: originalRun.scenarioId,\n variantId: originalRun.variantId\n ? `${originalRun.variantId}+cf:${mutation.kind}@${mutation.at}`\n : `cf:${mutation.kind}@${mutation.at}`,\n projectId: originalRun.projectId,\n parentRunId: originalRunId,\n layer: 'meta',\n tags: { counterfactual: 'true', mutationKind: mutation.kind, mutationAt: String(mutation.at) },\n })\n\n await runner.executeFrom(\n {\n originalRunId,\n originalTrajectory: trajectory,\n prefix: trajectory.steps.slice(0, mutation.at),\n mutation,\n mutatedStep,\n },\n cfEmitter,\n )\n\n const counterfactual = await store.getRun(cfEmitter.runId)\n const delta = {\n originalOutcomeScore: originalRun.outcome?.score ?? null,\n counterfactualOutcomeScore: counterfactual?.outcome?.score ?? null,\n deltaScore:\n originalRun.outcome?.score !== undefined && counterfactual?.outcome?.score !== undefined\n ? counterfactual.outcome.score - originalRun.outcome.score\n : null,\n }\n return { counterfactualRunId: cfEmitter.runId, originalRunId, mutation, delta }\n}\n\nfunction applyMutation(step: TrajectoryStep, mutation: CounterfactualMutation): TrajectoryStep {\n if (mutation.kind === 'swap-model' && step.span.kind === 'llm') {\n const llm = step.span as LlmSpan\n return { ...step, span: { ...llm, model: mutation.newModel } }\n }\n if (mutation.kind === 'swap-tool-result' && step.span.kind === 'tool') {\n const tool = step.span as ToolSpan\n return { ...step, span: { ...tool, result: mutation.newResult } }\n }\n if (mutation.kind === 'inject-system-message' && step.span.kind === 'llm') {\n const llm = step.span as LlmSpan\n return {\n ...step,\n span: {\n ...llm,\n messages: [{ role: 'system', content: mutation.content }, ...llm.messages],\n },\n }\n }\n if (mutation.kind === 'custom') return mutation.apply(step)\n // swap-tool-result on non-tool span / swap-model on non-llm / truncate-after: no step-level change.\n return step\n}\n\n/**\n * Aggregate a batch of counterfactuals into a simple attribution table:\n * which mutation kinds move outcomes most? (Useful when you run a grid\n * over the same trajectory — swap-model at every llm span, swap-tool\n * at every tool span — and want a ranked summary.)\n */\nexport function attributeCounterfactuals(results: CounterfactualResult[]): Array<{\n mutationKind: CounterfactualMutation['kind']\n n: number\n meanAbsDelta: number\n meanSignedDelta: number\n}> {\n const grouped = new Map<string, CounterfactualResult[]>()\n for (const r of results) {\n const arr = grouped.get(r.mutation.kind) ?? []\n arr.push(r)\n grouped.set(r.mutation.kind, arr)\n }\n const out: Array<{\n mutationKind: CounterfactualMutation['kind']\n n: number\n meanAbsDelta: number\n meanSignedDelta: number\n }> = []\n for (const [kind, items] of grouped) {\n const deltas = items\n .map((i) => i.delta.deltaScore)\n .filter((d): d is number => typeof d === 'number')\n if (deltas.length === 0) continue\n const meanAbs = deltas.reduce((a, b) => a + Math.abs(b), 0) / deltas.length\n const meanSigned = deltas.reduce((a, b) => a + b, 0) / deltas.length\n out.push({\n mutationKind: kind as CounterfactualMutation['kind'],\n n: deltas.length,\n meanAbsDelta: meanAbs,\n meanSignedDelta: meanSigned,\n })\n }\n return out.sort((a, b) => b.meanAbsDelta - a.meanAbsDelta)\n}\n\n// Re-export Span type for consumer ergonomics.\nexport type { Span }\n","/**\n * Full cross-trace diff — align two trajectories step-by-step, report\n * per-step score deltas, attribute a variant's total outcome lead to\n * specific turns.\n *\n * 0.5 shipped `firstDivergenceView` (finds the first differing step).\n * This does the heavier work: full alignment via LCS, per-step\n * contribution to score delta using PRM verdicts when available,\n * fallback to structural heuristics (latency, token count, tool\n * outcome) otherwise.\n */\n\nimport type { JudgeSpan, Span } from './trace/schema'\nimport { isJudgeSpan } from './trace/schema'\nimport type { TraceStore } from './trace/store'\nimport { buildTrajectory, type TrajectoryStep } from './trajectory'\n\nexport type AlignmentOp =\n | { op: 'match'; a: TrajectoryStep; b: TrajectoryStep }\n | { op: 'insert'; b: TrajectoryStep }\n | { op: 'delete'; a: TrajectoryStep }\n | { op: 'replace'; a: TrajectoryStep; b: TrajectoryStep }\n\nexport interface StepAttribution {\n op: AlignmentOp\n /** Difference in PRM score (or null when not scored by a matching judge). */\n prmDelta: number | null\n /** Difference in latency (endedAt - startedAt). */\n latencyDeltaMs: number | null\n /** Difference in token count (LLM spans). */\n tokenDelta: number | null\n /** Reason this step is / isn't considered a contributor to the outcome delta. */\n note: string\n}\n\nexport interface CrossTraceDiff {\n runA: string\n runB: string\n alignment: AlignmentOp[]\n attributions: StepAttribution[]\n /** Total score delta (B - A). */\n totalScoreDelta: number | null\n /** Sum of PRM deltas across matched/replaced steps. Close to\n * `totalScoreDelta` when PRM covers the trajectory; gap indicates\n * unmodeled variance. */\n prmDeltaSum: number\n}\n\nexport interface CrossTraceDiffOptions {\n stepEquals?: (a: TrajectoryStep, b: TrajectoryStep) => boolean\n}\n\nexport async function crossTraceDiff(\n store: TraceStore,\n runA: string,\n runB: string,\n options: CrossTraceDiffOptions = {},\n): Promise<CrossTraceDiff> {\n const [a, b] = await Promise.all([buildTrajectory(store, runA), buildTrajectory(store, runB)])\n const eq = options.stepEquals ?? defaultStepEquals\n const alignment = align(a.steps, b.steps, eq)\n\n const [judgesA, judgesB] = await Promise.all([\n store.spans({ runId: runA, kind: 'judge' }).then((s) => s.filter(isJudgeSpan)),\n store.spans({ runId: runB, kind: 'judge' }).then((s) => s.filter(isJudgeSpan)),\n ])\n const prmByTargetA = indexPrmByTarget(judgesA)\n const prmByTargetB = indexPrmByTarget(judgesB)\n\n const attributions: StepAttribution[] = alignment.map((ao) =>\n attributeStep(ao, prmByTargetA, prmByTargetB),\n )\n const prmDeltaSum = attributions.reduce((acc, at) => acc + (at.prmDelta ?? 0), 0)\n\n const [runRecA, runRecB] = await Promise.all([store.getRun(runA), store.getRun(runB)])\n const totalScoreDelta =\n runRecA?.outcome?.score !== undefined && runRecB?.outcome?.score !== undefined\n ? runRecB.outcome.score - runRecA.outcome.score\n : null\n\n return { runA, runB, alignment, attributions, totalScoreDelta, prmDeltaSum }\n}\n\n// ── Alignment (LCS-based) ────────────────────────────────────────────\n\nfunction align(\n a: TrajectoryStep[],\n b: TrajectoryStep[],\n eq: (x: TrajectoryStep, y: TrajectoryStep) => boolean,\n): AlignmentOp[] {\n const dp: number[][] = Array.from({ length: a.length + 1 }, () => new Array(b.length + 1).fill(0))\n for (let i = 1; i <= a.length; i++) {\n for (let j = 1; j <= b.length; j++) {\n if (eq(a[i - 1]!, b[j - 1]!)) dp[i]![j] = dp[i - 1]![j - 1]! + 1\n else dp[i]![j] = Math.max(dp[i - 1]![j]!, dp[i]![j - 1]!)\n }\n }\n // Walk back to recover ops.\n const ops: AlignmentOp[] = []\n let i = a.length\n let j = b.length\n while (i > 0 || j > 0) {\n if (i > 0 && j > 0 && eq(a[i - 1]!, b[j - 1]!)) {\n ops.push({ op: 'match', a: a[i - 1]!, b: b[j - 1]! })\n i--\n j--\n } else if (i > 0 && j > 0 && dp[i - 1]![j]! === dp[i]![j - 1]!) {\n // Tie → call it a replace when same kind, else delete+insert.\n if (a[i - 1]!.span.kind === b[j - 1]!.span.kind) {\n ops.push({ op: 'replace', a: a[i - 1]!, b: b[j - 1]! })\n i--\n j--\n } else if (dp[i - 1]![j]! >= dp[i]![j - 1]!) {\n ops.push({ op: 'delete', a: a[i - 1]! })\n i--\n } else {\n ops.push({ op: 'insert', b: b[j - 1]! })\n j--\n }\n } else if (i > 0 && (j === 0 || dp[i - 1]![j]! >= dp[i]![j - 1]!)) {\n ops.push({ op: 'delete', a: a[i - 1]! })\n i--\n } else {\n ops.push({ op: 'insert', b: b[j - 1]! })\n j--\n }\n }\n return ops.reverse()\n}\n\nfunction defaultStepEquals(a: TrajectoryStep, b: TrajectoryStep): boolean {\n if (a.span.kind !== b.span.kind) return false\n if (a.span.kind === 'tool' && b.span.kind === 'tool') return a.span.toolName === b.span.toolName\n if (a.span.kind === 'llm' && b.span.kind === 'llm') return a.span.model === b.span.model\n return a.span.name === b.span.name\n}\n\n// ── PRM indexing + attribution ───────────────────────────────────────\n\nfunction indexPrmByTarget(judges: JudgeSpan[]): Map<string, number> {\n const out = new Map<string, number>()\n for (const j of judges) {\n const prior = out.get(j.targetSpanId) ?? 0\n out.set(j.targetSpanId, prior + j.score)\n }\n return out\n}\n\nfunction spanLatency(s: Span): number | null {\n return s.endedAt && s.startedAt ? s.endedAt - s.startedAt : null\n}\n\nfunction spanTokens(s: Span): number | null {\n if (s.kind !== 'llm') return null\n return (s.inputTokens ?? 0) + (s.outputTokens ?? 0)\n}\n\nfunction attributeStep(\n op: AlignmentOp,\n prmA: Map<string, number>,\n prmB: Map<string, number>,\n): StepAttribution {\n if (op.op === 'match') {\n const pa = prmA.get(op.a.span.spanId)\n const pb = prmB.get(op.b.span.spanId)\n const prmDelta = pa !== undefined && pb !== undefined ? pb - pa : null\n const la = spanLatency(op.a.span)\n const lb = spanLatency(op.b.span)\n const ta = spanTokens(op.a.span)\n const tb = spanTokens(op.b.span)\n return {\n op,\n prmDelta,\n latencyDeltaMs: la !== null && lb !== null ? lb - la : null,\n tokenDelta: ta !== null && tb !== null ? tb - ta : null,\n note:\n prmDelta === null ? 'matched step, no PRM coverage' : 'matched step, PRM delta recorded',\n }\n }\n if (op.op === 'replace') {\n const pa = prmA.get(op.a.span.spanId) ?? 0\n const pb = prmB.get(op.b.span.spanId) ?? 0\n return {\n op,\n prmDelta: pb - pa,\n latencyDeltaMs: null,\n tokenDelta: null,\n note: `replaced ${op.a.span.kind}/${op.a.span.name} → ${op.b.span.kind}/${op.b.span.name}`,\n }\n }\n if (op.op === 'insert') {\n const pb = prmB.get(op.b.span.spanId) ?? 0\n return {\n op,\n prmDelta: pb,\n latencyDeltaMs: null,\n tokenDelta: null,\n note: `inserted step in B (${op.b.span.kind}/${op.b.span.name})`,\n }\n }\n // delete\n const pa = prmA.get(op.a.span.spanId) ?? 0\n return {\n op,\n prmDelta: -pa,\n latencyDeltaMs: null,\n tokenDelta: null,\n note: `deleted step from A (${op.a.span.kind}/${op.a.span.name})`,\n }\n}\n","/**\n * Active learning — agent-as-scenario-author.\n *\n * Analyzes an existing Dataset + trace corpus for coverage gaps and\n * weak spots, returns a prioritized list of *synthesis targets*:\n * (gap description, existing-neighbor examples, suggested direction).\n *\n * Does NOT call an LLM itself — the proposer agent is caller-supplied.\n * This module's job is to identify WHERE new scenarios would compound\n * the most information, not to author them.\n *\n * Gaps we detect:\n * - dimensions with high score variance (unstable, need more data)\n * - dimensions with low coverage count (undersampled)\n * - failure classes with clusters (systematic weakness)\n * - difficulty bins with no coverage\n */\n\nimport type { Dataset, DatasetScenario } from './dataset'\nimport { classifyFailure } from './failure-taxonomy'\nimport type { Run } from './trace/schema'\nimport type { TraceStore } from './trace/store'\n\nexport type SynthesisReason =\n | 'high-variance'\n | 'undersampled'\n | 'failure-cluster'\n | 'difficulty-gap'\n\nexport interface SynthesisTarget {\n reason: SynthesisReason\n description: string\n /** Existing scenarios that are closest to the gap; caller feeds these to\n * their LLM proposer as few-shot examples. */\n neighbors: DatasetScenario[]\n /** Suggested direction — e.g. \"harder variants\", \"edge cases of X\", \"failure class Y\". */\n direction: string\n /** Priority score — higher = more information-dense gap. 0..1. */\n priority: number\n}\n\nexport interface ActiveLearningOptions {\n /** Minimum scenarios per difficulty band to count as \"covered\". */\n minPerBand?: number\n /** Variance threshold above which a scenario's dimension is \"unstable\". */\n varianceThreshold?: number\n /** Max synthesis targets returned. */\n topK?: number\n}\n\nexport async function proposeSynthesisTargets(\n dataset: Dataset,\n traceStore: TraceStore,\n options: ActiveLearningOptions = {},\n): Promise<SynthesisTarget[]> {\n const minPerBand = options.minPerBand ?? 5\n const varianceThreshold = options.varianceThreshold ?? 0.05\n const topK = options.topK ?? 10\n const scenarios = dataset.all()\n\n const targets: SynthesisTarget[] = []\n\n // 1. Difficulty coverage gaps\n const BANDS: Array<DatasetScenario['difficulty']> = ['easy', 'medium', 'hard', 'extreme']\n for (const band of BANDS) {\n const count = scenarios.filter((s) => s.difficulty === band).length\n if (count < minPerBand) {\n const neighbors = scenarios.filter((s) => s.difficulty === band).slice(0, 3)\n targets.push({\n reason: 'difficulty-gap',\n description: `difficulty=\"${band}\" has ${count} scenario(s) — below minimum ${minPerBand}`,\n neighbors: [...neighbors],\n direction: `create more \"${band}\" scenarios; reuse domain but shift complexity`,\n priority: Math.max(0, 1 - count / minPerBand),\n })\n }\n }\n\n // 2. Undersampled scenarios (few runs per scenario)\n const runs = await traceStore.listRuns()\n const runCountByScenario = new Map<string, number>()\n for (const r of runs) {\n runCountByScenario.set(r.scenarioId, (runCountByScenario.get(r.scenarioId) ?? 0) + 1)\n }\n const runCounts = [...runCountByScenario.values()]\n const p25 = runCounts.length > 0 ? quantile(runCounts, 0.25) : 0\n for (const s of scenarios) {\n const count = runCountByScenario.get(s.id) ?? 0\n if (count <= p25 && count < 3) {\n targets.push({\n reason: 'undersampled',\n description: `scenario \"${s.id}\" has only ${count} run(s)`,\n neighbors: [s],\n direction: `create near-duplicates of \"${s.id}\" to stabilize its mean`,\n priority: Math.max(0, 1 - count / 3) * 0.7,\n })\n }\n }\n\n // 3. High-variance scenarios (same scenario scored inconsistently)\n for (const s of scenarios) {\n const sRuns = runs.filter((r) => r.scenarioId === s.id)\n const scores = sRuns\n .map((r) => r.outcome?.score)\n .filter((x): x is number => typeof x === 'number')\n if (scores.length < 3) continue\n const mean = scores.reduce((a, b) => a + b, 0) / scores.length\n const variance = scores.reduce((a, b) => a + (b - mean) ** 2, 0) / scores.length\n if (variance > varianceThreshold) {\n targets.push({\n reason: 'high-variance',\n description: `scenario \"${s.id}\" has unstable scoring (variance ${variance.toFixed(3)})`,\n neighbors: [s],\n direction: `disambiguate the scenario description — current wording admits too many valid interpretations`,\n priority: Math.min(1, variance * 5),\n })\n }\n }\n\n // 4. Failure-class clusters — run classifier across the corpus\n const failureByClass = new Map<string, Run[]>()\n for (const run of runs) {\n if (run.outcome?.pass === true) continue\n const spans = await traceStore.spans({ runId: run.runId })\n const events = await traceStore.events({ runId: run.runId })\n const { failureClass } = classifyFailure({ run, spans, events })\n if (failureClass === 'success' || failureClass === 'unknown') continue\n const arr = failureByClass.get(failureClass) ?? []\n arr.push(run)\n failureByClass.set(failureClass, arr)\n }\n for (const [cls, runs] of failureByClass) {\n if (runs.length < 3) continue\n const affectedScenarios = [...new Set(runs.map((r) => r.scenarioId))]\n const neighbors = scenarios.filter((s) => affectedScenarios.includes(s.id)).slice(0, 3)\n targets.push({\n reason: 'failure-cluster',\n description: `failure class \"${cls}\" observed ${runs.length}× across ${affectedScenarios.length} scenario(s)`,\n neighbors,\n direction: `create scenarios that exercise \"${cls}\" recovery — currently a systematic weakness`,\n priority: Math.min(1, runs.length / 10),\n })\n }\n\n return targets.sort((a, b) => b.priority - a.priority).slice(0, topK)\n}\n\nfunction quantile(xs: number[], p: number): number {\n const sorted = [...xs].sort((a, b) => a - b)\n const idx = p * (sorted.length - 1)\n const lo = Math.floor(idx)\n const hi = Math.ceil(idx)\n return sorted[lo]! + (sorted[hi]! - sorted[lo]!) * (idx - lo)\n}\n","/**\n * Causal attribution via factorial experiments.\n *\n * Run every combination of {model × prompt × scenario × seed}, then\n * decompose observed score variance into main effects + interactions.\n * Moves from correlational \"variant B is better\" to causal \"the model\n * swap accounts for 42% of the lead; the prompt change accounts for 28%;\n * interaction is 30%.\"\n *\n * Minimal implementation: 2-way factorial (two factors at a time) with\n * main-effect + interaction decomposition via variance of cell means.\n * Consumers run the factorial design themselves (we don't schedule\n * runs); this module consumes the (factorLevels, observedScores)\n * table and does the attribution math.\n */\n\nexport interface FactorialCell {\n /** Map factor name → level id. e.g. { model: 'claude', prompt: 'v2' } */\n levels: Record<string, string>\n /** Observed score for this cell (mean over replications if n > 1). */\n score: number\n /** Number of replications averaged to produce `score`. */\n n: number\n}\n\nexport interface FactorContribution {\n factor: string\n /** Variance attributed to this factor's main effect, as a fraction of total. */\n shareOfVariance: number\n /** Range of cell means across levels of this factor. */\n range: number\n}\n\nexport interface InteractionContribution {\n factors: [string, string]\n shareOfVariance: number\n}\n\nexport interface CausalAttributionReport {\n totalVariance: number\n mainEffects: FactorContribution[]\n interactions: InteractionContribution[]\n /** Residual = variance unexplained by main effects + modeled interactions. */\n residualShare: number\n /** Sanity: shares sum to 1 (within fp). */\n sharesSum: number\n}\n\nexport function causalAttribution(cells: FactorialCell[]): CausalAttributionReport {\n if (cells.length < 4) throw new Error('causalAttribution: need ≥ 4 cells to estimate effects')\n const factors = Object.keys(cells[0]!.levels)\n if (factors.length < 2) throw new Error('causalAttribution: need ≥ 2 factors')\n\n const allScores = cells.map((c) => c.score)\n const grandMean = allScores.reduce((a, b) => a + b, 0) / allScores.length\n const totalVariance =\n allScores.reduce((acc, s) => acc + (s - grandMean) ** 2, 0) / allScores.length\n if (totalVariance === 0) {\n return {\n totalVariance: 0,\n mainEffects: factors.map((f) => ({ factor: f, shareOfVariance: 0, range: 0 })),\n interactions: [],\n residualShare: 1,\n sharesSum: 1,\n }\n }\n\n // Main effects: variance of cell-mean-by-level, averaged across other factors.\n const mainEffects: FactorContribution[] = factors.map((f) => {\n const byLevel = groupBy(cells, (c) => c.levels[f] ?? '')\n const means: number[] = []\n for (const arr of byLevel.values()) {\n means.push(arr.reduce((a, c) => a + c.score, 0) / arr.length)\n }\n const mainVariance = means.reduce((acc, m) => acc + (m - grandMean) ** 2, 0) / means.length\n return {\n factor: f,\n shareOfVariance: mainVariance / totalVariance,\n range: Math.max(...means) - Math.min(...means),\n }\n })\n\n // Pairwise interactions: cell mean by (factor_i, factor_j) vs main effects\n const interactions: InteractionContribution[] = []\n for (let i = 0; i < factors.length; i++) {\n for (let j = i + 1; j < factors.length; j++) {\n const fi = factors[i]!\n const fj = factors[j]!\n const byPair = groupBy(cells, (c) => `${c.levels[fi]}|${c.levels[fj]}`)\n const pairMeans: number[] = []\n for (const arr of byPair.values()) {\n pairMeans.push(arr.reduce((a, c) => a + c.score, 0) / arr.length)\n }\n const pairVariance =\n pairMeans.reduce((acc, m) => acc + (m - grandMean) ** 2, 0) / pairMeans.length\n const mainI = mainEffects[i]!.shareOfVariance * totalVariance\n const mainJ = mainEffects[j]!.shareOfVariance * totalVariance\n const interactionVariance = Math.max(0, pairVariance - mainI - mainJ)\n interactions.push({\n factors: [fi, fj],\n shareOfVariance: interactionVariance / totalVariance,\n })\n }\n }\n\n const mainSum = mainEffects.reduce((a, m) => a + m.shareOfVariance, 0)\n const interactionSum = interactions.reduce((a, m) => a + m.shareOfVariance, 0)\n const residualShare = Math.max(0, 1 - mainSum - interactionSum)\n const sharesSum = mainSum + interactionSum + residualShare\n return { totalVariance, mainEffects, interactions, residualShare, sharesSum }\n}\n\nfunction groupBy<T>(items: T[], key: (t: T) => string): Map<string, T[]> {\n const m = new Map<string, T[]>()\n for (const item of items) {\n const k = key(item)\n const arr = m.get(k) ?? []\n arr.push(item)\n m.set(k, arr)\n }\n return m\n}\n","/**\n * Reward-model export — the productizable wrapper around PRM training\n * data. Takes a TraceStore + PrmGrader, produces an embeddable\n * inference scorer that customers plug into their own agent stack.\n *\n * Two export forms:\n * - `exportRewardModel(store, graders)` — serializes the (step-context,\n * score) corpus to a framework-agnostic payload. Customer fine-tunes\n * their own model; we ship the scaffolding.\n * - `loadScorerFromTraces(store, grader)` — a zero-deps \"reward model\"\n * that literally replays the trained rubric at inference time. Works\n * as a reference baseline + deterministic fallback.\n */\n\nimport type { PrmGradedTrace, PrmGrader } from './prm/rubric'\nimport { exportTrainingData, type PrmTrainingSample, toNdjson } from './prm/training-export'\nimport type { TraceStore } from './trace/store'\nimport type { Trajectory } from './trajectory'\nimport { buildTrajectory } from './trajectory'\n\nexport interface ExportedRewardModel {\n /** Version of the export format. Bump when payload shape changes. */\n version: '1.0'\n /** Metadata about the training corpus. */\n metadata: {\n nTraces: number\n nSamples: number\n rubrics: string[]\n exportedAt: string\n /** Mean reward across training corpus — use as sanity check at load. */\n meanReward: number\n }\n /** NDJSON training payload suitable for most fine-tuning frameworks. */\n trainingNdjson: string\n}\n\nexport async function exportRewardModel(\n store: TraceStore,\n grader: PrmGrader,\n runIds: string[],\n): Promise<ExportedRewardModel> {\n const graded = await Promise.all(runIds.map((id) => grader.grade(store, id)))\n const samples = await exportTrainingData(store, graded)\n const rubrics = [...new Set(samples.map((s) => s.rubricId))]\n const meanReward =\n samples.length > 0 ? samples.reduce((a, s) => a + s.score, 0) / samples.length : 0\n return {\n version: '1.0',\n metadata: {\n nTraces: graded.length,\n nSamples: samples.length,\n rubrics,\n exportedAt: new Date().toISOString(),\n meanReward,\n },\n trainingNdjson: toNdjson(samples),\n }\n}\n\n/**\n * Zero-deps inference scorer — apply a grader to a trajectory and return\n * its aggregate score. This is the \"reward model\" customers embed when\n * they don't want (or can't) fine-tune one. Deterministic + portable.\n */\nexport interface InferenceScorer {\n /** Score a completed trajectory. Higher is better. */\n score(trajectory: Trajectory, store: TraceStore): Promise<number>\n metadata: { rubrics: string[]; deterministic: true }\n}\n\nexport function loadScorerFromGrader(grader: PrmGrader): InferenceScorer {\n return {\n async score(trajectory, store) {\n const graded = await grader.grade(store, trajectory.runId)\n return graded.aggregateScore\n },\n metadata: {\n rubrics: ['grader-backed'],\n deterministic: true,\n },\n }\n}\n\n/**\n * Replay a trace corpus through a scorer — produces the canonical\n * \"what would this reward model have said about every run?\" table.\n * Callers use this to validate a trained model against the training\n * corpus (expect high agreement; drift indicates overfitting).\n */\nexport async function replayScorerOverCorpus(\n store: TraceStore,\n scorer: InferenceScorer,\n runIds: string[],\n): Promise<Array<{ runId: string; score: number; outcomeScore: number | null }>> {\n return Promise.all(\n runIds.map(async (runId) => {\n const [trajectory, run] = await Promise.all([\n buildTrajectory(store, runId),\n store.getRun(runId),\n ])\n return {\n runId,\n score: await scorer.score(trajectory, store),\n outcomeScore: run?.outcome?.score ?? null,\n }\n }),\n )\n}\n\n// Re-export for ergonomics\nexport type { PrmGradedTrace, PrmTrainingSample }\n","/**\n * Self-play scenario evolution — agents generate adversarial scenarios\n * against each other; survivors become part of the eval corpus.\n *\n * Framework-agnostic about how scenarios are generated. Caller supplies:\n * - `propose`: asks a \"proposer\" agent for candidate scenarios\n * - `scoreAgainst`: runs a target agent against a scenario and returns\n * its score\n *\n * A scenario *survives* if it reveals a meaningful score difference\n * between two target agents (or between a target agent and itself on\n * different runs). Survivors are promoted to a Dataset; the caller\n * decides what to do with them (hold-out, training, regression set).\n *\n * Guard rails: minimum absolute score delta to consider a scenario\n * informative; floor on absolute target score so degenerate break-all\n * scenarios (noise, gibberish) don't flood the corpus.\n */\n\nimport { Dataset, type DatasetScenario } from './dataset'\n\nexport interface CandidateScenario {\n id: string\n payload: unknown\n /** Free-form tags (domain, generation, parent). */\n tags?: Record<string, string>\n}\n\nexport interface ScoredTarget {\n targetId: string\n score: number\n}\n\nexport interface EvolutionRound {\n round: number\n proposed: CandidateScenario[]\n survived: CandidateScenario[]\n rejected: Array<{ candidate: CandidateScenario; reason: string }>\n scoredBreakdown: Array<{ candidate: CandidateScenario; scores: ScoredTarget[]; spread: number }>\n}\n\nexport interface SelfPlayOptions {\n /** Minimum score spread across targets for a scenario to survive. Default 0.1. */\n minSpread?: number\n /** Minimum floor score across targets — keeps degenerate break-all scenarios\n * out. Default 0.1 (if every target scores below this, discard). */\n minAbsoluteFloor?: number\n /** Hard cap on survivors per round. Default 50. */\n maxSurvivors?: number\n /** Rounds to run. Default 1. Each round's survivors can be fed back into\n * `propose` to compound. */\n rounds?: number\n /** Seed for scenario id generation if proposer doesn't provide one. */\n seed?: number\n}\n\nexport interface SelfPlayProposer {\n propose(round: number, priorSurvivors: CandidateScenario[]): Promise<CandidateScenario[]>\n}\n\nexport interface SelfPlayScorer {\n /** Score one candidate against every target; returns parallel array. */\n scoreCandidate(candidate: CandidateScenario, targets: string[]): Promise<ScoredTarget[]>\n}\n\nexport async function runSelfPlay(\n proposer: SelfPlayProposer,\n scorer: SelfPlayScorer,\n targets: string[],\n options: SelfPlayOptions = {},\n): Promise<{ rounds: EvolutionRound[]; dataset: Dataset }> {\n if (targets.length < 2)\n throw new Error('runSelfPlay: at least 2 targets required (need a difference to measure)')\n const minSpread = options.minSpread ?? 0.1\n const floor = options.minAbsoluteFloor ?? 0.1\n const maxSurvivors = options.maxSurvivors ?? 50\n const totalRounds = options.rounds ?? 1\n\n const allRounds: EvolutionRound[] = []\n let priorSurvivors: CandidateScenario[] = []\n const datasetScenarios: DatasetScenario[] = []\n\n for (let r = 0; r < totalRounds; r++) {\n const proposed = await proposer.propose(r, priorSurvivors)\n const scored: EvolutionRound['scoredBreakdown'] = []\n const rejected: EvolutionRound['rejected'] = []\n const surviving: CandidateScenario[] = []\n for (const candidate of proposed) {\n const scores = await scorer.scoreCandidate(candidate, targets)\n if (scores.length < 2) {\n rejected.push({ candidate, reason: 'scorer returned <2 results' })\n continue\n }\n const values = scores.map((s) => s.score)\n const spread = Math.max(...values) - Math.min(...values)\n const maxScore = Math.max(...values)\n scored.push({ candidate, scores, spread })\n if (maxScore < floor) {\n rejected.push({\n candidate,\n reason: `every target below floor (max=${maxScore.toFixed(3)} < ${floor})`,\n })\n continue\n }\n if (spread < minSpread) {\n rejected.push({\n candidate,\n reason: `spread below threshold (${spread.toFixed(3)} < ${minSpread})`,\n })\n continue\n }\n surviving.push(candidate)\n }\n\n // Rank by spread descending, cap at maxSurvivors\n surviving.sort((a, b) => {\n const sa = scored.find((s) => s.candidate.id === a.id)?.spread ?? 0\n const sb = scored.find((s) => s.candidate.id === b.id)?.spread ?? 0\n return sb - sa\n })\n const capped = surviving.slice(0, maxSurvivors)\n\n for (const s of capped) {\n datasetScenarios.push({\n id: s.id,\n payload: s.payload,\n split: 'test',\n tags: { ...s.tags, evolutionRound: String(r), origin: 'self-play' },\n })\n }\n\n allRounds.push({ round: r, proposed, survived: capped, rejected, scoredBreakdown: scored })\n priorSurvivors = capped\n }\n\n const dataset = new Dataset({\n name: 'self-play-survivors',\n provenance: {\n version: '1.0.0',\n createdAt: new Date().toISOString(),\n contributor: 'self-play',\n description: `Evolved across ${totalRounds} round(s), ${allRounds.reduce((a, r) => a + r.survived.length, 0)} survivors`,\n },\n scenarios: datasetScenarios,\n })\n return { rounds: allRounds, dataset }\n}\n","/**\n * CommandRunner — abstract subprocess execution surface.\n *\n * Layers in a {@link MultiLayerVerifier} that need to invoke external\n * tools (compilers, test runners, package managers) call out via this\n * interface rather than directly using `child_process`. Two reasons:\n *\n * 1. **Sandbox interchangeability.** A run that targets a sandbox box\n * (via SDK-specific Box.exec) and a run that targets the host both\n * satisfy this same contract. The harness doesn't care which.\n * 2. **Testability.** Tests inject a fake runner and assert on calls\n * without spawning real subprocesses.\n *\n * agent-eval ships only the local implementation (host-process). Sandbox\n * implementations live with their consumer because they depend on\n * SDK-specific Box / Sandbox types that don't belong in this package.\n */\n\nimport { spawnSync } from 'node:child_process'\nimport { existsSync, readdirSync, readFileSync, statSync } from 'node:fs'\nimport { join } from 'node:path'\n\n// ─── Types ──────────────────────────────────────────────────────────────\n\nexport interface RunCommandInput {\n /** Executable name, looked up via PATH unless absolute. */\n cmd: string\n /** Argument vector, NOT shell-interpolated. Each element passed to argv. */\n argv: string[]\n /** Working directory. Defaults to runner's notion of cwd if omitted. */\n cwd?: string\n /**\n * Wall-clock cap in ms. The runner SHOULD return `timedOut: true` when\n * exceeded; callers MAY treat status null + timedOut as \"killed.\"\n */\n capMs?: number\n /** Env overrides merged on top of the runner's base environment. */\n env?: Record<string, string>\n /** Optional stdin payload. */\n stdin?: string\n}\n\nexport interface RunCommandResult {\n /** Exit code, or null when the process couldn't start / was killed. */\n status: number | null\n stdout: string\n stderr: string\n durationMs: number\n timedOut: boolean\n /** Non-fatal runner-side error (binary missing, signal, etc.). */\n runnerError?: string\n}\n\nexport interface DirEntry {\n name: string\n isDirectory: boolean\n isFile: boolean\n /** File size in bytes. `null` for directories (not stat'd). */\n sizeBytes: number | null\n}\n\nexport interface CommandRunner {\n /** Identifier for telemetry + logs. Open-ended literal-union for new runners. */\n readonly name: string\n /** Execute a command in the runner's environment. */\n run(input: RunCommandInput): Promise<RunCommandResult>\n /** True iff `<name>` resolves on the runner's PATH. */\n hasBin(name: string): Promise<boolean>\n /** True iff the given path exists in the runner's filesystem. */\n fileExists(path: string): Promise<boolean>\n /** Read a file. Returns `null` if missing or unreadable. */\n readFile(path: string): Promise<string | null>\n /** List a directory. Returns `[]` if unreadable / missing. */\n readDir(path: string): Promise<DirEntry[]>\n}\n\n// ─── Local runner ───────────────────────────────────────────────────────\n\n/**\n * Host-process runner. Uses node:child_process spawnSync (synchronous\n * under the hood — wrapped in a Promise to satisfy the interface). For\n * very long-running commands consider an async-spawn variant; this\n * shape matches VB's existing behavior and is fine for build/test/lint\n * subprocesses that finish in seconds-to-minutes.\n */\nexport const localCommandRunner: CommandRunner = {\n name: 'local',\n async run(input: RunCommandInput): Promise<RunCommandResult> {\n const start = Date.now()\n const res = spawnSync(input.cmd, input.argv, {\n cwd: input.cwd,\n encoding: 'utf8',\n timeout: input.capMs,\n env: { ...process.env, CI: '1', ...(input.env ?? {}) },\n input: input.stdin,\n })\n const durationMs = Date.now() - start\n const timedOut = !!(\n res.error &&\n 'code' in res.error &&\n (res.error as NodeJS.ErrnoException).code === 'ETIMEDOUT'\n )\n return {\n status: res.status ?? null,\n stdout: (res.stdout ?? '').toString(),\n stderr: (res.stderr ?? '').toString(),\n durationMs,\n timedOut,\n runnerError: res.error && !timedOut ? String(res.error.message ?? res.error) : undefined,\n }\n },\n async hasBin(name: string): Promise<boolean> {\n const r = spawnSync('which', [name], { encoding: 'utf8', timeout: 2000 })\n return r.status === 0 && (r.stdout ?? '').trim().length > 0\n },\n async fileExists(path: string): Promise<boolean> {\n return existsSync(path)\n },\n async readFile(path: string): Promise<string | null> {\n try {\n return readFileSync(path, 'utf8')\n } catch {\n return null\n }\n },\n async readDir(path: string): Promise<DirEntry[]> {\n let entries: string[]\n try {\n entries = readdirSync(path)\n } catch {\n return []\n }\n const out: DirEntry[] = []\n for (const name of entries) {\n try {\n const st = statSync(join(path, name))\n out.push({\n name,\n isDirectory: st.isDirectory(),\n isFile: st.isFile(),\n sizeBytes: st.isFile() ? st.size : null,\n })\n } catch {\n // skip unreadable\n }\n }\n return out\n },\n}\n","/**\n * Deploy gate layer — would the agent's build actually publish?\n *\n * The product Blueprint Agent fronts promises \"go from idea to live URL.\"\n * Pre-Gen-48 the eval stopped at install/typecheck/build/serve — every\n * one of which can pass while `vite build` (or `next build`, etc) fails\n * on a production-only constraint (env-var requirement, dynamic import\n * not statically resolvable, missing public asset).\n *\n * Deploy gate runs the production build via the supplied {@link DeployRunner}\n * and asserts:\n * - command exited 0\n * - artifact dir contains an entry point (index.html for static SPAs,\n * equivalent per framework family)\n *\n * Ships with a canonical `vite` runner. Additional runners\n * (wrangler-deploy --dry-run, next-build, etc.) plug in as factories.\n */\n\nimport type { Layer, LayerResult } from './multi-layer-verifier'\n\n// ─── Types ──────────────────────────────────────────────────────────────\n\nexport type DeployFamily = 'frontend-static' | 'nextjs' | 'remix' | 'fullstack-ts'\n\nexport interface DeployRunResult {\n ok: boolean\n /** Stdout/stderr tail surfaced as evidence. Bounded in caller. */\n output?: string\n /** Wall-clock duration of the build command. */\n durationMs?: number\n /** Path to artifact directory the runner expects (dist/, .next/, build/, etc). */\n artifactDir?: string\n /** True iff artifactDir contains the family's expected entry point. */\n artifactValid?: boolean\n}\n\nexport interface DeployRunner {\n /** Run the production build. The runner owns command + cwd. */\n run(): Promise<DeployRunResult>\n}\n\nexport interface DeployGateLayerInput {\n /** Build the runner per call. */\n runner: () => DeployRunner | Promise<DeployRunner>\n /** Family hint — for logging, surfaced in diagnostics. */\n family?: DeployFamily\n /** Layer name. Default `deploy`. */\n name?: string\n /** Layer dependencies — default `['build']`. */\n dependsOn?: string[]\n /** Weight in blendedScore. Default 1. */\n weight?: number\n /** Cap (ms). Default 120s — prod builds are slower than dev. */\n capMs?: number\n /** When true, treat artifactValid=false as a fail (default true). */\n requireArtifact?: boolean\n}\n\n// ─── Layer factory ──────────────────────────────────────────────────────\n\n/**\n * Build a deploy gate layer that runs the production build and verifies\n * the artifact. Pass: ok && artifactValid. Score: 1.0 (pass) or 0 (fail).\n *\n * For families where artifact-validation isn't applicable (e.g. a\n * server-rendered build that prints a manifest), set `requireArtifact:\n * false` and rely on the runner's own ok signal.\n */\nexport function deployGateLayer<Env = unknown>(input: DeployGateLayerInput): Layer<Env> {\n const requireArtifact = input.requireArtifact ?? true\n return {\n name: input.name ?? 'deploy',\n dependsOn: input.dependsOn ?? ['build'],\n weight: input.weight ?? 1,\n capMs: input.capMs ?? 120_000,\n run: async (ctx) => {\n const start = Date.now()\n let runner: DeployRunner\n try {\n runner = await input.runner()\n } catch (err) {\n return {\n layer: input.name ?? 'deploy',\n status: 'error',\n durationMs: Date.now() - start,\n findings: [\n {\n severity: 'major',\n message: `deploy runner failed to start: ${err instanceof Error ? err.message : String(err)}`,\n },\n ],\n reason: 'runner-init-failed',\n }\n }\n let result: DeployRunResult\n try {\n result = await runner.run()\n } catch (err) {\n return {\n layer: input.name ?? 'deploy',\n status: 'error',\n durationMs: Date.now() - start,\n findings: [\n {\n severity: 'major',\n message: `deploy command threw: ${err instanceof Error ? err.message : String(err)}`,\n },\n ],\n reason: 'runner-throw',\n }\n }\n if (ctx.signal.aborted) {\n return {\n layer: input.name ?? 'deploy',\n status: 'timeout',\n durationMs: Date.now() - start,\n findings: [],\n reason: 'aborted by overall cap',\n }\n }\n\n const artifactOk = !requireArtifact || result.artifactValid === true\n const pass = result.ok && artifactOk\n const findings: LayerResult['findings'] = []\n if (!result.ok) {\n findings.push({\n severity: 'critical',\n message: 'deploy build exited non-zero',\n evidence: (result.output ?? '').slice(-1200),\n })\n }\n if (result.ok && requireArtifact && !result.artifactValid) {\n findings.push({\n severity: 'major',\n message: `deploy build succeeded but artifact ${result.artifactDir ?? '(unknown)'} is invalid or empty`,\n })\n }\n return {\n layer: input.name ?? 'deploy',\n status: pass ? 'pass' : 'fail',\n score: pass ? 1 : 0,\n durationMs: Date.now() - start,\n findings,\n reason: pass\n ? `deploy build OK${input.family ? ` (${input.family})` : ''}${result.artifactDir ? ` → ${result.artifactDir}` : ''}`\n : !result.ok\n ? 'build command failed'\n : 'artifact missing or invalid',\n diagnostics: {\n deployBuildOk: result.ok ? 1 : 0,\n deployArtifactOk: result.artifactValid === true ? 1 : 0,\n deployBuildMs: result.durationMs ?? null,\n },\n }\n },\n }\n}\n\n// ─── Canonical vite runner ──────────────────────────────────────────────\n\nexport interface ViteDeployRunnerInput {\n /** Workdir to build. The runner cd's here. */\n workdir: string\n /**\n * Function to run a shell command in `workdir`. Same shape as\n * agent-eval's CommandRunner.run for compositional reuse.\n */\n exec: (\n cmd: string,\n opts?: { cwd?: string; timeoutMs?: number },\n ) => Promise<{ stdout: string; stderr: string; exitCode: number }>\n /**\n * Function to test whether a path exists in the workdir. Inject\n * `(p) => existsSync(join(workdir, p))` for host runs.\n */\n exists: (relativePath: string) => boolean | Promise<boolean>\n /** Build command. Default `npm run build`. */\n buildCommand?: string\n /** Artifact directory to validate. Default `dist`. */\n artifactDir?: string\n /** Entry-point file under artifactDir. Default `index.html`. */\n artifactEntry?: string\n /** Per-build cap (ms). Default 90s. */\n timeoutMs?: number\n}\n\n/**\n * Canonical runner for `frontend-static` family — runs the build script,\n * validates `<artifactDir>/<artifactEntry>` exists. Use as the `runner:`\n * factory for {@link deployGateLayer}.\n */\nexport function viteDeployRunner(input: ViteDeployRunnerInput): DeployRunner {\n return {\n run: async () => {\n const start = Date.now()\n const cmd = input.buildCommand ?? 'npm run build'\n const artifactDir = input.artifactDir ?? 'dist'\n const artifactEntry = input.artifactEntry ?? 'index.html'\n const timeoutMs = input.timeoutMs ?? 90_000\n const result = await input.exec(cmd, { cwd: input.workdir, timeoutMs })\n const ok = result.exitCode === 0\n let artifactValid = false\n try {\n const entryExists = await input.exists(`${artifactDir}/${artifactEntry}`)\n artifactValid = ok && Boolean(entryExists)\n } catch {\n artifactValid = false\n }\n const tail = ((result.stderr || result.stdout) ?? '').slice(-1500)\n return {\n ok,\n output: tail,\n durationMs: Date.now() - start,\n artifactDir,\n artifactValid,\n }\n },\n }\n}\n\n// ─── Canonical wrangler runner ──────────────────────────────────────────\n\nexport interface WranglerDeployRunnerInput {\n workdir: string\n exec: (\n cmd: string,\n opts?: { cwd?: string; timeoutMs?: number },\n ) => Promise<{ stdout: string; stderr: string; exitCode: number }>\n exists: (relativePath: string) => boolean | Promise<boolean>\n /** Build command. Default `npm run build`. */\n buildCommand?: string\n /** Wrangler dry-run command. Default `npx wrangler deploy --dry-run --outdir dist`. */\n dryRunCommand?: string\n /** Per-step cap (ms). Default 120s. */\n timeoutMs?: number\n}\n\n/**\n * Canonical runner for the `fullstack-ts` family on Cloudflare Workers\n * (Remix / React Router v7 / Hono on Workers). Detects wrangler.toml or\n * wrangler.jsonc in the workdir, builds, then `wrangler deploy --dry-run`\n * to catch missing bindings, syntax errors in wrangler config, and\n * import-time crashes that don't surface in `tsc`.\n *\n * No wrangler config = skip with \"no wrangler\" evidence (not a failure\n * — the gate caller decides whether to require deploy validation).\n */\nexport function wranglerDeployRunner(input: WranglerDeployRunnerInput): DeployRunner {\n return {\n run: async () => {\n const start = Date.now()\n const buildCmd = input.buildCommand ?? 'npm run build'\n const dryCmd = input.dryRunCommand ?? 'npx wrangler deploy --dry-run --outdir dist'\n const timeoutMs = input.timeoutMs ?? 120_000\n\n const hasToml = await input.exists('wrangler.toml')\n const hasJsonc = hasToml ? false : await input.exists('wrangler.jsonc')\n if (!hasToml && !hasJsonc) {\n return {\n ok: false,\n output: 'no wrangler config found (wrangler.toml / wrangler.jsonc absent)',\n durationMs: Date.now() - start,\n artifactDir: 'dist',\n artifactValid: false,\n }\n }\n\n const build = await input.exec(buildCmd, { cwd: input.workdir, timeoutMs })\n if (build.exitCode !== 0) {\n const tail = ((build.stderr || build.stdout) ?? '').slice(-1500)\n return {\n ok: false,\n output: `build failed: ${tail}`,\n durationMs: Date.now() - start,\n artifactDir: 'dist',\n artifactValid: false,\n }\n }\n\n const dry = await input.exec(dryCmd, { cwd: input.workdir, timeoutMs })\n if (dry.exitCode !== 0) {\n const tail = ((dry.stderr || dry.stdout) ?? '').slice(-1500)\n return {\n ok: false,\n output: `wrangler dry-run failed: ${tail}`,\n durationMs: Date.now() - start,\n artifactDir: 'dist',\n artifactValid: false,\n }\n }\n\n const tail = ((dry.stdout || dry.stderr) ?? '').slice(-1500)\n return {\n ok: true,\n output: tail,\n durationMs: Date.now() - start,\n artifactDir: 'dist',\n artifactValid: true,\n }\n },\n }\n}\n","/**\n * Toolchain error-count extractor.\n *\n * Given stderr/stdout from a compiler or test runner, count the number\n * of reported errors/failures. Patterns are deliberately narrow —\n * unknown stderr returns `null` rather than zero so callers can\n * distinguish \"no errors\" from \"different toolchain, couldn't parse\".\n *\n * All patterns are anchored to the start of a line and use bounded\n * character classes to avoid catastrophic backtracking on pathological\n * inputs.\n *\n * Add new toolchains by appending to {@link ERROR_COUNT_PATTERNS};\n * order matters only in the sense that the first matching pattern wins.\n */\n\nexport interface ErrorCountPattern {\n /** Stable identifier for logging + tests. */\n name: string\n /** Must be global (`g` flag) — the extractor counts matches. */\n regex: RegExp\n /** Optional post-processing to extract a count from a single captured match. */\n transform?: (match: RegExpMatchArray) => number\n}\n\nexport const ERROR_COUNT_PATTERNS: ErrorCountPattern[] = [\n {\n // tsc / ts-node: `src/foo.ts(12,3): error TS1234: ...`\n name: 'typescript-tsc',\n regex: /[\\w./-]+\\(\\d+,\\d+\\): error TS\\d+:/g,\n },\n {\n // pytest: `FAILED tests/test_foo.py::test_bar`\n name: 'pytest-failed',\n regex: /^FAILED\\s+\\S+/gm,\n },\n {\n // rustc: `error[E0308]: ...` or `error: ...`\n name: 'rustc',\n regex: /^error(?:\\[[A-Z]\\d+\\])?:/gm,\n },\n {\n // go build: `./foo.go:12:3: ...` — any file:line:col: is an error line\n name: 'golang',\n regex: /^\\.\\/[\\w./-]+\\.go:\\d+:\\d+:/gm,\n },\n {\n // eslint default formatter per-line: ` 12:34 error message rule-id`\n name: 'eslint',\n regex: /^\\s+\\d+:\\d+\\s+error\\s+/gm,\n },\n {\n // eslint summary line: `✖ 17 problems (12 errors, 5 warnings)`\n // Use this only when the per-line formatter isn't present; transform\n // reads the errors count directly.\n name: 'eslint-summary',\n regex: /✖\\s+\\d+\\s+problems?\\s+\\((\\d+)\\s+errors?/gm,\n transform: (m) => Number(m[1] ?? 0),\n },\n]\n\nexport interface ExtractOptions {\n /** Restrict to named patterns — default: all patterns. */\n only?: string[]\n /** Additional patterns to consider BEFORE the built-in list. */\n extra?: ErrorCountPattern[]\n}\n\nexport interface ExtractResult {\n /** Total count of matched errors, or null when no pattern matched. */\n count: number | null\n /** Name of the pattern that matched, or null. */\n matched: string | null\n /** Original matches for callers that want to surface specifics. */\n samples: string[]\n}\n\n/**\n * Try each pattern in order; return the first with matches.\n *\n * Returning `null` (instead of zero) on no-match is deliberate — a\n * callsite that greps for \"typescript errors\" on cargo output should\n * NOT treat that as \"zero TS errors\" because the toolchain is wrong.\n */\nexport function extractErrorCount(text: string, opts: ExtractOptions = {}): ExtractResult {\n if (!text) return { count: null, matched: null, samples: [] }\n\n const patterns = [...(opts.extra ?? []), ...ERROR_COUNT_PATTERNS].filter(\n (p) => !opts.only || opts.only.includes(p.name),\n )\n\n for (const p of patterns) {\n const matches = Array.from(text.matchAll(p.regex))\n if (matches.length === 0) continue\n\n const count = p.transform\n ? matches.reduce((sum, m) => sum + p.transform!(m), 0)\n : matches.length\n\n return {\n count,\n matched: p.name,\n samples: matches.slice(0, 5).map((m) => m[0]),\n }\n }\n\n return { count: null, matched: null, samples: [] }\n}\n","/**\n * Flow layer — drive a previewed app through a scripted user walk.\n *\n * The MultiLayerVerifier already had a `flow` slot wired in\n * VerticalBench's verification-harness, but the layer module was\n * always-skipped (\"flow layer module not yet wired\"). This adds the\n * module: a Layer<Env> that takes a {@link FlowSpec} (URL + steps),\n * boots a preview server via the supplied {@link FlowRunner}, executes\n * each step, and returns a LayerResult whose `findings` enumerate\n * which step failed.\n *\n * The runner is injected so this module can swap between:\n * - production: agent-browser CLI (a11y-tree based steps)\n * - test: in-memory mock that returns canned step outcomes\n * - future: Playwright, Puppeteer, custom scrapers\n *\n * Paired with {@link runIntentMatchJudge}: intent-match catches \"wrong\n * app entirely\"; flow-layer catches \"right app but the buttons don't work.\"\n */\n\nimport type { Layer, LayerResult, Severity } from './multi-layer-verifier'\n\n// ─── Types ──────────────────────────────────────────────────────────────\n\nexport type FlowAction =\n | 'navigate'\n | 'click'\n | 'fill'\n | 'expect-text'\n | 'expect-element'\n | 'expect-url'\n | 'wait'\n\nexport interface FlowStep {\n /** What this step does. */\n action: FlowAction\n /** Human-readable description for findings. */\n describe?: string\n /**\n * For navigate/expect-url: full URL. For click/fill/expect-element:\n * accessible-name selector or CSS selector.\n * For expect-text: substring expected on the page.\n * For wait: ignored (use `value` for ms).\n */\n target?: string\n /** For fill: text to enter. For wait: ms. */\n value?: string\n /** Severity of a failure. Default `major`. */\n severity?: Severity\n}\n\nexport interface FlowSpec {\n /** Initial URL the runner should open. */\n url: string\n /** Ordered steps. Stops at the first failure unless `continueOnFail: true`. */\n steps: FlowStep[]\n /** When true, execute every step even after a failure (collect all findings). */\n continueOnFail?: boolean\n /** Per-step wall cap (ms). Default 15s. */\n stepTimeoutMs?: number\n}\n\nexport interface FlowRunnerStepResult {\n ok: boolean\n /** Concrete observation: matched text snippet, captured URL, error message. */\n evidence?: string\n /** Wall-clock duration of the step. */\n durationMs?: number\n}\n\nexport interface FlowRunner {\n /** Open the target URL. Returns when the page is interactable. */\n open(url: string): Promise<FlowRunnerStepResult>\n /** Execute one step. The runner owns interpretation of `target`. */\n step(step: FlowStep): Promise<FlowRunnerStepResult>\n /** Tear down browser, free resources. Always called once per layer.run. */\n close(): Promise<void>\n}\n\nexport interface FlowLayerEnv {\n /** Optional override per-call. Defaults supplied by the layer factory. */\n flowSpec?: FlowSpec\n}\n\nexport interface FlowLayerFactoryInput {\n /** Static spec (used when env doesn't supply one). */\n flowSpec?: FlowSpec\n /** Build the runner per call (lets the layer create + tear down per leaf). */\n runner: () => FlowRunner | Promise<FlowRunner>\n /** Layer name. Default `flow`. */\n name?: string\n /** Layer dependencies — default `['serve']` so a non-booting preview skips us. */\n dependsOn?: string[]\n /** Layer weight for blendedScore (0..1+). Default 1. */\n weight?: number\n /** Cap for the entire flow run (ms). Default 60s. */\n capMs?: number\n}\n\n// ─── Layer factory ──────────────────────────────────────────────────────\n\n/**\n * Build a flow layer that scripts a user walk via the supplied runner.\n *\n * Score: 1.0 when every step passed; otherwise 1 - (failedSteps / totalSteps).\n * Status: `pass` iff every step passed; `fail` if any step failed; `error`\n * on runner setup error; `skipped` when no flowSpec is available.\n */\nexport function flowLayer<Env extends FlowLayerEnv = FlowLayerEnv>(\n input: FlowLayerFactoryInput,\n): Layer<Env> {\n return {\n name: input.name ?? 'flow',\n dependsOn: input.dependsOn ?? ['serve'],\n weight: input.weight ?? 1,\n capMs: input.capMs ?? 60_000,\n run: async (ctx) => {\n const start = Date.now()\n const spec = ctx.env?.flowSpec ?? input.flowSpec\n if (!spec) {\n return {\n layer: input.name ?? 'flow',\n status: 'skipped',\n durationMs: 0,\n findings: [],\n reason: 'no flowSpec supplied',\n }\n }\n\n let runner: FlowRunner\n try {\n runner = await input.runner()\n } catch (err) {\n return {\n layer: input.name ?? 'flow',\n status: 'error',\n durationMs: Date.now() - start,\n findings: [\n {\n severity: 'major',\n message: `flow runner failed to start: ${err instanceof Error ? err.message : String(err)}`,\n },\n ],\n reason: 'runner-init-failed',\n }\n }\n\n const findings: LayerResult['findings'] = []\n const stepResults: Array<{ step: FlowStep; result: FlowRunnerStepResult; index: number }> = []\n let openOk = false\n try {\n const opened = await runner.open(spec.url)\n openOk = opened.ok\n if (!opened.ok) {\n findings.push({\n severity: 'major',\n message: `flow.open(${spec.url}) failed${opened.evidence ? `: ${opened.evidence}` : ''}`,\n })\n }\n if (openOk || spec.continueOnFail) {\n for (let i = 0; i < spec.steps.length; i++) {\n const step = spec.steps[i]!\n if (ctx.signal.aborted) break\n const stepStart = Date.now()\n let result: FlowRunnerStepResult\n try {\n result = await runner.step(step)\n } catch (err) {\n result = {\n ok: false,\n evidence: err instanceof Error ? err.message : String(err),\n durationMs: Date.now() - stepStart,\n }\n }\n stepResults.push({ step, result, index: i })\n if (!result.ok) {\n findings.push({\n severity: step.severity ?? 'major',\n message: `step[${i}] ${step.action}${step.target ? `(${step.target})` : ''} failed${result.evidence ? `: ${result.evidence}` : ''}`,\n })\n if (!spec.continueOnFail) break\n }\n }\n }\n } finally {\n try {\n await runner.close()\n } catch {\n /* best effort */\n }\n }\n\n const totalSteps = spec.steps.length\n const ranSteps = stepResults.length\n const passedSteps = stepResults.filter((s) => s.result.ok).length\n const status: LayerResult['status'] = !openOk\n ? 'fail'\n : passedSteps === totalSteps\n ? 'pass'\n : 'fail'\n // Score: open + each passing step contribute equally. A flow with\n // 4 steps where 3 pass scores 4/5 = 0.8 (0.2 from the open + 3*0.2\n // from the steps when totalSteps=4). We weight open and steps\n // equally to avoid any single step dominating short specs.\n const denominator = 1 + totalSteps\n const numerator = (openOk ? 1 : 0) + passedSteps\n const score = denominator > 0 ? Number((numerator / denominator).toFixed(3)) : 0\n\n return {\n layer: input.name ?? 'flow',\n status,\n score,\n durationMs: Date.now() - start,\n findings,\n reason:\n status === 'pass'\n ? `${totalSteps}/${totalSteps} steps passed`\n : `${passedSteps}/${totalSteps} steps passed${ranSteps < totalSteps ? ` (stopped at step ${ranSteps})` : ''}`,\n diagnostics: {\n flowOpenOk: openOk ? 1 : 0,\n flowStepsTotal: totalSteps,\n flowStepsPassed: passedSteps,\n flowStepsRan: ranSteps,\n },\n }\n },\n }\n}\n","/**\n * Intent-match judge — \"did the agent build the right APP, ignoring\n * whether every feature is wired up?\"\n *\n * Distinct from {@link runSemanticConceptJudge} which scores per-concept\n * presence. The semantic judge can return 0/4 concepts present even\n * when the agent built a thoughtful, polished, on-brief app that just\n * lacks one or two features. The semantic judge can also return 4/4\n * present even when the agent shipped the wrong project (keyword-rich\n * stub).\n *\n * Intent-match asks ONE question:\n * \"Looking at the agent's work as a whole — independent of feature\n * coverage — is this an honest attempt at the user's request?\"\n *\n * Returns a 0–1 score and a 1-sentence evidence string. Use as a sanity\n * check on `completenessScore`-style metrics: if intent-match is high\n * and concept count is low, the agent built the right thing but is\n * missing features (ship and iterate). If intent-match is low, the\n * agent built the wrong thing (reject regardless of concept count).\n *\n * Soft-fails on LLM/JSON error (`available: false`) so callers can\n * treat failure as \"judge skipped.\"\n */\n\nimport { callLlmJson, type LlmClientOptions } from './llm-client'\n\nexport const INTENT_MATCH_JUDGE_VERSION = 'intent-match-judge-v1-2026-04-24'\n\nexport interface IntentMatchInput {\n /** The full natural-language prompt the agent was handed. */\n userRequest: string\n /** Top-level source files from the agent's workdir. */\n sourceFiles: Array<{ path: string; content: string }>\n /** Rendered HTML the preview returned, when available. */\n servedHtml?: string\n /** Optional metadata to inject (id, vertical, difficulty). */\n artifactLabel?: string\n artifactDescription?: string\n}\n\nexport interface IntentMatchResult {\n kind: 'intent-match'\n version: string\n /** 0..1 — 1 = unmistakably the right app, 0 = unrelated to the brief. */\n score: number\n /** One-sentence rationale citing concrete evidence (file or HTML). */\n evidence: string\n durationMs: number\n costUsd: number | null\n available: boolean\n error?: string\n}\n\nexport interface IntentMatchOptions {\n model?: string\n timeoutMs?: number\n maxSourceChars?: number\n maxPerFileChars?: number\n maxHtmlChars?: number\n llm?: LlmClientOptions\n}\n\nconst DEFAULT_MODEL = 'claude-sonnet-4-6'\nconst DEFAULT_TIMEOUT = 90_000\nconst DEFAULT_MAX_SOURCE = 25_000\nconst DEFAULT_MAX_PER_FILE = 12_000\nconst DEFAULT_MAX_HTML = 20_000\n\nconst INTENT_SCHEMA = {\n type: 'object',\n additionalProperties: false,\n required: ['score', 'evidence'],\n properties: {\n score: { type: 'number', minimum: 0, maximum: 1 },\n evidence: { type: 'string', minLength: 10, maxLength: 400 },\n },\n}\n\nfunction truncate(body: string, cap: number, label: string): string {\n if (body.length <= cap) return body\n return `${body.slice(0, cap)}\\n… [truncated ${body.length - cap} chars of ${label}]`\n}\n\nfunction buildPrompt(input: IntentMatchInput, opts: Required<IntentMatchOptions>): string {\n const sourceBlob = input.sourceFiles\n .filter((f) => f.content.length <= opts.maxPerFileChars)\n .map((f) => `--- FILE: ${f.path} ---\\n${f.content}`)\n .join('\\n\\n')\n const html = input.servedHtml ?? ''\n\n return `You are evaluating whether an agent built THE RIGHT APP for a user request.\n\nYou are NOT scoring feature coverage. You are NOT scoring code quality.\nYou are answering ONE question: when a person looks at this work, do they\nsee an honest attempt at the user's request — or do they see the wrong\nproject entirely?\n\nUSER REQUEST:\n${input.userRequest}\n\n${input.artifactLabel ? `ARTIFACT METADATA:\\n name: ${input.artifactLabel}\\n description: ${input.artifactDescription ?? ''}\\n\\n` : ''}${html ? `SERVED HTML (what the preview returns):\\n${truncate(html, opts.maxHtmlChars, 'HTML')}\\n\\n` : ''}SOURCE FILES (the agent's workdir):\n${truncate(sourceBlob, opts.maxSourceChars, 'source')}\n\nScore 0–1:\n 1.0 — unmistakably the right app. Even with bugs, gaps, or missing\n features, a reviewer would say \"yes, this is what was asked for.\"\n 0.7 — recognizable. Domain matches; some required surface areas exist.\n A reviewer would say \"right direction, lots of work needed.\"\n 0.4 — partially related. Wrong framing or wrong product entirely but\n with some shared keywords or a tangential overlap.\n 0.0 — wrong project. The agent shipped something unrelated to the\n request (e.g. asked for an NFT mint page, shipped a generic\n landing page with zero NFT-related code).\n\nEvidence: one sentence citing the strongest concrete signal — a file\nname, a route, a rendered headline, a missing core surface. Don't\nrestate the request.\n\nExamples:\n - \"src/App.tsx renders <MintWidget /> with mint-1/mint-5 buttons and\n wagmi imports — clearly the requested NFT mint page.\" → 0.95\n - \"src/App.tsx is the default Vite React template; no\n mint/wallet/contract code in any file under src/.\" → 0.05\n\nReturn STRICT JSON. No prose outside.`\n}\n\n/**\n * Run the intent-match judge. Soft-fails to available=false on error.\n */\nexport async function runIntentMatchJudge(\n input: IntentMatchInput,\n options: IntentMatchOptions = {},\n): Promise<IntentMatchResult> {\n const start = Date.now()\n const opts: Required<IntentMatchOptions> = {\n model: options.model ?? DEFAULT_MODEL,\n timeoutMs: options.timeoutMs ?? DEFAULT_TIMEOUT,\n maxSourceChars: options.maxSourceChars ?? DEFAULT_MAX_SOURCE,\n maxPerFileChars: options.maxPerFileChars ?? DEFAULT_MAX_PER_FILE,\n maxHtmlChars: options.maxHtmlChars ?? DEFAULT_MAX_HTML,\n llm: options.llm ?? {},\n }\n\n if (input.sourceFiles.length === 0 && !input.servedHtml) {\n return {\n kind: 'intent-match',\n version: INTENT_MATCH_JUDGE_VERSION,\n score: 0,\n evidence: 'no source files and no served HTML — nothing to evaluate',\n durationMs: 0,\n costUsd: null,\n available: false,\n error: 'no input artifact',\n }\n }\n\n try {\n const { value, result } = await callLlmJson<{ score: number; evidence: string }>(\n {\n model: opts.model,\n messages: [\n {\n role: 'system',\n content:\n 'You are a holistic code reviewer answering one question: did the agent build the right app for the user. Return strict JSON. No prose outside.',\n },\n { role: 'user', content: buildPrompt(input, opts) },\n ],\n jsonSchema: { name: 'intent_match_judge', schema: INTENT_SCHEMA },\n temperature: 0,\n timeoutMs: opts.timeoutMs,\n },\n opts.llm,\n )\n\n const score = Math.max(0, Math.min(1, Number(value?.score ?? 0)))\n return {\n kind: 'intent-match',\n version: INTENT_MATCH_JUDGE_VERSION,\n score: Number(score.toFixed(3)),\n evidence: String(value?.evidence ?? '').slice(0, 400),\n durationMs: Date.now() - start,\n costUsd: result.costUsd ?? null,\n available: true,\n }\n } catch (err) {\n return {\n kind: 'intent-match',\n version: INTENT_MATCH_JUDGE_VERSION,\n score: 0,\n evidence: '',\n durationMs: Date.now() - start,\n costUsd: null,\n available: false,\n error: err instanceof Error ? err.message : String(err),\n }\n }\n}\n\n/**\n * Factory: pin LLM options once, return a closure.\n */\nexport function createIntentMatchJudge(\n options: IntentMatchOptions = {},\n): (input: IntentMatchInput) => Promise<IntentMatchResult> {\n return (input) => runIntentMatchJudge(input, options)\n}\n","/**\n * Keyword-coverage judge — baseline complement to the semantic concept\n * judge.\n *\n * Where {@link runSemanticConceptJudge} uses an LLM to read source code\n * and decide whether a concept is REALLY implemented (not just\n * keyword-mentioned), this judge does the cheap, deterministic version:\n * fetch the served preview, concatenate every linked CSS/JS asset, and\n * substring-match each expected concept's keywords against the\n * concatenated haystack. Optional `requiredElement` selector adds a\n * structural gate so \"supply counter\" can require an actual `<input>` or\n * `<table>`, not just a comment containing the word.\n *\n * Use both judges. Keyword coverage is a fast 0-cost gate — a stub page\n * with the right keywords passes here, fails the semantic judge. Score\n * divergence between the two is itself a signal: high keyword coverage\n * + low semantic = \"the agent slapped the right words on the right\n * scaffold but didn't wire any of it up.\"\n *\n * Pure functions, soft-fail on fetch error, no LLM dependency.\n */\n\n// ─── Types ──────────────────────────────────────────────────────────────\n\nexport interface KeywordConceptSpec {\n name: string\n keywords: string[]\n /**\n * Optional CSS selector that must match in the HTML for the concept\n * to count as present. Tiny subset:\n * - `tag` (e.g. `form`)\n * - `tag[attr=\"value\"]` (e.g. `input[type=\"number\"]`)\n * - `tag[attr]` (presence only)\n * Anything more complex is rejected with `null` (treated as\n * \"unenforced\", not \"failed\").\n */\n requiredElement?: string\n}\n\nexport interface KeywordCoverageFinding {\n concept: string\n found: boolean\n matchedKeywords: string[]\n /** True iff the optional requiredElement selector matched; null when no selector. */\n requiredElementPresent: boolean | null\n}\n\nexport interface KeywordCoverageResult {\n /** 0..1 share of concepts satisfied. */\n score: number\n presentCount: number\n totalCount: number\n findings: KeywordCoverageFinding[]\n durationMs: number\n /** Total bytes assembled across html + linked assets. */\n totalAssembledBytes: number\n /** Soft-failure reason if the audit couldn't run. */\n error?: string\n}\n\nexport interface KeywordCoverageOptions {\n /** Override fetch implementation — for tests. */\n fetch?: typeof fetch\n /** Per-asset fetch timeout (default 3s). */\n assetTimeoutMs?: number\n /** Initial-HTML fetch timeout (default 5s). */\n htmlTimeoutMs?: number\n}\n\n// ─── Selector matcher ──────────────────────────────────────────────────\n\n/**\n * Element-presence check using a tiny CSS-selector subset. Returns\n * null when the selector isn't supported — caller treats that as\n * \"unenforced\" rather than \"failed.\"\n */\nexport function htmlContainsElement(html: string, selector: string): boolean | null {\n const tagOnly = /^([a-zA-Z][\\w-]*)$/.exec(selector)\n if (tagOnly) {\n const re = new RegExp(`<${tagOnly[1]}\\\\b`, 'i')\n return re.test(html)\n }\n const tagAttrEq = /^([a-zA-Z][\\w-]*)\\[([\\w-]+)\\s*=\\s*[\"']?([^\"'\\]]+)[\"']?\\]$/.exec(selector)\n if (tagAttrEq) {\n const [, tag, attr, value] = tagAttrEq\n const re = new RegExp(\n `<${tag}\\\\b[^>]*\\\\b${attr}\\\\s*=\\\\s*[\"']${value!.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')}[\"']`,\n 'i',\n )\n return re.test(html)\n }\n const tagAttrPresence = /^([a-zA-Z][\\w-]*)\\[([\\w-]+)\\]$/.exec(selector)\n if (tagAttrPresence) {\n const [, tag, attr] = tagAttrPresence\n const re = new RegExp(`<${tag}\\\\b[^>]*\\\\b${attr}\\\\b`, 'i')\n return re.test(html)\n }\n return null\n}\n\n// ─── Asset extraction ─────────────────────────────────────────────────\n\n/**\n * Pull every `<link rel=stylesheet href>` and `<script src>` from a\n * raw HTML body. Returns absolute URLs resolved against `baseUrl`.\n * Permissive regex — agent-authored markup doesn't always quote\n * attributes the same way.\n */\nexport function extractAssetUrls(html: string, baseUrl: string): string[] {\n const urls = new Set<string>()\n const linkRe = /<link\\b[^>]*\\bhref\\s*=\\s*[\"']([^\"']+)[\"'][^>]*>/gi\n const scriptRe = /<script\\b[^>]*\\bsrc\\s*=\\s*[\"']([^\"']+)[\"'][^>]*>/gi\n for (const re of [linkRe, scriptRe]) {\n let match: RegExpExecArray | null\n while ((match = re.exec(html)) !== null) {\n const raw = match[1]!\n try {\n urls.add(new URL(raw, baseUrl).toString())\n } catch {\n // unresolvable refs (e.g. data: URLs) — skip\n }\n }\n }\n return Array.from(urls)\n}\n\n// ─── Coverage scorer ──────────────────────────────────────────────────\n\n/**\n * Score expected concepts against an already-fetched HTML payload + any\n * pre-fetched CSS/JS assets. Use when the runner has the bytes in hand\n * and doesn't want a fresh HTTP round-trip — e.g. sandbox runtime where\n * the preview content was fetched via curl from inside the container.\n */\nexport function runKeywordCoverageJudge(\n html: string,\n expectedConcepts: ReadonlyArray<KeywordConceptSpec>,\n assets: ReadonlyArray<string> = [],\n): KeywordCoverageResult {\n const start = Date.now()\n if (expectedConcepts.length === 0) {\n return {\n score: 0,\n presentCount: 0,\n totalCount: 0,\n findings: [],\n durationMs: 0,\n totalAssembledBytes: 0,\n }\n }\n const haystack = `${html}\\n${assets.join('\\n')}`.toLowerCase()\n const findings: KeywordCoverageFinding[] = expectedConcepts.map((concept) => {\n const matchedKeywords: string[] = []\n for (const kw of concept.keywords) {\n if (haystack.includes(kw.toLowerCase())) matchedKeywords.push(kw)\n }\n const requiredElementPresent = concept.requiredElement\n ? htmlContainsElement(html, concept.requiredElement)\n : null\n const passesElementGate = requiredElementPresent === null || requiredElementPresent === true\n const found = matchedKeywords.length > 0 && passesElementGate\n return { concept: concept.name, found, matchedKeywords, requiredElementPresent }\n })\n const presentCount = findings.filter((f) => f.found).length\n return {\n score: presentCount / expectedConcepts.length,\n presentCount,\n totalCount: expectedConcepts.length,\n findings,\n durationMs: Date.now() - start,\n totalAssembledBytes: haystack.length,\n }\n}\n\n/**\n * URL-fetch flavor — GET the preview, parallel-fetch every linked\n * stylesheet + script (with bounded timeouts, soft-fail individually),\n * then score via {@link runKeywordCoverageJudge}.\n */\nexport async function runKeywordCoverageJudgeUrl(\n previewUrl: string,\n expectedConcepts: ReadonlyArray<KeywordConceptSpec>,\n options: KeywordCoverageOptions = {},\n): Promise<KeywordCoverageResult> {\n const start = Date.now()\n const fetchFn = options.fetch ?? globalThis.fetch\n const htmlTimeout = options.htmlTimeoutMs ?? 5_000\n const assetTimeout = options.assetTimeoutMs ?? 3_000\n\n if (expectedConcepts.length === 0) {\n return {\n score: 0,\n presentCount: 0,\n totalCount: 0,\n findings: [],\n durationMs: 0,\n totalAssembledBytes: 0,\n }\n }\n\n let html = ''\n try {\n const resp = await fetchFn(previewUrl, {\n redirect: 'follow',\n signal: AbortSignal.timeout(htmlTimeout),\n })\n if (!resp.ok) {\n return softFail(expectedConcepts, start, `preview HTTP ${resp.status}`)\n }\n html = await resp.text()\n } catch (err) {\n return softFail(expectedConcepts, start, err instanceof Error ? err.message : String(err))\n }\n\n const assetUrls = extractAssetUrls(html, previewUrl)\n const assetBodies = await Promise.all(\n assetUrls.map(async (u) => {\n try {\n const r = await fetchFn(u, {\n redirect: 'follow',\n signal: AbortSignal.timeout(assetTimeout),\n })\n if (!r.ok) return ''\n return await r.text()\n } catch {\n return ''\n }\n }),\n )\n\n return runKeywordCoverageJudge(html, expectedConcepts, assetBodies)\n}\n\nfunction softFail(\n expectedConcepts: ReadonlyArray<KeywordConceptSpec>,\n start: number,\n error: string,\n): KeywordCoverageResult {\n return {\n score: 0,\n presentCount: 0,\n totalCount: expectedConcepts.length,\n findings: expectedConcepts.map((c) => ({\n concept: c.name,\n found: false,\n matchedKeywords: [],\n requiredElementPresent: null,\n })),\n durationMs: Date.now() - start,\n totalAssembledBytes: 0,\n error,\n }\n}\n","/**\n * Multi-layer verifier — ordered pipeline of verification layers.\n *\n * Different contract from {@link JudgeRunner} (which runs parallel\n * specs against a sandbox). MultiLayerVerifier is a DAG of layers\n * (install → typecheck → build → lint → serve → semantic → …) with\n * dependency-based skip, per-layer findings, soft-fail semantics, and\n * an aggregated `blendedScore` across all passed layers.\n *\n * Use when you want:\n * - ordered stages where a failing upstream stage skips downstream ones\n * - each stage produces rich `findings` (severity + message + evidence)\n * - a single composite score across stages with per-stage weights\n * - soft-fail stages whose failure doesn't abort the pipeline\n *\n * Use {@link JudgeRunner} when you want:\n * - N independent judges running in parallel against the same artifact\n * - no inter-judge dependencies\n * - boolean `passed` per judge + overall\n *\n * Both primitives compose — JudgeRunner can be invoked as a single\n * layer inside a MultiLayerVerifier if that suits the caller.\n */\n\n// ─── Types ──────────────────────────────────────────────────────────────\n\nexport type LayerStatus = 'pass' | 'fail' | 'skipped' | 'error' | 'timeout'\n\nexport type Severity = 'critical' | 'major' | 'minor' | 'info'\n\nexport interface Finding {\n severity: Severity\n message: string\n evidence?: string\n /** Optional layer name the finding belongs to (set by the verifier if omitted). */\n layer?: string\n /**\n * Free-form structured payload — used by `multiToolchainLayer` to attach\n * `{ adapter: 'pnpm' }`, by judges to attach evidence pointers, etc.\n * Renderers MAY interrogate; agent-eval primitives never assume shape.\n */\n detail?: Record<string, unknown>\n}\n\nexport interface LayerResult {\n layer: string\n status: LayerStatus\n /** 0..1 score, optional — layers that don't produce a numeric score omit. */\n score?: number\n durationMs: number\n findings: Finding[]\n /** Short human-readable summary (one line). */\n reason?: string\n /**\n * Numeric layer-level diagnostics: error counts, warning counts,\n * cyclomatic complexity, total adapter wall-time, etc. Keyed by\n * diagnostic name; null = \"diagnostic not applicable / not measured.\"\n * Renderers that know the keys can display them; ones that don't,\n * ignore. Free-form on purpose — consumers type the value shape in\n * their own namespace.\n */\n diagnostics?: Record<string, number | null>\n /** Any rich per-layer detail — rendered as-is by consumers that know the layer. */\n detail?: Record<string, unknown>\n}\n\nexport interface VerifyContext<Env = unknown> {\n /** Per-run opaque context the caller provides. Layers destructure what they need. */\n env: Env\n /** Previously-computed results from layers that already ran. */\n prior: Record<string, LayerResult>\n /** Signal — if aborted, layers MUST bail within reasonable wall. */\n signal: AbortSignal\n}\n\nexport interface Layer<Env = unknown> {\n name: string\n /** Stages that must have `status: 'pass'` before this layer runs. */\n dependsOn?: string[]\n /**\n * Weight in the composite `blendedScore`. Default 1.0. Layers with weight 0\n * contribute findings but not score.\n */\n weight?: number\n /**\n * If true, a `fail` status contributes to `blendedScore` (as 0) instead of\n * being dropped — use for layers whose failure is a real signal. Default:\n * fail drops from numerator + denominator, matching VB's existing semantics.\n */\n failContributesToScore?: boolean\n /** Optional per-layer wall-cap in ms. Honored by the verifier (AbortSignal). */\n capMs?: number\n run: (ctx: VerifyContext<Env>) => Promise<LayerResult> | LayerResult\n}\n\nexport interface VerifyOptions<Env = unknown> {\n env: Env\n /**\n * Overall wall cap. Default: sum of layer capMs, or Infinity if any layer\n * omits a cap. The verifier short-circuits remaining layers on overall cap.\n */\n overallCapMs?: number\n /** Called with each layer result as it completes. */\n onLayer?: (result: LayerResult) => void\n}\n\nexport interface VerificationReport {\n layers: LayerResult[]\n passCount: number\n failCount: number\n skippedCount: number\n errorCount: number\n /** True iff at least one scored layer ran AND every scored layer passed. */\n allPass: boolean\n /**\n * Weighted mean of `score` across contributing layers. 0 when no layers\n * contributed. See {@link Layer.failContributesToScore} for fail semantics.\n */\n blendedScore: number\n durationMs: number\n startedAt: string\n finishedAt: string\n}\n\n// ─── Helpers ────────────────────────────────────────────────────────────\n\n/**\n * Grade a semantic-concept-style judge result into a single layer status.\n *\n * Pass when overall score >= threshold AND no critical-severity concept gap.\n * Fail otherwise. Use inside a `Layer.run` when wrapping a concept judge.\n *\n * Generalized from VerticalBench H3 fix: `failingConcepts.length === 0` was\n * too strict — a single concept at 6/10 failed the entire layer despite\n * overall score being >= 0.7. Now we trust the judge's own `severity` field:\n * `critical` findings veto; `major`/`minor` reduce the score but don't veto.\n */\nexport function gradeSemanticStatus(input: {\n score: number\n findings: Array<{ severity: Severity; present?: boolean; score?: number }>\n available: boolean\n threshold?: number\n}): LayerStatus {\n if (!input.available) return 'error'\n const threshold = input.threshold ?? 0.7\n const criticalGaps = input.findings.filter(\n (f) => f.severity === 'critical' && (f.present === false || (f.score ?? 0) < 7),\n )\n return input.score >= threshold && criticalGaps.length === 0 ? 'pass' : 'fail'\n}\n\n// ─── Verifier ───────────────────────────────────────────────────────────\n\nexport class MultiLayerVerifier<Env = unknown> {\n constructor(private readonly layers: Layer<Env>[]) {\n const seen = new Set<string>()\n for (const l of layers) {\n if (seen.has(l.name)) throw new Error(`MultiLayerVerifier: duplicate layer name \"${l.name}\"`)\n seen.add(l.name)\n }\n for (const l of layers) {\n for (const dep of l.dependsOn ?? []) {\n if (!seen.has(dep)) {\n throw new Error(\n `MultiLayerVerifier: layer \"${l.name}\" depends on \"${dep}\" which is not registered`,\n )\n }\n }\n }\n }\n\n async run(opts: VerifyOptions<Env>): Promise<VerificationReport> {\n const startedAtMs = Date.now()\n const startedAt = new Date(startedAtMs).toISOString()\n const controller = new AbortController()\n const overallCap = opts.overallCapMs\n const overallTimer =\n overallCap != null\n ? setTimeout(() => controller.abort(new Error('overall cap exceeded')), overallCap)\n : null\n\n const results: LayerResult[] = []\n const byName: Record<string, LayerResult> = {}\n\n try {\n for (const layer of this.layers) {\n // Skip if any dependency didn't pass.\n const unmet = (layer.dependsOn ?? []).filter((d) => byName[d]?.status !== 'pass')\n if (unmet.length > 0) {\n const skipped: LayerResult = {\n layer: layer.name,\n status: 'skipped',\n durationMs: 0,\n findings: [],\n reason: `skipped — upstream not passing: ${unmet.join(', ')}`,\n }\n results.push(skipped)\n byName[layer.name] = skipped\n opts.onLayer?.(skipped)\n continue\n }\n\n // Per-layer cap — compose with overall signal.\n const perLayerController = new AbortController()\n const mergedSignal = mergeSignals(controller.signal, perLayerController.signal)\n const layerTimer =\n layer.capMs != null\n ? setTimeout(\n () => perLayerController.abort(new Error(`layer ${layer.name} cap`)),\n layer.capMs,\n )\n : null\n\n const layerStart = Date.now()\n let result: LayerResult\n try {\n result = await layer.run({ env: opts.env, prior: { ...byName }, signal: mergedSignal })\n } catch (err) {\n const aborted = mergedSignal.aborted\n result = {\n layer: layer.name,\n status: aborted ? 'timeout' : 'error',\n durationMs: Date.now() - layerStart,\n findings: [\n {\n severity: 'major',\n message: err instanceof Error ? err.message : String(err),\n layer: layer.name,\n },\n ],\n reason: err instanceof Error ? err.message : String(err),\n }\n } finally {\n if (layerTimer) clearTimeout(layerTimer)\n }\n\n // Normalize findings to attach layer name if omitted.\n result.findings = result.findings.map((f) => ({ ...f, layer: f.layer ?? layer.name }))\n results.push(result)\n byName[layer.name] = result\n opts.onLayer?.(result)\n\n if (controller.signal.aborted) break\n }\n\n const report = aggregate(this.layers, results, startedAt, startedAtMs)\n return report\n } finally {\n if (overallTimer) clearTimeout(overallTimer)\n }\n }\n}\n\nfunction aggregate<Env>(\n layers: Layer<Env>[],\n results: LayerResult[],\n startedAt: string,\n startedAtMs: number,\n): VerificationReport {\n const weightByName = new Map<string, number>()\n const failContribByName = new Map<string, boolean>()\n for (const l of layers) {\n weightByName.set(l.name, l.weight ?? 1)\n failContribByName.set(l.name, l.failContributesToScore ?? false)\n }\n\n let passCount = 0\n let failCount = 0\n let skippedCount = 0\n let errorCount = 0\n let scoredWeightSum = 0\n let scoredWeightedTotal = 0\n let ranAnyScoredLayer = false\n let anyScoredLayerFailed = false\n\n for (const r of results) {\n const weight = weightByName.get(r.layer) ?? 1\n const failContrib = failContribByName.get(r.layer) ?? false\n if (r.status === 'pass') passCount++\n else if (r.status === 'fail') failCount++\n else if (r.status === 'skipped') skippedCount++\n else errorCount++\n\n if (r.score != null && weight > 0) {\n if (r.status === 'pass') {\n ranAnyScoredLayer = true\n scoredWeightSum += weight\n scoredWeightedTotal += weight * r.score\n } else if (r.status === 'fail') {\n if (failContrib) {\n ranAnyScoredLayer = true\n scoredWeightSum += weight\n scoredWeightedTotal += weight * r.score\n }\n anyScoredLayerFailed = true\n }\n // skipped / error / timeout layers don't contribute\n } else if (r.status === 'fail') {\n anyScoredLayerFailed = true\n }\n }\n\n const finishedAtMs = Date.now()\n return {\n layers: results,\n passCount,\n failCount,\n skippedCount,\n errorCount,\n allPass: ranAnyScoredLayer && !anyScoredLayerFailed && failCount === 0 && errorCount === 0,\n blendedScore: scoredWeightSum > 0 ? scoredWeightedTotal / scoredWeightSum : 0,\n durationMs: finishedAtMs - startedAtMs,\n startedAt,\n finishedAt: new Date(finishedAtMs).toISOString(),\n }\n}\n\nfunction mergeSignals(a: AbortSignal, b: AbortSignal): AbortSignal {\n if (a.aborted) return a\n if (b.aborted) return b\n const c = new AbortController()\n const onAbort = (signal: AbortSignal) => () => c.abort(signal.reason)\n a.addEventListener('abort', onAbort(a), { once: true })\n b.addEventListener('abort', onAbort(b), { once: true })\n return c.signal\n}\n","/**\n * Multi-toolchain layer factory + merge helper.\n *\n * Some verification stages (install, typecheck, build, lint) run the\n * SAME logical layer across multiple parallel adapters — pnpm AND npm\n * AND cargo AND forge for a polyglot scaffold. The verifier presents\n * one row per stage; the toolchain breakdown lives in `findings.detail`.\n *\n * This module provides the merge: take N independent `LayerResult`s\n * (one per adapter) and reduce them to a single `LayerResult` whose\n * status is the worst of the parts and whose findings cite the adapter\n * that produced each one. Plus a {@link multiToolchainLayer} factory\n * that runs the adapter calls in parallel + applies the reducer.\n *\n * Pure utility — composes with {@link MultiLayerVerifier}.{run}.\n */\n\nimport type {\n Layer,\n LayerResult,\n LayerStatus,\n Severity,\n VerifyContext,\n} from './multi-layer-verifier'\n\n// ─── Status reduction ──────────────────────────────────────────────────\n\nconst STATUS_RANK: Record<LayerStatus, number> = {\n pass: 0,\n skipped: 1,\n fail: 2,\n timeout: 3,\n error: 4,\n}\n\nfunction worst(a: LayerStatus, b: LayerStatus): LayerStatus {\n return (STATUS_RANK[a] ?? 0) >= (STATUS_RANK[b] ?? 0) ? a : b\n}\n\nconst SEVERITY_RANK: Record<Severity, number> = {\n info: 0,\n minor: 1,\n major: 2,\n critical: 3,\n}\n\nfunction maxSeverity(findings: ReadonlyArray<{ severity: Severity }>): Severity {\n let best: Severity = 'info'\n for (const f of findings) {\n if (SEVERITY_RANK[f.severity] > SEVERITY_RANK[best]) best = f.severity\n }\n return best\n}\n\n// ─── Merge ──────────────────────────────────────────────────────────────\n\nexport interface AdapterRun {\n /** Identifier for the adapter (e.g. 'pnpm', 'npm', 'cargo', 'forge'). */\n adapter: string\n result: LayerResult\n}\n\nexport interface MergeOptions {\n /**\n * How to combine per-adapter `durationMs`. Default `'max'` (parallel\n * wall-clock). Set `'sum'` when reporting total work done across\n * adapters rather than wall time.\n */\n mergeDuration?: 'max' | 'sum'\n /**\n * Prefix finding messages with a per-adapter tag (e.g. `[pnpm] typecheck failed`).\n * Default: no prefix (renderers read `detail.adapter` instead).\n */\n messagePrefixer?: (adapter: string) => string\n /**\n * How to reduce per-adapter `LayerResult.diagnostics` into the merged\n * result's diagnostics. `'max'` (default) — for each key, merged =\n * max across adapters where value is non-null (matches \"if ANY adapter\n * saw N errors, merged saw N\"). `'sum'` — sum non-null values.\n */\n mergeDiagnostics?: 'max' | 'sum'\n}\n\n/**\n * Reduce N adapter runs to a single `LayerResult` for a logical layer.\n *\n * - status: worst of the parts (pass < skipped < fail < timeout < error)\n * - score: weighted mean of numeric scores (skip = no contribution)\n * - findings: union, each tagged with `detail.adapter`\n * - durationMs: `mergeDuration` option (default 'max' for parallel wall-clock)\n * - diagnostics: `mergeDiagnostics` option (default 'max' per key)\n * - reason: \" · \"-joined `name: status` per adapter\n */\nexport function mergeLayerResults(\n name: string,\n perAdapter: AdapterRun[],\n options: MergeOptions = {},\n): LayerResult {\n const mergeDuration = options.mergeDuration ?? 'max'\n const mergeDiagnostics = options.mergeDiagnostics ?? 'max'\n const prefix = options.messagePrefixer\n\n if (perAdapter.length === 0) {\n return {\n layer: name,\n status: 'skipped',\n durationMs: 0,\n findings: [],\n reason: 'no adapters',\n }\n }\n if (perAdapter.length === 1) {\n const only = perAdapter[0]!\n return {\n ...only.result,\n layer: name,\n findings: only.result.findings.map((f) => ({\n ...f,\n layer: name,\n message: prefix ? `${prefix(only.adapter)} ${f.message}` : f.message,\n detail: { ...(f.detail ?? {}), adapter: only.adapter },\n })),\n reason: only.result.reason ?? `${only.adapter}: ${only.result.status}`,\n }\n }\n\n let status: LayerStatus = 'pass'\n let weightedScoreSum = 0\n let weightCount = 0\n const findings: LayerResult['findings'] = []\n let durationMs = 0\n const reasonParts: string[] = []\n const diagnostics: Record<string, number | null> = {}\n\n for (const { adapter, result } of perAdapter) {\n status = worst(status, result.status)\n if (typeof result.score === 'number') {\n weightedScoreSum += result.score\n weightCount += 1\n }\n durationMs =\n mergeDuration === 'sum'\n ? durationMs + result.durationMs\n : Math.max(durationMs, result.durationMs)\n reasonParts.push(`${adapter}: ${result.status}`)\n for (const f of result.findings) {\n findings.push({\n ...f,\n layer: name,\n message: prefix ? `${prefix(adapter)} ${f.message}` : f.message,\n detail: { ...(f.detail ?? {}), adapter },\n })\n }\n for (const [k, v] of Object.entries(result.diagnostics ?? {})) {\n if (typeof v !== 'number' || !Number.isFinite(v)) continue\n const prev = diagnostics[k]\n if (prev == null) diagnostics[k] = v\n else diagnostics[k] = mergeDiagnostics === 'sum' ? prev + v : Math.max(prev, v)\n }\n }\n\n return {\n layer: name,\n status,\n score: weightCount > 0 ? weightedScoreSum / weightCount : undefined,\n durationMs,\n findings,\n reason: reasonParts.join(' · '),\n diagnostics: Object.keys(diagnostics).length > 0 ? diagnostics : undefined,\n detail: {\n adapters: perAdapter.map(({ adapter, result }) => ({\n adapter,\n status: result.status,\n score: result.score ?? null,\n })),\n worstSeverity: maxSeverity(findings),\n },\n }\n}\n\n// ─── Layer factory ──────────────────────────────────────────────────────\n\nexport interface MultiToolchainLayerConfig<Env, Adapter> {\n name: string\n adapters: ReadonlyArray<Adapter>\n /** Adapter identifier — used in findings + reason. */\n adapterName: (a: Adapter) => string\n /** Run a single adapter against the verify context. */\n run: (a: Adapter, ctx: VerifyContext<Env>) => Promise<LayerResult> | LayerResult\n dependsOn?: string[]\n weight?: number\n failContributesToScore?: boolean\n capMs?: number\n /**\n * Per-adapter parallel cap. Defaults to 8 — defense in depth against a\n * caller passing 50 adapters and fanning out 50 simultaneous subprocesses.\n * Adapters that need higher concurrency raise this explicitly.\n */\n maxParallel?: number\n}\n\n/**\n * Build a {@link Layer} that fans the same logical stage across N adapters\n * in parallel and merges via {@link mergeLayerResults}.\n *\n * Per-adapter throws are caught + converted to `status: 'error'` results\n * so one bad adapter doesn't poison the whole layer.\n */\nexport function multiToolchainLayer<Env, Adapter>(\n config: MultiToolchainLayerConfig<Env, Adapter>,\n): Layer<Env> {\n const maxParallel = Math.max(1, config.maxParallel ?? 8)\n return {\n name: config.name,\n dependsOn: config.dependsOn,\n weight: config.weight,\n failContributesToScore: config.failContributesToScore,\n capMs: config.capMs,\n async run(ctx) {\n if (config.adapters.length === 0) {\n return {\n layer: config.name,\n status: 'skipped',\n durationMs: 0,\n findings: [],\n reason: 'no adapters detected',\n }\n }\n\n const runOne = async (adapter: Adapter): Promise<AdapterRun> => {\n const adapterName = config.adapterName(adapter)\n try {\n const r = await config.run(adapter, ctx)\n return { adapter: adapterName, result: r }\n } catch (err) {\n return {\n adapter: adapterName,\n result: {\n layer: config.name,\n status: 'error',\n durationMs: 0,\n findings: [\n {\n severity: 'major',\n layer: config.name,\n message: err instanceof Error ? err.message : String(err),\n detail: { adapter: adapterName },\n },\n ],\n reason: err instanceof Error ? err.message : String(err),\n },\n }\n }\n }\n\n // Bounded parallelism — chunked into groups of size maxParallel.\n const results: AdapterRun[] = []\n for (let i = 0; i < config.adapters.length; i += maxParallel) {\n const chunk = config.adapters.slice(i, i + maxParallel)\n const chunkResults = await Promise.all(chunk.map(runOne))\n results.push(...chunkResults)\n }\n return mergeLayerResults(config.name, results)\n },\n }\n}\n","/**\n * Reference replay — score an agent against withheld historical outcomes.\n *\n * This is the generic version of the public-audit replay pattern:\n * run a candidate system on an old task, keep the reference answers hidden\n * until after execution, then score recall/precision and gate promotion\n * across train/dev/test/holdout splits.\n */\n\nimport { appendFileSync, existsSync, mkdirSync, readFileSync } from 'node:fs'\nimport { dirname } from 'node:path'\nimport { Mutex } from './concurrency'\n\nexport type ReferenceReplaySplit = 'train' | 'dev' | 'test' | 'holdout'\nexport type ReferenceReplayMatchStrategy = 'reference-order' | 'global-greedy'\n\nexport interface ReferenceReplayItem {\n id: string\n title: string\n description?: string\n severity?: string\n tags?: string[]\n weight?: number\n}\n\nexport interface ReferenceReplayCandidate {\n id: string\n title: string\n description?: string\n severity?: string\n tags?: string[]\n metadata?: Record<string, unknown>\n}\n\nexport interface ReferenceReplayScenario {\n id: string\n split?: ReferenceReplaySplit\n references: ReferenceReplayItem[]\n candidates: ReferenceReplayCandidate[]\n metadata?: Record<string, unknown>\n}\n\nexport interface ReferenceReplayCase<Input = unknown> {\n id: string\n split?: ReferenceReplaySplit\n input: Input\n references: ReferenceReplayItem[]\n metadata?: Record<string, unknown>\n}\n\nexport interface ReferenceReplayExecutionScenario<Input = unknown> {\n id: string\n split: ReferenceReplaySplit\n input: Input\n metadata?: Record<string, unknown>\n}\n\nexport interface ReferenceReplayRunContext {\n runId: string\n caseIndex: number\n abortSignal?: AbortSignal\n}\n\nexport interface ReferenceReplayAdapter<Input = unknown> {\n run(\n scenario: ReferenceReplayExecutionScenario<Input>,\n context: ReferenceReplayRunContext,\n ): Promise<ReferenceReplayCandidate[]>\n}\n\nexport type ReferenceReplayAdapterFn<Input = unknown> = (\n scenario: ReferenceReplayExecutionScenario<Input>,\n context: ReferenceReplayRunContext,\n) => Promise<ReferenceReplayCandidate[]>\n\nexport type ReferenceReplayAdapterLike<Input = unknown> =\n | ReferenceReplayAdapter<Input>\n | ReferenceReplayAdapterFn<Input>\n\nexport interface ReferenceReplayMatch {\n scenarioId: string\n referenceId: string\n candidateId: string | null\n score: number\n matched: boolean\n weight: number\n reason: string\n}\n\nexport interface ReferenceReplayScenarioScore {\n scenarioId: string\n split: ReferenceReplaySplit\n matched: number\n total: number\n falsePositives: number\n matchedWeight: number\n totalWeight: number\n precision: number\n recall: number\n f1: number\n matches: ReferenceReplayMatch[]\n}\n\nexport interface ReferenceReplayAggregate {\n matched: number\n total: number\n falsePositives: number\n matchedWeight: number\n totalWeight: number\n precision: number\n recall: number\n f1: number\n weightedRecall: number\n}\n\nexport interface ReferenceReplayScore {\n scenarios: ReferenceReplayScenarioScore[]\n aggregate: ReferenceReplayAggregate\n bySplit: Partial<Record<ReferenceReplaySplit, ReferenceReplayAggregate>>\n}\n\nexport interface ReferenceMatchResult {\n score: number\n reason?: string\n}\n\nexport type ReferenceReplayMatcher = (\n reference: ReferenceReplayItem,\n candidate: ReferenceReplayCandidate,\n scenario: ReferenceReplayScenario,\n) => ReferenceMatchResult\n\nexport interface ReferenceReplayScoreOptions {\n matcher?: ReferenceReplayMatcher\n matchThreshold?: number\n matchStrategy?: ReferenceReplayMatchStrategy\n includeHoldout?: boolean\n splits?: ReferenceReplaySplit[]\n}\n\nexport interface ReferenceReplayPromotionPolicy {\n /** Splits that must improve or stay flat. Default: ['dev', 'test']. */\n requiredSplits?: ReferenceReplaySplit[]\n /** Minimum aggregate F1 lift required on required splits. Default 0. */\n minF1Delta?: number\n /** Maximum F1 drop allowed on any compared split. Default 0. */\n maxRegression?: number\n /** If true, holdout must be present and must not regress. Default true. */\n requireHoldoutNonRegression?: boolean\n}\n\nexport interface ReferenceReplaySplitComparison {\n split: ReferenceReplaySplit\n baselineF1: number\n candidateF1: number\n f1Delta: number\n baselineRecall: number\n candidateRecall: number\n recallDelta: number\n}\n\nexport interface ReferenceReplayPromotionDecision {\n promote: boolean\n reason: string\n aggregateDelta: number\n comparisons: ReferenceReplaySplitComparison[]\n regressions: ReferenceReplaySplitComparison[]\n}\n\nexport interface ReferenceReplayCaseRun<Input = unknown> {\n caseId: string\n split: ReferenceReplaySplit\n input: Input\n metadata?: Record<string, unknown>\n references: ReferenceReplayItem[]\n candidates: ReferenceReplayCandidate[]\n score: ReferenceReplayScenarioScore\n durationMs: number\n error?: string\n}\n\nexport interface ReferenceReplayRun<Input = unknown> {\n id: string\n variantId?: string\n startedAt: number\n completedAt: number\n durationMs: number\n cases: ReferenceReplayCaseRun<Input>[]\n score: ReferenceReplayScore\n metadata?: Record<string, unknown>\n}\n\nexport interface ReferenceReplayRunOptions<Input = unknown> extends ReferenceReplayScoreOptions {\n adapter: ReferenceReplayAdapterLike<Input>\n runId?: string\n variantId?: string\n metadata?: Record<string, unknown>\n store?: ReferenceReplayRunStore<Input>\n abortSignal?: AbortSignal\n continueOnError?: boolean\n now?: () => number\n}\n\nexport interface ReferenceReplayRunStore<Input = unknown> {\n save(run: ReferenceReplayRun<Input>): Promise<void>\n list(): Promise<ReferenceReplayRun<Input>[]>\n}\n\nconst DEFAULT_MATCH_THRESHOLD = 0.55\nconst ALL_SPLITS: ReferenceReplaySplit[] = ['train', 'dev', 'test', 'holdout']\n\nexport async function runReferenceReplay<Input = unknown>(\n cases: ReferenceReplayCase<Input>[],\n options: ReferenceReplayRunOptions<Input>,\n): Promise<ReferenceReplayRun<Input>> {\n const now = options.now ?? Date.now\n const startedAt = now()\n const runId = options.runId ?? `${options.variantId ?? 'reference-replay'}-${startedAt}`\n const allowedSplits = new Set(options.splits ?? ALL_SPLITS)\n const caseRuns: ReferenceReplayCaseRun<Input>[] = []\n\n for (const [caseIndex, replayCase] of cases.entries()) {\n const split = replayCase.split ?? 'train'\n if (split === 'holdout' && !options.includeHoldout) continue\n if (!allowedSplits.has(split)) continue\n\n const caseStart = now()\n const executionScenario: ReferenceReplayExecutionScenario<Input> = {\n id: replayCase.id,\n split,\n input: replayCase.input,\n ...(replayCase.metadata !== undefined ? { metadata: replayCase.metadata } : {}),\n }\n\n let candidates: ReferenceReplayCandidate[] = []\n let error: string | undefined\n try {\n throwIfAborted(options.abortSignal)\n candidates = await runAdapter(options.adapter, executionScenario, {\n runId,\n caseIndex,\n abortSignal: options.abortSignal,\n })\n throwIfAborted(options.abortSignal)\n } catch (cause) {\n if (options.abortSignal?.aborted) throw cause\n if (!options.continueOnError) throw cause\n error = cause instanceof Error ? cause.message : String(cause)\n }\n\n const scenario: ReferenceReplayScenario = {\n id: replayCase.id,\n split,\n references: replayCase.references,\n candidates,\n ...(replayCase.metadata !== undefined ? { metadata: replayCase.metadata } : {}),\n }\n const scoreOptions: ReferenceReplayScoreOptions = {\n matcher: options.matcher,\n matchThreshold: options.matchThreshold,\n matchStrategy: options.matchStrategy,\n includeHoldout: true,\n }\n const scenarioScore = scoreReferenceReplay([scenario], scoreOptions).scenarios[0]!\n caseRuns.push({\n caseId: replayCase.id,\n split,\n input: replayCase.input,\n references: replayCase.references,\n candidates,\n score: scenarioScore,\n durationMs: Math.max(0, now() - caseStart),\n ...(replayCase.metadata !== undefined ? { metadata: replayCase.metadata } : {}),\n ...(error !== undefined ? { error } : {}),\n })\n }\n\n const completedAt = now()\n const scoreOptions: ReferenceReplayScoreOptions = {\n matcher: options.matcher,\n matchThreshold: options.matchThreshold,\n matchStrategy: options.matchStrategy,\n includeHoldout: true,\n }\n const run: ReferenceReplayRun<Input> = {\n id: runId,\n startedAt,\n completedAt,\n durationMs: Math.max(0, completedAt - startedAt),\n cases: caseRuns,\n score: scoreReferenceReplay(\n caseRuns.map((caseRun) => ({\n id: caseRun.caseId,\n split: caseRun.split,\n references: caseRun.references,\n candidates: caseRun.candidates,\n ...(caseRun.metadata !== undefined ? { metadata: caseRun.metadata } : {}),\n })),\n scoreOptions,\n ),\n ...(options.variantId !== undefined ? { variantId: options.variantId } : {}),\n ...(options.metadata !== undefined ? { metadata: options.metadata } : {}),\n }\n\n await options.store?.save(run)\n return run\n}\n\nexport function decideReferenceReplayRunPromotion(\n baseline: ReferenceReplayRun,\n candidate: ReferenceReplayRun,\n policy: ReferenceReplayPromotionPolicy = {},\n): ReferenceReplayPromotionDecision {\n return decideReferenceReplayPromotion(baseline.score, candidate.score, policy)\n}\n\nexport function inMemoryReferenceReplayStore<Input = unknown>(\n initial: ReferenceReplayRun<Input>[] = [],\n): ReferenceReplayRunStore<Input> {\n const runs = [...initial]\n return {\n async save(run) {\n runs.push(run)\n },\n async list() {\n return [...runs]\n },\n }\n}\n\n// Per-path Mutex registry. `appendFileSync` on POSIX is only atomic up to\n// PIPE_BUF (~4KB) — and a `ReferenceReplayRun` line routinely exceeds that.\n// Concurrent in-process writers without a lock produce torn lines that\n// break `list()` on parse. Cross-process safety still requires file\n// locking (fcntl/flock); we don't take that on here because every current\n// agent-eval flow is single-process.\nconst jsonlStoreLocks = new Map<string, Mutex>()\nfunction getJsonlStoreLock(path: string): Mutex {\n let m = jsonlStoreLocks.get(path)\n if (!m) {\n m = new Mutex()\n jsonlStoreLocks.set(path, m)\n }\n return m\n}\n\nexport function jsonlReferenceReplayStore<Input = unknown>(\n path: string,\n): ReferenceReplayRunStore<Input> {\n const lock = getJsonlStoreLock(path)\n return {\n async save(run) {\n await lock.runExclusive(() => {\n mkdirSync(dirname(path), { recursive: true })\n appendFileSync(path, `${JSON.stringify(run)}\\n`)\n })\n },\n async list() {\n return lock.runExclusive(() => {\n if (!existsSync(path)) return []\n return readJsonl(path)\n })\n },\n }\n}\n\nexport function scoreReferenceReplay(\n scenarios: ReferenceReplayScenario[],\n options: ReferenceReplayScoreOptions = {},\n): ReferenceReplayScore {\n const matcher = options.matcher ?? defaultReferenceReplayMatcher\n const threshold = options.matchThreshold ?? DEFAULT_MATCH_THRESHOLD\n const matchStrategy = options.matchStrategy ?? 'reference-order'\n const allowedSplits = new Set(options.splits ?? ALL_SPLITS)\n const scores = scenarios\n .filter((scenario) => {\n const split = scenario.split ?? 'train'\n if (split === 'holdout' && !options.includeHoldout) return false\n return allowedSplits.has(split)\n })\n .map((scenario) => scoreScenario(scenario, matcher, threshold, matchStrategy))\n\n return {\n scenarios: scores,\n aggregate: aggregateScenarioScores(scores),\n bySplit: aggregateBySplit(scores),\n }\n}\n\nexport function compareReferenceReplay(\n baseline: ReferenceReplayScore,\n candidate: ReferenceReplayScore,\n): ReferenceReplaySplitComparison[] {\n const splits = new Set<ReferenceReplaySplit>([\n ...(Object.keys(baseline.bySplit) as ReferenceReplaySplit[]),\n ...(Object.keys(candidate.bySplit) as ReferenceReplaySplit[]),\n ])\n return [...splits].sort(bySplitOrder).map((split) => {\n const before = baseline.bySplit[split] ?? emptyAggregate()\n const after = candidate.bySplit[split] ?? emptyAggregate()\n return {\n split,\n baselineF1: before.f1,\n candidateF1: after.f1,\n f1Delta: after.f1 - before.f1,\n baselineRecall: before.recall,\n candidateRecall: after.recall,\n recallDelta: after.recall - before.recall,\n }\n })\n}\n\nexport function decideReferenceReplayPromotion(\n baseline: ReferenceReplayScore,\n candidate: ReferenceReplayScore,\n policy: ReferenceReplayPromotionPolicy = {},\n): ReferenceReplayPromotionDecision {\n const requiredSplits = policy.requiredSplits ?? ['dev', 'test']\n const minF1Delta = policy.minF1Delta ?? 0\n const maxRegression = policy.maxRegression ?? 0\n const requireHoldout = policy.requireHoldoutNonRegression ?? true\n const comparisons = compareReferenceReplay(baseline, candidate)\n const missingRequiredSplits = requiredSplits.filter(\n (split) => !hasSplit(baseline, split) || !hasSplit(candidate, split),\n )\n const compared = comparisons.filter((item) => requiredSplits.includes(item.split))\n const regressions = comparisons.filter((item) => item.f1Delta < -maxRegression)\n const aggregateDelta = candidate.aggregate.f1 - baseline.aggregate.f1\n\n if (missingRequiredSplits.length > 0) {\n return {\n promote: false,\n reason: `Required split missing from baseline or candidate: ${missingRequiredSplits.join(', ')}`,\n aggregateDelta,\n comparisons,\n regressions,\n }\n }\n\n if (compared.length === 0) {\n return {\n promote: false,\n reason: `No required split scores found: ${requiredSplits.join(', ')}`,\n aggregateDelta,\n comparisons,\n regressions,\n }\n }\n\n if (regressions.length > 0) {\n return {\n promote: false,\n reason: `Regression in ${regressions.map((r) => r.split).join(', ')}`,\n aggregateDelta,\n comparisons,\n regressions,\n }\n }\n\n if (requireHoldout && (!hasSplit(baseline, 'holdout') || !hasSplit(candidate, 'holdout'))) {\n return {\n promote: false,\n reason: 'Holdout split is required for promotion',\n aggregateDelta,\n comparisons,\n regressions,\n }\n }\n\n const requiredMeanDelta = mean(compared.map((item) => item.f1Delta))\n if (requiredMeanDelta < minF1Delta) {\n return {\n promote: false,\n reason: `Required split F1 delta ${formatPct(requiredMeanDelta)} below ${formatPct(minF1Delta)}`,\n aggregateDelta,\n comparisons,\n regressions,\n }\n }\n\n return {\n promote: true,\n reason: `Required splits improved by ${formatPct(requiredMeanDelta)} with no regressions`,\n aggregateDelta,\n comparisons,\n regressions,\n }\n}\n\nexport function defaultReferenceReplayMatcher(\n reference: ReferenceReplayItem,\n candidate: ReferenceReplayCandidate,\n): ReferenceMatchResult {\n const referenceText = `${reference.title} ${reference.description ?? ''}`\n const candidateText = `${candidate.title} ${candidate.description ?? ''}`\n const textScore = tokenJaccard(referenceText, candidateText)\n const severityScore =\n reference.severity && candidate.severity\n ? normalize(reference.severity) === normalize(candidate.severity)\n ? 0.1\n : -0.05\n : 0\n const tagScore = tagOverlap(reference.tags, candidate.tags) * 0.15\n const score = clamp01(textScore * 0.85 + tagScore + severityScore)\n return {\n score,\n reason: `token=${textScore.toFixed(2)} tags=${tagScore.toFixed(2)} severity=${severityScore.toFixed(2)}`,\n }\n}\n\nfunction scoreScenario(\n scenario: ReferenceReplayScenario,\n matcher: ReferenceReplayMatcher,\n threshold: number,\n matchStrategy: ReferenceReplayMatchStrategy,\n): ReferenceReplayScenarioScore {\n return matchStrategy === 'global-greedy'\n ? scoreScenarioGlobalGreedy(scenario, matcher, threshold)\n : scoreScenarioReferenceOrder(scenario, matcher, threshold)\n}\n\nfunction scoreScenarioReferenceOrder(\n scenario: ReferenceReplayScenario,\n matcher: ReferenceReplayMatcher,\n threshold: number,\n): ReferenceReplayScenarioScore {\n const candidatesLeft = scenario.candidates.map((candidate, index) => ({ candidate, index }))\n const matches: ReferenceReplayMatch[] = []\n\n for (const reference of scenario.references) {\n let best: {\n candidate: ReferenceReplayCandidate\n index: number\n score: number\n reason: string\n } | null = null\n for (const item of candidatesLeft) {\n const result = scorePair(scenario, matcher, reference, item.candidate)\n if (!best || result.score > best.score) {\n best = { ...item, ...result }\n }\n }\n\n const weight = reference.weight ?? 1\n if (best && best.score >= threshold) {\n const matchIndex = candidatesLeft.findIndex((item) => item.index === best.index)\n if (matchIndex >= 0) candidatesLeft.splice(matchIndex, 1)\n matches.push({\n scenarioId: scenario.id,\n referenceId: reference.id,\n candidateId: best.candidate.id,\n score: best.score,\n matched: true,\n weight,\n reason: best.reason,\n })\n } else {\n matches.push({\n scenarioId: scenario.id,\n referenceId: reference.id,\n candidateId: best?.candidate.id ?? null,\n score: best?.score ?? 0,\n matched: false,\n weight,\n reason: best?.reason ?? 'no candidates',\n })\n }\n }\n\n return buildScenarioScore(scenario, matches, candidatesLeft.length)\n}\n\ninterface ReferenceCandidatePair {\n referenceIndex: number\n candidateIndex: number\n reference: ReferenceReplayItem\n candidate: ReferenceReplayCandidate\n score: number\n reason: string\n}\n\nfunction scoreScenarioGlobalGreedy(\n scenario: ReferenceReplayScenario,\n matcher: ReferenceReplayMatcher,\n threshold: number,\n): ReferenceReplayScenarioScore {\n const pairs: ReferenceCandidatePair[] = []\n for (const [referenceIndex, reference] of scenario.references.entries()) {\n for (const [candidateIndex, candidate] of scenario.candidates.entries()) {\n pairs.push({\n referenceIndex,\n candidateIndex,\n reference,\n candidate,\n ...scorePair(scenario, matcher, reference, candidate),\n })\n }\n }\n\n pairs.sort(\n (a, b) =>\n b.score - a.score ||\n a.referenceIndex - b.referenceIndex ||\n a.candidateIndex - b.candidateIndex,\n )\n\n const selectedByReference = new Map<number, ReferenceCandidatePair>()\n const selectedCandidates = new Set<number>()\n for (const pair of pairs) {\n if (pair.score < threshold) break\n if (selectedByReference.has(pair.referenceIndex) || selectedCandidates.has(pair.candidateIndex))\n continue\n selectedByReference.set(pair.referenceIndex, pair)\n selectedCandidates.add(pair.candidateIndex)\n }\n\n const matches = scenario.references.map((reference, referenceIndex) => {\n const weight = reference.weight ?? 1\n const selected = selectedByReference.get(referenceIndex)\n if (selected) {\n return {\n scenarioId: scenario.id,\n referenceId: reference.id,\n candidateId: selected.candidate.id,\n score: selected.score,\n matched: true,\n weight,\n reason: selected.reason,\n }\n }\n\n const bestRejected = pairs.find((pair) => pair.referenceIndex === referenceIndex)\n return {\n scenarioId: scenario.id,\n referenceId: reference.id,\n candidateId: bestRejected?.candidate.id ?? null,\n score: bestRejected?.score ?? 0,\n matched: false,\n weight,\n reason: bestRejected?.reason ?? 'no candidates',\n }\n })\n\n return buildScenarioScore(scenario, matches, scenario.candidates.length - selectedCandidates.size)\n}\n\nfunction scorePair(\n scenario: ReferenceReplayScenario,\n matcher: ReferenceReplayMatcher,\n reference: ReferenceReplayItem,\n candidate: ReferenceReplayCandidate,\n): { score: number; reason: string } {\n const result = matcher(reference, candidate, scenario)\n if (!Number.isFinite(result.score)) {\n throw new Error(\n `reference replay matcher returned non-finite score for ${scenario.id}:${reference.id}:${candidate.id}`,\n )\n }\n return { score: clamp01(result.score), reason: result.reason ?? '' }\n}\n\nfunction buildScenarioScore(\n scenario: ReferenceReplayScenario,\n matches: ReferenceReplayMatch[],\n falsePositives: number,\n): ReferenceReplayScenarioScore {\n const matched = matches.filter((match) => match.matched).length\n const total = scenario.references.length\n const matchedWeight = matches\n .filter((match) => match.matched)\n .reduce((sum, match) => sum + match.weight, 0)\n const totalWeight = matches.reduce((sum, match) => sum + match.weight, 0)\n const precision = ratio(matched, matched + falsePositives)\n const recall = ratio(matched, total)\n return {\n scenarioId: scenario.id,\n split: scenario.split ?? 'train',\n matched,\n total,\n falsePositives,\n matchedWeight,\n totalWeight,\n precision,\n recall,\n f1: f1(precision, recall),\n matches,\n }\n}\n\nfunction aggregateBySplit(\n scores: ReferenceReplayScenarioScore[],\n): Partial<Record<ReferenceReplaySplit, ReferenceReplayAggregate>> {\n const out: Partial<Record<ReferenceReplaySplit, ReferenceReplayAggregate>> = {}\n for (const split of ALL_SPLITS) {\n const scoped = scores.filter((score) => score.split === split)\n if (scoped.length > 0) out[split] = aggregateScenarioScores(scoped)\n }\n return out\n}\n\nfunction aggregateScenarioScores(scores: ReferenceReplayScenarioScore[]): ReferenceReplayAggregate {\n const matched = sum(scores.map((score) => score.matched))\n const total = sum(scores.map((score) => score.total))\n const falsePositives = sum(scores.map((score) => score.falsePositives))\n const matchedWeight = sum(scores.map((score) => score.matchedWeight))\n const totalWeight = sum(scores.map((score) => score.totalWeight))\n const precision = ratio(matched, matched + falsePositives)\n const recall = ratio(matched, total)\n return {\n matched,\n total,\n falsePositives,\n matchedWeight,\n totalWeight,\n precision,\n recall,\n f1: f1(precision, recall),\n weightedRecall: ratio(matchedWeight, totalWeight),\n }\n}\n\nfunction emptyAggregate(): ReferenceReplayAggregate {\n return {\n matched: 0,\n total: 0,\n falsePositives: 0,\n matchedWeight: 0,\n totalWeight: 0,\n precision: 0,\n recall: 0,\n f1: 0,\n weightedRecall: 0,\n }\n}\n\nfunction hasSplit(score: ReferenceReplayScore, split: ReferenceReplaySplit): boolean {\n return score.bySplit[split] !== undefined\n}\n\nfunction f1(precision: number, recall: number): number {\n return precision + recall === 0 ? 0 : (2 * precision * recall) / (precision + recall)\n}\n\nfunction ratio(numerator: number, denominator: number): number {\n return denominator > 0 ? numerator / denominator : 0\n}\n\nfunction tokenJaccard(a: string, b: string): number {\n const left = new Set(tokens(a))\n const right = new Set(tokens(b))\n if (left.size === 0 || right.size === 0) return 0\n let intersection = 0\n for (const token of left) {\n if (right.has(token)) intersection++\n }\n return intersection / (left.size + right.size - intersection)\n}\n\nfunction tagOverlap(a: string[] | undefined, b: string[] | undefined): number {\n if (!a?.length || !b?.length) return 0\n const left = new Set(a.map(normalize))\n const right = new Set(b.map(normalize))\n let intersection = 0\n for (const tag of left) {\n if (right.has(tag)) intersection++\n }\n return intersection / Math.max(left.size, right.size)\n}\n\nfunction tokens(text: string): string[] {\n return normalize(text)\n .split(/\\s+/)\n .filter((token) => token.length >= 3 && !STOP_WORDS.has(token))\n}\n\nfunction normalize(text: string): string {\n return text\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, ' ')\n .trim()\n}\n\nfunction clamp01(value: number): number {\n if (!Number.isFinite(value)) return 0\n return Math.max(0, Math.min(1, value))\n}\n\nfunction sum(values: number[]): number {\n return values.reduce((acc, value) => acc + value, 0)\n}\n\nfunction mean(values: number[]): number {\n return values.length ? sum(values) / values.length : 0\n}\n\nfunction formatPct(value: number): string {\n return `${(value * 100).toFixed(1)}%`\n}\n\nfunction bySplitOrder(a: ReferenceReplaySplit, b: ReferenceReplaySplit): number {\n return ALL_SPLITS.indexOf(a) - ALL_SPLITS.indexOf(b)\n}\n\nfunction runAdapter<Input>(\n adapter: ReferenceReplayAdapterLike<Input>,\n scenario: ReferenceReplayExecutionScenario<Input>,\n context: ReferenceReplayRunContext,\n): Promise<ReferenceReplayCandidate[]> {\n return typeof adapter === 'function' ? adapter(scenario, context) : adapter.run(scenario, context)\n}\n\nfunction throwIfAborted(signal: AbortSignal | undefined): void {\n if (!signal?.aborted) return\n if (signal.reason instanceof Error) throw signal.reason\n throw new Error(signal.reason ? String(signal.reason) : 'reference replay aborted')\n}\n\nfunction readJsonl<Input>(path: string): ReferenceReplayRun<Input>[] {\n const raw = readFileSync(path, 'utf8')\n const out: ReferenceReplayRun<Input>[] = []\n for (const line of raw.split('\\n')) {\n const trimmed = line.trim()\n if (!trimmed) continue\n out.push(JSON.parse(trimmed) as ReferenceReplayRun<Input>)\n }\n return out\n}\n\nconst STOP_WORDS = new Set([\n 'the',\n 'and',\n 'for',\n 'with',\n 'that',\n 'this',\n 'from',\n 'into',\n 'onto',\n 'are',\n 'can',\n 'will',\n 'should',\n 'could',\n 'would',\n 'when',\n 'where',\n 'which',\n])\n","/**\n * Reviewer primitives — prompt builder + default ReviewFn factory.\n *\n * `buildReviewerPrompt` is the pure, LLM-agnostic piece: takes\n * `ReviewerPromptInput` (user request, trace summary, verification\n * summary, memory, optional extra context) and emits the system +\n * user message pair. No LLM dependency — callers that want to drive\n * their own transport get full control.\n *\n * `createDefaultReviewer` is the convenience factory: wires the prompt\n * builder to `callLlmJson` with a default schema + soft-fail policy.\n * Returns a function that maps `ReviewerPromptInput` to `ReviewerOutput`.\n *\n * Same pattern as `runSemanticConceptJudge` / `createSemanticConceptJudge`:\n * low-level pure builder + high-level factory built on top.\n */\n\nimport { callLlmJson, type LlmClientOptions } from './llm-client'\n\n// ─── Types ──────────────────────────────────────────────────────────────\n\nexport interface ReviewerMemoryEntry {\n shot: number\n ts?: string\n observations?: string\n diagnosis?: string\n nextShotInstruction?: string\n shouldContinue?: boolean\n confidence?: number\n}\n\nexport interface ReviewerVerificationSummary {\n blendedScore: number\n allPass: boolean\n failCount: number\n failingLayers?: string[]\n}\n\nexport interface ReviewerPromptInput {\n shot: number\n userRequest: string\n /**\n * Compact trace summary — tool-call counts, errors, recent activity\n * lines. Built by the caller from whatever trace format they have;\n * agent-eval does not prescribe.\n */\n traceSummary: string\n verification: ReviewerVerificationSummary\n memory: ReviewerMemoryEntry[]\n /**\n * Optional extra context injected into the prompt between the trace\n * and the verification blocks. Use for workdir file-tree snapshots,\n * scaffold descriptions, or any environmental fact the reviewer\n * needs to direct the next shot accurately.\n */\n extraContext?: string\n /**\n * Optional extra section appended at the end of the prompt (e.g.\n * leaf metadata, scenario id). Free-form — no agent-eval-shaped\n * schema.\n */\n trailingContext?: string\n}\n\nexport interface ReviewerOutput {\n shot: number\n observations: string\n diagnosis: string\n nextShotInstruction: string\n shouldContinue: boolean\n /** 0..1 self-assessed confidence in the directive. */\n confidence: number\n /** LLM cost in USD if the transport reports it, else null. */\n costUsd: number | null\n durationMs: number\n /** False when the LLM errored or returned malformed JSON; caller soft-fails to defaults. */\n available: boolean\n error?: string\n}\n\nexport interface ReviewerSoftFailDefaults {\n observations?: string\n diagnosis?: string\n nextShotInstruction?: string\n shouldContinue?: boolean\n confidence?: number\n}\n\nexport interface CreateDefaultReviewerOptions {\n /** Model id to call. */\n model: string\n /** Per-call timeout. Default 180s. */\n timeoutMs?: number\n /** LlmClient transport config (baseUrl, apiKey, authHeader, etc.). */\n llm?: LlmClientOptions\n /**\n * Override the prompt builder. Default: `buildReviewerPrompt`.\n * Consumers with different reviewer voices pass their own.\n */\n promptBuilder?: (input: ReviewerPromptInput) => { system: string; user: string }\n /**\n * Soft-fail values when the LLM throws or returns unparseable JSON.\n * Matches VerticalBench's shipped policy: continue with generic\n * instruction at confidence 0.3 so the worker keeps trying.\n */\n softFailDefaults?: ReviewerSoftFailDefaults\n}\n\n// ─── JSON schema ───────────────────────────────────────────────────────\n\nconst REVIEWER_SCHEMA = {\n type: 'object',\n additionalProperties: false,\n required: ['observations', 'diagnosis', 'nextShotInstruction', 'shouldContinue', 'confidence'],\n properties: {\n observations: { type: 'string', minLength: 20, maxLength: 2000 },\n diagnosis: { type: 'string', minLength: 20, maxLength: 1500 },\n nextShotInstruction: { type: 'string', minLength: 40, maxLength: 3000 },\n shouldContinue: { type: 'boolean' },\n confidence: { type: 'number', minimum: 0, maximum: 1 },\n },\n} as const\n\n// ─── Prompt builder ────────────────────────────────────────────────────\n\nfunction summarizeMemory(memory: ReviewerMemoryEntry[]): string {\n if (memory.length === 0) return '(no prior shots)'\n return memory\n .map((m) => {\n const header = `shot ${m.shot} — confidence=${(m.confidence ?? 0).toFixed(2)} shouldContinue=${m.shouldContinue ?? '?'}`\n const obs = m.observations ? ` observations: ${m.observations.slice(0, 400)}` : ''\n const diag = m.diagnosis ? ` diagnosis: ${m.diagnosis.slice(0, 400)}` : ''\n const instr = m.nextShotInstruction\n ? ` instruction given: ${m.nextShotInstruction.slice(0, 400)}`\n : ''\n return [header, obs, diag, instr].filter(Boolean).join('\\n')\n })\n .join('\\n\\n')\n}\n\n/**\n * Build the reviewer's system + user messages. Pure function, no LLM\n * call. Callers that want their own transport or a different structured\n * output can use this and skip `createDefaultReviewer` entirely.\n */\nexport function buildReviewerPrompt(input: ReviewerPromptInput): { system: string; user: string } {\n const system =\n 'You are a senior-engineer-grade reviewer directing an agent through a multi-shot build. ' +\n \"Your job is NOT to grade; your job IS to direct the worker's next shot using the trace, \" +\n 'verification result, prior memory, and user request. Return STRICT JSON. No prose outside the JSON.'\n\n const failingLayersBlock =\n input.verification.failingLayers && input.verification.failingLayers.length > 0\n ? `failing layers: ${input.verification.failingLayers.join(', ')}`\n : 'no layers failing'\n\n const user = `=== SHOT NUMBER ===\nshot ${input.shot} of the review loop\n\n=== USER REQUEST ===\n${input.userRequest}\n\n=== WORKER TRACE (shot ${input.shot}) ===\n${input.traceSummary}\n${input.extraContext ? `\\n=== EXTRA CONTEXT ===\\n${input.extraContext}\\n` : ''}\n=== VERIFICATION (shot ${input.shot}) ===\nblendedScore: ${input.verification.blendedScore.toFixed(2)}\nallPass: ${input.verification.allPass}\nfailCount: ${input.verification.failCount}\n${failingLayersBlock}\n\n=== REVIEWER MEMORY ===\n${summarizeMemory(input.memory)}\n${input.trailingContext ? `\\n=== TRAILING CONTEXT ===\\n${input.trailingContext}\\n` : ''}\n=== YOUR TASK ===\nReturn STRICT JSON:\n\n1. observations (20-2000 chars): first-person worker behavior from the trace (tool call counts, errors, loops).\n2. diagnosis (20-1500 chars): root cause of current failures, not a restatement of verification.\n3. nextShotInstruction (40-3000 chars): concrete \"FIX THESE:\" directive for the worker's next shot. Reference memory when instructions repeat.\n4. shouldContinue (boolean): FALSE if verification.allPass=true, if worker is thrashing, if confidence < 0.3, or if the request looks unachievable. TRUE otherwise.\n5. confidence (0-1): self-assessment.\n\nRULES:\n- If verification.allPass is true, shouldContinue MUST be false.\n- If memory shows the same failing layer for 2 shots, reduce confidence — strategy isn't working.\n- If the trace shows zero tool calls, the worker didn't run — surface that.\n- Do NOT re-grade. Direct.`\n\n return { system, user }\n}\n\n// ─── Default reviewer factory ───────────────────────────────────────────\n\nconst DEFAULT_SOFT_FAIL: Required<ReviewerSoftFailDefaults> = {\n observations: 'reviewer soft-failed — no observations captured',\n diagnosis: 'reviewer soft-failed — inspect verification findings and retry',\n nextShotInstruction:\n 'Inspect the verification findings above and address the highest-severity failing layer first. ' +\n 'If install failed, start there; otherwise work from the first failing gate and address compilation/build errors before layout/semantic issues.',\n shouldContinue: true,\n confidence: 0.3,\n}\n\n/**\n * Factory: returns a function that invokes the default reviewer against\n * an LLM and parses the structured output. Soft-fails to the provided\n * defaults on LLM throw or JSON-parse error so the shot loop keeps\n * moving rather than crashing.\n */\nexport function createDefaultReviewer(\n options: CreateDefaultReviewerOptions,\n): (input: ReviewerPromptInput) => Promise<ReviewerOutput> {\n const softFail: Required<ReviewerSoftFailDefaults> = {\n ...DEFAULT_SOFT_FAIL,\n ...(options.softFailDefaults ?? {}),\n }\n const promptBuilder = options.promptBuilder ?? buildReviewerPrompt\n const timeoutMs = options.timeoutMs ?? 180_000\n\n return async (input) => {\n const start = Date.now()\n const { system, user } = promptBuilder(input)\n try {\n const { value, result } = await callLlmJson<{\n observations: string\n diagnosis: string\n nextShotInstruction: string\n shouldContinue: boolean\n confidence: number\n }>(\n {\n model: options.model,\n messages: [\n { role: 'system', content: system },\n { role: 'user', content: user },\n ],\n jsonSchema: { name: 'reviewer_output', schema: REVIEWER_SCHEMA },\n temperature: 0,\n timeoutMs,\n },\n options.llm ?? {},\n )\n\n return {\n shot: input.shot,\n observations: String(value.observations ?? softFail.observations),\n diagnosis: String(value.diagnosis ?? softFail.diagnosis),\n nextShotInstruction: String(value.nextShotInstruction ?? softFail.nextShotInstruction),\n shouldContinue: Boolean(value.shouldContinue),\n confidence: Math.max(0, Math.min(1, Number(value.confidence ?? softFail.confidence))),\n costUsd: result.costUsd ?? null,\n durationMs: Date.now() - start,\n available: true,\n }\n } catch (err) {\n return {\n shot: input.shot,\n observations: softFail.observations,\n diagnosis: softFail.diagnosis,\n nextShotInstruction: softFail.nextShotInstruction,\n shouldContinue: softFail.shouldContinue,\n confidence: softFail.confidence,\n costUsd: null,\n durationMs: Date.now() - start,\n available: false,\n error: err instanceof Error ? err.message : String(err),\n }\n }\n }\n}\n","/**\n * Walk a personas directory and return every file matching the convention\n * `NN-slug.{yaml,yml,json,md}`. Sorted by filename so the numeric prefix\n * gives stable persona ordering for reproducibility. Consumers filter\n * through `include` / `exclude`.\n */\n\nimport { promises as fs } from 'node:fs'\nimport { basename, extname, join } from 'node:path'\n\nexport interface DiscoverPersonasOptions {\n /**\n * Regex applied to filenames. Files that don't match are skipped.\n * Default: `^[0-9]{2}-.+\\.(yaml|yml|json|md)$`.\n */\n pattern?: RegExp\n /**\n * Filenames (or basenames) to skip. Use this to exclude WIP / archived\n * personas without removing the file.\n */\n exclude?: readonly string[]\n /**\n * If set, return only personas whose basename contains one of these\n * substrings (post-pattern filter).\n */\n include?: readonly string[]\n /** Recurse into subdirectories. Default false. */\n recursive?: boolean\n}\n\nexport interface DiscoveredPersona {\n /** Absolute file path. */\n path: string\n /** Filename without directory. */\n filename: string\n /** Filename without extension — the conventional persona id. */\n id: string\n}\n\nconst DEFAULT_PATTERN = /^\\d{2}-.+\\.(yaml|yml|json|md)$/\n\nexport async function discoverPersonas(\n dir: string,\n opts: DiscoverPersonasOptions = {},\n): Promise<DiscoveredPersona[]> {\n const pattern = opts.pattern ?? DEFAULT_PATTERN\n const exclude = new Set(opts.exclude ?? [])\n const include = opts.include\n\n async function walk(d: string): Promise<DiscoveredPersona[]> {\n let entries: Array<{ name: string; isDir: boolean }>\n try {\n const raw = await fs.readdir(d, { withFileTypes: true })\n entries = raw.map((e) => ({ name: e.name, isDir: e.isDirectory() }))\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code\n if (code === 'ENOENT') return []\n throw err\n }\n const out: DiscoveredPersona[] = []\n for (const entry of entries) {\n const full = join(d, entry.name)\n if (entry.isDir) {\n if (opts.recursive) out.push(...(await walk(full)))\n continue\n }\n if (!pattern.test(entry.name)) continue\n if (exclude.has(entry.name) || exclude.has(basename(entry.name, extname(entry.name))))\n continue\n if (include && include.length > 0) {\n const id = basename(entry.name, extname(entry.name))\n const matched = include.some((needle) => entry.name.includes(needle) || id.includes(needle))\n if (!matched) continue\n }\n out.push({\n path: full,\n filename: entry.name,\n id: basename(entry.name, extname(entry.name)),\n })\n }\n return out\n }\n\n const results = await walk(dir)\n results.sort((a, b) => a.filename.localeCompare(b.filename))\n return results\n}\n","/**\n * GoldenMatcher — fuzzy matcher for \"did the agent produce the expected things?\".\n *\n * Universal primitive across agent-eval consumers. Use it for:\n * - Test suites: did the run hit the expected assertions?\n * - Tool agents: did the agent emit the expected tool call sequence?\n * - Judges: did the verdict include the expected concepts?\n * - Design audits: did the auditor surface the planted defects?\n *\n * Match rule (per golden):\n * - Any phrase in `golden.any` (case-insensitive substring) appears in the\n * candidate's text fields, OR\n * - Any pattern in `golden.anyRegex` (case-insensitive) matches.\n *\n * Recall is severity-weighted by default: critical=3, major=2, minor=1.\n * Missing one critical hurts more than missing three minors.\n */\n\nexport type GoldenSeverity = 'critical' | 'major' | 'minor'\n\nexport interface GoldenSpec {\n /** Stable identifier — survives across runs so consumers can grep by id. */\n id: string\n /** Severity drives recall weighting. */\n severity: GoldenSeverity\n /**\n * Substring phrases (case-insensitive). A hit on ANY phrase counts as a\n * match. Keep these SHORT (3-6 words) and SPECIFIC.\n */\n any: string[]\n /** Optional regex patterns. ORed with `any`. */\n anyRegex?: string[]\n /** Free-form note — surfaces in reports for humans. */\n hint?: string\n /** Optional category for grouping/filtering. */\n category?: string\n}\n\nexport interface MatchResult {\n /** Same length as goldens; `true` when matched. */\n matches: boolean[]\n /** Convenience: count of hits. */\n hits: number\n /** Convenience: total goldens. */\n total: number\n}\n\n/**\n * Match each golden against `candidates`, where each candidate exposes one or\n * more text fields the matcher should search. Defaults to searching all\n * string-typed fields concatenated.\n */\nexport function matchGoldens<T>(\n goldens: GoldenSpec[],\n candidates: T[],\n options: {\n /**\n * Extract the searchable text for a candidate. Default: concatenate every\n * top-level string field with a space.\n */\n text?: (candidate: T) => string\n } = {},\n): MatchResult {\n const extract = options.text ?? defaultExtract\n const haystacks = candidates.map((c) => extract(c).toLowerCase())\n const matches = goldens.map((golden) => goldenMatched(golden, haystacks))\n return {\n matches,\n hits: matches.filter(Boolean).length,\n total: goldens.length,\n }\n}\n\nfunction defaultExtract(candidate: unknown): string {\n if (typeof candidate === 'string') return candidate\n if (candidate && typeof candidate === 'object') {\n const parts: string[] = []\n for (const v of Object.values(candidate as Record<string, unknown>)) {\n if (typeof v === 'string') parts.push(v)\n }\n return parts.join(' ')\n }\n return String(candidate ?? '')\n}\n\nfunction goldenMatched(golden: GoldenSpec, haystacks: string[]): boolean {\n for (const phrase of golden.any) {\n const needle = phrase.toLowerCase().trim()\n if (!needle) continue\n if (haystacks.some((h) => h.includes(needle))) return true\n }\n for (const pattern of golden.anyRegex ?? []) {\n let re: RegExp\n try {\n re = new RegExp(pattern, 'i')\n } catch {\n continue\n }\n if (haystacks.some((h) => re.test(h))) return true\n }\n return false\n}\n\n/** Severity weights — exposed so consumers can override (rare). */\nexport const DEFAULT_SEVERITY_WEIGHTS: Record<GoldenSeverity, number> = {\n critical: 3,\n major: 2,\n minor: 1,\n}\n\n/** Severity-weighted recall over a MatchResult + the goldens that produced it. */\nexport function weightedRecall(\n goldens: GoldenSpec[],\n result: MatchResult,\n weights: Record<GoldenSeverity, number> = DEFAULT_SEVERITY_WEIGHTS,\n): number {\n if (goldens.length === 0) return 1\n const total = goldens.reduce((s, g) => s + (weights[g.severity] ?? 1), 0)\n if (total === 0) return 1\n const hit = goldens.reduce(\n (s, g, i) => s + (result.matches[i] ? (weights[g.severity] ?? 1) : 0),\n 0,\n )\n return hit / total\n}\n\n/**\n * Precision proxy: fraction of emitted candidates that match SOME golden.\n *\n * No human-labelled negatives means unmatched candidates are SOFT false\n * positives — punishes verbose agents that pad with filler. Doesn't punish\n * unknown-but-real findings; the way to tighten this is to grow the golden\n * set, not to invent a stricter score.\n */\nexport function precision<T>(\n goldens: GoldenSpec[],\n candidates: T[],\n options: { text?: (candidate: T) => string } = {},\n): number {\n if (candidates.length === 0) return 1\n const extract = options.text ?? defaultExtract\n let matched = 0\n for (const cand of candidates) {\n const haystack = extract(cand).toLowerCase()\n const matchedAny = goldens.some(\n (g) =>\n g.any.some((phrase) => phrase.length > 0 && haystack.includes(phrase.toLowerCase())) ||\n (g.anyRegex ?? []).some((pat) => {\n try {\n return new RegExp(pat, 'i').test(haystack)\n } catch {\n return false\n }\n }),\n )\n if (matchedAny) matched++\n }\n return matched / candidates.length\n}\n","/**\n * HeldOutGate — first-class held-out paired-delta promotion gate.\n *\n * Encodes the \"honesty override\" pattern that lived inline in\n * `~/webb/redteam/scripts/agent-eval-autoresearch.ts:138–171`.\n * The optimizer's best-guess is one thing; what we should actually\n * ship is another. The gate is the line between them.\n *\n * A candidate is promoted iff ALL three pass:\n *\n * 1. **Productive runs**: the candidate has at least\n * `minProductiveRuns` paired observations on items where BOTH\n * candidate and baseline produced a real (non-silent) score.\n * 2. **Paired delta**: the lower bound of the bootstrap CI on the\n * median per-item delta (candidate − baseline) on the HOLDOUT\n * split is strictly greater than `pairedDeltaThreshold`.\n * 3. **Overfit gap**: the candidate's gap between search-split\n * score and holdout-split score is no worse (more positive)\n * than the baseline's gap by more than `overfitGapThreshold`.\n * \"Better on search, worse on holdout\" is the canonical\n * overfit pattern; this catches it.\n *\n * The decision carries a machine-readable `rejectionCode` plus an\n * `evidence` block with every number the gate looked at, so the\n * downstream researcher / paper / dashboard can re-derive the\n * verdict without re-running.\n *\n * See also:\n * - `src/statistics.ts` for `pairedBootstrap` + `wilcoxonSignedRank`\n * - `src/run-record.ts` for the input row schema\n * - `src/reference-replay.ts` for the older, reference-replay-\n * specific promotion path (still useful for replay-style evals).\n */\n\nimport type { RunRecord } from './run-record'\nimport { pairedBootstrap, wilcoxonSignedRank } from './statistics'\n\nexport type HeldOutGateRejectionCode =\n | 'few_runs'\n | 'negative_delta'\n | 'overfit_gap'\n | 'cost_ceiling'\n\nexport interface HeldOutGateConfig {\n /** Minimum number of paired (candidate, baseline) holdout observations\n * required before the gate will even consider promoting. Default 3. */\n minProductiveRuns?: number\n /** The bootstrap-CI lower bound on the median paired holdout delta\n * must exceed this to promote. Default 0. */\n pairedDeltaThreshold?: number\n /** Maximum allowed worsening of (search − holdout) gap relative to\n * baseline. Default 0.15 (i.e. candidate may overfit by up to 15\n * absolute score points more than baseline before rejection). */\n overfitGapThreshold?: number\n /** Stable label of the baseline candidate. Required — paper-grade\n * evaluation never compares two unlabelled candidates. */\n baselineKey: string\n /** Confidence level for the bootstrap CI. Default 0.95. */\n confidence?: number\n /** Bootstrap resamples. Default 2000. */\n bootstrapResamples?: number\n /** Optional deterministic seed for the bootstrap. Default undefined\n * (Math.random). */\n seed?: number\n /**\n * Hard ceiling on the candidate's median per-task USD cost. When the\n * candidate clears the quality gates (paired-delta + overfit-gap) but\n * its median cost exceeds this number, the gate rejects with\n * `cost_ceiling`. Default `undefined` = no cost ceiling, behaving\n * exactly like the pre-cost gate.\n *\n * This exists because \"we ship the better prompt\" is only an honest\n * pitch when the better prompt also fits a customer-stated budget.\n * Cost is read from `RunRecord.costUsd` (already mandatory on every\n * run) so no new schema is required.\n */\n costPerTaskCeiling?: number\n}\n\nexport interface GateEvidence {\n /** Number of paired (candidate, baseline) holdout observations used. */\n productiveRuns: number\n /** Median of (candidate − baseline) paired holdout deltas. */\n medianPairedDelta: number\n /** Bootstrap CI on the median paired holdout delta. */\n pairedCI: { low: number; high: number }\n /** Wilcoxon signed-rank p-value on the paired holdout deltas. */\n pairedPValue: number\n /** Mean candidate score on the search split (NaN if none). */\n searchScore: number\n /** Mean candidate score on the holdout split (NaN if none). */\n holdoutScore: number\n /** Candidate (search − holdout) gap. */\n overfitGap: number\n /** Baseline (search − holdout) gap. */\n baselineOverfitGap: number\n /** Median per-task USD cost across the candidate's runs. Recorded\n * even when no `costPerTaskCeiling` is configured so downstream\n * dashboards (intelligence.tangle.tools) can render \\$/task per\n * generation regardless of gating policy. */\n medianCandidateCost: number\n /** Median per-task USD cost across the baseline runs, for\n * symmetric reporting. */\n medianBaselineCost: number\n}\n\nexport interface GateDecision {\n /** Final promote/no-promote verdict. */\n promote: boolean\n /** The candidate that was evaluated. */\n candidateId: string\n /** The baseline it was compared against. */\n baselineId: string\n /** Every number the gate looked at, for audit + paper export. */\n evidence: GateEvidence\n /** Human-readable reason. */\n reason: string\n /** Machine-readable rejection code, or null on promote. */\n rejectionCode: HeldOutGateRejectionCode | null\n}\n\n/**\n * Held-out paired-delta promotion gate. Construct once with config,\n * call `evaluate(candidateRuns, baselineRuns)` per (candidate,\n * baseline) pair. Stateless across calls.\n */\nexport class HeldOutGate {\n private readonly minProductiveRuns: number\n private readonly pairedDeltaThreshold: number\n private readonly overfitGapThreshold: number\n private readonly baselineKey: string\n private readonly confidence: number\n private readonly resamples: number\n private readonly seed?: number\n private readonly costPerTaskCeiling?: number\n\n constructor(config: HeldOutGateConfig) {\n if (!config.baselineKey) {\n throw new Error('HeldOutGate: baselineKey is required')\n }\n this.minProductiveRuns = config.minProductiveRuns ?? 3\n this.pairedDeltaThreshold = config.pairedDeltaThreshold ?? 0\n this.overfitGapThreshold = config.overfitGapThreshold ?? 0.15\n this.baselineKey = config.baselineKey\n this.confidence = config.confidence ?? 0.95\n this.resamples = config.bootstrapResamples ?? 2000\n this.seed = config.seed\n if (\n config.costPerTaskCeiling !== undefined &&\n !(Number.isFinite(config.costPerTaskCeiling) && config.costPerTaskCeiling > 0)\n ) {\n throw new Error('HeldOutGate: costPerTaskCeiling must be a positive finite number')\n }\n this.costPerTaskCeiling = config.costPerTaskCeiling\n }\n\n /** Decide whether `candidate` should replace `baseline`. Pairing\n * is by (experimentId, seed) — identical experiment + seed pairs\n * the candidate run with the matching baseline run. Pairs without\n * a holdout score on both sides are dropped. */\n evaluate(candidate: RunRecord[], baseline: RunRecord[]): GateDecision {\n const candidateId = inferCandidateId(candidate, this.baselineKey)\n const baselineId = this.baselineKey\n\n // Pair holdout runs by (experimentId, seed).\n const baselineHoldoutByKey = indexHoldoutByKey(baseline)\n const beforeHoldout: number[] = []\n const afterHoldout: number[] = []\n for (const run of candidate) {\n if (run.splitTag !== 'holdout') continue\n if (run.outcome.holdoutScore === undefined) continue\n const key = pairKey(run)\n const counterpart = baselineHoldoutByKey.get(key)\n if (counterpart === undefined) continue\n beforeHoldout.push(counterpart)\n afterHoldout.push(run.outcome.holdoutScore)\n }\n\n const productiveRuns = beforeHoldout.length\n\n // Always compute the gap numbers — useful even when we reject on\n // few_runs (you want to see why).\n const candidateSearchMean = mean(scores(candidate, 'searchScore', 'search'))\n const candidateHoldoutMean = mean(scores(candidate, 'holdoutScore', 'holdout'))\n const baselineSearchMean = mean(scores(baseline, 'searchScore', 'search'))\n const baselineHoldoutMean = mean(scores(baseline, 'holdoutScore', 'holdout'))\n\n const overfitGap = safeDiff(candidateSearchMean, candidateHoldoutMean)\n const baselineOverfitGap = safeDiff(baselineSearchMean, baselineHoldoutMean)\n\n // Cost summary — surfaced in evidence regardless of gating policy\n // so downstream dashboards always know what the candidate cost.\n const medianCandidateCost = medianFinite(candidate.map((r) => r.costUsd))\n const medianBaselineCost = medianFinite(baseline.map((r) => r.costUsd))\n\n // Few-runs gate.\n if (productiveRuns < this.minProductiveRuns) {\n return {\n promote: false,\n candidateId,\n baselineId,\n evidence: {\n productiveRuns,\n medianPairedDelta: productiveRuns > 0 ? medianDelta(beforeHoldout, afterHoldout) : 0,\n pairedCI: { low: 0, high: 0 },\n pairedPValue: 1,\n searchScore: candidateSearchMean,\n holdoutScore: candidateHoldoutMean,\n overfitGap,\n baselineOverfitGap,\n medianCandidateCost,\n medianBaselineCost,\n },\n reason: `few_runs: ${productiveRuns} paired holdout observation(s) < min ${this.minProductiveRuns}`,\n rejectionCode: 'few_runs',\n }\n }\n\n // Paired bootstrap on holdout deltas.\n const ci = pairedBootstrap(beforeHoldout, afterHoldout, {\n confidence: this.confidence,\n resamples: this.resamples,\n statistic: 'median',\n seed: this.seed,\n })\n const wilcoxon = wilcoxonSignedRank(beforeHoldout, afterHoldout)\n\n const evidence: GateEvidence = {\n productiveRuns,\n medianPairedDelta: ci.median,\n pairedCI: { low: ci.low, high: ci.high },\n pairedPValue: wilcoxon.p,\n searchScore: candidateSearchMean,\n holdoutScore: candidateHoldoutMean,\n overfitGap,\n baselineOverfitGap,\n medianCandidateCost,\n medianBaselineCost,\n }\n\n // Negative-delta gate (CI lower bound must clear the threshold).\n if (!(ci.low > this.pairedDeltaThreshold)) {\n return {\n promote: false,\n candidateId,\n baselineId,\n evidence,\n reason:\n `negative_delta: paired holdout median Δ=${fmt(ci.median)} ` +\n `CI=[${fmt(ci.low)}, ${fmt(ci.high)}] does not clear threshold ${fmt(this.pairedDeltaThreshold)}`,\n rejectionCode: 'negative_delta',\n }\n }\n\n // Overfit-gap gate. We allow some absolute slack —\n // candidate.gap ≤ baseline.gap + overfitGapThreshold.\n if (\n Number.isFinite(overfitGap) &&\n Number.isFinite(baselineOverfitGap) &&\n overfitGap > baselineOverfitGap + this.overfitGapThreshold\n ) {\n return {\n promote: false,\n candidateId,\n baselineId,\n evidence,\n reason:\n `overfit_gap: candidate gap=${fmt(overfitGap)} exceeds baseline gap=${fmt(baselineOverfitGap)} ` +\n `by more than ${fmt(this.overfitGapThreshold)}`,\n rejectionCode: 'overfit_gap',\n }\n }\n\n // Cost-ceiling gate. Runs after quality gates so a cost-driven\n // rejection always carries a \"you cleared quality but blew budget\"\n // story rather than masking a quality failure. NaN cost is treated\n // as \"unknown\" and does NOT trip the ceiling — the data is just\n // missing, and the operator's stated ceiling is for known cost,\n // not for absent telemetry.\n if (\n this.costPerTaskCeiling !== undefined &&\n Number.isFinite(medianCandidateCost) &&\n medianCandidateCost > this.costPerTaskCeiling\n ) {\n return {\n promote: false,\n candidateId,\n baselineId,\n evidence,\n reason:\n `cost_ceiling: candidate median cost $${fmt(medianCandidateCost)} ` +\n `exceeds ceiling $${fmt(this.costPerTaskCeiling)} (baseline $${fmt(medianBaselineCost)})`,\n rejectionCode: 'cost_ceiling',\n }\n }\n\n return {\n promote: true,\n candidateId,\n baselineId,\n evidence,\n reason:\n `promote: paired holdout median Δ=${fmt(ci.median)} ` +\n `CI=[${fmt(ci.low)}, ${fmt(ci.high)}] over ${productiveRuns} pairs; ` +\n `overfit gap candidate=${fmt(overfitGap)} vs baseline=${fmt(baselineOverfitGap)}; ` +\n `median cost candidate=$${fmt(medianCandidateCost)} vs baseline=$${fmt(medianBaselineCost)}`,\n rejectionCode: null,\n }\n }\n}\n\n// ── Helpers ──────────────────────────────────────────────────────────\n\nfunction inferCandidateId(candidate: RunRecord[], baselineKey: string): string {\n for (const run of candidate) {\n if (run.candidateId && run.candidateId !== baselineKey) return run.candidateId\n }\n // All candidate rows match the baseline key — caller mistake, but\n // surface the symptom rather than throwing inside the gate.\n return candidate[0]?.candidateId ?? '(unknown candidate)'\n}\n\nfunction indexHoldoutByKey(runs: RunRecord[]): Map<string, number> {\n const out = new Map<string, number>()\n for (const r of runs) {\n if (r.splitTag !== 'holdout') continue\n if (r.outcome.holdoutScore === undefined) continue\n out.set(pairKey(r), r.outcome.holdoutScore)\n }\n return out\n}\n\nfunction pairKey(r: RunRecord): string {\n return `${r.experimentId}::${r.seed}`\n}\n\nfunction scores(\n runs: RunRecord[],\n field: 'searchScore' | 'holdoutScore',\n splitFilter: 'search' | 'holdout',\n): number[] {\n const out: number[] = []\n for (const r of runs) {\n if (r.splitTag !== splitFilter) continue\n const v = r.outcome[field]\n if (typeof v === 'number' && Number.isFinite(v)) out.push(v)\n }\n return out\n}\n\nfunction mean(xs: number[]): number {\n if (xs.length === 0) return Number.NaN\n return xs.reduce((s, x) => s + x, 0) / xs.length\n}\n\nfunction safeDiff(a: number, b: number): number {\n if (!Number.isFinite(a) || !Number.isFinite(b)) return Number.NaN\n return a - b\n}\n\nfunction medianDelta(before: number[], after: number[]): number {\n const ds = before.map((b, i) => after[i]! - b).sort((x, y) => x - y)\n if (ds.length === 0) return 0\n const mid = Math.floor(ds.length / 2)\n return ds.length % 2 === 0 ? (ds[mid - 1]! + ds[mid]!) / 2 : ds[mid]!\n}\n\nfunction medianFinite(xs: number[]): number {\n const ys = xs.filter((x) => Number.isFinite(x)).sort((x, y) => x - y)\n if (ys.length === 0) return Number.NaN\n const mid = Math.floor(ys.length / 2)\n return ys.length % 2 === 0 ? (ys[mid - 1]! + ys[mid]!) / 2 : ys[mid]!\n}\n\nfunction fmt(x: number): string {\n if (!Number.isFinite(x)) return String(x)\n return x.toFixed(4)\n}\n","/**\n * Wrap a single judge LLM call with retry, optional fallback-model\n * rotation, exponential backoff, and a typed `JudgeRetryOutcome`. Callers\n * MUST inspect `succeeded` before using `value`; on failure the library\n * returns `value: null` rather than substituting a default, so a judge\n * abort cannot silently corrupt a downstream composite.\n *\n * Reporting contract: callers ship `TrialResult.judgeSucceeded = succeeded`\n * and `TrialResult.judgeAttempts = attempts` so `aggregateTrialsByMode`\n * with `mode: 'exclude-failed'` drops the trial.\n */\n\nimport { backoffMs, isTransientLlmError } from './llm-client'\n\n/** Retry policy for judge LLM calls. */\nexport interface JudgeRetryPolicy {\n /** Max attempts per model. Default 3 (one initial + two retries). */\n maxAttempts?: number\n /** Per-attempt timeout in ms. Default 90_000 (1.5×agent-eval's 60s default). */\n timeoutMs?: number\n /**\n * Models to try, in order. The first model is the primary; subsequent\n * models are fallbacks invoked only when ALL retries on the previous\n * model have been exhausted. Example: `['claude-code/sonnet', 'kimi-code/k2p6']`\n * runs claude-code up to maxAttempts times, then falls back to kimi.\n * If omitted, the caller's judge function controls model selection and\n * the retries apply to that single model.\n */\n models?: readonly string[]\n /** Exponential backoff function, default `attempt → min(500 * 2^attempt, 16_000)`. */\n backoffMs?: (attempt: number) => number\n /**\n * Predicate deciding whether an error should trigger a retry. Defaults to\n * `isTransientLlmError` — the package-wide classifier shared with\n * `callLlm` — which retries aborts/timeouts, network faults, HTTP/2\n * transport faults, and any `LlmCallError` with status in {429,502,503,504}.\n * JSON-parse and schema-rejection errors are NOT retriable (the model\n * needs prompt adjustment, not another shot).\n */\n isRetryable?: (err: unknown) => boolean\n}\n\n/** Outcome of a wrapped judge invocation. */\nexport interface JudgeRetryOutcome<T> {\n /** The judge's returned value when `succeeded === true`. */\n value: T | null\n /** True iff one of the attempts completed without throwing. */\n succeeded: boolean\n /** Total attempts made across all models. */\n attempts: number\n /** Which model the successful attempt used (when succeeded). */\n modelUsed?: string\n /** Last error captured when `succeeded === false`. */\n error?: Error\n /** Per-attempt error log for forensics. */\n attemptErrors: Array<{ attempt: number; model: string; error: string }>\n}\n\nconst DEFAULT_MAX_ATTEMPTS = 3\nconst DEFAULT_TIMEOUT_MS = 90_000\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n\n/**\n * Wrap a judge call with retry + fallback-model + typed outcome semantics.\n *\n * The `judgeFn` signature is `(model: string, signal: AbortSignal) => Promise<T>`.\n * The signal will be aborted at `timeoutMs`. Callers should pass the signal\n * to their underlying fetch/SDK call so the abort actually fires.\n *\n * Returns a typed outcome — callers MUST inspect `succeeded` before using\n * `value`. The library refuses to default to a silent zero score because a\n * synthetic zero is indistinguishable from a real low score downstream.\n */\nexport async function withJudgeRetry<T>(\n judgeFn: (model: string, signal: AbortSignal) => Promise<T>,\n policy: JudgeRetryPolicy = {},\n): Promise<JudgeRetryOutcome<T>> {\n const maxAttempts = policy.maxAttempts ?? DEFAULT_MAX_ATTEMPTS\n const timeoutMs = policy.timeoutMs ?? DEFAULT_TIMEOUT_MS\n const backoff = policy.backoffMs ?? backoffMs\n const isRetryable = policy.isRetryable ?? isTransientLlmError\n const models =\n policy.models && policy.models.length > 0 ? policy.models : [undefined as unknown as string]\n\n let totalAttempts = 0\n const attemptErrors: JudgeRetryOutcome<T>['attemptErrors'] = []\n let lastError: Error | undefined\n\n for (const model of models) {\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\n totalAttempts += 1\n const controller = new AbortController()\n const timer = setTimeout(() => controller.abort(new Error('TimeoutError')), timeoutMs)\n try {\n const value = await judgeFn(model as string, controller.signal)\n clearTimeout(timer)\n return {\n value,\n succeeded: true,\n attempts: totalAttempts,\n modelUsed: model,\n attemptErrors,\n }\n } catch (err) {\n clearTimeout(timer)\n const errObj = err instanceof Error ? err : new Error(String(err))\n lastError = errObj\n attemptErrors.push({\n attempt: totalAttempts,\n model: model ?? '(default)',\n error: errObj.message,\n })\n if (!isRetryable(errObj)) {\n // Non-retriable (e.g., JSON parse, schema rejection): break out of\n // attempts on this model AND skip the fallback rotation — a\n // permanent error here will be permanent on the fallback too.\n return {\n value: null,\n succeeded: false,\n attempts: totalAttempts,\n error: errObj,\n attemptErrors,\n }\n }\n if (attempt < maxAttempts - 1) {\n await sleep(backoff(attempt))\n }\n }\n }\n // Exhausted attempts on this model — fall through to next model in the\n // rotation (if any). The backoff between MODEL rotations is the same\n // as the last per-attempt backoff (already slept above).\n }\n\n return {\n value: null,\n succeeded: false,\n attempts: totalAttempts,\n error: lastError,\n attemptErrors,\n }\n}\n","/**\n * Inter-critic / inter-pass orthogonality.\n *\n * Detects redundant ensembles. When you run N critics (or N audit passes,\n * or N specialized agents) on the same input, you want them to disagree —\n * each contributing distinct signal. If they all converge on the same set\n * of findings, you're paying N× cost for ~1× signal.\n *\n * The metric is `1 − mean pairwise cosine similarity` over bags of words\n * extracted from each pass's outputs. 1.0 = fully orthogonal,\n * 0.0 = fully redundant.\n *\n * Universal primitive: pass anything that produces text (findings, tool\n * calls rendered as JSON, verdict strings) and the matcher derives its own\n * vocabulary.\n */\n\nexport interface OrthogonalityInput<T> {\n passes: Array<{ findings: T[] }>\n /** Render one element to text. Default: defaultRender (concatenates string fields). */\n text?: (item: T) => string\n /** Minimum token length kept in the bag. Default 4 (drops short fillers). */\n minTokenLength?: number\n}\n\nexport interface OrthogonalityResult {\n /** 1 − mean pairwise cosine similarity across passes. 1=fully orthogonal, 0=fully redundant. */\n orthogonality: number\n /** Number of passes considered. */\n passCount: number\n /** Pairwise cosine similarities, in upper-triangular order (for debugging). */\n similarities: number[]\n}\n\nexport function passOrthogonality<T>(input: OrthogonalityInput<T>): OrthogonalityResult {\n const passes = input.passes\n if (passes.length < 2) {\n return { orthogonality: 1, passCount: passes.length, similarities: [] }\n }\n const render = input.text ?? defaultRender\n const minLen = input.minTokenLength ?? 4\n const vectors = passes.map((p) => bagOfWords(p.findings, render, minLen))\n const sims: number[] = []\n for (let i = 0; i < vectors.length; i++) {\n for (let j = i + 1; j < vectors.length; j++) {\n sims.push(cosineSimilarity(vectors[i]!, vectors[j]!))\n }\n }\n const mean = sims.length === 0 ? 0 : sims.reduce((a, b) => a + b, 0) / sims.length\n return {\n orthogonality: Math.max(0, Math.min(1, 1 - mean)),\n passCount: passes.length,\n similarities: sims,\n }\n}\n\nfunction defaultRender(item: unknown): string {\n if (typeof item === 'string') return item\n if (item && typeof item === 'object') {\n const parts: string[] = []\n for (const v of Object.values(item as Record<string, unknown>)) {\n if (typeof v === 'string') parts.push(v)\n }\n return parts.join(' ')\n }\n return String(item ?? '')\n}\n\nfunction bagOfWords<T>(\n items: T[],\n render: (item: T) => string,\n minLen: number,\n): Map<string, number> {\n const bag = new Map<string, number>()\n for (const item of items) {\n const text = render(item).toLowerCase()\n for (const tok of text.split(/[^a-z0-9]+/).filter((w) => w.length >= minLen)) {\n bag.set(tok, (bag.get(tok) ?? 0) + 1)\n }\n }\n return bag\n}\n\nfunction cosineSimilarity(a: Map<string, number>, b: Map<string, number>): number {\n let dot = 0\n let aMag = 0\n let bMag = 0\n for (const [, v] of a) aMag += v * v\n for (const [, v] of b) bMag += v * v\n for (const [k, v] of a) {\n const bv = b.get(k)\n if (bv) dot += v * bv\n }\n if (aMag === 0 || bMag === 0) return 0\n return dot / (Math.sqrt(aMag) * Math.sqrt(bMag))\n}\n","import type {\n ReferenceReplayCaseRun,\n ReferenceReplayRun,\n ReferenceReplayScenarioScore,\n} from './reference-replay'\nimport type { RunScore } from './run-score'\nimport type { SteeringBundle } from './steering'\nimport type { SteeringOptimizationRow } from './steering-optimizer'\n\nexport interface ReferenceReplaySteeringRowsOptions<Input = unknown> {\n bundleForRun?: (run: ReferenceReplayRun<Input>) => SteeringBundle\n scoreForCase?: (\n caseRun: ReferenceReplayCaseRun<Input>,\n run: ReferenceReplayRun<Input>,\n ) => RunScore\n}\n\nexport function referenceReplayRunsToSteeringRows<Input = unknown>(\n runs: ReferenceReplayRun<Input>[],\n options: ReferenceReplaySteeringRowsOptions<Input> = {},\n): SteeringOptimizationRow[] {\n const rows: SteeringOptimizationRow[] = []\n for (const run of runs) {\n const variantId = run.variantId ?? run.id\n const bundle = options.bundleForRun?.(run) ?? {\n id: variantId,\n metadata: run.metadata,\n }\n\n for (const caseRun of run.cases) {\n rows.push({\n variantId,\n scenarioId: caseRun.caseId,\n bundle,\n score:\n options.scoreForCase?.(caseRun, run) ??\n referenceReplayScenarioToRunScore(caseRun.score, caseRun.durationMs),\n metadata: {\n runId: run.id,\n split: caseRun.split,\n task: caseRun.metadata?.task ?? caseRun.metadata?.repo ?? caseRun.caseId,\n referenceCount: caseRun.references.length,\n candidateCount: caseRun.candidates.length,\n matched: caseRun.score.matched,\n total: caseRun.score.total,\n falsePositives: caseRun.score.falsePositives,\n precision: caseRun.score.precision,\n recall: caseRun.score.recall,\n f1: caseRun.score.f1,\n error: caseRun.error,\n ...(caseRun.metadata ?? {}),\n },\n })\n }\n }\n return rows\n}\n\nexport function referenceReplayScenarioToRunScore(\n scenarioScore: ReferenceReplayScenarioScore,\n durationMs = 0,\n): RunScore {\n const success = scenarioScore.f1\n const recall = scenarioScore.recall\n const precision = scenarioScore.precision\n const failed = scenarioScore.total > 0 && scenarioScore.matched === 0\n\n return {\n success,\n goalProgress: recall,\n repoGroundedness: precision,\n driftPenalty: 1 - precision,\n toolUseQuality: precision,\n patchQuality: 0,\n testReality: scenarioScore.total > 0 ? 1 : 0,\n finalGate: success,\n reviewerBlockers: failed ? 1 : 0,\n costUsd: 0,\n wallSeconds: Math.max(0, durationMs / 1000),\n notes: [\n `reference-replay matched ${scenarioScore.matched}/${scenarioScore.total}`,\n `precision=${precision.toFixed(3)} recall=${recall.toFixed(3)} f1=${success.toFixed(3)}`,\n ],\n }\n}\n","/**\n * Researcher interface — stable hook for an external autonomous-research\n * agent to drive the meta-loop.\n *\n * Implementations live downstream (typically in a private repo that\n * runs the actual LLM). This package ships only the contract + a\n * `NoopResearcher` so consumers can wire the surface without being\n * forced to implement every method up front.\n *\n * The four methods mirror the four stages of the paper \"Two Loops,\n * Three Roles\":\n *\n * inspectFailures — given the observed runs, what failure modes\n * are present? (data → diagnosis)\n * proposeChange — given diagnosed failure modes, what\n * structural changes should we try?\n * (diagnosis → plan delta)\n * applyChange — fold the proposed deltas into a concrete\n * experiment plan against an existing baseline.\n * (plan delta → executable plan)\n * evaluateChange — run the plan, return runs + the gate verdict.\n * (executable plan → verdict)\n *\n * Composition is the discipline: a Researcher implementation MUST\n * keep these four steps separate and inspectable. Conflating\n * \"diagnose + propose + run\" into a single LLM call defeats the\n * point of the framework — you can't audit which step lied.\n *\n * THIS INTERFACE IS STABLE. Breaking changes require a new module\n * (e.g. `Researcher2`) so existing implementations keep working.\n */\n\nimport type { GateDecision } from './held-out-gate'\nimport type { RunRecord, RunSplitTag } from './run-record'\n\n/** A diagnosed failure mode with the run-IDs that exhibit it. */\nexport interface FailureMode {\n /** Short machine-readable code. Must be stable across runs of the\n * same researcher to enable longitudinal tracking. */\n code: string\n /** Human-readable description for the paper / dashboard. */\n description: string\n evidence: {\n /** Run IDs (from `RunRecord.runId`) where this failure mode was\n * observed. */\n runIds: string[]\n /** Number of run samples that informed the diagnosis. */\n samples: number\n }\n}\n\n/** A single steering change the researcher wants to try. */\nexport interface SteeringChange {\n kind: 'reviewer_prompt' | 'skill_add' | 'skill_remove' | 'threshold' | 'budget'\n /** Implementation-specific payload. Researcher implementations\n * define the schema — keep this `unknown` here to avoid coupling\n * the public interface to any one researcher's internal model. */\n payload: unknown\n /** Why the researcher proposed this change. Goes into the audit\n * trail next to the failure-mode evidence. */\n rationale: string\n /** Optional self-reported expected delta on the headline metric. */\n expectedDelta?: number\n}\n\n/** A single experiment plan, mapped onto the search/holdout splits. */\nexport interface ExperimentPlan {\n baselineCandidateId: string\n proposedCandidateId: string\n changes: SteeringChange[]\n /** USD ceiling for the entire experiment. The runner must stop\n * before exceeding this and report a partial result. */\n evaluationBudgetUsd: number\n /** Item IDs (your dataset keys) for the search vs holdout splits. */\n splits: { search: string[]; holdout: string[] }\n}\n\n/** Result of running a plan: every run, plus the gate verdict. */\nexport interface ExperimentResult {\n plan: ExperimentPlan\n runs: RunRecord[]\n gateDecision: GateDecision\n}\n\n/**\n * The researcher loop. Stable, four-step, inspectable.\n *\n * ┌──────────┐ inspectFailures ┌──────────┐ proposeChange ┌──────────┐\n * │ runs │ ─────────────────▶│ failures │ ──────────────▶│ changes │\n * └──────────┘ └──────────┘ └────┬─────┘\n * │\n * ▼\n * ┌────────────────┐ applyChange ┌────────┐\n * │ ExperimentPlan │ ◀────────────│ base │\n * └────────┬───────┘ └────────┘\n * │\n * evaluateChange ▼\n * ┌────────────────┐\n * │ ExperimentResult│\n * └────────────────┘\n */\nexport interface Researcher {\n inspectFailures(runs: RunRecord[]): Promise<FailureMode[]>\n proposeChange(failures: FailureMode[]): Promise<SteeringChange[]>\n applyChange(changes: SteeringChange[], baseline: ExperimentPlan): Promise<ExperimentPlan>\n evaluateChange(plan: ExperimentPlan): Promise<ExperimentResult>\n}\n\nexport interface CallbackResearcherOptions {\n inspectFailures: Researcher['inspectFailures']\n proposeChange: Researcher['proposeChange']\n applyChange: Researcher['applyChange']\n evaluateChange: Researcher['evaluateChange']\n}\n\n/**\n * Minimal concrete researcher for tests, scripts, and small integrations.\n * Larger autonomous researchers can still implement `Researcher` directly.\n */\nexport class CallbackResearcher implements Researcher {\n constructor(private readonly callbacks: CallbackResearcherOptions) {}\n\n inspectFailures(runs: RunRecord[]): Promise<FailureMode[]> {\n return this.callbacks.inspectFailures(runs)\n }\n\n proposeChange(failures: FailureMode[]): Promise<SteeringChange[]> {\n return this.callbacks.proposeChange(failures)\n }\n\n applyChange(changes: SteeringChange[], baseline: ExperimentPlan): Promise<ExperimentPlan> {\n return this.callbacks.applyChange(changes, baseline)\n }\n\n evaluateChange(plan: ExperimentPlan): Promise<ExperimentResult> {\n return this.callbacks.evaluateChange(plan)\n }\n}\n\n/**\n * No-op researcher — fails loud on every method. Use as a placeholder\n * in code paths that wire the interface but don't have an implementation\n * yet. Importantly, this does NOT silently succeed: a no-op researcher\n * that returned empty arrays would muffle the loop's signal that\n * nobody implemented the brain.\n */\nexport class NoopResearcher implements Researcher {\n private readonly hint: string\n\n constructor(hint = 'NoopResearcher: no implementation wired') {\n this.hint = hint\n }\n\n async inspectFailures(_runs: RunRecord[]): Promise<FailureMode[]> {\n throw new Error(`${this.hint} (inspectFailures not implemented)`)\n }\n\n async proposeChange(_failures: FailureMode[]): Promise<SteeringChange[]> {\n throw new Error(`${this.hint} (proposeChange not implemented)`)\n }\n\n async applyChange(\n _changes: SteeringChange[],\n _baseline: ExperimentPlan,\n ): Promise<ExperimentPlan> {\n throw new Error(`${this.hint} (applyChange not implemented)`)\n }\n\n async evaluateChange(_plan: ExperimentPlan): Promise<ExperimentResult> {\n throw new Error(`${this.hint} (evaluateChange not implemented)`)\n }\n}\n\n/** Re-export the split alias so callers don't have to import twice. */\nexport type { RunSplitTag }\n","/**\n * SandboxPool — bounded checkout/release pool for mutation slots.\n *\n * The composite-mutator's `code` channel needs an isolated workspace per\n * mutation attempt: a git worktree, a sandbox container, a tmpdir clone —\n * whatever the consumer's runtime is. Without a pool, every consumer\n * re-implements the same machinery (mint N slots, check one out per\n * mutation, reset before reuse, drain at the end, track utilisation for\n * the cost ledger). This primitive ships that machinery so consumers\n * supply only a `SlotFactory`.\n *\n * Generic over a slot resource `T` so the same pool serves git worktrees\n * (T = path), Tangle sandboxes (T = SandboxBox), or anything else with\n * the create/reset/destroy lifecycle.\n *\n * Concurrency: FIFO via the shared `Mutex` primitive. Each `checkout()`\n * either takes an idle slot or queues until one is released. Lifecycle\n * is single-process — multi-process pools need external coordination\n * (file locks, etc.) and are deliberately out of scope.\n */\n\nimport { Mutex } from './concurrency'\n\nexport interface PoolSlot<T> {\n /** Stable id assigned at slot creation. Use for telemetry / lineage. */\n readonly id: string\n /** Consumer-defined resource. */\n readonly resource: T\n}\n\nexport interface SlotFactory<T> {\n /** Build a new slot. Called lazily as the pool grows up to `size`. */\n create(slotId: string): Promise<T>\n /**\n * Reset a slot to a clean state before reuse. Called BEFORE every\n * checkout returns it (including the first — so the factory's\n * `create` can leave the slot dirty and let `reset` normalise).\n * Optional; default is a no-op.\n */\n reset?(slot: PoolSlot<T>): Promise<void>\n /** Tear the slot down. Called by `drain()`. */\n destroy(slot: PoolSlot<T>): Promise<void>\n}\n\nexport interface SandboxPool<T> {\n /**\n * Take a slot. If all slots are busy, the promise resolves when one\n * is released. Always pair with the returned `release` (or wrap with\n * `withSlot`).\n */\n checkout(): Promise<{ slot: PoolSlot<T>; release: () => void }>\n /**\n * Run `fn` with a checked-out slot, releasing on completion or throw.\n * The convenience wrapper most callers should use.\n */\n withSlot<R>(fn: (slot: PoolSlot<T>) => Promise<R>): Promise<R>\n /** Destroy every slot. Idempotent. */\n drain(): Promise<void>\n /** How many slots have been minted (≤ `size`). */\n poolSize(): number\n /** How many checkouts are currently outstanding. */\n activeCheckouts(): number\n /** Snapshot of busy/total durations for the cost ledger. */\n utilization(): { busyMs: number; totalMs: number; checkouts: number }\n}\n\nexport interface CreateSandboxPoolOpts<T> {\n /** Maximum concurrent slots. Slots are minted on first need, not eagerly. */\n size: number\n factory: SlotFactory<T>\n}\n\ninterface SlotState<T> {\n slot: PoolSlot<T>\n busy: boolean\n}\n\nexport function createSandboxPool<T>(opts: CreateSandboxPoolOpts<T>): SandboxPool<T> {\n if (opts.size < 1) throw new Error(`sandbox pool size must be >= 1 (got ${opts.size})`)\n\n const slots: SlotState<T>[] = []\n const waiters: Array<(s: SlotState<T>) => void> = []\n const mutex = new Mutex()\n let nextSlotId = 0\n let totalCheckouts = 0\n let busyMs = 0\n const startedAt = Date.now()\n\n /**\n * Acquire — atomic across `mutex`. Either find an idle slot, mint a\n * new one (if under capacity), or queue. The mutex bounds at the\n * search/mint boundary; the actual create() runs OUTSIDE the lock so\n * a slow factory doesn't starve other waiters.\n */\n async function acquireSlot(): Promise<SlotState<T>> {\n let mintId: string | undefined\n const ready = await mutex.runExclusive(async () => {\n const idle = slots.find((s) => !s.busy)\n if (idle) {\n idle.busy = true\n return idle\n }\n if (slots.length < opts.size) {\n // Reserve a slot ID synchronously so concurrent acquireSlot\n // calls don't all decide to mint past the cap.\n mintId = `slot_${nextSlotId++}`\n return null\n }\n return null\n })\n if (ready) return ready\n if (mintId !== undefined) {\n const resource = await opts.factory.create(mintId)\n const state: SlotState<T> = {\n slot: { id: mintId, resource },\n busy: true,\n }\n await mutex.runExclusive(() => {\n slots.push(state)\n })\n return state\n }\n // All slots busy + at cap: queue.\n return new Promise<SlotState<T>>((resolve) => {\n waiters.push((s) => {\n s.busy = true\n resolve(s)\n })\n })\n }\n\n function releaseSlot(state: SlotState<T>): void {\n // Non-async release — runs synchronously inside the user's finally.\n // Reset is async; we kick it off and let the next waiter see a\n // freshly-reset slot once it lands.\n void (async () => {\n try {\n if (opts.factory.reset) await opts.factory.reset(state.slot)\n } catch (err) {\n // A failing reset is the consumer's bug; we still release\n // (otherwise the pool deadlocks). Surface via console.warn so\n // it doesn't get lost.\n console.warn(`[sandbox-pool] reset failed for slot ${state.slot.id}:`, err)\n }\n state.busy = false\n const next = waiters.shift()\n if (next) next(state)\n })()\n }\n\n async function checkout(): Promise<{ slot: PoolSlot<T>; release: () => void }> {\n const state = await acquireSlot()\n const checkoutStart = Date.now()\n totalCheckouts++\n return {\n slot: state.slot,\n release: () => {\n busyMs += Date.now() - checkoutStart\n releaseSlot(state)\n },\n }\n }\n\n async function withSlot<R>(fn: (slot: PoolSlot<T>) => Promise<R>): Promise<R> {\n const { slot, release } = await checkout()\n try {\n return await fn(slot)\n } finally {\n release()\n }\n }\n\n async function drain(): Promise<void> {\n // Snapshot under lock; destroy outside lock so a slow teardown\n // doesn't block a concurrent drain caller.\n const snapshot = await mutex.runExclusive(() => {\n const taken = slots.splice(0, slots.length)\n // Reject any pending waiters — pool is going away.\n for (const w of waiters.splice(0, waiters.length)) {\n // Best-effort rejection: the waiter is still pending; we\n // can't reject a Promise we already resolved. Surface as a\n // warning. In practice, drain() is called when nothing's in\n // flight (end of run), so this is a defensive no-op.\n void w\n }\n return taken\n })\n await Promise.allSettled(snapshot.map((s) => opts.factory.destroy(s.slot)))\n }\n\n function utilization() {\n return {\n busyMs,\n totalMs: Date.now() - startedAt,\n checkouts: totalCheckouts,\n }\n }\n\n return {\n checkout,\n withSlot,\n drain,\n poolSize: () => slots.length,\n activeCheckouts: () => slots.filter((s) => s.busy).length,\n utilization,\n }\n}\n","/**\n * Pipeline-level OTEL integration — auto-attaches an OTEL exporter when\n * OTEL_EXPORTER_OTLP_ENDPOINT is set. Pipelines call `withOtelPipeline()`\n * to get a configured exporter + shutdown handle without manual wiring.\n *\n * Used by: runEvalCampaign, runProductionLoop, runAgentMatrix.\n */\n\nimport { createOtelExporter, type OtelExportConfig, type OtelExporter } from './trace/otel-export'\n\nexport interface OtelPipelineHandle {\n /** The active exporter, or undefined if no endpoint is configured. */\n exporter: OtelExporter | undefined\n /** Call at pipeline end to flush + shutdown. Safe to call even if exporter is undefined. */\n shutdown(): Promise<void>\n}\n\nexport interface OtelPipelineOptions {\n /** Override OTEL config. */\n otelConfig?: OtelExportConfig\n /** Pipeline-specific resource attributes. */\n pipelineKind?: string\n pipelineId?: string\n}\n\n/**\n * Create an OTEL exporter scoped to a pipeline run. Auto-reads\n * OTEL_EXPORTER_OTLP_ENDPOINT from env when no explicit config is passed.\n *\n * Returns a handle with `exporter` (possibly undefined) and `shutdown()`.\n */\nexport function withOtelPipeline(opts?: OtelPipelineOptions): OtelPipelineHandle {\n const config: OtelExportConfig = {\n ...opts?.otelConfig,\n resourceAttributes: {\n ...(opts?.pipelineKind ? { 'pipeline.kind': opts.pipelineKind } : {}),\n ...(opts?.pipelineId ? { 'pipeline.id': opts.pipelineId } : {}),\n ...opts?.otelConfig?.resourceAttributes,\n },\n }\n\n const exporter = createOtelExporter(config)\n\n return {\n exporter,\n async shutdown() {\n if (exporter) await exporter.shutdown()\n },\n }\n}\n\n/**\n * Check if OTEL export is configured (endpoint is set).\n */\nexport function isOtelConfigured(): boolean {\n return !!(typeof process !== 'undefined' && process.env.OTEL_EXPORTER_OTLP_ENDPOINT)\n}\n","/**\n * Traced analyst wrapper — instruments `analyzeTraces` with spans so the\n * analyst's internal LLM calls (actor + responder turns) appear in the\n * trace tree. Also wraps each actor turn callback with a span.\n *\n * Since the analyst uses @ax-llm/ax internally (an agent framework with\n * its own turn loop), we cannot wrap individual `tc.chat()` calls without\n * forking ax. Instead, we wrap at the boundary:\n * 1. A parent span for the entire analyst run.\n * 2. Per-turn child spans from the `onTurn` callback (captures code,\n * output size, error status).\n * 3. Summary attributes on the parent (total turns, usage, findings).\n */\n\nimport type { TraceEmitter } from './trace/emitter'\nimport type {\n AnalyzeTracesInput,\n AnalyzeTracesOptions,\n AnalyzeTracesResult,\n AnalyzeTracesTurnSnapshot,\n} from './trace-analyst/analyst'\nimport { analyzeTraces } from './trace-analyst/analyst'\n\nexport interface TracedAnalystOptions {\n /** TraceEmitter for span emission. */\n emitter: TraceEmitter\n /** Parent span id. If omitted, uses emitter stack. */\n parentSpanId?: string\n}\n\n/**\n * Run `analyzeTraces` wrapped in a parent span with per-turn child spans.\n */\nexport async function tracedAnalyzeTraces(\n input: AnalyzeTracesInput,\n options: AnalyzeTracesOptions,\n traceOpts: TracedAnalystOptions,\n): Promise<AnalyzeTracesResult> {\n const parentSpan = await traceOpts.emitter.span({\n kind: 'custom',\n name: 'analyst:analyze-traces',\n parentSpanId: traceOpts.parentSpanId,\n attributes: {\n 'analyst.question_length': input.question.length,\n 'analyst.max_turns': options.maxTurns ?? 12,\n 'analyst.max_depth': options.maxDepth ?? 1,\n 'eval.phase': 'analyst',\n },\n })\n\n // Intercept onTurn to emit per-turn spans.\n const originalOnTurn = options.onTurn\n const turnSpanIds: string[] = []\n\n const wrappedOptions: AnalyzeTracesOptions = {\n ...options,\n onTurn: async (turn: AnalyzeTracesTurnSnapshot) => {\n const turnSpan = await traceOpts.emitter.span({\n kind: 'custom',\n name: `analyst:turn-${turn.turn}`,\n parentSpanId: parentSpan.span.spanId,\n attributes: {\n 'analyst.turn': turn.turn,\n 'analyst.is_error': turn.isError,\n 'analyst.code_length': turn.code.length,\n 'analyst.output_length': turn.output.length,\n 'eval.phase': 'analyst',\n },\n })\n turnSpanIds.push(turnSpan.span.spanId)\n if (turn.isError) {\n await turnSpan.fail('Turn produced an error')\n } else {\n await turnSpan.end()\n }\n if (originalOnTurn) await originalOnTurn(turn)\n },\n }\n\n try {\n const result = await analyzeTraces(input, wrappedOptions)\n await parentSpan.end({\n attributes: {\n 'analyst.question_length': input.question.length,\n 'analyst.turn_count': result.turnCount,\n 'analyst.finding_count': result.findings.length,\n 'analyst.answer_length': result.answer.length,\n 'eval.phase': 'analyst',\n },\n } as Record<string, unknown>)\n return result\n } catch (err) {\n await parentSpan.fail(err instanceof Error ? err : String(err))\n throw err\n }\n}\n","/**\n * Traced judge wrappers — instruments every LLM call inside the judge\n * ensemble with child spans so OTEL sinks see per-judge latency, model,\n * token counts, and score dimensions.\n *\n * The ensemble parent span groups all individual judge spans; each judge\n * gets its own child span with model + score as attributes.\n */\n\nimport type { TCloud } from '@tangle-network/tcloud'\nimport type { TraceEmitter } from './trace/emitter'\nimport type { JudgeFn, JudgeInput, JudgeScore } from './types'\n\nexport interface TracedJudgeOptions {\n /** TraceEmitter to emit spans into. */\n emitter: TraceEmitter\n /** Parent span id for the ensemble. If omitted, uses the emitter stack. */\n parentSpanId?: string\n}\n\n/**\n * Wrap a single JudgeFn so its LLM call emits a traced span.\n */\nexport function traceJudge(judge: JudgeFn, judgeName: string, opts: TracedJudgeOptions): JudgeFn {\n return async (tc: TCloud, input: JudgeInput): Promise<JudgeScore[]> => {\n const span = await opts.emitter.span({\n kind: 'llm',\n name: `judge:${judgeName}`,\n parentSpanId: opts.parentSpanId,\n attributes: {\n 'judge.name': judgeName,\n 'eval.phase': 'judge',\n },\n })\n try {\n const scores = await judge(tc, input)\n const composite =\n scores.length > 0 ? scores.reduce((sum, s) => sum + s.score, 0) / scores.length : 0\n await span.end({\n attributes: {\n 'judge.name': judgeName,\n 'judge.composite_score': composite,\n 'judge.dimension_count': scores.length,\n 'eval.phase': 'judge',\n },\n } as Record<string, unknown>)\n return scores\n } catch (err) {\n await span.fail(err instanceof Error ? err : String(err))\n throw err\n }\n }\n}\n\n/**\n * Wrap an array of JudgeFns with tracing, running them inside an ensemble\n * parent span. Returns a single function that calls all judges and merges\n * their scores.\n */\nexport function traceJudgeEnsemble(\n judges: JudgeFn[],\n judgeNames: string[],\n opts: TracedJudgeOptions,\n): JudgeFn {\n return async (tc: TCloud, input: JudgeInput) => {\n const ensembleSpan = await opts.emitter.span({\n kind: 'custom',\n name: 'judge:ensemble',\n parentSpanId: opts.parentSpanId,\n attributes: {\n 'judge.ensemble_size': judges.length,\n 'eval.phase': 'judge',\n },\n })\n try {\n const allScores: JudgeScore[] = []\n for (let i = 0; i < judges.length; i++) {\n const judge = judges[i]!\n const name = judgeNames[i] ?? `judge_${i}`\n const tracedFn = traceJudge(judge, name, {\n emitter: opts.emitter,\n parentSpanId: ensembleSpan.span.spanId,\n })\n const scores = await tracedFn(tc, input)\n allScores.push(...scores)\n }\n const composite =\n allScores.length > 0 ? allScores.reduce((sum, s) => sum + s.score, 0) / allScores.length : 0\n await ensembleSpan.end({\n attributes: {\n 'judge.ensemble_size': judges.length,\n 'judge.composite_score': composite,\n 'judge.total_dimensions': allScores.length,\n 'eval.phase': 'judge',\n },\n } as Record<string, unknown>)\n return allScores\n } catch (err) {\n await ensembleSpan.fail(err instanceof Error ? err : String(err))\n throw err\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6BO,IAAM,4BAA6C;AAAA,EACxD,SAAS;AAAA,EACT,cAAc;AAAA,EACd,kBAAkB;AAAA,EAClB,cAAc;AAAA,EACd,gBAAgB;AAAA,EAChB,cAAc;AAAA,EACd,aAAa;AAAA,EACb,WAAW;AAAA,EACX,kBAAkB;AAAA,EAClB,SAAS;AAAA,EACT,aAAa;AACf;AAEO,SAAS,kBAAkB,OAAiB,UAAoC,CAAC,GAAW;AACjG,QAAM,IAAI,EAAE,GAAG,2BAA2B,GAAG,QAAQ;AACrD,SACE,EAAE,UAAU,QAAQ,MAAM,OAAO,IACjC,EAAE,eAAe,QAAQ,MAAM,YAAY,IAC3C,EAAE,mBAAmB,QAAQ,MAAM,gBAAgB,IACnD,EAAE,eAAe,QAAQ,MAAM,YAAY,IAC3C,EAAE,iBAAiB,QAAQ,MAAM,cAAc,IAC/C,EAAE,eAAe,QAAQ,MAAM,YAAY,IAC3C,EAAE,cAAc,QAAQ,MAAM,WAAW,IACzC,EAAE,YAAY,QAAQ,MAAM,SAAS,IACrC,EAAE,mBAAmB,QAAQ,MAAM,gBAAgB,IACnD,EAAE,UAAU,KAAK,IAAI,GAAG,aAAa,MAAM,OAAO,CAAC,IACnD,EAAE,cAAc,KAAK,IAAI,GAAG,aAAa,MAAM,WAAW,IAAI,EAAE;AAEpE;AAEO,SAAS,QAAQ,OAAuB;AAC7C,MAAI,CAAC,OAAO,SAAS,KAAK,EAAG,QAAO;AACpC,SAAO,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,KAAK,CAAC;AACvC;AAEA,SAAS,aAAa,OAAuB;AAC3C,SAAO,OAAO,SAAS,KAAK,IAAI,QAAQ;AAC1C;;;AClDA,IAAM,yBAAyB;AAAA,EAC7B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEO,IAAM,YAAN,MAAgB;AAAA,EACJ;AAAA,EACA;AAAA,EAEjB,YAAY,UAA4B,CAAC,GAAG;AAC1C,SAAK,UAAU,QAAQ;AACvB,SAAK,gBAAgB,QAAQ,iBAAiB;AAAA,EAChD;AAAA,EAEA,MAAM,MAAM,OAAmB,OAAkC;AAC/D,UAAM,MAAM,MAAM,MAAM,OAAO,KAAK;AACpC,QAAI,CAAC,IAAK,OAAM,IAAI,cAAc,OAAO,KAAK,YAAY;AAC1D,UAAM,CAAC,OAAO,QAAQ,WAAW,MAAM,IAAI,MAAM,QAAQ,IAAI;AAAA,MAC3D,MAAM,MAAM,EAAE,MAAM,CAAC;AAAA,MACrB,MAAM,OAAO,EAAE,MAAM,CAAC;AAAA,MACtB,MAAM,UAAU,KAAK;AAAA,MACrB,MAAM,OAAO,KAAK;AAAA,IACpB,CAAC;AACD,WAAO,KAAK,WAAW,EAAE,KAAK,OAAO,QAAQ,WAAW,OAAO,CAAC;AAAA,EAClE;AAAA,EAEA,WAAW,OAA2B;AACpC,UAAM,QAAkB,CAAC;AACzB,UAAMA,YAAW,MAAM,MAAM;AAAA,MAC3B,CAAC,MAA2C,EAAE,SAAS;AAAA,IACzD;AACA,UAAMC,aAAY,MAAM,MAAM;AAAA,MAC5B,CAAC,MAA4C,EAAE,SAAS;AAAA,IAC1D;AACA,UAAMC,cAAa,MAAM,MAAM;AAAA,MAC7B,CAAC,MAA6C,EAAE,SAAS;AAAA,IAC3D;AACA,UAAM,eAAe,MAAM,MAAM;AAAA,MAC/B,CAAC,MAA+C,EAAE,SAAS;AAAA,IAC7D;AACA,UAAM,iBAAiBA,YAAW;AAAA,MAChC,CAAC,SAAS,KAAK,cAAc,gBAAgB,KAAK,YAAY,cAAc;AAAA,IAC9E;AAEA,UAAM,UACJ,MAAM,IAAI,SAAS,SAAS,OAAO,IAAI,MAAM,IAAI,WAAW,cAAc,MAAM;AAClF,QAAI,CAAC,QAAS,OAAM,KAAK,qCAAqC;AAE9D,UAAM,eAAeA,YAAW,SAC5BA,YAAW,OAAO,CAACC,MAAK,SAASA,OAAM,oBAAoB,KAAK,KAAK,GAAG,CAAC,IACzED,YAAW,SACX;AACJ,UAAM,eACJ,OAAO,MAAM,IAAI,SAAS,UAAU,WAChC;AAAA,MACE,MAAM,IAAI,QAAQ,QAAQ,IAAI,MAAM,IAAI,QAAQ,QAAQ,MAAM,MAAM,IAAI,QAAQ;AAAA,IAClF,IACA;AACN,UAAM,eAAe,gBAAgB,gBAAgB;AAErD,UAAM,kBAAkBD,WAAU,OAAO,CAAC,SAAS,KAAK,WAAW,OAAO,EAAE;AAC5E,UAAM,iBAAiBA,WAAU,WAAW,IAAI,IAAI,kBAAkBA,WAAU;AAChF,QAAIA,WAAU,WAAW,EAAG,OAAM,KAAK,wBAAwB;AAE/D,UAAM,gBACJ,MAAM,UAAU,SAChBA,WAAU,OAAO,CAAC,SAAS,0BAA0B,KAAK,KAAK,QAAQ,CAAC,EAAE;AAC5E,UAAM,eAAe,gBAAgB,IAAI,QAAQ,gBAAgB,CAAC,IAAI;AACtE,QAAI,CAAC,aAAc,OAAM,KAAK,uCAAuC;AAErE,UAAM,eAAe,aAAa;AAAA,MAChC,CAAC,SAAS,OAAO,KAAK,eAAe,YAAY,KAAK,aAAa;AAAA,IACrE;AACA,UAAM,cAAc,aAAa,SAC7B,aAAa;AAAA,MACX,CAACE,MAAK,SAASA,QAAO,KAAK,eAAe,KAAK,KAAK,IAAI,GAAG,KAAK,cAAc,CAAC;AAAA,MAC/E;AAAA,IACF,IAAI,aAAa,SACjBF,WAAU;AAAA,MAAK,CAAC,SACZ,yCAAyC,KAAK,KAAK,UAAU,KAAK,IAAI,CAAC;AAAA,IACzE,IACA,MACA;AACN,QAAI,CAAC,YAAa,OAAM,KAAK,sCAAsC;AAEnE,UAAM,eAAeC,YAAW,OAAO,CAAC,SAAS,gBAAgB,IAAI,CAAC;AACtE,UAAM,oBAAoB,eAAe,OAAO,CAAC,SAAS,gBAAgB,IAAI,CAAC;AAC/E,UAAM,YAAY,eAAe,SAAU,kBAAkB,SAAS,IAAI,IAAK;AAC/E,QAAI,kBAAkB;AACpB,YAAM,KAAK,yBAAyB,kBAAkB,MAAM,cAAc;AAAA,aACnE,CAAC,eAAe,OAAQ,OAAM,KAAK,iCAAiC;AAE7E,UAAM,mBAAmBA,YAAW,SAAS,aAAa,SAASA,YAAW,SAAS;AACvF,QAAI,iBAAkB,OAAM,KAAK,YAAY,aAAa,MAAM,8BAA8B;AAE9F,UAAM,2BACJ,gBACA,aAAa,SACbF,UAAS,OAAO,CAAC,SAAS,kBAAkB,KAAK,UAAU,EAAE,CAAC,EAAE;AAClE,UAAM,eACJA,UAAS,OAAO,CAAC,SAAS,KAAK,QAAQ,KAAK,UAAU,EAAE,CAAC,EAAE,SAC3D,MAAM,OAAO,OAAO,CAAC,UAAU,KAAK,QAAQ,KAAK,UAAU,MAAM,OAAO,CAAC,CAAC,EAAE;AAC9E,UAAM,mBACJ,2BAA2B,iBAAiB,IACxC,IACA,4BAA4B,2BAA2B;AAC7D,UAAM,eACJ,2BAA2B,iBAAiB,IACxC,IACA,gBAAgB,2BAA2B;AACjD,QAAI,eAAe,EAAG,OAAM,KAAK,YAAY,YAAY,kBAAkB;AAE3E,UAAM,UAAU,MAAM,OAAO,SACzB,KAAK;AAAA,MACH,GAAG,MAAM,OACN,OAAO,CAAC,UAA6B,MAAM,cAAc,KAAK,EAC9D,IAAI,CAAC,UAA6B,MAAM,QAAQ;AAAA,MACnD;AAAA,IACF,IACAA,UAAS,OAAO,CAACG,MAAK,SAASA,QAAO,KAAK,WAAW,IAAI,CAAC;AAC/D,UAAM,cACJ,MAAM,IAAI,WAAW,MAAM,IAAI,YAC3B,KAAK,IAAI,IAAI,MAAM,IAAI,UAAU,MAAM,IAAI,aAAa,GAAI,IAC5D;AAEN,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,KAAK,OAAyB;AAC5B,WAAO,kBAAkB,OAAO,KAAK,OAAO;AAAA,EAC9C;AAAA,EAEQ,QAAQ,MAAuB;AACrC,WAAO,KAAK,cAAc,KAAK,CAAC,YAAY,QAAQ,KAAK,IAAI,CAAC;AAAA,EAChE;AACF;AAEA,SAAS,oBAAoB,OAAuB;AAClD,SAAO,QAAQ,IAAI,QAAQ,QAAQ,EAAE,IAAI,QAAQ,KAAK;AACxD;AAEA,SAAS,kBAAkB,MAAuB;AAChD,SAAO,qGAAqG;AAAA,IAC1G;AAAA,EACF;AACF;AAEA,SAAS,gBAAgB,MAAiD;AACxE,SACE,KAAK,YAAY,aAAa,QAC9B,KAAK,YAAY,YAAY,cAC7B,eAAe,KAAK,YAAY,gBAAgB,KAChD,eAAe,KAAK,YAAY,YAAY,KAC5C,KAAK,SAAS;AAElB;AAEA,SAAS,eAAe,OAAyB;AAC/C,SAAO,OAAO,UAAU,YAAY,QAAQ;AAC9C;;;ACvFO,IAAM,6BAAgE;AAAA,EAC3E,QAAQ;AAAA,EACR,WAAW;AAAA,EACX,SAAS;AACX;AA2BO,IAAM,iCAAiC;AAE9C,IAAM,qBAAqB;AAC3B,IAAM,mBAAmB;AACzB,IAAM,uBAAuB;AAC7B,IAAM,kBAAkB;AACxB,IAAM,gBAAgB;AAEtB,IAAM,kBAAkB;AAAA,EACtB,MAAM;AAAA,EACN,sBAAsB;AAAA,EACtB,UAAU,CAAC,WAAW,UAAU;AAAA,EAChC,YAAY;AAAA,IACV,SAAS,EAAE,MAAM,UAAU,WAAW,IAAI,WAAW,IAAI;AAAA,IACzD,UAAU;AAAA,MACR,MAAM;AAAA,MACN,UAAU;AAAA,MACV,OAAO;AAAA,QACL,MAAM;AAAA,QACN,sBAAsB;AAAA,QACtB,UAAU,CAAC,WAAW,WAAW,SAAS,YAAY,UAAU;AAAA,QAChE,YAAY;AAAA,UACV,SAAS,EAAE,MAAM,UAAU,WAAW,GAAG,WAAW,IAAI;AAAA,UACxD,SAAS,EAAE,MAAM,UAAU;AAAA,UAC3B,OAAO,EAAE,MAAM,UAAU,SAAS,GAAG,SAAS,GAAG;AAAA,UACjD,UAAU,EAAE,MAAM,UAAU,WAAW,GAAG,WAAW,IAAI;AAAA,UACzD,UAAU,EAAE,MAAM,UAAU,MAAM,CAAC,YAAY,SAAS,SAAS,MAAM,EAAE;AAAA,QAC3E;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,SAAS,MAAc,KAAa,OAAuB;AAClE,MAAI,KAAK,UAAU,IAAK,QAAO;AAC/B,SAAO,GAAG,KAAK,MAAM,GAAG,GAAG,CAAC;AAAA,oBAAkB,KAAK,SAAS,GAAG,aAAa,KAAK;AACnF;AAEA,SAAS,YACP,OACA,MACQ;AACR,QAAM,aAAa,MAAM,YACtB,OAAO,CAAC,MAAM,EAAE,QAAQ,UAAU,KAAK,eAAe,EACtD,IAAI,CAAC,MAAM,aAAa,EAAE,IAAI;AAAA,EAAS,EAAE,OAAO,EAAE,EAClD,KAAK,MAAM;AAEd,QAAM,OAAO,MAAM,cAAc;AAEjC,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUP,MAAM,WAAW;AAAA;AAAA,EAEjB,MAAM,gBAAgB;AAAA,UAA+B,MAAM,aAAa;AAAA,iBAAoB,MAAM,uBAAuB,EAAE;AAAA;AAAA,IAAS,EAAE;AAAA,EACtI,MAAM,iBACL;AAAA,IACC,CAAC,GAAG,MACF,KAAK,IAAI,CAAC,MAAM,EAAE,IAAI,IAAI,EAAE,UAAU,SAAS,mBAAc,EAAE,SAAS,MAAM,GAAG,CAAC,EAAE,KAAK,KAAK,CAAC,MAAM,EAAE;AAAA,EAC3G,EACC,KAAK,IAAI,CAAC;AAAA;AAAA,EAEX,OAAO;AAAA,EAAqD,SAAS,MAAM,KAAK,cAAc,MAAM,CAAC;AAAA;AAAA,IAAS,EAAE;AAAA,EAChH,SAAS,YAAY,KAAK,gBAAgB,QAAQ,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAkBrD;AASA,eAAsB,wBACpB,OACA,UAAuC,CAAC,GACH;AACrC,QAAM,QAAQ,KAAK,IAAI;AACvB,QAAM,aAAa,MAAM,iBAAiB;AAE1C,MAAI,eAAe,GAAG;AACpB,WAAO;AAAA,MACL,MAAM;AAAA,MACN,SAAS;AAAA,MACT,OAAO;AAAA,MACP,cAAc;AAAA,MACd,YAAY;AAAA,MACZ,UAAU,CAAC;AAAA,MACX,SAAS;AAAA,MACT,YAAY;AAAA,MACZ,SAAS;AAAA,MACT,WAAW;AAAA,MACX,OAAO;AAAA,IACT;AAAA,EACF;AAEA,QAAM,OAA8C;AAAA,IAClD,OAAO,QAAQ,SAAS;AAAA,IACxB,WAAW,QAAQ,aAAa;AAAA,IAChC,gBAAgB,QAAQ,kBAAkB;AAAA,IAC1C,iBAAiB,QAAQ,mBAAmB;AAAA,IAC5C,cAAc,QAAQ,gBAAgB;AAAA,IACtC,KAAK,QAAQ,OAAO,CAAC;AAAA,IACrB,gBAAgB,QAAQ,kBAAkB;AAAA,IAC1C,mBAAmB,EAAE,GAAG,4BAA4B,GAAI,QAAQ,qBAAqB,CAAC,EAAG;AAAA,EAC3F;AAMA,QAAM,mBAAmB,CAAC,SAA8B;AACtD,QAAI,KAAK,mBAAmB,OAAQ,QAAO;AAC3C,QAAI,KAAK,UAAU,KAAM,QAAO,KAAK;AACrC,QAAI,KAAK,mBAAmB,cAAc;AACxC,aAAO,KAAK,kBAAkB,KAAK,cAAc,QAAQ,KAAK;AAAA,IAChE;AACA,WAAO;AAAA,EACT;AACA,QAAM,eAAe,IAAI;AAAA,IACvB,MAAM,iBAAiB,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,iBAAiB,CAAC,CAAC,CAAC;AAAA,EACjE;AAEA,MAAI;AACF,UAAM,EAAE,OAAO,OAAO,IAAI,MAAM;AAAA,MAI9B;AAAA,QACE,OAAO,KAAK;AAAA,QACZ,UAAU;AAAA,UACR;AAAA,YACE,MAAM;AAAA,YACN,SACE;AAAA,UACJ;AAAA,UACA,EAAE,MAAM,QAAQ,SAAS,YAAY,OAAO,IAAI,EAAE;AAAA,QACpD;AAAA,QACA,YAAY,EAAE,MAAM,0BAA0B,QAAQ,gBAAgB;AAAA,QACtE,aAAa;AAAA,QACb,WAAW,KAAK;AAAA,MAClB;AAAA,MACA,KAAK;AAAA,IACP;AAEA,QAAI,CAAC,OAAO,YAAY,CAAC,MAAM,QAAQ,MAAM,QAAQ,GAAG;AACtD,YAAM,IAAI,MAAM,0EAAqE;AAAA,IACvF;AAEA,UAAM,WAA6B,MAAM,SAAS,IAAI,CAAC,OAAO;AAAA,MAC5D,SAAS,OAAO,EAAE,OAAO;AAAA,MACzB,SAAS,QAAQ,EAAE,OAAO;AAAA,MAC1B,OAAO,KAAK,IAAI,GAAG,KAAK,IAAI,IAAI,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC;AAAA,MACrD,UAAU,OAAO,EAAE,YAAY,EAAE;AAAA,MACjC,UAAW,CAAC,YAAY,SAAS,SAAS,MAAM,EAAY,SAAS,EAAE,QAAQ,IAC3E,EAAE,WACF;AAAA,IACN,EAAE;AAEF,UAAM,eAAe,SAAS,OAAO,CAAC,MAAM,EAAE,WAAW,EAAE,SAAS,CAAC,EAAE;AACvE,QAAI,YAAY;AAChB,QAAI,mBAAmB;AACvB,eAAW,KAAK,UAAU;AACxB,YAAM,IAAI,aAAa,IAAI,EAAE,OAAO,KAAK;AACzC,mBAAa;AACb,0BAAoB,IAAI,EAAE;AAAA,IAC5B;AACA,UAAM,WACJ,YAAY,IACR,mBAAmB,YACnB,SAAS,OAAO,CAAC,GAAG,MAAM,IAAI,EAAE,OAAO,CAAC,IAAI,KAAK,IAAI,GAAG,SAAS,MAAM;AAE7E,WAAO;AAAA,MACL,MAAM;AAAA,MACN,SAAS;AAAA,MACT,OAAO,QAAQ,WAAW,IAAI,QAAQ,CAAC,CAAC;AAAA,MACxC;AAAA,MACA;AAAA,MACA;AAAA,MACA,SAAS,OAAO,MAAM,WAAW,EAAE;AAAA,MACnC,YAAY,KAAK,IAAI,IAAI;AAAA,MACzB,SAAS,OAAO,WAAW;AAAA,MAC3B,WAAW;AAAA,IACb;AAAA,EACF,SAAS,KAAK;AACZ,WAAO;AAAA,MACL,MAAM;AAAA,MACN,SAAS;AAAA,MACT,OAAO;AAAA,MACP,cAAc;AAAA,MACd;AAAA,MACA,UAAU,CAAC;AAAA,MACX,SAAS;AAAA,MACT,YAAY,KAAK,IAAI,IAAI;AAAA,MACzB,SAAS;AAAA,MACT,WAAW;AAAA,MACX,OAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,IACxD;AAAA,EACF;AACF;AAMO,SAAS,2BACd,UAAuC,CAAC,GACmC;AAC3E,SAAO,CAAC,UAAU,wBAAwB,OAAO,OAAO;AAC1D;;;ACjWA,SAAS,kBAAkB;AAsKpB,SAAS,iBAAiB,OAOtB;AACT,QAAM,QAAQ,KAAK,UAAU;AAAA,IAC3B,GAAG,MAAM;AAAA,IACT,GAAG,MAAM;AAAA,IACT,GAAG,MAAM,WAAW;AAAA,IACpB,GAAG,eAAe,MAAM,YAAY,MAAM,KAAK;AAAA,EACjD,CAAC;AACD,SAAO,KAAK,WAAW,QAAQ,EAAE,OAAO,KAAK,EAAE,OAAO,KAAK,EAAE,MAAM,GAAG,EAAE,CAAC;AAC3E;AAEA,SAAS,eAAe,GAAmB;AAGzC,SAAO,EACJ,YAAY,EACZ,QAAQ,QAAQ,GAAG,EACnB,QAAQ,eAAe,EAAE,EACzB,KAAK;AACV;AAMO,SAAS,YACd,MAIgB;AAChB,QAAM,EAAE,UAAU,aAAa,GAAG,KAAK,IAAI;AAC3C,SAAO;AAAA,IACL,gBAAgB;AAAA,IAChB,YAAY,iBAAiB;AAAA,MAC3B,YAAY,KAAK;AAAA,MACjB,MAAM,KAAK;AAAA,MACX,SAAS,KAAK;AAAA,MACd,OAAO,KAAK;AAAA,MACZ;AAAA,IACF,CAAC;AAAA,IACD,aAAa,gBAAe,oBAAI,KAAK,GAAE,YAAY;AAAA,IACnD,GAAG;AAAA,EACL;AACF;;;AClMA,IAAM,cAAc;AAIb,SAAS,aAAa,GAAmC;AAC9D,UAAQ,GAAG;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,EACX;AACF;AAwBO,SAAS,0BACd,MAC6B;AAC7B,QAAM,KAAK,KAAK,MAAM;AACtB,QAAM,OAAO,KAAK,QAAQ;AAC1B,SAAO;AAAA,IACL;AAAA,IACA,aACE;AAAA,IACF,WAAW;AAAA,IACX,MAAM,EAAE,MAAM,OAAO,QAAQ,KAAK,QAAQ,CAAC,KAAK,KAAK,IAAI,OAAU;AAAA,IACnE,SAAS,iBAAiB,WAAW;AAAA,IACrC,MAAM,QAAQ,OAAO,KAAK;AACxB,YAAM,MAAwB,CAAC;AAC/B,iBAAW,YAAY,KAAK,WAAW;AACrC,YAAI,IAAI,QAAQ,QAAS;AACzB,cAAM,SAAS,MAAM;AAAA,UACnB,EAAE,SAAS;AAAA,UACX,EAAE,QAAQ,OAAO,IAAI,KAAK,IAAI,OAAO,KAAK,OAAO,GAAG,KAAK,MAAM;AAAA,QACjE;AACA,cAAM,UAAU,IAAI,MAAM,WAAW,SAAS,MAAM,GAAG,EAAE;AAIzD,YAAI,OAAO,SAAS,WAAW,GAAG;AAChC,cAAI;AAAA,YACF,YAAY;AAAA,cACV,YAAY;AAAA,cACZ;AAAA,cACA;AAAA,cACA,OAAO,OAAO,OAAO,MAAM,GAAG,GAAG;AAAA,cACjC,WAAW,OAAO;AAAA,cAClB,UAAU;AAAA,cACV,YAAY;AAAA,cACZ,eAAe,CAAC;AAAA,cAChB,UAAU;AAAA,gBACR,sBAAsB,OAAO;AAAA,gBAC7B,OAAO,OAAO;AAAA,cAChB;AAAA,YACF,CAAC;AAAA,UACH;AACA;AAAA,QACF;AACA,eAAO,SAAS,QAAQ,CAAC,OAAO,MAAM;AACpC,cAAI;AAAA,YACF,YAAY;AAAA,cACV,YAAY;AAAA,cACZ;AAAA,cACA;AAAA,cACA;AAAA,cACA,WAAW,MAAM,IAAI,OAAO,SAAS;AAAA,cACrC,UAAU;AAAA,cACV,YAAY;AAAA,cACZ,eAAe,CAAC;AAAA,cAChB,UAAU,EAAE,UAAU,OAAO,OAAO,WAAW,eAAe,EAAE;AAAA,YAClE,CAAC;AAAA,UACH;AAAA,QACF,CAAC;AAAA,MACH;AACA,aAAO;AAAA,IACT;AAAA,EACF;AACF;AAeO,SAAS,sBAA2B,MAA8C;AACvF,QAAM,KAAK,KAAK,MAAM;AACtB,QAAM,OAAO,KAAK,QAAQ;AAC1B,SAAO;AAAA,IACL;AAAA,IACA,aACE;AAAA,IACF,WAAW;AAAA,IACX,MAAM,EAAE,MAAM,gBAAgB;AAAA,IAC9B,SAAS,YAAY,WAAW;AAAA,IAChC,MAAM,QAAQ,KAAK,KAAK;AACtB,YAAM,SAAS,MAAM,KAAK,SAAS,IAAI,EAAE,KAAK,GAAG,KAAK,QAAQ,CAAC;AAC/D,YAAM,MAAwB,CAAC;AAC/B,iBAAW,SAAS,OAAO,QAAQ;AACjC,mBAAWC,YAAW,MAAM,UAAU;AACpC,cAAI,KAAK,iBAAiB,IAAI,MAAM,MAAM,OAAOA,QAAO,CAAC;AAAA,QAC3D;AAGA,YAAI,MAAM,WAAW,UAAU,MAAM,WAAW,WAAW,MAAM,WAAW,WAAW;AACrF,cAAI;AAAA,YACF,YAAY;AAAA,cACV,YAAY;AAAA,cACZ;AAAA,cACA,SAAS,MAAM;AAAA,cACf,OAAO,UAAU,MAAM,KAAK,KAAK,MAAM,MAAM,KAAK,MAAM,UAAU,iBAAiB;AAAA,cACnF,UACE,MAAM,WAAW,UAAU,SAAS,MAAM,WAAW,YAAY,WAAW;AAAA,cAC9E,YAAY;AAAA,cACZ,eAAe,CAAC;AAAA,cAChB,UAAU;AAAA,gBACR,cAAc,MAAM;AAAA,gBACpB,aAAa,MAAM;AAAA,gBACnB,OAAO,MAAM;AAAA,gBACb,aAAa,MAAM;AAAA,cACrB;AAAA,YACF,CAAC;AAAA,UACH;AAAA,QACF;AAAA,MACF;AACA,UAAI,MAAM,qBAAqB;AAAA,QAC7B,QAAQ,OAAO,OAAO;AAAA,QACtB,SAAS,OAAO;AAAA,QAChB,UAAU,OAAO;AAAA,MACnB,CAAC;AACD,aAAO;AAAA,IACT;AAAA,EACF;AACF;AAEA,SAAS,iBACP,YACA,MACA,OACA,GACgB;AAChB,SAAO,YAAY;AAAA,IACjB;AAAA,IACA;AAAA,IACA,SAAS,EAAE,SAAS;AAAA,IACpB,OAAO,EAAE;AAAA,IACT,UAAU,aAAa,EAAE,QAAQ;AAAA,IACjC,YAAY;AAAA,IACZ,eAAe,EAAE,WACb,CAAC,EAAE,MAAM,YAAY,KAAK,mBAAmB,SAAS,EAAE,SAAS,CAAC,IAClE,CAAC;AAAA,IACL,UAAU,EAAE;AAAA,EACd,CAAC;AACH;AAYO,SAAS,uBAAuB,OAA6B,CAAC,GAAsB;AACzF,QAAM,KAAK,KAAK,MAAM;AACtB,QAAM,OAAO,KAAK,QAAQ;AAC1B,QAAM,SAAS,KAAK,UAAU,IAAI,UAAU;AAC5C,QAAM,YAAY,KAAK,aAAa;AACpC,SAAO;AAAA,IACL;AAAA,IACA,aACE;AAAA,IACF,WAAW;AAAA,IACX,MAAM,EAAE,MAAM,gBAAgB;AAAA,IAC9B,SAAS,cAAc,WAAW;AAAA,IAClC,MAAM,QAAQ,OAAO;AACnB,YAAM,QAAQ,OAAO,WAAW,KAAK;AACrC,YAAM,MAAwB,CAAC;AAC/B,YAAM,OAA6D;AAAA,QACjE,CAAC,WAAW,YAAY,mCAAmC;AAAA,QAC3D,CAAC,gBAAgB,QAAQ,sBAAsB;AAAA,QAC/C,CAAC,oBAAoB,QAAQ,6CAA6C;AAAA,QAC1E,CAAC,kBAAkB,UAAU,yBAAyB;AAAA,QACtD,CAAC,gBAAgB,UAAU,6BAA6B;AAAA,QACxD,CAAC,eAAe,QAAQ,6BAA6B;AAAA,QACrD,CAAC,aAAa,YAAY,wBAAwB;AAAA,MACpD;AACA,iBAAW,CAAC,KAAK,KAAK,GAAG,KAAK,MAAM;AAClC,cAAM,QAAQ,MAAM,GAAG;AACvB,YAAI,OAAO,UAAU,YAAY,QAAQ,WAAW;AAClD,cAAI;AAAA,YACF,YAAY;AAAA,cACV,YAAY;AAAA,cACZ;AAAA,cACA,SAAS;AAAA,cACT,OAAO;AAAA,cACP,WAAW,GAAG,GAAG,IAAI,MAAM,QAAQ,CAAC,CAAC,oBAAoB,SAAS;AAAA,cAClE,UAAU;AAAA,cACV,YAAY;AAAA,cACZ,eAAe,CAAC;AAAA,cAChB,UAAU,EAAE,WAAW,KAAK,OAAO,WAAW,QAAQ,MAAM,IAAI,MAAM;AAAA,YACxE,CAAC;AAAA,UACH;AAAA,QACF;AAAA,MACF;AAEA,UAAI,MAAM,eAAe,IAAI,WAAW;AACtC,YAAI;AAAA,UACF,YAAY;AAAA,YACV,YAAY;AAAA,YACZ;AAAA,YACA,SAAS;AAAA,YACT,OAAO;AAAA,YACP,WAAW,gBAAgB,MAAM,aAAa,QAAQ,CAAC,CAAC;AAAA,YACxD,UAAU;AAAA,YACV,YAAY;AAAA,YACZ,eAAe,CAAC;AAAA,YAChB,UAAU,EAAE,eAAe,MAAM,cAAc,OAAO,MAAM,MAAM;AAAA,UACpE,CAAC;AAAA,QACH;AAAA,MACF;AACA,aAAO;AAAA,IACT;AAAA,EACF;AACF;AAgBO,SAAS,mBAAmB,MAA6C;AAC9E,QAAM,KAAK,KAAK,MAAM;AACtB,QAAM,OAAO,KAAK,QAAQ;AAC1B,QAAM,YAAY,KAAK,aAAa;AACpC,SAAO;AAAA,IACL;AAAA,IACA,aACE;AAAA,IACF,WAAW;AAAA,IACX,MAAM,KAAK,QAAQ,EAAE,MAAM,MAAM;AAAA,IACjC,SAAS,SAAS,WAAW;AAAA,IAC7B,MAAM,QAAQ,OAAO;AACnB,YAAMC,UAAS,MAAM,KAAK,MAAM,KAAK,QAAQ,KAAK;AAClD,aAAOA,QACJ,OAAO,CAAC,MAAM,YAAY,EAAE,KAAK,IAAI,SAAS,EAC9C,IAAI,CAAC,MAAM,eAAe,IAAI,MAAM,CAAC,CAAC;AAAA,IAC3C;AAAA,EACF;AACF;AAEA,SAAS,YAAY,GAAmB;AAEtC,SAAO,KAAK,IAAI,IAAI,KAAK;AAC3B;AAEA,SAAS,eAAe,YAAoB,MAAc,GAA+B;AACvF,QAAM,UAAU,YAAY,EAAE,KAAK;AACnC,QAAM,WACJ,UAAU,IAAI,aAAa,UAAU,IAAI,SAAS,UAAU,IAAI,WAAW;AAC7E,SAAO,YAAY;AAAA,IACjB;AAAA,IACA;AAAA,IACA,SAAS,EAAE;AAAA,IACX,OAAO,GAAG,EAAE,SAAS,IAAI,EAAE,SAAS,WAAW,QAAQ,QAAQ,CAAC,CAAC;AAAA,IACjE,WAAW,EAAE;AAAA,IACb;AAAA,IACA,YAAY;AAAA,IACZ,eAAe,EAAE,WACb,CAAC,EAAE,MAAM,YAAY,KAAK,mBAAmB,SAAS,EAAE,SAAS,CAAC,IAClE,CAAC;AAAA,IACL,UAAU,EAAE,YAAY,EAAE,WAAW,WAAW,EAAE,WAAW,UAAU,QAAQ;AAAA,EACjF,CAAC;AACH;AAUO,SAAS,kCACd,OAAwC,CAAC,GACL;AACpC,QAAM,KAAK,KAAK,MAAM;AACtB,QAAM,OAAO,KAAK,QAAQ;AAC1B,SAAO;AAAA,IACL;AAAA,IACA,aACE;AAAA,IACF,WAAW;AAAA,IACX,MAAM,EAAE,MAAM,OAAO,QAAQ,KAAK,SAAS,QAAQ,CAAC,KAAK,QAAQ,KAAK,IAAI,OAAU;AAAA,IACpF,SAAS,GAAG,8BAA8B,YAAY,WAAW;AAAA,IACjE,MAAM,QAAQ,OAAO;AACnB,YAAM,SAAS,MAAM,wBAAwB,OAAO,KAAK,OAAO;AAChE,UAAI,CAAC,OAAO,WAAW;AACrB,eAAO;AAAA,UACL,YAAY;AAAA,YACV,YAAY;AAAA,YACZ;AAAA,YACA,OAAO;AAAA,YACP,WAAW,OAAO;AAAA,YAClB,UAAU;AAAA,YACV,YAAY;AAAA,YACZ,eAAe,CAAC;AAAA,YAChB,UAAU,EAAE,QAAQ,OAAO,MAAM;AAAA,UACnC,CAAC;AAAA,QACH;AAAA,MACF;AACA,YAAM,MAAwB,CAAC;AAC/B,iBAAW,KAAK,OAAO,UAAU;AAG/B,YAAI,EAAE,WAAW,EAAE,SAAS,EAAG;AAC/B,YAAI;AAAA,UACF,YAAY;AAAA,YACV,YAAY;AAAA,YACZ;AAAA,YACA,SAAS,EAAE;AAAA,YACX,OAAO,EAAE,UACL,YAAY,EAAE,OAAO,cAAc,EAAE,KAAK,SAC1C,YAAY,EAAE,OAAO;AAAA,YACzB,WAAW,EAAE;AAAA,YACb,UAAU,aAAa,EAAE,QAAQ;AAAA,YACjC,YAAY;AAAA,YACZ,eAAe,CAAC,EAAE,MAAM,YAAY,KAAK,mBAAmB,SAAS,EAAE,SAAS,CAAC;AAAA,YACjF,UAAU;AAAA,cACR,SAAS,EAAE;AAAA,cACX,SAAS,EAAE;AAAA,cACX,UAAU,EAAE;AAAA,cACZ,UAAU,OAAO,WAAW;AAAA,YAC9B;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF;AACA,aAAO;AAAA,IACT;AAAA,EACF;AACF;;;AC7SO,SAAS,iBAAiB,MAAwC;AACvE,UAAQ,KAAK,WAAW;AAAA,IACtB,KAAK;AACH,aAAO;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,QACL,IAAI,UAAU;AAAA,UACZ,SAAS,KAAK,WAAW;AAAA,UACzB,QAAQ,KAAK;AAAA,QACf,CAAqB;AAAA,MACvB;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,QACL,IAAI,UAAU;AAAA,UACZ,SAAS,KAAK,WAAW;AAAA,UACzB,QAAQ,KAAK,UAAU;AAAA,QACzB,CAAqB;AAAA,MACvB;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,QACL,IAAI,UAAU;AAAA,UACZ,SAAS,KAAK;AAAA,UACd,QAAQ,KAAK;AAAA,QACf,CAAqB;AAAA,MACvB;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,WAAW;AAAA,QACX,cAAc,KAAK;AAAA,QACnB,MAAM,OAAO,KAAK,aAAa,KAAK,KAAK,aAAa,KAAK,KAAK,YAAY,GAAG,QAAQ;AAAA,MACzF;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,WAAW;AAAA,QACX,cAAc,KAAK;AAAA,QACnB,MAAM,OAAO,KAAK,aAAa,KAAK,QAAQ,aAAa,KAAK,KAAK,YAAY,GAAG,QAAQ;AAAA,MAC5F;AAAA,EACJ;AACF;AAEA,SAAS,cACP,WACA,cACA,OACY;AACZ,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,MAAM,OAAO,KAAK,aAAa;AAC7B,YAAM,WAAW,aAAa,KAAK,YAAY;AAO/C,YAAM,OAAO,MAAM,KAAK;AAAA,QACtB,OAAO,SAAS;AAAA,QAChB,UAAU,IAAI;AAAA,QACd,UAAU,IAAI;AAAA,QACd,YAAY,IAAI;AAAA,QAChB,aAAa,IAAI;AAAA,QACjB,WAAW,IAAI;AAAA,QACf,WAAW,IAAI;AAAA,MACjB,CAAC;AACD,UAAI,CAAC,UAAU,OAAQ,QAAO,MAAM;AACpC,aAAO,MAAM,QAAQ,KAAK,CAAC,MAAM,iBAAiB,SAAS,MAAM,CAAC,CAAC;AAAA,IACrE;AAAA,EACF;AACF;AAEA,SAAS,iBAAiB,QAAqC;AAC7D,MAAI,OAAO,QAAS,QAAO,QAAQ,OAAO,aAAa,MAAM,CAAC;AAC9D,SAAO,IAAI,QAAe,CAAC,GAAG,WAAW;AACvC,WAAO,iBAAiB,SAAS,MAAM,OAAO,aAAa,MAAM,CAAC,GAAG,EAAE,MAAM,KAAK,CAAC;AAAA,EACrF,CAAC;AACH;AAEA,SAAS,aAAa,QAA4B;AAChD,QAAM,SAAU,OAAgC;AAChD,MAAI,kBAAkB,MAAO,QAAO;AACpC,QAAM,IAAI,IAAI,MAAM,0BAA0B;AAC9C,IAAE,OAAO;AACT,SAAO;AACT;AAEA,SAAS,aAAa,KAAkB,cAA+C;AACrF,MAAI,IAAI,MAAO,QAAO;AACtB,MAAI,CAAC,cAAc;AACjB,UAAM,IAAI;AAAA,MACR;AAAA,IAEF;AAAA,EACF;AACA,SAAO,EAAE,GAAG,KAAK,OAAO,aAAa;AACvC;;;AC1MA,SAAS,KAAAC,UAAS;;;ACkBlB,SAAS,SAAS;AAkCX,IAAM,wBAA2D;AAAA,EACtE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAoBO,SAAS,oBAAoB,KAAuD;AACzF,MAAI,QAAQ,QAAQ,QAAQ,OAAW,QAAO;AAC9C,QAAM,UAAU,IAAI,KAAK;AACzB,MAAI,QAAQ,WAAW,EAAG,QAAO;AAGjC,QAAM,OAAO,QAAQ;AAAA,IACnB;AAAA,EACF;AACA,MAAI;AACF,WAAO,EAAE,MAAM,kBAAkB,MAAM,KAAK,CAAC,GAAI,GAAI,KAAK,CAAC,IAAI,EAAE,SAAS,KAAK,CAAC,EAAE,IAAI,CAAC,EAAG;AAG5F,QAAM,QAAQ,QAAQ,MAAM,8BAA8B;AAC1D,MAAI,SAAS,MAAM,CAAC,EAAG,KAAK,EAAE,SAAS;AACrC,WAAO,EAAE,MAAM,mBAAmB,OAAO,MAAM,CAAC,EAAG,KAAK,EAAE;AAG5D,QAAM,OAAO,QAAQ,MAAM,4BAA4B;AACvD,MAAI,QAAQ,KAAK,CAAC,EAAG,KAAK,EAAE,SAAS;AACnC,WAAO,EAAE,MAAM,iBAAiB,UAAU,KAAK,CAAC,EAAG,KAAK,EAAE;AAG5D,QAAM,QAAQ,QAAQ,MAAM,8CAA8C;AAC1E,MAAI,MAAO,QAAO,EAAE,MAAM,mBAAmB,MAAM,MAAM,CAAC,EAAG;AAG7D,QAAM,KAAK,QAAQ,MAAM,sBAAsB;AAC/C,MAAI,MAAM,GAAG,CAAC,EAAG,KAAK,EAAE,SAAS,EAAG,QAAO,EAAE,MAAM,iBAAiB,SAAS,GAAG,CAAC,EAAG,KAAK,EAAE;AAG3F,QAAM,WAAW,QAAQ,MAAM,uCAAuC;AACtE,MAAI,YAAY,SAAS,CAAC,EAAG,KAAK,EAAE,SAAS,GAAG;AAC9C,WAAO,EAAE,MAAM,YAAY,MAAM,SAAS,CAAC,GAAI,QAAQ,SAAS,CAAC,EAAG,KAAK,EAAE;AAAA,EAC7E;AACA,QAAM,KAAK,QAAQ,MAAM,kCAAkC;AAC3D,MAAI,GAAI,QAAO,EAAE,MAAM,YAAY,MAAM,GAAG,CAAC,EAAG;AAGhD,QAAM,KAAK,QAAQ,MAAM,kCAAkC;AAC3D,MAAI,GAAI,QAAO,EAAE,MAAM,YAAY,MAAM,GAAG,CAAC,EAAG;AAGhD,QAAM,MAAM,QAAQ,MAAM,kCAAkC;AAC5D,MAAI,OAAO,IAAI,CAAC,EAAG,KAAK,EAAE,SAAS,GAAG;AACpC,WAAO,EAAE,MAAM,OAAO,QAAQ,IAAI,CAAC,GAAI,OAAO,IAAI,CAAC,EAAG,KAAK,EAAE;AAAA,EAC/D;AAGA,QAAM,MAAM,QAAQ,MAAM,eAAe;AACzC,MAAI,OAAO,IAAI,CAAC,EAAG,KAAK,EAAE,SAAS,EAAG,QAAO,EAAE,MAAM,UAAU,KAAK,IAAI,CAAC,EAAG,KAAK,EAAE;AAGnF,QAAM,KAAK,QAAQ,MAAM,oBAAoB;AAC7C,MAAI,MAAM,GAAG,CAAC,EAAG,KAAK,EAAE,SAAS,EAAG,QAAO,EAAE,MAAM,eAAe,SAAS,GAAG,CAAC,EAAG,KAAK,EAAE;AAGzF,QAAM,KAAK,QAAQ,MAAM,sBAAsB;AAC/C,MAAI,MAAM,GAAG,CAAC,EAAG,KAAK,EAAE,SAAS,EAAG,QAAO,EAAE,MAAM,iBAAiB,OAAO,GAAG,CAAC,EAAG,KAAK,EAAE;AAGzF,QAAM,KAAK,QAAQ,MAAM,2BAA2B;AACpD,MAAI,MAAM,GAAG,CAAC,EAAG,KAAK,EAAE,SAAS,EAAG,QAAO,EAAE,MAAM,sBAAsB,OAAO,GAAG,CAAC,EAAG,KAAK,EAAE;AAG9F,QAAM,MAAM,QAAQ,MAAM,0BAA0B;AACpD,MAAI,OAAO,IAAI,CAAC,EAAG,KAAK,EAAE,SAAS,EAAG,QAAO,EAAE,MAAM,qBAAqB,OAAO,IAAI,CAAC,EAAG,KAAK,EAAE;AAGhG,MAAI,uBAAuB,KAAK,OAAO,KAAK,QAAQ,UAAU,IAAI;AAChE,WAAO,EAAE,MAAM,WAAW,OAAO,QAAQ;AAAA,EAC3C;AAEA,SAAO;AACT;AAQO,SAAS,qBAAqB,GAA2B;AAC9D,UAAQ,EAAE,MAAM;AAAA,IACd,KAAK;AACH,aAAO,EAAE,UACL,wBAAwB,EAAE,IAAI,IAAI,EAAE,OAAO,KAC3C,wBAAwB,EAAE,IAAI;AAAA,IACpC,KAAK;AACH,aAAO,yBAAyB,EAAE,KAAK;AAAA,IACzC,KAAK;AACH,aAAO,uBAAuB,EAAE,QAAQ;AAAA,IAC1C,KAAK;AACH,aAAO,yBAAyB,EAAE,IAAI;AAAA,IACxC,KAAK;AACH,aAAO,iBAAiB,EAAE,OAAO;AAAA,IACnC,KAAK;AACH,aAAO,EAAE,SAAS,YAAY,EAAE,IAAI,IAAI,EAAE,MAAM,KAAK,YAAY,EAAE,IAAI;AAAA,IACzE,KAAK;AACH,aAAO,YAAY,EAAE,IAAI;AAAA,IAC3B,KAAK;AACH,aAAO,OAAO,EAAE,MAAM,IAAI,EAAE,KAAK;AAAA,IACnC,KAAK;AACH,aAAO,UAAU,EAAE,GAAG;AAAA,IACxB,KAAK;AACH,aAAO,eAAe,EAAE,OAAO;AAAA,IACjC,KAAK;AACH,aAAO,iBAAiB,EAAE,KAAK;AAAA,IACjC,KAAK;AACH,aAAO,sBAAsB,EAAE,KAAK;AAAA,IACtC,KAAK;AACH,aAAO,qBAAqB,EAAE,KAAK;AAAA,IACrC,KAAK;AACH,aAAO,EAAE;AAAA,EACb;AACF;AAaO,IAAM,iCAAiC;AAAA,EAC5C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,EAAE,KAAK,IAAI;AAYJ,IAAM,yBAA4E;AAAA,EACvF,gBAAgB,CAAC,SAAS;AAAA,EAC1B,iBAAiB;AAAA,IACf;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,uBAAuB;AAAA,IACrB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,aAAa;AAAA,IACX;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAeO,IAAM,6BAA6B,EACvC,OAAO,EACP,OAAO,CAAC,MAAM,oBAAoB,CAAC,MAAM,MAAM;AAAA,EAC9C,SAAS;AACX,CAAC;;;AD/SI,IAAM,qBAAqB,CAAC,YAAY,QAAQ,UAAU,OAAO,MAAM;AAEvE,IAAM,0BAA0BC,GACpC,OAAO;AAAA,EACN,UAAUA,GAAE,KAAK,kBAAkB;AAAA,EACnC,OAAOA,GAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYjC,SAASA,GACN,OAAO,EACP,IAAI,GAAG,EACP,OAAO,CAAC,MAAM,oBAAoB,CAAC,MAAM,MAAM;AAAA,IAC9C,SAAS;AAAA,EACX,CAAC,EACA,SAAS;AAAA,EACZ,cAAcA,GAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAI;AAAA,EACxC,kBAAkBA,GAAE,OAAO,EAAE,IAAI,GAAI,EAAE,SAAS;AAAA,EAChD,YAAYA,GAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC;AAAA,EACnC,WAAWA,GAAE,OAAO,EAAE,IAAI,GAAI,EAAE,SAAS;AAAA,EACzC,oBAAoBA,GAAE,OAAO,EAAE,IAAI,GAAI,EAAE,SAAS;AACpD,CAAC,EACA,OAAO;AASH,IAAM,4BAA4B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAiBlC,SAAS,gBACd,KACA,KAC0B;AAC1B,QAAM,SAAS,wBAAwB,UAAU,GAAG;AACpD,MAAI,CAAC,OAAO,SAAS;AACnB,UAAM,oCAAoC;AAAA,MACxC,QAAQ,OAAO,MAAM,OAAO,IAAI,CAAC,OAAO;AAAA,QACtC,MAAM,EAAE,KAAK,KAAK,GAAG;AAAA,QACrB,MAAM,EAAE;AAAA,QACR,SAAS,EAAE;AAAA,MACb,EAAE;AAAA,IACJ,CAAC;AACD,WAAO;AAAA,EACT;AACA,SAAO,OAAO;AAChB;;;AExEA,SAAS,cAAAC,aAAY,oBAAoB;;;ACTzC,SAAS,gBAAgB,YAAY,iBAAiB;AACtD,SAAS,eAAe;;;ACAjB,IAAM,QAAN,MAAY;AAAA,EACT,SAAS;AAAA,EACA,UAA6B,CAAC;AAAA,EAE/C,MAAM,UAA+B;AACnC,QAAI,CAAC,KAAK,QAAQ;AAChB,WAAK,SAAS;AACd,aAAO,MAAM,KAAK,QAAQ;AAAA,IAC5B;AACA,WAAO,IAAI,QAAoB,CAAC,YAAY;AAC1C,WAAK,QAAQ,KAAK,MAAM;AACtB,gBAAQ,MAAM,KAAK,QAAQ,CAAC;AAAA,MAC9B,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAAA,EAEQ,UAAgB;AACtB,UAAM,OAAO,KAAK,QAAQ,MAAM;AAChC,QAAI,MAAM;AACR,WAAK;AAAA,IACP,OAAO;AACL,WAAK,SAAS;AAAA,IAChB;AAAA,EACF;AAAA,EAEA,MAAM,aAAgB,IAAsC;AAC1D,UAAM,UAAU,MAAM,KAAK,QAAQ;AACnC,QAAI;AACF,aAAO,MAAM,GAAG;AAAA,IAClB,UAAE;AACA,cAAQ;AAAA,IACV;AAAA,EACF;AAAA;AAAA,EAGA,IAAI,WAAoB;AACtB,WAAO,KAAK;AAAA,EACd;AAAA;AAAA,EAGA,IAAI,UAAkB;AACpB,WAAO,KAAK,QAAQ;AAAA,EACtB;AACF;;;ADxCA,IAAM,UAAU,oBAAI,IAAmB;AAEvC,SAAS,SAAS,MAAqB;AACrC,MAAI,IAAI,QAAQ,IAAI,IAAI;AACxB,MAAI,CAAC,GAAG;AACN,QAAI,IAAI,MAAM;AACd,YAAQ,IAAI,MAAM,CAAC;AAAA,EACrB;AACA,SAAO;AACT;AAEO,IAAM,sBAAN,MAA0B;AAAA,EAE/B,YAA4B,MAAc;AAAd;AAC1B,SAAK,QAAQ,SAAS,IAAI;AAC1B,QAAI,CAAC,WAAW,QAAQ,IAAI,CAAC,GAAG;AAC9B,gBAAU,QAAQ,IAAI,GAAG,EAAE,WAAW,KAAK,CAAC;AAAA,IAC9C;AAAA,EACF;AAAA,EAL4B;AAAA,EADX;AAAA,EAQjB,MAAM,OAAO,OAA+B;AAC1C,UAAM,OAAO,GAAG,KAAK,UAAU,KAAK,CAAC;AAAA;AACrC,UAAM,KAAK,MAAM,aAAa,MAAM;AAClC,qBAAe,KAAK,MAAM,IAAI;AAAA,IAChC,CAAC;AAAA,EACH;AACF;AAGO,SAAS,iCAAuC;AACrD,UAAQ,MAAM;AAChB;;;ADZO,IAAM,gBAAN,MAAoB;AAAA,EAGzB,YAA4B,MAAc;AAAd;AAC1B,SAAK,WAAW,IAAI,oBAAoB,IAAI;AAAA,EAC9C;AAAA,EAF4B;AAAA,EAFX;AAAA,EAMjB,MAAM,OAAO,OAAe,UAA2C;AACrE,eAAW,KAAK,UAAU;AACxB,YAAM,MAAwB,EAAE,GAAG,GAAG,QAAQ,MAAM;AACpD,YAAM,KAAK,SAAS,OAAO,GAAG;AAAA,IAChC;AAAA,EACF;AAAA;AAAA,EAGA,UAA8B;AAC5B,QAAI,CAACC,YAAW,KAAK,IAAI,EAAG,QAAO,CAAC;AACpC,UAAM,MAAM,aAAa,KAAK,MAAM,MAAM;AAC1C,QAAI,CAAC,IAAK,QAAO,CAAC;AAClB,UAAM,MAA0B,CAAC;AACjC,eAAW,QAAQ,IAAI,MAAM,IAAI,GAAG;AAClC,UAAI,CAAC,KAAM;AACX,UAAI;AACF,YAAI,KAAK,KAAK,MAAM,IAAI,CAAqB;AAAA,MAC/C,QAAQ;AAAA,MAGR;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,QAAQ,OAAmC;AACzC,WAAO,KAAK,QAAQ,EAAE,OAAO,CAAC,MAAM,EAAE,WAAW,KAAK;AAAA,EACxD;AACF;AAiCO,SAAS,kBAAkB,GAAmB,GAA4B;AAC/E,MAAI,EAAE,aAAa,EAAE,SAAU,QAAO;AACtC,MAAI,KAAK,KAAK,EAAE,cAAc,MAAM,EAAE,cAAc,EAAE,IAAI,KAAM,QAAO;AACvE,MAAI,EAAE,cAAc,WAAW,EAAE,cAAc,OAAQ,QAAO;AAC9D,SAAO;AACT;AAMO,SAAS,aACd,UACA,SACA,SAAqB,CAAC,GACR;AACd,QAAM,aAAa,OAAO,cAAc;AACxC,QAAM,WAAW,IAAI,IAAI,SAAS,IAAI,CAAC,MAAM,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC;AAC/D,QAAM,UAAU,IAAI,IAAI,QAAQ,IAAI,CAAC,MAAM,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC;AAE7D,QAAM,WAA+B,CAAC;AACtC,QAAM,cAAkC,CAAC;AACzC,QAAM,YAAgC,CAAC;AACvC,QAAM,UAAmC,CAAC;AAE1C,aAAW,CAAC,IAAI,GAAG,KAAK,SAAS;AAC/B,UAAM,OAAO,SAAS,IAAI,EAAE;AAC5B,QAAI,CAAC,MAAM;AACT,eAAS,KAAK,GAAG;AACjB;AAAA,IACF;AACA,QAAI,WAAW,MAAM,GAAG,GAAG;AACzB,cAAQ,KAAK,EAAE,UAAU,MAAM,SAAS,IAAI,CAAC;AAAA,IAC/C,OAAO;AACL,gBAAU,KAAK,GAAG;AAAA,IACpB;AAAA,EACF;AACA,aAAW,CAAC,IAAI,IAAI,KAAK,UAAU;AACjC,QAAI,CAAC,QAAQ,IAAI,EAAE,EAAG,aAAY,KAAK,IAAI;AAAA,EAC7C;AACA,SAAO,EAAE,UAAU,aAAa,WAAW,QAAQ;AACrD;;;AGpHA,SAAS,aAAa,aAAa;AAyE5B,SAAS,uBACd,MACA,MAC6B;AAC7B,QAAM,UAAU,KAAK,gBAAgB,GAAG,KAAK,OAAO,IAAI,KAAK,aAAa,KAAK,KAAK;AACpF,SAAO;AAAA,IACL,IAAI,KAAK;AAAA,IACT,aAAa,KAAK;AAAA,IAClB,WAAW;AAAA,IACX,MAAM,KAAK;AAAA,IACX;AAAA,IACA,MAAM,QAAQ,OAAO,KAAK;AACxB,YAAM,QAAQ,KAAK,WAAW,KAAK;AACnC,YAAM,WAAW,KAAK,WAAW,YAAY;AAC7C,YAAM,cAAc,KAAK,WAAW,wBAAwB;AAC5D,YAAM,eAAe,oBAAoB,IAAI,aAAa;AAE1D,YAAM,mBACJ,KAAK,iBAAiB,KAAK,IAC3B,eACA,SACA,4BACA;AAGF,YAAM,KAAK;AAAA,QACT;AAAA,QACA;AAAA,UACE,eAAe;AAAA,YACb,MAAM,KAAK;AAAA,YACX,aAAa,KAAK;AAAA,UACpB;AAAA,UACA,eAAe,CAAC,UAAU;AAAA,UAC1B,SAAS,IAAI,YAAY;AAAA,YACvB,aAAa,CAAC;AAAA,YACd,oBAAoB;AAAA,YACpB,gBAAgB,CAAC;AAAA,YACjB,kBAAkB;AAAA,YAClB,kBAAkB;AAAA,YAClB,6BAA6B;AAAA,UAC/B,CAAC;AAAA,UACD,MAAM,WAAW,IAAI,aAAa;AAAA,UAClC,kBAAkB,WAAW,IAAI,EAAE,SAAS,IAAI;AAAA,UAChD,UAAU,KAAK,YAAY;AAAA,UAC3B,iBAAiB,KAAK,mBAAmB;AAAA,UACzC,+BAA+B;AAAA,UAC/B,aAAa;AAAA,UACb,eAAe,EAAE,QAAQ,QAAQ,QAAQ,WAAW;AAAA,UACpD,WAAW,EAAE,OAAO,MAAM;AAAA,UAC1B,cAAc;AAAA,YACZ,aAAa;AAAA,YACb,GAAI,KAAK,QAAQ,EAAE,OAAO,KAAK,MAAM,IAAI,CAAC;AAAA,YAC1C,cAAc;AAAA,YACd,qBAAqB;AAAA,UACvB;AAAA,UACA,kBAAkB;AAAA,YAChB,aACE,KAAK,wBACL;AAAA,YACF,GAAI,KAAK,QAAQ,EAAE,OAAO,KAAK,MAAM,IAAI,CAAC;AAAA,YAC1C,cAAc;AAAA,UAChB;AAAA,UACA,cAAc,CAAC,qBAAqB;AAAA,QACtC;AAAA,MACF;AAEA,UAAI,MAAM,gBAAgB,KAAK,EAAE,YAAY;AAAA,QAC3C,WAAW;AAAA,QACX,YAAY,MAAM;AAAA,QAClB,MAAM,IAAI;AAAA,MACZ,CAAC;AAED,YAAM,SAAS,MAAM,GAAG,QAAQ,KAAK,IAAI,EAAE,UAAU,eAAe,KAAK,IAAI,EAAE,CAAC;AAEhF,YAAM,mBAAmB,uBAAuB,KAAK,EAAE;AACvD,YAAM,MAAwB,CAAC;AAC/B,YAAM,UAAU,MAAM,QAAQ,OAAO,QAAQ,IAAI,OAAO,WAAW,CAAC;AACpE,UAAI,oBAAoB;AACxB,iBAAW,OAAO,SAAS;AACzB,cAAM,SAAS,gBAAgB,KAAK,IAAI,GAAG;AAC3C,YAAI,CAAC,OAAQ;AAMb,YAAI,oBAAoB,OAAO,YAAY,QAAW;AACpD,gBAAM,gBAAgB,oBAAoB,OAAO,OAAO;AACxD,cAAI,kBAAkB,MAAM;AAC1B,gBAAI,MAAM,6CAA6C;AAAA,cACrD,MAAM,KAAK;AAAA,cACX,SAAS,OAAO;AAAA,YAClB,CAAC;AACD,iCAAqB;AACrB;AAAA,UACF;AACA,cAAI,CAAC,iBAAiB,SAAS,cAAc,IAAI,GAAG;AAClD,gBAAI,MAAM,+DAA+D;AAAA,cACvE,MAAM,KAAK;AAAA,cACX,cAAc,cAAc;AAAA,cAC5B,SAAS,OAAO;AAAA,cAChB,SAAS;AAAA,YACX,CAAC;AACD,iCAAqB;AACrB;AAAA,UACF;AAAA,QACF;AACA,cAAM,gBAAgB,KAAK,cAAc,QAAQ,GAAG,KAAK;AACzD,YAAI,CAAC,cAAe;AACpB,YAAI,KAAK,iBAAiB,MAAM,aAAa,CAAC;AAAA,MAChD;AAEA,UAAI,MAAM,gBAAgB,KAAK,EAAE,SAAS;AAAA,QACxC,SAAS,QAAQ;AAAA,QACjB,UAAU,IAAI;AAAA,QACd,wBAAwB;AAAA,MAC1B,CAAC;AACD,aAAO;AAAA,IACT;AAAA,EACF;AACF;AAEA,SAAS,eAAe,KAAqB,MAAoC;AAK/E,QAAM,QAAQ,IAAI,MAAM,OAAO,KAAK;AACpC,MAAI,MAAO,QAAO,GAAG,KAAK,EAAE,KAAK,KAAK;AACtC,SAAO,KAAK;AACd;AAEA,SAAS,iBAAiB,MAA4B,KAAwC;AAC5F,SAAO,YAAY;AAAA,IACjB,YAAY,KAAK;AAAA,IACjB,MAAM,KAAK;AAAA,IACX,SAAS,IAAI;AAAA,IACb,OAAO,IAAI;AAAA,IACX,WAAW,IAAI;AAAA,IACf,UAAU,IAAI;AAAA,IACd,YAAY,IAAI;AAAA,IAChB,eAAe;AAAA,MACb;AAAA,QACE,MAAM,oBAAoB,IAAI,YAAY;AAAA,QAC1C,KAAK,IAAI;AAAA,QACT,SAAS,IAAI;AAAA,MACf;AAAA,IACF;AAAA,IACA,oBAAoB,IAAI;AAAA,IACxB,UAAU,EAAE,cAAc,KAAK,QAAQ;AAAA,EACzC,CAAC;AACH;AAEA,SAAS,oBAAoB,KAAmE;AAC9F,MAAI,IAAI,WAAW,SAAS,EAAG,QAAO;AACtC,MAAI,IAAI,WAAW,aAAa,EAAG,QAAO;AAC1C,MAAI,IAAI,WAAW,WAAW,EAAG,QAAO;AACxC,MAAI,IAAI,WAAW,UAAU,EAAG,QAAO;AACvC,MAAI,IAAI,WAAW,YAAY,EAAG,QAAO;AACzC,SAAO;AACT;AAgBO,SAAS,oBAAoB,OAAgD;AAClF,MAAI,CAAC,SAAS,MAAM,WAAW,EAAG,QAAO;AACzC,QAAM,WAAW;AACjB,QAAM,OAAO,MAAM,MAAM,GAAG,QAAQ,EAAE,IAAI,CAAC,MAAM;AAC/C,UAAM,UAAU,EAAE,UAAU,KAAK,EAAE,OAAO,MAAM;AAChD,WAAO,UAAU,EAAE,UAAU,IAAI,EAAE,QAAQ,GAAG,OAAO,IAAI,mBAAmB,EAAE,OAAO,GAAG,CAAC;AAAA,EAC3F,CAAC;AACD,QAAM,WACJ,MAAM,SAAS,WACX;AAAA,SAAY,MAAM,SAAS,QAAQ,mDACnC;AACN,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAG;AAAA,IACH;AAAA,EACF,EACG,OAAO,OAAO,EACd,KAAK,IAAI;AACd;AAEA,SAAS,mBAAmB,GAAW,KAAqB;AAC1D,MAAI,EAAE,UAAU,IAAK,QAAO;AAC5B,SAAO,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC,EAAE,QAAQ,CAAC;AACzC;;;ACnRA,IAAM,sBAAuE;AAAA,EAC3E,KAAK,oBAAI,IAAI;AAAA,EACb,WAAW,oBAAI,IAAI,CAAC,sBAAsB,eAAe,aAAa,CAAC;AAAA,EACvE,kBAAkB,oBAAI,IAAI;AAAA,IACxB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAAA,EACD,oBAAoB,oBAAI,IAAI;AAAA,IAC1B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAAA,EACD,UAAU,oBAAI,IAAI,CAAC,sBAAsB,eAAe,aAAa,YAAY,CAAC;AACpF;AASO,SAAS,wBACd,OACA,OACc;AACd,QAAM,MAAM,uBAAuB,EAAE,MAAM,CAAC;AAC5C,MAAI,UAAU,MAAO,QAAO;AAC5B,QAAM,QAAQ,oBAAoB,KAAK;AACvC,MAAI,CAAC,MAAO,OAAM,IAAI,MAAM,6BAA6B,KAAK,EAAE;AAChE,SAAO,IAAI,OAAO,CAAC,SAAS,MAAM,IAAK,KAA0B,IAAI,CAAC;AACxE;;;AC7CA,IAAM,eAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA+Bd,IAAM,yBAA+C;AAAA,EAC1D,IAAI;AAAA,EACJ,aACE;AAAA,EACF,MAAM;AAAA,EACN,SAAS;AAAA,EACT,kBAAkB;AAAA,EAClB,YAAY,CAAC,UAAU,wBAAwB,OAAO,KAAK;AAAA,EAC3D,WAAW,EAAE,UAAU,GAAG,sBAAsB,EAAE;AAAA,EAClD,UAAU;AAAA,EACV,MAAM,EAAE,MAAM,MAAM;AACtB;;;ACtCA,IAAMC,gBAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAsCd,IAAM,wBAA8C;AAAA,EACzD,IAAI;AAAA,EACJ,aACE;AAAA,EACF,MAAM;AAAA,EACN,SAAS;AAAA,EACT,kBAAkBA;AAAA,EAClB,YAAY,CAAC,UAAU,wBAAwB,OAAO,KAAK;AAAA,EAC3D,WAAW,EAAE,UAAU,GAAG,sBAAsB,EAAE;AAAA,EAClD,UAAU;AAAA,EACV,iBAAiB;AAAA,EACjB,MAAM,EAAE,MAAM,MAAM;AACtB;;;AC7CA,IAAMC,gBAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA4Cd,IAAM,0BAAgD;AAAA,EAC3D,IAAI;AAAA,EACJ,aACE;AAAA,EACF,MAAM;AAAA,EACN,SAAS;AAAA,EACT,kBAAkBA;AAAA,EAClB,YAAY,CAAC,UAAU,wBAAwB,sBAAsB,KAAK;AAAA,EAC1E,WAAW,EAAE,UAAU,GAAG,sBAAsB,EAAE;AAAA,EAClD,UAAU;AAAA,EACV,MAAM,EAAE,MAAM,MAAM;AACtB;;;AC7DA,IAAMC,gBAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAoCd,IAAM,gCAAsD;AAAA,EACjE,IAAI;AAAA,EACJ,aACE;AAAA,EACF,MAAM;AAAA,EACN,SAAS;AAAA,EACT,kBAAkBA;AAAA,EAClB,YAAY,CAAC,UAAU,wBAAwB,OAAO,KAAK;AAAA,EAC3D,WAAW,EAAE,UAAU,GAAG,sBAAsB,EAAE;AAAA,EAClD,UAAU;AAAA,EACV,MAAM,EAAE,MAAM,MAAM;AACtB;;;AC3CO,IAAM,8BAA+D;AAAA,EAC1E;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;;;ACXA,SAAS,cAAAC,aAAY,aAAa,gBAAAC,eAAc,gBAAgB;AAChE,SAAS,YAAY;AAyDrB,IAAM,uBAAuB;AAE7B,IAAM,oBACJ;AACF,IAAM,aAAa;AAInB,SAAS,cAAc,MAAgD;AACrE,MAAI,CAACC,YAAW,IAAI,EAAG,QAAO,CAAC;AAC/B,QAAM,MAAwC,CAAC;AAC/C,aAAW,SAAS,YAAY,MAAM,EAAE,eAAe,KAAK,CAAC,GAAG;AAC9D,QAAI,CAAC,MAAM,YAAY,KAAK,CAAC,MAAM,eAAe,EAAG;AACrD,UAAM,UAAU,KAAK,MAAM,MAAM,MAAM,UAAU;AACjD,QAAIA,YAAW,OAAO,EAAG,KAAI,KAAK,EAAE,MAAM,MAAM,MAAM,MAAM,QAAQ,CAAC;AAAA,EACvE;AACA,SAAO;AACT;AAEA,SAAS,UAAU,KAAa,KAAuB;AACrD,MAAI,CAACA,YAAW,GAAG,EAAG,QAAO,CAAC;AAC9B,QAAM,QAAkB,CAAC;AACzB,QAAM,QAAQ,CAAC,GAAG;AAClB,SAAO,MAAM,QAAQ;AACnB,UAAM,MAAM,MAAM,IAAI;AACtB,QAAI;AACJ,QAAI;AACF,gBAAU,YAAY,KAAK,EAAE,eAAe,KAAK,CAAC;AAAA,IACpD,QAAQ;AACN;AAAA,IACF;AACA,eAAW,KAAK,SAAS;AACvB,YAAM,OAAO,KAAK,KAAK,EAAE,IAAI;AAC7B,UAAI,EAAE,YAAY,EAAG,OAAM,KAAK,IAAI;AAAA,eAC3B,EAAE,KAAK,SAAS,QAAQ,GAAG;AAClC,cAAM,KAAK,IAAI;AACf,YAAI,MAAM,KAAK,MAAM,UAAU,IAAK,QAAO;AAAA,MAC7C;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,uBAAuB,MAAsB;AACpD,QAAM,KAAK,wBAAwB,KAAK,IAAI;AAC5C,QAAM,QAAQ,KAAK,CAAC,KAAK;AACzB,QAAM,IAAI,uBAAuB,KAAK,KAAK;AAC3C,SAAO,IAAI,CAAC,KAAK;AACnB;AAEA,SAAS,eAAe,OAAiB,MAAc,SAA2B;AAChF,MAAI,IAAI;AACR,aAAW,QAAQ,OAAO;AACxB,UAAM,aAAa,CAAC,KAAK,MAAM,WAAW,IAAI,GAAG,GAAG,QAAQ,IAAI,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC;AACrF,eAAW,OAAO,YAAY;AAC5B,UAAI,CAACA,YAAW,GAAG,EAAG;AACtB,UAAI;AACF,YAAI,SAAS,GAAG,EAAE,YAAY,EAAG,MAAK,YAAY,GAAG,EAAE;AAAA,YAClD,MAAK;AAAA,MACZ,QAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAGO,SAAS,sBAAsB,QAAgD;AACpF,QAAM,SAAS,OAAO,WAAW;AAAA,IAAQ,CAAC,EAAE,MAAM,KAAK,MACrD,cAAc,IAAI,EAAE,IAAI,CAAC,OAAO,EAAE,GAAG,GAAG,KAAK,EAAE;AAAA,EACjD;AACA,QAAM,QAAQ,OAAO,IAAI,CAAC,MAAM,EAAE,IAAI;AAGtC,QAAM,SAAS,IAAI,IAAoB,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;AAC/D,QAAM,QAAQ,IAAI,IAAoB,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;AAC9D,QAAM,UAAU;AAChB,QAAM,QAAQ;AACd,MAAI,cAAc;AAClB,aAAW,OAAO,OAAO,gBAAgB;AACvC,eAAW,QAAQ,UAAU,KAAK,OAAO,wBAAwB,CAAC,GAAG;AACnE,qBAAe;AACf,UAAI;AACJ,UAAI;AACF,eAAOC,cAAa,MAAM,MAAM;AAAA,MAClC,QAAQ;AACN;AAAA,MACF;AACA,iBAAW,KAAK,KAAK,SAAS,OAAO,GAAG;AACtC,cAAM,IAAI,EAAE,CAAC;AACb,YAAI,CAAC,EAAG;AACR,cAAM,IAAI,EAAE,MAAM,GAAG,EAAE,IAAI,KAAK;AAChC,cAAM,OAAO,OAAO,IAAI,CAAC;AACzB,YAAI,SAAS,OAAW,QAAO,IAAI,GAAG,OAAO,CAAC;AAAA,MAChD;AACA,iBAAW,KAAK,KAAK,SAAS,KAAK,GAAG;AACpC,cAAM,IAAI,EAAE,CAAC;AACb,YAAI,MAAM,OAAW;AACrB,cAAM,OAAO,MAAM,IAAI,CAAC;AACxB,YAAI,SAAS,OAAW,OAAM,IAAI,GAAG,OAAO,CAAC;AAAA,MAC/C;AAAA,IACF;AAAA,EACF;AAGA,QAAM,SAAS,oBAAI,IAAoB;AACvC,aAAW,KAAK,QAAQ;AACtB,QAAI;AACF,aAAO,IAAI,EAAE,MAAMA,cAAa,EAAE,MAAM,MAAM,CAAC;AAAA,IACjD,QAAQ;AACN,aAAO,IAAI,EAAE,MAAM,EAAE;AAAA,IACvB;AAAA,EACF;AACA,QAAM,UAAU,IAAI,IAAoB,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;AAChE,aAAW,UAAU,OAAO;AAC1B,UAAM,MAAM,IAAI,OAAO,IAAI,MAAM,aAAa,MAAM,QAAQ;AAC5D,eAAW,KAAK,QAAQ;AACtB,UAAI,EAAE,SAAS,OAAQ;AACvB,UAAI,IAAI,KAAK,OAAO,IAAI,EAAE,IAAI,KAAK,EAAE,EAAG,SAAQ,IAAI,QAAQ,QAAQ,IAAI,MAAM,IAAK,CAAC;AAAA,IACtF;AAAA,EACF;AAEA,QAAM,UAA8B,OAAO,IAAI,CAAC,MAAM;AACpD,UAAM,OAAO,OAAO,IAAI,EAAE,IAAI,KAAK;AACnC,UAAM,MAAM,EAAE,KAAK,QAAQ,gBAAgB,EAAE;AAC7C,WAAO;AAAA,MACL,MAAM,EAAE;AAAA,MACR,MAAM,EAAE;AAAA,MACR,MAAM,EAAE;AAAA,MACR,OAAO,OAAO,KAAK,MAAM,IAAI,EAAE,SAAS;AAAA,MACxC,mBAAmB,OAAO,IAAI,EAAE,IAAI,KAAK;AAAA,MACzC,kBAAkB,MAAM,IAAI,EAAE,IAAI,KAAK;AAAA,MACvC,aAAa,QAAQ,IAAI,EAAE,IAAI,KAAK;AAAA,MACpC,eAAe;AAAA,QACb,OAAO,iBAAiB,CAAC;AAAA,QACzB,EAAE;AAAA,QACF,OAAO,kBAAkB,EAAE,IAAI,KAAK,CAAC;AAAA,MACvC;AAAA,MACA,oBAAoB,KAAK,MAAM,iBAAiB,KAAK,CAAC,GAAG;AAAA,MACzD,kBAAkBD,YAAW,KAAK,KAAK,YAAY,CAAC;AAAA,MACpD,aAAaA,YAAW,KAAK,KAAK,OAAO,CAAC;AAAA,MAC1C,UAAU,KAAK,SAAS,kBAAkB;AAAA,MAC1C,mBAAmB,WAAW,KAAK,uBAAuB,IAAI,KAAK,KAAK,MAAM,GAAG,GAAG,CAAC;AAAA,IACvF;AAAA,EACF,CAAC;AACD,SAAO,EAAE,qBAAqB,aAAa,QAAQ;AACrD;AAIA,IAAM,aAAa;AAEnB,SAAS,QACP,MACA,SACA,OACA,UACA,YACA,YACA,aACA,aACA,WACgB;AAChB,SAAO;AAAA,IACL,gBAAgB;AAAA,IAChB,YAAY,iBAAiB,EAAE,YAAY,YAAY,MAAM,SAAS,MAAM,CAAC;AAAA,IAC7E,YAAY;AAAA,IACZ,aAAa;AAAA,IACb;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,eAAe,CAAC,EAAE,MAAM,YAAY,KAAK,YAAY,CAAC;AAAA,IACtD,oBAAoB;AAAA,IACpB;AAAA,IACA;AAAA,EACF;AACF;AAGO,SAAS,uBACd,QACA,YACkB;AAClB,QAAM,MAAwB,CAAC;AAC/B,aAAW,KAAK,OAAO,SAAS;AAC9B,UAAM,cAAc,EAAE,oBAAoB,EAAE;AAC5C,UAAM,YAAY,cAAc,EAAE,cAAc,EAAE;AAGlD,QAAI,cAAc,GAAG;AACnB,UAAI;AAAA,QACF;AAAA,UACE;AAAA,UACA,EAAE;AAAA,UACF,UAAU,EAAE,IAAI;AAAA,UAChB;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA,EAAE;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF,WAAW,gBAAgB,KAAK,EAAE,cAAc,EAAE,gBAAgB,GAAG;AAEnE,UAAI;AAAA,QACF;AAAA,UACE;AAAA,UACA,EAAE;AAAA,UACF,UAAU,EAAE,IAAI,iFAAiF,EAAE,WAAW,eAAe,EAAE,aAAa;AAAA,UAC5I;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA,EAAE;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAGA,QAAI,eAAe,KAAK,CAAC,EAAE,mBAAmB;AAC5C,UAAI;AAAA,QACF;AAAA,UACE;AAAA,UACA,EAAE;AAAA,UACF,UAAU,EAAE,IAAI;AAAA,UAChB;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA,EAAE;AAAA,QACJ;AAAA,MACF;AAAA,IACF;AAGA,QAAI,EAAE,SAAS,YAAY,EAAE,oBAAoB,GAAG;AAClD,UAAI;AAAA,QACF;AAAA,UACE;AAAA,UACA,EAAE;AAAA,UACF,iBAAiB,EAAE,IAAI,aAAa,EAAE,iBAAiB;AAAA,UACvD;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA,EAAE;AAAA,QACJ;AAAA,MACF;AAAA,IACF;AAGA,QAAI,EAAE,QAAQ,wBAAwB,CAAC,EAAE,kBAAkB;AACzD,UAAI;AAAA,QACF;AAAA,UACE;AAAA,UACA,EAAE;AAAA,UACF,UAAU,EAAE,IAAI,QAAQ,EAAE,KAAK;AAAA,UAC/B;AAAA,UACA;AAAA,UACA;AAAA,UACA,mFAAmF,EAAE,KAAK;AAAA,UAC1F,EAAE;AAAA,QACJ;AAAA,MACF;AAAA,IACF;AAGA,QAAI,CAAC,EAAE,aAAa;AAClB,UAAI;AAAA,QACF;AAAA,UACE;AAAA,UACA,EAAE;AAAA,UACF,UAAU,EAAE,IAAI;AAAA,UAChB;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA,EAAE;AAAA,QACJ;AAAA,MACF;AAAA,IACF;AAGA,QAAI,CAAC,EAAE,UAAU;AACf,UAAI;AAAA,QACF;AAAA,UACE;AAAA,UACA,EAAE;AAAA,UACF,UAAU,EAAE,IAAI;AAAA,UAChB;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA,EAAE;AAAA,QACJ;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAIO,IAAM,oBAAN,MAA6D;AAAA,EACzD,KAAK;AAAA,EACL,cACP;AAAA,EACO,YAAY;AAAA,EACZ,OAAO,EAAE,MAAM,iBAA0B,iBAAiB,EAAE;AAAA,EAC5D,UAAU;AAAA,EAEnB,MAAM,QAAQ,OAAyB,KAAgD;AACrF,UAAM,aAAa,IAAI,MAAM,eAAc,oBAAI,KAAK,GAAE,YAAY;AAClE,QAAI;AAAA,MACF,gBAAgB,MAAM,QAAQ,MAAM,gBAAgB,MAAM,mBAAmB;AAAA,IAC/E;AACA,WAAO,uBAAuB,OAAO,UAAU;AAAA,EACjD;AACF;AAEO,IAAM,sBAAsB,IAAI,kBAAkB;;;ACjYzD,SAAS,kBAAkB;AA+FpB,IAAM,kBAAN,MAAsB;AAAA,EACV,WAAW,oBAAI,IAAqB;AAAA,EACpC;AAAA,EAEjB,YAAY,UAAkC,CAAC,GAAG;AAChD,SAAK,UAAU;AAAA,EACjB;AAAA,EAEA,SAAS,SAAwB;AAC/B,QAAI,CAAC,QAAQ,GAAI,OAAM,IAAI,MAAM,kDAAkD;AACnF,QAAI,KAAK,SAAS,IAAI,QAAQ,EAAE,GAAG;AACjC,YAAM,IAAI,MAAM,mDAAmD,QAAQ,EAAE,GAAG;AAAA,IAClF;AACA,QAAI,CAAC,QAAQ,SAAS;AACpB,YAAM,IAAI,MAAM,sCAAsC,QAAQ,EAAE,0BAA0B;AAAA,IAC5F;AACA,SAAK,SAAS,IAAI,QAAQ,IAAI,OAAO;AAAA,EACvC;AAAA,EAEA,OAKG;AACD,WAAO,MAAM,KAAK,KAAK,SAAS,OAAO,CAAC,EAAE,IAAI,CAAC,OAAO;AAAA,MACpD,IAAI,EAAE;AAAA,MACN,aAAa,EAAE;AAAA,MACf,SAAS,EAAE;AAAA,MACX,MAAM,EAAE;AAAA,IACV,EAAE;AAAA,EACJ;AAAA,EAEA,MAAM,IACJ,OACA,QACA,UAA2B,CAAC,GACD;AAG3B,qBAAiB,MAAM,KAAK,UAAU,OAAO,QAAQ,OAAO,GAAG;AAC7D,UAAI,GAAG,SAAS,gBAAiB,QAAO,GAAG;AAAA,IAC7C;AACA,UAAM,IAAI,MAAM,mEAAmE;AAAA,EACrF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,OAAO,UACL,OACA,QACA,UAA2B,CAAC,GACiB;AAC7C,UAAM,gBAAgB,MAAM,WAAW,EAAE,MAAM,GAAG,EAAE,CAAC;AACrD,UAAM,MAAM,KAAK,QAAQ,QAAQ,MAAM;AAAA,IAAC;AACxC,UAAM,QAAQ,KAAK,QAAQ,SAAS,CAAC;AACrC,UAAM,aAAY,oBAAI,KAAK,GAAE,YAAY;AACzC,UAAM,UAAU,KAAK,IAAI;AACzB,UAAM,aAAa,QAAQ,YAAY,UAAU,QAAQ,YAAY;AAErE,UAAM,WAAW,KAAK,eAAe,OAAO;AAC5C,UAAM,SAAS,QAAQ,UAAU,KAAK,QAAQ;AAE9C,UAAM;AAAA,MACJ,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,gBAAgB;AAAA,MAChB,YAAY;AAAA,MACZ,aAAa,SAAS,IAAI,CAAC,MAAM,EAAE,EAAE;AAAA,IACvC;AAEA,UAAM,YAAiC,CAAC;AACxC,UAAM,cAAgC,CAAC;AACvC,QAAI,YAAY;AAChB,QAAI,eAAe,QAAQ;AAE3B,eAAW,WAAW,UAAU;AAC9B,YAAM,KAAK,KAAK,IAAI;AACpB,YAAM,QAAQ,KAAK,WAAW,SAAS,MAAM;AAC7C,UAAI,MAAM,SAAS,WAAW;AAC5B,cAAM,UAA6B;AAAA,UACjC,YAAY,QAAQ;AAAA,UACpB,QAAQ;AAAA,UACR,QAAQ,0BAA0B,QAAQ,SAAS;AAAA,UACnD,gBAAgB;AAAA,UAChB,YAAY;AAAA,UACZ,UAAU;AAAA,QACZ;AACA,kBAAU,KAAK,OAAO;AACtB,YAAI,kBAAkB,QAAQ,EAAE,yBAAoB,EAAE,OAAO,MAAM,QAAQ,UAAU,CAAC;AACtF,cAAM,MAAM,iBAAiB,EAAE,SAAS,SAAS,UAAU,CAAC,GAAG,MAAM,CAAC;AACtE,cAAM,EAAE,MAAM,mBAAmB,QAAQ;AACzC;AAAA,MACF;AAEA,YAAM,YAAY,eAAe,QAAQ;AAAA,QACvC;AAAA,QACA;AAAA,QACA,cAAc,SAAS;AAAA,MACzB,CAAC;AAED,YAAM,MAAsB;AAAA,QAC1B;AAAA,QACA;AAAA,QACA;AAAA,QACA,WAAW;AAAA,QACX,MAAM,KAAK,QAAQ;AAAA,QACnB,MAAM,QAAQ;AAAA,QACd,KAAK,CAAC,KAAK,WAAW,IAAI,IAAI,QAAQ,EAAE,KAAK,GAAG,IAAI,EAAE,OAAO,eAAe,GAAG,OAAO,CAAC;AAAA,QACvF,QAAQ,QAAQ;AAAA,QAChB,eAAe,oBAAoB,QAAQ,eAAe,QAAQ,EAAE;AAAA,MACtE;AAEA,YAAM,MAAM,kBAAkB,EAAE,SAAS,KAAK,MAAM,CAAC;AACrD,YAAM;AAAA,QACJ,MAAM;AAAA,QACN,YAAY,QAAQ;AAAA,QACpB,YAAY,IAAI,KAAK,EAAE,EAAE,YAAY;AAAA,MACvC;AAEA,UAAI;AACF,cAAM,WAAW,MAAO,QAA6B,QAAQ,MAAM,OAAO,GAAG;AAC7E,cAAM,UAAU,KAAK,IAAI,IAAI;AAC7B,cAAM,OAAO,eAAe,QAAQ;AACpC,qBAAa;AACb,YAAI,OAAO,iBAAiB,SAAU,gBAAe,KAAK,IAAI,GAAG,eAAe,IAAI;AACpF,oBAAY,KAAK,GAAG,QAAQ;AAC5B,cAAM,UAA6B;AAAA,UACjC,YAAY,QAAQ;AAAA,UACpB,QAAQ;AAAA,UACR,gBAAgB,SAAS;AAAA,UACzB,YAAY;AAAA,UACZ,UAAU;AAAA,QACZ;AACA,kBAAU,KAAK,OAAO;AACtB,YAAI,gBAAgB,QAAQ,EAAE,IAAI;AAAA,UAChC;AAAA,UACA,UAAU,SAAS;AAAA,UACnB,YAAY;AAAA,UACZ,UAAU;AAAA,QACZ,CAAC;AACD,cAAM,MAAM,iBAAiB,EAAE,SAAS,SAAS,UAAU,MAAM,CAAC;AAClE,cAAM,EAAE,MAAM,qBAAqB,SAAS,SAAS;AAAA,MACvD,SAAS,KAAK;AACZ,cAAM,UAAU,KAAK,IAAI,IAAI;AAC7B,cAAM,IAAI,eAAe,QAAQ,MAAM,IAAI,MAAM,OAAO,GAAG,CAAC;AAE5D,cAAM,eAAgB,MAAM,MAAM,UAAU,EAAE,SAAS,OAAO,GAAG,MAAM,CAAC,KAAM,CAAC;AAC/E,YAAI,aAAa,OAAQ,aAAY,KAAK,GAAG,YAAY;AACzD,cAAM,UAA6B;AAAA,UACjC,YAAY,QAAQ;AAAA,UACpB,QAAQ;AAAA,UACR,gBAAgB,aAAa;AAAA,UAC7B,YAAY;AAAA,UACZ,UAAU;AAAA,UACV,OAAO,EAAE,OAAO,EAAE,YAAY,MAAM,SAAS,EAAE,QAAQ;AAAA,QACzD;AACA,kBAAU,KAAK,OAAO;AACtB,YAAI,kBAAkB,QAAQ,EAAE,IAAI;AAAA,UAClC;AAAA,UACA,aAAa,EAAE,YAAY;AAAA,UAC3B,OAAO,EAAE;AAAA,QACX,CAAC;AACD,cAAM,MAAM,iBAAiB,EAAE,SAAS,SAAS,UAAU,cAAc,MAAM,CAAC;AAChF,cAAM,EAAE,MAAM,qBAAqB,SAAS,UAAU,aAAa;AAAA,MAErE;AAAA,IACF;AAEA,UAAM,SAA2B;AAAA,MAC/B,QAAQ;AAAA,MACR,gBAAgB;AAAA,MAChB,YAAY;AAAA,MACZ,WAAU,oBAAI,KAAK,GAAE,YAAY;AAAA,MACjC,UAAU;AAAA,MACV,aAAa;AAAA,MACb,gBAAgB;AAAA,IAClB;AACA,UAAM,MAAM,aAAa,EAAE,OAAO,CAAC;AACnC,UAAM,EAAE,MAAM,iBAAiB,OAAO;AAAA,EACxC;AAAA,EAEQ,eAAe,MAAkC;AACvD,QAAI,aAAa,MAAM,KAAK,KAAK,SAAS,OAAO,CAAC;AAClD,QAAI,KAAK,MAAM,QAAQ;AACrB,YAAM,OAAO,IAAI,IAAI,KAAK,IAAI;AAC9B,mBAAa,WAAW,OAAO,CAAC,MAAM,KAAK,IAAI,EAAE,EAAE,CAAC;AAAA,IACtD;AACA,QAAI,KAAK,MAAM,QAAQ;AACrB,YAAM,OAAO,IAAI,IAAI,KAAK,IAAI;AAC9B,mBAAa,WAAW,OAAO,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE,EAAE,CAAC;AAAA,IACvD;AACA,WAAO;AAAA,EACT;AAAA,EAEQ,WACN,SACA,QAC2D;AAC3D,YAAQ,QAAQ,WAAW;AAAA,MACzB,KAAK;AACH,eAAO,OAAO,aACV,EAAE,MAAM,WAAW,OAAO,OAAO,WAAW,IAC5C,EAAE,MAAM,UAAU;AAAA,MACxB,KAAK;AACH,eAAO,OAAO,cACV,EAAE,MAAM,WAAW,OAAO,OAAO,YAAY,IAC7C,EAAE,MAAM,UAAU;AAAA,MACxB,KAAK;AACH,eAAO,OAAO,YAAY,EAAE,MAAM,WAAW,OAAO,OAAO,UAAU,IAAI,EAAE,MAAM,UAAU;AAAA,MAC7F,KAAK;AACH,eAAO,OAAO,aACV,EAAE,MAAM,WAAW,OAAO,OAAO,WAAW,IAC5C,EAAE,MAAM,UAAU;AAAA,MACxB,KAAK,UAAU;AACb,cAAM,IAAI,OAAO,SAAS,QAAQ,EAAE;AACpC,eAAO,MAAM,SAAY,EAAE,MAAM,WAAW,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU;AAAA,MAC7E;AAAA,IACF;AAAA,EACF;AACF;AAOA,SAAS,eACP,QACA,MACoB;AACpB,MAAI,CAAC,OAAQ,QAAO;AACpB,MAAI,OAAO,UAAU;AACnB,WAAO,OAAO,SAAS;AAAA,MACrB,SAAS,KAAK;AAAA,MACd,UAAU,OAAO;AAAA,MACjB,cAAc,KAAK;AAAA,MACnB,cAAc,KAAK;AAAA,IACrB,CAAC;AAAA,EACH;AACA,MAAI,OAAO,YAAY,KAAM,QAAO;AACpC,MAAI,OAAO,SAAS;AAOlB,UAAM,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,KAAK;AAC7C,UAAM,cAAc,KAAK,IAAI,GAAG,KAAK,YAAY;AACjD,WAAQ,OAAO,WAAW,IAAK;AAAA,EACjC;AACA,SAAO,OAAO,WAAW,KAAK,IAAI,GAAG,KAAK,YAAY;AACxD;AAOA,SAAS,eAAe,UAAoC;AAC1D,MAAIE,OAAM;AACV,aAAW,KAAK,UAAU;AACxB,UAAM,IAAI,EAAE,UAAU;AACtB,QAAI,OAAO,MAAM,YAAY,OAAO,SAAS,CAAC,EAAG,CAAAA,QAAO;AAAA,EAC1D;AACA,SAAOA;AACT;AAcA,SAAS,oBACP,QACA,WAC2C;AAC3C,MAAI,CAAC,OAAQ,QAAO;AACpB,MAAI,MAAM,QAAQ,MAAM,GAAG;AACzB,UAAMC,OAAM,OAAO,OAAO,CAAC,MAAM,EAAE,eAAe,SAAS;AAC3D,WAAOA,KAAI,SAAS,IAAIA,OAAM;AAAA,EAChC;AACA,QAAM,SAAS;AACf,QAAM,MAAM,OAAO,SAAS,KAAK,CAAC;AAClC,QAAM,WAAW,OAAO,GAAG,KAAK,CAAC;AACjC,QAAM,SAAS,CAAC,GAAG,KAAK,GAAG,QAAQ;AACnC,SAAO,OAAO,SAAS,IAAI,SAAS;AACtC;;;AC5UA,eAAsB,4BACpB,QACA,OAC4C;AAC5C,WAAS,KAAK;AACd,SAAO,OAAO,cAAc,KAAK;AACnC;AAEA,SAAS,SAAS,OAA+C;AAC/D,MAAI,CAAC,MAAM,KAAK,MAAM,KAAK,KAAK,CAAC,MAAM,KAAK,KAAK,KAAK,GAAG;AACvD,UAAM,IAAI,gBAAgB,gEAAgE;AAAA,EAC5F;AACA,MAAI,CAAC,MAAM,WAAW,KAAK,KAAK,KAAK,KAAK,MAAM,UAAU,GAAG;AAC3D,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,MAAI,MAAM,gBAAgB,MAAM,cAAc,SAAS;AACrD,UAAM,IAAI,gBAAgB,qEAAqE;AAAA,EACjG;AACA,MAAI,MAAM,YAAY,WAAW,GAAG;AAClC,UAAM,IAAI,gBAAgB,4DAA4D;AAAA,EACxF;AACA,QAAM,YAAY,oBAAI,IAAY;AAClC,aAAW,UAAU,MAAM,aAAa;AACtC,QAAI,CAAC,OAAO,KAAK,KAAK,KAAK,OAAO,KAAK,SAAS,IAAI,KAAK,OAAO,KAAK,WAAW,GAAG,GAAG;AACpF,YAAM,IAAI;AAAA,QACR,mDAAmD,OAAO,IAAI;AAAA,MAChE;AAAA,IACF;AACA,QAAI,UAAU,IAAI,OAAO,IAAI,GAAG;AAC9B,YAAM,IAAI,gBAAgB,qDAAqD,OAAO,IAAI,GAAG;AAAA,IAC/F;AACA,cAAU,IAAI,OAAO,IAAI;AAAA,EAC3B;AACA,MAAI,CAAC,MAAM,MAAM,KAAK,GAAG;AACvB,UAAM,IAAI,gBAAgB,sDAAsD;AAAA,EAClF;AACF;AA8CO,SAAS,iBAAiB,MAA6C;AAC5E,QAAM,YAAY,KAAK,aAAa;AACpC,QAAM,WAAW,KAAK,WAAW,0BAA0B,QAAQ,QAAQ,EAAE;AAC7E,QAAM,MAAM,KAAK,QAAQ,MAAM,oBAAI,KAAK;AAExC,iBAAe,IACb,QACA,MACA,MACA,YAAY,OACO;AACnB,UAAM,MAAM,MAAM,UAAU,GAAG,OAAO,GAAG,IAAI,IAAI;AAAA,MAC/C;AAAA,MACA,SAAS;AAAA,QACP,QAAQ;AAAA,QACR,gBAAgB;AAAA,QAChB,eAAe,UAAU,KAAK,KAAK;AAAA,QACnC,wBAAwB;AAAA,MAC1B;AAAA,MACA,MAAM,SAAS,SAAY,SAAY,KAAK,UAAU,IAAI;AAAA,IAC5D,CAAC;AACD,QAAI,aAAa,IAAI,WAAW,IAAK,QAAO;AAC5C,QAAI,CAAC,IAAI,IAAI;AACX,YAAM,OAAO,MAAM,IAAI,KAAK,EAAE,MAAM,MAAM,EAAE;AAC5C,YAAM,IAAI;AAAA,QACR,uCAAuC,MAAM,IAAI,IAAI,WAAM,IAAI,MAAM,IAAI,KAAK,MAAM,GAAG,GAAG,CAAC;AAAA,MAC7F;AAAA,IACF;AACA,WAAQ,MAAM,IAAI,KAAK;AAAA,EACzB;AAEA,SAAO;AAAA,IACL,MAAM,cAAc,OAAO;AACzB,YAAM,aAAa,MAAM,cAAc;AACvC,YAAM,WAAW,UAAU,MAAM,KAAK,KAAK,IAAI,MAAM,KAAK,IAAI;AAE9D,UAAI,MAAM,QAAQ;AAChB,eAAO;AAAA,UACL,OAAO,sBAAsB,MAAM,KAAK,KAAK,IAAI,MAAM,KAAK,IAAI,YAAY,UAAU,MAAM,MAAM,UAAU;AAAA,UAC5G,YAAY,MAAM;AAAA,UAClB,SAAS;AAAA,UACT,QAAQ;AAAA,QACV;AAAA,MACF;AAGA,YAAM,UAAU,MAAM,IAAW,OAAO,GAAG,QAAQ,kBAAkB,UAAU,EAAE;AACjF,UAAI,CAAC,SAAS;AACZ,cAAM,IAAI,YAAY,6CAA6C,UAAU,aAAa;AAAA,MAC5F;AACA,YAAM,UAAU,QAAQ,OAAO;AAC/B,YAAM,aAAa,MAAM,IAAc,OAAO,GAAG,QAAQ,gBAAgB,OAAO,EAAE;AAClF,UAAI,CAAC,YAAY;AACf,cAAM,IAAI;AAAA,UACR,4CAA4C,OAAO;AAAA,QACrD;AAAA,MACF;AAGA,YAAM,cAAc,CAAC;AACrB,iBAAW,UAAU,MAAM,aAAa;AACtC,cAAM,OAAO,MAAM,IAAY,QAAQ,GAAG,QAAQ,cAAc;AAAA,UAC9D,SAAS,OAAO;AAAA,UAChB,UAAU;AAAA,QACZ,CAAC;AACD,YAAI,CAAC,KAAM,OAAM,IAAI,YAAY,0DAA0D;AAC3F,oBAAY,KAAK;AAAA,UACf,MAAM,OAAO;AAAA,UACb,MAAM;AAAA,UACN,MAAM;AAAA,UACN,KAAK,KAAK;AAAA,QACZ,CAAC;AAAA,MACH;AAGA,YAAM,OAAO,MAAM,IAAY,QAAQ,GAAG,QAAQ,cAAc;AAAA,QAC9D,WAAW,WAAW,KAAK;AAAA,QAC3B,MAAM;AAAA,MACR,CAAC;AACD,UAAI,CAAC,KAAM,OAAM,IAAI,YAAY,0DAA0D;AAG3F,YAAM,SACJ,MAAM,cAAc,MAAM,cACtB,EAAE,MAAM,MAAM,YAAY,OAAO,MAAM,aAAa,MAAM,IAAI,EAAE,YAAY,EAAE,IAC9E;AACN,YAAM,gBAAgB,oBAAoB,KAAK;AAC/C,YAAM,SAAS,MAAM,IAAc,QAAQ,GAAG,QAAQ,gBAAgB;AAAA,QACpE,SAAS;AAAA,QACT,MAAM,KAAK;AAAA,QACX,SAAS,CAAC,OAAO;AAAA,QACjB,GAAI,SAAS,EAAE,QAAQ,WAAW,OAAO,IAAI,CAAC;AAAA,MAChD,CAAC;AACD,UAAI,CAAC;AACH,cAAM,IAAI,YAAY,4DAA4D;AAGpF,YAAM,WAAW,MAAM;AAAA,QACrB;AAAA,QACA,GAAG,QAAQ,kBAAkB,MAAM,UAAU;AAAA,QAC7C;AAAA,QACA;AAAA,MACF;AACA,UAAI,CAAC,UAAU;AACb,cAAM,IAAI,QAAQ,GAAG,QAAQ,aAAa;AAAA,UACxC,KAAK,cAAc,MAAM,UAAU;AAAA,UACnC,KAAK,OAAO;AAAA,QACd,CAAC;AAAA,MACH,WAAW,SAAS,OAAO,QAAQ,OAAO,KAAK;AAC7C,cAAM,IAAI,SAAS,GAAG,QAAQ,mBAAmB,MAAM,UAAU,IAAI;AAAA,UACnE,KAAK,OAAO;AAAA,UACZ,OAAO;AAAA,QACT,CAAC;AAAA,MACH;AAGA,YAAM,UAAU,MAAM;AAAA,QACpB;AAAA,QACA,GAAG,QAAQ,0BAA0B,mBAAmB,GAAG,MAAM,KAAK,KAAK,IAAI,MAAM,UAAU,EAAE,CAAC;AAAA,MACpG;AACA,UAAI;AACJ,UAAI,WAAW,QAAQ,SAAS,GAAG;AACjC,aAAK,QAAQ,CAAC;AAAA,MAChB,OAAO;AACL,cAAM,UAAU,MAAM,IAAmB,QAAQ,GAAG,QAAQ,UAAU;AAAA,UACpE,OAAO,MAAM;AAAA,UACb,MAAM,MAAM;AAAA,UACZ,MAAM,MAAM;AAAA,UACZ,MAAM;AAAA,QACR,CAAC;AACD,YAAI,CAAC;AACH,gBAAM,IAAI,YAAY,wDAAwD;AAChF,aAAK;AAAA,MACP;AAEA,UAAI,MAAM,aAAa,MAAM,UAAU,SAAS,GAAG;AACjD,cAAM;AAAA,UACJ;AAAA,UACA,GAAG,QAAQ,UAAU,GAAG,MAAM;AAAA,UAC9B,EAAE,WAAW,MAAM,UAAU;AAAA,UAC7B;AAAA,QACF,EAAE,MAAM,MAAM;AAAA,QAEd,CAAC;AAAA,MACH;AACA,UAAI,MAAM,UAAU,MAAM,OAAO,SAAS,GAAG;AAC3C,cAAM;AAAA,UACJ;AAAA,UACA,GAAG,QAAQ,WAAW,GAAG,MAAM;AAAA,UAC/B,EAAE,QAAQ,MAAM,OAAO;AAAA,UACvB;AAAA,QACF,EAAE,MAAM,MAAM;AAAA,QAEd,CAAC;AAAA,MACH;AAEA,aAAO;AAAA,QACL,OAAO,GAAG;AAAA,QACV,YAAY,MAAM;AAAA,QAClB,SAAS,OAAO;AAAA,QAChB,QAAQ;AAAA,MACV;AAAA,IACF;AAAA,EACF;AACF;AA0BO,SAAS,YAAY,OAA2B,CAAC,GAAiB;AACvE,QAAM,MAAM,KAAK,OAAO;AACxB,QAAM,MAAM,KAAK,OAAO,QAAQ,IAAI;AACpC,QAAM,OAAO,KAAK,QAAQ;AAE1B,iBAAe,IACb,KACA,MACA,OAC6C;AAC7C,UAAM,IAAI,MAAM,KAAK,KAAK,MAAM,EAAE,KAAK,MAAM,CAAC;AAC9C,QAAI,EAAE,aAAa,GAAG;AACpB,YAAM,IAAI;AAAA,QACR,gCAAgC,GAAG,IAAI,KAAK,KAAK,GAAG,CAAC,YAAY,EAAE,QAAQ,MAAM,EAAE,OAAO,KAAK,KAAK,EAAE,OAAO,KAAK,CAAC;AAAA,MACrH;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAEA,SAAO;AAAA,IACL,MAAM,cAAc,OAAO;AACzB,YAAM,aAAa,MAAM,cAAc;AACvC,UAAI,MAAM,QAAQ;AAChB,eAAO;AAAA,UACL,OAAO,sBAAsB,MAAM,KAAK,KAAK,IAAI,MAAM,KAAK,IAAI,YAAY,UAAU,MAAM,MAAM,UAAU;AAAA,UAC5G,YAAY,MAAM;AAAA,UAClB,SAAS;AAAA,UACT,QAAQ;AAAA,QACV;AAAA,MACF;AAGA,YAAM,IAAI,OAAO,CAAC,SAAS,UAAU,UAAU,CAAC;AAChD,YAAM,IAAI,OAAO,CAAC,YAAY,UAAU,CAAC;AACzC,YAAM,IAAI,OAAO,CAAC,SAAS,UAAU,UAAU,UAAU,EAAE,CAAC;AAG5D,YAAM,KAAK,OAAO,CAAC,UAAU,MAAM,MAAM,UAAU,GAAG,EAAE,IAAI,CAAC;AAC7D,YAAM,IAAI,OAAO,CAAC,YAAY,MAAM,MAAM,UAAU,CAAC;AAGrD,YAAM,EAAE,OAAO,UAAU,IAAI,MAAM,OAAO,aAAkB;AAC5D,YAAM,EAAE,SAAAC,UAAS,MAAAC,OAAM,QAAQ,IAAI,MAAM,OAAO,MAAW;AAC3D,iBAAW,UAAU,MAAM,aAAa;AACtC,cAAM,MAAM,QAAQ,KAAK,OAAO,IAAI;AACpC,cAAM,MAAMD,SAAQ,GAAG,GAAG,EAAE,WAAW,KAAK,CAAC;AAC7C,cAAM,UAAU,KAAK,OAAO,UAAU,MAAM;AAC5C,cAAM,IAAI,OAAO,CAAC,OAAOC,MAAK,OAAO,IAAI,CAAC,CAAC;AAAA,MAC7C;AAGA,YAAM,MAA8B,CAAC;AACrC,UAAI,MAAM,WAAY,KAAI,kBAAkB,MAAM;AAClD,UAAI,MAAM,YAAa,KAAI,mBAAmB,MAAM;AACpD,UAAI,MAAM,WAAY,KAAI,qBAAqB,MAAM;AACrD,UAAI,MAAM,YAAa,KAAI,sBAAsB,MAAM;AACvD,YAAM,UAAU,oBAAoB,KAAK;AACzC,YAAM,IAAI,OAAO,CAAC,UAAU,MAAM,OAAO,CAAC;AAE1C,YAAM,UAAU,MAAM,IAAI,OAAO,CAAC,aAAa,MAAM,CAAC;AACtD,YAAM,UAAU,QAAQ,OAAO,KAAK;AAGpC,YAAM,IAAI,OAAO,CAAC,QAAQ,MAAM,UAAU,MAAM,UAAU,CAAC;AAG3D,YAAM,WAAW,MAAM;AAAA,QACrB;AAAA,QACA;AAAA,UACE;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA,MAAM;AAAA,UACN;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,QACA,EAAE,IAAI;AAAA,MACR;AACA,UAAI,QAAQ;AACZ,UAAI,SAAS,aAAa,KAAK,SAAS,OAAO,KAAK,GAAG;AACrD,cAAM,SAAS,KAAK,MAAM,SAAS,MAAM;AACzC,YAAI,OAAO,SAAS,KAAK,OAAO,CAAC,EAAG,SAAQ,OAAO,CAAC,EAAE;AAAA,MACxD;AACA,UAAI,CAAC,OAAO;AACV,cAAM,OAAO;AAAA,UACX;AAAA,UACA;AAAA,UACA;AAAA,UACA,MAAM;AAAA,UACN;AAAA,UACA,MAAM;AAAA,UACN;AAAA,UACA;AAAA,QACF;AACA,YAAI,MAAM,aAAa,MAAM,UAAU,SAAS,GAAG;AACjD,eAAK,KAAK,cAAc,MAAM,UAAU,KAAK,GAAG,CAAC;AAAA,QACnD;AACA,YAAI,MAAM,UAAU,MAAM,OAAO,SAAS,GAAG;AAC3C,eAAK,KAAK,WAAW,MAAM,OAAO,KAAK,GAAG,CAAC;AAAA,QAC7C;AACA,cAAM,IAAI,MAAM,IAAI,KAAK,IAAI;AAC7B,cAAM,QAAQ,EAAE,OAAO,MAAM,gBAAgB;AAC7C,gBAAQ,QAAQ,MAAM,CAAC,IAAI,EAAE,OAAO,KAAK;AAAA,MAC3C;AAEA,aAAO,EAAE,OAAO,YAAY,MAAM,YAAY,SAAS,QAAQ,MAAM;AAAA,IACvE;AAAA,EACF;AACF;AAEA,eAAe,YACb,KACA,MACA,MAC+D;AAC/D,QAAM,EAAE,MAAM,IAAI,MAAM,OAAO,eAAoB;AACnD,SAAO,IAAI,QAAQ,CAAC,gBAAgB;AAClC,UAAM,QAAQ,MAAM,KAAK,MAAM,EAAE,KAAK,KAAK,IAAI,CAAC;AAChD,QAAI,SAAS;AACb,QAAI,SAAS;AACb,UAAM,OAAO,GAAG,QAAQ,CAAC,MAAM;AAC7B,gBAAU,EAAE,SAAS;AAAA,IACvB,CAAC;AACD,UAAM,OAAO,GAAG,QAAQ,CAAC,MAAM;AAC7B,gBAAU,EAAE,SAAS;AAAA,IACvB,CAAC;AACD,QAAI,KAAK,MAAO,OAAM,MAAM,IAAI,KAAK,KAAK;AAC1C,UAAM,GAAG,SAAS,CAAC,QAAQ;AACzB,kBAAY,EAAE,QAAQ,QAAQ,GAAG,MAAM,GAAG,IAAI,OAAO,IAAI,UAAU,EAAE,CAAC;AAAA,IACxE,CAAC;AACD,UAAM,GAAG,SAAS,CAAC,SAAS;AAC1B,kBAAY,EAAE,QAAQ,QAAQ,UAAU,QAAQ,EAAE,CAAC;AAAA,IACrD,CAAC;AAAA,EACH,CAAC;AACH;AAEA,SAAS,oBAAoB,OAAiD;AAC5E,QAAM,QAAQ,CAAC,MAAM,OAAO,EAAE;AAC9B,aAAW,UAAU,MAAM,aAAa;AACtC,QAAI,OAAO,UAAW,OAAM,KAAK,KAAK,OAAO,IAAI,KAAK,OAAO,SAAS,EAAE;AAAA,EAC1E;AACA,MAAI,MAAM,MAAM,SAAS,CAAC,MAAM,GAAI,OAAM,KAAK,EAAE;AACjD,QAAM,KAAK,MAAM,KAAK,KAAK,CAAC;AAC5B,SAAO,MAAM,KAAK,IAAI,EAAE,KAAK;AAC/B;;;ACpdA,eAAsB,gBACpB,IACA,UACA,QACyB;AACzB,QAAM,YAAY,KAAK,IAAI;AAC3B,QAAM,QAAQ,OAAO,SAAS;AAE9B,QAAM,eAAe,CAAC,OAAO,cAAc,SAAS,sBAAsB,EAAE,EACzE,OAAO,OAAO,EACd,KAAK,MAAM;AAEd,QAAM,WAA0B,CAAC,EAAE,MAAM,UAAU,SAAS,aAAa,CAAC;AAE1E,QAAM,QAAsB,CAAC;AAC7B,QAAM,gBAAsD,CAAC;AAC7D,QAAM,YAAgE,CAAC;AACvE,QAAM,eAAyB,CAAC;AAEhC,QAAM,UAAU,OAAO,gBAAgB;AAEvC,WAAS,IAAI,GAAG,IAAI,SAAS,MAAM,QAAQ,KAAK;AAC9C,UAAM,OAAO,SAAS,MAAM,CAAC;AAC7B,UAAM,YAAY,KAAK,IAAI;AAE3B,aAAS,KAAK,EAAE,MAAM,QAAQ,SAAS,KAAK,KAAK,CAAC;AAElD,UAAM,OAAO,MAAM,GAAG,KAAK;AAAA,MACzB;AAAA,MACA;AAAA,MACA,aAAa;AAAA,MACb,WAAW;AAAA,IACb,CAAC;AAED,UAAM,UACH,KAA4D,UAAU,CAAC,GAAG,SAAS,WACpF;AAEF,aAAS,KAAK,EAAE,MAAM,aAAa,QAAQ,CAAC;AAG5C,UAAM,SAAS;AACf,QAAI;AACJ,YAAQ,YAAY,OAAO,KAAK,OAAO,OAAO,MAAM;AAClD,oBAAc,KAAK,EAAE,UAAU,UAAU,CAAC,KAAK,QAAQ,MAAM,UAAU,CAAC,KAAK,GAAG,CAAC;AAAA,IACnF;AAGA,UAAM,aAAgD,CAAC;AACvD,QAAI;AACJ,UAAM,eAAe,IAAI,OAAO,QAAQ,QAAQ,QAAQ,KAAK;AAC7D,YAAQ,aAAa,aAAa,KAAK,OAAO,OAAO,MAAM;AACzD,YAAM,SAAiC,CAAC;AACxC,iBAAW,SAAS,WAAW,CAAC,KAAK,IAAI,MAAM,IAAI,GAAG;AACpD,cAAM,MAAM,KAAK,QAAQ,GAAG;AAC5B,YAAI,MAAM,EAAG,QAAO,KAAK,MAAM,GAAG,GAAG,EAAE,KAAK,CAAC,IAAI,KAAK,MAAM,MAAM,CAAC,EAAE,KAAK;AAAA,MAC5E;AACA,YAAM,YAAY,WAAW,CAAC,KAAK;AACnC,gBAAU,KAAK,EAAE,MAAM,WAAW,OAAO,CAAC;AAC1C,iBAAW,KAAK,EAAE,MAAM,WAAW,OAAO,OAAO,SAAS,GAAG,CAAC;AAAA,IAChE;AAGA,QAAI,cAAc;AAClB,QAAI,OAAO,kBAAkB;AAC3B,iBAAW,WAAW,OAAO,kBAAkB;AAC7C,cAAM,KAAK,IAAI,OAAO,QAAQ,QAAQ,QAAQ,KAAK;AACnD,YAAI;AACJ,gBAAQ,YAAY,GAAG,KAAK,OAAO,OAAO,MAAM;AAC9C,uBAAa,KAAK,UAAU,CAAC,CAAC;AAC9B,wBAAc;AAAA,QAChB;AAAA,MACF;AAAA,IACF;AAEA,UAAM,KAAK;AAAA,MACT,WAAW;AAAA,MACX,aAAa,KAAK;AAAA,MAClB,eAAe;AAAA,MACf,YAAY,KAAK,IAAI,IAAI;AAAA,MACzB,iBAAiB;AAAA,MACjB,cAAc,cAAc,SAAS;AAAA,MACrC,kBAAkB;AAAA,IACpB,CAAC;AAAA,EACH;AAEA,QAAM,YAAgC;AAAA,IACpC,YAAY,CAAC;AAAA,IACb,iBAAiB;AAAA,IACjB,YAAY;AAAA,IACZ,WAAW;AAAA,EACb;AAGA,QAAM,kBAAkB,SAAS,eAAe,IAAI,CAACC,WAAU;AAE7D,QAAI,OAAO,iBAAiB;AAC1B,YAAM,SAAS,OAAO,gBAAgBA,QAAO,SAAS;AACtD,UAAI,OAAQ,QAAO,EAAE,OAAAA,QAAO,GAAG,OAAO;AAAA,IACxC;AAEA,YAAQA,OAAM,MAAM;AAAA,MAClB,KAAK,mBAAmB;AACtB,cAAM,QAAQ,UAAU,OAAO,CAAC,MAAM,EAAE,SAASA,OAAM,MAAM,EAAE;AAC/D,eAAO;AAAA,UACL,OAAAA;AAAA,UACA,QAAQ,UAAUA,OAAM,YAAY;AAAA,UACpC,QAAQ,SAAS,KAAK,IAAIA,OAAM,MAAM,iBAAiBA,OAAM,YAAY,CAAC;AAAA,QAC5E;AAAA,MACF;AAAA,MACA,KAAK,cAAc;AACjB,cAAM,UAAU,cAAc;AAAA,UAC5B,CAAC,MAAM,EAAE,aAAaA,OAAM,UAAU,EAAE,KAAK,SAASA,OAAM,MAAM;AAAA,QACpE;AACA,eAAO,EAAE,OAAAA,QAAO,QAAQ,SAAS,QAAQ,UAAU,qBAAqB,mBAAmB;AAAA,MAC7F;AAAA,MACA;AACE,eAAO;AAAA,UACL,OAAAA;AAAA,UACA,QAAQ;AAAA,UACR,QAAQ,eAAeA,OAAM,IAAI;AAAA,QACnC;AAAA,IACJ;AAAA,EACF,CAAC;AAGD,QAAM,aAAa,EAAE,UAAU,OAAO,UAAU;AAChD,QAAM,eAA+B,CAAC;AAEtC,aAAW,SAAS,OAAO,QAAQ;AACjC,QAAI,UAAU;AACd,aAAS,UAAU,GAAG,UAAU,GAAG,WAAW;AAC5C,UAAI;AACF,YAAI,UAAU,GAAG;AACf,gBAAM,OAAO,UAAU;AACvB,kBAAQ,IAAI,mBAAmB,OAAO,eAAe,OAAO,GAAI,IAAI;AACpE,gBAAM,IAAI,QAAQ,CAAC,MAAM,WAAW,GAAG,IAAI,CAAC;AAAA,QAC9C;AACA,cAAMC,UAAS,MAAM,MAAM,IAAI,UAAU;AACzC,qBAAa,KAAKA,OAAM;AACxB,cAAM,IAAI,QAAQ,CAAC,MAAM,WAAW,GAAG,GAAI,CAAC;AAC5C;AAAA,MACF,SAAS,KAAK;AACZ,kBAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AACzD,YAAI,YAAY,GAAG;AACjB,uBAAa,KAAK;AAAA,YAChB;AAAA,cACE,WAAW;AAAA,cACX,WAAW;AAAA,cACX,OAAO;AAAA,cACP,WAAW,kCAAkC,QAAQ,MAAM,GAAG,GAAG,CAAC;AAAA,YACpE;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,QAAM,YAAY,aAAa,KAAK;AACpC,QAAM,cAAc,UAAU;AAAA,IAC5B,CAAC,MAAM,EAAE,cAAc,iBAAiB,EAAE,cAAc;AAAA,EAC1D;AACA,QAAM,cAAc,UAAU;AAAA,IAC5B,CAAC,MAAM,EAAE,cAAc,iBAAiB,EAAE,cAAc;AAAA,EAC1D;AACA,QAAM,aAAa,gBAAgB,WAAW;AAG9C,QAAM,YAAY,oBAAI,IAAoB;AAC1C,aAAW,OAAO,SAAS,YAAY;AACrC,cAAU,IAAI,KAAK,CAAC;AAAA,EACtB;AAEA,QAAM,eAAe;AAAA,IACnB,WAAW,IAAI,CAAC,OAAO;AAAA,MACrB,OAAO,EAAE;AAAA,MACT,QAAQ,UAAU,IAAI,EAAE,SAAS,KAAK;AAAA,IACxC,EAAE;AAAA,EACJ;AAEA,SAAO;AAAA,IACL,YAAY,SAAS;AAAA,IACrB,SAAS,SAAS;AAAA,IAClB;AAAA,IACA;AAAA,IACA,aAAa;AAAA,IACb,aAAa,YAAY;AAAA,IACzB;AAAA,IACA,iBAAiB,KAAK,IAAI,IAAI;AAAA,IAC9B;AAAA,EACF;AACF;;;AC7NO,IAAM,kBAAN,MAAsB;AAAA,EACnB;AAAA,EACA;AAAA,EAER,YAAY,IAAY,QAA+B;AACrD,SAAK,KAAK;AACV,SAAK,SAAS;AAAA,EAChB;AAAA,EAEA,MAAM,IAAI,WAAkD;AAC1D,UAAM,QAAQ,aAAa,KAAK,OAAO;AACvC,UAAM,gBAAgB,KAAK,OAAO,iBAAiB;AAEnD,YAAQ,IAAI,IAAI,OAAO,EAAE,CAAC;AAC1B,YAAQ,IAAI,8BAAyB;AACrC,YAAQ,IAAI,2CAA2C;AACvD,YAAQ,IAAI,IAAI,OAAO,EAAE,CAAC;AAC1B,YAAQ,IAAI,cAAc,MAAM,MAAM,EAAE;AACxC,YAAQ,IAAI,WAAW,KAAK,OAAO,OAAO,MAAM,EAAE;AAClD,YAAQ,IAAI,UAAU,KAAK,OAAO,SAAS,QAAQ,EAAE;AACrD,YAAQ,IAAI;AAEZ,UAAM,UAA4B,CAAC;AAEnC,aAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,YAAM,WAAW,MAAM,CAAC;AACxB,cAAQ,IAAI,IAAI,IAAI,CAAC,IAAI,MAAM,MAAM,KAAK,SAAS,EAAE,KAAK,SAAS,OAAO,GAAG;AAC7E,cAAQ,IAAI,aAAa,SAAS,MAAM,EAAE;AAC1C,cAAQ,IAAI,YAAY,SAAS,MAAM,MAAM,EAAE;AAE/C,YAAM,SAAS,MAAM,gBAAgB,KAAK,IAAI,UAAU;AAAA,QACtD,cAAc,KAAK,OAAO;AAAA,QAC1B,OAAO,KAAK,OAAO;AAAA,QACnB,QAAQ,KAAK,OAAO;AAAA,MACtB,CAAC;AACD,cAAQ,KAAK,MAAM;AAGnB,iBAAW,QAAQ,OAAO,OAAO;AAC/B,cAAM,WAAW,KAAK,eAAe,WAAW;AAChD,cAAM,WAAW,KAAK,mBAAmB,WAAW;AACpD,cAAM,aAAa,KAAK,gBAAgB;AACxC,cAAM,YAAY,aAAa,IAAI,WAAW,UAAU,MAAM;AAC9D,gBAAQ;AAAA,UACN,UAAU,KAAK,YAAY,CAAC,MAAM,KAAK,aAAa,KAAM,QAAQ,CAAC,CAAC,KAAK,QAAQ,IAAI,QAAQ,IAAI,SAAS,KAAK,KAAK,cAAc,MAAM;AAAA,QAC1I;AAAA,MACF;AAGA,iBAAW,MAAM,OAAO,iBAAiB;AACvC,cAAM,OAAO,GAAG,SAAS,MAAM;AAC/B,gBAAQ,IAAI,gBAAgB,IAAI,KAAK,GAAG,MAAM,WAAW,WAAM,GAAG,MAAM,EAAE;AAAA,MAC5E;AAGA,cAAQ,IAAI,WAAW;AACvB,YAAM,UAAsE,CAAC;AAC7E,iBAAW,MAAM,OAAO,aAAa;AACnC,cAAM,QAAQ,QAAQ,GAAG,SAAS,KAAK,EAAE,QAAQ,CAAC,GAAG,YAAY,CAAC,EAAE;AACpE,cAAM,OAAO,KAAK,GAAG,KAAK;AAC1B,cAAM,WAAW,KAAK,GAAG,GAAG,SAAS,IAAI,GAAG,KAAK,EAAE;AACnD,gBAAQ,GAAG,SAAS,IAAI;AAAA,MAC1B;AACA,iBAAW,CAAC,MAAM,IAAI,KAAK,OAAO,QAAQ,OAAO,GAAG;AAClD,cAAM,OAAO,KAAK,OAAO,OAAO,CAAC,GAAG,MAAM,IAAI,GAAG,CAAC,IAAI,KAAK,OAAO,QAAQ,QAAQ,CAAC;AACnF,gBAAQ,IAAI,OAAO,KAAK,OAAO,EAAE,CAAC,QAAQ,GAAG,MAAM,KAAK,WAAW,KAAK,IAAI,CAAC,GAAG;AAAA,MAClF;AAEA,cAAQ;AAAA,QACN,cAAc,OAAO,aAAa,QAAQ,CAAC,CAAC,SAAS,OAAO,kBAAkB,KAAM,QAAQ,CAAC,CAAC;AAAA,MAChG;AACA,cAAQ,IAAI;AAAA,IACd;AAGA,UAAM,YAA4E,CAAC;AACnF,UAAM,cAAiE,CAAC;AAExE,eAAW,KAAK,SAAS;AACvB,YAAM,eAAe,UAAU,EAAE,OAAO,KAAK,EAAE,KAAK,GAAG,QAAQ,GAAG,OAAO,EAAE;AAC3E,mBAAa;AACb,mBAAa,OAAO,EAAE;AACtB,UAAI,EAAE,gBAAgB,cAAe,cAAa;AAClD,gBAAU,EAAE,OAAO,IAAI;AAEvB,iBAAW,MAAM,EAAE,aAAa;AAC9B,cAAM,WAAW,YAAY,GAAG,SAAS,KAAK,EAAE,KAAK,GAAG,QAAQ,CAAC,EAAE;AACnE,iBAAS,OAAO,KAAK,GAAG,KAAK;AAC7B,oBAAY,GAAG,SAAS,IAAI;AAAA,MAC9B;AAAA,IACF;AAEA,eAAW,KAAK,OAAO,OAAO,SAAS,GAAG;AACxC,QAAE,MAAM,EAAE,QAAQ,IAAI,EAAE,MAAM,EAAE,QAAQ;AAAA,IAC1C;AACA,eAAW,KAAK,OAAO,OAAO,WAAW,GAAG;AAC1C,QAAE,MAAM,EAAE,OAAO,SAAS,IAAI,EAAE,OAAO,OAAO,CAAC,GAAG,MAAM,IAAI,GAAG,CAAC,IAAI,EAAE,OAAO,SAAS;AAAA,IACxF;AAEA,UAAM,SAAS,CAAC,GAAG,OAAO,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,eAAe,EAAE,YAAY;AAC1E,UAAM,UAAU,OAAO,MAAM,GAAG,CAAC,EAAE,IAAI,CAAC,OAAO;AAAA,MAC7C,UAAU,EAAE;AAAA,MACZ,OAAO,EAAE;AAAA,MACT,QACE,EAAE,YACC,OAAO,CAAC,MAAM,EAAE,QAAQ,aAAa,EACrC,IAAI,CAAC,MAAM,GAAG,EAAE,SAAS,IAAI,EAAE,KAAK,EAAE,EACtC,KAAK,IAAI,KAAK;AAAA,IACrB,EAAE;AACF,UAAM,YAAY,OACf,MAAM,EAAE,EACR,QAAQ,EACR,IAAI,CAAC,OAAO;AAAA,MACX,UAAU,EAAE;AAAA,MACZ,OAAO,EAAE;AAAA,MACT,QACE,EAAE,YACC,OAAO,CAAC,MAAM,EAAE,SAAS,CAAC,EAC1B,IAAI,CAAC,MAAM,GAAG,EAAE,SAAS,IAAI,EAAE,KAAK,EAAE,EACtC,KAAK,IAAI,KAAK;AAAA,IACrB,EAAE;AAGJ,YAAQ,IAAI,IAAI,OAAO,EAAE,CAAC;AAC1B,YAAQ,IAAI,UAAU;AACtB,YAAQ,IAAI,IAAI,OAAO,EAAE,CAAC;AAE1B,UAAM,aACJ,QAAQ,SAAS,IAAI,QAAQ,OAAO,CAAC,GAAG,MAAM,IAAI,EAAE,cAAc,CAAC,IAAI,QAAQ,SAAS;AAE1F,YAAQ,IAAI,YAAY,WAAW,QAAQ,CAAC,CAAC,KAAK;AAClD,YAAQ,IAAI;AAEZ,YAAQ,IAAI,aAAa;AACzB,eAAW,CAAC,MAAM,IAAI,KAAK,OAAO,QAAQ,SAAS,GAAG;AACpD,cAAQ;AAAA,QACN,KAAK,KAAK,OAAO,EAAE,CAAC,IAAI,KAAK,IAAI,QAAQ,CAAC,CAAC,SAAS,KAAK,MAAM,IAAI,KAAK,KAAK;AAAA,MAC/E;AAAA,IACF;AACA,YAAQ,IAAI;AAEZ,YAAQ,IAAI,eAAe;AAC3B,UAAM,aAAa,OAAO,QAAQ,WAAW,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,GAAG;AACjF,eAAW,CAAC,MAAM,IAAI,KAAK,YAAY;AACrC,YAAM,MAAM,KAAK,IAAI,GAAG,KAAK,MAAM;AACnC,YAAM,MAAM,KAAK,IAAI,GAAG,KAAK,MAAM;AACnC,cAAQ;AAAA,QACN,KAAK,KAAK,OAAO,EAAE,CAAC,QAAQ,KAAK,IAAI,QAAQ,CAAC,CAAC,YAAY,GAAG,IAAI,GAAG,QAAQ,KAAK,OAAO,MAAM;AAAA,MACjG;AAAA,IACF;AACA,YAAQ,IAAI;AAEZ,QAAI,QAAQ,SAAS,GAAG;AACtB,cAAQ,IAAI,UAAU;AACtB,iBAAW,KAAK,SAAS;AACvB,gBAAQ,IAAI,KAAK,EAAE,QAAQ,KAAK,EAAE,MAAM,QAAQ,CAAC,CAAC,WAAM,EAAE,MAAM,EAAE;AAAA,MACpE;AACA,cAAQ,IAAI;AAAA,IACd;AAEA,WAAO;AAAA,MACL,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MAClC,YAAY,KAAK,OAAO,cAAc;AAAA,MACtC,eAAe,KAAK,OAAO,iBAAiB;AAAA,MAC5C,eAAe,MAAM;AAAA,MACrB;AAAA,MACA,SAAS,EAAE,YAAY,WAAW,aAAa,SAAS,UAAU;AAAA,IACpE;AAAA,EACF;AACF;;;AC3KO,IAAM,gBAAN,MAAoB;AAAA,EACjB;AAAA,EACA;AAAA,EACA,UAAkB;AAAA,EAE1B,YAAY,QAA6B;AACvC,SAAK,UAAU,OAAO,QAAQ,QAAQ,QAAQ,EAAE;AAChD,SAAK,SAAS,OAAO;AAAA,EACvB;AAAA,EAEQ,MAAM,MAA8B;AAC1C,UAAM,OAAO,KAAK,OAAO,IAAI;AAC7B,QAAI,CAAC,KAAM,OAAM,IAAI,MAAM,UAAU,IAAI,kBAAkB;AAC3D,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,OAAO,MAAc,OAAe,UAA+C;AACvF,UAAM,MAAM,MAAM,KAAK,KAAK,KAAK,MAAM,QAAQ,GAAG,EAAE,MAAM,OAAO,SAAS,CAAC;AAC3E,UAAM,OAAO,IAAI;AACjB,QAAI,CAAC,MAAM,GAAI,OAAM,IAAI,MAAM,kBAAkB,KAAK,UAAU,GAAG,CAAC,EAAE;AACtE,WAAO,EAAE,QAAQ,KAAK,GAAa;AAAA,EACrC;AAAA,EAEA,MAAM,MAAM,OAAe,UAAiC;AAC1D,UAAM,MAAM,MAAM,MAAM,GAAG,KAAK,OAAO,GAAG,KAAK,MAAM,OAAO,CAAC,IAAI;AAAA,MAC/D,QAAQ;AAAA,MACR,SAAS,EAAE,gBAAgB,oBAAoB,QAAQ,KAAK,QAAQ;AAAA,MACpE,MAAM,KAAK,UAAU,EAAE,OAAO,SAAS,CAAC;AAAA,MACxC,UAAU;AAAA,IACZ,CAAC;AACD,UAAM,YAAY,IAAI,QAAQ,IAAI,YAAY;AAC9C,QAAI,WAAW;AACb,WAAK,UAAU,UAAU,MAAM,GAAG,EAAE,CAAC,KAAK;AAAA,IAC5C;AACA,UAAM,OAAQ,MAAM,IAAI,KAAK;AAC7B,QAAI,CAAC,KAAK,KAAM,OAAM,IAAI,MAAM,iBAAiB,KAAK,UAAU,IAAI,CAAC,EAAE;AAAA,EACzE;AAAA,EAEA,MAAM,gBAAgB,MAAc,OAAO,WAA4B;AACrE,UAAM,MAAM,MAAM,KAAK,KAAK,KAAK,MAAM,YAAY,GAAG,EAAE,MAAM,KAAK,CAAC;AACpE,UAAM,KAAK,IAAI;AACf,QAAI,CAAC,IAAI,GAAI,OAAM,IAAI,MAAM,8BAA8B,KAAK,UAAU,GAAG,CAAC,EAAE;AAChF,WAAO,GAAG;AAAA,EACZ;AAAA,EAEA,MAAM,aAAa,aAAsC;AACvD,UAAM,MAAM,MAAM,KAAK,KAAK,KAAK,MAAM,SAAS,GAAG,EAAE,YAAY,CAAC;AAClE,UAAM,SAAS,IAAI;AACnB,QAAI,CAAC,QAAQ,GAAI,OAAM,IAAI,MAAM,2BAA2B,KAAK,UAAU,GAAG,CAAC,EAAE;AACjF,WAAO,OAAO;AAAA,EAChB;AAAA,EAEA,MAAM,KACJ,aACA,UACA,SACA,OACsE;AACtE,UAAM,MAAM,MAAM,MAAM,GAAG,KAAK,OAAO,GAAG,KAAK,MAAM,MAAM,CAAC,IAAI;AAAA,MAC9D,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,gBAAgB;AAAA,QAChB,QAAQ,KAAK;AAAA,QACb,QAAQ,KAAK;AAAA,MACf;AAAA,MACA,MAAM,KAAK,UAAU,EAAE,aAAa,UAAU,QAAQ,CAAC;AAAA,IACzD,CAAC;AAED,QAAI,CAAC,IAAI,MAAM,CAAC,IAAI,KAAM,OAAM,IAAI,MAAM,gBAAgB,IAAI,MAAM,EAAE;AAGtE,UAAM,SAAS,IAAI,KAAK,UAAU;AAClC,UAAM,UAAU,IAAI,YAAY;AAChC,QAAI,MAAM;AACV,QAAI,OAAO;AACX,UAAM,SAA4C,CAAC;AAEnD,WAAO,MAAM;AACX,YAAM,EAAE,MAAM,MAAM,IAAI,MAAM,OAAO,KAAK;AAC1C,UAAI,KAAM;AACV,aAAO,QAAQ,OAAO,OAAO,EAAE,QAAQ,KAAK,CAAC;AAC7C,YAAM,QAAQ,IAAI,MAAM,IAAI;AAC5B,YAAM,MAAM,IAAI,KAAK;AACrB,iBAAW,QAAQ,OAAO;AACxB,YAAI,CAAC,KAAK,KAAK,EAAG;AAClB,YAAI;AACF,gBAAM,QAAQ,KAAK,MAAM,IAAI;AAC7B,cAAI,MAAM,SAAS,0BAA0B,MAAM,MAAM,OAAO;AAC9D,oBAAQ,MAAM,KAAK;AAAA,UACrB;AAAA,QACF,QAAQ;AAAA,QAER;AAAA,MACF;AAAA,IACF;AAGA,UAAM,UAAU;AAChB,QAAI;AACJ,YAAQ,QAAQ,QAAQ,KAAK,IAAI,OAAO,MAAM;AAC5C,YAAM,SAAiC,CAAC;AACxC,iBAAW,QAAQ,MAAM,CAAC,EAAG,MAAM,IAAI,GAAG;AACxC,cAAM,MAAM,KAAK,QAAQ,GAAG;AAC5B,YAAI,MAAM,EAAG,QAAO,KAAK,MAAM,GAAG,GAAG,EAAE,KAAK,CAAC,IAAI,KAAK,MAAM,MAAM,CAAC,EAAE,KAAK;AAAA,MAC5E;AACA,aAAO,KAAK,EAAE,MAAM,MAAM,CAAC,GAAI,OAAO,OAAO,SAAS,GAAG,CAAC;AAAA,IAC5D;AAEA,WAAO,EAAE,MAAM,OAAO;AAAA,EACxB;AAAA,EAEA,MAAM,SACJ,aAC4E;AAC5E,UAAM,MAAM,MAAM,KAAK,IAAI,GAAG,KAAK,MAAM,OAAO,CAAC,gBAAgB,WAAW,EAAE;AAC9E,WAAQ,IAAI,SAAS,CAAC;AAAA,EACxB;AAAA,EAEA,MAAM,UAAU,aAA6E;AAC3F,UAAM,MAAM,MAAM,KAAK,IAAI,GAAG,KAAK,MAAM,QAAQ,CAAC,gBAAgB,WAAW,EAAE;AAC/E,WAAQ,IAAI,UAAU,CAAC;AAAA,EACzB;AAAA,EAEA,MAAM,aACJ,aACwE;AACxE,UAAM,MAAM,MAAM,KAAK,IAAI,GAAG,KAAK,MAAM,WAAW,CAAC,gBAAgB,WAAW,EAAE;AAClF,WAAQ,IAAI,WAAW,CAAC;AAAA,EAC1B;AAAA,EAEA,MAAM,aAAa,aAAwC;AACzD,UAAM,MAAM,MAAM,KAAK,IAAI,GAAG,KAAK,MAAM,OAAO,CAAC,gBAAgB,WAAW,EAAE;AAC9E,UAAM,QAAkB,CAAC;AACzB,aAAS,QAAQ,OAAkB;AACjC,iBAAW,KAAK,OAAO;AACrB,cAAM,OAAO;AACb,YAAI,KAAK,SAAS,UAAU,KAAK,KAAM,OAAM,KAAK,KAAK,IAAI;AAC3D,YAAI,KAAK,SAAU,SAAQ,KAAK,QAAQ;AAAA,MAC1C;AAAA,IACF;AACA,YAAS,IAAI,QAAQ,CAAC,CAAe;AACrC,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,cAAc,aAAqB,IAA2B;AAClE,UAAM,KAAK,MAAM,KAAK,MAAM,WAAW,GAAG,EAAE,aAAa,IAAI,QAAQ,WAAW,CAAC;AAAA,EACnF;AAAA,EAEA,MAAM,aAAa,aAAqB,IAAY,QAA+B;AACjF,UAAM,KAAK,MAAM,KAAK,MAAM,WAAW,GAAG,EAAE,aAAa,IAAI,QAAQ,YAAY,OAAO,CAAC;AAAA,EAC3F;AAAA,EAEA,MAAM,eACJ,aACyD;AACzD,UAAM,MAAM,MAAM,KAAK,IAAI,GAAG,KAAK,MAAM,aAAa,CAAC,gBAAgB,WAAW,EAAE;AACpF,WAAQ,IAAI,eAAe,CAAC;AAAA,EAC9B;AAAA;AAAA,EAGA,MAAM,IAAI,MAAgD;AACxD,UAAM,MAAM,MAAM,MAAM,GAAG,KAAK,OAAO,GAAG,IAAI,IAAI;AAAA,MAChD,SAAS,EAAE,QAAQ,KAAK,QAAQ;AAAA,IAClC,CAAC;AACD,WAAO,IAAI,KAAK;AAAA,EAClB;AAAA;AAAA,EAGA,MAAM,KAAK,MAAc,MAAiE;AACxF,UAAM,MAAM,MAAM,MAAM,GAAG,KAAK,OAAO,GAAG,IAAI,IAAI;AAAA,MAChD,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,gBAAgB;AAAA,QAChB,QAAQ,KAAK;AAAA,QACb,QAAQ,KAAK;AAAA,MACf;AAAA,MACA,MAAM,KAAK,UAAU,IAAI;AAAA,IAC3B,CAAC;AACD,WAAO,IAAI,KAAK;AAAA,EAClB;AAAA;AAAA,EAGA,MAAM,MAAM,MAAc,MAAiE;AACzF,UAAM,MAAM,MAAM,MAAM,GAAG,KAAK,OAAO,GAAG,IAAI,IAAI;AAAA,MAChD,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,gBAAgB;AAAA,QAChB,QAAQ,KAAK;AAAA,QACb,QAAQ,KAAK;AAAA,MACf;AAAA,MACA,MAAM,KAAK,UAAU,IAAI;AAAA,IAC3B,CAAC;AACD,WAAO,IAAI,KAAK;AAAA,EAClB;AACF;AAQA,eAAsB,eACpB,QACA,MACA,UACqB;AACrB,QAAM,QAAQ,KAAK,IAAI;AACvB,QAAM,SAAwB,CAAC;AAE/B,MAAI;AACF,UAAM,UAAU,MAAM,SAAS,MAAM;AACrC,WAAO,KAAK,GAAG,OAAO;AAAA,EACxB,SAAS,KAAK;AACZ,WAAO,KAAK;AAAA,MACV,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,QAAQ,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,IACzD,CAAC;AAAA,EACH;AAEA,SAAO;AAAA,IACL;AAAA,IACA,QAAQ,OAAO,MAAM,CAAC,MAAM,EAAE,MAAM;AAAA,IACpC,UAAU,KAAK,IAAI,IAAI;AAAA,IACvB,QAAQ,GAAG,OAAO,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,IAAI,OAAO,MAAM;AAAA,IACjE;AAAA,EACF;AACF;;;ACpOO,IAAM,qBAAN,MAAyB;AAAA,EACtB;AAAA,EACA,UAIF,CAAC;AAAA,EAEP,YAAY,UAAiC;AAC3C,SAAK,WAAW;AAAA,EAClB;AAAA;AAAA,EAGA,OACE,MACA,OAKA;AACA,UAAM,iBAAmD,CAAC;AAC1D,QAAI,cAAc;AAElB,eAAW,aAAa,KAAK,UAAU;AACrC,UAAI,UAAU,UAAU;AACtB,cAAM,SAAS,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,UAAU,SAAS,KAAK,CAAC,CAAC;AACjE,uBAAe,UAAU,IAAI,IAAI;AACjC,uBAAe;AAAA,MACjB,OAAO;AACL,cAAM,SAAS,UAAU,MAAM,KAAK;AACpC,uBAAe,UAAU,IAAI,IAAI;AACjC,uBAAe,SAAS,IAAI;AAAA,MAC9B;AAAA,IACF;AAEA,UAAM,oBACJ,KAAK,SAAS,SAAS,IAAK,cAAc,KAAK,SAAS,SAAU,MAAM;AAE1E,SAAK,QAAQ,KAAK,EAAE,MAAM,mBAAmB,eAAe,CAAC;AAE7D,WAAO;AAAA,MACL;AAAA,MACA,UAAU,eAAe,KAAK,SAAS;AAAA,MACvC;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAGA,WAAqB;AACnB,WAAO,KAAK,QAAQ,IAAI,CAAC,MAAM,EAAE,iBAAiB;AAAA,EACpD;AAAA;AAAA,EAGA,aAAa;AACX,WAAO,CAAC,GAAG,KAAK,OAAO;AAAA,EACzB;AAAA;AAAA,EAGA,sBAAqC;AACnC,UAAM,QAAQ,KAAK,QAAQ,KAAK,CAAC,MAAM,EAAE,sBAAsB,GAAG;AAClE,WAAO,OAAO,QAAQ;AAAA,EACxB;AACF;;;AC9DO,IAAM,gBAA4C;AAAA,EACvD,UAAU,EAAE,OAAO,OAAQ,QAAQ,KAAK;AAAA,EACxC,eAAe,EAAE,OAAO,OAAS,QAAQ,KAAO;AAAA,EAChD,eAAe,EAAE,OAAO,MAAM,QAAQ,KAAK;AAAA,EAC3C,4BAA4B,EAAE,OAAO,MAAO,QAAQ,MAAM;AAAA,EAC1D,0BAA0B,EAAE,OAAO,OAAO,QAAQ,MAAM;AAAA,EACxD,2BAA2B,EAAE,OAAO,OAAS,QAAQ,OAAQ;AAC/D;AASA,IAAM,iBAA8C;AAAA,EAClD,CAAC,gBAAgB,EAAE,OAAO,OAAO,QAAQ,MAAM,CAAC;AAAA,EAChD,CAAC,iBAAiB,EAAE,OAAO,MAAQ,QAAQ,KAAM,CAAC;AAAA,EAClD,CAAC,4CAA4C,EAAE,OAAO,MAAO,QAAQ,MAAM,CAAC;AAAA,EAC5E,CAAC,eAAe,EAAE,OAAO,OAAS,QAAQ,KAAO,CAAC;AAAA,EAClD,CAAC,2BAA2B,EAAE,OAAO,QAAS,QAAQ,KAAK,CAAC;AAAA,EAC5D,CAAC,gBAAgB,EAAE,OAAO,OAAQ,QAAQ,KAAK,CAAC;AAAA,EAChD,CAAC,YAAY,EAAE,OAAO,MAAQ,QAAQ,MAAO,CAAC;AAAA,EAC9C,CAAC,iBAAiB,EAAE,OAAO,MAAQ,QAAQ,MAAO,CAAC;AAAA,EACnD,CAAC,iBAAiB,EAAE,OAAO,MAAQ,QAAQ,MAAO,CAAC;AAAA,EACnD,CAAC,QAAQ,EAAE,OAAO,MAAQ,QAAQ,MAAO,CAAC;AAAA,EAC1C,CAAC,iBAAiB,EAAE,OAAO,MAAQ,QAAQ,KAAO,CAAC;AAAA,EACnD,CAAC,UAAU,EAAE,OAAO,QAAS,QAAQ,KAAM,CAAC;AAAA,EAC5C,CAAC,SAAS,EAAE,OAAO,MAAQ,QAAQ,KAAO,CAAC;AAC7C;AAKA,SAAS,iBAAiB,OAAuB;AAC/C,UAAQ,MAAM,MAAM,GAAG,EAAE,CAAC,KAAK,OAAO,KAAK,EAAE,YAAY;AAC3D;AAKO,SAAS,oBAAoB,OAAkC;AACpE,MAAI,cAAc,KAAK,EAAG,QAAO,cAAc,KAAK;AACpD,QAAM,KAAK,iBAAiB,KAAK;AACjC,MAAI,cAAc,EAAE,EAAG,QAAO,cAAc,EAAE;AAC9C,aAAW,CAAC,SAAS,KAAK,KAAK,gBAAgB;AAC7C,QAAI,QAAQ,KAAK,EAAE,EAAG,QAAO;AAAA,EAC/B;AACA,SAAO;AACT;AAIO,SAAS,cAAc,OAAwB;AACpD,SAAO,oBAAoB,KAAK,MAAM;AACxC;AAEA,IAAM,uBAAuB,oBAAI,IAAY;AAGtC,SAAS,eAAe,MAAsB;AACnD,SAAO,KAAK,KAAK,KAAK,SAAS,CAAC;AAClC;AAKO,SAAS,aAAa,aAAqB,cAAsB,OAAuB;AAC7F,QAAM,UAAU,oBAAoB,KAAK;AACzC,MAAI,CAAC,SAAS;AACZ,QAAI,CAAC,qBAAqB,IAAI,KAAK,GAAG;AACpC,2BAAqB,IAAI,KAAK;AAC9B,cAAQ;AAAA,QACN,uCAAuC,KAAK;AAAA,MAE9C;AAAA,IACF;AACA,WAAO;AAAA,EACT;AACA,SAAQ,cAAc,MAAQ,QAAQ,QAAS,eAAe,MAAQ,QAAQ;AAChF;AAKO,IAAM,eAAN,MAAmB;AAAA,EAChB,aAAa;AAAA,EACb,cAAc;AAAA,EACd,YAAY;AAAA,EACZ;AAAA,EAER,YAAY,QAAQ,UAAU;AAC5B,SAAK,QAAQ;AAAA,EACf;AAAA;AAAA,EAGA,OAAO,aAAqB,cAA8B;AACxD,SAAK,cAAc;AACnB,SAAK,eAAe;AACpB,UAAM,OAAO,aAAa,aAAa,cAAc,KAAK,KAAK;AAC/D,SAAK,aAAa;AAClB,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,eACE,WACA,YAC6D;AAC7D,UAAM,cAAc,eAAe,SAAS;AAC5C,UAAM,eAAe,eAAe,UAAU;AAC9C,UAAM,OAAO,KAAK,OAAO,aAAa,YAAY;AAClD,WAAO,EAAE,aAAa,cAAc,KAAK;AAAA,EAC3C;AAAA,EAEA,gBAAwB;AACtB,WAAO,KAAK;AAAA,EACd;AAAA,EACA,iBAAyB;AACvB,WAAO,KAAK;AAAA,EACd;AAAA,EACA,eAAuB;AACrB,WAAO,KAAK;AAAA,EACd;AACF;AAOO,IAAM,mBAAN,MAAuB;AAAA,EACpB;AAAA,EACA;AAAA,EACA,UAAyB,CAAC;AAAA,EAClC,YAAY,QAAuB,aAAqB;AACtD,SAAK,SAAS;AACd,SAAK,cAAc;AAAA,EACrB;AAAA;AAAA,EAGA,MAAM,QACJ,MACA,mBACA,eACA,oBACA,iBACA,uBACA,yBACA,cACA,cAAc,GACd,eAAe,GACf,mBAAmB,GACG;AACtB,UAAM,QAAQ,MAAM,KAAK,SAAS;AAElC,UAAM,IAAiB;AAAA,MACrB;AAAA,MACA,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MAClC,OAAO,MAAM;AAAA,MACb,QAAQ,MAAM;AAAA,MACd,WAAW,MAAM;AAAA,MACjB,YAAY,MAAM,WAAW;AAAA,MAC7B;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,cAAc;AAAA,MACd,mBACE,0BAA0B,IAAK,wBAAwB,0BAA2B,MAAM;AAAA,IAC5F;AAEA,SAAK,QAAQ,KAAK,CAAC;AACnB,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,MAAM,WAAiC;AACrC,UAAM,CAAC,OAAO,QAAQ,WAAW,UAAU,IAAI,MAAM,QAAQ,IAAI;AAAA,MAC/D,KAAK,OAAO,SAAS,KAAK,WAAW;AAAA,MACrC,KAAK,OAAO,UAAU,KAAK,WAAW;AAAA,MACtC,KAAK,OAAO,aAAa,KAAK,WAAW;AAAA,MACzC,KAAK,OAAO,aAAa,KAAK,WAAW;AAAA,IAC3C,CAAC;AAED,WAAO;AAAA,MACL,OAAO,MAAM;AAAA,MACb,QAAQ,OAAO;AAAA,MACf,WAAW;AAAA,QACT,SAAS,UAAU,OAAO,CAAC,MAAM,EAAE,WAAW,SAAS,EAAE;AAAA,QACzD,UAAU,UAAU,OAAO,CAAC,MAAM,EAAE,WAAW,UAAU,EAAE;AAAA,QAC3D,UAAU,UAAU,OAAO,CAAC,MAAM,EAAE,WAAW,UAAU,EAAE;AAAA,MAC7D;AAAA,MACA;AAAA,MACA,YAAY;AAAA,MACZ,aAAa;AAAA,IACf;AAAA,EACF;AAAA;AAAA,EAGA,aAA4B;AAC1B,WAAO,CAAC,GAAG,KAAK,OAAO;AAAA,EACzB;AAAA;AAAA,EAGA,sBAAgC;AAC9B,WAAO,KAAK,QAAQ,IAAI,CAAC,MAAM,EAAE,iBAAiB;AAAA,EACpD;AACF;;;AC7MA,IAAM,eAA6C;AAAA,EACjD,aACE;AAAA,EACF,WACE;AAAA,EACF,YACE;AACJ;AASO,IAAM,cAAN,MAAkB;AAAA,EACf;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAER,YAAY,IAAY,QAA2B;AACjD,SAAK,KAAK;AACV,SAAK,SAAS,OAAO;AACrB,SAAK,cAAc,OAAO,eAAe;AACzC,SAAK,iBAAiB,OAAO,kBAAkB;AAAA,EACjD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,IAAI,SAA+C;AAEvD,UAAM,QAAQ,eAAe,KAAK,IAAI,CAAC;AACvC,UAAM,KAAK,OAAO,OAAO,UAAU,QAAQ,IAAI,IAAI,OAAO,kBAAkB;AAC5E,UAAM,KAAK,OAAO,MAAM,OAAO,kBAAkB;AACjD,UAAM,cAAc,MAAM,KAAK,OAAO,gBAAgB,GAAG,QAAQ,IAAI,OAAO;AAC5E,UAAM,WAAW,MAAM,KAAK,OAAO,aAAa,WAAW;AAE3D,UAAM,UAAU,IAAI,iBAAiB,KAAK,QAAQ,WAAW;AAC7D,UAAM,cAAc,IAAI,mBAAmB,QAAQ,kBAAkB;AACrE,UAAM,cAA6B,CAAC;AACpC,UAAM,sBAA2D,CAAC;AAElE,QAAI,YAAY;AAChB,QAAI,oBAAmC;AACvC,QAAI,oBAAmC;AAEvC,aAAS,OAAO,GAAG,QAAQ,QAAQ,UAAU,QAAQ;AAEnD,YAAM,QAAQ,MAAM,QAAQ,SAAS;AAGrC,YAAM,cAAc,MAAM,KAAK,kBAAkB,SAAS,OAAO,mBAAmB;AAEpF,UAAI,gBAAgB,QAAQ;AAC1B,oBAAY;AACZ,4BAAoB,OAAO;AAC3B,gBAAQ,IAAI,6BAA6B,QAAQ,IAAI,eAAe,OAAO,CAAC,EAAE;AAC9E;AAAA,MACF;AAGA,YAAM,YAAY,KAAK,IAAI;AAC3B,YAAM,WAAW,MAAM,KAAK,OAAO,KAAK,aAAa,UAAU,WAAW;AAC1E,YAAM,UAAU,KAAK,IAAI,IAAI;AAE7B,0BAAoB;AAAA,QAClB,EAAE,MAAM,QAAQ,SAAS,YAAY;AAAA,QACrC,EAAE,MAAM,aAAa,SAAS,SAAS,KAAK;AAAA,MAC9C;AAGA,YAAM,IAAI,QAAQ,CAAC,MAAM,WAAW,GAAG,GAAI,CAAC;AAG5C,YAAM,KAAK,gBAAgB,SAAS,aAAa,KAAK;AAGtD,YAAM,YAAY,MAAM,QAAQ,SAAS;AACzC,YAAM,OAAO,YAAY,OAAO,MAAM,SAAS;AAG/C,YAAM,kBAAkB,SAAS,KAAK,MAAM,WAAW,KAAK,CAAC,GAAG;AAChE,YAAM,IAAI,MAAM,QAAQ;AAAA,QACtB;AAAA,QACA;AAAA,QACA,SAAS,KAAK;AAAA,QACd;AAAA,QACA,SAAS,OAAO;AAAA,QAChB,OAAO,OAAO,KAAK,cAAc,EAAE,OAAO,OAAO,EAAE;AAAA,QACnD,QAAQ,mBAAmB;AAAA,MAC7B;AACA,kBAAY,KAAK,CAAC;AAGlB,YAAM,cAAc,OAAO,QAAQ,KAAK,cAAc,EACnD,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,IAAI,MAAM,GAAG,EAAE,EACvC,KAAK,GAAG;AACX,cAAQ;AAAA,QACN,WAAW,IAAI,KAAK,KAAK,kBAAkB,QAAQ,CAAC,CAAC,YAAO,WAAW,MAAM,UAAU,KAAM,QAAQ,CAAC,CAAC;AAAA,MACzG;AAKA,UAAI,KAAK,YAAY,sBAAsB,MAAM;AAC/C,4BAAoB;AACpB,gBAAQ,IAAI,0BAA0B,IAAI,2CAAsC;AAAA,MAClF;AAAA,IACF;AAEA,UAAM,aAAa,MAAM,QAAQ,SAAS;AAE1C,WAAO;AAAA,MACL,WAAW,QAAQ;AAAA,MACnB;AAAA,MACA;AAAA,MACA;AAAA,MACA,YAAY,YAAY;AAAA,MACxB,SAAS;AAAA,MACT;AAAA,MACA,kBAAkB,YAAY,SAAS;AAAA,MACvC,cAAc;AAAA,MACd,mBAAmB;AAAA,IACrB;AAAA,EACF;AAAA;AAAA,EAGA,MAAc,kBACZ,SACA,OACA,SACiB;AACjB,WAAO,mBAAmB,KAAK,IAAI;AAAA,MACjC;AAAA,MACA;AAAA,MACA;AAAA,MACA,gBAAgB,KAAK;AAAA,MACrB,OAAO,KAAK;AAAA,IACd,CAAC;AAAA,EACH;AAAA;AAAA,EAGA,MAAc,gBACZ,SACA,aACA,QACe;AACf,UAAM,YAAY,MAAM,KAAK,OAAO,aAAa,WAAW;AAC5D,UAAM,UAAU,UAAU,OAAO,CAAC,MAAM,EAAE,WAAW,SAAS;AAE9D,eAAW,UAAU,SAAS;AAE5B,YAAM,YAAY,QAAQ,kBAAkB,KAAK,CAAC,OAAO;AACvD,cAAM,QAAQ,OAAO,MAAM,YAAY;AACvC,eAAO,MAAM,SAAS,GAAG,QAAQ,YAAY,CAAC;AAAA,MAChD,CAAC;AAED,UAAI,WAAW;AACb,cAAM,KAAK,OAAO,aAAa,aAAa,OAAO,IAAI,UAAU,QAAQ;AACzE,gBAAQ,IAAI,iBAAiB,OAAO,KAAK,WAAM,UAAU,SAAS,MAAM,GAAG,EAAE,CAAC,EAAE;AAAA,MAClF,OAAO;AACL,cAAM,KAAK,OAAO,cAAc,aAAa,OAAO,EAAE;AACtD,gBAAQ,IAAI,iBAAiB,OAAO,KAAK,EAAE;AAAA,MAC7C;AAAA,IACF;AAAA,EACF;AACF;AAGA,SAAS,mBAAmB,SAAwB,OAA4B;AAC9E,QAAM,UAAU,QAAQ,mBAAmB,IAAI,CAAC,MAAM;AACpD,UAAM,MAAM,EAAE,MAAM,KAAK;AACzB,WAAO,GAAG,EAAE,IAAI,KAAK,MAAM,QAAQ,SAAS;AAAA,EAC9C,CAAC;AACD,QAAM,WAAW,QAAQ,OAAO,CAAC,MAAM,EAAE,SAAS,KAAK,KAAK,CAAC,EAAE,SAAS,KAAK,CAAC,EAAE;AAChF,SAAO,GAAG,QAAQ,IAAI,QAAQ,mBAAmB,MAAM,WAAM,QAAQ,KAAK,IAAI,CAAC;AACjF;AAWO,SAAS,wBACd,SACA,OACA,iBAAiB,IACT;AACR,QAAM,QAAsB,QAAQ,SAAS;AAC7C,QAAM,YAAY,QAAQ,YAAY,YAAY,QAAQ,SAAS,MAAM;AAEzE,QAAM,WACJ,QAAQ,kBAAkB,QAAQ,eAAe,SAAS,IACtD;AAAA,cAAiB,QAAQ,IAAI;AAAA,EAAiD,QAAQ,eACnF,IAAI,CAAC,MAAM,OAAO,CAAC,EAAE,EACrB;AAAA,IACC;AAAA,EACF,CAAC;AAAA;AAAA,IACH;AAEN,QAAM,aACJ,QAAQ,cAAc,QAAQ,WAAW,SAAS,IAC9C;AAAA;AAAA,EAAyH,QAAQ,WAC9H,IAAI,CAAC,MAAM,OAAO,CAAC,EAAE,EACrB,KAAK,IAAI,CAAC;AAAA,IACb;AAEN,SAAO,+BAA+B,QAAQ,IAAI,0CAA0C,SAAS;AAAA,kBACrF,QAAQ,IAAI;AAAA;AAAA;AAAA,EAG5B,aAAa,KAAK,CAAC;AAAA,EACnB,iBAAiB;AAAA,EAAqB,cAAc;AAAA,IAAO,EAAE;AAAA,WACpD,MAAM,KAAK,cAAc,MAAM,MAAM;AAAA,uBACzB,MAAM,UAAU,OAAO,cAAc,MAAM,UAAU,QAAQ,cAAc,MAAM,UAAU,QAAQ;AAAA,iBACzG,MAAM,WAAW,MAAM,MAAM,MAAM,WAAW,MAAM,GAAG,EAAE,EAAE,KAAK,IAAI,CAAC,GAAG,MAAM,WAAW,SAAS,KAAK,YAAO,EAAE;AAAA,2BACtG,mBAAmB,SAAS,KAAK,CAAC;AAAA,EAC3D,QAAQ,GAAG,UAAU;AAAA;AAAA,wDAEiC,QAAQ,IAAI;AAAA;AAAA;AAAA,8BAGtC,QAAQ,IAAI;AAAA;AAAA;AAAA;AAAA,oDAIU,QAAQ,IAAI;AAAA;AAAA;AAGhE;AAoBA,eAAsB,mBACpB,IACA,MACiB;AACjB,QAAM,EAAE,SAAS,OAAO,SAAS,iBAAiB,IAAI,QAAQ,oBAAoB,IAAI;AAEtF,QAAM,eACJ,QAAQ,SAAS,IACb,QAAQ,QAAQ,SAAS,CAAC,EAAG,QAAQ,MAAM,GAAG,GAAI,IAClD;AAEN,QAAM,gBAAgB,QACnB,MAAM,EAAE,EACR,IAAI,CAAC,MAAM,GAAG,EAAE,IAAI,KAAK,EAAE,QAAQ,MAAM,GAAG,GAAG,CAAC,EAAE,EAClD,KAAK,MAAM;AAEd,QAAM,OAAO,MAAM,GAAG,KAAK;AAAA,IACzB;AAAA,IACA,UAAU;AAAA,MACR,EAAE,MAAM,UAAU,SAAS,wBAAwB,SAAS,OAAO,cAAc,EAAE;AAAA,MACnF;AAAA,QACE,MAAM;AAAA,QACN,SAAS,gBACL;AAAA,EAAyB,aAAa;AAAA;AAAA;AAAA,EAAqC,YAAY,KACvF;AAAA,MACN;AAAA,IACF;AAAA,IACA,aAAa;AAAA,IACb,WAAW;AAAA,EACb,CAAC;AAED,QAAM,UACH,KAA4D,UAAU,CAAC,GAAG,SAAS,WACpF;AAEF,SAAO,QAAQ,KAAK;AACtB;;;ACnKA,IAAM,uBAAsD;AAAA,EAC1D,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,YAAY;AACd;AAEO,IAAM,kCAAN,MAAyE;AAAA,EAC7D,eAAe,oBAAI,IAAgC;AAAA,EAEpE,MAAM,KAAK,YAA+C;AACxD,SAAK,aAAa,IAAI,WAAW,IAAI,gBAAgB,UAAU,CAAC;AAAA,EAClE;AAAA,EAEA,MAAM,IAAI,IAAgD;AACxD,UAAM,aAAa,KAAK,aAAa,IAAI,EAAE;AAC3C,WAAO,aAAa,gBAAgB,UAAU,IAAI;AAAA,EACpD;AAAA,EAEA,MAAM,KAAK,SAAmC,CAAC,GAAkC;AAC/E,WAAO,CAAC,GAAG,KAAK,aAAa,OAAO,CAAC,EAClC,OAAO,CAAC,eAAe,cAAc,YAAY,MAAM,CAAC,EACxD,IAAI,eAAe;AAAA,EACxB;AAAA,EAEA,MAAM,cAAc,IAAY,SAAuD;AACrF,UAAM,aAAa,KAAK,aAAa,IAAI,EAAE;AAC3C,QAAI,CAAC;AACH,YAAM,IAAI,MAAM,8DAA8D,EAAE,GAAG;AACrF,UAAM,OAAO,gBAAgB;AAAA,MAC3B,GAAG;AAAA,MACH,UAAU,CAAC,GAAG,WAAW,UAAU,OAAO;AAAA,MAC1C,WAAW,QAAQ;AAAA,IACrB,CAAC;AACD,SAAK,aAAa,IAAI,IAAI,IAAI;AAC9B,WAAO,gBAAgB,IAAI;AAAA,EAC7B;AAAA,EAEA,MAAM,YACJ,IACA,OACA,WAC6B;AAC7B,UAAM,aAAa,KAAK,aAAa,IAAI,EAAE;AAC3C,QAAI,CAAC;AACH,YAAM,IAAI,MAAM,4DAA4D,EAAE,GAAG;AACnF,UAAM,WAAW,YACb,WAAW,SAAS;AAAA,MAAI,CAAC,YACvB,QAAQ,OAAO,YACX,EAAE,GAAG,SAAS,UAAU,CAAC,GAAI,QAAQ,YAAY,CAAC,GAAI,KAAK,EAAE,IAC7D;AAAA,IACN,IACA,WAAW;AACf,UAAM,OAAO,gBAAgB;AAAA,MAC3B,GAAG;AAAA,MACH;AAAA,MACA,QAAQ,YAAY,WAAW,SAAS,CAAC,GAAG,WAAW,QAAQ,KAAK;AAAA,MACpE,WAAW,MAAM;AAAA,IACnB,CAAC;AACD,SAAK,aAAa,IAAI,IAAI,IAAI;AAC9B,WAAO,gBAAgB,IAAI;AAAA,EAC7B;AACF;AAEO,IAAM,oCAAN,MAA2E;AAAA,EAC/D;AAAA,EACA,SAAS,IAAI,gCAAgC;AAAA,EACtD,SAAS;AAAA,EAEjB,YAAY,SAA0B;AACpC,SAAK,MAAM,QAAQ;AAAA,EACrB;AAAA,EAEA,MAAM,KAAK,YAA+C;AACxD,UAAM,KAAK,KAAK;AAChB,UAAM,KAAK,OAAO,KAAK,UAAU;AACjC,UAAM,KAAK,OAAO,EAAE,IAAI,QAAQ,WAAW,CAAC;AAAA,EAC9C;AAAA,EAEA,MAAM,IAAI,IAAgD;AACxD,UAAM,KAAK,KAAK;AAChB,WAAO,KAAK,OAAO,IAAI,EAAE;AAAA,EAC3B;AAAA,EAEA,MAAM,KAAK,SAAmC,CAAC,GAAkC;AAC/E,UAAM,KAAK,KAAK;AAChB,WAAO,KAAK,OAAO,KAAK,MAAM;AAAA,EAChC;AAAA,EAEA,MAAM,cAAc,IAAY,SAAuD;AACrF,UAAM,KAAK,KAAK;AAChB,UAAM,OAAO,MAAM,KAAK,OAAO,cAAc,IAAI,OAAO;AACxD,UAAM,KAAK,OAAO,EAAE,IAAI,iBAAiB,IAAI,QAAQ,CAAC;AACtD,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,YACJ,IACA,OACA,WAC6B;AAC7B,UAAM,KAAK,KAAK;AAChB,UAAM,OAAO,MAAM,KAAK,OAAO,YAAY,IAAI,OAAO,SAAS;AAC/D,UAAM,KAAK,OAAO,EAAE,IAAI,eAAe,IAAI,OAAO,UAAU,CAAC;AAC7D,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,OAAO,QAAgC;AACnD,UAAM,EAAE,YAAY,MAAM,IAAI,MAAM,OAAO,aAAkB;AAC7D,UAAM,EAAE,MAAAC,MAAK,IAAI,MAAM,OAAO,MAAW;AACzC,UAAM,MAAM,KAAK,KAAK,EAAE,WAAW,KAAK,CAAC;AACzC,UAAM;AAAA,MACJA,MAAK,KAAK,KAAK,8BAA8B;AAAA,MAC7C,GAAG,KAAK,UAAU,MAAM,CAAC;AAAA;AAAA,MACzB;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAc,OAAsB;AAClC,QAAI,KAAK,OAAQ;AACjB,UAAM,EAAE,SAAS,IAAI,MAAM,OAAO,aAAkB;AACpD,UAAM,EAAE,MAAAA,MAAK,IAAI,MAAM,OAAO,MAAW;AACzC,UAAM,OAAOA,MAAK,KAAK,KAAK,8BAA8B;AAC1D,QAAI;AACF,YAAM,MAAM,MAAM,SAAS,MAAM,MAAM;AACvC,iBAAW,QAAQ,IAAI,MAAM,IAAI,GAAG;AAClC,YAAI,CAAC,KAAK,KAAK,EAAG;AAClB,YAAI;AACF,gBAAM,SAAS,KAAK,MAAM,IAAI;AAI9B,cAAI,OAAO,OAAO,OAAQ,OAAM,KAAK,OAAO,KAAK,OAAO,UAAU;AAClE,cAAI,OAAO,OAAO;AAChB,kBAAM,KAAK,OAAO,cAAc,OAAO,IAAI,OAAO,OAAO;AAC3D,cAAI,OAAO,OAAO;AAChB,kBAAM,KAAK,OAAO,YAAY,OAAO,IAAI,OAAO,OAAO,OAAO,SAAS;AAAA,QAC3E,QAAQ;AAAA,QAER;AAAA,MACF;AAAA,IACF,QAAQ;AAAA,IAER;AACA,SAAK,SAAS;AAAA,EAChB;AACF;AAEO,SAAS,yBAAyB,OAYlB;AACrB,QAAM,YAAY,MAAM,cAAa,oBAAI,KAAK,GAAE,YAAY;AAC5D,QAAM,KACJ,MAAM,MACN,MAAM,WAAW,GAAG,MAAM,aAAa,EAAE,IAAI,MAAM,cAAc,EAAE,IAAI,MAAM,KAAK,MAAM,IAAI,SAAS,EAAE,EAAE,SAAS,EAAE,CAAC;AACvH,SAAO;AAAA,IACL;AAAA,IACA,WAAW,MAAM;AAAA,IACjB,YAAY,MAAM;AAAA,IAClB,MAAM,MAAM;AAAA,IACZ,UAAU,MAAM,YAAY,CAAC;AAAA,IAC7B,QAAQ,MAAM,UAAU,CAAC;AAAA,IACzB,SAAS,MAAM;AAAA,IACf,OAAO,MAAM;AAAA,IACb,MAAM,MAAM;AAAA,IACZ;AAAA,IACA,UAAU,MAAM;AAAA,EAClB;AACF;AAEO,SAAS,oBACd,YACA,SAA8B,CAAC,GACjB;AACd,QAAM,QAAQ,EAAE,GAAG,sBAAsB,GAAG,OAAO;AACnD,QAAM,QAAQ,MAAM,WAAW,MAAM,SAAS,MAAM,UAAU,MAAM;AACpE,MAAI,SAAS,EAAG,OAAM,IAAI,MAAM,4DAA4D;AAC5F,QAAM,SACJ;AAAA,IACE,GAAG,WAAW,aAAa,EAAE,IAAI,WAAW,cAAc,EAAE,IAAI,WAAW,EAAE,IAAI,WAAW,KAAK,MAAM;AAAA,EACzG,IAAI;AACN,MAAI,SAAS,MAAM,SAAU,QAAO;AACpC,MAAI,SAAS,MAAM,WAAW,MAAM,OAAQ,QAAO;AACnD,MAAI,SAAS,MAAM,WAAW,MAAM,SAAS,MAAM,QAAS,QAAO;AACnE,SAAO;AACT;AAEO,SAAS,0BACd,YACA,QACoB;AACpB,SAAO;AAAA,IACL,GAAG;AAAA,IACH,OAAO,WAAW,SAAS,oBAAoB,YAAY,MAAM;AAAA,EACnE;AACF;AAEO,SAAS,oCACd,YACiB;AACjB,QAAM,YAAY,0BAA0B,UAAU;AACtD,SAAO;AAAA,IACL,IAAI,UAAU,cAAc,UAAU;AAAA,IACtC,OAAO,UAAU;AAAA,IACjB,SAAS;AAAA,IACT,MAAM;AAAA,MACJ,GAAI,UAAU,YAAY,EAAE,WAAW,UAAU,UAAU,IAAI,CAAC;AAAA,MAChE,GAAI,UAAU,QAAQ,CAAC;AAAA,MACvB,QAAQ;AAAA,IACV;AAAA,EACF;AACF;AAEO,SAAS,uCACd,cACmB;AACnB,SAAO,aAAa,IAAI,mCAAmC;AAC7D;AAEO,SAAS,iCACd,YACsB;AACtB,QAAM,SAAS,UAAU,UAAU;AACnC,SAAO;AAAA,IACL,YAAY,WAAW,cAAc,WAAW;AAAA,IAChD,cAAc,WAAW;AAAA,IACzB,YAAY,CAAC,GAAG,IAAI,IAAI,OAAO,IAAI,CAAC,UAAU,MAAM,IAAI,CAAC,CAAC;AAAA,IAC1D,OAAO,WAAW,SAAS,SAAS,gBAAgB,MAAM;AAAA,IAC1D,UAAU;AAAA,MACR,WAAW,WAAW;AAAA,MACtB,OAAO,WAAW;AAAA,MAClB,QAAQ,WAAW,KAAK;AAAA,MACxB,UAAU,WAAW,SAAS;AAAA,MAC9B,SAAS,WAAW;AAAA,MACpB;AAAA,IACF;AAAA,EACF;AACF;AAEO,SAAS,oCACd,cACwB;AACxB,SAAO,aAAa,IAAI,gCAAgC;AAC1D;AAEA,eAAsB,yBACpB,YACA,SAC+B;AAC/B,MAAI;AACF,UAAM,SAAS,MAAM,QAAQ,OAAO,UAAU;AAC9C,WAAO;AAAA,MACL,cAAc,WAAW;AAAA,MACzB,GAAG;AAAA,IACL;AAAA,EACF,SAAS,KAAK;AACZ,UAAM,aAAY,oBAAI,KAAK,GAAE,YAAY;AACzC,UAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC/D,WAAO;AAAA,MACL,cAAc,WAAW;AAAA,MACzB,MAAM;AAAA,MACN,QAAQ;AAAA,QACN;AAAA,UACE,QAAQ;AAAA,UACR,MAAM;AAAA,UACN,OAAO;AAAA,UACP,QAAQ;AAAA,UACR,UAAU;AAAA,UACV;AAAA,QACF;AAAA,MACF;AAAA,MACA,SAAS;AAAA,QACP,SAAS;AAAA,QACT,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,YAAY;AAAA,MACd;AAAA,MACA,UAAU,EAAE,aAAa,KAAK;AAAA,IAChC;AAAA,EACF;AACF;AAEA,eAAsB,2BACpB,cACA,SACiC;AACjC,QAAM,UAAkC,CAAC;AACzC,aAAW,cAAc,cAAc;AACrC,YAAQ,KAAK,MAAM,yBAAyB,YAAY,OAAO,CAAC;AAAA,EAClE;AACA,SAAO;AACT;AAEO,SAAS,0BACd,cACA,UAAmC,CAAC,GACX;AACzB,QAAM,aAAa,QAAQ,cAAc;AACzC,QAAM,UAAmC,CAAC;AAC1C,aAAW,cAAc,cAAc;AACrC,eAAW,SAAS,UAAU,UAAU,GAAG;AACzC,YAAM,cAAc,qBAAqB,YAAY,KAAK;AAC1D,UAAI,CAAC,YAAa;AAClB,cAAQ,KAAK;AAAA,QACX;AAAA,QACA,WAAW,MAAM,UAAU,GAAG,MAAM,IAAI,eAAe,MAAM,MAAM;AAAA,QACnE,QAAQ,eAAe,KAAK;AAAA,QAC5B,oBAAoB,WAAW;AAAA,QAC/B,eAAe,MAAM;AAAA,QACrB,UAAU,MAAM;AAAA,MAClB,CAAC;AAAA,IACH;AAAA,EACF;AAEA,QAAM,gBAAgB,oBAAI,IAAmC;AAC7D,aAAW,SAAS,SAAS;AAC3B,UAAM,MAAM,MAAM,YAAY,YAAY,EAAE,QAAQ,QAAQ,GAAG,EAAE,KAAK;AACtE,UAAM,WAAW,cAAc,IAAI,GAAG;AACtC,QAAI,CAAC,YAAY,MAAM,SAAS,SAAS,OAAQ,eAAc,IAAI,KAAK,KAAK;AAAA,EAC/E;AACA,SAAO,CAAC,GAAG,cAAc,OAAO,CAAC,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,UAAU;AAC5F;AAEO,SAAS,+BAA+B,SAA0C;AACvF,QAAM,QAAQ,CAAC,uBAAuB,EAAE;AACxC,aAAW,SAAS,SAAS;AAC3B,UAAM,KAAK,KAAK,MAAM,WAAW,EAAE;AACnC,UAAM,KAAK,gBAAgB,MAAM,SAAS,EAAE;AAC5C,UAAM,KAAK,aAAa,MAAM,kBAAkB,EAAE;AAClD,UAAM,KAAK,EAAE;AAAA,EACf;AACA,SAAO,GAAG,MAAM,KAAK,IAAI,EAAE,KAAK,CAAC;AAAA;AACnC;AAEO,SAAS,mCAAmC,cAA4C;AAC7F,SAAO,GAAG,aACP,MAAM,EACN,KAAK,CAAC,GAAG,MAAM,EAAE,GAAG,cAAc,EAAE,EAAE,CAAC,EACvC,IAAI,CAAC,eAAe,KAAK,UAAUC,cAAa,UAAU,CAAC,CAAC,EAC5D,KAAK,IAAI,CAAC;AAAA;AACf;AAEO,SAAS,+BAA+B,OAAqC;AAClF,QAAM,eAAqC,CAAC;AAC5C,aAAW,QAAQ,MAAM,MAAM,IAAI,GAAG;AACpC,QAAI,CAAC,KAAK,KAAK,EAAG;AAClB,iBAAa,KAAK,KAAK,MAAM,IAAI,CAAuB;AAAA,EAC1D;AACA,SAAO;AACT;AAEO,SAAS,+BACd,KACA,UASI,CAAC,GACe;AACpB,QAAM,YAAY,QAAQ,cAAa,oBAAI,KAAK,GAAE,YAAY;AAC9D,QAAM,eACJ,IAAI,SAAS,cAAc,WAAW,GAAG,IAAI,MAAM,IAAI,SAAS,EAAE,EAAE,SAAS,EAAE,CAAC;AAClF,SAAO,yBAAyB;AAAA,IAC9B,IAAI;AAAA,IACJ,WAAW,QAAQ;AAAA,IACnB,YAAY,QAAQ;AAAA,IACpB,MAAM,EAAE,QAAQ,IAAI,OAAO;AAAA,IAC3B;AAAA,IACA,UAAU,IAAI,MAAM,IAAI,CAAC,UAAU;AAAA,MACjC,IAAI,GAAG,YAAY,SAAS,KAAK,KAAK;AAAA,MACtC,WAAW,KAAK;AAAA,MAChB,cAAc,QAAQ,gBAAgB;AAAA,MACtC,UAAU,QAAQ,mBAAmB,IAAI,KAAK,KAAK,eAAe,UAAU,KAAK;AAAA,MACjF,gBAAgB,QAAQ,yBAAyB,IAAI;AAAA,MACrD,OAAO,KAAK;AAAA,MACZ,WAAW,KAAK;AAAA,MAChB,UAAU;AAAA,QACR,UAAU,KAAK;AAAA,QACf,eAAe,KAAK;AAAA,MACtB;AAAA,IACF,EAAE;AAAA,IACF,QAAQ;AAAA,MACN;AAAA,QACE,QAAQ;AAAA,QACR,MAAM,IAAI,OAAO,YAAY;AAAA,QAC7B,OAAO,IAAI;AAAA,QACX,QAAQ,IAAI;AAAA,QACZ,UAAU,IAAI,OAAO,SAAS;AAAA,QAC9B;AAAA,MACF;AAAA,IACF;AAAA,IACA,SAAS;AAAA,MACP,SAAS,IAAI;AAAA,MACb,OAAO,IAAI;AAAA,MACX,SAAS,IAAI;AAAA,MACb,QAAQ,IAAI;AAAA,MACZ,YAAY;AAAA,MACZ,UAAU;AAAA,QACR,WAAW,IAAI;AAAA,QACf,cAAc,IAAI;AAAA,MACpB;AAAA,IACF;AAAA,EACF,CAAC;AACH;AAEA,SAAS,UAAU,YAAiD;AAClE,QAAM,SAAS;AAAA,IACb,GAAG,WAAW;AAAA,IACd,GAAG,WAAW,SAAS,QAAQ,CAAC,YAAY,QAAQ,YAAY,CAAC,CAAC;AAAA,EACpE;AACA,QAAM,OAAO,oBAAI,IAAY;AAC7B,SAAO,OAAO,OAAO,CAAC,UAAU;AAC9B,UAAM,MACJ,MAAM,MAAM,GAAG,MAAM,MAAM,IAAI,MAAM,IAAI,IAAI,MAAM,SAAS,IAAI,KAAK,UAAU,MAAM,KAAK,CAAC;AAC7F,QAAI,KAAK,IAAI,GAAG,EAAG,QAAO;AAC1B,SAAK,IAAI,GAAG;AACZ,WAAO;AAAA,EACT,CAAC;AACH;AAEA,SAAS,gBAAgB,QAA6C;AACpE,MAAI,CAAC,OAAO,OAAQ,QAAO;AAC3B,QAAM,SAAS,OACZ,IAAI,CAAC,UAAU;AACd,QAAI,MAAM,SAAS,aAAa,MAAM,SAAS,SAAU,QAAO;AAChE,QAAI,MAAM,SAAS,YAAY,MAAM,SAAS,eAAgB,QAAO;AACrE,QAAI,MAAM,SAAS,UAAU,OAAO,MAAM,UAAU;AAClD,aAAO,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,MAAM,KAAK,CAAC;AAC7C,WAAO;AAAA,EACT,CAAC,EACA,OAAO,CAAC,UAA2B,OAAO,UAAU,QAAQ;AAC/D,MAAI,CAAC,OAAO,OAAQ,QAAO;AAC3B,SAAO,KAAK,MAAO,OAAO,OAAO,CAACC,MAAK,UAAUA,OAAM,OAAO,CAAC,IAAI,OAAO,SAAU,GAAI,IAAI;AAC9F;AAEA,SAAS,qBACP,YACA,OACoB;AACpB,MAAI,MAAM,SAAS,YAAY,MAAM;AACnC,WAAO,uBAAuB,QAAQ,WAAW,KAAK,QAAQ,EAAE,CAAC,WAAW,MAAM,MAAM;AAC1F,MAAI,MAAM,SAAS,sBAAsB,MAAM;AAC7C,WAAO,oCAAoC,MAAM,MAAM;AACzD,MAAI,MAAM,SAAS,YAAY,MAAM;AACnC,WAAO,gCAAgC,QAAQ,WAAW,KAAK,QAAQ,EAAE,CAAC,cAAc,MAAM,MAAM;AACtG,MAAI,MAAM,SAAS,aAAa,MAAM;AACpC,WAAO,oCAAoC,QAAQ,WAAW,KAAK,QAAQ,EAAE,CAAC,MAAM,MAAM,MAAM;AAClG,MAAI,MAAM,SAAS,aAAa,MAAM,OAAQ,QAAO,MAAM;AAC3D,SAAO;AACT;AAEA,SAAS,eAAe,OAA8B;AACpD,QAAM,WACJ,MAAM,aAAa,aACf,IACA,MAAM,aAAa,UACjB,IACA,MAAM,aAAa,YACjB,IACA;AACV,QAAM,SACJ,MAAM,WAAW,SACb,IACA,MAAM,WAAW,YAAY,MAAM,WAAW,gBAC5C,IACA;AACR,SAAO,WAAW;AACpB;AAEA,SAAS,cAAc,YAAgC,QAA2C;AAChG,MAAI,OAAO,aAAa,WAAW,cAAc,OAAO,UAAW,QAAO;AAC1E,MAAI,OAAO,cAAc,WAAW,eAAe,OAAO,WAAY,QAAO;AAC7E,MAAI,OAAO,SAAS,WAAW,UAAU,OAAO,MAAO,QAAO;AAC9D,MAAI,OAAO,KAAK;AACd,UAAM,CAAC,KAAK,KAAK,IAAI,OAAO;AAC5B,QAAI,WAAW,OAAO,GAAG,MAAM,MAAO,QAAO;AAAA,EAC/C;AACA,SAAO;AACT;AAEA,SAAS,gBAAgB,YAAoD;AAC3E,SAAO,KAAK,MAAM,KAAK,UAAU,UAAU,CAAC;AAC9C;AAEA,SAAS,QAAQ,OAAe,KAAqB;AACnD,QAAM,aAAa,MAAM,QAAQ,QAAQ,GAAG,EAAE,KAAK;AACnD,SAAO,WAAW,SAAS,MAAM,GAAG,WAAW,MAAM,GAAG,GAAG,EAAE,KAAK,CAAC,QAAQ;AAC7E;AAEA,SAAS,WAAW,OAAuB;AACzC,MAAI,OAAO;AACX,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK,GAAG;AACxC,YAAQ,MAAM,WAAW,CAAC;AAC1B,WAAO,KAAK,KAAK,MAAM,QAAQ;AAAA,EACjC;AACA,SAAO,SAAS;AAClB;AAEA,SAASD,cAAa,OAAyB;AAC7C,MAAI,UAAU,QAAQ,OAAO,UAAU,SAAU,QAAO;AACxD,MAAI,MAAM,QAAQ,KAAK,EAAG,QAAO,MAAM,IAAIA,aAAY;AACvD,QAAM,MAA+B,CAAC;AACtC,aAAW,OAAO,OAAO,KAAK,KAAgC,EAAE,KAAK,GAAG;AACtE,QAAI,GAAG,IAAIA,cAAc,MAAkC,GAAG,CAAC;AAAA,EACjE;AACA,SAAO;AACT;;;AC/lBO,IAAM,qBAAN,cAAiC,eAAe;AAAA,EACrD,YACE,SACgB,QAChB;AACA,UAAM,qBAAqB,OAAO;AAFlB;AAGhB,SAAK,OAAO;AAAA,EACd;AAAA,EAJkB;AAKpB;AAEA,SAAS,WAAW,KAAqB;AACvC,SAAO,IAAI,QAAQ,QAAQ,EAAE;AAC/B;AAOO,SAAS,oBACdE,QACA,OACA,OAAmC,CAAC,GACf;AACrB,QAAM,cAAyC,CAAC;AAEhD,MAAIA,OAAM,SAAS,MAAM,MAAM;AAC7B,gBAAY,KAAK,EAAE,OAAO,QAAQ,OAAOA,OAAM,MAAM,OAAO,MAAM,KAAK,CAAC;AAAA,EAC1E;AACA,MAAI,WAAWA,OAAM,OAAO,MAAM,WAAW,MAAM,OAAO,GAAG;AAC3D,gBAAY,KAAK,EAAE,OAAO,WAAW,OAAOA,OAAM,SAAS,OAAO,MAAM,QAAQ,CAAC;AAAA,EACnF;AACA,MAAIA,OAAM,UAAU,MAAM,OAAO;AAC/B,gBAAY,KAAK,EAAE,OAAO,SAAS,OAAOA,OAAM,OAAO,OAAO,MAAM,MAAM,CAAC;AAAA,EAC7E;AAEA,MAAIA,OAAM,aAAa,MAAM,UAAU;AACrC,gBAAY,KAAK,EAAE,OAAO,YAAY,OAAOA,OAAM,UAAU,OAAO,MAAM,SAAS,CAAC;AAAA,EACtF;AAEA,QAAM,cAAc,QAAQA,OAAM,MAAM;AACxC,QAAM,cAAc,QAAQ,MAAM,MAAM;AACxC,MAAI,gBAAgB,aAAa;AAC/B,gBAAY,KAAK;AAAA,MACf,OAAO;AAAA,MACP,OAAO,cAAc,QAAQ;AAAA,MAC7B,OAAO,cAAc,QAAQ;AAAA,IAC/B,CAAC;AAAA,EACH;AAEA,QAAM,WAAW,KAAK,SAAS,cAAc,YAAY,OAAO,CAAC,MAAM,EAAE,UAAU,OAAO;AAC1F,QAAM,KAAK,SAAS,WAAW;AAC/B,QAAM,SAA8B,EAAE,IAAI,YAAY;AAEtD,MAAI,CAAC,IAAI;AACP,UAAM,aAAa,KAAK,cAAc;AACtC,UAAM,aAAa,KAAK,cAAc;AACtC,UAAM,SAAS,SACZ,IAAI,CAAC,MAAM,GAAG,EAAE,KAAK,KAAK,UAAU,IAAI,EAAE,SAAS,QAAG,OAAO,UAAU,IAAI,EAAE,SAAS,QAAG,EAAE,EAC3F,KAAK,IAAI;AACZ,UAAM,IAAI;AAAA,MACR,mBAAmB,UAAU,QAAQ,UAAU,iGACW,MAAM;AAAA,MAChE;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;;;ACxGA,IAAM,kBAA+C;AAAA,EACnD,WAAW;AAAA,EACX,QAAQ;AAAA,EACR,gBAAgB;AAAA,EAChB,QAAQ;AAAA,EACR,iBAAiB;AAAA,EACjB,MAAM;AAAA,EACN,cAAc;AAAA,EACd,SAAS;AAAA,EACT,WAAW;AAAA,EACX,UAAU;AAAA,EACV,KAAK;AAAA,EACL,MAAM;AAAA,EACN,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,UAAU;AAAA,EACV,YAAY;AAAA,EACZ,MAAM;AAAA,EACN,aAAa;AAAA,EACb,OAAO;AAAA,EACP,SAAS;AAAA,EACT,KAAK;AAAA,EACL,QAAQ;AAAA,EACR,KAAK;AACP;AAGA,IAAM,gBAA8C;AAAA,EAClD,CAAC,WAAW,WAAW;AAAA,EACvB,CAAC,0DAA0D,QAAQ;AAAA,EACnE,CAAC,4BAA4B,QAAQ;AAAA,EACrC,CAAC,UAAU,MAAM;AAAA,EACjB,CAAC,oCAAoC,SAAS;AAAA,EAC9C,CAAC,aAAa,UAAU;AAAA,EACxB,CAAC,SAAS,KAAK;AAAA,EACf,CAAC,SAAS,MAAM;AAAA,EAChB,CAAC,oBAAoB,QAAQ;AAAA,EAC7B,CAAC,qBAAqB,QAAQ;AAAA,EAC9B,CAAC,sBAAsB,UAAU;AAAA,EACjC,CAAC,4BAA4B,OAAO;AACtC;AAQO,SAAS,YAAY,SAA8B;AACxD,QAAM,KAAK,QAAQ,KAAK,EAAE,MAAM,GAAG,EAAE,CAAC,EAAG,YAAY;AACrD,QAAM,QAAQ,GAAG,QAAQ,GAAG;AAC5B,MAAI,QAAQ,GAAG;AACb,UAAM,SAAS,GAAG,MAAM,GAAG,KAAK;AAChC,UAAM,SAAS,gBAAgB,MAAM;AACrC,QAAI,OAAQ,QAAO;AAAA,EACrB;AACA,aAAW,CAAC,SAAS,MAAM,KAAK,eAAe;AAC7C,QAAI,QAAQ,KAAK,EAAE,EAAG,QAAO;AAAA,EAC/B;AACA,SAAO;AACT;AAWO,IAAM,mBAAN,cAA+B,MAAM;AAAA,EAC1C,YACE,SACgB,UACA,QAChB;AACA,UAAM,OAAO;AAHG;AACA;AAGhB,SAAK,OAAO;AAAA,EACd;AAAA,EALkB;AAAA,EACA;AAKpB;AAOO,SAAS,kBACd,QACA,OAAiC,CAAC,GACnB;AACf,QAAM,cAAc,KAAK,eAAe;AACxC,QAAM,WAAW,oBAAI,IAAiB;AACtC,aAAW,KAAK,QAAQ;AACtB,UAAM,IAAI,YAAY,CAAC;AACvB,QAAI,MAAM,aAAa,CAAC,KAAK,aAAc;AAC3C,aAAS,IAAI,CAAC;AAAA,EAChB;AACA,QAAM,OAAO,CAAC,GAAG,QAAQ,EAAE,KAAK;AAChC,MAAI,KAAK,SAAS,aAAa;AAC7B,UAAM,IAAI;AAAA,MACR,wBAAwB,KAAK,MAAM,kBAAkB,KAAK,WAAW,IAAI,MAAM,KAAK,KAC9E,KAAK,KAAK,IAAI,KAAK,MAAM,SAAS,WAAW;AAAA,MAEnD;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;;;AClIO,SAAS,wBAAwB,QAAyB;AAC/D,SAAO,OACL,IACA,EAAE,UAAU,MAAM,MACQ;AAC1B,UAAM,eAAe,MAClB;AAAA,MACC,CAAC,GAAG,MACF,QAAQ,IAAI,CAAC;AAAA,QAAY,EAAE,WAAW;AAAA,SAAY,EAAE,cAAc,MAAM,GAAG,GAAI,CAAC;AAAA,IACpF,EACC,KAAK,aAAa;AAErB,UAAM,OAAO,MAAM,GAAG,KAAK;AAAA,MACzB,OAAO;AAAA,MACP,UAAU;AAAA,QACR;AAAA,UACE,MAAM;AAAA,UACN,SAAS,oBAAoB,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QASrC;AAAA,QACA;AAAA,UACE,MAAM;AAAA,UACN,SAAS,YAAY,SAAS,OAAO,KAAK,SAAS,KAAK;AAAA,YAAgB,SAAS,MAAM;AAAA;AAAA,EAAO,YAAY;AAAA,QAC5G;AAAA,MACF;AAAA,MACA,aAAa;AAAA,MACb,WAAW;AAAA,IACb,CAAC;AAED,WAAO,mBAAmB,iBAAiB,IAAI;AAAA,EACjD;AACF;AAKO,IAAM,qBAA8B,OAAO,IAAI,EAAE,UAAU,UAAU,MAAM;AAChF,QAAM,aAAa,UAAU;AAC7B,MAAI,WAAW,WAAW,GAAG;AAC3B,WAAO;AAAA,MACL;AAAA,QACE,WAAW;AAAA,QACX,WAAW;AAAA,QACX,OAAO;AAAA,QACP,WAAW;AAAA,MACb;AAAA,IACF;AAAA,EACF;AAEA,QAAM,WAAW,WACd;AAAA,IACC,CAAC,GAAG,MACF,SAAS,IAAI,CAAC,KAAK,EAAE,QAAQ;AAAA,QAAa,EAAE,QAAQ;AAAA,EAAK,EAAE,KAAK,MAAM,GAAG,GAAI,CAAC;AAAA;AAAA,EAClF,EACC,KAAK,MAAM;AAEd,QAAM,OAAO,MAAM,GAAG,KAAK;AAAA,IACzB,OAAO;AAAA,IACP,UAAU;AAAA,MACR;AAAA,QACE,MAAM;AAAA,QACN,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAQX;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,SAAS,SAAS,SAAS,MAAM;AAAA;AAAA,EAAO,QAAQ;AAAA,MAClD;AAAA,IACF;AAAA,IACA,aAAa;AAAA,IACb,WAAW;AAAA,EACb,CAAC;AAED,SAAO,mBAAmB,kBAAkB,IAAI;AAClD;AAKO,IAAM,iBAA0B,OAAO,IAAI,EAAE,UAAU,MAAM,MAAM;AACxE,MAAI,MAAM,SAAS,GAAG;AAIpB,WAAO,CAAC;AAAA,EACV;AAEA,QAAM,eAAe,MAClB;AAAA,IACC,CAAC,GAAG,MACF,QAAQ,IAAI,CAAC;AAAA,QAAY,EAAE,WAAW;AAAA,SAAY,EAAE,cAAc,MAAM,YAAY,EAAE,cAAc,MAAM,GAAG,IAAI,CAAC;AAAA,EACtH,EACC,KAAK,aAAa;AAErB,QAAM,OAAO,MAAM,GAAG,KAAK;AAAA,IACzB,OAAO;AAAA,IACP,UAAU;AAAA,MACR;AAAA,QACE,MAAM;AAAA,QACN,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAQX;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,SAAS,aAAa,SAAS,MAAM;AAAA;AAAA,EAAO,YAAY;AAAA,MAC1D;AAAA,IACF;AAAA,IACA,aAAa;AAAA,IACb,WAAW;AAAA,EACb,CAAC;AAED,SAAO,mBAAmB,aAAa,IAAI;AAC7C;AAKO,IAAM,mBAA4B,OAAO,IAAI,EAAE,UAAU,MAAM,MAAM;AAC1E,QAAM,eAAe,MAClB;AAAA,IACC,CAAC,GAAG,MAAM,QAAQ,IAAI,CAAC;AAAA,QAAY,EAAE,WAAW;AAAA,SAAY,EAAE,cAAc,MAAM,GAAG,IAAI,CAAC;AAAA,EAC5F,EACC,KAAK,aAAa;AAErB,QAAM,OAAO,MAAM,GAAG,KAAK;AAAA,IACzB,OAAO;AAAA,IACP,UAAU;AAAA,MACR;AAAA,QACE,MAAM;AAAA,QACN,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MASX;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,SAAS,YAAY,SAAS,OAAO;AAAA,YAAe,SAAS,MAAM;AAAA;AAAA,EAAO,YAAY;AAAA,MACxF;AAAA,IACF;AAAA,IACA,aAAa;AAAA,IACb,WAAW;AAAA,EACb,CAAC;AAED,SAAO,mBAAmB,eAAe,IAAI;AAC/C;AAKO,SAAS,kBACd,MACA,cACA,MACS;AACT,SAAO,OAAO,IAAI,EAAE,UAAU,MAAM,MAAM;AACxC,UAAM,eAAe,MAClB;AAAA,MACC,CAAC,GAAG,MACF,QAAQ,IAAI,CAAC;AAAA,QAAY,EAAE,WAAW;AAAA,SAAY,EAAE,cAAc,MAAM,GAAG,GAAI,CAAC;AAAA,IACpF,EACC,KAAK,aAAa;AAErB,UAAM,OAAO,MAAM,GAAG,KAAK;AAAA,MACzB,OAAO,MAAM,SAAS;AAAA,MACtB,UAAU;AAAA,QACR;AAAA,UACE,MAAM;AAAA,UACN,SAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAM;AAAA,UACN,SAAS,YAAY,SAAS,OAAO,KAAK,SAAS,KAAK;AAAA,YAAgB,SAAS,MAAM;AAAA;AAAA,EAAO,YAAY;AAAA,QAC5G;AAAA,MACF;AAAA,MACA,aAAa,MAAM,eAAe;AAAA,MAClC,WAAW,MAAM,aAAa;AAAA,IAChC,CAAC;AAED,WAAO,mBAAmB,MAAM,IAAI;AAAA,EACtC;AACF;AAGO,SAAS,cAAc,QAA2B;AACvD,SAAO,CAAC,wBAAwB,MAAM,GAAG,oBAAoB,gBAAgB,gBAAgB;AAC/F;AAIA,SAAS,mBAAmB,WAAmB,MAA6B;AAC1E,MAAI;AACF,UAAM,UACH,KAA4D,UAAU,CAAC,GAAG,SAAS,WACpF;AACF,QAAI,UAAU,QAAQ,QAAQ,sBAAsB,EAAE,EAAE,KAAK;AAC7D,UAAM,aAAa,QAAQ,MAAM,aAAa;AAC9C,QAAI,WAAY,WAAU,WAAW,CAAC;AACtC,UAAM,SAAS,KAAK,MAAM,OAAO;AAMjC,WAAO,OAAO,IAAI,CAAC,OAAO;AAAA,MACxB;AAAA,MACA,WAAW,EAAE;AAAA,MACb,OAAO,KAAK,IAAI,GAAG,KAAK,IAAI,IAAI,EAAE,KAAK,CAAC;AAAA,MACxC,WAAW,EAAE,aAAa;AAAA,MAC1B,UAAU,EAAE;AAAA,IACd,EAAE;AAAA,EACJ,SAAS,KAAK;AACZ,UAAM,UACH,KAA4D,UAAU,CAAC,GAAG,SAAS,WACpF;AACF,YAAQ;AAAA,MACN,qBAAqB,SAAS,KAAM,IAAc,SAAS,MAAM,GAAG,EAAE,CAAC,gBAAgB,QAAQ,MAAM,GAAG,GAAG,CAAC;AAAA,IAC9G;AACA,WAAO;AAAA,MACL;AAAA,QACE;AAAA,QACA,WAAW;AAAA,QACX,OAAO;AAAA,QACP,WAAW,iBAAkB,IAAc,SAAS,MAAM,GAAG,GAAG,CAAC,UAAU,QAAQ,MAAM,GAAG,GAAG,CAAC;AAAA,MAClG;AAAA,IACF;AAAA,EACF;AACF;;;AC3LA,eAAsB,aAAa,QAAmD;AACpF,QAAM,YAAY,KAAK,IAAI;AAC3B,QAAM,SAAwB,CAAC;AAC/B,QAAM,YAAiC,CAAC;AACxC,QAAM,SAA0B,CAAC;AACjC,QAAM,aAA6C,CAAC;AACpD,QAAM,WAAW,EAAE,GAAI,OAAO,YAAY,CAAC,GAAI,MAAM,KAAK;AAC1D,QAAM,UAA4B;AAAA,IAChC,WAAW,OAAO;AAAA,IAClB,YAAY,OAAO;AAAA,IACnB,MAAM,OAAO;AAAA,IACb;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,UAAU,CAACC,WAAU,OAAO,KAAKA,MAAK;AAAA,IACtC,aAAa,CAAC,aAAa,UAAU,KAAK,QAAQ;AAAA,IAClD,UAAU,CAAC,UACT,OAAO,KAAK,EAAE,GAAG,OAAO,WAAW,MAAM,cAAa,oBAAI,KAAK,GAAE,YAAY,EAAE,CAAC;AAAA,IAClF,SAAS,CAAC,SAAS,WAAW,KAAK,EAAE,GAAG,MAAM,IAAI,KAAK,OAAM,oBAAI,KAAK,GAAE,YAAY,EAAE,CAAC;AAAA,EACzF;AAEA,MAAI;AACF,UAAM,OAAO,MAAM,OAAO;AAC1B,UAAM,mBAAmB,MAAM,OAAO,WAAW,OAAO;AACxD,QAAI,iBAAkB,QAAO,KAAK,GAAG,gBAAgB;AAAA,EACvD,SAAS,KAAK;AACZ,WAAO,KAAK;AAAA,MACV,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,QAAQ,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,IACzD,CAAC;AAAA,EACH;AAEA,aAAW,QAAQ,OAAO,qBAAqB,CAAC,GAAG;AACjD,WAAO,KAAK;AAAA,MACV,MAAM,YAAY,IAAI;AAAA,MACtB,QAAQ,UAAU,KAAK,CAAC,aAAa,SAAS,SAAS,IAAI;AAAA,MAC3D,UAAU,iBAAiB,IAAI;AAAA,MAC/B,QAAQ,UAAU,IAAI,CAAC,aAAa,SAAS,IAAI,EAAE,KAAK,IAAI,KAAK;AAAA,IACnE,CAAC;AAAA,EACH;AAEA,QAAM,WACJ,OAAO,WAAW,IAAI,IAAI,OAAO,OAAO,CAACA,WAAUA,OAAM,MAAM,EAAE,SAAS,OAAO;AACnF,MAAI,OAAO,gBAAgB,QAAW;AACpC,WAAO,KAAK;AAAA,MACV,MAAM;AAAA,MACN,QAAQ,YAAY,OAAO;AAAA,MAC3B,UAAU,gBAAgB,OAAO,WAAW;AAAA,MAC5C,QAAQ,SAAS,QAAQ,CAAC;AAAA,IAC5B,CAAC;AAAA,EACH;AAEA,QAAM,SAAS,OAAO,SAAS,KAAK,OAAO,MAAM,CAACA,WAAUA,OAAM,MAAM;AACxE,QAAM,WAAW,KAAK,IAAI,IAAI;AAC9B,QAAM,aAAa,yBAAyB;AAAA,IAC1C,WAAW,OAAO;AAAA,IAClB,YAAY,OAAO;AAAA,IACnB,MAAM,EAAE,QAAQ,OAAO,KAAK;AAAA,IAC5B;AAAA,IACA,SAAS;AAAA,MACP,SAAS;AAAA,MACT,OACE,OAAO,WAAW,IAAI,IAAI,OAAO,OAAO,CAACA,WAAUA,OAAM,MAAM,EAAE,SAAS,OAAO;AAAA,MACnF,QAAQ,GAAG,OAAO,OAAO,CAACA,WAAUA,OAAM,MAAM,EAAE,MAAM,IAAI,OAAO,MAAM;AAAA,MACzE,aAAY,oBAAI,KAAK,GAAE,YAAY;AAAA,MACnC,UAAU;AAAA,QACR;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,IACA;AAAA,EACF,CAAC;AACD,QAAM,OAAO,iBAAiB,KAAK,UAAU;AAE7C,QAAM,oBAAoB,OAAO,oBAC7B,0BAA0B;AAAA,IACxB,GAAG,OAAO;AAAA,IACV,QAAQ,CAAC,wBAAwB,QAAQ,YAAY,QAAQ,CAAC;AAAA,IAC9D,YAAY;AAAA,MACV,eAAe;AAAA,MACf,gBAAgB;AAAA,MAChB,kBAAkB;AAAA,MAClB,eAAe;AAAA,MACf,gBAAgB;AAAA,MAChB,uBAAuB;AAAA,MACvB,GAAI,OAAO,kBAAkB,cAAc,CAAC;AAAA,IAC9C;AAAA,EACF,CAAC,IACD;AAEJ,SAAO;AAAA,IACL,MAAM,OAAO;AAAA,IACb,QAAQ,WAAW,oBAAoB,kBAAkB,WAAW,SAAS;AAAA,IAC7E;AAAA,IACA,QAAQ,GAAG,OAAO,OAAO,CAACA,WAAUA,OAAM,MAAM,EAAE,MAAM,IAAI,OAAO,MAAM;AAAA,IACzE;AAAA,IACA,WAAW,OAAO;AAAA,IAClB,YAAY,OAAO;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,wBACP,QACA,YACA,YACsB;AACtB,SAAO;AAAA,IACL,YAAY,OAAO;AAAA,IACnB,aAAa,OAAO,mBAAmB;AAAA,IACvC,OACE,WAAW,UAAU,YAAY,YAAY,WAAW,UAAU,QAAQ,QAAQ;AAAA,IACpF,OAAO,WAAW,SAAS;AAAA,IAC3B,IAAI,WAAW,SAAS;AAAA,IACxB,WAAW,MAAM,QAAQ,WAAW,SAAS,UAAU,UAAU,IAC7D,WAAW,QAAQ,SAAS,WAAW,SACvC;AAAA,IACJ;AAAA,IACA,UAAU;AAAA,MACR,WAAW,OAAO;AAAA,MAClB,WAAW,WAAW,SAAS,UAAU;AAAA,IAC3C;AAAA,EACF;AACF;;;ACnGO,IAAM,kCAAwD;AAAA,EACnE,QAAQ;AAAA,EACR,WAAW;AAAA,EACX,eAAe;AAAA,EACf,qBAAqB;AAAA,EACrB,UAAU;AACZ;AAEO,SAAS,kBACd,WACA,QACmB;AACnB,SAAO,UAAU,SAAS,OAAO,CAAC,YAAY,QAAQ,WAAW,MAAM;AACzE;AAEO,SAAS,oBACd,WACA,QACA,UAAyC,CAAC,GAC3B;AACf,SAAO,sBAAsB,WAAW,kBAAkB,WAAW,MAAM,GAAG,QAAQ,OAAO;AAC/F;AAEO,SAAS,sBACd,WACA,UACA,QACA,UAAyC,CAAC,GAC3B;AACf,QAAM,kBAAkB,uBAAuB,UAAU,mBAAmB,QAAQ;AACpF,QAAM,oBAAoB,IAAI,IAAI,gBAAgB,IAAI,CAAC,UAAU,MAAM,SAAS,CAAC;AACjF,QAAM,mBAAmB,SAAS,OAAO,CAAC,YAAY,kBAAkB,QAAQ,OAAO,CAAC;AACxF,QAAM,mBAAmB,SAAS,OAAO,CAAC,YAAY,kBAAkB,QAAQ,OAAO,CAAC;AACxF,QAAM,qBAAqB,SAAS,OAAO,mBAAmB;AAC9D,QAAM,mBAAmB,SAAS,OAAO,CAAC,YAAY,QAAQ,QAAQ;AACtE,QAAM,kBAAkB,iBAAiB;AAAA,IAAO,CAAC,YAC/C,kBAAkB,SAAS,UAAU,mBAAmB,eAAe;AAAA,EACzE;AAEA,QAAM,SAAS,UAAU,kBAAkB,SACvC,gBAAgB,SAAS,UAAU,kBAAkB,SACrD,SAAS,WAAW,IAClB,IACA;AAEN,QAAM,uBAAuB,iBAAiB,SAAS,iBAAiB;AACxE,QAAMC,aACJ,uBAAuB,IACnB,iBAAiB,SAAS,uBAC1B,SAAS,SAAS,IAChB,kBAAkB,OAAO,SAAS,SAClC,UAAU,kBAAkB,WAAW,IACrC,IACA;AAEV,QAAM,gBAAgB,SAAS,SAAS,mBAAmB,SAAS,SAAS,SAAS;AACtF,QAAM,sBAAsB,iBAAiB,SACzC,gBAAgB,SAAS,iBAAiB,SAC1C,gBAAgB,SACd,MACA;AACN,QAAM,WAAW,SAAS,SAAS,IAAI,iBAAiB,SAAS,SAAS,SAAS;AACnF,QAAMC,aAAY;AAAA,IAChB,EAAE,QAAQ,WAAAD,YAAW,eAAe,qBAAqB,SAAS;AAAA,IAClE;AAAA,EACF;AAEA,SAAO;AAAA,IACL,QAAQ,UAAU;AAAA,IAClB;AAAA,IACA,cAAc,SAAS;AAAA,IACvB,gBAAgB,UAAU,kBAAkB;AAAA,IAC5C;AAAA,IACA;AAAA,IACA,WAAAA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,WAAAC;AAAA,IACA,OAAO,gBAAgB;AAAA,MACrB;AAAA,MACA,gBAAgB,UAAU,kBAAkB;AAAA,MAC5C;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAEO,SAAS,2BAA2BC,SAAqD;AAC9F,QAAM,WAAW,oBAAI,IAAqC;AAC1D,aAAW,SAASA,SAAQ;AAC1B,aAAS,IAAI,MAAM,QAAQ,CAAC,GAAI,SAAS,IAAI,MAAM,MAAM,KAAK,CAAC,GAAI,KAAK,CAAC;AAAA,EAC3E;AACA,SAAO,CAAC,GAAG,SAAS,QAAQ,CAAC,EAC1B,IAAI,CAAC,CAAC,QAAQ,YAAY,OAAO;AAAA,IAChC;AAAA,IACA,WAAW,aAAa;AAAA,IACxB,cAAc,IAAI,aAAa,IAAI,CAAC,UAAU,MAAM,YAAY,CAAC;AAAA,IACjE,eAAe,KAAK,aAAa,IAAI,CAAC,UAAU,MAAM,SAAS,CAAC;AAAA,IAChE,YAAY,KAAK,aAAa,IAAI,CAAC,UAAU,MAAM,MAAM,CAAC;AAAA,IAC1D,eAAe,KAAK,aAAa,IAAI,CAAC,UAAU,MAAM,SAAS,CAAC;AAAA,IAChE,mBAAmB,KAAK,aAAa,IAAI,CAAC,UAAU,MAAM,aAAa,CAAC;AAAA,IACxE,yBAAyB,KAAK,aAAa,IAAI,CAAC,UAAU,MAAM,mBAAmB,CAAC;AAAA,IACpF,cAAc,KAAK,aAAa,IAAI,CAAC,UAAU,MAAM,QAAQ,CAAC;AAAA,EAChE,EAAE,EACD,KAAK,CAAC,GAAG,MAAM,EAAE,gBAAgB,EAAE,aAAa;AACrD;AAEO,SAAS,uBACd,YAIA,UAAyC,CAAC,GAClC;AACR,QAAM,SAAS,EAAE,GAAG,iCAAiC,GAAG,QAAQ;AAChE,QAAM,YAAY,OAAO,OAAO,MAAM,EAAE,OAAO,CAAC,OAAO,UAAU,QAAQ,KAAK,IAAI,GAAG,KAAK,GAAG,CAAC;AAC9F,MAAI,aAAa,EAAG,QAAO;AAC3B,UACG,OAAO,SAAS,QAAQ,WAAW,MAAM,IACxC,OAAO,YAAY,QAAQ,WAAW,SAAS,IAC/C,OAAO,gBAAgB,QAAQ,WAAW,aAAa,IACvD,OAAO,sBAAsB,QAAQ,WAAW,mBAAmB,IACnE,OAAO,WAAW,QAAQ,WAAW,QAAQ,KAC/C;AAEJ;AAEA,SAAS,uBACP,YACA,UAC0B;AAC1B,QAAM,UAAoC,CAAC;AAC3C,QAAM,iBAAiB,oBAAI,IAAY;AAEvC,aAAW,aAAa,YAAY;AAClC,UAAM,aAAa,SAChB,OAAO,CAAC,YAAY,CAAC,eAAe,IAAI,QAAQ,EAAE,CAAC,EACnD,IAAI,CAAC,aAAa,EAAE,SAAS,OAAO,WAAW,WAAW,OAAO,EAAE,EAAE,EACrE,OAAO,CAAC,EAAE,MAAM,MAAM,SAAS,IAAI,EACnC,KAAK,CAAC,GAAG,MAAM,EAAE,QAAQ,EAAE,KAAK;AACnC,UAAM,OAAO,WAAW,CAAC;AACzB,QAAI,CAAC,KAAM;AACX,mBAAe,IAAI,KAAK,QAAQ,EAAE;AAClC,YAAQ,KAAK,EAAE,aAAa,UAAU,IAAI,WAAW,KAAK,QAAQ,IAAI,OAAO,KAAK,MAAM,CAAC;AAAA,EAC3F;AAEA,SAAO;AACT;AAEA,SAAS,WAAW,WAAqC,SAAkC;AACzF,MAAI,QAAQ;AACZ,MAAI,UAAU,kBAAkB,SAAS,QAAQ,EAAE,EAAG,UAAS;AAC/D,MACE,UAAU,QACV,QAAQ,QACR,cAAc,UAAU,IAAI,MAAM,cAAc,QAAQ,IAAI,GAC5D;AACA,aAAS;AAAA,EACX;AACA,MAAI,UAAU,QAAQ,QAAQ,QAAQ,KAAK,IAAI,UAAU,OAAO,QAAQ,IAAI,KAAK,EAAG,UAAS;AAE7F,QAAM,QAAQ,CAAC,GAAI,UAAU,YAAY,CAAC,GAAI,GAAG,SAAS,UAAU,KAAK,CAAC;AAC1E,QAAM,cAAc,CAAC,GAAG,IAAI,IAAI,MAAM,IAAI,aAAa,EAAE,OAAO,CAAC,SAAS,KAAK,UAAU,CAAC,CAAC,CAAC;AAC5F,MAAI,YAAY,SAAS,GAAG;AAC1B,UAAM,YAAY,IAAI,IAAI,SAAS,QAAQ,IAAI,EAAE,IAAI,aAAa,CAAC;AACnE,UAAM,UAAU,YAAY,OAAO,CAAC,SAAS,UAAU,IAAI,IAAI,CAAC,EAAE;AAClE,aAAS,OAAO,UAAU,YAAY;AAAA,EACxC;AAEA,SAAO,QAAQ,KAAK;AACtB;AAEA,SAAS,oBAAoB,SAAmC;AAC9D,QAAM,OAAO,QAAQ,KAAK,KAAK;AAC/B,MAAI,CAAC,QAAQ,QAAQ,CAAC,+DAA+D,KAAK,IAAI,GAAG;AAC/F,WAAO;AAAA,EACT;AACA,SAAO,+FAA+F;AAAA,IACpG;AAAA,EACF;AACF;AAEA,SAAS,kBACP,SACA,YACA,SACS;AACT,MAAI,CAAC,QAAQ,SAAU,QAAO;AAC9B,QAAM,QAAQ,QAAQ,KAAK,CAAC,cAAc,UAAU,cAAc,QAAQ,EAAE;AAC5E,MAAI,CAAC,MAAO,QAAO,QAAQ,aAAa,SAAS,QAAQ,aAAa;AACtE,QAAM,YAAY,WAAW,KAAK,CAAC,cAAc,UAAU,OAAO,MAAM,WAAW;AACnF,MAAI,CAAC,UAAW,QAAO;AACvB,SAAO,KAAK,IAAI,aAAa,QAAQ,QAAQ,IAAI,aAAa,UAAU,QAAQ,CAAC,KAAK;AACxF;AAEA,SAAS,gBAAgB,OAMZ;AACX,QAAM,QAAkB,CAAC;AACzB,MAAI,MAAM,iBAAiB,KAAK,MAAM,gBAAgB,WAAW,GAAG;AAClE,UAAM,KAAK,+BAA+B;AAAA,EAC5C;AACA,MAAI,MAAM,iBAAiB,SAAS,GAAG;AACrC,UAAM,KAAK,GAAG,MAAM,iBAAiB,MAAM,+CAA+C;AAAA,EAC5F;AACA,MAAI,MAAM,SAAS,SAAS,KAAK,MAAM,mBAAmB,WAAW,GAAG;AACtE,UAAM,KAAK,iEAAiE;AAAA,EAC9E;AACA,SAAO;AACT;AAEA,SAAS,kBAAkB,SAA+C;AACxE,SAAO,YAAY,cAAc,YAAY;AAC/C;AAEA,SAAS,kBAAkB,SAA+C;AACxE,SAAO,YAAY,cAAc,YAAY,eAAe,YAAY;AAC1E;AAEA,SAAS,aAAa,UAAoC;AACxD,UAAQ,UAAU;AAAA,IAChB,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,EACX;AACF;AAEA,SAAS,SAAS,OAAyB;AACzC,SAAO,MAAM,MAAM,oBAAoB,KAAK,CAAC;AAC/C;AAEA,SAAS,cAAc,OAAuB;AAC5C,SAAO,MAAM,YAAY,EAAE,QAAQ,8BAA8B,EAAE;AACrE;AAEA,SAAS,cAAc,OAAuB;AAC5C,SAAO,MAAM,QAAQ,UAAU,EAAE;AACnC;AAEA,SAAS,KAAK,QAA0B;AACtC,SAAO,OAAO,SAAS,IAAI,MAAM,IAAI,OAAO,SAAS;AACvD;AAEA,SAAS,IAAI,QAA0B;AACrC,SAAO,OAAO,OAAO,CAAC,OAAO,UAAU,QAAQ,OAAO,CAAC;AACzD;;;ACjWO,IAAM,mBAAN,MAAuB;AAAA,EACpB,YAAwB,CAAC;AAAA,EACzB,gBAAgC,CAAC;AAAA;AAAA,EAGzC,cAAc,OAA6B;AACzC,SAAK,cAAc,KAAK,GAAG,KAAK;AAChC,SAAK,UAAU,KAAK,GAAG,MAAM,IAAI,UAAU,CAAC;AAAA,EAC9C;AAAA;AAAA,EAGA,SAAS,WAA6B;AACpC,SAAK,UAAU,KAAK,GAAG,SAAS;AAAA,EAClC;AAAA;AAAA,EAGA,MAAkB;AAChB,WAAO,CAAC,GAAG,KAAK,SAAS;AAAA,EAC3B;AAAA;AAAA,EAGA,WAAW,UAA8B;AACvC,UAAM,YAAY,KAAK,cAAc,OAAO,CAAC,OAAO,GAAG,aAAa,QAAQ,EAAE,IAAI,UAAU;AAC5F,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,iBAAwD;AACtD,UAAM,SAAiC,CAAC;AACxC,eAAW,MAAM,KAAK,eAAe;AACnC,aAAO,GAAG,QAAQ,KAAK,OAAO,GAAG,QAAQ,KAAK,KAAK;AAAA,IACrD;AACA,WAAO,OAAO,QAAQ,MAAM,EAAE,IAAI,CAAC,CAAC,UAAU,KAAK,OAAO,EAAE,UAAU,MAAM,EAAE;AAAA,EAChF;AAAA;AAAA,EAGA,UAAU,SAA6B;AACrC,WAAO,KAAK,UAAU,OAAO,CAAC,MAAM,EAAE,YAAY,OAAO;AAAA,EAC3D;AAAA;AAAA,EAGA,KAAK,IAAkC;AACrC,WAAO,KAAK,UAAU,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE;AAAA,EAC/C;AAAA;AAAA,EAGA,IAAI,QAAgB;AAClB,WAAO,KAAK,UAAU;AAAA,EACxB;AACF;AAGA,SAAS,WAAW,IAA4B;AAC9C,SAAO;AAAA,IACL,IAAI,GAAG;AAAA,IACP,SAAS,GAAG;AAAA,IACZ,OAAO,GAAG;AAAA,IACV,QAAQ,GAAG;AAAA,IACX,YAAY,CAAC;AAAA,IACb,OAAO,GAAG;AAAA,IACV,gBAAgB,GAAG;AAAA,IACnB,oBAAoB,GAAG,YAAY,oCAAoC;AAAA,EACzE;AACF;;;AC7DO,SAAS,sBAAsB,QAAiC;AACrE,QAAM,QAAkB,CAAC;AAEzB,QAAM,KAAK,oBAAoB;AAC/B,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,aAAa,OAAO,SAAS,EAAE;AAC1C,QAAM,KAAK,mBAAmB,OAAO,UAAU,EAAE;AACjD,QAAM,KAAK,uBAAuB,OAAO,aAAa,EAAE;AACxD,QAAM,KAAK,kBAAkB,OAAO,aAAa,EAAE;AACnD,QAAM,KAAK,sBAAsB,OAAO,QAAQ,WAAW,QAAQ,CAAC,CAAC,KAAK;AAC1E,QAAM,KAAK,EAAE;AAGb,QAAM,KAAK,eAAe;AAC1B,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,oCAAoC;AAC/C,QAAM,KAAK,oCAAoC;AAC/C,aAAW,CAAC,MAAM,IAAI,KAAK,OAAO,QAAQ,OAAO,QAAQ,SAAS,GAAG;AACnE,UAAM,KAAK,KAAK,IAAI,MAAM,KAAK,IAAI,QAAQ,CAAC,CAAC,MAAM,KAAK,MAAM,MAAM,KAAK,KAAK,IAAI;AAAA,EACpF;AACA,QAAM,KAAK,EAAE;AAGb,QAAM,KAAK,iBAAiB;AAC5B,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,iCAAiC;AAC5C,QAAM,KAAK,iCAAiC;AAC5C,QAAM,aAAa,OAAO,QAAQ,OAAO,QAAQ,WAAW,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,GAAG;AAChG,aAAW,CAAC,MAAM,IAAI,KAAK,YAAY;AACrC,UAAM,MAAM,KAAK,IAAI,GAAG,KAAK,MAAM;AACnC,UAAM,MAAM,KAAK,IAAI,GAAG,KAAK,MAAM;AACnC,UAAM,KAAK,KAAK,IAAI,MAAM,KAAK,IAAI,QAAQ,CAAC,CAAC,MAAM,GAAG,IAAI,GAAG,MAAM,KAAK,OAAO,MAAM,IAAI;AAAA,EAC3F;AACA,QAAM,KAAK,EAAE;AAGb,MAAI,OAAO,QAAQ,QAAQ,SAAS,GAAG;AACrC,UAAM,KAAK,sBAAsB;AACjC,UAAM,KAAK,EAAE;AACb,eAAW,KAAK,OAAO,QAAQ,SAAS;AACtC,YAAM,KAAK,OAAO,EAAE,QAAQ,OAAO,EAAE,MAAM,QAAQ,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE;AAAA,IACvE;AACA,UAAM,KAAK,EAAE;AAAA,EACf;AAGA,MAAI,OAAO,QAAQ,UAAU,SAAS,GAAG;AACvC,UAAM,KAAK,wBAAwB;AACnC,UAAM,KAAK,EAAE;AACb,eAAW,KAAK,OAAO,QAAQ,WAAW;AACxC,YAAM,KAAK,OAAO,EAAE,QAAQ,OAAO,EAAE,MAAM,QAAQ,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE;AAAA,IACvE;AACA,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;AAGO,SAAS,mBAAmB,SAAiC;AAClE,QAAM,QAAkB,CAAC;AAEzB,QAAM,KAAK,uBAAuB;AAClC,QAAM,KAAK,EAAE;AAEb,aAAW,KAAK,SAAS;AACvB,UAAM,KAAK,eAAe,EAAE,SAAS,EAAE;AACvC,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,oBAAoB,EAAE,YAAY,QAAQ,IAAI,EAAE;AAC3D,UAAM,KAAK,8BAA8B,EAAE,qBAAqB,KAAK,EAAE;AACvE,UAAM,KAAK,sBAAsB,EAAE,UAAU,EAAE;AAC/C,UAAM;AAAA,MACJ,sBAAsB,EAAE,WAAW,KAAK,WAAW,EAAE,WAAW,MAAM,YAAY,EAAE,WAAW,WAAW,MAAM;AAAA,IAClH;AACA,UAAM,KAAK,EAAE;AAGb,UAAM,KAAK,iBAAiB;AAC5B,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,KAAK;AAChB,aAAS,IAAI,GAAG,IAAI,EAAE,iBAAiB,QAAQ,KAAK;AAClD,YAAM,MAAM,EAAE,iBAAiB,CAAC;AAChC,YAAM,MAAM,IAAI,OAAO,KAAK,MAAM,MAAM,CAAC,CAAC;AAC1C,YAAM,KAAK,UAAU,OAAO,IAAI,CAAC,EAAE,SAAS,CAAC,CAAC,KAAK,GAAG,IAAI,IAAI,QAAQ,CAAC,CAAC,GAAG;AAAA,IAC7E;AACA,UAAM,KAAK,KAAK;AAChB,UAAM,KAAK,EAAE;AAGb,QAAI,EAAE,QAAQ,SAAS,GAAG;AACxB,YAAM,KAAK,sBAAsB;AACjC,YAAM,KAAK,EAAE;AACb,YAAM,KAAK,0DAA0D;AACrE,YAAM,KAAK,0DAA0D;AACrE,iBAAW,KAAK,EAAE,SAAS;AACzB,cAAM;AAAA,UACJ,KAAK,EAAE,IAAI,MAAM,EAAE,KAAK,MAAM,EAAE,MAAM,MAAM,EAAE,UAAU,OAAO,EAAE,oBAAoB,KAAM,QAAQ,CAAC,CAAC,OAAO,EAAE,kBAAkB,QAAQ,CAAC,CAAC;AAAA,QAC5I;AAAA,MACF;AACA,YAAM,KAAK,EAAE;AAAA,IACf;AAAA,EACF;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;AAGO,SAAS,mBAAmB,SAA+B;AAChE,UAAQ,IAAI,IAAI,OAAO,EAAE,CAAC;AAC1B,UAAQ,IAAI,8BAAyB;AACrC,UAAQ,IAAI,IAAI,OAAO,EAAE,CAAC;AAE1B,aAAW,KAAK,SAAS;AACvB,UAAM,SAAS,EAAE,YAAY,aAAa;AAC1C,UAAM,QAAQ,EAAE,qBAAqB,EAAE;AACvC,YAAQ;AAAA,MACN,KAAK,EAAE,UAAU,OAAO,EAAE,CAAC,IAAI,OAAO,OAAO,EAAE,CAAC,UAAU,KAAK,WAAW,EAAE,WAAW,KAAK,YAAY,EAAE,WAAW,MAAM,WAAW,EAAE,WAAW,WAAW,MAAM;AAAA,IACtK;AAAA,EACF;AAEA,UAAQ,IAAI;AACZ,QAAM,iBAAiB,QAAQ,OAAO,CAAC,MAAM,EAAE,SAAS,EAAE;AAC1D,UAAQ,IAAI,GAAG,cAAc,IAAI,QAAQ,MAAM,qBAAqB;AACtE;;;AC9EA,IAAM,iBAA2B;AAAA,EAC/B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,IAAM,oBAA8B;AAAA,EAClC;AAAA,EACA;AAAA,EACA;AACF;AAGO,SAAS,oBAAoB,SAAyB,CAAC,GAAY;AACxE,QAAM,OAEF;AAAA,IACF,QAAQ,OAAO,UAAU;AAAA,IACzB,eAAe,OAAO,iBAAiB,CAAC;AAAA,IACxC,gBAAgB,OAAO,kBAAkB,CAAC;AAAA,IAC1C,iBAAiB,OAAO,mBAAmB;AAAA,IAC3C,iBAAiB,OAAO,mBAAmB;AAAA,IAC3C,qBAAqB,OAAO,uBAAuB;AAAA,IACnD,WAAW,OAAO,aAAa;AAAA,IAC/B,WAAW,OAAO,aAAa;AAAA,IAC/B,gBAAgB;AAAA,MACd,eAAe;AAAA,MACf,gBAAgB;AAAA,MAChB,SAAS;AAAA,MACT,SAAS;AAAA,MACT,YAAY;AAAA,MACZ,QAAQ;AAAA,MACR,GAAG,OAAO;AAAA,IACZ;AAAA,EACF;AAEA,QAAM,QAAiB,OAAO,KAAK,UAA6C;AAC9E,UAAM,UAAU,MAAM,MAAM,IAAI,CAAC,MAAM,EAAE,iBAAiB,EAAE;AAC5D,UAAM,SAAS,gBAAgB,SAAS,IAAI;AAC5C,WAAO;AAAA,MACL;AAAA,QACE,WAAW,aAAa,KAAK,MAAM;AAAA,QACnC,WAAW;AAAA,QACX,OAAO,OAAO;AAAA,QACd,WAAW,OAAO,OAAO,SACrB,OAAO,OACJ,MAAM,GAAG,CAAC,EACV,IAAI,CAAC,MAAM,GAAG,EAAE,QAAQ,KAAK,EAAE,MAAM,EAAE,EACvC,KAAK,IAAI,IACZ;AAAA,QACJ,UAAU,OAAO,OAAO,CAAC,GAAG;AAAA,MAC9B;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAoBO,SAAS,gBACd,SACA,QAGgB;AAChB,QAAM,SAA0B,CAAC;AACjC,QAAM,SAAuC;AAAA,IAC3C,eAAe;AAAA,IACf,gBAAgB;AAAA,IAChB,SAAS;AAAA,IACT,SAAS;AAAA,IACT,YAAY;AAAA,IACZ,QAAQ;AAAA,EACV;AAEA,aAAW,UAAU,SAAS;AAC5B,QAAI,CAAC,OAAQ;AACb,UAAM,QAAQ,OAAO,YAAY;AAEjC,eAAW,UAAU,OAAO,eAAe;AACzC,YAAM,SAAS,OAAO,YAAY;AAClC,UAAI,MAAM;AACV,cAAQ,MAAM,MAAM,QAAQ,QAAQ,GAAG,OAAO,IAAI;AAChD,eAAO,iBAAiB;AACxB,YAAI,OAAO,SAAS,IAAI;AACtB,iBAAO,KAAK;AAAA,YACV,UAAU;AAAA,YACV,QAAQ,IAAI,MAAM;AAAA,YAClB,SAAS,QAAQ,QAAQ,KAAK,OAAO,MAAM;AAAA,UAC7C,CAAC;AAAA,QACH;AACA,eAAO,OAAO;AAAA,MAChB;AAAA,IACF;AAEA,eAAW,MAAM,OAAO,gBAAgB;AACtC,UAAI,GAAG,KAAK,MAAM,GAAG;AACnB,eAAO,kBAAkB;AACzB,eAAO,KAAK,EAAE,UAAU,kBAAkB,QAAQ,GAAG,QAAQ,SAAS,OAAO,MAAM,GAAG,EAAE,EAAE,CAAC;AAAA,MAC7F;AAAA,IACF;AAEA,eAAW,MAAM,OAAO,iBAAiB;AACvC,YAAM,UAAU,OAAO;AAAA,QACrB,IAAI,OAAO,IAAI,GAAG,MAAM,SAAS,GAAG,IAAI,GAAG,QAAQ,GAAG,GAAG,KAAK,GAAG;AAAA,MACnE;AACA,UAAI,SAAS;AACX,eAAO,WAAW,QAAQ;AAC1B,eAAO,KAAK;AAAA,UACV,UAAU;AAAA,UACV,QAAQ,GAAG,QAAQ,MAAM,KAAK,GAAG,MAAM;AAAA,UACvC,SAAS,QAAQ,CAAC;AAAA,QACpB,CAAC;AAAA,MACH;AAAA,IACF;AAEA,eAAW,MAAM,OAAO,iBAAiB;AACvC,YAAM,UAAU,OAAO;AAAA,QACrB,IAAI,OAAO,IAAI,GAAG,MAAM,SAAS,GAAG,IAAI,GAAG,QAAQ,GAAG,GAAG,KAAK,GAAG;AAAA,MACnE;AACA,UAAI,SAAS;AACX,eAAO,WAAW,QAAQ;AAC1B,eAAO,KAAK;AAAA,UACV,UAAU;AAAA,UACV,QAAQ,GAAG,QAAQ,MAAM,KAAK,GAAG,MAAM;AAAA,UACvC,SAAS,QAAQ,CAAC;AAAA,QACpB,CAAC;AAAA,MACH;AAAA,IACF;AAGA,UAAM,YAAY,eAAe,MAAM;AACvC,QAAI,UAAU,UAAU,GAAG;AACzB,YAAM,OAAO,oBAAI,IAAoB;AACrC,iBAAW,KAAK,WAAW;AACzB,cAAM,MAAM,iBAAiB,CAAC;AAC9B,YAAI,CAAC,IAAK;AACV,aAAK,IAAI,MAAM,KAAK,IAAI,GAAG,KAAK,KAAK,CAAC;AAAA,MACxC;AACA,UAAI,QAAQ;AACZ,iBAAW,KAAK,KAAK,OAAO,EAAG,KAAI,IAAI,EAAG,UAAS,IAAI;AACvD,YAAMC,SAAQ,QAAQ,UAAU;AAChC,UAAIA,SAAQ,OAAO,qBAAqB;AACtC,eAAO,cAAc;AACrB,eAAO,KAAK;AAAA,UACV,UAAU;AAAA,UACV,QAAQ,IAAIA,SAAQ,KAAK,QAAQ,CAAC,CAAC,4BAA4B,OAAO,sBAAsB,KAAK,QAAQ,CAAC,CAAC;AAAA,QAC7G,CAAC;AAAA,MACH;AAAA,IACF;AAGA,QAAI,OAAO,SAAS,OAAO,WAAW;AACpC,aAAO,UAAU;AACjB,aAAO,KAAK;AAAA,QACV,UAAU;AAAA,QACV,QAAQ,cAAc,OAAO,MAAM,MAAM,OAAO,SAAS;AAAA,MAC3D,CAAC;AAAA,IACH,WAAW,OAAO,SAAS,OAAO,WAAW;AAC3C,aAAO,UAAU;AACjB,aAAO,KAAK;AAAA,QACV,UAAU;AAAA,QACV,QAAQ,aAAa,OAAO,MAAM,MAAM,OAAO,SAAS;AAAA,MAC1D,CAAC;AAAA,IACH;AAAA,EACF;AAIA,MAAI,UAAU;AACd,aAAW,OAAO,OAAO,KAAK,MAAM,GAAqB;AACvD,eAAW,OAAO,GAAG,KAAK,OAAO,eAAe,GAAG,KAAK;AAAA,EAC1D;AACA,QAAM,QAAQ,KAAK,IAAI,GAAG,KAAK,IAAI,IAAI,KAAK,OAAO,CAAC;AAEpD,SAAO,EAAE,OAAO,QAAQ,OAAO;AACjC;AAEA,SAAS,QAAQ,QAAgB,IAAY,KAAqB;AAChE,QAAM,MAAM;AACZ,QAAM,QAAQ,KAAK,IAAI,GAAG,KAAK,GAAG;AAClC,QAAM,MAAM,KAAK,IAAI,OAAO,QAAQ,KAAK,MAAM,GAAG;AAClD,UAAQ,QAAQ,IAAI,WAAM,MAAM,OAAO,MAAM,OAAO,GAAG,KAAK,MAAM,OAAO,SAAS,WAAM;AAC1F;AAEA,SAAS,eAAe,MAAwB;AAE9C,SAAO,KACJ,MAAM,UAAU,EAChB,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,EACnB,OAAO,CAAC,MAAM,EAAE,SAAS,CAAC;AAC/B;AAEA,SAAS,iBAAiB,GAAmB;AAC3C,SAAO,EACJ,YAAY,EACZ,QAAQ,QAAQ,GAAG,EACnB,QAAQ,eAAe,EAAE,EACzB,KAAK;AACV;;;AC1MO,SAAS,kBACd,YACA,SACmB;AACnB,QAAM,UAAU,SAAS,WAAW,WAAW,IAAI,MAAM,CAAC;AAC1D,MAAI,QAAQ,WAAW,WAAW,QAAQ;AACxC,UAAM,IAAI,MAAM,4CAA4C;AAAA,EAC9D;AACA,QAAM,cAAc,QAAQ,OAAO,CAAC,GAAG,MAAM,IAAI,GAAG,CAAC,KAAK;AAC1D,SAAO;AAAA,IACL,MAAM,SAAS,QAAQ,WAAW,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,GAAG;AAAA,IAC7D,MAAM,SAAS,UAAU,KAAK;AAC5B,YAAM,UAAU,MAAM,QAAQ,IAAI,WAAW,IAAI,CAAC,MAAM,EAAE,SAAS,UAAU,GAAG,CAAC,CAAC;AAClF,YAAM,OAAO,QAAQ,MAAM,CAAC,MAAM,EAAE,IAAI;AACxC,YAAM,QAAQ,QAAQ,OAAO,CAAC,KAAK,GAAG,MAAM,MAAM,EAAE,QAAQ,QAAQ,CAAC,GAAI,CAAC,IAAI;AAC9E,aAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA,QAAQ,QAAQ;AAAA,UAAQ,CAAC,GAAG,MAC1B,EAAE,OAAO,IAAI,CAAC,WAAW;AAAA,YACvB,GAAG;AAAA,YACH,OAAO,MAAM,QAAQ,GAAG,WAAW,CAAC,EAAG,IAAI,IAAI,MAAM,KAAK,KAAK,WAAW,CAAC,EAAG;AAAA,UAChF,EAAE;AAAA,QACJ;AAAA,QACA,UAAU,OAAO,YAAY,QAAQ,IAAI,CAAC,GAAG,MAAM,CAAC,WAAW,CAAC,EAAG,MAAM,EAAE,QAAQ,CAAC,CAAC;AAAA,MACvF;AAAA,IACF;AAAA,EACF;AACF;AAOO,SAAS,WAAW,MAAc,SAAoC;AAC3E,SAAO;AAAA,IACL;AAAA,IACA,MAAM,SAAS,UAAU;AACvB,YAAM,OAAO,SAAS,WAAW;AACjC,YAAM,KAAK,QAAQ,KAAK,IAAI;AAC5B,aAAO;AAAA,QACL,MAAM;AAAA,QACN,OAAO,KAAK,IAAI;AAAA,QAChB,QAAQ,KACJ,CAAC,IACD,CAAC,EAAE,UAAU,SAAS,SAAS,kCAAkC,OAAO,GAAG,CAAC;AAAA,MAClF;AAAA,IACF;AAAA,EACF;AACF;AAGO,SAAS,YAAY,MAAc,eAA4C;AACpF,SAAO;AAAA,IACL;AAAA,IACA,MAAM,SAAS,UAAU;AACvB,YAAM,OAAO,SAAS,WAAW;AACjC,UAAI;AACJ,UAAI;AACF,iBAAS,KAAK,MAAM,IAAI;AAAA,MAC1B,SAAS,KAAK;AACZ,eAAO;AAAA,UACL,MAAM;AAAA,UACN,OAAO;AAAA,UACP,QAAQ;AAAA,YACN;AAAA,cACE,UAAU;AAAA,cACV,SAAS,iBAAiB,eAAe,QAAQ,IAAI,UAAU,GAAG;AAAA,YACpE;AAAA,UACF;AAAA,QACF;AAAA,MACF;AACA,YAAM,UAAoB,CAAC;AAC3B,iBAAW,QAAQ,eAAe;AAChC,YAAI,CAAC,WAAW,QAAQ,IAAI,EAAG,SAAQ,KAAK,IAAI;AAAA,MAClD;AACA,YAAM,OAAO,QAAQ,WAAW;AAChC,aAAO;AAAA,QACL;AAAA,QACA,OAAO,IAAI,QAAQ,SAAS,KAAK,IAAI,GAAG,cAAc,MAAM;AAAA,QAC5D,QAAQ,QAAQ,IAAI,CAAC,OAAO;AAAA,UAC1B,UAAU;AAAA,UACV,SAAS,iBAAiB,CAAC;AAAA,UAC3B,OAAO;AAAA,QACT,EAAE;AAAA,MACJ;AAAA,IACF;AAAA,EACF;AACF;AAGO,SAAS,gBAAgB,MAAc,KAAa,KAAgC;AACzF,SAAO;AAAA,IACL;AAAA,IACA,MAAM,SAAS,UAAU;AACvB,YAAM,OACJ,SAAS,OAAO,cAAc,IAAI,YAAY,EAAE,OAAO,SAAS,WAAW,EAAE,EAAE;AACjF,YAAM,OAAO,QAAQ,OAAO,QAAQ;AACpC,YAAM,QAAQ,OAAO,IAAI,OAAO,MAAM,KAAK,IAAI,GAAG,OAAO,GAAG,IAAI,KAAK,IAAI,GAAG,MAAM,IAAI;AACtF,aAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA,QAAQ,OACJ,CAAC,IACD,CAAC,EAAE,UAAU,SAAS,SAAS,QAAQ,IAAI,aAAa,GAAG,KAAK,GAAG,IAAI,CAAC;AAAA,MAC9E;AAAA,IACF;AAAA,EACF;AACF;AAGO,SAAS,YACd,MACA,UACA,SACmB;AACnB,QAAM,KAAK,SAAS,iBAAiB;AACrC,SAAO;AAAA,IACL;AAAA,IACA,MAAM,SAAS,UAAU;AACvB,YAAM,OAAO,KAAM,SAAS,WAAW,MAAO,SAAS,WAAW,IAAI,YAAY;AAClF,YAAM,UAAoB,CAAC;AAC3B,iBAAW,UAAU,UAAU;AAC7B,cAAM,QAAQ,KAAK,SAAS,OAAO,YAAY;AAC/C,YAAI,CAAC,KAAK,SAAS,KAAK,EAAG,SAAQ,KAAK,MAAM;AAAA,MAChD;AACA,YAAM,OAAO,QAAQ,WAAW;AAChC,aAAO;AAAA,QACL;AAAA,QACA,OAAO,IAAI,QAAQ,SAAS,KAAK,IAAI,GAAG,SAAS,MAAM;AAAA,QACvD,QAAQ,QAAQ,IAAI,CAAC,OAAO;AAAA,UAC1B,UAAU;AAAA,UACV,SAAS,sBAAsB,CAAC;AAAA,QAClC,EAAE;AAAA,MACJ;AAAA,IACF;AAAA,EACF;AACF;AAMA,SAAS,WAAW,KAAc,MAAuB;AACvD,QAAM,QAAQ,KAAK,MAAM,GAAG;AAC5B,MAAI,UAAmB;AACvB,aAAW,QAAQ,OAAO;AACxB,QAAI,YAAY,QAAQ,OAAO,YAAY,SAAU,QAAO;AAC5D,UAAM,MAAM,QAAQ,KAAK,IAAI,IAAI,OAAO,IAAI,IAAI;AAChD,cAAW,QAAoC,GAAwB;AACvE,QAAI,YAAY,OAAW,QAAO;AAAA,EACpC;AACA,SAAO;AACT;;;AC7HA,IAAM,YAAY,oBAAI,IAAI;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAED,IAAM,kBAAkB;AACxB,IAAM,oBAAoB;AAE1B,SAAS,OAAO,GAAwB;AACtC,SAAO,IAAI;AAAA,IACT,EACG,YAAY,EACZ,MAAM,YAAY,EAClB,OAAO,CAAC,MAAM,EAAE,SAAS,KAAK,CAAC,UAAU,IAAI,CAAC,CAAC;AAAA,EACpD;AACF;AAOA,SAAS,YAAY,iBAAyB,eAA+B;AAC3E,QAAM,MAAM,OAAO,eAAe;AAClC,MAAI,IAAI,SAAS,EAAG,QAAO;AAC3B,QAAM,OAAO,OAAO,aAAa;AACjC,MAAI,MAAM;AACV,aAAW,KAAK,IAAK,KAAI,KAAK,IAAI,CAAC,EAAG;AACtC,SAAO,MAAM,IAAI;AACnB;AAYA,SAAS,mBACP,KACA,UACA,WACa;AACb,QAAM,UAAU,GAAG,IAAI,KAAK,IAAI,IAAI,YAAY,EAAE;AAClD,QAAM,MAAmB,CAAC;AAC1B,YAAU,QAAQ,CAAC,GAAG,MAAM;AAC1B,SAAK,EAAE,WAAW,IAAI,KAAK,EAAE,SAAS,kBAAmB;AACzD,QAAI,QAAQ,YAAY,SAAS,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE;AAC5D,QAAI,IAAI,YAAY,EAAE,QAAQ,IAAI,SAAS,YAAY,MAAM,EAAE,KAAK,YAAY,GAAG;AACjF,cAAQ,KAAK,IAAI,OAAO,CAAC;AAAA,IAC3B;AACA,QAAI,QAAQ,gBAAiB;AAC7B,QAAI,KAAK;AAAA,MACP;AAAA,MACA,SAAS,YAAY,CAAC;AAAA,MACtB;AAAA,MACA,UAAU,aAAa,EAAE,QAAQ,EAAE,IAAI,2BAA2B,MAAM,QAAQ,CAAC,CAAC;AAAA,MAClF,SAAS,EAAE,WAAW;AAAA,IACxB,CAAC;AAAA,EACH,CAAC;AACD,SAAO;AACT;AAEA,SAAS,mBACP,KACA,UACA,WACa;AACb,QAAM,UAAU,GAAG,IAAI,KAAK,IAAI,IAAI,YAAY,EAAE;AAClD,QAAM,MAAmB,CAAC;AAC1B,aAAW,KAAK,WAAW;AAEzB,QAAI,EAAE,WAAW,WAAY;AAC7B,UAAM,QAAQ,YAAY,SAAS,EAAE,KAAK;AAC1C,QAAI,QAAQ,gBAAiB;AAC7B,UAAM,OAAO,EAAE,WAAW;AAC1B,QAAI,KAAK;AAAA,MACP;AAAA,MACA,SAAS,YAAY,EAAE,EAAE;AAAA,MACzB;AAAA,MACA,UAAU,sBAAsB,EAAE,KAAK,2BAA2B,MAAM,QAAQ,CAAC,CAAC;AAAA,MAClF,SAAS,KAAK,KAAK,EAAE,UAAU,oBAAoB,OAAO;AAAA,IAC5D,CAAC;AAAA,EACH;AACA,SAAO;AACT;AAEA,SAAS,mBACP,KACA,UACA,WACa;AACb,QAAM,MAAmB,CAAC;AAC1B,YAAU,QAAQ,CAAC,MAAM,MAAM;AAC7B,UAAM,QAAQ,YAAY,IAAI,OAAO,IAAI;AACzC,QAAI,QAAQ,gBAAiB;AAC7B,QAAI,KAAK;AAAA,MACP;AAAA,MACA,SAAS,QAAQ,CAAC;AAAA,MAClB;AAAA,MACA,UAAU,cAAc,IAAI,2BAA2B,MAAM,QAAQ,CAAC,CAAC;AAAA,MACvE,SAAS;AAAA,IACX,CAAC;AAAA,EACH,CAAC;AACD,SAAO;AACT;AASA,eAAsB,iBACpB,MACA,OACA,kBAC4B;AAC5B,MAAI,KAAK,aAAa,WAAW,GAAG;AAClC,UAAM,IAAI;AAAA,MACR,2BAA2B,KAAK,MAAM;AAAA,IACxC;AAAA,EACF;AAKA,QAAM,aAA0B,CAAC;AACjC,OAAK,aAAa,QAAQ,CAAC,KAAK,MAAM;AACpC,UAAM,KAAK,IAAI,eAAe;AAC9B,QAAI,OAAO,cAAc,OAAO,OAAO;AACrC,iBAAW,KAAK,GAAG,mBAAmB,KAAK,GAAG,MAAM,SAAS,CAAC;AAAA,IAChE;AACA,QAAI,OAAO,cAAc,OAAO,OAAO;AACrC,iBAAW,KAAK,GAAG,mBAAmB,KAAK,GAAG,MAAM,SAAS,CAAC;AAAA,IAChE;AACA,QAAI,OAAO,eAAe,OAAO,OAAO;AACtC,iBAAW,KAAK,GAAG,mBAAmB,KAAK,GAAG,MAAM,SAAS,CAAC;AAAA,IAChE;AAAA,EACF,CAAC;AACD,aAAW,KAAK,CAAC,GAAG,MAAM,EAAE,QAAQ,EAAE,KAAK;AAE3C,QAAM,WAAW,oBAAI,IAAuB;AAC5C,QAAM,YAAY,oBAAI,IAAY;AAClC,aAAW,KAAK,YAAY;AAC1B,QAAI,SAAS,IAAI,EAAE,QAAQ,KAAK,UAAU,IAAI,EAAE,OAAO,EAAG;AAC1D,aAAS,IAAI,EAAE,UAAU,CAAC;AAC1B,cAAU,IAAI,EAAE,OAAO;AAAA,EACzB;AAEA,QAAM,eAAmC,CAAC;AAC1C,WAAS,IAAI,GAAG,IAAI,KAAK,aAAa,QAAQ,KAAK;AACjD,UAAM,MAAM,KAAK,aAAa,CAAC;AAC/B,UAAM,QAAQ,SAAS,IAAI,CAAC;AAC5B,UAAM,WAAqB,CAAC;AAC5B,QAAI,UAA0B;AAE9B,QAAI,OAAO;AACT,eAAS,KAAK,MAAM,QAAQ;AAC5B,UAAI,MAAM,YAAY,MAAM;AAC1B,cAAM,IAAI,MAAM,iBAAiB,KAAK,MAAM,OAAO;AACnD,kBAAU,EAAE;AACZ,iBAAS,KAAK,gBAAgB,EAAE,UAAU,SAAS,MAAM,WAAM,EAAE,MAAM,EAAE;AAAA,MAC3E,OAAO;AACL,iBAAS,KAAK,kEAA6D;AAAA,MAC7E;AAAA,IACF,OAAO;AACL,YAAM,KAAK,IAAI,eAAe;AAC9B,YAAM,OAAO,OAAO,QAAQ,gCAAgC;AAC5D,eAAS,KAAK,eAAe,IAAI,2BAA2B;AAAA,IAC9D;AAEA,UAAM,sBAAsB,UAAU;AACtC,UAAM,YAAY,uBAAuB,YAAY;AACrD,iBAAa,KAAK;AAAA,MAChB,OAAO,IAAI;AAAA,MACX,OAAO,IAAI;AAAA,MACX;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAEA,QAAM,iBAAiB,aAAa,OAAO,CAAC,MAAM,EAAE,SAAS,EAAE;AAC/D,SAAO;AAAA,IACL,QAAQ,KAAK;AAAA,IACb;AAAA,IACA,gBAAgB,iBAAiB,aAAa;AAAA,IAC9C,eAAe,mBAAmB,aAAa;AAAA,EACjD;AACF;AASO,SAAS,yBAAyB,KAAmD;AAC1F,QAAM,QAAQ,IAAI,MAAM,aAAa;AACrC,MAAI,CAAC,OAAO;AACV,UAAM,IAAI,MAAM,0DAA0D,IAAI,MAAM,GAAG,GAAG,CAAC,EAAE;AAAA,EAC/F;AACA,QAAM,SAAS,KAAK,MAAM,MAAM,CAAC,CAAC;AAClC,MAAI,OAAO,OAAO,YAAY,WAAW;AACvC,UAAM,IAAI,MAAM,uDAAuD,MAAM,CAAC,EAAE,MAAM,GAAG,GAAG,CAAC,EAAE;AAAA,EACjG;AACA,SAAO,EAAE,SAAS,OAAO,SAAS,QAAQ,OAAO,OAAO,WAAW,WAAW,OAAO,SAAS,GAAG;AACnG;AAQO,SAAS,4BACd,IACA,OAAkC,CAAC,GACf;AACpB,QAAM,QAAQ,KAAK,SAAS;AAC5B,QAAM,kBAAkB,KAAK,mBAAmB;AAChD,SAAO,OAAO,aAAa,YAAY;AACrC,UAAM,OAAO,MAAM,GAAG,KAAK;AAAA,MACzB;AAAA,MACA,UAAU;AAAA,QACR;AAAA,UACE,MAAM;AAAA,UACN,SACE;AAAA,QACJ;AAAA,QACA;AAAA,UACE,MAAM;AAAA,UACN,SAAS,gBAAgB,YAAY,KAAK;AAAA,EACxC,YAAY,WAAW,aAAa,YAAY,QAAQ;AAAA,IAAO,EACjE;AAAA;AAAA,EAAyB,QAAQ,MAAM,GAAG,eAAe,CAAC;AAAA,QAC5D;AAAA,MACF;AAAA,MACA,aAAa;AAAA,MACb,WAAW;AAAA,IACb,CAAC;AACD,UAAM,MACH,KAA4D,UAAU,CAAC,GAAG,SAAS,WACpF;AACF,WAAO,yBAAyB,GAAG;AAAA,EACrC;AACF;;;AC3RO,IAAM,iBAAN,MAAqB;AAAA,EAC1B,MAAM,IAAI,QAAwD;AAChE,UAAM,YAAY,OAAO,aAAa;AACtC,UAAM,YAAY,OAAO,wBAAwB;AAEjD,QAAI,OAAO,UAAU,WAAW,GAAG;AACjC,YAAM,IAAI,MAAM,6CAA6C;AAAA,IAC/D;AAEA,UAAM,UAAqC,CAAC;AAE5C,eAAW,YAAY,OAAO,WAAW;AACvC,YAAM,UAA4B,CAAC;AACnC,UAAI,YAAY;AAChB,UAAI,mBAAkC;AACtC,UAAI,gBAAgB;AACpB,UAAI,YAAY;AAChB,UAAI;AAEJ,eAAS,IAAI,GAAG,IAAI,WAAW,KAAK;AAClC,cAAM,gBAAgB,QAAQ,QAAQ,SAAS,CAAC,GAAG;AACnD,cAAM,WAAW,MAAM,OAAO,QAAQ;AAAA,UACpC;AAAA,UACA,YAAY;AAAA,UACZ;AAAA,UACA;AAAA,QACF,CAAC;AACD,cAAM,EAAE,UAAU,iBAAiB,IAAI,MAAM,OAAO,SAAS;AAAA,UAC3D;AAAA,UACA,YAAY;AAAA,UACZ;AAAA,QACF,CAAC;AAED,YAAI,CAAC,OAAO,SAAS,gBAAgB,KAAK,mBAAmB,KAAK,mBAAmB,GAAG;AACtF,gBAAM,IAAI;AAAA,YACR,uDAAuD,gBAAgB,iBAAiB,SAAS,EAAE,UAAU,CAAC;AAAA,UAChH;AAAA,QACF;AAEA,cAAM,QAAwB;AAAA,UAC5B,YAAY;AAAA,UACZ;AAAA,UACA;AAAA,UACA;AAAA,QACF;AACA,gBAAQ,KAAK,KAAK;AAClB,eAAO,kBAAkB,EAAE,YAAY,SAAS,IAAI,MAAM,CAAC;AAE3D,wBAAgB;AAChB,oBAAY;AACZ,wBAAgB;AAEhB,YAAI,oBAAoB,WAAW;AACjC,sBAAY;AACZ,6BAAmB,IAAI;AACvB;AAAA,QACF;AAAA,MACF;AAEA,cAAQ,KAAK;AAAA,QACX,YAAY,SAAS;AAAA,QACrB;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,YAAY;AAAA,MACd,CAAC;AAAA,IACH;AAEA,UAAM,mBAAmB,QAAQ,OAAO,CAAC,MAAM,EAAE,SAAS;AAC1D,UAAM,kBAAkB,QAAQ,SAAS,iBAAiB,SAAS,QAAQ,SAAS;AACpF,UAAM,sBAAsB,iBAAiB,SACzC,iBAAiB,OAAO,CAAC,KAAK,MAAM,OAAO,EAAE,oBAAoB,IAAI,CAAC,IACtE,iBAAiB,SACjB;AACJ,UAAM,gBAAgB,QAAQ,SAC1B,QAAQ,OAAO,CAAC,KAAK,MAAM,MAAM,EAAE,YAAY,CAAC,IAAI,QAAQ,SAC5D;AAEJ,WAAO;AAAA,MACL,WAAW;AAAA,MACX,WAAW,EAAE,iBAAiB,qBAAqB,cAAc;AAAA,MACjE,QAAQ,EAAE,WAAW,sBAAsB,UAAU;AAAA,IACvD;AAAA,EACF;AACF;;;AC5GO,IAAM,0BAAN,MAAyD;AAAA,EAC7C,cAAc,oBAAI,IAAwB;AAAA,EAC1C,OAAO,oBAAI,IAAiB;AAAA,EAE7C,MAAM,eAAe,KAAgC;AACnD,SAAK,YAAY,IAAI,IAAI,IAAI,EAAE,GAAG,IAAI,CAAC;AAAA,EACzC;AAAA,EACA,MAAM,cAAc,IAAwC;AAC1D,UAAM,IAAI,KAAK,YAAY,IAAI,EAAE;AACjC,WAAO,IAAI,EAAE,GAAG,EAAE,IAAI;AAAA,EACxB;AAAA,EACA,MAAM,kBAAyC;AAC7C,WAAO,CAAC,GAAG,KAAK,YAAY,OAAO,CAAC,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,UAAU,cAAc,EAAE,SAAS,CAAC;AAAA,EAC7F;AAAA,EACA,MAAM,QAAQ,KAAyB;AACrC,SAAK,KAAK,IAAI,IAAI,IAAI,gBAAgB,GAAG,CAAC;AAAA,EAC5C;AAAA,EACA,MAAM,OAAO,IAAiC;AAC5C,UAAM,IAAI,KAAK,KAAK,IAAI,EAAE;AAC1B,WAAO,IAAI,gBAAgB,CAAC,IAAI;AAAA,EAClC;AAAA,EACA,MAAM,SAAS,cAAsC;AACnD,WAAO,CAAC,GAAG,KAAK,KAAK,OAAO,CAAC,EAC1B,OAAO,CAAC,MAAM,EAAE,iBAAiB,YAAY,EAC7C,KAAK,CAAC,GAAG,MAAM,EAAE,UAAU,cAAc,EAAE,SAAS,CAAC,EACrD,IAAI,CAAC,MAAM,gBAAgB,CAAC,CAAC;AAAA,EAClC;AACF;AAMO,IAAM,oBAAN,MAAwB;AAAA,EAC7B,YAA6B,OAAwB;AAAxB;AAAA,EAAyB;AAAA,EAAzB;AAAA,EAE7B,MAAM,gBAAgB,MAAc,UAAyD;AAC3F,UAAM,MAAkB;AAAA,MACtB,IAAI,OAAO,KAAK,CAAC,CAAC;AAAA,MAClB;AAAA,MACA,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MAClC;AAAA,IACF;AACA,UAAM,KAAK,MAAM,eAAe,GAAG;AACnC,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,SAAS,QAAiC;AAC9C,UAAM,MAAM,MAAM,KAAK,MAAM,cAAc,OAAO,YAAY;AAC9D,QAAI,CAAC,IAAK,OAAM,IAAI,MAAM,cAAc,OAAO,YAAY,YAAY;AAEvE,UAAM,MAAW;AAAA,MACf,IAAI,OAAO,KAAK,EAAE,CAAC;AAAA,MACnB,cAAc,OAAO;AAAA,MACrB,MAAM,OAAO;AAAA,MACb;AAAA,MACA,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MAClC,QAAQ;AAAA,IACV;AACA,UAAM,KAAK,MAAM,QAAQ,GAAG;AAC5B,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,YAAY,OAAe,QAAwC;AACvE,UAAM,MAAM,MAAM,KAAK,MAAM,OAAO,KAAK;AACzC,QAAI,CAAC,IAAK,OAAM,IAAI,MAAM,OAAO,KAAK,YAAY;AAClD,QAAI,SAAS;AACb,QAAI,eAAc,oBAAI,KAAK,GAAE,YAAY;AACzC,QAAI,SAAS;AACb,UAAM,KAAK,MAAM,QAAQ,GAAG;AAAA,EAC9B;AAAA,EAEA,MAAM,QAAQ,OAAe,OAA8B;AACzD,UAAM,MAAM,MAAM,KAAK,MAAM,OAAO,KAAK;AACzC,QAAI,CAAC,IAAK,OAAM,IAAI,MAAM,OAAO,KAAK,YAAY;AAClD,QAAI,SAAS;AACb,QAAI,eAAc,oBAAI,KAAK,GAAE,YAAY;AACzC,QAAI,QAAQ;AACZ,UAAM,KAAK,MAAM,QAAQ,GAAG;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,KAAK,QAAgB,QAAkC;AAC3D,UAAM,CAAC,GAAG,CAAC,IAAI,MAAM,QAAQ,IAAI,CAAC,KAAK,MAAM,OAAO,MAAM,GAAG,KAAK,MAAM,OAAO,MAAM,CAAC,CAAC;AACvF,QAAI,CAAC,KAAK,CAAC,EAAG,OAAM,IAAI,MAAM,sBAAsB;AACpD,QAAI,CAAC,EAAE,UAAU,CAAC,EAAE,OAAQ,OAAM,IAAI,MAAM,0CAA0C;AAEtF,UAAM,cAAc,IAAI,IAAI,EAAE,OAAO,QAAQ,IAAI,CAAC,MAAM,CAAC,EAAE,YAAY,EAAE,YAAY,CAAC,CAAC;AACvF,UAAM,cAAc,IAAI,IAAI,EAAE,OAAO,QAAQ,IAAI,CAAC,MAAM,CAAC,EAAE,YAAY,EAAE,YAAY,CAAC,CAAC;AAEvF,UAAM,cAAc,oBAAI,IAAI,CAAC,GAAG,YAAY,KAAK,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC;AAC1E,UAAM,YAAkC,CAAC;AACzC,eAAW,MAAM,aAAa;AAC5B,YAAM,SAAS,YAAY,IAAI,EAAE;AACjC,YAAM,SAAS,YAAY,IAAI,EAAE;AACjC,UAAI,WAAW,QAAW;AACxB,kBAAU,KAAK;AAAA,UACb,YAAY;AAAA,UACZ,QAAQ;AAAA,UACR,OAAO;AAAA,UACP,OAAO;AAAA,UACP,QAAQ;AAAA,QACV,CAAC;AAAA,MACH,WAAW,WAAW,QAAW;AAC/B,kBAAU,KAAK;AAAA,UACb,YAAY;AAAA,UACZ,QAAQ;AAAA,UACR,OAAO;AAAA,UACP,OAAO;AAAA,UACP,QAAQ;AAAA,QACV,CAAC;AAAA,MACH,OAAO;AACL,kBAAU,KAAK;AAAA,UACb,YAAY;AAAA,UACZ,QAAQ;AAAA,UACR,OAAO;AAAA,UACP,OAAO,SAAS;AAAA,UAChB,QAAQ,SAAS,SAAS,aAAa,SAAS,SAAS,cAAc;AAAA,QACzE,CAAC;AAAA,MACH;AAAA,IACF;AACA,cAAU,KAAK,CAAC,GAAG,OAAO,EAAE,SAAS,MAAM,EAAE,SAAS,EAAE;AAExD,UAAM,iBAAiB,EAAE,OAAO,QAAQ,aAAa,EAAE,OAAO,QAAQ;AACtE,UAAM,gBAAqE,CAAC;AAC5E,UAAM,OAAO,oBAAI,IAAI,CAAC,GAAG,OAAO,KAAK,EAAE,MAAM,GAAG,GAAG,OAAO,KAAK,EAAE,MAAM,CAAC,CAAC;AACzE,UAAM,OAAO,EAAE;AACf,UAAM,OAAO,EAAE;AACf,eAAW,KAAK,MAAM;AACpB,UAAI,KAAK,UAAU,KAAK,CAAC,CAAC,MAAM,KAAK,UAAU,KAAK,CAAC,CAAC,GAAG;AACvD,sBAAc,CAAC,IAAI,EAAE,QAAQ,KAAK,CAAC,GAAG,OAAO,KAAK,CAAC,EAAE;AAAA,MACvD;AAAA,IACF;AAEA,WAAO;AAAA,MACL,QAAQ,EAAE,OAAO,QAAQ,MAAM,EAAE,MAAM,WAAW,EAAE,UAAU;AAAA,MAC9D,OAAO,EAAE,OAAO,QAAQ,MAAM,EAAE,MAAM,WAAW,EAAE,UAAU;AAAA,MAC7D;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,SACJ,cAC8E;AAC9E,UAAM,OAAO,MAAM,KAAK,MAAM,SAAS,YAAY;AACnD,WAAO,KACJ,MAAM,EACN,KAAK,CAAC,GAAG,MAAM,EAAE,UAAU,cAAc,EAAE,SAAS,CAAC,EACrD,IAAI,CAAC,OAAO;AAAA,MACX,OAAO,EAAE;AAAA,MACT,WAAW,EAAE;AAAA,MACb,SAAS,EAAE,QAAQ,QAAQ,cAAc;AAAA,IAC3C,EAAE;AAAA,EACN;AACF;AAgBA,SAAS,KAAK,OAAuB;AACnC,QAAM,MAAM,IAAI,WAAW,KAAK;AAChC,SAAO,gBAAgB,GAAG;AAC1B,SAAO,MAAM,KAAK,GAAG,EAClB,IAAI,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG,CAAC,EAC1C,KAAK,EAAE;AACZ;;;ACzLA,IAAM,iBAAiB;AAEhB,IAAM,oBAAN,MAAmD;AAAA,EACvC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACT,cAAc;AAAA,EAEtB,YAAY,SAAmC;AAC7C,SAAK,KAAK,QAAQ;AAClB,UAAM,SAAS,QAAQ,eAAe;AACtC,SAAK,mBAAmB,GAAG,MAAM;AACjC,SAAK,YAAY,GAAG,MAAM;AAC1B,SAAK,YAAY,GAAG,MAAM;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,eAA8B;AAClC,QAAI,KAAK,YAAa;AAEtB,UAAM,MAAM;AAAA,mCACmB,KAAK,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mCAMrB,KAAK,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,uCAWV,KAAK,SAAS,kBAAkB,KAAK,SAAS;AAAA,uCAC9C,KAAK,SAAS,eAAe,KAAK,SAAS;AAAA,mCAC/C,KAAK,SAAS;AAAA;AAAA;AAAA;AAAA,+BAIlB,KAAK,SAAS,2CAA2C,cAAc;AAAA;AAElG,UAAM,KAAK,GAAG,KAAK,IAAI,KAAK,EAAE,QAAQ,QAAQ,GAAG,CAAC;AAClD,SAAK,cAAc;AAAA,EACrB;AAAA,EAEA,MAAM,eAAe,KAAgC;AACnD,UAAM,KAAK,aAAa;AACxB,UAAM,KAAK,GACR;AAAA,MACC,eAAe,KAAK,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAMtC,EACC,KAAK,IAAI,IAAI,IAAI,MAAM,IAAI,WAAW,IAAI,WAAW,KAAK,UAAU,IAAI,QAAQ,IAAI,IAAI,EACxF,IAAI;AAAA,EACT;AAAA,EAEA,MAAM,cAAc,IAAwC;AAC1D,UAAM,KAAK,aAAa;AACxB,UAAM,MAAM,MAAM,KAAK,GACpB;AAAA,MACC;AAAA,gBACQ,KAAK,gBAAgB;AAAA;AAAA,IAE/B,EACC,KAAK,EAAE,EACP,MAAqB;AACxB,WAAO,MAAM,gBAAgB,GAAG,IAAI;AAAA,EACtC;AAAA,EAEA,MAAM,kBAAyC;AAC7C,UAAM,KAAK,aAAa;AACxB,UAAM,EAAE,QAAQ,IAAI,MAAM,KAAK,GAC5B;AAAA,MACC;AAAA,gBACQ,KAAK,gBAAgB;AAAA;AAAA,IAE/B,EACC,IAAmB;AACtB,WAAO,QAAQ,IAAI,eAAe;AAAA,EACpC;AAAA,EAEA,MAAM,QAAQ,KAAyB;AACrC,UAAM,KAAK,aAAa;AACxB,UAAM,KAAK,GACR;AAAA,MACC,eAAe,KAAK,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAW/B,EACC;AAAA,MACC,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ,IAAI,QAAQ;AAAA,MACZ,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ,IAAI,eAAe;AAAA,MACnB,KAAK,UAAU,IAAI,MAAM;AAAA,MACzB,IAAI,SAAS,KAAK,UAAU,IAAI,MAAM,IAAI;AAAA,MAC1C,IAAI,SAAS;AAAA,IACf,EACC,IAAI;AAAA,EACT;AAAA,EAEA,MAAM,OAAO,IAAiC;AAC5C,UAAM,KAAK,aAAa;AACxB,UAAM,MAAM,MAAM,KAAK,GACpB;AAAA,MACC;AAAA,gBACQ,KAAK,SAAS;AAAA;AAAA,IAExB,EACC,KAAK,EAAE,EACP,MAAc;AACjB,WAAO,MAAM,SAAS,GAAG,IAAI;AAAA,EAC/B;AAAA,EAEA,MAAM,SAAS,cAAsC;AACnD,UAAM,KAAK,aAAa;AACxB,UAAM,EAAE,QAAQ,IAAI,MAAM,KAAK,GAC5B;AAAA,MACC;AAAA,gBACQ,KAAK,SAAS;AAAA;AAAA;AAAA,IAGxB,EACC,KAAK,YAAY,EACjB,IAAY;AACf,WAAO,QAAQ,IAAI,QAAQ;AAAA,EAC7B;AACF;AAqBA,SAAS,gBAAgB,KAAgC;AACvD,SAAO;AAAA,IACL,IAAI,IAAI;AAAA,IACR,MAAM,IAAI;AAAA,IACV,WAAW,IAAI;AAAA,IACf,GAAI,IAAI,gBACJ,EAAE,UAAU,KAAK,MAAM,IAAI,aAAa,EAA6B,IACrE,CAAC;AAAA,EACP;AACF;AAEA,SAAS,SAAS,KAAkB;AAClC,SAAO;AAAA,IACL,IAAI,IAAI;AAAA,IACR,cAAc,IAAI;AAAA,IAClB,GAAI,IAAI,OAAO,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;AAAA,IACrC,QAAQ,IAAI;AAAA,IACZ,WAAW,IAAI;AAAA,IACf,GAAI,IAAI,eAAe,EAAE,aAAa,IAAI,aAAa,IAAI,CAAC;AAAA,IAC5D,QAAQ,KAAK,MAAM,IAAI,WAAW;AAAA,IAClC,GAAI,IAAI,cAAc,EAAE,QAAQ,KAAK,MAAM,IAAI,WAAW,EAAE,IAAI,CAAC;AAAA,IACjE,GAAI,IAAI,QAAQ,EAAE,OAAO,IAAI,MAAM,IAAI,CAAC;AAAA,EAC1C;AACF;;;ACxNO,IAAM,4BAAN,MAA2D;AAAA,EAC/C;AAAA,EACA;AAAA,EACT;AAAA,EACA,SAAS;AAAA,EAEjB,YAAY,SAA2C;AACrD,SAAK,MAAM,QAAQ;AACnB,SAAK,WAAW,QAAQ,YAAY,KAAK,OAAO;AAAA,EAClD;AAAA,EAEA,MAAM,eAAe,KAAgC;AACnD,UAAM,MAAM,MAAM,KAAK,KAAK;AAC5B,UAAM,IAAI,eAAe,GAAG;AAC5B,UAAM,KAAK,OAAO,eAAe,GAAG;AAAA,EACtC;AAAA,EAEA,MAAM,cAAc,IAAwC;AAC1D,UAAM,MAAM,MAAM,KAAK,KAAK;AAC5B,WAAO,IAAI,cAAc,EAAE;AAAA,EAC7B;AAAA,EAEA,MAAM,kBAAyC;AAC7C,UAAM,MAAM,MAAM,KAAK,KAAK;AAC5B,WAAO,IAAI,gBAAgB;AAAA,EAC7B;AAAA,EAEA,MAAM,QAAQ,KAAyB;AACrC,UAAM,MAAM,MAAM,KAAK,KAAK;AAC5B,UAAM,IAAI,QAAQ,GAAG;AACrB,UAAM,KAAK,OAAO,QAAQ,GAAG;AAAA,EAC/B;AAAA,EAEA,MAAM,OAAO,IAAiC;AAC5C,UAAM,MAAM,MAAM,KAAK,KAAK;AAC5B,WAAO,IAAI,OAAO,EAAE;AAAA,EACtB;AAAA,EAEA,MAAM,SAAS,cAAsC;AACnD,UAAM,MAAM,MAAM,KAAK,KAAK;AAC5B,WAAO,IAAI,SAAS,YAAY;AAAA,EAClC;AAAA,EAEA,MAAc,YAA2B;AACvC,UAAMC,MAAK,MAAM,OAAO,aAAkB;AAC1C,UAAMA,IAAG,MAAM,KAAK,KAAK,EAAE,WAAW,KAAK,CAAC;AAAA,EAC9C;AAAA,EAEA,MAAc,OAAO,MAA8B,QAAgC;AACjF,UAAM,KAAK,UAAU;AACrB,UAAMA,MAAK,MAAM,OAAO,aAAkB;AAC1C,UAAM,OAAO,MAAM,OAAO,MAAW;AACrC,UAAM,SAAS,KAAK,KAAK,KAAK,KAAK,GAAG,IAAI,SAAS;AACnD,QAAI;AACF,YAAM,OAAO,MAAMA,IAAG,KAAK,MAAM;AACjC,UAAI,KAAK,QAAQ,KAAK,UAAU;AAC9B,cAAM,SAAS,KAAK,KAAK,KAAK,KAAK,GAAG,IAAI,IAAI,KAAK,IAAI,CAAC,SAAS;AACjE,cAAMA,IAAG,OAAO,QAAQ,MAAM;AAAA,MAChC;AAAA,IACF,QAAQ;AAAA,IAER;AACA,UAAMA,IAAG,WAAW,QAAQ,GAAG,KAAK,UAAU,MAAM,CAAC;AAAA,GAAM,MAAM;AAAA,EACnE;AAAA,EAEA,MAAc,OAAyC;AACrD,QAAI,KAAK,UAAU,KAAK,MAAO,QAAO,KAAK;AAC3C,UAAMA,MAAK,MAAM,OAAO,aAAkB;AAC1C,UAAM,OAAO,MAAM,OAAO,MAAW;AACrC,UAAM,QAAQ,IAAI,wBAAwB;AAC1C,QAAI;AACF,YAAM,UAAU,MAAMA,IAAG,QAAQ,KAAK,GAAG;AAIzC,YAAM,SAAS,QAAQ,OAAO,CAAC,MAAM,EAAE,SAAS,SAAS,CAAC,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,cAAc,CAAC,CAAC;AAC7F,iBAAW,QAAQ,QAAQ;AACzB,cAAM,OAAO,KAAK,KAAK,KAAK,KAAK,IAAI;AACrC,cAAM,UAAU,MAAMA,IAAG,SAAS,MAAM,MAAM;AAC9C,cAAM,OAAO,KAAK,MAAM,GAAG,EAAE,CAAC;AAC9B,mBAAW,QAAQ,QAAQ,MAAM,IAAI,GAAG;AACtC,cAAI,CAAC,KAAK,KAAK,EAAG;AAClB,cAAI;AACJ,cAAI;AACF,qBAAS,KAAK,MAAM,IAAI;AAAA,UAC1B,QAAQ;AAEN;AAAA,UACF;AACA,cAAI,SAAS,eAAe;AAC1B,kBAAM,MAAM,eAAe,MAAoB;AAAA,UACjD,WAAW,SAAS,QAAQ;AAC1B,kBAAM,MAAM,QAAQ,MAAa;AAAA,UACnC;AAAA,QACF;AAAA,MACF;AAAA,IACF,QAAQ;AAAA,IAER;AACA,SAAK,QAAQ;AACb,SAAK,SAAS;AACd,WAAO;AAAA,EACT;AACF;;;AClCO,IAAM,6BAAqE;AAAA,EAChF,EAAE,MAAM,aAAa,WAAW,YAAY,OAAO,CAAC,MAAM,EAAE,cAAc;AAAA,EAC1E,EAAE,MAAM,aAAa,WAAW,YAAY,OAAO,CAAC,MAAM,EAAE,SAAS;AAAA,EACrE,EAAE,MAAM,QAAQ,WAAW,YAAY,OAAO,CAAC,MAAM,EAAE,YAAY;AAAA,EACnE,EAAE,MAAM,QAAQ,WAAW,YAAY,OAAO,CAAC,MAAM,EAAE,gBAAgB;AACzE;AAEA,eAAsB,qBACpB,QACkC;AAClC,QAAM,OAAO,UAAU,MAAM;AAC7B,QAAM,SAAS,IAAI,UAAU,EAAE,SAAS,OAAO,QAAQ,CAAC;AACxD,QAAM,QAAQ,OAAO,UAAU,CAAC,UAAoB,OAAO,WAAW,KAAK;AAC3E,QAAM,UAAU,MAAM,SAAS,MAAM,OAAO,eAAe,GAAG,OAAO,YAAY;AAC/E,UAAM,QAAQ,MAAM,OAAO,QAAQ,IAAI,OAAO;AAC9C,UAAMC,YAAW,MAAM,MAAM,OAAO,OAAO;AAC3C,UAAM,SAA2B;AAAA,MAC/B,SAAS,QAAQ;AAAA,MACjB,UAAU,QAAQ;AAAA,MAClB,YAAY,QAAQ;AAAA,MACpB;AAAA,MACA,OAAOA;AAAA,MACP,WAAW,kBAAkBA,WAAU,OAAO,OAAO;AAAA,IACvD;AACA,UAAM,OAAO,WAAW,MAAM;AAC9B,WAAO;AAAA,EACT,CAAC;AACD,SAAO,EAAE,SAAS,WAAW,qBAAqB,SAAS,OAAO,UAAU,EAAE;AAChF;AAEO,SAAS,qBACd,SACA,aAAqD,4BACnC;AAClB,QAAM,UAAU,wBAAwB,OAAO;AAC/C,MAAI,QAAQ,WAAW,EAAG,OAAM,IAAI,MAAM,kCAAkC;AAC5E,QAAM,WAAW,eAAe,SAAS,UAAU;AACnD,QAAM,aAAa,SAAS,SAAS,SAAS,SAAS,WAAW;AAClE,QAAM,SAAS,CAAC,GAAG,UAAU,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,gBAAgB,EAAE,aAAa,EAAE,CAAC;AAClF,MAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,iCAAiC;AAC9D,SAAO,EAAE,QAAQ,UAAU,QAAQ;AACrC;AAEO,SAAS,wBAAwB,SAAqD;AAC3F,QAAM,YAAY,oBAAI,IAAgC;AACtD,aAAW,UAAU,SAAS;AAC5B,cAAU,IAAI,OAAO,QAAQ,IAAI,CAAC,GAAI,UAAU,IAAI,OAAO,QAAQ,EAAE,KAAK,CAAC,GAAI,MAAM,CAAC;AAAA,EACxF;AACA,SAAO,CAAC,GAAG,UAAU,OAAO,CAAC,EAC1B,IAAI,CAAC,SAAS;AACb,UAAM,UAAU,KAAK,CAAC,GAAG;AACzB,QAAI,CAAC,QAAS,OAAM,IAAI,MAAM,+CAA+C;AAC7E,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,eAAeC,MAAK,KAAK,IAAI,CAAC,MAAM,EAAE,SAAS,CAAC;AAAA,MAChD,UAAUA,MAAK,KAAK,IAAI,CAAC,MAAM,EAAE,MAAM,OAAO,CAAC;AAAA,MAC/C,aAAaA,MAAK,KAAK,IAAI,CAAC,MAAM,EAAE,MAAM,OAAO,CAAC;AAAA,MAClD,iBAAiBA,MAAK,KAAK,IAAI,CAAC,MAAM,EAAE,MAAM,WAAW,CAAC;AAAA,MAC1D,WAAW,aAAa,KAAK,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC;AAAA,IAClD;AAAA,EACF,CAAC,EACA,KAAK,CAAC,GAAG,MAAM,EAAE,gBAAgB,EAAE,aAAa;AACrD;AAEA,SAAS,UAAU,QAAsD;AACvE,MAAI,OAAO,SAAS,WAAW;AAC7B,UAAM,IAAI,MAAM,qDAAqD;AACvE,MAAI,OAAO,UAAU,WAAW;AAC9B,UAAM,IAAI,MAAM,sDAAsD;AACxE,QAAM,SAAS,KAAK,IAAI,GAAG,KAAK,MAAM,OAAO,qBAAqB,CAAC,CAAC;AACpE,QAAM,OAA4B,CAAC;AACnC,aAAW,WAAW,OAAO,UAAU;AACrC,eAAW,YAAY,OAAO,WAAW;AACvC,eAAS,aAAa,GAAG,aAAa,QAAQ,cAAc;AAC1D,aAAK,KAAK,EAAE,SAAS,UAAU,WAAW,CAAC;AAAA,MAC7C;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAEA,eAAe,SACb,OACA,OACA,IACc;AACd,QAAM,UAAe,IAAI,MAAM,MAAM,MAAM;AAC3C,MAAI,OAAO;AACX,QAAM,cAAc,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC;AACzE,QAAM,QAAQ;AAAA,IACZ,MAAM,KAAK,EAAE,QAAQ,YAAY,GAAG,YAAY;AAC9C,aAAO,OAAO,MAAM,QAAQ;AAC1B,cAAM,QAAQ;AACd,cAAM,OAAO,MAAM,KAAK;AACxB,YAAI,SAAS,OAAW;AACxB,gBAAQ,KAAK,IAAI,MAAM,GAAG,IAAI;AAAA,MAChC;AAAA,IACF,CAAC;AAAA,EACH;AACA,SAAO;AACT;AAEA,SAASA,MAAK,QAA0B;AACtC,SAAO,OAAO,SAAS,OAAO,OAAO,CAACC,MAAK,UAAUA,OAAM,OAAO,CAAC,IAAI,OAAO,SAAS;AACzF;AAEA,SAAS,aAAaC,SAA8B;AAClD,SAAO;AAAA,IACL,SAASF,MAAKE,QAAO,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC;AAAA,IAC1C,cAAcF,MAAKE,QAAO,IAAI,CAAC,MAAM,EAAE,YAAY,CAAC;AAAA,IACpD,kBAAkBF,MAAKE,QAAO,IAAI,CAAC,MAAM,EAAE,gBAAgB,CAAC;AAAA,IAC5D,cAAcF,MAAKE,QAAO,IAAI,CAAC,MAAM,EAAE,YAAY,CAAC;AAAA,IACpD,gBAAgBF,MAAKE,QAAO,IAAI,CAAC,MAAM,EAAE,cAAc,CAAC;AAAA,IACxD,cAAcF,MAAKE,QAAO,IAAI,CAAC,MAAM,EAAE,YAAY,CAAC;AAAA,IACpD,aAAaF,MAAKE,QAAO,IAAI,CAAC,MAAM,EAAE,WAAW,CAAC;AAAA,IAClD,WAAWF,MAAKE,QAAO,IAAI,CAAC,MAAM,EAAE,SAAS,CAAC;AAAA,IAC9C,kBAAkBF,MAAKE,QAAO,IAAI,CAAC,MAAM,EAAE,gBAAgB,CAAC;AAAA,IAC5D,SAASF,MAAKE,QAAO,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC;AAAA,IAC1C,aAAaF,MAAKE,QAAO,IAAI,CAAC,MAAM,EAAE,WAAW,CAAC;AAAA,IAClD,OAAOA,QAAO,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;AAAA,EAC5C;AACF;;;AC7LO,IAAM,cAAN,MAAkB;AAAA,EACN;AAAA,EAEjB,YAAY,SAAwB,IAAI,wBAAwB,GAAG;AACjE,SAAK,SAAS;AAAA,EAChB;AAAA,EAEA,MAAM,IAAI,MAAqD;AAC7D,UAAM,QAAQ,IAAI,mBAAmB;AACrC,UAAM,UAAU,IAAI,aAAa,OAAO,EAAE,OAAO,SAAS,KAAK,EAAE,GAAG,CAAC;AACrE,UAAM,QAAQ,SAAS;AAAA,MACrB,YAAY,KAAK;AAAA,MACjB,OAAO;AAAA,MACP,WAAW;AAAA,IACb,CAAC;AACD,UAAM,UAAU,IAAI,eAAe,KAAK,MAAM;AAC9C,UAAM,SAAS,MAAM,QAAQ,IAAI,KAAK,QAAQ,OAAO;AACrD,UAAM,QAAQ,OAAO,EAAE,MAAM,OAAO,QAAQ,OAAO,OAAO,OAAO,OAAO,GAAG,KAAK,IAAI,SAAS,CAAC;AAC9F,WAAO;AAAA,MACL,IAAI,KAAK;AAAA,MACT,MAAM,KAAK;AAAA,MACX,QAAQ,OAAO;AAAA,MACf,OAAO,OAAO;AAAA,MACd,SAAS,mBAAmB,KAAK,MAAM,MAAM;AAAA,MAC7C;AAAA,IACF;AAAA,EACF;AACF;AAEA,eAAsB,cACpB,OACA,UAA6B,CAAC,GACC;AAC/B,QAAM,SAAS,IAAI,YAAY,QAAQ,MAAM;AAC7C,MAAI,QAAQ,aAAa,OAAO;AAC9B,UAAM,UAAgC,CAAC;AACvC,eAAW,QAAQ,MAAO,SAAQ,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC;AAC7D,WAAO;AAAA,EACT;AACA,SAAO,MAAM,QAAQ,IAAI,MAAM,IAAI,CAAC,SAAS,OAAO,IAAI,IAAI,CAAC,CAAC;AAChE;AAEO,SAAS,cAAc,IAAY,QAAyC;AACjF,SAAO,EAAE,IAAI,MAAM,YAAY,OAAO;AACxC;AAEO,SAAS,UAAU,IAAY,QAAyC;AAC7E,SAAO,EAAE,IAAI,MAAM,QAAQ,OAAO;AACpC;AAEO,SAAS,YAAY,IAAY,QAAyC;AAC/E,SAAO,EAAE,IAAI,MAAM,UAAU,OAAO;AACtC;AAEO,SAAS,cAAc,IAAY,QAAyC;AACjF,SAAO,EAAE,IAAI,MAAM,YAAY,OAAO;AACxC;AAEA,SAAS,mBAAmB,MAAwB,QAAsC;AACxF,MAAI,CAAC,OAAO,OAAQ,QAAO,GAAG,IAAI;AAClC,MAAI,OAAO,MAAM;AACf,WAAO,GAAG,IAAI,iBAAiB,OAAO,KAAK,WAAW,IAAI,OAAO,KAAK,UAAU;AAClF,SAAO,GAAG,IAAI;AAChB;;;AClFO,SAAS,gBACd,SACA,UAAmC,CAAC,GAC1B;AACV,QAAM,aAAa,QAAQ,cAAc;AACzC,QAAM,gBAAgB,oBAAI,IAA2B;AAErD,aAAW,SAAS,SAAS;AAC3B,UAAM,MAAM,qBAAqB,MAAM,WAAW;AAClD,UAAM,WAAW,cAAc,IAAI,GAAG;AACtC,QAAI,CAAC,aAAa,MAAM,UAAU,MAAM,SAAS,UAAU,IAAI;AAC7D,oBAAc,IAAI,KAAK,EAAE,GAAG,OAAO,aAAa,qBAAqB,MAAM,WAAW,EAAE,CAAC;AAAA,IAC3F;AAAA,EACF;AAEA,QAAM,YAAY,CAAC,GAAG,cAAc,OAAO,CAAC,EACzC,KAAK,CAAC,GAAG,OAAO,EAAE,UAAU,MAAM,EAAE,UAAU,EAAE,EAChD,MAAM,GAAG,UAAU;AAEtB,SAAO,EAAE,SAAS,UAAU;AAC9B;AAEO,SAAS,uBAAuB,UAA4B;AACjE,QAAM,QAAQ,CAAC,cAAc,EAAE;AAC/B,aAAW,SAAS,SAAS,SAAS;AACpC,UAAM,KAAK,KAAK,MAAM,WAAW,EAAE;AACnC,UAAM,KAAK,gBAAgB,MAAM,SAAS,EAAE;AAC5C,QAAI,MAAM,SAAU,OAAM,KAAK,eAAe,MAAM,QAAQ,EAAE;AAC9D,QAAI,MAAM,SAAU,OAAM,KAAK,eAAe,MAAM,QAAQ,EAAE;AAC9D,QAAI,MAAM,YAAa,OAAM,KAAK,iBAAiB,MAAM,WAAW,EAAE;AACtE,UAAM,KAAK,EAAE;AAAA,EACf;AACA,SAAO,GAAG,MAAM,KAAK,IAAI,EAAE,KAAK,CAAC;AAAA;AACnC;AAEA,SAAS,qBAAqB,OAAuB;AACnD,SAAO,MAAM,KAAK,EAAE,YAAY,EAAE,QAAQ,QAAQ,GAAG;AACvD;AAEA,SAAS,qBAAqB,OAAuB;AACnD,QAAM,aAAa,MAAM,KAAK,EAAE,QAAQ,QAAQ,GAAG;AACnD,SAAO,WAAW,WAAW,IAAI,aAAa,WAAW,CAAC,EAAG,YAAY,IAAI,WAAW,MAAM,CAAC;AACjG;;;ACIA,SAAS,aAAa,UAAsC;AAC1D,MAAI,CAAC,SAAU,QAAO;AACtB,MAAI,SAAS,SAAS,MAAM,EAAG,QAAO;AACtC,MAAI,SAAS,WAAW,OAAO,EAAG,QAAO;AACzC,SAAO;AACT;AAYO,SAAS,qBAAqB,QAAoD;AACvF,QAAM,YAAwB,CAAC;AAC/B,QAAM,YAAgC,CAAC;AACvC,QAAM,YAAsB,CAAC;AAC7B,QAAM,YAAY,oBAAI,IAAY;AAElC,aAAW,MAAM,QAAQ;AACvB,QAAI,GAAG,SAAS,aAAa;AAC3B,YAAM,OAAQ,GAAyB;AACvC,UAAI,QAAQ,CAAC,UAAU,IAAI,IAAI,GAAG;AAChC,kBAAU,IAAI,IAAI;AAClB,kBAAU,KAAK,IAAI;AAAA,MACrB;AAAA,IACF,WAAW,GAAG,SAAS,YAAY;AACjC,YAAM,IAAI;AACV,gBAAU,KAAK;AAAA,QACb,MAAM,aAAa,EAAE,QAAQ;AAAA,QAC7B,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE;AAAA,QAC3B,SAAS,EAAE,WAAW;AAAA,MACxB,CAAC;AAAA,IACH,WAAW,GAAG,SAAS,oBAAoB;AACzC,YAAM,IAAI;AACV,gBAAU,KAAK,EAAE,IAAI,EAAE,YAAY,OAAO,EAAE,OAAO,QAAQ,EAAE,UAAU,UAAU,CAAC;AAAA,IACpF;AAAA,EACF;AAEA,SAAO,EAAE,WAAW,WAAW,UAAU;AAC3C;;;AChFO,IAAM,iBAAN,MAAqB;AAAA,EACT,UAAU,oBAAI,IAA0B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOzD,MAAM,SAAS,IAAY,SAAiB,SAAwC;AAClF,eAAW,EAAE;AACb,oBAAgB,OAAO;AAEvB,UAAM,MAAM,QAAQ,IAAI,OAAO;AAC/B,UAAM,OAAO,MAAM,YAAY,OAAO;AACtC,UAAM,WAAW,KAAK,QAAQ,IAAI,GAAG;AACrC,QAAI,UAAU;AACZ,UAAI,SAAS,SAAS,MAAM;AAC1B,cAAM,IAAI;AAAA,UACR,UAAU,GAAG,8CAA8C,SAAS,IAAI,OAAO,IAAI;AAAA,QACrF;AAAA,MACF;AACA,aAAO;AAAA,IACT;AACA,UAAM,SAAuB,EAAE,IAAI,SAAS,MAAM,QAAQ;AAC1D,SAAK,QAAQ,IAAI,KAAK,MAAM;AAC5B,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,IAAI,IAAY,SAA+B;AAC7C,UAAM,MAAM,QAAQ,IAAI,OAAO;AAC/B,UAAM,SAAS,KAAK,QAAQ,IAAI,GAAG;AACnC,QAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,UAAU,GAAG,iBAAiB;AAC3D,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,aAAa,IAA4B;AACvC,WAAO,CAAC,GAAG,KAAK,QAAQ,OAAO,CAAC,EAC7B,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE,EACzB,KAAK,CAAC,GAAG,MAAM,EAAE,QAAQ,cAAc,EAAE,OAAO,CAAC;AAAA,EACtD;AAAA;AAAA,EAGA,OAAuB;AACrB,WAAO,CAAC,GAAG,KAAK,QAAQ,OAAO,CAAC;AAAA,EAClC;AAAA;AAAA,EAGA,WAAW,IAAY,SAAiB,cAAsC;AAC5E,UAAM,SAAS,KAAK,QAAQ,IAAI,QAAQ,IAAI,OAAO,CAAC;AACpD,QAAI,CAAC,OAAQ,QAAO;AACpB,WAAO,OAAO,SAAS;AAAA,EACzB;AACF;AAGA,eAAsB,YAAY,SAAkC;AAClE,QAAM,QAAQ,IAAI,YAAY,EAAE,OAAO,OAAO;AAC9C,QAAM,SAAS,MAAM,OAAO,OAAO,OAAO,WAAW,KAAK;AAC1D,QAAM,OAAO,MAAM,KAAK,IAAI,WAAW,MAAM,CAAC,EAC3C,IAAI,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG,CAAC,EAC1C,KAAK,EAAE;AACV,SAAO,KAAK,MAAM,GAAG,EAAE;AACzB;AAEA,SAAS,QAAQ,IAAY,SAAyB;AACpD,SAAO,GAAG,EAAE,IAAI,OAAO;AACzB;AAEA,IAAM,QAAQ;AACd,SAAS,WAAW,IAAkB;AACpC,MAAI,CAAC,MAAM,KAAK,EAAE,GAAG;AACnB,UAAM,IAAI,MAAM,sBAAsB,EAAE,iBAAiB,KAAK,EAAE;AAAA,EAClE;AACF;AAEA,SAAS,gBAAgB,SAAuB;AAC9C,MAAI,CAAC,WAAW,QAAQ,SAAS,IAAI;AACnC,UAAM,IAAI,MAAM,oBAAoB,OAAO,4BAAuB;AAAA,EACpE;AACF;;;AChFO,SAAS,oBAAoB,MAAsB,OAAsC;AAC9F,SAAO;AAAA,IACL,GAAG;AAAA,IACH,GAAI,MAAM,gBAAgB,SAAY,EAAE,aAAa,MAAM,YAAY,IAAI,CAAC;AAAA,IAC5E,GAAI,MAAM,mBAAmB,SAAY,EAAE,gBAAgB,MAAM,eAAe,IAAI,CAAC;AAAA,IACrF,iBAAiB;AAAA,MACf,GAAI,KAAK,mBAAmB,CAAC;AAAA,MAC7B,GAAI,MAAM,mBAAmB,CAAC;AAAA,IAChC;AAAA,IACA,QAAQ,MAAM,UAAU,KAAK;AAAA,IAC7B,aAAa;AAAA,MACX,GAAI,KAAK,eAAe,CAAC;AAAA,MACzB,GAAI,MAAM,eAAe,CAAC;AAAA,IAC5B;AAAA,IACA,UAAU;AAAA,MACR,GAAI,KAAK,YAAY,CAAC;AAAA,MACtB,GAAI,MAAM,YAAY,CAAC;AAAA,IACzB;AAAA,EACF;AACF;AAEO,SAAS,mBAAmB,QAAgC;AACjE,QAAM,QAAkB,CAAC,UAAU,OAAO,EAAE,EAAE;AAC9C,MAAI,OAAO,YAAa,OAAM,KAAK,SAAS,OAAO,WAAW,EAAE;AAChE,MAAI,OAAO,eAAgB,OAAM,KAAK,YAAY,OAAO,cAAc,EAAE;AACzE,QAAM,YAAY,OAAO,QAAQ,OAAO,mBAAmB,CAAC,CAAC,EAAE;AAAA,IAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAC1E,EAAE,cAAc,CAAC;AAAA,EACnB;AACA,aAAW,CAAC,MAAM,MAAM,KAAK,UAAW,OAAM,KAAK,YAAY,IAAI,IAAI,MAAM,EAAE;AAC/E,QAAM,SAAS,CAAC,GAAI,OAAO,UAAU,CAAC,CAAE,EAAE,KAAK;AAC/C,MAAI,OAAO,OAAQ,OAAM,KAAK,UAAU,OAAO,KAAK,GAAG,CAAC,EAAE;AAC1D,SAAO,MAAM,KAAK,IAAI;AACxB;;;ACoCO,IAAM,4BAAN,MAAgC;AAAA,EACrC,SACE,MACA,SAAkC,CAAC,GACP;AAC5B,UAAM,SAAS,SAAS,MAAM,OAAO,OAAO;AAC5C,QAAI,CAAC,OAAO,OAAQ,OAAM,IAAI,MAAM,+BAA+B;AACnE,WAAO;AAAA,MACL,SAAS;AAAA,MACT,sBAAsB,OAAO,CAAC,EAAG;AAAA,MACjC,WAAW,0CAA0C,KAAK,MAAM;AAAA,MAChE,UAAU;AAAA,IACZ;AAAA,EACF;AACF;AAEO,IAAM,0BAAN,MAA8B;AAAA,EACnC,YAA6B,QAAmC;AAAnC;AAAA,EAAoC;AAAA,EAApC;AAAA,EAE7B,MAAM,SAAS,MAAsE;AACnF,UAAM,WAAW,IAAI,0BAA0B,EAAE,SAAS,MAAM,KAAK,MAAM;AAC3E,UAAM,UAAU,KAAK,OAAO,WAAW;AACvC,UAAM,aAAa,CAAC,GAAG,IAAI,IAAI,KAAK,IAAI,CAAC,QAAQ,IAAI,SAAS,CAAC,CAAC;AAChE,UAAM,aAAa,wBAAwB,MAAM,KAAK,OAAO,OAAO;AACpE,QAAI,WAAW,SAAS,KAAK,WAAW,SAAS,SAAS;AACxD,aAAO;AAAA,QACL,GAAG;AAAA,QACH,SAAS;AAAA,QACT,SAAS;AAAA,QACT,WAAW,2CAA2C,OAAO,0BAA0B,WAAW,MAAM,mBAAmB,WAAW,MAAM;AAAA,MAC9I;AAAA,IACF;AAEA,QAAI;AACJ,QAAI;AACF,cAAS,MAAM,OAAO,YAAY;AAAA,IACpC,QAAQ;AACN,aAAO;AAAA,QACL,GAAG;AAAA,QACH,SAAS;AAAA,QACT,SAAS;AAAA,QACT,WAAW;AAAA,MACb;AAAA,IACF;AAEA,UAAM,EAAE,IAAI,IAAI,OAAO,IAAI;AAC3B,UAAM,YAAY,qEAAqE,WAAW,KAAK,IAAI,CAAC;AAC5G,UAAM,WAAW,GAAG,WAAW;AAAA,MAC7B,aAAa;AAAA,IACf,CAAC;AACD,UAAM,aAAa,KAAK,IAAI,GAAG,KAAK,MAAM,WAAW,SAAS,GAAG,CAAC;AAClE,UAAM,QAAQ,WAAW,MAAM,GAAG,UAAU;AAC5C,UAAM,aAAa,WAAW,MAAM,UAAU;AAC9C,QAAI,CAAC,WAAW,QAAQ;AACtB,aAAO;AAAA,QACL,GAAG;AAAA,QACH,SAAS;AAAA,QACT,SAAS;AAAA,QACT,WAAW;AAAA,MACb;AAAA,IACF;AAEA,UAAM,YAAY,IAAI,OAAO;AAAA,MAC3B,WAAW,gBAAgB,IAAI,KAAK,OAAO,UAAU,KAAK,OAAO,QAAQ,KAAK,OAAO,KAAK;AAAA,MAC1F,WAAW;AAAA,QACT;AAAA,QACA,KAAK,OAAO;AAAA,QACZ,KAAK,OAAO;AAAA,QACZ,KAAK,OAAO,gBAAgB,KAAK,OAAO;AAAA,MAC1C;AAAA,MACA,WAAW;AAAA,MACX,WAAW;AAAA,MACX,eAAe;AAAA,MACf,qBAAqB;AAAA,MACrB,aAAa;AAAA,IACf,CAAC;AAED,UAAM,WAAW,MAAM,UAAU;AAAA,MAC/B;AAAA,MACA;AAAA,MACA,CAAC,EAAE,YAAY,QAAQ,MAAO,YAAY,cAAc,SAAS,YAAY,IAAI;AAAA,MACjF;AAAA,QACE,oBAAoB;AAAA,QACpB,gBAAgB;AAAA,MAClB;AAAA,IACF;AACA,QAAI,SAAS,qBAAqB,QAAW;AAC3C,eAAS,kBAAkB,SAAS,gBAAgB;AAAA,IACtD;AAEA,WAAO;AAAA,MACL,GAAG;AAAA,MACH,SAAS;AAAA,MACT,WAAW,0CAA0C,WAAW,MAAM,sDAAsD,SAAS,oBAAoB;AAAA,MACzJ,UAAU;AAAA,QACR,SAAS;AAAA,QACT;AAAA,QACA,QAAQ;AAAA,QACR,WAAW,SAAS,cAAc,SAAY,aAAa,SAAS,SAAS,KAAK;AAAA,MACpF;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,SAAS,MAAiC,SAAoC;AACrF,QAAM,UAAU,oBAAI,IAAsB;AAC1C,aAAW,OAAO,MAAM;AACtB,UAAM,SAAS,QAAQ,IAAI,IAAI,SAAS,KAAK,CAAC;AAC9C,WAAO,KAAK,kBAAkB,IAAI,OAAO,OAAO,CAAC;AACjD,YAAQ,IAAI,IAAI,WAAW,MAAM;AAAA,EACnC;AACA,SAAO,CAAC,GAAG,QAAQ,QAAQ,CAAC,EACzB,IAAI,CAAC,CAAC,WAAW,MAAM,OAAO;AAAA,IAC7B;AAAA,IACA,MAAM,OAAO,OAAO,CAACC,MAAK,UAAUA,OAAM,OAAO,CAAC,IAAI,OAAO;AAAA,IAC7D,MAAM,OAAO;AAAA,EACf,EAAE,EACD,KAAK,CAAC,GAAG,MAAM,EAAE,OAAO,EAAE,IAAI;AACnC;AAEA,SAAS,wBACP,MACA,SACA;AACA,QAAM,aAAa,oBAAI,IAAuC;AAC9D,aAAW,OAAO,MAAM;AACtB,UAAM,SAAS,WAAW,IAAI,IAAI,UAAU,KAAK,CAAC;AAClD,WAAO,KAAK,GAAG;AACf,eAAW,IAAI,IAAI,YAAY,MAAM;AAAA,EACvC;AACA,SAAO,CAAC,GAAG,WAAW,QAAQ,CAAC,EAAE,IAAI,CAAC,CAAC,YAAY,YAAY,MAAM;AACnE,UAAM,OAAO,aACV,IAAI,CAAC,SAAS,EAAE,KAAK,WAAW,kBAAkB,IAAI,OAAO,OAAO,EAAE,EAAE,EACxE,KAAK,CAAC,GAAG,MAAM,EAAE,YAAY,EAAE,SAAS,EAAE,CAAC;AAC9C,WAAO;AAAA,MACL,MAAM,OAAO,KAAK,IAAI,UAAU,QAAQ,KAAK,IAAI,UAAU,gBAAgB,UAAU;AAAA,MACrF,OAAO,OAAO,KAAK,IAAI,UAAU,SAAS,OAAO;AAAA,MACjD,aAAa,OAAO,KAAK,IAAI,UAAU,gBAAgB,EAAE;AAAA,MACzD,WAAW,KAAK,IAAI;AAAA,IACtB;AAAA,EACF,CAAC;AACH;AAEA,SAAS,gBACP,WACA,UACA,QACA,OACA;AACA,SAAO,UAAU;AAAA,IACf,MAAM;AAAA,IACN;AAAA,IACA,QAAQ,EAAE,MAAM;AAAA,EAClB,CAAC;AACH;;;AChNO,IAAM,6BAAN,MAA+D;AAAA,EAC3D,OAAO;AAAA,EACC,YAAY,oBAAI,IAA+B;AAAA,EAEhE,IAAI,SAAiB,UAAmC;AACtD,SAAK,UAAU,IAAI,SAAS,QAAQ;AAAA,EACtC;AAAA,EAEA,MAAM,SAAS,SAAuD;AACpE,WAAO,KAAK,UAAU,IAAI,QAAQ,OAAO,KAAK,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,GAAG,IAAI,CAAC,EAAE;AAAA,EAC9E;AACF;AAmBO,SAAS,WAAW,MAAkC;AAC3D,SAAO;AAAA,IACL,MAAM,eAAe,IAAI;AAAA,IACzB,MAAM,UAAU;AACd,YAAM,OAAO,QAAQ,SAAS;AAC9B,aAAO;AAAA,QACL;AAAA,QACA,OAAO,OAAO,IAAI;AAAA,QAClB,QAAQ,OAAO,SAAY,cAAc,IAAI;AAAA,MAC/C;AAAA,IACF;AAAA,EACF;AACF;AAEO,SAAS,aAAa,MAAc,QAAoC;AAC7E,SAAO;AAAA,IACL,MAAM,iBAAiB,IAAI,IAAI,MAAM;AAAA,IACrC,MAAM,UAAU;AACd,YAAM,UAAU,SAAS,MAAM,IAAI;AACnC,UAAI,YAAY,QAAW;AACzB,eAAO,EAAE,MAAM,OAAO,OAAO,GAAG,QAAQ,QAAQ,IAAI,WAAW;AAAA,MACjE;AACA,YAAM,OAAO,QAAQ,SAAS,MAAM;AACpC,aAAO;AAAA,QACL;AAAA,QACA,OAAO,OAAO,IAAI;AAAA,QAClB,QAAQ,OAAO,SAAY,QAAQ,IAAI,uBAAuB,MAAM;AAAA,MACtE;AAAA,IACF;AAAA,EACF;AACF;AAEO,SAAS,SAAS,OAAe,KAAa,KAAkC;AACrF,SAAO;AAAA,IACL,MAAM,aAAa,KAAK,KAAK,GAAG,IAAI,OAAO,QAAG;AAAA,IAC9C,MAAM,UAAU;AACd,YAAM,OAAO,SAAS,KAAK,KAAK,KAAK,CAAC;AACtC,YAAM,QAAQ,KAAK;AACnB,YAAM,QAAQ,OAAO;AACrB,YAAM,OAAO,SAAS,OAAO,SAAS;AACtC,YAAM,QAAQ,OAAO,IAAI,QAAQ,MAAM,KAAK,IAAI,GAAG,QAAQ,GAAG,IAAI,KAAK,IAAI,GAAG,QAAQ,KAAK;AAC3F,aAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA,QAAQ,OACJ,SACA,SAAS,KAAK,QAAQ,KAAK,oBAAoB,GAAG,KAAK,OAAO,QAAG;AAAA,MACvE;AAAA,IACF;AAAA,EACF;AACF;AAEO,SAAS,SACd,OACA,WACA,SACoB;AACpB,QAAM,MAAM,SAAS,OAAO;AAC5B,SAAO;AAAA,IACL,MAAM,aAAa,KAAK;AAAA,IACxB,MAAM,UAAU;AACd,YAAM,OAAQ,SAAS,KAAK,KAAK,KAAK,CAAC;AACvC,YAAM,WAAW,KAAK,OAAO,SAAS,EAAE;AACxC,YAAM,OAAO,YAAY;AACzB,aAAO;AAAA,QACL;AAAA,QACA,OAAO,OAAO,IAAI,KAAK,IAAI,GAAG,WAAW,GAAG;AAAA,QAC5C,QAAQ,OACJ,SACA,SAAS,KAAK,QAAQ,QAAQ,mCAA8B,GAAG;AAAA,MACrE;AAAA,IACF;AAAA,EACF;AACF;AAGO,SAAS,cACd,UACA,YAKA;AACA,QAAM,UAAU,WAAW,IAAI,CAAC,OAAO,EAAE,WAAW,EAAE,MAAM,QAAQ,EAAE,MAAM,QAAQ,EAAE,EAAE;AACxF,QAAM,OAAO,QAAQ,MAAM,CAAC,MAAM,EAAE,OAAO,IAAI;AAC/C,QAAM,QAAQ,QAAQ,SAClB,QAAQ,OAAO,CAAC,KAAK,MAAM,MAAM,EAAE,OAAO,OAAO,CAAC,IAAI,QAAQ,SAC9D;AACJ,SAAO,EAAE,MAAM,OAAO,QAAQ;AAChC;;;AChJO,IAAM,oBAAN,cAAgC,eAAe;AAAA,EACpD,YACS,WACA,OACA,WACP;AACA,UAAM,gBAAgB,oBAAoB,SAAS,eAAe,SAAS,aAAa,KAAK,EAAE;AAJxF;AACA;AACA;AAAA,EAGT;AAAA,EALS;AAAA,EACA;AAAA,EACA;AAIX;AAEO,IAAM,cAAN,MAAkB;AAAA,EACf,WAA6C,EAAE,QAAQ,GAAG,QAAQ,GAAG,OAAO,GAAG,KAAK,EAAE;AAAA,EACtF;AAAA,EACA;AAAA,EACA;AAAA,EAER,YAAY,SAAuB,QAAoB,MAAoB,MAAM,KAAK,IAAI,GAAG;AAC3F,SAAK,UAAU;AACf,SAAK,SAAS;AACd,SAAK,YAAY,IAAI;AAAA,EACvB;AAAA;AAAA,EAGA,MAAM,OAAO,OAAkD,QAAgC;AAC7F,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,KAAK,GAAwC;AACrF,UAAI,CAAC,OAAO,SAAS,KAAK,KAAK,QAAQ,GAAG;AACxC,cAAM,IAAI,MAAM,8CAA8C,GAAG,IAAI,KAAK,EAAE;AAAA,MAC9E;AACA,WAAK,SAAS,GAAG,KAAK;AACtB,YAAM,QAAQ,KAAK,OAAO,GAAG;AAC7B,YAAM,WAAW,KAAK,SAAS,GAAG;AAClC,YAAM,YAAY,UAAU,SAAY,WAAW,QAAQ;AAC3D,YAAM,WAAW,UAAU,UAAa,WAAW;AACnD,UAAI,UAAU,QAAW;AACvB,cAAM,KAAK,QAAQ,aAAa;AAAA,UAC9B,WAAW;AAAA,UACX;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF,CAAC;AAAA,MACH;AACA,UAAI,UAAU;AACZ,cAAM,IAAI,kBAAkB,KAAK,OAAQ,QAAQ;AAAA,MACnD;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,SAAS,OAAe,QAAgC;AAC5D,UAAM,UAAU,QAAQ,KAAK;AAC7B,UAAM,UAAU,KAAK,SAAS;AAC9B,UAAM,QAAQ,KAAK,IAAI,GAAG,UAAU,OAAO;AAC3C,QAAI,QAAQ,EAAG,OAAM,KAAK,OAAO,EAAE,QAAQ,MAAM,GAAG,MAAM;AAAA,EAC5D;AAAA,EAEA,IAAI,QAA0C;AAC5C,WAAO,EAAE,GAAG,KAAK,SAAS;AAAA,EAC5B;AACF;;;ACjCO,IAAM,cAAN,MAAkB;AAAA,EACf,aAAa,oBAAI,IAA0B;AAAA,EAEnD,OAAO,OAAyE;AAC9E,UAAM,OAAkB,EAAE,WAAW,MAAM,aAAa,KAAK,IAAI,GAAG,GAAG,MAAM;AAC7E,sBAAkB,KAAK,aAAa,aAAa;AACjD,sBAAkB,KAAK,cAAc,cAAc;AACnD,QAAI,SAAS,KAAK,WAAW,IAAI,KAAK,UAAU;AAChD,QAAI,CAAC,QAAQ;AACX,eAAS;AAAA,QACP,YAAY,KAAK;AAAA,QACjB,SAAS,CAAC;AAAA,QACV,kBAAkB;AAAA,QAClB,mBAAmB;AAAA,QACnB,mBAAmB;AAAA,QACnB,cAAc;AAAA,MAChB;AACA,WAAK,WAAW,IAAI,KAAK,YAAY,MAAM;AAAA,IAC7C;AACA,WAAO,QAAQ,KAAK,IAAI;AACxB,WAAO,oBAAoB,KAAK;AAChC,WAAO,qBAAqB,KAAK;AACjC,WAAO,qBAAqB,KAAK,gBAAgB;AACjD,WAAO,gBAAgB,QAAQ,IAAI;AACnC,WAAO;AAAA,EACT;AAAA,EAEA,YAAY,YAAoB,WAA0B;AACxD,UAAM,SAAS,KAAK,WAAW,IAAI,UAAU;AAC7C,QAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,8CAA8C,UAAU,GAAG;AACxF,WAAO,YAAY;AAAA,EACrB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,cACE,SAUA,YACA,MACkB;AAClB,QAAI,CAAC,QAAQ,MAAO,QAAO;AAC3B,UAAM,QAAQ,KAAK,OAAO;AAAA,MACxB;AAAA,MACA,OAAO,QAAQ,MAAM;AAAA,MACrB,aAAa,QAAQ,MAAM;AAAA,MAC3B,cAAc,QAAQ,MAAM;AAAA,MAC5B,cAAc,QAAQ,MAAM;AAAA,MAC5B,iBAAiB,QAAQ,MAAM;AAAA,MAC/B;AAAA,IACF,CAAC;AACD,SAAK,YAAY,YAAY,QAAQ,YAAY,MAAM;AACvD,WAAO;AAAA,EACT;AAAA,EAEA,IAAI,YAA8C;AAChD,WAAO,KAAK,WAAW,IAAI,UAAU;AAAA,EACvC;AAAA,EAEA,OAAuB;AACrB,WAAO,CAAC,GAAG,KAAK,WAAW,OAAO,CAAC;AAAA,EACrC;AAAA,EAEA,UAAuB;AACrB,UAAM,YAAY,KAAK,KAAK;AAC5B,UAAM,YAAY,UAAU,OAAO,CAAC,MAAM,EAAE,cAAc,IAAI;AAC9D,UAAM,YAAY,UAAU,OAAO,CAAC,GAAG,MAAM,IAAI,EAAE,cAAc,CAAC;AAClE,UAAM,aAAa,UAAU,OAAO,CAAC,GAAG,MAAM,IAAI,EAAE,kBAAkB,CAAC;AACvE,UAAM,cAAc,UAAU,OAAO,CAAC,GAAG,MAAM,IAAI,EAAE,mBAAmB,CAAC;AACzE,UAAM,qBAAqB,UAAU,OAAO,CAAC,GAAG,MAAM,IAAI,EAAE,cAAc,CAAC;AAC3E,WAAO;AAAA,MACL,eAAe,UAAU;AAAA,MACzB,gBAAgB,UAAU;AAAA,MAC1B,kBAAkB;AAAA,MAClB,mBAAmB;AAAA,MACnB,cAAc;AAAA,MACd,uBAAuB,UAAU,SAAS,YAAY,UAAU,SAAS;AAAA,MACzE,yBAAyB,UAAU,SAAS,qBAAqB,UAAU,SAAS;AAAA,IACtF;AAAA,EACF;AACF;AAaA,SAAS,QAAQ,OAA0B;AACzC,MAAI,OAAO,MAAM,kBAAkB,YAAY,OAAO,SAAS,MAAM,aAAa,GAAG;AACnF,WAAO,MAAM;AAAA,EACf;AACA,SAAO,aAAa,MAAM,aAAa,MAAM,cAAc,MAAM,KAAK;AACxE;AAEA,SAAS,kBAAkB,GAAW,MAAoB;AACxD,MAAI,CAAC,OAAO,SAAS,CAAC,KAAK,IAAI,GAAG;AAChC,UAAM,IAAI,MAAM,gBAAgB,IAAI,8CAA8C,CAAC,EAAE;AAAA,EACvF;AACF;;;ACpIA,SAAS,cAAAC,aAAY,eAAAC,cAAa,gBAAAC,eAAc,YAAAC,iBAAgB;AAChE,SAAS,QAAAC,aAAY;AAqCrB,SAAS,OAAO,MAAsB;AACpC,SAAO,KAAK,QAAQ,WAAW,EAAE,EAAE,QAAQ,aAAa,EAAE;AAC5D;AAGA,SAAS,WAAW,MAAuB;AACzC,SAAO,KAAK,SAAS,YAAY;AACnC;AAMO,IAAM,qBAAoC,CAAC,MAAM,SAAS;AAC/D,QAAM,MAAwB,CAAC;AAC/B,QAAM,QAAQ,KAAK,MAAM,IAAI;AAC7B,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,UAAM,OAAO,MAAM,CAAC;AACpB,QAAI,WAAW,IAAI,EAAG;AACtB,UAAM,OAAO,OAAO,IAAI;AACxB,QAAI,CAAC,KAAK,KAAK,EAAG;AAClB,QAAI,YAAY,KAAK,IAAI,KAAK,yCAAyC,KAAK,IAAI,GAAG;AACjF,UAAI,KAAK;AAAA,QACP;AAAA,QACA,MAAM,IAAI;AAAA,QACV,UAAU,KAAK,KAAK;AAAA,QACpB,SAAS;AAAA,MACX,CAAC;AAAA,IACH;AAAA,EACF;AACA,SAAO;AACT;AAMO,IAAM,sBAAqC,CAAC,MAAM,SAAS;AAChE,QAAM,MAAwB,CAAC;AAC/B,QAAM,QAAQ,KAAK,MAAM,IAAI;AAC7B,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,UAAM,OAAO,MAAM,CAAC;AACpB,QAAI,WAAW,IAAI,EAAG;AACtB,UAAM,OAAO,OAAO,IAAI;AACxB,QAAI,CAAC,KAAK,KAAK,EAAG;AAClB,QAAI,iCAAiC,KAAK,IAAI,GAAG;AAC/C,UAAI,KAAK;AAAA,QACP;AAAA,QACA,MAAM,IAAI;AAAA,QACV,UAAU,KAAK,KAAK;AAAA,QACpB,SAAS;AAAA,MACX,CAAC;AAAA,IACH;AAAA,EACF;AACA,SAAO;AACT;AAQO,IAAM,4BAA2C,CAAC,MAAM,SAAS;AACtE,QAAM,MAAwB,CAAC;AAC/B,QAAM,QAAQ,KAAK,MAAM,IAAI;AAC7B,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,UAAM,OAAO,MAAM,CAAC;AACpB,QAAI,WAAW,IAAI,EAAG;AACtB,UAAM,OAAO,OAAO,IAAI;AACxB,QAAI,CAAC,KAAK,KAAK,EAAG;AAClB,QAAI,sDAAsD,KAAK,IAAI,GAAG;AACpE,UAAI,KAAK;AAAA,QACP;AAAA,QACA,MAAM,IAAI;AAAA,QACV,UAAU,KAAK,KAAK;AAAA,QACpB,SACE;AAAA,MACJ,CAAC;AAAA,IACH;AAAA,EACF;AACA,SAAO;AACT;AAMO,IAAM,6BAA4C,CAAC,MAAM,SAAS;AACvE,QAAM,MAAwB,CAAC;AAC/B,QAAM,QAAQ,KAAK,MAAM,IAAI;AAC7B,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,UAAM,OAAO,MAAM,CAAC;AACpB,QAAI,WAAW,IAAI,EAAG;AACtB,UAAM,OAAO,OAAO,IAAI;AACxB,QAAI,CAAC,KAAK,KAAK,EAAG;AAClB,QAAI,2CAA2C,KAAK,IAAI,GAAG;AACzD,UAAI,KAAK;AAAA,QACP;AAAA,QACA,MAAM,IAAI;AAAA,QACV,UAAU,KAAK,KAAK;AAAA,QACpB,SAAS;AAAA,MACX,CAAC;AAAA,IACH;AAAA,EACF;AACA,SAAO;AACT;AAOO,IAAM,uBAAsC,CAAC,MAAM,SAAS;AACjE,QAAM,MAAwB,CAAC;AAC/B,QAAM,QAAQ,KAAK,MAAM,IAAI;AAC7B,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,UAAM,OAAO,MAAM,CAAC;AACpB,QAAI,WAAW,IAAI,EAAG;AACtB,UAAM,OAAO,OAAO,IAAI;AACxB,QAAI,CAAC,KAAK,KAAK,EAAG;AAClB,QAAI,8CAA8C,KAAK,IAAI,GAAG;AAC5D,UAAI,KAAK;AAAA,QACP;AAAA,QACA,MAAM,IAAI;AAAA,QACV,UAAU,KAAK,KAAK;AAAA,QACpB,SAAS;AAAA,MACX,CAAC;AAAA,IACH;AAAA,EACF;AACA,SAAO;AACT;AAMO,IAAM,kBAAmC;AAAA,EAC9C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAGO,IAAM,oBAAqC,CAAC,yBAAyB;AAM5E,SAAS,oBACP,UACA,OACA,YACA,gBACU;AACV,QAAM,UAAoB,CAAC;AAC3B,QAAM,OAAO,CAAC,QAAgB;AAC5B,UAAM,MAAMA,MAAK,UAAU,GAAG;AAC9B,QAAI,CAACJ,YAAW,GAAG,EAAG;AACtB,eAAW,SAASC,aAAY,GAAG,GAAG;AACpC,YAAM,MAAMG,MAAK,KAAK,KAAK;AAC3B,YAAM,SAASA,MAAK,UAAU,GAAG;AACjC,UAAI;AACJ,UAAI;AACF,aAAKD,UAAS,MAAM;AAAA,MACtB,QAAQ;AACN;AAAA,MACF;AACA,UAAI,GAAG,YAAY,GAAG;AACpB,YACE,UAAU,kBACV,UAAU,UACV,UAAU,gBACV,MAAM,WAAW,GAAG;AAEpB;AACF,aAAK,GAAG;AAAA,MACV,WAAW,GAAG,OAAO,KAAK,WAAW,KAAK,KAAK,GAAG;AAChD,YAAI,MAAM,SAAS,UAAU,KAAK,MAAM,SAAS,WAAW,KAAK,MAAM,SAAS,UAAU;AACxF;AACF,YAAI;AACJ,YAAI;AACF,iBAAOD,cAAa,QAAQ,MAAM;AAAA,QACpC,QAAQ;AACN;AAAA,QACF;AACA,YAAI,KAAK,SAAS,cAAc,EAAG,SAAQ,KAAK,GAAG;AAAA,MACrD;AAAA,IACF;AAAA,EACF;AACA,aAAW,KAAK,MAAO,MAAK,CAAC;AAC7B,SAAO;AACT;AAMO,SAAS,oBAAoB,MAAqC;AACvE,QAAM,WAA6B,CAAC;AACpC,QAAM,UAAU,oBAAI,IAAY;AAGhC,aAAW,QAAQ,KAAK,WAAW;AACjC,UAAM,MAAME,MAAK,KAAK,UAAU,IAAI;AACpC,QAAI,CAACJ,YAAW,GAAG,EAAG;AACtB,UAAM,OAAOE,cAAa,KAAK,MAAM;AACrC,eAAW,QAAQ,KAAK,QAAS,UAAS,KAAK,GAAG,KAAK,MAAM,IAAI,CAAC;AAClE,YAAQ,IAAI,IAAI;AAAA,EAClB;AAGA,MAAI,KAAK,YAAY;AACnB,UAAM,YAAY;AAAA,MAChB,KAAK;AAAA,MACL,KAAK,WAAW;AAAA,MAChB,KAAK,WAAW;AAAA,MAChB,KAAK,WAAW;AAAA,IAClB;AACA,eAAW,QAAQ,WAAW;AAC5B,UAAI,QAAQ,IAAI,IAAI,EAAG;AACvB,YAAM,MAAME,MAAK,KAAK,UAAU,IAAI;AACpC,UAAI,CAACJ,YAAW,GAAG,EAAG;AACtB,YAAM,OAAOE,cAAa,KAAK,MAAM;AACrC,iBAAW,QAAQ,KAAK,WAAW,iBAAkB,UAAS,KAAK,GAAG,KAAK,MAAM,IAAI,CAAC;AAAA,IACxF;AAAA,EACF;AAEA,SAAO;AACT;AAMO,SAAS,eAAe,UAAoC;AACjE,MAAI,SAAS,WAAW,EAAG,QAAO;AAClC,SAAO;AAAA,IACL,SAAS,SAAS,MAAM;AAAA,IACxB;AAAA,IACA;AAAA,IACA,GAAG,SAAS,IAAI,CAAC,MAAM,KAAK,EAAE,IAAI,IAAI,EAAE,IAAI,WAAM,EAAE,OAAO;AAAA,MAAS,EAAE,QAAQ,EAAE;AAAA,EAClF,EAAE,KAAK,IAAI;AACb;;;ACrRO,SAAS,eAAe,QAAgB,OAAoC,CAAC,GAAW;AAC7F,QAAM,KAAK,oBAAoB,MAAM;AACrC,SAAO;AAAA,IACL;AAAA,IACA,MAAM,KAAK;AACT,YAAM,MAAM,IAAI,QAAQ;AACxB,YAAM,QAAQ,KAAK,gBACf,IAAI,SAAS,MAAM,IACnB,IAAI,YAAY,EAAE,SAAS,OAAO,YAAY,CAAC;AACnD,aAAO;AAAA,QACL;AAAA,QACA,MAAM;AAAA,QACN,QAAQ,QAAQ,IAAI,MAAM,YAAY,IAAI,MAAM;AAAA,QAChD,UAAU,QAAQ,QAAQ,KAAK,QAAQ,KAAK,aAAa,IAAI;AAAA,MAC/D;AAAA,IACF;AAAA,EACF;AACF;AAEO,SAAS,YAAY,UAA0B;AACpD,QAAM,KAAK,gBAAgB,QAAQ;AACnC,SAAO;AAAA,IACL;AAAA,IACA,MAAM,KAAK;AACT,YAAM,MAAM,IAAI,OAAO;AACvB,YAAM,OAAO,IAAI,YAAY,EAAE,SAAS,SAAS,YAAY,CAAC;AAC9D,aAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA,QAAQ,OAAO,WAAW,GAAG,MAAM,QAAQ,GAAG,cAAc,QAAQ;AAAA,QACpE,UAAU;AAAA,MACZ;AAAA,IACF;AAAA,EACF;AACF;AAEO,SAAS,UAAU,UAA2C;AACnE,QAAM,KAAK,cAAc,OAAO,KAAK,QAAQ,EAAE,KAAK,GAAG,CAAC;AACxD,SAAO;AAAA,IACL;AAAA,IACA,MAAM,KAAK;AACT,YAAM,OAAO,IAAI;AACjB,UAAI,CAAC,SAAS,IAAI,GAAG;AACnB,eAAO,EAAE,IAAI,MAAM,OAAO,QAAQ,4CAA4C;AAAA,MAChF;AACA,iBAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,QAAQ,GAAG;AAC7C,YAAI,EAAE,KAAK,MAAO,QAAO,EAAE,IAAI,MAAM,OAAO,QAAQ,QAAQ,CAAC,YAAY;AACzE,cAAM,SAAU,KAAiC,CAAC;AAClD,YAAI,OAAO,MAAM,YAAY,EAAE,WAAW,KAAK,GAAG;AAChD,gBAAM,KAAK,IAAI,OAAO,EAAE,MAAM,CAAC,CAAC;AAChC,cAAI,OAAO,WAAW,YAAY,CAAC,GAAG,KAAK,MAAM,GAAG;AAClD,mBAAO,EAAE,IAAI,MAAM,OAAO,QAAQ,QAAQ,CAAC,kBAAkB,CAAC,GAAG;AAAA,UACnE;AAAA,QACF,WAAW,WAAW,GAAG;AACvB,iBAAO;AAAA,YACL;AAAA,YACA,MAAM;AAAA,YACN,QAAQ,QAAQ,CAAC,OAAO,KAAK,UAAU,MAAM,CAAC,cAAc,KAAK,UAAU,CAAC,CAAC;AAAA,UAC/E;AAAA,QACF;AAAA,MACF;AACA,aAAO,EAAE,IAAI,MAAM,MAAM,QAAQ,iBAAiB;AAAA,IACpD;AAAA,EACF;AACF;AAEO,SAAS,aAAa,SAAyB;AACpD,QAAM,KAAK,SAAS,QAAQ,MAAM;AAClC,SAAO;AAAA,IACL;AAAA,IACA,MAAM,KAAK;AACT,YAAM,MAAM,IAAI,QAAQ;AACxB,YAAM,IAAI,IAAI,MAAM,OAAO;AAC3B,aAAO;AAAA,QACL;AAAA,QACA,MAAM,MAAM;AAAA,QACZ,QAAQ,IAAI,YAAY,EAAE,CAAC,CAAC,MAAM,WAAW,QAAQ,MAAM;AAAA,QAC3D,UAAU,IAAI,CAAC;AAAA,MACjB;AAAA,IACF;AAAA,EACF;AACF;AAQO,SAAS,aAAqB;AACnC,QAAM,KAAK;AACX,QAAM,UAA+C;AAAA,IACnD,EAAE,MAAM,cAAc,IAAI,4DAA4D;AAAA,IACtF,EAAE,MAAM,aAAa,IAAI,8CAA8C;AAAA,IACvE,EAAE,MAAM,YAAY,IAAI,YAAY;AAAA,IACpC,EAAE,MAAM,UAAU,IAAI,2BAA2B;AAAA,IACjD,EAAE,MAAM,cAAc,IAAI,yBAAyB;AAAA,IACnD,EAAE,MAAM,cAAc,IAAI,qCAAqC;AAAA,IAC/D,EAAE,MAAM,iBAAiB,IAAI,+BAA+B;AAAA,EAC9D;AACA,SAAO;AAAA,IACL;AAAA,IACA,MAAM,KAAK;AACT,YAAM,MAAM,IAAI,QAAQ;AACxB,iBAAW,EAAE,MAAM,GAAG,KAAK,SAAS;AAClC,YAAI,GAAG,KAAK,GAAG,GAAG;AAChB,iBAAO;AAAA,YACL;AAAA,YACA,MAAM;AAAA,YACN,QAAQ,cAAc,IAAI;AAAA,YAC1B,WAAW,IAAI,MAAM,EAAE,KAAK,CAAC,GAAG,CAAC;AAAA,UACnC;AAAA,QACF;AAAA,MACF;AACA,aAAO,EAAE,IAAI,MAAM,MAAM,QAAQ,6BAA6B;AAAA,IAChE;AAAA,EACF;AACF;AAYO,SAAS,gBAAgB,KAAwB,SAAiC;AACvF,QAAM,UAAU,QAAQ,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,CAAC;AAC/C,QAAM,YAAY,QAAQ,OAAO,CAAC,MAAM,EAAE,IAAI,EAAE;AAChD,QAAM,YAAY,QAAQ,SAAS;AACnC,SAAO;AAAA,IACL;AAAA,IACA,MAAM,cAAc,KAAK,QAAQ,SAAS;AAAA,IAC1C;AAAA,IACA;AAAA,IACA,OAAO,QAAQ,SAAS,YAAY,QAAQ,SAAS;AAAA,EACvD;AACF;AAEA,SAAS,QAAQ,KAAa,QAAgB,gBAAgB,OAAe;AAC3E,QAAM,YAAY,gBAAgB,MAAM,IAAI,YAAY;AACxD,QAAM,eAAe,gBAAgB,SAAS,OAAO,YAAY;AACjE,QAAM,MAAM,UAAU,QAAQ,YAAY;AAC1C,MAAI,QAAQ,GAAI,QAAO;AACvB,QAAM,QAAQ,KAAK,IAAI,GAAG,MAAM,EAAE;AAClC,QAAM,MAAM,KAAK,IAAI,IAAI,QAAQ,MAAM,OAAO,SAAS,EAAE;AACzD,UAAQ,QAAQ,IAAI,WAAM,MAAM,IAAI,MAAM,OAAO,GAAG,KAAK,MAAM,IAAI,SAAS,WAAM;AACpF;AAEA,SAAS,SAAS,GAA0C;AAC1D,SAAO,OAAO,MAAM,YAAY,MAAM,QAAQ,CAAC,MAAM,QAAQ,CAAC;AAChE;;;AC5KA,SAAS,kBAAAG,iBAAgB,cAAAC,aAAY,aAAAC,YAAW,gBAAAC,qBAAoB;AACpE,SAAS,WAAAC,gBAAe;AA2DxB,SAAS,OAAO,IAAsB;AACpC,MAAI,GAAG,WAAW,EAAG,QAAO;AAC5B,QAAM,SAAS,CAAC,GAAG,EAAE,EAAE,KAAK,CAAC,GAAG,MAAM,IAAI,CAAC;AAC3C,QAAM,MAAM,KAAK,MAAM,OAAO,SAAS,CAAC;AACxC,SAAO,OAAO,SAAS,MAAM,KAAK,OAAO,MAAM,CAAC,IAAK,OAAO,GAAG,KAAM,IAAI,OAAO,GAAG;AACrF;AAGA,SAAS,SAAS,KAAoC;AACpD,SAAO,IAAI,QAAQ,gBAAgB,IAAI,QAAQ;AACjD;AAGA,SAAS,sBAAsB,MAAuD;AACpF,QAAM,OAAO,oBAAI,IAA8C;AAC/D,aAAW,OAAO,MAAM;AACtB,UAAM,OAAO,IAAI,QAAQ,aAAa;AACtC,QAAI,CAAC,KAAM;AACX,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,IAAI,GAAG;AAC/C,UAAI,CAAC,OAAO,SAAS,KAAK,EAAG;AAC7B,YAAM,MAAM,KAAK,IAAI,GAAG,KAAK,EAAE,OAAO,GAAG,OAAO,EAAE;AAClD,UAAI,SAAS;AACb,UAAI,SAAS;AACb,WAAK,IAAI,KAAK,GAAG;AAAA,IACnB;AAAA,EACF;AACA,MAAI,KAAK,SAAS,EAAG,QAAO;AAC5B,QAAM,MAA8B,CAAC;AACrC,aAAW,CAAC,KAAK,GAAG,KAAK,KAAM,KAAI,GAAG,IAAI,IAAI,QAAQ,IAAI;AAC1D,SAAO;AACT;AAQO,SAAS,WAAW,MAAmB,MAA6C;AACzF,QAAM,cAAc,iBAAiB,KAAK,OAAO;AACjD,QAAM,YAAY,KAAK,cAAa,oBAAI,KAAK,GAAE,YAAY;AAE3D,QAAM,aAAa,oBAAI,IAAyB;AAChD,aAAW,OAAO,MAAM;AACtB,UAAM,aAAa,IAAI;AACvB,QAAI,CAAC,WAAY;AACjB,UAAM,SAAS,WAAW,IAAI,UAAU;AACxC,QAAI,OAAQ,QAAO,KAAK,GAAG;AAAA,QACtB,YAAW,IAAI,YAAY,CAAC,GAAG,CAAC;AAAA,EACvC;AAEA,QAAM,QAA4B,CAAC;AACnC,aAAW,CAAC,YAAY,YAAY,KAAK,YAAY;AACnD,UAAM,SAAS,aACZ,IAAI,CAAC,SAAS,EAAE,KAAK,OAAO,SAAS,GAAG,EAAE,EAAE,EAC5C,OAAO,CAAC,MAA8C,EAAE,UAAU,MAAS;AAC9E,QAAI,OAAO,WAAW,EAAG;AACzB,UAAMC,UAAS,OAAO,IAAI,CAAC,MAAM,EAAE,KAAK;AACxC,UAAM,QAAwB;AAAA,MAC5B,WAAW,KAAK;AAAA,MAChB;AAAA,MACA,QAAAA;AAAA,MACA,WAAW,OAAOA,OAAM;AAAA,MACxB,QAAQ,OAAO,IAAI,CAAC,MAAM,EAAE,IAAI,KAAK;AAAA,IACvC;AACA,UAAM,eAAe,sBAAsB,YAAY;AACvD,QAAI,aAAc,OAAM,eAAe;AACvC,UAAM,KAAK;AAAA,MACT;AAAA,MACA;AAAA,MACA,OAAO,KAAK,QAAQ;AAAA,MACpB,SAAS,KAAK;AAAA,MACd;AAAA,IACF,CAAC;AAAA,EACH;AACA,SAAO;AACT;AAKO,SAAS,gBAAgB,SAAiB,OAAiC;AAChF,MAAI,MAAM,WAAW,EAAG;AACxB,EAAAC,WAAUC,SAAQ,OAAO,GAAG,EAAE,WAAW,KAAK,CAAC;AAC/C,EAAAC,gBAAe,SAAS,GAAG,MAAM,IAAI,CAAC,SAAS,KAAK,UAAU,IAAI,CAAC,EAAE,KAAK,IAAI,CAAC;AAAA,CAAI;AACrF;AAGO,SAAS,sBACd,SACA,MACA,MACoB;AACpB,QAAM,QAAQ,WAAW,MAAM,IAAI;AACnC,kBAAgB,SAAS,KAAK;AAC9B,SAAO;AACT;AAOO,SAAS,cAAc,SAA4B;AACxD,MAAI,CAACC,YAAW,OAAO,EAAG,QAAO,EAAE,OAAO,CAAC,GAAG,UAAU,CAAC,EAAE;AAC3D,QAAM,QAAQ,oBAAI,IAA2B;AAC7C,QAAM,WAAyC,CAAC;AAEhD,aAAW,OAAOC,cAAa,SAAS,MAAM,EAAE,MAAM,IAAI,GAAG;AAC3D,UAAM,OAAO,IAAI,KAAK;AACtB,QAAI,CAAC,KAAM;AACX,QAAI;AACJ,QAAI;AACF,eAAS,KAAK,MAAM,IAAI;AAAA,IAC1B,QAAQ;AACN;AAAA,IACF;AACA,QAAI,CAAC,QAAQ,cAAc,CAAC,OAAO,eAAe,CAAC,OAAO,MAAO;AACjE,UAAM,MAAM,GAAG,OAAO,UAAU,KAAK,OAAO,WAAW;AACvD,QAAI,OAAO,MAAM,IAAI,GAAG;AACxB,QAAI,CAAC,MAAM;AACT,aAAO;AAAA,QACL,YAAY,OAAO;AAAA,QACnB,aAAa,OAAO;AAAA,QACpB,OAAO,OAAO;AAAA,QACd,UAAU,CAAC;AAAA,MACb;AACA,YAAM,IAAI,KAAK,IAAI;AAAA,IACrB;AACA,SAAK,SAAS,KAAK,OAAO,KAAK;AAC/B,QAAI,OAAO,QAAS,UAAS,OAAO,WAAW,IAAI,OAAO;AAAA,EAC5D;AAEA,aAAW,QAAQ,MAAM,OAAO,GAAG;AACjC,SAAK,SAAS,KAAK,CAAC,GAAG,MAAM,EAAE,UAAU,cAAc,EAAE,SAAS,CAAC;AAAA,EACrE;AACA,SAAO,EAAE,OAAO,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,SAAS;AAChD;AAkDO,SAAS,cACd,WACA,OAA6B,CAAC,GACf;AACf,QAAM,YAAY,KAAK,aAAa;AACpC,QAAM,OAAO,KAAK,QAAQ;AAC1B,QAAM,WAAW,KAAK,YAAY;AAElC,QAAM,QAA6B,CAAC;AACpC,aAAW,QAAQ,UAAU,OAAO;AAClC,UAAM,WAAW,KAAK;AACtB,QAAI,SAAS,WAAW,EAAG;AAC3B,UAAM,UAAU,SAAS,SAAS,SAAS,CAAC;AAE5C,UAAM,WAAW,KAAK,iBAClB,CAAC,GAAG,QAAQ,EAAE,QAAQ,EAAE,KAAK,CAAC,MAAM,EAAE,cAAc,KAAK,kBAAkB,MAAM,OAAO,IACxF,SAAS,SAAS,SAAS,CAAC;AAEhC,UAAM,OAGF;AAAA,MACF,YAAY,KAAK;AAAA,MACjB,aAAa,KAAK;AAAA,MAClB,OAAO,KAAK;AAAA,MACZ,SAAS,QAAQ;AAAA,MACjB,eAAe,QAAQ;AAAA,IACzB;AAEA,QAAI,CAAC,UAAU;AACb,YAAM,KAAK;AAAA,QACT,GAAG;AAAA,QACH,SAAS;AAAA,QACT,UAAU;AAAA,QACV,OAAO;AAAA,QACP,SAAS;AAAA,QACT,QAAQ;AAAA,QACR,gBAAgB;AAAA,MAClB,CAAC;AACD;AAAA,IACF;AAEA,UAAM,QAAQ,QAAQ,YAAY,SAAS;AAC3C,UAAM,UAAU,SAAS,OAAO,UAAU,KAAK,QAAQ,OAAO,UAAU;AACxE,QAAI,IAAmB;AACvB,QAAI,IAAmB;AACvB,QAAI;AAEJ,QAAI,SAAS;AACX,UAAI,QAAQ,SAAS,QAAQ,QAAQ,MAAM;AAC3C,YAAM,IAAI,YAAY,SAAS,QAAQ,QAAQ,MAAM;AACrD,UAAI,OAAO,SAAS,EAAE,CAAC,IAAI,EAAE,IAAI;AACjC,YAAM,cAAc,KAAK,IAAI,CAAC,KAAK,aAAa,MAAM,QAAQ,KAAK;AACnE,gBAAU,cAAe,QAAQ,IAAI,aAAa,cAAe;AAAA,IACnE,OAAO;AAEL,gBAAU,KAAK,IAAI,KAAK,KAAK,WAAY,QAAQ,IAAI,aAAa,cAAe;AAAA,IACnF;AAEA,UAAM,KAAK;AAAA,MACT,GAAG;AAAA,MACH;AAAA,MACA,UAAU,SAAS;AAAA,MACnB;AAAA,MACA,SAAS;AAAA,MACT,QAAQ;AAAA,MACR,gBAAgB,SAAS;AAAA,IAC3B,CAAC;AAAA,EACH;AAEA,QAAM,UAAU,EAAE,UAAU,GAAG,WAAW,GAAG,MAAM,GAAG,KAAK,EAAE;AAC7D,aAAW,QAAQ,MAAO,SAAQ,KAAK,OAAO,KAAK;AACnD,SAAO,EAAE,OAAO,QAAQ;AAC1B;AAOO,SAAS,oBAAoB,MAA6B;AAC/D,QAAM,QAAkB,CAAC;AACzB,QAAM,EAAE,QAAQ,IAAI;AACpB,QAAM;AAAA,IACJ,cAAc,QAAQ,SAAS,mBAAgB,QAAQ,QAAQ,kBAC1D,QAAQ,IAAI,cAAW,QAAQ,GAAG;AAAA,EACzC;AAEA,QAAMC,OAAM,CAAC,MAAc,EAAE,QAAQ,CAAC;AACtC,QAAM,aAAa,KAAK,MACrB,OAAO,CAAC,MAAM,EAAE,YAAY,eAAe,EAAE,YAAY,UAAU,EACnE,KAAK,CAAC,GAAG,MAAM;AAEd,QAAI,EAAE,YAAY,EAAE,QAAS,QAAO,EAAE,YAAY,cAAc,KAAK;AACrE,WAAO,KAAK,IAAI,EAAE,SAAS,CAAC,IAAI,KAAK,IAAI,EAAE,SAAS,CAAC;AAAA,EACvD,CAAC;AAEH,aAAW,QAAQ,YAAY;AAC7B,UAAM,OAAO,KAAK,YAAY,cAAc,cAAc;AAC1D,UAAM,WACJ,KAAK,UAAU,OAAQ,KAAK,SAAS,IAAI,IAAIA,KAAI,KAAK,KAAK,CAAC,KAAKA,KAAI,KAAK,KAAK,IAAK;AACtF,UAAM,OACJ,KAAK,YAAY,OACb,OAAO,KAAK,QAAQ,QAAQ,CAAC,CAAC,GAAG,KAAK,WAAW,OAAO,OAAO,KAAK,OAAO,QAAQ,CAAC,CAAC,KAAK,EAAE,MAC5F;AACN,UAAM;AAAA,MACJ,KAAK,IAAI,KAAK,KAAK,UAAU,SAAM,KAAK,KAAK,SAAM,KAAK,YAAY,MAAM,GAAG,CAAC,CAAC,KAC1EA,KAAI,KAAK,YAAY,CAAC,CAAC,WAAMA,KAAI,KAAK,OAAO,CAAC,KAAK,QAAQ,GAAG,IAAI;AAAA,IACzE;AAAA,EACF;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;;;ACvVO,SAAS,cACd,QACA,UAAoC,CAAC,GACZ;AACzB,QAAM,SAAS,QAAQ,UAAU;AACjC,QAAM,WAAW,QAAQ,YAAY;AACrC,QAAM,WAAW,QAAQ,YAAY;AAErC,MAAI,OAAO,SAAS,KAAK,IAAI,GAAG,KAAK,IAAI,QAAQ,CAAC,CAAC,GAAG;AACpD,WAAO,EAAE,OAAO,qBAAqB,YAAY,GAAG,UAAU,GAAG,SAAS,GAAG,QAAQ,MAAM;AAAA,EAC7F;AAEA,QAAM,OAAO,OAAO,MAAM,CAAC,MAAM;AACjC,QAAMC,QAAO,KAAK,OAAO,CAAC,GAAG,MAAM,IAAI,GAAG,CAAC,IAAI,KAAK;AACpD,QAAM,WAAW,KAAK,OAAO,CAAC,KAAK,MAAM,OAAO,IAAIA,UAAS,GAAG,CAAC,IAAI,KAAK;AAC1E,QAAM,SAAS,KAAK,KAAK,QAAQ;AACjC,QAAM,UAAU,KAAK,IAAIA,KAAI,IAAI,OAAO,KAAK,IAAIA,KAAI,IAAI;AACzD,QAAM,KAAK,SAAS;AACpB,QAAM,SAAS,KAAK,UAAU,UAAU,MAAM;AAI9C,MAAI,UAAU;AACd,MAAI,YAAwB;AAC5B,WAAS,IAAI,OAAO,SAAS,GAAG,IAAI,GAAG,KAAK;AAC1C,UAAM,QAAQ,OAAO,CAAC,IAAK,OAAO,IAAI,CAAC;AACvC,QAAI,UAAU,EAAG;AACjB,UAAM,MAAM,QAAQ,IAAI,IAAI;AAC5B,QAAI,cAAc,EAAG,aAAY;AACjC,QAAI,QAAQ,UAAW;AACvB,eAAW;AAAA,EACb;AAEA,MAAI;AACJ,MAAI,QAAQ;AACV,YAAQ;AAAA,EACV,WAAW,KAAK,IAAI,OAAO,KAAK,UAAU;AACxC,YAAQ,UAAU,IAAI,gBAAgB;AAAA,EACxC,OAAO;AACL,YAAQ;AAAA,EACV;AAEA,SAAO,EAAE,OAAO,YAAYA,OAAM,UAAU,IAAI,SAAS,OAAO;AAClE;;;AC3BO,SAAS,UAAU,SAAiC,MAAwB;AACjF,QAAM,UAA4B,KAAK,IAAI,CAAC,QAAQ,MAAM,KAAK,QAAQ,IAAI,MAAM,CAAC,CAAC;AACnF,QAAM,mBAAmB,QAAQ,OAAO,CAAC,MAAM,CAAC,EAAE,UAAU,EAAE,IAAI,aAAa,UAAU;AACzF,QAAM,WAAW,QAAQ,OAAO,CAAC,MAAM,CAAC,EAAE,UAAU,EAAE,IAAI,aAAa,SAAS;AAChF,SAAO,EAAE,SAAS,gBAAgB,iBAAiB,WAAW,GAAG,kBAAkB,SAAS;AAC9F;AAEA,SAAS,MAAM,KAAU,QAA4C;AACnE,MAAI,WAAW,UAAa,CAAC,OAAO,SAAS,MAAM,GAAG;AACpD,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,QAAQ,WAAW,IAAI,MAAM;AAAA,IAC/B;AAAA,EACF;AACA,MAAI,IAAI,eAAe,OAAO;AAC5B,UAAMC,UAAS,UAAU,IAAI;AAC7B,UAAMC,UAAS,IAAI,cAAc,IAAK,WAAW,IAAI,WAAW,IAAK,IAAI,YAAY;AACrF,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,QAAAD;AAAA,MACA,QAAAC;AAAA,MACA,QAAQ,GAAG,MAAM,WAAM,IAAI,SAAS,KAAKD,UAAS,OAAO,QAAQ;AAAA,IACnE;AAAA,EACF;AACA,QAAM,SAAS,UAAU,IAAI;AAC7B,QAAM,SAAS,WAAW,IAAI,IAAI,SAAS,IAAI;AAC/C,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,QAAQ,GAAG,MAAM,WAAM,IAAI,SAAS,KAAK,SAAS,OAAO,QAAQ;AAAA,EACnE;AACF;AAGO,IAAM,qBAA4B;AAAA,EACvC;AAAA,IACE,IAAI;AAAA,IACJ,aAAa;AAAA,IACb,QAAQ;AAAA,IACR,YAAY;AAAA,IACZ,WAAW;AAAA,IACX,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,aAAa;AAAA,IACb,QAAQ;AAAA,IACR,YAAY;AAAA,IACZ,WAAW;AAAA,IACX,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,aAAa;AAAA,IACb,QAAQ;AAAA,IACR,YAAY;AAAA,IACZ,WAAW;AAAA,IACX,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,aAAa;AAAA,IACb,QAAQ;AAAA,IACR,YAAY;AAAA,IACZ,WAAW;AAAA,IACX,UAAU;AAAA,EACZ;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,aAAa;AAAA,IACb,QAAQ;AAAA,IACR,YAAY;AAAA,IACZ,WAAW;AAAA,IACX,UAAU;AAAA,EACZ;AACF;;;ACxFO,SAAS,gBACd,MACA,QACA,UAAsC,CAAC,GACrB;AAClB,MAAI,OAAO,WAAW,GAAG;AACvB,UAAM,IAAI,MAAM,4CAA4C;AAAA,EAC9D;AACA,QAAM,gBAAgB,QAAQ,iBAAiB;AAC/C,QAAM,UAAmC,OAAO,IAAI,CAAC,MAAM;AACzD,UAAM,MAAM,EAAE,MAAM,IAAI;AACxB,UAAM,UAAU,OAAO,SAAS,GAAG,IAAI,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,GAAG,CAAC,IAAI;AACvE,WAAO,EAAE,IAAI,EAAE,IAAI,aAAa,EAAE,aAAa,OAAO,SAAS,MAAM,WAAW,cAAc;AAAA,EAChG,CAAC;AACD,QAAM,eAAe,QAAQ,OAAO,CAAC,GAAG,MAAM,IAAI,EAAE,OAAO,CAAC,IAAI,QAAQ;AACxE,SAAO,EAAE,SAAS,cAAc,MAAM,QAAQ,MAAM,CAAC,MAAM,EAAE,IAAI,EAAE;AACrE;AAGO,SAAS,aACd,KACoB;AACpB,SAAO;AAAA,IACL,IAAI,aAAa,GAAG;AAAA,IACpB,aAAa,IAAI,GAAG;AAAA,IACpB,OAAO,CAAC,EAAE,QAAQ,MAAM,MAAO,OAAO,GAAG,MAAM,UAAa,OAAO,GAAG,MAAM,MAAM,GAAG,IAAI,IAAI;AAAA,EAC/F;AACF;AAGO,SAAS,oBACd,KACA,WAAW,GACS;AACpB,SAAO;AAAA,IACL,IAAI,wBAAwB,GAAG;AAAA,IAC/B,aAAa,IAAI,GAAG,mBAAc,QAAQ;AAAA,IAC1C,OAAO,CAAC,EAAE,QAAQ,MAAM,MAAM;AAC5B,YAAM,IAAI,OAAO,GAAG;AACpB,YAAM,IAAI,MAAM,GAAG;AACnB,UAAI,CAAC,MAAM,QAAQ,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,EAAG,QAAO;AACnD,UAAI,EAAE,WAAW,EAAG,QAAO,EAAE,WAAW,IAAI,IAAI;AAChD,aAAO,KAAK,IAAI,GAAG,EAAE,UAAU,EAAE,SAAS,SAAS;AAAA,IACrD;AAAA,EACF;AACF;AAGO,SAAS,eACd,KACA,aACoB;AACpB,SAAO;AAAA,IACL,IAAI,mBAAmB,GAAG;AAAA,IAC1B,aAAa,IAAI,GAAG,sBAAsB,YAAY,KAAK,QAAG,CAAC;AAAA,IAC/D,OAAO,CAAC,EAAE,QAAQ,MAAM,MAAM;AAC5B,YAAM,KAAK,YAAY,QAAQ,OAAO,OAAO,GAAG,CAAC,CAAC;AAClD,YAAM,KAAK,YAAY,QAAQ,OAAO,MAAM,GAAG,CAAC,CAAC;AACjD,UAAI,OAAO,MAAM,OAAO,GAAI,QAAO;AACnC,aAAO,MAAM,KAAK,IAAI;AAAA,IACxB;AAAA,EACF;AACF;;;ACzEO,IAAM,oBAAN,MAAwB;AAAA,EAC7B,YACU,OACA,OACR;AAFQ;AACA;AAAA,EACP;AAAA,EAFO;AAAA,EACA;AAAA,EAGV,OAAO,UAAmC;AACxC,WAAO,IAAI,gBAAgB,KAAK,OAAO,KAAK,OAAO,QAAQ;AAAA,EAC7D;AAAA,EAEA,SAAS,UAAoB,yBAAsC;AACjE,WAAO;AAAA,MACL,OAAO,SAAS,KAAK,KAAK;AAAA,MAC1B,OAAO,YAAY;AACjB,cAAM,QAAQ,MAAM,SAAS,KAAK,OAAO,KAAK,KAAK;AACnD,cAAM,SAAS,MAAM,IAAI,CAAC,MAAM,EAAE,UAAU,EAAE,EAAE,KAAK,IAAI;AACzD,cAAM,MAAM,QAAQ,KAAK,CAAC,OAAO,GAAG,KAAK,MAAM,CAAC;AAChD,eAAO,MACH,EAAE,IAAI,MAAM,QAAQ,0BAA0B,IAC9C;AAAA,UACE,IAAI;AAAA,UACJ,QAAQ;AAAA,UACR,UAAU,OAAO,MAAM,GAAG,GAAG;AAAA,QAC/B;AAAA,MACN;AAAA,IACF;AAAA,EACF;AAAA,EAEA,cAAc,SAA8B;AAC1C,WAAO;AAAA,MACL,OAAO,SAAS,KAAK,KAAK,mBAAmB,QAAQ,MAAM;AAAA,MAC3D,OAAO,YAAY;AACjB,cAAM,QAAQ,MAAM,SAAS,KAAK,OAAO,KAAK,KAAK;AACnD,cAAM,SAAS,MAAM,IAAI,CAAC,MAAM,EAAE,UAAU,EAAE,EAAE,KAAK,IAAI;AACzD,cAAM,IAAI,OAAO,MAAM,OAAO;AAC9B,eAAO,IACH,EAAE,IAAI,MAAM,QAAQ,YAAY,EAAE,CAAC,CAAC,KAAK,UAAU,EAAE,CAAC,EAAE,IACxD,EAAE,IAAI,OAAO,QAAQ,uBAAuB,UAAU,OAAO,MAAM,GAAG,GAAG,EAAE;AAAA,MACjF;AAAA,IACF;AAAA,EACF;AAAA,EAEA,gBACE,WACa;AACb,WAAO;AAAA,MACL,OAAO,SAAS,KAAK,KAAK,qBAAqB,OAAO,SAAS,CAAC;AAAA,MAChE,OAAO,YAAY;AACjB,cAAM,UAAU,MAAM,KAAK,MAAM,OAAO,KAAK,KAAK;AAClD,cAAM,WAAW,QAAQ,KAAK,CAAC,MAAM,EAAE,cAAc,aAAa,EAAE,QAAQ;AAC5E,eAAO,WACH,EAAE,IAAI,OAAO,QAAQ,WAAW,OAAO,SAAS,CAAC,aAAa,IAC9D,EAAE,IAAI,MAAM,QAAQ,iBAAiB,OAAO,SAAS,CAAC,IAAI;AAAA,MAChE;AAAA,IACF;AAAA,EACF;AAAA,EAEA,iBAAiB,QAID;AACd,WAAO;AAAA,MACL,OAAO,SAAS,KAAK,KAAK,sBAAsB,KAAK,UAAU,MAAM,CAAC;AAAA,MACtE,OAAO,YAAY;AACjB,cAAM,MAAM,MAAM,KAAK,MAAM,OAAO,KAAK,KAAK;AAC9C,YAAI,CAAC,KAAK,QAAS,QAAO,EAAE,IAAI,OAAO,QAAQ,wBAAwB;AACvE,cAAM,SAAS,IAAI,UAAU,IAAI;AACjC,cAAM,QAAQ,MAAM,UAAU,KAAK,OAAO,KAAK,KAAK,GAAG;AACvD,cAAM,OAAO,MAAM,SAAS,KAAK,OAAO,KAAK,KAAK,GAAG;AACrD,cAAM,aAAuB,CAAC;AAC9B,YAAI,OAAO,WAAW,UAAa,SAAS,OAAO;AACjD,qBAAW,KAAK,UAAU,MAAM,MAAM,OAAO,MAAM,EAAE;AACvD,YAAI,OAAO,cAAc,UAAa,OAAO,OAAO;AAClD,qBAAW,KAAK,aAAa,IAAI,MAAM,OAAO,SAAS,EAAE;AAC3D,YAAI,OAAO,aAAa,UAAa,MAAM,OAAO;AAChD,qBAAW,KAAK,YAAY,GAAG,MAAM,OAAO,QAAQ,EAAE;AACxD,eAAO,WAAW,WAAW,IACzB,EAAE,IAAI,MAAM,QAAQ,kBAAkB,MAAM,OAAO,IAAI,WAAW,GAAG,UAAU,IAC/E,EAAE,IAAI,OAAO,QAAQ,WAAW,KAAK,IAAI,EAAE;AAAA,MACjD;AAAA,IACF;AAAA,EACF;AAAA,EAEA,YAAY,UAA+B;AACzC,WAAO;AAAA,MACL,OAAO,SAAS,KAAK,KAAK,iBAAiB,QAAQ;AAAA,MACnD,OAAO,YAAY;AACjB,cAAM,QAAQ,MAAM,UAAU,KAAK,OAAO,KAAK,OAAO,QAAQ;AAC9D,eAAO,MAAM,WAAW,IACpB,EAAE,IAAI,MAAM,QAAQ,SAAS,QAAQ,gBAAgB,IACrD;AAAA,UACE,IAAI;AAAA,UACJ,QAAQ,SAAS,QAAQ,YAAY,MAAM,MAAM;AAAA,UACjD,UAAU,MAAM,CAAC,EAAG;AAAA,QACtB;AAAA,MACN;AAAA,IACF;AAAA,EACF;AACF;AAEO,IAAM,kBAAN,MAA6C;AAAA,EAKlD,YACU,OACA,OACA,UACR;AAHQ;AACA;AACA;AAAA,EACP;AAAA,EAHO;AAAA,EACA;AAAA,EACA;AAAA,EAPF,cAAiD,CAAC;AAAA,EAClD,WAAW;AAAA,EACX,WAAW;AAAA,EAQnB,IAAI,QAAgB;AAClB,WAAO,SAAS,KAAK,KAAK,YAAY,KAAK,QAAQ;AAAA,EACrD;AAAA,EAEA,SAAS,OAA+C;AACtD,SAAK,YAAY,KAAK,CAAC,SAAS,UAAU,MAAM,KAAK,CAAC;AACtD,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,GAAiB;AACrB,SAAK,WAAW;AAChB,SAAK,WAAW;AAChB,WAAO;AAAA,EACT;AAAA,EAEA,QAAQ,GAAiB;AACvB,SAAK,WAAW;AAChB,WAAO;AAAA,EACT;AAAA,EAEA,OAAO,GAAiB;AACtB,SAAK,WAAW;AAChB,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,QAAgC;AACpC,UAAM,QAAQ,MAAM,UAAU,KAAK,OAAO,KAAK,OAAO,KAAK,QAAQ;AACnE,UAAM,WAAW,MAAM,OAAO,CAAC,MAAM,KAAK,YAAY,MAAM,CAAC,OAAO,GAAG,EAAE,IAAI,CAAC,CAAC;AAC/E,UAAM,QAAQ,SAAS;AACvB,QAAI,QAAQ,KAAK;AACf,aAAO;AAAA,QACL,IAAI;AAAA,QACJ,QAAQ,mBAAc,KAAK,QAAQ,cAAc,KAAK,QAAQ,gBAAgB,KAAK;AAAA,MACrF;AACF,QAAI,QAAQ,KAAK;AACf,aAAO;AAAA,QACL,IAAI;AAAA,QACJ,QAAQ,mBAAc,KAAK,QAAQ,cAAc,KAAK,QAAQ,gBAAgB,KAAK;AAAA,MACrF;AACF,WAAO,EAAE,IAAI,MAAM,QAAQ,GAAG,KAAK,cAAc,KAAK,QAAQ,YAAY;AAAA,EAC5E;AACF;AAEO,SAAS,YAAY,OAAmB,OAAkC;AAC/E,SAAO,IAAI,kBAAkB,OAAO,KAAK;AAC3C;AAGA,eAAsB,gBAAgB,cAKnC;AACD,QAAM,UAAU,MAAM,QAAQ;AAAA,IAC5B,aAAa,IAAI,OAAO,OAAO,EAAE,OAAO,EAAE,OAAO,QAAQ,MAAM,EAAE,MAAM,EAAE,EAAE;AAAA,EAC7E;AACA,QAAM,YAAY,QAAQ,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE;AACrD,SAAO;AAAA,IACL;AAAA,IACA,MAAM,cAAc,QAAQ;AAAA,IAC5B;AAAA,IACA,WAAW,QAAQ,SAAS;AAAA,EAC9B;AACF;AAEA,IAAM,0BAA0B;AAAA,EAC9B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,SAAS,UAAU,MAAe,OAAkD;AAClF,MAAI,SAAS,QAAQ,OAAO,SAAS,SAAU,QAAO;AACtD,QAAM,SAAS;AACf,aAAW,CAAC,GAAG,QAAQ,KAAK,OAAO,QAAQ,KAAK,GAAG;AACjD,UAAM,SAAS,OAAO,CAAC;AACvB,QAAI,oBAAoB,QAAQ;AAC9B,UAAI,OAAO,WAAW,YAAY,CAAC,SAAS,KAAK,MAAM,EAAG,QAAO;AAAA,IACnE,WAAW,WAAW,UAAU;AAC9B,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AACT;;;ACpLA,eAAsB,iBACpB,OACA,UACyB;AACzB,QAAM,eAAe,MAAM,MAAM,SAAS,SAAS,QAAQ;AAC3D,QAAM,gBAAgB,MAAM,MAAM,SAAS,SAAS,SAAS;AAC7D,MAAI,cAAc,WAAW,GAAG;AAC9B,WAAO;AAAA,MACL,MAAM,SAAS;AAAA,MACf,gBAAgB,EAAE,SAAS,CAAC,GAAG,eAAe,OAAO,aAAa,KAAK;AAAA,MACvE,UAAU,CAAC,2BAA2B;AAAA,MACtC,MAAM;AAAA,IACR;AAAA,EACF;AAEA,QAAM,UAA2B,CAAC;AAClC,aAAW,KAAK,SAAS,SAAS;AAChC,UAAM,UAAU,EAAE,WAAW,eAAe,EAAE,MAAM;AACpD,UAAM,WAAW,MAAM,WAAW,cAAc,SAAS,KAAK;AAC9D,UAAM,YAAY,MAAM,WAAW,eAAe,SAAS,KAAK;AAChE,QAAI,SAAS,SAAS,KAAK,UAAU,SAAS,EAAG;AACjD,YAAQ,KAAK,EAAE,QAAQ,EAAE,QAAQ,gBAAgB,EAAE,gBAAgB,UAAU,UAAU,CAAC;AAAA,EAC1F;AAEA,QAAM,iBACJ,QAAQ,UAAU,IACd,kBAAkB,OAAO,IACzB,EAAE,SAAS,CAAC,GAAG,eAAe,OAAO,aAAa,QAAQ,WAAW,EAAE;AAG7E,MAAI;AACJ,MAAI,SAAS,QAAQ,SAAS,KAAK,SAAS,GAAG;AAC7C,UAAM,MAAM,MAAM,oBAAoB,eAAe,KAAK;AAC1D,gBAAY,UAAU,KAAK,SAAS,IAAI;AAAA,EAC1C;AAEA,QAAM,WAAqB,CAAC;AAC5B,aAAW,UAAU,eAAe,SAAS;AAC3C,UAAM,OAAO,SAAS,QAAQ,KAAK,CAAC,MAAM,EAAE,WAAW,OAAO,MAAM;AACpE,QAAI,CAAC,KAAM;AACX,QAAI,OAAO,YAAY,aAAa;AAClC,YAAM,YAAY,KAAK,IAAI,OAAO,KAAK;AACvC,UAAI,KAAK,kBAAkB,UAAa,YAAY,KAAK,eAAe;AACtE,iBAAS;AAAA,UACP,WAAW,OAAO,MAAM,kBAAkB,OAAO,MAAM,QAAQ,CAAC,CAAC,OAAO,OAAO,QAAQ,QAAQ,CAAC,CAAC,OAAO,OAAO,OAAO,cAAc,CAAC,CAAC;AAAA,QACxI;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,MAAI,WAAW;AACb,eAAW,KAAK,UAAU,kBAAkB;AAC1C,eAAS,KAAK,QAAQ,EAAE,IAAI,EAAE,eAAe,EAAE,MAAM,EAAE;AAAA,IACzD;AAAA,EACF;AAEA,SAAO,EAAE,MAAM,SAAS,MAAM,gBAAgB,WAAW,UAAU,MAAM,SAAS,WAAW,EAAE;AACjG;AAEO,SAAS,qBAAqB,SAAmC;AACtE,QAAM,QAAkB,CAAC;AACzB,QAAM,UAAU,QAAQ,MAAM,CAAC,MAAM,EAAE,IAAI;AAC3C,QAAM,KAAK,UAAU,oCAA+B,iCAA4B;AAChF,QAAM,KAAK,EAAE;AACb,aAAW,KAAK,SAAS;AACvB,UAAM,KAAK,OAAO,EAAE,IAAI,IAAI,EAAE,OAAO,WAAM,QAAG,EAAE;AAChD,QAAI,EAAE,SAAS,SAAS,GAAG;AACzB,YAAM,KAAK,EAAE;AACb,YAAM,KAAK,eAAe;AAC1B,iBAAW,KAAK,EAAE,SAAU,OAAM,KAAK,KAAK,CAAC,EAAE;AAAA,IACjD;AACA,QAAI,EAAE,eAAe,QAAQ,SAAS,GAAG;AACvC,YAAM,KAAK,EAAE;AACb,YAAM,KAAK,oEAA+D;AAC1E,YAAM,KAAK,+BAA+B;AAC1C,iBAAW,KAAK,EAAE,eAAe,SAAS;AACxC,cAAM;AAAA,UACJ,KAAK,EAAE,MAAM,MAAM,EAAE,aAAa,QAAQ,CAAC,CAAC,MAAM,EAAE,cAAc,QAAQ,CAAC,CAAC,MAAM,EAAE,MAAM,QAAQ,CAAC,CAAC,MAAM,EAAE,QAAQ,QAAQ,CAAC,CAAC,MAAM,EAAE,OAAO,cAAc,CAAC,CAAC,MAAM,EAAE,OAAO;AAAA,QAC9K;AAAA,MACF;AAAA,IACF;AACA,QAAI,EAAE,aAAa,EAAE,UAAU,QAAQ,SAAS,GAAG;AACjD,YAAM,KAAK,EAAE;AACb,YAAM,KAAK,kBAAkB;AAC7B,iBAAW,KAAK,EAAE,UAAU,SAAS;AACnC,cAAM,KAAK,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,QAAQ,MAAM,EAAE,SAAS,OAAO,QAAQ,WAAM,EAAE,MAAM,EAAE;AAAA,MAC7F;AAAA,IACF;AACA,UAAM,KAAK,EAAE;AAAA,EACf;AACA,SAAO,MAAM,KAAK,IAAI;AACxB;AAGA,eAAe,oBACb,MACA,OACiC;AACjC,MAAI,KAAK,WAAW,EAAG,QAAO,CAAC;AAC/B,QAAM,YAAsB,CAAC;AAC7B,QAAME,UAAmB,CAAC;AAC1B,QAAM,SAAmB,CAAC;AAC1B,QAAM,QAAkB,CAAC;AACzB,aAAW,KAAK,MAAM;AACpB,QAAI,EAAE,QAAS,WAAU,KAAK,EAAE,UAAU,EAAE,SAAS;AACrD,QAAI,EAAE,SAAS,UAAU,OAAW,CAAAA,QAAO,KAAK,EAAE,QAAQ,KAAK;AAC/D,WAAO,KAAK,EAAE,SAAS,SAAS,OAAO,IAAI,CAAC;AAC5C,UAAM,MAAM,MAAM,SAAS,OAAO,EAAE,KAAK;AACzC,UAAM,KAAK,aAAa,GAAG,EAAE,OAAO;AAAA,EACtC;AACA,SAAO;AAAA,IACL,aAAa,QAAQ,SAAS;AAAA,IAC9B,cAAc,QAAQ,SAAS;AAAA,IAC/B,QAAQ,QAAQ,SAAS;AAAA,IACzB,cAAc,QAAQA,OAAM;AAAA,IAC5B,UAAU,QAAQ,MAAM;AAAA,IACxB,SAAS,QAAQ,KAAK;AAAA,EACxB;AACF;AAEA,SAAS,QAAQ,IAAsB;AACrC,MAAI,GAAG,WAAW,EAAG,QAAO;AAC5B,SAAO,GAAG,OAAO,CAAC,GAAG,MAAM,IAAI,GAAG,CAAC,IAAI,GAAG;AAC5C;AAEA,eAAe,WACb,MACA,SACA,OACmB;AACnB,QAAM,MAAgB,CAAC;AACvB,aAAW,KAAK,MAAM;AACpB,UAAM,IAAI,MAAM,QAAQ,GAAG,KAAK;AAChC,QAAI,MAAM,QAAQ,OAAO,SAAS,CAAC,EAAG,KAAI,KAAK,CAAC;AAAA,EAClD;AACA,SAAO;AACT;AAEA,SAAS,eAAe,QAAyE;AAC/F,SAAO,OAAO,KAAK,UAAU;AAC3B,YAAQ,QAAQ;AAAA,MACd,KAAK;AAAA,MACL,KAAK;AACH,eAAO,IAAI,SAAS,SAAS;AAAA,MAC/B,KAAK;AACH,eAAO,IAAI,SAAS,SAAS,OAAO,IAAI;AAAA,MAC1C,KAAK;AACH,eAAO,IAAI,WAAW,IAAI,YAAY,IAAI,UAAU,IAAI,YAAY;AAAA,MACtE,KAAK,WAAW;AACd,cAAM,MAAM,MAAM,SAAS,OAAO,IAAI,KAAK;AAC3C,eAAO,aAAa,GAAG,EAAE;AAAA,MAC3B;AAAA,MACA,KAAK;AACH,eAAO,gBAAgB,GAAG,MAAM,YAAY,IAAI;AAAA,MAClD;AACE,eAAO;AAAA,IACX;AAAA,EACF;AACF;;;ACzJA,eAAsB,mBACpB,OACA,OAC2B;AAC3B,QAAM,MAAM,MAAM,MAAM,OAAO,KAAK;AACpC,MAAI,CAAC,IAAK,OAAM,IAAI,cAAc,OAAO,KAAK,YAAY;AAC1D,QAAM,MAAM,MAAM,SAAS,OAAO,KAAK;AACvC,QAAM,WAAW,MAAM,MAAM,MAAM,EAAE,MAAM,CAAC;AAC5C,QAAM,SAAS,SAAS,OAAO,CAAC,MAA6C,EAAE,SAAS,OAAO;AAE/F,QAAM,cAAoC,IAAI,IAAI,CAAC,OAAO;AAAA,IACxD,IAAI,EAAE;AAAA,IACN,SAAS,IAAI;AAAA,IACb,MAAM,EAAE;AAAA,IACR,OAAO,EAAE;AAAA,IACT,OAAO,EAAE;AAAA,IACT,QAAQ,EAAE;AAAA,IACV,WAAW,IAAI,KAAK,EAAE,SAAS,EAAE,YAAY;AAAA,IAC7C,SAAS,IAAI,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,YAAY;AAAA,IACxD,OAAO;AAAA,MACL,OAAO,EAAE,eAAe;AAAA,MACxB,QAAQ,EAAE,gBAAgB;AAAA,MAC1B,QAAQ,EAAE,eAAe,MAAM,EAAE,gBAAgB;AAAA,MACjD,WAAW,EAAE,WAAW;AAAA,IAC1B;AAAA,IACA,UAAU,EAAE,cAAc,EAAE,cAAc,cAAc,EAAE,aAAa;AAAA,EACzE,EAAE;AAEF,QAAMC,UAA0B,OAAO,IAAI,CAAC,OAAO;AAAA,IACjD,IAAI,EAAE;AAAA,IACN,SAAS,IAAI;AAAA,IACb,eAAe,EAAE;AAAA,IACjB,MAAM,GAAG,EAAE,OAAO,IAAI,EAAE,SAAS;AAAA,IACjC,OAAO,EAAE;AAAA,IACT,SAAS,EAAE;AAAA,EACb,EAAE;AAEF,SAAO,EAAE,SAAS,IAAI,OAAO,aAAa,QAAAA,QAAO;AACnD;AAIA,eAAsB,iBAAiB,OAAoC;AACzE,QAAM,OAAO,MAAM,MAAM,SAAS;AAClC,QAAM,YAAoC,CAAC;AAC3C,QAAM,aAAqC,CAAC;AAC5C,MAAI,sBAAsB;AAC1B,MAAI,uBAAuB;AAC3B,MAAI,eAAe;AACnB,MAAI,aAAa;AACjB,MAAI,aAAa;AACjB,aAAW,KAAK,MAAM;AACpB,QAAI,EAAE,SAAS,SAAS,KAAM;AAAA,aACrB,EAAE,SAAS,SAAS,MAAO;AACpC,UAAM,MAAM,MAAM,SAAS,OAAO,EAAE,KAAK;AACzC,UAAM,MAAM,aAAa,GAAG;AAC5B,2BAAuB,IAAI;AAC3B,4BAAwB,IAAI;AAC5B,oBAAgB,IAAI;AACpB,UAAM,QAAQ,MAAM,MAAM,MAAM,EAAE,OAAO,EAAE,OAAO,MAAM,OAAO,CAAC;AAChE,eAAW,KAAK,OAAO;AACrB,UAAI,EAAE,SAAS,OAAQ;AACvB,gBAAU,EAAE,QAAQ,KAAK,UAAU,EAAE,QAAQ,KAAK,KAAK;AACvD,UAAI,EAAE,WAAW,QAAS,YAAW,EAAE,QAAQ,KAAK,WAAW,EAAE,QAAQ,KAAK,KAAK;AAAA,IACrF;AAAA,EACF;AAEA,QAAM,QAAkB,CAAC;AACzB,QAAM,KAAK,6DAA6D;AACxE,QAAM,KAAK,sCAAsC;AACjD,QAAM,KAAK,yBAAyB,KAAK,MAAM,EAAE;AACjD,QAAM,KAAK,wEAAwE;AACnF,QAAM,KAAK,6CAA6C;AACxD,QAAM,KAAK,gCAAgC,UAAU,EAAE;AACvD,QAAM,KAAK,yEAAyE;AACpF,QAAM,KAAK,6CAA6C;AACxD,QAAM,KAAK,gCAAgC,UAAU,EAAE;AACvD,QAAM,KAAK,qEAAqE;AAChF,QAAM,KAAK,kDAAkD;AAC7D,QAAM,KAAK,qCAAqC,mBAAmB,EAAE;AACrE,QAAM,KAAK,uEAAuE;AAClF,QAAM,KAAK,mDAAmD;AAC9D,QAAM,KAAK,sCAAsC,oBAAoB,EAAE;AACvE,QAAM,KAAK,4DAA4D;AACvE,QAAM,KAAK,0CAA0C;AACrD,QAAM,KAAK,6BAA6B,YAAY,EAAE;AACtD,QAAM,KAAK,4DAA4D;AACvE,QAAM,KAAK,4CAA4C;AACvD,aAAW,CAAC,MAAM,CAAC,KAAK,OAAO,QAAQ,SAAS,GAAG;AACjD,UAAM,KAAK,qCAAqC,YAAY,IAAI,CAAC,MAAM,CAAC,EAAE;AAAA,EAC5E;AACA,QAAM,KAAK,8DAA8D;AACzE,QAAM,KAAK,6CAA6C;AACxD,aAAW,CAAC,MAAM,CAAC,KAAK,OAAO,QAAQ,UAAU,GAAG;AAClD,UAAM,KAAK,sCAAsC,YAAY,IAAI,CAAC,MAAM,CAAC,EAAE;AAAA,EAC7E;AACA,SAAO,GAAG,MAAM,KAAK,IAAI,CAAC;AAAA;AAC5B;AAEA,SAAS,YAAY,GAAmB;AACtC,SAAO,EAAE,QAAQ,OAAO,MAAM,EAAE,QAAQ,MAAM,KAAK,EAAE,QAAQ,OAAO,KAAK;AAC3E;AAiBA,eAAsB,wBACpB,OACA,OACA,OAK8B;AAC9B,QAAM,MAAM,MAAM,MAAM,OAAO,KAAK;AACpC,MAAI,CAAC,IAAK,OAAM,IAAI,cAAc,OAAO,KAAK,YAAY;AAC1D,QAAM,OAAO,MAAM,SAAS,OAAO,KAAK;AACxC,QAAM,UAAU,IAAI,aAAa,OAAO,EAAE,MAAM,CAAC;AACjD,QAAM,UAA+B,CAAC;AACtC,aAAW,QAAQ,MAAM;AACvB,UAAM,EAAE,OAAO,WAAW,SAAS,IAAI,MAAM,MAAM,MAAM,IAAI;AAC7D,UAAM,UAAU,MAAM,QAAQ,YAAY;AAAA,MACxC,SAAS,MAAM;AAAA,MACf,cAAc,KAAK;AAAA,MACnB,WAAW,MAAM;AAAA,MACjB;AAAA,MACA;AAAA,MACA;AAAA,MACA,MAAM,GAAG,MAAM,EAAE,IAAI,MAAM,SAAS;AAAA,IACtC,CAAC;AACD,YAAQ,KAAK;AAAA,MACX,QAAQ,QAAQ;AAAA,MAChB,cAAc,KAAK;AAAA,MACnB,WAAW,MAAM;AAAA,MACjB;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AACA,SAAO;AACT;;;ACtLA,eAAsB,qBACpB,QACA,UACA,SACA,UAA6B,CAAC,GACH;AAC3B,QAAM,OAAO,QAAQ,QAAQ;AAC7B,QAAM,gBAAgB,MAAM,QAAQ,MAAM;AAC1C,QAAM,gBAAmD,CAAC;AAC1D,QAAM,MAAgB,CAAC,aAAa;AACpC,aAAW,EAAE,IAAI,GAAG,KAAK,UAAU;AACjC,UAAM,UAAU,GAAG,QAAQ,IAAI;AAC/B,UAAM,QAAQ,MAAM,QAAQ,OAAO;AACnC,kBAAc,KAAK,EAAE,SAAS,IAAI,OAAO,QAAQ,CAAC;AAClD,QAAI,KAAK,KAAK;AAAA,EAChB;AACA,QAAMC,QAAO,IAAI,OAAO,CAAC,GAAG,MAAM,IAAI,GAAG,CAAC,IAAI,IAAI;AAClD,QAAM,WAAW,IAAI,OAAO,CAAC,GAAG,MAAM,KAAK,IAAIA,UAAS,GAAG,CAAC,IAAI,IAAI;AACpE,QAAM,SAAS,KAAK,KAAK,QAAQ;AACjC,QAAM,MAAM,KAAK,IAAIA,KAAI,IAAI,OAAO,KAAK,IAAIA,KAAI,IAAI;AACrD,QAAM,aAAa,KAAK,IAAI,GAAG,IAAI,SAAS,GAAG;AAC/C,SAAO,EAAE,eAAe,eAAe,WAAWA,OAAM,QAAQ,WAAW;AAC7E;AAKO,IAAM,mBAA4B,CAAC,MAAM,EAAE,YAAY;AAGvD,IAAM,yBAAkC,CAAC,GAAG,SAAS;AAC1D,QAAM,YAAY,EAAE,MAAM,eAAe,EAAE,OAAO,OAAO;AACzD,MAAI,UAAU,UAAU,EAAG,QAAO;AAClC,QAAM,WAAW,CAAC,GAAG,SAAS;AAC9B,MAAI,IAAI,SAAS;AACjB,WAAS,IAAI,SAAS,SAAS,GAAG,IAAI,GAAG,KAAK;AAC5C,QAAK,IAAI,aAAa,UAAW;AACjC,UAAM,IAAI,KAAK,IAAI;AAClB,KAAC,SAAS,CAAC,GAAG,SAAS,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,GAAI,SAAS,CAAC,CAAE;AAAA,EAC3D;AACA,SAAO,SAAS,KAAK,GAAG;AAC1B;AAGO,IAAM,cAAuB,CAAC,GAAG,SAAS;AAC/C,MAAI,EAAE,SAAS,EAAG,QAAO;AACzB,QAAM,QAAQ,EAAE,MAAM,EAAE;AACxB,MAAI,IAAI,SAAS;AACjB,QAAM,QAAQ,KAAK,IAAI,GAAG,KAAK,MAAM,MAAM,SAAS,EAAE,CAAC;AACvD,WAAS,IAAI,GAAG,IAAI,OAAO,KAAK;AAC9B,aAAS,UAAU,GAAG,UAAU,IAAI,WAAW;AAC7C,UAAK,IAAI,aAAa,UAAW;AACjC,YAAM,MAAM,KAAK,MAAM,SAAS;AAChC,YAAM,IAAI,MAAM,GAAG;AACnB,YAAM,IAAI,MAAM,MAAM,CAAC;AACvB,UAAI,MAAM,KAAK,WAAW,KAAK,CAAC,KAAK,WAAW,KAAK,CAAC,GAAG;AACvD,cAAM,GAAG,IAAI;AACb,cAAM,MAAM,CAAC,IAAI;AACjB;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,SAAO,MAAM,KAAK,EAAE;AACtB;AAGO,IAAM,0BAAmC,CAAC,MAAM,oCAAoC,CAAC;AAGrF,IAAM,4BAAqC,CAAC,MAAM,EAAE,QAAQ,QAAQ,GAAG,EAAE,KAAK;AAE9E,IAAM,mBAAuD;AAAA,EAClE,EAAE,IAAI,aAAa,IAAI,iBAAiB;AAAA,EACxC,EAAE,IAAI,oBAAoB,IAAI,uBAAuB;AAAA,EACrD,EAAE,IAAI,QAAQ,IAAI,YAAY;AAAA,EAC9B,EAAE,IAAI,qBAAqB,IAAI,wBAAwB;AAAA,EACvD,EAAE,IAAI,uBAAuB,IAAI,0BAA0B;AAC7D;AAyDA,eAAsB,8BACpB,MAC6C;AAC7C,QAAM,OAAO,KAAK,IAAI,GAAG,KAAK,QAAQ,CAAC;AACvC,QAAM,eAAe,KAAK,SAAS,IAAI,CAAC,MAAM,EAAE,IAAI;AAEpD,QAAM,cAAiE,CAAC;AAExE,aAAW,YAAY,KAAK,WAAW;AACrC,UAAM,WAAW,MAAM,KAAK,YAAY;AAAA,MACtC,IAAI,SAAS;AAAA,MACb,WAAW,SAAS;AAAA,IACtB,CAAC;AACD,UAAM,gBAAgB,SAAS;AAE/B,UAAM,SAAiC,CAAC;AACxC,UAAM,iBAA2B,CAAC;AAElC,eAAW,KAAK,KAAK,UAAU;AAC7B,YAAMC,UAAmB,CAAC;AAC1B,eAAS,IAAI,GAAG,IAAI,MAAM,KAAK;AAC7B,cAAM,eAAe,SAAS,UAAU,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;AAC/D,cAAM,MAAM,MAAM,KAAK,YAAY;AAAA,UACjC,IAAI,SAAS;AAAA,UACb,WAAW;AAAA,QACb,CAAC;AACD,QAAAA,QAAO,KAAK,IAAI,KAAK;AAAA,MACvB;AACA,YAAMD,QAAOC,QAAO,OAAO,CAAC,GAAG,MAAM,IAAI,GAAG,CAAC,IAAIA,QAAO;AACxD,aAAO,EAAE,IAAI,IAAID,QAAO;AACxB,qBAAe,KAAK,GAAGC,OAAM;AAAA,IAC/B;AAEA,UAAM,kBACJ,eAAe,WAAW,IACtB,gBACA,eAAe,OAAO,CAAC,GAAG,MAAM,IAAI,GAAG,CAAC,IAAI,eAAe;AAEjE,gBAAY,KAAK,EAAE,IAAI,SAAS,IAAI,eAAe,iBAAiB,OAAO,CAAC;AAAA,EAC9E;AAEA,QAAM,eACJ,YAAY,WAAW,IACnB,IACA,YAAY,OAAO,CAAC,GAAG,MAAM,IAAI,EAAE,eAAe,CAAC,IAAI,YAAY;AACzE,QAAM,kBACJ,YAAY,WAAW,IACnB,IACA,YAAY,OAAO,CAAC,GAAG,MAAM,IAAI,EAAE,iBAAiB,CAAC,IAAI,YAAY;AAE3E,QAAMC,SAAQ,gBAAgB,IAAI,IAAI,kBAAkB;AACxD,QAAM,QAAQ,KAAK,IAAI,GAAG,KAAK,IAAI,GAAGA,MAAK,CAAC;AAE5C,SAAO,EAAE,OAAO,aAAa,UAAU,aAAa;AACtD;;;AChLO,SAAS,WACd,GACA,GACA,UAA6B,CAAC,GACZ;AAClB,MAAI,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,EAAE,QAAQ;AAChD,UAAM,IAAI;AAAA,MACR,kCAAkC,EAAE,KAAK,IAAI,EAAE,MAAM,OAAO,EAAE,KAAK,IAAI,EAAE,MAAM;AAAA,IACjF;AAAA,EACF;AACA,MAAI,EAAE,KAAK,WAAW,EAAE,KAAK,QAAQ;AACnC,UAAM,IAAI,gBAAgB,wCAAwC;AAAA,EACpE;AACA,QAAM,YAAY,QAAQ,aAAa;AACvC,QAAM,cAAc,EAAE,QAAQ,EAAE;AAChC,MAAI,YAAY;AAChB,MAAI,WAAW;AACf,WAAS,IAAI,GAAG,IAAI,EAAE,KAAK,QAAQ,KAAK,GAAG;AACzC,UAAM,KAAK,KAAK,IAAI,EAAE,KAAK,CAAC,IAAK,EAAE,KAAK,CAAC,CAAE;AAC3C,UAAM,KAAK,KAAK,IAAI,EAAE,KAAK,IAAI,CAAC,IAAK,EAAE,KAAK,IAAI,CAAC,CAAE;AACnD,UAAM,KAAK,KAAK,IAAI,EAAE,KAAK,IAAI,CAAC,IAAK,EAAE,KAAK,IAAI,CAAC,CAAE;AACnD,UAAM,KAAK,KAAK,IAAI,EAAE,KAAK,IAAI,CAAC,IAAK,EAAE,KAAK,IAAI,CAAC,CAAE;AACnD,UAAMC,SAAQ,KAAK,IAAI,IAAI,IAAI,IAAI,EAAE;AACrC,QAAIA,SAAQ,SAAU,YAAWA;AACjC,QAAIA,SAAQ,UAAW;AAAA,EACzB;AACA,QAAM,YAAY,cAAc,IAAI,YAAY,cAAc;AAC9D,QAAM,SAAS,YAAY,OAAQ,cAAc,YAAY,OAAO,qBAAqB;AACzF,SAAO,EAAE,WAAW,iBAAiB,WAAW,aAAa,iBAAiB,UAAU,OAAO;AACjG;AAGO,SAAS,gBACd,GACA,GACA,OACA,QACA,YAAY,GACJ;AACR,SAAO,WAAW,EAAE,OAAO,QAAQ,MAAM,EAAE,GAAG,EAAE,OAAO,QAAQ,MAAM,EAAE,GAAG,EAAE,UAAU,CAAC,EAAE;AAC3F;;;AC3BA,eAAsB,OAAU,SAAqD;AACnF,QAAM,SAAS,QAAQ,WAAW,CAAC,GAAG,MAAM,OAAO,GAAG,GAAG,CAAC;AAC1D,QAAM,UAAU,QAAQ,iBAAiB;AACzC,QAAM,OAAwB,CAAC;AAE/B,QAAM,cAAc,MAAM,QAAQ,QAAQ,QAAQ,IAAI;AACtD,OAAK,KAAK,EAAE,OAAO,QAAQ,MAAM,GAAG,YAAY,CAAC;AACjD,QAAM,aAAa,MAAM,QAAQ,QAAQ,QAAQ,GAAG;AACpD,OAAK,KAAK,EAAE,OAAO,QAAQ,KAAK,GAAG,WAAW,CAAC;AAE/C,MAAI,CAAC,YAAY,MAAM;AACrB,WAAO,EAAE,SAAS,QAAQ,MAAM,MAAM,WAAW,OAAO,mBAAmB,KAAK;AAAA,EAClF;AACA,MAAI,WAAW,MAAM;AACnB,WAAO,EAAE,SAAS,QAAQ,KAAK,MAAM,WAAW,OAAO,mBAAmB,KAAK;AAAA,EACjF;AAEA,MAAI,OAAO,QAAQ;AACnB,MAAI,MAAM,QAAQ;AAClB,WAAS,IAAI,GAAG,IAAI,SAAS,KAAK;AAChC,UAAM,MAAM,QAAQ,QAAQ,MAAM,GAAG;AACrC,QAAI,QAAQ,QAAQ,OAAO,KAAK,IAAI,KAAK,OAAO,KAAK,GAAG,GAAG;AACzD,aAAO,EAAE,SAAS,KAAK,MAAM,WAAW,MAAM,mBAAmB,MAAM;AAAA,IACzE;AACA,UAAM,IAAI,MAAM,QAAQ,QAAQ,GAAG;AACnC,SAAK,KAAK,EAAE,OAAO,KAAK,GAAG,EAAE,CAAC;AAC9B,QAAI,EAAE,KAAM,QAAO;AAAA,QACd,OAAM;AAAA,EACb;AACA,SAAO,EAAE,SAAS,KAAK,MAAM,WAAW,OAAO,mBAAmB,MAAM;AAC1E;AAMA,eAAsB,aAAa,SAMD;AAChC,QAAM,EAAE,QAAQ,IAAI;AACpB,QAAM,UAAU,QAAQ,QAAQ,QAAQ,IAAI;AAC5C,QAAM,SAAS,QAAQ,QAAQ,QAAQ,GAAG;AAC1C,MAAI,UAAU,KAAK,SAAS,GAAG;AAC7B,UAAM,IAAI;AAAA,MACR,0DAA0D,QAAQ,IAAI,SAAS,QAAQ,GAAG;AAAA,IAC5F;AAAA,EACF;AACA,MAAI,WAAW,QAAQ;AACrB,UAAM,IAAI,MAAM,wDAAwD;AAAA,EAC1E;AACA,SAAO,OAAe;AAAA,IACpB,MAAM,QAAQ;AAAA,IACd,KAAK,QAAQ;AAAA,IACb,SAAS,QAAQ;AAAA,IACjB,eAAe,QAAQ;AAAA,IACvB,SAAS,CAAC,GAAG,MAAM;AACjB,YAAM,KAAK,QAAQ,QAAQ,CAAC;AAC5B,YAAM,KAAK,QAAQ,QAAQ,CAAC;AAC5B,UAAI,KAAK,MAAM,EAAG,QAAO;AACzB,aAAO,QAAQ,KAAK,OAAO,KAAK,MAAM,CAAC,CAAC,KAAK;AAAA,IAC/C;AAAA,EACF,CAAC;AACH;AASA,eAAsB,aAAa,SAMsC;AACvE,QAAM,QAAQ,QAAQ,sBAAsB,CAAC,MAAc,EAAE,MAAM,SAAS;AAC5E,QAAMC,QAAO,CAAC,eAAyB,WAAW,KAAK,MAAM;AAC7D,QAAM,YAAY,MAAM,QAAQ,IAAI;AACpC,QAAM,WAAW,MAAM,QAAQ,GAAG;AAClC,MAAI,UAAU,WAAW,SAAS,QAAQ;AACxC,UAAM,IAAI;AAAA,MACR,2CAA2C,UAAU,MAAM,OAAO,SAAS,MAAM;AAAA,IACnF;AAAA,EACF;AACA,MAAI,UAAU,SAAS,GAAG;AACxB,UAAM,IAAI,MAAM,oDAAoD;AAAA,EACtE;AAGA,QAAM,IAAI,UAAU;AACpB,QAAM,WAAW,IAAI,OAAO,CAAC;AAC7B,QAAM,UAAU,IAAI,OAAO,CAAC;AAE5B,WAAS,cAAc,MAAwB;AAC7C,WAAO,KAAK,MAAM,EAAE,EAAE,IAAI,CAAC,GAAG,MAAO,MAAM,MAAM,SAAS,CAAC,IAAK,UAAU,CAAC,CAAG;AAAA,EAChF;AAEA,QAAM,SAAS,MAAM,OAAe;AAAA,IAClC,MAAM;AAAA,IACN,KAAK;AAAA,IACL,SAAS,CAAC,SAAS,QAAQ,QAAQA,MAAK,cAAc,IAAI,CAAC,CAAC;AAAA,IAC5D,eAAe,QAAQ,iBAAiB,IAAI;AAAA,IAC5C,SAAS,CAAC,GAAG,MAAM;AAEjB,eAAS,IAAI,GAAG,IAAI,EAAE,QAAQ,KAAK;AACjC,YAAI,EAAE,CAAC,MAAM,EAAE,CAAC,GAAG;AAEjB,gBAAM,YAAsB,CAAC;AAC7B,mBAAS,IAAI,GAAG,IAAI,EAAE,QAAQ,IAAK,KAAI,EAAE,CAAC,MAAM,EAAE,CAAC,EAAG,WAAU,KAAK,CAAC;AACtE,cAAI,UAAU,WAAW,EAAG,QAAO;AACnC,cAAI,UAAU,WAAW,EAAG,QAAO;AAEnC,gBAAM,OAAO,UAAU,MAAM,GAAG,KAAK,KAAK,UAAU,SAAS,CAAC,CAAC;AAC/D,gBAAM,QAAQ,EAAE,MAAM,EAAE;AACxB,qBAAW,KAAK,KAAM,OAAM,CAAC,IAAI,EAAE,CAAC;AACpC,iBAAO,MAAM,KAAK,EAAE;AAAA,QACtB;AAAA,MACF;AACA,aAAO;AAAA,IACT;AAAA,IACA,QAAQ,CAAC,GAAG,MAAM,MAAM;AAAA,EAC1B,CAAC;AAID,MAAI;AACJ,QAAM,WAAW,OAAO,KAAK,OAAO,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI;AACvD,QAAM,UAAU,OAAO;AACvB,MAAI,UAAU;AACZ,aAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,UAAI,SAAS,MAAM,CAAC,MAAM,QAAQ,CAAC,GAAG;AACpC,kCAA0B;AAC1B;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAGA,QAAM,mBAAyC,OAAO,KAAK,IAAI,CAAC,OAAO;AAAA,IACrE,OAAOA,MAAK,cAAc,EAAE,KAAK,CAAC;AAAA,IAClC,OAAO,EAAE;AAAA,IACT,MAAM,EAAE;AAAA,EACV,EAAE;AAEF,SAAO;AAAA,IACL,SAASA,MAAK,cAAc,OAAO,CAAC;AAAA,IACpC,MAAM;AAAA,IACN,WAAW,OAAO;AAAA,IAClB,mBAAmB,OAAO;AAAA,IAC1B;AAAA,EACF;AACF;;;AC3IA,eAAsB,kBACpB,OACA,eACA,UACA,QAC+B;AAC/B,QAAM,cAAc,MAAM,MAAM,OAAO,aAAa;AACpD,MAAI,CAAC,YAAa,OAAM,IAAI,cAAc,uBAAuB,aAAa,YAAY;AAC1F,QAAM,aAAa,MAAM,gBAAgB,OAAO,aAAa;AAC7D,MAAI,SAAS,KAAK,KAAK,SAAS,MAAM,WAAW,MAAM,QAAQ;AAC7D,UAAM,IAAI;AAAA,MACR,+BAA+B,SAAS,EAAE,qBAAqB,WAAW,MAAM,MAAM;AAAA,IACxF;AAAA,EACF;AACA,QAAM,aAAa,WAAW,MAAM,SAAS,EAAE;AAC/C,QAAM,cAAc,cAAc,YAAY,QAAQ;AAEtD,QAAM,YAAY,IAAI,aAAa,KAAK;AACxC,QAAM,UAAU,SAAS;AAAA,IACvB,YAAY,YAAY;AAAA,IACxB,WAAW,YAAY,YACnB,GAAG,YAAY,SAAS,OAAO,SAAS,IAAI,IAAI,SAAS,EAAE,KAC3D,MAAM,SAAS,IAAI,IAAI,SAAS,EAAE;AAAA,IACtC,WAAW,YAAY;AAAA,IACvB,aAAa;AAAA,IACb,OAAO;AAAA,IACP,MAAM,EAAE,gBAAgB,QAAQ,cAAc,SAAS,MAAM,YAAY,OAAO,SAAS,EAAE,EAAE;AAAA,EAC/F,CAAC;AAED,QAAM,OAAO;AAAA,IACX;AAAA,MACE;AAAA,MACA,oBAAoB;AAAA,MACpB,QAAQ,WAAW,MAAM,MAAM,GAAG,SAAS,EAAE;AAAA,MAC7C;AAAA,MACA;AAAA,IACF;AAAA,IACA;AAAA,EACF;AAEA,QAAM,iBAAiB,MAAM,MAAM,OAAO,UAAU,KAAK;AACzD,QAAM,QAAQ;AAAA,IACZ,sBAAsB,YAAY,SAAS,SAAS;AAAA,IACpD,4BAA4B,gBAAgB,SAAS,SAAS;AAAA,IAC9D,YACE,YAAY,SAAS,UAAU,UAAa,gBAAgB,SAAS,UAAU,SAC3E,eAAe,QAAQ,QAAQ,YAAY,QAAQ,QACnD;AAAA,EACR;AACA,SAAO,EAAE,qBAAqB,UAAU,OAAO,eAAe,UAAU,MAAM;AAChF;AAEA,SAAS,cAAc,MAAsB,UAAkD;AAC7F,MAAI,SAAS,SAAS,gBAAgB,KAAK,KAAK,SAAS,OAAO;AAC9D,UAAM,MAAM,KAAK;AACjB,WAAO,EAAE,GAAG,MAAM,MAAM,EAAE,GAAG,KAAK,OAAO,SAAS,SAAS,EAAE;AAAA,EAC/D;AACA,MAAI,SAAS,SAAS,sBAAsB,KAAK,KAAK,SAAS,QAAQ;AACrE,UAAM,OAAO,KAAK;AAClB,WAAO,EAAE,GAAG,MAAM,MAAM,EAAE,GAAG,MAAM,QAAQ,SAAS,UAAU,EAAE;AAAA,EAClE;AACA,MAAI,SAAS,SAAS,2BAA2B,KAAK,KAAK,SAAS,OAAO;AACzE,UAAM,MAAM,KAAK;AACjB,WAAO;AAAA,MACL,GAAG;AAAA,MACH,MAAM;AAAA,QACJ,GAAG;AAAA,QACH,UAAU,CAAC,EAAE,MAAM,UAAU,SAAS,SAAS,QAAQ,GAAG,GAAG,IAAI,QAAQ;AAAA,MAC3E;AAAA,IACF;AAAA,EACF;AACA,MAAI,SAAS,SAAS,SAAU,QAAO,SAAS,MAAM,IAAI;AAE1D,SAAO;AACT;AAQO,SAAS,yBAAyB,SAKtC;AACD,QAAM,UAAU,oBAAI,IAAoC;AACxD,aAAW,KAAK,SAAS;AACvB,UAAM,MAAM,QAAQ,IAAI,EAAE,SAAS,IAAI,KAAK,CAAC;AAC7C,QAAI,KAAK,CAAC;AACV,YAAQ,IAAI,EAAE,SAAS,MAAM,GAAG;AAAA,EAClC;AACA,QAAM,MAKD,CAAC;AACN,aAAW,CAAC,MAAM,KAAK,KAAK,SAAS;AACnC,UAAM,SAAS,MACZ,IAAI,CAAC,MAAM,EAAE,MAAM,UAAU,EAC7B,OAAO,CAAC,MAAmB,OAAO,MAAM,QAAQ;AACnD,QAAI,OAAO,WAAW,EAAG;AACzB,UAAM,UAAU,OAAO,OAAO,CAAC,GAAG,MAAM,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,IAAI,OAAO;AACrE,UAAM,aAAa,OAAO,OAAO,CAAC,GAAG,MAAM,IAAI,GAAG,CAAC,IAAI,OAAO;AAC9D,QAAI,KAAK;AAAA,MACP,cAAc;AAAA,MACd,GAAG,OAAO;AAAA,MACV,cAAc;AAAA,MACd,iBAAiB;AAAA,IACnB,CAAC;AAAA,EACH;AACA,SAAO,IAAI,KAAK,CAAC,GAAG,MAAM,EAAE,eAAe,EAAE,YAAY;AAC3D;;;ACjIA,eAAsB,eACpB,OACA,MACA,MACA,UAAiC,CAAC,GACT;AACzB,QAAM,CAAC,GAAG,CAAC,IAAI,MAAM,QAAQ,IAAI,CAAC,gBAAgB,OAAO,IAAI,GAAG,gBAAgB,OAAO,IAAI,CAAC,CAAC;AAC7F,QAAM,KAAK,QAAQ,cAAc;AACjC,QAAM,YAAY,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE;AAE5C,QAAM,CAAC,SAAS,OAAO,IAAI,MAAM,QAAQ,IAAI;AAAA,IAC3C,MAAM,MAAM,EAAE,OAAO,MAAM,MAAM,QAAQ,CAAC,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO,WAAW,CAAC;AAAA,IAC7E,MAAM,MAAM,EAAE,OAAO,MAAM,MAAM,QAAQ,CAAC,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO,WAAW,CAAC;AAAA,EAC/E,CAAC;AACD,QAAM,eAAe,iBAAiB,OAAO;AAC7C,QAAM,eAAe,iBAAiB,OAAO;AAE7C,QAAM,eAAkC,UAAU;AAAA,IAAI,CAAC,OACrD,cAAc,IAAI,cAAc,YAAY;AAAA,EAC9C;AACA,QAAM,cAAc,aAAa,OAAO,CAAC,KAAK,OAAO,OAAO,GAAG,YAAY,IAAI,CAAC;AAEhF,QAAM,CAAC,SAAS,OAAO,IAAI,MAAM,QAAQ,IAAI,CAAC,MAAM,OAAO,IAAI,GAAG,MAAM,OAAO,IAAI,CAAC,CAAC;AACrF,QAAM,kBACJ,SAAS,SAAS,UAAU,UAAa,SAAS,SAAS,UAAU,SACjE,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QACxC;AAEN,SAAO,EAAE,MAAM,MAAM,WAAW,cAAc,iBAAiB,YAAY;AAC7E;AAIA,SAAS,MACP,GACA,GACA,IACe;AACf,QAAM,KAAiB,MAAM,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,MAAM,IAAI,MAAM,EAAE,SAAS,CAAC,EAAE,KAAK,CAAC,CAAC;AACjG,WAASC,KAAI,GAAGA,MAAK,EAAE,QAAQA,MAAK;AAClC,aAASC,KAAI,GAAGA,MAAK,EAAE,QAAQA,MAAK;AAClC,UAAI,GAAG,EAAED,KAAI,CAAC,GAAI,EAAEC,KAAI,CAAC,CAAE,EAAG,IAAGD,EAAC,EAAGC,EAAC,IAAI,GAAGD,KAAI,CAAC,EAAGC,KAAI,CAAC,IAAK;AAAA,UAC1D,IAAGD,EAAC,EAAGC,EAAC,IAAI,KAAK,IAAI,GAAGD,KAAI,CAAC,EAAGC,EAAC,GAAI,GAAGD,EAAC,EAAGC,KAAI,CAAC,CAAE;AAAA,IAC1D;AAAA,EACF;AAEA,QAAM,MAAqB,CAAC;AAC5B,MAAI,IAAI,EAAE;AACV,MAAI,IAAI,EAAE;AACV,SAAO,IAAI,KAAK,IAAI,GAAG;AACrB,QAAI,IAAI,KAAK,IAAI,KAAK,GAAG,EAAE,IAAI,CAAC,GAAI,EAAE,IAAI,CAAC,CAAE,GAAG;AAC9C,UAAI,KAAK,EAAE,IAAI,SAAS,GAAG,EAAE,IAAI,CAAC,GAAI,GAAG,EAAE,IAAI,CAAC,EAAG,CAAC;AACpD;AACA;AAAA,IACF,WAAW,IAAI,KAAK,IAAI,KAAK,GAAG,IAAI,CAAC,EAAG,CAAC,MAAO,GAAG,CAAC,EAAG,IAAI,CAAC,GAAI;AAE9D,UAAI,EAAE,IAAI,CAAC,EAAG,KAAK,SAAS,EAAE,IAAI,CAAC,EAAG,KAAK,MAAM;AAC/C,YAAI,KAAK,EAAE,IAAI,WAAW,GAAG,EAAE,IAAI,CAAC,GAAI,GAAG,EAAE,IAAI,CAAC,EAAG,CAAC;AACtD;AACA;AAAA,MACF,WAAW,GAAG,IAAI,CAAC,EAAG,CAAC,KAAM,GAAG,CAAC,EAAG,IAAI,CAAC,GAAI;AAC3C,YAAI,KAAK,EAAE,IAAI,UAAU,GAAG,EAAE,IAAI,CAAC,EAAG,CAAC;AACvC;AAAA,MACF,OAAO;AACL,YAAI,KAAK,EAAE,IAAI,UAAU,GAAG,EAAE,IAAI,CAAC,EAAG,CAAC;AACvC;AAAA,MACF;AAAA,IACF,WAAW,IAAI,MAAM,MAAM,KAAK,GAAG,IAAI,CAAC,EAAG,CAAC,KAAM,GAAG,CAAC,EAAG,IAAI,CAAC,IAAK;AACjE,UAAI,KAAK,EAAE,IAAI,UAAU,GAAG,EAAE,IAAI,CAAC,EAAG,CAAC;AACvC;AAAA,IACF,OAAO;AACL,UAAI,KAAK,EAAE,IAAI,UAAU,GAAG,EAAE,IAAI,CAAC,EAAG,CAAC;AACvC;AAAA,IACF;AAAA,EACF;AACA,SAAO,IAAI,QAAQ;AACrB;AAEA,SAAS,kBAAkB,GAAmB,GAA4B;AACxE,MAAI,EAAE,KAAK,SAAS,EAAE,KAAK,KAAM,QAAO;AACxC,MAAI,EAAE,KAAK,SAAS,UAAU,EAAE,KAAK,SAAS,OAAQ,QAAO,EAAE,KAAK,aAAa,EAAE,KAAK;AACxF,MAAI,EAAE,KAAK,SAAS,SAAS,EAAE,KAAK,SAAS,MAAO,QAAO,EAAE,KAAK,UAAU,EAAE,KAAK;AACnF,SAAO,EAAE,KAAK,SAAS,EAAE,KAAK;AAChC;AAIA,SAAS,iBAAiB,QAA0C;AAClE,QAAM,MAAM,oBAAI,IAAoB;AACpC,aAAW,KAAK,QAAQ;AACtB,UAAM,QAAQ,IAAI,IAAI,EAAE,YAAY,KAAK;AACzC,QAAI,IAAI,EAAE,cAAc,QAAQ,EAAE,KAAK;AAAA,EACzC;AACA,SAAO;AACT;AAEA,SAAS,YAAY,GAAwB;AAC3C,SAAO,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,YAAY;AAC9D;AAEA,SAAS,WAAW,GAAwB;AAC1C,MAAI,EAAE,SAAS,MAAO,QAAO;AAC7B,UAAQ,EAAE,eAAe,MAAM,EAAE,gBAAgB;AACnD;AAEA,SAAS,cACP,IACA,MACA,MACiB;AACjB,MAAI,GAAG,OAAO,SAAS;AACrB,UAAMC,MAAK,KAAK,IAAI,GAAG,EAAE,KAAK,MAAM;AACpC,UAAM,KAAK,KAAK,IAAI,GAAG,EAAE,KAAK,MAAM;AACpC,UAAM,WAAWA,QAAO,UAAa,OAAO,SAAY,KAAKA,MAAK;AAClE,UAAM,KAAK,YAAY,GAAG,EAAE,IAAI;AAChC,UAAM,KAAK,YAAY,GAAG,EAAE,IAAI;AAChC,UAAM,KAAK,WAAW,GAAG,EAAE,IAAI;AAC/B,UAAM,KAAK,WAAW,GAAG,EAAE,IAAI;AAC/B,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,gBAAgB,OAAO,QAAQ,OAAO,OAAO,KAAK,KAAK;AAAA,MACvD,YAAY,OAAO,QAAQ,OAAO,OAAO,KAAK,KAAK;AAAA,MACnD,MACE,aAAa,OAAO,kCAAkC;AAAA,IAC1D;AAAA,EACF;AACA,MAAI,GAAG,OAAO,WAAW;AACvB,UAAMA,MAAK,KAAK,IAAI,GAAG,EAAE,KAAK,MAAM,KAAK;AACzC,UAAM,KAAK,KAAK,IAAI,GAAG,EAAE,KAAK,MAAM,KAAK;AACzC,WAAO;AAAA,MACL;AAAA,MACA,UAAU,KAAKA;AAAA,MACf,gBAAgB;AAAA,MAChB,YAAY;AAAA,MACZ,MAAM,YAAY,GAAG,EAAE,KAAK,IAAI,IAAI,GAAG,EAAE,KAAK,IAAI,WAAM,GAAG,EAAE,KAAK,IAAI,IAAI,GAAG,EAAE,KAAK,IAAI;AAAA,IAC1F;AAAA,EACF;AACA,MAAI,GAAG,OAAO,UAAU;AACtB,UAAM,KAAK,KAAK,IAAI,GAAG,EAAE,KAAK,MAAM,KAAK;AACzC,WAAO;AAAA,MACL;AAAA,MACA,UAAU;AAAA,MACV,gBAAgB;AAAA,MAChB,YAAY;AAAA,MACZ,MAAM,uBAAuB,GAAG,EAAE,KAAK,IAAI,IAAI,GAAG,EAAE,KAAK,IAAI;AAAA,IAC/D;AAAA,EACF;AAEA,QAAM,KAAK,KAAK,IAAI,GAAG,EAAE,KAAK,MAAM,KAAK;AACzC,SAAO;AAAA,IACL;AAAA,IACA,UAAU,CAAC;AAAA,IACX,gBAAgB;AAAA,IAChB,YAAY;AAAA,IACZ,MAAM,wBAAwB,GAAG,EAAE,KAAK,IAAI,IAAI,GAAG,EAAE,KAAK,IAAI;AAAA,EAChE;AACF;;;AC/JA,eAAsB,wBACpB,SACA,YACA,UAAiC,CAAC,GACN;AAC5B,QAAM,aAAa,QAAQ,cAAc;AACzC,QAAM,oBAAoB,QAAQ,qBAAqB;AACvD,QAAM,OAAO,QAAQ,QAAQ;AAC7B,QAAM,YAAY,QAAQ,IAAI;AAE9B,QAAM,UAA6B,CAAC;AAGpC,QAAM,QAA8C,CAAC,QAAQ,UAAU,QAAQ,SAAS;AACxF,aAAW,QAAQ,OAAO;AACxB,UAAM,QAAQ,UAAU,OAAO,CAAC,MAAM,EAAE,eAAe,IAAI,EAAE;AAC7D,QAAI,QAAQ,YAAY;AACtB,YAAM,YAAY,UAAU,OAAO,CAAC,MAAM,EAAE,eAAe,IAAI,EAAE,MAAM,GAAG,CAAC;AAC3E,cAAQ,KAAK;AAAA,QACX,QAAQ;AAAA,QACR,aAAa,eAAe,IAAI,SAAS,KAAK,qCAAgC,UAAU;AAAA,QACxF,WAAW,CAAC,GAAG,SAAS;AAAA,QACxB,WAAW,gBAAgB,IAAI;AAAA,QAC/B,UAAU,KAAK,IAAI,GAAG,IAAI,QAAQ,UAAU;AAAA,MAC9C,CAAC;AAAA,IACH;AAAA,EACF;AAGA,QAAM,OAAO,MAAM,WAAW,SAAS;AACvC,QAAM,qBAAqB,oBAAI,IAAoB;AACnD,aAAW,KAAK,MAAM;AACpB,uBAAmB,IAAI,EAAE,aAAa,mBAAmB,IAAI,EAAE,UAAU,KAAK,KAAK,CAAC;AAAA,EACtF;AACA,QAAM,YAAY,CAAC,GAAG,mBAAmB,OAAO,CAAC;AACjD,QAAM,MAAM,UAAU,SAAS,IAAI,SAAS,WAAW,IAAI,IAAI;AAC/D,aAAW,KAAK,WAAW;AACzB,UAAM,QAAQ,mBAAmB,IAAI,EAAE,EAAE,KAAK;AAC9C,QAAI,SAAS,OAAO,QAAQ,GAAG;AAC7B,cAAQ,KAAK;AAAA,QACX,QAAQ;AAAA,QACR,aAAa,aAAa,EAAE,EAAE,cAAc,KAAK;AAAA,QACjD,WAAW,CAAC,CAAC;AAAA,QACb,WAAW,8BAA8B,EAAE,EAAE;AAAA,QAC7C,UAAU,KAAK,IAAI,GAAG,IAAI,QAAQ,CAAC,IAAI;AAAA,MACzC,CAAC;AAAA,IACH;AAAA,EACF;AAGA,aAAW,KAAK,WAAW;AACzB,UAAM,QAAQ,KAAK,OAAO,CAAC,MAAM,EAAE,eAAe,EAAE,EAAE;AACtD,UAAMC,UAAS,MACZ,IAAI,CAAC,MAAM,EAAE,SAAS,KAAK,EAC3B,OAAO,CAAC,MAAmB,OAAO,MAAM,QAAQ;AACnD,QAAIA,QAAO,SAAS,EAAG;AACvB,UAAMC,QAAOD,QAAO,OAAO,CAAC,GAAG,MAAM,IAAI,GAAG,CAAC,IAAIA,QAAO;AACxD,UAAM,WAAWA,QAAO,OAAO,CAAC,GAAG,MAAM,KAAK,IAAIC,UAAS,GAAG,CAAC,IAAID,QAAO;AAC1E,QAAI,WAAW,mBAAmB;AAChC,cAAQ,KAAK;AAAA,QACX,QAAQ;AAAA,QACR,aAAa,aAAa,EAAE,EAAE,oCAAoC,SAAS,QAAQ,CAAC,CAAC;AAAA,QACrF,WAAW,CAAC,CAAC;AAAA,QACb,WAAW;AAAA,QACX,UAAU,KAAK,IAAI,GAAG,WAAW,CAAC;AAAA,MACpC,CAAC;AAAA,IACH;AAAA,EACF;AAGA,QAAM,iBAAiB,oBAAI,IAAmB;AAC9C,aAAW,OAAO,MAAM;AACtB,QAAI,IAAI,SAAS,SAAS,KAAM;AAChC,UAAM,QAAQ,MAAM,WAAW,MAAM,EAAE,OAAO,IAAI,MAAM,CAAC;AACzD,UAAM,SAAS,MAAM,WAAW,OAAO,EAAE,OAAO,IAAI,MAAM,CAAC;AAC3D,UAAM,EAAE,aAAa,IAAI,gBAAgB,EAAE,KAAK,OAAO,OAAO,CAAC;AAC/D,QAAI,iBAAiB,aAAa,iBAAiB,UAAW;AAC9D,UAAM,MAAM,eAAe,IAAI,YAAY,KAAK,CAAC;AACjD,QAAI,KAAK,GAAG;AACZ,mBAAe,IAAI,cAAc,GAAG;AAAA,EACtC;AACA,aAAW,CAAC,KAAKE,KAAI,KAAK,gBAAgB;AACxC,QAAIA,MAAK,SAAS,EAAG;AACrB,UAAM,oBAAoB,CAAC,GAAG,IAAI,IAAIA,MAAK,IAAI,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;AACpE,UAAM,YAAY,UAAU,OAAO,CAAC,MAAM,kBAAkB,SAAS,EAAE,EAAE,CAAC,EAAE,MAAM,GAAG,CAAC;AACtF,YAAQ,KAAK;AAAA,MACX,QAAQ;AAAA,MACR,aAAa,kBAAkB,GAAG,cAAcA,MAAK,MAAM,eAAY,kBAAkB,MAAM;AAAA,MAC/F;AAAA,MACA,WAAW,mCAAmC,GAAG;AAAA,MACjD,UAAU,KAAK,IAAI,GAAGA,MAAK,SAAS,EAAE;AAAA,IACxC,CAAC;AAAA,EACH;AAEA,SAAO,QAAQ,KAAK,CAAC,GAAG,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;AACtE;AAEA,SAAS,SAAS,IAAc,GAAmB;AACjD,QAAM,SAAS,CAAC,GAAG,EAAE,EAAE,KAAK,CAAC,GAAG,MAAM,IAAI,CAAC;AAC3C,QAAM,MAAM,KAAK,OAAO,SAAS;AACjC,QAAM,KAAK,KAAK,MAAM,GAAG;AACzB,QAAM,KAAK,KAAK,KAAK,GAAG;AACxB,SAAO,OAAO,EAAE,KAAM,OAAO,EAAE,IAAK,OAAO,EAAE,MAAO,MAAM;AAC5D;;;ACzGO,SAAS,kBAAkB,OAAiD;AACjF,MAAI,MAAM,SAAS,EAAG,OAAM,IAAI,MAAM,4DAAuD;AAC7F,QAAM,UAAU,OAAO,KAAK,MAAM,CAAC,EAAG,MAAM;AAC5C,MAAI,QAAQ,SAAS,EAAG,OAAM,IAAI,MAAM,0CAAqC;AAE7E,QAAM,YAAY,MAAM,IAAI,CAAC,MAAM,EAAE,KAAK;AAC1C,QAAM,YAAY,UAAU,OAAO,CAAC,GAAG,MAAM,IAAI,GAAG,CAAC,IAAI,UAAU;AACnE,QAAM,gBACJ,UAAU,OAAO,CAAC,KAAK,MAAM,OAAO,IAAI,cAAc,GAAG,CAAC,IAAI,UAAU;AAC1E,MAAI,kBAAkB,GAAG;AACvB,WAAO;AAAA,MACL,eAAe;AAAA,MACf,aAAa,QAAQ,IAAI,CAAC,OAAO,EAAE,QAAQ,GAAG,iBAAiB,GAAG,OAAO,EAAE,EAAE;AAAA,MAC7E,cAAc,CAAC;AAAA,MACf,eAAe;AAAA,MACf,WAAW;AAAA,IACb;AAAA,EACF;AAGA,QAAM,cAAoC,QAAQ,IAAI,CAAC,MAAM;AAC3D,UAAM,UAAUC,SAAQ,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,EAAE;AACvD,UAAM,QAAkB,CAAC;AACzB,eAAW,OAAO,QAAQ,OAAO,GAAG;AAClC,YAAM,KAAK,IAAI,OAAO,CAAC,GAAG,MAAM,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,MAAM;AAAA,IAC9D;AACA,UAAM,eAAe,MAAM,OAAO,CAAC,KAAK,MAAM,OAAO,IAAI,cAAc,GAAG,CAAC,IAAI,MAAM;AACrF,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,iBAAiB,eAAe;AAAA,MAChC,OAAO,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,IAAI,GAAG,KAAK;AAAA,IAC/C;AAAA,EACF,CAAC;AAGD,QAAM,eAA0C,CAAC;AACjD,WAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACvC,aAAS,IAAI,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AAC3C,YAAM,KAAK,QAAQ,CAAC;AACpB,YAAM,KAAK,QAAQ,CAAC;AACpB,YAAM,SAASA,SAAQ,OAAO,CAAC,MAAM,GAAG,EAAE,OAAO,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE;AACtE,YAAM,YAAsB,CAAC;AAC7B,iBAAW,OAAO,OAAO,OAAO,GAAG;AACjC,kBAAU,KAAK,IAAI,OAAO,CAAC,GAAG,MAAM,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,MAAM;AAAA,MAClE;AACA,YAAM,eACJ,UAAU,OAAO,CAAC,KAAK,MAAM,OAAO,IAAI,cAAc,GAAG,CAAC,IAAI,UAAU;AAC1E,YAAM,QAAQ,YAAY,CAAC,EAAG,kBAAkB;AAChD,YAAM,QAAQ,YAAY,CAAC,EAAG,kBAAkB;AAChD,YAAM,sBAAsB,KAAK,IAAI,GAAG,eAAe,QAAQ,KAAK;AACpE,mBAAa,KAAK;AAAA,QAChB,SAAS,CAAC,IAAI,EAAE;AAAA,QAChB,iBAAiB,sBAAsB;AAAA,MACzC,CAAC;AAAA,IACH;AAAA,EACF;AAEA,QAAM,UAAU,YAAY,OAAO,CAAC,GAAG,MAAM,IAAI,EAAE,iBAAiB,CAAC;AACrE,QAAM,iBAAiB,aAAa,OAAO,CAAC,GAAG,MAAM,IAAI,EAAE,iBAAiB,CAAC;AAC7E,QAAM,gBAAgB,KAAK,IAAI,GAAG,IAAI,UAAU,cAAc;AAC9D,QAAM,YAAY,UAAU,iBAAiB;AAC7C,SAAO,EAAE,eAAe,aAAa,cAAc,eAAe,UAAU;AAC9E;AAEA,SAASA,SAAW,OAAY,KAAyC;AACvE,QAAM,IAAI,oBAAI,IAAiB;AAC/B,aAAW,QAAQ,OAAO;AACxB,UAAM,IAAI,IAAI,IAAI;AAClB,UAAM,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC;AACzB,QAAI,KAAK,IAAI;AACb,MAAE,IAAI,GAAG,GAAG;AAAA,EACd;AACA,SAAO;AACT;;;ACrFA,eAAsB,kBACpB,OACA,QACA,QAC8B;AAC9B,QAAM,SAAS,MAAM,QAAQ,IAAI,OAAO,IAAI,CAAC,OAAO,OAAO,MAAM,OAAO,EAAE,CAAC,CAAC;AAC5E,QAAM,UAAU,MAAM,mBAAmB,OAAO,MAAM;AACtD,QAAM,UAAU,CAAC,GAAG,IAAI,IAAI,QAAQ,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;AAC3D,QAAM,aACJ,QAAQ,SAAS,IAAI,QAAQ,OAAO,CAAC,GAAG,MAAM,IAAI,EAAE,OAAO,CAAC,IAAI,QAAQ,SAAS;AACnF,SAAO;AAAA,IACL,SAAS;AAAA,IACT,UAAU;AAAA,MACR,SAAS,OAAO;AAAA,MAChB,UAAU,QAAQ;AAAA,MAClB;AAAA,MACA,aAAY,oBAAI,KAAK,GAAE,YAAY;AAAA,MACnC;AAAA,IACF;AAAA,IACA,gBAAgB,SAAS,OAAO;AAAA,EAClC;AACF;AAaO,SAAS,qBAAqB,QAAoC;AACvE,SAAO;AAAA,IACL,MAAM,MAAM,YAAY,OAAO;AAC7B,YAAM,SAAS,MAAM,OAAO,MAAM,OAAO,WAAW,KAAK;AACzD,aAAO,OAAO;AAAA,IAChB;AAAA,IACA,UAAU;AAAA,MACR,SAAS,CAAC,eAAe;AAAA,MACzB,eAAe;AAAA,IACjB;AAAA,EACF;AACF;AAQA,eAAsB,uBACpB,OACA,QACA,QAC+E;AAC/E,SAAO,QAAQ;AAAA,IACb,OAAO,IAAI,OAAO,UAAU;AAC1B,YAAM,CAAC,YAAY,GAAG,IAAI,MAAM,QAAQ,IAAI;AAAA,QAC1C,gBAAgB,OAAO,KAAK;AAAA,QAC5B,MAAM,OAAO,KAAK;AAAA,MACpB,CAAC;AACD,aAAO;AAAA,QACL;AAAA,QACA,OAAO,MAAM,OAAO,MAAM,YAAY,KAAK;AAAA,QAC3C,cAAc,KAAK,SAAS,SAAS;AAAA,MACvC;AAAA,IACF,CAAC;AAAA,EACH;AACF;;;AC1CA,eAAsB,YACpB,UACA,QACA,SACA,UAA2B,CAAC,GAC6B;AACzD,MAAI,QAAQ,SAAS;AACnB,UAAM,IAAI,MAAM,yEAAyE;AAC3F,QAAM,YAAY,QAAQ,aAAa;AACvC,QAAM,QAAQ,QAAQ,oBAAoB;AAC1C,QAAM,eAAe,QAAQ,gBAAgB;AAC7C,QAAM,cAAc,QAAQ,UAAU;AAEtC,QAAM,YAA8B,CAAC;AACrC,MAAI,iBAAsC,CAAC;AAC3C,QAAM,mBAAsC,CAAC;AAE7C,WAAS,IAAI,GAAG,IAAI,aAAa,KAAK;AACpC,UAAM,WAAW,MAAM,SAAS,QAAQ,GAAG,cAAc;AACzD,UAAM,SAA4C,CAAC;AACnD,UAAM,WAAuC,CAAC;AAC9C,UAAM,YAAiC,CAAC;AACxC,eAAW,aAAa,UAAU;AAChC,YAAMC,UAAS,MAAM,OAAO,eAAe,WAAW,OAAO;AAC7D,UAAIA,QAAO,SAAS,GAAG;AACrB,iBAAS,KAAK,EAAE,WAAW,QAAQ,6BAA6B,CAAC;AACjE;AAAA,MACF;AACA,YAAM,SAASA,QAAO,IAAI,CAAC,MAAM,EAAE,KAAK;AACxC,YAAM,SAAS,KAAK,IAAI,GAAG,MAAM,IAAI,KAAK,IAAI,GAAG,MAAM;AACvD,YAAM,WAAW,KAAK,IAAI,GAAG,MAAM;AACnC,aAAO,KAAK,EAAE,WAAW,QAAAA,SAAQ,OAAO,CAAC;AACzC,UAAI,WAAW,OAAO;AACpB,iBAAS,KAAK;AAAA,UACZ;AAAA,UACA,QAAQ,iCAAiC,SAAS,QAAQ,CAAC,CAAC,MAAM,KAAK;AAAA,QACzE,CAAC;AACD;AAAA,MACF;AACA,UAAI,SAAS,WAAW;AACtB,iBAAS,KAAK;AAAA,UACZ;AAAA,UACA,QAAQ,2BAA2B,OAAO,QAAQ,CAAC,CAAC,MAAM,SAAS;AAAA,QACrE,CAAC;AACD;AAAA,MACF;AACA,gBAAU,KAAK,SAAS;AAAA,IAC1B;AAGA,cAAU,KAAK,CAAC,GAAG,MAAM;AACvB,YAAM,KAAK,OAAO,KAAK,CAAC,MAAM,EAAE,UAAU,OAAO,EAAE,EAAE,GAAG,UAAU;AAClE,YAAM,KAAK,OAAO,KAAK,CAAC,MAAM,EAAE,UAAU,OAAO,EAAE,EAAE,GAAG,UAAU;AAClE,aAAO,KAAK;AAAA,IACd,CAAC;AACD,UAAM,SAAS,UAAU,MAAM,GAAG,YAAY;AAE9C,eAAW,KAAK,QAAQ;AACtB,uBAAiB,KAAK;AAAA,QACpB,IAAI,EAAE;AAAA,QACN,SAAS,EAAE;AAAA,QACX,OAAO;AAAA,QACP,MAAM,EAAE,GAAG,EAAE,MAAM,gBAAgB,OAAO,CAAC,GAAG,QAAQ,YAAY;AAAA,MACpE,CAAC;AAAA,IACH;AAEA,cAAU,KAAK,EAAE,OAAO,GAAG,UAAU,UAAU,QAAQ,UAAU,iBAAiB,OAAO,CAAC;AAC1F,qBAAiB;AAAA,EACnB;AAEA,QAAM,UAAU,IAAI,QAAQ;AAAA,IAC1B,MAAM;AAAA,IACN,YAAY;AAAA,MACV,SAAS;AAAA,MACT,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MAClC,aAAa;AAAA,MACb,aAAa,kBAAkB,WAAW,cAAc,UAAU,OAAO,CAAC,GAAG,MAAM,IAAI,EAAE,SAAS,QAAQ,CAAC,CAAC;AAAA,IAC9G;AAAA,IACA,WAAW;AAAA,EACb,CAAC;AACD,SAAO,EAAE,QAAQ,WAAW,QAAQ;AACtC;;;AChIA,SAAS,iBAAiB;AAC1B,SAAS,cAAAC,aAAY,eAAAC,cAAa,gBAAAC,eAAc,YAAAC,iBAAgB;AAChE,SAAS,QAAAC,aAAY;AAiEd,IAAM,qBAAoC;AAAA,EAC/C,MAAM;AAAA,EACN,MAAM,IAAI,OAAmD;AAC3D,UAAM,QAAQ,KAAK,IAAI;AACvB,UAAM,MAAM,UAAU,MAAM,KAAK,MAAM,MAAM;AAAA,MAC3C,KAAK,MAAM;AAAA,MACX,UAAU;AAAA,MACV,SAAS,MAAM;AAAA,MACf,KAAK,EAAE,GAAG,QAAQ,KAAK,IAAI,KAAK,GAAI,MAAM,OAAO,CAAC,EAAG;AAAA,MACrD,OAAO,MAAM;AAAA,IACf,CAAC;AACD,UAAM,aAAa,KAAK,IAAI,IAAI;AAChC,UAAM,WAAW,CAAC,EAChB,IAAI,SACJ,UAAU,IAAI,SACb,IAAI,MAAgC,SAAS;AAEhD,WAAO;AAAA,MACL,QAAQ,IAAI,UAAU;AAAA,MACtB,SAAS,IAAI,UAAU,IAAI,SAAS;AAAA,MACpC,SAAS,IAAI,UAAU,IAAI,SAAS;AAAA,MACpC;AAAA,MACA;AAAA,MACA,aAAa,IAAI,SAAS,CAAC,WAAW,OAAO,IAAI,MAAM,WAAW,IAAI,KAAK,IAAI;AAAA,IACjF;AAAA,EACF;AAAA,EACA,MAAM,OAAO,MAAgC;AAC3C,UAAM,IAAI,UAAU,SAAS,CAAC,IAAI,GAAG,EAAE,UAAU,QAAQ,SAAS,IAAK,CAAC;AACxE,WAAO,EAAE,WAAW,MAAM,EAAE,UAAU,IAAI,KAAK,EAAE,SAAS;AAAA,EAC5D;AAAA,EACA,MAAM,WAAW,MAAgC;AAC/C,WAAOJ,YAAW,IAAI;AAAA,EACxB;AAAA,EACA,MAAM,SAAS,MAAsC;AACnD,QAAI;AACF,aAAOE,cAAa,MAAM,MAAM;AAAA,IAClC,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EACA,MAAM,QAAQ,MAAmC;AAC/C,QAAI;AACJ,QAAI;AACF,gBAAUD,aAAY,IAAI;AAAA,IAC5B,QAAQ;AACN,aAAO,CAAC;AAAA,IACV;AACA,UAAM,MAAkB,CAAC;AACzB,eAAW,QAAQ,SAAS;AAC1B,UAAI;AACF,cAAM,KAAKE,UAASC,MAAK,MAAM,IAAI,CAAC;AACpC,YAAI,KAAK;AAAA,UACP;AAAA,UACA,aAAa,GAAG,YAAY;AAAA,UAC5B,QAAQ,GAAG,OAAO;AAAA,UAClB,WAAW,GAAG,OAAO,IAAI,GAAG,OAAO;AAAA,QACrC,CAAC;AAAA,MACH,QAAQ;AAAA,MAER;AAAA,IACF;AACA,WAAO;AAAA,EACT;AACF;;;AC/EO,SAAS,gBAA+B,OAAyC;AACtF,QAAM,kBAAkB,MAAM,mBAAmB;AACjD,SAAO;AAAA,IACL,MAAM,MAAM,QAAQ;AAAA,IACpB,WAAW,MAAM,aAAa,CAAC,OAAO;AAAA,IACtC,QAAQ,MAAM,UAAU;AAAA,IACxB,OAAO,MAAM,SAAS;AAAA,IACtB,KAAK,OAAO,QAAQ;AAClB,YAAM,QAAQ,KAAK,IAAI;AACvB,UAAI;AACJ,UAAI;AACF,iBAAS,MAAM,MAAM,OAAO;AAAA,MAC9B,SAAS,KAAK;AACZ,eAAO;AAAA,UACL,OAAO,MAAM,QAAQ;AAAA,UACrB,QAAQ;AAAA,UACR,YAAY,KAAK,IAAI,IAAI;AAAA,UACzB,UAAU;AAAA,YACR;AAAA,cACE,UAAU;AAAA,cACV,SAAS,kCAAkC,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,YAC7F;AAAA,UACF;AAAA,UACA,QAAQ;AAAA,QACV;AAAA,MACF;AACA,UAAI;AACJ,UAAI;AACF,iBAAS,MAAM,OAAO,IAAI;AAAA,MAC5B,SAAS,KAAK;AACZ,eAAO;AAAA,UACL,OAAO,MAAM,QAAQ;AAAA,UACrB,QAAQ;AAAA,UACR,YAAY,KAAK,IAAI,IAAI;AAAA,UACzB,UAAU;AAAA,YACR;AAAA,cACE,UAAU;AAAA,cACV,SAAS,yBAAyB,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,YACpF;AAAA,UACF;AAAA,UACA,QAAQ;AAAA,QACV;AAAA,MACF;AACA,UAAI,IAAI,OAAO,SAAS;AACtB,eAAO;AAAA,UACL,OAAO,MAAM,QAAQ;AAAA,UACrB,QAAQ;AAAA,UACR,YAAY,KAAK,IAAI,IAAI;AAAA,UACzB,UAAU,CAAC;AAAA,UACX,QAAQ;AAAA,QACV;AAAA,MACF;AAEA,YAAM,aAAa,CAAC,mBAAmB,OAAO,kBAAkB;AAChE,YAAM,OAAO,OAAO,MAAM;AAC1B,YAAM,WAAoC,CAAC;AAC3C,UAAI,CAAC,OAAO,IAAI;AACd,iBAAS,KAAK;AAAA,UACZ,UAAU;AAAA,UACV,SAAS;AAAA,UACT,WAAW,OAAO,UAAU,IAAI,MAAM,KAAK;AAAA,QAC7C,CAAC;AAAA,MACH;AACA,UAAI,OAAO,MAAM,mBAAmB,CAAC,OAAO,eAAe;AACzD,iBAAS,KAAK;AAAA,UACZ,UAAU;AAAA,UACV,SAAS,uCAAuC,OAAO,eAAe,WAAW;AAAA,QACnF,CAAC;AAAA,MACH;AACA,aAAO;AAAA,QACL,OAAO,MAAM,QAAQ;AAAA,QACrB,QAAQ,OAAO,SAAS;AAAA,QACxB,OAAO,OAAO,IAAI;AAAA,QAClB,YAAY,KAAK,IAAI,IAAI;AAAA,QACzB;AAAA,QACA,QAAQ,OACJ,kBAAkB,MAAM,SAAS,KAAK,MAAM,MAAM,MAAM,EAAE,GAAG,OAAO,cAAc,WAAM,OAAO,WAAW,KAAK,EAAE,KACjH,CAAC,OAAO,KACN,yBACA;AAAA,QACN,aAAa;AAAA,UACX,eAAe,OAAO,KAAK,IAAI;AAAA,UAC/B,kBAAkB,OAAO,kBAAkB,OAAO,IAAI;AAAA,UACtD,eAAe,OAAO,cAAc;AAAA,QACtC;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAmCO,SAAS,iBAAiB,OAA4C;AAC3E,SAAO;AAAA,IACL,KAAK,YAAY;AACf,YAAM,QAAQ,KAAK,IAAI;AACvB,YAAM,MAAM,MAAM,gBAAgB;AAClC,YAAM,cAAc,MAAM,eAAe;AACzC,YAAM,gBAAgB,MAAM,iBAAiB;AAC7C,YAAM,YAAY,MAAM,aAAa;AACrC,YAAM,SAAS,MAAM,MAAM,KAAK,KAAK,EAAE,KAAK,MAAM,SAAS,UAAU,CAAC;AACtE,YAAM,KAAK,OAAO,aAAa;AAC/B,UAAI,gBAAgB;AACpB,UAAI;AACF,cAAM,cAAc,MAAM,MAAM,OAAO,GAAG,WAAW,IAAI,aAAa,EAAE;AACxE,wBAAgB,MAAM,QAAQ,WAAW;AAAA,MAC3C,QAAQ;AACN,wBAAgB;AAAA,MAClB;AACA,YAAM,SAAS,OAAO,UAAU,OAAO,WAAW,IAAI,MAAM,KAAK;AACjE,aAAO;AAAA,QACL;AAAA,QACA,QAAQ;AAAA,QACR,YAAY,KAAK,IAAI,IAAI;AAAA,QACzB;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AA6BO,SAAS,qBAAqB,OAAgD;AACnF,SAAO;AAAA,IACL,KAAK,YAAY;AACf,YAAM,QAAQ,KAAK,IAAI;AACvB,YAAM,WAAW,MAAM,gBAAgB;AACvC,YAAM,SAAS,MAAM,iBAAiB;AACtC,YAAM,YAAY,MAAM,aAAa;AAErC,YAAM,UAAU,MAAM,MAAM,OAAO,eAAe;AAClD,YAAM,WAAW,UAAU,QAAQ,MAAM,MAAM,OAAO,gBAAgB;AACtE,UAAI,CAAC,WAAW,CAAC,UAAU;AACzB,eAAO;AAAA,UACL,IAAI;AAAA,UACJ,QAAQ;AAAA,UACR,YAAY,KAAK,IAAI,IAAI;AAAA,UACzB,aAAa;AAAA,UACb,eAAe;AAAA,QACjB;AAAA,MACF;AAEA,YAAM,QAAQ,MAAM,MAAM,KAAK,UAAU,EAAE,KAAK,MAAM,SAAS,UAAU,CAAC;AAC1E,UAAI,MAAM,aAAa,GAAG;AACxB,cAAMC,UAAS,MAAM,UAAU,MAAM,WAAW,IAAI,MAAM,KAAK;AAC/D,eAAO;AAAA,UACL,IAAI;AAAA,UACJ,QAAQ,iBAAiBA,KAAI;AAAA,UAC7B,YAAY,KAAK,IAAI,IAAI;AAAA,UACzB,aAAa;AAAA,UACb,eAAe;AAAA,QACjB;AAAA,MACF;AAEA,YAAM,MAAM,MAAM,MAAM,KAAK,QAAQ,EAAE,KAAK,MAAM,SAAS,UAAU,CAAC;AACtE,UAAI,IAAI,aAAa,GAAG;AACtB,cAAMA,UAAS,IAAI,UAAU,IAAI,WAAW,IAAI,MAAM,KAAK;AAC3D,eAAO;AAAA,UACL,IAAI;AAAA,UACJ,QAAQ,4BAA4BA,KAAI;AAAA,UACxC,YAAY,KAAK,IAAI,IAAI;AAAA,UACzB,aAAa;AAAA,UACb,eAAe;AAAA,QACjB;AAAA,MACF;AAEA,YAAM,SAAS,IAAI,UAAU,IAAI,WAAW,IAAI,MAAM,KAAK;AAC3D,aAAO;AAAA,QACL,IAAI;AAAA,QACJ,QAAQ;AAAA,QACR,YAAY,KAAK,IAAI,IAAI;AAAA,QACzB,aAAa;AAAA,QACb,eAAe;AAAA,MACjB;AAAA,IACF;AAAA,EACF;AACF;;;ACrRO,IAAM,uBAA4C;AAAA,EACvD;AAAA;AAAA,IAEE,MAAM;AAAA,IACN,OAAO;AAAA,EACT;AAAA,EACA;AAAA;AAAA,IAEE,MAAM;AAAA,IACN,OAAO;AAAA,EACT;AAAA,EACA;AAAA;AAAA,IAEE,MAAM;AAAA,IACN,OAAO;AAAA,EACT;AAAA,EACA;AAAA;AAAA,IAEE,MAAM;AAAA,IACN,OAAO;AAAA,EACT;AAAA,EACA;AAAA;AAAA,IAEE,MAAM;AAAA,IACN,OAAO;AAAA,EACT;AAAA,EACA;AAAA;AAAA;AAAA;AAAA,IAIE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,WAAW,CAAC,MAAM,OAAO,EAAE,CAAC,KAAK,CAAC;AAAA,EACpC;AACF;AAyBO,SAAS,kBAAkB,MAAc,OAAuB,CAAC,GAAkB;AACxF,MAAI,CAAC,KAAM,QAAO,EAAE,OAAO,MAAM,SAAS,MAAM,SAAS,CAAC,EAAE;AAE5D,QAAM,WAAW,CAAC,GAAI,KAAK,SAAS,CAAC,GAAI,GAAG,oBAAoB,EAAE;AAAA,IAChE,CAAC,MAAM,CAAC,KAAK,QAAQ,KAAK,KAAK,SAAS,EAAE,IAAI;AAAA,EAChD;AAEA,aAAW,KAAK,UAAU;AACxB,UAAM,UAAU,MAAM,KAAK,KAAK,SAAS,EAAE,KAAK,CAAC;AACjD,QAAI,QAAQ,WAAW,EAAG;AAE1B,UAAM,QAAQ,EAAE,YACZ,QAAQ,OAAO,CAACC,MAAK,MAAMA,OAAM,EAAE,UAAW,CAAC,GAAG,CAAC,IACnD,QAAQ;AAEZ,WAAO;AAAA,MACL;AAAA,MACA,SAAS,EAAE;AAAA,MACX,SAAS,QAAQ,MAAM,GAAG,CAAC,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;AAAA,IAC9C;AAAA,EACF;AAEA,SAAO,EAAE,OAAO,MAAM,SAAS,MAAM,SAAS,CAAC,EAAE;AACnD;;;ACCO,SAAS,UACd,OACY;AACZ,SAAO;AAAA,IACL,MAAM,MAAM,QAAQ;AAAA,IACpB,WAAW,MAAM,aAAa,CAAC,OAAO;AAAA,IACtC,QAAQ,MAAM,UAAU;AAAA,IACxB,OAAO,MAAM,SAAS;AAAA,IACtB,KAAK,OAAO,QAAQ;AAClB,YAAM,QAAQ,KAAK,IAAI;AACvB,YAAM,OAAO,IAAI,KAAK,YAAY,MAAM;AACxC,UAAI,CAAC,MAAM;AACT,eAAO;AAAA,UACL,OAAO,MAAM,QAAQ;AAAA,UACrB,QAAQ;AAAA,UACR,YAAY;AAAA,UACZ,UAAU,CAAC;AAAA,UACX,QAAQ;AAAA,QACV;AAAA,MACF;AAEA,UAAI;AACJ,UAAI;AACF,iBAAS,MAAM,MAAM,OAAO;AAAA,MAC9B,SAAS,KAAK;AACZ,eAAO;AAAA,UACL,OAAO,MAAM,QAAQ;AAAA,UACrB,QAAQ;AAAA,UACR,YAAY,KAAK,IAAI,IAAI;AAAA,UACzB,UAAU;AAAA,YACR;AAAA,cACE,UAAU;AAAA,cACV,SAAS,gCAAgC,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,YAC3F;AAAA,UACF;AAAA,UACA,QAAQ;AAAA,QACV;AAAA,MACF;AAEA,YAAM,WAAoC,CAAC;AAC3C,YAAM,cAAsF,CAAC;AAC7F,UAAI,SAAS;AACb,UAAI;AACF,cAAM,SAAS,MAAM,OAAO,KAAK,KAAK,GAAG;AACzC,iBAAS,OAAO;AAChB,YAAI,CAAC,OAAO,IAAI;AACd,mBAAS,KAAK;AAAA,YACZ,UAAU;AAAA,YACV,SAAS,aAAa,KAAK,GAAG,WAAW,OAAO,WAAW,KAAK,OAAO,QAAQ,KAAK,EAAE;AAAA,UACxF,CAAC;AAAA,QACH;AACA,YAAI,UAAU,KAAK,gBAAgB;AACjC,mBAAS,IAAI,GAAG,IAAI,KAAK,MAAM,QAAQ,KAAK;AAC1C,kBAAM,OAAO,KAAK,MAAM,CAAC;AACzB,gBAAI,IAAI,OAAO,QAAS;AACxB,kBAAM,YAAY,KAAK,IAAI;AAC3B,gBAAI;AACJ,gBAAI;AACF,uBAAS,MAAM,OAAO,KAAK,IAAI;AAAA,YACjC,SAAS,KAAK;AACZ,uBAAS;AAAA,gBACP,IAAI;AAAA,gBACJ,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,gBACzD,YAAY,KAAK,IAAI,IAAI;AAAA,cAC3B;AAAA,YACF;AACA,wBAAY,KAAK,EAAE,MAAM,QAAQ,OAAO,EAAE,CAAC;AAC3C,gBAAI,CAAC,OAAO,IAAI;AACd,uBAAS,KAAK;AAAA,gBACZ,UAAU,KAAK,YAAY;AAAA,gBAC3B,SAAS,QAAQ,CAAC,KAAK,KAAK,MAAM,GAAG,KAAK,SAAS,IAAI,KAAK,MAAM,MAAM,EAAE,UAAU,OAAO,WAAW,KAAK,OAAO,QAAQ,KAAK,EAAE;AAAA,cACnI,CAAC;AACD,kBAAI,CAAC,KAAK,eAAgB;AAAA,YAC5B;AAAA,UACF;AAAA,QACF;AAAA,MACF,UAAE;AACA,YAAI;AACF,gBAAM,OAAO,MAAM;AAAA,QACrB,QAAQ;AAAA,QAER;AAAA,MACF;AAEA,YAAM,aAAa,KAAK,MAAM;AAC9B,YAAM,WAAW,YAAY;AAC7B,YAAM,cAAc,YAAY,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE;AAC3D,YAAM,SAAgC,CAAC,SACnC,SACA,gBAAgB,aACd,SACA;AAKN,YAAM,cAAc,IAAI;AACxB,YAAM,aAAa,SAAS,IAAI,KAAK;AACrC,YAAM,QAAQ,cAAc,IAAI,QAAQ,YAAY,aAAa,QAAQ,CAAC,CAAC,IAAI;AAE/E,aAAO;AAAA,QACL,OAAO,MAAM,QAAQ;AAAA,QACrB;AAAA,QACA;AAAA,QACA,YAAY,KAAK,IAAI,IAAI;AAAA,QACzB;AAAA,QACA,QACE,WAAW,SACP,GAAG,UAAU,IAAI,UAAU,kBAC3B,GAAG,WAAW,IAAI,UAAU,gBAAgB,WAAW,aAAa,qBAAqB,QAAQ,MAAM,EAAE;AAAA,QAC/G,aAAa;AAAA,UACX,YAAY,SAAS,IAAI;AAAA,UACzB,gBAAgB;AAAA,UAChB,iBAAiB;AAAA,UACjB,cAAc;AAAA,QAChB;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;ACxMO,IAAM,6BAA6B;AAoC1C,IAAMC,iBAAgB;AACtB,IAAMC,mBAAkB;AACxB,IAAMC,sBAAqB;AAC3B,IAAMC,wBAAuB;AAC7B,IAAMC,oBAAmB;AAEzB,IAAM,gBAAgB;AAAA,EACpB,MAAM;AAAA,EACN,sBAAsB;AAAA,EACtB,UAAU,CAAC,SAAS,UAAU;AAAA,EAC9B,YAAY;AAAA,IACV,OAAO,EAAE,MAAM,UAAU,SAAS,GAAG,SAAS,EAAE;AAAA,IAChD,UAAU,EAAE,MAAM,UAAU,WAAW,IAAI,WAAW,IAAI;AAAA,EAC5D;AACF;AAEA,SAASC,UAAS,MAAc,KAAa,OAAuB;AAClE,MAAI,KAAK,UAAU,IAAK,QAAO;AAC/B,SAAO,GAAG,KAAK,MAAM,GAAG,GAAG,CAAC;AAAA,oBAAkB,KAAK,SAAS,GAAG,aAAa,KAAK;AACnF;AAEA,SAASC,aAAY,OAAyB,MAA4C;AACxF,QAAM,aAAa,MAAM,YACtB,OAAO,CAAC,MAAM,EAAE,QAAQ,UAAU,KAAK,eAAe,EACtD,IAAI,CAAC,MAAM,aAAa,EAAE,IAAI;AAAA,EAAS,EAAE,OAAO,EAAE,EAClD,KAAK,MAAM;AACd,QAAM,OAAO,MAAM,cAAc;AAEjC,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQP,MAAM,WAAW;AAAA;AAAA,EAEjB,MAAM,gBAAgB;AAAA,UAA+B,MAAM,aAAa;AAAA,iBAAoB,MAAM,uBAAuB,EAAE;AAAA;AAAA,IAAS,EAAE,GAAG,OAAO;AAAA,EAA4CD,UAAS,MAAM,KAAK,cAAc,MAAM,CAAC;AAAA;AAAA,IAAS,EAAE;AAAA,EAChPA,UAAS,YAAY,KAAK,gBAAgB,QAAQ,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAwBrD;AAKA,eAAsB,oBACpB,OACA,UAA8B,CAAC,GACH;AAC5B,QAAM,QAAQ,KAAK,IAAI;AACvB,QAAM,OAAqC;AAAA,IACzC,OAAO,QAAQ,SAASL;AAAA,IACxB,WAAW,QAAQ,aAAaC;AAAA,IAChC,gBAAgB,QAAQ,kBAAkBC;AAAA,IAC1C,iBAAiB,QAAQ,mBAAmBC;AAAA,IAC5C,cAAc,QAAQ,gBAAgBC;AAAA,IACtC,KAAK,QAAQ,OAAO,CAAC;AAAA,EACvB;AAEA,MAAI,MAAM,YAAY,WAAW,KAAK,CAAC,MAAM,YAAY;AACvD,WAAO;AAAA,MACL,MAAM;AAAA,MACN,SAAS;AAAA,MACT,OAAO;AAAA,MACP,UAAU;AAAA,MACV,YAAY;AAAA,MACZ,SAAS;AAAA,MACT,WAAW;AAAA,MACX,OAAO;AAAA,IACT;AAAA,EACF;AAEA,MAAI;AACF,UAAM,EAAE,OAAO,OAAO,IAAI,MAAM;AAAA,MAC9B;AAAA,QACE,OAAO,KAAK;AAAA,QACZ,UAAU;AAAA,UACR;AAAA,YACE,MAAM;AAAA,YACN,SACE;AAAA,UACJ;AAAA,UACA,EAAE,MAAM,QAAQ,SAASE,aAAY,OAAO,IAAI,EAAE;AAAA,QACpD;AAAA,QACA,YAAY,EAAE,MAAM,sBAAsB,QAAQ,cAAc;AAAA,QAChE,aAAa;AAAA,QACb,WAAW,KAAK;AAAA,MAClB;AAAA,MACA,KAAK;AAAA,IACP;AAEA,UAAM,QAAQ,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,OAAO,OAAO,SAAS,CAAC,CAAC,CAAC;AAChE,WAAO;AAAA,MACL,MAAM;AAAA,MACN,SAAS;AAAA,MACT,OAAO,OAAO,MAAM,QAAQ,CAAC,CAAC;AAAA,MAC9B,UAAU,OAAO,OAAO,YAAY,EAAE,EAAE,MAAM,GAAG,GAAG;AAAA,MACpD,YAAY,KAAK,IAAI,IAAI;AAAA,MACzB,SAAS,OAAO,WAAW;AAAA,MAC3B,WAAW;AAAA,IACb;AAAA,EACF,SAAS,KAAK;AACZ,WAAO;AAAA,MACL,MAAM;AAAA,MACN,SAAS;AAAA,MACT,OAAO;AAAA,MACP,UAAU;AAAA,MACV,YAAY,KAAK,IAAI,IAAI;AAAA,MACzB,SAAS;AAAA,MACT,WAAW;AAAA,MACX,OAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,IACxD;AAAA,EACF;AACF;AAKO,SAAS,uBACd,UAA8B,CAAC,GAC0B;AACzD,SAAO,CAAC,UAAU,oBAAoB,OAAO,OAAO;AACtD;;;ACpIO,SAAS,oBAAoB,MAAc,UAAkC;AAClF,QAAM,UAAU,qBAAqB,KAAK,QAAQ;AAClD,MAAI,SAAS;AACX,UAAM,KAAK,IAAI,OAAO,IAAI,QAAQ,CAAC,CAAC,OAAO,GAAG;AAC9C,WAAO,GAAG,KAAK,IAAI;AAAA,EACrB;AACA,QAAM,YAAY,4DAA4D,KAAK,QAAQ;AAC3F,MAAI,WAAW;AACb,UAAM,CAAC,EAAE,KAAK,MAAM,KAAK,IAAI;AAC7B,UAAM,KAAK,IAAI;AAAA,MACb,IAAI,GAAG,cAAc,IAAI,gBAAgB,MAAO,QAAQ,uBAAuB,MAAM,CAAC;AAAA,MACtF;AAAA,IACF;AACA,WAAO,GAAG,KAAK,IAAI;AAAA,EACrB;AACA,QAAM,kBAAkB,iCAAiC,KAAK,QAAQ;AACtE,MAAI,iBAAiB;AACnB,UAAM,CAAC,EAAE,KAAK,IAAI,IAAI;AACtB,UAAM,KAAK,IAAI,OAAO,IAAI,GAAG,cAAc,IAAI,OAAO,GAAG;AACzD,WAAO,GAAG,KAAK,IAAI;AAAA,EACrB;AACA,SAAO;AACT;AAUO,SAAS,iBAAiB,MAAc,SAA2B;AACxE,QAAM,OAAO,oBAAI,IAAY;AAC7B,QAAM,SAAS;AACf,QAAM,WAAW;AACjB,aAAW,MAAM,CAAC,QAAQ,QAAQ,GAAG;AACnC,QAAI;AACJ,YAAQ,QAAQ,GAAG,KAAK,IAAI,OAAO,MAAM;AACvC,YAAM,MAAM,MAAM,CAAC;AACnB,UAAI;AACF,aAAK,IAAI,IAAI,IAAI,KAAK,OAAO,EAAE,SAAS,CAAC;AAAA,MAC3C,QAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF;AACA,SAAO,MAAM,KAAK,IAAI;AACxB;AAUO,SAAS,wBACd,MACA,kBACA,SAAgC,CAAC,GACV;AACvB,QAAM,QAAQ,KAAK,IAAI;AACvB,MAAI,iBAAiB,WAAW,GAAG;AACjC,WAAO;AAAA,MACL,OAAO;AAAA,MACP,cAAc;AAAA,MACd,YAAY;AAAA,MACZ,UAAU,CAAC;AAAA,MACX,YAAY;AAAA,MACZ,qBAAqB;AAAA,IACvB;AAAA,EACF;AACA,QAAM,WAAW,GAAG,IAAI;AAAA,EAAK,OAAO,KAAK,IAAI,CAAC,GAAG,YAAY;AAC7D,QAAM,WAAqC,iBAAiB,IAAI,CAAC,YAAY;AAC3E,UAAM,kBAA4B,CAAC;AACnC,eAAW,MAAM,QAAQ,UAAU;AACjC,UAAI,SAAS,SAAS,GAAG,YAAY,CAAC,EAAG,iBAAgB,KAAK,EAAE;AAAA,IAClE;AACA,UAAM,yBAAyB,QAAQ,kBACnC,oBAAoB,MAAM,QAAQ,eAAe,IACjD;AACJ,UAAM,oBAAoB,2BAA2B,QAAQ,2BAA2B;AACxF,UAAM,QAAQ,gBAAgB,SAAS,KAAK;AAC5C,WAAO,EAAE,SAAS,QAAQ,MAAM,OAAO,iBAAiB,uBAAuB;AAAA,EACjF,CAAC;AACD,QAAM,eAAe,SAAS,OAAO,CAAC,MAAM,EAAE,KAAK,EAAE;AACrD,SAAO;AAAA,IACL,OAAO,eAAe,iBAAiB;AAAA,IACvC;AAAA,IACA,YAAY,iBAAiB;AAAA,IAC7B;AAAA,IACA,YAAY,KAAK,IAAI,IAAI;AAAA,IACzB,qBAAqB,SAAS;AAAA,EAChC;AACF;AAOA,eAAsB,2BACpB,YACA,kBACA,UAAkC,CAAC,GACH;AAChC,QAAM,QAAQ,KAAK,IAAI;AACvB,QAAM,UAAU,QAAQ,SAAS,WAAW;AAC5C,QAAM,cAAc,QAAQ,iBAAiB;AAC7C,QAAM,eAAe,QAAQ,kBAAkB;AAE/C,MAAI,iBAAiB,WAAW,GAAG;AACjC,WAAO;AAAA,MACL,OAAO;AAAA,MACP,cAAc;AAAA,MACd,YAAY;AAAA,MACZ,UAAU,CAAC;AAAA,MACX,YAAY;AAAA,MACZ,qBAAqB;AAAA,IACvB;AAAA,EACF;AAEA,MAAI,OAAO;AACX,MAAI;AACF,UAAM,OAAO,MAAM,QAAQ,YAAY;AAAA,MACrC,UAAU;AAAA,MACV,QAAQ,YAAY,QAAQ,WAAW;AAAA,IACzC,CAAC;AACD,QAAI,CAAC,KAAK,IAAI;AACZ,aAAO,SAAS,kBAAkB,OAAO,gBAAgB,KAAK,MAAM,EAAE;AAAA,IACxE;AACA,WAAO,MAAM,KAAK,KAAK;AAAA,EACzB,SAAS,KAAK;AACZ,WAAO,SAAS,kBAAkB,OAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,EAC3F;AAEA,QAAM,YAAY,iBAAiB,MAAM,UAAU;AACnD,QAAM,cAAc,MAAM,QAAQ;AAAA,IAChC,UAAU,IAAI,OAAO,MAAM;AACzB,UAAI;AACF,cAAM,IAAI,MAAM,QAAQ,GAAG;AAAA,UACzB,UAAU;AAAA,UACV,QAAQ,YAAY,QAAQ,YAAY;AAAA,QAC1C,CAAC;AACD,YAAI,CAAC,EAAE,GAAI,QAAO;AAClB,eAAO,MAAM,EAAE,KAAK;AAAA,MACtB,QAAQ;AACN,eAAO;AAAA,MACT;AAAA,IACF,CAAC;AAAA,EACH;AAEA,SAAO,wBAAwB,MAAM,kBAAkB,WAAW;AACpE;AAEA,SAAS,SACP,kBACA,OACA,OACuB;AACvB,SAAO;AAAA,IACL,OAAO;AAAA,IACP,cAAc;AAAA,IACd,YAAY,iBAAiB;AAAA,IAC7B,UAAU,iBAAiB,IAAI,CAAC,OAAO;AAAA,MACrC,SAAS,EAAE;AAAA,MACX,OAAO;AAAA,MACP,iBAAiB,CAAC;AAAA,MAClB,wBAAwB;AAAA,IAC1B,EAAE;AAAA,IACF,YAAY,KAAK,IAAI,IAAI;AAAA,IACzB,qBAAqB;AAAA,IACrB;AAAA,EACF;AACF;;;ACnHO,SAAS,oBAAoB,OAKpB;AACd,MAAI,CAAC,MAAM,UAAW,QAAO;AAC7B,QAAM,YAAY,MAAM,aAAa;AACrC,QAAM,eAAe,MAAM,SAAS;AAAA,IAClC,CAAC,MAAM,EAAE,aAAa,eAAe,EAAE,YAAY,UAAU,EAAE,SAAS,KAAK;AAAA,EAC/E;AACA,SAAO,MAAM,SAAS,aAAa,aAAa,WAAW,IAAI,SAAS;AAC1E;AAIO,IAAM,qBAAN,MAAwC;AAAA,EAC7C,YAA6B,QAAsB;AAAtB;AAC3B,UAAM,OAAO,oBAAI,IAAY;AAC7B,eAAW,KAAK,QAAQ;AACtB,UAAI,KAAK,IAAI,EAAE,IAAI,EAAG,OAAM,IAAI,MAAM,6CAA6C,EAAE,IAAI,GAAG;AAC5F,WAAK,IAAI,EAAE,IAAI;AAAA,IACjB;AACA,eAAW,KAAK,QAAQ;AACtB,iBAAW,OAAO,EAAE,aAAa,CAAC,GAAG;AACnC,YAAI,CAAC,KAAK,IAAI,GAAG,GAAG;AAClB,gBAAM,IAAI;AAAA,YACR,8BAA8B,EAAE,IAAI,iBAAiB,GAAG;AAAA,UAC1D;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAf6B;AAAA,EAiB7B,MAAM,IAAI,MAAuD;AAC/D,UAAM,cAAc,KAAK,IAAI;AAC7B,UAAM,YAAY,IAAI,KAAK,WAAW,EAAE,YAAY;AACpD,UAAM,aAAa,IAAI,gBAAgB;AACvC,UAAM,aAAa,KAAK;AACxB,UAAM,eACJ,cAAc,OACV,WAAW,MAAM,WAAW,MAAM,IAAI,MAAM,sBAAsB,CAAC,GAAG,UAAU,IAChF;AAEN,UAAM,UAAyB,CAAC;AAChC,UAAM,SAAsC,CAAC;AAE7C,QAAI;AACF,iBAAW,SAAS,KAAK,QAAQ;AAE/B,cAAM,SAAS,MAAM,aAAa,CAAC,GAAG,OAAO,CAAC,MAAM,OAAO,CAAC,GAAG,WAAW,MAAM;AAChF,YAAI,MAAM,SAAS,GAAG;AACpB,gBAAM,UAAuB;AAAA,YAC3B,OAAO,MAAM;AAAA,YACb,QAAQ;AAAA,YACR,YAAY;AAAA,YACZ,UAAU,CAAC;AAAA,YACX,QAAQ,wCAAmC,MAAM,KAAK,IAAI,CAAC;AAAA,UAC7D;AACA,kBAAQ,KAAK,OAAO;AACpB,iBAAO,MAAM,IAAI,IAAI;AACrB,eAAK,UAAU,OAAO;AACtB;AAAA,QACF;AAGA,cAAM,qBAAqB,IAAI,gBAAgB;AAC/C,cAAM,eAAe,aAAa,WAAW,QAAQ,mBAAmB,MAAM;AAC9E,cAAM,aACJ,MAAM,SAAS,OACX;AAAA,UACE,MAAM,mBAAmB,MAAM,IAAI,MAAM,SAAS,MAAM,IAAI,MAAM,CAAC;AAAA,UACnE,MAAM;AAAA,QACR,IACA;AAEN,cAAM,aAAa,KAAK,IAAI;AAC5B,YAAI;AACJ,YAAI;AACF,mBAAS,MAAM,MAAM,IAAI,EAAE,KAAK,KAAK,KAAK,OAAO,EAAE,GAAG,OAAO,GAAG,QAAQ,aAAa,CAAC;AAAA,QACxF,SAAS,KAAK;AACZ,gBAAM,UAAU,aAAa;AAC7B,mBAAS;AAAA,YACP,OAAO,MAAM;AAAA,YACb,QAAQ,UAAU,YAAY;AAAA,YAC9B,YAAY,KAAK,IAAI,IAAI;AAAA,YACzB,UAAU;AAAA,cACR;AAAA,gBACE,UAAU;AAAA,gBACV,SAAS,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,gBACxD,OAAO,MAAM;AAAA,cACf;AAAA,YACF;AAAA,YACA,QAAQ,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,UACzD;AAAA,QACF,UAAE;AACA,cAAI,WAAY,cAAa,UAAU;AAAA,QACzC;AAGA,eAAO,WAAW,OAAO,SAAS,IAAI,CAAC,OAAO,EAAE,GAAG,GAAG,OAAO,EAAE,SAAS,MAAM,KAAK,EAAE;AACrF,gBAAQ,KAAK,MAAM;AACnB,eAAO,MAAM,IAAI,IAAI;AACrB,aAAK,UAAU,MAAM;AAErB,YAAI,WAAW,OAAO,QAAS;AAAA,MACjC;AAEA,YAAM,SAAS,UAAU,KAAK,QAAQ,SAAS,WAAW,WAAW;AACrE,aAAO;AAAA,IACT,UAAE;AACA,UAAI,aAAc,cAAa,YAAY;AAAA,IAC7C;AAAA,EACF;AACF;AAEA,SAAS,UACP,QACA,SACA,WACA,aACoB;AACpB,QAAM,eAAe,oBAAI,IAAoB;AAC7C,QAAM,oBAAoB,oBAAI,IAAqB;AACnD,aAAW,KAAK,QAAQ;AACtB,iBAAa,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC;AACtC,sBAAkB,IAAI,EAAE,MAAM,EAAE,0BAA0B,KAAK;AAAA,EACjE;AAEA,MAAI,YAAY;AAChB,MAAI,YAAY;AAChB,MAAI,eAAe;AACnB,MAAI,aAAa;AACjB,MAAI,kBAAkB;AACtB,MAAI,sBAAsB;AAC1B,MAAI,oBAAoB;AACxB,MAAI,uBAAuB;AAE3B,aAAW,KAAK,SAAS;AACvB,UAAM,SAAS,aAAa,IAAI,EAAE,KAAK,KAAK;AAC5C,UAAM,cAAc,kBAAkB,IAAI,EAAE,KAAK,KAAK;AACtD,QAAI,EAAE,WAAW,OAAQ;AAAA,aAChB,EAAE,WAAW,OAAQ;AAAA,aACrB,EAAE,WAAW,UAAW;AAAA,QAC5B;AAEL,QAAI,EAAE,SAAS,QAAQ,SAAS,GAAG;AACjC,UAAI,EAAE,WAAW,QAAQ;AACvB,4BAAoB;AACpB,2BAAmB;AACnB,+BAAuB,SAAS,EAAE;AAAA,MACpC,WAAW,EAAE,WAAW,QAAQ;AAC9B,YAAI,aAAa;AACf,8BAAoB;AACpB,6BAAmB;AACnB,iCAAuB,SAAS,EAAE;AAAA,QACpC;AACA,+BAAuB;AAAA,MACzB;AAAA,IAEF,WAAW,EAAE,WAAW,QAAQ;AAC9B,6BAAuB;AAAA,IACzB;AAAA,EACF;AAEA,QAAM,eAAe,KAAK,IAAI;AAC9B,SAAO;AAAA,IACL,QAAQ;AAAA,IACR;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,SAAS,qBAAqB,CAAC,wBAAwB,cAAc,KAAK,eAAe;AAAA,IACzF,cAAc,kBAAkB,IAAI,sBAAsB,kBAAkB;AAAA,IAC5E,YAAY,eAAe;AAAA,IAC3B;AAAA,IACA,YAAY,IAAI,KAAK,YAAY,EAAE,YAAY;AAAA,EACjD;AACF;AAEA,SAAS,aAAa,GAAgB,GAA6B;AACjE,MAAI,EAAE,QAAS,QAAO;AACtB,MAAI,EAAE,QAAS,QAAO;AACtB,QAAM,IAAI,IAAI,gBAAgB;AAC9B,QAAM,UAAU,CAAC,WAAwB,MAAM,EAAE,MAAM,OAAO,MAAM;AACpE,IAAE,iBAAiB,SAAS,QAAQ,CAAC,GAAG,EAAE,MAAM,KAAK,CAAC;AACtD,IAAE,iBAAiB,SAAS,QAAQ,CAAC,GAAG,EAAE,MAAM,KAAK,CAAC;AACtD,SAAO,EAAE;AACX;;;AC1SA,IAAM,cAA2C;AAAA,EAC/C,MAAM;AAAA,EACN,SAAS;AAAA,EACT,MAAM;AAAA,EACN,SAAS;AAAA,EACT,OAAO;AACT;AAEA,SAAS,MAAM,GAAgB,GAA6B;AAC1D,UAAQ,YAAY,CAAC,KAAK,OAAO,YAAY,CAAC,KAAK,KAAK,IAAI;AAC9D;AAEA,IAAM,gBAA0C;AAAA,EAC9C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,OAAO;AAAA,EACP,UAAU;AACZ;AAEA,SAAS,YAAY,UAA2D;AAC9E,MAAI,OAAiB;AACrB,aAAW,KAAK,UAAU;AACxB,QAAI,cAAc,EAAE,QAAQ,IAAI,cAAc,IAAI,EAAG,QAAO,EAAE;AAAA,EAChE;AACA,SAAO;AACT;AAyCO,SAAS,kBACd,MACA,YACA,UAAwB,CAAC,GACZ;AACb,QAAM,gBAAgB,QAAQ,iBAAiB;AAC/C,QAAM,mBAAmB,QAAQ,oBAAoB;AACrD,QAAM,SAAS,QAAQ;AAEvB,MAAI,WAAW,WAAW,GAAG;AAC3B,WAAO;AAAA,MACL,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,YAAY;AAAA,MACZ,UAAU,CAAC;AAAA,MACX,QAAQ;AAAA,IACV;AAAA,EACF;AACA,MAAI,WAAW,WAAW,GAAG;AAC3B,UAAM,OAAO,WAAW,CAAC;AACzB,WAAO;AAAA,MACL,GAAG,KAAK;AAAA,MACR,OAAO;AAAA,MACP,UAAU,KAAK,OAAO,SAAS,IAAI,CAAC,OAAO;AAAA,QACzC,GAAG;AAAA,QACH,OAAO;AAAA,QACP,SAAS,SAAS,GAAG,OAAO,KAAK,OAAO,CAAC,IAAI,EAAE,OAAO,KAAK,EAAE;AAAA,QAC7D,QAAQ,EAAE,GAAI,EAAE,UAAU,CAAC,GAAI,SAAS,KAAK,QAAQ;AAAA,MACvD,EAAE;AAAA,MACF,QAAQ,KAAK,OAAO,UAAU,GAAG,KAAK,OAAO,KAAK,KAAK,OAAO,MAAM;AAAA,IACtE;AAAA,EACF;AAEA,MAAI,SAAsB;AAC1B,MAAI,mBAAmB;AACvB,MAAI,cAAc;AAClB,QAAM,WAAoC,CAAC;AAC3C,MAAI,aAAa;AACjB,QAAM,cAAwB,CAAC;AAC/B,QAAM,cAA6C,CAAC;AAEpD,aAAW,EAAE,SAAS,OAAO,KAAK,YAAY;AAC5C,aAAS,MAAM,QAAQ,OAAO,MAAM;AACpC,QAAI,OAAO,OAAO,UAAU,UAAU;AACpC,0BAAoB,OAAO;AAC3B,qBAAe;AAAA,IACjB;AACA,iBACE,kBAAkB,QACd,aAAa,OAAO,aACpB,KAAK,IAAI,YAAY,OAAO,UAAU;AAC5C,gBAAY,KAAK,GAAG,OAAO,KAAK,OAAO,MAAM,EAAE;AAC/C,eAAW,KAAK,OAAO,UAAU;AAC/B,eAAS,KAAK;AAAA,QACZ,GAAG;AAAA,QACH,OAAO;AAAA,QACP,SAAS,SAAS,GAAG,OAAO,OAAO,CAAC,IAAI,EAAE,OAAO,KAAK,EAAE;AAAA,QACxD,QAAQ,EAAE,GAAI,EAAE,UAAU,CAAC,GAAI,QAAQ;AAAA,MACzC,CAAC;AAAA,IACH;AACA,eAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,OAAO,eAAe,CAAC,CAAC,GAAG;AAC7D,UAAI,OAAO,MAAM,YAAY,CAAC,OAAO,SAAS,CAAC,EAAG;AAClD,YAAM,OAAO,YAAY,CAAC;AAC1B,UAAI,QAAQ,KAAM,aAAY,CAAC,IAAI;AAAA,UAC9B,aAAY,CAAC,IAAI,qBAAqB,QAAQ,OAAO,IAAI,KAAK,IAAI,MAAM,CAAC;AAAA,IAChF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,OAAO;AAAA,IACP;AAAA,IACA,OAAO,cAAc,IAAI,mBAAmB,cAAc;AAAA,IAC1D;AAAA,IACA;AAAA,IACA,QAAQ,YAAY,KAAK,QAAK;AAAA,IAC9B,aAAa,OAAO,KAAK,WAAW,EAAE,SAAS,IAAI,cAAc;AAAA,IACjE,QAAQ;AAAA,MACN,UAAU,WAAW,IAAI,CAAC,EAAE,SAAS,OAAO,OAAO;AAAA,QACjD;AAAA,QACA,QAAQ,OAAO;AAAA,QACf,OAAO,OAAO,SAAS;AAAA,MACzB,EAAE;AAAA,MACF,eAAe,YAAY,QAAQ;AAAA,IACrC;AAAA,EACF;AACF;AA8BO,SAAS,oBACd,QACY;AACZ,QAAM,cAAc,KAAK,IAAI,GAAG,OAAO,eAAe,CAAC;AACvD,SAAO;AAAA,IACL,MAAM,OAAO;AAAA,IACb,WAAW,OAAO;AAAA,IAClB,QAAQ,OAAO;AAAA,IACf,wBAAwB,OAAO;AAAA,IAC/B,OAAO,OAAO;AAAA,IACd,MAAM,IAAI,KAAK;AACb,UAAI,OAAO,SAAS,WAAW,GAAG;AAChC,eAAO;AAAA,UACL,OAAO,OAAO;AAAA,UACd,QAAQ;AAAA,UACR,YAAY;AAAA,UACZ,UAAU,CAAC;AAAA,UACX,QAAQ;AAAA,QACV;AAAA,MACF;AAEA,YAAM,SAAS,OAAO,YAA0C;AAC9D,cAAM,cAAc,OAAO,YAAY,OAAO;AAC9C,YAAI;AACF,gBAAM,IAAI,MAAM,OAAO,IAAI,SAAS,GAAG;AACvC,iBAAO,EAAE,SAAS,aAAa,QAAQ,EAAE;AAAA,QAC3C,SAAS,KAAK;AACZ,iBAAO;AAAA,YACL,SAAS;AAAA,YACT,QAAQ;AAAA,cACN,OAAO,OAAO;AAAA,cACd,QAAQ;AAAA,cACR,YAAY;AAAA,cACZ,UAAU;AAAA,gBACR;AAAA,kBACE,UAAU;AAAA,kBACV,OAAO,OAAO;AAAA,kBACd,SAAS,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,kBACxD,QAAQ,EAAE,SAAS,YAAY;AAAA,gBACjC;AAAA,cACF;AAAA,cACA,QAAQ,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,YACzD;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAGA,YAAM,UAAwB,CAAC;AAC/B,eAAS,IAAI,GAAG,IAAI,OAAO,SAAS,QAAQ,KAAK,aAAa;AAC5D,cAAM,QAAQ,OAAO,SAAS,MAAM,GAAG,IAAI,WAAW;AACtD,cAAM,eAAe,MAAM,QAAQ,IAAI,MAAM,IAAI,MAAM,CAAC;AACxD,gBAAQ,KAAK,GAAG,YAAY;AAAA,MAC9B;AACA,aAAO,kBAAkB,OAAO,MAAM,OAAO;AAAA,IAC/C;AAAA,EACF;AACF;;;AChQA,SAAS,kBAAAC,iBAAgB,cAAAC,aAAY,aAAAC,YAAW,gBAAAC,qBAAoB;AACpE,SAAS,WAAAC,gBAAe;AAsMxB,IAAM,0BAA0B;AAChC,IAAM,aAAqC,CAAC,SAAS,OAAO,QAAQ,SAAS;AAE7E,eAAsB,mBACpB,OACA,SACoC;AACpC,QAAM,MAAM,QAAQ,OAAO,KAAK;AAChC,QAAM,YAAY,IAAI;AACtB,QAAM,QAAQ,QAAQ,SAAS,GAAG,QAAQ,aAAa,kBAAkB,IAAI,SAAS;AACtF,QAAM,gBAAgB,IAAI,IAAI,QAAQ,UAAU,UAAU;AAC1D,QAAM,WAA4C,CAAC;AAEnD,aAAW,CAAC,WAAW,UAAU,KAAK,MAAM,QAAQ,GAAG;AACrD,UAAM,QAAQ,WAAW,SAAS;AAClC,QAAI,UAAU,aAAa,CAAC,QAAQ,eAAgB;AACpD,QAAI,CAAC,cAAc,IAAI,KAAK,EAAG;AAE/B,UAAM,YAAY,IAAI;AACtB,UAAM,oBAA6D;AAAA,MACjE,IAAI,WAAW;AAAA,MACf;AAAA,MACA,OAAO,WAAW;AAAA,MAClB,GAAI,WAAW,aAAa,SAAY,EAAE,UAAU,WAAW,SAAS,IAAI,CAAC;AAAA,IAC/E;AAEA,QAAI,aAAyC,CAAC;AAC9C,QAAI;AACJ,QAAI;AACF,qBAAe,QAAQ,WAAW;AAClC,mBAAa,MAAM,WAAW,QAAQ,SAAS,mBAAmB;AAAA,QAChE;AAAA,QACA;AAAA,QACA,aAAa,QAAQ;AAAA,MACvB,CAAC;AACD,qBAAe,QAAQ,WAAW;AAAA,IACpC,SAAS,OAAO;AACd,UAAI,QAAQ,aAAa,QAAS,OAAM;AACxC,UAAI,CAAC,QAAQ,gBAAiB,OAAM;AACpC,cAAQ,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,IAC/D;AAEA,UAAM,WAAoC;AAAA,MACxC,IAAI,WAAW;AAAA,MACf;AAAA,MACA,YAAY,WAAW;AAAA,MACvB;AAAA,MACA,GAAI,WAAW,aAAa,SAAY,EAAE,UAAU,WAAW,SAAS,IAAI,CAAC;AAAA,IAC/E;AACA,UAAMC,gBAA4C;AAAA,MAChD,SAAS,QAAQ;AAAA,MACjB,gBAAgB,QAAQ;AAAA,MACxB,eAAe,QAAQ;AAAA,MACvB,gBAAgB;AAAA,IAClB;AACA,UAAM,gBAAgB,qBAAqB,CAAC,QAAQ,GAAGA,aAAY,EAAE,UAAU,CAAC;AAChF,aAAS,KAAK;AAAA,MACZ,QAAQ,WAAW;AAAA,MACnB;AAAA,MACA,OAAO,WAAW;AAAA,MAClB,YAAY,WAAW;AAAA,MACvB;AAAA,MACA,OAAO;AAAA,MACP,YAAY,KAAK,IAAI,GAAG,IAAI,IAAI,SAAS;AAAA,MACzC,GAAI,WAAW,aAAa,SAAY,EAAE,UAAU,WAAW,SAAS,IAAI,CAAC;AAAA,MAC7E,GAAI,UAAU,SAAY,EAAE,MAAM,IAAI,CAAC;AAAA,IACzC,CAAC;AAAA,EACH;AAEA,QAAM,cAAc,IAAI;AACxB,QAAM,eAA4C;AAAA,IAChD,SAAS,QAAQ;AAAA,IACjB,gBAAgB,QAAQ;AAAA,IACxB,eAAe,QAAQ;AAAA,IACvB,gBAAgB;AAAA,EAClB;AACA,QAAM,MAAiC;AAAA,IACrC,IAAI;AAAA,IACJ;AAAA,IACA;AAAA,IACA,YAAY,KAAK,IAAI,GAAG,cAAc,SAAS;AAAA,IAC/C,OAAO;AAAA,IACP,OAAO;AAAA,MACL,SAAS,IAAI,CAAC,aAAa;AAAA,QACzB,IAAI,QAAQ;AAAA,QACZ,OAAO,QAAQ;AAAA,QACf,YAAY,QAAQ;AAAA,QACpB,YAAY,QAAQ;AAAA,QACpB,GAAI,QAAQ,aAAa,SAAY,EAAE,UAAU,QAAQ,SAAS,IAAI,CAAC;AAAA,MACzE,EAAE;AAAA,MACF;AAAA,IACF;AAAA,IACA,GAAI,QAAQ,cAAc,SAAY,EAAE,WAAW,QAAQ,UAAU,IAAI,CAAC;AAAA,IAC1E,GAAI,QAAQ,aAAa,SAAY,EAAE,UAAU,QAAQ,SAAS,IAAI,CAAC;AAAA,EACzE;AAEA,QAAM,QAAQ,OAAO,KAAK,GAAG;AAC7B,SAAO;AACT;AAEO,SAAS,kCACd,UACA,WACA,SAAyC,CAAC,GACR;AAClC,SAAO,+BAA+B,SAAS,OAAO,UAAU,OAAO,MAAM;AAC/E;AAEO,SAAS,6BACd,UAAuC,CAAC,GACR;AAChC,QAAM,OAAO,CAAC,GAAG,OAAO;AACxB,SAAO;AAAA,IACL,MAAM,KAAK,KAAK;AACd,WAAK,KAAK,GAAG;AAAA,IACf;AAAA,IACA,MAAM,OAAO;AACX,aAAO,CAAC,GAAG,IAAI;AAAA,IACjB;AAAA,EACF;AACF;AAQA,IAAM,kBAAkB,oBAAI,IAAmB;AAC/C,SAAS,kBAAkB,MAAqB;AAC9C,MAAI,IAAI,gBAAgB,IAAI,IAAI;AAChC,MAAI,CAAC,GAAG;AACN,QAAI,IAAI,MAAM;AACd,oBAAgB,IAAI,MAAM,CAAC;AAAA,EAC7B;AACA,SAAO;AACT;AAEO,SAAS,0BACd,MACgC;AAChC,QAAM,OAAO,kBAAkB,IAAI;AACnC,SAAO;AAAA,IACL,MAAM,KAAK,KAAK;AACd,YAAM,KAAK,aAAa,MAAM;AAC5B,QAAAC,WAAUC,SAAQ,IAAI,GAAG,EAAE,WAAW,KAAK,CAAC;AAC5C,QAAAC,gBAAe,MAAM,GAAG,KAAK,UAAU,GAAG,CAAC;AAAA,CAAI;AAAA,MACjD,CAAC;AAAA,IACH;AAAA,IACA,MAAM,OAAO;AACX,aAAO,KAAK,aAAa,MAAM;AAC7B,YAAI,CAACC,YAAW,IAAI,EAAG,QAAO,CAAC;AAC/B,eAAO,UAAU,IAAI;AAAA,MACvB,CAAC;AAAA,IACH;AAAA,EACF;AACF;AAEO,SAAS,qBACd,WACA,UAAuC,CAAC,GAClB;AACtB,QAAM,UAAU,QAAQ,WAAW;AACnC,QAAM,YAAY,QAAQ,kBAAkB;AAC5C,QAAM,gBAAgB,QAAQ,iBAAiB;AAC/C,QAAM,gBAAgB,IAAI,IAAI,QAAQ,UAAU,UAAU;AAC1D,QAAMC,UAAS,UACZ,OAAO,CAAC,aAAa;AACpB,UAAM,QAAQ,SAAS,SAAS;AAChC,QAAI,UAAU,aAAa,CAAC,QAAQ,eAAgB,QAAO;AAC3D,WAAO,cAAc,IAAI,KAAK;AAAA,EAChC,CAAC,EACA,IAAI,CAAC,aAAa,cAAc,UAAU,SAAS,WAAW,aAAa,CAAC;AAE/E,SAAO;AAAA,IACL,WAAWA;AAAA,IACX,WAAW,wBAAwBA,OAAM;AAAA,IACzC,SAAS,iBAAiBA,OAAM;AAAA,EAClC;AACF;AAEO,SAAS,uBACd,UACA,WACkC;AAClC,QAAM,SAAS,oBAAI,IAA0B;AAAA,IAC3C,GAAI,OAAO,KAAK,SAAS,OAAO;AAAA,IAChC,GAAI,OAAO,KAAK,UAAU,OAAO;AAAA,EACnC,CAAC;AACD,SAAO,CAAC,GAAG,MAAM,EAAE,KAAK,YAAY,EAAE,IAAI,CAAC,UAAU;AACnD,UAAM,SAAS,SAAS,QAAQ,KAAK,KAAK,eAAe;AACzD,UAAM,QAAQ,UAAU,QAAQ,KAAK,KAAK,eAAe;AACzD,WAAO;AAAA,MACL;AAAA,MACA,YAAY,OAAO;AAAA,MACnB,aAAa,MAAM;AAAA,MACnB,SAAS,MAAM,KAAK,OAAO;AAAA,MAC3B,gBAAgB,OAAO;AAAA,MACvB,iBAAiB,MAAM;AAAA,MACvB,aAAa,MAAM,SAAS,OAAO;AAAA,IACrC;AAAA,EACF,CAAC;AACH;AAEO,SAAS,+BACd,UACA,WACA,SAAyC,CAAC,GACR;AAClC,QAAM,iBAAiB,OAAO,kBAAkB,CAAC,OAAO,MAAM;AAC9D,QAAM,aAAa,OAAO,cAAc;AACxC,QAAM,gBAAgB,OAAO,iBAAiB;AAC9C,QAAM,iBAAiB,OAAO,+BAA+B;AAC7D,QAAM,cAAc,uBAAuB,UAAU,SAAS;AAC9D,QAAM,wBAAwB,eAAe;AAAA,IAC3C,CAAC,UAAU,CAAC,SAAS,UAAU,KAAK,KAAK,CAAC,SAAS,WAAW,KAAK;AAAA,EACrE;AACA,QAAM,WAAW,YAAY,OAAO,CAAC,SAAS,eAAe,SAAS,KAAK,KAAK,CAAC;AACjF,QAAM,cAAc,YAAY,OAAO,CAAC,SAAS,KAAK,UAAU,CAAC,aAAa;AAC9E,QAAM,iBAAiB,UAAU,UAAU,KAAK,SAAS,UAAU;AAEnE,MAAI,sBAAsB,SAAS,GAAG;AACpC,WAAO;AAAA,MACL,SAAS;AAAA,MACT,QAAQ,sDAAsD,sBAAsB,KAAK,IAAI,CAAC;AAAA,MAC9F;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,MAAI,SAAS,WAAW,GAAG;AACzB,WAAO;AAAA,MACL,SAAS;AAAA,MACT,QAAQ,mCAAmC,eAAe,KAAK,IAAI,CAAC;AAAA,MACpE;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,MAAI,YAAY,SAAS,GAAG;AAC1B,WAAO;AAAA,MACL,SAAS;AAAA,MACT,QAAQ,iBAAiB,YAAY,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,IAAI,CAAC;AAAA,MACnE;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,MAAI,mBAAmB,CAAC,SAAS,UAAU,SAAS,KAAK,CAAC,SAAS,WAAW,SAAS,IAAI;AACzF,WAAO;AAAA,MACL,SAAS;AAAA,MACT,QAAQ;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,QAAM,oBAAoBC,MAAK,SAAS,IAAI,CAAC,SAAS,KAAK,OAAO,CAAC;AACnE,MAAI,oBAAoB,YAAY;AAClC,WAAO;AAAA,MACL,SAAS;AAAA,MACT,QAAQ,2BAA2B,UAAU,iBAAiB,CAAC,UAAU,UAAU,UAAU,CAAC;AAAA,MAC9F;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,SAAS;AAAA,IACT,QAAQ,+BAA+B,UAAU,iBAAiB,CAAC;AAAA,IACnE;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEO,SAAS,8BACd,WACA,WACsB;AACtB,QAAM,gBAAgB,GAAG,UAAU,KAAK,IAAI,UAAU,eAAe,EAAE;AACvE,QAAM,gBAAgB,GAAG,UAAU,KAAK,IAAI,UAAU,eAAe,EAAE;AACvE,QAAM,YAAY,aAAa,eAAe,aAAa;AAC3D,QAAM,gBACJ,UAAU,YAAY,UAAU,WAC5B,UAAU,UAAU,QAAQ,MAAM,UAAU,UAAU,QAAQ,IAC5D,MACA,QACF;AACN,QAAM,WAAW,WAAW,UAAU,MAAM,UAAU,IAAI,IAAI;AAC9D,QAAM,QAAQC,SAAQ,YAAY,OAAO,WAAW,aAAa;AACjE,SAAO;AAAA,IACL;AAAA,IACA,QAAQ,SAAS,UAAU,QAAQ,CAAC,CAAC,SAAS,SAAS,QAAQ,CAAC,CAAC,aAAa,cAAc,QAAQ,CAAC,CAAC;AAAA,EACxG;AACF;AAEA,SAAS,cACP,UACA,SACA,WACA,eAC8B;AAC9B,SAAO,kBAAkB,kBACrB,0BAA0B,UAAU,SAAS,SAAS,IACtD,4BAA4B,UAAU,SAAS,SAAS;AAC9D;AAEA,SAAS,4BACP,UACA,SACA,WAC8B;AAC9B,QAAM,iBAAiB,SAAS,WAAW,IAAI,CAAC,WAAW,WAAW,EAAE,WAAW,MAAM,EAAE;AAC3F,QAAM,UAAkC,CAAC;AAEzC,aAAW,aAAa,SAAS,YAAY;AAC3C,QAAI,OAKO;AACX,eAAW,QAAQ,gBAAgB;AACjC,YAAM,SAAS,UAAU,UAAU,SAAS,WAAW,KAAK,SAAS;AACrE,UAAI,CAAC,QAAQ,OAAO,QAAQ,KAAK,OAAO;AACtC,eAAO,EAAE,GAAG,MAAM,GAAG,OAAO;AAAA,MAC9B;AAAA,IACF;AAEA,UAAM,SAAS,UAAU,UAAU;AACnC,QAAI,QAAQ,KAAK,SAAS,WAAW;AACnC,YAAM,aAAa,eAAe,UAAU,CAAC,SAAS,KAAK,UAAU,KAAK,KAAK;AAC/E,UAAI,cAAc,EAAG,gBAAe,OAAO,YAAY,CAAC;AACxD,cAAQ,KAAK;AAAA,QACX,YAAY,SAAS;AAAA,QACrB,aAAa,UAAU;AAAA,QACvB,aAAa,KAAK,UAAU;AAAA,QAC5B,OAAO,KAAK;AAAA,QACZ,SAAS;AAAA,QACT;AAAA,QACA,QAAQ,KAAK;AAAA,MACf,CAAC;AAAA,IACH,OAAO;AACL,cAAQ,KAAK;AAAA,QACX,YAAY,SAAS;AAAA,QACrB,aAAa,UAAU;AAAA,QACvB,aAAa,MAAM,UAAU,MAAM;AAAA,QACnC,OAAO,MAAM,SAAS;AAAA,QACtB,SAAS;AAAA,QACT;AAAA,QACA,QAAQ,MAAM,UAAU;AAAA,MAC1B,CAAC;AAAA,IACH;AAAA,EACF;AAEA,SAAO,mBAAmB,UAAU,SAAS,eAAe,MAAM;AACpE;AAWA,SAAS,0BACP,UACA,SACA,WAC8B;AAC9B,QAAM,QAAkC,CAAC;AACzC,aAAW,CAAC,gBAAgB,SAAS,KAAK,SAAS,WAAW,QAAQ,GAAG;AACvE,eAAW,CAAC,gBAAgB,SAAS,KAAK,SAAS,WAAW,QAAQ,GAAG;AACvE,YAAM,KAAK;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,GAAG,UAAU,UAAU,SAAS,WAAW,SAAS;AAAA,MACtD,CAAC;AAAA,IACH;AAAA,EACF;AAEA,QAAM;AAAA,IACJ,CAAC,GAAG,MACF,EAAE,QAAQ,EAAE,SACZ,EAAE,iBAAiB,EAAE,kBACrB,EAAE,iBAAiB,EAAE;AAAA,EACzB;AAEA,QAAM,sBAAsB,oBAAI,IAAoC;AACpE,QAAM,qBAAqB,oBAAI,IAAY;AAC3C,aAAW,QAAQ,OAAO;AACxB,QAAI,KAAK,QAAQ,UAAW;AAC5B,QAAI,oBAAoB,IAAI,KAAK,cAAc,KAAK,mBAAmB,IAAI,KAAK,cAAc;AAC5F;AACF,wBAAoB,IAAI,KAAK,gBAAgB,IAAI;AACjD,uBAAmB,IAAI,KAAK,cAAc;AAAA,EAC5C;AAEA,QAAM,UAAU,SAAS,WAAW,IAAI,CAAC,WAAW,mBAAmB;AACrE,UAAM,SAAS,UAAU,UAAU;AACnC,UAAM,WAAW,oBAAoB,IAAI,cAAc;AACvD,QAAI,UAAU;AACZ,aAAO;AAAA,QACL,YAAY,SAAS;AAAA,QACrB,aAAa,UAAU;AAAA,QACvB,aAAa,SAAS,UAAU;AAAA,QAChC,OAAO,SAAS;AAAA,QAChB,SAAS;AAAA,QACT;AAAA,QACA,QAAQ,SAAS;AAAA,MACnB;AAAA,IACF;AAEA,UAAM,eAAe,MAAM,KAAK,CAAC,SAAS,KAAK,mBAAmB,cAAc;AAChF,WAAO;AAAA,MACL,YAAY,SAAS;AAAA,MACrB,aAAa,UAAU;AAAA,MACvB,aAAa,cAAc,UAAU,MAAM;AAAA,MAC3C,OAAO,cAAc,SAAS;AAAA,MAC9B,SAAS;AAAA,MACT;AAAA,MACA,QAAQ,cAAc,UAAU;AAAA,IAClC;AAAA,EACF,CAAC;AAED,SAAO,mBAAmB,UAAU,SAAS,SAAS,WAAW,SAAS,mBAAmB,IAAI;AACnG;AAEA,SAAS,UACP,UACA,SACA,WACA,WACmC;AACnC,QAAM,SAAS,QAAQ,WAAW,WAAW,QAAQ;AACrD,MAAI,CAAC,OAAO,SAAS,OAAO,KAAK,GAAG;AAClC,UAAM,IAAI;AAAA,MACR,0DAA0D,SAAS,EAAE,IAAI,UAAU,EAAE,IAAI,UAAU,EAAE;AAAA,IACvG;AAAA,EACF;AACA,SAAO,EAAE,OAAOA,SAAQ,OAAO,KAAK,GAAG,QAAQ,OAAO,UAAU,GAAG;AACrE;AAEA,SAAS,mBACP,UACA,SACA,gBAC8B;AAC9B,QAAM,UAAU,QAAQ,OAAO,CAAC,UAAU,MAAM,OAAO,EAAE;AACzD,QAAM,QAAQ,SAAS,WAAW;AAClC,QAAM,gBAAgB,QACnB,OAAO,CAAC,UAAU,MAAM,OAAO,EAC/B,OAAO,CAACC,MAAK,UAAUA,OAAM,MAAM,QAAQ,CAAC;AAC/C,QAAM,cAAc,QAAQ,OAAO,CAACA,MAAK,UAAUA,OAAM,MAAM,QAAQ,CAAC;AACxE,QAAMC,aAAY,MAAM,SAAS,UAAU,cAAc;AACzD,QAAM,SAAS,MAAM,SAAS,KAAK;AACnC,SAAO;AAAA,IACL,YAAY,SAAS;AAAA,IACrB,OAAO,SAAS,SAAS;AAAA,IACzB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,WAAAA;AAAA,IACA;AAAA,IACA,IAAI,GAAGA,YAAW,MAAM;AAAA,IACxB;AAAA,EACF;AACF;AAEA,SAAS,iBACPJ,SACiE;AACjE,QAAM,MAAuE,CAAC;AAC9E,aAAW,SAAS,YAAY;AAC9B,UAAM,SAASA,QAAO,OAAO,CAAC,UAAU,MAAM,UAAU,KAAK;AAC7D,QAAI,OAAO,SAAS,EAAG,KAAI,KAAK,IAAI,wBAAwB,MAAM;AAAA,EACpE;AACA,SAAO;AACT;AAEA,SAAS,wBAAwBA,SAAkE;AACjG,QAAM,UAAUG,KAAIH,QAAO,IAAI,CAAC,UAAU,MAAM,OAAO,CAAC;AACxD,QAAM,QAAQG,KAAIH,QAAO,IAAI,CAAC,UAAU,MAAM,KAAK,CAAC;AACpD,QAAM,iBAAiBG,KAAIH,QAAO,IAAI,CAAC,UAAU,MAAM,cAAc,CAAC;AACtE,QAAM,gBAAgBG,KAAIH,QAAO,IAAI,CAAC,UAAU,MAAM,aAAa,CAAC;AACpE,QAAM,cAAcG,KAAIH,QAAO,IAAI,CAAC,UAAU,MAAM,WAAW,CAAC;AAChE,QAAMI,aAAY,MAAM,SAAS,UAAU,cAAc;AACzD,QAAM,SAAS,MAAM,SAAS,KAAK;AACnC,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,WAAAA;AAAA,IACA;AAAA,IACA,IAAI,GAAGA,YAAW,MAAM;AAAA,IACxB,gBAAgB,MAAM,eAAe,WAAW;AAAA,EAClD;AACF;AAEA,SAAS,iBAA2C;AAClD,SAAO;AAAA,IACL,SAAS;AAAA,IACT,OAAO;AAAA,IACP,gBAAgB;AAAA,IAChB,eAAe;AAAA,IACf,aAAa;AAAA,IACb,WAAW;AAAA,IACX,QAAQ;AAAA,IACR,IAAI;AAAA,IACJ,gBAAgB;AAAA,EAClB;AACF;AAEA,SAAS,SAAS,OAA6B,OAAsC;AACnF,SAAO,MAAM,QAAQ,KAAK,MAAM;AAClC;AAEA,SAAS,GAAGA,YAAmB,QAAwB;AACrD,SAAOA,aAAY,WAAW,IAAI,IAAK,IAAIA,aAAY,UAAWA,aAAY;AAChF;AAEA,SAAS,MAAM,WAAmB,aAA6B;AAC7D,SAAO,cAAc,IAAI,YAAY,cAAc;AACrD;AAEA,SAAS,aAAa,GAAW,GAAmB;AAClD,QAAM,OAAO,IAAI,IAAIC,QAAO,CAAC,CAAC;AAC9B,QAAM,QAAQ,IAAI,IAAIA,QAAO,CAAC,CAAC;AAC/B,MAAI,KAAK,SAAS,KAAK,MAAM,SAAS,EAAG,QAAO;AAChD,MAAI,eAAe;AACnB,aAAW,SAAS,MAAM;AACxB,QAAI,MAAM,IAAI,KAAK,EAAG;AAAA,EACxB;AACA,SAAO,gBAAgB,KAAK,OAAO,MAAM,OAAO;AAClD;AAEA,SAAS,WAAW,GAAyB,GAAiC;AAC5E,MAAI,CAAC,GAAG,UAAU,CAAC,GAAG,OAAQ,QAAO;AACrC,QAAM,OAAO,IAAI,IAAI,EAAE,IAAI,SAAS,CAAC;AACrC,QAAM,QAAQ,IAAI,IAAI,EAAE,IAAI,SAAS,CAAC;AACtC,MAAI,eAAe;AACnB,aAAW,OAAO,MAAM;AACtB,QAAI,MAAM,IAAI,GAAG,EAAG;AAAA,EACtB;AACA,SAAO,eAAe,KAAK,IAAI,KAAK,MAAM,MAAM,IAAI;AACtD;AAEA,SAASA,QAAO,MAAwB;AACtC,SAAO,UAAU,IAAI,EAClB,MAAM,KAAK,EACX,OAAO,CAAC,UAAU,MAAM,UAAU,KAAK,CAAC,WAAW,IAAI,KAAK,CAAC;AAClE;AAEA,SAAS,UAAU,MAAsB;AACvC,SAAO,KACJ,YAAY,EACZ,QAAQ,eAAe,GAAG,EAC1B,KAAK;AACV;AAEA,SAASH,SAAQ,OAAuB;AACtC,MAAI,CAAC,OAAO,SAAS,KAAK,EAAG,QAAO;AACpC,SAAO,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,KAAK,CAAC;AACvC;AAEA,SAASC,KAAI,QAA0B;AACrC,SAAO,OAAO,OAAO,CAAC,KAAK,UAAU,MAAM,OAAO,CAAC;AACrD;AAEA,SAASF,MAAK,QAA0B;AACtC,SAAO,OAAO,SAASE,KAAI,MAAM,IAAI,OAAO,SAAS;AACvD;AAEA,SAAS,UAAU,OAAuB;AACxC,SAAO,IAAI,QAAQ,KAAK,QAAQ,CAAC,CAAC;AACpC;AAEA,SAAS,aAAa,GAAyB,GAAiC;AAC9E,SAAO,WAAW,QAAQ,CAAC,IAAI,WAAW,QAAQ,CAAC;AACrD;AAEA,SAAS,WACP,SACA,UACA,SACqC;AACrC,SAAO,OAAO,YAAY,aAAa,QAAQ,UAAU,OAAO,IAAI,QAAQ,IAAI,UAAU,OAAO;AACnG;AAEA,SAAS,eAAe,QAAuC;AAC7D,MAAI,CAAC,QAAQ,QAAS;AACtB,MAAI,OAAO,kBAAkB,MAAO,OAAM,OAAO;AACjD,QAAM,IAAI,MAAM,OAAO,SAAS,OAAO,OAAO,MAAM,IAAI,0BAA0B;AACpF;AAEA,SAAS,UAAiB,MAA2C;AACnE,QAAM,MAAMG,cAAa,MAAM,MAAM;AACrC,QAAM,MAAmC,CAAC;AAC1C,aAAW,QAAQ,IAAI,MAAM,IAAI,GAAG;AAClC,UAAM,UAAU,KAAK,KAAK;AAC1B,QAAI,CAAC,QAAS;AACd,QAAI,KAAK,KAAK,MAAM,OAAO,CAA8B;AAAA,EAC3D;AACA,SAAO;AACT;AAEA,IAAM,aAAa,oBAAI,IAAI;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;;;ACjuBD,IAAM,kBAAkB;AAAA,EACtB,MAAM;AAAA,EACN,sBAAsB;AAAA,EACtB,UAAU,CAAC,gBAAgB,aAAa,uBAAuB,kBAAkB,YAAY;AAAA,EAC7F,YAAY;AAAA,IACV,cAAc,EAAE,MAAM,UAAU,WAAW,IAAI,WAAW,IAAK;AAAA,IAC/D,WAAW,EAAE,MAAM,UAAU,WAAW,IAAI,WAAW,KAAK;AAAA,IAC5D,qBAAqB,EAAE,MAAM,UAAU,WAAW,IAAI,WAAW,IAAK;AAAA,IACtE,gBAAgB,EAAE,MAAM,UAAU;AAAA,IAClC,YAAY,EAAE,MAAM,UAAU,SAAS,GAAG,SAAS,EAAE;AAAA,EACvD;AACF;AAIA,SAAS,gBAAgB,QAAuC;AAC9D,MAAI,OAAO,WAAW,EAAG,QAAO;AAChC,SAAO,OACJ,IAAI,CAAC,MAAM;AACV,UAAM,SAAS,QAAQ,EAAE,IAAI,uBAAkB,EAAE,cAAc,GAAG,QAAQ,CAAC,CAAC,mBAAmB,EAAE,kBAAkB,GAAG;AACtH,UAAM,MAAM,EAAE,eAAe,mBAAmB,EAAE,aAAa,MAAM,GAAG,GAAG,CAAC,KAAK;AACjF,UAAM,OAAO,EAAE,YAAY,gBAAgB,EAAE,UAAU,MAAM,GAAG,GAAG,CAAC,KAAK;AACzE,UAAM,QAAQ,EAAE,sBACZ,wBAAwB,EAAE,oBAAoB,MAAM,GAAG,GAAG,CAAC,KAC3D;AACJ,WAAO,CAAC,QAAQ,KAAK,MAAM,KAAK,EAAE,OAAO,OAAO,EAAE,KAAK,IAAI;AAAA,EAC7D,CAAC,EACA,KAAK,MAAM;AAChB;AAOO,SAAS,oBAAoB,OAA8D;AAChG,QAAM,SACJ;AAIF,QAAM,qBACJ,MAAM,aAAa,iBAAiB,MAAM,aAAa,cAAc,SAAS,IAC1E,mBAAmB,MAAM,aAAa,cAAc,KAAK,IAAI,CAAC,KAC9D;AAEN,QAAM,OAAO;AAAA,OACR,MAAM,IAAI;AAAA;AAAA;AAAA,EAGf,MAAM,WAAW;AAAA;AAAA,yBAEM,MAAM,IAAI;AAAA,EACjC,MAAM,YAAY;AAAA,EAClB,MAAM,eAAe;AAAA;AAAA,EAA4B,MAAM,YAAY;AAAA,IAAO,EAAE;AAAA,yBACrD,MAAM,IAAI;AAAA,gBACnB,MAAM,aAAa,aAAa,QAAQ,CAAC,CAAC;AAAA,WAC/C,MAAM,aAAa,OAAO;AAAA,aACxB,MAAM,aAAa,SAAS;AAAA,EACvC,kBAAkB;AAAA;AAAA;AAAA,EAGlB,gBAAgB,MAAM,MAAM,CAAC;AAAA,EAC7B,MAAM,kBAAkB;AAAA;AAAA,EAA+B,MAAM,eAAe;AAAA,IAAO,EAAE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAgBrF,SAAO,EAAE,QAAQ,KAAK;AACxB;AAIA,IAAM,oBAAwD;AAAA,EAC5D,cAAc;AAAA,EACd,WAAW;AAAA,EACX,qBACE;AAAA,EAEF,gBAAgB;AAAA,EAChB,YAAY;AACd;AAQO,SAAS,sBACd,SACyD;AACzD,QAAMC,YAA+C;AAAA,IACnD,GAAG;AAAA,IACH,GAAI,QAAQ,oBAAoB,CAAC;AAAA,EACnC;AACA,QAAM,gBAAgB,QAAQ,iBAAiB;AAC/C,QAAM,YAAY,QAAQ,aAAa;AAEvC,SAAO,OAAO,UAAU;AACtB,UAAM,QAAQ,KAAK,IAAI;AACvB,UAAM,EAAE,QAAQ,KAAK,IAAI,cAAc,KAAK;AAC5C,QAAI;AACF,YAAM,EAAE,OAAO,OAAO,IAAI,MAAM;AAAA,QAO9B;AAAA,UACE,OAAO,QAAQ;AAAA,UACf,UAAU;AAAA,YACR,EAAE,MAAM,UAAU,SAAS,OAAO;AAAA,YAClC,EAAE,MAAM,QAAQ,SAAS,KAAK;AAAA,UAChC;AAAA,UACA,YAAY,EAAE,MAAM,mBAAmB,QAAQ,gBAAgB;AAAA,UAC/D,aAAa;AAAA,UACb;AAAA,QACF;AAAA,QACA,QAAQ,OAAO,CAAC;AAAA,MAClB;AAEA,aAAO;AAAA,QACL,MAAM,MAAM;AAAA,QACZ,cAAc,OAAO,MAAM,gBAAgBA,UAAS,YAAY;AAAA,QAChE,WAAW,OAAO,MAAM,aAAaA,UAAS,SAAS;AAAA,QACvD,qBAAqB,OAAO,MAAM,uBAAuBA,UAAS,mBAAmB;AAAA,QACrF,gBAAgB,QAAQ,MAAM,cAAc;AAAA,QAC5C,YAAY,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,OAAO,MAAM,cAAcA,UAAS,UAAU,CAAC,CAAC;AAAA,QACpF,SAAS,OAAO,WAAW;AAAA,QAC3B,YAAY,KAAK,IAAI,IAAI;AAAA,QACzB,WAAW;AAAA,MACb;AAAA,IACF,SAAS,KAAK;AACZ,aAAO;AAAA,QACL,MAAM,MAAM;AAAA,QACZ,cAAcA,UAAS;AAAA,QACvB,WAAWA,UAAS;AAAA,QACpB,qBAAqBA,UAAS;AAAA,QAC9B,gBAAgBA,UAAS;AAAA,QACzB,YAAYA,UAAS;AAAA,QACrB,SAAS;AAAA,QACT,YAAY,KAAK,IAAI,IAAI;AAAA,QACzB,WAAW;AAAA,QACX,OAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,MACxD;AAAA,IACF;AAAA,EACF;AACF;;;ACvQA,SAAS,YAAY,UAAU;AAC/B,SAAS,UAAU,SAAS,QAAAC,aAAY;AA+BxC,IAAM,kBAAkB;AAExB,eAAsB,iBACpB,KACA,OAAgC,CAAC,GACH;AAC9B,QAAM,UAAU,KAAK,WAAW;AAChC,QAAM,UAAU,IAAI,IAAI,KAAK,WAAW,CAAC,CAAC;AAC1C,QAAM,UAAU,KAAK;AAErB,iBAAe,KAAK,GAAyC;AAC3D,QAAI;AACJ,QAAI;AACF,YAAM,MAAM,MAAM,GAAG,QAAQ,GAAG,EAAE,eAAe,KAAK,CAAC;AACvD,gBAAU,IAAI,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,OAAO,EAAE,YAAY,EAAE,EAAE;AAAA,IACrE,SAAS,KAAK;AACZ,YAAM,OAAQ,IAA8B;AAC5C,UAAI,SAAS,SAAU,QAAO,CAAC;AAC/B,YAAM;AAAA,IACR;AACA,UAAM,MAA2B,CAAC;AAClC,eAAW,SAAS,SAAS;AAC3B,YAAM,OAAOA,MAAK,GAAG,MAAM,IAAI;AAC/B,UAAI,MAAM,OAAO;AACf,YAAI,KAAK,UAAW,KAAI,KAAK,GAAI,MAAM,KAAK,IAAI,CAAE;AAClD;AAAA,MACF;AACA,UAAI,CAAC,QAAQ,KAAK,MAAM,IAAI,EAAG;AAC/B,UAAI,QAAQ,IAAI,MAAM,IAAI,KAAK,QAAQ,IAAI,SAAS,MAAM,MAAM,QAAQ,MAAM,IAAI,CAAC,CAAC;AAClF;AACF,UAAI,WAAW,QAAQ,SAAS,GAAG;AACjC,cAAM,KAAK,SAAS,MAAM,MAAM,QAAQ,MAAM,IAAI,CAAC;AACnD,cAAM,UAAU,QAAQ,KAAK,CAAC,WAAW,MAAM,KAAK,SAAS,MAAM,KAAK,GAAG,SAAS,MAAM,CAAC;AAC3F,YAAI,CAAC,QAAS;AAAA,MAChB;AACA,UAAI,KAAK;AAAA,QACP,MAAM;AAAA,QACN,UAAU,MAAM;AAAA,QAChB,IAAI,SAAS,MAAM,MAAM,QAAQ,MAAM,IAAI,CAAC;AAAA,MAC9C,CAAC;AAAA,IACH;AACA,WAAO;AAAA,EACT;AAEA,QAAM,UAAU,MAAM,KAAK,GAAG;AAC9B,UAAQ,KAAK,CAAC,GAAG,MAAM,EAAE,SAAS,cAAc,EAAE,QAAQ,CAAC;AAC3D,SAAO;AACT;;;AClCO,SAAS,aACd,SACA,YACA,UAMI,CAAC,GACQ;AACb,QAAM,UAAU,QAAQ,QAAQC;AAChC,QAAM,YAAY,WAAW,IAAI,CAAC,MAAM,QAAQ,CAAC,EAAE,YAAY,CAAC;AAChE,QAAM,UAAU,QAAQ,IAAI,CAAC,WAAW,cAAc,QAAQ,SAAS,CAAC;AACxE,SAAO;AAAA,IACL;AAAA,IACA,MAAM,QAAQ,OAAO,OAAO,EAAE;AAAA,IAC9B,OAAO,QAAQ;AAAA,EACjB;AACF;AAEA,SAASA,gBAAe,WAA4B;AAClD,MAAI,OAAO,cAAc,SAAU,QAAO;AAC1C,MAAI,aAAa,OAAO,cAAc,UAAU;AAC9C,UAAM,QAAkB,CAAC;AACzB,eAAW,KAAK,OAAO,OAAO,SAAoC,GAAG;AACnE,UAAI,OAAO,MAAM,SAAU,OAAM,KAAK,CAAC;AAAA,IACzC;AACA,WAAO,MAAM,KAAK,GAAG;AAAA,EACvB;AACA,SAAO,OAAO,aAAa,EAAE;AAC/B;AAEA,SAAS,cAAc,QAAoB,WAA8B;AACvE,aAAW,UAAU,OAAO,KAAK;AAC/B,UAAM,SAAS,OAAO,YAAY,EAAE,KAAK;AACzC,QAAI,CAAC,OAAQ;AACb,QAAI,UAAU,KAAK,CAAC,MAAM,EAAE,SAAS,MAAM,CAAC,EAAG,QAAO;AAAA,EACxD;AACA,aAAW,WAAW,OAAO,YAAY,CAAC,GAAG;AAC3C,QAAI;AACJ,QAAI;AACF,WAAK,IAAI,OAAO,SAAS,GAAG;AAAA,IAC9B,QAAQ;AACN;AAAA,IACF;AACA,QAAI,UAAU,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,CAAC,EAAG,QAAO;AAAA,EAChD;AACA,SAAO;AACT;AAGO,IAAM,2BAA2D;AAAA,EACtE,UAAU;AAAA,EACV,OAAO;AAAA,EACP,OAAO;AACT;AAGO,SAAS,eACd,SACA,QACA,UAA0C,0BAClC;AACR,MAAI,QAAQ,WAAW,EAAG,QAAO;AACjC,QAAM,QAAQ,QAAQ,OAAO,CAAC,GAAG,MAAM,KAAK,QAAQ,EAAE,QAAQ,KAAK,IAAI,CAAC;AACxE,MAAI,UAAU,EAAG,QAAO;AACxB,QAAM,MAAM,QAAQ;AAAA,IAClB,CAAC,GAAG,GAAG,MAAM,KAAK,OAAO,QAAQ,CAAC,IAAK,QAAQ,EAAE,QAAQ,KAAK,IAAK;AAAA,IACnE;AAAA,EACF;AACA,SAAO,MAAM;AACf;AAUO,SAAS,UACd,SACA,YACA,UAA+C,CAAC,GACxC;AACR,MAAI,WAAW,WAAW,EAAG,QAAO;AACpC,QAAM,UAAU,QAAQ,QAAQA;AAChC,MAAI,UAAU;AACd,aAAW,QAAQ,YAAY;AAC7B,UAAM,WAAW,QAAQ,IAAI,EAAE,YAAY;AAC3C,UAAM,aAAa,QAAQ;AAAA,MACzB,CAAC,MACC,EAAE,IAAI,KAAK,CAAC,WAAW,OAAO,SAAS,KAAK,SAAS,SAAS,OAAO,YAAY,CAAC,CAAC,MAClF,EAAE,YAAY,CAAC,GAAG,KAAK,CAAC,QAAQ;AAC/B,YAAI;AACF,iBAAO,IAAI,OAAO,KAAK,GAAG,EAAE,KAAK,QAAQ;AAAA,QAC3C,QAAQ;AACN,iBAAO;AAAA,QACT;AAAA,MACF,CAAC;AAAA,IACL;AACA,QAAI,WAAY;AAAA,EAClB;AACA,SAAO,UAAU,WAAW;AAC9B;;;AChCO,IAAM,cAAN,MAAkB;AAAA,EACN;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEjB,YAAY,QAA2B;AACrC,QAAI,CAAC,OAAO,aAAa;AACvB,YAAM,IAAI,MAAM,sCAAsC;AAAA,IACxD;AACA,SAAK,oBAAoB,OAAO,qBAAqB;AACrD,SAAK,uBAAuB,OAAO,wBAAwB;AAC3D,SAAK,sBAAsB,OAAO,uBAAuB;AACzD,SAAK,cAAc,OAAO;AAC1B,SAAK,aAAa,OAAO,cAAc;AACvC,SAAK,YAAY,OAAO,sBAAsB;AAC9C,SAAK,OAAO,OAAO;AACnB,QACE,OAAO,uBAAuB,UAC9B,EAAE,OAAO,SAAS,OAAO,kBAAkB,KAAK,OAAO,qBAAqB,IAC5E;AACA,YAAM,IAAI,MAAM,kEAAkE;AAAA,IACpF;AACA,SAAK,qBAAqB,OAAO;AAAA,EACnC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,SAAS,WAAwB,UAAqC;AACpE,UAAM,cAAc,iBAAiB,WAAW,KAAK,WAAW;AAChE,UAAM,aAAa,KAAK;AAGxB,UAAM,uBAAuB,kBAAkB,QAAQ;AACvD,UAAM,gBAA0B,CAAC;AACjC,UAAM,eAAyB,CAAC;AAChC,eAAW,OAAO,WAAW;AAC3B,UAAI,IAAI,aAAa,UAAW;AAChC,UAAI,IAAI,QAAQ,iBAAiB,OAAW;AAC5C,YAAM,MAAM,QAAQ,GAAG;AACvB,YAAM,cAAc,qBAAqB,IAAI,GAAG;AAChD,UAAI,gBAAgB,OAAW;AAC/B,oBAAc,KAAK,WAAW;AAC9B,mBAAa,KAAK,IAAI,QAAQ,YAAY;AAAA,IAC5C;AAEA,UAAM,iBAAiB,cAAc;AAIrC,UAAM,sBAAsBC,MAAK,OAAO,WAAW,eAAe,QAAQ,CAAC;AAC3E,UAAM,uBAAuBA,MAAK,OAAO,WAAW,gBAAgB,SAAS,CAAC;AAC9E,UAAM,qBAAqBA,MAAK,OAAO,UAAU,eAAe,QAAQ,CAAC;AACzE,UAAM,sBAAsBA,MAAK,OAAO,UAAU,gBAAgB,SAAS,CAAC;AAE5E,UAAM,aAAa,SAAS,qBAAqB,oBAAoB;AACrE,UAAM,qBAAqB,SAAS,oBAAoB,mBAAmB;AAI3E,UAAM,sBAAsB,aAAa,UAAU,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC;AACxE,UAAM,qBAAqB,aAAa,SAAS,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC;AAGtE,QAAI,iBAAiB,KAAK,mBAAmB;AAC3C,aAAO;AAAA,QACL,SAAS;AAAA,QACT;AAAA,QACA;AAAA,QACA,UAAU;AAAA,UACR;AAAA,UACA,mBAAmB,iBAAiB,IAAI,YAAY,eAAe,YAAY,IAAI;AAAA,UACnF,UAAU,EAAE,KAAK,GAAG,MAAM,EAAE;AAAA,UAC5B,cAAc;AAAA,UACd,aAAa;AAAA,UACb,cAAc;AAAA,UACd;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,QACA,QAAQ,aAAa,cAAc,wCAAwC,KAAK,iBAAiB;AAAA,QACjG,eAAe;AAAA,MACjB;AAAA,IACF;AAGA,UAAM,KAAK,gBAAgB,eAAe,cAAc;AAAA,MACtD,YAAY,KAAK;AAAA,MACjB,WAAW,KAAK;AAAA,MAChB,WAAW;AAAA,MACX,MAAM,KAAK;AAAA,IACb,CAAC;AACD,UAAM,WAAW,mBAAmB,eAAe,YAAY;AAE/D,UAAM,WAAyB;AAAA,MAC7B;AAAA,MACA,mBAAmB,GAAG;AAAA,MACtB,UAAU,EAAE,KAAK,GAAG,KAAK,MAAM,GAAG,KAAK;AAAA,MACvC,cAAc,SAAS;AAAA,MACvB,aAAa;AAAA,MACb,cAAc;AAAA,MACd;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAGA,QAAI,EAAE,GAAG,MAAM,KAAK,uBAAuB;AACzC,aAAO;AAAA,QACL,SAAS;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,QACA,QACE,gDAA2C,IAAI,GAAG,MAAM,CAAC,QAClD,IAAI,GAAG,GAAG,CAAC,KAAK,IAAI,GAAG,IAAI,CAAC,8BAA8B,IAAI,KAAK,oBAAoB,CAAC;AAAA,QACjG,eAAe;AAAA,MACjB;AAAA,IACF;AAIA,QACE,OAAO,SAAS,UAAU,KAC1B,OAAO,SAAS,kBAAkB,KAClC,aAAa,qBAAqB,KAAK,qBACvC;AACA,aAAO;AAAA,QACL,SAAS;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,QACA,QACE,8BAA8B,IAAI,UAAU,CAAC,yBAAyB,IAAI,kBAAkB,CAAC,iBAC7E,IAAI,KAAK,mBAAmB,CAAC;AAAA,QAC/C,eAAe;AAAA,MACjB;AAAA,IACF;AAQA,QACE,KAAK,uBAAuB,UAC5B,OAAO,SAAS,mBAAmB,KACnC,sBAAsB,KAAK,oBAC3B;AACA,aAAO;AAAA,QACL,SAAS;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,QACA,QACE,wCAAwC,IAAI,mBAAmB,CAAC,qBAC5C,IAAI,KAAK,kBAAkB,CAAC,eAAe,IAAI,kBAAkB,CAAC;AAAA,QACxF,eAAe;AAAA,MACjB;AAAA,IACF;AAEA,WAAO;AAAA,MACL,SAAS;AAAA,MACT;AAAA,MACA;AAAA,MACA;AAAA,MACA,QACE,yCAAoC,IAAI,GAAG,MAAM,CAAC,QAC3C,IAAI,GAAG,GAAG,CAAC,KAAK,IAAI,GAAG,IAAI,CAAC,UAAU,cAAc,iCAClC,IAAI,UAAU,CAAC,gBAAgB,IAAI,kBAAkB,CAAC,4BACrD,IAAI,mBAAmB,CAAC,iBAAiB,IAAI,kBAAkB,CAAC;AAAA,MAC5F,eAAe;AAAA,IACjB;AAAA,EACF;AACF;AAIA,SAAS,iBAAiB,WAAwB,aAA6B;AAC7E,aAAW,OAAO,WAAW;AAC3B,QAAI,IAAI,eAAe,IAAI,gBAAgB,YAAa,QAAO,IAAI;AAAA,EACrE;AAGA,SAAO,UAAU,CAAC,GAAG,eAAe;AACtC;AAEA,SAAS,kBAAkB,MAAwC;AACjE,QAAM,MAAM,oBAAI,IAAoB;AACpC,aAAW,KAAK,MAAM;AACpB,QAAI,EAAE,aAAa,UAAW;AAC9B,QAAI,EAAE,QAAQ,iBAAiB,OAAW;AAC1C,QAAI,IAAI,QAAQ,CAAC,GAAG,EAAE,QAAQ,YAAY;AAAA,EAC5C;AACA,SAAO;AACT;AAEA,SAAS,QAAQ,GAAsB;AACrC,SAAO,GAAG,EAAE,YAAY,KAAK,EAAE,IAAI;AACrC;AAEA,SAAS,OACP,MACA,OACA,aACU;AACV,QAAM,MAAgB,CAAC;AACvB,aAAW,KAAK,MAAM;AACpB,QAAI,EAAE,aAAa,YAAa;AAChC,UAAM,IAAI,EAAE,QAAQ,KAAK;AACzB,QAAI,OAAO,MAAM,YAAY,OAAO,SAAS,CAAC,EAAG,KAAI,KAAK,CAAC;AAAA,EAC7D;AACA,SAAO;AACT;AAEA,SAASA,MAAK,IAAsB;AAClC,MAAI,GAAG,WAAW,EAAG,QAAO,OAAO;AACnC,SAAO,GAAG,OAAO,CAAC,GAAG,MAAM,IAAI,GAAG,CAAC,IAAI,GAAG;AAC5C;AAEA,SAAS,SAAS,GAAW,GAAmB;AAC9C,MAAI,CAAC,OAAO,SAAS,CAAC,KAAK,CAAC,OAAO,SAAS,CAAC,EAAG,QAAO,OAAO;AAC9D,SAAO,IAAI;AACb;AAEA,SAAS,YAAY,QAAkB,OAAyB;AAC9D,QAAM,KAAK,OAAO,IAAI,CAAC,GAAG,MAAM,MAAM,CAAC,IAAK,CAAC,EAAE,KAAK,CAAC,GAAG,MAAM,IAAI,CAAC;AACnE,MAAI,GAAG,WAAW,EAAG,QAAO;AAC5B,QAAM,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;AACpC,SAAO,GAAG,SAAS,MAAM,KAAK,GAAG,MAAM,CAAC,IAAK,GAAG,GAAG,KAAM,IAAI,GAAG,GAAG;AACrE;AAEA,SAAS,aAAa,IAAsB;AAC1C,QAAM,KAAK,GAAG,OAAO,CAAC,MAAM,OAAO,SAAS,CAAC,CAAC,EAAE,KAAK,CAAC,GAAG,MAAM,IAAI,CAAC;AACpE,MAAI,GAAG,WAAW,EAAG,QAAO,OAAO;AACnC,QAAM,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;AACpC,SAAO,GAAG,SAAS,MAAM,KAAK,GAAG,MAAM,CAAC,IAAK,GAAG,GAAG,KAAM,IAAI,GAAG,GAAG;AACrE;AAEA,SAAS,IAAI,GAAmB;AAC9B,MAAI,CAAC,OAAO,SAAS,CAAC,EAAG,QAAO,OAAO,CAAC;AACxC,SAAO,EAAE,QAAQ,CAAC;AACpB;;;AC/TA,IAAM,uBAAuB;AAC7B,IAAM,qBAAqB;AAE3B,SAAS,MAAM,IAA2B;AACxC,SAAO,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,EAAE,CAAC;AACzD;AAaA,eAAsB,eACpB,SACA,SAA2B,CAAC,GACG;AAC/B,QAAM,cAAc,OAAO,eAAe;AAC1C,QAAM,YAAY,OAAO,aAAa;AACtC,QAAM,UAAU,OAAO,aAAa;AACpC,QAAM,cAAc,OAAO,eAAe;AAC1C,QAAM,SACJ,OAAO,UAAU,OAAO,OAAO,SAAS,IAAI,OAAO,SAAS,CAAC,MAA8B;AAE7F,MAAI,gBAAgB;AACpB,QAAM,gBAAuD,CAAC;AAC9D,MAAI;AAEJ,aAAW,SAAS,QAAQ;AAC1B,aAAS,UAAU,GAAG,UAAU,aAAa,WAAW;AACtD,uBAAiB;AACjB,YAAM,aAAa,IAAI,gBAAgB;AACvC,YAAM,QAAQ,WAAW,MAAM,WAAW,MAAM,IAAI,MAAM,cAAc,CAAC,GAAG,SAAS;AACrF,UAAI;AACF,cAAM,QAAQ,MAAM,QAAQ,OAAiB,WAAW,MAAM;AAC9D,qBAAa,KAAK;AAClB,eAAO;AAAA,UACL;AAAA,UACA,WAAW;AAAA,UACX,UAAU;AAAA,UACV,WAAW;AAAA,UACX;AAAA,QACF;AAAA,MACF,SAAS,KAAK;AACZ,qBAAa,KAAK;AAClB,cAAM,SAAS,eAAe,QAAQ,MAAM,IAAI,MAAM,OAAO,GAAG,CAAC;AACjE,oBAAY;AACZ,sBAAc,KAAK;AAAA,UACjB,SAAS;AAAA,UACT,OAAO,SAAS;AAAA,UAChB,OAAO,OAAO;AAAA,QAChB,CAAC;AACD,YAAI,CAAC,YAAY,MAAM,GAAG;AAIxB,iBAAO;AAAA,YACL,OAAO;AAAA,YACP,WAAW;AAAA,YACX,UAAU;AAAA,YACV,OAAO;AAAA,YACP;AAAA,UACF;AAAA,QACF;AACA,YAAI,UAAU,cAAc,GAAG;AAC7B,gBAAM,MAAM,QAAQ,OAAO,CAAC;AAAA,QAC9B;AAAA,MACF;AAAA,IACF;AAAA,EAIF;AAEA,SAAO;AAAA,IACL,OAAO;AAAA,IACP,WAAW;AAAA,IACX,UAAU;AAAA,IACV,OAAO;AAAA,IACP;AAAA,EACF;AACF;;;AC9GO,SAAS,kBAAqB,OAAmD;AACtF,QAAM,SAAS,MAAM;AACrB,MAAI,OAAO,SAAS,GAAG;AACrB,WAAO,EAAE,eAAe,GAAG,WAAW,OAAO,QAAQ,cAAc,CAAC,EAAE;AAAA,EACxE;AACA,QAAM,SAAS,MAAM,QAAQ;AAC7B,QAAM,SAAS,MAAM,kBAAkB;AACvC,QAAM,UAAU,OAAO,IAAI,CAAC,MAAM,WAAW,EAAE,UAAU,QAAQ,MAAM,CAAC;AACxE,QAAM,OAAiB,CAAC;AACxB,WAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACvC,aAAS,IAAI,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AAC3C,WAAK,KAAK,iBAAiB,QAAQ,CAAC,GAAI,QAAQ,CAAC,CAAE,CAAC;AAAA,IACtD;AAAA,EACF;AACA,QAAMC,QAAO,KAAK,WAAW,IAAI,IAAI,KAAK,OAAO,CAAC,GAAG,MAAM,IAAI,GAAG,CAAC,IAAI,KAAK;AAC5E,SAAO;AAAA,IACL,eAAe,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,IAAIA,KAAI,CAAC;AAAA,IAChD,WAAW,OAAO;AAAA,IAClB,cAAc;AAAA,EAChB;AACF;AAEA,SAAS,cAAc,MAAuB;AAC5C,MAAI,OAAO,SAAS,SAAU,QAAO;AACrC,MAAI,QAAQ,OAAO,SAAS,UAAU;AACpC,UAAM,QAAkB,CAAC;AACzB,eAAW,KAAK,OAAO,OAAO,IAA+B,GAAG;AAC9D,UAAI,OAAO,MAAM,SAAU,OAAM,KAAK,CAAC;AAAA,IACzC;AACA,WAAO,MAAM,KAAK,GAAG;AAAA,EACvB;AACA,SAAO,OAAO,QAAQ,EAAE;AAC1B;AAEA,SAAS,WACP,OACA,QACA,QACqB;AACrB,QAAM,MAAM,oBAAI,IAAoB;AACpC,aAAW,QAAQ,OAAO;AACxB,UAAM,OAAO,OAAO,IAAI,EAAE,YAAY;AACtC,eAAW,OAAO,KAAK,MAAM,YAAY,EAAE,OAAO,CAAC,MAAM,EAAE,UAAU,MAAM,GAAG;AAC5E,UAAI,IAAI,MAAM,IAAI,IAAI,GAAG,KAAK,KAAK,CAAC;AAAA,IACtC;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,iBAAiB,GAAwB,GAAgC;AAChF,MAAI,MAAM;AACV,MAAI,OAAO;AACX,MAAI,OAAO;AACX,aAAW,CAAC,EAAE,CAAC,KAAK,EAAG,SAAQ,IAAI;AACnC,aAAW,CAAC,EAAE,CAAC,KAAK,EAAG,SAAQ,IAAI;AACnC,aAAW,CAAC,GAAG,CAAC,KAAK,GAAG;AACtB,UAAM,KAAK,EAAE,IAAI,CAAC;AAClB,QAAI,GAAI,QAAO,IAAI;AAAA,EACrB;AACA,MAAI,SAAS,KAAK,SAAS,EAAG,QAAO;AACrC,SAAO,OAAO,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,IAAI;AAChD;;;AC9EO,SAAS,kCACd,MACA,UAAqD,CAAC,GAC3B;AAC3B,QAAM,OAAkC,CAAC;AACzC,aAAW,OAAO,MAAM;AACtB,UAAM,YAAY,IAAI,aAAa,IAAI;AACvC,UAAM,SAAS,QAAQ,eAAe,GAAG,KAAK;AAAA,MAC5C,IAAI;AAAA,MACJ,UAAU,IAAI;AAAA,IAChB;AAEA,eAAW,WAAW,IAAI,OAAO;AAC/B,WAAK,KAAK;AAAA,QACR;AAAA,QACA,YAAY,QAAQ;AAAA,QACpB;AAAA,QACA,OACE,QAAQ,eAAe,SAAS,GAAG,KACnC,kCAAkC,QAAQ,OAAO,QAAQ,UAAU;AAAA,QACrE,UAAU;AAAA,UACR,OAAO,IAAI;AAAA,UACX,OAAO,QAAQ;AAAA,UACf,MAAM,QAAQ,UAAU,QAAQ,QAAQ,UAAU,QAAQ,QAAQ;AAAA,UAClE,gBAAgB,QAAQ,WAAW;AAAA,UACnC,gBAAgB,QAAQ,WAAW;AAAA,UACnC,SAAS,QAAQ,MAAM;AAAA,UACvB,OAAO,QAAQ,MAAM;AAAA,UACrB,gBAAgB,QAAQ,MAAM;AAAA,UAC9B,WAAW,QAAQ,MAAM;AAAA,UACzB,QAAQ,QAAQ,MAAM;AAAA,UACtB,IAAI,QAAQ,MAAM;AAAA,UAClB,OAAO,QAAQ;AAAA,UACf,GAAI,QAAQ,YAAY,CAAC;AAAA,QAC3B;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AACA,SAAO;AACT;AAEO,SAAS,kCACd,eACA,aAAa,GACH;AACV,QAAM,UAAU,cAAc;AAC9B,QAAM,SAAS,cAAc;AAC7B,QAAMC,aAAY,cAAc;AAChC,QAAM,SAAS,cAAc,QAAQ,KAAK,cAAc,YAAY;AAEpE,SAAO;AAAA,IACL;AAAA,IACA,cAAc;AAAA,IACd,kBAAkBA;AAAA,IAClB,cAAc,IAAIA;AAAA,IAClB,gBAAgBA;AAAA,IAChB,cAAc;AAAA,IACd,aAAa,cAAc,QAAQ,IAAI,IAAI;AAAA,IAC3C,WAAW;AAAA,IACX,kBAAkB,SAAS,IAAI;AAAA,IAC/B,SAAS;AAAA,IACT,aAAa,KAAK,IAAI,GAAG,aAAa,GAAI;AAAA,IAC1C,OAAO;AAAA,MACL,4BAA4B,cAAc,OAAO,IAAI,cAAc,KAAK;AAAA,MACxE,aAAaA,WAAU,QAAQ,CAAC,CAAC,WAAW,OAAO,QAAQ,CAAC,CAAC,OAAO,QAAQ,QAAQ,CAAC,CAAC;AAAA,IACxF;AAAA,EACF;AACF;;;ACmCO,IAAM,qBAAN,MAA+C;AAAA,EACpD,YAA6B,WAAsC;AAAtC;AAAA,EAAuC;AAAA,EAAvC;AAAA,EAE7B,gBAAgB,MAA2C;AACzD,WAAO,KAAK,UAAU,gBAAgB,IAAI;AAAA,EAC5C;AAAA,EAEA,cAAc,UAAoD;AAChE,WAAO,KAAK,UAAU,cAAc,QAAQ;AAAA,EAC9C;AAAA,EAEA,YAAY,SAA2B,UAAmD;AACxF,WAAO,KAAK,UAAU,YAAY,SAAS,QAAQ;AAAA,EACrD;AAAA,EAEA,eAAe,MAAiD;AAC9D,WAAO,KAAK,UAAU,eAAe,IAAI;AAAA,EAC3C;AACF;AASO,IAAM,iBAAN,MAA2C;AAAA,EAC/B;AAAA,EAEjB,YAAY,OAAO,2CAA2C;AAC5D,SAAK,OAAO;AAAA,EACd;AAAA,EAEA,MAAM,gBAAgB,OAA4C;AAChE,UAAM,IAAI,MAAM,GAAG,KAAK,IAAI,oCAAoC;AAAA,EAClE;AAAA,EAEA,MAAM,cAAc,WAAqD;AACvE,UAAM,IAAI,MAAM,GAAG,KAAK,IAAI,kCAAkC;AAAA,EAChE;AAAA,EAEA,MAAM,YACJ,UACA,WACyB;AACzB,UAAM,IAAI,MAAM,GAAG,KAAK,IAAI,gCAAgC;AAAA,EAC9D;AAAA,EAEA,MAAM,eAAe,OAAkD;AACrE,UAAM,IAAI,MAAM,GAAG,KAAK,IAAI,mCAAmC;AAAA,EACjE;AACF;;;AC9FO,SAAS,kBAAqB,MAAgD;AACnF,MAAI,KAAK,OAAO,EAAG,OAAM,IAAI,MAAM,uCAAuC,KAAK,IAAI,GAAG;AAEtF,QAAM,QAAwB,CAAC;AAC/B,QAAM,UAA4C,CAAC;AACnD,QAAM,QAAQ,IAAI,MAAM;AACxB,MAAI,aAAa;AACjB,MAAI,iBAAiB;AACrB,MAAI,SAAS;AACb,QAAM,YAAY,KAAK,IAAI;AAQ3B,iBAAe,cAAqC;AAClD,QAAI;AACJ,UAAM,QAAQ,MAAM,MAAM,aAAa,YAAY;AACjD,YAAM,OAAO,MAAM,KAAK,CAAC,MAAM,CAAC,EAAE,IAAI;AACtC,UAAI,MAAM;AACR,aAAK,OAAO;AACZ,eAAO;AAAA,MACT;AACA,UAAI,MAAM,SAAS,KAAK,MAAM;AAG5B,iBAAS,QAAQ,YAAY;AAC7B,eAAO;AAAA,MACT;AACA,aAAO;AAAA,IACT,CAAC;AACD,QAAI,MAAO,QAAO;AAClB,QAAI,WAAW,QAAW;AACxB,YAAM,WAAW,MAAM,KAAK,QAAQ,OAAO,MAAM;AACjD,YAAM,QAAsB;AAAA,QAC1B,MAAM,EAAE,IAAI,QAAQ,SAAS;AAAA,QAC7B,MAAM;AAAA,MACR;AACA,YAAM,MAAM,aAAa,MAAM;AAC7B,cAAM,KAAK,KAAK;AAAA,MAClB,CAAC;AACD,aAAO;AAAA,IACT;AAEA,WAAO,IAAI,QAAsB,CAAC,YAAY;AAC5C,cAAQ,KAAK,CAAC,MAAM;AAClB,UAAE,OAAO;AACT,gBAAQ,CAAC;AAAA,MACX,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAEA,WAAS,YAAY,OAA2B;AAI9C,UAAM,YAAY;AAChB,UAAI;AACF,YAAI,KAAK,QAAQ,MAAO,OAAM,KAAK,QAAQ,MAAM,MAAM,IAAI;AAAA,MAC7D,SAAS,KAAK;AAIZ,gBAAQ,KAAK,wCAAwC,MAAM,KAAK,EAAE,KAAK,GAAG;AAAA,MAC5E;AACA,YAAM,OAAO;AACb,YAAM,OAAO,QAAQ,MAAM;AAC3B,UAAI,KAAM,MAAK,KAAK;AAAA,IACtB,GAAG;AAAA,EACL;AAEA,iBAAe,WAAgE;AAC7E,UAAM,QAAQ,MAAM,YAAY;AAChC,UAAM,gBAAgB,KAAK,IAAI;AAC/B;AACA,WAAO;AAAA,MACL,MAAM,MAAM;AAAA,MACZ,SAAS,MAAM;AACb,kBAAU,KAAK,IAAI,IAAI;AACvB,oBAAY,KAAK;AAAA,MACnB;AAAA,IACF;AAAA,EACF;AAEA,iBAAe,SAAY,IAAmD;AAC5E,UAAM,EAAE,MAAM,QAAQ,IAAI,MAAM,SAAS;AACzC,QAAI;AACF,aAAO,MAAM,GAAG,IAAI;AAAA,IACtB,UAAE;AACA,cAAQ;AAAA,IACV;AAAA,EACF;AAEA,iBAAe,QAAuB;AAGpC,UAAM,WAAW,MAAM,MAAM,aAAa,MAAM;AAC9C,YAAM,QAAQ,MAAM,OAAO,GAAG,MAAM,MAAM;AAE1C,iBAAW,KAAK,QAAQ,OAAO,GAAG,QAAQ,MAAM,GAAG;AAKjD,aAAK;AAAA,MACP;AACA,aAAO;AAAA,IACT,CAAC;AACD,UAAM,QAAQ,WAAW,SAAS,IAAI,CAAC,MAAM,KAAK,QAAQ,QAAQ,EAAE,IAAI,CAAC,CAAC;AAAA,EAC5E;AAEA,WAAS,cAAc;AACrB,WAAO;AAAA,MACL;AAAA,MACA,SAAS,KAAK,IAAI,IAAI;AAAA,MACtB,WAAW;AAAA,IACb;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,UAAU,MAAM,MAAM;AAAA,IACtB,iBAAiB,MAAM,MAAM,OAAO,CAAC,MAAM,EAAE,IAAI,EAAE;AAAA,IACnD;AAAA,EACF;AACF;;;AC/KO,SAAS,iBAAiB,MAAgD;AAC/E,QAAM,SAA2B;AAAA,IAC/B,GAAG,MAAM;AAAA,IACT,oBAAoB;AAAA,MAClB,GAAI,MAAM,eAAe,EAAE,iBAAiB,KAAK,aAAa,IAAI,CAAC;AAAA,MACnE,GAAI,MAAM,aAAa,EAAE,eAAe,KAAK,WAAW,IAAI,CAAC;AAAA,MAC7D,GAAG,MAAM,YAAY;AAAA,IACvB;AAAA,EACF;AAEA,QAAM,WAAW,mBAAmB,MAAM;AAE1C,SAAO;AAAA,IACL;AAAA,IACA,MAAM,WAAW;AACf,UAAI,SAAU,OAAM,SAAS,SAAS;AAAA,IACxC;AAAA,EACF;AACF;AAKO,SAAS,mBAA4B;AAC1C,SAAO,CAAC,EAAE,OAAO,YAAY,eAAe,QAAQ,IAAI;AAC1D;;;ACvBA,eAAsB,oBACpB,OACA,SACA,WAC8B;AAC9B,QAAM,aAAa,MAAM,UAAU,QAAQ,KAAK;AAAA,IAC9C,MAAM;AAAA,IACN,MAAM;AAAA,IACN,cAAc,UAAU;AAAA,IACxB,YAAY;AAAA,MACV,2BAA2B,MAAM,SAAS;AAAA,MAC1C,qBAAqB,QAAQ,YAAY;AAAA,MACzC,qBAAqB,QAAQ,YAAY;AAAA,MACzC,cAAc;AAAA,IAChB;AAAA,EACF,CAAC;AAGD,QAAM,iBAAiB,QAAQ;AAC/B,QAAM,cAAwB,CAAC;AAE/B,QAAM,iBAAuC;AAAA,IAC3C,GAAG;AAAA,IACH,QAAQ,OAAO,SAAoC;AACjD,YAAM,WAAW,MAAM,UAAU,QAAQ,KAAK;AAAA,QAC5C,MAAM;AAAA,QACN,MAAM,gBAAgB,KAAK,IAAI;AAAA,QAC/B,cAAc,WAAW,KAAK;AAAA,QAC9B,YAAY;AAAA,UACV,gBAAgB,KAAK;AAAA,UACrB,oBAAoB,KAAK;AAAA,UACzB,uBAAuB,KAAK,KAAK;AAAA,UACjC,yBAAyB,KAAK,OAAO;AAAA,UACrC,cAAc;AAAA,QAChB;AAAA,MACF,CAAC;AACD,kBAAY,KAAK,SAAS,KAAK,MAAM;AACrC,UAAI,KAAK,SAAS;AAChB,cAAM,SAAS,KAAK,wBAAwB;AAAA,MAC9C,OAAO;AACL,cAAM,SAAS,IAAI;AAAA,MACrB;AACA,UAAI,eAAgB,OAAM,eAAe,IAAI;AAAA,IAC/C;AAAA,EACF;AAEA,MAAI;AACF,UAAM,SAAS,MAAM,cAAc,OAAO,cAAc;AACxD,UAAM,WAAW,IAAI;AAAA,MACnB,YAAY;AAAA,QACV,2BAA2B,MAAM,SAAS;AAAA,QAC1C,sBAAsB,OAAO;AAAA,QAC7B,yBAAyB,OAAO,SAAS;AAAA,QACzC,yBAAyB,OAAO,OAAO;AAAA,QACvC,cAAc;AAAA,MAChB;AAAA,IACF,CAA4B;AAC5B,WAAO;AAAA,EACT,SAAS,KAAK;AACZ,UAAM,WAAW,KAAK,eAAe,QAAQ,MAAM,OAAO,GAAG,CAAC;AAC9D,UAAM;AAAA,EACR;AACF;;;ACxEO,SAAS,WAAW,OAAgB,WAAmB,MAAmC;AAC/F,SAAO,OAAO,IAAY,UAA6C;AACrE,UAAM,OAAO,MAAM,KAAK,QAAQ,KAAK;AAAA,MACnC,MAAM;AAAA,MACN,MAAM,SAAS,SAAS;AAAA,MACxB,cAAc,KAAK;AAAA,MACnB,YAAY;AAAA,QACV,cAAc;AAAA,QACd,cAAc;AAAA,MAChB;AAAA,IACF,CAAC;AACD,QAAI;AACF,YAAMC,UAAS,MAAM,MAAM,IAAI,KAAK;AACpC,YAAM,YACJA,QAAO,SAAS,IAAIA,QAAO,OAAO,CAACC,MAAK,MAAMA,OAAM,EAAE,OAAO,CAAC,IAAID,QAAO,SAAS;AACpF,YAAM,KAAK,IAAI;AAAA,QACb,YAAY;AAAA,UACV,cAAc;AAAA,UACd,yBAAyB;AAAA,UACzB,yBAAyBA,QAAO;AAAA,UAChC,cAAc;AAAA,QAChB;AAAA,MACF,CAA4B;AAC5B,aAAOA;AAAA,IACT,SAAS,KAAK;AACZ,YAAM,KAAK,KAAK,eAAe,QAAQ,MAAM,OAAO,GAAG,CAAC;AACxD,YAAM;AAAA,IACR;AAAA,EACF;AACF;AAOO,SAAS,mBACd,QACA,YACA,MACS;AACT,SAAO,OAAO,IAAY,UAAsB;AAC9C,UAAM,eAAe,MAAM,KAAK,QAAQ,KAAK;AAAA,MAC3C,MAAM;AAAA,MACN,MAAM;AAAA,MACN,cAAc,KAAK;AAAA,MACnB,YAAY;AAAA,QACV,uBAAuB,OAAO;AAAA,QAC9B,cAAc;AAAA,MAChB;AAAA,IACF,CAAC;AACD,QAAI;AACF,YAAM,YAA0B,CAAC;AACjC,eAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;AACtC,cAAM,QAAQ,OAAO,CAAC;AACtB,cAAM,OAAO,WAAW,CAAC,KAAK,SAAS,CAAC;AACxC,cAAM,WAAW,WAAW,OAAO,MAAM;AAAA,UACvC,SAAS,KAAK;AAAA,UACd,cAAc,aAAa,KAAK;AAAA,QAClC,CAAC;AACD,cAAMA,UAAS,MAAM,SAAS,IAAI,KAAK;AACvC,kBAAU,KAAK,GAAGA,OAAM;AAAA,MAC1B;AACA,YAAM,YACJ,UAAU,SAAS,IAAI,UAAU,OAAO,CAACC,MAAK,MAAMA,OAAM,EAAE,OAAO,CAAC,IAAI,UAAU,SAAS;AAC7F,YAAM,aAAa,IAAI;AAAA,QACrB,YAAY;AAAA,UACV,uBAAuB,OAAO;AAAA,UAC9B,yBAAyB;AAAA,UACzB,0BAA0B,UAAU;AAAA,UACpC,cAAc;AAAA,QAChB;AAAA,MACF,CAA4B;AAC5B,aAAO;AAAA,IACT,SAAS,KAAK;AACZ,YAAM,aAAa,KAAK,eAAe,QAAQ,MAAM,OAAO,GAAG,CAAC;AAChE,YAAM;AAAA,IACR;AAAA,EACF;AACF;","names":["llmSpans","toolSpans","judgeSpans","sum","finding","scores","z","z","existsSync","existsSync","ACTOR_PROMPT","ACTOR_PROMPT","ACTOR_PROMPT","existsSync","readFileSync","existsSync","readFileSync","sum","own","dirname","join","check","scores","join","canonicalize","sum","agent","check","precision","aggregate","scores","ratio","fs","runScore","mean","sum","scores","sum","existsSync","readdirSync","readFileSync","statSync","join","appendFileSync","existsSync","mkdirSync","readFileSync","dirname","scores","mkdirSync","dirname","appendFileSync","existsSync","readFileSync","fmt","mean","passed","margin","scores","scores","mean","scores","ratio","worst","join","i","j","pa","scores","mean","runs","groupBy","scores","existsSync","readdirSync","readFileSync","statSync","join","tail","sum","DEFAULT_MODEL","DEFAULT_TIMEOUT","DEFAULT_MAX_SOURCE","DEFAULT_MAX_PER_FILE","DEFAULT_MAX_HTML","truncate","buildPrompt","appendFileSync","existsSync","mkdirSync","readFileSync","dirname","scoreOptions","mkdirSync","dirname","appendFileSync","existsSync","scores","mean","clamp01","sum","precision","tokens","readFileSync","softFail","join","defaultExtract","mean","mean","precision","scores","sum"]}