@tangle-network/agent-eval 0.100.2 → 0.101.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/dist/adapters/http.d.ts +1 -1
  3. package/dist/adapters/langchain.d.ts +1 -1
  4. package/dist/adapters/otel.d.ts +1 -1
  5. package/dist/campaign/index.d.ts +58 -8
  6. package/dist/campaign/index.js +207 -34
  7. package/dist/campaign/index.js.map +1 -1
  8. package/dist/chunk-63MBSQTX.js +350 -0
  9. package/dist/chunk-63MBSQTX.js.map +1 -0
  10. package/dist/{chunk-G7IB3GJ5.js → chunk-CHIFZIQD.js} +3 -3
  11. package/dist/{chunk-VWQ6PO5O.js → chunk-GUII3E73.js} +54 -1
  12. package/dist/{chunk-VWQ6PO5O.js.map → chunk-GUII3E73.js.map} +1 -1
  13. package/dist/{chunk-2KTBHICD.js → chunk-NK77GPUH.js} +3 -3
  14. package/dist/chunk-NK77GPUH.js.map +1 -0
  15. package/dist/{chunk-QZYXA7ZO.js → chunk-X5OUZB4T.js} +2 -2
  16. package/dist/{chunk-HRGTA6U5.js → chunk-XIOQHCHU.js} +256 -32
  17. package/dist/chunk-XIOQHCHU.js.map +1 -0
  18. package/dist/contract/index.d.ts +6 -6
  19. package/dist/contract/index.js +7 -7
  20. package/dist/{gepa-BRgNnmGZ.d.ts → gepa-CEy1AIWp.d.ts} +36 -2
  21. package/dist/hosted/index.d.ts +1 -1
  22. package/dist/index.d.ts +57 -7
  23. package/dist/index.js +33 -132
  24. package/dist/index.js.map +1 -1
  25. package/dist/multishot/index.d.ts +1 -1
  26. package/dist/openapi.json +1 -1
  27. package/dist/{pre-registration-DB8oDqZJ.d.ts → pre-registration-BjGZf9YA.d.ts} +1 -1
  28. package/dist/product-benchmark/index.d.ts +144 -0
  29. package/dist/product-benchmark/index.js +23 -0
  30. package/dist/{provenance-B0SZw1z2.d.ts → provenance-DdfmVfqR.d.ts} +2 -2
  31. package/dist/rl.d.ts +1 -1
  32. package/dist/{run-campaign-OWCFOEQG.js → run-campaign-HG4WTSDH.js} +4 -2
  33. package/dist/run-campaign-HG4WTSDH.js.map +1 -0
  34. package/dist/{types-Cv1bo4_a.d.ts → types-fWqEJm7h.d.ts} +3 -0
  35. package/docs/concepts.md +1 -0
  36. package/docs/eval-fixtures.md +115 -0
  37. package/docs/feature-guide.md +4 -0
  38. package/package.json +7 -2
  39. package/dist/chunk-2KTBHICD.js.map +0 -1
  40. package/dist/chunk-HRGTA6U5.js.map +0 -1
  41. /package/dist/{chunk-G7IB3GJ5.js.map → chunk-CHIFZIQD.js.map} +0 -0
  42. /package/dist/{chunk-QZYXA7ZO.js.map → chunk-X5OUZB4T.js.map} +0 -0
  43. /package/dist/{run-campaign-OWCFOEQG.js.map → product-benchmark/index.js.map} +0 -0
