@tangle-network/agent-eval 0.107.0 → 0.108.1

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.
Files changed (43) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/README.md +2 -2
  3. package/dist/adapters/http.d.ts +1 -1
  4. package/dist/adapters/langchain.d.ts +1 -1
  5. package/dist/adapters/otel.d.ts +1 -1
  6. package/dist/benchmarks/index.d.ts +3 -1
  7. package/dist/benchmarks/index.js +49 -3
  8. package/dist/campaign/index.d.ts +10 -7
  9. package/dist/campaign/index.js +72 -3407
  10. package/dist/campaign/index.js.map +1 -1
  11. package/dist/chunk-6SKVFBTR.js +4306 -0
  12. package/dist/chunk-6SKVFBTR.js.map +1 -0
  13. package/dist/{chunk-G4DLZAV5.js → chunk-OVPVM4JC.js} +1044 -643
  14. package/dist/chunk-OVPVM4JC.js.map +1 -0
  15. package/dist/chunk-T6W5ADLG.js +766 -0
  16. package/dist/chunk-T6W5ADLG.js.map +1 -0
  17. package/dist/contract/index.d.ts +16 -6
  18. package/dist/contract/index.js +10 -11
  19. package/dist/contract/index.js.map +1 -1
  20. package/dist/{gepa-BmqTrdtg.d.ts → gepa-B3x5Ulcv.d.ts} +3 -40
  21. package/dist/hosted/index.d.ts +1 -1
  22. package/dist/index-pPtfoIJO.d.ts +423 -0
  23. package/dist/index.d.ts +6 -5
  24. package/dist/index.js +8 -7
  25. package/dist/index.js.map +1 -1
  26. package/dist/multishot/index.d.ts +1 -1
  27. package/dist/openapi.json +1 -1
  28. package/dist/{pre-registration-x3f0VpxT.d.ts → pre-registration-BUhVPzE7.d.ts} +1 -1
  29. package/dist/{provenance-CIjRcI6m.d.ts → provenance-DdDhf6cg.d.ts} +3 -2
  30. package/dist/rl.d.ts +1 -1
  31. package/dist/rl.js +6 -6
  32. package/dist/storage-Dw_f7WMt.d.ts +39 -0
  33. package/dist/{types-CNZ0tHET.d.ts → types-BdIv5dvA.d.ts} +1 -1
  34. package/docs/improvement-glossary.md +5 -1
  35. package/package.json +1 -1
  36. package/dist/chunk-6PF6LXRY.js +0 -861
  37. package/dist/chunk-6PF6LXRY.js.map +0 -1
  38. package/dist/chunk-6QDKWHLS.js +0 -223
  39. package/dist/chunk-6QDKWHLS.js.map +0 -1
  40. package/dist/chunk-G4DLZAV5.js.map +0 -1
  41. package/dist/chunk-V75NN2ZR.js +0 -421
  42. package/dist/chunk-V75NN2ZR.js.map +0 -1
  43. package/dist/index-C2CC_dry.d.ts +0 -159
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/auto-pr.ts","../src/executor.ts","../src/benchmark.ts","../src/capability-headroom.ts","../src/client.ts","../src/convergence.ts","../src/driver.ts","../src/feedback-trajectory.ts","../src/integrity/preflight.ts","../src/integrity/single-backend.ts","../src/judge-families.ts","../src/live-proof.ts","../src/paired-arms.ts","../src/pr-review-benchmark.ts","../src/registry.ts","../src/reporter.ts","../src/treatment-gate.ts","../src/anti-slop.ts","../src/artifact-validator.ts","../src/dual-agent-bench.ts","../src/eval-tools.ts","../src/harness-optimizer.ts","../src/judge-ensemble.ts","../src/judge-retry.ts","../src/judge-panel.ts","../src/judge-runner.ts","../src/playbook.ts","../src/prompt-registry.ts","../src/steering.ts","../src/steering-optimizer.ts","../src/workspace-inspector.ts","../src/budget-guard.ts","../src/hidden-criteria-grading.ts","../src/cost-ledger.ts","../src/cost-tracker.ts","../src/eval-trace-store.ts","../src/experiment-tracker.ts","../src/leaderboard.ts","../src/muffled-gate-scanner.ts","../src/oracle.ts","../src/partition-held-out.ts","../src/scorecard.ts","../src/slo.ts","../src/state-continuity.ts","../src/ui-finding.ts","../src/trace-contracts.ts","../src/behavior-dsl.ts","../src/ci-gate.ts","../src/observability.ts","../src/paraphrase.ts","../src/visual-diff.ts","../src/bisector.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/description-length-gate.ts","../src/discover-personas.ts","../src/golden-matcher.ts","../src/held-out-gate.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","../src/campaign/distillation/agreement-judge.ts","../src/campaign/distillation/gold-scenarios.ts","../src/campaign/distillation/run-distillation.ts","../src/profile/index.ts","../src/profile/baselines.ts","../src/cost-report.ts","../src/model-seats.ts","../src/attestation.ts"],"sourcesContent":["/**\n * Automated pull-request transports for the production loop.\n *\n * A consumer's `runProductionLoop` ships a promoted surface diff as a\n * reviewable code change by handing one of these clients to its\n * `ProductionShipConfig.client`. Each `AutoPrClient.proposeChange`:\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 * (The campaign-loop `autoOnPromote: 'pr'` path uses `openAutoPr` in\n * `src/campaign/auto-pr.ts`, a self-contained `gh pr create` shell-out.)\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\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\n/**\n * Validate a proposed change before any transport touches the network. Each\n * `AutoPrClient.proposeChange` runs this at its boundary so a malformed input\n * (path traversal, duplicate path, branch == base, empty title) fails loud\n * locally instead of producing a broken commit on the remote.\n */\nfunction validateProposeInput(input: ProposeAutomatedPullRequestInput): void {\n if (!input.repo.owner.trim() || !input.repo.name.trim()) {\n throw new ValidationError('proposeChange: repo.owner and repo.name required')\n }\n if (!input.branchName.trim() || /\\s/.test(input.branchName)) {\n throw new ValidationError(\n 'proposeChange: branchName must be non-empty and contain no whitespace',\n )\n }\n if (input.branchName === (input.baseBranch ?? 'main')) {\n throw new ValidationError('proposeChange: branchName must differ from baseBranch')\n }\n if (input.fileChanges.length === 0) {\n throw new ValidationError('proposeChange: 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 `proposeChange: invalid file path \"${change.path}\" (no '..' or leading '/')`,\n )\n }\n if (seenPaths.has(change.path)) {\n throw new ValidationError(`proposeChange: duplicate file path \"${change.path}\"`)\n }\n seenPaths.add(change.path)\n }\n if (!input.title.trim()) {\n throw new ValidationError('proposeChange: 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 `proposeChange: 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 validateProposeInput(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(`proposeChange: 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(`proposeChange: base commit ${baseSha} not found (race condition?)`)\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('proposeChange: 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('proposeChange: 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) throw new ConfigError('proposeChange: 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) throw new ConfigError('proposeChange: 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 `proposeChange: ${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 validateProposeInput(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 { CaptureIntegrityError } from './errors'\nimport { JudgeParseError } from './judges'\nimport { isTransientLlmError } from './llm-client'\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 * Sleep used between judge retries and after a judge succeeds. Defaults to\n * real `setTimeout`. Injectable so tests exercise the retry policy without\n * the real multi-second backoff.\n */\n sleep?: (ms: number) => Promise<void>\n}\n\nfunction describeShape(content: unknown, message: unknown): string {\n if (message === undefined || message === null) return 'no choices[0].message'\n return `message.content of type ${content === null ? 'null' : typeof content}`\n}\n\nfunction errMessage(err: unknown): string {\n if (err instanceof Error) return `${err.name}: ${err.message}`\n return String(err)\n}\n\n/** Per-judge failure diagnostic, recorded additively on `ScenarioResult`. */\nexport interface JudgeFailure {\n judge: string\n attempts: number\n reason: string\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 message = (resp as { choices?: { message?: { content?: unknown } }[] }).choices?.[0]\n ?.message\n const rawContent = message?.content\n // A legitimately-empty turn ('' from a model that chose to say nothing) is\n // real signal and must survive. A missing choices[0].message, or a content\n // that is not a string, is a capture defect — the chat call hung or returned\n // a malformed shape — and is indistinguishable from a real empty turn once\n // collapsed to ''. Fail loud so it is never scored as a real response.\n if (message === undefined || message === null || typeof rawContent !== 'string') {\n throw new CaptureIntegrityError(\n `chat response for scenario \"${scenario.id}\" turn ${i} is malformed: ` +\n `expected choices[0].message.content to be a string, got ${describeShape(rawContent, message)}`,\n )\n }\n const content = rawContent\n\n messages.push({ role: 'assistant', content })\n\n // Extract code blocks\n const codeRe = /```(\\w+)?\\n([\\s\\S]*?)```/g\n let codeMatch: RegExpExecArray | null = codeRe.exec(content)\n while (codeMatch !== null) {\n allCodeBlocks.push({ language: codeMatch[1] ?? 'text', code: codeMatch[2] ?? '' })\n codeMatch = codeRe.exec(content)\n }\n\n // Extract structured blocks\n const turnBlocks: { type: string; title: string }[] = []\n const blockReLocal = new RegExp(blockRe.source, blockRe.flags)\n let blockMatch: RegExpExecArray | null = blockReLocal.exec(content)\n while (blockMatch !== 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 blockMatch = blockReLocal.exec(content)\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: RegExpExecArray | null = re.exec(content)\n while (toolMatch !== null) {\n allToolCalls.push(toolMatch[0])\n hasToolCall = true\n toolMatch = re.exec(content)\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. A judge that fails — unparseable\n // output (JudgeParseError, non-retryable) or errors across every attempt —\n // is COUNTED as a failed judge, never folded into the scores as a fake\n // zero row: a synthetic zero is indistinguishable from a real low score.\n const judgeInput = { scenario, turns, artifacts }\n const judgeResults: JudgeScore[][] = []\n let failedJudges = 0\n const judgeFailures: JudgeFailure[] = []\n const sleep = config.sleep ?? ((ms: number) => new Promise<void>((r) => setTimeout(r, ms)))\n\n for (let j = 0; j < config.judges.length; j++) {\n const judge = config.judges[j]!\n const judgeName = judge.name || `judge[${j}]`\n let lastError: unknown\n let madeAttempts = 0\n for (let attempt = 0; attempt < 3; attempt++) {\n madeAttempts = attempt + 1\n try {\n if (attempt > 0) {\n const wait = attempt * 10_000\n console.log(` ${judgeName} retry ${attempt}/2 (waiting ${wait / 1000}s)`)\n await sleep(wait)\n }\n const scores = await judge(tc, judgeInput)\n judgeResults.push(scores)\n await sleep(3000)\n lastError = undefined\n break\n } catch (err) {\n lastError = err\n if (err instanceof JudgeParseError) {\n // The model answered but unparseably — another identical prompt\n // won't fix it. Record the failure and move to the next judge.\n console.error(` ${judgeName} unparseable (no retry): ${errMessage(err)}`)\n break\n }\n console.error(` ${judgeName} attempt ${attempt} failed: ${errMessage(err)}`)\n // Deterministic errors (bad rubric, auth, 4xx) won't change on retry —\n // only retry connection/rate-limit class faults. Stop the loop now so a\n // permanent error is not masked by two pointless waits.\n if (!isTransientLlmError(err)) break\n }\n }\n if (lastError !== undefined) {\n failedJudges++\n judgeFailures.push({\n judge: judgeName,\n attempts: madeAttempts,\n reason: errMessage(lastError),\n })\n }\n }\n\n const allScores = judgeResults.flat()\n // Defensive: custom JudgeFns may still emit error-shaped rows.\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 // judgeFailures is additive diagnostic context (WHY each judge errored),\n // recorded alongside the existing judgeErrors count without widening the\n // shared ScenarioResult contract. Absent when every judge succeeded.\n const result: ScenarioResult & { judgeFailures?: JudgeFailure[] } = {\n scenarioId: scenario.id,\n persona: scenario.persona,\n turns,\n artifactResults,\n judgeScores: allScores,\n judgeErrors: errorScores.length + failedJudges,\n overallScore,\n totalDurationMs: Date.now() - startTime,\n artifacts,\n }\n if (judgeFailures.length > 0) result.judgeFailures = judgeFailures\n return result\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","/**\n * Capability-headroom gate — \"can this task set even SEE the capability\n * you're about to A/B?\"\n *\n * A capability A/B (grant one arm a tool, a skill, extra context — anything)\n * can only detect the capability on tasks the capability-ABSENT baseline\n * FAILS. A task the baseline already passes is saturated: the treatment arm\n * has no headroom to demonstrate anything, and averaging saturated tasks into\n * the comparison dilutes a real effect toward a false null. Calibrate before\n * measuring: run the baseline arm first, classify every task's headroom, and\n * refuse to run the comparison when no task has a gap.\n *\n * Fail-closed on unknown outcomes: a baseline run whose outcome could not be\n * determined (infra loss, unverified, missing) NEVER counts as a failure —\n * treating \"couldn't tell\" as \"failed\" would manufacture headroom out of\n * telemetry gaps and launder infra noise into a treatment effect.\n *\n * Domain-free by construction: the capability under test never appears here.\n * Callers decide what the baseline arm lacks; this module only classifies\n * baseline outcomes per task.\n */\n\nimport { ValidationError } from './errors'\n\n/** One baseline-arm (capability-absent) observation of one task. */\nexport interface HeadroomInput {\n /** Stable task identity; multiple rows per task are multiple baseline reps. */\n taskId: string\n /** Baseline outcome. 'unknown' = the outcome could not be determined —\n * distinct from 'fail' and never counted as one. */\n baselineOutcome: 'pass' | 'fail' | 'unknown'\n}\n\n/** Headroom classification for one task.\n * - 'gap': the baseline fails it — the comparison can see the capability here.\n * - 'saturated': the baseline already passes it — no headroom.\n * - 'unknown': every baseline outcome is unknown — fail-closed, not a gap. */\nexport type HeadroomClass = 'gap' | 'saturated' | 'unknown'\n\nexport interface TaskHeadroom {\n taskId: string\n /** Total baseline observations for this task (known + unknown). */\n n: number\n /** Observations with a known ('pass' | 'fail') outcome — the evidence the\n * classification actually rests on. A large `n` with a small `nKnown`\n * means the headroom verdict is thin, not well-replicated. */\n nKnown: number\n /** Pass rate over KNOWN outcomes only; NaN when every outcome is unknown\n * (no data ≠ measured zero). */\n baselinePassRate: number\n headroom: HeadroomClass\n}\n\nexport interface CapabilityHeadroomOptions {\n /** A task counts as 'gap' when its baseline pass rate is ≤ this. Default 0\n * (the baseline must fail every known rep). Must be in [0, 1) — a\n * threshold of 1 would classify a fully-saturated task as a gap. */\n keepThreshold?: number\n}\n\nexport interface CapabilityHeadroomResult {\n /** Per-task classification, sorted by `taskId`. */\n tasks: TaskHeadroom[]\n summary: {\n tasksWithGap: number\n tasksSaturated: number\n tasksUnknown: number\n /** Total unknown-outcome reps across ALL tasks (including tasks that\n * still classified via their known reps) — the size of the telemetry\n * hole behind the classifications. */\n repsUnknown: number\n }\n}\n\n/**\n * Classify every task's baseline headroom from capability-absent baseline\n * outcomes.\n *\n * A task is 'gap' when it has ≥ 1 known outcome and its pass rate over known\n * outcomes is ≤ `keepThreshold`; 'saturated' when the rate exceeds the\n * threshold; 'unknown' when every outcome is unknown. Unknown reps never\n * count toward the rate in either direction (fail-closed — see the module\n * doc), and evidence strength stays visible: each task reports `nKnown`\n * alongside `n`, and the summary totals the unknown reps in `repsUnknown`.\n * Throws on empty input, an out-of-range `keepThreshold`, or an\n * unrecognized outcome value (rows are often projected from untyped records).\n */\nexport function capabilityHeadroom(\n rows: readonly HeadroomInput[],\n opts: CapabilityHeadroomOptions = {},\n): CapabilityHeadroomResult {\n const keepThreshold = opts.keepThreshold ?? 0\n if (!Number.isFinite(keepThreshold) || keepThreshold < 0 || keepThreshold >= 1) {\n throw new ValidationError(\n `capabilityHeadroom: keepThreshold must be in [0, 1), got ${keepThreshold}`,\n )\n }\n if (rows.length === 0) {\n throw new ValidationError(\n 'capabilityHeadroom: no baseline rows supplied — run the capability-absent baseline arm first',\n )\n }\n\n // taskId → { n, passes, known }\n const byTask = new Map<string, { n: number; passes: number; known: number }>()\n for (const row of rows) {\n if (\n row.baselineOutcome !== 'pass' &&\n row.baselineOutcome !== 'fail' &&\n row.baselineOutcome !== 'unknown'\n ) {\n throw new ValidationError(\n `capabilityHeadroom: unrecognized baselineOutcome '${row.baselineOutcome}' for task '${row.taskId}' (expected 'pass' | 'fail' | 'unknown')`,\n )\n }\n const agg = byTask.get(row.taskId) ?? { n: 0, passes: 0, known: 0 }\n agg.n++\n if (row.baselineOutcome !== 'unknown') {\n agg.known++\n if (row.baselineOutcome === 'pass') agg.passes++\n }\n byTask.set(row.taskId, agg)\n }\n\n const tasks: TaskHeadroom[] = [...byTask.entries()]\n .sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0))\n .map(([taskId, agg]) => {\n if (agg.known === 0) {\n return {\n taskId,\n n: agg.n,\n nKnown: 0,\n baselinePassRate: Number.NaN,\n headroom: 'unknown' as const,\n }\n }\n const baselinePassRate = agg.passes / agg.known\n return {\n taskId,\n n: agg.n,\n nKnown: agg.known,\n baselinePassRate,\n headroom: baselinePassRate <= keepThreshold ? ('gap' as const) : ('saturated' as const),\n }\n })\n\n const summary = {\n tasksWithGap: tasks.filter((t) => t.headroom === 'gap').length,\n tasksSaturated: tasks.filter((t) => t.headroom === 'saturated').length,\n tasksUnknown: tasks.filter((t) => t.headroom === 'unknown').length,\n repsUnknown: tasks.reduce((sum, t) => sum + (t.n - t.nKnown), 0),\n }\n return { tasks, summary }\n}\n\nexport interface AssertCapabilityHeadroomOptions {\n /** Minimum tasks classified 'gap' for the comparison to proceed. Default 1. */\n minTasksWithGap?: number\n}\n\n/**\n * The go/no-go guard: throws when fewer than `minTasksWithGap` tasks have\n * baseline headroom — i.e. the benchmark cannot see the capability, so any\n * comparison run on it would measure noise. Call between the baseline\n * calibration run and the treatment run.\n */\nexport function assertCapabilityHeadroom(\n result: CapabilityHeadroomResult,\n opts: AssertCapabilityHeadroomOptions = {},\n): void {\n const minTasksWithGap = opts.minTasksWithGap ?? 1\n if (!Number.isInteger(minTasksWithGap) || minTasksWithGap < 1) {\n throw new ValidationError(\n `assertCapabilityHeadroom: minTasksWithGap must be an integer ≥ 1, got ${minTasksWithGap}`,\n )\n }\n const { tasksWithGap, tasksSaturated, tasksUnknown } = result.summary\n if (tasksWithGap < minTasksWithGap) {\n const total = result.tasks.length\n throw new ValidationError(\n `assertCapabilityHeadroom: only ${tasksWithGap} of ${total} task(s) have baseline headroom ` +\n `(need ≥ ${minTasksWithGap}). ${tasksSaturated} saturated (baseline already passes), ` +\n `${tasksUnknown} unknown (no determinable baseline outcome). A capability A/B on this ` +\n `task set cannot detect the capability — add tasks the baseline fails, or fix baseline ` +\n `outcome capture, before measuring.`,\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 */\nconst DEFAULT_REQUEST_TIMEOUT_MS = 30_000\n\nexport class ProductClient {\n private baseUrl: string\n private routes: RouteMap\n private cookies: string = ''\n private timeoutMs: number\n\n constructor(config: ProductClientConfig) {\n this.baseUrl = config.baseUrl.replace(/\\/+$/, '')\n this.routes = config.routes\n this.timeoutMs = config.timeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS\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 /**\n * Single HTTP boundary for every JSON request. Aborts after `timeoutMs`,\n * checks `res.ok` BEFORE parsing, and throws `${method} ${path} failed:\n * HTTP ${status} — ${body}` on a non-ok response so a 4xx/5xx error body\n * can never be parsed as a success shape. Callers inspect the resolved\n * value only after a successful return.\n */\n private async request(\n method: string,\n path: string,\n body?: Record<string, unknown>,\n ): Promise<Record<string, unknown>> {\n const controller = new AbortController()\n const timeout = setTimeout(() => controller.abort(), this.timeoutMs)\n let res: Response\n try {\n res = await fetch(`${this.baseUrl}${path}`, {\n method,\n headers: {\n ...(body ? { 'Content-Type': 'application/json' } : {}),\n Origin: this.baseUrl,\n Cookie: this.cookies,\n },\n ...(body ? { body: JSON.stringify(body) } : {}),\n signal: controller.signal,\n })\n } finally {\n clearTimeout(timeout)\n }\n if (!res.ok) {\n const text = await res.text().catch(() => '')\n throw new Error(`${method} ${path} failed: HTTP ${res.status} — ${text.slice(0, 500)}`)\n }\n return res.json() as Promise<Record<string, unknown>>\n }\n\n /**\n * Read a required collection field. A missing/non-array field is a contract\n * violation (wrong route, drift, partial body) — surface it loud instead of\n * masking it as a healthy empty set. A genuinely empty `[]` passes through.\n */\n private requireArray<T>(res: Record<string, unknown>, field: string): T[] {\n const value = res[field]\n if (!Array.isArray(value)) {\n throw new Error(\n `Response missing array field \"${field}\" (got ${typeof value}: ${JSON.stringify(value)?.slice(0, 200)})`,\n )\n }\n return value as T[]\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: RegExpExecArray | null = blockRe.exec(text)\n while (match !== 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 match = blockRe.exec(text)\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 this.requireArray<{ id: string; title: string; status: string; priority: string }>(\n res,\n 'tasks',\n )\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 this.requireArray<{ id: string; title: string; type: string }>(res, 'events')\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 this.requireArray<{ id: string; title: string; status: string; type: string }>(\n res,\n 'actions',\n )\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(this.requireArray<unknown>(res, 'tree'))\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 this.requireArray<{ id: string; type: string; prompt: string }>(res, 'generations')\n }\n\n /** Generic GET for custom routes */\n async get(path: string): Promise<Record<string, unknown>> {\n return this.request('GET', path)\n }\n\n /** Generic POST for custom routes */\n async post(path: string, body: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('POST', path, body)\n }\n\n /** Generic PATCH for custom routes */\n async patch(path: string, body: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('PATCH', path, body)\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 { 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 WorkerDriverContext {\n /** The goal (or sub-goal) the driven worker must actually accomplish. */\n goal: string\n /** The worker's harness — e.g. 'claude-code' | 'codex' | 'opencode' | 'router-tools'.\n * Names which capability profile the driver should exploit. */\n harness?: string\n /** A capability + caveat brief for THIS harness (parallel tool calls, sub-agents and\n * their depth/concurrency limits, autonomy/runaway profile, MCP, native tool-isolation)\n * — sourced from the harness-compat matrix. Free text so the substrate stays decoupled\n * from any runtime harness type. */\n harnessBrief?: string\n /** What the worker has done so far — the trace/state summary the driver reasons over to\n * write its next instruction. Empty on the first turn. */\n progress?: string\n /** Optional extra context (repo, constraints, the deliverable's acceptance check). */\n context?: string\n}\n\n/**\n * Build the WORKER-DRIVER system prompt — the harness-aware sibling of\n * `buildDriverSystemPrompt`. Where that one role-plays a demanding *user* of a\n * product, this one is a meta-agent that DRIVES a capable coding *worker* to\n * complete a goal: it writes rich, high-signal instructions that direct the\n * worker to exploit its harness's full power (parallelize, sub-agents, run-to-\n * completion, tools/MCP), matched to what THAT harness can actually do. The\n * load-bearing contract: the driver never writes a thin steer — every message\n * is the dense, specific directive a world-class engineering lead would write.\n * Pure function; exported so harness authors can inspect and regression-test it.\n */\nexport function buildWorkerDriverSystemPrompt(ctx: WorkerDriverContext): string {\n const harness = ctx.harness ?? 'a coding agent'\n const brief = ctx.harnessBrief\n ? `\\nThis worker's harness (${harness}) can:\\n${ctx.harnessBrief}\\nDrive it to USE these — and never ask for a capability it lacks.\\n`\n : `\\nThe worker runs in ${harness}. Drive it to exploit whatever its harness offers — parallel tool calls, sub-agents, run-to-completion — and never ask for a capability it lacks.\\n`\n const progress = ctx.progress\n ? `\\nWhat the worker has done so far:\\n${ctx.progress}\\n`\n : '\\nThe worker has not started yet — your first instruction sets the whole plan.\\n'\n const context = ctx.context ? `\\nContext:\\n${ctx.context}\\n` : ''\n\n return `You are a DRIVER: a meta-agent whose entire job is to drive a capable coding worker to ACHIEVE A GOAL by writing it precise, high-signal instructions. You do not do the work yourself — you direct the worker to do it, brilliantly, and you hold it to a standard it would not hold itself to.\n\nThe goal: ${ctx.goal}\n${context}${brief}${progress}\nTHE BAR — non-negotiable. Every instruction you write is dense, specific, and complete. You write the message a world-class engineering lead writes to a strong report: the exact next objective, the concrete sub-steps, what to do in parallel vs in sequence, what to verify and how, what \"done\" looks like, and the failure modes to avoid. A thin steer — \"try again\", \"fix the issues\", a single vague sentence — is a failure on YOUR part, not the worker's. Out-drive a human power-user.\n\nHOW to drive (each turn):\n1. Read what the worker actually did (its trace/state above), not what it claims. Find the real gap between here and the goal.\n2. Decide the next objective — the largest correct step the worker can take now.\n3. Decompose it: name the sub-tasks that can run IN PARALLEL (independent files/checks/searches) and tell the worker to fan them out (sub-agents / parallel tool calls where its harness allows); name what must run in SEQUENCE and why.\n4. Make it exploit the harness: drive it to run to completion under its own autonomy, spawn sub-agents for separable work, use its tools/MCP, and not stop at the first plausible stopping point.\n5. Specify verification: the exact command / test / check that proves the step landed, and tell it to run that and report the result — never accept \"done\" without the check.\n6. Name the traps: the specific failure modes for THIS step (editing the wrong file, a check that passes vacuously, scope creep) and forbid them.\n7. As the task gets harder, decompose MORE, not less — more parallel branches, deeper sub-agent trees, tighter verification.\n\nCOMPLETION: drive toward the goal's real acceptance check. Do not declare done — the deliverable's checker does. If the worker claims it is done, drive it to PROVE it with the check; if the check fails, drive the fix.\n\nOutput ONLY your next instruction to the worker — direct, detailed, actionable, in the first person as the driver. No meta-commentary, no preamble.`\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 * Backend preflight: verify the models a campaign is about to spend tokens\n * against are actually served by the router BEFORE the run starts. The PRE-hoc\n * complement to `assertRealBackend` (which inspects RunRecords AFTER the run to\n * catch a stub/unconfigured backend).\n *\n * Two checks, increasing in cost:\n * - membership (free): GET `{baseUrl}/models` once; a model is `listed` when\n * its id is in the served set.\n * - probe (spends a tiny number of tokens): POST `{baseUrl}/chat/completions`\n * per model with a 1-message, 5-token request; `served` is whether the\n * router returns 2xx, with the HTTP `status` and the body's `error.message`\n * captured in `detail`.\n *\n * A default model the router cannot serve is a config bug. Gate a campaign on\n * `assertModelsServed` and it surfaces every dead id with its status + detail\n * instead of silently producing a stub run.\n */\n\nimport { AgentEvalError, ConfigError } from '../errors'\n\nexport interface ModelPreflight {\n /** The model id as supplied by the caller. */\n model: string\n /** Membership in the `{baseUrl}/models` served set. */\n listed: boolean\n /** 2xx on a 1-token chat probe. `null` when `probe` was not requested. */\n served: boolean | null\n /** HTTP status of the probe. `null` when not probed. */\n status: number | null\n /** Probe body's `error.message` when present, else `null`. */\n detail: string | null\n}\n\nexport interface PreflightModelsOptions {\n /** Router base URL, e.g. `https://router.tangle.tools/v1`. Trailing slash tolerated. */\n baseUrl: string\n /** Bearer token sent as `Authorization: Bearer <apiKey>`. */\n apiKey: string\n /** Model ids to check. */\n models: string[]\n /** When true, additionally spend a 1-token chat probe per model. Default false. */\n probe?: boolean\n /** Injectable fetch for tests; defaults to the global. */\n fetchImpl?: typeof fetch\n}\n\nexport interface PreflightOutcome {\n succeeded: boolean\n value: ModelPreflight[] | null\n error: string | null\n}\n\ninterface ModelsListBody {\n data?: ReadonlyArray<{ id?: unknown }>\n}\n\ninterface ChatErrorBody {\n error?: { message?: unknown }\n message?: unknown\n}\n\nfunction stripSlash(url: string): string {\n return url.replace(/\\/+$/, '')\n}\n\n/** Extract `error.message` (then top-level `message`) from a chat-completions error body. */\nfunction errorMessage(body: unknown): string | null {\n if (body == null || typeof body !== 'object') return null\n const b = body as ChatErrorBody\n if (b.error && typeof b.error.message === 'string') return b.error.message\n if (typeof b.message === 'string') return b.message\n return null\n}\n\n/**\n * Check that `models` are reachable on the router. Returns a typed outcome —\n * a network failure yields `{ succeeded: false, error }`, never a throw and\n * never a partial result silently reported as success. No retries, no\n * fallbacks.\n *\n * The membership check (one GET) always runs. When `probe` is true, each model\n * additionally gets a 1-token chat probe so a model that is listed but\n * unconfigured (a 401 `model_not_found` from the router) is caught.\n */\nexport async function preflightModels(opts: PreflightModelsOptions): Promise<PreflightOutcome> {\n const fetchImpl = opts.fetchImpl ?? fetch\n const baseUrl = stripSlash(opts.baseUrl)\n const authHeaders = { authorization: `Bearer ${opts.apiKey}` }\n\n let served: Set<string>\n try {\n const res = await fetchImpl(`${baseUrl}/models`, { method: 'GET', headers: authHeaders })\n if (!res.ok) {\n const text = await res.text().catch(() => '')\n return {\n succeeded: false,\n value: null,\n error: `preflightModels: GET ${baseUrl}/models → ${res.status} ${text.slice(0, 400)}`,\n }\n }\n const body = (await res.json()) as ModelsListBody\n const ids = Array.isArray(body.data) ? body.data : []\n served = new Set(ids.map((m) => m.id).filter((id): id is string => typeof id === 'string'))\n } catch (err) {\n return {\n succeeded: false,\n value: null,\n error: `preflightModels: GET ${baseUrl}/models failed — ${err instanceof Error ? err.message : String(err)}`,\n }\n }\n\n const results: ModelPreflight[] = []\n for (const model of opts.models) {\n const listed = served.has(model)\n if (!opts.probe) {\n results.push({ model, listed, served: null, status: null, detail: null })\n continue\n }\n try {\n const res = await fetchImpl(`${baseUrl}/chat/completions`, {\n method: 'POST',\n headers: { ...authHeaders, 'content-type': 'application/json' },\n body: JSON.stringify({\n model,\n messages: [{ role: 'user', content: 'ping' }],\n max_tokens: 5,\n }),\n })\n let detail: string | null = null\n if (!res.ok) {\n const body = await res.json().catch(() => null)\n detail = errorMessage(body)\n }\n results.push({ model, listed, served: res.ok, status: res.status, detail })\n } catch (err) {\n return {\n succeeded: false,\n value: null,\n error: `preflightModels: probe POST ${baseUrl}/chat/completions (model ${model}) failed — ${err instanceof Error ? err.message : String(err)}`,\n }\n }\n }\n\n return { succeeded: true, value: results, error: null }\n}\n\nexport class ModelsUnreachableError extends AgentEvalError {\n constructor(\n message: string,\n public readonly results: ReadonlyArray<ModelPreflight>,\n ) {\n super('config', message)\n this.name = 'ModelsUnreachableError'\n }\n}\n\nfunction describeFailure(r: ModelPreflight): string {\n if (!r.listed) {\n const probeNote =\n r.served === false ? ` (probe ${r.status}${r.detail ? `: ${r.detail}` : ''})` : ''\n return `${r.model}: not in /models${probeNote}`\n }\n // listed but failed its probe\n return `${r.model}: listed but probe ${r.status}${r.detail ? ` — ${r.detail}` : ''}`\n}\n\n/**\n * Throw `ModelsUnreachableError` naming EVERY model that is unlisted or (when\n * probed) failed its probe — with status + detail per model. A model is dead\n * if it is unlisted, or if `served === false`. Callers gate a campaign on this\n * before spending tokens. When the network call itself fails the underlying\n * outcome error is rethrown — there is no partial silent pass.\n */\nexport async function assertModelsServed(opts: PreflightModelsOptions): Promise<ModelPreflight[]> {\n const outcome = await preflightModels(opts)\n if (!outcome.succeeded || outcome.value === null) {\n throw new ConfigError(\n outcome.error ?? 'assertModelsServed: preflight failed without an error message',\n )\n }\n const dead = outcome.value.filter((r) => !r.listed || r.served === false)\n if (dead.length > 0) {\n throw new ModelsUnreachableError(\n `assertModelsServed: ${dead.length}/${outcome.value.length} model(s) unreachable on the router — ${dead\n .map(describeFailure)\n .join('; ')}`,\n outcome.value,\n )\n }\n return outcome.value\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 {\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","/**\n * Matched-pair arm comparison — \"did the treatment arm beat the baseline arm\n * on the SAME work items?\"\n *\n * An arm A/B over run records is only trustworthy when it is PAIRED: the same\n * task/scenario/seed evaluated under both arms, compared item-by-item, so\n * inter-item difficulty variance cancels instead of masquerading as an arm\n * effect. This module owns the two error-prone steps every consumer otherwise\n * hand-rolls:\n *\n * 1. Pairing — matching rows across arms by `pairKey` (and by `repKey`\n * within multi-rep items), with leftovers REPORTED rather than silently\n * dropped (a silently unbalanced pairing biases every paired statistic\n * downstream). Pairing never keys on outcome content: matching reps by\n * their outcomes deflates discordant-pair counts and makes McNemar\n * anti-conservative, so reps pair only by (`pairKey`, `repKey`) identity.\n * 2. Composition — feeding the matched pairs to the correct paired\n * estimators that already live in `statistics`: `mcnemar` +\n * `pairedRiskDifference` for pass/fail, `pairedBootstrap` +\n * `wilcoxonSignedRank` for continuous metrics. No statistic is\n * re-implemented here.\n *\n * The row shape is deliberately structural — callers project a `RunRecord`\n * (or any record) into `{ pairKey, arm, pass?, metrics? }`. Arm names are\n * caller-supplied parameters; the module ships no domain literal.\n */\n\nimport { ValidationError } from './errors'\nimport type { McNemarResult, PairedBootstrapOptions, PairedBootstrapResult } from './statistics'\nimport {\n mcnemar,\n pairedBootstrap,\n pairedRiskDifference,\n type RiskDifferenceResult,\n wilcoxonSignedRank,\n} from './statistics'\n\n/** One arm observation of one work item. Structural on purpose: callers\n * project their own record type (e.g. a `RunRecord`) into this shape. */\nexport interface PairedArmRow {\n /** Matching key — rows sharing a `pairKey` across both arms form pairs\n * (typically the task/scenario/seed identity). */\n pairKey: string\n /** Rep identity within a `pairKey` (e.g. a seed or rep number). Required on\n * every row of a `pairKey` that has more than one rep in either arm; reps\n * then pair only on exact (`pairKey`, `repKey`) match, never on outcome\n * content. Optional when each arm has at most one rep of the item. */\n repKey?: string\n /** Arm label this row was produced under. */\n arm: string\n /** Binary outcome; omit when the comparison has no pass/fail notion. */\n pass?: boolean\n /** Named numeric measurements (score, cost, latency, …). */\n metrics?: Record<string, number>\n}\n\nexport interface PairArmsOptions {\n /** Arm treated as the control side of every pair. */\n baselineArm: string\n /** Arm treated as the treatment side of every pair. */\n treatmentArm: string\n}\n\n/** One matched (baseline, treatment) observation of the same work item. */\nexport interface MatchedPair {\n pairKey: string\n /** 0-based position of this pair within its `pairKey`, ordered by sorted\n * `repKey` (always 0 for a single-rep item). The rep identity itself is on\n * the rows (`baseline.repKey` / `treatment.repKey`). */\n repIndex: number\n baseline: PairedArmRow\n treatment: PairedArmRow\n}\n\nexport interface PairArmsResult {\n /** Matched pairs, ordered by (`pairKey`, `repIndex`). */\n pairs: MatchedPair[]\n /** Baseline rows left without a treatment counterpart — reported, never\n * silently dropped. */\n unpairedBaseline: PairedArmRow[]\n /** Treatment rows left without a baseline counterpart. */\n unpairedTreatment: PairedArmRow[]\n}\n\n/**\n * Match rows across two arms into (baseline, treatment) pairs by `pairKey`.\n *\n * A `pairKey` with at most one row per arm pairs directly, no `repKey`\n * needed. A `pairKey` with multiple reps in either arm requires `repKey` on\n * every one of its rows, and reps pair only on exact (`pairKey`, `repKey`)\n * match — pairing is keyed purely on row identity, never on outcome content\n * (outcome-keyed matching deflates discordant counts and biases McNemar), and\n * is therefore independent of input order. Reps whose `repKey` has no\n * counterpart in the other arm, and items present in only one arm, land in\n * the unpaired lists — reported, never truncated.\n *\n * Fail-loud: throws when either named arm has zero rows (an unknown arm\n * name would otherwise read as \"everything unpaired\"), when the two arm\n * names are equal, when a multi-rep `pairKey` has a row without `repKey`, or\n * when a (`pairKey`, arm) group repeats a `repKey` (the match would be\n * ambiguous).\n */\nexport function pairArms(rows: readonly PairedArmRow[], opts: PairArmsOptions): PairArmsResult {\n const { baselineArm, treatmentArm } = opts\n if (baselineArm === treatmentArm) {\n throw new ValidationError(\n `pairArms: baselineArm and treatmentArm are both '${baselineArm}' — an arm cannot be compared to itself`,\n )\n }\n\n // arm → pairKey → rows\n const byArm = new Map<string, Map<string, PairedArmRow[]>>()\n const armsSeen = new Set<string>()\n for (const row of rows) {\n armsSeen.add(row.arm)\n if (row.arm !== baselineArm && row.arm !== treatmentArm) continue\n const byKey = byArm.get(row.arm) ?? new Map<string, PairedArmRow[]>()\n const group = byKey.get(row.pairKey) ?? []\n group.push(row)\n byKey.set(row.pairKey, group)\n byArm.set(row.arm, byKey)\n }\n\n for (const arm of [baselineArm, treatmentArm]) {\n if (!byArm.has(arm)) {\n const seen = [...armsSeen].sort().join(', ') || '<none>'\n throw new ValidationError(`pairArms: no rows for arm '${arm}' (arms present: ${seen})`)\n }\n }\n\n const baselineByKey = byArm.get(baselineArm)!\n const treatmentByKey = byArm.get(treatmentArm)!\n\n const allKeys = [...new Set([...baselineByKey.keys(), ...treatmentByKey.keys()])].sort()\n const pairs: MatchedPair[] = []\n const unpairedBaseline: PairedArmRow[] = []\n const unpairedTreatment: PairedArmRow[] = []\n for (const pairKey of allKeys) {\n const b = baselineByKey.get(pairKey) ?? []\n const t = treatmentByKey.get(pairKey) ?? []\n\n if (b.length <= 1 && t.length <= 1) {\n if (b.length === 1 && t.length === 1) {\n pairs.push({ pairKey, repIndex: 0, baseline: b[0]!, treatment: t[0]! })\n } else {\n unpairedBaseline.push(...b)\n unpairedTreatment.push(...t)\n }\n continue\n }\n\n const bByRep = indexByRepKey(b, pairKey, baselineArm)\n const tByRep = indexByRepKey(t, pairKey, treatmentArm)\n const repKeys = [...new Set([...bByRep.keys(), ...tByRep.keys()])].sort()\n let repIndex = 0\n for (const repKey of repKeys) {\n const baseline = bByRep.get(repKey)\n const treatment = tByRep.get(repKey)\n if (baseline !== undefined && treatment !== undefined) {\n pairs.push({ pairKey, repIndex: repIndex++, baseline, treatment })\n } else if (baseline !== undefined) {\n unpairedBaseline.push(baseline)\n } else if (treatment !== undefined) {\n unpairedTreatment.push(treatment)\n }\n }\n }\n\n return { pairs, unpairedBaseline, unpairedTreatment }\n}\n\n/** Index a multi-rep (pairKey, arm) group by `repKey`, enforcing that every\n * row carries one and that no repKey repeats within the group. */\nfunction indexByRepKey(\n group: readonly PairedArmRow[],\n pairKey: string,\n arm: string,\n): Map<string, PairedArmRow> {\n const byRep = new Map<string, PairedArmRow>()\n for (const row of group) {\n if (row.repKey === undefined) {\n throw new ValidationError(\n `pairArms: pairKey '${pairKey}' has multiple reps in an arm, but a row in arm '${arm}' ` +\n `is missing repKey — multi-rep items require an explicit repKey on every row so reps ` +\n `pair by identity (pairing reps by outcome or by index would bias the paired statistics)`,\n )\n }\n if (byRep.has(row.repKey)) {\n throw new ValidationError(\n `pairArms: duplicate repKey '${row.repKey}' for pairKey '${pairKey}' in arm '${arm}' — ` +\n `(pairKey, repKey) must uniquely identify a rep within an arm`,\n )\n }\n byRep.set(row.repKey, row)\n }\n return byRep\n}\n\n/** Paired pass/fail comparison over the pairs where BOTH sides carry `pass`. */\nexport interface PairedCorrectness {\n /** Discordant pairs where the treatment passed and the baseline failed. */\n b10: number\n /** Discordant pairs where the baseline passed and the treatment failed. */\n b01: number\n /** Exact McNemar significance over the paired outcomes (`b === b10`, `c === b01`). */\n mcnemar: McNemarResult\n /** Paired effect size: p(treatment) − p(baseline) with a paired-variance CI. */\n riskDifference: RiskDifferenceResult\n}\n\n/** Paired delta summary for one named metric (delta = treatment − baseline). */\nexport interface PairedMetricDelta {\n name: string\n /** Pairs where BOTH sides carry a finite value for this metric. */\n n: number\n /** Pairs where at least one side does not carry the metric. */\n nMissing: number\n /** Median paired delta; NaN when `n === 0` (no data ≠ measured zero). */\n medianDelta: number\n /** Mean paired delta; NaN when `n === 0`. */\n meanDelta: number\n /** Bootstrap CI on the paired delta (`pairedBootstrap`); null when\n * `n === 0` — a zero-width [0, 0] interval on no data would read as a\n * measured tight null. */\n bootstrapCi: PairedBootstrapResult | null\n /** Wilcoxon signed-rank test on the paired deltas; null when `n === 0`. */\n wilcoxon: { w: number; p: number } | null\n}\n\nexport interface ComparePairedArmsOptions extends PairArmsOptions {\n /** Metrics to compare. Default: every metric name observed on any matched\n * pair, sorted. A name that appears on no pair is still reported (with\n * `n = 0`) so a misspelled metric is visible instead of vanishing. */\n metricNames?: string[]\n /** Passed through to `pairedBootstrap` — set `seed` for reproducible CIs. */\n bootstrap?: PairedBootstrapOptions\n}\n\nexport interface PairedArmsComparison {\n nPairs: number\n nUnpairedBaseline: number\n nUnpairedTreatment: number\n /** null when no matched pair carries `pass` on both sides — a pass/fail\n * verdict over rows that never measured pass/fail would be fabricated. */\n correctness: PairedCorrectness | null\n metricDeltas: PairedMetricDelta[]\n}\n\n/**\n * Full matched-pair arm comparison: pair via {@link pairArms}, then compose\n * the paired estimators from `statistics` over the matched pairs.\n *\n * Correctness uses only the pairs where both sides carry `pass` (`mcnemar.n`\n * is that subset's size); each metric uses only the pairs where both sides\n * carry a finite value for it, with the remainder counted in `nMissing`.\n * Deltas are treatment − baseline throughout.\n *\n * Fail-loud: inherits {@link pairArms}'s unknown-arm throw, and throws on a\n * non-finite metric value — silently treating corrupt telemetry as \"metric\n * absent\" would misreport it as missing coverage.\n */\nexport function comparePairedArms(\n rows: readonly PairedArmRow[],\n opts: ComparePairedArmsOptions,\n): PairedArmsComparison {\n const { pairs, unpairedBaseline, unpairedTreatment } = pairArms(rows, opts)\n\n let correctness: PairedCorrectness | null = null\n const baselinePass: number[] = []\n const treatmentPass: number[] = []\n for (const pair of pairs) {\n if (pair.baseline.pass === undefined || pair.treatment.pass === undefined) continue\n baselinePass.push(pair.baseline.pass ? 1 : 0)\n treatmentPass.push(pair.treatment.pass ? 1 : 0)\n }\n if (baselinePass.length > 0) {\n const mc = mcnemar(baselinePass, treatmentPass)\n correctness = {\n b10: mc.b,\n b01: mc.c,\n mcnemar: mc,\n riskDifference: pairedRiskDifference(baselinePass, treatmentPass),\n }\n }\n\n const metricNames =\n opts.metricNames ??\n [\n ...new Set(\n pairs.flatMap((p) => [\n ...Object.keys(p.baseline.metrics ?? {}),\n ...Object.keys(p.treatment.metrics ?? {}),\n ]),\n ),\n ].sort()\n\n const metricDeltas: PairedMetricDelta[] = metricNames.map((name) => {\n const before: number[] = []\n const after: number[] = []\n let nMissing = 0\n for (const pair of pairs) {\n const b = metricValue(pair.baseline, name)\n const t = metricValue(pair.treatment, name)\n if (b === undefined || t === undefined) {\n nMissing++\n continue\n }\n before.push(b)\n after.push(t)\n }\n const bootstrapCi = before.length === 0 ? null : pairedBootstrap(before, after, opts.bootstrap)\n return {\n name,\n n: before.length,\n nMissing,\n medianDelta: bootstrapCi === null ? Number.NaN : bootstrapCi.median,\n meanDelta: bootstrapCi === null ? Number.NaN : bootstrapCi.mean,\n bootstrapCi,\n wilcoxon: before.length === 0 ? null : wilcoxonSignedRank(before, after),\n }\n })\n\n return {\n nPairs: pairs.length,\n nUnpairedBaseline: unpairedBaseline.length,\n nUnpairedTreatment: unpairedTreatment.length,\n correctness,\n metricDeltas,\n }\n}\n\nfunction metricValue(row: PairedArmRow, name: string): number | undefined {\n const v = row.metrics?.[name]\n if (v === undefined) return undefined\n if (!Number.isFinite(v)) {\n throw new ValidationError(\n `comparePairedArms: non-finite value for metric '${name}' on pairKey '${row.pairKey}' (arm '${row.arm}'): ${v}`,\n )\n }\n return v\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 * Treatment-applied gate — \"did the treatment's tool actually fire this run?\"\n *\n * A tool-treatment A/B (mount a search provider, a browser, a code-exec\n * sandbox, a retrieval MCP — anything one arm gets and the other doesn't) only\n * means something on the treatment arm if that arm actually EXERCISED the tool.\n * A treatment run that never called the mounted tool is not a weak data point\n * — it is a NON-data-point: the manipulation never happened, so the run cannot\n * speak to the treatment and must be excluded from the objective, the same way\n * an infra-tainted run is excluded.\n *\n * This is the manipulation/validity precondition that protects the paired A/B\n * tests downstream (`mcnemar`, `pairedRiskDifference`): they must only ever see\n * runs where the treatment was applied, or they measure noise and report it as\n * an effect.\n *\n * Shape mirrors `authenticity`'s `gateRealness`: a pure predicate over already-\n * computed signals, with explicit fail-open/fail-closed discipline. It is not a\n * trace parser — the tool-call telemetry it reads is the deterministic\n * `toolHistogram` that `computeTraceMetrics(spans)` already produces (OTLP\n * tool-name extraction via `TOOL_NAME_ATTR_KEYS`), or the `ToolSpan[]` a\n * `toolSpans(store, runId)` query returns. The gate never re-derives either.\n *\n * General by construction:\n * - The \"which tool counts as the treatment\" decision is a `matches` PARAMETER\n * — a `(toolName: string) => boolean`. There is no `search`/`web`/`fetch`\n * literal anywhere in this module; a search A/B passes its own matcher.\n * - The \"is THIS run a treatment arm (vs a control)\" decision is the caller's\n * policy and stays at the call site. The gate only answers the narrower,\n * domain-free question: \"given this run's telemetry, did a matching tool\n * fire?\" — so it generalizes to any tool-treatment, not search.\n *\n * Fail-open on telemetry absence: when NO tool calls were captured at all\n * (`sum(toolHistogram) === 0`), the gate cannot distinguish \"the agent used no\n * tools\" from \"this harness's tool calls weren't recorded\". Quarantining on a\n * telemetry gap would silently delete real runs, so the default is\n * applied=true / gated=false. Pass `failOpenWhenNoTelemetry: false` to flip to\n * fail-closed for harnesses where tool capture is guaranteed.\n */\n\nimport type { RunRecord } from './run-record'\nimport type { ToolSpan } from './trace/schema'\nimport type { BehavioralMetrics } from './trace-analyst/behavioral-metrics'\nimport { computeTraceMetrics } from './trace-analyst/behavioral-metrics'\nimport type { TraceAnalystSpan } from './trace-analyst/types'\n\n/** A tool-name matcher: does this tool name belong to the treatment under test?\n * The caller supplies it — the substrate ships no `search` (or any) literal. */\nexport type ToolMatcher = (toolName: string) => boolean\n\nexport interface TreatmentGateInput {\n /** Tool-call counts by tool name — exactly `computeTraceMetrics(spans).toolHistogram`.\n * The gate consumes this; it does not parse spans itself. */\n toolHistogram: Readonly<Record<string, number>>\n /** Which tool names count as the treatment firing. A parameter, never baked in. */\n matches: ToolMatcher\n}\n\nexport interface TreatmentGateOptions {\n /** When the histogram is empty (no tool telemetry captured), treat the run as\n * applied rather than quarantining it. Default true — a telemetry gap must\n * never be mistaken for \"treatment not applied\". Set false only when tool\n * capture is guaranteed for this harness. */\n failOpenWhenNoTelemetry?: boolean\n}\n\nexport interface TreatmentGate {\n /** True iff the treatment's tool is considered to have fired this run. False\n * ONLY when telemetry was present and no matching call appears. */\n applied: boolean\n /** Objective-exclusion flag, parallel to `outcome.realness.gated`: a gated run\n * is dropped from the objective denominator and reported as\n * treatment-not-applied (like infra-loss). `gated === !applied`. */\n gated: boolean\n reason?: string\n /** How many recorded tool calls matched the treatment matcher. */\n matchedCalls: number\n /** Total recorded tool calls (`sum(toolHistogram)`) — 0 means no telemetry. */\n observedTools: number\n}\n\n/**\n * Core predicate. Gated (treatment-not-applied) ONLY when telemetry was\n * captured AND zero matching calls appear; an empty histogram fails open.\n */\nexport function gateTreatmentApplied(\n input: TreatmentGateInput,\n opts: TreatmentGateOptions = {},\n): TreatmentGate {\n const failOpen = opts.failOpenWhenNoTelemetry ?? true\n\n let observedTools = 0\n let matchedCalls = 0\n for (const [tool, count] of Object.entries(input.toolHistogram)) {\n const n = Number.isFinite(count) && count > 0 ? count : 0\n observedTools += n\n if (n > 0 && input.matches(tool)) matchedCalls += n\n }\n\n if (observedTools === 0) {\n return failOpen\n ? {\n applied: true,\n gated: false,\n reason: 'no tool telemetry captured — fail-open (not quarantined)',\n matchedCalls: 0,\n observedTools: 0,\n }\n : {\n applied: false,\n gated: true,\n reason: 'no tool telemetry captured — fail-closed',\n matchedCalls: 0,\n observedTools: 0,\n }\n }\n\n if (matchedCalls === 0) {\n return {\n applied: false,\n gated: true,\n reason: `treatment tool never fired (${observedTools} tool calls, 0 matched)`,\n matchedCalls: 0,\n observedTools,\n }\n }\n\n return { applied: true, gated: false, matchedCalls, observedTools }\n}\n\n/**\n * Convenience: gate from an already-computed `BehavioralMetrics` (the common\n * case — analysts already hold `computeTraceMetrics(spans)` for the run). Reads\n * the metrics' `toolHistogram`; does no re-derivation.\n */\nexport function gateTreatmentFromMetrics(\n metrics: Pick<BehavioralMetrics, 'toolHistogram'>,\n matches: ToolMatcher,\n opts?: TreatmentGateOptions,\n): TreatmentGate {\n return gateTreatmentApplied({ toolHistogram: metrics.toolHistogram, matches }, opts)\n}\n\n/**\n * Convenience: gate directly from analyst spans, reusing the substrate's\n * deterministic histogram builder. For callers holding the trace store's typed\n * `ToolSpan[]` instead, see {@link gateTreatmentFromToolSpans}.\n */\nexport function gateTreatmentFromSpans(\n spans: readonly TraceAnalystSpan[],\n matches: ToolMatcher,\n opts?: TreatmentGateOptions,\n): TreatmentGate {\n return gateTreatmentFromMetrics(computeTraceMetrics(spans), matches, opts)\n}\n\n/**\n * Convenience: gate from the trace store's canonical `ToolSpan[]` (e.g. the\n * result of `toolSpans(store, runId)`). Counts by `toolName` — the typed\n * tool-call field — so it needs no OTLP attribute extraction.\n */\nexport function gateTreatmentFromToolSpans(\n toolSpans: readonly ToolSpan[],\n matches: ToolMatcher,\n opts?: TreatmentGateOptions,\n): TreatmentGate {\n const toolHistogram: Record<string, number> = {}\n for (const s of toolSpans) {\n if (s.toolName) toolHistogram[s.toolName] = (toolHistogram[s.toolName] ?? 0) + 1\n }\n return gateTreatmentApplied({ toolHistogram, matches }, opts)\n}\n\n/** Measurable runs count toward the objective; treatment-not-applied runs are\n * excluded (like infra-loss), NOT counted as treatment failures. This is a\n * partition over the existing exclusion-flag pattern — it adds no new\n * classification enum. */\nexport type TreatmentClass = 'measurable' | 'treatment-not-applied'\n\n/**\n * Map a gate verdict onto a single measurable-vs-excluded label keyed on a\n * `RunRecord`, so consumers (paired A/B filters, reporters) read the partition\n * in one place instead of re-implementing the fail-open guard inline. The\n * `RunRecord` is accepted so callers key on the canonical run row, mirroring\n * how `outcome.realness.gated` rides along on the record; the verdict itself is\n * the gate's, not re-derived here.\n */\nexport function classifyTreatment(_record: RunRecord, gate: TreatmentGate): TreatmentClass {\n return gate.gated ? 'treatment-not-applied' : 'measurable'\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 = lower.indexOf(needle, 0)\n while (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 = lower.indexOf(needle, 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 * 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 * Eval primitives as agent tools — `makeEvalTools` packages the substrate's\n * judge / completion / analysis entry points as JSON-Schema tool definitions\n * an LLM agent loop can call. The host closes over the live config (judge\n * panels, the correctness checker, analyst registry); the agent passes only\n * data over the wire.\n *\n * Three tools, each present only when its config section is supplied:\n * - `run_judges` — score an artifact with the configured `JudgeConfig`s\n * - `verify_completion` — gold-spec requirement check → `CompletionVerdict`\n * - `analyze_runs` — `RunRecord[]` (inline or from a file) → `InsightReport`\n *\n * `toOpenAiTool` converts a definition to the OpenAI function-tool wire shape.\n */\n\nimport { readFile } from 'node:fs/promises'\nimport type { JudgeConfig, JudgeScore, Scenario } from './campaign/types'\nimport {\n type CompletionVerdict,\n type CorrectnessChecker,\n type ProducedState,\n type TaskGold,\n verifyCompletion,\n} from './completion-verifier'\nimport { type AnalyzeRunsOptions, analyzeRuns } from './contract/analyze-runs'\nimport type { RunRecord } from './run-record'\n\n/** One agent-callable tool. `parameters` is a JSON Schema (draft-07+) object. */\nexport interface EvalToolDef {\n name: string\n description: string\n parameters: Record<string, unknown>\n handler: (args: unknown, ctx?: { signal?: AbortSignal }) => Promise<unknown>\n}\n\nexport interface MakeEvalToolsConfig {\n /** Judges available to `run_judges`. Omit to exclude the tool. */\n judges?: Array<JudgeConfig<unknown>>\n /** Host-side correctness checker for `verify_completion` (the third\n * `verifyCompletion` argument — a function, so it cannot cross the wire).\n * Omit to exclude the tool. */\n completion?: { checkCorrectness: CorrectnessChecker }\n /** `analyzeRuns` options minus `runs` (runs arrive as tool args, inline or\n * via `path`). Omit to exclude the tool. */\n analyze?: Omit<AnalyzeRunsOptions, 'runs'>\n}\n\n/** OpenAI function-tool wire shape for an `EvalToolDef`. */\nexport function toOpenAiTool(def: EvalToolDef): {\n type: 'function'\n function: { name: string; description: string; parameters: Record<string, unknown> }\n} {\n return {\n type: 'function',\n function: { name: def.name, description: def.description, parameters: def.parameters },\n }\n}\n\n/**\n * Build the eval toolset for the supplied config. Only sections present in\n * `cfg` produce tools, so the agent's tool list mirrors what the host\n * actually wired. Handlers fail loud on malformed args — no silent defaults.\n */\nexport function makeEvalTools(cfg: MakeEvalToolsConfig): EvalToolDef[] {\n const tools: EvalToolDef[] = []\n if (cfg.judges) tools.push(runJudgesTool(cfg.judges))\n if (cfg.completion) tools.push(verifyCompletionTool(cfg.completion.checkCorrectness))\n if (cfg.analyze) tools.push(analyzeRunsTool(cfg.analyze))\n return tools\n}\n\n// ── run_judges ───────────────────────────────────────────────────────────\n\nfunction runJudgesTool(judges: Array<JudgeConfig<unknown>>): EvalToolDef {\n if (judges.length === 0) {\n throw new Error('makeEvalTools: cfg.judges is empty — supply judges or omit the section')\n }\n const names = judges.map((j) => j.name)\n return {\n name: 'run_judges',\n description:\n `Score an artifact with the configured judges (${names.join(', ')}). ` +\n 'Pass `judge` to run one judge by name; omit it to run all. ' +\n 'Returns per-judge scores keyed by judge name.',\n parameters: {\n type: 'object',\n properties: {\n judge: {\n type: 'string',\n enum: names,\n description: 'Run only this judge. Omit to run every configured judge.',\n },\n artifact: {\n description: 'The artifact to score — any JSON value the judges understand.',\n },\n scenario: {\n description: 'Optional scenario context forwarded to the judges.',\n },\n },\n required: ['artifact'],\n additionalProperties: false,\n },\n handler: async (args, ctx) => {\n const a = requireObjectArgs('run_judges', args)\n if (!('artifact' in a)) {\n throw new Error('run_judges: args.artifact is required')\n }\n let selected = judges\n if (a.judge !== undefined) {\n if (typeof a.judge !== 'string') throw new Error('run_judges: args.judge must be a string')\n selected = judges.filter((j) => j.name === a.judge)\n if (selected.length === 0) {\n throw new Error(\n `run_judges: unknown judge '${a.judge}' — configured: ${names.join(', ')}`,\n )\n }\n }\n const signal = ctx?.signal ?? new AbortController().signal\n const scenario = a.scenario as Scenario\n const scores: Record<string, JudgeScore> = {}\n for (const judge of selected) {\n if (scenario !== undefined && judge.appliesTo && !judge.appliesTo(scenario)) continue\n scores[judge.name] = await judge.score({ artifact: a.artifact, scenario, signal })\n }\n return { scores }\n },\n }\n}\n\n// ── verify_completion ────────────────────────────────────────────────────\n\nfunction verifyCompletionTool(checkCorrectness: CorrectnessChecker): EvalToolDef {\n return {\n name: 'verify_completion',\n description:\n 'Verify produced state against a gold task spec: each gold requirement is ' +\n 'matched to at most one produced artifact/proposal/tool-call, correctness-checked ' +\n 'by the host, and reduced to a CompletionVerdict (completionRate, fullyComplete, ' +\n 'per-requirement checks).',\n parameters: {\n type: 'object',\n properties: {\n gold: {\n type: 'object',\n description: 'TaskGold — taskId + requirements the produced state must satisfy.',\n },\n state: {\n type: 'object',\n description: 'ProducedState — artifacts, proposals, and tool calls the agent produced.',\n },\n },\n required: ['gold', 'state'],\n additionalProperties: false,\n },\n handler: async (args): Promise<CompletionVerdict> => {\n const a = requireObjectArgs('verify_completion', args)\n if (typeof a.gold !== 'object' || a.gold === null) {\n throw new Error('verify_completion: args.gold (TaskGold) is required')\n }\n if (typeof a.state !== 'object' || a.state === null) {\n throw new Error('verify_completion: args.state (ProducedState) is required')\n }\n return verifyCompletion(a.gold as TaskGold, a.state as ProducedState, checkCorrectness)\n },\n }\n}\n\n// ── analyze_runs ─────────────────────────────────────────────────────────\n\nfunction analyzeRunsTool(analyzeOpts: Omit<AnalyzeRunsOptions, 'runs'>): EvalToolDef {\n return {\n name: 'analyze_runs',\n description:\n 'Run analyzeRuns over a set of RunRecords and return the InsightReport ' +\n '(composite distribution, per-dimension stats, lift, failure clusters, ' +\n 'recommendations). Pass the records inline via `runs`, or `path` to a ' +\n '.json (array) or .jsonl (one record per line) file on the host.',\n parameters: {\n type: 'object',\n properties: {\n runs: {\n type: 'array',\n items: { type: 'object' },\n description: 'RunRecord[] inline.',\n },\n path: {\n type: 'string',\n description: 'Host path to a JSON array or JSONL file of RunRecords.',\n },\n },\n additionalProperties: false,\n },\n handler: async (args) => {\n const a = requireObjectArgs('analyze_runs', args)\n const hasRuns = Array.isArray(a.runs)\n const hasPath = typeof a.path === 'string' && a.path.length > 0\n if (hasRuns === hasPath) {\n throw new Error('analyze_runs: pass exactly one of args.runs (array) or args.path (string)')\n }\n const runs = hasRuns ? (a.runs as RunRecord[]) : await loadRunRecords(a.path as string)\n if (runs.length === 0) {\n throw new Error('analyze_runs: no runs to analyze')\n }\n return analyzeRuns({ ...analyzeOpts, runs })\n },\n }\n}\n\nasync function loadRunRecords(path: string): Promise<RunRecord[]> {\n const text = await readFile(path, 'utf8')\n const trimmed = text.trim()\n if (trimmed.length === 0) {\n throw new Error(`analyze_runs: file '${path}' is empty`)\n }\n if (trimmed.startsWith('[')) {\n const parsed = JSON.parse(trimmed) as unknown\n if (!Array.isArray(parsed)) {\n throw new Error(`analyze_runs: file '${path}' did not parse to an array`)\n }\n return parsed as RunRecord[]\n }\n // JSONL: one record per non-empty line. A malformed line throws with its\n // line number rather than being skipped.\n return trimmed.split('\\n').flatMap((line, i) => {\n const l = line.trim()\n if (l.length === 0) return []\n try {\n return [JSON.parse(l) as RunRecord]\n } catch (err) {\n throw new Error(\n `analyze_runs: file '${path}' line ${i + 1} is not valid JSON: ${err instanceof Error ? err.message : String(err)}`,\n )\n }\n })\n}\n\nfunction requireObjectArgs(tool: string, args: unknown): Record<string, unknown> {\n if (typeof args !== 'object' || args === null || Array.isArray(args)) {\n throw new Error(`${tool}: args must be an object`)\n }\n return args as Record<string, unknown>\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","/**\n * Judge-ensemble reducer — folds N independent judge verdicts on the same\n * artifact into one aggregate score.\n *\n * The pattern every multi-model judge re-implements: run K uncorrelated judges\n * (different model families remove within-family bias), then reduce their\n * per-dimension verdicts to a single composite + an inter-rater disagreement\n * signal. This is the pure reduction — no LLM, no I/O — so a lift it produces\n * is attributable to the scores, not to where they came from.\n *\n * Fail-loud: a judge that errored or returned malformed output is recorded in\n * `failedJudges` with `perDimension: null`, never folded into a zero. If EVERY\n * judge failed the reducer throws — a silent zero here would corrupt the gate's\n * number. A failed judge still burned tokens, so its `costUsd` is still summed.\n */\n\nimport { clamp01 } from './run-score'\nimport { weightedComposite } from './statistics'\n\n/** One judge's verdict. `perDimension: null` ⇒ that judge call failed (threw or\n * returned malformed output) — recorded, never folded into a zero. */\nexport interface JudgeVerdict<D extends string = string> {\n /** Judge identity (typically the model id) — the `perJudge` / `failedJudges` key. */\n model: string\n /** Per-dimension scores, or `null` when the judge failed. */\n perDimension: Record<D, number> | null\n /** Optional one-line rationale; the first non-empty one becomes the aggregate's. */\n rationale?: string\n /** Optional reported cost — summed across ALL verdicts (failed included). */\n costUsd?: number\n /** Optional per-dimension reasoning/evidence. Carried through to\n * `EnsembleAggregate.verdicts` verbatim — never folded into the math. */\n detail?: Partial<Record<D, { reasoning?: string; evidence?: string }>>\n}\n\n/** The aggregated ensemble result. */\nexport interface EnsembleAggregate<D extends string = string> {\n /** Mean over SURVIVING judges, per dimension (absent-everywhere ⇒ 0). */\n perDimension: Record<D, number>\n /** Weighted mean of `perDimension` (uniform unless `weights` given). */\n composite: number\n /** Each surviving judge's clamped per-dimension scores, for trace drill-down. */\n perJudge: Record<string, Record<D, number>>\n /** Max over dimensions of (max − min) across survivors — the inter-rater signal. */\n maxDisagreement: number\n /** Models whose verdict was null (failed). */\n failedJudges: string[]\n /** Sum of `costUsd` over ALL verdicts, failed included. */\n costUsd: number\n /** First non-empty survivor rationale, or `'llm-judge'`. */\n rationale: string\n /** The input verdicts, verbatim — drill-down to raw scores, `detail`\n * reasoning/evidence, and per-verdict cost without re-running judges. */\n verdicts: JudgeVerdict<D>[]\n}\n\n/**\n * Reduce per-judge verdicts to one aggregate. Generic over the rubric: pass the\n * stable-ordered `dimensionKeys` the judges scored.\n *\n * - Per-dimension score = mean over surviving judges (out-of-range clamped to [0,1]).\n * - `composite` = `weightedComposite` of `perDimension`. No `weights` ⇒ uniform\n * over every dimension. A partial `weights` map selects AND weights exactly the\n * named dimensions (others excluded from the composite) — the substrate's\n * sum-normalized weighting, not re-implemented here.\n * - Throws if `verdicts` or `dimensionKeys` is empty, or if every judge failed.\n */\nexport function aggregateJudgeVerdicts<D extends string>(\n verdicts: readonly JudgeVerdict<D>[],\n dimensionKeys: readonly D[],\n weights?: Partial<Record<D, number>>,\n): EnsembleAggregate<D> {\n if (verdicts.length === 0) {\n throw new Error('aggregateJudgeVerdicts: no verdicts to aggregate')\n }\n if (dimensionKeys.length === 0) {\n throw new Error('aggregateJudgeVerdicts: dimensionKeys is empty')\n }\n\n const perJudge: Record<string, Record<D, number>> = {}\n const failedJudges: string[] = []\n const dimAcc = {} as Record<D, number[]>\n for (const d of dimensionKeys) dimAcc[d] = []\n let rationale = ''\n let costUsd = 0\n\n // Same model sampled k times (best-of-N judging) gets keys 'm', 'm#2',\n // 'm#3'… so repeat votes land as distinct perJudge/failedJudges entries\n // instead of overwriting each other.\n const seenCount = new Map<string, number>()\n const keyFor = (model: string): string => {\n const n = (seenCount.get(model) ?? 0) + 1\n seenCount.set(model, n)\n return n === 1 ? model : `${model}#${n}`\n }\n\n for (const v of verdicts) {\n costUsd += v.costUsd ?? 0\n const key = keyFor(v.model)\n if (!v.perDimension) {\n failedJudges.push(key)\n continue\n }\n const dims = {} as Record<D, number>\n for (const d of dimensionKeys) dims[d] = clamp01(Number(v.perDimension[d]))\n perJudge[key] = dims\n for (const d of dimensionKeys) dimAcc[d].push(dims[d])\n if (!rationale && typeof v.rationale === 'string' && v.rationale) rationale = v.rationale\n }\n\n if (failedJudges.length === verdicts.length) {\n throw new Error(`aggregateJudgeVerdicts: all ${verdicts.length} judges failed`)\n }\n\n const perDimension = {} as Record<D, number>\n for (const d of dimensionKeys) {\n const vals = dimAcc[d]\n perDimension[d] = vals.length === 0 ? 0 : vals.reduce((s, x) => s + x, 0) / vals.length\n }\n\n let maxDisagreement = 0\n for (const d of dimensionKeys) {\n const vals = dimAcc[d]\n if (vals.length < 2) continue\n const spread = Math.max(...vals) - Math.min(...vals)\n if (spread > maxDisagreement) maxDisagreement = spread\n }\n\n const w: Record<string, number> = {}\n if (weights) {\n for (const [d, weight] of Object.entries(weights)) {\n if (weight !== undefined) w[d] = weight as number\n }\n } else {\n for (const d of dimensionKeys) w[d] = 1 / dimensionKeys.length\n }\n const composite = weightedComposite({ dims: perDimension, weights: w }).composite\n\n return {\n perDimension,\n composite,\n perJudge,\n maxDisagreement,\n failedJudges,\n costUsd,\n rationale: rationale || 'llm-judge',\n verdicts: [...verdicts],\n }\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 300_000. */\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 = 300_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 * Multi-model judge panel — `ensembleJudge` builds a campaign `JudgeConfig`\n * that fans one artifact out to K judge models and reduces their verdicts\n * through `aggregateJudgeVerdicts` (src/judge-ensemble.ts).\n *\n * The panel is the fail-loud composition of the substrate's existing judge\n * primitives:\n * - `assertCrossFamily` (construction-time) — a single-family panel is\n * correlated bias, not independent signal.\n * - `withJudgeRetry` (per model, opt-in) — transient-fault retry with a\n * typed outcome; a judge that exhausts retries is recorded as failed,\n * never folded into a zero.\n * - `aggregateJudgeVerdicts` — the pure reducer; throws when EVERY judge\n * failed so a silent zero can't reach the gate.\n *\n * The returned `JudgeScore` is on the campaign [0,1] scale and carries the\n * ensemble extras (`maxDisagreement`, `failedJudges`, `perJudge`) declared\n * on the canonical `JudgeScore` in src/campaign/types.ts.\n */\n\nimport type { JudgeConfig, JudgeScore } from './campaign/types'\nimport { aggregateJudgeVerdicts, type JudgeVerdict } from './judge-ensemble'\nimport { assertCrossFamily } from './judge-families'\nimport { type JudgeRetryPolicy, withJudgeRetry } from './judge-retry'\n\nexport interface EnsembleJudgeOptions<D extends string> {\n /** Judge name — becomes the returned `JudgeConfig.name`. */\n name: string\n /** Rubric dimensions every model scores. Keys of the verdict's `perDimension`. */\n dimensions: D[]\n /** Judge model ids — one `scoreWith` call per entry. List a model twice to\n * sample it twice (votes are suffix-keyed `model#2` so none overwrite). */\n models: string[]\n /**\n * Score the artifact with one model. Throw (or reject) on failure — the\n * panel records that model as a failed judge; it is never folded into a\n * zero. Verdict scores are clamped to [0,1] by the reducer.\n */\n scoreWith: (\n model: string,\n input: { artifact: unknown; scenario?: unknown },\n ) => Promise<JudgeVerdict<D>>\n /**\n * Per-model retry policy, applied via `withJudgeRetry`. The panel's\n * `models` list drives the fan-out, so `retry.models` (the fallback\n * rotation) is overridden to each panel model in turn.\n */\n retry?: JudgeRetryPolicy\n /** Enforce `assertCrossFamily` over `models` at construction. Default true.\n * Opt out only for deliberate single-family panels (e.g. self-consistency\n * sampling of one model). */\n crossFamily?: boolean\n /** Composite weights forwarded to `aggregateJudgeVerdicts`: a partial map\n * selects AND weights exactly the named dimensions. Omit for uniform. */\n weights?: Partial<Record<D, number>>\n}\n\n/**\n * Build a campaign-shaped `JudgeConfig` whose `score()` runs every panel\n * model in parallel and reduces the surviving verdicts to one canonical\n * `JudgeScore` in [0,1].\n *\n * Failure semantics: a model whose `scoreWith` throws (or exhausts `retry`)\n * lands in `failedJudges` and is excluded from the means. When EVERY model\n * fails, `aggregateJudgeVerdicts` throws — the campaign engine records a\n * failed cell instead of averaging a fabricated zero.\n */\nexport function ensembleJudge<D extends string>(\n opts: EnsembleJudgeOptions<D>,\n): JudgeConfig<unknown> {\n if (opts.models.length === 0) {\n throw new Error(`ensembleJudge '${opts.name}': models is empty — nothing to score with`)\n }\n if (opts.dimensions.length === 0) {\n throw new Error(`ensembleJudge '${opts.name}': dimensions is empty — nothing to score`)\n }\n if (opts.crossFamily !== false) {\n assertCrossFamily(opts.models)\n }\n\n const scoreOne = async (\n model: string,\n input: { artifact: unknown; scenario?: unknown },\n ): Promise<JudgeVerdict<D>> => {\n if (opts.retry) {\n const outcome = await withJudgeRetry((m) => opts.scoreWith(m, input), {\n ...opts.retry,\n models: [model],\n })\n if (!outcome.succeeded || outcome.value === null) {\n return {\n model,\n perDimension: null,\n rationale: outcome.error?.message ?? 'judge failed after retries',\n }\n }\n return outcome.value\n }\n try {\n return await opts.scoreWith(model, input)\n } catch (err) {\n return {\n model,\n perDimension: null,\n rationale: err instanceof Error ? err.message : String(err),\n }\n }\n }\n\n return {\n name: opts.name,\n dimensions: opts.dimensions.map((d) => ({ key: d, description: d })),\n async score({ artifact, scenario }): Promise<JudgeScore> {\n const input = { artifact, scenario }\n const verdicts = await Promise.all(opts.models.map((model) => scoreOne(model, input)))\n // All-failed throws here — propagate so the engine records a failed cell.\n const agg = aggregateJudgeVerdicts(verdicts, opts.dimensions, opts.weights)\n const score: JudgeScore = {\n dimensions: agg.perDimension,\n composite: agg.composite,\n notes: agg.rationale,\n maxDisagreement: agg.maxDisagreement,\n perJudge: agg.perJudge,\n }\n if (agg.failedJudges.length > 0) score.failedJudges = agg.failedJudges\n return score\n },\n }\n}\n","import { cpus } from 'node:os'\nimport {\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 * Max concurrent judge subprocesses. Each spec spawns its own subprocess\n * via the driver, so unbounded fan-out exhausts file descriptors / PIDs.\n * Defaults to the host CPU count. Ignored when `parallel === false`.\n */\n concurrency?: number\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 const concurrency = Math.max(1, options.concurrency ?? cpus().length)\n const results: SandboxJudgeResult[] = new Array(specs.length)\n let cursor = 0\n async function worker(): Promise<void> {\n while (true) {\n const i = cursor++\n if (i >= specs.length) return\n results[i] = await runner.run(specs[i]!)\n }\n }\n await Promise.all(Array.from({ length: Math.min(concurrency, specs.length) }, () => worker()))\n return results\n}\n\n/** Build a `SandboxJudgeSpec` that scores whether the harness compiles without errors. */\nexport function compilerJudge(id: string, config: HarnessConfig): SandboxJudgeSpec {\n return { id, kind: 'compiler', config }\n}\n\n/** Build a `SandboxJudgeSpec` that scores the harness by its test-suite pass rate. */\nexport function testJudge(id: string, config: HarnessConfig): SandboxJudgeSpec {\n return { id, kind: 'test', config }\n}\n\n/** Build a `SandboxJudgeSpec` that scores the harness by linter rule violations. */\nexport function linterJudge(id: string, config: HarnessConfig): SandboxJudgeSpec {\n return { id, kind: 'linter', config }\n}\n\n/** Build a `SandboxJudgeSpec` that scores the harness output for security issues via a security scanner. */\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 * 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 roles = Object.entries(bundle.rolePrompts ?? {}).sort(([a], [b]) => a.localeCompare(b))\n for (const [name, role] of roles) {\n lines.push(`role:${name}:system:${role.system ?? ''}:append:${role.append ?? ''}`)\n }\n const skills = [...(bundle.skills ?? [])].sort()\n if (skills.length) lines.push(`skills:${skills.join(',')}`)\n return lines.join('\\n')\n}\n","import { type AxAIService, AxGEPA, ai, ax } from '@ax-llm/ax'\nimport { 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 /** Runnable handle on the trained classifier. Present only when the\n * ax-gepa backend completed training; calls the optimized selector\n * program via ax's `forward`. */\n selectVariant?: (row: {\n task: string\n split: string\n seedPreview: string\n }) => Promise<{ variantId: string; rationale: string }>\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 minScenarioWinners?: number\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 minScenarioWinners = this.config.minScenarioWinners ?? 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 < minScenarioWinners) {\n return {\n ...fallback,\n backend: 'ax-gepa',\n skipped: true,\n rationale: `AxGEPA skipped: need >=2 variants and >=${minScenarioWinners} scenario winners, got ${variantIds.length} variant(s) and ${byScenario.length} scenario winner(s).`,\n }\n }\n\n const signature = `task:string, split:string, seedPreview:string -> variantId:class \"${variantIds.join(', ')}\", rationale:string`\n const selector = ax<\n { task: string; split: string; seedPreview: string },\n { variantId: string; rationale?: string }\n >(signature, {\n description: 'Choose the best steering bundle variant for an autopilot task.',\n })\n const shuffled = seededShuffle(byScenario, signature)\n const splitIndex = Math.max(1, Math.floor(shuffled.length * 0.8))\n const train = shuffled.slice(0, splitIndex)\n const validation = shuffled.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 studentAI = createAxService(this.config.provider, this.config.apiKey, this.config.model)\n const optimizer = new AxGEPA({\n studentAI,\n teacherAI: createAxService(\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 (input: { prediction?: { variantId?: string }; example?: ScenarioWinner }) =>\n input.prediction?.variantId === input.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 // After applyOptimization the `selector` program carries the trained\n // weights; the closure runs it through ax's `forward` so the caller can\n // classify unseen tasks rather than only read a description string.\n const selectVariant = async (row: { task: string; split: string; seedPreview: string }) => {\n const prediction = await selector.forward(studentAI, row)\n return {\n variantId: String(prediction.variantId),\n rationale: String(prediction.rationale ?? ''),\n }\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 selectVariant,\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 provider: 'openai' | 'anthropic',\n apiKey: string,\n model: string,\n): AxAIService {\n return ai({\n name: provider,\n apiKey,\n config: { model },\n })\n}\n\n// Deterministic Fisher-Yates driven by a seeded mulberry32 PRNG. Seeding from\n// a stable value (the signature) keeps train/validation splits reproducible\n// across runs while removing positional skew when rows arrive grouped.\nfunction seededShuffle<T>(items: readonly T[], seed: string): T[] {\n const rng = mulberry32(hashString(seed))\n const out = [...items]\n for (let i = out.length - 1; i > 0; i--) {\n const j = Math.floor(rng() * (i + 1))\n ;[out[i], out[j]] = [out[j]!, out[i]!]\n }\n return out\n}\n\nfunction hashString(value: string): number {\n let h = 2166136261\n for (let i = 0; i < value.length; i++) {\n h ^= value.charCodeAt(i)\n h = Math.imul(h, 16777619)\n }\n return h >>> 0\n}\n\nfunction mulberry32(seed: number): () => number {\n let a = seed >>> 0\n return () => {\n a = (a + 0x6d2b79f5) | 0\n let t = Math.imul(a ^ (a >>> 15), 1 | a)\n t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296\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 * Hidden-criteria grading firewall — grade an agent on criteria it never saw.\n *\n * A trustworthy benchmark splits every scenario's data by WHERE each field is\n * allowed to flow, then proves the held-out / judge-only fields never reach the\n * agent during the run. The coding bench expresses this with four destinations\n * (prompt / develop-against / held-out suite / rubric); this module lifts the\n * domain-FREE core out of it so research, legal, tax, content — any domain —\n * can declare the same routing and get the same firewall enforcement and the\n * same held-out-weighted composite, plugging in its OWN grader.\n *\n * Two reusable pieces, both domain-agnostic:\n *\n * 1. FIELD ROUTING BY DESTINATION. A scenario declares each field's\n * `FieldDestination`; `assertNoHiddenLeak` is a pure checker that throws if\n * a grading-only or judge-only field's value appears in what reaches the\n * agent. The domain decides which fields exist and where they go — the\n * substrate only enforces \"hidden stays hidden\".\n *\n * 2. HIDDEN-CRITERIA GRADING. The domain supplies its own grader\n * `(artifact, hiddenCriteria) => { passRate, total }` — the coding\n * node-test executor is ONE such grader a consumer plugs in; the substrate\n * bakes in NO node/test/TS/exec/regex. `gradeOnHidden` runs that grader\n * behind the firewall and `blendHeldout` composes its pass rate with a\n * judge score into the final number the leaderboard ranks on.\n *\n * Shape mirrors `treatment-gate`/`authenticity`: pure predicates and pure\n * composition over already-computed values, fail-loud, with the\n * \"which field / which weight / which grader\" decisions left as parameters and\n * no domain literal anywhere in the module.\n *\n * Lives next to `test-graded-scenario` and `partition-held-out` — it is a\n * scorecard/grading concept that makes sense without a running agent loop.\n */\n\nimport type { JudgeScore } from './campaign/types'\nimport { ValidationError } from './errors'\n\n// ── 1. field routing by destination ──────────────────────────────────────────\n\n/**\n * Where one scenario field is allowed to flow. The firewall guarantee is keyed\n * on this tag, not on a field name — a domain can have any number of fields per\n * destination.\n *\n * - `agent-visible` reaches the agent's context during the run (the prompt,\n * the task statement — what the agent reads to act).\n * - `develop-against` seeded into the agent's environment during the run so it\n * can iterate (a visible example/test/reference). The\n * agent MAY read it — that is intentional (real TDD). Not\n * a leak: it is example-grade, not the grading criteria.\n * - `grading-only` the hidden criteria. Used ONLY at grading, after the run\n * — the held-out suite / answer key / hidden requirements.\n * Must NEVER reach the agent context. This is what makes a\n * good score un-memorizable.\n * - `judge-only` grading context for the judge only (rubric anchors,\n * design intent). Lives with the judge, never in the agent\n * context.\n */\nexport type FieldDestination = 'agent-visible' | 'develop-against' | 'grading-only' | 'judge-only'\n\n/** The destinations a value must be kept OUT of the agent context for. */\nconst hiddenDestinations: ReadonlySet<FieldDestination> = new Set<FieldDestination>([\n 'grading-only',\n 'judge-only',\n])\n\n/** True for the destinations whose values must never reach the agent context. */\nexport function isHiddenDestination(destination: FieldDestination): boolean {\n return hiddenDestinations.has(destination)\n}\n\n/**\n * A scenario's fields routed by destination. The domain owns the field set\n * (`TFields` — a record of its named fields to their string-renderable values)\n * and declares one `FieldDestination` per field. `routeFields` builds this from\n * a domain's `(value, destination)` map; the firewall reads it.\n */\nexport interface RoutedField {\n /** The field's name — for diagnostics only. */\n name: string\n /** The field's value as it would be rendered into text. The firewall compares\n * this against the agent context, so a domain that ships structured data\n * passes a stable string projection (e.g. JSON) of the hidden value. */\n value: string\n destination: FieldDestination\n}\n\n/**\n * Route a domain's named fields by destination into the firewall's input shape.\n * The `routing` declares each field's destination; the `values` carry each\n * field's renderable string. A field present in `routing` but missing from\n * `values` is an authoring error (fail loud) — every routed field must have a\n * value the firewall can check.\n */\nexport function routeFields<TName extends string>(\n routing: Readonly<Record<TName, FieldDestination>>,\n values: Readonly<Record<TName, string>>,\n): RoutedField[] {\n const out: RoutedField[] = []\n for (const name of Object.keys(routing) as TName[]) {\n const value = values[name]\n if (value === undefined) {\n throw new ValidationError(\n `routed field \"${name}\" has a destination but no value — every routed field must carry its value`,\n )\n }\n out.push({ name, value, destination: routing[name] })\n }\n return out\n}\n\n/** A single detected leak: a hidden field whose value appears in the agent context. */\nexport interface HiddenLeak {\n field: string\n destination: FieldDestination\n}\n\nexport interface NoLeakOptions {\n /** Minimum hidden-value length to check. A hidden value shorter than this is\n * skipped — a one-word or empty hidden field would substring-match innocuous\n * prose and is not meaningful evidence of a leak. Default 12. */\n minMatchLength?: number\n}\n\n/**\n * The FIREWALL. Throws `ValidationError` if any `grading-only`/`judge-only`\n * field's value is found inside `agentContext` — the exact text that reaches the\n * agent during the run (its prompt, its seeded files concatenated, whatever the\n * caller assembled). `agent-visible` and `develop-against` fields are never\n * checked: they are meant to be there.\n *\n * Substring containment is the check: it is domain-free and catches the failure\n * that matters — a hidden answer key, held-out case, or rubric anchor pasted\n * into the prompt. Returns the routed fields on success so a caller can chain.\n */\nexport function assertNoHiddenLeak(\n fields: readonly RoutedField[],\n agentContext: string,\n opts: NoLeakOptions = {},\n): readonly RoutedField[] {\n const minLen = opts.minMatchLength ?? 12\n const leaks: HiddenLeak[] = []\n for (const field of fields) {\n if (!isHiddenDestination(field.destination)) continue\n const needle = field.value.trim()\n if (needle.length < minLen) continue\n if (agentContext.includes(needle)) {\n leaks.push({ field: field.name, destination: field.destination })\n }\n }\n if (leaks.length > 0) {\n const detail = leaks.map((l) => `\"${l.field}\" (${l.destination})`).join(', ')\n throw new ValidationError(\n `hidden-criteria firewall breached: ${leaks.length} hidden field(s) reached the agent context: ${detail}`,\n )\n }\n return fields\n}\n\n/** Collect the values a domain may safely render into the agent context — the\n * `agent-visible` (and, by intent, `develop-against`) fields — so a caller can\n * ASSEMBLE the context from the routing rather than hand-picking fields and\n * risking a slip. `develop-against` is included because it is seeded into the\n * agent's environment during the run on purpose. */\nexport function agentVisibleFields(fields: readonly RoutedField[]): RoutedField[] {\n return fields.filter((f) => !isHiddenDestination(f.destination))\n}\n\n// ── 2. hidden-criteria grading ────────────────────────────────────────────────\n\n/** What a hidden-criteria grader reports. `passRate = passed / total` over the\n * hidden checks; `total === 0` means the criteria never ran (e.g. the artifact\n * did not even load) — an honest zero, never a spurious pass. */\nexport interface HiddenGradeResult {\n /** Hidden checks that passed. */\n passed: number\n /** Total hidden checks attempted. 0 when the criteria could not run at all. */\n total: number\n /** `passed / total`, or 0 when `total === 0`. The PRIMARY correctness score. */\n passRate: number\n /** Free-form provenance the caller may record (runner output, reason for 0). */\n notes?: string\n}\n\n/**\n * The domain's grader: given the agent's artifact and the HIDDEN criteria,\n * return a pass rate. This is the ONE seam a non-coding domain implements — the\n * coding node-test executor is a single implementation of it; a legal grader\n * checks the brief against hidden required holdings, a research grader checks an\n * answer against held-out facts, a tax grader runs hidden return assertions.\n * The substrate calls it ONLY at grading time, behind the firewall.\n *\n * `THidden` is the domain's hidden-criteria payload (the held-out suite, the\n * answer key, the hidden requirements) — opaque to the substrate.\n */\nexport type HiddenCriteriaGrader<TArtifact, THidden> = (\n artifact: TArtifact,\n hiddenCriteria: THidden,\n signal?: AbortSignal,\n) => Promise<HiddenGradeResult> | HiddenGradeResult\n\n/** Normalize a grader's raw `{passed, total}` into a `HiddenGradeResult` with a\n * consistent, fail-loud `passRate` — the canonical \"honest zero on no-run\"\n * rule, single-sourced so every domain grader gets it. */\nexport function hiddenGrade(passed: number, total: number, notes?: string): HiddenGradeResult {\n const p = Number.isFinite(passed) && passed > 0 ? Math.floor(passed) : 0\n const t = Number.isFinite(total) && total > 0 ? Math.floor(total) : 0\n const passRate = t > 0 ? Math.min(1, p / t) : 0\n return { passed: Math.min(p, t > 0 ? t : p), total: t, passRate, notes }\n}\n\n/**\n * Run a domain's hidden-criteria grader behind the firewall. Before grading, it\n * re-asserts the firewall against the agent context the run actually used —\n * proving (at grading time, on real data) that the hidden criteria never\n * reached the agent — then invokes the grader and returns its pass rate. A\n * domain that wants the firewall and the grader wired together in one call uses\n * this; a domain that already asserted the firewall at dispatch time can call\n * its grader directly and feed the result to `blendHeldout`.\n */\nexport async function gradeOnHidden<TArtifact, THidden>(args: {\n artifact: TArtifact\n hiddenCriteria: THidden\n grader: HiddenCriteriaGrader<TArtifact, THidden>\n /** The routed fields + the exact agent context, re-checked before grading. */\n firewall: { fields: readonly RoutedField[]; agentContext: string; options?: NoLeakOptions }\n signal?: AbortSignal\n}): Promise<HiddenGradeResult> {\n assertNoHiddenLeak(args.firewall.fields, args.firewall.agentContext, args.firewall.options)\n const result = await args.grader(args.artifact, args.hiddenCriteria, args.signal)\n return hiddenGrade(result.passed, result.total, result.notes)\n}\n\n// ── the composite: hidden correctness (PRIMARY) + judge quality (secondary) ────\n\n/** Weights for the held-out / judge blend. Must be finite and non-negative;\n * they are renormalized to sum to 1 so a caller can pass any positive ratio. */\nexport interface BlendWeights {\n /** Weight on the hidden-criteria pass rate (the primary, ungameable score). */\n heldout: number\n /** Weight on the judge's quality composite (the secondary style/quality score). */\n judge: number\n}\n\n/** Default blend: 0.7 hidden correctness, 0.3 judge quality. The coding bench's\n * long-standing split — execution truth dominates, style refines. */\nexport const defaultBlendWeights: BlendWeights = { heldout: 0.7, judge: 0.3 }\n\n/** The input shape a judge's `score` receives — exactly `JudgeConfig.score`'s\n * argument: the artifact, plus any scenario/signal fields the judge carries.\n * `withHeldoutBlend` only reads `artifact`; the rest rides through. */\nexport interface JudgeScoreInput<TArtifact> {\n artifact: TArtifact\n /** Pass-through for the judge's extra input fields (scenario, signal). */\n [key: string]: unknown\n}\n\nfunction normalizeWeights(weights: BlendWeights): { heldout: number; judge: number } {\n const h = Number.isFinite(weights.heldout) && weights.heldout >= 0 ? weights.heldout : 0\n const j = Number.isFinite(weights.judge) && weights.judge >= 0 ? weights.judge : 0\n const sum = h + j\n if (sum <= 0) {\n throw new ValidationError(\n 'blend weights must have a positive sum (got heldout+judge <= 0) — cannot weight a composite by zero',\n )\n }\n return { heldout: h / sum, judge: j / sum }\n}\n\n/**\n * Compose the PRIMARY hidden-criteria pass rate with the SECONDARY judge\n * composite into the single score the leaderboard ranks on. Weights are\n * renormalized, so a solution that fails the hidden criteria is capped low no\n * matter how the judge felt about its style, while a stylistically-mediocre but\n * CORRECT solution still earns the bulk of the points. Both inputs are clamped\n * to [0,1] — a judge on a non-unit scale must be normalized by the caller first.\n */\nexport function blendHeldout(\n heldoutPassRate: number,\n judgeScore: number,\n weights: BlendWeights = defaultBlendWeights,\n): number {\n const w = normalizeWeights(weights)\n const heldout = clampUnit(heldoutPassRate)\n const judge = clampUnit(judgeScore)\n return w.heldout * heldout + w.judge * judge\n}\n\n/**\n * Wrap a judge's `score` so the `composite` it REPORTS is the held-out-weighted\n * blend. The judge still scores its quality dimensions (recorded, secondary),\n * but the composite that downstream selection/scorecard reads becomes\n * `blendHeldout(heldoutPassRate(artifact), judgeComposite, weights)`. The held-\n * out pass rate is read off the artifact via `heldoutPassRate` — already\n * computed before the judge runs — so no second grading pass is needed.\n *\n * Generic over the artifact type, inferred from `heldoutPassRate`, so it\n * composes with both a `campaign` `JudgeConfig.score` and a bare scoring\n * function. The input is the judge's `{ artifact, ... }` — any extra fields\n * (`scenario`, `signal`) ride through untouched via the index signature.\n */\nexport function withHeldoutBlend<TArtifact>(\n score: (input: JudgeScoreInput<TArtifact>) => JudgeScore | Promise<JudgeScore>,\n heldoutPassRate: (artifact: TArtifact) => number,\n weights: BlendWeights = defaultBlendWeights,\n): (input: JudgeScoreInput<TArtifact>) => Promise<JudgeScore> {\n return async (input: JudgeScoreInput<TArtifact>): Promise<JudgeScore> => {\n const base = await score(input)\n if (base.failed) return base\n const rate = clampUnit(heldoutPassRate(input.artifact))\n const composite = blendHeldout(rate, base.composite, weights)\n const w = normalizeWeights(weights)\n return {\n ...base,\n composite,\n notes:\n `composite=${composite.toFixed(3)} ` +\n `(held-out ${(rate * 100).toFixed(0)}% × ${w.heldout.toFixed(2)} + ` +\n `quality ${base.composite.toFixed(3)} × ${w.judge.toFixed(2)})` +\n (base.notes ? ` — ${base.notes}` : ''),\n }\n }\n}\n\nfunction clampUnit(value: number): number {\n if (!Number.isFinite(value)) return 0\n return Math.max(0, Math.min(1, value))\n}\n","/**\n * CostLedger — per-run token + USD accounting with an explicit `costUnknown`\n * axis, folded over the substrate's pricing resolver.\n *\n * `estimateCost` already resolves a model id to a price (exact table, then\n * family regex) and warns-once on a miss, but it returns 0 for an unpriced\n * model — indistinguishable downstream from a genuinely free run. Four\n * consumers re-wrap it to surface that distinction (physim's `costForUsage` /\n * `modelPriceKey` is the cleanest), and to bucket spend by \"channel\" (the\n * logical role of the call: agent / judge / verifier / …) so a dashboard can\n * answer \"how much did judging cost vs the agent itself?\".\n *\n * This is the canonical version. `modelPriceKey` exposes the resolver's verdict\n * as a stable key (or null). `CostLedger` folds usage records into per-channel\n * and total rollups, tracks `unpricedModels` so a $0 is never mistaken for a\n * measured zero, and computes cost-per-completed-task.\n */\n\nimport { ValidationError } from './errors'\nimport { estimateCost, isModelPriced, resolveModelPricing } from './metrics'\n\n/** Logical role of an LLM call. Free-form union — consumers add their own\n * channels; the rollup keys on whatever string is supplied. */\nexport type CostChannel = 'agent' | 'judge' | 'verifier' | 'analyst' | 'driver' | (string & {})\n\nexport interface CostUsage {\n inputTokens: number\n outputTokens: number\n cachedTokens?: number\n}\n\n/**\n * Resolve a model id to the stable pricing key the substrate's `MODEL_PRICING`\n * / family resolver would use, or null when the id is unpriced. A non-null\n * return means `estimateCost` will produce a real number for this id; null\n * means any cost computed is `costUnknown` and the 0 must not aggregate as a\n * measured cost.\n */\nexport function modelPriceKey(model: string): string | null {\n return isModelPriced(model) ? model : null\n}\n\nexport interface CostResult {\n costUsd: number\n /** True when `model` has no pricing — the 0 is \"not priced\", NOT \"free\". */\n costUnknown: boolean\n}\n\n/**\n * Cost for one usage record. Resolves pricing via the substrate resolver and\n * flags `costUnknown` when the model is unpriced so the 0 is observable rather\n * than silently emitted as a measured cost. Cached tokens are billed at the\n * model's input rate when present (no separate cache-discount table — callers\n * that need provider-specific cache pricing supply `actualCostUsd` upstream).\n */\nexport function costForUsage(model: string, usage: CostUsage): CostResult {\n assertNonNegative(usage.inputTokens, 'inputTokens')\n assertNonNegative(usage.outputTokens, 'outputTokens')\n if (usage.cachedTokens !== undefined) assertNonNegative(usage.cachedTokens, 'cachedTokens')\n const pricing = resolveModelPricing(model)\n if (!pricing) return { costUsd: 0, costUnknown: true }\n const billedInput = usage.inputTokens + (usage.cachedTokens ?? 0)\n return { costUsd: estimateCost(billedInput, usage.outputTokens, model), costUnknown: false }\n}\n\nexport interface CostLedgerEntry extends CostUsage {\n model: string\n channel: CostChannel\n costUsd: number\n costUnknown: boolean\n /** Override the estimate with an observed provider cost. */\n actualCostUsd?: number\n /** Free-form tags (scenario id, variant id, round, …). */\n tags?: Record<string, string>\n timestamp: number\n}\n\nexport interface ChannelRollup {\n channel: CostChannel\n calls: number\n inputTokens: number\n outputTokens: number\n cachedTokens: number\n costUsd: number\n /** Calls whose model was unpriced (their costUsd is 0-but-unknown). */\n unpricedCalls: number\n}\n\nexport interface CostLedgerSummary {\n totalCalls: number\n inputTokens: number\n outputTokens: number\n cachedTokens: number\n totalCostUsd: number\n /** Per-channel breakdown, sorted by channel name. */\n byChannel: ChannelRollup[]\n /** Distinct unpriced model ids seen — non-empty means totalCostUsd is a\n * lower bound (some calls priced to an unknown 0). */\n unpricedModels: string[]\n /** True when no unpriced model was charged — totalCostUsd is then exact. */\n fullyPriced: boolean\n}\n\n/**\n * Append-only ledger of LLM spend for a single run. Record each call with its\n * channel; read per-channel and total rollups plus the unpriced-model set.\n * Pure accounting — no I/O. The `markCompleted` / `costPerCompletedTask` pair\n * answers \"dollars per finished task\", the metric every optimizer's\n * quality-vs-cost tradeoff needs.\n */\nexport class CostLedger {\n private readonly entries: CostLedgerEntry[] = []\n private completedTasks = 0\n\n /**\n * Record one LLM call. The cost is computed from pricing unless\n * `actualCostUsd` is supplied (a finite observed cost from the provider\n * response), in which case `costUnknown` is false regardless of pricing.\n */\n record(input: {\n model: string\n channel: CostChannel\n usage: CostUsage\n actualCostUsd?: number\n tags?: Record<string, string>\n timestamp?: number\n }): CostLedgerEntry {\n const { costUsd, costUnknown } = costForUsage(input.model, input.usage)\n const hasActual =\n typeof input.actualCostUsd === 'number' && Number.isFinite(input.actualCostUsd)\n if (hasActual) assertNonNegative(input.actualCostUsd as number, 'actualCostUsd')\n const entry: CostLedgerEntry = {\n model: input.model,\n channel: input.channel,\n inputTokens: input.usage.inputTokens,\n outputTokens: input.usage.outputTokens,\n cachedTokens: input.usage.cachedTokens,\n costUsd: hasActual ? (input.actualCostUsd as number) : costUsd,\n costUnknown: hasActual ? false : costUnknown,\n actualCostUsd: hasActual ? (input.actualCostUsd as number) : undefined,\n tags: input.tags,\n timestamp: input.timestamp ?? Date.now(),\n }\n this.entries.push(entry)\n return entry\n }\n\n /** Increment the completed-task counter (used for cost-per-completed-task). */\n markCompleted(count = 1): void {\n if (!Number.isInteger(count) || count < 0) {\n throw new ValidationError(\n `CostLedger.markCompleted: count must be a non-negative integer, got ${count}`,\n )\n }\n this.completedTasks += count\n }\n\n list(): CostLedgerEntry[] {\n return [...this.entries]\n }\n\n summary(): CostLedgerSummary {\n const byChannel = new Map<string, ChannelRollup>()\n const unpriced = new Set<string>()\n let totalCost = 0\n let inputTokens = 0\n let outputTokens = 0\n let cachedTokens = 0\n for (const e of this.entries) {\n totalCost += e.costUsd\n inputTokens += e.inputTokens\n outputTokens += e.outputTokens\n cachedTokens += e.cachedTokens ?? 0\n if (e.costUnknown) unpriced.add(e.model)\n const roll = byChannel.get(e.channel) ?? {\n channel: e.channel,\n calls: 0,\n inputTokens: 0,\n outputTokens: 0,\n cachedTokens: 0,\n costUsd: 0,\n unpricedCalls: 0,\n }\n roll.calls += 1\n roll.inputTokens += e.inputTokens\n roll.outputTokens += e.outputTokens\n roll.cachedTokens += e.cachedTokens ?? 0\n roll.costUsd += e.costUsd\n if (e.costUnknown) roll.unpricedCalls += 1\n byChannel.set(e.channel, roll)\n }\n return {\n totalCalls: this.entries.length,\n inputTokens,\n outputTokens,\n cachedTokens,\n totalCostUsd: totalCost,\n byChannel: [...byChannel.values()].sort((a, b) => a.channel.localeCompare(b.channel)),\n unpricedModels: [...unpriced].sort(),\n fullyPriced: unpriced.size === 0,\n }\n }\n\n /** Total spend divided by completed tasks; null when nothing completed. */\n costPerCompletedTask(): number | null {\n if (this.completedTasks === 0) return null\n return this.summary().totalCostUsd / this.completedTasks\n }\n}\n\nfunction assertNonNegative(n: number, name: string): void {\n if (!Number.isFinite(n) || n < 0) {\n throw new ValidationError(`CostLedger: ${name} must be a non-negative finite number, got ${n}`)\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 * EvalTraceStore — JSONL save / query / compare over the analysis-time\n * `RunRecord` row.\n *\n * `FileSystemTraceStore` (in `./trace/store`) persists the rich TraceSchema-v1\n * span corpus — runs, spans, events, artifacts — the runtime emits live. That\n * is NOT the thing three consumers hand-roll in `tests/eval/lib/trace-store.ts`.\n * What they hand-roll is the *analysis* layer: append each finished run as one\n * JSONL line keyed by scenario/candidate, then query it (\"every run where score\n * < 50\"), pick the best run for a scenario (few-shot seeding), and compare two\n * candidates on matched scenarios.\n *\n * The substrate already has the canonical analysis-time row — `RunRecord` — so\n * this is that query/compare API expressed over `RunRecord[]`, with a\n * JSONL-backed store. It does NOT fork `FileSystemTraceStore`; it sits beside it\n * for the analysis projection.\n */\n\nimport { ValidationError } from './errors'\nimport { isRunRecord, type RunRecord, type RunSplitTag, validateRunRecord } from './run-record'\n\n/** The score the query/compare layer ranks on: holdout when present (the\n * gated number), else search. Throws when a record carries neither — a\n * RunRecord is invalid without at least one, but a hand-built object might. */\nexport function runScore(record: RunRecord): number {\n const { holdoutScore, searchScore } = record.outcome\n if (typeof holdoutScore === 'number') return holdoutScore\n if (typeof searchScore === 'number') return searchScore\n throw new ValidationError(\n `EvalTraceStore: run ${record.runId} has neither holdoutScore nor searchScore`,\n )\n}\n\nexport interface RunRecordFilter {\n experimentId?: string\n candidateId?: string\n scenarioId?: string\n model?: string\n splitTag?: RunSplitTag\n /** Inclusive lower bound on `runScore`. */\n minScore?: number\n /** Inclusive upper bound on `runScore`. */\n maxScore?: number\n /** Match a single tag in `outcome.raw` by exact numeric value. */\n rawEquals?: { key: string; value: number }\n /** Custom predicate, ANDed with the structured filters. */\n where?: (record: RunRecord) => boolean\n}\n\nfunction matches(record: RunRecord, f: RunRecordFilter): boolean {\n if (f.experimentId && record.experimentId !== f.experimentId) return false\n if (f.candidateId && record.candidateId !== f.candidateId) return false\n if (f.scenarioId && record.scenarioId !== f.scenarioId) return false\n if (f.model && record.model !== f.model) return false\n if (f.splitTag && record.splitTag !== f.splitTag) return false\n if (f.minScore !== undefined && runScore(record) < f.minScore) return false\n if (f.maxScore !== undefined && runScore(record) > f.maxScore) return false\n if (f.rawEquals && record.outcome.raw[f.rawEquals.key] !== f.rawEquals.value) return false\n if (f.where && !f.where(record)) return false\n return true\n}\n\nexport interface CandidateComparison {\n a: string\n b: string\n /** Scenario ids present for BOTH candidates — the paired comparison set. */\n pairedScenarioIds: string[]\n /** Mean `runScore` for candidate a over the paired scenarios. */\n meanA: number\n /** Mean `runScore` for candidate b over the paired scenarios. */\n meanB: number\n /** meanB − meanA. Positive ⇒ b scored higher on the matched scenarios. */\n meanDelta: number\n /** Scenarios where b beat a (strictly), tied, and a beat b. */\n bWins: number\n ties: number\n aWins: number\n}\n\n/**\n * Backing persistence for `EvalTraceStore`. The in-memory store is the default;\n * the JSONL file store appends one validated `RunRecord` per line. Both keep an\n * append order so `getBest` / `compareRuns` are reproducible.\n */\nexport interface RunRecordBackend {\n append(record: RunRecord): Promise<void>\n load(): Promise<RunRecord[]>\n}\n\nexport function inMemoryRunRecordBackend(initial: RunRecord[] = []): RunRecordBackend {\n const rows = initial.map((r) => validateRunRecord(r))\n return {\n async append(record) {\n rows.push(record)\n },\n async load() {\n return [...rows]\n },\n }\n}\n\n/**\n * JSONL-backed store at `path`, one `RunRecord` per line. Malformed lines fail\n * loud on load (a corrupt corpus must not silently shrink the analysis set);\n * pass `skipInvalid` only for forensics on a known-bad file.\n */\nexport function jsonlRunRecordBackend(\n path: string,\n opts: { skipInvalid?: boolean } = {},\n): RunRecordBackend {\n return {\n async append(record) {\n const fs = await import('node:fs/promises')\n const pathMod = await import('node:path')\n await fs.mkdir(pathMod.dirname(path), { recursive: true })\n await fs.appendFile(path, `${JSON.stringify(record)}\\n`, 'utf8')\n },\n async load() {\n const fs = await import('node:fs/promises')\n let raw: string\n try {\n raw = await fs.readFile(path, 'utf8')\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') return []\n throw err\n }\n const out: RunRecord[] = []\n let lineNo = 0\n for (const line of raw.split('\\n')) {\n lineNo++\n if (!line.trim()) continue\n let parsed: unknown\n try {\n parsed = JSON.parse(line)\n } catch (err) {\n if (opts.skipInvalid) continue\n throw new ValidationError(`EvalTraceStore: ${path}:${lineNo} is not valid JSON`)\n }\n if (opts.skipInvalid) {\n if (isRunRecord(parsed)) out.push(parsed)\n continue\n }\n try {\n out.push(validateRunRecord(parsed))\n } catch (err) {\n throw new ValidationError(\n `EvalTraceStore: ${path}:${lineNo} is not a valid RunRecord — ${(err as Error).message}`,\n )\n }\n }\n return out\n },\n }\n}\n\n/**\n * Query / compare layer over a `RunRecord` corpus. Append finished runs, query\n * with a structured filter, take the best run for a scenario, and compare two\n * candidates on their matched scenarios. Persistence is injected via\n * `RunRecordBackend` (in-memory by default, JSONL file via\n * `jsonlRunRecordBackend`).\n */\nexport class EvalTraceStore {\n private readonly backend: RunRecordBackend\n\n constructor(backend: RunRecordBackend = inMemoryRunRecordBackend()) {\n this.backend = backend\n }\n\n /** Validate and append one run. Throws on an invalid record — the corpus\n * stays paper-grade. */\n async append(record: RunRecord): Promise<void> {\n await this.backend.append(validateRunRecord(record))\n }\n\n async all(): Promise<RunRecord[]> {\n return this.backend.load()\n }\n\n async query(filter: RunRecordFilter = {}): Promise<RunRecord[]> {\n const rows = await this.backend.load()\n return rows.filter((r) => matches(r, filter))\n }\n\n /**\n * Highest-scoring run for a scenario (optionally restricted to a candidate).\n * Returns null when no run matches. Ties resolve to the earliest-appended run\n * so the result is stable.\n */\n async getBest(\n scenarioId: string,\n opts: { candidateId?: string; splitTag?: RunSplitTag } = {},\n ): Promise<RunRecord | null> {\n const rows = await this.query({\n scenarioId,\n candidateId: opts.candidateId,\n splitTag: opts.splitTag,\n })\n if (rows.length === 0) return null\n let best = rows[0]!\n let bestScore = runScore(best)\n for (let i = 1; i < rows.length; i++) {\n const s = runScore(rows[i]!)\n if (s > bestScore) {\n best = rows[i]!\n bestScore = s\n }\n }\n return best\n }\n\n /**\n * Compare two candidates on the scenarios they BOTH ran. When a candidate\n * ran a scenario more than once, its best `runScore` for that scenario is\n * used. Throws when there is no paired scenario — an unpaired \"comparison\" is\n * not one.\n */\n async compareRuns(candidateA: string, candidateB: string): Promise<CandidateComparison> {\n if (candidateA === candidateB) {\n throw new ValidationError(\n `EvalTraceStore.compareRuns: candidates must differ (\"${candidateA}\")`,\n )\n }\n const rows = await this.backend.load()\n const bestByScenario = (candidate: string): Map<string, number> => {\n const m = new Map<string, number>()\n for (const r of rows) {\n if (r.candidateId !== candidate) continue\n const sid = r.scenarioId\n if (!sid) continue\n const s = runScore(r)\n const prev = m.get(sid)\n if (prev === undefined || s > prev) m.set(sid, s)\n }\n return m\n }\n const aScores = bestByScenario(candidateA)\n const bScores = bestByScenario(candidateB)\n const paired = [...aScores.keys()].filter((sid) => bScores.has(sid)).sort()\n if (paired.length === 0) {\n throw new ValidationError(\n `EvalTraceStore.compareRuns: \"${candidateA}\" and \"${candidateB}\" share no scenario (need scenarioId on records)`,\n )\n }\n let sumA = 0\n let sumB = 0\n let bWins = 0\n let aWins = 0\n let ties = 0\n for (const sid of paired) {\n const sa = aScores.get(sid)!\n const sb = bScores.get(sid)!\n sumA += sa\n sumB += sb\n if (sb > sa) bWins++\n else if (sb < sa) aWins++\n else ties++\n }\n const meanA = sumA / paired.length\n const meanB = sumB / paired.length\n return {\n a: candidateA,\n b: candidateB,\n pairedScenarioIds: paired,\n meanA,\n meanB,\n meanDelta: meanB - meanA,\n bWins,\n ties,\n aWins,\n }\n }\n}\n","/**\n * Experiment tracker — git-provenanced experiment log with N-rep stats and a\n * KEEP / REGRESSION / NOISE verdict against a parent.\n *\n * Every loop the fleet runs reduces to the same question: \"I ran the candidate\n * N times — is the median measurably better than the parent, or is the delta\n * inside the noise band?\" The hand-rolled copies bake a fixed score scale\n * (percentage points), a fixed store path (`.evolve/experiments-v2.json`), and\n * `execSync('git …')` straight into the module. This is the canonical version:\n * provenance and persistence are injected, thresholds are configurable, and the\n * stats + verdict are pure functions you can unit-test without a git repo or a\n * filesystem.\n *\n * Stats per experiment: median / mean / min / max / iqr / stddev / passRate /\n * n, plus a `stable` flag (`iqr < iqrUnstableAbove && stddev < stddevUnstableAbove`).\n *\n * Verdict against a parent (both must have `n >= minRepsForVerdict`):\n * - NOISE — the candidate is too unstable to judge (`!stable`)\n * - KEEP — `medianDelta > keepThreshold`\n * - REGRESSION — `medianDelta < -regressionThreshold`\n * - NOISE — otherwise (delta inside the band)\n * With no parent (or insufficient reps) the verdict is the neutral ITERATE.\n */\n\nimport { execSync } from 'node:child_process'\nimport { iqr } from './baseline'\nimport { ValidationError } from './errors'\n\n/** Verdict for one experiment relative to its parent. ITERATE is the neutral\n * \"keep collecting reps / no parent to compare against\" state. */\nexport type ExperimentVerdict = 'KEEP' | 'ITERATE' | 'NOISE' | 'REGRESSION'\n\n/** Git provenance for the working tree an experiment was run from. */\nexport interface ExperimentProvenance {\n /** Commit sha (short or full — the tracker does not interpret it). */\n commit: string\n /** First line of the commit message. */\n message: string\n /** Files changed vs the parent commit, or a marker like 'uncommitted'. */\n changedFiles: string[]\n}\n\n/** A single repetition of an experiment, carrying the score the verdict is\n * computed on plus any free-form per-rep metrics the consumer wants kept. */\nexport interface ExperimentRep {\n /** 0-indexed repetition number within the experiment. */\n rep: number\n /** The score this rep is judged on (same scale as the thresholds). */\n score: number\n /** ISO timestamp the rep completed. */\n timestamp: string\n /** Whether this rep passed the consumer's own gate — folded into `passRate`. */\n passed?: boolean\n /** Free-form numeric metrics retained for later analysis. */\n metrics?: Record<string, number>\n}\n\nexport interface ExperimentStats {\n median: number\n mean: number\n min: number\n max: number\n /** Inter-quartile range of the rep scores. */\n iqr: number\n /** Population standard deviation of the rep scores. */\n stddev: number\n /** Fraction of reps with `passed === true`, over reps that set `passed`.\n * null when no rep declared a pass/fail outcome. */\n passRate: number | null\n /** Number of reps. */\n n: number\n /** True when the sample is tight enough to trust for a verdict. */\n stable: boolean\n}\n\nexport interface Experiment {\n /** Stable id for the experiment. */\n id: string\n /** Free-form label / config descriptor. */\n label: string\n /** Git provenance captured when the experiment was created. */\n provenance: ExperimentProvenance\n /** Parent experiment id this candidate is compared against, if any. */\n parentId?: string\n /** One-line summary of what changed from the parent. */\n changeSummary: string\n reps: ExperimentRep[]\n stats: ExperimentStats\n verdict: ExperimentVerdict\n /** ISO timestamp the experiment was created. */\n createdAt: string\n}\n\nexport interface ImprovementThresholds {\n /** medianDelta strictly above this ⇒ KEEP. Default 5. */\n keepThreshold?: number\n /** medianDelta strictly below the negative of this ⇒ REGRESSION. Default 5. */\n regressionThreshold?: number\n /** iqr at or above this ⇒ unstable. Default 10. */\n iqrUnstableAbove?: number\n /** stddev at or above this ⇒ unstable. Default Infinity (iqr-only stability). */\n stddevUnstableAbove?: number\n /** Reps required on BOTH candidate and parent before a verdict is rendered.\n * Default 3. */\n minRepsForVerdict?: number\n}\n\nexport interface ImprovementVerdictResult {\n verdict: ExperimentVerdict\n /** candidate.median − parent.median; null when no parent or insufficient reps. */\n medianDelta: number | null\n /** Human-readable reason for the verdict — for dashboards and logs. */\n reason: string\n}\n\nconst DEFAULTS: Required<ImprovementThresholds> = {\n keepThreshold: 5,\n regressionThreshold: 5,\n iqrUnstableAbove: 10,\n stddevUnstableAbove: Number.POSITIVE_INFINITY,\n minRepsForVerdict: 3,\n}\n\nfunction resolveThresholds(t: ImprovementThresholds | undefined): Required<ImprovementThresholds> {\n const r = { ...DEFAULTS, ...(t ?? {}) }\n if (r.keepThreshold < 0) {\n throw new ValidationError(\n `experiment-tracker: keepThreshold must be >= 0, got ${r.keepThreshold}`,\n )\n }\n if (r.regressionThreshold < 0) {\n throw new ValidationError(\n `experiment-tracker: regressionThreshold must be >= 0, got ${r.regressionThreshold}`,\n )\n }\n if (r.minRepsForVerdict < 1) {\n throw new ValidationError(\n `experiment-tracker: minRepsForVerdict must be >= 1, got ${r.minRepsForVerdict}`,\n )\n }\n return r\n}\n\nfunction median(sorted: number[]): number {\n const n = sorted.length\n if (n === 0) return 0\n const mid = Math.floor(n / 2)\n return n % 2 === 0 ? (sorted[mid - 1]! + sorted[mid]!) / 2 : sorted[mid]!\n}\n\n/** Population standard deviation (÷n). 0 for fewer than 2 values. */\nfunction stddev(values: number[], mean: number): number {\n if (values.length < 2) return 0\n const variance = values.reduce((acc, v) => acc + (v - mean) ** 2, 0) / values.length\n return Math.sqrt(variance)\n}\n\n/**\n * Compute the N-rep statistics for a set of reps. Pure — no I/O. The `stable`\n * flag is the trust gate the verdict depends on: a sample whose spread exceeds\n * the configured bounds can't distinguish a real delta from run-to-run noise.\n */\nexport function computeExperimentStats(\n reps: ExperimentRep[],\n thresholds?: ImprovementThresholds,\n): ExperimentStats {\n const t = resolveThresholds(thresholds)\n const n = reps.length\n if (n === 0) {\n return {\n median: 0,\n mean: 0,\n min: 0,\n max: 0,\n iqr: 0,\n stddev: 0,\n passRate: null,\n n: 0,\n stable: false,\n }\n }\n const scores = reps.map((r) => {\n if (!Number.isFinite(r.score)) {\n throw new ValidationError(`experiment-tracker: rep ${r.rep} has non-finite score ${r.score}`)\n }\n return r.score\n })\n const sorted = [...scores].sort((a, b) => a - b)\n const mean = scores.reduce((s, v) => s + v, 0) / n\n const sd = stddev(scores, mean)\n const spread = iqr(scores)\n const rated = reps.filter((r) => typeof r.passed === 'boolean')\n const passRate = rated.length === 0 ? null : rated.filter((r) => r.passed).length / rated.length\n const stable = spread < t.iqrUnstableAbove && sd < t.stddevUnstableAbove\n return {\n median: median(sorted),\n mean,\n min: sorted[0]!,\n max: sorted[n - 1]!,\n iqr: spread,\n stddev: sd,\n passRate,\n n,\n stable,\n }\n}\n\n/**\n * Verdict for a candidate against its parent. Pure — operates on already-computed\n * stats. KEEP/REGRESSION require both sides to have `>= minRepsForVerdict` reps\n * AND the candidate to be `stable`; otherwise the result is NOISE (unstable) or\n * ITERATE (not enough reps / no parent).\n */\nexport function improvementVerdict(\n candidate: ExperimentStats,\n parent: ExperimentStats | null,\n thresholds?: ImprovementThresholds,\n): ImprovementVerdictResult {\n const t = resolveThresholds(thresholds)\n if (!parent) {\n return {\n verdict: 'ITERATE',\n medianDelta: null,\n reason: 'no parent experiment to compare against',\n }\n }\n if (candidate.n < t.minRepsForVerdict || parent.n < t.minRepsForVerdict) {\n return {\n verdict: 'ITERATE',\n medianDelta: null,\n reason: `need >= ${t.minRepsForVerdict} reps on both sides (candidate n=${candidate.n}, parent n=${parent.n})`,\n }\n }\n if (!candidate.stable) {\n return {\n verdict: 'NOISE',\n medianDelta: candidate.median - parent.median,\n reason: `candidate unstable (iqr=${candidate.iqr}, stddev=${candidate.stddev.toFixed(2)})`,\n }\n }\n const medianDelta = candidate.median - parent.median\n if (medianDelta > t.keepThreshold) {\n return { verdict: 'KEEP', medianDelta, reason: `median +${medianDelta} > +${t.keepThreshold}` }\n }\n if (medianDelta < -t.regressionThreshold) {\n return {\n verdict: 'REGRESSION',\n medianDelta,\n reason: `median ${medianDelta} < -${t.regressionThreshold}`,\n }\n }\n return {\n verdict: 'NOISE',\n medianDelta,\n reason: `median delta ${medianDelta} inside noise band [-${t.regressionThreshold}, +${t.keepThreshold}]`,\n }\n}\n\n// ── Provenance + persistence seams ───────────────────────────────────\n\n/** Reads git provenance for the working tree. Inject a fake in tests; the\n * default implementation shells out to `git`. */\nexport type ProvenanceReader = () => ExperimentProvenance | Promise<ExperimentProvenance>\n\n/** Persistence seam for the experiment log. Inject in-memory in tests; the\n * filesystem implementation is `fileExperimentStore`. */\nexport interface ExperimentStore {\n load(): Promise<Experiment[]>\n save(experiments: Experiment[]): Promise<void>\n}\n\n/**\n * Default provenance reader: `git rev-parse HEAD`, the subject line, and the\n * files changed vs `HEAD~1`. Fail-loud — a tracker that silently logs\n * `commit: 'unknown'` corrupts the provenance the whole point of the log is to\n * carry. When the working tree genuinely has no parent commit, pass an override.\n */\nexport const gitProvenanceReader: ProvenanceReader = () => {\n const run = (cmd: string): string => execSync(cmd, { encoding: 'utf8' }).trim()\n const commit = run('git rev-parse --short HEAD')\n const message = run('git log -1 --format=%s')\n const changedRaw = run('git diff --name-only HEAD~1')\n const changedFiles = changedRaw.length === 0 ? [] : changedRaw.split('\\n').filter(Boolean)\n return { commit, message, changedFiles }\n}\n\n/** In-memory store — the default when no persistence is wanted (tests, ephemeral\n * runs). State lives on the instance. */\nexport function inMemoryExperimentStore(initial: Experiment[] = []): ExperimentStore {\n let state = initial.map((e) => structuredClone(e))\n return {\n async load() {\n return state.map((e) => structuredClone(e))\n },\n async save(experiments) {\n state = experiments.map((e) => structuredClone(e))\n },\n }\n}\n\n/** Filesystem store — a single JSON array at `path`, created on first save. */\nexport function fileExperimentStore(path: string): ExperimentStore {\n return {\n async load() {\n const fs = await import('node:fs/promises')\n try {\n const raw = await fs.readFile(path, 'utf8')\n const parsed = JSON.parse(raw)\n if (!Array.isArray(parsed)) {\n throw new ValidationError(`experiment-tracker: store at ${path} is not a JSON array`)\n }\n return parsed as Experiment[]\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') return []\n throw err\n }\n },\n async save(experiments) {\n const fs = await import('node:fs/promises')\n const pathMod = await import('node:path')\n await fs.mkdir(pathMod.dirname(path), { recursive: true })\n await fs.writeFile(path, JSON.stringify(experiments, null, 2), 'utf8')\n },\n }\n}\n\nexport interface ExperimentTrackerOptions {\n store?: ExperimentStore\n provenanceReader?: ProvenanceReader\n thresholds?: ImprovementThresholds\n /** Clock seam for deterministic timestamps in tests. Default `Date.now`. */\n now?: () => number\n}\n\nexport interface CreateExperimentInput {\n id: string\n label: string\n changeSummary: string\n parentId?: string\n /** Override provenance instead of reading from git (e.g. CI metadata). */\n provenance?: ExperimentProvenance\n}\n\n/**\n * Stateful tracker over an `ExperimentStore`. Create an experiment (provenance\n * is captured once), append reps as they complete (stats + verdict recompute on\n * every append), and read the log back for a dashboard. All persistence and git\n * access flow through the injected seams, so the tracker is fully testable\n * without a repo or disk.\n */\nexport class ExperimentTracker {\n private readonly store: ExperimentStore\n private readonly provenanceReader: ProvenanceReader\n private readonly thresholds: Required<ImprovementThresholds>\n private readonly now: () => number\n\n constructor(options: ExperimentTrackerOptions = {}) {\n this.store = options.store ?? inMemoryExperimentStore()\n this.provenanceReader = options.provenanceReader ?? gitProvenanceReader\n this.thresholds = resolveThresholds(options.thresholds)\n this.now = options.now ?? Date.now\n }\n\n async create(input: CreateExperimentInput): Promise<Experiment> {\n const experiments = await this.store.load()\n if (experiments.some((e) => e.id === input.id)) {\n throw new ValidationError(`experiment-tracker: experiment id \"${input.id}\" already exists`)\n }\n if (input.parentId && !experiments.some((e) => e.id === input.parentId)) {\n throw new ValidationError(\n `experiment-tracker: parent experiment \"${input.parentId}\" not found`,\n )\n }\n const provenance = input.provenance ?? (await this.provenanceReader())\n const experiment: Experiment = {\n id: input.id,\n label: input.label,\n provenance,\n parentId: input.parentId,\n changeSummary: input.changeSummary,\n reps: [],\n stats: computeExperimentStats([], this.thresholds),\n verdict: 'ITERATE',\n createdAt: new Date(this.now()).toISOString(),\n }\n experiments.push(experiment)\n await this.store.save(experiments)\n return structuredClone(experiment)\n }\n\n /** Append a rep (its `rep` index defaults to the current rep count) and\n * recompute stats + verdict. Returns the updated experiment. */\n async addRep(\n experimentId: string,\n rep: Omit<ExperimentRep, 'rep' | 'timestamp'> & { rep?: number; timestamp?: string },\n ): Promise<Experiment> {\n const experiments = await this.store.load()\n const exp = experiments.find((e) => e.id === experimentId)\n if (!exp)\n throw new ValidationError(`experiment-tracker: experiment \"${experimentId}\" not found`)\n const fullRep: ExperimentRep = {\n rep: rep.rep ?? exp.reps.length,\n score: rep.score,\n passed: rep.passed,\n metrics: rep.metrics,\n timestamp: rep.timestamp ?? new Date(this.now()).toISOString(),\n }\n exp.reps.push(fullRep)\n exp.stats = computeExperimentStats(exp.reps, this.thresholds)\n const parent = exp.parentId ? experiments.find((e) => e.id === exp.parentId) : undefined\n exp.verdict = improvementVerdict(exp.stats, parent?.stats ?? null, this.thresholds).verdict\n await this.store.save(experiments)\n return structuredClone(exp)\n }\n\n async get(experimentId: string): Promise<Experiment | undefined> {\n const experiments = await this.store.load()\n const found = experiments.find((e) => e.id === experimentId)\n return found ? structuredClone(found) : undefined\n }\n\n async list(): Promise<Experiment[]> {\n return this.store.load()\n }\n\n /** Full verdict (not just the enum) for an experiment vs its parent. */\n async verdictFor(experimentId: string): Promise<ImprovementVerdictResult> {\n const experiments = await this.store.load()\n const exp = experiments.find((e) => e.id === experimentId)\n if (!exp)\n throw new ValidationError(`experiment-tracker: experiment \"${experimentId}\" not found`)\n const parent = exp.parentId ? experiments.find((e) => e.id === exp.parentId) : undefined\n return improvementVerdict(exp.stats, parent?.stats ?? null, this.thresholds)\n }\n}\n","/**\n * Cross-profile leaderboard — rank agent profiles (or any grouping) over a corpus\n * of RunRecords on pass-rate with a Wilson CI, joined with the cost / token /\n * latency rollup every benchmark wants next to the score.\n *\n * This is substrate, not benchmark-specific: any consumer of agent-eval gets a\n * cross-harness × model leaderboard without re-implementing grouping, binomial\n * CIs, or the observability join. The benchmark supplies only what \"passed\"\n * means; everything else composes existing primitives (`wilson`, the RunRecord\n * cost/token/wall fields, the AgentProfileCell grouping key).\n */\nimport type { RunRecord } from './run-record'\nimport { wilson } from './statistics'\n\nexport interface LeaderboardRow {\n /** Group key — the agent-profile cellId by default, else a caller dimension. */\n key: string\n /** Display label: `harness · model` when the profile carries them, else the key. */\n label: string\n harness?: string\n model?: string\n rank: number\n /** Measured runs in this group. */\n n: number\n passRate: number\n passRateCi95: [number, number]\n /** Observability rollup — means over the group; null when no run reported it. */\n meanCostUsd: number | null\n meanTokensIn: number | null\n meanTokensOut: number | null\n meanWallMs: number | null\n}\n\nexport interface LeaderboardOptions {\n /** Per-run pass predicate — the benchmark defines what \"passed\" means (real-build\n * hit-rate, test-pass, etc.). The leaderboard owns only the grouping + stats. */\n passed: (record: RunRecord) => boolean\n /** Group key. Default: the agent-profile cellId (harness × model × dimensions),\n * so persona/harness/model sweeps separate without parsing labels. */\n groupBy?: (record: RunRecord) => string\n}\n\nfunction mean(xs: number[]): number | null {\n return xs.length ? xs.reduce((a, b) => a + b, 0) / xs.length : null\n}\n\n/**\n * Group `records`, compute pass-rate + Wilson CI + cost/token/latency means per\n * group, and rank by pass-rate (cost as the tiebreaker — cheaper wins a tie).\n * Pure projection: no I/O, deterministic, safe to call on any RunRecord[].\n */\nexport function leaderboard(records: RunRecord[], opts: LeaderboardOptions): LeaderboardRow[] {\n const keyOf = opts.groupBy ?? ((r: RunRecord) => r.agentProfile?.cellId ?? 'ungrouped')\n const groups = new Map<string, RunRecord[]>()\n for (const r of records) {\n const k = keyOf(r)\n const g = groups.get(k)\n if (g) g.push(r)\n else groups.set(k, [r])\n }\n\n const rows: LeaderboardRow[] = [...groups.entries()].map(([key, rs]) => {\n const passes = rs.filter((r) => opts.passed(r)).length\n const ci = wilson(passes, rs.length)\n const profile = rs[0]!.agentProfile\n const harness = profile?.harness?.id\n const model = profile?.model\n return {\n key,\n label: harness && model ? `${harness} · ${model}` : key,\n ...(harness ? { harness } : {}),\n ...(model ? { model } : {}),\n rank: 0,\n n: rs.length,\n passRate: ci.estimate,\n passRateCi95: [ci.lower, ci.upper],\n meanCostUsd: mean(rs.map((r) => r.costUsd)),\n meanTokensIn: mean(rs.map((r) => r.tokenUsage.input)),\n meanTokensOut: mean(rs.map((r) => r.tokenUsage.output)),\n meanWallMs: mean(rs.map((r) => r.wallMs)),\n }\n })\n\n rows.sort(\n (a, b) => b.passRate - a.passRate || (a.meanCostUsd ?? Infinity) - (b.meanCostUsd ?? Infinity),\n )\n rows.forEach((row, i) => {\n row.rank = i + 1\n })\n return rows\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: ReturnType<typeof statSync>\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 * Deterministic held-out partitioning over stable ids.\n *\n * A promotion gate's paired-delta math needs a fixed partition: the same\n * scenario id lands in the same bucket forever, regardless of when it ran or\n * which loop emitted the record — otherwise the gate has nothing paired to\n * compare against. Picking one global split per run is wrong: every run then\n * stamps either ALL search or ALL holdout, and no id is ever observed on both\n * sides. Per-id deterministic hashing fixes that.\n *\n * Two consumers hand-roll this (agent-builder's `deterministicSplit` and the\n * frontier persona-splitter). The substrate already has a 3-way benchmark\n * `deterministicSplit` in `./benchmarks`; this is the generic, validated batch\n * partitioner: it takes a list of ids, splits them by a stable FNV-1a hash, and\n * fails loud when the inputs can't support a trustworthy held-out comparison\n * (duplicate ids, or a holdout set below the significance floor).\n */\n\nimport { ValidationError } from './errors'\n\n/** 32-bit FNV-1a hash. Stable, allocation-free, deterministic across runtimes —\n * the same id+seed maps to the same bucket on every machine and process. */\nexport function fnv1a32(input: string): number {\n let h = 0x811c9dc5\n for (let i = 0; i < input.length; i++) {\n h ^= input.charCodeAt(i) & 0xff\n h = Math.imul(h, 0x01000193)\n }\n return h >>> 0\n}\n\n/** Map an id+seed to the half-open unit interval [0, 1) deterministically. */\nexport function hashToUnit(id: string, seed: string): number {\n // Newline separator: 'ab' + '\\n' + 'c' can't collide with 'a' + '\\n' + 'bc'.\n return fnv1a32(`${id}\\n${seed}`) / 0x1_0000_0000\n}\n\nexport interface PartitionHeldOutOptions {\n /** Partition seed. Bumping it reshuffles every assignment — do that only when\n * the corpus/policy changes meaningfully so old and new records can't pair.\n * Default 'held-out-v1'. */\n seed?: string\n /** Fraction routed to the held-out bucket, in (0, 1). Default 0.5. */\n holdoutFraction?: number\n /**\n * Minimum held-out ids required for the split to be admissible. Below this,\n * a paired comparison has too few observations to be significant, so the\n * partition throws rather than hand back an underpowered holdout. Default 1\n * (only the empty-holdout degenerate case is rejected). Raise it to enforce\n * real statistical power. */\n minHoldout?: number\n /** Same floor for the search side. Default 1. */\n minSearch?: number\n}\n\nexport interface HeldOutPartition {\n /** Ids the optimizer is allowed to read/optimize against. */\n search: string[]\n /** Ids reserved for gated, held-out evaluation. */\n holdout: string[]\n seed: string\n holdoutFraction: number\n}\n\n/**\n * Assign a single id to `'search'` or `'holdout'` deterministically. Same\n * `(id, seed)` always returns the same tag — the invariant the gate relies on.\n * Use this in a `splitTag:` field literal when stamping records one at a time;\n * use `partitionHeldOut` when you have the whole id list up front and want the\n * validated disjoint split.\n */\nexport function assignHeldOutTag(\n id: string,\n options: { seed?: string; holdoutFraction?: number } = {},\n): 'search' | 'holdout' {\n const seed = options.seed ?? 'held-out-v1'\n const holdoutFraction = options.holdoutFraction ?? 0.5\n assertFraction(holdoutFraction)\n return hashToUnit(id, seed) < holdoutFraction ? 'holdout' : 'search'\n}\n\n/**\n * Partition a list of stable ids into disjoint `search` / `holdout` sets by a\n * deterministic hash. Fail-loud:\n * - empty input throws,\n * - duplicate ids throw (a dup would be observed on both sides, double-counting),\n * - a holdout (or search) set below its floor throws (underpowered comparison).\n *\n * Order within each bucket follows the input order, so the result is stable and\n * reproducible.\n */\nexport function partitionHeldOut(\n ids: string[],\n options: PartitionHeldOutOptions = {},\n): HeldOutPartition {\n const seed = options.seed ?? 'held-out-v1'\n const holdoutFraction = options.holdoutFraction ?? 0.5\n const minHoldout = options.minHoldout ?? 1\n const minSearch = options.minSearch ?? 1\n assertFraction(holdoutFraction)\n if (ids.length === 0) {\n throw new ValidationError('partitionHeldOut: no ids supplied')\n }\n\n const seen = new Set<string>()\n const search: string[] = []\n const holdout: string[] = []\n for (const id of ids) {\n if (typeof id !== 'string' || id.length === 0) {\n throw new ValidationError(\n `partitionHeldOut: ids must be non-empty strings, got ${JSON.stringify(id)}`,\n )\n }\n if (seen.has(id)) {\n throw new ValidationError(\n `partitionHeldOut: duplicate id \"${id}\" — a paired comparison must not double-count`,\n )\n }\n seen.add(id)\n if (hashToUnit(id, seed) < holdoutFraction) holdout.push(id)\n else search.push(id)\n }\n\n if (holdout.length < minHoldout) {\n throw new ValidationError(\n `partitionHeldOut: holdout set has ${holdout.length} id(s), below the floor of ${minHoldout} ` +\n `(n=${ids.length}, holdoutFraction=${holdoutFraction}) — too few for a significant comparison`,\n )\n }\n if (search.length < minSearch) {\n throw new ValidationError(\n `partitionHeldOut: search set has ${search.length} id(s), below the floor of ${minSearch} ` +\n `(n=${ids.length}, holdoutFraction=${holdoutFraction})`,\n )\n }\n\n return { search, holdout, seed, holdoutFraction }\n}\n\nfunction assertFraction(f: number): void {\n if (!Number.isFinite(f) || f <= 0 || f >= 1) {\n throw new ValidationError(`partitionHeldOut: holdoutFraction must be in (0, 1), got ${f}`)\n }\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, agentProfileModelId } 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 model = agentProfileModelId(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,\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 * 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 * UI audit finding — substrate primitive for \"what is wrong with the UI?\"\n *\n * Used by:\n * - `@tangle-network/agent-runtime` (ui-auditor profile + delegate) —\n * produced as the canonical output of an audit iteration, persisted to\n * disk as GitHub-issue Markdown, surfaced over MCP.\n * - Downstream ship gates / dashboards / analyst consumers — load and\n * transform findings without depending on the runtime.\n *\n * Repo layering: agent-eval is the substrate (no upward deps). Consumers\n * read this type from here; the reverse is forbidden. See CLAUDE.md\n * \"Repo layering\" for the rule. A UI finding makes sense WITHOUT a running\n * agent loop (you can load a saved finding, ship-gate against a set of\n * them, render them in a dashboard), which puts it firmly in substrate.\n *\n * The shape is intentionally minimal — runtime-shaped state (capture\n * timestamps, OTel trace IDs, sandbox placement) lives on auxiliary\n * runtime types in `agent-runtime`, not on the finding itself.\n */\n\n/**\n * Canonical audit lenses. Each lens scopes a finding to a single class of\n * problem so a single audit pass can iterate them without pile-on findings\n * under a generic label.\n *\n * Naming is fixed for cross-package wire compatibility. Treat additions as\n * a substrate-level decision — analysts, gates, and writers all branch on\n * the lens.\n */\nexport type UiLens =\n | 'consistency'\n | 'hierarchy'\n | 'layout'\n | 'ux-flow'\n | 'duplication'\n | 'accessibility'\n | 'responsive'\n | 'states'\n | 'content'\n | 'interaction'\n | 'performance-perceived'\n | 'other'\n\n/** Frozen tuple of lenses for validation + iteration. */\nexport const UI_LENSES: readonly UiLens[] = [\n 'consistency',\n 'hierarchy',\n 'layout',\n 'ux-flow',\n 'duplication',\n 'accessibility',\n 'responsive',\n 'states',\n 'content',\n 'interaction',\n 'performance-perceived',\n 'other',\n] as const\n\n/**\n * Severity scale — intentionally narrow.\n *\n * - `critical` — blocks a core task or is an accessibility blocker.\n * - `high` — confusing, broken-looking, or noticeable friction.\n * - `med` — visible polish issue, would be caught in code review.\n * - `low` — nitpick worth fixing eventually.\n */\nexport type UiFindingSeverity = 'low' | 'med' | 'high' | 'critical'\n\n/** Frozen severity tuple, ordered worst → least bad for sort/report. */\nexport const UI_FINDING_SEVERITIES: readonly UiFindingSeverity[] = [\n 'critical',\n 'high',\n 'med',\n 'low',\n] as const\n\n/**\n * Pointer to a screenshot referenced by the finding. The path is\n * intentionally a relative string (relative to the audit workspace root)\n * so findings remain portable across machines and into GitHub issues.\n */\nexport interface UiFindingScreenshot {\n /** Workspace-relative path to the screenshot file (e.g. `screenshots/home--1280x800--...png`). */\n path: string\n /** Optional viewport the screenshot was taken at, e.g. `1280x800`. */\n viewport?: string\n /** Optional short label that disambiguates multiple captures of the same surface (e.g. `t0`, `step-1`). */\n label?: string\n}\n\n/**\n * A single UI audit finding — the unit of work a contributor can act on.\n *\n * Every field except the documented optionals is required. The shape is\n * deliberately constraining: a finding without a screenshot, a lens, a\n * concrete title, and a suggested fix is not actionable, and the auditor\n * validator hard-fails on those gaps.\n */\nexport interface UiFinding {\n /**\n * Stable identifier within a single audit workspace. Monotonically\n * increasing integer (1, 2, …) assigned by the writer when persisting.\n * Optional in transit (before persistence) — undefined on freshly minted\n * findings emitted from a loop iteration.\n */\n id?: number\n /** Concrete title — names the offending element AND what's wrong. */\n title: string\n /** Lens this finding belongs to. */\n lens: UiLens\n /** Severity. */\n severity: UiFindingSeverity\n /** Logical route the finding was observed on (e.g. `home`, `checkout-step-2`). */\n route: string\n /** Fully qualified URL the finding was observed at. */\n url?: string\n /** Viewport string the offending capture was taken at (e.g. `1280x800`). */\n viewport?: string\n /** CSS selector pinning the offending element, when one can be identified. */\n selector?: string\n /** 1–3 sentences describing what the screenshot shows that is wrong. */\n observation: string\n /** Who is affected and how. Concrete user impact. */\n impact: string\n /** A specific change a contributor could apply without asking back. */\n suggestedFix: string\n /** Optional explicit reproduction steps. Writer synthesizes from route/url/selector when omitted. */\n reproSteps?: string\n /** Free-form tags. */\n tags?: readonly string[]\n /** Screenshot references — required to be non-empty for actionable findings. */\n screenshots: readonly UiFindingScreenshot[]\n /** Cross-references to similar findings already on file, by id. */\n similarTo?: readonly number[]\n /** ISO-8601 creation timestamp set by the writer when persisted. */\n createdAt?: string\n}\n","/**\n * Trace contracts — finite-trace temporal assertions over span sequences.\n *\n * Five LTLf operators over one ordered span sequence — `always(p)`,\n * `never(p)`, `eventually(p)`, `precedes(a, b)`, `neverUnless(p, prior)` —\n * deterministic and judge-free. No nesting: each rule is one operator over\n * flat `SpanPredicate`s; compose richer checks with multiple rules.\n *\n * A built `TraceContract` is a serializable plain object (RegExp matchers\n * are normalized to `SerializedRegex`), so ONE contract definition is\n * dual-use:\n *\n * - recorded eval traces — `evaluateTraceContract(contract, await\n * store.spans({ runId }))`, or via the behavior DSL:\n * `expectAgent(store, runId).toSatisfyContract(contract)`.\n * - the production OTLP stream — `ExportableSpan`s flattened by\n * `trace/otel-bridge` satisfy `ContractSpan` structurally. A production\n * monitor implements `OtelExporter`, buffers `exportSpan` payloads per\n * trace, and runs `checkTraceContracts(buffer, contracts)` on flush:\n *\n * const buffer: ContractSpan[] = []\n * const monitor: OtelExporter = {\n * exportSpan: (s) => { buffer.push(s) },\n * flush: async () => {\n * const { allValid, verdicts } = checkTraceContracts(buffer, contracts)\n * if (!allValid) alert(verdicts)\n * },\n * shutdown: async () => {},\n * }\n * const store = createOtelTracingStore(inner, monitor, runId)\n *\n * `custom` predicate functions are the one non-serializable escape hatch:\n * the builder stamps `requiresCustom: true` (which DOES survive JSON) so a\n * deserialized contract that lost its function fails loud at evaluation\n * instead of silently weakening.\n *\n * Naming: the root barrel exports ci-gate's threshold-contract\n * `evaluateContract`, so the evaluators here are `evaluateTraceContract` /\n * `checkTraceContracts`.\n */\n\nimport type { JudgeConfig, JudgeDimension, Scenario } from './campaign/types'\nimport { ValidationError } from './errors'\nimport type { DefaultVerdict } from './verdict'\n\n// ── Span surface ──────────────────────────────────────────────────────\n\n/**\n * Minimal structural span the checker reads. Both the eval-side `Span`\n * (trace/schema) and the OTLP-flattened `ExportableSpan` (trace/otel-export)\n * satisfy it; any other producer only needs these fields.\n */\nexport interface ContractSpan {\n spanId?: string\n name?: string\n kind?: string\n startedAt?: number\n status?: string\n error?: string\n /** Typed field on eval-side ToolSpans; OTLP flattenings drop it (see\n * `tool` matching order in {@link matchSpan}). */\n toolName?: string\n attributes?: Record<string, unknown>\n}\n\n/** JSON-safe RegExp form — what the builder normalizes RegExp matchers to. */\nexport interface SerializedRegex {\n $regex: string\n flags: string\n}\n\nexport type TextMatcher = string | RegExp | SerializedRegex\n\n/**\n * Proposition over one span. All specified fields must match (AND).\n * At least one field is required — an empty predicate would match every\n * span and is rejected.\n *\n * `tool` resolution order covers both span shapes: `span.toolName` (typed\n * ToolSpan) → `attributes['tool.name']` / `attributes['toolName']`\n * (OTLP-flat attribute conventions) → `span.name` when `kind === 'tool'`\n * (otel-bridge's `ExportableSpan`, which drops `toolName`).\n *\n * `attr` values match by strict equality, or regex-test when the value is a\n * RegExp/SerializedRegex and the attribute is a string. Structured attribute\n * values need `custom`.\n */\nexport interface SpanPredicate {\n name?: TextMatcher\n tool?: TextMatcher\n attr?: Record<string, unknown>\n custom?: (span: ContractSpan) => boolean\n /** Stamped by the builder when `custom` is present. Survives JSON while\n * the function does not, so evaluation of a deserialized contract throws\n * instead of silently dropping the check. */\n requiresCustom?: true\n}\n\n// ── Contract shape ────────────────────────────────────────────────────\n\nexport type ContractRuleKind = 'always' | 'never' | 'eventually' | 'precedes' | 'neverUnless'\n\nexport interface ContractRule {\n kind: ContractRuleKind\n /** Unique within the contract — keys the per-rule score. */\n label: string\n /** Subject predicate for always / never / eventually / neverUnless. */\n p?: SpanPredicate\n /** precedes: the required precondition. */\n a?: SpanPredicate\n /** precedes: the guarded match — every b-match needs an earlier a-match. */\n b?: SpanPredicate\n /** neverUnless: the authorizing earlier match. */\n prior?: SpanPredicate\n}\n\n/** Serializable plain object — `traceContract(name)....build()` output. */\nexport interface TraceContract {\n name: string\n rules: ContractRule[]\n}\n\nexport interface ContractViolation {\n rule: string\n spanId?: string\n detail: string\n}\n\nexport interface ContractVerdict extends DefaultVerdict {\n /** Contract name — keys this verdict in multi-contract reports. */\n contract: string\n valid: boolean\n /** Fraction of rules passing, in [0, 1]. */\n score: number\n /** Per-rule 0|1 keyed by rule label. */\n scores: Record<string, number>\n violations: ContractViolation[]\n}\n\nexport interface ContractCheckResult {\n verdicts: ContractVerdict[]\n allValid: boolean\n}\n\n// ── Predicate matching ────────────────────────────────────────────────\n\nfunction isSerializedRegex(v: unknown): v is SerializedRegex {\n return (\n typeof v === 'object' &&\n v !== null &&\n typeof (v as SerializedRegex).$regex === 'string' &&\n typeof (v as SerializedRegex).flags === 'string'\n )\n}\n\nfunction matchText(actual: string | undefined, matcher: TextMatcher): boolean {\n if (typeof actual !== 'string') return false\n if (typeof matcher === 'string') return actual === matcher\n if (matcher instanceof RegExp) return matcher.test(actual)\n return new RegExp(matcher.$regex, matcher.flags).test(actual)\n}\n\nfunction resolveToolName(span: ContractSpan): string | undefined {\n if (typeof span.toolName === 'string') return span.toolName\n const fromAttr = span.attributes?.['tool.name'] ?? span.attributes?.toolName\n if (typeof fromAttr === 'string') return fromAttr\n if (span.kind === 'tool' && typeof span.name === 'string') return span.name\n return undefined\n}\n\nfunction assertPredicate(value: unknown, where: string): asserts value is SpanPredicate {\n if (value === null || typeof value !== 'object') {\n throw new ValidationError(`${where}: predicate must be an object, got ${typeof value}`)\n }\n const p = value as SpanPredicate\n for (const field of ['name', 'tool'] as const) {\n const m = p[field]\n if (\n m !== undefined &&\n typeof m !== 'string' &&\n !(m instanceof RegExp) &&\n !isSerializedRegex(m)\n ) {\n throw new ValidationError(`${where}: \"${field}\" must be string | RegExp | SerializedRegex`)\n }\n }\n if (\n p.attr !== undefined &&\n (p.attr === null || typeof p.attr !== 'object' || Array.isArray(p.attr))\n ) {\n throw new ValidationError(`${where}: \"attr\" must be a plain object`)\n }\n if (p.requiresCustom && typeof p.custom !== 'function') {\n throw new ValidationError(\n `${where}: rule was built with a custom predicate function, which does not survive JSON ` +\n 'serialization — re-attach `custom` after deserializing or drop the rule',\n )\n }\n const hasAttr = p.attr !== undefined && Object.keys(p.attr).length > 0\n if (p.name === undefined && p.tool === undefined && !hasAttr && typeof p.custom !== 'function') {\n throw new ValidationError(\n `${where}: empty predicate would match every span — specify name, tool, attr, or custom`,\n )\n }\n}\n\n/** Test one span against one predicate. All specified fields must match. */\nexport function matchSpan(span: ContractSpan, predicate: SpanPredicate): boolean {\n assertPredicate(predicate, 'matchSpan')\n if (predicate.name !== undefined && !matchText(span.name, predicate.name)) return false\n if (predicate.tool !== undefined && !matchText(resolveToolName(span), predicate.tool))\n return false\n if (predicate.attr !== undefined) {\n for (const [key, expected] of Object.entries(predicate.attr)) {\n const actual = span.attributes?.[key]\n if (expected instanceof RegExp || isSerializedRegex(expected)) {\n if (!matchText(typeof actual === 'string' ? actual : undefined, expected as TextMatcher)) {\n return false\n }\n } else if (actual !== expected) {\n return false\n }\n }\n }\n if (predicate.custom !== undefined && !predicate.custom(span)) return false\n return true\n}\n\n// ── Builder ───────────────────────────────────────────────────────────\n\nfunction describeMatcher(m: TextMatcher): string {\n if (typeof m === 'string') return m\n if (m instanceof RegExp) return `/${m.source}/${m.flags}`\n return `/${m.$regex}/${m.flags}`\n}\n\nfunction describePredicate(p: SpanPredicate): string {\n const parts: string[] = []\n if (p.name !== undefined) parts.push(`name=${describeMatcher(p.name)}`)\n if (p.tool !== undefined) parts.push(`tool=${describeMatcher(p.tool)}`)\n if (p.attr !== undefined) {\n for (const [k, v] of Object.entries(p.attr)) {\n parts.push(\n `attr.${k}=${v instanceof RegExp || isSerializedRegex(v) ? describeMatcher(v as TextMatcher) : JSON.stringify(v)}`,\n )\n }\n }\n if (typeof p.custom === 'function') parts.push(`custom=${p.custom.name || 'fn'}`)\n return parts.join(',')\n}\n\nfunction normalizeMatcher(m: TextMatcher): string | SerializedRegex {\n return m instanceof RegExp ? { $regex: m.source, flags: m.flags } : m\n}\n\nfunction normalizePredicate(p: SpanPredicate, where: string): SpanPredicate {\n assertPredicate(p, where)\n const out: SpanPredicate = {}\n if (p.name !== undefined) out.name = normalizeMatcher(p.name)\n if (p.tool !== undefined) out.tool = normalizeMatcher(p.tool)\n if (p.attr !== undefined) {\n out.attr = Object.fromEntries(\n Object.entries(p.attr).map(([k, v]) => [k, v instanceof RegExp ? normalizeMatcher(v) : v]),\n )\n }\n if (typeof p.custom === 'function') {\n out.custom = p.custom\n out.requiresCustom = true\n }\n return out\n}\n\nexport class TraceContractBuilder {\n private readonly rules: ContractRule[] = []\n\n constructor(private readonly name: string) {}\n\n /** Every span in the trace must satisfy `p`. */\n always(p: SpanPredicate, label?: string): this {\n const np = normalizePredicate(p, `traceContract(\"${this.name}\").always`)\n return this.add({ kind: 'always', label: label ?? `always(${describePredicate(np)})`, p: np })\n }\n\n /** No span in the trace may satisfy `p`. */\n never(p: SpanPredicate, label?: string): this {\n const np = normalizePredicate(p, `traceContract(\"${this.name}\").never`)\n return this.add({ kind: 'never', label: label ?? `never(${describePredicate(np)})`, p: np })\n }\n\n /** At least one span in the trace must satisfy `p`. */\n eventually(p: SpanPredicate, label?: string): this {\n const np = normalizePredicate(p, `traceContract(\"${this.name}\").eventually`)\n return this.add({\n kind: 'eventually',\n label: label ?? `eventually(${describePredicate(np)})`,\n p: np,\n })\n }\n\n /** Every `b`-match must have a strictly earlier `a`-match. */\n precedes(a: SpanPredicate, b: SpanPredicate, label?: string): this {\n const na = normalizePredicate(a, `traceContract(\"${this.name}\").precedes (a)`)\n const nb = normalizePredicate(b, `traceContract(\"${this.name}\").precedes (b)`)\n return this.add({\n kind: 'precedes',\n label: label ?? `precedes(${describePredicate(na)} -> ${describePredicate(nb)})`,\n a: na,\n b: nb,\n })\n }\n\n /** Every `p`-match is a violation unless a strictly earlier `prior`-match exists. */\n neverUnless(p: SpanPredicate, prior: SpanPredicate, label?: string): this {\n const np = normalizePredicate(p, `traceContract(\"${this.name}\").neverUnless (p)`)\n const nprior = normalizePredicate(prior, `traceContract(\"${this.name}\").neverUnless (prior)`)\n return this.add({\n kind: 'neverUnless',\n label: label ?? `neverUnless(${describePredicate(np)} unless ${describePredicate(nprior)})`,\n p: np,\n prior: nprior,\n })\n }\n\n build(): TraceContract {\n if (this.rules.length === 0) {\n throw new ValidationError(\n `traceContract(\"${this.name}\").build(): no rules — an empty contract would vacuously pass`,\n )\n }\n return { name: this.name, rules: [...this.rules] }\n }\n\n private add(rule: ContractRule): this {\n // Labels key per-rule scores — auto-suffix duplicates so two identical\n // operator+predicate rules never collapse into one score entry.\n let label = rule.label\n let n = 2\n while (this.rules.some((r) => r.label === label)) {\n label = `${rule.label} #${n}`\n n += 1\n }\n this.rules.push({ ...rule, label })\n return this\n }\n}\n\nexport function traceContract(name: string): TraceContractBuilder {\n if (typeof name !== 'string' || name.length === 0) {\n throw new ValidationError('traceContract: name must be a non-empty string')\n }\n return new TraceContractBuilder(name)\n}\n\n// ── Evaluation ────────────────────────────────────────────────────────\n\nfunction assertContract(contract: TraceContract): void {\n if (typeof contract?.name !== 'string' || contract.name.length === 0) {\n throw new ValidationError('evaluateTraceContract: contract.name must be a non-empty string')\n }\n if (!Array.isArray(contract.rules) || contract.rules.length === 0) {\n throw new ValidationError(\n `evaluateTraceContract: contract \"${contract.name}\" has no rules — an empty contract would vacuously pass`,\n )\n }\n const seen = new Set<string>()\n for (const rule of contract.rules) {\n const where = `contract \"${contract.name}\" rule \"${rule?.label ?? '<unlabeled>'}\"`\n if (typeof rule?.label !== 'string' || rule.label.length === 0) {\n throw new ValidationError(`${where}: label must be a non-empty string`)\n }\n if (seen.has(rule.label)) {\n throw new ValidationError(`${where}: duplicate label would collapse per-rule scores`)\n }\n seen.add(rule.label)\n switch (rule.kind) {\n case 'always':\n case 'never':\n case 'eventually':\n assertPredicate(rule.p, `${where} (p)`)\n break\n case 'precedes':\n assertPredicate(rule.a, `${where} (a)`)\n assertPredicate(rule.b, `${where} (b)`)\n break\n case 'neverUnless':\n assertPredicate(rule.p, `${where} (p)`)\n assertPredicate(rule.prior, `${where} (prior)`)\n break\n default:\n throw new ValidationError(\n `${where}: unknown rule kind \"${String((rule as ContractRule).kind)}\"`,\n )\n }\n }\n}\n\n/**\n * Order spans for temporal evaluation: by `startedAt` when EVERY span carries\n * one (stable — ties keep array order), by array order when NONE does. Mixed\n * timestamps throw: neither time order nor array order is a trustworthy total\n * order over a partially-stamped sequence, and guessing would corrupt\n * `precedes` / `neverUnless` verdicts.\n */\nfunction orderSpans(spans: readonly ContractSpan[]): ContractSpan[] {\n const timed = spans.filter(\n (s) => typeof s.startedAt === 'number' && Number.isFinite(s.startedAt),\n ).length\n if (timed === spans.length) {\n return spans\n .map((span, i) => ({ span, i }))\n .sort((x, y) => x.span.startedAt! - y.span.startedAt! || x.i - y.i)\n .map((x) => x.span)\n }\n if (timed === 0) return [...spans]\n throw new ValidationError(\n `evaluateTraceContract: ${timed}/${spans.length} spans carry a finite startedAt — ` +\n 'mixed timestamps make ordering ambiguous; stamp every span or none',\n )\n}\n\nfunction spanRef(span: ContractSpan, index: number): string {\n return span.spanId ?? `#${index}`\n}\n\n// precedes(a, b) and neverUnless(p, prior) share one semantics: every\n// guarded-match must have a STRICTLY earlier guard-match. The guard flag\n// updates after the guarded check, so a span matching both cannot witness\n// itself.\nfunction checkGuarded(args: {\n label: string\n ordered: readonly ContractSpan[]\n guard: SpanPredicate\n guarded: SpanPredicate\n detail: (ref: string) => string\n}): ContractViolation[] {\n const out: ContractViolation[] = []\n let guardSeen = false\n for (let i = 0; i < args.ordered.length; i++) {\n const span = args.ordered[i]!\n if (!guardSeen && matchSpan(span, args.guarded)) {\n out.push({ rule: args.label, spanId: span.spanId, detail: args.detail(spanRef(span, i)) })\n }\n if (matchSpan(span, args.guard)) guardSeen = true\n }\n return out\n}\n\nfunction checkRule(rule: ContractRule, ordered: readonly ContractSpan[]): ContractViolation[] {\n switch (rule.kind) {\n case 'always': {\n const out: ContractViolation[] = []\n for (let i = 0; i < ordered.length; i++) {\n const span = ordered[i]!\n if (!matchSpan(span, rule.p!)) {\n out.push({\n rule: rule.label,\n spanId: span.spanId,\n detail: `span ${spanRef(span, i)} (\"${span.name ?? ''}\") fails always(${describePredicate(rule.p!)})`,\n })\n }\n }\n return out\n }\n case 'never': {\n const out: ContractViolation[] = []\n for (let i = 0; i < ordered.length; i++) {\n const span = ordered[i]!\n if (matchSpan(span, rule.p!)) {\n out.push({\n rule: rule.label,\n spanId: span.spanId,\n detail: `span ${spanRef(span, i)} (\"${span.name ?? ''}\") matches never(${describePredicate(rule.p!)})`,\n })\n }\n }\n return out\n }\n case 'eventually': {\n const hit = ordered.some((span) => matchSpan(span, rule.p!))\n return hit\n ? []\n : [\n {\n rule: rule.label,\n detail: `no span matches eventually(${describePredicate(rule.p!)}) over ${ordered.length} span(s)`,\n },\n ]\n }\n case 'precedes':\n return checkGuarded({\n label: rule.label,\n ordered,\n guard: rule.a!,\n guarded: rule.b!,\n detail: (ref) =>\n `span ${ref} matches ${describePredicate(rule.b!)} with no earlier ${describePredicate(rule.a!)} match`,\n })\n case 'neverUnless':\n return checkGuarded({\n label: rule.label,\n ordered,\n guard: rule.prior!,\n guarded: rule.p!,\n detail: (ref) =>\n `span ${ref} matches ${describePredicate(rule.p!)} with no earlier ${describePredicate(rule.prior!)} match`,\n })\n }\n}\n\n/**\n * Evaluate one contract over a span sequence. Pure and synchronous — works\n * on `Span[]` from a TraceStore, `ExportableSpan[]` from the otel-bridge\n * flattening, or any array satisfying `ContractSpan`.\n */\nexport function evaluateTraceContract(\n contract: TraceContract,\n spans: readonly ContractSpan[],\n): ContractVerdict {\n assertContract(contract)\n const ordered = orderSpans(spans)\n const scores: Record<string, number> = {}\n const violations: ContractViolation[] = []\n for (const rule of contract.rules) {\n const ruleViolations = checkRule(rule, ordered)\n scores[rule.label] = ruleViolations.length === 0 ? 1 : 0\n violations.push(...ruleViolations)\n }\n const ruleCount = contract.rules.length\n const passCount = Object.values(scores).filter((s) => s === 1).length\n return {\n contract: contract.name,\n valid: passCount === ruleCount,\n score: passCount / ruleCount,\n scores,\n violations,\n notes: `${passCount}/${ruleCount} rules passed`,\n }\n}\n\n/**\n * Evaluate many contracts over one span sequence. Throws on an empty\n * contract list — `allValid: true` over zero contracts is a silent pass.\n */\nexport function checkTraceContracts(\n spans: readonly ContractSpan[],\n contracts: readonly TraceContract[],\n): ContractCheckResult {\n if (contracts.length === 0) {\n throw new ValidationError(\n 'checkTraceContracts: empty contract list would vacuously pass — supply at least one contract',\n )\n }\n const verdicts = contracts.map((c) => evaluateTraceContract(c, spans))\n return { verdicts, allValid: verdicts.every((v) => v.valid) }\n}\n\n// ── Campaign judge adapter ────────────────────────────────────────────\n\nexport interface ContractJudgeOptions<TArtifact, TScenario extends Scenario = Scenario> {\n /**\n * Project the span sequence out of a cell's artifact. `JudgeConfig.score`\n * receives only `{ artifact, scenario, signal }` (src/campaign/types.ts) —\n * spans are NOT reachable generically — so the consumer supplies this\n * explicit extraction (e.g. dispatch writes spans into the artifact, or\n * closes over a per-cell TraceStore read).\n */\n spans: (input: { artifact: TArtifact; scenario: TScenario }) => readonly ContractSpan[]\n /** Judge name in campaign reports. Default 'trace-contracts'. */\n name?: string\n}\n\n/**\n * Adapt trace contracts to a campaign `JudgeConfig`. One judge dimension per\n * contract (key = contract name, value = its rule-pass fraction); composite\n * is the mean across contracts. Deterministic — no LLM call.\n */\nexport function contractJudge<TArtifact, TScenario extends Scenario = Scenario>(\n contracts: readonly TraceContract[],\n opts: ContractJudgeOptions<TArtifact, TScenario>,\n): JudgeConfig<TArtifact, TScenario> {\n if (contracts.length === 0) {\n throw new ValidationError('contractJudge: at least one contract required')\n }\n for (const c of contracts) assertContract(c)\n const names = new Set<string>()\n for (const c of contracts) {\n if (names.has(c.name)) {\n throw new ValidationError(\n `contractJudge: duplicate contract name \"${c.name}\" would collapse judge dimensions`,\n )\n }\n names.add(c.name)\n }\n if (typeof opts?.spans !== 'function') {\n throw new ValidationError('contractJudge: opts.spans extraction function is required')\n }\n const dimensions: JudgeDimension[] = contracts.map((c) => ({\n key: c.name,\n description: c.rules.map((r) => r.label).join('; '),\n }))\n return {\n name: opts.name ?? 'trace-contracts',\n dimensions,\n score({ artifact, scenario }) {\n const spans = opts.spans({ artifact, scenario })\n if (!Array.isArray(spans)) {\n throw new ValidationError(\n `contractJudge: spans() must return a span array, got ${typeof spans}`,\n )\n }\n const { verdicts } = checkTraceContracts(spans, contracts)\n const dims: Record<string, number> = {}\n const violations: ContractViolation[] = []\n for (const v of verdicts) {\n dims[v.contract] = v.score\n violations.push(...v.violations)\n }\n const composite = verdicts.reduce((acc, v) => acc + v.score, 0) / verdicts.length\n return {\n dimensions: dims,\n composite,\n notes:\n violations.length === 0\n ? 'all trace contracts satisfied'\n : violations\n .slice(0, 8)\n .map((x) => `${x.rule}: ${x.detail}`)\n .join('\\n'),\n }\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'\nimport { evaluateTraceContract, type TraceContract } from './trace-contracts'\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 /** Evaluate a finite-trace temporal contract (`traceContract(...)`) over\n * this run's span sequence. See `trace-contracts.ts` for the operators. */\n toSatisfyContract(contract: TraceContract): Expectation {\n return {\n label: `agent(${this.runId}).toSatisfyContract(${contract.name})`,\n check: async () => {\n const spans = await this.store.spans({ runId: this.runId })\n const verdict = evaluateTraceContract(contract, spans)\n if (verdict.valid) {\n return { ok: true, detail: `contract \"${contract.name}\": ${verdict.notes}` }\n }\n return {\n ok: false,\n detail: verdict.violations.map((v) => `${v.rule}: ${v.detail}`).join('; '),\n evidence: verdict.violations.find((v) => v.spanId)?.spanId,\n }\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 * 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 {\n accessSync,\n existsSync,\n constants as fsConstants,\n readdirSync,\n readFileSync,\n statSync,\n} from 'node:fs'\nimport { delimiter, 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 return resolveBinOnPath(name) !== null\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 (err) {\n // ENOENT is the only \"legitimately absent\" signal → null. Any other\n // errno (EACCES, EISDIR, EIO, …) is a real failure that must NOT\n // masquerade as \"file not present\" — surface it so callers don't\n // treat a permission/IO error as a missing artifact.\n if (isErrnoCode(err, 'ENOENT')) return null\n throw err\n }\n },\n async readDir(path: string): Promise<DirEntry[]> {\n let entries: string[]\n try {\n entries = readdirSync(path)\n } catch (err) {\n // Same ENOENT-vs-real-error split as readFile: a missing directory\n // is legitimately empty (→ []); EACCES/ENOTDIR/EIO must surface so\n // an unreadable directory isn't silently reported as having no files.\n if (isErrnoCode(err, 'ENOENT')) return []\n throw err\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 (err) {\n // An entry that vanished between readdir and stat (TOCTOU) is a\n // benign race → skip. Any other errno surfaces.\n if (isErrnoCode(err, 'ENOENT')) continue\n throw err\n }\n }\n return out\n },\n}\n\nfunction isErrnoCode(err: unknown, code: NodeJS.ErrnoException['code']): boolean {\n return typeof err === 'object' && err !== null && (err as NodeJS.ErrnoException).code === code\n}\n\n/**\n * Resolve `name` to an executable absolute path using the runner's PATH,\n * or `null` if not found. Cross-platform: does not depend on `which`\n * (absent on Windows) or a `command -v` shell (absent on minimal\n * containers). On Windows, candidate extensions come from PATHEXT.\n *\n * Throws only on a non-ENOENT/EACCES filesystem error while probing a\n * candidate — those indicate a real IO fault, not \"binary absent.\"\n */\nfunction resolveBinOnPath(name: string): string | null {\n // An explicit path component means PATH lookup doesn't apply: probe directly.\n if (name.includes('/') || name.includes('\\\\')) {\n return isExecutable(name) ? name : null\n }\n const pathEnv = process.env.PATH ?? ''\n const dirs = pathEnv.split(delimiter).filter((d) => d.length > 0)\n const exts =\n process.platform === 'win32'\n ? (process.env.PATHEXT ?? '.COM;.EXE;.BAT;.CMD').split(';').filter((e) => e.length > 0)\n : ['']\n for (const dir of dirs) {\n for (const ext of exts) {\n const candidate = join(dir, name + ext)\n if (isExecutable(candidate)) return candidate\n }\n }\n return null\n}\n\nfunction isExecutable(path: string): boolean {\n try {\n // On win32 X_OK is a no-op; presence of the file (with a PATHEXT\n // extension) is the executability signal there.\n accessSync(path, process.platform === 'win32' ? fsConstants.F_OK : fsConstants.X_OK)\n return true\n } catch (err) {\n // Not found / not executable / not permitted → \"not a usable binary\n // here,\" keep scanning. A different errno (EIO, ELOOP, …) is a real\n // fault and must surface rather than silently yield a false negative.\n if (isErrnoCode(err, 'ENOENT') || isErrnoCode(err, 'EACCES') || isErrnoCode(err, 'ENOTDIR')) {\n return false\n }\n throw err\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 = 300_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 = re.exec(html)\n while (match !== 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 match = re.exec(html)\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\nimport type { DefaultVerdict } from './verdict'\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\n/** Extends the substrate verdict spine: `valid` = `allPass` and `score` =\n * `blendedScore` — derived where the report is aggregated, so spine\n * consumers (drivers, gates) read this report without an adapter. */\nexport interface VerificationReport extends DefaultVerdict {\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\n/**\n * Ordered DAG of verification layers with dependency-based skipping, per-layer findings, soft-fail semantics, and a blended composite score across all passed layers.\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 const allPass = ranAnyScoredLayer && !anyScoredLayerFailed && failCount === 0 && errorCount === 0\n const blendedScore = scoredWeightSum > 0 ? scoredWeightedTotal / scoredWeightSum : 0\n return {\n layers: results,\n passCount,\n failCount,\n skippedCount,\n errorCount,\n allPass,\n blendedScore,\n valid: allPass,\n score: blendedScore,\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 300s. */\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 ?? 300_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","import { gzipSync } from 'node:zlib'\nimport type { RunRecord } from './run-record'\n\n/**\n * DescriptionLengthGate — a Minimum-Description-Length promotion gate, the\n * Builder/Breaker acceptance rule from Wang & Buehler, \"Self-Revising Discovery\n * Systems for Science\" (arXiv:2606.01444, MIT LAMM), eq. 5:\n *\n * L(M, D) = L_model(M) + L_data(D | M)\n * accept M' over M iff L(M', D∪E) < L(M, D∪E)\n *\n * Both candidate and baseline are scored on the SAME enlarged evidence set\n * (every accumulated task — NOT just the held-out split), and the candidate is\n * accepted only if it lowers the TOTAL bit cost. This is the gate's whole\n * point and what distinguishes it from a monotone held-out delta:\n *\n * - L_model(M) — the candidate's own description length: the compressed size\n * of its model text (a prompt, skill, profile, or symbolic model). A bigger\n * model pays more bits.\n * - L_data(D|M) — the residual: bits of \"surprise\" that the model did not\n * simply succeed, −Σ_i log2(s_i) over the model's per-task score s_i.\n * Perfect scores cost 0 bits; failure costs a lot (capped, not infinite).\n *\n * A candidate that merely memorizes new counterexamples grows L_model faster\n * than it shrinks L_data and LOSES — a principled, complexity-penalized\n * alternative to HeldOutGate's held-out paired delta. Use this gate\n * when the model text whose size you want to penalize is available; use\n * HeldOutGate when promotion should turn on held-out generalization with an\n * overfit-gap check instead.\n *\n * Scale / calibration: a gzip'd prose model is hundreds–thousands of bits;\n * a single task contributes at most −log2(scoreFloor) data bits (≈10). So with\n * little evidence the model term dominates and the gate is conservative about\n * model GROWTH — it promotes a larger model only once accumulated evidence\n * genuinely pays for the added bits (exactly the paper's regime, where D∪E\n * grows). `lambda` is the lever: λ<1 discounts model bits (more permissive),\n * λ>1 is stricter. A shrinking-or-equal model that does no worse always wins.\n *\n * Stateless: construct once with the description-length budget, call\n * `evaluate` per (candidate, baseline) pair.\n */\n\nexport type DescriptionLengthRejectionCode = 'few_tasks' | 'no_total_gain' | 'model_bloat'\n\nexport interface DescriptionLengthConfig {\n /** Stable label of the baseline. Required — paper-grade evaluation never\n * compares two unlabelled candidates. */\n baselineKey: string\n /** Weight on model bits relative to data bits (the description-length\n * budget λ). 1 = bits are bits. >1 = more complexity-averse. Default 1. */\n lambda?: number\n /** The candidate must beat the baseline by at least this many bits to\n * promote — a robustness margin against measurement noise. Default 0\n * (strict `<`, as the paper). */\n marginBits?: number\n /** Per-task score floor for the residual code: −log2(max(s, floor)). Caps a\n * total-failure task's surprise instead of letting it diverge. Default\n * 2^-10 (a failed task costs 10 bits, not ∞). */\n scoreFloor?: number\n /** Minimum number of shared (candidate, baseline) tasks before the gate will\n * consider promoting. Default 3. */\n minTasks?: number\n}\n\nexport interface DescriptionLengthEvidence {\n /** Shared tasks scored on both sides (the enlarged evidence D∪E). */\n tasks: number\n /** Compressed-model bits — L_model. */\n modelBits: { candidate: number; baseline: number }\n /** Residual surprise bits — L_data(D|M). */\n dataBits: { candidate: number; baseline: number }\n /** λ·L_model + L_data — the quantity the gate minimizes. */\n totalBits: { candidate: number; baseline: number }\n /** candidate − baseline total. Negative = candidate compresses better. */\n deltaBits: number\n /** Per-component deltas, for audit: did the win come from a smaller model,\n * better outcomes, or both? */\n modelBitsDelta: number\n dataBitsDelta: number\n}\n\nexport interface DescriptionLengthDecision {\n promote: boolean\n candidateId: string\n baselineId: string\n evidence: DescriptionLengthEvidence\n reason: string\n rejectionCode: DescriptionLengthRejectionCode | null\n}\n\nexport interface DescriptionLengthCandidate {\n /** The model text whose size is L_model (a prompt, skill, profile, or\n * symbolic model; concatenated if several files). */\n content: string\n /** Runs whose per-task scores form L_data. */\n runs: RunRecord[]\n}\n\n/** Score a single run, preferring the held-out score, then search, then the\n * raw `score` metric. Returns undefined when the run carries no score. */\nfunction runScore(run: RunRecord): number | undefined {\n const o = run.outcome\n const s = o.holdoutScore ?? o.searchScore ?? o.raw?.score\n return typeof s === 'number' && Number.isFinite(s) ? s : undefined\n}\n\n/** Pairing key — the same scenario/experiment identity HeldOutGate pairs on. */\nfunction taskKey(run: RunRecord): string {\n return run.scenarioId ?? run.experimentId\n}\n\n/** Mean per-task score for a model: { taskKey -> mean(score over its runs) }. */\nfunction perTaskMeanScore(runs: RunRecord[]): Map<string, number> {\n const acc = new Map<string, { sum: number; n: number }>()\n for (const run of runs) {\n const s = runScore(run)\n if (s === undefined) continue\n const key = taskKey(run)\n const cur = acc.get(key) ?? { sum: 0, n: 0 }\n cur.sum += s\n cur.n += 1\n acc.set(key, cur)\n }\n return new Map([...acc].map(([k, v]) => [k, v.sum / v.n]))\n}\n\n/** Compressed-model bits — the model's description length L_model. gzip is a\n * deterministic, dependency-free stand-in for Kolmogorov complexity; it\n * rewards genuine compactness and penalizes boilerplate padding. */\nexport function modelDescriptionBits(content: string): number {\n return gzipSync(Buffer.from(content, 'utf8')).byteLength * 8\n}\n\n/** Residual surprise L_data(D|M) = −Σ_i log2(max(s_i, floor)) over the given\n * per-task scores. Lower = the model more reliably succeeds. */\nexport function dataDescriptionBits(\n scoreByTask: Map<string, number>,\n keys: Iterable<string>,\n scoreFloor: number,\n): number {\n let bits = 0\n for (const key of keys) {\n const s = scoreByTask.get(key)\n if (s === undefined) continue\n bits += -Math.log2(Math.max(s, scoreFloor))\n }\n return bits\n}\n\nexport class DescriptionLengthGate {\n private readonly baselineKey: string\n private readonly lambda: number\n private readonly marginBits: number\n private readonly scoreFloor: number\n private readonly minTasks: number\n\n constructor(config: DescriptionLengthConfig) {\n if (!config.baselineKey) throw new Error('DescriptionLengthGate: baselineKey is required')\n this.baselineKey = config.baselineKey\n this.lambda = config.lambda ?? 1\n this.marginBits = config.marginBits ?? 0\n this.scoreFloor = config.scoreFloor ?? 2 ** -10\n this.minTasks = config.minTasks ?? 3\n if (!(this.lambda >= 0)) throw new Error('DescriptionLengthGate: lambda must be ≥ 0')\n if (!(this.scoreFloor > 0 && this.scoreFloor < 1))\n throw new Error('DescriptionLengthGate: scoreFloor must be in (0,1)')\n }\n\n /** Decide whether `candidate` should replace `baseline`. Both are scored on\n * the shared task set (the enlarged evidence); the candidate promotes only\n * if λ·L_model + L_data is strictly lower by at least `marginBits`. */\n evaluate(\n candidate: DescriptionLengthCandidate,\n baseline: DescriptionLengthCandidate,\n ): DescriptionLengthDecision {\n const candidateId = inferCandidateId(candidate.runs, this.baselineKey)\n const candScores = perTaskMeanScore(candidate.runs)\n const baseScores = perTaskMeanScore(baseline.runs)\n // Enlarged evidence = tasks scored on BOTH sides (paired, like the paper's\n // \"both models refit on the same accumulated evidence\").\n const shared = [...candScores.keys()].filter((k) => baseScores.has(k))\n\n const modelBits = {\n candidate: this.lambda * modelDescriptionBits(candidate.content),\n baseline: this.lambda * modelDescriptionBits(baseline.content),\n }\n const dataBits = {\n candidate: dataDescriptionBits(candScores, shared, this.scoreFloor),\n baseline: dataDescriptionBits(baseScores, shared, this.scoreFloor),\n }\n const totalBits = {\n candidate: modelBits.candidate + dataBits.candidate,\n baseline: modelBits.baseline + dataBits.baseline,\n }\n const evidence: DescriptionLengthEvidence = {\n tasks: shared.length,\n modelBits,\n dataBits,\n totalBits,\n deltaBits: totalBits.candidate - totalBits.baseline,\n modelBitsDelta: modelBits.candidate - modelBits.baseline,\n dataBitsDelta: dataBits.candidate - dataBits.baseline,\n }\n const base = { candidateId, baselineId: this.baselineKey, evidence }\n const fmt = (n: number) => n.toFixed(1)\n\n if (shared.length < this.minTasks) {\n return {\n ...base,\n promote: false,\n reason: `few_tasks: ${shared.length} shared task(s) < min ${this.minTasks}`,\n rejectionCode: 'few_tasks',\n }\n }\n if (!(evidence.deltaBits < -this.marginBits)) {\n // No net compression. Name the cause: did the model bloat eat a real\n // data gain, or was there no data gain at all?\n const code: DescriptionLengthRejectionCode =\n evidence.dataBitsDelta < 0 ? 'model_bloat' : 'no_total_gain'\n const why =\n code === 'model_bloat'\n ? `model grew ${fmt(evidence.modelBitsDelta)} bits, outpacing a ${fmt(-evidence.dataBitsDelta)}-bit data gain`\n : `outcomes did not improve (data Δ=${fmt(evidence.dataBitsDelta)} bits)`\n return {\n ...base,\n promote: false,\n reason: `${code}: total Δ=${fmt(evidence.deltaBits)} bits does not clear the ${fmt(this.marginBits)}-bit margin — ${why}`,\n rejectionCode: code,\n }\n }\n return {\n ...base,\n promote: true,\n reason: `promote: total Δ=${fmt(evidence.deltaBits)} bits (model Δ=${fmt(evidence.modelBitsDelta)}, data Δ=${fmt(evidence.dataBitsDelta)}) over ${shared.length} tasks`,\n rejectionCode: null,\n }\n }\n}\n\nfunction inferCandidateId(runs: RunRecord[], baselineKey: string): string {\n for (const run of runs)\n if (run.candidateId && run.candidateId !== baselineKey) return run.candidateId\n return runs[0]?.candidateId ?? '(unknown candidate)'\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 * 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 interface Waiter {\n resolve: (s: SlotState<T>) => void\n reject: (err: unknown) => void\n }\n const waiters: Waiter[] = []\n const mutex = new Mutex()\n let nextSlotId = 0\n // In-flight mints: a slot is decided under the mutex but only push()ed into\n // `slots` AFTER the un-locked factory.create(). Counting reservations against\n // capacity in the SAME critical section as the gate stops two concurrent\n // acquires from both minting past `size` (slots.length alone is still 0 for\n // both until the first push lands).\n let reserving = 0\n let totalCheckouts = 0\n let busyMs = 0\n let drained = false\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 + reserving < opts.size) {\n // Reserve capacity synchronously (live slots + in-flight mints) so\n // concurrent acquireSlot calls can't all decide to mint past the cap.\n mintId = `slot_${nextSlotId++}`\n reserving++\n return null\n }\n return null\n })\n if (ready) return ready\n if (mintId !== undefined) {\n let resource: T\n try {\n resource = await opts.factory.create(mintId)\n } catch (err) {\n // Release the reservation and hand the freed capacity to a waiter,\n // otherwise a failed create leaks a capacity slot forever.\n await mutex.runExclusive(() => {\n reserving--\n })\n if (!drained) wakeWaiterToMint()\n throw err\n }\n const state: SlotState<T> = {\n slot: { id: mintId, resource },\n busy: true,\n }\n await mutex.runExclusive(() => {\n slots.push(state)\n reserving--\n })\n return state\n }\n // All slots busy + at cap: queue.\n return new Promise<SlotState<T>>((resolve, reject) => {\n waiters.push({ resolve, reject })\n })\n }\n\n /**\n * Hand `state` (clean + idle) to the next queued waiter, or leave it\n * idle if none are waiting. Caller must have already marked the slot\n * not-busy. Runs under no lock; waiters are FIFO.\n */\n function handOffCleanSlot(state: SlotState<T>): void {\n const next = waiters.shift()\n if (next) {\n state.busy = true\n next.resolve(state)\n }\n }\n\n /**\n * Wake a queued waiter when a slot was destroyed (so capacity freed up\n * but no clean slot is on hand). The waiter re-enters acquisition and\n * mints a fresh slot. Any acquisition failure is routed to that waiter\n * — never dropped on the floor.\n */\n function wakeWaiterToMint(): void {\n const next = waiters.shift()\n if (!next) return\n acquireSlot().then(next.resolve, next.reject)\n }\n\n /**\n * Release a checked-out slot. Reset is async; we kick it off and the\n * slot only becomes available to the next waiter once reset lands\n * CLEAN. If reset fails, the slot is dirty — destroy and remove it\n * rather than recycle a corrupted workspace to the next waiter, then\n * free the capacity so a fresh slot can be minted. The whole flow is\n * awaited inside one IIFE whose rejection is caught, so a failed\n * destroy can't surface as an unhandled rejection.\n */\n function releaseSlot(state: SlotState<T>): void {\n void (async () => {\n try {\n if (opts.factory.reset) {\n await opts.factory.reset(state.slot)\n }\n state.busy = false\n if (!drained) handOffCleanSlot(state)\n } catch (resetErr) {\n // Dirty slot: do NOT recycle it. Remove from the pool and tear it\n // down, then wake a waiter to mint a clean replacement.\n await mutex.runExclusive(() => {\n const i = slots.indexOf(state)\n if (i !== -1) slots.splice(i, 1)\n })\n try {\n await opts.factory.destroy(state.slot)\n } catch (destroyErr) {\n console.warn(\n `[sandbox-pool] destroy of dirty slot ${state.slot.id} failed after reset error:`,\n destroyErr,\n )\n }\n console.warn(\n `[sandbox-pool] reset failed for slot ${state.slot.id} — slot destroyed, not recycled:`,\n resetErr,\n )\n if (!drained) wakeWaiterToMint()\n }\n })().catch((err) => {\n // Defense in depth: nothing above should throw out here, but if it\n // does, surface it instead of producing an unhandled rejection.\n console.warn(`[sandbox-pool] release of slot ${state.slot.id} faulted:`, err)\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 drained = true\n // Snapshot under lock; destroy outside lock so a slow teardown\n // doesn't block a concurrent drain caller.\n const { snapshot, pending } = await mutex.runExclusive(() => {\n const taken = slots.splice(0, slots.length)\n const queued = waiters.splice(0, waiters.length)\n return { snapshot: taken, pending: queued }\n })\n // Reject any pending waiters — the pool is going away, so their\n // checkout promise can never be satisfied. Failing loud beats leaving\n // a caller hung on an awaited checkout() forever.\n for (const w of pending) {\n w.reject(new Error('sandbox pool drained while a checkout was pending'))\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\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 { JudgeParseError } from './judges'\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 let failedJudges = 0\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 try {\n const scores = await tracedFn(tc, input)\n allScores.push(...scores)\n } catch (err) {\n // One unparseable judge must not sink the whole ensemble — its\n // child span is already marked failed by traceJudge; record it and\n // keep scoring with the surviving judges. Anything else (network,\n // abort) still aborts the ensemble.\n if (!(err instanceof JudgeParseError)) throw err\n failedJudges++\n }\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 'judge.failed_judges': failedJudges,\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","/**\n * Agreement judge for teacher→student distillation. Scores a STUDENT artifact\n * (the cheap analyst's produced label) against the GoldScenario's gold label\n * (the teacher's verdict). The score IS the distillation objective: 1.0 means\n * the student reproduced the teacher exactly, 0.0 means total disagreement.\n *\n * The comparison function is INJECTED (`compareLabels`) so the judge is\n * domain-agnostic — distilling a skill-audit analyst, a triage analyst, or any\n * other student is a one-line comparator swap. A default `fieldAgreement`\n * comparator is provided for the common case: a flat verdict object with\n * categorical and array fields.\n *\n * Everything here is PURE + unit-testable — no LLM. (The student spends tokens\n * producing the artifact; scoring it against frozen gold does not.)\n */\n\nimport type { JudgeConfig, JudgeScore, Scenario } from '../types'\nimport type { GoldScenario } from './gold-scenarios'\n\n/** What an injected comparator returns: a [0,1] composite plus the per-field\n * (per-dimension) agreement breakdown the GEPA proposer reflects on to learn\n * WHICH part of the verdict the student is getting wrong. */\nexport interface AgreementResult {\n /** Overall agreement in [0,1]. */\n score: number\n /** Per-dimension agreement in [0,1] — keyed by field/aspect name. The\n * reflective proposer surfaces the weakest of these as the lever to fix. */\n dimensions: Record<string, number>\n}\n\n/** Compare a produced label against a gold label → agreement. Injected so the\n * judge is domain-agnostic. */\nexport type CompareLabels<TProduced = unknown, TLabel = unknown> = (\n produced: TProduced,\n gold: TLabel,\n) => AgreementResult\n\nexport interface BuildAgreementJudgeOptions<TProduced = unknown, TLabel = unknown> {\n /** Judge name surfaced in `CampaignResult.aggregates.byJudge` + the gate. */\n name?: string\n /** The agreement function — produced student label vs gold teacher label. */\n compareLabels: CompareLabels<TProduced, TLabel>\n /** Dimension keys the judge declares up-front (for `JudgeConfig.dimensions`).\n * When omitted, the dimensions present on the first scored result are used\n * for display only; the composite is unaffected. */\n dimensionKeys?: string[]\n /** Only score `gold`-kind scenarios. Default true — a mixed campaign won't\n * mis-apply the agreement judge to non-gold scenarios. */\n goldOnly?: boolean\n}\n\nconst AGREEMENT_DIM = 'agreement'\n\n/** Build a `JudgeConfig` that scores a produced student artifact against the\n * scenario's gold label. Conforms to the substrate `JudgeConfig` contract:\n * `score({artifact, scenario, signal}) => JudgeScore`. The `composite` is the\n * comparator's `score`; `dimensions` carries its per-field breakdown plus the\n * scalar `agreement` so a single-dimension consumer still sees the number. */\nexport function buildAgreementJudge<TProduced, TInput, TLabel>(\n options: BuildAgreementJudgeOptions<TProduced, TLabel>,\n): JudgeConfig<TProduced, GoldScenario<TInput, TLabel>> {\n const name = options.name ?? 'gold-agreement'\n const goldOnly = options.goldOnly ?? true\n const declaredDims = options.dimensionKeys ?? [AGREEMENT_DIM]\n return {\n name,\n dimensions: declaredDims.map((key) => ({\n key,\n description: `Per-field agreement between the produced label and the gold label on '${key}'`,\n })),\n appliesTo: goldOnly ? (scenario: Scenario) => scenario.kind === 'gold' : undefined,\n score({ artifact, scenario }): JudgeScore {\n const { score, dimensions } = options.compareLabels(artifact, scenario.label)\n if (!Number.isFinite(score) || score < 0 || score > 1) {\n throw new Error(\n `buildAgreementJudge: comparator returned out-of-range score ${score} for scenario '${scenario.id}' (must be in [0,1])`,\n )\n }\n // Surface the scalar under `agreement` too, so a consumer reading a\n // single dimension always finds the headline number even when the\n // comparator named its fields differently.\n const outDims: Record<string, number> = { [AGREEMENT_DIM]: score, ...dimensions }\n const weakest = Object.entries(dimensions).sort((a, b) => a[1] - b[1])[0]\n const notes = weakest\n ? `agreement ${score.toFixed(3)}; weakest field '${weakest[0]}' (${weakest[1].toFixed(3)})`\n : `agreement ${score.toFixed(3)}`\n return { composite: score, dimensions: outDims, notes }\n },\n }\n}\n\nexport interface FieldAgreementSpec {\n /** Categorical fields — scored exact-match (1 if equal, else 0). Compared\n * with `===` after `JSON`-normalizing so `true`/`'high'`/`3` all work. */\n categorical?: string[]\n /** Array fields — scored by Jaccard overlap (|A∩B| / |A∪B|). Two empty\n * arrays agree perfectly (1.0). Order-insensitive; elements compared by\n * their `JSON.stringify`. */\n array?: string[]\n}\n\n/** Default comparator: average per-field agreement over a flat verdict object.\n * Categorical fields score exact-match; array fields score set-overlap\n * (Jaccard). The composite is the unweighted mean across all declared fields,\n * so missing a single boolean (e.g. `public_leak_risk`) costs `1/nFields` of\n * the score — the leak-detection lever the audit cares about is a real,\n * non-trivial fraction of the objective, not rounding noise.\n *\n * Pure. A field absent from BOTH produced + gold is treated as agreeing\n * (both undefined ⇒ 1.0); a field present in only one side disagrees. */\nexport function fieldAgreement<TProduced extends Record<string, unknown>, TLabel>(\n spec: FieldAgreementSpec,\n): CompareLabels<TProduced, TLabel> {\n const categorical = spec.categorical ?? []\n const array = spec.array ?? []\n if (categorical.length === 0 && array.length === 0) {\n throw new Error('fieldAgreement: at least one categorical or array field is required')\n }\n return (produced, gold) => {\n const p = (produced ?? {}) as Record<string, unknown>\n const g = (gold ?? {}) as Record<string, unknown>\n const dimensions: Record<string, number> = {}\n for (const field of categorical) {\n dimensions[field] = categoricalAgreement(p[field], g[field])\n }\n for (const field of array) {\n dimensions[field] = jaccard(asArray(p[field]), asArray(g[field]))\n }\n const values = Object.values(dimensions)\n const score = values.length === 0 ? 0 : values.reduce((a, b) => a + b, 0) / values.length\n return { score, dimensions }\n }\n}\n\nfunction categoricalAgreement(produced: unknown, gold: unknown): number {\n if (produced === undefined && gold === undefined) return 1\n // Normalize so primitives compare by value regardless of source typing\n // (e.g. a produced boolean vs a gold boolean parsed from JSON).\n return normalizeScalar(produced) === normalizeScalar(gold) ? 1 : 0\n}\n\nfunction normalizeScalar(value: unknown): string {\n // Sentinels carry a leading '\\0'-free marker JSON.stringify never produces\n // (its output of any value starts with a quote, brace, bracket, digit, or\n // -/t/f/n) so they can't collide with a real stringified value.\n if (value === undefined) return '__undefined__'\n if (value === null) return '__null__'\n return JSON.stringify(value)\n}\n\nfunction asArray(value: unknown): unknown[] {\n if (Array.isArray(value)) return value\n if (value === undefined || value === null) return []\n return [value]\n}\n\n/** Jaccard similarity over two multisets compared by `JSON.stringify` of each\n * element. Two empty sets ⇒ 1.0 (perfect agreement on \"nothing\"). */\nfunction jaccard(a: unknown[], b: unknown[]): number {\n const sa = new Set(a.map((x) => JSON.stringify(x)))\n const sb = new Set(b.map((x) => JSON.stringify(x)))\n if (sa.size === 0 && sb.size === 0) return 1\n let inter = 0\n for (const x of sa) if (sb.has(x)) inter++\n const union = sa.size + sb.size - inter\n return union === 0 ? 1 : inter / union\n}\n","/**\n * Gold scenarios for teacher→student distillation. The TEACHER is an\n * expensive workflow (e.g. the 70-agent skill audit) whose verdicts are\n * frozen as gold labels; the STUDENT is a cheap single-shot analyst whose\n * prompt GEPA optimizes toward reproducing those labels.\n *\n * A `GoldScenario` is a `Scenario` (the substrate's input contract) carrying\n * an OPAQUE `input` (what the student sees) and an OPAQUE `label` (the gold\n * verdict the student's output is scored against). Both are typed `unknown`\n * here: this module is domain-agnostic — it distills ANY analyst against ANY\n * gold JSONL. The agreement comparator (see `agreement-judge.ts`) is what\n * knows the label's shape.\n *\n * Loading + splitting are DETERMINISTIC and LLM-free: the gold set is the\n * fixed ground truth, never regenerated here.\n */\n\nimport { readFileSync } from 'node:fs'\nimport type { Scenario } from '../types'\n\n/** A held gold record: opaque student-input + opaque gold-label, carried as a\n * substrate `Scenario` so it flows through `runCampaign` unchanged. */\nexport interface GoldScenario<TInput = unknown, TLabel = unknown> extends Scenario {\n kind: 'gold'\n /** What the student analyst is shown (rendered into its user prompt). */\n input: TInput\n /** The teacher's gold verdict — the target the student's output is scored\n * against by the agreement judge. NEVER shown to the student. */\n label: TLabel\n}\n\n/** One raw JSONL line. `scenarioId` and `id` are both accepted (the audit\n * emits `scenarioId`); `split` is honored when present. */\ninterface GoldJsonlLine {\n scenarioId?: string\n id?: string\n input: unknown\n label: unknown\n split?: 'train' | 'test'\n}\n\n/** Read a gold JSONL (one `{scenarioId|id, input, label, split?}` per line) into\n * `GoldScenario[]`. Deterministic, no LLM. Blank lines are skipped; a line\n * missing an id, `input`, or `label` throws (a silent skip would corrupt the\n * split silently — fail loud on a malformed gold set). */\nexport function loadGoldScenarios<TInput = unknown, TLabel = unknown>(\n jsonlPath: string,\n): GoldScenario<TInput, TLabel>[] {\n const text = readFileSync(jsonlPath, 'utf8')\n return parseGoldJsonl<TInput, TLabel>(text, jsonlPath)\n}\n\n/** Parse gold JSONL text directly (no fs). Exported so tests + in-memory\n * callers exercise the same parse path as {@link loadGoldScenarios}. */\nexport function parseGoldJsonl<TInput = unknown, TLabel = unknown>(\n text: string,\n sourceLabel = '<inline>',\n): GoldScenario<TInput, TLabel>[] {\n const out: GoldScenario<TInput, TLabel>[] = []\n const lines = text.split('\\n')\n for (let i = 0; i < lines.length; i++) {\n const raw = lines[i]!.trim()\n if (raw.length === 0) continue\n let parsed: GoldJsonlLine\n try {\n parsed = JSON.parse(raw) as GoldJsonlLine\n } catch (err) {\n throw new Error(\n `loadGoldScenarios: ${sourceLabel}:${i + 1} is not valid JSON — ${\n err instanceof Error ? err.message : String(err)\n }`,\n )\n }\n const rawId = parsed.scenarioId ?? parsed.id\n if (typeof rawId !== 'string' || rawId.length === 0) {\n throw new Error(\n `loadGoldScenarios: ${sourceLabel}:${i + 1} missing string \\`scenarioId\\`/\\`id\\``,\n )\n }\n // runCampaign forms the cellId as `${scenario.id}:${rep}` and heldOutGate\n // recovers the scenarioId via `cellId.split(':')[0]`. A ':' in the id (the\n // real skill-audit gold uses ids like `skill:blueprint-launch`) would\n // collapse every scenario into the first segment's bucket and zero the\n // holdout delta. Sanitize ':' → '__' for the campaign id; the original is\n // preserved on the scenario for display + traceback.\n const id = rawId.replace(/:/g, '__')\n if (parsed.input === undefined) {\n throw new Error(`loadGoldScenarios: ${sourceLabel}:${i + 1} (${rawId}) missing \\`input\\``)\n }\n if (parsed.label === undefined) {\n throw new Error(`loadGoldScenarios: ${sourceLabel}:${i + 1} (${rawId}) missing \\`label\\``)\n }\n const scenario: GoldScenario<TInput, TLabel> = {\n id,\n kind: 'gold',\n input: parsed.input as TInput,\n label: parsed.label as TLabel,\n }\n const tags: string[] = []\n if (id !== rawId) tags.push(`gold-id:${rawId}`)\n if (parsed.split !== undefined) tags.push(`split:${parsed.split}`)\n if (tags.length > 0) scenario.tags = tags\n out.push(scenario)\n }\n if (out.length === 0) {\n throw new Error(`loadGoldScenarios: ${sourceLabel} contained no gold records`)\n }\n return out\n}\n\nexport interface SplitGoldOptions {\n /** Every Nth scenario (0-based index) goes to the TEST/holdout split; the\n * rest train. Default 4 ⇒ a 25% holdout. Ignored for any scenario that\n * carries an explicit `split:` tag (that is honored verbatim). */\n testEveryNth?: number\n}\n\nexport interface GoldSplit<TInput, TLabel> {\n /** Training scenarios — the optimization pool the proposer searches over. */\n train: GoldScenario<TInput, TLabel>[]\n /** Held-out scenarios — kept OUT of training; scored only at the gate. */\n test: GoldScenario<TInput, TLabel>[]\n}\n\n/** Deterministic train/test split. A scenario tagged `split:train|test` is\n * routed by that tag; the rest fall to a modulo split (`index % testEveryNth\n * === 0 ⇒ test`). Pure — same input always yields the same split, so a gold\n * set's holdout is stable across runs (a shuffled split would let a lucky\n * seed flatter the gate). */\nexport function splitGold<TInput, TLabel>(\n scenarios: GoldScenario<TInput, TLabel>[],\n options: SplitGoldOptions = {},\n): GoldSplit<TInput, TLabel> {\n const testEveryNth = options.testEveryNth ?? 4\n if (!Number.isInteger(testEveryNth) || testEveryNth < 2) {\n throw new Error('splitGold: testEveryNth must be an integer ≥ 2 (else train or test is empty)')\n }\n const train: GoldScenario<TInput, TLabel>[] = []\n const test: GoldScenario<TInput, TLabel>[] = []\n let implicitIndex = 0\n for (const scenario of scenarios) {\n const explicit = explicitSplit(scenario)\n if (explicit === 'train') {\n train.push(scenario)\n } else if (explicit === 'test') {\n test.push(scenario)\n } else {\n // Only implicit scenarios are counted for the modulo, so honoring some\n // explicit tags doesn't skew the deterministic stride of the rest.\n if (implicitIndex % testEveryNth === 0) test.push(scenario)\n else train.push(scenario)\n implicitIndex += 1\n }\n }\n return { train, test }\n}\n\nfunction explicitSplit(scenario: GoldScenario): 'train' | 'test' | undefined {\n for (const tag of scenario.tags ?? []) {\n if (tag === 'split:train') return 'train'\n if (tag === 'split:test') return 'test'\n }\n return undefined\n}\n","/**\n * `runDistillation` — the teacher→student distillation loop. COMPOSES existing\n * substrate primitives; reimplements none of them:\n *\n * - DRIVER = `gepaProposer` (reflective prompt optimizer)\n * - LOOP = `runImprovementLoop` (outer: optimize → holdout re-score → gate)\n * - MEASUREMENT = `runCampaign` (inside the loop) scoring the student\n * - JUDGE = `buildAgreementJudge` — student label vs gold teacher label\n * - GATE = caller-supplied (`heldOutGate` / `defaultProductionGate`)\n * - STUDENT = a cheap single-shot analyst whose system prompt is the\n * `MutableSurface` GEPA mutates; it calls the LLM through\n * `createChatClient` and emits a JSON label.\n *\n * The surface IS the student's system prompt. Each generation GEPA rewrites it;\n * `dispatchWithSurface` renders {surface + scenario.input} into a chat request,\n * calls the (cheap) model, parses the produced JSON label, and returns it as\n * the artifact. The agreement judge scores that label against the gold label.\n *\n * `autoOnPromote: 'none'` is FORCED — the loop never opens a PR; the caller\n * (the `distill` CLI) decides what to do with the winning prompt.\n */\n\nimport {\n type ChatRequest,\n type ChatResponse,\n type CreateChatClientOpts,\n createChatClient,\n} from '../../analyst/chat-client'\nimport type { LlmCallResult, LlmClientOptions } from '../../llm-client'\nimport { heldOutGate } from '../gates/heldout-gate'\nimport { type RunImprovementLoopResult, runImprovementLoop } from '../presets/run-improvement-loop'\nimport { type GepaProposerConstraints, gepaProposer } from '../proposers/gepa'\nimport { campaignMeanComposite } from '../score-utils'\nimport type { CampaignResult, Gate, JudgeConfig } from '../types'\nimport type { GoldScenario } from './gold-scenarios'\n\n/** Render the student's prompt from {current surface, scenario input}. The\n * surface is the system prompt; the scenario input is the user turn. Override\n * to inject few-shot framing or a JSON-schema reminder. */\nexport type RenderStudentPrompt<TInput> = (args: {\n surface: string\n input: TInput\n scenarioId: string\n}) => ChatRequest['messages']\n\n/** Parse the model's raw text into a typed produced label. Throws on\n * unparseable output — a thrown dispatch is recorded as a failed cell (never\n * silently scored 0), which is the honest signal that the prompt isn't\n * emitting valid JSON yet. */\nexport type ParseStudentLabel<TProduced> = (rawContent: string, scenarioId: string) => TProduced\n\nexport interface RunDistillationOptions<TProduced, TInput, TLabel> {\n /** The student analyst's INITIAL system prompt — the baseline surface GEPA\n * searches from. */\n baselinePrompt: string\n /** Training scenarios (the optimization pool). */\n train: GoldScenario<TInput, TLabel>[]\n /** Held-out scenarios — kept OUT of training; scored only at the gate. */\n holdout: GoldScenario<TInput, TLabel>[]\n /** Transport for BOTH the student (cheap model) and the GEPA reflection\n * (the optimizer model). The student calls it via `createChatClient`. */\n llm: CreateChatClientOpts\n /** Router transport the GEPA proposer reflects through. `gepaProposer` uses the\n * package `LlmClient` directly (`LlmClientOptions`), not the ChatClient —\n * pass the router creds here. A test may inject `fetch` to stub the\n * reflection HTTP and exercise the wiring without real tokens. */\n reflectionLlm: LlmClientOptions\n /** Cheap model the student runs (e.g. a small/fast model). */\n studentModel: string\n /** Model GEPA uses to propose prompt rewrites (typically a stronger model). */\n optimizerModel: string\n /** Agreement judge — produced student label vs gold teacher label. */\n judge: JudgeConfig<TProduced, GoldScenario<TInput, TLabel>>\n /** Promotion gate. Default: `heldOutGate` over the holdout. Pass\n * `defaultProductionGate({ holdoutScenarios: holdout, ... })` for the full\n * red-team / reward-hacking / canary stack. */\n gate?: Gate<TProduced, GoldScenario<TInput, TLabel>>\n /** GEPA population size (candidates per generation). Default 4. */\n populationSize?: number\n /** GEPA generations. Default 3. */\n maxGenerations?: number\n /** Campaign reps per scenario. Default 1 — raise for CI bands on a flaky\n * student. */\n reps?: number\n /** Where campaign artifacts + traces land. Default a temp dir under cwd. */\n runDir?: string\n /** Levers offered to the GEPA reflection prompt. */\n mutationPrimitives?: string[]\n /** GEPA structured-doc constraints (preserve sections, edit budget). */\n constraints?: GepaProposerConstraints\n /** Gate's minimum holdout-agreement delta to ship. Default 0.0 — a\n * distillation run reports the lift; the caller decides the bar. Only used\n * when `gate` is omitted (the default `heldOutGate`). */\n deltaThreshold?: number\n /** Render the student prompt. Default: surface as system, JSON-stringified\n * input as the user turn with a JSON-only instruction. */\n renderStudentPrompt?: RenderStudentPrompt<TInput>\n /** Parse the model's text into a produced label. Default: strict JSON parse\n * with fenced-block stripping. */\n parseStudentLabel?: ParseStudentLabel<TProduced>\n /** Per-student-call sampling temperature. Default 0 (deterministic student;\n * the optimization signal must come from the PROMPT, not sampling noise). */\n studentTemperature?: number\n /** Per-student-call max tokens. Default 1024. */\n studentMaxTokens?: number\n}\n\nexport interface RunDistillationResult<TProduced, TInput, TLabel>\n extends RunImprovementLoopResult<TProduced, GoldScenario<TInput, TLabel>> {\n /** The winning student prompt (a string surface). */\n winnerPrompt: string\n /** Mean agreement on the HOLDOUT — baseline vs winner. The headline number:\n * did distillation move the student closer to the teacher on UNSEEN gold? */\n holdoutAgreement: { baseline: number; winner: number; delta: number }\n}\n\nexport async function runDistillation<TProduced, TInput, TLabel>(\n opts: RunDistillationOptions<TProduced, TInput, TLabel>,\n): Promise<RunDistillationResult<TProduced, TInput, TLabel>> {\n if (opts.train.length === 0) throw new Error('runDistillation: train split is empty')\n if (opts.holdout.length === 0) throw new Error('runDistillation: holdout split is empty')\n\n const chat = createChatClient(opts.llm)\n const render = opts.renderStudentPrompt ?? defaultRenderStudentPrompt\n const parse = opts.parseStudentLabel ?? (defaultParseStudentLabel as ParseStudentLabel<TProduced>)\n const runDir = opts.runDir ?? `.evolve/distillation/${Date.now()}`\n const studentTemperature = opts.studentTemperature ?? 0\n const studentMaxTokens = opts.studentMaxTokens ?? 1024\n\n const proposer = gepaProposer({\n llm: opts.reflectionLlm,\n model: opts.optimizerModel,\n target:\n 'a cheap single-shot analyst system prompt that reproduces an expensive workflow gold verdict',\n mutationPrimitives: opts.mutationPrimitives ?? DEFAULT_MUTATION_PRIMITIVES,\n constraints: opts.constraints,\n })\n\n const gate =\n opts.gate ??\n heldOutGate<TProduced, GoldScenario<TInput, TLabel>>({\n scenarios: opts.holdout,\n deltaThreshold: opts.deltaThreshold ?? 0,\n })\n\n const loop = await runImprovementLoop<GoldScenario<TInput, TLabel>, TProduced>({\n baselineSurface: opts.baselinePrompt,\n scenarios: opts.train,\n holdoutScenarios: opts.holdout,\n judges: [opts.judge],\n proposer,\n gate,\n autoOnPromote: 'none', // the loop NEVER opens a PR — the caller decides\n populationSize: opts.populationSize ?? 4,\n maxGenerations: opts.maxGenerations ?? 3,\n reps: opts.reps ?? 1,\n runDir,\n // The student spends tokens; tracing must stay on (the proposer is wired and\n // runImprovementLoop refuses tracing='off' with a proposer).\n tracing: 'on',\n dispatchWithSurface: async (surface, scenario, ctx) => {\n const prompt = render({\n surface: typeof surface === 'string' ? surface : JSON.stringify(surface),\n input: scenario.input,\n scenarioId: scenario.id,\n })\n const response: ChatResponse = await chat.chat(\n {\n model: opts.studentModel,\n messages: prompt,\n jsonMode: true,\n temperature: studentTemperature,\n maxTokens: studentMaxTokens,\n },\n { signal: ctx.signal },\n )\n reportUsage(ctx.cost, response)\n return parse(response.content, scenario.id)\n },\n })\n\n const winnerPrompt =\n typeof loop.winnerSurface === 'string' ? loop.winnerSurface : opts.baselinePrompt\n const baseline = campaignMeanComposite(loop.baselineOnHoldout)\n const winner = campaignMeanComposite(loop.winnerOnHoldout)\n\n return {\n ...loop,\n winnerPrompt,\n holdoutAgreement: { baseline, winner, delta: winner - baseline },\n }\n}\n\n/** Report the student call's cost + tokens to the cell meter. A cell that\n * reports neither reads as a stub to `assertRealBackend` — every student call\n * MUST report. When the proxy doesn't return a cost we still report tokens so\n * the cell is non-stub. */\nfunction reportUsage(\n cost: {\n observe(amountUsd: number, source: string): void\n observeTokens(u: { input: number; output: number; cached?: number }): void\n },\n response: LlmCallResult,\n): void {\n if (typeof response.costUsd === 'number') cost.observe(response.costUsd, 'distillation-student')\n cost.observeTokens({\n input: response.usage.promptTokens,\n output: response.usage.completionTokens,\n cached: response.usage.cachedPromptTokens,\n })\n}\n\nconst DEFAULT_MUTATION_PRIMITIVES = [\n 'Add an explicit output-schema instruction so the model emits exactly the gold label fields as JSON.',\n 'Add a one-line decision rule for each verdict field the student keeps getting wrong.',\n 'Add a worked example mapping a representative input to its correct gold label.',\n 'Tighten ambiguous phrasing that lets the student hedge instead of committing to a verdict.',\n 'Add a guardrail that forces the student to set boolean risk flags (e.g. leak risk) when the triggering condition is present.',\n]\n\n/** Default student prompt render: surface as system, JSON input as the user\n * turn, with a JSON-only output instruction. */\nexport function defaultRenderStudentPrompt<TInput>(args: {\n surface: string\n input: TInput\n scenarioId: string\n}): ChatRequest['messages'] {\n return [\n { role: 'system', content: args.surface },\n {\n role: 'user',\n content:\n `Input:\\n${stableStringify(args.input)}\\n\\n` +\n 'Respond with ONLY a single JSON object — the verdict. No prose, no code fences.',\n },\n ]\n}\n\n/** Default label parse: strip a ```json fence if present, then `JSON.parse`.\n * Throws on failure so the cell is recorded as failed, not silently zeroed. */\nexport function defaultParseStudentLabel<TProduced>(\n rawContent: string,\n scenarioId: string,\n): TProduced {\n const stripped = stripFence(rawContent).trim()\n if (stripped.length === 0) {\n throw new Error(`distillation student returned empty output for scenario '${scenarioId}'`)\n }\n try {\n return JSON.parse(stripped) as TProduced\n } catch (err) {\n throw new Error(\n `distillation student returned non-JSON for scenario '${scenarioId}': ${\n err instanceof Error ? err.message : String(err)\n } — raw: ${stripped.slice(0, 200)}`,\n )\n }\n}\n\nfunction stripFence(text: string): string {\n const fenced = /```(?:json)?\\s*([\\s\\S]*?)\\s*```/.exec(text)\n return fenced ? (fenced[1] ?? text) : text\n}\n\n/** Deterministic JSON stringify with sorted keys — so the same input always\n * renders the same prompt (a key-order shuffle would perturb the student). */\nfunction stableStringify(value: unknown): string {\n return JSON.stringify(value, replacerSortKeys(), 2)\n}\n\nfunction replacerSortKeys(): (key: string, value: unknown) => unknown {\n return (_key, value) => {\n if (value && typeof value === 'object' && !Array.isArray(value)) {\n const sorted: Record<string, unknown> = {}\n for (const k of Object.keys(value as Record<string, unknown>).sort()) {\n sorted[k] = (value as Record<string, unknown>)[k]\n }\n return sorted\n }\n return value\n }\n}\n\nexport type { CampaignResult }\n","/**\n * Structured prompt profile — the system prompt as named, addressable sections\n * instead of one opaque blob. The self-improvement loop targets ONE evolvable\n * `domain` section at a time (via `applyDomainPatch`); the role, environment,\n * tool conventions, and skill roster stay fixed so a candidate diff is\n * attributable to a single section rather than a whole-prompt rewrite.\n *\n * `renderProfile` emits the prompt in a fixed five-zone order — role,\n * Environment, Tool conventions, Skills, Domain guidance — mirroring the layout\n * of Harvey LAB's `harness/system_prompt.md` (workspace root, read-only\n * documents, output dir, skills dir). `profileToSurface` is the bridge to the\n * loop's string `MutableSurface`: a profile renders to exactly the text a\n * candidate is scored on.\n *\n * Distinct from the canonical `AgentProfile` exported by\n * `@tangle-network/agent-interface`. This helper builds prompt content that can\n * be rendered into an agent-interface profile's `prompt.systemPrompt`.\n */\n\nimport { surfaceContentHash } from '../campaign/provenance'\nimport { BASELINE_ROLES, type BaselineRoleKey } from './baselines'\n\nexport {\n BASELINE_ROLES,\n type BaselineRoleKey,\n engineerRole,\n generalistRole,\n researcherRole,\n} from './baselines'\n\n/** A named, addressable region of the system prompt. `evolvable` marks whether\n * the self-improvement loop is allowed to patch its body; fixed scaffolding\n * (e.g. a compliance preamble) sets `evolvable: false`. */\nexport interface AgentProfileSection {\n id: string\n title: string\n body: string\n evolvable: boolean\n}\n\n/** A skill the agent can invoke. `triggers` are the phrases/conditions that\n * should activate it; `scriptsDir` points at its executable scripts when the\n * skill ships code (mirrors Harvey's `skills/<name>/scripts/`). */\nexport interface ProfileSkill {\n name: string\n description: string\n triggers: string[]\n scriptsDir?: string\n}\n\n/** The structured system prompt. The first four fields are fixed scaffolding;\n * `domain` is the evolvable surface the loop optimizes. */\nexport interface PromptProfile {\n role: string\n environment: string\n toolConventions: string\n skills: ProfileSkill[]\n domain: AgentProfileSection[]\n}\n\nfunction renderSkill(skill: ProfileSkill): string {\n const lines = [`### ${skill.name}`, skill.description]\n if (skill.triggers.length > 0) {\n lines.push(`Triggers: ${skill.triggers.join(', ')}`)\n }\n if (skill.scriptsDir !== undefined) {\n lines.push(`Scripts: ${skill.scriptsDir}`)\n }\n return lines.join('\\n')\n}\n\n/**\n * Emit the sectioned system prompt in fixed order: role text, then\n * `## Environment`, `## Tool conventions`, `## Skills` (each skill as\n * `### <name>` + description + triggers), `## Domain guidance` (each section as\n * `### <title>` + body). The order is load-bearing — the loop diffs rendered\n * text, and reordering would make every candidate look like a full rewrite.\n */\nexport function renderProfile(p: PromptProfile): string {\n const zones: string[] = [\n p.role.trim(),\n `## Environment\\n\\n${p.environment.trim()}`,\n `## Tool conventions\\n\\n${p.toolConventions.trim()}`,\n `## Skills\\n\\n${\n p.skills.length > 0 ? p.skills.map(renderSkill).join('\\n\\n') : '_No skills configured._'\n }`,\n `## Domain guidance\\n\\n${\n p.domain.length > 0\n ? p.domain.map((s) => `### ${s.title}\\n\\n${s.body.trim()}`).join('\\n\\n')\n : '_No domain guidance yet._'\n }`,\n ]\n return zones.join('\\n\\n')\n}\n\n/** The string `MutableSurface` the self-improvement loop scores — a profile\n * renders to exactly the text a candidate is graded on. */\nexport function profileToSurface(p: PromptProfile): string {\n return renderProfile(p)\n}\n\nconst STOCK_SKILLS: ProfileSkill[] = [\n {\n name: 'read-documents',\n description:\n 'Read every source document under the read-only documents directory before drafting.',\n triggers: [\n 'task references a source document',\n 'instructions cite an exhibit, filing, or input file',\n ],\n },\n {\n name: 'write-deliverable',\n description:\n 'Write deliverables to the output directory; use markdown for notes and the file-type skills for binary artifacts.',\n triggers: ['the task asks for a produced artifact', 'a deliverable is named in the brief'],\n },\n]\n\nconst ENVIRONMENT_PREAMBLE =\n 'You are an AI agent executing a task within a single workspace root.\\n\\n' +\n '- Workspace root: bash starts here. Use it for notes, scratch files, and intermediate work.\\n' +\n '- Documents directory: task source documents live here and are read-only — never write to them.\\n' +\n '- Output directory: write every deliverable here; relative write/edit paths route here automatically.\\n' +\n '- Skills directory: skill scripts live at <workspace>/skills/<name>/scripts/.'\n\nconst TOOL_CONVENTIONS_PREAMBLE =\n 'Use read to consume input files. Use write only for plain markdown (typically a response summary). ' +\n 'Use edit for incremental refinement of a file you already created. ' +\n 'External-boundary calls return typed outcomes — inspect success before using a value.'\n\n/**\n * The fixed-scaffolding baseline: a `role`/`environment`/`toolConventions`\n * profile with the stock skill roster and NO domain guidance. The\n * production profile is this plus shipped domain sections.\n */\nexport function baselineProfile(args: {\n role: string\n environment?: string\n toolConventions?: string\n skills?: ProfileSkill[]\n}): PromptProfile {\n return {\n role: args.role,\n environment: args.environment ?? ENVIRONMENT_PREAMBLE,\n toolConventions: args.toolConventions ?? TOOL_CONVENTIONS_PREAMBLE,\n skills: args.skills ?? STOCK_SKILLS,\n domain: [],\n }\n}\n\n/**\n * Baseline from one of the strong generic roles (`'engineer' | 'researcher' |\n * 'generalist'`) — the common case: pick a role foundation, optionally override\n * the environment to describe THIS product's sandbox, then layer domain via\n * `prodProfile`. Domain guidance stays in the product repo; this only supplies\n * the generically-useful role + stock scaffolding.\n */\nexport function baselineProfileFromRole(\n role: BaselineRoleKey,\n args: { environment?: string; toolConventions?: string; skills?: ProfileSkill[] } = {},\n): PromptProfile {\n return baselineProfile({ role: BASELINE_ROLES[role], ...args })\n}\n\n/** The production profile: the baseline scaffolding plus the domain sections\n * shipped after self-improvement. Differs from the baseline ONLY in `domain`\n * (and any skills the caller layered into the baseline) — the role,\n * environment, and tool conventions are carried through unchanged. */\nexport function prodProfile(\n baseline: PromptProfile,\n shipped: AgentProfileSection[],\n): PromptProfile {\n return { ...baseline, domain: [...baseline.domain, ...shipped] }\n}\n\n/**\n * Section-scoped edit — replace the body of ONE domain section by id, leaving\n * every other section byte-identical. This is how the loop targets a single\n * evolvable surface. Throws on an unknown section id (a patch that hits no\n * section is a silent no-op otherwise — fail loud). Throws when the targeted\n * section is `evolvable: false`.\n */\nexport function applyDomainPatch(\n p: PromptProfile,\n sectionId: string,\n newBody: string,\n): PromptProfile {\n const idx = p.domain.findIndex((s) => s.id === sectionId)\n if (idx === -1) {\n throw new Error(\n `applyDomainPatch: no domain section \"${sectionId}\" (have: ${\n p.domain.map((s) => s.id).join(', ') || '<none>'\n })`,\n )\n }\n const target = p.domain[idx]\n if (target === undefined) {\n throw new Error(`applyDomainPatch: domain section \"${sectionId}\" resolved to undefined`)\n }\n if (!target.evolvable) {\n throw new Error(`applyDomainPatch: domain section \"${sectionId}\" is not evolvable`)\n }\n const next = [...p.domain]\n next[idx] = { ...target, body: newBody }\n return { ...p, domain: next }\n}\n\n/**\n * Content hash of a single section — its loop identity. Delegates to the\n * campaign provenance `surfaceContentHash` (the same helper the loop's\n * provenance record uses for full surfaces), so a section hash is byte-for-byte\n * comparable with the `sha256:`-prefixed content hashes that record carries.\n * Two sections that render identically (same title + body) share a hash; the\n * `id` and `evolvable` flag are excluded — they are routing metadata, not\n * content.\n */\nexport function sectionHash(section: AgentProfileSection): string {\n return surfaceContentHash(JSON.stringify({ title: section.title, body: section.body }))\n}\n","/**\n * Strong, generically-useful baseline ROLES — the top zone of an `AgentProfile`\n * before any domain layer. A product composes one of these with its own\n * environment description (its sandbox) and its domain guidance, which lives in\n * the product repo (not here): a profile is `<baseline role> + <environment> +\n * <domain sections>`. Domain strength is NOT generalized into the substrate —\n * it is lifted here only once ≥2 products genuinely reuse it.\n *\n * Three roles cover the common shapes:\n * - `engineerRole` — builds + verifies real artifacts in a sandbox. Distilled\n * from agent-runtime's `coderProfile` doctrine (minimal\n * correct change, run the checks, fix the root cause,\n * never weaken a test or hide an error).\n * - `researcherRole` — gathers from real sources and grounds every claim\n * (cite or mark inferred; never fabricate).\n * - `generalistRole` — a strong default: helpful, grounded, verify-before-assert.\n *\n * All three are verification-first and domain-agnostic. They describe HOW a\n * capable IC operates, not WHAT domain it works in.\n */\n\n/** Senior-IC engineer operating in a sandbox — produces real artifacts and\n * verifies them before declaring done. The shared operator foundation for any\n * file-producing, tool-using product agent. */\nexport const engineerRole: string = [\n 'You are a senior principal engineer — a 10x individual contributor — operating inside an isolated sandbox workspace with real tools (shell, filesystem, editors, test runners).',\n 'You do not behave like a chatbot that describes work. You DO the work: you produce the actual artifact in the workspace, then you verify it.',\n '',\n 'How you operate:',\n '- Deliver the smallest correct change that fully satisfies the goal. Bias to the real artifact (the file, the patch, the document), never a description of it.',\n '- Before declaring done, run the available checks (tests, typecheck, validators, a re-read of what you produced). If a check fails, fix the ROOT CAUSE — never weaken the check, never hide the error, never fake success.',\n '- External-boundary calls (shell, network, filesystem) can fail. Inspect the outcome before relying on it; surface failures loudly rather than proceeding on a bad value.',\n '- State outcomes faithfully: what you verified, what you skipped, what is still failing. \"Done\" means produced AND verified.',\n].join('\\n')\n\n/** Researcher who grounds every claim in real sources — gathers, cites, and\n * distinguishes verified fact from inference. */\nexport const researcherRole: string = [\n 'You are a principal research analyst operating inside a workspace with tools to read sources, search, and record findings.',\n 'Your output is only as good as its grounding. You gather from the real sources in front of you and you ground every material claim.',\n '',\n 'How you operate:',\n '- Read the actual sources before concluding. Do not answer from memory when a source is available to check.',\n '- Cite the source for every material claim; explicitly mark anything you infer rather than verify. Never fabricate a source, a quote, a number, or a citation.',\n '- Distinguish what the sources establish from what you are extrapolating, and say which is which.',\n '- When the sources are insufficient or contradictory, say so plainly rather than papering over the gap.',\n].join('\\n')\n\n/** Strong general-purpose default — helpful, grounded, verifies before asserting. */\nexport const generalistRole: string = [\n 'You are a capable, senior generalist assistant operating inside a workspace with real tools.',\n 'You are direct and grounded: you verify before you assert, and you produce real output rather than describing it.',\n '',\n 'How you operate:',\n '- Prefer doing over describing — when the workspace lets you produce the artifact, produce it.',\n '- Ground claims in what you can check; when you cannot check something, say so instead of guessing confidently.',\n '- Verify your output before declaring done, and report what you verified vs. what remains uncertain.',\n '- Ask the user only when a choice is genuinely theirs and you cannot resolve it from the task, the workspace, or sensible defaults.',\n].join('\\n')\n\n/** The named baseline roles, for selection by key (e.g. from a product config). */\nexport const BASELINE_ROLES = {\n engineer: engineerRole,\n researcher: researcherRole,\n generalist: generalistRole,\n} as const\n\nexport type BaselineRoleKey = keyof typeof BASELINE_ROLES\n","/**\n * Program cost report — a thin projection over `CostLedger.summary()` that\n * adds the per-model rollup the summary lacks, plus `attachCostToReport`, the\n * one way every artifact (capsules, campaign results, diagnose reports) gets\n * its cost stamp.\n *\n * Honesty contract carried through from the ledger: `total.unknownEntries`\n * and `perModel[].unpriced` surface the costUnknown axis — a $0 from an\n * unpriced model is a lower bound, never a measured zero.\n */\n\nimport type { ChannelRollup, CostLedger } from './cost-ledger'\nimport { ValidationError } from './errors'\n\nexport interface ModelCostRollup {\n model: string\n usd: number\n entries: number\n /** ≥1 entry for this model was costUnknown — `usd` is a lower bound. An\n * `actualCostUsd` override clears the flag for that entry (the dollars are\n * observed, even when the model has no pricing). */\n unpriced: boolean\n}\n\nexport interface CostReport {\n /** Per-channel breakdown — `CostLedgerSummary.byChannel` verbatim. */\n perChannel: ChannelRollup[]\n total: {\n usd: number\n /** Entries whose cost was unknown — non-zero means `usd` is a lower bound. */\n unknownEntries: number\n }\n /** Per-model spend, sorted by model id. */\n perModel: ModelCostRollup[]\n}\n\n/** Project a ledger into the program cost report. Pure — no I/O, no clock. */\nexport function costReport(ledger: CostLedger): CostReport {\n const summary = ledger.summary()\n const perModel = new Map<string, ModelCostRollup>()\n for (const entry of ledger.list()) {\n const roll = perModel.get(entry.model) ?? {\n model: entry.model,\n usd: 0,\n entries: 0,\n unpriced: false,\n }\n roll.usd += entry.costUsd\n roll.entries += 1\n if (entry.costUnknown) roll.unpriced = true\n perModel.set(entry.model, roll)\n }\n return {\n perChannel: summary.byChannel,\n total: {\n usd: summary.totalCostUsd,\n unknownEntries: summary.byChannel.reduce((sum, c) => sum + c.unpricedCalls, 0),\n },\n perModel: [...perModel.values()].sort((a, b) => a.model.localeCompare(b.model)),\n }\n}\n\n/**\n * Stamp a report-shaped object with its cost projection under the `cost` key.\n * Generic so capsules, campaign results, and diagnose reports all stamp the\n * same way. Throws when the report already carries a `cost` key — silently\n * overwriting an existing stamp would corrupt the artifact's provenance.\n */\nexport function attachCostToReport<R extends object>(\n report: R,\n ledger: CostLedger,\n): R & { cost: CostReport } {\n if ('cost' in report) {\n throw new ValidationError(\n \"attachCostToReport: report already has a 'cost' key — refusing to overwrite an existing stamp\",\n )\n }\n return { ...report, cost: costReport(ledger) }\n}\n","/**\n * ModelSeats — the program's model seating chart.\n *\n * One object names which model fills each role in an eval program: the worker\n * under evaluation, the judge panel, the analyst, the reflection/driver model,\n * and the verifier. Re-tiering an entire program (economy ↔ frontier) is one\n * swapped object instead of a hunt through call sites.\n *\n * Wiring points — consumers thread seats; this module implements none of them\n * (those files belong to other surfaces):\n * - `judges` → `ensembleJudge({ models: seats.judges, … })` (src/judge-panel.ts)\n * and the `JudgeConfig`s handed to `makeEvalTools({ judges })`\n * (src/eval-tools.ts).\n * - `reflection` → `selfImprove({ llm: { model: seats.reflection } })` — the\n * `gepaProposer` reflection model (src/contract/self-improve.ts);\n * same seat for any custom `SurfaceProposer`'s LLM.\n * - `worker` → the dispatch model the agent itself calls — the model an\n * `AgentProfile` declares.\n * - `analyst` → the LLM behind `analyzeRuns` / analyst-registry kinds.\n * - `verifier` → completion-verifier / objective-checker model.\n * - campaign cells thread `judges` + driver models the same way; that wiring\n * lands with the campaign surface, not here.\n *\n * `resolveSeat` is the only read path: an unset seat with no explicit fallback\n * throws — a model id is a budget decision, never a silent default.\n */\n\nimport { ConfigError, ValidationError } from './errors'\n\nexport interface ModelSeats {\n /** The model under evaluation — what the agent itself dispatches with. */\n worker?: string\n /** Judge-panel model ids — thread into `ensembleJudge({ models })`. */\n judges?: string[]\n /** Analyst model — `analyzeRuns` / analyst-registry LLM calls. */\n analyst?: string\n /** Reflection/proposer model — `gepaProposer` mutation proposals. */\n reflection?: string\n /** Verifier model — completion/objective checking. */\n verifier?: string\n}\n\nexport type SeatName = keyof ModelSeats\n\nexport type SeatPresetName = keyof typeof seatPresets\n\n/**\n * Tier presets — plain data, swap or spread freely.\n *\n * `economy` uses the fleet-policy ids: every id resolves through the\n * substrate's family pricing (no costUnknown axis) and the judge trio spans\n * three provider families (moonshot / deepseek / openai), so it passes\n * `assertCrossFamily` as-is.\n *\n * `frontier` is deliberately EMPTY: entitled frontier ids vary per router\n * account, and a hardcoded claude/gpt-5 id 401s on keys that lack it. Supply\n * your own: `{ ...seatPresets.frontier, worker: '<your-frontier-id>', … }` —\n * `resolveSeat` throws on every seat you haven't filled.\n */\nexport const seatPresets: Record<'economy' | 'frontier', ModelSeats> = {\n economy: {\n worker: 'kimi-k2.6',\n judges: ['kimi-k2.6', 'deepseek-v4-pro', 'gpt-4.1-mini'],\n analyst: 'gpt-4.1-mini',\n reflection: 'gpt-4.1-mini',\n verifier: 'deepseek-v4-pro',\n },\n frontier: {},\n}\n\n/** Thrown by `resolveSeat` when a seat is unset and no fallback was given. */\nexport class SeatUnsetError extends ConfigError {\n constructor(public readonly seat: SeatName) {\n super(\n `ModelSeats: seat '${seat}' is unset and no fallback was given — ` +\n 'name a model explicitly (a model id is a budget decision, never a silent default)',\n )\n }\n}\n\n/**\n * Read one seat. Blank strings and empty arrays count as unset (env-var\n * plumbing produces them); malformed values (non-string seat, non-array or\n * blank-entry `judges`) throw `ValidationError`. When the seat is unset, an\n * explicit `fallback` is returned (`[fallback]` for `judges` — a one-model\n * panel); without one, `SeatUnsetError`.\n */\nexport function resolveSeat(seats: ModelSeats, seat: 'judges', fallback?: string): string[]\nexport function resolveSeat(\n seats: ModelSeats,\n seat: Exclude<SeatName, 'judges'>,\n fallback?: string,\n): string\nexport function resolveSeat(seats: ModelSeats, seat: SeatName, fallback?: string): string | string[]\nexport function resolveSeat(\n seats: ModelSeats,\n seat: SeatName,\n fallback?: string,\n): string | string[] {\n const value = seats[seat]\n if (seat === 'judges') {\n if (value !== undefined && !Array.isArray(value)) {\n throw new ValidationError(`ModelSeats: seat 'judges' must be a string[], got ${typeof value}`)\n }\n const models = Array.isArray(value) ? value : []\n if (models.length > 0) {\n const blank = models.findIndex((m) => typeof m !== 'string' || m.trim() === '')\n if (blank >= 0) {\n throw new ValidationError(\n `ModelSeats: judges[${blank}] is blank — every panel model must be a non-empty id`,\n )\n }\n return [...models]\n }\n } else {\n if (value !== undefined && typeof value !== 'string') {\n throw new ValidationError(`ModelSeats: seat '${seat}' must be a string, got ${typeof value}`)\n }\n if (typeof value === 'string' && value.trim() !== '') return value\n }\n if (fallback !== undefined) {\n if (fallback.trim() === '') {\n throw new ValidationError(`ModelSeats: fallback for seat '${seat}' is blank`)\n }\n return seat === 'judges' ? [fallback] : fallback\n }\n throw new SeatUnsetError(seat)\n}\n","/**\n * Reproducibility attestation for any serializable report object.\n *\n * `attest()` binds a report to its content address (sha-256 over canonical\n * JSON) plus the provenance needed to reproduce it: model versions, seeds,\n * price-table hash, code SHA, inputs hash. `verifyAttestation()` recomputes\n * the address and answers \"is this the exact report that provenance\n * describes?\" — any single-field tamper changes the hash.\n *\n * Layering: content-addressing is the substrate's job; cryptographic SIGNING\n * (who vouches for the attestation, key management, transparency logs) is the\n * consumer's layer on top. An `AttestedReport` is a stable byte-identical\n * payload a consumer can sign — the substrate never holds keys.\n *\n * Generic by design: the report parameter is ANY value `canonicalJson`\n * accepts (campaign results, fuzz capsules, scorecards, cost ledgers). Do not\n * couple this module to a specific report schema.\n */\n\nimport { contentHash } from './verdict-cache'\n\n/** Hash scheme identifier carried by every attestation. A verifier rejects\n * unknown algorithms instead of guessing. */\nexport const ATTESTATION_ALGORITHM = 'sha256/canonical-json' as const\n\nexport interface AttestationProvenance {\n /** Every model involved in producing the report, name → version/id. */\n modelVersions: Record<string, string>\n /** RNG seeds the run was driven by, when seeded. */\n seeds?: number[]\n /** Content hash of the price table used for cost figures — cost numbers\n * are only reproducible against the same prices. */\n priceTableHash?: string\n /** Git SHA of the code that produced the report. */\n codeSha: string\n /** Content hash of the input set (scenarios, dataset manifest, ...). */\n inputsHash?: string\n /** ISO-8601 timestamp, caller-supplied — the substrate stays clock-free\n * so attestation is deterministic and testable. */\n createdAt: string\n}\n\nexport interface AttestedReport {\n /** Hex sha-256 over the canonical JSON of the report. */\n reportHash: string\n provenance: AttestationProvenance\n algorithm: typeof ATTESTATION_ALGORITHM\n}\n\nexport interface AttestationVerification {\n valid: boolean\n /** Populated iff `valid` is false — names the exact mismatch. */\n reason?: string\n}\n\n/**\n * Content-address a report and bind it to its provenance. Throws (via\n * `canonicalJson`) if the report contains undefined / function / symbol /\n * non-finite numbers — a report that cannot be unambiguously serialized\n * cannot be attested.\n */\nexport function attest(report: unknown, provenance: AttestationProvenance): AttestedReport {\n return {\n reportHash: contentHash(report),\n provenance,\n algorithm: ATTESTATION_ALGORITHM,\n }\n}\n\n/**\n * Verify a report against its attestation. Returns a typed outcome rather\n * than throwing: an unverifiable report (e.g. one that no longer\n * canonicalizes) is a verification failure with the cause in `reason`, not a\n * crash — verifiers run in pipelines that must record WHY, not die.\n */\nexport function verifyAttestation(\n report: unknown,\n attested: AttestedReport,\n): AttestationVerification {\n if (attested.algorithm !== ATTESTATION_ALGORITHM) {\n return {\n valid: false,\n reason: `unknown algorithm '${attested.algorithm}' — this verifier only checks '${ATTESTATION_ALGORITHM}'`,\n }\n }\n let recomputed: string\n try {\n recomputed = contentHash(report)\n } catch (err) {\n return {\n valid: false,\n reason: `report is not canonicalizable: ${err instanceof Error ? err.message : String(err)}`,\n }\n }\n if (recomputed !== attested.reportHash) {\n return {\n valid: false,\n reason: `report hash mismatch: attested ${attested.reportHash}, recomputed ${recomputed}`,\n }\n }\n return { valid: true }\n}\n"],"mappings":"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","names":["dirname","join","check","sleep","scores","sum","join","readFile","canonicalize","sum","stripSlash","check","pairKey","bootstrapCi","precision","aggregate","scores","matches","matches","toolSpans","matches","ratio","scores","runScore","mean","sum","scores","results","sum","mulberry32","sum","assertNonNegative","fs","mean","scores","medianDelta","fs","mean","matches","existsSync","readFileSync","median","runScore","scores","existsSync","readFileSync","fmt","passed","margin","ai","scores","scores","scores","mean","scores","ratio","worst","join","i","j","pa","scores","mean","runs","groupBy","scores","existsSync","readdirSync","readFileSync","statSync","join","tail","matches","sum","appendFileSync","existsSync","mkdirSync","readFileSync","dirname","scoreOptions","mkdirSync","dirname","appendFileSync","existsSync","scores","mean","clamp01","matches","sum","precision","readFileSync","softFail","runScore","fmt","join","defaultExtract","matches","inferCandidateId","mean","mean","precision","scores","sum","readFileSync","DEFAULT_MUTATION_PRIMITIVES","sum"]}
1
+ {"version":3,"sources":["../src/auto-pr.ts","../src/executor.ts","../src/benchmark.ts","../src/capability-headroom.ts","../src/client.ts","../src/convergence.ts","../src/driver.ts","../src/feedback-trajectory.ts","../src/integrity/preflight.ts","../src/integrity/single-backend.ts","../src/judge-families.ts","../src/live-proof.ts","../src/paired-arms.ts","../src/pr-review-benchmark.ts","../src/registry.ts","../src/reporter.ts","../src/treatment-gate.ts","../src/anti-slop.ts","../src/artifact-validator.ts","../src/dual-agent-bench.ts","../src/eval-tools.ts","../src/harness-optimizer.ts","../src/judge-ensemble.ts","../src/judge-retry.ts","../src/judge-panel.ts","../src/judge-runner.ts","../src/playbook.ts","../src/prompt-registry.ts","../src/steering.ts","../src/steering-optimizer.ts","../src/workspace-inspector.ts","../src/budget-guard.ts","../src/hidden-criteria-grading.ts","../src/cost-ledger.ts","../src/cost-tracker.ts","../src/eval-trace-store.ts","../src/experiment-tracker.ts","../src/leaderboard.ts","../src/muffled-gate-scanner.ts","../src/oracle.ts","../src/partition-held-out.ts","../src/scorecard.ts","../src/slo.ts","../src/state-continuity.ts","../src/ui-finding.ts","../src/trace-contracts.ts","../src/behavior-dsl.ts","../src/ci-gate.ts","../src/observability.ts","../src/paraphrase.ts","../src/visual-diff.ts","../src/bisector.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/description-length-gate.ts","../src/discover-personas.ts","../src/golden-matcher.ts","../src/held-out-gate.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","../src/campaign/distillation/agreement-judge.ts","../src/campaign/distillation/gold-scenarios.ts","../src/campaign/distillation/run-distillation.ts","../src/profile/index.ts","../src/profile/baselines.ts","../src/cost-report.ts","../src/model-seats.ts","../src/attestation.ts"],"sourcesContent":["/**\n * Automated pull-request transports for the production loop.\n *\n * A consumer's `runProductionLoop` ships a promoted surface diff as a\n * reviewable code change by handing one of these clients to its\n * `ProductionShipConfig.client`. Each `AutoPrClient.proposeChange`:\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 * (The campaign-loop `autoOnPromote: 'pr'` path uses `openAutoPr` in\n * `src/campaign/auto-pr.ts`, a self-contained `gh pr create` shell-out.)\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\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\n/**\n * Validate a proposed change before any transport touches the network. Each\n * `AutoPrClient.proposeChange` runs this at its boundary so a malformed input\n * (path traversal, duplicate path, branch == base, empty title) fails loud\n * locally instead of producing a broken commit on the remote.\n */\nfunction validateProposeInput(input: ProposeAutomatedPullRequestInput): void {\n if (!input.repo.owner.trim() || !input.repo.name.trim()) {\n throw new ValidationError('proposeChange: repo.owner and repo.name required')\n }\n if (!input.branchName.trim() || /\\s/.test(input.branchName)) {\n throw new ValidationError(\n 'proposeChange: branchName must be non-empty and contain no whitespace',\n )\n }\n if (input.branchName === (input.baseBranch ?? 'main')) {\n throw new ValidationError('proposeChange: branchName must differ from baseBranch')\n }\n if (input.fileChanges.length === 0) {\n throw new ValidationError('proposeChange: 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 `proposeChange: invalid file path \"${change.path}\" (no '..' or leading '/')`,\n )\n }\n if (seenPaths.has(change.path)) {\n throw new ValidationError(`proposeChange: duplicate file path \"${change.path}\"`)\n }\n seenPaths.add(change.path)\n }\n if (!input.title.trim()) {\n throw new ValidationError('proposeChange: 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 `proposeChange: 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 validateProposeInput(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(`proposeChange: 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(`proposeChange: base commit ${baseSha} not found (race condition?)`)\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('proposeChange: 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('proposeChange: 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) throw new ConfigError('proposeChange: 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) throw new ConfigError('proposeChange: 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 `proposeChange: ${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 validateProposeInput(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 { CaptureIntegrityError } from './errors'\nimport { JudgeParseError } from './judges'\nimport { isTransientLlmError } from './llm-client'\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 * Sleep used between judge retries and after a judge succeeds. Defaults to\n * real `setTimeout`. Injectable so tests exercise the retry policy without\n * the real multi-second backoff.\n */\n sleep?: (ms: number) => Promise<void>\n}\n\nfunction describeShape(content: unknown, message: unknown): string {\n if (message === undefined || message === null) return 'no choices[0].message'\n return `message.content of type ${content === null ? 'null' : typeof content}`\n}\n\nfunction errMessage(err: unknown): string {\n if (err instanceof Error) return `${err.name}: ${err.message}`\n return String(err)\n}\n\n/** Per-judge failure diagnostic, recorded additively on `ScenarioResult`. */\nexport interface JudgeFailure {\n judge: string\n attempts: number\n reason: string\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 message = (resp as { choices?: { message?: { content?: unknown } }[] }).choices?.[0]\n ?.message\n const rawContent = message?.content\n // A legitimately-empty turn ('' from a model that chose to say nothing) is\n // real signal and must survive. A missing choices[0].message, or a content\n // that is not a string, is a capture defect — the chat call hung or returned\n // a malformed shape — and is indistinguishable from a real empty turn once\n // collapsed to ''. Fail loud so it is never scored as a real response.\n if (message === undefined || message === null || typeof rawContent !== 'string') {\n throw new CaptureIntegrityError(\n `chat response for scenario \"${scenario.id}\" turn ${i} is malformed: ` +\n `expected choices[0].message.content to be a string, got ${describeShape(rawContent, message)}`,\n )\n }\n const content = rawContent\n\n messages.push({ role: 'assistant', content })\n\n // Extract code blocks\n const codeRe = /```(\\w+)?\\n([\\s\\S]*?)```/g\n let codeMatch: RegExpExecArray | null = codeRe.exec(content)\n while (codeMatch !== null) {\n allCodeBlocks.push({ language: codeMatch[1] ?? 'text', code: codeMatch[2] ?? '' })\n codeMatch = codeRe.exec(content)\n }\n\n // Extract structured blocks\n const turnBlocks: { type: string; title: string }[] = []\n const blockReLocal = new RegExp(blockRe.source, blockRe.flags)\n let blockMatch: RegExpExecArray | null = blockReLocal.exec(content)\n while (blockMatch !== 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 blockMatch = blockReLocal.exec(content)\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: RegExpExecArray | null = re.exec(content)\n while (toolMatch !== null) {\n allToolCalls.push(toolMatch[0])\n hasToolCall = true\n toolMatch = re.exec(content)\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. A judge that fails — unparseable\n // output (JudgeParseError, non-retryable) or errors across every attempt —\n // is COUNTED as a failed judge, never folded into the scores as a fake\n // zero row: a synthetic zero is indistinguishable from a real low score.\n const judgeInput = { scenario, turns, artifacts }\n const judgeResults: JudgeScore[][] = []\n let failedJudges = 0\n const judgeFailures: JudgeFailure[] = []\n const sleep = config.sleep ?? ((ms: number) => new Promise<void>((r) => setTimeout(r, ms)))\n\n for (let j = 0; j < config.judges.length; j++) {\n const judge = config.judges[j]!\n const judgeName = judge.name || `judge[${j}]`\n let lastError: unknown\n let madeAttempts = 0\n for (let attempt = 0; attempt < 3; attempt++) {\n madeAttempts = attempt + 1\n try {\n if (attempt > 0) {\n const wait = attempt * 10_000\n console.log(` ${judgeName} retry ${attempt}/2 (waiting ${wait / 1000}s)`)\n await sleep(wait)\n }\n const scores = await judge(tc, judgeInput)\n judgeResults.push(scores)\n await sleep(3000)\n lastError = undefined\n break\n } catch (err) {\n lastError = err\n if (err instanceof JudgeParseError) {\n // The model answered but unparseably — another identical prompt\n // won't fix it. Record the failure and move to the next judge.\n console.error(` ${judgeName} unparseable (no retry): ${errMessage(err)}`)\n break\n }\n console.error(` ${judgeName} attempt ${attempt} failed: ${errMessage(err)}`)\n // Deterministic errors (bad rubric, auth, 4xx) won't change on retry —\n // only retry connection/rate-limit class faults. Stop the loop now so a\n // permanent error is not masked by two pointless waits.\n if (!isTransientLlmError(err)) break\n }\n }\n if (lastError !== undefined) {\n failedJudges++\n judgeFailures.push({\n judge: judgeName,\n attempts: madeAttempts,\n reason: errMessage(lastError),\n })\n }\n }\n\n const allScores = judgeResults.flat()\n // Defensive: custom JudgeFns may still emit error-shaped rows.\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 // judgeFailures is additive diagnostic context (WHY each judge errored),\n // recorded alongside the existing judgeErrors count without widening the\n // shared ScenarioResult contract. Absent when every judge succeeded.\n const result: ScenarioResult & { judgeFailures?: JudgeFailure[] } = {\n scenarioId: scenario.id,\n persona: scenario.persona,\n turns,\n artifactResults,\n judgeScores: allScores,\n judgeErrors: errorScores.length + failedJudges,\n overallScore,\n totalDurationMs: Date.now() - startTime,\n artifacts,\n }\n if (judgeFailures.length > 0) result.judgeFailures = judgeFailures\n return result\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","/**\n * Capability-headroom gate — \"can this task set even SEE the capability\n * you're about to A/B?\"\n *\n * A capability A/B (grant one arm a tool, a skill, extra context — anything)\n * can only detect the capability on tasks the capability-ABSENT baseline\n * FAILS. A task the baseline already passes is saturated: the treatment arm\n * has no headroom to demonstrate anything, and averaging saturated tasks into\n * the comparison dilutes a real effect toward a false null. Calibrate before\n * measuring: run the baseline arm first, classify every task's headroom, and\n * refuse to run the comparison when no task has a gap.\n *\n * Fail-closed on unknown outcomes: a baseline run whose outcome could not be\n * determined (infra loss, unverified, missing) NEVER counts as a failure —\n * treating \"couldn't tell\" as \"failed\" would manufacture headroom out of\n * telemetry gaps and launder infra noise into a treatment effect.\n *\n * Domain-free by construction: the capability under test never appears here.\n * Callers decide what the baseline arm lacks; this module only classifies\n * baseline outcomes per task.\n */\n\nimport { ValidationError } from './errors'\n\n/** One baseline-arm (capability-absent) observation of one task. */\nexport interface HeadroomInput {\n /** Stable task identity; multiple rows per task are multiple baseline reps. */\n taskId: string\n /** Baseline outcome. 'unknown' = the outcome could not be determined —\n * distinct from 'fail' and never counted as one. */\n baselineOutcome: 'pass' | 'fail' | 'unknown'\n}\n\n/** Headroom classification for one task.\n * - 'gap': the baseline fails it — the comparison can see the capability here.\n * - 'saturated': the baseline already passes it — no headroom.\n * - 'unknown': every baseline outcome is unknown — fail-closed, not a gap. */\nexport type HeadroomClass = 'gap' | 'saturated' | 'unknown'\n\nexport interface TaskHeadroom {\n taskId: string\n /** Total baseline observations for this task (known + unknown). */\n n: number\n /** Observations with a known ('pass' | 'fail') outcome — the evidence the\n * classification actually rests on. A large `n` with a small `nKnown`\n * means the headroom verdict is thin, not well-replicated. */\n nKnown: number\n /** Pass rate over KNOWN outcomes only; NaN when every outcome is unknown\n * (no data ≠ measured zero). */\n baselinePassRate: number\n headroom: HeadroomClass\n}\n\nexport interface CapabilityHeadroomOptions {\n /** A task counts as 'gap' when its baseline pass rate is ≤ this. Default 0\n * (the baseline must fail every known rep). Must be in [0, 1) — a\n * threshold of 1 would classify a fully-saturated task as a gap. */\n keepThreshold?: number\n}\n\nexport interface CapabilityHeadroomResult {\n /** Per-task classification, sorted by `taskId`. */\n tasks: TaskHeadroom[]\n summary: {\n tasksWithGap: number\n tasksSaturated: number\n tasksUnknown: number\n /** Total unknown-outcome reps across ALL tasks (including tasks that\n * still classified via their known reps) — the size of the telemetry\n * hole behind the classifications. */\n repsUnknown: number\n }\n}\n\n/**\n * Classify every task's baseline headroom from capability-absent baseline\n * outcomes.\n *\n * A task is 'gap' when it has ≥ 1 known outcome and its pass rate over known\n * outcomes is ≤ `keepThreshold`; 'saturated' when the rate exceeds the\n * threshold; 'unknown' when every outcome is unknown. Unknown reps never\n * count toward the rate in either direction (fail-closed — see the module\n * doc), and evidence strength stays visible: each task reports `nKnown`\n * alongside `n`, and the summary totals the unknown reps in `repsUnknown`.\n * Throws on empty input, an out-of-range `keepThreshold`, or an\n * unrecognized outcome value (rows are often projected from untyped records).\n */\nexport function capabilityHeadroom(\n rows: readonly HeadroomInput[],\n opts: CapabilityHeadroomOptions = {},\n): CapabilityHeadroomResult {\n const keepThreshold = opts.keepThreshold ?? 0\n if (!Number.isFinite(keepThreshold) || keepThreshold < 0 || keepThreshold >= 1) {\n throw new ValidationError(\n `capabilityHeadroom: keepThreshold must be in [0, 1), got ${keepThreshold}`,\n )\n }\n if (rows.length === 0) {\n throw new ValidationError(\n 'capabilityHeadroom: no baseline rows supplied — run the capability-absent baseline arm first',\n )\n }\n\n // taskId → { n, passes, known }\n const byTask = new Map<string, { n: number; passes: number; known: number }>()\n for (const row of rows) {\n if (\n row.baselineOutcome !== 'pass' &&\n row.baselineOutcome !== 'fail' &&\n row.baselineOutcome !== 'unknown'\n ) {\n throw new ValidationError(\n `capabilityHeadroom: unrecognized baselineOutcome '${row.baselineOutcome}' for task '${row.taskId}' (expected 'pass' | 'fail' | 'unknown')`,\n )\n }\n const agg = byTask.get(row.taskId) ?? { n: 0, passes: 0, known: 0 }\n agg.n++\n if (row.baselineOutcome !== 'unknown') {\n agg.known++\n if (row.baselineOutcome === 'pass') agg.passes++\n }\n byTask.set(row.taskId, agg)\n }\n\n const tasks: TaskHeadroom[] = [...byTask.entries()]\n .sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0))\n .map(([taskId, agg]) => {\n if (agg.known === 0) {\n return {\n taskId,\n n: agg.n,\n nKnown: 0,\n baselinePassRate: Number.NaN,\n headroom: 'unknown' as const,\n }\n }\n const baselinePassRate = agg.passes / agg.known\n return {\n taskId,\n n: agg.n,\n nKnown: agg.known,\n baselinePassRate,\n headroom: baselinePassRate <= keepThreshold ? ('gap' as const) : ('saturated' as const),\n }\n })\n\n const summary = {\n tasksWithGap: tasks.filter((t) => t.headroom === 'gap').length,\n tasksSaturated: tasks.filter((t) => t.headroom === 'saturated').length,\n tasksUnknown: tasks.filter((t) => t.headroom === 'unknown').length,\n repsUnknown: tasks.reduce((sum, t) => sum + (t.n - t.nKnown), 0),\n }\n return { tasks, summary }\n}\n\nexport interface AssertCapabilityHeadroomOptions {\n /** Minimum tasks classified 'gap' for the comparison to proceed. Default 1. */\n minTasksWithGap?: number\n}\n\n/**\n * The go/no-go guard: throws when fewer than `minTasksWithGap` tasks have\n * baseline headroom — i.e. the benchmark cannot see the capability, so any\n * comparison run on it would measure noise. Call between the baseline\n * calibration run and the treatment run.\n */\nexport function assertCapabilityHeadroom(\n result: CapabilityHeadroomResult,\n opts: AssertCapabilityHeadroomOptions = {},\n): void {\n const minTasksWithGap = opts.minTasksWithGap ?? 1\n if (!Number.isInteger(minTasksWithGap) || minTasksWithGap < 1) {\n throw new ValidationError(\n `assertCapabilityHeadroom: minTasksWithGap must be an integer ≥ 1, got ${minTasksWithGap}`,\n )\n }\n const { tasksWithGap, tasksSaturated, tasksUnknown } = result.summary\n if (tasksWithGap < minTasksWithGap) {\n const total = result.tasks.length\n throw new ValidationError(\n `assertCapabilityHeadroom: only ${tasksWithGap} of ${total} task(s) have baseline headroom ` +\n `(need ≥ ${minTasksWithGap}). ${tasksSaturated} saturated (baseline already passes), ` +\n `${tasksUnknown} unknown (no determinable baseline outcome). A capability A/B on this ` +\n `task set cannot detect the capability — add tasks the baseline fails, or fix baseline ` +\n `outcome capture, before measuring.`,\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 */\nconst DEFAULT_REQUEST_TIMEOUT_MS = 30_000\n\nexport class ProductClient {\n private baseUrl: string\n private routes: RouteMap\n private cookies: string = ''\n private timeoutMs: number\n\n constructor(config: ProductClientConfig) {\n this.baseUrl = config.baseUrl.replace(/\\/+$/, '')\n this.routes = config.routes\n this.timeoutMs = config.timeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS\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 /**\n * Single HTTP boundary for every JSON request. Aborts after `timeoutMs`,\n * checks `res.ok` BEFORE parsing, and throws `${method} ${path} failed:\n * HTTP ${status} — ${body}` on a non-ok response so a 4xx/5xx error body\n * can never be parsed as a success shape. Callers inspect the resolved\n * value only after a successful return.\n */\n private async request(\n method: string,\n path: string,\n body?: Record<string, unknown>,\n ): Promise<Record<string, unknown>> {\n const controller = new AbortController()\n const timeout = setTimeout(() => controller.abort(), this.timeoutMs)\n let res: Response\n try {\n res = await fetch(`${this.baseUrl}${path}`, {\n method,\n headers: {\n ...(body ? { 'Content-Type': 'application/json' } : {}),\n Origin: this.baseUrl,\n Cookie: this.cookies,\n },\n ...(body ? { body: JSON.stringify(body) } : {}),\n signal: controller.signal,\n })\n } finally {\n clearTimeout(timeout)\n }\n if (!res.ok) {\n const text = await res.text().catch(() => '')\n throw new Error(`${method} ${path} failed: HTTP ${res.status} — ${text.slice(0, 500)}`)\n }\n return res.json() as Promise<Record<string, unknown>>\n }\n\n /**\n * Read a required collection field. A missing/non-array field is a contract\n * violation (wrong route, drift, partial body) — surface it loud instead of\n * masking it as a healthy empty set. A genuinely empty `[]` passes through.\n */\n private requireArray<T>(res: Record<string, unknown>, field: string): T[] {\n const value = res[field]\n if (!Array.isArray(value)) {\n throw new Error(\n `Response missing array field \"${field}\" (got ${typeof value}: ${JSON.stringify(value)?.slice(0, 200)})`,\n )\n }\n return value as T[]\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: RegExpExecArray | null = blockRe.exec(text)\n while (match !== 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 match = blockRe.exec(text)\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 this.requireArray<{ id: string; title: string; status: string; priority: string }>(\n res,\n 'tasks',\n )\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 this.requireArray<{ id: string; title: string; type: string }>(res, 'events')\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 this.requireArray<{ id: string; title: string; status: string; type: string }>(\n res,\n 'actions',\n )\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(this.requireArray<unknown>(res, 'tree'))\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 this.requireArray<{ id: string; type: string; prompt: string }>(res, 'generations')\n }\n\n /** Generic GET for custom routes */\n async get(path: string): Promise<Record<string, unknown>> {\n return this.request('GET', path)\n }\n\n /** Generic POST for custom routes */\n async post(path: string, body: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('POST', path, body)\n }\n\n /** Generic PATCH for custom routes */\n async patch(path: string, body: Record<string, unknown>): Promise<Record<string, unknown>> {\n return this.request('PATCH', path, body)\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 { 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 WorkerDriverContext {\n /** The goal (or sub-goal) the driven worker must actually accomplish. */\n goal: string\n /** The worker's harness — e.g. 'claude-code' | 'codex' | 'opencode' | 'router-tools'.\n * Names which capability profile the driver should exploit. */\n harness?: string\n /** A capability + caveat brief for THIS harness (parallel tool calls, sub-agents and\n * their depth/concurrency limits, autonomy/runaway profile, MCP, native tool-isolation)\n * — sourced from the harness-compat matrix. Free text so the substrate stays decoupled\n * from any runtime harness type. */\n harnessBrief?: string\n /** What the worker has done so far — the trace/state summary the driver reasons over to\n * write its next instruction. Empty on the first turn. */\n progress?: string\n /** Optional extra context (repo, constraints, the deliverable's acceptance check). */\n context?: string\n}\n\n/**\n * Build the WORKER-DRIVER system prompt — the harness-aware sibling of\n * `buildDriverSystemPrompt`. Where that one role-plays a demanding *user* of a\n * product, this one is a meta-agent that DRIVES a capable coding *worker* to\n * complete a goal: it writes rich, high-signal instructions that direct the\n * worker to exploit its harness's full power (parallelize, sub-agents, run-to-\n * completion, tools/MCP), matched to what THAT harness can actually do. The\n * load-bearing contract: the driver never writes a thin steer — every message\n * is the dense, specific directive a world-class engineering lead would write.\n * Pure function; exported so harness authors can inspect and regression-test it.\n */\nexport function buildWorkerDriverSystemPrompt(ctx: WorkerDriverContext): string {\n const harness = ctx.harness ?? 'a coding agent'\n const brief = ctx.harnessBrief\n ? `\\nThis worker's harness (${harness}) can:\\n${ctx.harnessBrief}\\nDrive it to USE these — and never ask for a capability it lacks.\\n`\n : `\\nThe worker runs in ${harness}. Drive it to exploit whatever its harness offers — parallel tool calls, sub-agents, run-to-completion — and never ask for a capability it lacks.\\n`\n const progress = ctx.progress\n ? `\\nWhat the worker has done so far:\\n${ctx.progress}\\n`\n : '\\nThe worker has not started yet — your first instruction sets the whole plan.\\n'\n const context = ctx.context ? `\\nContext:\\n${ctx.context}\\n` : ''\n\n return `You are a DRIVER: a meta-agent whose entire job is to drive a capable coding worker to ACHIEVE A GOAL by writing it precise, high-signal instructions. You do not do the work yourself — you direct the worker to do it, brilliantly, and you hold it to a standard it would not hold itself to.\n\nThe goal: ${ctx.goal}\n${context}${brief}${progress}\nTHE BAR — non-negotiable. Every instruction you write is dense, specific, and complete. You write the message a world-class engineering lead writes to a strong report: the exact next objective, the concrete sub-steps, what to do in parallel vs in sequence, what to verify and how, what \"done\" looks like, and the failure modes to avoid. A thin steer — \"try again\", \"fix the issues\", a single vague sentence — is a failure on YOUR part, not the worker's. Out-drive a human power-user.\n\nHOW to drive (each turn):\n1. Read what the worker actually did (its trace/state above), not what it claims. Find the real gap between here and the goal.\n2. Decide the next objective — the largest correct step the worker can take now.\n3. Decompose it: name the sub-tasks that can run IN PARALLEL (independent files/checks/searches) and tell the worker to fan them out (sub-agents / parallel tool calls where its harness allows); name what must run in SEQUENCE and why.\n4. Make it exploit the harness: drive it to run to completion under its own autonomy, spawn sub-agents for separable work, use its tools/MCP, and not stop at the first plausible stopping point.\n5. Specify verification: the exact command / test / check that proves the step landed, and tell it to run that and report the result — never accept \"done\" without the check.\n6. Name the traps: the specific failure modes for THIS step (editing the wrong file, a check that passes vacuously, scope creep) and forbid them.\n7. As the task gets harder, decompose MORE, not less — more parallel branches, deeper sub-agent trees, tighter verification.\n\nCOMPLETION: drive toward the goal's real acceptance check. Do not declare done — the deliverable's checker does. If the worker claims it is done, drive it to PROVE it with the check; if the check fails, drive the fix.\n\nOutput ONLY your next instruction to the worker — direct, detailed, actionable, in the first person as the driver. No meta-commentary, no preamble.`\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 * Backend preflight: verify the models a campaign is about to spend tokens\n * against are actually served by the router BEFORE the run starts. The PRE-hoc\n * complement to `assertRealBackend` (which inspects RunRecords AFTER the run to\n * catch a stub/unconfigured backend).\n *\n * Two checks, increasing in cost:\n * - membership (free): GET `{baseUrl}/models` once; a model is `listed` when\n * its id is in the served set.\n * - probe (spends a tiny number of tokens): POST `{baseUrl}/chat/completions`\n * per model with a 1-message, 5-token request; `served` is whether the\n * router returns 2xx, with the HTTP `status` and the body's `error.message`\n * captured in `detail`.\n *\n * A default model the router cannot serve is a config bug. Gate a campaign on\n * `assertModelsServed` and it surfaces every dead id with its status + detail\n * instead of silently producing a stub run.\n */\n\nimport { AgentEvalError, ConfigError } from '../errors'\n\nexport interface ModelPreflight {\n /** The model id as supplied by the caller. */\n model: string\n /** Membership in the `{baseUrl}/models` served set. */\n listed: boolean\n /** 2xx on a 1-token chat probe. `null` when `probe` was not requested. */\n served: boolean | null\n /** HTTP status of the probe. `null` when not probed. */\n status: number | null\n /** Probe body's `error.message` when present, else `null`. */\n detail: string | null\n}\n\nexport interface PreflightModelsOptions {\n /** Router base URL, e.g. `https://router.tangle.tools/v1`. Trailing slash tolerated. */\n baseUrl: string\n /** Bearer token sent as `Authorization: Bearer <apiKey>`. */\n apiKey: string\n /** Model ids to check. */\n models: string[]\n /** When true, additionally spend a 1-token chat probe per model. Default false. */\n probe?: boolean\n /** Injectable fetch for tests; defaults to the global. */\n fetchImpl?: typeof fetch\n}\n\nexport interface PreflightOutcome {\n succeeded: boolean\n value: ModelPreflight[] | null\n error: string | null\n}\n\ninterface ModelsListBody {\n data?: ReadonlyArray<{ id?: unknown }>\n}\n\ninterface ChatErrorBody {\n error?: { message?: unknown }\n message?: unknown\n}\n\nfunction stripSlash(url: string): string {\n return url.replace(/\\/+$/, '')\n}\n\n/** Extract `error.message` (then top-level `message`) from a chat-completions error body. */\nfunction errorMessage(body: unknown): string | null {\n if (body == null || typeof body !== 'object') return null\n const b = body as ChatErrorBody\n if (b.error && typeof b.error.message === 'string') return b.error.message\n if (typeof b.message === 'string') return b.message\n return null\n}\n\n/**\n * Check that `models` are reachable on the router. Returns a typed outcome —\n * a network failure yields `{ succeeded: false, error }`, never a throw and\n * never a partial result silently reported as success. No retries, no\n * fallbacks.\n *\n * The membership check (one GET) always runs. When `probe` is true, each model\n * additionally gets a 1-token chat probe so a model that is listed but\n * unconfigured (a 401 `model_not_found` from the router) is caught.\n */\nexport async function preflightModels(opts: PreflightModelsOptions): Promise<PreflightOutcome> {\n const fetchImpl = opts.fetchImpl ?? fetch\n const baseUrl = stripSlash(opts.baseUrl)\n const authHeaders = { authorization: `Bearer ${opts.apiKey}` }\n\n let served: Set<string>\n try {\n const res = await fetchImpl(`${baseUrl}/models`, { method: 'GET', headers: authHeaders })\n if (!res.ok) {\n const text = await res.text().catch(() => '')\n return {\n succeeded: false,\n value: null,\n error: `preflightModels: GET ${baseUrl}/models → ${res.status} ${text.slice(0, 400)}`,\n }\n }\n const body = (await res.json()) as ModelsListBody\n const ids = Array.isArray(body.data) ? body.data : []\n served = new Set(ids.map((m) => m.id).filter((id): id is string => typeof id === 'string'))\n } catch (err) {\n return {\n succeeded: false,\n value: null,\n error: `preflightModels: GET ${baseUrl}/models failed — ${err instanceof Error ? err.message : String(err)}`,\n }\n }\n\n const results: ModelPreflight[] = []\n for (const model of opts.models) {\n const listed = served.has(model)\n if (!opts.probe) {\n results.push({ model, listed, served: null, status: null, detail: null })\n continue\n }\n try {\n const res = await fetchImpl(`${baseUrl}/chat/completions`, {\n method: 'POST',\n headers: { ...authHeaders, 'content-type': 'application/json' },\n body: JSON.stringify({\n model,\n messages: [{ role: 'user', content: 'ping' }],\n max_tokens: 5,\n }),\n })\n let detail: string | null = null\n if (!res.ok) {\n const body = await res.json().catch(() => null)\n detail = errorMessage(body)\n }\n results.push({ model, listed, served: res.ok, status: res.status, detail })\n } catch (err) {\n return {\n succeeded: false,\n value: null,\n error: `preflightModels: probe POST ${baseUrl}/chat/completions (model ${model}) failed — ${err instanceof Error ? err.message : String(err)}`,\n }\n }\n }\n\n return { succeeded: true, value: results, error: null }\n}\n\nexport class ModelsUnreachableError extends AgentEvalError {\n constructor(\n message: string,\n public readonly results: ReadonlyArray<ModelPreflight>,\n ) {\n super('config', message)\n this.name = 'ModelsUnreachableError'\n }\n}\n\nfunction describeFailure(r: ModelPreflight): string {\n if (!r.listed) {\n const probeNote =\n r.served === false ? ` (probe ${r.status}${r.detail ? `: ${r.detail}` : ''})` : ''\n return `${r.model}: not in /models${probeNote}`\n }\n // listed but failed its probe\n return `${r.model}: listed but probe ${r.status}${r.detail ? ` — ${r.detail}` : ''}`\n}\n\n/**\n * Throw `ModelsUnreachableError` naming EVERY model that is unlisted or (when\n * probed) failed its probe — with status + detail per model. A model is dead\n * if it is unlisted, or if `served === false`. Callers gate a campaign on this\n * before spending tokens. When the network call itself fails the underlying\n * outcome error is rethrown — there is no partial silent pass.\n */\nexport async function assertModelsServed(opts: PreflightModelsOptions): Promise<ModelPreflight[]> {\n const outcome = await preflightModels(opts)\n if (!outcome.succeeded || outcome.value === null) {\n throw new ConfigError(\n outcome.error ?? 'assertModelsServed: preflight failed without an error message',\n )\n }\n const dead = outcome.value.filter((r) => !r.listed || r.served === false)\n if (dead.length > 0) {\n throw new ModelsUnreachableError(\n `assertModelsServed: ${dead.length}/${outcome.value.length} model(s) unreachable on the router — ${dead\n .map(describeFailure)\n .join('; ')}`,\n outcome.value,\n )\n }\n return outcome.value\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 {\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","/**\n * Matched-pair arm comparison — \"did the treatment arm beat the baseline arm\n * on the SAME work items?\"\n *\n * An arm A/B over run records is only trustworthy when it is PAIRED: the same\n * task/scenario/seed evaluated under both arms, compared item-by-item, so\n * inter-item difficulty variance cancels instead of masquerading as an arm\n * effect. This module owns the two error-prone steps every consumer otherwise\n * hand-rolls:\n *\n * 1. Pairing — matching rows across arms by `pairKey` (and by `repKey`\n * within multi-rep items), with leftovers REPORTED rather than silently\n * dropped (a silently unbalanced pairing biases every paired statistic\n * downstream). Pairing never keys on outcome content: matching reps by\n * their outcomes deflates discordant-pair counts and makes McNemar\n * anti-conservative, so reps pair only by (`pairKey`, `repKey`) identity.\n * 2. Composition — feeding the matched pairs to the correct paired\n * estimators that already live in `statistics`: `mcnemar` +\n * `pairedRiskDifference` for pass/fail, `pairedBootstrap` +\n * `wilcoxonSignedRank` for continuous metrics. No statistic is\n * re-implemented here.\n *\n * The row shape is deliberately structural — callers project a `RunRecord`\n * (or any record) into `{ pairKey, arm, pass?, metrics? }`. Arm names are\n * caller-supplied parameters; the module ships no domain literal.\n */\n\nimport { ValidationError } from './errors'\nimport type { McNemarResult, PairedBootstrapOptions, PairedBootstrapResult } from './statistics'\nimport {\n mcnemar,\n pairedBootstrap,\n pairedRiskDifference,\n type RiskDifferenceResult,\n wilcoxonSignedRank,\n} from './statistics'\n\n/** One arm observation of one work item. Structural on purpose: callers\n * project their own record type (e.g. a `RunRecord`) into this shape. */\nexport interface PairedArmRow {\n /** Matching key — rows sharing a `pairKey` across both arms form pairs\n * (typically the task/scenario/seed identity). */\n pairKey: string\n /** Rep identity within a `pairKey` (e.g. a seed or rep number). Required on\n * every row of a `pairKey` that has more than one rep in either arm; reps\n * then pair only on exact (`pairKey`, `repKey`) match, never on outcome\n * content. Optional when each arm has at most one rep of the item. */\n repKey?: string\n /** Arm label this row was produced under. */\n arm: string\n /** Binary outcome; omit when the comparison has no pass/fail notion. */\n pass?: boolean\n /** Named numeric measurements (score, cost, latency, …). */\n metrics?: Record<string, number>\n}\n\nexport interface PairArmsOptions {\n /** Arm treated as the control side of every pair. */\n baselineArm: string\n /** Arm treated as the treatment side of every pair. */\n treatmentArm: string\n}\n\n/** One matched (baseline, treatment) observation of the same work item. */\nexport interface MatchedPair {\n pairKey: string\n /** 0-based position of this pair within its `pairKey`, ordered by sorted\n * `repKey` (always 0 for a single-rep item). The rep identity itself is on\n * the rows (`baseline.repKey` / `treatment.repKey`). */\n repIndex: number\n baseline: PairedArmRow\n treatment: PairedArmRow\n}\n\nexport interface PairArmsResult {\n /** Matched pairs, ordered by (`pairKey`, `repIndex`). */\n pairs: MatchedPair[]\n /** Baseline rows left without a treatment counterpart — reported, never\n * silently dropped. */\n unpairedBaseline: PairedArmRow[]\n /** Treatment rows left without a baseline counterpart. */\n unpairedTreatment: PairedArmRow[]\n}\n\n/**\n * Match rows across two arms into (baseline, treatment) pairs by `pairKey`.\n *\n * A `pairKey` with at most one row per arm pairs directly, no `repKey`\n * needed. A `pairKey` with multiple reps in either arm requires `repKey` on\n * every one of its rows, and reps pair only on exact (`pairKey`, `repKey`)\n * match — pairing is keyed purely on row identity, never on outcome content\n * (outcome-keyed matching deflates discordant counts and biases McNemar), and\n * is therefore independent of input order. Reps whose `repKey` has no\n * counterpart in the other arm, and items present in only one arm, land in\n * the unpaired lists — reported, never truncated.\n *\n * Fail-loud: throws when either named arm has zero rows (an unknown arm\n * name would otherwise read as \"everything unpaired\"), when the two arm\n * names are equal, when a multi-rep `pairKey` has a row without `repKey`, or\n * when a (`pairKey`, arm) group repeats a `repKey` (the match would be\n * ambiguous).\n */\nexport function pairArms(rows: readonly PairedArmRow[], opts: PairArmsOptions): PairArmsResult {\n const { baselineArm, treatmentArm } = opts\n if (baselineArm === treatmentArm) {\n throw new ValidationError(\n `pairArms: baselineArm and treatmentArm are both '${baselineArm}' — an arm cannot be compared to itself`,\n )\n }\n\n // arm → pairKey → rows\n const byArm = new Map<string, Map<string, PairedArmRow[]>>()\n const armsSeen = new Set<string>()\n for (const row of rows) {\n armsSeen.add(row.arm)\n if (row.arm !== baselineArm && row.arm !== treatmentArm) continue\n const byKey = byArm.get(row.arm) ?? new Map<string, PairedArmRow[]>()\n const group = byKey.get(row.pairKey) ?? []\n group.push(row)\n byKey.set(row.pairKey, group)\n byArm.set(row.arm, byKey)\n }\n\n for (const arm of [baselineArm, treatmentArm]) {\n if (!byArm.has(arm)) {\n const seen = [...armsSeen].sort().join(', ') || '<none>'\n throw new ValidationError(`pairArms: no rows for arm '${arm}' (arms present: ${seen})`)\n }\n }\n\n const baselineByKey = byArm.get(baselineArm)!\n const treatmentByKey = byArm.get(treatmentArm)!\n\n const allKeys = [...new Set([...baselineByKey.keys(), ...treatmentByKey.keys()])].sort()\n const pairs: MatchedPair[] = []\n const unpairedBaseline: PairedArmRow[] = []\n const unpairedTreatment: PairedArmRow[] = []\n for (const pairKey of allKeys) {\n const b = baselineByKey.get(pairKey) ?? []\n const t = treatmentByKey.get(pairKey) ?? []\n\n if (b.length <= 1 && t.length <= 1) {\n if (b.length === 1 && t.length === 1) {\n pairs.push({ pairKey, repIndex: 0, baseline: b[0]!, treatment: t[0]! })\n } else {\n unpairedBaseline.push(...b)\n unpairedTreatment.push(...t)\n }\n continue\n }\n\n const bByRep = indexByRepKey(b, pairKey, baselineArm)\n const tByRep = indexByRepKey(t, pairKey, treatmentArm)\n const repKeys = [...new Set([...bByRep.keys(), ...tByRep.keys()])].sort()\n let repIndex = 0\n for (const repKey of repKeys) {\n const baseline = bByRep.get(repKey)\n const treatment = tByRep.get(repKey)\n if (baseline !== undefined && treatment !== undefined) {\n pairs.push({ pairKey, repIndex: repIndex++, baseline, treatment })\n } else if (baseline !== undefined) {\n unpairedBaseline.push(baseline)\n } else if (treatment !== undefined) {\n unpairedTreatment.push(treatment)\n }\n }\n }\n\n return { pairs, unpairedBaseline, unpairedTreatment }\n}\n\n/** Index a multi-rep (pairKey, arm) group by `repKey`, enforcing that every\n * row carries one and that no repKey repeats within the group. */\nfunction indexByRepKey(\n group: readonly PairedArmRow[],\n pairKey: string,\n arm: string,\n): Map<string, PairedArmRow> {\n const byRep = new Map<string, PairedArmRow>()\n for (const row of group) {\n if (row.repKey === undefined) {\n throw new ValidationError(\n `pairArms: pairKey '${pairKey}' has multiple reps in an arm, but a row in arm '${arm}' ` +\n `is missing repKey — multi-rep items require an explicit repKey on every row so reps ` +\n `pair by identity (pairing reps by outcome or by index would bias the paired statistics)`,\n )\n }\n if (byRep.has(row.repKey)) {\n throw new ValidationError(\n `pairArms: duplicate repKey '${row.repKey}' for pairKey '${pairKey}' in arm '${arm}' — ` +\n `(pairKey, repKey) must uniquely identify a rep within an arm`,\n )\n }\n byRep.set(row.repKey, row)\n }\n return byRep\n}\n\n/** Paired pass/fail comparison over the pairs where BOTH sides carry `pass`. */\nexport interface PairedCorrectness {\n /** Discordant pairs where the treatment passed and the baseline failed. */\n b10: number\n /** Discordant pairs where the baseline passed and the treatment failed. */\n b01: number\n /** Exact McNemar significance over the paired outcomes (`b === b10`, `c === b01`). */\n mcnemar: McNemarResult\n /** Paired effect size: p(treatment) − p(baseline) with a paired-variance CI. */\n riskDifference: RiskDifferenceResult\n}\n\n/** Paired delta summary for one named metric (delta = treatment − baseline). */\nexport interface PairedMetricDelta {\n name: string\n /** Pairs where BOTH sides carry a finite value for this metric. */\n n: number\n /** Pairs where at least one side does not carry the metric. */\n nMissing: number\n /** Median paired delta; NaN when `n === 0` (no data ≠ measured zero). */\n medianDelta: number\n /** Mean paired delta; NaN when `n === 0`. */\n meanDelta: number\n /** Bootstrap CI on the paired delta (`pairedBootstrap`); null when\n * `n === 0` — a zero-width [0, 0] interval on no data would read as a\n * measured tight null. */\n bootstrapCi: PairedBootstrapResult | null\n /** Wilcoxon signed-rank test on the paired deltas; null when `n === 0`. */\n wilcoxon: { w: number; p: number } | null\n}\n\nexport interface ComparePairedArmsOptions extends PairArmsOptions {\n /** Metrics to compare. Default: every metric name observed on any matched\n * pair, sorted. A name that appears on no pair is still reported (with\n * `n = 0`) so a misspelled metric is visible instead of vanishing. */\n metricNames?: string[]\n /** Passed through to `pairedBootstrap` — set `seed` for reproducible CIs. */\n bootstrap?: PairedBootstrapOptions\n}\n\nexport interface PairedArmsComparison {\n nPairs: number\n nUnpairedBaseline: number\n nUnpairedTreatment: number\n /** null when no matched pair carries `pass` on both sides — a pass/fail\n * verdict over rows that never measured pass/fail would be fabricated. */\n correctness: PairedCorrectness | null\n metricDeltas: PairedMetricDelta[]\n}\n\n/**\n * Full matched-pair arm comparison: pair via {@link pairArms}, then compose\n * the paired estimators from `statistics` over the matched pairs.\n *\n * Correctness uses only the pairs where both sides carry `pass` (`mcnemar.n`\n * is that subset's size); each metric uses only the pairs where both sides\n * carry a finite value for it, with the remainder counted in `nMissing`.\n * Deltas are treatment − baseline throughout.\n *\n * Fail-loud: inherits {@link pairArms}'s unknown-arm throw, and throws on a\n * non-finite metric value — silently treating corrupt telemetry as \"metric\n * absent\" would misreport it as missing coverage.\n */\nexport function comparePairedArms(\n rows: readonly PairedArmRow[],\n opts: ComparePairedArmsOptions,\n): PairedArmsComparison {\n const { pairs, unpairedBaseline, unpairedTreatment } = pairArms(rows, opts)\n\n let correctness: PairedCorrectness | null = null\n const baselinePass: number[] = []\n const treatmentPass: number[] = []\n for (const pair of pairs) {\n if (pair.baseline.pass === undefined || pair.treatment.pass === undefined) continue\n baselinePass.push(pair.baseline.pass ? 1 : 0)\n treatmentPass.push(pair.treatment.pass ? 1 : 0)\n }\n if (baselinePass.length > 0) {\n const mc = mcnemar(baselinePass, treatmentPass)\n correctness = {\n b10: mc.b,\n b01: mc.c,\n mcnemar: mc,\n riskDifference: pairedRiskDifference(baselinePass, treatmentPass),\n }\n }\n\n const metricNames =\n opts.metricNames ??\n [\n ...new Set(\n pairs.flatMap((p) => [\n ...Object.keys(p.baseline.metrics ?? {}),\n ...Object.keys(p.treatment.metrics ?? {}),\n ]),\n ),\n ].sort()\n\n const metricDeltas: PairedMetricDelta[] = metricNames.map((name) => {\n const before: number[] = []\n const after: number[] = []\n let nMissing = 0\n for (const pair of pairs) {\n const b = metricValue(pair.baseline, name)\n const t = metricValue(pair.treatment, name)\n if (b === undefined || t === undefined) {\n nMissing++\n continue\n }\n before.push(b)\n after.push(t)\n }\n const bootstrapCi = before.length === 0 ? null : pairedBootstrap(before, after, opts.bootstrap)\n return {\n name,\n n: before.length,\n nMissing,\n medianDelta: bootstrapCi === null ? Number.NaN : bootstrapCi.median,\n meanDelta: bootstrapCi === null ? Number.NaN : bootstrapCi.mean,\n bootstrapCi,\n wilcoxon: before.length === 0 ? null : wilcoxonSignedRank(before, after),\n }\n })\n\n return {\n nPairs: pairs.length,\n nUnpairedBaseline: unpairedBaseline.length,\n nUnpairedTreatment: unpairedTreatment.length,\n correctness,\n metricDeltas,\n }\n}\n\nfunction metricValue(row: PairedArmRow, name: string): number | undefined {\n const v = row.metrics?.[name]\n if (v === undefined) return undefined\n if (!Number.isFinite(v)) {\n throw new ValidationError(\n `comparePairedArms: non-finite value for metric '${name}' on pairKey '${row.pairKey}' (arm '${row.arm}'): ${v}`,\n )\n }\n return v\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 * Treatment-applied gate — \"did the treatment's tool actually fire this run?\"\n *\n * A tool-treatment A/B (mount a search provider, a browser, a code-exec\n * sandbox, a retrieval MCP — anything one arm gets and the other doesn't) only\n * means something on the treatment arm if that arm actually EXERCISED the tool.\n * A treatment run that never called the mounted tool is not a weak data point\n * — it is a NON-data-point: the manipulation never happened, so the run cannot\n * speak to the treatment and must be excluded from the objective, the same way\n * an infra-tainted run is excluded.\n *\n * This is the manipulation/validity precondition that protects the paired A/B\n * tests downstream (`mcnemar`, `pairedRiskDifference`): they must only ever see\n * runs where the treatment was applied, or they measure noise and report it as\n * an effect.\n *\n * Shape mirrors `authenticity`'s `gateRealness`: a pure predicate over already-\n * computed signals, with explicit fail-open/fail-closed discipline. It is not a\n * trace parser — the tool-call telemetry it reads is the deterministic\n * `toolHistogram` that `computeTraceMetrics(spans)` already produces (OTLP\n * tool-name extraction via `TOOL_NAME_ATTR_KEYS`), or the `ToolSpan[]` a\n * `toolSpans(store, runId)` query returns. The gate never re-derives either.\n *\n * General by construction:\n * - The \"which tool counts as the treatment\" decision is a `matches` PARAMETER\n * — a `(toolName: string) => boolean`. There is no `search`/`web`/`fetch`\n * literal anywhere in this module; a search A/B passes its own matcher.\n * - The \"is THIS run a treatment arm (vs a control)\" decision is the caller's\n * policy and stays at the call site. The gate only answers the narrower,\n * domain-free question: \"given this run's telemetry, did a matching tool\n * fire?\" — so it generalizes to any tool-treatment, not search.\n *\n * Fail-open on telemetry absence: when NO tool calls were captured at all\n * (`sum(toolHistogram) === 0`), the gate cannot distinguish \"the agent used no\n * tools\" from \"this harness's tool calls weren't recorded\". Quarantining on a\n * telemetry gap would silently delete real runs, so the default is\n * applied=true / gated=false. Pass `failOpenWhenNoTelemetry: false` to flip to\n * fail-closed for harnesses where tool capture is guaranteed.\n */\n\nimport type { RunRecord } from './run-record'\nimport type { ToolSpan } from './trace/schema'\nimport type { BehavioralMetrics } from './trace-analyst/behavioral-metrics'\nimport { computeTraceMetrics } from './trace-analyst/behavioral-metrics'\nimport type { TraceAnalystSpan } from './trace-analyst/types'\n\n/** A tool-name matcher: does this tool name belong to the treatment under test?\n * The caller supplies it — the substrate ships no `search` (or any) literal. */\nexport type ToolMatcher = (toolName: string) => boolean\n\nexport interface TreatmentGateInput {\n /** Tool-call counts by tool name — exactly `computeTraceMetrics(spans).toolHistogram`.\n * The gate consumes this; it does not parse spans itself. */\n toolHistogram: Readonly<Record<string, number>>\n /** Which tool names count as the treatment firing. A parameter, never baked in. */\n matches: ToolMatcher\n}\n\nexport interface TreatmentGateOptions {\n /** When the histogram is empty (no tool telemetry captured), treat the run as\n * applied rather than quarantining it. Default true — a telemetry gap must\n * never be mistaken for \"treatment not applied\". Set false only when tool\n * capture is guaranteed for this harness. */\n failOpenWhenNoTelemetry?: boolean\n}\n\nexport interface TreatmentGate {\n /** True iff the treatment's tool is considered to have fired this run. False\n * ONLY when telemetry was present and no matching call appears. */\n applied: boolean\n /** Objective-exclusion flag, parallel to `outcome.realness.gated`: a gated run\n * is dropped from the objective denominator and reported as\n * treatment-not-applied (like infra-loss). `gated === !applied`. */\n gated: boolean\n reason?: string\n /** How many recorded tool calls matched the treatment matcher. */\n matchedCalls: number\n /** Total recorded tool calls (`sum(toolHistogram)`) — 0 means no telemetry. */\n observedTools: number\n}\n\n/**\n * Core predicate. Gated (treatment-not-applied) ONLY when telemetry was\n * captured AND zero matching calls appear; an empty histogram fails open.\n */\nexport function gateTreatmentApplied(\n input: TreatmentGateInput,\n opts: TreatmentGateOptions = {},\n): TreatmentGate {\n const failOpen = opts.failOpenWhenNoTelemetry ?? true\n\n let observedTools = 0\n let matchedCalls = 0\n for (const [tool, count] of Object.entries(input.toolHistogram)) {\n const n = Number.isFinite(count) && count > 0 ? count : 0\n observedTools += n\n if (n > 0 && input.matches(tool)) matchedCalls += n\n }\n\n if (observedTools === 0) {\n return failOpen\n ? {\n applied: true,\n gated: false,\n reason: 'no tool telemetry captured — fail-open (not quarantined)',\n matchedCalls: 0,\n observedTools: 0,\n }\n : {\n applied: false,\n gated: true,\n reason: 'no tool telemetry captured — fail-closed',\n matchedCalls: 0,\n observedTools: 0,\n }\n }\n\n if (matchedCalls === 0) {\n return {\n applied: false,\n gated: true,\n reason: `treatment tool never fired (${observedTools} tool calls, 0 matched)`,\n matchedCalls: 0,\n observedTools,\n }\n }\n\n return { applied: true, gated: false, matchedCalls, observedTools }\n}\n\n/**\n * Convenience: gate from an already-computed `BehavioralMetrics` (the common\n * case — analysts already hold `computeTraceMetrics(spans)` for the run). Reads\n * the metrics' `toolHistogram`; does no re-derivation.\n */\nexport function gateTreatmentFromMetrics(\n metrics: Pick<BehavioralMetrics, 'toolHistogram'>,\n matches: ToolMatcher,\n opts?: TreatmentGateOptions,\n): TreatmentGate {\n return gateTreatmentApplied({ toolHistogram: metrics.toolHistogram, matches }, opts)\n}\n\n/**\n * Convenience: gate directly from analyst spans, reusing the substrate's\n * deterministic histogram builder. For callers holding the trace store's typed\n * `ToolSpan[]` instead, see {@link gateTreatmentFromToolSpans}.\n */\nexport function gateTreatmentFromSpans(\n spans: readonly TraceAnalystSpan[],\n matches: ToolMatcher,\n opts?: TreatmentGateOptions,\n): TreatmentGate {\n return gateTreatmentFromMetrics(computeTraceMetrics(spans), matches, opts)\n}\n\n/**\n * Convenience: gate from the trace store's canonical `ToolSpan[]` (e.g. the\n * result of `toolSpans(store, runId)`). Counts by `toolName` — the typed\n * tool-call field — so it needs no OTLP attribute extraction.\n */\nexport function gateTreatmentFromToolSpans(\n toolSpans: readonly ToolSpan[],\n matches: ToolMatcher,\n opts?: TreatmentGateOptions,\n): TreatmentGate {\n const toolHistogram: Record<string, number> = {}\n for (const s of toolSpans) {\n if (s.toolName) toolHistogram[s.toolName] = (toolHistogram[s.toolName] ?? 0) + 1\n }\n return gateTreatmentApplied({ toolHistogram, matches }, opts)\n}\n\n/** Measurable runs count toward the objective; treatment-not-applied runs are\n * excluded (like infra-loss), NOT counted as treatment failures. This is a\n * partition over the existing exclusion-flag pattern — it adds no new\n * classification enum. */\nexport type TreatmentClass = 'measurable' | 'treatment-not-applied'\n\n/**\n * Map a gate verdict onto a single measurable-vs-excluded label keyed on a\n * `RunRecord`, so consumers (paired A/B filters, reporters) read the partition\n * in one place instead of re-implementing the fail-open guard inline. The\n * `RunRecord` is accepted so callers key on the canonical run row, mirroring\n * how `outcome.realness.gated` rides along on the record; the verdict itself is\n * the gate's, not re-derived here.\n */\nexport function classifyTreatment(_record: RunRecord, gate: TreatmentGate): TreatmentClass {\n return gate.gated ? 'treatment-not-applied' : 'measurable'\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 = lower.indexOf(needle, 0)\n while (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 = lower.indexOf(needle, 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 * 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 * Eval primitives as agent tools — `makeEvalTools` packages the substrate's\n * judge / completion / analysis entry points as JSON-Schema tool definitions\n * an LLM agent loop can call. The host closes over the live config (judge\n * panels, the correctness checker, analyst registry); the agent passes only\n * data over the wire.\n *\n * Three tools, each present only when its config section is supplied:\n * - `run_judges` — score an artifact with the configured `JudgeConfig`s\n * - `verify_completion` — gold-spec requirement check → `CompletionVerdict`\n * - `analyze_runs` — `RunRecord[]` (inline or from a file) → `InsightReport`\n *\n * `toOpenAiTool` converts a definition to the OpenAI function-tool wire shape.\n */\n\nimport { readFile } from 'node:fs/promises'\nimport type { JudgeConfig, JudgeScore, Scenario } from './campaign/types'\nimport {\n type CompletionVerdict,\n type CorrectnessChecker,\n type ProducedState,\n type TaskGold,\n verifyCompletion,\n} from './completion-verifier'\nimport { type AnalyzeRunsOptions, analyzeRuns } from './contract/analyze-runs'\nimport type { RunRecord } from './run-record'\n\n/** One agent-callable tool. `parameters` is a JSON Schema (draft-07+) object. */\nexport interface EvalToolDef {\n name: string\n description: string\n parameters: Record<string, unknown>\n handler: (args: unknown, ctx?: { signal?: AbortSignal }) => Promise<unknown>\n}\n\nexport interface MakeEvalToolsConfig {\n /** Judges available to `run_judges`. Omit to exclude the tool. */\n judges?: Array<JudgeConfig<unknown>>\n /** Host-side correctness checker for `verify_completion` (the third\n * `verifyCompletion` argument — a function, so it cannot cross the wire).\n * Omit to exclude the tool. */\n completion?: { checkCorrectness: CorrectnessChecker }\n /** `analyzeRuns` options minus `runs` (runs arrive as tool args, inline or\n * via `path`). Omit to exclude the tool. */\n analyze?: Omit<AnalyzeRunsOptions, 'runs'>\n}\n\n/** OpenAI function-tool wire shape for an `EvalToolDef`. */\nexport function toOpenAiTool(def: EvalToolDef): {\n type: 'function'\n function: { name: string; description: string; parameters: Record<string, unknown> }\n} {\n return {\n type: 'function',\n function: { name: def.name, description: def.description, parameters: def.parameters },\n }\n}\n\n/**\n * Build the eval toolset for the supplied config. Only sections present in\n * `cfg` produce tools, so the agent's tool list mirrors what the host\n * actually wired. Handlers fail loud on malformed args — no silent defaults.\n */\nexport function makeEvalTools(cfg: MakeEvalToolsConfig): EvalToolDef[] {\n const tools: EvalToolDef[] = []\n if (cfg.judges) tools.push(runJudgesTool(cfg.judges))\n if (cfg.completion) tools.push(verifyCompletionTool(cfg.completion.checkCorrectness))\n if (cfg.analyze) tools.push(analyzeRunsTool(cfg.analyze))\n return tools\n}\n\n// ── run_judges ───────────────────────────────────────────────────────────\n\nfunction runJudgesTool(judges: Array<JudgeConfig<unknown>>): EvalToolDef {\n if (judges.length === 0) {\n throw new Error('makeEvalTools: cfg.judges is empty — supply judges or omit the section')\n }\n const names = judges.map((j) => j.name)\n return {\n name: 'run_judges',\n description:\n `Score an artifact with the configured judges (${names.join(', ')}). ` +\n 'Pass `judge` to run one judge by name; omit it to run all. ' +\n 'Returns per-judge scores keyed by judge name.',\n parameters: {\n type: 'object',\n properties: {\n judge: {\n type: 'string',\n enum: names,\n description: 'Run only this judge. Omit to run every configured judge.',\n },\n artifact: {\n description: 'The artifact to score — any JSON value the judges understand.',\n },\n scenario: {\n description: 'Optional scenario context forwarded to the judges.',\n },\n },\n required: ['artifact'],\n additionalProperties: false,\n },\n handler: async (args, ctx) => {\n const a = requireObjectArgs('run_judges', args)\n if (!('artifact' in a)) {\n throw new Error('run_judges: args.artifact is required')\n }\n let selected = judges\n if (a.judge !== undefined) {\n if (typeof a.judge !== 'string') throw new Error('run_judges: args.judge must be a string')\n selected = judges.filter((j) => j.name === a.judge)\n if (selected.length === 0) {\n throw new Error(\n `run_judges: unknown judge '${a.judge}' — configured: ${names.join(', ')}`,\n )\n }\n }\n const signal = ctx?.signal ?? new AbortController().signal\n const scenario = a.scenario as Scenario\n const scores: Record<string, JudgeScore> = {}\n for (const judge of selected) {\n if (scenario !== undefined && judge.appliesTo && !judge.appliesTo(scenario)) continue\n scores[judge.name] = await judge.score({ artifact: a.artifact, scenario, signal })\n }\n return { scores }\n },\n }\n}\n\n// ── verify_completion ────────────────────────────────────────────────────\n\nfunction verifyCompletionTool(checkCorrectness: CorrectnessChecker): EvalToolDef {\n return {\n name: 'verify_completion',\n description:\n 'Verify produced state against a gold task spec: each gold requirement is ' +\n 'matched to at most one produced artifact/proposal/tool-call, correctness-checked ' +\n 'by the host, and reduced to a CompletionVerdict (completionRate, fullyComplete, ' +\n 'per-requirement checks).',\n parameters: {\n type: 'object',\n properties: {\n gold: {\n type: 'object',\n description: 'TaskGold — taskId + requirements the produced state must satisfy.',\n },\n state: {\n type: 'object',\n description: 'ProducedState — artifacts, proposals, and tool calls the agent produced.',\n },\n },\n required: ['gold', 'state'],\n additionalProperties: false,\n },\n handler: async (args): Promise<CompletionVerdict> => {\n const a = requireObjectArgs('verify_completion', args)\n if (typeof a.gold !== 'object' || a.gold === null) {\n throw new Error('verify_completion: args.gold (TaskGold) is required')\n }\n if (typeof a.state !== 'object' || a.state === null) {\n throw new Error('verify_completion: args.state (ProducedState) is required')\n }\n return verifyCompletion(a.gold as TaskGold, a.state as ProducedState, checkCorrectness)\n },\n }\n}\n\n// ── analyze_runs ─────────────────────────────────────────────────────────\n\nfunction analyzeRunsTool(analyzeOpts: Omit<AnalyzeRunsOptions, 'runs'>): EvalToolDef {\n return {\n name: 'analyze_runs',\n description:\n 'Run analyzeRuns over a set of RunRecords and return the InsightReport ' +\n '(composite distribution, per-dimension stats, lift, failure clusters, ' +\n 'recommendations). Pass the records inline via `runs`, or `path` to a ' +\n '.json (array) or .jsonl (one record per line) file on the host.',\n parameters: {\n type: 'object',\n properties: {\n runs: {\n type: 'array',\n items: { type: 'object' },\n description: 'RunRecord[] inline.',\n },\n path: {\n type: 'string',\n description: 'Host path to a JSON array or JSONL file of RunRecords.',\n },\n },\n additionalProperties: false,\n },\n handler: async (args) => {\n const a = requireObjectArgs('analyze_runs', args)\n const hasRuns = Array.isArray(a.runs)\n const hasPath = typeof a.path === 'string' && a.path.length > 0\n if (hasRuns === hasPath) {\n throw new Error('analyze_runs: pass exactly one of args.runs (array) or args.path (string)')\n }\n const runs = hasRuns ? (a.runs as RunRecord[]) : await loadRunRecords(a.path as string)\n if (runs.length === 0) {\n throw new Error('analyze_runs: no runs to analyze')\n }\n return analyzeRuns({ ...analyzeOpts, runs })\n },\n }\n}\n\nasync function loadRunRecords(path: string): Promise<RunRecord[]> {\n const text = await readFile(path, 'utf8')\n const trimmed = text.trim()\n if (trimmed.length === 0) {\n throw new Error(`analyze_runs: file '${path}' is empty`)\n }\n if (trimmed.startsWith('[')) {\n const parsed = JSON.parse(trimmed) as unknown\n if (!Array.isArray(parsed)) {\n throw new Error(`analyze_runs: file '${path}' did not parse to an array`)\n }\n return parsed as RunRecord[]\n }\n // JSONL: one record per non-empty line. A malformed line throws with its\n // line number rather than being skipped.\n return trimmed.split('\\n').flatMap((line, i) => {\n const l = line.trim()\n if (l.length === 0) return []\n try {\n return [JSON.parse(l) as RunRecord]\n } catch (err) {\n throw new Error(\n `analyze_runs: file '${path}' line ${i + 1} is not valid JSON: ${err instanceof Error ? err.message : String(err)}`,\n )\n }\n })\n}\n\nfunction requireObjectArgs(tool: string, args: unknown): Record<string, unknown> {\n if (typeof args !== 'object' || args === null || Array.isArray(args)) {\n throw new Error(`${tool}: args must be an object`)\n }\n return args as Record<string, unknown>\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","/**\n * Judge-ensemble reducer — folds N independent judge verdicts on the same\n * artifact into one aggregate score.\n *\n * The pattern every multi-model judge re-implements: run K uncorrelated judges\n * (different model families remove within-family bias), then reduce their\n * per-dimension verdicts to a single composite + an inter-rater disagreement\n * signal. This is the pure reduction — no LLM, no I/O — so a lift it produces\n * is attributable to the scores, not to where they came from.\n *\n * Fail-loud: a judge that errored or returned malformed output is recorded in\n * `failedJudges` with `perDimension: null`, never folded into a zero. If EVERY\n * judge failed the reducer throws — a silent zero here would corrupt the gate's\n * number. A failed judge still burned tokens, so its `costUsd` is still summed.\n */\n\nimport { clamp01 } from './run-score'\nimport { weightedComposite } from './statistics'\n\n/** One judge's verdict. `perDimension: null` ⇒ that judge call failed (threw or\n * returned malformed output) — recorded, never folded into a zero. */\nexport interface JudgeVerdict<D extends string = string> {\n /** Judge identity (typically the model id) — the `perJudge` / `failedJudges` key. */\n model: string\n /** Per-dimension scores, or `null` when the judge failed. */\n perDimension: Record<D, number> | null\n /** Optional one-line rationale; the first non-empty one becomes the aggregate's. */\n rationale?: string\n /** Optional reported cost — summed across ALL verdicts (failed included). */\n costUsd?: number\n /** Optional per-dimension reasoning/evidence. Carried through to\n * `EnsembleAggregate.verdicts` verbatim — never folded into the math. */\n detail?: Partial<Record<D, { reasoning?: string; evidence?: string }>>\n}\n\n/** The aggregated ensemble result. */\nexport interface EnsembleAggregate<D extends string = string> {\n /** Mean over SURVIVING judges, per dimension (absent-everywhere ⇒ 0). */\n perDimension: Record<D, number>\n /** Weighted mean of `perDimension` (uniform unless `weights` given). */\n composite: number\n /** Each surviving judge's clamped per-dimension scores, for trace drill-down. */\n perJudge: Record<string, Record<D, number>>\n /** Max over dimensions of (max − min) across survivors — the inter-rater signal. */\n maxDisagreement: number\n /** Models whose verdict was null (failed). */\n failedJudges: string[]\n /** Sum of `costUsd` over ALL verdicts, failed included. */\n costUsd: number\n /** First non-empty survivor rationale, or `'llm-judge'`. */\n rationale: string\n /** The input verdicts, verbatim — drill-down to raw scores, `detail`\n * reasoning/evidence, and per-verdict cost without re-running judges. */\n verdicts: JudgeVerdict<D>[]\n}\n\n/**\n * Reduce per-judge verdicts to one aggregate. Generic over the rubric: pass the\n * stable-ordered `dimensionKeys` the judges scored.\n *\n * - Per-dimension score = mean over surviving judges (out-of-range clamped to [0,1]).\n * - `composite` = `weightedComposite` of `perDimension`. No `weights` ⇒ uniform\n * over every dimension. A partial `weights` map selects AND weights exactly the\n * named dimensions (others excluded from the composite) — the substrate's\n * sum-normalized weighting, not re-implemented here.\n * - Throws if `verdicts` or `dimensionKeys` is empty, or if every judge failed.\n */\nexport function aggregateJudgeVerdicts<D extends string>(\n verdicts: readonly JudgeVerdict<D>[],\n dimensionKeys: readonly D[],\n weights?: Partial<Record<D, number>>,\n): EnsembleAggregate<D> {\n if (verdicts.length === 0) {\n throw new Error('aggregateJudgeVerdicts: no verdicts to aggregate')\n }\n if (dimensionKeys.length === 0) {\n throw new Error('aggregateJudgeVerdicts: dimensionKeys is empty')\n }\n\n const perJudge: Record<string, Record<D, number>> = {}\n const failedJudges: string[] = []\n const dimAcc = {} as Record<D, number[]>\n for (const d of dimensionKeys) dimAcc[d] = []\n let rationale = ''\n let costUsd = 0\n\n // Same model sampled k times (best-of-N judging) gets keys 'm', 'm#2',\n // 'm#3'… so repeat votes land as distinct perJudge/failedJudges entries\n // instead of overwriting each other.\n const seenCount = new Map<string, number>()\n const keyFor = (model: string): string => {\n const n = (seenCount.get(model) ?? 0) + 1\n seenCount.set(model, n)\n return n === 1 ? model : `${model}#${n}`\n }\n\n for (const v of verdicts) {\n costUsd += v.costUsd ?? 0\n const key = keyFor(v.model)\n if (!v.perDimension) {\n failedJudges.push(key)\n continue\n }\n const dims = {} as Record<D, number>\n for (const d of dimensionKeys) dims[d] = clamp01(Number(v.perDimension[d]))\n perJudge[key] = dims\n for (const d of dimensionKeys) dimAcc[d].push(dims[d])\n if (!rationale && typeof v.rationale === 'string' && v.rationale) rationale = v.rationale\n }\n\n if (failedJudges.length === verdicts.length) {\n throw new Error(`aggregateJudgeVerdicts: all ${verdicts.length} judges failed`)\n }\n\n const perDimension = {} as Record<D, number>\n for (const d of dimensionKeys) {\n const vals = dimAcc[d]\n perDimension[d] = vals.length === 0 ? 0 : vals.reduce((s, x) => s + x, 0) / vals.length\n }\n\n let maxDisagreement = 0\n for (const d of dimensionKeys) {\n const vals = dimAcc[d]\n if (vals.length < 2) continue\n const spread = Math.max(...vals) - Math.min(...vals)\n if (spread > maxDisagreement) maxDisagreement = spread\n }\n\n const w: Record<string, number> = {}\n if (weights) {\n for (const [d, weight] of Object.entries(weights)) {\n if (weight !== undefined) w[d] = weight as number\n }\n } else {\n for (const d of dimensionKeys) w[d] = 1 / dimensionKeys.length\n }\n const composite = weightedComposite({ dims: perDimension, weights: w }).composite\n\n return {\n perDimension,\n composite,\n perJudge,\n maxDisagreement,\n failedJudges,\n costUsd,\n rationale: rationale || 'llm-judge',\n verdicts: [...verdicts],\n }\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 300_000. */\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 = 300_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 * Multi-model judge panel — `ensembleJudge` builds a campaign `JudgeConfig`\n * that fans one artifact out to K judge models and reduces their verdicts\n * through `aggregateJudgeVerdicts` (src/judge-ensemble.ts).\n *\n * The panel is the fail-loud composition of the substrate's existing judge\n * primitives:\n * - `assertCrossFamily` (construction-time) — a single-family panel is\n * correlated bias, not independent signal.\n * - `withJudgeRetry` (per model, opt-in) — transient-fault retry with a\n * typed outcome; a judge that exhausts retries is recorded as failed,\n * never folded into a zero.\n * - `aggregateJudgeVerdicts` — the pure reducer; throws when EVERY judge\n * failed so a silent zero can't reach the gate.\n *\n * The returned `JudgeScore` is on the campaign [0,1] scale and carries the\n * ensemble extras (`maxDisagreement`, `failedJudges`, `perJudge`) declared\n * on the canonical `JudgeScore` in src/campaign/types.ts.\n */\n\nimport type { JudgeConfig, JudgeScore } from './campaign/types'\nimport { aggregateJudgeVerdicts, type JudgeVerdict } from './judge-ensemble'\nimport { assertCrossFamily } from './judge-families'\nimport { type JudgeRetryPolicy, withJudgeRetry } from './judge-retry'\n\nexport interface EnsembleJudgeOptions<D extends string> {\n /** Judge name — becomes the returned `JudgeConfig.name`. */\n name: string\n /** Rubric dimensions every model scores. Keys of the verdict's `perDimension`. */\n dimensions: D[]\n /** Judge model ids — one `scoreWith` call per entry. List a model twice to\n * sample it twice (votes are suffix-keyed `model#2` so none overwrite). */\n models: string[]\n /**\n * Score the artifact with one model. Throw (or reject) on failure — the\n * panel records that model as a failed judge; it is never folded into a\n * zero. Verdict scores are clamped to [0,1] by the reducer.\n */\n scoreWith: (\n model: string,\n input: { artifact: unknown; scenario?: unknown },\n ) => Promise<JudgeVerdict<D>>\n /**\n * Per-model retry policy, applied via `withJudgeRetry`. The panel's\n * `models` list drives the fan-out, so `retry.models` (the fallback\n * rotation) is overridden to each panel model in turn.\n */\n retry?: JudgeRetryPolicy\n /** Enforce `assertCrossFamily` over `models` at construction. Default true.\n * Opt out only for deliberate single-family panels (e.g. self-consistency\n * sampling of one model). */\n crossFamily?: boolean\n /** Composite weights forwarded to `aggregateJudgeVerdicts`: a partial map\n * selects AND weights exactly the named dimensions. Omit for uniform. */\n weights?: Partial<Record<D, number>>\n}\n\n/**\n * Build a campaign-shaped `JudgeConfig` whose `score()` runs every panel\n * model in parallel and reduces the surviving verdicts to one canonical\n * `JudgeScore` in [0,1].\n *\n * Failure semantics: a model whose `scoreWith` throws (or exhausts `retry`)\n * lands in `failedJudges` and is excluded from the means. When EVERY model\n * fails, `aggregateJudgeVerdicts` throws — the campaign engine records a\n * failed cell instead of averaging a fabricated zero.\n */\nexport function ensembleJudge<D extends string>(\n opts: EnsembleJudgeOptions<D>,\n): JudgeConfig<unknown> {\n if (opts.models.length === 0) {\n throw new Error(`ensembleJudge '${opts.name}': models is empty — nothing to score with`)\n }\n if (opts.dimensions.length === 0) {\n throw new Error(`ensembleJudge '${opts.name}': dimensions is empty — nothing to score`)\n }\n if (opts.crossFamily !== false) {\n assertCrossFamily(opts.models)\n }\n\n const scoreOne = async (\n model: string,\n input: { artifact: unknown; scenario?: unknown },\n ): Promise<JudgeVerdict<D>> => {\n if (opts.retry) {\n const outcome = await withJudgeRetry((m) => opts.scoreWith(m, input), {\n ...opts.retry,\n models: [model],\n })\n if (!outcome.succeeded || outcome.value === null) {\n return {\n model,\n perDimension: null,\n rationale: outcome.error?.message ?? 'judge failed after retries',\n }\n }\n return outcome.value\n }\n try {\n return await opts.scoreWith(model, input)\n } catch (err) {\n return {\n model,\n perDimension: null,\n rationale: err instanceof Error ? err.message : String(err),\n }\n }\n }\n\n return {\n name: opts.name,\n dimensions: opts.dimensions.map((d) => ({ key: d, description: d })),\n async score({ artifact, scenario }): Promise<JudgeScore> {\n const input = { artifact, scenario }\n const verdicts = await Promise.all(opts.models.map((model) => scoreOne(model, input)))\n // All-failed throws here — propagate so the engine records a failed cell.\n const agg = aggregateJudgeVerdicts(verdicts, opts.dimensions, opts.weights)\n const score: JudgeScore = {\n dimensions: agg.perDimension,\n composite: agg.composite,\n notes: agg.rationale,\n maxDisagreement: agg.maxDisagreement,\n perJudge: agg.perJudge,\n }\n if (agg.failedJudges.length > 0) score.failedJudges = agg.failedJudges\n return score\n },\n }\n}\n","import { cpus } from 'node:os'\nimport {\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 * Max concurrent judge subprocesses. Each spec spawns its own subprocess\n * via the driver, so unbounded fan-out exhausts file descriptors / PIDs.\n * Defaults to the host CPU count. Ignored when `parallel === false`.\n */\n concurrency?: number\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 const concurrency = Math.max(1, options.concurrency ?? cpus().length)\n const results: SandboxJudgeResult[] = new Array(specs.length)\n let cursor = 0\n async function worker(): Promise<void> {\n while (true) {\n const i = cursor++\n if (i >= specs.length) return\n results[i] = await runner.run(specs[i]!)\n }\n }\n await Promise.all(Array.from({ length: Math.min(concurrency, specs.length) }, () => worker()))\n return results\n}\n\n/** Build a `SandboxJudgeSpec` that scores whether the harness compiles without errors. */\nexport function compilerJudge(id: string, config: HarnessConfig): SandboxJudgeSpec {\n return { id, kind: 'compiler', config }\n}\n\n/** Build a `SandboxJudgeSpec` that scores the harness by its test-suite pass rate. */\nexport function testJudge(id: string, config: HarnessConfig): SandboxJudgeSpec {\n return { id, kind: 'test', config }\n}\n\n/** Build a `SandboxJudgeSpec` that scores the harness by linter rule violations. */\nexport function linterJudge(id: string, config: HarnessConfig): SandboxJudgeSpec {\n return { id, kind: 'linter', config }\n}\n\n/** Build a `SandboxJudgeSpec` that scores the harness output for security issues via a security scanner. */\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 * 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 roles = Object.entries(bundle.rolePrompts ?? {}).sort(([a], [b]) => a.localeCompare(b))\n for (const [name, role] of roles) {\n lines.push(`role:${name}:system:${role.system ?? ''}:append:${role.append ?? ''}`)\n }\n const skills = [...(bundle.skills ?? [])].sort()\n if (skills.length) lines.push(`skills:${skills.join(',')}`)\n return lines.join('\\n')\n}\n","import { type AxAIService, AxGEPA, ai, ax } from '@ax-llm/ax'\nimport { 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 /** Runnable handle on the trained classifier. Present only when the\n * ax-gepa backend completed training; calls the optimized selector\n * program via ax's `forward`. */\n selectVariant?: (row: {\n task: string\n split: string\n seedPreview: string\n }) => Promise<{ variantId: string; rationale: string }>\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 minScenarioWinners?: number\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 minScenarioWinners = this.config.minScenarioWinners ?? 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 < minScenarioWinners) {\n return {\n ...fallback,\n backend: 'ax-gepa',\n skipped: true,\n rationale: `AxGEPA skipped: need >=2 variants and >=${minScenarioWinners} scenario winners, got ${variantIds.length} variant(s) and ${byScenario.length} scenario winner(s).`,\n }\n }\n\n const signature = `task:string, split:string, seedPreview:string -> variantId:class \"${variantIds.join(', ')}\", rationale:string`\n const selector = ax<\n { task: string; split: string; seedPreview: string },\n { variantId: string; rationale?: string }\n >(signature, {\n description: 'Choose the best steering bundle variant for an autopilot task.',\n })\n const shuffled = seededShuffle(byScenario, signature)\n const splitIndex = Math.max(1, Math.floor(shuffled.length * 0.8))\n const train = shuffled.slice(0, splitIndex)\n const validation = shuffled.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 studentAI = createAxService(this.config.provider, this.config.apiKey, this.config.model)\n const optimizer = new AxGEPA({\n studentAI,\n teacherAI: createAxService(\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 (input: { prediction?: { variantId?: string }; example?: ScenarioWinner }) =>\n input.prediction?.variantId === input.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 // After applyOptimization the `selector` program carries the trained\n // weights; the closure runs it through ax's `forward` so the caller can\n // classify unseen tasks rather than only read a description string.\n const selectVariant = async (row: { task: string; split: string; seedPreview: string }) => {\n const prediction = await selector.forward(studentAI, row)\n return {\n variantId: String(prediction.variantId),\n rationale: String(prediction.rationale ?? ''),\n }\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 selectVariant,\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 provider: 'openai' | 'anthropic',\n apiKey: string,\n model: string,\n): AxAIService {\n return ai({\n name: provider,\n apiKey,\n config: { model },\n })\n}\n\n// Deterministic Fisher-Yates driven by a seeded mulberry32 PRNG. Seeding from\n// a stable value (the signature) keeps train/validation splits reproducible\n// across runs while removing positional skew when rows arrive grouped.\nfunction seededShuffle<T>(items: readonly T[], seed: string): T[] {\n const rng = mulberry32(hashString(seed))\n const out = [...items]\n for (let i = out.length - 1; i > 0; i--) {\n const j = Math.floor(rng() * (i + 1))\n ;[out[i], out[j]] = [out[j]!, out[i]!]\n }\n return out\n}\n\nfunction hashString(value: string): number {\n let h = 2166136261\n for (let i = 0; i < value.length; i++) {\n h ^= value.charCodeAt(i)\n h = Math.imul(h, 16777619)\n }\n return h >>> 0\n}\n\nfunction mulberry32(seed: number): () => number {\n let a = seed >>> 0\n return () => {\n a = (a + 0x6d2b79f5) | 0\n let t = Math.imul(a ^ (a >>> 15), 1 | a)\n t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296\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 * Hidden-criteria grading firewall — grade an agent on criteria it never saw.\n *\n * A trustworthy benchmark splits every scenario's data by WHERE each field is\n * allowed to flow, then proves the held-out / judge-only fields never reach the\n * agent during the run. The coding bench expresses this with four destinations\n * (prompt / develop-against / held-out suite / rubric); this module lifts the\n * domain-FREE core out of it so research, legal, tax, content — any domain —\n * can declare the same routing and get the same firewall enforcement and the\n * same held-out-weighted composite, plugging in its OWN grader.\n *\n * Two reusable pieces, both domain-agnostic:\n *\n * 1. FIELD ROUTING BY DESTINATION. A scenario declares each field's\n * `FieldDestination`; `assertNoHiddenLeak` is a pure checker that throws if\n * a grading-only or judge-only field's value appears in what reaches the\n * agent. The domain decides which fields exist and where they go — the\n * substrate only enforces \"hidden stays hidden\".\n *\n * 2. HIDDEN-CRITERIA GRADING. The domain supplies its own grader\n * `(artifact, hiddenCriteria) => { passRate, total }` — the coding\n * node-test executor is ONE such grader a consumer plugs in; the substrate\n * bakes in NO node/test/TS/exec/regex. `gradeOnHidden` runs that grader\n * behind the firewall and `blendHeldout` composes its pass rate with a\n * judge score into the final number the leaderboard ranks on.\n *\n * Shape mirrors `treatment-gate`/`authenticity`: pure predicates and pure\n * composition over already-computed values, fail-loud, with the\n * \"which field / which weight / which grader\" decisions left as parameters and\n * no domain literal anywhere in the module.\n *\n * Lives next to `test-graded-scenario` and `partition-held-out` — it is a\n * scorecard/grading concept that makes sense without a running agent loop.\n */\n\nimport type { JudgeScore } from './campaign/types'\nimport { ValidationError } from './errors'\n\n// ── 1. field routing by destination ──────────────────────────────────────────\n\n/**\n * Where one scenario field is allowed to flow. The firewall guarantee is keyed\n * on this tag, not on a field name — a domain can have any number of fields per\n * destination.\n *\n * - `agent-visible` reaches the agent's context during the run (the prompt,\n * the task statement — what the agent reads to act).\n * - `develop-against` seeded into the agent's environment during the run so it\n * can iterate (a visible example/test/reference). The\n * agent MAY read it — that is intentional (real TDD). Not\n * a leak: it is example-grade, not the grading criteria.\n * - `grading-only` the hidden criteria. Used ONLY at grading, after the run\n * — the held-out suite / answer key / hidden requirements.\n * Must NEVER reach the agent context. This is what makes a\n * good score un-memorizable.\n * - `judge-only` grading context for the judge only (rubric anchors,\n * design intent). Lives with the judge, never in the agent\n * context.\n */\nexport type FieldDestination = 'agent-visible' | 'develop-against' | 'grading-only' | 'judge-only'\n\n/** The destinations a value must be kept OUT of the agent context for. */\nconst hiddenDestinations: ReadonlySet<FieldDestination> = new Set<FieldDestination>([\n 'grading-only',\n 'judge-only',\n])\n\n/** True for the destinations whose values must never reach the agent context. */\nexport function isHiddenDestination(destination: FieldDestination): boolean {\n return hiddenDestinations.has(destination)\n}\n\n/**\n * A scenario's fields routed by destination. The domain owns the field set\n * (`TFields` — a record of its named fields to their string-renderable values)\n * and declares one `FieldDestination` per field. `routeFields` builds this from\n * a domain's `(value, destination)` map; the firewall reads it.\n */\nexport interface RoutedField {\n /** The field's name — for diagnostics only. */\n name: string\n /** The field's value as it would be rendered into text. The firewall compares\n * this against the agent context, so a domain that ships structured data\n * passes a stable string projection (e.g. JSON) of the hidden value. */\n value: string\n destination: FieldDestination\n}\n\n/**\n * Route a domain's named fields by destination into the firewall's input shape.\n * The `routing` declares each field's destination; the `values` carry each\n * field's renderable string. A field present in `routing` but missing from\n * `values` is an authoring error (fail loud) — every routed field must have a\n * value the firewall can check.\n */\nexport function routeFields<TName extends string>(\n routing: Readonly<Record<TName, FieldDestination>>,\n values: Readonly<Record<TName, string>>,\n): RoutedField[] {\n const out: RoutedField[] = []\n for (const name of Object.keys(routing) as TName[]) {\n const value = values[name]\n if (value === undefined) {\n throw new ValidationError(\n `routed field \"${name}\" has a destination but no value — every routed field must carry its value`,\n )\n }\n out.push({ name, value, destination: routing[name] })\n }\n return out\n}\n\n/** A single detected leak: a hidden field whose value appears in the agent context. */\nexport interface HiddenLeak {\n field: string\n destination: FieldDestination\n}\n\nexport interface NoLeakOptions {\n /** Minimum hidden-value length to check. A hidden value shorter than this is\n * skipped — a one-word or empty hidden field would substring-match innocuous\n * prose and is not meaningful evidence of a leak. Default 12. */\n minMatchLength?: number\n}\n\n/**\n * The FIREWALL. Throws `ValidationError` if any `grading-only`/`judge-only`\n * field's value is found inside `agentContext` — the exact text that reaches the\n * agent during the run (its prompt, its seeded files concatenated, whatever the\n * caller assembled). `agent-visible` and `develop-against` fields are never\n * checked: they are meant to be there.\n *\n * Substring containment is the check: it is domain-free and catches the failure\n * that matters — a hidden answer key, held-out case, or rubric anchor pasted\n * into the prompt. Returns the routed fields on success so a caller can chain.\n */\nexport function assertNoHiddenLeak(\n fields: readonly RoutedField[],\n agentContext: string,\n opts: NoLeakOptions = {},\n): readonly RoutedField[] {\n const minLen = opts.minMatchLength ?? 12\n const leaks: HiddenLeak[] = []\n for (const field of fields) {\n if (!isHiddenDestination(field.destination)) continue\n const needle = field.value.trim()\n if (needle.length < minLen) continue\n if (agentContext.includes(needle)) {\n leaks.push({ field: field.name, destination: field.destination })\n }\n }\n if (leaks.length > 0) {\n const detail = leaks.map((l) => `\"${l.field}\" (${l.destination})`).join(', ')\n throw new ValidationError(\n `hidden-criteria firewall breached: ${leaks.length} hidden field(s) reached the agent context: ${detail}`,\n )\n }\n return fields\n}\n\n/** Collect the values a domain may safely render into the agent context — the\n * `agent-visible` (and, by intent, `develop-against`) fields — so a caller can\n * ASSEMBLE the context from the routing rather than hand-picking fields and\n * risking a slip. `develop-against` is included because it is seeded into the\n * agent's environment during the run on purpose. */\nexport function agentVisibleFields(fields: readonly RoutedField[]): RoutedField[] {\n return fields.filter((f) => !isHiddenDestination(f.destination))\n}\n\n// ── 2. hidden-criteria grading ────────────────────────────────────────────────\n\n/** What a hidden-criteria grader reports. `passRate = passed / total` over the\n * hidden checks; `total === 0` means the criteria never ran (e.g. the artifact\n * did not even load) — an honest zero, never a spurious pass. */\nexport interface HiddenGradeResult {\n /** Hidden checks that passed. */\n passed: number\n /** Total hidden checks attempted. 0 when the criteria could not run at all. */\n total: number\n /** `passed / total`, or 0 when `total === 0`. The PRIMARY correctness score. */\n passRate: number\n /** Free-form provenance the caller may record (runner output, reason for 0). */\n notes?: string\n}\n\n/**\n * The domain's grader: given the agent's artifact and the HIDDEN criteria,\n * return a pass rate. This is the ONE seam a non-coding domain implements — the\n * coding node-test executor is a single implementation of it; a legal grader\n * checks the brief against hidden required holdings, a research grader checks an\n * answer against held-out facts, a tax grader runs hidden return assertions.\n * The substrate calls it ONLY at grading time, behind the firewall.\n *\n * `THidden` is the domain's hidden-criteria payload (the held-out suite, the\n * answer key, the hidden requirements) — opaque to the substrate.\n */\nexport type HiddenCriteriaGrader<TArtifact, THidden> = (\n artifact: TArtifact,\n hiddenCriteria: THidden,\n signal?: AbortSignal,\n) => Promise<HiddenGradeResult> | HiddenGradeResult\n\n/** Normalize a grader's raw `{passed, total}` into a `HiddenGradeResult` with a\n * consistent, fail-loud `passRate` — the canonical \"honest zero on no-run\"\n * rule, single-sourced so every domain grader gets it. */\nexport function hiddenGrade(passed: number, total: number, notes?: string): HiddenGradeResult {\n const p = Number.isFinite(passed) && passed > 0 ? Math.floor(passed) : 0\n const t = Number.isFinite(total) && total > 0 ? Math.floor(total) : 0\n const passRate = t > 0 ? Math.min(1, p / t) : 0\n return { passed: Math.min(p, t > 0 ? t : p), total: t, passRate, notes }\n}\n\n/**\n * Run a domain's hidden-criteria grader behind the firewall. Before grading, it\n * re-asserts the firewall against the agent context the run actually used —\n * proving (at grading time, on real data) that the hidden criteria never\n * reached the agent — then invokes the grader and returns its pass rate. A\n * domain that wants the firewall and the grader wired together in one call uses\n * this; a domain that already asserted the firewall at dispatch time can call\n * its grader directly and feed the result to `blendHeldout`.\n */\nexport async function gradeOnHidden<TArtifact, THidden>(args: {\n artifact: TArtifact\n hiddenCriteria: THidden\n grader: HiddenCriteriaGrader<TArtifact, THidden>\n /** The routed fields + the exact agent context, re-checked before grading. */\n firewall: { fields: readonly RoutedField[]; agentContext: string; options?: NoLeakOptions }\n signal?: AbortSignal\n}): Promise<HiddenGradeResult> {\n assertNoHiddenLeak(args.firewall.fields, args.firewall.agentContext, args.firewall.options)\n const result = await args.grader(args.artifact, args.hiddenCriteria, args.signal)\n return hiddenGrade(result.passed, result.total, result.notes)\n}\n\n// ── the composite: hidden correctness (PRIMARY) + judge quality (secondary) ────\n\n/** Weights for the held-out / judge blend. Must be finite and non-negative;\n * they are renormalized to sum to 1 so a caller can pass any positive ratio. */\nexport interface BlendWeights {\n /** Weight on the hidden-criteria pass rate (the primary, ungameable score). */\n heldout: number\n /** Weight on the judge's quality composite (the secondary style/quality score). */\n judge: number\n}\n\n/** Default blend: 0.7 hidden correctness, 0.3 judge quality. The coding bench's\n * long-standing split — execution truth dominates, style refines. */\nexport const defaultBlendWeights: BlendWeights = { heldout: 0.7, judge: 0.3 }\n\n/** The input shape a judge's `score` receives — exactly `JudgeConfig.score`'s\n * argument: the artifact, plus any scenario/signal fields the judge carries.\n * `withHeldoutBlend` only reads `artifact`; the rest rides through. */\nexport interface JudgeScoreInput<TArtifact> {\n artifact: TArtifact\n /** Pass-through for the judge's extra input fields (scenario, signal). */\n [key: string]: unknown\n}\n\nfunction normalizeWeights(weights: BlendWeights): { heldout: number; judge: number } {\n const h = Number.isFinite(weights.heldout) && weights.heldout >= 0 ? weights.heldout : 0\n const j = Number.isFinite(weights.judge) && weights.judge >= 0 ? weights.judge : 0\n const sum = h + j\n if (sum <= 0) {\n throw new ValidationError(\n 'blend weights must have a positive sum (got heldout+judge <= 0) — cannot weight a composite by zero',\n )\n }\n return { heldout: h / sum, judge: j / sum }\n}\n\n/**\n * Compose the PRIMARY hidden-criteria pass rate with the SECONDARY judge\n * composite into the single score the leaderboard ranks on. Weights are\n * renormalized, so a solution that fails the hidden criteria is capped low no\n * matter how the judge felt about its style, while a stylistically-mediocre but\n * CORRECT solution still earns the bulk of the points. Both inputs are clamped\n * to [0,1] — a judge on a non-unit scale must be normalized by the caller first.\n */\nexport function blendHeldout(\n heldoutPassRate: number,\n judgeScore: number,\n weights: BlendWeights = defaultBlendWeights,\n): number {\n const w = normalizeWeights(weights)\n const heldout = clampUnit(heldoutPassRate)\n const judge = clampUnit(judgeScore)\n return w.heldout * heldout + w.judge * judge\n}\n\n/**\n * Wrap a judge's `score` so the `composite` it REPORTS is the held-out-weighted\n * blend. The judge still scores its quality dimensions (recorded, secondary),\n * but the composite that downstream selection/scorecard reads becomes\n * `blendHeldout(heldoutPassRate(artifact), judgeComposite, weights)`. The held-\n * out pass rate is read off the artifact via `heldoutPassRate` — already\n * computed before the judge runs — so no second grading pass is needed.\n *\n * Generic over the artifact type, inferred from `heldoutPassRate`, so it\n * composes with both a `campaign` `JudgeConfig.score` and a bare scoring\n * function. The input is the judge's `{ artifact, ... }` — any extra fields\n * (`scenario`, `signal`) ride through untouched via the index signature.\n */\nexport function withHeldoutBlend<TArtifact>(\n score: (input: JudgeScoreInput<TArtifact>) => JudgeScore | Promise<JudgeScore>,\n heldoutPassRate: (artifact: TArtifact) => number,\n weights: BlendWeights = defaultBlendWeights,\n): (input: JudgeScoreInput<TArtifact>) => Promise<JudgeScore> {\n return async (input: JudgeScoreInput<TArtifact>): Promise<JudgeScore> => {\n const base = await score(input)\n if (base.failed) return base\n const rate = clampUnit(heldoutPassRate(input.artifact))\n const composite = blendHeldout(rate, base.composite, weights)\n const w = normalizeWeights(weights)\n return {\n ...base,\n composite,\n notes:\n `composite=${composite.toFixed(3)} ` +\n `(held-out ${(rate * 100).toFixed(0)}% × ${w.heldout.toFixed(2)} + ` +\n `quality ${base.composite.toFixed(3)} × ${w.judge.toFixed(2)})` +\n (base.notes ? ` — ${base.notes}` : ''),\n }\n }\n}\n\nfunction clampUnit(value: number): number {\n if (!Number.isFinite(value)) return 0\n return Math.max(0, Math.min(1, value))\n}\n","/**\n * CostLedger — per-run token + USD accounting with an explicit `costUnknown`\n * axis, folded over the substrate's pricing resolver.\n *\n * `estimateCost` already resolves a model id to a price (exact table, then\n * family regex) and warns-once on a miss, but it returns 0 for an unpriced\n * model — indistinguishable downstream from a genuinely free run. Four\n * consumers re-wrap it to surface that distinction (physim's `costForUsage` /\n * `modelPriceKey` is the cleanest), and to bucket spend by \"channel\" (the\n * logical role of the call: agent / judge / verifier / …) so a dashboard can\n * answer \"how much did judging cost vs the agent itself?\".\n *\n * This is the canonical version. `modelPriceKey` exposes the resolver's verdict\n * as a stable key (or null). `CostLedger` folds usage records into per-channel\n * and total rollups, tracks `unpricedModels` so a $0 is never mistaken for a\n * measured zero, and computes cost-per-completed-task.\n */\n\nimport { ValidationError } from './errors'\nimport { estimateCost, isModelPriced, resolveModelPricing } from './metrics'\n\n/** Logical role of an LLM call. Free-form union — consumers add their own\n * channels; the rollup keys on whatever string is supplied. */\nexport type CostChannel = 'agent' | 'judge' | 'verifier' | 'analyst' | 'driver' | (string & {})\n\nexport interface CostUsage {\n inputTokens: number\n outputTokens: number\n cachedTokens?: number\n}\n\n/**\n * Resolve a model id to the stable pricing key the substrate's `MODEL_PRICING`\n * / family resolver would use, or null when the id is unpriced. A non-null\n * return means `estimateCost` will produce a real number for this id; null\n * means any cost computed is `costUnknown` and the 0 must not aggregate as a\n * measured cost.\n */\nexport function modelPriceKey(model: string): string | null {\n return isModelPriced(model) ? model : null\n}\n\nexport interface CostResult {\n costUsd: number\n /** True when `model` has no pricing — the 0 is \"not priced\", NOT \"free\". */\n costUnknown: boolean\n}\n\n/**\n * Cost for one usage record. Resolves pricing via the substrate resolver and\n * flags `costUnknown` when the model is unpriced so the 0 is observable rather\n * than silently emitted as a measured cost. Cached tokens are billed at the\n * model's input rate when present (no separate cache-discount table — callers\n * that need provider-specific cache pricing supply `actualCostUsd` upstream).\n */\nexport function costForUsage(model: string, usage: CostUsage): CostResult {\n assertNonNegative(usage.inputTokens, 'inputTokens')\n assertNonNegative(usage.outputTokens, 'outputTokens')\n if (usage.cachedTokens !== undefined) assertNonNegative(usage.cachedTokens, 'cachedTokens')\n const pricing = resolveModelPricing(model)\n if (!pricing) return { costUsd: 0, costUnknown: true }\n const billedInput = usage.inputTokens + (usage.cachedTokens ?? 0)\n return { costUsd: estimateCost(billedInput, usage.outputTokens, model), costUnknown: false }\n}\n\nexport interface CostLedgerEntry extends CostUsage {\n model: string\n channel: CostChannel\n costUsd: number\n costUnknown: boolean\n /** Override the estimate with an observed provider cost. */\n actualCostUsd?: number\n /** Free-form tags (scenario id, variant id, round, …). */\n tags?: Record<string, string>\n timestamp: number\n}\n\nexport interface ChannelRollup {\n channel: CostChannel\n calls: number\n inputTokens: number\n outputTokens: number\n cachedTokens: number\n costUsd: number\n /** Calls whose model was unpriced (their costUsd is 0-but-unknown). */\n unpricedCalls: number\n}\n\nexport interface CostLedgerSummary {\n totalCalls: number\n inputTokens: number\n outputTokens: number\n cachedTokens: number\n totalCostUsd: number\n /** Per-channel breakdown, sorted by channel name. */\n byChannel: ChannelRollup[]\n /** Distinct unpriced model ids seen — non-empty means totalCostUsd is a\n * lower bound (some calls priced to an unknown 0). */\n unpricedModels: string[]\n /** True when no unpriced model was charged — totalCostUsd is then exact. */\n fullyPriced: boolean\n}\n\n/**\n * Append-only ledger of LLM spend for a single run. Record each call with its\n * channel; read per-channel and total rollups plus the unpriced-model set.\n * Pure accounting — no I/O. The `markCompleted` / `costPerCompletedTask` pair\n * answers \"dollars per finished task\", the metric every optimizer's\n * quality-vs-cost tradeoff needs.\n */\nexport class CostLedger {\n private readonly entries: CostLedgerEntry[] = []\n private completedTasks = 0\n\n /**\n * Record one LLM call. The cost is computed from pricing unless\n * `actualCostUsd` is supplied (a finite observed cost from the provider\n * response), in which case `costUnknown` is false regardless of pricing.\n */\n record(input: {\n model: string\n channel: CostChannel\n usage: CostUsage\n actualCostUsd?: number\n tags?: Record<string, string>\n timestamp?: number\n }): CostLedgerEntry {\n const { costUsd, costUnknown } = costForUsage(input.model, input.usage)\n const hasActual =\n typeof input.actualCostUsd === 'number' && Number.isFinite(input.actualCostUsd)\n if (hasActual) assertNonNegative(input.actualCostUsd as number, 'actualCostUsd')\n const entry: CostLedgerEntry = {\n model: input.model,\n channel: input.channel,\n inputTokens: input.usage.inputTokens,\n outputTokens: input.usage.outputTokens,\n cachedTokens: input.usage.cachedTokens,\n costUsd: hasActual ? (input.actualCostUsd as number) : costUsd,\n costUnknown: hasActual ? false : costUnknown,\n actualCostUsd: hasActual ? (input.actualCostUsd as number) : undefined,\n tags: input.tags,\n timestamp: input.timestamp ?? Date.now(),\n }\n this.entries.push(entry)\n return entry\n }\n\n /** Increment the completed-task counter (used for cost-per-completed-task). */\n markCompleted(count = 1): void {\n if (!Number.isInteger(count) || count < 0) {\n throw new ValidationError(\n `CostLedger.markCompleted: count must be a non-negative integer, got ${count}`,\n )\n }\n this.completedTasks += count\n }\n\n list(): CostLedgerEntry[] {\n return [...this.entries]\n }\n\n summary(): CostLedgerSummary {\n const byChannel = new Map<string, ChannelRollup>()\n const unpriced = new Set<string>()\n let totalCost = 0\n let inputTokens = 0\n let outputTokens = 0\n let cachedTokens = 0\n for (const e of this.entries) {\n totalCost += e.costUsd\n inputTokens += e.inputTokens\n outputTokens += e.outputTokens\n cachedTokens += e.cachedTokens ?? 0\n if (e.costUnknown) unpriced.add(e.model)\n const roll = byChannel.get(e.channel) ?? {\n channel: e.channel,\n calls: 0,\n inputTokens: 0,\n outputTokens: 0,\n cachedTokens: 0,\n costUsd: 0,\n unpricedCalls: 0,\n }\n roll.calls += 1\n roll.inputTokens += e.inputTokens\n roll.outputTokens += e.outputTokens\n roll.cachedTokens += e.cachedTokens ?? 0\n roll.costUsd += e.costUsd\n if (e.costUnknown) roll.unpricedCalls += 1\n byChannel.set(e.channel, roll)\n }\n return {\n totalCalls: this.entries.length,\n inputTokens,\n outputTokens,\n cachedTokens,\n totalCostUsd: totalCost,\n byChannel: [...byChannel.values()].sort((a, b) => a.channel.localeCompare(b.channel)),\n unpricedModels: [...unpriced].sort(),\n fullyPriced: unpriced.size === 0,\n }\n }\n\n /** Total spend divided by completed tasks; null when nothing completed. */\n costPerCompletedTask(): number | null {\n if (this.completedTasks === 0) return null\n return this.summary().totalCostUsd / this.completedTasks\n }\n}\n\nfunction assertNonNegative(n: number, name: string): void {\n if (!Number.isFinite(n) || n < 0) {\n throw new ValidationError(`CostLedger: ${name} must be a non-negative finite number, got ${n}`)\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 * EvalTraceStore — JSONL save / query / compare over the analysis-time\n * `RunRecord` row.\n *\n * `FileSystemTraceStore` (in `./trace/store`) persists the rich TraceSchema-v1\n * span corpus — runs, spans, events, artifacts — the runtime emits live. That\n * is NOT the thing three consumers hand-roll in `tests/eval/lib/trace-store.ts`.\n * What they hand-roll is the *analysis* layer: append each finished run as one\n * JSONL line keyed by scenario/candidate, then query it (\"every run where score\n * < 50\"), pick the best run for a scenario (few-shot seeding), and compare two\n * candidates on matched scenarios.\n *\n * The substrate already has the canonical analysis-time row — `RunRecord` — so\n * this is that query/compare API expressed over `RunRecord[]`, with a\n * JSONL-backed store. It does NOT fork `FileSystemTraceStore`; it sits beside it\n * for the analysis projection.\n */\n\nimport { ValidationError } from './errors'\nimport { isRunRecord, type RunRecord, type RunSplitTag, validateRunRecord } from './run-record'\n\n/** The score the query/compare layer ranks on: holdout when present (the\n * gated number), else search. Throws when a record carries neither — a\n * RunRecord is invalid without at least one, but a hand-built object might. */\nexport function runScore(record: RunRecord): number {\n const { holdoutScore, searchScore } = record.outcome\n if (typeof holdoutScore === 'number') return holdoutScore\n if (typeof searchScore === 'number') return searchScore\n throw new ValidationError(\n `EvalTraceStore: run ${record.runId} has neither holdoutScore nor searchScore`,\n )\n}\n\nexport interface RunRecordFilter {\n experimentId?: string\n candidateId?: string\n scenarioId?: string\n model?: string\n splitTag?: RunSplitTag\n /** Inclusive lower bound on `runScore`. */\n minScore?: number\n /** Inclusive upper bound on `runScore`. */\n maxScore?: number\n /** Match a single tag in `outcome.raw` by exact numeric value. */\n rawEquals?: { key: string; value: number }\n /** Custom predicate, ANDed with the structured filters. */\n where?: (record: RunRecord) => boolean\n}\n\nfunction matches(record: RunRecord, f: RunRecordFilter): boolean {\n if (f.experimentId && record.experimentId !== f.experimentId) return false\n if (f.candidateId && record.candidateId !== f.candidateId) return false\n if (f.scenarioId && record.scenarioId !== f.scenarioId) return false\n if (f.model && record.model !== f.model) return false\n if (f.splitTag && record.splitTag !== f.splitTag) return false\n if (f.minScore !== undefined && runScore(record) < f.minScore) return false\n if (f.maxScore !== undefined && runScore(record) > f.maxScore) return false\n if (f.rawEquals && record.outcome.raw[f.rawEquals.key] !== f.rawEquals.value) return false\n if (f.where && !f.where(record)) return false\n return true\n}\n\nexport interface CandidateComparison {\n a: string\n b: string\n /** Scenario ids present for BOTH candidates — the paired comparison set. */\n pairedScenarioIds: string[]\n /** Mean `runScore` for candidate a over the paired scenarios. */\n meanA: number\n /** Mean `runScore` for candidate b over the paired scenarios. */\n meanB: number\n /** meanB − meanA. Positive ⇒ b scored higher on the matched scenarios. */\n meanDelta: number\n /** Scenarios where b beat a (strictly), tied, and a beat b. */\n bWins: number\n ties: number\n aWins: number\n}\n\n/**\n * Backing persistence for `EvalTraceStore`. The in-memory store is the default;\n * the JSONL file store appends one validated `RunRecord` per line. Both keep an\n * append order so `getBest` / `compareRuns` are reproducible.\n */\nexport interface RunRecordBackend {\n append(record: RunRecord): Promise<void>\n load(): Promise<RunRecord[]>\n}\n\nexport function inMemoryRunRecordBackend(initial: RunRecord[] = []): RunRecordBackend {\n const rows = initial.map((r) => validateRunRecord(r))\n return {\n async append(record) {\n rows.push(record)\n },\n async load() {\n return [...rows]\n },\n }\n}\n\n/**\n * JSONL-backed store at `path`, one `RunRecord` per line. Malformed lines fail\n * loud on load (a corrupt corpus must not silently shrink the analysis set);\n * pass `skipInvalid` only for forensics on a known-bad file.\n */\nexport function jsonlRunRecordBackend(\n path: string,\n opts: { skipInvalid?: boolean } = {},\n): RunRecordBackend {\n return {\n async append(record) {\n const fs = await import('node:fs/promises')\n const pathMod = await import('node:path')\n await fs.mkdir(pathMod.dirname(path), { recursive: true })\n await fs.appendFile(path, `${JSON.stringify(record)}\\n`, 'utf8')\n },\n async load() {\n const fs = await import('node:fs/promises')\n let raw: string\n try {\n raw = await fs.readFile(path, 'utf8')\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') return []\n throw err\n }\n const out: RunRecord[] = []\n let lineNo = 0\n for (const line of raw.split('\\n')) {\n lineNo++\n if (!line.trim()) continue\n let parsed: unknown\n try {\n parsed = JSON.parse(line)\n } catch (err) {\n if (opts.skipInvalid) continue\n throw new ValidationError(`EvalTraceStore: ${path}:${lineNo} is not valid JSON`)\n }\n if (opts.skipInvalid) {\n if (isRunRecord(parsed)) out.push(parsed)\n continue\n }\n try {\n out.push(validateRunRecord(parsed))\n } catch (err) {\n throw new ValidationError(\n `EvalTraceStore: ${path}:${lineNo} is not a valid RunRecord — ${(err as Error).message}`,\n )\n }\n }\n return out\n },\n }\n}\n\n/**\n * Query / compare layer over a `RunRecord` corpus. Append finished runs, query\n * with a structured filter, take the best run for a scenario, and compare two\n * candidates on their matched scenarios. Persistence is injected via\n * `RunRecordBackend` (in-memory by default, JSONL file via\n * `jsonlRunRecordBackend`).\n */\nexport class EvalTraceStore {\n private readonly backend: RunRecordBackend\n\n constructor(backend: RunRecordBackend = inMemoryRunRecordBackend()) {\n this.backend = backend\n }\n\n /** Validate and append one run. Throws on an invalid record — the corpus\n * stays paper-grade. */\n async append(record: RunRecord): Promise<void> {\n await this.backend.append(validateRunRecord(record))\n }\n\n async all(): Promise<RunRecord[]> {\n return this.backend.load()\n }\n\n async query(filter: RunRecordFilter = {}): Promise<RunRecord[]> {\n const rows = await this.backend.load()\n return rows.filter((r) => matches(r, filter))\n }\n\n /**\n * Highest-scoring run for a scenario (optionally restricted to a candidate).\n * Returns null when no run matches. Ties resolve to the earliest-appended run\n * so the result is stable.\n */\n async getBest(\n scenarioId: string,\n opts: { candidateId?: string; splitTag?: RunSplitTag } = {},\n ): Promise<RunRecord | null> {\n const rows = await this.query({\n scenarioId,\n candidateId: opts.candidateId,\n splitTag: opts.splitTag,\n })\n if (rows.length === 0) return null\n let best = rows[0]!\n let bestScore = runScore(best)\n for (let i = 1; i < rows.length; i++) {\n const s = runScore(rows[i]!)\n if (s > bestScore) {\n best = rows[i]!\n bestScore = s\n }\n }\n return best\n }\n\n /**\n * Compare two candidates on the scenarios they BOTH ran. When a candidate\n * ran a scenario more than once, its best `runScore` for that scenario is\n * used. Throws when there is no paired scenario — an unpaired \"comparison\" is\n * not one.\n */\n async compareRuns(candidateA: string, candidateB: string): Promise<CandidateComparison> {\n if (candidateA === candidateB) {\n throw new ValidationError(\n `EvalTraceStore.compareRuns: candidates must differ (\"${candidateA}\")`,\n )\n }\n const rows = await this.backend.load()\n const bestByScenario = (candidate: string): Map<string, number> => {\n const m = new Map<string, number>()\n for (const r of rows) {\n if (r.candidateId !== candidate) continue\n const sid = r.scenarioId\n if (!sid) continue\n const s = runScore(r)\n const prev = m.get(sid)\n if (prev === undefined || s > prev) m.set(sid, s)\n }\n return m\n }\n const aScores = bestByScenario(candidateA)\n const bScores = bestByScenario(candidateB)\n const paired = [...aScores.keys()].filter((sid) => bScores.has(sid)).sort()\n if (paired.length === 0) {\n throw new ValidationError(\n `EvalTraceStore.compareRuns: \"${candidateA}\" and \"${candidateB}\" share no scenario (need scenarioId on records)`,\n )\n }\n let sumA = 0\n let sumB = 0\n let bWins = 0\n let aWins = 0\n let ties = 0\n for (const sid of paired) {\n const sa = aScores.get(sid)!\n const sb = bScores.get(sid)!\n sumA += sa\n sumB += sb\n if (sb > sa) bWins++\n else if (sb < sa) aWins++\n else ties++\n }\n const meanA = sumA / paired.length\n const meanB = sumB / paired.length\n return {\n a: candidateA,\n b: candidateB,\n pairedScenarioIds: paired,\n meanA,\n meanB,\n meanDelta: meanB - meanA,\n bWins,\n ties,\n aWins,\n }\n }\n}\n","/**\n * Experiment tracker — git-provenanced experiment log with N-rep stats and a\n * KEEP / REGRESSION / NOISE verdict against a parent.\n *\n * Every loop the fleet runs reduces to the same question: \"I ran the candidate\n * N times — is the median measurably better than the parent, or is the delta\n * inside the noise band?\" The hand-rolled copies bake a fixed score scale\n * (percentage points), a fixed store path (`.evolve/experiments-v2.json`), and\n * `execSync('git …')` straight into the module. This is the canonical version:\n * provenance and persistence are injected, thresholds are configurable, and the\n * stats + verdict are pure functions you can unit-test without a git repo or a\n * filesystem.\n *\n * Stats per experiment: median / mean / min / max / iqr / stddev / passRate /\n * n, plus a `stable` flag (`iqr < iqrUnstableAbove && stddev < stddevUnstableAbove`).\n *\n * Verdict against a parent (both must have `n >= minRepsForVerdict`):\n * - NOISE — the candidate is too unstable to judge (`!stable`)\n * - KEEP — `medianDelta > keepThreshold`\n * - REGRESSION — `medianDelta < -regressionThreshold`\n * - NOISE — otherwise (delta inside the band)\n * With no parent (or insufficient reps) the verdict is the neutral ITERATE.\n */\n\nimport { execSync } from 'node:child_process'\nimport { iqr } from './baseline'\nimport { ValidationError } from './errors'\n\n/** Verdict for one experiment relative to its parent. ITERATE is the neutral\n * \"keep collecting reps / no parent to compare against\" state. */\nexport type ExperimentVerdict = 'KEEP' | 'ITERATE' | 'NOISE' | 'REGRESSION'\n\n/** Git provenance for the working tree an experiment was run from. */\nexport interface ExperimentProvenance {\n /** Commit sha (short or full — the tracker does not interpret it). */\n commit: string\n /** First line of the commit message. */\n message: string\n /** Files changed vs the parent commit, or a marker like 'uncommitted'. */\n changedFiles: string[]\n}\n\n/** A single repetition of an experiment, carrying the score the verdict is\n * computed on plus any free-form per-rep metrics the consumer wants kept. */\nexport interface ExperimentRep {\n /** 0-indexed repetition number within the experiment. */\n rep: number\n /** The score this rep is judged on (same scale as the thresholds). */\n score: number\n /** ISO timestamp the rep completed. */\n timestamp: string\n /** Whether this rep passed the consumer's own gate — folded into `passRate`. */\n passed?: boolean\n /** Free-form numeric metrics retained for later analysis. */\n metrics?: Record<string, number>\n}\n\nexport interface ExperimentStats {\n median: number\n mean: number\n min: number\n max: number\n /** Inter-quartile range of the rep scores. */\n iqr: number\n /** Population standard deviation of the rep scores. */\n stddev: number\n /** Fraction of reps with `passed === true`, over reps that set `passed`.\n * null when no rep declared a pass/fail outcome. */\n passRate: number | null\n /** Number of reps. */\n n: number\n /** True when the sample is tight enough to trust for a verdict. */\n stable: boolean\n}\n\nexport interface Experiment {\n /** Stable id for the experiment. */\n id: string\n /** Free-form label / config descriptor. */\n label: string\n /** Git provenance captured when the experiment was created. */\n provenance: ExperimentProvenance\n /** Parent experiment id this candidate is compared against, if any. */\n parentId?: string\n /** One-line summary of what changed from the parent. */\n changeSummary: string\n reps: ExperimentRep[]\n stats: ExperimentStats\n verdict: ExperimentVerdict\n /** ISO timestamp the experiment was created. */\n createdAt: string\n}\n\nexport interface ImprovementThresholds {\n /** medianDelta strictly above this ⇒ KEEP. Default 5. */\n keepThreshold?: number\n /** medianDelta strictly below the negative of this ⇒ REGRESSION. Default 5. */\n regressionThreshold?: number\n /** iqr at or above this ⇒ unstable. Default 10. */\n iqrUnstableAbove?: number\n /** stddev at or above this ⇒ unstable. Default Infinity (iqr-only stability). */\n stddevUnstableAbove?: number\n /** Reps required on BOTH candidate and parent before a verdict is rendered.\n * Default 3. */\n minRepsForVerdict?: number\n}\n\nexport interface ImprovementVerdictResult {\n verdict: ExperimentVerdict\n /** candidate.median − parent.median; null when no parent or insufficient reps. */\n medianDelta: number | null\n /** Human-readable reason for the verdict — for dashboards and logs. */\n reason: string\n}\n\nconst DEFAULTS: Required<ImprovementThresholds> = {\n keepThreshold: 5,\n regressionThreshold: 5,\n iqrUnstableAbove: 10,\n stddevUnstableAbove: Number.POSITIVE_INFINITY,\n minRepsForVerdict: 3,\n}\n\nfunction resolveThresholds(t: ImprovementThresholds | undefined): Required<ImprovementThresholds> {\n const r = { ...DEFAULTS, ...(t ?? {}) }\n if (r.keepThreshold < 0) {\n throw new ValidationError(\n `experiment-tracker: keepThreshold must be >= 0, got ${r.keepThreshold}`,\n )\n }\n if (r.regressionThreshold < 0) {\n throw new ValidationError(\n `experiment-tracker: regressionThreshold must be >= 0, got ${r.regressionThreshold}`,\n )\n }\n if (r.minRepsForVerdict < 1) {\n throw new ValidationError(\n `experiment-tracker: minRepsForVerdict must be >= 1, got ${r.minRepsForVerdict}`,\n )\n }\n return r\n}\n\nfunction median(sorted: number[]): number {\n const n = sorted.length\n if (n === 0) return 0\n const mid = Math.floor(n / 2)\n return n % 2 === 0 ? (sorted[mid - 1]! + sorted[mid]!) / 2 : sorted[mid]!\n}\n\n/** Population standard deviation (÷n). 0 for fewer than 2 values. */\nfunction stddev(values: number[], mean: number): number {\n if (values.length < 2) return 0\n const variance = values.reduce((acc, v) => acc + (v - mean) ** 2, 0) / values.length\n return Math.sqrt(variance)\n}\n\n/**\n * Compute the N-rep statistics for a set of reps. Pure — no I/O. The `stable`\n * flag is the trust gate the verdict depends on: a sample whose spread exceeds\n * the configured bounds can't distinguish a real delta from run-to-run noise.\n */\nexport function computeExperimentStats(\n reps: ExperimentRep[],\n thresholds?: ImprovementThresholds,\n): ExperimentStats {\n const t = resolveThresholds(thresholds)\n const n = reps.length\n if (n === 0) {\n return {\n median: 0,\n mean: 0,\n min: 0,\n max: 0,\n iqr: 0,\n stddev: 0,\n passRate: null,\n n: 0,\n stable: false,\n }\n }\n const scores = reps.map((r) => {\n if (!Number.isFinite(r.score)) {\n throw new ValidationError(`experiment-tracker: rep ${r.rep} has non-finite score ${r.score}`)\n }\n return r.score\n })\n const sorted = [...scores].sort((a, b) => a - b)\n const mean = scores.reduce((s, v) => s + v, 0) / n\n const sd = stddev(scores, mean)\n const spread = iqr(scores)\n const rated = reps.filter((r) => typeof r.passed === 'boolean')\n const passRate = rated.length === 0 ? null : rated.filter((r) => r.passed).length / rated.length\n const stable = spread < t.iqrUnstableAbove && sd < t.stddevUnstableAbove\n return {\n median: median(sorted),\n mean,\n min: sorted[0]!,\n max: sorted[n - 1]!,\n iqr: spread,\n stddev: sd,\n passRate,\n n,\n stable,\n }\n}\n\n/**\n * Verdict for a candidate against its parent. Pure — operates on already-computed\n * stats. KEEP/REGRESSION require both sides to have `>= minRepsForVerdict` reps\n * AND the candidate to be `stable`; otherwise the result is NOISE (unstable) or\n * ITERATE (not enough reps / no parent).\n */\nexport function improvementVerdict(\n candidate: ExperimentStats,\n parent: ExperimentStats | null,\n thresholds?: ImprovementThresholds,\n): ImprovementVerdictResult {\n const t = resolveThresholds(thresholds)\n if (!parent) {\n return {\n verdict: 'ITERATE',\n medianDelta: null,\n reason: 'no parent experiment to compare against',\n }\n }\n if (candidate.n < t.minRepsForVerdict || parent.n < t.minRepsForVerdict) {\n return {\n verdict: 'ITERATE',\n medianDelta: null,\n reason: `need >= ${t.minRepsForVerdict} reps on both sides (candidate n=${candidate.n}, parent n=${parent.n})`,\n }\n }\n if (!candidate.stable) {\n return {\n verdict: 'NOISE',\n medianDelta: candidate.median - parent.median,\n reason: `candidate unstable (iqr=${candidate.iqr}, stddev=${candidate.stddev.toFixed(2)})`,\n }\n }\n const medianDelta = candidate.median - parent.median\n if (medianDelta > t.keepThreshold) {\n return { verdict: 'KEEP', medianDelta, reason: `median +${medianDelta} > +${t.keepThreshold}` }\n }\n if (medianDelta < -t.regressionThreshold) {\n return {\n verdict: 'REGRESSION',\n medianDelta,\n reason: `median ${medianDelta} < -${t.regressionThreshold}`,\n }\n }\n return {\n verdict: 'NOISE',\n medianDelta,\n reason: `median delta ${medianDelta} inside noise band [-${t.regressionThreshold}, +${t.keepThreshold}]`,\n }\n}\n\n// ── Provenance + persistence seams ───────────────────────────────────\n\n/** Reads git provenance for the working tree. Inject a fake in tests; the\n * default implementation shells out to `git`. */\nexport type ProvenanceReader = () => ExperimentProvenance | Promise<ExperimentProvenance>\n\n/** Persistence seam for the experiment log. Inject in-memory in tests; the\n * filesystem implementation is `fileExperimentStore`. */\nexport interface ExperimentStore {\n load(): Promise<Experiment[]>\n save(experiments: Experiment[]): Promise<void>\n}\n\n/**\n * Default provenance reader: `git rev-parse HEAD`, the subject line, and the\n * files changed vs `HEAD~1`. Fail-loud — a tracker that silently logs\n * `commit: 'unknown'` corrupts the provenance the whole point of the log is to\n * carry. When the working tree genuinely has no parent commit, pass an override.\n */\nexport const gitProvenanceReader: ProvenanceReader = () => {\n const run = (cmd: string): string => execSync(cmd, { encoding: 'utf8' }).trim()\n const commit = run('git rev-parse --short HEAD')\n const message = run('git log -1 --format=%s')\n const changedRaw = run('git diff --name-only HEAD~1')\n const changedFiles = changedRaw.length === 0 ? [] : changedRaw.split('\\n').filter(Boolean)\n return { commit, message, changedFiles }\n}\n\n/** In-memory store — the default when no persistence is wanted (tests, ephemeral\n * runs). State lives on the instance. */\nexport function inMemoryExperimentStore(initial: Experiment[] = []): ExperimentStore {\n let state = initial.map((e) => structuredClone(e))\n return {\n async load() {\n return state.map((e) => structuredClone(e))\n },\n async save(experiments) {\n state = experiments.map((e) => structuredClone(e))\n },\n }\n}\n\n/** Filesystem store — a single JSON array at `path`, created on first save. */\nexport function fileExperimentStore(path: string): ExperimentStore {\n return {\n async load() {\n const fs = await import('node:fs/promises')\n try {\n const raw = await fs.readFile(path, 'utf8')\n const parsed = JSON.parse(raw)\n if (!Array.isArray(parsed)) {\n throw new ValidationError(`experiment-tracker: store at ${path} is not a JSON array`)\n }\n return parsed as Experiment[]\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') return []\n throw err\n }\n },\n async save(experiments) {\n const fs = await import('node:fs/promises')\n const pathMod = await import('node:path')\n await fs.mkdir(pathMod.dirname(path), { recursive: true })\n await fs.writeFile(path, JSON.stringify(experiments, null, 2), 'utf8')\n },\n }\n}\n\nexport interface ExperimentTrackerOptions {\n store?: ExperimentStore\n provenanceReader?: ProvenanceReader\n thresholds?: ImprovementThresholds\n /** Clock seam for deterministic timestamps in tests. Default `Date.now`. */\n now?: () => number\n}\n\nexport interface CreateExperimentInput {\n id: string\n label: string\n changeSummary: string\n parentId?: string\n /** Override provenance instead of reading from git (e.g. CI metadata). */\n provenance?: ExperimentProvenance\n}\n\n/**\n * Stateful tracker over an `ExperimentStore`. Create an experiment (provenance\n * is captured once), append reps as they complete (stats + verdict recompute on\n * every append), and read the log back for a dashboard. All persistence and git\n * access flow through the injected seams, so the tracker is fully testable\n * without a repo or disk.\n */\nexport class ExperimentTracker {\n private readonly store: ExperimentStore\n private readonly provenanceReader: ProvenanceReader\n private readonly thresholds: Required<ImprovementThresholds>\n private readonly now: () => number\n\n constructor(options: ExperimentTrackerOptions = {}) {\n this.store = options.store ?? inMemoryExperimentStore()\n this.provenanceReader = options.provenanceReader ?? gitProvenanceReader\n this.thresholds = resolveThresholds(options.thresholds)\n this.now = options.now ?? Date.now\n }\n\n async create(input: CreateExperimentInput): Promise<Experiment> {\n const experiments = await this.store.load()\n if (experiments.some((e) => e.id === input.id)) {\n throw new ValidationError(`experiment-tracker: experiment id \"${input.id}\" already exists`)\n }\n if (input.parentId && !experiments.some((e) => e.id === input.parentId)) {\n throw new ValidationError(\n `experiment-tracker: parent experiment \"${input.parentId}\" not found`,\n )\n }\n const provenance = input.provenance ?? (await this.provenanceReader())\n const experiment: Experiment = {\n id: input.id,\n label: input.label,\n provenance,\n parentId: input.parentId,\n changeSummary: input.changeSummary,\n reps: [],\n stats: computeExperimentStats([], this.thresholds),\n verdict: 'ITERATE',\n createdAt: new Date(this.now()).toISOString(),\n }\n experiments.push(experiment)\n await this.store.save(experiments)\n return structuredClone(experiment)\n }\n\n /** Append a rep (its `rep` index defaults to the current rep count) and\n * recompute stats + verdict. Returns the updated experiment. */\n async addRep(\n experimentId: string,\n rep: Omit<ExperimentRep, 'rep' | 'timestamp'> & { rep?: number; timestamp?: string },\n ): Promise<Experiment> {\n const experiments = await this.store.load()\n const exp = experiments.find((e) => e.id === experimentId)\n if (!exp)\n throw new ValidationError(`experiment-tracker: experiment \"${experimentId}\" not found`)\n const fullRep: ExperimentRep = {\n rep: rep.rep ?? exp.reps.length,\n score: rep.score,\n passed: rep.passed,\n metrics: rep.metrics,\n timestamp: rep.timestamp ?? new Date(this.now()).toISOString(),\n }\n exp.reps.push(fullRep)\n exp.stats = computeExperimentStats(exp.reps, this.thresholds)\n const parent = exp.parentId ? experiments.find((e) => e.id === exp.parentId) : undefined\n exp.verdict = improvementVerdict(exp.stats, parent?.stats ?? null, this.thresholds).verdict\n await this.store.save(experiments)\n return structuredClone(exp)\n }\n\n async get(experimentId: string): Promise<Experiment | undefined> {\n const experiments = await this.store.load()\n const found = experiments.find((e) => e.id === experimentId)\n return found ? structuredClone(found) : undefined\n }\n\n async list(): Promise<Experiment[]> {\n return this.store.load()\n }\n\n /** Full verdict (not just the enum) for an experiment vs its parent. */\n async verdictFor(experimentId: string): Promise<ImprovementVerdictResult> {\n const experiments = await this.store.load()\n const exp = experiments.find((e) => e.id === experimentId)\n if (!exp)\n throw new ValidationError(`experiment-tracker: experiment \"${experimentId}\" not found`)\n const parent = exp.parentId ? experiments.find((e) => e.id === exp.parentId) : undefined\n return improvementVerdict(exp.stats, parent?.stats ?? null, this.thresholds)\n }\n}\n","/**\n * Cross-profile leaderboard — rank agent profiles (or any grouping) over a corpus\n * of RunRecords on pass-rate with a Wilson CI, joined with the cost / token /\n * latency rollup every benchmark wants next to the score.\n *\n * This is substrate, not benchmark-specific: any consumer of agent-eval gets a\n * cross-harness × model leaderboard without re-implementing grouping, binomial\n * CIs, or the observability join. The benchmark supplies only what \"passed\"\n * means; everything else composes existing primitives (`wilson`, the RunRecord\n * cost/token/wall fields, the AgentProfileCell grouping key).\n */\nimport type { RunRecord } from './run-record'\nimport { wilson } from './statistics'\n\nexport interface LeaderboardRow {\n /** Group key — the agent-profile cellId by default, else a caller dimension. */\n key: string\n /** Display label: `harness · model` when the profile carries them, else the key. */\n label: string\n harness?: string\n model?: string\n rank: number\n /** Measured runs in this group. */\n n: number\n passRate: number\n passRateCi95: [number, number]\n /** Observability rollup — means over the group; null when no run reported it. */\n meanCostUsd: number | null\n meanTokensIn: number | null\n meanTokensOut: number | null\n meanWallMs: number | null\n}\n\nexport interface LeaderboardOptions {\n /** Per-run pass predicate — the benchmark defines what \"passed\" means (real-build\n * hit-rate, test-pass, etc.). The leaderboard owns only the grouping + stats. */\n passed: (record: RunRecord) => boolean\n /** Group key. Default: the agent-profile cellId (harness × model × dimensions),\n * so persona/harness/model sweeps separate without parsing labels. */\n groupBy?: (record: RunRecord) => string\n}\n\nfunction mean(xs: number[]): number | null {\n return xs.length ? xs.reduce((a, b) => a + b, 0) / xs.length : null\n}\n\n/**\n * Group `records`, compute pass-rate + Wilson CI + cost/token/latency means per\n * group, and rank by pass-rate (cost as the tiebreaker — cheaper wins a tie).\n * Pure projection: no I/O, deterministic, safe to call on any RunRecord[].\n */\nexport function leaderboard(records: RunRecord[], opts: LeaderboardOptions): LeaderboardRow[] {\n const keyOf = opts.groupBy ?? ((r: RunRecord) => r.agentProfile?.cellId ?? 'ungrouped')\n const groups = new Map<string, RunRecord[]>()\n for (const r of records) {\n const k = keyOf(r)\n const g = groups.get(k)\n if (g) g.push(r)\n else groups.set(k, [r])\n }\n\n const rows: LeaderboardRow[] = [...groups.entries()].map(([key, rs]) => {\n const passes = rs.filter((r) => opts.passed(r)).length\n const ci = wilson(passes, rs.length)\n const profile = rs[0]!.agentProfile\n const harness = profile?.harness?.id\n const model = profile?.model\n return {\n key,\n label: harness && model ? `${harness} · ${model}` : key,\n ...(harness ? { harness } : {}),\n ...(model ? { model } : {}),\n rank: 0,\n n: rs.length,\n passRate: ci.estimate,\n passRateCi95: [ci.lower, ci.upper],\n meanCostUsd: mean(rs.map((r) => r.costUsd)),\n meanTokensIn: mean(rs.map((r) => r.tokenUsage.input)),\n meanTokensOut: mean(rs.map((r) => r.tokenUsage.output)),\n meanWallMs: mean(rs.map((r) => r.wallMs)),\n }\n })\n\n rows.sort(\n (a, b) => b.passRate - a.passRate || (a.meanCostUsd ?? Infinity) - (b.meanCostUsd ?? Infinity),\n )\n rows.forEach((row, i) => {\n row.rank = i + 1\n })\n return rows\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: ReturnType<typeof statSync>\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 * Deterministic held-out partitioning over stable ids.\n *\n * A promotion gate's paired-delta math needs a fixed partition: the same\n * scenario id lands in the same bucket forever, regardless of when it ran or\n * which loop emitted the record — otherwise the gate has nothing paired to\n * compare against. Picking one global split per run is wrong: every run then\n * stamps either ALL search or ALL holdout, and no id is ever observed on both\n * sides. Per-id deterministic hashing fixes that.\n *\n * Two consumers hand-roll this (agent-builder's `deterministicSplit` and the\n * frontier persona-splitter). The substrate already has a 3-way benchmark\n * `deterministicSplit` in `./benchmarks`; this is the generic, validated batch\n * partitioner: it takes a list of ids, splits them by a stable FNV-1a hash, and\n * fails loud when the inputs can't support a trustworthy held-out comparison\n * (duplicate ids, or a holdout set below the significance floor).\n */\n\nimport { ValidationError } from './errors'\n\n/** 32-bit FNV-1a hash. Stable, allocation-free, deterministic across runtimes —\n * the same id+seed maps to the same bucket on every machine and process. */\nexport function fnv1a32(input: string): number {\n let h = 0x811c9dc5\n for (let i = 0; i < input.length; i++) {\n h ^= input.charCodeAt(i) & 0xff\n h = Math.imul(h, 0x01000193)\n }\n return h >>> 0\n}\n\n/** Map an id+seed to the half-open unit interval [0, 1) deterministically. */\nexport function hashToUnit(id: string, seed: string): number {\n // Newline separator: 'ab' + '\\n' + 'c' can't collide with 'a' + '\\n' + 'bc'.\n return fnv1a32(`${id}\\n${seed}`) / 0x1_0000_0000\n}\n\nexport interface PartitionHeldOutOptions {\n /** Partition seed. Bumping it reshuffles every assignment — do that only when\n * the corpus/policy changes meaningfully so old and new records can't pair.\n * Default 'held-out-v1'. */\n seed?: string\n /** Fraction routed to the held-out bucket, in (0, 1). Default 0.5. */\n holdoutFraction?: number\n /**\n * Minimum held-out ids required for the split to be admissible. Below this,\n * a paired comparison has too few observations to be significant, so the\n * partition throws rather than hand back an underpowered holdout. Default 1\n * (only the empty-holdout degenerate case is rejected). Raise it to enforce\n * real statistical power. */\n minHoldout?: number\n /** Same floor for the search side. Default 1. */\n minSearch?: number\n}\n\nexport interface HeldOutPartition {\n /** Ids the optimizer is allowed to read/optimize against. */\n search: string[]\n /** Ids reserved for gated, held-out evaluation. */\n holdout: string[]\n seed: string\n holdoutFraction: number\n}\n\n/**\n * Assign a single id to `'search'` or `'holdout'` deterministically. Same\n * `(id, seed)` always returns the same tag — the invariant the gate relies on.\n * Use this in a `splitTag:` field literal when stamping records one at a time;\n * use `partitionHeldOut` when you have the whole id list up front and want the\n * validated disjoint split.\n */\nexport function assignHeldOutTag(\n id: string,\n options: { seed?: string; holdoutFraction?: number } = {},\n): 'search' | 'holdout' {\n const seed = options.seed ?? 'held-out-v1'\n const holdoutFraction = options.holdoutFraction ?? 0.5\n assertFraction(holdoutFraction)\n return hashToUnit(id, seed) < holdoutFraction ? 'holdout' : 'search'\n}\n\n/**\n * Partition a list of stable ids into disjoint `search` / `holdout` sets by a\n * deterministic hash. Fail-loud:\n * - empty input throws,\n * - duplicate ids throw (a dup would be observed on both sides, double-counting),\n * - a holdout (or search) set below its floor throws (underpowered comparison).\n *\n * Order within each bucket follows the input order, so the result is stable and\n * reproducible.\n */\nexport function partitionHeldOut(\n ids: string[],\n options: PartitionHeldOutOptions = {},\n): HeldOutPartition {\n const seed = options.seed ?? 'held-out-v1'\n const holdoutFraction = options.holdoutFraction ?? 0.5\n const minHoldout = options.minHoldout ?? 1\n const minSearch = options.minSearch ?? 1\n assertFraction(holdoutFraction)\n if (ids.length === 0) {\n throw new ValidationError('partitionHeldOut: no ids supplied')\n }\n\n const seen = new Set<string>()\n const search: string[] = []\n const holdout: string[] = []\n for (const id of ids) {\n if (typeof id !== 'string' || id.length === 0) {\n throw new ValidationError(\n `partitionHeldOut: ids must be non-empty strings, got ${JSON.stringify(id)}`,\n )\n }\n if (seen.has(id)) {\n throw new ValidationError(\n `partitionHeldOut: duplicate id \"${id}\" — a paired comparison must not double-count`,\n )\n }\n seen.add(id)\n if (hashToUnit(id, seed) < holdoutFraction) holdout.push(id)\n else search.push(id)\n }\n\n if (holdout.length < minHoldout) {\n throw new ValidationError(\n `partitionHeldOut: holdout set has ${holdout.length} id(s), below the floor of ${minHoldout} ` +\n `(n=${ids.length}, holdoutFraction=${holdoutFraction}) — too few for a significant comparison`,\n )\n }\n if (search.length < minSearch) {\n throw new ValidationError(\n `partitionHeldOut: search set has ${search.length} id(s), below the floor of ${minSearch} ` +\n `(n=${ids.length}, holdoutFraction=${holdoutFraction})`,\n )\n }\n\n return { search, holdout, seed, holdoutFraction }\n}\n\nfunction assertFraction(f: number): void {\n if (!Number.isFinite(f) || f <= 0 || f >= 1) {\n throw new ValidationError(`partitionHeldOut: holdoutFraction must be in (0, 1), got ${f}`)\n }\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, agentProfileModelId } 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 model = agentProfileModelId(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,\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 * 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 * UI audit finding — substrate primitive for \"what is wrong with the UI?\"\n *\n * Used by:\n * - `@tangle-network/agent-runtime` (ui-auditor profile + delegate) —\n * produced as the canonical output of an audit iteration, persisted to\n * disk as GitHub-issue Markdown, surfaced over MCP.\n * - Downstream ship gates / dashboards / analyst consumers — load and\n * transform findings without depending on the runtime.\n *\n * Repo layering: agent-eval is the substrate (no upward deps). Consumers\n * read this type from here; the reverse is forbidden. See CLAUDE.md\n * \"Repo layering\" for the rule. A UI finding makes sense WITHOUT a running\n * agent loop (you can load a saved finding, ship-gate against a set of\n * them, render them in a dashboard), which puts it firmly in substrate.\n *\n * The shape is intentionally minimal — runtime-shaped state (capture\n * timestamps, OTel trace IDs, sandbox placement) lives on auxiliary\n * runtime types in `agent-runtime`, not on the finding itself.\n */\n\n/**\n * Canonical audit lenses. Each lens scopes a finding to a single class of\n * problem so a single audit pass can iterate them without pile-on findings\n * under a generic label.\n *\n * Naming is fixed for cross-package wire compatibility. Treat additions as\n * a substrate-level decision — analysts, gates, and writers all branch on\n * the lens.\n */\nexport type UiLens =\n | 'consistency'\n | 'hierarchy'\n | 'layout'\n | 'ux-flow'\n | 'duplication'\n | 'accessibility'\n | 'responsive'\n | 'states'\n | 'content'\n | 'interaction'\n | 'performance-perceived'\n | 'other'\n\n/** Frozen tuple of lenses for validation + iteration. */\nexport const UI_LENSES: readonly UiLens[] = [\n 'consistency',\n 'hierarchy',\n 'layout',\n 'ux-flow',\n 'duplication',\n 'accessibility',\n 'responsive',\n 'states',\n 'content',\n 'interaction',\n 'performance-perceived',\n 'other',\n] as const\n\n/**\n * Severity scale — intentionally narrow.\n *\n * - `critical` — blocks a core task or is an accessibility blocker.\n * - `high` — confusing, broken-looking, or noticeable friction.\n * - `med` — visible polish issue, would be caught in code review.\n * - `low` — nitpick worth fixing eventually.\n */\nexport type UiFindingSeverity = 'low' | 'med' | 'high' | 'critical'\n\n/** Frozen severity tuple, ordered worst → least bad for sort/report. */\nexport const UI_FINDING_SEVERITIES: readonly UiFindingSeverity[] = [\n 'critical',\n 'high',\n 'med',\n 'low',\n] as const\n\n/**\n * Pointer to a screenshot referenced by the finding. The path is\n * intentionally a relative string (relative to the audit workspace root)\n * so findings remain portable across machines and into GitHub issues.\n */\nexport interface UiFindingScreenshot {\n /** Workspace-relative path to the screenshot file (e.g. `screenshots/home--1280x800--...png`). */\n path: string\n /** Optional viewport the screenshot was taken at, e.g. `1280x800`. */\n viewport?: string\n /** Optional short label that disambiguates multiple captures of the same surface (e.g. `t0`, `step-1`). */\n label?: string\n}\n\n/**\n * A single UI audit finding — the unit of work a contributor can act on.\n *\n * Every field except the documented optionals is required. The shape is\n * deliberately constraining: a finding without a screenshot, a lens, a\n * concrete title, and a suggested fix is not actionable, and the auditor\n * validator hard-fails on those gaps.\n */\nexport interface UiFinding {\n /**\n * Stable identifier within a single audit workspace. Monotonically\n * increasing integer (1, 2, …) assigned by the writer when persisting.\n * Optional in transit (before persistence) — undefined on freshly minted\n * findings emitted from a loop iteration.\n */\n id?: number\n /** Concrete title — names the offending element AND what's wrong. */\n title: string\n /** Lens this finding belongs to. */\n lens: UiLens\n /** Severity. */\n severity: UiFindingSeverity\n /** Logical route the finding was observed on (e.g. `home`, `checkout-step-2`). */\n route: string\n /** Fully qualified URL the finding was observed at. */\n url?: string\n /** Viewport string the offending capture was taken at (e.g. `1280x800`). */\n viewport?: string\n /** CSS selector pinning the offending element, when one can be identified. */\n selector?: string\n /** 1–3 sentences describing what the screenshot shows that is wrong. */\n observation: string\n /** Who is affected and how. Concrete user impact. */\n impact: string\n /** A specific change a contributor could apply without asking back. */\n suggestedFix: string\n /** Optional explicit reproduction steps. Writer synthesizes from route/url/selector when omitted. */\n reproSteps?: string\n /** Free-form tags. */\n tags?: readonly string[]\n /** Screenshot references — required to be non-empty for actionable findings. */\n screenshots: readonly UiFindingScreenshot[]\n /** Cross-references to similar findings already on file, by id. */\n similarTo?: readonly number[]\n /** ISO-8601 creation timestamp set by the writer when persisted. */\n createdAt?: string\n}\n","/**\n * Trace contracts — finite-trace temporal assertions over span sequences.\n *\n * Five LTLf operators over one ordered span sequence — `always(p)`,\n * `never(p)`, `eventually(p)`, `precedes(a, b)`, `neverUnless(p, prior)` —\n * deterministic and judge-free. No nesting: each rule is one operator over\n * flat `SpanPredicate`s; compose richer checks with multiple rules.\n *\n * A built `TraceContract` is a serializable plain object (RegExp matchers\n * are normalized to `SerializedRegex`), so ONE contract definition is\n * dual-use:\n *\n * - recorded eval traces — `evaluateTraceContract(contract, await\n * store.spans({ runId }))`, or via the behavior DSL:\n * `expectAgent(store, runId).toSatisfyContract(contract)`.\n * - the production OTLP stream — `ExportableSpan`s flattened by\n * `trace/otel-bridge` satisfy `ContractSpan` structurally. A production\n * monitor implements `OtelExporter`, buffers `exportSpan` payloads per\n * trace, and runs `checkTraceContracts(buffer, contracts)` on flush:\n *\n * const buffer: ContractSpan[] = []\n * const monitor: OtelExporter = {\n * exportSpan: (s) => { buffer.push(s) },\n * flush: async () => {\n * const { allValid, verdicts } = checkTraceContracts(buffer, contracts)\n * if (!allValid) alert(verdicts)\n * },\n * shutdown: async () => {},\n * }\n * const store = createOtelTracingStore(inner, monitor, runId)\n *\n * `custom` predicate functions are the one non-serializable escape hatch:\n * the builder stamps `requiresCustom: true` (which DOES survive JSON) so a\n * deserialized contract that lost its function fails loud at evaluation\n * instead of silently weakening.\n *\n * Naming: the root barrel exports ci-gate's threshold-contract\n * `evaluateContract`, so the evaluators here are `evaluateTraceContract` /\n * `checkTraceContracts`.\n */\n\nimport type { JudgeConfig, JudgeDimension, Scenario } from './campaign/types'\nimport { ValidationError } from './errors'\nimport type { DefaultVerdict } from './verdict'\n\n// ── Span surface ──────────────────────────────────────────────────────\n\n/**\n * Minimal structural span the checker reads. Both the eval-side `Span`\n * (trace/schema) and the OTLP-flattened `ExportableSpan` (trace/otel-export)\n * satisfy it; any other producer only needs these fields.\n */\nexport interface ContractSpan {\n spanId?: string\n name?: string\n kind?: string\n startedAt?: number\n status?: string\n error?: string\n /** Typed field on eval-side ToolSpans; OTLP flattenings drop it (see\n * `tool` matching order in {@link matchSpan}). */\n toolName?: string\n attributes?: Record<string, unknown>\n}\n\n/** JSON-safe RegExp form — what the builder normalizes RegExp matchers to. */\nexport interface SerializedRegex {\n $regex: string\n flags: string\n}\n\nexport type TextMatcher = string | RegExp | SerializedRegex\n\n/**\n * Proposition over one span. All specified fields must match (AND).\n * At least one field is required — an empty predicate would match every\n * span and is rejected.\n *\n * `tool` resolution order covers both span shapes: `span.toolName` (typed\n * ToolSpan) → `attributes['tool.name']` / `attributes['toolName']`\n * (OTLP-flat attribute conventions) → `span.name` when `kind === 'tool'`\n * (otel-bridge's `ExportableSpan`, which drops `toolName`).\n *\n * `attr` values match by strict equality, or regex-test when the value is a\n * RegExp/SerializedRegex and the attribute is a string. Structured attribute\n * values need `custom`.\n */\nexport interface SpanPredicate {\n name?: TextMatcher\n tool?: TextMatcher\n attr?: Record<string, unknown>\n custom?: (span: ContractSpan) => boolean\n /** Stamped by the builder when `custom` is present. Survives JSON while\n * the function does not, so evaluation of a deserialized contract throws\n * instead of silently dropping the check. */\n requiresCustom?: true\n}\n\n// ── Contract shape ────────────────────────────────────────────────────\n\nexport type ContractRuleKind = 'always' | 'never' | 'eventually' | 'precedes' | 'neverUnless'\n\nexport interface ContractRule {\n kind: ContractRuleKind\n /** Unique within the contract — keys the per-rule score. */\n label: string\n /** Subject predicate for always / never / eventually / neverUnless. */\n p?: SpanPredicate\n /** precedes: the required precondition. */\n a?: SpanPredicate\n /** precedes: the guarded match — every b-match needs an earlier a-match. */\n b?: SpanPredicate\n /** neverUnless: the authorizing earlier match. */\n prior?: SpanPredicate\n}\n\n/** Serializable plain object — `traceContract(name)....build()` output. */\nexport interface TraceContract {\n name: string\n rules: ContractRule[]\n}\n\nexport interface ContractViolation {\n rule: string\n spanId?: string\n detail: string\n}\n\nexport interface ContractVerdict extends DefaultVerdict {\n /** Contract name — keys this verdict in multi-contract reports. */\n contract: string\n valid: boolean\n /** Fraction of rules passing, in [0, 1]. */\n score: number\n /** Per-rule 0|1 keyed by rule label. */\n scores: Record<string, number>\n violations: ContractViolation[]\n}\n\nexport interface ContractCheckResult {\n verdicts: ContractVerdict[]\n allValid: boolean\n}\n\n// ── Predicate matching ────────────────────────────────────────────────\n\nfunction isSerializedRegex(v: unknown): v is SerializedRegex {\n return (\n typeof v === 'object' &&\n v !== null &&\n typeof (v as SerializedRegex).$regex === 'string' &&\n typeof (v as SerializedRegex).flags === 'string'\n )\n}\n\nfunction matchText(actual: string | undefined, matcher: TextMatcher): boolean {\n if (typeof actual !== 'string') return false\n if (typeof matcher === 'string') return actual === matcher\n if (matcher instanceof RegExp) return matcher.test(actual)\n return new RegExp(matcher.$regex, matcher.flags).test(actual)\n}\n\nfunction resolveToolName(span: ContractSpan): string | undefined {\n if (typeof span.toolName === 'string') return span.toolName\n const fromAttr = span.attributes?.['tool.name'] ?? span.attributes?.toolName\n if (typeof fromAttr === 'string') return fromAttr\n if (span.kind === 'tool' && typeof span.name === 'string') return span.name\n return undefined\n}\n\nfunction assertPredicate(value: unknown, where: string): asserts value is SpanPredicate {\n if (value === null || typeof value !== 'object') {\n throw new ValidationError(`${where}: predicate must be an object, got ${typeof value}`)\n }\n const p = value as SpanPredicate\n for (const field of ['name', 'tool'] as const) {\n const m = p[field]\n if (\n m !== undefined &&\n typeof m !== 'string' &&\n !(m instanceof RegExp) &&\n !isSerializedRegex(m)\n ) {\n throw new ValidationError(`${where}: \"${field}\" must be string | RegExp | SerializedRegex`)\n }\n }\n if (\n p.attr !== undefined &&\n (p.attr === null || typeof p.attr !== 'object' || Array.isArray(p.attr))\n ) {\n throw new ValidationError(`${where}: \"attr\" must be a plain object`)\n }\n if (p.requiresCustom && typeof p.custom !== 'function') {\n throw new ValidationError(\n `${where}: rule was built with a custom predicate function, which does not survive JSON ` +\n 'serialization — re-attach `custom` after deserializing or drop the rule',\n )\n }\n const hasAttr = p.attr !== undefined && Object.keys(p.attr).length > 0\n if (p.name === undefined && p.tool === undefined && !hasAttr && typeof p.custom !== 'function') {\n throw new ValidationError(\n `${where}: empty predicate would match every span — specify name, tool, attr, or custom`,\n )\n }\n}\n\n/** Test one span against one predicate. All specified fields must match. */\nexport function matchSpan(span: ContractSpan, predicate: SpanPredicate): boolean {\n assertPredicate(predicate, 'matchSpan')\n if (predicate.name !== undefined && !matchText(span.name, predicate.name)) return false\n if (predicate.tool !== undefined && !matchText(resolveToolName(span), predicate.tool))\n return false\n if (predicate.attr !== undefined) {\n for (const [key, expected] of Object.entries(predicate.attr)) {\n const actual = span.attributes?.[key]\n if (expected instanceof RegExp || isSerializedRegex(expected)) {\n if (!matchText(typeof actual === 'string' ? actual : undefined, expected as TextMatcher)) {\n return false\n }\n } else if (actual !== expected) {\n return false\n }\n }\n }\n if (predicate.custom !== undefined && !predicate.custom(span)) return false\n return true\n}\n\n// ── Builder ───────────────────────────────────────────────────────────\n\nfunction describeMatcher(m: TextMatcher): string {\n if (typeof m === 'string') return m\n if (m instanceof RegExp) return `/${m.source}/${m.flags}`\n return `/${m.$regex}/${m.flags}`\n}\n\nfunction describePredicate(p: SpanPredicate): string {\n const parts: string[] = []\n if (p.name !== undefined) parts.push(`name=${describeMatcher(p.name)}`)\n if (p.tool !== undefined) parts.push(`tool=${describeMatcher(p.tool)}`)\n if (p.attr !== undefined) {\n for (const [k, v] of Object.entries(p.attr)) {\n parts.push(\n `attr.${k}=${v instanceof RegExp || isSerializedRegex(v) ? describeMatcher(v as TextMatcher) : JSON.stringify(v)}`,\n )\n }\n }\n if (typeof p.custom === 'function') parts.push(`custom=${p.custom.name || 'fn'}`)\n return parts.join(',')\n}\n\nfunction normalizeMatcher(m: TextMatcher): string | SerializedRegex {\n return m instanceof RegExp ? { $regex: m.source, flags: m.flags } : m\n}\n\nfunction normalizePredicate(p: SpanPredicate, where: string): SpanPredicate {\n assertPredicate(p, where)\n const out: SpanPredicate = {}\n if (p.name !== undefined) out.name = normalizeMatcher(p.name)\n if (p.tool !== undefined) out.tool = normalizeMatcher(p.tool)\n if (p.attr !== undefined) {\n out.attr = Object.fromEntries(\n Object.entries(p.attr).map(([k, v]) => [k, v instanceof RegExp ? normalizeMatcher(v) : v]),\n )\n }\n if (typeof p.custom === 'function') {\n out.custom = p.custom\n out.requiresCustom = true\n }\n return out\n}\n\nexport class TraceContractBuilder {\n private readonly rules: ContractRule[] = []\n\n constructor(private readonly name: string) {}\n\n /** Every span in the trace must satisfy `p`. */\n always(p: SpanPredicate, label?: string): this {\n const np = normalizePredicate(p, `traceContract(\"${this.name}\").always`)\n return this.add({ kind: 'always', label: label ?? `always(${describePredicate(np)})`, p: np })\n }\n\n /** No span in the trace may satisfy `p`. */\n never(p: SpanPredicate, label?: string): this {\n const np = normalizePredicate(p, `traceContract(\"${this.name}\").never`)\n return this.add({ kind: 'never', label: label ?? `never(${describePredicate(np)})`, p: np })\n }\n\n /** At least one span in the trace must satisfy `p`. */\n eventually(p: SpanPredicate, label?: string): this {\n const np = normalizePredicate(p, `traceContract(\"${this.name}\").eventually`)\n return this.add({\n kind: 'eventually',\n label: label ?? `eventually(${describePredicate(np)})`,\n p: np,\n })\n }\n\n /** Every `b`-match must have a strictly earlier `a`-match. */\n precedes(a: SpanPredicate, b: SpanPredicate, label?: string): this {\n const na = normalizePredicate(a, `traceContract(\"${this.name}\").precedes (a)`)\n const nb = normalizePredicate(b, `traceContract(\"${this.name}\").precedes (b)`)\n return this.add({\n kind: 'precedes',\n label: label ?? `precedes(${describePredicate(na)} -> ${describePredicate(nb)})`,\n a: na,\n b: nb,\n })\n }\n\n /** Every `p`-match is a violation unless a strictly earlier `prior`-match exists. */\n neverUnless(p: SpanPredicate, prior: SpanPredicate, label?: string): this {\n const np = normalizePredicate(p, `traceContract(\"${this.name}\").neverUnless (p)`)\n const nprior = normalizePredicate(prior, `traceContract(\"${this.name}\").neverUnless (prior)`)\n return this.add({\n kind: 'neverUnless',\n label: label ?? `neverUnless(${describePredicate(np)} unless ${describePredicate(nprior)})`,\n p: np,\n prior: nprior,\n })\n }\n\n build(): TraceContract {\n if (this.rules.length === 0) {\n throw new ValidationError(\n `traceContract(\"${this.name}\").build(): no rules — an empty contract would vacuously pass`,\n )\n }\n return { name: this.name, rules: [...this.rules] }\n }\n\n private add(rule: ContractRule): this {\n // Labels key per-rule scores — auto-suffix duplicates so two identical\n // operator+predicate rules never collapse into one score entry.\n let label = rule.label\n let n = 2\n while (this.rules.some((r) => r.label === label)) {\n label = `${rule.label} #${n}`\n n += 1\n }\n this.rules.push({ ...rule, label })\n return this\n }\n}\n\nexport function traceContract(name: string): TraceContractBuilder {\n if (typeof name !== 'string' || name.length === 0) {\n throw new ValidationError('traceContract: name must be a non-empty string')\n }\n return new TraceContractBuilder(name)\n}\n\n// ── Evaluation ────────────────────────────────────────────────────────\n\nfunction assertContract(contract: TraceContract): void {\n if (typeof contract?.name !== 'string' || contract.name.length === 0) {\n throw new ValidationError('evaluateTraceContract: contract.name must be a non-empty string')\n }\n if (!Array.isArray(contract.rules) || contract.rules.length === 0) {\n throw new ValidationError(\n `evaluateTraceContract: contract \"${contract.name}\" has no rules — an empty contract would vacuously pass`,\n )\n }\n const seen = new Set<string>()\n for (const rule of contract.rules) {\n const where = `contract \"${contract.name}\" rule \"${rule?.label ?? '<unlabeled>'}\"`\n if (typeof rule?.label !== 'string' || rule.label.length === 0) {\n throw new ValidationError(`${where}: label must be a non-empty string`)\n }\n if (seen.has(rule.label)) {\n throw new ValidationError(`${where}: duplicate label would collapse per-rule scores`)\n }\n seen.add(rule.label)\n switch (rule.kind) {\n case 'always':\n case 'never':\n case 'eventually':\n assertPredicate(rule.p, `${where} (p)`)\n break\n case 'precedes':\n assertPredicate(rule.a, `${where} (a)`)\n assertPredicate(rule.b, `${where} (b)`)\n break\n case 'neverUnless':\n assertPredicate(rule.p, `${where} (p)`)\n assertPredicate(rule.prior, `${where} (prior)`)\n break\n default:\n throw new ValidationError(\n `${where}: unknown rule kind \"${String((rule as ContractRule).kind)}\"`,\n )\n }\n }\n}\n\n/**\n * Order spans for temporal evaluation: by `startedAt` when EVERY span carries\n * one (stable — ties keep array order), by array order when NONE does. Mixed\n * timestamps throw: neither time order nor array order is a trustworthy total\n * order over a partially-stamped sequence, and guessing would corrupt\n * `precedes` / `neverUnless` verdicts.\n */\nfunction orderSpans(spans: readonly ContractSpan[]): ContractSpan[] {\n const timed = spans.filter(\n (s) => typeof s.startedAt === 'number' && Number.isFinite(s.startedAt),\n ).length\n if (timed === spans.length) {\n return spans\n .map((span, i) => ({ span, i }))\n .sort((x, y) => x.span.startedAt! - y.span.startedAt! || x.i - y.i)\n .map((x) => x.span)\n }\n if (timed === 0) return [...spans]\n throw new ValidationError(\n `evaluateTraceContract: ${timed}/${spans.length} spans carry a finite startedAt — ` +\n 'mixed timestamps make ordering ambiguous; stamp every span or none',\n )\n}\n\nfunction spanRef(span: ContractSpan, index: number): string {\n return span.spanId ?? `#${index}`\n}\n\n// precedes(a, b) and neverUnless(p, prior) share one semantics: every\n// guarded-match must have a STRICTLY earlier guard-match. The guard flag\n// updates after the guarded check, so a span matching both cannot witness\n// itself.\nfunction checkGuarded(args: {\n label: string\n ordered: readonly ContractSpan[]\n guard: SpanPredicate\n guarded: SpanPredicate\n detail: (ref: string) => string\n}): ContractViolation[] {\n const out: ContractViolation[] = []\n let guardSeen = false\n for (let i = 0; i < args.ordered.length; i++) {\n const span = args.ordered[i]!\n if (!guardSeen && matchSpan(span, args.guarded)) {\n out.push({ rule: args.label, spanId: span.spanId, detail: args.detail(spanRef(span, i)) })\n }\n if (matchSpan(span, args.guard)) guardSeen = true\n }\n return out\n}\n\nfunction checkRule(rule: ContractRule, ordered: readonly ContractSpan[]): ContractViolation[] {\n switch (rule.kind) {\n case 'always': {\n const out: ContractViolation[] = []\n for (let i = 0; i < ordered.length; i++) {\n const span = ordered[i]!\n if (!matchSpan(span, rule.p!)) {\n out.push({\n rule: rule.label,\n spanId: span.spanId,\n detail: `span ${spanRef(span, i)} (\"${span.name ?? ''}\") fails always(${describePredicate(rule.p!)})`,\n })\n }\n }\n return out\n }\n case 'never': {\n const out: ContractViolation[] = []\n for (let i = 0; i < ordered.length; i++) {\n const span = ordered[i]!\n if (matchSpan(span, rule.p!)) {\n out.push({\n rule: rule.label,\n spanId: span.spanId,\n detail: `span ${spanRef(span, i)} (\"${span.name ?? ''}\") matches never(${describePredicate(rule.p!)})`,\n })\n }\n }\n return out\n }\n case 'eventually': {\n const hit = ordered.some((span) => matchSpan(span, rule.p!))\n return hit\n ? []\n : [\n {\n rule: rule.label,\n detail: `no span matches eventually(${describePredicate(rule.p!)}) over ${ordered.length} span(s)`,\n },\n ]\n }\n case 'precedes':\n return checkGuarded({\n label: rule.label,\n ordered,\n guard: rule.a!,\n guarded: rule.b!,\n detail: (ref) =>\n `span ${ref} matches ${describePredicate(rule.b!)} with no earlier ${describePredicate(rule.a!)} match`,\n })\n case 'neverUnless':\n return checkGuarded({\n label: rule.label,\n ordered,\n guard: rule.prior!,\n guarded: rule.p!,\n detail: (ref) =>\n `span ${ref} matches ${describePredicate(rule.p!)} with no earlier ${describePredicate(rule.prior!)} match`,\n })\n }\n}\n\n/**\n * Evaluate one contract over a span sequence. Pure and synchronous — works\n * on `Span[]` from a TraceStore, `ExportableSpan[]` from the otel-bridge\n * flattening, or any array satisfying `ContractSpan`.\n */\nexport function evaluateTraceContract(\n contract: TraceContract,\n spans: readonly ContractSpan[],\n): ContractVerdict {\n assertContract(contract)\n const ordered = orderSpans(spans)\n const scores: Record<string, number> = {}\n const violations: ContractViolation[] = []\n for (const rule of contract.rules) {\n const ruleViolations = checkRule(rule, ordered)\n scores[rule.label] = ruleViolations.length === 0 ? 1 : 0\n violations.push(...ruleViolations)\n }\n const ruleCount = contract.rules.length\n const passCount = Object.values(scores).filter((s) => s === 1).length\n return {\n contract: contract.name,\n valid: passCount === ruleCount,\n score: passCount / ruleCount,\n scores,\n violations,\n notes: `${passCount}/${ruleCount} rules passed`,\n }\n}\n\n/**\n * Evaluate many contracts over one span sequence. Throws on an empty\n * contract list — `allValid: true` over zero contracts is a silent pass.\n */\nexport function checkTraceContracts(\n spans: readonly ContractSpan[],\n contracts: readonly TraceContract[],\n): ContractCheckResult {\n if (contracts.length === 0) {\n throw new ValidationError(\n 'checkTraceContracts: empty contract list would vacuously pass — supply at least one contract',\n )\n }\n const verdicts = contracts.map((c) => evaluateTraceContract(c, spans))\n return { verdicts, allValid: verdicts.every((v) => v.valid) }\n}\n\n// ── Campaign judge adapter ────────────────────────────────────────────\n\nexport interface ContractJudgeOptions<TArtifact, TScenario extends Scenario = Scenario> {\n /**\n * Project the span sequence out of a cell's artifact. `JudgeConfig.score`\n * receives only `{ artifact, scenario, signal }` (src/campaign/types.ts) —\n * spans are NOT reachable generically — so the consumer supplies this\n * explicit extraction (e.g. dispatch writes spans into the artifact, or\n * closes over a per-cell TraceStore read).\n */\n spans: (input: { artifact: TArtifact; scenario: TScenario }) => readonly ContractSpan[]\n /** Judge name in campaign reports. Default 'trace-contracts'. */\n name?: string\n}\n\n/**\n * Adapt trace contracts to a campaign `JudgeConfig`. One judge dimension per\n * contract (key = contract name, value = its rule-pass fraction); composite\n * is the mean across contracts. Deterministic — no LLM call.\n */\nexport function contractJudge<TArtifact, TScenario extends Scenario = Scenario>(\n contracts: readonly TraceContract[],\n opts: ContractJudgeOptions<TArtifact, TScenario>,\n): JudgeConfig<TArtifact, TScenario> {\n if (contracts.length === 0) {\n throw new ValidationError('contractJudge: at least one contract required')\n }\n for (const c of contracts) assertContract(c)\n const names = new Set<string>()\n for (const c of contracts) {\n if (names.has(c.name)) {\n throw new ValidationError(\n `contractJudge: duplicate contract name \"${c.name}\" would collapse judge dimensions`,\n )\n }\n names.add(c.name)\n }\n if (typeof opts?.spans !== 'function') {\n throw new ValidationError('contractJudge: opts.spans extraction function is required')\n }\n const dimensions: JudgeDimension[] = contracts.map((c) => ({\n key: c.name,\n description: c.rules.map((r) => r.label).join('; '),\n }))\n return {\n name: opts.name ?? 'trace-contracts',\n dimensions,\n score({ artifact, scenario }) {\n const spans = opts.spans({ artifact, scenario })\n if (!Array.isArray(spans)) {\n throw new ValidationError(\n `contractJudge: spans() must return a span array, got ${typeof spans}`,\n )\n }\n const { verdicts } = checkTraceContracts(spans, contracts)\n const dims: Record<string, number> = {}\n const violations: ContractViolation[] = []\n for (const v of verdicts) {\n dims[v.contract] = v.score\n violations.push(...v.violations)\n }\n const composite = verdicts.reduce((acc, v) => acc + v.score, 0) / verdicts.length\n return {\n dimensions: dims,\n composite,\n notes:\n violations.length === 0\n ? 'all trace contracts satisfied'\n : violations\n .slice(0, 8)\n .map((x) => `${x.rule}: ${x.detail}`)\n .join('\\n'),\n }\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'\nimport { evaluateTraceContract, type TraceContract } from './trace-contracts'\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 /** Evaluate a finite-trace temporal contract (`traceContract(...)`) over\n * this run's span sequence. See `trace-contracts.ts` for the operators. */\n toSatisfyContract(contract: TraceContract): Expectation {\n return {\n label: `agent(${this.runId}).toSatisfyContract(${contract.name})`,\n check: async () => {\n const spans = await this.store.spans({ runId: this.runId })\n const verdict = evaluateTraceContract(contract, spans)\n if (verdict.valid) {\n return { ok: true, detail: `contract \"${contract.name}\": ${verdict.notes}` }\n }\n return {\n ok: false,\n detail: verdict.violations.map((v) => `${v.rule}: ${v.detail}`).join('; '),\n evidence: verdict.violations.find((v) => v.spanId)?.spanId,\n }\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 * 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 {\n accessSync,\n existsSync,\n constants as fsConstants,\n readdirSync,\n readFileSync,\n statSync,\n} from 'node:fs'\nimport { delimiter, 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 return resolveBinOnPath(name) !== null\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 (err) {\n // ENOENT is the only \"legitimately absent\" signal → null. Any other\n // errno (EACCES, EISDIR, EIO, …) is a real failure that must NOT\n // masquerade as \"file not present\" — surface it so callers don't\n // treat a permission/IO error as a missing artifact.\n if (isErrnoCode(err, 'ENOENT')) return null\n throw err\n }\n },\n async readDir(path: string): Promise<DirEntry[]> {\n let entries: string[]\n try {\n entries = readdirSync(path)\n } catch (err) {\n // Same ENOENT-vs-real-error split as readFile: a missing directory\n // is legitimately empty (→ []); EACCES/ENOTDIR/EIO must surface so\n // an unreadable directory isn't silently reported as having no files.\n if (isErrnoCode(err, 'ENOENT')) return []\n throw err\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 (err) {\n // An entry that vanished between readdir and stat (TOCTOU) is a\n // benign race → skip. Any other errno surfaces.\n if (isErrnoCode(err, 'ENOENT')) continue\n throw err\n }\n }\n return out\n },\n}\n\nfunction isErrnoCode(err: unknown, code: NodeJS.ErrnoException['code']): boolean {\n return typeof err === 'object' && err !== null && (err as NodeJS.ErrnoException).code === code\n}\n\n/**\n * Resolve `name` to an executable absolute path using the runner's PATH,\n * or `null` if not found. Cross-platform: does not depend on `which`\n * (absent on Windows) or a `command -v` shell (absent on minimal\n * containers). On Windows, candidate extensions come from PATHEXT.\n *\n * Throws only on a non-ENOENT/EACCES filesystem error while probing a\n * candidate — those indicate a real IO fault, not \"binary absent.\"\n */\nfunction resolveBinOnPath(name: string): string | null {\n // An explicit path component means PATH lookup doesn't apply: probe directly.\n if (name.includes('/') || name.includes('\\\\')) {\n return isExecutable(name) ? name : null\n }\n const pathEnv = process.env.PATH ?? ''\n const dirs = pathEnv.split(delimiter).filter((d) => d.length > 0)\n const exts =\n process.platform === 'win32'\n ? (process.env.PATHEXT ?? '.COM;.EXE;.BAT;.CMD').split(';').filter((e) => e.length > 0)\n : ['']\n for (const dir of dirs) {\n for (const ext of exts) {\n const candidate = join(dir, name + ext)\n if (isExecutable(candidate)) return candidate\n }\n }\n return null\n}\n\nfunction isExecutable(path: string): boolean {\n try {\n // On win32 X_OK is a no-op; presence of the file (with a PATHEXT\n // extension) is the executability signal there.\n accessSync(path, process.platform === 'win32' ? fsConstants.F_OK : fsConstants.X_OK)\n return true\n } catch (err) {\n // Not found / not executable / not permitted → \"not a usable binary\n // here,\" keep scanning. A different errno (EIO, ELOOP, …) is a real\n // fault and must surface rather than silently yield a false negative.\n if (isErrnoCode(err, 'ENOENT') || isErrnoCode(err, 'EACCES') || isErrnoCode(err, 'ENOTDIR')) {\n return false\n }\n throw err\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 = 300_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 = re.exec(html)\n while (match !== 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 match = re.exec(html)\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\nimport type { DefaultVerdict } from './verdict'\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\n/** Extends the substrate verdict spine: `valid` = `allPass` and `score` =\n * `blendedScore` — derived where the report is aggregated, so spine\n * consumers (drivers, gates) read this report without an adapter. */\nexport interface VerificationReport extends DefaultVerdict {\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\n/**\n * Ordered DAG of verification layers with dependency-based skipping, per-layer findings, soft-fail semantics, and a blended composite score across all passed layers.\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 const allPass = ranAnyScoredLayer && !anyScoredLayerFailed && failCount === 0 && errorCount === 0\n const blendedScore = scoredWeightSum > 0 ? scoredWeightedTotal / scoredWeightSum : 0\n return {\n layers: results,\n passCount,\n failCount,\n skippedCount,\n errorCount,\n allPass,\n blendedScore,\n valid: allPass,\n score: blendedScore,\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 300s. */\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 ?? 300_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","import { gzipSync } from 'node:zlib'\nimport type { RunRecord } from './run-record'\n\n/**\n * DescriptionLengthGate — a Minimum-Description-Length promotion gate, the\n * Builder/Breaker acceptance rule from Wang & Buehler, \"Self-Revising Discovery\n * Systems for Science\" (arXiv:2606.01444, MIT LAMM), eq. 5:\n *\n * L(M, D) = L_model(M) + L_data(D | M)\n * accept M' over M iff L(M', D∪E) < L(M, D∪E)\n *\n * Both candidate and baseline are scored on the SAME enlarged evidence set\n * (every accumulated task — NOT just the held-out split), and the candidate is\n * accepted only if it lowers the TOTAL bit cost. This is the gate's whole\n * point and what distinguishes it from a monotone held-out delta:\n *\n * - L_model(M) — the candidate's own description length: the compressed size\n * of its model text (a prompt, skill, profile, or symbolic model). A bigger\n * model pays more bits.\n * - L_data(D|M) — the residual: bits of \"surprise\" that the model did not\n * simply succeed, −Σ_i log2(s_i) over the model's per-task score s_i.\n * Perfect scores cost 0 bits; failure costs a lot (capped, not infinite).\n *\n * A candidate that merely memorizes new counterexamples grows L_model faster\n * than it shrinks L_data and LOSES — a principled, complexity-penalized\n * alternative to HeldOutGate's held-out paired delta. Use this gate\n * when the model text whose size you want to penalize is available; use\n * HeldOutGate when promotion should turn on held-out generalization with an\n * overfit-gap check instead.\n *\n * Scale / calibration: a gzip'd prose model is hundreds–thousands of bits;\n * a single task contributes at most −log2(scoreFloor) data bits (≈10). So with\n * little evidence the model term dominates and the gate is conservative about\n * model GROWTH — it promotes a larger model only once accumulated evidence\n * genuinely pays for the added bits (exactly the paper's regime, where D∪E\n * grows). `lambda` is the lever: λ<1 discounts model bits (more permissive),\n * λ>1 is stricter. A shrinking-or-equal model that does no worse always wins.\n *\n * Stateless: construct once with the description-length budget, call\n * `evaluate` per (candidate, baseline) pair.\n */\n\nexport type DescriptionLengthRejectionCode = 'few_tasks' | 'no_total_gain' | 'model_bloat'\n\nexport interface DescriptionLengthConfig {\n /** Stable label of the baseline. Required — paper-grade evaluation never\n * compares two unlabelled candidates. */\n baselineKey: string\n /** Weight on model bits relative to data bits (the description-length\n * budget λ). 1 = bits are bits. >1 = more complexity-averse. Default 1. */\n lambda?: number\n /** The candidate must beat the baseline by at least this many bits to\n * promote — a robustness margin against measurement noise. Default 0\n * (strict `<`, as the paper). */\n marginBits?: number\n /** Per-task score floor for the residual code: −log2(max(s, floor)). Caps a\n * total-failure task's surprise instead of letting it diverge. Default\n * 2^-10 (a failed task costs 10 bits, not ∞). */\n scoreFloor?: number\n /** Minimum number of shared (candidate, baseline) tasks before the gate will\n * consider promoting. Default 3. */\n minTasks?: number\n}\n\nexport interface DescriptionLengthEvidence {\n /** Shared tasks scored on both sides (the enlarged evidence D∪E). */\n tasks: number\n /** Compressed-model bits — L_model. */\n modelBits: { candidate: number; baseline: number }\n /** Residual surprise bits — L_data(D|M). */\n dataBits: { candidate: number; baseline: number }\n /** λ·L_model + L_data — the quantity the gate minimizes. */\n totalBits: { candidate: number; baseline: number }\n /** candidate − baseline total. Negative = candidate compresses better. */\n deltaBits: number\n /** Per-component deltas, for audit: did the win come from a smaller model,\n * better outcomes, or both? */\n modelBitsDelta: number\n dataBitsDelta: number\n}\n\nexport interface DescriptionLengthDecision {\n promote: boolean\n candidateId: string\n baselineId: string\n evidence: DescriptionLengthEvidence\n reason: string\n rejectionCode: DescriptionLengthRejectionCode | null\n}\n\nexport interface DescriptionLengthCandidate {\n /** The model text whose size is L_model (a prompt, skill, profile, or\n * symbolic model; concatenated if several files). */\n content: string\n /** Runs whose per-task scores form L_data. */\n runs: RunRecord[]\n}\n\n/** Score a single run, preferring the held-out score, then search, then the\n * raw `score` metric. Returns undefined when the run carries no score. */\nfunction runScore(run: RunRecord): number | undefined {\n const o = run.outcome\n const s = o.holdoutScore ?? o.searchScore ?? o.raw?.score\n return typeof s === 'number' && Number.isFinite(s) ? s : undefined\n}\n\n/** Pairing key — the same scenario/experiment identity HeldOutGate pairs on. */\nfunction taskKey(run: RunRecord): string {\n return run.scenarioId ?? run.experimentId\n}\n\n/** Mean per-task score for a model: { taskKey -> mean(score over its runs) }. */\nfunction perTaskMeanScore(runs: RunRecord[]): Map<string, number> {\n const acc = new Map<string, { sum: number; n: number }>()\n for (const run of runs) {\n const s = runScore(run)\n if (s === undefined) continue\n const key = taskKey(run)\n const cur = acc.get(key) ?? { sum: 0, n: 0 }\n cur.sum += s\n cur.n += 1\n acc.set(key, cur)\n }\n return new Map([...acc].map(([k, v]) => [k, v.sum / v.n]))\n}\n\n/** Compressed-model bits — the model's description length L_model. gzip is a\n * deterministic, dependency-free stand-in for Kolmogorov complexity; it\n * rewards genuine compactness and penalizes boilerplate padding. */\nexport function modelDescriptionBits(content: string): number {\n return gzipSync(Buffer.from(content, 'utf8')).byteLength * 8\n}\n\n/** Residual surprise L_data(D|M) = −Σ_i log2(max(s_i, floor)) over the given\n * per-task scores. Lower = the model more reliably succeeds. */\nexport function dataDescriptionBits(\n scoreByTask: Map<string, number>,\n keys: Iterable<string>,\n scoreFloor: number,\n): number {\n let bits = 0\n for (const key of keys) {\n const s = scoreByTask.get(key)\n if (s === undefined) continue\n bits += -Math.log2(Math.max(s, scoreFloor))\n }\n return bits\n}\n\nexport class DescriptionLengthGate {\n private readonly baselineKey: string\n private readonly lambda: number\n private readonly marginBits: number\n private readonly scoreFloor: number\n private readonly minTasks: number\n\n constructor(config: DescriptionLengthConfig) {\n if (!config.baselineKey) throw new Error('DescriptionLengthGate: baselineKey is required')\n this.baselineKey = config.baselineKey\n this.lambda = config.lambda ?? 1\n this.marginBits = config.marginBits ?? 0\n this.scoreFloor = config.scoreFloor ?? 2 ** -10\n this.minTasks = config.minTasks ?? 3\n if (!(this.lambda >= 0)) throw new Error('DescriptionLengthGate: lambda must be ≥ 0')\n if (!(this.scoreFloor > 0 && this.scoreFloor < 1))\n throw new Error('DescriptionLengthGate: scoreFloor must be in (0,1)')\n }\n\n /** Decide whether `candidate` should replace `baseline`. Both are scored on\n * the shared task set (the enlarged evidence); the candidate promotes only\n * if λ·L_model + L_data is strictly lower by at least `marginBits`. */\n evaluate(\n candidate: DescriptionLengthCandidate,\n baseline: DescriptionLengthCandidate,\n ): DescriptionLengthDecision {\n const candidateId = inferCandidateId(candidate.runs, this.baselineKey)\n const candScores = perTaskMeanScore(candidate.runs)\n const baseScores = perTaskMeanScore(baseline.runs)\n // Enlarged evidence = tasks scored on BOTH sides (paired, like the paper's\n // \"both models refit on the same accumulated evidence\").\n const shared = [...candScores.keys()].filter((k) => baseScores.has(k))\n\n const modelBits = {\n candidate: this.lambda * modelDescriptionBits(candidate.content),\n baseline: this.lambda * modelDescriptionBits(baseline.content),\n }\n const dataBits = {\n candidate: dataDescriptionBits(candScores, shared, this.scoreFloor),\n baseline: dataDescriptionBits(baseScores, shared, this.scoreFloor),\n }\n const totalBits = {\n candidate: modelBits.candidate + dataBits.candidate,\n baseline: modelBits.baseline + dataBits.baseline,\n }\n const evidence: DescriptionLengthEvidence = {\n tasks: shared.length,\n modelBits,\n dataBits,\n totalBits,\n deltaBits: totalBits.candidate - totalBits.baseline,\n modelBitsDelta: modelBits.candidate - modelBits.baseline,\n dataBitsDelta: dataBits.candidate - dataBits.baseline,\n }\n const base = { candidateId, baselineId: this.baselineKey, evidence }\n const fmt = (n: number) => n.toFixed(1)\n\n if (shared.length < this.minTasks) {\n return {\n ...base,\n promote: false,\n reason: `few_tasks: ${shared.length} shared task(s) < min ${this.minTasks}`,\n rejectionCode: 'few_tasks',\n }\n }\n if (!(evidence.deltaBits < -this.marginBits)) {\n // No net compression. Name the cause: did the model bloat eat a real\n // data gain, or was there no data gain at all?\n const code: DescriptionLengthRejectionCode =\n evidence.dataBitsDelta < 0 ? 'model_bloat' : 'no_total_gain'\n const why =\n code === 'model_bloat'\n ? `model grew ${fmt(evidence.modelBitsDelta)} bits, outpacing a ${fmt(-evidence.dataBitsDelta)}-bit data gain`\n : `outcomes did not improve (data Δ=${fmt(evidence.dataBitsDelta)} bits)`\n return {\n ...base,\n promote: false,\n reason: `${code}: total Δ=${fmt(evidence.deltaBits)} bits does not clear the ${fmt(this.marginBits)}-bit margin — ${why}`,\n rejectionCode: code,\n }\n }\n return {\n ...base,\n promote: true,\n reason: `promote: total Δ=${fmt(evidence.deltaBits)} bits (model Δ=${fmt(evidence.modelBitsDelta)}, data Δ=${fmt(evidence.dataBitsDelta)}) over ${shared.length} tasks`,\n rejectionCode: null,\n }\n }\n}\n\nfunction inferCandidateId(runs: RunRecord[], baselineKey: string): string {\n for (const run of runs)\n if (run.candidateId && run.candidateId !== baselineKey) return run.candidateId\n return runs[0]?.candidateId ?? '(unknown candidate)'\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 * 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 interface Waiter {\n resolve: (s: SlotState<T>) => void\n reject: (err: unknown) => void\n }\n const waiters: Waiter[] = []\n const mutex = new Mutex()\n let nextSlotId = 0\n // In-flight mints: a slot is decided under the mutex but only push()ed into\n // `slots` AFTER the un-locked factory.create(). Counting reservations against\n // capacity in the SAME critical section as the gate stops two concurrent\n // acquires from both minting past `size` (slots.length alone is still 0 for\n // both until the first push lands).\n let reserving = 0\n let totalCheckouts = 0\n let busyMs = 0\n let drained = false\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 + reserving < opts.size) {\n // Reserve capacity synchronously (live slots + in-flight mints) so\n // concurrent acquireSlot calls can't all decide to mint past the cap.\n mintId = `slot_${nextSlotId++}`\n reserving++\n return null\n }\n return null\n })\n if (ready) return ready\n if (mintId !== undefined) {\n let resource: T\n try {\n resource = await opts.factory.create(mintId)\n } catch (err) {\n // Release the reservation and hand the freed capacity to a waiter,\n // otherwise a failed create leaks a capacity slot forever.\n await mutex.runExclusive(() => {\n reserving--\n })\n if (!drained) wakeWaiterToMint()\n throw err\n }\n const state: SlotState<T> = {\n slot: { id: mintId, resource },\n busy: true,\n }\n await mutex.runExclusive(() => {\n slots.push(state)\n reserving--\n })\n return state\n }\n // All slots busy + at cap: queue.\n return new Promise<SlotState<T>>((resolve, reject) => {\n waiters.push({ resolve, reject })\n })\n }\n\n /**\n * Hand `state` (clean + idle) to the next queued waiter, or leave it\n * idle if none are waiting. Caller must have already marked the slot\n * not-busy. Runs under no lock; waiters are FIFO.\n */\n function handOffCleanSlot(state: SlotState<T>): void {\n const next = waiters.shift()\n if (next) {\n state.busy = true\n next.resolve(state)\n }\n }\n\n /**\n * Wake a queued waiter when a slot was destroyed (so capacity freed up\n * but no clean slot is on hand). The waiter re-enters acquisition and\n * mints a fresh slot. Any acquisition failure is routed to that waiter\n * — never dropped on the floor.\n */\n function wakeWaiterToMint(): void {\n const next = waiters.shift()\n if (!next) return\n acquireSlot().then(next.resolve, next.reject)\n }\n\n /**\n * Release a checked-out slot. Reset is async; we kick it off and the\n * slot only becomes available to the next waiter once reset lands\n * CLEAN. If reset fails, the slot is dirty — destroy and remove it\n * rather than recycle a corrupted workspace to the next waiter, then\n * free the capacity so a fresh slot can be minted. The whole flow is\n * awaited inside one IIFE whose rejection is caught, so a failed\n * destroy can't surface as an unhandled rejection.\n */\n function releaseSlot(state: SlotState<T>): void {\n void (async () => {\n try {\n if (opts.factory.reset) {\n await opts.factory.reset(state.slot)\n }\n state.busy = false\n if (!drained) handOffCleanSlot(state)\n } catch (resetErr) {\n // Dirty slot: do NOT recycle it. Remove from the pool and tear it\n // down, then wake a waiter to mint a clean replacement.\n await mutex.runExclusive(() => {\n const i = slots.indexOf(state)\n if (i !== -1) slots.splice(i, 1)\n })\n try {\n await opts.factory.destroy(state.slot)\n } catch (destroyErr) {\n console.warn(\n `[sandbox-pool] destroy of dirty slot ${state.slot.id} failed after reset error:`,\n destroyErr,\n )\n }\n console.warn(\n `[sandbox-pool] reset failed for slot ${state.slot.id} — slot destroyed, not recycled:`,\n resetErr,\n )\n if (!drained) wakeWaiterToMint()\n }\n })().catch((err) => {\n // Defense in depth: nothing above should throw out here, but if it\n // does, surface it instead of producing an unhandled rejection.\n console.warn(`[sandbox-pool] release of slot ${state.slot.id} faulted:`, err)\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 drained = true\n // Snapshot under lock; destroy outside lock so a slow teardown\n // doesn't block a concurrent drain caller.\n const { snapshot, pending } = await mutex.runExclusive(() => {\n const taken = slots.splice(0, slots.length)\n const queued = waiters.splice(0, waiters.length)\n return { snapshot: taken, pending: queued }\n })\n // Reject any pending waiters — the pool is going away, so their\n // checkout promise can never be satisfied. Failing loud beats leaving\n // a caller hung on an awaited checkout() forever.\n for (const w of pending) {\n w.reject(new Error('sandbox pool drained while a checkout was pending'))\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\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 { JudgeParseError } from './judges'\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 let failedJudges = 0\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 try {\n const scores = await tracedFn(tc, input)\n allScores.push(...scores)\n } catch (err) {\n // One unparseable judge must not sink the whole ensemble — its\n // child span is already marked failed by traceJudge; record it and\n // keep scoring with the surviving judges. Anything else (network,\n // abort) still aborts the ensemble.\n if (!(err instanceof JudgeParseError)) throw err\n failedJudges++\n }\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 'judge.failed_judges': failedJudges,\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","/**\n * Agreement judge for teacher→student distillation. Scores a STUDENT artifact\n * (the cheap analyst's produced label) against the GoldScenario's gold label\n * (the teacher's verdict). The score IS the distillation objective: 1.0 means\n * the student reproduced the teacher exactly, 0.0 means total disagreement.\n *\n * The comparison function is INJECTED (`compareLabels`) so the judge is\n * domain-agnostic — distilling a skill-audit analyst, a triage analyst, or any\n * other student is a one-line comparator swap. A default `fieldAgreement`\n * comparator is provided for the common case: a flat verdict object with\n * categorical and array fields.\n *\n * Everything here is PURE + unit-testable — no LLM. (The student spends tokens\n * producing the artifact; scoring it against frozen gold does not.)\n */\n\nimport type { JudgeConfig, JudgeScore, Scenario } from '../types'\nimport type { GoldScenario } from './gold-scenarios'\n\n/** What an injected comparator returns: a [0,1] composite plus the per-field\n * (per-dimension) agreement breakdown the GEPA proposer reflects on to learn\n * WHICH part of the verdict the student is getting wrong. */\nexport interface AgreementResult {\n /** Overall agreement in [0,1]. */\n score: number\n /** Per-dimension agreement in [0,1] — keyed by field/aspect name. The\n * reflective proposer surfaces the weakest of these as the lever to fix. */\n dimensions: Record<string, number>\n}\n\n/** Compare a produced label against a gold label → agreement. Injected so the\n * judge is domain-agnostic. */\nexport type CompareLabels<TProduced = unknown, TLabel = unknown> = (\n produced: TProduced,\n gold: TLabel,\n) => AgreementResult\n\nexport interface BuildAgreementJudgeOptions<TProduced = unknown, TLabel = unknown> {\n /** Judge name surfaced in `CampaignResult.aggregates.byJudge` + the gate. */\n name?: string\n /** The agreement function — produced student label vs gold teacher label. */\n compareLabels: CompareLabels<TProduced, TLabel>\n /** Dimension keys the judge declares up-front (for `JudgeConfig.dimensions`).\n * When omitted, the dimensions present on the first scored result are used\n * for display only; the composite is unaffected. */\n dimensionKeys?: string[]\n /** Only score `gold`-kind scenarios. Default true — a mixed campaign won't\n * mis-apply the agreement judge to non-gold scenarios. */\n goldOnly?: boolean\n}\n\nconst AGREEMENT_DIM = 'agreement'\n\n/** Build a `JudgeConfig` that scores a produced student artifact against the\n * scenario's gold label. Conforms to the substrate `JudgeConfig` contract:\n * `score({artifact, scenario, signal}) => JudgeScore`. The `composite` is the\n * comparator's `score`; `dimensions` carries its per-field breakdown plus the\n * scalar `agreement` so a single-dimension consumer still sees the number. */\nexport function buildAgreementJudge<TProduced, TInput, TLabel>(\n options: BuildAgreementJudgeOptions<TProduced, TLabel>,\n): JudgeConfig<TProduced, GoldScenario<TInput, TLabel>> {\n const name = options.name ?? 'gold-agreement'\n const goldOnly = options.goldOnly ?? true\n const declaredDims = options.dimensionKeys ?? [AGREEMENT_DIM]\n return {\n name,\n dimensions: declaredDims.map((key) => ({\n key,\n description: `Per-field agreement between the produced label and the gold label on '${key}'`,\n })),\n appliesTo: goldOnly ? (scenario: Scenario) => scenario.kind === 'gold' : undefined,\n score({ artifact, scenario }): JudgeScore {\n const { score, dimensions } = options.compareLabels(artifact, scenario.label)\n if (!Number.isFinite(score) || score < 0 || score > 1) {\n throw new Error(\n `buildAgreementJudge: comparator returned out-of-range score ${score} for scenario '${scenario.id}' (must be in [0,1])`,\n )\n }\n // Surface the scalar under `agreement` too, so a consumer reading a\n // single dimension always finds the headline number even when the\n // comparator named its fields differently.\n const outDims: Record<string, number> = { [AGREEMENT_DIM]: score, ...dimensions }\n const weakest = Object.entries(dimensions).sort((a, b) => a[1] - b[1])[0]\n const notes = weakest\n ? `agreement ${score.toFixed(3)}; weakest field '${weakest[0]}' (${weakest[1].toFixed(3)})`\n : `agreement ${score.toFixed(3)}`\n return { composite: score, dimensions: outDims, notes }\n },\n }\n}\n\nexport interface FieldAgreementSpec {\n /** Categorical fields — scored exact-match (1 if equal, else 0). Compared\n * with `===` after `JSON`-normalizing so `true`/`'high'`/`3` all work. */\n categorical?: string[]\n /** Array fields — scored by Jaccard overlap (|A∩B| / |A∪B|). Two empty\n * arrays agree perfectly (1.0). Order-insensitive; elements compared by\n * their `JSON.stringify`. */\n array?: string[]\n}\n\n/** Default comparator: average per-field agreement over a flat verdict object.\n * Categorical fields score exact-match; array fields score set-overlap\n * (Jaccard). The composite is the unweighted mean across all declared fields,\n * so missing a single boolean (e.g. `public_leak_risk`) costs `1/nFields` of\n * the score — the leak-detection lever the audit cares about is a real,\n * non-trivial fraction of the objective, not rounding noise.\n *\n * Pure. A field absent from BOTH produced + gold is treated as agreeing\n * (both undefined ⇒ 1.0); a field present in only one side disagrees. */\nexport function fieldAgreement<TProduced extends Record<string, unknown>, TLabel>(\n spec: FieldAgreementSpec,\n): CompareLabels<TProduced, TLabel> {\n const categorical = spec.categorical ?? []\n const array = spec.array ?? []\n if (categorical.length === 0 && array.length === 0) {\n throw new Error('fieldAgreement: at least one categorical or array field is required')\n }\n return (produced, gold) => {\n const p = (produced ?? {}) as Record<string, unknown>\n const g = (gold ?? {}) as Record<string, unknown>\n const dimensions: Record<string, number> = {}\n for (const field of categorical) {\n dimensions[field] = categoricalAgreement(p[field], g[field])\n }\n for (const field of array) {\n dimensions[field] = jaccard(asArray(p[field]), asArray(g[field]))\n }\n const values = Object.values(dimensions)\n const score = values.length === 0 ? 0 : values.reduce((a, b) => a + b, 0) / values.length\n return { score, dimensions }\n }\n}\n\nfunction categoricalAgreement(produced: unknown, gold: unknown): number {\n if (produced === undefined && gold === undefined) return 1\n // Normalize so primitives compare by value regardless of source typing\n // (e.g. a produced boolean vs a gold boolean parsed from JSON).\n return normalizeScalar(produced) === normalizeScalar(gold) ? 1 : 0\n}\n\nfunction normalizeScalar(value: unknown): string {\n // Sentinels carry a leading '\\0'-free marker JSON.stringify never produces\n // (its output of any value starts with a quote, brace, bracket, digit, or\n // -/t/f/n) so they can't collide with a real stringified value.\n if (value === undefined) return '__undefined__'\n if (value === null) return '__null__'\n return JSON.stringify(value)\n}\n\nfunction asArray(value: unknown): unknown[] {\n if (Array.isArray(value)) return value\n if (value === undefined || value === null) return []\n return [value]\n}\n\n/** Jaccard similarity over two multisets compared by `JSON.stringify` of each\n * element. Two empty sets ⇒ 1.0 (perfect agreement on \"nothing\"). */\nfunction jaccard(a: unknown[], b: unknown[]): number {\n const sa = new Set(a.map((x) => JSON.stringify(x)))\n const sb = new Set(b.map((x) => JSON.stringify(x)))\n if (sa.size === 0 && sb.size === 0) return 1\n let inter = 0\n for (const x of sa) if (sb.has(x)) inter++\n const union = sa.size + sb.size - inter\n return union === 0 ? 1 : inter / union\n}\n","/**\n * Gold scenarios for teacher→student distillation. The TEACHER is an\n * expensive workflow (e.g. the 70-agent skill audit) whose verdicts are\n * frozen as gold labels; the STUDENT is a cheap single-shot analyst whose\n * prompt GEPA optimizes toward reproducing those labels.\n *\n * A `GoldScenario` is a `Scenario` (the substrate's input contract) carrying\n * an OPAQUE `input` (what the student sees) and an OPAQUE `label` (the gold\n * verdict the student's output is scored against). Both are typed `unknown`\n * here: this module is domain-agnostic — it distills ANY analyst against ANY\n * gold JSONL. The agreement comparator (see `agreement-judge.ts`) is what\n * knows the label's shape.\n *\n * Loading + splitting are DETERMINISTIC and LLM-free: the gold set is the\n * fixed ground truth, never regenerated here.\n */\n\nimport { readFileSync } from 'node:fs'\nimport type { Scenario } from '../types'\n\n/** A held gold record: opaque student-input + opaque gold-label, carried as a\n * substrate `Scenario` so it flows through `runCampaign` unchanged. */\nexport interface GoldScenario<TInput = unknown, TLabel = unknown> extends Scenario {\n kind: 'gold'\n /** What the student analyst is shown (rendered into its user prompt). */\n input: TInput\n /** The teacher's gold verdict — the target the student's output is scored\n * against by the agreement judge. NEVER shown to the student. */\n label: TLabel\n}\n\n/** One raw JSONL line. `scenarioId` and `id` are both accepted (the audit\n * emits `scenarioId`); `split` is honored when present. */\ninterface GoldJsonlLine {\n scenarioId?: string\n id?: string\n input: unknown\n label: unknown\n split?: 'train' | 'test'\n}\n\n/** Read a gold JSONL (one `{scenarioId|id, input, label, split?}` per line) into\n * `GoldScenario[]`. Deterministic, no LLM. Blank lines are skipped; a line\n * missing an id, `input`, or `label` throws (a silent skip would corrupt the\n * split silently — fail loud on a malformed gold set). */\nexport function loadGoldScenarios<TInput = unknown, TLabel = unknown>(\n jsonlPath: string,\n): GoldScenario<TInput, TLabel>[] {\n const text = readFileSync(jsonlPath, 'utf8')\n return parseGoldJsonl<TInput, TLabel>(text, jsonlPath)\n}\n\n/** Parse gold JSONL text directly (no fs). Exported so tests + in-memory\n * callers exercise the same parse path as {@link loadGoldScenarios}. */\nexport function parseGoldJsonl<TInput = unknown, TLabel = unknown>(\n text: string,\n sourceLabel = '<inline>',\n): GoldScenario<TInput, TLabel>[] {\n const out: GoldScenario<TInput, TLabel>[] = []\n const lines = text.split('\\n')\n for (let i = 0; i < lines.length; i++) {\n const raw = lines[i]!.trim()\n if (raw.length === 0) continue\n let parsed: GoldJsonlLine\n try {\n parsed = JSON.parse(raw) as GoldJsonlLine\n } catch (err) {\n throw new Error(\n `loadGoldScenarios: ${sourceLabel}:${i + 1} is not valid JSON — ${\n err instanceof Error ? err.message : String(err)\n }`,\n )\n }\n const rawId = parsed.scenarioId ?? parsed.id\n if (typeof rawId !== 'string' || rawId.length === 0) {\n throw new Error(\n `loadGoldScenarios: ${sourceLabel}:${i + 1} missing string \\`scenarioId\\`/\\`id\\``,\n )\n }\n // runCampaign forms the cellId as `${scenario.id}:${rep}` and heldOutGate\n // recovers the scenarioId via `cellId.split(':')[0]`. A ':' in the id (the\n // real skill-audit gold uses ids like `skill:blueprint-launch`) would\n // collapse every scenario into the first segment's bucket and zero the\n // holdout delta. Sanitize ':' → '__' for the campaign id; the original is\n // preserved on the scenario for display + traceback.\n const id = rawId.replace(/:/g, '__')\n if (parsed.input === undefined) {\n throw new Error(`loadGoldScenarios: ${sourceLabel}:${i + 1} (${rawId}) missing \\`input\\``)\n }\n if (parsed.label === undefined) {\n throw new Error(`loadGoldScenarios: ${sourceLabel}:${i + 1} (${rawId}) missing \\`label\\``)\n }\n const scenario: GoldScenario<TInput, TLabel> = {\n id,\n kind: 'gold',\n input: parsed.input as TInput,\n label: parsed.label as TLabel,\n }\n const tags: string[] = []\n if (id !== rawId) tags.push(`gold-id:${rawId}`)\n if (parsed.split !== undefined) tags.push(`split:${parsed.split}`)\n if (tags.length > 0) scenario.tags = tags\n out.push(scenario)\n }\n if (out.length === 0) {\n throw new Error(`loadGoldScenarios: ${sourceLabel} contained no gold records`)\n }\n return out\n}\n\nexport interface SplitGoldOptions {\n /** Every Nth scenario (0-based index) goes to the TEST/holdout split; the\n * rest train. Default 4 ⇒ a 25% holdout. Ignored for any scenario that\n * carries an explicit `split:` tag (that is honored verbatim). */\n testEveryNth?: number\n}\n\nexport interface GoldSplit<TInput, TLabel> {\n /** Training scenarios — the optimization pool the proposer searches over. */\n train: GoldScenario<TInput, TLabel>[]\n /** Held-out scenarios — kept OUT of training; scored only at the gate. */\n test: GoldScenario<TInput, TLabel>[]\n}\n\n/** Deterministic train/test split. A scenario tagged `split:train|test` is\n * routed by that tag; the rest fall to a modulo split (`index % testEveryNth\n * === 0 ⇒ test`). Pure — same input always yields the same split, so a gold\n * set's holdout is stable across runs (a shuffled split would let a lucky\n * seed flatter the gate). */\nexport function splitGold<TInput, TLabel>(\n scenarios: GoldScenario<TInput, TLabel>[],\n options: SplitGoldOptions = {},\n): GoldSplit<TInput, TLabel> {\n const testEveryNth = options.testEveryNth ?? 4\n if (!Number.isInteger(testEveryNth) || testEveryNth < 2) {\n throw new Error('splitGold: testEveryNth must be an integer ≥ 2 (else train or test is empty)')\n }\n const train: GoldScenario<TInput, TLabel>[] = []\n const test: GoldScenario<TInput, TLabel>[] = []\n let implicitIndex = 0\n for (const scenario of scenarios) {\n const explicit = explicitSplit(scenario)\n if (explicit === 'train') {\n train.push(scenario)\n } else if (explicit === 'test') {\n test.push(scenario)\n } else {\n // Only implicit scenarios are counted for the modulo, so honoring some\n // explicit tags doesn't skew the deterministic stride of the rest.\n if (implicitIndex % testEveryNth === 0) test.push(scenario)\n else train.push(scenario)\n implicitIndex += 1\n }\n }\n return { train, test }\n}\n\nfunction explicitSplit(scenario: GoldScenario): 'train' | 'test' | undefined {\n for (const tag of scenario.tags ?? []) {\n if (tag === 'split:train') return 'train'\n if (tag === 'split:test') return 'test'\n }\n return undefined\n}\n","/**\n * `runDistillation` — the teacher→student distillation loop. COMPOSES existing\n * substrate primitives; reimplements none of them:\n *\n * - DRIVER = `gepaProposer` (reflective prompt optimizer)\n * - LOOP = `runImprovementLoop` (outer: optimize → holdout re-score → gate)\n * - MEASUREMENT = `runCampaign` (inside the loop) scoring the student\n * - JUDGE = `buildAgreementJudge` — student label vs gold teacher label\n * - GATE = caller-supplied (`heldOutGate` / `defaultProductionGate`)\n * - STUDENT = a cheap single-shot analyst whose system prompt is the\n * `MutableSurface` GEPA mutates; it calls the LLM through\n * `createChatClient` and emits a JSON label.\n *\n * The surface IS the student's system prompt. Each generation GEPA rewrites it;\n * `dispatchWithSurface` renders {surface + scenario.input} into a chat request,\n * calls the (cheap) model, parses the produced JSON label, and returns it as\n * the artifact. The agreement judge scores that label against the gold label.\n *\n * `autoOnPromote: 'none'` is FORCED — the loop never opens a PR; the caller\n * (the `distill` CLI) decides what to do with the winning prompt.\n */\n\nimport {\n type ChatRequest,\n type ChatResponse,\n type CreateChatClientOpts,\n createChatClient,\n} from '../../analyst/chat-client'\nimport type { LlmCallResult, LlmClientOptions } from '../../llm-client'\nimport { heldOutGate } from '../gates/heldout-gate'\nimport { type RunImprovementLoopResult, runImprovementLoop } from '../presets/run-improvement-loop'\nimport { type GepaProposerConstraints, gepaProposer } from '../proposers/gepa'\nimport { campaignMeanComposite } from '../score-utils'\nimport type { CampaignResult, Gate, JudgeConfig } from '../types'\nimport type { GoldScenario } from './gold-scenarios'\n\n/** Render the student's prompt from {current surface, scenario input}. The\n * surface is the system prompt; the scenario input is the user turn. Override\n * to inject few-shot framing or a JSON-schema reminder. */\nexport type RenderStudentPrompt<TInput> = (args: {\n surface: string\n input: TInput\n scenarioId: string\n}) => ChatRequest['messages']\n\n/** Parse the model's raw text into a typed produced label. Throws on\n * unparseable output — a thrown dispatch is recorded as a failed cell (never\n * silently scored 0), which is the honest signal that the prompt isn't\n * emitting valid JSON yet. */\nexport type ParseStudentLabel<TProduced> = (rawContent: string, scenarioId: string) => TProduced\n\nexport interface RunDistillationOptions<TProduced, TInput, TLabel> {\n /** The student analyst's INITIAL system prompt — the baseline surface GEPA\n * searches from. */\n baselinePrompt: string\n /** Training scenarios (the optimization pool). */\n train: GoldScenario<TInput, TLabel>[]\n /** Held-out scenarios — kept OUT of training; scored only at the gate. */\n holdout: GoldScenario<TInput, TLabel>[]\n /** Transport for BOTH the student (cheap model) and the GEPA reflection\n * (the optimizer model). The student calls it via `createChatClient`. */\n llm: CreateChatClientOpts\n /** Router transport the GEPA proposer reflects through. `gepaProposer` uses the\n * package `LlmClient` directly (`LlmClientOptions`), not the ChatClient —\n * pass the router creds here. A test may inject `fetch` to stub the\n * reflection HTTP and exercise the wiring without real tokens. */\n reflectionLlm: LlmClientOptions\n /** Cheap model the student runs (e.g. a small/fast model). */\n studentModel: string\n /** Model GEPA uses to propose prompt rewrites (typically a stronger model). */\n optimizerModel: string\n /** Agreement judge — produced student label vs gold teacher label. */\n judge: JudgeConfig<TProduced, GoldScenario<TInput, TLabel>>\n /** Promotion gate. Default: `heldOutGate` over the holdout. Pass\n * `defaultProductionGate({ holdoutScenarios: holdout, ... })` for the full\n * red-team / reward-hacking / canary stack. */\n gate?: Gate<TProduced, GoldScenario<TInput, TLabel>>\n /** GEPA population size (candidates per generation). Default 4. */\n populationSize?: number\n /** GEPA generations. Default 3. */\n maxGenerations?: number\n /** Campaign reps per scenario. Default 1 — raise for CI bands on a flaky\n * student. */\n reps?: number\n /** Where campaign artifacts + traces land. Default a temp dir under cwd. */\n runDir?: string\n /** Levers offered to the GEPA reflection prompt. */\n mutationPrimitives?: string[]\n /** GEPA structured-doc constraints (preserve sections, edit budget). */\n constraints?: GepaProposerConstraints\n /** Gate's minimum holdout-agreement delta to ship. Default 0.0 — a\n * distillation run reports the lift; the caller decides the bar. Only used\n * when `gate` is omitted (the default `heldOutGate`). */\n deltaThreshold?: number\n /** Render the student prompt. Default: surface as system, JSON-stringified\n * input as the user turn with a JSON-only instruction. */\n renderStudentPrompt?: RenderStudentPrompt<TInput>\n /** Parse the model's text into a produced label. Default: strict JSON parse\n * with fenced-block stripping. */\n parseStudentLabel?: ParseStudentLabel<TProduced>\n /** Per-student-call sampling temperature. Default 0 (deterministic student;\n * the optimization signal must come from the PROMPT, not sampling noise). */\n studentTemperature?: number\n /** Per-student-call max tokens. Default 1024. */\n studentMaxTokens?: number\n}\n\nexport interface RunDistillationResult<TProduced, TInput, TLabel>\n extends RunImprovementLoopResult<TProduced, GoldScenario<TInput, TLabel>> {\n /** The winning student prompt (a string surface). */\n winnerPrompt: string\n /** Mean agreement on the HOLDOUT — baseline vs winner. The headline number:\n * did distillation move the student closer to the teacher on UNSEEN gold? */\n holdoutAgreement: { baseline: number; winner: number; delta: number }\n}\n\nexport async function runDistillation<TProduced, TInput, TLabel>(\n opts: RunDistillationOptions<TProduced, TInput, TLabel>,\n): Promise<RunDistillationResult<TProduced, TInput, TLabel>> {\n if (opts.train.length === 0) throw new Error('runDistillation: train split is empty')\n if (opts.holdout.length === 0) throw new Error('runDistillation: holdout split is empty')\n\n const chat = createChatClient(opts.llm)\n const render = opts.renderStudentPrompt ?? defaultRenderStudentPrompt\n const parse = opts.parseStudentLabel ?? (defaultParseStudentLabel as ParseStudentLabel<TProduced>)\n const runDir = opts.runDir ?? `.evolve/distillation/${Date.now()}`\n const studentTemperature = opts.studentTemperature ?? 0\n const studentMaxTokens = opts.studentMaxTokens ?? 1024\n\n const proposer = gepaProposer({\n llm: opts.reflectionLlm,\n model: opts.optimizerModel,\n target:\n 'a cheap single-shot analyst system prompt that reproduces an expensive workflow gold verdict',\n mutationPrimitives: opts.mutationPrimitives ?? DEFAULT_MUTATION_PRIMITIVES,\n constraints: opts.constraints,\n })\n\n const gate =\n opts.gate ??\n heldOutGate<TProduced, GoldScenario<TInput, TLabel>>({\n scenarios: opts.holdout,\n deltaThreshold: opts.deltaThreshold ?? 0,\n })\n\n const loop = await runImprovementLoop<GoldScenario<TInput, TLabel>, TProduced>({\n baselineSurface: opts.baselinePrompt,\n scenarios: opts.train,\n holdoutScenarios: opts.holdout,\n judges: [opts.judge],\n proposer,\n gate,\n autoOnPromote: 'none', // the loop NEVER opens a PR — the caller decides\n populationSize: opts.populationSize ?? 4,\n maxGenerations: opts.maxGenerations ?? 3,\n reps: opts.reps ?? 1,\n runDir,\n // The student spends tokens; tracing must stay on (the proposer is wired and\n // runImprovementLoop refuses tracing='off' with a proposer).\n tracing: 'on',\n dispatchWithSurface: async (surface, scenario, ctx) => {\n const prompt = render({\n surface: typeof surface === 'string' ? surface : JSON.stringify(surface),\n input: scenario.input,\n scenarioId: scenario.id,\n })\n const response: ChatResponse = await chat.chat(\n {\n model: opts.studentModel,\n messages: prompt,\n jsonMode: true,\n temperature: studentTemperature,\n maxTokens: studentMaxTokens,\n },\n { signal: ctx.signal },\n )\n reportUsage(ctx.cost, response)\n return parse(response.content, scenario.id)\n },\n })\n\n const winnerPrompt =\n typeof loop.winnerSurface === 'string' ? loop.winnerSurface : opts.baselinePrompt\n const baseline = campaignMeanComposite(loop.baselineOnHoldout)\n const winner = campaignMeanComposite(loop.winnerOnHoldout)\n\n return {\n ...loop,\n winnerPrompt,\n holdoutAgreement: { baseline, winner, delta: winner - baseline },\n }\n}\n\n/** Report the student call's cost + tokens to the cell meter. A cell that\n * reports neither reads as a stub to `assertRealBackend` — every student call\n * MUST report. When the proxy doesn't return a cost we still report tokens so\n * the cell is non-stub. */\nfunction reportUsage(\n cost: {\n observe(amountUsd: number, source: string): void\n observeTokens(u: { input: number; output: number; cached?: number }): void\n },\n response: LlmCallResult,\n): void {\n if (typeof response.costUsd === 'number') cost.observe(response.costUsd, 'distillation-student')\n cost.observeTokens({\n input: response.usage.promptTokens,\n output: response.usage.completionTokens,\n cached: response.usage.cachedPromptTokens,\n })\n}\n\nconst DEFAULT_MUTATION_PRIMITIVES = [\n 'Add an explicit output-schema instruction so the model emits exactly the gold label fields as JSON.',\n 'Add a one-line decision rule for each verdict field the student keeps getting wrong.',\n 'Add a worked example mapping a representative input to its correct gold label.',\n 'Tighten ambiguous phrasing that lets the student hedge instead of committing to a verdict.',\n 'Add a guardrail that forces the student to set boolean risk flags (e.g. leak risk) when the triggering condition is present.',\n]\n\n/** Default student prompt render: surface as system, JSON input as the user\n * turn, with a JSON-only output instruction. */\nexport function defaultRenderStudentPrompt<TInput>(args: {\n surface: string\n input: TInput\n scenarioId: string\n}): ChatRequest['messages'] {\n return [\n { role: 'system', content: args.surface },\n {\n role: 'user',\n content:\n `Input:\\n${stableStringify(args.input)}\\n\\n` +\n 'Respond with ONLY a single JSON object — the verdict. No prose, no code fences.',\n },\n ]\n}\n\n/** Default label parse: strip a ```json fence if present, then `JSON.parse`.\n * Throws on failure so the cell is recorded as failed, not silently zeroed. */\nexport function defaultParseStudentLabel<TProduced>(\n rawContent: string,\n scenarioId: string,\n): TProduced {\n const stripped = stripFence(rawContent).trim()\n if (stripped.length === 0) {\n throw new Error(`distillation student returned empty output for scenario '${scenarioId}'`)\n }\n try {\n return JSON.parse(stripped) as TProduced\n } catch (err) {\n throw new Error(\n `distillation student returned non-JSON for scenario '${scenarioId}': ${\n err instanceof Error ? err.message : String(err)\n } — raw: ${stripped.slice(0, 200)}`,\n )\n }\n}\n\nfunction stripFence(text: string): string {\n const fenced = /```(?:json)?\\s*([\\s\\S]*?)\\s*```/.exec(text)\n return fenced ? (fenced[1] ?? text) : text\n}\n\n/** Deterministic JSON stringify with sorted keys — so the same input always\n * renders the same prompt (a key-order shuffle would perturb the student). */\nfunction stableStringify(value: unknown): string {\n return JSON.stringify(value, replacerSortKeys(), 2)\n}\n\nfunction replacerSortKeys(): (key: string, value: unknown) => unknown {\n return (_key, value) => {\n if (value && typeof value === 'object' && !Array.isArray(value)) {\n const sorted: Record<string, unknown> = {}\n for (const k of Object.keys(value as Record<string, unknown>).sort()) {\n sorted[k] = (value as Record<string, unknown>)[k]\n }\n return sorted\n }\n return value\n }\n}\n\nexport type { CampaignResult }\n","/**\n * Structured prompt profile — the system prompt as named, addressable sections\n * instead of one opaque blob. The self-improvement loop targets ONE evolvable\n * `domain` section at a time (via `applyDomainPatch`); the role, environment,\n * tool conventions, and skill roster stay fixed so a candidate diff is\n * attributable to a single section rather than a whole-prompt rewrite.\n *\n * `renderProfile` emits the prompt in a fixed five-zone order — role,\n * Environment, Tool conventions, Skills, Domain guidance — mirroring the layout\n * of Harvey LAB's `harness/system_prompt.md` (workspace root, read-only\n * documents, output dir, skills dir). `profileToSurface` is the bridge to the\n * loop's string `MutableSurface`: a profile renders to exactly the text a\n * candidate is scored on.\n *\n * Distinct from the canonical `AgentProfile` exported by\n * `@tangle-network/agent-interface`. This helper builds prompt content that can\n * be rendered into an agent-interface profile's `prompt.systemPrompt`.\n */\n\nimport { surfaceContentHash } from '../campaign/provenance'\nimport { BASELINE_ROLES, type BaselineRoleKey } from './baselines'\n\nexport {\n BASELINE_ROLES,\n type BaselineRoleKey,\n engineerRole,\n generalistRole,\n researcherRole,\n} from './baselines'\n\n/** A named, addressable region of the system prompt. `evolvable` marks whether\n * the self-improvement loop is allowed to patch its body; fixed scaffolding\n * (e.g. a compliance preamble) sets `evolvable: false`. */\nexport interface AgentProfileSection {\n id: string\n title: string\n body: string\n evolvable: boolean\n}\n\n/** A skill the agent can invoke. `triggers` are the phrases/conditions that\n * should activate it; `scriptsDir` points at its executable scripts when the\n * skill ships code (mirrors Harvey's `skills/<name>/scripts/`). */\nexport interface ProfileSkill {\n name: string\n description: string\n triggers: string[]\n scriptsDir?: string\n}\n\n/** The structured system prompt. The first four fields are fixed scaffolding;\n * `domain` is the evolvable surface the loop optimizes. */\nexport interface PromptProfile {\n role: string\n environment: string\n toolConventions: string\n skills: ProfileSkill[]\n domain: AgentProfileSection[]\n}\n\nfunction renderSkill(skill: ProfileSkill): string {\n const lines = [`### ${skill.name}`, skill.description]\n if (skill.triggers.length > 0) {\n lines.push(`Triggers: ${skill.triggers.join(', ')}`)\n }\n if (skill.scriptsDir !== undefined) {\n lines.push(`Scripts: ${skill.scriptsDir}`)\n }\n return lines.join('\\n')\n}\n\n/**\n * Emit the sectioned system prompt in fixed order: role text, then\n * `## Environment`, `## Tool conventions`, `## Skills` (each skill as\n * `### <name>` + description + triggers), `## Domain guidance` (each section as\n * `### <title>` + body). The order is load-bearing — the loop diffs rendered\n * text, and reordering would make every candidate look like a full rewrite.\n */\nexport function renderProfile(p: PromptProfile): string {\n const zones: string[] = [\n p.role.trim(),\n `## Environment\\n\\n${p.environment.trim()}`,\n `## Tool conventions\\n\\n${p.toolConventions.trim()}`,\n `## Skills\\n\\n${\n p.skills.length > 0 ? p.skills.map(renderSkill).join('\\n\\n') : '_No skills configured._'\n }`,\n `## Domain guidance\\n\\n${\n p.domain.length > 0\n ? p.domain.map((s) => `### ${s.title}\\n\\n${s.body.trim()}`).join('\\n\\n')\n : '_No domain guidance yet._'\n }`,\n ]\n return zones.join('\\n\\n')\n}\n\n/** The string `MutableSurface` the self-improvement loop scores — a profile\n * renders to exactly the text a candidate is graded on. */\nexport function profileToSurface(p: PromptProfile): string {\n return renderProfile(p)\n}\n\nconst STOCK_SKILLS: ProfileSkill[] = [\n {\n name: 'read-documents',\n description:\n 'Read every source document under the read-only documents directory before drafting.',\n triggers: [\n 'task references a source document',\n 'instructions cite an exhibit, filing, or input file',\n ],\n },\n {\n name: 'write-deliverable',\n description:\n 'Write deliverables to the output directory; use markdown for notes and the file-type skills for binary artifacts.',\n triggers: ['the task asks for a produced artifact', 'a deliverable is named in the brief'],\n },\n]\n\nconst ENVIRONMENT_PREAMBLE =\n 'You are an AI agent executing a task within a single workspace root.\\n\\n' +\n '- Workspace root: bash starts here. Use it for notes, scratch files, and intermediate work.\\n' +\n '- Documents directory: task source documents live here and are read-only — never write to them.\\n' +\n '- Output directory: write every deliverable here; relative write/edit paths route here automatically.\\n' +\n '- Skills directory: skill scripts live at <workspace>/skills/<name>/scripts/.'\n\nconst TOOL_CONVENTIONS_PREAMBLE =\n 'Use read to consume input files. Use write only for plain markdown (typically a response summary). ' +\n 'Use edit for incremental refinement of a file you already created. ' +\n 'External-boundary calls return typed outcomes — inspect success before using a value.'\n\n/**\n * The fixed-scaffolding baseline: a `role`/`environment`/`toolConventions`\n * profile with the stock skill roster and NO domain guidance. The\n * production profile is this plus shipped domain sections.\n */\nexport function baselineProfile(args: {\n role: string\n environment?: string\n toolConventions?: string\n skills?: ProfileSkill[]\n}): PromptProfile {\n return {\n role: args.role,\n environment: args.environment ?? ENVIRONMENT_PREAMBLE,\n toolConventions: args.toolConventions ?? TOOL_CONVENTIONS_PREAMBLE,\n skills: args.skills ?? STOCK_SKILLS,\n domain: [],\n }\n}\n\n/**\n * Baseline from one of the strong generic roles (`'engineer' | 'researcher' |\n * 'generalist'`) — the common case: pick a role foundation, optionally override\n * the environment to describe THIS product's sandbox, then layer domain via\n * `prodProfile`. Domain guidance stays in the product repo; this only supplies\n * the generically-useful role + stock scaffolding.\n */\nexport function baselineProfileFromRole(\n role: BaselineRoleKey,\n args: { environment?: string; toolConventions?: string; skills?: ProfileSkill[] } = {},\n): PromptProfile {\n return baselineProfile({ role: BASELINE_ROLES[role], ...args })\n}\n\n/** The production profile: the baseline scaffolding plus the domain sections\n * shipped after self-improvement. Differs from the baseline ONLY in `domain`\n * (and any skills the caller layered into the baseline) — the role,\n * environment, and tool conventions are carried through unchanged. */\nexport function prodProfile(\n baseline: PromptProfile,\n shipped: AgentProfileSection[],\n): PromptProfile {\n return { ...baseline, domain: [...baseline.domain, ...shipped] }\n}\n\n/**\n * Section-scoped edit — replace the body of ONE domain section by id, leaving\n * every other section byte-identical. This is how the loop targets a single\n * evolvable surface. Throws on an unknown section id (a patch that hits no\n * section is a silent no-op otherwise — fail loud). Throws when the targeted\n * section is `evolvable: false`.\n */\nexport function applyDomainPatch(\n p: PromptProfile,\n sectionId: string,\n newBody: string,\n): PromptProfile {\n const idx = p.domain.findIndex((s) => s.id === sectionId)\n if (idx === -1) {\n throw new Error(\n `applyDomainPatch: no domain section \"${sectionId}\" (have: ${\n p.domain.map((s) => s.id).join(', ') || '<none>'\n })`,\n )\n }\n const target = p.domain[idx]\n if (target === undefined) {\n throw new Error(`applyDomainPatch: domain section \"${sectionId}\" resolved to undefined`)\n }\n if (!target.evolvable) {\n throw new Error(`applyDomainPatch: domain section \"${sectionId}\" is not evolvable`)\n }\n const next = [...p.domain]\n next[idx] = { ...target, body: newBody }\n return { ...p, domain: next }\n}\n\n/**\n * Content hash of a single section — its loop identity. Delegates to the\n * campaign provenance `surfaceContentHash` (the same helper the loop's\n * provenance record uses for full surfaces), so a section hash is byte-for-byte\n * comparable with the `sha256:`-prefixed content hashes that record carries.\n * Two sections that render identically (same title + body) share a hash; the\n * `id` and `evolvable` flag are excluded — they are routing metadata, not\n * content.\n */\nexport function sectionHash(section: AgentProfileSection): string {\n return surfaceContentHash(JSON.stringify({ title: section.title, body: section.body }))\n}\n","/**\n * Strong, generically-useful baseline ROLES — the top zone of an `AgentProfile`\n * before any domain layer. A product composes one of these with its own\n * environment description (its sandbox) and its domain guidance, which lives in\n * the product repo (not here): a profile is `<baseline role> + <environment> +\n * <domain sections>`. Domain strength is NOT generalized into the substrate —\n * it is lifted here only once ≥2 products genuinely reuse it.\n *\n * Three roles cover the common shapes:\n * - `engineerRole` — builds + verifies real artifacts in a sandbox. Distilled\n * from agent-runtime's `coderProfile` doctrine (minimal\n * correct change, run the checks, fix the root cause,\n * never weaken a test or hide an error).\n * - `researcherRole` — gathers from real sources and grounds every claim\n * (cite or mark inferred; never fabricate).\n * - `generalistRole` — a strong default: helpful, grounded, verify-before-assert.\n *\n * All three are verification-first and domain-agnostic. They describe HOW a\n * capable IC operates, not WHAT domain it works in.\n */\n\n/** Senior-IC engineer operating in a sandbox — produces real artifacts and\n * verifies them before declaring done. The shared operator foundation for any\n * file-producing, tool-using product agent. */\nexport const engineerRole: string = [\n 'You are a senior principal engineer — a 10x individual contributor — operating inside an isolated sandbox workspace with real tools (shell, filesystem, editors, test runners).',\n 'You do not behave like a chatbot that describes work. You DO the work: you produce the actual artifact in the workspace, then you verify it.',\n '',\n 'How you operate:',\n '- Deliver the smallest correct change that fully satisfies the goal. Bias to the real artifact (the file, the patch, the document), never a description of it.',\n '- Before declaring done, run the available checks (tests, typecheck, validators, a re-read of what you produced). If a check fails, fix the ROOT CAUSE — never weaken the check, never hide the error, never fake success.',\n '- External-boundary calls (shell, network, filesystem) can fail. Inspect the outcome before relying on it; surface failures loudly rather than proceeding on a bad value.',\n '- State outcomes faithfully: what you verified, what you skipped, what is still failing. \"Done\" means produced AND verified.',\n].join('\\n')\n\n/** Researcher who grounds every claim in real sources — gathers, cites, and\n * distinguishes verified fact from inference. */\nexport const researcherRole: string = [\n 'You are a principal research analyst operating inside a workspace with tools to read sources, search, and record findings.',\n 'Your output is only as good as its grounding. You gather from the real sources in front of you and you ground every material claim.',\n '',\n 'How you operate:',\n '- Read the actual sources before concluding. Do not answer from memory when a source is available to check.',\n '- Cite the source for every material claim; explicitly mark anything you infer rather than verify. Never fabricate a source, a quote, a number, or a citation.',\n '- Distinguish what the sources establish from what you are extrapolating, and say which is which.',\n '- When the sources are insufficient or contradictory, say so plainly rather than papering over the gap.',\n].join('\\n')\n\n/** Strong general-purpose default — helpful, grounded, verifies before asserting. */\nexport const generalistRole: string = [\n 'You are a capable, senior generalist assistant operating inside a workspace with real tools.',\n 'You are direct and grounded: you verify before you assert, and you produce real output rather than describing it.',\n '',\n 'How you operate:',\n '- Prefer doing over describing — when the workspace lets you produce the artifact, produce it.',\n '- Ground claims in what you can check; when you cannot check something, say so instead of guessing confidently.',\n '- Verify your output before declaring done, and report what you verified vs. what remains uncertain.',\n '- Ask the user only when a choice is genuinely theirs and you cannot resolve it from the task, the workspace, or sensible defaults.',\n].join('\\n')\n\n/** The named baseline roles, for selection by key (e.g. from a product config). */\nexport const BASELINE_ROLES = {\n engineer: engineerRole,\n researcher: researcherRole,\n generalist: generalistRole,\n} as const\n\nexport type BaselineRoleKey = keyof typeof BASELINE_ROLES\n","/**\n * Program cost report — a thin projection over `CostLedger.summary()` that\n * adds the per-model rollup the summary lacks, plus `attachCostToReport`, the\n * one way every artifact (capsules, campaign results, diagnose reports) gets\n * its cost stamp.\n *\n * Honesty contract carried through from the ledger: `total.unknownEntries`\n * and `perModel[].unpriced` surface the costUnknown axis — a $0 from an\n * unpriced model is a lower bound, never a measured zero.\n */\n\nimport type { ChannelRollup, CostLedger } from './cost-ledger'\nimport { ValidationError } from './errors'\n\nexport interface ModelCostRollup {\n model: string\n usd: number\n entries: number\n /** ≥1 entry for this model was costUnknown — `usd` is a lower bound. An\n * `actualCostUsd` override clears the flag for that entry (the dollars are\n * observed, even when the model has no pricing). */\n unpriced: boolean\n}\n\nexport interface CostReport {\n /** Per-channel breakdown — `CostLedgerSummary.byChannel` verbatim. */\n perChannel: ChannelRollup[]\n total: {\n usd: number\n /** Entries whose cost was unknown — non-zero means `usd` is a lower bound. */\n unknownEntries: number\n }\n /** Per-model spend, sorted by model id. */\n perModel: ModelCostRollup[]\n}\n\n/** Project a ledger into the program cost report. Pure — no I/O, no clock. */\nexport function costReport(ledger: CostLedger): CostReport {\n const summary = ledger.summary()\n const perModel = new Map<string, ModelCostRollup>()\n for (const entry of ledger.list()) {\n const roll = perModel.get(entry.model) ?? {\n model: entry.model,\n usd: 0,\n entries: 0,\n unpriced: false,\n }\n roll.usd += entry.costUsd\n roll.entries += 1\n if (entry.costUnknown) roll.unpriced = true\n perModel.set(entry.model, roll)\n }\n return {\n perChannel: summary.byChannel,\n total: {\n usd: summary.totalCostUsd,\n unknownEntries: summary.byChannel.reduce((sum, c) => sum + c.unpricedCalls, 0),\n },\n perModel: [...perModel.values()].sort((a, b) => a.model.localeCompare(b.model)),\n }\n}\n\n/**\n * Stamp a report-shaped object with its cost projection under the `cost` key.\n * Generic so capsules, campaign results, and diagnose reports all stamp the\n * same way. Throws when the report already carries a `cost` key — silently\n * overwriting an existing stamp would corrupt the artifact's provenance.\n */\nexport function attachCostToReport<R extends object>(\n report: R,\n ledger: CostLedger,\n): R & { cost: CostReport } {\n if ('cost' in report) {\n throw new ValidationError(\n \"attachCostToReport: report already has a 'cost' key — refusing to overwrite an existing stamp\",\n )\n }\n return { ...report, cost: costReport(ledger) }\n}\n","/**\n * ModelSeats — the program's model seating chart.\n *\n * One object names which model fills each role in an eval program: the worker\n * under evaluation, the judge panel, the analyst, the reflection/driver model,\n * and the verifier. Re-tiering an entire program (economy ↔ frontier) is one\n * swapped object instead of a hunt through call sites.\n *\n * Wiring points — consumers thread seats; this module implements none of them\n * (those files belong to other surfaces):\n * - `judges` → `ensembleJudge({ models: seats.judges, … })` (src/judge-panel.ts)\n * and the `JudgeConfig`s handed to `makeEvalTools({ judges })`\n * (src/eval-tools.ts).\n * - `reflection` → `selfImprove({ llm: { model: seats.reflection } })` — the\n * `gepaProposer` reflection model (src/contract/self-improve.ts);\n * same seat for any custom `SurfaceProposer`'s LLM.\n * - `worker` → the dispatch model the agent itself calls — the model an\n * `AgentProfile` declares.\n * - `analyst` → the LLM behind `analyzeRuns` / analyst-registry kinds.\n * - `verifier` → completion-verifier / objective-checker model.\n * - campaign cells thread `judges` + driver models the same way; that wiring\n * lands with the campaign surface, not here.\n *\n * `resolveSeat` is the only read path: an unset seat with no explicit fallback\n * throws — a model id is a budget decision, never a silent default.\n */\n\nimport { ConfigError, ValidationError } from './errors'\n\nexport interface ModelSeats {\n /** The model under evaluation — what the agent itself dispatches with. */\n worker?: string\n /** Judge-panel model ids — thread into `ensembleJudge({ models })`. */\n judges?: string[]\n /** Analyst model — `analyzeRuns` / analyst-registry LLM calls. */\n analyst?: string\n /** Reflection/proposer model — `gepaProposer` mutation proposals. */\n reflection?: string\n /** Verifier model — completion/objective checking. */\n verifier?: string\n}\n\nexport type SeatName = keyof ModelSeats\n\nexport type SeatPresetName = keyof typeof seatPresets\n\n/**\n * Tier presets — plain data, swap or spread freely.\n *\n * `economy` uses the fleet-policy ids: every id resolves through the\n * substrate's family pricing (no costUnknown axis) and the judge trio spans\n * three provider families (moonshot / deepseek / openai), so it passes\n * `assertCrossFamily` as-is.\n *\n * `frontier` is deliberately EMPTY: entitled frontier ids vary per router\n * account, and a hardcoded claude/gpt-5 id 401s on keys that lack it. Supply\n * your own: `{ ...seatPresets.frontier, worker: '<your-frontier-id>', … }` —\n * `resolveSeat` throws on every seat you haven't filled.\n */\nexport const seatPresets: Record<'economy' | 'frontier', ModelSeats> = {\n economy: {\n worker: 'kimi-k2.6',\n judges: ['kimi-k2.6', 'deepseek-v4-pro', 'gpt-4.1-mini'],\n analyst: 'gpt-4.1-mini',\n reflection: 'gpt-4.1-mini',\n verifier: 'deepseek-v4-pro',\n },\n frontier: {},\n}\n\n/** Thrown by `resolveSeat` when a seat is unset and no fallback was given. */\nexport class SeatUnsetError extends ConfigError {\n constructor(public readonly seat: SeatName) {\n super(\n `ModelSeats: seat '${seat}' is unset and no fallback was given — ` +\n 'name a model explicitly (a model id is a budget decision, never a silent default)',\n )\n }\n}\n\n/**\n * Read one seat. Blank strings and empty arrays count as unset (env-var\n * plumbing produces them); malformed values (non-string seat, non-array or\n * blank-entry `judges`) throw `ValidationError`. When the seat is unset, an\n * explicit `fallback` is returned (`[fallback]` for `judges` — a one-model\n * panel); without one, `SeatUnsetError`.\n */\nexport function resolveSeat(seats: ModelSeats, seat: 'judges', fallback?: string): string[]\nexport function resolveSeat(\n seats: ModelSeats,\n seat: Exclude<SeatName, 'judges'>,\n fallback?: string,\n): string\nexport function resolveSeat(seats: ModelSeats, seat: SeatName, fallback?: string): string | string[]\nexport function resolveSeat(\n seats: ModelSeats,\n seat: SeatName,\n fallback?: string,\n): string | string[] {\n const value = seats[seat]\n if (seat === 'judges') {\n if (value !== undefined && !Array.isArray(value)) {\n throw new ValidationError(`ModelSeats: seat 'judges' must be a string[], got ${typeof value}`)\n }\n const models = Array.isArray(value) ? value : []\n if (models.length > 0) {\n const blank = models.findIndex((m) => typeof m !== 'string' || m.trim() === '')\n if (blank >= 0) {\n throw new ValidationError(\n `ModelSeats: judges[${blank}] is blank — every panel model must be a non-empty id`,\n )\n }\n return [...models]\n }\n } else {\n if (value !== undefined && typeof value !== 'string') {\n throw new ValidationError(`ModelSeats: seat '${seat}' must be a string, got ${typeof value}`)\n }\n if (typeof value === 'string' && value.trim() !== '') return value\n }\n if (fallback !== undefined) {\n if (fallback.trim() === '') {\n throw new ValidationError(`ModelSeats: fallback for seat '${seat}' is blank`)\n }\n return seat === 'judges' ? [fallback] : fallback\n }\n throw new SeatUnsetError(seat)\n}\n","/**\n * Reproducibility attestation for any serializable report object.\n *\n * `attest()` binds a report to its content address (sha-256 over canonical\n * JSON) plus the provenance needed to reproduce it: model versions, seeds,\n * price-table hash, code SHA, inputs hash. `verifyAttestation()` recomputes\n * the address and answers \"is this the exact report that provenance\n * describes?\" — any single-field tamper changes the hash.\n *\n * Layering: content-addressing is the substrate's job; cryptographic SIGNING\n * (who vouches for the attestation, key management, transparency logs) is the\n * consumer's layer on top. An `AttestedReport` is a stable byte-identical\n * payload a consumer can sign — the substrate never holds keys.\n *\n * Generic by design: the report parameter is ANY value `canonicalJson`\n * accepts (campaign results, fuzz capsules, scorecards, cost ledgers). Do not\n * couple this module to a specific report schema.\n */\n\nimport { contentHash } from './verdict-cache'\n\n/** Hash scheme identifier carried by every attestation. A verifier rejects\n * unknown algorithms instead of guessing. */\nexport const ATTESTATION_ALGORITHM = 'sha256/canonical-json' as const\n\nexport interface AttestationProvenance {\n /** Every model involved in producing the report, name → version/id. */\n modelVersions: Record<string, string>\n /** RNG seeds the run was driven by, when seeded. */\n seeds?: number[]\n /** Content hash of the price table used for cost figures — cost numbers\n * are only reproducible against the same prices. */\n priceTableHash?: string\n /** Git SHA of the code that produced the report. */\n codeSha: string\n /** Content hash of the input set (scenarios, dataset manifest, ...). */\n inputsHash?: string\n /** ISO-8601 timestamp, caller-supplied — the substrate stays clock-free\n * so attestation is deterministic and testable. */\n createdAt: string\n}\n\nexport interface AttestedReport {\n /** Hex sha-256 over the canonical JSON of the report. */\n reportHash: string\n provenance: AttestationProvenance\n algorithm: typeof ATTESTATION_ALGORITHM\n}\n\nexport interface AttestationVerification {\n valid: boolean\n /** Populated iff `valid` is false — names the exact mismatch. */\n reason?: string\n}\n\n/**\n * Content-address a report and bind it to its provenance. Throws (via\n * `canonicalJson`) if the report contains undefined / function / symbol /\n * non-finite numbers — a report that cannot be unambiguously serialized\n * cannot be attested.\n */\nexport function attest(report: unknown, provenance: AttestationProvenance): AttestedReport {\n return {\n reportHash: contentHash(report),\n provenance,\n algorithm: ATTESTATION_ALGORITHM,\n }\n}\n\n/**\n * Verify a report against its attestation. Returns a typed outcome rather\n * than throwing: an unverifiable report (e.g. one that no longer\n * canonicalizes) is a verification failure with the cause in `reason`, not a\n * crash — verifiers run in pipelines that must record WHY, not die.\n */\nexport function verifyAttestation(\n report: unknown,\n attested: AttestedReport,\n): AttestationVerification {\n if (attested.algorithm !== ATTESTATION_ALGORITHM) {\n return {\n valid: false,\n reason: `unknown algorithm '${attested.algorithm}' — this verifier only checks '${ATTESTATION_ALGORITHM}'`,\n }\n }\n let recomputed: string\n try {\n recomputed = contentHash(report)\n } catch (err) {\n return {\n valid: false,\n reason: `report is not canonicalizable: ${err instanceof Error ? err.message : String(err)}`,\n }\n }\n if (recomputed !== attested.reportHash) {\n return {\n valid: false,\n reason: `report hash mismatch: attested ${attested.reportHash}, recomputed ${recomputed}`,\n }\n }\n return { valid: true }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2FA,SAAS,qBAAqB,OAA+C;AAC3E,MAAI,CAAC,MAAM,KAAK,MAAM,KAAK,KAAK,CAAC,MAAM,KAAK,KAAK,KAAK,GAAG;AACvD,UAAM,IAAI,gBAAgB,kDAAkD;AAAA,EAC9E;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,uDAAuD;AAAA,EACnF;AACA,MAAI,MAAM,YAAY,WAAW,GAAG;AAClC,UAAM,IAAI,gBAAgB,8CAA8C;AAAA,EAC1E;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,qCAAqC,OAAO,IAAI;AAAA,MAClD;AAAA,IACF;AACA,QAAI,UAAU,IAAI,OAAO,IAAI,GAAG;AAC9B,YAAM,IAAI,gBAAgB,uCAAuC,OAAO,IAAI,GAAG;AAAA,IACjF;AACA,cAAU,IAAI,OAAO,IAAI;AAAA,EAC3B;AACA,MAAI,CAAC,MAAM,MAAM,KAAK,GAAG;AACvB,UAAM,IAAI,gBAAgB,wCAAwC;AAAA,EACpE;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,yBAAyB,MAAM,IAAI,IAAI,WAAM,IAAI,MAAM,IAAI,KAAK,MAAM,GAAG,GAAG,CAAC;AAAA,MAC/E;AAAA,IACF;AACA,WAAQ,MAAM,IAAI,KAAK;AAAA,EACzB;AAEA,SAAO;AAAA,IACL,MAAM,cAAc,OAAO;AACzB,2BAAqB,KAAK;AAC1B,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,+BAA+B,UAAU,aAAa;AAAA,MAC9E;AACA,YAAM,UAAU,QAAQ,OAAO;AAC/B,YAAM,aAAa,MAAM,IAAc,OAAO,GAAG,QAAQ,gBAAgB,OAAO,EAAE;AAClF,UAAI,CAAC,YAAY;AACf,cAAM,IAAI,YAAY,8BAA8B,OAAO,8BAA8B;AAAA,MAC3F;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,4CAA4C;AAC7E,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,4CAA4C;AAG7E,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,OAAQ,OAAM,IAAI,YAAY,8CAA8C;AAGjF,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,QAAS,OAAM,IAAI,YAAY,0CAA0C;AAC9E,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,kBAAkB,GAAG,IAAI,KAAK,KAAK,GAAG,CAAC,YAAY,EAAE,QAAQ,MAAM,EAAE,OAAO,KAAK,KAAK,EAAE,OAAO,KAAK,CAAC;AAAA,MACvG;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAEA,SAAO;AAAA,IACL,MAAM,cAAc,OAAO;AACzB,2BAAqB,KAAK;AAC1B,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,SAAAA,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;;;AC5cA,SAAS,cAAc,SAAkB,SAA0B;AACjE,MAAI,YAAY,UAAa,YAAY,KAAM,QAAO;AACtD,SAAO,2BAA2B,YAAY,OAAO,SAAS,OAAO,OAAO;AAC9E;AAEA,SAAS,WAAW,KAAsB;AACxC,MAAI,eAAe,MAAO,QAAO,GAAG,IAAI,IAAI,KAAK,IAAI,OAAO;AAC5D,SAAO,OAAO,GAAG;AACnB;AAcA,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,UAAW,KAA6D,UAAU,CAAC,GACrF;AACJ,UAAM,aAAa,SAAS;AAM5B,QAAI,YAAY,UAAa,YAAY,QAAQ,OAAO,eAAe,UAAU;AAC/E,YAAM,IAAI;AAAA,QACR,+BAA+B,SAAS,EAAE,UAAU,CAAC,0EACQ,cAAc,YAAY,OAAO,CAAC;AAAA,MACjG;AAAA,IACF;AACA,UAAM,UAAU;AAEhB,aAAS,KAAK,EAAE,MAAM,aAAa,QAAQ,CAAC;AAG5C,UAAM,SAAS;AACf,QAAI,YAAoC,OAAO,KAAK,OAAO;AAC3D,WAAO,cAAc,MAAM;AACzB,oBAAc,KAAK,EAAE,UAAU,UAAU,CAAC,KAAK,QAAQ,MAAM,UAAU,CAAC,KAAK,GAAG,CAAC;AACjF,kBAAY,OAAO,KAAK,OAAO;AAAA,IACjC;AAGA,UAAM,aAAgD,CAAC;AACvD,UAAM,eAAe,IAAI,OAAO,QAAQ,QAAQ,QAAQ,KAAK;AAC7D,QAAI,aAAqC,aAAa,KAAK,OAAO;AAClE,WAAO,eAAe,MAAM;AAC1B,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;AAC9D,mBAAa,aAAa,KAAK,OAAO;AAAA,IACxC;AAGA,QAAI,cAAc;AAClB,QAAI,OAAO,kBAAkB;AAC3B,iBAAW,WAAW,OAAO,kBAAkB;AAC7C,cAAM,KAAK,IAAI,OAAO,QAAQ,QAAQ,QAAQ,KAAK;AACnD,YAAI,YAAoC,GAAG,KAAK,OAAO;AACvD,eAAO,cAAc,MAAM;AACzB,uBAAa,KAAK,UAAU,CAAC,CAAC;AAC9B,wBAAc;AACd,sBAAY,GAAG,KAAK,OAAO;AAAA,QAC7B;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;AAMD,QAAM,aAAa,EAAE,UAAU,OAAO,UAAU;AAChD,QAAM,eAA+B,CAAC;AACtC,MAAI,eAAe;AACnB,QAAM,gBAAgC,CAAC;AACvC,QAAMC,SAAQ,OAAO,UAAU,CAAC,OAAe,IAAI,QAAc,CAAC,MAAM,WAAW,GAAG,EAAE,CAAC;AAEzF,WAAS,IAAI,GAAG,IAAI,OAAO,OAAO,QAAQ,KAAK;AAC7C,UAAM,QAAQ,OAAO,OAAO,CAAC;AAC7B,UAAM,YAAY,MAAM,QAAQ,SAAS,CAAC;AAC1C,QAAI;AACJ,QAAI,eAAe;AACnB,aAAS,UAAU,GAAG,UAAU,GAAG,WAAW;AAC5C,qBAAe,UAAU;AACzB,UAAI;AACF,YAAI,UAAU,GAAG;AACf,gBAAM,OAAO,UAAU;AACvB,kBAAQ,IAAI,OAAO,SAAS,UAAU,OAAO,eAAe,OAAO,GAAI,IAAI;AAC3E,gBAAMA,OAAM,IAAI;AAAA,QAClB;AACA,cAAMC,UAAS,MAAM,MAAM,IAAI,UAAU;AACzC,qBAAa,KAAKA,OAAM;AACxB,cAAMD,OAAM,GAAI;AAChB,oBAAY;AACZ;AAAA,MACF,SAAS,KAAK;AACZ,oBAAY;AACZ,YAAI,eAAe,iBAAiB;AAGlC,kBAAQ,MAAM,OAAO,SAAS,4BAA4B,WAAW,GAAG,CAAC,EAAE;AAC3E;AAAA,QACF;AACA,gBAAQ,MAAM,OAAO,SAAS,YAAY,OAAO,YAAY,WAAW,GAAG,CAAC,EAAE;AAI9E,YAAI,CAAC,oBAAoB,GAAG,EAAG;AAAA,MACjC;AAAA,IACF;AACA,QAAI,cAAc,QAAW;AAC3B;AACA,oBAAc,KAAK;AAAA,QACjB,OAAO;AAAA,QACP,UAAU;AAAA,QACV,QAAQ,WAAW,SAAS;AAAA,MAC9B,CAAC;AAAA,IACH;AAAA,EACF;AAEA,QAAM,YAAY,aAAa,KAAK;AAEpC,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;AAKA,QAAM,SAA8D;AAAA,IAClE,YAAY,SAAS;AAAA,IACrB,SAAS,SAAS;AAAA,IAClB;AAAA,IACA;AAAA,IACA,aAAa;AAAA,IACb,aAAa,YAAY,SAAS;AAAA,IAClC;AAAA,IACA,iBAAiB,KAAK,IAAI,IAAI;AAAA,IAC9B;AAAA,EACF;AACA,MAAI,cAAc,SAAS,EAAG,QAAO,gBAAgB;AACrD,SAAO;AACT;;;AChSO,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;;;AC3FO,SAAS,mBACd,MACA,OAAkC,CAAC,GACT;AAC1B,QAAM,gBAAgB,KAAK,iBAAiB;AAC5C,MAAI,CAAC,OAAO,SAAS,aAAa,KAAK,gBAAgB,KAAK,iBAAiB,GAAG;AAC9E,UAAM,IAAI;AAAA,MACR,4DAA4D,aAAa;AAAA,IAC3E;AAAA,EACF;AACA,MAAI,KAAK,WAAW,GAAG;AACrB,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAGA,QAAM,SAAS,oBAAI,IAA0D;AAC7E,aAAW,OAAO,MAAM;AACtB,QACE,IAAI,oBAAoB,UACxB,IAAI,oBAAoB,UACxB,IAAI,oBAAoB,WACxB;AACA,YAAM,IAAI;AAAA,QACR,qDAAqD,IAAI,eAAe,eAAe,IAAI,MAAM;AAAA,MACnG;AAAA,IACF;AACA,UAAM,MAAM,OAAO,IAAI,IAAI,MAAM,KAAK,EAAE,GAAG,GAAG,QAAQ,GAAG,OAAO,EAAE;AAClE,QAAI;AACJ,QAAI,IAAI,oBAAoB,WAAW;AACrC,UAAI;AACJ,UAAI,IAAI,oBAAoB,OAAQ,KAAI;AAAA,IAC1C;AACA,WAAO,IAAI,IAAI,QAAQ,GAAG;AAAA,EAC5B;AAEA,QAAM,QAAwB,CAAC,GAAG,OAAO,QAAQ,CAAC,EAC/C,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAO,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,CAAE,EAC/C,IAAI,CAAC,CAAC,QAAQ,GAAG,MAAM;AACtB,QAAI,IAAI,UAAU,GAAG;AACnB,aAAO;AAAA,QACL;AAAA,QACA,GAAG,IAAI;AAAA,QACP,QAAQ;AAAA,QACR,kBAAkB,OAAO;AAAA,QACzB,UAAU;AAAA,MACZ;AAAA,IACF;AACA,UAAM,mBAAmB,IAAI,SAAS,IAAI;AAC1C,WAAO;AAAA,MACL;AAAA,MACA,GAAG,IAAI;AAAA,MACP,QAAQ,IAAI;AAAA,MACZ;AAAA,MACA,UAAU,oBAAoB,gBAAiB,QAAmB;AAAA,IACpE;AAAA,EACF,CAAC;AAEH,QAAM,UAAU;AAAA,IACd,cAAc,MAAM,OAAO,CAAC,MAAM,EAAE,aAAa,KAAK,EAAE;AAAA,IACxD,gBAAgB,MAAM,OAAO,CAAC,MAAM,EAAE,aAAa,WAAW,EAAE;AAAA,IAChE,cAAc,MAAM,OAAO,CAAC,MAAM,EAAE,aAAa,SAAS,EAAE;AAAA,IAC5D,aAAa,MAAM,OAAO,CAACE,MAAK,MAAMA,QAAO,EAAE,IAAI,EAAE,SAAS,CAAC;AAAA,EACjE;AACA,SAAO,EAAE,OAAO,QAAQ;AAC1B;AAaO,SAAS,yBACd,QACA,OAAwC,CAAC,GACnC;AACN,QAAM,kBAAkB,KAAK,mBAAmB;AAChD,MAAI,CAAC,OAAO,UAAU,eAAe,KAAK,kBAAkB,GAAG;AAC7D,UAAM,IAAI;AAAA,MACR,8EAAyE,eAAe;AAAA,IAC1F;AAAA,EACF;AACA,QAAM,EAAE,cAAc,gBAAgB,aAAa,IAAI,OAAO;AAC9D,MAAI,eAAe,iBAAiB;AAClC,UAAM,QAAQ,OAAO,MAAM;AAC3B,UAAM,IAAI;AAAA,MACR,kCAAkC,YAAY,OAAO,KAAK,gDAC7C,eAAe,MAAM,cAAc,yCAC3C,YAAY;AAAA,IAGnB;AAAA,EACF;AACF;;;ACpLA,IAAM,6BAA6B;AAE5B,IAAM,gBAAN,MAAoB;AAAA,EACjB;AAAA,EACA;AAAA,EACA,UAAkB;AAAA,EAClB;AAAA,EAER,YAAY,QAA6B;AACvC,SAAK,UAAU,OAAO,QAAQ,QAAQ,QAAQ,EAAE;AAChD,SAAK,SAAS,OAAO;AACrB,SAAK,YAAY,OAAO,aAAa;AAAA,EACvC;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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAc,QACZ,QACA,MACA,MACkC;AAClC,UAAM,aAAa,IAAI,gBAAgB;AACvC,UAAM,UAAU,WAAW,MAAM,WAAW,MAAM,GAAG,KAAK,SAAS;AACnE,QAAI;AACJ,QAAI;AACF,YAAM,MAAM,MAAM,GAAG,KAAK,OAAO,GAAG,IAAI,IAAI;AAAA,QAC1C;AAAA,QACA,SAAS;AAAA,UACP,GAAI,OAAO,EAAE,gBAAgB,mBAAmB,IAAI,CAAC;AAAA,UACrD,QAAQ,KAAK;AAAA,UACb,QAAQ,KAAK;AAAA,QACf;AAAA,QACA,GAAI,OAAO,EAAE,MAAM,KAAK,UAAU,IAAI,EAAE,IAAI,CAAC;AAAA,QAC7C,QAAQ,WAAW;AAAA,MACrB,CAAC;AAAA,IACH,UAAE;AACA,mBAAa,OAAO;AAAA,IACtB;AACA,QAAI,CAAC,IAAI,IAAI;AACX,YAAM,OAAO,MAAM,IAAI,KAAK,EAAE,MAAM,MAAM,EAAE;AAC5C,YAAM,IAAI,MAAM,GAAG,MAAM,IAAI,IAAI,iBAAiB,IAAI,MAAM,WAAM,KAAK,MAAM,GAAG,GAAG,CAAC,EAAE;AAAA,IACxF;AACA,WAAO,IAAI,KAAK;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOQ,aAAgB,KAA8B,OAAoB;AACxE,UAAM,QAAQ,IAAI,KAAK;AACvB,QAAI,CAAC,MAAM,QAAQ,KAAK,GAAG;AACzB,YAAM,IAAI;AAAA,QACR,iCAAiC,KAAK,UAAU,OAAO,KAAK,KAAK,KAAK,UAAU,KAAK,GAAG,MAAM,GAAG,GAAG,CAAC;AAAA,MACvG;AAAA,IACF;AACA,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,QAAgC,QAAQ,KAAK,IAAI;AACrD,WAAO,UAAU,MAAM;AACrB,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;AAC1D,cAAQ,QAAQ,KAAK,IAAI;AAAA,IAC3B;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,WAAO,KAAK;AAAA,MACV;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,UAAU,aAA6E;AAC3F,UAAM,MAAM,MAAM,KAAK,IAAI,GAAG,KAAK,MAAM,QAAQ,CAAC,gBAAgB,WAAW,EAAE;AAC/E,WAAO,KAAK,aAA0D,KAAK,QAAQ;AAAA,EACrF;AAAA,EAEA,MAAM,aACJ,aACwE;AACxE,UAAM,MAAM,MAAM,KAAK,IAAI,GAAG,KAAK,MAAM,WAAW,CAAC,gBAAgB,WAAW,EAAE;AAClF,WAAO,KAAK;AAAA,MACV;AAAA,MACA;AAAA,IACF;AAAA,EACF;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,YAAQ,KAAK,aAAsB,KAAK,MAAM,CAAC;AAC/C,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,WAAO,KAAK,aAA2D,KAAK,aAAa;AAAA,EAC3F;AAAA;AAAA,EAGA,MAAM,IAAI,MAAgD;AACxD,WAAO,KAAK,QAAQ,OAAO,IAAI;AAAA,EACjC;AAAA;AAAA,EAGA,MAAM,KAAK,MAAc,MAAiE;AACxF,WAAO,KAAK,QAAQ,QAAQ,MAAM,IAAI;AAAA,EACxC;AAAA;AAAA,EAGA,MAAM,MAAM,MAAc,MAAiE;AACzF,WAAO,KAAK,QAAQ,SAAS,MAAM,IAAI;AAAA,EACzC;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;;;AC7QO,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;;;ACtDA,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;AA+BO,SAAS,8BAA8B,KAAkC;AAC9E,QAAM,UAAU,IAAI,WAAW;AAC/B,QAAM,QAAQ,IAAI,eACd;AAAA,yBAA4B,OAAO;AAAA,EAAW,IAAI,YAAY;AAAA;AAAA,IAC9D;AAAA,qBAAwB,OAAO;AAAA;AACnC,QAAM,WAAW,IAAI,WACjB;AAAA;AAAA,EAAuC,IAAI,QAAQ;AAAA,IACnD;AACJ,QAAM,UAAU,IAAI,UAAU;AAAA;AAAA,EAAe,IAAI,OAAO;AAAA,IAAO;AAE/D,SAAO;AAAA;AAAA,YAEG,IAAI,IAAI;AAAA,EAClB,OAAO,GAAG,KAAK,GAAG,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAe5B;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;;;AC9NA,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,UAAAC,UAAS,IAAI,MAAM,OAAO,aAAkB;AACpD,UAAM,EAAE,MAAAD,MAAK,IAAI,MAAM,OAAO,MAAW;AACzC,UAAM,OAAOA,MAAK,KAAK,KAAK,8BAA8B;AAC1D,QAAI;AACF,YAAM,MAAM,MAAMC,UAAS,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;;;AChmBA,SAAS,WAAW,KAAqB;AACvC,SAAO,IAAI,QAAQ,QAAQ,EAAE;AAC/B;AAGA,SAAS,aAAa,MAA8B;AAClD,MAAI,QAAQ,QAAQ,OAAO,SAAS,SAAU,QAAO;AACrD,QAAM,IAAI;AACV,MAAI,EAAE,SAAS,OAAO,EAAE,MAAM,YAAY,SAAU,QAAO,EAAE,MAAM;AACnE,MAAI,OAAO,EAAE,YAAY,SAAU,QAAO,EAAE;AAC5C,SAAO;AACT;AAYA,eAAsB,gBAAgB,MAAyD;AAC7F,QAAM,YAAY,KAAK,aAAa;AACpC,QAAM,UAAU,WAAW,KAAK,OAAO;AACvC,QAAM,cAAc,EAAE,eAAe,UAAU,KAAK,MAAM,GAAG;AAE7D,MAAI;AACJ,MAAI;AACF,UAAM,MAAM,MAAM,UAAU,GAAG,OAAO,WAAW,EAAE,QAAQ,OAAO,SAAS,YAAY,CAAC;AACxF,QAAI,CAAC,IAAI,IAAI;AACX,YAAM,OAAO,MAAM,IAAI,KAAK,EAAE,MAAM,MAAM,EAAE;AAC5C,aAAO;AAAA,QACL,WAAW;AAAA,QACX,OAAO;AAAA,QACP,OAAO,wBAAwB,OAAO,kBAAa,IAAI,MAAM,IAAI,KAAK,MAAM,GAAG,GAAG,CAAC;AAAA,MACrF;AAAA,IACF;AACA,UAAM,OAAQ,MAAM,IAAI,KAAK;AAC7B,UAAM,MAAM,MAAM,QAAQ,KAAK,IAAI,IAAI,KAAK,OAAO,CAAC;AACpD,aAAS,IAAI,IAAI,IAAI,IAAI,CAAC,MAAM,EAAE,EAAE,EAAE,OAAO,CAAC,OAAqB,OAAO,OAAO,QAAQ,CAAC;AAAA,EAC5F,SAAS,KAAK;AACZ,WAAO;AAAA,MACL,WAAW;AAAA,MACX,OAAO;AAAA,MACP,OAAO,wBAAwB,OAAO,yBAAoB,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,IAC5G;AAAA,EACF;AAEA,QAAM,UAA4B,CAAC;AACnC,aAAW,SAAS,KAAK,QAAQ;AAC/B,UAAM,SAAS,OAAO,IAAI,KAAK;AAC/B,QAAI,CAAC,KAAK,OAAO;AACf,cAAQ,KAAK,EAAE,OAAO,QAAQ,QAAQ,MAAM,QAAQ,MAAM,QAAQ,KAAK,CAAC;AACxE;AAAA,IACF;AACA,QAAI;AACF,YAAM,MAAM,MAAM,UAAU,GAAG,OAAO,qBAAqB;AAAA,QACzD,QAAQ;AAAA,QACR,SAAS,EAAE,GAAG,aAAa,gBAAgB,mBAAmB;AAAA,QAC9D,MAAM,KAAK,UAAU;AAAA,UACnB;AAAA,UACA,UAAU,CAAC,EAAE,MAAM,QAAQ,SAAS,OAAO,CAAC;AAAA,UAC5C,YAAY;AAAA,QACd,CAAC;AAAA,MACH,CAAC;AACD,UAAI,SAAwB;AAC5B,UAAI,CAAC,IAAI,IAAI;AACX,cAAM,OAAO,MAAM,IAAI,KAAK,EAAE,MAAM,MAAM,IAAI;AAC9C,iBAAS,aAAa,IAAI;AAAA,MAC5B;AACA,cAAQ,KAAK,EAAE,OAAO,QAAQ,QAAQ,IAAI,IAAI,QAAQ,IAAI,QAAQ,OAAO,CAAC;AAAA,IAC5E,SAAS,KAAK;AACZ,aAAO;AAAA,QACL,WAAW;AAAA,QACX,OAAO;AAAA,QACP,OAAO,+BAA+B,OAAO,4BAA4B,KAAK,mBAAc,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,MAC9I;AAAA,IACF;AAAA,EACF;AAEA,SAAO,EAAE,WAAW,MAAM,OAAO,SAAS,OAAO,KAAK;AACxD;AAEO,IAAM,yBAAN,cAAqC,eAAe;AAAA,EACzD,YACE,SACgB,SAChB;AACA,UAAM,UAAU,OAAO;AAFP;AAGhB,SAAK,OAAO;AAAA,EACd;AAAA,EAJkB;AAKpB;AAEA,SAAS,gBAAgB,GAA2B;AAClD,MAAI,CAAC,EAAE,QAAQ;AACb,UAAM,YACJ,EAAE,WAAW,QAAQ,WAAW,EAAE,MAAM,GAAG,EAAE,SAAS,KAAK,EAAE,MAAM,KAAK,EAAE,MAAM;AAClF,WAAO,GAAG,EAAE,KAAK,mBAAmB,SAAS;AAAA,EAC/C;AAEA,SAAO,GAAG,EAAE,KAAK,sBAAsB,EAAE,MAAM,GAAG,EAAE,SAAS,WAAM,EAAE,MAAM,KAAK,EAAE;AACpF;AASA,eAAsB,mBAAmB,MAAyD;AAChG,QAAM,UAAU,MAAM,gBAAgB,IAAI;AAC1C,MAAI,CAAC,QAAQ,aAAa,QAAQ,UAAU,MAAM;AAChD,UAAM,IAAI;AAAA,MACR,QAAQ,SAAS;AAAA,IACnB;AAAA,EACF;AACA,QAAM,OAAO,QAAQ,MAAM,OAAO,CAAC,MAAM,CAAC,EAAE,UAAU,EAAE,WAAW,KAAK;AACxE,MAAI,KAAK,SAAS,GAAG;AACnB,UAAM,IAAI;AAAA,MACR,uBAAuB,KAAK,MAAM,IAAI,QAAQ,MAAM,MAAM,8CAAyC,KAChG,IAAI,eAAe,EACnB,KAAK,IAAI,CAAC;AAAA,MACb,QAAQ;AAAA,IACV;AAAA,EACF;AACA,SAAO,QAAQ;AACjB;;;AChIO,IAAM,qBAAN,cAAiC,eAAe;AAAA,EACrD,YACE,SACgB,QAChB;AACA,UAAM,qBAAqB,OAAO;AAFlB;AAGhB,SAAK,OAAO;AAAA,EACd;AAAA,EAJkB;AAKpB;AAEA,SAASE,YAAW,KAAqB;AACvC,SAAO,IAAI,QAAQ,QAAQ,EAAE;AAC/B;AAOO,SAAS,oBACd,OACA,OACA,OAAmC,CAAC,GACf;AACrB,QAAM,cAAyC,CAAC;AAEhD,MAAI,MAAM,SAAS,MAAM,MAAM;AAC7B,gBAAY,KAAK,EAAE,OAAO,QAAQ,OAAO,MAAM,MAAM,OAAO,MAAM,KAAK,CAAC;AAAA,EAC1E;AACA,MAAIA,YAAW,MAAM,OAAO,MAAMA,YAAW,MAAM,OAAO,GAAG;AAC3D,gBAAY,KAAK,EAAE,OAAO,WAAW,OAAO,MAAM,SAAS,OAAO,MAAM,QAAQ,CAAC;AAAA,EACnF;AACA,MAAI,MAAM,UAAU,MAAM,OAAO;AAC/B,gBAAY,KAAK,EAAE,OAAO,SAAS,OAAO,MAAM,OAAO,OAAO,MAAM,MAAM,CAAC;AAAA,EAC7E;AAEA,MAAI,MAAM,aAAa,MAAM,UAAU;AACrC,gBAAY,KAAK,EAAE,OAAO,YAAY,OAAO,MAAM,UAAU,OAAO,MAAM,SAAS,CAAC;AAAA,EACtF;AAEA,QAAM,cAAc,QAAQ,MAAM,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;;;ACnEA,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;;;ACpGO,SAAS,SAAS,MAA+B,MAAuC;AAC7F,QAAM,EAAE,aAAa,aAAa,IAAI;AACtC,MAAI,gBAAgB,cAAc;AAChC,UAAM,IAAI;AAAA,MACR,oDAAoD,WAAW;AAAA,IACjE;AAAA,EACF;AAGA,QAAM,QAAQ,oBAAI,IAAyC;AAC3D,QAAM,WAAW,oBAAI,IAAY;AACjC,aAAW,OAAO,MAAM;AACtB,aAAS,IAAI,IAAI,GAAG;AACpB,QAAI,IAAI,QAAQ,eAAe,IAAI,QAAQ,aAAc;AACzD,UAAM,QAAQ,MAAM,IAAI,IAAI,GAAG,KAAK,oBAAI,IAA4B;AACpE,UAAM,QAAQ,MAAM,IAAI,IAAI,OAAO,KAAK,CAAC;AACzC,UAAM,KAAK,GAAG;AACd,UAAM,IAAI,IAAI,SAAS,KAAK;AAC5B,UAAM,IAAI,IAAI,KAAK,KAAK;AAAA,EAC1B;AAEA,aAAW,OAAO,CAAC,aAAa,YAAY,GAAG;AAC7C,QAAI,CAAC,MAAM,IAAI,GAAG,GAAG;AACnB,YAAM,OAAO,CAAC,GAAG,QAAQ,EAAE,KAAK,EAAE,KAAK,IAAI,KAAK;AAChD,YAAM,IAAI,gBAAgB,8BAA8B,GAAG,oBAAoB,IAAI,GAAG;AAAA,IACxF;AAAA,EACF;AAEA,QAAM,gBAAgB,MAAM,IAAI,WAAW;AAC3C,QAAM,iBAAiB,MAAM,IAAI,YAAY;AAE7C,QAAM,UAAU,CAAC,GAAG,oBAAI,IAAI,CAAC,GAAG,cAAc,KAAK,GAAG,GAAG,eAAe,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK;AACvF,QAAM,QAAuB,CAAC;AAC9B,QAAM,mBAAmC,CAAC;AAC1C,QAAM,oBAAoC,CAAC;AAC3C,aAAWC,YAAW,SAAS;AAC7B,UAAM,IAAI,cAAc,IAAIA,QAAO,KAAK,CAAC;AACzC,UAAM,IAAI,eAAe,IAAIA,QAAO,KAAK,CAAC;AAE1C,QAAI,EAAE,UAAU,KAAK,EAAE,UAAU,GAAG;AAClC,UAAI,EAAE,WAAW,KAAK,EAAE,WAAW,GAAG;AACpC,cAAM,KAAK,EAAE,SAAAA,UAAS,UAAU,GAAG,UAAU,EAAE,CAAC,GAAI,WAAW,EAAE,CAAC,EAAG,CAAC;AAAA,MACxE,OAAO;AACL,yBAAiB,KAAK,GAAG,CAAC;AAC1B,0BAAkB,KAAK,GAAG,CAAC;AAAA,MAC7B;AACA;AAAA,IACF;AAEA,UAAM,SAAS,cAAc,GAAGA,UAAS,WAAW;AACpD,UAAM,SAAS,cAAc,GAAGA,UAAS,YAAY;AACrD,UAAM,UAAU,CAAC,GAAG,oBAAI,IAAI,CAAC,GAAG,OAAO,KAAK,GAAG,GAAG,OAAO,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK;AACxE,QAAI,WAAW;AACf,eAAW,UAAU,SAAS;AAC5B,YAAM,WAAW,OAAO,IAAI,MAAM;AAClC,YAAM,YAAY,OAAO,IAAI,MAAM;AACnC,UAAI,aAAa,UAAa,cAAc,QAAW;AACrD,cAAM,KAAK,EAAE,SAAAA,UAAS,UAAU,YAAY,UAAU,UAAU,CAAC;AAAA,MACnE,WAAW,aAAa,QAAW;AACjC,yBAAiB,KAAK,QAAQ;AAAA,MAChC,WAAW,cAAc,QAAW;AAClC,0BAAkB,KAAK,SAAS;AAAA,MAClC;AAAA,IACF;AAAA,EACF;AAEA,SAAO,EAAE,OAAO,kBAAkB,kBAAkB;AACtD;AAIA,SAAS,cACP,OACAA,UACA,KAC2B;AAC3B,QAAM,QAAQ,oBAAI,IAA0B;AAC5C,aAAW,OAAO,OAAO;AACvB,QAAI,IAAI,WAAW,QAAW;AAC5B,YAAM,IAAI;AAAA,QACR,sBAAsBA,QAAO,oDAAoD,GAAG;AAAA,MAGtF;AAAA,IACF;AACA,QAAI,MAAM,IAAI,IAAI,MAAM,GAAG;AACzB,YAAM,IAAI;AAAA,QACR,+BAA+B,IAAI,MAAM,kBAAkBA,QAAO,aAAa,GAAG;AAAA,MAEpF;AAAA,IACF;AACA,UAAM,IAAI,IAAI,QAAQ,GAAG;AAAA,EAC3B;AACA,SAAO;AACT;AAiEO,SAAS,kBACd,MACA,MACsB;AACtB,QAAM,EAAE,OAAO,kBAAkB,kBAAkB,IAAI,SAAS,MAAM,IAAI;AAE1E,MAAI,cAAwC;AAC5C,QAAM,eAAyB,CAAC;AAChC,QAAM,gBAA0B,CAAC;AACjC,aAAW,QAAQ,OAAO;AACxB,QAAI,KAAK,SAAS,SAAS,UAAa,KAAK,UAAU,SAAS,OAAW;AAC3E,iBAAa,KAAK,KAAK,SAAS,OAAO,IAAI,CAAC;AAC5C,kBAAc,KAAK,KAAK,UAAU,OAAO,IAAI,CAAC;AAAA,EAChD;AACA,MAAI,aAAa,SAAS,GAAG;AAC3B,UAAM,KAAK,QAAQ,cAAc,aAAa;AAC9C,kBAAc;AAAA,MACZ,KAAK,GAAG;AAAA,MACR,KAAK,GAAG;AAAA,MACR,SAAS;AAAA,MACT,gBAAgB,qBAAqB,cAAc,aAAa;AAAA,IAClE;AAAA,EACF;AAEA,QAAM,cACJ,KAAK,eACL;AAAA,IACE,GAAG,IAAI;AAAA,MACL,MAAM,QAAQ,CAAC,MAAM;AAAA,QACnB,GAAG,OAAO,KAAK,EAAE,SAAS,WAAW,CAAC,CAAC;AAAA,QACvC,GAAG,OAAO,KAAK,EAAE,UAAU,WAAW,CAAC,CAAC;AAAA,MAC1C,CAAC;AAAA,IACH;AAAA,EACF,EAAE,KAAK;AAET,QAAM,eAAoC,YAAY,IAAI,CAAC,SAAS;AAClE,UAAM,SAAmB,CAAC;AAC1B,UAAM,QAAkB,CAAC;AACzB,QAAI,WAAW;AACf,eAAW,QAAQ,OAAO;AACxB,YAAM,IAAI,YAAY,KAAK,UAAU,IAAI;AACzC,YAAM,IAAI,YAAY,KAAK,WAAW,IAAI;AAC1C,UAAI,MAAM,UAAa,MAAM,QAAW;AACtC;AACA;AAAA,MACF;AACA,aAAO,KAAK,CAAC;AACb,YAAM,KAAK,CAAC;AAAA,IACd;AACA,UAAMC,eAAc,OAAO,WAAW,IAAI,OAAO,gBAAgB,QAAQ,OAAO,KAAK,SAAS;AAC9F,WAAO;AAAA,MACL;AAAA,MACA,GAAG,OAAO;AAAA,MACV;AAAA,MACA,aAAaA,iBAAgB,OAAO,OAAO,MAAMA,aAAY;AAAA,MAC7D,WAAWA,iBAAgB,OAAO,OAAO,MAAMA,aAAY;AAAA,MAC3D,aAAAA;AAAA,MACA,UAAU,OAAO,WAAW,IAAI,OAAO,mBAAmB,QAAQ,KAAK;AAAA,IACzE;AAAA,EACF,CAAC;AAED,SAAO;AAAA,IACL,QAAQ,MAAM;AAAA,IACd,mBAAmB,iBAAiB;AAAA,IACpC,oBAAoB,kBAAkB;AAAA,IACtC;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,YAAY,KAAmB,MAAkC;AACxE,QAAM,IAAI,IAAI,UAAU,IAAI;AAC5B,MAAI,MAAM,OAAW,QAAO;AAC5B,MAAI,CAAC,OAAO,SAAS,CAAC,GAAG;AACvB,UAAM,IAAI;AAAA,MACR,mDAAmD,IAAI,iBAAiB,IAAI,OAAO,WAAW,IAAI,GAAG,OAAO,CAAC;AAAA,IAC/G;AAAA,EACF;AACA,SAAO;AACT;;;AC7OO,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,QAAMC,WAAoC,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,IAAAA,SAAQ,KAAK,EAAE,aAAa,UAAU,IAAI,WAAW,KAAK,QAAQ,IAAI,OAAO,KAAK,MAAM,CAAC;AAAA,EAC3F;AAEA,SAAOA;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,YACAA,UACS;AACT,MAAI,CAAC,QAAQ,SAAU,QAAO;AAC9B,QAAM,QAAQA,SAAQ,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;;;AChDO,SAAS,qBACd,OACA,OAA6B,CAAC,GACf;AACf,QAAM,WAAW,KAAK,2BAA2B;AAEjD,MAAI,gBAAgB;AACpB,MAAI,eAAe;AACnB,aAAW,CAAC,MAAM,KAAK,KAAK,OAAO,QAAQ,MAAM,aAAa,GAAG;AAC/D,UAAM,IAAI,OAAO,SAAS,KAAK,KAAK,QAAQ,IAAI,QAAQ;AACxD,qBAAiB;AACjB,QAAI,IAAI,KAAK,MAAM,QAAQ,IAAI,EAAG,iBAAgB;AAAA,EACpD;AAEA,MAAI,kBAAkB,GAAG;AACvB,WAAO,WACH;AAAA,MACE,SAAS;AAAA,MACT,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,cAAc;AAAA,MACd,eAAe;AAAA,IACjB,IACA;AAAA,MACE,SAAS;AAAA,MACT,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,cAAc;AAAA,MACd,eAAe;AAAA,IACjB;AAAA,EACN;AAEA,MAAI,iBAAiB,GAAG;AACtB,WAAO;AAAA,MACL,SAAS;AAAA,MACT,OAAO;AAAA,MACP,QAAQ,+BAA+B,aAAa;AAAA,MACpD,cAAc;AAAA,MACd;AAAA,IACF;AAAA,EACF;AAEA,SAAO,EAAE,SAAS,MAAM,OAAO,OAAO,cAAc,cAAc;AACpE;AAOO,SAAS,yBACd,SACAC,UACA,MACe;AACf,SAAO,qBAAqB,EAAE,eAAe,QAAQ,eAAe,SAAAA,SAAQ,GAAG,IAAI;AACrF;AAOO,SAAS,uBACd,OACAA,UACA,MACe;AACf,SAAO,yBAAyB,oBAAoB,KAAK,GAAGA,UAAS,IAAI;AAC3E;AAOO,SAAS,2BACdC,YACAD,UACA,MACe;AACf,QAAM,gBAAwC,CAAC;AAC/C,aAAW,KAAKC,YAAW;AACzB,QAAI,EAAE,SAAU,eAAc,EAAE,QAAQ,KAAK,cAAc,EAAE,QAAQ,KAAK,KAAK;AAAA,EACjF;AACA,SAAO,qBAAqB,EAAE,eAAe,SAAAD,SAAQ,GAAG,IAAI;AAC9D;AAgBO,SAAS,kBAAkB,SAAoB,MAAqC;AACzF,SAAO,KAAK,QAAQ,0BAA0B;AAChD;;;ACtIA,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,MAAM,QAAQ,QAAQ,CAAC;AACjC,aAAO,QAAQ,IAAI;AACjB,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,cAAM,MAAM,QAAQ,QAAQ,MAAM,OAAO,MAAM;AAAA,MACjD;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,YAAME,WAAU,OAAO;AAAA,QACrB,IAAI,OAAO,IAAI,GAAG,MAAM,SAAS,GAAG,IAAI,GAAG,QAAQ,GAAG,GAAG,KAAK,GAAG;AAAA,MACnE;AACA,UAAIA,UAAS;AACX,eAAO,WAAWA,SAAQ;AAC1B,eAAO,KAAK;AAAA,UACV,UAAU;AAAA,UACV,QAAQ,GAAGA,SAAQ,MAAM,KAAK,GAAG,MAAM;AAAA,UACvC,SAASA,SAAQ,CAAC;AAAA,QACpB,CAAC;AAAA,MACH;AAAA,IACF;AAEA,eAAW,MAAM,OAAO,iBAAiB;AACvC,YAAMA,WAAU,OAAO;AAAA,QACrB,IAAI,OAAO,IAAI,GAAG,MAAM,SAAS,GAAG,IAAI,GAAG,QAAQ,GAAG,GAAG,KAAK,GAAG;AAAA,MACnE;AACA,UAAIA,UAAS;AACX,eAAO,WAAWA,SAAQ;AAC1B,eAAO,KAAK;AAAA,UACV,UAAU;AAAA,UACV,QAAQ,GAAGA,SAAQ,MAAM,KAAK,GAAG,MAAM;AAAA,UACvC,SAASA,SAAQ,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;;;AClJO,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;;;ACnJA,SAAS,gBAAgB;AAiClB,SAAS,aAAa,KAG3B;AACA,SAAO;AAAA,IACL,MAAM;AAAA,IACN,UAAU,EAAE,MAAM,IAAI,MAAM,aAAa,IAAI,aAAa,YAAY,IAAI,WAAW;AAAA,EACvF;AACF;AAOO,SAAS,cAAc,KAAyC;AACrE,QAAM,QAAuB,CAAC;AAC9B,MAAI,IAAI,OAAQ,OAAM,KAAK,cAAc,IAAI,MAAM,CAAC;AACpD,MAAI,IAAI,WAAY,OAAM,KAAK,qBAAqB,IAAI,WAAW,gBAAgB,CAAC;AACpF,MAAI,IAAI,QAAS,OAAM,KAAK,gBAAgB,IAAI,OAAO,CAAC;AACxD,SAAO;AACT;AAIA,SAAS,cAAc,QAAkD;AACvE,MAAI,OAAO,WAAW,GAAG;AACvB,UAAM,IAAI,MAAM,6EAAwE;AAAA,EAC1F;AACA,QAAM,QAAQ,OAAO,IAAI,CAAC,MAAM,EAAE,IAAI;AACtC,SAAO;AAAA,IACL,MAAM;AAAA,IACN,aACE,iDAAiD,MAAM,KAAK,IAAI,CAAC;AAAA,IAGnE,YAAY;AAAA,MACV,MAAM;AAAA,MACN,YAAY;AAAA,QACV,OAAO;AAAA,UACL,MAAM;AAAA,UACN,MAAM;AAAA,UACN,aAAa;AAAA,QACf;AAAA,QACA,UAAU;AAAA,UACR,aAAa;AAAA,QACf;AAAA,QACA,UAAU;AAAA,UACR,aAAa;AAAA,QACf;AAAA,MACF;AAAA,MACA,UAAU,CAAC,UAAU;AAAA,MACrB,sBAAsB;AAAA,IACxB;AAAA,IACA,SAAS,OAAO,MAAM,QAAQ;AAC5B,YAAM,IAAI,kBAAkB,cAAc,IAAI;AAC9C,UAAI,EAAE,cAAc,IAAI;AACtB,cAAM,IAAI,MAAM,uCAAuC;AAAA,MACzD;AACA,UAAI,WAAW;AACf,UAAI,EAAE,UAAU,QAAW;AACzB,YAAI,OAAO,EAAE,UAAU,SAAU,OAAM,IAAI,MAAM,yCAAyC;AAC1F,mBAAW,OAAO,OAAO,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK;AAClD,YAAI,SAAS,WAAW,GAAG;AACzB,gBAAM,IAAI;AAAA,YACR,8BAA8B,EAAE,KAAK,wBAAmB,MAAM,KAAK,IAAI,CAAC;AAAA,UAC1E;AAAA,QACF;AAAA,MACF;AACA,YAAM,SAAS,KAAK,UAAU,IAAI,gBAAgB,EAAE;AACpD,YAAM,WAAW,EAAE;AACnB,YAAMC,UAAqC,CAAC;AAC5C,iBAAW,SAAS,UAAU;AAC5B,YAAI,aAAa,UAAa,MAAM,aAAa,CAAC,MAAM,UAAU,QAAQ,EAAG;AAC7E,QAAAA,QAAO,MAAM,IAAI,IAAI,MAAM,MAAM,MAAM,EAAE,UAAU,EAAE,UAAU,UAAU,OAAO,CAAC;AAAA,MACnF;AACA,aAAO,EAAE,QAAAA,QAAO;AAAA,IAClB;AAAA,EACF;AACF;AAIA,SAAS,qBAAqB,kBAAmD;AAC/E,SAAO;AAAA,IACL,MAAM;AAAA,IACN,aACE;AAAA,IAIF,YAAY;AAAA,MACV,MAAM;AAAA,MACN,YAAY;AAAA,QACV,MAAM;AAAA,UACJ,MAAM;AAAA,UACN,aAAa;AAAA,QACf;AAAA,QACA,OAAO;AAAA,UACL,MAAM;AAAA,UACN,aAAa;AAAA,QACf;AAAA,MACF;AAAA,MACA,UAAU,CAAC,QAAQ,OAAO;AAAA,MAC1B,sBAAsB;AAAA,IACxB;AAAA,IACA,SAAS,OAAO,SAAqC;AACnD,YAAM,IAAI,kBAAkB,qBAAqB,IAAI;AACrD,UAAI,OAAO,EAAE,SAAS,YAAY,EAAE,SAAS,MAAM;AACjD,cAAM,IAAI,MAAM,qDAAqD;AAAA,MACvE;AACA,UAAI,OAAO,EAAE,UAAU,YAAY,EAAE,UAAU,MAAM;AACnD,cAAM,IAAI,MAAM,2DAA2D;AAAA,MAC7E;AACA,aAAO,iBAAiB,EAAE,MAAkB,EAAE,OAAwB,gBAAgB;AAAA,IACxF;AAAA,EACF;AACF;AAIA,SAAS,gBAAgB,aAA4D;AACnF,SAAO;AAAA,IACL,MAAM;AAAA,IACN,aACE;AAAA,IAIF,YAAY;AAAA,MACV,MAAM;AAAA,MACN,YAAY;AAAA,QACV,MAAM;AAAA,UACJ,MAAM;AAAA,UACN,OAAO,EAAE,MAAM,SAAS;AAAA,UACxB,aAAa;AAAA,QACf;AAAA,QACA,MAAM;AAAA,UACJ,MAAM;AAAA,UACN,aAAa;AAAA,QACf;AAAA,MACF;AAAA,MACA,sBAAsB;AAAA,IACxB;AAAA,IACA,SAAS,OAAO,SAAS;AACvB,YAAM,IAAI,kBAAkB,gBAAgB,IAAI;AAChD,YAAM,UAAU,MAAM,QAAQ,EAAE,IAAI;AACpC,YAAM,UAAU,OAAO,EAAE,SAAS,YAAY,EAAE,KAAK,SAAS;AAC9D,UAAI,YAAY,SAAS;AACvB,cAAM,IAAI,MAAM,2EAA2E;AAAA,MAC7F;AACA,YAAM,OAAO,UAAW,EAAE,OAAuB,MAAM,eAAe,EAAE,IAAc;AACtF,UAAI,KAAK,WAAW,GAAG;AACrB,cAAM,IAAI,MAAM,kCAAkC;AAAA,MACpD;AACA,aAAO,YAAY,EAAE,GAAG,aAAa,KAAK,CAAC;AAAA,IAC7C;AAAA,EACF;AACF;AAEA,eAAe,eAAe,MAAoC;AAChE,QAAM,OAAO,MAAM,SAAS,MAAM,MAAM;AACxC,QAAM,UAAU,KAAK,KAAK;AAC1B,MAAI,QAAQ,WAAW,GAAG;AACxB,UAAM,IAAI,MAAM,uBAAuB,IAAI,YAAY;AAAA,EACzD;AACA,MAAI,QAAQ,WAAW,GAAG,GAAG;AAC3B,UAAM,SAAS,KAAK,MAAM,OAAO;AACjC,QAAI,CAAC,MAAM,QAAQ,MAAM,GAAG;AAC1B,YAAM,IAAI,MAAM,uBAAuB,IAAI,6BAA6B;AAAA,IAC1E;AACA,WAAO;AAAA,EACT;AAGA,SAAO,QAAQ,MAAM,IAAI,EAAE,QAAQ,CAAC,MAAM,MAAM;AAC9C,UAAM,IAAI,KAAK,KAAK;AACpB,QAAI,EAAE,WAAW,EAAG,QAAO,CAAC;AAC5B,QAAI;AACF,aAAO,CAAC,KAAK,MAAM,CAAC,CAAc;AAAA,IACpC,SAAS,KAAK;AACZ,YAAM,IAAI;AAAA,QACR,uBAAuB,IAAI,UAAU,IAAI,CAAC,uBAAuB,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,MACnH;AAAA,IACF;AAAA,EACF,CAAC;AACH;AAEA,SAAS,kBAAkB,MAAc,MAAwC;AAC/E,MAAI,OAAO,SAAS,YAAY,SAAS,QAAQ,MAAM,QAAQ,IAAI,GAAG;AACpE,UAAM,IAAI,MAAM,GAAG,IAAI,0BAA0B;AAAA,EACnD;AACA,SAAO;AACT;;;AC9IO,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;;;AC1JO,SAAS,uBACd,UACA,eACA,SACsB;AACtB,MAAI,SAAS,WAAW,GAAG;AACzB,UAAM,IAAI,MAAM,kDAAkD;AAAA,EACpE;AACA,MAAI,cAAc,WAAW,GAAG;AAC9B,UAAM,IAAI,MAAM,gDAAgD;AAAA,EAClE;AAEA,QAAM,WAA8C,CAAC;AACrD,QAAM,eAAyB,CAAC;AAChC,QAAM,SAAS,CAAC;AAChB,aAAW,KAAK,cAAe,QAAO,CAAC,IAAI,CAAC;AAC5C,MAAI,YAAY;AAChB,MAAI,UAAU;AAKd,QAAM,YAAY,oBAAI,IAAoB;AAC1C,QAAM,SAAS,CAAC,UAA0B;AACxC,UAAM,KAAK,UAAU,IAAI,KAAK,KAAK,KAAK;AACxC,cAAU,IAAI,OAAO,CAAC;AACtB,WAAO,MAAM,IAAI,QAAQ,GAAG,KAAK,IAAI,CAAC;AAAA,EACxC;AAEA,aAAW,KAAK,UAAU;AACxB,eAAW,EAAE,WAAW;AACxB,UAAM,MAAM,OAAO,EAAE,KAAK;AAC1B,QAAI,CAAC,EAAE,cAAc;AACnB,mBAAa,KAAK,GAAG;AACrB;AAAA,IACF;AACA,UAAM,OAAO,CAAC;AACd,eAAW,KAAK,cAAe,MAAK,CAAC,IAAI,QAAQ,OAAO,EAAE,aAAa,CAAC,CAAC,CAAC;AAC1E,aAAS,GAAG,IAAI;AAChB,eAAW,KAAK,cAAe,QAAO,CAAC,EAAE,KAAK,KAAK,CAAC,CAAC;AACrD,QAAI,CAAC,aAAa,OAAO,EAAE,cAAc,YAAY,EAAE,UAAW,aAAY,EAAE;AAAA,EAClF;AAEA,MAAI,aAAa,WAAW,SAAS,QAAQ;AAC3C,UAAM,IAAI,MAAM,+BAA+B,SAAS,MAAM,gBAAgB;AAAA,EAChF;AAEA,QAAM,eAAe,CAAC;AACtB,aAAW,KAAK,eAAe;AAC7B,UAAM,OAAO,OAAO,CAAC;AACrB,iBAAa,CAAC,IAAI,KAAK,WAAW,IAAI,IAAI,KAAK,OAAO,CAAC,GAAG,MAAM,IAAI,GAAG,CAAC,IAAI,KAAK;AAAA,EACnF;AAEA,MAAI,kBAAkB;AACtB,aAAW,KAAK,eAAe;AAC7B,UAAM,OAAO,OAAO,CAAC;AACrB,QAAI,KAAK,SAAS,EAAG;AACrB,UAAM,SAAS,KAAK,IAAI,GAAG,IAAI,IAAI,KAAK,IAAI,GAAG,IAAI;AACnD,QAAI,SAAS,gBAAiB,mBAAkB;AAAA,EAClD;AAEA,QAAM,IAA4B,CAAC;AACnC,MAAI,SAAS;AACX,eAAW,CAAC,GAAG,MAAM,KAAK,OAAO,QAAQ,OAAO,GAAG;AACjD,UAAI,WAAW,OAAW,GAAE,CAAC,IAAI;AAAA,IACnC;AAAA,EACF,OAAO;AACL,eAAW,KAAK,cAAe,GAAE,CAAC,IAAI,IAAI,cAAc;AAAA,EAC1D;AACA,QAAM,YAAY,kBAAkB,EAAE,MAAM,cAAc,SAAS,EAAE,CAAC,EAAE;AAExE,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,WAAW,aAAa;AAAA,IACxB,UAAU,CAAC,GAAG,QAAQ;AAAA,EACxB;AACF;;;AC1FA,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;;;AC7EO,SAAS,cACd,MACsB;AACtB,MAAI,KAAK,OAAO,WAAW,GAAG;AAC5B,UAAM,IAAI,MAAM,kBAAkB,KAAK,IAAI,iDAA4C;AAAA,EACzF;AACA,MAAI,KAAK,WAAW,WAAW,GAAG;AAChC,UAAM,IAAI,MAAM,kBAAkB,KAAK,IAAI,gDAA2C;AAAA,EACxF;AACA,MAAI,KAAK,gBAAgB,OAAO;AAC9B,sBAAkB,KAAK,MAAM;AAAA,EAC/B;AAEA,QAAM,WAAW,OACf,OACA,UAC6B;AAC7B,QAAI,KAAK,OAAO;AACd,YAAM,UAAU,MAAM,eAAe,CAAC,MAAM,KAAK,UAAU,GAAG,KAAK,GAAG;AAAA,QACpE,GAAG,KAAK;AAAA,QACR,QAAQ,CAAC,KAAK;AAAA,MAChB,CAAC;AACD,UAAI,CAAC,QAAQ,aAAa,QAAQ,UAAU,MAAM;AAChD,eAAO;AAAA,UACL;AAAA,UACA,cAAc;AAAA,UACd,WAAW,QAAQ,OAAO,WAAW;AAAA,QACvC;AAAA,MACF;AACA,aAAO,QAAQ;AAAA,IACjB;AACA,QAAI;AACF,aAAO,MAAM,KAAK,UAAU,OAAO,KAAK;AAAA,IAC1C,SAAS,KAAK;AACZ,aAAO;AAAA,QACL;AAAA,QACA,cAAc;AAAA,QACd,WAAW,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,MAC5D;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,MAAM,KAAK;AAAA,IACX,YAAY,KAAK,WAAW,IAAI,CAAC,OAAO,EAAE,KAAK,GAAG,aAAa,EAAE,EAAE;AAAA,IACnE,MAAM,MAAM,EAAE,UAAU,SAAS,GAAwB;AACvD,YAAM,QAAQ,EAAE,UAAU,SAAS;AACnC,YAAM,WAAW,MAAM,QAAQ,IAAI,KAAK,OAAO,IAAI,CAAC,UAAU,SAAS,OAAO,KAAK,CAAC,CAAC;AAErF,YAAM,MAAM,uBAAuB,UAAU,KAAK,YAAY,KAAK,OAAO;AAC1E,YAAM,QAAoB;AAAA,QACxB,YAAY,IAAI;AAAA,QAChB,WAAW,IAAI;AAAA,QACf,OAAO,IAAI;AAAA,QACX,iBAAiB,IAAI;AAAA,QACrB,UAAU,IAAI;AAAA,MAChB;AACA,UAAI,IAAI,aAAa,SAAS,EAAG,OAAM,eAAe,IAAI;AAC1D,aAAO;AAAA,IACT;AAAA,EACF;AACF;;;AChIA,SAAS,YAAY;AAuCd,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,UAAMC,WAAgC,CAAC;AACvC,eAAW,QAAQ,MAAO,CAAAA,SAAQ,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC;AAC7D,WAAOA;AAAA,EACT;AACA,QAAM,cAAc,KAAK,IAAI,GAAG,QAAQ,eAAe,KAAK,EAAE,MAAM;AACpE,QAAM,UAAgC,IAAI,MAAM,MAAM,MAAM;AAC5D,MAAI,SAAS;AACb,iBAAe,SAAwB;AACrC,WAAO,MAAM;AACX,YAAM,IAAI;AACV,UAAI,KAAK,MAAM,OAAQ;AACvB,cAAQ,CAAC,IAAI,MAAM,OAAO,IAAI,MAAM,CAAC,CAAE;AAAA,IACzC;AAAA,EACF;AACA,QAAM,QAAQ,IAAI,MAAM,KAAK,EAAE,QAAQ,KAAK,IAAI,aAAa,MAAM,MAAM,EAAE,GAAG,MAAM,OAAO,CAAC,CAAC;AAC7F,SAAO;AACT;AAGO,SAAS,cAAc,IAAY,QAAyC;AACjF,SAAO,EAAE,IAAI,MAAM,YAAY,OAAO;AACxC;AAGO,SAAS,UAAU,IAAY,QAAyC;AAC7E,SAAO,EAAE,IAAI,MAAM,QAAQ,OAAO;AACpC;AAGO,SAAS,YAAY,IAAY,QAAyC;AAC/E,SAAO,EAAE,IAAI,MAAM,UAAU,OAAO;AACtC;AAGO,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;;;ACxGO,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;;;AChCO,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,QAAQ,OAAO,QAAQ,OAAO,eAAe,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;AAC5F,aAAW,CAAC,MAAM,IAAI,KAAK,OAAO;AAChC,UAAM,KAAK,QAAQ,IAAI,WAAW,KAAK,UAAU,EAAE,WAAW,KAAK,UAAU,EAAE,EAAE;AAAA,EACnF;AACA,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;;;AC5DA,SAA2B,QAAQ,IAAI,UAAU;AAyD1C,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,qBAAqB,KAAK,OAAO,sBAAsB;AAC7D,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,oBAAoB;AACnE,aAAO;AAAA,QACL,GAAG;AAAA,QACH,SAAS;AAAA,QACT,SAAS;AAAA,QACT,WAAW,2CAA2C,kBAAkB,0BAA0B,WAAW,MAAM,mBAAmB,WAAW,MAAM;AAAA,MACzJ;AAAA,IACF;AAEA,UAAM,YAAY,qEAAqE,WAAW,KAAK,IAAI,CAAC;AAC5G,UAAM,WAAW,GAGf,WAAW;AAAA,MACX,aAAa;AAAA,IACf,CAAC;AACD,UAAM,WAAW,cAAc,YAAY,SAAS;AACpD,UAAM,aAAa,KAAK,IAAI,GAAG,KAAK,MAAM,SAAS,SAAS,GAAG,CAAC;AAChE,UAAM,QAAQ,SAAS,MAAM,GAAG,UAAU;AAC1C,UAAM,aAAa,SAAS,MAAM,UAAU;AAC5C,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,gBAAgB,KAAK,OAAO,UAAU,KAAK,OAAO,QAAQ,KAAK,OAAO,KAAK;AAC7F,UAAM,YAAY,IAAI,OAAO;AAAA,MAC3B;AAAA,MACA,WAAW;AAAA,QACT,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,UACC,MAAM,YAAY,cAAc,MAAM,SAAS,YAAY,IAAI;AAAA,MACjE;AAAA,QACE,oBAAoB;AAAA,QACpB,gBAAgB;AAAA,MAClB;AAAA,IACF;AACA,QAAI,SAAS,qBAAqB,QAAW;AAC3C,eAAS,kBAAkB,SAAS,gBAAgB;AAAA,IACtD;AAKA,UAAM,gBAAgB,OAAO,QAA8D;AACzF,YAAM,aAAa,MAAM,SAAS,QAAQ,WAAW,GAAG;AACxD,aAAO;AAAA,QACL,WAAW,OAAO,WAAW,SAAS;AAAA,QACtC,WAAW,OAAO,WAAW,aAAa,EAAE;AAAA,MAC9C;AAAA,IACF;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,MACA;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,UACA,QACA,OACa;AACb,SAAO,GAAG;AAAA,IACR,MAAM;AAAA,IACN;AAAA,IACA,QAAQ,EAAE,MAAM;AAAA,EAClB,CAAC;AACH;AAKA,SAAS,cAAiB,OAAqB,MAAmB;AAChE,QAAM,MAAMC,YAAW,WAAW,IAAI,CAAC;AACvC,QAAM,MAAM,CAAC,GAAG,KAAK;AACrB,WAAS,IAAI,IAAI,SAAS,GAAG,IAAI,GAAG,KAAK;AACvC,UAAM,IAAI,KAAK,MAAM,IAAI,KAAK,IAAI,EAAE;AACnC,KAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAI,IAAI,CAAC,CAAE;AAAA,EACvC;AACA,SAAO;AACT;AAEA,SAAS,WAAW,OAAuB;AACzC,MAAI,IAAI;AACR,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,SAAK,MAAM,WAAW,CAAC;AACvB,QAAI,KAAK,KAAK,GAAG,QAAQ;AAAA,EAC3B;AACA,SAAO,MAAM;AACf;AAEA,SAASA,YAAW,MAA4B;AAC9C,MAAI,IAAI,SAAS;AACjB,SAAO,MAAM;AACX,QAAK,IAAI,aAAc;AACvB,QAAI,IAAI,KAAK,KAAK,IAAK,MAAM,IAAK,IAAI,CAAC;AACvC,QAAK,IAAI,KAAK,KAAK,IAAK,MAAM,GAAI,KAAK,CAAC,IAAK;AAC7C,aAAS,IAAK,MAAM,QAAS,KAAK;AAAA,EACpC;AACF;;;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;;;ACZA,IAAM,qBAAoD,oBAAI,IAAsB;AAAA,EAClF;AAAA,EACA;AACF,CAAC;AAGM,SAAS,oBAAoB,aAAwC;AAC1E,SAAO,mBAAmB,IAAI,WAAW;AAC3C;AAyBO,SAAS,YACd,SACA,QACe;AACf,QAAM,MAAqB,CAAC;AAC5B,aAAW,QAAQ,OAAO,KAAK,OAAO,GAAc;AAClD,UAAM,QAAQ,OAAO,IAAI;AACzB,QAAI,UAAU,QAAW;AACvB,YAAM,IAAI;AAAA,QACR,iBAAiB,IAAI;AAAA,MACvB;AAAA,IACF;AACA,QAAI,KAAK,EAAE,MAAM,OAAO,aAAa,QAAQ,IAAI,EAAE,CAAC;AAAA,EACtD;AACA,SAAO;AACT;AA0BO,SAAS,mBACd,QACA,cACA,OAAsB,CAAC,GACC;AACxB,QAAM,SAAS,KAAK,kBAAkB;AACtC,QAAM,QAAsB,CAAC;AAC7B,aAAW,SAAS,QAAQ;AAC1B,QAAI,CAAC,oBAAoB,MAAM,WAAW,EAAG;AAC7C,UAAM,SAAS,MAAM,MAAM,KAAK;AAChC,QAAI,OAAO,SAAS,OAAQ;AAC5B,QAAI,aAAa,SAAS,MAAM,GAAG;AACjC,YAAM,KAAK,EAAE,OAAO,MAAM,MAAM,aAAa,MAAM,YAAY,CAAC;AAAA,IAClE;AAAA,EACF;AACA,MAAI,MAAM,SAAS,GAAG;AACpB,UAAM,SAAS,MAAM,IAAI,CAAC,MAAM,IAAI,EAAE,KAAK,MAAM,EAAE,WAAW,GAAG,EAAE,KAAK,IAAI;AAC5E,UAAM,IAAI;AAAA,MACR,sCAAsC,MAAM,MAAM,+CAA+C,MAAM;AAAA,IACzG;AAAA,EACF;AACA,SAAO;AACT;AAOO,SAAS,mBAAmB,QAA+C;AAChF,SAAO,OAAO,OAAO,CAAC,MAAM,CAAC,oBAAoB,EAAE,WAAW,CAAC;AACjE;AAsCO,SAAS,YAAY,QAAgB,OAAe,OAAmC;AAC5F,QAAM,IAAI,OAAO,SAAS,MAAM,KAAK,SAAS,IAAI,KAAK,MAAM,MAAM,IAAI;AACvE,QAAM,IAAI,OAAO,SAAS,KAAK,KAAK,QAAQ,IAAI,KAAK,MAAM,KAAK,IAAI;AACpE,QAAM,WAAW,IAAI,IAAI,KAAK,IAAI,GAAG,IAAI,CAAC,IAAI;AAC9C,SAAO,EAAE,QAAQ,KAAK,IAAI,GAAG,IAAI,IAAI,IAAI,CAAC,GAAG,OAAO,GAAG,UAAU,MAAM;AACzE;AAWA,eAAsB,cAAkC,MAOzB;AAC7B,qBAAmB,KAAK,SAAS,QAAQ,KAAK,SAAS,cAAc,KAAK,SAAS,OAAO;AAC1F,QAAM,SAAS,MAAM,KAAK,OAAO,KAAK,UAAU,KAAK,gBAAgB,KAAK,MAAM;AAChF,SAAO,YAAY,OAAO,QAAQ,OAAO,OAAO,OAAO,KAAK;AAC9D;AAeO,IAAM,sBAAoC,EAAE,SAAS,KAAK,OAAO,IAAI;AAW5E,SAAS,iBAAiB,SAA2D;AACnF,QAAM,IAAI,OAAO,SAAS,QAAQ,OAAO,KAAK,QAAQ,WAAW,IAAI,QAAQ,UAAU;AACvF,QAAM,IAAI,OAAO,SAAS,QAAQ,KAAK,KAAK,QAAQ,SAAS,IAAI,QAAQ,QAAQ;AACjF,QAAMC,OAAM,IAAI;AAChB,MAAIA,QAAO,GAAG;AACZ,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,SAAO,EAAE,SAAS,IAAIA,MAAK,OAAO,IAAIA,KAAI;AAC5C;AAUO,SAAS,aACd,iBACA,YACA,UAAwB,qBAChB;AACR,QAAM,IAAI,iBAAiB,OAAO;AAClC,QAAM,UAAU,UAAU,eAAe;AACzC,QAAM,QAAQ,UAAU,UAAU;AAClC,SAAO,EAAE,UAAU,UAAU,EAAE,QAAQ;AACzC;AAeO,SAAS,iBACd,OACA,iBACA,UAAwB,qBACoC;AAC5D,SAAO,OAAO,UAA2D;AACvE,UAAM,OAAO,MAAM,MAAM,KAAK;AAC9B,QAAI,KAAK,OAAQ,QAAO;AACxB,UAAM,OAAO,UAAU,gBAAgB,MAAM,QAAQ,CAAC;AACtD,UAAM,YAAY,aAAa,MAAM,KAAK,WAAW,OAAO;AAC5D,UAAM,IAAI,iBAAiB,OAAO;AAClC,WAAO;AAAA,MACL,GAAG;AAAA,MACH;AAAA,MACA,OACE,aAAa,UAAU,QAAQ,CAAC,CAAC,eACnB,OAAO,KAAK,QAAQ,CAAC,CAAC,UAAO,EAAE,QAAQ,QAAQ,CAAC,CAAC,cACpD,KAAK,UAAU,QAAQ,CAAC,CAAC,SAAM,EAAE,MAAM,QAAQ,CAAC,CAAC,OAC3D,KAAK,QAAQ,WAAM,KAAK,KAAK,KAAK;AAAA,IACvC;AAAA,EACF;AACF;AAEA,SAAS,UAAU,OAAuB;AACxC,MAAI,CAAC,OAAO,SAAS,KAAK,EAAG,QAAO;AACpC,SAAO,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,KAAK,CAAC;AACvC;;;AClSO,SAAS,cAAc,OAA8B;AAC1D,SAAO,cAAc,KAAK,IAAI,QAAQ;AACxC;AAeO,SAAS,aAAa,OAAe,OAA8B;AACxE,oBAAkB,MAAM,aAAa,aAAa;AAClD,oBAAkB,MAAM,cAAc,cAAc;AACpD,MAAI,MAAM,iBAAiB,OAAW,mBAAkB,MAAM,cAAc,cAAc;AAC1F,QAAM,UAAU,oBAAoB,KAAK;AACzC,MAAI,CAAC,QAAS,QAAO,EAAE,SAAS,GAAG,aAAa,KAAK;AACrD,QAAM,cAAc,MAAM,eAAe,MAAM,gBAAgB;AAC/D,SAAO,EAAE,SAAS,aAAa,aAAa,MAAM,cAAc,KAAK,GAAG,aAAa,MAAM;AAC7F;AA+CO,IAAM,aAAN,MAAiB;AAAA,EACL,UAA6B,CAAC;AAAA,EACvC,iBAAiB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOzB,OAAO,OAOa;AAClB,UAAM,EAAE,SAAS,YAAY,IAAI,aAAa,MAAM,OAAO,MAAM,KAAK;AACtE,UAAM,YACJ,OAAO,MAAM,kBAAkB,YAAY,OAAO,SAAS,MAAM,aAAa;AAChF,QAAI,UAAW,mBAAkB,MAAM,eAAyB,eAAe;AAC/E,UAAM,QAAyB;AAAA,MAC7B,OAAO,MAAM;AAAA,MACb,SAAS,MAAM;AAAA,MACf,aAAa,MAAM,MAAM;AAAA,MACzB,cAAc,MAAM,MAAM;AAAA,MAC1B,cAAc,MAAM,MAAM;AAAA,MAC1B,SAAS,YAAa,MAAM,gBAA2B;AAAA,MACvD,aAAa,YAAY,QAAQ;AAAA,MACjC,eAAe,YAAa,MAAM,gBAA2B;AAAA,MAC7D,MAAM,MAAM;AAAA,MACZ,WAAW,MAAM,aAAa,KAAK,IAAI;AAAA,IACzC;AACA,SAAK,QAAQ,KAAK,KAAK;AACvB,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,cAAc,QAAQ,GAAS;AAC7B,QAAI,CAAC,OAAO,UAAU,KAAK,KAAK,QAAQ,GAAG;AACzC,YAAM,IAAI;AAAA,QACR,uEAAuE,KAAK;AAAA,MAC9E;AAAA,IACF;AACA,SAAK,kBAAkB;AAAA,EACzB;AAAA,EAEA,OAA0B;AACxB,WAAO,CAAC,GAAG,KAAK,OAAO;AAAA,EACzB;AAAA,EAEA,UAA6B;AAC3B,UAAM,YAAY,oBAAI,IAA2B;AACjD,UAAM,WAAW,oBAAI,IAAY;AACjC,QAAI,YAAY;AAChB,QAAI,cAAc;AAClB,QAAI,eAAe;AACnB,QAAI,eAAe;AACnB,eAAW,KAAK,KAAK,SAAS;AAC5B,mBAAa,EAAE;AACf,qBAAe,EAAE;AACjB,sBAAgB,EAAE;AAClB,sBAAgB,EAAE,gBAAgB;AAClC,UAAI,EAAE,YAAa,UAAS,IAAI,EAAE,KAAK;AACvC,YAAM,OAAO,UAAU,IAAI,EAAE,OAAO,KAAK;AAAA,QACvC,SAAS,EAAE;AAAA,QACX,OAAO;AAAA,QACP,aAAa;AAAA,QACb,cAAc;AAAA,QACd,cAAc;AAAA,QACd,SAAS;AAAA,QACT,eAAe;AAAA,MACjB;AACA,WAAK,SAAS;AACd,WAAK,eAAe,EAAE;AACtB,WAAK,gBAAgB,EAAE;AACvB,WAAK,gBAAgB,EAAE,gBAAgB;AACvC,WAAK,WAAW,EAAE;AAClB,UAAI,EAAE,YAAa,MAAK,iBAAiB;AACzC,gBAAU,IAAI,EAAE,SAAS,IAAI;AAAA,IAC/B;AACA,WAAO;AAAA,MACL,YAAY,KAAK,QAAQ;AAAA,MACzB;AAAA,MACA;AAAA,MACA;AAAA,MACA,cAAc;AAAA,MACd,WAAW,CAAC,GAAG,UAAU,OAAO,CAAC,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,QAAQ,cAAc,EAAE,OAAO,CAAC;AAAA,MACpF,gBAAgB,CAAC,GAAG,QAAQ,EAAE,KAAK;AAAA,MACnC,aAAa,SAAS,SAAS;AAAA,IACjC;AAAA,EACF;AAAA;AAAA,EAGA,uBAAsC;AACpC,QAAI,KAAK,mBAAmB,EAAG,QAAO;AACtC,WAAO,KAAK,QAAQ,EAAE,eAAe,KAAK;AAAA,EAC5C;AACF;AAEA,SAAS,kBAAkB,GAAW,MAAoB;AACxD,MAAI,CAAC,OAAO,SAAS,CAAC,KAAK,IAAI,GAAG;AAChC,UAAM,IAAI,gBAAgB,eAAe,IAAI,8CAA8C,CAAC,EAAE;AAAA,EAChG;AACF;;;AC7KO,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,IAAAC,mBAAkB,KAAK,aAAa,aAAa;AACjD,IAAAA,mBAAkB,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,SAASA,mBAAkB,GAAW,MAAoB;AACxD,MAAI,CAAC,OAAO,SAAS,CAAC,KAAK,IAAI,GAAG;AAChC,UAAM,IAAI,MAAM,gBAAgB,IAAI,8CAA8C,CAAC,EAAE;AAAA,EACvF;AACF;;;ACzIO,SAAS,SAAS,QAA2B;AAClD,QAAM,EAAE,cAAc,YAAY,IAAI,OAAO;AAC7C,MAAI,OAAO,iBAAiB,SAAU,QAAO;AAC7C,MAAI,OAAO,gBAAgB,SAAU,QAAO;AAC5C,QAAM,IAAI;AAAA,IACR,uBAAuB,OAAO,KAAK;AAAA,EACrC;AACF;AAkBA,SAAS,QAAQ,QAAmB,GAA6B;AAC/D,MAAI,EAAE,gBAAgB,OAAO,iBAAiB,EAAE,aAAc,QAAO;AACrE,MAAI,EAAE,eAAe,OAAO,gBAAgB,EAAE,YAAa,QAAO;AAClE,MAAI,EAAE,cAAc,OAAO,eAAe,EAAE,WAAY,QAAO;AAC/D,MAAI,EAAE,SAAS,OAAO,UAAU,EAAE,MAAO,QAAO;AAChD,MAAI,EAAE,YAAY,OAAO,aAAa,EAAE,SAAU,QAAO;AACzD,MAAI,EAAE,aAAa,UAAa,SAAS,MAAM,IAAI,EAAE,SAAU,QAAO;AACtE,MAAI,EAAE,aAAa,UAAa,SAAS,MAAM,IAAI,EAAE,SAAU,QAAO;AACtE,MAAI,EAAE,aAAa,OAAO,QAAQ,IAAI,EAAE,UAAU,GAAG,MAAM,EAAE,UAAU,MAAO,QAAO;AACrF,MAAI,EAAE,SAAS,CAAC,EAAE,MAAM,MAAM,EAAG,QAAO;AACxC,SAAO;AACT;AA6BO,SAAS,yBAAyB,UAAuB,CAAC,GAAqB;AACpF,QAAM,OAAO,QAAQ,IAAI,CAAC,MAAM,kBAAkB,CAAC,CAAC;AACpD,SAAO;AAAA,IACL,MAAM,OAAO,QAAQ;AACnB,WAAK,KAAK,MAAM;AAAA,IAClB;AAAA,IACA,MAAM,OAAO;AACX,aAAO,CAAC,GAAG,IAAI;AAAA,IACjB;AAAA,EACF;AACF;AAOO,SAAS,sBACd,MACA,OAAkC,CAAC,GACjB;AAClB,SAAO;AAAA,IACL,MAAM,OAAO,QAAQ;AACnB,YAAMC,MAAK,MAAM,OAAO,aAAkB;AAC1C,YAAM,UAAU,MAAM,OAAO,MAAW;AACxC,YAAMA,IAAG,MAAM,QAAQ,QAAQ,IAAI,GAAG,EAAE,WAAW,KAAK,CAAC;AACzD,YAAMA,IAAG,WAAW,MAAM,GAAG,KAAK,UAAU,MAAM,CAAC;AAAA,GAAM,MAAM;AAAA,IACjE;AAAA,IACA,MAAM,OAAO;AACX,YAAMA,MAAK,MAAM,OAAO,aAAkB;AAC1C,UAAI;AACJ,UAAI;AACF,cAAM,MAAMA,IAAG,SAAS,MAAM,MAAM;AAAA,MACtC,SAAS,KAAK;AACZ,YAAK,IAA8B,SAAS,SAAU,QAAO,CAAC;AAC9D,cAAM;AAAA,MACR;AACA,YAAM,MAAmB,CAAC;AAC1B,UAAI,SAAS;AACb,iBAAW,QAAQ,IAAI,MAAM,IAAI,GAAG;AAClC;AACA,YAAI,CAAC,KAAK,KAAK,EAAG;AAClB,YAAI;AACJ,YAAI;AACF,mBAAS,KAAK,MAAM,IAAI;AAAA,QAC1B,SAAS,KAAK;AACZ,cAAI,KAAK,YAAa;AACtB,gBAAM,IAAI,gBAAgB,mBAAmB,IAAI,IAAI,MAAM,oBAAoB;AAAA,QACjF;AACA,YAAI,KAAK,aAAa;AACpB,cAAI,YAAY,MAAM,EAAG,KAAI,KAAK,MAAM;AACxC;AAAA,QACF;AACA,YAAI;AACF,cAAI,KAAK,kBAAkB,MAAM,CAAC;AAAA,QACpC,SAAS,KAAK;AACZ,gBAAM,IAAI;AAAA,YACR,mBAAmB,IAAI,IAAI,MAAM,oCAAgC,IAAc,OAAO;AAAA,UACxF;AAAA,QACF;AAAA,MACF;AACA,aAAO;AAAA,IACT;AAAA,EACF;AACF;AASO,IAAM,iBAAN,MAAqB;AAAA,EACT;AAAA,EAEjB,YAAY,UAA4B,yBAAyB,GAAG;AAClE,SAAK,UAAU;AAAA,EACjB;AAAA;AAAA;AAAA,EAIA,MAAM,OAAO,QAAkC;AAC7C,UAAM,KAAK,QAAQ,OAAO,kBAAkB,MAAM,CAAC;AAAA,EACrD;AAAA,EAEA,MAAM,MAA4B;AAChC,WAAO,KAAK,QAAQ,KAAK;AAAA,EAC3B;AAAA,EAEA,MAAM,MAAM,SAA0B,CAAC,GAAyB;AAC9D,UAAM,OAAO,MAAM,KAAK,QAAQ,KAAK;AACrC,WAAO,KAAK,OAAO,CAAC,MAAM,QAAQ,GAAG,MAAM,CAAC;AAAA,EAC9C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,QACJ,YACA,OAAyD,CAAC,GAC/B;AAC3B,UAAM,OAAO,MAAM,KAAK,MAAM;AAAA,MAC5B;AAAA,MACA,aAAa,KAAK;AAAA,MAClB,UAAU,KAAK;AAAA,IACjB,CAAC;AACD,QAAI,KAAK,WAAW,EAAG,QAAO;AAC9B,QAAI,OAAO,KAAK,CAAC;AACjB,QAAI,YAAY,SAAS,IAAI;AAC7B,aAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,YAAM,IAAI,SAAS,KAAK,CAAC,CAAE;AAC3B,UAAI,IAAI,WAAW;AACjB,eAAO,KAAK,CAAC;AACb,oBAAY;AAAA,MACd;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,YAAY,YAAoB,YAAkD;AACtF,QAAI,eAAe,YAAY;AAC7B,YAAM,IAAI;AAAA,QACR,wDAAwD,UAAU;AAAA,MACpE;AAAA,IACF;AACA,UAAM,OAAO,MAAM,KAAK,QAAQ,KAAK;AACrC,UAAM,iBAAiB,CAAC,cAA2C;AACjE,YAAM,IAAI,oBAAI,IAAoB;AAClC,iBAAW,KAAK,MAAM;AACpB,YAAI,EAAE,gBAAgB,UAAW;AACjC,cAAM,MAAM,EAAE;AACd,YAAI,CAAC,IAAK;AACV,cAAM,IAAI,SAAS,CAAC;AACpB,cAAM,OAAO,EAAE,IAAI,GAAG;AACtB,YAAI,SAAS,UAAa,IAAI,KAAM,GAAE,IAAI,KAAK,CAAC;AAAA,MAClD;AACA,aAAO;AAAA,IACT;AACA,UAAM,UAAU,eAAe,UAAU;AACzC,UAAM,UAAU,eAAe,UAAU;AACzC,UAAM,SAAS,CAAC,GAAG,QAAQ,KAAK,CAAC,EAAE,OAAO,CAAC,QAAQ,QAAQ,IAAI,GAAG,CAAC,EAAE,KAAK;AAC1E,QAAI,OAAO,WAAW,GAAG;AACvB,YAAM,IAAI;AAAA,QACR,gCAAgC,UAAU,UAAU,UAAU;AAAA,MAChE;AAAA,IACF;AACA,QAAI,OAAO;AACX,QAAI,OAAO;AACX,QAAI,QAAQ;AACZ,QAAI,QAAQ;AACZ,QAAI,OAAO;AACX,eAAW,OAAO,QAAQ;AACxB,YAAM,KAAK,QAAQ,IAAI,GAAG;AAC1B,YAAM,KAAK,QAAQ,IAAI,GAAG;AAC1B,cAAQ;AACR,cAAQ;AACR,UAAI,KAAK,GAAI;AAAA,eACJ,KAAK,GAAI;AAAA,UACb;AAAA,IACP;AACA,UAAM,QAAQ,OAAO,OAAO;AAC5B,UAAM,QAAQ,OAAO,OAAO;AAC5B,WAAO;AAAA,MACL,GAAG;AAAA,MACH,GAAG;AAAA,MACH,mBAAmB;AAAA,MACnB;AAAA,MACA;AAAA,MACA,WAAW,QAAQ;AAAA,MACnB;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;;;ACxPA,SAAS,gBAAgB;AA2FzB,IAAM,WAA4C;AAAA,EAChD,eAAe;AAAA,EACf,qBAAqB;AAAA,EACrB,kBAAkB;AAAA,EAClB,qBAAqB,OAAO;AAAA,EAC5B,mBAAmB;AACrB;AAEA,SAAS,kBAAkB,GAAuE;AAChG,QAAM,IAAI,EAAE,GAAG,UAAU,GAAI,KAAK,CAAC,EAAG;AACtC,MAAI,EAAE,gBAAgB,GAAG;AACvB,UAAM,IAAI;AAAA,MACR,uDAAuD,EAAE,aAAa;AAAA,IACxE;AAAA,EACF;AACA,MAAI,EAAE,sBAAsB,GAAG;AAC7B,UAAM,IAAI;AAAA,MACR,6DAA6D,EAAE,mBAAmB;AAAA,IACpF;AAAA,EACF;AACA,MAAI,EAAE,oBAAoB,GAAG;AAC3B,UAAM,IAAI;AAAA,MACR,2DAA2D,EAAE,iBAAiB;AAAA,IAChF;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,OAAO,QAA0B;AACxC,QAAM,IAAI,OAAO;AACjB,MAAI,MAAM,EAAG,QAAO;AACpB,QAAM,MAAM,KAAK,MAAM,IAAI,CAAC;AAC5B,SAAO,IAAI,MAAM,KAAK,OAAO,MAAM,CAAC,IAAK,OAAO,GAAG,KAAM,IAAI,OAAO,GAAG;AACzE;AAGA,SAAS,OAAO,QAAkBC,OAAsB;AACtD,MAAI,OAAO,SAAS,EAAG,QAAO;AAC9B,QAAM,WAAW,OAAO,OAAO,CAAC,KAAK,MAAM,OAAO,IAAIA,UAAS,GAAG,CAAC,IAAI,OAAO;AAC9E,SAAO,KAAK,KAAK,QAAQ;AAC3B;AAOO,SAAS,uBACd,MACA,YACiB;AACjB,QAAM,IAAI,kBAAkB,UAAU;AACtC,QAAM,IAAI,KAAK;AACf,MAAI,MAAM,GAAG;AACX,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,GAAG;AAAA,MACH,QAAQ;AAAA,IACV;AAAA,EACF;AACA,QAAMC,UAAS,KAAK,IAAI,CAAC,MAAM;AAC7B,QAAI,CAAC,OAAO,SAAS,EAAE,KAAK,GAAG;AAC7B,YAAM,IAAI,gBAAgB,2BAA2B,EAAE,GAAG,yBAAyB,EAAE,KAAK,EAAE;AAAA,IAC9F;AACA,WAAO,EAAE;AAAA,EACX,CAAC;AACD,QAAM,SAAS,CAAC,GAAGA,OAAM,EAAE,KAAK,CAAC,GAAG,MAAM,IAAI,CAAC;AAC/C,QAAMD,QAAOC,QAAO,OAAO,CAAC,GAAG,MAAM,IAAI,GAAG,CAAC,IAAI;AACjD,QAAM,KAAK,OAAOA,SAAQD,KAAI;AAC9B,QAAM,SAAS,IAAIC,OAAM;AACzB,QAAM,QAAQ,KAAK,OAAO,CAAC,MAAM,OAAO,EAAE,WAAW,SAAS;AAC9D,QAAM,WAAW,MAAM,WAAW,IAAI,OAAO,MAAM,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,MAAM;AAC1F,QAAM,SAAS,SAAS,EAAE,oBAAoB,KAAK,EAAE;AACrD,SAAO;AAAA,IACL,QAAQ,OAAO,MAAM;AAAA,IACrB,MAAAD;AAAA,IACA,KAAK,OAAO,CAAC;AAAA,IACb,KAAK,OAAO,IAAI,CAAC;AAAA,IACjB,KAAK;AAAA,IACL,QAAQ;AAAA,IACR;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAQO,SAAS,mBACd,WACA,QACA,YAC0B;AAC1B,QAAM,IAAI,kBAAkB,UAAU;AACtC,MAAI,CAAC,QAAQ;AACX,WAAO;AAAA,MACL,SAAS;AAAA,MACT,aAAa;AAAA,MACb,QAAQ;AAAA,IACV;AAAA,EACF;AACA,MAAI,UAAU,IAAI,EAAE,qBAAqB,OAAO,IAAI,EAAE,mBAAmB;AACvE,WAAO;AAAA,MACL,SAAS;AAAA,MACT,aAAa;AAAA,MACb,QAAQ,WAAW,EAAE,iBAAiB,oCAAoC,UAAU,CAAC,cAAc,OAAO,CAAC;AAAA,IAC7G;AAAA,EACF;AACA,MAAI,CAAC,UAAU,QAAQ;AACrB,WAAO;AAAA,MACL,SAAS;AAAA,MACT,aAAa,UAAU,SAAS,OAAO;AAAA,MACvC,QAAQ,2BAA2B,UAAU,GAAG,YAAY,UAAU,OAAO,QAAQ,CAAC,CAAC;AAAA,IACzF;AAAA,EACF;AACA,QAAME,eAAc,UAAU,SAAS,OAAO;AAC9C,MAAIA,eAAc,EAAE,eAAe;AACjC,WAAO,EAAE,SAAS,QAAQ,aAAAA,cAAa,QAAQ,WAAWA,YAAW,OAAO,EAAE,aAAa,GAAG;AAAA,EAChG;AACA,MAAIA,eAAc,CAAC,EAAE,qBAAqB;AACxC,WAAO;AAAA,MACL,SAAS;AAAA,MACT,aAAAA;AAAA,MACA,QAAQ,UAAUA,YAAW,OAAO,EAAE,mBAAmB;AAAA,IAC3D;AAAA,EACF;AACA,SAAO;AAAA,IACL,SAAS;AAAA,IACT,aAAAA;AAAA,IACA,QAAQ,gBAAgBA,YAAW,wBAAwB,EAAE,mBAAmB,MAAM,EAAE,aAAa;AAAA,EACvG;AACF;AAqBO,IAAM,sBAAwC,MAAM;AACzD,QAAM,MAAM,CAAC,QAAwB,SAAS,KAAK,EAAE,UAAU,OAAO,CAAC,EAAE,KAAK;AAC9E,QAAM,SAAS,IAAI,4BAA4B;AAC/C,QAAM,UAAU,IAAI,wBAAwB;AAC5C,QAAM,aAAa,IAAI,6BAA6B;AACpD,QAAM,eAAe,WAAW,WAAW,IAAI,CAAC,IAAI,WAAW,MAAM,IAAI,EAAE,OAAO,OAAO;AACzF,SAAO,EAAE,QAAQ,SAAS,aAAa;AACzC;AAIO,SAAS,wBAAwB,UAAwB,CAAC,GAAoB;AACnF,MAAI,QAAQ,QAAQ,IAAI,CAAC,MAAM,gBAAgB,CAAC,CAAC;AACjD,SAAO;AAAA,IACL,MAAM,OAAO;AACX,aAAO,MAAM,IAAI,CAAC,MAAM,gBAAgB,CAAC,CAAC;AAAA,IAC5C;AAAA,IACA,MAAM,KAAK,aAAa;AACtB,cAAQ,YAAY,IAAI,CAAC,MAAM,gBAAgB,CAAC,CAAC;AAAA,IACnD;AAAA,EACF;AACF;AAGO,SAAS,oBAAoB,MAA+B;AACjE,SAAO;AAAA,IACL,MAAM,OAAO;AACX,YAAMC,MAAK,MAAM,OAAO,aAAkB;AAC1C,UAAI;AACF,cAAM,MAAM,MAAMA,IAAG,SAAS,MAAM,MAAM;AAC1C,cAAM,SAAS,KAAK,MAAM,GAAG;AAC7B,YAAI,CAAC,MAAM,QAAQ,MAAM,GAAG;AAC1B,gBAAM,IAAI,gBAAgB,gCAAgC,IAAI,sBAAsB;AAAA,QACtF;AACA,eAAO;AAAA,MACT,SAAS,KAAK;AACZ,YAAK,IAA8B,SAAS,SAAU,QAAO,CAAC;AAC9D,cAAM;AAAA,MACR;AAAA,IACF;AAAA,IACA,MAAM,KAAK,aAAa;AACtB,YAAMA,MAAK,MAAM,OAAO,aAAkB;AAC1C,YAAM,UAAU,MAAM,OAAO,MAAW;AACxC,YAAMA,IAAG,MAAM,QAAQ,QAAQ,IAAI,GAAG,EAAE,WAAW,KAAK,CAAC;AACzD,YAAMA,IAAG,UAAU,MAAM,KAAK,UAAU,aAAa,MAAM,CAAC,GAAG,MAAM;AAAA,IACvE;AAAA,EACF;AACF;AA0BO,IAAM,oBAAN,MAAwB;AAAA,EACZ;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEjB,YAAY,UAAoC,CAAC,GAAG;AAClD,SAAK,QAAQ,QAAQ,SAAS,wBAAwB;AACtD,SAAK,mBAAmB,QAAQ,oBAAoB;AACpD,SAAK,aAAa,kBAAkB,QAAQ,UAAU;AACtD,SAAK,MAAM,QAAQ,OAAO,KAAK;AAAA,EACjC;AAAA,EAEA,MAAM,OAAO,OAAmD;AAC9D,UAAM,cAAc,MAAM,KAAK,MAAM,KAAK;AAC1C,QAAI,YAAY,KAAK,CAAC,MAAM,EAAE,OAAO,MAAM,EAAE,GAAG;AAC9C,YAAM,IAAI,gBAAgB,sCAAsC,MAAM,EAAE,kBAAkB;AAAA,IAC5F;AACA,QAAI,MAAM,YAAY,CAAC,YAAY,KAAK,CAAC,MAAM,EAAE,OAAO,MAAM,QAAQ,GAAG;AACvE,YAAM,IAAI;AAAA,QACR,0CAA0C,MAAM,QAAQ;AAAA,MAC1D;AAAA,IACF;AACA,UAAM,aAAa,MAAM,cAAe,MAAM,KAAK,iBAAiB;AACpE,UAAM,aAAyB;AAAA,MAC7B,IAAI,MAAM;AAAA,MACV,OAAO,MAAM;AAAA,MACb;AAAA,MACA,UAAU,MAAM;AAAA,MAChB,eAAe,MAAM;AAAA,MACrB,MAAM,CAAC;AAAA,MACP,OAAO,uBAAuB,CAAC,GAAG,KAAK,UAAU;AAAA,MACjD,SAAS;AAAA,MACT,WAAW,IAAI,KAAK,KAAK,IAAI,CAAC,EAAE,YAAY;AAAA,IAC9C;AACA,gBAAY,KAAK,UAAU;AAC3B,UAAM,KAAK,MAAM,KAAK,WAAW;AACjC,WAAO,gBAAgB,UAAU;AAAA,EACnC;AAAA;AAAA;AAAA,EAIA,MAAM,OACJ,cACA,KACqB;AACrB,UAAM,cAAc,MAAM,KAAK,MAAM,KAAK;AAC1C,UAAM,MAAM,YAAY,KAAK,CAAC,MAAM,EAAE,OAAO,YAAY;AACzD,QAAI,CAAC;AACH,YAAM,IAAI,gBAAgB,mCAAmC,YAAY,aAAa;AACxF,UAAM,UAAyB;AAAA,MAC7B,KAAK,IAAI,OAAO,IAAI,KAAK;AAAA,MACzB,OAAO,IAAI;AAAA,MACX,QAAQ,IAAI;AAAA,MACZ,SAAS,IAAI;AAAA,MACb,WAAW,IAAI,aAAa,IAAI,KAAK,KAAK,IAAI,CAAC,EAAE,YAAY;AAAA,IAC/D;AACA,QAAI,KAAK,KAAK,OAAO;AACrB,QAAI,QAAQ,uBAAuB,IAAI,MAAM,KAAK,UAAU;AAC5D,UAAM,SAAS,IAAI,WAAW,YAAY,KAAK,CAAC,MAAM,EAAE,OAAO,IAAI,QAAQ,IAAI;AAC/E,QAAI,UAAU,mBAAmB,IAAI,OAAO,QAAQ,SAAS,MAAM,KAAK,UAAU,EAAE;AACpF,UAAM,KAAK,MAAM,KAAK,WAAW;AACjC,WAAO,gBAAgB,GAAG;AAAA,EAC5B;AAAA,EAEA,MAAM,IAAI,cAAuD;AAC/D,UAAM,cAAc,MAAM,KAAK,MAAM,KAAK;AAC1C,UAAM,QAAQ,YAAY,KAAK,CAAC,MAAM,EAAE,OAAO,YAAY;AAC3D,WAAO,QAAQ,gBAAgB,KAAK,IAAI;AAAA,EAC1C;AAAA,EAEA,MAAM,OAA8B;AAClC,WAAO,KAAK,MAAM,KAAK;AAAA,EACzB;AAAA;AAAA,EAGA,MAAM,WAAW,cAAyD;AACxE,UAAM,cAAc,MAAM,KAAK,MAAM,KAAK;AAC1C,UAAM,MAAM,YAAY,KAAK,CAAC,MAAM,EAAE,OAAO,YAAY;AACzD,QAAI,CAAC;AACH,YAAM,IAAI,gBAAgB,mCAAmC,YAAY,aAAa;AACxF,UAAM,SAAS,IAAI,WAAW,YAAY,KAAK,CAAC,MAAM,EAAE,OAAO,IAAI,QAAQ,IAAI;AAC/E,WAAO,mBAAmB,IAAI,OAAO,QAAQ,SAAS,MAAM,KAAK,UAAU;AAAA,EAC7E;AACF;;;ACxYA,SAASC,MAAK,IAA6B;AACzC,SAAO,GAAG,SAAS,GAAG,OAAO,CAAC,GAAG,MAAM,IAAI,GAAG,CAAC,IAAI,GAAG,SAAS;AACjE;AAOO,SAAS,YAAY,SAAsB,MAA4C;AAC5F,QAAM,QAAQ,KAAK,YAAY,CAAC,MAAiB,EAAE,cAAc,UAAU;AAC3E,QAAM,SAAS,oBAAI,IAAyB;AAC5C,aAAW,KAAK,SAAS;AACvB,UAAM,IAAI,MAAM,CAAC;AACjB,UAAM,IAAI,OAAO,IAAI,CAAC;AACtB,QAAI,EAAG,GAAE,KAAK,CAAC;AAAA,QACV,QAAO,IAAI,GAAG,CAAC,CAAC,CAAC;AAAA,EACxB;AAEA,QAAM,OAAyB,CAAC,GAAG,OAAO,QAAQ,CAAC,EAAE,IAAI,CAAC,CAAC,KAAK,EAAE,MAAM;AACtE,UAAM,SAAS,GAAG,OAAO,CAAC,MAAM,KAAK,OAAO,CAAC,CAAC,EAAE;AAChD,UAAM,KAAK,OAAO,QAAQ,GAAG,MAAM;AACnC,UAAM,UAAU,GAAG,CAAC,EAAG;AACvB,UAAM,UAAU,SAAS,SAAS;AAClC,UAAM,QAAQ,SAAS;AACvB,WAAO;AAAA,MACL;AAAA,MACA,OAAO,WAAW,QAAQ,GAAG,OAAO,SAAM,KAAK,KAAK;AAAA,MACpD,GAAI,UAAU,EAAE,QAAQ,IAAI,CAAC;AAAA,MAC7B,GAAI,QAAQ,EAAE,MAAM,IAAI,CAAC;AAAA,MACzB,MAAM;AAAA,MACN,GAAG,GAAG;AAAA,MACN,UAAU,GAAG;AAAA,MACb,cAAc,CAAC,GAAG,OAAO,GAAG,KAAK;AAAA,MACjC,aAAaA,MAAK,GAAG,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC;AAAA,MAC1C,cAAcA,MAAK,GAAG,IAAI,CAAC,MAAM,EAAE,WAAW,KAAK,CAAC;AAAA,MACpD,eAAeA,MAAK,GAAG,IAAI,CAAC,MAAM,EAAE,WAAW,MAAM,CAAC;AAAA,MACtD,YAAYA,MAAK,GAAG,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC;AAAA,IAC1C;AAAA,EACF,CAAC;AAED,OAAK;AAAA,IACH,CAAC,GAAG,MAAM,EAAE,WAAW,EAAE,aAAa,EAAE,eAAe,aAAa,EAAE,eAAe;AAAA,EACvF;AACA,OAAK,QAAQ,CAAC,KAAK,MAAM;AACvB,QAAI,OAAO,IAAI;AAAA,EACjB,CAAC;AACD,SAAO;AACT;;;AC7DA,SAAS,YAAY,aAAa,cAAc,gBAAgB;AAChE,SAAS,YAAY;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,QAAMC,WAAoB,CAAC;AAC3B,QAAM,OAAO,CAAC,QAAgB;AAC5B,UAAM,MAAM,KAAK,UAAU,GAAG;AAC9B,QAAI,CAAC,WAAW,GAAG,EAAG;AACtB,eAAW,SAAS,YAAY,GAAG,GAAG;AACpC,YAAM,MAAM,KAAK,KAAK,KAAK;AAC3B,YAAM,SAAS,KAAK,UAAU,GAAG;AACjC,UAAI;AACJ,UAAI;AACF,aAAK,SAAS,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,iBAAO,aAAa,QAAQ,MAAM;AAAA,QACpC,QAAQ;AACN;AAAA,QACF;AACA,YAAI,KAAK,SAAS,cAAc,EAAG,CAAAA,SAAQ,KAAK,GAAG;AAAA,MACrD;AAAA,IACF;AAAA,EACF;AACA,aAAW,KAAK,MAAO,MAAK,CAAC;AAC7B,SAAOA;AACT;AAMO,SAAS,oBAAoB,MAAqC;AACvE,QAAM,WAA6B,CAAC;AACpC,QAAM,UAAU,oBAAI,IAAY;AAGhC,aAAW,QAAQ,KAAK,WAAW;AACjC,UAAM,MAAM,KAAK,KAAK,UAAU,IAAI;AACpC,QAAI,CAAC,WAAW,GAAG,EAAG;AACtB,UAAM,OAAO,aAAa,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,MAAM,KAAK,KAAK,UAAU,IAAI;AACpC,UAAI,CAAC,WAAW,GAAG,EAAG;AACtB,YAAM,OAAO,aAAa,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;;;ACvKO,SAAS,QAAQ,OAAuB;AAC7C,MAAI,IAAI;AACR,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,SAAK,MAAM,WAAW,CAAC,IAAI;AAC3B,QAAI,KAAK,KAAK,GAAG,QAAU;AAAA,EAC7B;AACA,SAAO,MAAM;AACf;AAGO,SAAS,WAAW,IAAY,MAAsB;AAE3D,SAAO,QAAQ,GAAG,EAAE;AAAA,EAAK,IAAI,EAAE,IAAI;AACrC;AAoCO,SAAS,iBACd,IACA,UAAuD,CAAC,GAClC;AACtB,QAAM,OAAO,QAAQ,QAAQ;AAC7B,QAAM,kBAAkB,QAAQ,mBAAmB;AACnD,iBAAe,eAAe;AAC9B,SAAO,WAAW,IAAI,IAAI,IAAI,kBAAkB,YAAY;AAC9D;AAYO,SAAS,iBACd,KACA,UAAmC,CAAC,GAClB;AAClB,QAAM,OAAO,QAAQ,QAAQ;AAC7B,QAAM,kBAAkB,QAAQ,mBAAmB;AACnD,QAAM,aAAa,QAAQ,cAAc;AACzC,QAAM,YAAY,QAAQ,aAAa;AACvC,iBAAe,eAAe;AAC9B,MAAI,IAAI,WAAW,GAAG;AACpB,UAAM,IAAI,gBAAgB,mCAAmC;AAAA,EAC/D;AAEA,QAAM,OAAO,oBAAI,IAAY;AAC7B,QAAM,SAAmB,CAAC;AAC1B,QAAM,UAAoB,CAAC;AAC3B,aAAW,MAAM,KAAK;AACpB,QAAI,OAAO,OAAO,YAAY,GAAG,WAAW,GAAG;AAC7C,YAAM,IAAI;AAAA,QACR,wDAAwD,KAAK,UAAU,EAAE,CAAC;AAAA,MAC5E;AAAA,IACF;AACA,QAAI,KAAK,IAAI,EAAE,GAAG;AAChB,YAAM,IAAI;AAAA,QACR,mCAAmC,EAAE;AAAA,MACvC;AAAA,IACF;AACA,SAAK,IAAI,EAAE;AACX,QAAI,WAAW,IAAI,IAAI,IAAI,gBAAiB,SAAQ,KAAK,EAAE;AAAA,QACtD,QAAO,KAAK,EAAE;AAAA,EACrB;AAEA,MAAI,QAAQ,SAAS,YAAY;AAC/B,UAAM,IAAI;AAAA,MACR,qCAAqC,QAAQ,MAAM,8BAA8B,UAAU,OACnF,IAAI,MAAM,qBAAqB,eAAe;AAAA,IACxD;AAAA,EACF;AACA,MAAI,OAAO,SAAS,WAAW;AAC7B,UAAM,IAAI;AAAA,MACR,oCAAoC,OAAO,MAAM,8BAA8B,SAAS,OAChF,IAAI,MAAM,qBAAqB,eAAe;AAAA,IACxD;AAAA,EACF;AAEA,SAAO,EAAE,QAAQ,SAAS,MAAM,gBAAgB;AAClD;AAEA,SAAS,eAAe,GAAiB;AACvC,MAAI,CAAC,OAAO,SAAS,CAAC,KAAK,KAAK,KAAK,KAAK,GAAG;AAC3C,UAAM,IAAI,gBAAgB,4DAA4D,CAAC,EAAE;AAAA,EAC3F;AACF;;;AC9HA,SAAS,gBAAgB,cAAAC,aAAY,WAAW,gBAAAC,qBAAoB;AACpE,SAAS,eAAe;AA2DxB,SAASC,QAAO,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,SAASC,UAAS,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,QAAQ,oBAAoB,KAAK,OAAO;AAC9C,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,OAAOA,UAAS,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,WAAWF,QAAOE,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;AAAA,MACA,SAAS,KAAK;AAAA,MACd;AAAA,IACF,CAAC;AAAA,EACH;AACA,SAAO;AACT;AAKO,SAAS,gBAAgB,SAAiB,OAAiC;AAChF,MAAI,MAAM,WAAW,EAAG;AACxB,YAAU,QAAQ,OAAO,GAAG,EAAE,WAAW,KAAK,CAAC;AAC/C,iBAAe,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;;;ACxUO,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,YAAME,MAAK,YAAY,QAAQ,OAAO,MAAM,GAAG,CAAC,CAAC;AACjD,UAAI,OAAO,MAAMA,QAAO,GAAI,QAAO;AACnC,aAAOA,OAAM,KAAK,IAAI;AAAA,IACxB;AAAA,EACF;AACF;;;AC3DO,IAAM,YAA+B;AAAA,EAC1C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAaO,IAAM,wBAAsD;AAAA,EACjE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;;;ACsEA,SAAS,kBAAkB,GAAkC;AAC3D,SACE,OAAO,MAAM,YACb,MAAM,QACN,OAAQ,EAAsB,WAAW,YACzC,OAAQ,EAAsB,UAAU;AAE5C;AAEA,SAAS,UAAU,QAA4B,SAA+B;AAC5E,MAAI,OAAO,WAAW,SAAU,QAAO;AACvC,MAAI,OAAO,YAAY,SAAU,QAAO,WAAW;AACnD,MAAI,mBAAmB,OAAQ,QAAO,QAAQ,KAAK,MAAM;AACzD,SAAO,IAAI,OAAO,QAAQ,QAAQ,QAAQ,KAAK,EAAE,KAAK,MAAM;AAC9D;AAEA,SAAS,gBAAgB,MAAwC;AAC/D,MAAI,OAAO,KAAK,aAAa,SAAU,QAAO,KAAK;AACnD,QAAM,WAAW,KAAK,aAAa,WAAW,KAAK,KAAK,YAAY;AACpE,MAAI,OAAO,aAAa,SAAU,QAAO;AACzC,MAAI,KAAK,SAAS,UAAU,OAAO,KAAK,SAAS,SAAU,QAAO,KAAK;AACvE,SAAO;AACT;AAEA,SAAS,gBAAgB,OAAgB,OAA+C;AACtF,MAAI,UAAU,QAAQ,OAAO,UAAU,UAAU;AAC/C,UAAM,IAAI,gBAAgB,GAAG,KAAK,sCAAsC,OAAO,KAAK,EAAE;AAAA,EACxF;AACA,QAAM,IAAI;AACV,aAAW,SAAS,CAAC,QAAQ,MAAM,GAAY;AAC7C,UAAM,IAAI,EAAE,KAAK;AACjB,QACE,MAAM,UACN,OAAO,MAAM,YACb,EAAE,aAAa,WACf,CAAC,kBAAkB,CAAC,GACpB;AACA,YAAM,IAAI,gBAAgB,GAAG,KAAK,MAAM,KAAK,6CAA6C;AAAA,IAC5F;AAAA,EACF;AACA,MACE,EAAE,SAAS,WACV,EAAE,SAAS,QAAQ,OAAO,EAAE,SAAS,YAAY,MAAM,QAAQ,EAAE,IAAI,IACtE;AACA,UAAM,IAAI,gBAAgB,GAAG,KAAK,iCAAiC;AAAA,EACrE;AACA,MAAI,EAAE,kBAAkB,OAAO,EAAE,WAAW,YAAY;AACtD,UAAM,IAAI;AAAA,MACR,GAAG,KAAK;AAAA,IAEV;AAAA,EACF;AACA,QAAM,UAAU,EAAE,SAAS,UAAa,OAAO,KAAK,EAAE,IAAI,EAAE,SAAS;AACrE,MAAI,EAAE,SAAS,UAAa,EAAE,SAAS,UAAa,CAAC,WAAW,OAAO,EAAE,WAAW,YAAY;AAC9F,UAAM,IAAI;AAAA,MACR,GAAG,KAAK;AAAA,IACV;AAAA,EACF;AACF;AAGO,SAAS,UAAU,MAAoB,WAAmC;AAC/E,kBAAgB,WAAW,WAAW;AACtC,MAAI,UAAU,SAAS,UAAa,CAAC,UAAU,KAAK,MAAM,UAAU,IAAI,EAAG,QAAO;AAClF,MAAI,UAAU,SAAS,UAAa,CAAC,UAAU,gBAAgB,IAAI,GAAG,UAAU,IAAI;AAClF,WAAO;AACT,MAAI,UAAU,SAAS,QAAW;AAChC,eAAW,CAAC,KAAK,QAAQ,KAAK,OAAO,QAAQ,UAAU,IAAI,GAAG;AAC5D,YAAM,SAAS,KAAK,aAAa,GAAG;AACpC,UAAI,oBAAoB,UAAU,kBAAkB,QAAQ,GAAG;AAC7D,YAAI,CAAC,UAAU,OAAO,WAAW,WAAW,SAAS,QAAW,QAAuB,GAAG;AACxF,iBAAO;AAAA,QACT;AAAA,MACF,WAAW,WAAW,UAAU;AAC9B,eAAO;AAAA,MACT;AAAA,IACF;AAAA,EACF;AACA,MAAI,UAAU,WAAW,UAAa,CAAC,UAAU,OAAO,IAAI,EAAG,QAAO;AACtE,SAAO;AACT;AAIA,SAAS,gBAAgB,GAAwB;AAC/C,MAAI,OAAO,MAAM,SAAU,QAAO;AAClC,MAAI,aAAa,OAAQ,QAAO,IAAI,EAAE,MAAM,IAAI,EAAE,KAAK;AACvD,SAAO,IAAI,EAAE,MAAM,IAAI,EAAE,KAAK;AAChC;AAEA,SAAS,kBAAkB,GAA0B;AACnD,QAAM,QAAkB,CAAC;AACzB,MAAI,EAAE,SAAS,OAAW,OAAM,KAAK,QAAQ,gBAAgB,EAAE,IAAI,CAAC,EAAE;AACtE,MAAI,EAAE,SAAS,OAAW,OAAM,KAAK,QAAQ,gBAAgB,EAAE,IAAI,CAAC,EAAE;AACtE,MAAI,EAAE,SAAS,QAAW;AACxB,eAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,EAAE,IAAI,GAAG;AAC3C,YAAM;AAAA,QACJ,QAAQ,CAAC,IAAI,aAAa,UAAU,kBAAkB,CAAC,IAAI,gBAAgB,CAAgB,IAAI,KAAK,UAAU,CAAC,CAAC;AAAA,MAClH;AAAA,IACF;AAAA,EACF;AACA,MAAI,OAAO,EAAE,WAAW,WAAY,OAAM,KAAK,UAAU,EAAE,OAAO,QAAQ,IAAI,EAAE;AAChF,SAAO,MAAM,KAAK,GAAG;AACvB;AAEA,SAAS,iBAAiB,GAA0C;AAClE,SAAO,aAAa,SAAS,EAAE,QAAQ,EAAE,QAAQ,OAAO,EAAE,MAAM,IAAI;AACtE;AAEA,SAAS,mBAAmB,GAAkB,OAA8B;AAC1E,kBAAgB,GAAG,KAAK;AACxB,QAAM,MAAqB,CAAC;AAC5B,MAAI,EAAE,SAAS,OAAW,KAAI,OAAO,iBAAiB,EAAE,IAAI;AAC5D,MAAI,EAAE,SAAS,OAAW,KAAI,OAAO,iBAAiB,EAAE,IAAI;AAC5D,MAAI,EAAE,SAAS,QAAW;AACxB,QAAI,OAAO,OAAO;AAAA,MAChB,OAAO,QAAQ,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,aAAa,SAAS,iBAAiB,CAAC,IAAI,CAAC,CAAC;AAAA,IAC3F;AAAA,EACF;AACA,MAAI,OAAO,EAAE,WAAW,YAAY;AAClC,QAAI,SAAS,EAAE;AACf,QAAI,iBAAiB;AAAA,EACvB;AACA,SAAO;AACT;AAEO,IAAM,uBAAN,MAA2B;AAAA,EAGhC,YAA6B,MAAc;AAAd;AAAA,EAAe;AAAA,EAAf;AAAA,EAFZ,QAAwB,CAAC;AAAA;AAAA,EAK1C,OAAO,GAAkB,OAAsB;AAC7C,UAAM,KAAK,mBAAmB,GAAG,kBAAkB,KAAK,IAAI,WAAW;AACvE,WAAO,KAAK,IAAI,EAAE,MAAM,UAAU,OAAO,SAAS,UAAU,kBAAkB,EAAE,CAAC,KAAK,GAAG,GAAG,CAAC;AAAA,EAC/F;AAAA;AAAA,EAGA,MAAM,GAAkB,OAAsB;AAC5C,UAAM,KAAK,mBAAmB,GAAG,kBAAkB,KAAK,IAAI,UAAU;AACtE,WAAO,KAAK,IAAI,EAAE,MAAM,SAAS,OAAO,SAAS,SAAS,kBAAkB,EAAE,CAAC,KAAK,GAAG,GAAG,CAAC;AAAA,EAC7F;AAAA;AAAA,EAGA,WAAW,GAAkB,OAAsB;AACjD,UAAM,KAAK,mBAAmB,GAAG,kBAAkB,KAAK,IAAI,eAAe;AAC3E,WAAO,KAAK,IAAI;AAAA,MACd,MAAM;AAAA,MACN,OAAO,SAAS,cAAc,kBAAkB,EAAE,CAAC;AAAA,MACnD,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA;AAAA,EAGA,SAAS,GAAkB,GAAkB,OAAsB;AACjE,UAAM,KAAK,mBAAmB,GAAG,kBAAkB,KAAK,IAAI,iBAAiB;AAC7E,UAAM,KAAK,mBAAmB,GAAG,kBAAkB,KAAK,IAAI,iBAAiB;AAC7E,WAAO,KAAK,IAAI;AAAA,MACd,MAAM;AAAA,MACN,OAAO,SAAS,YAAY,kBAAkB,EAAE,CAAC,OAAO,kBAAkB,EAAE,CAAC;AAAA,MAC7E,GAAG;AAAA,MACH,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA;AAAA,EAGA,YAAY,GAAkB,OAAsB,OAAsB;AACxE,UAAM,KAAK,mBAAmB,GAAG,kBAAkB,KAAK,IAAI,oBAAoB;AAChF,UAAM,SAAS,mBAAmB,OAAO,kBAAkB,KAAK,IAAI,wBAAwB;AAC5F,WAAO,KAAK,IAAI;AAAA,MACd,MAAM;AAAA,MACN,OAAO,SAAS,eAAe,kBAAkB,EAAE,CAAC,WAAW,kBAAkB,MAAM,CAAC;AAAA,MACxF,GAAG;AAAA,MACH,OAAO;AAAA,IACT,CAAC;AAAA,EACH;AAAA,EAEA,QAAuB;AACrB,QAAI,KAAK,MAAM,WAAW,GAAG;AAC3B,YAAM,IAAI;AAAA,QACR,kBAAkB,KAAK,IAAI;AAAA,MAC7B;AAAA,IACF;AACA,WAAO,EAAE,MAAM,KAAK,MAAM,OAAO,CAAC,GAAG,KAAK,KAAK,EAAE;AAAA,EACnD;AAAA,EAEQ,IAAI,MAA0B;AAGpC,QAAI,QAAQ,KAAK;AACjB,QAAI,IAAI;AACR,WAAO,KAAK,MAAM,KAAK,CAAC,MAAM,EAAE,UAAU,KAAK,GAAG;AAChD,cAAQ,GAAG,KAAK,KAAK,KAAK,CAAC;AAC3B,WAAK;AAAA,IACP;AACA,SAAK,MAAM,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC;AAClC,WAAO;AAAA,EACT;AACF;AAEO,SAAS,cAAc,MAAoC;AAChE,MAAI,OAAO,SAAS,YAAY,KAAK,WAAW,GAAG;AACjD,UAAM,IAAI,gBAAgB,gDAAgD;AAAA,EAC5E;AACA,SAAO,IAAI,qBAAqB,IAAI;AACtC;AAIA,SAAS,eAAe,UAA+B;AACrD,MAAI,OAAO,UAAU,SAAS,YAAY,SAAS,KAAK,WAAW,GAAG;AACpE,UAAM,IAAI,gBAAgB,iEAAiE;AAAA,EAC7F;AACA,MAAI,CAAC,MAAM,QAAQ,SAAS,KAAK,KAAK,SAAS,MAAM,WAAW,GAAG;AACjE,UAAM,IAAI;AAAA,MACR,oCAAoC,SAAS,IAAI;AAAA,IACnD;AAAA,EACF;AACA,QAAM,OAAO,oBAAI,IAAY;AAC7B,aAAW,QAAQ,SAAS,OAAO;AACjC,UAAM,QAAQ,aAAa,SAAS,IAAI,WAAW,MAAM,SAAS,aAAa;AAC/E,QAAI,OAAO,MAAM,UAAU,YAAY,KAAK,MAAM,WAAW,GAAG;AAC9D,YAAM,IAAI,gBAAgB,GAAG,KAAK,oCAAoC;AAAA,IACxE;AACA,QAAI,KAAK,IAAI,KAAK,KAAK,GAAG;AACxB,YAAM,IAAI,gBAAgB,GAAG,KAAK,kDAAkD;AAAA,IACtF;AACA,SAAK,IAAI,KAAK,KAAK;AACnB,YAAQ,KAAK,MAAM;AAAA,MACjB,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AACH,wBAAgB,KAAK,GAAG,GAAG,KAAK,MAAM;AACtC;AAAA,MACF,KAAK;AACH,wBAAgB,KAAK,GAAG,GAAG,KAAK,MAAM;AACtC,wBAAgB,KAAK,GAAG,GAAG,KAAK,MAAM;AACtC;AAAA,MACF,KAAK;AACH,wBAAgB,KAAK,GAAG,GAAG,KAAK,MAAM;AACtC,wBAAgB,KAAK,OAAO,GAAG,KAAK,UAAU;AAC9C;AAAA,MACF;AACE,cAAM,IAAI;AAAA,UACR,GAAG,KAAK,wBAAwB,OAAQ,KAAsB,IAAI,CAAC;AAAA,QACrE;AAAA,IACJ;AAAA,EACF;AACF;AASA,SAAS,WAAW,OAAgD;AAClE,QAAM,QAAQ,MAAM;AAAA,IAClB,CAAC,MAAM,OAAO,EAAE,cAAc,YAAY,OAAO,SAAS,EAAE,SAAS;AAAA,EACvE,EAAE;AACF,MAAI,UAAU,MAAM,QAAQ;AAC1B,WAAO,MACJ,IAAI,CAAC,MAAM,OAAO,EAAE,MAAM,EAAE,EAAE,EAC9B,KAAK,CAAC,GAAG,MAAM,EAAE,KAAK,YAAa,EAAE,KAAK,aAAc,EAAE,IAAI,EAAE,CAAC,EACjE,IAAI,CAAC,MAAM,EAAE,IAAI;AAAA,EACtB;AACA,MAAI,UAAU,EAAG,QAAO,CAAC,GAAG,KAAK;AACjC,QAAM,IAAI;AAAA,IACR,0BAA0B,KAAK,IAAI,MAAM,MAAM;AAAA,EAEjD;AACF;AAEA,SAAS,QAAQ,MAAoB,OAAuB;AAC1D,SAAO,KAAK,UAAU,IAAI,KAAK;AACjC;AAMA,SAAS,aAAa,MAME;AACtB,QAAM,MAA2B,CAAC;AAClC,MAAI,YAAY;AAChB,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,QAAQ,KAAK;AAC5C,UAAM,OAAO,KAAK,QAAQ,CAAC;AAC3B,QAAI,CAAC,aAAa,UAAU,MAAM,KAAK,OAAO,GAAG;AAC/C,UAAI,KAAK,EAAE,MAAM,KAAK,OAAO,QAAQ,KAAK,QAAQ,QAAQ,KAAK,OAAO,QAAQ,MAAM,CAAC,CAAC,EAAE,CAAC;AAAA,IAC3F;AACA,QAAI,UAAU,MAAM,KAAK,KAAK,EAAG,aAAY;AAAA,EAC/C;AACA,SAAO;AACT;AAEA,SAAS,UAAU,MAAoB,SAAuD;AAC5F,UAAQ,KAAK,MAAM;AAAA,IACjB,KAAK,UAAU;AACb,YAAM,MAA2B,CAAC;AAClC,eAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACvC,cAAM,OAAO,QAAQ,CAAC;AACtB,YAAI,CAAC,UAAU,MAAM,KAAK,CAAE,GAAG;AAC7B,cAAI,KAAK;AAAA,YACP,MAAM,KAAK;AAAA,YACX,QAAQ,KAAK;AAAA,YACb,QAAQ,QAAQ,QAAQ,MAAM,CAAC,CAAC,MAAM,KAAK,QAAQ,EAAE,mBAAmB,kBAAkB,KAAK,CAAE,CAAC;AAAA,UACpG,CAAC;AAAA,QACH;AAAA,MACF;AACA,aAAO;AAAA,IACT;AAAA,IACA,KAAK,SAAS;AACZ,YAAM,MAA2B,CAAC;AAClC,eAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACvC,cAAM,OAAO,QAAQ,CAAC;AACtB,YAAI,UAAU,MAAM,KAAK,CAAE,GAAG;AAC5B,cAAI,KAAK;AAAA,YACP,MAAM,KAAK;AAAA,YACX,QAAQ,KAAK;AAAA,YACb,QAAQ,QAAQ,QAAQ,MAAM,CAAC,CAAC,MAAM,KAAK,QAAQ,EAAE,oBAAoB,kBAAkB,KAAK,CAAE,CAAC;AAAA,UACrG,CAAC;AAAA,QACH;AAAA,MACF;AACA,aAAO;AAAA,IACT;AAAA,IACA,KAAK,cAAc;AACjB,YAAM,MAAM,QAAQ,KAAK,CAAC,SAAS,UAAU,MAAM,KAAK,CAAE,CAAC;AAC3D,aAAO,MACH,CAAC,IACD;AAAA,QACE;AAAA,UACE,MAAM,KAAK;AAAA,UACX,QAAQ,8BAA8B,kBAAkB,KAAK,CAAE,CAAC,UAAU,QAAQ,MAAM;AAAA,QAC1F;AAAA,MACF;AAAA,IACN;AAAA,IACA,KAAK;AACH,aAAO,aAAa;AAAA,QAClB,OAAO,KAAK;AAAA,QACZ;AAAA,QACA,OAAO,KAAK;AAAA,QACZ,SAAS,KAAK;AAAA,QACd,QAAQ,CAAC,QACP,QAAQ,GAAG,YAAY,kBAAkB,KAAK,CAAE,CAAC,oBAAoB,kBAAkB,KAAK,CAAE,CAAC;AAAA,MACnG,CAAC;AAAA,IACH,KAAK;AACH,aAAO,aAAa;AAAA,QAClB,OAAO,KAAK;AAAA,QACZ;AAAA,QACA,OAAO,KAAK;AAAA,QACZ,SAAS,KAAK;AAAA,QACd,QAAQ,CAAC,QACP,QAAQ,GAAG,YAAY,kBAAkB,KAAK,CAAE,CAAC,oBAAoB,kBAAkB,KAAK,KAAM,CAAC;AAAA,MACvG,CAAC;AAAA,EACL;AACF;AAOO,SAAS,sBACd,UACA,OACiB;AACjB,iBAAe,QAAQ;AACvB,QAAM,UAAU,WAAW,KAAK;AAChC,QAAMC,UAAiC,CAAC;AACxC,QAAM,aAAkC,CAAC;AACzC,aAAW,QAAQ,SAAS,OAAO;AACjC,UAAM,iBAAiB,UAAU,MAAM,OAAO;AAC9C,IAAAA,QAAO,KAAK,KAAK,IAAI,eAAe,WAAW,IAAI,IAAI;AACvD,eAAW,KAAK,GAAG,cAAc;AAAA,EACnC;AACA,QAAM,YAAY,SAAS,MAAM;AACjC,QAAM,YAAY,OAAO,OAAOA,OAAM,EAAE,OAAO,CAAC,MAAM,MAAM,CAAC,EAAE;AAC/D,SAAO;AAAA,IACL,UAAU,SAAS;AAAA,IACnB,OAAO,cAAc;AAAA,IACrB,OAAO,YAAY;AAAA,IACnB,QAAAA;AAAA,IACA;AAAA,IACA,OAAO,GAAG,SAAS,IAAI,SAAS;AAAA,EAClC;AACF;AAMO,SAAS,oBACd,OACA,WACqB;AACrB,MAAI,UAAU,WAAW,GAAG;AAC1B,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,QAAM,WAAW,UAAU,IAAI,CAAC,MAAM,sBAAsB,GAAG,KAAK,CAAC;AACrE,SAAO,EAAE,UAAU,UAAU,SAAS,MAAM,CAAC,MAAM,EAAE,KAAK,EAAE;AAC9D;AAsBO,SAAS,cACd,WACA,MACmC;AACnC,MAAI,UAAU,WAAW,GAAG;AAC1B,UAAM,IAAI,gBAAgB,+CAA+C;AAAA,EAC3E;AACA,aAAW,KAAK,UAAW,gBAAe,CAAC;AAC3C,QAAM,QAAQ,oBAAI,IAAY;AAC9B,aAAW,KAAK,WAAW;AACzB,QAAI,MAAM,IAAI,EAAE,IAAI,GAAG;AACrB,YAAM,IAAI;AAAA,QACR,2CAA2C,EAAE,IAAI;AAAA,MACnD;AAAA,IACF;AACA,UAAM,IAAI,EAAE,IAAI;AAAA,EAClB;AACA,MAAI,OAAO,MAAM,UAAU,YAAY;AACrC,UAAM,IAAI,gBAAgB,2DAA2D;AAAA,EACvF;AACA,QAAM,aAA+B,UAAU,IAAI,CAAC,OAAO;AAAA,IACzD,KAAK,EAAE;AAAA,IACP,aAAa,EAAE,MAAM,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,IAAI;AAAA,EACpD,EAAE;AACF,SAAO;AAAA,IACL,MAAM,KAAK,QAAQ;AAAA,IACnB;AAAA,IACA,MAAM,EAAE,UAAU,SAAS,GAAG;AAC5B,YAAM,QAAQ,KAAK,MAAM,EAAE,UAAU,SAAS,CAAC;AAC/C,UAAI,CAAC,MAAM,QAAQ,KAAK,GAAG;AACzB,cAAM,IAAI;AAAA,UACR,wDAAwD,OAAO,KAAK;AAAA,QACtE;AAAA,MACF;AACA,YAAM,EAAE,SAAS,IAAI,oBAAoB,OAAO,SAAS;AACzD,YAAM,OAA+B,CAAC;AACtC,YAAM,aAAkC,CAAC;AACzC,iBAAW,KAAK,UAAU;AACxB,aAAK,EAAE,QAAQ,IAAI,EAAE;AACrB,mBAAW,KAAK,GAAG,EAAE,UAAU;AAAA,MACjC;AACA,YAAM,YAAY,SAAS,OAAO,CAAC,KAAK,MAAM,MAAM,EAAE,OAAO,CAAC,IAAI,SAAS;AAC3E,aAAO;AAAA,QACL,YAAY;AAAA,QACZ;AAAA,QACA,OACE,WAAW,WAAW,IAClB,kCACA,WACG,MAAM,GAAG,CAAC,EACV,IAAI,CAAC,MAAM,GAAG,EAAE,IAAI,KAAK,EAAE,MAAM,EAAE,EACnC,KAAK,IAAI;AAAA,MACpB;AAAA,IACF;AAAA,EACF;AACF;;;ACvlBO,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;AAAA;AAAA,EAIA,kBAAkB,UAAsC;AACtD,WAAO;AAAA,MACL,OAAO,SAAS,KAAK,KAAK,uBAAuB,SAAS,IAAI;AAAA,MAC9D,OAAO,YAAY;AACjB,cAAM,QAAQ,MAAM,KAAK,MAAM,MAAM,EAAE,OAAO,KAAK,MAAM,CAAC;AAC1D,cAAM,UAAU,sBAAsB,UAAU,KAAK;AACrD,YAAI,QAAQ,OAAO;AACjB,iBAAO,EAAE,IAAI,MAAM,QAAQ,aAAa,SAAS,IAAI,MAAM,QAAQ,KAAK,GAAG;AAAA,QAC7E;AACA,eAAO;AAAA,UACL,IAAI;AAAA,UACJ,QAAQ,QAAQ,WAAW,IAAI,CAAC,MAAM,GAAG,EAAE,IAAI,KAAK,EAAE,MAAM,EAAE,EAAE,KAAK,IAAI;AAAA,UACzE,UAAU,QAAQ,WAAW,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG;AAAA,QACtD;AAAA,MACF;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;;;ACzMA,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,QAAMC,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;;;ACzJA,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;AAAA,EACE;AAAA,EACA,cAAAC;AAAA,EACA,aAAa;AAAA,EACb,eAAAC;AAAA,EACA,gBAAAC;AAAA,EACA,YAAAC;AAAA,OACK;AACP,SAAS,WAAW,QAAAC,aAAY;AAiEzB,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,WAAO,iBAAiB,IAAI,MAAM;AAAA,EACpC;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,SAAS,KAAK;AAKZ,UAAI,YAAY,KAAK,QAAQ,EAAG,QAAO;AACvC,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EACA,MAAM,QAAQ,MAAmC;AAC/C,QAAI;AACJ,QAAI;AACF,gBAAUD,aAAY,IAAI;AAAA,IAC5B,SAAS,KAAK;AAIZ,UAAI,YAAY,KAAK,QAAQ,EAAG,QAAO,CAAC;AACxC,YAAM;AAAA,IACR;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,SAAS,KAAK;AAGZ,YAAI,YAAY,KAAK,QAAQ,EAAG;AAChC,cAAM;AAAA,MACR;AAAA,IACF;AACA,WAAO;AAAA,EACT;AACF;AAEA,SAAS,YAAY,KAAc,MAA8C;AAC/E,SAAO,OAAO,QAAQ,YAAY,QAAQ,QAAS,IAA8B,SAAS;AAC5F;AAWA,SAAS,iBAAiB,MAA6B;AAErD,MAAI,KAAK,SAAS,GAAG,KAAK,KAAK,SAAS,IAAI,GAAG;AAC7C,WAAO,aAAa,IAAI,IAAI,OAAO;AAAA,EACrC;AACA,QAAM,UAAU,QAAQ,IAAI,QAAQ;AACpC,QAAM,OAAO,QAAQ,MAAM,SAAS,EAAE,OAAO,CAAC,MAAM,EAAE,SAAS,CAAC;AAChE,QAAM,OACJ,QAAQ,aAAa,WAChB,QAAQ,IAAI,WAAW,uBAAuB,MAAM,GAAG,EAAE,OAAO,CAAC,MAAM,EAAE,SAAS,CAAC,IACpF,CAAC,EAAE;AACT,aAAW,OAAO,MAAM;AACtB,eAAW,OAAO,MAAM;AACtB,YAAM,YAAYA,MAAK,KAAK,OAAO,GAAG;AACtC,UAAI,aAAa,SAAS,EAAG,QAAO;AAAA,IACtC;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,aAAa,MAAuB;AAC3C,MAAI;AAGF,eAAW,MAAM,QAAQ,aAAa,UAAU,YAAY,OAAO,YAAY,IAAI;AACnF,WAAO;AAAA,EACT,SAAS,KAAK;AAIZ,QAAI,YAAY,KAAK,QAAQ,KAAK,YAAY,KAAK,QAAQ,KAAK,YAAY,KAAK,SAAS,GAAG;AAC3F,aAAO;AAAA,IACT;AACA,UAAM;AAAA,EACR;AACF;;;ACnJO,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,UAAMC,WAAU,MAAM,KAAK,KAAK,SAAS,EAAE,KAAK,CAAC;AACjD,QAAIA,SAAQ,WAAW,EAAG;AAE1B,UAAM,QAAQ,EAAE,YACZA,SAAQ,OAAO,CAACC,MAAK,MAAMA,OAAM,EAAE,UAAW,CAAC,GAAG,CAAC,IACnDD,SAAQ;AAEZ,WAAO;AAAA,MACL;AAAA,MACA,SAAS,EAAE;AAAA,MACX,SAASA,SAAQ,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,IAAM,gBAAgB;AACtB,IAAM,kBAAkB;AACxB,IAAM,qBAAqB;AAC3B,IAAM,uBAAuB;AAC7B,IAAM,mBAAmB;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,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,YAAY,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,EAA4C,SAAS,MAAM,KAAK,cAAc,MAAM,CAAC;AAAA;AAAA,IAAS,EAAE;AAAA,EAChP,SAAS,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,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,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,SAAS,YAAY,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,QAAgC,GAAG,KAAK,IAAI;AAChD,WAAO,UAAU,MAAM;AACrB,YAAM,MAAM,MAAM,CAAC;AACnB,UAAI;AACF,aAAK,IAAI,IAAI,IAAI,KAAK,OAAO,EAAE,SAAS,CAAC;AAAA,MAC3C,QAAQ;AAAA,MAER;AACA,cAAQ,GAAG,KAAK,IAAI;AAAA,IACtB;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;;;AC/GO,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;AAOO,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,QAAM,UAAU,qBAAqB,CAAC,wBAAwB,cAAc,KAAK,eAAe;AAChG,QAAM,eAAe,kBAAkB,IAAI,sBAAsB,kBAAkB;AACnF,SAAO;AAAA,IACL,QAAQ;AAAA,IACR;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,OAAO;AAAA,IACP,OAAO;AAAA,IACP,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;;;ACtTA,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,kBAAAE,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,QAAMC,WAAkC,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,MAAAA,SAAQ,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,MAAAA,SAAQ,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,UAAUA,UAAS,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,QAAMA,WAAU,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,UAAUA,UAAS,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,OAAOD,SAAQ,OAAO,KAAK,GAAG,QAAQ,OAAO,UAAU,GAAG;AACrE;AAEA,SAAS,mBACP,UACAC,UACA,gBAC8B;AAC9B,QAAM,UAAUA,SAAQ,OAAO,CAAC,UAAU,MAAM,OAAO,EAAE;AACzD,QAAM,QAAQ,SAAS,WAAW;AAClC,QAAM,gBAAgBA,SACnB,OAAO,CAAC,UAAU,MAAM,OAAO,EAC/B,OAAO,CAACC,MAAK,UAAUA,OAAM,MAAM,QAAQ,CAAC;AAC/C,QAAM,cAAcD,SAAQ,OAAO,CAACC,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,SAAAF;AAAA,EACF;AACF;AAEA,SAAS,iBACPH,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,UAAUI,KAAIJ,QAAO,IAAI,CAAC,UAAU,MAAM,OAAO,CAAC;AACxD,QAAM,QAAQI,KAAIJ,QAAO,IAAI,CAAC,UAAU,MAAM,KAAK,CAAC;AACpD,QAAM,iBAAiBI,KAAIJ,QAAO,IAAI,CAAC,UAAU,MAAM,cAAc,CAAC;AACtE,QAAM,gBAAgBI,KAAIJ,QAAO,IAAI,CAAC,UAAU,MAAM,aAAa,CAAC;AACpE,QAAM,cAAcI,KAAIJ,QAAO,IAAI,CAAC,UAAU,MAAM,WAAW,CAAC;AAChE,QAAMK,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,IAAI,OAAO,CAAC,CAAC;AAC9B,QAAM,QAAQ,IAAI,IAAI,OAAO,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,SAAS,OAAO,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,SAASE,KAAI,QAA0B;AACrC,SAAO,OAAO,OAAO,CAAC,KAAK,UAAU,MAAM,OAAO,CAAC;AACrD;AAEA,SAASH,MAAK,QAA0B;AACtC,SAAO,OAAO,SAASG,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,MAAME,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;;;AC9QA,SAAS,gBAAgB;AAoGzB,SAASC,UAAS,KAAoC;AACpD,QAAM,IAAI,IAAI;AACd,QAAM,IAAI,EAAE,gBAAgB,EAAE,eAAe,EAAE,KAAK;AACpD,SAAO,OAAO,MAAM,YAAY,OAAO,SAAS,CAAC,IAAI,IAAI;AAC3D;AAGA,SAAS,QAAQ,KAAwB;AACvC,SAAO,IAAI,cAAc,IAAI;AAC/B;AAGA,SAAS,iBAAiB,MAAwC;AAChE,QAAM,MAAM,oBAAI,IAAwC;AACxD,aAAW,OAAO,MAAM;AACtB,UAAM,IAAIA,UAAS,GAAG;AACtB,QAAI,MAAM,OAAW;AACrB,UAAM,MAAM,QAAQ,GAAG;AACvB,UAAM,MAAM,IAAI,IAAI,GAAG,KAAK,EAAE,KAAK,GAAG,GAAG,EAAE;AAC3C,QAAI,OAAO;AACX,QAAI,KAAK;AACT,QAAI,IAAI,KAAK,GAAG;AAAA,EAClB;AACA,SAAO,IAAI,IAAI,CAAC,GAAG,GAAG,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;AAC3D;AAKO,SAAS,qBAAqB,SAAyB;AAC5D,SAAO,SAAS,OAAO,KAAK,SAAS,MAAM,CAAC,EAAE,aAAa;AAC7D;AAIO,SAAS,oBACd,aACA,MACA,YACQ;AACR,MAAI,OAAO;AACX,aAAW,OAAO,MAAM;AACtB,UAAM,IAAI,YAAY,IAAI,GAAG;AAC7B,QAAI,MAAM,OAAW;AACrB,YAAQ,CAAC,KAAK,KAAK,KAAK,IAAI,GAAG,UAAU,CAAC;AAAA,EAC5C;AACA,SAAO;AACT;AAEO,IAAM,wBAAN,MAA4B;AAAA,EAChB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEjB,YAAY,QAAiC;AAC3C,QAAI,CAAC,OAAO,YAAa,OAAM,IAAI,MAAM,gDAAgD;AACzF,SAAK,cAAc,OAAO;AAC1B,SAAK,SAAS,OAAO,UAAU;AAC/B,SAAK,aAAa,OAAO,cAAc;AACvC,SAAK,aAAa,OAAO,cAAc,KAAK;AAC5C,SAAK,WAAW,OAAO,YAAY;AACnC,QAAI,EAAE,KAAK,UAAU,GAAI,OAAM,IAAI,MAAM,gDAA2C;AACpF,QAAI,EAAE,KAAK,aAAa,KAAK,KAAK,aAAa;AAC7C,YAAM,IAAI,MAAM,oDAAoD;AAAA,EACxE;AAAA;AAAA;AAAA;AAAA,EAKA,SACE,WACA,UAC2B;AAC3B,UAAM,cAAc,iBAAiB,UAAU,MAAM,KAAK,WAAW;AACrE,UAAM,aAAa,iBAAiB,UAAU,IAAI;AAClD,UAAM,aAAa,iBAAiB,SAAS,IAAI;AAGjD,UAAM,SAAS,CAAC,GAAG,WAAW,KAAK,CAAC,EAAE,OAAO,CAAC,MAAM,WAAW,IAAI,CAAC,CAAC;AAErE,UAAM,YAAY;AAAA,MAChB,WAAW,KAAK,SAAS,qBAAqB,UAAU,OAAO;AAAA,MAC/D,UAAU,KAAK,SAAS,qBAAqB,SAAS,OAAO;AAAA,IAC/D;AACA,UAAM,WAAW;AAAA,MACf,WAAW,oBAAoB,YAAY,QAAQ,KAAK,UAAU;AAAA,MAClE,UAAU,oBAAoB,YAAY,QAAQ,KAAK,UAAU;AAAA,IACnE;AACA,UAAM,YAAY;AAAA,MAChB,WAAW,UAAU,YAAY,SAAS;AAAA,MAC1C,UAAU,UAAU,WAAW,SAAS;AAAA,IAC1C;AACA,UAAM,WAAsC;AAAA,MAC1C,OAAO,OAAO;AAAA,MACd;AAAA,MACA;AAAA,MACA;AAAA,MACA,WAAW,UAAU,YAAY,UAAU;AAAA,MAC3C,gBAAgB,UAAU,YAAY,UAAU;AAAA,MAChD,eAAe,SAAS,YAAY,SAAS;AAAA,IAC/C;AACA,UAAM,OAAO,EAAE,aAAa,YAAY,KAAK,aAAa,SAAS;AACnE,UAAMC,OAAM,CAAC,MAAc,EAAE,QAAQ,CAAC;AAEtC,QAAI,OAAO,SAAS,KAAK,UAAU;AACjC,aAAO;AAAA,QACL,GAAG;AAAA,QACH,SAAS;AAAA,QACT,QAAQ,cAAc,OAAO,MAAM,yBAAyB,KAAK,QAAQ;AAAA,QACzE,eAAe;AAAA,MACjB;AAAA,IACF;AACA,QAAI,EAAE,SAAS,YAAY,CAAC,KAAK,aAAa;AAG5C,YAAM,OACJ,SAAS,gBAAgB,IAAI,gBAAgB;AAC/C,YAAM,MACJ,SAAS,gBACL,cAAcA,KAAI,SAAS,cAAc,CAAC,sBAAsBA,KAAI,CAAC,SAAS,aAAa,CAAC,mBAC5F,yCAAoCA,KAAI,SAAS,aAAa,CAAC;AACrE,aAAO;AAAA,QACL,GAAG;AAAA,QACH,SAAS;AAAA,QACT,QAAQ,GAAG,IAAI,kBAAaA,KAAI,SAAS,SAAS,CAAC,4BAA4BA,KAAI,KAAK,UAAU,CAAC,sBAAiB,GAAG;AAAA,QACvH,eAAe;AAAA,MACjB;AAAA,IACF;AACA,WAAO;AAAA,MACL,GAAG;AAAA,MACH,SAAS;AAAA,MACT,QAAQ,yBAAoBA,KAAI,SAAS,SAAS,CAAC,uBAAkBA,KAAI,SAAS,cAAc,CAAC,iBAAYA,KAAI,SAAS,aAAa,CAAC,UAAU,OAAO,MAAM;AAAA,MAC/J,eAAe;AAAA,IACjB;AAAA,EACF;AACF;AAEA,SAAS,iBAAiB,MAAmB,aAA6B;AACxE,aAAW,OAAO;AAChB,QAAI,IAAI,eAAe,IAAI,gBAAgB,YAAa,QAAO,IAAI;AACrE,SAAO,KAAK,CAAC,GAAG,eAAe;AACjC;;;AC5OA,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,QAAMC,WAAU,QAAQ,IAAI,CAAC,WAAW,cAAc,QAAQ,SAAS,CAAC;AACxE,SAAO;AAAA,IACL,SAAAA;AAAA,IACA,MAAMA,SAAQ,OAAO,OAAO,EAAE;AAAA,IAC9B,OAAO,QAAQ;AAAA,EACjB;AACF;AAEA,SAASD,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,cAAcE,kBAAiB,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,SAASD,kBAAiB,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,SAASC,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;;;ACvVO,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;AAK/B,QAAM,UAAoB,CAAC;AAC3B,QAAM,QAAQ,IAAI,MAAM;AACxB,MAAI,aAAa;AAMjB,MAAI,YAAY;AAChB,MAAI,iBAAiB;AACrB,MAAI,SAAS;AACb,MAAI,UAAU;AACd,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,YAAY,KAAK,MAAM;AAGxC,iBAAS,QAAQ,YAAY;AAC7B;AACA,eAAO;AAAA,MACT;AACA,aAAO;AAAA,IACT,CAAC;AACD,QAAI,MAAO,QAAO;AAClB,QAAI,WAAW,QAAW;AACxB,UAAI;AACJ,UAAI;AACF,mBAAW,MAAM,KAAK,QAAQ,OAAO,MAAM;AAAA,MAC7C,SAAS,KAAK;AAGZ,cAAM,MAAM,aAAa,MAAM;AAC7B;AAAA,QACF,CAAC;AACD,YAAI,CAAC,QAAS,kBAAiB;AAC/B,cAAM;AAAA,MACR;AACA,YAAM,QAAsB;AAAA,QAC1B,MAAM,EAAE,IAAI,QAAQ,SAAS;AAAA,QAC7B,MAAM;AAAA,MACR;AACA,YAAM,MAAM,aAAa,MAAM;AAC7B,cAAM,KAAK,KAAK;AAChB;AAAA,MACF,CAAC;AACD,aAAO;AAAA,IACT;AAEA,WAAO,IAAI,QAAsB,CAAC,SAAS,WAAW;AACpD,cAAQ,KAAK,EAAE,SAAS,OAAO,CAAC;AAAA,IAClC,CAAC;AAAA,EACH;AAOA,WAAS,iBAAiB,OAA2B;AACnD,UAAM,OAAO,QAAQ,MAAM;AAC3B,QAAI,MAAM;AACR,YAAM,OAAO;AACb,WAAK,QAAQ,KAAK;AAAA,IACpB;AAAA,EACF;AAQA,WAAS,mBAAyB;AAChC,UAAM,OAAO,QAAQ,MAAM;AAC3B,QAAI,CAAC,KAAM;AACX,gBAAY,EAAE,KAAK,KAAK,SAAS,KAAK,MAAM;AAAA,EAC9C;AAWA,WAAS,YAAY,OAA2B;AAC9C,UAAM,YAAY;AAChB,UAAI;AACF,YAAI,KAAK,QAAQ,OAAO;AACtB,gBAAM,KAAK,QAAQ,MAAM,MAAM,IAAI;AAAA,QACrC;AACA,cAAM,OAAO;AACb,YAAI,CAAC,QAAS,kBAAiB,KAAK;AAAA,MACtC,SAAS,UAAU;AAGjB,cAAM,MAAM,aAAa,MAAM;AAC7B,gBAAM,IAAI,MAAM,QAAQ,KAAK;AAC7B,cAAI,MAAM,GAAI,OAAM,OAAO,GAAG,CAAC;AAAA,QACjC,CAAC;AACD,YAAI;AACF,gBAAM,KAAK,QAAQ,QAAQ,MAAM,IAAI;AAAA,QACvC,SAAS,YAAY;AACnB,kBAAQ;AAAA,YACN,wCAAwC,MAAM,KAAK,EAAE;AAAA,YACrD;AAAA,UACF;AAAA,QACF;AACA,gBAAQ;AAAA,UACN,wCAAwC,MAAM,KAAK,EAAE;AAAA,UACrD;AAAA,QACF;AACA,YAAI,CAAC,QAAS,kBAAiB;AAAA,MACjC;AAAA,IACF,GAAG,EAAE,MAAM,CAAC,QAAQ;AAGlB,cAAQ,KAAK,kCAAkC,MAAM,KAAK,EAAE,aAAa,GAAG;AAAA,IAC9E,CAAC;AAAA,EACH;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;AACpC,cAAU;AAGV,UAAM,EAAE,UAAU,QAAQ,IAAI,MAAM,MAAM,aAAa,MAAM;AAC3D,YAAM,QAAQ,MAAM,OAAO,GAAG,MAAM,MAAM;AAC1C,YAAM,SAAS,QAAQ,OAAO,GAAG,QAAQ,MAAM;AAC/C,aAAO,EAAE,UAAU,OAAO,SAAS,OAAO;AAAA,IAC5C,CAAC;AAID,eAAW,KAAK,SAAS;AACvB,QAAE,OAAO,IAAI,MAAM,mDAAmD,CAAC;AAAA,IACzE;AACA,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;;;ACzPO,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;;;ACrBA,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;;;ACvEO,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,UAAI,eAAe;AACnB,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,YAAI;AACF,gBAAMA,UAAS,MAAM,SAAS,IAAI,KAAK;AACvC,oBAAU,KAAK,GAAGA,OAAM;AAAA,QAC1B,SAAS,KAAK;AAKZ,cAAI,EAAE,eAAe,iBAAkB,OAAM;AAC7C;AAAA,QACF;AAAA,MACF;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,uBAAuB;AAAA,UACvB,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;;;AC/DA,IAAM,gBAAgB;AAOf,SAAS,oBACd,SACsD;AACtD,QAAM,OAAO,QAAQ,QAAQ;AAC7B,QAAM,WAAW,QAAQ,YAAY;AACrC,QAAM,eAAe,QAAQ,iBAAiB,CAAC,aAAa;AAC5D,SAAO;AAAA,IACL;AAAA,IACA,YAAY,aAAa,IAAI,CAAC,SAAS;AAAA,MACrC;AAAA,MACA,aAAa,yEAAyE,GAAG;AAAA,IAC3F,EAAE;AAAA,IACF,WAAW,WAAW,CAAC,aAAuB,SAAS,SAAS,SAAS;AAAA,IACzE,MAAM,EAAE,UAAU,SAAS,GAAe;AACxC,YAAM,EAAE,OAAO,WAAW,IAAI,QAAQ,cAAc,UAAU,SAAS,KAAK;AAC5E,UAAI,CAAC,OAAO,SAAS,KAAK,KAAK,QAAQ,KAAK,QAAQ,GAAG;AACrD,cAAM,IAAI;AAAA,UACR,+DAA+D,KAAK,kBAAkB,SAAS,EAAE;AAAA,QACnG;AAAA,MACF;AAIA,YAAM,UAAkC,EAAE,CAAC,aAAa,GAAG,OAAO,GAAG,WAAW;AAChF,YAAM,UAAU,OAAO,QAAQ,UAAU,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;AACxE,YAAM,QAAQ,UACV,aAAa,MAAM,QAAQ,CAAC,CAAC,oBAAoB,QAAQ,CAAC,CAAC,MAAM,QAAQ,CAAC,EAAE,QAAQ,CAAC,CAAC,MACtF,aAAa,MAAM,QAAQ,CAAC,CAAC;AACjC,aAAO,EAAE,WAAW,OAAO,YAAY,SAAS,MAAM;AAAA,IACxD;AAAA,EACF;AACF;AAqBO,SAAS,eACd,MACkC;AAClC,QAAM,cAAc,KAAK,eAAe,CAAC;AACzC,QAAM,QAAQ,KAAK,SAAS,CAAC;AAC7B,MAAI,YAAY,WAAW,KAAK,MAAM,WAAW,GAAG;AAClD,UAAM,IAAI,MAAM,qEAAqE;AAAA,EACvF;AACA,SAAO,CAAC,UAAU,SAAS;AACzB,UAAM,IAAK,YAAY,CAAC;AACxB,UAAM,IAAK,QAAQ,CAAC;AACpB,UAAM,aAAqC,CAAC;AAC5C,eAAW,SAAS,aAAa;AAC/B,iBAAW,KAAK,IAAI,qBAAqB,EAAE,KAAK,GAAG,EAAE,KAAK,CAAC;AAAA,IAC7D;AACA,eAAW,SAAS,OAAO;AACzB,iBAAW,KAAK,IAAI,QAAQ,QAAQ,EAAE,KAAK,CAAC,GAAG,QAAQ,EAAE,KAAK,CAAC,CAAC;AAAA,IAClE;AACA,UAAM,SAAS,OAAO,OAAO,UAAU;AACvC,UAAM,QAAQ,OAAO,WAAW,IAAI,IAAI,OAAO,OAAO,CAAC,GAAG,MAAM,IAAI,GAAG,CAAC,IAAI,OAAO;AACnF,WAAO,EAAE,OAAO,WAAW;AAAA,EAC7B;AACF;AAEA,SAAS,qBAAqB,UAAmB,MAAuB;AACtE,MAAI,aAAa,UAAa,SAAS,OAAW,QAAO;AAGzD,SAAO,gBAAgB,QAAQ,MAAM,gBAAgB,IAAI,IAAI,IAAI;AACnE;AAEA,SAAS,gBAAgB,OAAwB;AAI/C,MAAI,UAAU,OAAW,QAAO;AAChC,MAAI,UAAU,KAAM,QAAO;AAC3B,SAAO,KAAK,UAAU,KAAK;AAC7B;AAEA,SAAS,QAAQ,OAA2B;AAC1C,MAAI,MAAM,QAAQ,KAAK,EAAG,QAAO;AACjC,MAAI,UAAU,UAAa,UAAU,KAAM,QAAO,CAAC;AACnD,SAAO,CAAC,KAAK;AACf;AAIA,SAAS,QAAQ,GAAc,GAAsB;AACnD,QAAM,KAAK,IAAI,IAAI,EAAE,IAAI,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC;AAClD,QAAM,KAAK,IAAI,IAAI,EAAE,IAAI,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC;AAClD,MAAI,GAAG,SAAS,KAAK,GAAG,SAAS,EAAG,QAAO;AAC3C,MAAI,QAAQ;AACZ,aAAW,KAAK,GAAI,KAAI,GAAG,IAAI,CAAC,EAAG;AACnC,QAAM,QAAQ,GAAG,OAAO,GAAG,OAAO;AAClC,SAAO,UAAU,IAAI,IAAI,QAAQ;AACnC;;;ACrJA,SAAS,gBAAAC,qBAAoB;AA4BtB,SAAS,kBACd,WACgC;AAChC,QAAM,OAAOA,cAAa,WAAW,MAAM;AAC3C,SAAO,eAA+B,MAAM,SAAS;AACvD;AAIO,SAAS,eACd,MACA,cAAc,YACkB;AAChC,QAAM,MAAsC,CAAC;AAC7C,QAAM,QAAQ,KAAK,MAAM,IAAI;AAC7B,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,UAAM,MAAM,MAAM,CAAC,EAAG,KAAK;AAC3B,QAAI,IAAI,WAAW,EAAG;AACtB,QAAI;AACJ,QAAI;AACF,eAAS,KAAK,MAAM,GAAG;AAAA,IACzB,SAAS,KAAK;AACZ,YAAM,IAAI;AAAA,QACR,sBAAsB,WAAW,IAAI,IAAI,CAAC,6BACxC,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CACjD;AAAA,MACF;AAAA,IACF;AACA,UAAM,QAAQ,OAAO,cAAc,OAAO;AAC1C,QAAI,OAAO,UAAU,YAAY,MAAM,WAAW,GAAG;AACnD,YAAM,IAAI;AAAA,QACR,sBAAsB,WAAW,IAAI,IAAI,CAAC;AAAA,MAC5C;AAAA,IACF;AAOA,UAAM,KAAK,MAAM,QAAQ,MAAM,IAAI;AACnC,QAAI,OAAO,UAAU,QAAW;AAC9B,YAAM,IAAI,MAAM,sBAAsB,WAAW,IAAI,IAAI,CAAC,KAAK,KAAK,qBAAqB;AAAA,IAC3F;AACA,QAAI,OAAO,UAAU,QAAW;AAC9B,YAAM,IAAI,MAAM,sBAAsB,WAAW,IAAI,IAAI,CAAC,KAAK,KAAK,qBAAqB;AAAA,IAC3F;AACA,UAAM,WAAyC;AAAA,MAC7C;AAAA,MACA,MAAM;AAAA,MACN,OAAO,OAAO;AAAA,MACd,OAAO,OAAO;AAAA,IAChB;AACA,UAAM,OAAiB,CAAC;AACxB,QAAI,OAAO,MAAO,MAAK,KAAK,WAAW,KAAK,EAAE;AAC9C,QAAI,OAAO,UAAU,OAAW,MAAK,KAAK,SAAS,OAAO,KAAK,EAAE;AACjE,QAAI,KAAK,SAAS,EAAG,UAAS,OAAO;AACrC,QAAI,KAAK,QAAQ;AAAA,EACnB;AACA,MAAI,IAAI,WAAW,GAAG;AACpB,UAAM,IAAI,MAAM,sBAAsB,WAAW,4BAA4B;AAAA,EAC/E;AACA,SAAO;AACT;AAqBO,SAAS,UACd,WACA,UAA4B,CAAC,GACF;AAC3B,QAAM,eAAe,QAAQ,gBAAgB;AAC7C,MAAI,CAAC,OAAO,UAAU,YAAY,KAAK,eAAe,GAAG;AACvD,UAAM,IAAI,MAAM,mFAA8E;AAAA,EAChG;AACA,QAAM,QAAwC,CAAC;AAC/C,QAAM,OAAuC,CAAC;AAC9C,MAAI,gBAAgB;AACpB,aAAW,YAAY,WAAW;AAChC,UAAM,WAAW,cAAc,QAAQ;AACvC,QAAI,aAAa,SAAS;AACxB,YAAM,KAAK,QAAQ;AAAA,IACrB,WAAW,aAAa,QAAQ;AAC9B,WAAK,KAAK,QAAQ;AAAA,IACpB,OAAO;AAGL,UAAI,gBAAgB,iBAAiB,EAAG,MAAK,KAAK,QAAQ;AAAA,UACrD,OAAM,KAAK,QAAQ;AACxB,uBAAiB;AAAA,IACnB;AAAA,EACF;AACA,SAAO,EAAE,OAAO,KAAK;AACvB;AAEA,SAAS,cAAc,UAAsD;AAC3E,aAAW,OAAO,SAAS,QAAQ,CAAC,GAAG;AACrC,QAAI,QAAQ,cAAe,QAAO;AAClC,QAAI,QAAQ,aAAc,QAAO;AAAA,EACnC;AACA,SAAO;AACT;;;AC/CA,eAAsB,gBACpB,MAC2D;AAC3D,MAAI,KAAK,MAAM,WAAW,EAAG,OAAM,IAAI,MAAM,uCAAuC;AACpF,MAAI,KAAK,QAAQ,WAAW,EAAG,OAAM,IAAI,MAAM,yCAAyC;AAExF,QAAM,OAAO,iBAAiB,KAAK,GAAG;AACtC,QAAM,SAAS,KAAK,uBAAuB;AAC3C,QAAM,QAAQ,KAAK,qBAAsB;AACzC,QAAM,SAAS,KAAK,UAAU,wBAAwB,KAAK,IAAI,CAAC;AAChE,QAAM,qBAAqB,KAAK,sBAAsB;AACtD,QAAM,mBAAmB,KAAK,oBAAoB;AAElD,QAAM,WAAW,aAAa;AAAA,IAC5B,KAAK,KAAK;AAAA,IACV,OAAO,KAAK;AAAA,IACZ,QACE;AAAA,IACF,oBAAoB,KAAK,sBAAsBC;AAAA,IAC/C,aAAa,KAAK;AAAA,EACpB,CAAC;AAED,QAAM,OACJ,KAAK,QACL,YAAqD;AAAA,IACnD,WAAW,KAAK;AAAA,IAChB,gBAAgB,KAAK,kBAAkB;AAAA,EACzC,CAAC;AAEH,QAAM,OAAO,MAAM,mBAA4D;AAAA,IAC7E,iBAAiB,KAAK;AAAA,IACtB,WAAW,KAAK;AAAA,IAChB,kBAAkB,KAAK;AAAA,IACvB,QAAQ,CAAC,KAAK,KAAK;AAAA,IACnB;AAAA,IACA;AAAA,IACA,eAAe;AAAA;AAAA,IACf,gBAAgB,KAAK,kBAAkB;AAAA,IACvC,gBAAgB,KAAK,kBAAkB;AAAA,IACvC,MAAM,KAAK,QAAQ;AAAA,IACnB;AAAA;AAAA;AAAA,IAGA,SAAS;AAAA,IACT,qBAAqB,OAAO,SAAS,UAAU,QAAQ;AACrD,YAAM,SAAS,OAAO;AAAA,QACpB,SAAS,OAAO,YAAY,WAAW,UAAU,KAAK,UAAU,OAAO;AAAA,QACvE,OAAO,SAAS;AAAA,QAChB,YAAY,SAAS;AAAA,MACvB,CAAC;AACD,YAAM,WAAyB,MAAM,KAAK;AAAA,QACxC;AAAA,UACE,OAAO,KAAK;AAAA,UACZ,UAAU;AAAA,UACV,UAAU;AAAA,UACV,aAAa;AAAA,UACb,WAAW;AAAA,QACb;AAAA,QACA,EAAE,QAAQ,IAAI,OAAO;AAAA,MACvB;AACA,kBAAY,IAAI,MAAM,QAAQ;AAC9B,aAAO,MAAM,SAAS,SAAS,SAAS,EAAE;AAAA,IAC5C;AAAA,EACF,CAAC;AAED,QAAM,eACJ,OAAO,KAAK,kBAAkB,WAAW,KAAK,gBAAgB,KAAK;AACrE,QAAM,WAAW,sBAAsB,KAAK,iBAAiB;AAC7D,QAAM,SAAS,sBAAsB,KAAK,eAAe;AAEzD,SAAO;AAAA,IACL,GAAG;AAAA,IACH;AAAA,IACA,kBAAkB,EAAE,UAAU,QAAQ,OAAO,SAAS,SAAS;AAAA,EACjE;AACF;AAMA,SAAS,YACP,MAIA,UACM;AACN,MAAI,OAAO,SAAS,YAAY,SAAU,MAAK,QAAQ,SAAS,SAAS,sBAAsB;AAC/F,OAAK,cAAc;AAAA,IACjB,OAAO,SAAS,MAAM;AAAA,IACtB,QAAQ,SAAS,MAAM;AAAA,IACvB,QAAQ,SAAS,MAAM;AAAA,EACzB,CAAC;AACH;AAEA,IAAMA,+BAA8B;AAAA,EAClC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAIO,SAAS,2BAAmC,MAIvB;AAC1B,SAAO;AAAA,IACL,EAAE,MAAM,UAAU,SAAS,KAAK,QAAQ;AAAA,IACxC;AAAA,MACE,MAAM;AAAA,MACN,SACE;AAAA,EAAW,gBAAgB,KAAK,KAAK,CAAC;AAAA;AAAA;AAAA,IAE1C;AAAA,EACF;AACF;AAIO,SAAS,yBACd,YACA,YACW;AACX,QAAM,WAAW,WAAW,UAAU,EAAE,KAAK;AAC7C,MAAI,SAAS,WAAW,GAAG;AACzB,UAAM,IAAI,MAAM,4DAA4D,UAAU,GAAG;AAAA,EAC3F;AACA,MAAI;AACF,WAAO,KAAK,MAAM,QAAQ;AAAA,EAC5B,SAAS,KAAK;AACZ,UAAM,IAAI;AAAA,MACR,wDAAwD,UAAU,MAChE,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CACjD,gBAAW,SAAS,MAAM,GAAG,GAAG,CAAC;AAAA,IACnC;AAAA,EACF;AACF;AAEA,SAAS,WAAW,MAAsB;AACxC,QAAM,SAAS,kCAAkC,KAAK,IAAI;AAC1D,SAAO,SAAU,OAAO,CAAC,KAAK,OAAQ;AACxC;AAIA,SAAS,gBAAgB,OAAwB;AAC/C,SAAO,KAAK,UAAU,OAAO,iBAAiB,GAAG,CAAC;AACpD;AAEA,SAAS,mBAA6D;AACpE,SAAO,CAAC,MAAM,UAAU;AACtB,QAAI,SAAS,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK,GAAG;AAC/D,YAAM,SAAkC,CAAC;AACzC,iBAAW,KAAK,OAAO,KAAK,KAAgC,EAAE,KAAK,GAAG;AACpE,eAAO,CAAC,IAAK,MAAkC,CAAC;AAAA,MAClD;AACA,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT;AACF;;;ACzRA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACwBO,IAAM,eAAuB;AAAA,EAClC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,EAAE,KAAK,IAAI;AAIJ,IAAM,iBAAyB;AAAA,EACpC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,EAAE,KAAK,IAAI;AAGJ,IAAM,iBAAyB;AAAA,EACpC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,EAAE,KAAK,IAAI;AAGJ,IAAM,iBAAiB;AAAA,EAC5B,UAAU;AAAA,EACV,YAAY;AAAA,EACZ,YAAY;AACd;;;ADLA,SAAS,YAAY,OAA6B;AAChD,QAAM,QAAQ,CAAC,OAAO,MAAM,IAAI,IAAI,MAAM,WAAW;AACrD,MAAI,MAAM,SAAS,SAAS,GAAG;AAC7B,UAAM,KAAK,aAAa,MAAM,SAAS,KAAK,IAAI,CAAC,EAAE;AAAA,EACrD;AACA,MAAI,MAAM,eAAe,QAAW;AAClC,UAAM,KAAK,YAAY,MAAM,UAAU,EAAE;AAAA,EAC3C;AACA,SAAO,MAAM,KAAK,IAAI;AACxB;AASO,SAAS,cAAc,GAA0B;AACtD,QAAM,QAAkB;AAAA,IACtB,EAAE,KAAK,KAAK;AAAA,IACZ;AAAA;AAAA,EAAqB,EAAE,YAAY,KAAK,CAAC;AAAA,IACzC;AAAA;AAAA,EAA0B,EAAE,gBAAgB,KAAK,CAAC;AAAA,IAClD;AAAA;AAAA,EACE,EAAE,OAAO,SAAS,IAAI,EAAE,OAAO,IAAI,WAAW,EAAE,KAAK,MAAM,IAAI,yBACjE;AAAA,IACA;AAAA;AAAA,EACE,EAAE,OAAO,SAAS,IACd,EAAE,OAAO,IAAI,CAAC,MAAM,OAAO,EAAE,KAAK;AAAA;AAAA,EAAO,EAAE,KAAK,KAAK,CAAC,EAAE,EAAE,KAAK,MAAM,IACrE,2BACN;AAAA,EACF;AACA,SAAO,MAAM,KAAK,MAAM;AAC1B;AAIO,SAAS,iBAAiB,GAA0B;AACzD,SAAO,cAAc,CAAC;AACxB;AAEA,IAAM,eAA+B;AAAA,EACnC;AAAA,IACE,MAAM;AAAA,IACN,aACE;AAAA,IACF,UAAU;AAAA,MACR;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,aACE;AAAA,IACF,UAAU,CAAC,yCAAyC,qCAAqC;AAAA,EAC3F;AACF;AAEA,IAAM,uBACJ;AAMF,IAAM,4BACJ;AASK,SAAS,gBAAgB,MAKd;AAChB,SAAO;AAAA,IACL,MAAM,KAAK;AAAA,IACX,aAAa,KAAK,eAAe;AAAA,IACjC,iBAAiB,KAAK,mBAAmB;AAAA,IACzC,QAAQ,KAAK,UAAU;AAAA,IACvB,QAAQ,CAAC;AAAA,EACX;AACF;AASO,SAAS,wBACd,MACA,OAAoF,CAAC,GACtE;AACf,SAAO,gBAAgB,EAAE,MAAM,eAAe,IAAI,GAAG,GAAG,KAAK,CAAC;AAChE;AAMO,SAAS,YACd,UACA,SACe;AACf,SAAO,EAAE,GAAG,UAAU,QAAQ,CAAC,GAAG,SAAS,QAAQ,GAAG,OAAO,EAAE;AACjE;AASO,SAAS,iBACd,GACA,WACA,SACe;AACf,QAAM,MAAM,EAAE,OAAO,UAAU,CAAC,MAAM,EAAE,OAAO,SAAS;AACxD,MAAI,QAAQ,IAAI;AACd,UAAM,IAAI;AAAA,MACR,wCAAwC,SAAS,YAC/C,EAAE,OAAO,IAAI,CAAC,MAAM,EAAE,EAAE,EAAE,KAAK,IAAI,KAAK,QAC1C;AAAA,IACF;AAAA,EACF;AACA,QAAM,SAAS,EAAE,OAAO,GAAG;AAC3B,MAAI,WAAW,QAAW;AACxB,UAAM,IAAI,MAAM,qCAAqC,SAAS,yBAAyB;AAAA,EACzF;AACA,MAAI,CAAC,OAAO,WAAW;AACrB,UAAM,IAAI,MAAM,qCAAqC,SAAS,oBAAoB;AAAA,EACpF;AACA,QAAM,OAAO,CAAC,GAAG,EAAE,MAAM;AACzB,OAAK,GAAG,IAAI,EAAE,GAAG,QAAQ,MAAM,QAAQ;AACvC,SAAO,EAAE,GAAG,GAAG,QAAQ,KAAK;AAC9B;AAWO,SAAS,YAAY,SAAsC;AAChE,SAAO,mBAAmB,KAAK,UAAU,EAAE,OAAO,QAAQ,OAAO,MAAM,QAAQ,KAAK,CAAC,CAAC;AACxF;;;AEtLO,SAAS,WAAW,QAAgC;AACzD,QAAM,UAAU,OAAO,QAAQ;AAC/B,QAAM,WAAW,oBAAI,IAA6B;AAClD,aAAW,SAAS,OAAO,KAAK,GAAG;AACjC,UAAM,OAAO,SAAS,IAAI,MAAM,KAAK,KAAK;AAAA,MACxC,OAAO,MAAM;AAAA,MACb,KAAK;AAAA,MACL,SAAS;AAAA,MACT,UAAU;AAAA,IACZ;AACA,SAAK,OAAO,MAAM;AAClB,SAAK,WAAW;AAChB,QAAI,MAAM,YAAa,MAAK,WAAW;AACvC,aAAS,IAAI,MAAM,OAAO,IAAI;AAAA,EAChC;AACA,SAAO;AAAA,IACL,YAAY,QAAQ;AAAA,IACpB,OAAO;AAAA,MACL,KAAK,QAAQ;AAAA,MACb,gBAAgB,QAAQ,UAAU,OAAO,CAACC,MAAK,MAAMA,OAAM,EAAE,eAAe,CAAC;AAAA,IAC/E;AAAA,IACA,UAAU,CAAC,GAAG,SAAS,OAAO,CAAC,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,MAAM,cAAc,EAAE,KAAK,CAAC;AAAA,EAChF;AACF;AAQO,SAAS,mBACd,QACA,QAC0B;AAC1B,MAAI,UAAU,QAAQ;AACpB,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,SAAO,EAAE,GAAG,QAAQ,MAAM,WAAW,MAAM,EAAE;AAC/C;;;ACnBO,IAAM,cAA0D;AAAA,EACrE,SAAS;AAAA,IACP,QAAQ;AAAA,IACR,QAAQ,CAAC,aAAa,mBAAmB,cAAc;AAAA,IACvD,SAAS;AAAA,IACT,YAAY;AAAA,IACZ,UAAU;AAAA,EACZ;AAAA,EACA,UAAU,CAAC;AACb;AAGO,IAAM,iBAAN,cAA6B,YAAY;AAAA,EAC9C,YAA4B,MAAgB;AAC1C;AAAA,MACE,qBAAqB,IAAI;AAAA,IAE3B;AAJ0B;AAAA,EAK5B;AAAA,EAL4B;AAM9B;AAgBO,SAAS,YACd,OACA,MACA,UACmB;AACnB,QAAM,QAAQ,MAAM,IAAI;AACxB,MAAI,SAAS,UAAU;AACrB,QAAI,UAAU,UAAa,CAAC,MAAM,QAAQ,KAAK,GAAG;AAChD,YAAM,IAAI,gBAAgB,qDAAqD,OAAO,KAAK,EAAE;AAAA,IAC/F;AACA,UAAM,SAAS,MAAM,QAAQ,KAAK,IAAI,QAAQ,CAAC;AAC/C,QAAI,OAAO,SAAS,GAAG;AACrB,YAAM,QAAQ,OAAO,UAAU,CAAC,MAAM,OAAO,MAAM,YAAY,EAAE,KAAK,MAAM,EAAE;AAC9E,UAAI,SAAS,GAAG;AACd,cAAM,IAAI;AAAA,UACR,sBAAsB,KAAK;AAAA,QAC7B;AAAA,MACF;AACA,aAAO,CAAC,GAAG,MAAM;AAAA,IACnB;AAAA,EACF,OAAO;AACL,QAAI,UAAU,UAAa,OAAO,UAAU,UAAU;AACpD,YAAM,IAAI,gBAAgB,qBAAqB,IAAI,2BAA2B,OAAO,KAAK,EAAE;AAAA,IAC9F;AACA,QAAI,OAAO,UAAU,YAAY,MAAM,KAAK,MAAM,GAAI,QAAO;AAAA,EAC/D;AACA,MAAI,aAAa,QAAW;AAC1B,QAAI,SAAS,KAAK,MAAM,IAAI;AAC1B,YAAM,IAAI,gBAAgB,kCAAkC,IAAI,YAAY;AAAA,IAC9E;AACA,WAAO,SAAS,WAAW,CAAC,QAAQ,IAAI;AAAA,EAC1C;AACA,QAAM,IAAI,eAAe,IAAI;AAC/B;;;ACxGO,IAAM,wBAAwB;AAsC9B,SAAS,OAAO,QAAiB,YAAmD;AACzF,SAAO;AAAA,IACL,YAAY,YAAY,MAAM;AAAA,IAC9B;AAAA,IACA,WAAW;AAAA,EACb;AACF;AAQO,SAAS,kBACd,QACA,UACyB;AACzB,MAAI,SAAS,cAAc,uBAAuB;AAChD,WAAO;AAAA,MACL,OAAO;AAAA,MACP,QAAQ,sBAAsB,SAAS,SAAS,uCAAkC,qBAAqB;AAAA,IACzG;AAAA,EACF;AACA,MAAI;AACJ,MAAI;AACF,iBAAa,YAAY,MAAM;AAAA,EACjC,SAAS,KAAK;AACZ,WAAO;AAAA,MACL,OAAO;AAAA,MACP,QAAQ,kCAAkC,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,IAC5F;AAAA,EACF;AACA,MAAI,eAAe,SAAS,YAAY;AACtC,WAAO;AAAA,MACL,OAAO;AAAA,MACP,QAAQ,kCAAkC,SAAS,UAAU,gBAAgB,UAAU;AAAA,IACzF;AAAA,EACF;AACA,SAAO,EAAE,OAAO,KAAK;AACvB;","names":["dirname","join","check","sleep","scores","sum","join","readFile","canonicalize","sum","stripSlash","check","pairKey","bootstrapCi","precision","aggregate","scores","matches","matches","toolSpans","matches","ratio","scores","runScore","mean","sum","scores","results","sum","mulberry32","sum","assertNonNegative","fs","mean","scores","medianDelta","fs","mean","matches","existsSync","readFileSync","median","runScore","scores","existsSync","readFileSync","fmt","passed","margin","ai","scores","scores","scores","mean","scores","ratio","worst","join","i","j","pa","scores","mean","runs","groupBy","scores","existsSync","readdirSync","readFileSync","statSync","join","tail","matches","sum","appendFileSync","existsSync","mkdirSync","readFileSync","dirname","scoreOptions","mkdirSync","dirname","appendFileSync","existsSync","scores","mean","clamp01","matches","sum","precision","readFileSync","softFail","runScore","fmt","join","defaultExtract","matches","inferCandidateId","mean","mean","precision","scores","sum","readFileSync","DEFAULT_MUTATION_PRIMITIVES","sum"]}