@tangle-network/agent-eval 0.133.1 → 0.133.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +165 -0
- package/dist/{analyze-runs-DZr7JW-m.d.ts → analyze-runs-BClW9OSe.d.ts} +3 -3
- package/dist/{analyze-runs-DZr7JW-m.d.ts.map → analyze-runs-BClW9OSe.d.ts.map} +1 -1
- package/dist/{analyze-runs-B-afTpCv.js → analyze-runs-qk8op0tN.js} +63 -42
- package/dist/analyze-runs-qk8op0tN.js.map +1 -0
- package/dist/baseline-BaPxoROc.js +149 -0
- package/dist/baseline-BaPxoROc.js.map +1 -0
- package/dist/{baseline-hG3K85h4.d.ts → baseline-D_fT6277.d.ts} +43 -11
- package/dist/baseline-D_fT6277.d.ts.map +1 -0
- package/dist/benchmarks/index.d.ts +1 -1
- package/dist/benchmarks/index.js +1 -1
- package/dist/{benchmarks-BU7P6PCW.js → benchmarks-BP9sgMia.js} +3 -3
- package/dist/{benchmarks-BU7P6PCW.js.map → benchmarks-BP9sgMia.js.map} +1 -1
- package/dist/builder-eval/index.js +1 -1
- package/dist/campaign/index.d.ts +2 -2
- package/dist/campaign/index.js +2 -2
- package/dist/{campaign-CnzHQndg.js → campaign--V4ffEKR.js} +12 -6
- package/dist/{campaign-CnzHQndg.js.map → campaign--V4ffEKR.js.map} +1 -1
- package/dist/{client-D4F9hdzR.d.ts → client-Du7B81wW.d.ts} +28 -14
- package/dist/client-Du7B81wW.d.ts.map +1 -0
- package/dist/{client-CYzbdJOZ.js → client-LIuo-KPv.js} +19 -7
- package/dist/client-LIuo-KPv.js.map +1 -0
- package/dist/contract/index.d.ts +3 -3
- package/dist/contract/index.d.ts.map +1 -1
- package/dist/contract/index.js +9 -8
- package/dist/contract/index.js.map +1 -1
- package/dist/{eval-campaign-DXhpZghy.js → eval-campaign-CvPcvqXC.js} +2 -2
- package/dist/{eval-campaign-DXhpZghy.js.map → eval-campaign-CvPcvqXC.js.map} +1 -1
- package/dist/hosted/index.d.ts +1 -1
- package/dist/hosted/index.d.ts.map +1 -1
- package/dist/hosted/index.js +1 -1
- package/dist/index-3cdlURSk.d.ts.map +1 -1
- package/dist/{index-Wek5mU0y.d.ts → index-B5MNN1f1.d.ts} +3 -3
- package/dist/{index-Wek5mU0y.d.ts.map → index-B5MNN1f1.d.ts.map} +1 -1
- package/dist/{index-Ba636PKl.d.ts → index-DOqvIJ8I.d.ts} +27 -10
- package/dist/index-DOqvIJ8I.d.ts.map +1 -0
- package/dist/{index-DSC51roc.d.ts → index-DSC51roc2.d.ts} +1 -1
- package/dist/index-DSC51roc2.d.ts.map +1 -0
- package/dist/{index-nhIYz9hn.d.ts → index-DuhJaaiH.d.ts} +68 -7
- package/dist/index-DuhJaaiH.d.ts.map +1 -0
- package/dist/index.d.ts +56 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +39 -22
- package/dist/index.js.map +1 -1
- package/dist/ledger-core/index.d.ts +2 -2
- package/dist/ledger-core/index.js +2 -2
- package/dist/{ledger-core-CPZfcrC2.js → ledger-core-DAKFKRzi.js} +136 -18
- package/dist/ledger-core-DAKFKRzi.js.map +1 -0
- package/dist/matrix/index.d.ts +1 -1
- package/dist/meta-eval/index.d.ts +1 -1
- package/dist/meta-eval/index.js +2 -2
- package/dist/multishot/index.d.ts +1 -1
- package/dist/openapi.json +1 -1
- package/dist/{opencode-sqlite-BGrHeDu3.js → opencode-sqlite-8r6WUfHc.js} +2 -3
- package/dist/opencode-sqlite-8r6WUfHc.js.map +1 -0
- package/dist/{paired-arms-6XItKzd1.js → paired-arms-CA_8pN01.js} +2 -2
- package/dist/{paired-arms-6XItKzd1.js.map → paired-arms-CA_8pN01.js.map} +1 -1
- package/dist/pipelines/index.d.ts +1 -1
- package/dist/pipelines/index.js +3 -2
- package/dist/pipelines/index.js.map +1 -1
- package/dist/{release-report-wuilQkvK.js → release-report-BVZBmRZp.js} +2 -2
- package/dist/{release-report-wuilQkvK.js.map → release-report-BVZBmRZp.js.map} +1 -1
- package/dist/{release-report-DfmKSIEE.d.ts → release-report-DKBtegGt.d.ts} +2 -2
- package/dist/{release-report-DfmKSIEE.d.ts.map → release-report-DKBtegGt.d.ts.map} +1 -1
- package/dist/reporting.d.ts +3 -3
- package/dist/reporting.js +4 -4
- package/dist/{researcher-DMimgHtN.d.ts → researcher-BtD5U1Up.d.ts} +2 -2
- package/dist/{researcher-DMimgHtN.d.ts.map → researcher-BtD5U1Up.d.ts.map} +1 -1
- package/dist/{reward-hacking-Dl2UBzej.js → reward-hacking-DCdRK9TY.js} +2 -2
- package/dist/{reward-hacking-Dl2UBzej.js.map → reward-hacking-DCdRK9TY.js.map} +1 -1
- package/dist/rl.d.ts +1 -1
- package/dist/rl.js +4 -4
- package/dist/rollout/index.js +2 -2
- package/dist/{rollout-CeTlDrf6.js → rollout-CreDz__7.js} +2 -2
- package/dist/{rollout-CeTlDrf6.js.map → rollout-CreDz__7.js.map} +1 -1
- package/dist/{rubric-predictive-validity-QG7ydk0s.js → rubric-predictive-validity-D6Q6n9oq.js} +2 -2
- package/dist/{rubric-predictive-validity-QG7ydk0s.js.map → rubric-predictive-validity-D6Q6n9oq.js.map} +1 -1
- package/dist/{skillopt-optimization-method-CAASpcS3.d.ts → skillopt-optimization-method-Dxr8pdZd.d.ts} +12 -7
- package/dist/{skillopt-optimization-method-CAASpcS3.d.ts.map → skillopt-optimization-method-Dxr8pdZd.d.ts.map} +1 -1
- package/dist/{skillopt-optimization-method-BoIzh7Dl.js → skillopt-optimization-method-vvJ4bMNI.js} +123 -24
- package/dist/skillopt-optimization-method-vvJ4bMNI.js.map +1 -0
- package/dist/{statistics-DbvkkDPa.d.ts → statistics-D_4Snl-5.d.ts} +158 -30
- package/dist/statistics-D_4Snl-5.d.ts.map +1 -0
- package/dist/{statistics-DWM_AyLe.js → statistics-RwRNu2__.js} +546 -98
- package/dist/statistics-RwRNu2__.js.map +1 -0
- package/dist/{summary-report-Ci17nIdU.js → summary-report-BxtossFi.js} +3 -3
- package/dist/{summary-report-Ci17nIdU.js.map → summary-report-BxtossFi.js.map} +1 -1
- package/dist/{summary-report-DnUcjVpV.d.ts → summary-report-DyOhItws.d.ts} +4 -3
- package/dist/summary-report-DyOhItws.d.ts.map +1 -0
- package/dist/supervisor-run/index.js +1 -1
- package/dist/{supervisor-run-_lnTLM3z.js → supervisor-run-B7lUGoyZ.js} +2 -2
- package/dist/{supervisor-run-_lnTLM3z.js.map → supervisor-run-B7lUGoyZ.js.map} +1 -1
- package/dist/{baseline-DcX5hQDv.js → tool-use-metrics-DEGMKycK.js} +2 -114
- package/dist/tool-use-metrics-DEGMKycK.js.map +1 -0
- package/docs/design/statistics-decisions.md +271 -0
- package/docs/design.md +1 -0
- package/docs/insight-report.md +1 -1
- package/docs/research-report-methodology.md +4 -1
- package/package.json +2 -1
- package/dist/analyze-runs-B-afTpCv.js.map +0 -1
- package/dist/baseline-DcX5hQDv.js.map +0 -1
- package/dist/baseline-hG3K85h4.d.ts.map +0 -1
- package/dist/client-CYzbdJOZ.js.map +0 -1
- package/dist/client-D4F9hdzR.d.ts.map +0 -1
- package/dist/index-Ba636PKl.d.ts.map +0 -1
- package/dist/index-DSC51roc.d.ts.map +0 -1
- package/dist/index-nhIYz9hn.d.ts.map +0 -1
- package/dist/ledger-core-CPZfcrC2.js.map +0 -1
- package/dist/opencode-sqlite-BGrHeDu3.js.map +0 -1
- package/dist/skillopt-optimization-method-BoIzh7Dl.js.map +0 -1
- package/dist/statistics-DWM_AyLe.js.map +0 -1
- package/dist/statistics-DbvkkDPa.d.ts.map +0 -1
- package/dist/summary-report-DnUcjVpV.d.ts.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reward-hacking-Dl2UBzej.js","names":["mean","clamp01"],"sources":["../src/campaign/run-record.ts","../src/rl/verifiable-reward.ts","../src/rl/reward-hacking.ts"],"sourcesContent":["import type { AgentProfileCell } from '../agent-profile-cell'\nimport type {\n JudgeScoresRecord,\n RunOutcome,\n RunRecord,\n RunSplitTag,\n RunTerminalOutcome,\n} from '../run-record'\nimport { validateRunRecord } from '../run-record'\nimport type { CampaignCellResult, JudgeScore } from './types'\n\nexport interface CampaignCellRunRecordOptions {\n runId: string\n experimentId: string\n candidateId: string\n model: string\n promptHash: string\n configHash: string\n commitSha: string\n splitTag: RunSplitTag\n seed?: number\n scenarioId?: string\n defaultCostUsd?: number\n agentProfile?: AgentProfileCell\n raw?: Record<string, number>\n}\n\nexport interface CampaignCellQualityProjection {\n score?: number\n judgeScores?: JudgeScoresRecord\n successfulJudgeScores: Record<string, JudgeScore>\n failedJudges: string[]\n raw: Record<string, number>\n}\n\nexport interface CampaignCellExecutionEvidence {\n terminalOutcome: RunTerminalOutcome\n executionErrorCount?: number\n judgeErrorCount?: number\n unclassifiedErrorCount?: number\n terminalFailureReason?: string\n}\n\n/**\n * Project one campaign cell into the canonical run format.\n *\n * A dispatch error establishes terminal execution failure. A judge error only\n * establishes that quality measurement failed after dispatch completed.\n * Failures without a stage remain unknown. No failure becomes a zero-quality\n * label.\n */\nexport function campaignCellToRunRecord<TArtifact>(\n cell: CampaignCellResult<TArtifact>,\n options: CampaignCellRunRecordOptions,\n): RunRecord {\n const quality = projectCampaignCellQuality(cell)\n const execution = campaignCellExecutionEvidence(cell)\n const judgeErrorCount = Math.max(\n quality.raw.judge_error_count ?? 0,\n execution.judgeErrorCount ?? 0,\n )\n const cellCostCaptured = Number.isFinite(cell.costUsd) && cell.costUsd >= 0\n const costUsd = cellCostCaptured ? cell.costUsd : (options.defaultCostUsd ?? null)\n const costProvenance =\n costUsd === null\n ? ({ kind: 'uncaptured', usd: null } as const)\n : cellCostCaptured && !cell.costEstimated\n ? ({ kind: 'observed', usd: costUsd } as const)\n : ({ kind: 'estimated', usd: costUsd } as const)\n const raw: Record<string, number> = {\n ...finiteMetrics(options.raw),\n ...quality.raw,\n rep: cell.rep,\n duration_ms: cell.durationMs,\n ...(costUsd === null ? {} : { cost_usd: costUsd }),\n cost_estimated: cell.costEstimated ? 1 : 0,\n tokens_input: cell.tokenUsage.input,\n tokens_output: cell.tokenUsage.output,\n latency_ms: cell.durationMs,\n ...(execution.executionErrorCount === undefined\n ? {}\n : { execution_error_count: execution.executionErrorCount }),\n ...(judgeErrorCount > 0 ? { judge_error_count: judgeErrorCount } : {}),\n ...(execution.unclassifiedErrorCount === undefined\n ? {}\n : { unclassified_error_count: execution.unclassifiedErrorCount }),\n }\n if (typeof cell.generation === 'number') raw.generation = cell.generation\n if (cell.tokenUsage.reasoning !== undefined) {\n raw.tokens_reasoning = cell.tokenUsage.reasoning\n }\n if (cell.tokenUsage.cached !== undefined) raw.tokens_cached = cell.tokenUsage.cached\n if (cell.tokenUsage.cacheWrite !== undefined) {\n raw.tokens_cache_write = cell.tokenUsage.cacheWrite\n }\n if (costUsd !== null && costUsd > 0) {\n raw.tokens_per_dollar = (cell.tokenUsage.input + cell.tokenUsage.output) / costUsd\n }\n if (costUsd !== null && quality.score !== undefined && quality.score > 0.01) {\n raw.cost_per_quality = costUsd / quality.score\n }\n\n const outcome: RunOutcome = {\n raw,\n ...(quality.judgeScores ? { judgeScores: quality.judgeScores } : {}),\n }\n if (quality.score !== undefined) {\n if (options.splitTag === 'holdout') outcome.holdoutScore = quality.score\n else outcome.searchScore = quality.score\n }\n\n return validateRunRecord({\n runId: options.runId,\n experimentId: options.experimentId,\n candidateId: options.candidateId,\n seed: options.seed ?? cell.seed,\n model: options.model,\n promptHash: options.promptHash,\n configHash: options.configHash,\n commitSha: options.commitSha,\n wallMs: cell.durationMs,\n costUsd,\n costProvenance,\n tokenUsage: { ...cell.tokenUsage },\n terminalOutcome: execution.terminalOutcome,\n ...(execution.terminalFailureReason\n ? { terminalFailureReason: execution.terminalFailureReason }\n : {}),\n outcome,\n splitTag: options.splitTag,\n scenarioId: options.scenarioId ?? cell.scenarioId,\n ...(options.agentProfile ? { agentProfile: options.agentProfile } : {}),\n })\n}\n\nexport function campaignCellExecutionEvidence<TArtifact>(\n cell: CampaignCellResult<TArtifact>,\n): CampaignCellExecutionEvidence {\n if (cell.errorStage === 'dispatch') {\n return {\n terminalOutcome: 'failed',\n executionErrorCount: 1,\n ...(cell.error ? { terminalFailureReason: cell.error } : {}),\n }\n }\n if (cell.errorStage === 'judge') {\n return {\n terminalOutcome: 'succeeded',\n executionErrorCount: 0,\n judgeErrorCount: 1,\n }\n }\n if (!cell.error) {\n return { terminalOutcome: 'succeeded', executionErrorCount: 0 }\n }\n return {\n terminalOutcome: 'unknown',\n unclassifiedErrorCount: 1,\n }\n}\n\n/**\n * Produce the only task-quality view used by campaign aggregates and exports.\n *\n * Successful judge results remain available for diagnosis after another judge\n * fails, but a task score exists only for an error-free cell whose reported\n * judge values are all finite.\n */\nexport function projectCampaignCellQuality<TArtifact>(\n cell: CampaignCellResult<TArtifact>,\n): CampaignCellQualityProjection {\n if (cell.errorStage === 'dispatch') {\n return { successfulJudgeScores: {}, failedJudges: [], raw: {} }\n }\n\n const perJudge: Record<string, Record<string, number>> = {}\n const successfulJudgeScores: Record<string, JudgeScore> = {}\n const dimensionValues = new Map<string, number[]>()\n const composites: number[] = []\n const notes: string[] = []\n const failedJudges = new Set<string>(\n cell.errorStage === 'judge' ? [cell.errorJudge ?? 'unknown-judge'] : [],\n )\n const raw: Record<string, number> = {}\n\n for (const [judgeName, score] of Object.entries(cell.judgeScores)) {\n const finiteDimensions = Object.values(score.dimensions).every(Number.isFinite)\n if (score.failed || !Number.isFinite(score.composite) || !finiteDimensions) {\n failedJudges.add(judgeName)\n continue\n }\n\n composites.push(score.composite)\n successfulJudgeScores[judgeName] = score\n const dimensions = { ...score.dimensions }\n perJudge[judgeName] = dimensions\n for (const [dimension, value] of Object.entries(dimensions)) {\n raw[`${judgeName}.${dimension}`] = value\n const values = dimensionValues.get(dimension) ?? []\n values.push(value)\n dimensionValues.set(dimension, values)\n }\n if (score.notes) notes.push(`${judgeName}: ${score.notes}`)\n for (const failedJudge of score.failedJudges ?? []) {\n failedJudges.add(`${judgeName}/${failedJudge}`)\n }\n }\n\n if (failedJudges.size > 0) raw.judge_error_count = failedJudges.size\n const sortedFailedJudges = [...failedJudges].sort()\n if (composites.length === 0) {\n return {\n successfulJudgeScores,\n failedJudges: sortedFailedJudges,\n raw,\n }\n }\n\n const composite = mean(composites)\n const perDimMean = Object.fromEntries(\n [...dimensionValues.entries()].map(([dimension, values]) => [dimension, mean(values)]),\n )\n const complete =\n cell.error === undefined && cell.errorStage === undefined && failedJudges.size === 0\n if (complete) raw.composite = composite\n\n return {\n ...(complete ? { score: composite } : {}),\n raw,\n successfulJudgeScores,\n failedJudges: sortedFailedJudges,\n judgeScores: {\n perJudge,\n perDimMean,\n composite,\n ...(sortedFailedJudges.length > 0 ? { failedJudges: sortedFailedJudges } : {}),\n ...(notes.length > 0 ? { notes: notes.join(' | ') } : {}),\n },\n }\n}\n\n/** Read the canonical task score without recomputing cell quality. */\nexport function campaignCellTaskScore<TArtifact>(\n cell: CampaignCellResult<TArtifact>,\n): number | undefined {\n return projectCampaignCellQuality(cell).score\n}\n\n/** Read canonical successful judge dimensions without recomputing cell quality. */\nexport function campaignCellJudgeDimensions<TArtifact>(\n cell: CampaignCellResult<TArtifact>,\n): Record<string, Record<string, number>> {\n return projectCampaignCellQuality(cell).judgeScores?.perJudge ?? {}\n}\n\nfunction finiteMetrics(metrics: Record<string, number> | undefined): Record<string, number> {\n const finite: Record<string, number> = {}\n for (const [key, value] of Object.entries(metrics ?? {})) {\n if (Number.isFinite(value)) finite[key] = value\n }\n return finite\n}\n\nfunction mean(values: number[]): number {\n return values.reduce((sum, value) => sum + value, 0) / values.length\n}\n","/**\n * Verifiable reward channel.\n *\n * For RL on coding / math / theorem-proving / structured-output tasks, the\n * reward signal is *decidable* — a test passes or fails, a proof checks or\n * doesn't, an output validates against a schema or doesn't. These rewards\n * are dramatically more useful for RL training than LLM-judge scores\n * because they don't drift, can't be Goodhart-gamed by the policy in the\n * same way, and don't require a separate calibration loop.\n *\n * The `MultiLayerVerifier` already produces this signal — it just doesn't\n * surface it in a shape that's clean enough for RL training. This module\n * wraps the verifier output so consumers can:\n *\n * 1. Extract a clean `VerifiableReward` from a `VerificationReport`\n * 2. Distinguish *deterministic* rewards (compile, test, schema) from\n * *probabilistic* rewards (judge) so they can be weighted differently\n * in the RL training step\n * 3. Filter `RunRecord[]` to only those with a verifiable reward,\n * producing the clean training set that DeepSeek-R1-style GRPO and\n * AlphaProof-style search both depend on\n *\n * Why this matters: every credible 2025-2026 frontier RL result on coding\n * agents leans on verifiable reward (DeepSeek-R1 GRPO on test pass-rate,\n * o-series RL on math/code, AlphaProof on Lean kernel checking). Mixing\n * judge scores into the reward signal poisons the gradient. This module\n * is the seam.\n */\n\nimport type { LayerResult, VerificationReport } from '../multi-layer-verifier'\nimport { isRealnessGated, observedScore, trainingScore } from '../rollout/reward'\nimport type { RunRecord } from '../run-record'\n\nexport type VerifiableRewardSource =\n | 'compile' // typecheck / build / lint passed\n | 'test' // unit / integration test pass-rate\n | 'schema' // structured output validates\n | 'sandbox' // sandbox exec exit code\n | 'judge' // LLM judge — probabilistic, included for completeness\n | 'composite' // weighted blend across multiple of the above\n\nexport interface VerifiableReward {\n /** Scalar in [0, 1]. The RL training signal. */\n value: number\n /** What produced the reward — different sources have different determinism. */\n source: VerifiableRewardSource\n /**\n * Determinism class. `'deterministic'` rewards are repeatable byte-for-byte\n * given the same inputs (compile, test, schema validation, sandbox exit code).\n * `'probabilistic'` rewards depend on a stochastic component (LLM judge).\n * Mixing these in the same training batch without separation is a known\n * footgun in production RLHF pipelines.\n */\n determinism: 'deterministic' | 'probabilistic'\n /**\n * Confidence in the reward value. For deterministic sources this is 1.0\n * (the bit either flipped or didn't). For judge sources this is the\n * judge-reported confidence or — when missing — a calibrated prior.\n */\n confidence: number\n /** The layer / judge id that produced the signal, for provenance. */\n origin: string\n /**\n * Per-source contribution to `value`, keyed by layer/judge id. Single-source\n * rewards carry one entry (`{ [origin]: value }`); composite rewards carry\n * every contributing layer's score — the anti-scalar-collapse surface RL\n * consumers weight per-source instead of trusting one blended number.\n */\n components: Record<string, number>\n /**\n * The run carries `outcome.realness.gated` — the authenticity gate flagged\n * its success signal as faked.\n *\n * With the gate applied (the default) `value` and every `components` entry\n * are 0 on such a run; with `applyRealnessGate: false` the observed numbers\n * come back untouched and this flag is the only marker that they are not to\n * be trusted. Either way it distinguishes \"measured a genuine failure\" from\n * \"claimed a success we refuse to believe\", which a bare 0 cannot.\n */\n realnessGated?: boolean\n /**\n * Whether an authenticity screen COULD run on this reward at all — the same\n * distinction `RolloutOutcome.realness_screened` draws, for the same reason.\n *\n * `false` on every reward from `extractVerifiableReward`, because a\n * `VerificationReport` carries layer scores and nothing else: there is no\n * `outcome.realness` to consult, so no gate has run, and `realnessGated`\n * being absent there means \"unknown\", NOT \"clean\". Absent on the\n * `RunRecord` path when the record itself carries no realness verdict.\n *\n * This matters most exactly where it is easiest to miss: a report whose\n * deterministic layers all passed yields `determinism: 'deterministic'`,\n * `confidence: 1` — the highest-credibility reward this module can emit —\n * and a stubbed integration reporting green is precisely what a gamed run\n * looks like. Consumers driving training off this shape must screen the run\n * themselves; the flag is what tells them nobody has.\n */\n realnessScreened?: boolean\n}\n\nexport interface VerifiableRewardExtractionOptions {\n /**\n * Which layers count as deterministic-reward sources. The verifier doesn't\n * tag layers as \"this is verifiable\"; the caller declares it via this list\n * (or via the layer name → source mapping). Default treats common names\n * (`install`, `typecheck`, `build`, `lint`, `test`, `compile`, `schema`,\n * `sandbox`) as deterministic.\n */\n deterministicLayers?: string[]\n /**\n * Map layer name → reward source. Defaults to a sensible string-match.\n */\n sourceFor?: (layerName: string) => VerifiableRewardSource\n /**\n * Whether to fall back to a probabilistic (judge) reward when no\n * deterministic layer produced a numeric score. Default `true`. Set to\n * `false` for \"deterministic-only\" training pipelines that should\n * discard runs without a verifiable signal.\n */\n fallbackToJudge?: boolean\n /**\n * Default confidence for probabilistic (judge) rewards when the judge\n * doesn't report one. Default `0.7`.\n */\n judgeConfidenceFloor?: number\n /**\n * Whether the anti-Goodhart realness gate applies. Default `true`, and the\n * default is the one every training path must keep.\n *\n * Set `false` ONLY for detection and analysis. `rl/reward-hacking.ts` does,\n * for the same reason it reads `observedScore` for its proxy: it measures the\n * DIVERGENCE between the judge signal and the deterministic one, and a\n * deterministic reward that another gate already forced to 0 manufactures\n * exactly that divergence on exactly the gamed population. The detector would\n * then be re-reporting a verdict it was supposed to reach independently.\n */\n applyRealnessGate?: boolean\n}\n\nconst DEFAULT_DETERMINISTIC_LAYERS = new Set([\n 'install',\n 'typecheck',\n 'build',\n 'lint',\n 'test',\n 'compile',\n 'schema',\n 'sandbox',\n 'unit_tests',\n 'integration_tests',\n])\n\nconst DEFAULT_SOURCE_FOR = (name: string): VerifiableRewardSource => {\n const lower = name.toLowerCase()\n if (lower.includes('test')) return 'test'\n if (\n lower.includes('compile') ||\n lower.includes('build') ||\n lower.includes('typecheck') ||\n lower.includes('lint')\n )\n return 'compile'\n if (lower.includes('schema')) return 'schema'\n if (lower.includes('sandbox')) return 'sandbox'\n if (lower.includes('judge') || lower.includes('semantic')) return 'judge'\n return 'composite'\n}\n\n/**\n * Extract a `VerifiableReward` from a `VerificationReport`.\n *\n * Strategy: prefer the deterministic layers (in order: test → compile →\n * schema → sandbox), fall back to the judge layer if `fallbackToJudge` is\n * true, return `null` if no signal qualifies. When multiple deterministic\n * layers contribute, return a `'composite'` source with a weighted blend.\n *\n * NO realness gate is applied and none can be: a `VerificationReport` carries\n * layer scores and nothing about whether the run faked them — `realness` lives\n * on the `RunRecord`. Use `extractVerifiableRewardsFromRecords` for anything\n * that becomes training data; this signature is for scoring a report in hand.\n */\nexport function extractVerifiableReward(\n report: VerificationReport,\n opts: VerifiableRewardExtractionOptions = {},\n): VerifiableReward | null {\n const deterministicSet = new Set(opts.deterministicLayers ?? [...DEFAULT_DETERMINISTIC_LAYERS])\n const sourceFor = opts.sourceFor ?? DEFAULT_SOURCE_FOR\n const fallbackToJudge = opts.fallbackToJudge ?? true\n const judgeFloor = opts.judgeConfidenceFloor ?? 0.7\n\n const deterministic = report.layers.filter(\n (layer) => deterministicSet.has(layer.layer) && isMeasuredLayer(layer),\n )\n\n if (deterministic.length === 1) {\n const layer = deterministic[0]!\n const value = clamp01(layer.score!)\n return {\n value,\n source: sourceFor(layer.layer),\n determinism: 'deterministic',\n confidence: 1,\n origin: layer.layer,\n components: { [layer.layer]: value },\n realnessScreened: false,\n }\n }\n\n if (deterministic.length > 1) {\n // Composite: weighted blend by `Layer.weight` if present, else equal.\n let num = 0\n let denom = 0\n const components: Record<string, number> = {}\n for (const l of deterministic) {\n const w = (l.detail?.weight as number | undefined) ?? 1\n num += w * (l.score ?? 0)\n denom += w\n components[l.layer] = l.score!\n }\n return {\n value: denom === 0 ? 0 : clamp01(num / denom),\n source: 'composite',\n determinism: 'deterministic',\n confidence: 1,\n origin: deterministic.map((l) => l.layer).join('+'),\n components,\n realnessScreened: false,\n }\n }\n\n if (!fallbackToJudge) return null\n\n const judge =\n report.layers.find((layer) => isMeasuredLayer(layer) && sourceFor(layer.layer) === 'judge') ??\n report.layers.find(isMeasuredLayer)\n\n if (!judge) return null\n\n const confFromDetail = judge.detail?.confidence as number | undefined\n const judgeValue = clamp01(judge.score!)\n return {\n value: judgeValue,\n source: 'judge',\n determinism: 'probabilistic',\n confidence: typeof confFromDetail === 'number' ? confFromDetail : judgeFloor,\n origin: judge.layer,\n components: { [judge.layer]: judgeValue },\n realnessScreened: false,\n }\n}\n\nfunction isMeasuredLayer(\n layer: LayerResult,\n): layer is LayerResult & { status: 'pass' | 'fail'; score: number } {\n return (\n (layer.status === 'pass' || layer.status === 'fail') &&\n typeof layer.score === 'number' &&\n Number.isFinite(layer.score) &&\n layer.score >= 0 &&\n layer.score <= 1\n )\n}\n\n/**\n * Extract verifiable rewards from `RunRecord[]` produced via the\n * `verificationReportToRunRecord` adapter (which encodes per-layer scores\n * in `outcome.raw['layer.<name>']`). For records that don't carry layer\n * scores, returns `null` for that record.\n *\n * This is the canonical bridge from \"campaign-shaped artifacts\" to\n * \"RL-training-ready reward signals\": every record that has a clean\n * verifiable reward becomes a training datum, every record that doesn't\n * gets filtered out (or kept with `'probabilistic'` determinism for\n * separate downstream handling).\n *\n * The realness gate applies to EVERY channel here, and to the deterministic one\n * MOST. It is tempting to reason that a decidable signal cannot be gamed, so\n * the gate is redundant on it — that reasoning is backwards. `realness.gated`\n * means the run's success signal was FAKED, and a test suite reporting green on\n * a stubbed integration is precisely what that looks like: the deterministic\n * layer is the thing that got faked. Exporting it ungated hands a trainer the\n * highest-credibility reward the module can emit (`determinism: 'deterministic'`,\n * `confidence: 1`) for the one population the gate exists to catch. Pass\n * `applyRealnessGate: false` only to look at the ungated numbers for detection.\n */\nexport function extractVerifiableRewardsFromRecords(\n runs: RunRecord[],\n opts: VerifiableRewardExtractionOptions = {},\n): Array<{ runId: string; reward: VerifiableReward | null }> {\n const sourceFor = opts.sourceFor ?? DEFAULT_SOURCE_FOR\n const deterministicSet = new Set(opts.deterministicLayers ?? [...DEFAULT_DETERMINISTIC_LAYERS])\n const fallbackToJudge = opts.fallbackToJudge ?? true\n const judgeFloor = opts.judgeConfidenceFloor ?? 0.7\n const applyGate = opts.applyRealnessGate ?? true\n\n return runs.map((run) => {\n const flagged = isRealnessGated(run)\n // Present only when the record carries an actual realness verdict. Absent\n // is the honest \"unknown\"; `false` is reserved for a producer that\n // declares it HAS no screen, which is the report-shaped path above.\n const screened = run.outcome.realness === undefined ? {} : ({ realnessScreened: true } as const)\n // Zeroed with `value`, never left at the measured number: `components`\n // exists so an RL consumer can re-weight per source, and a raw layer score\n // surviving there would let that re-weighting reconstruct the very reward\n // the gate just refused. The measured layer scores stay on\n // `run.outcome.raw['layer.*']`, which is where analysis reads them.\n const gate = (value: number): number => (applyGate && flagged ? 0 : value)\n // Recover per-layer scores from outcome.raw['layer.<name>']\n const layerScores: Array<{ name: string; score: number }> = []\n for (const [k, v] of Object.entries(run.outcome.raw)) {\n if (\n k.startsWith('layer.') &&\n !k.includes('.', 6) &&\n typeof v === 'number' &&\n Number.isFinite(v)\n ) {\n layerScores.push({ name: k.slice('layer.'.length), score: v })\n }\n }\n const det = layerScores.filter((l) => deterministicSet.has(l.name))\n\n if (det.length === 1) {\n const layer = det[0]!\n const value = gate(clamp01(layer.score))\n return {\n runId: run.runId,\n reward: {\n value,\n source: sourceFor(layer.name),\n determinism: 'deterministic',\n confidence: 1,\n origin: layer.name,\n components: { [layer.name]: value },\n realnessGated: flagged,\n ...screened,\n },\n }\n }\n if (det.length > 1) {\n const value = gate(clamp01(det.reduce((s, l) => s + l.score, 0) / det.length))\n // Same clamp as the headline value: a producer writing layer.score 1.5\n // into outcome.raw must not propagate 1.5 through a component either.\n const components: Record<string, number> = Object.fromEntries(\n det.map((l) => [l.name, gate(clamp01(l.score))]),\n )\n return {\n runId: run.runId,\n reward: {\n value,\n source: 'composite',\n determinism: 'deterministic',\n confidence: 1,\n origin: det.map((l) => l.name).join('+'),\n components,\n realnessGated: flagged,\n ...screened,\n },\n }\n }\n if (!fallbackToJudge) return { runId: run.runId, reward: null }\n\n // Probabilistic fallback: the run's primary score. `trainingScore` already\n // carries the gate, so a gamed run falls to 0 rather than earning the\n // judge's number; `observedScore` is the ungated reader the detection\n // opt-out asks for. Either way an unscored run stays a labeled gap\n // (`reward: null`), never a fabricated 0.\n const primary = applyGate ? trainingScore(run) : observedScore(run)\n if (typeof primary !== 'number' || !Number.isFinite(primary)) {\n return { runId: run.runId, reward: null }\n }\n const primaryValue = clamp01(primary)\n return {\n runId: run.runId,\n reward: {\n value: primaryValue,\n source: 'judge',\n determinism: 'probabilistic',\n confidence: judgeFloor,\n origin: 'run.outcome.score',\n components: { 'run.outcome.score': primaryValue },\n realnessGated: flagged,\n ...screened,\n },\n }\n })\n}\n\n/**\n * Filter `RunRecord[]` to those with deterministic verifiable rewards.\n *\n * A realness-gated run is KEPT, at reward 0 with `realnessGated: true` — the\n * same rule GRPO uses on a gated line. 0 is the honest label for a faked\n * success and is usable signal, whereas dropping the run would move a group\n * baseline without saying so. (SFT differs: there every row is a target to\n * imitate, so a gated row is removed outright.)\n */\nexport function filterDeterministicallyRewarded(\n runs: RunRecord[],\n opts: VerifiableRewardExtractionOptions = {},\n): Array<{ run: RunRecord; reward: VerifiableReward }> {\n const rewarded = extractVerifiableRewardsFromRecords(runs, { ...opts, fallbackToJudge: false })\n const out: Array<{ run: RunRecord; reward: VerifiableReward }> = []\n for (let i = 0; i < runs.length; i++) {\n const r = rewarded[i]!\n if (r.reward && r.reward.determinism === 'deterministic') {\n out.push({ run: runs[i]!, reward: r.reward })\n }\n }\n return out\n}\n\nfunction clamp01(x: number): number {\n if (!Number.isFinite(x)) return 0\n return Math.max(0, Math.min(1, x))\n}\n","/**\n * Reward hacking / Goodhart detection.\n *\n * Goodhart's Law says: when a measure becomes a target, it ceases to be\n * a good measure. In RLHF and agentic-RL settings this is the dominant\n * failure mode — the policy learns to produce outputs that score well on\n * the proxy reward (judge, rubric, test pass-rate) without producing\n * the underlying capability the proxy was meant to track.\n *\n * Krakovna et al. (2020, \"Specification Gaming Examples in AI\") and the\n * subsequent RLHF reward-hacking literature (Skalse et al. 2022, Kim et al.\n * 2023) converge on a few diagnostic signatures:\n *\n * 1. **Reward divergence:** the proxy reward grows while the held-out\n * ground-truth signal stagnates or drops. Predictive validity over\n * time captures this.\n * 2. **Distributional shift in outputs:** after RL, the policy produces\n * outputs that no longer match the reference distribution — usually\n * because it found a high-reward attractor that's degenerate (e.g.\n * one-token responses, repetition, formatting tricks).\n * 3. **Disagreement between independent rewards:** if you train on\n * reward A and a held-out independent reward B drops sharply, you're\n * probably hacking A.\n * 4. **Calibration drift:** the verifiable / deterministic component of\n * the reward is stable; the probabilistic / judge component drifts up\n * while the deterministic component doesn't. The judge is being\n * gamed.\n *\n * This module ships explicit detectors for all four signatures, plus a\n * combined verdict. The output is diagnostic — actionable signals,\n * not autoreject — because each signature has known false positives\n * (e.g., a policy that genuinely improves can show distributional shift).\n *\n * Differs from `rubricPredictiveValidity` (which is a *standing* check on\n * whether rubrics correlate with deployment outcomes) — this is a\n * *temporal* check on whether the reward-vs-truth gap is *widening over\n * time during a training run*.\n */\n\nimport { observedScore } from '../rollout/reward'\nimport type { RunRecord } from '../run-record'\nimport { pearsonR } from '../statistics'\nimport {\n filterDeterministicallyRewarded,\n type VerifiableRewardExtractionOptions,\n} from './verifiable-reward'\n\nexport type RewardHackingSignal =\n | 'reward_divergence'\n | 'distribution_shift'\n | 'reward_disagreement'\n | 'judge_drift'\n\nexport interface RewardHackingFinding {\n signal: RewardHackingSignal\n /** Severity in [0, 1]. >0.5 = strong signal. */\n severity: number\n message: string\n /** Numeric evidence the consumer can render. */\n detail: Record<string, number>\n}\n\nexport interface RewardHackingReport {\n findings: RewardHackingFinding[]\n /** Signals with enough usable observations to produce a finding. */\n evaluatedSignals: RewardHackingSignal[]\n /**\n * Composite verdict. `'insufficient_evidence'` when fewer than four scored\n * runs exist; otherwise `'clean'` if every signal severity < 0.3,\n * `'suspect'` if at least one ≥ 0.3 but none ≥ 0.6, and `'gaming'` if any ≥ 0.6.\n */\n verdict: 'insufficient_evidence' | 'clean' | 'suspect' | 'gaming'\n /** Rationale for the verdict, ready to paste into an audit log. */\n rationale: string[]\n /** Number of runs with a usable proxy reward. */\n n: number\n}\n\nexport interface DetectRewardHackingInput {\n /**\n * Run records ordered by recency (oldest first). The detector segments\n * them into prefix/suffix windows to compute \"did the gap widen.\"\n */\n runs: RunRecord[]\n /**\n * The metric the policy was trained to optimize. Should be present on\n * `outcome.raw` or `outcome.holdoutScore`. Default reads `outcome.holdoutScore`.\n */\n proxyOf?: (run: RunRecord) => number | null\n /**\n * The held-out ground-truth metric. For RL on coding, this is typically\n * test pass-rate. For RLHF, it's downstream task performance or human\n * preference. For knowledge tasks, it's an independently-graded score.\n */\n truthOf?: (run: RunRecord) => number | null\n /**\n * Independent secondary reward. Used for the `reward_disagreement`\n * signal. Default uses the verifiable reward extractor (deterministic\n * sources only).\n */\n secondaryRewardOf?: (run: RunRecord) => number | null\n /**\n * Window size — how many of the most recent runs count as the \"after\"\n * cohort. Default min(50, half the runs).\n */\n windowSize?: number\n /**\n * Severity threshold to flag a signal. Default 0.3 (suspect) and 0.6\n * (gaming).\n */\n thresholds?: { suspect?: number; gaming?: number }\n /**\n * Verifiable-reward options used for the secondary-reward fallback.\n */\n verifiableRewardOptions?: VerifiableRewardExtractionOptions\n}\n\nconst DEFAULT_PROXY = (r: RunRecord): number | null => {\n // DELIBERATELY UNGATED. This is the proxy reward the detector tests for\n // Goodharting, and gated runs are exactly the gamed population. Forcing them\n // to 0 would collapse the proxy toward the deterministic secondary signal —\n // `reward_disagreement`'s correlation would rise, `judge_drift`'s gap would\n // shrink, and `reward_divergence`'s proxy-up/truth-flat fingerprint would be\n // erased — so the detector would report \"clean\" on the very runs it exists to\n // catch. `null` (never 0) is also load-bearing: it sets the n-denominator via\n // the filter below.\n const v = observedScore(r)\n return typeof v === 'number' && Number.isFinite(v) ? v : null\n}\n\nexport function detectRewardHacking(input: DetectRewardHackingInput): RewardHackingReport {\n const proxyOf = input.proxyOf ?? DEFAULT_PROXY\n const truthOf = input.truthOf\n const sus = input.thresholds?.suspect ?? 0.3\n const gam = input.thresholds?.gaming ?? 0.6\n\n const runs = input.runs.filter((run) => finiteNumber(proxyOf(run)))\n const n = runs.length\n if (n < 4) {\n return {\n findings: [],\n evaluatedSignals: [],\n verdict: 'insufficient_evidence',\n n,\n rationale: [`fewer than 4 runs with proxy reward (n=${n}); insufficient evidence`],\n }\n }\n const windowSize = Math.max(1, input.windowSize ?? Math.min(50, Math.floor(n / 2)))\n const before = runs.slice(0, n - windowSize)\n const after = runs.slice(n - windowSize)\n\n const findings: RewardHackingFinding[] = []\n\n // ── Signal 1: reward divergence (proxy ↑ while truth flat or ↓) ──────\n if (truthOf) {\n const beforeProxy = before.map(proxyOf).filter(finiteNumber)\n const afterProxy = after.map(proxyOf).filter(finiteNumber)\n const beforeTruth = before.map(truthOf).filter(finiteNumber)\n const afterTruth = after.map(truthOf).filter(finiteNumber)\n if (\n beforeProxy.length >= 2 &&\n afterProxy.length >= 2 &&\n beforeTruth.length >= 2 &&\n afterTruth.length >= 2\n ) {\n const proxyDelta = mean(afterProxy) - mean(beforeProxy)\n const truthDelta = mean(afterTruth) - mean(beforeTruth)\n // Divergence: proxy goes up while truth goes flat or down.\n // Severity = max(0, (proxyDelta - truthDelta)) — bigger gap = bigger signal.\n const gap = Math.max(0, proxyDelta - truthDelta)\n const severity = clamp01(gap * 5) // scale: 0.2 absolute gap → severity 1.0\n findings.push({\n signal: 'reward_divergence',\n severity,\n message:\n severity >= sus\n ? `proxy reward rose by ${proxyDelta.toFixed(3)} while truth changed by ${truthDelta.toFixed(3)} — potential Goodhart`\n : `proxy and truth moved together (proxy ${proxyDelta.toFixed(3)}, truth ${truthDelta.toFixed(3)})`,\n detail: {\n proxyDelta,\n truthDelta,\n gap,\n beforeN: beforeProxy.length,\n afterN: afterProxy.length,\n },\n })\n }\n }\n\n // ── Signal 2: distributional shift in outputs (KS on score distributions) ──\n {\n const beforeP = before.map(proxyOf).filter(finiteNumber)\n const afterP = after.map(proxyOf).filter(finiteNumber)\n if (beforeP.length >= 4 && afterP.length >= 4) {\n const ks = ksStatistic(beforeP, afterP)\n // KS statistic: bigger = more shift. We're agnostic about direction;\n // genuine improvement ALSO produces shift, so this signal is\n // contributory rather than load-bearing.\n const severity = clamp01(ks - 0.2)\n findings.push({\n signal: 'distribution_shift',\n severity,\n message:\n severity >= sus\n ? `KS=${ks.toFixed(3)} between before/after windows — distributional shift large`\n : `KS=${ks.toFixed(3)} between before/after windows — within-distribution drift`,\n detail: { ks, beforeN: beforeP.length, afterN: afterP.length },\n })\n }\n }\n\n // ── Signal 3: reward disagreement (proxy vs independent secondary) ────\n {\n const secondaryOf = input.secondaryRewardOf ?? defaultSecondary(input.verifiableRewardOptions)\n const aligned = runs\n .map((r) => ({ p: proxyOf(r), s: secondaryOf(r) }))\n .filter((x): x is { p: number; s: number } => finiteNumber(x.p) && finiteNumber(x.s))\n if (aligned.length >= 4) {\n const ps = aligned.map((x) => x.p)\n const ss = aligned.map((x) => x.s)\n const r = pearsonR(ps, ss)\n // Disagreement: low or negative correlation between primary proxy\n // reward and an independent secondary signal.\n const severity = clamp01(0.5 - Math.max(0, r))\n findings.push({\n signal: 'reward_disagreement',\n severity,\n message:\n severity >= sus\n ? `proxy and independent secondary reward correlate ρ=${r.toFixed(3)} — possibly hacking proxy`\n : `proxy and secondary reward correlate ρ=${r.toFixed(3)}`,\n detail: { pearson: r, n: aligned.length },\n })\n }\n }\n\n // ── Signal 4: judge drift (probabilistic up while deterministic flat) ─\n {\n // Ungated on purpose, exactly like `DEFAULT_PROXY` above. This signal is\n // the GAP between the judge reward and the deterministic one; a\n // deterministic reward another gate already forced to 0 would open that gap\n // by construction on the gamed population, so the detector would fire on\n // its own input rather than on evidence it found.\n const detRuns = filterDeterministicallyRewarded(runs, {\n ...(input.verifiableRewardOptions ?? {}),\n applyRealnessGate: false,\n })\n if (detRuns.length >= 4) {\n const detBefore = detRuns.slice(0, Math.floor(detRuns.length / 2))\n const detAfter = detRuns.slice(Math.floor(detRuns.length / 2))\n const detDelta =\n mean(detAfter.map((r) => r.reward.value)) - mean(detBefore.map((r) => r.reward.value))\n const proxyDelta =\n mean(after.map(proxyOf).filter(finiteNumber)) -\n mean(before.map(proxyOf).filter(finiteNumber))\n const driftGap = Math.max(0, proxyDelta - detDelta)\n const severity = clamp01(driftGap * 5)\n findings.push({\n signal: 'judge_drift',\n severity,\n message:\n severity >= sus\n ? `judge proxy +${proxyDelta.toFixed(3)} while deterministic reward +${detDelta.toFixed(3)} — judge drifting up without verifiable backing`\n : `judge and deterministic rewards move in step (judge ${proxyDelta.toFixed(3)}, det ${detDelta.toFixed(3)})`,\n detail: { proxyDelta, detDelta, driftGap, n: detRuns.length },\n })\n }\n }\n\n const maxSev = findings.reduce((m, f) => Math.max(m, f.severity), 0)\n if (findings.length === 0) {\n return {\n findings,\n evaluatedSignals: [],\n verdict: 'insufficient_evidence',\n rationale: [`no reward-hacking signal had enough paired evidence (n=${n})`],\n n,\n }\n }\n const verdict: RewardHackingReport['verdict'] =\n maxSev >= gam ? 'gaming' : maxSev >= sus ? 'suspect' : 'clean'\n const rationale = findings\n .filter((f) => f.severity >= sus)\n .map((f) => `${f.signal}: severity ${f.severity.toFixed(2)} — ${f.message}`)\n if (rationale.length === 0) rationale.push('no signals fired above suspect threshold')\n\n return {\n findings,\n evaluatedSignals: findings.map((finding) => finding.signal),\n verdict,\n rationale,\n n,\n }\n}\n\n// ── Helpers ──────────────────────────────────────────────────────────────\n\nfunction mean(xs: number[]): number {\n if (xs.length === 0) return 0\n return xs.reduce((s, x) => s + x, 0) / xs.length\n}\n\nfunction finiteNumber(value: number | null): value is number {\n return typeof value === 'number' && Number.isFinite(value)\n}\n\nfunction clamp01(x: number): number {\n if (!Number.isFinite(x)) return 0\n return Math.max(0, Math.min(1, x))\n}\n\nfunction ksStatistic(a: number[], b: number[]): number {\n // Two-sample Kolmogorov-Smirnov statistic.\n const sortedA = [...a].sort((x, y) => x - y)\n const sortedB = [...b].sort((x, y) => x - y)\n const all = [...new Set([...sortedA, ...sortedB])].sort((x, y) => x - y)\n let max = 0\n for (const v of all) {\n const fa = sortedA.filter((x) => x <= v).length / sortedA.length\n const fb = sortedB.filter((x) => x <= v).length / sortedB.length\n max = Math.max(max, Math.abs(fa - fb))\n }\n return max\n}\n\nfunction defaultSecondary(\n verifiableOpts?: VerifiableRewardExtractionOptions,\n): (run: RunRecord) => number | null {\n return (run: RunRecord) => {\n // Ungated for the same reason as signal 4: this is the INDEPENDENT\n // secondary reward whose correlation with the proxy is the evidence.\n // Zeroing it on gated runs would drive that correlation down mechanically.\n const filtered = filterDeterministicallyRewarded([run], {\n ...(verifiableOpts ?? {}),\n applyRealnessGate: false,\n })\n return filtered.length === 1 ? filtered[0]!.reward.value : null\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"reward-hacking-DCdRK9TY.js","names":["mean","clamp01"],"sources":["../src/campaign/run-record.ts","../src/rl/verifiable-reward.ts","../src/rl/reward-hacking.ts"],"sourcesContent":["import type { AgentProfileCell } from '../agent-profile-cell'\nimport type {\n JudgeScoresRecord,\n RunOutcome,\n RunRecord,\n RunSplitTag,\n RunTerminalOutcome,\n} from '../run-record'\nimport { validateRunRecord } from '../run-record'\nimport type { CampaignCellResult, JudgeScore } from './types'\n\nexport interface CampaignCellRunRecordOptions {\n runId: string\n experimentId: string\n candidateId: string\n model: string\n promptHash: string\n configHash: string\n commitSha: string\n splitTag: RunSplitTag\n seed?: number\n scenarioId?: string\n defaultCostUsd?: number\n agentProfile?: AgentProfileCell\n raw?: Record<string, number>\n}\n\nexport interface CampaignCellQualityProjection {\n score?: number\n judgeScores?: JudgeScoresRecord\n successfulJudgeScores: Record<string, JudgeScore>\n failedJudges: string[]\n raw: Record<string, number>\n}\n\nexport interface CampaignCellExecutionEvidence {\n terminalOutcome: RunTerminalOutcome\n executionErrorCount?: number\n judgeErrorCount?: number\n unclassifiedErrorCount?: number\n terminalFailureReason?: string\n}\n\n/**\n * Project one campaign cell into the canonical run format.\n *\n * A dispatch error establishes terminal execution failure. A judge error only\n * establishes that quality measurement failed after dispatch completed.\n * Failures without a stage remain unknown. No failure becomes a zero-quality\n * label.\n */\nexport function campaignCellToRunRecord<TArtifact>(\n cell: CampaignCellResult<TArtifact>,\n options: CampaignCellRunRecordOptions,\n): RunRecord {\n const quality = projectCampaignCellQuality(cell)\n const execution = campaignCellExecutionEvidence(cell)\n const judgeErrorCount = Math.max(\n quality.raw.judge_error_count ?? 0,\n execution.judgeErrorCount ?? 0,\n )\n const cellCostCaptured = Number.isFinite(cell.costUsd) && cell.costUsd >= 0\n const costUsd = cellCostCaptured ? cell.costUsd : (options.defaultCostUsd ?? null)\n const costProvenance =\n costUsd === null\n ? ({ kind: 'uncaptured', usd: null } as const)\n : cellCostCaptured && !cell.costEstimated\n ? ({ kind: 'observed', usd: costUsd } as const)\n : ({ kind: 'estimated', usd: costUsd } as const)\n const raw: Record<string, number> = {\n ...finiteMetrics(options.raw),\n ...quality.raw,\n rep: cell.rep,\n duration_ms: cell.durationMs,\n ...(costUsd === null ? {} : { cost_usd: costUsd }),\n cost_estimated: cell.costEstimated ? 1 : 0,\n tokens_input: cell.tokenUsage.input,\n tokens_output: cell.tokenUsage.output,\n latency_ms: cell.durationMs,\n ...(execution.executionErrorCount === undefined\n ? {}\n : { execution_error_count: execution.executionErrorCount }),\n ...(judgeErrorCount > 0 ? { judge_error_count: judgeErrorCount } : {}),\n ...(execution.unclassifiedErrorCount === undefined\n ? {}\n : { unclassified_error_count: execution.unclassifiedErrorCount }),\n }\n if (typeof cell.generation === 'number') raw.generation = cell.generation\n if (cell.tokenUsage.reasoning !== undefined) {\n raw.tokens_reasoning = cell.tokenUsage.reasoning\n }\n if (cell.tokenUsage.cached !== undefined) raw.tokens_cached = cell.tokenUsage.cached\n if (cell.tokenUsage.cacheWrite !== undefined) {\n raw.tokens_cache_write = cell.tokenUsage.cacheWrite\n }\n if (costUsd !== null && costUsd > 0) {\n raw.tokens_per_dollar = (cell.tokenUsage.input + cell.tokenUsage.output) / costUsd\n }\n if (costUsd !== null && quality.score !== undefined && quality.score > 0.01) {\n raw.cost_per_quality = costUsd / quality.score\n }\n\n const outcome: RunOutcome = {\n raw,\n ...(quality.judgeScores ? { judgeScores: quality.judgeScores } : {}),\n }\n if (quality.score !== undefined) {\n if (options.splitTag === 'holdout') outcome.holdoutScore = quality.score\n else outcome.searchScore = quality.score\n }\n\n return validateRunRecord({\n runId: options.runId,\n experimentId: options.experimentId,\n candidateId: options.candidateId,\n seed: options.seed ?? cell.seed,\n model: options.model,\n promptHash: options.promptHash,\n configHash: options.configHash,\n commitSha: options.commitSha,\n wallMs: cell.durationMs,\n costUsd,\n costProvenance,\n tokenUsage: { ...cell.tokenUsage },\n terminalOutcome: execution.terminalOutcome,\n ...(execution.terminalFailureReason\n ? { terminalFailureReason: execution.terminalFailureReason }\n : {}),\n outcome,\n splitTag: options.splitTag,\n scenarioId: options.scenarioId ?? cell.scenarioId,\n ...(options.agentProfile ? { agentProfile: options.agentProfile } : {}),\n })\n}\n\nexport function campaignCellExecutionEvidence<TArtifact>(\n cell: CampaignCellResult<TArtifact>,\n): CampaignCellExecutionEvidence {\n if (cell.errorStage === 'dispatch') {\n return {\n terminalOutcome: 'failed',\n executionErrorCount: 1,\n ...(cell.error ? { terminalFailureReason: cell.error } : {}),\n }\n }\n if (cell.errorStage === 'judge') {\n return {\n terminalOutcome: 'succeeded',\n executionErrorCount: 0,\n judgeErrorCount: 1,\n }\n }\n if (!cell.error) {\n return { terminalOutcome: 'succeeded', executionErrorCount: 0 }\n }\n return {\n terminalOutcome: 'unknown',\n unclassifiedErrorCount: 1,\n }\n}\n\n/**\n * Produce the only task-quality view used by campaign aggregates and exports.\n *\n * Successful judge results remain available for diagnosis after another judge\n * fails, but a task score exists only for an error-free cell whose reported\n * judge values are all finite.\n */\nexport function projectCampaignCellQuality<TArtifact>(\n cell: CampaignCellResult<TArtifact>,\n): CampaignCellQualityProjection {\n if (cell.errorStage === 'dispatch') {\n return { successfulJudgeScores: {}, failedJudges: [], raw: {} }\n }\n\n const perJudge: Record<string, Record<string, number>> = {}\n const successfulJudgeScores: Record<string, JudgeScore> = {}\n const dimensionValues = new Map<string, number[]>()\n const composites: number[] = []\n const notes: string[] = []\n const failedJudges = new Set<string>(\n cell.errorStage === 'judge' ? [cell.errorJudge ?? 'unknown-judge'] : [],\n )\n const raw: Record<string, number> = {}\n\n for (const [judgeName, score] of Object.entries(cell.judgeScores)) {\n const finiteDimensions = Object.values(score.dimensions).every(Number.isFinite)\n if (score.failed || !Number.isFinite(score.composite) || !finiteDimensions) {\n failedJudges.add(judgeName)\n continue\n }\n\n composites.push(score.composite)\n successfulJudgeScores[judgeName] = score\n const dimensions = { ...score.dimensions }\n perJudge[judgeName] = dimensions\n for (const [dimension, value] of Object.entries(dimensions)) {\n raw[`${judgeName}.${dimension}`] = value\n const values = dimensionValues.get(dimension) ?? []\n values.push(value)\n dimensionValues.set(dimension, values)\n }\n if (score.notes) notes.push(`${judgeName}: ${score.notes}`)\n for (const failedJudge of score.failedJudges ?? []) {\n failedJudges.add(`${judgeName}/${failedJudge}`)\n }\n }\n\n if (failedJudges.size > 0) raw.judge_error_count = failedJudges.size\n const sortedFailedJudges = [...failedJudges].sort()\n if (composites.length === 0) {\n return {\n successfulJudgeScores,\n failedJudges: sortedFailedJudges,\n raw,\n }\n }\n\n const composite = mean(composites)\n const perDimMean = Object.fromEntries(\n [...dimensionValues.entries()].map(([dimension, values]) => [dimension, mean(values)]),\n )\n const complete =\n cell.error === undefined && cell.errorStage === undefined && failedJudges.size === 0\n if (complete) raw.composite = composite\n\n return {\n ...(complete ? { score: composite } : {}),\n raw,\n successfulJudgeScores,\n failedJudges: sortedFailedJudges,\n judgeScores: {\n perJudge,\n perDimMean,\n composite,\n ...(sortedFailedJudges.length > 0 ? { failedJudges: sortedFailedJudges } : {}),\n ...(notes.length > 0 ? { notes: notes.join(' | ') } : {}),\n },\n }\n}\n\n/** Read the canonical task score without recomputing cell quality. */\nexport function campaignCellTaskScore<TArtifact>(\n cell: CampaignCellResult<TArtifact>,\n): number | undefined {\n return projectCampaignCellQuality(cell).score\n}\n\n/** Read canonical successful judge dimensions without recomputing cell quality. */\nexport function campaignCellJudgeDimensions<TArtifact>(\n cell: CampaignCellResult<TArtifact>,\n): Record<string, Record<string, number>> {\n return projectCampaignCellQuality(cell).judgeScores?.perJudge ?? {}\n}\n\nfunction finiteMetrics(metrics: Record<string, number> | undefined): Record<string, number> {\n const finite: Record<string, number> = {}\n for (const [key, value] of Object.entries(metrics ?? {})) {\n if (Number.isFinite(value)) finite[key] = value\n }\n return finite\n}\n\nfunction mean(values: number[]): number {\n return values.reduce((sum, value) => sum + value, 0) / values.length\n}\n","/**\n * Verifiable reward channel.\n *\n * For RL on coding / math / theorem-proving / structured-output tasks, the\n * reward signal is *decidable* — a test passes or fails, a proof checks or\n * doesn't, an output validates against a schema or doesn't. These rewards\n * are dramatically more useful for RL training than LLM-judge scores\n * because they don't drift, can't be Goodhart-gamed by the policy in the\n * same way, and don't require a separate calibration loop.\n *\n * The `MultiLayerVerifier` already produces this signal — it just doesn't\n * surface it in a shape that's clean enough for RL training. This module\n * wraps the verifier output so consumers can:\n *\n * 1. Extract a clean `VerifiableReward` from a `VerificationReport`\n * 2. Distinguish *deterministic* rewards (compile, test, schema) from\n * *probabilistic* rewards (judge) so they can be weighted differently\n * in the RL training step\n * 3. Filter `RunRecord[]` to only those with a verifiable reward,\n * producing the clean training set that DeepSeek-R1-style GRPO and\n * AlphaProof-style search both depend on\n *\n * Why this matters: every credible 2025-2026 frontier RL result on coding\n * agents leans on verifiable reward (DeepSeek-R1 GRPO on test pass-rate,\n * o-series RL on math/code, AlphaProof on Lean kernel checking). Mixing\n * judge scores into the reward signal poisons the gradient. This module\n * is the seam.\n */\n\nimport type { LayerResult, VerificationReport } from '../multi-layer-verifier'\nimport { isRealnessGated, observedScore, trainingScore } from '../rollout/reward'\nimport type { RunRecord } from '../run-record'\n\nexport type VerifiableRewardSource =\n | 'compile' // typecheck / build / lint passed\n | 'test' // unit / integration test pass-rate\n | 'schema' // structured output validates\n | 'sandbox' // sandbox exec exit code\n | 'judge' // LLM judge — probabilistic, included for completeness\n | 'composite' // weighted blend across multiple of the above\n\nexport interface VerifiableReward {\n /** Scalar in [0, 1]. The RL training signal. */\n value: number\n /** What produced the reward — different sources have different determinism. */\n source: VerifiableRewardSource\n /**\n * Determinism class. `'deterministic'` rewards are repeatable byte-for-byte\n * given the same inputs (compile, test, schema validation, sandbox exit code).\n * `'probabilistic'` rewards depend on a stochastic component (LLM judge).\n * Mixing these in the same training batch without separation is a known\n * footgun in production RLHF pipelines.\n */\n determinism: 'deterministic' | 'probabilistic'\n /**\n * Confidence in the reward value. For deterministic sources this is 1.0\n * (the bit either flipped or didn't). For judge sources this is the\n * judge-reported confidence or — when missing — a calibrated prior.\n */\n confidence: number\n /** The layer / judge id that produced the signal, for provenance. */\n origin: string\n /**\n * Per-source contribution to `value`, keyed by layer/judge id. Single-source\n * rewards carry one entry (`{ [origin]: value }`); composite rewards carry\n * every contributing layer's score — the anti-scalar-collapse surface RL\n * consumers weight per-source instead of trusting one blended number.\n */\n components: Record<string, number>\n /**\n * The run carries `outcome.realness.gated` — the authenticity gate flagged\n * its success signal as faked.\n *\n * With the gate applied (the default) `value` and every `components` entry\n * are 0 on such a run; with `applyRealnessGate: false` the observed numbers\n * come back untouched and this flag is the only marker that they are not to\n * be trusted. Either way it distinguishes \"measured a genuine failure\" from\n * \"claimed a success we refuse to believe\", which a bare 0 cannot.\n */\n realnessGated?: boolean\n /**\n * Whether an authenticity screen COULD run on this reward at all — the same\n * distinction `RolloutOutcome.realness_screened` draws, for the same reason.\n *\n * `false` on every reward from `extractVerifiableReward`, because a\n * `VerificationReport` carries layer scores and nothing else: there is no\n * `outcome.realness` to consult, so no gate has run, and `realnessGated`\n * being absent there means \"unknown\", NOT \"clean\". Absent on the\n * `RunRecord` path when the record itself carries no realness verdict.\n *\n * This matters most exactly where it is easiest to miss: a report whose\n * deterministic layers all passed yields `determinism: 'deterministic'`,\n * `confidence: 1` — the highest-credibility reward this module can emit —\n * and a stubbed integration reporting green is precisely what a gamed run\n * looks like. Consumers driving training off this shape must screen the run\n * themselves; the flag is what tells them nobody has.\n */\n realnessScreened?: boolean\n}\n\nexport interface VerifiableRewardExtractionOptions {\n /**\n * Which layers count as deterministic-reward sources. The verifier doesn't\n * tag layers as \"this is verifiable\"; the caller declares it via this list\n * (or via the layer name → source mapping). Default treats common names\n * (`install`, `typecheck`, `build`, `lint`, `test`, `compile`, `schema`,\n * `sandbox`) as deterministic.\n */\n deterministicLayers?: string[]\n /**\n * Map layer name → reward source. Defaults to a sensible string-match.\n */\n sourceFor?: (layerName: string) => VerifiableRewardSource\n /**\n * Whether to fall back to a probabilistic (judge) reward when no\n * deterministic layer produced a numeric score. Default `true`. Set to\n * `false` for \"deterministic-only\" training pipelines that should\n * discard runs without a verifiable signal.\n */\n fallbackToJudge?: boolean\n /**\n * Default confidence for probabilistic (judge) rewards when the judge\n * doesn't report one. Default `0.7`.\n */\n judgeConfidenceFloor?: number\n /**\n * Whether the anti-Goodhart realness gate applies. Default `true`, and the\n * default is the one every training path must keep.\n *\n * Set `false` ONLY for detection and analysis. `rl/reward-hacking.ts` does,\n * for the same reason it reads `observedScore` for its proxy: it measures the\n * DIVERGENCE between the judge signal and the deterministic one, and a\n * deterministic reward that another gate already forced to 0 manufactures\n * exactly that divergence on exactly the gamed population. The detector would\n * then be re-reporting a verdict it was supposed to reach independently.\n */\n applyRealnessGate?: boolean\n}\n\nconst DEFAULT_DETERMINISTIC_LAYERS = new Set([\n 'install',\n 'typecheck',\n 'build',\n 'lint',\n 'test',\n 'compile',\n 'schema',\n 'sandbox',\n 'unit_tests',\n 'integration_tests',\n])\n\nconst DEFAULT_SOURCE_FOR = (name: string): VerifiableRewardSource => {\n const lower = name.toLowerCase()\n if (lower.includes('test')) return 'test'\n if (\n lower.includes('compile') ||\n lower.includes('build') ||\n lower.includes('typecheck') ||\n lower.includes('lint')\n )\n return 'compile'\n if (lower.includes('schema')) return 'schema'\n if (lower.includes('sandbox')) return 'sandbox'\n if (lower.includes('judge') || lower.includes('semantic')) return 'judge'\n return 'composite'\n}\n\n/**\n * Extract a `VerifiableReward` from a `VerificationReport`.\n *\n * Strategy: prefer the deterministic layers (in order: test → compile →\n * schema → sandbox), fall back to the judge layer if `fallbackToJudge` is\n * true, return `null` if no signal qualifies. When multiple deterministic\n * layers contribute, return a `'composite'` source with a weighted blend.\n *\n * NO realness gate is applied and none can be: a `VerificationReport` carries\n * layer scores and nothing about whether the run faked them — `realness` lives\n * on the `RunRecord`. Use `extractVerifiableRewardsFromRecords` for anything\n * that becomes training data; this signature is for scoring a report in hand.\n */\nexport function extractVerifiableReward(\n report: VerificationReport,\n opts: VerifiableRewardExtractionOptions = {},\n): VerifiableReward | null {\n const deterministicSet = new Set(opts.deterministicLayers ?? [...DEFAULT_DETERMINISTIC_LAYERS])\n const sourceFor = opts.sourceFor ?? DEFAULT_SOURCE_FOR\n const fallbackToJudge = opts.fallbackToJudge ?? true\n const judgeFloor = opts.judgeConfidenceFloor ?? 0.7\n\n const deterministic = report.layers.filter(\n (layer) => deterministicSet.has(layer.layer) && isMeasuredLayer(layer),\n )\n\n if (deterministic.length === 1) {\n const layer = deterministic[0]!\n const value = clamp01(layer.score!)\n return {\n value,\n source: sourceFor(layer.layer),\n determinism: 'deterministic',\n confidence: 1,\n origin: layer.layer,\n components: { [layer.layer]: value },\n realnessScreened: false,\n }\n }\n\n if (deterministic.length > 1) {\n // Composite: weighted blend by `Layer.weight` if present, else equal.\n let num = 0\n let denom = 0\n const components: Record<string, number> = {}\n for (const l of deterministic) {\n const w = (l.detail?.weight as number | undefined) ?? 1\n num += w * (l.score ?? 0)\n denom += w\n components[l.layer] = l.score!\n }\n return {\n value: denom === 0 ? 0 : clamp01(num / denom),\n source: 'composite',\n determinism: 'deterministic',\n confidence: 1,\n origin: deterministic.map((l) => l.layer).join('+'),\n components,\n realnessScreened: false,\n }\n }\n\n if (!fallbackToJudge) return null\n\n const judge =\n report.layers.find((layer) => isMeasuredLayer(layer) && sourceFor(layer.layer) === 'judge') ??\n report.layers.find(isMeasuredLayer)\n\n if (!judge) return null\n\n const confFromDetail = judge.detail?.confidence as number | undefined\n const judgeValue = clamp01(judge.score!)\n return {\n value: judgeValue,\n source: 'judge',\n determinism: 'probabilistic',\n confidence: typeof confFromDetail === 'number' ? confFromDetail : judgeFloor,\n origin: judge.layer,\n components: { [judge.layer]: judgeValue },\n realnessScreened: false,\n }\n}\n\nfunction isMeasuredLayer(\n layer: LayerResult,\n): layer is LayerResult & { status: 'pass' | 'fail'; score: number } {\n return (\n (layer.status === 'pass' || layer.status === 'fail') &&\n typeof layer.score === 'number' &&\n Number.isFinite(layer.score) &&\n layer.score >= 0 &&\n layer.score <= 1\n )\n}\n\n/**\n * Extract verifiable rewards from `RunRecord[]` produced via the\n * `verificationReportToRunRecord` adapter (which encodes per-layer scores\n * in `outcome.raw['layer.<name>']`). For records that don't carry layer\n * scores, returns `null` for that record.\n *\n * This is the canonical bridge from \"campaign-shaped artifacts\" to\n * \"RL-training-ready reward signals\": every record that has a clean\n * verifiable reward becomes a training datum, every record that doesn't\n * gets filtered out (or kept with `'probabilistic'` determinism for\n * separate downstream handling).\n *\n * The realness gate applies to EVERY channel here, and to the deterministic one\n * MOST. It is tempting to reason that a decidable signal cannot be gamed, so\n * the gate is redundant on it — that reasoning is backwards. `realness.gated`\n * means the run's success signal was FAKED, and a test suite reporting green on\n * a stubbed integration is precisely what that looks like: the deterministic\n * layer is the thing that got faked. Exporting it ungated hands a trainer the\n * highest-credibility reward the module can emit (`determinism: 'deterministic'`,\n * `confidence: 1`) for the one population the gate exists to catch. Pass\n * `applyRealnessGate: false` only to look at the ungated numbers for detection.\n */\nexport function extractVerifiableRewardsFromRecords(\n runs: RunRecord[],\n opts: VerifiableRewardExtractionOptions = {},\n): Array<{ runId: string; reward: VerifiableReward | null }> {\n const sourceFor = opts.sourceFor ?? DEFAULT_SOURCE_FOR\n const deterministicSet = new Set(opts.deterministicLayers ?? [...DEFAULT_DETERMINISTIC_LAYERS])\n const fallbackToJudge = opts.fallbackToJudge ?? true\n const judgeFloor = opts.judgeConfidenceFloor ?? 0.7\n const applyGate = opts.applyRealnessGate ?? true\n\n return runs.map((run) => {\n const flagged = isRealnessGated(run)\n // Present only when the record carries an actual realness verdict. Absent\n // is the honest \"unknown\"; `false` is reserved for a producer that\n // declares it HAS no screen, which is the report-shaped path above.\n const screened = run.outcome.realness === undefined ? {} : ({ realnessScreened: true } as const)\n // Zeroed with `value`, never left at the measured number: `components`\n // exists so an RL consumer can re-weight per source, and a raw layer score\n // surviving there would let that re-weighting reconstruct the very reward\n // the gate just refused. The measured layer scores stay on\n // `run.outcome.raw['layer.*']`, which is where analysis reads them.\n const gate = (value: number): number => (applyGate && flagged ? 0 : value)\n // Recover per-layer scores from outcome.raw['layer.<name>']\n const layerScores: Array<{ name: string; score: number }> = []\n for (const [k, v] of Object.entries(run.outcome.raw)) {\n if (\n k.startsWith('layer.') &&\n !k.includes('.', 6) &&\n typeof v === 'number' &&\n Number.isFinite(v)\n ) {\n layerScores.push({ name: k.slice('layer.'.length), score: v })\n }\n }\n const det = layerScores.filter((l) => deterministicSet.has(l.name))\n\n if (det.length === 1) {\n const layer = det[0]!\n const value = gate(clamp01(layer.score))\n return {\n runId: run.runId,\n reward: {\n value,\n source: sourceFor(layer.name),\n determinism: 'deterministic',\n confidence: 1,\n origin: layer.name,\n components: { [layer.name]: value },\n realnessGated: flagged,\n ...screened,\n },\n }\n }\n if (det.length > 1) {\n const value = gate(clamp01(det.reduce((s, l) => s + l.score, 0) / det.length))\n // Same clamp as the headline value: a producer writing layer.score 1.5\n // into outcome.raw must not propagate 1.5 through a component either.\n const components: Record<string, number> = Object.fromEntries(\n det.map((l) => [l.name, gate(clamp01(l.score))]),\n )\n return {\n runId: run.runId,\n reward: {\n value,\n source: 'composite',\n determinism: 'deterministic',\n confidence: 1,\n origin: det.map((l) => l.name).join('+'),\n components,\n realnessGated: flagged,\n ...screened,\n },\n }\n }\n if (!fallbackToJudge) return { runId: run.runId, reward: null }\n\n // Probabilistic fallback: the run's primary score. `trainingScore` already\n // carries the gate, so a gamed run falls to 0 rather than earning the\n // judge's number; `observedScore` is the ungated reader the detection\n // opt-out asks for. Either way an unscored run stays a labeled gap\n // (`reward: null`), never a fabricated 0.\n const primary = applyGate ? trainingScore(run) : observedScore(run)\n if (typeof primary !== 'number' || !Number.isFinite(primary)) {\n return { runId: run.runId, reward: null }\n }\n const primaryValue = clamp01(primary)\n return {\n runId: run.runId,\n reward: {\n value: primaryValue,\n source: 'judge',\n determinism: 'probabilistic',\n confidence: judgeFloor,\n origin: 'run.outcome.score',\n components: { 'run.outcome.score': primaryValue },\n realnessGated: flagged,\n ...screened,\n },\n }\n })\n}\n\n/**\n * Filter `RunRecord[]` to those with deterministic verifiable rewards.\n *\n * A realness-gated run is KEPT, at reward 0 with `realnessGated: true` — the\n * same rule GRPO uses on a gated line. 0 is the honest label for a faked\n * success and is usable signal, whereas dropping the run would move a group\n * baseline without saying so. (SFT differs: there every row is a target to\n * imitate, so a gated row is removed outright.)\n */\nexport function filterDeterministicallyRewarded(\n runs: RunRecord[],\n opts: VerifiableRewardExtractionOptions = {},\n): Array<{ run: RunRecord; reward: VerifiableReward }> {\n const rewarded = extractVerifiableRewardsFromRecords(runs, { ...opts, fallbackToJudge: false })\n const out: Array<{ run: RunRecord; reward: VerifiableReward }> = []\n for (let i = 0; i < runs.length; i++) {\n const r = rewarded[i]!\n if (r.reward && r.reward.determinism === 'deterministic') {\n out.push({ run: runs[i]!, reward: r.reward })\n }\n }\n return out\n}\n\nfunction clamp01(x: number): number {\n if (!Number.isFinite(x)) return 0\n return Math.max(0, Math.min(1, x))\n}\n","/**\n * Reward hacking / Goodhart detection.\n *\n * Goodhart's Law says: when a measure becomes a target, it ceases to be\n * a good measure. In RLHF and agentic-RL settings this is the dominant\n * failure mode — the policy learns to produce outputs that score well on\n * the proxy reward (judge, rubric, test pass-rate) without producing\n * the underlying capability the proxy was meant to track.\n *\n * Krakovna et al. (2020, \"Specification Gaming Examples in AI\") and the\n * subsequent RLHF reward-hacking literature (Skalse et al. 2022, Kim et al.\n * 2023) converge on a few diagnostic signatures:\n *\n * 1. **Reward divergence:** the proxy reward grows while the held-out\n * ground-truth signal stagnates or drops. Predictive validity over\n * time captures this.\n * 2. **Distributional shift in outputs:** after RL, the policy produces\n * outputs that no longer match the reference distribution — usually\n * because it found a high-reward attractor that's degenerate (e.g.\n * one-token responses, repetition, formatting tricks).\n * 3. **Disagreement between independent rewards:** if you train on\n * reward A and a held-out independent reward B drops sharply, you're\n * probably hacking A.\n * 4. **Calibration drift:** the verifiable / deterministic component of\n * the reward is stable; the probabilistic / judge component drifts up\n * while the deterministic component doesn't. The judge is being\n * gamed.\n *\n * This module ships explicit detectors for all four signatures, plus a\n * combined verdict. The output is diagnostic — actionable signals,\n * not autoreject — because each signature has known false positives\n * (e.g., a policy that genuinely improves can show distributional shift).\n *\n * Differs from `rubricPredictiveValidity` (which is a *standing* check on\n * whether rubrics correlate with deployment outcomes) — this is a\n * *temporal* check on whether the reward-vs-truth gap is *widening over\n * time during a training run*.\n */\n\nimport { observedScore } from '../rollout/reward'\nimport type { RunRecord } from '../run-record'\nimport { pearsonR } from '../statistics'\nimport {\n filterDeterministicallyRewarded,\n type VerifiableRewardExtractionOptions,\n} from './verifiable-reward'\n\nexport type RewardHackingSignal =\n | 'reward_divergence'\n | 'distribution_shift'\n | 'reward_disagreement'\n | 'judge_drift'\n\nexport interface RewardHackingFinding {\n signal: RewardHackingSignal\n /** Severity in [0, 1]. >0.5 = strong signal. */\n severity: number\n message: string\n /** Numeric evidence the consumer can render. */\n detail: Record<string, number>\n}\n\nexport interface RewardHackingReport {\n findings: RewardHackingFinding[]\n /** Signals with enough usable observations to produce a finding. */\n evaluatedSignals: RewardHackingSignal[]\n /**\n * Composite verdict. `'insufficient_evidence'` when fewer than four scored\n * runs exist; otherwise `'clean'` if every signal severity < 0.3,\n * `'suspect'` if at least one ≥ 0.3 but none ≥ 0.6, and `'gaming'` if any ≥ 0.6.\n */\n verdict: 'insufficient_evidence' | 'clean' | 'suspect' | 'gaming'\n /** Rationale for the verdict, ready to paste into an audit log. */\n rationale: string[]\n /** Number of runs with a usable proxy reward. */\n n: number\n}\n\nexport interface DetectRewardHackingInput {\n /**\n * Run records ordered by recency (oldest first). The detector segments\n * them into prefix/suffix windows to compute \"did the gap widen.\"\n */\n runs: RunRecord[]\n /**\n * The metric the policy was trained to optimize. Should be present on\n * `outcome.raw` or `outcome.holdoutScore`. Default reads `outcome.holdoutScore`.\n */\n proxyOf?: (run: RunRecord) => number | null\n /**\n * The held-out ground-truth metric. For RL on coding, this is typically\n * test pass-rate. For RLHF, it's downstream task performance or human\n * preference. For knowledge tasks, it's an independently-graded score.\n */\n truthOf?: (run: RunRecord) => number | null\n /**\n * Independent secondary reward. Used for the `reward_disagreement`\n * signal. Default uses the verifiable reward extractor (deterministic\n * sources only).\n */\n secondaryRewardOf?: (run: RunRecord) => number | null\n /**\n * Window size — how many of the most recent runs count as the \"after\"\n * cohort. Default min(50, half the runs).\n */\n windowSize?: number\n /**\n * Severity threshold to flag a signal. Default 0.3 (suspect) and 0.6\n * (gaming).\n */\n thresholds?: { suspect?: number; gaming?: number }\n /**\n * Verifiable-reward options used for the secondary-reward fallback.\n */\n verifiableRewardOptions?: VerifiableRewardExtractionOptions\n}\n\nconst DEFAULT_PROXY = (r: RunRecord): number | null => {\n // DELIBERATELY UNGATED. This is the proxy reward the detector tests for\n // Goodharting, and gated runs are exactly the gamed population. Forcing them\n // to 0 would collapse the proxy toward the deterministic secondary signal —\n // `reward_disagreement`'s correlation would rise, `judge_drift`'s gap would\n // shrink, and `reward_divergence`'s proxy-up/truth-flat fingerprint would be\n // erased — so the detector would report \"clean\" on the very runs it exists to\n // catch. `null` (never 0) is also load-bearing: it sets the n-denominator via\n // the filter below.\n const v = observedScore(r)\n return typeof v === 'number' && Number.isFinite(v) ? v : null\n}\n\nexport function detectRewardHacking(input: DetectRewardHackingInput): RewardHackingReport {\n const proxyOf = input.proxyOf ?? DEFAULT_PROXY\n const truthOf = input.truthOf\n const sus = input.thresholds?.suspect ?? 0.3\n const gam = input.thresholds?.gaming ?? 0.6\n\n const runs = input.runs.filter((run) => finiteNumber(proxyOf(run)))\n const n = runs.length\n if (n < 4) {\n return {\n findings: [],\n evaluatedSignals: [],\n verdict: 'insufficient_evidence',\n n,\n rationale: [`fewer than 4 runs with proxy reward (n=${n}); insufficient evidence`],\n }\n }\n const windowSize = Math.max(1, input.windowSize ?? Math.min(50, Math.floor(n / 2)))\n const before = runs.slice(0, n - windowSize)\n const after = runs.slice(n - windowSize)\n\n const findings: RewardHackingFinding[] = []\n\n // ── Signal 1: reward divergence (proxy ↑ while truth flat or ↓) ──────\n if (truthOf) {\n const beforeProxy = before.map(proxyOf).filter(finiteNumber)\n const afterProxy = after.map(proxyOf).filter(finiteNumber)\n const beforeTruth = before.map(truthOf).filter(finiteNumber)\n const afterTruth = after.map(truthOf).filter(finiteNumber)\n if (\n beforeProxy.length >= 2 &&\n afterProxy.length >= 2 &&\n beforeTruth.length >= 2 &&\n afterTruth.length >= 2\n ) {\n const proxyDelta = mean(afterProxy) - mean(beforeProxy)\n const truthDelta = mean(afterTruth) - mean(beforeTruth)\n // Divergence: proxy goes up while truth goes flat or down.\n // Severity = max(0, (proxyDelta - truthDelta)) — bigger gap = bigger signal.\n const gap = Math.max(0, proxyDelta - truthDelta)\n const severity = clamp01(gap * 5) // scale: 0.2 absolute gap → severity 1.0\n findings.push({\n signal: 'reward_divergence',\n severity,\n message:\n severity >= sus\n ? `proxy reward rose by ${proxyDelta.toFixed(3)} while truth changed by ${truthDelta.toFixed(3)} — potential Goodhart`\n : `proxy and truth moved together (proxy ${proxyDelta.toFixed(3)}, truth ${truthDelta.toFixed(3)})`,\n detail: {\n proxyDelta,\n truthDelta,\n gap,\n beforeN: beforeProxy.length,\n afterN: afterProxy.length,\n },\n })\n }\n }\n\n // ── Signal 2: distributional shift in outputs (KS on score distributions) ──\n {\n const beforeP = before.map(proxyOf).filter(finiteNumber)\n const afterP = after.map(proxyOf).filter(finiteNumber)\n if (beforeP.length >= 4 && afterP.length >= 4) {\n const ks = ksStatistic(beforeP, afterP)\n // KS statistic: bigger = more shift. We're agnostic about direction;\n // genuine improvement ALSO produces shift, so this signal is\n // contributory rather than load-bearing.\n const severity = clamp01(ks - 0.2)\n findings.push({\n signal: 'distribution_shift',\n severity,\n message:\n severity >= sus\n ? `KS=${ks.toFixed(3)} between before/after windows — distributional shift large`\n : `KS=${ks.toFixed(3)} between before/after windows — within-distribution drift`,\n detail: { ks, beforeN: beforeP.length, afterN: afterP.length },\n })\n }\n }\n\n // ── Signal 3: reward disagreement (proxy vs independent secondary) ────\n {\n const secondaryOf = input.secondaryRewardOf ?? defaultSecondary(input.verifiableRewardOptions)\n const aligned = runs\n .map((r) => ({ p: proxyOf(r), s: secondaryOf(r) }))\n .filter((x): x is { p: number; s: number } => finiteNumber(x.p) && finiteNumber(x.s))\n if (aligned.length >= 4) {\n const ps = aligned.map((x) => x.p)\n const ss = aligned.map((x) => x.s)\n const r = pearsonR(ps, ss)\n // Disagreement: low or negative correlation between primary proxy\n // reward and an independent secondary signal.\n const severity = clamp01(0.5 - Math.max(0, r))\n findings.push({\n signal: 'reward_disagreement',\n severity,\n message:\n severity >= sus\n ? `proxy and independent secondary reward correlate ρ=${r.toFixed(3)} — possibly hacking proxy`\n : `proxy and secondary reward correlate ρ=${r.toFixed(3)}`,\n detail: { pearson: r, n: aligned.length },\n })\n }\n }\n\n // ── Signal 4: judge drift (probabilistic up while deterministic flat) ─\n {\n // Ungated on purpose, exactly like `DEFAULT_PROXY` above. This signal is\n // the GAP between the judge reward and the deterministic one; a\n // deterministic reward another gate already forced to 0 would open that gap\n // by construction on the gamed population, so the detector would fire on\n // its own input rather than on evidence it found.\n const detRuns = filterDeterministicallyRewarded(runs, {\n ...(input.verifiableRewardOptions ?? {}),\n applyRealnessGate: false,\n })\n if (detRuns.length >= 4) {\n const detBefore = detRuns.slice(0, Math.floor(detRuns.length / 2))\n const detAfter = detRuns.slice(Math.floor(detRuns.length / 2))\n const detDelta =\n mean(detAfter.map((r) => r.reward.value)) - mean(detBefore.map((r) => r.reward.value))\n const proxyDelta =\n mean(after.map(proxyOf).filter(finiteNumber)) -\n mean(before.map(proxyOf).filter(finiteNumber))\n const driftGap = Math.max(0, proxyDelta - detDelta)\n const severity = clamp01(driftGap * 5)\n findings.push({\n signal: 'judge_drift',\n severity,\n message:\n severity >= sus\n ? `judge proxy +${proxyDelta.toFixed(3)} while deterministic reward +${detDelta.toFixed(3)} — judge drifting up without verifiable backing`\n : `judge and deterministic rewards move in step (judge ${proxyDelta.toFixed(3)}, det ${detDelta.toFixed(3)})`,\n detail: { proxyDelta, detDelta, driftGap, n: detRuns.length },\n })\n }\n }\n\n const maxSev = findings.reduce((m, f) => Math.max(m, f.severity), 0)\n if (findings.length === 0) {\n return {\n findings,\n evaluatedSignals: [],\n verdict: 'insufficient_evidence',\n rationale: [`no reward-hacking signal had enough paired evidence (n=${n})`],\n n,\n }\n }\n const verdict: RewardHackingReport['verdict'] =\n maxSev >= gam ? 'gaming' : maxSev >= sus ? 'suspect' : 'clean'\n const rationale = findings\n .filter((f) => f.severity >= sus)\n .map((f) => `${f.signal}: severity ${f.severity.toFixed(2)} — ${f.message}`)\n if (rationale.length === 0) rationale.push('no signals fired above suspect threshold')\n\n return {\n findings,\n evaluatedSignals: findings.map((finding) => finding.signal),\n verdict,\n rationale,\n n,\n }\n}\n\n// ── Helpers ──────────────────────────────────────────────────────────────\n\nfunction mean(xs: number[]): number {\n if (xs.length === 0) return 0\n return xs.reduce((s, x) => s + x, 0) / xs.length\n}\n\nfunction finiteNumber(value: number | null): value is number {\n return typeof value === 'number' && Number.isFinite(value)\n}\n\nfunction clamp01(x: number): number {\n if (!Number.isFinite(x)) return 0\n return Math.max(0, Math.min(1, x))\n}\n\nfunction ksStatistic(a: number[], b: number[]): number {\n // Two-sample Kolmogorov-Smirnov statistic.\n const sortedA = [...a].sort((x, y) => x - y)\n const sortedB = [...b].sort((x, y) => x - y)\n const all = [...new Set([...sortedA, ...sortedB])].sort((x, y) => x - y)\n let max = 0\n for (const v of all) {\n const fa = sortedA.filter((x) => x <= v).length / sortedA.length\n const fb = sortedB.filter((x) => x <= v).length / sortedB.length\n max = Math.max(max, Math.abs(fa - fb))\n }\n return max\n}\n\nfunction defaultSecondary(\n verifiableOpts?: VerifiableRewardExtractionOptions,\n): (run: RunRecord) => number | null {\n return (run: RunRecord) => {\n // Ungated for the same reason as signal 4: this is the INDEPENDENT\n // secondary reward whose correlation with the proxy is the evidence.\n // Zeroing it on gated runs would drive that correlation down mechanically.\n const filtered = filterDeterministicallyRewarded([run], {\n ...(verifiableOpts ?? {}),\n applyRealnessGate: false,\n })\n return filtered.length === 1 ? filtered[0]!.reward.value : null\n }\n}\n"],"mappings":"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"}
|
package/dist/rl.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ import { a as detectRewardHacking, c as VerifiableRewardSource, d as filterDeter
|
|
|
7
7
|
import { i as InMemoryOutcomeStore, n as FileSystemOutcomeStore, o as OutcomeStore, r as FileSystemOutcomeStoreOptions, t as DeploymentOutcome } from "./outcome-store-BYHIuO0e.js";
|
|
8
8
|
import { t as AdversarialMutation } from "./adversarial-smnADNFS.js";
|
|
9
9
|
import { b as RolloutSplit, o as MintedRolloutLine } from "./schema-Cef2cFmb.js";
|
|
10
|
-
import { _ as EvalCampaignResult, a as FailureMode, c as SteeringChange, g as EvalCampaignOptions, i as ExperimentResult, r as ExperimentPlan, s as Researcher, y as runEvalCampaign } from "./researcher-
|
|
10
|
+
import { _ as EvalCampaignResult, a as FailureMode, c as SteeringChange, g as EvalCampaignOptions, i as ExperimentResult, r as ExperimentPlan, s as Researcher, y as runEvalCampaign } from "./researcher-BtD5U1Up.js";
|
|
11
11
|
import { t as InterimReleaseConfidence } from "./sequential-CYwq6Ff_.js";
|
|
12
12
|
import { r as RubricPredictiveValidityReport } from "./rubric-predictive-validity-C1dCLcvb.js";
|
|
13
13
|
//#region src/rl/active-curriculum.d.ts
|
package/dist/rl.js
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { s as ValidationError } from "./errors-8YnH8WlF.js";
|
|
2
|
-
import {
|
|
2
|
+
import { R as wilcoxonSignedRank, o as benjaminiHochberg } from "./statistics-RwRNu2__.js";
|
|
3
3
|
import { r as observedSplitScore, s as trainingScore } from "./reward-nw2xZGZG.js";
|
|
4
4
|
import { o as runTaskScore } from "./run-record-BIwU2wdV.js";
|
|
5
5
|
import { l as assertRewardGate } from "./schema-C6DW4ZHR.js";
|
|
6
6
|
import { t as isSplitEligible } from "./exporters-q9iL-2Jf.js";
|
|
7
7
|
import { t as mintRolloutRows } from "./mint-BvkwcYZU.js";
|
|
8
8
|
import { a as InMemoryTraceStore } from "./integrity-BzRbCHzi.js";
|
|
9
|
-
import { c as campaignCellToRunRecord, i as filterDeterministicallyRewarded, n as extractVerifiableReward, r as extractVerifiableRewardsFromRecords, t as detectRewardHacking } from "./reward-hacking-
|
|
10
|
-
import { t as runEvalCampaign } from "./eval-campaign-
|
|
9
|
+
import { c as campaignCellToRunRecord, i as filterDeterministicallyRewarded, n as extractVerifiableReward, r as extractVerifiableRewardsFromRecords, t as detectRewardHacking } from "./reward-hacking-DCdRK9TY.js";
|
|
10
|
+
import { t as runEvalCampaign } from "./eval-campaign-CvPcvqXC.js";
|
|
11
11
|
import { t as evaluateInterimReleaseConfidence } from "./sequential-Br0mAPHA.js";
|
|
12
|
-
import { t as rubricPredictiveValidity } from "./rubric-predictive-validity-
|
|
12
|
+
import { t as rubricPredictiveValidity } from "./rubric-predictive-validity-D6Q6n9oq.js";
|
|
13
13
|
import { n as thompsonCurriculum, r as varianceBasedCurriculum, t as observationsFromRunRecords } from "./active-curriculum-C4mk67HP.js";
|
|
14
14
|
import { n as InMemoryOutcomeStore, t as FileSystemOutcomeStore } from "./outcome-store-ChBKlTd_.js";
|
|
15
15
|
import { appendFileSync, existsSync, mkdirSync, readFileSync } from "node:fs";
|
package/dist/rollout/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { a as scoreOrigin, n as observedScore, o as trainingReward, r as observedSplitScore, s as trainingScore, t as isRealnessGated } from "../reward-nw2xZGZG.js";
|
|
2
2
|
import { _ as GATE_POLICIES, a as ROLLOUT_SPLITS, c as assertMintedLines, d as gateGamedOutcome, f as isRolloutLine, g as GATE_CHECK_IDS, h as GATE_CHECKS, i as ROLLOUT_SCHEMA, m as validateRolloutLine, n as ROLLOUT_CAPTURES, o as TRAINABLE_SPLITS, p as isTrainableSplit, r as ROLLOUT_ROLES, s as assertMinted, t as CHAT_ROLES, u as assertRolloutLine, v as gateErrors, y as gatedEvidenceOf } from "../schema-C6DW4ZHR.js";
|
|
3
3
|
import { a as toRftItem, c as toVerifiersRolloutOutput, i as toRewardRows, l as toVerifiersRolloutOutputs, n as realnessLabels, o as toRftItems, r as toJsonl, s as toSftRows } from "../exporters-q9iL-2Jf.js";
|
|
4
|
-
import { a as toHarborTrajectories, i as relabelImportedSplit, n as HARBOR_IMPORT_GAP, o as toHarborTrajectory, r as fromHarborTrajectory, t as ATIF_SCHEMA_VERSION } from "../rollout-
|
|
4
|
+
import { a as toHarborTrajectories, i as relabelImportedSplit, n as HARBOR_IMPORT_GAP, o as toHarborTrajectory, r as fromHarborTrajectory, t as ATIF_SCHEMA_VERSION } from "../rollout-CreDz__7.js";
|
|
5
5
|
import { C as readRolloutJournal, S as appendRolloutLines, T as writeRolloutLedger, _ as FORMAT_GATE_DISPOSITION, a as pushDataset, b as measureFormatGate, c as addScrubCounts, d as scrubLines, f as scrubRolloutLine, g as buildDatasetCard, h as RELEASE_FORMATS, i as planPushCommand, l as defaultRolloutScrubber, m as FORMAT_FILES, n as buildHfDataset, o as runRolloutReleaseCli, p as scrubText, r as parseRolloutReleaseArgs, s as SCRUB_RULES, t as ROLLOUT_RELEASE_USAGE, u as emptyScrubCounts, v as assertGateReport, w as readRolloutLedger, x as releaseRowRefs, y as gatedRolloutIds } from "../hf-dataset-DBJXXoY1.js";
|
|
6
6
|
import { t as mintRolloutRows } from "../mint-BvkwcYZU.js";
|
|
7
|
-
import { a as readOpencodeSessionMessages, c as findClaudeTranscripts, i as openOpencodeDb, n as findOpencodeSessionById, o as DEFAULT_CLAUDE_PROJECTS_DIR, r as findOpencodeSessionsByDirectory, s as claudeProjectSlug, t as DEFAULT_OPENCODE_DB, u as readClaudeTranscript } from "../opencode-sqlite-
|
|
7
|
+
import { a as readOpencodeSessionMessages, c as findClaudeTranscripts, i as openOpencodeDb, n as findOpencodeSessionById, o as DEFAULT_CLAUDE_PROJECTS_DIR, r as findOpencodeSessionsByDirectory, s as claudeProjectSlug, t as DEFAULT_OPENCODE_DB, u as readClaudeTranscript } from "../opencode-sqlite-8r6WUfHc.js";
|
|
8
8
|
export { ATIF_SCHEMA_VERSION, CHAT_ROLES, DEFAULT_CLAUDE_PROJECTS_DIR, DEFAULT_OPENCODE_DB, FORMAT_FILES, FORMAT_GATE_DISPOSITION, GATE_CHECKS, GATE_CHECK_IDS, GATE_POLICIES, HARBOR_IMPORT_GAP, RELEASE_FORMATS, ROLLOUT_CAPTURES, ROLLOUT_RELEASE_USAGE, ROLLOUT_ROLES, ROLLOUT_SCHEMA, ROLLOUT_SPLITS, SCRUB_RULES, TRAINABLE_SPLITS, addScrubCounts, appendRolloutLines, assertGateReport, assertMinted, assertMintedLines, assertRolloutLine, buildDatasetCard, buildHfDataset, claudeProjectSlug, defaultRolloutScrubber, emptyScrubCounts, findClaudeTranscripts, findOpencodeSessionById, findOpencodeSessionsByDirectory, fromHarborTrajectory, gateErrors, gateGamedOutcome, gatedEvidenceOf, gatedRolloutIds, isRealnessGated, isRolloutLine, isTrainableSplit, measureFormatGate, mintRolloutRows, observedScore, observedSplitScore, openOpencodeDb, parseRolloutReleaseArgs, planPushCommand, pushDataset, readClaudeTranscript, readOpencodeSessionMessages, readRolloutJournal, readRolloutLedger, realnessLabels, relabelImportedSplit, releaseRowRefs, runRolloutReleaseCli, scoreOrigin, scrubLines, scrubRolloutLine, scrubText, toHarborTrajectories, toHarborTrajectory, toJsonl, toRewardRows, toRftItem, toRftItems, toSftRows, toVerifiersRolloutOutput, toVerifiersRolloutOutputs, trainingReward, trainingScore, validateRolloutLine, writeRolloutLedger };
|
|
@@ -2,7 +2,7 @@ import { a as ROLLOUT_SPLITS, i as ROLLOUT_SCHEMA, n as ROLLOUT_CAPTURES, r as R
|
|
|
2
2
|
import "./exporters-q9iL-2Jf.js";
|
|
3
3
|
import "./hf-dataset-DBJXXoY1.js";
|
|
4
4
|
import "./mint-BvkwcYZU.js";
|
|
5
|
-
import "./opencode-sqlite-
|
|
5
|
+
import "./opencode-sqlite-8r6WUfHc.js";
|
|
6
6
|
//#region src/rollout/interchange/harbor.ts
|
|
7
7
|
/**
|
|
8
8
|
* Harbor ATIF-v1.7 interchange — `tangle.rollout.v1` ⇄ Agent Trajectory
|
|
@@ -621,4 +621,4 @@ function relabelImportedSplit(lines, split) {
|
|
|
621
621
|
//#endregion
|
|
622
622
|
export { toHarborTrajectories as a, relabelImportedSplit as i, HARBOR_IMPORT_GAP as n, toHarborTrajectory as o, fromHarborTrajectory as r, ATIF_SCHEMA_VERSION as t };
|
|
623
623
|
|
|
624
|
-
//# sourceMappingURL=rollout-
|
|
624
|
+
//# sourceMappingURL=rollout-CreDz__7.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rollout-CeTlDrf6.js","names":[],"sources":["../src/rollout/interchange/harbor.ts"],"sourcesContent":["/**\n * Harbor ATIF-v1.7 interchange — `tangle.rollout.v1` ⇄ Agent Trajectory\n * Interchange Format.\n *\n * ATIF is the portability format (spec:\n * https://www.harborframework.com/docs/agents/trajectory-format, normative\n * RFC: harbor-framework/harbor `rfcs/0001-trajectory-format.md`). It sits\n * BELOW the waist of the rollout hourglass in both directions — export reads\n * `RolloutLine[]`, import writes `RolloutLine[]` — and it is never a source\n * of training labels:\n *\n * ATIF models NO reward, NO judge verdict, NO task/split coordinates.\n *\n * Consequences, both deliberate:\n * - EXPORT drops `outcome.reward`, `outcome.reward_source` and\n * `outcome.verdict` entirely. They are not smuggled into `extra`: a\n * third-party reading our ATIF file must not be able to mistake an\n * agent-eval judge score for something ATIF sanctioned.\n * - IMPORT therefore mints UNLABELED lines: `reward: null` (the existing\n * \"null reward is a labeled gap, never 0\" semantics), `verdict: null`,\n * and a `provenance.gap` naming the missing label. An imported\n * trajectory is not a training example until a judge scores it.\n *\n * Everything else we own that ATIF has no field for travels in a namespaced\n * escrow at `extra.tangle.*`, so our own round-trip is exact while a foreign\n * reader can ignore it. Fields that neither ATIF nor the escrow can carry\n * come back explicitly null / fail-closed, never invented.\n *\n * THE ESCROW IS NAMESPACED, NOT AUTHENTICATED. Anyone can write\n * `extra.tangle.*` into a file. So the escrow may restore what a value IS, but\n * never what a line is ALLOWED to do: `task.split` is forced to `holdout` on\n * every import regardless of what the document claims, and promoting an\n * imported trajectory to a trainable split is an explicit, greppable act\n * (`relabelImportedSplit`) rather than a property of the file. The document\n * keeps its claim — the claim just is not authority.\n *\n * Multi-agent shape differs on purpose. ATIF EMBEDS children in\n * `subagent_trajectories`; we keep a flat ledger with a normalized\n * `parent_rollout_id` edge. Export assembles the tree, import flattens it.\n * `session_id` is RUN-scoped in ATIF, so it carries `run_id` — the coordinate\n * that is shared by every invocation of one run — not `rollout_id`, which\n * identifies a single invocation and would split one run across session ids.\n *\n * ROUND-TRIPPING IS IDEMPOTENT: `import(export(import(export(x))))` is\n * byte-identical to `import(export(x))`. Import composes `provenance.gap` as a\n * de-duplicated ordered set rather than appending, and it emits every\n * `ChatMessage` with keys in the canonical schema order (role, content,\n * reasoning_content, tool_calls, tool_call_id, name, is_copied_context), so a\n * ledger hashed on serialized bytes sees no diff across further passes. The\n * FIRST import may re-order a producer's keys — that is the canonicalization.\n *\n * NOT building a Letta converter. Letta's trajectory-v1 is a strict subset of\n * what we need from ATIF here — no per-step or aggregate cost, no\n * multi-agent/subagent structure, no token-id or logprob channel — so a Letta\n * sink would carry less than this one and add a second format to keep\n * correct. Decision recorded in docs/rollout.md; do not re-litigate without a\n * concrete consumer that reads Letta and cannot read ATIF.\n */\n\nimport {\n assertRolloutLine,\n type ChatMessage,\n type ChatRole,\n type ChatToolCall,\n type GatedEvidence,\n ROLLOUT_CAPTURES,\n ROLLOUT_ROLES,\n ROLLOUT_SCHEMA,\n ROLLOUT_SPLITS,\n type RolloutArtifacts,\n type RolloutCapture,\n type RolloutCostBlock,\n type RolloutLine,\n type RolloutPolicy,\n type RolloutRole,\n type RolloutSplit,\n type RolloutStep,\n type RolloutTask,\n type ToolDef,\n} from '../schema'\n\nexport const ATIF_SCHEMA_VERSION = 'ATIF-v1.7'\n\n/** Gap note on every imported line — ATIF carries no verdict, so nothing is scored. */\nexport const HARBOR_IMPORT_GAP = 'imported from Harbor ATIF; no verdict'\n\n/** Namespaced escrow key for everything ATIF does not model but we must not lose. */\nconst ESCROW = 'tangle'\n\n/**\n * Marks a step we synthesized purely to hold tool results that answered no\n * assistant turn IN THIS DOCUMENT. ATIF has no `tool` source, so such results\n * need a carrier step; the marker lets import drop the carrier instead of\n * inventing a turn.\n *\n * A carrier's results carry NO `source_call_id`. RFC 0001 rule 2 requires every\n * `source_call_id` to match a `tool_call_id` in the same step's `tool_calls`,\n * and a carrier declares no calls (a `system` step cannot legally make one), so\n * emitting the id there would produce an invalid document. The id is escrowed\n * instead and restored verbatim on import — the link survives without the\n * document lying about who made the call.\n */\nconst TOOL_RESULTS_ONLY = 'tool-results-only'\n\n// ---------------------------------------------------------------------------\n// ATIF-v1.7 wire types (RFC 0001). Optional fields are optional here too.\n// ---------------------------------------------------------------------------\n\nexport type HarborStepSource = 'system' | 'user' | 'agent'\n\nexport interface HarborImageSource {\n media_type: string\n path: string\n}\n\nexport interface HarborContentPart {\n type: 'text' | 'image'\n text?: string\n source?: HarborImageSource\n}\n\nexport interface HarborToolCall {\n tool_call_id: string\n function_name: string\n /** ATIF requires a decoded JSON object here, unlike our raw argument string. */\n arguments: Record<string, unknown>\n extra?: Record<string, unknown>\n}\n\nexport interface HarborSubagentTrajectoryRef {\n trajectory_id?: string\n trajectory_path?: string\n /** Informational only since v1.7 — never a resolution key. */\n session_id?: string\n extra?: Record<string, unknown>\n}\n\nexport interface HarborObservationResult {\n source_call_id?: string\n content?: string | HarborContentPart[]\n subagent_trajectory_ref?: HarborSubagentTrajectoryRef[]\n extra?: Record<string, unknown>\n}\n\nexport interface HarborObservation {\n results: HarborObservationResult[]\n}\n\nexport interface HarborMetrics {\n prompt_tokens?: number\n completion_tokens?: number\n cached_tokens?: number\n cost_usd?: number\n prompt_token_ids?: number[]\n completion_token_ids?: number[]\n logprobs?: number[]\n extra?: Record<string, unknown>\n}\n\nexport interface HarborStep {\n /** Ordinal, sequential from 1. */\n step_id: number\n timestamp?: string\n source: HarborStepSource\n model_name?: string\n reasoning_effort?: string | number\n message: string | HarborContentPart[]\n reasoning_content?: string\n tool_calls?: HarborToolCall[]\n observation?: HarborObservation\n metrics?: HarborMetrics\n llm_call_count?: number\n is_copied_context?: boolean\n extra?: Record<string, unknown>\n}\n\nexport interface HarborAgent {\n name: string\n version: string\n model_name?: string\n /** OpenAI function-calling schema — byte-identical to our `ToolDef`. */\n tool_definitions?: ToolDef[]\n extra?: Record<string, unknown>\n}\n\nexport interface HarborFinalMetrics {\n total_prompt_tokens?: number\n total_completion_tokens?: number\n total_cached_tokens?: number\n total_cost_usd?: number\n total_steps?: number\n extra?: Record<string, unknown>\n}\n\nexport interface HarborTrajectory {\n schema_version: string\n session_id?: string\n /** Required on embedded subagents; we always set it so lines stay joinable. */\n trajectory_id?: string\n agent: HarborAgent\n steps: HarborStep[]\n notes?: string\n final_metrics?: HarborFinalMetrics\n continued_trajectory_ref?: string\n subagent_trajectories?: HarborTrajectory[]\n extra?: Record<string, unknown>\n}\n\n// ---------------------------------------------------------------------------\n// Shared helpers\n// ---------------------------------------------------------------------------\n\nconst isRecord = (v: unknown): v is Record<string, unknown> =>\n typeof v === 'object' && v !== null && !Array.isArray(v)\n\nconst asString = (v: unknown): string | undefined => (typeof v === 'string' ? v : undefined)\n\nconst asNumberOrNull = (v: unknown): number | null =>\n typeof v === 'number' && Number.isFinite(v) ? v : null\n\nconst asIntegerOrUndefined = (v: unknown): number | undefined =>\n Number.isInteger(v) ? (v as number) : undefined\n\nconst asNumberArray = (v: unknown): number[] | undefined =>\n Array.isArray(v) && v.every((n) => typeof n === 'number' && Number.isFinite(n))\n ? (v as number[])\n : undefined\n\nconst asIntegerArray = (v: unknown): number[] | undefined =>\n Array.isArray(v) && v.every((n) => Number.isInteger(n)) ? (v as number[]) : undefined\n\n/**\n * Builds a `ChatMessage` with keys in the schema's declaration order.\n *\n * Object key order is insertion order in JS, so a message assembled\n * conditionally field-by-field serializes differently depending on which\n * optional fields were present — which makes a byte-hashed ledger see a diff\n * across an import that changed nothing. One builder, one order, stable bytes.\n */\nfunction canonicalChatMessage(parts: {\n role: ChatRole\n content: string | null\n reasoning_content?: string\n tool_calls?: ChatToolCall[]\n tool_call_id?: string\n name?: string\n is_copied_context?: boolean\n}): ChatMessage {\n const message: ChatMessage = { role: parts.role, content: parts.content }\n if (parts.reasoning_content !== undefined) message.reasoning_content = parts.reasoning_content\n if (parts.tool_calls !== undefined) message.tool_calls = parts.tool_calls\n if (parts.tool_call_id !== undefined) message.tool_call_id = parts.tool_call_id\n if (parts.name !== undefined) message.name = parts.name\n if (parts.is_copied_context === true) message.is_copied_context = true\n return message\n}\n\n/** Reads the `extra.tangle` escrow, tolerating a foreign file that has none. */\nfunction escrowOf(extra: Record<string, unknown> | undefined): Record<string, unknown> | undefined {\n if (!isRecord(extra)) return undefined\n const value = extra[ESCROW]\n return isRecord(value) ? value : undefined\n}\n\nfunction escrowSection(\n escrow: Record<string, unknown> | undefined,\n key: string,\n): Record<string, unknown> | undefined {\n if (escrow === undefined) return undefined\n const value = escrow[key]\n return isRecord(value) ? value : undefined\n}\n\n// ---------------------------------------------------------------------------\n// Export: RolloutLine[] → ATIF trajectory tree\n// ---------------------------------------------------------------------------\n\nfunction toHarborToolCall(call: ChatToolCall): HarborToolCall {\n // ATIF requires `arguments` to be a JSON object; ours is the raw\n // JSON-encoded string the model emitted, and models really do emit\n // malformed ones. Keep the exact bytes in `extra` so import restores the\n // string verbatim instead of re-serializing a normalized parse.\n let parsed: Record<string, unknown> | undefined\n try {\n const decoded: unknown = JSON.parse(call.function.arguments)\n if (isRecord(decoded)) parsed = decoded\n } catch {\n parsed = undefined\n }\n return {\n tool_call_id: call.id,\n function_name: call.function.name,\n arguments: parsed ?? {},\n extra: { [ESCROW]: { arguments_raw: call.function.arguments } },\n }\n}\n\n/**\n * `linked` = this result is attached to the step that actually declared the\n * call, so `source_call_id` is legal (RFC 0001 rule 2). When it is not, the id\n * goes to escrow instead of onto the wire.\n */\nfunction toObservationResult(message: ChatMessage, linked: boolean): HarborObservationResult {\n const result: HarborObservationResult = {}\n if (linked && message.tool_call_id !== undefined) result.source_call_id = message.tool_call_id\n if (message.content !== null) result.content = message.content\n const escrow: Record<string, unknown> = {}\n if (!linked && message.tool_call_id !== undefined) escrow.source_call_id = message.tool_call_id\n if (message.name !== undefined) escrow.name = message.name\n // `content: null` on a tool turn is meaningful (a tool that returned\n // nothing) and is not the same as the empty string ATIF would round-trip it to.\n if (message.content === null) escrow.content_null = true\n if (message.reasoning_content !== undefined) escrow.reasoning_content = message.reasoning_content\n if (message.is_copied_context === true) escrow.is_copied_context = true\n if (Object.keys(escrow).length > 0) result.extra = { [ESCROW]: escrow }\n return result\n}\n\n/** True when `step` is the agent turn that declared `callId` — the rule-2 test. */\nfunction declaresCall(step: HarborStep, callId: string | undefined): boolean {\n if (callId === undefined) return false\n return step.tool_calls?.some((call) => call.tool_call_id === callId) === true\n}\n\n/**\n * Attaches the four RL fields lifted from ATIF onto the agent step the span\n * describes. They are ALSO escrowed with the whole span under `extra.tangle`,\n * on purpose: the escrow is how our own round-trip stays exact, and these\n * native fields are how a foreign consumer — which never reads our escrow —\n * gets the logprobs and token ids at all. A field carried only in the escrow is\n * not an interchange field.\n */\nfunction applySpanMetrics(step: HarborStep, span: RolloutStep | undefined): void {\n if (span === undefined) return\n if (span.llm_call_count !== undefined) step.llm_call_count = span.llm_call_count\n const metrics: HarborMetrics = {}\n if (span.prompt_token_ids !== undefined) metrics.prompt_token_ids = span.prompt_token_ids\n if (span.completion_token_ids !== undefined) {\n metrics.completion_token_ids = span.completion_token_ids\n }\n if (span.logprobs !== undefined) metrics.logprobs = span.logprobs\n if (Object.keys(metrics).length > 0) step.metrics = metrics\n}\n\n/**\n * Coalescing fold, not a 1:1 map: ATIF has no `tool` source, so a tool result\n * becomes an `observation.results[]` entry on the agent step THAT DECLARED ITS\n * `tool_call_id`.\n *\n * Linking by id, not by adjacency. Adjacency emitted invalid documents in three\n * shapes the RFC forbids — an assistant turn with no `tool_calls` swallowing the\n * results that followed it, a result whose id matched none of the preceding\n * step's calls, and an unanswered result riding a `system` step that carried a\n * `source_call_id` it could never declare. Attaching only to the step that owns\n * the id also preserves message order exactly: a result either joins the step\n * immediately before it or becomes its own carrier at its own position.\n *\n * `line.steps` span projections are matched to agent steps in order (k-th llm\n * span → k-th agent step) purely to fill ATIF's native per-step `metrics`;\n * extra spans on either side are simply not matched, never invented.\n */\nfunction messagesToSteps(line: RolloutLine): HarborStep[] {\n const steps: HarborStep[] = []\n const llmSpans = (line.steps ?? []).filter((span) => span.kind === 'llm')\n let nextSpan = 0\n for (const message of line.messages) {\n if (message.role === 'tool') {\n const previous = steps[steps.length - 1]\n if (previous !== undefined && declaresCall(previous, message.tool_call_id)) {\n if (previous.observation === undefined) previous.observation = { results: [] }\n previous.observation.results.push(toObservationResult(message, true))\n continue\n }\n // A tool result answering no assistant turn in this document (truncated or\n // reconstructed transcript). It still has to survive, so it rides a marked\n // carrier step whose observation states no call id.\n const carrier: HarborStep = {\n step_id: steps.length + 1,\n source: 'system',\n message: '',\n observation: { results: [toObservationResult(message, false)] },\n extra: { [ESCROW]: { synthetic: TOOL_RESULTS_ONLY } },\n }\n if (message.is_copied_context === true) carrier.is_copied_context = true\n steps.push(carrier)\n continue\n }\n const step: HarborStep = {\n step_id: steps.length + 1,\n source: message.role === 'assistant' ? 'agent' : message.role,\n message: message.content ?? '',\n }\n const escrow: Record<string, unknown> = {}\n if (message.content === null) escrow.content_null = true\n if (message.name !== undefined) escrow.name = message.name\n if (message.role === 'assistant') {\n if (line.policy.model !== null) step.model_name = line.policy.model\n if (message.reasoning_content !== undefined) {\n step.reasoning_content = message.reasoning_content\n }\n if (message.tool_calls !== undefined && message.tool_calls.length > 0) {\n step.tool_calls = message.tool_calls.map(toHarborToolCall)\n }\n applySpanMetrics(step, llmSpans[nextSpan])\n nextSpan += 1\n } else if (message.reasoning_content !== undefined) {\n // ATIF confines `reasoning_content` to agent steps; ours is not confined.\n escrow.reasoning_content = message.reasoning_content\n }\n // RFC 0001 rule 7: a copied-context turn was not authored by this agent, and\n // an SFT pipeline MUST exclude it. Native ATIF field, both directions.\n if (message.is_copied_context === true) step.is_copied_context = true\n if (Object.keys(escrow).length > 0) step.extra = { [ESCROW]: escrow }\n steps.push(step)\n }\n return steps\n}\n\nfunction finalMetricsOf(line: RolloutLine, stepCount: number): HarborFinalMetrics {\n const metrics: HarborFinalMetrics = {}\n if (line.cost.tokens_in !== null) metrics.total_prompt_tokens = line.cost.tokens_in\n if (line.cost.tokens_out !== null) metrics.total_completion_tokens = line.cost.tokens_out\n if (line.cost.cache_read !== null) metrics.total_cached_tokens = line.cost.cache_read\n // Omitted, never 0, when cost was not captured — a fake 0 is a lie about spend.\n if (line.cost.usd !== null) metrics.total_cost_usd = line.cost.usd\n metrics.total_steps = stepCount\n // ATIF has no aggregate field for these three; `reasoning_tokens` under\n // `extra` is the key the RFC's own worked example uses.\n const extra: Record<string, unknown> = {}\n if (line.cost.tokens_reasoning !== null) extra.reasoning_tokens = line.cost.tokens_reasoning\n if (line.cost.cache_write !== null) extra.cache_write_tokens = line.cost.cache_write\n if (line.cost.wall_s !== null) extra.wall_s = line.cost.wall_s\n if (line.cost.llm_call_count !== undefined && line.cost.llm_call_count !== null) {\n extra.llm_call_count = line.cost.llm_call_count\n }\n if (Object.keys(extra).length > 0) metrics.extra = extra\n return metrics\n}\n\nfunction notesOf(line: RolloutLine): string | undefined {\n const parts: string[] = []\n if (line.provenance.gap !== undefined) parts.push(line.provenance.gap)\n if (line.outcome.realness_gated === true) {\n // ATIF has no gate field. A third-party consumer that ignores `extra`\n // would otherwise see a gamed trajectory with nothing marking it, so the\n // flag is stated in prose as well. This export carries no reward at all,\n // so it is not a training-data door — but it is an audit record.\n parts.push('realness-gated: this run faked its success signal (anti-Goodhart gate fired)')\n }\n return parts.length > 0 ? parts.join(' | ') : undefined\n}\n\nfunction toTrajectoryNode(line: RolloutLine): HarborTrajectory {\n const steps = messagesToSteps(line)\n const trajectory: HarborTrajectory = {\n schema_version: ATIF_SCHEMA_VERSION,\n // RUN-scoped, per the spec — so it is `run_id`, the coordinate every\n // invocation of one run shares. `rollout_id` identifies a single\n // invocation: using it gave two roots of the same run different session\n // ids, and foreign tooling that groups by session_id would split the run.\n session_id: line.run_id,\n trajectory_id: line.rollout_id,\n agent: {\n // ATIF requires both; ours are nullable, so a null is substituted here\n // and restored on import from the escrowed policy — never guessed back.\n name: line.policy.harness ?? 'unknown',\n version: line.policy.harness_version ?? '0.0.0',\n ...(line.policy.model !== null ? { model_name: line.policy.model } : {}),\n ...(line.tool_defs.length > 0 ? { tool_definitions: line.tool_defs } : {}),\n },\n steps,\n final_metrics: finalMetricsOf(line, steps.length),\n extra: {\n [ESCROW]: {\n schema: line.schema,\n rollout_id: line.rollout_id,\n parent_rollout_id: line.parent_rollout_id,\n run_id: line.run_id,\n ...(line.experiment_id !== undefined ? { experiment_id: line.experiment_id } : {}),\n ...(line.candidate_id !== undefined ? { candidate_id: line.candidate_id } : {}),\n generation: line.generation,\n candidate_index: line.candidate_index,\n role: line.role,\n task: line.task,\n policy: line.policy,\n // Span projections overlap the same turns as `steps[]`; folding them\n // into ATIF steps would double-count the run, so they stay escrowed.\n ...(line.steps !== undefined ? { spans: line.steps } : {}),\n outcome: {\n // reward / reward_source / verdict are deliberately absent — see the\n // module header. Only the non-scalar outcome fields travel.\n metrics: line.outcome.metrics,\n is_completed: line.outcome.is_completed,\n is_truncated: line.outcome.is_truncated,\n error: line.outcome.error,\n ...(line.outcome.realness_gated !== undefined\n ? { realness_gated: line.outcome.realness_gated }\n : {}),\n },\n artifacts: line.artifacts,\n provenance: line.provenance,\n },\n },\n }\n const notes = notesOf(line)\n if (notes !== undefined) trajectory.notes = notes\n return trajectory\n}\n\ninterface Forest {\n roots: RolloutLine[]\n childrenOf: Map<string, RolloutLine[]>\n}\n\nfunction buildForest(lines: RolloutLine[]): Forest {\n const byId = new Map<string, RolloutLine>()\n for (const line of lines) {\n if (byId.has(line.rollout_id)) {\n throw new Error(`duplicate rollout_id in input: ${line.rollout_id}`)\n }\n byId.set(line.rollout_id, line)\n }\n const roots: RolloutLine[] = []\n const childrenOf = new Map<string, RolloutLine[]>()\n for (const line of lines) {\n const parent = line.parent_rollout_id\n // A parent outside this set is a root OF WHAT WE HAVE: the edge is kept in\n // escrow so a later import restores the dangling pointer instead of nulling it.\n if (parent === null || !byId.has(parent)) {\n roots.push(line)\n continue\n }\n const siblings = childrenOf.get(parent)\n if (siblings === undefined) childrenOf.set(parent, [line])\n else siblings.push(line)\n }\n // Every line has a parent inside the set: the edges form a cycle with no\n // root. Returning zero documents would drop the whole episode silently.\n if (lines.length > 0 && roots.length === 0) {\n throw new Error(\n `parent_rollout_id cycle: no root among ${lines.length} lines (${lines.map((l) => l.rollout_id).join(', ')})`,\n )\n }\n return { roots, childrenOf }\n}\n\nfunction assemble(line: RolloutLine, forest: Forest, onPath: Set<string>): HarborTrajectory {\n if (onPath.has(line.rollout_id)) {\n throw new Error(`parent_rollout_id cycle through rollout_id ${line.rollout_id}`)\n }\n onPath.add(line.rollout_id)\n const node = toTrajectoryNode(line)\n const children = forest.childrenOf.get(line.rollout_id)\n if (children !== undefined && children.length > 0) {\n node.subagent_trajectories = children.map((child) => assemble(child, forest, onPath))\n }\n onPath.delete(line.rollout_id)\n return node\n}\n\n/**\n * Assemble one episode's flat lines into a single ATIF trajectory tree,\n * linked by `parent_rollout_id`.\n *\n * Reward, verdict and split are NOT emitted (ATIF models none of them); the\n * split and the rest of the task coordinates survive only in `extra.tangle`.\n *\n * We deliberately do NOT synthesize an `observation.subagent_trajectory_ref`\n * pointing at each child: our ledger records WHICH invocation spawned a\n * worker, not which STEP did, and attaching the ref to a guessed step would\n * fabricate a causal claim. Children are embedded in `subagent_trajectories`\n * (each with the `trajectory_id` the spec requires) and the edge is stated in\n * the child's escrowed `parent_rollout_id`.\n *\n * Throws when the lines are not one tree — use `toHarborTrajectories` for a forest.\n */\nexport function toHarborTrajectory(lines: RolloutLine[]): HarborTrajectory {\n const trees = toHarborTrajectories(lines)\n if (trees.length === 0) throw new Error('toHarborTrajectory: no lines')\n if (trees.length > 1) {\n const ids = trees.map((t) => t.trajectory_id ?? '?').join(', ')\n throw new Error(\n `toHarborTrajectory: ${trees.length} roots (${ids}) — ATIF is one tree per document; use toHarborTrajectories`,\n )\n }\n return trees[0]!\n}\n\n/** Every independent tree in the input, one ATIF document each. */\nexport function toHarborTrajectories(lines: RolloutLine[]): HarborTrajectory[] {\n const forest = buildForest(lines)\n return forest.roots.map((root) => assemble(root, forest, new Set()))\n}\n\n// ---------------------------------------------------------------------------\n// Import: ATIF trajectory tree → RolloutLine[]\n// ---------------------------------------------------------------------------\n\nfunction contentToString(message: string | HarborContentPart[]): string {\n if (typeof message === 'string') return message\n return message\n .map((part) =>\n part.type === 'image'\n ? // Our chat content is text-only. Describing the image is honest about\n // what the source held; dropping it silently would not be.\n `[image ${part.source?.media_type ?? 'unknown'} ${part.source?.path ?? ''}]`.trim()\n : (part.text ?? ''),\n )\n .join('\\n')\n}\n\nfunction fromHarborToolCall(call: HarborToolCall): ChatToolCall {\n const raw = asString(escrowOf(call.extra)?.arguments_raw)\n return {\n id: call.tool_call_id,\n type: 'function',\n function: { name: call.function_name, arguments: raw ?? JSON.stringify(call.arguments ?? {}) },\n }\n}\n\nfunction fromObservationResult(\n result: HarborObservationResult,\n callId: string | undefined,\n): ChatMessage {\n const escrow = escrowOf(result.extra)\n return canonicalChatMessage({\n role: 'tool',\n content:\n escrow?.content_null === true\n ? null\n : result.content === undefined\n ? ''\n : contentToString(result.content),\n reasoning_content: asString(escrow?.reasoning_content),\n tool_call_id: callId,\n name: asString(escrow?.name),\n is_copied_context: escrow?.is_copied_context === true,\n })\n}\n\nfunction stepsToMessages(steps: HarborStep[]): ChatMessage[] {\n const messages: ChatMessage[] = []\n for (const step of steps) {\n const escrow = escrowOf(step.extra)\n const carrierOnly = escrow?.synthetic === TOOL_RESULTS_ONLY\n if (!carrierOnly) {\n messages.push(\n canonicalChatMessage({\n role: step.source === 'agent' ? 'assistant' : step.source,\n content: escrow?.content_null === true ? null : contentToString(step.message),\n reasoning_content: step.reasoning_content ?? asString(escrow?.reasoning_content),\n tool_calls:\n step.tool_calls !== undefined && step.tool_calls.length > 0\n ? step.tool_calls.map(fromHarborToolCall)\n : undefined,\n name: asString(escrow?.name),\n is_copied_context: step.is_copied_context === true,\n }),\n )\n }\n for (const result of step.observation?.results ?? []) {\n const resultEscrow = escrowOf(result.extra)\n const callId = result.source_call_id ?? asString(resultEscrow?.source_call_id)\n if (carrierOnly) {\n // Our own carrier: every result on it was a tool turn, and its call id\n // (if the transcript had one) is in escrow, not on the wire.\n messages.push(fromObservationResult(result, callId))\n continue\n }\n if (typeof callId === 'string') {\n messages.push(fromObservationResult(result, callId))\n continue\n }\n // ATIF allows a result from a non-tool-calling action. Our chat schema\n // requires `tool_call_id` on a tool turn, so inventing one would forge a\n // link; the text is preserved as a system observation instead.\n if (result.content !== undefined) {\n messages.push(\n canonicalChatMessage({ role: 'system', content: contentToString(result.content) }),\n )\n }\n }\n }\n return messages\n}\n\nfunction taskFrom(escrow: Record<string, unknown> | undefined, fallbackId: string): RolloutTask {\n const task = escrowSection(escrow, 'task')\n return {\n suite: asString(task?.suite) ?? 'harbor-atif-import',\n instance_id: asString(task?.instance_id) ?? fallbackId,\n // ALWAYS holdout — the escrowed claim is read for nothing here.\n //\n // `extra.tangle.task.split` is a namespaced key, not an authenticated one:\n // a hand-written or third-party document can set `split: 'search'` as\n // easily as our own exporter can, and honouring it made \"this file says so\"\n // sufficient to walk into a training export. Trainability is a decision\n // about a file, so it is made by an operator through\n // `relabelImportedSplit`, never by the file about itself. The claim is not\n // destroyed — it stays readable in the source document.\n split: 'holdout',\n seed: asNumberOrNull(task?.seed),\n rep: asIntegerOrUndefined(task?.rep) ?? 0,\n }\n}\n\nfunction policyFrom(\n escrow: Record<string, unknown> | undefined,\n agent: HarborAgent,\n): RolloutPolicy {\n const escrowed = escrowSection(escrow, 'policy')\n if (escrowed !== undefined) {\n // Our own export: restore verbatim, including the nulls ATIF forced us to\n // substitute placeholders for in `agent.name` / `agent.version`.\n return {\n harness: asString(escrowed.harness) ?? null,\n harness_version: asString(escrowed.harness_version) ?? null,\n model: asString(escrowed.model) ?? null,\n provider: asString(escrowed.provider) ?? null,\n profile_commit: asString(escrowed.profile_commit) ?? null,\n ...(escrowed.prompt_hash !== undefined\n ? { prompt_hash: asString(escrowed.prompt_hash) ?? null }\n : {}),\n ...(escrowed.config_hash !== undefined\n ? { config_hash: asString(escrowed.config_hash) ?? null }\n : {}),\n ...(escrowed.agent_profile_cell_id !== undefined\n ? { agent_profile_cell_id: asString(escrowed.agent_profile_cell_id) ?? null }\n : {}),\n sampling: isRecord(escrowed.sampling) ? escrowed.sampling : null,\n }\n }\n return {\n harness: agent.name,\n harness_version: agent.version,\n model: agent.model_name ?? null,\n provider: null,\n profile_commit: null,\n sampling: null,\n }\n}\n\nfunction artifactsFrom(escrow: Record<string, unknown> | undefined): RolloutArtifacts {\n const artifacts = escrowSection(escrow, 'artifacts')\n return {\n patch_path: asString(artifacts?.patch_path) ?? null,\n run_dir: asString(artifacts?.run_dir) ?? null,\n transcript_ref: asString(artifacts?.transcript_ref) ?? null,\n }\n}\n\nfunction costFrom(final: HarborFinalMetrics | undefined): RolloutCostBlock {\n const rawExtra = final?.extra\n const extra = isRecord(rawExtra) ? rawExtra : undefined\n const calls = asIntegerOrUndefined(extra?.llm_call_count)\n return {\n usd: asNumberOrNull(final?.total_cost_usd),\n tokens_in: asNumberOrNull(final?.total_prompt_tokens),\n tokens_out: asNumberOrNull(final?.total_completion_tokens),\n tokens_reasoning: asNumberOrNull(extra?.reasoning_tokens),\n cache_read: asNumberOrNull(final?.total_cached_tokens),\n cache_write: asNumberOrNull(extra?.cache_write_tokens),\n wall_s: asNumberOrNull(extra?.wall_s),\n ...(calls !== undefined ? { llm_call_count: calls } : {}),\n }\n}\n\n/**\n * Recovers span projections from ATIF's NATIVE per-step channel, for documents\n * with no `extra.tangle.spans` escrow — i.e. everything a foreign producer\n * writes. Without this the logprobs and token ids a Harbor-native trainer\n * records would be read, validated, and then dropped on the floor.\n *\n * Only steps that actually carry one of the four fields produce a span: an\n * agent step with no metrics means \"not captured\", and inventing an empty span\n * for it would claim the run had a shape we did not observe.\n */\nfunction spansFromSteps(steps: HarborStep[]): RolloutStep[] {\n const spans: RolloutStep[] = []\n for (const step of steps) {\n if (step.source !== 'agent') continue\n const calls = asIntegerOrUndefined(step.llm_call_count)\n const promptIds = asIntegerArray(step.metrics?.prompt_token_ids)\n const completionIds = asIntegerArray(step.metrics?.completion_token_ids)\n const logprobs = asNumberArray(step.metrics?.logprobs)\n if (\n calls === undefined &&\n promptIds === undefined &&\n completionIds === undefined &&\n logprobs === undefined\n ) {\n continue\n }\n spans.push({\n kind: 'llm',\n name: step.model_name ?? 'chat',\n ...(calls !== undefined ? { llm_call_count: calls } : {}),\n ...(promptIds !== undefined ? { prompt_token_ids: promptIds } : {}),\n ...(completionIds !== undefined ? { completion_token_ids: completionIds } : {}),\n ...(logprobs !== undefined ? { logprobs } : {}),\n })\n }\n return spans\n}\n\n/**\n * Composes `provenance.gap` as an ordered SET of reasons.\n *\n * Appending made the note accrete on every pass (\"…no verdict | …no verdict\"),\n * which both grows without bound and breaks byte-level idempotency for a ledger\n * hashed on its serialized lines.\n */\nfunction composeGap(escrowedGap: string | undefined, added: readonly string[]): string {\n const parts: string[] = []\n const seen = new Set<string>()\n for (const raw of [...(escrowedGap?.split(' | ') ?? []), ...added]) {\n const reason = raw.trim()\n if (reason.length === 0 || seen.has(reason)) continue\n seen.add(reason)\n parts.push(reason)\n }\n return parts.join(' | ')\n}\n\nexport interface FromHarborOptions {\n /** Injected clock for deterministic output when the source carries no capture time. */\n now?: () => Date\n}\n\nfunction nodeToLine(\n trajectory: HarborTrajectory,\n parentId: string | null,\n capturedAt: string,\n): RolloutLine {\n const escrow = escrowOf(trajectory.extra)\n const rolloutId =\n asString(escrow?.rollout_id) ?? trajectory.trajectory_id ?? trajectory.session_id\n if (rolloutId === undefined || rolloutId.length === 0) {\n throw new Error(\n 'fromHarborTrajectory: trajectory has no trajectory_id or session_id — cannot mint a joinable rollout_id without inventing one',\n )\n }\n const outcome = escrowSection(escrow, 'outcome')\n const provenance = escrowSection(escrow, 'provenance')\n const capture = provenance?.capture\n const escrowedGap = asString(provenance?.gap)\n const role = escrow?.role\n const escrowedSpans = escrow?.spans\n // The escrow wins when it exists (our own export: exact, including an empty\n // array, which claims \"captured, none\" rather than \"not captured\"), and the\n // native per-step channel is the fallback (a foreign export: still signal).\n const nativeSpans = spansFromSteps(trajectory.steps)\n const spans: RolloutStep[] | undefined = Array.isArray(escrowedSpans)\n ? (escrowedSpans as RolloutStep[])\n : nativeSpans.length > 0\n ? nativeSpans\n : undefined\n const messages = stepsToMessages(trajectory.steps)\n const line: RolloutLine = {\n schema: ROLLOUT_SCHEMA,\n rollout_id: rolloutId,\n // The tree edge wins for embedded children; for a root, the escrowed\n // pointer may reference a line outside this document and is preserved.\n parent_rollout_id: parentId ?? asString(escrow?.parent_rollout_id) ?? null,\n run_id: asString(escrow?.run_id) ?? trajectory.session_id ?? rolloutId,\n // Required keys on the wire (0.127.0): a foreign document that never\n // stated them imports as explicit `null`, not as an absent field.\n experiment_id: asString(escrow?.experiment_id) ?? null,\n candidate_id: asString(escrow?.candidate_id) ?? null,\n generation: asIntegerOrUndefined(escrow?.generation) ?? null,\n candidate_index: asIntegerOrUndefined(escrow?.candidate_index) ?? null,\n role: ROLLOUT_ROLES.includes(role as RolloutRole) ? (role as RolloutRole) : 'agent',\n task: taskFrom(escrow, rolloutId),\n policy: policyFrom(escrow, trajectory.agent),\n messages,\n tool_defs: trajectory.agent.tool_definitions ?? [],\n ...(spans !== undefined ? { steps: spans } : {}),\n outcome: {\n // ATIF carries no label. Null is the labeled gap; a 0 here would be a\n // fabricated failure and a 1 a fabricated success.\n reward: null,\n reward_source: null,\n verdict: null,\n metrics: isRecord(outcome?.metrics) ? outcome.metrics : {},\n is_completed: typeof outcome?.is_completed === 'boolean' ? outcome.is_completed : true,\n is_truncated:\n typeof outcome?.is_truncated === 'boolean'\n ? outcome.is_truncated\n : trajectory.continued_trajectory_ref !== undefined,\n error: asString(outcome?.error) ?? null,\n // The anti-Goodhart flag is restored when the source document stated\n // it; the wire schema requires the field, so a document that never did\n // imports as `false`. That is safe here because the reward is already\n // forced to `null` (not trainable) and `realness_screened` stays\n // absent = unknown rather than claiming a screen ran.\n realness_gated: outcome?.realness_gated === true,\n },\n cost: costFrom(trajectory.final_metrics),\n artifacts: artifactsFrom(escrow),\n provenance: {\n captured_at: asString(provenance?.captured_at) ?? capturedAt,\n capture: ROLLOUT_CAPTURES.includes(capture as RolloutCapture)\n ? (capture as RolloutCapture)\n : 'backfill',\n gap: composeGap(escrowedGap, [HARBOR_IMPORT_GAP]),\n // Restored for the same reason `realness_gated` is, and with the opposite\n // risk profile from the reward: this is the gated run's own measurement\n // bag, moved off `outcome` by `gateGamedOutcome` so no exporter reads it\n // as training input. Dropping it here would silently destroy the audit\n // trail that says WHY the run was flagged and what it claimed, on the one\n // population an auditor most wants to inspect. It cannot be fail-open —\n // nothing projects `provenance` into a training row.\n ...(isRecord(provenance?.gated_evidence)\n ? { gated_evidence: provenance.gated_evidence as GatedEvidence }\n : {}),\n },\n }\n assertRolloutLine(line, `rollout line imported from ATIF trajectory ${rolloutId}`)\n return line\n}\n\n/**\n * Flatten an ATIF trajectory tree back into `tangle.rollout.v1` lines, parent\n * first, each child carrying `parent_rollout_id`.\n *\n * Every line comes back UNLABELED: `reward`, `reward_source` and `verdict` are\n * null and `provenance.gap` says why. ATIF models no verdict, so scoring an\n * imported trajectory is a judge's job, not this function's. Every line lands\n * on `holdout` whatever the document claims — see `relabelImportedSplit`.\n */\nexport function fromHarborTrajectory(\n trajectory: HarborTrajectory,\n options: FromHarborOptions = {},\n): RolloutLine[] {\n const capturedAt = (options.now?.() ?? new Date()).toISOString()\n const lines: RolloutLine[] = []\n const walk = (node: HarborTrajectory, parentId: string | null, onPath: Set<string>): void => {\n const line = nodeToLine(node, parentId, capturedAt)\n if (onPath.has(line.rollout_id)) {\n throw new Error(`subagent_trajectories cycle through trajectory_id ${line.rollout_id}`)\n }\n onPath.add(line.rollout_id)\n lines.push(line)\n for (const child of node.subagent_trajectories ?? []) {\n walk(child, line.rollout_id, onPath)\n }\n onPath.delete(line.rollout_id)\n }\n walk(trajectory, null, new Set())\n return lines\n}\n\n/**\n * THE explicit door out of `holdout` for imported lines.\n *\n * Import forces `holdout` because a document's own claim about its split is not\n * evidence — anyone can write `extra.tangle.task.split`. Promoting a file to a\n * trainable split is an operator's decision about provenance they verified, so\n * it is a separate, greppable call: `grep relabelImportedSplit` enumerates\n * every place foreign data was declared trainable, which is exactly the audit\n * the trusted-escrow version made impossible.\n *\n * Returns plain `RolloutLine`s. They still have to pass `assertMinted` (and its\n * anti-Goodhart check) to reach an exporter — re-labeling a split is not\n * minting a reward.\n */\nexport function relabelImportedSplit(\n lines: readonly RolloutLine[],\n split: RolloutSplit,\n): RolloutLine[] {\n if (!ROLLOUT_SPLITS.includes(split)) {\n throw new Error(`relabelImportedSplit: unknown split ${String(split)}`)\n }\n return lines.map((line) => ({ ...line, task: { ...line.task, split } }))\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"rollout-CreDz__7.js","names":[],"sources":["../src/rollout/interchange/harbor.ts"],"sourcesContent":["/**\n * Harbor ATIF-v1.7 interchange — `tangle.rollout.v1` ⇄ Agent Trajectory\n * Interchange Format.\n *\n * ATIF is the portability format (spec:\n * https://www.harborframework.com/docs/agents/trajectory-format, normative\n * RFC: harbor-framework/harbor `rfcs/0001-trajectory-format.md`). It sits\n * BELOW the waist of the rollout hourglass in both directions — export reads\n * `RolloutLine[]`, import writes `RolloutLine[]` — and it is never a source\n * of training labels:\n *\n * ATIF models NO reward, NO judge verdict, NO task/split coordinates.\n *\n * Consequences, both deliberate:\n * - EXPORT drops `outcome.reward`, `outcome.reward_source` and\n * `outcome.verdict` entirely. They are not smuggled into `extra`: a\n * third-party reading our ATIF file must not be able to mistake an\n * agent-eval judge score for something ATIF sanctioned.\n * - IMPORT therefore mints UNLABELED lines: `reward: null` (the existing\n * \"null reward is a labeled gap, never 0\" semantics), `verdict: null`,\n * and a `provenance.gap` naming the missing label. An imported\n * trajectory is not a training example until a judge scores it.\n *\n * Everything else we own that ATIF has no field for travels in a namespaced\n * escrow at `extra.tangle.*`, so our own round-trip is exact while a foreign\n * reader can ignore it. Fields that neither ATIF nor the escrow can carry\n * come back explicitly null / fail-closed, never invented.\n *\n * THE ESCROW IS NAMESPACED, NOT AUTHENTICATED. Anyone can write\n * `extra.tangle.*` into a file. So the escrow may restore what a value IS, but\n * never what a line is ALLOWED to do: `task.split` is forced to `holdout` on\n * every import regardless of what the document claims, and promoting an\n * imported trajectory to a trainable split is an explicit, greppable act\n * (`relabelImportedSplit`) rather than a property of the file. The document\n * keeps its claim — the claim just is not authority.\n *\n * Multi-agent shape differs on purpose. ATIF EMBEDS children in\n * `subagent_trajectories`; we keep a flat ledger with a normalized\n * `parent_rollout_id` edge. Export assembles the tree, import flattens it.\n * `session_id` is RUN-scoped in ATIF, so it carries `run_id` — the coordinate\n * that is shared by every invocation of one run — not `rollout_id`, which\n * identifies a single invocation and would split one run across session ids.\n *\n * ROUND-TRIPPING IS IDEMPOTENT: `import(export(import(export(x))))` is\n * byte-identical to `import(export(x))`. Import composes `provenance.gap` as a\n * de-duplicated ordered set rather than appending, and it emits every\n * `ChatMessage` with keys in the canonical schema order (role, content,\n * reasoning_content, tool_calls, tool_call_id, name, is_copied_context), so a\n * ledger hashed on serialized bytes sees no diff across further passes. The\n * FIRST import may re-order a producer's keys — that is the canonicalization.\n *\n * NOT building a Letta converter. Letta's trajectory-v1 is a strict subset of\n * what we need from ATIF here — no per-step or aggregate cost, no\n * multi-agent/subagent structure, no token-id or logprob channel — so a Letta\n * sink would carry less than this one and add a second format to keep\n * correct. Decision recorded in docs/rollout.md; do not re-litigate without a\n * concrete consumer that reads Letta and cannot read ATIF.\n */\n\nimport {\n assertRolloutLine,\n type ChatMessage,\n type ChatRole,\n type ChatToolCall,\n type GatedEvidence,\n ROLLOUT_CAPTURES,\n ROLLOUT_ROLES,\n ROLLOUT_SCHEMA,\n ROLLOUT_SPLITS,\n type RolloutArtifacts,\n type RolloutCapture,\n type RolloutCostBlock,\n type RolloutLine,\n type RolloutPolicy,\n type RolloutRole,\n type RolloutSplit,\n type RolloutStep,\n type RolloutTask,\n type ToolDef,\n} from '../schema'\n\nexport const ATIF_SCHEMA_VERSION = 'ATIF-v1.7'\n\n/** Gap note on every imported line — ATIF carries no verdict, so nothing is scored. */\nexport const HARBOR_IMPORT_GAP = 'imported from Harbor ATIF; no verdict'\n\n/** Namespaced escrow key for everything ATIF does not model but we must not lose. */\nconst ESCROW = 'tangle'\n\n/**\n * Marks a step we synthesized purely to hold tool results that answered no\n * assistant turn IN THIS DOCUMENT. ATIF has no `tool` source, so such results\n * need a carrier step; the marker lets import drop the carrier instead of\n * inventing a turn.\n *\n * A carrier's results carry NO `source_call_id`. RFC 0001 rule 2 requires every\n * `source_call_id` to match a `tool_call_id` in the same step's `tool_calls`,\n * and a carrier declares no calls (a `system` step cannot legally make one), so\n * emitting the id there would produce an invalid document. The id is escrowed\n * instead and restored verbatim on import — the link survives without the\n * document lying about who made the call.\n */\nconst TOOL_RESULTS_ONLY = 'tool-results-only'\n\n// ---------------------------------------------------------------------------\n// ATIF-v1.7 wire types (RFC 0001). Optional fields are optional here too.\n// ---------------------------------------------------------------------------\n\nexport type HarborStepSource = 'system' | 'user' | 'agent'\n\nexport interface HarborImageSource {\n media_type: string\n path: string\n}\n\nexport interface HarborContentPart {\n type: 'text' | 'image'\n text?: string\n source?: HarborImageSource\n}\n\nexport interface HarborToolCall {\n tool_call_id: string\n function_name: string\n /** ATIF requires a decoded JSON object here, unlike our raw argument string. */\n arguments: Record<string, unknown>\n extra?: Record<string, unknown>\n}\n\nexport interface HarborSubagentTrajectoryRef {\n trajectory_id?: string\n trajectory_path?: string\n /** Informational only since v1.7 — never a resolution key. */\n session_id?: string\n extra?: Record<string, unknown>\n}\n\nexport interface HarborObservationResult {\n source_call_id?: string\n content?: string | HarborContentPart[]\n subagent_trajectory_ref?: HarborSubagentTrajectoryRef[]\n extra?: Record<string, unknown>\n}\n\nexport interface HarborObservation {\n results: HarborObservationResult[]\n}\n\nexport interface HarborMetrics {\n prompt_tokens?: number\n completion_tokens?: number\n cached_tokens?: number\n cost_usd?: number\n prompt_token_ids?: number[]\n completion_token_ids?: number[]\n logprobs?: number[]\n extra?: Record<string, unknown>\n}\n\nexport interface HarborStep {\n /** Ordinal, sequential from 1. */\n step_id: number\n timestamp?: string\n source: HarborStepSource\n model_name?: string\n reasoning_effort?: string | number\n message: string | HarborContentPart[]\n reasoning_content?: string\n tool_calls?: HarborToolCall[]\n observation?: HarborObservation\n metrics?: HarborMetrics\n llm_call_count?: number\n is_copied_context?: boolean\n extra?: Record<string, unknown>\n}\n\nexport interface HarborAgent {\n name: string\n version: string\n model_name?: string\n /** OpenAI function-calling schema — byte-identical to our `ToolDef`. */\n tool_definitions?: ToolDef[]\n extra?: Record<string, unknown>\n}\n\nexport interface HarborFinalMetrics {\n total_prompt_tokens?: number\n total_completion_tokens?: number\n total_cached_tokens?: number\n total_cost_usd?: number\n total_steps?: number\n extra?: Record<string, unknown>\n}\n\nexport interface HarborTrajectory {\n schema_version: string\n session_id?: string\n /** Required on embedded subagents; we always set it so lines stay joinable. */\n trajectory_id?: string\n agent: HarborAgent\n steps: HarborStep[]\n notes?: string\n final_metrics?: HarborFinalMetrics\n continued_trajectory_ref?: string\n subagent_trajectories?: HarborTrajectory[]\n extra?: Record<string, unknown>\n}\n\n// ---------------------------------------------------------------------------\n// Shared helpers\n// ---------------------------------------------------------------------------\n\nconst isRecord = (v: unknown): v is Record<string, unknown> =>\n typeof v === 'object' && v !== null && !Array.isArray(v)\n\nconst asString = (v: unknown): string | undefined => (typeof v === 'string' ? v : undefined)\n\nconst asNumberOrNull = (v: unknown): number | null =>\n typeof v === 'number' && Number.isFinite(v) ? v : null\n\nconst asIntegerOrUndefined = (v: unknown): number | undefined =>\n Number.isInteger(v) ? (v as number) : undefined\n\nconst asNumberArray = (v: unknown): number[] | undefined =>\n Array.isArray(v) && v.every((n) => typeof n === 'number' && Number.isFinite(n))\n ? (v as number[])\n : undefined\n\nconst asIntegerArray = (v: unknown): number[] | undefined =>\n Array.isArray(v) && v.every((n) => Number.isInteger(n)) ? (v as number[]) : undefined\n\n/**\n * Builds a `ChatMessage` with keys in the schema's declaration order.\n *\n * Object key order is insertion order in JS, so a message assembled\n * conditionally field-by-field serializes differently depending on which\n * optional fields were present — which makes a byte-hashed ledger see a diff\n * across an import that changed nothing. One builder, one order, stable bytes.\n */\nfunction canonicalChatMessage(parts: {\n role: ChatRole\n content: string | null\n reasoning_content?: string\n tool_calls?: ChatToolCall[]\n tool_call_id?: string\n name?: string\n is_copied_context?: boolean\n}): ChatMessage {\n const message: ChatMessage = { role: parts.role, content: parts.content }\n if (parts.reasoning_content !== undefined) message.reasoning_content = parts.reasoning_content\n if (parts.tool_calls !== undefined) message.tool_calls = parts.tool_calls\n if (parts.tool_call_id !== undefined) message.tool_call_id = parts.tool_call_id\n if (parts.name !== undefined) message.name = parts.name\n if (parts.is_copied_context === true) message.is_copied_context = true\n return message\n}\n\n/** Reads the `extra.tangle` escrow, tolerating a foreign file that has none. */\nfunction escrowOf(extra: Record<string, unknown> | undefined): Record<string, unknown> | undefined {\n if (!isRecord(extra)) return undefined\n const value = extra[ESCROW]\n return isRecord(value) ? value : undefined\n}\n\nfunction escrowSection(\n escrow: Record<string, unknown> | undefined,\n key: string,\n): Record<string, unknown> | undefined {\n if (escrow === undefined) return undefined\n const value = escrow[key]\n return isRecord(value) ? value : undefined\n}\n\n// ---------------------------------------------------------------------------\n// Export: RolloutLine[] → ATIF trajectory tree\n// ---------------------------------------------------------------------------\n\nfunction toHarborToolCall(call: ChatToolCall): HarborToolCall {\n // ATIF requires `arguments` to be a JSON object; ours is the raw\n // JSON-encoded string the model emitted, and models really do emit\n // malformed ones. Keep the exact bytes in `extra` so import restores the\n // string verbatim instead of re-serializing a normalized parse.\n let parsed: Record<string, unknown> | undefined\n try {\n const decoded: unknown = JSON.parse(call.function.arguments)\n if (isRecord(decoded)) parsed = decoded\n } catch {\n parsed = undefined\n }\n return {\n tool_call_id: call.id,\n function_name: call.function.name,\n arguments: parsed ?? {},\n extra: { [ESCROW]: { arguments_raw: call.function.arguments } },\n }\n}\n\n/**\n * `linked` = this result is attached to the step that actually declared the\n * call, so `source_call_id` is legal (RFC 0001 rule 2). When it is not, the id\n * goes to escrow instead of onto the wire.\n */\nfunction toObservationResult(message: ChatMessage, linked: boolean): HarborObservationResult {\n const result: HarborObservationResult = {}\n if (linked && message.tool_call_id !== undefined) result.source_call_id = message.tool_call_id\n if (message.content !== null) result.content = message.content\n const escrow: Record<string, unknown> = {}\n if (!linked && message.tool_call_id !== undefined) escrow.source_call_id = message.tool_call_id\n if (message.name !== undefined) escrow.name = message.name\n // `content: null` on a tool turn is meaningful (a tool that returned\n // nothing) and is not the same as the empty string ATIF would round-trip it to.\n if (message.content === null) escrow.content_null = true\n if (message.reasoning_content !== undefined) escrow.reasoning_content = message.reasoning_content\n if (message.is_copied_context === true) escrow.is_copied_context = true\n if (Object.keys(escrow).length > 0) result.extra = { [ESCROW]: escrow }\n return result\n}\n\n/** True when `step` is the agent turn that declared `callId` — the rule-2 test. */\nfunction declaresCall(step: HarborStep, callId: string | undefined): boolean {\n if (callId === undefined) return false\n return step.tool_calls?.some((call) => call.tool_call_id === callId) === true\n}\n\n/**\n * Attaches the four RL fields lifted from ATIF onto the agent step the span\n * describes. They are ALSO escrowed with the whole span under `extra.tangle`,\n * on purpose: the escrow is how our own round-trip stays exact, and these\n * native fields are how a foreign consumer — which never reads our escrow —\n * gets the logprobs and token ids at all. A field carried only in the escrow is\n * not an interchange field.\n */\nfunction applySpanMetrics(step: HarborStep, span: RolloutStep | undefined): void {\n if (span === undefined) return\n if (span.llm_call_count !== undefined) step.llm_call_count = span.llm_call_count\n const metrics: HarborMetrics = {}\n if (span.prompt_token_ids !== undefined) metrics.prompt_token_ids = span.prompt_token_ids\n if (span.completion_token_ids !== undefined) {\n metrics.completion_token_ids = span.completion_token_ids\n }\n if (span.logprobs !== undefined) metrics.logprobs = span.logprobs\n if (Object.keys(metrics).length > 0) step.metrics = metrics\n}\n\n/**\n * Coalescing fold, not a 1:1 map: ATIF has no `tool` source, so a tool result\n * becomes an `observation.results[]` entry on the agent step THAT DECLARED ITS\n * `tool_call_id`.\n *\n * Linking by id, not by adjacency. Adjacency emitted invalid documents in three\n * shapes the RFC forbids — an assistant turn with no `tool_calls` swallowing the\n * results that followed it, a result whose id matched none of the preceding\n * step's calls, and an unanswered result riding a `system` step that carried a\n * `source_call_id` it could never declare. Attaching only to the step that owns\n * the id also preserves message order exactly: a result either joins the step\n * immediately before it or becomes its own carrier at its own position.\n *\n * `line.steps` span projections are matched to agent steps in order (k-th llm\n * span → k-th agent step) purely to fill ATIF's native per-step `metrics`;\n * extra spans on either side are simply not matched, never invented.\n */\nfunction messagesToSteps(line: RolloutLine): HarborStep[] {\n const steps: HarborStep[] = []\n const llmSpans = (line.steps ?? []).filter((span) => span.kind === 'llm')\n let nextSpan = 0\n for (const message of line.messages) {\n if (message.role === 'tool') {\n const previous = steps[steps.length - 1]\n if (previous !== undefined && declaresCall(previous, message.tool_call_id)) {\n if (previous.observation === undefined) previous.observation = { results: [] }\n previous.observation.results.push(toObservationResult(message, true))\n continue\n }\n // A tool result answering no assistant turn in this document (truncated or\n // reconstructed transcript). It still has to survive, so it rides a marked\n // carrier step whose observation states no call id.\n const carrier: HarborStep = {\n step_id: steps.length + 1,\n source: 'system',\n message: '',\n observation: { results: [toObservationResult(message, false)] },\n extra: { [ESCROW]: { synthetic: TOOL_RESULTS_ONLY } },\n }\n if (message.is_copied_context === true) carrier.is_copied_context = true\n steps.push(carrier)\n continue\n }\n const step: HarborStep = {\n step_id: steps.length + 1,\n source: message.role === 'assistant' ? 'agent' : message.role,\n message: message.content ?? '',\n }\n const escrow: Record<string, unknown> = {}\n if (message.content === null) escrow.content_null = true\n if (message.name !== undefined) escrow.name = message.name\n if (message.role === 'assistant') {\n if (line.policy.model !== null) step.model_name = line.policy.model\n if (message.reasoning_content !== undefined) {\n step.reasoning_content = message.reasoning_content\n }\n if (message.tool_calls !== undefined && message.tool_calls.length > 0) {\n step.tool_calls = message.tool_calls.map(toHarborToolCall)\n }\n applySpanMetrics(step, llmSpans[nextSpan])\n nextSpan += 1\n } else if (message.reasoning_content !== undefined) {\n // ATIF confines `reasoning_content` to agent steps; ours is not confined.\n escrow.reasoning_content = message.reasoning_content\n }\n // RFC 0001 rule 7: a copied-context turn was not authored by this agent, and\n // an SFT pipeline MUST exclude it. Native ATIF field, both directions.\n if (message.is_copied_context === true) step.is_copied_context = true\n if (Object.keys(escrow).length > 0) step.extra = { [ESCROW]: escrow }\n steps.push(step)\n }\n return steps\n}\n\nfunction finalMetricsOf(line: RolloutLine, stepCount: number): HarborFinalMetrics {\n const metrics: HarborFinalMetrics = {}\n if (line.cost.tokens_in !== null) metrics.total_prompt_tokens = line.cost.tokens_in\n if (line.cost.tokens_out !== null) metrics.total_completion_tokens = line.cost.tokens_out\n if (line.cost.cache_read !== null) metrics.total_cached_tokens = line.cost.cache_read\n // Omitted, never 0, when cost was not captured — a fake 0 is a lie about spend.\n if (line.cost.usd !== null) metrics.total_cost_usd = line.cost.usd\n metrics.total_steps = stepCount\n // ATIF has no aggregate field for these three; `reasoning_tokens` under\n // `extra` is the key the RFC's own worked example uses.\n const extra: Record<string, unknown> = {}\n if (line.cost.tokens_reasoning !== null) extra.reasoning_tokens = line.cost.tokens_reasoning\n if (line.cost.cache_write !== null) extra.cache_write_tokens = line.cost.cache_write\n if (line.cost.wall_s !== null) extra.wall_s = line.cost.wall_s\n if (line.cost.llm_call_count !== undefined && line.cost.llm_call_count !== null) {\n extra.llm_call_count = line.cost.llm_call_count\n }\n if (Object.keys(extra).length > 0) metrics.extra = extra\n return metrics\n}\n\nfunction notesOf(line: RolloutLine): string | undefined {\n const parts: string[] = []\n if (line.provenance.gap !== undefined) parts.push(line.provenance.gap)\n if (line.outcome.realness_gated === true) {\n // ATIF has no gate field. A third-party consumer that ignores `extra`\n // would otherwise see a gamed trajectory with nothing marking it, so the\n // flag is stated in prose as well. This export carries no reward at all,\n // so it is not a training-data door — but it is an audit record.\n parts.push('realness-gated: this run faked its success signal (anti-Goodhart gate fired)')\n }\n return parts.length > 0 ? parts.join(' | ') : undefined\n}\n\nfunction toTrajectoryNode(line: RolloutLine): HarborTrajectory {\n const steps = messagesToSteps(line)\n const trajectory: HarborTrajectory = {\n schema_version: ATIF_SCHEMA_VERSION,\n // RUN-scoped, per the spec — so it is `run_id`, the coordinate every\n // invocation of one run shares. `rollout_id` identifies a single\n // invocation: using it gave two roots of the same run different session\n // ids, and foreign tooling that groups by session_id would split the run.\n session_id: line.run_id,\n trajectory_id: line.rollout_id,\n agent: {\n // ATIF requires both; ours are nullable, so a null is substituted here\n // and restored on import from the escrowed policy — never guessed back.\n name: line.policy.harness ?? 'unknown',\n version: line.policy.harness_version ?? '0.0.0',\n ...(line.policy.model !== null ? { model_name: line.policy.model } : {}),\n ...(line.tool_defs.length > 0 ? { tool_definitions: line.tool_defs } : {}),\n },\n steps,\n final_metrics: finalMetricsOf(line, steps.length),\n extra: {\n [ESCROW]: {\n schema: line.schema,\n rollout_id: line.rollout_id,\n parent_rollout_id: line.parent_rollout_id,\n run_id: line.run_id,\n ...(line.experiment_id !== undefined ? { experiment_id: line.experiment_id } : {}),\n ...(line.candidate_id !== undefined ? { candidate_id: line.candidate_id } : {}),\n generation: line.generation,\n candidate_index: line.candidate_index,\n role: line.role,\n task: line.task,\n policy: line.policy,\n // Span projections overlap the same turns as `steps[]`; folding them\n // into ATIF steps would double-count the run, so they stay escrowed.\n ...(line.steps !== undefined ? { spans: line.steps } : {}),\n outcome: {\n // reward / reward_source / verdict are deliberately absent — see the\n // module header. Only the non-scalar outcome fields travel.\n metrics: line.outcome.metrics,\n is_completed: line.outcome.is_completed,\n is_truncated: line.outcome.is_truncated,\n error: line.outcome.error,\n ...(line.outcome.realness_gated !== undefined\n ? { realness_gated: line.outcome.realness_gated }\n : {}),\n },\n artifacts: line.artifacts,\n provenance: line.provenance,\n },\n },\n }\n const notes = notesOf(line)\n if (notes !== undefined) trajectory.notes = notes\n return trajectory\n}\n\ninterface Forest {\n roots: RolloutLine[]\n childrenOf: Map<string, RolloutLine[]>\n}\n\nfunction buildForest(lines: RolloutLine[]): Forest {\n const byId = new Map<string, RolloutLine>()\n for (const line of lines) {\n if (byId.has(line.rollout_id)) {\n throw new Error(`duplicate rollout_id in input: ${line.rollout_id}`)\n }\n byId.set(line.rollout_id, line)\n }\n const roots: RolloutLine[] = []\n const childrenOf = new Map<string, RolloutLine[]>()\n for (const line of lines) {\n const parent = line.parent_rollout_id\n // A parent outside this set is a root OF WHAT WE HAVE: the edge is kept in\n // escrow so a later import restores the dangling pointer instead of nulling it.\n if (parent === null || !byId.has(parent)) {\n roots.push(line)\n continue\n }\n const siblings = childrenOf.get(parent)\n if (siblings === undefined) childrenOf.set(parent, [line])\n else siblings.push(line)\n }\n // Every line has a parent inside the set: the edges form a cycle with no\n // root. Returning zero documents would drop the whole episode silently.\n if (lines.length > 0 && roots.length === 0) {\n throw new Error(\n `parent_rollout_id cycle: no root among ${lines.length} lines (${lines.map((l) => l.rollout_id).join(', ')})`,\n )\n }\n return { roots, childrenOf }\n}\n\nfunction assemble(line: RolloutLine, forest: Forest, onPath: Set<string>): HarborTrajectory {\n if (onPath.has(line.rollout_id)) {\n throw new Error(`parent_rollout_id cycle through rollout_id ${line.rollout_id}`)\n }\n onPath.add(line.rollout_id)\n const node = toTrajectoryNode(line)\n const children = forest.childrenOf.get(line.rollout_id)\n if (children !== undefined && children.length > 0) {\n node.subagent_trajectories = children.map((child) => assemble(child, forest, onPath))\n }\n onPath.delete(line.rollout_id)\n return node\n}\n\n/**\n * Assemble one episode's flat lines into a single ATIF trajectory tree,\n * linked by `parent_rollout_id`.\n *\n * Reward, verdict and split are NOT emitted (ATIF models none of them); the\n * split and the rest of the task coordinates survive only in `extra.tangle`.\n *\n * We deliberately do NOT synthesize an `observation.subagent_trajectory_ref`\n * pointing at each child: our ledger records WHICH invocation spawned a\n * worker, not which STEP did, and attaching the ref to a guessed step would\n * fabricate a causal claim. Children are embedded in `subagent_trajectories`\n * (each with the `trajectory_id` the spec requires) and the edge is stated in\n * the child's escrowed `parent_rollout_id`.\n *\n * Throws when the lines are not one tree — use `toHarborTrajectories` for a forest.\n */\nexport function toHarborTrajectory(lines: RolloutLine[]): HarborTrajectory {\n const trees = toHarborTrajectories(lines)\n if (trees.length === 0) throw new Error('toHarborTrajectory: no lines')\n if (trees.length > 1) {\n const ids = trees.map((t) => t.trajectory_id ?? '?').join(', ')\n throw new Error(\n `toHarborTrajectory: ${trees.length} roots (${ids}) — ATIF is one tree per document; use toHarborTrajectories`,\n )\n }\n return trees[0]!\n}\n\n/** Every independent tree in the input, one ATIF document each. */\nexport function toHarborTrajectories(lines: RolloutLine[]): HarborTrajectory[] {\n const forest = buildForest(lines)\n return forest.roots.map((root) => assemble(root, forest, new Set()))\n}\n\n// ---------------------------------------------------------------------------\n// Import: ATIF trajectory tree → RolloutLine[]\n// ---------------------------------------------------------------------------\n\nfunction contentToString(message: string | HarborContentPart[]): string {\n if (typeof message === 'string') return message\n return message\n .map((part) =>\n part.type === 'image'\n ? // Our chat content is text-only. Describing the image is honest about\n // what the source held; dropping it silently would not be.\n `[image ${part.source?.media_type ?? 'unknown'} ${part.source?.path ?? ''}]`.trim()\n : (part.text ?? ''),\n )\n .join('\\n')\n}\n\nfunction fromHarborToolCall(call: HarborToolCall): ChatToolCall {\n const raw = asString(escrowOf(call.extra)?.arguments_raw)\n return {\n id: call.tool_call_id,\n type: 'function',\n function: { name: call.function_name, arguments: raw ?? JSON.stringify(call.arguments ?? {}) },\n }\n}\n\nfunction fromObservationResult(\n result: HarborObservationResult,\n callId: string | undefined,\n): ChatMessage {\n const escrow = escrowOf(result.extra)\n return canonicalChatMessage({\n role: 'tool',\n content:\n escrow?.content_null === true\n ? null\n : result.content === undefined\n ? ''\n : contentToString(result.content),\n reasoning_content: asString(escrow?.reasoning_content),\n tool_call_id: callId,\n name: asString(escrow?.name),\n is_copied_context: escrow?.is_copied_context === true,\n })\n}\n\nfunction stepsToMessages(steps: HarborStep[]): ChatMessage[] {\n const messages: ChatMessage[] = []\n for (const step of steps) {\n const escrow = escrowOf(step.extra)\n const carrierOnly = escrow?.synthetic === TOOL_RESULTS_ONLY\n if (!carrierOnly) {\n messages.push(\n canonicalChatMessage({\n role: step.source === 'agent' ? 'assistant' : step.source,\n content: escrow?.content_null === true ? null : contentToString(step.message),\n reasoning_content: step.reasoning_content ?? asString(escrow?.reasoning_content),\n tool_calls:\n step.tool_calls !== undefined && step.tool_calls.length > 0\n ? step.tool_calls.map(fromHarborToolCall)\n : undefined,\n name: asString(escrow?.name),\n is_copied_context: step.is_copied_context === true,\n }),\n )\n }\n for (const result of step.observation?.results ?? []) {\n const resultEscrow = escrowOf(result.extra)\n const callId = result.source_call_id ?? asString(resultEscrow?.source_call_id)\n if (carrierOnly) {\n // Our own carrier: every result on it was a tool turn, and its call id\n // (if the transcript had one) is in escrow, not on the wire.\n messages.push(fromObservationResult(result, callId))\n continue\n }\n if (typeof callId === 'string') {\n messages.push(fromObservationResult(result, callId))\n continue\n }\n // ATIF allows a result from a non-tool-calling action. Our chat schema\n // requires `tool_call_id` on a tool turn, so inventing one would forge a\n // link; the text is preserved as a system observation instead.\n if (result.content !== undefined) {\n messages.push(\n canonicalChatMessage({ role: 'system', content: contentToString(result.content) }),\n )\n }\n }\n }\n return messages\n}\n\nfunction taskFrom(escrow: Record<string, unknown> | undefined, fallbackId: string): RolloutTask {\n const task = escrowSection(escrow, 'task')\n return {\n suite: asString(task?.suite) ?? 'harbor-atif-import',\n instance_id: asString(task?.instance_id) ?? fallbackId,\n // ALWAYS holdout — the escrowed claim is read for nothing here.\n //\n // `extra.tangle.task.split` is a namespaced key, not an authenticated one:\n // a hand-written or third-party document can set `split: 'search'` as\n // easily as our own exporter can, and honouring it made \"this file says so\"\n // sufficient to walk into a training export. Trainability is a decision\n // about a file, so it is made by an operator through\n // `relabelImportedSplit`, never by the file about itself. The claim is not\n // destroyed — it stays readable in the source document.\n split: 'holdout',\n seed: asNumberOrNull(task?.seed),\n rep: asIntegerOrUndefined(task?.rep) ?? 0,\n }\n}\n\nfunction policyFrom(\n escrow: Record<string, unknown> | undefined,\n agent: HarborAgent,\n): RolloutPolicy {\n const escrowed = escrowSection(escrow, 'policy')\n if (escrowed !== undefined) {\n // Our own export: restore verbatim, including the nulls ATIF forced us to\n // substitute placeholders for in `agent.name` / `agent.version`.\n return {\n harness: asString(escrowed.harness) ?? null,\n harness_version: asString(escrowed.harness_version) ?? null,\n model: asString(escrowed.model) ?? null,\n provider: asString(escrowed.provider) ?? null,\n profile_commit: asString(escrowed.profile_commit) ?? null,\n ...(escrowed.prompt_hash !== undefined\n ? { prompt_hash: asString(escrowed.prompt_hash) ?? null }\n : {}),\n ...(escrowed.config_hash !== undefined\n ? { config_hash: asString(escrowed.config_hash) ?? null }\n : {}),\n ...(escrowed.agent_profile_cell_id !== undefined\n ? { agent_profile_cell_id: asString(escrowed.agent_profile_cell_id) ?? null }\n : {}),\n sampling: isRecord(escrowed.sampling) ? escrowed.sampling : null,\n }\n }\n return {\n harness: agent.name,\n harness_version: agent.version,\n model: agent.model_name ?? null,\n provider: null,\n profile_commit: null,\n sampling: null,\n }\n}\n\nfunction artifactsFrom(escrow: Record<string, unknown> | undefined): RolloutArtifacts {\n const artifacts = escrowSection(escrow, 'artifacts')\n return {\n patch_path: asString(artifacts?.patch_path) ?? null,\n run_dir: asString(artifacts?.run_dir) ?? null,\n transcript_ref: asString(artifacts?.transcript_ref) ?? null,\n }\n}\n\nfunction costFrom(final: HarborFinalMetrics | undefined): RolloutCostBlock {\n const rawExtra = final?.extra\n const extra = isRecord(rawExtra) ? rawExtra : undefined\n const calls = asIntegerOrUndefined(extra?.llm_call_count)\n return {\n usd: asNumberOrNull(final?.total_cost_usd),\n tokens_in: asNumberOrNull(final?.total_prompt_tokens),\n tokens_out: asNumberOrNull(final?.total_completion_tokens),\n tokens_reasoning: asNumberOrNull(extra?.reasoning_tokens),\n cache_read: asNumberOrNull(final?.total_cached_tokens),\n cache_write: asNumberOrNull(extra?.cache_write_tokens),\n wall_s: asNumberOrNull(extra?.wall_s),\n ...(calls !== undefined ? { llm_call_count: calls } : {}),\n }\n}\n\n/**\n * Recovers span projections from ATIF's NATIVE per-step channel, for documents\n * with no `extra.tangle.spans` escrow — i.e. everything a foreign producer\n * writes. Without this the logprobs and token ids a Harbor-native trainer\n * records would be read, validated, and then dropped on the floor.\n *\n * Only steps that actually carry one of the four fields produce a span: an\n * agent step with no metrics means \"not captured\", and inventing an empty span\n * for it would claim the run had a shape we did not observe.\n */\nfunction spansFromSteps(steps: HarborStep[]): RolloutStep[] {\n const spans: RolloutStep[] = []\n for (const step of steps) {\n if (step.source !== 'agent') continue\n const calls = asIntegerOrUndefined(step.llm_call_count)\n const promptIds = asIntegerArray(step.metrics?.prompt_token_ids)\n const completionIds = asIntegerArray(step.metrics?.completion_token_ids)\n const logprobs = asNumberArray(step.metrics?.logprobs)\n if (\n calls === undefined &&\n promptIds === undefined &&\n completionIds === undefined &&\n logprobs === undefined\n ) {\n continue\n }\n spans.push({\n kind: 'llm',\n name: step.model_name ?? 'chat',\n ...(calls !== undefined ? { llm_call_count: calls } : {}),\n ...(promptIds !== undefined ? { prompt_token_ids: promptIds } : {}),\n ...(completionIds !== undefined ? { completion_token_ids: completionIds } : {}),\n ...(logprobs !== undefined ? { logprobs } : {}),\n })\n }\n return spans\n}\n\n/**\n * Composes `provenance.gap` as an ordered SET of reasons.\n *\n * Appending made the note accrete on every pass (\"…no verdict | …no verdict\"),\n * which both grows without bound and breaks byte-level idempotency for a ledger\n * hashed on its serialized lines.\n */\nfunction composeGap(escrowedGap: string | undefined, added: readonly string[]): string {\n const parts: string[] = []\n const seen = new Set<string>()\n for (const raw of [...(escrowedGap?.split(' | ') ?? []), ...added]) {\n const reason = raw.trim()\n if (reason.length === 0 || seen.has(reason)) continue\n seen.add(reason)\n parts.push(reason)\n }\n return parts.join(' | ')\n}\n\nexport interface FromHarborOptions {\n /** Injected clock for deterministic output when the source carries no capture time. */\n now?: () => Date\n}\n\nfunction nodeToLine(\n trajectory: HarborTrajectory,\n parentId: string | null,\n capturedAt: string,\n): RolloutLine {\n const escrow = escrowOf(trajectory.extra)\n const rolloutId =\n asString(escrow?.rollout_id) ?? trajectory.trajectory_id ?? trajectory.session_id\n if (rolloutId === undefined || rolloutId.length === 0) {\n throw new Error(\n 'fromHarborTrajectory: trajectory has no trajectory_id or session_id — cannot mint a joinable rollout_id without inventing one',\n )\n }\n const outcome = escrowSection(escrow, 'outcome')\n const provenance = escrowSection(escrow, 'provenance')\n const capture = provenance?.capture\n const escrowedGap = asString(provenance?.gap)\n const role = escrow?.role\n const escrowedSpans = escrow?.spans\n // The escrow wins when it exists (our own export: exact, including an empty\n // array, which claims \"captured, none\" rather than \"not captured\"), and the\n // native per-step channel is the fallback (a foreign export: still signal).\n const nativeSpans = spansFromSteps(trajectory.steps)\n const spans: RolloutStep[] | undefined = Array.isArray(escrowedSpans)\n ? (escrowedSpans as RolloutStep[])\n : nativeSpans.length > 0\n ? nativeSpans\n : undefined\n const messages = stepsToMessages(trajectory.steps)\n const line: RolloutLine = {\n schema: ROLLOUT_SCHEMA,\n rollout_id: rolloutId,\n // The tree edge wins for embedded children; for a root, the escrowed\n // pointer may reference a line outside this document and is preserved.\n parent_rollout_id: parentId ?? asString(escrow?.parent_rollout_id) ?? null,\n run_id: asString(escrow?.run_id) ?? trajectory.session_id ?? rolloutId,\n // Required keys on the wire (0.127.0): a foreign document that never\n // stated them imports as explicit `null`, not as an absent field.\n experiment_id: asString(escrow?.experiment_id) ?? null,\n candidate_id: asString(escrow?.candidate_id) ?? null,\n generation: asIntegerOrUndefined(escrow?.generation) ?? null,\n candidate_index: asIntegerOrUndefined(escrow?.candidate_index) ?? null,\n role: ROLLOUT_ROLES.includes(role as RolloutRole) ? (role as RolloutRole) : 'agent',\n task: taskFrom(escrow, rolloutId),\n policy: policyFrom(escrow, trajectory.agent),\n messages,\n tool_defs: trajectory.agent.tool_definitions ?? [],\n ...(spans !== undefined ? { steps: spans } : {}),\n outcome: {\n // ATIF carries no label. Null is the labeled gap; a 0 here would be a\n // fabricated failure and a 1 a fabricated success.\n reward: null,\n reward_source: null,\n verdict: null,\n metrics: isRecord(outcome?.metrics) ? outcome.metrics : {},\n is_completed: typeof outcome?.is_completed === 'boolean' ? outcome.is_completed : true,\n is_truncated:\n typeof outcome?.is_truncated === 'boolean'\n ? outcome.is_truncated\n : trajectory.continued_trajectory_ref !== undefined,\n error: asString(outcome?.error) ?? null,\n // The anti-Goodhart flag is restored when the source document stated\n // it; the wire schema requires the field, so a document that never did\n // imports as `false`. That is safe here because the reward is already\n // forced to `null` (not trainable) and `realness_screened` stays\n // absent = unknown rather than claiming a screen ran.\n realness_gated: outcome?.realness_gated === true,\n },\n cost: costFrom(trajectory.final_metrics),\n artifacts: artifactsFrom(escrow),\n provenance: {\n captured_at: asString(provenance?.captured_at) ?? capturedAt,\n capture: ROLLOUT_CAPTURES.includes(capture as RolloutCapture)\n ? (capture as RolloutCapture)\n : 'backfill',\n gap: composeGap(escrowedGap, [HARBOR_IMPORT_GAP]),\n // Restored for the same reason `realness_gated` is, and with the opposite\n // risk profile from the reward: this is the gated run's own measurement\n // bag, moved off `outcome` by `gateGamedOutcome` so no exporter reads it\n // as training input. Dropping it here would silently destroy the audit\n // trail that says WHY the run was flagged and what it claimed, on the one\n // population an auditor most wants to inspect. It cannot be fail-open —\n // nothing projects `provenance` into a training row.\n ...(isRecord(provenance?.gated_evidence)\n ? { gated_evidence: provenance.gated_evidence as GatedEvidence }\n : {}),\n },\n }\n assertRolloutLine(line, `rollout line imported from ATIF trajectory ${rolloutId}`)\n return line\n}\n\n/**\n * Flatten an ATIF trajectory tree back into `tangle.rollout.v1` lines, parent\n * first, each child carrying `parent_rollout_id`.\n *\n * Every line comes back UNLABELED: `reward`, `reward_source` and `verdict` are\n * null and `provenance.gap` says why. ATIF models no verdict, so scoring an\n * imported trajectory is a judge's job, not this function's. Every line lands\n * on `holdout` whatever the document claims — see `relabelImportedSplit`.\n */\nexport function fromHarborTrajectory(\n trajectory: HarborTrajectory,\n options: FromHarborOptions = {},\n): RolloutLine[] {\n const capturedAt = (options.now?.() ?? new Date()).toISOString()\n const lines: RolloutLine[] = []\n const walk = (node: HarborTrajectory, parentId: string | null, onPath: Set<string>): void => {\n const line = nodeToLine(node, parentId, capturedAt)\n if (onPath.has(line.rollout_id)) {\n throw new Error(`subagent_trajectories cycle through trajectory_id ${line.rollout_id}`)\n }\n onPath.add(line.rollout_id)\n lines.push(line)\n for (const child of node.subagent_trajectories ?? []) {\n walk(child, line.rollout_id, onPath)\n }\n onPath.delete(line.rollout_id)\n }\n walk(trajectory, null, new Set())\n return lines\n}\n\n/**\n * THE explicit door out of `holdout` for imported lines.\n *\n * Import forces `holdout` because a document's own claim about its split is not\n * evidence — anyone can write `extra.tangle.task.split`. Promoting a file to a\n * trainable split is an operator's decision about provenance they verified, so\n * it is a separate, greppable call: `grep relabelImportedSplit` enumerates\n * every place foreign data was declared trainable, which is exactly the audit\n * the trusted-escrow version made impossible.\n *\n * Returns plain `RolloutLine`s. They still have to pass `assertMinted` (and its\n * anti-Goodhart check) to reach an exporter — re-labeling a split is not\n * minting a reward.\n */\nexport function relabelImportedSplit(\n lines: readonly RolloutLine[],\n split: RolloutSplit,\n): RolloutLine[] {\n if (!ROLLOUT_SPLITS.includes(split)) {\n throw new Error(`relabelImportedSplit: unknown split ${String(split)}`)\n }\n return lines.map((line) => ({ ...line, task: { ...line.task, split } }))\n}\n"],"mappings":"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"}
|