package/CHANGELOG.md CHANGED
@@ -4,6 +4,25 @@ All notable changes to `@tangle-network/agent-eval` and its sibling `agent-eval-
4
4
 
5
5
  ---
6
6
 
7
+ ## [0.100.3] — 2026-07-01 — product benchmark contract + eval fixture UX
8
+
9
+ ### Added
10
+
11
+ - Published the `@tangle-network/agent-eval/product-benchmark` subpath so product agents can share one strict product-benchmark manifest, record, artifact, and integrity validator instead of copying Agent Lab or product-local schema code.
12
+ - **Vercel-style eval fixture loading in `/campaign`.** `discoverEvalFixtures`, `loadEvalFixture`, `loadEvalFixtureScenarios`, and `planEvalFixtureRun` let agents use the simple `evals/<name>/PROMPT.md + EVAL.ts + package.json` shape while still executing through the existing `runCampaign` primitive.
13
+ - **Dry-run planning for campaigns.** `planCampaignRun` reports `totalCells`, `cellsCached`, `cellsToRun`, per-cell cache paths, and miss reasons before any agent work starts. This is the cheap proof before spending tokens.
14
+ - **`dispatchRef` on `runCampaign`.** Callers can include the model/tool/prompt/runtime identity in the manifest when the same dispatch function name can run different behavior.
15
+
16
+ ### Fixed
17
+
18
+ - **Campaign resumability now validates `manifestHash` before reusing a cached cell.** Reusing the same `runDir` after changing scenario payloads, judges, seed/reps, or `dispatchRef` no longer serves stale cells that only match by `cellId`.
19
+
20
+ ### Docs
21
+
22
+ - Added `docs/eval-fixtures.md` and `examples/eval-fixtures-quickstart/` so agents can add fixture-backed evals without rediscovering the campaign plumbing.
23
+
24
+ ---
25
+
7
26
  ## [0.96.4] — 2026-06-22 — multishot fatal tool errors
8
27
 
9
28
  ### Added
@@ -1,4 +1,4 @@
1
- import { S as Scenario, D as DispatchFn, b as DispatchContext } from '../types-Cv1bo4_a.js';
1
+ import { S as Scenario, D as DispatchFn, b as DispatchContext } from '../types-fWqEJm7h.js';
2
2
  import '../run-record-DEwidcqn.js';
3
3
  import '@tangle-network/agent-interface';
4
4
  import '../errors-CzMUYo7b.js';
@@ -1,4 +1,4 @@
1
- import { S as Scenario, J as JudgeScore, D as DispatchFn, a as JudgeConfig } from '../types-Cv1bo4_a.js';
1
+ import { S as Scenario, J as JudgeScore, D as DispatchFn, a as JudgeConfig } from '../types-fWqEJm7h.js';
2
2
  import '../run-record-DEwidcqn.js';
3
3
  import '@tangle-network/agent-interface';
4
4
  import '../errors-CzMUYo7b.js';
@@ -1,5 +1,5 @@
1
1
  import { TraceSpanEvent, HostedClient } from '../hosted/index.js';
2
- import '../types-Cv1bo4_a.js';
2
+ import '../types-fWqEJm7h.js';
3
3
  import '../run-record-DEwidcqn.js';
4
4
  import '@tangle-network/agent-interface';
5
5
  import '../errors-CzMUYo7b.js';
@@ -1,11 +1,11 @@
1
- import { S as SignedManifest, B as BackendIntegrityReport, C as CompletionRequirement, R as RuntimeEventLike, a as CompletionVerdict, P as ProducedState, b as CorrectnessChecker } from '../pre-registration-DB8oDqZJ.js';
2
- export { L as LlmJudgeDimension, c as LlmJudgeOptions, l as llmJudge } from '../pre-registration-DB8oDqZJ.js';
1
+ import { S as SignedManifest, B as BackendIntegrityReport, C as CompletionRequirement, R as RuntimeEventLike, a as CompletionVerdict, P as ProducedState, b as CorrectnessChecker } from '../pre-registration-BjGZf9YA.js';
2
+ export { L as LlmJudgeDimension, c as LlmJudgeOptions, l as llmJudge } from '../pre-registration-BjGZf9YA.js';
3
3
  import { A as AnalyzeTracesOptions, a as AnalyzeTracesInput, b as AnalyzeTracesResult } from '../analyst-C8HHvfJp.js';
4
- import { S as Scenario, M as MutableSurface, b as DispatchContext, a as JudgeConfig, e as GenerationRecord, g as Gate, J as JudgeScore, L as LabeledScenarioStore, s as LabeledScenarioWrite, t as LabeledScenarioSampleArgs, u as LabeledScenarioRecord, v as LabelTrust, f as SurfaceProposer, w as ProposedCandidate, x as ProposeContext, y as LabeledScenarioSource, C as CampaignResult, o as CodeSurface } from '../types-Cv1bo4_a.js';
5
- export { k as CampaignAggregates, l as CampaignArtifactWriter, m as CampaignCellResult, n as CampaignCostMeter, z as CampaignTokenUsage, d as CampaignTraceWriter, D as DispatchFn, h as GateContext, j as GateDecision, G as GateResult, p as GenerationCandidate, A as JudgeAggregate, c as JudgeDimension, i as Mutator, O as OptimizationProposer, q as OptimizerConfig, P as ParetoParent, R as RedactionStatus, B as ScenarioAggregate, r as SessionScript, T as TraceSpan, E as isProposedCandidate, F as labelTrustRank } from '../types-Cv1bo4_a.js';
6
- import { R as RunCampaignOptions, c as RunImprovementLoopOptions, C as CampaignStorage } from '../gepa-BRgNnmGZ.js';
7
- export { e as GepaProposerConstraints, G as GepaProposerOptions, O as OpenAutoPrOptions, h as OpenAutoPrResult, b as RunImprovementLoopResult, a as RunOptimizationOptions, j as RunOptimizationResult, k as countSentenceEdits, l as defaultRenderDiff, m as extractH2Sections, f as fsCampaignStorage, g as gepaProposer, i as inMemoryCampaignStorage, o as openAutoPr, r as runCampaign, d as runImprovementLoop, n as runOptimization, s as surfaceHash } from '../gepa-BRgNnmGZ.js';
8
- export { A as AxisEvidence, a as AxisVerdict, B as BuildEvidenceVectorOptions, k as BuildLoopProvenanceArgs, D as DefaultProductionGateOptions, l as EmitLoopProvenanceArgs, m as EmitLoopProvenanceResult, E as EvidenceVector, b as EvolutionaryProposerOptions, H as HeldOutGateOptions, n as LoopProvenanceBackend, o as LoopProvenanceCandidate, L as LoopProvenanceRecord, O as ObjectiveSource, P as ParetoSignificanceGateOptions, c as PromotionObjective, d as PromotionPolicy, R as RunEvalOptions, e as buildEvidenceVector, q as buildLoopProvenanceRecord, f as composeGate, g as defaultProductionGate, s as emitLoopProvenance, h as evolutionaryProposer, i as heldOutGate, t as loopProvenanceSpans, p as paretoPolicy, j as paretoSignificanceGate, u as provenanceRecordPath, v as provenanceSpansPath, r as runEval, w as surfaceContentHash } from '../provenance-B0SZw1z2.js';
4
+ import { S as Scenario, M as MutableSurface, b as DispatchContext, a as JudgeConfig, e as GenerationRecord, g as Gate, J as JudgeScore, L as LabeledScenarioStore, s as LabeledScenarioWrite, t as LabeledScenarioSampleArgs, u as LabeledScenarioRecord, v as LabelTrust, f as SurfaceProposer, w as ProposedCandidate, x as ProposeContext, y as LabeledScenarioSource, C as CampaignResult, o as CodeSurface } from '../types-fWqEJm7h.js';
5
+ export { k as CampaignAggregates, l as CampaignArtifactWriter, m as CampaignCellResult, n as CampaignCostMeter, z as CampaignTokenUsage, d as CampaignTraceWriter, D as DispatchFn, h as GateContext, j as GateDecision, G as GateResult, p as GenerationCandidate, A as JudgeAggregate, c as JudgeDimension, i as Mutator, O as OptimizationProposer, q as OptimizerConfig, P as ParetoParent, R as RedactionStatus, B as ScenarioAggregate, r as SessionScript, T as TraceSpan, E as isProposedCandidate, F as labelTrustRank } from '../types-fWqEJm7h.js';
6
+ import { e as CampaignRunPlan, P as PlanCampaignRunOptions, C as CampaignStorage, R as RunCampaignOptions, c as RunImprovementLoopOptions } from '../gepa-CEy1AIWp.js';
7
+ export { h as CampaignRunPlanCell, j as GepaProposerConstraints, G as GepaProposerOptions, O as OpenAutoPrOptions, k as OpenAutoPrResult, b as RunImprovementLoopResult, a as RunOptimizationOptions, l as RunOptimizationResult, m as countSentenceEdits, n as defaultRenderDiff, o as extractH2Sections, f as fsCampaignStorage, g as gepaProposer, i as inMemoryCampaignStorage, p as openAutoPr, q as planCampaignRun, r as runCampaign, d as runImprovementLoop, s as runOptimization, t as surfaceHash } from '../gepa-CEy1AIWp.js';
8
+ export { A as AxisEvidence, a as AxisVerdict, B as BuildEvidenceVectorOptions, k as BuildLoopProvenanceArgs, D as DefaultProductionGateOptions, l as EmitLoopProvenanceArgs, m as EmitLoopProvenanceResult, E as EvidenceVector, b as EvolutionaryProposerOptions, H as HeldOutGateOptions, n as LoopProvenanceBackend, o as LoopProvenanceCandidate, L as LoopProvenanceRecord, O as ObjectiveSource, P as ParetoSignificanceGateOptions, c as PromotionObjective, d as PromotionPolicy, R as RunEvalOptions, e as buildEvidenceVector, q as buildLoopProvenanceRecord, f as composeGate, g as defaultProductionGate, s as emitLoopProvenance, h as evolutionaryProposer, i as heldOutGate, t as loopProvenanceSpans, p as paretoPolicy, j as paretoSignificanceGate, u as provenanceRecordPath, v as provenanceSpansPath, r as runEval, w as surfaceContentHash } from '../provenance-DdfmVfqR.js';
9
9
  import { E as EProcessState, a as PairedBootstrapResult } from '../statistics-xP-cWc5k.js';
10
10
  import { L as LlmClientOptions } from '../llm-client-Bj7g0rqu.js';
11
11
  import { AgentProfile } from '@tangle-network/agent-interface';
@@ -139,6 +139,56 @@ interface FailureModeRecallJudgeOptions {
139
139
  */
140
140
  declare function failureModeRecallJudge(opts?: FailureModeRecallJudgeOptions): JudgeConfig<AnalystArtifact, AnalystScenario>;
141
141
 
142
+ type EvalFixtureValidationMode = 'vitest' | 'none';
143
+ interface EvalFixtureFile {
144
+ path: string;
145
+ sha256: string;
146
+ bytes: number;
147
+ }
148
+ interface EvalFixture {
149
+ name: string;
150
+ path: string;
151
+ promptPath: string;
152
+ evalPath?: string;
153
+ packageJsonPath?: string;
154
+ prompt: string;
155
+ files: EvalFixtureFile[];
156
+ fingerprint: string;
157
+ }
158
+ interface EvalFixtureScenario extends Scenario {
159
+ kind: 'eval-fixture';
160
+ fixtureName: string;
161
+ fixturePath: string;
162
+ promptPath: string;
163
+ evalPath?: string;
164
+ packageJsonPath?: string;
165
+ prompt: string;
166
+ fingerprint: string;
167
+ }
168
+ interface EvalFixtureLoadOptions {
169
+ /** `vitest` requires EVAL.ts/EVAL.tsx and package.json type=module. `none` only requires PROMPT.md. */
170
+ validation?: EvalFixtureValidationMode;
171
+ /** Extra caller-owned knobs that affect fixture behavior, folded into the fingerprint. */
172
+ fingerprintConfig?: unknown;
173
+ }
174
+ interface LoadEvalFixtureScenariosOptions extends EvalFixtureLoadOptions {
175
+ names?: string[];
176
+ }
177
+ interface PlanEvalFixtureRunOptions<TArtifact = unknown> extends Pick<PlanCampaignRunOptions<EvalFixtureScenario, TArtifact>, 'dispatchRef' | 'judges' | 'seed' | 'reps' | 'resumable' | 'runDir'> {
178
+ evalsDir: string;
179
+ validation?: EvalFixtureValidationMode;
180
+ fingerprintConfig?: unknown;
181
+ names?: string[];
182
+ storage?: CampaignStorage;
183
+ }
184
+ type EvalFixtureRunPlan = CampaignRunPlan & {
185
+ fixtures: Array<Pick<EvalFixtureScenario, 'fixtureName' | 'fixturePath' | 'fingerprint'>>;
186
+ };
187
+ declare function discoverEvalFixtures(evalsDir: string): string[];
188
+ declare function loadEvalFixture(evalsDir: string, name: string, options?: EvalFixtureLoadOptions): EvalFixture;
189
+ declare function loadEvalFixtureScenarios(evalsDir: string, options?: LoadEvalFixtureScenariosOptions): EvalFixtureScenario[];
190
+ declare function planEvalFixtureRun<TArtifact = unknown>(options: PlanEvalFixtureRunOptions<TArtifact>): EvalFixtureRunPlan;
191
+
142
192
  /**
143
193
  * Anytime-valid sequential promotion gate — an e-process (betting
144
194
  * test-martingale, see `eProcess` in `statistics.ts`) over paired
@@ -1475,4 +1525,4 @@ declare function gitWorktreeAdapter(opts: GitWorktreeAdapterOptions): WorktreeAd
1475
1525
  * as a ref under the adapter's worktree dir. */
1476
1526
  declare function resolveWorktreePath(surface: CodeSurface, worktreeDir?: string): string;
1477
1527
 
1478
- export { type AcceptedEdit, type AceProposerOptions, type AnalystArtifact, type AnalystScenario, type ApplySkillPatchResult, type BuildAnalystSurfaceDispatchOptions, type CampaignBreakdown, CampaignResult, CampaignStorage, CodeSurface, type CompareProposersOptions, type DimensionRegression, DispatchContext, type FailureModeRecallJudgeOptions, type FapoAttributionSignals, type FapoEntryConfig, type FapoFailureCluster, type FapoOptimizationLevel, type FapoProposerOptions, type FapoReviewInput, type FapoReviewIssue, type FapoReviewResult, type FapoScopeContract, FsLabeledScenarioStore, type FsLabeledScenarioStoreOptions, Gate, GenerationRecord, type GitWorktreeAdapterOptions, type HaloProposerOptions, type HeldoutSignificance, type HeldoutSignificanceOptions, type JsonPrimitive, type JsonValue, JudgeConfig, JudgeScore, LabelTrust, LabeledScenarioRecord, LabeledScenarioSampleArgs, LabeledScenarioSource, LabeledScenarioStore, LabeledScenarioStoreError, LabeledScenarioWrite, type MemoryCurationProposerOptions, MutableSurface, type OptimizerEntryConfig, type PairedHoldout, type ParameterCandidate, type ParameterChange, type ParameterSweepProposerOptions, type PlaybackContext, type PlaybackDriver, type PlaybackStep, type PolicyEditProposerOptions, type ProfileDispatchFn, ProfileMatrixError, type ProfileSummary, ProposeContext, type ProposePatchesArgs, ProposedCandidate, type ProposerComparison, type ProposerEntry, type ProposerPairwise, type ProposerScore, type RejectedEdit, RunCampaignOptions, RunImprovementLoopOptions, type RunProfileMatrixOptions, type RunProfileMatrixResult, type RunSkillOptOptions, type RunSkillOptResult, Scenario, type ScenarioRollup, type ScoreboardRenderOptions, type ScoreboardRow, type ScoreboardSummary, type SequentialDecideFn, type SequentialDecideOptions, type SequentialDecision, type SequentialObservation, type SequentialPairedGate, type SequentialPairedGateOptions, type SkillOptEpochRecord, type SkillOptEvidence, type SkillOptProposer, type SkillOptProposerOptions, type SkillPatch, type SkillPatchOp, SkillPatchParseError, type SkillPatchRejection, SurfaceProposer, type TraceAnalystProposerOptions, type UserStory, type UserStoryVerdict, type Worktree, type WorktreeAdapter, WorktreeAdapterError, aceProposer, applySkillPatch, buildAnalystSurfaceDispatch, campaignBreakdown, campaignMeanComposite, compareProposers, detectScale, dimensionRegressions, extractFapoAttributionSignals, failureModeRecallJudge, fapoEscalationEntry, fapoProposer, gepaParetoEntry, gepaReflectionEntry, gitWorktreeAdapter, haloProposer, heldoutSignificance, makePlaybackDispatch, memoryCurationProposer, pairHoldout, parameterSweepProposer, parseSkillPatchResponse, patchEditCount, policyEditProposer, renderScoreboardMarkdown, resolveWorktreePath, runProfileMatrix, runSkillOpt, scoreUserStory, scoreboardSummary, sequentialDecide, sequentialPairedGate, skillOptEntry, skillOptProposer, traceAnalystProposer, userStoryScoreboard };
1528
+ export { type AcceptedEdit, type AceProposerOptions, type AnalystArtifact, type AnalystScenario, type ApplySkillPatchResult, type BuildAnalystSurfaceDispatchOptions, type CampaignBreakdown, CampaignResult, CampaignRunPlan, CampaignStorage, CodeSurface, type CompareProposersOptions, type DimensionRegression, DispatchContext, type EvalFixture, type EvalFixtureFile, type EvalFixtureLoadOptions, type EvalFixtureRunPlan, type EvalFixtureScenario, type EvalFixtureValidationMode, type FailureModeRecallJudgeOptions, type FapoAttributionSignals, type FapoEntryConfig, type FapoFailureCluster, type FapoOptimizationLevel, type FapoProposerOptions, type FapoReviewInput, type FapoReviewIssue, type FapoReviewResult, type FapoScopeContract, FsLabeledScenarioStore, type FsLabeledScenarioStoreOptions, Gate, GenerationRecord, type GitWorktreeAdapterOptions, type HaloProposerOptions, type HeldoutSignificance, type HeldoutSignificanceOptions, type JsonPrimitive, type JsonValue, JudgeConfig, JudgeScore, LabelTrust, LabeledScenarioRecord, LabeledScenarioSampleArgs, LabeledScenarioSource, LabeledScenarioStore, LabeledScenarioStoreError, LabeledScenarioWrite, type LoadEvalFixtureScenariosOptions, type MemoryCurationProposerOptions, MutableSurface, type OptimizerEntryConfig, type PairedHoldout, type ParameterCandidate, type ParameterChange, type ParameterSweepProposerOptions, PlanCampaignRunOptions, type PlanEvalFixtureRunOptions, type PlaybackContext, type PlaybackDriver, type PlaybackStep, type PolicyEditProposerOptions, type ProfileDispatchFn, ProfileMatrixError, type ProfileSummary, ProposeContext, type ProposePatchesArgs, ProposedCandidate, type ProposerComparison, type ProposerEntry, type ProposerPairwise, type ProposerScore, type RejectedEdit, RunCampaignOptions, RunImprovementLoopOptions, type RunProfileMatrixOptions, type RunProfileMatrixResult, type RunSkillOptOptions, type RunSkillOptResult, Scenario, type ScenarioRollup, type ScoreboardRenderOptions, type ScoreboardRow, type ScoreboardSummary, type SequentialDecideFn, type SequentialDecideOptions, type SequentialDecision, type SequentialObservation, type SequentialPairedGate, type SequentialPairedGateOptions, type SkillOptEpochRecord, type SkillOptEvidence, type SkillOptProposer, type SkillOptProposerOptions, type SkillPatch, type SkillPatchOp, SkillPatchParseError, type SkillPatchRejection, SurfaceProposer, type TraceAnalystProposerOptions, type UserStory, type UserStoryVerdict, type Worktree, type WorktreeAdapter, WorktreeAdapterError, aceProposer, applySkillPatch, buildAnalystSurfaceDispatch, campaignBreakdown, campaignMeanComposite, compareProposers, detectScale, dimensionRegressions, discoverEvalFixtures, extractFapoAttributionSignals, failureModeRecallJudge, fapoEscalationEntry, fapoProposer, gepaParetoEntry, gepaReflectionEntry, gitWorktreeAdapter, haloProposer, heldoutSignificance, loadEvalFixture, loadEvalFixtureScenarios, makePlaybackDispatch, memoryCurationProposer, pairHoldout, parameterSweepProposer, parseSkillPatchResponse, patchEditCount, planEvalFixtureRun, policyEditProposer, renderScoreboardMarkdown, resolveWorktreePath, runProfileMatrix, runSkillOpt, scoreUserStory, scoreboardSummary, sequentialDecide, sequentialPairedGate, skillOptEntry, skillOptProposer, traceAnalystProposer, userStoryScoreboard };
@@ -10,15 +10,16 @@ import {
10
10
  paretoPolicy,
11
11
  paretoSignificanceGate,
12
12
  runEval
13
- } from "../chunk-G7IB3GJ5.js";
13
+ } from "../chunk-CHIFZIQD.js";
14
14
  import {
15
15
  agentProfileHash,
16
16
  agentProfileId,
17
17
  agentProfileModelId,
18
18
  extractProducedState,
19
+ harnessAxisOf,
19
20
  llmJudge,
20
21
  verifyCompletion
21
- } from "../chunk-VWQ6PO5O.js";
22
+ } from "../chunk-GUII3E73.js";
22
23
  import {
23
24
  buildLoopProvenanceRecord,
24
25
  campaignBreakdown,
@@ -40,14 +41,16 @@ import {
40
41
  runOptimization,
41
42
  surfaceContentHash,
42
43
  surfaceHash
43
- } from "../chunk-2KTBHICD.js";
44
+ } from "../chunk-NK77GPUH.js";
44
45
  import {
45
46
  assertRealBackend,
47
+ contentHash,
46
48
  fsCampaignStorage,
47
49
  inMemoryCampaignStorage,
50
+ planCampaignRun,
48
51
  runCampaign,
49
52
  summarizeBackendIntegrity
50
- } from "../chunk-HRGTA6U5.js";
53
+ } from "../chunk-XIOQHCHU.js";
51
54
  import {
52
55
  estimateCost,
53
56
  isModelPriced
@@ -84,7 +87,9 @@ import "../chunk-PC4UYEBM.js";
84
87
  import {
85
88
  validateRunRecord
86
89
  } from "../chunk-G6S73VA7.js";
87
- import "../chunk-ABOIVNXL.js";
90
+ import {
91
+ buildAgentProfileCell
92
+ } from "../chunk-ABOIVNXL.js";
88
93
  import {
89
94
  canonicalize
90
95
  } from "../chunk-VSMTAMNK.js";
@@ -155,17 +160,171 @@ function failureModeRecallJudge(opts = {}) {
155
160
  };
156
161
  }
157
162
 
158
- // src/campaign/gates/sequential.ts
163
+ // src/campaign/fixtures.ts
159
164
  import { createHash } from "crypto";
165
+ import { existsSync, readdirSync, readFileSync, statSync } from "fs";
166
+ import { isAbsolute, join, relative, resolve } from "path";
167
+ function discoverEvalFixtures(evalsDir) {
168
+ const root = resolve(evalsDir);
169
+ if (!existsSync(root)) throw new Error(`discoverEvalFixtures: evalsDir not found: ${root}`);
170
+ const fixtures = [];
171
+ const walk = (dir, base = "") => {
172
+ for (const entry of readdirSync(dir).sort()) {
173
+ if (entry.startsWith(".") || entry === "node_modules") continue;
174
+ const fullPath = join(dir, entry);
175
+ if (!statSync(fullPath).isDirectory()) continue;
176
+ const name = base ? `${base}/${entry}` : entry;
177
+ if (existsWithExactCase(fullPath, "PROMPT.md")) {
178
+ fixtures.push(name);
179
+ } else {
180
+ walk(fullPath, name);
181
+ }
182
+ }
183
+ };
184
+ walk(root);
185
+ return fixtures;
186
+ }
187
+ function loadEvalFixture(evalsDir, name, options = {}) {
188
+ const validation = options.validation ?? "vitest";
189
+ const root = resolve(evalsDir);
190
+ const fixturePath = resolve(root, name);
191
+ assertInside(root, fixturePath, name);
192
+ if (!existsSync(fixturePath) || !statSync(fixturePath).isDirectory()) {
193
+ throw new Error(`loadEvalFixture: fixture not found: ${name}`);
194
+ }
195
+ if (!existsWithExactCase(fixturePath, "PROMPT.md")) {
196
+ throw new Error(`loadEvalFixture: ${name} is missing exact-case PROMPT.md`);
197
+ }
198
+ const promptPath = join(fixturePath, "PROMPT.md");
199
+ const evalPath = resolveEvalPath(fixturePath);
200
+ const packageJsonPath = existsWithExactCase(fixturePath, "package.json") ? join(fixturePath, "package.json") : void 0;
201
+ if (validation !== "none") {
202
+ if (!evalPath)
203
+ throw new Error(`loadEvalFixture: ${name} is missing exact-case EVAL.ts or EVAL.tsx`);
204
+ if (!packageJsonPath)
205
+ throw new Error(`loadEvalFixture: ${name} is missing exact-case package.json`);
206
+ assertModulePackage(packageJsonPath, name);
207
+ }
208
+ const files = collectFixtureFiles(fixturePath);
209
+ return {
210
+ name,
211
+ path: fixturePath,
212
+ promptPath,
213
+ evalPath,
214
+ packageJsonPath,
215
+ prompt: readFileSync(promptPath, "utf8"),
216
+ files,
217
+ fingerprint: contentHash({
218
+ files,
219
+ config: options.fingerprintConfig ?? null
220
+ })
221
+ };
222
+ }
223
+ function loadEvalFixtureScenarios(evalsDir, options = {}) {
224
+ const names = options.names ?? discoverEvalFixtures(evalsDir);
225
+ return names.map((name) => {
226
+ const fixture = loadEvalFixture(evalsDir, name, options);
227
+ return {
228
+ id: fixture.name,
229
+ kind: "eval-fixture",
230
+ tags: ["eval-fixture"],
231
+ fixtureName: fixture.name,
232
+ fixturePath: fixture.path,
233
+ promptPath: fixture.promptPath,
234
+ evalPath: fixture.evalPath,
235
+ packageJsonPath: fixture.packageJsonPath,
236
+ prompt: fixture.prompt,
237
+ fingerprint: fixture.fingerprint
238
+ };
239
+ });
240
+ }
241
+ function planEvalFixtureRun(options) {
242
+ const scenarios = loadEvalFixtureScenarios(options.evalsDir, {
243
+ names: options.names,
244
+ validation: options.validation,
245
+ fingerprintConfig: options.fingerprintConfig
246
+ });
247
+ const plan = planCampaignRun({
248
+ scenarios,
249
+ dispatchRef: options.dispatchRef ?? "eval-fixture-dispatch",
250
+ judges: options.judges,
251
+ seed: options.seed,
252
+ reps: options.reps,
253
+ resumable: options.resumable,
254
+ runDir: options.runDir,
255
+ storage: options.storage
256
+ });
257
+ return {
258
+ ...plan,
259
+ fixtures: scenarios.map((scenario) => ({
260
+ fixtureName: scenario.fixtureName,
261
+ fixturePath: scenario.fixturePath,
262
+ fingerprint: scenario.fingerprint
263
+ }))
264
+ };
265
+ }
266
+ function existsWithExactCase(dirPath, fileName) {
267
+ try {
268
+ return readdirSync(dirPath).includes(fileName);
269
+ } catch {
270
+ return false;
271
+ }
272
+ }
273
+ function resolveEvalPath(fixturePath) {
274
+ if (existsWithExactCase(fixturePath, "EVAL.ts")) return join(fixturePath, "EVAL.ts");
275
+ if (existsWithExactCase(fixturePath, "EVAL.tsx")) return join(fixturePath, "EVAL.tsx");
276
+ return void 0;
277
+ }
278
+ function assertModulePackage(packageJsonPath, name) {
279
+ let parsed;
280
+ try {
281
+ parsed = JSON.parse(readFileSync(packageJsonPath, "utf8"));
282
+ } catch (err) {
283
+ throw new Error(
284
+ `loadEvalFixture: ${name} package.json is invalid JSON: ${err instanceof Error ? err.message : String(err)}`
285
+ );
286
+ }
287
+ if (typeof parsed !== "object" || parsed === null || parsed.type !== "module") {
288
+ throw new Error(`loadEvalFixture: ${name} package.json must set "type": "module"`);
289
+ }
290
+ }
291
+ function collectFixtureFiles(fixturePath, base = "") {
292
+ const files = [];
293
+ for (const entry of readdirSync(join(fixturePath, base)).sort()) {
294
+ if (entry === "node_modules" || entry === ".git") continue;
295
+ const relativePath = base ? `${base}/${entry}` : entry;
296
+ const fullPath = join(fixturePath, relativePath);
297
+ const stat = statSync(fullPath);
298
+ if (stat.isDirectory()) {
299
+ files.push(...collectFixtureFiles(fixturePath, relativePath));
300
+ continue;
301
+ }
302
+ const bytes = readFileSync(fullPath);
303
+ files.push({
304
+ path: relativePath,
305
+ sha256: createHash("sha256").update(bytes).digest("hex"),
306
+ bytes: bytes.byteLength
307
+ });
308
+ }
309
+ return files;
310
+ }
311
+ function assertInside(root, target, label) {
312
+ const rel = relative(root, target);
313
+ if (rel === "" || !rel.startsWith("..") && !isAbsolute(rel)) return;
314
+ throw new Error(`loadEvalFixture: fixture path escapes evalsDir: ${label}`);
315
+ }
316
+
317
+ // src/campaign/gates/sequential.ts
318
+ import { createHash as createHash2 } from "crypto";
160
319
  function verifyManifestSync(m) {
161
320
  if (m.algo !== void 0 && m.algo !== "sha256-content") {
162
321
  throw new Error(`sequentialPairedGate: unrecognized manifest hash algo '${m.algo}'`);
163
322
  }
164
- const { contentHash, algo: _algo, ...rest } = m;
323
+ const { contentHash: contentHash2, algo: _algo, ...rest } = m;
165
324
  void _algo;
166
325
  const bytes = JSON.stringify(canonicalize(rest));
167
- const hash = createHash("sha256").update(bytes, "utf8").digest("hex");
168
- return hash === contentHash;
326
+ const hash = createHash2("sha256").update(bytes, "utf8").digest("hex");
327
+ return hash === contentHash2;
169
328
  }
170
329
  function resolveConfig(opts) {
171
330
  const m = opts.preRegistration;
@@ -422,9 +581,9 @@ function sequentialDecide(options = {}) {
422
581
  }
423
582
 
424
583
  // src/campaign/labeled-store/fs-adapter.ts
425
- import { createHash as createHash2 } from "crypto";
426
- import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
427
- import { join } from "path";
584
+ import { createHash as createHash3 } from "crypto";
585
+ import { existsSync as existsSync2, mkdirSync, readFileSync as readFileSync2, writeFileSync } from "fs";
586
+ import { join as join2 } from "path";
428
587
  var LabeledScenarioStoreError = class extends Error {
429
588
  constructor(code, message) {
430
589
  super(message);
@@ -436,7 +595,7 @@ var LabeledScenarioStoreError = class extends Error {
436
595
  var FsLabeledScenarioStore = class {
437
596
  constructor(options) {
438
597
  this.options = options;
439
- if (!existsSync(options.root)) mkdirSync(options.root, { recursive: true });
598
+ if (!existsSync2(options.root)) mkdirSync(options.root, { recursive: true });
440
599
  this.now = options.now ?? Date.now;
441
600
  }
442
601
  options;
@@ -471,8 +630,8 @@ var FsLabeledScenarioStore = class {
471
630
  if (!explicit) continue;
472
631
  }
473
632
  const path = this.pathForSource(source);
474
- if (!existsSync(path)) continue;
475
- const lines = readFileSync(path, "utf8").split("\n").filter(Boolean);
633
+ if (!existsSync2(path)) continue;
634
+ const lines = readFileSync2(path, "utf8").split("\n").filter(Boolean);
476
635
  for (const line of lines) {
477
636
  let record;
478
637
  try {
@@ -500,11 +659,11 @@ var FsLabeledScenarioStore = class {
500
659
  let total = 0;
501
660
  for (const source of ALL_SOURCES) {
502
661
  const path = this.pathForSource(source);
503
- if (!existsSync(path)) {
662
+ if (!existsSync2(path)) {
504
663
  bySource[source] = 0;
505
664
  continue;
506
665
  }
507
- const lines = readFileSync(path, "utf8").split("\n").filter(Boolean);
666
+ const lines = readFileSync2(path, "utf8").split("\n").filter(Boolean);
508
667
  bySource[source] = lines.length;
509
668
  total += lines.length;
510
669
  for (const line of lines) {
@@ -584,7 +743,7 @@ var FsLabeledScenarioStore = class {
584
743
  };
585
744
  }
586
745
  pathForSource(source) {
587
- return join(this.options.root, `${source}.jsonl`);
746
+ return join2(this.options.root, `${source}.jsonl`);
588
747
  }
589
748
  };
590
749
  var ALL_SOURCES = [
@@ -621,11 +780,11 @@ function matchesFilter(record, args, source) {
621
780
  return true;
622
781
  }
623
782
  function sha256(input) {
624
- return createHash2("sha256").update(input).digest("hex").slice(0, 16);
783
+ return createHash3("sha256").update(input).digest("hex").slice(0, 16);
625
784
  }
626
785
  function appendLine(path, line) {
627
- if (existsSync(path)) {
628
- const existing = readFileSync(path, "utf8");
786
+ if (existsSync2(path)) {
787
+ const existing = readFileSync2(path, "utf8");
629
788
  writeFileSync(path, existing + line);
630
789
  } else {
631
790
  writeFileSync(path, line);
@@ -1850,8 +2009,8 @@ function renderScoreboardMarkdown(rows, opts = {}) {
1850
2009
  }
1851
2010
 
1852
2011
  // src/campaign/presets/run-profile-matrix.ts
1853
- import { createHash as createHash3 } from "crypto";
1854
- import { join as join2 } from "path";
2012
+ import { createHash as createHash4 } from "crypto";
2013
+ import { join as join3 } from "path";
1855
2014
  var ProfileMatrixError = class extends AgentEvalError {
1856
2015
  constructor(message) {
1857
2016
  super("profile_matrix", message);
@@ -1861,7 +2020,7 @@ function sanitize(id) {
1861
2020
  return id.replace(/[^a-zA-Z0-9_-]/g, "_");
1862
2021
  }
1863
2022
  function sha(input) {
1864
- return createHash3("sha256").update(JSON.stringify(input)).digest("hex");
2023
+ return createHash4("sha256").update(JSON.stringify(input)).digest("hex");
1865
2024
  }
1866
2025
  function mean2(xs) {
1867
2026
  return xs.length === 0 ? 0 : xs.reduce((a, b) => a + b, 0) / xs.length;
@@ -1930,6 +2089,7 @@ function buildRunRecord(args) {
1930
2089
  outcome,
1931
2090
  splitTag,
1932
2091
  scenarioId: cell.scenarioId,
2092
+ ...args.agentProfileCell ? { agentProfile: args.agentProfileCell } : {},
1933
2093
  ...cell.error ? { failureMode: cell.error } : {}
1934
2094
  };
1935
2095
  if (args.corpusText && args.scenario) {
@@ -2008,7 +2168,14 @@ async function runProfileMatrix(opts) {
2008
2168
  captureSource: opts.captureSource,
2009
2169
  storage: opts.storage,
2010
2170
  now: opts.now,
2011
- runDir: join2(opts.runDir, sanitize(profileId))
2171
+ runDir: join3(opts.runDir, sanitize(profileId))
2172
+ });
2173
+ const axis = harnessAxisOf(profile);
2174
+ const agentProfileCell = await buildAgentProfileCell({
2175
+ profileId,
2176
+ sourceProfile: { kind: "agent-interface-profile", hash: profileHash },
2177
+ model,
2178
+ ...axis ? { harness: { id: axis.harness } } : {}
2012
2179
  });
2013
2180
  const profileRecords = [];
2014
2181
  for (const cell of campaign.cells) {
@@ -2021,6 +2188,7 @@ async function runProfileMatrix(opts) {
2021
2188
  splitTag,
2022
2189
  commitSha: opts.commitSha,
2023
2190
  matrixId,
2191
+ agentProfileCell,
2024
2192
  scenario: scenarioById.get(cell.scenarioId),
2025
2193
  corpusText: opts.corpusText
2026
2194
  });
@@ -2175,7 +2343,7 @@ import { promisify } from "util";
2175
2343
  // src/campaign/proposers/analysis-edit.ts
2176
2344
  import { mkdtempSync, writeFileSync as writeFileSync2 } from "fs";
2177
2345
  import { tmpdir } from "os";
2178
- import { join as join3 } from "path";
2346
+ import { join as join4 } from "path";
2179
2347
  var APPLY_SYSTEM = "You apply a trace-analysis report to an agent instruction prompt. Output ONLY the full revised prompt \u2014 no preamble, no commentary, no code fences. Make the minimal edits that address the report findings; preserve everything else verbatim.";
2180
2348
  function surfaceToPromptText(surface) {
2181
2349
  return typeof surface === "string" ? surface : JSON.stringify(surface);
@@ -2187,8 +2355,8 @@ function analysisEditProposer(opts) {
2187
2355
  const parent = surfaceToPromptText(ctx.currentSurface);
2188
2356
  const traces = await opts.resolveTraces(ctx) ?? "";
2189
2357
  if (!traces.trim()) throw new Error(opts.noTracesError);
2190
- const dir = mkdtempSync(join3(tmpdir(), `${opts.kind}-proposer-`));
2191
- const tracePath = join3(dir, "traces.jsonl");
2358
+ const dir = mkdtempSync(join4(tmpdir(), `${opts.kind}-proposer-`));
2359
+ const tracePath = join4(dir, "traces.jsonl");
2192
2360
  writeFileSync2(tracePath, traces.endsWith("\n") ? traces : `${traces}
