@tangle-network/agent-eval 0.137.0 → 0.138.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +48 -0
- package/README.md +33 -0
- package/dist/analyst/index.d.ts +473 -39
- package/dist/analyst/index.d.ts.map +1 -1
- package/dist/analyst/index.js +11 -593
- package/dist/analyst/index.js.map +1 -1
- package/dist/{analyze-runs-PVtnfjvA.d.ts → analyze-runs-CPYxfPWT.d.ts} +5 -5
- package/dist/{analyze-runs-PVtnfjvA.d.ts.map → analyze-runs-CPYxfPWT.d.ts.map} +1 -1
- package/dist/{benchmark-YDrpumqB.js → benchmark-D8dkki-J.js} +299 -159
- package/dist/benchmark-D8dkki-J.js.map +1 -0
- package/dist/{benchmark-CHX4orG7.d.ts → benchmark-DlQgU_XI.d.ts} +67 -15
- package/dist/benchmark-DlQgU_XI.d.ts.map +1 -0
- package/dist/benchmark-command-CMqVqReF.js +4332 -0
- package/dist/benchmark-command-CMqVqReF.js.map +1 -0
- package/dist/benchmarks/index.d.ts +1 -1
- package/dist/benchmarks/index.js +1 -1
- package/dist/{benchmarks-DCLkQOmc.js → benchmarks-BJ_xK5rQ.js} +4 -3
- package/dist/{benchmarks-DCLkQOmc.js.map → benchmarks-BJ_xK5rQ.js.map} +1 -1
- package/dist/campaign/index.d.ts +5 -5
- package/dist/campaign/index.js +3 -3
- package/dist/{campaign-lgObcHFC.js → campaign-BIBS-NHV.js} +16 -9
- package/dist/campaign-BIBS-NHV.js.map +1 -0
- package/dist/cli.js +9 -2
- package/dist/cli.js.map +1 -1
- package/dist/{client-C8L6h6Wf.d.ts → client-BwPKohkJ.d.ts} +4 -4
- package/dist/{client-C8L6h6Wf.d.ts.map → client-BwPKohkJ.d.ts.map} +1 -1
- package/dist/{completion-verifier-DSyRNVzU.d.ts → completion-verifier-B4-IMYcS.d.ts} +3 -3
- package/dist/{completion-verifier-DSyRNVzU.d.ts.map → completion-verifier-B4-IMYcS.d.ts.map} +1 -1
- package/dist/contract/index.d.ts +10 -10
- package/dist/contract/index.js +8 -8
- package/dist/control.d.ts +2 -2
- package/dist/{cost-ledger-D2o6JOrL.d.ts → cost-ledger-B1D3COAc.d.ts} +5 -4
- package/dist/{cost-ledger-D2o6JOrL.d.ts.map → cost-ledger-B1D3COAc.d.ts.map} +1 -1
- package/dist/{cost-ledger-D-5_-dhi.js → cost-ledger-CHDLA0Ss.js} +90 -45
- package/dist/cost-ledger-CHDLA0Ss.js.map +1 -0
- package/dist/{default-registry-Dc5D_Loc.d.ts → default-registry-PUhIVRWz.d.ts} +18 -5
- package/dist/default-registry-PUhIVRWz.d.ts.map +1 -0
- package/dist/{default-registry-CLXbRt0f.js → default-registry-lp5R0lve.js} +1503 -258
- package/dist/default-registry-lp5R0lve.js.map +1 -0
- package/dist/{eval-campaign-CHqfLnff.js → eval-campaign-9MozgKL7.js} +2 -2
- package/dist/{eval-campaign-CHqfLnff.js.map → eval-campaign-9MozgKL7.js.map} +1 -1
- package/dist/exact-types-Dpw2LeHA.d.ts +234 -0
- package/dist/exact-types-Dpw2LeHA.d.ts.map +1 -0
- package/dist/{extract-usage-p-56bh8q.js → extract-usage-CS391dOE.js} +2 -2
- package/dist/{extract-usage-p-56bh8q.js.map → extract-usage-CS391dOE.js.map} +1 -1
- package/dist/{feedback-trajectory-N_F0PwHz.d.ts → feedback-trajectory-CoNep7rl.d.ts} +3 -2
- package/dist/feedback-trajectory-CoNep7rl.d.ts.map +1 -0
- package/dist/fuzz.d.ts +1 -1
- package/dist/fuzz.js +1 -1
- package/dist/hosted/index.d.ts +3 -3
- package/dist/{index-U3RHOShi.d.ts → index-B2-IxCMB.d.ts} +2 -2
- package/dist/{index-U3RHOShi.d.ts.map → index-B2-IxCMB.d.ts.map} +1 -1
- package/dist/{index-BnP1QJUv.d.ts → index-CjVYlVBK.d.ts} +5 -5
- package/dist/{index-BnP1QJUv.d.ts.map → index-CjVYlVBK.d.ts.map} +1 -1
- package/dist/{index-C-Pr4OWg.d.ts → index-D0cxAdaV.d.ts} +11 -10
- package/dist/index-D0cxAdaV.d.ts.map +1 -0
- package/dist/index-DEb46kc6.d.ts.map +1 -1
- package/dist/{index-DRNl6g_N.d.ts → index-sMN_hI4E.d.ts} +3 -3
- package/dist/{index-DRNl6g_N.d.ts.map → index-sMN_hI4E.d.ts.map} +1 -1
- package/dist/index.d.ts +24 -23
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +19 -353
- package/dist/index.js.map +1 -1
- package/dist/{insight-report-B9ooYH_g.d.ts → insight-report-CXd8VBDR.d.ts} +4 -4
- package/dist/{insight-report-B9ooYH_g.d.ts.map → insight-report-CXd8VBDR.d.ts.map} +1 -1
- package/dist/{integrity-CKxosZ5Z.d.ts → integrity-B-MLFz0I.d.ts} +2 -2
- package/dist/{integrity-CKxosZ5Z.d.ts.map → integrity-B-MLFz0I.d.ts.map} +1 -1
- package/dist/ledger-core/index.js +1 -1
- package/dist/{ledger-core-t6sItivm.js → ledger-core-C0Yx1I14.js} +220 -27
- package/dist/ledger-core-C0Yx1I14.js.map +1 -0
- package/dist/{llm-client-DKB25jV8.js → llm-client-Cj3c7PEm.js} +5 -5
- package/dist/llm-client-Cj3c7PEm.js.map +1 -0
- package/dist/meta-eval/index.d.ts +2 -2
- package/dist/multishot/index.d.ts +2 -2
- package/dist/openapi.json +1 -1
- package/dist/{proposal-findings-DCawte-y.js → proposal-findings-2GIUo1et.js} +2 -68
- package/dist/proposal-findings-2GIUo1et.js.map +1 -0
- package/dist/{registry-BdM7SuTr.d.ts → registry-C4yJTza7.d.ts} +60 -6
- package/dist/registry-C4yJTza7.d.ts.map +1 -0
- package/dist/{release-report-CofgVNZt.d.ts → release-report-CoyvyLBs.d.ts} +3 -3
- package/dist/{release-report-CofgVNZt.d.ts.map → release-report-CoyvyLBs.d.ts.map} +1 -1
- package/dist/{replay-Bju0T8Ls.js → replay-Cb-4Vf0k.js} +8 -7
- package/dist/replay-Cb-4Vf0k.js.map +1 -0
- package/dist/{replay-K8FaC0CB.d.ts → replay-DbIYwso6.d.ts} +7 -7
- package/dist/{replay-K8FaC0CB.d.ts.map → replay-DbIYwso6.d.ts.map} +1 -1
- package/dist/reporting.d.ts +4 -4
- package/dist/{researcher-Da0Wj-bt.d.ts → researcher-BCeOEjtR.d.ts} +5 -5
- package/dist/{researcher-Da0Wj-bt.d.ts.map → researcher-BCeOEjtR.d.ts.map} +1 -1
- package/dist/{reward-hacking-CQ3hTCO3.d.ts → reward-hacking-sE2l_NV6.d.ts} +2 -2
- package/dist/{reward-hacking-CQ3hTCO3.d.ts.map → reward-hacking-sE2l_NV6.d.ts.map} +1 -1
- package/dist/rl.d.ts +5 -5
- package/dist/rl.js +1 -1
- package/dist/rollout/index.d.ts +1 -1
- package/dist/{rubric-predictive-validity-C4sztLR3.d.ts → rubric-predictive-validity-w2klGv1u.d.ts} +2 -2
- package/dist/{rubric-predictive-validity-C4sztLR3.d.ts.map → rubric-predictive-validity-w2klGv1u.d.ts.map} +1 -1
- package/dist/{run-evidence-BDIircdA.d.ts → run-evidence-CbE0A8Xg.d.ts} +3 -3
- package/dist/{run-evidence-BDIircdA.d.ts.map → run-evidence-CbE0A8Xg.d.ts.map} +1 -1
- package/dist/{run-record-BPCa2rQ8.d.ts → run-record-DwHMk1Ai.d.ts} +2 -2
- package/dist/{run-record-BPCa2rQ8.d.ts.map → run-record-DwHMk1Ai.d.ts.map} +1 -1
- package/dist/{semantic-concept-judge-Bz64IckK.js → semantic-concept-judge-DYXDPZW0.js} +11 -5
- package/dist/semantic-concept-judge-DYXDPZW0.js.map +1 -0
- package/dist/{server-KjXZZUDX.js → server-DLEvyW2z.js} +3 -3
- package/dist/{server-KjXZZUDX.js.map → server-DLEvyW2z.js.map} +1 -1
- package/dist/single-run-lock-D_bS5xhj.js +318 -0
- package/dist/single-run-lock-D_bS5xhj.js.map +1 -0
- package/dist/{skill-usage-CFDLLlhF.d.ts → skill-usage-Bv3G4VkA.d.ts} +18 -8
- package/dist/skill-usage-Bv3G4VkA.d.ts.map +1 -0
- package/dist/{skillopt-optimization-method-f4o9sUT4.js → skillopt-optimization-method-CjKMZy0d.js} +7 -182
- package/dist/skillopt-optimization-method-CjKMZy0d.js.map +1 -0
- package/dist/{skillopt-optimization-method-BpbnlvAZ.d.ts → skillopt-optimization-method-CzfnA8O-.d.ts} +10 -10
- package/dist/{skillopt-optimization-method-BpbnlvAZ.d.ts.map → skillopt-optimization-method-CzfnA8O-.d.ts.map} +1 -1
- package/dist/{statistics-_7P642CN.d.ts → statistics-mf70aXKp.d.ts} +2 -2
- package/dist/{statistics-_7P642CN.d.ts.map → statistics-mf70aXKp.d.ts.map} +1 -1
- package/dist/{tools-DZk2Jn64.js → store-otlp-BenKynPE.js} +4 -192
- package/dist/store-otlp-BenKynPE.js.map +1 -0
- package/dist/{summary-report-DHipz9Kx.d.ts → summary-report-BKinV4yD.d.ts} +3 -3
- package/dist/{summary-report-DHipz9Kx.d.ts.map → summary-report-BKinV4yD.d.ts.map} +1 -1
- package/dist/tools-DZGdROtG.js +255 -0
- package/dist/tools-DZGdROtG.js.map +1 -0
- package/dist/traces.d.ts +5 -5
- package/dist/traces.js +4 -3
- package/dist/{types-CTvKfr5F.d.ts → types-5q2T25iW.d.ts} +2 -2
- package/dist/{types-CTvKfr5F.d.ts.map → types-5q2T25iW.d.ts.map} +1 -1
- package/dist/{types-CKswbJGO.d.ts → types-BtJhn8v6.d.ts} +4 -4
- package/dist/{types-CKswbJGO.d.ts.map → types-BtJhn8v6.d.ts.map} +1 -1
- package/dist/{types-CTGbIm57.d.ts → types-zFYez3PK.d.ts} +5 -5
- package/dist/{types-CTGbIm57.d.ts.map → types-zFYez3PK.d.ts.map} +1 -1
- package/dist/wire/index.d.ts +3 -3
- package/dist/wire/index.js +1 -1
- package/docs/trace-analysis.md +123 -3
- package/package.json +5 -3
- package/dist/benchmark-CHX4orG7.d.ts.map +0 -1
- package/dist/benchmark-YDrpumqB.js.map +0 -1
- package/dist/campaign-lgObcHFC.js.map +0 -1
- package/dist/concurrency-MUjT7VjM.js +0 -109
- package/dist/concurrency-MUjT7VjM.js.map +0 -1
- package/dist/cost-ledger-D-5_-dhi.js.map +0 -1
- package/dist/default-registry-CLXbRt0f.js.map +0 -1
- package/dist/default-registry-Dc5D_Loc.d.ts.map +0 -1
- package/dist/feedback-trajectory-N_F0PwHz.d.ts.map +0 -1
- package/dist/index-C-Pr4OWg.d.ts.map +0 -1
- package/dist/ledger-core-t6sItivm.js.map +0 -1
- package/dist/llm-client-DKB25jV8.js.map +0 -1
- package/dist/proposal-findings-DCawte-y.js.map +0 -1
- package/dist/registry-BdM7SuTr.d.ts.map +0 -1
- package/dist/replay-Bju0T8Ls.js.map +0 -1
- package/dist/semantic-concept-judge-Bz64IckK.js.map +0 -1
- package/dist/skill-usage-CFDLLlhF.d.ts.map +0 -1
- package/dist/skillopt-optimization-method-f4o9sUT4.js.map +0 -1
- package/dist/tools-DZk2Jn64.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"replay-Bju0T8Ls.js","names":["toAttributes","padSpanId","msToNs","padTraceId","padSpanId"],"sources":["../src/trace-analyst/prompts.ts","../src/trace-analyst/analyst.ts","../src/trace-analyst/hook.ts","../src/trace-analyst/insights.ts","../src/trace/otlp-flat.ts","../src/trace-analyst/otlp-flatten.ts","../src/trace-analyst/otlp-to-run-records.ts","../src/trace-analyst/store-tool-spans.ts","../src/trace/capture-fetch.ts","../src/trace/otel.ts","../src/trace/otel-bridge.ts","../src/trace/otel-export.ts","../src/trace/store-to-otlp.ts","../src/replay.ts"],"sourcesContent":["/** Ax RLM prompt for bounded trace discovery and evidence-backed analysis. */\n\nexport const TRACE_ANALYST_ACTOR_DESCRIPTION = `You answer questions about an OTLP-shaped JSONL trace dataset using the trace tools provided in the \\`traces\\` namespace.\n\nDISCOVERY → NARROW → DEEP-READ protocol — follow exactly:\n\n1. ALWAYS call \\`traces.getDatasetOverview({})\\` FIRST without a regex_pattern. The result tells you total_traces, raw_jsonl_bytes, services, agents, models, and sample_trace_ids (real ids — never fabricate one).\n\n2. Use raw_jsonl_bytes to gauge how expensive raw scans will be. \\`filters.regex_pattern\\` is the one scan-heavy filter on getDatasetOverview / queryTraces / countTraces — narrow with indexed fields (has_errors, model_names, service_names, agent_names, time bounds) BEFORE adding a regex on a large dataset.\n\n3. To list more traces than the sample, call \\`traces.queryTraces({ filters?, limit, offset? })\\`. Each summary carries raw_jsonl_bytes — use it to choose between viewTrace and searchTrace BEFORE calling either.\n\n4. Per-trace inspection:\n - SMALL trace (raw_jsonl_bytes well under 150_000): call \\`traces.viewTrace({ trace_id })\\`. Returns all spans. Per-attribute payloads are head-capped at ~4KB; large \\`input.value\\` / \\`output.value\\` / \\`llm.input_messages\\` will show a \\`[trace-analyst truncated: N bytes]\\` marker.\n - LARGE trace (raw_jsonl_bytes near or above 150_000, or you saw an \\`oversized\\` response): use \\`traces.searchTrace({ trace_id, regex_pattern })\\` to get bounded SpanMatchRecords (span metadata + matched text + surrounding context). Then call \\`traces.viewSpans({ trace_id, span_ids: [...] })\\` for surgical reads (~16KB cap, 4× higher than discovery), or \\`traces.searchSpan({ trace_id, span_id, regex_pattern })\\` for one large span. Stays bounded regardless of trace size.\n - Useful regex patterns: \\`STATUS_CODE_ERROR\\` (failures), tool names like \\`grep\\` or \\`view_trace\\`, error strings like \\`MaxTurnsExceeded\\`, model names, attribute keys.\n\n5. ONLY call viewTrace / viewSpans / searchTrace / searchSpan with trace/span ids you have already seen in sample_trace_ids, a queryTraces page, or a previous search result. Never invent ids.\n\n5a. **Result-shape contract** — searchTrace and searchSpan return \\`{ trace_id, hits, has_more }\\`. Iterate \\`result.hits\\` (NOT result.matches). Each hit has \\`{ span_id, span_name, span_kind, attribute_path, matched_text, context_before, context_after, match_offset }\\`. viewTrace returns \\`{ trace_id, spans }\\` (or \\`oversized\\`). viewSpans returns \\`{ trace_id, spans, missing_span_ids, omitted_span_ids, has_more, truncated_attribute_count }\\`; retry only \\`omitted_span_ids\\`. Never assume a field name — log the result shape first if unsure.\n\n6. If viewTrace returns an \\`oversized\\` summary instead of \\`spans\\`, DO NOT retry the same call. Read the summary's top_span_names, span_count, span_response_bytes_max, error_span_count to plan a follow-up: switch to searchTrace (or searchSpan for one large span), then viewSpans on a smaller, surgical span_ids set.\n\n7. If searchTrace or searchSpan returns has_more=true, REFINE the regex to be more specific rather than blindly raising max_matches.\n\n8. If a tool errors (invalid regex, range error), STOP and reconsider — don't retry with a guessed id or argument. Use the discovery tools above to recover.\n\n9. If a ~4KB-truncated payload from viewTrace / searchTrace matters for your answer, first try viewSpans on that span id (~16KB cap). If a 16KB-truncated payload from viewSpans still matters, narrow further with searchSpan against a more specific regex rather than asking for the full payload again.\n\n10. If the question splits into independent reasoning branches, use bounded \\`llmQuery(...)\\` calls over evidence you already loaded. Subqueries cannot inspect the trace store, so pass the exact trace excerpts they need. Example:\n\n const reviews = await llmQuery([\n { query: 'Classify the failure mechanism in this excerpt.', context: traceAbcExcerpt },\n { query: 'Classify the failure mechanism in this excerpt.', context: traceDefExcerpt },\n ]);\n\nOBSERVABILITY rules:\n- Each discovery turn must emit at least one concise \\`console.log(...)\\` showing what evidence was learned.\n- Finish gathering evidence before submitting the analysis.\n- Reuse runtime variables across turns; don't recompute.\n\nOUTPUT contract — your final answer must include:\n- A clear prose conclusion answering the user's question.\n- Trace ids and span ids cited as evidence for each claim.\n- Failure modes named in the user's domain language, with frequency and concrete examples.\n- A concise findings array containing only claims supported by inspected evidence.\n\nDo NOT invent trace ids, span ids, error messages, or model names. Every fact must be traceable to a tool result.`\n\nexport const TRACE_ANALYST_ACTOR_DESCRIPTION_VERSION = 'trace-analyst-actor-v6-2026-07-14'\n","import type { AxAgentActorTurnCallbackArgs, AxAIService, AxFunction } from '@ax-llm/ax'\nimport { runTraceAnalysisLoop, type TraceAnalysisLoopResult } from './loop'\nimport { TRACE_ANALYST_ACTOR_DESCRIPTION, TRACE_ANALYST_ACTOR_DESCRIPTION_VERSION } from './prompts'\nimport type { TraceAnalysisStore } from './store'\nimport { OtlpFileTraceStore } from './store-otlp'\nimport { buildTraceAnalystTools } from './tools'\n\nexport interface AnalyzeTracesInput {\n /** The user-facing question. Domain framing belongs here, not in the\n * actor description. */\n question: string\n}\n\nexport interface AnalyzeTracesResult {\n /** The actor's submitted prose answer. */\n answer: string\n /** Bulleted findings from the actor's structured completion. */\n findings: string[]\n /** Per-turn snapshots captured via `actorTurnCallback`. */\n turns: AnalyzeTracesTurnSnapshot[]\n /** Total turns the actor took. */\n turnCount: number\n /** Token usage by role. */\n usage: TraceAnalystUsage\n /** Full system + assistant + tool message log by role. */\n chatLog: TraceAnalystChatLog\n /** Prompt version that produced this run. */\n actorPromptVersion: string\n}\n\nexport interface TraceAnalystUsage {\n actor: TraceAnalystUsageEntry[]\n responder: TraceAnalystUsageEntry[]\n}\n\nexport interface TraceAnalystUsageEntry {\n [key: string]: unknown\n}\n\nexport interface TraceAnalystChatLog {\n actor: TraceAnalystChatMessage[]\n responder: TraceAnalystChatMessage[]\n}\n\nexport interface TraceAnalystChatMessage {\n [key: string]: unknown\n}\n\nexport interface AnalyzeTracesTurnSnapshot {\n stage: AxAgentActorTurnCallbackArgs['stage']\n turn: number\n isError: boolean\n /** The JS code the actor produced for this turn. */\n code: string\n /** The formatted action-log entry the actor sees on the next turn. */\n output: string\n /** Provider thought (when `executorOptions.showThoughts` is true and the\n * provider returns it). */\n thought?: string\n}\n\nexport interface AnalyzeTracesOptions {\n /** Trace data source. Pass either an OTLP-JSONL path or a custom store. */\n source: string | TraceAnalysisStore\n /** Caller-provided AxAIService. */\n ai: AxAIService\n /** Model id forwarded to the actor. */\n model?: string\n /** Maximum model subqueries. 0 disables model fan-out. Default 4. */\n maxSubqueries?: number\n /** Maximum actor turns. Default 12. */\n maxTurns?: number\n /** Maximum parallel model subqueries. Default 2. */\n maxParallelSubqueries?: number\n /** Cancels in-flight model and tool work. */\n signal?: AbortSignal\n /** Override the actor description. */\n actorDescription?: string\n /** Per-turn observability hook. */\n onTurn?: (turn: AnalyzeTracesTurnSnapshot) => void | Promise<void>\n /** Override max runtime characters per turn. Default 6000. */\n maxRuntimeChars?: number\n /** When set, every turn's snapshot is appended to this JSONL file\n * immediately. If the analyst crashes mid-loop (provider 503,\n * network error, validator reject) the partial reasoning is still\n * on disk for diagnosis and recovery. */\n progressLogPath?: string\n}\n\n/**\n * Run the trace analyst.\n *\n * Throws:\n * - `TraceFileMissingError` if `source` is a path and doesn't exist.\n * - `AxAgentClarificationError` if the analyst asks for clarification.\n * - Provider errors (auth, rate limits) propagate from the AI service.\n */\nexport async function analyzeTraces(\n input: AnalyzeTracesInput,\n options: AnalyzeTracesOptions,\n): Promise<AnalyzeTracesResult> {\n if (!input.question || typeof input.question !== 'string') {\n throw new TypeError('analyzeTraces: input.question must be a non-empty string')\n }\n rejectRemovedOptions(options)\n\n const store: TraceAnalysisStore =\n typeof options.source === 'string'\n ? new OtlpFileTraceStore({ path: options.source })\n : options.source\n\n // Pre-warm file stores so missing inputs fail before the RLM starts.\n if (store instanceof OtlpFileTraceStore) {\n await store.ensureIndexed(options.signal ? { signal: options.signal } : undefined)\n }\n\n const tools: AxFunction[] = buildTraceAnalystTools({ store })\n const turns: AnalyzeTracesTurnSnapshot[] = []\n\n // Persist each turn as JSONL so interrupted analyst runs keep useful evidence.\n let progressFs: import('node:fs').WriteStream | undefined\n if (options.progressLogPath) {\n const { createWriteStream } = await import('node:fs')\n const { mkdir } = await import('node:fs/promises')\n const { dirname } = await import('node:path')\n await mkdir(dirname(options.progressLogPath), { recursive: true })\n progressFs = createWriteStream(options.progressLogPath, { flags: 'a' })\n }\n\n const actorTurnCallback = async (turn: AxAgentActorTurnCallbackArgs): Promise<void> => {\n const snap: AnalyzeTracesTurnSnapshot = {\n stage: turn.stage,\n turn: turn.turn,\n isError: turn.isError,\n code: turn.code,\n output: turn.output,\n thought: turn.thought,\n }\n turns.push(snap)\n if (progressFs) {\n try {\n progressFs.write(`${JSON.stringify({ ...snap, ts: Date.now() })}\\n`)\n } catch {\n // Progress logging must never fail the analyst.\n }\n }\n if (options.onTurn) await options.onTurn(snap)\n }\n\n const maxSubqueries = options.maxSubqueries ?? 4\n const maxTurns = options.maxTurns ?? 12\n const maxParallelSubqueries = options.maxParallelSubqueries ?? 2\n const maxRuntimeChars = options.maxRuntimeChars ?? 6000\n let completed: TraceAnalysisLoopResult<string>\n try {\n completed = await runTraceAnalysisLoop({\n id: 'TraceAnalyst',\n description:\n 'Analyzes OTLP-shaped JSONL traces using bounded discovery tools to identify systemic failure modes.',\n prompt: `${options.actorDescription ?? TRACE_ANALYST_ACTOR_DESCRIPTION}\n\nThe report must answer the user's question, and findings must be an array of concise evidence-backed strings.`,\n question: input.question,\n ai: options.ai,\n ...(options.model ? { model: options.model } : {}),\n tools,\n findingType: 'string',\n maxSubqueries,\n maxParallelSubqueries,\n maxTurns,\n maxRuntimeChars,\n ...(options.signal ? { signal: options.signal } : {}),\n onTurn: actorTurnCallback,\n })\n } finally {\n if (progressFs) {\n await new Promise<void>((resolve) => progressFs!.end(() => resolve()))\n }\n }\n\n return {\n answer: completed.report,\n findings: completed.findings,\n turns,\n turnCount: turns.length,\n usage: { actor: normalizeRecordArray(completed.usage), responder: [] },\n chatLog: { actor: normalizeRecordArray(completed.chatLog), responder: [] },\n actorPromptVersion: TRACE_ANALYST_ACTOR_DESCRIPTION_VERSION,\n }\n}\n\nfunction rejectRemovedOptions(options: AnalyzeTracesOptions): void {\n const supplied = options as unknown as Record<string, unknown>\n const migrations = [\n ['maxDepth', 'maxSubqueries'],\n ['maxParallelSubagents', 'maxParallelSubqueries'],\n ['subagentDescription', 'actorDescription'],\n ] as const\n for (const [removed, replacement] of migrations) {\n if (removed in supplied) {\n throw new TypeError(`analyzeTraces: '${removed}' is unsupported; use '${replacement}'`)\n }\n }\n}\n\nfunction normalizeRecordArray(value: unknown): Record<string, unknown>[] {\n if (!Array.isArray(value)) return []\n return value.map((item) =>\n item && typeof item === 'object' ? { ...(item as Record<string, unknown>) } : { value: item },\n )\n}\n","/**\n * Trace-analyst auto-execution hook.\n *\n * Wires `analyzeTraces` into a `TraceEmitter`'s `onRunComplete` so a\n * direct matrix run produces an analysis artifact without an out-of-band\n * step. Designed for the case where the consumer reports \"the analyst\n * never ran\" — the cause is almost always orchestration, not the analyst.\n *\n * Usage:\n *\n * const emitter = new TraceEmitter(store, {\n * onRunComplete: [traceAnalystOnRunComplete({ analyze: opts, save })],\n * })\n *\n * Hooks are best-effort by default — they never crash the underlying run.\n * The caller decides whether to gate the run on the analysis result via\n * the `gateOn` callback.\n */\n\nimport type { RunCompleteHook, RunCompleteHookContext } from '../trace/emitter'\nimport { type AnalyzeTracesOptions, type AnalyzeTracesResult, analyzeTraces } from './analyst'\n\nexport interface TraceAnalystHookOptions {\n /**\n * Options forwarded to `analyzeTraces`. The hook supplies the question\n * if you don't pass one — defaulting to a launch-grade prompt that asks\n * for failure modes, surprising findings, and a recommendation.\n */\n analyze: Omit<AnalyzeTracesOptions, 'source'> & { source?: AnalyzeTracesOptions['source'] }\n /**\n * Override the question. The default is intentionally generic:\n * \"Summarise what happened in this run, surface any failure modes,\n * surprising findings, or evidence the verdict is wrong.\"\n */\n question?: string\n /**\n * Persist the result. The hook calls this with the analysis output and\n * the run context. Common implementations write to a TraceAnalysisStore\n * or append to a per-run JSONL.\n */\n save?: (result: AnalyzeTracesResult, ctx: RunCompleteHookContext) => Promise<void>\n /**\n * Predicate gating execution per run. Default: every completed run.\n * Use to skip aborted runs, debug runs, or runs without LLM activity.\n */\n shouldRun?: (ctx: RunCompleteHookContext) => boolean\n /**\n * Optional gate: if set and returns false, the hook records the failure\n * as a log event on the run instead of staying quiet. The caller can\n * then trigger downstream alerts off `analyst_gate_failed` log events.\n */\n gateOn?: (result: AnalyzeTracesResult, ctx: RunCompleteHookContext) => boolean\n}\n\nconst DEFAULT_QUESTION =\n \"Summarise what happened in this run. Surface any failure modes, surprising findings, or evidence that the run's verdict is wrong.\"\n\nexport function traceAnalystOnRunComplete(opts: TraceAnalystHookOptions): RunCompleteHook {\n return async (ctx: RunCompleteHookContext) => {\n if (opts.shouldRun && !opts.shouldRun(ctx)) return\n const source = opts.analyze.source\n if (source === undefined) {\n // The analyst needs a source. If the caller didn't supply one we don't\n // run — but we do leave a breadcrumb so the absence is visible.\n await ctx.store.appendEvent({\n eventId: `analyst-skip-${ctx.runId}`,\n runId: ctx.runId,\n kind: 'log',\n timestamp: Date.now(),\n payload: { source: 'trace_analyst_hook', reason: 'no source configured' },\n })\n return\n }\n const result = await analyzeTraces({ question: opts.question ?? DEFAULT_QUESTION }, {\n ...opts.analyze,\n source,\n } as AnalyzeTracesOptions)\n if (opts.save) await opts.save(result, ctx)\n if (opts.gateOn && !opts.gateOn(result, ctx)) {\n await ctx.store.appendEvent({\n eventId: `analyst-gate-${ctx.runId}`,\n runId: ctx.runId,\n kind: 'log',\n timestamp: Date.now(),\n payload: {\n source: 'trace_analyst_hook',\n reason: 'analyst_gate_failed',\n findings: result.findings,\n },\n })\n }\n }\n}\n","export interface TraceInsightTask {\n id: string\n name: string\n prompt?: string\n difficulty?: string\n tags?: string[]\n outcome?: string\n score?: number\n gaps?: string[]\n}\n\nexport interface TraceInsightSuite {\n name: string\n collectionId?: string\n tasks: TraceInsightTask[]\n}\n\nexport interface TraceInsightFinding {\n kind: string\n severity?: string\n taskIds: string[]\n evidence?: string\n proposedFixClass?: string\n}\n\nexport interface TraceInsightQuestion {\n id: string\n question: string\n why: string\n}\n\nexport interface TraceInsightPanelRole {\n id: string\n name: string\n responsibility: string\n}\n\nexport interface TraceInsightPromptInput {\n suite: TraceInsightSuite\n findings?: TraceInsightFinding[]\n agent?: Record<string, unknown>\n totals?: Record<string, unknown>\n maxRepresentativeTraces?: number\n}\n\nexport interface TraceInsightContext {\n suite: TraceInsightSuite\n scope: string\n keywords: string[]\n questions: TraceInsightQuestion[]\n panel: TraceInsightPanelRole[]\n findings: TraceInsightFinding[]\n agent: Record<string, unknown> | null\n totals: Record<string, unknown> | null\n}\n\nexport interface TraceInsightQualityGate {\n id: string\n label: string\n passed: boolean\n severity: 'critical' | 'high' | 'medium' | 'low'\n detail: string\n}\n\nexport interface TraceInsightReadiness {\n score: number\n grade: 'external-ready' | 'internal-review' | 'raw-analysis'\n gates: TraceInsightQualityGate[]\n}\n\nconst DOMAIN_STOP_WORDS = new Set([\n 'and',\n 'advanced',\n 'app',\n 'build',\n 'create',\n 'easy',\n 'expert',\n 'extreme',\n 'for',\n 'from',\n 'hard',\n 'implementation',\n 'integrate',\n 'medium',\n 'project',\n 'task',\n 'the',\n 'this',\n 'with',\n 'workflow',\n])\n\nexport function tokenizeDomainWords(value: string): string[] {\n return [...value.matchAll(/[A-Za-z][A-Za-z0-9.+#-]{2,}/g)]\n .map((match) => match[0].toLowerCase())\n .filter((word) => !DOMAIN_STOP_WORDS.has(word))\n}\n\nexport function inferDomainKeywords(suite: TraceInsightSuite): string[] {\n const suiteWords = new Set(tokenizeDomainWords(`${suite.name} ${suite.collectionId ?? ''}`))\n const source = [\n suite.name,\n suite.collectionId ?? '',\n ...suite.tasks.flatMap((task) => [\n task.id,\n task.name,\n task.prompt ?? '',\n task.difficulty ?? '',\n ...(task.tags ?? []),\n ...(task.gaps ?? []),\n ]),\n ].join(' ')\n const counts = new Map<string, number>()\n for (const word of tokenizeDomainWords(source)) counts.set(word, (counts.get(word) ?? 0) + 1)\n return [...counts.entries()]\n .filter(([word, count]) => count >= 2 || suiteWords.has(word))\n .sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0]))\n .map(([word]) => word)\n .slice(0, 18)\n}\n\nexport function domainEvidencePattern(keywords: string[]): RegExp {\n const escaped = keywords\n .filter((keyword) => keyword.length >= 3)\n .map((keyword) => keyword.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&'))\n return escaped.length > 0\n ? new RegExp(`(?<![A-Za-z0-9])(?:${escaped.join('|')})(?![A-Za-z0-9])`, 'i')\n : /(?<![A-Za-z0-9])(?:sdk|api|css|dns|xml|provider|client|service|integration|webhook|transaction|auth|oauth|graphql|rest)(?![A-Za-z0-9])/i\n}\n\nexport function describeTraceInsightScope(suite: TraceInsightSuite): string {\n const taskLabel =\n suite.tasks.length === 1\n ? '1 implementation task'\n : `${suite.tasks.length} implementation tasks`\n const tags = new Map<string, number>()\n for (const task of suite.tasks) {\n for (const tag of task.tags ?? []) tags.set(tag, (tags.get(tag) ?? 0) + 1)\n }\n const topTags = [...tags.entries()]\n .sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0]))\n .slice(0, 8)\n .map(([tag]) => tag)\n if (topTags.length > 0) return `${taskLabel} across ${topTags.join(', ')}.`\n const difficulties = [\n ...new Set(\n suite.tasks.map((task) => task.difficulty).filter((value): value is string => Boolean(value)),\n ),\n ].join(', ')\n return `${taskLabel} across ${difficulties || 'the selected benchmark scope'}.`\n}\n\nexport function planTraceInsightQuestions(input: TraceInsightPromptInput): TraceInsightQuestion[] {\n const hasFailures = input.suite.tasks.some((task) => task.outcome && task.outcome !== 'satisfied')\n const hasMultipleShots = input.suite.tasks.some((task) =>\n (task.gaps ?? []).some((gap) => /shot|review|retry|continue/i.test(gap)),\n )\n const questions: TraceInsightQuestion[] = [\n {\n id: 'execution-path',\n question: 'What did the worker actually do before the first meaningful implementation edit?',\n why: 'Separates grounded execution from polished but shallow output.',\n },\n {\n id: 'research-grounding',\n question:\n 'Did the worker inspect docs, source, examples, or package references before committing to an implementation path?',\n why: 'Identifies whether failures came from weak retrieval, weak examples, or premature coding.',\n },\n {\n id: 'domain-proof',\n question:\n 'Which tasks produced executable domain proof versus UI copy, placeholders, or inferred behavior?',\n why: 'Keeps product-quality claims tied to concrete evidence.',\n },\n {\n id: 'root-cause',\n question:\n 'For each major failure cluster, is the likely root cause prompt/scaffold, docs/examples, SDK/API ergonomics, evaluator, runtime, or model behavior?',\n why: 'Turns trace observations into actionable ownership.',\n },\n {\n id: 'evidence-quality',\n question:\n 'Which external-facing claims are directly supported by trace ids, span ids, verifier findings, reviewer notes, or generated code?',\n why: 'Prevents unsupported customer-report conclusions.',\n },\n ]\n if (hasMultipleShots) {\n questions.push({\n id: 'reviewer-lift',\n question: 'Where did reviewer feedback improve score, stall, or regress across shots?',\n why: 'Shows whether the driver loop is learning or merely repeating work.',\n })\n }\n if (hasFailures) {\n questions.push({\n id: 'optimization-targets',\n question:\n 'Which prompt, evaluator, scaffold, or workflow changes should feed the next GEPA/autoresearch optimization run?',\n why: 'Connects benchmark evidence to the optimization loop.',\n })\n }\n return questions\n}\n\nexport function buildTraceInsightContext(input: TraceInsightPromptInput): TraceInsightContext {\n return {\n suite: input.suite,\n scope: describeTraceInsightScope(input.suite),\n keywords: inferDomainKeywords(input.suite),\n questions: planTraceInsightQuestions(input),\n panel: defaultTraceInsightPanel(),\n findings: input.findings ?? [],\n agent: input.agent ?? null,\n totals: input.totals ?? null,\n }\n}\n\nexport function scoreTraceInsightReadiness(context: TraceInsightContext): TraceInsightReadiness {\n const failedTasks = context.suite.tasks.filter(\n (task) => task.outcome && task.outcome !== 'satisfied',\n )\n const findingTaskIds = new Set(context.findings.flatMap((finding) => finding.taskIds))\n const failedTasksWithFindings = failedTasks.filter((task) => findingTaskIds.has(task.id))\n const tasksWithGaps = context.suite.tasks.filter((task) => (task.gaps ?? []).length > 0)\n const gates: TraceInsightQualityGate[] = [\n {\n id: 'domain-context',\n label: 'Domain context inferred',\n passed: context.keywords.length > 0,\n severity: 'high',\n detail:\n context.keywords.length > 0\n ? `${context.keywords.length} domain terms inferred: ${context.keywords.slice(0, 8).join(', ')}`\n : 'No domain terms were inferred from suite, tasks, prompts, tags, or gaps.',\n },\n {\n id: 'panel-coverage',\n label: 'Analyst panel planned',\n passed: context.panel.length >= 4 && context.questions.length >= 5,\n severity: 'high',\n detail: `${context.panel.length} panel roles and ${context.questions.length} investigation questions planned.`,\n },\n {\n id: 'failure-coverage',\n label: 'Failures mapped to findings',\n passed:\n failedTasks.length === 0 || failedTasksWithFindings.length / failedTasks.length >= 0.5,\n severity: 'critical',\n detail:\n failedTasks.length === 0\n ? 'No failed tasks in suite.'\n : `${failedTasksWithFindings.length}/${failedTasks.length} failed tasks appear in finding clusters.`,\n },\n {\n id: 'gap-evidence',\n label: 'Task gaps captured',\n passed: failedTasks.length === 0 || tasksWithGaps.length / failedTasks.length >= 0.5,\n severity: 'medium',\n detail: `${tasksWithGaps.length} tasks include explicit evaluator or analyst gaps.`,\n },\n ]\n const penalty = gates.reduce((sum, gate) => {\n if (gate.passed) return sum\n if (gate.severity === 'critical') return sum + 35\n if (gate.severity === 'high') return sum + 20\n if (gate.severity === 'medium') return sum + 10\n return sum + 5\n }, 0)\n const score = Math.max(0, Math.min(1, 1 - penalty / 100))\n return {\n score,\n grade: score >= 0.9 ? 'external-ready' : score >= 0.7 ? 'internal-review' : 'raw-analysis',\n gates,\n }\n}\n\nexport function defaultTraceInsightPanel(): TraceInsightPanelRole[] {\n return [\n {\n id: 'trace-forensics',\n name: 'Trace Forensics',\n responsibility:\n 'Reconstruct what the worker did in order, including research, edits, reviewer interventions, verifier feedback, and stop reason.',\n },\n {\n id: 'root-cause',\n name: 'Root Cause',\n responsibility:\n 'Map failures to prompt/scaffold, docs/examples, SDK/API/product ergonomics, evaluator, runtime, or model behavior.',\n },\n {\n id: 'optimization',\n name: 'Optimization',\n responsibility:\n 'Identify prompt, reviewer, evaluator, scaffold, and GEPA/autoresearch changes that should be tested next.',\n },\n {\n id: 'external-evidence',\n name: 'External Evidence',\n responsibility:\n 'Separate customer-safe claims from internal harness findings and reject conclusions without task, trace, span, code, reviewer, or verifier evidence.',\n },\n ]\n}\n\nexport function buildTraceInsightPrompt(input: TraceInsightPromptInput): string {\n const context = buildTraceInsightContext(input)\n const maxRepresentativeTraces = input.maxRepresentativeTraces ?? 6\n return `Analyze this benchmark run and produce evidence-backed trace intelligence.\n\nAudience:\n- internal AI/product leadership\n- possible customer-facing report for ${input.suite.name}\n\nInvestigation plan:\n${context.questions.map((item, index) => `${index + 1}. ${item.question} (${item.why})`).join('\\n')}\n\nAnalyst panel:\n${context.panel.map((role) => `- ${role.name}: ${role.responsibility}`).join('\\n')}\n\nIf the task branches are independent, use subagents for the panel roles above and aggregate their findings. Do not run a panel role unless its answer will change the final report.\n\nRequired output:\n1. Executive verdict: what this run proves and does not prove.\n2. The investigation questions you answered and the evidence used.\n3. Failure taxonomy: agent prompting, evaluator/harness, docs/examples, SDK/API/product integration, infra.\n4. Evidence-backed examples with trace ids/task ids and concrete verifier findings.\n5. Highest-ROI fixes for the benchmark harness, prompt/GEPA optimization, and customer-facing product/docs surface.\n6. What is safe for an external report versus what must stay internal.\n7. One rerun plan that would validate lift after optimization.\n\nBudget:\n- Inspect the dataset overview, the failure summary, and at most ${maxRepresentativeTraces} representative traces.\n- Prefer traces named in the failure summary over broad exploration.\n- Do not do exhaustive trace sweeps.\n- Return the final report as soon as the taxonomy and examples are supported.\n\nRun summary:\n${JSON.stringify(\n {\n suite: input.suite.name,\n scope: context.scope,\n inferredKeywords: context.keywords,\n agent: context.agent,\n totals: context.totals,\n findings: context.findings.map((finding) => ({\n kind: finding.kind,\n severity: finding.severity,\n taskCount: finding.taskIds.length,\n proposedFixClass: finding.proposedFixClass,\n })),\n failures: input.suite.tasks\n .filter((task) => task.outcome && task.outcome !== 'satisfied')\n .map((task) => ({\n task: task.id,\n difficulty: task.difficulty,\n outcome: task.outcome,\n score: task.score,\n gaps: task.gaps ?? [],\n })),\n },\n null,\n 2,\n)}\n\nUse the trace tools. Do not invent facts. Cite task ids. Separate customer-facing claims from internal harness/model findings.`\n}\n","/** Canonical flattened OTLP span shape shared by trace producers and readers. */\n\nimport type { SpanStatus } from './schema'\n\nexport type OtlpStatusCode = 'STATUS_CODE_OK' | 'STATUS_CODE_ERROR' | 'STATUS_CODE_UNSET'\n\nexport interface OtlpFlatLine {\n trace_id: string\n span_id: string\n parent_span_id: string | null\n name: string\n kind: string\n start_time: string\n end_time: string\n status: {\n code: OtlpStatusCode\n message?: string\n }\n resource: { attributes: Record<string, unknown> }\n attributes: Record<string, unknown>\n events?: Array<{ name: string; timeUnixNano?: string; attributes?: Record<string, unknown> }>\n}\n\nexport interface CreateOtlpFlatLineInput {\n traceId: string\n spanId: string\n parentSpanId: string | null\n name: string\n kind: string\n startTime: string\n endTime: string\n statusCode: OtlpStatusCode\n statusMessage?: string\n resource: OtlpFlatLine['resource']\n attributes: Record<string, unknown>\n events?: OtlpFlatLine['events']\n}\n\nexport function createOtlpFlatLine(input: CreateOtlpFlatLineInput): OtlpFlatLine {\n return {\n trace_id: input.traceId,\n span_id: input.spanId,\n parent_span_id: input.parentSpanId,\n name: input.name,\n kind: input.kind,\n start_time: input.startTime,\n end_time: input.endTime,\n status: {\n code: input.statusCode,\n ...(input.statusMessage !== undefined ? { message: input.statusMessage } : {}),\n },\n resource: input.resource,\n attributes: input.attributes,\n ...(input.events && input.events.length > 0 ? { events: input.events } : {}),\n }\n}\n\n/** Map the canonical trace status while letting each caller choose its legacy default. */\nexport function spanStatusToOtlp(\n status: SpanStatus | undefined,\n error: string | undefined,\n defaultCode: OtlpStatusCode,\n): OtlpStatusCode {\n if (status === 'error' || error) return 'STATUS_CODE_ERROR'\n if (status === 'ok') return 'STATUS_CODE_OK'\n return defaultCode\n}\n\n/** Convert epoch milliseconds, returning `undefined` for invalid or out-of-range values. */\nexport function epochMillisToIso(value: number): string | undefined {\n if (!Number.isFinite(value)) return undefined\n try {\n return new Date(value).toISOString()\n } catch {\n return undefined\n }\n}\n","/**\n * `flattenOtlpExportToNdjson` — flatten an `OtlpExport` (the shape\n * `exportRunAsOtlp` produces) into the per-line JSON the analyst's\n * `OtlpFileTraceStore` index reads. Replaces three per-consumer OTLP\n * flatteners with one canonical projection.\n *\n * Pure function, no I/O — the caller does `.map(JSON.stringify).join('\\n')`\n * and writes the file (consumers want control over rotation + naming).\n */\n\nimport type { OtlpExport, OtlpSpan } from '../trace/otel'\nimport {\n LLM_INPUT_TOKENS,\n LLM_MODEL_NAME,\n LLM_OUTPUT_TOKENS,\n OPENINFERENCE_SPAN_KIND,\n TOOL_NAME,\n} from '../trace/otlp-attributes'\nimport { createOtlpFlatLine, type OtlpFlatLine } from '../trace/otlp-flat'\n\nexport type { OtlpFlatLine } from '../trace/otlp-flat'\n\nexport interface FlattenOtlpOptions {\n /** `'openinference'` (default) maps source per-span attributes into the\n * canonical OpenInference vocabulary the analyst readers consume. `'none'`\n * passes attributes through untouched. */\n attributeVocabulary?: 'openinference' | 'none'\n /** Override the numeric-kind → otlp-string mapping. */\n kindMap?: Partial<Record<number, string>>\n}\n\nconst DEFAULT_KIND_MAP: Record<number, string> = {\n 0: 'SPAN_KIND_UNSPECIFIED',\n 1: 'SPAN_KIND_INTERNAL',\n 2: 'SPAN_KIND_SERVER',\n 3: 'SPAN_KIND_CLIENT',\n 4: 'SPAN_KIND_PRODUCER',\n 5: 'SPAN_KIND_CONSUMER',\n}\n\nconst STATUS_MAP: Record<number, OtlpFlatLine['status']['code']> = {\n 0: 'STATUS_CODE_UNSET',\n 1: 'STATUS_CODE_OK',\n 2: 'STATUS_CODE_ERROR',\n}\n\n/** Unwrap an OTLP attribute-value union to a scalar. */\nfunction attrValue(v: OtlpSpan['attributes'][number]['value']): string | number | boolean {\n if (v.stringValue !== undefined) return v.stringValue\n if (v.intValue !== undefined) return Number(v.intValue)\n if (v.doubleValue !== undefined) return v.doubleValue\n if (v.boolValue !== undefined) return v.boolValue\n return ''\n}\n\nfunction attrsToRecord(attrs: OtlpSpan['attributes']): Record<string, string | number | boolean> {\n const out: Record<string, string | number | boolean> = {}\n for (const a of attrs) out[a.key] = attrValue(a.value)\n return out\n}\n\nfunction nanoToIso(nano: string): string {\n const ms = Number(nano) / 1_000_000\n return Number.isFinite(ms) ? new Date(ms).toISOString() : new Date(0).toISOString()\n}\n\n/** Mirror selected attributes into the OpenInference vocabulary in place. */\nfunction applyOpenInference(attrs: Record<string, string | number | boolean>): void {\n if ('llm.model' in attrs && !(LLM_MODEL_NAME in attrs)) {\n attrs[LLM_MODEL_NAME] = attrs['llm.model']!\n }\n if ('llm.input_tokens' in attrs && !(LLM_INPUT_TOKENS in attrs)) {\n attrs[LLM_INPUT_TOKENS] = attrs['llm.input_tokens']!\n }\n if ('inference.llm.input_tokens' in attrs && !(LLM_INPUT_TOKENS in attrs)) {\n attrs[LLM_INPUT_TOKENS] = attrs['inference.llm.input_tokens']!\n }\n if ('llm.output_tokens' in attrs && !(LLM_OUTPUT_TOKENS in attrs)) {\n attrs[LLM_OUTPUT_TOKENS] = attrs['llm.output_tokens']!\n }\n if ('inference.llm.output_tokens' in attrs && !(LLM_OUTPUT_TOKENS in attrs)) {\n attrs[LLM_OUTPUT_TOKENS] = attrs['inference.llm.output_tokens']!\n }\n if (TOOL_NAME in attrs && !('inference.tool.name' in attrs)) {\n attrs['inference.tool.name'] = attrs[TOOL_NAME]!\n }\n if ('span.kind' in attrs && !(OPENINFERENCE_SPAN_KIND in attrs)) {\n attrs[OPENINFERENCE_SPAN_KIND] = String(attrs['span.kind']).toUpperCase()\n }\n}\n\nexport function flattenOtlpExportToNdjson(\n otlpExport: OtlpExport,\n opts: FlattenOtlpOptions = {},\n): OtlpFlatLine[] {\n const vocab = opts.attributeVocabulary ?? 'openinference'\n const kindMap = { ...DEFAULT_KIND_MAP, ...opts.kindMap }\n const lines: OtlpFlatLine[] = []\n\n for (const rs of otlpExport.resourceSpans ?? []) {\n const resource = { attributes: attrsToRecord(rs.resource?.attributes ?? []) }\n for (const scope of rs.scopeSpans ?? []) {\n for (const span of scope.spans ?? []) {\n const attributes = attrsToRecord(span.attributes ?? [])\n if (vocab === 'openinference') applyOpenInference(attributes)\n const line = createOtlpFlatLine({\n traceId: span.traceId,\n spanId: span.spanId,\n parentSpanId: span.parentSpanId ?? null,\n name: span.name,\n kind: kindMap[span.kind] ?? 'SPAN_KIND_UNSPECIFIED',\n startTime: nanoToIso(span.startTimeUnixNano),\n endTime: nanoToIso(span.endTimeUnixNano),\n statusCode: STATUS_MAP[span.status?.code ?? 0] ?? 'STATUS_CODE_UNSET',\n statusMessage: span.status?.message,\n resource,\n attributes,\n events: span.events?.map((e) => ({\n name: e.name,\n timeUnixNano: e.timeUnixNano,\n ...(e.attributes ? { attributes: attrsToRecord(e.attributes) } : {}),\n })),\n })\n lines.push(line)\n }\n }\n }\n\n return lines\n}\n","/**\n * `otlpToRunRecords` — fold an OTLP traces.jsonl (one OTLP span per line;\n * the form AppWorld / HALO emit via their OpenInference OTLP exporter, the\n * same shape `flattenOtlpExportToNdjson` produces) into validated\n * `RunRecord[]` — one record per `trace_id` by default, or per caller-defined\n * logical run when one task is fragmented across multiple OTLP traces.\n *\n * This is the offline ingestion primitive the AppWorld proposer bench and the\n * hosted Intelligence product both stand on: traces in, paper-grade rows\n * out, ready for `compareOptimizationMethods` / `analyzeRuns` / the promotion gate.\n *\n * Aggregation per trace:\n * - tokenUsage: reconcile input, output, cache-read, and cache-write across\n * nested model-call wrappers without double-counting parent aggregates.\n * - costUsd: reconcile complete observed model-call cost when present; else priced via\n * `opts.priceUsdPerToken` from the aggregated tokens; else `null` with a\n * loud `raw.cost_unpriced = 1` marker.\n * - task failure class and detail: read from process-root\n * `tangle.task.failure_*` attributes; malformed or conflicting values throw.\n * - terminalFailureReason: the failed root's normalized status message,\n * when one unambiguous root supplies terminal failure evidence.\n * - terminalOutcome: reduced from root-span status only. Child tool errors\n * remain visible in `error_span_count` and `execution_error_count` without\n * changing the run outcome. Root, guardrail, evaluator, propagated, and\n * unknown errors retain separate counters.\n * - model: the dominant LLM model in the trace (snapshot-padded to satisfy\n * `validateRunRecord` when the trace's model is a bare alias).\n * - outcome score: `opts.scoreForTrace` (AppWorld `world.evaluate()` →\n * TGC/SGC) when supplied. Traces without an external task-quality signal\n * remain unlabeled; execution errors never become a task score.\n * - prompt / completion: carried into `raw` as token-count signals and,\n * when the first/last LLM span exposes `input.value` / `output.value`,\n * the verbatim text is preserved on the optional `promptText` /\n * `completionText` of the returned `OtlpTraceRunRecord`.\n *\n * Fail-loud: an OTLP file with zero valid spans throws. A trace with no\n * spans is impossible (a trace exists only because a span referenced it).\n * `validateRunRecord` runs on every row — a malformed projection throws\n * rather than silently producing a half-record.\n */\n\nimport {\n type RunCostProvenance,\n type RunRecord,\n type RunSplitTag,\n type RunTerminalOutcome,\n type RunTokenUsage,\n validateRunRecord,\n} from '../run-record'\nimport { summarizeTraceErrors, type TraceErrorRole } from '../trace/error-classification'\nimport {\n type MeasurementCoverage,\n recordAggregateMeasurements,\n summarizeExecutionMeasurements,\n} from '../trace/execution-measurements'\nimport {\n classifyOtlpSpanRole,\n isOtlpModelCall,\n LLM_MODEL_ATTR_KEYS,\n} from '../trace/otlp-attributes'\nimport { readTaskFailureLabels } from '../trace/task-failure-attributes'\nimport {\n compareSpanTime,\n firstStringAttr,\n type ProjectedOtlpSpan,\n projectOtlpFlatLine,\n spanEpochMillis,\n} from './otlp-span'\n\nexport interface OtlpToRunRecordsOptions {\n /** Logical experiment grouping for every produced record. */\n experimentId: string\n /** Candidate (variant) id — the surface these traces exercised. The\n * bench passes the proposer label here so `compareOptimizationMethods` can pair rows. */\n candidateId: string\n /** Split assignment for every produced record. Default `'holdout'` —\n * ingested traces are evidence, not the optimizer's training pool. */\n splitTag?: RunSplitTag\n /** Git SHA the traces were produced from. Default `'unknown'`. */\n commitSha?: string\n /** sha256 of the effective prompt surface. Default `'unknown'`. */\n promptHash?: string\n /** sha256 of the effective config. Default `'unknown'`. */\n configHash?: string\n /** RNG seed recorded on every row. Default 0. */\n seed?: number\n /**\n * Fallback model snapshot when the trace exposes no LLM model attribute\n * OR exposes a bare alias `validateRunRecord` would reject. The trace's\n * own model wins when it already carries a snapshot. Default\n * `'unknown@otlp'` (opaque-snapshot form the validator accepts).\n */\n fallbackModel?: string\n /**\n * USD per total token (input+output) used to price a trace when no\n * per-span cost attribute is present. When unset, an unpriced trace\n * records `costUsd: null` and `raw.cost_unpriced = 1`.\n */\n priceUsdPerToken?: number\n /**\n * Map each OTLP `trace_id` to the logical run it belongs to. Use this when a\n * provider emits several traces for one task attempt. All mapped traces are\n * aggregated into one record; duplicate span ids remain isolated by their\n * source trace. The callback must return a non-empty id for every trace.\n *\n * When omitted, every `trace_id` remains an independent run.\n */\n logicalRunIdForTrace?: (traceId: string) => string\n /**\n * Score for a produced run's outcome (AppWorld `world.evaluate()` →\n * TGC/SGC, or\n * any [0,1] task-success signal). Keyed by the logical run id when\n * `logicalRunIdForTrace` is supplied, otherwise by `trace_id`. When the map\n * has no entry or the function returns undefined, the record remains\n * unlabeled.\n */\n scoreForTrace?: (runId: string, span: TraceAggregate) => number | undefined\n /**\n * Per-record judge metadata when an external judge produced the score.\n * Keyed by the logical run id when supplied, otherwise by `trace_id`.\n */\n judgeMetadataForTrace?: (runId: string) => RunRecord['judgeMetadata'] | undefined\n}\n\n/** A `RunRecord` plus the verbatim prompt/completion text when the trace's\n * LLM spans exposed it. The text is NOT on the validated `RunRecord`\n * (`outcome.raw` is numeric-only) but consumers ingesting full traces want\n * it — so it rides alongside. */\nexport interface OtlpTraceRunRecord {\n record: RunRecord\n /** Verbatim first-LLM-span `input.value`, when present. */\n promptText?: string\n /** Verbatim last-LLM-span `output.value`, when present. */\n completionText?: string\n}\n\n/** Per-trace rollup the score callback can inspect. */\nexport interface TraceAggregate {\n traceId: string\n /** Number of source OTLP traces folded into this run. */\n sourceTraceCount: number\n /** Source OTLP trace ids folded into this run, sorted for deterministic audit output. */\n sourceTraceIds: readonly string[]\n spanCount: number\n llmSpanCount: number\n toolSpanCount: number\n agentSpanCount: number\n errorSpanCount: number\n executionErrorCount: number\n processErrorCount: number\n guardrailErrorCount: number\n judgeErrorCount: number\n propagatedErrorCount: number\n unclassifiedErrorCount: number\n tokenUsage: RunTokenUsage\n /** First error span's normalized status message, if any. */\n firstErrorMessage?: string\n model: string\n startTime: string\n endTime: string\n wallMs: number\n /** Root-span terminal result. Child span errors do not change this value. */\n terminalOutcome: RunTerminalOutcome\n}\n\ninterface AggregatedTrace extends TraceAggregate {\n callSpanIds: string[]\n costMeasurement: MeasurementCoverage\n aggregateMeasurement?: ReturnType<typeof summarizeExecutionMeasurements>['aggregate']\n terminalFailureMessage?: string\n}\n\n/**\n * Parse + aggregate an OTLP traces.jsonl string into validated\n * `RunRecord[]` (one per trace). Use {@link otlpToTraceRunRecords} when you\n * also want the verbatim prompt/completion text alongside each record.\n */\nexport function otlpToRunRecords(otlpJsonl: string, opts: OtlpToRunRecordsOptions): RunRecord[] {\n return otlpToTraceRunRecords(otlpJsonl, opts).map((r) => r.record)\n}\n\n/**\n * Aggregate already-parsed OTLP flat rows without serializing them back to\n * JSONL. This is the in-memory counterpart to {@link otlpToRunRecords}; both\n * paths share projection, reconciliation, validation, and ordering.\n */\nexport function otlpRowsToRunRecords(\n rows: Iterable<object>,\n opts: OtlpToRunRecordsOptions,\n): RunRecord[] {\n return otlpRowsToTraceRunRecords(rows, opts).map((row) => row.record)\n}\n\n/** As {@link otlpToRunRecords} but returns the prompt/completion text too. */\nexport function otlpToTraceRunRecords(\n otlpJsonl: string,\n opts: OtlpToRunRecordsOptions,\n): OtlpTraceRunRecord[] {\n return traceRunRecordsFromSpans(\n groupSpansByLogicalRun(groupJsonlSpansByTrace(otlpJsonl), opts.logicalRunIdForTrace),\n opts,\n )\n}\n\n/** Parsed-row counterpart to {@link otlpToTraceRunRecords}. */\nexport function otlpRowsToTraceRunRecords(\n rows: Iterable<object>,\n opts: OtlpToRunRecordsOptions,\n): OtlpTraceRunRecord[] {\n return traceRunRecordsFromSpans(\n groupSpansByLogicalRun(groupRowsByTrace(rows), opts.logicalRunIdForTrace),\n opts,\n )\n}\n\nfunction traceRunRecordsFromSpans(\n byTrace: Map<string, ProjectedOtlpSpan[]>,\n opts: OtlpToRunRecordsOptions,\n): OtlpTraceRunRecord[] {\n const splitTag = opts.splitTag ?? 'holdout'\n const commitSha = opts.commitSha ?? 'unknown'\n const promptHash = opts.promptHash ?? 'unknown'\n const configHash = opts.configHash ?? 'unknown'\n const seed = opts.seed ?? 0\n const fallbackModel = opts.fallbackModel ?? 'unknown@otlp'\n\n if (byTrace.size === 0) {\n throw new Error(\n 'otlpToRunRecords: OTLP input produced zero valid spans — every row was empty, malformed, or missing trace_id/span_id',\n )\n }\n\n // Stable trace order (insertion order of first appearance is preserved by\n // Map; sort by trace_id for determinism across producers).\n const traceIds = [...byTrace.keys()].sort()\n const out: OtlpTraceRunRecord[] = []\n\n for (const traceId of traceIds) {\n const spans = byTrace.get(traceId)!\n const agg = aggregateTrace(traceId, spans, fallbackModel)\n\n const score = resolveScore(opts, traceId, agg)\n const { costUsd, costProvenance } = resolveCost(opts, agg)\n\n const raw: Record<string, number> = {\n source_trace_count: agg.sourceTraceCount,\n span_count: agg.spanCount,\n llm_span_count: agg.llmSpanCount,\n tool_span_count: agg.toolSpanCount,\n agent_span_count: agg.agentSpanCount,\n error_span_count: agg.errorSpanCount,\n execution_error_count: agg.executionErrorCount,\n process_error_count: agg.processErrorCount,\n guardrail_error_count: agg.guardrailErrorCount,\n judge_error_count: agg.judgeErrorCount,\n propagated_error_count: agg.propagatedErrorCount,\n unclassified_error_count: agg.unclassifiedErrorCount,\n prompt_tokens: agg.tokenUsage.input,\n completion_tokens: agg.tokenUsage.output,\n }\n if (agg.tokenUsage.reasoning !== undefined) raw.reasoning_tokens = agg.tokenUsage.reasoning\n if (agg.tokenUsage.cached !== undefined) raw.cached_tokens = agg.tokenUsage.cached\n if (agg.tokenUsage.cacheWrite !== undefined) {\n raw.cache_write_tokens = agg.tokenUsage.cacheWrite\n }\n if (agg.costMeasurement.value !== undefined && !agg.costMeasurement.complete) {\n raw.partial_observed_cost_usd = agg.costMeasurement.value\n }\n recordAggregateMeasurements(raw, agg.aggregateMeasurement)\n if (costProvenance.kind === 'uncaptured') raw.cost_unpriced = 1\n\n const outcome: RunRecord['outcome'] = { raw }\n if (score !== undefined) {\n if (splitTag === 'holdout') outcome.holdoutScore = score\n else outcome.searchScore = score\n }\n\n const { promptText, completionText } = extractPromptCompletion(spans, agg.callSpanIds)\n const judgeMetadata = opts.judgeMetadataForTrace?.(traceId)\n const taskFailure = readTaskFailureLabels(\n spans.filter((span) => span.parent_span_id === null && isTerminalRootCandidate(span)),\n `otlpToRunRecords: run '${traceId}'`,\n )\n\n const record = validateRunRecord({\n runId: `otlp:${opts.experimentId}:${opts.candidateId}:${traceId}`,\n experimentId: opts.experimentId,\n candidateId: opts.candidateId,\n seed,\n model: ensureSnapshot(agg.model, fallbackModel),\n promptHash,\n configHash,\n commitSha,\n wallMs: agg.wallMs,\n costUsd,\n costProvenance,\n tokenUsage: agg.tokenUsage,\n terminalOutcome: agg.terminalOutcome,\n ...(agg.terminalFailureMessage ? { terminalFailureReason: agg.terminalFailureMessage } : {}),\n ...(judgeMetadata ? { judgeMetadata } : {}),\n outcome,\n ...taskFailure,\n splitTag,\n scenarioId: traceId,\n })\n\n out.push({\n record,\n ...(promptText !== undefined ? { promptText } : {}),\n ...(completionText !== undefined ? { completionText } : {}),\n })\n }\n\n return out\n}\n\n// ── Internals ──────────────────────────────────────────────────────────\n\nfunction* yieldJsonlRows(otlpJsonl: string): Iterable<Record<string, unknown>> {\n for (const line of otlpJsonl.split('\\n')) {\n const trimmed = line.trim()\n if (trimmed.length === 0) continue\n let parsed: unknown\n try {\n parsed = JSON.parse(trimmed)\n } catch {\n // Tolerate a stray malformed line — mirrors the store's index, which\n // skips unparseable lines rather than nuking a whole dataset. A file\n // that is ENTIRELY malformed still throws (zero valid spans).\n continue\n }\n if (parsed && typeof parsed === 'object') yield parsed as Record<string, unknown>\n }\n}\n\nfunction groupJsonlSpansByTrace(otlpJsonl: string): Map<string, ProjectedOtlpSpan[]> {\n return groupRowsByTrace(yieldJsonlRows(otlpJsonl))\n}\n\nfunction groupRowsByTrace(rows: Iterable<object>): Map<string, ProjectedOtlpSpan[]> {\n const byTrace = new Map<string, ProjectedOtlpSpan[]>()\n for (const row of rows) {\n if (!row || typeof row !== 'object') continue\n const span = projectOtlpFlatLine(row as Record<string, unknown>)\n if (!span) continue\n const arr = byTrace.get(span.trace_id)\n if (arr) arr.push(span)\n else byTrace.set(span.trace_id, [span])\n }\n return byTrace\n}\n\nfunction groupSpansByLogicalRun(\n byTrace: Map<string, ProjectedOtlpSpan[]>,\n logicalRunIdForTrace: OtlpToRunRecordsOptions['logicalRunIdForTrace'],\n): Map<string, ProjectedOtlpSpan[]> {\n if (!logicalRunIdForTrace) return byTrace\n\n const byRun = new Map<string, ProjectedOtlpSpan[]>()\n for (const [traceId, spans] of byTrace) {\n const suppliedRunId = logicalRunIdForTrace(traceId)\n if (typeof suppliedRunId !== 'string' || suppliedRunId.trim().length === 0) {\n throw new Error(\n `otlpToRunRecords: logicalRunIdForTrace('${traceId}') returned an empty run id`,\n )\n }\n const runId = suppliedRunId.trim()\n const target = byRun.get(runId) ?? []\n for (const span of spans) {\n target.push({\n ...span,\n span_id: qualifySpanId(traceId, span.span_id),\n parent_span_id: span.parent_span_id ? qualifySpanId(traceId, span.parent_span_id) : null,\n })\n }\n byRun.set(runId, target)\n }\n return byRun\n}\n\nfunction qualifySpanId(traceId: string, spanId: string): string {\n const prefix = `${traceId}:`\n return spanId.startsWith(prefix) ? spanId : `${prefix}${spanId}`\n}\n\nfunction aggregateTrace(\n traceId: string,\n spans: ProjectedOtlpSpan[],\n fallbackModel: string,\n): AggregatedTrace {\n // Span order within a trace is by start time (epoch-aware across ISO/epoch\n // dialects), then a stable tiebreak.\n const ordered = [...spans].sort(\n (a, b) => compareSpanTime(a.start_time, b.start_time) || a.span_id.localeCompare(b.span_id),\n )\n\n const measurements = summarizeExecutionMeasurements(\n ordered.map((span) => ({\n id: span.span_id,\n ...(span.parent_span_id ? { parentId: span.parent_span_id } : {}),\n attributes: span.attributes,\n modelCall: isOtlpModelCall({\n kind: span.kind,\n name: span.name,\n attributes: span.attributes,\n }),\n aggregate: span.kind !== 'LLM' && span.kind !== 'UNKNOWN',\n })),\n )\n let toolSpanCount = 0\n let agentSpanCount = 0\n let firstErrorMessage: string | undefined\n const modelVotes = new Map<string, number>()\n let earliest = ordered[0]?.start_time ?? ''\n let latest = ordered[0]?.end_time ?? ''\n\n for (const s of ordered) {\n if (s.start_time && (!earliest || compareSpanTime(s.start_time, earliest) < 0))\n earliest = s.start_time\n if (s.end_time && (!latest || compareSpanTime(s.end_time, latest) > 0)) latest = s.end_time\n\n if (s.kind === 'TOOL') {\n toolSpanCount += 1\n } else if (s.kind === 'AGENT') {\n agentSpanCount += 1\n }\n\n if (s.status === 'ERROR') {\n if (firstErrorMessage === undefined) {\n firstErrorMessage = (s.status_message ?? `${s.name} — STATUS_CODE_ERROR`).slice(0, 500)\n }\n }\n }\n\n const callSpanIds = new Set(measurements.callSpanIds)\n for (const span of ordered) {\n if (!callSpanIds.has(span.span_id)) continue\n const model = firstStringAttr(span.attributes, LLM_MODEL_ATTR_KEYS) ?? span.model_name\n if (model) modelVotes.set(model, (modelVotes.get(model) ?? 0) + 1)\n }\n\n // Dominant model across LLM spans; falls back to any model attribute on a\n // non-LLM span, then the supplied fallback snapshot.\n const model = topVote(modelVotes) ?? firstModelAttr(ordered) ?? fallbackModel\n\n let wallMs = 0\n // epoch-aware: Date.parse returns NaN for a bare epoch-millis string, which\n // silently zeroed wallMs for traces emitted with epoch timestamps.\n const a = spanEpochMillis(earliest)\n const b = spanEpochMillis(latest)\n if (a !== null && b !== null) wallMs = Math.max(0, b - a)\n\n const sourceTraceIds = [...new Set(spans.map((span) => span.trace_id))].sort()\n\n const terminal = terminalEvidenceFromRoots(ordered)\n const errorSummary = summarizeTraceErrors(\n ordered.map((span) => ({\n id: span.span_id,\n ...(span.parent_span_id ? { parentId: span.parent_span_id } : {}),\n role: errorRoleForProjectedSpan(span),\n error: span.status === 'ERROR',\n processRoot: span.parent_span_id === null && isTerminalRootCandidate(span),\n })),\n )\n return {\n traceId,\n sourceTraceCount: sourceTraceIds.length,\n sourceTraceIds,\n spanCount: spans.length,\n llmSpanCount: measurements.modelCallCount,\n toolSpanCount,\n agentSpanCount,\n errorSpanCount: errorSummary.total,\n executionErrorCount: errorSummary.execution,\n processErrorCount: errorSummary.process,\n guardrailErrorCount: errorSummary.guardrail,\n judgeErrorCount: errorSummary.evaluation,\n propagatedErrorCount: errorSummary.propagated,\n unclassifiedErrorCount: errorSummary.unclassified,\n tokenUsage: measurements.tokenUsage,\n firstErrorMessage,\n model,\n startTime: earliest,\n endTime: latest,\n wallMs,\n terminalOutcome: terminal.outcome,\n ...(terminal.failureMessage ? { terminalFailureMessage: terminal.failureMessage } : {}),\n callSpanIds: measurements.callSpanIds,\n costMeasurement: measurements.cost,\n ...(measurements.aggregate ? { aggregateMeasurement: measurements.aggregate } : {}),\n }\n}\n\nfunction terminalEvidenceFromRoots(spans: ProjectedOtlpSpan[]): {\n outcome: RunTerminalOutcome\n failureMessage?: string\n} {\n const roots = spans.filter(\n (span) => span.parent_span_id === null && isTerminalRootCandidate(span),\n )\n if (roots.length !== 1) return { outcome: 'unknown' }\n const root = roots[0]!\n if (root.status === 'ERROR') {\n return {\n outcome: 'failed',\n failureMessage: (root.status_message ?? `${root.name} — STATUS_CODE_ERROR`).slice(0, 500),\n }\n }\n if (root.status === 'OK') return { outcome: 'succeeded' }\n return { outcome: 'unknown' }\n}\n\nfunction isTerminalRootCandidate(span: ProjectedOtlpSpan): boolean {\n const role = errorRoleForProjectedSpan(span)\n return role !== 'LLM' && role !== 'TOOL' && role !== 'EVALUATOR' && role !== 'GUARDRAIL'\n}\n\nfunction errorRoleForProjectedSpan(span: ProjectedOtlpSpan): TraceErrorRole {\n return classifyOtlpSpanRole({\n kind: span.kind,\n name: span.name,\n attributes: span.attributes,\n })\n}\n\nfunction resolveScore(\n opts: OtlpToRunRecordsOptions,\n traceId: string,\n agg: TraceAggregate,\n): number | undefined {\n const supplied = opts.scoreForTrace?.(traceId, agg)\n if (supplied !== undefined) {\n if (!Number.isFinite(supplied)) {\n throw new Error(\n `otlpToRunRecords: scoreForTrace('${traceId}') returned non-finite ${supplied}`,\n )\n }\n return supplied\n }\n return undefined\n}\n\nfunction resolveCost(\n opts: OtlpToRunRecordsOptions,\n agg: AggregatedTrace,\n): { costUsd: number | null; costProvenance: RunCostProvenance } {\n const observedCost = agg.costMeasurement\n if (observedCost.complete && observedCost.value !== undefined) {\n return {\n costUsd: observedCost.value,\n costProvenance: { kind: 'observed', usd: observedCost.value },\n }\n }\n if (agg.aggregateMeasurement?.costUsd !== undefined) {\n return {\n costUsd: agg.aggregateMeasurement.costUsd,\n costProvenance: { kind: 'observed', usd: agg.aggregateMeasurement.costUsd },\n }\n }\n\n if (opts.priceUsdPerToken !== undefined) {\n const totalTokens = agg.tokenUsage.input + agg.tokenUsage.output\n const costUsd = totalTokens * opts.priceUsdPerToken\n return { costUsd, costProvenance: { kind: 'estimated', usd: costUsd } }\n }\n\n return { costUsd: null, costProvenance: { kind: 'uncaptured', usd: null } }\n}\n\nfunction extractPromptCompletion(\n spans: ProjectedOtlpSpan[],\n callSpanIds: string[],\n): {\n promptText?: string\n completionText?: string\n} {\n const callIds = new Set(callSpanIds)\n const measuredCalls = spans.filter((span) => callIds.has(span.span_id))\n const llm = (\n measuredCalls.length > 0 ? measuredCalls : spans.filter((s) => s.kind === 'LLM')\n ).sort(\n (a, b) => compareSpanTime(a.start_time, b.start_time) || a.span_id.localeCompare(b.span_id),\n )\n if (llm.length === 0) return {}\n const promptText =\n firstStringAttr(llm[0]!.attributes, ['input.value', 'llm.input_messages', 'gen_ai.prompt']) ??\n undefined\n const last = llm[llm.length - 1]!\n const completionText =\n firstStringAttr(last.attributes, [\n 'output.value',\n 'llm.output_messages',\n 'gen_ai.completion',\n ]) ?? undefined\n return {\n ...(promptText !== undefined ? { promptText } : {}),\n ...(completionText !== undefined ? { completionText } : {}),\n }\n}\n\nfunction topVote(votes: Map<string, number>): string | null {\n let best: string | null = null\n let bestN = 0\n for (const [k, n] of votes) {\n // Strict > keeps the higher count; lexicographic tie-break makes the winner\n // independent of Map insertion order (reproducible across producers).\n if (n > bestN || (n === bestN && best !== null && k < best)) {\n best = k\n bestN = n\n }\n }\n return best\n}\n\nfunction firstModelAttr(spans: ProjectedOtlpSpan[]): string | null {\n for (const s of spans) {\n const m = firstStringAttr(s.attributes, LLM_MODEL_ATTR_KEYS) ?? s.model_name\n if (m) return m\n }\n return null\n}\n\n/**\n * `validateRunRecord` rejects bare model aliases (`gpt-4o`) that remap\n * silently. AppWorld/HALO traces frequently carry such bare ids (or a null\n * model). When the model already encodes a snapshot we keep it; otherwise we\n * append the fallback snapshot token so the row is admissible without lying\n * about the model — the bare base name is preserved verbatim before `@`.\n */\nfunction ensureSnapshot(model: string, fallbackModel: string): string {\n if (modelHasSnapshot(model)) return model\n const fallbackTag = fallbackModel.includes('@')\n ? fallbackModel.slice(fallbackModel.indexOf('@'))\n : '@otlp'\n return `${model}${fallbackTag}`\n}\n\nfunction modelHasSnapshot(model: string): boolean {\n if (model.includes('@')) return true\n if (/-\\d{8}$/.test(model)) return true\n if (/-\\d{4}-\\d{2}-\\d{2}$/.test(model)) return true\n if (/:date-/.test(model)) return true\n return false\n}\n","import { CaptureIntegrityError } from '../errors'\nimport { applyToolSpanOtlpAttributes, OPENINFERENCE_SPAN_KIND } from '../trace/otlp-attributes'\nimport { createOtlpFlatLine, epochMillisToIso, spanStatusToOtlp } from '../trace/otlp-flat'\nimport type { ToolSpan } from '../trace/schema'\nimport type { TraceAnalysisStore } from './store'\nimport { createOtlpBufferTraceStore, type ToolSpansToTraceAnalysisStoreOptions } from './store-otlp'\n\n/** Missing tool spans cannot distinguish a tool-free run from broken capture. */\nexport class ToolTraceMissingError extends CaptureIntegrityError {\n constructor() {\n super('toolSpansToTraceAnalysisStore: no tool spans supplied; trace evidence is missing')\n }\n}\n\n/**\n * Snapshot canonical tool spans into the read interface used by trace analysts.\n * One run becomes one trace while arguments, results, errors, and timing remain searchable.\n */\nexport function toolSpansToTraceAnalysisStore(\n spans: readonly ToolSpan[] | null | undefined,\n options: ToolSpansToTraceAnalysisStoreOptions = {},\n): TraceAnalysisStore {\n if (!spans || spans.length === 0) throw new ToolTraceMissingError()\n\n const seen = new Set<string>()\n const lines = spans.map((span, index) => {\n assertToolSpanIdentity(span, index)\n const identity = `${span.runId}\\u0000${span.spanId}`\n if (seen.has(identity)) {\n throw new CaptureIntegrityError(\n `toolSpansToTraceAnalysisStore: duplicate span '${span.spanId}' in run '${span.runId}'`,\n )\n }\n seen.add(identity)\n\n const attributes = { ...(span.attributes ?? {}) }\n applyToolSpanOtlpAttributes(attributes, span)\n attributes[OPENINFERENCE_SPAN_KIND] = 'TOOL'\n\n const endedAt = span.endedAt ?? span.startedAt + (span.latencyMs ?? 0)\n const line = createOtlpFlatLine({\n traceId: span.runId,\n spanId: span.spanId,\n parentSpanId: span.parentSpanId ?? null,\n name: span.name,\n kind: 'SPAN_KIND_INTERNAL',\n startTime: toolSpanTimeIso(span.startedAt, span.spanId, 'startedAt'),\n endTime: toolSpanTimeIso(endedAt, span.spanId, 'endedAt'),\n statusCode: spanStatusToOtlp(span.status, span.error, 'STATUS_CODE_UNSET'),\n statusMessage: span.error,\n resource: { attributes: {} },\n attributes,\n })\n try {\n return JSON.stringify(line)\n } catch (cause) {\n throw new CaptureIntegrityError(\n `toolSpansToTraceAnalysisStore: span '${span.spanId}' in run '${span.runId}' is not JSON-serializable`,\n { cause },\n )\n }\n })\n\n return createOtlpBufferTraceStore(Buffer.from(`${lines.join('\\n')}\\n`, 'utf8'), options)\n}\n\nfunction assertToolSpanIdentity(span: ToolSpan, index: number): void {\n if (span.kind !== 'tool') {\n throw new CaptureIntegrityError(\n `toolSpansToTraceAnalysisStore: span at index ${index} has kind '${String(span.kind)}', not 'tool'`,\n )\n }\n if (!span.runId || !span.spanId || !span.name || !span.toolName) {\n throw new CaptureIntegrityError(\n `toolSpansToTraceAnalysisStore: span at index ${index} is missing runId, spanId, name, or toolName`,\n )\n }\n if (!Number.isFinite(span.startedAt)) {\n throw new CaptureIntegrityError(\n `toolSpansToTraceAnalysisStore: span '${span.spanId}' has invalid startedAt`,\n )\n }\n if (span.endedAt !== undefined && !Number.isFinite(span.endedAt)) {\n throw new CaptureIntegrityError(\n `toolSpansToTraceAnalysisStore: span '${span.spanId}' has invalid endedAt`,\n )\n }\n if (span.endedAt !== undefined && span.endedAt < span.startedAt) {\n throw new CaptureIntegrityError(\n `toolSpansToTraceAnalysisStore: span '${span.spanId}' ends before it starts`,\n )\n }\n if (span.latencyMs !== undefined && (!Number.isFinite(span.latencyMs) || span.latencyMs < 0)) {\n throw new CaptureIntegrityError(\n `toolSpansToTraceAnalysisStore: span '${span.spanId}' has invalid latencyMs`,\n )\n }\n}\n\nfunction toolSpanTimeIso(value: number, spanId: string, field: string): string {\n const iso = epochMillisToIso(value)\n if (iso) return iso\n throw new CaptureIntegrityError(\n `toolSpansToTraceAnalysisStore: span '${spanId}' has invalid ${field}`,\n )\n}\n","/**\n * Wrap a provider `fetch` and record request, response, and error events.\n *\n * The returned value is a plain `typeof fetch`. Capture is best-effort by\n * default; set `failClosed` when telemetry loss must stop the provider call.\n */\n\nimport {\n type ExtractedUsage,\n extractUsage,\n extractUsageFromSse,\n type SseUsageMode,\n} from './extract-usage'\nimport {\n defaultProviderRedactor,\n type ProviderRedactor,\n providerFromBaseUrl,\n type RawProviderDirection,\n type RawProviderEvent,\n type RawProviderSink,\n} from './raw-provider-sink'\n\nexport interface CaptureFetchContext {\n /** Logical run id stamped on every captured event. Required — without it\n * the raw events can't be paired with their parent `Run`. */\n runId: string\n /** Optional logical span id (enables span-level sink filtering). */\n spanId?: string\n /** Resolved base URL (normalised, no trailing slash). Used for the event's\n * `baseUrl` and for endpoint-path extraction. */\n baseUrl: string\n /** Model id the caller intends to invoke. Stamped on every event. */\n model: string\n /** Provider override. When omitted, `providerFromBaseUrl(baseUrl)`. */\n provider?: string\n}\n\nexport interface CaptureFetchOptions {\n /** Override the capture-time redactor. Default `defaultProviderRedactor`. */\n redactor?: ProviderRedactor\n /** Cap on captured response-body bytes; beyond it the body is truncated and\n * `body_truncated` is added to `redactedFields`. Default 2 MiB. */\n responseBodyByteCap?: number\n /** When true, a sink-write failure propagates to the caller. Default false\n * — capture is best-effort so a sink failure never kills the LLM call. */\n failClosed?: boolean\n /**\n * Invoked with the token usage parsed off each successful response (JSON or\n * SSE), keyed by the captured context. Lets a caller fold usage → cost without\n * re-cloning the response themselves. Not called when the response carries no\n * usage. Best-effort: a throw here is swallowed (it never kills the LLM call)\n * unless `failClosed` is set.\n */\n onUsage?: (usage: ExtractedUsage, ctx: CaptureFetchContext) => void\n /** How repeated SSE usage events should be reconciled. Default `cumulative`. */\n sseUsageMode?: SseUsageMode\n}\n\nconst DEFAULT_BODY_CAP = 2 * 1024 * 1024\n\nfunction headersToRecord(headers: Headers | undefined): Record<string, string> | undefined {\n if (!headers) return undefined\n const out: Record<string, string> = {}\n headers.forEach((value, key) => {\n out[key.toLowerCase()] = value\n })\n return Object.keys(out).length > 0 ? out : undefined\n}\n\nfunction parseMaybeJson(text: string): unknown {\n if (text.length === 0) return undefined\n try {\n return JSON.parse(text)\n } catch {\n return text\n }\n}\n\n/** Best-effort request-body read across the `fetch` input forms. */\nasync function readRequestBody(\n input: RequestInfo | URL,\n init: RequestInit | undefined,\n): Promise<unknown> {\n if (typeof init?.body === 'string') return parseMaybeJson(init.body)\n if (init?.body != null) return undefined // streams / FormData / Blob — not captured\n if (input instanceof Request) {\n try {\n return parseMaybeJson(await input.clone().text())\n } catch {\n return undefined\n }\n }\n return undefined\n}\n\nfunction endpointFromUrl(url: string, baseUrl: string): string {\n const normalisedBase = baseUrl.replace(/\\/+$/, '')\n if (url.startsWith(normalisedBase)) return url.slice(normalisedBase.length) || '/'\n try {\n return new URL(url).pathname\n } catch {\n return url\n }\n}\n\nexport function captureFetchToRawSink(\n fetch: typeof globalThis.fetch,\n sink: RawProviderSink,\n ctx: CaptureFetchContext,\n opts: CaptureFetchOptions = {},\n): typeof globalThis.fetch {\n const provider = ctx.provider ?? providerFromBaseUrl(ctx.baseUrl)\n const redactor = opts.redactor ?? defaultProviderRedactor\n const bodyCap = opts.responseBodyByteCap ?? DEFAULT_BODY_CAP\n let warned = false\n\n const baseEvent = (direction: RawProviderDirection, endpoint: string): RawProviderEvent => ({\n eventId: crypto.randomUUID(),\n runId: ctx.runId,\n spanId: ctx.spanId,\n provider,\n model: ctx.model,\n endpoint,\n baseUrl: ctx.baseUrl,\n attemptIndex: 0, // retries are re-invocations one layer up; documented in 0.x\n direction,\n timestamp: Date.now(),\n redactedFields: [],\n })\n\n const record = async (event: RawProviderEvent): Promise<void> => {\n try {\n await sink.record(redactor(event))\n } catch (err) {\n if (opts.failClosed) throw err\n if (!warned) {\n warned = true\n console.warn(\n `captureFetchToRawSink: sink.record failed (capture is best-effort) — ${\n err instanceof Error ? err.message : String(err)\n }`,\n )\n }\n }\n }\n\n return async (input: RequestInfo | URL, init?: RequestInit): Promise<Response> => {\n const url =\n typeof input === 'string' ? input : input instanceof URL ? input.toString() : input.url\n const method = (init?.method ?? (input instanceof Request ? input.method : 'GET')).toUpperCase()\n const endpoint = endpointFromUrl(url, ctx.baseUrl)\n\n const reqHeaders = new Headers(\n init?.headers ?? (input instanceof Request ? input.headers : undefined),\n )\n await record({\n ...baseEvent('request', endpoint),\n requestHeaders: { ...headersToRecord(reqHeaders), 'x-http-method': method },\n requestBody: await readRequestBody(input, init),\n })\n\n const start = Date.now()\n let response: Response\n try {\n response = await fetch(input, init)\n } catch (err) {\n await record({\n ...baseEvent('error', endpoint),\n durationMs: Date.now() - start,\n errorMessage: err instanceof Error ? err.message : String(err),\n })\n throw err\n }\n\n // Read the body off a clone so the caller still consumes the original.\n let responseBody: unknown\n let rawText: string | undefined\n const redactedFields: string[] = []\n try {\n rawText = await response.clone().text()\n if (rawText.length > bodyCap) {\n responseBody = rawText.slice(0, bodyCap)\n redactedFields.push('body_truncated')\n } else {\n responseBody = parseMaybeJson(rawText)\n }\n } catch {\n responseBody = undefined\n }\n\n if (opts.onUsage && rawText !== undefined) {\n // Reuse the body already read for capture; no extra clone. JSON first,\n // then SSE accumulation. A throw in the consumer's callback is swallowed\n // (best-effort) unless failClosed is set — the LLM call must not die here.\n try {\n const parsedForUsage = parseMaybeJson(rawText)\n const usage =\n extractUsage(parsedForUsage) ??\n (typeof parsedForUsage === 'string'\n ? extractUsageFromSse(rawText, { mode: opts.sseUsageMode })\n : null)\n if (usage) opts.onUsage(usage, ctx)\n } catch (err) {\n if (opts.failClosed) throw err\n }\n }\n\n await record({\n ...baseEvent('response', endpoint),\n durationMs: Date.now() - start,\n statusCode: response.status,\n responseHeaders: headersToRecord(response.headers),\n responseBody,\n redactedFields,\n })\n\n return response\n }\n}\n","/**\n * OpenTelemetry JSON export — maps TraceSchema v1 to OTLP/JSON so\n * traces render natively in Jaeger / Honeycomb / Langfuse / Grafana.\n *\n * Wire format only. We do NOT depend on the @opentelemetry SDK — that\n * would drag in polyfills incompatible with Workers/Edge. Consumers\n * push the JSON to their collector of choice via HTTP.\n *\n * Reference: OTLP 1.3.2 (ResourceSpans / ScopeSpans / Span).\n */\n\nimport {\n applyLlmSpanOtlpAttributes,\n applyToolSpanOtlpAttributes,\n OPENINFERENCE_SPAN_KIND,\n traceSpanKindToOpenInferenceKind,\n} from './otlp-attributes'\nimport type { Run, Span, TraceEvent } from './schema'\nimport type { TraceStore } from './store'\n\nexport const OTEL_AGENT_EVAL_SCOPE = { name: '@tangle-network/agent-eval', version: '0.3.0' }\n\nexport interface OtlpSpan {\n traceId: string\n spanId: string\n parentSpanId?: string\n name: string\n kind: number\n startTimeUnixNano: string\n endTimeUnixNano: string\n attributes: Array<{\n key: string\n value: { stringValue?: string; intValue?: string; doubleValue?: number; boolValue?: boolean }\n }>\n events?: Array<{ timeUnixNano: string; name: string; attributes?: OtlpSpan['attributes'] }>\n status?: { code: number; message?: string }\n}\n\nexport interface OtlpResourceSpans {\n resource: { attributes: OtlpSpan['attributes'] }\n scopeSpans: Array<{ scope: typeof OTEL_AGENT_EVAL_SCOPE; spans: OtlpSpan[] }>\n}\n\nexport interface OtlpExport {\n resourceSpans: OtlpResourceSpans[]\n}\n\n/** Export a single run's spans + events in OTLP/JSON. */\nexport async function exportRunAsOtlp(\n store: TraceStore,\n runId: string,\n resourceAttrs: Record<string, string | number | boolean> = {},\n): Promise<OtlpExport> {\n const run = await store.getRun(runId)\n if (!run) throw new Error(`run ${runId} not found`)\n const spans = await store.spans({ runId })\n const events = await store.events({ runId })\n const eventsBySpan = new Map<string, TraceEvent[]>()\n for (const e of events) {\n if (!e.spanId) continue\n const arr = eventsBySpan.get(e.spanId) ?? []\n arr.push(e)\n eventsBySpan.set(e.spanId, arr)\n }\n const traceId = runToTraceId(run)\n const otlpSpans: OtlpSpan[] = spans.map((s) =>\n spanToOtlp(s, traceId, eventsBySpan.get(s.spanId) ?? []),\n )\n return {\n resourceSpans: [\n {\n resource: {\n attributes: toAttributes({\n 'service.name': 'agent-eval',\n 'run.id': run.runId,\n 'run.scenario_id': run.scenarioId,\n 'run.variant_id': run.variantId ?? '',\n 'run.dataset_version': run.datasetVersion ?? '',\n 'run.code_sha': run.codeSha ?? '',\n 'run.model_fingerprint': run.modelFingerprint ?? '',\n ...resourceAttrs,\n }),\n },\n scopeSpans: [{ scope: OTEL_AGENT_EVAL_SCOPE, spans: otlpSpans }],\n },\n ],\n }\n}\n\nfunction spanToOtlp(span: Span, traceId: string, events: TraceEvent[]): OtlpSpan {\n const endedAt = span.endedAt ?? span.startedAt\n return {\n traceId,\n spanId: padSpanId(span.spanId),\n parentSpanId: span.parentSpanId ? padSpanId(span.parentSpanId) : undefined,\n name: span.name,\n kind: 1, // SPAN_KIND_INTERNAL\n startTimeUnixNano: msToNs(span.startedAt),\n endTimeUnixNano: msToNs(endedAt),\n attributes: toAttributes(flattenSpanAttributes(span)),\n events: events.map((e) => ({\n timeUnixNano: msToNs(e.timestamp),\n name: e.kind,\n attributes: toAttributes(flattenPayload(e.payload)),\n })),\n status: span.status === 'error' ? { code: 2, message: span.error } : { code: 1 },\n }\n}\n\nfunction flattenSpanAttributes(span: Span): Record<string, string | number | boolean> {\n const base: Record<string, string | number | boolean> = {}\n if (span.attributes) {\n for (const [k, v] of Object.entries(span.attributes)) {\n if (typeof v === 'string' || typeof v === 'number' || typeof v === 'boolean') base[k] = v\n }\n }\n base[OPENINFERENCE_SPAN_KIND] = traceSpanKindToOpenInferenceKind(span.kind)\n if (span.kind === 'llm') {\n applyLlmSpanOtlpAttributes(base, span)\n } else if (span.kind === 'tool') {\n applyToolSpanOtlpAttributes(base, span)\n } else if (span.kind === 'retrieval') {\n base['retrieval.query'] = span.query\n base['retrieval.hits'] = span.hits.length\n } else if (span.kind === 'judge') {\n base['judge.id'] = span.judgeId\n base['judge.dimension'] = span.dimension\n base['judge.score'] = span.score\n base['judge.target_span_id'] = span.targetSpanId\n } else if (span.kind === 'sandbox') {\n if (span.image) base['sandbox.image'] = span.image\n if (span.exitCode !== undefined) base['sandbox.exit_code'] = span.exitCode\n if (span.testsPassed !== undefined) base['sandbox.tests_passed'] = span.testsPassed\n if (span.testsTotal !== undefined) base['sandbox.tests_total'] = span.testsTotal\n }\n return base\n}\n\nfunction flattenPayload(\n payload: Record<string, unknown>,\n): Record<string, string | number | boolean> {\n const out: Record<string, string | number | boolean> = {}\n for (const [k, v] of Object.entries(payload)) {\n if (typeof v === 'string' || typeof v === 'number' || typeof v === 'boolean') out[k] = v\n else out[k] = JSON.stringify(v)\n }\n return out\n}\n\nfunction toAttributes(record: Record<string, string | number | boolean>): OtlpSpan['attributes'] {\n return Object.entries(record).map(([key, value]) => ({\n key,\n value:\n typeof value === 'number'\n ? Number.isInteger(value)\n ? { intValue: value.toString() }\n : { doubleValue: value }\n : typeof value === 'boolean'\n ? { boolValue: value }\n : { stringValue: value },\n }))\n}\n\nfunction msToNs(ms: number): string {\n return (BigInt(Math.floor(ms)) * 1_000_000n).toString()\n}\n\nfunction padSpanId(id: string): string {\n // OTLP wants 16-hex spanIds. UUIDs are 32-hex; strip dashes and take first 16.\n const cleaned = id.replace(/-/g, '')\n return cleaned.slice(0, 16).padEnd(16, '0')\n}\n\nfunction runToTraceId(run: Run): string {\n // OTLP wants 32-hex traceIds. Use runId directly when it's 32-hex already,\n // else SHA-ish truncate.\n const cleaned = run.runId.replace(/-/g, '')\n return cleaned.slice(0, 32).padEnd(32, '0')\n}\n","/**\n * OTEL bridge — connects TraceEmitter span lifecycle to the OtelExporter.\n *\n * When an OtelExporter is active, every span that closes through the\n * TraceEmitter is also pushed to the exporter for real-time streaming to\n * the user's OTEL collector.\n *\n * The bridge is opt-in: attach via `otelRunCompleteHook(exporter)` as a\n * RunCompleteHook, or wrap the store with `createOtelTracingStore` for\n * real-time per-span export.\n */\n\nimport type { RunCompleteHook } from './emitter'\nimport type { ExportableSpan, OtelExporter } from './otel-export'\nimport type { LlmSpan, Span, ToolSpan } from './schema'\nimport type { TraceStore } from './store'\n\n/**\n * Create a RunCompleteHook that exports all spans from the completed run\n * to the OTEL exporter, then flushes.\n */\nexport function otelRunCompleteHook(exporter: OtelExporter): RunCompleteHook {\n return async (ctx) => {\n const spans = await ctx.store.spans({ runId: ctx.runId })\n for (const span of spans) {\n if (span.endedAt) {\n exporter.exportSpan(storeSpanToExportable(span, ctx.runId))\n }\n }\n await exporter.flush()\n }\n}\n\n/**\n * Create an auto-exporting TraceStore wrapper that intercepts updateSpan\n * calls. When a span gets an endedAt, it's exported immediately. This\n * gives real-time streaming instead of batch-at-end.\n *\n * This is the preferred integration path: wrap the store before\n * constructing the TraceEmitter.\n */\nexport function createOtelTracingStore(\n inner: TraceStore,\n exporter: OtelExporter,\n traceId: string,\n): TraceStore {\n return {\n async appendRun(run) {\n return inner.appendRun(run)\n },\n async updateRun(runId, patch) {\n return inner.updateRun(runId, patch)\n },\n async appendSpan(span) {\n if (span.endedAt) {\n exporter.exportSpan(storeSpanToExportable(span, traceId))\n }\n return inner.appendSpan(span)\n },\n async updateSpan(spanId, patch) {\n await inner.updateSpan(spanId, patch)\n if (patch.endedAt) {\n const spans = await inner.spans({ runId: traceId })\n const found = spans.find((s) => s.spanId === spanId)\n if (found) {\n exporter.exportSpan(storeSpanToExportable(found, traceId))\n }\n }\n },\n async appendEvent(event) {\n return inner.appendEvent(event)\n },\n async appendBudgetEntry(entry) {\n return inner.appendBudgetEntry(entry)\n },\n async appendArtifact(artifact) {\n return inner.appendArtifact(artifact)\n },\n getRun: inner.getRun.bind(inner),\n listRuns: inner.listRuns.bind(inner),\n spans: inner.spans.bind(inner),\n events: inner.events.bind(inner),\n budget: inner.budget.bind(inner),\n artifacts: inner.artifacts.bind(inner),\n }\n}\n\nfunction storeSpanToExportable(span: Span, traceId: string): ExportableSpan {\n const llm = span.kind === 'llm' ? (span as LlmSpan) : undefined\n const tool = span.kind === 'tool' ? (span as ToolSpan) : undefined\n return {\n traceId,\n spanId: span.spanId,\n parentSpanId: span.parentSpanId,\n name: span.name,\n kind: span.kind,\n startedAt: span.startedAt,\n endedAt: span.endedAt,\n status: span.status,\n error: span.error,\n model: llm?.model,\n inputTokens: llm?.inputTokens,\n outputTokens: llm?.outputTokens,\n reasoningTokens: llm?.reasoningTokens,\n cachedTokens: llm?.cachedTokens,\n cacheWriteTokens: llm?.cacheWriteTokens,\n costUsd: llm?.costUsd,\n tool: tool\n ? {\n toolName: tool.toolName,\n args: tool.args,\n argsCaptured: tool.argsCaptured,\n result: tool.result,\n latencyMs: tool.latencyMs,\n }\n : undefined,\n attributes: span.attributes as Record<string, unknown> | undefined,\n }\n}\n","/**\n * OTEL span exporter — streams spans to an OTLP/HTTP collector.\n *\n * Reads OTEL_EXPORTER_OTLP_ENDPOINT + OTEL_EXPORTER_OTLP_HEADERS from env\n * when no explicit config is given. Batches spans and flushes periodically\n * or when the batch fills. No @opentelemetry SDK dependency — minimal\n * OTLP/JSON serializer (~120 LOC) using the existing otel.ts helpers.\n */\n\nimport { OTEL_AGENT_EVAL_SCOPE, type OtlpExport, type OtlpSpan } from './otel'\nimport {\n applyLlmSpanOtlpAttributes,\n applyToolSpanOtlpAttributes,\n OPENINFERENCE_SPAN_KIND,\n type ToolSpanOtlpInput,\n traceSpanKindToOpenInferenceKind,\n} from './otlp-attributes'\n\nexport interface OtelExportConfig {\n /** OTLP endpoint. Reads OTEL_EXPORTER_OTLP_ENDPOINT env by default. */\n endpoint?: string\n /** OTLP headers. Reads OTEL_EXPORTER_OTLP_HEADERS env by default. */\n headers?: Record<string, string>\n /** Batch size before flush. Default 64. */\n batchSize?: number\n /** Flush interval ms. Default 5000. */\n flushIntervalMs?: number\n /** Resource attributes stamped on every export. */\n resourceAttributes?: Record<string, string | number | boolean>\n /** Service name. Default 'agent-eval'. */\n serviceName?: string\n}\n\nexport interface OtelExporter {\n /** Called by the TraceEmitter on every span close. */\n exportSpan(span: ExportableSpan): void\n /** Force flush pending spans. */\n flush(): Promise<void>\n /** Shutdown cleanly — flushes remaining spans and stops the timer. */\n shutdown(): Promise<void>\n}\n\nexport interface ExportableSpan {\n traceId: string\n spanId: string\n parentSpanId?: string\n name: string\n kind: string\n startedAt: number\n endedAt?: number\n status?: string\n error?: string\n model?: string\n inputTokens?: number\n outputTokens?: number\n reasoningTokens?: number\n cachedTokens?: number\n cacheWriteTokens?: number\n costUsd?: number\n tool?: ToolSpanOtlpInput\n attributes?: Record<string, unknown>\n}\n\n/**\n * Create an OTEL exporter. Returns undefined when no endpoint is configured\n * (neither via config nor env) — callers should check before attaching.\n */\nexport function createOtelExporter(config?: OtelExportConfig): OtelExporter | undefined {\n const resolvedEndpoint =\n config?.endpoint ??\n (typeof process !== 'undefined' ? process.env.OTEL_EXPORTER_OTLP_ENDPOINT : undefined)\n if (!resolvedEndpoint) return undefined\n const endpoint: string = resolvedEndpoint\n\n const headers = config?.headers ?? parseHeadersFromEnv()\n const batchSize = config?.batchSize ?? 64\n const flushIntervalMs = config?.flushIntervalMs ?? 5000\n const serviceName = config?.serviceName ?? 'agent-eval'\n const resourceAttrs = config?.resourceAttributes ?? {}\n\n const pending: OtlpSpan[] = []\n let timer: ReturnType<typeof setInterval> | undefined\n let stopped = false\n\n const exporter: OtelExporter = {\n exportSpan(span: ExportableSpan): void {\n if (stopped) return\n pending.push(toOtlpSpan(span))\n if (pending.length >= batchSize) {\n void doFlush()\n }\n },\n\n async flush(): Promise<void> {\n await doFlush()\n },\n\n async shutdown(): Promise<void> {\n stopped = true\n if (timer !== undefined) {\n clearInterval(timer)\n timer = undefined\n }\n await doFlush()\n },\n }\n\n timer = setInterval(() => {\n if (pending.length > 0) void doFlush()\n }, flushIntervalMs)\n // Unref so the timer doesn't keep the process alive.\n if (typeof timer === 'object' && 'unref' in timer) {\n ;(timer as NodeJS.Timeout).unref()\n }\n\n async function doFlush(): Promise<void> {\n if (pending.length === 0) return\n const batch = pending.splice(0)\n const body: OtlpExport = {\n resourceSpans: [\n {\n resource: {\n attributes: toAttributes({\n 'service.name': serviceName,\n ...resourceAttrs,\n }),\n },\n scopeSpans: [{ scope: OTEL_AGENT_EVAL_SCOPE, spans: batch }],\n },\n ],\n }\n const url = `${endpoint.replace(/\\/+$/, '')}/v1/traces`\n try {\n await fetch(url, {\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n ...headers,\n },\n body: JSON.stringify(body),\n })\n } catch {\n // Best-effort — telemetry export must not crash the pipeline.\n }\n }\n\n return exporter\n}\n\nfunction parseHeadersFromEnv(): Record<string, string> {\n if (typeof process === 'undefined') return {}\n const raw = process.env.OTEL_EXPORTER_OTLP_HEADERS\n if (!raw) return {}\n const out: Record<string, string> = {}\n for (const pair of raw.split(',')) {\n const eq = pair.indexOf('=')\n if (eq < 0) continue\n const key = pair.slice(0, eq).trim()\n const value = pair.slice(eq + 1).trim()\n if (key) out[key] = value\n }\n return out\n}\n\nfunction toOtlpSpan(span: ExportableSpan): OtlpSpan {\n const endedAt = span.endedAt ?? span.startedAt\n const attrs: Record<string, string | number | boolean> = {}\n if (span.attributes) {\n for (const [k, v] of Object.entries(span.attributes)) {\n if (typeof v === 'string' || typeof v === 'number' || typeof v === 'boolean') attrs[k] = v\n }\n }\n attrs[OPENINFERENCE_SPAN_KIND] = traceSpanKindToOpenInferenceKind(span.kind)\n applyLlmSpanOtlpAttributes(attrs, span)\n if (span.tool) applyToolSpanOtlpAttributes(attrs, span.tool)\n return {\n traceId: padTraceId(span.traceId),\n spanId: padSpanId(span.spanId),\n parentSpanId: span.parentSpanId ? padSpanId(span.parentSpanId) : undefined,\n name: span.name,\n kind: 1, // SPAN_KIND_INTERNAL\n startTimeUnixNano: msToNs(span.startedAt),\n endTimeUnixNano: msToNs(endedAt),\n attributes: toAttributes(attrs),\n status: span.status === 'error' ? { code: 2, message: span.error } : { code: 1 },\n }\n}\n\nfunction toAttributes(record: Record<string, string | number | boolean>): OtlpSpan['attributes'] {\n return Object.entries(record).map(([key, value]) => ({\n key,\n value:\n typeof value === 'number'\n ? Number.isInteger(value)\n ? { intValue: value.toString() }\n : { doubleValue: value }\n : typeof value === 'boolean'\n ? { boolValue: value }\n : { stringValue: value },\n }))\n}\n\nfunction msToNs(ms: number): string {\n return (BigInt(Math.floor(ms)) * 1_000_000n).toString()\n}\n\nfunction padSpanId(id: string): string {\n const cleaned = id.replace(/-/g, '')\n return cleaned.slice(0, 16).padEnd(16, '0')\n}\n\nfunction padTraceId(id: string): string {\n const cleaned = id.replace(/-/g, '')\n return cleaned.slice(0, 32).padEnd(32, '0')\n}\n","/**\n * Convert agent-eval's internal trace shape (`FileSystemTraceStore` → `Run`,\n * `Span`, `TraceEvent`) into the OTLP-flat JSONL the trace analyst\n * (`analyzeTraces` + `OtlpFileTraceStore`) reads.\n *\n * Eval harnesses shard a `FileSystemTraceStore` per cell (persona / variant)\n * under a run directory. The analyst consumes a single OTLP-NDJSON file keyed\n * on `trace_id` + `span_id` with `start_time`/`end_time` in ISO-8601 and\n * resource + `attributes` rolled up per-span. This module walks every shard,\n * projects each `Span` (plus events pinned to it) into the flat OTLP shape,\n * and emits one NDJSON file.\n *\n * Generic OTLP/OpenInference fields are always emitted (`service.name`,\n * `agent.name`, `run.id`/`run.status`, `openinference.span.kind`,\n * `llm.model_name`, …). Domain attributes (`legal.*`, `tax.*`, …) are injected\n * per-run via {@link TraceStoreToOtlpOptions.resourceAttributes} /\n * {@link TraceStoreToOtlpOptions.runAttributes} so consumers don't re-roll the\n * walker.\n */\n\nimport { readdirSync, readFileSync, statSync, writeFileSync } from 'node:fs'\nimport { join } from 'node:path'\nimport {\n applyLlmSpanOtlpAttributes,\n applyToolSpanOtlpAttributes,\n OPENINFERENCE_SPAN_KIND,\n traceSpanKindToOpenInferenceKind,\n} from './otlp-attributes'\nimport { createOtlpFlatLine, epochMillisToIso, spanStatusToOtlp } from './otlp-flat'\nimport type { Run, Span, TraceEvent } from './schema'\n\n/** Marker `FileSystemTraceStore` stamps on partial-update NDJSON rows. */\ninterface MaybeUpdate {\n _update?: boolean\n}\n\nexport interface TracesToOtlpResult {\n /** Total spans emitted across every cell. */\n spanCount: number\n /** Total run-anchor spans (one per Run) appended for analyst visibility. */\n runCount: number\n /** Cells whose shards parsed cleanly. */\n cellCount: number\n /** Cells that errored mid-conversion — surfaced so a partial conversion\n * isn't silently masked. */\n cellErrorCount: number\n}\n\n/**\n * A trace source the analyst should ingest. Two layouts are supported:\n *\n * - `celled` (default): the root holds one cell subdirectory per\n * persona/variant, each a `FileSystemTraceStore` (`runs.ndjson`,\n * `spans.ndjson`, `events.ndjson`).\n * - `flat`: the root is itself a single `FileSystemTraceStore` (e.g. a\n * production-ingestion sidecar that appends one ndjson set directly under\n * the chosen directory).\n */\nexport interface TraceStoreSource {\n /** Absolute path to the trace store root. */\n root: string\n /** Layout — `celled` (default) or `flat`. */\n layout?: 'celled' | 'flat'\n /** OTLP `service.name` for this source. Overrides the options default. */\n serviceName?: string\n}\n\n/** Domain hooks. The walker is generic; consumers inject the namespaced\n * attributes that ride along on every run + span for analyst discovery. */\nexport interface TraceStoreToOtlpOptions {\n /** Default OTLP `service.name` when a source doesn't set its own.\n * Default `agent-eval`. */\n serviceName?: string\n /** Extra resource attributes per run, e.g.\n * `(run) => ({ 'legal.persona_id': run.tags?.personaId ?? '' })`. */\n resourceAttributes?: (run: Run) => Record<string, unknown>\n /** Extra attributes on the per-run anchor span, e.g. domain outcome fields. */\n runAttributes?: (run: Run) => Record<string, unknown>\n}\n\n/**\n * Read every per-cell shard under each source root and write a flat OTLP-JSONL\n * view of the corpus to `outPath`. Each cell directory is a\n * `FileSystemTraceStore` — NDJSON append-only with size-based rotation;\n * `updateRun`/`updateSpan` append `{ id, ...patch, _update: true }` rows\n * rather than rewriting, so readers must merge those patches in (done here).\n *\n * A `string` source is treated as a celled root.\n */\nexport function convertTraceStoresToOtlp(\n source: string | TraceStoreSource | readonly TraceStoreSource[],\n outPath: string,\n opts: TraceStoreToOtlpOptions = {},\n): TracesToOtlpResult {\n const sources: TraceStoreSource[] = Array.isArray(source)\n ? [...source]\n : typeof source === 'string'\n ? [{ root: source, layout: 'celled' }]\n : [source as TraceStoreSource]\n\n const defaultServiceName = opts.serviceName ?? 'agent-eval'\n const resourceAttributes = opts.resourceAttributes ?? (() => ({}))\n const runAttributes = opts.runAttributes ?? (() => ({}))\n\n const lines: string[] = []\n let spanCount = 0\n let runCount = 0\n let cellCount = 0\n let cellErrorCount = 0\n\n for (const src of sources) {\n const serviceName = src.serviceName ?? defaultServiceName\n const cellDirs: Array<{ label: string; dir: string }> =\n src.layout === 'flat'\n ? [{ label: '<root>', dir: src.root }]\n : listCells(src.root).map((name) => ({ label: name, dir: join(src.root, name) }))\n\n for (const cell of cellDirs) {\n try {\n const result = projectCell({\n cellDir: cell.dir,\n serviceName,\n resourceAttributes,\n runAttributes,\n })\n for (const line of result.lines) lines.push(line)\n spanCount += result.spanCount\n runCount += result.runCount\n cellCount += 1\n } catch (err) {\n console.warn(\n `[traces-to-otlp] cell ${cell.label} (${cell.dir}) skipped: ${err instanceof Error ? err.message : String(err)}`,\n )\n cellErrorCount += 1\n }\n }\n }\n\n writeFileSync(outPath, lines.join('\\n') + (lines.length > 0 ? '\\n' : ''))\n return { spanCount, runCount, cellCount, cellErrorCount }\n}\n\ninterface ProjectCellResult {\n lines: string[]\n runCount: number\n spanCount: number\n}\n\nfunction projectCell(args: {\n cellDir: string\n serviceName: string\n resourceAttributes: (run: Run) => Record<string, unknown>\n runAttributes: (run: Run) => Record<string, unknown>\n}): ProjectCellResult {\n const { cellDir, serviceName, resourceAttributes, runAttributes } = args\n const lines: string[] = []\n let runCount = 0\n let spanCount = 0\n\n const runs = readMergedShards<Run & MaybeUpdate>(cellDir, 'runs', 'runId')\n const spans = readMergedShards<Span & MaybeUpdate>(cellDir, 'spans', 'spanId')\n const events = readShards<TraceEvent>(cellDir, 'events')\n\n const runByRunId = new Map<string, Run>()\n for (const r of runs) runByRunId.set(r.runId, r)\n const spanBySpanId = new Map<string, Span>()\n for (const s of spans) spanBySpanId.set(s.spanId, s)\n const eventsBySpanId = new Map<string, TraceEvent[]>()\n\n // An HTTP-backed trace store can only POST `TraceEvent`s through the wire;\n // run/span lifecycle is projected into `state_mutation` events with\n // `payload.entity ∈ { run, run.update, span, span.update }`. Fold those back\n // so the analyst sees a complete Run + Span tree.\n for (const e of events) {\n if (e.kind === 'state_mutation' && e.payload && typeof e.payload === 'object') {\n const entity = (e.payload as Record<string, unknown>).entity\n if (entity === 'run') {\n const run = (e.payload as { run?: Run }).run\n if (run?.runId) runByRunId.set(run.runId, run)\n continue\n }\n if (entity === 'run.update') {\n const patch = (e.payload as { patch?: Partial<Run> }).patch\n if (patch && e.runId) {\n const prior = runByRunId.get(e.runId)\n if (prior) runByRunId.set(e.runId, { ...prior, ...patch })\n }\n continue\n }\n if (entity === 'span') {\n const span = (e.payload as { span?: Span }).span\n if (span?.spanId) spanBySpanId.set(span.spanId, span)\n continue\n }\n if (entity === 'span.update') {\n const spanId = (e.payload as { spanId?: string }).spanId\n const patch = (e.payload as { patch?: Partial<Span> }).patch\n if (spanId && patch) {\n const prior = spanBySpanId.get(spanId)\n if (prior) spanBySpanId.set(spanId, { ...prior, ...patch } as Span)\n }\n continue\n }\n }\n if (!e.spanId) continue\n const arr = eventsBySpanId.get(e.spanId) ?? []\n arr.push(e)\n eventsBySpanId.set(e.spanId, arr)\n }\n\n for (const run of runByRunId.values()) {\n const traceId = padTraceId(run.runId)\n const agentName = run.variantId ?? run.scenarioId\n const sharedResource = {\n attributes: {\n 'service.name': serviceName,\n 'agent.name': agentName,\n 'run.id': run.runId,\n 'run.status': run.status,\n ...resourceAttributes(run),\n },\n }\n\n const runSpanId = padSpanId(`run-${run.runId}`)\n const runStart = msToIso(run.startedAt)\n const runEnd = msToIso(run.endedAt ?? run.startedAt)\n const runStatus =\n run.outcome?.failureClass && run.outcome.failureClass !== 'success'\n ? 'STATUS_CODE_ERROR'\n : 'STATUS_CODE_OK'\n const runAttrs: Record<string, unknown> = {\n [OPENINFERENCE_SPAN_KIND]: 'AGENT',\n 'agent.name': agentName,\n 'agent.workflow.name': serviceName,\n ...runAttributes(run),\n }\n lines.push(\n JSON.stringify(\n toLine({\n traceId,\n spanId: runSpanId,\n parentSpanId: '',\n name: `run.${agentName}`,\n kind: 'SPAN_KIND_INTERNAL',\n startTime: runStart,\n endTime: runEnd,\n statusCode: runStatus,\n statusMessage: run.outcome?.notes ?? '',\n resource: sharedResource,\n attributes: runAttrs,\n }),\n ),\n )\n runCount += 1\n\n for (const span of spanBySpanId.values()) {\n if (span.runId !== run.runId) continue\n const spanAttrs = spanToAttributes(span, eventsBySpanId.get(span.spanId) ?? [])\n const statusCode = spanStatusToOtlp(span.status, span.error, 'STATUS_CODE_OK')\n lines.push(\n JSON.stringify(\n toLine({\n traceId,\n spanId: padSpanId(span.spanId),\n parentSpanId: span.parentSpanId ? padSpanId(span.parentSpanId) : runSpanId,\n name: span.name,\n kind: spanKindToOtlpKind(span.kind),\n startTime: msToIso(span.startedAt),\n endTime: msToIso(span.endedAt ?? span.startedAt),\n statusCode,\n statusMessage: span.error ?? '',\n resource: sharedResource,\n attributes: spanAttrs,\n }),\n ),\n )\n spanCount += 1\n }\n }\n\n return { lines, runCount, spanCount }\n}\n\nfunction listCells(root: string): string[] {\n try {\n return readdirSync(root, { withFileTypes: true })\n .filter((d) => d.isDirectory())\n .map((d) => d.name)\n .sort()\n } catch {\n return []\n }\n}\n\n/**\n * Read every NDJSON shard for `name` under `cellDir`, ordered by mtime so\n * rotated files apply before the active one. Yields raw rows including any\n * `_update: true` patches.\n */\nfunction readShards<T>(cellDir: string, name: string): T[] {\n let entries: string[]\n try {\n entries = readdirSync(cellDir)\n } catch {\n return []\n }\n const shards = entries\n .filter((f) => (f === `${name}.ndjson` || f.startsWith(`${name}.`)) && f.endsWith('.ndjson'))\n .map((f) => ({ file: f, path: join(cellDir, f) }))\n .map((s) => {\n let mtime = 0\n try {\n mtime = statSync(s.path).mtimeMs\n } catch {\n /* skip stat errors */\n }\n return { ...s, mtime }\n })\n .sort((a, b) => a.mtime - b.mtime || a.file.localeCompare(b.file))\n\n const rows: T[] = []\n for (const shard of shards) {\n let text: string\n try {\n text = readFileSync(shard.path, 'utf-8')\n } catch {\n continue\n }\n for (const line of text.split('\\n')) {\n const trimmed = line.trim()\n if (!trimmed) continue\n try {\n rows.push(JSON.parse(trimmed) as T)\n } catch {\n /* skip partial line */\n }\n }\n }\n return rows\n}\n\n/**\n * Read NDJSON shards and merge `{ ...patch, _update: true }` rows into the\n * prior record keyed on `idKey` — mirrors the in-memory merge\n * `FileSystemTraceStore` keeps but doesn't replay on cross-process load.\n */\nfunction readMergedShards<T extends { _update?: boolean }>(\n cellDir: string,\n name: string,\n idKey: keyof T,\n): T[] {\n const rows = readShards<T>(cellDir, name)\n const byId = new Map<string, T>()\n for (const row of rows) {\n const id = row[idKey] as unknown as string\n if (!id) continue\n const prior = byId.get(id)\n if (prior && row._update) {\n byId.set(id, { ...prior, ...row, _update: undefined } as T)\n } else {\n byId.set(id, row)\n }\n }\n return [...byId.values()]\n}\n\nfunction spanToAttributes(span: Span, events: TraceEvent[]): Record<string, unknown> {\n const attrs: Record<string, unknown> = {\n [OPENINFERENCE_SPAN_KIND]: traceSpanKindToOpenInferenceKind(span.kind),\n }\n if (span.kind === 'llm') {\n applyLlmSpanOtlpAttributes(attrs, span)\n if (Array.isArray(span.messages)) {\n attrs['llm.input_messages'] = JSON.stringify(span.messages.slice(-6))\n }\n if (typeof span.output === 'string') {\n attrs['llm.output_messages'] = JSON.stringify([{ role: 'assistant', content: span.output }])\n }\n } else if (span.kind === 'tool') {\n applyToolSpanOtlpAttributes(attrs, span)\n } else if (span.kind === 'judge') {\n attrs['judge.id'] = span.judgeId\n attrs['judge.dimension'] = span.dimension\n attrs['judge.score'] = span.score\n attrs['judge.target_span_id'] = span.targetSpanId\n }\n if (span.attributes) {\n for (const [k, v] of Object.entries(span.attributes)) {\n attrs[`agent_eval.${k}`] = v\n }\n }\n if (events.length > 0) {\n attrs['agent_eval.event_count'] = events.length\n attrs['agent_eval.event_kinds'] = JSON.stringify(events.map((e) => e.kind))\n }\n return attrs\n}\n\nfunction spanKindToOtlpKind(kind: Span['kind']): string {\n switch (kind) {\n case 'llm':\n return 'SPAN_KIND_CLIENT'\n case 'retrieval':\n return 'SPAN_KIND_CLIENT'\n default:\n return 'SPAN_KIND_INTERNAL'\n }\n}\n\nconst toLine = createOtlpFlatLine\n\nfunction msToIso(ms: number): string {\n if (ms <= 0) return new Date(0).toISOString()\n return epochMillisToIso(ms) ?? new Date(0).toISOString()\n}\n\n/** OTLP wants 16-hex span ids; eval traces use UUID-ish strings. Hex-strip +\n * take 16, else deterministic FNV fold. */\nfunction padSpanId(id: string): string {\n const cleaned = id.replace(/[^a-f0-9]/gi, '').toLowerCase()\n if (cleaned.length >= 16) return cleaned.slice(0, 16)\n return foldTo16Hex(id)\n}\n\n/** OTLP wants 32-hex trace ids; fold deterministically when too short. */\nfunction padTraceId(id: string): string {\n const cleaned = id.replace(/[^a-f0-9]/gi, '').toLowerCase()\n if (cleaned.length >= 32) return cleaned.slice(0, 32)\n return foldTo32Hex(id)\n}\n\nfunction foldTo16Hex(s: string): string {\n let h1 = 0x811c9dc5\n for (const ch of s) {\n h1 ^= ch.charCodeAt(0)\n h1 = Math.imul(h1, 0x01000193) >>> 0\n }\n const part = h1.toString(16).padStart(8, '0')\n return (part + part).slice(0, 16)\n}\n\nfunction foldTo32Hex(s: string): string {\n return foldTo16Hex(s) + foldTo16Hex(`${s}::trace`).slice(0, 16)\n}\n","/**\n * Replay-from-raw-events — turn every captured campaign run into a\n * re-runnable artifact.\n *\n * `RawProviderSink` captures every provider HTTP envelope; `runEvalCampaign`\n * makes that capture the default. Together they make every past run a\n * complete fingerprint of what happened on the wire — enough to replay\n * the run without burning new LLM cost.\n *\n * Three use cases this primitive enables:\n *\n * 1. **Post-hoc judging** — apply a new judge / rubric / scoring callback\n * to last week's runs without re-calling any LLM. The cost of trying\n * a new rubric drops from \"another full sweep\" to a CPU-bound replay.\n * 2. **Determinism audits** — replay the same campaign and verify the\n * raw responses match byte-for-byte. Any drift is a non-determinism\n * bug (in the harness, the prompt builder, the sandbox, …).\n * 3. **Free judge calibration** — run two judges on identical responses\n * and measure inter-judge agreement without doubling LLM spend.\n *\n * The interface is deliberately fetch-shaped. Inject `createReplayFetch`\n * into `LlmClientOptions.fetch` and every `callLlm` transparently reads\n * from the cache instead of calling the network. No new code path through\n * the LLM client is needed; the cache hit is invisible to the runner.\n */\n\nimport { ReplayError } from './errors'\nimport { canonicalize, hashJson } from './pre-registration'\nimport type { RawProviderEvent, RawProviderSink } from './trace/raw-provider-sink'\n\nexport class ReplayCacheMissError extends ReplayError {\n constructor(\n public readonly url: string,\n public readonly requestKey: string,\n message?: string,\n ) {\n super(message ?? `replay cache miss for ${url} (key=${requestKey})`)\n }\n}\n\nexport interface ReplayCacheEntry {\n request: RawProviderEvent\n response: RawProviderEvent\n}\n\nexport interface ReplayCacheStats {\n total: number\n byProvider: Record<string, number>\n byModel: Record<string, number>\n /** Spans for which we have a request but no response (run aborted mid-call). */\n orphanRequests: number\n}\n\n/**\n * In-memory deterministic cache of (request → response) keyed on a stable\n * hash of the request body. Built from a `RawProviderSink` containing\n * paired `request` and `response` events from a previous run.\n *\n * The cache is the source of truth for replay; `createReplayFetch` is a\n * thin wrapper that reads from it.\n */\nexport class ReplayCache {\n private byKey = new Map<string, ReplayCacheEntry>()\n private orphans = 0\n private byProvider: Record<string, number> = {}\n private byModel: Record<string, number> = {}\n\n /**\n * Build a cache from a sink's events. The sink must implement `list()`.\n * Filter by `runId` / `spanId` to scope to a specific replay.\n */\n static async fromSink(\n sink: RawProviderSink,\n filter: { runId?: string; spanId?: string } = {},\n ): Promise<ReplayCache> {\n if (!sink.list) {\n throw new ReplayError('ReplayCache.fromSink: sink must implement list() to be replayable.')\n }\n const events = await sink.list(filter)\n return ReplayCache.fromEvents(events)\n }\n\n /** Build a cache from an in-memory event list. */\n static async fromEvents(events: RawProviderEvent[]): Promise<ReplayCache> {\n const cache = new ReplayCache()\n // Group by (runId, spanId, attemptIndex) so request/response/error pairs are matched.\n // A cell can have many spans; each retry attempt within a span is a separate group.\n type GroupKey = string\n const groups = new Map<GroupKey, { req?: RawProviderEvent; res?: RawProviderEvent }>()\n for (const e of events) {\n const k = `${e.runId ?? ''}::${e.spanId ?? ''}::${e.attemptIndex}`\n const g = groups.get(k) ?? {}\n if (e.direction === 'request') g.req = e\n else g.res = e\n groups.set(k, g)\n }\n for (const g of groups.values()) {\n if (!g.req) continue\n if (!g.res) {\n cache.orphans += 1\n continue\n }\n const key = await requestKey(g.req)\n cache.byKey.set(key, { request: g.req, response: g.res })\n cache.byProvider[g.req.provider] = (cache.byProvider[g.req.provider] ?? 0) + 1\n cache.byModel[g.req.model] = (cache.byModel[g.req.model] ?? 0) + 1\n }\n return cache\n }\n\n /** Number of cacheable (request, response) pairs in the cache. */\n size(): number {\n return this.byKey.size\n }\n\n stats(): ReplayCacheStats {\n return {\n total: this.byKey.size,\n byProvider: { ...this.byProvider },\n byModel: { ...this.byModel },\n orphanRequests: this.orphans,\n }\n }\n\n /** Iterate every cached `(request, response)` pair in insertion order. */\n *entries(): IterableIterator<ReplayCacheEntry> {\n for (const entry of this.byKey.values()) yield entry\n }\n\n /**\n * Look up a cached response by hashing the (model, messages, temperature,\n * maxTokens, response_format) shape. Returns `undefined` on miss; the\n * caller decides whether to throw, fall back to the network, or skip.\n */\n async lookup(requestBody: unknown): Promise<ReplayCacheEntry | undefined> {\n const key = await keyFromBody(requestBody)\n return this.byKey.get(key)\n }\n}\n\nexport interface ReplayFetchOptions {\n /**\n * Behaviour on cache miss. Default `'throw'`. `'fallback'` calls the\n * `fallbackFetch` (typically `globalThis.fetch`) so a partial replay can\n * still complete; `'fail-closed'` returns a synthetic 599 response so the\n * call site sees a non-retriable failure.\n */\n onMiss?: 'throw' | 'fallback' | 'fail-closed'\n fallbackFetch?: typeof fetch\n /** Optional callback fired once per replayed call (for telemetry / counters). */\n onHit?: (info: { url: string; provider: string; model: string }) => void\n /** Optional callback fired on cache miss before the `onMiss` policy applies. */\n onMissNotify?: (info: { url: string; requestBody: unknown }) => void\n}\n\n/**\n * Build a `fetch`-shaped function that serves cached responses out of a\n * `ReplayCache` for any URL ending in `/chat/completions`. Pass through\n * `LlmClientOptions.fetch` and `callLlm` becomes free.\n *\n * Non-`/chat/completions` URLs are passed straight to the fallback fetch\n * (default: `globalThis.fetch`). This matters because non-LLM HTTP work\n * (judge HTTP servers, sandbox callbacks) sometimes flows through the same\n * `fetch` and shouldn't be intercepted.\n */\nexport function createReplayFetch(cache: ReplayCache, opts: ReplayFetchOptions = {}): typeof fetch {\n const onMiss = opts.onMiss ?? 'throw'\n const fallback = opts.fallbackFetch ?? globalThis.fetch?.bind(globalThis)\n\n return (async (input: RequestInfo | URL, init?: RequestInit) => {\n const url =\n typeof input === 'string' ? input : input instanceof URL ? input.toString() : input.url\n if (!/\\/chat\\/completions(?:[?#].*)?$/.test(url)) {\n if (!fallback)\n throw new ReplayError(\n `replay fetch: non-completions URL ${url} but no fallbackFetch configured`,\n )\n return fallback(input as RequestInfo, init)\n }\n let bodyParsed: unknown\n if (init?.body && typeof init.body === 'string') {\n try {\n bodyParsed = JSON.parse(init.body)\n } catch {\n /* raw body, not JSON */\n }\n }\n const hit = bodyParsed === undefined ? undefined : await cache.lookup(bodyParsed)\n if (hit) {\n opts.onHit?.({ url, provider: hit.request.provider, model: hit.request.model })\n const status = hit.response.statusCode ?? 200\n const headers = new Headers(\n Object.entries(hit.response.responseHeaders ?? { 'Content-Type': 'application/json' }),\n )\n const bodyText =\n typeof hit.response.responseBody === 'string'\n ? hit.response.responseBody\n : JSON.stringify(hit.response.responseBody ?? {})\n return new Response(bodyText, { status, headers })\n }\n opts.onMissNotify?.({ url, requestBody: bodyParsed })\n if (onMiss === 'throw') {\n const key = bodyParsed === undefined ? '<unparseable>' : await keyFromBody(bodyParsed)\n throw new ReplayCacheMissError(url, key)\n }\n if (onMiss === 'fail-closed') {\n return new Response(JSON.stringify({ error: 'replay_cache_miss' }), { status: 599 })\n }\n if (!fallback)\n throw new ReplayError('replay fetch: onMiss=fallback but no fallbackFetch configured')\n return fallback(input as RequestInfo, init)\n }) as typeof fetch\n}\n\n/**\n * Convenience iterator over `(request, response)` pairs in a sink — for\n * post-hoc scoring that doesn't need a `fetch` shim. The judge or scorer\n * runs purely in-process over cached LLM outputs.\n */\nexport async function* iterateRawCalls(\n sink: RawProviderSink,\n filter: { runId?: string; spanId?: string } = {},\n): AsyncGenerator<ReplayCacheEntry> {\n if (!sink.list) {\n throw new ReplayError('iterateRawCalls: sink must implement list().')\n }\n const events = await sink.list(filter)\n const cache = await ReplayCache.fromEvents(events)\n for (const entry of cache.entries()) yield entry\n}\n\n// ── Hashing ──────────────────────────────────────────────────────────────\n\n/**\n * Canonical request key.\n *\n * `model + messages + temperature + max_tokens|max_completion_tokens +\n * response_format` are the dimensions that affect the response shape.\n * Other fields (timestamp headers, provider-specific metadata) are\n * intentionally excluded so a request hashes the same across re-runs.\n */\nasync function requestKey(event: RawProviderEvent): Promise<string> {\n return keyFromBody(event.requestBody)\n}\n\nasync function keyFromBody(body: unknown): Promise<string> {\n if (body == null || typeof body !== 'object') return hashJson({ raw: String(body) })\n const b = body as Record<string, unknown>\n const reduced = canonicalize({\n model: b.model ?? null,\n messages: b.messages ?? null,\n temperature: b.temperature ?? null,\n max_tokens: b.max_tokens ?? null,\n max_completion_tokens: b.max_completion_tokens ?? null,\n response_format: b.response_format ?? null,\n })\n return hashJson(reduced)\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"semantic-concept-judge-Bz64IckK.js","names":[],"sources":["../src/locked-jsonl-appender.ts","../src/analyst/findings-store.ts","../src/analyst/kinds/skill-usage.ts","../src/run-critic.ts","../src/semantic-concept-judge.ts"],"sourcesContent":["/**\n * LockedJsonlAppender — mutex-serialized JSONL append helper for arbitrary\n * payloads. The reference-replay store does the same thing for typed\n * `ReferenceReplayRun` rows; this is the generic version used by\n * `MutationTelemetry`, `TrialTelemetry`, and any other consumer that wants\n * append-only durable telemetry without rolling its own lock.\n *\n * Locks are per absolute file path (process-local). Cross-process\n * concurrency is NOT addressed — that's an fcntl/flock problem.\n */\n\nimport { appendFileSync, existsSync, mkdirSync } from 'node:fs'\nimport { dirname } from 'node:path'\nimport { Mutex } from './concurrency'\n\nconst mutexes = new Map<string, Mutex>()\n\nfunction getMutex(path: string): Mutex {\n let m = mutexes.get(path)\n if (!m) {\n m = new Mutex()\n mutexes.set(path, m)\n }\n return m\n}\n\nexport class LockedJsonlAppender {\n private readonly mutex: Mutex\n constructor(public readonly path: string) {\n this.mutex = getMutex(path)\n if (!existsSync(dirname(path))) {\n mkdirSync(dirname(path), { recursive: true })\n }\n }\n\n async append(entry: unknown): Promise<void> {\n const line = `${JSON.stringify(entry)}\\n`\n await this.mutex.runExclusive(() => {\n appendFileSync(this.path, line)\n })\n }\n}\n\n/** Reset all internal mutex state — tests only. */\nexport function resetLockedAppendersForTesting(): void {\n mutexes.clear()\n}\n","/**\n * FindingsStore — durable persistence for AnalystFinding rows + a diff\n * helper so we can answer \"what changed since the last run?\" without\n * recomputing analysts.\n *\n * On-disk shape is JSONL: one finding per line, append-only, locked via\n * LockedJsonlAppender. Operators get crash-safety (no partial JSON),\n * cheap reads (sequential parse), and trivial backup (rsync the file).\n *\n * Reads are non-locking: a reader sees a consistent snapshot of all\n * fully-written lines and skips an incomplete trailing line if the\n * writer is mid-append. Cross-process locking is intentionally out of\n * scope (see locked-jsonl-appender.ts).\n *\n * The store is run-scoped: callers pass `runId` on append and on load,\n * which keeps multi-run files cleanly partitioned. The `diffFindings`\n * helper compares two run-id sets using stable `finding_id` semantics —\n * the diff is the cross-run signal the regression dashboard renders.\n */\n\nimport { existsSync, readFileSync } from 'node:fs'\n\nimport { LockedJsonlAppender } from '../locked-jsonl-appender'\nimport type { AnalystFinding } from './types'\n\n/**\n * One persisted row. We attach `run_id` on disk so a single file can\n * hold multiple runs and the diff helper can query without re-walking\n * separate files.\n */\nexport interface PersistedFinding extends AnalystFinding {\n run_id: string\n}\n\nexport class FindingsStore {\n private readonly appender: LockedJsonlAppender\n\n constructor(public readonly path: string) {\n this.appender = new LockedJsonlAppender(path)\n }\n\n async append(runId: string, findings: AnalystFinding[]): Promise<void> {\n for (const f of findings) {\n const row: PersistedFinding = { ...f, run_id: runId }\n await this.appender.append(row)\n }\n }\n\n /** Load every persisted finding. Discards malformed trailing lines silently. */\n loadAll(): PersistedFinding[] {\n if (!existsSync(this.path)) return []\n const raw = readFileSync(this.path, 'utf8')\n if (!raw) return []\n const out: PersistedFinding[] = []\n for (const line of raw.split('\\n')) {\n if (!line) continue\n try {\n out.push(JSON.parse(line) as PersistedFinding)\n } catch {\n // Skip torn trailing line — the lock guarantees no torn lines\n // mid-file, only at EOF when a writer is in-flight.\n }\n }\n return out\n }\n\n /** Filter to a single run. */\n loadRun(runId: string): PersistedFinding[] {\n return this.loadAll().filter((r) => r.run_id === runId)\n }\n}\n\n// ── Cross-run diff ──────────────────────────────────────────────────\n\nexport interface FindingsDiff {\n /** New finding ids in `current` that weren't in `previous`. */\n appeared: PersistedFinding[]\n /** Finding ids in `previous` that aren't in `current`. */\n disappeared: PersistedFinding[]\n /** Same finding id present in both runs and unchanged per the materiality test. */\n persisted: PersistedFinding[]\n /**\n * Same finding id in both runs but at least one non-identity field\n * shifted per `DiffPolicy.isMaterial`. Reported as [previous, current].\n */\n changed: Array<{ previous: PersistedFinding; current: PersistedFinding }>\n}\n\nexport interface DiffPolicy {\n /**\n * Predicate that decides whether two findings (same finding_id) count\n * as a material change. Defaults to {@link defaultIsMaterial}: severity\n * shift, confidence Δ > 0.05, or evidence count change. Compliance /\n * perf consumers MAY supply a stricter predicate (e.g. rationale text\n * diff, metric Δ thresholds).\n */\n isMaterial?: (previous: AnalystFinding, current: AnalystFinding) => boolean\n}\n\n/**\n * Default materiality test. Deliberately narrow so LLM-reword churn\n * doesn't flood the diff. Stricter tests are opt-in via DiffPolicy.\n */\nexport function defaultIsMaterial(a: AnalystFinding, b: AnalystFinding): boolean {\n if (a.severity !== b.severity) return true\n if (Math.abs((a.confidence ?? 0) - (b.confidence ?? 0)) > 0.05) return true\n if (a.evidence_refs.length !== b.evidence_refs.length) return true\n return false\n}\n\n/**\n * Diff two findings sets by stable finding_id. Callers typically load\n * the two run-id slices from the same store and pass them in.\n */\nexport function diffFindings(\n previous: PersistedFinding[],\n current: PersistedFinding[],\n policy: DiffPolicy = {},\n): FindingsDiff {\n const isMaterial = policy.isMaterial ?? defaultIsMaterial\n const prevById = new Map(previous.map((f) => [f.finding_id, f]))\n const curById = new Map(current.map((f) => [f.finding_id, f]))\n\n const appeared: PersistedFinding[] = []\n const disappeared: PersistedFinding[] = []\n const persisted: PersistedFinding[] = []\n const changed: FindingsDiff['changed'] = []\n\n for (const [id, cur] of curById) {\n const prev = prevById.get(id)\n if (!prev) {\n appeared.push(cur)\n continue\n }\n if (isMaterial(prev, cur)) {\n changed.push({ previous: prev, current: cur })\n } else {\n persisted.push(cur)\n }\n }\n for (const [id, prev] of prevById) {\n if (!curById.has(id)) disappeared.push(prev)\n }\n return { appeared, disappeared, persisted, changed }\n}\n","/**\n * Skill-usage analyst — a DETERMINISTIC `Analyst` over a Claude/Codex skill\n * library + its trace corpus. Unlike the trace-store kinds (failure-mode,\n * improvement, ...) this kind calls no LLM: it mines real usage and skill\n * structure and emits findings by rule.\n *\n * It exists because the naive \"Skill-tool invocation count\" lies low — it\n * misses orchestrated sub-dispatch (a leaf skill run BY /pursue or /governor\n * logs under the parent), slash-command entry, local-script bypass, and\n * on-disk artifacts. The 2026-05-30 skill audit found 39/53 skills at zero\n * direct invocations, yet only one was a genuine cut: the rest were\n * measurement-invisible or discovery-limited. This analyst encodes that\n * lesson as a multi-signal usage model so a cheap repeatable pass can keep\n * the library honest, and so the expensive audit workflow's verdicts can\n * GEPA-distill it toward agreement (see `gold/skill-verdicts.gold.jsonl`).\n *\n * Report-building (`buildSkillUsageReport`, an fs scan) is separated from\n * finding emission (`SkillUsageAnalyst.analyze`, pure) so the slow scan runs\n * once at the registry boundary and the rule logic stays unit-testable.\n */\n\nimport { type Dirent, existsSync, readdirSync, readFileSync, statSync } from 'node:fs'\nimport { join } from 'node:path'\nimport type { Analyst, AnalystContext, AnalystFinding, AnalystSeverity } from '../types'\nimport { computeFindingId } from '../types'\n\n// ── Input model ──────────────────────────────────────────────────────\n\nexport type SkillKind = 'public' | 'private'\n\n/** One skill's multi-signal usage + structure. All counts are deterministic. */\nexport interface SkillUsageRecord {\n name: string\n kind: SkillKind\n /** Absolute path to the skill's SKILL.md. */\n path: string\n lines: number\n /** `\"skill\":\"<name>\"` Skill-tool invocations across the trace corpus. */\n directInvocations: number\n /** `<command-name>/<name>` slash invocations across the trace corpus. */\n slashInvocations: number\n /** Sibling skills whose SKILL.md dispatches to this one (`/<name>`). Proxy\n * for orchestrated sub-dispatch the per-skill counter cannot see. */\n inboundRefs: number\n /** On-disk artifacts attributable to the skill (e.g. `.evolve/<name>/**`). */\n artifactCount: number\n /** Tangle-private reference count in the body (leak signal for public skills). */\n tanglePrivateRefs: number\n hasReferencesDir: boolean\n hasEvalsDir: boolean\n /** Body mentions `skill-runs.jsonl` (visible to /reflect + /governor). */\n logsRuns: boolean\n /** Description carries an explicit `Triggers:` clause / trigger phrases. */\n hasTriggerPhrases: boolean\n}\n\nexport interface SkillUsageReport {\n generatedFromTraces: number\n records: SkillUsageRecord[]\n}\n\nexport interface SkillUsageScanConfig {\n /** Dirs holding `*.jsonl` transcripts (Claude `~/.claude/projects`, Codex sessions). */\n transcriptDirs: string[]\n /** Skill roots to scan; each dir directly under `root` with a `SKILL.md` is a skill. */\n skillRoots: { root: string; kind: SkillKind }[]\n /** Roots scanned for `<root>/.evolve/<skill>` artifact dirs. */\n artifactRoots?: string[]\n /** Token-prefixed mappings: skill name → extra artifact subpaths under an artifactRoot\n * (e.g. reflect → `.evolve/reflections`). Catches non-eponymous artifact dirs. */\n artifactAliases?: Record<string, string[]>\n /** Cap files read per transcript dir (bounds a huge corpus); 0 = unbounded. */\n maxTranscriptsPerDir?: number\n}\n\n// ── Deterministic thresholds ─────────────────────────────────────────\n\n/** Anthropic's authoring guidance keeps SKILL.md short; past this with no\n * `references/` split the body burns context budget every session. */\nconst BLOAT_LINE_THRESHOLD = 300\n\nconst TANGLE_PRIVATE_RE =\n /\\b(cli-bridge|tangletools|ops-board|drew-gtr-pro|@tangle-network\\/|~\\/company|tangle\\.tools|gtm-agent)\\b|\\bkimi\\b|\\btcloud\\b/gi\nconst TRIGGER_RE = /triggers?\\s*[:-]/i\n\n// ── Report builder (fs scan — slow, runs once at the registry boundary) ──\n\nfunction listSkillDirs(root: string): { name: string; path: string }[] {\n if (!existsSync(root)) return []\n const out: { name: string; path: string }[] = []\n for (const entry of readdirSync(root, { withFileTypes: true })) {\n if (!entry.isDirectory() && !entry.isSymbolicLink()) continue\n const skillMd = join(root, entry.name, 'SKILL.md')\n if (existsSync(skillMd)) out.push({ name: entry.name, path: skillMd })\n }\n return out\n}\n\nfunction walkJsonl(dir: string, cap: number): string[] {\n if (!existsSync(dir)) return []\n const files: string[] = []\n const stack = [dir]\n while (stack.length) {\n const cur = stack.pop()!\n let entries: Dirent[]\n try {\n entries = readdirSync(cur, { withFileTypes: true })\n } catch {\n continue\n }\n for (const e of entries) {\n const full = join(cur, e.name)\n if (e.isDirectory()) stack.push(full)\n else if (e.name.endsWith('.jsonl')) {\n files.push(full)\n if (cap > 0 && files.length >= cap) return files\n }\n }\n }\n return files\n}\n\nfunction frontmatterDescription(body: string): string {\n const fm = /^---\\n([\\s\\S]*?)\\n---/.exec(body)\n const block = fm?.[1] ?? ''\n const m = /description:\\s*(.+)/i.exec(block)\n return m?.[1] ?? ''\n}\n\nfunction countArtifacts(roots: string[], name: string, aliases: string[]): number {\n let n = 0\n for (const root of roots) {\n const candidates = [join(root, '.evolve', name), ...aliases.map((a) => join(root, a))]\n for (const dir of candidates) {\n if (!existsSync(dir)) continue\n try {\n if (statSync(dir).isDirectory()) n += readdirSync(dir).length\n else n += 1\n } catch {\n /* unreadable — skip */\n }\n }\n }\n return n\n}\n\n/** Scan the corpus + skill roots into a {@link SkillUsageReport}. Deterministic. */\nexport function buildSkillUsageReport(config: SkillUsageScanConfig): SkillUsageReport {\n const skills = config.skillRoots.flatMap(({ root, kind }) =>\n listSkillDirs(root).map((s) => ({ ...s, kind })),\n )\n const names = skills.map((s) => s.name)\n\n // One pass over the corpus accumulating direct + slash counts per skill.\n const direct = new Map<string, number>(names.map((n) => [n, 0]))\n const slash = new Map<string, number>(names.map((n) => [n, 0]))\n const skillRe = /\"skill\"\\s*:\\s*\"([a-z0-9_:-]+)\"/g\n const cmdRe = /<command-name>\\/?([a-z0-9_:-]+)<\\/command-name>/g\n let transcripts = 0\n for (const dir of config.transcriptDirs) {\n for (const file of walkJsonl(dir, config.maxTranscriptsPerDir ?? 0)) {\n transcripts += 1\n let data: string\n try {\n data = readFileSync(file, 'utf8')\n } catch {\n continue\n }\n for (const m of data.matchAll(skillRe)) {\n const g = m[1]\n if (!g) continue\n const n = g.split(':').pop() ?? g\n const prev = direct.get(n)\n if (prev !== undefined) direct.set(n, prev + 1)\n }\n for (const m of data.matchAll(cmdRe)) {\n const g = m[1]\n if (g === undefined) continue\n const prev = slash.get(g)\n if (prev !== undefined) slash.set(g, prev + 1)\n }\n }\n }\n\n // Read each skill body once; compute structure + inbound refs across siblings.\n const bodies = new Map<string, string>()\n for (const s of skills) {\n try {\n bodies.set(s.name, readFileSync(s.path, 'utf8'))\n } catch {\n bodies.set(s.name, '')\n }\n }\n const inbound = new Map<string, number>(names.map((n) => [n, 0]))\n for (const target of names) {\n const ref = new RegExp(`/${target}\\\\b|\\\\[\\\\[${target}\\\\]\\\\]`)\n for (const s of skills) {\n if (s.name === target) continue\n if (ref.test(bodies.get(s.name) ?? '')) inbound.set(target, inbound.get(target)! + 1)\n }\n }\n\n const records: SkillUsageRecord[] = skills.map((s) => {\n const body = bodies.get(s.name) ?? ''\n const dir = s.path.replace(/\\/SKILL\\.md$/, '')\n return {\n name: s.name,\n kind: s.kind,\n path: s.path,\n lines: body ? body.split('\\n').length : 0,\n directInvocations: direct.get(s.name) ?? 0,\n slashInvocations: slash.get(s.name) ?? 0,\n inboundRefs: inbound.get(s.name) ?? 0,\n artifactCount: countArtifacts(\n config.artifactRoots ?? [],\n s.name,\n config.artifactAliases?.[s.name] ?? [],\n ),\n tanglePrivateRefs: (body.match(TANGLE_PRIVATE_RE) ?? []).length,\n hasReferencesDir: existsSync(join(dir, 'references')),\n hasEvalsDir: existsSync(join(dir, 'evals')),\n logsRuns: body.includes('skill-runs.jsonl'),\n hasTriggerPhrases: TRIGGER_RE.test(frontmatterDescription(body) || body.slice(0, 600)),\n }\n })\n return { generatedFromTraces: transcripts, records }\n}\n\n// ── Finding emission (pure — unit-testable, no LLM, no fs) ────────────\n\nconst ANALYST_ID = 'skill-usage'\n\nfunction finding(\n area: string,\n subject: string,\n claim: string,\n severity: AnalystSeverity,\n confidence: number,\n producedAt: string,\n recommended: string,\n evidenceUri: string,\n rationale?: string,\n): AnalystFinding {\n return {\n schema_version: '1.0.0',\n finding_id: computeFindingId({ analyst_id: ANALYST_ID, area, subject, claim }),\n analyst_id: ANALYST_ID,\n produced_at: producedAt,\n severity,\n area,\n claim,\n rationale,\n evidence_refs: [{ kind: 'artifact', uri: evidenceUri }],\n recommended_action: recommended,\n confidence,\n subject,\n }\n}\n\n/** Pure rule pass over a report → findings. Exported for direct/unit use. */\nexport function emitSkillUsageFindings(\n report: SkillUsageReport,\n producedAt: string,\n): AnalystFinding[] {\n const out: AnalystFinding[] = []\n for (const r of report.records) {\n const directTotal = r.directInvocations + r.slashInvocations\n const trueUsage = directTotal + r.inboundRefs + r.artifactCount\n\n // 1. Dead: no usage signal of ANY kind. The only real deprecation candidate.\n if (trueUsage === 0) {\n out.push(\n finding(\n 'skill-usage',\n r.name,\n `Skill '${r.name}' has zero usage across all signals (direct, slash, inbound-refs, artifacts)`,\n 'high',\n 0.6,\n producedAt,\n 'Confirm the skill covers a real recurring job; if not, deprecate. Zero true usage is the only deterministic deprecation candidate.',\n r.path,\n 'No Skill-tool call, no slash invocation, no sibling dispatches to it, and no on-disk artifacts.',\n ),\n )\n } else if (directTotal === 0 && r.inboundRefs + r.artifactCount > 0) {\n // 2. Measurement-invisible: real use via orchestration/artifacts, never invoked directly.\n out.push(\n finding(\n 'skill-usage',\n r.name,\n `Skill '${r.name}' shows 0 direct invocations but is used via orchestration/artifacts (inbound=${r.inboundRefs}, artifacts=${r.artifactCount})`,\n 'info',\n 0.8,\n producedAt,\n 'Do NOT treat as unused — usage is real but logged under parent skills or on disk. Strengthen direct-invocation discovery only if direct use is desired.',\n r.path,\n 'The Skill-tool counter undercounts orchestrated/chained leaf skills.',\n ),\n )\n }\n\n // 3. Discovery gap: low direct use AND weak trigger surface.\n if (directTotal <= 2 && !r.hasTriggerPhrases) {\n out.push(\n finding(\n 'discoverability',\n r.name,\n `Skill '${r.name}' is rarely invoked directly and its description has no explicit trigger phrases`,\n 'medium',\n 0.7,\n producedAt,\n 'Add a `Triggers:` clause with verbatim user phrases to the frontmatter description so the model auto-invokes it.',\n r.path,\n ),\n )\n }\n\n // 4. Public-repo leak.\n if (r.kind === 'public' && r.tanglePrivateRefs > 0) {\n out.push(\n finding(\n 'safety',\n r.name,\n `Public skill '${r.name}' carries ${r.tanglePrivateRefs} Tangle-private reference(s)`,\n 'high',\n 0.75,\n producedAt,\n 'Sanitize incidental internal refs (cli-bridge/kimi/tcloud/~company/private repos) or relocate to a private repo. Verify @tangle-network/* refs are to PUBLISHED packages before treating as a leak.',\n r.path,\n ),\n )\n }\n\n // 5. Bloat / no progressive disclosure.\n if (r.lines > BLOAT_LINE_THRESHOLD && !r.hasReferencesDir) {\n out.push(\n finding(\n 'maintainability',\n r.name,\n `Skill '${r.name}' is ${r.lines} lines with no references/ split (progressive disclosure)`,\n 'medium',\n 0.8,\n producedAt,\n `Split detail into references/ loaded on demand; keep SKILL.md a short overview. ${r.lines} lines load into every session's context budget.`,\n r.path,\n ),\n )\n }\n\n // 6. No evals (Anthropic's \">=3 evals before docs\" rule).\n if (!r.hasEvalsDir) {\n out.push(\n finding(\n 'data-quality',\n r.name,\n `Skill '${r.name}' ships no evals/`,\n 'low',\n 0.6,\n producedAt,\n 'Add evals/evals.json with >=3 scenarios proving the skill beats baseline; gives regression coverage.',\n r.path,\n ),\n )\n }\n\n // 7. No run logging → invisible to /reflect and /governor.\n if (!r.logsRuns) {\n out.push(\n finding(\n 'observability',\n r.name,\n `Skill '${r.name}' never appends to .evolve/skill-runs.jsonl`,\n 'low',\n 0.55,\n producedAt,\n 'Append one run line to .evolve/skill-runs.jsonl on completion, or declare it a non-logging leaf, so the self-improvement loop can see it ran.',\n r.path,\n ),\n )\n }\n }\n return out\n}\n\n// ── The Analyst ──────────────────────────────────────────────────────\n\nexport class SkillUsageAnalyst implements Analyst<SkillUsageReport> {\n readonly id = ANALYST_ID\n readonly description =\n 'Deterministic multi-signal skill-usage analysis: flags dead skills, measurement-invisible (orchestrated) usage, discovery gaps, public-repo leaks, bloat, missing evals, and missing run-logging.'\n readonly inputKind = 'custom' as const\n readonly cost = { kind: 'deterministic' as const, est_usd_per_run: 0 }\n readonly version = '1.0.0'\n\n async analyze(input: SkillUsageReport, ctx: AnalystContext): Promise<AnalystFinding[]> {\n const producedAt = ctx.tags?.producedAt ?? new Date().toISOString()\n ctx.log?.(\n `skill-usage: ${input.records.length} skills over ${input.generatedFromTraces} transcripts`,\n )\n return emitSkillUsageFindings(input, producedAt)\n }\n}\n\nexport const SKILL_USAGE_ANALYST = new SkillUsageAnalyst()\n","import { NotFoundError } from './errors'\nimport { aggregateRunScore, clamp01, type RunScore, type RunScoreWeights } from './run-score'\nimport type { Artifact, BudgetLedgerEntry, Run, Span, TraceEvent, TraceStore } from './trace'\n\nexport interface RunTrace {\n run: Run\n spans: Span[]\n events: TraceEvent[]\n artifacts: Artifact[]\n budget: BudgetLedgerEntry[]\n}\n\nexport interface RunCriticOptions {\n weights?: Partial<RunScoreWeights>\n driftPatterns?: RegExp[]\n}\n\nconst DEFAULT_DRIFT_PATTERNS = [\n /https?:\\/\\//i,\n /\\btitle:\\s/i,\n /\\bsummary:\\s/i,\n /\\burl:\\s/i,\n /\\bnpm package usage\\b/i,\n /\\bnews\\b/i,\n]\n\nexport class RunCritic {\n private readonly weights?: Partial<RunScoreWeights>\n private readonly driftPatterns: RegExp[]\n\n constructor(options: RunCriticOptions = {}) {\n this.weights = options.weights\n this.driftPatterns = options.driftPatterns ?? DEFAULT_DRIFT_PATTERNS\n }\n\n async score(store: TraceStore, runId: string): Promise<RunScore> {\n const run = await store.getRun(runId)\n if (!run) throw new NotFoundError(`run ${runId} not found`)\n const [spans, events, artifacts, budget] = await Promise.all([\n store.spans({ runId }),\n store.events({ runId }),\n store.artifacts(runId),\n store.budget(runId),\n ])\n return this.scoreTrace({ run, spans, events, artifacts, budget })\n }\n\n scoreTrace(trace: RunTrace): RunScore {\n const notes: string[] = []\n const llmSpans = trace.spans.filter(\n (s): s is Extract<Span, { kind: 'llm' }> => s.kind === 'llm',\n )\n const toolSpans = trace.spans.filter(\n (s): s is Extract<Span, { kind: 'tool' }> => s.kind === 'tool',\n )\n const judgeSpans = trace.spans.filter(\n (s): s is Extract<Span, { kind: 'judge' }> => s.kind === 'judge',\n )\n const sandboxSpans = trace.spans.filter(\n (s): s is Extract<Span, { kind: 'sandbox' }> => s.kind === 'sandbox',\n )\n const finalGateSpans = judgeSpans.filter(\n (span) => span.dimension === 'final_gate' || span.attributes?.finalGate === true,\n )\n\n const success =\n trace.run.outcome?.pass === true ? 1 : trace.run.status === 'completed' ? 0.5 : 0\n if (!success) notes.push('run did not complete with pass=true')\n\n const judgeAverage = judgeSpans.length\n ? judgeSpans.reduce((sum, span) => sum + normalizeJudgeScore(span.score), 0) /\n judgeSpans.length\n : undefined\n const outcomeScore =\n typeof trace.run.outcome?.score === 'number'\n ? clamp01(\n trace.run.outcome.score > 1 ? trace.run.outcome.score / 100 : trace.run.outcome.score,\n )\n : undefined\n const goalProgress = outcomeScore ?? judgeAverage ?? success\n\n const successfulTools = toolSpans.filter((span) => span.status !== 'error').length\n const toolUseQuality = toolSpans.length === 0 ? 0 : successfulTools / toolSpans.length\n if (toolSpans.length === 0) notes.push('no tool spans recorded')\n\n const patchEvidence =\n trace.artifacts.length +\n toolSpans.filter((span) => /write|edit|patch|apply/i.test(span.toolName)).length\n const patchQuality = patchEvidence > 0 ? clamp01(patchEvidence / 4) : 0\n if (!patchQuality) notes.push('no artifact or edit evidence recorded')\n\n const sandboxTests = sandboxSpans.filter(\n (span) => typeof span.testsTotal === 'number' && span.testsTotal > 0,\n )\n const testReality = sandboxTests.length\n ? sandboxTests.reduce(\n (sum, span) => sum + (span.testsPassed ?? 0) / Math.max(1, span.testsTotal ?? 1),\n 0,\n ) / sandboxTests.length\n : toolSpans.some((span) =>\n /\\btest|vitest|pytest|jest|build|tsc\\b/i.test(JSON.stringify(span.args)),\n )\n ? 0.4\n : 0\n if (!testReality) notes.push('no real test/build evidence recorded')\n\n const blockerSpans = judgeSpans.filter((span) => isBlockingJudge(span))\n const finalGateBlockers = finalGateSpans.filter((span) => isBlockingJudge(span))\n const finalGate = finalGateSpans.length ? (finalGateBlockers.length ? 0 : 1) : success\n if (finalGateBlockers.length)\n notes.push(`final gate blocked by ${finalGateBlockers.length} reviewer(s)`)\n else if (!finalGateSpans.length) notes.push('no final gate judgment recorded')\n\n const reviewerBlockers = judgeSpans.length ? blockerSpans.length / judgeSpans.length : 0\n if (reviewerBlockers) notes.push(`detected ${blockerSpans.length} blocking reviewer signal(s)`)\n\n const positiveGroundingSignals =\n patchEvidence +\n sandboxSpans.length +\n llmSpans.filter((span) => looksRepoGrounded(span.output ?? '')).length\n const driftSignals =\n llmSpans.filter((span) => this.isDrift(span.output ?? '')).length +\n trace.events.filter((event) => this.isDrift(JSON.stringify(event.payload))).length\n const repoGroundedness =\n positiveGroundingSignals + driftSignals === 0\n ? 0\n : positiveGroundingSignals / (positiveGroundingSignals + driftSignals)\n const driftPenalty =\n positiveGroundingSignals + driftSignals === 0\n ? 0\n : driftSignals / (positiveGroundingSignals + driftSignals)\n if (driftSignals > 0) notes.push(`detected ${driftSignals} drift signal(s)`)\n\n const costUsd = trace.budget.length\n ? Math.max(\n ...trace.budget\n .filter((entry: BudgetLedgerEntry) => entry.dimension === 'usd')\n .map((entry: BudgetLedgerEntry) => entry.consumed),\n 0,\n )\n : llmSpans.reduce((sum, span) => sum + (span.costUsd ?? 0), 0)\n const wallSeconds =\n trace.run.endedAt && trace.run.startedAt\n ? Math.max(0, (trace.run.endedAt - trace.run.startedAt) / 1000)\n : 0\n\n return {\n success,\n goalProgress,\n repoGroundedness,\n driftPenalty,\n toolUseQuality,\n patchQuality,\n testReality,\n finalGate,\n reviewerBlockers,\n costUsd,\n wallSeconds,\n notes,\n }\n }\n\n rank(score: RunScore): number {\n return aggregateRunScore(score, this.weights)\n }\n\n private isDrift(text: string): boolean {\n return this.driftPatterns.some((pattern) => pattern.test(text))\n }\n}\n\nfunction normalizeJudgeScore(score: number): number {\n return score > 1 ? clamp01(score / 10) : clamp01(score)\n}\n\nfunction looksRepoGrounded(text: string): boolean {\n return /(?:src\\/|tests?\\/|package\\.json|tsconfig|\\.ts\\b|\\.tsx\\b|git status|pnpm |npm |vitest|pytest|jest)/i.test(\n text,\n )\n}\n\nfunction isBlockingJudge(span: Extract<Span, { kind: 'judge' }>): boolean {\n return (\n span.attributes?.blocking === true ||\n span.attributes?.verdict === 'BLOCKING' ||\n positiveNumber(span.attributes?.blockingFindings) ||\n positiveNumber(span.attributes?.highFindings) ||\n span.score <= 2\n )\n}\n\nfunction positiveNumber(value: unknown): boolean {\n return typeof value === 'number' && value > 0\n}\n","/**\n * Semantic concept judge — \"does the built artifact actually implement\n * the features the user asked for?\"\n *\n * Distinct from the domain/code/coherence judges in `judges.ts`:\n * - those judges score free-form conversational agent outputs along\n * quality dimensions (accuracy, depth, etc.)\n * - this judge scores a *built artifact* (served HTML + source files)\n * against an explicit list of expected concepts, returning per-concept\n * {present, score 0-10, evidence, severity}.\n *\n * The judge is strict about distinguishing (a) a working implementation\n * from (b) a keyword-present stub. \"// TODO: mint button\" is NOT present.\n * Only real, functional, wired-up code counts.\n *\n * Use via {@link createSemanticConceptJudge} or directly via\n * {@link runSemanticConceptJudge}. Soft-fails (available=false) on LLM\n * or JSON-parse errors so the caller can treat that as \"layer skipped\"\n * rather than \"layer failed\" in a multi-layer pipeline.\n */\n\nimport { CostLedger, type CostLedgerHandle, type CostReceipt } from './cost-ledger'\nimport {\n callLlmJson,\n costReceiptFromLlm,\n costReceiptFromLlmError,\n type LlmCallRequest,\n type LlmClientOptions,\n maximumChargeForLlmRequest,\n} from './llm-client'\nimport type { Severity } from './multi-layer-verifier'\n\n// ─── Types ──────────────────────────────────────────────────────────────\n\n/**\n * Implementation complexity class for weighted scoring.\n *\n * - `render` (default): the concept is a UI surface that displays static\n * data — render a list, show a counter, lay out a button. Single-file\n * work, no external integration.\n * - `integrate`: the concept requires wiring a real external system —\n * wallet connect (wagmi + RainbowKit + chain config), payment provider\n * (Stripe Elements + intent + webhook), an API client with auth.\n * Multi-file, library-knowledge, runtime correctness matters.\n * - `compute`: the concept requires algorithmic work — solver, simulator,\n * constraint propagation, ML inference. Correctness > UI polish.\n *\n * Default weights (when applied via `weightConcepts: 'complexity'`):\n * render=1.0, integrate=2.0, compute=2.5\n *\n * Cross-vertical scoring without complexity weighting silently inflates\n * the rate of UI-heavy verticals (healthcare, fintech dashboards) vs\n * integration-heavy verticals (DeFi, wallets) — all concepts treated\n * equally even though the agent does 2-3x the work for `integrate`.\n */\nexport type ConceptComplexity = 'render' | 'integrate' | 'compute'\n\nexport interface ConceptSpec {\n name: string\n /** Short hints that help the judge; not used for matching. */\n keywords?: string[]\n /** Optional explicit weight; default 1.0. Overrides complexity-derived weight. */\n weight?: number\n /** Implementation complexity class. Default `render`. */\n complexity?: ConceptComplexity\n}\n\nexport interface ConceptFinding {\n concept: string\n present: boolean\n /** 0..10. 10 = production-ready; 7 = functional thin; 4 = partial; 0 = absent. */\n score: number\n evidence: string\n severity: Severity\n}\n\nexport interface SemanticConceptJudgeInput {\n /** Full natural-language prompt the agent was handed. */\n userRequest: string\n /** Rendered HTML the preview returns (UI artifacts). Optional. */\n servedHtml?: string\n /** Top-level source files from the agent's workdir. */\n sourceFiles: Array<{ path: string; content: string }>\n /** The expected concept list. */\n expectedConcepts: ConceptSpec[]\n /** Free-form metadata (id, difficulty) to inject into the prompt. */\n artifactLabel?: string\n artifactDescription?: string\n}\n\nexport interface SemanticConceptJudgeResult {\n kind: 'semantic-concept'\n version: string\n /** Normalized 0..1 score — mean of per-concept scores / 10. */\n score: number\n presentCount: number\n totalCount: number\n findings: ConceptFinding[]\n summary: string\n durationMs: number\n costUsd: number | null\n /** False on LLM/JSON error — treat as \"skipped / unable to judge\" in pipelines. */\n available: boolean\n error?: string\n}\n\n/**\n * Score-aggregation strategy. `mean` averages 0-10 scores uniformly.\n * `complexity` applies the default weight table (render=1, integrate=2,\n * compute=2.5) unless a concept has an explicit `weight`. `explicit`\n * honors only `weight` (defaulting to 1 for unspecified).\n */\nexport type ConceptWeightStrategy = 'mean' | 'complexity' | 'explicit'\n\nexport const DEFAULT_COMPLEXITY_WEIGHTS: Record<ConceptComplexity, number> = {\n render: 1.0,\n integrate: 2.0,\n compute: 2.5,\n}\n\nexport interface SemanticConceptJudgeOptions {\n /** Model id to call. Default 'claude-sonnet-4-6' via agent-eval defaults. */\n model?: string\n /** Per-call timeout. Default 300s. */\n timeoutMs?: number\n /** Provider-enforced output limit. Default 16000. */\n maxTokens?: number\n /** Pipeline budget for the prompt (source blob truncation). Default 45000. */\n maxSourceChars?: number\n /** Per-file cap before inclusion. Default 20000. */\n maxPerFileChars?: number\n /** HTML cap. Default 30000. */\n maxHtmlChars?: number\n /** LlmClient config (baseUrl, apiKey, authHeader, …). */\n llm?: LlmClientOptions\n costLedger?: CostLedgerHandle\n costPhase?: string\n costTags?: Record<string, string>\n signal?: AbortSignal\n /**\n * Score aggregation strategy. Default `mean` — uniform average across\n * concepts. Cross-vertical comparisons should use `complexity` to\n * neutralize the integrate-vs-render asymmetry.\n */\n weightConcepts?: ConceptWeightStrategy\n /** Override the default complexity → weight table. */\n complexityWeights?: Partial<Record<ConceptComplexity, number>>\n}\n\n// ─── Prompt assembly ────────────────────────────────────────────────────\n\nexport const SEMANTIC_CONCEPT_JUDGE_VERSION = 'semantic-concept-judge-v1-2026-04-24'\n\nconst DEFAULT_MAX_SOURCE = 45_000\nconst DEFAULT_MAX_HTML = 30_000\nconst DEFAULT_MAX_PER_FILE = 20_000\nconst DEFAULT_TIMEOUT = 300_000\nconst DEFAULT_MAX_TOKENS = 16_000\nconst DEFAULT_MODEL = 'claude-sonnet-4-6'\n\nconst SEMANTIC_SCHEMA = {\n type: 'object',\n additionalProperties: false,\n required: ['summary', 'concepts'],\n properties: {\n summary: { type: 'string', minLength: 20, maxLength: 600 },\n concepts: {\n type: 'array',\n minItems: 1,\n items: {\n type: 'object',\n additionalProperties: false,\n required: ['concept', 'present', 'score', 'evidence', 'severity'],\n properties: {\n concept: { type: 'string', minLength: 1, maxLength: 120 },\n present: { type: 'boolean' },\n score: { type: 'number', minimum: 0, maximum: 10 },\n evidence: { type: 'string', minLength: 5, maxLength: 400 },\n severity: { type: 'string', enum: ['critical', 'major', 'minor', 'info'] },\n },\n },\n },\n },\n}\n\nfunction truncate(body: string, cap: number, label: string): string {\n if (body.length <= cap) return body\n return `${body.slice(0, cap)}\\n… [truncated ${body.length - cap} chars of ${label}]`\n}\n\nfunction buildPrompt(\n input: SemanticConceptJudgeInput,\n opts: Required<SemanticConceptJudgeOptions>,\n): string {\n const sourceBlob = input.sourceFiles\n .filter((f) => f.content.length <= opts.maxPerFileChars)\n .map((f) => `--- FILE: ${f.path} ---\\n${f.content}`)\n .join('\\n\\n')\n\n const html = input.servedHtml ?? ''\n\n return `You are a strict code-review judge evaluating whether an agent's 0-to-1 build actually implements the features the user asked for.\n\nYou MUST distinguish:\n (a) WORKING code that implements the concept (rendered UI, wired handler, real API call),\n (b) KEYWORD-PRESENT stub (comments mentioning the concept, variable names, TODOs),\n (c) ABSENT (concept nowhere).\n\nA comment like \"// TODO: add mint button\" is NOT present — score 2-3. Only count a concept as present if there is real functional code: a rendered component, a call handler wired to state or a network call, a computed value actually used.\n\nUSER REQUEST (what the agent was asked to build):\n${input.userRequest}\n\n${input.artifactLabel ? `ARTIFACT METADATA:\\n name: ${input.artifactLabel}\\n description: ${input.artifactDescription ?? ''}\\n\\n` : ''}EXPECTED CONCEPTS (each must be graded independently):\n${input.expectedConcepts\n .map(\n (c, i) =>\n ` ${i + 1}. \"${c.name}\"${c.keywords?.length ? ` — hints: [${c.keywords.slice(0, 6).join(' | ')}]` : ''}`,\n )\n .join('\\n')}\n\n${html ? `SERVED HTML (what the preview returns when hit):\\n${truncate(html, opts.maxHtmlChars, 'HTML')}\\n\\n` : ''}SOURCE FILES (the agent's workdir):\n${truncate(sourceBlob, opts.maxSourceChars, 'source')}\n\nFor EACH concept, return:\n - concept: the concept name as given (match exactly)\n - present: boolean — does a working implementation exist?\n - score: 0-10 — 10 = production-ready; 7 = functional but thin; 4 = partial/stubbed; 2 = keyword-only comment; 0 = absent\n - evidence: cite \"<file>:<line>\" or \"served-html:<selector>\" pointing at the strongest supporting code. If the concept is absent or stubbed, explain what's missing.\n - severity:\n \"info\" when present: true AND score >= 7\n \"minor\" when present: true AND 4 <= score < 7\n \"major\" when present: false OR score < 4\n \"critical\" when the concept is not only absent but a core user flow depends on it\n\nAlso produce a \"summary\" (one sentence, 20-600 chars): overall verdict on whether this is a shippable implementation of the user request vs a keyword-dense placeholder.\n\nBE SKEPTICAL. Keyword matching already passed — your job is to catch what keyword matching misses. If the agent shipped a working build, say so. If it shipped a stub, say so. Don't grade on effort.\n\nReturn STRICT JSON. No prose outside the JSON.`\n}\n\n// ─── Runner ─────────────────────────────────────────────────────────────\n\n/**\n * Run the semantic concept judge. Soft-fails to available=false on\n * LLM/JSON errors — callers in a MultiLayerVerifier pipeline can treat\n * that as \"skip\" rather than \"fail.\"\n */\nexport async function runSemanticConceptJudge(\n input: SemanticConceptJudgeInput,\n options: SemanticConceptJudgeOptions = {},\n): Promise<SemanticConceptJudgeResult> {\n const start = Date.now()\n const totalCount = input.expectedConcepts.length\n\n if (totalCount === 0) {\n return {\n kind: 'semantic-concept',\n version: SEMANTIC_CONCEPT_JUDGE_VERSION,\n score: 0,\n presentCount: 0,\n totalCount: 0,\n findings: [],\n summary: 'no expected concepts declared',\n durationMs: 0,\n costUsd: null,\n available: false,\n error: 'no expected concepts declared',\n }\n }\n\n const opts: Required<SemanticConceptJudgeOptions> = {\n model: options.model ?? DEFAULT_MODEL,\n timeoutMs: options.timeoutMs ?? DEFAULT_TIMEOUT,\n maxTokens: options.maxTokens ?? DEFAULT_MAX_TOKENS,\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 costLedger: options.costLedger ?? new CostLedger(),\n costPhase: options.costPhase ?? 'judge.semantic-concept',\n costTags: options.costTags ?? {},\n signal: options.signal ?? new AbortController().signal,\n weightConcepts: options.weightConcepts ?? 'mean',\n complexityWeights: { ...DEFAULT_COMPLEXITY_WEIGHTS, ...(options.complexityWeights ?? {}) },\n }\n\n // Build a name → weight map for aggregation. Mean strategy keeps every\n // weight at 1 (uniform average). Complexity strategy reads the table\n // and lets an explicit `weight` override. Explicit strategy uses ONLY\n // the spec's `weight` (defaulting to 1).\n const weightForConcept = (spec: ConceptSpec): number => {\n if (opts.weightConcepts === 'mean') return 1\n if (spec.weight != null) return spec.weight\n if (opts.weightConcepts === 'complexity') {\n return opts.complexityWeights[spec.complexity ?? 'render'] ?? 1\n }\n return 1\n }\n const weightByName = new Map<string, number>(\n input.expectedConcepts.map((c) => [c.name, weightForConcept(c)]),\n )\n\n let receipt: CostReceipt | undefined\n try {\n const request = {\n model: opts.model,\n messages: [\n {\n role: 'system' as const,\n content:\n 'You are a strict code-review judge. Return strict JSON only. No prose outside the JSON. A keyword in a comment is NOT a working implementation.',\n },\n { role: 'user' as const, content: buildPrompt(input, opts) },\n ],\n jsonSchema: { name: 'semantic_concept_judge', schema: SEMANTIC_SCHEMA },\n temperature: 0,\n maxTokens: opts.maxTokens,\n timeoutMs: opts.timeoutMs,\n } satisfies LlmCallRequest\n const paid = await opts.costLedger.runPaidCall({\n channel: 'judge',\n phase: opts.costPhase,\n actor: 'semantic-concept',\n model: opts.model,\n ...(Object.keys(opts.costTags).length > 0 ? { tags: opts.costTags } : {}),\n maximumCharge: maximumChargeForLlmRequest(request, opts.llm),\n signal: opts.signal,\n execute: (signal, callId) =>\n callLlmJson<{ summary: string; concepts: ConceptFinding[] }>(request, {\n ...opts.llm,\n signal,\n idempotencyKey: callId,\n }),\n receipt: ({ result }) => costReceiptFromLlm(result),\n receiptFromError: costReceiptFromLlmError,\n })\n receipt = paid.receipt\n if (!paid.succeeded) throw paid.error\n const { value } = paid.value\n\n if (!value?.concepts || !Array.isArray(value.concepts)) {\n throw new Error('judge returned malformed response — expected array under \"concepts\"')\n }\n\n const findings: ConceptFinding[] = value.concepts.map((c) => ({\n concept: String(c.concept),\n present: Boolean(c.present),\n score: Math.max(0, Math.min(10, Number(c.score ?? 0))),\n evidence: String(c.evidence ?? ''),\n severity: (['critical', 'major', 'minor', 'info'] as const).includes(c.severity)\n ? c.severity\n : 'info',\n }))\n\n const presentCount = findings.filter((f) => f.present && f.score >= 7).length\n let weightSum = 0\n let weightedScoreSum = 0\n for (const f of findings) {\n const w = weightByName.get(f.concept) ?? 1\n weightSum += w\n weightedScoreSum += w * f.score\n }\n const scoreAvg =\n weightSum > 0\n ? weightedScoreSum / weightSum\n : findings.reduce((a, f) => a + f.score, 0) / Math.max(1, findings.length)\n\n return {\n kind: 'semantic-concept',\n version: SEMANTIC_CONCEPT_JUDGE_VERSION,\n score: Number((scoreAvg / 10).toFixed(3)),\n presentCount,\n totalCount,\n findings,\n summary: String(value.summary ?? ''),\n durationMs: Date.now() - start,\n costUsd: paid.receipt.costUnknown ? null : paid.receipt.costUsd,\n available: true,\n }\n } catch (err) {\n return {\n kind: 'semantic-concept',\n version: SEMANTIC_CONCEPT_JUDGE_VERSION,\n score: 0,\n presentCount: 0,\n totalCount,\n findings: [],\n summary: '',\n durationMs: Date.now() - start,\n costUsd: receipt && !receipt.costUnknown ? receipt.costUsd : null,\n available: false,\n error: err instanceof Error ? err.message : String(err),\n }\n }\n}\n\n/**\n * Factory: pin LLM options once, return a closure that accepts inputs.\n * Convenient for pipelines that want to share a single LlmClient config.\n */\nexport function createSemanticConceptJudge(\n options: SemanticConceptJudgeOptions = {},\n): (input: SemanticConceptJudgeInput) => Promise<SemanticConceptJudgeResult> {\n return (input) => runSemanticConceptJudge(input, options)\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAeA,MAAM,0BAAU,IAAI,IAAmB;AAEvC,SAAS,SAAS,MAAqB;CACrC,IAAI,IAAI,QAAQ,IAAI,IAAI;CACxB,IAAI,CAAC,GAAG;EACN,IAAI,IAAI,MAAM;EACd,QAAQ,IAAI,MAAM,CAAC;CACrB;CACA,OAAO;AACT;AAEA,IAAa,sBAAb,MAAiC;CAEH;CAD5B;CACA,YAAY,MAA8B;EAAd,KAAA,OAAA;EAC1B,KAAK,QAAQ,SAAS,IAAI;EAC1B,IAAI,CAAC,WAAW,QAAQ,IAAI,CAAC,GAC3B,UAAU,QAAQ,IAAI,GAAG,EAAE,WAAW,KAAK,CAAC;CAEhD;CAEA,MAAM,OAAO,OAA+B;EAC1C,MAAM,OAAO,GAAG,KAAK,UAAU,KAAK,EAAE;EACtC,MAAM,KAAK,MAAM,mBAAmB;GAClC,eAAe,KAAK,MAAM,IAAI;EAChC,CAAC;CACH;AACF;;;;;;;;;;;;;;;;;;;;;;ACPA,IAAa,gBAAb,MAA2B;CAGG;CAF5B;CAEA,YAAY,MAA8B;EAAd,KAAA,OAAA;EAC1B,KAAK,WAAW,IAAI,oBAAoB,IAAI;CAC9C;CAEA,MAAM,OAAO,OAAe,UAA2C;EACrE,KAAK,MAAM,KAAK,UAAU;GACxB,MAAM,MAAwB;IAAE,GAAG;IAAG,QAAQ;GAAM;GACpD,MAAM,KAAK,SAAS,OAAO,GAAG;EAChC;CACF;;CAGA,UAA8B;EAC5B,IAAI,CAAC,WAAW,KAAK,IAAI,GAAG,OAAO,CAAC;EACpC,MAAM,MAAM,aAAa,KAAK,MAAM,MAAM;EAC1C,IAAI,CAAC,KAAK,OAAO,CAAC;EAClB,MAAM,MAA0B,CAAC;EACjC,KAAK,MAAM,QAAQ,IAAI,MAAM,IAAI,GAAG;GAClC,IAAI,CAAC,MAAM;GACX,IAAI;IACF,IAAI,KAAK,KAAK,MAAM,IAAI,CAAqB;GAC/C,QAAQ,CAGR;EACF;EACA,OAAO;CACT;;CAGA,QAAQ,OAAmC;EACzC,OAAO,KAAK,QAAQ,CAAC,CAAC,QAAQ,MAAM,EAAE,WAAW,KAAK;CACxD;AACF;;;;;AAiCA,SAAgB,kBAAkB,GAAmB,GAA4B;CAC/E,IAAI,EAAE,aAAa,EAAE,UAAU,OAAO;CACtC,IAAI,KAAK,KAAK,EAAE,cAAc,MAAM,EAAE,cAAc,EAAE,IAAI,KAAM,OAAO;CACvE,IAAI,EAAE,cAAc,WAAW,EAAE,cAAc,QAAQ,OAAO;CAC9D,OAAO;AACT;;;;;AAMA,SAAgB,aACd,UACA,SACA,SAAqB,CAAC,GACR;CACd,MAAM,aAAa,OAAO,cAAc;CACxC,MAAM,WAAW,IAAI,IAAI,SAAS,KAAK,MAAM,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC;CAC/D,MAAM,UAAU,IAAI,IAAI,QAAQ,KAAK,MAAM,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC;CAE7D,MAAM,WAA+B,CAAC;CACtC,MAAM,cAAkC,CAAC;CACzC,MAAM,YAAgC,CAAC;CACvC,MAAM,UAAmC,CAAC;CAE1C,KAAK,MAAM,CAAC,IAAI,QAAQ,SAAS;EAC/B,MAAM,OAAO,SAAS,IAAI,EAAE;EAC5B,IAAI,CAAC,MAAM;GACT,SAAS,KAAK,GAAG;GACjB;EACF;EACA,IAAI,WAAW,MAAM,GAAG,GACtB,QAAQ,KAAK;GAAE,UAAU;GAAM,SAAS;EAAI,CAAC;OAE7C,UAAU,KAAK,GAAG;CAEtB;CACA,KAAK,MAAM,CAAC,IAAI,SAAS,UACvB,IAAI,CAAC,QAAQ,IAAI,EAAE,GAAG,YAAY,KAAK,IAAI;CAE7C,OAAO;EAAE;EAAU;EAAa;EAAW;CAAQ;AACrD;;;;;;;;;;;;;;;;;;;;;;;;;ACjEA,MAAM,uBAAuB;AAE7B,MAAM,oBACJ;AACF,MAAM,aAAa;AAInB,SAAS,cAAc,MAAgD;CACrE,IAAI,CAAC,WAAW,IAAI,GAAG,OAAO,CAAC;CAC/B,MAAM,MAAwC,CAAC;CAC/C,KAAK,MAAM,SAAS,YAAY,MAAM,EAAE,eAAe,KAAK,CAAC,GAAG;EAC9D,IAAI,CAAC,MAAM,YAAY,KAAK,CAAC,MAAM,eAAe,GAAG;EACrD,MAAM,UAAU,KAAK,MAAM,MAAM,MAAM,UAAU;EACjD,IAAI,WAAW,OAAO,GAAG,IAAI,KAAK;GAAE,MAAM,MAAM;GAAM,MAAM;EAAQ,CAAC;CACvE;CACA,OAAO;AACT;AAEA,SAAS,UAAU,KAAa,KAAuB;CACrD,IAAI,CAAC,WAAW,GAAG,GAAG,OAAO,CAAC;CAC9B,MAAM,QAAkB,CAAC;CACzB,MAAM,QAAQ,CAAC,GAAG;CAClB,OAAO,MAAM,QAAQ;EACnB,MAAM,MAAM,MAAM,IAAI;EACtB,IAAI;EACJ,IAAI;GACF,UAAU,YAAY,KAAK,EAAE,eAAe,KAAK,CAAC;EACpD,QAAQ;GACN;EACF;EACA,KAAK,MAAM,KAAK,SAAS;GACvB,MAAM,OAAO,KAAK,KAAK,EAAE,IAAI;GAC7B,IAAI,EAAE,YAAY,GAAG,MAAM,KAAK,IAAI;QAC/B,IAAI,EAAE,KAAK,SAAS,QAAQ,GAAG;IAClC,MAAM,KAAK,IAAI;IACf,IAAI,MAAM,KAAK,MAAM,UAAU,KAAK,OAAO;GAC7C;EACF;CACF;CACA,OAAO;AACT;AAEA,SAAS,uBAAuB,MAAsB;CAEpD,MAAM,QADK,wBAAwB,KAAK,IACzB,CAAC,GAAG,MAAM;CAEzB,OADU,uBAAuB,KAAK,KAC/B,CAAC,GAAG,MAAM;AACnB;AAEA,SAAS,eAAe,OAAiB,MAAc,SAA2B;CAChF,IAAI,IAAI;CACR,KAAK,MAAM,QAAQ,OAAO;EACxB,MAAM,aAAa,CAAC,KAAK,MAAM,WAAW,IAAI,GAAG,GAAG,QAAQ,KAAK,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC;EACrF,KAAK,MAAM,OAAO,YAAY;GAC5B,IAAI,CAAC,WAAW,GAAG,GAAG;GACtB,IAAI;IACF,IAAI,SAAS,GAAG,CAAC,CAAC,YAAY,GAAG,KAAK,YAAY,GAAG,CAAC,CAAC;SAClD,KAAK;GACZ,QAAQ,CAER;EACF;CACF;CACA,OAAO;AACT;;AAGA,SAAgB,sBAAsB,QAAgD;CACpF,MAAM,SAAS,OAAO,WAAW,SAAS,EAAE,MAAM,WAChD,cAAc,IAAI,CAAC,CAAC,KAAK,OAAO;EAAE,GAAG;EAAG;CAAK,EAAE,CACjD;CACA,MAAM,QAAQ,OAAO,KAAK,MAAM,EAAE,IAAI;CAGtC,MAAM,SAAS,IAAI,IAAoB,MAAM,KAAK,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;CAC/D,MAAM,QAAQ,IAAI,IAAoB,MAAM,KAAK,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;CAC9D,MAAM,UAAU;CAChB,MAAM,QAAQ;CACd,IAAI,cAAc;CAClB,KAAK,MAAM,OAAO,OAAO,gBACvB,KAAK,MAAM,QAAQ,UAAU,KAAK,OAAO,wBAAwB,CAAC,GAAG;EACnE,eAAe;EACf,IAAI;EACJ,IAAI;GACF,OAAO,aAAa,MAAM,MAAM;EAClC,QAAQ;GACN;EACF;EACA,KAAK,MAAM,KAAK,KAAK,SAAS,OAAO,GAAG;GACtC,MAAM,IAAI,EAAE;GACZ,IAAI,CAAC,GAAG;GACR,MAAM,IAAI,EAAE,MAAM,GAAG,CAAC,CAAC,IAAI,KAAK;GAChC,MAAM,OAAO,OAAO,IAAI,CAAC;GACzB,IAAI,SAAS,KAAA,GAAW,OAAO,IAAI,GAAG,OAAO,CAAC;EAChD;EACA,KAAK,MAAM,KAAK,KAAK,SAAS,KAAK,GAAG;GACpC,MAAM,IAAI,EAAE;GACZ,IAAI,MAAM,KAAA,GAAW;GACrB,MAAM,OAAO,MAAM,IAAI,CAAC;GACxB,IAAI,SAAS,KAAA,GAAW,MAAM,IAAI,GAAG,OAAO,CAAC;EAC/C;CACF;CAIF,MAAM,yBAAS,IAAI,IAAoB;CACvC,KAAK,MAAM,KAAK,QACd,IAAI;EACF,OAAO,IAAI,EAAE,MAAM,aAAa,EAAE,MAAM,MAAM,CAAC;CACjD,QAAQ;EACN,OAAO,IAAI,EAAE,MAAM,EAAE;CACvB;CAEF,MAAM,UAAU,IAAI,IAAoB,MAAM,KAAK,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;CAChE,KAAK,MAAM,UAAU,OAAO;EAC1B,MAAM,MAAM,IAAI,OAAO,IAAI,OAAO,YAAY,OAAO,OAAO;EAC5D,KAAK,MAAM,KAAK,QAAQ;GACtB,IAAI,EAAE,SAAS,QAAQ;GACvB,IAAI,IAAI,KAAK,OAAO,IAAI,EAAE,IAAI,KAAK,EAAE,GAAG,QAAQ,IAAI,QAAQ,QAAQ,IAAI,MAAM,IAAK,CAAC;EACtF;CACF;CAEA,MAAM,UAA8B,OAAO,KAAK,MAAM;EACpD,MAAM,OAAO,OAAO,IAAI,EAAE,IAAI,KAAK;EACnC,MAAM,MAAM,EAAE,KAAK,QAAQ,gBAAgB,EAAE;EAC7C,OAAO;GACL,MAAM,EAAE;GACR,MAAM,EAAE;GACR,MAAM,EAAE;GACR,OAAO,OAAO,KAAK,MAAM,IAAI,CAAC,CAAC,SAAS;GACxC,mBAAmB,OAAO,IAAI,EAAE,IAAI,KAAK;GACzC,kBAAkB,MAAM,IAAI,EAAE,IAAI,KAAK;GACvC,aAAa,QAAQ,IAAI,EAAE,IAAI,KAAK;GACpC,eAAe,eACb,OAAO,iBAAiB,CAAC,GACzB,EAAE,MACF,OAAO,kBAAkB,EAAE,SAAS,CAAC,CACvC;GACA,oBAAoB,KAAK,MAAM,iBAAiB,KAAK,CAAC,EAAA,CAAG;GACzD,kBAAkB,WAAW,KAAK,KAAK,YAAY,CAAC;GACpD,aAAa,WAAW,KAAK,KAAK,OAAO,CAAC;GAC1C,UAAU,KAAK,SAAS,kBAAkB;GAC1C,mBAAmB,WAAW,KAAK,uBAAuB,IAAI,KAAK,KAAK,MAAM,GAAG,GAAG,CAAC;EACvF;CACF,CAAC;CACD,OAAO;EAAE,qBAAqB;EAAa;CAAQ;AACrD;AAIA,MAAM,aAAa;AAEnB,SAAS,QACP,MACA,SACA,OACA,UACA,YACA,YACA,aACA,aACA,WACgB;CAChB,OAAO;EACL,gBAAgB;EAChB,YAAY,iBAAiB;GAAE,YAAY;GAAY;GAAM;GAAS;EAAM,CAAC;EAC7E,YAAY;EACZ,aAAa;EACb;EACA;EACA;EACA;EACA,eAAe,CAAC;GAAE,MAAM;GAAY,KAAK;EAAY,CAAC;EACtD,oBAAoB;EACpB;EACA;CACF;AACF;;AAGA,SAAgB,uBACd,QACA,YACkB;CAClB,MAAM,MAAwB,CAAC;CAC/B,KAAK,MAAM,KAAK,OAAO,SAAS;EAC9B,MAAM,cAAc,EAAE,oBAAoB,EAAE;EAI5C,IAHkB,cAAc,EAAE,cAAc,EAAE,kBAGhC,GAChB,IAAI,KACF,QACE,eACA,EAAE,MACF,UAAU,EAAE,KAAK,+EACjB,QACA,IACA,YACA,sIACA,EAAE,MACF,iGACF,CACF;OACK,IAAI,gBAAgB,KAAK,EAAE,cAAc,EAAE,gBAAgB,GAEhE,IAAI,KACF,QACE,eACA,EAAE,MACF,UAAU,EAAE,KAAK,gFAAgF,EAAE,YAAY,cAAc,EAAE,cAAc,IAC7I,QACA,IACA,YACA,2JACA,EAAE,MACF,sEACF,CACF;EAIF,IAAI,eAAe,KAAK,CAAC,EAAE,mBACzB,IAAI,KACF,QACE,mBACA,EAAE,MACF,UAAU,EAAE,KAAK,mFACjB,UACA,IACA,YACA,oHACA,EAAE,IACJ,CACF;EAIF,IAAI,EAAE,SAAS,YAAY,EAAE,oBAAoB,GAC/C,IAAI,KACF,QACE,UACA,EAAE,MACF,iBAAiB,EAAE,KAAK,YAAY,EAAE,kBAAkB,+BACxD,QACA,KACA,YACA,uMACA,EAAE,IACJ,CACF;EAIF,IAAI,EAAE,QAAQ,wBAAwB,CAAC,EAAE,kBACvC,IAAI,KACF,QACE,mBACA,EAAE,MACF,UAAU,EAAE,KAAK,OAAO,EAAE,MAAM,4DAChC,UACA,IACA,YACA,mFAAmF,EAAE,MAAM,mDAC3F,EAAE,IACJ,CACF;EAIF,IAAI,CAAC,EAAE,aACL,IAAI,KACF,QACE,gBACA,EAAE,MACF,UAAU,EAAE,KAAK,oBACjB,OACA,IACA,YACA,wGACA,EAAE,IACJ,CACF;EAIF,IAAI,CAAC,EAAE,UACL,IAAI,KACF,QACE,iBACA,EAAE,MACF,UAAU,EAAE,KAAK,8CACjB,OACA,KACA,YACA,iJACA,EAAE,IACJ,CACF;CAEJ;CACA,OAAO;AACT;AAIA,IAAa,oBAAb,MAAoE;CAClE,KAAc;CACd,cACE;CACF,YAAqB;CACrB,OAAgB;EAAE,MAAM;EAA0B,iBAAiB;CAAE;CACrE,UAAmB;CAEnB,MAAM,QAAQ,OAAyB,KAAgD;EACrF,MAAM,aAAa,IAAI,MAAM,+BAAc,IAAI,KAAK,EAAA,CAAE,YAAY;EAClE,IAAI,MACF,gBAAgB,MAAM,QAAQ,OAAO,eAAe,MAAM,oBAAoB,aAChF;EACA,OAAO,uBAAuB,OAAO,UAAU;CACjD;AACF;AAEA,MAAa,sBAAsB,IAAI,kBAAkB;;;AClYzD,MAAM,yBAAyB;CAC7B;CACA;CACA;CACA;CACA;CACA;AACF;AAEA,IAAa,YAAb,MAAuB;CACrB;CACA;CAEA,YAAY,UAA4B,CAAC,GAAG;EAC1C,KAAK,UAAU,QAAQ;EACvB,KAAK,gBAAgB,QAAQ,iBAAiB;CAChD;CAEA,MAAM,MAAM,OAAmB,OAAkC;EAC/D,MAAM,MAAM,MAAM,MAAM,OAAO,KAAK;EACpC,IAAI,CAAC,KAAK,MAAM,IAAI,cAAc,OAAO,MAAM,WAAW;EAC1D,MAAM,CAAC,OAAO,QAAQ,WAAW,UAAU,MAAM,QAAQ,IAAI;GAC3D,MAAM,MAAM,EAAE,MAAM,CAAC;GACrB,MAAM,OAAO,EAAE,MAAM,CAAC;GACtB,MAAM,UAAU,KAAK;GACrB,MAAM,OAAO,KAAK;EACpB,CAAC;EACD,OAAO,KAAK,WAAW;GAAE;GAAK;GAAO;GAAQ;GAAW;EAAO,CAAC;CAClE;CAEA,WAAW,OAA2B;EACpC,MAAM,QAAkB,CAAC;EACzB,MAAM,WAAW,MAAM,MAAM,QAC1B,MAA2C,EAAE,SAAS,KACzD;EACA,MAAM,YAAY,MAAM,MAAM,QAC3B,MAA4C,EAAE,SAAS,MAC1D;EACA,MAAM,aAAa,MAAM,MAAM,QAC5B,MAA6C,EAAE,SAAS,OAC3D;EACA,MAAM,eAAe,MAAM,MAAM,QAC9B,MAA+C,EAAE,SAAS,SAC7D;EACA,MAAM,iBAAiB,WAAW,QAC/B,SAAS,KAAK,cAAc,gBAAgB,KAAK,YAAY,cAAc,IAC9E;EAEA,MAAM,UACJ,MAAM,IAAI,SAAS,SAAS,OAAO,IAAI,MAAM,IAAI,WAAW,cAAc,KAAM;EAClF,IAAI,CAAC,SAAS,MAAM,KAAK,qCAAqC;EAE9D,MAAM,eAAe,WAAW,SAC5B,WAAW,QAAQ,KAAK,SAAS,MAAM,oBAAoB,KAAK,KAAK,GAAG,CAAC,IACzE,WAAW,SACX,KAAA;EAOJ,MAAM,gBALJ,OAAO,MAAM,IAAI,SAAS,UAAU,WAChC,QACE,MAAM,IAAI,QAAQ,QAAQ,IAAI,MAAM,IAAI,QAAQ,QAAQ,MAAM,MAAM,IAAI,QAAQ,KAClF,IACA,KAAA,MAC+B,gBAAgB;EAErD,MAAM,kBAAkB,UAAU,QAAQ,SAAS,KAAK,WAAW,OAAO,CAAC,CAAC;EAC5E,MAAM,iBAAiB,UAAU,WAAW,IAAI,IAAI,kBAAkB,UAAU;EAChF,IAAI,UAAU,WAAW,GAAG,MAAM,KAAK,wBAAwB;EAE/D,MAAM,gBACJ,MAAM,UAAU,SAChB,UAAU,QAAQ,SAAS,0BAA0B,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC;EAC5E,MAAM,eAAe,gBAAgB,IAAI,QAAQ,gBAAgB,CAAC,IAAI;EACtE,IAAI,CAAC,cAAc,MAAM,KAAK,uCAAuC;EAErE,MAAM,eAAe,aAAa,QAC/B,SAAS,OAAO,KAAK,eAAe,YAAY,KAAK,aAAa,CACrE;EACA,MAAM,cAAc,aAAa,SAC7B,aAAa,QACV,KAAK,SAAS,OAAO,KAAK,eAAe,KAAK,KAAK,IAAI,GAAG,KAAK,cAAc,CAAC,GAC/E,CACF,IAAI,aAAa,SACjB,UAAU,MAAM,SACZ,yCAAyC,KAAK,KAAK,UAAU,KAAK,IAAI,CAAC,CACzE,IACA,KACA;EACN,IAAI,CAAC,aAAa,MAAM,KAAK,sCAAsC;EAEnE,MAAM,eAAe,WAAW,QAAQ,SAAS,gBAAgB,IAAI,CAAC;EACtE,MAAM,oBAAoB,eAAe,QAAQ,SAAS,gBAAgB,IAAI,CAAC;EAC/E,MAAM,YAAY,eAAe,SAAU,kBAAkB,SAAS,IAAI,IAAK;EAC/E,IAAI,kBAAkB,QACpB,MAAM,KAAK,yBAAyB,kBAAkB,OAAO,aAAa;OACvE,IAAI,CAAC,eAAe,QAAQ,MAAM,KAAK,iCAAiC;EAE7E,MAAM,mBAAmB,WAAW,SAAS,aAAa,SAAS,WAAW,SAAS;EACvF,IAAI,kBAAkB,MAAM,KAAK,YAAY,aAAa,OAAO,6BAA6B;EAE9F,MAAM,2BACJ,gBACA,aAAa,SACb,SAAS,QAAQ,SAAS,kBAAkB,KAAK,UAAU,EAAE,CAAC,CAAC,CAAC;EAClE,MAAM,eACJ,SAAS,QAAQ,SAAS,KAAK,QAAQ,KAAK,UAAU,EAAE,CAAC,CAAC,CAAC,SAC3D,MAAM,OAAO,QAAQ,UAAU,KAAK,QAAQ,KAAK,UAAU,MAAM,OAAO,CAAC,CAAC,CAAC,CAAC;EAC9E,MAAM,mBACJ,2BAA2B,iBAAiB,IACxC,IACA,4BAA4B,2BAA2B;EAC7D,MAAM,eACJ,2BAA2B,iBAAiB,IACxC,IACA,gBAAgB,2BAA2B;EACjD,IAAI,eAAe,GAAG,MAAM,KAAK,YAAY,aAAa,iBAAiB;EAe3E,OAAO;GACL;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA,SAvBc,MAAM,OAAO,SACzB,KAAK,IACH,GAAG,MAAM,OACN,QAAQ,UAA6B,MAAM,cAAc,KAAK,CAAC,CAC/D,KAAK,UAA6B,MAAM,QAAQ,GACnD,CACF,IACA,SAAS,QAAQ,KAAK,SAAS,OAAO,KAAK,WAAW,IAAI,CAAC;GAiB7D,aAfA,MAAM,IAAI,WAAW,MAAM,IAAI,YAC3B,KAAK,IAAI,IAAI,MAAM,IAAI,UAAU,MAAM,IAAI,aAAa,GAAI,IAC5D;GAcJ;EACF;CACF;CAEA,KAAK,OAAyB;EAC5B,OAAO,kBAAkB,OAAO,KAAK,OAAO;CAC9C;CAEA,QAAgB,MAAuB;EACrC,OAAO,KAAK,cAAc,MAAM,YAAY,QAAQ,KAAK,IAAI,CAAC;CAChE;AACF;AAEA,SAAS,oBAAoB,OAAuB;CAClD,OAAO,QAAQ,IAAI,QAAQ,QAAQ,EAAE,IAAI,QAAQ,KAAK;AACxD;AAEA,SAAS,kBAAkB,MAAuB;CAChD,OAAO,qGAAqG,KAC1G,IACF;AACF;AAEA,SAAS,gBAAgB,MAAiD;CACxE,OACE,KAAK,YAAY,aAAa,QAC9B,KAAK,YAAY,YAAY,cAC7B,eAAe,KAAK,YAAY,gBAAgB,KAChD,eAAe,KAAK,YAAY,YAAY,KAC5C,KAAK,SAAS;AAElB;AAEA,SAAS,eAAe,OAAyB;CAC/C,OAAO,OAAO,UAAU,YAAY,QAAQ;AAC9C;;;;;;;;;;;;;;;;;;;;;;;AC/EA,MAAa,6BAAgE;CAC3E,QAAQ;CACR,WAAW;CACX,SAAS;AACX;AAiCA,MAAa,iCAAiC;AAE9C,MAAM,qBAAqB;AAC3B,MAAM,mBAAmB;AACzB,MAAM,uBAAuB;AAC7B,MAAM,kBAAkB;AACxB,MAAM,qBAAqB;AAC3B,MAAM,gBAAgB;AAEtB,MAAM,kBAAkB;CACtB,MAAM;CACN,sBAAsB;CACtB,UAAU,CAAC,WAAW,UAAU;CAChC,YAAY;EACV,SAAS;GAAE,MAAM;GAAU,WAAW;GAAI,WAAW;EAAI;EACzD,UAAU;GACR,MAAM;GACN,UAAU;GACV,OAAO;IACL,MAAM;IACN,sBAAsB;IACtB,UAAU;KAAC;KAAW;KAAW;KAAS;KAAY;IAAU;IAChE,YAAY;KACV,SAAS;MAAE,MAAM;MAAU,WAAW;MAAG,WAAW;KAAI;KACxD,SAAS,EAAE,MAAM,UAAU;KAC3B,OAAO;MAAE,MAAM;MAAU,SAAS;MAAG,SAAS;KAAG;KACjD,UAAU;MAAE,MAAM;MAAU,WAAW;MAAG,WAAW;KAAI;KACzD,UAAU;MAAE,MAAM;MAAU,MAAM;OAAC;OAAY;OAAS;OAAS;MAAM;KAAE;IAC3E;GACF;EACF;CACF;AACF;AAEA,SAAS,SAAS,MAAc,KAAa,OAAuB;CAClE,IAAI,KAAK,UAAU,KAAK,OAAO;CAC/B,OAAO,GAAG,KAAK,MAAM,GAAG,GAAG,EAAE,iBAAiB,KAAK,SAAS,IAAI,YAAY,MAAM;AACpF;AAEA,SAAS,YACP,OACA,MACQ;CACR,MAAM,aAAa,MAAM,YACtB,QAAQ,MAAM,EAAE,QAAQ,UAAU,KAAK,eAAe,CAAC,CACvD,KAAK,MAAM,aAAa,EAAE,KAAK,QAAQ,EAAE,SAAS,CAAC,CACnD,KAAK,MAAM;CAEd,MAAM,OAAO,MAAM,cAAc;CAEjC,OAAO;;;;;;;;;;EAUP,MAAM,YAAY;;EAElB,MAAM,gBAAgB,+BAA+B,MAAM,cAAc,mBAAmB,MAAM,uBAAuB,GAAG,QAAQ,GAAG;EACvI,MAAM,iBACL,KACE,GAAG,MACF,KAAK,IAAI,EAAE,KAAK,EAAE,KAAK,GAAG,EAAE,UAAU,SAAS,cAAc,EAAE,SAAS,MAAM,GAAG,CAAC,CAAC,CAAC,KAAK,KAAK,EAAE,KAAK,IACzG,CAAC,CACA,KAAK,IAAI,EAAE;;EAEZ,OAAO,qDAAqD,SAAS,MAAM,KAAK,cAAc,MAAM,EAAE,QAAQ,GAAG;EACjH,SAAS,YAAY,KAAK,gBAAgB,QAAQ,EAAE;;;;;;;;;;;;;;;;;;AAkBtD;;;;;;AASA,eAAsB,wBACpB,OACA,UAAuC,CAAC,GACH;CACrC,MAAM,QAAQ,KAAK,IAAI;CACvB,MAAM,aAAa,MAAM,iBAAiB;CAE1C,IAAI,eAAe,GACjB,OAAO;EACL,MAAM;EACN,SAAS;EACT,OAAO;EACP,cAAc;EACd,YAAY;EACZ,UAAU,CAAC;EACX,SAAS;EACT,YAAY;EACZ,SAAS;EACT,WAAW;EACX,OAAO;CACT;CAGF,MAAM,OAA8C;EAClD,OAAO,QAAQ,SAAS;EACxB,WAAW,QAAQ,aAAa;EAChC,WAAW,QAAQ,aAAa;EAChC,gBAAgB,QAAQ,kBAAkB;EAC1C,iBAAiB,QAAQ,mBAAmB;EAC5C,cAAc,QAAQ,gBAAgB;EACtC,KAAK,QAAQ,OAAO,CAAC;EACrB,YAAY,QAAQ,cAAc,IAAI,WAAW;EACjD,WAAW,QAAQ,aAAa;EAChC,UAAU,QAAQ,YAAY,CAAC;EAC/B,QAAQ,QAAQ,UAAU,IAAI,gBAAgB,CAAC,CAAC;EAChD,gBAAgB,QAAQ,kBAAkB;EAC1C,mBAAmB;GAAE,GAAG;GAA4B,GAAI,QAAQ,qBAAqB,CAAC;EAAG;CAC3F;CAMA,MAAM,oBAAoB,SAA8B;EACtD,IAAI,KAAK,mBAAmB,QAAQ,OAAO;EAC3C,IAAI,KAAK,UAAU,MAAM,OAAO,KAAK;EACrC,IAAI,KAAK,mBAAmB,cAC1B,OAAO,KAAK,kBAAkB,KAAK,cAAc,aAAa;EAEhE,OAAO;CACT;CACA,MAAM,eAAe,IAAI,IACvB,MAAM,iBAAiB,KAAK,MAAM,CAAC,EAAE,MAAM,iBAAiB,CAAC,CAAC,CAAC,CACjE;CAEA,IAAI;CACJ,IAAI;EACF,MAAM,UAAU;GACd,OAAO,KAAK;GACZ,UAAU,CACR;IACE,MAAM;IACN,SACE;GACJ,GACA;IAAE,MAAM;IAAiB,SAAS,YAAY,OAAO,IAAI;GAAE,CAC7D;GACA,YAAY;IAAE,MAAM;IAA0B,QAAQ;GAAgB;GACtE,aAAa;GACb,WAAW,KAAK;GAChB,WAAW,KAAK;EAClB;EACA,MAAM,OAAO,MAAM,KAAK,WAAW,YAAY;GAC7C,SAAS;GACT,OAAO,KAAK;GACZ,OAAO;GACP,OAAO,KAAK;GACZ,GAAI,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,SAAS,IAAI,EAAE,MAAM,KAAK,SAAS,IAAI,CAAC;GACvE,eAAe,2BAA2B,SAAS,KAAK,GAAG;GAC3D,QAAQ,KAAK;GACb,UAAU,QAAQ,WAChB,YAA6D,SAAS;IACpE,GAAG,KAAK;IACR;IACA,gBAAgB;GAClB,CAAC;GACH,UAAU,EAAE,aAAa,mBAAmB,MAAM;GAClD,kBAAkB;EACpB,CAAC;EACD,UAAU,KAAK;EACf,IAAI,CAAC,KAAK,WAAW,MAAM,KAAK;EAChC,MAAM,EAAE,UAAU,KAAK;EAEvB,IAAI,CAAC,OAAO,YAAY,CAAC,MAAM,QAAQ,MAAM,QAAQ,GACnD,MAAM,IAAI,MAAM,uEAAqE;EAGvF,MAAM,WAA6B,MAAM,SAAS,KAAK,OAAO;GAC5D,SAAS,OAAO,EAAE,OAAO;GACzB,SAAS,QAAQ,EAAE,OAAO;GAC1B,OAAO,KAAK,IAAI,GAAG,KAAK,IAAI,IAAI,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC;GACrD,UAAU,OAAO,EAAE,YAAY,EAAE;GACjC,UAAW;IAAC;IAAY;IAAS;IAAS;GAAM,CAAC,CAAW,SAAS,EAAE,QAAQ,IAC3E,EAAE,WACF;EACN,EAAE;EAEF,MAAM,eAAe,SAAS,QAAQ,MAAM,EAAE,WAAW,EAAE,SAAS,CAAC,CAAC,CAAC;EACvE,IAAI,YAAY;EAChB,IAAI,mBAAmB;EACvB,KAAK,MAAM,KAAK,UAAU;GACxB,MAAM,IAAI,aAAa,IAAI,EAAE,OAAO,KAAK;GACzC,aAAa;GACb,oBAAoB,IAAI,EAAE;EAC5B;EACA,MAAM,WACJ,YAAY,IACR,mBAAmB,YACnB,SAAS,QAAQ,GAAG,MAAM,IAAI,EAAE,OAAO,CAAC,IAAI,KAAK,IAAI,GAAG,SAAS,MAAM;EAE7E,OAAO;GACL,MAAM;GACN,SAAS;GACT,OAAO,QAAQ,WAAW,GAAA,CAAI,QAAQ,CAAC,CAAC;GACxC;GACA;GACA;GACA,SAAS,OAAO,MAAM,WAAW,EAAE;GACnC,YAAY,KAAK,IAAI,IAAI;GACzB,SAAS,KAAK,QAAQ,cAAc,OAAO,KAAK,QAAQ;GACxD,WAAW;EACb;CACF,SAAS,KAAK;EACZ,OAAO;GACL,MAAM;GACN,SAAS;GACT,OAAO;GACP,cAAc;GACd;GACA,UAAU,CAAC;GACX,SAAS;GACT,YAAY,KAAK,IAAI,IAAI;GACzB,SAAS,WAAW,CAAC,QAAQ,cAAc,QAAQ,UAAU;GAC7D,WAAW;GACX,OAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;EACxD;CACF;AACF;;;;;AAMA,SAAgB,2BACd,UAAuC,CAAC,GACmC;CAC3E,QAAQ,UAAU,wBAAwB,OAAO,OAAO;AAC1D"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"skill-usage-CFDLLlhF.d.ts","names":[],"sources":["../src/run-score.ts","../src/run-critic.ts","../src/semantic-concept-judge.ts","../src/analyst/ax-service.ts","../src/analyst/finding-subject.ts","../src/analyst/findings-store.ts","../src/analyst/kinds/control-integrity.ts","../src/analyst/kinds/failure-mode.ts","../src/analyst/kinds/improvement.ts","../src/analyst/kinds/knowledge-gap.ts","../src/analyst/kinds/knowledge-poisoning.ts","../src/analyst/kinds/index.ts","../src/analyst/kinds/skill-usage.ts"],"mappings":"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"}
|