@tangle-network/agent-runtime 0.300.0 → 0.306.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 (88) hide show
  1. package/dist/{activation-DqWmWTyB.js → activation-C5wesfzd.js} +3 -3
  2. package/dist/{activation-DqWmWTyB.js.map → activation-C5wesfzd.js.map} +1 -1
  3. package/dist/{activation-Bhp8dYV5.d.ts → activation-wZ-8vOjV.d.ts} +88 -13
  4. package/dist/agent.d.ts +2 -2
  5. package/dist/agent.js +2 -2
  6. package/dist/{bundle-C9v5TH_H.js → bundle-C8EO05u3.js} +2 -2
  7. package/dist/{bundle-C9v5TH_H.js.map → bundle-C8EO05u3.js.map} +1 -1
  8. package/dist/candidate-execution/index.d.ts +3 -26
  9. package/dist/candidate-execution/index.js +6 -6
  10. package/dist/{coordination-driver-DzTvehd6.js → coordination-driver-yj9HPXef.js} +322 -223
  11. package/dist/coordination-driver-yj9HPXef.js.map +1 -0
  12. package/dist/{delegate-vJ2g76r6.js → delegate-KtrL9HWq.js} +5 -5
  13. package/dist/delegate-KtrL9HWq.js.map +1 -0
  14. package/dist/durable.d.ts +3 -15
  15. package/dist/durable.js +158 -124
  16. package/dist/durable.js.map +1 -1
  17. package/dist/{graph-BDQh3qry.js → graph-DcdyHbgf.js} +5 -6
  18. package/dist/graph-DcdyHbgf.js.map +1 -0
  19. package/dist/{improvement-cycle-D6cPLi6k.js → improvement-cycle-DsN-TVXR.js} +1129 -10
  20. package/dist/improvement-cycle-DsN-TVXR.js.map +1 -0
  21. package/dist/{index-sC6sl88d.d.ts → index-DflDZq_I.d.ts} +188 -748
  22. package/dist/index.d.ts +378 -12
  23. package/dist/index.js +223 -320
  24. package/dist/index.js.map +1 -1
  25. package/dist/intelligence.d.ts +5 -5
  26. package/dist/intelligence.js +7 -8
  27. package/dist/intelligence.js.map +1 -1
  28. package/dist/kernel.d.ts +4 -4
  29. package/dist/kernel.js +9 -9
  30. package/dist/{loop-runner-bin-DZglq4Cf.d.ts → loop-runner-bin-DZfRUVWy.d.ts} +3 -3
  31. package/dist/{loop-runner-bin-DQIHnCL0.js → loop-runner-bin-rVrSX5l1.js} +3 -3
  32. package/dist/{loop-runner-bin-DQIHnCL0.js.map → loop-runner-bin-rVrSX5l1.js.map} +1 -1
  33. package/dist/loop-runner-bin.d.ts +1 -1
  34. package/dist/loop-runner-bin.js +1 -1
  35. package/dist/mcp/bin.js +3 -3
  36. package/dist/mcp/index.d.ts +6 -35
  37. package/dist/mcp/index.js +311 -364
  38. package/dist/mcp/index.js.map +1 -1
  39. package/dist/model-policy-DydyWTQg.js.map +1 -1
  40. package/dist/{openai-tools-DvR82zEo.d.ts → openai-tools-YO30D2s3.d.ts} +2 -2
  41. package/dist/{prepare-CGVNMb1o.js → prepare--nWcazPr.js} +7 -13
  42. package/dist/prepare--nWcazPr.js.map +1 -0
  43. package/dist/{profile-BetOB4_Q.js → profile-h04LDjV6.js} +2 -2
  44. package/dist/{profile-BetOB4_Q.js.map → profile-h04LDjV6.js.map} +1 -1
  45. package/dist/profiles.d.ts +2 -94
  46. package/dist/profiles.js +2 -451
  47. package/dist/profiles.js.map +1 -1
  48. package/dist/{protected-model-port-CAa0t1MT.d.ts → protected-model-port-C9QtEf3y.d.ts} +2 -2
  49. package/dist/{protected-model-port-CuVHkhti.js → protected-model-port-wwalbyXM.js} +4 -4
  50. package/dist/{protected-model-port-CuVHkhti.js.map → protected-model-port-wwalbyXM.js.map} +1 -1
  51. package/dist/{provision-supervisor-IXBlLHE0.js → provision-supervisor-WxFEFQeJ.js} +14 -24
  52. package/dist/provision-supervisor-WxFEFQeJ.js.map +1 -0
  53. package/dist/{runtime-DpEt5v42.js → runtime-B9eBIyws.js} +86 -496
  54. package/dist/runtime-B9eBIyws.js.map +1 -0
  55. package/dist/{search-method-DvU-fc-f.js → search-executor-2tWr38Qw.js} +239 -1132
  56. package/dist/search-executor-2tWr38Qw.js.map +1 -0
  57. package/dist/{server-CIE8s4AN.js → server-CpKcrOPj.js} +5 -12
  58. package/dist/server-CpKcrOPj.js.map +1 -0
  59. package/dist/{stream-agent-turn-I3bb0eqF.d.ts → stream-agent-turn-B1giFgOg.d.ts} +4 -2
  60. package/dist/{substrate-UjsxukjZ.d.ts → substrate-L_sC7jCD.d.ts} +2 -2
  61. package/dist/{supervise-C5mktzrh.js → supervise-DllOHM4M.js} +206 -80
  62. package/dist/supervise-DllOHM4M.js.map +1 -0
  63. package/dist/{supervisor-CQSu5XGl.js → supervisor-gCfG6K1-.js} +1130 -1667
  64. package/dist/supervisor-gCfG6K1-.js.map +1 -0
  65. package/dist/testing.d.ts +2 -2
  66. package/dist/testing.js +14 -14
  67. package/dist/tui/index.d.ts +1 -1
  68. package/dist/tui/index.js +1 -1
  69. package/dist/{types-C73caP0U.d.ts → types-DeuEkBhI.d.ts} +167 -261
  70. package/dist/{workspace-archive-pz8YJ1fr.d.ts → workspace-streams-CpSmt3zx.d.ts} +67 -3
  71. package/dist/{workspace-streams-D5gHJdTb.js → workspace-streams-ILw0eWZ0.js} +694 -2
  72. package/dist/workspace-streams-ILw0eWZ0.js.map +1 -0
  73. package/package.json +8 -8
  74. package/skills/generate-eval/SKILL.md +1 -1
  75. package/skills/profile-authoring/SKILL.md +5 -5
  76. package/skills/supervise/SKILL.md +2 -2
  77. package/dist/coordination-driver-DzTvehd6.js.map +0 -1
  78. package/dist/delegate-vJ2g76r6.js.map +0 -1
  79. package/dist/graph-BDQh3qry.js.map +0 -1
  80. package/dist/improvement-cycle-D6cPLi6k.js.map +0 -1
  81. package/dist/prepare-CGVNMb1o.js.map +0 -1
  82. package/dist/provision-supervisor-IXBlLHE0.js.map +0 -1
  83. package/dist/runtime-DpEt5v42.js.map +0 -1
  84. package/dist/search-method-DvU-fc-f.js.map +0 -1
  85. package/dist/server-CIE8s4AN.js.map +0 -1
  86. package/dist/supervise-C5mktzrh.js.map +0 -1
  87. package/dist/supervisor-CQSu5XGl.js.map +0 -1
  88. package/dist/workspace-streams-D5gHJdTb.js.map +0 -1
@@ -1,19 +1,18 @@
1
- import { At as createExecutor, Ba as promptFromAgentTurnInput, Bn as InMemoryResultBlobStore, Ca as sleep, Dt as captureReusableExecutorConfig, En as LEAF_CONTINUATION_TASK, Fa as awaitAbortable, Fi as authoredProfileDigest, Gi as runtimeOwnedExecutorMaterialization, Ha as providerMessageText, Hr as createOtelExporter, Jr as toOtelAttributes, Kr as padSpanId, La as armDeadlineTimer, M as withDriverExecutor, Mn as unavailableSignalOfFailure, Ri as knownExecutionBindingReceipt, Va as promptOptionsFromAgentTurnInput, Vn as InMemorySpawnJournal, Vr as createOpenInferenceFileExporter, Wi as runtimeOwnedExecutorExecutionBinding, Wr as generateSpanId, Xi as unknownMaterializationReceipt, Yi as unknownExecutionBindingReceipt, Zi as executableAgentProfileSnapshot, aa as createSandboxToolPartState, ca as isSandboxTerminalEvent, ia as canonicalStreamEventFromSandboxEvent, jn as unavailablePauseMs, jt as createExecutorRegistry, la as mapSandboxEvent, na as readSandboxOutcome, oa as createSandboxUsageLedger, qi as runtimeOwnedPendingExecutorMaterialization, qr as padTraceId, r as createSupervisor, si as harnessInvocation, ta as projectSandboxOutcome, ua as mapSandboxToolEvent, yr as openSlotGroup, zi as knownMaterializationReceipt } from "./supervisor-CQSu5XGl.js";
1
+ import { Ai as runtimeOwnedExecutorExecutionBinding, Fi as unknownExecutionBindingReceipt, Gi as createSandboxToolPartState, Hi as readSandboxOutcome, Ii as unknownMaterializationReceipt, Ir as padSpanId, Ji as isSandboxTerminalEvent, Ki as createSandboxUsageLedger, Li as executableAgentProfileSnapshot, Lr as padTraceId, Mr as createOtelExporter, Ni as runtimeOwnedPendingExecutorMaterialization, On as InMemoryResultBlobStore, Pr as generateSpanId, Rr as toOtelAttributes, St as createExecutorRegistry, Ti as knownMaterializationReceipt, Vi as projectSandboxOutcome, Wi as canonicalStreamEventFromSandboxEvent, Xi as mapSandboxToolEvent, Yi as mapSandboxEvent, Zr as harnessInvocation, aa as promptOptionsFromAgentTurnInput, bn as unavailableSignalOfFailure, ia as promptFromAgentTurnInput, j as withDriverExecutor, ji as runtimeOwnedExecutorMaterialization, jr as createOpenInferenceFileExporter, kn as InMemorySpawnJournal, lr as openSlotGroup, mn as LEAF_CONTINUATION_TASK, oa as providerMessageText, r as createSupervisor, ra as awaitAbortable, vt as captureReusableExecutorConfig, wi as knownExecutionBindingReceipt, xi as authoredProfileDigest, xt as createExecutor, yn as unavailablePauseMs } from "./supervisor-gCfG6K1-.js";
2
2
  import { i as ConfigError, m as ValidationError, p as SessionMismatchError, r as BackendTransportError } from "./errors-DodWX-cb.js";
3
+ import { F as immutableCandidateValue, G as errorMessage$1, Y as isAsyncIterable, _t as armDeadlineTimer, tt as sleep } from "./workspace-streams-ILw0eWZ0.js";
3
4
  import { a as concreteProfileModel, c as profileModelExecutionSettings, g as observedModelMatchesDeclared, i as concreteModelId, l as profileProviderModel, o as enforceTokenLimits, s as profileBridgeWireModel, t as assertExecutableAgentProfile } from "./model-policy-DydyWTQg.js";