2193
2361
  `);
2194
2362
  const report = await opts.analyze(tracePath, ctx);
@@ -2473,8 +2641,8 @@ ${report.slice(0, 800)}`,
2473
2641
 
2474
2642
  // src/campaign/worktree/index.ts
2475
2643
  import { execFileSync } from "child_process";
2476
- import { existsSync as existsSync2 } from "fs";
2477
- import { basename, isAbsolute, join as join4 } from "path";
2644
+ import { existsSync as existsSync3 } from "fs";
2645
+ import { basename, isAbsolute as isAbsolute2, join as join5 } from "path";
2478
2646
  var WorktreeAdapterError = class extends Error {
2479
2647
  constructor(message, cause) {
2480
2648
  super(message);
@@ -2496,13 +2664,13 @@ function slug2(label) {
2496
2664
  }
2497
2665
  function gitWorktreeAdapter(opts) {
2498
2666
  const git = opts.git ?? defaultGit;
2499
- const worktreeDir = opts.worktreeDir ?? join4(opts.repoRoot, ".worktrees");
2667
+ const worktreeDir = opts.worktreeDir ?? join5(opts.repoRoot, ".worktrees");
2500
2668
  const branchPrefix = opts.branchPrefix ?? "improve";
2501
2669
  return {
2502
2670
  async create({ baseRef, label }) {
2503
2671
  const id = `${slug2(label)}-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 6)}`;
2504
2672
  const branch = `${branchPrefix}/${id}`;
2505
- const path = join4(worktreeDir, id);
2673
+ const path = join5(worktreeDir, id);
2506
2674
  git(["worktree", "add", "-b", branch, path, baseRef], opts.repoRoot);
2507
2675
  return { path, branch, baseRef };
2508
2676
  },
@@ -2526,8 +2694,8 @@ function gitWorktreeAdapter(opts) {
2526
2694
  };
2527
2695
  }
2528
2696
  function resolveWorktreePath(surface, worktreeDir) {
2529
- if (isAbsolute(surface.worktreeRef) && existsSync2(surface.worktreeRef)) return surface.worktreeRef;
2530
- if (worktreeDir) return join4(worktreeDir, basename(surface.worktreeRef));
2697
+ if (isAbsolute2(surface.worktreeRef) && existsSync3(surface.worktreeRef)) return surface.worktreeRef;
2698
+ if (worktreeDir) return join5(worktreeDir, basename(surface.worktreeRef));
2531
2699
  return surface.worktreeRef;
2532
2700
  }
2533
2701
  export {
@@ -2550,6 +2718,7 @@ export {
2550
2718
  defaultRenderDiff,
2551
2719
  detectScale,
2552
2720
  dimensionRegressions,
2721
+ discoverEvalFixtures,
2553
2722
  emitLoopProvenance,
2554
2723
  evolutionaryProposer,
2555
2724
  extractFapoAttributionSignals,
@@ -2569,6 +2738,8 @@ export {
2569
2738
  isProposedCandidate,
2570
2739
  labelTrustRank,
2571
2740
  llmJudge,
2741
+ loadEvalFixture,
2742
+ loadEvalFixtureScenarios,
2572
2743
  loopProvenanceSpans,
2573
2744
  makePlaybackDispatch,
2574
2745
  memoryCurationProposer,
@@ -2579,6 +2750,8 @@ export {
2579
2750
  paretoSignificanceGate,
2580
2751
  parseSkillPatchResponse,
2581
2752
  patchEditCount,
2753
+ planCampaignRun,
2754
+ planEvalFixtureRun,
2582
2755
  policyEditProposer,
2583
2756
  provenanceRecordPath,
2584
2757
  provenanceSpansPath,