@tangle-network/agent-eval 0.197.0 → 0.198.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +45 -0
- package/dist/active-curriculum-B_Lc9kfO.js +61 -0
- package/dist/active-curriculum-B_Lc9kfO.js.map +1 -0
- package/dist/adapters/http.d.ts +2 -2
- package/dist/analyst/index.d.ts +5 -5
- package/dist/analyst/index.js +3 -3
- package/dist/{analyze-runs-B6gv7vAT.js → analyze-runs-DFbp2gB8.js} +5 -5
- package/dist/{analyze-runs-B6gv7vAT.js.map → analyze-runs-DFbp2gB8.js.map} +1 -1
- package/dist/{benchmark-command-DB7pxlks.js → benchmark-command-D8E5TaPC.js} +6 -5
- package/dist/{benchmark-command-DB7pxlks.js.map → benchmark-command-D8E5TaPC.js.map} +1 -1
- package/dist/benchmarks/index.d.ts +4 -3
- package/dist/benchmarks/index.d.ts.map +1 -1
- package/dist/benchmarks/index.js +3 -3
- package/dist/campaign/index.d.ts +5 -4
- package/dist/campaign/index.js +13 -11
- package/dist/{campaign-BUFSOI36.js → campaign-Dlg2iOzH.js} +13 -12
- package/dist/{campaign-BUFSOI36.js.map → campaign-Dlg2iOzH.js.map} +1 -1
- package/dist/{campaign-evidence-DJc60F9C.js → campaign-evidence-jL_U7Ikv.js} +2 -2
- package/dist/{campaign-evidence-DJc60F9C.js.map → campaign-evidence-jL_U7Ikv.js.map} +1 -1
- package/dist/cli.js +243 -13
- package/dist/cli.js.map +1 -1
- package/dist/contract/index.d.ts +7 -6
- package/dist/contract/index.js +9 -9
- package/dist/{default-registry-D2csUBBQ.d.ts → default-registry-oK9hHfX_.d.ts} +3 -3
- package/dist/{default-registry-D2csUBBQ.d.ts.map → default-registry-oK9hHfX_.d.ts.map} +1 -1
- package/dist/{define-agent-eval-ulRlLvse.d.ts → define-agent-eval-By9PImpa.d.ts} +5 -4
- package/dist/define-agent-eval-By9PImpa.d.ts.map +1 -0
- package/dist/{define-agent-eval-4J02MdF7.js → define-agent-eval-DvBgSzAI.js} +6 -6
- package/dist/{define-agent-eval-4J02MdF7.js.map → define-agent-eval-DvBgSzAI.js.map} +1 -1
- package/dist/diagnosis/index.js +1 -1
- package/dist/{dspy-rlm-engine-k_QdEBZo.js → dspy-rlm-engine-B5T43BkZ.js} +2 -2
- package/dist/{dspy-rlm-engine-k_QdEBZo.js.map → dspy-rlm-engine-B5T43BkZ.js.map} +1 -1
- package/dist/{engine-De2hfuiQ.d.ts → engine-Dc996kAg.d.ts} +2 -2
- package/dist/{engine-De2hfuiQ.d.ts.map → engine-Dc996kAg.d.ts.map} +1 -1
- package/dist/{eval-campaign-CXT2WYUe.js → eval-campaign-GapmPHIA.js} +2 -2
- package/dist/{eval-campaign-CXT2WYUe.js.map → eval-campaign-GapmPHIA.js.map} +1 -1
- package/dist/evaluation.d.ts +1 -1
- package/dist/experiment/index.d.ts +1 -1
- package/dist/experiment/index.js +8 -6
- package/dist/experiment/index.js.map +1 -1
- package/dist/{external-optimizer-process-_YIECYJ7.js → external-optimizer-process-CEXcCKqd.js} +2 -2
- package/dist/{external-optimizer-process-_YIECYJ7.js.map → external-optimizer-process-CEXcCKqd.js.map} +1 -1
- package/dist/{external-optimizer-subprocess-BrghTvEp.js → external-optimizer-subprocess-laM1-UDV.js} +2 -61
- package/dist/external-optimizer-subprocess-laM1-UDV.js.map +1 -0
- package/dist/fuzz.d.ts.map +1 -1
- package/dist/fuzz.js +2 -3
- package/dist/fuzz.js.map +1 -1
- package/dist/hosted/index.js +1 -1
- package/dist/{index-DJKZEldg.d.ts → index-BhoOCduB.d.ts} +12 -947
- package/dist/index-BhoOCduB.d.ts.map +1 -0
- package/dist/{index-CRsmcAGl.d.ts → index-D-tI1vgf.d.ts} +6 -6
- package/dist/{index-CRsmcAGl.d.ts.map → index-D-tI1vgf.d.ts.map} +1 -1
- package/dist/{index-kKECJfib.d.ts → index-lbwvO9vJ.d.ts} +3 -3
- package/dist/{index-kKECJfib.d.ts.map → index-lbwvO9vJ.d.ts.map} +1 -1
- package/dist/index.d.ts +9 -9
- package/dist/index.js +15 -13
- package/dist/index.js.map +1 -1
- package/dist/jev.d.ts +1 -1
- package/dist/{llm-judge-fhkFQL1N.js → llm-judge-BYWXsxhZ.js} +415 -1981
- package/dist/llm-judge-BYWXsxhZ.js.map +1 -0
- package/dist/{matrix-C1X-fIVX.d.ts → matrix-BnksRaDD.d.ts} +2 -2
- package/dist/{matrix-C1X-fIVX.d.ts.map → matrix-BnksRaDD.d.ts.map} +1 -1
- package/dist/multiplicity-D9cjmStq.js +101 -0
- package/dist/multiplicity-D9cjmStq.js.map +1 -0
- package/dist/multishot/golden/index.d.ts +1 -1
- package/dist/multishot/golden/index.js +1 -1
- package/dist/multishot/index.d.ts +2 -2
- package/dist/multishot/index.js +1 -1
- package/dist/openapi.json +1 -1
- package/dist/{paired-arms-JSDcs2zx.js → paired-arms-DKZFVPt8.js} +4 -398
- package/dist/paired-arms-DKZFVPt8.js.map +1 -0
- package/dist/paired-binary-fzkwENI4.js +399 -0
- package/dist/paired-binary-fzkwENI4.js.map +1 -0
- package/dist/{paired-promotion-decision-DTKl6-G8.js → paired-promotion-decision-D5B1Cxc2.js} +78 -5
- package/dist/paired-promotion-decision-D5B1Cxc2.js.map +1 -0
- package/dist/{power-and-mde-BJOpt6pq.js → power-and-mde-K_CmO3dc.js} +3 -101
- package/dist/power-and-mde-K_CmO3dc.js.map +1 -0
- package/dist/{produced-state-1RnbLrSa.js → produced-state-DOfmCEwP.js} +3 -3
- package/dist/{produced-state-1RnbLrSa.js.map → produced-state-DOfmCEwP.js.map} +1 -1
- package/dist/{promotion-policy-Cy5OV8BV.js → promotion-policy-C6FAJvmZ.js} +3 -3
- package/dist/{promotion-policy-Cy5OV8BV.js.map → promotion-policy-C6FAJvmZ.js.map} +1 -1
- package/dist/reporting.js +3 -3
- package/dist/rl.d.ts +17 -39
- package/dist/rl.d.ts.map +1 -1
- package/dist/rl.js +5 -5
- package/dist/search/index.d.ts +1162 -0
- package/dist/search/index.d.ts.map +1 -0
- package/dist/search/index.js +187 -0
- package/dist/search/index.js.map +1 -0
- package/dist/search-kernel-CuvbakC_.d.ts +1176 -0
- package/dist/search-kernel-CuvbakC_.d.ts.map +1 -0
- package/dist/search-kernel-D8_kxChy.js +2399 -0
- package/dist/search-kernel-D8_kxChy.js.map +1 -0
- package/dist/{search-ledger-9W0g5FP6.js → search-ledger-BnUytR8X.js} +3 -1
- package/dist/search-ledger-BnUytR8X.js.map +1 -0
- package/dist/{search-shipper-CYbmJQx8.js → search-shipper-Cn8cxcyp.js} +2 -2
- package/dist/{search-shipper-CYbmJQx8.js.map → search-shipper-Cn8cxcyp.js.map} +1 -1
- package/dist/search-summary-Dmppg8kV.js +133 -0
- package/dist/search-summary-Dmppg8kV.js.map +1 -0
- package/dist/{semantic-concept-judge-Bh5lvKGg.js → semantic-concept-judge-2SE_kXGF.js} +2 -2
- package/dist/{semantic-concept-judge-Bh5lvKGg.js.map → semantic-concept-judge-2SE_kXGF.js.map} +1 -1
- package/dist/{sequential-C21_PP7F.js → sequential-Yz3OSskl.js} +2 -2
- package/dist/{sequential-C21_PP7F.js.map → sequential-Yz3OSskl.js.map} +1 -1
- package/dist/single-run-lock-fVu3MZWH.js +62 -0
- package/dist/single-run-lock-fVu3MZWH.js.map +1 -0
- package/dist/{skillopt-optimization-method-CHUcZ8w6.js → skillopt-optimization-method-BMP2qV_1.js} +8 -7
- package/dist/{skillopt-optimization-method-CHUcZ8w6.js.map → skillopt-optimization-method-BMP2qV_1.js.map} +1 -1
- package/dist/{statistical-heldout-DANVmyug.js → statistical-heldout-BAFDCo07.js} +2 -2
- package/dist/{statistical-heldout-DANVmyug.js.map → statistical-heldout-BAFDCo07.js.map} +1 -1
- package/dist/{statistical-heldout-BedVSZb2.d.ts → statistical-heldout-CMpxMjlQ.d.ts} +2 -2
- package/dist/{statistical-heldout-BedVSZb2.d.ts.map → statistical-heldout-CMpxMjlQ.d.ts.map} +1 -1
- package/dist/{store-tool-spans-CawP-WxM.d.ts → store-tool-spans-CUwWSXoj.d.ts} +3 -3
- package/dist/{store-tool-spans-CawP-WxM.d.ts.map → store-tool-spans-CUwWSXoj.d.ts.map} +1 -1
- package/dist/{summary-report-BMvou2oZ.js → summary-report-BeYnvddy.js} +4 -3
- package/dist/{summary-report-BMvou2oZ.js.map → summary-report-BeYnvddy.js.map} +1 -1
- package/dist/{tool-groups-B4JVrH3g.d.ts → tool-groups-DVJAR1GE.d.ts} +2 -2
- package/dist/tool-groups-DVJAR1GE.d.ts.map +1 -0
- package/dist/trace-repair/index.d.ts +1 -1
- package/dist/traces.d.ts +2 -2
- package/dist/tree-DHHWsH-X.js +4045 -0
- package/dist/tree-DHHWsH-X.js.map +1 -0
- package/dist/{types-B3jzCp0p.js → types-B3jzCp0p2.js} +1 -1
- package/dist/types-B3jzCp0p2.js.map +1 -0
- package/dist/{types-CjFDKMDe.d.ts → types-D94EanDL.d.ts} +2 -2
- package/dist/{types-CjFDKMDe.d.ts.map → types-D94EanDL.d.ts.map} +1 -1
- package/dist/{types-B2673PBj.d.ts → types-EBUav9Bu.d.ts} +8 -4
- package/dist/types-EBUav9Bu.d.ts.map +1 -0
- package/docs/campaign-proposers.md +2 -0
- package/docs/design/statistics-decisions.md +1 -1
- package/docs/search-ledger.md +143 -8
- package/package.json +6 -1
- package/dist/active-curriculum-OjIWgrUJ.js +0 -204
- package/dist/active-curriculum-OjIWgrUJ.js.map +0 -1
- package/dist/define-agent-eval-ulRlLvse.d.ts.map +0 -1
- package/dist/external-optimizer-subprocess-BrghTvEp.js.map +0 -1
- package/dist/index-DJKZEldg.d.ts.map +0 -1
- package/dist/llm-judge-fhkFQL1N.js.map +0 -1
- package/dist/paired-arms-JSDcs2zx.js.map +0 -1
- package/dist/paired-delta-test-BF-FEP8V.js +0 -78
- package/dist/paired-delta-test-BF-FEP8V.js.map +0 -1
- package/dist/paired-promotion-decision-DTKl6-G8.js.map +0 -1
- package/dist/power-and-mde-BJOpt6pq.js.map +0 -1
- package/dist/search-ledger-9W0g5FP6.js.map +0 -1
- package/dist/search-summary-CcavvYLe.js +0 -378
- package/dist/search-summary-CcavvYLe.js.map +0 -1
- package/dist/tool-groups-B4JVrH3g.d.ts.map +0 -1
- package/dist/types-B2673PBj.d.ts.map +0 -1
- package/dist/types-B3jzCp0p.js.map +0 -1
|
@@ -0,0 +1,1176 @@
|
|
|
1
|
+
import { o as CostLedger } from "./cost-ledger-DbQdN3nO.js";
|
|
2
|
+
import { a as RunRecord } from "./run-record-DF-fuu31.js";
|
|
3
|
+
import { A as SearchLedgerHash, C as SearchEdgeOperator, E as SearchExecutionIdentity, G as SearchSplit, H as SearchProposerKind, I as SearchNodeStatus, L as SearchOpenedEvent, N as SearchNodeDecision, O as SearchLedgerEntry, P as SearchNodeRef, Q as SearchTaskOutcome, R as SearchOperationKind, S as SearchEdgeAttribution, U as SearchReservation, V as SearchProposer, W as SearchSourceRef, Y as SearchSurfaceEvidence, Z as SearchTask, _ as SearchClaimPower, a as SearchAttemptAccounting, et as SearchTraceRef, i as SearchArtifactRef, j as SearchModelIdentity, k as SearchLedgerEvent, l as SearchCandidateSurface, m as SearchClaim, nt as EvaluationClaim, o as SearchAudit, p as SearchCellStage, t as NodeEstimate, tt as SearchUnknown, y as SearchCloseReason, z as SearchOperationRecordedEvent } from "./search-ledger-types-p2xKfiDJ.js";
|
|
4
|
+
import { b as LedgerTrustedHeadRemoval, f as LedgerLineContext, h as LedgerTextStore, y as LedgerTrustedHead } from "./index-Bj96W0jZ.js";
|
|
5
|
+
import { $ as SearchNode, at as SearchUnitScore, it as SearchStateView, j as MutableSurface, tt as SearchScoredCell } from "./types-EBUav9Bu.js";
|
|
6
|
+
//#region src/campaign/storage.d.ts
|
|
7
|
+
/**
|
|
8
|
+
* `CampaignStorage` — the filesystem seam `runCampaign` writes through
|
|
9
|
+
* (run/cell dirs, the resumability cache, per-cell artifacts, trace spans).
|
|
10
|
+
*
|
|
11
|
+
* The default (`fsCampaignStorage`) is the Node filesystem — identical
|
|
12
|
+
* behavior to the inline `node:fs` calls it replaces, so existing CLI
|
|
13
|
+
* consumers are unaffected. `inMemoryCampaignStorage` keeps everything in a
|
|
14
|
+
* `Map`, so the substrate runs in environments WITHOUT a filesystem
|
|
15
|
+
* (Cloudflare Workers, Deno Deploy, other edge runtimes) — the campaign
|
|
16
|
+
* still produces its `CampaignResult` (cells + aggregates) in memory;
|
|
17
|
+
* artifacts/traces simply aren't persisted to disk.
|
|
18
|
+
*
|
|
19
|
+
* Paths are opaque keys to the in-memory adapter — it does not parse them,
|
|
20
|
+
* so the same `join(...)`-built paths work unchanged across both adapters.
|
|
21
|
+
*/
|
|
22
|
+
interface CampaignStorage {
|
|
23
|
+
/** `filesystem` for the Node filesystem, whose paths durable journals such
|
|
24
|
+
* as the search ledger may open directly; any other storage keeps those
|
|
25
|
+
* journals in itself. */
|
|
26
|
+
readonly kind?: 'filesystem' | 'memory';
|
|
27
|
+
/** Ensure a directory exists (recursive). No-op for in-memory. */
|
|
28
|
+
ensureDir(dir: string): void;
|
|
29
|
+
/** Does this path exist (as a written file or an ensured dir)? */
|
|
30
|
+
exists(path: string): boolean;
|
|
31
|
+
/** Read a UTF-8 file; `undefined` when missing or unreadable. */
|
|
32
|
+
read(path: string): string | undefined;
|
|
33
|
+
/** Write a file (string or bytes). Parent dir is assumed ensured. */
|
|
34
|
+
write(path: string, content: string | Uint8Array): void;
|
|
35
|
+
/** Append only when the current UTF-8 byte length matches `expectedBytes`.
|
|
36
|
+
* Returns the new length, or undefined when another writer won. */
|
|
37
|
+
append(path: string, content: string, expectedBytes: number): number | undefined;
|
|
38
|
+
}
|
|
39
|
+
/** Node-filesystem storage — the default. Lazily requires `node:fs` so the
|
|
40
|
+
* module imports cleanly in non-Node runtimes (where the caller passes
|
|
41
|
+
* `inMemoryCampaignStorage` instead and never constructs this).
|
|
42
|
+
*
|
|
43
|
+
* `createRequire(import.meta.url)` is the ESM-native lazy require — a bare
|
|
44
|
+
* `require` is a ReferenceError under `"type": "module"`, which is exactly
|
|
45
|
+
* the shape this package publishes. */
|
|
46
|
+
declare function fsCampaignStorage(): CampaignStorage;
|
|
47
|
+
/** In-memory storage for filesystem-less runtimes. Artifacts + trace spans
|
|
48
|
+
* live in a `Map` for the duration of the run; the `CampaignResult` is
|
|
49
|
+
* fully populated, but nothing is persisted to disk. */
|
|
50
|
+
declare function inMemoryCampaignStorage(): CampaignStorage;
|
|
51
|
+
/** Open the durable spend account stored beside a logical run. */
|
|
52
|
+
declare function createRunCostLedger(input: {
|
|
53
|
+
storage: CampaignStorage;
|
|
54
|
+
runDir: string;
|
|
55
|
+
costCeilingUsd?: number;
|
|
56
|
+
/** Set false for read-only inspection that must not create the run directory. */
|
|
57
|
+
ensureRunDir?: boolean;
|
|
58
|
+
}): CostLedger;
|
|
59
|
+
//#endregion
|
|
60
|
+
//#region src/campaign/search-ledger.d.ts
|
|
61
|
+
/** Validate and return a canonical copy. Arrays whose order carries no meaning
|
|
62
|
+
* are sorted, so retries from different processes produce identical bytes. */
|
|
63
|
+
declare function validateSearchLedgerEvent(input: unknown): SearchLedgerEvent;
|
|
64
|
+
/**
|
|
65
|
+
* How this ledger uses its trusted head — the `(sequence, entryHash)` pin kept
|
|
66
|
+
* in the sibling `<path>.head` file that a hash chain needs to prove entries
|
|
67
|
+
* were not deleted from the end. `ledger-core/trusted-head.ts` holds the threat
|
|
68
|
+
* model.
|
|
69
|
+
*
|
|
70
|
+
* - `pin` (default): every append records the new head, and a pin that is
|
|
71
|
+
* present is verified on every read.
|
|
72
|
+
* - `require`: additionally refuses to read a non-empty ledger whose pin is
|
|
73
|
+
* gone, so deleting the sibling file cannot downgrade the guarantee.
|
|
74
|
+
* - `off`: chain verification only. Truncation to a valid shorter prefix is
|
|
75
|
+
* undetectable.
|
|
76
|
+
*/
|
|
77
|
+
type SearchLedgerTrustedHeadMode = 'pin' | 'require' | 'off';
|
|
78
|
+
interface OpenSearchLedgerOptions {
|
|
79
|
+
path: string;
|
|
80
|
+
searchId: string;
|
|
81
|
+
trustedHead?: SearchLedgerTrustedHeadMode;
|
|
82
|
+
/**
|
|
83
|
+
* Keep the ledger's text in this in-process store instead of a file, for a
|
|
84
|
+
* run without a filesystem (an in-memory `CampaignStorage`, keyed by `path`).
|
|
85
|
+
* The chain, parse and state rules are the file ledger's; there is no lock,
|
|
86
|
+
* fsync or trusted head, and the ledger lives as long as the store.
|
|
87
|
+
*/
|
|
88
|
+
store?: LedgerTextStore;
|
|
89
|
+
}
|
|
90
|
+
interface SearchLedgerAppendResult {
|
|
91
|
+
entry: SearchLedgerEntry;
|
|
92
|
+
/** False when the exact event was already durably present. */
|
|
93
|
+
appended: boolean;
|
|
94
|
+
state: SearchStateView;
|
|
95
|
+
}
|
|
96
|
+
interface SearchLedger {
|
|
97
|
+
readonly path: string;
|
|
98
|
+
readonly searchId: string;
|
|
99
|
+
/** Sibling file holding this ledger's trusted head. */
|
|
100
|
+
readonly trustedHeadPath: string;
|
|
101
|
+
append(event: SearchLedgerEvent): Promise<SearchLedgerAppendResult>;
|
|
102
|
+
/** The verified state at the file's current head. */
|
|
103
|
+
state(): Promise<SearchStateView>;
|
|
104
|
+
/** The pinned head, or null when this ledger has never been pinned. */
|
|
105
|
+
trustedHead(): Promise<LedgerTrustedHead | null>;
|
|
106
|
+
/** Pin the current verified head without rewriting a byte. */
|
|
107
|
+
pinTrustedHead(): Promise<LedgerTrustedHead>;
|
|
108
|
+
/** Discard this ledger's pin, reporting what was discarded. It gives up the
|
|
109
|
+
* deletion guarantee for every entry the pin covered. */
|
|
110
|
+
clearTrustedHead(): Promise<LedgerTrustedHeadRemoval>;
|
|
111
|
+
}
|
|
112
|
+
/** Open a durable filesystem search ledger. Construction performs no I/O; the
|
|
113
|
+
* first `append` or `state` verifies the whole existing file. */
|
|
114
|
+
declare function openSearchLedger(options: OpenSearchLedgerOptions): SearchLedger;
|
|
115
|
+
/** Verify and project immutable search-ledger JSONL through the same codec as
|
|
116
|
+
* `FileSearchLedger`. */
|
|
117
|
+
declare function replaySearchLedgerText(text: string, searchId: string, source: string): SearchStateView;
|
|
118
|
+
/**
|
|
119
|
+
* Verify one stored ledger line in isolation: the schema tag, the entry and
|
|
120
|
+
* event schemas, canonical bytes, the entry's own hash, and its search. The
|
|
121
|
+
* chain (sequence and previous hash) and the state machine are the caller's,
|
|
122
|
+
* because they need the lines before this one. An ingest server runs this on
|
|
123
|
+
* every received line, so it hashes exactly the bytes the producer hashed.
|
|
124
|
+
*/
|
|
125
|
+
declare function parseSearchLedgerLine(line: string, searchId: string, context: LedgerLineContext): SearchLedgerEntry;
|
|
126
|
+
/** Append-only file-backed search ledger with idempotent writes. */
|
|
127
|
+
declare class FileSearchLedger implements SearchLedger {
|
|
128
|
+
readonly path: string;
|
|
129
|
+
readonly searchId: string;
|
|
130
|
+
readonly trustedHeadPath: string;
|
|
131
|
+
private readonly trustedHeadMode;
|
|
132
|
+
private readonly journal;
|
|
133
|
+
constructor(path: string, searchId: string, trustedHead?: SearchLedgerTrustedHeadMode);
|
|
134
|
+
state(): Promise<SearchStateView>;
|
|
135
|
+
append(input: SearchLedgerEvent): Promise<SearchLedgerAppendResult>;
|
|
136
|
+
trustedHead(): Promise<LedgerTrustedHead | null>;
|
|
137
|
+
pinTrustedHead(): Promise<LedgerTrustedHead>;
|
|
138
|
+
clearTrustedHead(): Promise<LedgerTrustedHeadRemoval>;
|
|
139
|
+
}
|
|
140
|
+
//#endregion
|
|
141
|
+
//#region src/campaign/search-history-receipt.d.ts
|
|
142
|
+
declare const SEARCH_HISTORY_RECEIPT_SCHEMA_VERSION: '2026-09';
|
|
143
|
+
declare const SEARCH_HISTORY_RECEIPT_DIGEST_ALGORITHM: 'rfc8785-sha256';
|
|
144
|
+
/** Bounded summary of a search's audit. Exact ids stay in the ledger. */
|
|
145
|
+
interface SearchHistoryAuditSummary {
|
|
146
|
+
readonly searchId: string;
|
|
147
|
+
readonly headHash: SearchLedgerHash | null;
|
|
148
|
+
readonly status: SearchAudit['status'];
|
|
149
|
+
readonly closeReason: SearchAudit['closeReason'];
|
|
150
|
+
readonly claimDecision: 'ship' | 'hold' | 'test-cannot-resolve' | null;
|
|
151
|
+
readonly selectedNodeId: string | null;
|
|
152
|
+
readonly eventCount: number;
|
|
153
|
+
readonly nodes: number;
|
|
154
|
+
readonly edges: number;
|
|
155
|
+
readonly cells: number;
|
|
156
|
+
readonly openCells: number;
|
|
157
|
+
readonly openOperations: number;
|
|
158
|
+
readonly nodesWithoutEdge: number;
|
|
159
|
+
readonly undecidedNodes: number;
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* A bounded proof envelope over one search ledger.
|
|
163
|
+
*
|
|
164
|
+
* The content-addressed ledger stays the only rich history. The receipt binds
|
|
165
|
+
* its producer and run, the exact ledger bytes, the digest of the complete
|
|
166
|
+
* audit, and a bounded summary. `complete` means the ledger holds
|
|
167
|
+
* `search-closed`, which the ledger admits only when every allocated cell has
|
|
168
|
+
* an outcome or was cancelled, every started operation was recorded, and every
|
|
169
|
+
* node has an edge and a terminal decision.
|
|
170
|
+
*/
|
|
171
|
+
interface SearchHistoryReceipt {
|
|
172
|
+
readonly schemaVersion: typeof SEARCH_HISTORY_RECEIPT_SCHEMA_VERSION;
|
|
173
|
+
readonly kind: 'search-history-receipt';
|
|
174
|
+
readonly digestAlgorithm: typeof SEARCH_HISTORY_RECEIPT_DIGEST_ALGORITHM;
|
|
175
|
+
readonly receiptDigest: SearchLedgerHash;
|
|
176
|
+
/** Stable producer identity, for example an OptimizationMethod name. */
|
|
177
|
+
readonly producerId: string;
|
|
178
|
+
/** Concrete optimizer or runtime invocation that produced the ledger. */
|
|
179
|
+
readonly runId: string;
|
|
180
|
+
/** The ledger file: `sha256` and `byteLength` of its exact bytes. */
|
|
181
|
+
readonly ledger: SearchArtifactRef;
|
|
182
|
+
/** `hashCanonical` of the complete `SearchAudit` from replaying those bytes. */
|
|
183
|
+
readonly auditDigest: SearchLedgerHash;
|
|
184
|
+
readonly summary: SearchHistoryAuditSummary;
|
|
185
|
+
readonly complete: boolean;
|
|
186
|
+
readonly incompleteReasons: readonly string[];
|
|
187
|
+
}
|
|
188
|
+
interface CreateSearchHistoryReceiptInput {
|
|
189
|
+
readonly producerId: string;
|
|
190
|
+
readonly runId: string;
|
|
191
|
+
readonly ledger: {
|
|
192
|
+
readonly path: string;
|
|
193
|
+
readonly searchId: string;
|
|
194
|
+
};
|
|
195
|
+
readonly storage?: Pick<CampaignStorage, 'read'>;
|
|
196
|
+
}
|
|
197
|
+
type SearchHistoryPolicy = 'allow-missing' | 'require-complete';
|
|
198
|
+
interface SearchHistoryAdmissionOptions {
|
|
199
|
+
/** Missing history is reported by default; require-complete refuses final
|
|
200
|
+
* assessment without a closed search ledger. */
|
|
201
|
+
searchHistoryPolicy?: SearchHistoryPolicy;
|
|
202
|
+
/** Receipt checks are the default. Ledger checks also resolve and replay the bytes. */
|
|
203
|
+
searchHistoryVerification?: 'receipt' | 'ledger';
|
|
204
|
+
}
|
|
205
|
+
/** Read the ledger's bytes, replay them through the search codec, and build
|
|
206
|
+
* the receipt from that replay. */
|
|
207
|
+
declare function createSearchHistoryReceipt(input: CreateSearchHistoryReceiptInput): SearchHistoryReceipt;
|
|
208
|
+
/** Verify the receipt, then resolve its ledger bytes, check them, and replay
|
|
209
|
+
* them with the canonical codec. Never trusts a caller-supplied projection. */
|
|
210
|
+
declare function verifySearchHistoryArtifact(receipt: SearchHistoryReceipt, storage: Pick<CampaignStorage, 'read'>): void;
|
|
211
|
+
interface SearchHistoryCoverageRow {
|
|
212
|
+
readonly producerId: string;
|
|
213
|
+
readonly status: 'complete' | 'incomplete' | 'missing';
|
|
214
|
+
readonly reasons: readonly string[];
|
|
215
|
+
readonly stages?: readonly SearchHistoryCoverageRow[];
|
|
216
|
+
readonly receipt?: SearchHistoryReceipt;
|
|
217
|
+
/** Present only after the referenced bytes and replay were verified. */
|
|
218
|
+
readonly ledgerVerified?: true;
|
|
219
|
+
}
|
|
220
|
+
interface SearchHistoryCoverage {
|
|
221
|
+
readonly policy: SearchHistoryPolicy;
|
|
222
|
+
readonly allComplete: boolean;
|
|
223
|
+
readonly producers: readonly SearchHistoryCoverageRow[];
|
|
224
|
+
}
|
|
225
|
+
declare class SearchHistoryRequiredError extends Error {
|
|
226
|
+
readonly producerId: string;
|
|
227
|
+
readonly reasons: readonly string[];
|
|
228
|
+
constructor(producerId: string, reasons: readonly string[]);
|
|
229
|
+
}
|
|
230
|
+
/** Verify a receipt's own consistency and digest. */
|
|
231
|
+
declare function verifySearchHistoryReceipt(receipt: SearchHistoryReceipt): SearchHistoryReceipt;
|
|
232
|
+
/** Prove that a receipt describes exactly the supplied replayed state. */
|
|
233
|
+
declare function assertSearchHistoryMatchesState(receipt: SearchHistoryReceipt, state: SearchStateView): void;
|
|
234
|
+
/** Require a receipt owned by this producer over a closed search. */
|
|
235
|
+
declare function assertCompleteSearchHistory(producerId: string, receipt: SearchHistoryReceipt | undefined): asserts receipt is SearchHistoryReceipt;
|
|
236
|
+
/** Classify one producer's history without treating malformed evidence as absence. */
|
|
237
|
+
declare function searchHistoryCoverageRow(producerId: string, receipt: SearchHistoryReceipt | undefined): SearchHistoryCoverageRow;
|
|
238
|
+
//#endregion
|
|
239
|
+
//#region src/campaign/search-ledger-recording.d.ts
|
|
240
|
+
/** Identities the ledger needs and a loop cannot infer. */
|
|
241
|
+
interface SearchRunIdentity {
|
|
242
|
+
/** The agent implementation under optimization. */
|
|
243
|
+
agent: SearchSourceRef;
|
|
244
|
+
/** The candidate generator: a model call or deterministic code. */
|
|
245
|
+
proposer: SearchOperationRecordedEvent['execution'];
|
|
246
|
+
/** The code that runs the search and decides its nodes. */
|
|
247
|
+
search: SearchSourceRef;
|
|
248
|
+
/** Model the agent runs; used for a cell that reported none. */
|
|
249
|
+
model: SearchModelIdentity;
|
|
250
|
+
/** What the search improves, for example `vb/coder`. Default: the producer's name. */
|
|
251
|
+
subject?: string;
|
|
252
|
+
/** The judge's pinned source. Default: unknown, because judges arrive as functions. */
|
|
253
|
+
judge?: SearchSourceRef;
|
|
254
|
+
/** The claim the search's numbers may support. Default: a development claim
|
|
255
|
+
* over the supplied tasks, one unit per task. */
|
|
256
|
+
claim?: EvaluationClaim;
|
|
257
|
+
}
|
|
258
|
+
/** A ledger and the identities a loop records into it. */
|
|
259
|
+
interface SearchLedgerBinding {
|
|
260
|
+
ledger: SearchLedger;
|
|
261
|
+
identity: SearchRunIdentity;
|
|
262
|
+
}
|
|
263
|
+
/** The default claim: development numbers over exactly the supplied tasks. */
|
|
264
|
+
declare function developmentClaim(populationId: string): EvaluationClaim;
|
|
265
|
+
/** The header of a search, with plain task lists; the recorder digests them. */
|
|
266
|
+
type SearchOpening = Omit<SearchOpenedEvent, 'kind' | 'eventId' | 'occurredAt' | 'artifacts' | 'splits'> & {
|
|
267
|
+
splits: {
|
|
268
|
+
train: SearchTask[];
|
|
269
|
+
selection: SearchTask[];
|
|
270
|
+
test: SearchTask[];
|
|
271
|
+
heldOutUnits: boolean;
|
|
272
|
+
};
|
|
273
|
+
};
|
|
274
|
+
interface SearchRecorderOptions {
|
|
275
|
+
ledger: SearchLedger;
|
|
276
|
+
/** Where content-addressed blobs are written. Default: `blobs/` beside the ledger. */
|
|
277
|
+
blobDir?: string;
|
|
278
|
+
storage?: CampaignStorage;
|
|
279
|
+
/** Milliseconds since the epoch. Default: `Date.now`. */
|
|
280
|
+
now?: () => number;
|
|
281
|
+
}
|
|
282
|
+
interface RegisterSearchNodeInput {
|
|
283
|
+
artifactDigest: `sha256:${string}`;
|
|
284
|
+
artifact: SearchArtifactRef;
|
|
285
|
+
surfaces: SearchCandidateSurface[];
|
|
286
|
+
}
|
|
287
|
+
interface RecordSearchEdgeInput {
|
|
288
|
+
childNodeId: string;
|
|
289
|
+
/** Parents in this search, primary first, as node ids; or refs for a derive edge. */
|
|
290
|
+
parents: Array<string | SearchNodeRef>;
|
|
291
|
+
operator: SearchEdgeOperator;
|
|
292
|
+
attribution: SearchEdgeAttribution;
|
|
293
|
+
proposer: SearchProposer | null;
|
|
294
|
+
/** Stable id of this proposal within the search, so a resumed search
|
|
295
|
+
* recognizes the edge; for example `gen-3:candidate-1`. */
|
|
296
|
+
proposalKey: string;
|
|
297
|
+
selection?: {
|
|
298
|
+
rule: string;
|
|
299
|
+
evidence: Record<string, number>;
|
|
300
|
+
} | null;
|
|
301
|
+
/** The proposer's free-text rationale; redacted before it is stored. */
|
|
302
|
+
rationale: string | SearchUnknown;
|
|
303
|
+
/** One per parent: a diff blob from `recorder.blob('diff', …)`, or why there is none. */
|
|
304
|
+
diffs: Array<SearchArtifactRef | SearchUnknown>;
|
|
305
|
+
label?: string;
|
|
306
|
+
}
|
|
307
|
+
interface AllocateSearchCellInput {
|
|
308
|
+
nodeId: string;
|
|
309
|
+
taskId: string;
|
|
310
|
+
split: SearchSplit;
|
|
311
|
+
rep: number;
|
|
312
|
+
stage: SearchCellStage;
|
|
313
|
+
lane?: string | null;
|
|
314
|
+
reservation?: SearchReservation | null;
|
|
315
|
+
}
|
|
316
|
+
interface SettleSearchCellInput {
|
|
317
|
+
cellId: string;
|
|
318
|
+
/** Default: the next attempt. An attempt already in the ledger is not appended again. */
|
|
319
|
+
attempt?: number;
|
|
320
|
+
outcome: SearchTaskOutcome;
|
|
321
|
+
accounting: SearchAttemptAccounting;
|
|
322
|
+
identity: SearchExecutionIdentity;
|
|
323
|
+
boxMinutes?: number | null;
|
|
324
|
+
wallMs?: number | null;
|
|
325
|
+
queueMs?: number | null;
|
|
326
|
+
placement?: {
|
|
327
|
+
lane: string;
|
|
328
|
+
boxId: string | null;
|
|
329
|
+
} | null;
|
|
330
|
+
surfaceEvidence?: SearchSurfaceEvidence[];
|
|
331
|
+
traceRef?: SearchTraceRef;
|
|
332
|
+
/** The attempt's RunRecord; its search coordinates and runId must match. */
|
|
333
|
+
runRecord?: RunRecord;
|
|
334
|
+
artifacts?: SearchArtifactRef[];
|
|
335
|
+
}
|
|
336
|
+
/** Deterministic edge id: one proposal of one child within one search. */
|
|
337
|
+
declare function searchEdgeId(searchId: string, childNodeId: string, proposalKey: string): string;
|
|
338
|
+
/** Writes one search's events into its ledger as they happen. */
|
|
339
|
+
declare class SearchRecorder {
|
|
340
|
+
readonly ledger: SearchLedger;
|
|
341
|
+
private readonly storage;
|
|
342
|
+
private readonly blobDir;
|
|
343
|
+
private readonly now;
|
|
344
|
+
private readonly tasks;
|
|
345
|
+
private lastStampMs;
|
|
346
|
+
private constructor();
|
|
347
|
+
/**
|
|
348
|
+
* Open the search: append `search-opened`, or, when the ledger already holds
|
|
349
|
+
* one, check that it is this search and continue it.
|
|
350
|
+
*/
|
|
351
|
+
static open(options: SearchRecorderOptions, opening: SearchOpening, artifacts?: SearchArtifactRef[]): Promise<SearchRecorder>;
|
|
352
|
+
get searchId(): string;
|
|
353
|
+
/** The ledger's verified state now. */
|
|
354
|
+
state(): Promise<SearchStateView>;
|
|
355
|
+
/** Store `body` as a canonical JSON blob and return its content address. */
|
|
356
|
+
blob(role: string, body: unknown): SearchArtifactRef;
|
|
357
|
+
/**
|
|
358
|
+
* Read back a blob this recorder stored, by its content address. The bytes
|
|
359
|
+
* must hash to the reference's digest and length, so a resumed search reads
|
|
360
|
+
* exactly what the ledger bound.
|
|
361
|
+
*/
|
|
362
|
+
readBlob(ref: SearchArtifactRef): unknown;
|
|
363
|
+
/** Register a node, or return the existing node with the same artifact digest. */
|
|
364
|
+
registerNode(input: RegisterSearchNodeInput): Promise<{
|
|
365
|
+
nodeId: string;
|
|
366
|
+
existed: boolean;
|
|
367
|
+
}>;
|
|
368
|
+
/** Record the proposal that derived a node. Returns the edge id. */
|
|
369
|
+
recordEdge(input: RecordSearchEdgeInput): Promise<string>;
|
|
370
|
+
startOperation(input: {
|
|
371
|
+
operationId: string;
|
|
372
|
+
operationKind: SearchOperationKind;
|
|
373
|
+
reservation?: SearchReservation | null;
|
|
374
|
+
/** Bound at the start, so a restart finds them even if the operation
|
|
375
|
+
* never records a result. */
|
|
376
|
+
artifacts?: SearchArtifactRef[];
|
|
377
|
+
}): Promise<void>;
|
|
378
|
+
recordOperation(input: Omit<SearchOperationRecordedEvent, 'kind' | 'eventId' | 'occurredAt' | 'artifacts'> & {
|
|
379
|
+
artifacts?: SearchArtifactRef[];
|
|
380
|
+
}): Promise<void>;
|
|
381
|
+
/** Plan one cell. Returns the cell id; an allocated cell is not allocated again. */
|
|
382
|
+
allocateCell(input: AllocateSearchCellInput): Promise<string>;
|
|
383
|
+
/** Record one finished attempt at a cell. */
|
|
384
|
+
settleCell(input: SettleSearchCellInput): Promise<void>;
|
|
385
|
+
cancelCell(input: {
|
|
386
|
+
cellId: string;
|
|
387
|
+
reason: 'pruned' | 'budget' | 'deadline' | 'aborted';
|
|
388
|
+
}): Promise<void>;
|
|
389
|
+
/** Record a decision about a node. Repeating the node's latest decision appends nothing. */
|
|
390
|
+
decideNode(input: {
|
|
391
|
+
nodeId: string;
|
|
392
|
+
decision: SearchNodeDecision;
|
|
393
|
+
basis?: NodeEstimate | null;
|
|
394
|
+
rule: string;
|
|
395
|
+
reason: string;
|
|
396
|
+
}): Promise<void>;
|
|
397
|
+
/** Close the search. The ledger refuses a close while any cell, operation or
|
|
398
|
+
* node decision is outstanding. */
|
|
399
|
+
close(input: {
|
|
400
|
+
reason: SearchCloseReason;
|
|
401
|
+
claim: SearchClaim | null;
|
|
402
|
+
}): Promise<void>;
|
|
403
|
+
/** A bounded receipt over the exact ledger bytes. */
|
|
404
|
+
receipt(input: {
|
|
405
|
+
producerId: string;
|
|
406
|
+
runId: string;
|
|
407
|
+
}): SearchHistoryReceipt;
|
|
408
|
+
private append;
|
|
409
|
+
/** Non-decreasing ISO stamps; the ledger refuses an event that moves back. */
|
|
410
|
+
private stamp;
|
|
411
|
+
}
|
|
412
|
+
/** A mutable surface as a node: its content digest, stored bytes and declared surfaces. */
|
|
413
|
+
declare function surfaceNode(recorder: SearchRecorder, surface: MutableSurface): RegisterSearchNodeInput;
|
|
414
|
+
/** A parent-to-child diff of two mutable surfaces, stored as a blob. */
|
|
415
|
+
declare function surfaceDiff(recorder: SearchRecorder, parent: MutableSurface, child: MutableSurface): SearchArtifactRef;
|
|
416
|
+
//#endregion
|
|
417
|
+
//#region src/search/lenses/shared.d.ts
|
|
418
|
+
/** The search's own ranking split: selection when the search declares one,
|
|
419
|
+
* else train. Matches `searchPolicyView` and `agent-eval search show`, so a
|
|
420
|
+
* lens ranks nodes on exactly the split the search itself ranks them on. */
|
|
421
|
+
declare function rankingSplit(state: SearchStateView): 'train' | 'selection';
|
|
422
|
+
/** One named signal a `SearchPolicy` can read: a small, quantitative payload
|
|
423
|
+
* under one label, so a policy reads `signal.value` without knowing a lens's
|
|
424
|
+
* full `data` shape. */
|
|
425
|
+
interface LensSignal<T> {
|
|
426
|
+
name: string;
|
|
427
|
+
value: T;
|
|
428
|
+
}
|
|
429
|
+
interface LensResult<TData, TSignal> {
|
|
430
|
+
data: TData;
|
|
431
|
+
signal: LensSignal<TSignal>;
|
|
432
|
+
}
|
|
433
|
+
/** A descriptive summary of an independent (unpaired) numeric sample, staged
|
|
434
|
+
* exactly like `NodeEstimate.method`: `none` below 2 observations,
|
|
435
|
+
* `insufficient` below {@link INSUFFICIENT_FROM}, `descriptive` (bootstrap
|
|
436
|
+
* interval, spread only) below `BOOTSTRAP_GATE_MIN_N`, `bootstrap`
|
|
437
|
+
* (decision-grade interval) from there. Unlike `estimateNode`, these samples
|
|
438
|
+
* are not paired on a shared unit, so this is never a claim — only a
|
|
439
|
+
* lens's own honest description of what it measured. */
|
|
440
|
+
interface SampleSummary {
|
|
441
|
+
n: number;
|
|
442
|
+
mean: number | null;
|
|
443
|
+
method: 'none' | 'insufficient' | 'descriptive' | 'bootstrap';
|
|
444
|
+
interval: [number, number] | null;
|
|
445
|
+
}
|
|
446
|
+
declare function summarizeSamples(samples: readonly number[], seed?: number): SampleSummary;
|
|
447
|
+
//#endregion
|
|
448
|
+
//#region src/search/lenses/operator-yield.d.ts
|
|
449
|
+
/** The operators an expansion may choose (`SearchExpansion.operator` in
|
|
450
|
+
* `search-policy.ts`): every edge operator except `seed` (the search's own
|
|
451
|
+
* start) and `derive` (a cross-search edge a proposer never chooses). */
|
|
452
|
+
declare const EXPANSION_OPERATORS: readonly ['draft', 'improve', 'debug', 'merge'];
|
|
453
|
+
type ExpansionOperator = (typeof EXPANSION_OPERATORS)[number];
|
|
454
|
+
/** The bandit's own gate: an operator's weight is used only once it has this
|
|
455
|
+
* many yield-eligible outcomes; below it, the policy falls back to a fixed
|
|
456
|
+
* weight for that operator. Same threshold `NodeEstimate.method` uses for
|
|
457
|
+
* `insufficient` (`minimumPairsForPairedDeltaTest(0.95)` = 6). */
|
|
458
|
+
declare const MIN_OUTCOMES_FOR_WEIGHT = 6;
|
|
459
|
+
interface OperatorOutcomeCounts {
|
|
460
|
+
advanced: number;
|
|
461
|
+
finalist: number;
|
|
462
|
+
selected: number;
|
|
463
|
+
pruned: number;
|
|
464
|
+
rejected: number;
|
|
465
|
+
invalid: number;
|
|
466
|
+
undecided: number;
|
|
467
|
+
}
|
|
468
|
+
interface OperatorYieldRow {
|
|
469
|
+
operator: SearchEdgeOperator;
|
|
470
|
+
/** Edges recorded with this operator, regardless of whether their child
|
|
471
|
+
* yields a usable sample. */
|
|
472
|
+
proposals: number;
|
|
473
|
+
outcomes: OperatorOutcomeCounts;
|
|
474
|
+
/** Children excluded from `yield`: no shared unit with the root (unknown
|
|
475
|
+
* posterior) or an unknown/zero known cost. Never imputed into `yield`. */
|
|
476
|
+
excluded: number;
|
|
477
|
+
yield: SampleSummary;
|
|
478
|
+
}
|
|
479
|
+
interface OperatorYieldData {
|
|
480
|
+
split: 'train' | 'selection';
|
|
481
|
+
rows: OperatorYieldRow[];
|
|
482
|
+
}
|
|
483
|
+
interface OperatorYieldOptions {
|
|
484
|
+
split?: 'train' | 'selection';
|
|
485
|
+
}
|
|
486
|
+
/** One weight per expandable operator: an operator's yield mean once it has
|
|
487
|
+
* `MIN_OUTCOMES_FOR_WEIGHT` or more samples, else `null` (not yet trusted —
|
|
488
|
+
* the policy's own fallback decides what an untrusted operator gets). */
|
|
489
|
+
type OperatorYieldSignal = Record<ExpansionOperator, number | null>;
|
|
490
|
+
declare function operatorYield(state: SearchStateView, options?: OperatorYieldOptions): {
|
|
491
|
+
data: OperatorYieldData;
|
|
492
|
+
signal: {
|
|
493
|
+
name: string;
|
|
494
|
+
value: OperatorYieldSignal;
|
|
495
|
+
};
|
|
496
|
+
};
|
|
497
|
+
//#endregion
|
|
498
|
+
//#region src/campaign/estimate-node.d.ts
|
|
499
|
+
/** The estimator every `NodeEstimate` names. */
|
|
500
|
+
declare const SEARCH_ESTIMATOR: SearchSourceRef;
|
|
501
|
+
interface EstimateNodeCellsInput {
|
|
502
|
+
nodeId: string;
|
|
503
|
+
against: string;
|
|
504
|
+
split: SearchSplit;
|
|
505
|
+
direction: 'maximize' | 'minimize';
|
|
506
|
+
/** Every scored cell of `nodeId` on `split`. */
|
|
507
|
+
nodeCells: readonly SearchScoredCell[];
|
|
508
|
+
/** Every scored cell of `against` on `split`. */
|
|
509
|
+
againstCells: readonly SearchScoredCell[];
|
|
510
|
+
}
|
|
511
|
+
/**
|
|
512
|
+
* Digest of the cells an estimate reads, with the contrast they serve. Cells
|
|
513
|
+
* are listed in cellId order, so the digest names the set, not the order it
|
|
514
|
+
* was read in.
|
|
515
|
+
*/
|
|
516
|
+
declare function searchCellSetDigest(input: Omit<EstimateNodeCellsInput, 'direction'>): SearchLedgerHash;
|
|
517
|
+
/**
|
|
518
|
+
* The paired contrast of `nodeId` against `against` on the units both scored.
|
|
519
|
+
*
|
|
520
|
+
* `delta` is the mean per-unit difference, node minus `against`, in the
|
|
521
|
+
* metric's own units; for a `minimize` objective an improvement is negative.
|
|
522
|
+
* The exact sign test is one-sided toward improvement in the objective's
|
|
523
|
+
* direction. Unscored cells (errored, cancelled or in flight) are absent from
|
|
524
|
+
* the inputs, never zero.
|
|
525
|
+
*
|
|
526
|
+
* - `none` (0 or 1 pair): no delta.
|
|
527
|
+
* - `insufficient` (2 to 5): the delta only.
|
|
528
|
+
* - `descriptive` (6 to 19): the bootstrap interval as spread, and the sign-test p.
|
|
529
|
+
* - `bootstrap` (20 or more): the decision-grade bootstrap interval.
|
|
530
|
+
*
|
|
531
|
+
* When every paired delta is equal the interval would have zero width, which
|
|
532
|
+
* is an absence of evidence; the estimate is then `indeterminate` and carries
|
|
533
|
+
* neither an interval nor a p-value.
|
|
534
|
+
*/
|
|
535
|
+
declare function estimateNodeFromCells(input: EstimateNodeCellsInput): NodeEstimate;
|
|
536
|
+
/**
|
|
537
|
+
* `estimateNodeFromCells` over the cells a search state holds: `nodeId`
|
|
538
|
+
* against `against` on one split, in the direction the search's objective
|
|
539
|
+
* declares.
|
|
540
|
+
*/
|
|
541
|
+
declare function estimateNode(state: SearchStateView, nodeId: string, options: {
|
|
542
|
+
against: string;
|
|
543
|
+
split: SearchSplit;
|
|
544
|
+
}): NodeEstimate;
|
|
545
|
+
/** A node's normal posterior on its improvement over the root. */
|
|
546
|
+
interface NodePosterior {
|
|
547
|
+
nodeId: string;
|
|
548
|
+
/** Units the node and the root both scored. */
|
|
549
|
+
pairs: number;
|
|
550
|
+
/** Mean per-unit improvement over the root in the objective's direction,
|
|
551
|
+
* so larger is better for either direction. Null without a shared unit. */
|
|
552
|
+
mean: number | null;
|
|
553
|
+
/** The pooled variance divided by `pairs`. Null when either is unknown. */
|
|
554
|
+
variance: number | null;
|
|
555
|
+
}
|
|
556
|
+
interface SearchPosterior {
|
|
557
|
+
split: SearchSplit;
|
|
558
|
+
rootNodeId: string;
|
|
559
|
+
/**
|
|
560
|
+
* Between-unit variance of the per-unit improvements over the root, pooled
|
|
561
|
+
* across every non-root node with at least 2 shared units. Null until some
|
|
562
|
+
* node has 2.
|
|
563
|
+
*/
|
|
564
|
+
pooledVariance: number | null;
|
|
565
|
+
/** Sum over the pooled nodes of their shared units minus one. */
|
|
566
|
+
degreesOfFreedom: number;
|
|
567
|
+
/** Every node in registration order; the root first, at exactly 0. */
|
|
568
|
+
nodes: NodePosterior[];
|
|
569
|
+
}
|
|
570
|
+
/**
|
|
571
|
+
* The posterior every node's parent-selection draw uses. Each node's mean is
|
|
572
|
+
* its improvement over the root on shared units; its variance is the search's
|
|
573
|
+
* pooled between-unit variance divided by its unit count, so a node measured
|
|
574
|
+
* on one unit has a wide posterior rather than none. The root is the reference
|
|
575
|
+
* and sits at exactly 0.
|
|
576
|
+
*/
|
|
577
|
+
declare function searchPosterior(state: SearchStateView, options?: {
|
|
578
|
+
split?: SearchSplit;
|
|
579
|
+
}): SearchPosterior;
|
|
580
|
+
//#endregion
|
|
581
|
+
//#region src/campaign/search-policy.d.ts
|
|
582
|
+
/** What a policy may read about a search. */
|
|
583
|
+
interface SearchPolicyView {
|
|
584
|
+
readonly searchId: string;
|
|
585
|
+
readonly seed: number;
|
|
586
|
+
readonly direction: 'maximize' | 'minimize';
|
|
587
|
+
/** The split nodes are ranked on: selection, or train when the search
|
|
588
|
+
* declares no selection split (the proposer's own feedback then ranks). */
|
|
589
|
+
readonly split: 'selection' | 'train';
|
|
590
|
+
readonly rootNodeId: string;
|
|
591
|
+
/** Proposals completed so far. One an interrupted process lost does not count. */
|
|
592
|
+
readonly expansions: number;
|
|
593
|
+
/** Admitted nodes whose screen finished, in registration order, root first. */
|
|
594
|
+
readonly screened: readonly string[];
|
|
595
|
+
/** Admitted nodes still being screened. */
|
|
596
|
+
readonly screening: number;
|
|
597
|
+
/** True when the node has a scored cell on `split` and none of its cells
|
|
598
|
+
* there ran and ended unscored. A node that dodged a unit cannot lead; cells
|
|
599
|
+
* still to run, such as a rung the allocator just opened, do not count. */
|
|
600
|
+
complete(nodeId: string): boolean;
|
|
601
|
+
/** Per-unit means on `split`, in unitId order. */
|
|
602
|
+
unitScores(nodeId: string): readonly SearchUnitScore[];
|
|
603
|
+
/** The paired contrast of `nodeId` against `against` on `split`. */
|
|
604
|
+
estimate(nodeId: string, against: string): NodeEstimate;
|
|
605
|
+
/** Every node whose edge is recorded, in registration order, root first:
|
|
606
|
+
* nodes still being screened and nodes decided invalid included. */
|
|
607
|
+
nodes(): readonly SearchPolicyNode[];
|
|
608
|
+
/** Each node's normal posterior on its improvement over the root on
|
|
609
|
+
* `split` (`searchPosterior`), computed once per ledger state. */
|
|
610
|
+
readonly posterior: SearchPosterior;
|
|
611
|
+
/** The `operatorYield` lens's signal (search-tree-design §12) on `split`:
|
|
612
|
+
* an expandable operator's yield mean once it has enough measured
|
|
613
|
+
* outcomes, else null. Computed from the view's ledger state when first
|
|
614
|
+
* read. */
|
|
615
|
+
readonly operatorWeights: OperatorYieldSignal;
|
|
616
|
+
}
|
|
617
|
+
/** What a policy may read about one node. */
|
|
618
|
+
interface SearchPolicyNode {
|
|
619
|
+
readonly nodeId: string;
|
|
620
|
+
readonly ordinal: number;
|
|
621
|
+
/** The primary parent; null for the root. */
|
|
622
|
+
readonly parent: string | null;
|
|
623
|
+
/** The operator of the edge that placed the node: `seed` for the root. */
|
|
624
|
+
readonly operator: SearchEdgeOperator;
|
|
625
|
+
/** The rule that chose the node's parent (that edge's `selection.rule`);
|
|
626
|
+
* null when the edge records none. */
|
|
627
|
+
readonly rule: string | null;
|
|
628
|
+
/** Nodes placed from this one, in registration order. */
|
|
629
|
+
readonly children: readonly string[];
|
|
630
|
+
/** The node's latest decision; null while undecided. */
|
|
631
|
+
readonly status: SearchNodeStatus | null;
|
|
632
|
+
/** Its cells outside the test split whose outcome is final: passed or failed. */
|
|
633
|
+
readonly outcomes: number;
|
|
634
|
+
/** Of those, the cells that failed: the agent's defect, such as a crash, a
|
|
635
|
+
* broken build or a judge integrity flag. An `errored` cell is the
|
|
636
|
+
* environment's fault and never counts. */
|
|
637
|
+
readonly defects: number;
|
|
638
|
+
}
|
|
639
|
+
/** One expansion: the parents a proposer derives a child from, and how. */
|
|
640
|
+
interface SearchExpansion {
|
|
641
|
+
parents: string[];
|
|
642
|
+
operator: Exclude<SearchEdgeOperator, 'seed' | 'derive'>;
|
|
643
|
+
/** Why these parents: recorded on every edge the expansion produces. */
|
|
644
|
+
selection: {
|
|
645
|
+
rule: string;
|
|
646
|
+
evidence: Record<string, number>;
|
|
647
|
+
};
|
|
648
|
+
}
|
|
649
|
+
interface SearchPolicy {
|
|
650
|
+
/** Recorded as the search's `policy.expansion`. */
|
|
651
|
+
readonly name: string;
|
|
652
|
+
/** Stop after this many expansions without a new leader. */
|
|
653
|
+
readonly patience?: number;
|
|
654
|
+
/** The next expansion, or null to wait for more evidence. */
|
|
655
|
+
expand(view: SearchPolicyView): SearchExpansion | null;
|
|
656
|
+
/** The node the search keeps if it stopped now. */
|
|
657
|
+
leader(view: SearchPolicyView): string;
|
|
658
|
+
}
|
|
659
|
+
/**
|
|
660
|
+
* The hill climb. The leader starts at the root; a screened node that dodged no
|
|
661
|
+
* unit takes the lead when it scored every unit the leader scored and its mean
|
|
662
|
+
* on them beats the leader's. A node measured on fewer units than the leader,
|
|
663
|
+
* such as one an allocator has only screened, cannot take the lead on less
|
|
664
|
+
* evidence than the leader holds. Nodes are taken in registration order, so
|
|
665
|
+
* the leader is a pure function of the ledger. The policy expands the leader,
|
|
666
|
+
* and only once every earlier child is screened, so each proposal sees every
|
|
667
|
+
* result before it.
|
|
668
|
+
*/
|
|
669
|
+
declare function incumbent(options?: {
|
|
670
|
+
patience?: number;
|
|
671
|
+
}): SearchPolicy;
|
|
672
|
+
/**
|
|
673
|
+
* The hill climb (as `incumbent`), with its operator drawn from the
|
|
674
|
+
* `operatorYield` lens instead of fixed at `improve` (search-tree-design
|
|
675
|
+
* §12): a weighted draw, seeded from `seed` and the expansion index like
|
|
676
|
+
* `crowdedFrontierParent`, over the lens's per-operator yield. The fallback
|
|
677
|
+
* is per operator, not all-or-nothing: an operator the lens has not yet
|
|
678
|
+
* measured `MIN_OUTCOMES_FOR_WEIGHT` outcomes for draws on `fixedWeights`
|
|
679
|
+
* (uniform by default) instead, so it is never starved while unmeasured, and
|
|
680
|
+
* an operator that does have enough outcomes draws on its own measured
|
|
681
|
+
* yield right away rather than waiting for every other operator to catch
|
|
682
|
+
* up — proved against real search-sim ledgers where a hill climb had only
|
|
683
|
+
* ever proposed `improve`: an all-or-nothing gate would keep every draw
|
|
684
|
+
* uniform forever, because `draft`/`debug`/`merge` are never measured by a
|
|
685
|
+
* policy that never chooses them. A measured operator's weight is its own
|
|
686
|
+
* `fixedWeights` prior plus its yield, not the yield alone: the two are on
|
|
687
|
+
* different scales (yield is improvement per known dollar; the prior is an
|
|
688
|
+
* arbitrary share), so using the yield by itself would let a small positive
|
|
689
|
+
* yield draw LESS than an untested operator sitting on the default prior of
|
|
690
|
+
* 1 — the same real ledgers caught exactly that before this was fixed. The
|
|
691
|
+
* sum is floored just above zero, so a so-far-bad operator can still be
|
|
692
|
+
* re-measured rather than excluded outright.
|
|
693
|
+
*/
|
|
694
|
+
declare function incumbentWithOperatorBandit(options?: {
|
|
695
|
+
patience?: number;
|
|
696
|
+
seed: number;
|
|
697
|
+
fixedWeights?: Partial<Record<ExpansionOperator, number>>;
|
|
698
|
+
}): SearchPolicy;
|
|
699
|
+
/**
|
|
700
|
+
* The hill climb with a different parent: each expansion draws two distinct
|
|
701
|
+
* members of the Pareto frontier (per-unit means on the policy split) with a
|
|
702
|
+
* PRNG seeded from `seed` and the expansion index, and keeps the one with the
|
|
703
|
+
* larger crowding distance, the more isolated. Boundary members carry infinite
|
|
704
|
+
* distance. Ties fall to the higher mean, then to the earlier node. The leader
|
|
705
|
+
* rule is the incumbent's: a frontier parent explores, and only a node that
|
|
706
|
+
* beats the leader leads.
|
|
707
|
+
*/
|
|
708
|
+
declare function crowdedFrontierParent(options: {
|
|
709
|
+
seed: number;
|
|
710
|
+
}): SearchPolicy;
|
|
711
|
+
interface AideOptions {
|
|
712
|
+
/** Children of the root drafted as whole alternatives before the policy
|
|
713
|
+
* debugs or improves. Default 5. */
|
|
714
|
+
drafts?: number;
|
|
715
|
+
/** The chance an expansion debugs a buggy leaf when one exists. Default 0.5. */
|
|
716
|
+
debugProbability?: number;
|
|
717
|
+
/** Debug edges in a row that one chain may hold. Default 3. */
|
|
718
|
+
maxDebugDepth?: number;
|
|
719
|
+
/** Improve children in a row that leave their lineage's best posterior mean
|
|
720
|
+
* unraised before the lineage counts as stalled. Default 4. */
|
|
721
|
+
stallAfter?: number;
|
|
722
|
+
}
|
|
723
|
+
/**
|
|
724
|
+
* AIDE's search policy (`aide/agent.py`, `search_policy`) with three changes
|
|
725
|
+
* for noisy scores.
|
|
726
|
+
*
|
|
727
|
+
* 1. **Draft** while fewer than `drafts` nodes were drafted: the root is the
|
|
728
|
+
* parent, and the proposer writes a whole alternative, not an edit.
|
|
729
|
+
* 2. **Debug**, with probability `debugProbability`: a buggy leaf, drawn
|
|
730
|
+
* uniformly, whose chain holds fewer than `maxDebugDepth` debug edges. A
|
|
731
|
+
* node is buggy when at least half of its final cells outside the test
|
|
732
|
+
* split failed: defects, not a low score. An `errored` cell is the
|
|
733
|
+
* environment's fault; it is retried and never makes a node buggy.
|
|
734
|
+
* 3. **Improve** otherwise. The parent is drawn by Thompson sampling, not
|
|
735
|
+
* AIDE's argmax, from every screened node that is not buggy and has a
|
|
736
|
+
* posterior (`searchPosterior`): the root sits at 0, and every other node
|
|
737
|
+
* at its mean improvement over the root with the search's pooled
|
|
738
|
+
* between-unit variance divided by its shared units, so a node measured on
|
|
739
|
+
* few units draws from a wide posterior. Until some node shares 2 units
|
|
740
|
+
* with the root the pooled variance is unknown, every posterior is as wide
|
|
741
|
+
* as it can be, and the draw is uniform. With no such node, the policy
|
|
742
|
+
* drafts.
|
|
743
|
+
* 4. **Stall:** when the drawn parent's lineage (the nodes under its nearest
|
|
744
|
+
* draft, or under the root) has had `stallAfter` improve children in a row
|
|
745
|
+
* that did not raise the lineage's best posterior mean, the improve forks
|
|
746
|
+
* from the node with the best posterior mean instead. This is AIDE²'s
|
|
747
|
+
* inner policy. A fork's children restart the run of the lineage they
|
|
748
|
+
* join, so a stalled lineage that holds the global best forks once, not
|
|
749
|
+
* on every later expansion.
|
|
750
|
+
*
|
|
751
|
+
* A parent is always a node whose screen finished; a node refused at
|
|
752
|
+
* admission or decided invalid never is. Draws come from a PRNG seeded by the
|
|
753
|
+
* search seed and the count of completed expansions, so the policy is a pure
|
|
754
|
+
* function of the ledger. The leader is the incumbent's.
|
|
755
|
+
*/
|
|
756
|
+
declare function aide(options?: AideOptions): SearchPolicy;
|
|
757
|
+
/**
|
|
758
|
+
* Beam search: the beam is the top `width` nodes by posterior mean
|
|
759
|
+
* (`searchPosterior`), and the member with the fewest children is expanded,
|
|
760
|
+
* so each member is expanded in turn, as in a generation of `width`. A member
|
|
761
|
+
* is the root, a node an allocator advanced, or a node that scored every unit
|
|
762
|
+
* the root scored: a node an allocator has only screened waits for its rank
|
|
763
|
+
* before it enters. Ties go to the higher mean, then to the earlier node. The
|
|
764
|
+
* leader is the incumbent's. Strategy evolution is `beam` with its population
|
|
765
|
+
* as the width.
|
|
766
|
+
*/
|
|
767
|
+
declare function beam(options: {
|
|
768
|
+
width: number;
|
|
769
|
+
}): SearchPolicy;
|
|
770
|
+
//#endregion
|
|
771
|
+
//#region src/campaign/allocation.d.ts
|
|
772
|
+
/** One cell an allocator wants for a node. */
|
|
773
|
+
interface SearchCellPlan {
|
|
774
|
+
taskId: string;
|
|
775
|
+
split: SearchSplit;
|
|
776
|
+
rep: number;
|
|
777
|
+
stage: SearchCellStage;
|
|
778
|
+
}
|
|
779
|
+
/** What an allocator reads when it decides. */
|
|
780
|
+
interface SearchAllocationView {
|
|
781
|
+
readonly state: SearchStateView;
|
|
782
|
+
/** True when no cell allocated to the node can still run: each one ended
|
|
783
|
+
* scored, failed, cancelled or out of attempts. */
|
|
784
|
+
idle(nodeId: string): boolean;
|
|
785
|
+
}
|
|
786
|
+
/** A rank decision an allocator asks the kernel to record. */
|
|
787
|
+
interface SearchRungDecision {
|
|
788
|
+
nodeId: string;
|
|
789
|
+
decision: {
|
|
790
|
+
status: 'advanced';
|
|
791
|
+
rung: number;
|
|
792
|
+
} | {
|
|
793
|
+
status: 'pruned';
|
|
794
|
+
};
|
|
795
|
+
/** The node against the root on the ranked split, as it stood at the decision. */
|
|
796
|
+
basis: NodeEstimate | null;
|
|
797
|
+
rule: string;
|
|
798
|
+
reason: string;
|
|
799
|
+
}
|
|
800
|
+
interface SearchAllocator {
|
|
801
|
+
/** Recorded as the search's `policy.allocation`. */
|
|
802
|
+
readonly name: string;
|
|
803
|
+
/** Repeats of each task. The claim runs its test cells at the same repeats. */
|
|
804
|
+
readonly reps: number;
|
|
805
|
+
/** Every cell the node needs through `rung`. The kernel allocates the ones
|
|
806
|
+
* missing; a node that was never advanced is at rung 0. */
|
|
807
|
+
plan(state: SearchStateView, nodeId: string, rung: number): SearchCellPlan[];
|
|
808
|
+
/** Cells a newly admitted node's screen allocates, so the kernel can price an
|
|
809
|
+
* expansion against the budget before the proposer runs. */
|
|
810
|
+
screenSize(state: SearchStateView): number;
|
|
811
|
+
/** Nodes the evidence now moves to a further rung, deepest rung first. The
|
|
812
|
+
* kernel records each one the budget admits and allocates its rung. */
|
|
813
|
+
advance(view: SearchAllocationView): SearchRungDecision[];
|
|
814
|
+
/** At close: nodes left waiting below the top rung, decided `pruned` with
|
|
815
|
+
* their rank. `keep`, the node the search keeps, is never pruned. */
|
|
816
|
+
prune(view: SearchAllocationView, keep: string): SearchRungDecision[];
|
|
817
|
+
}
|
|
818
|
+
/**
|
|
819
|
+
* Every node gets every train and selection task at every repeat: the root as
|
|
820
|
+
* `root` cells, every other node as `train` cells (the proposer's feedback) and
|
|
821
|
+
* `screen` cells (the policy's private evidence). This is the fixed plan the
|
|
822
|
+
* generation loop ran and GEPA runs. It has one rung, so it never advances or
|
|
823
|
+
* prunes a node.
|
|
824
|
+
*/
|
|
825
|
+
declare function uniform(options?: {
|
|
826
|
+
reps?: number;
|
|
827
|
+
}): SearchAllocator;
|
|
828
|
+
interface AshaOptions {
|
|
829
|
+
/** Units of the first rung. Default 6, `minimumPairsForPairedDeltaTest(0.95)`:
|
|
830
|
+
* the fewest shared units a paired contrast needs, so every screened edge
|
|
831
|
+
* gets one. */
|
|
832
|
+
units?: number;
|
|
833
|
+
/** Reduction factor: a node advances when it ranks in the top 1/eta of the
|
|
834
|
+
* nodes that finished its rung. Default 3. */
|
|
835
|
+
eta?: number;
|
|
836
|
+
/** Train units every non-root node also runs, as the proposer's feedback.
|
|
837
|
+
* They never enter a rank. Default 2. */
|
|
838
|
+
trainUnits?: number;
|
|
839
|
+
/** Repeats per task. Default 1. */
|
|
840
|
+
reps?: number;
|
|
841
|
+
/** How a rung beyond the first chooses the units it adds. Default: the
|
|
842
|
+
* next units of the seeded permutation. */
|
|
843
|
+
extend?: SearchUnitExtension;
|
|
844
|
+
}
|
|
845
|
+
/**
|
|
846
|
+
* How `asha` chooses the units a rung adds beyond the rung below it, for
|
|
847
|
+
* example the units that best separate the current leaders
|
|
848
|
+
* (`nextUnitExtension` in `search/lenses`). A rung's units are chosen once,
|
|
849
|
+
* when the first `advanced` decision opens the rung, and read back from that
|
|
850
|
+
* point of the ledger afterwards, so every node at the rung runs the same
|
|
851
|
+
* units and a replayed or resumed search derives the same plan.
|
|
852
|
+
*/
|
|
853
|
+
interface SearchUnitExtension {
|
|
854
|
+
/** Recorded inside the allocator's name, so the ledger names it. */
|
|
855
|
+
readonly name: string;
|
|
856
|
+
/**
|
|
857
|
+
* Up to `count` units of `remaining`, best first. The chooser must read
|
|
858
|
+
* only evidence the ledger held at `asOfSequence` (the decision that opened
|
|
859
|
+
* the rung). Units it does not name are filled from the seeded order.
|
|
860
|
+
*/
|
|
861
|
+
choose(input: {
|
|
862
|
+
state: SearchStateView;
|
|
863
|
+
asOfSequence: number;
|
|
864
|
+
split: 'selection' | 'train';
|
|
865
|
+
rung: number;
|
|
866
|
+
/** Units of the rungs below, in rung order. */
|
|
867
|
+
measured: readonly string[];
|
|
868
|
+
remaining: readonly string[];
|
|
869
|
+
count: number;
|
|
870
|
+
}): readonly string[];
|
|
871
|
+
}
|
|
872
|
+
/**
|
|
873
|
+
* Asynchronous successive halving (Li et al., 2020) over one seeded
|
|
874
|
+
* permutation of the ranked split's units, fixed by the search's seed.
|
|
875
|
+
*
|
|
876
|
+
* Rung k is the first `units × 2^k` units of the permutation; the top rung is
|
|
877
|
+
* every unit. The root runs every unit before anything else, so every rung
|
|
878
|
+
* pairs against it. A new node screens on rung 0 plus `trainUnits` train
|
|
879
|
+
* units. Every node at a rung runs the same units as its parent, the root and
|
|
880
|
+
* its siblings, so every contrast pairs.
|
|
881
|
+
*
|
|
882
|
+
* A node that finished rung k advances once it ranks in the top
|
|
883
|
+
* floor(n / eta) of the n nodes that finished rung k, the root included, by
|
|
884
|
+
* mean over the rung's units; a node with an unscored unit ranks last and
|
|
885
|
+
* never advances. There is no barrier: a node outside the top waits, because
|
|
886
|
+
* the set grows as more nodes finish. At close a waiting node is pruned with
|
|
887
|
+
* its rank. The ranked split is selection, or train when a search declares no
|
|
888
|
+
* selection split, as the policy's.
|
|
889
|
+
*/
|
|
890
|
+
declare function asha(options?: AshaOptions): SearchAllocator;
|
|
891
|
+
//#endregion
|
|
892
|
+
//#region src/campaign/search-claim.d.ts
|
|
893
|
+
/** The claim procedure every `SearchClaim` and claim plan names. */
|
|
894
|
+
declare const SEARCH_CLAIM_RULE: SearchSourceRef;
|
|
895
|
+
/**
|
|
896
|
+
* The claim reserve a search needs: the root and 3 finalists on every test
|
|
897
|
+
* task at `reps` repeats, each held at `cellUsd`. Declare at least this as
|
|
898
|
+
* `budget.reservedClaimUsd`; `runSearch` refuses to start a capped search
|
|
899
|
+
* with less.
|
|
900
|
+
*/
|
|
901
|
+
declare function searchClaimReserveUsd(input: {
|
|
902
|
+
testTasks: number;
|
|
903
|
+
reps: number;
|
|
904
|
+
cellUsd: number;
|
|
905
|
+
}): number;
|
|
906
|
+
/**
|
|
907
|
+
* The claim's design, fixed before any test cell runs, and stored as the
|
|
908
|
+
* `claim-plan` artifact of the ledger's `claim` operation.
|
|
909
|
+
*/
|
|
910
|
+
interface SearchClaimPlan {
|
|
911
|
+
kind: 'search-claim-plan';
|
|
912
|
+
rule: SearchSourceRef;
|
|
913
|
+
/** Why expansion stopped; the search closes with this reason. */
|
|
914
|
+
stopReason: SearchCloseReason;
|
|
915
|
+
/** Best first. Every one is decided `finalist` and named by the claim. */
|
|
916
|
+
finalists: Array<{
|
|
917
|
+
nodeId: string;
|
|
918
|
+
selectionMean: number;
|
|
919
|
+
}>;
|
|
920
|
+
power: SearchClaimPower;
|
|
921
|
+
/** `run`: the root and the finalists run every test task. Otherwise the
|
|
922
|
+
* claim closes with this decision and spends nothing on test cells. */
|
|
923
|
+
test: 'run' | 'hold' | 'test-cannot-resolve';
|
|
924
|
+
reason: string;
|
|
925
|
+
}
|
|
926
|
+
interface PlanSearchClaimInput {
|
|
927
|
+
stopReason: SearchCloseReason;
|
|
928
|
+
/** Repeats per test task. */
|
|
929
|
+
reps: number;
|
|
930
|
+
/** Whether the budget admits the test cells of the root and `finalists`. */
|
|
931
|
+
affordable(finalists: number): boolean;
|
|
932
|
+
}
|
|
933
|
+
/** Fix the claim's design from a search that stopped expanding. */
|
|
934
|
+
declare function planSearchClaim(state: SearchStateView, input: PlanSearchClaimInput): SearchClaimPlan;
|
|
935
|
+
/** A node decision the claim makes, ready for `recorder.decideNode`. */
|
|
936
|
+
interface SearchClaimDecision {
|
|
937
|
+
nodeId: string;
|
|
938
|
+
decision: SearchNodeDecision;
|
|
939
|
+
basis: NodeEstimate | null;
|
|
940
|
+
rule: string;
|
|
941
|
+
reason: string;
|
|
942
|
+
}
|
|
943
|
+
/**
|
|
944
|
+
* Decide the claim from the test cells of the root and the finalists. Call it
|
|
945
|
+
* once every claim cell is settled or cancelled. It returns the claim and the
|
|
946
|
+
* terminal decisions of the root and every finalist.
|
|
947
|
+
*/
|
|
948
|
+
declare function decideSearchClaim(state: SearchStateView, plan: SearchClaimPlan): {
|
|
949
|
+
claim: SearchClaim;
|
|
950
|
+
decisions: SearchClaimDecision[];
|
|
951
|
+
};
|
|
952
|
+
/** Whether a closed search's claim is the one its own ledger supports. */
|
|
953
|
+
type SearchClaimVerification = {
|
|
954
|
+
status: 'verified';
|
|
955
|
+
} |
|
|
956
|
+
/** The claim differs from the one the claim rule makes from the ledger. */
|
|
957
|
+
{
|
|
958
|
+
status: 'mismatch';
|
|
959
|
+
differences: string[];
|
|
960
|
+
} |
|
|
961
|
+
/** The claim names a rule revision this code does not implement, so this
|
|
962
|
+
* code can neither confirm nor refute it. */
|
|
963
|
+
{
|
|
964
|
+
status: 'unknown';
|
|
965
|
+
reason: string;
|
|
966
|
+
};
|
|
967
|
+
/**
|
|
968
|
+
* Make a closed search's claim again from its ledger alone and compare it with
|
|
969
|
+
* the recorded one, byte for byte: the power check, the finalists, each
|
|
970
|
+
* finalist's test estimate and deciding interval, the selection, the decision
|
|
971
|
+
* and the reason. A producer's claim is not evidence until this holds; a store
|
|
972
|
+
* keeps what this function derives, not what the producer wrote.
|
|
973
|
+
*
|
|
974
|
+
* It needs no blob, so it works on a store that keeps digests only. The
|
|
975
|
+
* finalists are the nodes the ledger decided `finalist`, in decision order.
|
|
976
|
+
* The one input the ledger cannot replay is whether the budget covered k
|
|
977
|
+
* finalists' test cells; the claim cells that ran answer it (none ran: the
|
|
978
|
+
* budget covered none). Test repeats come from the claim cells too; without
|
|
979
|
+
* test cells, the recorded estimator stands for them (binary needs one repeat,
|
|
980
|
+
* so any other count reproduces continuous).
|
|
981
|
+
*
|
|
982
|
+
* Returns null for a search that made no claim.
|
|
983
|
+
*/
|
|
984
|
+
declare function verifySearchClaim(state: SearchStateView): SearchClaimVerification | null;
|
|
985
|
+
//#endregion
|
|
986
|
+
//#region src/campaign/search-kernel.d.ts
|
|
987
|
+
/** The kernel every `runSearch` ledger names as its search implementation. */
|
|
988
|
+
declare const SEARCH_KERNEL_SOURCE: SearchSourceRef;
|
|
989
|
+
/** An execution lane: a pool of slots whose cells share a cost rule. */
|
|
990
|
+
interface SearchLane {
|
|
991
|
+
name: string;
|
|
992
|
+
/** Cells the lane runs at once. */
|
|
993
|
+
capacity: number;
|
|
994
|
+
/** `hard`: the lane enforces `cellUsd` as each cell's maximum. `estimate`:
|
|
995
|
+
* it cannot, and the kernel holds an estimate, recording any overshoot. */
|
|
996
|
+
costCap: 'hard' | 'estimate';
|
|
997
|
+
/** The enforced per-cell maximum of a hard lane; the prior estimate of an
|
|
998
|
+
* estimate lane until it has settled enough cells to estimate its own. */
|
|
999
|
+
cellUsd: number;
|
|
1000
|
+
}
|
|
1001
|
+
/** One attempt at one cell, as the kernel hands it to an executor. */
|
|
1002
|
+
interface SearchCellWork<TArtifact> {
|
|
1003
|
+
searchId: string;
|
|
1004
|
+
cellId: string;
|
|
1005
|
+
nodeId: string;
|
|
1006
|
+
taskId: string;
|
|
1007
|
+
unitId: string;
|
|
1008
|
+
split: SearchSplit;
|
|
1009
|
+
rep: number;
|
|
1010
|
+
stage: SearchCellStage;
|
|
1011
|
+
lane: string;
|
|
1012
|
+
attempt: number;
|
|
1013
|
+
/** `cellId:attempt`: the id an executor keys the attempt's run by. */
|
|
1014
|
+
runId: string;
|
|
1015
|
+
artifact: TArtifact;
|
|
1016
|
+
signal: AbortSignal;
|
|
1017
|
+
}
|
|
1018
|
+
/** What an attempt produced: everything `cell-settled` records except the
|
|
1019
|
+
* coordinates the kernel owns. An environment fault is an `errored` outcome,
|
|
1020
|
+
* not a rejection; a rejection stops the search. */
|
|
1021
|
+
type SearchCellResult = Omit<SettleSearchCellInput, 'cellId' | 'attempt'>;
|
|
1022
|
+
/** The executor port: lanes, placement, running a cell, and adopting an
|
|
1023
|
+
* attempt an earlier kernel process started. */
|
|
1024
|
+
interface SearchExecutor<TArtifact> {
|
|
1025
|
+
lanes(): readonly SearchLane[];
|
|
1026
|
+
/** The lane a planned cell runs on. */
|
|
1027
|
+
place(cell: SearchCellPlan & {
|
|
1028
|
+
nodeId: string;
|
|
1029
|
+
}): string;
|
|
1030
|
+
run(work: SearchCellWork<TArtifact>): Promise<SearchCellResult>;
|
|
1031
|
+
/** The result of `work.runId` if the executor already has it, else null.
|
|
1032
|
+
* Called before the first dispatch of a cell the ledger shows unsettled when
|
|
1033
|
+
* the kernel starts, so a restart does not run an attempt twice. */
|
|
1034
|
+
adopt(work: SearchCellWork<TArtifact>): Promise<SearchCellResult | null>;
|
|
1035
|
+
}
|
|
1036
|
+
/** How a search stores, compares and restores its artifacts. */
|
|
1037
|
+
interface SearchArtifactCodec<TArtifact> {
|
|
1038
|
+
/** The artifact as a content-addressed node; stores its bytes. */
|
|
1039
|
+
node(recorder: SearchRecorder, artifact: TArtifact): RegisterSearchNodeInput;
|
|
1040
|
+
/** The parent-to-child diff, stored as a blob, or why there is none. */
|
|
1041
|
+
diff(recorder: SearchRecorder, parent: TArtifact, child: TArtifact): SearchArtifactRef | SearchUnknown;
|
|
1042
|
+
/** The artifact a node holds, read back from its stored bytes. */
|
|
1043
|
+
load(recorder: SearchRecorder, node: SearchNode): TArtifact;
|
|
1044
|
+
}
|
|
1045
|
+
interface SearchProposalRequest<TArtifact> {
|
|
1046
|
+
expansion: number;
|
|
1047
|
+
operationId: string;
|
|
1048
|
+
operator: Exclude<SearchEdgeOperator, 'seed' | 'derive'>;
|
|
1049
|
+
/** The parents the policy chose, primary first. */
|
|
1050
|
+
parents: ReadonlyArray<{
|
|
1051
|
+
nodeId: string;
|
|
1052
|
+
artifact: TArtifact;
|
|
1053
|
+
}>;
|
|
1054
|
+
/** The node the search keeps now. */
|
|
1055
|
+
leader: string;
|
|
1056
|
+
signal: AbortSignal;
|
|
1057
|
+
}
|
|
1058
|
+
/** One child a proposal returned. */
|
|
1059
|
+
interface SearchProposedChild<TArtifact> {
|
|
1060
|
+
artifact: TArtifact;
|
|
1061
|
+
label: string;
|
|
1062
|
+
/** The proposer's reason; redacted with the share profile before it is stored. */
|
|
1063
|
+
rationale: string;
|
|
1064
|
+
/** Typed JSON the proposer attaches to the child, stored with the proposal
|
|
1065
|
+
* and never interpreted by the kernel. */
|
|
1066
|
+
attribution?: Readonly<Record<string, unknown>>;
|
|
1067
|
+
}
|
|
1068
|
+
interface SearchProposalResult<TArtifact> {
|
|
1069
|
+
children: ReadonlyArray<SearchProposedChild<TArtifact>>;
|
|
1070
|
+
/** Set when the proposer judges the search converged; expansion stops. */
|
|
1071
|
+
stop?: string;
|
|
1072
|
+
/** What generated the children; default the port's `execution`. */
|
|
1073
|
+
execution?: SearchOperationRecordedEvent['execution'];
|
|
1074
|
+
accounting: SearchAttemptAccounting;
|
|
1075
|
+
}
|
|
1076
|
+
/** The proposer port: derives children from the parents the policy chose. */
|
|
1077
|
+
interface SearchProposerPort<TArtifact> {
|
|
1078
|
+
readonly name: string;
|
|
1079
|
+
readonly kind: SearchProposerKind;
|
|
1080
|
+
readonly source: SearchSourceRef;
|
|
1081
|
+
readonly execution: SearchOperationRecordedEvent['execution'];
|
|
1082
|
+
/** Prior hold for one proposal until 20 proposals have settled. Default 0. */
|
|
1083
|
+
readonly reservationUsd?: number;
|
|
1084
|
+
/** Children one proposal usually returns, to price an expansion's screens
|
|
1085
|
+
* before it runs. Default 1. */
|
|
1086
|
+
readonly childrenPerProposal?: number;
|
|
1087
|
+
propose(request: SearchProposalRequest<TArtifact>): Promise<SearchProposalResult<TArtifact>>;
|
|
1088
|
+
}
|
|
1089
|
+
interface RunSearchOptions<TArtifact> {
|
|
1090
|
+
/** An opened recorder; its header names this policy and allocator. */
|
|
1091
|
+
recorder: SearchRecorder;
|
|
1092
|
+
/** The starting artifact: the seeded root. */
|
|
1093
|
+
root: TArtifact;
|
|
1094
|
+
codec: SearchArtifactCodec<TArtifact>;
|
|
1095
|
+
policy: SearchPolicy;
|
|
1096
|
+
allocation: SearchAllocator;
|
|
1097
|
+
proposer: SearchProposerPort<TArtifact>;
|
|
1098
|
+
executor: SearchExecutor<TArtifact>;
|
|
1099
|
+
/** Refuse a child before it runs: the reason, or null to admit it. A
|
|
1100
|
+
* refused child is recorded, decided `invalid`, and never becomes a parent. */
|
|
1101
|
+
admit?: (artifact: TArtifact) => string | null;
|
|
1102
|
+
/** Stop expanding after this many proposals. */
|
|
1103
|
+
maxExpansions?: number;
|
|
1104
|
+
/** Attempts per cell for retryable environment errors. Default 3. */
|
|
1105
|
+
maxAttempts?: number;
|
|
1106
|
+
/** Aborting pauses the search: in-flight cells are aborted, what settled is
|
|
1107
|
+
* recorded, the ledger stays open, and the call rejects. Run the kernel on
|
|
1108
|
+
* the same ledger again to continue. */
|
|
1109
|
+
signal?: AbortSignal;
|
|
1110
|
+
/** Milliseconds since the epoch, for the deadline. Default `Date.now`. */
|
|
1111
|
+
now?: () => number;
|
|
1112
|
+
}
|
|
1113
|
+
interface SearchRunResult {
|
|
1114
|
+
/** The closed search. */
|
|
1115
|
+
state: SearchStateView;
|
|
1116
|
+
/** The node the search keeps: the claim's selection, or without a claim the
|
|
1117
|
+
* policy leader; the root when nothing was selected. */
|
|
1118
|
+
leader: string;
|
|
1119
|
+
reason: SearchCloseReason;
|
|
1120
|
+
/** The claim on the sealed test split; null for a search without one. */
|
|
1121
|
+
claim: SearchClaim | null;
|
|
1122
|
+
/** The claim made again from the ledger alone (`verifySearchClaim`): never
|
|
1123
|
+
* `mismatch`, which `runSearch` throws; `unknown` for a claim another rule
|
|
1124
|
+
* revision made; null without a claim. */
|
|
1125
|
+
claimVerification: SearchClaimVerification | null;
|
|
1126
|
+
}
|
|
1127
|
+
/** Run a search to its close, or continue one from its ledger. */
|
|
1128
|
+
declare function runSearch<TArtifact>(options: RunSearchOptions<TArtifact>): Promise<SearchRunResult>;
|
|
1129
|
+
/** The expansion index a kernel operation id encodes, or null. */
|
|
1130
|
+
declare function searchExpansionIndex(operationId: string): number | null;
|
|
1131
|
+
/** The stored output of one proposal: enough to register its children again. */
|
|
1132
|
+
interface SearchProposalBlob {
|
|
1133
|
+
kind: 'search-proposal';
|
|
1134
|
+
operator: SearchProposalRequest<unknown>['operator'];
|
|
1135
|
+
parents: string[];
|
|
1136
|
+
selection: {
|
|
1137
|
+
rule: string;
|
|
1138
|
+
evidence: Record<string, number>;
|
|
1139
|
+
};
|
|
1140
|
+
children: Array<{
|
|
1141
|
+
node: RegisterSearchNodeInput;
|
|
1142
|
+
diffs: Array<SearchArtifactRef | SearchUnknown>;
|
|
1143
|
+
label: string;
|
|
1144
|
+
rationale: string;
|
|
1145
|
+
attribution: Readonly<Record<string, unknown>> | null;
|
|
1146
|
+
invalid: string | null;
|
|
1147
|
+
}>;
|
|
1148
|
+
}
|
|
1149
|
+
/**
|
|
1150
|
+
* A policy's read of a search: `screened` lists the admitted nodes whose screen
|
|
1151
|
+
* finished, in registration order; `screening` counts the admitted nodes still
|
|
1152
|
+
* being screened. Nodes are ranked on the selection split, or on train when
|
|
1153
|
+
* the search declares no selection split. The view reads no test cell.
|
|
1154
|
+
* `maxAttempts` (default 3, the kernel's) says when an errored cell has no
|
|
1155
|
+
* attempt left, which makes its unit a dodge.
|
|
1156
|
+
*/
|
|
1157
|
+
declare function searchPolicyView(state: SearchStateView, input: {
|
|
1158
|
+
screened: readonly string[];
|
|
1159
|
+
screening: number;
|
|
1160
|
+
expansions: number;
|
|
1161
|
+
maxAttempts?: number;
|
|
1162
|
+
}): SearchPolicyView;
|
|
1163
|
+
/**
|
|
1164
|
+
* The divergence rule: a node whose train mean rose over its parent's on the
|
|
1165
|
+
* train units they share while its selection interval against the parent (6
|
|
1166
|
+
* or more units, not indeterminate) lies wholly on the worse side. Train is
|
|
1167
|
+
* what the proposer reads; a gain there that selection contradicts is the
|
|
1168
|
+
* signature of fitting the feedback instead of the task.
|
|
1169
|
+
*/
|
|
1170
|
+
declare function searchDivergence(state: SearchStateView, nodeId: string): {
|
|
1171
|
+
basis: NodeEstimate;
|
|
1172
|
+
reason: string;
|
|
1173
|
+
} | null;
|
|
1174
|
+
//#endregion
|
|
1175
|
+
export { EXPANSION_OPERATORS as $, SearchCellPlan as A, SearchHistoryCoverageRow as At, aide as B, FileSearchLedger as Bt, decideSearchClaim as C, searchEdgeId as Ct, AshaOptions as D, SearchHistoryAdmissionOptions as Dt, verifySearchClaim as E, CreateSearchHistoryReceiptInput as Et, AideOptions as F, assertSearchHistoryMatchesState as Ft, EstimateNodeCellsInput as G, openSearchLedger as Gt, crowdedFrontierParent as H, SearchLedger as Ht, SearchExpansion as I, createSearchHistoryReceipt as It, SearchPosterior as J, validateSearchLedgerEvent as Jt, NodePosterior as K, parseSearchLedgerLine as Kt, SearchPolicy as L, searchHistoryCoverageRow as Lt, SearchUnitExtension as M, SearchHistoryReceipt as Mt, asha as N, SearchHistoryRequiredError as Nt, SearchAllocationView as O, SearchHistoryAuditSummary as Ot, uniform as P, assertCompleteSearchHistory as Pt, searchPosterior as Q, inMemoryCampaignStorage as Qt, SearchPolicyNode as R, verifySearchHistoryArtifact as Rt, SearchClaimVerification as S, developmentClaim as St, searchClaimReserveUsd as T, surfaceNode as Tt, incumbent as U, SearchLedgerAppendResult as Ut, beam as V, OpenSearchLedgerOptions as Vt, incumbentWithOperatorBandit as W, SearchLedgerTrustedHeadMode as Wt, estimateNodeFromCells as X, createRunCostLedger as Xt, estimateNode as Y, CampaignStorage as Yt, searchCellSetDigest as Z, fsCampaignStorage as Zt, searchPolicyView as _, SearchOpening as _t, SearchCellWork as a, OperatorYieldRow as at, SearchClaimDecision as b, SearchRunIdentity as bt, SearchProposalBlob as c, LensResult as ct, SearchProposedChild as d, rankingSplit as dt, ExpansionOperator as et, SearchProposerPort as f, summarizeSamples as ft, searchExpansionIndex as g, SearchLedgerBinding as gt, searchDivergence as h, RegisterSearchNodeInput as ht, SearchCellResult as i, OperatorYieldOptions as it, SearchRungDecision as j, SearchHistoryPolicy as jt, SearchAllocator as k, SearchHistoryCoverage as kt, SearchProposalRequest as l, LensSignal as lt, runSearch as m, RecordSearchEdgeInput as mt, SEARCH_KERNEL_SOURCE as n, OperatorOutcomeCounts as nt, SearchExecutor as o, OperatorYieldSignal as ot, SearchRunResult as p, AllocateSearchCellInput as pt, SEARCH_ESTIMATOR as q, replaySearchLedgerText as qt, SearchArtifactCodec as r, OperatorYieldData as rt, SearchLane as s, operatorYield as st, RunSearchOptions as t, MIN_OUTCOMES_FOR_WEIGHT as tt, SearchProposalResult as u, SampleSummary as ut, PlanSearchClaimInput as v, SearchRecorder as vt, planSearchClaim as w, surfaceDiff as wt, SearchClaimPlan as x, SettleSearchCellInput as xt, SEARCH_CLAIM_RULE as y, SearchRecorderOptions as yt, SearchPolicyView as z, verifySearchHistoryReceipt as zt };
|
|
1176
|
+
//# sourceMappingURL=search-kernel-CuvbakC_.d.ts.map
|