4
- import { N as immutableCandidateValue, k as canonicalCandidateDigest$1 } from "./workspace-streams-D5gHJdTb.js";
5
- import { agentProfileSchema, applyAgentProfileDiff, canonicalAgentProfileDigest, canonicalCandidateDigest, diffAgentProfiles, renderInputPartsAsText, sha256DigestSchema } from "@tangle-network/agent-interface";
6
- import { CostAccountingIncompleteError, CostCeilingReachedError, canonicalJson, costForTokenPricing, costForUsage, makeProposalFinding, scoreKnowledgeReadiness } from "@tangle-network/agent-eval";
5
+ import { agentProfileSchema, canonicalAgentProfileDigest, canonicalCandidateDigest, renderInputPartsAsText } from "@tangle-network/agent-interface";
6
+ import { CostAccountingIncompleteError, CostCeilingReachedError, costForTokenPricing, costForUsage, makeProposalFinding, scoreKnowledgeReadiness } from "@tangle-network/agent-eval";
7
7
  import { createAgentRunOutcomeTracker } from "@tangle-network/sandbox/runtime";
8
- import { randomBytes, randomUUID } from "node:crypto";
8
+ import { createHash, randomBytes, randomUUID } from "node:crypto";
9
9
  import { mkdirSync, renameSync, writeFileSync } from "node:fs";
10
10
  import { dirname, join } from "node:path";
11
11
  import { materializeProfile } from "@tangle-network/agent-profile-materialize";
12
12
  import { ATTR, branchSpan } from "@tangle-network/agent-trace-contract";
13
- import { redact } from "@tangle-network/agent-eval/traces";
14
13
  import { assertProposalFindings } from "@tangle-network/agent-eval/analyst";
15
- import { SearchRecorder, aide, asha, campaignCellSearchResult, campaignScenarioIdentity, campaignSplitDigestFromIdentities, createRunCostLedger, fsCampaignStorage, isProposedCandidate, openSearchLedger, renderSearchSummary, resolveRunDir, runCampaign, runSearch, searchClaimReserveUsd, searchNodeId, searchProposalExecution, searchProposerView, searchReceiptAccounting } from "@tangle-network/agent-eval/campaign";
16
- import { defineEvaluationClaim, summarizeEvaluationUnits } from "@tangle-network/agent-eval/experiment";
14
+ import { createRunCostLedger, fsCampaignStorage, openSearchLedger, searchClaimDecision, searchReceiptAccounting, verifySearchClaim } from "@tangle-network/agent-eval/campaign";
15
+ import { sealExperiment } from "@tangle-network/agent-eval/experiment";
17
16
  import { harnessSystemPromptIntents } from "@tangle-network/agent-interface/harness-capabilities";
18
17
  //#region src/sessions.ts
19
18
  /**
@@ -817,9 +816,6 @@ function executorTaskValue(input) {
817
816
  ...input.interactions === void 0 ? {} : { interactions: input.interactions }
818
817
  };
819
818
  }
820
- function isAsyncIterable(value) {
821
- return typeof value === "object" && value !== null && Symbol.asyncIterator in value;
822
- }
823
819
  /**
824
820
  * Pull one provider iterator under Runtime's deadline.
825
821
  *
@@ -1188,15 +1184,6 @@ const strategyAuthorMethod = [
1188
1184
  " comment at the top of the module — the holdout verdict will be read against it."
1189
1185
  ].join("\n");
1190
1186
  //#endregion
1191
- //#region src/improvement/improve-result.ts
1192
- function copyImproveCost(cost) {
1193
- return {
1194
- totalCostUsd: cost.totalCostUsd,
1195
- accountingComplete: cost.accountingComplete,
1196
- incompleteReasons: [...cost.incompleteReasons]
1197
- };
1198
- }
1199
- //#endregion
1200
1187
  //#region src/runtime/profile-chat-client.ts
1201
1188
  /** Profile-exact adapter for packages that consume agent-eval's ChatClient contract.
1202
1189
  * Every call still enters Runtime through createExecutor -> streamAgentTurn, and every
@@ -1532,9 +1519,6 @@ function optimizerTokenCount(value, label) {
1532
1519
  if (!Number.isSafeInteger(value) || value < 0) throw new Error(`profile optimizer ${label} must be a non-negative integer`);
1533
1520
  return value;
1534
1521
  }
1535
- function errorMessage$1(error) {
1536
- return error instanceof Error ? error.message : String(error);
1537
- }
1538
1522
  //#endregion
1539
1523
  //#region src/runtime/observe.ts
1540
1524
  /**
@@ -2900,560 +2884,264 @@ function structuralRollout(config = {}) {
2900
2884
  });
2901
2885
  }
2902
2886
  //#endregion
2903
- //#region src/improvement/rollout-policy.ts
2904
- /** The profile extensions namespace the policy persists under. */
2905
- const ROLLOUT_POLICY_EXTENSION = "structural-rollout";
2906
- const isBoundedInt = (v, min) => typeof v === "number" && Number.isInteger(v) && v >= min;
2907
- /** Parse a serialized policy surface. Returns `undefined` for non-strings,
2908
- * malformed JSON, or values outside the policy invariants. Unknown fields are
2909
- * dropped; supported optional fields are preserved. */
2910
- function parseRolloutPolicy(surface) {
2911
- if (typeof surface !== "string" || surface.trim().length === 0) return void 0;
2912
- let raw;
2913
- try {
2914
- raw = JSON.parse(surface);
2915
- } catch {
2916
- return;
2917
- }
2918
- return normalizeRolloutPolicy(raw);
2919
- }
2920
- /** Normalize an untyped policy bag (a parsed surface or a profile extension) into
2921
- * a full `StructuralRolloutPolicy`, defaults merged. Returns `undefined` when any
2922
- * present dial violates the policy invariants (mirrors `resolvePolicy`: integer
2923
- * k ≥ 1, repairRounds ≥ 0, testgen ≥ 0) — a corrupt config must read as "not
2924
- * configured", never as a fabricated recipe. */
2925
- function normalizeRolloutPolicy(raw) {
2926
- if (typeof raw !== "object" || raw === null || Array.isArray(raw)) return void 0;
2927
- const bag = raw;
2928
- const k = bag.k ?? defaultStructuralRolloutPolicy.k;
2929
- const repairRounds = bag.repairRounds ?? defaultStructuralRolloutPolicy.repairRounds;
2930
- const testgen = bag.testgen ?? defaultStructuralRolloutPolicy.testgen;
2931
- if (!isBoundedInt(k, 1) || !isBoundedInt(repairRounds, 0) || !isBoundedInt(testgen, 0)) return;
2932
- return {
2933
- k,
2934
- repairRounds,
2935
- testgen,
2936
- ...typeof bag.diverse === "boolean" ? { diverse: bag.diverse } : {}
2937
- };
2938
- }
2939
- /** Stable serialization with fixed field order. */
2940
- function serializeRolloutPolicy(policy) {
2941
- return JSON.stringify({
2942
- k: policy.k,
2943
- repairRounds: policy.repairRounds,
2944
- testgen: policy.testgen,
2945
- ...policy.diverse !== void 0 ? { diverse: policy.diverse } : {}
2946
- });
2947
- }
2948
- /** Read the persisted policy off the profile. `undefined` when the profile does
2949
- * not opt into structural rollout. */
2950
- function structuralRolloutPolicyFromProfile(profile) {
2951
- const bag = profile.extensions?.[ROLLOUT_POLICY_EXTENSION];
2952
- if (bag === void 0) return void 0;
2953
- return normalizeRolloutPolicy(bag);
2954
- }
2955
- /** Persist a detached policy under the profile extension without mutating the input. */
2956
- function applyRolloutPolicyToProfile(profile, policy) {
2957
- const candidate = structuredClone(profile);
2958
- const bag = {
2959
- k: policy.k,
2960
- repairRounds: policy.repairRounds,
2961
- testgen: policy.testgen,
2962
- ...policy.diverse !== void 0 ? { diverse: policy.diverse } : {}
2887
+ //#region src/improvement/search-decision.ts
2888
+ /**
2889
+ * Runtime's decision on a closed search, made from its records alone: the claim
2890
+ * the ledger supports, the cost ledger's accounting, the ship rule, and, when
2891
+ * the search ships, the profiles-table promotion that cites the claim.
2892
+ *
2893
+ * `improve()` applies it when a search closes. `decideSearchImprovement`
2894
+ * applies it to a closed search's directory, so a search is decided again under
2895
+ * the current rule without running or spending anything. The ship rule is not
2896
+ * part of a search's identity: the same ledger re-decided after a rule change is
2897
+ * the same search.
2898
+ */
2899
+ /**
2900
+ * A search's cost as `ImproveCost`: the ledger's summary, plus the bound on the
2901
+ * calls whose cost is unknown when each declared a maximum before it ran. Those
2902
+ * are calls that failed with no receipt, or that a killed process left pending
2903
+ * and a restart settled unknown. Each counts at its maximum, the same bound the
2904
+ * ledger enforces its ceiling with.
2905
+ */
2906
+ function improveSearchCost(ledger) {
2907
+ const summary = ledger.summary();
2908
+ const cost = {
2909
+ totalCostUsd: summary.totalCostUsd,
2910
+ accountingComplete: summary.accountingComplete,
2911
+ incompleteReasons: [...summary.incompleteReasons]
2963
2912
  };
2913
+ if (summary.accountingComplete || summary.pendingCalls > 0) return cost;
2914
+ let unknownCalls = 0;
2915
+ let unknownMaximumUsd = 0;
2916
+ for (const receipt of ledger.list()) if (receipt.costUnknown) {
2917
+ if (receipt.maximumCostUsd === void 0) return cost;
2918
+ unknownCalls += 1;
2919
+ unknownMaximumUsd += receipt.maximumCostUsd;
2920
+ } else if (receipt.usageUnknown || receipt.maximumCostUsd !== void 0 && receipt.costUsd > receipt.maximumCostUsd) return cost;
2921
+ if (unknownCalls === 0) return cost;
2964
2922
  return {
2965
- ...candidate,
2966
- extensions: {
2967
- ...candidate.extensions,
2968
- [ROLLOUT_POLICY_EXTENSION]: bag
2923
+ ...cost,
2924
+ costBound: {
2925
+ unknownCalls,
2926
+ unknownMaximumUsd,
2927
+ totalMaximumUsd: summary.totalCostUsd + unknownMaximumUsd
2969
2928
  }
2970
2929
  };
2971
2930
  }
2972
- //#endregion
2973
- //#region src/improvement/profile-surface.ts
2974
- /** Extract the baseline optimized by a method and retain its structured value
2975
- * so external optimizers can inspect it for private fields before serialization. */
2976
- function prepareProfileSurface(profile, surface, skills, profileComponents) {
2977
- switch (surface) {
2978
- case "prompt": return {
2979
- surface: profile.prompt?.systemPrompt ?? "",
2980
- value: profile.prompt?.systemPrompt ?? ""
2981
- };
2982
- case "skills": {
2983
- const value = inlineSkill(profile, skills).content;
2984
- return {
2985
- surface: value,
2986
- value
2987
- };
2988
- }
2989
- case "tools": {
2990
- const value = profile.tools ?? {};
2991
- return {
2992
- surface: canonicalJson(value),
2993
- value
2994
- };
2995
- }
2996
- case "mcp": {
2997
- const value = profile.mcp ?? {};
2998
- return {
2999
- surface: canonicalJson(value),
3000
- value
3001
- };
3002
- }
3003
- case "hooks": {
3004
- const value = profile.hooks ?? {};
3005
- return {
3006
- surface: canonicalJson(value),
3007
- value
3008
- };
3009
- }
3010
- case "subagents": {
3011
- const value = profile.subagents ?? {};
3012
- return {
3013
- surface: canonicalJson(value),
3014
- value
3015
- };
3016
- }
3017
- case "agent-profile":
3018
- if (profileComponents) {
3019
- if (profileComponents.encoding !== void 0 && profileComponents.encoding !== "components" && profileComponents.encoding !== "json") throw new ConfigError("improve(): profileComponents.encoding must be components or json");
3020
- const value = profileComponents.read(profile);
3021
- const components = componentSurface(value, "profileComponents.read");
3022
- return {
3023
- surface: profileComponents.encoding === "json" ? canonicalJson(components.components) : components,
3024
- value
3025
- };
3026
- }
3027
- return {
3028
- surface: canonicalJson(profile),
3029
- value: profile
3030
- };
3031
- case "memory": {
3032
- const value = profileInstructions(profile);
3033
- return {
3034
- surface: value,
3035
- value
3036
- };
3037
- }
3038
- case "rollout-policy": {
3039
- const policy = structuralRolloutPolicyFromProfile(profile);
3040
- return {
3041
- surface: policy ? serializeRolloutPolicy(policy) : "",
3042
- value: policy ?? null
3043
- };
3044
- }
3045
- case "code": throw new ConfigError("improve(): code requires the isolated baseline created from opts.code.repoRoot");
3046
- }
3047
- }
3048
- function isCodeSurface(surface) {
3049
- return typeof surface === "object" && surface !== null && surface.kind === "code";
3050
- }
3051
- function isComponentSurface(surface) {
3052
- return typeof surface === "object" && surface !== null && surface.kind === "components";
3053
- }
3054
- function componentSurface(components, source) {
3055
- const entries = validateComponents(components, source);
3056
- return immutableCandidateValue({
3057
- kind: "components",
3058
- components: Object.fromEntries(entries)
3059
- });
3060
- }
3061
- function validateComponents(components, source) {
3062
- if (typeof components !== "object" || components === null || Array.isArray(components)) throw new ConfigError(`improve(): ${source} must return a component record`);
3063
- const entries = Object.entries(components);
3064
- if (entries.length === 0) throw new ConfigError(`improve(): ${source} must return at least one component`);
3065
- for (const [name, value] of entries) if (!name || name.trim() !== name || typeof value !== "string") throw new ConfigError(`improve(): ${source} must return trimmed component names with string values`);
3066
- return entries;
3067
- }
3068
- /** Parse a JSON winner surface with a typed, contextual error. */
3069
- function parseWinnerJson(winner, surface) {
3070
- try {
3071
- return JSON.parse(winner);
3072
- } catch (cause) {
3073
- throw new ConfigError(`improve(): the '${surface}' candidate is not valid JSON, so it cannot form a profile candidate: ${cause.message}`);
3074
- }
3075
- }
3076
- function assertCandidateSurfaceKind(surface, baseline, winner) {
3077
- if (surface === "code") {
3078
- if (isCodeSurface(winner)) return;
3079
- throw new ConfigError(`improve(): the '${surface}' candidate returned an incompatible surface value`);
3080
- }
3081
- if (typeof baseline === "string") {
3082
- if (typeof winner === "string") return;
3083
- throw new ConfigError(`improve(): the '${surface}' candidate changed from a text surface to an incompatible surface value`);
3084
- }
3085
- if (!isComponentSurface(baseline) || !isComponentSurface(winner)) throw new ConfigError(`improve(): the '${surface}' candidate returned an incompatible surface value`);
3086
- validateComponents(winner.components, `the '${surface}' candidate`);
3087
- const baselineNames = Object.keys(baseline.components).sort();
3088
- const winnerNames = Object.keys(winner.components).sort();
3089
- if (baselineNames.length !== winnerNames.length || baselineNames.some((name, index) => name !== winnerNames[index])) throw new ConfigError(`improve(): the '${surface}' candidate must preserve the exact component names`);
3090
- }
3091
- /** Materialize a detached profile candidate without changing the baseline. */
3092
- function materializeImprovementProfileCandidate(profile, surface, winner, skills, profileComponents) {
3093
- let candidate;
3094
- if (isComponentSurface(winner)) {
3095
- if (surface !== "agent-profile" || !profileComponents) throw new ConfigError(`improve(): the '${surface}' candidate has no profile component mapping`);
3096
- const winnerComponents = immutableCandidateValue({ ...winner.components });
3097
- const validated = parseMaterializedProfile(profileComponents.apply(profile, winnerComponents), surface);
3098
- const materializedComponents = Object.fromEntries(validateComponents(profileComponents.read(validated), "profileComponents.read after apply"));
3099
- const names = Object.keys(winnerComponents);
3100
- if (names.length !== Object.keys(materializedComponents).length || names.some((name) => materializedComponents[name] !== winnerComponents[name])) throw new ConfigError("improve(): profileComponents.apply must round-trip every winning component exactly");
3101
- return validated;
3102
- }
3103
- if (typeof winner !== "string") throw new ConfigError(`improve(): the '${surface}' candidate cannot form an AgentProfile`);
3104
- switch (surface) {
3105
- case "prompt":
3106
- candidate = {
3107
- ...profile,
3108
- prompt: {
3109
- ...profile.prompt,
3110
- systemPrompt: winner
3111
- }
3112
- };
3113
- break;
3114
- case "skills": {
3115
- const selectedSkill = inlineSkill(profile, skills);
3116
- candidate = {
3117
- ...profile,
3118
- resources: {
3119
- ...profile.resources,
3120
- skills: profile.resources?.skills?.map((resource) => resource === selectedSkill ? {
3121
- ...resource,
3122
- content: winner
3123
- } : resource)
3124
- }
3125
- };
3126
- break;
3127
- }
3128
- case "tools":
3129
- candidate = {
3130
- ...profile,
3131
- tools: parseWinnerJson(winner, surface)
3132
- };
3133
- break;
3134
- case "mcp":
3135
- candidate = {
3136
- ...profile,
3137
- mcp: parseWinnerJson(winner, surface)
3138
- };
3139
- break;
3140
- case "hooks":
3141
- candidate = {
3142
- ...profile,
3143
- hooks: parseWinnerJson(winner, surface)
3144
- };
3145
- break;
3146
- case "subagents":
3147
- candidate = {
3148
- ...profile,
3149
- subagents: parseWinnerJson(winner, surface)
3150
- };
3151
- break;
3152
- case "agent-profile":
3153
- candidate = parseWinnerJson(winner, surface);
3154
- break;
3155
- case "memory":
3156
- candidate = {
3157
- ...profile,
3158
- resources: {
3159
- ...profile.resources,
3160
- instructions: replaceProfileInstructions(profile, winner)
3161
- }
3162
- };
3163
- break;
3164
- case "rollout-policy": {
3165
- const policy = normalizeRolloutPolicy(parseWinnerJson(winner, surface));
3166
- if (!policy) throw new ConfigError(`improve(): the shipped 'rollout-policy' winner is not a valid StructuralRolloutPolicy (integer k >= 1, repairRounds >= 0, testgen >= 0), so it cannot be applied: ${winner}`);
3167
- candidate = applyRolloutPolicyToProfile(profile, policy);
3168
- break;
3169
- }
3170
- }
3171
- return parseMaterializedProfile(candidate, surface);
3172
- }
3173
- function parseMaterializedProfile(candidate, surface) {
3174
- const parsed = agentProfileSchema.safeParse(candidate);
3175
- if (!parsed.success) throw new ConfigError(`improve(): the '${surface}' candidate does not produce a valid AgentProfile: ${parsed.error.message}`);
3176
- return immutableCandidateValue(parsed.data);
3177
- }
3178
- function createProfileCandidateMaterializer(profile, surface, baselineSurface, skills, profileComponents) {
3179
- const decode = (candidate) => {
3180
- if (profileComponents?.encoding !== "json") return candidate;
3181
- if (typeof candidate !== "string") throw new ConfigError("improve(): JSON profile components require a text surface");
3182
- return componentSurface(parseWinnerJson(candidate, surface), "JSON profile components");
2931
+ /** Runtime's ship rule over the kernel's statistical claim (design §6.5 step 5), shared by
2932
+ * `searchMethod` and `runStrategyEvolution`. */
2933
+ function runtimeShipDecision(input) {
2934
+ const { claim, cost, costCeiling } = input;
2935
+ if (claim.decision !== "ship") return {
2936
+ decision: "hold",
2937
+ reason: claim.reason
3183
2938
  };
3184
- const decodedBaseline = decode(baselineSurface);
3185
- const baselineDigest = canonicalCandidateDigest$1(baselineSurface);
3186
- if (profileComponents) {
3187
- if (canonicalAgentProfileDigest(materializeImprovementProfileCandidate(profile, surface, decodedBaseline, skills, profileComponents)) !== canonicalAgentProfileDigest(profile)) throw new ConfigError("improve(): profileComponents.apply(profile, profileComponents.read(profile)) must reproduce the complete baseline profile exactly");
3188
- }
3189
- const candidates = /* @__PURE__ */ new Map([[baselineDigest, profile]]);
3190
- return (candidateSurface) => {
3191
- assertCandidateSurfaceKind(surface, baselineSurface, candidateSurface);
3192
- const decodedCandidate = decode(candidateSurface);
3193
- assertCandidateSurfaceKind(surface, decodedBaseline, decodedCandidate);
3194
- const digest = canonicalCandidateDigest$1(candidateSurface);
3195
- const existing = candidates.get(digest);
3196
- if (existing) return existing;
3197
- const candidate = materializeImprovementProfileCandidate(profile, surface, immutableCandidateValue(decodedCandidate), skills, profileComponents);
3198
- candidates.set(digest, candidate);
3199
- return candidate;
2939
+ if (!input.verified) return {
2940
+ decision: "hold",
2941
+ reason: "the claim shipped, but it does not re-derive from the ledger under this rule revision"
2942
+ };
2943
+ const bound = cost.accountingComplete ? void 0 : cost.costBound;
2944
+ if (!cost.accountingComplete && bound === void 0) return {
2945
+ decision: "hold",
2946
+ reason: "the claim shipped, but the search cost accounting is incomplete"
2947
+ };
2948
+ if (bound && costCeiling !== void 0 && bound.totalMaximumUsd > costCeiling) return {
2949
+ decision: "hold",
2950
+ reason: `the claim shipped, but ${bound.unknownCalls} call(s) of unknown cost, counted at their declared maximum, put the search at up to $${dollars$1(bound.totalMaximumUsd)}, above its $${dollars$1(costCeiling)} ceiling`
2951
+ };
2952
+ if (input.lowerBound === null || !(input.lowerBound > input.minimumLift)) return {
2953
+ decision: "hold",
2954
+ reason: `the claim shipped, but its test lower bound ${input.lowerBound} does not exceed minimumLift ${input.minimumLift}`
3200
2955
  };
3201
- }
3202
- function inlineSkill(profile, options) {
3203
- const resourceName = options?.resourceName.trim();
3204
- if (!resourceName) throw new ConfigError("improve(): surface 'skills' requires opts.skills.resourceName for one inline profile skill");
3205
- assertFailClosedResources(profile, "skills");
3206
- const matches = (profile.resources?.skills ?? []).filter((resource) => resource.name === resourceName);
3207
- if (matches.length !== 1 || matches[0]?.kind !== "inline") throw new ConfigError(`improve(): skill '${resourceName}' must identify exactly one inline profile resource`);
3208
- return matches[0];
3209
- }
3210
- function profileInstructions(profile) {
3211
- assertFailClosedResources(profile, "memory");
3212
- const instructions = profile.resources?.instructions;
3213
- if (instructions === void 0) return "";
3214
- if (typeof instructions === "string") return instructions;
3215
- if (instructions.kind === "inline") return instructions.content;
3216
- throw new ConfigError("improve(): surface 'memory' requires inline profile instructions so candidate bytes are exact");
3217
- }
3218
- function replaceProfileInstructions(profile, content) {
3219
- const instructions = profile.resources?.instructions;
3220
- if (typeof instructions !== "object") return content;
3221
- if (instructions.kind !== "inline") throw new ConfigError("improve(): surface 'memory' requires inline profile instructions so candidate bytes are exact");
3222
2956
  return {
3223
- ...instructions,
3224
- content
2957
+ decision: "ship",
2958
+ reason: bound ? `${claim.reason}; ${bound.unknownCalls} call(s) ended with no receipt and count at their declared maximum, $${dollars$1(bound.unknownMaximumUsd)}, so the search cost at most $${dollars$1(bound.totalMaximumUsd)}${costCeiling === void 0 ? "" : ` of its $${dollars$1(costCeiling)} ceiling`}` : claim.reason
3225
2959
  };
3226
2960
  }
3227
- function assertFailClosedResources(profile, surface) {
3228
- if (profile.resources?.failOnError !== true) throw new ConfigError(`improve(): surface '${surface}' requires profile.resources.failOnError: true`);
3229
- }
3230
- //#endregion
3231
- //#region src/improvement/candidate-validation.ts
3232
- /** One spelling of the execution-identity rule for optimization, training, and the harness. */
3233
- function parseExecutionRef(value, label) {
3234
- const parsed = sha256DigestSchema.safeParse(value);
3235
- if (!parsed.success) throw new ConfigError(`${label}: executionRef must be a lowercase sha256:<64 hex> digest`);
3236
- return parsed.data;
3237
- }
3238
- /** Validate the callback itself before any optimizer, trainer, or candidate work starts. */
3239
- function assertCandidateValidator(validator) {
3240
- if (validator !== void 0 && typeof validator !== "function") throw new ConfigError("validateCandidate must be a function when present");
3241
- }
3242
- /** A validator accepts synchronously by returning void, or rejects by throwing. */
3243
- function validateProfileCandidate(validator, input) {
3244
- assertCandidateValidator(validator);
3245
- const result = validator?.(Object.freeze(input));
3246
- if (result !== void 0) {
3247
- Promise.resolve(result).catch(() => {});
3248
- throw new ConfigError("candidate validators must return void synchronously or throw");
3249
- }
3250
- }
3251
2961
  /**
3252
- * Refuse exact held-out content digests already declared in this profile's training lineage.
3253
- * Both training and trainer-visible validation rows are exposure. This is an exact
3254
- * provenance check, not fuzzy decontamination or proof that undeclared training was fresh.
2962
+ * Decide a closed search: the ship rule, and the promotion when it ships.
2963
+ * `profileOf` returns the exact profile a node holds.
3255
2964
  */
3256
- function assertProfileTrainingIsHeldOut(profile, heldOutDigests) {
3257
- const training = profile.metadata?.training;
3258
- if (!training) return;
3259
- for (const receipt of [training.receipt, ...training.ancestors]) if (receipt.dataset.tasks.some((task) => heldOutDigests.has(task.contentDigest))) throw new ConfigError("known training exposure overlaps held-out evaluation");
3260
- }
3261
- /**
3262
- * JSON paths of credential and private values in candidate content, found by
3263
- * the redaction core, which names each value it would change. A candidate that
3264
- * leaves Runtime (an external optimizer, a search ledger) is refused on any.
3265
- */
3266
- function privateValuePaths(values) {
3267
- return [...new Set(values.flatMap((value) => redact(value).report.findings.map((finding) => jsonPathOf(finding.path))))];
3268
- }
3269
- /** `/remote/url` or `/tools/0/env` as `$.remote.url` or `$.tools[0].env`. */
3270
- function jsonPathOf(pointer) {
3271
- return pointer.split("/").slice(1).map((segment) => segment.replaceAll("~1", "/").replaceAll("~0", "~")).reduce((path, segment) => /^\d+$/.test(segment) ? `${path}[${segment}]` : `${path}.${segment}`, "$");
3272
- }
3273
- //#endregion
3274
- //#region src/improvement/method-identity.ts
3275
- function buildMethodEvaluationIdentity(input) {
3276
- const optimizationReps = input.optimizationRunOptions?.reps ?? 1;
3277
- const finalTestReps = input.reps ?? 1;
3278
- const scenarioPartitions = immutableCandidateValue({
3279
- train: input.trainScenarios.map(campaignScenarioIdentity),
3280
- selection: input.selectionScenarios.map(campaignScenarioIdentity),
3281
- finalTest: input.testScenarios.map(campaignScenarioIdentity),
3282
- optimizationReps,
3283
- finalTestReps
3284
- });
3285
- const developmentSplitDigest = canonicalCandidateDigest$1({
3286
- train: campaignSplitDigestFromIdentities(scenarioPartitions.train, optimizationReps),
3287
- selection: campaignSplitDigestFromIdentities(scenarioPartitions.selection, optimizationReps)
2965
+ async function decideClosedSearch(input) {
2966
+ const { claim, state } = input;
2967
+ const shipped = claim.finalists.find((finalist) => finalist.nodeId === claim.selected && finalist.test !== null);
2968
+ const ruled = runtimeShipDecision({
2969
+ claim,
2970
+ verified: input.claimVerification.status === "verified",
2971
+ cost: input.cost,
2972
+ costCeiling: input.costCeiling,
2973
+ lowerBound: shipped?.test?.interval[0] ?? null,
2974
+ minimumLift: input.minimumLift
3288
2975
  });
3289
- const finalTestSplitDigest = campaignSplitDigestFromIdentities(scenarioPartitions.finalTest, finalTestReps);
3290
- const judgeDescriptors = input.judges.map(judgeDescriptor);
3291
- return {
3292
- evaluationRef: canonicalCandidateDigest$1({
3293
- executionRef: input.executionRef,
3294
- baselineProfileDigest: input.baselineProfileDigest,
3295
- coordinate: profileCoordinate(input.surface, input.baselineSurface, input.skills),
3296
- candidateValidation: input.validateCandidate ? Function.prototype.toString.call(input.validateCandidate) : null,
3297
- developmentSplitDigest,
3298
- finalTestSplitDigest,
3299
- findings: input.findings,
3300
- judges: judgeDescriptors,
3301
- run: {
3302
- seed: input.seed ?? 42,
3303
- finalReps: input.reps ?? 1,
3304
- optimizationReps,
3305
- costCeiling: input.costCeiling ?? null,
3306
- resumable: input.optimizationRunOptions?.resumable ?? true,
3307
- maxConcurrency: input.optimizationRunOptions?.maxConcurrency ?? 2,
3308
- abortOnCellError: input.optimizationRunOptions?.abortOnCellError ?? false,
3309
- dispatchTimeoutMs: input.optimizationRunOptions?.dispatchTimeoutMs ?? null,
3310
- dispatchShutdownTimeoutMs: input.optimizationRunOptions?.dispatchShutdownTimeoutMs ?? 5e3,
3311
- tracing: input.optimizationRunOptions?.tracing ?? "on",
3312
- expectUsage: input.optimizationRunOptions?.expectUsage ?? "warn",
3313
- captureSource: input.optimizationRunOptions?.captureSource ?? null,
3314
- captureSourceVersionHash: input.optimizationRunOptions?.captureSourceVersionHash ?? null
3315
- }
3316
- }),
3317
- developmentSplitDigest,
3318
- finalTestSplitDigest,
3319
- scenarioPartitions,
3320
- judgeDescriptors
2976
+ const lift = shipped?.test ? {
2977
+ lift: shipped.test.delta,
2978
+ liftInterval: {
2979
+ low: shipped.test.interval[0],
2980
+ high: shipped.test.interval[1]
2981
+ }
2982
+ } : {};
2983
+ if (ruled.decision !== "ship") return {
2984
+ ...ruled,
2985
+ ...lift
3321
2986
  };
3322
- }
3323
- function profileCoordinate(surface, baselineSurface, skills) {
3324
- return {
3325
- surface,
3326
- resourceName: surface === "skills" ? skills?.resourceName.trim() ?? null : null,
3327
- componentNames: typeof baselineSurface === "object" && baselineSurface !== null && baselineSurface.kind === "components" ? Object.keys(baselineSurface.components).sort() : []
2987
+ const promotion = await searchPromotion(state, claim, input.profileOf);
2988
+ if ("refused" in promotion) return {
2989
+ decision: "hold",
2990
+ reason: `${ruled.reason}; held: ${promotion.refused}`,
2991
+ ...lift
3328
2992
  };
3329
- }
3330
- function judgeDescriptor(judge) {
3331
2993
  return {
3332
- name: judge.name,
3333
- dimensions: judge.dimensions.map((dimension) => ({ ...dimension })),
3334
- declaredVersion: judge.judgeVersion ?? null,
3335
- scoreImplementation: Function.prototype.toString.call(judge.score),
3336
- appliesToImplementation: judge.appliesTo ? Function.prototype.toString.call(judge.appliesTo) : null
2994
+ ...ruled,
2995
+ ...lift,
2996
+ promotion
3337
2997
  };
3338
2998
  }
3339
- //#endregion
3340
- //#region src/improvement/profile-improvement.ts
3341
2999
  /**
3342
- * What every profile improvement prepares before any optimizer or search runs:
3343
- * the exact surface and its baseline, the evaluation identity, identified
3344
- * judges, the identities a search ledger records, and one materializer that
3345
- * admits a candidate only after the held-out and caller checks. `improve()`
3346
- * with an external method and with `searchMethod` share it, so a candidate is
3347
- * materialized and admitted the same way on both paths.
3000
+ * The claim as a profiles-table promotion. The sealed experiment states the
3001
+ * claim's design: the root as control and every finalist the claim tested as a
3002
+ * treatment, each by its exact profile digest, fixed before any test cell ran.
3003
+ * The decision is Eval's paired decision for the selected finalist, made again
3004
+ * from the ledger by `searchClaimDecision`. The seal is dated by the search's
3005
+ * close, so the same ledger always yields the same promotion.
3348
3006
  */
3349
- function prepareProfileImprovement(profile, input) {
3350
- const { surface = "prompt", validateCandidate, skills, profileComponents, minimumLift = 0 } = input;
3351
- assertCandidateValidator(validateCandidate);
3352
- if (!Number.isFinite(minimumLift) || minimumLift < 0) throw new ConfigError("improve(): minimumLift must be a finite number greater than or equal to 0");
3353
- if (profileComponents && surface !== "agent-profile") throw new ConfigError("improve(): profileComponents is valid only with surface 'agent-profile'");
3354
- if (input.subject !== void 0 && (typeof input.subject !== "string" || !input.subject.trim() || input.subject !== input.subject.trim())) throw new ConfigError("improve(): subject must be a trimmed non-empty string");
3355
- const executionRef = parseExecutionRef(input.executionRef, "improve()");
3356
- const findings = immutableCandidateValue([...assertProposalFindings(input.findings ?? [], "improve() method findings")]);
3357
- const preparedSurface = prepareProfileSurface(profile, surface, skills, profileComponents);
3358
- const baselineSurface = preparedSurface.surface;
3359
- const baselineValue = immutableCandidateValue(preparedSurface.value);
3360
- const baselineProfileDigest = canonicalAgentProfileDigest(profile);
3361
- const identity = buildMethodEvaluationIdentity({
3362
- executionRef,
3363
- baselineProfileDigest,
3364
- baselineSurface,
3365
- surface,
3366
- skills,
3367
- validateCandidate,
3368
- findings,
3369
- trainScenarios: input.trainScenarios,
3370
- selectionScenarios: input.selectionScenarios,
3371
- testScenarios: input.testScenarios,
3372
- judges: input.judges,
3373
- seed: input.seed,
3374
- reps: input.reps,
3375
- costCeiling: input.costCeiling,
3376
- optimizationRunOptions: input.optimizationRunOptions
3377
- });
3378
- const judges = input.judges.map((judge, index) => Object.freeze({
3379
- ...judge,
3380
- judgeVersion: canonicalCandidateDigest$1({
3381
- evaluationRef: identity.evaluationRef,
3382
- descriptor: identity.judgeDescriptors[index]
3383
- })
3384
- }));
3385
- const rawMaterializeProfile = createProfileCandidateMaterializer(profile, surface, baselineSurface, skills, profileComponents);
3386
- const baselineSurfaceDigest = canonicalCandidateDigest$1(baselineSurface);
3387
- const heldOutDigests = new Set(identity.scenarioPartitions.finalTest.map((task) => task.scenarioDigest));
3388
- const validatedCandidates = /* @__PURE__ */ new Set();
3389
- const validateMaterialized = (validator, candidate, candidateSurface, isBaseline) => {
3390
- const prepared = prepareProfileSurface(candidate, surface, skills, profileComponents);
3391
- validateProfileCandidate(validator, {
3392
- profile: candidate,
3393
- surface,
3394
- candidateSurface,
3395
- value: immutableCandidateValue(prepared.value),
3396
- isBaseline
3397
- });
3398
- };
3399
- const admitCandidate = (candidate, candidateSurface) => {
3400
- const candidateDigest = canonicalCandidateDigest$1(candidateSurface);
3401
- if (validatedCandidates.has(candidateDigest)) return;
3402
- assertProfileTrainingIsHeldOut(candidate, heldOutDigests);
3403
- validateMaterialized(validateCandidate, candidate, immutableCandidateValue(candidateSurface), candidateDigest === baselineSurfaceDigest);
3404
- validatedCandidates.add(candidateDigest);
3405
- };
3406
- const materializeProfile = (candidateSurface) => {
3407
- const candidate = rawMaterializeProfile(candidateSurface);
3408
- admitCandidate(candidate, candidateSurface);
3409
- return candidate;
3007
+ async function searchPromotion(state, claim, profileOf) {
3008
+ const header = state.header;
3009
+ const closed = state.closed;
3010
+ const root = state.rootNodeId;
3011
+ const selected = claim.selected;
3012
+ if (!header || !closed || root === null || selected === null) return { refused: "the ledger holds no closed claim with a selected finalist" };
3013
+ const decision = searchClaimDecision(state, selected);
3014
+ if (decision === null || decision.promote !== true) return { refused: `Eval's paired decision for ${selected} does not promote` };
3015
+ if (!("adequate" in claim.power)) return { refused: "the claim tested its finalists without a known power" };
3016
+ const tested = claim.finalists.filter((finalist) => finalist.test !== null);
3017
+ const estimator = claim.power.estimator;
3018
+ let outcome;
3019
+ if (estimator.kind === "binary") outcome = {
3020
+ kind: "binary",
3021
+ pass: `the per-unit test mean equals ${estimator.scale}`
3410
3022
  };
3411
- materializeProfile(baselineSurface);
3023
+ else {
3024
+ if ([root, ...tested.map((finalist) => finalist.nodeId)].flatMap((nodeId) => state.unitScores(nodeId, "test").map((unit) => unit.mean)).some((score) => score < 0 || score > 1)) return { refused: "a test score leaves the campaign's [0, 1] score scale" };
3025
+ outcome = {
3026
+ kind: "bounded-score",
3027
+ min: 0,
3028
+ max: 1,
3029
+ orientation: header.objective.direction === "maximize" ? "higher-is-better" : "lower-is-better"
3030
+ };
3031
+ }
3032
+ const arm = (nodeId, role) => ({
3033
+ id: nodeId,
3034
+ role,
3035
+ profileDigest: canonicalAgentProfileDigest(profileOf(nodeId)),
3036
+ pins: {
3037
+ searchId: state.searchId,
3038
+ nodeId
3039
+ }
3040
+ });
3041
+ const testUnits = new Set(header.splits.test.tasks.map((task) => task.unitId)).size;
3412
3042
  return {
3413
- profile,
3414
- surface,
3415
- executionRef,
3416
- findings,
3417
- minimumLift,
3418
- baselineSurface,
3419
- baselineValue,
3420
- baselineProfileDigest,
3421
- identity,
3422
- invocationId: `runtime-optimization:${randomUUID()}`,
3423
- judges,
3424
- searchIdentity: Object.freeze({
3425
- subject: input.subject ?? profile.name ?? "agent-profile",
3426
- agent: {
3427
- uri: "agent-runtime:improve-execution-ref",
3428
- revision: executionRef
3429
- },
3430
- judge: {
3431
- uri: "agent-runtime:improve-judges",
3432
- revision: canonicalCandidateDigest$1(identity.judgeDescriptors)
3043
+ experiment: await sealExperiment({
3044
+ id: `${state.searchId}.claim`,
3045
+ claim: header.objective.claim,
3046
+ hypothesis: `Each finalist of search ${state.searchId} beats the root on its ${testUnits} sealed test units at confidence ${tested[0]?.test?.confidence ?? claim.confidence}, by Eval's paired decision (${claim.rule.uri} ${claim.rule.revision}); the claim fixed these arms before any test cell ran.`,
3047
+ arms: [arm(root, "control"), ...tested.map((finalist) => arm(finalist.nodeId, "treatment"))],
3048
+ outcome,
3049
+ decision: {
3050
+ kind: "report-only",
3051
+ estimands: [],
3052
+ intervals: [],
3053
+ perRow: []
3433
3054
  },
3434
- model: profileModel(profile)
3435
- }),
3436
- surfaceOf: (candidate) => prepareProfileSurface(candidate, surface, skills, profileComponents).surface,
3437
- materializeCandidate: rawMaterializeProfile,
3438
- admitCandidate,
3439
- materializeProfile,
3440
- validateMaterialized
3055
+ seed: header.policy.seed
3056
+ }, { sealedAt: closed.occurredAt }),
3057
+ decision
3441
3058
  };
3442
3059
  }
3443
- /** The profile's model hint as a moving alias; each cell records what it resolved. */
3444
- function profileModel(profile) {
3445
- const hint = profile.model?.default;
3446
- if (!hint) return {
3447
- provider: "unspecified",
3448
- alias: "unspecified",
3449
- unknown: "the profile names no model; each cell records the model it resolved"
3450
- };
3060
+ /**
3061
+ * Decide a closed search from its directory, under the current ship rule, with
3062
+ * no model call: the claim verified from the ledger, the cost from its cost
3063
+ * ledger, and the promotion when it ships. Use it to cite a finished search as
3064
+ * a registry promotion, or to re-decide one that an earlier rule held.
3065
+ */
3066
+ async function decideSearchImprovement(options) {
3067
+ const storage = options.storage ?? fsCampaignStorage();
3068
+ const minimumLift = options.minimumLift ?? 0;
3069
+ if (!Number.isFinite(minimumLift) || minimumLift < 0) throw new ConfigError("decideSearchImprovement(): minimumLift must be a finite number of at least 0");
3070
+ const ledgerPath = join(options.searchDir, "ledger.jsonl");
3071
+ const text = storage.read(ledgerPath);
3072
+ if (text === void 0) throw new ConfigError(`decideSearchImprovement(): no search ledger at ${ledgerPath}`);
3073
+ const first = text.slice(0, text.indexOf("\n"));
3074
+ const searchId = JSON.parse(first).searchId;
3075
+ if (typeof searchId !== "string") throw new ConfigError(`decideSearchImprovement(): ${ledgerPath} names no searchId`);
3076
+ const state = await (storage.kind === "filesystem" ? openSearchLedger({
3077
+ path: ledgerPath,
3078
+ searchId
3079
+ }) : openSearchLedger({
3080
+ path: ledgerPath,
3081
+ searchId,
3082
+ store: storage
3083
+ })).state();
3084
+ const claim = state.closed?.claim;
3085
+ if (!state.closed || !claim) throw new ConfigError(`decideSearchImprovement(): search ${searchId} is ${state.closed ? "closed without a claim" : "still open"}`);
3086
+ const costLedger = options.costLedger ?? createRunCostLedger({
3087
+ storage,
3088
+ runDir: options.searchDir,
3089
+ ensureRunDir: false
3090
+ });
3091
+ const profileOf = searchProfileReader(state, storage, dirname(ledgerPath));
3092
+ const cost = improveSearchCost(costLedger);
3093
+ const claimVerification = verifySearchClaim(state);
3094
+ const decided = await decideClosedSearch({
3095
+ state,
3096
+ claim,
3097
+ claimVerification,
3098
+ cost,
3099
+ costCeiling: state.header?.budget.maxUsd ?? void 0,
3100
+ minimumLift,
3101
+ profileOf
3102
+ });
3103
+ const root = state.rootNodeId;
3451
3104
  return {
3452
- provider: profile.model?.provider ?? "unspecified",
3453
- alias: hint,
3454
- unknown: "the profile names a model hint, not a snapshot; each cell records the model it resolved"
3105
+ searchId,
3106
+ claim,
3107
+ claimVerification,
3108
+ cost,
3109
+ ...decided,
3110
+ baseline: profileOf(root),
3111
+ candidate: profileOf(claim.selected ?? root)
3112
+ };
3113
+ }
3114
+ /** Each node's exact profile from the search's blob store, checked against
3115
+ * the blob's content address and the node's profile digest. */
3116
+ function searchProfileReader(state, storage, dir) {
3117
+ const read = /* @__PURE__ */ new Map();
3118
+ return (nodeId) => {
3119
+ const known = read.get(nodeId);
3120
+ if (known) return known;
3121
+ const node = state.node(nodeId);
3122
+ if (!node) throw new ConfigError(`decideSearchImprovement(): no node ${nodeId}`);
3123
+ const stored = readBlob(storage, dir, node.artifact);
3124
+ const parsed = agentProfileSchema.safeParse(stored.profile);
3125
+ if (stored.kind !== "agent-profile" || !parsed.success) throw new ConfigError(`decideSearchImprovement(): node ${nodeId} holds no AgentProfile`);
3126
+ const profile = immutableCandidateValue(parsed.data);
3127
+ if (canonicalAgentProfileDigest(profile) !== node.artifactDigest) throw new ConfigError(`decideSearchImprovement(): node ${nodeId}'s profile does not match its digest ${node.artifactDigest}`);
3128
+ read.set(nodeId, profile);
3129
+ return profile;
3455
3130
  };
3456
3131
  }
3132
+ /** A blob the search stored, read from the blob directory beside its ledger,
3133
+ * whatever directory the ledger was written in, and checked against its digest. */
3134
+ function readBlob(storage, dir, ref) {
3135
+ const hex = ref.sha256.slice(7);
3136
+ const path = join(dir, "blobs", `${hex}.json`);
3137
+ const text = storage.read(path);
3138
+ if (text === void 0) throw new ConfigError(`decideSearchImprovement(): missing blob ${path}`);
3139
+ if (createHash("sha256").update(text, "utf8").digest("hex") !== hex) throw new ConfigError(`decideSearchImprovement(): blob ${path} does not match its digest`);
3140
+ return JSON.parse(text);
3141
+ }
3142
+ function dollars$1(value) {
3143
+ return value.toFixed(value < 1 ? 4 : 2);
3144
+ }
3457
3145
  //#endregion
3458
3146
  //#region src/runtime/shared-box.ts
3459
3147
  /**
@@ -5092,587 +4780,6 @@ function otelSpan(input) {
5092
4780
  };
5093
4781
  }
5094
4782
  //#endregion
5095
- //#region src/improvement/search-method.ts
5096
- /** Build Runtime's native search for `improve(profile, { method })`. */
5097
- function searchMethod(options) {
5098
- if (!options || typeof options !== "object") throw new ConfigError("searchMethod(): options are required");
5099
- const { proposer } = options;
5100
- if (!proposer || typeof proposer.kind !== "string" || typeof proposer.propose !== "function") throw new ConfigError("searchMethod(): proposer must be a SurfaceProposer");
5101
- const count = (name, value, fallback, min) => {
5102
- const resolved = value ?? fallback;
5103
- if (!Number.isSafeInteger(resolved) || resolved < min) throw new ConfigError(`searchMethod(): ${name} must be an integer of at least ${min}`);
5104
- return resolved;
5105
- };
5106
- const dollars = (name, value) => {
5107
- if (value === void 0) return null;
5108
- if (!Number.isFinite(value) || value < 0) throw new ConfigError(`searchMethod(): ${name} must be a finite non-negative number`);
5109
- return value;
5110
- };
5111
- if (options.deadline !== void 0 && !Number.isFinite(Date.parse(options.deadline))) throw new ConfigError("searchMethod(): deadline must be an ISO time");
5112
- const name = options.name ?? "search";
5113
- if (!name.trim() || name.trim() !== name) throw new ConfigError("searchMethod(): name must be a trimmed non-empty string");
5114
- assertSearchLanes(options.lanes, "searchMethod()");
5115
- return Object.freeze({
5116
- kind: "search",
5117
- name,
5118
- policy: options.policy ?? aide(),
5119
- allocation: options.allocation ?? asha(),
5120
- proposer,
5121
- maxExpansions: count("maxExpansions", options.maxExpansions, NaN, 0),
5122
- childrenPerProposal: count("childrenPerProposal", options.childrenPerProposal, 1, 1),
5123
- lanes: Object.freeze([...options.lanes]),
5124
- claimReserveUsd: dollars("claimReserveUsd", options.claimReserveUsd),
5125
- deadline: options.deadline === void 0 ? null : new Date(options.deadline).toISOString(),
5126
- maxAttempts: count("maxAttempts", options.maxAttempts, 3, 1)
5127
- });
5128
- }
5129
- function isImproveSearchMethod(value) {
5130
- return typeof value === "object" && value !== null && value.kind === "search";
5131
- }
5132
- const SEARCH_METHOD_SOURCE = {
5133
- uri: "npm:@tangle-network/agent-runtime#searchMethod",
5134
- revision: canonicalCandidateDigest$1({
5135
- name: "agent-runtime.search-method.2026-09",
5136
- node: "an exact AgentProfile materialized from the baseline and one surface, content-addressed by canonicalAgentProfileDigest; a surface that does not materialize is a node addressed by its surface and refused",
5137
- edge: "the Interface diffs from the parent profile to the child, stored when they reproduce the child digest",
5138
- admission: "a candidate is refused when it does not materialize, declares training on a test task, fails the caller validator, carries a credential or private value, or no lane can run its profile",
5139
- cell: "a one-cell runCampaign of the materialized profile in a directory addressed by its digest, on a lane that accepts the profile; a cached cell is read back, not run again; a finished attempt is recorded by run id before it settles and adopted after a restart",
5140
- lanes: "a hard lane refuses a paid call that declares no priced maximum or would take the cell past its cellUsd; an environment fault settles errored and retryable; a subscription seat reports no tokens and charges no dollars",
5141
- proposer: "a SurfaceProposer reads the parents, the train view and the train summary; paid calls it makes are its operation accounting",
5142
- ship: "the claim shipped, re-derives from the ledger, cost accounting is complete, and the shipped finalist test lower bound exceeds minimumLift"
5143
- })
5144
- };
5145
- async function runSearchImprovement(profile, opts) {
5146
- const { method, claim: inputClaim, agent, executionRunId, recordCell, trainScenarios, selectionScenarios, testScenarios, judges: _judges, surface: _surface, executionRef: _executionRef, validateCandidate: _validateCandidate, findings: _findings, skills: _skills, profileComponents: _profileComponents, minimumLift: _minimumLift, subject: _subject, costCeiling, costLedger: inputCostLedger, seed = 42, signal, workerSlots, budgetPool, trace, ...campaignOptions } = opts;
5147
- if (!isImproveSearchMethod(method)) throw new ConfigError("improve(): a search needs method: searchMethod(...)");
5148
- const claim = defineEvaluationClaim(inputClaim);
5149
- if (claim.minimumEffect === void 0) throw new ConfigError("improve(): a search claim needs minimumEffect for its power check");
5150
- for (const [name, split] of [
5151
- ["trainScenarios", trainScenarios],
5152
- ["selectionScenarios", selectionScenarios],
5153
- ["testScenarios", testScenarios]
5154
- ]) if (!Array.isArray(split) || split.length === 0) throw new ConfigError(`improve(): a search needs at least one of ${name}`);
5155
- const { allocation, policy, lanes } = method;
5156
- const reps = allocation.reps;
5157
- const concurrency = lanes.reduce((total, lane) => total + lane.capacity, 0);
5158
- const prepared = prepareProfileImprovement(profile, {
5159
- ...opts,
5160
- seed,
5161
- reps,
5162
- optimizationRunOptions: {
5163
- reps,
5164
- maxConcurrency: concurrency
5165
- }
5166
- });
5167
- const { evaluationRef } = prepared.identity;
5168
- const storage = campaignOptions.storage ?? fsCampaignStorage();
5169
- const runDir = resolveRunDir(campaignOptions.runDir, campaignOptions.repo);
5170
- const searchId = `improve-${canonicalCandidateDigest$1({
5171
- evaluationRef,
5172
- process: SEARCH_METHOD_SOURCE,
5173
- method: searchMethodDescriptor(method)
5174
- }).slice(7, 31)}`;
5175
- const searchDir = `${runDir}/search/${searchId}`;
5176
- const costLedger = inputCostLedger ?? createRunCostLedger({
5177
- storage,
5178
- runDir: searchDir,
5179
- costCeilingUsd: costCeiling
5180
- });
5181
- const unitOf = (scenario) => summarizeEvaluationUnits(claim, [scenario]).units[0].id;
5182
- const tasks = (scenarios) => scenarios.map((scenario) => ({
5183
- taskId: scenario.id,
5184
- unitId: unitOf(scenario),
5185
- source: {
5186
- uri: `scenario://${scenario.id}`,
5187
- revision: canonicalCandidateDigest$1(scenario)
5188
- }
5189
- }));
5190
- const splits = {
5191
- train: tasks(trainScenarios),
5192
- selection: tasks(selectionScenarios),
5193
- test: tasks(testScenarios)
5194
- };
5195
- const developmentUnits = new Set([...splits.train, ...splits.selection].map((task) => task.unitId));
5196
- const execution = {
5197
- model: prepared.searchIdentity.model,
5198
- agent: prepared.searchIdentity.agent,
5199
- benchmark: {
5200
- uri: "agent-runtime:improve-splits",
5201
- revision: canonicalCandidateDigest$1({
5202
- development: prepared.identity.developmentSplitDigest,
5203
- test: prepared.identity.finalTestSplitDigest
5204
- })
5205
- }
5206
- };
5207
- const reservedClaimUsd = Math.max(method.claimReserveUsd ?? 0, searchClaimReserveUsd({
5208
- testTasks: splits.test.length,
5209
- reps,
5210
- cellUsd: Math.max(...lanes.map((lane) => lane.cellUsd))
5211
- }));
5212
- const recorder = await SearchRecorder.open({
5213
- ledger: storage.kind === "filesystem" ? openSearchLedger({
5214
- path: `${searchDir}/ledger.jsonl`,
5215
- searchId
5216
- }) : openSearchLedger({
5217
- path: `${searchDir}/ledger.jsonl`,
5218
- searchId,
5219
- store: storage
5220
- }),
5221
- storage
5222
- }, {
5223
- subject: prepared.searchIdentity.subject,
5224
- process: {
5225
- name: method.name,
5226
- executionRef: SEARCH_METHOD_SOURCE
5227
- },
5228
- artifactKind: "agent-profile",
5229
- objective: {
5230
- metric: "composite",
5231
- direction: "maximize",
5232
- judge: prepared.searchIdentity.judge,
5233
- claim
5234
- },
5235
- splits: {
5236
- ...splits,
5237
- heldOutUnits: splits.test.every((task) => !developmentUnits.has(task.unitId))
5238
- },
5239
- policy: {
5240
- expansion: policy.name,
5241
- allocation: allocation.name,
5242
- seed
5243
- },
5244
- budget: {
5245
- maxUsd: costCeiling ?? null,
5246
- maxCells: null,
5247
- maxNodes: 1 + method.maxExpansions * method.childrenPerProposal,
5248
- deadline: method.deadline,
5249
- maxConcurrency: concurrency,
5250
- reservedClaimUsd: costCeiling === void 0 ? 0 : reservedClaimUsd
5251
- },
5252
- containment: null,
5253
- derivedFrom: null,
5254
- identity: execution
5255
- });
5256
- const nodeOf = (candidateSurface) => {
5257
- const surface = immutableCandidateValue(candidateSurface);
5258
- try {
5259
- return {
5260
- surface,
5261
- profile: prepared.materializeCandidate(surface),
5262
- refusal: null
5263
- };
5264
- } catch (error) {
5265
- return {
5266
- surface,
5267
- profile: null,
5268
- refusal: refusalText(error)
5269
- };
5270
- }
5271
- };
5272
- const profiles = /* @__PURE__ */ new Map();
5273
- const profiled = profileCodec(prepared);
5274
- const codec = {
5275
- node(recorder, node) {
5276
- const registered = profiled.node(recorder, node);
5277
- profiles.set(searchNodeId(searchId, registered.artifactDigest), node.profile);
5278
- return registered;
5279
- },
5280
- diff: profiled.diff,
5281
- load(recorder, node) {
5282
- const loaded = profiled.load(recorder, node);
5283
- profiles.set(node.nodeId, loaded.profile);
5284
- return loaded;
5285
- }
5286
- };
5287
- for (const node of (await recorder.state()).nodes()) codec.load(recorder, node);
5288
- await reconcileInterruptedSearchCalls(costLedger, searchId, lanes);
5289
- const laneRefusal = (nodeProfile) => {
5290
- const refusals = lanes.map((lane) => `${lane.name}: ${lane.refusal(nodeProfile)}`);
5291
- return lanes.some((lane) => lane.refusal(nodeProfile) === void 0) ? null : `no lane can run the profile (${refusals.join("; ")})`;
5292
- };
5293
- const root = nodeOf(prepared.baselineSurface);
5294
- if (root.profile) {
5295
- const refused = laneRefusal(root.profile);
5296
- if (refused) throw new ConfigError(`improve(): the baseline profile cannot run: ${refused}`);
5297
- }
5298
- const scenarios = [
5299
- ...trainScenarios,
5300
- ...selectionScenarios,
5301
- ...testScenarios
5302
- ];
5303
- const scenarioIds = /* @__PURE__ */ new Set();
5304
- for (const scenario of scenarios) {
5305
- if (scenarioIds.has(scenario.id)) throw new ConfigError(`improve(): scenario '${scenario.id}' appears in more than one split`);
5306
- scenarioIds.add(scenario.id);
5307
- }
5308
- const executor = searchExecutor({
5309
- lanes,
5310
- profileOf(nodeId) {
5311
- const known = profiles.get(nodeId);
5312
- if (known === void 0) throw new Error(`improve(): node ${nodeId} was placed unregistered`);
5313
- return known;
5314
- },
5315
- costLedger,
5316
- identity: execution,
5317
- storage,
5318
- dir: searchDir,
5319
- ...workerSlots ? { workerSlots } : {},
5320
- ...budgetPool ? { budgetPool } : {},
5321
- ...trace ? { trace } : {},
5322
- async runAttempt({ work, lane, context, costLedger: cellLedger, span }) {
5323
- const nodeProfile = work.artifact.profile;
5324
- if (!nodeProfile) throw new Error(`improve(): refused node ${work.nodeId} was given a cell`);
5325
- const profileDigest = canonicalAgentProfileDigest(nodeProfile);
5326
- let fault;
5327
- const cell = (await runCampaign({
5328
- ...campaignOptions,
5329
- ...lane.kind === "subscription" && campaignOptions.expectUsage === void 0 ? { expectUsage: "off" } : {},
5330
- scenarios,
5331
- judges: prepared.judges.map((judge) => ({
5332
- ...judge,
5333
- async score(input) {
5334
- try {
5335
- return await judge.score(input);
5336
- } catch (error) {
5337
- if (isSearchEnvironmentFault(error)) fault = error;
5338
- throw error;
5339
- }
5340
- }
5341
- })),
5342
- seed,
5343
- reps,
5344
- storage,
5345
- runDir: `${searchDir}/nodes/${profileDigest.slice(7)}`,
5346
- dispatchRef: `improve:${evaluationRef}:${profileDigest}`,
5347
- async dispatch(scenario, ctx) {
5348
- try {
5349
- return await agent(nodeProfile, scenario, {
5350
- ...ctx,
5351
- search: context
5352
- });
5353
- } catch (error) {
5354
- if (isSearchEnvironmentFault(error)) fault = error;
5355
- throw error;
5356
- }
5357
- },
5358
- cellFilter: ({ scenario, rep }) => scenario.id === work.taskId && rep === work.rep,
5359
- resumable: true,
5360
- maxConcurrency: 1,
5361
- costLedger: cellLedger,
5362
- costPhase: `search.${work.stage}`,
5363
- buildTraceWriter: () => ({
5364
- span,
5365
- flush: async () => {}
5366
- }),
5367
- signal: work.signal
5368
- })).cells[0];
5369
- if (!cell) throw new Error(`improve(): cell ${work.cellId} produced no campaign cell`);
5370
- const result = campaignCellSearchResult(cell, {
5371
- execution,
5372
- lane: lane.name
5373
- });
5374
- const execRunId = cell.error ? null : executionRunId?.(cell.artifact) ?? null;
5375
- const settled = faultResult(execRunId && context.trace ? {
5376
- ...result,
5377
- traceRef: {
5378
- traceId: context.trace.traceId,
5379
- execRunId,
5380
- spansWritten: null,
5381
- spansDropped: null
5382
- }
5383
- } : result, fault);
5384
- return recordCell && settled.outcome.status !== "errored" ? {
5385
- ...settled,
5386
- recordCell: (finalResult) => recordCell({
5387
- cell,
5388
- search: context,
5389
- result: finalResult
5390
- })
5391
- } : settled;
5392
- }
5393
- });
5394
- const { proposer } = method;
5395
- const proposerSource = {
5396
- uri: `proposer:${proposer.kind}`,
5397
- revision: canonicalCandidateDigest$1({
5398
- kind: proposer.kind,
5399
- propose: Function.prototype.toString.call(proposer.propose),
5400
- decide: proposer.decide ? Function.prototype.toString.call(proposer.decide) : null
5401
- })
5402
- };
5403
- const proposalPhase = "search.proposal";
5404
- const port = {
5405
- name: proposer.kind,
5406
- kind: "optimizer",
5407
- source: proposerSource,
5408
- execution: {
5409
- kind: "deterministic",
5410
- source: proposerSource
5411
- },
5412
- childrenPerProposal: method.childrenPerProposal,
5413
- async propose(request) {
5414
- const tags = searchCallTags(searchId, { operation: request.operationId });
5415
- const state = await recorder.state();
5416
- const parents = request.parents.map(({ nodeId, artifact }) => ({
5417
- nodeId,
5418
- artifact: artifact.surface
5419
- }));
5420
- const context = Object.freeze({
5421
- currentSurface: parents[0]?.artifact ?? prepared.baselineSurface,
5422
- operator: request.operator,
5423
- parents,
5424
- train: searchProposerView(state),
5425
- summary: renderSearchSummary(state, { split: "train" }),
5426
- history: [],
5427
- findings: prepared.findings,
5428
- populationSize: method.childrenPerProposal,
5429
- generation: request.expansion,
5430
- signal: request.signal,
5431
- costLedger: taggedLedger(costLedger, tags),
5432
- costPhase: proposalPhase
5433
- });
5434
- const decision = proposer.decide?.({ history: [] });
5435
- const proposed = decision?.stop ? [] : await proposer.propose(context);
5436
- if (!Array.isArray(proposed)) throw new ConfigError("improve(): the search proposer must return an array");
5437
- const fresh = costLedger.list({
5438
- phase: proposalPhase,
5439
- tags
5440
- });
5441
- return {
5442
- children: proposed.slice(0, method.childrenPerProposal).map((child) => isProposedCandidate(child) ? {
5443
- artifact: nodeOf(child.surface),
5444
- label: child.label,
5445
- rationale: child.rationale,
5446
- ...child.attribution ? { attribution: child.attribution } : {}
5447
- } : {
5448
- artifact: nodeOf(child),
5449
- label: "",
5450
- rationale: ""
5451
- }),
5452
- ...decision?.stop ? { stop: decision.reason ?? "the proposer decided to stop" } : {},
5453
- accounting: searchReceiptAccounting(fresh),
5454
- execution: searchProposalExecution(fresh, prepared.searchIdentity.model.provider, proposerSource)
5455
- };
5456
- }
5457
- };
5458
- const admit = (node) => {
5459
- if (node.refusal !== null || node.profile === null) return node.refusal;
5460
- try {
5461
- prepared.admitCandidate(node.profile, node.surface);
5462
- } catch (error) {
5463
- return refusalText(error);
5464
- }
5465
- const paths = privateValuePaths([node.surface]);
5466
- if (paths.length > 0) return `the surface carries a credential or private value at ${paths.slice(0, 8).join(", ")}`;
5467
- return laneRefusal(node.profile);
5468
- };
5469
- const startedAt = Date.now();
5470
- const result = await runSearch({
5471
- recorder,
5472
- root,
5473
- codec,
5474
- policy,
5475
- allocation,
5476
- proposer: port,
5477
- executor,
5478
- admit,
5479
- maxExpansions: method.maxExpansions,
5480
- maxAttempts: method.maxAttempts,
5481
- ...signal ? { signal } : {}
5482
- });
5483
- const { state } = result;
5484
- const claimResult = result.claim;
5485
- if (!claimResult || !result.claimVerification) throw new Error(`improve(): search ${searchId} closed without a claim`);
5486
- const kept = codec.load(recorder, state.node(result.leader));
5487
- if (!kept.profile) throw new Error(`improve(): search ${searchId} kept a refused node`);
5488
- const candidate = Object.freeze({
5489
- surface: prepared.surface,
5490
- value: kept.surface,
5491
- profile: kept.profile
5492
- });
5493
- const cost = copyImproveCost(costLedger.summary());
5494
- const shipped = claimResult.finalists.find((finalist) => finalist.nodeId === claimResult.selected && finalist.test !== null);
5495
- const { decision, reason } = runtimeShipDecision({
5496
- claim: claimResult,
5497
- verified: result.claimVerification.status === "verified",
5498
- accountingComplete: cost.accountingComplete,
5499
- lowerBound: shipped?.test?.interval[0] ?? null,
5500
- minimumLift: prepared.minimumLift
5501
- });
5502
- return {
5503
- mode: "search",
5504
- method: method.name,
5505
- candidate,
5506
- decision,
5507
- reason,
5508
- claim: claimResult,
5509
- claimVerification: result.claimVerification,
5510
- ...shipped?.test ? {
5511
- lift: shipped.test.delta,
5512
- liftInterval: {
5513
- low: shipped.test.interval[0],
5514
- high: shipped.test.interval[1]
5515
- }
5516
- } : {},
5517
- searchHistory: recorder.receipt({
5518
- producerId: method.name,
5519
- runId: searchId
5520
- }),
5521
- cost,
5522
- durationMs: Date.now() - startedAt,
5523
- lineage: Object.freeze({
5524
- invocationId: prepared.invocationId,
5525
- runId: searchId,
5526
- developmentSplitDigest: prepared.identity.developmentSplitDigest,
5527
- finalTestSplitDigest: prepared.identity.finalTestSplitDigest,
5528
- scenarioPartitions: prepared.identity.scenarioPartitions,
5529
- executionRef: prepared.executionRef,
5530
- baselineProfileDigest: prepared.baselineProfileDigest
5531
- }),
5532
- async dispose() {}
5533
- };
5534
- }
5535
- /** Runtime's ship rule over the kernel's statistical claim (design §6.5 step 5), shared by
5536
- * `searchMethod` and `runStrategyEvolution`. */
5537
- function runtimeShipDecision(input) {
5538
- const { claim } = input;
5539
- if (claim.decision !== "ship") return {
5540
- decision: "hold",
5541
- reason: claim.reason
5542
- };
5543
- if (!input.verified) return {
5544
- decision: "hold",
5545
- reason: "the claim shipped, but it does not re-derive from the ledger under this rule revision"
5546
- };
5547
- if (!input.accountingComplete) return {
5548
- decision: "hold",
5549
- reason: "the claim shipped, but the search cost accounting is incomplete"
5550
- };
5551
- if (input.lowerBound === null || !(input.lowerBound > input.minimumLift)) return {
5552
- decision: "hold",
5553
- reason: `the claim shipped, but its test lower bound ${input.lowerBound} does not exceed minimumLift ${input.minimumLift}`
5554
- };
5555
- return {
5556
- decision: "ship",
5557
- reason: claim.reason
5558
- };
5559
- }
5560
- /** Profiles as search artifacts: nodes by profile digest, edges by profile diffs. */
5561
- function profileCodec(prepared) {
5562
- const surfaceId = prepared.surface;
5563
- return {
5564
- node(recorder, node) {
5565
- if (node.profile) {
5566
- const artifact = recorder.blob("agent-profile", {
5567
- kind: "agent-profile",
5568
- profile: node.profile
5569
- });
5570
- return {
5571
- artifactDigest: canonicalAgentProfileDigest(node.profile),
5572
- artifact,
5573
- surfaces: [{
5574
- surfaceId,
5575
- kind: "agent-profile",
5576
- artifact
5577
- }]
5578
- };
5579
- }
5580
- const artifact = recorder.blob("surface", {
5581
- kind: "unmaterialized-surface",
5582
- surface: node.surface,
5583
- refusal: node.refusal
5584
- });
5585
- return {
5586
- artifactDigest: canonicalCandidateDigest$1({
5587
- kind: "unmaterialized-surface",
5588
- surface: node.surface
5589
- }),
5590
- artifact,
5591
- surfaces: [{
5592
- surfaceId,
5593
- kind: "agent-profile",
5594
- artifact
5595
- }]
5596
- };
5597
- },
5598
- diff(recorder, parent, child) {
5599
- if (!parent.profile || !child.profile) return { unknown: "a surface that does not materialize has no profile to diff" };
5600
- const diffs = diffAgentProfiles(parent.profile, child.profile);
5601
- const to = canonicalAgentProfileDigest(child.profile);
5602
- if (canonicalAgentProfileDigest(diffs.reduce(applyAgentProfileDiff, parent.profile)) !== to) return { unknown: "the Interface profile diffs do not reproduce the child profile" };
5603
- return recorder.blob("diff", {
5604
- kind: "agent-profile-diff",
5605
- from: canonicalAgentProfileDigest(parent.profile),
5606
- to,
5607
- diffs
5608
- });
5609
- },
5610
- load(recorder, node) {
5611
- const stored = recorder.readBlob(node.artifact);
5612
- if (stored.kind === "agent-profile") {
5613
- const parsed = agentProfileSchema.safeParse(stored.profile);
5614
- if (!parsed.success) throw new Error(`improve(): node ${node.nodeId} holds an invalid AgentProfile`);
5615
- const loaded = immutableCandidateValue(parsed.data);
5616
- return {
5617
- surface: prepared.surfaceOf(loaded),
5618
- profile: loaded,
5619
- refusal: null
5620
- };
5621
- }
5622
- if (stored.kind === "unmaterialized-surface" && stored.surface !== void 0) return {
5623
- surface: stored.surface,
5624
- profile: null,
5625
- refusal: stored.refusal ?? null
5626
- };
5627
- throw new Error(`improve(): node ${node.nodeId} holds no profile search artifact`);
5628
- }
5629
- };
5630
- }
5631
- /** Everything that decides which search a call continues. */
5632
- function searchMethodDescriptor(method) {
5633
- return {
5634
- name: method.name,
5635
- policy: method.policy.name,
5636
- allocation: method.allocation.name,
5637
- reps: method.allocation.reps,
5638
- proposer: method.proposer.kind,
5639
- maxExpansions: method.maxExpansions,
5640
- childrenPerProposal: method.childrenPerProposal,
5641
- lanes: method.lanes.map(({ name, kind, capacity, costCap, cellUsd }) => ({
5642
- name,
5643
- kind,
5644
- capacity,
5645
- costCap,
5646
- cellUsd
5647
- })),
5648
- claimReserveUsd: method.claimReserveUsd,
5649
- deadline: method.deadline,
5650
- maxAttempts: method.maxAttempts
5651
- };
5652
- }
5653
- /**
5654
- * An environment fault the agent raised settles retryable. The campaign reports every error as
5655
- * final because it applies its own retry policy; here the kernel owns retries.
5656
- */
5657
- function faultResult(result, fault) {
5658
- if (fault === void 0 || result.outcome.status !== "errored") return result;
5659
- return {
5660
- ...result,
5661
- outcome: {
5662
- ...result.outcome,
5663
- error: {
5664
- code: "environment-fault",
5665
- message: refusalText(fault),
5666
- retryable: true
5667
- }
5668
- }
5669
- };
5670
- }
5671
- /** A refusal as the ledger stores it: redacted with the share profile. */
5672
- function refusalText(error) {
5673
- return redact(error instanceof Error ? error.message : String(error), { profile: "share" }).value;
5674
- }
5675
- //#endregion
5676
- export { sampleThenRefine as $, parseRolloutPolicy as A, officialChecksFromMeta as B, privateValuePaths as C, ROLLOUT_POLICY_EXTENSION as D, isCodeSurface as E, composeCheckSources as F, visibleCheckScore as G, sandboxCheckRunner as H, defaultExtractCandidate as I, defineStrategy as J, adaptiveRefine as K, defaultStructuralRolloutPolicy as L, structuralRolloutPolicyFromProfile as M, canDisplace as N, applyRolloutPolicyToProfile as O, compareCheckOutcomes as P, sample as Q, filterAuthoredAsserts as R, parseExecutionRef as S, assertCandidateSurfaceKind as T, selectBestIndex as U, resolveEntrySymbol as V, structuralRollout as W, refine as X, depthStrategy as Y, runAgentic as Z, sharedBoxRefusal as _, startOrResumeRuntimeSession as _t, SearchEnvironmentFault as a, profileOptimizerModelCall as at, assertCandidateValidator as b, reconcileInterruptedSearchCalls as c, strategyAuthorMethod as ct, sharedBoxLane as d, createIterableBackend as dt, ObservationError as et, subscriptionLane as f, createSandboxPromptBackend as ft, sharedBoxPlacement as g, nowIso as gt, ROUTER_CLIENT_HEADER as h, newRuntimeSession as ht, searchMethod as i, profileChatClient as it, serializeRolloutPolicy as j, normalizeRolloutPolicy as k, routerLane as l, collectAgentTurn as lt, DEFAULT_SHARED_BOX_WORKERS as m, InMemoryRuntimeSessionStore as mt, runSearchImprovement as n, observe as nt, dedicatedLane as o, copyImproveCost as ot, DEFAULT_SHARED_BOX_RESOURCES as p, normalizeBackendStreamEvent as pt, breadthStrategy as q, runtimeShipDecision as r, renderReport as rt, isSearchEnvironmentFault as s, optimizerMethod as st, isImproveSearchMethod as t, defaultAnalystInstruction as tt, searchExecutor as u, streamAgentTurn as ut, sharedWorkerClientName as v, touchSession as vt, validateProfileCandidate as w, assertProfileTrainingIsHeldOut as x, prepareProfileImprovement as y, modelAuthoredChecks as z };
4783
+ export { createIterableBackend as $, resolveEntrySymbol as A, runAgentic as B, compareCheckOutcomes as C, filterAuthoredAsserts as D, defaultStructuralRolloutPolicy as E, adaptiveRefine as F, observe as G, sampleThenRefine as H, breadthStrategy as I, profileOptimizerModelCall as J, renderReport as K, defineStrategy as L, selectBestIndex as M, structuralRollout as N, modelAuthoredChecks as O, visibleCheckScore as P, streamAgentTurn as Q, depthStrategy as R, canDisplace as S, defaultExtractCandidate as T, ObservationError as U, sample as V, defaultAnalystInstruction as W, strategyAuthorMethod as X, optimizerMethod as Y, collectAgentTurn as Z, sharedWorkerClientName as _, reconcileInterruptedSearchCalls as a, startOrResumeRuntimeSession as at, improveSearchCost as b, searchExecutor as c, taggedLedger as d, createSandboxPromptBackend as et, DEFAULT_SHARED_BOX_RESOURCES as f, sharedBoxRefusal as g, sharedBoxPlacement as h, isSearchEnvironmentFault as i, nowIso as it, sandboxCheckRunner as j, officialChecksFromMeta as k, sharedBoxLane as l, ROUTER_CLIENT_HEADER as m, assertSearchLanes as n, InMemoryRuntimeSessionStore as nt, routerLane as o, touchSession as ot, DEFAULT_SHARED_BOX_WORKERS as p, profileChatClient as q, dedicatedLane as r, newRuntimeSession as rt, searchCallTags as s, SearchEnvironmentFault as t, normalizeBackendStreamEvent as tt, subscriptionLane as u, decideClosedSearch as v, composeCheckSources as w, runtimeShipDecision as x, decideSearchImprovement as y, refine as z };
5677
4784
 
5678
- //# sourceMappingURL=search-method-DvU-fc-f.js.map
4785
+ //# sourceMappingURL=search-executor-2tWr38Qw.js.map